bfd_vma bfd_coff_reloc16_get_value (arelent *reloc, struct bfd_link_info *link_info, asection *input_section) { bfd_vma value; asymbol *symbol = *(reloc->sym_ptr_ptr); /* A symbol holds a pointer to a section, and an offset from the base of the section. To relocate, we find where the section will live in the output and add that in. */ if (bfd_is_und_section (symbol->section) || bfd_is_com_section (symbol->section)) { struct bfd_link_hash_entry *h; /* The symbol is undefined in this BFD. Look it up in the global linker hash table. FIXME: This should be changed when we convert this stuff to use a specific final_link function and change the interface to bfd_relax_section to not require the generic symbols. */ h = bfd_wrapped_link_hash_lookup (input_section->owner, link_info, bfd_asymbol_name (symbol), FALSE, FALSE, TRUE); if (h != (struct bfd_link_hash_entry *) NULL && (h->type == bfd_link_hash_defined || h->type == bfd_link_hash_defweak)) value = (h->u.def.value + h->u.def.section->output_section->vma + h->u.def.section->output_offset); else if (h != (struct bfd_link_hash_entry *) NULL && h->type == bfd_link_hash_common) value = h->u.c.size; else if (h != (struct bfd_link_hash_entry *) NULL && h->type == bfd_link_hash_undefweak) /* This is a GNU extension. */ value = 0; else { if (!((*link_info->callbacks->undefined_symbol) (link_info, bfd_asymbol_name (symbol), input_section->owner, input_section, reloc->address, TRUE))) abort (); value = 0; } } else { value = symbol->value + symbol->section->output_offset + symbol->section->output_section->vma; } /* Add the value contained in the relocation. */ value += reloc->addend; return value; }
uv_err_t UVDBFDPatSection::setFunctionSizes() { //Functions were sorted into modules, but we need a contiguous list to determine sizes std::vector<UVDBFDPatFunction *> allSectionFunctions; int sectionSize = 0; for( std::vector<UVDBFDPatModule *>::iterator iter = m_modules.begin(); iter != m_modules.end(); ++iter ) { UVDBFDPatModule *module = *iter; uv_assert_ret(module); //std::vector<UVDBFDPatFunction *> m_functions allSectionFunctions.insert(allSectionFunctions.end(), module->m_functions.begin(), module->m_functions.end()); } sectionSize = bfd_section_size(m_core->m_bfd, m_section); //Iterate over all functions within that section for( std::vector<UVDBFDPatFunction *>::iterator iter = allSectionFunctions.begin(); iter != allSectionFunctions.end(); ) { UVDBFDPatFunction *function = NULL; std::vector<UVDBFDPatFunction *>::iterator iterStart = iter; /* What if we have a 0 sized symbol in the section? Special case: symbol is at the end of the section */ do { function = *iter; ++iter; //Get the next size //Did we reach the section end? if( iter == allSectionFunctions.end() ) { function->m_size = sectionSize - function->m_offset; //Even if we still have 0 size, we need to break break; } else { UVDBFDPatFunction *functionNext = NULL; functionNext = *iter; function->m_size = functionNext->m_offset - function->m_offset; } } while( function->m_size == 0 ); //And set any previously skipped elements from same symbol position while( iterStart != iter ) { (*iterStart)->m_size = function->m_size; ++iterStart; } printf_flirt_debug("early func size %s is 0x%04X\n", bfd_asymbol_name(function->m_bfdAsymbol), function->m_size); } return UV_ERR_OK; }
static long get_sym_offset(char *filename, char *sym) { bfd *objfile; size_t symtabsize, numsyms, i; long offset = -1; asymbol **symtab = 0; objfile = bfd_openr(filename, 0); if (!objfile) goto bail; if (!bfd_check_format(objfile, bfd_object)) goto bail; /* Get the symbol table */ symtabsize = bfd_get_symtab_upper_bound(objfile); symtab = (asymbol **) malloc (symtabsize); if (!symtab) { fprintf(stderr, "Out of memory.\n"); exit(1); } numsyms = bfd_canonicalize_symtab(objfile, symtab); /* Walk the symbol table */ for (i=0; i < numsyms; i++) if (strcmp(bfd_asymbol_name(symtab[i]),sym)==0) { offset = symtab[i]->value + symtab[i]->section->filepos; break; } bail: if (objfile) bfd_close(objfile); if (symtab) free(symtab); return offset; }
void dump_symbols(const char *filename){ bfd *abfd; asymbol *store; char *p; void *minisyms; int symnum,i; size_t size; int dyn=0; int ret; abfd=bfd_openr(filename,NULL); assert(abfd); ret=bfd_check_format(abfd,bfd_object); assert(ret); if(!(bfd_get_file_flags(abfd)&& HAS_SYMS)){ bfd_close(abfd); return; } store = bfd_make_empty_symbol(abfd); symnum = bfd_read_minisymbols(abfd,dyn,&minisyms,&size); assert(symnum>=0); p=(char *)minisyms; for(i=0;i<symnum;i++){ asymbol *sym = bfd_minisymbol_to_symbol(abfd,dyn,p,store); const char *name = bfd_asymbol_name(sym); int value = bfd_asymbol_value(sym); printf("%08x %s\n",value,name); p+=size; } free(store); free(minisyms); bfd_close(abfd); }
bool keepSymbol(bfd* abfd, asymbol* sym) { if (sym->flags & BSF_DEBUGGING) return false; if (bfd_is_target_special_symbol(abfd, sym)) return false; if (strncmp(bfd_asymbol_name(sym), ".LANCHOR", 8) == 0) return false; return true; }
int find_symbol_maxcnt (asymbol **symtab, char *name, int max_idx) { int i; for (i = 0; (symtab[i] != NULL) && (i < max_idx); i++) { if (strcmp(bfd_asymbol_name(symtab[i]), name) == 0) { return i; } } return -1; }
/* utility function to look up a symbol by its name */ int find_symbol (asymbol **symtab, char *name) { int i; for (i = 0; symtab[i] != NULL; i++) { if (strcmp(bfd_asymbol_name(symtab[i]), name) == 0) { return i; } } return -1; }
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; }
/* Get the memory bank parameters by looking at the global symbols defined by the linker. */ static int sim_get_bank_parameters (SIM_DESC sd, bfd* abfd) { sim_cpu *cpu; long symsize; long symbol_count, i; unsigned size; asymbol** asymbols; asymbol** current; cpu = STATE_CPU (sd, 0); symsize = bfd_get_symtab_upper_bound (abfd); if (symsize < 0) { sim_io_eprintf (sd, "Cannot read symbols of program"); return 0; } asymbols = (asymbol **) xmalloc (symsize); symbol_count = bfd_canonicalize_symtab (abfd, asymbols); if (symbol_count < 0) { sim_io_eprintf (sd, "Cannot read symbols of program"); return 0; } size = 0; for (i = 0, current = asymbols; i < symbol_count; i++, current++) { const char* name = bfd_asymbol_name (*current); if (strcmp (name, BFD_M68HC11_BANK_START_NAME) == 0) { cpu->bank_start = bfd_asymbol_value (*current); } else if (strcmp (name, BFD_M68HC11_BANK_SIZE_NAME) == 0) { size = bfd_asymbol_value (*current); } else if (strcmp (name, BFD_M68HC11_BANK_VIRTUAL_NAME) == 0) { cpu->bank_virtual = bfd_asymbol_value (*current); } } free (asymbols); cpu->bank_end = cpu->bank_start + size; cpu->bank_shift = 0; for (; size > 1; size >>= 1) cpu->bank_shift++; return 0; }
static asymbol *lookup_symbol(asymbol ** symbols, int nr_symbols, const char *symbol_name) { int i; for (i = 0; i < nr_symbols; i++) { asymbol *symbol = symbols[i]; if (!strcmp(bfd_asymbol_name(symbol), symbol_name)) return symbol; } return NULL; }
/** * Obtain the information of dynamic symbol (library call) */ dyn_functions_t *get_synthetic_symbols(const char *filename) { asymbol** syms = NULL; long symcount = 0; asymbol** dynsyms = NULL; long dynsymcount = 0; asymbol* synthsyms = NULL; long synthcount = 0; long storage; vector<dyn_function_t *> *ret = new vector<dyn_function_t *>(); asm_program_t *prog = new asm_program_t; bfd *abfd = initialize_bfd(filename); initialize_sections(abfd, prog); if (bfd_get_file_flags (abfd) & HAS_SYMS) { storage = bfd_get_symtab_upper_bound (abfd); assert (storage >= 0); if (storage > 0) syms = (asymbol**) xmalloc(storage); symcount = bfd_canonicalize_symtab (abfd, syms); assert (symcount >= 0); } storage = bfd_get_dynamic_symtab_upper_bound (abfd); if (storage > 0) { dynsyms = (asymbol**) xmalloc(storage); dynsymcount = bfd_canonicalize_dynamic_symtab (abfd, dynsyms); } synthcount = bfd_get_synthetic_symtab (abfd, symcount, syms, dynsymcount, dynsyms, &synthsyms); if (synthcount < 0) synthcount = 0; for (int i=0; i<synthcount; ++i) { dyn_function_t *temp = new dyn_function_t; temp->name = string(bfd_asymbol_name(&(synthsyms[i]))); temp->addr = bfd_asymbol_value(&(synthsyms[i])); ret->push_back(temp); } if (synthsyms) free(synthsyms); if (dynsyms) free(dynsyms); if (syms) free(syms); bfd_close(abfd); return ret; }
static asymbol *lookup(asymbol **symbols, int nr_symbols, const char *symbol_name) { int i, ret; ret = -ENOENT; for (i = 0; i < nr_symbols; i++) { asymbol *symbol = symbols[i]; if (!strcmp(bfd_asymbol_name(symbol), symbol_name)) return symbol; } return ERR_PTR(ret); }
/** * Load text symbols from the file into supplied table. * * @param bc the BFD context pointing to the file * @param st the symbol table where symbols should be added */ static void bfd_util_load_text(bfd_ctx_t *bc, symbols_t *st) { long i; asymbol* empty; void *p; bfd_ctx_check(bc); g_assert(st != NULL); if (0 == bc->count) return; mutex_lock_fast(&bc->lock); g_assert(bc->symbols != NULL); empty = bfd_make_empty_symbol(bc->handle); symbols_lock(st); for ( i = 0, p = bc->symbols; i < bc->count; i++, p = ptr_add_offset(p, bc->symsize) ) { asymbol *sym; symbol_info syminfo; sym = bfd_minisymbol_to_symbol(bc->handle, bc->dynamic, p, empty); bfd_get_symbol_info(bc->handle, sym, &syminfo); if ('T' == syminfo.type || 't' == syminfo.type) { const char *name = bfd_asymbol_name(sym); if (name != NULL && name[0] != '.') { void *addr = ulong_to_pointer(syminfo.value); symbols_append(st, addr, name); } } } symbols_unlock(st); mutex_unlock_fast(&bc->lock); }
/* search symbol */ int get_symbol_pos(const char* symbol_name, bfd* abfd, asymbol** syms, int symnum, char* file_o) { int i; int symbol_pos = 0; for (i = 0; i < symnum; i++) { asymbol *sym = syms[i]; const char *name = bfd_asymbol_name(sym); if (NULL == name || 0 == strlen(name) || '.' == name[0]) continue; if (0 == strcmp(name, symbol_name)) { LOG("[INFO] %s\n", name); int value = bfd_asymbol_value(sym); symbol_pos = (int)file_o + abfd->origin + sym->section->filepos + value; LOG("Found %s :0x%08X (absolute)\n", name, symbol_pos); break; } } return symbol_pos; }
long locate_dv_func(void) { asymbol **symbol_table; bfd *b = bfd_openr(oracle, NULL); if (b == NULL) { perror("bfd_openr"); exit(-1); } bfd_check_format(b, bfd_object); long storage_needed = bfd_get_symtab_upper_bound(b); if(storage_needed < 0) { fprintf(stderr, "wtf?!\n"); exit(-1); } if((symbol_table = (asymbol**)malloc(storage_needed)) == 0) { perror("malloc"); exit(-1); } int num_symbols; if((num_symbols = bfd_canonicalize_symtab(b, symbol_table)) <= 0) { fprintf(stderr, "no symbols info\n"); exit(-1); } int i; for(i = 0; i < num_symbols; i++) { char *symname = bfd_asymbol_name(symbol_table[i]); void *symaddr = bfd_asymbol_value(symbol_table[i]); /* don't even ask why this funciton, for real hardcore: gdb -p <oraclePIDs> */ if(!strcmp(symname, "kzvtins")) { fprintf(stderr, "[%d] symbol \"kzvtins\" at 0x%lx\n", getpid(), (long) symaddr); return (long) symaddr; } } return 0; }
void create_symbol_function_pos(char* file_o, bfd* abfd, asymbol** syms, int symnum) { int i; for (i = 0; i < symnum; i++) { asymbol *sym = syms[i]; const char *name = bfd_asymbol_name(sym); int value = bfd_asymbol_value(sym); symbol_info info; if (NULL == name || 0 == strlen(name) || '.' == name[0]) continue; LOG("[INFO] %s\n", name); bfd_get_symbol_info(abfd, sym, &info); /* 定義されたシンボルのみを探す */ if (!bfd_is_undefined_symclass(info.type)) { if (name[0] != '_') { int symbol_pos = 0; symbol_pos = abfd->origin + sym->section->filepos + value; LOG("Found %s :0x%08X (relative), ", name, symbol_pos); symbol_pos += (int)file_o; LOG("Found %s :0x%08X (absolute)\n", name, symbol_pos); add_symbol(name, symbol_pos); } } } }
SymbolTable::SymbolTable(string path) { //Open the file as binary file descriptor: bfd* descr = bfd_openr(path.c_str(), NULL); if (!descr) { throw runtime_error("Failed to open binary file descriptor."); } //Check the format of the file: if (!bfd_check_format(descr, bfd_object)) { bfd_close(descr); throw runtime_error("Failed to verify binary format."); } //Get the size of the symbol table: long symbolTableSize = bfd_get_symtab_upper_bound(descr); if (symbolTableSize <= 0) { bfd_close(descr); if (symbolTableSize < 0) { throw runtime_error("Failed to read the upper bound of the symbol table."); } else { return; } } //Alloc space for the table: asymbol** symbolTable = (asymbol**)malloc(symbolTableSize); if (!symbolTable) { bfd_close(descr); throw runtime_error("Failed to allocate space for the symbol table."); } //Get the number of symbols by canonicalizing the table: long symbolTableCount = bfd_canonicalize_symtab(descr, symbolTable); if (symbolTableCount < 0) { bfd_close(descr); free(symbolTable); throw runtime_error("Failed to read the number of symbols in the symbol table."); } //Iterate: for (int i = 0; i < symbolTableCount; i++) { //Is there a name? if (!symbolTable[i]->name) { continue; } //Get the symbol data: Symbol* newSymbol = new Symbol(string(bfd_asymbol_name(symbolTable[i])), (pword)bfd_asymbol_value(symbolTable[i])); //Check: if (!newSymbol) { throw runtime_error("Failed to allocate space for a symbol."); } this->table[newSymbol->getName()] = newSymbol; } //Close the file descriptor and free the table: bfd_close(descr); free(symbolTable); }
vine_symbols_t * get_symbols_of_file(const char *filename) { asymbol** syms = NULL; long symcount = 0; long sorted_symcount = 0; asymbol** dynsyms = NULL; long dynsymcount = 0; asymbol* synthsyms = NULL; long synthcount = 0; long storage; vector<vine_symbol_t *> *ret = new vector<vine_symbol_t *>(); // asm_program_t *prog = new asm_program_t; // printf("initializing bfd\n\n"); bfd *abfd = initialize_bfd(filename); // printf("done\n\n"); // printf("initializing sections...\n\n"); // initialize_sections(abfd, prog); // printf("done\n\n"); asymbol *sym; if (bfd_get_file_flags (abfd) & HAS_SYMS) { storage = bfd_get_symtab_upper_bound (abfd); assert (storage >= 0); if (storage > 0) syms = (asymbol**) xmalloc(storage); symcount = bfd_canonicalize_symtab (abfd, syms); assert (symcount >= 0); sorted_symcount = remove_useless_symbols(syms, symcount); qsort(syms, sorted_symcount, sizeof(asymbol *), compare_symbols); for(int i= 0; i < sorted_symcount; i++){ vine_symbol_t *temp = new vine_symbol_t; temp->name = string(bfd_asymbol_name((syms[i]))); temp->addr = bfd_asymbol_value((syms[i])); sym = syms[i]; temp->is_function = (sym->flags & BSF_FUNCTION) != 0; temp->is_dynamic = 0; ret->push_back(temp); } } storage = bfd_get_dynamic_symtab_upper_bound (abfd); if (storage > 0) { dynsyms = (asymbol**) xmalloc(storage); dynsymcount = bfd_canonicalize_dynamic_symtab (abfd, dynsyms); } synthcount = bfd_get_synthetic_symtab (abfd, symcount, syms, dynsymcount, dynsyms, &synthsyms); if (synthcount < 0) synthcount = 0; for (int i=0; i<synthcount; i++) { vine_symbol_t *temp = new vine_symbol_t; temp->name = string(bfd_asymbol_name(&(synthsyms[i]))); temp->addr = bfd_asymbol_value(&(synthsyms[i])); temp->is_function = (synthsyms[i].flags & BSF_FUNCTION) != 0; temp->is_dynamic = 1; ret->push_back(temp); } if (synthsyms) free(synthsyms); if (dynsyms) free(dynsyms); if (syms) free(syms); bfd_close(abfd); return ret; }
static bfd_boolean read_symbol_stabs_debugging_info (bfd *abfd, asymbol **syms, long symcount, void *dhandle, bfd_boolean *pfound) { void *shandle; asymbol **ps, **symend; shandle = NULL; symend = syms + symcount; for (ps = syms; ps < symend; ps++) { symbol_info i; bfd_get_symbol_info (abfd, *ps, &i); if (i.type == '-') { const char *s; char *f; if (shandle == NULL) { shandle = start_stab (dhandle, abfd, FALSE, syms, symcount); if (shandle == NULL) return FALSE; } *pfound = TRUE; s = i.name; f = NULL; while (s[strlen (s) - 1] == '\\' && ps + 1 < symend) { char *sc, *n; ++ps; sc = xstrdup (s); sc[strlen (sc) - 1] = '\0'; n = concat (sc, bfd_asymbol_name (*ps), (const char *) NULL); free (sc); if (f != NULL) free (f); f = n; s = n; } save_stab (i.stab_type, i.stab_desc, i.value, s); if (! parse_stab (dhandle, shandle, i.stab_type, i.stab_desc, i.value, s)) { stab_context (); free_saved_stabs (); return FALSE; } /* Don't free f, since I think the stabs code expects strings to hang around. This should be straightened out. FIXME. */ } } free_saved_stabs (); if (shandle != NULL) { if (! finish_stab (dhandle, shandle)) return FALSE; } return TRUE; }
static debug_type parse_coff_struct_type (bfd *abfd, struct coff_symbols *symbols, struct coff_types *types, int ntype, union internal_auxent *pauxent, void *dhandle) { long symend; int alloc; debug_field *fields; int count; bfd_boolean done; symend = pauxent->x_sym.x_fcnary.x_fcn.x_endndx.l; alloc = 10; fields = (debug_field *) xmalloc (alloc * sizeof *fields); count = 0; done = FALSE; while (! done && symbols->coff_symno < symend && symbols->symno < symbols->symcount) { asymbol *sym; long this_coff_symno; struct internal_syment syment; union internal_auxent auxent; union internal_auxent *psubaux; bfd_vma bitpos = 0, bitsize = 0; sym = symbols->syms[symbols->symno]; if (! bfd_coff_get_syment (abfd, sym, &syment)) { non_fatal (_("bfd_coff_get_syment failed: %s"), bfd_errmsg (bfd_get_error ())); return DEBUG_TYPE_NULL; } this_coff_symno = symbols->coff_symno; ++symbols->symno; symbols->coff_symno += 1 + syment.n_numaux; if (syment.n_numaux == 0) psubaux = NULL; else { if (! bfd_coff_get_auxent (abfd, sym, 0, &auxent)) { non_fatal (_("bfd_coff_get_auxent failed: %s"), bfd_errmsg (bfd_get_error ())); return DEBUG_TYPE_NULL; } psubaux = &auxent; } switch (syment.n_sclass) { case C_MOS: case C_MOU: bitpos = 8 * bfd_asymbol_value (sym); bitsize = 0; break; case C_FIELD: bitpos = bfd_asymbol_value (sym); bitsize = auxent.x_sym.x_misc.x_lnsz.x_size; break; case C_EOS: done = TRUE; break; } if (! done) { debug_type ftype; debug_field f; ftype = parse_coff_type (abfd, symbols, types, this_coff_symno, syment.n_type, psubaux, TRUE, dhandle); f = debug_make_field (dhandle, bfd_asymbol_name (sym), ftype, bitpos, bitsize, DEBUG_VISIBILITY_PUBLIC); if (f == DEBUG_FIELD_NULL) return DEBUG_TYPE_NULL; if (count + 1 >= alloc) { alloc += 10; fields = ((debug_field *) xrealloc (fields, alloc * sizeof *fields)); } fields[count] = f; ++count; } } fields[count] = DEBUG_FIELD_NULL; return debug_make_struct_type (dhandle, ntype == T_STRUCT, pauxent->x_sym.x_misc.x_lnsz.x_size, fields); }
void sim_disasm_one (void) { static int last_sym = -1; static const char * prev_filename = ""; static int prev_lineno = 0; const char * filename; const char * functionname; unsigned int lineno; int sym, bestaddr; int min, max, i; int save_trace = trace; int mypc = get_reg (pc); if (! sim_get_current_source_location (& filename, & functionname, & lineno)) return; trace = 0; if (filename && functionname && lineno) { if (lineno != prev_lineno || strcmp (prev_filename, filename)) { char * the_line = load_file_and_line (filename, lineno); const char * slash = strrchr (filename, '/'); if (!slash) slash = filename; else slash++; printf ("========================================" "=====================================\n"); printf ("\033[37;41m %s:%d: \033[33;40m %s\033[K\033[0m\n", slash, lineno, the_line); } prev_lineno = lineno; prev_filename = filename; } min = -1; max = symcount; while (min < max - 1) { bfd_vma sa; sym = (min + max) / 2; sa = bfd_asymbol_value (symtab[sym]); /*printf("checking %4d %08x %s\n", sym, sa, bfd_asymbol_name (symtab[sym])); */ if (sa > mypc) max = sym; else if (sa < mypc) min = sym; else { min = sym; break; } } if (min != -1 && min != last_sym) { bestaddr = bfd_asymbol_value (symtab[min]); printf ("\033[43;30m%s", bfd_asymbol_name (symtab[min])); if (bestaddr != mypc) printf ("+%d", mypc - bestaddr); printf (":\t\t\t\033[0m\n"); last_sym = min; #if 0 if (trace == 1) if (strcmp (bfd_asymbol_name (symtab[min]), "abort") == 0 || strcmp (bfd_asymbol_name (symtab[min]), "exit") == 0) trace = 0; #endif } opbuf[0] = 0; #ifdef CYCLE_ACCURATE printf ("\033[33m %04u %06x: ", (int)(regs.cycle_count % 10000), mypc); #else printf ("\033[33m %06x: ", mypc); #endif max = print_insn_rx (mypc, & info); for (i = 0; i < max; i++) { if (rx_big_endian) printf ("%02x", mem_get_qi ((mypc + i) ^ 3)); else printf ("%02x", mem_get_qi (mypc + i)); } do { printf (" "); i ++; } while (i < 6); printf ("%-16s ", opbuf); printf ("\033[0m\n"); trace = save_trace; }
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); }
main (int argc, char **argv) { bfd *ibfd, *obfd; asection *p; static asymbol **osympp, **delsympp; long symsize, symcount, delsymcount; int i; int c; int idx; struct add_reloc_struct *new_reloc; struct change_reloc_struct *new_change; struct delete_reloc_struct *new_delete; struct modify_byte_struct *new_modify; struct globalize_sym_struct *new_globalize; while ((c = getopt (argc, argv, "a:d:c:m:G:")) != -1) { switch (c) { case 'a': /* check to see if we have two args: name and loc */ if ((index(optarg, ',') == NULL) || (index(optarg, ',') != rindex(optarg, ','))) { fprintf(stderr, "usage: -a argument should be <symbolname>,<location>, not \"%s\"\n", optarg); exit(1); } /* record the add reloc command in the global array */ new_reloc = (add_reloc_struct *)malloc(sizeof(add_reloc_struct)); new_reloc->symbol_name = strndup(optarg, (index(optarg, ',') - optarg)); new_reloc->loc = strtol(index(optarg, ',') + 1, NULL, 0); if (errno == EINVAL) { fprintf(stderr, "the value %s is not a valid location for the add command\n", index(optarg, ',') + 1); exit(1); } new_reloc->next = additional_relocs; additional_relocs = new_reloc; break; case 'c': /* check to see if we have two args */ if ((index(optarg, ',') == NULL) || (index(optarg, ',') != rindex(optarg, ','))) { fprintf(stderr, "usage: -c argument should be <symbolname>,<symbolname>, not \"%s\"\n", optarg); exit(1); } new_change = (change_reloc_struct *)malloc(sizeof(change_reloc_struct)); new_change->old_symbol_name = strndup(optarg, strlen(optarg) - strlen(index(optarg, ','))); new_change->new_symbol_name = strdup(index(optarg, ',') + 1); new_change->next = change_relocs; change_relocs = new_change; break; case 'd': new_delete = (delete_reloc_struct *)malloc(sizeof(delete_reloc_struct)); new_delete->symbol_name = strdup(optarg); new_delete->next = delete_relocs; delete_relocs = new_delete; break; case 'm': if ((index(optarg, '=') == NULL) || (index(optarg, '=') != rindex(optarg, '='))) { fprintf(stderr, "usage: -m argument should be <location>=<value>, not \"%s\"\n", optarg); exit(1); } new_modify = (modify_byte_struct *)malloc(sizeof(modify_byte_struct)); new_modify->location = strtol(optarg, NULL, 0); new_modify->value = strtol(index(optarg, '=') + 1, NULL, 0); if (new_modify->value > 0xff) { fprintf(stderr, "requested modify value %lx for location %lx exceeds 0xff\n", new_modify->value, new_modify->location); exit(1); } new_modify->next = modify_bytes; modify_bytes = new_modify; break; case 'G': new_globalize = (globalize_sym_struct *)malloc(sizeof(globalize_sym_struct)); new_globalize->symbol_name = strdup(optarg); new_globalize->next = globalize_syms; globalize_syms = new_globalize; break; default: fprintf(stderr, "unrecognized argument character |%c|\n", c); } } if ((argc - optind) != 2) { fprintf(stderr, "usage: fixup_relocs [-a newsymbol,location] [-c oldsymbol,newsymbol] [-d symbol] infile.o outfile.o\n"); exit(1); } ibfd = bfd_openr(argv[optind], NULL); if (ibfd == NULL) { bfd_perror("while opening input object file"); exit(1); } /* if I don't do "check_format", there's no data in the bfd object. wtf? */ if (!bfd_check_format(ibfd, bfd_object)) { fprintf(stderr, "input file %s seems to NOT be an object file! exiting.\n", argv[optind]); exit(1); } obfd = bfd_openw(argv[optind+1], bfd_get_target(ibfd)); if (obfd == NULL) { bfd_perror("while opening output object file"); exit(1); } if (!bfd_set_format(obfd, bfd_get_format(ibfd))) { bfd_perror("while setting output object file format"); } /* copy a bunch of necessary global stuff */ bfd_set_start_address(obfd, bfd_get_start_address(ibfd)); bfd_set_file_flags(obfd, bfd_get_file_flags(ibfd)); bfd_set_arch_mach(obfd, bfd_get_arch(ibfd), bfd_get_mach(ibfd)); /* BOZO objcopy sets format again at this point. why? */ bfd_map_over_sections (ibfd, setup_section, obfd); setup_bfd_headers (ibfd, obfd); /* Symbol filtering must happen after the output sections have been created, but before their contents are set. */ symsize = bfd_get_symtab_upper_bound (ibfd); if (symsize < 0) { fprintf(stderr, "problem processing %s\n", bfd_get_filename (ibfd)); return FALSE; } /* count the added relocations so we can put extra space in the output symbol table for them */ int reloc_add_cnt, reloc_delete_cnt; reloc_add_cnt = 0; reloc_delete_cnt = 0; for (new_reloc = additional_relocs; new_reloc != NULL; new_reloc = new_reloc->next) { reloc_add_cnt++; } /* the "change" symbols might also not be in the symbol table yet */ for (new_change = change_relocs; new_change != NULL; new_change = new_change->next) { reloc_add_cnt++; /* the old symbol may be deleted, also */ reloc_delete_cnt++; } for (new_delete = delete_relocs; new_delete != NULL; new_delete = new_delete->next) { reloc_delete_cnt++; } /* filter symbol table in two steps: */ /* 1) move symbols bound for deletion to the end of the output symbol table array */ /* 2) truncate the table at the first of those */ /* this makes it possible to do the reloc processing with the symbol table intact, */ /* and remove the deleted symbols afterwards, without corrupting the reloc data structures */ isympp = malloc (symsize); osympp = malloc (symsize + reloc_add_cnt * sizeof(asymbol *)); delsympp = malloc (reloc_delete_cnt * sizeof(asymbol *)); symcount = bfd_canonicalize_symtab (ibfd, isympp); if (symcount < 0) { fprintf(stderr, "problem processing %s\n", bfd_get_filename (ibfd)); return FALSE; } /* remove any undefined symbols whose relocation entries were deleted or changed */ int osym_idx, delsym_idx; osym_idx = delsym_idx = 0; delsymcount = 0; for (i = 0; i < symcount; i++) { if ((is_delete_reloc(bfd_asymbol_name(isympp[i]), delete_relocs) || (find_change_reloc(bfd_asymbol_name(isympp[i]), change_relocs) != NULL)) && (isympp[i]->section != NULL) && (strcmp(isympp[i]->section->name, BFD_UND_SECTION_NAME) == 0)) { delsympp[delsym_idx++] = isympp[i]; } else { if (is_globalize_sym(bfd_asymbol_name(isympp[i]), globalize_syms)) { isympp[i]->flags = BSF_GLOBAL; } osympp[osym_idx++] = isympp[i]; } } symcount = osym_idx; delsymcount = delsym_idx; osympp[symcount] = NULL; /* add the symbols for additional relocs to the table */ int added_symbol_cnt = 0; for (new_reloc = additional_relocs; new_reloc != NULL; new_reloc = new_reloc->next) { if (find_symbol(osympp, new_reloc->symbol_name) < 0) { /* not yet present, so add it */ asymbol *new_sym; new_sym = bfd_make_empty_symbol(obfd); new_sym->name = strdup(new_reloc->symbol_name); new_sym->section = bfd_get_section_by_name (obfd, ".text"); new_sym->value = new_reloc->loc; new_sym->flags = BSF_GLOBAL; osympp[symcount + added_symbol_cnt++] = new_sym; osympp[symcount + added_symbol_cnt] = NULL; } } /* do the same for changed relocs */ for (new_change = change_relocs; new_change != NULL; new_change = new_change->next) { if (find_symbol(osympp, new_change->new_symbol_name) < 0) { /* not yet present, so add it */ /* since this is a name change, we will reuse the existing address (value field of reloc) */ int old_symbol_idx; if ((old_symbol_idx = find_symbol(isympp, new_change->old_symbol_name)) < 0) { fprintf(stderr, "change command old symbol name %s not found in symbol table! Exiting.\n", new_change->old_symbol_name); exit(1); } asymbol *new_sym; new_sym = bfd_make_empty_symbol(obfd); new_sym->name = strdup(new_change->new_symbol_name); new_sym->section = bfd_und_section_ptr; new_sym->value = isympp[old_symbol_idx]->value; new_sym->flags = BSF_GLOBAL; fprintf(stderr, "adding new symbol %s for change reloc command\n", new_sym->name); osympp[symcount + added_symbol_cnt++] = new_sym; osympp[symcount + added_symbol_cnt] = NULL; } } /* append the soon-to-be deleted symbols to the end of the output symbol table */ for (i = 0; i < delsymcount; i++) { osympp[symcount + added_symbol_cnt + i] = delsympp[i]; } osympp[symcount + added_symbol_cnt + delsymcount] = NULL; bfd_set_symtab (obfd, osympp, symcount + added_symbol_cnt + delsymcount); /* This has to happen after the symbol table has been set. */ bfd_map_over_sections (ibfd, copy_section_relocs_edit, obfd); /* now truncate the symbol table to eliminate the deleted symbols */ osympp[symcount + added_symbol_cnt] = NULL; bfd_set_symtab (obfd, osympp, symcount + added_symbol_cnt); /* now that we've set the relocs and cleaned the symtab, can call this */ bfd_map_over_sections (ibfd, copy_section_data, obfd); bfd_close(obfd); bfd_close(ibfd); return 0; }
static void extra_case (bfd *in_abfd, struct bfd_link_info *link_info, struct bfd_link_order *link_order, arelent *reloc, bfd_byte *data, unsigned int *src_ptr, unsigned int *dst_ptr) { asection * input_section = link_order->u.indirect.section; switch (reloc->howto->type) { case R_IMM8: bfd_put_8 (in_abfd, bfd_coff_reloc16_get_value (reloc, link_info, input_section), data + *dst_ptr); (*dst_ptr) += 1; (*src_ptr) += 1; break; case R_IMM32: /* If no flags are set, assume immediate value. */ if (! (*reloc->sym_ptr_ptr)->section->flags) { bfd_put_32 (in_abfd, bfd_coff_reloc16_get_value (reloc, link_info, input_section), data + *dst_ptr); } else { bfd_vma dst = bfd_coff_reloc16_get_value (reloc, link_info, input_section); /* Addresses are 23 bit, and the layout of those in a 32-bit value is as follows: 1AAAAAAA xxxxxxxx AAAAAAAA AAAAAAAA (A - address bits, x - ignore). */ dst = (dst & 0xffff) | ((dst & 0xff0000) << 8) | 0x80000000; bfd_put_32 (in_abfd, dst, data + *dst_ptr); } (*dst_ptr) += 4; (*src_ptr) += 4; break; case R_IMM4L: bfd_put_8 (in_abfd, ((bfd_get_8 (in_abfd, data + *dst_ptr) & 0xf0) | (0x0f & bfd_coff_reloc16_get_value (reloc, link_info, input_section))), data + *dst_ptr); (*dst_ptr) += 1; (*src_ptr) += 1; break; case R_IMM16: bfd_put_16 (in_abfd, bfd_coff_reloc16_get_value (reloc, link_info, input_section), data + *dst_ptr); (*dst_ptr) += 2; (*src_ptr) += 2; break; case R_JR: { bfd_vma dst = bfd_coff_reloc16_get_value (reloc, link_info, input_section); bfd_vma dot = (link_order->offset + *dst_ptr + input_section->output_section->vma); /* -1L, since we are in the odd byte of the word, and the pc has been * incremented: */ ptrdiff_t gap = ((ptrdiff_t)(dst - dot) - 1L); if (gap & 1L) abort(); gap /= 2L; if ((gap > 128L) || (gap < -128L)) { if (!((*link_info->callbacks->reloc_overflow) (link_info, NULL, bfd_asymbol_name(*reloc->sym_ptr_ptr), reloc->howto->name, reloc->addend, input_section->owner, input_section, reloc->address))) abort(); } bfd_put_8(in_abfd, gap, (data + *dst_ptr)); (*dst_ptr)++; (*src_ptr)++; break; } case R_DISP7: { bfd_vma dst = bfd_coff_reloc16_get_value (reloc, link_info, input_section); bfd_vma dot = (link_order->offset + *dst_ptr + input_section->output_section->vma); /* -1L, since we are in the odd byte of the word, and the pc has been * incremented: */ ptrdiff_t gap = ((ptrdiff_t)(dst - dot) - 1L); if (gap & 1L) abort(); gap /= 2L; if ((gap > 0L) || (gap < -127L)) { if (!((*link_info->callbacks->reloc_overflow) (link_info, NULL, bfd_asymbol_name(*reloc->sym_ptr_ptr), reloc->howto->name, reloc->addend, input_section->owner, input_section, reloc->address))) abort(); } bfd_put_8(in_abfd, (bfd_get_8(in_abfd, data + *dst_ptr) & 0x80) + (-gap & 0x7f), (data + *dst_ptr)); (*dst_ptr)++; (*src_ptr)++; break; } case R_CALLR: { bfd_vma dst = bfd_coff_reloc16_get_value (reloc, link_info, input_section); bfd_vma dot = (link_order->offset + *dst_ptr + input_section->output_section->vma); ptrdiff_t gap = ((ptrdiff_t)(dst - dot) - 2L); if (gap & 1L) abort(); if ((gap > 4096L) || (gap < -4095L)) { if (!((*link_info->callbacks->reloc_overflow) (link_info, NULL, bfd_asymbol_name(*reloc->sym_ptr_ptr), reloc->howto->name, reloc->addend, input_section->owner, input_section, reloc->address))) abort(); } gap /= 2L; bfd_put_16(in_abfd, ((bfd_get_16(in_abfd, (data + *dst_ptr)) & 0xf000) | (-gap & 0x0fff)), (data + *dst_ptr)); (*dst_ptr) += 2; (*src_ptr) += 2; break; } case R_REL16: { bfd_vma dst = bfd_coff_reloc16_get_value (reloc, link_info, input_section); bfd_vma dot = (link_order->offset + *dst_ptr + input_section->output_section->vma); ptrdiff_t gap = ((ptrdiff_t)(dst - dot) - 2L); if ((gap > 32767L) || (gap < -32768L)) { if (!((*link_info->callbacks->reloc_overflow) (link_info, NULL, bfd_asymbol_name(*reloc->sym_ptr_ptr), reloc->howto->name, reloc->addend, input_section->owner, input_section, reloc->address))) abort(); } bfd_put_16(in_abfd, (bfd_vma)gap, (data + *dst_ptr)); (*dst_ptr) += 2; (*src_ptr) += 2; break; } default: abort(); } }
/* ripped off from objdump.c, line 469 */ int compare_symbols(const void *ap, const void *bp) { const asymbol *a = * (const asymbol **) ap; const asymbol *b = * (const asymbol **) bp; const char *an; const char *bn; size_t anl; size_t bnl; bfd_boolean af; bfd_boolean bf; flagword aflags; flagword bflags; if (bfd_asymbol_value (a) > bfd_asymbol_value (b)) return 1; else if (bfd_asymbol_value (a) < bfd_asymbol_value (b)) return -1; if (a->section > b->section) return 1; else if (a->section < b->section) return -1; an = bfd_asymbol_name (a); bn = bfd_asymbol_name (b); anl = strlen (an); bnl = strlen (bn); /* The symbols gnu_compiled and gcc2_compiled convey no real information, so put them after other symbols with the same value. */ af = (strstr (an, "gnu_compiled") != NULL || strstr (an, "gcc2_compiled") != NULL); bf = (strstr (bn, "gnu_compiled") != NULL || strstr (bn, "gcc2_compiled") != NULL); if (af && ! bf) return 1; if (! af && bf) return -1; /* We use a heuristic for the file name, to try to sort it after more useful symbols. It may not work on non Unix systems, but it doesn't really matter; the only difference is precisely which symbol names get printed. */ #define file_symbol(s, sn, snl) \ (((s)->flags & BSF_FILE) != 0 \ || ((sn)[(snl) - 2] == '.' \ && ((sn)[(snl) - 1] == 'o' \ || (sn)[(snl) - 1] == 'a'))) af = file_symbol (a, an, anl); bf = file_symbol (b, bn, bnl); if (af && ! bf) return 1; if (! af && bf) return -1; aflags = a->flags; bflags = b->flags; if ((aflags & BSF_DEBUGGING) != (bflags & BSF_DEBUGGING)) { if ((aflags & BSF_DEBUGGING) != 0) return 1; else return -1; } if ((aflags & BSF_FUNCTION) != (bflags & BSF_FUNCTION)) { if ((aflags & BSF_FUNCTION) != 0) return -1; else return 1; } if ((aflags & BSF_LOCAL) != (bflags & BSF_LOCAL)) { if ((aflags & BSF_LOCAL) != 0) return 1; else return -1; } if ((aflags & BSF_GLOBAL) != (bflags & BSF_GLOBAL)) { if ((aflags & BSF_GLOBAL) != 0) return -1; else return 1; } /* Symbols that start with '.' might be section names, so sort them after symbols that don't start with '.'. */ if (an[0] == '.' && bn[0] != '.') return 1; if (an[0] != '.' && bn[0] == '.') return -1; /* Finally, if we can't distinguish them in any other way, try to get consistent results by sorting the symbols by name. */ return strcmp (an, bn); }
/* just reloc parts - data comes later */ static void copy_section_relocs_edit (bfd *ibfd, sec_ptr isection, void *obfdarg) { bfd *obfd = obfdarg; arelent **relpp; long relcount; sec_ptr osection; bfd_size_type size; long relsize; flagword flags; flags = bfd_get_section_flags (ibfd, isection); if ((flags & SEC_GROUP) != 0) return; osection = isection->output_section; size = bfd_get_section_size (isection); if (size == 0 || osection == 0) return; relsize = bfd_get_reloc_upper_bound (ibfd, isection); if (relsize <= 0) { /* not good */ bfd_perror("attempting to do relocs"); return; } relpp = malloc (relsize); relcount = bfd_canonicalize_reloc (ibfd, isection, relpp, isympp); /* copy each reloc, possibly removing or changing it on the fly */ arelent **temp_relpp; long temp_relcount = 0; long i; int msg_cnt = 0; struct change_reloc_struct *change_ptr; struct add_reloc_struct *new_reloc; asymbol **osympp; /* count new relocs to allocate space in reloc list */ int reloc_add_cnt; reloc_add_cnt = 0; for (new_reloc = additional_relocs; new_reloc != NULL; new_reloc = new_reloc->next) { reloc_add_cnt++; } osympp = bfd_get_outsymbols(obfd); /* note: cannot run mprobe on osympp b/c the copy contents will sometimes realloc it from internal BFD storage */ temp_relpp = malloc (relsize + reloc_add_cnt * sizeof(arelent *)); for (i = 0; i < relcount; i++) { if (is_delete_reloc(bfd_asymbol_name(*relpp[i]->sym_ptr_ptr), delete_relocs)) { continue; } else if ((change_ptr = find_change_reloc(bfd_asymbol_name(*relpp[i]->sym_ptr_ptr), change_relocs)) != NULL) { int sym_idx; sym_idx = find_symbol(osympp, change_ptr->new_symbol_name); if (sym_idx < 0) { fprintf(stderr, "internal error: could not find new symbol %s in output symbol table\n", change_ptr->new_symbol_name); exit(1); } relpp[i]->sym_ptr_ptr = &(osympp[sym_idx]); } temp_relpp [temp_relcount++] = relpp [i]; } /* now the additional relocs from the command line */ if (strcmp(bfd_get_section_name(ibfd, isection), ".text") == 0) { add_reloc_struct *add_reloc; for (add_reloc = additional_relocs; add_reloc != NULL; add_reloc = add_reloc->next) { arelent *new_reloc; int symbol_idx; new_reloc = malloc(sizeof(*new_reloc)); if ((symbol_idx = find_symbol(osympp, add_reloc->symbol_name)) < 0) { fprintf(stderr, "could not find symbol %s to perform a relocation! possible internal error\n", add_reloc->symbol_name); continue; } new_reloc->sym_ptr_ptr = &osympp[symbol_idx]; new_reloc->address = add_reloc->loc; new_reloc->addend = 0; /* never seemed to be used in my cursory investigation */ new_reloc->howto = bfd_reloc_type_lookup(ibfd, BFD_RELOC_32_PCREL); if (new_reloc->howto == NULL) { fprintf(stderr, "could not get howto back from bfd subsystem\n"); exit(1); } temp_relpp[temp_relcount++] = new_reloc; } } temp_relpp[temp_relcount] = NULL; relcount = temp_relcount; free (relpp); relpp = temp_relpp; bfd_set_reloc (obfd, osection, relcount == 0 ? NULL : relpp, relcount); if (relcount == 0) free (relpp); mcheck_check_all(); }
void leaky::ReadSymbols(const char *aFileName, u_long aBaseAddress) { int initialSymbols = usefulSymbols; if (nullptr == externalSymbols) { externalSymbols = (Symbol**) calloc(sizeof(Symbol*),10000); Symbol *new_array = new Symbol[10000]; for (int i = 0; i < 10000; i++) { externalSymbols[i] = &new_array[i]; } numExternalSymbols = 10000; } Symbol** sp = externalSymbols + usefulSymbols; lastSymbol = externalSymbols + numExternalSymbols; // Create a dummy symbol for the library so, if it doesn't have any // symbols, we show it by library. (*sp)->Init(aFileName, aBaseAddress); NEXT_SYMBOL; bfd_boolean kDynamic = (bfd_boolean) false; static int firstTime = 1; if (firstTime) { firstTime = 0; bfd_init (); } bfd* lib = bfd_openr(aFileName, nullptr); if (nullptr == lib) { return; } if (!bfd_check_format(lib, bfd_object)) { bfd_close(lib); return; } bfd *symbolFile = find_debug_file(lib, aFileName); // read mini symbols PTR minisyms; unsigned int size; long symcount = 0; if (symbolFile) { symcount = bfd_read_minisymbols(symbolFile, kDynamic, &minisyms, &size); if (symcount == 0) { bfd_close(symbolFile); } else { bfd_close(lib); } } if (symcount == 0) { symcount = bfd_read_minisymbols(lib, kDynamic, &minisyms, &size); if (symcount == 0) { // symtab is empty; try dynamic symbols kDynamic = (bfd_boolean) true; symcount = bfd_read_minisymbols(lib, kDynamic, &minisyms, &size); } symbolFile = lib; } asymbol* store; store = bfd_make_empty_symbol(symbolFile); // Scan symbols bfd_byte* from = (bfd_byte *) minisyms; bfd_byte* fromend = from + symcount * size; for (; from < fromend; from += size) { asymbol *sym; sym = bfd_minisymbol_to_symbol(symbolFile, kDynamic, (const PTR) from, store); symbol_info syminfo; bfd_get_symbol_info (symbolFile, sym, &syminfo); // if ((syminfo.type == 'T') || (syminfo.type == 't')) { const char* nm = bfd_asymbol_name(sym); if (nm && nm[0]) { char* dnm = nullptr; if (strncmp("__thunk", nm, 7)) { dnm = abi::__cxa_demangle(nm, 0, 0, 0); } (*sp)->Init(dnm ? dnm : nm, syminfo.value + aBaseAddress); if (dnm) { free(dnm); } NEXT_SYMBOL; } // } } bfd_close(symbolFile); int interesting = sp - externalSymbols; if (!quiet) { printf("%s provided %d symbols\n", aFileName, interesting - initialSymbols); } usefulSymbols = interesting; }
void msp430_trace_one (int mypc) { static int last_sym = -1; static const char * prev_filename = ""; static int prev_lineno = 0; const char * filename; const char * functionname; unsigned int lineno; int sym, bestaddr; int min, max, i; if (! msp430_get_current_source_location (mypc, & filename, & functionname, & lineno)) return; if (filename && functionname && lineno) { if (lineno != prev_lineno || strcmp (prev_filename, filename)) { char * the_line = load_file_and_line (filename, lineno); const char * slash = strrchr (filename, '/'); if (!slash) slash = filename; else slash ++; fprintf (stderr, "========================================" "=====================================\n"); fprintf (stderr, "\033[37;41m %s:%d: \033[33;40m %s\033[K\033[0m\n", slash, lineno, the_line); } prev_lineno = lineno; prev_filename = filename; } min = -1; max = symcount; while (min < max - 1) { bfd_vma sa; sym = (min + max) / 2; sa = bfd_asymbol_value (symtab[sym]); /*printf ("checking %4d %08x %s\n", sym, sa, bfd_asymbol_name (symtab[sym])); */ if (sa > mypc) max = sym; else if (sa < mypc) min = sym; else { min = sym; break; } } if (min != -1 && min != last_sym) { bestaddr = bfd_asymbol_value (symtab[min]); fprintf (stderr, "\033[43;30m%s", bfd_asymbol_name (symtab[min])); if (bestaddr != mypc) fprintf (stderr, "+%d", mypc - bestaddr); fprintf (stderr, ":\t\t\t\033[0m\n"); last_sym = min; #if 0 if (trace == 1) if (strcmp (bfd_asymbol_name (symtab[min]), "abort") == 0 || strcmp (bfd_asymbol_name (symtab[min]), "exit") == 0) trace = 0; #endif } }
void sim_disasm_one (void) { static int initted = 0; static asymbol **symtab = 0; static int symcount = 0; static int last_sym = -1; static struct disassemble_info info; int storage, sym, bestaddr; int min, max, i; static asection *code_section = 0; static bfd_vma code_base = 0; asection *s; int save_trace = trace; static const char *prev_filename = ""; static int prev_lineno = 0; const char *filename; const char *functionname; unsigned int lineno; int mypc = get_reg (pc); if (current_bfd == 0) return; trace = 0; if (!initted) { initted = 1; memset (&info, 0, sizeof (info)); INIT_DISASSEMBLE_INFO (info, stdout, op_printf); info.read_memory_func = sim_dis_read; info.arch = bfd_get_arch (current_bfd); info.mach = bfd_get_mach (current_bfd); if (info.mach == 0) { info.arch = bfd_arch_m32c; info.mach = default_machine; } disassemble_init_for_target (&info); storage = bfd_get_symtab_upper_bound (current_bfd); if (storage > 0) { symtab = (asymbol **) malloc (storage); symcount = bfd_canonicalize_symtab (current_bfd, symtab); symcount = remove_useless_symbols (symtab, symcount); qsort (symtab, symcount, sizeof (asymbol *), compare_symbols); } for (s = current_bfd->sections; s; s = s->next) { if (s->flags & SEC_CODE || code_section == 0) { code_section = s; code_base = bfd_section_lma (current_bfd, s); break; } } } filename = functionname = 0; lineno = 0; if (bfd_find_nearest_line (current_bfd, code_section, symtab, mypc - code_base, &filename, &functionname, &lineno)) { if (filename && functionname && lineno) { if (lineno != prev_lineno || strcmp (prev_filename, filename)) { char *the_line = load_file_and_line (filename, lineno); const char *slash = strrchr (filename, '/'); if (!slash) slash = filename; else slash++; printf ("========================================" "=====================================\n"); printf ("\033[37;41m %s:%d: \033[33;40m %s\033[K\033[0m\n", slash, lineno, the_line); } prev_lineno = lineno; prev_filename = filename; } } { min = -1; max = symcount; while (min < max - 1) { bfd_vma sa; sym = (min + max) / 2; sa = bfd_asymbol_value (symtab[sym]); /*printf("checking %4d %08x %s\n", sym, sa, bfd_asymbol_name (symtab[sym])); */ if (sa > mypc) max = sym; else if (sa < mypc) min = sym; else { min = sym; break; } } if (min != -1 && min != last_sym) { bestaddr = bfd_asymbol_value (symtab[min]); printf ("\033[43;30m%s", bfd_asymbol_name (symtab[min])); if (bestaddr != mypc) printf ("+%d", mypc - bestaddr); printf (":\t\t\t\033[0m\n"); last_sym = min; #if 0 if (trace == 1) if (strcmp (bfd_asymbol_name (symtab[min]), "abort") == 0 || strcmp (bfd_asymbol_name (symtab[min]), "exit") == 0) trace = 0; #endif } } opbuf[0] = 0; printf ("\033[33m%06x: ", mypc); max = print_insn_m32c (mypc, &info); for (i = 0; i < max; i++) printf ("%02x", mem_get_qi (mypc + i)); for (; i < 6; i++) printf (" "); printf ("%-16s ", opbuf); printf ("\033[0m\n"); trace = save_trace; }
int main(int argc, char *argv[]) { int i, f, size, symcnt, off; unsigned int fingerprint; int num_funcs = 0; int fancy_output = 0; int strip_names = 0; bfd *b; asymbol **syms; unsigned char buf[SIGNATSIZE+4]; char *nameptr; const char *short_options = "fsh"; struct option long_options[] = { {"fancy", no_argument, NULL, 'f'}, {"strip", no_argument, NULL, 's'}, {"help", no_argument, NULL, 'h'}, {0, no_argument, NULL, 0} }; while ((i = getopt_long(argc, argv, short_options, long_options, NULL)) != EOF) { switch (i) { case 'f': fancy_output = 1; break; case 's': strip_names = 1; break; case 'h': case '?': usage(argv[0]); /* never returns */ default: break; } } if (optind >= argc) { usage(argv[0]); /* never returns */ exit(1); } while (optind < argc) { b = bfd_openr(argv[optind++], 0); if (!b) { fprintf(stderr, "bfd_openr failed for '%s'\n", argv[optind - 1]); continue; } bfd_check_format(b, bfd_archive); bfd_check_format_matches(b, bfd_object, 0); if ((bfd_get_file_flags(b) & HAS_SYMS) == 0) { fprintf(stderr, (fancy_output) ? "EMPTY" : "No symbols.\n"); continue; } size = bfd_get_symtab_upper_bound(b); syms = (asymbol **) malloc(size); symcnt = bfd_canonicalize_symtab(b, syms); for (i = 0; i < symcnt; ++i) { if (syms[i]->flags & BSF_FUNCTION) { nameptr = (char *)(bfd_asymbol_name(syms[i])); if (strip_names!=0) { while (*nameptr == '_') { nameptr++; } } off = syms[i]->value; if (syms[i]->section) { off += syms[i]->section->filepos; } f = open(argv[optind - 1], O_RDONLY); lseek(f, off, SEEK_SET); num_funcs++; read(f, buf, SIGNATSIZE); fingerprint = fnprint_compute(buf); close(f); // Ignore only NOPs if (fingerprint != 0xA120AD5C) { printf("[%s+%d] %s %08X\n", argv[optind - 1], off, nameptr, fingerprint); } else { printf("\n"); } } } if (fancy_output) { fprintf(stderr, "%d function%s", num_funcs, PLURAL(num_funcs, "s")); } else { fprintf(stderr, "[*] %s: (%d function%s)\n", argv[optind - 1], num_funcs, PLURAL(num_funcs, "s")); } } return 0; }