std::vector<BuSymbolOwn> getSymbols(bfd* abfd, asymbol** symtab, size_t symcount) { std::vector<asymbol*> symbols = getSymbolsSortedFiltered(abfd, symtab, symcount); std::vector<BuSymbolOwn> result(symbols.size()); for (size_t i = 0; i < symbols.size(); ++i) { asymbol* sym = symbols[i]; symbol_info info; bfd_get_symbol_info(abfd, sym, &info); char* name = getDemangledName(abfd, info.name); BuSymbolOwn s; s.address = info.value; s.size = getSymbolPaddedSize(abfd, sym, (i + 1 < symbols.size()) ? symbols[i + 1] : nullptr); s.type = info.type; s.name = name; s.namestorage.reset(name); result[i] = std::move(s); } return std::move(result); }
extern void DEBUG_LoadSymbols( const char *name ) { bfd* abfd; char **matching; bfd_init(); abfd = bfd_openr(name, "default"); if (abfd == NULL) { barf("can't open executable %s to get symbol table", name); } if (!bfd_check_format_matches (abfd, bfd_object, &matching)) { barf("mismatch"); } { long storage_needed; asymbol **symbol_table; long number_of_symbols; long num_real_syms = 0; long i; storage_needed = bfd_get_symtab_upper_bound (abfd); if (storage_needed < 0) { barf("can't read symbol table"); } symbol_table = (asymbol **) stgMallocBytes(storage_needed,"DEBUG_LoadSymbols"); number_of_symbols = bfd_canonicalize_symtab (abfd, symbol_table); if (number_of_symbols < 0) { barf("can't canonicalise symbol table"); } if (add_to_fname_table == NULL) add_to_fname_table = allocHashTable(); for( i = 0; i != number_of_symbols; ++i ) { symbol_info info; bfd_get_symbol_info(abfd,symbol_table[i],&info); if (isReal(info.type, info.name)) { insertHashTable(add_to_fname_table, info.value, (void*)info.name); num_real_syms += 1; } } IF_DEBUG(interpreter, debugBelch("Loaded %ld symbols. Of which %ld are real symbols\n", number_of_symbols, num_real_syms) ); stgFree(symbol_table); } }
/** * 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); }
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); } } } }
static int core_sym_class (asymbol *sym) { symbol_info syminfo; const char *name; char sym_prefix; int i; if (sym->section == NULL || (sym->flags & BSF_DEBUGGING) != 0) return 0; /* Must be a text symbol, and static text symbols don't qualify if ignore_static_funcs set. */ if (ignore_static_funcs && (sym->flags & BSF_LOCAL)) { DBG (AOUTDEBUG, printf ("[core_sym_class] %s: not a function\n", sym->name)); return 0; } bfd_get_symbol_info (core_bfd, sym, &syminfo); i = syminfo.type; if (i == 'T') return i; /* It's a global symbol. */ if (i == 'W') /* Treat weak symbols as text symbols. FIXME: a weak symbol may also be a data symbol. */ return 'T'; if (i != 't') { /* Not a static text symbol. */ DBG (AOUTDEBUG, printf ("[core_sym_class] %s is of class %c\n", sym->name, i)); return 0; } /* Do some more filtering on static function-names. */ if (ignore_static_funcs) return 0; /* Can't zero-length name or funny characters in name, where `funny' includes: `.' (.o file names) and `$' (Pascal labels). */ if (!sym->name || sym->name[0] == '\0') return 0; for (name = sym->name; *name; ++name) { if (*name == '$') return 0; while (*name == '.') { /* Allow both nested subprograms (which end with ".NNN", where N is a digit) and GCC cloned functions (which contain ".clone"). Allow for multiple iterations of both - apparently GCC can clone clones and subprograms. */ int digit_seen = 0; #define CLONE_NAME ".clone." #define CLONE_NAME_LEN strlen (CLONE_NAME) if (strlen (name) > CLONE_NAME_LEN && strncmp (name, CLONE_NAME, CLONE_NAME_LEN) == 0) name += CLONE_NAME_LEN - 1; for (name++; *name; name++) if (digit_seen && *name == '.') break; else if (ISDIGIT (*name)) digit_seen = 1; else return 0; } } /* On systems where the C compiler adds an underscore to all names, static names without underscores seem usually to be labels in hand written assembler in the library. We don't want these names. This is certainly necessary on a Sparc running SunOS 4.1 (try profiling a program that does a lot of division). I don't know whether it has harmful side effects on other systems. Perhaps it should be made configurable. */ sym_prefix = bfd_get_symbol_leading_char (core_bfd); if ((sym_prefix && sym_prefix != sym->name[0]) /* GCC may add special symbols to help gdb figure out the file language. We want to ignore these, since sometimes they mask the real function. (dj@ctron) */ || !strncmp (sym->name, "__gnu_compiled", 14) || !strncmp (sym->name, "___gnu_compiled", 15)) { return 0; } /* If the object file supports marking of function symbols, then we can zap anything that doesn't have BSF_FUNCTION set. */ if (ignore_non_functions && (sym->flags & BSF_FUNCTION) == 0) return 0; return 't'; /* It's a static text symbol. */ }
static void BFDmanager_loadBFDdata (char *file, bfd **image, asymbol ***symbols, unsigned *nDataSymbols, data_symbol_t **DataSymbols) { bfd *bfdImage = NULL; asymbol **bfdSymbols = NULL; if (nDataSymbols) *nDataSymbols = 0; if (DataSymbols) *DataSymbols = NULL; /* Open the binary file in read-only mode */ bfdImage = bfd_openr (file, NULL); if (bfdImage == NULL) { const char *errmsg = bfd_errmsg (bfd_get_error()); fprintf (stderr, "mpi2prv: WARNING! Cannot open binary file '%s': %s.\n" " Addresses will not be translated into source code references\n", file, errmsg); return; } /* Check the binary file format */ if (!bfd_check_format (bfdImage, bfd_object)) { const char *errmsg = bfd_errmsg( bfd_get_error() ); fprintf (stderr, "mpi2prv: WARNING! Binary file format does not match for file '%s' : %s\n" " Addresses will not be translated into source code references\n", file, errmsg); } /* Load the mini-Symbol Table */ if (bfd_get_file_flags (bfdImage) & HAS_SYMS) { long symcount; size_t size = bfd_get_symtab_upper_bound (bfdImage); if (size > 0) { #if defined(BFD_MANAGER_GENERATE_ADDRESSES) long s; unsigned nDataSyms = 0; data_symbol_t *DataSyms = NULL; #endif bfdSymbols = (asymbol**) malloc (size); if (bfdSymbols == NULL) FATAL_ERROR ("Cannot allocate memory to translate addresses into source code references\n"); #if 0 /* HSG This is supposed to be space-efficient, but showed some errors .... :( */ symcount = bfd_read_minisymbols (bfdImage, FALSE, (PTR) bfdSymbols, &usize); if (symcount == 0) symcount = bfd_read_minisymbols (bfdImage, TRUE, (PTR) bfdSymbols, &usize); #else symcount = bfd_canonicalize_symtab (bfdImage, bfdSymbols); # if defined(BFD_MANAGER_GENERATE_ADDRESSES) if (nDataSymbols && DataSymbols) { for (s = 0; s < symcount; s++) { symbol_info syminfo; bfd_get_symbol_info (bfdImage, bfdSymbols[s], &syminfo); if (((bfdSymbols[s]->flags & BSF_DEBUGGING) == 0) && (syminfo.type == 'R' || syminfo.type == 'r' || /* read-only data */ syminfo.type == 'B' || syminfo.type == 'b' || /* uninited data */ syminfo.type == 'G' || syminfo.type == 'g' || /* inited data */ syminfo.type == 'C')) /* common data*/ { unsigned long long sz = 0; if (bfd_get_flavour(bfdImage) == bfd_target_elf_flavour) sz = ((elf_symbol_type*) bfdSymbols[s])->internal_elf_sym.st_size; DataSyms = (data_symbol_t*) realloc (DataSyms, sizeof(data_symbol_t)*(nDataSyms+1)); if (DataSyms == NULL) FATAL_ERROR ("Cannot allocate memory to allocate data symbols\n"); DataSyms[nDataSyms].name = strdup (syminfo.name); DataSyms[nDataSyms].address = (void*) syminfo.value; DataSyms[nDataSyms].size = sz; nDataSyms++; } } *nDataSymbols = nDataSyms; *DataSymbols = DataSyms; } # endif #endif if (symcount < 0) { /* There aren't symbols! */ const char *errmsg = bfd_errmsg( bfd_get_error() ); fprintf(stderr, "mpi2prv: WARNING! Cannot read symbol table for file '%s' : %s\n" " Addresses will not be translated into source code references\n", file, errmsg); } } } *image = bfdImage; *symbols = bfdSymbols; #if defined(DEBUG) printf ("BFD file=%s bfdImage = %p bfdSymbols = %p\n", file, bfdImage, bfdSymbols); #endif }
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; }
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; }