[llvm] [llvm-readobj][COFF] Implement --coff-pseudoreloc in llvm-readobj to dump runtime pseudo-relocation records (PR #151816)

Tomohiro Kashiwada via llvm-commits llvm-commits at lists.llvm.org
Sat Aug 2 06:09:48 PDT 2025


https://github.com/kikairoya created https://github.com/llvm/llvm-project/pull/151816

MinGW toolchain uses "runtime pseudo-relocation" mechanism to support auto-importing symbols from DLLs.
There is no commonly used tools for dump the pseudo-relocation records, so we implement that functionality in llvm-readobj.


>From 8fa4896bfc5ef7acf2dd41db824709ae60a932e5 Mon Sep 17 00:00:00 2001
From: kikairoya <kikairoya at gmail.com>
Date: Thu, 31 Jul 2025 21:58:09 +0900
Subject: [PATCH 1/4] implement llvm-readobj --coff-pseudoreloc stub

---
 .../llvm-readobj/COFF/Inputs/pseudoreloc.exe  | Bin 0 -> 4096 bytes
 .../tools/llvm-readobj/COFF/pseudoreloc.test  |  68 ++++++++++++++++++
 llvm/tools/llvm-readobj/COFFDumper.cpp        |   3 +
 llvm/tools/llvm-readobj/ObjDumper.h           |   1 +
 llvm/tools/llvm-readobj/Opts.td               |   3 +
 llvm/tools/llvm-readobj/llvm-readobj.cpp      |   4 ++
 6 files changed, 79 insertions(+)
 create mode 100644 llvm/test/tools/llvm-readobj/COFF/Inputs/pseudoreloc.exe
 create mode 100644 llvm/test/tools/llvm-readobj/COFF/pseudoreloc.test

diff --git a/llvm/test/tools/llvm-readobj/COFF/Inputs/pseudoreloc.exe b/llvm/test/tools/llvm-readobj/COFF/Inputs/pseudoreloc.exe
new file mode 100644
index 0000000000000000000000000000000000000000..d4106e99d96f357920d24b3cb206bedbaccfb17d
GIT binary patch
literal 4096
zcmeHK&ubG=5T1=uQ-7otya?64LJx|tY$}Q;S?cCc*ft?aFJ4|Z&0-cd*|6DQdefUw
z5dQ!V&HvDYco3l=Jy`H4c=12cZ{F^Pr6qduVBC+Loq6BPzI`)1-jA(kW73GI2+6|C
zHfGpk at a2^cWjb0oU45_Fr>m{5Hxz>~cpf at EvFG&rK_uF)2uFS4^@UYyieAuh^);e;
zmB`jE(vg4Ar83cF^!0-Z+EopW0ve^{r%TW*3TAA>e<@*7O}ikHBrcHoN(HL#@Jha)
zc7sq;5Z#5Ii8>L6Nn{W$&kQ>6hy>BK^YoO_BX=C3b)Oj?5a)WP_=0Fx4?9le5FNrz
zAXMBmStgMK9=$#C{EpXo$OOi!;?mkN2bdfecNdQhgo?WYoq<X8Ne^8=*h_Lp4OHBj
zgb=rp`7Ag8;R;Mjrb&w*OOv9~OA}I>w6EI9 at q~m)2iFa}@0}cf$uWNwNT;p_gV!!H
z<K<=yyO`L_mlFFYKtQUy at TGVQTlJ9=8T}Hz*APb5CK~SdD$GK!6Agy$s1v9~NbmSQ
zJ97Nx3aC98|0qCiL6&*X!yeLTTFt|6pWnRu?nv9VMBUoZd7k8$p9+kyw(mn;Kyv(t
z6~GzvCeqf71>=Ts$5`Vtq?sI<jiOQFc8<BNfE-3n$QKfT*Y*NQoc|ra(&kG9UrbVF
zUA3}I#eqACNv+#3;(nM};TKRygy;z at o>DQx9Y{HFy$6pUN!$`6ujfj&`8!b%!X+C!
k+pW#5s;oDwJ626Ls&?(Ev^SeADSz*-Zd(Y+ at rMfh0-HAh+yDRo

literal 0
HcmV?d00001

diff --git a/llvm/test/tools/llvm-readobj/COFF/pseudoreloc.test b/llvm/test/tools/llvm-readobj/COFF/pseudoreloc.test
new file mode 100644
index 0000000000000..9568afca1d924
--- /dev/null
+++ b/llvm/test/tools/llvm-readobj/COFF/pseudoreloc.test
@@ -0,0 +1,68 @@
+RUN: llvm-readobj --coff-pseudoreloc %p/Inputs/pseudoreloc.exe | FileCheck %s
+
+CHECK:      Format: COFF-i386
+CHECK-NEXT: Arch: i386
+CHECK-NEXT: AddressSize: 32bit
+CHECK-NEXT: PseudoReloc [
+CHECK-NEXT: ]
+
+pseudoreloc.exe is generated by following script:
+
+#--- generate.sh
+llvm-mc -triple i386-mingw32 -filetype obj pseudoreloc.dll.s -o pseudoreloc.dll.o
+ld.lld -m i386pe --dll pseudoreloc.dll.o -o pseudoreloc.dll -entry=
+llvm-mc -triple i386-mingw32 -filetype obj pseudoreloc.s -o pseudoreloc.o
+ld.lld -m i386pe pseudoreloc.o pseudoreloc.dll -o pseudoreloc.exe -entry=start
+
+#--- pseudoreloc.dll.s
+    .data
+    .globl _sym1
+_sym1:
+    .long 0x11223344
+    .globl _sym2
+_sym2:
+    .long 0x55667788
+    .section .drectve
+    .ascii " -export:sym1,data "
+    .ascii " -export:sym2,data "
+    .addrsig
+
+#--- pseudoreloc.s
+    .text
+    .globl _start
+_start:
+    mov _local1b, %eax
+    movsb (%eax), %ecx
+    mov _local2, %eax
+    movsb (%eax), %edx
+    mov _local1a, %eax
+    movsb (%eax), %eax
+    add %edx, %eax
+    add %ecx, %eax
+    ret
+
+    .globl __pei386_runtime_relocator
+__pei386_runtime_relocator:
+    mov ___RUNTIME_PSEUDO_RELOC_LIST__, %eax
+    mov ___RUNTIME_PSEUDO_RELOC_LIST_END__, %ecx
+    sub %ecx, %eax
+    ret
+
+    .data
+    .globl  _local1a
+    .p2align 2
+_local1a:
+    .long _sym1+1
+
+    .globl _local2
+    .p2align 2
+_local2:
+    .long _sym2+1
+
+    .globl  _local1b
+    .p2align 2
+_local1b:
+    .long _sym1+3
+
+    .addrsig
+
diff --git a/llvm/tools/llvm-readobj/COFFDumper.cpp b/llvm/tools/llvm-readobj/COFFDumper.cpp
index 96e0a634648e4..3c1317590f539 100644
--- a/llvm/tools/llvm-readobj/COFFDumper.cpp
+++ b/llvm/tools/llvm-readobj/COFFDumper.cpp
@@ -95,6 +95,7 @@ class COFFDumper : public ObjDumper {
   void printCOFFExports() override;
   void printCOFFDirectives() override;
   void printCOFFBaseReloc() override;
+  void printCOFFPseudoReloc() override;
   void printCOFFDebugDirectory() override;
   void printCOFFTLSDirectory() override;
   void printCOFFResources() override;
@@ -2000,6 +2001,8 @@ void COFFDumper::printCOFFBaseReloc() {
   }
 }
 
+void COFFDumper::printCOFFPseudoReloc() { ListScope D(W, "PseudoReloc"); }
+
 void COFFDumper::printCOFFResources() {
   ListScope ResourcesD(W, "Resources");
   for (const SectionRef &S : Obj->sections()) {
diff --git a/llvm/tools/llvm-readobj/ObjDumper.h b/llvm/tools/llvm-readobj/ObjDumper.h
index 1dc29661f7178..a654078a770ff 100644
--- a/llvm/tools/llvm-readobj/ObjDumper.h
+++ b/llvm/tools/llvm-readobj/ObjDumper.h
@@ -146,6 +146,7 @@ class ObjDumper {
   virtual void printCOFFExports() { }
   virtual void printCOFFDirectives() { }
   virtual void printCOFFBaseReloc() { }
+  virtual void printCOFFPseudoReloc() {}
   virtual void printCOFFDebugDirectory() { }
   virtual void printCOFFTLSDirectory() {}
   virtual void printCOFFResources() {}
diff --git a/llvm/tools/llvm-readobj/Opts.td b/llvm/tools/llvm-readobj/Opts.td
index 48d43cc635a4f..d519e34a72983 100644
--- a/llvm/tools/llvm-readobj/Opts.td
+++ b/llvm/tools/llvm-readobj/Opts.td
@@ -82,6 +82,9 @@ def codeview_ghash : FF<"codeview-ghash", "Enable global hashing for CodeView ty
 def codeview_merged_types : FF<"codeview-merged-types", "Display the merged CodeView type stream">, Group<grp_coff>;
 def codeview_subsection_bytes : FF<"codeview-subsection-bytes", "Dump raw contents of codeview debug sections and records">, Group<grp_coff>;
 def coff_basereloc : FF<"coff-basereloc", "Display .reloc section">, Group<grp_coff>;
+def coff_pseudoreloc
+    : FF<"coff-pseudoreloc", "Display runtime pseudo-relocations">,
+      Group<grp_coff>;
 def coff_debug_directory : FF<"coff-debug-directory", "Display debug directory">, Group<grp_coff>;
 def coff_directives : FF<"coff-directives", "Display .drectve section">, Group<grp_coff>;
 def coff_exports : FF<"coff-exports", "Display export table">, Group<grp_coff>;
diff --git a/llvm/tools/llvm-readobj/llvm-readobj.cpp b/llvm/tools/llvm-readobj/llvm-readobj.cpp
index 4c84ed701bb9a..2b34761b2cc6c 100644
--- a/llvm/tools/llvm-readobj/llvm-readobj.cpp
+++ b/llvm/tools/llvm-readobj/llvm-readobj.cpp
@@ -154,6 +154,7 @@ static bool CodeViewEnableGHash;
 static bool CodeViewMergedTypes;
 bool CodeViewSubsectionBytes;
 static bool COFFBaseRelocs;
+static bool COFFPseudoRelocs;
 static bool COFFDebugDirectory;
 static bool COFFDirectives;
 static bool COFFExports;
@@ -305,6 +306,7 @@ static void parseOptions(const opt::InputArgList &Args) {
   opts::CodeViewMergedTypes = Args.hasArg(OPT_codeview_merged_types);
   opts::CodeViewSubsectionBytes = Args.hasArg(OPT_codeview_subsection_bytes);
   opts::COFFBaseRelocs = Args.hasArg(OPT_coff_basereloc);
+  opts::COFFPseudoRelocs = Args.hasArg(OPT_coff_pseudoreloc);
   opts::COFFDebugDirectory = Args.hasArg(OPT_coff_debug_directory);
   opts::COFFDirectives = Args.hasArg(OPT_coff_directives);
   opts::COFFExports = Args.hasArg(OPT_coff_exports);
@@ -492,6 +494,8 @@ static void dumpObject(ObjectFile &Obj, ScopedPrinter &Writer,
       Dumper->printCOFFDirectives();
     if (opts::COFFBaseRelocs)
       Dumper->printCOFFBaseReloc();
+    if (opts::COFFPseudoRelocs)
+      Dumper->printCOFFPseudoReloc();
     if (opts::COFFDebugDirectory)
       Dumper->printCOFFDebugDirectory();
     if (opts::COFFTLSDirectory)

>From 48f4280548ef82826b3e01273cf50a923905b7b5 Mon Sep 17 00:00:00 2001
From: kikairoya <kikairoya at gmail.com>
Date: Wed, 30 Jul 2025 21:34:59 +0900
Subject: [PATCH 2/4] find pseudo-reloc symbols

---
 .../tools/llvm-readobj/COFF/pseudoreloc.test  | 11 +++++++
 llvm/tools/llvm-readobj/COFFDumper.cpp        | 33 ++++++++++++++++++-
 2 files changed, 43 insertions(+), 1 deletion(-)

diff --git a/llvm/test/tools/llvm-readobj/COFF/pseudoreloc.test b/llvm/test/tools/llvm-readobj/COFF/pseudoreloc.test
index 9568afca1d924..b2bc7a4553298 100644
--- a/llvm/test/tools/llvm-readobj/COFF/pseudoreloc.test
+++ b/llvm/test/tools/llvm-readobj/COFF/pseudoreloc.test
@@ -1,4 +1,6 @@
 RUN: llvm-readobj --coff-pseudoreloc %p/Inputs/pseudoreloc.exe | FileCheck %s
+RUN: llvm-readobj --coff-pseudoreloc %p/Inputs/nop.exe.coff-x86-64 | FileCheck %s --check-prefix=NOSYM
+RUN: llvm-readobj --coff-pseudoreloc %p/Inputs/trivial.obj.coff-i386 | FileCheck %s --check-prefix=NORELOC
 
 CHECK:      Format: COFF-i386
 CHECK-NEXT: Arch: i386
@@ -6,6 +8,15 @@ CHECK-NEXT: AddressSize: 32bit
 CHECK-NEXT: PseudoReloc [
 CHECK-NEXT: ]
 
+NOSYM-NOT: PseudoReloc
+NOSYM: The symbol table has been stripped
+NOSYM-NOT: PseudoReloc
+
+NORELOC-NOT: PseudoReloc
+NORELOC: The symbols for runtime pseudo-relocation are not found
+NORELOC-NOT: PseudoReloc
+
+
 pseudoreloc.exe is generated by following script:
 
 #--- generate.sh
diff --git a/llvm/tools/llvm-readobj/COFFDumper.cpp b/llvm/tools/llvm-readobj/COFFDumper.cpp
index 3c1317590f539..a997e3519cc2d 100644
--- a/llvm/tools/llvm-readobj/COFFDumper.cpp
+++ b/llvm/tools/llvm-readobj/COFFDumper.cpp
@@ -2001,7 +2001,38 @@ void COFFDumper::printCOFFBaseReloc() {
   }
 }
 
-void COFFDumper::printCOFFPseudoReloc() { ListScope D(W, "PseudoReloc"); }
+void COFFDumper::printCOFFPseudoReloc() {
+  const StringRef RelocBeginName = Obj->getArch() == Triple::x86
+                                       ? "___RUNTIME_PSEUDO_RELOC_LIST__"
+                                       : "__RUNTIME_PSEUDO_RELOC_LIST__";
+  const StringRef RelocEndName = Obj->getArch() == Triple::x86
+                                     ? "___RUNTIME_PSEUDO_RELOC_LIST_END__"
+                                     : "__RUNTIME_PSEUDO_RELOC_LIST_END__";
+
+  COFFSymbolRef RelocBegin, RelocEnd;
+  auto Count = Obj->getNumberOfSymbols();
+  if (Count == 0) {
+    W.startLine() << "The symbol table has been stripped\n";
+    return;
+  }
+  for (auto i = 0u;
+       i < Count && (!RelocBegin.getRawPtr() || !RelocEnd.getRawPtr()); ++i) {
+    auto Sym = Obj->getSymbol(i);
+    if (Sym.takeError())
+      continue;
+    auto Name = Obj->getSymbolName(*Sym);
+    if (*Name == RelocBeginName)
+      RelocBegin = *Sym;
+    else if (*Name == RelocEndName)
+      RelocEnd = *Sym;
+  }
+  if (!RelocBegin.getRawPtr() || !RelocEnd.getRawPtr()) {
+    W.startLine()
+        << "The symbols for runtime pseudo-relocation are not found\n";
+    return;
+  }
+  ListScope D(W, "PseudoReloc");
+}
 
 void COFFDumper::printCOFFResources() {
   ListScope ResourcesD(W, "Resources");

>From fff11ce555dc1705f1522f3381918dd64d6d10f4 Mon Sep 17 00:00:00 2001
From: kikairoya <kikairoya at gmail.com>
Date: Thu, 31 Jul 2025 21:58:45 +0900
Subject: [PATCH 3/4] dump raw reloc data

---
 .../tools/llvm-readobj/COFF/pseudoreloc.test  | 15 +++++
 llvm/tools/llvm-readobj/COFFDumper.cpp        | 55 +++++++++++++++++--
 2 files changed, 66 insertions(+), 4 deletions(-)

diff --git a/llvm/test/tools/llvm-readobj/COFF/pseudoreloc.test b/llvm/test/tools/llvm-readobj/COFF/pseudoreloc.test
index b2bc7a4553298..2989053a8e040 100644
--- a/llvm/test/tools/llvm-readobj/COFF/pseudoreloc.test
+++ b/llvm/test/tools/llvm-readobj/COFF/pseudoreloc.test
@@ -6,6 +6,21 @@ CHECK:      Format: COFF-i386
 CHECK-NEXT: Arch: i386
 CHECK-NEXT: AddressSize: 32bit
 CHECK-NEXT: PseudoReloc [
+CHECK-NEXT:  Entry {
+CHECK-NEXT:   Symbol: 0x{{[0-9A-Z]+}}
+CHECK-NEXT:   Target: 0x{{[0-9A-Z]+}}
+CHECK-NEXT:   BitWidth: {{[0-9]+}}
+CHECK-NEXT:  }
+CHECK-NEXT:  Entry {
+CHECK-NEXT:   Symbol: 0x{{[0-9A-Z]+}}
+CHECK-NEXT:   Target: 0x{{[0-9A-Z]+}}
+CHECK-NEXT:   BitWidth: {{[0-9]+}}
+CHECK-NEXT:  }
+CHECK-NEXT:  Entry {
+CHECK-NEXT:   Symbol: 0x{{[0-9A-Z]+}}
+CHECK-NEXT:   Target: 0x{{[0-9A-Z]+}}
+CHECK-NEXT:   BitWidth: {{[0-9]+}}
+CHECK-NEXT:  }
 CHECK-NEXT: ]
 
 NOSYM-NOT: PseudoReloc
diff --git a/llvm/tools/llvm-readobj/COFFDumper.cpp b/llvm/tools/llvm-readobj/COFFDumper.cpp
index a997e3519cc2d..e3cc9d7e7e5c9 100644
--- a/llvm/tools/llvm-readobj/COFFDumper.cpp
+++ b/llvm/tools/llvm-readobj/COFFDumper.cpp
@@ -2021,17 +2021,64 @@ void COFFDumper::printCOFFPseudoReloc() {
     if (Sym.takeError())
       continue;
     auto Name = Obj->getSymbolName(*Sym);
-    if (*Name == RelocBeginName)
-      RelocBegin = *Sym;
-    else if (*Name == RelocEndName)
-      RelocEnd = *Sym;
+    if (Name.takeError())
+      continue;
+    if (*Name == RelocBeginName) {
+      if (Sym->getSectionNumber() > 0)
+        RelocBegin = *Sym;
+    } else if (*Name == RelocEndName) {
+      if (Sym->getSectionNumber() > 0)
+        RelocEnd = *Sym;
+    }
   }
   if (!RelocBegin.getRawPtr() || !RelocEnd.getRawPtr()) {
     W.startLine()
         << "The symbols for runtime pseudo-relocation are not found\n";
     return;
   }
+
+  ArrayRef<uint8_t> Data;
+  auto Section = Obj->getSection(RelocBegin.getSectionNumber());
+  if (auto E = Section.takeError()) {
+    reportError(std::move(E), Obj->getFileName());
+    return;
+  }
+  if (auto E = Obj->getSectionContents(*Section, Data)) {
+    reportError(std::move(E), Obj->getFileName());
+    return;
+  }
+  ArrayRef<uint8_t> RawRelocs =
+      Data.take_front(RelocEnd.getValue()).drop_front(RelocBegin.getValue());
+  struct alignas(4) PseudoRelocationHeader {
+    uint32_t Zero1;
+    uint32_t Zero2;
+    uint32_t Signature;
+  };
+  static const PseudoRelocationHeader HeaderV2 = {0, 0, 1};
+  if (RawRelocs.size() < sizeof(HeaderV2) ||
+      (memcmp(RawRelocs.data(), &HeaderV2, sizeof(HeaderV2)) != 0)) {
+    reportWarning(
+        createStringError("Invalid runtime pseudo-relocation records"),
+        Obj->getFileName());
+    return;
+  }
+  struct alignas(4) PseudoRelocationRecord {
+    uint32_t Symbol;
+    uint32_t Target;
+    uint32_t BitSize;
+  };
+  ArrayRef<PseudoRelocationRecord> RelocRecords(
+      reinterpret_cast<const PseudoRelocationRecord *>(
+          RawRelocs.data() + sizeof(PseudoRelocationHeader)),
+      (RawRelocs.size() - sizeof(PseudoRelocationHeader)) /
+          sizeof(PseudoRelocationRecord));
   ListScope D(W, "PseudoReloc");
+  for (const auto &Reloc : RelocRecords) {
+    DictScope Entry(W, "Entry");
+    W.printHex("Symbol", Reloc.Symbol);
+    W.printHex("Target", Reloc.Target);
+    W.printNumber("BitWidth", Reloc.BitSize);
+  }
 }
 
 void COFFDumper::printCOFFResources() {

>From be77e1c7e180b985c87c1c0cd3b0f6ea1e36bdd1 Mon Sep 17 00:00:00 2001
From: kikairoya <kikairoya at gmail.com>
Date: Thu, 31 Jul 2025 23:22:55 +0900
Subject: [PATCH 4/4] show symbol name

---
 .../tools/llvm-readobj/COFF/pseudoreloc.test  |  3 ++
 llvm/tools/llvm-readobj/COFFDumper.cpp        | 28 +++++++++++++++++++
 2 files changed, 31 insertions(+)

diff --git a/llvm/test/tools/llvm-readobj/COFF/pseudoreloc.test b/llvm/test/tools/llvm-readobj/COFF/pseudoreloc.test
index 2989053a8e040..f3db464b4ae69 100644
--- a/llvm/test/tools/llvm-readobj/COFF/pseudoreloc.test
+++ b/llvm/test/tools/llvm-readobj/COFF/pseudoreloc.test
@@ -8,16 +8,19 @@ CHECK-NEXT: AddressSize: 32bit
 CHECK-NEXT: PseudoReloc [
 CHECK-NEXT:  Entry {
 CHECK-NEXT:   Symbol: 0x{{[0-9A-Z]+}}
+CHECK-NEXT:   SymbolName: sym1
 CHECK-NEXT:   Target: 0x{{[0-9A-Z]+}}
 CHECK-NEXT:   BitWidth: {{[0-9]+}}
 CHECK-NEXT:  }
 CHECK-NEXT:  Entry {
 CHECK-NEXT:   Symbol: 0x{{[0-9A-Z]+}}
+CHECK-NEXT:   SymbolName: sym2
 CHECK-NEXT:   Target: 0x{{[0-9A-Z]+}}
 CHECK-NEXT:   BitWidth: {{[0-9]+}}
 CHECK-NEXT:  }
 CHECK-NEXT:  Entry {
 CHECK-NEXT:   Symbol: 0x{{[0-9A-Z]+}}
+CHECK-NEXT:   SymbolName: sym1
 CHECK-NEXT:   Target: 0x{{[0-9A-Z]+}}
 CHECK-NEXT:   BitWidth: {{[0-9]+}}
 CHECK-NEXT:  }
diff --git a/llvm/tools/llvm-readobj/COFFDumper.cpp b/llvm/tools/llvm-readobj/COFFDumper.cpp
index e3cc9d7e7e5c9..45ca018b714f2 100644
--- a/llvm/tools/llvm-readobj/COFFDumper.cpp
+++ b/llvm/tools/llvm-readobj/COFFDumper.cpp
@@ -2072,10 +2072,38 @@ void COFFDumper::printCOFFPseudoReloc() {
           RawRelocs.data() + sizeof(PseudoRelocationHeader)),
       (RawRelocs.size() - sizeof(PseudoRelocationHeader)) /
           sizeof(PseudoRelocationRecord));
+
+  // Cache of symbol searched at least once in IAT
+  DenseMap<uint32_t, StringRef> ImportedSymbols;
+
   ListScope D(W, "PseudoReloc");
   for (const auto &Reloc : RelocRecords) {
     DictScope Entry(W, "Entry");
     W.printHex("Symbol", Reloc.Symbol);
+
+    // find and print the pointed symbol from IAT
+    [&]() {
+      for (auto D : Obj->import_directories()) {
+        uint32_t RVA;
+        if (auto E = D.getImportAddressTableRVA(RVA))
+          reportError(std::move(E), Obj->getFileName());
+        if (Reloc.Symbol < RVA)
+          continue;
+        for (auto S : D.imported_symbols()) {
+          if (RVA == Reloc.Symbol) {
+            if (auto E = S.getSymbolName(ImportedSymbols[RVA]))
+              reportError(std::move(E), Obj->getFileName());
+            return;
+          }
+          RVA += Obj->is64() ? 8 : 4;
+        }
+      }
+    }();
+    if (auto Ite = ImportedSymbols.find(Reloc.Symbol);
+        Ite != ImportedSymbols.end()) {
+      W.printString("SymbolName", Ite->second);
+    }
+
     W.printHex("Target", Reloc.Target);
     W.printNumber("BitWidth", Reloc.BitSize);
   }



More information about the llvm-commits mailing list