[lld] [LLD] [COFF] Warn if the runtime pseudo relocation function is missing (PR #88573)

Martin Storsjö via llvm-commits llvm-commits at lists.llvm.org
Fri Apr 12 13:29:36 PDT 2024


https://github.com/mstorsjo created https://github.com/llvm/llvm-project/pull/88573

When then linker creates runtime pseudo relocations, it places them in a list with the assumption that the runtime will fix these relocations later, when the image gets loaded. If the relevant runtime function doesn't seem to be present in the linked image, print a warning.

Normally when linking the mingw-w64 runtime libraries, this function always is available. However, if linking without including the mingw-w64 CRT startup files, and the image needs runtime pseudo relocations, try to make the user aware of the situation.

This just prints a warning to alert the user about this situation. Alternatively, we could also make this situation a hard error.

With ld.bfd, this situation is a hard error; ld.bfd adds an undefined reference to this symbol if runtime pseudo relocations are needed.

Yet another alternative would be to actually try to pull in the symbol (if seen in a static library, but not included yet). This would allow decoupling the function from the main CRT startup code (making it optional, only running if the linker actually produced runtime pseudo relocations). Doing that would require restructuring the code (gathering pseudo relocations earlier, in order to be able to continue linking in more object files if the initial set did require pseudo relocations) though.

Also, ld.bfd doesn't currently successfully pull in more object files to satisfy the dependency on _pei386_runtime_relocator, so with that in mind, there's not much extra value in making LLD do it currently either.

This fixes one issue brought up in
https://github.com/llvm/llvm-project/issues/84424.

>From d2eb34dd70459ec89cf6cb8fdb56de7aa21a1312 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Martin=20Storsj=C3=B6?= <martin at martin.st>
Date: Fri, 12 Apr 2024 23:16:27 +0300
Subject: [PATCH] =?UTF-8?q?[LLD]=C2=A0[COFF]=20Warn=20if=20the=20runtime?=
 =?UTF-8?q?=20pseudo=20relocation=20function=20is=20missing?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

When then linker creates runtime pseudo relocations, it places them
in a list with the assumption that the runtime will fix these
relocations later, when the image gets loaded. If the relevant
runtime function doesn't seem to be present in the linked image,
print a warning.

Normally when linking the mingw-w64 runtime libraries, this function
always is available. However, if linking without including the
mingw-w64 CRT startup files, and the image needs runtime pseudo
relocations, try to make the user aware of the situation.

This just prints a warning to alert the user about this situation.
Alternatively, we could also make this situation a hard error.

With ld.bfd, this situation is a hard error; ld.bfd adds an
undefined reference to this symbol if runtime pseudo relocations
are needed.

Yet another alternative would be to actually try to pull in the
symbol (if seen in a static library, but not included yet). This
would allow decoupling the function from the main CRT startup code
(making it optional, only running if the linker actually produced
runtime pseudo relocations). Doing that would require restructuring
the code (gathering pseudo relocations earlier, in order to be able
to continue linking in more object files if the initial set did
require pseudo relocations) though.

Also, ld.bfd doesn't currently successfully pull in more object
files to satisfy the dependency on _pei386_runtime_relocator,
so with that in mind, there's not much extra value in making LLD
do it currently either.

This fixes one issue brought up in
https://github.com/llvm/llvm-project/issues/84424.
---
 lld/COFF/Writer.cpp                  | 10 +++++++-
 lld/test/COFF/autoimport-warn-func.s | 36 ++++++++++++++++++++++++++++
 2 files changed, 45 insertions(+), 1 deletion(-)
 create mode 100644 lld/test/COFF/autoimport-warn-func.s

diff --git a/lld/COFF/Writer.cpp b/lld/COFF/Writer.cpp
index 9c20bbb83d86d1..f2194616b93a63 100644
--- a/lld/COFF/Writer.cpp
+++ b/lld/COFF/Writer.cpp
@@ -2072,8 +2072,16 @@ void Writer::createRuntimePseudoRelocs() {
     return;
   }
 
-  if (!rels.empty())
+  if (!rels.empty()) {
     log("Writing " + Twine(rels.size()) + " runtime pseudo relocations");
+    const char *symbolName = "_pei386_runtime_relocator";
+    Symbol *relocator = ctx.symtab.findUnderscore(symbolName);
+    if (!relocator)
+      warn("output image has pseudo relocations, but function " +
+           Twine(symbolName) +
+           " missing; the relocations might not get fixed at runtime");
+  }
+
   PseudoRelocTableChunk *table = make<PseudoRelocTableChunk>(rels);
   rdataSec->addChunk(table);
   EmptyChunk *endOfList = make<EmptyChunk>();
diff --git a/lld/test/COFF/autoimport-warn-func.s b/lld/test/COFF/autoimport-warn-func.s
new file mode 100644
index 00000000000000..94e1238376b710
--- /dev/null
+++ b/lld/test/COFF/autoimport-warn-func.s
@@ -0,0 +1,36 @@
+# REQUIRES: x86
+# RUN: split-file %s %t.dir
+
+# RUN: llvm-dlltool -m i386:x86-64 -d %t.dir/lib.def -D lib.dll -l %t.dir/lib.lib
+
+# RUN: llvm-mc -triple=x86_64-windows-gnu %t.dir/main.s -filetype=obj -o %t.dir/main.obj
+# RUN: llvm-mc -triple=x86_64-windows-gnu %t.dir/func.s -filetype=obj -o %t.dir/func.obj
+# RUN: lld-link -lldmingw -out:%t.dir/main.exe -entry:main %t.dir/main.obj %t.dir/lib.lib 2>&1 | FileCheck %s --check-prefix=WARN
+
+# RUN: lld-link -lldmingw -out:%t.dir/main.exe -entry:main %t.dir/main.obj %t.dir/func.obj %t.dir/lib.lib 2>&1 | FileCheck %s --check-prefix=NOWARN --allow-empty
+
+# WARN: warning: output image has pseudo relocations, but function _pei386_runtime_relocator missing; the relocations might not get fixed at runtime
+
+# NOWARN-NOT: warning
+
+#--- main.s
+    .global main
+    .text
+main:
+    ret
+
+    .data
+    .long 1
+    .quad variable
+    .long 2
+
+#--- func.s
+    .global _pei386_runtime_relocator
+    .text
+_pei386_runtime_relocator:
+    ret
+
+#--- lib.def
+EXPORTS
+variable DATA
+



More information about the llvm-commits mailing list