1 """A tool for extracting a list of private lldb symbols to export for MSVC.
3 When exporting symbols from a dll or exe we either need to mark the symbols in
4 the source code as __declspec(dllexport) or supply a list of symbols to the
5 linker. Private symbols in LLDB don't explicitly specific dllexport, so we
6 automate that by examining the symbol table.
16 def extract_symbols(nm_path
: str, lib
: str):
17 """Extract all of the private lldb symbols from the given path to llvm-nm and
18 library to extract from."""
20 # Matches mangled symbols containing 'lldb_private'.
21 lldb_sym_re
= r
"[0-9a-zA-Z]* [BT] (?P<symbol>[?]+[^?].*lldb_private.*)"
23 # '-g' means we only get global symbols.
24 # '-p' do not waste time sorting the symbols.
25 process
= subprocess
.Popen(
26 [nm_path
, "-g", "-p", lib
],
28 stdout
=subprocess
.PIPE
,
29 stdin
=subprocess
.PIPE
,
30 universal_newlines
=True,
35 for line
in process
.stdout
:
36 match
= re
.match(lldb_sym_re
, line
)
38 symbol
= match
.group("symbol")
40 symbol
.count(" ") == 0
41 ), "Regex matched too much, probably got undecorated name as well"
42 # Deleting destructors start with ?_G or ?_E and can be discarded
43 # because link.exe gives you a warning telling you they can't be
44 # exported if you don't.
45 if symbol
.startswith("??_G") or symbol
.startswith("??_E"):
47 lldb_symbols
.add(symbol
)
53 parser
= argparse
.ArgumentParser(description
="Generate LLDB dll exports")
55 "-o", metavar
="file", type=str, help="The name of the resultant export file."
57 parser
.add_argument("--nm", help="Path to the llvm-nm executable.")
63 help="The libraries to extract symbols from.",
65 args
= parser
.parse_args()
67 # Get the list of libraries to extract symbols from
70 # When invoked by cmake the arguments are the cmake target names of the
71 # libraries, so we need to add .lib/.a to the end and maybe lib to the
72 # start to get the filename. Also allow objects.
73 suffixes
= [".lib", ".a", ".obj", ".o"]
74 if not any([lib
.endswith(s
) for s
in suffixes
]):
75 for suffix
in suffixes
:
76 if os
.path
.exists(lib
+ suffix
):
79 if os
.path
.exists("lib" + lib
+ suffix
):
80 lib
= "lib" + lib
+ suffix
82 if not any([lib
.endswith(s
) for s
in suffixes
]):
84 "Unknown extension type for library argument: " + lib
, file=sys
.stderr
89 # Extract symbols from the input libraries.
92 for sym
in list(extract_symbols(args
.nm
, lib
)):
95 # Write out the symbols to the output file.
96 with
open(args
.o
, "w", newline
="") as f
:
97 for s
in sorted(symbols
):
101 if __name__
== "__main__":