From d96a93ff00ac02bc523d36dd2e687d597a068ae1 Mon Sep 17 00:00:00 2001 From: Fangrui Song Date: Sat, 22 Nov 2025 12:54:50 -0800 Subject: ELF: Use index 0 for unversioned undefined symbols (#168189) The GNU documentation is ambiguous about the version index for unversioned undefined symbols. The current specification at https://sourceware.org/gnu-gabi/program-loading-and-dynamic-linking.txt defines VER_NDX_LOCAL (0) as "The symbol is private, and is not available outside this object." However, this naming is misleading for undefined symbols. As suggested in discussions, VER_NDX_LOCAL should conceptually be VER_NDX_NONE and apply to unversioned undefined symbols as well. GNU ld has used index 0 for unversioned undefined symbols both before version 2.35 (see https://sourceware.org/PR26002) and in the upcoming 2.46 release (see https://sourceware.org/PR33577). This change aligns with GNU ld's behavior by switching from index 1 to index 0. While here, add a test to dso-undef-extract-lazy.s that undefined symbols of index 0 in DSO are treated as unversioned symbols. --- lld/ELF/InputFiles.cpp | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'lld/ELF/InputFiles.cpp') diff --git a/lld/ELF/InputFiles.cpp b/lld/ELF/InputFiles.cpp index a5921feb1829..240a6d0cd4b2 100644 --- a/lld/ELF/InputFiles.cpp +++ b/lld/ELF/InputFiles.cpp @@ -1676,8 +1676,9 @@ template void SharedFile::parse() { const uint16_t ver = versyms[i], idx = ver & ~VERSYM_HIDDEN; if (sym.isUndefined()) { - // For unversioned undefined symbols, VER_NDX_GLOBAL makes more sense but - // as of binutils 2.34, GNU ld produces VER_NDX_LOCAL. + // Index 0 (VER_NDX_LOCAL) is used for unversioned undefined symbols. + // GNU ld versions between 2.35 and 2.45 also generate VER_NDX_GLOBAL + // for this case (https://sourceware.org/PR33577). if (ver != VER_NDX_LOCAL && ver != VER_NDX_GLOBAL) { if (idx >= verneeds.size()) { ErrAlways(ctx) << "corrupt input file: version need index " << idx -- cgit v1.2.3