static int elf_read_symbols(elf_reader_t *reader, const char *path, elfread_src_t srcsec) { int i, nsymbols, nfiltered, iflt; size_t storage_needed; reader->__abfd = bfd_openr(path, NULL); if (!reader->__abfd) return -1; bfd_check_format(reader->__abfd, bfd_object); storage_needed = (srcsec == READSYMBOLS_TEXT) ? bfd_get_symtab_upper_bound(reader->__abfd) : bfd_get_dynamic_symtab_upper_bound(reader->__abfd); if (storage_needed <= 0) { return -1; } reader->__symbol_table = (asymbol**)malloc(storage_needed); if (!reader->__symbol_table) return -1; nsymbols = (srcsec == READSYMBOLS_TEXT) ? bfd_canonicalize_symtab(reader->__abfd, reader->__symbol_table) : bfd_canonicalize_dynamic_symtab(reader->__abfd, reader->__symbol_table); if (nsymbols < 0) return -1; nfiltered = 0; for (i = 0; i < nsymbols; i++) { if (reader->__symbol_table[i]->flags & (BSF_FUNCTION | BSF_GLOBAL)) nfiltered++; } reader->symbols = (elf_symbol_t *)malloc(nfiltered * sizeof(elf_symbol_t)); if (!reader->symbols) return -1; for (i = 0, iflt = 0; i < nsymbols && iflt < nfiltered; i++) { asymbol *is = reader->__symbol_table[i]; if (is->flags & (BSF_FUNCTION | BSF_GLOBAL)) { elf_symbol_t *os = reader->symbols + iflt++; os->symbol_name = (const char *)bfd_asymbol_name(is); os->symbol_value = bfd_asymbol_value(is); os->symbol_size = BFD_GET_SYMBOL_SIZE(is); os->symbol_class = (char)bfd_decode_symclass(is); } } assert(iflt == nfiltered); return iflt; }
void bfd_symbol_info (asymbol *symbol, symbol_info *ret) { ret->type = bfd_decode_symclass (symbol); if (bfd_is_undefined_symclass (ret->type)) ret->value = 0; else ret->value = symbol->value + symbol->section->vma; ret->name = symbol->name; }
int main(int argc, char *argv[]) { bfd *abfd; bfd_init(); abfd = bfd_openr(argv[1], NULL); if (abfd == NULL) { bfd_perror("bfd_openr"); exit(1); } if (! bfd_check_format(abfd, bfd_object)) { bfd_perror("bfd_check_format"); } printf("SYMBOL TABLE:\n"); { long storage_needed; asymbol **symbol_table; long number_of_symbols; long i; storage_needed = bfd_get_symtab_upper_bound (abfd); printf("storage_need=%d\n", storage_needed); if (storage_needed < 0) { bfd_perror("bfd_get_symtab_upper_bound"); exit(1); } if (storage_needed == 0) { printf("no symbols\n"); exit(0); } symbol_table = (asymbol **)malloc (storage_needed); number_of_symbols = bfd_canonicalize_symtab (abfd, symbol_table); if (number_of_symbols < 0) { bfd_perror("bfd_canonicalize_symtab"); exit(1); } for (i = 0; i < number_of_symbols; i++) { asymbol *asym = symbol_table[i]; int symclass = bfd_decode_symclass(asym); symbol_info syminfo; bfd_symbol_info(asym, &syminfo); bfd_print_symbol_vandf(abfd, stdout, asym); printf(" 0x%x %s ", symclass, bfd_is_undefined_symclass(symclass) ? "?" : " "); printf(" %s ", bfd_asymbol_name(asym)); printf("%p ", bfd_asymbol_value(asym)); // printf(" %d ", syminfo.value); /* asymbol_value */ // printf(" %d ", syminfo.type); /* symclass */ // printf(" %s ", syminfo.name); /* asymbol_name */ printf(" %d ", syminfo.stab_type); printf(" %d ", syminfo.stab_other); printf(" %d ", syminfo.stab_desc); // printf(" %s ", syminfo.stab_name); printf("\n"); } } printf("DYNAMIC SYMBOL TABLE:\n"); { long storage_needed; asymbol **symbol_table; long number_of_symbols; long i; storage_needed = bfd_get_dynamic_symtab_upper_bound (abfd); printf("storage_need=%d\n", storage_needed); if (storage_needed < 0) { bfd_perror("bfd_get_symtab_upper_bound"); exit(1); } if (storage_needed == 0) { printf("no symbols\n"); exit(0); } symbol_table = (asymbol **)malloc (storage_needed); number_of_symbols = bfd_canonicalize_dynamic_symtab (abfd, symbol_table); if (number_of_symbols < 0) { bfd_perror("bfd_canonicalize_symtab"); exit(1); } for (i = 0; i < number_of_symbols; i++) { asymbol *asym = symbol_table[i]; int symclass = bfd_decode_symclass(asym); symbol_info syminfo; bfd_symbol_info(asym, &syminfo); bfd_print_symbol_vandf(abfd, stdout, asym); printf(" 0x%x %s ", symclass, bfd_is_undefined_symclass(symclass) ? "?" : " "); printf(" %s ", bfd_asymbol_name(asym)); printf("%p ", bfd_asymbol_value(asym)); // printf(" %d ", syminfo.value); /* asymbol_value */ // printf(" %d ", syminfo.type); /* symclass */ // printf(" %s ", syminfo.name); /* asymbol_name */ printf(" %d ", syminfo.stab_type); printf(" %d ", syminfo.stab_other); printf(" %d ", syminfo.stab_desc); // printf(" %s ", syminfo.stab_name); printf("\n"); } } exit(0); }
static int printStackTrace(JNIEnv *env, jobject sobj, StackTrace tr) { bfd *abfd; long storage_needed; asymbol **symbol_table; symtab_entry *symtab; long number_of_symbols; long number_of_text_symbols; long i, j; StackTrace curr; bfd_init(); abfd = bfd_openr(name_of_binary, "default"); bfd_set_format(abfd, bfd_object); if (!bfd_check_format(abfd, bfd_object)) { printf("Error(1) in printStackTrace\n"); return(1); } storage_needed = bfd_get_symtab_upper_bound(abfd); if (storage_needed < 0) { printf("Error(2) in printStackTrace\n"); return(2); } if (storage_needed == 0) { printf("Error(3) no symbols\n"); return(3); } symbol_table = (asymbol **) xmalloc (storage_needed); number_of_symbols = bfd_canonicalize_symtab (abfd, symbol_table); if (number_of_symbols < 0) { printf("Error(4) in printStackTrace\n"); return(4); } /* count number of symbols in text segment */ for (i = number_of_text_symbols = 0; i < number_of_symbols; i++) if (bfd_decode_symclass(symbol_table[i]) == 'T') number_of_text_symbols++; if (number_of_text_symbols < 0) { printf("Error(5) in printStackTrace\n"); return(5); } if (number_of_text_symbols == 0) { printf("Error(6) No symbols in text segment.\n"); return(6); } symtab = (symtab_entry *) malloc(number_of_text_symbols * sizeof(symtab_entry)); for (i = j = 0; i < number_of_symbols; i++) { symbol_info si; bfd_symbol_info(symbol_table[i], &si); if (bfd_decode_symclass(symbol_table[i]) == 'T') { if (j >= number_of_text_symbols) { printf("Error(7) in printStackTrace\n"); return(7); } (symtab+j)->value = (unsigned long)si.value; (symtab+j)->name = si.name; j++; } } qsort(symtab, number_of_text_symbols, sizeof(symtab_entry), compare_symtab_entry); curr = tr; while(curr != NULL) { symtab_entry *found = bsearch_symtab((symvalue)curr->retaddr, symtab, number_of_text_symbols); printItem(env, sobj, found, curr); curr = curr->next; } /* clean up */ free(symtab); bfd_close(abfd); return(0); }