|  | #!/usr/bin/env python3 | 
|  | # | 
|  | # Copyright (c) 2017 Intel Corporation. | 
|  | # | 
|  | # SPDX-License-Identifier: Apache-2.0 | 
|  | # | 
|  |  | 
|  | """ | 
|  | This script scans a specified object file and generates a header file | 
|  | that defined macros for the offsets of various found structure members | 
|  | (particularly symbols ending with ``_OFFSET`` or ``_SIZEOF``), primarily | 
|  | intended for use in assembly code. | 
|  | """ | 
|  |  | 
|  | from elftools.elf.elffile import ELFFile | 
|  | from elftools.elf.sections import SymbolTableSection | 
|  | import argparse | 
|  | import sys | 
|  |  | 
|  |  | 
|  | def get_symbol_table(obj): | 
|  | for section in obj.iter_sections(): | 
|  | if isinstance(section, SymbolTableSection): | 
|  | return section | 
|  |  | 
|  | raise LookupError("Could not find symbol table") | 
|  |  | 
|  |  | 
|  | def gen_offset_header(input_name, input_file, output_file): | 
|  | include_guard = "__GEN_OFFSETS_H__" | 
|  | output_file.write("""/* THIS FILE IS AUTO GENERATED.  PLEASE DO NOT EDIT. | 
|  | * | 
|  | * This header file provides macros for the offsets of various structure | 
|  | * members.  These offset macros are primarily intended to be used in | 
|  | * assembly code. | 
|  | */ | 
|  |  | 
|  | #ifndef %s | 
|  | #define %s\n\n""" % (include_guard, include_guard)) | 
|  |  | 
|  | obj = ELFFile(input_file) | 
|  | for sym in get_symbol_table(obj).iter_symbols(): | 
|  | if isinstance(sym.name, bytes): | 
|  | sym.name = str(sym.name, 'ascii') | 
|  |  | 
|  | if not sym.name.endswith(('_OFFSET', '_SIZEOF')): | 
|  | continue | 
|  | if sym.entry['st_shndx'] != 'SHN_ABS': | 
|  | continue | 
|  | if sym.entry['st_info']['bind'] != 'STB_GLOBAL': | 
|  | continue | 
|  |  | 
|  | output_file.write( | 
|  | "#define %s 0x%x\n" % | 
|  | (sym.name, sym.entry['st_value'])) | 
|  |  | 
|  | output_file.write("\n#endif /* %s */\n" % include_guard) | 
|  |  | 
|  | return 0 | 
|  |  | 
|  |  | 
|  | if __name__ == '__main__': | 
|  | parser = argparse.ArgumentParser( | 
|  | description=__doc__, | 
|  | formatter_class=argparse.RawDescriptionHelpFormatter, allow_abbrev=False) | 
|  |  | 
|  | parser.add_argument( | 
|  | "-i", | 
|  | "--input", | 
|  | required=True, | 
|  | help="Input object file") | 
|  | parser.add_argument( | 
|  | "-o", | 
|  | "--output", | 
|  | required=True, | 
|  | help="Output header file") | 
|  |  | 
|  | args = parser.parse_args() | 
|  |  | 
|  | input_file = open(args.input, 'rb') | 
|  | output_file = open(args.output, 'w') | 
|  |  | 
|  | ret = gen_offset_header(args.input, input_file, output_file) | 
|  | sys.exit(ret) |