[llvm] ce4fcfc - [llvm-jitlink] Make -show-addrs work without -check, fix fallout. (#175491)

via llvm-commits llvm-commits at lists.llvm.org
Mon Jan 12 05:13:16 PST 2026


Author: Lang Hames
Date: 2026-01-13T00:13:12+11:00
New Revision: ce4fcfc9e4b391c24d89f24d9ef1fc1f6ed230ee

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

LOG:  [llvm-jitlink] Make -show-addrs work without -check, fix fallout. (#175491)

Ensures that the address scraping passes are added to the JIT linker pipeline
if either of the -check or -show-addrs are passed. Prior to this commit we only
considered -check, so passing -show-addrs on its own was printing an empty
(unpopulated) symbol table.

This change exposed bugs in RuntimeDyldChecker's `MemoryRegionInfo` type, aned
llvm-jitlink's symbol printing code:

 - `MemoryRegionInfo` was assuming that zero-sized symbols wouldn't be defined
   and was using Size == 0 as a proxy for "region info uninitialized". This was
   triggering assertions for valid LinkGraphs containing zero-sized symbols.

 - llvm-jitlink's symbol printing code was assuming that all defined symbols
   contained content, and was not correctly handling zero-fill / absolute
   symbols. This triggered assertions about requesting content addresses for
   non-content symbols.

This commit fixes the issues above, and adds both a generic testcase for the
-show-addrs option, and an ELF-specific testcase with a zero-sized symbol to
check that the option works for such symbols.

Added: 
    llvm/test/ExecutionEngine/JITLink/AArch64/ELF_zero_sized_symbols_with_show_addrs.s
    llvm/test/ExecutionEngine/JITLink/Generic/llvm-jitlink-option-show-addrs.test

Modified: 
    llvm/include/llvm/ExecutionEngine/RuntimeDyldChecker.h
    llvm/tools/llvm-jitlink/llvm-jitlink-elf.cpp
    llvm/tools/llvm-jitlink/llvm-jitlink.cpp

Removed: 
    


################################################################################
diff  --git a/llvm/include/llvm/ExecutionEngine/RuntimeDyldChecker.h b/llvm/include/llvm/ExecutionEngine/RuntimeDyldChecker.h
index ec9bee8edb595..79e873c5f7219 100644
--- a/llvm/include/llvm/ExecutionEngine/RuntimeDyldChecker.h
+++ b/llvm/include/llvm/ExecutionEngine/RuntimeDyldChecker.h
@@ -82,35 +82,41 @@ class RuntimeDyldChecker {
 public:
   class MemoryRegionInfo {
   public:
-    MemoryRegionInfo() = default;
+    MemoryRegionInfo() : Size(0), Initialized(false) {}
 
     /// Constructor for symbols/sections with content and TargetFlag.
     MemoryRegionInfo(ArrayRef<char> Content, JITTargetAddress TargetAddress,
                      TargetFlagsType TargetFlags)
         : ContentPtr(Content.data()), Size(Content.size()),
-          TargetAddress(TargetAddress), TargetFlags(TargetFlags) {}
+          TargetAddress(TargetAddress), TargetFlags(TargetFlags) {
+      Initialized = true;
+    }
 
     /// Constructor for zero-fill symbols/sections.
     MemoryRegionInfo(uint64_t Size, JITTargetAddress TargetAddress)
-        : Size(Size), TargetAddress(TargetAddress) {}
+        : Size(Size), TargetAddress(TargetAddress) {
+      Initialized = true;
+    }
 
     /// Returns true if this is a zero-fill symbol/section.
     bool isZeroFill() const {
-      assert(Size && "setContent/setZeroFill must be called first");
+      assert(Initialized && "setZeroFill / setContent not called");
       return !ContentPtr;
     }
 
     /// Set the content for this memory region.
     void setContent(ArrayRef<char> Content) {
-      assert(!ContentPtr && !Size && "Content/zero-fill already set");
+      assert(!Initialized && "Content/zero-fill already set");
       ContentPtr = Content.data();
       Size = Content.size();
+      Initialized = true;
     }
 
     /// Set a zero-fill length for this memory region.
     void setZeroFill(uint64_t Size) {
-      assert(!ContentPtr && !this->Size && "Content/zero-fill already set");
+      assert(!Initialized && "Content/zero-fill already set");
       this->Size = Size;
+      Initialized = true;
     }
 
     /// Returns the content for this section if there is any.
@@ -145,7 +151,8 @@ class RuntimeDyldChecker {
 
   private:
     const char *ContentPtr = nullptr;
-    uint64_t Size = 0;
+    uint64_t Size : 63;
+    uint64_t Initialized : 1;
     JITTargetAddress TargetAddress = 0;
     TargetFlagsType TargetFlags = 0;
   };

diff  --git a/llvm/test/ExecutionEngine/JITLink/AArch64/ELF_zero_sized_symbols_with_show_addrs.s b/llvm/test/ExecutionEngine/JITLink/AArch64/ELF_zero_sized_symbols_with_show_addrs.s
new file mode 100644
index 0000000000000..2ddd545de3953
--- /dev/null
+++ b/llvm/test/ExecutionEngine/JITLink/AArch64/ELF_zero_sized_symbols_with_show_addrs.s
@@ -0,0 +1,16 @@
+# RUN: llvm-mc -triple=aarch64-unknown-linux-gnu \
+# RUN:   -position-independent -filetype=obj -o %t.o %s
+# RUN: llvm-jitlink -noexec -show-addrs %t.o | FileCheck %s
+
+# Check that show-addrs works with zero-sized symbols.
+
+# CHECK: main{{.*}}target addr =
+
+        .text
+        .globl  main
+        .p2align        2
+        .type   main, at function
+main:
+        mov     w0, wzr
+        ret
+        .size   main, 0

diff  --git a/llvm/test/ExecutionEngine/JITLink/Generic/llvm-jitlink-option-show-addrs.test b/llvm/test/ExecutionEngine/JITLink/Generic/llvm-jitlink-option-show-addrs.test
new file mode 100644
index 0000000000000..96635f57a09f9
--- /dev/null
+++ b/llvm/test/ExecutionEngine/JITLink/Generic/llvm-jitlink-option-show-addrs.test
@@ -0,0 +1,14 @@
+# RUN: llc -filetype=obj -o %t.o %S/Inputs/main-ret-0.ll
+# RUN: llvm-jitlink -noexec -show-addrs %t.o | FileCheck %s
+#
+# Check that the llvm-jitlink -show-addrs option reports an address for main.
+
+# Jitlink does not support ARM64 COFF files.
+# UNSUPPORTED: target=aarch64-{{.*}}-windows-{{.*}}
+
+# On MinGW targets, when compiling the main() function, it gets
+# an implicitly generated call to __main(), which is missing in
+# this context.
+# XFAIL: target={{.*}}-windows-gnu
+
+# CHECK: main{{.*}} target addr = 0x{{[[:xdigit:]]+}}, content:
\ No newline at end of file

diff  --git a/llvm/tools/llvm-jitlink/llvm-jitlink-elf.cpp b/llvm/tools/llvm-jitlink/llvm-jitlink-elf.cpp
index 8bd17ebb6317a..0ba04eba89f47 100644
--- a/llvm/tools/llvm-jitlink/llvm-jitlink-elf.cpp
+++ b/llvm/tools/llvm-jitlink/llvm-jitlink-elf.cpp
@@ -176,6 +176,8 @@ Error registerELFGraphInfo(Session &S, LinkGraph &G) {
     }
 
     // Add symbol info for absolute symbols.
+    // MemoryRegionInfo doesn't support zero-sized symbols, so use a minimum of
+    // 1.
     for (auto *Sym : G.absolute_symbols())
       S.SymbolInfos[Sym->getName()] = {Sym->getSize(),
                                        Sym->getAddress().getValue()};

diff  --git a/llvm/tools/llvm-jitlink/llvm-jitlink.cpp b/llvm/tools/llvm-jitlink/llvm-jitlink.cpp
index 7732992f77cb3..f6b86307798cc 100644
--- a/llvm/tools/llvm-jitlink/llvm-jitlink.cpp
+++ b/llvm/tools/llvm-jitlink/llvm-jitlink.cpp
@@ -418,11 +418,16 @@ namespace llvm {
 
 static raw_ostream &
 operator<<(raw_ostream &OS, const Session::MemoryRegionInfo &MRI) {
-  return OS << "target addr = "
-            << format("0x%016" PRIx64, MRI.getTargetAddress())
-            << ", content: " << (const void *)MRI.getContent().data() << " -- "
-            << (const void *)(MRI.getContent().data() + MRI.getContent().size())
-            << " (" << MRI.getContent().size() << " bytes)";
+  OS << "target addr = " << format("0x%016" PRIx64, MRI.getTargetAddress());
+
+  if (MRI.isZeroFill())
+    OS << ", zero-fill: " << MRI.getZeroFillLength() << " bytes";
+  else
+    OS << ", content: " << (const void *)MRI.getContent().data() << " -- "
+       << (const void *)(MRI.getContent().data() + MRI.getContent().size())
+       << " (" << MRI.getContent().size() << " bytes)";
+
+  return OS;
 }
 
 static raw_ostream &
@@ -1396,7 +1401,7 @@ void Session::modifyPassConfig(LinkGraph &G, PassConfiguration &PassConfig) {
   if (ShowLinkedFiles)
     outs() << "Linking " << G.getName() << "\n";
 
-  if (!CheckFiles.empty())
+  if (!CheckFiles.empty() || ShowAddrs)
     PassConfig.PostFixupPasses.push_back([this](LinkGraph &G) {
       if (ES.getTargetTriple().getObjectFormat() == Triple::ELF)
         return registerELFGraphInfo(*this, G);


        


More information about the llvm-commits mailing list