MC: Teach the COFF object writer to write address-significance tables.
The format is the same as in ELF: a sequence of ULEB128-encoded symbol indexes. Differential Revision: https://reviews.llvm.org/D51047 llvm-svn: 340499
This commit is contained in:
parent
a2761e437f
commit
bc3089f45f
|
@ -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
|
||||
|
|
|
@ -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:
|
|
@ -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
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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)
|
||||
|
|
Loading…
Reference in New Issue