1#!/usr/bin/env python3 2# 3# Copyright (c) 2017 Intel Corporation. 4# 5# SPDX-License-Identifier: Apache-2.0 6# 7 8""" 9This script scans a specified object file and generates a header file 10that defined macros for the offsets of various found structure members 11(particularly symbols ending with ``_OFFSET`` or ``_SIZEOF``), primarily 12intended for use in assembly code. 13""" 14 15import argparse 16import sys 17 18from elftools.elf.elffile import ELFFile 19from elftools.elf.sections import SymbolTableSection 20 21 22def get_symbol_table(obj): 23 for section in obj.iter_sections(): 24 if isinstance(section, SymbolTableSection): 25 return section 26 27 raise LookupError("Could not find symbol table") 28 29 30def gen_offset_header(input_name, input_file, output_file): 31 include_guard = "__GEN_OFFSETS_H__" 32 output_file.write( 33 f"""/* THIS FILE IS AUTO GENERATED. PLEASE DO NOT EDIT. 34 * 35 * This header file provides macros for the offsets of various structure 36 * members. These offset macros are primarily intended to be used in 37 * assembly code. 38 */ 39 40#ifndef {include_guard} 41#define {include_guard}\n\n""" 42 ) 43 44 obj = ELFFile(input_file) 45 for sym in get_symbol_table(obj).iter_symbols(): 46 if isinstance(sym.name, bytes): 47 sym.name = str(sym.name, 'ascii') 48 49 if not sym.name.endswith(('_OFFSET', '_SIZEOF')): 50 continue 51 if sym.entry['st_shndx'] != 'SHN_ABS': 52 continue 53 if sym.entry['st_info']['bind'] != 'STB_GLOBAL': 54 continue 55 56 output_file.write(f"#define {sym.name} 0x{sym.entry['st_value']:x}\n") 57 58 output_file.write(f"\n#endif /* {include_guard} */\n") 59 60 return 0 61 62 63if __name__ == '__main__': 64 parser = argparse.ArgumentParser( 65 description=__doc__, 66 formatter_class=argparse.RawDescriptionHelpFormatter, 67 allow_abbrev=False, 68 ) 69 70 parser.add_argument("-i", "--input", required=True, help="Input object file") 71 parser.add_argument("-o", "--output", required=True, help="Output header file") 72 73 args = parser.parse_args() 74 75 with open(args.input, 'rb') as input_file, open(args.output, 'w') as output_file: 76 ret = gen_offset_header(args.input, input_file, output_file) 77 78 sys.exit(ret) 79