From 51bb529b5b06d1abbf7e6520893dcec0300749c4 Mon Sep 17 00:00:00 2001 From: Reid Kleckner Date: Thu, 14 Jan 2016 17:51:54 +0000 Subject: [PATCH] [codeview] Print relocations against code and data offset fields These fields are almost always zero. However, there are relocations against them, and we should print the relocation symbol with it as SYM+0xNN. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@257776 91177308-0d34-0410-b5e6-96231b3b80d8 --- tools/llvm-readobj/COFFDumper.cpp | 138 +++++++++++++++++--------------------- tools/llvm-readobj/StreamWriter.h | 5 ++ 2 files changed, 67 insertions(+), 76 deletions(-) diff --git a/tools/llvm-readobj/COFFDumper.cpp b/tools/llvm-readobj/COFFDumper.cpp index 05bcf1124f2..fcc17adfc97 100644 --- a/tools/llvm-readobj/COFFDumper.cpp +++ b/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 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(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 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(&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(&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(&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(&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(&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(&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(&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/tools/llvm-readobj/StreamWriter.h b/tools/llvm-readobj/StreamWriter.h index a255fe5fa19..809a09a2cd4 100644 --- a/tools/llvm-readobj/StreamWriter.h +++ b/tools/llvm-readobj/StreamWriter.h @@ -224,6 +224,11 @@ public: startLine() << Label << ": " << Str << " (" << hex(Value) << ")\n"; } + template + void printSymbolOffset(StringRef Label, StringRef Symbol, T Value) { + startLine() << Label << ": " << Symbol << '+' << hex(Value) << '\n'; + } + void printString(StringRef Label, StringRef Value) { startLine() << Label << ": " << Value << "\n"; } -- 2.11.0