diff options
Diffstat (limited to 'llvm/tools/llvm-readobj/COFFDumper.cpp')
-rw-r--r-- | llvm/tools/llvm-readobj/COFFDumper.cpp | 138 |
1 files changed, 62 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); |