-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathdefs
executable file
·103 lines (94 loc) · 3.23 KB
/
defs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
#!/usr/bin/env python
from __future__ import print_function
import os
import subprocess
import sys
if sys.version_info[0] == 2:
subp_ascii = {}
else:
subp_ascii = dict(encoding='ascii')
def main():
import argparse
ap = argparse.ArgumentParser()
ap.add_argument('-d','--with-data', action='store_true',
help='Show data symbols in addition to functions')
ap.add_argument('binfile',
help='Executable or object file')
args = ap.parse_args()
un = os.path.basename(ap.prog).startswith('un')
#
binfile = args.binfile
try:
if not os.path.isfile(binfile):
if os.path.sep not in binfile:
full = ffip(binfile)
if full is None:
raise ValueError('%s not found in PATH' % binfile)
binfile = full
else:
raise ValueError('%s: No such file or directory' % binfile)
with open(binfile, 'rb') as f:
magic = f.read(32)
if magic[:4] == b'\x7FELF':
symdefs = elf_defs(un, binfile,
with_data=args.with_data)
elif magic[2:4] == b'\x01\x07':
# big-endian executable
if magic[1:2] in (b'\x01', b'\x02'):
# mc68010 or mc68020
symdefs = m68k_defs(un, binfile,
with_data=args.with_data)
else:
raise ValueError('%s: Unknown file type' % binfile)
for sym in sorted(set(symdefs)):
print(sym)
except Exception as e:
raise
import sys
print('%s: %s' % (ap.prog, e))
sys.exit(1)
def elf_defs(un, binfile, with_data=False):
for line in iter_output(['readelf','--symbols','--wide',binfile]):
fields = line.split(None, 7)
if len(fields) < 8:
continue
if fields[0].endswith(':') and fields[0][:-1].isdigit():
#print(fields)
_, _, _, type, bind, _, ndx, syminfo = fields[:8]
sym, _, scope = syminfo.partition('@')
if un:
if ndx == 'UND':
yield sym
else:
if ndx != 'UND':
if with_data or type == 'FUNC':
yield sym
def m68k_defs(un, binfile, with_data=False):
return _nm_defs('nm68k', un, binfile, with_data=with_data)
def _nm_defs(nm, un, binfile, with_data=False):
"""Extract symbols using 'nm' or a variant thereof"""
if not ffip(nm):
raise RuntimeError('No %s found in PATH' % nm)
if un:
tmatch = set('U')
else:
tmatch = set('T')
if with_data:
tmatch.add('D')
for line in iter_output([nm,'-p',binfile]):
xaddr, t, sym = ('x'+line).split(None, 2)
if t in tmatch:
yield sym
def iter_output(cmd):
p = subprocess.Popen(cmd, stdout=subprocess.PIPE, **subp_ascii)
for line in p.stdout:
yield line.rstrip('\n')
p.wait()
def ffip(name):
"""Find named file in PATH"""
for dir in os.environ.get('PATH','/bin:/usr/bin').split(os.pathsep):
fullname = os.path.join(dir, name)
if os.path.isfile(fullname):
return fullname
return None
main()