Esempio n. 1
0
extern "C" void SwitchSection(ObjectWriter *OW, const char *SectionName) {
  assert(OW && "ObjWriter is null");
  auto *AsmPrinter = &OW->getAsmPrinter();
  auto &OST = *AsmPrinter->OutStreamer;
  MCContext &OutContext = OST.getContext();
  const MCObjectFileInfo *MOFI = OutContext.getObjectFileInfo();

  MCSection *Section = nullptr;
  if (strcmp(SectionName, "text") == 0) {
    Section = MOFI->getTextSection();
    if (!Section->hasInstructions()) {
      Section->setHasInstructions(true);
      OutContext.addGenDwarfSection(Section);
    }
  } else if (strcmp(SectionName, "data") == 0) {
    Section = MOFI->getDataSection();
  } else if (strcmp(SectionName, "rdata") == 0) {
    Section = MOFI->getReadOnlySection();
  } else if (strcmp(SectionName, "xdata") == 0) {
    Section = MOFI->getXDataSection();
  } else {
    std::string SectionNameStr(SectionName);
    if (OW->CustomSections.find(SectionNameStr) != OW->CustomSections.end()) {
      Section = OW->CustomSections[SectionNameStr];
    } else {
      // Add more general cases
      assert(!"Unsupported section");
    }
  }

  OW->Sections.insert(Section);
  OST.SwitchSection(Section);

  if (!Section->getBeginSymbol()) {
    MCSymbol *SectionStartSym = OutContext.createTempSymbol();
    OST.EmitLabel(SectionStartSym);
    Section->setBeginSymbol(SectionStartSym);
  }
}
Esempio n. 2
0
void MCObjectStreamer::EmitInstruction(const MCInst &Inst,
                                       const MCSubtargetInfo &STI) {
    MCStreamer::EmitInstruction(Inst, STI);

    MCSection *Sec = getCurrentSectionOnly();
    Sec->setHasInstructions(true);

    // Now that a machine instruction has been assembled into this section, make
    // a line entry for any .loc directive that has been seen.
    MCCVLineEntry::Make(this);
    MCDwarfLineEntry::Make(this, getCurrentSection().first);

    // If this instruction doesn't need relaxation, just emit it as data.
    MCAssembler &Assembler = getAssembler();
    if (!Assembler.getBackend().mayNeedRelaxation(Inst)) {
        EmitInstToData(Inst, STI);
        return;
    }

    // Otherwise, relax and emit it as data if either:
    // - The RelaxAll flag was passed
    // - Bundling is enabled and this instruction is inside a bundle-locked
    //   group. We want to emit all such instructions into the same data
    //   fragment.
    if (Assembler.getRelaxAll() ||
            (Assembler.isBundlingEnabled() && Sec->isBundleLocked())) {
        MCInst Relaxed;
        getAssembler().getBackend().relaxInstruction(Inst, STI, Relaxed);
        while (getAssembler().getBackend().mayNeedRelaxation(Relaxed))
            getAssembler().getBackend().relaxInstruction(Relaxed, STI, Relaxed);
        EmitInstToData(Relaxed, STI);
        return;
    }

    // Otherwise emit to a separate fragment.
    EmitInstToFragment(Inst, STI);
}
Esempio n. 3
0
extern "C" bool CreateCustomSection(ObjectWriter *OW, const char *SectionName,
                                    CustomSectionAttributes attributes,
                                    const char *ComdatName) {
  assert(OW && "ObjWriter is null");
  Triple TheTriple(TripleName);
  auto *AsmPrinter = &OW->getAsmPrinter();
  auto &OST = *AsmPrinter->OutStreamer;
  MCContext &OutContext = OST.getContext();

  std::string SectionNameStr(SectionName);
  assert(OW->CustomSections.find(SectionNameStr) == OW->CustomSections.end() &&
         "Section with duplicate name already exists");
  assert(ComdatName == nullptr ||
         OW->MOFI->getObjectFileType() == OW->MOFI->IsCOFF);

  MCSection *Section = nullptr;
  SectionKind Kind = (attributes & CustomSectionAttributes_Executable)
                         ? SectionKind::getText()
                         : (attributes & CustomSectionAttributes_Writeable)
                               ? SectionKind::getData()
                               : SectionKind::getReadOnly();

  switch (TheTriple.getObjectFormat()) {
  case Triple::MachO: {
    unsigned typeAndAttributes = 0;
    if (attributes & CustomSectionAttributes_MachO_Init_Func_Pointers) {
      typeAndAttributes |= MachO::SectionType::S_MOD_INIT_FUNC_POINTERS;
    }
    Section = OutContext.getMachOSection(
        (attributes & CustomSectionAttributes_Executable) ? "__TEXT" : "__DATA",
        SectionName, typeAndAttributes, Kind);
    break;
  }
  case Triple::COFF: {
    unsigned Characteristics = COFF::IMAGE_SCN_MEM_READ;

    if (attributes & CustomSectionAttributes_Executable) {
      Characteristics |= COFF::IMAGE_SCN_CNT_CODE | COFF::IMAGE_SCN_MEM_EXECUTE;
    } else if (attributes & CustomSectionAttributes_Writeable) {
      Characteristics |=
          COFF::IMAGE_SCN_CNT_INITIALIZED_DATA | COFF::IMAGE_SCN_MEM_WRITE;
    } else {
      Characteristics |= COFF::IMAGE_SCN_CNT_INITIALIZED_DATA;
    }

    if (ComdatName != nullptr) {
      Section = OutContext.getCOFFSection(
          SectionName, Characteristics | COFF::IMAGE_SCN_LNK_COMDAT, Kind,
          ComdatName, COFF::COMDATType::IMAGE_COMDAT_SELECT_ANY);
    } else {
      Section = OutContext.getCOFFSection(SectionName, Characteristics, Kind);
    }
    break;
  }
  case Triple::ELF: {
    unsigned Flags = ELF::SHF_ALLOC;
    if (attributes & CustomSectionAttributes_Executable) {
      Flags |= ELF::SHF_EXECINSTR;
    } else if (attributes & CustomSectionAttributes_Writeable) {
      Flags |= ELF::SHF_WRITE;
    }
    Section = OutContext.getELFSection(SectionName, ELF::SHT_PROGBITS, Flags);
    break;
  }
  default:
    return error("Unknown output format for target " + TripleName);
    break;
  }

  if (attributes & CustomSectionAttributes_Executable) {
    Section->setHasInstructions(true);
    OutContext.addGenDwarfSection(Section);
  }

  OW->CustomSections[SectionNameStr] = Section;
  return true;
}