diff --git a/include/eld/Diagnostics/DiagCommonKinds.inc b/include/eld/Diagnostics/DiagCommonKinds.inc index 010707af7..cbcb3b9b0 100644 --- a/include/eld/Diagnostics/DiagCommonKinds.inc +++ b/include/eld/Diagnostics/DiagCommonKinds.inc @@ -173,6 +173,8 @@ DIAG(warn_unknown_trace_option, DiagnosticEngine::Warning, "Unknown trace option '%0'") DIAG(err_shared_objects_in_partial_link, DiagnosticEngine::Error, "Shared libraries are not allowed with partial links, found %0") +DIAG(warn_duplicate_soname, DiagnosticEngine::Warning, + "multiple shared objects with same shared object name '%0': %1") DIAG(err_patch_base_not_executable, DiagnosticEngine::Error, "The file %0, specified by --patch-base, must be an executable ELF file") DIAG(err_patch_not_static, DiagnosticEngine::Error, diff --git a/lib/Core/Linker.cpp b/lib/Core/Linker.cpp index 6b37bbde9..c35950033 100644 --- a/lib/Core/Linker.cpp +++ b/lib/Core/Linker.cpp @@ -16,6 +16,7 @@ #include "eld/Diagnostics/DiagnosticEngine.h" #include "eld/Fragment/FragmentRef.h" #include "eld/Input/ELFObjectFile.h" +#include "eld/Input/ELFDynObjectFile.h" #include "eld/Input/InputBuilder.h" #include "eld/Input/InternalInputFile.h" #include "eld/LayoutMap/LayoutInfo.h" @@ -338,6 +339,30 @@ bool Linker::normalize() { return false; } + // Check for multiple shared objects with same SO name and issue warning + { + std::map> sonameToFiles; + for (const auto &InputFile : ThisModule->getObjectList()) { + auto T = InputFile->getInput()->getInputType(); + if (T == Input::DynObj) { + // Get the SO name from the shared object + std::string soname = InputFile->getInput()->getName(); // Default to filename + if (ELFDynObjectFile *dynObj = llvm::dyn_cast(InputFile)) { + soname = dynObj->getSOName(); + } + sonameToFiles[soname].push_back(InputFile->getInput()->getName()); + } + } + + // Warn about duplicate SO names + for (const auto &entry : sonameToFiles) { + if (entry.second.size() > 1) { + std::string fileList = llvm::join(entry.second, ", "); + ThisConfig->raise(Diag::warn_duplicate_soname) << entry.first << fileList; + } + } + } + // 2. - set up code position LinkerProgress->incrementAndDisplayProgress(); if (LinkerConfig::DynObj == ThisConfig->codeGenType() || diff --git a/test/Hexagon/standalone/SharedLibraries/DuplicateSOName/DuplicateSOName.test b/test/Hexagon/standalone/SharedLibraries/DuplicateSOName/DuplicateSOName.test new file mode 100644 index 000000000..19b43b715 --- /dev/null +++ b/test/Hexagon/standalone/SharedLibraries/DuplicateSOName/DuplicateSOName.test @@ -0,0 +1,11 @@ +#---DuplicateSOName.test------------------------ SharedLibrary -----------------# +#BIGIN_COMMENT +# Test that linker issues a warning for duplicate shared object names. +#END_COMMENT +#START_TEST +RUN: %clang -c %p/Inputs/1.c -ffunction-sections -shared -o %t1.o +RUN: %clang -c %p/Inputs/2.c -ffunction-sections -shared -o %t2.o +RUN: %link -shared -soname=foo -o %libt1.so %t1.o +RUN: %link -shared -soname=foo -o %libt2.so %t2.o +RUN: %link -o %t.out %libt1.so %libt2.so +#END_TEST \ No newline at end of file diff --git a/test/Hexagon/standalone/SharedLibraries/DuplicateSOName/Inputs/1.c b/test/Hexagon/standalone/SharedLibraries/DuplicateSOName/Inputs/1.c new file mode 100644 index 000000000..cfe552472 --- /dev/null +++ b/test/Hexagon/standalone/SharedLibraries/DuplicateSOName/Inputs/1.c @@ -0,0 +1,3 @@ +int foo() { + return 1; +} diff --git a/test/Hexagon/standalone/SharedLibraries/DuplicateSOName/Inputs/2.c b/test/Hexagon/standalone/SharedLibraries/DuplicateSOName/Inputs/2.c new file mode 100644 index 000000000..188c3eb6b --- /dev/null +++ b/test/Hexagon/standalone/SharedLibraries/DuplicateSOName/Inputs/2.c @@ -0,0 +1,3 @@ +int bar() { + return 3; +} diff --git a/test/x86_64/standalone/LinkDriver/DuplicateSONames-1.test b/test/x86_64/standalone/LinkDriver/DuplicateSONames-1.test new file mode 100644 index 000000000..ade0eca4f --- /dev/null +++ b/test/x86_64/standalone/LinkDriver/DuplicateSONames-1.test @@ -0,0 +1,13 @@ +#---DuplicateSOName.test------------------------ SharedLibrary -----------------# +#BIGIN_COMMENT +# Test that linker issues a warning for duplicate shared object names. +#END_COMMENT +#START_TEST +RUN: %clang -c %p/Inputs/1.c -ffunction-sections -shared -o %t1.o +RUN: %clang -c %p/Inputs/2.c -ffunction-sections -shared -o %t2.o +RUN: %link -shared -soname=foo -o %libt1.so %t1.o +RUN: %link -shared -soname=foo -o %libt2.so %t2.o +RUN: %link -o %t.out %libt1.so %libt2.so 2>&1 | %filecheck %s + +#CHECK:Warning: multiple shared objects with same shared object name 'foo': libt1.so, libt2.so +#END_TEST \ No newline at end of file diff --git a/test/x86_64/standalone/LinkDriver/DuplicateSONames-2.test b/test/x86_64/standalone/LinkDriver/DuplicateSONames-2.test new file mode 100644 index 000000000..93ef35a7a --- /dev/null +++ b/test/x86_64/standalone/LinkDriver/DuplicateSONames-2.test @@ -0,0 +1,11 @@ +#---DuplicateSOName-2.test---------------------- SharedLibrary -----------------# +#BIGIN_COMMENT +# Test that linker issues a warning for duplicate shared objects. +#END_COMMENT +#START_TEST +RUN: %clang -c %p/Inputs/1.c -ffunction-sections -shared -o %t1.o +RUN: %link -shared -soname=foo -o %libt1.so %t1.o +RUN: %link -o %t.out %libt1.so %libt1.so 2>&1 | %filecheck %s + +#CHECK:Warning: multiple shared objects with same shared object name 'foo': libt1.so, libt1.so +#END_TEST diff --git a/test/x86_64/standalone/LinkDriver/Inputs/2.c b/test/x86_64/standalone/LinkDriver/Inputs/2.c new file mode 100644 index 000000000..188c3eb6b --- /dev/null +++ b/test/x86_64/standalone/LinkDriver/Inputs/2.c @@ -0,0 +1,3 @@ +int bar() { + return 3; +}