| @@ -471,12 +471,43 @@ ST_FUNC addr_t get_elf_sym_addr(TCCState *s, const char *name, int err) · 470 unmodified lines |
| 471 | 471 | return sym->st_value; |
| 472 | 472 | } |
| 473 | 473 | |
| 474 | +/* list elf symbol names and values */ |
| 475 | +ST_FUNC void list_elf_symbols(TCCState *s, void *ctx, |
| 476 | + void (*symbol_cb)(void *ctx, const char *name, const void *val)) |
| 477 | +{ |
| 478 | + ElfW(Sym) *sym; |
| 479 | + Section *symtab; |
| 480 | + int sym_index, end_sym; |
| 481 | + const char *name; |
| 482 | + unsigned char sym_vis, sym_bind; |
| 483 | + |
| 484 | + symtab = s->symtab; |
| 485 | + end_sym = symtab->data_offset / sizeof (ElfSym); |
| 486 | + for (sym_index = 0; sym_index < end_sym; ++sym_index) { |
| 487 | + sym = &((ElfW(Sym) *)symtab->data)[sym_index]; |
| 488 | + if (sym->st_value) { |
| 489 | + name = (char *) symtab->link->data + sym->st_name; |
| 490 | + sym_bind = ELFW(ST_BIND)(sym->st_info); |
| 491 | + sym_vis = ELFW(ST_VISIBILITY)(sym->st_other); |
| 492 | + if (sym_bind == STB_GLOBAL && sym_vis == STV_DEFAULT) |
| 493 | + symbol_cb(ctx, name, (void*)(uintptr_t)sym->st_value); |
| 494 | + } |
| 495 | + } |
| 496 | +} |
| 497 | + |
| 474 | 498 | /* return elf symbol value */ |
| 475 | 499 | LIBTCCAPI void *tcc_get_symbol(TCCState *s, const char *name) |
| 476 | 500 | { |
| 477 | 501 | return (void*)(uintptr_t)get_elf_sym_addr(s, name, 0); |
| 478 | 502 | } |
| 479 | 503 | |
| 504 | +/* list elf symbol names and values */ |
| 505 | +LIBTCCAPI void tcc_list_symbols(TCCState *s, void *ctx, |
| 506 | + void (*symbol_cb)(void *ctx, const char *name, const void *val)) |
| 507 | +{ |
| 508 | + list_elf_symbols(s, ctx, symbol_cb); |
| 509 | +} |
| 510 | + |
| 480 | 511 | #if defined TCC_IS_NATIVE || defined TCC_TARGET_PE |
| 481 | 512 | /* return elf symbol value or error */ |
| 482 | 513 | ST_FUNC void* tcc_get_symbol_err(TCCState *s, const char *name) |