From 1f933daa8f43154ca09a04e1be7ad53b80053f9c Mon Sep 17 00:00:00 2001 From: Parth Arora Date: Fri, 2 Jan 2026 02:58:09 -0800 Subject: [PATCH] Fix incorrect NEEDED entry due to unneeded shared lib reference This commit fixes the incorrect NEEDED entry when --as-needed is used and a shared library symbol is referenced by an another unneeded shared library. The root cause of the issue was the logic that was used to determine whether a shared library symbol ResolveInfo should have an outSymbol or not. Resolves #668 Signed-off-by: Parth Arora --- lib/SymbolResolver/IRBuilder.cpp | 2 +- .../UnneededSharedLibReference/Inputs/1.c | 2 ++ .../UnneededSharedLibReference/Inputs/2.c | 4 ++++ .../UnneededSharedLibReference/Inputs/main.c | 2 ++ .../UnneededSharedLibDependency.test | 16 ++++++++++++++++ 5 files changed, 25 insertions(+), 1 deletion(-) create mode 100644 test/Common/standalone/AsNeeded/UnneededSharedLibReference/Inputs/1.c create mode 100644 test/Common/standalone/AsNeeded/UnneededSharedLibReference/Inputs/2.c create mode 100644 test/Common/standalone/AsNeeded/UnneededSharedLibReference/Inputs/main.c create mode 100644 test/Common/standalone/AsNeeded/UnneededSharedLibReference/UnneededSharedLibDependency.test diff --git a/lib/SymbolResolver/IRBuilder.cpp b/lib/SymbolResolver/IRBuilder.cpp index 088de4066..449a31043 100644 --- a/lib/SymbolResolver/IRBuilder.cpp +++ b/lib/SymbolResolver/IRBuilder.cpp @@ -364,7 +364,7 @@ LDSymbol *IRBuilder::addSymbolFromDynObj( Input.setNeeded(); NP.addSharedLibSymbol(InputSym); } - if (ResolvedResult.Overriden && ResolvedResult.Existent) { + if (ResolvedResult.Overriden && ResolvedResult.Info->outSymbol()) { ResolvedResult.Info->setOutSymbol(InputSym); } // If the symbol is from dynamic library and we are not making a dynamic diff --git a/test/Common/standalone/AsNeeded/UnneededSharedLibReference/Inputs/1.c b/test/Common/standalone/AsNeeded/UnneededSharedLibReference/Inputs/1.c new file mode 100644 index 000000000..3a5d6d0d7 --- /dev/null +++ b/test/Common/standalone/AsNeeded/UnneededSharedLibReference/Inputs/1.c @@ -0,0 +1,2 @@ +int foo() { return 1; } + diff --git a/test/Common/standalone/AsNeeded/UnneededSharedLibReference/Inputs/2.c b/test/Common/standalone/AsNeeded/UnneededSharedLibReference/Inputs/2.c new file mode 100644 index 000000000..63de46b33 --- /dev/null +++ b/test/Common/standalone/AsNeeded/UnneededSharedLibReference/Inputs/2.c @@ -0,0 +1,4 @@ +int foo(); +int bar() { return 3; } +int baz() { return foo(); } + diff --git a/test/Common/standalone/AsNeeded/UnneededSharedLibReference/Inputs/main.c b/test/Common/standalone/AsNeeded/UnneededSharedLibReference/Inputs/main.c new file mode 100644 index 000000000..b54a2202d --- /dev/null +++ b/test/Common/standalone/AsNeeded/UnneededSharedLibReference/Inputs/main.c @@ -0,0 +1,2 @@ +int main() { return 0; } + diff --git a/test/Common/standalone/AsNeeded/UnneededSharedLibReference/UnneededSharedLibDependency.test b/test/Common/standalone/AsNeeded/UnneededSharedLibReference/UnneededSharedLibDependency.test new file mode 100644 index 000000000..88960089e --- /dev/null +++ b/test/Common/standalone/AsNeeded/UnneededSharedLibReference/UnneededSharedLibDependency.test @@ -0,0 +1,16 @@ +#---UnneededSharedLibReference.test-------------------- Executable, LS -------# +#BEGIN_COMMENT +# Validates that with --as-needed we do not add DT_NEEDED entries for libraries +# that are referenced only by an unneeded shared library. +#END_COMMENT +#START_TEST +RUN: %clang %clangopts -o %t1.1.o %p/Inputs/1.c -c -ffunction-sections +RUN: %clang %clangopts -o %t1.2.o %p/Inputs/2.c -c -ffunction-sections +RUN: %clang %clangopts -o %t1.main.o %p/Inputs/main.c -c -ffunction-sections +RUN: %link %linkopts -o %t1.lib1.so -shared %t1.1.o +RUN: %link %linkopts -o %t1.lib2.so -shared %t1.2.o +RUN: %link %linkopts -o %t1.out %t1.main.o --as-needed %t1.lib2.so %t1.lib1.so +RUN: %readelf --dynamic %t1.out 2>&1 | %filecheck %s --check-prefix=DYN +#END_TEST +DYN-NOT: lib2.so +DYN-NOT: lib1.so