예제 #1
0
static
BOOL BfdGetSymFromAddr(bfd *abfd, asymbol **syms, long symcount, DWORD dwAddress, LPTSTR lpSymName, DWORD nSize)
{
	HMODULE hModule;
	struct find_handle info;

	if(!(hModule = (HMODULE) GetModuleBase(dwAddress)))
		return FALSE;

	info.pc = dwAddress;

	if(!(bfd_get_file_flags (abfd) & HAS_SYMS) || !symcount)
		return FALSE;
	info.syms = syms;

	info.found = FALSE;
	bfd_map_over_sections (abfd, find_address_in_section, (PTR) &info);
	if (info.found == FALSE || info.line == 0)
		return FALSE;

	assert(lpSymName);

	if(info.functionname == NULL && *info.functionname == '\0')
		return FALSE;

	lstrcpyn(lpSymName, info.functionname, nSize);

	return TRUE;
}
static void
osf_solib_create_inferior_hook (void)
{
  /* Nothing to do for statically bound executables.  */

  if (symfile_objfile == NULL
      || symfile_objfile->obfd == NULL
      || ((bfd_get_file_flags (symfile_objfile->obfd) & DYNAMIC) == 0))
    return;

  /* Now run the target.  It will eventually get a SIGTRAP, at
     which point all of the libraries will have been mapped in and we
     can go groveling around in the rld structures to find
     out what we need to know about them. */

  clear_proceed_status ();
  stop_soon = STOP_QUIETLY;
  stop_signal = TARGET_SIGNAL_0;
  do
    {
      target_resume (minus_one_ptid, 0, stop_signal);
      wait_for_inferior (0);
    }
  while (stop_signal != TARGET_SIGNAL_TRAP);

  /*  solib_add will call reinit_frame_cache.
     But we are stopped in the runtime loader and we do not have symbols
     for the runtime loader. So heuristic_proc_start will be called
     and will put out an annoying warning.
     Delaying the resetting of stop_soon until after symbol loading
     suppresses the warning.  */
  solib_add ((char *) 0, 0, (struct target_ops *) 0, auto_solib_add);
  stop_soon = NO_STOP_QUIETLY;
}
예제 #3
0
파일: srcline.c 프로젝트: DenisLug/mptcp
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;
}
예제 #4
0
static
BOOL BfdGetLineFromAddr(bfd *abfd, asymbol **syms, long symcount, DWORD dwAddress,  LPTSTR lpFileName, DWORD nSize, LPDWORD lpLineNumber)
{
	HMODULE hModule;
	struct find_handle info;

	if(!(hModule = (HMODULE) GetModuleBase(dwAddress)))
		return FALSE;

	info.pc = dwAddress;

	if(!(bfd_get_file_flags (abfd) & HAS_SYMS) || !symcount)
		return FALSE;

	info.syms = syms;

	info.found = FALSE;
	bfd_map_over_sections (abfd, find_address_in_section, (PTR) &info);
	if (info.found == FALSE || info.line == 0)
		return FALSE;

	assert(lpFileName && lpLineNumber);

	lstrcpyn(lpFileName, info.filename, nSize);
	*lpLineNumber = info.line;

	return TRUE;
}
예제 #5
0
    bool loadSymbols(void)
    {
        if (m_syms)
            return true;

        if (!m_abfd)
            return false;

        if ((bfd_get_file_flags(m_abfd) & HAS_SYMS) == 0) {
            std::cerr << m_path << ": File has no symbols.\n";
            return false;
        }

        long symcount;
        unsigned size;

        //std::cerr << "Loading symbols from " << m_path << "...\n";
        symcount = bfd_read_minisymbols(m_abfd, FALSE, (void**)&m_syms, &size);

        if (!symcount)
            symcount = bfd_read_minisymbols(m_abfd, TRUE /* dynamic */, (void**)&m_syms, &size);

        m_text = bfd_get_section_by_name(m_abfd, ".text");

        return true;
    }
예제 #6
0
void dump_symbols(const char *filename){
	bfd *abfd;
	asymbol *store;
	char *p;
	void *minisyms;
	int symnum,i;
	size_t size;
	int dyn=0;
	int ret;

	abfd=bfd_openr(filename,NULL);
	assert(abfd);
	ret=bfd_check_format(abfd,bfd_object);
	assert(ret);
	if(!(bfd_get_file_flags(abfd)&& HAS_SYMS)){
		bfd_close(abfd);
		return;
	}
	store = bfd_make_empty_symbol(abfd);
	symnum = bfd_read_minisymbols(abfd,dyn,&minisyms,&size);
	assert(symnum>=0);
	p=(char *)minisyms;
	for(i=0;i<symnum;i++){
		asymbol *sym = bfd_minisymbol_to_symbol(abfd,dyn,p,store);
		const char *name = bfd_asymbol_name(sym);
		int value = bfd_asymbol_value(sym);
		printf("%08x %s\n",value,name);
		p+=size;
	}
	free(store);
	free(minisyms);
	bfd_close(abfd);
}
예제 #7
0
파일: gcore.c 프로젝트: gygy/asuswrt
static int
gcore_create_callback (CORE_ADDR vaddr, unsigned long size,
		       int read, int write, int exec, void *data)
{
  bfd *obfd = data;
  asection *osec;
  flagword flags = SEC_ALLOC | SEC_HAS_CONTENTS | SEC_LOAD;

  /* If the memory segment has no permissions set, ignore it, otherwise
     when we later try to access it for read/write, we'll get an error
     or jam the kernel.  */
  if (read == 0 && write == 0 && exec == 0)
    {
      if (info_verbose)
        {
          fprintf_filtered (gdb_stdout, "Ignore segment, %s bytes at 0x%s\n",
                           paddr_d (size), paddr_nz (vaddr));
        }

      return 0;
    }

  if (write == 0)
    {
      /* See if this region of memory lies inside a known file on disk.
	 If so, we can avoid copying its contents by clearing SEC_LOAD.  */
      struct objfile *objfile;
      struct obj_section *objsec;

      ALL_OBJSECTIONS (objfile, objsec)
	{
	  bfd *abfd = objfile->obfd;
	  asection *asec = objsec->the_bfd_section;
	  bfd_vma align = (bfd_vma) 1 << bfd_get_section_alignment (abfd,
								    asec);
	  bfd_vma start = objsec->addr & -align;
	  bfd_vma end = (objsec->endaddr + align - 1) & -align;
	  /* Match if either the entire memory region lies inside the
	     section (i.e. a mapping covering some pages of a large
	     segment) or the entire section lies inside the memory region
	     (i.e. a mapping covering multiple small sections).

	     This BFD was synthesized from reading target memory,
	     we don't want to omit that.  */
	  if (((vaddr >= start && vaddr + size <= end)
	       || (start >= vaddr && end <= vaddr + size))
	      && !(bfd_get_file_flags (abfd) & BFD_IN_MEMORY))
	    {
	      flags &= ~SEC_LOAD;
	      flags |= SEC_NEVER_LOAD;
	      goto keep;	/* break out of two nested for loops */
	    }
	}

    keep:
      flags |= SEC_READONLY;
    }
예제 #8
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();
}
예제 #9
0
파일: bfd.c 프로젝트: chrisglass/ufoai
static int init_bfd_ctx (struct bfd_ctx *bc, const char * procname, struct output_buffer *ob)
{
	bfd *b;
	void *symbol_table;
	unsigned dummy = 0;
	char **matching = NULL;

	bc->handle = NULL;
	bc->symbol = NULL;

	b = bfd_openr(procname, 0);
	if (!b) {
		output_print(ob, "Failed to open bfd from (%s)\n", procname);
		return 1;
	}

	if (bfd_check_format(b, bfd_archive)) {
		output_print(ob, "Cannot get addresses from archive (%s)\n", b->filename);
		bfd_close(b);
		return -1;
	}

	if (!bfd_check_format_matches(b, bfd_object, &matching)) {
		const char *errmsg = bfd_errmsg(bfd_get_error());
		output_print(ob, "%s (%s)\n", errmsg, b->filename);
		if (bfd_get_error() == bfd_error_file_ambiguously_recognized) {
			list_matching_formats(ob, b->filename, matching);
			free(matching);
		}
		bfd_close(b);
		return -1;
	}

	if ((bfd_get_file_flags(b) & HAS_SYMS) == 0) {
		const char *errmsg = bfd_errmsg(bfd_get_error());
		output_print(ob, "Failed to get file flags from (%s) %s\n", b->filename, errmsg);
		bfd_close(b);
		return 1;
	}

	if (bfd_read_minisymbols(b, FALSE, &symbol_table, &dummy) == 0) {
		if (bfd_read_minisymbols(b, TRUE, &symbol_table, &dummy) < 0) {
			const char *errmsg = bfd_errmsg(bfd_get_error());
			output_print(ob, "Failed to read symbols from (%s): %s\n", b->filename, errmsg);
			free(symbol_table);
			bfd_close(b);
			return 1;
		}
	}

	bc->handle = b;
	bc->symbol = symbol_table;

	return 0;
}
예제 #10
0
static void
osf_solib_create_inferior_hook (int from_tty)
{
    struct inferior *inf;
    struct thread_info *tp;

    inf = current_inferior ();

    /* If we are attaching to the inferior, the shared libraries
       have already been mapped, so nothing more to do.  */
    if (inf->attach_flag)
        return;

    /* Nothing to do for statically bound executables.  */

    if (symfile_objfile == NULL
            || symfile_objfile->obfd == NULL
            || ((bfd_get_file_flags (symfile_objfile->obfd) & DYNAMIC) == 0))
        return;

    /* Now run the target.  It will eventually get a SIGTRAP, at
       which point all of the libraries will have been mapped in and we
       can go groveling around in the rld structures to find
       out what we need to know about them.

       If debugging from a core file, we cannot resume the execution
       of the inferior.  But this is actually not an issue, because
       shared libraries have already been mapped anyways, which means
       we have nothing more to do.  */
    if (!target_can_run (&current_target))
        return;

    tp = inferior_thread ();
    clear_proceed_status ();
    inf->stop_soon = STOP_QUIETLY;
    tp->stop_signal = TARGET_SIGNAL_0;
    do
    {
        target_resume (minus_one_ptid, 0, tp->stop_signal);
        wait_for_inferior (0);
    }
    while (tp->stop_signal != TARGET_SIGNAL_TRAP);

    /*  solib_add will call reinit_frame_cache.
       But we are stopped in the runtime loader and we do not have symbols
       for the runtime loader. So heuristic_proc_start will be called
       and will put out an annoying warning.
       Delaying the resetting of stop_soon until after symbol loading
       suppresses the warning.  */
    solib_add ((char *) 0, 0, (struct target_ops *) 0, auto_solib_add);
    inf->stop_soon = NO_STOP_QUIETLY;
}
예제 #11
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;
}
예제 #12
0
static void slurp_symtab(bfd * abfd) {
	long symcount;
	unsigned int size;

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

	symcount = bfd_read_minisymbols(abfd, false, (PTR) & syms, &size);
	if (symcount == 0)
		symcount = bfd_read_minisymbols(abfd, true /* dynamic */, (PTR) & syms, &size);

	if (symcount < 0)
		bfd_fatal(bfd_get_filename(abfd));
}
예제 #13
0
static void
gldelf64ltsmip_vercheck (lang_input_statement_type *s)
{
  const char *soname;
  struct bfd_link_needed_list *l;

  if (global_vercheck_failed)
    return;
  if (s->the_bfd == NULL
      || (bfd_get_file_flags (s->the_bfd) & DYNAMIC) == 0)
    return;

  soname = bfd_elf_get_dt_soname (s->the_bfd);
  if (soname == NULL)
    soname = lbasename (bfd_get_filename (s->the_bfd));

  for (l = global_vercheck_needed; l != NULL; l = l->next)
    {
      const char *suffix;

      if (strcmp (soname, l->name) == 0)
	{
	  /* Probably can't happen, but it's an easy check.  */
	  continue;
	}

      if (strchr (l->name, '/') != NULL)
	continue;

      suffix = strstr (l->name, ".so.");
      if (suffix == NULL)
	continue;

      suffix += sizeof ".so." - 1;

      if (strncmp (soname, l->name, suffix - l->name) == 0)
	{
	  /* Here we know that S is a dynamic object FOO.SO.VER1, and
	     the object we are considering needs a dynamic object
	     FOO.SO.VER2, and VER1 and VER2 are different.  This
	     appears to be a version mismatch, so we tell the caller
	     to try a different version of this library.  */
	  global_vercheck_failed = TRUE;
	  return;
	}
    }
}
예제 #14
0
파일: naev.c 프로젝트: ekrumme/naev
/**
 * @brief Sets up the SignalHandler for Linux.
 */
static void debug_sigInit( void )
{
#if HAS_LINUX && defined(DEBUGGING)
   char **matching;
   struct sigaction sa, so;

   bfd_init();

   /* Read the executable */
   abfd = bfd_openr("/proc/self/exe", NULL);
   if (abfd != NULL) {
      bfd_check_format_matches(abfd, bfd_object, &matching);

      /* Read symbols */
      if (bfd_get_file_flags(abfd) & HAS_SYMS) {
         long symcount;
         unsigned int size;

         /* static */
         symcount = bfd_read_minisymbols (abfd, FALSE, (void **)&syms, &size);
         if (symcount == 0) /* dynamic */
            symcount = bfd_read_minisymbols (abfd, TRUE, (void **)&syms, &size);
         assert(symcount >= 0);
      }
   }

   /* Set up handler. */
   sa.sa_handler   = NULL;
   sa.sa_sigaction = debug_sigHandler;
   sigemptyset(&sa.sa_mask);
   sa.sa_flags     = SA_SIGINFO;

   /* Attach signals. */
   sigaction(SIGSEGV, &sa, &so);
   if (so.sa_handler == SIG_IGN)
      DEBUG("Unable to set up SIGSEGV signal handler.");
   sigaction(SIGFPE, &sa, &so);
   if (so.sa_handler == SIG_IGN)
      DEBUG("Unable to set up SIGFPE signal handler.");
   sigaction(SIGABRT, &sa, &so);
   if (so.sa_handler == SIG_IGN)
      DEBUG("Unable to set up SIGABRT signal handler.");
#else /* HAS_LINUX && defined(DEBUGGING) */
   (void) executable;
#endif /* HAS_LINUX && defined(DEBUGGING) */
}
예제 #15
0
void
init_entry_point_info (struct objfile *objfile)
{
  /* Save startup file's range of PC addresses to help blockframe.c
     decide where the bottom of the stack is.  */

  if (bfd_get_file_flags (objfile->obfd) & EXEC_P)
    {
      /* Executable file -- record its entry point so we'll recognize
         the startup file because it contains the entry point.  */
      objfile->ei.entry_point = bfd_get_start_address (objfile->obfd);
    }
  else
    {
      /* Examination of non-executable.o files.  Short-circuit this stuff.  */
      objfile->ei.entry_point = INVALID_ENTRY_POINT;
    }
}
예제 #16
0
파일: backtrace.c 프로젝트: asqz/runner
static int
init_bfd_ctx(struct bfd_ctx *bc, struct output_buffer *ob)
{
	bc->handle = NULL;
	bc->symbol = NULL;

	char procname[MAX_PATH];
	GetModuleFileNameA(NULL, procname, sizeof procname);

	bfd_init();
	bfd *b = bfd_openr(procname, 0);
	if (!b) {
		output_print(ob,"Failed to init bfd\n");
		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\n");
		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 init bfd\n");
			return 1;
		}
	}

	bc->handle = b;
	bc->symbol = symbol_table;

	return 0;
}
예제 #17
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;
	}
}
예제 #18
0
// Read in the symbol table.
static bfd_boolean
slurp_symtab (bfd *abfd, asymbol ***syms, long *symcount)
{
	long storage;

	if ((bfd_get_file_flags (abfd) & HAS_SYMS) == 0)
		return FALSE;

	storage = bfd_get_symtab_upper_bound (abfd);
	if (storage < 0)
		return FALSE;

	*syms = (asymbol **) GlobalAlloc(GMEM_FIXED, storage);
	if (*syms == NULL)
		return FALSE;

	if((*symcount = bfd_canonicalize_symtab (abfd, *syms)) < 0)
		return FALSE;

	return TRUE;
}
예제 #19
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;
}
예제 #20
0
static int is_bfd_symbols_available(void) {
	char name_buf[PATH_MAX];
	int n = readlink("/proc/self/exe", name_buf, sizeof(name_buf) - 1);
	if (n < 1)
		return 0;

	bfd *abfd;
	char** matching;

	bfd_init();
	name_buf[n] = 0;
	abfd = bfd_openr(name_buf, NULL);
	if (! abfd)
		return 0;

	n = 0;
	if ((bfd_get_file_flags(abfd) & HAS_SYMS) != 0
			&& bfd_check_format_matches(abfd, bfd_object, &matching))
		n = bfd_get_symtab_upper_bound(abfd) > 0;
	bfd_close(abfd);
	return n;
}
예제 #21
0
/* 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;
}
예제 #22
0
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;
}
예제 #23
0
파일: bfd.c 프로젝트: easyaspi314/agbcc
bfd_boolean
bfd_set_file_flags (bfd *abfd, flagword flags)
{
  if (abfd->format != bfd_object)
    {
      bfd_set_error (bfd_error_wrong_format);
      return FALSE;
    }

  if (bfd_read_p (abfd))
    {
      bfd_set_error (bfd_error_invalid_operation);
      return FALSE;
    }

  bfd_get_file_flags (abfd) = flags;
  if ((flags & bfd_applicable_file_flags (abfd)) != flags)
    {
      bfd_set_error (bfd_error_invalid_operation);
      return FALSE;
    }

  return TRUE;
}
예제 #24
0
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

}
예제 #25
0
static bfd_boolean
gldelf64ltsmip_try_needed (const char *name, int force)
{
  bfd *abfd;
  const char *soname;

  abfd = bfd_openr (name, bfd_get_target (output_bfd));
  if (abfd == NULL)
    return FALSE;
  if (! bfd_check_format (abfd, bfd_object))
    {
      bfd_close (abfd);
      return FALSE;
    }
  if ((bfd_get_file_flags (abfd) & DYNAMIC) == 0)
    {
      bfd_close (abfd);
      return FALSE;
    }

  /* For DT_NEEDED, they have to match.  */
  if (abfd->xvec != output_bfd->xvec)
    {
      bfd_close (abfd);
      return FALSE;
    }

  /* Check whether this object would include any conflicting library
     versions.  If FORCE is set, then we skip this check; we use this
     the second time around, if we couldn't find any compatible
     instance of the shared library.  */

  if (! force)
    {
      struct bfd_link_needed_list *needed;

      if (! bfd_elf_get_bfd_needed_list (abfd, &needed))
	einfo ("%F%P:%B: bfd_elf_get_bfd_needed_list failed: %E\n", abfd);

      if (needed != NULL)
	{
	  global_vercheck_needed = needed;
	  global_vercheck_failed = FALSE;
	  lang_for_each_input_file (gldelf64ltsmip_vercheck);
	  if (global_vercheck_failed)
	    {
	      bfd_close (abfd);
	      /* Return FALSE to force the caller to move on to try
		 another file on the search path.  */
	      return FALSE;
	    }

	  /* But wait!  It gets much worse.  On Linux, if a shared
	     library does not use libc at all, we are supposed to skip
	     it the first time around in case we encounter a shared
	     library later on with the same name which does use the
	     version of libc that we want.  This is much too horrible
	     to use on any system other than Linux.  */

	  {
	    struct bfd_link_needed_list *l;

	    for (l = needed; l != NULL; l = l->next)
	      if (strncmp (l->name, "libc.so", 7) == 0)
		break;
	    if (l == NULL)
	      {
		bfd_close (abfd);
		return FALSE;
	      }
	  }

	}
    }

  /* We've found a dynamic object matching the DT_NEEDED entry.  */

  /* We have already checked that there is no other input file of the
     same name.  We must now check again that we are not including the
     same file twice.  We need to do this because on many systems
     libc.so is a symlink to, e.g., libc.so.1.  The SONAME entry will
     reference libc.so.1.  If we have already included libc.so, we
     don't want to include libc.so.1 if they are the same file, and we
     can only check that using stat.  */

  if (bfd_stat (abfd, &global_stat) != 0)
    einfo ("%F%P:%B: bfd_stat failed: %E\n", abfd);

  /* First strip off everything before the last '/'.  */
  soname = lbasename (abfd->filename);

  if (trace_file_tries)
    info_msg (_("found %s at %s\n"), soname, name);

  global_found = FALSE;
  lang_for_each_input_file (gldelf64ltsmip_stat_needed);
  if (global_found)
    {
      /* Return TRUE to indicate that we found the file, even though
	 we aren't going to do anything with it.  */
      return TRUE;
    }

  /* Tell the ELF backend that we don't want the output file to have a
     DT_NEEDED entry for this file.  */
  bfd_elf_set_dt_needed_name (abfd, "");

  /* Tell the ELF backend that the output file needs a DT_NEEDED
     entry for this file if it is used to resolve the reference in
     a regular object.  */
  bfd_elf_set_dt_needed_soname (abfd, soname);

  /* Add this file into the symbol table.  */
  if (! bfd_link_add_symbols (abfd, &link_info))
    einfo ("%F%B: could not read symbols: %E\n", abfd);

  return TRUE;
}
예제 #26
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);
}
예제 #27
0
map<address_t, asm_function_t *>
identify_functions(const map<address_t, section_t *> sections, bfd *abfd)
{
  map<address_t, asm_function_t *> funcs;
  //set<asm_function_t *> funcs;
  long storage_needed;
  asymbol **symtbl;
  long symcount, sorted_symcount;
  /* 
     We could identify function boundries in stripped binaries by
     looking for the function prologue. TBD.
   */ 
  if(!(bfd_get_file_flags(abfd) & HAS_SYMS)){
    return get_stripped_binary_functions( abfd);
    //fatal("identify_functions", 
	  //"No support for stripped binaries (yet)");
  }

  //assert(bfd_get_flavour(abfd) == bfd_target_elf_flavour);
  /*
    instead of handling only elf format binary, allow other types 
    with a warning -- pongsin
  */
  if (bfd_get_flavour(abfd) != bfd_target_elf_flavour)
      cerr << "Warning! The binary is not in ELF format. " 
	   << "Other formats haven't been thoroughly tested."
	   << endl;

  storage_needed = bfd_get_symtab_upper_bound(abfd);
  if(storage_needed <= 0){
    fatal("identify_functions", "symbol table damaged");
  }
  
  symtbl = (asymbol **) xmalloc(storage_needed);
  symcount = bfd_canonicalize_symtab(abfd, symtbl);
  if(symcount <= 0)
    fatal("initialize_symtable", "symbol table damaged");

  sorted_symcount = remove_useless_symbols(symtbl, symcount);
  qsort(symtbl, sorted_symcount, sizeof(asymbol *), compare_symbols);
  
  long i, place;
  asymbol *sym, *nextsym;

  for(i = 0; i < sorted_symcount; i++){
    sym = symtbl[i];
    /*    if(sym->name != NULL){
      printf("name: %s %u F:%x\n", sym->name, sym->flags & BSF_FUNCTION,
    sym->flags);
    } */
    if(sym->flags & BSF_FUNCTION){
      asm_function_t *f = new asm_function_t;
      f->start_addr = sym->section->vma + sym->value;
      f->name = sym->name;
      //      memcpy(&(s->symbol), sym, sizeof(asymbol));
      place = i;
      // FIXME: this still doesn't do the right thing for _init on ARM
      // also, this doesn't work for the last symbol
      while(place < sorted_symcount && (bfd_asymbol_value(sym) >=
				bfd_asymbol_value(symtbl[place])) )
	place++;
      nextsym = symtbl[place];

      // FIXME: We could approximate end_addr better, eg, by looking at where
      // the section ends.
      /* end addrress is approximation. the last valid address
	 may be before this value */
      f->end_addr =  nextsym->value + nextsym->section->vma;

      //bfd_symbol_info(sym, &(s->info));
      // end_addr so far is really the start_addr of the next function
      // subtract one if possible.
      if(f->end_addr != f->start_addr)
	f->end_addr--;
      
      if(funcs.find(f->start_addr) != funcs.end()){
	asm_function_t *old = funcs[f->start_addr];
	// Replace old functions with the new one if the new
	// one is bigger.
	if( (f->end_addr - f->start_addr) >
	    (old->end_addr - old->start_addr)){
	  funcs[f->start_addr] =  f;
	}
      } else {
	funcs[f->start_addr] = f;
      }
    }
  }
   free(symtbl);  
   return funcs;
}
예제 #28
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;
}
예제 #29
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;
}
예제 #30
0
/**
 * Initialize the bfd context.
 *
 * @return TRUE if OK.
 */
static bool
bfd_util_open(bfd_ctx_t *bc, const char *path)
{
	static mutex_t bfd_library_mtx = MUTEX_INIT;
	bfd *b;
	void *symbols = NULL;
	unsigned size = 0;
	long count;
	int fd = -1;
	const char *libpath = path;

	/*
	 * On Debian systems, there is a debugging version of libraries held
	 * under /usr/lib/debug.  We'll get better symbol resolution by
	 * opening these instead of the usually stripped runtime versions
	 * that will only contain externally visible symbols.
	 */

	if (!is_running_on_mingw() && is_absolute_path(path)) {
		static char debugpath[MAX_PATH_LEN];
		const char *base = filepath_basename(path);

		concat_strings(debugpath, sizeof debugpath,
			"/usr/lib/debug/", base, NULL_PTR);

		fd = open(debugpath, O_RDONLY);
		if (-1 == fd) {
			concat_strings(debugpath, sizeof debugpath,
				"/usr/lib/debug", path, NULL_PTR);
			fd = open(debugpath, O_RDONLY);
		}
		if (-1 != fd)
			libpath = debugpath;
	}

	if (-1 == fd)
		fd = open(libpath, O_RDONLY);

	if (-1 == fd) {
		s_miniwarn("%s: can't open %s: %m", G_STRFUNC, libpath);
		return FALSE;
	}

	/*
	 * Protect calls to BFD opening: they don't appear to be fully
	 * thread-safe and we could enter here concurrently.
	 */

	mutex_lock_fast(&bfd_library_mtx);

	b = bfd_fdopenr(libpath, NULL, fd);
	if (NULL == b) {
		mutex_unlock_fast(&bfd_library_mtx);
		close(fd);
		return FALSE;
	}

	if (!bfd_util_check_format(b, bfd_object, libpath)) {
		s_miniwarn("%s: %s is not an object", G_STRFUNC, libpath);
		goto failed;
	}

	if (0 == (bfd_get_file_flags(b) & HAS_SYMS)) {
		s_miniwarn("%s: %s has no symbols", G_STRFUNC, libpath);
		goto failed;
	}

	count = bfd_read_minisymbols(b, FALSE, &symbols, &size);
	if (count <= 0) {
		bc->dynamic = TRUE;
		count = bfd_read_minisymbols(b, TRUE, &symbols, &size);
	}

	if (count >= 0)
		goto done;

	s_miniwarn("%s: unable to load symbols from %s ", G_STRFUNC, libpath);
	symbols = NULL;
	/* FALL THROUGH */

	/*
	 * We keep the context on errors to avoid logging them over and over
	 * each time we attempt to access the same file.  The BFD and system
	 * resources are released though.
	 */

failed:
	bfd_close(b);
	b = NULL;
	count = 0;
	/* FALL THROUGH */

done:
	mutex_unlock_fast(&bfd_library_mtx);

	bc->magic = BFD_CTX_MAGIC;
	bc->handle = b;
	bc->symbols = symbols;		/* Allocated by the bfd library */
	bc->count = count;
	bc->symsize = size;
	mutex_init(&bc->lock);

	return TRUE;
}