[llvm] 4750a8b - Reapply [llvm-readobj] [ARMWinEH] Fix handling of relocations and symbol offsets

Martin Storsjö via llvm-commits llvm-commits at lists.llvm.org
Thu Apr 29 23:51:30 PDT 2021


Author: Martin Storsjö
Date: 2021-04-30T09:51:23+03:00
New Revision: 4750a8b1bcded31ba15d21b14530882092a9d5cc

URL: https://github.com/llvm/llvm-project/commit/4750a8b1bcded31ba15d21b14530882092a9d5cc
DIFF: https://github.com/llvm/llvm-project/commit/4750a8b1bcded31ba15d21b14530882092a9d5cc.diff

LOG: Reapply [llvm-readobj] [ARMWinEH] Fix handling of relocations and symbol offsets

When looking up data referenced from pdata/xdata structures, the
referenced data can be found in two different ways:
- For an unrelocated object file, it's located via a relocation
- For a relocated, linked image, the data is referenced with an
  (image relative) absolute address

For the latter case, the absolute address can optionally be
described with a symbol.

For the case of an object file, there's two offsets involved; one
immediate offset encoded in the data location that is modified by
the relocation, and a section offset in the symbol.

Previously, for the ExceptionRecord field, we printed the offset
from the symbol (only) but used the immediate offset ignoring
the symbol's address (using only the symbol's section) for printing
the exception data.

Add a helper method for doing the lookup and address calculation,
for simplifying the calling code and making all the cases consistent.

This addresses an existing FIXME comment, fixing printing of the
exception data for cases where relocations point at individual
symbols in the xdata section (which is what MSVC generates) instead of
all relocations pointing at the start of the xdata section (which is
what LLVM generates).

This also fixes printing of the function name for packed entries in
linked images.

Relanded with a format string fix in the formatSymbol function; one
can't use %X as format string for an uint64_t. That bug has been
present since this code was added in e6971cab306cd.

Differential Revision: https://reviews.llvm.org/D100305

Added: 
    llvm/test/tools/llvm-readobj/COFF/arm64-packed-symbol-name.yaml
    llvm/test/tools/llvm-readobj/COFF/arm64-unwind-reference.yaml

Modified: 
    llvm/tools/llvm-readobj/ARMWinEHPrinter.cpp
    llvm/tools/llvm-readobj/ARMWinEHPrinter.h

Removed: 
    


################################################################################
diff  --git a/llvm/test/tools/llvm-readobj/COFF/arm64-packed-symbol-name.yaml b/llvm/test/tools/llvm-readobj/COFF/arm64-packed-symbol-name.yaml
new file mode 100644
index 0000000000000..af2bd8aa9a097
--- /dev/null
+++ b/llvm/test/tools/llvm-readobj/COFF/arm64-packed-symbol-name.yaml
@@ -0,0 +1,59 @@
+# Check that we resolve the function name properly
+
+# RUN: yaml2obj %s -o %t.obj
+# RUN: llvm-readobj --unwind %t.obj | FileCheck %s
+
+# CHECK: Function: entry (0x140001000)
+
+--- !COFF
+OptionalHeader:
+  AddressOfEntryPoint: 4096
+  ImageBase:       5368709120
+  SectionAlignment: 4096
+  FileAlignment:   512
+  MajorOperatingSystemVersion: 6
+  MinorOperatingSystemVersion: 0
+  MajorImageVersion: 0
+  MinorImageVersion: 0
+  MajorSubsystemVersion: 6
+  MinorSubsystemVersion: 0
+  Subsystem:       IMAGE_SUBSYSTEM_WINDOWS_CUI
+  DLLCharacteristics: [ IMAGE_DLL_CHARACTERISTICS_HIGH_ENTROPY_VA, IMAGE_DLL_CHARACTERISTICS_DYNAMIC_BASE, IMAGE_DLL_CHARACTERISTICS_NX_COMPAT, IMAGE_DLL_CHARACTERISTICS_TERMINAL_SERVER_AWARE ]
+  SizeOfStackReserve: 1048576
+  SizeOfStackCommit: 4096
+  SizeOfHeapReserve: 1048576
+  SizeOfHeapCommit: 4096
+header:
+  Machine:         IMAGE_FILE_MACHINE_ARM64
+  Characteristics: [ IMAGE_FILE_EXECUTABLE_IMAGE, IMAGE_FILE_LARGE_ADDRESS_AWARE ]
+sections:
+  - Name:            .text
+    Characteristics: [ IMAGE_SCN_CNT_CODE, IMAGE_SCN_MEM_EXECUTE, IMAGE_SCN_MEM_READ ]
+    VirtualAddress:  4096
+    VirtualSize:     20
+    SectionData:     FD7BBFA9FD0300911F2003D5FD7BC1A8C0035FD6
+  - Name:            .pdata
+    Characteristics: [ IMAGE_SCN_CNT_INITIALIZED_DATA, IMAGE_SCN_MEM_READ ]
+    VirtualAddress:  8192
+    VirtualSize:     8
+    SectionData:     '001000001500E000'
+symbols:
+  - Name:            .text
+    Value:           0
+    SectionNumber:   1
+    SimpleType:      IMAGE_SYM_TYPE_NULL
+    ComplexType:     IMAGE_SYM_DTYPE_NULL
+    StorageClass:    IMAGE_SYM_CLASS_STATIC
+  - Name:            .pdata
+    Value:           0
+    SectionNumber:   2
+    SimpleType:      IMAGE_SYM_TYPE_NULL
+    ComplexType:     IMAGE_SYM_DTYPE_NULL
+    StorageClass:    IMAGE_SYM_CLASS_STATIC
+  - Name:            entry
+    Value:           0
+    SectionNumber:   1
+    SimpleType:      IMAGE_SYM_TYPE_NULL
+    ComplexType:     IMAGE_SYM_DTYPE_FUNCTION
+    StorageClass:    IMAGE_SYM_CLASS_EXTERNAL
+...

diff  --git a/llvm/test/tools/llvm-readobj/COFF/arm64-unwind-reference.yaml b/llvm/test/tools/llvm-readobj/COFF/arm64-unwind-reference.yaml
new file mode 100644
index 0000000000000..80a9dfa739436
--- /dev/null
+++ b/llvm/test/tools/llvm-readobj/COFF/arm64-unwind-reference.yaml
@@ -0,0 +1,196 @@
+# Test reading an ExceptionRecord which is referenced in 
diff erent ways:
+# - Relocation against base of .xdata record, immediate offset in .pdata
+#   (what LLVM produces)
+# - Relocation against symbol in .xdata, no immediate offset in .pdata
+#   (what MSVC produces)
+# - Combination of the two above (unlikely to occur in the wild, but for
+#   testing the consistency of the code)
+
+# RUN: yaml2obj %s -o %t.obj
+# RUN: llvm-readobj --unwind %t.obj | FileCheck %s
+
+# CHECK:      UnwindInformation [
+# CHECK-NEXT:   RuntimeFunction {
+# CHECK-NEXT:     Function: func (0x0)
+# CHECK-NEXT:     ExceptionRecord: .xdata (0x0)
+# CHECK-NEXT:     ExceptionData {
+# CHECK-NEXT:       FunctionLength: 4
+# CHECK-NEXT:       Version: 0
+# CHECK-NEXT:       ExceptionData: No
+# CHECK-NEXT:       EpiloguePacked: No
+# CHECK-NEXT:       EpilogueScopes: 0
+# CHECK-NEXT:       ByteCodeLength: 4
+# CHECK-NEXT:       Prologue [
+# CHECK-NEXT:         0xd400              ; str x19, [sp, #-8]!
+# CHECK-NEXT:         0xe4                ; end
+# CHECK-NEXT:       ]
+# CHECK-NEXT:       EpilogueScopes [
+# CHECK-NEXT:       ]
+# CHECK-NEXT:     }
+# CHECK-NEXT:   }
+# CHECK-NEXT:   RuntimeFunction {
+# CHECK-NEXT:     Function: func2 (0x4)
+# CHECK-NEXT:     ExceptionRecord: .xdata +0x8 (0x8)
+# CHECK-NEXT:     ExceptionData {
+# CHECK-NEXT:       FunctionLength: 4
+# CHECK-NEXT:       Version: 0
+# CHECK-NEXT:       ExceptionData: No
+# CHECK-NEXT:       EpiloguePacked: No
+# CHECK-NEXT:       EpilogueScopes: 0
+# CHECK-NEXT:       ByteCodeLength: 4
+# CHECK-NEXT:       Prologue [
+# CHECK-NEXT:         0xdc01              ; str d8, [sp, #8]
+# CHECK-NEXT:         0xe4                ; end
+# CHECK-NEXT:       ]
+# CHECK-NEXT:       EpilogueScopes [
+# CHECK-NEXT:       ]
+# CHECK-NEXT:     }
+# CHECK-NEXT:   }
+# CHECK-NEXT:   RuntimeFunction {
+# CHECK-NEXT:     Function: func3 (0x8)
+# CHECK-NEXT:     ExceptionRecord: func3_xdata (0x10)
+# CHECK-NEXT:     ExceptionData {
+# CHECK-NEXT:       FunctionLength: 4
+# CHECK-NEXT:       Version: 0
+# CHECK-NEXT:       ExceptionData: No
+# CHECK-NEXT:       EpiloguePacked: No
+# CHECK-NEXT:       EpilogueScopes: 0
+# CHECK-NEXT:       ByteCodeLength: 4
+# CHECK-NEXT:       Prologue [
+# CHECK-NEXT:         0xe1                ; mov fp, sp
+# CHECK-NEXT:         0xe4                ; end
+# CHECK-NEXT:       ]
+# CHECK-NEXT:       EpilogueScopes [
+# CHECK-NEXT:       ]
+# CHECK-NEXT:     }
+# CHECK-NEXT:   }
+# CHECK-NEXT:   RuntimeFunction {
+# CHECK-NEXT:     Function: func4 (0xC)
+# CHECK-NEXT:     ExceptionRecord: func3_xdata +0x8 (0x18)
+# CHECK-NEXT:     ExceptionData {
+# CHECK-NEXT:       FunctionLength: 4
+# CHECK-NEXT:       Version: 0
+# CHECK-NEXT:       ExceptionData: No
+# CHECK-NEXT:       EpiloguePacked: No
+# CHECK-NEXT:       EpilogueScopes: 0
+# CHECK-NEXT:       ByteCodeLength: 4
+# CHECK-NEXT:       Prologue [
+# CHECK-NEXT:         0x81                ; stp x29, x30, [sp, #-16]!
+# CHECK-NEXT:         0xe4                ; end
+# CHECK-NEXT:       ]
+# CHECK-NEXT:       EpilogueScopes [
+# CHECK-NEXT:       ]
+# CHECK-NEXT:     }
+# CHECK-NEXT:   }
+# CHECK-NEXT: ]
+
+--- !COFF
+header:
+  Machine:         IMAGE_FILE_MACHINE_ARM64
+  Characteristics: [  ]
+sections:
+  - Name:            .text
+    Characteristics: [ IMAGE_SCN_CNT_CODE, IMAGE_SCN_MEM_EXECUTE, IMAGE_SCN_MEM_READ ]
+    Alignment:       4
+    SectionData:     F38F1FF8E80700FDFD030091FD7BBFA9
+  - Name:            .xdata
+    Characteristics: [ IMAGE_SCN_CNT_INITIALIZED_DATA, IMAGE_SCN_MEM_READ ]
+    Alignment:       4
+    SectionData:     01000008D400E4E301000008DC01E4E301000008E1E4E3E30100000881E4E3E3
+  - Name:            .pdata
+    Characteristics: [ IMAGE_SCN_CNT_INITIALIZED_DATA, IMAGE_SCN_MEM_READ ]
+    Alignment:       4
+    SectionData:     '0000000000000000000000000800000000000000000000000000000008000000'
+    Relocations:
+      - VirtualAddress:  0
+        SymbolName:      func
+        Type:            IMAGE_REL_ARM64_ADDR32NB
+      - VirtualAddress:  4
+        SymbolName:      .xdata
+        Type:            IMAGE_REL_ARM64_ADDR32NB
+      - VirtualAddress:  8
+        SymbolName:      func2
+        Type:            IMAGE_REL_ARM64_ADDR32NB
+      - VirtualAddress:  12
+        SymbolName:      .xdata
+        Type:            IMAGE_REL_ARM64_ADDR32NB
+      - VirtualAddress:  16
+        SymbolName:      func3
+        Type:            IMAGE_REL_ARM64_ADDR32NB
+      - VirtualAddress:  20
+        SymbolName:      func3_xdata
+        Type:            IMAGE_REL_ARM64_ADDR32NB
+      - VirtualAddress:  24
+        SymbolName:      func4
+        Type:            IMAGE_REL_ARM64_ADDR32NB
+      - VirtualAddress:  28
+        SymbolName:      func3_xdata
+        Type:            IMAGE_REL_ARM64_ADDR32NB
+symbols:
+  - Name:            .text
+    Value:           0
+    SectionNumber:   1
+    SimpleType:      IMAGE_SYM_TYPE_NULL
+    ComplexType:     IMAGE_SYM_DTYPE_NULL
+    StorageClass:    IMAGE_SYM_CLASS_STATIC
+    SectionDefinition:
+      Length:          16
+      NumberOfRelocations: 0
+      NumberOfLinenumbers: 0
+      CheckSum:        2581817939
+      Number:          1
+  - Name:            .xdata
+    Value:           0
+    SectionNumber:   2
+    SimpleType:      IMAGE_SYM_TYPE_NULL
+    ComplexType:     IMAGE_SYM_DTYPE_NULL
+    StorageClass:    IMAGE_SYM_CLASS_STATIC
+    SectionDefinition:
+      Length:          32
+      NumberOfRelocations: 0
+      NumberOfLinenumbers: 0
+      CheckSum:        3086971960
+      Number:          2
+  - Name:            .pdata
+    Value:           0
+    SectionNumber:   3
+    SimpleType:      IMAGE_SYM_TYPE_NULL
+    ComplexType:     IMAGE_SYM_DTYPE_NULL
+    StorageClass:    IMAGE_SYM_CLASS_STATIC
+    SectionDefinition:
+      Length:          32
+      NumberOfRelocations: 8
+      NumberOfLinenumbers: 0
+      CheckSum:        0
+      Number:          3
+  - Name:            func
+    Value:           0
+    SectionNumber:   1
+    SimpleType:      IMAGE_SYM_TYPE_NULL
+    ComplexType:     IMAGE_SYM_DTYPE_NULL
+    StorageClass:    IMAGE_SYM_CLASS_STATIC
+  - Name:            func2
+    Value:           4
+    SectionNumber:   1
+    SimpleType:      IMAGE_SYM_TYPE_NULL
+    ComplexType:     IMAGE_SYM_DTYPE_NULL
+    StorageClass:    IMAGE_SYM_CLASS_STATIC
+  - Name:            func3
+    Value:           8
+    SectionNumber:   1
+    SimpleType:      IMAGE_SYM_TYPE_NULL
+    ComplexType:     IMAGE_SYM_DTYPE_NULL
+    StorageClass:    IMAGE_SYM_CLASS_STATIC
+  - Name:            func4
+    Value:           12
+    SectionNumber:   1
+    SimpleType:      IMAGE_SYM_TYPE_NULL
+    ComplexType:     IMAGE_SYM_DTYPE_NULL
+    StorageClass:    IMAGE_SYM_CLASS_STATIC
+  - Name:            func3_xdata
+    Value:           16
+    SectionNumber:   2
+    SimpleType:      IMAGE_SYM_TYPE_NULL
+    ComplexType:     IMAGE_SYM_DTYPE_NULL
+    StorageClass:    IMAGE_SYM_CLASS_STATIC
+...

diff  --git a/llvm/tools/llvm-readobj/ARMWinEHPrinter.cpp b/llvm/tools/llvm-readobj/ARMWinEHPrinter.cpp
index 3491ea464b5ec..cc9e3d944bbe8 100644
--- a/llvm/tools/llvm-readobj/ARMWinEHPrinter.cpp
+++ b/llvm/tools/llvm-readobj/ARMWinEHPrinter.cpp
@@ -100,7 +100,7 @@ static std::string formatSymbol(StringRef Name, uint64_t Address,
     OS << Name << " ";
 
   if (Offset)
-    OS << format("+0x%X (0x%" PRIX64 ")", Offset, Address);
+    OS << format("+0x%" PRIX64 " (0x%" PRIX64 ")", Offset, Address);
   else if (!Name.empty())
     OS << format("(0x%" PRIX64 ")", Address);
   else
@@ -238,6 +238,41 @@ ErrorOr<SymbolRef> Decoder::getRelocatedSymbol(const COFFObjectFile &,
   return inconvertibleErrorCode();
 }
 
+ErrorOr<SymbolRef> Decoder::getSymbolForLocation(
+    const COFFObjectFile &COFF, const SectionRef &Section,
+    uint64_t OffsetInSection, uint64_t ImmediateOffset, uint64_t &SymbolAddress,
+    uint64_t &SymbolOffset, bool FunctionOnly) {
+  // Try to locate a relocation that points at the offset in the section
+  ErrorOr<SymbolRef> SymOrErr =
+      getRelocatedSymbol(COFF, Section, OffsetInSection);
+  if (SymOrErr) {
+    // We found a relocation symbol; the immediate offset needs to be added
+    // to the symbol address.
+    SymbolOffset = ImmediateOffset;
+
+    Expected<uint64_t> AddressOrErr = SymOrErr->getAddress();
+    if (!AddressOrErr) {
+      std::string Buf;
+      llvm::raw_string_ostream OS(Buf);
+      logAllUnhandledErrors(AddressOrErr.takeError(), OS);
+      OS.flush();
+      report_fatal_error(Buf);
+    }
+    // We apply SymbolOffset here directly. We return it separately to allow
+    // the caller to print it as an offset on the symbol name.
+    SymbolAddress = *AddressOrErr + SymbolOffset;
+  } else {
+    // No matching relocation found; operating on a linked image. Try to
+    // find a descriptive symbol if possible. The immediate offset contains
+    // the image relative address, and we shouldn't add any offset to the
+    // symbol.
+    SymbolAddress = COFF.getImageBase() + ImmediateOffset;
+    SymbolOffset = 0;
+    SymOrErr = getSymbol(COFF, SymbolAddress, FunctionOnly);
+  }
+  return SymOrErr;
+}
+
 bool Decoder::opcode_0xxxxxxx(const uint8_t *OC, unsigned &Offset,
                               unsigned Length, bool Prologue) {
   uint8_t Imm = OC[Offset] & 0x7f;
@@ -919,16 +954,16 @@ bool Decoder::dumpXDataRecord(const COFFObjectFile &COFF,
   }
 
   if (XData.X()) {
-    const uint64_t Address = COFF.getImageBase() + XData.ExceptionHandlerRVA();
     const uint32_t Parameter = XData.ExceptionHandlerParameter();
-    const size_t HandlerOffset = HeaderWords(XData)
-                               + (XData.E() ? 0 : XData.EpilogueCount())
-                               + XData.CodeWords();
-
-    ErrorOr<SymbolRef> Symbol = getRelocatedSymbol(
-        COFF, Section, Offset + HandlerOffset * sizeof(uint32_t));
-    if (!Symbol)
-      Symbol = getSymbol(COFF, Address, /*FunctionOnly=*/true);
+    const size_t HandlerOffset = HeaderWords(XData) +
+                                 (XData.E() ? 0 : XData.EpilogueCount()) +
+                                 XData.CodeWords();
+
+    uint64_t Address, SymbolOffset;
+    ErrorOr<SymbolRef> Symbol = getSymbolForLocation(
+        COFF, Section, Offset + HandlerOffset * sizeof(uint32_t),
+        XData.ExceptionHandlerRVA(), Address, SymbolOffset,
+        /*FunctionOnly=*/true);
     if (!Symbol) {
       ListScope EHS(SW, "ExceptionHandler");
       SW.printHex("Routine", Address);
@@ -946,7 +981,7 @@ bool Decoder::dumpXDataRecord(const COFFObjectFile &COFF,
     }
 
     ListScope EHS(SW, "ExceptionHandler");
-    SW.printString("Routine", formatSymbol(*Name, Address));
+    SW.printString("Routine", formatSymbol(*Name, Address, SymbolOffset));
     SW.printHex("Parameter", Parameter);
   }
 
@@ -959,14 +994,15 @@ bool Decoder::dumpUnpackedEntry(const COFFObjectFile &COFF,
   assert(RF.Flag() == RuntimeFunctionFlag::RFF_Unpacked &&
          "packed entry cannot be treated as an unpacked entry");
 
-  ErrorOr<SymbolRef> Function = getRelocatedSymbol(COFF, Section, Offset);
-  if (!Function)
-    Function = getSymbol(COFF, COFF.getImageBase() + RF.BeginAddress,
-                         /*FunctionOnly=*/true);
+  uint64_t FunctionAddress, FunctionOffset;
+  ErrorOr<SymbolRef> Function = getSymbolForLocation(
+      COFF, Section, Offset, RF.BeginAddress, FunctionAddress, FunctionOffset,
+      /*FunctionOnly=*/true);
 
-  ErrorOr<SymbolRef> XDataRecord = getRelocatedSymbol(COFF, Section, Offset + 4);
-  if (!XDataRecord)
-    XDataRecord = getSymbol(COFF, RF.ExceptionInformationRVA());
+  uint64_t XDataAddress, XDataOffset;
+  ErrorOr<SymbolRef> XDataRecord = getSymbolForLocation(
+      COFF, Section, Offset + 4, RF.ExceptionInformationRVA(), XDataAddress,
+      XDataOffset);
 
   if (!RF.BeginAddress && !Function)
     return false;
@@ -974,7 +1010,6 @@ bool Decoder::dumpUnpackedEntry(const COFFObjectFile &COFF,
     return false;
 
   StringRef FunctionName;
-  uint64_t FunctionAddress;
   if (Function) {
     Expected<StringRef> FunctionNameOrErr = Function->getName();
     if (!FunctionNameOrErr) {
@@ -985,20 +1020,10 @@ bool Decoder::dumpUnpackedEntry(const COFFObjectFile &COFF,
       report_fatal_error(Buf);
     }
     FunctionName = *FunctionNameOrErr;
-    Expected<uint64_t> FunctionAddressOrErr = Function->getAddress();
-    if (!FunctionAddressOrErr) {
-      std::string Buf;
-      llvm::raw_string_ostream OS(Buf);
-      logAllUnhandledErrors(FunctionAddressOrErr.takeError(), OS);
-      OS.flush();
-      report_fatal_error(Buf);
-    }
-    FunctionAddress = *FunctionAddressOrErr;
-  } else {
-    FunctionAddress = COFF.getImageBase() + RF.BeginAddress;
   }
 
-  SW.printString("Function", formatSymbol(FunctionName, FunctionAddress));
+  SW.printString("Function",
+                 formatSymbol(FunctionName, FunctionAddress, FunctionOffset));
 
   if (XDataRecord) {
     Expected<StringRef> Name = XDataRecord->getName();
@@ -1010,17 +1035,8 @@ bool Decoder::dumpUnpackedEntry(const COFFObjectFile &COFF,
       report_fatal_error(Buf);
     }
 
-    Expected<uint64_t> AddressOrErr = XDataRecord->getAddress();
-    if (!AddressOrErr) {
-      std::string Buf;
-      llvm::raw_string_ostream OS(Buf);
-      logAllUnhandledErrors(AddressOrErr.takeError(), OS);
-      OS.flush();
-      report_fatal_error(Buf);
-    }
-    uint64_t Address = *AddressOrErr;
-
-    SW.printString("ExceptionRecord", formatSymbol(*Name, Address));
+    SW.printString("ExceptionRecord",
+                   formatSymbol(*Name, XDataAddress, XDataOffset));
 
     Expected<section_iterator> SIOrErr = XDataRecord->getSection();
     if (!SIOrErr) {
@@ -1030,18 +1046,15 @@ bool Decoder::dumpUnpackedEntry(const COFFObjectFile &COFF,
     }
     section_iterator SI = *SIOrErr;
 
-    // FIXME: Do we need to add an offset from the relocation?
-    return dumpXDataRecord(COFF, *SI, FunctionAddress,
-                           RF.ExceptionInformationRVA());
+    return dumpXDataRecord(COFF, *SI, FunctionAddress, XDataAddress);
   } else {
-    uint64_t Address = COFF.getImageBase() + RF.ExceptionInformationRVA();
-    SW.printString("ExceptionRecord", formatSymbol("", Address));
+    SW.printString("ExceptionRecord", formatSymbol("", XDataAddress));
 
-    ErrorOr<SectionRef> Section = getSectionContaining(COFF, Address);
+    ErrorOr<SectionRef> Section = getSectionContaining(COFF, XDataAddress);
     if (!Section)
       return false;
 
-    return dumpXDataRecord(COFF, *Section, FunctionAddress, Address);
+    return dumpXDataRecord(COFF, *Section, FunctionAddress, XDataAddress);
   }
 }
 
@@ -1052,12 +1065,12 @@ bool Decoder::dumpPackedEntry(const object::COFFObjectFile &COFF,
           RF.Flag() == RuntimeFunctionFlag::RFF_PackedFragment) &&
          "unpacked entry cannot be treated as a packed entry");
 
-  ErrorOr<SymbolRef> Function = getRelocatedSymbol(COFF, Section, Offset);
-  if (!Function)
-    Function = getSymbol(COFF, RF.BeginAddress, /*FunctionOnly=*/true);
+  uint64_t FunctionAddress, FunctionOffset;
+  ErrorOr<SymbolRef> Function = getSymbolForLocation(
+      COFF, Section, Offset, RF.BeginAddress, FunctionAddress, FunctionOffset,
+      /*FunctionOnly=*/true);
 
   StringRef FunctionName;
-  uint64_t FunctionAddress;
   if (Function) {
     Expected<StringRef> FunctionNameOrErr = Function->getName();
     if (!FunctionNameOrErr) {
@@ -1068,20 +1081,10 @@ bool Decoder::dumpPackedEntry(const object::COFFObjectFile &COFF,
       report_fatal_error(Buf);
     }
     FunctionName = *FunctionNameOrErr;
-    Expected<uint64_t> FunctionAddressOrErr = Function->getAddress();
-    if (!FunctionAddressOrErr) {
-      std::string Buf;
-      llvm::raw_string_ostream OS(Buf);
-      logAllUnhandledErrors(FunctionAddressOrErr.takeError(), OS);
-      OS.flush();
-      report_fatal_error(Buf);
-    }
-    FunctionAddress = *FunctionAddressOrErr;
-  } else {
-    FunctionAddress = COFF.getPE32Header()->ImageBase + RF.BeginAddress;
   }
 
-  SW.printString("Function", formatSymbol(FunctionName, FunctionAddress));
+  SW.printString("Function",
+                 formatSymbol(FunctionName, FunctionAddress, FunctionOffset));
   if (!isAArch64)
     SW.printBoolean("Fragment",
                     RF.Flag() == RuntimeFunctionFlag::RFF_PackedFragment);
@@ -1104,12 +1107,12 @@ bool Decoder::dumpPackedARM64Entry(const object::COFFObjectFile &COFF,
           RF.Flag() == RuntimeFunctionFlag::RFF_PackedFragment) &&
          "unpacked entry cannot be treated as a packed entry");
 
-  ErrorOr<SymbolRef> Function = getRelocatedSymbol(COFF, Section, Offset);
-  if (!Function)
-    Function = getSymbol(COFF, RF.BeginAddress, /*FunctionOnly=*/true);
+  uint64_t FunctionAddress, FunctionOffset;
+  ErrorOr<SymbolRef> Function = getSymbolForLocation(
+      COFF, Section, Offset, RF.BeginAddress, FunctionAddress, FunctionOffset,
+      /*FunctionOnly=*/true);
 
   StringRef FunctionName;
-  uint64_t FunctionAddress;
   if (Function) {
     Expected<StringRef> FunctionNameOrErr = Function->getName();
     if (!FunctionNameOrErr) {
@@ -1120,20 +1123,10 @@ bool Decoder::dumpPackedARM64Entry(const object::COFFObjectFile &COFF,
       report_fatal_error(Buf);
     }
     FunctionName = *FunctionNameOrErr;
-    Expected<uint64_t> FunctionAddressOrErr = Function->getAddress();
-    if (!FunctionAddressOrErr) {
-      std::string Buf;
-      llvm::raw_string_ostream OS(Buf);
-      logAllUnhandledErrors(FunctionAddressOrErr.takeError(), OS);
-      OS.flush();
-      report_fatal_error(Buf);
-    }
-    FunctionAddress = *FunctionAddressOrErr;
-  } else {
-    FunctionAddress = COFF.getPE32PlusHeader()->ImageBase + RF.BeginAddress;
   }
 
-  SW.printString("Function", formatSymbol(FunctionName, FunctionAddress));
+  SW.printString("Function",
+                 formatSymbol(FunctionName, FunctionAddress, FunctionOffset));
   SW.printBoolean("Fragment",
                   RF.Flag() == RuntimeFunctionFlag::RFF_PackedFragment);
   SW.printNumber("FunctionLength", RF.FunctionLength());

diff  --git a/llvm/tools/llvm-readobj/ARMWinEHPrinter.h b/llvm/tools/llvm-readobj/ARMWinEHPrinter.h
index 3263841a267bc..7870f97904868 100644
--- a/llvm/tools/llvm-readobj/ARMWinEHPrinter.h
+++ b/llvm/tools/llvm-readobj/ARMWinEHPrinter.h
@@ -146,6 +146,13 @@ class Decoder {
   getRelocatedSymbol(const object::COFFObjectFile &COFF,
                      const object::SectionRef &Section, uint64_t Offset);
 
+  ErrorOr<object::SymbolRef>
+  getSymbolForLocation(const object::COFFObjectFile &COFF,
+                       const object::SectionRef &Section,
+                       uint64_t OffsetInSection, uint64_t ImmediateOffset,
+                       uint64_t &SymbolAddress, uint64_t &SymbolOffset,
+                       bool FunctionOnly = false);
+
   bool dumpXDataRecord(const object::COFFObjectFile &COFF,
                        const object::SectionRef &Section,
                        uint64_t FunctionAddress, uint64_t VA);


        


More information about the llvm-commits mailing list