Beispiel #1
0
static void find_addr_sect(bfd *abfd, asection *section, void *obj)
{
	struct bfd_data *data = obj;
	bfd_vma vma;
	bfd_size_type size;

	if (data->found)
		return;

	if (!(bfd_get_section_vma(abfd, section)))
		return;

	vma = bfd_get_section_vma(abfd, section);
	if (data->pc < vma)
		return;

	size = bfd_get_section_size(section);
	if (data->pc >= vma + size)
		return;

	data->found = bfd_find_nearest_line(abfd, section, syms,
					    data->pc - vma,
					    &data->filename,
					    &data->function,
					    &data->line);
}
Beispiel #2
0
static unsigned long
find_base (bfd *prog_bfd)
{
  int found;
  unsigned long base = ~(0UL);
  asection *s;

  found = 0;
  for (s = prog_bfd->sections; s; s = s->next)
    {
      if ((strcmp (bfd_get_section_name (prog_bfd, s), ".boot") == 0)
	  || (strcmp (bfd_get_section_name (prog_bfd, s), ".text") == 0)
	  || (strcmp (bfd_get_section_name (prog_bfd, s), ".data") == 0)
	  || (strcmp (bfd_get_section_name (prog_bfd, s), ".bss") == 0))
	{
	  if (!found)
	    {
	      base = bfd_get_section_vma (prog_bfd, s);
	      found = 1;
	    }
	  else
	    base =
	      bfd_get_section_vma (prog_bfd,
				   s) < base ? bfd_get_section_vma (prog_bfd,
								    s) : base;
	}
    }
  return base & ~(0xffffUL);
}
void
stacktrace::find_address_in_section (bfd* abfd, asection* section, void* data)
{
  stacktrace* self = static_cast<stacktrace*> (data);

  bfd_vma vma;
  bfd_size_type size;

  if (self->found)
    return;

  if ((bfd_get_section_flags (abfd, section) & SEC_ALLOC) == 0)
    return;

  vma = bfd_get_section_vma (abfd, section);
  if (self->pc < vma)
    return;

  size = bfd_section_size (abfd, section);
  if (self->pc >= vma + size)
    return;

  self->found = bfd_find_nearest_line (abfd, section, self->syms, self->pc - vma,
                                       &self->filename, &self->funcname, &self->line);
}
Beispiel #4
0
    bool resolve(uint64_t ip, SP_Location &loc)
    {
        uint64_t vma = bfd_get_section_vma(m_abfd, m_text);
        uint64_t size = bfd_get_section_size(m_text);
        uint64_t offset =  ip - vma;

        if (ip < vma || ip > vma + size)
            return false;

        loc.ip = ip;
        loc.module = m_path;

        const char *sym, *file;

        if (!bfd_find_nearest_line(m_abfd, m_text, m_syms, offset, &file, &sym, &loc.line))
            return false;

        loc.symbol = sym;
        loc.file = file ? file : "";

        char *demangled = cplus_demangle(sym, DMGL_AUTO);

        if (demangled) {
            loc.symbol = demangled;
            free(demangled);
        }

        return true;
    }
Beispiel #5
0
/** Find_Address_In_Section
 *
 * Localitza la direccio (pc) dins de la seccio ".text" del binari
 *
 * @param abfd
 * @param section
 * @param data
 *
 * @return No return value.
 */
static void BFDmanager_findAddressInSection (bfd * abfd, asection * section, PTR data)
{
#if HAVE_BFD_GET_SECTION_SIZE || HAVE_BFD_GET_SECTION_SIZE_BEFORE_RELOC
	bfd_size_type size;
#endif
	bfd_vma vma;
	BFDmanager_symbolInfo_t *symdata = (BFDmanager_symbolInfo_t*) data;

	if (symdata->found)
		return;

	if ((bfd_get_section_flags (abfd, section) & SEC_ALLOC) == 0)
		return;

	vma = bfd_get_section_vma (abfd, section);;

	if (symdata->pc < vma)
		return;

#if HAVE_BFD_GET_SECTION_SIZE
	size = bfd_get_section_size (section);
	if (symdata->pc >= vma + size)
		return;
#elif HAVE_BFD_GET_SECTION_SIZE_BEFORE_RELOC
	size = bfd_get_section_size_before_reloc (section);
	if (symdata->pc >= vma + size)
		return;
#else
	/* Do nothing? */
#endif

	symdata->found = bfd_find_nearest_line (abfd, section, symdata->symbols,
	  symdata->pc - vma, &symdata->filename, &symdata->function,
	  &symdata->line);
}
Beispiel #6
0
/* Look for an address in a section.
 * This is called via bfd_map_over_sections.
 */
static void
find_address_in_section (bfd *abfd,
			 asection *section,
			 void *data)
{
    bfd_vma vma;
    bfd_size_type size;
    struct symbol *symbol = data;
    struct symtab *symtab = symbol->symtab;

    if (symbol->found)
	return;

    if ((bfd_get_section_flags (symtab->bfd, section) & SEC_ALLOC) == 0)
	return;

    vma = bfd_get_section_vma (symtab->bfd, section);
    if (symbol->pc < vma)
	return;

    size = bfd_section_size (symtab->bfd, section);
    if (symbol->pc >= vma + size)
	return;

    symbol->found = bfd_find_nearest_line (symtab->bfd, section,
	                                   symtab->syms,
					   symbol->pc - vma,
					   &symbol->filename,
					   &symbol->functionname,
					   &symbol->line);
}
Beispiel #7
0
static void debug_translateAddress(const char *symbol, bfd_vma address)
{
   const char *file, *func;
   unsigned int line;
   asection *section;

   for (section = abfd->sections; section != NULL; section = section->next) {
      if ((bfd_get_section_flags(abfd, section) & SEC_ALLOC) == 0)
         continue;

      bfd_vma vma = bfd_get_section_vma(abfd, section);
      bfd_size_type size = bfd_get_section_size(section);
      if (address < vma || address >= vma + size)
         continue;

      if (!bfd_find_nearest_line(abfd, section, syms, address - vma,
            &file, &func, &line))
         continue;

      do {
         if (func == NULL || func[0] == '\0')
            func = "??";
         if (file == NULL || file[0] == '\0')
            file = "??";
         DEBUG("%s %s(...):%u %s", symbol, func, line, file);
      } while (bfd_find_inliner_info(abfd, &file, &func, &line));

      return;
   }

   DEBUG("%s %s(...):%u %s", symbol, "??", 0, "??");
}
Beispiel #8
0
static void find_address_in_section(bfd *abfd, asection *section, void *data)
{
	bfd_vma pc, vma;
	bfd_size_type size;
	struct a2l_data *a2l = data;

	if (a2l->found)
		return;

	if ((bfd_get_section_flags(abfd, section) & SEC_ALLOC) == 0)
		return;

	pc = a2l->addr;
	vma = bfd_get_section_vma(abfd, section);
	size = bfd_get_section_size(section);

	if (pc < vma || pc >= vma + size)
		return;

	a2l->found = bfd_find_nearest_line(abfd, section, a2l->syms, pc - vma,
					   &a2l->filename, &a2l->funcname,
					   &a2l->line);

	if (a2l->filename && !strlen(a2l->filename))
		a2l->filename = NULL;
}
Beispiel #9
0
/* Read inferior memory at ADDR to find the header of a loaded object file
   and read its in-core symbols out of inferior memory.  TEMPL is a bfd
   representing the target's format.  NAME is the name to use for this
   symbol file in messages; it can be NULL or a malloc-allocated string
   which will be attached to the BFD.  */
static struct objfile *
symbol_file_add_from_memory (struct bfd *templ, CORE_ADDR addr, char *name,
			     int from_tty)
{
  struct objfile *objf;
  struct bfd *nbfd;
  struct bfd_section *sec;
  bfd_vma loadbase;
  struct section_addr_info *sai;
  unsigned int i;
  struct cleanup *cleanup;

  if (bfd_get_flavour (templ) != bfd_target_elf_flavour)
    error (_("add-symbol-file-from-memory not supported for this target"));

  nbfd = bfd_elf_bfd_from_remote_memory (templ, addr, &loadbase,
					 target_read_memory_bfd);
  if (nbfd == NULL)
    error (_("Failed to read a valid object file image from memory."));

  gdb_bfd_ref (nbfd);
  if (name == NULL)
    nbfd->filename = "shared object read from target memory";
  else
    {
      nbfd->filename = name;
      gdb_bfd_stash_filename (nbfd);
      xfree (name);
    }

  cleanup = make_cleanup_bfd_unref (nbfd);

  if (!bfd_check_format (nbfd, bfd_object))
    error (_("Got object file from memory but can't read symbols: %s."),
	   bfd_errmsg (bfd_get_error ()));

  sai = alloc_section_addr_info (bfd_count_sections (nbfd));
  make_cleanup (xfree, sai);
  i = 0;
  for (sec = nbfd->sections; sec != NULL; sec = sec->next)
    if ((bfd_get_section_flags (nbfd, sec) & (SEC_ALLOC|SEC_LOAD)) != 0)
      {
	sai->other[i].addr = bfd_get_section_vma (nbfd, sec) + loadbase;
	sai->other[i].name = (char *) bfd_get_section_name (nbfd, sec);
	sai->other[i].sectindex = sec->index;
	++i;
      }
  sai->num_sections = i;

  objf = symbol_file_add_from_bfd (nbfd, bfd_get_filename (nbfd),
				   from_tty ? SYMFILE_VERBOSE : 0,
                                   sai, OBJF_SHARED, NULL);

  /* This might change our ideas about frames already looked at.  */
  reinit_frame_cache ();

  do_cleanups (cleanup);
  return objf;
}
Beispiel #10
0
static void process_section(bfd *bfdobj, asection *section, void *obj)
{
	struct bfd_data *data = obj;
	const char *file, *func;
	unsigned int line;
	bfd_vma offset;
	bfd_vma vma;
	bfd_size_type size;
	bfd_boolean line_found = 0;
	char *fn;
	int inlined = 0;

	offset = data->pc - (data->dynamic ? (bfd_vma)(uintptr_t) data->dli.dli_fbase : 0);

	if (!(bfd_get_section_flags(bfdobj, section) & SEC_ALLOC)) {
		return;
	}

	vma = bfd_get_section_vma(bfdobj, section);
	size = bfd_get_section_size(section);

	if (offset < vma || offset >= vma + size) {
		/* Not in this section */
		return;
	}

	line_found = bfd_find_nearest_line(bfdobj, section, data->syms, offset - vma, &file,
		&func, &line);
	if (!line_found) {
		return;
	}

	/*
	 * If we find a line, we will want to continue calling bfd_find_inliner_info
	 * to capture any inlined functions that don't have their own stack frames.
	 */
	do {
		data->found++;
		/* file can possibly be null even with a success result from bfd_find_nearest_line */
		file = file ? file : "";
		fn = strrchr(file, '/');
#define FMT_INLINED     "[%s] %s %s:%u %s()"
#define FMT_NOT_INLINED "[%p] %s %s:%u %s()"

		snprintf(data->msg, MSG_BUFF_LEN, inlined ? FMT_INLINED : FMT_NOT_INLINED,
			inlined ? "inlined" : (char *)(uintptr_t) data->pc,
			data->libname,
			fn ? fn + 1 : file,
			line, S_OR(func, "???"));

		if (AST_VECTOR_APPEND(data->return_strings, strdup(data->msg))) {
			return;
		}

		inlined++;
		/* Let's see if there are any inlined functions */
	} while (bfd_find_inliner_info(bfdobj, &file, &func, &line));
}
Beispiel #11
0
int main(int argc, char *argv[])
{
    bfd *abfd;
    asection *text;
    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;
    }
    if ((storage_needed = bfd_get_symtab_upper_bound(abfd)) < 0)
        return -1;
    symbol_table = (asymbol **) xmalloc(storage_needed);
    number_of_symbols = bfd_canonicalize_symtab(abfd, symbol_table);
    if (number_of_symbols < 0)
        return -1;
    fun_table = (FUN_TABLE **)malloc(sizeof(FUN_TABLE)*number_of_symbols);
    bzero(fun_table, sizeof(FUN_TABLE)*number_of_symbols);

    for (i = 0; i < number_of_symbols; i++) {
        if (symbol_table[i]->flags & (BSF_FUNCTION|BSF_GLOBAL)) {
            section = symbol_table[i]->section;
            section_vma = bfd_get_section_vma(abfd, section);
            symbol_name = symbol_table[i]->name;
            symbol_offset = symbol_table[i]->value;
            symbol_address = section_vma + symbol_offset;
            if (section->flags & SEC_CODE) {
                add_function_table(symbol_name,
                                   symbol_address);
            }
        }
    }
    bfd_close(abfd);
    /* 將函式對照表作排序 */
    qsort(fun_table, table_count, sizeof(FUN_TABLE), compare_function);
    dump_function_table();
}
Beispiel #12
0
static int
derive_heap_segment (bfd *abfd, bfd_vma *bottom, bfd_vma *top)
{
  bfd_vma top_of_data_memory = 0;
  bfd_vma top_of_heap = 0;
  bfd_size_type sec_size;
  bfd_vma sec_vaddr;
  asection *sec;

  gdb_assert (bottom);
  gdb_assert (top);

  /* This function depends on being able to call a function in the
     inferior.  */
  if (!target_has_execution)
    return 0;

  /* The following code assumes that the link map is arranged as
     follows (low to high addresses):

     ---------------------------------
     | text sections                 |
     ---------------------------------
     | data sections (including bss) |
     ---------------------------------
     | heap                          |
     --------------------------------- */

  for (sec = abfd->sections; sec; sec = sec->next)
    {
      if (bfd_get_section_flags (abfd, sec) & SEC_DATA
	  || strcmp (".bss", bfd_section_name (abfd, sec)) == 0)
	{
	  sec_vaddr = bfd_get_section_vma (abfd, sec);
	  sec_size = bfd_get_section_size (sec);
	  if (sec_vaddr + sec_size > top_of_data_memory)
	    top_of_data_memory = sec_vaddr + sec_size;
	}
    }

  top_of_heap = call_target_sbrk (0);
  if (top_of_heap == (bfd_vma) 0)
    return 0;

  /* Return results.  */
  if (top_of_heap > top_of_data_memory)
    {
      *bottom = top_of_data_memory;
      *top = top_of_heap;
      return 1;
    }

  /* No additional heap space needs to be saved.  */
  return 0;
}
/* Read inferior memory at ADDR to find the header of a loaded object file
   and read its in-core symbols out of inferior memory.  TEMPL is a bfd
   representing the target's format.  NAME is the name to use for this
   symbol file in messages; it can be NULL or a malloc-allocated string
   which will be attached to the BFD.  */
static struct objfile *
symbol_file_add_from_memory (struct bfd *templ, CORE_ADDR addr, char *name,
			     int from_tty)
{
  struct objfile *objf;
  struct bfd *nbfd;
  struct bfd_section *sec;
  bfd_vma loadbase;
  struct section_addr_info *sai;
  unsigned int i;

  if (bfd_get_flavour (templ) != bfd_target_elf_flavour)
    error (_("add-symbol-file-from-memory not supported for this target"));

  nbfd = bfd_elf_bfd_from_remote_memory (templ, addr, &loadbase,
					 target_read_memory);
  if (nbfd == NULL)
    error (_("Failed to read a valid object file image from memory."));

  if (name == NULL)
    nbfd->filename = xstrdup ("shared object read from target memory");
  else
    nbfd->filename = name;

  if (!bfd_check_format (nbfd, bfd_object))
    {
      /* 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).  */
      bfd_close (nbfd);
      error (_("Got object file from memory but can't read symbols: %s."),
	     bfd_errmsg (bfd_get_error ()));
    }

  sai = alloc_section_addr_info (bfd_count_sections (nbfd));
  make_cleanup (xfree, sai);
  i = 0;
  for (sec = nbfd->sections; sec != NULL; sec = sec->next)
    if ((bfd_get_section_flags (nbfd, sec) & (SEC_ALLOC|SEC_LOAD)) != 0)
      {
	sai->other[i].addr = bfd_get_section_vma (nbfd, sec) + loadbase;
	sai->other[i].name = (char *) bfd_get_section_name (nbfd, sec);
	sai->other[i].sectindex = sec->index;
	++i;
      }

  objf = symbol_file_add_from_bfd (nbfd, from_tty ? SYMFILE_VERBOSE : 0,
                                   sai, OBJF_SHARED);

  /* This might change our ideas about frames already looked at.  */
  reinit_frame_cache ();

  return objf;
}
Beispiel #14
0
/* Read inferior memory at ADDR to find the header of a loaded object file
   and read its in-core symbols out of inferior memory.  SIZE, if
   non-zero, is the known size of the object.  TEMPL is a bfd
   representing the target's format.  NAME is the name to use for this
   symbol file in messages; it can be NULL or a malloc-allocated string
   which will be attached to the BFD.  */
static struct objfile *
symbol_file_add_from_memory (struct bfd *templ, CORE_ADDR addr,
			     size_t size, char *name, int from_tty)
{
  struct objfile *objf;
  struct bfd *nbfd;
  struct bfd_section *sec;
  bfd_vma loadbase;
  symfile_add_flags add_flags = 0;

  if (bfd_get_flavour (templ) != bfd_target_elf_flavour)
    error (_("add-symbol-file-from-memory not supported for this target"));

  nbfd = bfd_elf_bfd_from_remote_memory (templ, addr, size, &loadbase,
					 target_read_memory_bfd);
  if (nbfd == NULL)
    error (_("Failed to read a valid object file image from memory."));

  /* Manage the new reference for the duration of this function.  */
  gdb_bfd_ref_ptr nbfd_holder = gdb_bfd_ref_ptr::new_reference (nbfd);

  xfree (bfd_get_filename (nbfd));
  if (name == NULL)
    nbfd->filename = xstrdup ("shared object read from target memory");
  else
    nbfd->filename = name;

  if (!bfd_check_format (nbfd, bfd_object))
    error (_("Got object file from memory but can't read symbols: %s."),
	   bfd_errmsg (bfd_get_error ()));

  section_addr_info sai;
  for (sec = nbfd->sections; sec != NULL; sec = sec->next)
    if ((bfd_get_section_flags (nbfd, sec) & (SEC_ALLOC|SEC_LOAD)) != 0)
      sai.emplace_back (bfd_get_section_vma (nbfd, sec) + loadbase,
			bfd_get_section_name (nbfd, sec),
			sec->index);

  if (from_tty)
    add_flags |= SYMFILE_VERBOSE;

  objf = symbol_file_add_from_bfd (nbfd, bfd_get_filename (nbfd),
				   add_flags, &sai, OBJF_SHARED, NULL);

  add_target_sections_of_objfile (objf);

  /* This might change our ideas about frames already looked at.  */
  reinit_frame_cache ();

  return objf;
}
Beispiel #15
0
// Look for an address in a section.  This is called via  bfd_map_over_sections.
static void find_address_in_section (bfd *abfd, asection *section, PTR data)
{
	struct find_handle *info = (struct find_handle *) data;
	bfd_vma vma;
	bfd_size_type size;

	if (info->found)
		return;

	if ((bfd_get_section_flags (abfd, section) & SEC_ALLOC) == 0)
		return;

	vma = bfd_get_section_vma (abfd, section);
	size = bfd_get_section_size (section);

	if (info->pc < (vma = bfd_get_section_vma (abfd, section)))
		return;

	if (info->pc >= vma + (size = bfd_get_section_size (section)))
		return;

	info->found = bfd_find_nearest_line (abfd, section, info->syms, info->pc - vma, &info->filename, &info->functionname, &info->line);
}
Beispiel #16
0
enum sh64_elf_cr_type
sh64_get_contents_type (asection *sec, bfd_vma addr, sh64_elf_crange *rangep)
{
  asection *cranges;

  /* Fill in the range with the boundaries of the section as a default.  */
  if (bfd_get_flavour (sec->owner) == bfd_target_elf_flavour
      && elf_elfheader (sec->owner)->e_type == ET_EXEC)
    {
      rangep->cr_addr = bfd_get_section_vma (sec->owner, sec);
      rangep->cr_size = sec->size;
      rangep->cr_type = CRT_NONE;
    }
  else
    return FALSE;

  /* If none of the pertinent bits are set, then it's a SHcompact (or at
     least not SHmedia).  */
  if ((elf_section_data (sec)->this_hdr.sh_flags
       & (SHF_SH5_ISA32 | SHF_SH5_ISA32_MIXED)) == 0)
    {
      enum sh64_elf_cr_type cr_type
	= ((bfd_get_section_flags (sec->owner, sec) & SEC_CODE) != 0
	   ? CRT_SH5_ISA16 : CRT_DATA);
      rangep->cr_type = cr_type;
      return cr_type;
    }

  /* If only the SHF_SH5_ISA32 bit is set, then we have SHmedia.  */
  if ((elf_section_data (sec)->this_hdr.sh_flags
       & (SHF_SH5_ISA32 | SHF_SH5_ISA32_MIXED)) == SHF_SH5_ISA32)
    {
      rangep->cr_type = CRT_SH5_ISA32;
      return CRT_SH5_ISA32;
    }

  /* Otherwise, we have to look up the .cranges section.  */
  cranges = bfd_get_section_by_name (sec->owner, SH64_CRANGES_SECTION_NAME);

  if (cranges == NULL)
    /* A mixed section but there's no .cranges section.  This is probably
       bad input; it does not comply to specs.  */
    return CRT_NONE;

  /* If this call fails, we will still have CRT_NONE in rangep->cr_type
     and that will be suitable to return.  */
  sh64_address_in_cranges (cranges, addr, rangep);

  return rangep->cr_type;
}
Beispiel #17
0
static void
get_section_vmas (bfd *abfd, asection *sectp, void *context)
{
  struct read_pe_section_data *sections = context;
  int sectix = read_pe_section_index (sectp->name);

  if (sectix != PE_SECTION_INDEX_INVALID)
    {
      /* Data within the section start at rva_start in the pe and at
         bfd_get_section_vma() within memory. Store the offset. */

      sections[sectix].vma_offset
	= bfd_get_section_vma (abfd, sectp) - sections[sectix].rva_start;
    }
}
void lookup_section(bfd * abfd, asection * sec, void * opaque_data)
{
	find_info * data = (find_info*)opaque_data;

	if (data->func)
		return;

	if (!(bfd_get_section_flags(abfd, sec) & SEC_ALLOC))
		return;

	bfd_vma vma = bfd_get_section_vma(abfd, sec);
	if (data->counter < vma || vma + bfd_get_section_size(sec) <= data->counter)
		return;

	bfd_find_nearest_line(abfd, sec, data->symbol, data->counter - vma, &(data->file), &(data->func), &(data->line));
}
Beispiel #19
0
void traceback::Bfd::Context::lookup_section(bfd* abfd, asection* sec, void* opaque_data)
{
	Bfd::Info* data = static_cast<Bfd::Info*>(opaque_data);

	if (data->func)
		return;

	if (!(bfd_get_section_flags(abfd, sec) & SEC_ALLOC))
		return;

	bfd_vma vma = bfd_get_section_vma(abfd, sec);
	if (data->counter < vma || vma + bfd_get_section_size(sec) <= data->counter)
		return;

	data->displacement = data->counter - vma;
	bfd_find_nearest_line(abfd, sec, data->symbol, data->displacement, &(data->file), &(data->func), &(data->line));
}
Beispiel #20
0
/**
 * Lookup callback.
 */
static void
bfd_util_lookup_section(bfd *b, asection *sec, void *data)
{
	struct symbol_ctx *sc = data;
	bfd_vma vma;

	if (sc->location.function != NULL)
		return;		/* Already found */

	if (0 == (bfd_get_section_flags(b, sec) & SEC_ALLOC))
		return;

	vma = bfd_get_section_vma(b, sec);
	if (sc->addr < vma || sc->addr >= bfd_get_section_size(sec) + vma)
		return;

	bfd_find_nearest_line(b, sec, sc->symbols, sc->addr - vma,
		&sc->location.file, &sc->location.function, &sc->location.line);
}
Beispiel #21
0
static void find_address_in_section(bfd *abfd, asection *section, void *data) {
  addr2line_data *adata = reinterpret_cast<addr2line_data*>(data);

  bfd_vma vma;
  bfd_size_type size;

  if (adata->found) {
    return;
  }

  if ((bfd_get_section_flags(abfd, section) & SEC_ALLOC) == 0) {
    return;
  }

  vma = bfd_get_section_vma(abfd, section);
  if (adata->pc < vma) {
    return;
  }

  size = bfd_get_section_size(section);
  if (adata->pc >= vma + size) {
    return;
  }

  // libdwarf allocates its own unaligned memory so it doesn't play well with
  // valgrind
#ifndef VALGRIND
  adata->found = bfd_find_nearest_line(abfd, section, adata->syms,
                                       adata->pc - vma, &adata->filename,
                                       &adata->functionname, &adata->line);
#endif

  if (adata->found) {
    const char *file = adata->filename;
    unsigned int line = adata->line;
    bfd_boolean found = TRUE;
    while (found) {
      found = bfd_find_inliner_info(abfd, &file, &adata->functionname, &line);
    }
  }
}
Beispiel #22
0
/// Examines the bfd in order to find the sections containing data to be loaded.
/// Also fills the program_data array.
void trap::ExecLoader::load_program_data() {
  bfd_section* p = NULL;
  std::map<unsigned long, unsigned char> mem_map;
  for (p = this->exec_image->sections; p != NULL; p = p->next) {
    flagword flags = bfd_get_section_flags(this->exec_image, p);
    if ((flags & SEC_ALLOC) != 0 && (flags & SEC_DEBUGGING) == 0 && (flags & SEC_THREAD_LOCAL) == 0) {
      //Ok, this is a section which must be in the final executable;
      //Lets see if it has content: if not I have to pad the section with zeros,
      //otherwise I load it
      bfd_size_type datasize = bfd_section_size(this->exec_image, p);
      bfd_vma vma = bfd_get_section_vma(this->exec_image, p);
      std::map<unsigned long, unsigned char>::iterator mem_it = mem_map.begin();
      if ((flags & SEC_HAS_CONTENTS) != 0) {
/*#ifndef NDEBUG
        std::cerr << "Loading data fom section " << p->name << " Start Address " << std::showbase << std::hex << vma << " Size " << std::hex << datasize << " End Address " << std::hex << datasize + vma << std::dec << " Swap Endianess " << swap_endianess << " flags " << std::hex << std::showbase << flags << std::dec << std::endl;
#endif*/
        bfd_byte* data = new bfd_byte[datasize];
        bfd_get_section_contents (this->exec_image, p, data, 0, datasize);
        for (unsigned i = 0; i < datasize; i++) {
          mem_it = mem_map.insert(mem_it, std::pair<unsigned long, unsigned char>(vma + i, data[i]));
        }
        delete [] data;
      } else {
/*#ifndef NDEBUG
        std::cerr << "Filling with 0s section " << p->name << " Start Address " << std::showbase << std::hex << vma << " Size " << std::hex << datasize << " End Address " << std::hex << datasize + vma << std::dec << std::endl;
#endif*/
        for (unsigned i = 0; i < datasize; i++)
          mem_it = mem_map.insert(mem_it, std::pair<unsigned long, unsigned char>(vma + i, 0));
      }
    }
  }
  //ok,  I now have all the map of the memory; I simply have to fill in the
  //this->program_data  array
  this->data_start = mem_map.begin()->first;
  this->program_dim = mem_map.rbegin()->first - this->data_start + 1;
  this->program_data = new unsigned char[this->program_dim];
  std::map<unsigned long, unsigned char>::iterator mem_it,  mem_end;
  for (mem_it = mem_map.begin(),  mem_end = mem_map.end(); mem_it != mem_end; mem_it++) {
    this->program_data[mem_it->first - this->data_start] = mem_it->second;
  }
} // ExecLoader::load_program_data()
Beispiel #23
0
    static void find_address_in_section (bfd *abfd, asection *section, void *data)
    {
        GetFileLineContext* ctx = static_cast<GetFileLineContext*>(data);

        if (ctx->found) return;

        uint64_t pc = ctx->address;
        
        if ((bfd_get_section_flags (abfd, section) & SEC_ALLOC) == 0)
            return;

        bfd_vma vma = bfd_get_section_vma (abfd, section);
        if (pc < vma)
            return;

        bfd_size_type size = bfd_get_section_size (section);
        if (pc >= vma + size)
            return;

        ctx->found = bfd_find_nearest_line (abfd, section, ctx->syms, pc - vma, &ctx->filename, &ctx->functionname, &ctx->line);
    }
Beispiel #24
0
static void find_address_in_section(bfd *abfd, asection *section, void *data) {
  addr2line_data *adata = reinterpret_cast<addr2line_data*>(data);

  bfd_vma vma;
  bfd_size_type size;

  if (adata->found) {
    return;
  }

  if ((bfd_get_section_flags(abfd, section) & SEC_ALLOC) == 0) {
    return;
  }

  vma = bfd_get_section_vma(abfd, section);
  if (adata->pc < vma) {
    return;
  }

  size = bfd_get_section_size(section);
  if (adata->pc >= vma + size) {
    return;
  }

  adata->found = bfd_find_nearest_line(abfd, section, adata->syms,
                                       adata->pc - vma, &adata->filename,
                                       &adata->functionname, &adata->line);
  if (adata->found) {
    const char *file = adata->filename;
    unsigned int line = adata->line;
    bfd_boolean found = TRUE;
    while (found) {
      found = bfd_find_inliner_info(abfd, &file, &adata->functionname, &line);
    }
  }
}
Beispiel #25
0
static bfd_boolean
pex64_bfd_print_pdata_section (bfd *abfd, void *vfile, asection *pdata_section)
{
  FILE *file = (FILE *) vfile;
  bfd_byte *pdata = NULL;
  bfd_byte *xdata = NULL;
  asection *xdata_section = NULL;
  bfd_vma xdata_base;
  bfd_size_type i;
  bfd_size_type datasize;
  bfd_size_type stop;
  bfd_vma prev_beginaddress = (bfd_vma) -1;
  bfd_vma prev_unwinddata_rva = (bfd_vma) -1;
  bfd_vma imagebase;
  int onaline = PDATA_ROW_SIZE;
  int seen_error = 0;
  bfd_vma *xdata_arr = NULL;
  int xdata_arr_cnt;
  bfd_boolean virt_size_is_zero = FALSE;

  /* Sanity checks.  */
  if (pdata_section == NULL
      || coff_section_data (abfd, pdata_section) == NULL
      || pei_section_data (abfd, pdata_section) == NULL)
    return TRUE;

  stop = pei_section_data (abfd, pdata_section)->virt_size;
  if ((stop % onaline) != 0)
    fprintf (file,
	     _("Warning: %s section size (%ld) is not a multiple of %d\n"),
	     pdata_section->name, (long) stop, onaline);

  datasize = pdata_section->size;
  if (datasize == 0)
    {
      if (stop)
	fprintf (file, _("Warning: %s section size is zero\n"),
		 pdata_section->name);
      return TRUE;
    }

  /* virt_size might be zero for objects.  */
  if (stop == 0 && strcmp (abfd->xvec->name, "pe-x86-64") == 0)
    {
      stop = (datasize / onaline) * onaline;
      virt_size_is_zero = TRUE;
    }
  else if (datasize < stop)
      {
	fprintf (file,
		 _("Warning: %s section size (%ld) is smaller than virtual size (%ld)\n"),
		 pdata_section->name, (unsigned long) datasize,
		 (unsigned long) stop);
	/* Be sure not to read passed datasize.  */
	stop = datasize / onaline;
      }

  /* Display functions table.  */
  fprintf (file,
	   _("\nThe Function Table (interpreted %s section contents)\n"),
	   pdata_section->name);

  fprintf (file, _("vma:\t\t\tBeginAddress\t EndAddress\t  UnwindData\n"));

  if (!bfd_malloc_and_get_section (abfd, pdata_section, &pdata))
    goto done;

  /* Table of xdata entries.  */
  xdata_arr = (bfd_vma *) xmalloc (sizeof (bfd_vma) * ((stop / onaline) + 1));
  xdata_arr_cnt = 0;

  if (strcmp (abfd->xvec->name, "pei-x86-64") == 0)
    imagebase = pe_data (abfd)->pe_opthdr.ImageBase;
  else
    imagebase = 0;

  for (i = 0; i < stop; i += onaline)
    {
      struct pex64_runtime_function rf;

      if (i + PDATA_ROW_SIZE > stop)
	break;

      pex64_get_runtime_function (abfd, &rf, &pdata[i]);

      if (rf.rva_BeginAddress == 0 && rf.rva_EndAddress == 0
	  && rf.rva_UnwindData == 0)
	/* We are probably into the padding of the section now.  */
	break;
      fputc (' ', file);
      fprintf_vma (file, i + pdata_section->vma);
      fprintf (file, ":\t");
      fprintf_vma (file, imagebase + rf.rva_BeginAddress);
      fprintf (file, " ");
      fprintf_vma (file, imagebase + rf.rva_EndAddress);
      fprintf (file, " ");
      fprintf_vma (file, imagebase + rf.rva_UnwindData);
      fprintf (file, "\n");
      if (i != 0 && rf.rva_BeginAddress <= prev_beginaddress)
	{
	  seen_error = 1;
	  fprintf (file, "  has %s begin address as predecessor\n",
	    (rf.rva_BeginAddress < prev_beginaddress ? "smaller" : "same"));
        }
      prev_beginaddress = rf.rva_BeginAddress;
      /* Now we check for negative addresses.  */
      if ((prev_beginaddress & 0x80000000) != 0)
	{
	  seen_error = 1;
	  fprintf (file, "  has negative begin address\n");
	}
      if ((rf.rva_EndAddress & 0x80000000) != 0)
	{
	  seen_error = 1;
	  fprintf (file, "  has negative end address\n");
	}
      if ((rf.rva_UnwindData & 0x80000000) != 0)
	{
	  seen_error = 1;
	  fprintf (file, "  has negative unwind address\n");
	}
      else if ((rf.rva_UnwindData && !PEX64_IS_RUNTIME_FUNCTION_CHAINED (&rf))
		|| virt_size_is_zero)
	xdata_arr[xdata_arr_cnt++] = rf.rva_UnwindData;
    }

  if (seen_error)
    goto done;

  /* Add end of list marker.  */
  xdata_arr[xdata_arr_cnt++] = ~((bfd_vma) 0);

  /* Sort start RVAs of xdata.  */
  if (xdata_arr_cnt > 1)
    qsort (xdata_arr, (size_t) xdata_arr_cnt, sizeof (bfd_vma),
	   sort_xdata_arr);

  /* Find the section containing the unwind data (.xdata).  */
  xdata_base = xdata_arr[0];
  /* For sections with long names, first look for the same
     section name, replacing .pdata by .xdata prefix.  */
  if (strcmp (pdata_section->name, ".pdata") != 0)
    {
      size_t len = strlen (pdata_section->name);
      char *xdata_name = alloca (len + 1);

      xdata_name = memcpy (xdata_name, pdata_section->name, len + 1);
      /* Transform .pdata prefix into .xdata prefix.  */
      if (len > 1)
	xdata_name [1] = 'x';
      xdata_section = pex64_get_section_by_rva (abfd, xdata_base,
						xdata_name);
    }
  /* Second, try the .xdata section itself.  */
  if (!xdata_section)
    xdata_section = pex64_get_section_by_rva (abfd, xdata_base, ".xdata");
  /* Otherwise, if xdata_base is non zero, search also inside
     other standard sections.  */
  if (!xdata_section && xdata_base)
    xdata_section = pex64_get_section_by_rva (abfd, xdata_base, ".rdata");
  if (!xdata_section && xdata_base)
    xdata_section = pex64_get_section_by_rva (abfd, xdata_base, ".data");
  if (!xdata_section && xdata_base)
    xdata_section = pex64_get_section_by_rva (abfd, xdata_base, ".pdata");
  if (!xdata_section && xdata_base)
    xdata_section = pex64_get_section_by_rva (abfd, xdata_base, ".text");
  /* Transfer xdata section into xdata array.  */
  if (!xdata_section
      || !bfd_malloc_and_get_section (abfd, xdata_section, &xdata))
    goto done;

  /* Avoid "also used "... ouput for single unwind info
     in object file.  */
  prev_unwinddata_rva = (bfd_vma) -1;

  /* Do dump of pdata related xdata.  */
  for (i = 0; i < stop; i += onaline)
    {
      struct pex64_runtime_function rf;

      if (i + PDATA_ROW_SIZE > stop)
	break;

      pex64_get_runtime_function (abfd, &rf, &pdata[i]);

      if (rf.rva_BeginAddress == 0 && rf.rva_EndAddress == 0
	  && rf.rva_UnwindData == 0)
	/* We are probably into the padding of the section now.  */
	break;
      if (i == 0)
        fprintf (file, _("\nDump of %s\n"), xdata_section->name);

      fputc (' ', file);
      fprintf_vma (file, rf.rva_UnwindData + imagebase);

      if (prev_unwinddata_rva == rf.rva_UnwindData)
	{
	  /* Do not dump again the xdata for the same entry.  */
	  fprintf (file, " also used for function at ");
	  fprintf_vma (file, rf.rva_BeginAddress + imagebase);
	  fputc ('\n', file);
	  continue;
	}
      else
	prev_unwinddata_rva = rf.rva_UnwindData;

      fprintf (file, " (rva: %08x): ",
	       (unsigned int) rf.rva_UnwindData);
      fprintf_vma (file, rf.rva_BeginAddress + imagebase);
      fprintf (file, " - ");
      fprintf_vma (file, rf.rva_EndAddress + imagebase);
      fputc ('\n', file);

      if (rf.rva_UnwindData != 0 || virt_size_is_zero)
	{
	  if (PEX64_IS_RUNTIME_FUNCTION_CHAINED (&rf))
	    {
	      bfd_vma altent = PEX64_GET_UNWINDDATA_UNIFIED_RVA (&rf);
	      bfd_vma pdata_vma = bfd_get_section_vma (abfd, pdata_section);
	      struct pex64_runtime_function arf;

	      fprintf (file, "\t shares information with ");
	      altent += imagebase;

	      if (altent >= pdata_vma
		  && (altent + PDATA_ROW_SIZE <= pdata_vma
		      + pei_section_data (abfd, pdata_section)->virt_size))
		{
		  pex64_get_runtime_function
		    (abfd, &arf, &pdata[altent - pdata_vma]);
		  fprintf (file, "pdata element at 0x");
		  fprintf_vma (file, arf.rva_UnwindData);
		}
	      else
		fprintf (file, "unknown pdata element");
	      fprintf (file, ".\n");
	    }
	  else
	    {
	      bfd_vma *p;

	      /* Search for the current entry in the sorted array.  */
	      p = (bfd_vma *)
	          bsearch (&rf.rva_UnwindData, xdata_arr,
			   (size_t) xdata_arr_cnt, sizeof (bfd_vma),
			   sort_xdata_arr);

	      /* Advance to the next pointer into the xdata section.  We may
		 have shared xdata entries, which will result in a string of
		 identical pointers in the array; advance past all of them.  */
	      while (p[0] <= rf.rva_UnwindData)
		++p;

	      if (p[0] == ~((bfd_vma) 0))
		p = NULL;

	      pex64_dump_xdata (file, abfd, xdata_section, xdata, p, &rf);
	    }
	}
    }

 done:
  free (pdata);
  free (xdata_arr);
  free (xdata);

  return TRUE;
}
Beispiel #26
0
void
core_create_function_syms (void)
{
  bfd_vma min_vma = ~ (bfd_vma) 0;
  bfd_vma max_vma = 0;
  int cxxclass;
  long i;
  struct function_map * found = NULL;
  int core_has_func_syms = 0;

  switch (core_bfd->xvec->flavour)
    {
    default:
      break;
    case bfd_target_coff_flavour:
    case bfd_target_ecoff_flavour:
    case bfd_target_xcoff_flavour:
    case bfd_target_elf_flavour:
    case bfd_target_nlm_flavour:
    case bfd_target_som_flavour:
      core_has_func_syms = 1;
    }

  /* Pass 1 - determine upper bound on number of function names.  */
  symtab.len = 0;

  for (i = 0; i < core_num_syms; ++i)
    {
      if (!core_sym_class (core_syms[i]))
	continue;

      /* Don't create a symtab entry for a function that has
	 a mapping to a file, unless it's the first function
	 in the file.  */
      if (symbol_map_count != 0)
	{
	  /* Note: some systems (SunOS 5.8) crash if bsearch base argument
	     is NULL.  */
	  found = (struct function_map *) bsearch
	    (core_syms[i]->name, symbol_map, symbol_map_count,
	     sizeof (struct function_map), search_mapped_symbol);
	}
      if (found == NULL || found->is_first)
	++symtab.len;
    }

  if (symtab.len == 0)
    {
      fprintf (stderr, _("%s: file `%s' has no symbols\n"), whoami, a_out_name);
      done (1);
    }

  symtab.base = (Sym *) xmalloc (symtab.len * sizeof (Sym));

  /* Pass 2 - create symbols.  */
  symtab.limit = symtab.base;

  for (i = 0; i < core_num_syms; ++i)
    {
      asection *sym_sec;

      cxxclass = core_sym_class (core_syms[i]);

      if (!cxxclass)
	{
	  DBG (AOUTDEBUG,
	       printf ("[core_create_function_syms] rejecting: 0x%lx %s\n",
		       (unsigned long) core_syms[i]->value,
		       core_syms[i]->name));
	  continue;
	}

      if (symbol_map_count != 0)
	{
	  /* Note: some systems (SunOS 5.8) crash if bsearch base argument
	     is NULL.  */
	  found = (struct function_map *) bsearch
	    (core_syms[i]->name, symbol_map, symbol_map_count,
	     sizeof (struct function_map), search_mapped_symbol);
	}
      if (found && ! found->is_first)
	continue;

      sym_init (symtab.limit);

      /* Symbol offsets are always section-relative.  */
      sym_sec = core_syms[i]->section;
      symtab.limit->addr = core_syms[i]->value;
      if (sym_sec)
	symtab.limit->addr += bfd_get_section_vma (sym_sec->owner, sym_sec);

      if (found)
	{
	  symtab.limit->name = found->file_name;
	  symtab.limit->mapped = 1;
	}
      else
	{
	  symtab.limit->name = core_syms[i]->name;
	  symtab.limit->mapped = 0;
	}

      /* Lookup filename and line number, if we can.  */
      {
	const char * filename;
	const char * func_name;

	if (get_src_info (symtab.limit->addr, & filename, & func_name,
			  & symtab.limit->line_num))
	  {
	    symtab.limit->file = source_file_lookup_path (filename);

	    /* FIXME: Checking __osf__ here does not work with a cross
	       gprof.  */
#ifdef __osf__
	    /* Suppress symbols that are not function names.  This is
	       useful to suppress code-labels and aliases.

	       This is known to be useful under DEC's OSF/1.  Under SunOS 4.x,
	       labels do not appear in the symbol table info, so this isn't
	       necessary.  */

	    if (strcmp (symtab.limit->name, func_name) != 0)
	      {
		/* The symbol's address maps to a different name, so
		   it can't be a function-entry point.  This happens
		   for labels, for example.  */
		DBG (AOUTDEBUG,
		     printf ("[core_create_function_syms: rej %s (maps to %s)\n",
			     symtab.limit->name, func_name));
		continue;
	      }
#endif
	  }
      }

      symtab.limit->is_func = (!core_has_func_syms
			       || (core_syms[i]->flags & BSF_FUNCTION) != 0);
      symtab.limit->is_bb_head = TRUE;

      if (cxxclass == 't')
	symtab.limit->is_static = TRUE;

      /* Keep track of the minimum and maximum vma addresses used by all
	 symbols.  When computing the max_vma, use the ending address of the
	 section containing the symbol, if available.  */
      min_vma = MIN (symtab.limit->addr, min_vma);
      if (sym_sec)
	max_vma = MAX (bfd_get_section_vma (sym_sec->owner, sym_sec)
		       + bfd_section_size (sym_sec->owner, sym_sec) - 1,
		       max_vma);
      else
	max_vma = MAX (symtab.limit->addr, max_vma);

      DBG (AOUTDEBUG, printf ("[core_create_function_syms] %ld %s 0x%lx\n",
			      (long) (symtab.limit - symtab.base),
			      symtab.limit->name,
			      (unsigned long) symtab.limit->addr));
      ++symtab.limit;
    }

  symtab.len = symtab.limit - symtab.base;
  symtab_finalize (&symtab);
}
Beispiel #27
0
static void
update_for_binary_section(bfd *abfd,
			  asection *the_section,
			  PTR obj)
{
  unsigned_word section_vma;
  unsigned_word section_size;
  access_type access;
  device *me = (device*)obj;

  /* skip the section if no memory to allocate */
  if (! (bfd_get_section_flags(abfd, the_section) & SEC_ALLOC))
    return;

  /* check/ignore any sections of size zero */
  section_size = bfd_get_section_size_before_reloc(the_section);
  if (section_size == 0)
    return;

  /* find where it is to go */
  section_vma = bfd_get_section_vma(abfd, the_section);

  DTRACE(binary,
	 ("name=%-7s, vma=0x%.8lx, size=%6ld, flags=%3lx(%s%s%s%s%s )\n",
	  bfd_get_section_name(abfd, the_section),
	  (long)section_vma,
	  (long)section_size,
	  (long)bfd_get_section_flags(abfd, the_section),
	  bfd_get_section_flags(abfd, the_section) & SEC_LOAD ? " LOAD" : "",
	  bfd_get_section_flags(abfd, the_section) & SEC_CODE ? " CODE" : "",
	  bfd_get_section_flags(abfd, the_section) & SEC_DATA ? " DATA" : "",
	  bfd_get_section_flags(abfd, the_section) & SEC_ALLOC ? " ALLOC" : "",
	  bfd_get_section_flags(abfd, the_section) & SEC_READONLY ? " READONLY" : ""
	  ));

  /* If there is an .interp section, it means it needs a shared library interpreter.  */
  if (strcmp(".interp", bfd_get_section_name(abfd, the_section)) == 0)
    error("Shared libraries are not yet supported.\n");

  /* determine the devices access */
  access = access_read;
  if (bfd_get_section_flags(abfd, the_section) & SEC_CODE)
    access |= access_exec;
  if (!(bfd_get_section_flags(abfd, the_section) & SEC_READONLY))
    access |= access_write;

  /* if claim specified, allocate region from the memory device */
  if (device_find_property(me, "claim") != NULL) {
    device_instance *memory = tree_find_ihandle_property(me, "/chosen/memory");
    unsigned_cell mem_in[3];
    unsigned_cell mem_out[1];
    mem_in[0] = 0; /*alignment - top-of-stack*/
    mem_in[1] = section_size;
    mem_in[2] = section_vma;
    if (device_instance_call_method(memory, "claim", 3, mem_in, 1, mem_out) < 0)
      device_error(me, "failed to claim memory for section at 0x%lx (0x%lx",
		   section_vma,
		   section_size);
    if (mem_out[0] != section_vma)
      device_error(me, "section address not as requested");
  }

  /* if a map, pass up a request to create the memory in core */
  if (strncmp(device_name(me), "map-binary", strlen("map-binary")) == 0)
    device_attach_address(device_parent(me),
			  attach_raw_memory,
			  0 /*address space*/,
			  section_vma,
			  section_size,
			  access,
			  me);

  /* if a load dma in the required data */
  if (bfd_get_section_flags(abfd, the_section) & SEC_LOAD) {
    void *section_init = zalloc(section_size);
    if (!bfd_get_section_contents(abfd,
				  the_section,
				  section_init, 0,
				  section_size)) {
      bfd_perror("binary");
      device_error(me, "load of data failed");
      return;
    }
    if (device_dma_write_buffer(device_parent(me),
				section_init,
				0 /*space*/,
				section_vma,
				section_size,
				1 /*violate_read_only*/)
	!= section_size)
      device_error(me, "broken transfer\n");
    zfree(section_init); /* only free if load */
  }
}
static int
hppa64_hpux_in_solib_call_trampoline (struct gdbarch *gdbarch,
				      CORE_ADDR pc, char *name)
{
  enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);

  /* PA64 has a completely different stub/trampoline scheme.  Is it
     better?  Maybe.  It's certainly harder to determine with any
     certainty that we are in a stub because we can not refer to the
     unwinders to help.

     The heuristic is simple.  Try to lookup the current PC value in th
     minimal symbol table.  If that fails, then assume we are not in a
     stub and return.

     Then see if the PC value falls within the section bounds for the
     section containing the minimal symbol we found in the first
     step.  If it does, then assume we are not in a stub and return.

     Finally peek at the instructions to see if they look like a stub.  */
  struct minimal_symbol *minsym;
  asection *sec;
  CORE_ADDR addr;
  int insn, i;

  minsym = lookup_minimal_symbol_by_pc (pc);
  if (! minsym)
    return 0;

  sec = SYMBOL_OBJ_SECTION (minsym)->the_bfd_section;

  if (bfd_get_section_vma (sec->owner, sec) <= pc
      && pc < (bfd_get_section_vma (sec->owner, sec)
		 + bfd_section_size (sec->owner, sec)))
      return 0;

  /* We might be in a stub.  Peek at the instructions.  Stubs are 3
     instructions long.  */
  insn = read_memory_integer (pc, 4, byte_order);

  /* Find out where we think we are within the stub.  */
  if ((insn & 0xffffc00e) == 0x53610000)
    addr = pc;
  else if ((insn & 0xffffffff) == 0xe820d000)
    addr = pc - 4;
  else if ((insn & 0xffffc00e) == 0x537b0000)
    addr = pc - 8;
  else
    return 0;

  /* Now verify each insn in the range looks like a stub instruction.  */
  insn = read_memory_integer (addr, 4, byte_order);
  if ((insn & 0xffffc00e) != 0x53610000)
    return 0;
	
  /* Now verify each insn in the range looks like a stub instruction.  */
  insn = read_memory_integer (addr + 4, 4, byte_order);
  if ((insn & 0xffffffff) != 0xe820d000)
    return 0;
    
  /* Now verify each insn in the range looks like a stub instruction.  */
  insn = read_memory_integer (addr + 8, 4, byte_order);
  if ((insn & 0xffffc00e) != 0x537b0000)
    return 0;

  /* Looks like a stub.  */
  return 1;
}
Beispiel #29
0
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);
}
Beispiel #30
0
static int
derive_heap_segment (bfd *abfd, bfd_vma *bottom, bfd_vma *top)
{
  bfd_vma top_of_data_memory = 0;
  bfd_vma top_of_heap = 0;
  bfd_size_type sec_size;
  struct value *zero, *sbrk;
  bfd_vma sec_vaddr;
  asection *sec;

  gdb_assert (bottom);
  gdb_assert (top);

  /* This function depends on being able to call a function in the
     inferior.  */
  if (!target_has_execution)
    return 0;

  /* The following code assumes that the link map is arranged as
     follows (low to high addresses):

     ---------------------------------
     | text sections                 |
     ---------------------------------
     | data sections (including bss) |
     ---------------------------------
     | heap                          |
     --------------------------------- */

  for (sec = abfd->sections; sec; sec = sec->next)
    {
      if (bfd_get_section_flags (abfd, sec) & SEC_DATA
	  || strcmp (".bss", bfd_section_name (abfd, sec)) == 0)
	{
	  sec_vaddr = bfd_get_section_vma (abfd, sec);
	  sec_size = bfd_get_section_size (sec);
	  if (sec_vaddr + sec_size > top_of_data_memory)
	    top_of_data_memory = sec_vaddr + sec_size;
	}
    }

  /* Now get the top-of-heap by calling sbrk in the inferior.  */
  if (lookup_minimal_symbol ("sbrk", NULL, NULL) != NULL)
    {
      sbrk = find_function_in_inferior ("sbrk");
      if (sbrk == NULL)
	return 0;
    }
  else if (lookup_minimal_symbol ("_sbrk", NULL, NULL) != NULL)
    {
      sbrk = find_function_in_inferior ("_sbrk");
      if (sbrk == NULL)
	return 0;
    }
  else
    return 0;

  zero = value_from_longest (builtin_type_int, 0);
  gdb_assert (zero);
  sbrk = call_function_by_hand (sbrk, 1, &zero);
  if (sbrk == NULL)
    return 0;
  top_of_heap = value_as_long (sbrk);

  /* Return results.  */
  if (top_of_heap > top_of_data_memory)
    {
      *bottom = top_of_data_memory;
      *top = top_of_heap;
      return 1;
    }

  /* No additional heap space needs to be saved.  */
  return 0;
}