[lld] [llvm] ELF: Use index 0 for unversioned undefined symbols (PR #168189)

Fangrui Song via llvm-commits llvm-commits at lists.llvm.org
Mon Nov 17 21:56:16 PST 2025


MaskRay wrote:

> Trying to summarise [sourceware.org/bugzilla/show_bug.cgi?id=33577](https://sourceware.org/bugzilla/show_bug.cgi?id=33577)
> 
> * `VER_NDX_LOCAL` for a defined symbol should be used for symbols with STB_LOCAL_BINDING, should these be in the dynamic symbol table for any reason.

STB_LOCAL symbols should not be in .dynsym . In GNU ld, the ia64 port (unsupported by LLVM) has local .dynsym defined symbols for unclear reasons.

> * While not clear from the specification, the intent for undefined symbols is to use `VER_NDX_LOCAL` as if it were called `VER_NDX_NONE` meaning no version.

Right that both Solaris and older GNU ld versions use index 0 (VER_NDX_LOCAL, or VER_NDX_NONE as it should have been called) for unversioned undefined symbols.
While the specification isn't clear, the intent is to treat VER_NDX_LOCAL as meaning "no version".

> * GNU ld, while starting at `VER_NDX_LOCAL` switched to `VER_NDX_GLOBAL` and is now switching back to `VER_NDX_GLOBAL`.

Right.

> * Mold currently rejects undefined symbols with `VER_NDX_LOCAL` and would like more time to update.

Right.

In contrast, LLD has always supported both index 0 and 1 for unversioned undefined symbols. My 2020 change that added versioned symbol recognition (https://reviews.llvm.org/D80059) checks both VER_NDX_LOCAL and VER_NDX_GLOBAL, though test coverage was missing.
The lld/test/ELF/dso-undef-extract-lazy.s change in this PR improves that coverage, and I'm inclined to land it separately since it's unrelated to the producer change.

The `lld/test/ELF/dso-undef-extract-lazy.s` change in this PR is to improve the coverage. If it looks good, I'm inclined to land it separately as it's unrelated to the producer change.

> * GNU ld.so is able to handle `VER_NDX_LOCAL` and `VER_NDX_GLOBAL`.

Yes, likely since 1990+.

> Pragmatically [1] I think it would be best to bring ourselves in line with the GNU tools, which would mean merging this. Before I approve can I check a few things:
> 
> * Are we confident that other dynamic linkers that handle symbol versions (bionic, BSD rtld) can handle this change? At a brief glance at the source they look OK, but I haven't thought about it too hard.

glibc has definitely supported index 0 undefined symbols since the 1990s. I believe FreeBSD rtld and Bionic can handle them as well (index into a versym array, and index 0 and index 1 should behave similarly), though I haven't tested this directly.

> * Are we confident that the GNU ld change will stick given Rui's comment. [sourceware.org/bugzilla/show_bug.cgi?id=33577#c23](https://sourceware.org/bugzilla/show_bug.cgi?id=33577#c23) ? I guess we could revert if necessary.
> 
> [1] My reading of the spec was that `VER_NDX_GLOBAL` made more sense given the description of `VERN_NDX_LOCAL` as private.

There's some confusion in that thread. I want to emphasize that using VER_NDX_LOCAL is the traditional GNU ld behavior we're returning to.

I'll wait to land the LLD change until the discussion settles.


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


More information about the llvm-commits mailing list