build: symtab: Add a dummy entry at the end for the binary search

The `symtab_find_symbol_name()` is using an adapted binary
search function to get the entry between 2 addresses, we need
to add a dummy entry at the end so that the search function
can remain simple and straightforward without doing
out-of-bound checks:

   20  \
       |
       |
   50  x
       |
       |
   90  x
    .  |
    .  |
    .  |
dummy  /

Signed-off-by: Yong Cong Sin <ycsin@meta.com>
This commit is contained in:
Yong Cong Sin 2024-05-27 21:38:55 +08:00 committed by David Leach
commit f5934de8e5
2 changed files with 33 additions and 16 deletions

View file

@ -55,8 +55,9 @@ def parse_args():
class symtab_entry:
def __init__(self, addr, offset, name):
def __init__(self, addr, size, offset, name):
self.addr = addr
self.size = size
self.offset = offset
self.name = name
@ -90,11 +91,12 @@ def main():
for nsym, symbol in enumerate(symtab.iter_symbols()): # pylint: disable=unused-variable
symbol_type = describe_symbol_type(symbol['st_info']['type'])
symbol_addr = symbol['st_value']
symbol_size = symbol['st_size']
if symbol_type == 'FUNC' and symbol_addr != 0:
symbol_name = sanitize_func_name(symbol.name)
symtab_list.append(symtab_entry(
symbol_addr, symbol_addr, symbol_name))
symbol_addr, symbol_addr, symbol_size, symbol_name))
log.debug('%6d: %s %.25s' % (
i,
hex(symbol_addr),
@ -115,10 +117,21 @@ def main():
print("#include <zephyr/debug/symtab.h>", file=wf)
print("", file=wf)
print(
f"const struct z_symtab_entry z_symtab_entries[{len(symtab_list)}] = {{", file=wf)
f"const struct z_symtab_entry z_symtab_entries[{len(symtab_list) + 1}] = {{", file=wf)
for i, entry in enumerate(symtab_list):
print(
f"\t[{i}] = {{.offset = {hex(entry.offset)}, .name = \"{entry.name}\"}}, /* {hex(entry.addr)} */", file=wf)
f"\t/* ADDR: {hex(entry.addr)} SIZE: {hex(entry.size)} */", file=wf)
print(
f"\t[{i}] = {{.offset = {hex(entry.offset)}, .name = \"{entry.name}\"}},", file=wf)
# Append a dummy entry at the end to facilitate the binary search
if symtab_list[-1].size == 0:
dummy_offset = f"{hex(symtab_list[-1].offset)} + sizeof(uintptr_t)"
else:
dummy_offset = f"{hex(symtab_list[-1].offset + symtab_list[-1].size)}"
print("\t/* dummy entry */", file=wf)
print(
f"\t[{len(symtab_list)}] = {{.offset = {dummy_offset}, .name = \"?\"}},", file=wf)
print(f"}};\n", file=wf)
print(f"const struct symtab_info z_symtab = {{", file=wf)

View file

@ -5,6 +5,7 @@
*/
#include <string.h>
#include <stdbool.h>
#include <zephyr/debug/symtab.h>
@ -19,22 +20,25 @@ const char *const symtab_find_symbol_name(uintptr_t addr, uint32_t *offset)
{
const struct symtab_info *const symtab = symtab_get();
const uint32_t symbol_offset = addr - symtab->start_addr;
uint32_t left = 0, right = symtab->length - 1;
uint32_t left = 0, right = symtab->length;
uint32_t ret_offset = 0;
const char *ret_name = "?";
while (left <= right) {
uint32_t mid = left + (right - left) / 2;
/* No need to search if the address is out-of-bound */
if (symbol_offset < symtab->entries[symtab->length].offset) {
while (left <= right) {
uint32_t mid = left + (right - left) / 2;
if ((symbol_offset >= symtab->entries[mid].offset) &&
(symbol_offset < symtab->entries[mid + 1].offset)) {
ret_offset = symbol_offset - symtab->entries[mid].offset;
ret_name = symtab->entries[mid].name;
break;
} else if (symbol_offset < symtab->entries[mid].offset) {
right = mid - 1;
} else {
left = mid + 1;
if ((symbol_offset >= symtab->entries[mid].offset) &&
(symbol_offset < symtab->entries[mid + 1].offset)) {
ret_offset = symbol_offset - symtab->entries[mid].offset;
ret_name = symtab->entries[mid].name;
break;
} else if (symbol_offset < symtab->entries[mid].offset) {
right = mid - 1;
} else {
left = mid + 1;
}
}
}