public inbox for gentoo-commits@lists.gentoo.org
 help / color / mirror / Atom feed
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__':


             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