mirror of
https://github.com/espressif/esp-idf.git
synced 2025-08-08 20:21:04 +00:00
feat(debugging): move gdbinit generation to CMake
This feature is useful for 3rd-party software to run GDB with predefined options that described in project_description.json file allow to pass custom options to "idf.py gdb": --gdb-commands: command line arguments for gdb. (without changes) -ex: pass command to gdb. -x: pass gdbinit file to gdb. Alias for old --gdbinit command
This commit is contained in:
70
components/esp_rom/gen_gdbinit.py
Normal file
70
components/esp_rom/gen_gdbinit.py
Normal file
@@ -0,0 +1,70 @@
|
||||
#!/usr/bin/env python
|
||||
#
|
||||
# SPDX-FileCopyrightText: 2024 Espressif Systems (Shanghai) CO LTD
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
import json
|
||||
import os
|
||||
import sys
|
||||
from textwrap import indent
|
||||
|
||||
IDF_PATH = os.getenv('IDF_PATH', '')
|
||||
ROMS_JSON = os.path.join(IDF_PATH, 'tools', 'idf_py_actions', 'roms.json') # type: ignore
|
||||
|
||||
|
||||
# Direct string extraction and comparison is not feasible due to:
|
||||
# 1. ROM ELF binaries for esp32XX chips are little-endian. The byte order in
|
||||
# the binary may differ from the system's endianness. We must ensure the
|
||||
# bytes are read correctly for the system where the script runs.
|
||||
# 2. GDB lacks built-in string comparison functionality. To work around this,
|
||||
# strings are converted to numeric values for comparison.
|
||||
def get_rom_if_condition_str(date_addr: int, date_str: str) -> str:
|
||||
r = []
|
||||
for i in range(0, len(date_str), 4):
|
||||
value = hex(int.from_bytes(bytes(date_str[i:i + 4], 'utf-8'), 'little'))
|
||||
r.append(f'(*(int*) {hex(date_addr + i)}) == {value}')
|
||||
return 'if ' + ' && '.join(r)
|
||||
|
||||
|
||||
def generate_gdbinit_rom_add_symbols(target: str) -> str:
|
||||
base_ident = ' '
|
||||
rom_elfs_dir = os.getenv('ESP_ROM_ELF_DIR')
|
||||
if not rom_elfs_dir:
|
||||
raise EnvironmentError(
|
||||
'ESP_ROM_ELF_DIR environment variable is not defined. Please try to run IDF "install" and "export" scripts.')
|
||||
with open(ROMS_JSON, 'r') as f:
|
||||
roms = json.load(f)
|
||||
if target not in roms:
|
||||
msg_body = f'Warning: ROM ELF is not supported yet for "{target}".' # noqa: E713
|
||||
return f'echo {msg_body}\\n\n'
|
||||
r = ['', f'# Load {target} ROM ELF symbols']
|
||||
r.append('define target hookpost-remote')
|
||||
r.append('set confirm off')
|
||||
# Since GDB does not have 'else if' statement than we use nested 'if..else' instead.
|
||||
for i, k in enumerate(roms[target], 1):
|
||||
indent_str = base_ident * i
|
||||
rom_file = f'{target}_rev{k["rev"]}_rom.elf'
|
||||
build_date_addr = int(k['build_date_str_addr'], base=16)
|
||||
r.append(indent(f'# if $_streq((char *) {hex(build_date_addr)}, "{k["build_date_str"]}")', indent_str))
|
||||
r.append(indent(get_rom_if_condition_str(build_date_addr, k['build_date_str']), indent_str))
|
||||
r.append(indent(f'add-symbol-file {rom_elfs_dir}{rom_file}', indent_str + base_ident))
|
||||
r.append(indent('else', indent_str))
|
||||
if i == len(roms[target]):
|
||||
# In case no one known ROM ELF fits - print warning
|
||||
indent_str += base_ident
|
||||
msg_body = f'Warning: Unknown {target} ROM revision.'
|
||||
r.append(indent(f'echo {msg_body}\\n', indent_str))
|
||||
# Close 'else' operators
|
||||
for i in range(len(roms[target]), 0, -1):
|
||||
r.append(indent('end', base_ident * i))
|
||||
r.append('set confirm on')
|
||||
r.append('end')
|
||||
return '\n'.join(r)[1:]
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
if len(sys.argv) != 2:
|
||||
raise ValueError('Please pass only one argument (target).')
|
||||
|
||||
target = sys.argv[1]
|
||||
gdbinit_lines = generate_gdbinit_rom_add_symbols(target)
|
||||
print(gdbinit_lines)
|
Reference in New Issue
Block a user