Пример #1
0
int main( int argc, char* argv[]) {
	//bfd_vma dis_addr;
	//disassemble_info info;
	//disassembler_ftype disassemble_fn;
    bfd *abfd;							//BFD object
    char **matching, *target = NULL;
	extern bfd_target *bfd_target_vector[];
	int x;


    if ( argc < 2) {
		printf("Usage: %s filename\n", argv[0]);
		return 1;
	}

    bfd_init ();
    abfd = bfd_openr(argv[1], target);
    if ( abfd == NULL) { printf("Unable to open %s\n", argv[1]); return 1;}
	else  printf("Acquired target: %s\n", argv[1]);
	// -------------------------------------------BFD?
	if (! bfd_check_format_matches(abfd, bfd_object, &matching)){
	  printf("Unrecognized File!\n Supported targets: ");
	  for ( x = 0; bfd_target_vector[x]; x++) {
			bfd_target *p = bfd_target_vector[x];
			printf("%s ", p->name);
	  }
	} else {
		printf("\nMapping %s sections...\n", abfd->filename);
		//iterate through the sections, using hdr_summary as a callback
		bfd_map_over_sections(abfd, hdr_summary, (PTR) NULL);
		printf(".....done\n");
	}

	if (! bfd_close(abfd)) printf("Unable to close BFD!\n");

	return 0;
}
Пример #2
0
bfd_boolean
bfd_check_format (bfd *abfd, bfd_format format)
{
  return bfd_check_format_matches (abfd, format, NULL);
}
Пример #3
0
void
exec_file_attach (char *filename, int from_tty)
{
  /* Remove any previous exec file.  */
  exec_close ();

  /* Now open and digest the file the user requested, if any.  */

  if (!filename)
    {
      if (from_tty)
        printf_unfiltered (_("No executable file now.\n"));

      set_gdbarch_from_file (NULL);
    }
  else
    {
      struct cleanup *cleanups;
      char *scratch_pathname, *canonical_pathname;
      int scratch_chan;
      struct target_section *sections = NULL, *sections_end = NULL;
      char **matching;

      scratch_chan = openp (getenv ("PATH"), OPF_TRY_CWD_FIRST, filename,
		   write_files ? O_RDWR | O_BINARY : O_RDONLY | O_BINARY,
			    &scratch_pathname);
#if defined(__GO32__) || defined(_WIN32) || defined(__CYGWIN__)
      if (scratch_chan < 0)
	{
	  char *exename = alloca (strlen (filename) + 5);

	  strcat (strcpy (exename, filename), ".exe");
	  scratch_chan = openp (getenv ("PATH"), OPF_TRY_CWD_FIRST, exename,
	     write_files ? O_RDWR | O_BINARY : O_RDONLY | O_BINARY,
	     &scratch_pathname);
	}
#endif
      if (scratch_chan < 0)
	perror_with_name (filename);

      cleanups = make_cleanup (xfree, scratch_pathname);

      /* gdb_bfd_open (and its variants) prefers canonicalized pathname for
	 better BFD caching.  */
      canonical_pathname = gdb_realpath (scratch_pathname);
      make_cleanup (xfree, canonical_pathname);

      if (write_files)
	exec_bfd = gdb_bfd_fopen (canonical_pathname, gnutarget,
				  FOPEN_RUB, scratch_chan);
      else
	exec_bfd = gdb_bfd_open (canonical_pathname, gnutarget, scratch_chan);

      if (!exec_bfd)
	{
	  error (_("\"%s\": could not open as an executable file: %s"),
		 scratch_pathname, bfd_errmsg (bfd_get_error ()));
	}

      gdb_assert (exec_filename == NULL);
      exec_filename = gdb_realpath_keepfile (scratch_pathname);

      if (!bfd_check_format_matches (exec_bfd, bfd_object, &matching))
	{
	  /* Make sure to close exec_bfd, or else "run" might try to use
	     it.  */
	  exec_close ();
	  error (_("\"%s\": not in executable format: %s"),
		 scratch_pathname,
		 gdb_bfd_errmsg (bfd_get_error (), matching));
	}

      if (build_section_table (exec_bfd, &sections, &sections_end))
	{
	  /* Make sure to close exec_bfd, or else "run" might try to use
	     it.  */
	  exec_close ();
	  error (_("\"%s\": can't find the file sections: %s"),
		 scratch_pathname, bfd_errmsg (bfd_get_error ()));
	}

      exec_bfd_mtime = bfd_get_mtime (exec_bfd);

      validate_files ();

      set_gdbarch_from_file (exec_bfd);

      /* Add the executable's sections to the current address spaces'
	 list of sections.  This possibly pushes the exec_ops
	 target.  */
      add_target_sections (&exec_bfd, sections, sections_end);
      xfree (sections);

      /* Tell display code (if any) about the changed file name.  */
      if (deprecated_exec_file_display_hook)
	(*deprecated_exec_file_display_hook) (filename);

      do_cleanups (cleanups);
    }
  bfd_cache_close_all ();
  observer_notify_executable_changed ();
}
Пример #4
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);
}
Пример #5
0
extern void DEBUG_LoadSymbols( char *name )
{
    bfd* abfd;
    char **matching;

    bfd_init();
    abfd = bfd_openr(name, "default");
    if (abfd == NULL) {
	barf("can't open executable %s to get symbol table", name);
    }
    if (!bfd_check_format_matches (abfd, bfd_object, &matching)) {
	barf("mismatch");
    }

    {
	long storage_needed;
	asymbol **symbol_table;
	long number_of_symbols;
        long num_real_syms = 0;
	long i;
     
	storage_needed = bfd_get_symtab_upper_bound (abfd);
     
	if (storage_needed < 0) {
	    barf("can't read symbol table");
	}     
#if 0
	if (storage_needed == 0) {
	    debugBelch("no storage needed");
	}
#endif
	symbol_table = (asymbol **) stgMallocBytes(storage_needed,"DEBUG_LoadSymbols");

	number_of_symbols = bfd_canonicalize_symtab (abfd, symbol_table);
     
	if (number_of_symbols < 0) {
	    barf("can't canonicalise symbol table");
	}

        for( i = 0; i != number_of_symbols; ++i ) {
            symbol_info info;
            bfd_get_symbol_info(abfd,symbol_table[i],&info);
            /*debugBelch("\t%c\t0x%x      \t%s\n",info.type,(nat)info.value,info.name); */
            if (isReal(info.type, info.name)) {
                num_real_syms += 1;
            }
        }
    
        IF_DEBUG(interpreter,
                 debugBelch("Loaded %ld symbols. Of which %ld are real symbols\n", 
                         number_of_symbols, num_real_syms)
                 );

        reset_table( num_real_syms );
    
        for( i = 0; i != number_of_symbols; ++i ) {
            symbol_info info;
            bfd_get_symbol_info(abfd,symbol_table[i],&info);
            if (isReal(info.type, info.name)) {
                insert( info.value, info.name );
            }
        }

        stgFree(symbol_table);
    }
    prepare_table();
}
Пример #6
0
void
exec_file_attach (const char *filename, int from_tty)
{
  struct cleanup *cleanups;

  /* First, acquire a reference to the current exec_bfd.  We release
     this at the end of the function; but acquiring it now lets the
     BFD cache return it if this call refers to the same file.  */
  gdb_bfd_ref (exec_bfd);
  cleanups = make_cleanup_bfd_unref (exec_bfd);

  /* Remove any previous exec file.  */
  exec_close ();

  /* Now open and digest the file the user requested, if any.  */

  if (!filename)
    {
      if (from_tty)
        printf_unfiltered (_("No executable file now.\n"));

      set_gdbarch_from_file (NULL);
    }
  else
    {
      int load_via_target = 0;
      char *scratch_pathname, *canonical_pathname;
      int scratch_chan;
      struct target_section *sections = NULL, *sections_end = NULL;
      char **matching;

      if (is_target_filename (filename))
	{
	  if (target_filesystem_is_local ())
	    filename += strlen (TARGET_SYSROOT_PREFIX);
	  else
	    load_via_target = 1;
	}

      if (load_via_target)
	{
	  /* gdb_bfd_fopen does not support "target:" filenames.  */
	  if (write_files)
	    warning (_("writing into executable files is "
		       "not supported for %s sysroots"),
		     TARGET_SYSROOT_PREFIX);

	  scratch_pathname = xstrdup (filename);
	  make_cleanup (xfree, scratch_pathname);

	  scratch_chan = -1;

	  canonical_pathname = scratch_pathname;
	}
      else
	{
	  scratch_chan = openp (getenv ("PATH"), OPF_TRY_CWD_FIRST,
				filename, write_files ?
				O_RDWR | O_BINARY : O_RDONLY | O_BINARY,
				&scratch_pathname);
#if defined(__GO32__) || defined(_WIN32) || defined(__CYGWIN__)
	  if (scratch_chan < 0)
	    {
	      char *exename = alloca (strlen (filename) + 5);

	      strcat (strcpy (exename, filename), ".exe");
	      scratch_chan = openp (getenv ("PATH"), OPF_TRY_CWD_FIRST,
				    exename, write_files ?
				    O_RDWR | O_BINARY
				    : O_RDONLY | O_BINARY,
				    &scratch_pathname);
	    }
#endif
	  if (scratch_chan < 0)
	    perror_with_name (filename);

	  make_cleanup (xfree, scratch_pathname);

	  /* gdb_bfd_open (and its variants) prefers canonicalized
	     pathname for better BFD caching.  */
	  canonical_pathname = gdb_realpath (scratch_pathname);
	  make_cleanup (xfree, canonical_pathname);
	}

      if (write_files && !load_via_target)
	exec_bfd = gdb_bfd_fopen (canonical_pathname, gnutarget,
				  FOPEN_RUB, scratch_chan);
      else
	exec_bfd = gdb_bfd_open (canonical_pathname, gnutarget, scratch_chan);

      if (!exec_bfd)
	{
	  error (_("\"%s\": could not open as an executable file: %s"),
		 scratch_pathname, bfd_errmsg (bfd_get_error ()));
	}

      /* gdb_realpath_keepfile resolves symlinks on the local
	 filesystem and so cannot be used for "target:" files.  */
      gdb_assert (exec_filename == NULL);
      if (load_via_target)
	exec_filename = xstrdup (bfd_get_filename (exec_bfd));
      else
	exec_filename = gdb_realpath_keepfile (scratch_pathname);

      if (!bfd_check_format_matches (exec_bfd, bfd_object, &matching))
	{
	  /* Make sure to close exec_bfd, or else "run" might try to use
	     it.  */
	  exec_close ();
	  error (_("\"%s\": not in executable format: %s"),
		 scratch_pathname,
		 gdb_bfd_errmsg (bfd_get_error (), matching));
	}

      if (build_section_table (exec_bfd, &sections, &sections_end))
	{
	  /* Make sure to close exec_bfd, or else "run" might try to use
	     it.  */
	  exec_close ();
	  error (_("\"%s\": can't find the file sections: %s"),
		 scratch_pathname, bfd_errmsg (bfd_get_error ()));
	}

      exec_bfd_mtime = bfd_get_mtime (exec_bfd);

      validate_files ();

      set_gdbarch_from_file (exec_bfd);

      /* Add the executable's sections to the current address spaces'
	 list of sections.  This possibly pushes the exec_ops
	 target.  */
      add_target_sections (&exec_bfd, sections, sections_end);
      xfree (sections);

      /* Tell display code (if any) about the changed file name.  */
      if (deprecated_exec_file_display_hook)
	(*deprecated_exec_file_display_hook) (filename);
    }

  do_cleanups (cleanups);

  bfd_cache_close_all ();
  observer_notify_executable_changed ();
}
Пример #7
0
void
exec_file_attach (char *filename, int from_tty)
{
  /* Remove any previous exec file.  */
  exec_close ();

  /* Now open and digest the file the user requested, if any.  */

  if (!filename)
    {
      if (from_tty)
        printf_unfiltered (_("No executable file now.\n"));

      set_gdbarch_from_file (NULL);
    }
  else
    {
      struct cleanup *cleanups;
      char *scratch_pathname;
      int scratch_chan;
      struct target_section *sections = NULL, *sections_end = NULL;
      char **matching;

      scratch_chan = openp (getenv ("PATH"), OPF_TRY_CWD_FIRST, filename,
		   write_files ? O_RDWR | O_BINARY : O_RDONLY | O_BINARY,
			    &scratch_pathname);
#if defined(__GO32__) || defined(_WIN32) || defined(__CYGWIN__)
      if (scratch_chan < 0)
	{
	  char *exename = alloca (strlen (filename) + 5);
	  strcat (strcpy (exename, filename), ".exe");
	  scratch_chan = openp (getenv ("PATH"), OPF_TRY_CWD_FIRST, exename,
	     write_files ? O_RDWR | O_BINARY : O_RDONLY | O_BINARY,
	     &scratch_pathname);
	}
#endif
      if (scratch_chan < 0)
	perror_with_name (filename);
      exec_bfd = bfd_fopen (scratch_pathname, gnutarget,
			    write_files ? FOPEN_RUB : FOPEN_RB,
			    scratch_chan);

      if (!exec_bfd)
	{
	  close (scratch_chan);
	  error (_("\"%s\": could not open as an executable file: %s"),
		 scratch_pathname, bfd_errmsg (bfd_get_error ()));
	}

      /* At this point, scratch_pathname and exec_bfd->name both point to the
         same malloc'd string.  However exec_close() will attempt to free it
         via the exec_bfd->name pointer, so we need to make another copy and
         leave exec_bfd as the new owner of the original copy. */
      scratch_pathname = xstrdup (scratch_pathname);
      cleanups = make_cleanup (xfree, scratch_pathname);

      if (!bfd_check_format_matches (exec_bfd, bfd_object, &matching))
	{
	  /* Make sure to close exec_bfd, or else "run" might try to use
	     it.  */
	  exec_close ();
	  error (_("\"%s\": not in executable format: %s"),
		 scratch_pathname,
		 gdb_bfd_errmsg (bfd_get_error (), matching));
	}

      /* FIXME - This should only be run for RS6000, but the ifdef is a poor
         way to accomplish.  */
#ifdef DEPRECATED_IBM6000_TARGET
      /* Setup initial vmap. */

      map_vmap (exec_bfd, 0);
      if (vmap == NULL)
	{
	  /* Make sure to close exec_bfd, or else "run" might try to use
	     it.  */
	  exec_close ();
	  error (_("\"%s\": can't find the file sections: %s"),
		 scratch_pathname, bfd_errmsg (bfd_get_error ()));
	}
#endif /* DEPRECATED_IBM6000_TARGET */

      if (build_section_table (exec_bfd, &sections, &sections_end))
	{
	  /* Make sure to close exec_bfd, or else "run" might try to use
	     it.  */
	  exec_close ();
	  error (_("\"%s\": can't find the file sections: %s"),
		 scratch_pathname, bfd_errmsg (bfd_get_error ()));
	}

      exec_bfd_mtime = bfd_get_mtime (exec_bfd);

      validate_files ();

      set_gdbarch_from_file (exec_bfd);

      /* Add the executable's sections to the current address spaces'
	 list of sections.  This possibly pushes the exec_ops
	 target.  */
      add_target_sections (sections, sections_end);
      xfree (sections);

      /* Tell display code (if any) about the changed file name.  */
      if (deprecated_exec_file_display_hook)
	(*deprecated_exec_file_display_hook) (filename);

      do_cleanups (cleanups);
    }
  bfd_cache_close_all ();
  observer_notify_executable_changed ();
}
Пример #8
0
void DebugInfo::generatePidMapOverlay() {
  if (!m_perfMap || !pidMapOverlayStart) return;

  std::string self = current_executable_path();
  bfd* abfd = bfd_openr(self.c_str(), nullptr);
#ifdef BFD_DECOMPRESS
  abfd->flags |= BFD_DECOMPRESS;
#endif
  char **match = nullptr;
  if (!bfd_check_format(abfd, bfd_archive) &&
      bfd_check_format_matches(abfd, bfd_object, &match)) {

    std::vector<asymbol*> sorted;
    long storage_needed = bfd_get_symtab_upper_bound (abfd);

    if (storage_needed <= 0) return;

    auto symbol_table = (asymbol**)malloc(storage_needed);

    long number_of_symbols = bfd_canonicalize_symtab(abfd, symbol_table);

    for (long i = 0; i < number_of_symbols; i++) {
      auto sym = symbol_table[i];
      if (sym->flags &
          (BSF_INDIRECT |
           BSF_SECTION_SYM |
           BSF_FILE |
           BSF_DEBUGGING_RELOC |
           BSF_OBJECT)) {
        continue;
      }
      auto sec = sym->section;
      if (!(sec->flags & (SEC_ALLOC|SEC_LOAD|SEC_CODE))) continue;
      auto addr = sec->vma + sym->value;
      if (addr < uintptr_t(pidMapOverlayStart) ||
          addr >= uintptr_t(pidMapOverlayEnd)) {
        continue;
      }
      sorted.push_back(sym);
    }

    std::sort(sorted.begin(), sorted.end(), [](asymbol* a, asymbol* b) {
        auto addra = a->section->vma + a->value;
        auto addrb = b->section->vma + b->value;
        if (addra != addrb) return addra < addrb;
        return strncmp("_ZN4HPHP", a->name, 8) &&
          !strncmp("_ZN4HPHP", b->name, 8);
      });

    for (size_t i = 0; i < sorted.size(); i++) {
      auto sym = sorted[i];
      auto addr = sym->section->vma + sym->value;
      int status;
      char* demangled =
        abi::__cxa_demangle(sym->name, nullptr, nullptr, &status);
      if (status != 0) demangled = const_cast<char*>(sym->name);
      unsigned size;
      if (i + 1 < sorted.size()) {
        auto s2 = sorted[i + 1];
        size = s2->section->vma + s2->value - addr;
      } else {
        size = uintptr_t(pidMapOverlayEnd) - addr;
      }
      if (!size) continue;
      fprintf(m_perfMap, "%lx %x %s\n",
              long(addr), size, demangled);
      if (status == 0) free(demangled);
    }

    free(symbol_table);
    free(match);
  }
  bfd_close(abfd);
  return;
}
Пример #9
0
struct compile_module *
compile_object_load (const char *object_file, const char *source_file,
		     enum compile_i_scope_types scope, void *scope_data)
{
  struct cleanup *cleanups, *cleanups_free_objfile;
  bfd *abfd;
  struct setup_sections_data setup_sections_data;
  CORE_ADDR addr, regs_addr, out_value_addr = 0;
  struct symbol *func_sym;
  struct type *func_type;
  struct bound_minimal_symbol bmsym;
  long storage_needed;
  asymbol **symbol_table, **symp;
  long number_of_symbols, missing_symbols;
  struct type *dptr_type = builtin_type (target_gdbarch ())->builtin_data_ptr;
  unsigned dptr_type_len = TYPE_LENGTH (dptr_type);
  struct compile_module *retval;
  struct type *regs_type, *out_value_type = NULL;
  char *filename, **matching;
  struct objfile *objfile;
  int expect_parameters;
  struct type *expect_return_type;
  struct munmap_list *munmap_list_head = NULL;

  filename = tilde_expand (object_file);
  cleanups = make_cleanup (xfree, filename);

  abfd = gdb_bfd_open (filename, gnutarget, -1);
  if (abfd == NULL)
    error (_("\"%s\": could not open as compiled module: %s"),
          filename, bfd_errmsg (bfd_get_error ()));
  make_cleanup_bfd_unref (abfd);

  if (!bfd_check_format_matches (abfd, bfd_object, &matching))
    error (_("\"%s\": not in loadable format: %s"),
          filename, gdb_bfd_errmsg (bfd_get_error (), matching));

  if ((bfd_get_file_flags (abfd) & (EXEC_P | DYNAMIC)) != 0)
    error (_("\"%s\": not in object format."), filename);

  setup_sections_data.last_size = 0;
  setup_sections_data.last_section_first = abfd->sections;
  setup_sections_data.last_prot = -1;
  setup_sections_data.last_max_alignment = 1;
  setup_sections_data.munmap_list_headp = &munmap_list_head;
  make_cleanup (munmap_listp_free_cleanup, &munmap_list_head);
  bfd_map_over_sections (abfd, setup_sections, &setup_sections_data);
  setup_sections (abfd, NULL, &setup_sections_data);

  storage_needed = bfd_get_symtab_upper_bound (abfd);
  if (storage_needed < 0)
    error (_("Cannot read symbols of compiled module \"%s\": %s"),
          filename, bfd_errmsg (bfd_get_error ()));

  /* SYMFILE_VERBOSE is not passed even if FROM_TTY, user is not interested in
     "Reading symbols from ..." message for automatically generated file.  */
  objfile = symbol_file_add_from_bfd (abfd, filename, 0, NULL, 0, NULL);
  cleanups_free_objfile = make_cleanup_free_objfile (objfile);

  func_sym = lookup_global_symbol_from_objfile (objfile,
						GCC_FE_WRAPPER_FUNCTION,
						VAR_DOMAIN).symbol;
  if (func_sym == NULL)
    error (_("Cannot find function \"%s\" in compiled module \"%s\"."),
	   GCC_FE_WRAPPER_FUNCTION, objfile_name (objfile));
  func_type = SYMBOL_TYPE (func_sym);
  if (TYPE_CODE (func_type) != TYPE_CODE_FUNC)
    error (_("Invalid type code %d of function \"%s\" in compiled "
	     "module \"%s\"."),
	   TYPE_CODE (func_type), GCC_FE_WRAPPER_FUNCTION,
	   objfile_name (objfile));

  switch (scope)
    {
    case COMPILE_I_SIMPLE_SCOPE:
      expect_parameters = 1;
      expect_return_type = builtin_type (target_gdbarch ())->builtin_void;
      break;
    case COMPILE_I_RAW_SCOPE:
      expect_parameters = 0;
      expect_return_type = builtin_type (target_gdbarch ())->builtin_void;
      break;
    case COMPILE_I_PRINT_ADDRESS_SCOPE:
    case COMPILE_I_PRINT_VALUE_SCOPE:
      expect_parameters = 2;
      expect_return_type = builtin_type (target_gdbarch ())->builtin_void;
      break;
    default:
      internal_error (__FILE__, __LINE__, _("invalid scope %d"), scope);
    }
  if (TYPE_NFIELDS (func_type) != expect_parameters)
    error (_("Invalid %d parameters of function \"%s\" in compiled "
	     "module \"%s\"."),
	   TYPE_NFIELDS (func_type), GCC_FE_WRAPPER_FUNCTION,
	   objfile_name (objfile));
  if (!types_deeply_equal (expect_return_type, TYPE_TARGET_TYPE (func_type)))
    error (_("Invalid return type of function \"%s\" in compiled "
	    "module \"%s\"."),
	  GCC_FE_WRAPPER_FUNCTION, objfile_name (objfile));

  /* The memory may be later needed
     by bfd_generic_get_relocated_section_contents
     called from default_symfile_relocate.  */
  symbol_table = obstack_alloc (&objfile->objfile_obstack, storage_needed);
  number_of_symbols = bfd_canonicalize_symtab (abfd, symbol_table);
  if (number_of_symbols < 0)
    error (_("Cannot parse symbols of compiled module \"%s\": %s"),
          filename, bfd_errmsg (bfd_get_error ()));

  missing_symbols = 0;
  for (symp = symbol_table; symp < symbol_table + number_of_symbols; symp++)
    {
      asymbol *sym = *symp;

      if (sym->flags != 0)
	continue;
      sym->flags = BSF_GLOBAL;
      sym->section = bfd_abs_section_ptr;
      if (strcmp (sym->name, "_GLOBAL_OFFSET_TABLE_") == 0)
	{
	  if (compile_debug)
	    fprintf_unfiltered (gdb_stdlog,
				"ELF symbol \"%s\" relocated to zero\n",
				sym->name);

	  /* It seems to be a GCC bug, with -mcmodel=large there should be no
	     need for _GLOBAL_OFFSET_TABLE_.  Together with -fPIE the data
	     remain PC-relative even with _GLOBAL_OFFSET_TABLE_ as zero.  */
	  sym->value = 0;
	  continue;
	}
      bmsym = lookup_minimal_symbol (sym->name, NULL, NULL);
      switch (bmsym.minsym == NULL
	      ? mst_unknown : MSYMBOL_TYPE (bmsym.minsym))
	{
	case mst_text:
	  sym->value = BMSYMBOL_VALUE_ADDRESS (bmsym);
	  if (compile_debug)
	    fprintf_unfiltered (gdb_stdlog,
				"ELF mst_text symbol \"%s\" relocated to %s\n",
				sym->name,
				paddress (target_gdbarch (), sym->value));
	  break;
	case mst_text_gnu_ifunc:
	  sym->value = gnu_ifunc_resolve_addr (target_gdbarch (),
					       BMSYMBOL_VALUE_ADDRESS (bmsym));
	  if (compile_debug)
	    fprintf_unfiltered (gdb_stdlog,
				"ELF mst_text_gnu_ifunc symbol \"%s\" "
				"relocated to %s\n",
				sym->name,
				paddress (target_gdbarch (), sym->value));
	  break;
	default:
	  warning (_("Could not find symbol \"%s\" "
		     "for compiled module \"%s\"."),
		   sym->name, filename);
	  missing_symbols++;
	}
    }
  if (missing_symbols)
    error (_("%ld symbols were missing, cannot continue."), missing_symbols);

  bfd_map_over_sections (abfd, copy_sections, symbol_table);

  regs_type = get_regs_type (func_sym, objfile);
  if (regs_type == NULL)
    regs_addr = 0;
  else
    {
      /* Use read-only non-executable memory protection.  */
      regs_addr = gdbarch_infcall_mmap (target_gdbarch (),
					TYPE_LENGTH (regs_type),
					GDB_MMAP_PROT_READ);
      gdb_assert (regs_addr != 0);
      munmap_list_add (&munmap_list_head, regs_addr, TYPE_LENGTH (regs_type));
      if (compile_debug)
	fprintf_unfiltered (gdb_stdlog,
			    "allocated %s bytes at %s for registers\n",
			    paddress (target_gdbarch (),
				      TYPE_LENGTH (regs_type)),
			    paddress (target_gdbarch (), regs_addr));
      store_regs (regs_type, regs_addr);
    }

  if (scope == COMPILE_I_PRINT_ADDRESS_SCOPE
      || scope == COMPILE_I_PRINT_VALUE_SCOPE)
    {
      out_value_type = get_out_value_type (func_sym, objfile, scope);
      if (out_value_type == NULL)
	{
	  do_cleanups (cleanups);
	  return NULL;
	}
      check_typedef (out_value_type);
      out_value_addr = gdbarch_infcall_mmap (target_gdbarch (),
					     TYPE_LENGTH (out_value_type),
					     (GDB_MMAP_PROT_READ
					      | GDB_MMAP_PROT_WRITE));
      gdb_assert (out_value_addr != 0);
      munmap_list_add (&munmap_list_head, out_value_addr,
		       TYPE_LENGTH (out_value_type));
      if (compile_debug)
	fprintf_unfiltered (gdb_stdlog,
			    "allocated %s bytes at %s for printed value\n",
			    paddress (target_gdbarch (),
				      TYPE_LENGTH (out_value_type)),
			    paddress (target_gdbarch (), out_value_addr));
    }

  discard_cleanups (cleanups_free_objfile);

  retval = xmalloc (sizeof (*retval));
  retval->objfile = objfile;
  retval->source_file = xstrdup (source_file);
  retval->func_sym = func_sym;
  retval->regs_addr = regs_addr;
  retval->scope = scope;
  retval->scope_data = scope_data;
  retval->out_value_type = out_value_type;
  retval->out_value_addr = out_value_addr;

  /* CLEANUPS will free MUNMAP_LIST_HEAD.  */
  retval->munmap_list_head = munmap_list_head;
  munmap_list_head = NULL;

  do_cleanups (cleanups);

  return retval;
}
Пример #10
0
int main(int argc, char *argv[])
{
    int i, f, size, symcnt, off;
    unsigned int fingerprint;
    int num_funcs = 0;
    int fancy_output = 0;
    int strip_names = 0;
    bfd *b;
    asymbol **syms;
    unsigned char buf[SIGNATSIZE+4];
    char *nameptr;

    const char *short_options = "fsh";
    struct option long_options[] = {
        {"fancy", no_argument, NULL, 'f'},
        {"strip", no_argument, NULL, 's'},
        {"help",  no_argument, NULL, 'h'},
        {0,       no_argument, NULL, 0}
    };

    while ((i = getopt_long(argc, argv, short_options, long_options, NULL)) != EOF) {
        switch (i) {
            case 'f':
                fancy_output = 1;
                break;
            case 's':
                strip_names = 1;
                break;
            case 'h':
            case '?':
                usage(argv[0]); /* never returns */
            default:
                break;
        }
    }

    if (optind >= argc) {
        usage(argv[0]); /* never returns */
        exit(1);
    }

    while (optind < argc) {
        b = bfd_openr(argv[optind++], 0);
        if (!b) {
            fprintf(stderr, "bfd_openr failed for '%s'\n", argv[optind - 1]);
            continue;
        }

        bfd_check_format(b, bfd_archive);
        bfd_check_format_matches(b, bfd_object, 0);

        if ((bfd_get_file_flags(b) & HAS_SYMS) == 0) {
            fprintf(stderr, (fancy_output) ? "EMPTY" : "No symbols.\n");
            continue;
        }

        size = bfd_get_symtab_upper_bound(b);
        syms = (asymbol **) malloc(size);
        symcnt = bfd_canonicalize_symtab(b, syms);

        for (i = 0; i < symcnt; ++i) {
            if (syms[i]->flags & BSF_FUNCTION) {
                nameptr = (char *)(bfd_asymbol_name(syms[i]));
                if (strip_names!=0) {
                    while (*nameptr == '_') {
                        nameptr++;
                    }
                }
                off = syms[i]->value;
                if (syms[i]->section) {
                    off += syms[i]->section->filepos;
                }

                f = open(argv[optind - 1], O_RDONLY);
                lseek(f, off, SEEK_SET);
                num_funcs++;
                read(f, buf, SIGNATSIZE);
                fingerprint = fnprint_compute(buf);
                close(f);

                // Ignore only NOPs
                if (fingerprint != 0xA120AD5C) {
                    printf("[%s+%d] %s %08X\n", argv[optind - 1], off, nameptr, fingerprint);
                } else {
                    printf("\n");
                }
            }
        }

        if (fancy_output) {
            fprintf(stderr, "%d function%s", num_funcs, PLURAL(num_funcs, "s"));
        } else {
            fprintf(stderr, "[*] %s: (%d function%s)\n", argv[optind - 1], num_funcs, PLURAL(num_funcs, "s"));
        }
    }
    return 0;
}
Пример #11
0
struct compile_module *
compile_object_load (const char *object_file, const char *source_file)
{
  struct cleanup *cleanups, *cleanups_free_objfile;
  bfd *abfd;
  struct setup_sections_data setup_sections_data;
  CORE_ADDR addr, func_addr, regs_addr;
  struct bound_minimal_symbol bmsym;
  long storage_needed;
  asymbol **symbol_table, **symp;
  long number_of_symbols, missing_symbols;
  struct type *dptr_type = builtin_type (target_gdbarch ())->builtin_data_ptr;
  unsigned dptr_type_len = TYPE_LENGTH (dptr_type);
  struct compile_module *retval;
  struct type *regs_type;
  char *filename, **matching;
  struct objfile *objfile;

  filename = tilde_expand (object_file);
  cleanups = make_cleanup (xfree, filename);

  abfd = gdb_bfd_open (filename, gnutarget, -1);
  if (abfd == NULL)
    error (_("\"%s\": could not open as compiled module: %s"),
          filename, bfd_errmsg (bfd_get_error ()));
  make_cleanup_bfd_unref (abfd);

  if (!bfd_check_format_matches (abfd, bfd_object, &matching))
    error (_("\"%s\": not in loadable format: %s"),
          filename, gdb_bfd_errmsg (bfd_get_error (), matching));

  if ((bfd_get_file_flags (abfd) & (EXEC_P | DYNAMIC)) != 0)
    error (_("\"%s\": not in object format."), filename);

  setup_sections_data.last_size = 0;
  setup_sections_data.last_section_first = abfd->sections;
  setup_sections_data.last_prot = -1;
  setup_sections_data.last_max_alignment = 1;
  bfd_map_over_sections (abfd, setup_sections, &setup_sections_data);
  setup_sections (abfd, NULL, &setup_sections_data);

  storage_needed = bfd_get_symtab_upper_bound (abfd);
  if (storage_needed < 0)
    error (_("Cannot read symbols of compiled module \"%s\": %s"),
          filename, bfd_errmsg (bfd_get_error ()));

  /* SYMFILE_VERBOSE is not passed even if FROM_TTY, user is not interested in
     "Reading symbols from ..." message for automatically generated file.  */
  objfile = symbol_file_add_from_bfd (abfd, filename, 0, NULL, 0, NULL);
  cleanups_free_objfile = make_cleanup_free_objfile (objfile);

  bmsym = lookup_minimal_symbol_text (GCC_FE_WRAPPER_FUNCTION, objfile);
  if (bmsym.minsym == NULL || MSYMBOL_TYPE (bmsym.minsym) == mst_file_text)
    error (_("Could not find symbol \"%s\" of compiled module \"%s\"."),
	   GCC_FE_WRAPPER_FUNCTION, filename);
  func_addr = BMSYMBOL_VALUE_ADDRESS (bmsym);

  /* The memory may be later needed
     by bfd_generic_get_relocated_section_contents
     called from default_symfile_relocate.  */
  symbol_table = obstack_alloc (&objfile->objfile_obstack, storage_needed);
  number_of_symbols = bfd_canonicalize_symtab (abfd, symbol_table);
  if (number_of_symbols < 0)
    error (_("Cannot parse symbols of compiled module \"%s\": %s"),
          filename, bfd_errmsg (bfd_get_error ()));

  missing_symbols = 0;
  for (symp = symbol_table; symp < symbol_table + number_of_symbols; symp++)
    {
      asymbol *sym = *symp;

      if (sym->flags != 0)
	continue;
      if (compile_debug)
	fprintf_unfiltered (gdb_stdout,
			    "lookup undefined ELF symbol \"%s\"\n",
			    sym->name);
      sym->flags = BSF_GLOBAL;
      sym->section = bfd_abs_section_ptr;
      if (strcmp (sym->name, "_GLOBAL_OFFSET_TABLE_") == 0)
	{
	  sym->value = 0;
	  continue;
	}
      bmsym = lookup_minimal_symbol (sym->name, NULL, NULL);
      switch (bmsym.minsym == NULL
	      ? mst_unknown : MSYMBOL_TYPE (bmsym.minsym))
	{
	case mst_text:
	  sym->value = BMSYMBOL_VALUE_ADDRESS (bmsym);
	  break;
	default:
	  warning (_("Could not find symbol \"%s\" "
		     "for compiled module \"%s\"."),
		   sym->name, filename);
	  missing_symbols++;
	}
    }
  if (missing_symbols)
    error (_("%ld symbols were missing, cannot continue."), missing_symbols);

  bfd_map_over_sections (abfd, copy_sections, symbol_table);

  regs_type = get_regs_type (objfile);
  if (regs_type == NULL)
    regs_addr = 0;
  else
    {
      /* Use read-only non-executable memory protection.  */
      regs_addr = gdbarch_infcall_mmap (target_gdbarch (),
					TYPE_LENGTH (regs_type),
					GDB_MMAP_PROT_READ);
      gdb_assert (regs_addr != 0);
      store_regs (regs_type, regs_addr);
    }

  discard_cleanups (cleanups_free_objfile);
  do_cleanups (cleanups);

  retval = xmalloc (sizeof (*retval));
  retval->objfile = objfile;
  retval->source_file = xstrdup (source_file);
  retval->func_addr = func_addr;
  retval->regs_addr = regs_addr;
  return retval;
}
Пример #12
0
int
main(int ac, char **av)
{
  bfd *abfd;
  struct coff_ofile *tree;
  char **matching;
  char *input_file = NULL;
  int opt;
  static struct option long_options[] =
    {
      { "help", no_argument, 0, 'h' },
      { "version", no_argument, 0, 'V' },
      { NULL, no_argument, 0, 0 }
    };

#if defined(HAVE_SETLOCALE) && defined(HAVE_LC_MESSAGES)
  setlocale(LC_MESSAGES, "");
#endif /* HAVE_SETLOCALE && HAVE_LC_MESSAGES */
#if defined(HAVE_SETLOCALE)
  setlocale(LC_CTYPE, "");
#endif /* HAVE_SETLOCALE */
  bindtextdomain(PACKAGE, LOCALEDIR);
  textdomain(PACKAGE);

  program_name = av[0];
  xmalloc_set_program_name (program_name);

  while ((opt = getopt_long(ac, av, "HhVv", long_options,
                            (int *)NULL)) != EOF)
    {
      switch (opt)
	{
	case 'H':
	case 'h':
	  show_usage(stdout, 0);
	  break;
	case 'v':
	case 'V':
	  print_version("coffdump");
	  xexit(0);
	case 0:
	  break;
	default:
	  show_usage(stderr, 1);
	  break;
	}
    }

  if (optind < ac)
    {
      input_file = av[optind];
    }

  if (!input_file)
    fatal(_("no input file specified"));

  abfd = bfd_openr(input_file, 0);

  if (!abfd)
    bfd_fatal(input_file);

  if (! bfd_check_format_matches(abfd, bfd_object, &matching))
    {
      bfd_nonfatal(input_file);

      if (bfd_get_error() == bfd_error_file_ambiguously_recognized)
	{
	  list_matching_formats(matching);
	  free(matching);
	}
      xexit(1);
    }

  tree = coff_grok(abfd);

  coff_dump(tree);
  printf("\n");

  return 0;
}