• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1#! /usr/bin/env python3
2"""nm2def.py
3
4Helpers to extract symbols from Unix libs and auto-generate
5Windows definition files from them. Depends on nm(1). Tested
6on Linux and Solaris only (-p option to nm is for Solaris only).
7
8By Marc-Andre Lemburg, Aug 1998.
9
10Additional notes: the output of nm is supposed to look like this:
11
12acceler.o:
13000001fd T PyGrammar_AddAccelerators
14         U PyGrammar_FindDFA
1500000237 T PyGrammar_RemoveAccelerators
16         U _IO_stderr_
17         U exit
18         U fprintf
19         U free
20         U malloc
21         U printf
22
23grammar1.o:
2400000000 T PyGrammar_FindDFA
2500000034 T PyGrammar_LabelRepr
26         U _PyParser_TokenNames
27         U abort
28         U printf
29         U sprintf
30
31...
32
33Even if this isn't the default output of your nm, there is generally an
34option to produce this format (since it is the original v7 Unix format).
35
36"""
37import os, sys
38
39PYTHONLIB = 'libpython%d.%d.a' % sys.version_info[:2]
40PC_PYTHONLIB = 'Python%d%d.dll' % sys.version_info[:2]
41NM = 'nm -p -g %s'                      # For Linux, use "nm -g %s"
42
43def symbols(lib=PYTHONLIB,types=('T','C','D')):
44
45    with os.popen(NM % lib) as pipe:
46        lines = pipe.readlines()
47    lines = [s.strip() for s in lines]
48    symbols = {}
49    for line in lines:
50        if len(line) == 0 or ':' in line:
51            continue
52        items = line.split()
53        if len(items) != 3:
54            continue
55        address, type, name = items
56        if type not in types:
57            continue
58        symbols[name] = address,type
59    return symbols
60
61def export_list(symbols):
62
63    data = []
64    code = []
65    for name,(addr,type) in symbols.items():
66        if type in ('C','D'):
67            data.append('\t'+name)
68        else:
69            code.append('\t'+name)
70    data.sort()
71    data.append('')
72    code.sort()
73    return ' DATA\n'.join(data)+'\n'+'\n'.join(code)
74
75# Definition file template
76DEF_TEMPLATE = """\
77EXPORTS
78%s
79"""
80
81# Special symbols that have to be included even though they don't
82# pass the filter
83SPECIALS = (
84    )
85
86def filter_Python(symbols,specials=SPECIALS):
87
88    for name in list(symbols.keys()):
89        if name[:2] == 'Py' or name[:3] == '_Py':
90            pass
91        elif name not in specials:
92            del symbols[name]
93
94def main():
95
96    s = symbols(PYTHONLIB)
97    filter_Python(s)
98    exports = export_list(s)
99    f = sys.stdout # open('PC/python_nt.def','w')
100    f.write(DEF_TEMPLATE % (exports))
101    # f.close()
102
103if __name__ == '__main__':
104    main()
105