xref: /openbmc/qemu/scripts/undefsym.py (revision 9a2ea4f4)
1604f3e4eSYonggang Luo#!/usr/bin/env python3
2604f3e4eSYonggang Luo
3604f3e4eSYonggang Luo# Before a shared module's DSO is produced, a static library is built for it
4604f3e4eSYonggang Luo# and passed to this script.  The script generates -Wl,-u options to force
5604f3e4eSYonggang Luo# the inclusion of symbol from libqemuutil.a if the shared modules need them,
6604f3e4eSYonggang Luo# This is necessary because the modules may use functions not needed by the
7604f3e4eSYonggang Luo# executable itself, which would cause the function to not be linked in.
8604f3e4eSYonggang Luo# Then the DSO loading would fail because of the missing symbol.
9604f3e4eSYonggang Luo
10604f3e4eSYonggang Luo
11604f3e4eSYonggang Luoimport sys
12604f3e4eSYonggang Luoimport subprocess
13604f3e4eSYonggang Luo
14604f3e4eSYonggang Luodef filter_lines_set(stdout, from_staticlib):
15604f3e4eSYonggang Luo    linesSet = set()
16604f3e4eSYonggang Luo    for line in stdout.splitlines():
17604f3e4eSYonggang Luo        tokens = line.split(b' ')
18*da0dfe25SPaolo Bonzini        if len(tokens) >= 2:
19604f3e4eSYonggang Luo            if from_staticlib and tokens[1] == b'U':
20604f3e4eSYonggang Luo                continue
21604f3e4eSYonggang Luo            if not from_staticlib and tokens[1] != b'U':
22604f3e4eSYonggang Luo                continue
23604f3e4eSYonggang Luo            new_line = b'-Wl,-u,' + tokens[0]
24604f3e4eSYonggang Luo            if not new_line in linesSet:
25604f3e4eSYonggang Luo                linesSet.add(new_line)
26604f3e4eSYonggang Luo    return linesSet
27604f3e4eSYonggang Luo
28604f3e4eSYonggang Luodef main(args):
29604f3e4eSYonggang Luo    if len(args) <= 3:
30604f3e4eSYonggang Luo        sys.exit(0)
31604f3e4eSYonggang Luo
32604f3e4eSYonggang Luo    nm = args[1]
33604f3e4eSYonggang Luo    staticlib = args[2]
34604f3e4eSYonggang Luo    pc = subprocess.run([nm, "-P", "-g", staticlib], stdout=subprocess.PIPE)
35604f3e4eSYonggang Luo    if pc.returncode != 0:
36604f3e4eSYonggang Luo        sys.exit(1)
37604f3e4eSYonggang Luo    staticlib_syms = filter_lines_set(pc.stdout, True)
38604f3e4eSYonggang Luo
39604f3e4eSYonggang Luo    shared_modules = args[3:]
40604f3e4eSYonggang Luo    pc = subprocess.run([nm, "-P", "-g"] + shared_modules, stdout=subprocess.PIPE)
41604f3e4eSYonggang Luo    if pc.returncode != 0:
42604f3e4eSYonggang Luo        sys.exit(1)
43604f3e4eSYonggang Luo    modules_undef_syms = filter_lines_set(pc.stdout, False)
44604f3e4eSYonggang Luo    lines = sorted(staticlib_syms.intersection(modules_undef_syms))
45604f3e4eSYonggang Luo    sys.stdout.buffer.write(b'\n'.join(lines))
46604f3e4eSYonggang Luo
47604f3e4eSYonggang Luoif __name__ == "__main__":
48604f3e4eSYonggang Luo    main(sys.argv)
49