int main( int argc, char* argv[]) { //bfd_vma dis_addr; //disassemble_info info; //disassembler_ftype disassemble_fn; bfd *abfd; //BFD object char **matching, *target = NULL; extern bfd_target *bfd_target_vector[]; int x; if ( argc < 2) { printf("Usage: %s filename\n", argv[0]); return 1; } bfd_init (); abfd = bfd_openr(argv[1], target); if ( abfd == NULL) { printf("Unable to open %s\n", argv[1]); return 1;} else printf("Acquired target: %s\n", argv[1]); // -------------------------------------------BFD? if (! bfd_check_format_matches(abfd, bfd_object, &matching)){ printf("Unrecognized File!\n Supported targets: "); for ( x = 0; bfd_target_vector[x]; x++) { bfd_target *p = bfd_target_vector[x]; printf("%s ", p->name); } } else { printf("\nMapping %s sections...\n", abfd->filename); //iterate through the sections, using hdr_summary as a callback bfd_map_over_sections(abfd, hdr_summary, (PTR) NULL); printf(".....done\n"); } if (! bfd_close(abfd)) printf("Unable to close BFD!\n"); return 0; }
bfd_boolean bfd_check_format (bfd *abfd, bfd_format format) { return bfd_check_format_matches (abfd, format, NULL); }
void exec_file_attach (char *filename, int from_tty) { /* Remove any previous exec file. */ exec_close (); /* Now open and digest the file the user requested, if any. */ if (!filename) { if (from_tty) printf_unfiltered (_("No executable file now.\n")); set_gdbarch_from_file (NULL); } else { struct cleanup *cleanups; char *scratch_pathname, *canonical_pathname; int scratch_chan; struct target_section *sections = NULL, *sections_end = NULL; char **matching; scratch_chan = openp (getenv ("PATH"), OPF_TRY_CWD_FIRST, filename, write_files ? O_RDWR | O_BINARY : O_RDONLY | O_BINARY, &scratch_pathname); #if defined(__GO32__) || defined(_WIN32) || defined(__CYGWIN__) if (scratch_chan < 0) { char *exename = alloca (strlen (filename) + 5); strcat (strcpy (exename, filename), ".exe"); scratch_chan = openp (getenv ("PATH"), OPF_TRY_CWD_FIRST, exename, write_files ? O_RDWR | O_BINARY : O_RDONLY | O_BINARY, &scratch_pathname); } #endif if (scratch_chan < 0) perror_with_name (filename); cleanups = make_cleanup (xfree, scratch_pathname); /* gdb_bfd_open (and its variants) prefers canonicalized pathname for better BFD caching. */ canonical_pathname = gdb_realpath (scratch_pathname); make_cleanup (xfree, canonical_pathname); if (write_files) exec_bfd = gdb_bfd_fopen (canonical_pathname, gnutarget, FOPEN_RUB, scratch_chan); else exec_bfd = gdb_bfd_open (canonical_pathname, gnutarget, scratch_chan); if (!exec_bfd) { error (_("\"%s\": could not open as an executable file: %s"), scratch_pathname, bfd_errmsg (bfd_get_error ())); } gdb_assert (exec_filename == NULL); exec_filename = gdb_realpath_keepfile (scratch_pathname); if (!bfd_check_format_matches (exec_bfd, bfd_object, &matching)) { /* Make sure to close exec_bfd, or else "run" might try to use it. */ exec_close (); error (_("\"%s\": not in executable format: %s"), scratch_pathname, gdb_bfd_errmsg (bfd_get_error (), matching)); } if (build_section_table (exec_bfd, §ions, §ions_end)) { /* Make sure to close exec_bfd, or else "run" might try to use it. */ exec_close (); error (_("\"%s\": can't find the file sections: %s"), scratch_pathname, bfd_errmsg (bfd_get_error ())); } exec_bfd_mtime = bfd_get_mtime (exec_bfd); validate_files (); set_gdbarch_from_file (exec_bfd); /* Add the executable's sections to the current address spaces' list of sections. This possibly pushes the exec_ops target. */ add_target_sections (&exec_bfd, sections, sections_end); xfree (sections); /* Tell display code (if any) about the changed file name. */ if (deprecated_exec_file_display_hook) (*deprecated_exec_file_display_hook) (filename); do_cleanups (cleanups); } bfd_cache_close_all (); observer_notify_executable_changed (); }
int main(int argc, char *argv[]) { bfd *abfd; long storage_needed; asymbol **symbol_table; long number_of_symbols; long i; char **matching; sec_ptr section; char *symbol_name; long symbol_offset, section_vma, symbol_address; if (argc < 2) return 0; printf("Open %s\n", argv[1]); bfd_init(); abfd = bfd_openr(argv[1],NULL); if (abfd == (bfd *) 0) { bfd_perror("bfd_openr"); return -1; } if (!bfd_check_format_matches(abfd, bfd_object, &matching)) { return -1; } if (!(bfd_get_file_flags (abfd) & HAS_SYMS)) { printf("ERROR flag!\n"); return -1; } /* 取得符號表大小 */ storage_needed = bfd_get_symtab_upper_bound(abfd); if (storage_needed < 0) return -1; symbol_table = (asymbol **) xmalloc(storage_needed); /* 將符號表讀進所配置的記憶體裡(symbol_table), 並傳回符號表個數 */ number_of_symbols = bfd_canonicalize_symtab(abfd, symbol_table); if (number_of_symbols < 0) return -1; for (i = 0; i < number_of_symbols; i++) { /* 檢查此符號是否為函式 */ if (symbol_table[i]->flags & (BSF_FUNCTION|BSF_GLOBAL)) { /* 反查此函式所處的區段(section) 及 區段位址(section_vma) */ section = symbol_table[i]->section; section_vma = bfd_get_section_vma(abfd, section); /* 取得此函式的名稱(symbol_name)、 偏移位址(symbol_offset) */ symbol_name = symbol_table[i]->name; symbol_offset = symbol_table[i]->value; /* 將此函式的偏移位址加上區段位址,則為此函式在執行時 的記憶體位址(symbol_address */ symbol_address = section_vma + symbol_offset; /* 檢查此函式是否處在程式本文區段 */ if (section->flags & SEC_CODE) printf("<%s> 0x%x 0x%x 0x%x\n", symbol_name, section_vma, symbol_offset, symbol_address); } } bfd_close(abfd); }
extern void DEBUG_LoadSymbols( 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"); } #if 0 if (storage_needed == 0) { debugBelch("no storage needed"); } #endif 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"); } for( i = 0; i != number_of_symbols; ++i ) { symbol_info info; bfd_get_symbol_info(abfd,symbol_table[i],&info); /*debugBelch("\t%c\t0x%x \t%s\n",info.type,(nat)info.value,info.name); */ if (isReal(info.type, 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) ); reset_table( num_real_syms ); 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)) { insert( info.value, info.name ); } } stgFree(symbol_table); } prepare_table(); }
void exec_file_attach (const char *filename, int from_tty) { struct cleanup *cleanups; /* First, acquire a reference to the current exec_bfd. We release this at the end of the function; but acquiring it now lets the BFD cache return it if this call refers to the same file. */ gdb_bfd_ref (exec_bfd); cleanups = make_cleanup_bfd_unref (exec_bfd); /* Remove any previous exec file. */ exec_close (); /* Now open and digest the file the user requested, if any. */ if (!filename) { if (from_tty) printf_unfiltered (_("No executable file now.\n")); set_gdbarch_from_file (NULL); } else { int load_via_target = 0; char *scratch_pathname, *canonical_pathname; int scratch_chan; struct target_section *sections = NULL, *sections_end = NULL; char **matching; if (is_target_filename (filename)) { if (target_filesystem_is_local ()) filename += strlen (TARGET_SYSROOT_PREFIX); else load_via_target = 1; } if (load_via_target) { /* gdb_bfd_fopen does not support "target:" filenames. */ if (write_files) warning (_("writing into executable files is " "not supported for %s sysroots"), TARGET_SYSROOT_PREFIX); scratch_pathname = xstrdup (filename); make_cleanup (xfree, scratch_pathname); scratch_chan = -1; canonical_pathname = scratch_pathname; } else { scratch_chan = openp (getenv ("PATH"), OPF_TRY_CWD_FIRST, filename, write_files ? O_RDWR | O_BINARY : O_RDONLY | O_BINARY, &scratch_pathname); #if defined(__GO32__) || defined(_WIN32) || defined(__CYGWIN__) if (scratch_chan < 0) { char *exename = alloca (strlen (filename) + 5); strcat (strcpy (exename, filename), ".exe"); scratch_chan = openp (getenv ("PATH"), OPF_TRY_CWD_FIRST, exename, write_files ? O_RDWR | O_BINARY : O_RDONLY | O_BINARY, &scratch_pathname); } #endif if (scratch_chan < 0) perror_with_name (filename); make_cleanup (xfree, scratch_pathname); /* gdb_bfd_open (and its variants) prefers canonicalized pathname for better BFD caching. */ canonical_pathname = gdb_realpath (scratch_pathname); make_cleanup (xfree, canonical_pathname); } if (write_files && !load_via_target) exec_bfd = gdb_bfd_fopen (canonical_pathname, gnutarget, FOPEN_RUB, scratch_chan); else exec_bfd = gdb_bfd_open (canonical_pathname, gnutarget, scratch_chan); if (!exec_bfd) { error (_("\"%s\": could not open as an executable file: %s"), scratch_pathname, bfd_errmsg (bfd_get_error ())); } /* gdb_realpath_keepfile resolves symlinks on the local filesystem and so cannot be used for "target:" files. */ gdb_assert (exec_filename == NULL); if (load_via_target) exec_filename = xstrdup (bfd_get_filename (exec_bfd)); else exec_filename = gdb_realpath_keepfile (scratch_pathname); if (!bfd_check_format_matches (exec_bfd, bfd_object, &matching)) { /* Make sure to close exec_bfd, or else "run" might try to use it. */ exec_close (); error (_("\"%s\": not in executable format: %s"), scratch_pathname, gdb_bfd_errmsg (bfd_get_error (), matching)); } if (build_section_table (exec_bfd, §ions, §ions_end)) { /* Make sure to close exec_bfd, or else "run" might try to use it. */ exec_close (); error (_("\"%s\": can't find the file sections: %s"), scratch_pathname, bfd_errmsg (bfd_get_error ())); } exec_bfd_mtime = bfd_get_mtime (exec_bfd); validate_files (); set_gdbarch_from_file (exec_bfd); /* Add the executable's sections to the current address spaces' list of sections. This possibly pushes the exec_ops target. */ add_target_sections (&exec_bfd, sections, sections_end); xfree (sections); /* Tell display code (if any) about the changed file name. */ if (deprecated_exec_file_display_hook) (*deprecated_exec_file_display_hook) (filename); } do_cleanups (cleanups); bfd_cache_close_all (); observer_notify_executable_changed (); }
void exec_file_attach (char *filename, int from_tty) { /* Remove any previous exec file. */ exec_close (); /* Now open and digest the file the user requested, if any. */ if (!filename) { if (from_tty) printf_unfiltered (_("No executable file now.\n")); set_gdbarch_from_file (NULL); } else { struct cleanup *cleanups; char *scratch_pathname; int scratch_chan; struct target_section *sections = NULL, *sections_end = NULL; char **matching; scratch_chan = openp (getenv ("PATH"), OPF_TRY_CWD_FIRST, filename, write_files ? O_RDWR | O_BINARY : O_RDONLY | O_BINARY, &scratch_pathname); #if defined(__GO32__) || defined(_WIN32) || defined(__CYGWIN__) if (scratch_chan < 0) { char *exename = alloca (strlen (filename) + 5); strcat (strcpy (exename, filename), ".exe"); scratch_chan = openp (getenv ("PATH"), OPF_TRY_CWD_FIRST, exename, write_files ? O_RDWR | O_BINARY : O_RDONLY | O_BINARY, &scratch_pathname); } #endif if (scratch_chan < 0) perror_with_name (filename); exec_bfd = bfd_fopen (scratch_pathname, gnutarget, write_files ? FOPEN_RUB : FOPEN_RB, scratch_chan); if (!exec_bfd) { close (scratch_chan); error (_("\"%s\": could not open as an executable file: %s"), scratch_pathname, bfd_errmsg (bfd_get_error ())); } /* At this point, scratch_pathname and exec_bfd->name both point to the same malloc'd string. However exec_close() will attempt to free it via the exec_bfd->name pointer, so we need to make another copy and leave exec_bfd as the new owner of the original copy. */ scratch_pathname = xstrdup (scratch_pathname); cleanups = make_cleanup (xfree, scratch_pathname); if (!bfd_check_format_matches (exec_bfd, bfd_object, &matching)) { /* Make sure to close exec_bfd, or else "run" might try to use it. */ exec_close (); error (_("\"%s\": not in executable format: %s"), scratch_pathname, gdb_bfd_errmsg (bfd_get_error (), matching)); } /* FIXME - This should only be run for RS6000, but the ifdef is a poor way to accomplish. */ #ifdef DEPRECATED_IBM6000_TARGET /* Setup initial vmap. */ map_vmap (exec_bfd, 0); if (vmap == NULL) { /* Make sure to close exec_bfd, or else "run" might try to use it. */ exec_close (); error (_("\"%s\": can't find the file sections: %s"), scratch_pathname, bfd_errmsg (bfd_get_error ())); } #endif /* DEPRECATED_IBM6000_TARGET */ if (build_section_table (exec_bfd, §ions, §ions_end)) { /* Make sure to close exec_bfd, or else "run" might try to use it. */ exec_close (); error (_("\"%s\": can't find the file sections: %s"), scratch_pathname, bfd_errmsg (bfd_get_error ())); } exec_bfd_mtime = bfd_get_mtime (exec_bfd); validate_files (); set_gdbarch_from_file (exec_bfd); /* Add the executable's sections to the current address spaces' list of sections. This possibly pushes the exec_ops target. */ add_target_sections (sections, sections_end); xfree (sections); /* Tell display code (if any) about the changed file name. */ if (deprecated_exec_file_display_hook) (*deprecated_exec_file_display_hook) (filename); do_cleanups (cleanups); } bfd_cache_close_all (); observer_notify_executable_changed (); }
void DebugInfo::generatePidMapOverlay() { if (!m_perfMap || !pidMapOverlayStart) return; std::string self = current_executable_path(); bfd* abfd = bfd_openr(self.c_str(), nullptr); #ifdef BFD_DECOMPRESS abfd->flags |= BFD_DECOMPRESS; #endif char **match = nullptr; if (!bfd_check_format(abfd, bfd_archive) && bfd_check_format_matches(abfd, bfd_object, &match)) { std::vector<asymbol*> sorted; long storage_needed = bfd_get_symtab_upper_bound (abfd); if (storage_needed <= 0) return; auto symbol_table = (asymbol**)malloc(storage_needed); long number_of_symbols = bfd_canonicalize_symtab(abfd, symbol_table); for (long i = 0; i < number_of_symbols; i++) { auto sym = symbol_table[i]; if (sym->flags & (BSF_INDIRECT | BSF_SECTION_SYM | BSF_FILE | BSF_DEBUGGING_RELOC | BSF_OBJECT)) { continue; } auto sec = sym->section; if (!(sec->flags & (SEC_ALLOC|SEC_LOAD|SEC_CODE))) continue; auto addr = sec->vma + sym->value; if (addr < uintptr_t(pidMapOverlayStart) || addr >= uintptr_t(pidMapOverlayEnd)) { continue; } sorted.push_back(sym); } std::sort(sorted.begin(), sorted.end(), [](asymbol* a, asymbol* b) { auto addra = a->section->vma + a->value; auto addrb = b->section->vma + b->value; if (addra != addrb) return addra < addrb; return strncmp("_ZN4HPHP", a->name, 8) && !strncmp("_ZN4HPHP", b->name, 8); }); for (size_t i = 0; i < sorted.size(); i++) { auto sym = sorted[i]; auto addr = sym->section->vma + sym->value; int status; char* demangled = abi::__cxa_demangle(sym->name, nullptr, nullptr, &status); if (status != 0) demangled = const_cast<char*>(sym->name); unsigned size; if (i + 1 < sorted.size()) { auto s2 = sorted[i + 1]; size = s2->section->vma + s2->value - addr; } else { size = uintptr_t(pidMapOverlayEnd) - addr; } if (!size) continue; fprintf(m_perfMap, "%lx %x %s\n", long(addr), size, demangled); if (status == 0) free(demangled); } free(symbol_table); free(match); } bfd_close(abfd); return; }
struct compile_module * compile_object_load (const char *object_file, const char *source_file, enum compile_i_scope_types scope, void *scope_data) { struct cleanup *cleanups, *cleanups_free_objfile; bfd *abfd; struct setup_sections_data setup_sections_data; CORE_ADDR addr, regs_addr, out_value_addr = 0; struct symbol *func_sym; struct type *func_type; struct bound_minimal_symbol bmsym; long storage_needed; asymbol **symbol_table, **symp; long number_of_symbols, missing_symbols; struct type *dptr_type = builtin_type (target_gdbarch ())->builtin_data_ptr; unsigned dptr_type_len = TYPE_LENGTH (dptr_type); struct compile_module *retval; struct type *regs_type, *out_value_type = NULL; char *filename, **matching; struct objfile *objfile; int expect_parameters; struct type *expect_return_type; struct munmap_list *munmap_list_head = NULL; filename = tilde_expand (object_file); cleanups = make_cleanup (xfree, filename); abfd = gdb_bfd_open (filename, gnutarget, -1); if (abfd == NULL) error (_("\"%s\": could not open as compiled module: %s"), filename, bfd_errmsg (bfd_get_error ())); make_cleanup_bfd_unref (abfd); if (!bfd_check_format_matches (abfd, bfd_object, &matching)) error (_("\"%s\": not in loadable format: %s"), filename, gdb_bfd_errmsg (bfd_get_error (), matching)); if ((bfd_get_file_flags (abfd) & (EXEC_P | DYNAMIC)) != 0) error (_("\"%s\": not in object format."), filename); setup_sections_data.last_size = 0; setup_sections_data.last_section_first = abfd->sections; setup_sections_data.last_prot = -1; setup_sections_data.last_max_alignment = 1; setup_sections_data.munmap_list_headp = &munmap_list_head; make_cleanup (munmap_listp_free_cleanup, &munmap_list_head); bfd_map_over_sections (abfd, setup_sections, &setup_sections_data); setup_sections (abfd, NULL, &setup_sections_data); storage_needed = bfd_get_symtab_upper_bound (abfd); if (storage_needed < 0) error (_("Cannot read symbols of compiled module \"%s\": %s"), filename, bfd_errmsg (bfd_get_error ())); /* SYMFILE_VERBOSE is not passed even if FROM_TTY, user is not interested in "Reading symbols from ..." message for automatically generated file. */ objfile = symbol_file_add_from_bfd (abfd, filename, 0, NULL, 0, NULL); cleanups_free_objfile = make_cleanup_free_objfile (objfile); func_sym = lookup_global_symbol_from_objfile (objfile, GCC_FE_WRAPPER_FUNCTION, VAR_DOMAIN).symbol; if (func_sym == NULL) error (_("Cannot find function \"%s\" in compiled module \"%s\"."), GCC_FE_WRAPPER_FUNCTION, objfile_name (objfile)); func_type = SYMBOL_TYPE (func_sym); if (TYPE_CODE (func_type) != TYPE_CODE_FUNC) error (_("Invalid type code %d of function \"%s\" in compiled " "module \"%s\"."), TYPE_CODE (func_type), GCC_FE_WRAPPER_FUNCTION, objfile_name (objfile)); switch (scope) { case COMPILE_I_SIMPLE_SCOPE: expect_parameters = 1; expect_return_type = builtin_type (target_gdbarch ())->builtin_void; break; case COMPILE_I_RAW_SCOPE: expect_parameters = 0; expect_return_type = builtin_type (target_gdbarch ())->builtin_void; break; case COMPILE_I_PRINT_ADDRESS_SCOPE: case COMPILE_I_PRINT_VALUE_SCOPE: expect_parameters = 2; expect_return_type = builtin_type (target_gdbarch ())->builtin_void; break; default: internal_error (__FILE__, __LINE__, _("invalid scope %d"), scope); } if (TYPE_NFIELDS (func_type) != expect_parameters) error (_("Invalid %d parameters of function \"%s\" in compiled " "module \"%s\"."), TYPE_NFIELDS (func_type), GCC_FE_WRAPPER_FUNCTION, objfile_name (objfile)); if (!types_deeply_equal (expect_return_type, TYPE_TARGET_TYPE (func_type))) error (_("Invalid return type of function \"%s\" in compiled " "module \"%s\"."), GCC_FE_WRAPPER_FUNCTION, objfile_name (objfile)); /* The memory may be later needed by bfd_generic_get_relocated_section_contents called from default_symfile_relocate. */ symbol_table = obstack_alloc (&objfile->objfile_obstack, storage_needed); number_of_symbols = bfd_canonicalize_symtab (abfd, symbol_table); if (number_of_symbols < 0) error (_("Cannot parse symbols of compiled module \"%s\": %s"), filename, bfd_errmsg (bfd_get_error ())); missing_symbols = 0; for (symp = symbol_table; symp < symbol_table + number_of_symbols; symp++) { asymbol *sym = *symp; if (sym->flags != 0) continue; sym->flags = BSF_GLOBAL; sym->section = bfd_abs_section_ptr; if (strcmp (sym->name, "_GLOBAL_OFFSET_TABLE_") == 0) { if (compile_debug) fprintf_unfiltered (gdb_stdlog, "ELF symbol \"%s\" relocated to zero\n", sym->name); /* It seems to be a GCC bug, with -mcmodel=large there should be no need for _GLOBAL_OFFSET_TABLE_. Together with -fPIE the data remain PC-relative even with _GLOBAL_OFFSET_TABLE_ as zero. */ sym->value = 0; continue; } bmsym = lookup_minimal_symbol (sym->name, NULL, NULL); switch (bmsym.minsym == NULL ? mst_unknown : MSYMBOL_TYPE (bmsym.minsym)) { case mst_text: sym->value = BMSYMBOL_VALUE_ADDRESS (bmsym); if (compile_debug) fprintf_unfiltered (gdb_stdlog, "ELF mst_text symbol \"%s\" relocated to %s\n", sym->name, paddress (target_gdbarch (), sym->value)); break; case mst_text_gnu_ifunc: sym->value = gnu_ifunc_resolve_addr (target_gdbarch (), BMSYMBOL_VALUE_ADDRESS (bmsym)); if (compile_debug) fprintf_unfiltered (gdb_stdlog, "ELF mst_text_gnu_ifunc symbol \"%s\" " "relocated to %s\n", sym->name, paddress (target_gdbarch (), sym->value)); break; default: warning (_("Could not find symbol \"%s\" " "for compiled module \"%s\"."), sym->name, filename); missing_symbols++; } } if (missing_symbols) error (_("%ld symbols were missing, cannot continue."), missing_symbols); bfd_map_over_sections (abfd, copy_sections, symbol_table); regs_type = get_regs_type (func_sym, objfile); if (regs_type == NULL) regs_addr = 0; else { /* Use read-only non-executable memory protection. */ regs_addr = gdbarch_infcall_mmap (target_gdbarch (), TYPE_LENGTH (regs_type), GDB_MMAP_PROT_READ); gdb_assert (regs_addr != 0); munmap_list_add (&munmap_list_head, regs_addr, TYPE_LENGTH (regs_type)); if (compile_debug) fprintf_unfiltered (gdb_stdlog, "allocated %s bytes at %s for registers\n", paddress (target_gdbarch (), TYPE_LENGTH (regs_type)), paddress (target_gdbarch (), regs_addr)); store_regs (regs_type, regs_addr); } if (scope == COMPILE_I_PRINT_ADDRESS_SCOPE || scope == COMPILE_I_PRINT_VALUE_SCOPE) { out_value_type = get_out_value_type (func_sym, objfile, scope); if (out_value_type == NULL) { do_cleanups (cleanups); return NULL; } check_typedef (out_value_type); out_value_addr = gdbarch_infcall_mmap (target_gdbarch (), TYPE_LENGTH (out_value_type), (GDB_MMAP_PROT_READ | GDB_MMAP_PROT_WRITE)); gdb_assert (out_value_addr != 0); munmap_list_add (&munmap_list_head, out_value_addr, TYPE_LENGTH (out_value_type)); if (compile_debug) fprintf_unfiltered (gdb_stdlog, "allocated %s bytes at %s for printed value\n", paddress (target_gdbarch (), TYPE_LENGTH (out_value_type)), paddress (target_gdbarch (), out_value_addr)); } discard_cleanups (cleanups_free_objfile); retval = xmalloc (sizeof (*retval)); retval->objfile = objfile; retval->source_file = xstrdup (source_file); retval->func_sym = func_sym; retval->regs_addr = regs_addr; retval->scope = scope; retval->scope_data = scope_data; retval->out_value_type = out_value_type; retval->out_value_addr = out_value_addr; /* CLEANUPS will free MUNMAP_LIST_HEAD. */ retval->munmap_list_head = munmap_list_head; munmap_list_head = NULL; do_cleanups (cleanups); return retval; }
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; }
struct compile_module * compile_object_load (const char *object_file, const char *source_file) { struct cleanup *cleanups, *cleanups_free_objfile; bfd *abfd; struct setup_sections_data setup_sections_data; CORE_ADDR addr, func_addr, regs_addr; struct bound_minimal_symbol bmsym; long storage_needed; asymbol **symbol_table, **symp; long number_of_symbols, missing_symbols; struct type *dptr_type = builtin_type (target_gdbarch ())->builtin_data_ptr; unsigned dptr_type_len = TYPE_LENGTH (dptr_type); struct compile_module *retval; struct type *regs_type; char *filename, **matching; struct objfile *objfile; filename = tilde_expand (object_file); cleanups = make_cleanup (xfree, filename); abfd = gdb_bfd_open (filename, gnutarget, -1); if (abfd == NULL) error (_("\"%s\": could not open as compiled module: %s"), filename, bfd_errmsg (bfd_get_error ())); make_cleanup_bfd_unref (abfd); if (!bfd_check_format_matches (abfd, bfd_object, &matching)) error (_("\"%s\": not in loadable format: %s"), filename, gdb_bfd_errmsg (bfd_get_error (), matching)); if ((bfd_get_file_flags (abfd) & (EXEC_P | DYNAMIC)) != 0) error (_("\"%s\": not in object format."), filename); setup_sections_data.last_size = 0; setup_sections_data.last_section_first = abfd->sections; setup_sections_data.last_prot = -1; setup_sections_data.last_max_alignment = 1; bfd_map_over_sections (abfd, setup_sections, &setup_sections_data); setup_sections (abfd, NULL, &setup_sections_data); storage_needed = bfd_get_symtab_upper_bound (abfd); if (storage_needed < 0) error (_("Cannot read symbols of compiled module \"%s\": %s"), filename, bfd_errmsg (bfd_get_error ())); /* SYMFILE_VERBOSE is not passed even if FROM_TTY, user is not interested in "Reading symbols from ..." message for automatically generated file. */ objfile = symbol_file_add_from_bfd (abfd, filename, 0, NULL, 0, NULL); cleanups_free_objfile = make_cleanup_free_objfile (objfile); bmsym = lookup_minimal_symbol_text (GCC_FE_WRAPPER_FUNCTION, objfile); if (bmsym.minsym == NULL || MSYMBOL_TYPE (bmsym.minsym) == mst_file_text) error (_("Could not find symbol \"%s\" of compiled module \"%s\"."), GCC_FE_WRAPPER_FUNCTION, filename); func_addr = BMSYMBOL_VALUE_ADDRESS (bmsym); /* The memory may be later needed by bfd_generic_get_relocated_section_contents called from default_symfile_relocate. */ symbol_table = obstack_alloc (&objfile->objfile_obstack, storage_needed); number_of_symbols = bfd_canonicalize_symtab (abfd, symbol_table); if (number_of_symbols < 0) error (_("Cannot parse symbols of compiled module \"%s\": %s"), filename, bfd_errmsg (bfd_get_error ())); missing_symbols = 0; for (symp = symbol_table; symp < symbol_table + number_of_symbols; symp++) { asymbol *sym = *symp; if (sym->flags != 0) continue; if (compile_debug) fprintf_unfiltered (gdb_stdout, "lookup undefined ELF symbol \"%s\"\n", sym->name); sym->flags = BSF_GLOBAL; sym->section = bfd_abs_section_ptr; if (strcmp (sym->name, "_GLOBAL_OFFSET_TABLE_") == 0) { sym->value = 0; continue; } bmsym = lookup_minimal_symbol (sym->name, NULL, NULL); switch (bmsym.minsym == NULL ? mst_unknown : MSYMBOL_TYPE (bmsym.minsym)) { case mst_text: sym->value = BMSYMBOL_VALUE_ADDRESS (bmsym); break; default: warning (_("Could not find symbol \"%s\" " "for compiled module \"%s\"."), sym->name, filename); missing_symbols++; } } if (missing_symbols) error (_("%ld symbols were missing, cannot continue."), missing_symbols); bfd_map_over_sections (abfd, copy_sections, symbol_table); regs_type = get_regs_type (objfile); if (regs_type == NULL) regs_addr = 0; else { /* Use read-only non-executable memory protection. */ regs_addr = gdbarch_infcall_mmap (target_gdbarch (), TYPE_LENGTH (regs_type), GDB_MMAP_PROT_READ); gdb_assert (regs_addr != 0); store_regs (regs_type, regs_addr); } discard_cleanups (cleanups_free_objfile); do_cleanups (cleanups); retval = xmalloc (sizeof (*retval)); retval->objfile = objfile; retval->source_file = xstrdup (source_file); retval->func_addr = func_addr; retval->regs_addr = regs_addr; return retval; }
int main(int ac, char **av) { bfd *abfd; struct coff_ofile *tree; char **matching; char *input_file = NULL; int opt; static struct option long_options[] = { { "help", no_argument, 0, 'h' }, { "version", no_argument, 0, 'V' }, { NULL, no_argument, 0, 0 } }; #if defined(HAVE_SETLOCALE) && defined(HAVE_LC_MESSAGES) setlocale(LC_MESSAGES, ""); #endif /* HAVE_SETLOCALE && HAVE_LC_MESSAGES */ #if defined(HAVE_SETLOCALE) setlocale(LC_CTYPE, ""); #endif /* HAVE_SETLOCALE */ bindtextdomain(PACKAGE, LOCALEDIR); textdomain(PACKAGE); program_name = av[0]; xmalloc_set_program_name (program_name); while ((opt = getopt_long(ac, av, "HhVv", long_options, (int *)NULL)) != EOF) { switch (opt) { case 'H': case 'h': show_usage(stdout, 0); break; case 'v': case 'V': print_version("coffdump"); xexit(0); case 0: break; default: show_usage(stderr, 1); break; } } if (optind < ac) { input_file = av[optind]; } if (!input_file) fatal(_("no input file specified")); abfd = bfd_openr(input_file, 0); if (!abfd) bfd_fatal(input_file); if (! bfd_check_format_matches(abfd, bfd_object, &matching)) { bfd_nonfatal(input_file); if (bfd_get_error() == bfd_error_file_ambiguously_recognized) { list_matching_formats(matching); free(matching); } xexit(1); } tree = coff_grok(abfd); coff_dump(tree); printf("\n"); return 0; }