* [gentoo-commits] proj/elfix:master commit in: misc/
@ 2012-12-23 1:02 Anthony G. Basile
0 siblings, 0 replies; 30+ messages in thread
From: Anthony G. Basile @ 2012-12-23 1:02 UTC (permalink / raw
To: gentoo-commits
commit: 2139325a508786968aecf364203d8ab17d0e575f
Author: Anthony G. Basile <blueness <AT> gentoo <DOT> org>
AuthorDate: Sun Dec 23 01:02:47 2012 +0000
Commit: Anthony G. Basile <blueness <AT> gentoo <DOT> org>
CommitDate: Sun Dec 23 01:02:47 2012 +0000
URL: http://git.overlays.gentoo.org/gitweb/?p=proj/elfix.git;a=commit;h=2139325a
misc/alt-revdep-pax: integration with the old revdep-pax
---
misc/alt-revdep-pax | 503 +++++++++++++++++++++++++++++++-----
misc/{alt-revdep-pax => link_maps} | 0
2 files changed, 440 insertions(+), 63 deletions(-)
diff --git a/misc/alt-revdep-pax b/misc/alt-revdep-pax
index a6adacd..6c0c7ba 100755
--- a/misc/alt-revdep-pax
+++ b/misc/alt-revdep-pax
@@ -1,4 +1,21 @@
#!/usr/bin/env python
+#
+# alt-revdep-pax: this file is part of the elfix package
+# Copyright (C) 2011 Anthony G. Basile
+#
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+#
#
# Note: This alternative way of doing revdep-pax only
@@ -9,12 +26,21 @@
# echo "${arch:3};${obj};${soname};${rpath};${needed}" >> "${PORTAGE_BUILDDIR}"/build-info/NEEDED.ELF.2
#
+import getopt
import os
import sys
import re
import pax
+""" python2/3 compat input """
+def get_input(prompt):
+ if sys.hexversion > 0x03000000:
+ return input(prompt)
+ else:
+ return raw_input(prompt)
+
+
"""
Return object_needed dictionary which has structure
@@ -132,6 +158,14 @@ def get_soname_linkings( soname_needed, soname2library ):
return
+def get_object_linkings():
+ object_needed = get_object_needed()
+ ( library2soname, soname2library ) = get_libraries()
+ soname_needed = get_soname_needed( object_needed, library2soname )
+ get_soname_linkings( soname_needed, soname2library )
+ return ( object_needed, soname2library )
+
+
def get_object_reverse_linkings( object_linkings ):
object_reverse_linkings = {}
@@ -142,83 +176,426 @@ def get_object_reverse_linkings( object_linkings ):
return object_reverse_linkings
-def main():
+#XXXXXXXXXXXXXXXX
+def invert_linkings( forward_linkings ):
+ reverse_linkings = {}
+ return reverse_linkings
+#XXXXXXXXXXXXXXXX
- # 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 )
+def print_object_linkings( object_linkings, soname2library, verbose ):
- # 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 )
+ elfs_without_flags = []
+ sonames_without_flags = []
+ sonames_missing_library = []
+
+ for elf in object_linkings:
+ try:
+ ( elf_str_flags, elf_bin_flags ) = pax.getflags(elf)
+ sv = '%s ( %s )\n' % ( elf, elf_str_flags )
+ s = sv
+ except pax.PaxError:
+ elf_without_flags.append(elf)
+ continue
+
+ count = 0
+ for soname in object_linkings[elf]:
+ try:
+ library = soname2library[soname]
+ ( library_str_flags, library_bin_flags ) = pax.getflags(library)
+ sv = '%s\n\t%s\t%s ( %s )' % ( sv, soname, library, library_str_flags )
+ if elf_str_flags != library_str_flags:
+ s = '%s\n\t%s\t%s ( %s )' % ( s, soname, library, library_str_flags )
+ count = count + 1
+ except KeyError:
+ sonames_missing_library.append(soname)
+ except pax.PaxError:
+ sonames_without_flags.append(soname)
+
+
+ if verbose:
+ print('%s\n' % sv)
+ if count == 0:
+ print('\tNo mismatches\n\n')
+ else:
+ print('\tMismatches\n\n')
+ else:
+ if count != 0:
+ print('%s\n\n' % s)
- object_linkings = object_needed
- object_needed = None
+ elfs_without_flags = set(elfs_without_flags)
+ print('\n**** ELF objections without any PAX flags ****')
+ for m in elfs_without_flags:
+ print('\t%s' % m)
- soname_linkings = soname_needed
- soname_needed = None
+ sonames_without_flags = set(sonames_without_flags)
+ print('\n**** SONAMEs with library files without PAX flags ****')
+ for m in sonames_without_flags:
+ print('\t%s' % m)
- object_reverse_linkings = get_object_reverse_linkings( object_linkings )
+ sonames_missing_library = set(sonames_missing_library)
+ print('\n**** SONAMES without any library files ****')
+ for m in sonames_missing_library:
+ print('\t%s' % m)
- """ Print out all ELF objects and their PaX flags
- for elf in object_needed:
+
+def run_forward(verbose):
+ ( object_linkings, soname2library ) = get_object_linkings()
+ print_object_linkings( object_linkings, soname2library, verbose)
+
+
+def print_reverse_linkings( reverse_linkings, so2library_mappings, verbose, executable_only ):
+ shell_path = path = os.getenv('PATH').split(':')
+ missing_sonames = []
+ missing_links = []
+
+ for soname in reverse_linkings:
try:
- flags = pax.getflags(elf)[0]
- if flags:
- print("%s %s" % (flags, elf))
+ library = so2library_mappings[soname]
+ ( library_str_flags, library_bin_flags ) = pax.getflags(library)
+ sv = '%s\t%s ( %s )\n' % ( soname, library, library_str_flags )
+ s = sv
+ except pax.PaxError:
+ missing_sonames.append(soname)
+ continue
+
+ count = 0
+ for binary in reverse_linkings[soname]:
+ try:
+ ( binary_str_flags, binary_bin_flags ) = pax.getflags(binary)
+ if executable_only:
+ if os.path.dirname(binary) in shell_path:
+ sv = '%s\n\t%s ( %s )' % ( sv, binary, binary_str_flags )
+ if library_str_flags != binary_str_flags:
+ s = '%s\n\t%s ( %s )' % ( s, binary, binary_str_flags )
+ count = count + 1
+ else:
+ sv = '%s\n\t%s ( %s )' % ( sv, binary, binary_str_flags )
+ if library_str_flags != binary_str_flags:
+ s = '%s\n\t%s ( %s )' % ( s, binary, binary_str_flags )
+ count = count + 1
+ except pax.PaxError:
+ missing_links.append(binary)
+
+ if verbose:
+ print('%s\n' % sv)
+ if count == 0:
+ print('\tNo mismatches\n\n')
else:
- print("NONE: %s" % elf)
- except pax.error:
- print("CANT: %s" % elf)
+ print('\tMismatches\n\n')
+ else:
+ if count != 0:
+ print('%s\n\n' % s)
+
+ missing_sonames = set(missing_sonames)
+ print('\n**** Missing sonames ****\n')
+ for m in missing_sonames:
+ print('\t%s\n' % m)
+
+ missing_links = set(missing_links)
+ print('\n**** Missing reverse linkings ****\n')
+ for m in missing_links:
+ print('\t%s\n' % m)
+
+
+def run_reverse(verbose, executable_only):
+ ( forward_linkings, so2library_mappings ) = get_object_linkings()
+ reverse_linkings = invert_linkings( forward_linkings )
+ print_reverse_linkings( reverse_linkings, so2library_mappings, verbose, executable_only)
+
+
+def migrate_flags(importer, exporter_str_flags, exporter_bin_flags):
+ # We implement the following logic for setting the pax flags
+ # on the target elf object, the IMPORTER, given that the flags
+ # from the elf object we want it to match to, the EXPORTER.
+ #
+ # EXPORTER IMPORTER RESULT
+ # On On On
+ # On Off On + Warn
+ # On - On
+ # Off On On + Warn
+ # Off Off Off
+ # Off - Off
+ # - On On
+ # - Off Off
+ # - - -
+
+ #See /usr/include/elf.h for these values
+ pf_flags = {
+ 'P':1<<4, 'p':1<<5,
+ 'S':1<<6, 's':1<<7,
+ 'M':1<<8, 'm':1<<9,
+ 'X':1<<10, 'x':1<<11,
+ 'E':1<<12, 'e':1<<13,
+ 'R':1<<14, 'r':1<<15
+ }
+
+ ( importer_str_flags, importer_bin_flags ) = pax.getflags(importer)
+
+ # Start with the exporter's flags
+ result_bin_flags = exporter_bin_flags
+
+ for i in range(len(importer_str_flags)):
+
+ # The exporter's flag contradicts the importer's flag, so do nothing
+ if (exporter_str_flags[i].isupper() and importer_str_flags[i].islower()) or \
+ (exporter_str_flags[i].islower() and importer_str_flags[i].isupper()):
+
+ # Revert the exporter's flag, use the importer's flag and warn
+ result_bin_flags = result_bin_flags ^ pf_flags[exporter_str_flags[i]]
+ result_bin_flags = result_bin_flags | pf_flags[importer_str_flags[i]]
+ print('\t\tWarning: %s has %s, refusing to set to %s' % (
+ importer, importer_str_flags[i], exporter_str_flags[i] )),
+
+ # The exporter's flags is off, so use the importer's flag
+ if (exporter_str_flags[i] == '-' and importer_str_flags[i] != '-'):
+ result_bin_flags = result_bin_flags | pf_flags[importer_str_flags[i]]
+
+ pax.setbinflags(importer, result_bin_flags)
+
+
+def run_binary(binary, verbose, mark, allyes):
+ if not os.path.exists(binary):
+ print('%s\tNo such OBJECT' % binary)
+ return
+ ( linkings, mappings ) = get_ldd_linkings(binary)
+ ( binary_str_flags, binary_bin_flags ) = pax.getflags(binary)
+ print('%s (%s)\n' % ( binary, binary_str_flags ))
+
+ mismatched_libraries = []
+
+ for soname in linkings:
+ try:
+ library = mappings[soname]
+ ( library_str_flags, library_bin_flags ) = pax.getflags(library)
+ if verbose:
+ print('\t%s\t%s ( %s )' % ( soname, library, library_str_flags ))
+ if binary_str_flags != library_str_flags:
+ mismatched_libraries.append(library)
+ if not verbose:
+ print('\t%s\t%s ( %s )' % ( soname, library, library_str_flags ))
+ except pax.PaxError:
+ print('file for soname %s not found' % soname)
+
+ if len(mismatched_libraries) == 0:
+ if not verbose:
+ print('\tNo mismatches\n')
+ else:
+ print('\n'),
+ if mark:
+ print('\tWill mark libraries with %s\n' % binary_str_flags)
+ for library in mismatched_libraries:
+ do_marking = False
+ while True:
+ if allyes:
+ ans = 'y'
+ else:
+ ans = get_input('\tSet flags for %s (y/n): ' % library)
+ if ans == 'y':
+ do_marking = True
+ break
+ elif ans == 'n':
+ do_marking = False
+ break
+ else:
+ print('\t\tPlease enter y or n')
+
+ if do_marking:
+ try:
+ migrate_flags(library, binary_str_flags, binary_bin_flags)
+ except pax.PaxError:
+ print("\n\tCould not set pax flags on %s, file is probably busy" % library)
+ print("\tShut down all processes that use it and try again")
+ ( library_str_flags, library_bin_flags ) = pax.getflags(library)
+ print('\n\t\t%s ( %s )\n' % ( library, library_str_flags ))
+
+
+def invert_so2library_mappings( so2library_mappings ):
+ library2soname_mappings = {}
+ for soname, library in so2library_mappings.items():
+ library2soname_mappings[library] = soname
+ return library2soname_mappings
+
+#XXXXXXXXXXXXXXXXX
+
+def run_soname(name, verbose, use_soname, mark, allyes, executable_only):
+ shell_path = path = os.getenv('PATH').split(':')
+
+ ( forward_linkings, so2library_mappings ) = get_object_linkings()
+ reverse_linkings = invert_linkings( forward_linkings )
+
+ if use_soname:
+ soname = name
+ else:
+ library2soname_mappings = invert_so2library_mappings(so2library_mappings)
+ try:
+ soname = library2soname_mappings[name]
+ except KeyError:
+ print('%s\tNo such LIBRARY' % name)
+ return
- """
+ try:
+ linkings = reverse_linkings[soname]
+ except KeyError:
+ print('%s\tNo such SONAME' % soname)
+ return
- """ Print out all sonames and their library paths
- for soname in sorted(soname2library):
- elf = soname2library[soname]
- print("%s : %s" % ( soname, elf ))
- """
+ library = so2library_mappings[soname]
+ ( library_str_flags, library_bin_flags ) = pax.getflags(library)
+ print('%s\t%s (%s)\n' % ( soname, library, library_str_flags ))
- """ Print out all ELF objects and the NEEDED sonames and full library paths
- for elf in object_needed:
- sonames = object_needed[elf]
- print("%s" % elf)
- for soname in sorted(object_needed[elf]):
- try:
- print("\t%s\t=> %s" % (soname, soname2library[soname]))
- except KeyError:
- print("\t%s\t=> ****" % soname)
- print("\n\n")
- """
+ mismatched_binaries = []
+ for binary in linkings:
+ try:
+ ( binary_str_flags, binary_bin_flags ) = pax.getflags(binary)
+ if verbose:
+ if executable_only:
+ if os.path.dirname(binary) in shell_path:
+ print('\t%s ( %s )' % ( binary, binary_str_flags ))
+ else:
+ print('\t%s ( %s )' % ( binary, binary_str_flags ))
+ if library_str_flags != binary_str_flags:
+ if executable_only:
+ if os.path.dirname(binary) in shell_path:
+ mismatched_binaries.append(binary)
+ if not verbose:
+ print('\t%s ( %s )' % ( binary, binary_str_flags ))
+ else:
+ mismatched_binaries.append(binary)
+ if not verbose:
+ print('\t%s ( %s )' % ( binary, binary_str_flags ))
+ except pax.PaxError:
+ print('cannot obtain pax flags for %s' % binary)
+
+ if len(mismatched_binaries) == 0:
+ if not verbose:
+ print('\tNo mismatches\n')
+ else:
+ print('\n'),
+ if mark:
+ print('\tWill mark binaries with %s\n' % library_str_flags)
+ for binary in mismatched_binaries:
+ if executable_only:
+ if not os.path.dirname(binary) in shell_path:
+ continue
+ do_marking = False
+ while True:
+ if allyes:
+ ans = 'y'
+ else:
+ ans = get_input('\tSet flags for %s (y/n): ' % binary)
+ if ans == 'y':
+ do_marking = True
+ break
+ elif ans == 'n':
+ do_marking = False
+ break
+ else:
+ print('\t\tPlease enter y or n')
+ if do_marking:
+ try:
+ migrate_flags(binary, library_str_flags, library_bin_flags)
+ except pax.PaxError:
+ print('\n\tCould not set pax flags on %s, file is probably busy' % binary)
+ print('\tShut down all processes that use it and try again')
+ ( binary_str_flags, binary_bin_flags ) = pax.getflags(binary)
+ print('\n\t\t%s ( %s )\n' % ( binary, binary_str_flags ))
+
+
+def run_usage():
+ print('Package Name : elfix')
+ print('Bug Reports : http://bugs.gentoo.org/')
+ print('Program Name : revdep-pax')
+ print('Description : Get or set pax flags on an ELF object')
+ print('')
+ print('Usage : revdep-pax -f [-v] print out all forward mappings for all system binaries')
+ print(' : revdep-pax -r [-ve] print out all reverse mappings for all system sonames')
+ print(' : revdep-pax -b OBJECT [-myv] print all forward mappings only for OBJECT')
+ print(' : revdep-pax -s SONAME [-myve] print all reverse mappings only for SONAME')
+ print(' : revdep-pax -l LIBRARY [-myve] print all reverse mappings only for LIBRARY file')
+ print(' : revdep-pax [-h] print out this help')
+ print(' : -v verbose, otherwise just print mismatching objects')
+ print(' : -e only print out executables in shell $PATH')
+ print(' : -m don\'t just report, but mark the mismatching objects')
+ print(' : -y assume "yes" to all prompts for marking (USE CAREFULLY!)')
+ print('')
+
+
+def main():
+ try:
+ opts, args = getopt.getopt(sys.argv[1:], 'hfrb:s:l:vemy')
+ except getopt.GetoptError as err:
+ print(str(err)) # will print something like 'option -a not recognized'
+ run_usage()
+ sys.exit(1)
+
+ if len(opts) == 0:
+ run_usage()
+ sys.exit(1)
+
+ do_usage = False
+ do_forward = False
+ do_reverse = False
+
+ binary = None
+ soname = None
+ library = None
+
+ verbose = False
+ executable_only = False
+ mark = False
+ allyes = False
+
+ opt_count = 0
+
+ for o, a in opts:
+ if o == '-h':
+ do_usage = True
+ opt_count += 1
+ elif o == '-f':
+ do_forward = True
+ opt_count += 1
+ elif o == '-r':
+ do_reverse = True
+ opt_count += 1
+ elif o == '-b':
+ binary = a
+ opt_count += 1
+ elif o == '-s':
+ soname = a
+ opt_count += 1
+ elif o == '-l':
+ library = a
+ opt_count += 1
+ elif o == '-v':
+ verbose = True
+ elif o == '-e':
+ executable_only = True
+ elif o == '-m':
+ mark = True
+ elif o == '-y':
+ allyes = True
+ else:
+ print('Option included in getopt but not handled here!')
+ print('Please file a bug')
+ sys.exit(1)
+
+ # Only allow one of -h, -f -r -b -s
+ if opt_count > 1 or do_usage:
+ run_usage()
+ elif do_forward:
+ run_forward(verbose)
+ elif do_reverse:
+ run_reverse(verbose, executable_only)
+ elif binary != None:
+ run_binary(binary, verbose, mark, allyes)
+ elif soname != None:
+ run_soname(soname, verbose, True, mark, allyes, executable_only)
+ elif library != None:
+ library = os.path.realpath(library)
+ run_soname(library, verbose, False, mark, allyes, executable_only)
- """ 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/alt-revdep-pax b/misc/link_maps
similarity index 100%
copy from misc/alt-revdep-pax
copy to misc/link_maps
^ permalink raw reply related [flat|nested] 30+ messages in thread
* [gentoo-commits] proj/elfix:master commit in: misc/
@ 2016-02-13 21:38 Anthony G. Basile
0 siblings, 0 replies; 30+ messages in thread
From: Anthony G. Basile @ 2016-02-13 21:38 UTC (permalink / raw
To: gentoo-commits
commit: 1d6d75bd4e5143e56b09a664df58d719fbe92164
Author: Anthony G. Basile <blueness <AT> gentoo <DOT> org>
AuthorDate: Sat Feb 13 21:47:16 2016 +0000
Commit: Anthony G. Basile <blueness <AT> gentoo <DOT> org>
CommitDate: Sat Feb 13 21:47:16 2016 +0000
URL: https://gitweb.gentoo.org/proj/elfix.git/commit/?id=1d6d75bd
misc/bundle.sh: generalize bundle.sh for all misc packages
misc/bundle.sh | 16 ++++++++++++++++
misc/install-xattr-bundle.sh | 10 ----------
2 files changed, 16 insertions(+), 10 deletions(-)
diff --git a/misc/bundle.sh b/misc/bundle.sh
new file mode 100755
index 0000000..13e9318
--- /dev/null
+++ b/misc/bundle.sh
@@ -0,0 +1,16 @@
+#!/bin/bash
+
+if [[ -z $2 ]]; then
+ echo "Usage $0 <package> <version>"
+ exit
+fi
+
+if [[ ! -d $1 ]]; then
+ echo "No such pacakge $1 to bundle"
+ exit
+fi
+
+PKG=${1%%/}
+
+tar jcvf ${PKG}-${2}.tar.bz2 ${PKG}/
+gpg -s -a -b ${PKG}-${2}.tar.bz2
diff --git a/misc/install-xattr-bundle.sh b/misc/install-xattr-bundle.sh
deleted file mode 100755
index b332606..0000000
--- a/misc/install-xattr-bundle.sh
+++ /dev/null
@@ -1,10 +0,0 @@
-#!/bin/bash
-
-if [[ -z ${1} ]]; then
- echo "Usage $0 <version>"
- exit
-fi
-
-tar jcvf install-xattr-${1}.tar.bz2 install-xattr/
-gpg -s -a -b install-xattr-${1}.tar.bz2
-
^ permalink raw reply related [flat|nested] 30+ messages in thread
* [gentoo-commits] proj/elfix:master commit in: misc/
@ 2014-02-13 19:07 Anthony G. Basile
0 siblings, 0 replies; 30+ messages in thread
From: Anthony G. Basile @ 2014-02-13 19:07 UTC (permalink / raw
To: gentoo-commits
commit: e52a4b8a482f1689af29474e4197a7f3467e86dc
Author: Anthony G. Basile <blueness <AT> gentoo <DOT> org>
AuthorDate: Thu Feb 13 19:08:46 2014 +0000
Commit: Anthony G. Basile <blueness <AT> gentoo <DOT> org>
CommitDate: Thu Feb 13 19:08:46 2014 +0000
URL: http://git.overlays.gentoo.org/gitweb/?p=proj/elfix.git;a=commit;h=e52a4b8a
misc/install-xattr-bundle.sh: to make bundling install-xattr easier
---
misc/install-xattr-bundle.sh | 10 ++++++++++
1 file changed, 10 insertions(+)
diff --git a/misc/install-xattr-bundle.sh b/misc/install-xattr-bundle.sh
new file mode 100755
index 0000000..b332606
--- /dev/null
+++ b/misc/install-xattr-bundle.sh
@@ -0,0 +1,10 @@
+#!/bin/bash
+
+if [[ -z ${1} ]]; then
+ echo "Usage $0 <version>"
+ exit
+fi
+
+tar jcvf install-xattr-${1}.tar.bz2 install-xattr/
+gpg -s -a -b install-xattr-${1}.tar.bz2
+
^ permalink raw reply related [flat|nested] 30+ messages in thread
* [gentoo-commits] proj/elfix:master commit in: misc/
@ 2013-05-21 15:21 Anthony G. Basile
0 siblings, 0 replies; 30+ messages in thread
From: Anthony G. Basile @ 2013-05-21 15:21 UTC (permalink / raw
To: gentoo-commits
commit: e9ba3f646fc2e702a2e8957ff804b347e7b2f29d
Author: Anthony G. Basile <blueness <AT> gentoo <DOT> org>
AuthorDate: Tue May 21 15:21:13 2013 +0000
Commit: Anthony G. Basile <blueness <AT> gentoo <DOT> org>
CommitDate: Tue May 21 15:21:13 2013 +0000
URL: http://git.overlays.gentoo.org/gitweb/?p=proj/elfix.git;a=commit;h=e9ba3f64
misc/pax-utils.eclass: add a copy for the records
---
misc/pax-utils.eclass | 218 +++++++++++++++++++++++++++++++++++++++++++++++++
1 files changed, 218 insertions(+), 0 deletions(-)
diff --git a/misc/pax-utils.eclass b/misc/pax-utils.eclass
new file mode 100644
index 0000000..547d6ac
--- /dev/null
+++ b/misc/pax-utils.eclass
@@ -0,0 +1,218 @@
+# Copyright 1999-2013 Gentoo Foundation
+# Distributed under the terms of the GNU General Public License v2
+# $Header: /var/cvsroot/gentoo-x86/eclass/pax-utils.eclass,v 1.21 2013/05/18 13:43:20 zorry Exp $
+
+# @ECLASS: pax-utils.eclass
+# @MAINTAINER:
+# The Gentoo Linux Hardened Team <hardened@gentoo.org>
+# @AUTHOR:
+# Original Author: Kevin F. Quinn <kevquinn@gentoo.org>
+# Modifications for bug #365825, @ ECLASS markup: Anthony G. Basile <blueness@gentoo.org>
+# Modifications for bug #431092: Anthony G. Basile <blueness@gentoo.org>
+# @BLURB: functions to provide pax markings
+# @DESCRIPTION:
+#
+# This eclass provides support for manipulating PaX markings on ELF binaries,
+# whether the system is using legacy PT_PAX markings or the newer XATTR_PAX.
+# The eclass wraps the use of paxctl-ng, paxctl, set/getattr and scanelf utilities,
+# deciding which to use depending on what's installed on the build host, and
+# whether we're working with PT_PAX, XATTR_PAX or both.
+#
+# To control what markings are made, set PAX_MARKINGS in /etc/portage/make.conf
+# to contain either "PT", "XT" or "none". The default is to attempt both
+# PT_PAX and XATTR_PAX.
+
+if [[ ${___ECLASS_ONCE_PAX_UTILS} != "recur -_+^+_- spank" ]] ; then
+___ECLASS_ONCE_PAX_UTILS="recur -_+^+_- spank"
+
+# @ECLASS-VARIABLE: PAX_MARKINGS
+# @DESCRIPTION:
+# Control which markings are made:
+# PT = PT_PAX markings, XT = XATTR_PAX markings
+# Default to PT markings.
+PAX_MARKINGS=${PAX_MARKINGS:="PT"}
+
+# @FUNCTION: pax-mark
+# @USAGE: <flags> {<ELF files>}
+# @RETURN: Shell true if we succeed, shell false otherwise
+# @DESCRIPTION:
+# Marks <ELF files> with provided PaX <flags>
+#
+# Flags are passed directly to the utilities unchanged
+#
+# p: disable PAGEEXEC P: enable PAGEEXEC
+# e: disable EMUTRAMP E: enable EMUTRAMP
+# m: disable MPROTECT M: enable MPROTECT
+# r: disable RANDMMAP R: enable RANDMMAP
+# s: disable SEGMEXEC S: enable SEGMEXEC
+#
+# Default flags are 'PeMRS', which are the most restrictive settings. Refer
+# to http://pax.grsecurity.net/ for details on what these flags are all about.
+#
+# Please confirm any relaxation of restrictions with the Gentoo Hardened team.
+# Either ask on the gentoo-hardened mailing list, or CC/assign hardened@g.o on
+# the bug report.
+pax-mark() {
+
+ local f # loop over paxables
+ local flags # pax flags
+ local pt_fail=0 pt_failures="" # record PT_PAX failures
+ local xt_fail=0 xt_failures="" # record xattr PAX marking failures
+ local ret=0 # overal return code of this function
+
+ # Only the actual PaX flags and z are accepted
+ # 1. The leading '-' is optional
+ # 2. -C -c only make sense for paxctl, but are unnecessary
+ # because we progressively do -q -qc -qC
+ # 3. z is allowed for the default
+
+ flags="${1//[!zPpEeMmRrSs]}"
+ [[ "${flags}" ]] || return 0
+ shift
+
+ # z = default. For XATTR_PAX, the default is no xattr field at all
+ local dodefault=""
+ [[ "${flags//[!z]}" ]] && dodefault="yes"
+
+ if has PT ${PAX_MARKINGS}; then
+
+ #First try paxctl -> this might try to create/convert program headers
+ if type -p paxctl > /dev/null; then
+ einfo "PT PaX marking -${flags} with paxctl"
+ _pax_list_files einfo "$@"
+ for f in "$@"; do
+ # First, try modifying the existing PAX_FLAGS header
+ paxctl -q${flags} "${f}" && continue
+ # Second, try creating a PT_PAX header (works on ET_EXEC)
+ # Even though this is less safe, most exes need it, eg bug #463170
+ paxctl -qC${flags} "${f}" && continue
+ # Third, try stealing the (unused under PaX) PT_GNU_STACK header
+ paxctl -qc${flags} "${f}" && continue
+ pt_fail=1
+ pt_failures="${pt_failures} ${f}"
+ done
+
+ #Next try paxctl-ng -> this will not create/convert any program headers
+ elif type -p paxctl-ng > /dev/null && paxctl-ng -L ; then
+ einfo "PT PaX marking -${flags} with paxctl-ng"
+ flags="${flags//z}"
+ _pax_list_files einfo "$@"
+ for f in "$@"; do
+ [[ ${dodefault} == "yes" ]] && paxctl-ng -L -z "${f}"
+ [[ "${flags}" ]] || continue
+ paxctl-ng -L -${flags} "${f}" && continue
+ pt_fail=1
+ pt_failures="${pt_failures} ${f}"
+ done
+
+ #Finally fall back on scanelf
+ elif type -p scanelf > /dev/null && [[ ${PAX_MARKINGS} != "none" ]]; then
+ einfo "Fallback PaX marking -${flags} with scanelf"
+ _pax_list_files einfo "$@"
+ scanelf -Xxz ${flags} "$@"
+
+ #We failed to set PT_PAX flags
+ elif [[ ${PAX_MARKINGS} != "none" ]]; then
+ pt_failures="$*"
+ pt_fail=1
+ fi
+
+ if [[ ${pt_fail} == 1 ]]; then
+ elog "Failed to set PT_PAX markings -${flags} for:"
+ _pax_list_files elog ${pt_failures}
+ ret=1
+ fi
+ fi
+
+ if has XT ${PAX_MARKINGS}; then
+
+ flags="${flags//z}"
+
+ #First try paxctl-ng
+ if type -p paxctl-ng > /dev/null && paxctl-ng -l ; then
+ einfo "XT PaX marking -${flags} with paxctl-ng"
+ _pax_list_files einfo "$@"
+ for f in "$@"; do
+ [[ ${dodefault} == "yes" ]] && paxctl-ng -d "${f}"
+ [[ "${flags}" ]] || continue
+ paxctl-ng -l -${flags} "${f}" && continue
+ xt_fail=1
+ xt_failures="${tx_failures} ${f}"
+ done
+
+ #Next try setfattr
+ elif type -p setfattr > /dev/null; then
+ [[ "${flags//[!Ee]}" ]] || flags+="e" # bug 447150
+ einfo "XT PaX marking -${flags} with setfattr"
+ _pax_list_files einfo "$@"
+ for f in "$@"; do
+ [[ ${dodefault} == "yes" ]] && setfattr -x "user.pax.flags" "${f}"
+ setfattr -n "user.pax.flags" -v "${flags}" "${f}" && continue
+ xt_fail=1
+ xt_failures="${tx_failures} ${f}"
+ done
+
+ #We failed to set XATTR_PAX flags
+ elif [[ ${PAX_MARKINGS} != "none" ]]; then
+ xt_failures="$*"
+ xt_fail=1
+ fi
+
+ if [[ ${xt_fail} == 1 ]]; then
+ elog "Failed to set XATTR_PAX markings -${flags} for:"
+ _pax_list_files elog ${xt_failures}
+ ret=1
+ fi
+ fi
+
+ # [[ ${ret} == 1 ]] && elog "Executables may be killed by PaX kernels."
+
+ return ${ret}
+}
+
+# @FUNCTION: list-paxables
+# @USAGE: {<files>}
+# @RETURN: Subset of {<files>} which are ELF executables or shared objects
+# @DESCRIPTION:
+# Print to stdout all of the <files> that are suitable to have PaX flag
+# markings, i.e., filter out the ELF executables or shared objects from a list
+# of files. This is useful for passing wild-card lists to pax-mark, although
+# in general it is preferable for ebuilds to list precisely which ELFS are to
+# be marked. Often not all the ELF installed by a package need remarking.
+# @EXAMPLE:
+# pax-mark -m $(list-paxables ${S}/{,usr/}bin/*)
+list-paxables() {
+ file "$@" 2> /dev/null | grep -E 'ELF.*(executable|shared object)' | sed -e 's/: .*$//'
+}
+
+# @FUNCTION: host-is-pax
+# @RETURN: Shell true if the build process is PaX enabled, shell false otherwise
+# @DESCRIPTION:
+# This is intended for use where the build process must be modified conditionally
+# depending on whether the host is PaX enabled or not. It is not intedened to
+# determine whether the final binaries need PaX markings. Note: if procfs is
+# not mounted on /proc, this returns shell false (e.g. Gentoo/FBSD).
+host-is-pax() {
+ grep -qs ^PaX: /proc/self/status
+}
+
+
+# INTERNAL FUNCTIONS
+# ------------------
+#
+# These functions are for use internally by the eclass - do not use
+# them elsewhere as they are not supported (i.e. they may be removed
+# or their function may change arbitratily).
+
+# Display a list of things, one per line, indented a bit, using the
+# display command in $1.
+_pax_list_files() {
+ local f cmd
+ cmd=$1
+ shift
+ for f in "$@"; do
+ ${cmd} " ${f}"
+ done
+}
+
+fi
^ permalink raw reply related [flat|nested] 30+ messages in thread
* [gentoo-commits] proj/elfix:master commit in: misc/
@ 2013-02-09 21:50 Anthony G. Basile
0 siblings, 0 replies; 30+ messages in thread
From: Anthony G. Basile @ 2013-02-09 21:50 UTC (permalink / raw
To: gentoo-commits
commit: 590ee3ea903fcf3fa6baf5194cc339ccc4c67bba
Author: Anthony G. Basile <blueness <AT> gentoo <DOT> org>
AuthorDate: Sat Feb 9 21:49:46 2013 +0000
Commit: Anthony G. Basile <blueness <AT> gentoo <DOT> org>
CommitDate: Sat Feb 9 21:49:46 2013 +0000
URL: http://git.overlays.gentoo.org/gitweb/?p=proj/elfix.git;a=commit;h=590ee3ea
misc/remove-ptpax.c: code to convert PT_PAX_FLAGS to PT_NULL phdr
---
misc/remove-ptpax.c | 103 +++++++++++++++++++++++++++++++++++++++++++++++++++
1 files changed, 103 insertions(+), 0 deletions(-)
diff --git a/misc/remove-ptpax.c b/misc/remove-ptpax.c
new file mode 100644
index 0000000..ba441a5
--- /dev/null
+++ b/misc/remove-ptpax.c
@@ -0,0 +1,103 @@
+/*
+ remove-ptpax.c: this file is part of the elfix package
+ Copyright (C) 2013 Anthony G. Basile
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
+*/
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <gelf.h>
+
+#ifndef PT_PAX_FLAGS
+ #define PT_PAX_FLAGS 0x65041580
+#endif
+
+int
+remove_ptpax(int fd)
+{
+ Elf *elf;
+ GElf_Phdr phdr;
+ size_t i, phnum;
+
+ if(elf_version(EV_CURRENT) == EV_NONE)
+ {
+ printf("\tELF ERROR: Library out of date.\n");
+ return EXIT_FAILURE;
+ }
+
+ if((elf = elf_begin(fd, ELF_C_RDWR_MMAP, NULL)) == NULL)
+ {
+ printf("\tELF ERROR: elf_begin() fail: %s\n", elf_errmsg(elf_errno()));
+ return EXIT_FAILURE;
+ }
+
+ if(elf_kind(elf) != ELF_K_ELF)
+ {
+ elf_end(elf);
+ printf("\tELF ERROR: elf_kind() fail: this is not an elf file.\n");
+ return EXIT_FAILURE;
+ }
+
+ elf_getphdrnum(elf, &phnum);
+
+ for(i=0; i<phnum; i++)
+ {
+ if(gelf_getphdr(elf, i, &phdr) != &phdr)
+ {
+ elf_end(elf);
+ printf("\tELF ERROR: gelf_getphdr(): %s\n", elf_errmsg(elf_errno()));
+ return EXIT_FAILURE;
+ }
+
+ if(phdr.p_type == PT_PAX_FLAGS)
+ {
+ phdr.p_type = PT_NULL;
+ if(!gelf_update_phdr(elf, i, &phdr))
+ {
+ elf_end(elf);
+ printf("\tELF ERROR: gelf_update_phdr(): %s", elf_errmsg(elf_errno()));
+ return EXIT_FAILURE;
+ }
+ }
+ }
+
+ elf_end(elf);
+ return EXIT_SUCCESS;
+}
+
+
+int
+main( int argc, char *argv[])
+{
+ int fd;
+
+ if(argc != 2)
+ {
+ fprintf(stderr, "Usage: %s <filename>\n", argv[0]) ;
+ exit(EXIT_SUCCESS);
+ }
+
+ if((fd = open(argv[1], O_RDWR)) < 0)
+ {
+ printf("\topen(O_RDWR) failed: cannot change PT_PAX flags\n");
+ exit(EXIT_FAILURE);
+ }
+ else
+ exit(remove_ptpax(fd));
+
+}
^ permalink raw reply related [flat|nested] 30+ messages in thread
* [gentoo-commits] proj/elfix:master commit in: misc/
@ 2012-12-27 3:11 Anthony G. Basile
0 siblings, 0 replies; 30+ messages in thread
From: Anthony G. Basile @ 2012-12-27 3:11 UTC (permalink / raw
To: gentoo-commits
commit: 9051961e0c4fb3a916cd81a934972d9453a9a49a
Author: Anthony G. Basile <blueness <AT> gentoo <DOT> org>
AuthorDate: Thu Dec 27 03:10:58 2012 +0000
Commit: Anthony G. Basile <blueness <AT> gentoo <DOT> org>
CommitDate: Thu Dec 27 03:10:58 2012 +0000
URL: http://git.overlays.gentoo.org/gitweb/?p=proj/elfix.git;a=commit;h=9051961e
misc/alt-revdep-pax: cleanup wrt object with no pax flags
---
misc/alt-revdep-pax | 123 ++++++++++++++++++++++++--------------------------
1 files changed, 59 insertions(+), 64 deletions(-)
diff --git a/misc/alt-revdep-pax b/misc/alt-revdep-pax
index be51bf9..dda9025 100755
--- a/misc/alt-revdep-pax
+++ b/misc/alt-revdep-pax
@@ -41,15 +41,7 @@ def get_input(prompt):
return raw_input(prompt)
-def print_problems(elfs_without_flags, sonames_without_flags, sonames_missing_library):
- elfs_without_flags = set(elfs_without_flags)
- print('\n**** ELF objections without any PAX flags ****')
- for m in elfs_without_flags:
- print('\t%s' % m)
- sonames_without_flags = set(sonames_without_flags)
- print('\n**** SONAMEs with library files without PAX flags ****')
- for m in sonames_without_flags:
- print('\t%s' % m)
+def print_problems(sonames_missing_library):
sonames_missing_library = set(sonames_missing_library)
print('\n**** SONAMES without any library files ****')
for m in sonames_missing_library:
@@ -59,8 +51,6 @@ def print_problems(elfs_without_flags, sonames_without_flags, sonames_missing_li
def run_forward(verbose):
(object_linkings, object_reverse_linkings, library2soname, soname2library) = LinkMap().get_maps()
- elfs_without_flags = []
- sonames_without_flags = []
sonames_missing_library = []
for abi in object_linkings:
@@ -70,22 +60,24 @@ def run_forward(verbose):
sv = '%s :%s ( %s )' % (elf, abi, elf_str_flags)
s = sv
except pax.PaxError:
- elfs_without_flags.append(elf)
+ sv = '%s :%s ( %s )' % (elf, abi, '****')
+ s = sv
continue
count = 0
for soname in object_linkings[abi][elf]:
try:
- library = soname2library[(soname,abi)]
- (library_str_flags, library_bin_flags) = pax.getflags(library)
+ library = soname2library[(soname, abi)]
+ try:
+ (library_str_flags, library_bin_flags) = pax.getflags(library)
+ except pax.PaxError:
+ library_str_flags = '****'
sv = '%s\n\t%s\t%s ( %s )' % (sv, soname, library, library_str_flags)
if elf_str_flags != library_str_flags:
s = '%s\n\t%s\t%s ( %s )' % (s, soname, library, library_str_flags)
count = count + 1
except KeyError:
sonames_missing_library.append(soname)
- except pax.PaxError:
- sonames_without_flags.append(soname)
if verbose:
print('%s\n' % sv)
@@ -98,7 +90,7 @@ def run_forward(verbose):
print('%s\n\n' % s)
if verbose:
- print_problems(elfs_without_flags, sonames_without_flags, sonames_missing_library)
+ print_problems(sonames_missing_library)
def run_reverse(verbose, executable_only):
@@ -106,39 +98,38 @@ def run_reverse(verbose, executable_only):
shell_path = path = os.getenv('PATH').split(':')
- elfs_without_flags = []
- sonames_without_flags = []
sonames_missing_library = []
for abi in object_reverse_linkings:
for soname in object_reverse_linkings[abi]:
try:
- library = soname2library[(soname,abi)]
- (library_str_flags, library_bin_flags) = pax.getflags(library)
+ library = soname2library[(soname, abi)]
+ try:
+ (library_str_flags, library_bin_flags) = pax.getflags(library)
+ except pax.PaxError:
+ library_str_flags = '****'
sv = '%s\t%s :%s ( %s )' % (soname, library, abi, library_str_flags)
s = sv
except KeyError:
sonames_missing_library.append(soname)
- except pax.PaxError:
- sonames_without_flags.append(soname)
count = 0
for elf in object_reverse_linkings[abi][soname]:
try:
(elf_str_flags, elf_bin_flags) = pax.getflags(elf)
- if executable_only:
- if os.path.dirname(elf) in shell_path:
- sv = '%s\n\t%s ( %s )' % (sv, elf, elf_str_flags)
- if library_str_flags != elf_str_flags:
- s = '%s\n\t%s ( %s )' % (s, elf, elf_str_flags)
- count = count + 1
- else:
+ except pax.PaxError:
+ elf_str_flags = '****'
+ if executable_only:
+ if os.path.dirname(elf) in shell_path:
sv = '%s\n\t%s ( %s )' % (sv, elf, elf_str_flags)
if library_str_flags != elf_str_flags:
s = '%s\n\t%s ( %s )' % (s, elf, elf_str_flags)
count = count + 1
- except pax.PaxError:
- elfs_without_flags.append(elf)
+ else:
+ sv = '%s\n\t%s ( %s )' % (sv, elf, elf_str_flags)
+ if library_str_flags != elf_str_flags:
+ s = '%s\n\t%s ( %s )' % (s, elf, elf_str_flags)
+ count = count + 1
if verbose:
print('%s\n' % sv)
@@ -151,7 +142,7 @@ def run_reverse(verbose, executable_only):
print('%s\n\n' % s)
if verbose:
- print_problems( elfs_without_flags, sonames_without_flags, sonames_missing_library)
+ print_problems(sonames_missing_library)
def migrate_flags(importer, exporter_str_flags, exporter_bin_flags):
@@ -180,7 +171,12 @@ def migrate_flags(importer, exporter_str_flags, exporter_bin_flags):
'R':1<<14, 'r':1<<15
}
- (importer_str_flags, importer_bin_flags) = pax.getflags(importer)
+ try:
+ (importer_str_flags, importer_bin_flags) = pax.getflags(importer)
+ except pax.PaxError:
+ # The importer has no flags, so just set them
+ pax.setbinflags(importer, exporter_bin_flags)
+ return
# Start with the exporter's flags
result_bin_flags = exporter_bin_flags
@@ -226,21 +222,24 @@ def run_elf(elf, verbose, mark, allyes):
for soname in object_linkings[abi][elf]:
try:
library = soname2library[(soname,abi)]
- (library_str_flags, library_bin_flags) = pax.getflags(library)
+ try:
+ (library_str_flags, library_bin_flags) = pax.getflags(library)
+ except pax.PaxError:
+ library_str_flags = '****'
if verbose:
print('\t%s\t%s :%s ( %s )' % (soname, library, abi, library_str_flags))
if elf_str_flags != library_str_flags:
mismatched_libraries.append(library)
if not verbose:
print('\t%s\t%s :%s ( %s )' % (soname, library, abi, library_str_flags))
- except pax.PaxError:
- print('%s :%s: file for soname not found' % (soname,abi))
+ except KeyError:
+ print('%s :%s: file for soname not found' % (soname, abi))
if len(mismatched_libraries) == 0:
if not verbose:
print('\tNo mismatches\n')
else:
- print('\n'),
+ print('')
if mark:
print('\tWill mark libraries with %s\n' % elf_str_flags)
for library in mismatched_libraries:
@@ -249,7 +248,7 @@ def run_elf(elf, verbose, mark, allyes):
if allyes:
ans = 'y'
else:
- ans = get_input('\tSet flags for %s :%s (y/n): ' % (library,abi))
+ ans = get_input('\tSet flags for %s :%s (y/n): ' % (library, abi))
if ans == 'y':
do_marking = True
break
@@ -263,7 +262,7 @@ def run_elf(elf, verbose, mark, allyes):
try:
migrate_flags(library, elf_str_flags, elf_bin_flags)
except pax.PaxError:
- print('\n\tCould not set PAX flags on %s, text maybe busy' % (library,abi))
+ print('\n\tCould not set PAX flags on %s, text maybe busy' % (library, abi))
try:
(library_str_flags, library_bin_flags) = pax.getflags(library)
@@ -303,46 +302,42 @@ def run_soname(name, verbose, use_soname, mark, allyes, executable_only):
if not soname in object_reverse_linkings[abi]:
continue
- library = soname2library[(soname,abi)]
- (library_str_flags, library_bin_flags) = pax.getflags(library)
- print('%s\t%s :%s (%s)\n' % (soname, library, ", ".join(abi_list), library_str_flags))
+ library = soname2library[(soname, abi)]
+
+ try:
+ (library_str_flags, library_bin_flags) = pax.getflags(library)
+ print('%s\t%s :%s (%s)\n' % (soname, library, abi, library_str_flags))
+ except pax.PaxError:
+ print('%s :%s : No PAX flags found\n' % (library, abi))
+ continue
for elf in object_reverse_linkings[abi][soname]:
try:
(elf_str_flags, elf_bin_flags ) = pax.getflags(elf)
- if verbose:
- if executable_only:
- if os.path.dirname(elf) in shell_path:
- print('\t%s ( %s )' % (elf, elf_str_flags ))
- else:
- print('\t%s ( %s )' % ( elf, elf_str_flags ))
- if library_str_flags != elf_str_flags:
- if executable_only:
- if os.path.dirname(elf) in shell_path:
- mismatched_elfs.append(elf)
- if not verbose:
- print('\t%s ( %s )' % (elf, elf_str_flags ))
- else:
- mismatched_elfs.append(elf)
- if not verbose:
- print('\t%s ( %s )' % (elf, elf_str_flags ))
except pax.PaxError:
- # If you can't get the pax flags, then its automatically mismatched
+ elf_str_flags = '****'
+ if verbose:
+ if executable_only:
+ if os.path.dirname(elf) in shell_path:
+ print('\t%s ( %s )' % (elf, elf_str_flags))
+ else:
+ print('\t%s ( %s )' % (elf, elf_str_flags))
+ if library_str_flags != elf_str_flags:
if executable_only:
if os.path.dirname(elf) in shell_path:
mismatched_elfs.append(elf)
if not verbose:
- print('\t%s ( %s )' % (elf, '****' ))
+ print('\t%s ( %s )' % (elf, elf_str_flags))
else:
mismatched_elfs.append(elf)
if not verbose:
- print('\t%s ( %s )' % (elf, '****' ))
+ print('\t%s ( %s )' % (elf, elf_str_flags))
if len(mismatched_elfs) == 0:
if not verbose:
print('\tNo mismatches\n')
else:
- print('\n'),
+ print('')
if mark:
print('\tWill mark elf with %s\n' % library_str_flags)
for elf in mismatched_elfs:
@@ -370,7 +365,7 @@ def run_soname(name, verbose, use_soname, mark, allyes, executable_only):
print('\n\tCould not set pax flags on %s, file is probably busy' % elf)
print('\tShut down all processes that use it and try again')
(elf_str_flags, elf_bin_flags) = pax.getflags(elf)
- print('\n\t\t%s ( %s )\n' % (elf, elf_str_flags ))
+ print('\n\t\t%s ( %s )\n' % (elf, elf_str_flags))
def run_usage():
^ permalink raw reply related [flat|nested] 30+ messages in thread
* [gentoo-commits] proj/elfix:master commit in: misc/
@ 2012-12-26 21:43 Anthony G. Basile
0 siblings, 0 replies; 30+ messages in thread
From: Anthony G. Basile @ 2012-12-26 21:43 UTC (permalink / raw
To: gentoo-commits
commit: a74b692444927eb366c1d057204a124b38af5143
Author: Anthony G. Basile <blueness <AT> gentoo <DOT> org>
AuthorDate: Wed Dec 26 21:43:20 2012 +0000
Commit: Anthony G. Basile <blueness <AT> gentoo <DOT> org>
CommitDate: Wed Dec 26 21:43:20 2012 +0000
URL: http://git.overlays.gentoo.org/gitweb/?p=proj/elfix.git;a=commit;h=a74b6924
misc/link_map.py: place class in its own module
---
misc/{link_maps => link_map.py} | 61 +++++++++++----------------------------
misc/link_map_test | 61 +++++++++++++++++++++++++++++++++++++++
2 files changed, 78 insertions(+), 44 deletions(-)
diff --git a/misc/link_maps b/misc/link_map.py
similarity index 83%
rename from misc/link_maps
rename to misc/link_map.py
index 508af24..5b0e822 100755
--- a/misc/link_maps
+++ b/misc/link_map.py
@@ -1,12 +1,24 @@
#!/usr/bin/env python
+#
+# LinkMap.py: this file is part of the elfix package
+# Copyright (C) 2011 Anthony G. Basile
+#
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
-import os
-import sys
import re
-import pax
import portage
-
class LinkMap:
def __init__(self):
@@ -22,6 +34,7 @@ class LinkMap:
See /usr/lib/portage/bin/misc-functions.sh ~line 520
"""
+
vardb = portage.db[portage.root]["vartree"].dbapi
self.pkgs = []
@@ -183,43 +196,3 @@ class LinkMap:
return ( object_linkings, object_reverse_linkings, library2soname, soname2library )
-
-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)
-
- link_maps = LinkMap()
- ( object_linkings, object_reverse_linkings, library2soname, soname2library ) = link_maps.get_maps()
-
- layout = "{0:<30} => {1:<30}"
-
- #Print out all ELF objects and the NEEDED sonames and full library paths
- 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' % layout.format(soname, soname2library[(soname,abi)]))
- except KeyError:
- print('\t%s' % layout.format(soname, '***' ))
- print('')
-
- # Print out all ELF objects and the NEEDED sonames and full library paths
- for abi in object_linkings:
- for soname in object_reverse_linkings[abi]:
- try:
- print('%s: %s' % (abi, layout.format(soname, soname2library[(soname,abi)])))
- except KeyError:
- print('%s: %s' % (abi, layout.format(soname, '***' )))
- for elf in sorted(object_reverse_linkings[abi][soname]):
- print('\t%s' % elf)
- print('')
-
-
-if __name__ == '__main__':
- main()
diff --git a/misc/link_map_test b/misc/link_map_test
new file mode 100755
index 0000000..9a1af8e
--- /dev/null
+++ b/misc/link_map_test
@@ -0,0 +1,61 @@
+#!/usr/bin/env python
+#
+# link_map_test: this file is part of the elfix package
+# Copyright (C) 2011 Anthony G. Basile
+#
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+
+import os
+import sys
+from link_map import LinkMap
+
+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)
+
+ link_map = LinkMap()
+ ( object_linkings, object_reverse_linkings, library2soname, soname2library ) = link_map.get_maps()
+
+ layout = "{0:<30} => {1:<30}"
+
+ #Print out all ELF objects and the NEEDED sonames and full library paths
+ 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' % layout.format(soname, soname2library[(soname,abi)]))
+ except KeyError:
+ print('\t%s' % layout.format(soname, '***' ))
+ print('')
+
+ # Print out all ELF objects and the NEEDED sonames and full library paths
+ for abi in object_linkings:
+ for soname in object_reverse_linkings[abi]:
+ try:
+ print('%s: %s' % (abi, layout.format(soname, soname2library[(soname,abi)])))
+ except KeyError:
+ print('%s: %s' % (abi, layout.format(soname, '***' )))
+ for elf in sorted(object_reverse_linkings[abi][soname]):
+ print('\t%s' % elf)
+ print('')
+
+
+if __name__ == '__main__':
+ main()
^ permalink raw reply related [flat|nested] 30+ messages in thread
* [gentoo-commits] proj/elfix:master commit in: misc/
@ 2012-12-26 21:23 Anthony G. Basile
0 siblings, 0 replies; 30+ messages in thread
From: Anthony G. Basile @ 2012-12-26 21:23 UTC (permalink / raw
To: gentoo-commits
commit: beacfc74b3af09d5a87ea60edba019a8d7f51f6a
Author: Anthony G. Basile <blueness <AT> gentoo <DOT> org>
AuthorDate: Wed Dec 26 21:23:09 2012 +0000
Commit: Anthony G. Basile <blueness <AT> gentoo <DOT> org>
CommitDate: Wed Dec 26 21:23:09 2012 +0000
URL: http://git.overlays.gentoo.org/gitweb/?p=proj/elfix.git;a=commit;h=beacfc74
misc/link_maps: encapsulate all logic in class LinkMap
---
misc/link_maps | 302 +++++++++++++++++++++++++++++---------------------------
1 files changed, 156 insertions(+), 146 deletions(-)
diff --git a/misc/link_maps b/misc/link_maps
index 3707298..508af24 100755
--- a/misc/link_maps
+++ b/misc/link_maps
@@ -1,14 +1,5 @@
#!/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
@@ -16,147 +7,181 @@ import pax
import portage
-def get_object_needed():
- """ Return object_needed dictionary which has structure
+class LinkMap:
- {
- abi1 : { full_path_to_ELF_object : [ soname1, soname2, ... ], ... },
- abi2 : { full_path_to_ELF_object : [ soname1, soname2, ... ], ... },
- ....
- }
+ def __init__(self):
+ """ Put all the NEEDED.ELF.2 files for all installed packages
+ into a dictionary of the form
- Here the sonames were obtained from the ELF object by scanelf -nm
- (like readelf -d) during emerge.
- """
+ { pkg : line_from_NEEDED.ELF.2, ... }
- vardb = portage.db[portage.root]["vartree"].dbapi
+ where the line has the following form:
- object_needed = {}
+ echo "${arch:3};${obj};${soname};${rpath};${needed}" >> \
+ "${PORTAGE_BUILDDIR}"/build-info/NEEDED.ELF.2
- 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)
- abi = link[0]
- elf = link[1]
- sonames = re.split(',', link[4])
- object_needed.setdefault(abi,{}).update({elf:sonames})
+ See /usr/lib/portage/bin/misc-functions.sh ~line 520
+ """
+ vardb = portage.db[portage.root]["vartree"].dbapi
- return object_needed
+ self.pkgs = []
+ self.pkgs_needed = {}
+ for pkg in vardb.cpv_all():
+ needed = vardb.aux_get(pkg, ['NEEDED.ELF.2'])[0].strip()
+ if needed: # Some packages have no NEEDED.ELF.2
+ self.pkgs.append(pkg)
+ for line in re.split('\n', needed):
+ self.pkgs_needed.setdefault(pkg,[]).append(re.split(';', line))
-def get_libraries():
- """ Return library2soname dictionary which has structure
- { full_path_to_library : (soname, abi), ... }
+ def get_object_needed(self):
+ """ Return object_needed dictionary which has structure
- and its inverse which has structure
+ {
+ abi1 : { full_path_to_ELF_object : [ soname1, soname2, ... ], ... },
+ abi2 : { full_path_to_ELF_object : [ soname1, soname2, ... ], ... },
+ ....
+ }
- { (soname, abi) : full_path_to_library, ... }
- """
+ Here the sonames were obtained from the ELF object by scanelf -nm
+ (like readelf -d) during emerge.
+ """
+ object_needed = {}
- vardb = portage.db[portage.root]["vartree"].dbapi
+ for pkg in self.pkgs:
+ for link in self.pkgs_needed[pkg]:
+ abi = link[0]
+ elf = link[1]
+ sonames = re.split(',', link[4])
+ object_needed.setdefault(abi,{}).update({elf:sonames})
- library2soname = {}
- soname2library = {}
+ return 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)
- abi = link[0]
- elf = link[1]
- soname = link[2]
- if soname: #no soname => executable
- library2soname[elf] = (soname,abi)
- soname2library[(soname,abi)] = elf
- return ( library2soname, soname2library )
+ def get_libraries(self):
+ """ Return library2soname dictionary which has structure
+ { full_path_to_library : (soname, abi), ... }
-def get_soname_needed( object_needed, library2soname ):
- """ Return soname_needed dictionary which has structure:
+ and its inverse which has structure
- {
- abi1: { soname: [ soname1, soname2, ... ], .... },
- abi2: { soname: [ soname1, soname2, ... ], .... },
- }
+ { (soname, abi) : full_path_to_library, ... }
+ """
+ library2soname = {}
+ soname2library = {}
- Here the soname1, soname2,... were obtained from soname's corresponding
- ELF object by scanelf -n during emerge.
- """
+ for pkg in self.pkgs:
+ for link in self.pkgs_needed[pkg]:
+ abi = link[0]
+ elf = link[1]
+ soname = link[2]
+ if soname: #no soname => executable
+ library2soname[elf] = (soname,abi)
+ soname2library[(soname,abi)] = elf
- soname_needed = {}
+ return ( library2soname, soname2library )
- 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 expand_linkings( object_needed, soname2library ):
- """ Expands the object_needed dictionary which has structure
-
- {
- abi1 : { full_path_to_ELF_object : [ soname1, soname2, ... ], ... },
- abi2 : { full_path_to_ELF_object : [ soname1, soname2, ... ], ... },
- ....
- }
-
- 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.
- """
-
- 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 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)
+ def get_soname_needed(self, object_needed, library2soname ):
+ """ Return soname_needed dictionary which has structure:
+
+ {
+ 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.
+ """
+ soname_needed = {}
+
+ for abi in object_needed:
+ for elf in object_needed[abi]:
+ try:
+ (soname, abi_check) = library2soname[elf]
+ assert abi == abi_check # We should get the same abi associated with the soname
+ soname_needed.setdefault(abi,{}).update({soname:object_needed[abi][elf]})
+ except KeyError:
+ continue # no soname, its probably an executable
+
+ return soname_needed
+
+
+ def expand_linkings(self, object_needed, soname2library):
+ """ Expands the object_needed dictionary which has structure
+
+ {
+ abi1 : { full_path_to_ELF_object : [ soname1, soname2, ... ], ... },
+ abi2 : { full_path_to_ELF_object : [ soname1, soname2, ... ], ... },
+ ....
+ }
+
+ 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.
+ """
+ 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.
- return object_reverse_linkings
+ 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(self, object_linkings):
+ """ Return object_reverse_linkings dictionary which has structure
+
+ {
+ abi1 : { soname : [ path_to_elf1, path_to_elf2, ... ], ... },
+ abi2 : { soname : [ path_to_elf3, path_to_elf4, ... ], ... },
+ ....
+ }
+ """
+ object_reverse_linkings = {}
+
+ 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
+
+
+ def get_maps(self):
+ """ Generate the full forward and reverse links using the above functions """
+
+ # After get_object_needed() and get_soname_needed(), both object_linkings and
+ # soname_linkings are only one step into the entire link chain.
+
+ object_linkings = self.get_object_needed()
+ ( library2soname, soname2library ) = self.get_libraries()
+ soname_linkings = self.get_soname_needed( object_linkings, library2soname )
+
+ # After the appending in expand_linkings(), forward_linkings and soname_linkings
+ # have been extended through the entire chain of linking. expand_linkings() is
+ # a "side-effect" function, so we note it here.
+ self.expand_linkings( soname_linkings, soname2library )
+ object_reverse_linkings = self.get_object_reverse_linkings( object_linkings )
+
+ return ( object_linkings, object_reverse_linkings, library2soname, soname2library )
def main():
@@ -167,27 +192,12 @@ def main():
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 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 expand_linkings().
- expand_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 )
+ link_maps = LinkMap()
+ ( object_linkings, object_reverse_linkings, library2soname, soname2library ) = link_maps.get_maps()
layout = "{0:<30} => {1:<30}"
- """ Print out all ELF objects and the NEEDED sonames and full library paths """
+ #Print out all ELF objects and the NEEDED sonames and full library paths
for abi in object_linkings:
for elf in object_linkings[abi]:
sonames = object_linkings[abi][elf]
@@ -199,7 +209,7 @@ def main():
print('\t%s' % layout.format(soname, '***' ))
print('')
- """ Print out all ELF objects and the NEEDED sonames and full library paths """
+ # Print out all ELF objects and the NEEDED sonames and full library paths
for abi in object_linkings:
for soname in object_reverse_linkings[abi]:
try:
^ permalink raw reply related [flat|nested] 30+ messages in thread
* [gentoo-commits] proj/elfix:master commit in: misc/
@ 2012-12-26 3:42 Anthony G. Basile
0 siblings, 0 replies; 30+ messages in thread
From: Anthony G. Basile @ 2012-12-26 3:42 UTC (permalink / raw
To: gentoo-commits
commit: 53cd005f5c80fbb93c56cb60e0d80d2635eb939f
Author: Anthony G. Basile <blueness <AT> gentoo <DOT> org>
AuthorDate: Wed Dec 26 03:42:02 2012 +0000
Commit: Anthony G. Basile <blueness <AT> gentoo <DOT> org>
CommitDate: Wed Dec 26 03:42:02 2012 +0000
URL: http://git.overlays.gentoo.org/gitweb/?p=proj/elfix.git;a=commit;h=53cd005f
misc/link_maps: refactorize indentation
---
misc/link_maps | 318 ++++++++++++++++++++++++++++----------------------------
1 files changed, 158 insertions(+), 160 deletions(-)
diff --git a/misc/link_maps b/misc/link_maps
index 9b774bc..3707298 100755
--- a/misc/link_maps
+++ b/misc/link_maps
@@ -16,202 +16,200 @@ import pax
import portage
-"""
-Return object_needed dictionary which has structure
-
- {
- 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.
-"""
def get_object_needed():
+ """ Return object_needed dictionary which has structure
- vardb = portage.db[portage.root]["vartree"].dbapi
+ {
+ abi1 : { full_path_to_ELF_object : [ soname1, soname2, ... ], ... },
+ abi2 : { full_path_to_ELF_object : [ soname1, soname2, ... ], ... },
+ ....
+ }
- object_needed = {}
+ Here the sonames were obtained from the ELF object by scanelf -nm
+ (like readelf -d) during emerge.
+ """
- 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)
- abi = link[0]
- elf = link[1]
- sonames = re.split(',', link[4])
- object_needed.setdefault(abi,{}).update({elf:sonames})
+ vardb = portage.db[portage.root]["vartree"].dbapi
- return object_needed
+ 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)
+ abi = link[0]
+ elf = link[1]
+ sonames = re.split(',', link[4])
+ object_needed.setdefault(abi,{}).update({elf:sonames})
-"""
-Return library2soname dictionary which has structure
+ return object_needed
- { full_path_to_library : (soname, abi), ... }
-and its inverse which has structure
-
- { (soname, abi) : full_path_to_library, ... }
-"""
def get_libraries():
+ """ Return library2soname dictionary which has structure
+
+ { full_path_to_library : (soname, abi), ... }
- vardb = portage.db[portage.root]["vartree"].dbapi
+ and its inverse which has structure
- library2soname = {}
- soname2library = {}
+ { (soname, abi) : full_path_to_library, ... }
+ """
- 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)
- abi = link[0]
- elf = link[1]
- soname = link[2]
- if soname: #no soname => executable
- library2soname[elf] = (soname,abi)
- soname2library[(soname,abi)] = elf
+ vardb = portage.db[portage.root]["vartree"].dbapi
- return ( library2soname, soname2library )
+ 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)
+ abi = link[0]
+ elf = link[1]
+ soname = link[2]
+ if soname: #no soname => executable
+ library2soname[elf] = (soname,abi)
+ soname2library[(soname,abi)] = elf
-"""
-Return soname_needed dictionary which has structure:
+ return ( library2soname, soname2library )
- {
- 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.
-"""
def get_soname_needed( object_needed, library2soname ):
+ """ Return soname_needed dictionary which has structure:
- soname_needed = {}
+ {
+ abi1: { soname: [ soname1, soname2, ... ], .... },
+ abi2: { soname: [ soname1, soname2, ... ], .... },
+ }
- 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
+ Here the soname1, soname2,... were obtained from soname's corresponding
+ ELF object by scanelf -n during emerge.
+ """
- return soname_needed
+ soname_needed = {}
+ 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
-"""
-Expands the object_needed dictionary which has structure
+ return soname_needed
- {
- abi1 : { full_path_to_ELF_object : [ soname1, soname2, ... ], ... },
- abi2 : { full_path_to_ELF_object : [ soname1, soname2, ... ], ... },
- ....
- }
-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
+ """ Expands the object_needed dictionary which has structure
+
+ {
+ abi1 : { full_path_to_ELF_object : [ soname1, soname2, ... ], ... },
+ abi2 : { full_path_to_ELF_object : [ soname1, soname2, ... ], ... },
+ ....
+ }
+
+ 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.
+ """
+
+ 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 = {}
+ object_reverse_linkings = {}
- 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)
+ 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
+ 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 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 expand_linkings().
- expand_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 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 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")
+ # 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 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 expand_linkings().
+ expand_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 )
+
+ layout = "{0:<30} => {1:<30}"
+
+ """ Print out all ELF objects and the NEEDED sonames and full library paths """
+ 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' % layout.format(soname, soname2library[(soname,abi)]))
+ except KeyError:
+ print('\t%s' % layout.format(soname, '***' ))
+ print('')
+
+ """ Print out all ELF objects and the NEEDED sonames and full library paths """
+ for abi in object_linkings:
+ for soname in object_reverse_linkings[abi]:
+ try:
+ print('%s: %s' % (abi, layout.format(soname, soname2library[(soname,abi)])))
+ except KeyError:
+ print('%s: %s' % (abi, layout.format(soname, '***' )))
+ for elf in sorted(object_reverse_linkings[abi][soname]):
+ print('\t%s' % elf)
+ print('')
if __name__ == '__main__':
- main()
+ main()
^ permalink raw reply related [flat|nested] 30+ messages in thread
* [gentoo-commits] proj/elfix:master commit in: misc/
@ 2012-12-25 14:22 Anthony G. Basile
0 siblings, 0 replies; 30+ messages in thread
From: Anthony G. Basile @ 2012-12-25 14:22 UTC (permalink / raw
To: gentoo-commits
commit: 19810f757e41f8b66fb4d737d36a7651042725cc
Author: Anthony G. Basile <blueness <AT> gentoo <DOT> org>
AuthorDate: Tue Dec 25 14:22:06 2012 +0000
Commit: Anthony G. Basile <blueness <AT> gentoo <DOT> org>
CommitDate: Tue Dec 25 14:22:06 2012 +0000
URL: http://git.overlays.gentoo.org/gitweb/?p=proj/elfix.git;a=commit;h=19810f75
misc/link_maps_portage: dumped, misc/link_maps now uses portage only
---
misc/link_maps | 66 ++++++---------
misc/link_maps_portage | 217 ------------------------------------------------
2 files changed, 28 insertions(+), 255 deletions(-)
diff --git a/misc/link_maps b/misc/link_maps
index a7c59ba..9b774bc 100755
--- a/misc/link_maps
+++ b/misc/link_maps
@@ -13,6 +13,7 @@ import os
import sys
import re
import pax
+import portage
"""
@@ -29,26 +30,21 @@ Here the sonames were obtained from the ELF object by scanelf -nm
"""
def get_object_needed():
- var_db_pkg = '/var/db/pkg'
+ vardb = portage.db[portage.root]["vartree"].dbapi
object_needed = {}
- for cat in os.listdir(var_db_pkg):
- catdir = '%s/%s' % (var_db_pkg, cat)
- for pkg in os.listdir(catdir):
- pkgdir = '%s/%s' % (catdir, pkg)
- need = '%s/%s' % (pkgdir, 'NEEDED.ELF.2')
- try:
- g = open(need, 'r')
- needs = g.readlines()
- for line in needs:
- line = line.strip()
- link = re.split(';', line)
- abi = link[0]
- elf = link[1]
- sonames = re.split(',', link[4])
- object_needed.setdefault(abi,{}).update({elf:sonames})
- except IOError:
- continue #File probably doesn't exist, which is okay
+
+ 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)
+ abi = link[0]
+ elf = link[1]
+ sonames = re.split(',', link[4])
+ object_needed.setdefault(abi,{}).update({elf:sonames})
return object_needed
@@ -64,30 +60,24 @@ and its inverse which has structure
"""
def get_libraries():
- var_db_pkg = '/var/db/pkg'
+ vardb = portage.db[portage.root]["vartree"].dbapi
library2soname = {}
soname2library = {}
- for cat in os.listdir(var_db_pkg):
- catdir = '%s/%s' % (var_db_pkg, cat)
- for pkg in os.listdir(catdir):
- pkgdir = '%s/%s' % (catdir, pkg)
- need = '%s/%s' % (pkgdir, 'NEEDED.ELF.2')
- try:
- g = open(need, 'r')
- needs = g.readlines()
- 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,abi)
- soname2library[(soname,abi)] = elf
- except IOError:
- continue #File probably doesn't exist, which is okay
+ 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)
+ abi = link[0]
+ elf = link[1]
+ soname = link[2]
+ if soname: #no soname => executable
+ library2soname[elf] = (soname,abi)
+ soname2library[(soname,abi)] = elf
return ( library2soname, soname2library )
diff --git a/misc/link_maps_portage b/misc/link_maps_portage
deleted file mode 100755
index 9b774bc..0000000
--- a/misc/link_maps_portage
+++ /dev/null
@@ -1,217 +0,0 @@
-#!/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
-
- {
- 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.
-"""
-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)
- abi = link[0]
- elf = link[1]
- sonames = re.split(',', link[4])
- object_needed.setdefault(abi,{}).update({elf:sonames})
-
- return object_needed
-
-
-"""
-Return library2soname dictionary which has structure
-
- { full_path_to_library : (soname, abi), ... }
-
-and its inverse which has structure
-
- { (soname, abi) : 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)
- abi = link[0]
- elf = link[1]
- soname = link[2]
- if soname: #no soname => executable
- library2soname[elf] = (soname,abi)
- soname2library[(soname,abi)] = elf
-
- return ( library2soname, soname2library )
-
-
-"""
-Return soname_needed dictionary which has structure:
-
- {
- 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.
-"""
-def get_soname_needed( object_needed, library2soname ):
-
- soname_needed = {}
-
- 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
-
-
-"""
-Expands the object_needed dictionary which has structure
-
- {
- abi1 : { full_path_to_ELF_object : [ soname1, soname2, ... ], ... },
- abi2 : { full_path_to_ELF_object : [ soname1, soname2, ... ], ... },
- ....
- }
-
-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 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
-
-
-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 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 expand_linkings().
- expand_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 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 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__':
- main()
^ permalink raw reply related [flat|nested] 30+ messages in thread
* [gentoo-commits] proj/elfix:master commit in: misc/
@ 2012-12-24 23:26 Anthony G. Basile
0 siblings, 0 replies; 30+ messages in thread
From: Anthony G. Basile @ 2012-12-24 23:26 UTC (permalink / raw
To: gentoo-commits
commit: 21fc8b25cbe7e1869982083394df59d68a6fe5db
Author: Anthony G. Basile <blueness <AT> gentoo <DOT> org>
AuthorDate: Mon Dec 24 23:25:57 2012 +0000
Commit: Anthony G. Basile <blueness <AT> gentoo <DOT> org>
CommitDate: Mon Dec 24 23:25:57 2012 +0000
URL: http://git.overlays.gentoo.org/gitweb/?p=proj/elfix.git;a=commit;h=21fc8b25
misc/link_maps_portage: fix python2-isms
---
misc/link_maps | 2 +-
misc/link_maps_portage | 2 +-
2 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/misc/link_maps b/misc/link_maps
index 9753794..a7c59ba 100755
--- a/misc/link_maps
+++ b/misc/link_maps
@@ -112,7 +112,7 @@ def get_soname_needed( object_needed, library2soname ):
try:
(soname, abi_check) = library2soname[elf]
if abi != abi_check:
- print "This should never happen!"
+ print("This should never happen!")
sys.exit(1)
soname_needed.setdefault(abi,{}).update({soname:object_needed[abi][elf]})
except KeyError:
diff --git a/misc/link_maps_portage b/misc/link_maps_portage
index 28bc0ea..9b774bc 100755
--- a/misc/link_maps_portage
+++ b/misc/link_maps_portage
@@ -102,7 +102,7 @@ def get_soname_needed( object_needed, library2soname ):
try:
(soname, abi_check) = library2soname[elf]
if abi != abi_check:
- print "This should never happen!"
+ print("This should never happen!")
sys.exit(1)
soname_needed.setdefault(abi,{}).update({soname:object_needed[abi][elf]})
except KeyError:
^ permalink raw reply related [flat|nested] 30+ messages in thread
* [gentoo-commits] proj/elfix:master commit in: misc/
@ 2012-12-24 21:44 Anthony G. Basile
0 siblings, 0 replies; 30+ messages in thread
From: Anthony G. Basile @ 2012-12-24 21:44 UTC (permalink / raw
To: gentoo-commits
commit: e853f3f933ead5540562701533a389c31337877f
Author: Anthony G. Basile <blueness <AT> gentoo <DOT> org>
AuthorDate: Mon Dec 24 21:44:35 2012 +0000
Commit: Anthony G. Basile <blueness <AT> gentoo <DOT> org>
CommitDate: Mon Dec 24 21:44:35 2012 +0000
URL: http://git.overlays.gentoo.org/gitweb/?p=proj/elfix.git;a=commit;h=e853f3f9
misc/link_maps_portage: fix get_{object_needed,libraries} for multilib
---
misc/link_maps_portage | 8 +++++---
1 files changed, 5 insertions(+), 3 deletions(-)
diff --git a/misc/link_maps_portage b/misc/link_maps_portage
index f55db6a..28bc0ea 100755
--- a/misc/link_maps_portage
+++ b/misc/link_maps_portage
@@ -41,9 +41,10 @@ def get_object_needed():
lines = re.split('\n', needs)
for line in lines:
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})
return object_needed
@@ -71,11 +72,12 @@ def get_libraries():
lines = re.split('\n', needs)
for line in lines:
link = re.split(';', line)
+ abi = link[0]
elf = link[1]
soname = link[2]
if soname: #no soname => executable
- library2soname[elf] = soname
- soname2library[soname] = elf
+ library2soname[elf] = (soname,abi)
+ soname2library[(soname,abi)] = elf
return ( library2soname, soname2library )
^ permalink raw reply related [flat|nested] 30+ messages in thread
* [gentoo-commits] proj/elfix:master commit in: misc/
@ 2012-12-24 21:08 Anthony G. Basile
0 siblings, 0 replies; 30+ messages in thread
From: Anthony G. Basile @ 2012-12-24 21:08 UTC (permalink / raw
To: gentoo-commits
commit: b6d64d5913333a4520aac2cc9ab2ea696eb84ee6
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: Mon Dec 24 21:08:39 2012 +0000
URL: http://git.overlays.gentoo.org/gitweb/?p=proj/elfix.git;a=commit;h=b6d64d59
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__':
^ permalink raw reply related [flat|nested] 30+ messages in thread
* [gentoo-commits] proj/elfix:master commit in: misc/
@ 2012-12-24 2:18 Anthony G. Basile
0 siblings, 0 replies; 30+ messages in thread
From: Anthony G. Basile @ 2012-12-24 2:18 UTC (permalink / raw
To: gentoo-commits
commit: 94a5e3365b3d6f3658e090838004e9a3bf9ab148
Author: Anthony G. Basile <blueness <AT> gentoo <DOT> org>
AuthorDate: Mon Dec 24 02:18:28 2012 +0000
Commit: Anthony G. Basile <blueness <AT> gentoo <DOT> org>
CommitDate: Mon Dec 24 02:18:28 2012 +0000
URL: http://git.overlays.gentoo.org/gitweb/?p=proj/elfix.git;a=commit;h=94a5e336
misc/alt-revdep-pax: read NEEDED.ELF.2 via portage
---
misc/alt-revdep-pax | 67 +++++++++++++++++++--------------------------------
1 files changed, 25 insertions(+), 42 deletions(-)
diff --git a/misc/alt-revdep-pax b/misc/alt-revdep-pax
index f35a9ea..69086af 100755
--- a/misc/alt-revdep-pax
+++ b/misc/alt-revdep-pax
@@ -31,6 +31,7 @@ import os
import sys
import re
import pax
+import portage
""" python2/3 compat input """
@@ -51,32 +52,20 @@ Here the sonames were obtained from the ELF object by scanelf -nm
"""
def get_object_needed():
- """
- import portage
vardb = portage.db[portage.root]["vartree"].dbapi
- vardb.aux_get('sys-apps/coreutils-8.20', ['NEEDED.ELF.2'])
- vardb.cpv_all() # list of all packages
- """
-
- var_db_pkg = '/var/db/pkg'
object_needed = {}
- for cat in os.listdir(var_db_pkg):
- catdir = '%s/%s' % (var_db_pkg, cat)
- for pkg in os.listdir(catdir):
- pkgdir = '%s/%s' % (catdir, pkg)
- need = '%s/%s' % (pkgdir, 'NEEDED.ELF.2')
- try:
- g = open(need, 'r')
- needs = g.readlines()
- for line in needs:
- line = line.strip()
- link = re.split(';', line)
- elf = link[1]
- sonames = re.split(',', link[4])
- object_needed[elf] = sonames
- except IOError:
- continue #File probably doesn't exist, which is okay
+
+ 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
@@ -92,29 +81,23 @@ and its inverse which has structure
"""
def get_libraries():
- var_db_pkg = '/var/db/pkg'
+ vardb = portage.db[portage.root]["vartree"].dbapi
library2soname = {}
soname2library = {}
- for cat in os.listdir(var_db_pkg):
- catdir = '%s/%s' % (var_db_pkg, cat)
- for pkg in os.listdir(catdir):
- pkgdir = '%s/%s' % (catdir, pkg)
- need = '%s/%s' % (pkgdir, 'NEEDED.ELF.2')
- try:
- g = open(need, 'r')
- needs = g.readlines()
- for line in needs:
- line = line.strip()
- link = re.split(';', line)
- elf = link[1]
- soname = link[2]
- if soname: #no soname => executable
- library2soname[elf] = soname
- soname2library[soname] = elf
- except IOError:
- continue #File probably doesn't exist, which is okay
+ 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 )
^ permalink raw reply related [flat|nested] 30+ messages in thread
* [gentoo-commits] proj/elfix:master commit in: misc/
@ 2012-12-24 1:54 Anthony G. Basile
0 siblings, 0 replies; 30+ messages in thread
From: Anthony G. Basile @ 2012-12-24 1:54 UTC (permalink / raw
To: gentoo-commits
commit: 4e2f986868fd06f077354f3442b90ba319951593
Author: Anthony G. Basile <blueness <AT> gentoo <DOT> org>
AuthorDate: Mon Dec 24 01:54:10 2012 +0000
Commit: Anthony G. Basile <blueness <AT> gentoo <DOT> org>
CommitDate: Mon Dec 24 01:54:10 2012 +0000
URL: http://git.overlays.gentoo.org/gitweb/?p=proj/elfix.git;a=commit;h=4e2f9868
misc/link_maps{,_portage}: compare reading /var/db/pkg directly and via portage
---
misc/link_maps | 60 ++++------------
misc/{link_maps => link_maps_portage} | 122 +++++++++++----------------------
2 files changed, 56 insertions(+), 126 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 b/misc/link_maps_portage
similarity index 61%
copy from misc/link_maps
copy to misc/link_maps_portage
index a6adacd..bf5b447 100755
--- a/misc/link_maps
+++ b/misc/link_maps_portage
@@ -13,6 +13,7 @@ import os
import sys
import re
import pax
+import portage
"""
@@ -25,25 +26,20 @@ Here the sonames were obtained from the ELF object by scanelf -nm
"""
def get_object_needed():
- var_db_pkg = '/var/db/pkg'
+ vardb = portage.db[portage.root]["vartree"].dbapi
object_needed = {}
- for cat in os.listdir(var_db_pkg):
- catdir = '%s/%s' % (var_db_pkg, cat)
- for pkg in os.listdir(catdir):
- pkgdir = '%s/%s' % (catdir, pkg)
- need = '%s/%s' % (pkgdir, 'NEEDED.ELF.2')
- try:
- g = open(need, 'r')
- needs = g.readlines()
- for line in needs:
- line = line.strip()
- link = re.split(';', line)
- elf = link[1]
- sonames = re.split(',', link[4])
- object_needed[elf] = sonames
- except IOError:
- continue #File probably doesn't exist, which is okay
+
+ 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
@@ -59,29 +55,23 @@ and its inverse which has structure
"""
def get_libraries():
- var_db_pkg = '/var/db/pkg'
+ vardb = portage.db[portage.root]["vartree"].dbapi
library2soname = {}
soname2library = {}
- for cat in os.listdir(var_db_pkg):
- catdir = '%s/%s' % (var_db_pkg, cat)
- for pkg in os.listdir(catdir):
- pkgdir = '%s/%s' % (catdir, pkg)
- need = '%s/%s' % (pkgdir, 'NEEDED.ELF.2')
- try:
- g = open(need, 'r')
- needs = g.readlines()
- for line in needs:
- line = line.strip()
- link = re.split(';', line)
- elf = link[1]
- soname = link[2]
- if soname: #no soname => executable
- library2soname[elf] = soname
- soname2library[soname] = elf
- except IOError:
- continue #File probably doesn't exist, which is okay
+ 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 )
@@ -168,57 +158,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()
^ permalink raw reply related [flat|nested] 30+ messages in thread
* [gentoo-commits] proj/elfix:master commit in: misc/
@ 2012-12-23 11:51 Anthony G. Basile
0 siblings, 0 replies; 30+ messages in thread
From: Anthony G. Basile @ 2012-12-23 11:51 UTC (permalink / raw
To: gentoo-commits
commit: 5137b1f8d5eaa878c13c18f0ae869dcbf0294a8a
Author: Anthony G. Basile <blueness <AT> gentoo <DOT> org>
AuthorDate: Sun Dec 23 11:50:55 2012 +0000
Commit: Anthony G. Basile <blueness <AT> gentoo <DOT> org>
CommitDate: Sun Dec 23 11:50:55 2012 +0000
URL: http://git.overlays.gentoo.org/gitweb/?p=proj/elfix.git;a=commit;h=5137b1f8
misc/alt-revdep-pax: comment on how to use portage for /var/db/pkg data
---
misc/alt-revdep-pax | 7 +++++++
1 files changed, 7 insertions(+), 0 deletions(-)
diff --git a/misc/alt-revdep-pax b/misc/alt-revdep-pax
index d5770e4..f35a9ea 100755
--- a/misc/alt-revdep-pax
+++ b/misc/alt-revdep-pax
@@ -51,6 +51,13 @@ Here the sonames were obtained from the ELF object by scanelf -nm
"""
def get_object_needed():
+ """
+ import portage
+ vardb = portage.db[portage.root]["vartree"].dbapi
+ vardb.aux_get('sys-apps/coreutils-8.20', ['NEEDED.ELF.2'])
+ vardb.cpv_all() # list of all packages
+ """
+
var_db_pkg = '/var/db/pkg'
object_needed = {}
^ permalink raw reply related [flat|nested] 30+ messages in thread
* [gentoo-commits] proj/elfix:master commit in: misc/
@ 2012-12-23 4:53 Anthony G. Basile
0 siblings, 0 replies; 30+ messages in thread
From: Anthony G. Basile @ 2012-12-23 4:53 UTC (permalink / raw
To: gentoo-commits
commit: d8bd573cdd3b2a1e6b4f7a2332ef6f8e9d24854f
Author: Anthony G. Basile <blueness <AT> gentoo <DOT> org>
AuthorDate: Sun Dec 23 04:53:37 2012 +0000
Commit: Anthony G. Basile <blueness <AT> gentoo <DOT> org>
CommitDate: Sun Dec 23 04:53:37 2012 +0000
URL: http://git.overlays.gentoo.org/gitweb/?p=proj/elfix.git;a=commit;h=d8bd573c
misc/alt-revdep-pax: correct expand_linkings() to include first ELF object in linkage chain
---
misc/alt-revdep-pax | 18 +++++++++---------
1 files changed, 9 insertions(+), 9 deletions(-)
diff --git a/misc/alt-revdep-pax b/misc/alt-revdep-pax
index 4ea90d4..d5770e4 100755
--- a/misc/alt-revdep-pax
+++ b/misc/alt-revdep-pax
@@ -134,19 +134,19 @@ def get_soname_needed( object_needed, library2soname ):
return soname_needed
"""
-Run through the entire chain of sonameX -> sonameY ... -> sonameZ chain.
-We do this by continuously expanding the list pointed to by the dictionary
+Run through the entire chain of obj -> sonameX -> sonameY ... -> sonameZ chain.
+We do this by continuously expanding the list value of the dictionary key elf
entry until there are no new soname's found.
"""
-def get_soname_linkings( soname_needed, soname2library ):
+def expand_linkings( object_needed, soname2library ):
- for soname in soname_needed:
+ for elf in object_needed:
while True:
found_new_soname = False
- for s in soname_needed[soname]: # For all the next links ...
+ for s in object_needed[elf]: # For all the next links ...
try:
- for sf in soname_needed[s]: # ... go one step ahead in the chain
- if sf in soname_needed[soname]: # ... skip it if we already included it
+ for sf in object_needed[soname2library[s]]: # ... go one step ahead in the chain
+ if sf in object_needed[elf]: # ... skip it if we already included it
continue
if not sf in soname2library: # ... skip if its a vdso
continue
@@ -155,7 +155,7 @@ def get_soname_linkings( soname_needed, soname2library ):
# was done so its the same lists in
# memory for both, and its modified
# for both.
- soname_needed[soname].append(sf) # ... otherwise collapse it back into
+ object_needed[elf].append(sf) # ... otherwise collapse it back into
found_new_soname = True # first node of the chain.
except KeyError: # Not all nodes in the chain have a next node
@@ -172,7 +172,7 @@ def get_object_linkings():
object_needed = get_object_needed()
( library2soname, soname2library ) = get_libraries()
soname_needed = get_soname_needed( object_needed, library2soname )
- get_soname_linkings( soname_needed, soname2library )
+ expand_linkings( object_needed, soname2library )
return ( object_needed, soname2library )
^ permalink raw reply related [flat|nested] 30+ messages in thread
* [gentoo-commits] proj/elfix:master commit in: misc/
@ 2012-12-23 3:49 Anthony G. Basile
0 siblings, 0 replies; 30+ messages in thread
From: Anthony G. Basile @ 2012-12-23 3:49 UTC (permalink / raw
To: gentoo-commits
commit: e7efaf0473dfeacdaa8404ca6a7b70dc441c1485
Author: Anthony G. Basile <blueness <AT> gentoo <DOT> org>
AuthorDate: Sun Dec 23 03:47:31 2012 +0000
Commit: Anthony G. Basile <blueness <AT> gentoo <DOT> org>
CommitDate: Sun Dec 23 03:49:10 2012 +0000
URL: http://git.overlays.gentoo.org/gitweb/?p=proj/elfix.git;a=commit;h=e7efaf04
misc/alt-revdep-pax: add print forward linkings per elf object (-b)
---
misc/alt-revdep-pax | 52 ++++++++++++++++++++++++++++++--------------------
1 files changed, 31 insertions(+), 21 deletions(-)
diff --git a/misc/alt-revdep-pax b/misc/alt-revdep-pax
index 6fb88fa..4ea90d4 100755
--- a/misc/alt-revdep-pax
+++ b/misc/alt-revdep-pax
@@ -365,28 +365,35 @@ def migrate_flags(importer, exporter_str_flags, exporter_bin_flags):
pax.setbinflags(importer, result_bin_flags)
-def run_binary(binary, verbose, mark, allyes):
- if not os.path.exists(binary):
- print('%s\tNo such OBJECT' % binary)
+def run_elf(elf, verbose, mark, allyes):
+
+ if not os.path.exists(elf):
+ print('%s\tNo such OBJECT' % elf)
return
- ( linkings, mappings ) = get_ldd_linkings(binary)
- ( binary_str_flags, binary_bin_flags ) = pax.getflags(binary)
- print('%s (%s)\n' % ( binary, binary_str_flags ))
+
+ try:
+ (elf_str_flags, elf_bin_flags) = pax.getflags(elf)
+ print('%s (%s)\n' % (elf, elf_str_flags))
+ except pax.PaxError:
+ print('%s: No PAX flags found\n' % elf)
+ return
+
+ (object_linkings, soname2library) = get_object_linkings()
mismatched_libraries = []
- for soname in linkings:
+ for soname in object_linkings[elf]:
try:
- library = mappings[soname]
+ library = soname2library[soname]
( library_str_flags, library_bin_flags ) = pax.getflags(library)
if verbose:
print('\t%s\t%s ( %s )' % ( soname, library, library_str_flags ))
- if binary_str_flags != library_str_flags:
+ if elf_str_flags != library_str_flags:
mismatched_libraries.append(library)
if not verbose:
print('\t%s\t%s ( %s )' % ( soname, library, library_str_flags ))
except pax.PaxError:
- print('file for soname %s not found' % soname)
+ print('%s: file for soname not found' % soname)
if len(mismatched_libraries) == 0:
if not verbose:
@@ -394,7 +401,7 @@ def run_binary(binary, verbose, mark, allyes):
else:
print('\n'),
if mark:
- print('\tWill mark libraries with %s\n' % binary_str_flags)
+ print('\tWill mark libraries with %s\n' % elf_str_flags)
for library in mismatched_libraries:
do_marking = False
while True:
@@ -413,12 +420,15 @@ def run_binary(binary, verbose, mark, allyes):
if do_marking:
try:
- migrate_flags(library, binary_str_flags, binary_bin_flags)
+ migrate_flags(library, elf_str_flags, elf_bin_flags)
+ except pax.PaxError:
+ print('\n\tCould not set PAX flags on %s, text maybe busy' % library)
+
+ try:
+ ( library_str_flags, library_bin_flags ) = pax.getflags(library)
+ print('\n\t\t%s ( %s )\n' % ( library, library_str_flags ))
except pax.PaxError:
- print("\n\tCould not set pax flags on %s, file is probably busy" % library)
- print("\tShut down all processes that use it and try again")
- ( library_str_flags, library_bin_flags ) = pax.getflags(library)
- print('\n\t\t%s ( %s )\n' % ( library, library_str_flags ))
+ print('\n\t\t%s: Could not read PAX flags')
def invert_so2library_mappings( so2library_mappings ):
@@ -555,8 +565,8 @@ def main():
do_forward = False
do_reverse = False
- binary = None
- soname = None
+ elf = None
+ soname = None
library = None
verbose = False
@@ -577,7 +587,7 @@ def main():
do_reverse = True
opt_count += 1
elif o == '-b':
- binary = a
+ elf = a
opt_count += 1
elif o == '-s':
soname = a
@@ -605,8 +615,8 @@ def main():
run_forward(verbose)
elif do_reverse:
run_reverse(verbose, executable_only)
- elif binary != None:
- run_binary(binary, verbose, mark, allyes)
+ elif elf != None:
+ run_elf(elf, verbose, mark, allyes)
elif soname != None:
run_soname(soname, verbose, True, mark, allyes, executable_only)
elif library != None:
^ permalink raw reply related [flat|nested] 30+ messages in thread
* [gentoo-commits] proj/elfix:master commit in: misc/
@ 2012-12-23 3:49 Anthony G. Basile
0 siblings, 0 replies; 30+ messages in thread
From: Anthony G. Basile @ 2012-12-23 3:49 UTC (permalink / raw
To: gentoo-commits
commit: 84caac5ffcf2ca15f0a899f5b651a24cdaad56a6
Author: Anthony G. Basile <blueness <AT> gentoo <DOT> org>
AuthorDate: Sun Dec 23 02:33:53 2012 +0000
Commit: Anthony G. Basile <blueness <AT> gentoo <DOT> org>
CommitDate: Sun Dec 23 03:48:39 2012 +0000
URL: http://git.overlays.gentoo.org/gitweb/?p=proj/elfix.git;a=commit;h=84caac5f
misc/alt-revdep-pax: add print all reverse linkings (-r)
---
misc/alt-revdep-pax | 149 +++++++++++++++++++++++++++-----------------------
1 files changed, 80 insertions(+), 69 deletions(-)
diff --git a/misc/alt-revdep-pax b/misc/alt-revdep-pax
index b46fe23..6fb88fa 100755
--- a/misc/alt-revdep-pax
+++ b/misc/alt-revdep-pax
@@ -128,37 +128,47 @@ def get_soname_needed( object_needed, library2soname ):
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
-
+"""
+Run through the entire chain of sonameX -> sonameY ... -> sonameZ chain.
+We do this by continuously expanding the list pointed to by the dictionary
+entry until there are no new soname's found.
+"""
def get_soname_linkings( soname_needed, soname2library ):
+
for soname in soname_needed:
while True:
- count = 0
- for s in soname_needed[soname]:
+ found_new_soname = False
+ for s in soname_needed[soname]: # For all the next links ...
try:
- for sf in soname_needed[s]:
- if sf in soname_needed[soname]: # Skip it if we already included it
+ for sf in soname_needed[s]: # ... go one step ahead in the chain
+ if sf in soname_needed[soname]: # ... skip it if we already included it
continue
- if not sf in soname2library: #Skip if its a vdso
+ 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:
+ # 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.
+ soname_needed[soname].append(sf) # ... otherwise collapse it back into
+ found_new_soname = True # first node of the chain.
+
+ except KeyError: # Not all nodes in the chain have a next node
continue
- if count == 0:
- break
- return
+ if not found_new_soname: # We're done, that last iteration found
+ break # no new nodes
+
+
def get_object_linkings():
+
object_needed = get_object_needed()
( library2soname, soname2library ) = get_libraries()
soname_needed = get_soname_needed( object_needed, library2soname )
@@ -166,21 +176,22 @@ def get_object_linkings():
return ( object_needed, soname2library )
-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)
+def print_problems( elfs_without_flags, sonames_without_flags, sonames_missing_library):
- return object_reverse_linkings
+ elfs_without_flags = set(elfs_without_flags)
+ print('\n**** ELF objections without any PAX flags ****\n')
+ for m in elfs_without_flags:
+ print('\t%s' % m)
+ sonames_without_flags = set(sonames_without_flags)
+ print('\n**** SONAMEs with library files without PAX flags ****\n')
+ for m in sonames_without_flags:
+ print('\t%s' % m)
-#XXXXXXXXXXXXXXXX
-def invert_linkings( forward_linkings ):
- reverse_linkings = {}
- return reverse_linkings
-#XXXXXXXXXXXXXXXX
+ sonames_missing_library = set(sonames_missing_library)
+ print('\n**** SONAMES without any library files ****\n')
+ for m in sonames_missing_library:
+ print('\t%s' % m)
def print_object_linkings( object_linkings, soname2library, verbose ):
@@ -223,59 +234,65 @@ def print_object_linkings( object_linkings, soname2library, verbose ):
if count != 0:
print('%s\n\n' % s)
- elfs_without_flags = set(elfs_without_flags)
- print('\n**** ELF objections without any PAX flags ****')
- for m in elfs_without_flags:
- print('\t%s' % m)
-
- sonames_without_flags = set(sonames_without_flags)
- print('\n**** SONAMEs with library files without PAX flags ****')
- for m in sonames_without_flags:
- print('\t%s' % m)
+ print_problems( elfs_without_flags, sonames_without_flags, sonames_missing_library)
- sonames_missing_library = set(sonames_missing_library)
- print('\n**** SONAMES without any library files ****')
- for m in sonames_missing_library:
- print('\t%s' % m)
def run_forward(verbose):
+
( object_linkings, soname2library ) = get_object_linkings()
print_object_linkings( object_linkings, soname2library, verbose)
-def print_reverse_linkings( reverse_linkings, so2library_mappings, verbose, executable_only ):
+
+
+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 print_object_reverse_linkings( object_reverse_linkings, soname2library, verbose, executable_only):
+
shell_path = path = os.getenv('PATH').split(':')
- missing_sonames = []
- missing_links = []
- for soname in reverse_linkings:
+ elfs_without_flags = []
+ sonames_without_flags = []
+ sonames_missing_library = []
+
+ for soname in object_reverse_linkings:
try:
- library = so2library_mappings[soname]
+ library = soname2library[soname]
( library_str_flags, library_bin_flags ) = pax.getflags(library)
sv = '%s\t%s ( %s )\n' % ( soname, library, library_str_flags )
s = sv
+ except KeyError:
+ sonames_missing_library.append(soname)
except pax.PaxError:
- missing_sonames.append(soname)
- continue
+ sonames_without_flags.append(soname)
count = 0
- for binary in reverse_linkings[soname]:
+ for elf in object_reverse_linkings[soname]:
try:
- ( binary_str_flags, binary_bin_flags ) = pax.getflags(binary)
+ ( elf_str_flags, elf_bin_flags ) = pax.getflags(elf)
if executable_only:
- if os.path.dirname(binary) in shell_path:
- sv = '%s\n\t%s ( %s )' % ( sv, binary, binary_str_flags )
- if library_str_flags != binary_str_flags:
- s = '%s\n\t%s ( %s )' % ( s, binary, binary_str_flags )
+ if os.path.dirname(elf) in shell_path:
+ sv = '%s\n\t%s ( %s )' % ( sv, elf, elf_str_flags )
+ if library_str_flags != elf_str_flags:
+ s = '%s\n\t%s ( %s )' % ( s, elf, elf_str_flags )
count = count + 1
else:
- sv = '%s\n\t%s ( %s )' % ( sv, binary, binary_str_flags )
- if library_str_flags != binary_str_flags:
- s = '%s\n\t%s ( %s )' % ( s, binary, binary_str_flags )
+ sv = '%s\n\t%s ( %s )' % ( sv, elf, elf_str_flags )
+ if library_str_flags != elf_str_flags:
+ s = '%s\n\t%s ( %s )' % ( s, elf, elf_str_flags )
count = count + 1
except pax.PaxError:
- missing_links.append(binary)
+ elfs_without_flags.append(elf)
if verbose:
print('%s\n' % sv)
@@ -287,21 +304,15 @@ def print_reverse_linkings( reverse_linkings, so2library_mappings, verbose, exec
if count != 0:
print('%s\n\n' % s)
- missing_sonames = set(missing_sonames)
- print('\n**** Missing sonames ****\n')
- for m in missing_sonames:
- print('\t%s\n' % m)
-
- missing_links = set(missing_links)
- print('\n**** Missing reverse linkings ****\n')
- for m in missing_links:
- print('\t%s\n' % m)
+ print_problems( elfs_without_flags, sonames_without_flags, sonames_missing_library)
def run_reverse(verbose, executable_only):
- ( forward_linkings, so2library_mappings ) = get_object_linkings()
- reverse_linkings = invert_linkings( forward_linkings )
- print_reverse_linkings( reverse_linkings, so2library_mappings, verbose, executable_only)
+ ( object_linkings, soname2library ) = get_object_linkings()
+ object_reverse_linkings = get_object_reverse_linkings( object_linkings )
+ print_object_reverse_linkings( object_reverse_linkings, soname2library, verbose, executable_only)
+
+
def migrate_flags(importer, exporter_str_flags, exporter_bin_flags):
^ permalink raw reply related [flat|nested] 30+ messages in thread
* [gentoo-commits] proj/elfix:master commit in: misc/
@ 2012-12-23 3:49 Anthony G. Basile
0 siblings, 0 replies; 30+ messages in thread
From: Anthony G. Basile @ 2012-12-23 3:49 UTC (permalink / raw
To: gentoo-commits
commit: e01cb0cdc52b5d5b465d0372ef5ec7bfc975949a
Author: Anthony G. Basile <blueness <AT> gentoo <DOT> org>
AuthorDate: Sun Dec 23 01:02:47 2012 +0000
Commit: Anthony G. Basile <blueness <AT> gentoo <DOT> org>
CommitDate: Sun Dec 23 03:48:22 2012 +0000
URL: http://git.overlays.gentoo.org/gitweb/?p=proj/elfix.git;a=commit;h=e01cb0cd
misc/alt-revdep-pax: add old revdep-pax, add print all forward linkings (-f)
---
misc/alt-revdep-pax | 503 +++++++++++++++++++++++++++++++-----
misc/{alt-revdep-pax => link_maps} | 0
2 files changed, 440 insertions(+), 63 deletions(-)
diff --git a/misc/alt-revdep-pax b/misc/alt-revdep-pax
index a6adacd..6c0c7ba 100755
--- a/misc/alt-revdep-pax
+++ b/misc/alt-revdep-pax
@@ -1,4 +1,21 @@
#!/usr/bin/env python
+#
+# alt-revdep-pax: this file is part of the elfix package
+# Copyright (C) 2011 Anthony G. Basile
+#
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+#
#
# Note: This alternative way of doing revdep-pax only
@@ -9,12 +26,21 @@
# echo "${arch:3};${obj};${soname};${rpath};${needed}" >> "${PORTAGE_BUILDDIR}"/build-info/NEEDED.ELF.2
#
+import getopt
import os
import sys
import re
import pax
+""" python2/3 compat input """
+def get_input(prompt):
+ if sys.hexversion > 0x03000000:
+ return input(prompt)
+ else:
+ return raw_input(prompt)
+
+
"""
Return object_needed dictionary which has structure
@@ -132,6 +158,14 @@ def get_soname_linkings( soname_needed, soname2library ):
return
+def get_object_linkings():
+ object_needed = get_object_needed()
+ ( library2soname, soname2library ) = get_libraries()
+ soname_needed = get_soname_needed( object_needed, library2soname )
+ get_soname_linkings( soname_needed, soname2library )
+ return ( object_needed, soname2library )
+
+
def get_object_reverse_linkings( object_linkings ):
object_reverse_linkings = {}
@@ -142,83 +176,426 @@ def get_object_reverse_linkings( object_linkings ):
return object_reverse_linkings
-def main():
+#XXXXXXXXXXXXXXXX
+def invert_linkings( forward_linkings ):
+ reverse_linkings = {}
+ return reverse_linkings
+#XXXXXXXXXXXXXXXX
- # 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 )
+def print_object_linkings( object_linkings, soname2library, verbose ):
- # 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 )
+ elfs_without_flags = []
+ sonames_without_flags = []
+ sonames_missing_library = []
+
+ for elf in object_linkings:
+ try:
+ ( elf_str_flags, elf_bin_flags ) = pax.getflags(elf)
+ sv = '%s ( %s )\n' % ( elf, elf_str_flags )
+ s = sv
+ except pax.PaxError:
+ elf_without_flags.append(elf)
+ continue
+
+ count = 0
+ for soname in object_linkings[elf]:
+ try:
+ library = soname2library[soname]
+ ( library_str_flags, library_bin_flags ) = pax.getflags(library)
+ sv = '%s\n\t%s\t%s ( %s )' % ( sv, soname, library, library_str_flags )
+ if elf_str_flags != library_str_flags:
+ s = '%s\n\t%s\t%s ( %s )' % ( s, soname, library, library_str_flags )
+ count = count + 1
+ except KeyError:
+ sonames_missing_library.append(soname)
+ except pax.PaxError:
+ sonames_without_flags.append(soname)
+
+
+ if verbose:
+ print('%s\n' % sv)
+ if count == 0:
+ print('\tNo mismatches\n\n')
+ else:
+ print('\tMismatches\n\n')
+ else:
+ if count != 0:
+ print('%s\n\n' % s)
- object_linkings = object_needed
- object_needed = None
+ elfs_without_flags = set(elfs_without_flags)
+ print('\n**** ELF objections without any PAX flags ****')
+ for m in elfs_without_flags:
+ print('\t%s' % m)
- soname_linkings = soname_needed
- soname_needed = None
+ sonames_without_flags = set(sonames_without_flags)
+ print('\n**** SONAMEs with library files without PAX flags ****')
+ for m in sonames_without_flags:
+ print('\t%s' % m)
- object_reverse_linkings = get_object_reverse_linkings( object_linkings )
+ sonames_missing_library = set(sonames_missing_library)
+ print('\n**** SONAMES without any library files ****')
+ for m in sonames_missing_library:
+ print('\t%s' % m)
- """ Print out all ELF objects and their PaX flags
- for elf in object_needed:
+
+def run_forward(verbose):
+ ( object_linkings, soname2library ) = get_object_linkings()
+ print_object_linkings( object_linkings, soname2library, verbose)
+
+
+def print_reverse_linkings( reverse_linkings, so2library_mappings, verbose, executable_only ):
+ shell_path = path = os.getenv('PATH').split(':')
+ missing_sonames = []
+ missing_links = []
+
+ for soname in reverse_linkings:
try:
- flags = pax.getflags(elf)[0]
- if flags:
- print("%s %s" % (flags, elf))
+ library = so2library_mappings[soname]
+ ( library_str_flags, library_bin_flags ) = pax.getflags(library)
+ sv = '%s\t%s ( %s )\n' % ( soname, library, library_str_flags )
+ s = sv
+ except pax.PaxError:
+ missing_sonames.append(soname)
+ continue
+
+ count = 0
+ for binary in reverse_linkings[soname]:
+ try:
+ ( binary_str_flags, binary_bin_flags ) = pax.getflags(binary)
+ if executable_only:
+ if os.path.dirname(binary) in shell_path:
+ sv = '%s\n\t%s ( %s )' % ( sv, binary, binary_str_flags )
+ if library_str_flags != binary_str_flags:
+ s = '%s\n\t%s ( %s )' % ( s, binary, binary_str_flags )
+ count = count + 1
+ else:
+ sv = '%s\n\t%s ( %s )' % ( sv, binary, binary_str_flags )
+ if library_str_flags != binary_str_flags:
+ s = '%s\n\t%s ( %s )' % ( s, binary, binary_str_flags )
+ count = count + 1
+ except pax.PaxError:
+ missing_links.append(binary)
+
+ if verbose:
+ print('%s\n' % sv)
+ if count == 0:
+ print('\tNo mismatches\n\n')
else:
- print("NONE: %s" % elf)
- except pax.error:
- print("CANT: %s" % elf)
+ print('\tMismatches\n\n')
+ else:
+ if count != 0:
+ print('%s\n\n' % s)
+
+ missing_sonames = set(missing_sonames)
+ print('\n**** Missing sonames ****\n')
+ for m in missing_sonames:
+ print('\t%s\n' % m)
+
+ missing_links = set(missing_links)
+ print('\n**** Missing reverse linkings ****\n')
+ for m in missing_links:
+ print('\t%s\n' % m)
+
+
+def run_reverse(verbose, executable_only):
+ ( forward_linkings, so2library_mappings ) = get_object_linkings()
+ reverse_linkings = invert_linkings( forward_linkings )
+ print_reverse_linkings( reverse_linkings, so2library_mappings, verbose, executable_only)
+
+
+def migrate_flags(importer, exporter_str_flags, exporter_bin_flags):
+ # We implement the following logic for setting the pax flags
+ # on the target elf object, the IMPORTER, given that the flags
+ # from the elf object we want it to match to, the EXPORTER.
+ #
+ # EXPORTER IMPORTER RESULT
+ # On On On
+ # On Off On + Warn
+ # On - On
+ # Off On On + Warn
+ # Off Off Off
+ # Off - Off
+ # - On On
+ # - Off Off
+ # - - -
+
+ #See /usr/include/elf.h for these values
+ pf_flags = {
+ 'P':1<<4, 'p':1<<5,
+ 'S':1<<6, 's':1<<7,
+ 'M':1<<8, 'm':1<<9,
+ 'X':1<<10, 'x':1<<11,
+ 'E':1<<12, 'e':1<<13,
+ 'R':1<<14, 'r':1<<15
+ }
+
+ ( importer_str_flags, importer_bin_flags ) = pax.getflags(importer)
+
+ # Start with the exporter's flags
+ result_bin_flags = exporter_bin_flags
+
+ for i in range(len(importer_str_flags)):
+
+ # The exporter's flag contradicts the importer's flag, so do nothing
+ if (exporter_str_flags[i].isupper() and importer_str_flags[i].islower()) or \
+ (exporter_str_flags[i].islower() and importer_str_flags[i].isupper()):
+
+ # Revert the exporter's flag, use the importer's flag and warn
+ result_bin_flags = result_bin_flags ^ pf_flags[exporter_str_flags[i]]
+ result_bin_flags = result_bin_flags | pf_flags[importer_str_flags[i]]
+ print('\t\tWarning: %s has %s, refusing to set to %s' % (
+ importer, importer_str_flags[i], exporter_str_flags[i] )),
+
+ # The exporter's flags is off, so use the importer's flag
+ if (exporter_str_flags[i] == '-' and importer_str_flags[i] != '-'):
+ result_bin_flags = result_bin_flags | pf_flags[importer_str_flags[i]]
+
+ pax.setbinflags(importer, result_bin_flags)
+
+
+def run_binary(binary, verbose, mark, allyes):
+ if not os.path.exists(binary):
+ print('%s\tNo such OBJECT' % binary)
+ return
+ ( linkings, mappings ) = get_ldd_linkings(binary)
+ ( binary_str_flags, binary_bin_flags ) = pax.getflags(binary)
+ print('%s (%s)\n' % ( binary, binary_str_flags ))
+
+ mismatched_libraries = []
+
+ for soname in linkings:
+ try:
+ library = mappings[soname]
+ ( library_str_flags, library_bin_flags ) = pax.getflags(library)
+ if verbose:
+ print('\t%s\t%s ( %s )' % ( soname, library, library_str_flags ))
+ if binary_str_flags != library_str_flags:
+ mismatched_libraries.append(library)
+ if not verbose:
+ print('\t%s\t%s ( %s )' % ( soname, library, library_str_flags ))
+ except pax.PaxError:
+ print('file for soname %s not found' % soname)
+
+ if len(mismatched_libraries) == 0:
+ if not verbose:
+ print('\tNo mismatches\n')
+ else:
+ print('\n'),
+ if mark:
+ print('\tWill mark libraries with %s\n' % binary_str_flags)
+ for library in mismatched_libraries:
+ do_marking = False
+ while True:
+ if allyes:
+ ans = 'y'
+ else:
+ ans = get_input('\tSet flags for %s (y/n): ' % library)
+ if ans == 'y':
+ do_marking = True
+ break
+ elif ans == 'n':
+ do_marking = False
+ break
+ else:
+ print('\t\tPlease enter y or n')
+
+ if do_marking:
+ try:
+ migrate_flags(library, binary_str_flags, binary_bin_flags)
+ except pax.PaxError:
+ print("\n\tCould not set pax flags on %s, file is probably busy" % library)
+ print("\tShut down all processes that use it and try again")
+ ( library_str_flags, library_bin_flags ) = pax.getflags(library)
+ print('\n\t\t%s ( %s )\n' % ( library, library_str_flags ))
+
+
+def invert_so2library_mappings( so2library_mappings ):
+ library2soname_mappings = {}
+ for soname, library in so2library_mappings.items():
+ library2soname_mappings[library] = soname
+ return library2soname_mappings
+
+#XXXXXXXXXXXXXXXXX
+
+def run_soname(name, verbose, use_soname, mark, allyes, executable_only):
+ shell_path = path = os.getenv('PATH').split(':')
+
+ ( forward_linkings, so2library_mappings ) = get_object_linkings()
+ reverse_linkings = invert_linkings( forward_linkings )
+
+ if use_soname:
+ soname = name
+ else:
+ library2soname_mappings = invert_so2library_mappings(so2library_mappings)
+ try:
+ soname = library2soname_mappings[name]
+ except KeyError:
+ print('%s\tNo such LIBRARY' % name)
+ return
- """
+ try:
+ linkings = reverse_linkings[soname]
+ except KeyError:
+ print('%s\tNo such SONAME' % soname)
+ return
- """ Print out all sonames and their library paths
- for soname in sorted(soname2library):
- elf = soname2library[soname]
- print("%s : %s" % ( soname, elf ))
- """
+ library = so2library_mappings[soname]
+ ( library_str_flags, library_bin_flags ) = pax.getflags(library)
+ print('%s\t%s (%s)\n' % ( soname, library, library_str_flags ))
- """ Print out all ELF objects and the NEEDED sonames and full library paths
- for elf in object_needed:
- sonames = object_needed[elf]
- print("%s" % elf)
- for soname in sorted(object_needed[elf]):
- try:
- print("\t%s\t=> %s" % (soname, soname2library[soname]))
- except KeyError:
- print("\t%s\t=> ****" % soname)
- print("\n\n")
- """
+ mismatched_binaries = []
+ for binary in linkings:
+ try:
+ ( binary_str_flags, binary_bin_flags ) = pax.getflags(binary)
+ if verbose:
+ if executable_only:
+ if os.path.dirname(binary) in shell_path:
+ print('\t%s ( %s )' % ( binary, binary_str_flags ))
+ else:
+ print('\t%s ( %s )' % ( binary, binary_str_flags ))
+ if library_str_flags != binary_str_flags:
+ if executable_only:
+ if os.path.dirname(binary) in shell_path:
+ mismatched_binaries.append(binary)
+ if not verbose:
+ print('\t%s ( %s )' % ( binary, binary_str_flags ))
+ else:
+ mismatched_binaries.append(binary)
+ if not verbose:
+ print('\t%s ( %s )' % ( binary, binary_str_flags ))
+ except pax.PaxError:
+ print('cannot obtain pax flags for %s' % binary)
+
+ if len(mismatched_binaries) == 0:
+ if not verbose:
+ print('\tNo mismatches\n')
+ else:
+ print('\n'),
+ if mark:
+ print('\tWill mark binaries with %s\n' % library_str_flags)
+ for binary in mismatched_binaries:
+ if executable_only:
+ if not os.path.dirname(binary) in shell_path:
+ continue
+ do_marking = False
+ while True:
+ if allyes:
+ ans = 'y'
+ else:
+ ans = get_input('\tSet flags for %s (y/n): ' % binary)
+ if ans == 'y':
+ do_marking = True
+ break
+ elif ans == 'n':
+ do_marking = False
+ break
+ else:
+ print('\t\tPlease enter y or n')
+ if do_marking:
+ try:
+ migrate_flags(binary, library_str_flags, library_bin_flags)
+ except pax.PaxError:
+ print('\n\tCould not set pax flags on %s, file is probably busy' % binary)
+ print('\tShut down all processes that use it and try again')
+ ( binary_str_flags, binary_bin_flags ) = pax.getflags(binary)
+ print('\n\t\t%s ( %s )\n' % ( binary, binary_str_flags ))
+
+
+def run_usage():
+ print('Package Name : elfix')
+ print('Bug Reports : http://bugs.gentoo.org/')
+ print('Program Name : revdep-pax')
+ print('Description : Get or set pax flags on an ELF object')
+ print('')
+ print('Usage : revdep-pax -f [-v] print out all forward mappings for all system binaries')
+ print(' : revdep-pax -r [-ve] print out all reverse mappings for all system sonames')
+ print(' : revdep-pax -b OBJECT [-myv] print all forward mappings only for OBJECT')
+ print(' : revdep-pax -s SONAME [-myve] print all reverse mappings only for SONAME')
+ print(' : revdep-pax -l LIBRARY [-myve] print all reverse mappings only for LIBRARY file')
+ print(' : revdep-pax [-h] print out this help')
+ print(' : -v verbose, otherwise just print mismatching objects')
+ print(' : -e only print out executables in shell $PATH')
+ print(' : -m don\'t just report, but mark the mismatching objects')
+ print(' : -y assume "yes" to all prompts for marking (USE CAREFULLY!)')
+ print('')
+
+
+def main():
+ try:
+ opts, args = getopt.getopt(sys.argv[1:], 'hfrb:s:l:vemy')
+ except getopt.GetoptError as err:
+ print(str(err)) # will print something like 'option -a not recognized'
+ run_usage()
+ sys.exit(1)
+
+ if len(opts) == 0:
+ run_usage()
+ sys.exit(1)
+
+ do_usage = False
+ do_forward = False
+ do_reverse = False
+
+ binary = None
+ soname = None
+ library = None
+
+ verbose = False
+ executable_only = False
+ mark = False
+ allyes = False
+
+ opt_count = 0
+
+ for o, a in opts:
+ if o == '-h':
+ do_usage = True
+ opt_count += 1
+ elif o == '-f':
+ do_forward = True
+ opt_count += 1
+ elif o == '-r':
+ do_reverse = True
+ opt_count += 1
+ elif o == '-b':
+ binary = a
+ opt_count += 1
+ elif o == '-s':
+ soname = a
+ opt_count += 1
+ elif o == '-l':
+ library = a
+ opt_count += 1
+ elif o == '-v':
+ verbose = True
+ elif o == '-e':
+ executable_only = True
+ elif o == '-m':
+ mark = True
+ elif o == '-y':
+ allyes = True
+ else:
+ print('Option included in getopt but not handled here!')
+ print('Please file a bug')
+ sys.exit(1)
+
+ # Only allow one of -h, -f -r -b -s
+ if opt_count > 1 or do_usage:
+ run_usage()
+ elif do_forward:
+ run_forward(verbose)
+ elif do_reverse:
+ run_reverse(verbose, executable_only)
+ elif binary != None:
+ run_binary(binary, verbose, mark, allyes)
+ elif soname != None:
+ run_soname(soname, verbose, True, mark, allyes, executable_only)
+ elif library != None:
+ library = os.path.realpath(library)
+ run_soname(library, verbose, False, mark, allyes, executable_only)
- """ 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/alt-revdep-pax b/misc/link_maps
similarity index 100%
copy from misc/alt-revdep-pax
copy to misc/link_maps
^ permalink raw reply related [flat|nested] 30+ messages in thread
* [gentoo-commits] proj/elfix:master commit in: misc/
@ 2012-12-23 3:47 Anthony G. Basile
0 siblings, 0 replies; 30+ messages in thread
From: Anthony G. Basile @ 2012-12-23 3:47 UTC (permalink / raw
To: gentoo-commits
commit: 718cf5013101bb2e8c1eced72fd4bc37e5330f97
Author: Anthony G. Basile <blueness <AT> gentoo <DOT> org>
AuthorDate: Sun Dec 23 03:47:31 2012 +0000
Commit: Anthony G. Basile <blueness <AT> gentoo <DOT> org>
CommitDate: Sun Dec 23 03:47:31 2012 +0000
URL: http://git.overlays.gentoo.org/gitweb/?p=proj/elfix.git;a=commit;h=718cf501
misc/alt-revdep-pax: add printing forward linkings per elf object (-b)
---
misc/alt-revdep-pax | 52 ++++++++++++++++++++++++++++++--------------------
1 files changed, 31 insertions(+), 21 deletions(-)
diff --git a/misc/alt-revdep-pax b/misc/alt-revdep-pax
index 6fb88fa..4ea90d4 100755
--- a/misc/alt-revdep-pax
+++ b/misc/alt-revdep-pax
@@ -365,28 +365,35 @@ def migrate_flags(importer, exporter_str_flags, exporter_bin_flags):
pax.setbinflags(importer, result_bin_flags)
-def run_binary(binary, verbose, mark, allyes):
- if not os.path.exists(binary):
- print('%s\tNo such OBJECT' % binary)
+def run_elf(elf, verbose, mark, allyes):
+
+ if not os.path.exists(elf):
+ print('%s\tNo such OBJECT' % elf)
return
- ( linkings, mappings ) = get_ldd_linkings(binary)
- ( binary_str_flags, binary_bin_flags ) = pax.getflags(binary)
- print('%s (%s)\n' % ( binary, binary_str_flags ))
+
+ try:
+ (elf_str_flags, elf_bin_flags) = pax.getflags(elf)
+ print('%s (%s)\n' % (elf, elf_str_flags))
+ except pax.PaxError:
+ print('%s: No PAX flags found\n' % elf)
+ return
+
+ (object_linkings, soname2library) = get_object_linkings()
mismatched_libraries = []
- for soname in linkings:
+ for soname in object_linkings[elf]:
try:
- library = mappings[soname]
+ library = soname2library[soname]
( library_str_flags, library_bin_flags ) = pax.getflags(library)
if verbose:
print('\t%s\t%s ( %s )' % ( soname, library, library_str_flags ))
- if binary_str_flags != library_str_flags:
+ if elf_str_flags != library_str_flags:
mismatched_libraries.append(library)
if not verbose:
print('\t%s\t%s ( %s )' % ( soname, library, library_str_flags ))
except pax.PaxError:
- print('file for soname %s not found' % soname)
+ print('%s: file for soname not found' % soname)
if len(mismatched_libraries) == 0:
if not verbose:
@@ -394,7 +401,7 @@ def run_binary(binary, verbose, mark, allyes):
else:
print('\n'),
if mark:
- print('\tWill mark libraries with %s\n' % binary_str_flags)
+ print('\tWill mark libraries with %s\n' % elf_str_flags)
for library in mismatched_libraries:
do_marking = False
while True:
@@ -413,12 +420,15 @@ def run_binary(binary, verbose, mark, allyes):
if do_marking:
try:
- migrate_flags(library, binary_str_flags, binary_bin_flags)
+ migrate_flags(library, elf_str_flags, elf_bin_flags)
+ except pax.PaxError:
+ print('\n\tCould not set PAX flags on %s, text maybe busy' % library)
+
+ try:
+ ( library_str_flags, library_bin_flags ) = pax.getflags(library)
+ print('\n\t\t%s ( %s )\n' % ( library, library_str_flags ))
except pax.PaxError:
- print("\n\tCould not set pax flags on %s, file is probably busy" % library)
- print("\tShut down all processes that use it and try again")
- ( library_str_flags, library_bin_flags ) = pax.getflags(library)
- print('\n\t\t%s ( %s )\n' % ( library, library_str_flags ))
+ print('\n\t\t%s: Could not read PAX flags')
def invert_so2library_mappings( so2library_mappings ):
@@ -555,8 +565,8 @@ def main():
do_forward = False
do_reverse = False
- binary = None
- soname = None
+ elf = None
+ soname = None
library = None
verbose = False
@@ -577,7 +587,7 @@ def main():
do_reverse = True
opt_count += 1
elif o == '-b':
- binary = a
+ elf = a
opt_count += 1
elif o == '-s':
soname = a
@@ -605,8 +615,8 @@ def main():
run_forward(verbose)
elif do_reverse:
run_reverse(verbose, executable_only)
- elif binary != None:
- run_binary(binary, verbose, mark, allyes)
+ elif elf != None:
+ run_elf(elf, verbose, mark, allyes)
elif soname != None:
run_soname(soname, verbose, True, mark, allyes, executable_only)
elif library != None:
^ permalink raw reply related [flat|nested] 30+ messages in thread
* [gentoo-commits] proj/elfix:master commit in: misc/
@ 2012-12-23 2:36 Anthony G. Basile
0 siblings, 0 replies; 30+ messages in thread
From: Anthony G. Basile @ 2012-12-23 2:36 UTC (permalink / raw
To: gentoo-commits
commit: eb5aead030d04698ec21b294f4eb3e0a8c192905
Author: Anthony G. Basile <blueness <AT> gentoo <DOT> org>
AuthorDate: Sun Dec 23 02:33:53 2012 +0000
Commit: Anthony G. Basile <blueness <AT> gentoo <DOT> org>
CommitDate: Sun Dec 23 02:35:54 2012 +0000
URL: http://git.overlays.gentoo.org/gitweb/?p=proj/elfix.git;a=commit;h=eb5aead0
misc/alt-revdep-pax: add printing reverse linkings
---
misc/alt-revdep-pax | 149 +++++++++++++++++++++++++++-----------------------
1 files changed, 80 insertions(+), 69 deletions(-)
diff --git a/misc/alt-revdep-pax b/misc/alt-revdep-pax
index b46fe23..6fb88fa 100755
--- a/misc/alt-revdep-pax
+++ b/misc/alt-revdep-pax
@@ -128,37 +128,47 @@ def get_soname_needed( object_needed, library2soname ):
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
-
+"""
+Run through the entire chain of sonameX -> sonameY ... -> sonameZ chain.
+We do this by continuously expanding the list pointed to by the dictionary
+entry until there are no new soname's found.
+"""
def get_soname_linkings( soname_needed, soname2library ):
+
for soname in soname_needed:
while True:
- count = 0
- for s in soname_needed[soname]:
+ found_new_soname = False
+ for s in soname_needed[soname]: # For all the next links ...
try:
- for sf in soname_needed[s]:
- if sf in soname_needed[soname]: # Skip it if we already included it
+ for sf in soname_needed[s]: # ... go one step ahead in the chain
+ if sf in soname_needed[soname]: # ... skip it if we already included it
continue
- if not sf in soname2library: #Skip if its a vdso
+ 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:
+ # 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.
+ soname_needed[soname].append(sf) # ... otherwise collapse it back into
+ found_new_soname = True # first node of the chain.
+
+ except KeyError: # Not all nodes in the chain have a next node
continue
- if count == 0:
- break
- return
+ if not found_new_soname: # We're done, that last iteration found
+ break # no new nodes
+
+
def get_object_linkings():
+
object_needed = get_object_needed()
( library2soname, soname2library ) = get_libraries()
soname_needed = get_soname_needed( object_needed, library2soname )
@@ -166,21 +176,22 @@ def get_object_linkings():
return ( object_needed, soname2library )
-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)
+def print_problems( elfs_without_flags, sonames_without_flags, sonames_missing_library):
- return object_reverse_linkings
+ elfs_without_flags = set(elfs_without_flags)
+ print('\n**** ELF objections without any PAX flags ****\n')
+ for m in elfs_without_flags:
+ print('\t%s' % m)
+ sonames_without_flags = set(sonames_without_flags)
+ print('\n**** SONAMEs with library files without PAX flags ****\n')
+ for m in sonames_without_flags:
+ print('\t%s' % m)
-#XXXXXXXXXXXXXXXX
-def invert_linkings( forward_linkings ):
- reverse_linkings = {}
- return reverse_linkings
-#XXXXXXXXXXXXXXXX
+ sonames_missing_library = set(sonames_missing_library)
+ print('\n**** SONAMES without any library files ****\n')
+ for m in sonames_missing_library:
+ print('\t%s' % m)
def print_object_linkings( object_linkings, soname2library, verbose ):
@@ -223,59 +234,65 @@ def print_object_linkings( object_linkings, soname2library, verbose ):
if count != 0:
print('%s\n\n' % s)
- elfs_without_flags = set(elfs_without_flags)
- print('\n**** ELF objections without any PAX flags ****')
- for m in elfs_without_flags:
- print('\t%s' % m)
-
- sonames_without_flags = set(sonames_without_flags)
- print('\n**** SONAMEs with library files without PAX flags ****')
- for m in sonames_without_flags:
- print('\t%s' % m)
+ print_problems( elfs_without_flags, sonames_without_flags, sonames_missing_library)
- sonames_missing_library = set(sonames_missing_library)
- print('\n**** SONAMES without any library files ****')
- for m in sonames_missing_library:
- print('\t%s' % m)
def run_forward(verbose):
+
( object_linkings, soname2library ) = get_object_linkings()
print_object_linkings( object_linkings, soname2library, verbose)
-def print_reverse_linkings( reverse_linkings, so2library_mappings, verbose, executable_only ):
+
+
+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 print_object_reverse_linkings( object_reverse_linkings, soname2library, verbose, executable_only):
+
shell_path = path = os.getenv('PATH').split(':')
- missing_sonames = []
- missing_links = []
- for soname in reverse_linkings:
+ elfs_without_flags = []
+ sonames_without_flags = []
+ sonames_missing_library = []
+
+ for soname in object_reverse_linkings:
try:
- library = so2library_mappings[soname]
+ library = soname2library[soname]
( library_str_flags, library_bin_flags ) = pax.getflags(library)
sv = '%s\t%s ( %s )\n' % ( soname, library, library_str_flags )
s = sv
+ except KeyError:
+ sonames_missing_library.append(soname)
except pax.PaxError:
- missing_sonames.append(soname)
- continue
+ sonames_without_flags.append(soname)
count = 0
- for binary in reverse_linkings[soname]:
+ for elf in object_reverse_linkings[soname]:
try:
- ( binary_str_flags, binary_bin_flags ) = pax.getflags(binary)
+ ( elf_str_flags, elf_bin_flags ) = pax.getflags(elf)
if executable_only:
- if os.path.dirname(binary) in shell_path:
- sv = '%s\n\t%s ( %s )' % ( sv, binary, binary_str_flags )
- if library_str_flags != binary_str_flags:
- s = '%s\n\t%s ( %s )' % ( s, binary, binary_str_flags )
+ if os.path.dirname(elf) in shell_path:
+ sv = '%s\n\t%s ( %s )' % ( sv, elf, elf_str_flags )
+ if library_str_flags != elf_str_flags:
+ s = '%s\n\t%s ( %s )' % ( s, elf, elf_str_flags )
count = count + 1
else:
- sv = '%s\n\t%s ( %s )' % ( sv, binary, binary_str_flags )
- if library_str_flags != binary_str_flags:
- s = '%s\n\t%s ( %s )' % ( s, binary, binary_str_flags )
+ sv = '%s\n\t%s ( %s )' % ( sv, elf, elf_str_flags )
+ if library_str_flags != elf_str_flags:
+ s = '%s\n\t%s ( %s )' % ( s, elf, elf_str_flags )
count = count + 1
except pax.PaxError:
- missing_links.append(binary)
+ elfs_without_flags.append(elf)
if verbose:
print('%s\n' % sv)
@@ -287,21 +304,15 @@ def print_reverse_linkings( reverse_linkings, so2library_mappings, verbose, exec
if count != 0:
print('%s\n\n' % s)
- missing_sonames = set(missing_sonames)
- print('\n**** Missing sonames ****\n')
- for m in missing_sonames:
- print('\t%s\n' % m)
-
- missing_links = set(missing_links)
- print('\n**** Missing reverse linkings ****\n')
- for m in missing_links:
- print('\t%s\n' % m)
+ print_problems( elfs_without_flags, sonames_without_flags, sonames_missing_library)
def run_reverse(verbose, executable_only):
- ( forward_linkings, so2library_mappings ) = get_object_linkings()
- reverse_linkings = invert_linkings( forward_linkings )
- print_reverse_linkings( reverse_linkings, so2library_mappings, verbose, executable_only)
+ ( object_linkings, soname2library ) = get_object_linkings()
+ object_reverse_linkings = get_object_reverse_linkings( object_linkings )
+ print_object_reverse_linkings( object_reverse_linkings, soname2library, verbose, executable_only)
+
+
def migrate_flags(importer, exporter_str_flags, exporter_bin_flags):
^ permalink raw reply related [flat|nested] 30+ messages in thread
* [gentoo-commits] proj/elfix:master commit in: misc/
@ 2012-12-23 2:36 Anthony G. Basile
0 siblings, 0 replies; 30+ messages in thread
From: Anthony G. Basile @ 2012-12-23 2:36 UTC (permalink / raw
To: gentoo-commits
commit: e14bb283546820ed3bb5174a058af2a30750f97f
Author: Anthony G. Basile <blueness <AT> gentoo <DOT> org>
AuthorDate: Sun Dec 23 01:02:47 2012 +0000
Commit: Anthony G. Basile <blueness <AT> gentoo <DOT> org>
CommitDate: Sun Dec 23 02:35:14 2012 +0000
URL: http://git.overlays.gentoo.org/gitweb/?p=proj/elfix.git;a=commit;h=e14bb283
misc/alt-revdep-pax: add old revdep-pax, add printing forward linkings
---
misc/alt-revdep-pax | 503 +++++++++++++++++++++++++++++++-----
misc/{alt-revdep-pax => link_maps} | 0
2 files changed, 440 insertions(+), 63 deletions(-)
diff --git a/misc/alt-revdep-pax b/misc/alt-revdep-pax
index a6adacd..6c0c7ba 100755
--- a/misc/alt-revdep-pax
+++ b/misc/alt-revdep-pax
@@ -1,4 +1,21 @@
#!/usr/bin/env python
+#
+# alt-revdep-pax: this file is part of the elfix package
+# Copyright (C) 2011 Anthony G. Basile
+#
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+#
#
# Note: This alternative way of doing revdep-pax only
@@ -9,12 +26,21 @@
# echo "${arch:3};${obj};${soname};${rpath};${needed}" >> "${PORTAGE_BUILDDIR}"/build-info/NEEDED.ELF.2
#
+import getopt
import os
import sys
import re
import pax
+""" python2/3 compat input """
+def get_input(prompt):
+ if sys.hexversion > 0x03000000:
+ return input(prompt)
+ else:
+ return raw_input(prompt)
+
+
"""
Return object_needed dictionary which has structure
@@ -132,6 +158,14 @@ def get_soname_linkings( soname_needed, soname2library ):
return
+def get_object_linkings():
+ object_needed = get_object_needed()
+ ( library2soname, soname2library ) = get_libraries()
+ soname_needed = get_soname_needed( object_needed, library2soname )
+ get_soname_linkings( soname_needed, soname2library )
+ return ( object_needed, soname2library )
+
+
def get_object_reverse_linkings( object_linkings ):
object_reverse_linkings = {}
@@ -142,83 +176,426 @@ def get_object_reverse_linkings( object_linkings ):
return object_reverse_linkings
-def main():
+#XXXXXXXXXXXXXXXX
+def invert_linkings( forward_linkings ):
+ reverse_linkings = {}
+ return reverse_linkings
+#XXXXXXXXXXXXXXXX
- # 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 )
+def print_object_linkings( object_linkings, soname2library, verbose ):
- # 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 )
+ elfs_without_flags = []
+ sonames_without_flags = []
+ sonames_missing_library = []
+
+ for elf in object_linkings:
+ try:
+ ( elf_str_flags, elf_bin_flags ) = pax.getflags(elf)
+ sv = '%s ( %s )\n' % ( elf, elf_str_flags )
+ s = sv
+ except pax.PaxError:
+ elf_without_flags.append(elf)
+ continue
+
+ count = 0
+ for soname in object_linkings[elf]:
+ try:
+ library = soname2library[soname]
+ ( library_str_flags, library_bin_flags ) = pax.getflags(library)
+ sv = '%s\n\t%s\t%s ( %s )' % ( sv, soname, library, library_str_flags )
+ if elf_str_flags != library_str_flags:
+ s = '%s\n\t%s\t%s ( %s )' % ( s, soname, library, library_str_flags )
+ count = count + 1
+ except KeyError:
+ sonames_missing_library.append(soname)
+ except pax.PaxError:
+ sonames_without_flags.append(soname)
+
+
+ if verbose:
+ print('%s\n' % sv)
+ if count == 0:
+ print('\tNo mismatches\n\n')
+ else:
+ print('\tMismatches\n\n')
+ else:
+ if count != 0:
+ print('%s\n\n' % s)
- object_linkings = object_needed
- object_needed = None
+ elfs_without_flags = set(elfs_without_flags)
+ print('\n**** ELF objections without any PAX flags ****')
+ for m in elfs_without_flags:
+ print('\t%s' % m)
- soname_linkings = soname_needed
- soname_needed = None
+ sonames_without_flags = set(sonames_without_flags)
+ print('\n**** SONAMEs with library files without PAX flags ****')
+ for m in sonames_without_flags:
+ print('\t%s' % m)
- object_reverse_linkings = get_object_reverse_linkings( object_linkings )
+ sonames_missing_library = set(sonames_missing_library)
+ print('\n**** SONAMES without any library files ****')
+ for m in sonames_missing_library:
+ print('\t%s' % m)
- """ Print out all ELF objects and their PaX flags
- for elf in object_needed:
+
+def run_forward(verbose):
+ ( object_linkings, soname2library ) = get_object_linkings()
+ print_object_linkings( object_linkings, soname2library, verbose)
+
+
+def print_reverse_linkings( reverse_linkings, so2library_mappings, verbose, executable_only ):
+ shell_path = path = os.getenv('PATH').split(':')
+ missing_sonames = []
+ missing_links = []
+
+ for soname in reverse_linkings:
try:
- flags = pax.getflags(elf)[0]
- if flags:
- print("%s %s" % (flags, elf))
+ library = so2library_mappings[soname]
+ ( library_str_flags, library_bin_flags ) = pax.getflags(library)
+ sv = '%s\t%s ( %s )\n' % ( soname, library, library_str_flags )
+ s = sv
+ except pax.PaxError:
+ missing_sonames.append(soname)
+ continue
+
+ count = 0
+ for binary in reverse_linkings[soname]:
+ try:
+ ( binary_str_flags, binary_bin_flags ) = pax.getflags(binary)
+ if executable_only:
+ if os.path.dirname(binary) in shell_path:
+ sv = '%s\n\t%s ( %s )' % ( sv, binary, binary_str_flags )
+ if library_str_flags != binary_str_flags:
+ s = '%s\n\t%s ( %s )' % ( s, binary, binary_str_flags )
+ count = count + 1
+ else:
+ sv = '%s\n\t%s ( %s )' % ( sv, binary, binary_str_flags )
+ if library_str_flags != binary_str_flags:
+ s = '%s\n\t%s ( %s )' % ( s, binary, binary_str_flags )
+ count = count + 1
+ except pax.PaxError:
+ missing_links.append(binary)
+
+ if verbose:
+ print('%s\n' % sv)
+ if count == 0:
+ print('\tNo mismatches\n\n')
else:
- print("NONE: %s" % elf)
- except pax.error:
- print("CANT: %s" % elf)
+ print('\tMismatches\n\n')
+ else:
+ if count != 0:
+ print('%s\n\n' % s)
+
+ missing_sonames = set(missing_sonames)
+ print('\n**** Missing sonames ****\n')
+ for m in missing_sonames:
+ print('\t%s\n' % m)
+
+ missing_links = set(missing_links)
+ print('\n**** Missing reverse linkings ****\n')
+ for m in missing_links:
+ print('\t%s\n' % m)
+
+
+def run_reverse(verbose, executable_only):
+ ( forward_linkings, so2library_mappings ) = get_object_linkings()
+ reverse_linkings = invert_linkings( forward_linkings )
+ print_reverse_linkings( reverse_linkings, so2library_mappings, verbose, executable_only)
+
+
+def migrate_flags(importer, exporter_str_flags, exporter_bin_flags):
+ # We implement the following logic for setting the pax flags
+ # on the target elf object, the IMPORTER, given that the flags
+ # from the elf object we want it to match to, the EXPORTER.
+ #
+ # EXPORTER IMPORTER RESULT
+ # On On On
+ # On Off On + Warn
+ # On - On
+ # Off On On + Warn
+ # Off Off Off
+ # Off - Off
+ # - On On
+ # - Off Off
+ # - - -
+
+ #See /usr/include/elf.h for these values
+ pf_flags = {
+ 'P':1<<4, 'p':1<<5,
+ 'S':1<<6, 's':1<<7,
+ 'M':1<<8, 'm':1<<9,
+ 'X':1<<10, 'x':1<<11,
+ 'E':1<<12, 'e':1<<13,
+ 'R':1<<14, 'r':1<<15
+ }
+
+ ( importer_str_flags, importer_bin_flags ) = pax.getflags(importer)
+
+ # Start with the exporter's flags
+ result_bin_flags = exporter_bin_flags
+
+ for i in range(len(importer_str_flags)):
+
+ # The exporter's flag contradicts the importer's flag, so do nothing
+ if (exporter_str_flags[i].isupper() and importer_str_flags[i].islower()) or \
+ (exporter_str_flags[i].islower() and importer_str_flags[i].isupper()):
+
+ # Revert the exporter's flag, use the importer's flag and warn
+ result_bin_flags = result_bin_flags ^ pf_flags[exporter_str_flags[i]]
+ result_bin_flags = result_bin_flags | pf_flags[importer_str_flags[i]]
+ print('\t\tWarning: %s has %s, refusing to set to %s' % (
+ importer, importer_str_flags[i], exporter_str_flags[i] )),
+
+ # The exporter's flags is off, so use the importer's flag
+ if (exporter_str_flags[i] == '-' and importer_str_flags[i] != '-'):
+ result_bin_flags = result_bin_flags | pf_flags[importer_str_flags[i]]
+
+ pax.setbinflags(importer, result_bin_flags)
+
+
+def run_binary(binary, verbose, mark, allyes):
+ if not os.path.exists(binary):
+ print('%s\tNo such OBJECT' % binary)
+ return
+ ( linkings, mappings ) = get_ldd_linkings(binary)
+ ( binary_str_flags, binary_bin_flags ) = pax.getflags(binary)
+ print('%s (%s)\n' % ( binary, binary_str_flags ))
+
+ mismatched_libraries = []
+
+ for soname in linkings:
+ try:
+ library = mappings[soname]
+ ( library_str_flags, library_bin_flags ) = pax.getflags(library)
+ if verbose:
+ print('\t%s\t%s ( %s )' % ( soname, library, library_str_flags ))
+ if binary_str_flags != library_str_flags:
+ mismatched_libraries.append(library)
+ if not verbose:
+ print('\t%s\t%s ( %s )' % ( soname, library, library_str_flags ))
+ except pax.PaxError:
+ print('file for soname %s not found' % soname)
+
+ if len(mismatched_libraries) == 0:
+ if not verbose:
+ print('\tNo mismatches\n')
+ else:
+ print('\n'),
+ if mark:
+ print('\tWill mark libraries with %s\n' % binary_str_flags)
+ for library in mismatched_libraries:
+ do_marking = False
+ while True:
+ if allyes:
+ ans = 'y'
+ else:
+ ans = get_input('\tSet flags for %s (y/n): ' % library)
+ if ans == 'y':
+ do_marking = True
+ break
+ elif ans == 'n':
+ do_marking = False
+ break
+ else:
+ print('\t\tPlease enter y or n')
+
+ if do_marking:
+ try:
+ migrate_flags(library, binary_str_flags, binary_bin_flags)
+ except pax.PaxError:
+ print("\n\tCould not set pax flags on %s, file is probably busy" % library)
+ print("\tShut down all processes that use it and try again")
+ ( library_str_flags, library_bin_flags ) = pax.getflags(library)
+ print('\n\t\t%s ( %s )\n' % ( library, library_str_flags ))
+
+
+def invert_so2library_mappings( so2library_mappings ):
+ library2soname_mappings = {}
+ for soname, library in so2library_mappings.items():
+ library2soname_mappings[library] = soname
+ return library2soname_mappings
+
+#XXXXXXXXXXXXXXXXX
+
+def run_soname(name, verbose, use_soname, mark, allyes, executable_only):
+ shell_path = path = os.getenv('PATH').split(':')
+
+ ( forward_linkings, so2library_mappings ) = get_object_linkings()
+ reverse_linkings = invert_linkings( forward_linkings )
+
+ if use_soname:
+ soname = name
+ else:
+ library2soname_mappings = invert_so2library_mappings(so2library_mappings)
+ try:
+ soname = library2soname_mappings[name]
+ except KeyError:
+ print('%s\tNo such LIBRARY' % name)
+ return
- """
+ try:
+ linkings = reverse_linkings[soname]
+ except KeyError:
+ print('%s\tNo such SONAME' % soname)
+ return
- """ Print out all sonames and their library paths
- for soname in sorted(soname2library):
- elf = soname2library[soname]
- print("%s : %s" % ( soname, elf ))
- """
+ library = so2library_mappings[soname]
+ ( library_str_flags, library_bin_flags ) = pax.getflags(library)
+ print('%s\t%s (%s)\n' % ( soname, library, library_str_flags ))
- """ Print out all ELF objects and the NEEDED sonames and full library paths
- for elf in object_needed:
- sonames = object_needed[elf]
- print("%s" % elf)
- for soname in sorted(object_needed[elf]):
- try:
- print("\t%s\t=> %s" % (soname, soname2library[soname]))
- except KeyError:
- print("\t%s\t=> ****" % soname)
- print("\n\n")
- """
+ mismatched_binaries = []
+ for binary in linkings:
+ try:
+ ( binary_str_flags, binary_bin_flags ) = pax.getflags(binary)
+ if verbose:
+ if executable_only:
+ if os.path.dirname(binary) in shell_path:
+ print('\t%s ( %s )' % ( binary, binary_str_flags ))
+ else:
+ print('\t%s ( %s )' % ( binary, binary_str_flags ))
+ if library_str_flags != binary_str_flags:
+ if executable_only:
+ if os.path.dirname(binary) in shell_path:
+ mismatched_binaries.append(binary)
+ if not verbose:
+ print('\t%s ( %s )' % ( binary, binary_str_flags ))
+ else:
+ mismatched_binaries.append(binary)
+ if not verbose:
+ print('\t%s ( %s )' % ( binary, binary_str_flags ))
+ except pax.PaxError:
+ print('cannot obtain pax flags for %s' % binary)
+
+ if len(mismatched_binaries) == 0:
+ if not verbose:
+ print('\tNo mismatches\n')
+ else:
+ print('\n'),
+ if mark:
+ print('\tWill mark binaries with %s\n' % library_str_flags)
+ for binary in mismatched_binaries:
+ if executable_only:
+ if not os.path.dirname(binary) in shell_path:
+ continue
+ do_marking = False
+ while True:
+ if allyes:
+ ans = 'y'
+ else:
+ ans = get_input('\tSet flags for %s (y/n): ' % binary)
+ if ans == 'y':
+ do_marking = True
+ break
+ elif ans == 'n':
+ do_marking = False
+ break
+ else:
+ print('\t\tPlease enter y or n')
+ if do_marking:
+ try:
+ migrate_flags(binary, library_str_flags, library_bin_flags)
+ except pax.PaxError:
+ print('\n\tCould not set pax flags on %s, file is probably busy' % binary)
+ print('\tShut down all processes that use it and try again')
+ ( binary_str_flags, binary_bin_flags ) = pax.getflags(binary)
+ print('\n\t\t%s ( %s )\n' % ( binary, binary_str_flags ))
+
+
+def run_usage():
+ print('Package Name : elfix')
+ print('Bug Reports : http://bugs.gentoo.org/')
+ print('Program Name : revdep-pax')
+ print('Description : Get or set pax flags on an ELF object')
+ print('')
+ print('Usage : revdep-pax -f [-v] print out all forward mappings for all system binaries')
+ print(' : revdep-pax -r [-ve] print out all reverse mappings for all system sonames')
+ print(' : revdep-pax -b OBJECT [-myv] print all forward mappings only for OBJECT')
+ print(' : revdep-pax -s SONAME [-myve] print all reverse mappings only for SONAME')
+ print(' : revdep-pax -l LIBRARY [-myve] print all reverse mappings only for LIBRARY file')
+ print(' : revdep-pax [-h] print out this help')
+ print(' : -v verbose, otherwise just print mismatching objects')
+ print(' : -e only print out executables in shell $PATH')
+ print(' : -m don\'t just report, but mark the mismatching objects')
+ print(' : -y assume "yes" to all prompts for marking (USE CAREFULLY!)')
+ print('')
+
+
+def main():
+ try:
+ opts, args = getopt.getopt(sys.argv[1:], 'hfrb:s:l:vemy')
+ except getopt.GetoptError as err:
+ print(str(err)) # will print something like 'option -a not recognized'
+ run_usage()
+ sys.exit(1)
+
+ if len(opts) == 0:
+ run_usage()
+ sys.exit(1)
+
+ do_usage = False
+ do_forward = False
+ do_reverse = False
+
+ binary = None
+ soname = None
+ library = None
+
+ verbose = False
+ executable_only = False
+ mark = False
+ allyes = False
+
+ opt_count = 0
+
+ for o, a in opts:
+ if o == '-h':
+ do_usage = True
+ opt_count += 1
+ elif o == '-f':
+ do_forward = True
+ opt_count += 1
+ elif o == '-r':
+ do_reverse = True
+ opt_count += 1
+ elif o == '-b':
+ binary = a
+ opt_count += 1
+ elif o == '-s':
+ soname = a
+ opt_count += 1
+ elif o == '-l':
+ library = a
+ opt_count += 1
+ elif o == '-v':
+ verbose = True
+ elif o == '-e':
+ executable_only = True
+ elif o == '-m':
+ mark = True
+ elif o == '-y':
+ allyes = True
+ else:
+ print('Option included in getopt but not handled here!')
+ print('Please file a bug')
+ sys.exit(1)
+
+ # Only allow one of -h, -f -r -b -s
+ if opt_count > 1 or do_usage:
+ run_usage()
+ elif do_forward:
+ run_forward(verbose)
+ elif do_reverse:
+ run_reverse(verbose, executable_only)
+ elif binary != None:
+ run_binary(binary, verbose, mark, allyes)
+ elif soname != None:
+ run_soname(soname, verbose, True, mark, allyes, executable_only)
+ elif library != None:
+ library = os.path.realpath(library)
+ run_soname(library, verbose, False, mark, allyes, executable_only)
- """ 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/alt-revdep-pax b/misc/link_maps
similarity index 100%
copy from misc/alt-revdep-pax
copy to misc/link_maps
^ permalink raw reply related [flat|nested] 30+ messages in thread
* [gentoo-commits] proj/elfix:master commit in: misc/
@ 2012-12-23 2:34 Anthony G. Basile
0 siblings, 0 replies; 30+ messages in thread
From: Anthony G. Basile @ 2012-12-23 2:34 UTC (permalink / raw
To: gentoo-commits
commit: e80684bb766a7ccb8f51d7f131d524036a60ae5f
Author: Anthony G. Basile <blueness <AT> gentoo <DOT> org>
AuthorDate: Sun Dec 23 02:33:53 2012 +0000
Commit: Anthony G. Basile <blueness <AT> gentoo <DOT> org>
CommitDate: Sun Dec 23 02:33:53 2012 +0000
URL: http://git.overlays.gentoo.org/gitweb/?p=proj/elfix.git;a=commit;h=e80684bb
misc/alt-revdep-pax: add printing reverse linkings
---
misc/alt-revdep-pax | 149 +++++++++++++++++++++++++++-----------------------
1 files changed, 80 insertions(+), 69 deletions(-)
diff --git a/misc/alt-revdep-pax b/misc/alt-revdep-pax
index b46fe23..6fb88fa 100755
--- a/misc/alt-revdep-pax
+++ b/misc/alt-revdep-pax
@@ -128,37 +128,47 @@ def get_soname_needed( object_needed, library2soname ):
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
-
+"""
+Run through the entire chain of sonameX -> sonameY ... -> sonameZ chain.
+We do this by continuously expanding the list pointed to by the dictionary
+entry until there are no new soname's found.
+"""
def get_soname_linkings( soname_needed, soname2library ):
+
for soname in soname_needed:
while True:
- count = 0
- for s in soname_needed[soname]:
+ found_new_soname = False
+ for s in soname_needed[soname]: # For all the next links ...
try:
- for sf in soname_needed[s]:
- if sf in soname_needed[soname]: # Skip it if we already included it
+ for sf in soname_needed[s]: # ... go one step ahead in the chain
+ if sf in soname_needed[soname]: # ... skip it if we already included it
continue
- if not sf in soname2library: #Skip if its a vdso
+ 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:
+ # 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.
+ soname_needed[soname].append(sf) # ... otherwise collapse it back into
+ found_new_soname = True # first node of the chain.
+
+ except KeyError: # Not all nodes in the chain have a next node
continue
- if count == 0:
- break
- return
+ if not found_new_soname: # We're done, that last iteration found
+ break # no new nodes
+
+
def get_object_linkings():
+
object_needed = get_object_needed()
( library2soname, soname2library ) = get_libraries()
soname_needed = get_soname_needed( object_needed, library2soname )
@@ -166,21 +176,22 @@ def get_object_linkings():
return ( object_needed, soname2library )
-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)
+def print_problems( elfs_without_flags, sonames_without_flags, sonames_missing_library):
- return object_reverse_linkings
+ elfs_without_flags = set(elfs_without_flags)
+ print('\n**** ELF objections without any PAX flags ****\n')
+ for m in elfs_without_flags:
+ print('\t%s' % m)
+ sonames_without_flags = set(sonames_without_flags)
+ print('\n**** SONAMEs with library files without PAX flags ****\n')
+ for m in sonames_without_flags:
+ print('\t%s' % m)
-#XXXXXXXXXXXXXXXX
-def invert_linkings( forward_linkings ):
- reverse_linkings = {}
- return reverse_linkings
-#XXXXXXXXXXXXXXXX
+ sonames_missing_library = set(sonames_missing_library)
+ print('\n**** SONAMES without any library files ****\n')
+ for m in sonames_missing_library:
+ print('\t%s' % m)
def print_object_linkings( object_linkings, soname2library, verbose ):
@@ -223,59 +234,65 @@ def print_object_linkings( object_linkings, soname2library, verbose ):
if count != 0:
print('%s\n\n' % s)
- elfs_without_flags = set(elfs_without_flags)
- print('\n**** ELF objections without any PAX flags ****')
- for m in elfs_without_flags:
- print('\t%s' % m)
-
- sonames_without_flags = set(sonames_without_flags)
- print('\n**** SONAMEs with library files without PAX flags ****')
- for m in sonames_without_flags:
- print('\t%s' % m)
+ print_problems( elfs_without_flags, sonames_without_flags, sonames_missing_library)
- sonames_missing_library = set(sonames_missing_library)
- print('\n**** SONAMES without any library files ****')
- for m in sonames_missing_library:
- print('\t%s' % m)
def run_forward(verbose):
+
( object_linkings, soname2library ) = get_object_linkings()
print_object_linkings( object_linkings, soname2library, verbose)
-def print_reverse_linkings( reverse_linkings, so2library_mappings, verbose, executable_only ):
+
+
+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 print_object_reverse_linkings( object_reverse_linkings, soname2library, verbose, executable_only):
+
shell_path = path = os.getenv('PATH').split(':')
- missing_sonames = []
- missing_links = []
- for soname in reverse_linkings:
+ elfs_without_flags = []
+ sonames_without_flags = []
+ sonames_missing_library = []
+
+ for soname in object_reverse_linkings:
try:
- library = so2library_mappings[soname]
+ library = soname2library[soname]
( library_str_flags, library_bin_flags ) = pax.getflags(library)
sv = '%s\t%s ( %s )\n' % ( soname, library, library_str_flags )
s = sv
+ except KeyError:
+ sonames_missing_library.append(soname)
except pax.PaxError:
- missing_sonames.append(soname)
- continue
+ sonames_without_flags.append(soname)
count = 0
- for binary in reverse_linkings[soname]:
+ for elf in object_reverse_linkings[soname]:
try:
- ( binary_str_flags, binary_bin_flags ) = pax.getflags(binary)
+ ( elf_str_flags, elf_bin_flags ) = pax.getflags(elf)
if executable_only:
- if os.path.dirname(binary) in shell_path:
- sv = '%s\n\t%s ( %s )' % ( sv, binary, binary_str_flags )
- if library_str_flags != binary_str_flags:
- s = '%s\n\t%s ( %s )' % ( s, binary, binary_str_flags )
+ if os.path.dirname(elf) in shell_path:
+ sv = '%s\n\t%s ( %s )' % ( sv, elf, elf_str_flags )
+ if library_str_flags != elf_str_flags:
+ s = '%s\n\t%s ( %s )' % ( s, elf, elf_str_flags )
count = count + 1
else:
- sv = '%s\n\t%s ( %s )' % ( sv, binary, binary_str_flags )
- if library_str_flags != binary_str_flags:
- s = '%s\n\t%s ( %s )' % ( s, binary, binary_str_flags )
+ sv = '%s\n\t%s ( %s )' % ( sv, elf, elf_str_flags )
+ if library_str_flags != elf_str_flags:
+ s = '%s\n\t%s ( %s )' % ( s, elf, elf_str_flags )
count = count + 1
except pax.PaxError:
- missing_links.append(binary)
+ elfs_without_flags.append(elf)
if verbose:
print('%s\n' % sv)
@@ -287,21 +304,15 @@ def print_reverse_linkings( reverse_linkings, so2library_mappings, verbose, exec
if count != 0:
print('%s\n\n' % s)
- missing_sonames = set(missing_sonames)
- print('\n**** Missing sonames ****\n')
- for m in missing_sonames:
- print('\t%s\n' % m)
-
- missing_links = set(missing_links)
- print('\n**** Missing reverse linkings ****\n')
- for m in missing_links:
- print('\t%s\n' % m)
+ print_problems( elfs_without_flags, sonames_without_flags, sonames_missing_library)
def run_reverse(verbose, executable_only):
- ( forward_linkings, so2library_mappings ) = get_object_linkings()
- reverse_linkings = invert_linkings( forward_linkings )
- print_reverse_linkings( reverse_linkings, so2library_mappings, verbose, executable_only)
+ ( object_linkings, soname2library ) = get_object_linkings()
+ object_reverse_linkings = get_object_reverse_linkings( object_linkings )
+ print_object_reverse_linkings( object_reverse_linkings, soname2library, verbose, executable_only)
+
+
def migrate_flags(importer, exporter_str_flags, exporter_bin_flags):
^ permalink raw reply related [flat|nested] 30+ messages in thread
* [gentoo-commits] proj/elfix:master commit in: misc/
@ 2012-12-22 14:44 Anthony G. Basile
0 siblings, 0 replies; 30+ messages in thread
From: Anthony G. Basile @ 2012-12-22 14:44 UTC (permalink / raw
To: gentoo-commits
commit: 9eded889c6bccc979704a72be8b1a76606327e9c
Author: Anthony G. Basile <blueness <AT> gentoo <DOT> org>
AuthorDate: Sat Dec 22 14:44:14 2012 +0000
Commit: Anthony G. Basile <blueness <AT> gentoo <DOT> org>
CommitDate: Sat Dec 22 14:44:14 2012 +0000
URL: http://git.overlays.gentoo.org/gitweb/?p=proj/elfix.git;a=commit;h=9eded889
misc/alt-revdep-pax: remove soname list copy, add get_object_reverse_linkings()
---
misc/alt-revdep-pax | 91 +++++++++++++++++++++++++++++++--------------------
1 files changed, 55 insertions(+), 36 deletions(-)
diff --git a/misc/alt-revdep-pax b/misc/alt-revdep-pax
index 181b57e..a6adacd 100755
--- a/misc/alt-revdep-pax
+++ b/misc/alt-revdep-pax
@@ -13,16 +13,17 @@ import os
import sys
import re
import pax
-#from copy import copy
-def get_object_needed():
- """
- Return object_needed dictionary which has structure
- { full_path_to_ELF_object : [ soname1, soname2, ... ], ... }
+"""
+Return object_needed dictionary which has structure
- Here the sonames were obtained from the ELF object by readelf -d
- """
+ { 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():
var_db_pkg = '/var/db/pkg'
@@ -47,16 +48,17 @@ def get_object_needed():
return object_needed
-def get_library():
- """
- Return library2soname dictionary which has structure
+"""
+Return library2soname dictionary which has structure
- { full_path_to_library : soname, ... }
+ { full_path_to_library : soname, ... }
- and its inverse which has structure
+and its inverse which has structure
+
+ { soname : full_path_to_library, ... }
+"""
+def get_libraries():
- { soname : full_path_to_library, ... }
- """
var_db_pkg = '/var/db/pkg'
library2soname = {}
@@ -84,14 +86,15 @@ def get_library():
return ( library2soname, soname2library )
-def get_soname_needed( object_needed, library2soname ):
- """
- Return get_soname_needed dictionary which has structure:
+"""
+Return get_soname_needed dictionary which has structure:
- { soname : [ soname1, soname2, ... ], .... }
+ { soname : [ soname1, soname2, ... ], .... }
- Here the soname1,2,... were obtained from soname's corresponding ELF library by readelf -d
- """
+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 = {}
@@ -107,29 +110,36 @@ def get_soname_needed( object_needed, library2soname ):
def get_soname_linkings( soname_needed, soname2library ):
- soname_linkings = {}
for soname in soname_needed:
- needed = soname_needed[soname]
- #needed = copy(soname_needed[soname]) #copy the list
while True:
count = 0
- for s in needed:
+ for s in soname_needed[soname]:
try:
for sf in soname_needed[s]:
- if not sf in needed and sf in soname2library:
- # This appends to the object_needed and
- # soname_needed list. No copy was done
- needed.append(sf)
- count = 1
+ 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
+
- soname_linkings[soname] = needed
+def get_object_reverse_linkings( object_linkings ):
+ object_reverse_linkings = {}
- return soname_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():
@@ -141,14 +151,22 @@ def main():
sys.exit(0)
object_needed = get_object_needed()
- ( library2soname, soname2library ) = get_library()
+ ( library2soname, soname2library ) = get_libraries()
soname_needed = get_soname_needed( object_needed, library2soname )
- soname_linkings = get_soname_linkings( soname_needed, soname2library )
- # After the appending in get_soname_linkings, forward_needed has
- # been extended through the entire chain of linking.:w
+ # 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 their PaX flags
for elf in object_needed:
@@ -170,7 +188,7 @@ def main():
"""
- """ Print out all ELF objects and the NEEDED sonames and full library paths """
+ """ Print out all ELF objects and the NEEDED sonames and full library paths
for elf in object_needed:
sonames = object_needed[elf]
print("%s" % elf)
@@ -180,6 +198,7 @@ def main():
except KeyError:
print("\t%s\t=> ****" % soname)
print("\n\n")
+ """
""" Print out all the soname to soname NEEDED
for soname in soname_needed:
^ permalink raw reply related [flat|nested] 30+ messages in thread
* [gentoo-commits] proj/elfix:master commit in: misc/
@ 2012-12-22 4:21 Anthony G. Basile
0 siblings, 0 replies; 30+ messages in thread
From: Anthony G. Basile @ 2012-12-22 4:21 UTC (permalink / raw
To: gentoo-commits
commit: 43b0e6b5a90a5ddd66e6f201f9b1fdf8f671a2a0
Author: Anthony G. Basile <blueness <AT> gentoo <DOT> org>
AuthorDate: Sat Dec 22 04:21:43 2012 +0000
Commit: Anthony G. Basile <blueness <AT> gentoo <DOT> org>
CommitDate: Sat Dec 22 04:21:43 2012 +0000
URL: http://git.overlays.gentoo.org/gitweb/?p=proj/elfix.git;a=commit;h=43b0e6b5
misc/alt-revdep-pax: remove copy.copy in constructing object linking chain
---
misc/alt-revdep-pax | 26 +++++++++++++++-----------
1 files changed, 15 insertions(+), 11 deletions(-)
diff --git a/misc/alt-revdep-pax b/misc/alt-revdep-pax
index fcf63b6..181b57e 100755
--- a/misc/alt-revdep-pax
+++ b/misc/alt-revdep-pax
@@ -13,7 +13,7 @@ import os
import sys
import re
import pax
-from copy import copy
+#from copy import copy
def get_object_needed():
"""
@@ -98,23 +98,27 @@ def get_soname_needed( object_needed, library2soname ):
for elf in object_needed:
try:
soname = library2soname[elf]
- soname_needed[soname] = copy(object_needed[elf]) #copy the list
+ 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 ):
+def get_soname_linkings( soname_needed, soname2library ):
soname_linkings = {}
for soname in soname_needed:
- needed = copy(soname_needed[soname])
+ needed = soname_needed[soname]
+ #needed = copy(soname_needed[soname]) #copy the list
while True:
count = 0
for s in needed:
try:
for sf in soname_needed[s]:
- if not sf in needed:
+ if not sf in needed and sf in soname2library:
+ # This appends to the object_needed and
+ # soname_needed list. No copy was done
needed.append(sf)
count = 1
except KeyError:
@@ -139,10 +143,11 @@ def main():
object_needed = get_object_needed()
( library2soname, soname2library ) = get_library()
soname_needed = get_soname_needed( object_needed, library2soname )
- soname_linkings = get_soname_linkings( soname_needed )
- print soname_linkings
+ soname_linkings = get_soname_linkings( soname_needed, soname2library )
- #forward_linkings = get_forward_linkings( object_needed, soname_linkings )
+ # After the appending in get_soname_linkings, forward_needed has
+ # been extended through the entire chain of linking.:w
+ object_linkings = object_needed
""" Print out all ELF objects and their PaX flags
@@ -162,10 +167,10 @@ def main():
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
+ """ Print out all ELF objects and the NEEDED sonames and full library paths """
for elf in object_needed:
sonames = object_needed[elf]
print("%s" % elf)
@@ -175,7 +180,6 @@ def main():
except KeyError:
print("\t%s\t=> ****" % soname)
print("\n\n")
- """
""" Print out all the soname to soname NEEDED
for soname in soname_needed:
^ permalink raw reply related [flat|nested] 30+ messages in thread
* [gentoo-commits] proj/elfix:master commit in: misc/
@ 2012-12-22 3:58 Anthony G. Basile
0 siblings, 0 replies; 30+ messages in thread
From: Anthony G. Basile @ 2012-12-22 3:58 UTC (permalink / raw
To: gentoo-commits
commit: 8f5c0363ecd8716c5d03bb55940ac15e7cc07334
Author: Anthony G. Basile <blueness <AT> gentoo <DOT> org>
AuthorDate: Sat Dec 22 03:58:34 2012 +0000
Commit: Anthony G. Basile <blueness <AT> gentoo <DOT> org>
CommitDate: Sat Dec 22 03:58:34 2012 +0000
URL: http://git.overlays.gentoo.org/gitweb/?p=proj/elfix.git;a=commit;h=8f5c0363
misc/alt-revdep-pax: follow NEEDED to end of linking chain
---
misc/alt-revdep-pax | 89 +++++++++++++++++++++++++++++++++++++-------------
1 files changed, 66 insertions(+), 23 deletions(-)
diff --git a/misc/alt-revdep-pax b/misc/alt-revdep-pax
index 607372a..fcf63b6 100755
--- a/misc/alt-revdep-pax
+++ b/misc/alt-revdep-pax
@@ -13,10 +13,11 @@ import os
import sys
import re
import pax
+from copy import copy
-def get_forward_needed():
+def get_object_needed():
"""
- Return forward_needed dictionary which has structure
+ Return object_needed dictionary which has structure
{ full_path_to_ELF_object : [ soname1, soname2, ... ], ... }
@@ -25,7 +26,7 @@ def get_forward_needed():
var_db_pkg = '/var/db/pkg'
- forward_needed = {}
+ object_needed = {}
for cat in os.listdir(var_db_pkg):
catdir = '%s/%s' % (var_db_pkg, cat)
for pkg in os.listdir(catdir):
@@ -39,11 +40,11 @@ def get_forward_needed():
link = re.split(';', line)
elf = link[1]
sonames = re.split(',', link[4])
- forward_needed[elf] = sonames
+ object_needed[elf] = sonames
except IOError:
continue #File probably doesn't exist, which is okay
- return forward_needed
+ return object_needed
def get_library():
@@ -83,24 +84,48 @@ def get_library():
return ( library2soname, soname2library )
-def get_soname2soname_linkings( forward_needed, library2soname ):
+def get_soname_needed( object_needed, library2soname ):
"""
- Return get_soname2soname_linkings dictionary which has structure:
+ Return get_soname_needed dictionary which has structure:
{ soname : [ soname1, soname2, ... ], .... }
+ Here the soname1,2,... were obtained from soname's corresponding ELF library by readelf -d
"""
- soname2soname_linkings = {}
+ soname_needed = {}
- for elf in forward_needed:
+ for elf in object_needed:
try:
soname = library2soname[elf]
- soname2soname_linkings[soname] = forward_needed[elf]
+ soname_needed[soname] = copy(object_needed[elf]) #copy the list
except KeyError:
- continue #It doesn't have an soname and prabably isn't a library
+ continue # no soname, its probably an executable
- return soname2soname_linkings
+ return soname_needed
+
+
+def get_soname_linkings( soname_needed ):
+ soname_linkings = {}
+ for soname in soname_needed:
+ needed = copy(soname_needed[soname])
+ while True:
+ count = 0
+ for s in needed:
+ try:
+ for sf in soname_needed[s]:
+ if not sf in needed:
+ needed.append(sf)
+ count = 1
+ except KeyError:
+ continue
+
+ if count == 0:
+ break
+
+ soname_linkings[soname] = needed
+
+ return soname_linkings
def main():
@@ -111,19 +136,17 @@ def main():
print('RUN AS ROOT: cannot read all flags')
sys.exit(0)
- forward_needed = get_forward_needed()
+ object_needed = get_object_needed()
( library2soname, soname2library ) = get_library()
+ soname_needed = get_soname_needed( object_needed, library2soname )
+ soname_linkings = get_soname_linkings( soname_needed )
+ print soname_linkings
- soname2soname_linkings = get_soname2soname_linkings( forward_needed, library2soname )
+ #forward_linkings = get_forward_linkings( object_needed, soname_linkings )
- for soname in soname2soname_linkings:
- print("%s" % soname)
- for s in soname2soname_linkings[soname]:
- print("\t%s" % s )
- print('')
""" Print out all ELF objects and their PaX flags
- for elf in forward_needed:
+ for elf in object_needed:
try:
flags = pax.getflags(elf)[0]
if flags:
@@ -143,10 +166,10 @@ def main():
"""
""" Print out all ELF objects and the NEEDED sonames and full library paths
- for elf in forward_needed:
- sonames = forward_needed[elf]
+ for elf in object_needed:
+ sonames = object_needed[elf]
print("%s" % elf)
- for soname in sorted(forward_needed[elf]):
+ for soname in sorted(object_needed[elf]):
try:
print("\t%s\t=> %s" % (soname, soname2library[soname]))
except KeyError:
@@ -154,5 +177,25 @@ def main():
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()
^ permalink raw reply related [flat|nested] 30+ messages in thread
* [gentoo-commits] proj/elfix:master commit in: misc/
@ 2012-12-22 1:06 Anthony G. Basile
0 siblings, 0 replies; 30+ messages in thread
From: Anthony G. Basile @ 2012-12-22 1:06 UTC (permalink / raw
To: gentoo-commits
commit: 06ff2d1f0fd8041675ed4f928c63bbdb58b7e18c
Author: Anthony G. Basile <blueness <AT> gentoo <DOT> org>
AuthorDate: Sat Dec 22 01:06:17 2012 +0000
Commit: Anthony G. Basile <blueness <AT> gentoo <DOT> org>
CommitDate: Sat Dec 22 01:06:17 2012 +0000
URL: http://git.overlays.gentoo.org/gitweb/?p=proj/elfix.git;a=commit;h=06ff2d1f
misc/alt-revdep-pax: add soname to soname linkings for full linking chain
---
misc/alt-revdep-pax | 105 +++++++++++++++++++++++++++++++++++++++------------
1 files changed, 81 insertions(+), 24 deletions(-)
diff --git a/misc/alt-revdep-pax b/misc/alt-revdep-pax
index a9445a1..607372a 100755
--- a/misc/alt-revdep-pax
+++ b/misc/alt-revdep-pax
@@ -10,13 +10,22 @@
#
import os
+import sys
import re
import pax
-def get_forward_linkings():
+def get_forward_needed():
+ """
+ Return forward_needed dictionary which has structure
+
+ { full_path_to_ELF_object : [ soname1, soname2, ... ], ... }
+
+ Here the sonames were obtained from the ELF object by readelf -d
+ """
+
var_db_pkg = '/var/db/pkg'
- forward_linkings = {}
+ forward_needed = {}
for cat in os.listdir(var_db_pkg):
catdir = '%s/%s' % (var_db_pkg, cat)
for pkg in os.listdir(catdir):
@@ -30,18 +39,27 @@ def get_forward_linkings():
link = re.split(';', line)
elf = link[1]
sonames = re.split(',', link[4])
- forward_linkings[elf] = sonames
+ forward_needed[elf] = sonames
except IOError:
continue #File probably doesn't exist, which is okay
- return forward_linkings
+ return forward_needed
+
+
+def get_library():
+ """
+ Return library2soname dictionary which has structure
+ { full_path_to_library : soname, ... }
-def get_library_mappings():
+ and its inverse which has structure
+
+ { soname : full_path_to_library, ... }
+ """
var_db_pkg = '/var/db/pkg'
- library2soname_mappings = {}
- soname2library_mappings = {}
+ library2soname = {}
+ soname2library = {}
for cat in os.listdir(var_db_pkg):
catdir = '%s/%s' % (var_db_pkg, cat)
@@ -56,19 +74,56 @@ def get_library_mappings():
link = re.split(';', line)
elf = link[1]
soname = link[2]
- if soname:
- library2soname_mappings[elf] = soname
- soname2library_mappings[soname] = elf
+ if soname: #no soname => executable
+ library2soname[elf] = soname
+ soname2library[soname] = elf
except IOError:
continue #File probably doesn't exist, which is okay
- return ( library2soname_mappings, soname2library_mappings )
+ return ( library2soname, soname2library )
+
+
+def get_soname2soname_linkings( forward_needed, library2soname ):
+ """
+ Return get_soname2soname_linkings dictionary which has structure:
+
+ { soname : [ soname1, soname2, ... ], .... }
+
+ """
+
+ soname2soname_linkings = {}
+
+ for elf in forward_needed:
+ try:
+ soname = library2soname[elf]
+ soname2soname_linkings[soname] = forward_needed[elf]
+ except KeyError:
+ continue #It doesn't have an soname and prabably isn't a library
+
+ return soname2soname_linkings
+
def main():
- forward_linkings = get_forward_linkings()
- ( library2soname_mappings, soname2library_mappings ) = get_library_mappings()
- for elf in forward_linkings:
+ # 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)
+
+ forward_needed = get_forward_needed()
+ ( library2soname, soname2library ) = get_library()
+
+ soname2soname_linkings = get_soname2soname_linkings( forward_needed, library2soname )
+
+ for soname in soname2soname_linkings:
+ print("%s" % soname)
+ for s in soname2soname_linkings[soname]:
+ print("\t%s" % s )
+ print('')
+
+ """ Print out all ELF objects and their PaX flags
+ for elf in forward_needed:
try:
flags = pax.getflags(elf)[0]
if flags:
@@ -76,26 +131,28 @@ def main():
else:
print("NONE: %s" % elf)
except pax.error:
- print("BUSY: %s" % elf)
+ print("CANT: %s" % elf)
"""
- for soname in sorted(soname2library_mappings):
- elf = soname2library_mappings[soname]
+
+ """ Print out all sonames and their library paths
+ for soname in sorted(soname2library):
+ elf = soname2library[soname]
print("%s : %s" % ( soname, elf ))
- """
"""
- for elf in forward_linkings:
- sonames = forward_linkings[elf]
+
+ """ Print out all ELF objects and the NEEDED sonames and full library paths
+ for elf in forward_needed:
+ sonames = forward_needed[elf]
print("%s" % elf)
- for soname in sorted(forward_linkings[elf]):
+ for soname in sorted(forward_needed[elf]):
try:
- print("\t%s\t=> %s" % (soname, soname2library_mappings[soname]))
- except KeyError as e:
+ print("\t%s\t=> %s" % (soname, soname2library[soname]))
+ except KeyError:
print("\t%s\t=> ****" % soname)
print("\n\n")
"""
-
if __name__ == '__main__':
main()
^ permalink raw reply related [flat|nested] 30+ messages in thread
* [gentoo-commits] proj/elfix:master commit in: misc/
@ 2012-12-19 3:52 Anthony G. Basile
0 siblings, 0 replies; 30+ messages in thread
From: Anthony G. Basile @ 2012-12-19 3:52 UTC (permalink / raw
To: gentoo-commits
commit: 97996a2b35ad069f17d640fadcfe56b149da1d6c
Author: Anthony G. Basile <blueness <AT> gentoo <DOT> org>
AuthorDate: Wed Dec 19 03:51:58 2012 +0000
Commit: Anthony G. Basile <blueness <AT> gentoo <DOT> org>
CommitDate: Wed Dec 19 03:51:58 2012 +0000
URL: http://git.overlays.gentoo.org/gitweb/?p=proj/elfix.git;a=commit;h=97996a2b
misc/alt-revdep-pax: alternative approache to ELF exec <-> library mappings
---
misc/alt-revdep-pax | 101 +++++++++++++++++++++++++++++++++++++++++++++++++++
1 files changed, 101 insertions(+), 0 deletions(-)
diff --git a/misc/alt-revdep-pax b/misc/alt-revdep-pax
new file mode 100755
index 0000000..a9445a1
--- /dev/null
+++ b/misc/alt-revdep-pax
@@ -0,0 +1,101 @@
+#!/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 re
+import pax
+
+def get_forward_linkings():
+ var_db_pkg = '/var/db/pkg'
+
+ forward_linkings = {}
+ for cat in os.listdir(var_db_pkg):
+ catdir = '%s/%s' % (var_db_pkg, cat)
+ for pkg in os.listdir(catdir):
+ pkgdir = '%s/%s' % (catdir, pkg)
+ need = '%s/%s' % (pkgdir, 'NEEDED.ELF.2')
+ try:
+ g = open(need, 'r')
+ needs = g.readlines()
+ for line in needs:
+ line = line.strip()
+ link = re.split(';', line)
+ elf = link[1]
+ sonames = re.split(',', link[4])
+ forward_linkings[elf] = sonames
+ except IOError:
+ continue #File probably doesn't exist, which is okay
+
+ return forward_linkings
+
+
+def get_library_mappings():
+ var_db_pkg = '/var/db/pkg'
+
+ library2soname_mappings = {}
+ soname2library_mappings = {}
+
+ for cat in os.listdir(var_db_pkg):
+ catdir = '%s/%s' % (var_db_pkg, cat)
+ for pkg in os.listdir(catdir):
+ pkgdir = '%s/%s' % (catdir, pkg)
+ need = '%s/%s' % (pkgdir, 'NEEDED.ELF.2')
+ try:
+ g = open(need, 'r')
+ needs = g.readlines()
+ for line in needs:
+ line = line.strip()
+ link = re.split(';', line)
+ elf = link[1]
+ soname = link[2]
+ if soname:
+ library2soname_mappings[elf] = soname
+ soname2library_mappings[soname] = elf
+ except IOError:
+ continue #File probably doesn't exist, which is okay
+
+ return ( library2soname_mappings, soname2library_mappings )
+
+def main():
+ forward_linkings = get_forward_linkings()
+ ( library2soname_mappings, soname2library_mappings ) = get_library_mappings()
+
+ for elf in forward_linkings:
+ try:
+ flags = pax.getflags(elf)[0]
+ if flags:
+ print("%s %s" % (flags, elf))
+ else:
+ print("NONE: %s" % elf)
+ except pax.error:
+ print("BUSY: %s" % elf)
+
+ """
+ for soname in sorted(soname2library_mappings):
+ elf = soname2library_mappings[soname]
+ print("%s : %s" % ( soname, elf ))
+ """
+
+ """
+ for elf in forward_linkings:
+ sonames = forward_linkings[elf]
+ print("%s" % elf)
+ for soname in sorted(forward_linkings[elf]):
+ try:
+ print("\t%s\t=> %s" % (soname, soname2library_mappings[soname]))
+ except KeyError as e:
+ print("\t%s\t=> ****" % soname)
+ print("\n\n")
+ """
+
+
+if __name__ == '__main__':
+ main()
^ permalink raw reply related [flat|nested] 30+ messages in thread
* [gentoo-commits] proj/elfix:master commit in: misc/
@ 2011-07-08 1:32 Anthony G. Basile
0 siblings, 0 replies; 30+ messages in thread
From: Anthony G. Basile @ 2011-07-08 1:32 UTC (permalink / raw
To: gentoo-commits
commit: f0351e512de6fbac32d4f04fcbaf2607910b7604
Author: Anthony G. Basile <blueness <AT> gentoo <DOT> org>
AuthorDate: Fri Jul 8 01:32:45 2011 +0000
Commit: Anthony G. Basile <blueness <AT> gentoo <DOT> org>
CommitDate: Fri Jul 8 01:32:45 2011 +0000
URL: http://git.overlays.gentoo.org/gitweb/?p=proj/elfix.git;a=commit;h=f0351e51
misc/*.c: fixed cycling over section data
---
misc/Makefile | 2 +-
misc/clear-dt-path.c | 21 ++++++++++++---------
misc/parse-elf.c | 7 +++++--
misc/print-sections.c | 28 ++++++++++++++++------------
4 files changed, 34 insertions(+), 24 deletions(-)
diff --git a/misc/Makefile b/misc/Makefile
index 0434bb6..8918c54 100644
--- a/misc/Makefile
+++ b/misc/Makefile
@@ -4,4 +4,4 @@ all: clear-dt-path parse-elf print-sections
gcc -o $@ $^ -lelf
clean:
- rm -rf parse-elf print-sections
+ rm -rf clear-dt-path parse-elf print-sections
diff --git a/misc/clear-dt-path.c b/misc/clear-dt-path.c
index ca0117d..ae5ff9a 100644
--- a/misc/clear-dt-path.c
+++ b/misc/clear-dt-path.c
@@ -48,21 +48,24 @@ int main( int argc, char *argv[])
while((scn = elf_nextscn(elf, scn)) != NULL)
{
gelf_getshdr(scn, &shdr);
- data = elf_getdata(scn, NULL);
if(shdr.sh_type != SHT_DYNAMIC)
continue;
printf("Section name: %s\n", elf_strptr(elf, ehdr.e_shstrndx, shdr.sh_name));
- if(data != NULL)
- for( i=0; gelf_getdyn(data, i, &dyn) != NULL; i++)
- {
- if(dyn.d_tag == DT_RPATH)
- printf("DT_RPATH found\n");
- if(dyn.d_tag == DT_RUNPATH)
- printf("DT_RUNPATH found\n");
- }
+ data = NULL;
+ while((data = elf_getdata(scn, data)) != NULL)
+ {
+ if(data != NULL)
+ for( i=0; gelf_getdyn(data, i, &dyn) != NULL; i++)
+ {
+ if(dyn.d_tag == DT_RPATH)
+ printf("DT_RPATH found\n");
+ if(dyn.d_tag == DT_RUNPATH)
+ printf("DT_RUNPATH found\n");
+ }
+ }
}
}
diff --git a/misc/parse-elf.c b/misc/parse-elf.c
index c18d277..1ba8024 100644
--- a/misc/parse-elf.c
+++ b/misc/parse-elf.c
@@ -206,7 +206,11 @@ int main( int argc, char *argv[])
shdr.sh_entsize
);
- if((data = elf_getdata(scn, data)) != NULL)
+ if(shdr.sh_type == SHT_NOBITS)
+ continue;
+
+ data = NULL;
+ while((data = elf_getdata(scn, data)) != NULL)
{
printf("\n ***** DATA ***** \n");
printf( "Data:\t\t%s\nType:\t\t%d\nSize:\t\t%lu\n"
@@ -220,7 +224,6 @@ int main( int argc, char *argv[])
);
}
printf("\n\n");
-
}
diff --git a/misc/print-sections.c b/misc/print-sections.c
index 1209077..ba8d4ee 100644
--- a/misc/print-sections.c
+++ b/misc/print-sections.c
@@ -1,21 +1,22 @@
-#include <stdio.h> // printf
-#include <stdlib.h> // EXIT_FAILURE
-#include <error.h> // error
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <error.h>
-#include <gelf.h> // elf_* and gelf_*
+#include <gelf.h>
-#include <sys/types.h> // open
+#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
-#include <unistd.h> // close
+#include <unistd.h>
int main( int argc, char *argv[])
{
int fd, cmd;
size_t i;
- char *p;
+ char shname[1024];
Elf *arf, *elf;
GElf_Ehdr ehdr;
@@ -47,16 +48,20 @@ int main( int argc, char *argv[])
while((scn = elf_nextscn(elf, scn)) != NULL)
{
gelf_getshdr(scn, &shdr);
- printf("Section name: %s\n", elf_strptr(elf, ehdr.e_shstrndx, shdr.sh_name));
- if( elf_getdata(scn, NULL) == NULL)
- printf("no data\n");
+ strcpy(shname, elf_strptr(elf, ehdr.e_shstrndx, shdr.sh_name));
+ printf("%s\n", shname);
/*
+ if( !strcmp(shname, ".bss") || !strcmp(shname, ".tbss") )
+ continue;
+ */
+ if(shdr.sh_type == SHT_NOBITS)
+ continue;
+
data = NULL;
while((data = elf_getdata(scn, data)) != NULL)
{
- printf("%2x\n", data);
printf( "Type:\t\t%d\nSize:\t\t%lu\n"
"Off:\t\t%lu\nAlign:\t\t%lu\nVersion:\t%u\n",
data->d_type,
@@ -75,7 +80,6 @@ int main( int argc, char *argv[])
}
printf("\n\n");
- */
}
}
^ permalink raw reply related [flat|nested] 30+ messages in thread
end of thread, other threads:[~2016-02-13 21:38 UTC | newest]
Thread overview: 30+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2012-12-23 1:02 [gentoo-commits] proj/elfix:master commit in: misc/ Anthony G. Basile
-- strict thread matches above, loose matches on Subject: below --
2016-02-13 21:38 Anthony G. Basile
2014-02-13 19:07 Anthony G. Basile
2013-05-21 15:21 Anthony G. Basile
2013-02-09 21:50 Anthony G. Basile
2012-12-27 3:11 Anthony G. Basile
2012-12-26 21:43 Anthony G. Basile
2012-12-26 21:23 Anthony G. Basile
2012-12-26 3:42 Anthony G. Basile
2012-12-25 14:22 Anthony G. Basile
2012-12-24 23:26 Anthony G. Basile
2012-12-24 21:44 Anthony G. Basile
2012-12-24 21:08 Anthony G. Basile
2012-12-24 2:18 Anthony G. Basile
2012-12-24 1:54 Anthony G. Basile
2012-12-23 11:51 Anthony G. Basile
2012-12-23 4:53 Anthony G. Basile
2012-12-23 3:49 Anthony G. Basile
2012-12-23 3:49 Anthony G. Basile
2012-12-23 3:49 Anthony G. Basile
2012-12-23 3:47 Anthony G. Basile
2012-12-23 2:36 Anthony G. Basile
2012-12-23 2:36 Anthony G. Basile
2012-12-23 2:34 Anthony G. Basile
2012-12-22 14:44 Anthony G. Basile
2012-12-22 4:21 Anthony G. Basile
2012-12-22 3:58 Anthony G. Basile
2012-12-22 1:06 Anthony G. Basile
2012-12-19 3:52 Anthony G. Basile
2011-07-08 1:32 Anthony G. Basile
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox