diff options
Diffstat (limited to 'llvm/lib')
-rw-r--r-- | llvm/lib/MC/ELFObjectWriter.cpp | 37 | ||||
-rw-r--r-- | llvm/lib/MC/MCAsmStreamer.cpp | 14 | ||||
-rw-r--r-- | llvm/lib/MC/MCObjectStreamer.cpp | 9 | ||||
-rw-r--r-- | llvm/lib/MC/MCParser/AsmParser.cpp | 27 | ||||
-rw-r--r-- | llvm/lib/Object/ELF.cpp | 1 | ||||
-rw-r--r-- | llvm/lib/ObjectYAML/ELFYAML.cpp | 1 |
6 files changed, 89 insertions, 0 deletions
diff --git a/llvm/lib/MC/ELFObjectWriter.cpp b/llvm/lib/MC/ELFObjectWriter.cpp index f4117e75516..db531f75c87 100644 --- a/llvm/lib/MC/ELFObjectWriter.cpp +++ b/llvm/lib/MC/ELFObjectWriter.cpp @@ -43,6 +43,7 @@ #include "llvm/Support/Error.h" #include "llvm/Support/ErrorHandling.h" #include "llvm/Support/Host.h" +#include "llvm/Support/LEB128.h" #include "llvm/Support/MathExtras.h" #include "llvm/Support/SMLoc.h" #include "llvm/Support/StringSaver.h" @@ -199,6 +200,8 @@ public: const RevGroupMapTy &RevGroupMap, SectionOffsetsTy &SectionOffsets); + void writeAddrsigSection(); + MCSectionELF *createRelocationSection(MCContext &Ctx, const MCSectionELF &Sec); @@ -232,6 +235,9 @@ class ELFObjectWriter : public MCObjectWriter { DenseMap<const MCSymbolELF *, const MCSymbolELF *> Renames; + bool EmitAddrsigSection = false; + std::vector<const MCSymbol *> AddrsigSyms; + bool hasRelocationAddend() const; bool shouldRelocateWithSymbol(const MCAssembler &Asm, @@ -267,6 +273,11 @@ public: void executePostLayoutBinding(MCAssembler &Asm, const MCAsmLayout &Layout) override; + void emitAddrsigSection() override { EmitAddrsigSection = true; } + void addAddrsigSymbol(const MCSymbol *Sym) override { + AddrsigSyms.push_back(Sym); + } + friend struct ELFWriter; }; @@ -747,6 +758,11 @@ void ELFWriter::computeSymbolTable( SectionOffsets[SymtabShndxSection] = std::make_pair(SecStart, SecEnd); } +void ELFWriter::writeAddrsigSection() { + for (const MCSymbol *Sym : OWriter.AddrsigSyms) + encodeULEB128(Sym->getIndex(), W.OS); +} + MCSectionELF *ELFWriter::createRelocationSection(MCContext &Ctx, const MCSectionELF &Sec) { if (OWriter.Relocations[&Sec].empty()) @@ -977,6 +993,7 @@ void ELFWriter::writeSection(const SectionIndexMapTy &SectionIndexMap, case ELF::SHT_SYMTAB_SHNDX: case ELF::SHT_LLVM_CALL_GRAPH_PROFILE: + case ELF::SHT_LLVM_ADDRSIG: sh_link = SymbolTableIndex; break; @@ -1123,6 +1140,13 @@ uint64_t ELFWriter::writeObject(MCAssembler &Asm, const MCAsmLayout &Layout) { // string tables. StrTabBuilder.finalize(); } else { + MCSectionELF *AddrsigSection; + if (OWriter.EmitAddrsigSection) { + AddrsigSection = Ctx.getELFSection(".llvm_addrsig", ELF::SHT_LLVM_ADDRSIG, + ELF::SHF_EXCLUDE); + addToSectionTable(AddrsigSection); + } + // Compute symbol table information. computeSymbolTable(Asm, Layout, SectionIndexMap, RevGroupMap, SectionOffsets); @@ -1139,6 +1163,13 @@ uint64_t ELFWriter::writeObject(MCAssembler &Asm, const MCAsmLayout &Layout) { uint64_t SecEnd = W.OS.tell(); SectionOffsets[RelSection] = std::make_pair(SecStart, SecEnd); } + + if (OWriter.EmitAddrsigSection) { + uint64_t SecStart = W.OS.tell(); + writeAddrsigSection(); + uint64_t SecEnd = W.OS.tell(); + SectionOffsets[AddrsigSection] = std::make_pair(SecStart, SecEnd); + } } if (CGProfileSection) { @@ -1238,6 +1269,12 @@ void ELFObjectWriter::executePostLayoutBinding(MCAssembler &Asm, Renames.insert(std::make_pair(&Symbol, Alias)); } + + for (const MCSymbol *&Sym : AddrsigSyms) { + if (const MCSymbol *R = Renames.lookup(cast<MCSymbolELF>(Sym))) + Sym = R; + Sym->setUsedInReloc(); + } } // It is always valid to create a relocation with a symbol. It is preferable diff --git a/llvm/lib/MC/MCAsmStreamer.cpp b/llvm/lib/MC/MCAsmStreamer.cpp index 5398cfea786..1429f647b61 100644 --- a/llvm/lib/MC/MCAsmStreamer.cpp +++ b/llvm/lib/MC/MCAsmStreamer.cpp @@ -319,6 +319,9 @@ public: const MCExpr *Expr, SMLoc Loc, const MCSubtargetInfo &STI) override; + void EmitAddrsig() override; + void EmitAddrsigSym(const MCSymbol *Sym) override; + /// If this file is backed by an assembly streamer, this dumps the specified /// string in the output .s file. This capability is indicated by the /// hasRawTextSupport() predicate. @@ -1846,6 +1849,17 @@ bool MCAsmStreamer::EmitRelocDirective(const MCExpr &Offset, StringRef Name, return false; } +void MCAsmStreamer::EmitAddrsig() { + OS << "\t.addrsig"; + EmitEOL(); +} + +void MCAsmStreamer::EmitAddrsigSym(const MCSymbol *Sym) { + OS << "\t.addrsig_sym "; + Sym->print(OS, MAI); + EmitEOL(); +} + /// EmitRawText - If this file is backed by an assembly streamer, this dumps /// the specified string in the output .s file. This capability is /// indicated by the hasRawTextSupport() predicate. diff --git a/llvm/lib/MC/MCObjectStreamer.cpp b/llvm/lib/MC/MCObjectStreamer.cpp index 9d536883b98..4b6dad5ce8f 100644 --- a/llvm/lib/MC/MCObjectStreamer.cpp +++ b/llvm/lib/MC/MCObjectStreamer.cpp @@ -660,6 +660,15 @@ void MCObjectStreamer::EmitFileDirective(StringRef Filename) { getAssembler().addFileName(Filename); } +void MCObjectStreamer::EmitAddrsig() { + getAssembler().getWriter().emitAddrsigSection(); +} + +void MCObjectStreamer::EmitAddrsigSym(const MCSymbol *Sym) { + getAssembler().registerSymbol(*Sym); + getAssembler().getWriter().addAddrsigSymbol(Sym); +} + void MCObjectStreamer::FinishImpl() { getContext().RemapDebugPaths(); diff --git a/llvm/lib/MC/MCParser/AsmParser.cpp b/llvm/lib/MC/MCParser/AsmParser.cpp index f79a21b05d2..68e6e94a492 100644 --- a/llvm/lib/MC/MCParser/AsmParser.cpp +++ b/llvm/lib/MC/MCParser/AsmParser.cpp @@ -506,6 +506,8 @@ private: DK_ERROR, DK_WARNING, DK_PRINT, + DK_ADDRSIG, + DK_ADDRSIG_SYM, DK_END }; @@ -654,6 +656,10 @@ private: // .print <double-quotes-string> bool parseDirectivePrint(SMLoc DirectiveLoc); + // Directives to support address-significance tables. + bool parseDirectiveAddrsig(); + bool parseDirectiveAddrsigSym(); + void initializeDirectiveKindMap(); }; @@ -2127,6 +2133,10 @@ bool AsmParser::parseStatement(ParseStatementInfo &Info, return parseDirectiveDS(IDVal, 12); case DK_PRINT: return parseDirectivePrint(IDLoc); + case DK_ADDRSIG: + return parseDirectiveAddrsig(); + case DK_ADDRSIG_SYM: + return parseDirectiveAddrsigSym(); } return Error(IDLoc, "unknown directive"); @@ -5291,6 +5301,8 @@ void AsmParser::initializeDirectiveKindMap() { DirectiveKindMap[".ds.w"] = DK_DS_W; DirectiveKindMap[".ds.x"] = DK_DS_X; DirectiveKindMap[".print"] = DK_PRINT; + DirectiveKindMap[".addrsig"] = DK_ADDRSIG; + DirectiveKindMap[".addrsig_sym"] = DK_ADDRSIG_SYM; } MCAsmMacro *AsmParser::parseMacroLikeBody(SMLoc DirectiveLoc) { @@ -5530,6 +5542,21 @@ bool AsmParser::parseDirectivePrint(SMLoc DirectiveLoc) { return false; } +bool AsmParser::parseDirectiveAddrsig() { + getStreamer().EmitAddrsig(); + return false; +} + +bool AsmParser::parseDirectiveAddrsigSym() { + StringRef Name; + if (check(parseIdentifier(Name), + "expected identifier in '.addrsig_sym' directive")) + return true; + MCSymbol *Sym = getContext().getOrCreateSymbol(Name); + getStreamer().EmitAddrsigSym(Sym); + return false; +} + // We are comparing pointers, but the pointers are relative to a single string. // Thus, this should always be deterministic. static int rewritesSort(const AsmRewrite *AsmRewriteA, diff --git a/llvm/lib/Object/ELF.cpp b/llvm/lib/Object/ELF.cpp index d58a79115bd..3e2161a9396 100644 --- a/llvm/lib/Object/ELF.cpp +++ b/llvm/lib/Object/ELF.cpp @@ -246,6 +246,7 @@ StringRef llvm::object::getELFSectionTypeName(uint32_t Machine, unsigned Type) { STRINGIFY_ENUM_CASE(ELF, SHT_LLVM_ODRTAB); STRINGIFY_ENUM_CASE(ELF, SHT_LLVM_LINKER_OPTIONS); STRINGIFY_ENUM_CASE(ELF, SHT_LLVM_CALL_GRAPH_PROFILE); + STRINGIFY_ENUM_CASE(ELF, SHT_LLVM_ADDRSIG); STRINGIFY_ENUM_CASE(ELF, SHT_GNU_ATTRIBUTES); STRINGIFY_ENUM_CASE(ELF, SHT_GNU_HASH); STRINGIFY_ENUM_CASE(ELF, SHT_GNU_verdef); diff --git a/llvm/lib/ObjectYAML/ELFYAML.cpp b/llvm/lib/ObjectYAML/ELFYAML.cpp index 8964f5c811b..f916b5d5f39 100644 --- a/llvm/lib/ObjectYAML/ELFYAML.cpp +++ b/llvm/lib/ObjectYAML/ELFYAML.cpp @@ -444,6 +444,7 @@ void ScalarEnumerationTraits<ELFYAML::ELF_SHT>::enumeration( ECase(SHT_LLVM_ODRTAB); ECase(SHT_LLVM_LINKER_OPTIONS); ECase(SHT_LLVM_CALL_GRAPH_PROFILE); + ECase(SHT_LLVM_ADDRSIG); ECase(SHT_GNU_ATTRIBUTES); ECase(SHT_GNU_HASH); ECase(SHT_GNU_verdef); |