summaryrefslogtreecommitdiffstats
path: root/llvm/lib
diff options
context:
space:
mode:
Diffstat (limited to 'llvm/lib')
-rw-r--r--llvm/lib/MC/ELFObjectWriter.cpp37
-rw-r--r--llvm/lib/MC/MCAsmStreamer.cpp14
-rw-r--r--llvm/lib/MC/MCObjectStreamer.cpp9
-rw-r--r--llvm/lib/MC/MCParser/AsmParser.cpp27
-rw-r--r--llvm/lib/Object/ELF.cpp1
-rw-r--r--llvm/lib/ObjectYAML/ELFYAML.cpp1
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);
OpenPOWER on IntegriCloud