Exemplo n.º 1
0
static void
gldelf64ltsmip_find_exp_assignment (etree_type *exp)
{
  struct bfd_link_hash_entry *h;

  switch (exp->type.node_class)
    {
    case etree_provide:
      h = bfd_link_hash_lookup (link_info.hash, exp->assign.dst,
				FALSE, FALSE, FALSE);
      if (h == NULL)
	break;

      /* We call record_link_assignment even if the symbol is defined.
	 This is because if it is defined by a dynamic object, we
	 actually want to use the value defined by the linker script,
	 not the value from the dynamic object (because we are setting
	 symbols like etext).  If the symbol is defined by a regular
	 object, then, as it happens, calling record_link_assignment
	 will do no harm.  */

      /* Fall through.  */
    case etree_assign:
      if (strcmp (exp->assign.dst, ".") != 0)
	{
	  if (! (bfd_elf_record_link_assignment
		 (output_bfd, &link_info, exp->assign.dst,
		  exp->type.node_class == etree_provide ? TRUE : FALSE)))
	    einfo ("%P%F: failed to record assignment to %s: %E\n",
		   exp->assign.dst);
	}
      gldelf64ltsmip_find_exp_assignment (exp->assign.src);
      break;

    case etree_binary:
      gldelf64ltsmip_find_exp_assignment (exp->binary.lhs);
      gldelf64ltsmip_find_exp_assignment (exp->binary.rhs);
      break;

    case etree_trinary:
      gldelf64ltsmip_find_exp_assignment (exp->trinary.cond);
      gldelf64ltsmip_find_exp_assignment (exp->trinary.lhs);
      gldelf64ltsmip_find_exp_assignment (exp->trinary.rhs);
      break;

    case etree_unary:
      gldelf64ltsmip_find_exp_assignment (exp->unary.child);
      break;

    default:
      break;
    }
}
Exemplo n.º 2
0
/*
** Utility routine: bfd_pic30_report_data_sections()
*/ 
static void
bfd_pic30_report_data_sections (asection *sect, FILE *fp) {
  file_ptr start = sect->vma;
  unsigned int opb = bfd_octets_per_byte (output_bfd);
  bfd_size_type total = sect->_raw_size / opb; /* ignore phantom bytes */

  if (REPORT_AS_DATA(sect))
    {
      unsigned int gaps;
      char *name, *c;
      struct bfd_link_hash_entry *h = (struct bfd_link_hash_entry *) NULL;

      /* make a local copy of the name */
      name = xmalloc(strlen(sect->name) + strlen(GAP_ID) + 1);
      strcpy(name, sect->name);

      strcat(name, GAP_ID);
      h = bfd_link_hash_lookup (link_info.hash, name, FALSE, FALSE, TRUE);

      if (h == (struct bfd_link_hash_entry *) NULL)
        gaps = 0;
      else
        gaps = h->u.def.value / opb; /* ignore phantom bytes */

      /* clean the name of GAP_ID or %n.GAPID */
      c = strchr(name, '%');
      if (c) *c = '\x0';

      fprintf( fp, "%-24s%#10lx%#20x%#16lx  (%ld)\n", name,
             start, gaps, total, total);
      data_memory_used += total;

      free(name);
    }

  return;
} /* static void bfd_pic30_report_data_sections (...)*/
Exemplo n.º 3
0
static void
output_one_cref (FILE *fp, struct cref_hash_entry *h)
{
  int len;
  struct bfd_link_hash_entry *hl;
  struct cref_ref *r;

  hl = bfd_link_hash_lookup (link_info.hash, h->root.string, FALSE,
			     FALSE, TRUE);
  if (hl == NULL)
    einfo ("%P: symbol `%T' missing from main hash table\n",
	   h->root.string);
  else
    {
      /* If this symbol is defined in a dynamic object but never
	 referenced by a normal object, then don't print it.  */
      if (hl->type == bfd_link_hash_defined)
	{
	  if (hl->u.def.section->output_section == NULL)
	    return;
	  if (hl->u.def.section->owner != NULL
	      && (hl->u.def.section->owner->flags & DYNAMIC) != 0)
	    {
	      for (r = h->refs; r != NULL; r = r->next)
		if ((r->abfd->flags & DYNAMIC) == 0)
		  break;
	      if (r == NULL)
		return;
	    }
	}
    }

  fprintf (fp, "%s ", h->demangled);
  len = strlen (h->demangled) + 1;

  for (r = h->refs; r != NULL; r = r->next)
    {
      if (r->def)
	{
	  while (len < FILECOL)
	    {
	      putc (' ', fp);
	      ++len;
	    }
	  lfinfo (fp, "%B\n", r->abfd);
	  len = 0;
	}
    }

  for (r = h->refs; r != NULL; r = r->next)
    {
      if (! r->def)
	{
	  while (len < FILECOL)
	    {
	      putc (' ', fp);
	      ++len;
	    }
	  lfinfo (fp, "%B\n", r->abfd);
	  len = 0;
	}
    }

  ASSERT (len == 0);
}
Exemplo n.º 4
0
    free (asymbols);
}

/* Check one symbol to see if it is a prohibited cross reference.  */

static bfd_boolean
check_nocrossref (struct cref_hash_entry *h, void *ignore ATTRIBUTE_UNUSED)
{
  struct bfd_link_hash_entry *hl;
  asection *defsec;
  const char *defsecname;
  struct lang_nocrossrefs *ncrs;
  struct lang_nocrossref *ncr;
  struct cref_ref *ref;

  hl = bfd_link_hash_lookup (link_info.hash, h->root.string, FALSE,
			     FALSE, TRUE);
  if (hl == NULL)
    {
      einfo (_("%P: symbol `%T' missing from main hash table\n"),
	     h->root.string);
      return TRUE;
    }

  if (hl->type != bfd_link_hash_defined
      && hl->type != bfd_link_hash_defweak)
    return TRUE;

  defsec = hl->u.def.section->output_section;
  if (defsec == NULL)
    return TRUE;
  defsecname = bfd_get_section_name (defsec->owner, defsec);
Exemplo n.º 5
0
/* Get the symbol resolution info for a plugin-claimed input file.  */
static enum ld_plugin_status
get_symbols (const void *handle, int nsyms, struct ld_plugin_symbol *syms,
	     int def_ironly_exp)
{
  const bfd *abfd = handle;
  int n;

  ASSERT (called_plugin);
  for (n = 0; n < nsyms; n++)
    {
      struct bfd_link_hash_entry *blhe;
      asection *owner_sec;
      int res;

      if (syms[n].def != LDPK_UNDEF)
	blhe = bfd_link_hash_lookup (link_info.hash, syms[n].name,
				     FALSE, FALSE, TRUE);
      else
	blhe = bfd_wrapped_link_hash_lookup (link_info.output_bfd, &link_info,
					     syms[n].name, FALSE, FALSE, TRUE);
      if (!blhe)
	{
	  res = LDPR_UNKNOWN;
	  goto report_symbol;
	}

      /* Determine resolution from blhe type and symbol's original type.  */
      if (blhe->type == bfd_link_hash_undefined
	  || blhe->type == bfd_link_hash_undefweak)
	{
	  res = LDPR_UNDEF;
	  goto report_symbol;
	}
      if (blhe->type != bfd_link_hash_defined
	  && blhe->type != bfd_link_hash_defweak
	  && blhe->type != bfd_link_hash_common)
	{
	  /* We should not have a new, indirect or warning symbol here.  */
	  einfo ("%P%F: %s: plugin symbol table corrupt (sym type %d)\n",
		 called_plugin->name, blhe->type);
	}

      /* Find out which section owns the symbol.  Since it's not undef,
	 it must have an owner; if it's not a common symbol, both defs
	 and weakdefs keep it in the same place. */
      owner_sec = (blhe->type == bfd_link_hash_common
		   ? blhe->u.c.p->section
		   : blhe->u.def.section);


      /* If it was originally undefined or common, then it has been
	 resolved; determine how.  */
      if (syms[n].def == LDPK_UNDEF
	  || syms[n].def == LDPK_WEAKUNDEF
	  || syms[n].def == LDPK_COMMON)
	{
	  if (owner_sec->owner == link_info.output_bfd)
	    res = LDPR_RESOLVED_EXEC;
	  else if (owner_sec->owner == abfd)
	    res = LDPR_PREVAILING_DEF_IRONLY;
	  else if (is_ir_dummy_bfd (owner_sec->owner))
	    res = LDPR_RESOLVED_IR;
	  else if (owner_sec->owner != NULL
		   && (owner_sec->owner->flags & DYNAMIC) != 0)
	    res = LDPR_RESOLVED_DYN;
	  else
	    res = LDPR_RESOLVED_EXEC;
	}

      /* Was originally def, or weakdef.  Does it prevail?  If the
	 owner is the original dummy bfd that supplied it, then this
	 is the definition that has prevailed.  */
      else if (owner_sec->owner == link_info.output_bfd)
	res = LDPR_PREEMPTED_REG;
      else if (owner_sec->owner == abfd)
	res = LDPR_PREVAILING_DEF_IRONLY;

      /* Was originally def, weakdef, or common, but has been pre-empted.  */
      else if (is_ir_dummy_bfd (owner_sec->owner))
	res = LDPR_PREEMPTED_IR;
      else
	res = LDPR_PREEMPTED_REG;

      if (res == LDPR_PREVAILING_DEF_IRONLY)
	{
	  /* We need to know if the sym is referenced from non-IR files.  Or
	     even potentially-referenced, perhaps in a future final link if
	     this is a partial one, perhaps dynamically at load-time if the
	     symbol is externally visible.  */
	  if (blhe->non_ir_ref)
	    res = LDPR_PREVAILING_DEF;
	  else if (is_visible_from_outside (&syms[n], blhe))
	    res = def_ironly_exp;
	}

    report_symbol:
      syms[n].resolution = res;
      if (report_plugin_symbols)
	einfo (_("%P: %B: symbol `%s' "
		 "definition: %d, visibility: %d, resolution: %d\n"),
	       abfd, syms[n].name,
	       syms[n].def, syms[n].visibility, res);
    }
  return LDPS_OK;
}
Exemplo n.º 6
0
   the trampoline handler.  */

bfd_boolean
elf32_m68hc11_add_symbol_hook (bfd *abfd, struct bfd_link_info *info,
                               Elf_Internal_Sym *sym,
                               const char **namep ATTRIBUTE_UNUSED,
                               flagword *flagsp ATTRIBUTE_UNUSED,
                               asection **secp ATTRIBUTE_UNUSED,
                               bfd_vma *valp ATTRIBUTE_UNUSED)
{
  if (sym->st_other & STO_M68HC12_FAR)
    {
      struct elf_link_hash_entry *h;

      h = (struct elf_link_hash_entry *)
	bfd_link_hash_lookup (info->hash, "__far_trampoline",
                              FALSE, FALSE, FALSE);
      if (h == NULL)
        {
          struct bfd_link_hash_entry* entry = NULL;

          _bfd_generic_link_add_one_symbol (info, abfd,
                                            "__far_trampoline",
                                            BSF_GLOBAL,
                                            bfd_und_section_ptr,
                                            (bfd_vma) 0, (const char*) NULL,
                                            FALSE, FALSE, &entry);
        }

    }
  return TRUE;
}
Exemplo n.º 7
0
Arquivo: ldmain.c Projeto: msmania/gdb
int
main (int argc, char **argv)
{
  char *emulation;
  long start_time = get_run_time ();
#ifdef HAVE_SBRK
  char *start_sbrk = (char *) sbrk (0);
#endif

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

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

  START_PROGRESS (program_name, 0);

  expandargv (&argc, &argv);

  bfd_init ();

  bfd_set_error_program_name (program_name);

  /* We want to notice and fail on those nasty BFD assertions which are
     likely to signal incorrect output being generated but otherwise may
     leave no trace.  */
  default_bfd_assert_handler = bfd_set_assert_handler (ld_bfd_assert_handler);

  xatexit (ld_cleanup);

  /* Set up the sysroot directory.  */
  ld_sysroot = get_sysroot (argc, argv);
  if (*ld_sysroot)
    ld_canon_sysroot = lrealpath (ld_sysroot);
  if (ld_canon_sysroot)
    ld_canon_sysroot_len = strlen (ld_canon_sysroot);
  else
    ld_canon_sysroot_len = -1;

  /* Set the default BFD target based on the configured target.  Doing
     this permits the linker to be configured for a particular target,
     and linked against a shared BFD library which was configured for
     a different target.  The macro TARGET is defined by Makefile.  */
  if (! bfd_set_default_target (TARGET))
    {
      einfo (_("%X%P: can't set BFD default target to `%s': %E\n"), TARGET);
      xexit (1);
    }

#if YYDEBUG
  {
    extern int yydebug;
    yydebug = 1;
  }
#endif

  config.build_constructors = TRUE;
  config.rpath_separator = ':';
  config.split_by_reloc = (unsigned) -1;
  config.split_by_file = (bfd_size_type) -1;
  config.make_executable = TRUE;
  config.magic_demand_paged = TRUE;
  config.text_read_only = TRUE;
  link_info.disable_target_specific_optimizations = -1;

  command_line.warn_mismatch = TRUE;
  command_line.warn_search_mismatch = TRUE;
  command_line.check_section_addresses = -1;

  /* We initialize DEMANGLING based on the environment variable
     COLLECT_NO_DEMANGLE.  The gcc collect2 program will demangle the
     output of the linker, unless COLLECT_NO_DEMANGLE is set in the
     environment.  Acting the same way here lets us provide the same
     interface by default.  */
  demangling = getenv ("COLLECT_NO_DEMANGLE") == NULL;

  link_info.allow_undefined_version = TRUE;
  link_info.keep_memory = TRUE;
  link_info.combreloc = TRUE;
  link_info.strip_discarded = TRUE;
  link_info.emit_hash = TRUE;
  link_info.callbacks = &link_callbacks;
  link_info.input_bfds_tail = &link_info.input_bfds;
  /* SVR4 linkers seem to set DT_INIT and DT_FINI based on magic _init
     and _fini symbols.  We are compatible.  */
  link_info.init_function = "_init";
  link_info.fini_function = "_fini";
  link_info.relax_pass = 1;
  link_info.extern_protected_data = -1;
  link_info.dynamic_undefined_weak = -1;
  link_info.pei386_auto_import = -1;
  link_info.spare_dynamic_tags = 5;
  link_info.path_separator = ':';
#ifdef DEFAULT_FLAG_COMPRESS_DEBUG
  link_info.compress_debug = COMPRESS_DEBUG_GABI_ZLIB;
#endif

  ldfile_add_arch ("");
  emulation = get_emulation (argc, argv);
  ldemul_choose_mode (emulation);
  default_target = ldemul_choose_target (argc, argv);
  config.maxpagesize = bfd_emul_get_maxpagesize (default_target);
  config.commonpagesize = bfd_emul_get_commonpagesize (default_target);
  lang_init ();
  ldexp_init ();
  ldemul_before_parse ();
  lang_has_input_file = FALSE;
  parse_args (argc, argv);

  if (config.hash_table_size != 0)
    bfd_hash_set_default_size (config.hash_table_size);

#ifdef ENABLE_PLUGINS
  /* Now all the plugin arguments have been gathered, we can load them.  */
  plugin_load_plugins ();
#endif /* ENABLE_PLUGINS */

  ldemul_set_symbols ();

  /* If we have not already opened and parsed a linker script,
     try the default script from command line first.  */
  if (saved_script_handle == NULL
      && command_line.default_script != NULL)
    {
      ldfile_open_command_file (command_line.default_script);
      parser_input = input_script;
      yyparse ();
    }

  /* If we have not already opened and parsed a linker script
     read the emulation's appropriate default script.  */
  if (saved_script_handle == NULL)
    {
      int isfile;
      char *s = ldemul_get_script (&isfile);

      if (isfile)
	ldfile_open_default_command_file (s);
      else
	{
	  lex_string = s;
	  lex_redirect (s, _("built in linker script"), 1);
	}
      parser_input = input_script;
      yyparse ();
      lex_string = NULL;
    }

  if (verbose)
    {
      if (saved_script_handle)
	info_msg (_("using external linker script:"));
      else
	info_msg (_("using internal linker script:"));
      info_msg ("\n==================================================\n");

      if (saved_script_handle)
	{
	  static const int ld_bufsz = 8193;
	  size_t n;
	  char *buf = (char *) xmalloc (ld_bufsz);

	  rewind (saved_script_handle);
	  while ((n = fread (buf, 1, ld_bufsz - 1, saved_script_handle)) > 0)
	    {
	      buf[n] = 0;
	      info_msg (buf);
	    }
	  rewind (saved_script_handle);
	  free (buf);
	}
      else
	{
	  int isfile;

	  info_msg (ldemul_get_script (&isfile));
	}

      info_msg ("\n==================================================\n");
    }

  if (command_line.print_output_format)
    info_msg ("%s\n", lang_get_output_target ());

  lang_final ();

  /* If the only command line argument has been -v or --version or --verbose
     then ignore any input files provided by linker scripts and exit now.
     We do not want to create an output file when the linker is just invoked
     to provide version information.  */
  if (argc == 2 && version_printed)
    xexit (0);

  if (!lang_has_input_file)
    {
      if (version_printed || command_line.print_output_format)
	xexit (0);
      einfo (_("%P%F: no input files\n"));
    }

  if (trace_files)
    info_msg (_("%P: mode %s\n"), emulation);

  ldemul_after_parse ();

  if (config.map_filename)
    {
      if (strcmp (config.map_filename, "-") == 0)
	{
	  config.map_file = stdout;
	}
      else
	{
	  config.map_file = fopen (config.map_filename, FOPEN_WT);
	  if (config.map_file == (FILE *) NULL)
	    {
	      bfd_set_error (bfd_error_system_call);
	      einfo (_("%P%F: cannot open map file %s: %E\n"),
		     config.map_filename);
	    }
	}
    }

  lang_process ();

  /* Print error messages for any missing symbols, for any warning
     symbols, and possibly multiple definitions.  */
  if (bfd_link_relocatable (&link_info))
    link_info.output_bfd->flags &= ~EXEC_P;
  else
    link_info.output_bfd->flags |= EXEC_P;

  if ((link_info.compress_debug & COMPRESS_DEBUG))
    {
      link_info.output_bfd->flags |= BFD_COMPRESS;
      if (link_info.compress_debug == COMPRESS_DEBUG_GABI_ZLIB)
	link_info.output_bfd->flags |= BFD_COMPRESS_GABI;
    }

  ldwrite ();

  if (config.map_file != NULL)
    lang_map ();
  if (command_line.cref)
    output_cref (config.map_file != NULL ? config.map_file : stdout);
  if (nocrossref_list != NULL)
    check_nocrossrefs ();
  if (command_line.print_memory_usage)
    lang_print_memory_usage ();
#if 0
  {
    struct bfd_link_hash_entry * h;

    h = bfd_link_hash_lookup (link_info.hash, "__image_base__", 0,0,1);
    fprintf (stderr, "lookup = %p val %lx\n", h, h ? h->u.def.value : 1);
  }
#endif
  ldexp_finish ();
  lang_finish ();

  /* Even if we're producing relocatable output, some non-fatal errors should
     be reported in the exit status.  (What non-fatal errors, if any, do we
     want to ignore for relocatable output?)  */
  if (!config.make_executable && !force_make_executable)
    {
      if (trace_files)
	einfo (_("%P: link errors found, deleting executable `%s'\n"),
	       output_filename);

      /* The file will be removed by ld_cleanup.  */
      xexit (1);
    }
  else
    {
      if (! bfd_close (link_info.output_bfd))
	einfo (_("%F%B: final close failed: %E\n"), link_info.output_bfd);

      /* If the --force-exe-suffix is enabled, and we're making an
	 executable file and it doesn't end in .exe, copy it to one
	 which does.  */
      if (!bfd_link_relocatable (&link_info)
	  && command_line.force_exe_suffix)
	{
	  int len = strlen (output_filename);

	  if (len < 4
	      || (strcasecmp (output_filename + len - 4, ".exe") != 0
		  && strcasecmp (output_filename + len - 4, ".dll") != 0))
	    {
	      FILE *src;
	      FILE *dst;
	      const int bsize = 4096;
	      char *buf = (char *) xmalloc (bsize);
	      int l;
	      char *dst_name = (char *) xmalloc (len + 5);

	      strcpy (dst_name, output_filename);
	      strcat (dst_name, ".exe");
	      src = fopen (output_filename, FOPEN_RB);
	      dst = fopen (dst_name, FOPEN_WB);

	      if (!src)
		einfo (_("%P%F: unable to open for source of copy `%s'\n"),
		       output_filename);
	      if (!dst)
		einfo (_("%P%F: unable to open for destination of copy `%s'\n"),
		       dst_name);
	      while ((l = fread (buf, 1, bsize, src)) > 0)
		{
		  int done = fwrite (buf, 1, l, dst);

		  if (done != l)
		    einfo (_("%P: Error writing file `%s'\n"), dst_name);
		}

	      fclose (src);
	      if (fclose (dst) == EOF)
		einfo (_("%P: Error closing file `%s'\n"), dst_name);
	      free (dst_name);
	      free (buf);
	    }
	}
    }

  END_PROGRESS (program_name);

  if (config.stats)
    {
#ifdef HAVE_SBRK
      char *lim = (char *) sbrk (0);
#endif
      long run_time = get_run_time () - start_time;

      fflush (stdout);
      fprintf (stderr, _("%s: total time in link: %ld.%06ld\n"),
	       program_name, run_time / 1000000, run_time % 1000000);
#ifdef HAVE_SBRK
      fprintf (stderr, _("%s: data size %ld\n"), program_name,
	       (long) (lim - start_sbrk));
#endif
      fflush (stderr);
    }

  /* Prevent ld_cleanup from doing anything, after a successful link.  */
  output_filename = NULL;

  xexit (0);
  return 0;
}
Exemplo n.º 8
0
int main ( int argc, char ** argv )
{
    int init_address=-1;
    int max_align = 0;
    unsigned long curr_size = 0;
    bfd *obj_bfd = NULL;
    bfd_error_type myerr;
    unsigned u = 0, v = 0;
    asymbol **q = NULL;
    asection *s = NULL;
    static struct bfd_link_callbacks link_callbacks;
    static struct bfd_link_order link_order;

    void *current = NULL;
    void *cfd_self      = NULL;
    void *cfd_start     = NULL;
    int   cfd_size      = 0;
    void *the_start     = NULL;
    void *start_address = NULL;
    void *m             = NULL;
    
    fprintf ( stderr, "In BFD fast load test. Reloc_howto_type size %d\n",
              sizeof ( rhtt ) );
    
    if ( argc < 3 ) {
        fprintf ( stderr, "Need an executable (eg raw_gcl.exe) and an object file as arguments.\n" );
    } else {

        memset ( &link_info, 0, sizeof (link_info) );
        memset ( &link_order, 0, sizeof (link_order) );
        memset ( &link_callbacks, 0, sizeof (link_callbacks) );
        

        fprintf ( stderr, "BUILDING EXECUTABLE SYMBOL TABLE FOR %s \n", argv[1] );
        build_symbol_table_bfd ( argv[1] );        

        link_callbacks.add_archive_element=madd_archive_element;
        link_callbacks.multiple_definition=mmultiple_definition;
        link_callbacks.multiple_common=mmultiple_common;
        link_callbacks.add_to_set=madd_to_set;
        link_callbacks.constructor=mconstructor;
        link_callbacks.warning=mwarning;
        link_callbacks.undefined_symbol=mundefined_symbol;
        link_callbacks.reloc_overflow=mreloc_overflow;
        link_callbacks.reloc_dangerous=mreloc_dangerous;
        link_callbacks.unattached_reloc=munattached_reloc;
        link_callbacks.notice = mnotice;
        link_info.callbacks = &link_callbacks;
        link_order.type = bfd_indirect_link_order;

        fprintf ( stderr, "OPENING OBJECT FILE %s\n", argv[2] );
        if ( ! ( obj_bfd = bfd_openr ( argv[2], 0 ) ) ) {
            fprintf ( stderr, "Cannot open bfd.\n" );
        }
        
        if ( ( myerr = bfd_get_error () ) && myerr != 3 ) {
            fprintf ( stderr, "Unknown bfd error code on openr %s %d\n.", argv[2], myerr );
        }
        fflush ( stderr );
        if ( ! bfd_check_format ( obj_bfd, bfd_object ) ) {
            fprintf ( stderr, "Unknown bfd format %s.\n", argv[2] );
        }

        if ( ( myerr = bfd_get_error () ) && myerr != 3 ) {
            fprintf ( stderr, "Unknown bfd error code on check_format %s\n", argv[2] );
        }

        bfd_set_error(0);

        current = NULL;

        fprintf ( stderr, "CALCULATING CURRENT, MAX_ALIGN and ALLOCATING \n\n" );

        for ( s= obj_bfd->sections;s;s=s->next) {

            s->owner = obj_bfd;
            s->output_section = ( s->flags & SEC_ALLOC) ? s : obj_bfd->sections;
            s->output_offset=0;

            if (!(s->flags & SEC_ALLOC))
                continue;

            if (max_align<s->alignment_power)
                max_align=s->alignment_power;

            current=round_up(current,1<<s->alignment_power);

            current+=s->_raw_size;

            fprintf ( stderr,
                      "Section %s: owner = %x, output_offset = %x, "
                      "output_section = %x (%s)\n",
                      s->name, s->owner, s->output_offset, s->output_section,
                      s->output_section->name );
        }

        fprintf ( stderr, "1\n");
        curr_size=(unsigned long)current;
        max_align=1<<max_align;

        cfd_self      = 0;
        cfd_start     = 0;
        cfd_size      = curr_size + (max_align > sizeof(char *) ? max_align :0);
        
        cfd_start = (void *) malloc ( cfd_size );
        the_start = start_address = cfd_start;
        
        fprintf ( stderr, "ALLOCATED %d bytes \n\n", cfd_size );
        fprintf ( stderr,
                  "max_align = %d, current = %d, cfd_self  = %x, "
                  "cfd_size  = %x, cfd_start = %x\n",
                  max_align, current, cfd_self, cfd_size, cfd_start );

        start_address = ROUND_UP ( start_address, max_align );
        cfd_size = cfd_size - ( start_address - the_start );
        cfd_start = (void *) start_address;	

        fprintf ( stderr,
                  "max_align = %d, current = %d, cfd_self  = %x, "
                  "cfd_size  = %x, cfd_start = %x\n",
                  max_align, current, cfd_self, cfd_size, cfd_start );

        memset ( cfd_start, 0, cfd_size );
        
        for ( m = start_address, s = obj_bfd->sections; s; s=s->next ) {

            if (!(s->flags & SEC_ALLOC))
                continue;

            m=round_up(m,1<<s->alignment_power);
            s->output_section->vma=(unsigned long)m;
            m+=s->_raw_size;
            fprintf ( stderr, "Section address %x\n", s );
            fprintf ( stderr, "m loop Section %s: owner = %x, output_offset = %x, "
                      "output_section = %x (%s), vma = %x, m = %x\n",
                      s->name, s->owner, s->output_offset,
                      s->output_section, s->output_section->name,
                      s->output_section->vma, m );
        }

        fprintf ( stderr, "\n\nDOING SOMETHING WITH THE HASHED SYMBOLS\n\n" );
        if ((u=bfd_get_symtab_upper_bound(obj_bfd))<0)
            fprintf ( stderr, "Cannot get symtab uppoer bound.\n" );
        q = (asymbol **) alloca ( u );
        if ( ( v = bfd_canonicalize_symtab ( obj_bfd, q ) ) < 0 )
            fprintf ( stderr, "cannot canonicalize symtab.\n" );
        fprintf ( stderr, "u = %d, v = %d\n", u, v );
        for (u=0;u<v;u++) {

            struct bfd_link_hash_entry *h;

            fprintf ( stderr, "u loop q[%d]->name = %s\n", u, q[u]->name );

            if (!strncmp("init_",q[u]->name,5)) {
                init_address=q[u]->value;
                continue;
            }

            if (!(h=bfd_link_hash_lookup(link_info.hash,q[u]->name, MY_BFD_FALSE, MY_BFD_FALSE, MY_BFD_TRUE))) 
                continue;

            if (h->type!=bfd_link_hash_defined) 
                fprintf ( stderr, "Undefined symbol.\n" );
            
            if (h->u.def.section) {
                q[u]->value=h->u.def.value+h->u.def.section->vma;
                q[u]->flags|=BSF_WEAK;
            } else 
                fprintf ( stderr, "Symbol without section.\n" );

        }

        fprintf ( stderr, "\n\nDOING RELOCATIONS\n\n", cfd_size );
        fflush ( stderr );
        for ( s = obj_bfd->sections; s; s = s->next ) {

            fprintf ( stderr, "s->name %s, s->flags = %x\n", s->name, s->flags );
            if ( ! ( s->flags & SEC_LOAD ) )
                continue;

            link_order.u.indirect.section=s;

            fprintf ( stderr, "About to get reloc section contents\n" );

            fprintf ( stderr, "obj_bfd = %x, section %s, s->output_section = %x, q = %x\n",
                      obj_bfd, s->name, s->output_section, q);

            fflush ( stderr );
            if (!bfd_get_relocated_section_contents(obj_bfd, &link_info,&link_order,
                                                     (void *)(unsigned long)s->output_section->vma,0,q)) 
                fprintf ( stderr, "Cannot get relocated section contents\n");
            
        }
        
        bfd_close ( obj_bfd );
        printf("start address -T %x \n", cfd_start);
    }
}
Exemplo n.º 9
0
int build_symbol_table_bfd ( char *oname ) {

    int u,v;
    asymbol **q;

    bfd_init();
    if ( ! ( exe_bfd = bfd_openr ( oname, 0 ) ) ) {
        fprintf ( stderr, "Cannot open %s.\n", oname );
        exit ( 0 );
    }
    
    if ( ! bfd_check_format ( exe_bfd, bfd_object ) ) {
        fprintf ( stderr, "I'm not an object.\n" );
        exit ( 0 );
    }
    
    if ( !(link_info.hash = bfd_link_hash_table_create ( exe_bfd ) ) ) {
        fprintf ( stderr, "Cannot make hash table.\n" );
        exit ( 0 );
    }
    
    if ( !bfd_link_add_symbols ( exe_bfd, &link_info ) ) {
        fprintf ( stderr, "Cannot add self symbols\n.\n" );
        exit ( 0 );
    }
    
    if ( ( u = bfd_get_symtab_upper_bound ( exe_bfd ) ) < 0 ) {
        fprintf ( stderr, "Cannot get self's symtab upper bound.\n" );
        exit ( 0 );
    }
    
    fprintf ( stderr, "Allocating symbol table (%d bytes)\n", u );
    q = (asymbol **) malloc ( u );

    if ( ( v = bfd_canonicalize_symtab ( exe_bfd, q ) ) < 0 ) {
        fprintf ( stderr, "Cannot canonicalize self's symtab.\n" );
        exit ( 0 );
    }

#ifdef _WIN32        
    for ( u=0; u < v; u++ ) {
        char *c;
        if ( ( c = (char *) strstr ( q[u]->name, "_" ) ) ) {
            struct bfd_link_hash_entry *h;
            if ( ( h = bfd_link_hash_lookup ( link_info.hash,
                                                q[u]->name, MY_BFD_TRUE,MY_BFD_TRUE,MY_BFD_TRUE ) ) ) {
                h->type=bfd_link_hash_defined;
                if ( !q[u]->section )
                    fprintf ( stderr, "Symbol is missing section.\n" );
                h->u.def.value   = q[u]->value + q[u]->section->vma;
                h->u.def.section = q[u]->section;
                fprintf ( stderr, "Processed %s\n", q[u]->name );
            } else {
                fprintf ( stderr, "Cannot make new hash entry.\n" );
            }
        }
    }
#else    
    for (u=0;u<v;u++) {
        char *c;
        if ((c=(char *)strstr(q[u]->name,"@@GLIBC\n" ))) {
            struct bfd_link_hash_entry *h;
            *c=0;
            if (!(h=bfd_link_hash_lookup(link_info.hash,q[u]->name,MY_BFD_TRUE,MY_BFD_TRUE,MY_BFD_TRUE)))
                fprintf ( stderr, "Cannot make new hash entry.\n" );
            h->type=bfd_link_hash_defined;
            if (!q[u]->section)
                fprintf ( stderr, "Symbol is missing section.\n" );
            h->u.def.value=q[u]->value+q[u]->section->vma;
            h->u.def.section=q[u]->section;
            *c='@';
        }
    }
#endif        
    bfd_close ( exe_bfd );
    free(q);
    return 0;
    
}