Skip site navigation (1)Skip section navigation (2)
Date:      Mon, 1 Dec 2014 08:14:26 +0000 (UTC)
From:      Gleb Kurtsou <gleb@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org
Subject:   svn commit: r275354 - in head/tools/tools/shlib-compat: . test
Message-ID:  <201412010814.sB18EQiF095072@svn.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: gleb
Date: Mon Dec  1 08:14:25 2014
New Revision: 275354
URL: https://svnweb.freebsd.org/changeset/base/275354

Log:
  Update tools/shlib-compat.
  
  - Update dwarfdump / compiler support.
    Use hex instead of decimal for integers.
    Add boolean and restrict type definitions.
    Add options for specifing dwarfdump and objdump executables.
  
  - Fix reporting missing symbol definitions as matching.
  
  - Compare external variable definitions.
  
  - Exclude special symbols like _init, _end by default.
  
  - Fix test build.

Modified:
  head/tools/tools/shlib-compat/shlib-compat.py
  head/tools/tools/shlib-compat/test/Makefile.inc
  head/tools/tools/shlib-compat/test/regress.sh

Modified: head/tools/tools/shlib-compat/shlib-compat.py
==============================================================================
--- head/tools/tools/shlib-compat/shlib-compat.py	Mon Dec  1 07:37:29 2014	(r275353)
+++ head/tools/tools/shlib-compat/shlib-compat.py	Mon Dec  1 08:14:25 2014	(r275354)
@@ -60,6 +60,14 @@ class Config(object):
     origfile = FileConfig()
     newfile = FileConfig()
 
+    exclude_sym_default = [
+            '^__bss_start$',
+            '^_edata$',
+            '^_end$',
+            '^_fini$',
+            '^_init$',
+            ]
+
     @classmethod
     def init(cls):
         cls.version_filter = StrFilter()
@@ -338,15 +346,17 @@ class BaseTypeDef(Def):
     def _pp(self, pp):
         if self.encoding in self.inttypes:
             sign = '' if self.encoding == 'DW_ATE_signed' else 'u'
-            bits = int(self.byte_size) * 8
+            bits = int(self.byte_size, 0) * 8
             return '%sint%s_t' % (sign, bits)
-        elif self.encoding == 'DW_ATE_signed_char' and int(self.byte_size) == 1:
+        elif self.encoding == 'DW_ATE_signed_char' and int(self.byte_size, 0) == 1:
             return 'char';
+        elif self.encoding == 'DW_ATE_boolean' and int(self.byte_size, 0) == 1:
+            return 'bool';
         elif self.encoding == 'DW_ATE_float':
-            return self._mapval(self.byte_size, {
-                '16': 'long double',
-                '8': 'double',
-                '4': 'float',
+            return self._mapval(int(self.byte_size, 0), {
+                16: 'long double',
+                8: 'double',
+                4: 'float',
             })
         raise NotImplementedError('Invalid encoding: %s' % self)
 
@@ -374,6 +384,11 @@ class VolatileTypeDef(AnonymousDef):
     def _pp(self, pp):
         return 'volatile ' + self.type._pp(pp)
 
+class RestrictTypeDef(AnonymousDef):
+    _is_alias = True
+    def _pp(self, pp):
+        return 'restrict ' + self.type._pp(pp)
+
 class ArrayDef(AnonymousDef):
     def _pp(self, pp):
         t = pp.run(self.type)
@@ -411,6 +426,11 @@ class ParameterDef(Def):
         t = pp.run(self.type)
         return "%s %s" % (t, self._name_opt())
 
+class VariableDef(Def):
+    def _pp(self, pp):
+        t = pp.run(self.type)
+        return "%s %s" % (t, self._name_opt())
+
 # TODO
 class StructForwardDef(Def):
     pass
@@ -485,6 +505,10 @@ class Dwarf(object):
         result = self._build_optarg_type(raw)
         return FunctionDef(raw.id, raw.name, params=params, result=result)
 
+    def build_variable(self, raw):
+        type = self._build_optarg_type(raw)
+        return VariableDef(raw.id, raw.optname, type=type)
+
     def build_subroutine_type(self, raw):
         params = [ self.build(x) for x in raw.nested ]
         result = self._build_optarg_type(raw)
@@ -547,6 +571,10 @@ class Dwarf(object):
         type = self._build_optarg_type(raw)
         return VolatileTypeDef(raw.id, type=type)
 
+    def build_restrict_type(self, raw):
+        type = self._build_optarg_type(raw)
+        return RestrictTypeDef(raw.id, type=type)
+
     def build_enumeration_type(self, raw):
         # TODO handle DW_TAG_enumerator ???
         return EnumerationTypeDef(raw.id, name=raw.optname,
@@ -574,7 +602,7 @@ class Dwarf(object):
             return int(id)
         except ValueError:
             if (id.startswith('<') and id.endswith('>')):
-                return int(id[1:-1])
+                return int(id[1:-1], 0)
             else:
                 raise ValueError("Invalid dwarf id: %s" % id)
 
@@ -782,7 +810,7 @@ class DwarfdumpParser(Parser):
     class Tag(object):
         def __init__(self, unit, data):
             self.unit = unit
-            self.id = int(data['id'])
+            self.id = int(data['id'], 0)
             self.level = int(data['level'])
             self.tag = data['tag']
             self.args = {}
@@ -816,7 +844,7 @@ class DwarfdumpParser(Parser):
         def __repr__(self):
             return "Tag(%d, %d, %s)" % (self.level, self.id, self.tag)
 
-    re_header = re.compile('<(?P<level>\d+)><(?P<id>\d+\+*\d*)><(?P<tag>\w+)>')
+    re_header = re.compile('<(?P<level>\d+)><(?P<id>[0xX0-9a-fA-F]+(?:\+(0[xX])?[0-9a-fA-F]+)?)><(?P<tag>\w+)>')
     re_argname = re.compile('(?P<arg>\w+)<')
     re_argunknown = re.compile('<Unknown AT value \w+><[^<>]+>')
 
@@ -827,6 +855,10 @@ class DwarfdumpParser(Parser):
         'DW_TAG_variable',
         ])
 
+    external_tags = set([
+        'DW_TAG_variable',
+        ])
+
     def __init__(self, libfile):
         Parser.__init__(self, "%s -di %s" % (Config.dwarfdump, libfile))
         self.current_unit = None
@@ -888,9 +920,19 @@ class DwarfdumpParser(Parser):
         while args:
             args = self.parse_arg(tag, args)
         tag.unit.tags[tag.id] = tag
-        if tag.args.has_key('DW_AT_low_pc') and \
-                tag.tag not in DwarfdumpParser.skip_tags:
-            offset = int(tag.args['DW_AT_low_pc'], 16)
+        def parse_offset(tag):
+            if tag.args.has_key('DW_AT_low_pc'):
+                return int(tag.args['DW_AT_low_pc'], 16)
+            elif tag.args.has_key('DW_AT_location'):
+                location = tag.args['DW_AT_location']
+                if location.startswith('DW_OP_addr'):
+                    return int(location.replace('DW_OP_addr', ''), 16)
+            return None
+        offset = parse_offset(tag)
+        if offset is not None and \
+                (tag.tag not in DwarfdumpParser.skip_tags or \
+                (tag.args.has_key('DW_AT_external') and \
+                tag.tag in DwarfdumpParser.external_tags)):
             if self.offsetmap.has_key(offset):
                 raise ValueError("Dwarf dump parse error: " +
                         "symbol is aleady defined at offset 0x%x" % offset)
@@ -963,10 +1005,15 @@ def cmp_symbols(commonver):
         names.sort()
         for symname in names:
             sym = ver.symbols[symname]
-            match = sym.origsym.definition == sym.newsym.definition
+            missing = sym.origsym.definition is None or sym.newsym.definition is None
+            match = not missing and sym.origsym.definition == sym.newsym.definition
             if not match:
                 App.result_code = 1
             if Config.verbose >= 1 or not match:
+                if missing:
+                    print '%s: missing definition' % \
+                            (sym.origsym.name_ver,)
+                    continue
                 print '%s: definitions %smatch' % \
                         (sym.origsym.name_ver, "" if match else "mis")
                 if Config.dump or (not match and not Config.no_dump):
@@ -1035,10 +1082,16 @@ if __name__ == '__main__':
             help="result output file for original library", metavar="ORIGFILE")
     parser.add_option('--out-new', action='store',
             help="result output file for new library", metavar="NEWFILE")
+    parser.add_option('--dwarfdump', action='store',
+            help="path to dwarfdump executable", metavar="DWARFDUMP")
+    parser.add_option('--objdump', action='store',
+            help="path to objdump executable", metavar="OBJDUMP")
     parser.add_option('--exclude-ver', action='append', metavar="RE")
     parser.add_option('--include-ver', action='append', metavar="RE")
     parser.add_option('--exclude-sym', action='append', metavar="RE")
     parser.add_option('--include-sym', action='append', metavar="RE")
+    parser.add_option('--no-exclude-sym-default', action='store_true',
+            help="don't exclude special symbols like _init, _end, __bss_start")
     for opt in ['alias', 'cached', 'symbol']:
         parser.add_option("--w-" + opt,
                 action="store_true", dest="w_" + opt)
@@ -1049,6 +1102,10 @@ if __name__ == '__main__':
     if len(args) != 2:
         parser.print_help()
         sys.exit(-1)
+    if opts.dwarfdump:
+        Config.dwarfdump = opts.dwarfdump
+    if opts.objdump:
+        Config.objdump = opts.objdump
     if opts.out_orig:
         Config.origfile.init(opts.out_orig)
     if opts.out_new:
@@ -1071,6 +1128,8 @@ if __name__ == '__main__':
             opt = getattr(opts, a + k)
             if opt:
                 getattr(v, a).extend(opt)
+    if not opts.no_exclude_sym_default:
+        Config.symbol_filter.exclude.extend(Config.exclude_sym_default)
     Config.version_filter.compile()
     Config.symbol_filter.compile()
     for w in ['w_alias', 'w_cached', 'w_symbol']:

Modified: head/tools/tools/shlib-compat/test/Makefile.inc
==============================================================================
--- head/tools/tools/shlib-compat/test/Makefile.inc	Mon Dec  1 07:37:29 2014	(r275353)
+++ head/tools/tools/shlib-compat/test/Makefile.inc	Mon Dec  1 08:14:25 2014	(r275354)
@@ -11,3 +11,5 @@ DEBUG_FLAGS?=	-g
 
 VERSION_DEF=	${.CURDIR}/../Versions.def
 SYMBOL_MAPS=	${.CURDIR}/Symbol.map
+
+MK_DEBUG_FILES=	yes

Modified: head/tools/tools/shlib-compat/test/regress.sh
==============================================================================
--- head/tools/tools/shlib-compat/test/regress.sh	Mon Dec  1 07:37:29 2014	(r275353)
+++ head/tools/tools/shlib-compat/test/regress.sh	Mon Dec  1 08:14:25 2014	(r275354)
@@ -1,7 +1,7 @@
 #!/bin/sh
 # $FreeBSD$
 
-run() { ../shlib-compat.py --no-dump -vv libtest$1/libtest$1.so.0.debug libtest$2/libtest$2.so.0.debug; }
+run() { ../shlib-compat.py --no-dump -vv libtest$1/libtest$1.so.0.full libtest$2/libtest$2.so.0.full; }
 echo 1..9
 REGRESSION_START($1)
 REGRESSION_TEST(`1-1', `run 1 1')



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201412010814.sB18EQiF095072>