1#!/usr/bin/env python 2# 3# SPDX-FileCopyrightText: 2016 Cesanta Software Limited 4# 5# SPDX-License-Identifier: GPL-2.0-or-later 6# 7# SPDX-FileContributor: 2016-2022 Espressif Systems (Shanghai) CO LTD 8 9import argparse 10import base64 11import json 12import os 13import os.path 14import sys 15 16sys.path.append("..") 17import esptool # noqa: E402 18 19THIS_DIR = os.path.dirname(__file__) 20BUILD_DIR = os.path.join(THIS_DIR, "build") 21 22 23def wrap_stub(elf_file): 24 """Wrap an ELF file into a stub JSON dict""" 25 print("Wrapping ELF file %s..." % elf_file) 26 27 e = esptool.bin_image.ELFFile(elf_file) 28 29 text_section = e.get_section(".text") 30 stub = { 31 "entry": e.entrypoint, 32 "text": text_section.data, 33 "text_start": text_section.addr, 34 } 35 try: 36 data_section = e.get_section(".data") 37 stub["data"] = data_section.data 38 stub["data_start"] = data_section.addr 39 except ValueError: 40 pass 41 42 for s in e.nobits_sections: 43 if s.name == ".bss": 44 stub["bss_start"] = s.addr 45 46 # Pad text with NOPs to mod 4. 47 if len(stub["text"]) % 4 != 0: 48 stub["text"] += (4 - (len(stub["text"]) % 4)) * "\0" 49 50 print( 51 "Stub text: %d @ 0x%08x, data: %d @ 0x%08x, entry @ 0x%x" 52 % ( 53 len(stub["text"]), 54 stub["text_start"], 55 len(stub.get("data", "")), 56 stub.get("data_start", 0), 57 stub["entry"], 58 ), 59 file=sys.stderr, 60 ) 61 62 return stub 63 64 65def write_json_files(stubs_dict): 66 class BytesEncoder(json.JSONEncoder): 67 def default(self, obj): 68 if isinstance(obj, bytes): 69 return base64.b64encode(obj).decode("ascii") 70 return json.JSONEncoder.default(self, obj) 71 72 for filename, stub_data in stubs_dict.items(): 73 with open(os.path.join(BUILD_DIR, filename), "w") as outfile: 74 json.dump(stub_data, outfile, cls=BytesEncoder, indent=4) 75 76 77def stub_name(filename): 78 """Return a dictionary key for the stub with filename 'filename'""" 79 return os.path.splitext(os.path.basename(filename))[0] + ".json" 80 81 82if __name__ == "__main__": 83 parser = argparse.ArgumentParser() 84 parser.add_argument("elf_files", nargs="+", help="Stub ELF files to convert") 85 args = parser.parse_args() 86 87 stubs = dict( 88 (stub_name(elf_file), wrap_stub(elf_file)) for elf_file in args.elf_files 89 ) 90 write_json_files(stubs) 91