static CORE_ADDR
bfd_lookup_symbol (bfd *abfd, char *symname)
{
  long storage_needed;
  asymbol *sym;
  asymbol **symbol_table;
  unsigned int number_of_symbols;
  unsigned int i;
  struct cleanup *back_to;
  CORE_ADDR symaddr = 0;

  storage_needed = bfd_get_symtab_upper_bound (abfd);

  if (storage_needed > 0)
    {
      symbol_table = (asymbol **) xmalloc (storage_needed);
      back_to = make_cleanup (xfree, symbol_table);
      number_of_symbols = bfd_canonicalize_symtab (abfd, symbol_table);

      for (i = 0; i < number_of_symbols; i++)
	{
	  sym = *symbol_table++;
	  if (strcmp (sym->name, symname) == 0)
	    {
	      /* Bfd symbols are section relative. */
	      symaddr = sym->value + sym->section->vma;
	      break;
	    }
	}
      do_cleanups (back_to);
    }

  if (symaddr)
    return symaddr;

  /* Look for the symbol in the dynamic string table too.  */

  storage_needed = bfd_get_dynamic_symtab_upper_bound (abfd);

  if (storage_needed > 0)
    {
      symbol_table = (asymbol **) xmalloc (storage_needed);
      back_to = make_cleanup (xfree, symbol_table);
      number_of_symbols = bfd_canonicalize_dynamic_symtab (abfd, symbol_table);

      for (i = 0; i < number_of_symbols; i++)
	{
	  sym = *symbol_table++;
	  if (strcmp (sym->name, symname) == 0)
	    {
	      /* Bfd symbols are section relative. */
	      symaddr = sym->value + sym->section->vma;
	      break;
	    }
	}
      do_cleanups (back_to);
    }

  return symaddr;
}
Example #2
0
static int slurp_symtab(bfd *abfd, struct a2l_data *a2l)
{
	long storage;
	long symcount;
	asymbol **syms;
	bfd_boolean dynamic = FALSE;

	if ((bfd_get_file_flags(abfd) & HAS_SYMS) == 0)
		return bfd_error(bfd_get_filename(abfd));

	storage = bfd_get_symtab_upper_bound(abfd);
	if (storage == 0L) {
		storage = bfd_get_dynamic_symtab_upper_bound(abfd);
		dynamic = TRUE;
	}
	if (storage < 0L)
		return bfd_error(bfd_get_filename(abfd));

	syms = malloc(storage);
	if (dynamic)
		symcount = bfd_canonicalize_dynamic_symtab(abfd, syms);
	else
		symcount = bfd_canonicalize_symtab(abfd, syms);

	if (symcount < 0) {
		free(syms);
		return bfd_error(bfd_get_filename(abfd));
	}

	a2l->syms = syms;
	return 0;
}
Example #3
0
static int
elf_read_symbols(elf_reader_t *reader, const char *path, elfread_src_t srcsec)
{
    int i, nsymbols, nfiltered, iflt;
    size_t storage_needed;

    reader->__abfd = bfd_openr(path, NULL);
    if (!reader->__abfd)
        return -1;

    bfd_check_format(reader->__abfd, bfd_object);
    storage_needed = (srcsec == READSYMBOLS_TEXT) ? 
        bfd_get_symtab_upper_bound(reader->__abfd) :
        bfd_get_dynamic_symtab_upper_bound(reader->__abfd);

    if (storage_needed <= 0) {
        return -1;
    }
    
    reader->__symbol_table = (asymbol**)malloc(storage_needed);
    if (!reader->__symbol_table)
        return -1;

    nsymbols = (srcsec == READSYMBOLS_TEXT) ? 
        bfd_canonicalize_symtab(reader->__abfd, reader->__symbol_table) : 
        bfd_canonicalize_dynamic_symtab(reader->__abfd, reader->__symbol_table);

    if (nsymbols < 0)
        return -1;

    nfiltered = 0;
    for (i = 0; i < nsymbols; i++) {
        if (reader->__symbol_table[i]->flags & (BSF_FUNCTION | BSF_GLOBAL))
            nfiltered++;
    }

    reader->symbols = (elf_symbol_t *)malloc(nfiltered * sizeof(elf_symbol_t));
    if (!reader->symbols)
        return -1;

    for (i = 0, iflt = 0; i < nsymbols && iflt < nfiltered; i++) {
        asymbol *is = reader->__symbol_table[i];

        if (is->flags & (BSF_FUNCTION | BSF_GLOBAL)) {
            elf_symbol_t *os = reader->symbols + iflt++;
            os->symbol_name   = (const char *)bfd_asymbol_name(is);
            os->symbol_value  = bfd_asymbol_value(is);
            os->symbol_size   = BFD_GET_SYMBOL_SIZE(is);
            os->symbol_class  = (char)bfd_decode_symclass(is);
        }
    }

    assert(iflt == nfiltered);
    return iflt;
}
Example #4
0
std::vector<asymbol*> slurpDynamicSymtab(bfd* abfd)
{
    long storage_needed = bfd_get_dynamic_symtab_upper_bound (abfd);

    if (storage_needed <= 0) return std::vector<asymbol*>();

    std::vector<asymbol*> res(storage_needed);

    long symcount = bfd_canonicalize_dynamic_symtab (abfd, &res[0]);
    res.resize(symcount);

    return std::move(res);
}
Example #5
0
/**
 * Obtain the information of dynamic symbol (library call)
 */
dyn_functions_t *get_synthetic_symbols(const char *filename) {
    asymbol** syms = NULL;
    long symcount = 0;
    asymbol** dynsyms = NULL;
    long dynsymcount = 0;
    asymbol* synthsyms = NULL;
    long synthcount = 0;
    long storage;

    vector<dyn_function_t *> *ret = new vector<dyn_function_t *>();

    asm_program_t *prog = new asm_program_t;
    bfd *abfd = initialize_bfd(filename);
    initialize_sections(abfd, prog);
    
    if (bfd_get_file_flags (abfd) & HAS_SYMS) {
	storage = bfd_get_symtab_upper_bound (abfd);
	assert (storage >= 0);
	if (storage > 0)
	    syms = (asymbol**) xmalloc(storage);
	symcount = bfd_canonicalize_symtab (abfd, syms);
	assert (symcount >= 0);
    }

    storage = bfd_get_dynamic_symtab_upper_bound (abfd);
    
    if (storage > 0) {
	dynsyms = (asymbol**) xmalloc(storage);
	dynsymcount = bfd_canonicalize_dynamic_symtab (abfd, dynsyms);
    }

    synthcount = bfd_get_synthetic_symtab (abfd, symcount, syms,
					   dynsymcount, dynsyms, &synthsyms);
    if (synthcount < 0)
        synthcount = 0;

    for (int i=0; i<synthcount; ++i) {
	dyn_function_t *temp = new dyn_function_t;
	temp->name = string(bfd_asymbol_name(&(synthsyms[i])));
	temp->addr = bfd_asymbol_value(&(synthsyms[i]));
	ret->push_back(temp);
    }
    if (synthsyms)
	free(synthsyms);
    if (dynsyms)
	free(dynsyms);
    if (syms)
    free(syms);
    bfd_close(abfd);
    return ret;
}
Example #6
0
long
_bfd_generic_read_minisymbols (bfd *abfd,
			       bfd_boolean dynamic,
			       void **minisymsp,
			       unsigned int *sizep)
{
  long storage;
  asymbol **syms = NULL;
  long symcount;

  if (dynamic)
    storage = bfd_get_dynamic_symtab_upper_bound (abfd);
  else
    storage = bfd_get_symtab_upper_bound (abfd);
  if (storage < 0)
    goto error_return;
  if (storage == 0)
    return 0;

  syms = (asymbol **) bfd_malloc (storage);
  if (syms == NULL)
    goto error_return;

  if (dynamic)
    symcount = bfd_canonicalize_dynamic_symtab (abfd, syms);
  else
    symcount = bfd_canonicalize_symtab (abfd, syms);
  if (symcount < 0)
    goto error_return;

  *minisymsp = syms;
  *sizep = sizeof (asymbol *);

  return symcount;

 error_return:
  bfd_set_error (bfd_error_no_symbols);
  if (syms != NULL)
    free (syms);
  return -1;
}
Example #7
0
static void read_syms(bfd *abfd)
{
	long storage, symcount;
	bfd_boolean dynamic = FALSE;

	if (syms)
		return;

	if (!(bfd_get_file_flags(abfd) & HAS_SYMS)) {
		wpa_printf(MSG_INFO, "No symbols");
		return;
	}

	storage = bfd_get_symtab_upper_bound(abfd);
	if (storage == 0) {
		storage = bfd_get_dynamic_symtab_upper_bound(abfd);
		dynamic = TRUE;
	}
	if (storage < 0) {
		wpa_printf(MSG_INFO, "Unknown symtab upper bound");
		return;
	}

	syms = malloc(storage);
	if (syms == NULL) {
		wpa_printf(MSG_INFO, "Failed to allocate memory for symtab "
			   "(%ld bytes)", storage);
		return;
	}
	if (dynamic)
		symcount = bfd_canonicalize_dynamic_symtab(abfd, syms);
	else
		symcount = bfd_canonicalize_symtab(abfd, syms);
	if (symcount < 0) {
		wpa_printf(MSG_INFO, "Failed to canonicalize %ssymtab",
			   dynamic ? "dynamic " : "");
		free(syms);
		syms = NULL;
		return;
	}
}
Example #8
0
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);
}
Example #9
0
vine_symbols_t * get_symbols_of_file(const char *filename)
{
    asymbol** syms = NULL;
    long symcount = 0;
    long sorted_symcount = 0;
    asymbol** dynsyms = NULL;
    long dynsymcount = 0;

    asymbol* synthsyms = NULL;
    long synthcount = 0;
    long storage;

    vector<vine_symbol_t *> *ret = new vector<vine_symbol_t *>();

//     asm_program_t *prog = new asm_program_t;
//     printf("initializing bfd\n\n");
    bfd *abfd = initialize_bfd(filename);
//     printf("done\n\n");
//     printf("initializing sections...\n\n");
//     initialize_sections(abfd, prog);
//     printf("done\n\n");
    asymbol *sym;

    if (bfd_get_file_flags (abfd) & HAS_SYMS) {
	storage = bfd_get_symtab_upper_bound (abfd);


	assert (storage >= 0);
	if (storage > 0)
	    syms = (asymbol**) xmalloc(storage);
	symcount = bfd_canonicalize_symtab (abfd, syms);
	assert (symcount >= 0);
	sorted_symcount = remove_useless_symbols(syms, symcount);
	qsort(syms, sorted_symcount, sizeof(asymbol *), compare_symbols);
	for(int i= 0; i < sorted_symcount; i++){
	  vine_symbol_t *temp = new vine_symbol_t;
	  temp->name = string(bfd_asymbol_name((syms[i])));

	  temp->addr = bfd_asymbol_value((syms[i]));
	  sym = syms[i];
	  temp->is_function = (sym->flags & BSF_FUNCTION) != 0;
	  temp->is_dynamic = 0;
	  ret->push_back(temp);
	}
    }

    storage = bfd_get_dynamic_symtab_upper_bound (abfd);

    if (storage > 0) {
	dynsyms = (asymbol**) xmalloc(storage);
	dynsymcount = bfd_canonicalize_dynamic_symtab (abfd, dynsyms);
    }


    synthcount = bfd_get_synthetic_symtab (abfd, symcount, syms,
					   dynsymcount, dynsyms, &synthsyms);
    if (synthcount < 0)
        synthcount = 0;

    for (int i=0; i<synthcount; i++) {
      vine_symbol_t *temp = new vine_symbol_t;
      temp->name = string(bfd_asymbol_name(&(synthsyms[i])));
      temp->addr = bfd_asymbol_value(&(synthsyms[i]));

      temp->is_function = (synthsyms[i].flags & BSF_FUNCTION) != 0;
      temp->is_dynamic = 1;
      ret->push_back(temp);
    }
    if (synthsyms)
	free(synthsyms);
    if (dynsyms)
	free(dynsyms);
    if (syms)
    free(syms);
    bfd_close(abfd);
    return ret;
}
int main(int argc, char ** argv)
{
  bfd *fd;
  asection *sec;
  file_ptr offset;
  long st_size;
  asymbol ** symbol_table;
  long sym_count, i;

  if (argc != 2) {
    fprintf(stderr, "Usage: objinfo_helper <dynamic library>\n");
    return 2;
  }

  fd = bfd_openr(argv[1], "default");
  if (!fd) {
    fprintf(stderr, "Error opening file %s\n", argv[1]);
    return 2;
  }
  if (! bfd_check_format (fd, bfd_object)) {
    fprintf(stderr, "Error: wrong format\n");
    bfd_close(fd);
    return 2;
  }

  sec = bfd_get_section_by_name(fd, ".data");
  if (! sec) {
    fprintf(stderr, "Error: section .data not found\n");
    bfd_close(fd);
    return 2;
  }

  offset = sec->filepos;
  st_size = bfd_get_dynamic_symtab_upper_bound (fd);
  if (st_size <= 0) {
    fprintf(stderr, "Error: size of section .data unknown\n");
    bfd_close(fd);
    return 2;
  }

  symbol_table = malloc(st_size);
  if (! symbol_table) {
    fprintf(stderr, "Error: out of memory\n");
    bfd_close(fd);
    return 2;
  }

  sym_count = bfd_canonicalize_dynamic_symtab (fd, symbol_table);

  for (i = 0; i < sym_count; i++) {
    if (strcmp(symbol_table[i]->name, "caml_plugin_header") == 0) {
      printf("%ld\n", (long) (offset + symbol_table[i]->value));
      bfd_close(fd);
      return 0;
    }
  }

  fprintf(stderr, "Error: missing symbol caml_plugin_header\n");
  bfd_close(fd);
  return 2;
}
Example #11
0
void
mini_dump_get_debug_info_about_address(MiniDump *self, guint64 address, gchar *module_name, const gchar **source_file_name, const gchar **function_name,guint *line_number)
{
  gchar *filename = g_build_filename(self->bin_dir,module_name, NULL);
  bfd *abfd = bfd_openr(filename,NULL);
  asection *section;
  long storage;
  long symcount;
  bfd_boolean dynamic = FALSE;
  asymbol **syms;  
  if (abfd == NULL)
    return;
  if (!bfd_check_format (abfd, bfd_object))
    {
      bfd_close(abfd);
      return; 
    }
  if ((bfd_get_file_flags (abfd) & HAS_SYMS) == 0)
    {
      bfd_close(abfd);
      return;
    }
  storage = bfd_get_symtab_upper_bound (abfd);
  if (storage == 0)
    {
      storage = bfd_get_dynamic_symtab_upper_bound (abfd);
      dynamic = TRUE;
    }
  if (storage < 0)
    {
      bfd_close(abfd);
      return;
    }
  syms = (asymbol **) g_malloc0(storage);
  if (dynamic)
    symcount = bfd_canonicalize_dynamic_symtab (abfd, syms);
  else
    symcount = bfd_canonicalize_symtab (abfd, syms);
  if (symcount < 0)
    {
      bfd_close(abfd);
      g_free(syms);
      return;
    }
  section = abfd->sections;
  long i = 0;
  gchar *temp = g_strdup_printf("%s_symbols",filename);
  FILE *sym_file = fopen(temp,"wb");
  for (i = 0; i < symcount; i++)
    {
      fprintf(sym_file,"%s\t%08X\t%08X\t%p\n",syms[i]->name,syms[i]->value,syms[i]->flags,syms[i]->udata.p);
    }
  g_free(temp);
  fclose(sym_file);
  while(section)
    {
      bfd_vma vma;
      bfd_vma pc = address;
      bfd_size_type size;
      if ((bfd_get_section_flags (abfd, section) & SEC_ALLOC) == 0)
        {
          goto next_iteration;
        }
      vma = bfd_get_section_vma (abfd, section);
      if (pc < vma)
        {
          goto next_iteration;
        }
      size = bfd_get_section_size (section);
      if (pc >= vma + size)
        {
          goto next_iteration;
        }
      if (bfd_find_nearest_line (abfd, section, syms, pc - vma, source_file_name, function_name, line_number))
        {
          break;
        }
next_iteration:
      section = section->next;
    } 
}
Example #12
0
    void resolve(const address_type&   addr,
                 const char *   binfile,
                 const char **  source_file_name,
                 const char **  func_name,
                 unsigned int * line_number)
    {
        if (!binfile || !*binfile) {
            return;
        }

        *source_file_name = nullptr;
        *line_number      = 0;
        *func_name        = nullptr;

        boost::mutex::scoped_lock lock(_lib_mutex);

        _init();
        if (!_init_called)
        {
            return;
        }

        sym_map_type::iterator itBfd = _syms.find(binfile);
        if (itBfd == _syms.end()) {
            sym_tab_type fbfd;

            fbfd.base = _compute_maps_base(binfile);

            //FIXME: char *find_separate_debug_file (bfd *abfd);
            fbfd.abfd.reset(bfd_openr(binfile, 0), bfd_close_wrapper());
            if (!fbfd.abfd) {
                return;
            }
#ifdef BFD_DECOMPRESS // Old libbfd?
            fbfd.abfd->flags |= BFD_DECOMPRESS;
#endif

            // Required
            bfd_check_format(fbfd.abfd.get(), bfd_object);

            fbfd.text = bfd_get_section_by_name(fbfd.abfd.get(), ".text");

            fbfd.storage_needed = bfd_get_symtab_upper_bound(fbfd.abfd.get());
            if (0 == fbfd.storage_needed) {
                fbfd.dynamic = true;
                fbfd.storage_needed = bfd_get_dynamic_symtab_upper_bound(fbfd.abfd.get());
            }

            fbfd.syms.reset(static_cast<asymbol**>(::malloc(fbfd.storage_needed)),
                            free_wrapper<asymbol*>());

            if (fbfd.dynamic) {
                fbfd.cSymbols = bfd_canonicalize_dynamic_symtab(fbfd.abfd.get(), fbfd.syms.get());
            }
            else {
                fbfd.cSymbols = bfd_canonicalize_symtab(fbfd.abfd.get(), fbfd.syms.get());
            }
            BOOST_ASSERT(fbfd.cSymbols >= 0);

            _syms[binfile] = fbfd;
            itBfd = _syms.find(binfile);
        }

        if (itBfd != _syms.end()) {
            const sym_tab_type &stab = itBfd->second;

            bfd_vma vma = bfd_get_section_vma(stab.abfd.get(), stab.text);

            long offset = ((long)addr) - stab.base - vma; //stab.text->vma;
            if (offset > 0) {
                if ( !bfd_find_nearest_line(stab.abfd.get(),
                                            stab.text,
                                            stab.syms.get(),
                                            offset,
                                            source_file_name,
                                            func_name,
                                            line_number)
                    ) {
                    //std::cerr << "libbfd: could not find " << std::hex << addr;
                    *source_file_name = nullptr;
                    *line_number      = 0;
                    *func_name        = nullptr;
                }
                //trace it
            }
        }
    }
Example #13
0
static void
elf_symtab_read (struct objfile *objfile, int dynamic)
{
  long storage_needed;
  asymbol *sym;
  asymbol **symbol_table;
  long number_of_symbols;
  long i;
  int index;
  struct cleanup *back_to;
  CORE_ADDR symaddr;
  CORE_ADDR offset;
  enum minimal_symbol_type ms_type;
  /* If sectinfo is nonNULL, it contains section info that should end up
     filed in the objfile.  */
  struct stab_section_info *sectinfo = NULL;
  /* If filesym is nonzero, it points to a file symbol, but we haven't
     seen any section info for it yet.  */
  asymbol *filesym = 0;
#ifdef SOFUN_ADDRESS_MAYBE_MISSING
  /* Name of filesym, as saved on the symbol_obstack.  */
  char *filesymname = obsavestring ("", 0, &objfile->symbol_obstack);
#endif
  struct dbx_symfile_info *dbx = objfile->sym_stab_info;
  unsigned long size;
  int stripped = (bfd_get_symcount (objfile->obfd) == 0);

  if (dynamic)
    {
      storage_needed = bfd_get_dynamic_symtab_upper_bound (objfile->obfd);

      /* Nothing to be done if there is no dynamic symtab.  */
      if (storage_needed < 0)
	return;
    }
  else
    {
      storage_needed = bfd_get_symtab_upper_bound (objfile->obfd);
      if (storage_needed < 0)
	error ("Can't read symbols from %s: %s", bfd_get_filename (objfile->obfd),
	       bfd_errmsg (bfd_get_error ()));
    }
  if (storage_needed > 0)
    {
      symbol_table = (asymbol **) xmalloc (storage_needed);
      back_to = make_cleanup (xfree, symbol_table);
      if (dynamic)
	number_of_symbols = bfd_canonicalize_dynamic_symtab (objfile->obfd,
							     symbol_table);
      else
	number_of_symbols = bfd_canonicalize_symtab (objfile->obfd, symbol_table);
      if (number_of_symbols < 0)
	error ("Can't read symbols from %s: %s", bfd_get_filename (objfile->obfd),
	       bfd_errmsg (bfd_get_error ()));

      for (i = 0; i < number_of_symbols; i++)
	{
	  sym = symbol_table[i];
	  if (sym->name == NULL || *sym->name == '\0')
	    {
	      /* Skip names that don't exist (shouldn't happen), or names
	         that are null strings (may happen). */
	      continue;
	    }

          offset = ANOFFSET (objfile->section_offsets, sym->section->index);
	  if (dynamic
	      && sym->section == &bfd_und_section
	      && (sym->flags & BSF_FUNCTION))
	    {
	      struct minimal_symbol *msym;

	      /* Symbol is a reference to a function defined in
	         a shared library.
	         If its value is non zero then it is usually the address
	         of the corresponding entry in the procedure linkage table,
	         plus the desired section offset.
	         If its value is zero then the dynamic linker has to resolve
	         the symbol. We are unable to find any meaningful address
	         for this symbol in the executable file, so we skip it.  */
	      symaddr = sym->value;
	      if (symaddr == 0)
		continue;
	      symaddr += offset;
	      msym = record_minimal_symbol_and_info
		((char *) sym->name, symaddr,
		 mst_solib_trampoline, NULL, sym->section, objfile);
#ifdef SOFUN_ADDRESS_MAYBE_MISSING
	      if (msym != NULL)
		msym->filename = filesymname;
#endif
	      continue;
	    }

	  /* If it is a nonstripped executable, do not enter dynamic
	     symbols, as the dynamic symbol table is usually a subset
	     of the main symbol table.  */
	  if (dynamic && !stripped)
	    continue;
	  if (sym->flags & BSF_FILE)
	    {
	      /* STT_FILE debugging symbol that helps stabs-in-elf debugging.
	         Chain any old one onto the objfile; remember new sym.  */
	      if (sectinfo != NULL)
		{
		  sectinfo->next = dbx->stab_section_info;
		  dbx->stab_section_info = sectinfo;
		  sectinfo = NULL;
		}
	      filesym = sym;
#ifdef SOFUN_ADDRESS_MAYBE_MISSING
	      filesymname =
		obsavestring ((char *) filesym->name, strlen (filesym->name),
			      &objfile->symbol_obstack);
#endif
	    }
	  else if (sym->flags & (BSF_GLOBAL | BSF_LOCAL | BSF_WEAK))
	    {
	      struct minimal_symbol *msym;

	      /* Select global/local/weak symbols.  Note that bfd puts abs
	         symbols in their own section, so all symbols we are
	         interested in will have a section. */
	      /* Bfd symbols are section relative. */
	      symaddr = sym->value + sym->section->vma;
	      /* Relocate all non-absolute symbols by the section offset.  */
	      if (sym->section != &bfd_abs_section)
		{
		  symaddr += offset;
		}
	      /* For non-absolute symbols, use the type of the section
	         they are relative to, to intuit text/data.  Bfd provides
	         no way of figuring this out for absolute symbols. */
	      if (sym->section == &bfd_abs_section)
		{
		  /* This is a hack to get the minimal symbol type
		     right for Irix 5, which has absolute addresses
		     with special section indices for dynamic symbols. */
		  unsigned short shndx =
		  ((elf_symbol_type *) sym)->internal_elf_sym.st_shndx;

		  switch (shndx)
		    {
		    case SHN_MIPS_TEXT:
		      ms_type = mst_text;
		      break;
		    case SHN_MIPS_DATA:
		      ms_type = mst_data;
		      break;
		    case SHN_MIPS_ACOMMON:
		      ms_type = mst_bss;
		      break;
		    default:
		      ms_type = mst_abs;
		    }

		  /* If it is an Irix dynamic symbol, skip section name
		     symbols, relocate all others by section offset. */
		  if (ms_type != mst_abs)
		    {
		      if (sym->name[0] == '.')
			continue;
		      symaddr += offset;
		    }
		}
	      else if (sym->section->flags & SEC_CODE)
		{
		  if (sym->flags & BSF_GLOBAL)
		    {
		      ms_type = mst_text;
		    }
		  else if ((sym->name[0] == '.' && sym->name[1] == 'L')
			   || ((sym->flags & BSF_LOCAL)
			       && sym->name[0] == '$'
			       && sym->name[1] == 'L'))
		    /* Looks like a compiler-generated label.  Skip
		       it.  The assembler should be skipping these (to
		       keep executables small), but apparently with
		       gcc on the (OBSOLETE) delta m88k SVR4, it
		       loses.  So to have us check too should be
		       harmless (but I encourage people to fix this in
		       the assembler instead of adding checks here).  */
		    continue;
		  else
		    {
		      ms_type = mst_file_text;
		    }
		}
	      else if (sym->section->flags & SEC_ALLOC)
		{
		  if (sym->flags & (BSF_GLOBAL | BSF_WEAK))
		    {
		      if (sym->section->flags & SEC_LOAD)
			{
			  ms_type = mst_data;
			}
		      else
			{
			  ms_type = mst_bss;
			}
		    }
		  else if (sym->flags & BSF_LOCAL)
		    {
		      /* Named Local variable in a Data section.  Check its
		         name for stabs-in-elf.  The STREQ macro checks the
		         first character inline, so we only actually do a
		         strcmp function call on names that start with 'B'
		         or 'D' */
		      index = SECT_OFF_MAX;
		      if (STREQ ("Bbss.bss", sym->name))
			{
			  index = SECT_OFF_BSS (objfile);
			}
		      else if (STREQ ("Ddata.data", sym->name))
			{
			  index = SECT_OFF_DATA (objfile);
			}
		      else if (STREQ ("Drodata.rodata", sym->name))
			{
			  index = SECT_OFF_RODATA (objfile);
			}
		      if (index != SECT_OFF_MAX)
			{
			  /* Found a special local symbol.  Allocate a
			     sectinfo, if needed, and fill it in.  */
			  if (sectinfo == NULL)
			    {
			      sectinfo = (struct stab_section_info *)
				xmmalloc (objfile->md, sizeof (*sectinfo));
			      memset (sectinfo, 0,
				      sizeof (*sectinfo));
			      if (filesym == NULL)
				{
				  complain (&section_info_complaint,
					    sym->name);
				}
			      else
				{
				  sectinfo->filename =
				    (char *) filesym->name;
				}
			    }
			  if (index != -1)
			    { 
			      if (sectinfo->sections[index] != 0)
				{
				  complain (&section_info_dup_complaint,
					    sectinfo->filename);
				}
			    }
			  else
			    internal_error (__FILE__, __LINE__,
					    "Section index uninitialized.");
			  /* Bfd symbols are section relative. */
			  symaddr = sym->value + sym->section->vma;
			  /* Relocate non-absolute symbols by the section offset. */
			  if (sym->section != &bfd_abs_section)
			    {
			      symaddr += offset;
			    }
			  if (index != -1)
			    sectinfo->sections[index] = symaddr;
			  else
			    internal_error (__FILE__, __LINE__,
					    "Section index uninitialized.");
			  /* The special local symbols don't go in the
			     minimal symbol table, so ignore this one. */
			  continue;
			}
		      /* Not a special stabs-in-elf symbol, do regular
		         symbol processing. */
		      if (sym->section->flags & SEC_LOAD)
			{
			  ms_type = mst_file_data;
			}
		      else
			{
			  ms_type = mst_file_bss;
			}
		    }
		  else
		    {
		      ms_type = mst_unknown;
		    }
		}
	      else
		{
		  /* FIXME:  Solaris2 shared libraries include lots of
		     odd "absolute" and "undefined" symbols, that play 
		     hob with actions like finding what function the PC
		     is in.  Ignore them if they aren't text, data, or bss.  */
		  /* ms_type = mst_unknown; */
		  continue;	/* Skip this symbol. */
		}
	      /* Pass symbol size field in via BFD.  FIXME!!!  */
	      size = ((elf_symbol_type *) sym)->internal_elf_sym.st_size;
	      msym = record_minimal_symbol_and_info
		((char *) sym->name, symaddr,
		 ms_type, (void *) size, sym->section, objfile);
#ifdef SOFUN_ADDRESS_MAYBE_MISSING
	      if (msym != NULL)
		msym->filename = filesymname;
#endif
	      ELF_MAKE_MSYMBOL_SPECIAL (sym, msym);
	    }
	}
      do_cleanups (back_to);
    }
}
Example #14
0
struct ast_vector_string *__ast_bt_get_symbols(void **addresses, size_t num_frames)
{
	struct ast_vector_string *return_strings;
	int stackfr;
	bfd *bfdobj;
	long allocsize;
	char msg[MSG_BUFF_LEN];
	static pthread_mutex_t bfd_mutex = PTHREAD_MUTEX_INITIALIZER;

	return_strings = malloc(sizeof(struct ast_vector_string));
	if (!return_strings) {
		return NULL;
	}
	if (AST_VECTOR_INIT(return_strings, num_frames)) {
		free(return_strings);
		return NULL;
	}

	for (stackfr = 0; stackfr < num_frames; stackfr++) {
		int symbolcount;
		struct bfd_data data = {
			.return_strings = return_strings,
			.msg = msg,
			.pc = (bfd_vma)(uintptr_t) addresses[stackfr],
			.found = 0,
			.dynamic = 0,
		};

		msg[0] = '\0';

		if (!dladdr((void *)(uintptr_t) data.pc, &data.dli)) {
			continue;
		}
		data.libname = strrchr(data.dli.dli_fname, '/');
		if (!data.libname) {
			data.libname = data.dli.dli_fname;
		} else {
			data.libname++;
		}

		pthread_mutex_lock(&bfd_mutex);
		/* Using do while(0) here makes it easier to escape and clean up */
		do {
			bfdobj = bfd_openr(data.dli.dli_fname, NULL);
			if (!bfdobj) {
				break;
			}

			/* bfd_check_format does more than check.  It HAS to be called */
			if (!bfd_check_format(bfdobj, bfd_object)) {
				break;
			}

			data.has_syms = !!(bfd_get_file_flags(bfdobj) & HAS_SYMS);
			data.dynamic = !!(bfd_get_file_flags(bfdobj) & DYNAMIC);

			if (!data.has_syms) {
				break;
			}

			allocsize = data.dynamic ?
				bfd_get_dynamic_symtab_upper_bound(bfdobj) : bfd_get_symtab_upper_bound(bfdobj);
			if (allocsize < 0) {
				break;
			}

			data.syms = malloc(allocsize);
			if (!data.syms) {
				break;
			}

			symbolcount = data.dynamic ?
				bfd_canonicalize_dynamic_symtab(bfdobj, data.syms) : bfd_canonicalize_symtab(bfdobj, data.syms);
			if (symbolcount < 0) {
				break;
			}

			bfd_map_over_sections(bfdobj, process_section, &data);
		} while(0);

		if (bfdobj) {
			bfd_close(bfdobj);
			free(data.syms);
			data.syms = NULL;
		}
		pthread_mutex_unlock(&bfd_mutex);

		/* Default output, if we cannot find the information within BFD */
		if (!data.found) {
			snprintf(msg, sizeof(msg), "%s %s()",
				data.libname,
				S_OR(data.dli.dli_sname, "<unknown>"));
			AST_VECTOR_APPEND(return_strings, strdup(msg));
		}
	}

	return return_strings;
}

#else
struct ast_vector_string *__ast_bt_get_symbols(void **addresses, size_t num_frames)
{
	char **strings;
	struct ast_vector_string *return_strings;
	int i;

	return_strings = malloc(sizeof(struct ast_vector_string));
	if (!return_strings) {
		return NULL;
	}
	if (AST_VECTOR_INIT(return_strings, num_frames)) {
		free(return_strings);
		return NULL;
	}

	strings = backtrace_symbols(addresses, num_frames);
	if (strings) {
		for (i = 0; i < num_frames; i++) {
			AST_VECTOR_APPEND(return_strings, strdup(strings[i]));
		}
		free(strings);
	}

	return return_strings;
}
Example #15
0
/*
 * Implementation
 */
void
jit_init_debug(const char *progname)
{
#if DISASSEMBLER
    bfd_init();

    if (progname)
	disasm_bfd = bfd_openr(progname, NULL);
    if (disasm_bfd == NULL) {
#if defined(__linux__)
	disasm_bfd = bfd_openr("/proc/self/exe", NULL);
	if (disasm_bfd == NULL)
#endif
	    return;
    }
    bfd_check_format(disasm_bfd, bfd_object);
    bfd_check_format(disasm_bfd, bfd_archive);
    disasm_print = disassembler(disasm_bfd);
    assert(disasm_print);
    INIT_DISASSEMBLE_INFO(disasm_info, disasm_stream, fprintf);
#  if defined(__i386__) || defined(__x86_64__)
    disasm_info.arch = bfd_arch_i386;
#    if defined(__x86_64__)
#      if __WORDSIZE == 32
    disasm_info.mach = bfd_mach_x64_32;
#      else
    disasm_info.mach = bfd_mach_x86_64;
#      endif
#    else
    disasm_info.mach = bfd_mach_i386_i386;
#    endif
#  endif
#  if defined(__powerpc__)
    disasm_info.arch = bfd_arch_powerpc;
    disasm_info.mach = bfd_mach_ppc64;
#    if HAVE_DISASSEMBLE_INIT_FOR_TARGET
    disassemble_init_for_target(&disasm_info);
#    elif HAVE_DISASSEMBLE_INIT_POWERPC
    disassemble_init_powerpc(&disasm_info);
#    endif
#    if defined(__powerpc64__)
    disasm_info.disassembler_options = "64";
#    endif
#    if HAVE_DISASSEMBLE_INIT_FOR_TARGET
    disassemble_init_for_target(&disasm_info);
#    elif HAVE_DISASSEMBLE_INIT_POWERPC
    disassemble_init_powerpc(&disasm_info);
#    endif
#  endif
#  if defined(__sparc__)
    disasm_info.endian = disasm_info.display_endian = BFD_ENDIAN_BIG;
#  endif
#  if defined(__s390__) || defined(__s390x__)
    disasm_info.arch = bfd_arch_s390;
#    if __WORDSIZE == 32
    disasm_info.mach = bfd_mach_s390_31;
#    else
    disasm_info.mach = bfd_mach_s390_64;
#    endif
    disasm_info.endian = disasm_info.display_endian = BFD_ENDIAN_BIG;
    disasm_info.disassembler_options = "zarch";
#  endif
#  if defined(__alpha__)
    disasm_info.arch = bfd_arch_alpha;
    disasm_info.mach = bfd_mach_alpha_ev6;
#  endif
    disasm_info.print_address_func = disasm_print_address;

    if (bfd_get_file_flags(disasm_bfd) & HAS_SYMS) {
	asymbol		**in;
	asymbol		**out;
	asymbol		 *symbol;
	long		  offset;
	long		  sym_count;
	long		  dyn_count;
	long		  sym_storage;
	long		  dyn_storage;

	if ((sym_storage = bfd_get_symtab_upper_bound(disasm_bfd)) >= 0) {

	    if (bfd_get_file_flags(disasm_bfd) & DYNAMIC) {
		dyn_storage = bfd_get_dynamic_symtab_upper_bound(disasm_bfd);
#  if defined(__alpha__)
		/* XXX */
		if (dyn_storage < 0)
		    dyn_storage = 0;
#  else
		assert(dyn_storage >= 0);
#  endif
	    }
	    else
		dyn_storage = 0;

	    jit_alloc((jit_pointer_t *)&disasm_symbols,
		      (sym_storage + dyn_storage) * sizeof(asymbol *));
	    sym_count = bfd_canonicalize_symtab(disasm_bfd, disasm_symbols);
	    assert(sym_count >= 0);
	    if (dyn_storage) {
		dyn_count = bfd_canonicalize_dynamic_symtab(disasm_bfd,
							    disasm_symbols +
							    sym_count);
		assert(dyn_count >= 0);
	    }
	    else
		dyn_count = 0;
	    disasm_num_symbols = sym_count + dyn_count;

	    disasm_num_synthetic = bfd_get_synthetic_symtab(disasm_bfd,
							    sym_count,
							    disasm_symbols,
							    dyn_count,
							    disasm_symbols +
							    sym_count,
							    &disasm_synthetic);
	    if (disasm_num_synthetic > 0) {
		jit_realloc((jit_pointer_t *)&disasm_symbols,
			    (sym_storage + dyn_storage) * sizeof(asymbol *),
			    (sym_storage + dyn_storage + disasm_num_synthetic) *
			    sizeof(asymbol *));
		for (offset = 0; offset < disasm_num_synthetic; offset++)
		    disasm_symbols[disasm_num_symbols++] =
			disasm_synthetic + offset;
	    }

	    /* remove symbols not useful for disassemble */
	    in = out = disasm_symbols;
	    for (offset = 0; offset < disasm_num_symbols; offset++) {
		symbol = *in++;
		if (symbol->name &&
		    symbol->name[0] != '\0' &&
		    !(symbol->flags & (BSF_DEBUGGING | BSF_SECTION_SYM)) &&
		    !bfd_is_und_section(symbol->section) &&
		    !bfd_is_com_section(symbol->section))
		    *out++ = symbol;
	    }
	    disasm_num_symbols = out - disasm_symbols;
	    qsort(disasm_symbols, disasm_num_symbols,
		  sizeof(asymbol *), disasm_compare_symbols);
	}
    }
#endif
}