Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(192)

Side by Side Diff: third_party/android_platform/development/scripts/stack_libs.py

Issue 1412223008: stack: Adjust Pre-M Android incorrect debuggerd addresses. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Fix options ordering issue, tidy printed file paths. Created 5 years, 2 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
(Empty)
1 #!/usr/bin/env python
2 #
3 # Copyright (C) 2015 The Android Open Source Project
rmcilroy 2015/10/23 16:25:10 Was this taken straight from the Android project w
simonb (inactive) 2015/10/26 12:38:31 No, the file is brand new and only in here. Local
rmcilroy 2015/10/26 16:42:17 Acknowledged.
4 #
5 # Licensed under the Apache License, Version 2.0 (the "License");
6 # you may not use this file except in compliance with the License.
7 # You may obtain a copy of the License at
8 #
9 # http://www.apache.org/licenses/LICENSE-2.0
10 #
11 # Unless required by applicable law or agreed to in writing, software
12 # distributed under the License is distributed on an "AS IS" BASIS,
13 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 # See the License for the specific language governing permissions and
15 # limitations under the License.
16
17 """Identifies address adjustments required for native crash dumps."""
18
19 import glob
20 import os.path
21 import subprocess
22
23
24 def _HasElfHeader(path):
25 """Return True if the file at the given path has an ELF magic header.
26
27 Minimal check only, for 'ELF' in bytes 1 to 3 of the file. Filters out
28 the zero-byte false-positives such as libchromeview.so returned by glob.
29
30 Args:
31 path: Path to file to check.
32 Returns:
33 True or False
34 """
35 with open(path) as stream:
36 elf_header = stream.read(4)
37 return len(elf_header) == 4 and elf_header[1:4] == 'ELF'
38
39
40 def _ReadElfProgramHeaders(lib):
41 """Return an iterable of program headers, from 'readelf -l ...'.
42
43 Uses the platform readelf in all cases. This is somewhat lazy, but suffices
44 in practice because program headers in ELF files are architecture-agnostic.
45
46 Args:
47 lib: Library file to read.
48 Returns:
49 [readelf -l output line, ...]
50 """
51 string = subprocess.check_output(['readelf', '-l', lib])
52 return string.split('\n')
53
54
55 def _FindMinLoadVaddr(lib):
56 """Return the minimum VirtAddr field of all library LOAD segments.
57
58 Args:
59 lib: Library file to read.
60 Returns:
61 Min VirtAddr field for all LOAD segments, or 0 if none found.
62 """
63 vaddrs = []
64 # Locate LOAD lines and find the smallest VirtAddr field, eg:
65 # Type Offset VirtAddr PhysAddr FileSiz MemSiz Flg Align
66 # LOAD 0x000000 0x001d6000 0x001d6000 0x20f63fc 0x20f63fc R E 0x1000
67 # LOAD 0x20f6970 0x022cd970 0x022cd970 0x182df8 0x1b4490 RW 0x1000
68 # would return 0x1d6000. Ignores all non-LOAD lines.
69 for line in _ReadElfProgramHeaders(lib):
70 elements = line.split()
71 if elements and elements[0] == 'LOAD':
72 vaddrs.append(int(elements[2], 16))
73 if vaddrs:
74 return min(vaddrs)
75 return 0
76
77
78 def GetLoadVaddrs(apk_dir):
79 """Return a dictionary of minimum VirtAddr fields for libraries in apk_dir.
80
81 The dictionary returned may be passed to stack_core.ConvertTrace(). In
82 pre-M Android releases the addresses printed by debuggerd into tombstones
83 do not take account of non-zero vaddrs. Here we collect this information,
84 so that we can use it later to correct such debuggerd tombstones.
85
86 Args:
87 apk_dir: Path to APK staging directory.
88 Returns:
89 {'libchrome.so': 12345, ...}
90 """
91 pathname = apk_dir + '/libs/*/*.so'
92 libs = [lib for lib in glob.glob(pathname) if _HasElfHeader(lib)]
93
94 load_vaddrs = {}
95 for lib in libs:
96 min_vaddr = _FindMinLoadVaddr(lib)
97 if min_vaddr:
98 # Store with the library basename as the key. This is because once on
99 # the device its path may not fully match its place in the APK staging
100 # directory
101 load_vaddrs[os.path.basename(lib)] = min_vaddr
102
103 # Direct load from APK causes debuggerd to tag trace lines as if from the
104 # file .../base.apk. So if we encounter a libchrome.so with packed
105 # relocations, replicate this as base.apk so that later adjustment code
106 # finds the appropriate adjustment.
107 if 'libchrome.so' in load_vaddrs:
108 load_vaddrs['base.apk'] = load_vaddrs['libchrome.so']
109
110 return load_vaddrs
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698