5 sym_line = re.compile(r"^(?P<addr>[0-9a-f]+)\s[a-z]\s+F\s+\.[a-z._]+\s+[0-9a-f]+(?P<label>.+)$")
7 def main(kbin, sym_out, endianness='little', bits=32):
9 assert (1 << int(math.log2(bits))) == bits
12 result = subprocess.run(["objdump", "--syms", kbin],stdout=subprocess.PIPE, stderr=subprocess.PIPE)
13 if result.returncode != 0:
17 def to_native(val: int):
18 return val.to_bytes(b_len, endianness, signed=False)
20 output = result.stdout.split(b'\n')
27 mo = sym_line.match(l)
32 addr = int(mg["addr"], 16)
33 label = mg["label"].strip() + '\0'
35 functions.append((addr, label))
37 functions = sorted(functions, key=lambda x: x[0])
41 # unsigned int label_off;
43 sym_struct_sz = b_len * 2
44 meta_struct_sz = 4 * 2
45 label_off_base = sym_struct_sz * len(functions) + meta_struct_sz
46 alignment = bytearray([b'\0' for _ in range(b_len - 4)])
50 text_region = bytearray()
51 null = bytearray(b'\0')
52 with open(sym_out, mode='wb') as f:
54 # unsigned int num_entry;
55 # unsigned int label_off_base;
57 f.write(to_native(len(functions)))
58 f.write(to_native(label_off_base))
60 for a, l in functions:
62 f.write(to_native(label_off))
65 text_region += bytes(l, 'ascii')
66 aligned_len = (len(l) + bmask) & ~bmask
67 for i in range(aligned_len - len(l)):
68 text_region.append(null[0])
70 label_off += aligned_len
76 if __name__ == "__main__":
77 parser = argparse.ArgumentParser()
78 parser.add_argument('elf_exec')
79 parser.add_argument('-o', '--outfile', required=True)
80 parser.add_argument('--bits', default=32)
81 parser.add_argument('--order', default='little')
83 args = parser.parse_args()
85 main(args.elf_exec, args.outfile, endianness=args.order, bits=int(args.bits))