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
/// EmitValue - Emit debug information entry offset.
///
void DIEEntry::EmitValue(const AsmPrinter *AP, dwarf::Form Form) const {

  switch (Form) {
  case dwarf::DW_FORM_ref1:
  case dwarf::DW_FORM_ref2:
  case dwarf::DW_FORM_ref4:
  case dwarf::DW_FORM_ref8:
    AP->OutStreamer->EmitIntValue(Entry->getOffset(), SizeOf(AP, Form));
    return;

  case dwarf::DW_FORM_ref_udata:
    AP->EmitULEB128(Entry->getOffset());
    return;

  case dwarf::DW_FORM_ref_addr: {
    // Get the absolute offset for this DIE within the debug info/types section.
    unsigned Addr = Entry->getDebugSectionOffset();
    if (AP->MAI->doesDwarfUseRelocationsAcrossSections()) {
      const DwarfDebug *DD = AP->getDwarfDebug();
      if (DD)
        assert(!DD->useSplitDwarf() &&
               "TODO: dwo files can't have relocations.");
      const DIEUnit *Unit = Entry->getUnit();
      assert(Unit && "CUDie should belong to a CU.");
      MCSection *Section = Unit->getSection();
      if (Section) {
        const MCSymbol *SectionSym = Section->getBeginSymbol();
        AP->EmitLabelPlusOffset(SectionSym, Addr, SizeOf(AP, Form), true);
        return;
      }
    }
    AP->OutStreamer->EmitIntValue(Addr, SizeOf(AP, Form));
    return;
  }
  default:
    llvm_unreachable("Improper form for DIE reference");
  }
}
Esempio n. 3
0
bool ELFAsmParser::ParseSectionArguments(bool IsPush, SMLoc loc) {
  StringRef SectionName;

  if (ParseSectionName(SectionName))
    return TokError("expected identifier in directive");

  StringRef TypeName;
  int64_t Size = 0;
  StringRef GroupName;
  unsigned Flags = 0;
  const MCExpr *Subsection = nullptr;
  bool UseLastGroup = false;
  MCSymbolELF *Associated = nullptr;
  int64_t UniqueID = ~0;

  // Set the defaults first.
  if (hasPrefix(SectionName, ".rodata.") || SectionName == ".rodata1")
    Flags |= ELF::SHF_ALLOC;
  else if (SectionName == ".fini" || SectionName == ".init" ||
           hasPrefix(SectionName, ".text."))
    Flags |= ELF::SHF_ALLOC | ELF::SHF_EXECINSTR;
  else if (hasPrefix(SectionName, ".data.") || SectionName == ".data1" ||
           hasPrefix(SectionName, ".bss.") ||
           hasPrefix(SectionName, ".init_array.") ||
           hasPrefix(SectionName, ".fini_array.") ||
           hasPrefix(SectionName, ".preinit_array."))
    Flags |= ELF::SHF_ALLOC | ELF::SHF_WRITE;
  else if (hasPrefix(SectionName, ".tdata.") ||
           hasPrefix(SectionName, ".tbss."))
    Flags |= ELF::SHF_ALLOC | ELF::SHF_WRITE | ELF::SHF_TLS;

  if (getLexer().is(AsmToken::Comma)) {
    Lex();

    if (IsPush && getLexer().isNot(AsmToken::String)) {
      if (getParser().parseExpression(Subsection))
        return true;
      if (getLexer().isNot(AsmToken::Comma))
        goto EndStmt;
      Lex();
    }

    unsigned extraFlags;

    if (getLexer().isNot(AsmToken::String)) {
      if (!getContext().getAsmInfo()->usesSunStyleELFSectionSwitchSyntax()
          || getLexer().isNot(AsmToken::Hash))
        return TokError("expected string in directive");
      extraFlags = parseSunStyleSectionFlags();
    } else {
      StringRef FlagsStr = getTok().getStringContents();
      Lex();
      extraFlags = parseSectionFlags(FlagsStr, &UseLastGroup);
    }

    if (extraFlags == -1U)
      return TokError("unknown flag");
    Flags |= extraFlags;

    bool Mergeable = Flags & ELF::SHF_MERGE;
    bool Group = Flags & ELF::SHF_GROUP;
    if (Group && UseLastGroup)
      return TokError("Section cannot specifiy a group name while also acting "
                      "as a member of the last group");

    if (maybeParseSectionType(TypeName))
      return true;

    MCAsmLexer &L = getLexer();
    if (TypeName.empty()) {
      if (Mergeable)
        return TokError("Mergeable section must specify the type");
      if (Group)
        return TokError("Group section must specify the type");
      if (L.isNot(AsmToken::EndOfStatement))
        return TokError("unexpected token in directive");
    }

    if (Mergeable)
      if (parseMergeSize(Size))
        return true;
    if (Group)
      if (parseGroup(GroupName))
        return true;
    if (Flags & ELF::SHF_LINK_ORDER)
      if (parseMetadataSym(Associated))
        return true;
    if (maybeParseUniqueID(UniqueID))
      return true;
  }

EndStmt:
  if (getLexer().isNot(AsmToken::EndOfStatement))
    return TokError("unexpected token in directive");
  Lex();

  unsigned Type = ELF::SHT_PROGBITS;

  if (TypeName.empty()) {
    if (SectionName.startswith(".note"))
      Type = ELF::SHT_NOTE;
    else if (hasPrefix(SectionName, ".init_array."))
      Type = ELF::SHT_INIT_ARRAY;
    else if (hasPrefix(SectionName, ".bss."))
      Type = ELF::SHT_NOBITS;
    else if (hasPrefix(SectionName, ".tbss."))
      Type = ELF::SHT_NOBITS;
    else if (hasPrefix(SectionName, ".fini_array."))
      Type = ELF::SHT_FINI_ARRAY;
    else if (hasPrefix(SectionName, ".preinit_array."))
      Type = ELF::SHT_PREINIT_ARRAY;
  } else {
    if (TypeName == "init_array")
      Type = ELF::SHT_INIT_ARRAY;
    else if (TypeName == "fini_array")
      Type = ELF::SHT_FINI_ARRAY;
    else if (TypeName == "preinit_array")
      Type = ELF::SHT_PREINIT_ARRAY;
    else if (TypeName == "nobits")
      Type = ELF::SHT_NOBITS;
    else if (TypeName == "progbits")
      Type = ELF::SHT_PROGBITS;
    else if (TypeName == "note")
      Type = ELF::SHT_NOTE;
    else if (TypeName == "unwind")
      Type = ELF::SHT_X86_64_UNWIND;
    else if (TypeName == "llvm_odrtab")
      Type = ELF::SHT_LLVM_ODRTAB;
    else if (TypeName == "llvm_linker_options")
      Type = ELF::SHT_LLVM_LINKER_OPTIONS;
    else if (TypeName == "llvm_call_graph_profile")
      Type = ELF::SHT_LLVM_CALL_GRAPH_PROFILE;
    else if (TypeName.getAsInteger(0, Type))
      return TokError("unknown section type");
  }

  if (UseLastGroup) {
    MCSectionSubPair CurrentSection = getStreamer().getCurrentSection();
    if (const MCSectionELF *Section =
            cast_or_null<MCSectionELF>(CurrentSection.first))
      if (const MCSymbol *Group = Section->getGroup()) {
        GroupName = Group->getName();
        Flags |= ELF::SHF_GROUP;
      }
  }

  MCSection *ELFSection =
      getContext().getELFSection(SectionName, Type, Flags, Size, GroupName,
                                 UniqueID, Associated);
  getStreamer().SwitchSection(ELFSection, Subsection);

  if (getContext().getGenDwarfForAssembly()) {
    bool InsertResult = getContext().addGenDwarfSection(ELFSection);
    if (InsertResult) {
      if (getContext().getDwarfVersion() <= 2)
        Warning(loc, "DWARF2 only supports one section per compilation unit");

      if (!ELFSection->getBeginSymbol()) {
        MCSymbol *SectionStartSymbol = getContext().createTempSymbol();
        getStreamer().EmitLabel(SectionStartSymbol);
        ELFSection->setBeginSymbol(SectionStartSymbol);
      }
    }
  }

  return false;
}
Esempio n. 4
0
bool ELFAsmParser::ParseSectionArguments(bool IsPush, SMLoc loc) {
    StringRef SectionName;

    if (ParseSectionName(SectionName))
        return TokError("expected identifier in directive");

    StringRef TypeName;
    int64_t Size = 0;
    StringRef GroupName;
    unsigned Flags = 0;
    const MCExpr *Subsection = nullptr;
    bool UseLastGroup = false;
    StringRef UniqueStr;
    int64_t UniqueID = ~0;

    // Set the defaults first.
    if (SectionName == ".fini" || SectionName == ".init" ||
            SectionName == ".rodata")
        Flags |= ELF::SHF_ALLOC;
    if (SectionName == ".fini" || SectionName == ".init")
        Flags |= ELF::SHF_EXECINSTR;

    if (getLexer().is(AsmToken::Comma)) {
        Lex();

        if (IsPush && getLexer().isNot(AsmToken::String)) {
            if (getParser().parseExpression(Subsection))
                return true;
            if (getLexer().isNot(AsmToken::Comma))
                goto EndStmt;
            Lex();
        }

        unsigned extraFlags;

        if (getLexer().isNot(AsmToken::String)) {
            if (!getContext().getAsmInfo()->usesSunStyleELFSectionSwitchSyntax()
                    || getLexer().isNot(AsmToken::Hash))
                return TokError("expected string in directive");
            extraFlags = parseSunStyleSectionFlags();
        } else {
            StringRef FlagsStr = getTok().getStringContents();
            Lex();
            extraFlags = parseSectionFlags(FlagsStr, &UseLastGroup);
        }

        if (extraFlags == -1U)
            return TokError("unknown flag");
        Flags |= extraFlags;

        bool Mergeable = Flags & ELF::SHF_MERGE;
        bool Group = Flags & ELF::SHF_GROUP;
        if (Group && UseLastGroup)
            return TokError("Section cannot specifiy a group name while also acting "
                            "as a member of the last group");

        if (getLexer().isNot(AsmToken::Comma)) {
            if (Mergeable)
                return TokError("Mergeable section must specify the type");
            if (Group)
                return TokError("Group section must specify the type");
        } else {
            Lex();
            if (getLexer().is(AsmToken::At) || getLexer().is(AsmToken::Percent) ||
                    getLexer().is(AsmToken::String)) {
                if (!getLexer().is(AsmToken::String))
                    Lex();
            } else
                return TokError("expected '@<type>', '%<type>' or \"<type>\"");

            if (getParser().parseIdentifier(TypeName))
                return TokError("expected identifier in directive");

            if (Mergeable) {
                if (getLexer().isNot(AsmToken::Comma))
                    return TokError("expected the entry size");
                Lex();
                if (getParser().parseAbsoluteExpression(Size))
                    return true;
                if (Size <= 0)
                    return TokError("entry size must be positive");
            }

            if (Group) {
                if (getLexer().isNot(AsmToken::Comma))
                    return TokError("expected group name");
                Lex();
                if (getParser().parseIdentifier(GroupName))
                    return true;
                if (getLexer().is(AsmToken::Comma)) {
                    Lex();
                    StringRef Linkage;
                    if (getParser().parseIdentifier(Linkage))
                        return true;
                    if (Linkage != "comdat")
                        return TokError("Linkage must be 'comdat'");
                }
            }
            if (getLexer().is(AsmToken::Comma)) {
                Lex();
                if (getParser().parseIdentifier(UniqueStr))
                    return TokError("expected identifier in directive");
                if (UniqueStr != "unique")
                    return TokError("expected 'unique'");
                if (getLexer().isNot(AsmToken::Comma))
                    return TokError("expected commma");
                Lex();
                if (getParser().parseAbsoluteExpression(UniqueID))
                    return true;
                if (UniqueID < 0)
                    return TokError("unique id must be positive");
                if (!isUInt<32>(UniqueID) || UniqueID == ~0U)
                    return TokError("unique id is too large");
            }
        }
    }

EndStmt:
    if (getLexer().isNot(AsmToken::EndOfStatement))
        return TokError("unexpected token in directive");

    unsigned Type = ELF::SHT_PROGBITS;

    if (TypeName.empty()) {
        if (SectionName.startswith(".note"))
            Type = ELF::SHT_NOTE;
        else if (SectionName == ".init_array")
            Type = ELF::SHT_INIT_ARRAY;
        else if (SectionName == ".fini_array")
            Type = ELF::SHT_FINI_ARRAY;
        else if (SectionName == ".preinit_array")
            Type = ELF::SHT_PREINIT_ARRAY;
    } else {
        if (TypeName == "init_array")
            Type = ELF::SHT_INIT_ARRAY;
        else if (TypeName == "fini_array")
            Type = ELF::SHT_FINI_ARRAY;
        else if (TypeName == "preinit_array")
            Type = ELF::SHT_PREINIT_ARRAY;
        else if (TypeName == "nobits")
            Type = ELF::SHT_NOBITS;
        else if (TypeName == "progbits")
            Type = ELF::SHT_PROGBITS;
        else if (TypeName == "note")
            Type = ELF::SHT_NOTE;
        else if (TypeName == "unwind")
            Type = ELF::SHT_X86_64_UNWIND;
        else
            return TokError("unknown section type");
    }

    if (UseLastGroup) {
        MCSectionSubPair CurrentSection = getStreamer().getCurrentSection();
        if (const MCSectionELF *Section =
                    cast_or_null<MCSectionELF>(CurrentSection.first))
            if (const MCSymbol *Group = Section->getGroup()) {
                GroupName = Group->getName();
                Flags |= ELF::SHF_GROUP;
            }
    }

    MCSection *ELFSection = getContext().getELFSection(SectionName, Type, Flags,
                            Size, GroupName, UniqueID);
    getStreamer().SwitchSection(ELFSection, Subsection);

    if (getContext().getGenDwarfForAssembly()) {
        bool InsertResult = getContext().addGenDwarfSection(ELFSection);
        if (InsertResult) {
            if (getContext().getDwarfVersion() <= 2)
                Warning(loc, "DWARF2 only supports one section per compilation unit");

            if (!ELFSection->getBeginSymbol()) {
                MCSymbol *SectionStartSymbol = getContext().createTempSymbol();
                getStreamer().EmitLabel(SectionStartSymbol);
                ELFSection->setBeginSymbol(SectionStartSymbol);
            }
        }
    }

    return false;
}