/* initialize bincode */ bincode_t *initialize_bincode(const char *file) { bfd *abfd; bincode_t *bin; //char *target = "x86_64-unknown-linux-gnu"; char *target = "i686-pc-linux-gnu"; bfd_init(); if (!bfd_set_default_target(target)) { bs_dbgmsg(" (!) bfd_set_default_target()\n"); return NULL; } if ((abfd = bfd_openr(file, target)) == NULL) { bs_dbgmsg(" (!) bfd_openr(): %s\n", file); return NULL; } if (!bfd_check_format(abfd, bfd_object)) { bs_dbgmsg(" (!) bfd_check_format()\n"); bfd_close(abfd); return NULL; } if((bin = malloc(sizeof(bincode_t))) == NULL) { bs_errmsg(" (!) malloc(): bin\n"); exit(EXIT_FAILURE); } bin->filename = strdup(abfd->filename); bin->abfd = abfd; bin->filesize = bfd_get_size(abfd); bin->start_addr = bfd_get_start_address(abfd); init_disasm_info(bin->abfd, &bin->disasm_info); bin->disasm_info.application_data = bin; initialize_section(bin); return bin; }
static struct bfd* new_bfd_internal( const char* filename, int arch, int machine ) { char** matching; enum bfd_architecture _arch = (enum bfd_architecture) arch; struct bfd* p = bfd_openr( filename, DEFAULT_TARGET ); const bfd_arch_info_type* info; if ( !p ) error_exit( "failure: bfd_openr" ); if ( _arch == bfd_arch_unknown ) { if ( bfd_check_format( p, bfd_archive ) ) { // TODO: add archive handling code bfd_close_all_done( p ); error_exit( "currently not supported." ); } if ( bfd_check_format_matches( p, bfd_object, &matching ) ) { return p; } if ( bfd_get_error() == bfd_error_file_ambiguously_recognized ) { bfd_close_all_done( p ); error_exit( "file format is ambiguosly matched" ); } if ( bfd_get_error() != bfd_error_file_not_recognized ) { bfd_close_all_done( p ); error_exit( "file is not recognized" ); } if ( bfd_check_format_matches( p, bfd_core, &matching ) ) { return p; } error_exit( "failed to load the given file" ); return NULL; /* this will never be called */ } else { info = bfd_lookup_arch( _arch, machine ); if ( !info ) error_exit( "failed to lookup archicture" ); bfd_set_arch_info( p, info ); return p; } }
// Define BFD-related global variables. static int define_bfd_vars(void) { bfd * bfd; bfd_boolean r; int len; #define MAX_PATHLENGTH 2048 char mypath[MAX_PATHLENGTH]; len = readlink("/proc/self/exe", mypath, sizeof(mypath)); if (len < 0) { fprintf(stderr, "libopagent: readlink /proc/self/exe failed\n"); return -1; } if (len >= MAX_PATHLENGTH) { fprintf(stderr, "libopagent: readlink /proc/self/exe returned" " path length longer than %d.\n", MAX_PATHLENGTH); return -1; } mypath[len] = '\0'; bfd_init(); bfd = bfd_openr(mypath, NULL); if (bfd == NULL) { bfd_perror("bfd_openr error. Cannot get required BFD info"); return -1; } r = bfd_check_format(bfd, bfd_object); if (!r) { bfd_perror("bfd_get_arch error. Cannot get required BFD info"); return -1; } _bfd_target_name = bfd->xvec->name; _bfd_arch = bfd_get_arch(bfd); _bfd_mach = bfd_get_mach(bfd); return 0; }
int init_bfd_ctx(bfd_ctx * bc, PCWSTR procname) { LogTrace(); bc->handle = NULL; bc->symbol = NULL; LogTrace(); bfd *b = bfd_openr(Base::w2cp(procname, CP_OEMCP).c_str(), 0); if (!b) { LogFatal(L"Failed to open bfd from (%s)\n" , procname); return 1; } int r1 = bfd_check_format(b, bfd_object); int r2 = bfd_check_format_matches(b, bfd_object, NULL); int r3 = bfd_get_file_flags(b) & HAS_SYMS; if (!(r1 && r2 && r3)) { bfd_close(b); LogFatal(L"Failed to init bfd from (%s)\n", procname); return 1; } void * symbol_table; unsigned dummy = 0; if (bfd_read_minisymbols(b, FALSE, &symbol_table, &dummy) == 0) { if (bfd_read_minisymbols(b, TRUE, &symbol_table, &dummy) < 0) { free(symbol_table); bfd_close(b); LogFatal(L"Failed to read symbols from (%s)\n", procname); return 1; } } bc->handle = b; bc->symbol = (asymbol**)symbol_table; return 0; }
static int init_bfd_ctx(struct bfd_ctx *bc, const char * procname, struct output_buffer *ob) { bc->handle = NULL; bc->symbol = NULL; bfd *b = bfd_openr(procname, 0); if (!b) { output_print(ob,"Failed to open bfd from (%s)\n" , procname); return 1; } int r1 = bfd_check_format(b, bfd_object); int r2 = bfd_check_format_matches(b, bfd_object, NULL); int r3 = bfd_get_file_flags(b) & HAS_SYMS; if (!(r1 && r2 && r3)) { bfd_close(b); output_print(ob,"Failed to init bfd from (%s)\n", procname); return 1; } void *symbol_table; unsigned dummy = 0; if (bfd_read_minisymbols(b, FALSE, &symbol_table, &dummy) == 0) { if (bfd_read_minisymbols(b, TRUE, &symbol_table, &dummy) < 0) { free(symbol_table); bfd_close(b); output_print(ob,"Failed to read symbols from (%s)\n", procname); return 1; } } bc->handle = b; bc->symbol = symbol_table; return 0; }
int main (int argc, char **argv) { bfd *archive; bfd *last, *next; if (argc != 2) die ("bad usage"); archive = bfd_openr (argv[1], NULL); if (!bfd_check_format (archive, bfd_archive)) { bfd_close (archive); die ("bfd_check_format"); } for (last = bfd_openr_next_archived_file (archive, NULL); last; last = next) { next = bfd_openr_next_archived_file (archive, last); bfd_close (last); } for (last = bfd_openr_next_archived_file (archive, NULL); last; last = next) { next = bfd_openr_next_archived_file (archive, last); bfd_close (last); } if (!bfd_close (archive)) die ("bfd_close"); return 0; }
static bfd_cache_ptr get_bfd_cache(const char *filename) { bfdMap::const_iterator iter = s_bfds.find(filename); if (iter != s_bfds.end()) { return iter->second; } bfd_cache_ptr p(new bfd_cache()); bfd *abfd = bfd_openr(filename, NULL); if (abfd) { p->abfd = abfd; p->syms = NULL; char **match; if (bfd_check_format(abfd, bfd_archive) || !bfd_check_format_matches(abfd, bfd_object, &match) || !slurp_symtab(&p->syms, abfd)) { bfd_close(abfd); p.reset(); } } else { p.reset(); } s_bfds[filename] = p; return p; }
bfd * initialize_bfd(const char *filename) { bfd * abfd; char **matching; char *target = "i686-pc-linux-gnu"; bfd_init(); if(!bfd_set_default_target(target)) fatal("program::initialize", "couldn't set default bfd target"); abfd = bfd_openr(filename, target); if(abfd == NULL) fatal("initialize_bfd", "cannot open %s", filename); if (bfd_check_format (abfd, bfd_archive)) fatal("initalize_bfd", "archive files not supported\n"); if(!bfd_check_format_matches(abfd, bfd_object, &matching)) fatal("initialize_bfd", "bfd_check_format_matches failed"); return abfd; }
static bfd * spu_bfd_fopen (char *name, CORE_ADDR addr) { bfd *nbfd; CORE_ADDR *open_closure = XNEW (CORE_ADDR); *open_closure = addr; nbfd = gdb_bfd_openr_iovec (name, "elf32-spu", spu_bfd_iovec_open, open_closure, spu_bfd_iovec_pread, spu_bfd_iovec_close, spu_bfd_iovec_stat); if (!nbfd) return NULL; if (!bfd_check_format (nbfd, bfd_object)) { gdb_bfd_unref (nbfd); return NULL; } return nbfd; }
bfd * open_bfd_matching_arch (bfd *archive_bfd, bfd_format expected_format) { enum gdb_osabi osabi; bfd *abfd; osabi = GDB_OSABI_UNINITIALIZED; abfd = NULL; osabi = gdbarch_osabi (get_current_arch ()); if ((osabi <= GDB_OSABI_UNKNOWN) || (osabi >= GDB_OSABI_INVALID)) osabi = gdbarch_lookup_osabi (archive_bfd); // FIXME: gdbarch_lookup_osabi() doesn't work yet on archive_bfd, hardcode if ((osabi <= GDB_OSABI_UNKNOWN) || (osabi >= GDB_OSABI_INVALID)) osabi = GDB_OSABI_DARWIN; for (;;) { abfd = bfd_openr_next_archived_file (archive_bfd, abfd); if (abfd == NULL) break; if (! bfd_check_format (abfd, expected_format)) continue; if (osabi == gdbarch_lookup_osabi_from_bfd (abfd)) break; } // Copy the filename of the archive to the binary bfd. if (abfd) { xfree(abfd->filename); abfd->filename = archive_bfd->filename; } return abfd; }
traceback::Bfd::Context::Context(const char* image) : image(cstr::dup(image)), handle(), symbol() { LogTraceObj("(%s)", image); bfd* b = bfd_openr(image, 0); if (!b) { LogError("Failed to open bfd from (%s)", image); return; } auto r1 = bfd_check_format(b, bfd_object); auto r2 = bfd_check_format_matches(b, bfd_object, NULL); auto r3 = bfd_get_file_flags(b) & HAS_SYMS; if (!(r1 && r2 && r3)) { bfd_close(b); LogError("Failed to init bfd from (%d, %d, %d) (%s)", r1, r2, r3, image); return; } void* symbol_table = nullptr; unsigned dummy = 0; if (bfd_read_minisymbols(b, FALSE, &symbol_table, &dummy) == 0) { if (bfd_read_minisymbols(b, TRUE, &symbol_table, &dummy) < 0) { free(symbol_table); bfd_close(b); LogError("Failed to read symbols from (%s)", image); return; } } handle = b; symbol = (asymbol**)symbol_table; }
/* Read in the symbol table. */ static int _symtab_init (struct symtab *symtab, const char *filename) { char **matching; long symcount; unsigned int size; symtab->bfd = NULL; symtab->syms = NULL; symtab->bfd = bfd_openr (filename, NULL); if (symtab->bfd == NULL) goto BAIL; if (bfd_check_format (symtab->bfd, bfd_archive)) goto BAIL; if (! bfd_check_format_matches (symtab->bfd, bfd_object, &matching)) goto BAIL; symcount = bfd_read_minisymbols (symtab->bfd, false, (PTR) &symtab->syms, &size); if (symcount == 0) { symcount = bfd_read_minisymbols (symtab->bfd, true /* dynamic */ , (PTR) &symtab->syms, &size); } if (symcount < 0) goto BAIL; if ((bfd_get_file_flags (symtab->bfd) & HAS_SYMS) == 0) goto BAIL; return 1; BAIL: _symtab_fini (symtab); return 0; }
void Archive::Read(const char* filename, Symbol::SymbolIndex_t& symbolIndex) { char *target = 0; bfd *file; file = bfd_openr (filename, target); if (file == 0) { // bfd_nonfatal (filename); // return FALSE; } if (bfd_check_format (file, bfd_archive)) { // display_archive (file); bfd *arfile = 0; std::cout << "file " << bfd_get_filename (file) << std::endl; while(arfile = bfd_openr_next_archived_file (file, arfile)) { const char* objectname = bfd_get_filename (arfile); ObjectFile* o = new ObjectFile(objectname, symbolIndex); o->SetParent(*this); o->Read(arfile); std::cout << "file " << bfd_get_filename (arfile) << std::endl; } if (arfile == NULL) { //if (bfd_get_error () != bfd_error_no_more_archived_files) //bfd_fatal (bfd_get_filename (file)); //break; } } }
bool ElfFile::readExports() { long storage_needed; asymbol **symbol_table; long number_of_symbols; long i; m_symbols.clear(); bfd_set_default_target("bfd_target_elf_flavour"); m_bfd = bfd_openr(m_name.toStdString().c_str(),NULL); if(!bfd_check_format(m_bfd,bfd_object)) { return false; } storage_needed = bfd_get_symtab_upper_bound(m_bfd); symbol_table = (asymbol **)malloc(storage_needed); number_of_symbols = bfd_canonicalize_symtab(m_bfd, symbol_table); qDebug() << "Number of symbols " << number_of_symbols; for(i = 0; i < number_of_symbols; i++) { m_symbols << SymbolDescription( symbol_table[i]->section->name, symbol_table[i]->name, symbol_table[i]->flags, symbol_table[i]->value); qDebug() << "found " << symbol_table[i]->name; } free(symbol_table); symbol_table = NULL; return true; }
static bfd * initialize_bfd(const char *filename) { bfd * abfd; char **matching; char *target = "i686-pc-linux-gnu"; bfd_init(); if(!bfd_set_default_target(target)) { fprintf(stderr, "initialize_bfd: couldn't set default bfd target\n"); return NULL; } abfd = bfd_openr(filename, target); if(abfd == NULL) { fprintf(stderr, "initialize_bfd: cannot open %s\n", filename); return NULL; } if (bfd_check_format (abfd, bfd_archive)) { fprintf(stderr, "initalize_bfd: archive files not supported\n"); bfd_close_all_done(abfd); return NULL; } /* if(!bfd_check_format_matches(abfd, bfd_object, &matching)) { */ if( (!bfd_check_format_matches(abfd, bfd_object, &matching)) && (!bfd_check_format_matches(abfd, bfd_core, &matching)) ) { fprintf(stderr, "initialize_bfd: bfd_check_format_matches failed\n"); bfd_close_all_done(abfd); return NULL; } return abfd; }
static void core_open (char *filename, int from_tty) { const char *p; int siggy; struct cleanup *old_chain; char *temp; bfd *temp_bfd; int scratch_chan; int flags; volatile struct gdb_exception except; target_preopen (from_tty); if (!filename) { if (core_bfd) error (_("No core file specified. (Use `detach' " "to stop debugging a core file.)")); else error (_("No core file specified.")); } filename = tilde_expand (filename); if (!IS_ABSOLUTE_PATH (filename)) { temp = concat (current_directory, "/", filename, (char *) NULL); xfree (filename); filename = temp; } old_chain = make_cleanup (xfree, filename); flags = O_BINARY | O_LARGEFILE; if (write_files) flags |= O_RDWR; else flags |= O_RDONLY; scratch_chan = open (filename, flags, 0); if (scratch_chan < 0) perror_with_name (filename); temp_bfd = bfd_fopen (filename, gnutarget, write_files ? FOPEN_RUB : FOPEN_RB, scratch_chan); if (temp_bfd == NULL) perror_with_name (filename); if (!bfd_check_format (temp_bfd, bfd_core) && !gdb_check_format (temp_bfd)) { /* Do it after the err msg */ /* FIXME: should be checking for errors from bfd_close (for one thing, on error it does not free all the storage associated with the bfd). */ make_cleanup_bfd_close (temp_bfd); error (_("\"%s\" is not a core dump: %s"), filename, bfd_errmsg (bfd_get_error ())); } /* Looks semi-reasonable. Toss the old core file and work on the new. */ discard_cleanups (old_chain); /* Don't free filename any more */ unpush_target (&core_ops); core_bfd = temp_bfd; old_chain = make_cleanup (core_close_cleanup, 0 /*ignore*/); /* FIXME: kettenis/20031023: This is very dangerous. The CORE_GDBARCH that results from this call may very well be different from CURRENT_GDBARCH. However, its methods may only work if it is selected as the current architecture, because they rely on swapped data (see gdbarch.c). We should get rid of that swapped data. */ core_gdbarch = gdbarch_from_bfd (core_bfd); /* Find a suitable core file handler to munch on core_bfd */ core_vec = sniff_core_bfd (core_bfd); validate_files (); core_data = XZALLOC (struct target_section_table); /* Find the data section */ if (build_section_table (core_bfd, &core_data->sections, &core_data->sections_end)) error (_("\"%s\": Can't find sections: %s"), bfd_get_filename (core_bfd), bfd_errmsg (bfd_get_error ())); /* If we have no exec file, try to set the architecture from the core file. We don't do this unconditionally since an exec file typically contains more information that helps us determine the architecture than a core file. */ if (!exec_bfd) set_gdbarch_from_file (core_bfd); push_target (&core_ops); discard_cleanups (old_chain); /* Do this before acknowledging the inferior, so if post_create_inferior throws (can happen easilly if you're loading a core file with the wrong exec), we aren't left with threads from the previous inferior. */ init_thread_list (); inferior_ptid = null_ptid; /* Need to flush the register cache (and the frame cache) from a previous debug session. If inferior_ptid ends up the same as the last debug session --- e.g., b foo; run; gcore core1; step; gcore core2; core core1; core core2 --- then there's potential for get_current_regcache to return the cached regcache of the previous session, and the frame cache being stale. */ registers_changed (); /* Build up thread list from BFD sections, and possibly set the current thread to the .reg/NN section matching the .reg section. */ bfd_map_over_sections (core_bfd, add_to_thread_list, bfd_get_section_by_name (core_bfd, ".reg")); if (ptid_equal (inferior_ptid, null_ptid)) { /* Either we found no .reg/NN section, and hence we have a non-threaded core (single-threaded, from gdb's perspective), or for some reason add_to_thread_list couldn't determine which was the "main" thread. The latter case shouldn't usually happen, but we're dealing with input here, which can always be broken in different ways. */ struct thread_info *thread = first_thread_of_process (-1); if (thread == NULL) { inferior_appeared (current_inferior (), CORELOW_PID); inferior_ptid = pid_to_ptid (CORELOW_PID); add_thread_silent (inferior_ptid); } else switch_to_thread (thread->ptid); } post_create_inferior (&core_ops, from_tty); /* Now go through the target stack looking for threads since there may be a thread_stratum target loaded on top of target core by now. The layer above should claim threads found in the BFD sections. */ TRY_CATCH (except, RETURN_MASK_ERROR) { target_find_new_threads (); } if (except.reason < 0) exception_print (gdb_stderr, except); p = bfd_core_file_failing_command (core_bfd); if (p) printf_filtered (_("Core was generated by `%s'.\n"), p); siggy = bfd_core_file_failing_signal (core_bfd); if (siggy > 0) { /* If we don't have a CORE_GDBARCH to work with, assume a native core (map gdb_signal from host signals). If we do have CORE_GDBARCH to work with, but no gdb_signal_from_target implementation for that gdbarch, as a fallback measure, assume the host signal mapping. It'll be correct for native cores, but most likely incorrect for cross-cores. */ enum gdb_signal sig = (core_gdbarch != NULL && gdbarch_gdb_signal_from_target_p (core_gdbarch) ? gdbarch_gdb_signal_from_target (core_gdbarch, siggy) : gdb_signal_from_host (siggy)); printf_filtered (_("Program terminated with signal %d, %s.\n"), siggy, gdb_signal_to_string (sig)); } /* Fetch all registers from core file. */ target_fetch_registers (get_current_regcache (), -1); /* Now, set up the frame cache, and print the top of stack. */ reinit_frame_cache (); print_stack_frame (get_selected_frame (NULL), 1, SRC_AND_LOC); }
static void core_open (const char *arg, int from_tty) { const char *p; int siggy; struct cleanup *old_chain; char *temp; int scratch_chan; int flags; char *filename; target_preopen (from_tty); if (!arg) { if (core_bfd) error (_("No core file specified. (Use `detach' " "to stop debugging a core file.)")); else error (_("No core file specified.")); } filename = tilde_expand (arg); if (!IS_ABSOLUTE_PATH (filename)) { temp = concat (current_directory, "/", filename, (char *) NULL); xfree (filename); filename = temp; } old_chain = make_cleanup (xfree, filename); flags = O_BINARY | O_LARGEFILE; if (write_files) flags |= O_RDWR; else flags |= O_RDONLY; scratch_chan = gdb_open_cloexec (filename, flags, 0); if (scratch_chan < 0) perror_with_name (filename); gdb_bfd_ref_ptr temp_bfd (gdb_bfd_fopen (filename, gnutarget, write_files ? FOPEN_RUB : FOPEN_RB, scratch_chan)); if (temp_bfd == NULL) perror_with_name (filename); if (!bfd_check_format (temp_bfd.get (), bfd_core) && !gdb_check_format (temp_bfd.get ())) { /* Do it after the err msg */ /* FIXME: should be checking for errors from bfd_close (for one thing, on error it does not free all the storage associated with the bfd). */ error (_("\"%s\" is not a core dump: %s"), filename, bfd_errmsg (bfd_get_error ())); } /* Looks semi-reasonable. Toss the old core file and work on the new. */ do_cleanups (old_chain); unpush_target (&core_ops); core_bfd = temp_bfd.release (); old_chain = make_cleanup (core_close_cleanup, 0 /*ignore*/); core_gdbarch = gdbarch_from_bfd (core_bfd); /* Find a suitable core file handler to munch on core_bfd */ core_vec = sniff_core_bfd (core_bfd); validate_files (); core_data = XCNEW (struct target_section_table); /* Find the data section */ if (build_section_table (core_bfd, &core_data->sections, &core_data->sections_end)) error (_("\"%s\": Can't find sections: %s"), bfd_get_filename (core_bfd), bfd_errmsg (bfd_get_error ())); /* If we have no exec file, try to set the architecture from the core file. We don't do this unconditionally since an exec file typically contains more information that helps us determine the architecture than a core file. */ if (!exec_bfd) set_gdbarch_from_file (core_bfd); push_target (&core_ops); discard_cleanups (old_chain); /* Do this before acknowledging the inferior, so if post_create_inferior throws (can happen easilly if you're loading a core file with the wrong exec), we aren't left with threads from the previous inferior. */ init_thread_list (); inferior_ptid = null_ptid; /* Need to flush the register cache (and the frame cache) from a previous debug session. If inferior_ptid ends up the same as the last debug session --- e.g., b foo; run; gcore core1; step; gcore core2; core core1; core core2 --- then there's potential for get_current_regcache to return the cached regcache of the previous session, and the frame cache being stale. */ registers_changed (); /* Build up thread list from BFD sections, and possibly set the current thread to the .reg/NN section matching the .reg section. */ bfd_map_over_sections (core_bfd, add_to_thread_list, bfd_get_section_by_name (core_bfd, ".reg")); if (ptid_equal (inferior_ptid, null_ptid)) { /* Either we found no .reg/NN section, and hence we have a non-threaded core (single-threaded, from gdb's perspective), or for some reason add_to_thread_list couldn't determine which was the "main" thread. The latter case shouldn't usually happen, but we're dealing with input here, which can always be broken in different ways. */ struct thread_info *thread = first_thread_of_process (-1); if (thread == NULL) { inferior_appeared (current_inferior (), CORELOW_PID); inferior_ptid = pid_to_ptid (CORELOW_PID); add_thread_silent (inferior_ptid); } else switch_to_thread (thread->ptid); } post_create_inferior (&core_ops, from_tty); /* Now go through the target stack looking for threads since there may be a thread_stratum target loaded on top of target core by now. The layer above should claim threads found in the BFD sections. */ TRY { target_update_thread_list (); } CATCH (except, RETURN_MASK_ERROR) { exception_print (gdb_stderr, except); }
void core_init (const char * aout_name) { int core_sym_bytes; asymbol *synthsyms; long synth_count; core_bfd = bfd_openr (aout_name, 0); if (!core_bfd) { perror (aout_name); done (1); } if (!bfd_check_format (core_bfd, bfd_object)) { fprintf (stderr, _("%s: %s: not in executable format\n"), whoami, aout_name); done (1); } /* Get core's text section. */ core_text_sect = bfd_get_section_by_name (core_bfd, ".text"); if (!core_text_sect) { core_text_sect = bfd_get_section_by_name (core_bfd, "$CODE$"); if (!core_text_sect) { fprintf (stderr, _("%s: can't find .text section in %s\n"), whoami, aout_name); done (1); } } /* Read core's symbol table. */ /* This will probably give us more than we need, but that's ok. */ core_sym_bytes = bfd_get_symtab_upper_bound (core_bfd); if (core_sym_bytes < 0) { fprintf (stderr, "%s: %s: %s\n", whoami, aout_name, bfd_errmsg (bfd_get_error ())); done (1); } core_syms = (asymbol **) xmalloc (core_sym_bytes); core_num_syms = bfd_canonicalize_symtab (core_bfd, core_syms); if (core_num_syms < 0) { fprintf (stderr, "%s: %s: %s\n", whoami, aout_name, bfd_errmsg (bfd_get_error ())); done (1); } synth_count = bfd_get_synthetic_symtab (core_bfd, core_num_syms, core_syms, 0, NULL, &synthsyms); if (synth_count > 0) { asymbol **symp; long new_size; long i; new_size = (core_num_syms + synth_count + 1) * sizeof (*core_syms); core_syms = (asymbol **) xrealloc (core_syms, new_size); symp = core_syms + core_num_syms; core_num_syms += synth_count; for (i = 0; i < synth_count; i++) *symp++ = synthsyms + i; *symp = 0; } min_insn_size = 1; offset_to_code = 0; switch (bfd_get_arch (core_bfd)) { case bfd_arch_vax: case bfd_arch_tahoe: offset_to_code = 2; break; case bfd_arch_alpha: min_insn_size = 4; break; default: break; } if (function_mapping_file) read_function_mappings (function_mapping_file); }
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); }
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 }
int main(int argc, char *argv[]) { bfd *abfd; bfd_init(); abfd = bfd_openr(argv[1], NULL); if (abfd == NULL) { bfd_perror("bfd_openr"); exit(1); } if (! bfd_check_format(abfd, bfd_object)) { bfd_perror("bfd_check_format"); } printf("SYMBOL TABLE:\n"); { long storage_needed; asymbol **symbol_table; long number_of_symbols; long i; storage_needed = bfd_get_symtab_upper_bound (abfd); printf("storage_need=%d\n", storage_needed); if (storage_needed < 0) { bfd_perror("bfd_get_symtab_upper_bound"); exit(1); } if (storage_needed == 0) { printf("no symbols\n"); exit(0); } symbol_table = (asymbol **)malloc (storage_needed); number_of_symbols = bfd_canonicalize_symtab (abfd, symbol_table); if (number_of_symbols < 0) { bfd_perror("bfd_canonicalize_symtab"); exit(1); } for (i = 0; i < number_of_symbols; i++) { asymbol *asym = symbol_table[i]; int symclass = bfd_decode_symclass(asym); symbol_info syminfo; bfd_symbol_info(asym, &syminfo); bfd_print_symbol_vandf(abfd, stdout, asym); printf(" 0x%x %s ", symclass, bfd_is_undefined_symclass(symclass) ? "?" : " "); printf(" %s ", bfd_asymbol_name(asym)); printf("%p ", bfd_asymbol_value(asym)); // printf(" %d ", syminfo.value); /* asymbol_value */ // printf(" %d ", syminfo.type); /* symclass */ // printf(" %s ", syminfo.name); /* asymbol_name */ printf(" %d ", syminfo.stab_type); printf(" %d ", syminfo.stab_other); printf(" %d ", syminfo.stab_desc); // printf(" %s ", syminfo.stab_name); printf("\n"); } } printf("DYNAMIC SYMBOL TABLE:\n"); { long storage_needed; asymbol **symbol_table; long number_of_symbols; long i; storage_needed = bfd_get_dynamic_symtab_upper_bound (abfd); printf("storage_need=%d\n", storage_needed); if (storage_needed < 0) { bfd_perror("bfd_get_symtab_upper_bound"); exit(1); } if (storage_needed == 0) { printf("no symbols\n"); exit(0); } symbol_table = (asymbol **)malloc (storage_needed); number_of_symbols = bfd_canonicalize_dynamic_symtab (abfd, symbol_table); if (number_of_symbols < 0) { bfd_perror("bfd_canonicalize_symtab"); exit(1); } for (i = 0; i < number_of_symbols; i++) { asymbol *asym = symbol_table[i]; int symclass = bfd_decode_symclass(asym); symbol_info syminfo; bfd_symbol_info(asym, &syminfo); bfd_print_symbol_vandf(abfd, stdout, asym); printf(" 0x%x %s ", symclass, bfd_is_undefined_symclass(symclass) ? "?" : " "); printf(" %s ", bfd_asymbol_name(asym)); printf("%p ", bfd_asymbol_value(asym)); // printf(" %d ", syminfo.value); /* asymbol_value */ // printf(" %d ", syminfo.type); /* symclass */ // printf(" %s ", syminfo.name); /* asymbol_name */ printf(" %d ", syminfo.stab_type); printf(" %d ", syminfo.stab_other); printf(" %d ", syminfo.stab_desc); // printf(" %s ", syminfo.stab_name); printf("\n"); } } exit(0); }
static BOOL StackBackTrace(HANDLE hProcess, HANDLE hThread, PCONTEXT pContext) { STACKFRAME StackFrame; HMODULE hModule = NULL; TCHAR szModule[MAX_PATH]; #ifdef HAVE_BFD bfd *abfd = NULL; asymbol **syms = NULL; // The symbol table. long symcount = 0; // Number of symbols in `syms'. #endif /* HAVE_BFD */ assert(!bSymInitialized); j_SymSetOptions(/* SYMOPT_UNDNAME | */ SYMOPT_LOAD_LINES); if(j_SymInitialize(hProcess, NULL, TRUE)) bSymInitialized = TRUE; memset( &StackFrame, 0, sizeof(StackFrame) ); // Initialize the STACKFRAME structure for the first call. This is only // necessary for Intel CPUs, and isn't mentioned in the documentation. StackFrame.AddrPC.Offset = pContext->Eip; StackFrame.AddrPC.Mode = AddrModeFlat; StackFrame.AddrStack.Offset = pContext->Esp; StackFrame.AddrStack.Mode = AddrModeFlat; StackFrame.AddrFrame.Offset = pContext->Ebp; StackFrame.AddrFrame.Mode = AddrModeFlat; rprintf( _T("Call stack:\r\n") ); if(0) rprintf( _T("AddrPC AddrReturn AddrFrame AddrStack\r\n") ); while ( 1 ) { BOOL bSuccess = FALSE; #ifdef HAVE_BFD const HMODULE hPrevModule = hModule; #endif /* HAVE_BFD */ TCHAR szSymName[512] = _T(""); TCHAR szFileName[MAX_PATH] = _T(""); DWORD LineNumber = 0; if(bSymInitialized) { if(!j_StackWalk( IMAGE_FILE_MACHINE_I386, hProcess, hThread, &StackFrame, pContext, NULL, j_SymFunctionTableAccess, j_SymGetModuleBase, NULL ) ) break; } else { if(!IntelStackWalk( IMAGE_FILE_MACHINE_I386, hProcess, hThread, &StackFrame, pContext, NULL, NULL, NULL, NULL ) ) break; } // Basic sanity check to make sure the frame is OK. Bail if not. if ( 0 == StackFrame.AddrFrame.Offset ) break; if(0) { rprintf( _T("%08lX %08lX %08lX %08lX\r\n"), StackFrame.AddrPC.Offset, StackFrame.AddrReturn.Offset, StackFrame.AddrFrame.Offset, StackFrame.AddrStack.Offset ); rprintf( _T("%08lX %08lX %08lX %08lX\r\n"), StackFrame.Params[0], StackFrame.Params[1], StackFrame.Params[2], StackFrame.Params[3] ); } rprintf( _T("%08lX"), StackFrame.AddrPC.Offset); if((hModule = (HMODULE) GetModuleBase(StackFrame.AddrPC.Offset)) && GetModuleFileName(hModule, szModule, sizeof(szModule))) { #ifndef HAVE_BFD rprintf( _T(" %s:ModulBase %08lX"), szModule, hModule); #else /* HAVE_BFD */ rprintf( _T(" %s:%08lX"), szModule, StackFrame.AddrPC.Offset); if(hModule != hPrevModule) { if(syms) { GlobalFree(syms); syms = NULL; symcount = 0; } if(abfd) bfd_close(abfd); if((abfd = bfd_openr (szModule, NULL))) if(bfd_check_format(abfd, bfd_object)) { bfd_vma adjust_section_vma = 0; /* If we are adjusting section VMA's, change them all now. Changing the BFD information is a hack. However, we must do it, or bfd_find_nearest_line will not do the right thing. */ if ((adjust_section_vma = (bfd_vma) hModule - pe_data(abfd)->pe_opthdr.ImageBase)) { asection *s; for (s = abfd->sections; s != NULL; s = s->next) { s->vma += adjust_section_vma; s->lma += adjust_section_vma; } } if(bfd_get_file_flags(abfd) & HAS_SYMS) /* Read in the symbol table. */ slurp_symtab(abfd, &syms, &symcount); } } if(!bSuccess && abfd && syms && symcount) if((bSuccess = BfdGetSymFromAddr(abfd, syms, symcount, StackFrame.AddrPC.Offset, szSymName, 512))) { /* framepointer = StackFrame.AddrFrame.Offset; hprocess = hProcess; */ BfdDemangleSymName(szSymName, szSymName, 512); rprintf( _T(" %s"), szSymName); if(BfdGetLineFromAddr(abfd, syms, symcount, StackFrame.AddrPC.Offset, szFileName, MAX_PATH, &LineNumber)) rprintf( _T(" %s:%ld"), szFileName, LineNumber); } #endif /* HAVE_BFD */ if(!bSuccess && bSymInitialized) if((bSuccess = ImagehlpGetSymFromAddr(hProcess, StackFrame.AddrPC.Offset, szSymName, 512))) { rprintf( _T(" %s"), szSymName); ImagehlpDemangleSymName(szSymName, szSymName, 512); if(ImagehlpGetLineFromAddr(hProcess, StackFrame.AddrPC.Offset, szFileName, MAX_PATH, &LineNumber)) rprintf( _T(" %s:%ld"), szFileName, LineNumber); } if(!bSuccess) if((bSuccess = PEGetSymFromAddr(hProcess, StackFrame.AddrPC.Offset, szSymName, 512))) rprintf( _T(" %s"), szSymName); } rprintf(_T("\r\n")); } #ifdef HAVE_BFD if(syms) { GlobalFree(syms); syms = NULL; symcount = 0; } if(abfd) bfd_close(abfd); #endif /* HAVE_BFD */ if(bSymInitialized) { if(!j_SymCleanup(hProcess)) assert(0); bSymInitialized = FALSE; } return TRUE; }
static int enable_break (void) { int success = 0; struct minimal_symbol *msymbol; char **bkpt_namep; asection *interp_sect; /* First, remove all the solib event breakpoints. Their addresses may have changed since the last time we ran the program. */ remove_solib_event_breakpoints (); interp_text_sect_low = interp_text_sect_high = 0; interp_plt_sect_low = interp_plt_sect_high = 0; /* Find the .interp section; if not found, warn the user and drop into the old breakpoint at symbol code. */ interp_sect = bfd_get_section_by_name (exec_bfd, ".interp"); if (interp_sect) { unsigned int interp_sect_size; char *buf; CORE_ADDR load_addr; bfd *tmp_bfd; CORE_ADDR sym_addr = 0; /* Read the contents of the .interp section into a local buffer; the contents specify the dynamic linker this program uses. */ interp_sect_size = bfd_section_size (exec_bfd, interp_sect); buf = alloca (interp_sect_size); bfd_get_section_contents (exec_bfd, interp_sect, buf, 0, interp_sect_size); /* Now we need to figure out where the dynamic linker was loaded so that we can load its symbols and place a breakpoint in the dynamic linker itself. This address is stored on the stack. However, I've been unable to find any magic formula to find it for Solaris (appears to be trivial on GNU/Linux). Therefore, we have to try an alternate mechanism to find the dynamic linker's base address. */ tmp_bfd = bfd_openr (buf, gnutarget); if (tmp_bfd == NULL) goto bkpt_at_symbol; /* Make sure the dynamic linker's really a useful object. */ if (!bfd_check_format (tmp_bfd, bfd_object)) { warning (_("Unable to grok dynamic linker %s as an object file"), buf); bfd_close (tmp_bfd); goto bkpt_at_symbol; } /* We find the dynamic linker's base address by examining the current pc (which point at the entry point for the dynamic linker) and subtracting the offset of the entry point. */ load_addr = read_pc () - tmp_bfd->start_address; /* Record the relocated start and end address of the dynamic linker text and plt section for aix5_in_dynsym_resolve_code. */ interp_sect = bfd_get_section_by_name (tmp_bfd, ".text"); if (interp_sect) { interp_text_sect_low = bfd_section_vma (tmp_bfd, interp_sect) + load_addr; interp_text_sect_high = interp_text_sect_low + bfd_section_size (tmp_bfd, interp_sect); } interp_sect = bfd_get_section_by_name (tmp_bfd, ".plt"); if (interp_sect) { interp_plt_sect_low = bfd_section_vma (tmp_bfd, interp_sect) + load_addr; interp_plt_sect_high = interp_plt_sect_low + bfd_section_size (tmp_bfd, interp_sect); } /* Now try to set a breakpoint in the dynamic linker. */ for (bkpt_namep = solib_break_names; *bkpt_namep != NULL; bkpt_namep++) { sym_addr = bfd_lookup_symbol (tmp_bfd, *bkpt_namep); if (sym_addr != 0) break; } /* We're done with the temporary bfd. */ bfd_close (tmp_bfd); if (sym_addr != 0) { create_solib_event_breakpoint (load_addr + sym_addr); return 1; } /* For whatever reason we couldn't set a breakpoint in the dynamic linker. Warn and drop into the old code. */ bkpt_at_symbol: warning (_("Unable to find dynamic linker breakpoint function.\nGDB will be unable to debug shared library initializers\nand track explicitly loaded dynamic code.")); } /* Nothing good happened. */ success = 0; return (success); }
int main (int argc, char **argv) { char *name; char **prog_argv = NULL; struct bfd *prog_bfd; enum sim_stop reason; int sigrc = 0; int single_step = 0; RETSIGTYPE (*prev_sigint) (); myname = argv[0] + strlen (argv[0]); while (myname > argv[0] && myname[-1] != '/') --myname; /* INTERNAL: When MYNAME is `step', single step the simulator instead of allowing it to run free. The sole purpose of this HACK is to allow the sim_resume interface's step argument to be tested without having to build/run gdb. */ if (strlen (myname) > 4 && strcmp (myname - 4, "step") == 0) { single_step = 1; } /* Create an instance of the simulator. */ default_callback.init (&default_callback); sd = sim_open (SIM_OPEN_STANDALONE, &default_callback, NULL, argv); if (sd == 0) exit (1); if (STATE_MAGIC (sd) != SIM_MAGIC_NUMBER) { fprintf (stderr, "Internal error - bad magic number in simulator struct\n"); abort (); } /* We can't set the endianness in the callback structure until sim_config is called, which happens in sim_open. */ default_callback.target_endian = (CURRENT_TARGET_BYTE_ORDER == BIG_ENDIAN ? BFD_ENDIAN_BIG : BFD_ENDIAN_LITTLE); /* Was there a program to run? */ prog_argv = STATE_PROG_ARGV (sd); prog_bfd = STATE_PROG_BFD (sd); if (prog_argv == NULL || *prog_argv == NULL) usage (); name = *prog_argv; /* For simulators that don't open prog during sim_open() */ if (prog_bfd == NULL) { prog_bfd = bfd_openr (name, 0); if (prog_bfd == NULL) { fprintf (stderr, "%s: can't open \"%s\": %s\n", myname, name, bfd_errmsg (bfd_get_error ())); exit (1); } if (!bfd_check_format (prog_bfd, bfd_object)) { fprintf (stderr, "%s: \"%s\" is not an object file: %s\n", myname, name, bfd_errmsg (bfd_get_error ())); exit (1); } } if (STATE_VERBOSE_P (sd)) printf ("%s %s\n", myname, name); /* Load the program into the simulator. */ if (sim_load (sd, name, prog_bfd, 0) == SIM_RC_FAIL) exit (1); /* Prepare the program for execution. */ #ifdef HAVE_ENVIRON sim_create_inferior (sd, prog_bfd, prog_argv, environ); #else sim_create_inferior (sd, prog_bfd, prog_argv, NULL); #endif /* To accommodate relative file paths, chdir to sysroot now. We mustn't do this until BFD has opened the program, else we wouldn't find the executable if it has a relative file path. */ if (simulator_sysroot[0] != '\0' && chdir (simulator_sysroot) < 0) { fprintf (stderr, "%s: can't change directory to \"%s\"\n", myname, simulator_sysroot); exit (1); } /* Run/Step the program. */ if (single_step) { do { prev_sigint = signal (SIGINT, cntrl_c); sim_resume (sd, 1/*step*/, 0); signal (SIGINT, prev_sigint); sim_stop_reason (sd, &reason, &sigrc); if ((reason == sim_stopped) && (sigrc == sim_signal_to_host (sd, SIM_SIGINT))) break; /* exit on control-C */ } /* remain on breakpoint or signals in oe mode*/ while (((reason == sim_signalled) && (sigrc == sim_signal_to_host (sd, SIM_SIGTRAP))) || ((reason == sim_stopped) && (STATE_ENVIRONMENT (sd) == OPERATING_ENVIRONMENT))); } else { do { #if defined (HAVE_SIGACTION) && defined (SA_RESTART) struct sigaction sa, osa; sa.sa_handler = cntrl_c; sigemptyset (&sa.sa_mask); sa.sa_flags = 0; sigaction (SIGINT, &sa, &osa); prev_sigint = osa.sa_handler; #else prev_sigint = signal (SIGINT, cntrl_c); #endif sim_resume (sd, 0, sigrc); signal (SIGINT, prev_sigint); sim_stop_reason (sd, &reason, &sigrc); if ((reason == sim_stopped) && (sigrc == sim_signal_to_host (sd, SIM_SIGINT))) break; /* exit on control-C */ /* remain on signals in oe mode */ } while ((reason == sim_stopped) && (STATE_ENVIRONMENT (sd) == OPERATING_ENVIRONMENT)); } /* Print any stats the simulator collected. */ if (STATE_VERBOSE_P (sd)) sim_info (sd, 0); /* Shutdown the simulator. */ sim_close (sd, 0); /* If reason is sim_exited, then sigrc holds the exit code which we want to return. If reason is sim_stopped or sim_signalled, then sigrc holds the signal that the simulator received; we want to return that to indicate failure. */ /* Why did we stop? */ switch (reason) { case sim_signalled: case sim_stopped: if (sigrc != 0) fprintf (stderr, "program stopped with signal %d.\n", sigrc); break; case sim_exited: break; default: fprintf (stderr, "program in undefined state (%d:%d)\n", reason, sigrc); break; } return sigrc; }
int main (int argc, char **argv) { int o; int save_trace; bfd *prog; #ifdef HAVE_networking char *console_port_s = 0; #endif setbuf (stdout, 0); in_gdb = 0; while ((o = getopt (argc, argv, "tc:vdm:C")) != -1) switch (o) { case 't': trace++; break; case 'c': #ifdef HAVE_networking console_port_s = optarg; #else fprintf (stderr, "Nework console not available in this build.\n"); #endif break; case 'C': #ifdef HAVE_TERMIOS_H m32c_use_raw_console = 1; #else fprintf (stderr, "Raw console not available in this build.\n"); #endif break; case 'v': verbose++; break; case 'd': m32c_disassemble++; break; case 'm': if (strcmp (optarg, "r8c") == 0 || strcmp (optarg, "m16c") == 0) default_machine = bfd_mach_m16c; else if (strcmp (optarg, "m32cm") == 0 || strcmp (optarg, "m32c") == 0) default_machine = bfd_mach_m32c; else { fprintf (stderr, "Invalid machine: %s\n", optarg); exit (1); } break; case '?': fprintf (stderr, "usage: run [-v] [-C] [-c port] [-t] [-d] [-m r8c|m16c|m32cm|m32c]" " program\n"); exit (1); } prog = bfd_openr (argv[optind], 0); if (!prog) { fprintf (stderr, "Can't read %s\n", argv[optind]); exit (1); } if (!bfd_check_format (prog, bfd_object)) { fprintf (stderr, "%s not a m32c program\n", argv[optind]); exit (1); } save_trace = trace; trace = 0; m32c_load (prog); trace = save_trace; #ifdef HAVE_networking if (console_port_s) setup_tcp_console (console_port_s); #endif sim_disasm_init (prog); while (1) { int rc; if (trace) printf ("\n"); if (m32c_disassemble) sim_disasm_one (); enable_counting = verbose; cycles++; rc = decode_opcode (); enable_counting = 0; if (M32C_HIT_BREAK (rc)) done (1); else if (M32C_EXITED (rc)) done (M32C_EXIT_STATUS (rc)); else assert (M32C_STEPPED (rc)); trace_register_changes (); #ifdef TIMER_A update_timer_a (); #endif } }
/** * @brief initialization of a symbol table * * @param filename * @param arch_name */ void init_symbol_table(char* filename, char* arch_name) { long i,j, digit; ENTRY newentry, *oldentry; SYM_FUNC *symp; asymbol *symptr; int key; bfd *abfd; if(!filename){ skyeye_info("Can not get correct kernel filename!Maybe your skyeye.conf have something wrong!\n"); return; } abfd = bfd_openr (filename, get_bfd_target(arch_name)); if (!bfd_check_format(abfd, bfd_object)) { bfd_close(abfd); skyeye_log(Debug_log, __FUNCTION__, "wrong bfd format\n"); return; //exit(0); } storage_needed = bfd_get_symtab_upper_bound(abfd); if (storage_needed < 0){ printf("FAIL\n"); exit(0); } symbol_table = (asymbol **) skyeye_mm_zero (storage_needed); if(symbol_table == NULL){ fprintf(stderr, "Can not alloc memory for symbol table.\n"); exit(0); } number_of_symbols = bfd_canonicalize_symtab (abfd, symbol_table); kernel_number = number_of_symbols; /* <tktan> BUG200106022219 */ if (number_of_symbols < 0){ printf("FAIL\n"); exit(0); } if (!hcreate(number_of_symbols << 1)) { printf("Not enough memory for hash table\n"); exit(0); } for (i = 0; i < number_of_symbols; i++) { symptr = symbol_table[i] ; key = symptr->value + symptr->section->vma; // adjust for section address if (((i<kernel_number) && (symbol_table[i]->flags == 0x01)) || // <tktan> BUG200105172154, BUG200106022219 ((i<kernel_number) && (symbol_table[i]->flags == 0x02)) || // <tktan> BUG200204051654 (symbol_table[i]->flags & 0x10)) { // Is a function symbol // printf("%x %8x %s\n", symbol_table[i]->flags, key, symbol_table[i]->name); // *********************************************************** // This is converting the function symbol value to char string // and use it as a key in the GNU hash table // ******************************************************** newentry.key = (char *) skyeye_mm_zero(9); for (j=0;j<8;j++) { newentry.key[j] = itoa_tab[((key) >> (j << 2)) & 0xf] ; } newentry.key[8] = 0 ; // ************************************************* // This is allocating memory for a struct funcsym // ************************************************* symp = (SYM_FUNC *) skyeye_mm_zero(sizeof(SYM_FUNC)); newentry.data = (char *) symp; symp->name = (char *) symbol_table[i]->name ; symp->total_cycle = 0; symp->total_energy = 0; symp->instances = 0; // *********************************************** // Insert into hash table // ******************************************* /* <tktan> BUG200106022219 */ oldentry = hsearch(newentry, FIND) ; if (oldentry) { // was entered // printf("Duplicate Symbol: %x %s\n", key, symp->name); oldentry->data = (char *) symp ; } else if (!hsearch(newentry, ENTER)) { printf("Insufficient memory\n"); exit(0) ; } } }
static void bfin_user_init (SIM_DESC sd, SIM_CPU *cpu, struct bfd *abfd, const char * const *argv, const char * const *env) { /* XXX: Missing host -> target endian ... */ /* Linux starts the user app with the stack: argc argv[0] -- pointers to the actual strings argv[1..N] NULL env[0] env[1..N] NULL auxvt[0].type -- ELF Auxiliary Vector Table auxvt[0].value auxvt[1..N] AT_NULL 0 argv[0..N][0..M] -- actual argv/env strings env[0..N][0..M] FDPIC loadmaps -- for FDPIC apps So set things up the same way. */ int i, argc, envc; bu32 argv_flat, env_flat; bu32 sp, sp_flat; /* start, at_phdr, at_phnum, at_base, at_entry, pt_dynamic */ bu32 elf_addrs[6]; bu32 auxvt; bu32 exec_loadmap, ldso_loadmap; char *ldso_path; unsigned char null[4] = { 0, 0, 0, 0 }; host_callback *cb = STATE_CALLBACK (sd); elf_addrs[0] = elf_addrs[4] = bfd_get_start_address (abfd); elf_addrs[1] = elf_addrs[2] = elf_addrs[3] = elf_addrs[5] = 0; /* Keep the load addresses consistent between runs. Also make sure we make space for the fixed code region (part of the Blackfin Linux ABI). */ fdpic_load_offset = 0x1000; /* First try to load this as an FDPIC executable. */ sp = SPREG; if (!bfin_fdpic_load (sd, cpu, STATE_PROG_BFD (sd), &sp, elf_addrs, &ldso_path)) goto skip_fdpic_init; exec_loadmap = sp; /* If that worked, then load the fixed code region. We only do this for FDPIC ELFs atm because they are PIEs and let us relocate them without manual fixups. FLAT files however require location processing which we do not do ourselves, and they link with a VMA of 0. */ sim_write (sd, 0x400, bfin_linux_fixed_code, sizeof (bfin_linux_fixed_code)); /* If the FDPIC needs an interpreter, then load it up too. */ if (ldso_path) { const char *ldso_full_path = concat (simulator_sysroot, ldso_path, NULL); struct bfd *ldso_bfd; ldso_bfd = bfd_openr (ldso_full_path, STATE_TARGET (sd)); if (!ldso_bfd) { sim_io_eprintf (sd, "bfin-sim: bfd open failed: %s\n", ldso_full_path); goto static_fdpic; } if (!bfd_check_format (ldso_bfd, bfd_object)) sim_io_eprintf (sd, "bfin-sim: bfd format not valid: %s\n", ldso_full_path); bfd_set_arch_info (ldso_bfd, STATE_ARCHITECTURE (sd)); if (!bfin_fdpic_load (sd, cpu, ldso_bfd, &sp, elf_addrs, &ldso_path)) sim_io_eprintf (sd, "bfin-sim: FDPIC ldso failed to load: %s\n", ldso_full_path); if (ldso_path) sim_io_eprintf (sd, "bfin-sim: FDPIC ldso (%s) needs an interpreter (%s) !?\n", ldso_full_path, ldso_path); ldso_loadmap = sp; } else static_fdpic: ldso_loadmap = 0; /* Finally setup the registers required by the FDPIC ABI. */ SET_DREG (7, 0); /* Zero out FINI funcptr -- ldso will set this up. */ SET_PREG (0, exec_loadmap); /* Exec loadmap addr. */ SET_PREG (1, ldso_loadmap); /* Interp loadmap addr. */ SET_PREG (2, elf_addrs[5]); /* PT_DYNAMIC map addr. */ auxvt = 1; SET_SPREG (sp); skip_fdpic_init: sim_pc_set (cpu, elf_addrs[0]); /* Figure out how much storage the argv/env strings need. */ argc = count_argc (argv); if (argc == -1) argc = 0; argv_flat = argc; /* NUL bytes */ for (i = 0; i < argc; ++i) argv_flat += strlen (argv[i]); if (!env) env = simple_env; envc = count_argc (env); env_flat = envc; /* NUL bytes */ for (i = 0; i < envc; ++i) env_flat += strlen (env[i]); /* Push the Auxiliary Vector Table between argv/env and actual strings. */ sp_flat = sp = ALIGN (SPREG - argv_flat - env_flat - 4, 4); if (auxvt) { # define AT_PUSH(at, val) \ auxvt_size += 8; \ sp -= 4; \ auxvt = (val); \ sim_write (sd, sp, (void *)&auxvt, 4); \ sp -= 4; \ auxvt = (at); \ sim_write (sd, sp, (void *)&auxvt, 4) unsigned int egid = getegid (), gid = getgid (); unsigned int euid = geteuid (), uid = getuid (); bu32 auxvt_size = 0; AT_PUSH (AT_NULL, 0); AT_PUSH (AT_SECURE, egid != gid || euid != uid); AT_PUSH (AT_EGID, egid); AT_PUSH (AT_GID, gid); AT_PUSH (AT_EUID, euid); AT_PUSH (AT_UID, uid); AT_PUSH (AT_ENTRY, elf_addrs[4]); AT_PUSH (AT_FLAGS, 0); AT_PUSH (AT_BASE, elf_addrs[3]); AT_PUSH (AT_PHNUM, elf_addrs[2]); AT_PUSH (AT_PHENT, sizeof (Elf32_External_Phdr)); AT_PUSH (AT_PHDR, elf_addrs[1]); AT_PUSH (AT_CLKTCK, 100); /* XXX: This ever not 100 ? */ AT_PUSH (AT_PAGESZ, 4096); AT_PUSH (AT_HWCAP, 0); #undef AT_PUSH } SET_SPREG (sp); /* Push the argc/argv/env after the auxvt. */ sp -= ((1 + argc + 1 + envc + 1) * 4); SET_SPREG (sp); /* First push the argc value. */ sim_write (sd, sp, (void *)&argc, 4); sp += 4; /* Then the actual argv strings so we know where to point argv[]. */ for (i = 0; i < argc; ++i) { unsigned len = strlen (argv[i]) + 1; sim_write (sd, sp_flat, (void *)argv[i], len); sim_write (sd, sp, (void *)&sp_flat, 4); sp_flat += len; sp += 4; } sim_write (sd, sp, null, 4); sp += 4; /* Then the actual env strings so we know where to point env[]. */ for (i = 0; i < envc; ++i) { unsigned len = strlen (env[i]) + 1; sim_write (sd, sp_flat, (void *)env[i], len); sim_write (sd, sp, (void *)&sp_flat, 4); sp_flat += len; sp += 4; } /* Set some callbacks. */ cb->syscall_map = cb_linux_syscall_map; cb->errno_map = cb_linux_errno_map; cb->open_map = cb_linux_open_map; cb->signal_map = cb_linux_signal_map; cb->stat_map = stat_map_32 = cb_linux_stat_map_32; stat_map_64 = cb_linux_stat_map_64; }
/* load program text and initialized data into simulated virtual memory space and initialize program segment range variables */ void ld_load_prog(char *fname, /* program to load */ int argc, char **argv, /* simulated program cmd line args */ char **envp, /* simulated program environment */ struct regs_t *regs, /* registers to initialize for load */ struct mem_t *mem, /* memory space to load prog into */ int zero_bss_segs) /* zero uninit data segment? */ { int i; qword_t temp; md_addr_t sp, data_break = 0, null_ptr = 0, argv_addr, envp_addr; if (eio_valid(fname)) { if (argc != 1) { fprintf(stderr, "error: EIO file has arguments\n"); exit(1); } fprintf(stderr, "sim: loading EIO file: %s\n", fname); sim_eio_fname = mystrdup(fname); /* open the EIO file stream */ sim_eio_fd = eio_open(fname); /* load initial state checkpoint */ if (eio_read_chkpt(regs, mem, sim_eio_fd) != -1) fatal("bad initial checkpoint in EIO file"); /* load checkpoint? */ if (sim_chkpt_fname != NULL) { counter_t restore_icnt; FILE *chkpt_fd; fprintf(stderr, "sim: loading checkpoint file: %s\n", sim_chkpt_fname); if (!eio_valid(sim_chkpt_fname)) fatal("file `%s' does not appear to be a checkpoint file", sim_chkpt_fname); /* open the checkpoint file */ chkpt_fd = eio_open(sim_chkpt_fname); /* load the state image */ restore_icnt = eio_read_chkpt(regs, mem, chkpt_fd); /* fast forward the baseline EIO trace to checkpoint location */ myfprintf(stderr, "sim: fast forwarding to instruction %n\n", restore_icnt); eio_fast_forward(sim_eio_fd, restore_icnt); } /* computed state... */ ld_environ_base = regs->regs_R[MD_REG_SP]; ld_prog_entry = regs->regs_PC; /* fini... */ return; } #ifdef MD_CROSS_ENDIAN else { warn("endian of `%s' does not match host", fname); warn("running with experimental cross-endian execution support"); warn("****************************************"); warn("**>> please check results carefully <<**"); warn("****************************************"); #if 0 fatal("SimpleScalar/Alpha only supports binary execution on\n" " little-endian hosts, use EIO files on big-endian hosts"); #endif } #endif /* MD_CROSS_ENDIAN */ if (sim_chkpt_fname != NULL) fatal("checkpoints only supported while EIO tracing"); #ifdef BFD_LOADER { bfd *abfd; asection *sect; /* set up a local stack pointer, this is where the argv and envp data is written into program memory */ ld_stack_base = MD_STACK_BASE; sp = ROUND_DOWN(MD_STACK_BASE - MD_MAX_ENVIRON, sizeof(MD_DOUBLE_TYPE)); ld_stack_size = ld_stack_base - sp; printf("Thread 0 stack size (3)%d\n", current->ld_stack_size); /* initial stack pointer value */ ld_environ_base = sp; /* load the program into memory, try both endians */ if (!(abfd = bfd_openr(argv[0], "ss-coff-big"))) if (!(abfd = bfd_openr(argv[0], "ss-coff-little"))) fatal("cannot open executable `%s'", argv[0]); /* this call is mainly for its side effect of reading in the sections. we follow the traditional behavior of `strings' in that we don't complain if we don't recognize a file to be an object file. */ if (!bfd_check_format(abfd, bfd_object)) { bfd_close(abfd); fatal("cannot open executable `%s'", argv[0]); } /* record profile file name */ ld_prog_fname = argv[0]; /* record endian of target */ ld_target_big_endian = abfd->xvec->byteorder_big_p; debug("processing %d sections in `%s'...", bfd_count_sections(abfd), argv[0]); /* read all sections in file */ for (sect=abfd->sections; sect; sect=sect->next) { char *p; debug("processing section `%s', %d bytes @ 0x%08x...", bfd_section_name(abfd, sect), bfd_section_size(abfd, sect), bfd_section_vma(abfd, sect)); /* read the section data, if allocated and loadable and non-NULL */ if ((bfd_get_section_flags(abfd, sect) & SEC_ALLOC) && (bfd_get_section_flags(abfd, sect) & SEC_LOAD) && bfd_section_vma(abfd, sect) && bfd_section_size(abfd, sect)) { /* allocate a section buffer */ p = calloc(bfd_section_size(abfd, sect), sizeof(char)); if (!p) fatal("cannot allocate %d bytes for section `%s'", bfd_section_size(abfd, sect), bfd_section_name(abfd, sect)); if (!bfd_get_section_contents(abfd, sect, p, (file_ptr)0, bfd_section_size(abfd, sect))) fatal("could not read entire `%s' section from executable", bfd_section_name(abfd, sect)); /* copy program section it into simulator target memory */ mem_bcopy(mem_fn, Write, bfd_section_vma(abfd, sect), p, bfd_section_size(abfd, sect)); /* release the section buffer */ free(p); } /* zero out the section if it is loadable but not allocated in exec */ else if (zero_bss_segs && (bfd_get_section_flags(abfd, sect) & SEC_LOAD) && bfd_section_vma(abfd, sect) && bfd_section_size(abfd, sect)) { /* zero out the section region */ mem_bzero(mem_fn, bfd_section_vma(abfd, sect), bfd_section_size(abfd, sect)); } else { /* else do nothing with this section, it's probably debug data */ debug("ignoring section `%s' during load...", bfd_section_name(abfd, sect)); } /* expected text section */ if (!strcmp(bfd_section_name(abfd, sect), ".text")) { /* .text section processing */ ld_text_size = ((bfd_section_vma(abfd, sect) + bfd_section_size(abfd, sect)) - MD_TEXT_BASE) + /* for speculative fetches/decodes */TEXT_TAIL_PADDING; /* create tail padding and copy into simulator target memory */ #if 0 mem_bzero(mem_fn, bfd_section_vma(abfd, sect) + bfd_section_size(abfd, sect), TEXT_TAIL_PADDING); #endif } /* expected data sections */ else if (!strcmp(bfd_section_name(abfd, sect), ".rdata") || !strcmp(bfd_section_name(abfd, sect), ".data") || !strcmp(bfd_section_name(abfd, sect), ".sdata") || !strcmp(bfd_section_name(abfd, sect), ".bss") || !strcmp(bfd_section_name(abfd, sect), ".sbss")) { /* data section processing */ if (bfd_section_vma(abfd, sect) + bfd_section_size(abfd, sect) > data_break) data_break = (bfd_section_vma(abfd, sect) + bfd_section_size(abfd, sect)); } else { /* what is this section??? */ fatal("encountered unknown section `%s', %d bytes @ 0x%08x", bfd_section_name(abfd, sect), bfd_section_size(abfd, sect), bfd_section_vma(abfd, sect)); } } /* compute data segment size from data break point */ ld_text_base = MD_TEXT_BASE; ld_data_base = MD_DATA_BASE; ld_prog_entry = bfd_get_start_address(abfd); ld_data_size = data_break - ld_data_base; /* done with the executable, close it */ if (!bfd_close(abfd)) fatal("could not close executable `%s'", argv[0]); } #else /* !BFD_LOADER, i.e., standalone loader */ { FILE *fobj; long floc; struct ecoff_filehdr fhdr; struct ecoff_aouthdr ahdr; struct ecoff_scnhdr shdr; /* record profile file name */ ld_prog_fname = argv[0]; /* load the program into memory, try both endians */ #if defined(__CYGWIN32__) || defined(_MSC_VER) fobj = fopen(argv[0], "rb"); #else fobj = fopen(argv[0], "r"); #endif if (!fobj) fatal("cannot open executable `%s'", argv[0]); if (fread(&fhdr, sizeof(struct ecoff_filehdr), 1, fobj) < 1) fatal("cannot read header from executable `%s'", argv[0]); /* record endian of target */ if (fhdr.f_magic == MD_SWAPH(ECOFF_ALPHAMAGIC)) ld_target_big_endian = FALSE; else if (fhdr.f_magic == MD_SWAPH(ECOFF_EB_MAGIC) || fhdr.f_magic == MD_SWAPH(ECOFF_EL_MAGIC) || fhdr.f_magic == MD_SWAPH(ECOFF_EB_OTHER) || fhdr.f_magic == MD_SWAPH(ECOFF_EL_OTHER)) fatal("Alpha simulator cannot run PISA binary `%s'", argv[0]); else fatal("bad magic number in executable `%s' (not an executable)", argv[0]); if (fread(&ahdr, sizeof(struct ecoff_aouthdr), 1, fobj) < 1) fatal("cannot read AOUT header from executable `%s'", argv[0]); ld_text_base = MD_SWAPQ(ahdr.text_start); ld_text_size = MD_SWAPQ(ahdr.tsize); ld_prog_entry = MD_SWAPQ(ahdr.entry); ld_data_base = MD_SWAPQ(ahdr.data_start); ld_data_size = MD_SWAPQ(ahdr.dsize) + MD_SWAPQ(ahdr.bsize); regs->regs_R[MD_REG_GP] = MD_SWAPQ(ahdr.gp_value); /* compute data segment size from data break point */ data_break = ld_data_base + ld_data_size; /* seek to the beginning of the first section header, the file header comes first, followed by the optional header (this is the aouthdr), the size of the aouthdr is given in Fdhr.f_opthdr */ fseek(fobj, sizeof(struct ecoff_filehdr) + MD_SWAPH(fhdr.f_opthdr), 0); debug("processing %d sections in `%s'...", MD_SWAPH(fhdr.f_nscns), argv[0]); /* loop through the section headers */ floc = ftell(fobj); for (i = 0; i < MD_SWAPH(fhdr.f_nscns); i++) { char *p; if (fseek(fobj, floc, 0) == -1) fatal("could not reset location in executable"); if (fread(&shdr, sizeof(struct ecoff_scnhdr), 1, fobj) < 1) fatal("could not read section %d from executable", i); floc = ftell(fobj); switch (MD_SWAPW(shdr.s_flags)) { case ECOFF_STYP_TEXT: p = calloc(MD_SWAPQ(shdr.s_size), sizeof(char)); if (!p) fatal("out of virtual memory"); if (fseek(fobj, MD_SWAPQ(shdr.s_scnptr), 0) == -1) fatal("could not read `.text' from executable", i); if (fread(p, MD_SWAPQ(shdr.s_size), 1, fobj) < 1) fatal("could not read text section from executable"); /* copy program section into simulator target memory */ mem_bcopy(mem_access, mem, Write, MD_SWAPQ(shdr.s_vaddr), p, MD_SWAPQ(shdr.s_size)); #if 0 /* create tail padding and copy into simulator target memory */ mem_bzero(mem_access, mem, MD_SWAPQ(shdr.s_vaddr) + MD_SWAPQ(shdr.s_size), TEXT_TAIL_PADDING); #endif /* release the section buffer */ free(p); #if 0 Text_seek = MD_SWAPQ(shdr.s_scnptr); Text_start = MD_SWAPQ(shdr.s_vaddr); Text_size = MD_SWAPQ(shdr.s_size) / 4; /* there is a null routine after the supposed end of text */ Text_size += 10; Text_end = Text_start + Text_size * 4; /* create_text_reloc(shdr.s_relptr, shdr.s_nreloc); */ #endif break; case ECOFF_STYP_INIT: case ECOFF_STYP_FINI: if (MD_SWAPQ(shdr.s_size) > 0) { p = calloc(MD_SWAPQ(shdr.s_size), sizeof(char)); if (!p) fatal("out of virtual memory"); if (fseek(fobj, MD_SWAPQ(shdr.s_scnptr), 0) == -1) fatal("could not read `.text' from executable", i); if (fread(p, MD_SWAPQ(shdr.s_size), 1, fobj) < 1) fatal("could not read text section from executable"); /* copy program section into simulator target memory */ mem_bcopy(mem_access, mem, Write, MD_SWAPQ(shdr.s_vaddr), p, MD_SWAPQ(shdr.s_size)); /* release the section buffer */ free(p); } else warn("section `%s' is empty...", shdr.s_name); break; case ECOFF_STYP_LITA: case ECOFF_STYP_LIT8: case ECOFF_STYP_LIT4: case ECOFF_STYP_XDATA: case ECOFF_STYP_PDATA: case ECOFF_STYP_RCONST: /* fall through */ case ECOFF_STYP_RDATA: /* The .rdata section is sometimes placed before the text * section instead of being contiguous with the .data section. */ #if 0 Rdata_start = MD_SWAPQ(shdr.s_vaddr); Rdata_size = MD_SWAPQ(shdr.s_size); Rdata_seek = MD_SWAPQ(shdr.s_scnptr); #endif /* fall through */ case ECOFF_STYP_DATA: #if 0 Data_seek = MD_SWAPQ(shdr.s_scnptr); #endif /* fall through */ case ECOFF_STYP_SDATA: #if 0 Sdata_seek = MD_SWAPQ(shdr.s_scnptr); #endif if (MD_SWAPQ(shdr.s_size) > 0) { p = calloc(MD_SWAPQ(shdr.s_size), sizeof(char)); if (!p) fatal("out of virtual memory"); if (fseek(fobj, MD_SWAPQ(shdr.s_scnptr), 0) == -1) fatal("could not read `.text' from executable", i); if (fread(p, MD_SWAPQ(shdr.s_size), 1, fobj) < 1) fatal("could not read text section from executable"); /* copy program section it into simulator target memory */ mem_bcopy(mem_access, mem, Write, MD_SWAPQ(shdr.s_vaddr), p, MD_SWAPQ(shdr.s_size)); /* release the section buffer */ free(p); } else warn("section `%s' is empty...", shdr.s_name); break; case ECOFF_STYP_BSS: case ECOFF_STYP_SBSS: /* no data to read... */ break; default: warn("section `%s' ignored...", shdr.s_name); } } /* done with the executable, close it */ if (fclose(fobj)) fatal("could not close executable `%s'", argv[0]); } #endif /* BFD_LOADER */ /* perform sanity checks on segment ranges */ if (!ld_text_base || !ld_text_size) fatal("executable is missing a `.text' section"); if (!ld_data_base || !ld_data_size) fatal("executable is missing a `.data' section"); if (!ld_prog_entry) fatal("program entry point not specified"); /* determine byte/words swapping required to execute on this host */ sim_swap_bytes = (endian_host_byte_order() != endian_target_byte_order()); if (sim_swap_bytes) { #if 0 /* FIXME: disabled until further notice... */ /* cross-endian is never reliable, why this is so is beyond the scope of this comment, e-mail me for details... */ fprintf(stderr, "sim: *WARNING*: swapping bytes to match host...\n"); fprintf(stderr, "sim: *WARNING*: swapping may break your program!\n"); /* #else */ fatal("binary endian does not match host endian"); #endif } sim_swap_words = (endian_host_word_order() != endian_target_word_order()); if (sim_swap_words) { #if 0 /* FIXME: disabled until further notice... */ /* cross-endian is never reliable, why this is so is beyond the scope of this comment, e-mail me for details... */ fprintf(stderr, "sim: *WARNING*: swapping words to match host...\n"); fprintf(stderr, "sim: *WARNING*: swapping may break your program!\n"); /* #else */ fatal("binary endian does not match host endian"); #endif } /* set up a local stack pointer, this is where the argv and envp data is written into program memory */ ld_stack_base = ld_text_base - (409600+4096); #if 0 sp = ROUND_DOWN(ld_stack_base - MD_MAX_ENVIRON, sizeof(MD_DOUBLE_TYPE)); #endif sp = ld_stack_base - MD_MAX_ENVIRON; ld_stack_size = ld_stack_base - sp; printf("Thread 0 stack size (4)%d\n", current->ld_stack_size); /* initial stack pointer value */ ld_environ_base = sp; /* write [argc] to stack */ temp = MD_SWAPQ(argc); mem_access(mem, Write, sp, &temp, sizeof(qword_t)); regs->regs_R[MD_REG_A0] = temp; sp += sizeof(qword_t); /* skip past argv array and NULL */ argv_addr = sp; regs->regs_R[MD_REG_A1] = argv_addr; sp = sp + (argc + 1) * sizeof(md_addr_t); /* save space for envp array and NULL */ envp_addr = sp; for (i=0; envp[i]; i++) sp += sizeof(md_addr_t); sp += sizeof(md_addr_t); /* fill in the argv pointer array and data */ for (i=0; i<argc; i++) { /* write the argv pointer array entry */ temp = MD_SWAPQ(sp); mem_access(mem, Write, argv_addr + i*sizeof(md_addr_t), &temp, sizeof(md_addr_t)); /* and the data */ mem_strcpy(mem_access, mem, Write, sp, argv[i]); sp += strlen(argv[i])+1; } /* terminate argv array with a NULL */ mem_access(mem, Write, argv_addr + i*sizeof(md_addr_t), &null_ptr, sizeof(md_addr_t)); /* write envp pointer array and data to stack */ for (i = 0; envp[i]; i++) { /* write the envp pointer array entry */ temp = MD_SWAPQ(sp); mem_access(mem, Write, envp_addr + i*sizeof(md_addr_t), &temp, sizeof(md_addr_t)); /* and the data */ mem_strcpy(mem_access, mem, Write, sp, envp[i]); sp += strlen(envp[i]) + 1; } /* terminate the envp array with a NULL */ mem_access(mem, Write, envp_addr + i*sizeof(md_addr_t), &null_ptr, sizeof(md_addr_t)); /* did we tromp off the stop of the stack? */ if (sp > ld_stack_base) { /* we did, indicate to the user that MD_MAX_ENVIRON must be increased, alternatively, you can use a smaller environment, or fewer command line arguments */ fatal("environment overflow, increase MD_MAX_ENVIRON in alpha.h"); } /* initialize the bottom of heap to top of data segment */ ld_brk_point = ROUND_UP(ld_data_base + ld_data_size, MD_PAGE_SIZE); /* set initial minimum stack pointer value to initial stack value */ ld_stack_min = regs->regs_R[MD_REG_SP]; regs->regs_R[MD_REG_SP] = ld_environ_base; regs->regs_PC = ld_prog_entry; printf("ld_text_base: 0x%08x ld_text_size: 0x%08x", ld_text_base, ld_text_size); printf("ld_data_base: 0x%08x ld_data_size: 0x%08x", ld_data_base, ld_data_size); printf("ld_stack_base: 0x%08x ld_stack_size: 0x%08x", ld_stack_base, ld_stack_size); printf("ld_prog_entry: 0x%08x", ld_prog_entry); debug("ld_text_base: 0x%08x ld_text_size: 0x%08x", ld_text_base, ld_text_size); debug("ld_data_base: 0x%08x ld_data_size: 0x%08x", ld_data_base, ld_data_size); debug("ld_stack_base: 0x%08x ld_stack_size: 0x%08x", ld_stack_base, ld_stack_size); debug("ld_prog_entry: 0x%08x", ld_prog_entry); }
int main (int argc, char **argv) { int o; int save_trace; bfd *prog; int rc; /* By default, we exit when an execution error occurs. */ execution_error_init_standalone (); while ((o = getopt_long (argc, argv, "tvdeEwi", sim_options, NULL)) != -1) { if (o == 'E') /* Stop processing the command line. This is so that any remaining words on the command line that look like arguments will be passed on to the program being simulated. */ break; if (o >= OPT_ACT) { int e, a; o -= OPT_ACT; e = o / SIM_ERRACTION_NUM_ACTIONS; a = o % SIM_ERRACTION_NUM_ACTIONS; execution_error_set_action (e, a); } else switch (o) { case 't': trace++; break; case 'v': verbose++; break; case 'd': disassemble++; break; case 'e': execution_error_init_standalone (); break; case 'w': execution_error_warn_all (); break; case 'i': execution_error_ignore_all (); break; case '?': { int i; fprintf (stderr, "usage: run [options] program [arguments]\n"); fprintf (stderr, "\t-v\t- increase verbosity.\n" "\t-t\t- trace.\n" "\t-d\t- disassemble.\n" "\t-E\t- stop processing sim args\n" "\t-e\t- exit on all execution errors.\n" "\t-w\t- warn (do not exit) on all execution errors.\n" "\t-i\t- ignore all execution errors.\n"); for (i=0; sim_options[i].name; i++) fprintf (stderr, "\t--%s\n", sim_options[i].name); exit (1); } } } prog = bfd_openr (argv[optind], 0); if (!prog) { fprintf (stderr, "Can't read %s\n", argv[optind]); exit (1); } if (!bfd_check_format (prog, bfd_object)) { fprintf (stderr, "%s not a rx program\n", argv[optind]); exit (1); } init_regs (); rx_in_gdb = 0; save_trace = trace; trace = 0; rx_load (prog, NULL); trace = save_trace; sim_disasm_init (prog); enable_counting = verbose; rc = setjmp (decode_jmp_buf); if (rc == 0) { if (!trace && !disassemble) { /* This will longjmp to the above if an exception happens. */ for (;;) decode_opcode (); } else while (1) { if (trace) printf ("\n"); if (disassemble) { enable_counting = 0; sim_disasm_one (); enable_counting = verbose; } rc = decode_opcode (); if (trace) trace_register_changes (); } } if (RX_HIT_BREAK (rc)) done (1); else if (RX_EXITED (rc)) done (RX_EXIT_STATUS (rc)); else if (RX_STOPPED (rc)) { if (verbose) printf("Stopped on signal %d\n", RX_STOP_SIG (rc)); exit(1); } done (0); exit (0); }
void replace_hello(const char *input_path, const char *output_path) { bfd_init(); bfd *ibfd = bfd_openr(input_path, NULL); if (ibfd == NULL) errx(1, bfd_errmsg(bfd_get_error())); if (!bfd_check_format(ibfd, bfd_object)) { bfd_close_all_done(ibfd); errx(1, "Input file is not a valid object file."); } bfd *obfd = bfd_openw(output_path, bfd_get_target(ibfd)); if (obfd == NULL) { bfd_close_all_done(ibfd); errx(1, bfd_errmsg(bfd_get_error())); } if (!bfd_set_format(obfd, bfd_get_format(ibfd))) { bfd_close_all_done(ibfd); bfd_close_all_done(obfd); errx(1, "Setting obfd format failed: %s\n", bfd_errmsg(bfd_get_error())); } bfd_set_arch_info(obfd, bfd_get_arch_info(ibfd)); // Create sections for .data asection *section = bfd_get_section_by_name(ibfd, ".data"); while (section != NULL) { if (section->flags & SEC_HAS_CONTENTS) { char *section_contents = (char *)malloc(section->size); bfd_get_section_contents(ibfd, section, section_contents, 0, section->size); char *hello_pos = (char *)memmem(section_contents, section->size, "hello", 5); if (hello_pos != NULL) { if (bfd_make_section_anyway_with_flags(obfd, ".data", section->flags) == NULL) { free(section_contents); bfd_close_all_done(ibfd); bfd_close_all_done(obfd); errx(1, bfd_errmsg(bfd_get_error())); } } free(section_contents); } section = bfd_get_next_section_by_name(ibfd, section); } asection *comment_section = bfd_make_section_anyway_with_flags(obfd, ".comment.my_objcopy", SEC_HAS_CONTENTS); if (comment_section == NULL) { bfd_close_all_done(ibfd); bfd_close_all_done(obfd); errx(1, bfd_errmsg(bfd_get_error())); } if (!bfd_set_section_size(obfd, comment_section, 3)) { bfd_close_all_done(ibfd); bfd_close_all_done(obfd); errx(1, bfd_errmsg(bfd_get_error())); } if (!bfd_set_section_contents(obfd, comment_section, "moo", 0, 3)) { bfd_close_all_done(ibfd); bfd_close_all_done(obfd); errx(1, bfd_errmsg(bfd_get_error())); } // section = bfd_get_section_by_name(ibfd, ".data"); // asection *osection = bfd_get_section_by_name(obfd, ".data"); // if (osection == NULL) { // bfd_close_all_done(ibfd); // bfd_close_all_done(obfd); // errx(1, bfd_errmsg(bfd_get_error())); // } // while (section != NULL) { // if (section->flags & SEC_HAS_CONTENTS) { // char *section_contents = (char *)malloc(section->size); // bfd_get_section_contents(ibfd, section, section_contents, 0, section->size); // // char *hello_pos = (char *)memmem(section_contents, section->size, "hello", 5); // if (hello_pos != NULL) { // hello_pos[1] = 'o'; // hello_pos[4] = 'a'; // if (bfd_set_section_contents(obfd, osection, section_contents, 0, section->size)) { // free(section_contents); // bfd_close_all_done(ibfd); // bfd_close_all_done(obfd); // errx(1, bfd_errmsg(bfd_get_error())); // } // } // // free(section_contents); // osection = bfd_get_next_section_by_name(obfd, osection); // } // // section = bfd_get_next_section_by_name(ibfd, section); // } if (!bfd_close(obfd)) errx(1, "Closing obfd failed: %s\n", bfd_errmsg(bfd_get_error())); if (!bfd_close(ibfd)) errx(1, "Closing ibfd failed: %s\n", bfd_errmsg(bfd_get_error())); }