mirror of
https://github.com/justinian/jsix.git
synced 2025-12-09 16:04:32 -08:00
For some reason, cxxfilt fails to demangle some names on some systems. Instead of failing the build process, just skip those symbols.
76 lines
1.9 KiB
Python
Executable File
76 lines
1.9 KiB
Python
Executable File
#!/usr/bin/env python3
|
|
#
|
|
# Generate the jsix style symbol table. The format in memory of this table
|
|
# is as follows:
|
|
#
|
|
# <num_entires> : 8 bytes
|
|
# <index> : 16 * N bytes
|
|
# <name data> : variable
|
|
#
|
|
# Each index entry has the format
|
|
# <symbol address> : 8 bytes
|
|
# <offset of name> : 8 bytes
|
|
#
|
|
# Name offsets are from the start of the symbol table as a whole. (ie,
|
|
# where <num_entries> is located.)
|
|
|
|
def parse_syms(infile):
|
|
"""Take the output of the `nm` command, and parse it into a tuple
|
|
representing the symbols in the text segment of the binary. Returns
|
|
a list of (address, symbol_name)."""
|
|
|
|
from cxxfilt import demangle, InvalidName
|
|
|
|
syms = []
|
|
for line in sys.stdin:
|
|
addr, t, mangled = line.split()
|
|
if t not in "tTvVwW": continue
|
|
|
|
try:
|
|
name = demangle(mangled)
|
|
except InvalidName:
|
|
continue
|
|
|
|
addr = int(addr, base=16)
|
|
syms.append((addr, name))
|
|
|
|
return sorted(syms)
|
|
|
|
|
|
def write_table(syms, outfile):
|
|
"""Write the given symbol table as generated by parse_syms()
|
|
to the outfile, index first, and then name character data."""
|
|
|
|
import struct
|
|
|
|
outfile.write(struct.pack("@Q", len(syms)))
|
|
index_pos = outfile.tell()
|
|
|
|
outfile.seek(struct.calcsize("@QQ") * len(syms), 1)
|
|
nul = b'\0'
|
|
|
|
positions = {}
|
|
for s in syms:
|
|
addr, name = s
|
|
positions[addr] = outfile.tell()
|
|
|
|
data = name.encode('utf-8')
|
|
outfile.write(name.encode('utf-8'))
|
|
outfile.write(nul)
|
|
|
|
outfile.seek(index_pos)
|
|
for s in syms:
|
|
addr = s[0]
|
|
pos = positions[addr]
|
|
outfile.write(struct.pack("@QQ", addr, pos))
|
|
|
|
|
|
if __name__ == "__main__":
|
|
import sys
|
|
if len(sys.argv) != 2:
|
|
print(f"Usage: {sys.argv[0]} <output>")
|
|
sys.exit(1)
|
|
|
|
outfile = open(sys.argv[1], "wb")
|
|
write_table(parse_syms(sys.stdin), outfile)
|