aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAnthony G. Basile <blueness@gentoo.org>2012-12-23 20:54:10 -0500
committerAnthony G. Basile <blueness@gentoo.org>2012-12-24 05:57:57 -0500
commitbbed69289001490eb792727262035ff696c8fc44 (patch)
tree6c6dca53f51df3308a4efc47e95f3efc1c4805ae
parentsrc/paxctl-ng.c: fix flag logic under various --{en,dis}able-{pt,xt}pax (diff)
downloadelfix-bbed69289001490eb792727262035ff696c8fc44.tar.gz
elfix-bbed69289001490eb792727262035ff696c8fc44.tar.bz2
elfix-bbed69289001490eb792727262035ff696c8fc44.zip
misc/link_maps{,_portage}: compare reading /var/db/pkg directly and via portage
-rwxr-xr-xmisc/link_maps60
-rwxr-xr-xmisc/link_maps_portage184
2 files changed, 199 insertions, 45 deletions
diff --git a/misc/link_maps b/misc/link_maps
index a6adacd..3e4e3cb 100755
--- a/misc/link_maps
+++ b/misc/link_maps
@@ -168,57 +168,27 @@ def main():
object_reverse_linkings = get_object_reverse_linkings( object_linkings )
- """ Print out all ELF objects and their PaX flags
- for elf in object_needed:
- try:
- flags = pax.getflags(elf)[0]
- if flags:
- print("%s %s" % (flags, elf))
- else:
- print("NONE: %s" % elf)
- except pax.error:
- print("CANT: %s" % elf)
-
- """
-
- """ Print out all sonames and their library paths
- for soname in sorted(soname2library):
- elf = soname2library[soname]
- print("%s : %s" % ( soname, elf ))
- """
-
-
- """ Print out all ELF objects and the NEEDED sonames and full library paths
- for elf in object_needed:
- sonames = object_needed[elf]
+ """ Print out all ELF objects and the NEEDED sonames and full library paths """
+ for elf in object_linkings:
+ sonames = object_linkings[elf]
print("%s" % elf)
- for soname in sorted(object_needed[elf]):
+ for soname in sorted(object_linkings[elf]):
try:
print("\t%s\t=> %s" % (soname, soname2library[soname]))
except KeyError:
- print("\t%s\t=> ****" % soname)
+ print("%s\t=>%s " % (soname, '***'))
+ print("\n\n")
+
+ """ Print out all ELF objects and the NEEDED sonames and full library paths """
+ for soname in object_reverse_linkings:
+ try:
+ print("%s\t=> %s" % (soname, soname2library[soname]))
+ except KeyError:
+ print("%s\t=>%s " % (soname, '***'))
+ for elf in sorted(object_reverse_linkings[soname]):
+ print("\t%s" % elf)
print("\n\n")
- """
- """ Print out all the soname to soname NEEDED
- for soname in soname_needed:
- print("%s" % soname)
- for s in soname_needed[soname]:
- print("\t%s" % s )
- print('')
- """
-
-
- """ Print out all the soname to soname linkings
- for soname in soname_linkings:
- print("%s => %s" % (soname, soname2library[soname]))
- for s in soname_linkings[soname]:
- if s in soname2library:
- print("\t%s => %s" % (s, soname2library[s]))
- else:
- print("\t%s => ****" %s )
- print('')
- """
if __name__ == '__main__':
main()
diff --git a/misc/link_maps_portage b/misc/link_maps_portage
new file mode 100755
index 0000000..bf5b447
--- /dev/null
+++ b/misc/link_maps_portage
@@ -0,0 +1,184 @@
+#!/usr/bin/env python
+
+#
+# Note: This alternative way of doing revdep-pax only
+# works on Gentoo systems where NEEDED.ELF.2 all the
+# information we need generated by scanelf during emerge.
+#
+# See /usr/lib/portage/bin/misc-functions.sh ~line 520
+# echo "${arch:3};${obj};${soname};${rpath};${needed}" >> "${PORTAGE_BUILDDIR}"/build-info/NEEDED.ELF.2
+#
+
+import os
+import sys
+import re
+import pax
+import portage
+
+
+"""
+Return object_needed dictionary which has structure
+
+ { full_path_to_ELF_object : [ soname1, soname2, ... ], ... }
+
+Here the sonames were obtained from the ELF object by scanelf -nm
+(like readelf -d) during emerge.
+"""
+def get_object_needed():
+
+ vardb = portage.db[portage.root]["vartree"].dbapi
+
+ object_needed = {}
+
+ for pkg in vardb.cpv_all():
+ needs = vardb.aux_get(pkg, ['NEEDED.ELF.2'])[0].strip()
+ if not needs: #skip empty lines
+ continue
+ lines = re.split('\n', needs)
+ for line in lines:
+ link = re.split(';', line)
+ elf = link[1]
+ sonames = re.split(',', link[4])
+ object_needed[elf] = sonames
+
+ return object_needed
+
+
+"""
+Return library2soname dictionary which has structure
+
+ { full_path_to_library : soname, ... }
+
+and its inverse which has structure
+
+ { soname : full_path_to_library, ... }
+"""
+def get_libraries():
+
+ vardb = portage.db[portage.root]["vartree"].dbapi
+
+ library2soname = {}
+ soname2library = {}
+
+ for pkg in vardb.cpv_all():
+ needs = vardb.aux_get(pkg, ['NEEDED.ELF.2'])[0].strip()
+ if not needs: #skip empty lines
+ continue
+ lines = re.split('\n', needs)
+ for line in lines:
+ link = re.split(';', line)
+ elf = link[1]
+ soname = link[2]
+ if soname: #no soname => executable
+ library2soname[elf] = soname
+ soname2library[soname] = elf
+
+ return ( library2soname, soname2library )
+
+
+"""
+Return get_soname_needed dictionary which has structure:
+
+ { soname : [ soname1, soname2, ... ], .... }
+
+Here the soname1, soname2,... were obtained from soname's corresponding
+ELF object by scanelf -n during emerge.
+"""
+def get_soname_needed( object_needed, library2soname ):
+
+ soname_needed = {}
+
+ for elf in object_needed:
+ try:
+ soname = library2soname[elf]
+ soname_needed[soname] = object_needed[elf]
+ #soname_needed[soname] = copy(object_needed[elf]) #copy the list
+ except KeyError:
+ continue # no soname, its probably an executable
+
+ return soname_needed
+
+
+def get_soname_linkings( soname_needed, soname2library ):
+ for soname in soname_needed:
+ while True:
+ count = 0
+ for s in soname_needed[soname]:
+ try:
+ for sf in soname_needed[s]:
+ if sf in soname_needed[soname]: # Skip it if we already included it
+ continue
+ if not sf in soname2library: #Skip if its a vdso
+ continue
+ # This appends to the object_needed and soname_needed list.
+ # No copy was done so its the same list in memory for both.
+ soname_needed[soname].append(sf)
+ count = 1
+ except KeyError:
+ continue
+
+ if count == 0:
+ break
+ return
+
+
+def get_object_reverse_linkings( object_linkings ):
+ object_reverse_linkings = {}
+
+ for elf in object_linkings:
+ for soname in object_linkings[elf]:
+ object_reverse_linkings.setdefault(soname,[]).append(elf)
+
+ return object_reverse_linkings
+
+
+def main():
+
+ # Run as root to be able to real all files
+ uid = os.getuid()
+ if uid != 0:
+ print('RUN AS ROOT: cannot read all flags')
+ sys.exit(0)
+
+ object_needed = get_object_needed()
+ ( library2soname, soname2library ) = get_libraries()
+ soname_needed = get_soname_needed( object_needed, library2soname )
+
+ # After the appending to needed in get_soname_linkings(), forward_needed
+ # and soname_needed have been extended through the entire chain of linking.
+ # If we want to keep only the object_needed and soname_needed, then do
+ # a copy before calling get_soname_linkings().
+ get_soname_linkings( soname_needed, soname2library )
+
+ object_linkings = object_needed
+ object_needed = None
+
+ soname_linkings = soname_needed
+ soname_needed = None
+
+ object_reverse_linkings = get_object_reverse_linkings( object_linkings )
+
+ """ Print out all ELF objects and the NEEDED sonames and full library paths """
+ for elf in object_linkings:
+ sonames = object_linkings[elf]
+ print("%s" % elf)
+ for soname in sorted(object_linkings[elf]):
+ try:
+ print("\t%s\t=> %s" % (soname, soname2library[soname]))
+ except KeyError:
+ print("%s\t=>%s " % (soname, '***'))
+ print("\n\n")
+
+ """ Print out all ELF objects and the NEEDED sonames and full library paths """
+ for soname in object_reverse_linkings:
+ try:
+ print("%s\t=> %s" % (soname, soname2library[soname]))
+ except KeyError:
+ print("%s\t=>%s " % (soname, '***'))
+ for elf in sorted(object_reverse_linkings[soname]):
+ print("\t%s" % elf)
+ print("\n\n")
+
+
+if __name__ == '__main__':
+ main()