[lld] [lld] Use position independent argument parsing for Unresolved Symbol (PR #123950)

via llvm-commits llvm-commits at lists.llvm.org
Wed Jan 22 06:45:05 PST 2025


llvmbot wrote:


<!--LLVM PR SUMMARY COMMENT-->

@llvm/pr-subscribers-lld-elf

Author: None (aokblast)

<details>
<summary>Changes</summary>

# Discover

This issue is discovered a months ago when compiling fprintd on FreeBSD

Error Log:
https://gist.github.com/lwhsu/9d511afdd7c360660c743cfa2e73d13d#file-fprintd-1-94-4-log-L620

# What happens and work around

The ``unresolved_symbol=reports-all`` and ``use_shlib_undefined`` in lld is order sensitive.

That means if we compile (and link) the code in the order like 

``-Wl,--allow-shlib-undefined -Wl,unresolved-symbols=report-all``: failed

``-Wl,unresolved-symbols=report-all -Wl,--allow-shlib-undefined``: works

A work around for us is to patch the meson file in fprintd with ``Wl,unresolved-symbols=report-all`` that makes the whole command like ``-Wl,--allow-shlib-undefined -Wl,unresolved-symbols=report-all -Wl,unresolved-symbols=report-all``.

Notice that this error only happens on FreeBSD 14 and it is not the case for 15.

It is because 15 split ``libc.so`` with ``libc.so`` and ``libsys.so``. ``libsys.so`` is linked for executable.

That means ``libc.so`` will failed the requirement that ``DT_NEEDED`` should be all linked for shared library.

# What gold do

The ld.gold handle these two options (``allow-shlib-undefined`` and ``unresolved-symbols``) in symbol table and relocation step separately.

For ``allow-shlib-undefined``, it check if the lib is inside system path (e.g. /usr/lib, /lib). So libc will pass the test
For ``unresolved-symbols`` because __progname is not needed to relocated (only progname needs) for compiling the shared library, so it will pass the test.


## lld

lld combine these two option in  a global status to indicate if we should report this. 
To be better compatible with gold, allow_shlib and unresolved-symbols should be position independent and handle by a more specific way.


---
Full diff: https://github.com/llvm/llvm-project/pull/123950.diff


1 Files Affected:

- (modified) lld/ELF/Driver.cpp (+9-6) 


``````````diff
diff --git a/lld/ELF/Driver.cpp b/lld/ELF/Driver.cpp
index 019388c9bd2e2c..94f12d30a3671d 100644
--- a/lld/ELF/Driver.cpp
+++ b/lld/ELF/Driver.cpp
@@ -757,15 +757,18 @@ static void setUnresolvedSymbolPolicy(Ctx &ctx, opt::InputArgList &args) {
         break;
       arg->claim();
       break;
-    case OPT_allow_shlib_undefined:
-      diagShlib = false;
-      break;
-    case OPT_no_allow_shlib_undefined:
-      diagShlib = true;
-      break;
     }
   }
 
+  opt::Arg *allow_shlib = args.getLastArg(OPT_allow_shlib_undefined);
+  opt::Arg *no_allow_shlib = args.getLastArg(OPT_no_allow_shlib_undefined);
+
+  if (allow_shlib != nullptr && no_allow_shlib != nullptr)
+	  diagShlib = allow_shlib->getIndex() < no_allow_shlib->getIndex() ?
+		  true : false;
+  else if (allow_shlib != nullptr || no_allow_shlib != nullptr)
+	  diagShlib = no_allow_shlib != nullptr ? true : false;
+
   ctx.arg.unresolvedSymbols =
       diagRegular ? errorOrWarn : UnresolvedPolicy::Ignore;
   ctx.arg.unresolvedSymbolsInShlib =

``````````

</details>


https://github.com/llvm/llvm-project/pull/123950


More information about the llvm-commits mailing list