Bug 914253 patch 4 - Implement address adjustment for fix_linux_stack.py. No review.
authorL. David Baron <dbaron@dbaron.org>
Wed, 06 Aug 2014 15:52:48 -0700
changeset 198242 1acb2c5d135c15af1edb836c71a80fad8ee73866
parent 198241 0f99aee39def75b89cab5392bfbe8f6a2de2a300
child 198243 89a0fa83c6d737ba8624b82054fa0f706804cf93
push id27264
push usernigelbabu@gmail.com
push dateThu, 07 Aug 2014 03:31:37 +0000
treeherdermozilla-central@afcb3af79d09 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
bugs914253
milestone34.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 914253 patch 4 - Implement address adjustment for fix_linux_stack.py. No review.
tools/rb/fix_linux_stack.py
--- a/tools/rb/fix_linux_stack.py
+++ b/tools/rb/fix_linux_stack.py
@@ -164,26 +164,67 @@ def separate_debug_file_for(file):
             os.path.join(global_debug_dir, dirname.lstrip("/"), debuglink_name)
         ]
         for f in possible_files:
             if have_debug_file(f):
                 # FIXME: Check the CRC!
                 return f
     return None
 
+elf_type_re = re.compile("^\s*Type:\s+(\S+)")
+elf_text_section_re = re.compile("^\s*\[\s*\d+\]\s+\.text\s+\w+\s+(\w+)\s+(\w+)\s+")
+
+def address_adjustment_for(file):
+    """
+    Return the address adjustment to use for a file.
+
+    addr2line wants offsets relative to the base address for shared
+    libraries, but it wants addresses including the base address offset
+    for executables.  This returns the appropriate address adjustment to
+    add to an offset within file.  See bug 230336.
+    """
+    readelf = subprocess.Popen(['readelf', '-h', file],
+                               stdout=subprocess.PIPE)
+    elftype = None
+    for line in readelf.stdout.readlines():
+        m = elf_type_re.match(line)
+        if m:
+            elftype = m.groups()[0]
+            break
+    readelf.terminate()
+
+    if elftype != "EXEC":
+        # If we're not dealing with an executable, return 0.
+        return 0
+
+    adjustment = 0
+    readelf = subprocess.Popen(['readelf', '-S', file],
+                               stdout=subprocess.PIPE)
+    for line in readelf.stdout.readlines():
+        m = elf_text_section_re.match(line)
+        if m:
+            # Subtract the .text section's offset within the
+            # file from its base address.
+            adjustment = int(m.groups()[0], 16) - int(m.groups()[1], 16);
+            break
+    readelf.terminate()
+    return adjustment
+
 addr2lines = {}
 def addressToSymbol(file, address):
     converter = None
+    address_adjustment = None
     if not file in addr2lines:
         debug_file = separate_debug_file_for(file) or file
         converter = unbufferedLineConverter('/usr/bin/addr2line', ['-C', '-f', '-e', debug_file])
-        addr2lines[file] = converter
+        address_adjustment = address_adjustment_for(file)
+        addr2lines[file] = (converter, address_adjustment)
     else:
-        converter = addr2lines[file]
-    return converter.convert(address)
+        (converter, address_adjustment) = addr2lines[file]
+    return converter.convert(hex(int(address, 16) + address_adjustment))
 
 line_re = re.compile("^(.*) ?\[([^ ]*) \+(0x[0-9a-f]{1,8})\](.*)$")
 balance_tree_re = re.compile("^([ \|0-9-]*)")
 
 def fixSymbols(line):
     result = line_re.match(line)
     if result is not None:
         # before allows preservation of balance trees