From: "Anthony G. Basile" <blueness@gentoo.org>
To: gentoo-commits@lists.gentoo.org
Subject: [gentoo-commits] proj/elfix:elfix-0.7.x commit in: misc/
Date: Sat, 29 Dec 2012 01:16:08 +0000 (UTC) [thread overview]
Message-ID: <1356743239.f72fd5f0434f17c7052d8b1fec0bc7f3c8c400e2.blueness@gentoo> (raw)
commit: f72fd5f0434f17c7052d8b1fec0bc7f3c8c400e2
Author: Anthony G. Basile <blueness <AT> gentoo <DOT> org>
AuthorDate: Mon Dec 24 21:08:39 2012 +0000
Commit: Anthony G. Basile <blueness <AT> gentoo <DOT> org>
CommitDate: Sat Dec 29 01:07:19 2012 +0000
URL: http://git.overlays.gentoo.org/gitweb/?p=proj/elfix.git;a=commit;h=f72fd5f0
misc/link_maps{,_portage}: make multilib aware
---
misc/link_maps | 151 +++++++++++++++++++++++++++++-------------------
misc/link_maps_portage | 141 +++++++++++++++++++++++++++-----------------
2 files changed, 178 insertions(+), 114 deletions(-)
diff --git a/misc/link_maps b/misc/link_maps
index 3e4e3cb..9753794 100755
--- a/misc/link_maps
+++ b/misc/link_maps
@@ -18,7 +18,11 @@ import pax
"""
Return object_needed dictionary which has structure
- { full_path_to_ELF_object : [ soname1, soname2, ... ], ... }
+ {
+ abi1 : { full_path_to_ELF_object : [ soname1, soname2, ... ], ... },
+ abi2 : { full_path_to_ELF_object : [ soname1, soname2, ... ], ... },
+ ....
+ }
Here the sonames were obtained from the ELF object by scanelf -nm
(like readelf -d) during emerge.
@@ -39,9 +43,10 @@ def get_object_needed():
for line in needs:
line = line.strip()
link = re.split(';', line)
+ abi = link[0]
elf = link[1]
sonames = re.split(',', link[4])
- object_needed[elf] = sonames
+ object_needed.setdefault(abi,{}).update({elf:sonames})
except IOError:
continue #File probably doesn't exist, which is okay
@@ -51,11 +56,11 @@ def get_object_needed():
"""
Return library2soname dictionary which has structure
- { full_path_to_library : soname, ... }
+ { full_path_to_library : (soname, abi), ... }
and its inverse which has structure
- { soname : full_path_to_library, ... }
+ { (soname, abi) : full_path_to_library, ... }
"""
def get_libraries():
@@ -75,11 +80,12 @@ def get_libraries():
for line in needs:
line = line.strip()
link = re.split(';', line)
+ abi = link[0]
elf = link[1]
soname = link[2]
- if soname: #no soname => executable
- library2soname[elf] = soname
- soname2library[soname] = elf
+ if soname: #no soname => executable
+ library2soname[elf] = (soname,abi)
+ soname2library[(soname,abi)] = elf
except IOError:
continue #File probably doesn't exist, which is okay
@@ -87,9 +93,12 @@ def get_libraries():
"""
-Return get_soname_needed dictionary which has structure:
+Return soname_needed dictionary which has structure:
- { soname : [ soname1, soname2, ... ], .... }
+ {
+ abi1: { soname: [ soname1, soname2, ... ], .... },
+ abi2: { soname: [ soname1, soname2, ... ], .... },
+ }
Here the soname1, soname2,... were obtained from soname's corresponding
ELF object by scanelf -n during emerge.
@@ -98,46 +107,68 @@ 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
+ for abi in object_needed:
+ for elf in object_needed[abi]:
+ try:
+ (soname, abi_check) = library2soname[elf]
+ if abi != abi_check:
+ print "This should never happen!"
+ sys.exit(1)
+ soname_needed.setdefault(abi,{}).update({soname:object_needed[abi][elf]})
+ 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
+"""
+Expands the object_needed dictionary which has structure
+
+ {
+ abi1 : { full_path_to_ELF_object : [ soname1, soname2, ... ], ... },
+ abi2 : { full_path_to_ELF_object : [ soname1, soname2, ... ], ... },
+ ....
+ }
- if count == 0:
- break
- return
+such that the soname's are traced all the way to the end of
+the link chain. Here the sonames should be the same as those
+obtained from the ELF object by ldd.
+"""
+def expand_linkings( object_needed, soname2library ):
+
+ for abi in object_needed:
+ for elf in object_needed[abi]:
+ while True:
+ found_new_soname = False
+ for so in object_needed[abi][elf]: # For all the first links ...
+ try:
+ for sn in object_needed[abi][soname2library[(so,abi)]]: # go to the next links ...
+ if sn in object_needed[abi][elf]: # skip if already included ...
+ continue
+ if not (sn,abi) in soname2library: # skip if vdso ...
+ continue
+ # This appends to the object_needed
+ # and soname_needed lists. No copy
+ # was done so its the same lists in
+ # memory for both, and its modified
+ # for both.
+ object_needed[abi][elf].append(sn) # otherwise collapse it back into
+ found_new_soname = True # first links of the chain.
+
+ except KeyError: # Not all nodes in the chain have a next node
+ continue
+
+ if not found_new_soname: # We're done, that last iteration found
+ break # no new nodes
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)
+ for abi in object_linkings:
+ for elf in object_linkings[abi]:
+ for soname in object_linkings[abi][elf]:
+ object_reverse_linkings.setdefault(abi,{}).setdefault(soname,[]).append(elf)
return object_reverse_linkings
@@ -154,11 +185,11 @@ def main():
( library2soname, soname2library ) = get_libraries()
soname_needed = get_soname_needed( object_needed, library2soname )
- # After the appending to needed in get_soname_linkings(), forward_needed
+ # After the appending to needed in expand_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 )
+ # a copy before calling expand_linkings().
+ expand_linkings( soname_needed, soname2library )
object_linkings = object_needed
object_needed = None
@@ -169,25 +200,27 @@ def main():
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")
+ for abi in object_linkings:
+ for elf in object_linkings[abi]:
+ sonames = object_linkings[abi][elf]
+ print("%s: %s" % (abi,elf))
+ for soname in sorted(object_linkings[abi][elf]):
+ try:
+ print("\t%s\t=> %s" % (soname, soname2library[(soname,abi)]))
+ except KeyError:
+ print("\t%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")
+ for abi in object_linkings:
+ for soname in object_reverse_linkings[abi]:
+ try:
+ print("%s: %s\t=> %s" % (abi, soname, soname2library[(soname,abi)]))
+ except KeyError:
+ print("%s: %s\t=>%s " % (abi, soname, '***'))
+ for elf in sorted(object_reverse_linkings[abi][soname]):
+ print("\t%s" % elf)
+ print("\n\n")
if __name__ == '__main__':
diff --git a/misc/link_maps_portage b/misc/link_maps_portage
index bf5b447..f55db6a 100755
--- a/misc/link_maps_portage
+++ b/misc/link_maps_portage
@@ -19,7 +19,11 @@ import portage
"""
Return object_needed dictionary which has structure
- { full_path_to_ELF_object : [ soname1, soname2, ... ], ... }
+ {
+ abi1 : { full_path_to_ELF_object : [ soname1, soname2, ... ], ... },
+ abi2 : { full_path_to_ELF_object : [ soname1, soname2, ... ], ... },
+ ....
+ }
Here the sonames were obtained from the ELF object by scanelf -nm
(like readelf -d) during emerge.
@@ -47,11 +51,11 @@ def get_object_needed():
"""
Return library2soname dictionary which has structure
- { full_path_to_library : soname, ... }
+ { full_path_to_library : (soname, abi), ... }
and its inverse which has structure
- { soname : full_path_to_library, ... }
+ { (soname, abi) : full_path_to_library, ... }
"""
def get_libraries():
@@ -77,9 +81,12 @@ def get_libraries():
"""
-Return get_soname_needed dictionary which has structure:
+Return soname_needed dictionary which has structure:
- { soname : [ soname1, soname2, ... ], .... }
+ {
+ abi1: { soname: [ soname1, soname2, ... ], .... },
+ abi2: { soname: [ soname1, soname2, ... ], .... },
+ }
Here the soname1, soname2,... were obtained from soname's corresponding
ELF object by scanelf -n during emerge.
@@ -88,46 +95,68 @@ 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
+ for abi in object_needed:
+ for elf in object_needed[abi]:
+ try:
+ (soname, abi_check) = library2soname[elf]
+ if abi != abi_check:
+ print "This should never happen!"
+ sys.exit(1)
+ soname_needed.setdefault(abi,{}).update({soname:object_needed[abi][elf]})
+ 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
+"""
+Expands the object_needed dictionary which has structure
+
+ {
+ abi1 : { full_path_to_ELF_object : [ soname1, soname2, ... ], ... },
+ abi2 : { full_path_to_ELF_object : [ soname1, soname2, ... ], ... },
+ ....
+ }
- if count == 0:
- break
- return
+such that the soname's are traced all the way to the end of
+the link chain. Here the sonames should be the same as those
+obtained from the ELF object by ldd.
+"""
+def expand_linkings( object_needed, soname2library ):
+
+ for abi in object_needed:
+ for elf in object_needed[abi]:
+ while True:
+ found_new_soname = False
+ for so in object_needed[abi][elf]: # For all the first links ...
+ try:
+ for sn in object_needed[abi][soname2library[(so,abi)]]: # go to the next links ...
+ if sn in object_needed[abi][elf]: # skip if already included ...
+ continue
+ if not (sn,abi) in soname2library: # skip if vdso ...
+ continue
+ # This appends to the object_needed
+ # and soname_needed lists. No copy
+ # was done so its the same lists in
+ # memory for both, and its modified
+ # for both.
+ object_needed[abi][elf].append(sn) # otherwise collapse it back into
+ found_new_soname = True # first links of the chain.
+
+ except KeyError: # Not all nodes in the chain have a next node
+ continue
+
+ if not found_new_soname: # We're done, that last iteration found
+ break # no new nodes
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)
+ for abi in object_linkings:
+ for elf in object_linkings[abi]:
+ for soname in object_linkings[abi][elf]:
+ object_reverse_linkings.setdefault(abi,{}).setdefault(soname,[]).append(elf)
return object_reverse_linkings
@@ -144,11 +173,11 @@ def main():
( library2soname, soname2library ) = get_libraries()
soname_needed = get_soname_needed( object_needed, library2soname )
- # After the appending to needed in get_soname_linkings(), forward_needed
+ # After the appending to needed in expand_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 )
+ # a copy before calling expand_linkings().
+ expand_linkings( soname_needed, soname2library )
object_linkings = object_needed
object_needed = None
@@ -159,25 +188,27 @@ def main():
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")
+ for abi in object_linkings:
+ for elf in object_linkings[abi]:
+ sonames = object_linkings[abi][elf]
+ print("%s: %s" % (abi,elf))
+ for soname in sorted(object_linkings[abi][elf]):
+ try:
+ print("\t%s\t=> %s" % (soname, soname2library[(soname,abi)]))
+ except KeyError:
+ print("\t%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")
+ for abi in object_linkings:
+ for soname in object_reverse_linkings[abi]:
+ try:
+ print("%s: %s\t=> %s" % (abi, soname, soname2library[(soname,abi)]))
+ except KeyError:
+ print("%s: %s\t=>%s " % (abi, soname, '***'))
+ for elf in sorted(object_reverse_linkings[abi][soname]):
+ print("\t%s" % elf)
+ print("\n\n")
if __name__ == '__main__':
next reply other threads:[~2012-12-29 1:16 UTC|newest]
Thread overview: 19+ messages / expand[flat|nested] mbox.gz Atom feed top
2012-12-29 1:16 Anthony G. Basile [this message]
-- strict thread matches above, loose matches on Subject: below --
2012-12-29 1:29 [gentoo-commits] proj/elfix:elfix-0.7.x commit in: misc/ Anthony G. Basile
2012-12-29 1:16 Anthony G. Basile
2012-12-29 1:16 Anthony G. Basile
2012-12-29 1:16 Anthony G. Basile
2012-12-29 1:16 Anthony G. Basile
2012-12-29 1:16 Anthony G. Basile
2012-12-29 1:16 Anthony G. Basile
2012-12-24 10:59 Anthony G. Basile
2012-12-24 10:59 Anthony G. Basile
2012-12-24 10:59 Anthony G. Basile
2012-12-24 10:59 Anthony G. Basile
2012-12-24 10:59 Anthony G. Basile
2012-12-24 10:59 Anthony G. Basile
2012-12-24 10:59 Anthony G. Basile
2012-12-24 10:59 Anthony G. Basile
2012-12-24 10:59 Anthony G. Basile
2012-12-24 10:59 Anthony G. Basile
2012-12-24 10:59 Anthony G. Basile
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=1356743239.f72fd5f0434f17c7052d8b1fec0bc7f3c8c400e2.blueness@gentoo \
--to=blueness@gentoo.org \
--cc=gentoo-commits@lists.gentoo.org \
--cc=gentoo-dev@lists.gentoo.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox