[csw-devel] SF.net SVN: gar:[19264] csw/mgar/gar/v2-yann/lib/python/inspective_package. py

chninkel at users.sourceforge.net chninkel at users.sourceforge.net
Sat Sep 22 11:37:37 CEST 2012


Revision: 19264
          http://gar.svn.sourceforge.net/gar/?rev=19264&view=rev
Author:   chninkel
Date:     2012-09-22 09:37:37 +0000 (Sat, 22 Sep 2012)
Log Message:
-----------
separate function for shell + more simplification

Modified Paths:
--------------
    csw/mgar/gar/v2-yann/lib/python/inspective_package.py

Modified: csw/mgar/gar/v2-yann/lib/python/inspective_package.py
===================================================================
--- csw/mgar/gar/v2-yann/lib/python/inspective_package.py	2012-09-21 22:52:11 UTC (rev 19263)
+++ csw/mgar/gar/v2-yann/lib/python/inspective_package.py	2012-09-22 09:37:37 UTC (rev 19264)
@@ -69,7 +69,18 @@
             "Error in hachoir_parser processing %s: %r", file_path, e)
   return file_info
 
+def ShellCommand(args, env=None):
+      logging.debug("Running: %s", args)
+      proc = subprocess.Popen(args,
+                              stdout=subprocess.PIPE,
+                              stderr=subprocess.PIPE,
+                              env=env)
+      stdout, stderr = proc.communicate()
+      retcode = proc.wait()
 
+      return retcode, stdout, stderr
+
+
 class InspectivePackage(package.DirectoryFormatPackage):
   """Extends DirectoryFormatPackage to allow package inspection."""
 
@@ -176,11 +187,7 @@
         binary_in_tmp_dir = binary_in_tmp_dir.lstrip("/")
       binary_abs_path = os.path.join(self.directory, self.GetFilesDir(), binary_in_tmp_dir)
       binary_base_name = os.path.basename(binary_in_tmp_dir)
-      args = [common_constants.DUMP_BIN, "-Lv", binary_abs_path]
-      logging.debug("Running: %s", args)
-      dump_proc = subprocess.Popen(args, stdout=subprocess.PIPE, env=env)
-      stdout, stderr = dump_proc.communicate()
-      ret = dump_proc.wait()
+      retcode, stdout, stderr = ShellCommand([common_constants.DUMP_BIN, "-Lv", binary_abs_path], env)
       binary_data = ldd_emul.ParseDumpOutput(stdout)
       binary_data["path"] = binary
       if basedir:
@@ -230,7 +237,7 @@
     return defined_symbols
 
   def GetBinaryElfInfo(self):
-    """Returns various informations symbol and version present in elf header
+    """Returns various informations symbol and versions present in elf header
 
     To do this we parse output lines from elfdump -syv, it's the
     only command that will give us all informations we need on symbols and versions.
@@ -247,34 +254,38 @@
     for binary in binaries:
       binary_abspath = os.path.join(self.directory, "root", binary)
       # elfdump is the only tool that give us all informations
-      args = ["/usr/ccs/bin/elfdump", "-svy", binary_abspath]
-      elfdump_proc = subprocess.Popen(
-          args,
-          stdout=subprocess.PIPE,
-          stderr=subprocess.PIPE)
-      stdout, stderr = elfdump_proc.communicate()
-      retcode = elfdump_proc.wait()
+      retcode, stdout, stderr = ShellCommand(["/usr/ccs/bin/elfdump", "-svy", binary_abspath])
       if retcode or stderr:
-        logging.error("%s returned one or more errors: %s", args, stderr.splitlines()[0])
+        logging.error("%s returned one or more errors: %s", args, stderr)
         continue
       elfdump_out = stdout.splitlines()
 
       symbols = {}
       binary_info = {'version definition': [],
-                     'version needed': [],
-                     'symbol table': []}
-      # we will merge syminfo and symbol table information in one list
-      # so the syminfo list is the same as the symbol table one
-      binary_info['syminfo'] = binary_info['symbol table']
+                     'version needed': []}
 
       # The list of fields we want to retrieve in the elfdump output by section
-      # If the field is a tuple, it means we will map the original field name
-      # to another name in the final data structure
-      elf_fields = {'version definition': ['version', 'dependency'],
-                    'version needed': [('file', 'soname'), 'version'],
-                    'symbol table': [('name', 'symbol'), ('ver', 'version'),
-                                     'bind', 'shndx'],
-                    'syminfo': [('library', 'soname'), 'symbol', 'flags']}
+      # the key is the original field name and the value the destination field name
+      elf_fields = {'version definition': {
+                      'version': 'version',
+                      'dependency': 'dependancy',
+                      },
+                    'version needed': {
+                      'file': 'soname',
+                      'version': 'version',
+                      },
+                    'symbol table': {
+                      'name': 'symbol',
+                      'ver': 'version',
+                      'bind': 'bind',
+                      'shndx': 'shndx',
+                      },
+                    'syminfo': {
+                      'library': 'soname',
+                      'symbol': 'symbol',
+                      'flags': 'flags',
+                      }
+                    }
 
       cur_section = None
       for line in elfdump_out:
@@ -286,14 +297,11 @@
           continue
 
         elf_info = {}
-        for field in elf_fields[cur_section]:
-          if type(field) == tuple:
-            elf_info[field[1]] = elfdump_data[field[0]]
-          else:
-            elf_info[field] = elfdump_data[field]
+        for src_field, dest_field in elf_fields[cur_section].items():
+          elf_info[dest_field] = elfdump_data[src_field]
 
-        # we merge symbol table and syminfo informations so we have to check
-        # if the symbol has not already been added
+        # symbol table and syminfo section store various informations
+        # about the same symbols, we merge them in a dict
         if cur_section in ('symbol table', 'syminfo'):
           symbols.setdefault(elf_info['symbol'], {}).update(elf_info)
         else:
@@ -311,9 +319,10 @@
       if binary_info['version definition']:
         binary_info['version definition'].pop(0)
 
+      binary_info['symbol table'] = symbols.values()
       # To not rely of the section order output of elfdump, we resolve symbol version
       # informations here after having parsed all elfdump output
-      binary_info['symbol table'] = self._ResolveSymbolsVersionInfo (symbols.values(), binary_info)
+      self._ResolveSymbolsVersionInfo (binary_info)
 
       binaries_elf_info[binary] = binary_info
 
@@ -328,13 +337,7 @@
       # this could be potentially moved into the DirectoryFormatPackage class.
       # ldd needs the binary to be executable
       os.chmod(binary_abspath, 0755)
-      args = ["ldd", "-Ur", binary_abspath]
-      ldd_proc = subprocess.Popen(
-          args,
-          stdout=subprocess.PIPE,
-          stderr=subprocess.PIPE)
-      stdout, stderr = ldd_proc.communicate()
-      retcode = ldd_proc.wait()
+      retcode, stdout, stderr = ShellCommand(["ldd", "-Ur", binary_abspath])
       if retcode:
         uname_info = os.uname()
         if (uname_info[2] == '5.9' and uname_info[4] == 'i86pc' and
@@ -345,7 +348,7 @@
           # that the ldd infos will be the same on the 32 bits binaries analyzed
           return {}
         else:
-          logging.error("%s returned an error: %s", args, stderr)
+          logging.error("%s returned an error: %s", args, stderr.splitlines()[0].splitlines()[0])
 
       ldd_info = []
       for line in stdout.splitlines():
@@ -365,23 +368,25 @@
     sym = { 'address': fields[0], 'type': fields[1], 'name': fields[2] }
     return sym
 
-  def _ResolveSymbolsVersionInfo(self, symbols, binary_info):
+  def _ResolveSymbolsVersionInfo(self, binary_info):
 
     version_info = binary_info['version definition'] + binary_info['version needed']
 
-    for sym_info in symbols:
+    for sym_info in binary_info['symbol table']:
+      # version index is an 1-based index on the version information table
+      # from which we also removed the first entry which was the
+      # base library/binary itself
       version_index = int(sym_info['version']) - 2
-      if version_index > 1:
+      if version_index >= 0:
         version = version_info[version_index]
         sym_info['version'] = version['version']
         sym_info['soname'] = version['soname']
 
-      # we make sure the field are present even if the syminfo section is not
+      # we make sure these fields are present even if the syminfo section is not
       sym_info.setdefault('version')
       sym_info.setdefault('soname')
       sym_info.setdefault('flags')
 
-    return symbols
 
   def _ParseElfdumpLine(self, line, section=None):
 

This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.



More information about the devel mailing list