summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--llvm/lib/MC/WinCOFFObjectWriter.cpp35
-rw-r--r--llvm/test/MC/COFF/addrsig.s51
-rw-r--r--llvm/test/MC/ELF/addrsig.s4
-rw-r--r--llvm/tools/llvm-readobj/COFFDumper.cpp45
-rw-r--r--llvm/tools/llvm-readobj/llvm-readobj.cpp4
5 files changed, 136 insertions, 3 deletions
diff --git a/llvm/lib/MC/WinCOFFObjectWriter.cpp b/llvm/lib/MC/WinCOFFObjectWriter.cpp
index 4f6103c6d68..82c9fe76758 100644
--- a/llvm/lib/MC/WinCOFFObjectWriter.cpp
+++ b/llvm/lib/MC/WinCOFFObjectWriter.cpp
@@ -36,6 +36,7 @@
#include "llvm/Support/Endian.h"
#include "llvm/Support/ErrorHandling.h"
#include "llvm/Support/JamCRC.h"
+#include "llvm/Support/LEB128.h"
#include "llvm/Support/MathExtras.h"
#include "llvm/Support/raw_ostream.h"
#include <algorithm>
@@ -145,6 +146,10 @@ public:
bool UseBigObj;
+ bool EmitAddrsigSection = false;
+ MCSectionCOFF *AddrsigSection;
+ std::vector<const MCSymbol *> AddrsigSyms;
+
WinCOFFObjectWriter(std::unique_ptr<MCWinCOFFObjectTargetWriter> MOTW,
raw_pwrite_stream &OS);
@@ -204,6 +209,11 @@ public:
void assignSectionNumbers();
void assignFileOffsets(MCAssembler &Asm, const MCAsmLayout &Layout);
+ void emitAddrsigSection() override { EmitAddrsigSection = true; }
+ void addAddrsigSymbol(const MCSymbol *Sym) override {
+ AddrsigSyms.push_back(Sym);
+ }
+
uint64_t writeObject(MCAssembler &Asm, const MCAsmLayout &Layout) override;
};
@@ -657,6 +667,13 @@ void WinCOFFObjectWriter::writeSection(MCAssembler &Asm,
void WinCOFFObjectWriter::executePostLayoutBinding(MCAssembler &Asm,
const MCAsmLayout &Layout) {
+ if (EmitAddrsigSection) {
+ AddrsigSection = Asm.getContext().getCOFFSection(
+ ".llvm_addrsig", COFF::IMAGE_SCN_LNK_REMOVE,
+ SectionKind::getMetadata());
+ Asm.registerSection(*AddrsigSection);
+ }
+
// "Define" each section & symbol. This creates section & symbol
// entries in the staging area.
for (const auto &Section : Asm)
@@ -1024,6 +1041,24 @@ uint64_t WinCOFFObjectWriter::writeObject(MCAssembler &Asm,
Section->Symbol->Aux[0].Aux.SectionDefinition.Number = AssocSec->Number;
}
+ // Create the contents of the .llvm_addrsig section.
+ if (EmitAddrsigSection) {
+ auto Frag = new MCDataFragment(AddrsigSection);
+ raw_svector_ostream OS(Frag->getContents());
+ for (const MCSymbol *S : AddrsigSyms) {
+ if (!S->isTemporary()) {
+ encodeULEB128(S->getIndex(), OS);
+ continue;
+ }
+
+ MCSection *TargetSection = &S->getSection();
+ assert(SectionMap.find(TargetSection) != SectionMap.end() &&
+ "Section must already have been defined in "
+ "executePostLayoutBinding!");
+ encodeULEB128(SectionMap[TargetSection]->Symbol->getIndex(), OS);
+ }
+ }
+
assignFileOffsets(Asm, Layout);
// MS LINK expects to be able to use this timestamp to implement their
diff --git a/llvm/test/MC/COFF/addrsig.s b/llvm/test/MC/COFF/addrsig.s
new file mode 100644
index 00000000000..815102ed88f
--- /dev/null
+++ b/llvm/test/MC/COFF/addrsig.s
@@ -0,0 +1,51 @@
+// RUN: llvm-mc -filetype=obj -triple x86_64-pc-win32 %s -o - | llvm-readobj -s -t -sd -addrsig | FileCheck %s
+
+// CHECK: Name: .llvm_addrsig
+// CHECK-NEXT: VirtualSize: 0x0
+// CHECK-NEXT: VirtualAddress: 0x0
+// CHECK-NEXT: RawDataSize: 4
+// CHECK-NEXT: PointerToRawData:
+// CHECK-NEXT: PointerToRelocations: 0x0
+// CHECK-NEXT: PointerToLineNumbers: 0x0
+// CHECK-NEXT: RelocationCount: 0
+// CHECK-NEXT: LineNumberCount: 0
+// CHECK-NEXT: Characteristics [ (0x100800)
+// CHECK-NEXT: IMAGE_SCN_ALIGN_1BYTES (0x100000)
+// CHECK-NEXT: IMAGE_SCN_LNK_REMOVE (0x800)
+// CHECK-NEXT: ]
+// CHECK-NEXT: SectionData (
+// CHECK-NEXT: 0000: 080A0B02
+// CHECK-NEXT: )
+
+// CHECK: Symbols [
+// CHECK: Name: .text
+// CHECK: AuxSectionDef
+// CHECK: Name: .data
+// CHECK: AuxSectionDef
+// CHECK: Name: .bss
+// CHECK: AuxSectionDef
+// CHECK: Name: .llvm_addrsig
+// CHECK: AuxSectionDef
+// CHECK: Name: g1
+// CHECK: Name: g2
+// CHECK: Name: g3
+// CHECK: Name: local
+
+// CHECK: Addrsig [
+// CHECK-NEXT: Sym: g1 (8)
+// CHECK-NEXT: Sym: g3 (10)
+// CHECK-NEXT: Sym: local (11)
+// CHECK-NEXT: Sym: .data (2)
+// CHECK-NEXT: ]
+
+.addrsig
+.addrsig_sym g1
+.globl g2
+.addrsig_sym g3
+.addrsig_sym local
+.addrsig_sym .Llocal
+
+local:
+
+.data
+.Llocal:
diff --git a/llvm/test/MC/ELF/addrsig.s b/llvm/test/MC/ELF/addrsig.s
index 0587ad302fd..9e626c889f2 100644
--- a/llvm/test/MC/ELF/addrsig.s
+++ b/llvm/test/MC/ELF/addrsig.s
@@ -1,6 +1,6 @@
// 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-mc -filetype=obj -triple x86_64-pc-linux-gnu %s -o - | llvm-readobj -s -t -sd -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 -addrsig | FileCheck %s
// RUN: llvm-readobj -s %t.dwo | FileCheck --check-prefix=DWO %s
// CHECK: Name: .llvm_addrsig
diff --git a/llvm/tools/llvm-readobj/COFFDumper.cpp b/llvm/tools/llvm-readobj/COFFDumper.cpp
index 0ed4ccd09f6..c0579d63dff 100644
--- a/llvm/tools/llvm-readobj/COFFDumper.cpp
+++ b/llvm/tools/llvm-readobj/COFFDumper.cpp
@@ -50,6 +50,7 @@
#include "llvm/Support/ConvertUTF.h"
#include "llvm/Support/FormatVariadic.h"
#include "llvm/Support/ScopedPrinter.h"
+#include "llvm/Support/LEB128.h"
#include "llvm/Support/Win64EH.h"
#include "llvm/Support/raw_ostream.h"
@@ -98,6 +99,7 @@ public:
mergeCodeViewTypes(llvm::codeview::MergingTypeTableBuilder &CVIDs,
llvm::codeview::MergingTypeTableBuilder &CVTypes) override;
void printStackMap() const override;
+ void printAddrsig() override;
private:
void printSymbol(const SymbolRef &Sym);
void printRelocation(const SectionRef &Section, const RelocationRef &Reloc,
@@ -1830,6 +1832,49 @@ void COFFDumper::printStackMap() const {
StackMapV2Parser<support::big>(StackMapContentsArray));
}
+void COFFDumper::printAddrsig() {
+ object::SectionRef AddrsigSection;
+ for (auto Sec : Obj->sections()) {
+ StringRef Name;
+ Sec.getName(Name);
+ if (Name == ".llvm_addrsig") {
+ AddrsigSection = Sec;
+ break;
+ }
+ }
+
+ if (AddrsigSection == object::SectionRef())
+ return;
+
+ StringRef AddrsigContents;
+ AddrsigSection.getContents(AddrsigContents);
+ ArrayRef<uint8_t> AddrsigContentsArray(
+ reinterpret_cast<const uint8_t*>(AddrsigContents.data()),
+ AddrsigContents.size());
+
+ ListScope L(W, "Addrsig");
+ auto *Cur = reinterpret_cast<const uint8_t *>(AddrsigContents.begin());
+ auto *End = reinterpret_cast<const uint8_t *>(AddrsigContents.end());
+ while (Cur != End) {
+ unsigned Size;
+ const char *Err;
+ uint64_t SymIndex = decodeULEB128(Cur, &Size, End, &Err);
+ if (Err)
+ reportError(Err);
+
+ Expected<COFFSymbolRef> Sym = Obj->getSymbol(SymIndex);
+ StringRef SymName;
+ std::error_code EC = errorToErrorCode(Sym.takeError());
+ if (EC || (EC = Obj->getSymbolName(*Sym, SymName))) {
+ SymName = "";
+ error(EC);
+ }
+
+ W.printNumber("Sym", SymName, SymIndex);
+ Cur += Size;
+ }
+}
+
void llvm::dumpCodeViewMergedTypes(
ScopedPrinter &Writer, llvm::codeview::MergingTypeTableBuilder &IDTable,
llvm::codeview::MergingTypeTableBuilder &CVTypes) {
diff --git a/llvm/tools/llvm-readobj/llvm-readobj.cpp b/llvm/tools/llvm-readobj/llvm-readobj.cpp
index a7236c02b8a..70e925fc81c 100644
--- a/llvm/tools/llvm-readobj/llvm-readobj.cpp
+++ b/llvm/tools/llvm-readobj/llvm-readobj.cpp
@@ -302,7 +302,7 @@ namespace opts {
cl::opt<bool> CGProfile("elf-cg-profile", cl::desc("Display callgraph profile section"));
- cl::opt<bool> Addrsig("elf-addrsig",
+ cl::opt<bool> Addrsig("addrsig",
cl::desc("Display address-significance table"));
cl::opt<OutputStyleTy>
@@ -492,6 +492,8 @@ static void dumpObject(const ObjectFile *Obj, ScopedPrinter &Writer) {
Dumper->printCOFFResources();
if (opts::COFFLoadConfig)
Dumper->printCOFFLoadConfig();
+ if (opts::Addrsig)
+ Dumper->printAddrsig();
if (opts::CodeView)
Dumper->printCodeViewDebugInfo();
if (opts::CodeViewMergedTypes)
OpenPOWER on IntegriCloud