xref: /third_party/python/Tools/scripts/nm2def.py (revision 7db96d56)
17db96d56Sopenharmony_ci#! /usr/bin/env python3
27db96d56Sopenharmony_ci"""nm2def.py
37db96d56Sopenharmony_ci
47db96d56Sopenharmony_ciHelpers to extract symbols from Unix libs and auto-generate
57db96d56Sopenharmony_ciWindows definition files from them. Depends on nm(1). Tested
67db96d56Sopenharmony_cion Linux and Solaris only (-p option to nm is for Solaris only).
77db96d56Sopenharmony_ci
87db96d56Sopenharmony_ciBy Marc-Andre Lemburg, Aug 1998.
97db96d56Sopenharmony_ci
107db96d56Sopenharmony_ciAdditional notes: the output of nm is supposed to look like this:
117db96d56Sopenharmony_ci
127db96d56Sopenharmony_ciacceler.o:
137db96d56Sopenharmony_ci000001fd T PyGrammar_AddAccelerators
147db96d56Sopenharmony_ci         U PyGrammar_FindDFA
157db96d56Sopenharmony_ci00000237 T PyGrammar_RemoveAccelerators
167db96d56Sopenharmony_ci         U _IO_stderr_
177db96d56Sopenharmony_ci         U exit
187db96d56Sopenharmony_ci         U fprintf
197db96d56Sopenharmony_ci         U free
207db96d56Sopenharmony_ci         U malloc
217db96d56Sopenharmony_ci         U printf
227db96d56Sopenharmony_ci
237db96d56Sopenharmony_cigrammar1.o:
247db96d56Sopenharmony_ci00000000 T PyGrammar_FindDFA
257db96d56Sopenharmony_ci00000034 T PyGrammar_LabelRepr
267db96d56Sopenharmony_ci         U _PyParser_TokenNames
277db96d56Sopenharmony_ci         U abort
287db96d56Sopenharmony_ci         U printf
297db96d56Sopenharmony_ci         U sprintf
307db96d56Sopenharmony_ci
317db96d56Sopenharmony_ci...
327db96d56Sopenharmony_ci
337db96d56Sopenharmony_ciEven if this isn't the default output of your nm, there is generally an
347db96d56Sopenharmony_cioption to produce this format (since it is the original v7 Unix format).
357db96d56Sopenharmony_ci
367db96d56Sopenharmony_ci"""
377db96d56Sopenharmony_ciimport os, sys
387db96d56Sopenharmony_ci
397db96d56Sopenharmony_ciPYTHONLIB = 'libpython%d.%d.a' % sys.version_info[:2]
407db96d56Sopenharmony_ciPC_PYTHONLIB = 'Python%d%d.dll' % sys.version_info[:2]
417db96d56Sopenharmony_ciNM = 'nm -p -g %s'                      # For Linux, use "nm -g %s"
427db96d56Sopenharmony_ci
437db96d56Sopenharmony_cidef symbols(lib=PYTHONLIB,types=('T','C','D')):
447db96d56Sopenharmony_ci
457db96d56Sopenharmony_ci    with os.popen(NM % lib) as pipe:
467db96d56Sopenharmony_ci        lines = pipe.readlines()
477db96d56Sopenharmony_ci    lines = [s.strip() for s in lines]
487db96d56Sopenharmony_ci    symbols = {}
497db96d56Sopenharmony_ci    for line in lines:
507db96d56Sopenharmony_ci        if len(line) == 0 or ':' in line:
517db96d56Sopenharmony_ci            continue
527db96d56Sopenharmony_ci        items = line.split()
537db96d56Sopenharmony_ci        if len(items) != 3:
547db96d56Sopenharmony_ci            continue
557db96d56Sopenharmony_ci        address, type, name = items
567db96d56Sopenharmony_ci        if type not in types:
577db96d56Sopenharmony_ci            continue
587db96d56Sopenharmony_ci        symbols[name] = address,type
597db96d56Sopenharmony_ci    return symbols
607db96d56Sopenharmony_ci
617db96d56Sopenharmony_cidef export_list(symbols):
627db96d56Sopenharmony_ci
637db96d56Sopenharmony_ci    data = []
647db96d56Sopenharmony_ci    code = []
657db96d56Sopenharmony_ci    for name,(addr,type) in symbols.items():
667db96d56Sopenharmony_ci        if type in ('C','D'):
677db96d56Sopenharmony_ci            data.append('\t'+name)
687db96d56Sopenharmony_ci        else:
697db96d56Sopenharmony_ci            code.append('\t'+name)
707db96d56Sopenharmony_ci    data.sort()
717db96d56Sopenharmony_ci    data.append('')
727db96d56Sopenharmony_ci    code.sort()
737db96d56Sopenharmony_ci    return ' DATA\n'.join(data)+'\n'+'\n'.join(code)
747db96d56Sopenharmony_ci
757db96d56Sopenharmony_ci# Definition file template
767db96d56Sopenharmony_ciDEF_TEMPLATE = """\
777db96d56Sopenharmony_ciEXPORTS
787db96d56Sopenharmony_ci%s
797db96d56Sopenharmony_ci"""
807db96d56Sopenharmony_ci
817db96d56Sopenharmony_ci# Special symbols that have to be included even though they don't
827db96d56Sopenharmony_ci# pass the filter
837db96d56Sopenharmony_ciSPECIALS = (
847db96d56Sopenharmony_ci    )
857db96d56Sopenharmony_ci
867db96d56Sopenharmony_cidef filter_Python(symbols,specials=SPECIALS):
877db96d56Sopenharmony_ci
887db96d56Sopenharmony_ci    for name in list(symbols.keys()):
897db96d56Sopenharmony_ci        if name[:2] == 'Py' or name[:3] == '_Py':
907db96d56Sopenharmony_ci            pass
917db96d56Sopenharmony_ci        elif name not in specials:
927db96d56Sopenharmony_ci            del symbols[name]
937db96d56Sopenharmony_ci
947db96d56Sopenharmony_cidef main():
957db96d56Sopenharmony_ci
967db96d56Sopenharmony_ci    s = symbols(PYTHONLIB)
977db96d56Sopenharmony_ci    filter_Python(s)
987db96d56Sopenharmony_ci    exports = export_list(s)
997db96d56Sopenharmony_ci    f = sys.stdout # open('PC/python_nt.def','w')
1007db96d56Sopenharmony_ci    f.write(DEF_TEMPLATE % (exports))
1017db96d56Sopenharmony_ci    # f.close()
1027db96d56Sopenharmony_ci
1037db96d56Sopenharmony_ciif __name__ == '__main__':
1047db96d56Sopenharmony_ci    main()
105