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 15from elftools.elf.elffile import ELFFile 16from elftools.elf.sections import SymbolTableSection 17import argparse 18import sys 19 20 21def get_symbol_table(obj): 22 for section in obj.iter_sections(): 23 if isinstance(section, SymbolTableSection): 24 return section 25 26 raise LookupError("Could not find symbol table") 27 28 29def gen_offset_header(input_name, input_file, output_file): 30 include_guard = "__GEN_OFFSETS_H__" 31 output_file.write("""/* THIS FILE IS AUTO GENERATED. PLEASE DO NOT EDIT. 32 * 33 * This header file provides macros for the offsets of various structure 34 * members. These offset macros are primarily intended to be used in 35 * assembly code. 36 */ 37 38#ifndef %s 39#define %s\n\n""" % (include_guard, include_guard)) 40 41 obj = ELFFile(input_file) 42 for sym in get_symbol_table(obj).iter_symbols(): 43 if isinstance(sym.name, bytes): 44 sym.name = str(sym.name, 'ascii') 45 46 if not sym.name.endswith(('_OFFSET', '_SIZEOF')): 47 continue 48 if sym.entry['st_shndx'] != 'SHN_ABS': 49 continue 50 if sym.entry['st_info']['bind'] != 'STB_GLOBAL': 51 continue 52 53 output_file.write( 54 "#define %s 0x%x\n" % 55 (sym.name, sym.entry['st_value'])) 56 57 output_file.write("\n#endif /* %s */\n" % include_guard) 58 59 return 0 60 61 62if __name__ == '__main__': 63 parser = argparse.ArgumentParser( 64 description=__doc__, 65 formatter_class=argparse.RawDescriptionHelpFormatter, allow_abbrev=False) 66 67 parser.add_argument( 68 "-i", 69 "--input", 70 required=True, 71 help="Input object file") 72 parser.add_argument( 73 "-o", 74 "--output", 75 required=True, 76 help="Output header file") 77 78 args = parser.parse_args() 79 80 input_file = open(args.input, 'rb') 81 output_file = open(args.output, 'w') 82 83 ret = gen_offset_header(args.input, input_file, output_file) 84 sys.exit(ret) 85