#!/usr/bin/env python3 # # Generate the jsix style symbol table. The format in memory of this table # is as follows: # # : 8 bytes # : 16 * N bytes # : variable # # Each index entry has the format # : 8 bytes # : 8 bytes # # Name offsets are from the start of the symbol table as a whole. (ie, # where 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 syms = [] for line in sys.stdin: addr, t, mangled = line.split() if t not in "tTvVwW": continue addr = int(addr, base=16) name = demangle(mangled) 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]} ") sys.exit(1) outfile = open(sys.argv[1], "wb") write_table(parse_syms(sys.stdin), outfile)