コード例 #1
0
static unsigned long
find_base (bfd *prog_bfd)
{
  int found;
  unsigned long base = ~(0UL);
  asection *s;

  found = 0;
  for (s = prog_bfd->sections; s; s = s->next)
    {
      if ((strcmp (bfd_get_section_name (prog_bfd, s), ".boot") == 0)
	  || (strcmp (bfd_get_section_name (prog_bfd, s), ".text") == 0)
	  || (strcmp (bfd_get_section_name (prog_bfd, s), ".data") == 0)
	  || (strcmp (bfd_get_section_name (prog_bfd, s), ".bss") == 0))
	{
	  if (!found)
	    {
	      base = bfd_get_section_vma (prog_bfd, s);
	      found = 1;
	    }
	  else
	    base =
	      bfd_get_section_vma (prog_bfd,
				   s) < base ? bfd_get_section_vma (prog_bfd,
								    s) : base;
	}
    }
  return base & ~(0xffffUL);
}
コード例 #2
0
ファイル: subsegs.c プロジェクト: Caleb1994/stewieos-binutils
segT
subseg_get (const char *segname, int force_new)
{
  segT secptr;
  segment_info_type *seginfo;
  const char *now_seg_name = (now_seg
			      ? bfd_get_section_name (stdoutput, now_seg)
			      : 0);

  if (!force_new
      && now_seg_name
      && (now_seg_name == segname
	  || !strcmp (now_seg_name, segname)))
    return now_seg;

  if (!force_new)
    secptr = bfd_make_section_old_way (stdoutput, segname);
  else
    secptr = bfd_make_section_anyway (stdoutput, segname);

  seginfo = seg_info (secptr);
  if (! seginfo)
    {
      secptr->output_section = secptr;
      seginfo = XCNEW (segment_info_type);
      seginfo->bfd_section = secptr;
      bfd_set_section_userdata (stdoutput, secptr, seginfo);
    }
  return secptr;
}
コード例 #3
0
ファイル: dw2gencfi.c プロジェクト: aznrice/gnu_binutils
static char *
get_debugseg_name (segT seg, const char *base_name)
{
  const char *name;

  if (!seg)
    name = "";
  else
    {
      const char * dollar;
      const char * dot;

      name = bfd_get_section_name (stdoutput, seg);

      dollar = strchr (name, '$');
      dot = strchr (name + 1, '.');

      if (!dollar && !dot)
	name = "";
      else if (!dollar)
	name = dot;
      else if (!dot)
	name = dollar;
      else if (dot < dollar)
	name = dot;
      else
	name = dollar;
    }

  return concat (base_name, name, NULL);
}
コード例 #4
0
ファイル: symfile-mem.c プロジェクト: Xilinx/gdb
/* Read inferior memory at ADDR to find the header of a loaded object file
   and read its in-core symbols out of inferior memory.  TEMPL is a bfd
   representing the target's format.  NAME is the name to use for this
   symbol file in messages; it can be NULL or a malloc-allocated string
   which will be attached to the BFD.  */
static struct objfile *
symbol_file_add_from_memory (struct bfd *templ, CORE_ADDR addr, char *name,
			     int from_tty)
{
  struct objfile *objf;
  struct bfd *nbfd;
  struct bfd_section *sec;
  bfd_vma loadbase;
  struct section_addr_info *sai;
  unsigned int i;
  struct cleanup *cleanup;

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

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

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

  cleanup = make_cleanup_bfd_unref (nbfd);

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

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

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

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

  do_cleanups (cleanup);
  return objf;
}
コード例 #5
0
static bfd_boolean
link_callbacks_undefined_symbol (struct bfd_link_info *link_info,
				 const char *name, bfd *abfd, asection *section,
				 bfd_vma address, bfd_boolean is_fatal)
{
  warning (_("Cannot resolve relocation to \"%s\" "
	     "from compiled module \"%s\" section \"%s\"."),
	   name, bfd_get_filename (abfd), bfd_get_section_name (abfd, section));
  return FALSE;
}
コード例 #6
0
/* Read inferior memory at ADDR to find the header of a loaded object file
   and read its in-core symbols out of inferior memory.  TEMPL is a bfd
   representing the target's format.  NAME is the name to use for this
   symbol file in messages; it can be NULL or a malloc-allocated string
   which will be attached to the BFD.  */
static struct objfile *
symbol_file_add_from_memory (struct bfd *templ, CORE_ADDR addr, char *name,
			     int from_tty)
{
  struct objfile *objf;
  struct bfd *nbfd;
  struct bfd_section *sec;
  bfd_vma loadbase;
  struct section_addr_info *sai;
  unsigned int i;

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

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

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

  if (!bfd_check_format (nbfd, bfd_object))
    {
      /* FIXME: should be checking for errors from bfd_close (for one thing,
         on error it does not free all the storage associated with the
         bfd).  */
      bfd_close (nbfd);
      error (_("Got object file from memory but can't read symbols: %s."),
	     bfd_errmsg (bfd_get_error ()));
    }

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

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

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

  return objf;
}
コード例 #7
0
static bfd_boolean
link_callbacks_reloc_dangerous (struct bfd_link_info *link_info,
				const char *message, bfd *abfd,
				asection *section, bfd_vma address)
{
  warning (_("Compiled module \"%s\" section \"%s\": dangerous "
	     "relocation: %s\n"),
	   bfd_get_filename (abfd), bfd_get_section_name (abfd, section),
	   message);
  return FALSE;
}
コード例 #8
0
static bfd_boolean
link_callbacks_unattached_reloc (struct bfd_link_info *link_info,
				 const char *name, bfd *abfd, asection *section,
				 bfd_vma address)
{
  warning (_("Compiled module \"%s\" section \"%s\": unattached "
	     "relocation: %s\n"),
	   bfd_get_filename (abfd), bfd_get_section_name (abfd, section),
	   name);
  return FALSE;
}
コード例 #9
0
static bfd_boolean
link_callbacks_warning (struct bfd_link_info *link_info, const char *xwarning,
                        const char *symbol, bfd *abfd, asection *section,
			bfd_vma address)
{
  warning (_("Compiled module \"%s\" section \"%s\": warning: %s"),
	   bfd_get_filename (abfd), bfd_get_section_name (abfd, section),
	   xwarning);
  /* Maybe permit running as a module?  */
  return FALSE;
}
コード例 #10
0
ファイル: load.c プロジェクト: Drakey83/steamlink-sdk
/* Given a file offset, look up the section name.  */
static const char *
find_section_name_by_offset (bfd *abfd, file_ptr filepos)
{
  asection *s;

  for (s = abfd->sections; s; s = s->next)
    if (s->filepos == filepos)
      return bfd_get_section_name (abfd, s);

  return "(unknown)";
}
コード例 #11
0
ファイル: symfile-mem.c プロジェクト: jon-turney/binutils-gdb
/* Read inferior memory at ADDR to find the header of a loaded object file
   and read its in-core symbols out of inferior memory.  SIZE, if
   non-zero, is the known size of the object.  TEMPL is a bfd
   representing the target's format.  NAME is the name to use for this
   symbol file in messages; it can be NULL or a malloc-allocated string
   which will be attached to the BFD.  */
static struct objfile *
symbol_file_add_from_memory (struct bfd *templ, CORE_ADDR addr,
			     size_t size, char *name, int from_tty)
{
  struct objfile *objf;
  struct bfd *nbfd;
  struct bfd_section *sec;
  bfd_vma loadbase;
  symfile_add_flags add_flags = 0;

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

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

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

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

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

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

  if (from_tty)
    add_flags |= SYMFILE_VERBOSE;

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

  add_target_sections_of_objfile (objf);

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

  return objf;
}
コード例 #12
0
ファイル: mips-sde-tdep.c プロジェクト: ChrisG0x20/gdb
static void
mips_sde_elf_osabi_sniff_abi_tag_sections (bfd *abfd, asection *sect,
					   void *obj)
{
  enum gdb_osabi *os_ident_ptr = (enum gdb_osabi *) obj;
  const char *name;

  name = bfd_get_section_name (abfd, sect);

  /* The presence of a section with a ".sde" prefix is indicative
     of an SDE binary.  */
  if (startswith (name, ".sde"))
    *os_ident_ptr = GDB_OSABI_SDE;
}
コード例 #13
0
ファイル: mips-irix-tdep.c プロジェクト: gygy/asuswrt
static void
mips_irix_elf_osabi_sniff_abi_tag_sections (bfd *abfd, asection *sect,
                                            void *obj)
{
  enum gdb_osabi *os_ident_ptr = obj;
  const char *name;
  unsigned int sectsize;

  name = bfd_get_section_name (abfd, sect);
  sectsize = bfd_section_size (abfd, sect);

  if (strncmp (name, ".MIPS.", 6) == 0 && sectsize > 0)
    {
      /* The presence of a section named with a ".MIPS." prefix is
         indicative of an IRIX binary.  */
      *os_ident_ptr = GDB_OSABI_IRIX;
    }
}
コード例 #14
0
ファイル: low-sim.c プロジェクト: cooljeanius/apple-gdb-1824
static void
mygeneric_load (bfd *loadfile_bfd)
{
  asection *s;

  for (s = loadfile_bfd->sections; s; s = s->next)
    {
      if (s->flags & SEC_LOAD)
	{
	  bfd_size_type size;

	  size = bfd_get_section_size_before_reloc (s);
	  if (size > 0)
	    {
	      char *buffer;
	      bfd_vma lma;	/* use load address, not virtual address */

	      buffer = xmalloc (size);
	      lma = s->lma;

	      /* Is this really necessary? I guess it gives the user something
	       * to look at during a long download.
		   */
	      printf ("Loading section %s, size 0x%lx lma 0x%lx\n",
		      bfd_get_section_name (loadfile_bfd, s),
		      (unsigned long) size,
		      (unsigned long) lma);	/* chops high 32 bits.  FIXME!! */

	      bfd_get_section_contents (loadfile_bfd, s, buffer, 0, size);

	      write_inferior_memory (lma, buffer, size);
	      free (buffer);
	    }
	}
    }

  printf ("Start address 0x%lx\n",
	  (unsigned long) loadfile_bfd->start_address);

  /* We were doing this in remote-mips.c, I suspect it is right
   * for other targets too.
   */
  /* write_pc (loadfile_bfd->start_address); *//* FIXME!! */
}
コード例 #15
0
ファイル: bucomm.c プロジェクト: 0x7678/playbook-dev-tools
void
bfd_nonfatal_message (const char *filename,
		      const bfd *abfd,
		      const asection *section,
		      const char *format, ...)
{
  const char *errmsg;
  const char *section_name;
  va_list args;

  errmsg = bfd_errmsg (bfd_get_error ());
  fflush (stdout);
  section_name = NULL;
  va_start (args, format);
  fprintf (stderr, "%s", program_name);
  
  if (abfd)
    {
      if (!filename)
	filename = bfd_get_archive_filename (abfd);
      if (section)
	section_name = bfd_get_section_name (abfd, section);
    }
  if (section_name)
    fprintf (stderr, ":%s[%s]", filename, section_name);
  else
    fprintf (stderr, ":%s", filename);

  if (format)
    {
      fprintf (stderr, ": ");
      vfprintf (stderr, format, args);
    }
  fprintf (stderr, ": %s\n", errmsg);
  va_end (args);
}
コード例 #16
0
static void
copy_sections (bfd *abfd, asection *sect, void *data)
{
  asymbol **symbol_table = data;
  bfd_byte *sect_data, *sect_data_got;
  struct cleanup *cleanups;
  struct bfd_link_info link_info;
  struct bfd_link_order link_order;
  CORE_ADDR inferior_addr;
  struct link_hash_table_cleanup_data cleanup_data;

  if ((bfd_get_section_flags (abfd, sect) & (SEC_ALLOC | SEC_LOAD))
      != (SEC_ALLOC | SEC_LOAD))
    return;

  if (bfd_get_section_size (sect) == 0)
    return;

  /* Mostly a copy of bfd_simple_get_relocated_section_contents which GDB
     cannot use as it does not report relocations to undefined symbols.  */
  memset (&link_info, 0, sizeof (link_info));
  link_info.output_bfd = abfd;
  link_info.input_bfds = abfd;
  link_info.input_bfds_tail = &abfd->link.next;

  cleanup_data.abfd = abfd;
  cleanup_data.link_next = abfd->link.next;

  abfd->link.next = NULL;
  link_info.hash = bfd_link_hash_table_create (abfd);

  cleanups = make_cleanup (link_hash_table_free, &cleanup_data);
  link_info.callbacks = &link_callbacks;

  memset (&link_order, 0, sizeof (link_order));
  link_order.next = NULL;
  link_order.type = bfd_indirect_link_order;
  link_order.offset = 0;
  link_order.size = bfd_get_section_size (sect);
  link_order.u.indirect.section = sect;

  sect_data = xmalloc (bfd_get_section_size (sect));
  make_cleanup (xfree, sect_data);

  sect_data_got = bfd_get_relocated_section_contents (abfd, &link_info,
						      &link_order, sect_data,
						      FALSE, symbol_table);

  if (sect_data_got == NULL)
    error (_("Cannot map compiled module \"%s\" section \"%s\": %s"),
	   bfd_get_filename (abfd), bfd_get_section_name (abfd, sect),
	   bfd_errmsg (bfd_get_error ()));
  gdb_assert (sect_data_got == sect_data);

  inferior_addr = bfd_get_section_vma (abfd, sect);
  if (0 != target_write_memory (inferior_addr, sect_data,
				bfd_get_section_size (sect)))
    error (_("Cannot write compiled module \"%s\" section \"%s\" "
	     "to inferior memory range %s-%s."),
	   bfd_get_filename (abfd), bfd_get_section_name (abfd, sect),
	   paddress (target_gdbarch (), inferior_addr),
	   paddress (target_gdbarch (),
		     inferior_addr + bfd_get_section_size (sect)));

  do_cleanups (cleanups);
}
コード例 #17
0
ファイル: osabi.c プロジェクト: AhmadTux/DragonFlyBSD
void
generic_elf_osabi_sniff_abi_tag_sections (bfd *abfd, asection *sect, void *obj)
{
  enum gdb_osabi *osabi = obj;
  const char *name;
  unsigned int sectsize;
  char *note;

  name = bfd_get_section_name (abfd, sect);
  sectsize = bfd_section_size (abfd, sect);

  /* Limit the amount of data to read.  */
  if (sectsize > MAX_NOTESZ)
    sectsize = MAX_NOTESZ;

  note = alloca (sectsize);
  bfd_get_section_contents (abfd, sect, note, 0, sectsize);

  /* .note.ABI-tag notes, used by GNU/Linux and FreeBSD.  */
  if (strcmp (name, ".note.ABI-tag") == 0)
    {
      /* GNU.  */
      if (check_note (abfd, sect, note, "GNU", 16, NT_GNU_ABI_TAG))
	{
	  unsigned int abi_tag = bfd_h_get_32 (abfd, note + 16);

	  switch (abi_tag)
	    {
	    case GNU_ABI_TAG_LINUX:
	      *osabi = GDB_OSABI_LINUX;
	      break;

	    case GNU_ABI_TAG_HURD:
	      *osabi = GDB_OSABI_HURD;
	      break;

	    case GNU_ABI_TAG_SOLARIS:
	      *osabi = GDB_OSABI_SOLARIS;
	      break;

	    case GNU_ABI_TAG_FREEBSD:
	      *osabi = GDB_OSABI_FREEBSD_ELF;
	      break;

	    case GNU_ABI_TAG_NETBSD:
	      *osabi = GDB_OSABI_NETBSD_ELF;
	      break;

	    default:
	      internal_error (__FILE__, __LINE__,
			      _("generic_elf_osabi_sniff_abi_tag_sections: "
				"unknown OS number %d"),
			      abi_tag);
	    }
	  return;
	}

      /* FreeBSD.  */
      if (check_note (abfd, sect, note, "FreeBSD", 4, NT_FREEBSD_ABI_TAG))
	{
	  /* There is no need to check the version yet.  */
	  *osabi = GDB_OSABI_FREEBSD_ELF;
	  return;
	}

      /* DragonFly.  */
      if (check_note (abfd, sect, note, "DragonFly", 4, NT_DRAGONFLY_ABI_TAG))
	{
	  /* There is no need to check the version yet.  */
	  *osabi = GDB_OSABI_DRAGONFLY;
	  return;
	}

      return;
    }
      
  /* .note.netbsd.ident notes, used by NetBSD.  */
  if (strcmp (name, ".note.netbsd.ident") == 0
      && check_note (abfd, sect, note, "NetBSD", 4, NT_NETBSD_IDENT))
    {
      /* There is no need to check the version yet.  */
      *osabi = GDB_OSABI_NETBSD_ELF;
      return;
    }

  /* .note.openbsd.ident notes, used by OpenBSD.  */
  if (strcmp (name, ".note.openbsd.ident") == 0
      && check_note (abfd, sect, note, "OpenBSD", 4, NT_OPENBSD_IDENT))
    {
      /* There is no need to check the version yet.  */
      *osabi = GDB_OSABI_OPENBSD_ELF;
      return;
    }

  /* .note.netbsdcore.procinfo notes, used by NetBSD.  */
  if (strcmp (name, ".note.netbsdcore.procinfo") == 0)
    {
      *osabi = GDB_OSABI_NETBSD_ELF;
      return;
    }
}
コード例 #18
0
ファイル: eelf64ltsmip.c プロジェクト: VargMon/dd-wrt
static bfd_boolean
gldelf64ltsmip_place_orphan (lang_input_statement_type *file, asection *s)
{
  static struct orphan_save hold_text;
  static struct orphan_save hold_rodata;
  static struct orphan_save hold_data;
  static struct orphan_save hold_bss;
  static struct orphan_save hold_rel;
  static struct orphan_save hold_interp;
  static struct orphan_save hold_sdata;
  static int count = 1;
  struct orphan_save *place;
  lang_statement_list_type *old;
  lang_statement_list_type add;
  etree_type *address;
  const char *secname;
  const char *ps = NULL;
  lang_output_section_statement_type *os;
  lang_statement_union_type **os_tail;
  etree_type *load_base;
  int isdyn = 0;

  secname = bfd_get_section_name (s->owner, s);
  if (! link_info.relocatable
      && link_info.combreloc
      && (s->flags & SEC_ALLOC)
      && strncmp (secname, ".rel", 4) == 0)
    {
      if (secname[4] == 'a')
	secname = ".rela.dyn";
      else
	secname = ".rel.dyn";
      isdyn = 1;
    }

  if (isdyn || (!config.unique_orphan_sections && !unique_section_p (secname)))
    {
      /* Look through the script to see where to place this section.  */
      os = lang_output_section_find (secname);

      if (os != NULL
	  && (os->bfd_section == NULL
	      || ((s->flags ^ os->bfd_section->flags)
		  & (SEC_LOAD | SEC_ALLOC)) == 0))
	{
	  /* We already have an output section statement with this
	     name, and its bfd section, if any, has compatible flags.  */
	  lang_add_section (&os->children, s, os, file);
	  return TRUE;
	}
    }

  if (hold_text.os == NULL)
    hold_text.os = lang_output_section_find (".text");

  /* If this is a final link, then always put .gnu.warning.SYMBOL
     sections into the .text section to get them out of the way.  */
  if (link_info.executable
      && ! link_info.relocatable
      && strncmp (secname, ".gnu.warning.", sizeof ".gnu.warning." - 1) == 0
      && hold_text.os != NULL)
    {
      lang_add_section (&hold_text.os->children, s, hold_text.os, file);
      return TRUE;
    }

  /* Decide which segment the section should go in based on the
     section name and section flags.  We put loadable .note sections
     right after the .interp section, so that the PT_NOTE segment is
     stored right after the program headers where the OS can read it
     in the first page.  */
#define HAVE_SECTION(hold, name) (hold.os != NULL || (hold.os = lang_output_section_find (name)) != NULL)

  if ((s->flags & SEC_EXCLUDE) != 0 && !link_info.relocatable)
    {
      if (s->output_section == NULL)
	s->output_section = bfd_abs_section_ptr;
      return TRUE;
    }

  place = NULL;
  if ((s->flags & SEC_ALLOC) == 0)
    ;
  else if ((s->flags & SEC_LOAD) != 0
	   && strncmp (secname, ".note", 5) == 0
	   && HAVE_SECTION (hold_interp, ".interp"))
    place = &hold_interp;
  else if ((s->flags & SEC_HAS_CONTENTS) == 0
	   && HAVE_SECTION (hold_bss, ".bss"))
    place = &hold_bss;
  else if ((s->flags & SEC_SMALL_DATA) != 0
	   && HAVE_SECTION (hold_sdata, ".sdata"))
    place = &hold_sdata;
  else if ((s->flags & SEC_READONLY) == 0
	   && HAVE_SECTION (hold_data, ".data"))
    place = &hold_data;
  else if (strncmp (secname, ".rel", 4) == 0
	   && (s->flags & SEC_LOAD) != 0
	   && (hold_rel.os != NULL
	       || (hold_rel.os = output_rel_find (s, isdyn)) != NULL))
    place = &hold_rel;
  else if ((s->flags & (SEC_CODE | SEC_READONLY)) == SEC_READONLY
	   && HAVE_SECTION (hold_rodata, ".rodata"))
    place = &hold_rodata;
  else if ((s->flags & (SEC_CODE | SEC_READONLY)) == (SEC_CODE | SEC_READONLY)
	   && hold_text.os != NULL)
    place = &hold_text;

#undef HAVE_SECTION

  /* Choose a unique name for the section.  This will be needed if the
     same section name appears in the input file with different
     loadable or allocatable characteristics.  */
  if (bfd_get_section_by_name (output_bfd, secname) != NULL)
    {
      secname = bfd_get_unique_section_name (output_bfd, secname, &count);
      if (secname == NULL)
	einfo ("%F%P: place_orphan failed: %E\n");
    }

  /* Start building a list of statements for this section.
     First save the current statement pointer.  */
  old = stat_ptr;

  /* If we have found an appropriate place for the output section
     statements for this orphan, add them to our own private list,
     inserting them later into the global statement list.  */
  if (place != NULL)
    {
      stat_ptr = &add;
      lang_list_init (stat_ptr);
    }

  if (config.build_constructors)
    {
      /* If the name of the section is representable in C, then create
	 symbols to mark the start and the end of the section.  */
      for (ps = secname; *ps != '\0'; ps++)
	if (! ISALNUM (*ps) && *ps != '_')
	  break;
      if (*ps == '\0')
	{
	  char *symname;
	  etree_type *e_align;

	  symname = (char *) xmalloc (ps - secname + sizeof "__start_");
	  sprintf (symname, "__start_%s", secname);
	  e_align = exp_unop (ALIGN_K,
			      exp_intop ((bfd_vma) 1 << s->alignment_power));
	  lang_add_assignment (exp_assop ('=', symname, e_align));
	}
    }

  address = NULL;
  if (link_info.relocatable || (s->flags & (SEC_LOAD | SEC_ALLOC)) == 0)
    address = exp_intop ((bfd_vma) 0);

  load_base = NULL;
  if (place != NULL && place->os->load_base != NULL)
    {
      etree_type *lma_from_vma;
      lma_from_vma = exp_binop ('-', place->os->load_base,
				exp_nameop (ADDR, place->os->name));
      load_base = exp_binop ('+', lma_from_vma,
			     exp_nameop (ADDR, secname));
    }

  os_tail = lang_output_section_statement.tail;
  os = lang_enter_output_section_statement (secname, address, 0,
					    (bfd_vma) 0,
					    (etree_type *) NULL,
					    (etree_type *) NULL,
					    load_base);

  lang_add_section (&os->children, s, os, file);

  lang_leave_output_section_statement
    ((bfd_vma) 0, "*default*",
     (struct lang_output_section_phdr_list *) NULL, NULL);

  if (config.build_constructors && *ps == '\0')
    {
      char *symname;

      /* lang_leave_ouput_section_statement resets stat_ptr.  Put
	 stat_ptr back where we want it.  */
      if (place != NULL)
	stat_ptr = &add;

      symname = (char *) xmalloc (ps - secname + sizeof "__stop_");
      sprintf (symname, "__stop_%s", secname);
      lang_add_assignment (exp_assop ('=', symname,
				      exp_nameop (NAME, ".")));
    }

  /* Restore the global list pointer.  */
  stat_ptr = old;

  if (place != NULL && os->bfd_section != NULL)
    {
      asection *snew, **pps;

      snew = os->bfd_section;

      /* Shuffle the bfd section list to make the output file look
	 neater.  This is really only cosmetic.  */
      if (place->section == NULL)
	{
	  asection *bfd_section = place->os->bfd_section;

	  /* If the output statement hasn't been used to place
	     any input sections (and thus doesn't have an output
	     bfd_section), look for the closest prior output statement
	     having an output section.  */
	  if (bfd_section == NULL)
	    bfd_section = output_prev_sec_find (place->os);

	  if (bfd_section != NULL && bfd_section != snew)
	    place->section = &bfd_section->next;
	}

      if (place->section != NULL)
	{
	  /* Unlink the section.  */
	  for (pps = &output_bfd->sections; *pps != snew; pps = &(*pps)->next)
	    ;
	  bfd_section_list_remove (output_bfd, pps);

	  /* Now tack it on to the "place->os" section list.  */
	  bfd_section_list_insert (output_bfd, place->section, snew);
	}

      /* Save the end of this list.  Further ophans of this type will
	 follow the one we've just added.  */
      place->section = &snew->next;

      /* The following is non-cosmetic.  We try to put the output
	 statements in some sort of reasonable order here, because
	 they determine the final load addresses of the orphan
	 sections.  In addition, placing output statements in the
	 wrong order may require extra segments.  For instance,
	 given a typical situation of all read-only sections placed
	 in one segment and following that a segment containing all
	 the read-write sections, we wouldn't want to place an orphan
	 read/write section before or amongst the read-only ones.  */
      if (add.head != NULL)
	{
	  lang_statement_union_type *newly_added_os;

	  if (place->stmt == NULL)
	    {
	      /* Put the new statement list right at the head.  */
	      *add.tail = place->os->header.next;
	      place->os->header.next = add.head;

	      place->os_tail = &place->os->next;
	    }
	  else
	    {
	      /* Put it after the last orphan statement we added.  */
	      *add.tail = *place->stmt;
	      *place->stmt = add.head;
	    }

	  /* Fix the global list pointer if we happened to tack our
	     new list at the tail.  */
	  if (*old->tail == add.head)
	    old->tail = add.tail;

	  /* Save the end of this list.  */
	  place->stmt = add.tail;

	  /* Do the same for the list of output section statements.  */
	  newly_added_os = *os_tail;
	  *os_tail = NULL;
	  newly_added_os->output_section_statement.next = *place->os_tail;
	  *place->os_tail = newly_added_os;
	  place->os_tail = &newly_added_os->output_section_statement.next;

	  /* Fixing the global list pointer here is a little different.
	     We added to the list in lang_enter_output_section_statement,
	     trimmed off the new output_section_statment above when
	     assigning *os_tail = NULL, but possibly added it back in
	     the same place when assigning *place->os_tail.  */
	  if (*os_tail == NULL)
	    lang_output_section_statement.tail = os_tail;
	}
    }

  return TRUE;
}
コード例 #19
0
/* just reloc parts - data comes later */
static void copy_section_relocs_edit (bfd *ibfd, sec_ptr isection, void *obfdarg)
{
    bfd *obfd = obfdarg;
    arelent **relpp;
    long relcount;
    sec_ptr osection;
    bfd_size_type size;
    long relsize;
    flagword flags;


    flags = bfd_get_section_flags (ibfd, isection);
    if ((flags & SEC_GROUP) != 0)
	return;

    osection = isection->output_section;
    size = bfd_get_section_size (isection);

    if (size == 0 || osection == 0)
	return;

    relsize = bfd_get_reloc_upper_bound (ibfd, isection);

    if (relsize <= 0)
    {
	/* not good */
	bfd_perror("attempting to do relocs");
	return;
    }

    relpp = malloc (relsize);

    relcount = bfd_canonicalize_reloc (ibfd, isection, relpp, isympp);

    /* copy each reloc, possibly removing or changing it on the fly */
    arelent **temp_relpp;
    long temp_relcount = 0;
    long i;
    int msg_cnt = 0;
    struct change_reloc_struct *change_ptr;
    struct add_reloc_struct *new_reloc;
    asymbol **osympp;

    /* count new relocs to allocate space in reloc list */
    int reloc_add_cnt;
    reloc_add_cnt = 0;
    for (new_reloc = additional_relocs; new_reloc != NULL; new_reloc = new_reloc->next) {
	reloc_add_cnt++;
    }

    osympp = bfd_get_outsymbols(obfd);

    /* note: cannot run mprobe on osympp b/c the copy contents will sometimes realloc it from internal BFD storage */

    temp_relpp = malloc (relsize + reloc_add_cnt * sizeof(arelent *));
    for (i = 0; i < relcount; i++) {

	if (is_delete_reloc(bfd_asymbol_name(*relpp[i]->sym_ptr_ptr), delete_relocs)) {
	    continue;
	}
	else if ((change_ptr = find_change_reloc(bfd_asymbol_name(*relpp[i]->sym_ptr_ptr), change_relocs)) != NULL) {
	    int sym_idx;
	    sym_idx = find_symbol(osympp, change_ptr->new_symbol_name);
	    if (sym_idx < 0) {
		fprintf(stderr, "internal error: could not find new symbol %s in output symbol table\n", change_ptr->new_symbol_name);
		exit(1);
	    }
	    relpp[i]->sym_ptr_ptr = &(osympp[sym_idx]);
	}
	temp_relpp [temp_relcount++] = relpp [i];
    }

    /* now the additional relocs from the command line */
    if (strcmp(bfd_get_section_name(ibfd, isection), ".text") == 0) {
	add_reloc_struct *add_reloc;
	for (add_reloc = additional_relocs; add_reloc != NULL; add_reloc = add_reloc->next) {
	    arelent *new_reloc;
	    int symbol_idx;

	    new_reloc = malloc(sizeof(*new_reloc));
	    if ((symbol_idx = find_symbol(osympp, add_reloc->symbol_name)) < 0) {
		fprintf(stderr, "could not find symbol %s to perform a relocation! possible internal error\n", add_reloc->symbol_name);
		continue;
	    }
	    new_reloc->sym_ptr_ptr = &osympp[symbol_idx];
	    new_reloc->address = add_reloc->loc;
	    new_reloc->addend = 0;   /* never seemed to be used in my cursory investigation */
	    new_reloc->howto = bfd_reloc_type_lookup(ibfd, BFD_RELOC_32_PCREL);
	    if (new_reloc->howto == NULL) {
		fprintf(stderr, "could not get howto back from bfd subsystem\n");
		exit(1);
	    }

	    temp_relpp[temp_relcount++] = new_reloc;
	}
    }
    temp_relpp[temp_relcount] = NULL;

    relcount = temp_relcount;
    free (relpp);
    relpp = temp_relpp;

    bfd_set_reloc (obfd, osection, relcount == 0 ? NULL : relpp, relcount);
    if (relcount == 0)
	free (relpp);

    mcheck_check_all();

}
コード例 #20
0
/* the finishing piece for each section */
static void copy_section_data (bfd *ibfd, sec_ptr isection, void *obfdarg)
{
    bfd *obfd = obfdarg;
    sec_ptr osection;
    bfd_size_type size;
    struct add_reloc_struct *new_reloc;

    size = bfd_get_section_size (isection);

    osection = isection->output_section;

    if (size == 0 || osection == 0)
	return;

    if (bfd_get_section_flags (ibfd, isection) & SEC_HAS_CONTENTS
	&& bfd_get_section_flags (obfd, osection) & SEC_HAS_CONTENTS) {

	void *memhunk;

	mcheck_check_all();

	memhunk = malloc (size);

	if (!bfd_get_section_contents (ibfd, isection, memhunk, 0, size))
	    return;

	if (strcmp(bfd_get_section_name(ibfd, isection), ".text") == 0) {

	    /* make the data modifications, if requested */
	    modify_byte_struct *mbyte_ptr = modify_bytes;
	    while (mbyte_ptr != NULL) {
		((unsigned char *)memhunk)[mbyte_ptr->location] = (char)(mbyte_ptr->value & 0xff);
		mbyte_ptr = mbyte_ptr->next;
	    }

	    /* make sure additional relocs have proper data present */
	    /* kernel implements relocs relative to what's already there in the data! */
	    /* so if we're overriding a call, we need to set the old PC-relative data back to 0xfffffffc */
	    for (new_reloc = additional_relocs; new_reloc != NULL; new_reloc = new_reloc->next) {
		((unsigned char *)memhunk)[new_reloc->loc]   = (unsigned char)0xfc;
		((unsigned char *)memhunk)[new_reloc->loc+1] = (unsigned char)0xff;
		((unsigned char *)memhunk)[new_reloc->loc+2] = (unsigned char)0xff;
		((unsigned char *)memhunk)[new_reloc->loc+3] = (unsigned char)0xff;
	    }
	}

	if (!bfd_set_section_contents (obfd, osection, memhunk, 0, size))
	    return;

	/* note that bfd_set_section_contents will render the symbol table noncanonical */
	/* (the array will not be NULL terminated) */

	free (memhunk);
    }
    else if (!(bfd_get_section_flags (ibfd, isection) & SEC_HAS_CONTENTS)) {
	fprintf(stderr, "not copying input section %s because flags %x do not indicate contents (%x)\n",
	       isection->name,
	       bfd_get_section_flags (ibfd, isection),
	       SEC_HAS_CONTENTS);
    }
    else {
	fprintf(stderr, "not copying output section %s because flags %x do not indicate contents (%x)\n",
	       osection->name,
	       bfd_get_section_flags (obfd, osection),
	       SEC_HAS_CONTENTS);
    }
}
コード例 #21
0
static void
obj_coff_endef (int ignore ATTRIBUTE_UNUSED)
{
  symbolS *symbolP = NULL;

  dim_index = 0;
  if (def_symbol_in_progress == NULL)
    {
      as_warn (_(".endef pseudo-op used outside of .def/.endef: ignored."));
      demand_empty_rest_of_line ();
      return;
    }

  /* Set the section number according to storage class.  */
  switch (S_GET_STORAGE_CLASS (def_symbol_in_progress))
    {
    case C_STRTAG:
    case C_ENTAG:
    case C_UNTAG:
      SF_SET_TAG (def_symbol_in_progress);
      /* Fall through.  */
    case C_FILE:
    case C_TPDEF:
      SF_SET_DEBUG (def_symbol_in_progress);
      S_SET_SEGMENT (def_symbol_in_progress, fetch_coff_debug_section ());
      break;

    case C_EFCN:
      SF_SET_LOCAL (def_symbol_in_progress);	/* Do not emit this symbol.  */
      /* Fall through.  */
    case C_BLOCK:
      SF_SET_PROCESS (def_symbol_in_progress);	/* Will need processing before writing.  */
      /* Fall through.  */
    case C_FCN:
      {
	const char *name;

	S_SET_SEGMENT (def_symbol_in_progress, text_section);

	name = S_GET_NAME (def_symbol_in_progress);
	if (name[0] == '.' && name[2] == 'f' && name[3] == '\0')
	  {
	    switch (name[1])
	      {
	      case 'b':
		/* .bf */
		if (! in_function ())
		  as_warn (_("`%s' symbol without preceding function"), name);
		/* Will need relocating.  */
		SF_SET_PROCESS (def_symbol_in_progress);
		clear_function ();
		break;
#ifdef TE_PE
	      case 'e':
		/* .ef */
		/* The MS compilers output the actual endline, not the
		   function-relative one... we want to match without
		   changing the assembler input.  */
		SA_SET_SYM_LNNO (def_symbol_in_progress,
				 (SA_GET_SYM_LNNO (def_symbol_in_progress)
				  + coff_line_base));
		break;
#endif
	      }
	  }
      }
      break;

#ifdef C_AUTOARG
    case C_AUTOARG:
#endif /* C_AUTOARG */
    case C_AUTO:
    case C_REG:
    case C_ARG:
    case C_REGPARM:
    case C_FIELD:

    /* According to the COFF documentation:

       http://osr5doc.sco.com:1996/topics/COFF_SectNumFld.html

       A special section number (-2) marks symbolic debugging symbols,
       including structure/union/enumeration tag names, typedefs, and
       the name of the file. A section number of -1 indicates that the
       symbol has a value but is not relocatable. Examples of
       absolute-valued symbols include automatic and register variables,
       function arguments, and .eos symbols.

       But from Ian Lance Taylor:

       http://sources.redhat.com/ml/binutils/2000-08/msg00202.html

       the actual tools all marked them as section -1. So the GNU COFF
       assembler follows historical COFF assemblers.

       However, it causes problems for djgpp

       http://sources.redhat.com/ml/binutils/2000-08/msg00210.html

       By defining STRICTCOFF, a COFF port can make the assembler to
       follow the documented behavior.  */
#ifdef STRICTCOFF
    case C_MOS:
    case C_MOE:
    case C_MOU:
    case C_EOS:
#endif
      SF_SET_DEBUG (def_symbol_in_progress);
      S_SET_SEGMENT (def_symbol_in_progress, absolute_section);
      break;

#ifndef STRICTCOFF
    case C_MOS:
    case C_MOE:
    case C_MOU:
    case C_EOS:
      S_SET_SEGMENT (def_symbol_in_progress, absolute_section);
      break;
#endif

    case C_EXT:
    case C_WEAKEXT:
#ifdef TE_PE
    case C_NT_WEAK:
#endif
    case C_STAT:
    case C_LABEL:
      /* Valid but set somewhere else (s_comm, s_lcomm, colon).  */
      break;

    default:
    case C_USTATIC:
    case C_EXTDEF:
    case C_ULABEL:
      as_warn (_("unexpected storage class %d"),
	       S_GET_STORAGE_CLASS (def_symbol_in_progress));
      break;
    }

  /* Now that we have built a debug symbol, try to find if we should
     merge with an existing symbol or not.  If a symbol is C_EFCN or
     absolute_section or untagged SEG_DEBUG it never merges.  We also
     don't merge labels, which are in a different namespace, nor
     symbols which have not yet been defined since they are typically
     unique, nor do we merge tags with non-tags.  */

  /* Two cases for functions.  Either debug followed by definition or
     definition followed by debug.  For definition first, we will
     merge the debug symbol into the definition.  For debug first, the
     lineno entry MUST point to the definition function or else it
     will point off into space when obj_crawl_symbol_chain() merges
     the debug symbol into the real symbol.  Therefor, let's presume
     the debug symbol is a real function reference.  */

  /* FIXME-SOON If for some reason the definition label/symbol is
     never seen, this will probably leave an undefined symbol at link
     time.  */

  if (S_GET_STORAGE_CLASS (def_symbol_in_progress) == C_EFCN
      || S_GET_STORAGE_CLASS (def_symbol_in_progress) == C_LABEL
      || (streq (bfd_get_section_name (stdoutput,
				       S_GET_SEGMENT (def_symbol_in_progress)),
		 "*DEBUG*")
	  && !SF_GET_TAG (def_symbol_in_progress))
      || S_GET_SEGMENT (def_symbol_in_progress) == absolute_section
      || ! symbol_constant_p (def_symbol_in_progress)
      || (symbolP = symbol_find (S_GET_NAME (def_symbol_in_progress))) == NULL
      || SF_GET_TAG (def_symbol_in_progress) != SF_GET_TAG (symbolP))
    {
      /* If it already is at the end of the symbol list, do nothing */
      if (def_symbol_in_progress != symbol_lastP)
	{
	  symbol_remove (def_symbol_in_progress, &symbol_rootP, &symbol_lastP);
	  symbol_append (def_symbol_in_progress, symbol_lastP, &symbol_rootP,
			 &symbol_lastP);
	}
    }
  else
    {
      /* This symbol already exists, merge the newly created symbol
	 into the old one.  This is not mandatory. The linker can
	 handle duplicate symbols correctly. But I guess that it save
	 a *lot* of space if the assembly file defines a lot of
	 symbols. [loic]  */

      /* The debug entry (def_symbol_in_progress) is merged into the
	 previous definition.  */

      c_symbol_merge (def_symbol_in_progress, symbolP);
      symbol_remove (def_symbol_in_progress, &symbol_rootP, &symbol_lastP);

      def_symbol_in_progress = symbolP;

      if (SF_GET_FUNCTION (def_symbol_in_progress)
	  || SF_GET_TAG (def_symbol_in_progress)
	  || S_GET_STORAGE_CLASS (def_symbol_in_progress) == C_STAT)
	{
	  /* For functions, and tags, and static symbols, the symbol
	     *must* be where the debug symbol appears.  Move the
	     existing symbol to the current place.  */
	  /* If it already is at the end of the symbol list, do nothing.  */
	  if (def_symbol_in_progress != symbol_lastP)
	    {
	      symbol_remove (def_symbol_in_progress, &symbol_rootP, &symbol_lastP);
	      symbol_append (def_symbol_in_progress, symbol_lastP, &symbol_rootP, &symbol_lastP);
	    }
	}
    }

  if (SF_GET_TAG (def_symbol_in_progress))
    {
      symbolS *oldtag;

      oldtag = symbol_find (S_GET_NAME (def_symbol_in_progress));
      if (oldtag == NULL || ! SF_GET_TAG (oldtag))
	tag_insert (S_GET_NAME (def_symbol_in_progress),
		    def_symbol_in_progress);
    }

  if (SF_GET_FUNCTION (def_symbol_in_progress))
    {
      know (sizeof (def_symbol_in_progress) <= sizeof (long));
      set_function (def_symbol_in_progress);
      SF_SET_PROCESS (def_symbol_in_progress);

      if (symbolP == NULL)
	/* That is, if this is the first time we've seen the
	   function.  */
	symbol_table_insert (def_symbol_in_progress);

    }

  def_symbol_in_progress = NULL;
  demand_empty_rest_of_line ();
}
コード例 #22
0
static void
aix5_relocate_main_executable (void)
{
  struct so_list *so;
  struct section_offsets *new_offsets;
  int i;
  int changed = 0;
  struct cleanup *old_chain = make_cleanup (null_cleanup, 0);

  /* Fetch the mappings for the main executable from the map file.  */
  so = build_so_list_from_mapfile (PIDGET (inferior_ptid),
                                   MA_MAINEXEC, MA_MAINEXEC);

  /* Make sure we actually have some mappings to work with.  */
  if (so == NULL)
    {
      warning (_("Could not find main executable in map file"));
      do_cleanups (old_chain);
      return;
    }

  /* Allocate the data structure which'll contain the new offsets to
     relocate by.  Initialize it so it contains the current offsets.  */
  new_offsets = xcalloc (symfile_objfile->num_sections,
			 sizeof (struct section_offsets));
  make_cleanup (xfree, new_offsets);
  for (i = 0; i < symfile_objfile->num_sections; i++)
    new_offsets->offsets[i] = ANOFFSET (symfile_objfile->section_offsets, i);

  /* Iterate over the mappings in the main executable and compute
     the new offset value as appropriate.  */
  for (i = 0; i < so->lm_info->nmappings; i++)
    {
      CORE_ADDR increment = 0;
      struct obj_section *sect;
      bfd *obfd = symfile_objfile->obfd;
      struct lm_mapping *mapping = &so->lm_info->mapping[i];

      ALL_OBJFILE_OSECTIONS (symfile_objfile, sect)
	{
	  int flags = bfd_get_section_flags (obfd, sect->the_bfd_section);
	  if (flags & SEC_ALLOC)
	    {
	      file_ptr filepos = sect->the_bfd_section->filepos;
	      if (map_index_vs_section_name_okay (i,
		    bfd_get_section_name (obfd, sect->the_bfd_section)))
		{
		  int idx = sect->the_bfd_section->index;

		  if (increment == 0)
		    increment = mapping->addr
		      - (bfd_section_vma (obfd, sect->the_bfd_section) 
		         & SECTMAPMASK);

		  if (increment != ANOFFSET (new_offsets, idx))
		    {
		      new_offsets->offsets[idx] = increment;
		      changed = 1;
		    }
		}
	    }
	}
    }
コード例 #23
0
ファイル: sparcl-tdep.c プロジェクト: jichu4n/prc-tools-remix
static void
download (char *target_name, char *args, int from_tty,
	  void (*write_routine) (bfd *from_bfd, asection *from_sec,
				 file_ptr from_addr, bfd_vma to_addr, int len),
	  void (*start_routine) (bfd_vma entry))
{
  struct cleanup *old_chain;
  asection *section;
  bfd *pbfd;
  bfd_vma entry;
  int i;
#define WRITESIZE 1024
  char *filename;
  int quiet;
  int nostart;

  quiet = 0;
  nostart = 0;
  filename = NULL;

  while (*args != '\000')
    {
      char *arg;

      while (isspace (*args))
	args++;

      arg = args;

      while ((*args != '\000') && !isspace (*args))
	args++;

      if (*args != '\000')
	*args++ = '\000';

      if (*arg != '-')
	filename = arg;
      else if (strncmp (arg, "-quiet", strlen (arg)) == 0)
	quiet = 1;
      else if (strncmp (arg, "-nostart", strlen (arg)) == 0)
	nostart = 1;
      else
	error ("unknown option `%s'", arg);
    }

  if (!filename)
    filename = get_exec_file (1);

  pbfd = bfd_openr (filename, gnutarget);
  if (pbfd == NULL)
    {
      perror_with_name (filename);
      return;
    }
  old_chain = make_cleanup_bfd_close (pbfd);

  if (!bfd_check_format (pbfd, bfd_object))
    error ("\"%s\" is not an object file: %s", filename,
	   bfd_errmsg (bfd_get_error ()));

  for (section = pbfd->sections; section; section = section->next)
    {
      if (bfd_get_section_flags (pbfd, section) & SEC_LOAD)
	{
	  bfd_vma section_address;
	  bfd_size_type section_size;
	  file_ptr fptr;
	  const char *section_name;

	  section_name = bfd_get_section_name (pbfd, section);

	  section_address = bfd_get_section_vma (pbfd, section);

	  /* Adjust sections from a.out files, since they don't
	     carry their addresses with.  */
	  if (bfd_get_flavour (pbfd) == bfd_target_aout_flavour)
	    {
	      if (strcmp (section_name, ".text") == 0)
		section_address = bfd_get_start_address (pbfd);
	      else if (strcmp (section_name, ".data") == 0)
		{
		  /* Read the first 8 bytes of the data section.
		     There should be the string 'DaTa' followed by
		     a word containing the actual section address. */
		  struct data_marker
		    {
		      char signature[4];	/* 'DaTa' */
		      unsigned char sdata[4];	/* &sdata */
		    }
		  marker;
		  bfd_get_section_contents (pbfd, section, &marker, 0,
					    sizeof (marker));
		  if (strncmp (marker.signature, "DaTa", 4) == 0)
		    {
		      if (TARGET_BYTE_ORDER == BFD_ENDIAN_BIG)
			section_address = bfd_getb32 (marker.sdata);
		      else
			section_address = bfd_getl32 (marker.sdata);
		    }
		}
	    }

	  section_size = bfd_get_section_size_before_reloc (section);

	  if (!quiet)
	    printf_filtered ("[Loading section %s at 0x%x (%d bytes)]\n",
			     bfd_get_section_name (pbfd, section),
			     section_address,
			     section_size);

	  fptr = 0;
	  while (section_size > 0)
	    {
	      int count;
	      static char inds[] = "|/-\\";
	      static int k = 0;

	      QUIT;

	      count = min (section_size, WRITESIZE);

	      write_routine (pbfd, section, fptr, section_address, count);

	      if (!quiet)
		{
		  printf_unfiltered ("\r%c", inds[k++ % 4]);
		  gdb_flush (gdb_stdout);
		}

	      section_address += count;
	      fptr += count;
	      section_size -= count;
	    }
	}
    }

  if (!nostart)
    {
      entry = bfd_get_start_address (pbfd);

      if (!quiet)
	printf_unfiltered ("[Starting %s at 0x%x]\n", filename, entry);

      start_routine (entry);
    }

  do_cleanups (old_chain);
}
コード例 #24
0
ファイル: osabi.c プロジェクト: jichu4n/prc-tools-remix
void
generic_elf_osabi_sniff_abi_tag_sections (bfd *abfd, asection *sect, void *obj)
{
  enum gdb_osabi *os_ident_ptr = obj;
  const char *name;
  unsigned int sectsize;

  name = bfd_get_section_name (abfd, sect);
  sectsize = bfd_section_size (abfd, sect);

  /* .note.ABI-tag notes, used by GNU/Linux and FreeBSD.  */
  if (strcmp (name, ".note.ABI-tag") == 0 && sectsize > 0)
    {
      unsigned int name_length, data_length, note_type;
      char *note;

      /* If the section is larger than this, it's probably not what we are
	 looking for.  */
      if (sectsize > 128)
	sectsize = 128;

      note = alloca (sectsize);

      bfd_get_section_contents (abfd, sect, note,
				(file_ptr) 0, (bfd_size_type) sectsize);

      name_length = bfd_h_get_32 (abfd, note);
      data_length = bfd_h_get_32 (abfd, note + 4);
      note_type   = bfd_h_get_32 (abfd, note + 8);

      if (name_length == 4 && data_length == 16 && note_type == NT_GNU_ABI_TAG
	  && strcmp (note + 12, "GNU") == 0)
	{
	  int os_number = bfd_h_get_32 (abfd, note + 16);

	  switch (os_number)
	    {
	    case GNU_ABI_TAG_LINUX:
	      *os_ident_ptr = GDB_OSABI_LINUX;
	      break;

	    case GNU_ABI_TAG_HURD:
	      *os_ident_ptr = GDB_OSABI_HURD;
	      break;

	    case GNU_ABI_TAG_SOLARIS:
	      *os_ident_ptr = GDB_OSABI_SOLARIS;
	      break;

	    default:
	      internal_error
		(__FILE__, __LINE__,
		 "generic_elf_osabi_sniff_abi_tag_sections: unknown OS number %d",
		 os_number);
	    }
	  return;
	}
      else if (name_length == 8 && data_length == 4
	       && note_type == NT_FREEBSD_ABI_TAG
	       && strcmp (note + 12, "FreeBSD") == 0)
	{
	  /* XXX Should we check the version here?  Probably not
	     necessary yet.  */
	  *os_ident_ptr = GDB_OSABI_FREEBSD_ELF;
	}
      return;
    }

  /* .note.netbsd.ident notes, used by NetBSD.  */
  if (strcmp (name, ".note.netbsd.ident") == 0 && sectsize > 0)
    {
      unsigned int name_length, data_length, note_type;
      char *note;

      /* If the section is larger than this, it's probably not what we are
	 looking for.  */
      if (sectsize > 128) 
	sectsize = 128;

      note = alloca (sectsize);

      bfd_get_section_contents (abfd, sect, note,
				(file_ptr) 0, (bfd_size_type) sectsize);
      
      name_length = bfd_h_get_32 (abfd, note);
      data_length = bfd_h_get_32 (abfd, note + 4);
      note_type   = bfd_h_get_32 (abfd, note + 8);

      if (name_length == 7 && data_length == 4 && note_type == NT_NETBSD_IDENT
	  && strcmp (note + 12, "NetBSD") == 0)
	{
	  /* XXX Should we check the version here?  Probably not
	     necessary yet.  */
	  *os_ident_ptr = GDB_OSABI_NETBSD_ELF;
	}
      return;
    }
}
コード例 #25
0
static void
setup_sections (bfd *abfd, asection *sect, void *data_voidp)
{
  struct setup_sections_data *data = data_voidp;
  CORE_ADDR alignment;
  unsigned prot;

  if (sect != NULL)
    {
      /* It is required by later bfd_get_relocated_section_contents.  */
      if (sect->output_section == NULL)
	sect->output_section = sect;

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

      /* Make the memory always readable.  */
      prot = GDB_MMAP_PROT_READ;
      if ((bfd_get_section_flags (abfd, sect) & SEC_READONLY) == 0)
	prot |= GDB_MMAP_PROT_WRITE;
      if ((bfd_get_section_flags (abfd, sect) & SEC_CODE) != 0)
	prot |= GDB_MMAP_PROT_EXEC;

      if (compile_debug)
	fprintf_unfiltered (gdb_stdlog,
			    "module \"%s\" section \"%s\" size %s prot %u\n",
			    bfd_get_filename (abfd),
			    bfd_get_section_name (abfd, sect),
			    paddress (target_gdbarch (),
				      bfd_get_section_size (sect)),
			    prot);
    }
  else
    prot = -1;

  if (sect == NULL
      || (data->last_prot != prot && bfd_get_section_size (sect) != 0))
    {
      CORE_ADDR addr;
      asection *sect_iter;

      if (data->last_size != 0)
	{
	  addr = gdbarch_infcall_mmap (target_gdbarch (), data->last_size,
				       data->last_prot);
	  munmap_list_add (data->munmap_list_headp, addr, data->last_size);
	  if (compile_debug)
	    fprintf_unfiltered (gdb_stdlog,
				"allocated %s bytes at %s prot %u\n",
				paddress (target_gdbarch (), data->last_size),
				paddress (target_gdbarch (), addr),
				data->last_prot);
	}
      else
	addr = 0;

      if ((addr & (data->last_max_alignment - 1)) != 0)
	error (_("Inferior compiled module address %s "
		 "is not aligned to BFD required %s."),
	       paddress (target_gdbarch (), addr),
	       paddress (target_gdbarch (), data->last_max_alignment));

      for (sect_iter = data->last_section_first; sect_iter != sect;
	   sect_iter = sect_iter->next)
	if ((bfd_get_section_flags (abfd, sect_iter) & SEC_ALLOC) != 0)
	  bfd_set_section_vma (abfd, sect_iter,
			       addr + bfd_get_section_vma (abfd, sect_iter));

      data->last_size = 0;
      data->last_section_first = sect;
      data->last_prot = prot;
      data->last_max_alignment = 1;
    }

  if (sect == NULL)
    return;

  alignment = ((CORE_ADDR) 1) << bfd_get_section_alignment (abfd, sect);
  data->last_max_alignment = max (data->last_max_alignment, alignment);

  data->last_size = (data->last_size + alignment - 1) & -alignment;

  bfd_set_section_vma (abfd, sect, data->last_size);

  data->last_size += bfd_get_section_size (sect);
  data->last_size = (data->last_size + alignment - 1) & -alignment;
}
コード例 #26
0
ファイル: hw_init.c プロジェクト: jichu4n/prc-tools-remix
static void
update_for_binary_section(bfd *abfd,
			  asection *the_section,
			  PTR obj)
{
  unsigned_word section_vma;
  unsigned_word section_size;
  access_type access;
  device *me = (device*)obj;

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

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

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

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

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

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

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

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

  /* if a load dma in the required data */
  if (bfd_get_section_flags(abfd, the_section) & SEC_LOAD) {
    void *section_init = zalloc(section_size);
    if (!bfd_get_section_contents(abfd,
				  the_section,
				  section_init, 0,
				  section_size)) {
      bfd_perror("binary");
      device_error(me, "load of data failed");
      return;
    }
    if (device_dma_write_buffer(device_parent(me),
				section_init,
				0 /*space*/,
				section_vma,
				section_size,
				1 /*violate_read_only*/)
	!= section_size)
      device_error(me, "broken transfer\n");
    zfree(section_init); /* only free if load */
  }
}
コード例 #27
0
void
m32c_load (bfd * prog)
{
  asection *s;
  unsigned long mach = bfd_get_mach (prog);
  unsigned long highest_addr_loaded = 0;

  if (mach == 0 && default_machine != 0)
    mach = default_machine;

  m32c_set_mach (mach);

  for (s = prog->sections; s; s = s->next)
    {
#if 0
      /* This was a good idea until we started storing the RAM data in
         ROM, at which point everything was all messed up.  The code
         remains as a reminder.  */
      if ((s->flags & SEC_ALLOC) && !(s->flags & SEC_READONLY))
	{
	  if (strcmp (bfd_get_section_name (prog, s), ".stack"))
	    {
	      int secend =
		bfd_get_section_size (s) + bfd_section_lma (prog, s);
	      if (heaptop < secend && bfd_section_lma (prog, s) < 0x10000)
		{
		  heaptop = heapbottom = secend;
		}
	    }
	}
#endif
      if (s->flags & SEC_LOAD)
	{
	  char *buf;
	  bfd_size_type size;

	  size = bfd_get_section_size (s);
	  if (size <= 0)
	    continue;

	  bfd_vma base = bfd_section_lma (prog, s);
	  if (verbose)
	    fprintf (stderr, "[load a=%08x s=%08x %s]\n",
		     (int) base, (int) size, bfd_get_section_name (prog, s));
	  buf = (char *) malloc (size);
	  bfd_get_section_contents (prog, s, buf, 0, size);
	  mem_put_blk (base, buf, size);
	  free (buf);
	  if (highest_addr_loaded < base + size - 1 && size >= 4)
	    highest_addr_loaded = base + size - 1;
	}
    }

  if (strcmp (bfd_get_target (prog), "srec") == 0)
    {
      heaptop = heapbottom = 0;
      switch (mach)
	{
	case bfd_mach_m16c:
	  if (highest_addr_loaded > 0x10000)
	    regs.r_pc = mem_get_si (0x000ffffc) & membus_mask;
	  else
	    regs.r_pc = mem_get_si (0x000fffc) & membus_mask;
	  break;
	case bfd_mach_m32c:
	  regs.r_pc = mem_get_si (0x00fffffc) & membus_mask;
	  break;
	}
    }
  else
    regs.r_pc = prog->start_address;
  if (verbose)
    fprintf (stderr, "[start pc=%08x]\n", (unsigned int) regs.r_pc);
}
コード例 #28
0
ファイル: osabi.c プロジェクト: atgreen/binutils-gdb
void
generic_elf_osabi_sniff_abi_tag_sections (bfd *abfd, asection *sect, void *obj)
{
  enum gdb_osabi *osabi = obj;
  const char *name;
  unsigned int sectsize;
  char *note;

  name = bfd_get_section_name (abfd, sect);
  sectsize = bfd_section_size (abfd, sect);

  /* Limit the amount of data to read.  */
  if (sectsize > MAX_NOTESZ)
    sectsize = MAX_NOTESZ;

  /* We lazily read the section data here.  Since we use
     BFD_DECOMPRESS, we can't use bfd_get_section_contents on a
     compressed section.  But, since note sections are not compressed,
     deferring the reading until we recognize the section avoids any
     error.  */
  note = alloca (sectsize);

  /* .note.ABI-tag notes, used by GNU/Linux and FreeBSD.  */
  if (strcmp (name, ".note.ABI-tag") == 0)
    {
      /* GNU.  */
      if (check_note (abfd, sect, note, &sectsize, "GNU", 16, NT_GNU_ABI_TAG))
	{
	  unsigned int abi_tag = bfd_h_get_32 (abfd, note + 16);

	  switch (abi_tag)
	    {
	    case GNU_ABI_TAG_LINUX:
	      *osabi = GDB_OSABI_LINUX;
	      break;

	    case GNU_ABI_TAG_HURD:
	      *osabi = GDB_OSABI_HURD;
	      break;

	    case GNU_ABI_TAG_SOLARIS:
	      *osabi = GDB_OSABI_SOLARIS;
	      break;

	    case GNU_ABI_TAG_FREEBSD:
	      *osabi = GDB_OSABI_FREEBSD_ELF;
	      break;

	    case GNU_ABI_TAG_NETBSD:
	      *osabi = GDB_OSABI_NETBSD_ELF;
	      break;

	    default:
	      internal_error (__FILE__, __LINE__,
			      _("generic_elf_osabi_sniff_abi_tag_sections: "
				"unknown OS number %d"),
			      abi_tag);
	    }
	  return;
	}

      /* FreeBSD.  */
      if (check_note (abfd, sect, note, &sectsize, "FreeBSD", 4,
		      NT_FREEBSD_ABI_TAG))
	{
	  /* There is no need to check the version yet.  */
	  *osabi = GDB_OSABI_FREEBSD_ELF;
	  return;
	}

      return;
    }
      
  /* .note.netbsd.ident notes, used by NetBSD.  */
  if (strcmp (name, ".note.netbsd.ident") == 0
      && check_note (abfd, sect, note, &sectsize, "NetBSD", 4, NT_NETBSD_IDENT))
    {
      /* There is no need to check the version yet.  */
      *osabi = GDB_OSABI_NETBSD_ELF;
      return;
    }

  /* .note.openbsd.ident notes, used by OpenBSD.  */
  if (strcmp (name, ".note.openbsd.ident") == 0
      && check_note (abfd, sect, note, &sectsize, "OpenBSD", 4,
		     NT_OPENBSD_IDENT))
    {
      /* There is no need to check the version yet.  */
      *osabi = GDB_OSABI_OPENBSD_ELF;
      return;
    }

  /* .note.netbsdcore.procinfo notes, used by NetBSD.  */
  if (strcmp (name, ".note.netbsdcore.procinfo") == 0)
    {
      *osabi = GDB_OSABI_NETBSD_ELF;
      return;
    }
}
コード例 #29
0
ファイル: elf_bfd.c プロジェクト: mammon/mammon.github.com
//callback, ripped from objdump...
static void hdr_summary(bfd *abfd, asection *section, PTR jnk)
{
	  printf ("%3d %-13s %08lx %08lx  \n", section->index,
             bfd_get_section_name (abfd, section), section->vma,
             (unsigned long) bfd_section_size(abfd, section));
}