summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--llvm/tools/llvm-readobj/COFFDumper.cpp138
-rw-r--r--llvm/tools/llvm-readobj/StreamWriter.h5
2 files changed, 67 insertions, 76 deletions
diff --git a/llvm/tools/llvm-readobj/COFFDumper.cpp b/llvm/tools/llvm-readobj/COFFDumper.cpp
index 05bcf1124f2..fcc17adfc97 100644
--- a/llvm/tools/llvm-readobj/COFFDumper.cpp
+++ b/llvm/tools/llvm-readobj/COFFDumper.cpp
@@ -88,16 +88,23 @@ private:
void printCodeViewSymbolsSubsection(StringRef Subsection,
const SectionRef &Section,
- uint32_t Offset);
+ StringRef SectionContents);
void printMemberAttributes(MemberAttributes Attrs);
+ void printRelocatedField(StringRef Label, const coff_section *Sec,
+ StringRef SectionContents, const ulittle32_t *Field,
+ StringRef *RelocSym = nullptr);
+
void cacheRelocations();
std::error_code resolveSymbol(const coff_section *Section, uint64_t Offset,
SymbolRef &Sym);
std::error_code resolveSymbolName(const coff_section *Section,
uint64_t Offset, StringRef &Name);
+ std::error_code resolveSymbolName(const coff_section *Section,
+ StringRef SectionContents,
+ const void *RelocPtr, StringRef &Name);
void printImportedSymbols(iterator_range<imported_symbol_iterator> Range);
void printDelayImportedSymbols(
const DelayImportDirectoryEntryRef &I,
@@ -169,6 +176,32 @@ std::error_code COFFDumper::resolveSymbolName(const coff_section *Section,
return std::error_code();
}
+// Helper for when you have a pointer to real data and you want to know about
+// relocations against it.
+std::error_code COFFDumper::resolveSymbolName(const coff_section *Section,
+ StringRef SectionContents,
+ const void *RelocPtr,
+ StringRef &Name) {
+ assert(SectionContents.data() < RelocPtr &&
+ RelocPtr < SectionContents.data() + SectionContents.size() &&
+ "pointer to relocated object is not in section");
+ uint64_t Offset = ptrdiff_t(reinterpret_cast<const char *>(RelocPtr) -
+ SectionContents.data());
+ return resolveSymbolName(Section, Offset, Name);
+}
+
+void COFFDumper::printRelocatedField(StringRef Label, const coff_section *Sec,
+ StringRef SectionContents,
+ const ulittle32_t *Field,
+ StringRef *RelocSym) {
+ StringRef SymStorage;
+ StringRef &Symbol = RelocSym ? *RelocSym : SymStorage;
+ if (!resolveSymbolName(Sec, SectionContents, Field, Symbol))
+ W.printSymbolOffset(Label, Symbol, *Field);
+ else
+ W.printHex(Label, *Field);
+}
+
static const EnumEntry<COFF::MachineTypes> ImageFileMachineType[] = {
LLVM_READOBJ_ENUM_ENT(COFF, IMAGE_FILE_MACHINE_UNKNOWN ),
LLVM_READOBJ_ENUM_ENT(COFF, IMAGE_FILE_MACHINE_AM33 ),
@@ -929,7 +962,7 @@ void COFFDumper::printCodeViewSymbolSection(StringRef SectionName,
switch (ModuleSubstreamKind(SubType)) {
case ModuleSubstreamKind::Symbols:
- printCodeViewSymbolsSubsection(Contents, Section, SectionOffset);
+ printCodeViewSymbolsSubsection(Contents, Section, SectionContents);
break;
case ModuleSubstreamKind::Lines: {
// Holds a PC to file:line table. Some data to parse this subsection is
@@ -1194,10 +1227,12 @@ std::error_code decodeUIntLeaf(StringRef &Data, uint64_t &Num) {
void COFFDumper::printCodeViewSymbolsSubsection(StringRef Subsection,
const SectionRef &Section,
- uint32_t OffsetInSection) {
+ StringRef SectionContents) {
if (Subsection.size() < sizeof(SymRecord))
return error(object_error::parse_failed);
+ const coff_section *Sec = Obj->getCOFFSection(Section);
+
// This holds the remaining data to parse.
StringRef Data = Subsection;
@@ -1225,16 +1260,7 @@ void COFFDumper::printCodeViewSymbolsSubsection(StringRef Subsection,
return error(object_error::parse_failed);
InFunctionScope = true;
- // In a COFF object file, the CodeOffset field is typically zero and has a
- // relocation applied to it. Go and look up the symbol for that
- // relocation.
- ptrdiff_t SecOffsetOfCodeOffset =
- reinterpret_cast<const char *>(&Proc->CodeOffset) - Subsection.data();
StringRef LinkageName;
- error(resolveSymbolName(Obj->getCOFFSection(Section),
- OffsetInSection + SecOffsetOfCodeOffset,
- LinkageName));
-
StringRef DisplayName = SymData.split('\0').first;
W.printHex("PtrParent", Proc->PtrParent);
W.printHex("PtrEnd", Proc->PtrEnd);
@@ -1243,7 +1269,8 @@ void COFFDumper::printCodeViewSymbolsSubsection(StringRef Subsection,
W.printHex("DbgStart", Proc->DbgStart);
W.printHex("DbgEnd", Proc->DbgEnd);
printTypeIndex("FunctionType", Proc->FunctionType);
- W.printHex("CodeOffset", Proc->CodeOffset);
+ printRelocatedField("CodeOffset", Sec, SectionContents, &Proc->CodeOffset,
+ &LinkageName);
W.printHex("Segment", Proc->Segment);
W.printFlags("Flags", Proc->Flags, makeArrayRef(ProcSymFlags));
W.printString("DisplayName", DisplayName);
@@ -1262,21 +1289,13 @@ void COFFDumper::printCodeViewSymbolsSubsection(StringRef Subsection,
const BlockSym *Block;
error(consumeObject(SymData, Block));
- // In a COFF object file, the CodeOffset field is typically zero and has a
- // relocation applied to it. Go and look up the symbol for that
- // relocation.
- ptrdiff_t SecOffsetOfCodeOffset =
- reinterpret_cast<const char *>(&Block->CodeOffset) - Subsection.data();
- StringRef LinkageName;
- error(resolveSymbolName(Obj->getCOFFSection(Section),
- OffsetInSection + SecOffsetOfCodeOffset,
- LinkageName));
-
StringRef BlockName = SymData.split('\0').first;
+ StringRef LinkageName;
W.printHex("PtrParent", Block->PtrParent);
W.printHex("PtrEnd", Block->PtrEnd);
W.printHex("CodeSize", Block->CodeSize);
- W.printHex("CodeOffset", Block->CodeOffset);
+ printRelocatedField("CodeOffset", Sec, SectionContents,
+ &Block->CodeOffset, &LinkageName);
W.printHex("Segment", Block->Segment);
W.printString("BlockName", BlockName);
W.printString("LinkageName", LinkageName);
@@ -1294,18 +1313,10 @@ void COFFDumper::printCodeViewSymbolsSubsection(StringRef Subsection,
const LabelSym *Label;
error(consumeObject(SymData, Label));
- // In a COFF object file, the CodeOffset field is typically zero and has a
- // relocation applied to it. Go and look up the symbol for that
- // relocation.
- ptrdiff_t SecOffsetOfCodeOffset =
- reinterpret_cast<const char *>(&Label->CodeOffset) - Subsection.data();
- StringRef LinkageName;
- error(resolveSymbolName(Obj->getCOFFSection(Section),
- OffsetInSection + SecOffsetOfCodeOffset,
- LinkageName));
-
StringRef DisplayName = SymData.split('\0').first;
- W.printHex("CodeOffset", Label->CodeOffset);
+ StringRef LinkageName;
+ printRelocatedField("CodeOffset", Sec, SectionContents,
+ &Label->CodeOffset, &LinkageName);
W.printHex("Segment", Label->Segment);
W.printHex("Flags", Label->Flags);
W.printFlags("Flags", Label->Flags, makeArrayRef(ProcSymFlags));
@@ -1445,16 +1456,9 @@ void COFFDumper::printCodeViewSymbolsSubsection(StringRef Subsection,
const CallSiteInfoSym *CallSiteInfo;
error(consumeObject(SymData, CallSiteInfo));
- // In a COFF object file, the CodeOffset field is typically zero and has a
- // relocation applied to it. Go and look up the symbol for that
- // relocation.
- ptrdiff_t SecOffsetOfCodeOffset =
- reinterpret_cast<const char *>(&CallSiteInfo->CodeOffset) - Subsection.data();
StringRef LinkageName;
- error(resolveSymbolName(Obj->getCOFFSection(Section),
- OffsetInSection + SecOffsetOfCodeOffset,
- LinkageName));
- W.printHex("CodeOffset", CallSiteInfo->CodeOffset);
+ printRelocatedField("CodeOffset", Sec, SectionContents,
+ &CallSiteInfo->CodeOffset, &LinkageName);
W.printHex("Segment", CallSiteInfo->Segment);
W.printHex("Reserved", CallSiteInfo->Reserved);
printTypeIndex("Type", CallSiteInfo->Type);
@@ -1467,17 +1471,9 @@ void COFFDumper::printCodeViewSymbolsSubsection(StringRef Subsection,
const HeapAllocationSiteSym *HeapAllocationSite;
error(consumeObject(SymData, HeapAllocationSite));
- // In a COFF object file, the CodeOffset field is typically zero and has a
- // relocation applied to it. Go and look up the symbol for that
- // relocation.
- ptrdiff_t SecOffsetOfCodeOffset =
- reinterpret_cast<const char *>(&HeapAllocationSite->CodeOffset) -
- Subsection.data();
StringRef LinkageName;
- error(resolveSymbolName(Obj->getCOFFSection(Section),
- OffsetInSection + SecOffsetOfCodeOffset,
- LinkageName));
- W.printHex("CodeOffset", HeapAllocationSite->CodeOffset);
+ printRelocatedField("CodeOffset", Sec, SectionContents,
+ &HeapAllocationSite->CodeOffset, &LinkageName);
W.printHex("Segment", HeapAllocationSite->Segment);
W.printHex("CallInstructionSize",
HeapAllocationSite->CallInstructionSize);
@@ -1490,7 +1486,10 @@ void COFFDumper::printCodeViewSymbolsSubsection(StringRef Subsection,
DictScope S(W, "FrameCookie");
const FrameCookieSym *FrameCookie;
error(consumeObject(SymData, FrameCookie));
- W.printHex("CodeOffset", FrameCookie->CodeOffset);
+
+ StringRef LinkageName;
+ printRelocatedField("CodeOffset", Sec, SectionContents,
+ &FrameCookie->CodeOffset, &LinkageName);
W.printHex("Register", FrameCookie->Register);
W.printEnum("CookieKind", uint16_t(FrameCookie->CookieKind),
makeArrayRef(FrameCookieKinds));
@@ -1505,39 +1504,26 @@ void COFFDumper::printCodeViewSymbolsSubsection(StringRef Subsection,
const DataSym *Data;
error(consumeObject(SymData, Data));
- // In a COFF object file, the DataOffset field is typically zero and has a
- // relocation applied to it. Go and look up the symbol for that
- // relocation.
- ptrdiff_t SecOffsetOfDataOffset =
- reinterpret_cast<const char *>(&Data->DataOffset) - Subsection.data();
- StringRef LinkageName;
- error(resolveSymbolName(Obj->getCOFFSection(Section),
- OffsetInSection + SecOffsetOfDataOffset,
- LinkageName));
StringRef DisplayName = SymData.split('\0').first;
- W.printHex("DataOffset", Data->DataOffset);
+ StringRef LinkageName;
+ printRelocatedField("DataOffset", Sec, SectionContents, &Data->DataOffset,
+ &LinkageName);
printTypeIndex("Type", Data->Type);
W.printString("DisplayName", DisplayName);
W.printString("LinkageName", LinkageName);
break;
}
+
case S_LTHREAD32:
case S_GTHREAD32: {
DictScope S(W, "ThreadLocalDataSym");
- const DataSym *Data;
+ const ThreadLocalDataSym *Data;
error(consumeObject(SymData, Data));
- // In a COFF object file, the DataOffset field is typically zero and has a
- // relocation applied to it. Go and look up the symbol for that
- // relocation.
- ptrdiff_t SecOffsetOfDataOffset =
- reinterpret_cast<const char *>(&Data->DataOffset) - Subsection.data();
- StringRef LinkageName;
- error(resolveSymbolName(Obj->getCOFFSection(Section),
- OffsetInSection + SecOffsetOfDataOffset,
- LinkageName));
StringRef DisplayName = SymData.split('\0').first;
- W.printHex("DataOffset", Data->DataOffset);
+ StringRef LinkageName;
+ printRelocatedField("DataOffset", Sec, SectionContents, &Data->DataOffset,
+ &LinkageName);
printTypeIndex("Type", Data->Type);
W.printString("DisplayName", DisplayName);
W.printString("LinkageName", LinkageName);
diff --git a/llvm/tools/llvm-readobj/StreamWriter.h b/llvm/tools/llvm-readobj/StreamWriter.h
index a255fe5fa19..809a09a2cd4 100644
--- a/llvm/tools/llvm-readobj/StreamWriter.h
+++ b/llvm/tools/llvm-readobj/StreamWriter.h
@@ -224,6 +224,11 @@ public:
startLine() << Label << ": " << Str << " (" << hex(Value) << ")\n";
}
+ template <typename T>
+ void printSymbolOffset(StringRef Label, StringRef Symbol, T Value) {
+ startLine() << Label << ": " << Symbol << '+' << hex(Value) << '\n';
+ }
+
void printString(StringRef Label, StringRef Value) {
startLine() << Label << ": " << Value << "\n";
}
OpenPOWER on IntegriCloud