[llvm] r257776 - [codeview] Print relocations against code and data offset fields

Reid Kleckner via llvm-commits llvm-commits at lists.llvm.org
Thu Jan 14 09:51:54 PST 2016


Author: rnk
Date: Thu Jan 14 11:51:54 2016
New Revision: 257776

URL: http://llvm.org/viewvc/llvm-project?rev=257776&view=rev
Log:
[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.

Modified:
    llvm/trunk/tools/llvm-readobj/COFFDumper.cpp
    llvm/trunk/tools/llvm-readobj/StreamWriter.h

Modified: llvm/trunk/tools/llvm-readobj/COFFDumper.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/llvm-readobj/COFFDumper.cpp?rev=257776&r1=257775&r2=257776&view=diff
==============================================================================
--- llvm/trunk/tools/llvm-readobj/COFFDumper.cpp (original)
+++ llvm/trunk/tools/llvm-readobj/COFFDumper.cpp Thu Jan 14 11:51:54 2016
@@ -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::resolveSymbo
   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::printCodeViewSymbolSect
 
     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
 
 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::printCodeViewSymbolsSub
         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::printCodeViewSymbolsSub
       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::printCodeViewSymbolsSub
       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::printCodeViewSymbolsSub
       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::printCodeViewSymbolsSub
       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::printCodeViewSymbolsSub
       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::printCodeViewSymbolsSub
       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::printCodeViewSymbolsSub
       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);

Modified: llvm/trunk/tools/llvm-readobj/StreamWriter.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/llvm-readobj/StreamWriter.h?rev=257776&r1=257775&r2=257776&view=diff
==============================================================================
--- llvm/trunk/tools/llvm-readobj/StreamWriter.h (original)
+++ llvm/trunk/tools/llvm-readobj/StreamWriter.h Thu Jan 14 11:51:54 2016
@@ -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";
   }




More information about the llvm-commits mailing list