For dynamic libraries, infer an implicit DT_SONAME setting from the
file basename, which is consistent with dynamic linking behavior in
practice. This makes it possible to resolve soname dependencies for
musl's libc.so which lacks a DT_SONAME setting.

Bug: https://bugs.gentoo.org/715162
Signed-off-by: Zac Medico <zmed...@gentoo.org>
---
[PATCH v2] Use file command to distinguish shared library from PIE executable

 bin/misc-functions.sh                       |  6 ++++++
 lib/portage/util/_dyn_libs/LinkageMapELF.py | 16 ++++++++++++++++
 2 files changed, 22 insertions(+)

diff --git a/bin/misc-functions.sh b/bin/misc-functions.sh
index 4f8a4112d..9efe99b87 100755
--- a/bin/misc-functions.sh
+++ b/bin/misc-functions.sh
@@ -183,6 +183,12 @@ install_qa_check() {
                        soname=${l%%;*}; l=${l#*;}
                        rpath=${l%%;*}; l=${l#*;}; [ "${rpath}" = "  -  " ] && 
rpath=""
                        needed=${l%%;*}; l=${l#*;}
+
+                       # Infer implicit soname from basename (bug 715162).
+                       if [[ -z ${soname} && $(file "${D%/}${obj}") == *"SB 
shared object"* ]]; then
+                               soname=${obj##*/}
+                       fi
+
                        echo "${obj} ${needed}" >> 
"${PORTAGE_BUILDDIR}"/build-info/NEEDED
                        echo "${arch:3};${obj};${soname};${rpath};${needed}" >> 
"${PORTAGE_BUILDDIR}"/build-info/NEEDED.ELF.2
                done }
diff --git a/lib/portage/util/_dyn_libs/LinkageMapELF.py 
b/lib/portage/util/_dyn_libs/LinkageMapELF.py
index 70bec116a..2d4929445 100644
--- a/lib/portage/util/_dyn_libs/LinkageMapELF.py
+++ b/lib/portage/util/_dyn_libs/LinkageMapELF.py
@@ -311,6 +311,22 @@ class LinkageMapELF(object):
                                                        raise
                                                # File removed concurrently.
                                                continue
+
+                                       # Infer implicit soname from basename 
(bug 715162).
+                                       if not entry.soname:
+                                               try:
+                                                       proc = 
subprocess.Popen([b'file',
+                                                               
_unicode_encode(entry.filename,
+                                                                       
encoding=_encodings['fs'], errors='strict')],
+                                                               
stdout=subprocess.PIPE)
+                                                       out, err = 
proc.communicate()
+                                                       proc.wait()
+                                               except EnvironmentError:
+                                                       pass
+                                               else:
+                                                       if b'SB shared object' 
in out:
+                                                               entry.soname = 
os.path.basename(entry.filename)
+
                                        entry.multilib_category = 
compute_multilib_category(elf_header)
                                        entry.filename = 
entry.filename[root_len:]
                                        owner = plibs.pop(entry.filename, None)
-- 
2.24.1


Reply via email to