socsvn commit: r222846 -
soc2011/gk/ino64-head/tools/tools/shlib-compat
gk at FreeBSD.org
gk at FreeBSD.org
Sun Jun 5 16:22:14 UTC 2011
Author: gk
Date: Sun Jun 5 16:22:12 2011
New Revision: 222846
URL: http://svnweb.FreeBSD.org/socsvn/?view=rev&rev=222846
Log:
shlib-compat: add --alias-prefix option
Merge rev 80347e403bf6ed616a8d
Modified:
soc2011/gk/ino64-head/tools/tools/shlib-compat/shlib-compat
Modified: soc2011/gk/ino64-head/tools/tools/shlib-compat/shlib-compat
==============================================================================
--- soc2011/gk/ino64-head/tools/tools/shlib-compat/shlib-compat Sun Jun 5 16:22:01 2011 (r222845)
+++ soc2011/gk/ino64-head/tools/tools/shlib-compat/shlib-compat Sun Jun 5 16:22:12 2011 (r222846)
@@ -34,8 +34,10 @@
# controlled by user
verbose = 0
dump = False
+ no_dump = False
version_filter = None
symbol_filter = None
+ alias_prefix = None
# misc opts
objdump = 'objdump'
dwarfdump = 'dwarfdump'
@@ -58,6 +60,9 @@
cls.version_filter = StrFilter()
cls.symbol_filter = StrFilter()
+class App(object):
+ result_code = 0
+
# {{{ misc
class StrFilter(object):
@@ -187,6 +192,17 @@
def __repr__(self):
return "CommonSymbol(%s, %s)" % (self.name, self.version)
+class SymbolAlias(object):
+ def __init__(self, alias, offset):
+ assert alias.startswith(Config.alias_prefix)
+ self.alias = alias
+ self.name = alias[len(Config.alias_prefix):]
+ self.offset = offset
+
+ def __repr__(self):
+ return "SymbolAlias(%s, 0x%x)" % (self.alias, self.offset)
+
+
class VersionMap(object):
def __init__(self, name):
self.name = name
@@ -252,8 +268,9 @@
if ind != 0:
Dwarf.cmpcache.put(ind, r)
else:
- raise RuntimeError('Comparing different classes: %s, %s' %
- (a.__class__.__name__, b.__class__.__name__))
+ r = 0
+ #raise RuntimeError('Comparing different classes: %s, %s' %
+ # (a.__class__.__name__, b.__class__.__name__))
return r
def __repr__(self):
@@ -569,6 +586,7 @@
def __init__(self, libfile):
self.libfile = libfile
self.versions = {}
+ self.alias_syms = {}
def parse_objdump(self):
objdump = ObjdumpParser(self.libfile)
@@ -585,16 +603,41 @@
if not self.versions.has_key(vername):
self.versions[vername] = VersionMap(vername)
self.versions[vername].append(sym)
+ if Config.alias_prefix:
+ self.local_offsetmap = objdump.local_offsetmap
+ for p in objdump.local_symbols:
+ if p['symbol'].startswith(Config.alias_prefix):
+ alias = SymbolAlias(p['symbol'], p['offset'])
+ if self.alias_syms.has_key(alias.name):
+ print >> sys.stderr, "WARN: Symbol alias is already defined: %s/%s" % \
+ (self.name, self.alias)
+ self.alias_syms[alias.name] = alias
def parse_dwarfdump(self):
dwarfdump = DwarfdumpParser(self.libfile)
+ def lookup(sym):
+ raw = None
+ try:
+ raw = dwarfdump.offsetmap[sym.offset]
+ except:
+ try:
+ localnames = self.local_offsetmap[sym.offset]
+ localnames.sort(key=lambda x: -len(x))
+ for localname in localnames:
+ if not self.alias_syms.has_key(localname):
+ continue
+ alias = self.alias_syms[localname]
+ raw = dwarfdump.offsetmap[alias.offset]
+ break
+ except:
+ pass
+ return raw
dwarfdump.run()
dwarf = Dwarf(dwarfdump)
for ver in self.versions.values():
for sym in ver.symbols.values():
- try:
- raw = dwarfdump.offsetmap[sym.offset]
- except:
+ raw = lookup(sym);
+ if not raw:
print >> sys.stderr, "WARN: Symbol %s (%s) not found at offset 0x%x" % \
(sym.name_ver, self.libfile, sym.offset)
continue
@@ -636,19 +679,25 @@
re_dynamic_symbol = re.compile('(?P<offset>[0-9a-fA-F]+)\s+(?P<bind>\w+)\s+(?P<type>\w+)\s+(?P<section>[^\s]+)\s+(?P<foffset>[0-9a-fA-F]+)\s*(?P<ver>[^\s]*)\s*(?P<symbol>[^\s]*)')
def __init__(self, libfile):
- Parser.__init__(self, "%s -wT %s" % (Config.objdump, libfile))
+ Parser.__init__(self, "%s -wtT %s" % (Config.objdump, libfile))
self.dynamic_symbols = []
self.local_symbols = []
+ self.local_offsetmap = {}
def parse_begin(self, line):
self.parse_header(line)
- def add_symbol(self, table, symbol):
+ def add_symbol(self, table, symbol, offsetmap = None):
offset = int(symbol['offset'], 16);
symbol['offset'] = offset
if (offset == 0):
return
table.append(symbol)
+ if offsetmap != None:
+ if not offsetmap.has_key(offset):
+ offsetmap[offset] = [symbol['symbol']]
+ else:
+ offsetmap[offset].append(symbol['symbol'])
def parse_header(self, line):
m = self.re_header.match(line)
@@ -670,10 +719,11 @@
return
m = self.re_local_symbol.match(line)
if (not m):
- raise ValueError("Invalid symbol definition: %s" % line)
+ return
+ #raise ValueError("Invalid symbol definition: %s" % line)
p = m.groupdict()
if (p['symbol'] and p['symbol'].find('@') == -1):
- self.add_symbol(self.local_symbols, p);
+ self.add_symbol(self.local_symbols, p, self.local_offsetmap);
def parse_dynamic(self, line):
if (self.parse_header(line)):
@@ -843,20 +893,29 @@
print 'Removed version: ', vername
print ' Removed symbols: ', \
names_ver_str(vername, origlib.versions[vername].names())
+ added = []
+ removed = []
for vername in verdiff.common:
origver = origlib.versions[vername]
newver = newlib.versions[vername]
namediff = ListDiff(origver.names(), newver.names())
- if namediff.added or namediff.removed:
- print 'Added symbols: ', \
- names_ver_str(vername, namediff.added)
- print 'Removed symbols: ', \
- names_ver_str(vername, namediff.removed)
+ if namediff.added:
+ added.append(names_ver_str(vername, namediff.added))
+ if namediff.removed:
+ removed.append(names_ver_str(vername, namediff.removed))
commonver = VersionMap(vername)
result.append(commonver)
for n in namediff.common:
sym = CommonSymbol(origver.symbols[n], newver.symbols[n])
commonver.append(sym)
+ if added:
+ print 'Added symbols:'
+ for i in added:
+ print ' ', i
+ if removed:
+ print 'Removed symbols:'
+ for i in removed:
+ print ' ', i
return result
def cmp_symbols(commonver):
@@ -866,14 +925,20 @@
for symname in names:
sym = ver.symbols[symname]
match = sym.origsym.definition == sym.newsym.definition
+ if not match:
+ App.result_code = 1
if Config.verbose >= 1 or not match:
print '%s: definitions %smatch' % \
(sym.origsym.name_ver, "" if match else "mis")
- if Config.dump and not match:
+ if Config.dump or (not match and not Config.no_dump):
for x in [(sym.origsym, Config.origfile),
(sym.newsym, Config.newfile)]:
xsym = x[0]
xout = x[1].out
+ if not xsym.definition:
+ print >> xout, '\n// Definition not found: %s %s' % \
+ (xsym.name_ver, xsym.lib.libfile)
+ continue
print >> xout, '\n// Definitions mismatch: %s %s' % \
(xsym.name_ver, xsym.lib.libfile)
pp = PrettyPrinter()
@@ -921,8 +986,12 @@
version="%prog " + Config.version)
parser.add_option('-v', '--verbose', action='count',
help="verbose mode, may be specified several times")
+ parser.add_option('--alias-prefix', action='store',
+ help="name prefix to try for symbol alias lookup", metavar="STR")
parser.add_option('--dump', action='store_true',
help="dump symbol definitions")
+ parser.add_option('--no-dump', action='store_true',
+ help="disable dump for mismatched symbols")
parser.add_option('--out-orig', action='store',
help="result output file for original library", metavar="ORIGFILE")
parser.add_option('--out-new', action='store',
@@ -940,11 +1009,17 @@
Config.origfile.init(opts.out_orig)
if opts.out_new:
Config.newfile.init(opts.out_new)
+ if opts.no_dump:
+ Config.dump = False
+ Config.no_dump = True
if opts.dump:
Config.dump = True
+ Config.no_dump = False
Config.verbose = 1
if opts.verbose:
Config.verbose = opts.verbose
+ if opts.alias_prefix:
+ Config.alias_prefix = opts.alias_prefix
for (k, v) in ({ '_sym': Config.symbol_filter,
'_ver': Config.version_filter }).items():
for a in [ 'exclude', 'include' ]:
@@ -969,3 +1044,4 @@
print Dwarf.cmpcache.stats.show('Cmp')
print DwarfdumpParser.tagcache_stats.show('Dwarf tag')
+ sys.exit(App.result_code)
More information about the svn-soc-all
mailing list