mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2024-11-25 04:02:41 +01:00
MC: Implement support for new .addrsig and .addrsig_sym directives.
Part of the address-significance tables proposal: http://lists.llvm.org/pipermail/llvm-dev/2018-May/123514.html Differential Revision: https://reviews.llvm.org/D47744 llvm-svn: 337328
This commit is contained in:
parent
b27e787f6c
commit
ec56d20419
@ -329,6 +329,36 @@ symbol is undefined, then that symbol is defined as if ``.weak symbol`` has been
|
||||
written at the end of the file. This forces the symbol to show up in the symbol
|
||||
table.
|
||||
|
||||
``SHT_LLVM_ADDRSIG`` Section (address-significance table)
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
This section is used to mark symbols as address-significant, i.e. the address
|
||||
of the symbol is used in a comparison or leaks outside the translation unit. It
|
||||
has the same meaning as the absence of the LLVM attributes ``unnamed_addr``
|
||||
and ``local_unnamed_addr``.
|
||||
|
||||
Any sections referred to by symbols that are not marked as address-significant
|
||||
in any object file may be safely merged by a linker without breaking the
|
||||
address uniqueness guarantee provided by the C and C++ language standards.
|
||||
|
||||
The contents of the section are a sequence of ULEB128-encoded integers
|
||||
referring to the symbol table indexes of the address-significant symbols.
|
||||
|
||||
There are two associated assembly directives:
|
||||
|
||||
.. code-block:: gas
|
||||
|
||||
.addrsig
|
||||
|
||||
This instructs the assembler to emit an address-significance table. Without
|
||||
this directive, all symbols are considered address-significant.
|
||||
|
||||
.. code-block:: gas
|
||||
|
||||
.addrsig_sym sym
|
||||
|
||||
This marks ``sym`` as address-significant.
|
||||
|
||||
CodeView-Dependent
|
||||
------------------
|
||||
|
||||
|
@ -797,6 +797,8 @@ enum : unsigned {
|
||||
SHT_LLVM_ODRTAB = 0x6fff4c00, // LLVM ODR table.
|
||||
SHT_LLVM_LINKER_OPTIONS = 0x6fff4c01, // LLVM Linker Options.
|
||||
SHT_LLVM_CALL_GRAPH_PROFILE = 0x6fff4c02, // LLVM Call Graph Profile.
|
||||
SHT_LLVM_ADDRSIG = 0x6fff4c03, // List of address-significant symbols
|
||||
// for safe ICF.
|
||||
// Android's experimental support for SHT_RELR sections.
|
||||
// https://android.googlesource.com/platform/bionic/+/b7feec74547f84559a1467aca02708ff61346d2a/libc/include/elf.h#512
|
||||
SHT_ANDROID_RELR = 0x6fffff00, // Relocation entries; only offsets.
|
||||
|
@ -170,6 +170,9 @@ public:
|
||||
SMLoc Loc = SMLoc()) override;
|
||||
void EmitFileDirective(StringRef Filename) override;
|
||||
|
||||
void EmitAddrsig() override;
|
||||
void EmitAddrsigSym(const MCSymbol *Sym) override;
|
||||
|
||||
void FinishImpl() override;
|
||||
|
||||
/// Emit the absolute difference between two symbols if possible.
|
||||
|
@ -92,6 +92,15 @@ public:
|
||||
bool InSet,
|
||||
bool IsPCRel) const;
|
||||
|
||||
/// Tell the object writer to emit an address-significance table during
|
||||
/// writeObject(). If this function is not called, all symbols are treated as
|
||||
/// address-significant.
|
||||
virtual void emitAddrsigSection() {}
|
||||
|
||||
/// Record the given symbol in the address-significance table to be written
|
||||
/// diring writeObject().
|
||||
virtual void addAddrsigSymbol(const MCSymbol *Sym) {}
|
||||
|
||||
/// Write the object file and returns the number of bytes written.
|
||||
///
|
||||
/// This routine is called by the assembler after layout and relaxation is
|
||||
|
@ -924,6 +924,9 @@ public:
|
||||
return true;
|
||||
}
|
||||
|
||||
virtual void EmitAddrsig() {}
|
||||
virtual void EmitAddrsigSym(const MCSymbol *Sym) {}
|
||||
|
||||
/// Emit the given \p Instruction into the current section.
|
||||
/// PrintSchedInfo == true then schedul comment should be added to output
|
||||
virtual void EmitInstruction(const MCInst &Inst, const MCSubtargetInfo &STI,
|
||||
|
@ -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
|
||||
|
@ -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.
|
||||
|
@ -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();
|
||||
|
||||
|
@ -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,
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
|
5
test/MC/ELF/addrsig-error.s
Normal file
5
test/MC/ELF/addrsig-error.s
Normal file
@ -0,0 +1,5 @@
|
||||
// RUN: not llvm-mc -filetype=obj -triple x86_64-pc-linux-gnu %s -o - 2>&1 | FileCheck %s
|
||||
// CHECK: Undefined temporary symbol
|
||||
|
||||
.addrsig
|
||||
.addrsig_sym .Lundef
|
86
test/MC/ELF/addrsig.s
Normal file
86
test/MC/ELF/addrsig.s
Normal file
@ -0,0 +1,86 @@
|
||||
// RUN: llvm-mc -filetype=asm -triple x86_64-pc-linux-gnu %s -o - | FileCheck --check-prefix=ASM %s
|
||||
// RUN: llvm-mc -filetype=obj -triple x86_64-pc-linux-gnu %s -o - | llvm-readobj -s -t -sd -elf-addrsig | FileCheck %s
|
||||
// RUN: llvm-mc -filetype=obj -triple x86_64-pc-linux-gnu %s -split-dwarf-file %t.dwo -o - | llvm-readobj -s -t -sd -elf-addrsig | FileCheck %s
|
||||
// RUN: llvm-readobj -s %t.dwo | FileCheck --check-prefix=DWO %s
|
||||
|
||||
// CHECK: Name: .llvm_addrsig
|
||||
// CHECK-NEXT: Type: SHT_LLVM_ADDRSIG (0x6FFF4C03)
|
||||
// CHECK-NEXT: Flags [ (0x80000000)
|
||||
// CHECK-NEXT: SHF_EXCLUDE (0x80000000)
|
||||
// CHECK-NEXT: ]
|
||||
// CHECK-NEXT: Address:
|
||||
// CHECK-NEXT: Offset:
|
||||
// CHECK-NEXT: Size: 4
|
||||
// CHECK-NEXT: Link: 4
|
||||
// CHECK-NEXT: Info: 0
|
||||
// CHECK-NEXT: AddressAlignment: 1
|
||||
// CHECK-NEXT: EntrySize: 0
|
||||
// CHECK-NEXT: SectionData (
|
||||
// CHECK-NEXT: 0000: 03050201
|
||||
// CHECK-NEXT: )
|
||||
// CHECK-NEXT: }
|
||||
// CHECK-NEXT: Section {
|
||||
// CHECK-NEXT: Index: 4
|
||||
// CHECK-NEXT: Name: .symtab
|
||||
|
||||
// CHECK: Name: .Llocal
|
||||
// CHECK-NEXT: Value:
|
||||
// CHECK-NEXT: Size:
|
||||
// CHECK-NEXT: Binding:
|
||||
// CHECK-NEXT: Type:
|
||||
// CHECK-NEXT: Other:
|
||||
// CHECK-NEXT: Section:
|
||||
// CHECK-NEXT: }
|
||||
// CHECK-NEXT: Symbol {
|
||||
// CHECK-NEXT: Name: local
|
||||
// CHECK-NEXT: Value:
|
||||
// CHECK-NEXT: Size:
|
||||
// CHECK-NEXT: Binding:
|
||||
// CHECK-NEXT: Type:
|
||||
// CHECK-NEXT: Other:
|
||||
// CHECK-NEXT: Section:
|
||||
// CHECK-NEXT: }
|
||||
// CHECK-NEXT: Symbol {
|
||||
// CHECK-NEXT: Name: g1
|
||||
// CHECK-NEXT: Value:
|
||||
// CHECK-NEXT: Size:
|
||||
// CHECK-NEXT: Binding:
|
||||
// CHECK-NEXT: Type:
|
||||
// CHECK-NEXT: Other:
|
||||
// CHECK-NEXT: Section:
|
||||
// CHECK-NEXT: }
|
||||
// CHECK-NEXT: Symbol {
|
||||
// CHECK-NEXT: Name: g2
|
||||
// CHECK-NEXT: Value:
|
||||
// CHECK-NEXT: Size:
|
||||
// CHECK-NEXT: Binding:
|
||||
// CHECK-NEXT: Type:
|
||||
// CHECK-NEXT: Other:
|
||||
// CHECK-NEXT: Section:
|
||||
// CHECK-NEXT: }
|
||||
// CHECK-NEXT: Symbol {
|
||||
// CHECK-NEXT: Name: g3
|
||||
|
||||
// CHECK: Addrsig [
|
||||
// CHECK-NEXT: Sym: g1 (3)
|
||||
// CHECK-NEXT: Sym: g3 (5)
|
||||
// CHECK-NEXT: Sym: local (2)
|
||||
// CHECK-NEXT: Sym: .Llocal (1)
|
||||
// CHECK-NEXT: ]
|
||||
|
||||
// ASM: .addrsig
|
||||
.addrsig
|
||||
// ASM: .addrsig_sym g1
|
||||
.addrsig_sym g1
|
||||
.globl g2
|
||||
// ASM: .addrsig_sym g3
|
||||
.addrsig_sym g3
|
||||
// ASM: .addrsig_sym local
|
||||
.addrsig_sym local
|
||||
// ASM: .addrsig_sym .Llocal
|
||||
.addrsig_sym .Llocal
|
||||
|
||||
local:
|
||||
.Llocal:
|
||||
|
||||
// DWO-NOT: .llvm_addrsig
|
@ -44,6 +44,7 @@
|
||||
#include "llvm/Support/ErrorHandling.h"
|
||||
#include "llvm/Support/Format.h"
|
||||
#include "llvm/Support/FormattedStream.h"
|
||||
#include "llvm/Support/LEB128.h"
|
||||
#include "llvm/Support/MathExtras.h"
|
||||
#include "llvm/Support/MipsABIFlags.h"
|
||||
#include "llvm/Support/ScopedPrinter.h"
|
||||
@ -170,6 +171,7 @@ public:
|
||||
void printHashHistogram() override;
|
||||
|
||||
void printCGProfile() override;
|
||||
void printAddrsig() override;
|
||||
|
||||
void printNotes() override;
|
||||
|
||||
@ -219,6 +221,7 @@ private:
|
||||
const Elf_GnuHash *GnuHashTable = nullptr;
|
||||
const Elf_Shdr *DotSymtabSec = nullptr;
|
||||
const Elf_Shdr *DotCGProfileSec = nullptr;
|
||||
const Elf_Shdr *DotAddrsigSec = nullptr;
|
||||
StringRef DynSymtabName;
|
||||
ArrayRef<Elf_Word> ShndxTable;
|
||||
|
||||
@ -272,6 +275,7 @@ public:
|
||||
void printSymbolsHelper(bool IsDynamic) const;
|
||||
const Elf_Shdr *getDotSymtabSec() const { return DotSymtabSec; }
|
||||
const Elf_Shdr *getDotCGProfileSec() const { return DotCGProfileSec; }
|
||||
const Elf_Shdr *getDotAddrsigSec() const { return DotAddrsigSec; }
|
||||
ArrayRef<Elf_Word> getShndxTable() const { return ShndxTable; }
|
||||
StringRef getDynamicStringTable() const { return DynamicStringTable; }
|
||||
const DynRegionInfo &getDynRelRegion() const { return DynRelRegion; }
|
||||
@ -352,6 +356,7 @@ public:
|
||||
StringRef SectionName) = 0;
|
||||
virtual void printHashHistogram(const ELFFile<ELFT> *Obj) = 0;
|
||||
virtual void printCGProfile(const ELFFile<ELFT> *Obj) = 0;
|
||||
virtual void printAddrsig(const ELFFile<ELFT> *Obj) = 0;
|
||||
virtual void printNotes(const ELFFile<ELFT> *Obj) = 0;
|
||||
virtual void printELFLinkerOptions(const ELFFile<ELFT> *Obj) = 0;
|
||||
virtual void printMipsGOT(const MipsGOTParser<ELFT> &Parser) = 0;
|
||||
@ -384,6 +389,7 @@ public:
|
||||
void printSectionAsString(const ELFO *Obj, StringRef SectionName) override;
|
||||
void printHashHistogram(const ELFFile<ELFT> *Obj) override;
|
||||
void printCGProfile(const ELFFile<ELFT> *Obj) override;
|
||||
void printAddrsig(const ELFFile<ELFT> *Obj) override;
|
||||
void printNotes(const ELFFile<ELFT> *Obj) override;
|
||||
void printELFLinkerOptions(const ELFFile<ELFT> *Obj) override;
|
||||
void printMipsGOT(const MipsGOTParser<ELFT> &Parser) override;
|
||||
@ -448,6 +454,7 @@ public:
|
||||
void printSectionAsString(const ELFO *Obj, StringRef SectionName) override;
|
||||
void printHashHistogram(const ELFFile<ELFT> *Obj) override;
|
||||
void printCGProfile(const ELFFile<ELFT> *Obj) override;
|
||||
void printAddrsig(const ELFFile<ELFT> *Obj) override;
|
||||
void printNotes(const ELFFile<ELFT> *Obj) override;
|
||||
void printELFLinkerOptions(const ELFFile<ELFT> *Obj) override;
|
||||
void printMipsGOT(const MipsGOTParser<ELFT> &Parser) override;
|
||||
@ -1441,6 +1448,12 @@ ELFDumper<ELFT>::ELFDumper(const ELFFile<ELFT> *Obj, ScopedPrinter &Writer)
|
||||
if (DotCGProfileSec != nullptr)
|
||||
reportError("Multiple .note.llvm.cgprofile");
|
||||
DotCGProfileSec = &Sec;
|
||||
break;
|
||||
case ELF::SHT_LLVM_ADDRSIG:
|
||||
if (DotAddrsigSec != nullptr)
|
||||
reportError("Multiple .llvm_addrsig");
|
||||
DotAddrsigSec = &Sec;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@ -2460,6 +2473,10 @@ template <class ELFT> void ELFDumper<ELFT>::printGroupSections() {
|
||||
ELFDumperStyle->printGroupSections(Obj);
|
||||
}
|
||||
|
||||
template <class ELFT> void ELFDumper<ELFT>::printAddrsig() {
|
||||
ELFDumperStyle->printAddrsig(Obj);
|
||||
}
|
||||
|
||||
static inline void printFields(formatted_raw_ostream &OS, StringRef Str1,
|
||||
StringRef Str2) {
|
||||
OS.PadToColumn(2u);
|
||||
@ -2840,6 +2857,8 @@ std::string getSectionTypeString(unsigned Arch, unsigned Type) {
|
||||
return "LLVM_LINKER_OPTIONS";
|
||||
case SHT_LLVM_CALL_GRAPH_PROFILE:
|
||||
return "LLVM_CALL_GRAPH_PROFILE";
|
||||
case SHT_LLVM_ADDRSIG:
|
||||
return "LLVM_ADDRSIG";
|
||||
// FIXME: Parse processor specific GNU attributes
|
||||
case SHT_GNU_ATTRIBUTES:
|
||||
return "ATTRIBUTES";
|
||||
@ -3541,6 +3560,11 @@ void GNUStyle<ELFT>::printCGProfile(const ELFFile<ELFT> *Obj) {
|
||||
OS << "GNUStyle::printCGProfile not implemented\n";
|
||||
}
|
||||
|
||||
template <class ELFT>
|
||||
void GNUStyle<ELFT>::printAddrsig(const ELFFile<ELFT> *Obj) {
|
||||
OS << "GNUStyle::printAddrsig not implemented\n";
|
||||
}
|
||||
|
||||
static std::string getGNUNoteTypeName(const uint32_t NT) {
|
||||
static const struct {
|
||||
uint32_t ID;
|
||||
@ -4407,6 +4431,27 @@ void LLVMStyle<ELFT>::printCGProfile(const ELFFile<ELFT> *Obj) {
|
||||
}
|
||||
}
|
||||
|
||||
template <class ELFT>
|
||||
void LLVMStyle<ELFT>::printAddrsig(const ELFFile<ELFT> *Obj) {
|
||||
ListScope L(W, "Addrsig");
|
||||
if (!this->dumper()->getDotAddrsigSec())
|
||||
return;
|
||||
ArrayRef<uint8_t> Contents = unwrapOrError(
|
||||
Obj->getSectionContents(this->dumper()->getDotAddrsigSec()));
|
||||
const uint8_t *Cur = Contents.begin();
|
||||
const uint8_t *End = Contents.end();
|
||||
while (Cur != End) {
|
||||
unsigned Size;
|
||||
const char *Err;
|
||||
uint64_t SymIndex = decodeULEB128(Cur, &Size, Contents.end(), &Err);
|
||||
if (Err)
|
||||
reportError(Err);
|
||||
W.printNumber("Sym", this->dumper()->getStaticSymbolName(SymIndex),
|
||||
SymIndex);
|
||||
Cur += Size;
|
||||
}
|
||||
}
|
||||
|
||||
template <class ELFT>
|
||||
void LLVMStyle<ELFT>::printNotes(const ELFFile<ELFT> *Obj) {
|
||||
W.startLine() << "printNotes not implemented!\n";
|
||||
|
@ -52,6 +52,7 @@ public:
|
||||
virtual void printGroupSections() {}
|
||||
virtual void printHashHistogram() {}
|
||||
virtual void printCGProfile() {}
|
||||
virtual void printAddrsig() {}
|
||||
virtual void printNotes() {}
|
||||
virtual void printELFLinkerOptions() {}
|
||||
|
||||
|
@ -302,6 +302,9 @@ namespace opts {
|
||||
|
||||
cl::opt<bool> CGProfile("elf-cg-profile", cl::desc("Display callgraph profile section"));
|
||||
|
||||
cl::opt<bool> Addrsig("elf-addrsig",
|
||||
cl::desc("Display address-significance table"));
|
||||
|
||||
cl::opt<OutputStyleTy>
|
||||
Output("elf-output-style", cl::desc("Specify ELF dump style"),
|
||||
cl::values(clEnumVal(LLVM, "LLVM default style"),
|
||||
@ -469,6 +472,8 @@ static void dumpObject(const ObjectFile *Obj, ScopedPrinter &Writer) {
|
||||
Dumper->printHashHistogram();
|
||||
if (opts::CGProfile)
|
||||
Dumper->printCGProfile();
|
||||
if (opts::Addrsig)
|
||||
Dumper->printAddrsig();
|
||||
if (opts::Notes)
|
||||
Dumper->printNotes();
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user