Пример #1
0
static void
bfdsec_to_vmap (struct bfd *abfd, struct bfd_section *sect, void *arg3)
{
  struct vmap_and_bfd *vmap_bfd = (struct vmap_and_bfd *) arg3;
  struct vmap *vp;

  vp = vmap_bfd->pvmap;

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

  if (strcmp (bfd_section_name (abfd, sect), ".text") == 0)
    {
      vp->tstart = bfd_section_vma (abfd, sect);
      vp->tend = vp->tstart + bfd_section_size (abfd, sect);
      vp->tvma = bfd_section_vma (abfd, sect);
      vp->toffs = sect->filepos;
    }
  else if (strcmp (bfd_section_name (abfd, sect), ".data") == 0)
    {
      vp->dstart = bfd_section_vma (abfd, sect);
      vp->dend = vp->dstart + bfd_section_size (abfd, sect);
      vp->dvma = bfd_section_vma (abfd, sect);
    }
  /* Silently ignore other types of sections. (FIXME?)  */
}
static void
add_to_thread_list (bfd *abfd, asection *asect, void *reg_sect_arg)
{
  ptid_t ptid;
  int core_tid;
  int pid, lwpid;
  asection *reg_sect = (asection *) reg_sect_arg;

  if (strncmp (bfd_section_name (abfd, asect), ".reg/", 5) != 0)
    return;

  core_tid = atoi (bfd_section_name (abfd, asect) + 5);

  if (core_gdbarch
      && gdbarch_core_reg_section_encodes_pid (core_gdbarch))
    {
      uint32_t merged_pid = core_tid;
      pid = merged_pid & 0xffff;
      lwpid = merged_pid >> 16;

      /* This can happen on solaris core, for example, if we don't
	 find a NT_PSTATUS note in the core, but do find NT_LWPSTATUS
	 notes.  */
      if (pid == 0)
	{
	  core_has_fake_pid = 1;
	  pid = CORELOW_PID;
	}
    }
Пример #3
0
static void
add_to_thread_list (bfd *abfd, asection *asect, void *reg_sect_arg)
{
  ptid_t ptid;
  int core_tid;
  int pid, lwpid;
  asection *reg_sect = (asection *) reg_sect_arg;

  if (strncmp (bfd_section_name (abfd, asect), ".reg/", 5) != 0)
    return;

  core_tid = atoi (bfd_section_name (abfd, asect) + 5);

  pid = bfd_core_file_pid (core_bfd);
  if (pid == 0)
    {
      core_has_fake_pid = 1;
      pid = CORELOW_PID;
    }

  lwpid = core_tid;

  if (current_inferior ()->pid == 0)
    inferior_appeared (current_inferior (), pid);

  ptid = ptid_build (pid, lwpid, 0);

  add_thread (ptid);

/* Warning, Will Robinson, looking at BFD private data! */

  if (reg_sect != NULL
      && asect->filepos == reg_sect->filepos)	/* Did we find .reg?  */
    inferior_ptid = ptid;			/* Yes, make it current.  */
}
Пример #4
0
static void
fbsd_core_get_first_lwp (bfd *abfd, asection *asect, void *obj)
{
  if (strncmp (bfd_section_name (abfd, asect), ".reg/", 5) != 0)
    return;

  if (*(lwpid_t *)obj != 0)
    return;

  *(lwpid_t *)obj = atoi (bfd_section_name (abfd, asect) + 5);
}
Пример #5
0
static void
nbsd_add_to_thread_list (bfd *abfd, asection *asect, PTR reg_sect_arg)
{
  int regval;
  td_thread_t *dummy;

  if (strncmp (bfd_section_name (abfd, asect), ".reg/", 5) != 0)
    return;

  regval = atoi (bfd_section_name (abfd, asect) + 5);

  add_thread (ptid_build (ptid_get_pid (main_ptid), regval, 0));
}
Пример #6
0
static void
set_section_command (char *args, int from_tty)
{
  struct section_table *p;
  char *secname;
  unsigned seclen;
  unsigned long secaddr;
  char secprint[100];
  long offset;

  if (args == 0)
    error (_("Must specify section name and its virtual address"));

  /* Parse out section name */
  for (secname = args; !isspace (*args); args++);
  seclen = args - secname;

  /* Parse out new virtual address */
  secaddr = parse_and_eval_address (args);

  for (p = exec_ops.to_sections; p < exec_ops.to_sections_end; p++)
    {
      if (!strncmp (secname, bfd_section_name (exec_bfd, p->the_bfd_section), seclen)
	  && bfd_section_name (exec_bfd, p->the_bfd_section)[seclen] == '\0')
	{
	  offset = secaddr - p->addr;
	  p->addr += offset;
	  p->endaddr += offset;
	  /* (TiEmu 20050626 Kevin Kofler) Relocate symbol file (objfile). The bad
	     relocation API forces us to copy the entire offset table to change just
	     that one offset. */
	  if (exec_objfile)
	    {
	      struct section_offsets *new_offsets = ((struct section_offsets *) 
	        alloca (SIZEOF_N_SECTION_OFFSETS (exec_objfile->num_sections)));
	      memcpy (new_offsets, exec_objfile->section_offsets,
	              SIZEOF_N_SECTION_OFFSETS (exec_objfile->num_sections));
	      new_offsets->offsets[p->the_bfd_section->index] += offset;
	      objfile_relocate (exec_objfile, new_offsets);
	    }
	  if (from_tty)
	    exec_files_info (&exec_ops);
	  return;
	}
    }
  if (seclen >= sizeof (secprint))
    seclen = sizeof (secprint) - 1;
  strncpy (secprint, secname, seclen);
  secprint[seclen] = '\0';
  error (_("Section %s not found"), secprint);
}
Пример #7
0
void
print_section_info (struct target_ops *t, bfd *abfd)
{
  struct target_section *p;
  /* FIXME: 16 is not wide enough when gdbarch_addr_bit > 64.  */
  int wid = gdbarch_addr_bit (gdbarch_from_bfd (abfd)) <= 32 ? 8 : 16;

  printf_filtered ("\t`%s', ", bfd_get_filename (abfd));
  wrap_here ("        ");
  printf_filtered (_("file type %s.\n"), bfd_get_target (abfd));
  if (abfd == exec_bfd)
    printf_filtered (_("\tEntry point: %s\n"),
                     paddress (bfd_get_start_address (abfd)));
  for (p = t->to_sections; p < t->to_sections_end; p++)
    {
      printf_filtered ("\t%s", hex_string_custom (p->addr, wid));
      printf_filtered (" - %s", hex_string_custom (p->endaddr, wid));

      /* FIXME: A format of "08l" is not wide enough for file offsets
	 larger than 4GB.  OTOH, making it "016l" isn't desirable either
	 since most output will then be much wider than necessary.  It
	 may make sense to test the size of the file and choose the
	 format string accordingly.  */
      /* FIXME: i18n: Need to rewrite this sentence.  */
      if (info_verbose)
	printf_filtered (" @ %s",
			 hex_string_custom (p->the_bfd_section->filepos, 8));
      printf_filtered (" is %s", bfd_section_name (p->bfd, p->the_bfd_section));
      if (p->bfd != abfd)
	printf_filtered (" in %s", bfd_get_filename (p->bfd));
      printf_filtered ("\n");
    }
}
Пример #8
0
static void flash_section(bfd * ibfd, sec_ptr isection, void *arg)
{
	bfd_size_type size = bfd_section_size(ibfd, isection);
	/* bfd_vma vma = bfd_section_vma(ibfd, isection); */
	bfd_vma lma = bfd_section_lma(ibfd, isection);
	const char *section_name = bfd_section_name(ibfd, isection);
	bfd_byte *data = 0;
	struct flash_section_data *fsdata = arg;
	struct c2tool_state *state = fsdata->state;
	unsigned int offset = fsdata->offset;
	unsigned int flash_addr = lma + offset;

	printf("section %s: lma %016" BFD_VMA_FMT "x, size %d -> flash %08x\n",
	       section_name, lma, (int)size, flash_addr);

	if (!bfd_get_full_section_contents (ibfd,isection, &data)) {
		fprintf(stderr, "Reading section failed\n");
		return;
	}

	while (size) {
		int res;

		res = flash_chunk(state, flash_addr, size, data);
		if (res < 0) {
			fprintf(stderr, "flash chunk at %08x failed.\n", flash_addr);
			break;
		}
		flash_addr += res;
		size -= res;
		data += res;
	}
}
Пример #9
0
static void
fbsd_core_check_lwp (bfd *abfd, asection *asect, void *obj)
{
  lwpid_t lwp;

  if (strncmp (bfd_section_name (abfd, asect), ".reg/", 5) != 0)
    return;

  /* already found */
  if (*(lwpid_t *)obj == 0)
    return;

  lwp = atoi (bfd_section_name (abfd, asect) + 5);
  if (*(lwpid_t *)obj == lwp)
    *(lwpid_t *)obj = 0;
}
Пример #10
0
static void secscan (bfd *file, sec_ptr sec, void *userParam)
{
    SecScanParam *param = (SecScanParam *) userParam;
    if (strcmp(param->sectionName, bfd_section_name (file, sec))==0)
    {
        bfd_size_type size = bfd_section_size (file, sec);
        void *data = (void *) param->result.reserve(size);
        bfd_get_section_contents(file, sec, data, 0, size);
    }
}
Пример #11
0
static int
derive_heap_segment (bfd *abfd, bfd_vma *bottom, bfd_vma *top)
{
  bfd_vma top_of_data_memory = 0;
  bfd_vma top_of_heap = 0;
  bfd_size_type sec_size;
  bfd_vma sec_vaddr;
  asection *sec;

  gdb_assert (bottom);
  gdb_assert (top);

  /* This function depends on being able to call a function in the
     inferior.  */
  if (!target_has_execution)
    return 0;

  /* The following code assumes that the link map is arranged as
     follows (low to high addresses):

     ---------------------------------
     | text sections                 |
     ---------------------------------
     | data sections (including bss) |
     ---------------------------------
     | heap                          |
     --------------------------------- */

  for (sec = abfd->sections; sec; sec = sec->next)
    {
      if (bfd_get_section_flags (abfd, sec) & SEC_DATA
	  || strcmp (".bss", bfd_section_name (abfd, sec)) == 0)
	{
	  sec_vaddr = bfd_get_section_vma (abfd, sec);
	  sec_size = bfd_get_section_size (sec);
	  if (sec_vaddr + sec_size > top_of_data_memory)
	    top_of_data_memory = sec_vaddr + sec_size;
	}
    }

  top_of_heap = call_target_sbrk (0);
  if (top_of_heap == (bfd_vma) 0)
    return 0;

  /* Return results.  */
  if (top_of_heap > top_of_data_memory)
    {
      *bottom = top_of_data_memory;
      *top = top_of_heap;
      return 1;
    }

  /* No additional heap space needs to be saved.  */
  return 0;
}
Пример #12
0
static void
add_to_thread_list (bfd *abfd, asection *asect, void *reg_sect_arg)
{
  ptid_t ptid;
  int core_tid;
  int pid, lwpid;
  asection *reg_sect = (asection *) reg_sect_arg;
  int fake_pid_p = 0;
  struct inferior *inf;

  if (!startswith (bfd_section_name (abfd, asect), ".reg/"))
    return;

  core_tid = atoi (bfd_section_name (abfd, asect) + 5);

  pid = bfd_core_file_pid (core_bfd);
  if (pid == 0)
    {
      fake_pid_p = 1;
      pid = CORELOW_PID;
    }

  lwpid = core_tid;

  inf = current_inferior ();
  if (inf->pid == 0)
    {
      inferior_appeared (inf, pid);
      inf->fake_pid_p = fake_pid_p;
    }

  ptid = ptid_build (pid, lwpid, 0);

  add_thread (ptid);

/* Warning, Will Robinson, looking at BFD private data! */

  if (reg_sect != NULL
      && asect->filepos == reg_sect->filepos)	/* Did we find .reg?  */
    inferior_ptid = ptid;			/* Yes, make it current.  */
}
Пример #13
0
static symbolS *
obj_coff_common_parse (int ignore ATTRIBUTE_UNUSED, symbolS *symbolP, addressT size)
{
  addressT align = 0;

  if (*input_line_pointer == ',')
    {
      align = parse_align (0);
      if (align == (addressT) -1)
	return NULL;
    }

  S_SET_VALUE (symbolP, size);
  S_SET_EXTERNAL (symbolP);
  S_SET_SEGMENT (symbolP, bfd_com_section_ptr);

  symbol_get_bfdsym (symbolP)->flags |= BSF_OBJECT;

  /* There is no S_SET_ALIGN (symbolP, align) in COFF/PE.
     Instead we must add a note to the .drectve section.  */
  if (align)
    {
      segT current_seg = now_seg;
      subsegT current_subseg = now_subseg;
      flagword oldflags;
      asection *sec;
      size_t pfxlen, numlen;
      char *frag;
      char numbuff[20];

      sec = subseg_new (".drectve", 0);
      oldflags = bfd_get_section_flags (stdoutput, sec);
      if (oldflags == SEC_NO_FLAGS)
	{
	  if (!bfd_set_section_flags (stdoutput, sec,
		TC_COFF_SECTION_DEFAULT_ATTRIBUTES))
	    as_warn (_("error setting flags for \"%s\": %s"),
		bfd_section_name (stdoutput, sec),
		bfd_errmsg (bfd_get_error ()));
	}

      /* Emit a string.  Note no NUL-termination.  */
      pfxlen = strlen (" -aligncomm:") + 2 + strlen (S_GET_NAME (symbolP)) + 1;
      numlen = snprintf (numbuff, sizeof (numbuff), "%d", (int) align);
      frag = frag_more (pfxlen + numlen);
      (void) sprintf (frag, " -aligncomm:\"%s\",", S_GET_NAME (symbolP));
      memcpy (frag + pfxlen, numbuff, numlen);
      /* Restore original subseg. */
      subseg_set (current_seg, current_subseg);
    }

  return symbolP;
}
Пример #14
0
static CORE_ADDR
bss_data_overlap (struct objfile *objfile)
{
  struct obj_section *osect;
  struct bfd_section *data = NULL;
  struct bfd_section *bss = NULL;

  /* First, find the .data and .bss sections.  */
  ALL_OBJFILE_OSECTIONS (objfile, osect)
    {
      if (strcmp (bfd_section_name (objfile->obfd,
				    osect->the_bfd_section),
		  ".data") == 0)
	data = osect->the_bfd_section;
      else if (strcmp (bfd_section_name (objfile->obfd,
					 osect->the_bfd_section),
		       ".bss") == 0)
	bss = osect->the_bfd_section;
    }

  /* If either section is not defined, there can be no overlap.  */
  if (data == NULL || bss == NULL)
    return 0;

  /* Assume the problem only occurs with linkers that place the .bss
     section after the .data section (the problem has only been
     observed when using the GNU linker, and the default linker
     script always places the .data and .bss sections in that order).  */
  if (bfd_section_vma (objfile->obfd, bss)
      < bfd_section_vma (objfile->obfd, data))
    return 0;

  if (bfd_section_vma (objfile->obfd, bss)
      < bfd_section_vma (objfile->obfd, data) + bfd_get_section_size (data))
    return ((bfd_section_vma (objfile->obfd, data)
	     + bfd_get_section_size (data))
	    - bfd_section_vma (objfile->obfd, bss));

  return 0;
}
Пример #15
0
static void
set_section_command (char *args, int from_tty)
{
  struct target_section *p;
  char *secname;
  unsigned seclen;
  unsigned long secaddr;
  char secprint[100];
  long offset;

  if (args == 0)
    error (_("Must specify section name and its virtual address"));

  /* Parse out section name */
  for (secname = args; !isspace (*args); args++);
  seclen = args - secname;

  /* Parse out new virtual address */
  secaddr = parse_and_eval_address (args);

  for (p = exec_ops.to_sections; p < exec_ops.to_sections_end; p++)
    {
      if (!strncmp (secname, bfd_section_name (exec_bfd, p->the_bfd_section), seclen)
	  && bfd_section_name (exec_bfd, p->the_bfd_section)[seclen] == '\0')
	{
	  offset = secaddr - p->addr;
	  p->addr += offset;
	  p->endaddr += offset;
	  if (from_tty)
	    exec_files_info (&exec_ops);
	  return;
	}
    }
  if (seclen >= sizeof (secprint))
    seclen = sizeof (secprint) - 1;
  strncpy (secprint, secname, seclen);
  secprint[seclen] = '\0';
  error (_("Section %s not found"), secprint);
}
Пример #16
0
static void
make_output_phdrs (bfd *obfd, asection *osec, void *ignored)
{
  int p_flags = 0;
  int p_type = 0;

  /* FIXME: these constants may only be applicable for ELF.  */
  if (strncmp (bfd_section_name (obfd, osec), "load", 4) == 0)
    p_type = PT_LOAD;
  else if (strncmp (bfd_section_name (obfd, osec), "note", 4) == 0)
    p_type = PT_NOTE;
  else
    p_type = PT_NULL;

  p_flags |= PF_R;	/* Segment is readable.  */
  if (!(bfd_get_section_flags (obfd, osec) & SEC_READONLY))
    p_flags |= PF_W;	/* Segment is writable.  */
  if (bfd_get_section_flags (obfd, osec) & SEC_CODE)
    p_flags |= PF_X;	/* Segment is executable.  */

  bfd_record_phdr (obfd, p_type, 1, p_flags, 0, 0, 0, 0, 1, &osec);
}
Пример #17
0
static void
print_objfile_section_info(bfd *abfd, struct obj_section *asect,
			   const char *string)
{
  flagword flags = bfd_get_section_flags(abfd, asect->the_bfd_section);
  const char *name = bfd_section_name(abfd, asect->the_bfd_section);

  if ((string == NULL) || (*string == '\0')
      || match_substring(string, name)
      || match_bfd_flags(string, flags))
    {
      maint_print_section_info(name, flags, asect->addr, asect->endaddr,
			  (unsigned long)asect->the_bfd_section->filepos);
    }
}
Пример #18
0
static void
print_bfd_section_info(bfd *abfd, asection *asect, void *arg)
{
  flagword flags = bfd_get_section_flags(abfd, asect);
  const char *name = bfd_section_name(abfd, asect);

  if ((arg == NULL) || (*((char *)arg) == '\0')
      || match_substring((char *)arg, name)
      || match_bfd_flags((char *)arg, flags))
    {
      CORE_ADDR addr, endaddr;

      addr = bfd_section_vma(abfd, asect);
      endaddr = (addr + bfd_section_size(abfd, asect));
      maint_print_section_info(name, flags, addr, endaddr,
                               (unsigned long)asect->filepos);
    }
}
Пример #19
0
static void
add_to_spuid_list (bfd *abfd, asection *asect, void *list_p)
{
  struct spuid_list *list = list_p;
  enum bfd_endian byte_order
    = bfd_big_endian (abfd) ? BFD_ENDIAN_BIG : BFD_ENDIAN_LITTLE;
  int fd, pos = 0;

  sscanf (bfd_section_name (abfd, asect), "SPU/%d/regs%n", &fd, &pos);
  if (pos == 0)
    return;

  if (list->pos >= list->offset && list->pos + 4 <= list->offset + list->len)
    {
      store_unsigned_integer (list->buf + list->pos - list->offset,
			      4, byte_order, fd);
      list->written += 4;
    }
  list->pos += 4;
}
Пример #20
0
static void
print_bfd_section_info (bfd *abfd, 
			asection *asect, 
			void *arg)
{
  flagword flags = bfd_get_section_flags (abfd, asect);
  const char *name = bfd_section_name (abfd, asect);

  if (arg == NULL || *((char *) arg) == '\0'
      || match_substring ((char *) arg, name)
      || match_bfd_flags ((char *) arg, flags))
    {
      struct gdbarch *gdbarch = gdbarch_from_bfd (abfd);
      int addr_size = gdbarch_addr_bit (gdbarch) / 8;
      CORE_ADDR addr, endaddr;

      addr = bfd_section_vma (abfd, asect);
      endaddr = addr + bfd_section_size (abfd, asect);
      maint_print_section_info (name, flags, addr, endaddr,
				asect->filepos, addr_size);
    }
}
Пример #21
0
static void
print_objfile_section_info (bfd *abfd, 
			    struct obj_section *asect, 
			    const char *string)
{
  flagword flags = bfd_get_section_flags (abfd, asect->the_bfd_section);
  const char *name = bfd_section_name (abfd, asect->the_bfd_section);

  if (string == NULL || *string == '\0'
      || match_substring (string, name)
      || match_bfd_flags (string, flags))
    {
      struct gdbarch *gdbarch = gdbarch_from_bfd (abfd);
      int addr_size = gdbarch_addr_bit (gdbarch) / 8;

      maint_print_section_info (name, flags,
				obj_section_addr (asect),
				obj_section_endaddr (asect),
				asect->the_bfd_section->filepos,
				addr_size);
    }
}
Пример #22
0
void
print_section_info (struct target_ops *t, bfd *abfd)
{
  struct section_table *p;
  /* FIXME: "016l" is not wide enough when TARGET_ADDR_BIT > 64.  */
  char *fmt = TARGET_ADDR_BIT <= 32 ? "08l" : "016l";

  printf_filtered ("\t`%s', ", bfd_get_filename (abfd));
  wrap_here ("        ");
  printf_filtered ("file type %s.\n", bfd_get_target (abfd));
  if (abfd == exec_bfd)
    {
      printf_filtered ("\tEntry point: ");
      print_address_numeric (bfd_get_start_address (abfd), 1, gdb_stdout);
      printf_filtered ("\n");
    }
  for (p = t->to_sections; p < t->to_sections_end; p++)
    {
      printf_filtered ("\t%s", local_hex_string_custom (p->addr, fmt));
      printf_filtered (" - %s", local_hex_string_custom (p->endaddr, fmt));

      /* FIXME: A format of "08l" is not wide enough for file offsets
	 larger than 4GB.  OTOH, making it "016l" isn't desirable either
	 since most output will then be much wider than necessary.  It
	 may make sense to test the size of the file and choose the
	 format string accordingly.  */
      if (info_verbose)
	printf_filtered (" @ %s",
			 local_hex_string_custom (p->the_bfd_section->filepos, "08l"));
      printf_filtered (" is %s", bfd_section_name (p->bfd, p->the_bfd_section));
      if (p->bfd != abfd)
	{
	  printf_filtered (" in %s", bfd_get_filename (p->bfd));
	}
      printf_filtered ("\n");
    }
}
Пример #23
0
/* initialize section data */
void initialize_section(bincode_t *bin)
{
    asection *section;
    //const char *section_name;
    //flagword section_flags; // unsigned int
    bfd *abfd = bin->abfd;
    section_t *nextsec = NULL;

    for (section=abfd->sections;section!=NULL;section=section->next) {
        section_t *sec;
        bfd_byte *data;
        bfd_size_type datasize = bfd_get_section_size(section);

        if (datasize == 0) continue;

        if((data = malloc(datasize)) == NULL) {
            bs_errmsg("  (!) malloc(): data\n");
            exit(EXIT_FAILURE);
        }
        bfd_get_section_contents(abfd, section, data, 0 ,datasize);
        if((sec = malloc(sizeof(section_t))) == NULL) {
            bs_errmsg("  (!) malloc(): section\n");
            exit(EXIT_FAILURE);
        }
        sec->name = strdup(bfd_section_name(abfd, section));
        sec->data = data;
        sec->datasize = datasize;
        sec->vma = section->vma;
        sec->section = section;
        sec->is_code = section->flags & SEC_CODE;

        sec->next = nextsec;
        nextsec = sec;
    }
    bin->sec = nextsec;
}
static void
setup_section (bfd *ibfd, sec_ptr isection, void *obfdarg)
{
  bfd *obfd = obfdarg;
  struct section_list *p;
  sec_ptr osection;
  bfd_size_type size;
  bfd_vma vma;
  bfd_vma lma;
  const char *err;
  const char * name;

  name = bfd_section_name (ibfd, isection);

  osection = bfd_make_section_anyway (obfd, name);

  if (osection == NULL)
    {
      perror("setup_section: making");
    }

  size = bfd_section_size (ibfd, isection);
  if (! bfd_set_section_size (obfd, osection, size))
    {
      perror("setup_section: size");
    }

  vma = bfd_section_vma (ibfd, isection);

  if (! bfd_set_section_vma (obfd, osection, vma))
    {
      perror("setup_section: vma");
    }

  lma = isection->lma;

  osection->lma = lma;

  /* FIXME: This is probably not enough.  If we change the LMA we
     may have to recompute the header for the file as well.  */
  if (!bfd_set_section_alignment (obfd,
				  osection,
				  bfd_section_alignment (ibfd, isection)))
    {
      perror("setup_section: alignment");
    }

  if (!bfd_set_section_flags (obfd, osection, bfd_get_section_flags(ibfd, isection)))
    {
      perror("setup_section: flags");
    }

  /* Copy merge entity size.  */
  osection->entsize = isection->entsize;

  /* This used to be mangle_section; we do here to avoid using
     bfd_get_section_by_name since some formats allow multiple
     sections with the same name.  */

  isection->output_section = osection;
  isection->output_offset = 0;

  /* Allow the BFD backend to copy any private data it understands
     from the input section to the output section.  */
  if (!bfd_copy_private_section_data (ibfd, isection, obfd, osection))
    {
      perror("setup_section: private data");
    }

  /* All went well.  */
  return;

  perror("setup_section: %s: section `%s': error in %s: %s"),
	     bfd_get_filename (ibfd),
	     bfd_section_name (ibfd, isection),
	     err, bfd_errmsg (bfd_get_error ());
}
Пример #25
0
/* load program text and initialized data into simulated virtual memory
   space and initialize program segment range variables */
void
ld_load_prog(char *fname,		/* program to load */
	     int argc, char **argv,	/* simulated program cmd line args */
	     char **envp,		/* simulated program environment */
	     struct regs_t *regs,	/* registers to initialize for load */
	     struct mem_t *mem,		/* memory space to load prog into */
	     int zero_bss_segs)		/* zero uninit data segment? */
{
  int i;
  qword_t temp;
  md_addr_t sp, data_break = 0, null_ptr = 0, argv_addr, envp_addr;

  if (eio_valid(fname))
    {
      if (argc != 1)
	{
	  fprintf(stderr, "error: EIO file has arguments\n");
	  exit(1);
	}

      fprintf(stderr, "sim: loading EIO file: %s\n", fname);

      sim_eio_fname = mystrdup(fname);

      /* open the EIO file stream */
      sim_eio_fd = eio_open(fname);

      /* load initial state checkpoint */
      if (eio_read_chkpt(regs, mem, sim_eio_fd) != -1)
	fatal("bad initial checkpoint in EIO file");

      /* load checkpoint? */
      if (sim_chkpt_fname != NULL)
	{
	  counter_t restore_icnt;

	  FILE *chkpt_fd;

	  fprintf(stderr, "sim: loading checkpoint file: %s\n",
		  sim_chkpt_fname);

	  if (!eio_valid(sim_chkpt_fname))
	    fatal("file `%s' does not appear to be a checkpoint file",
		  sim_chkpt_fname);

	  /* open the checkpoint file */
	  chkpt_fd = eio_open(sim_chkpt_fname);

	  /* load the state image */
	  restore_icnt = eio_read_chkpt(regs, mem, chkpt_fd);

	  /* fast forward the baseline EIO trace to checkpoint location */
	  myfprintf(stderr, "sim: fast forwarding to instruction %n\n",
		    restore_icnt);
	  eio_fast_forward(sim_eio_fd, restore_icnt);
	}

      /* computed state... */
      ld_environ_base = regs->regs_R[MD_REG_SP];
      ld_prog_entry = regs->regs_PC;

      /* fini... */
      return;
    }
#ifdef MD_CROSS_ENDIAN
  else
    {
      warn("endian of `%s' does not match host", fname);
      warn("running with experimental cross-endian execution support");
      warn("****************************************");
      warn("**>> please check results carefully <<**");
      warn("****************************************");
#if 0
      fatal("SimpleScalar/Alpha only supports binary execution on\n"
	    "       little-endian hosts, use EIO files on big-endian hosts");
#endif
    }
#endif /* MD_CROSS_ENDIAN */

  if (sim_chkpt_fname != NULL)
    fatal("checkpoints only supported while EIO tracing");

#ifdef BFD_LOADER

  {
    bfd *abfd;
    asection *sect;

    /* set up a local stack pointer, this is where the argv and envp
       data is written into program memory */
    ld_stack_base = MD_STACK_BASE;
    sp = ROUND_DOWN(MD_STACK_BASE - MD_MAX_ENVIRON, sizeof(MD_DOUBLE_TYPE));
    ld_stack_size = ld_stack_base - sp;
    printf("Thread 0 stack size (3)%d\n",  current->ld_stack_size);

    /* initial stack pointer value */
    ld_environ_base = sp;

    /* load the program into memory, try both endians */
    if (!(abfd = bfd_openr(argv[0], "ss-coff-big")))
      if (!(abfd = bfd_openr(argv[0], "ss-coff-little")))
	fatal("cannot open executable `%s'", argv[0]);

    /* this call is mainly for its side effect of reading in the sections.
       we follow the traditional behavior of `strings' in that we don't
       complain if we don't recognize a file to be an object file.  */
    if (!bfd_check_format(abfd, bfd_object))
      {
	bfd_close(abfd);
	fatal("cannot open executable `%s'", argv[0]);
      }

    /* record profile file name */
    ld_prog_fname = argv[0];

    /* record endian of target */
    ld_target_big_endian = abfd->xvec->byteorder_big_p;

    debug("processing %d sections in `%s'...",
	  bfd_count_sections(abfd), argv[0]);

    /* read all sections in file */
    for (sect=abfd->sections; sect; sect=sect->next)
      {
	char *p;

	debug("processing section `%s', %d bytes @ 0x%08x...",
	      bfd_section_name(abfd, sect), bfd_section_size(abfd, sect),
	      bfd_section_vma(abfd, sect));

	/* read the section data, if allocated and loadable and non-NULL */
	if ((bfd_get_section_flags(abfd, sect) & SEC_ALLOC)
	    && (bfd_get_section_flags(abfd, sect) & SEC_LOAD)
	    && bfd_section_vma(abfd, sect)
	    && bfd_section_size(abfd, sect))
	  {
	    /* allocate a section buffer */
	    p = calloc(bfd_section_size(abfd, sect), sizeof(char));
	    if (!p)
	      fatal("cannot allocate %d bytes for section `%s'",
		    bfd_section_size(abfd, sect),
		    bfd_section_name(abfd, sect));

	    if (!bfd_get_section_contents(abfd, sect, p, (file_ptr)0,
					  bfd_section_size(abfd, sect)))
	      fatal("could not read entire `%s' section from executable",
		    bfd_section_name(abfd, sect));

	    /* copy program section it into simulator target memory */
	    mem_bcopy(mem_fn, Write, bfd_section_vma(abfd, sect),
		      p, bfd_section_size(abfd, sect));

	    /* release the section buffer */
	    free(p);
	  }
	/* zero out the section if it is loadable but not allocated in exec */
	else if (zero_bss_segs
		 && (bfd_get_section_flags(abfd, sect) & SEC_LOAD)
		 && bfd_section_vma(abfd, sect)
		 && bfd_section_size(abfd, sect))
	  {
	    /* zero out the section region */
	    mem_bzero(mem_fn,
		      bfd_section_vma(abfd, sect),
		      bfd_section_size(abfd, sect));
	  }
	else
	  {
	    /* else do nothing with this section, it's probably debug data */
	    debug("ignoring section `%s' during load...",
		  bfd_section_name(abfd, sect));
	  }

	/* expected text section */
	if (!strcmp(bfd_section_name(abfd, sect), ".text"))
	  {
	    /* .text section processing */
	    ld_text_size =
	      ((bfd_section_vma(abfd, sect) + bfd_section_size(abfd, sect))
	       - MD_TEXT_BASE)
		+ /* for speculative fetches/decodes */TEXT_TAIL_PADDING;

	    /* create tail padding and copy into simulator target memory */
#if 0
	    mem_bzero(mem_fn,
		      bfd_section_vma(abfd, sect)
		      + bfd_section_size(abfd, sect),
		      TEXT_TAIL_PADDING);
#endif
	  }
	/* expected data sections */
	else if (!strcmp(bfd_section_name(abfd, sect), ".rdata")
		 || !strcmp(bfd_section_name(abfd, sect), ".data")
		 || !strcmp(bfd_section_name(abfd, sect), ".sdata")
		 || !strcmp(bfd_section_name(abfd, sect), ".bss")
		 || !strcmp(bfd_section_name(abfd, sect), ".sbss"))
	  {
	    /* data section processing */
	    if (bfd_section_vma(abfd, sect) + bfd_section_size(abfd, sect) >
		data_break)
	      data_break = (bfd_section_vma(abfd, sect) +
			    bfd_section_size(abfd, sect));
	  }
	else
	  {
	    /* what is this section??? */
	    fatal("encountered unknown section `%s', %d bytes @ 0x%08x",
		  bfd_section_name(abfd, sect), bfd_section_size(abfd, sect),
		  bfd_section_vma(abfd, sect));
	  }
      }

    /* compute data segment size from data break point */
    ld_text_base = MD_TEXT_BASE;
    ld_data_base = MD_DATA_BASE;
    ld_prog_entry = bfd_get_start_address(abfd);
    ld_data_size = data_break - ld_data_base;

    /* done with the executable, close it */
    if (!bfd_close(abfd))
      fatal("could not close executable `%s'", argv[0]);
  }

#else /* !BFD_LOADER, i.e., standalone loader */

  {
    FILE *fobj;
    long floc;
    struct ecoff_filehdr fhdr;
    struct ecoff_aouthdr ahdr;
    struct ecoff_scnhdr shdr;

    /* record profile file name */
    ld_prog_fname = argv[0];

    /* load the program into memory, try both endians */
#if defined(__CYGWIN32__) || defined(_MSC_VER)
    fobj = fopen(argv[0], "rb");
#else
    fobj = fopen(argv[0], "r");
#endif
    if (!fobj)
      fatal("cannot open executable `%s'", argv[0]);

    if (fread(&fhdr, sizeof(struct ecoff_filehdr), 1, fobj) < 1)
      fatal("cannot read header from executable `%s'", argv[0]);

    /* record endian of target */
    if (fhdr.f_magic == MD_SWAPH(ECOFF_ALPHAMAGIC))
      ld_target_big_endian = FALSE;
    else if (fhdr.f_magic == MD_SWAPH(ECOFF_EB_MAGIC)
	     || fhdr.f_magic == MD_SWAPH(ECOFF_EL_MAGIC)
	     || fhdr.f_magic == MD_SWAPH(ECOFF_EB_OTHER)
	     || fhdr.f_magic == MD_SWAPH(ECOFF_EL_OTHER))
      fatal("Alpha simulator cannot run PISA binary `%s'", argv[0]);
    else
      fatal("bad magic number in executable `%s' (not an executable)",
	    argv[0]);

    if (fread(&ahdr, sizeof(struct ecoff_aouthdr), 1, fobj) < 1)
      fatal("cannot read AOUT header from executable `%s'", argv[0]);

    ld_text_base = MD_SWAPQ(ahdr.text_start);
    ld_text_size = MD_SWAPQ(ahdr.tsize);
    ld_prog_entry = MD_SWAPQ(ahdr.entry);
    ld_data_base = MD_SWAPQ(ahdr.data_start);
    ld_data_size = MD_SWAPQ(ahdr.dsize) + MD_SWAPQ(ahdr.bsize);
    regs->regs_R[MD_REG_GP] = MD_SWAPQ(ahdr.gp_value);

    /* compute data segment size from data break point */
    data_break = ld_data_base + ld_data_size;

    /* seek to the beginning of the first section header, the file header comes
       first, followed by the optional header (this is the aouthdr), the size
       of the aouthdr is given in Fdhr.f_opthdr */
    fseek(fobj, sizeof(struct ecoff_filehdr) + MD_SWAPH(fhdr.f_opthdr), 0);

    debug("processing %d sections in `%s'...",
	  MD_SWAPH(fhdr.f_nscns), argv[0]);

    /* loop through the section headers */
    floc = ftell(fobj);
    for (i = 0; i < MD_SWAPH(fhdr.f_nscns); i++)
      {
	char *p;

	if (fseek(fobj, floc, 0) == -1)
	  fatal("could not reset location in executable");
	if (fread(&shdr, sizeof(struct ecoff_scnhdr), 1, fobj) < 1)
	  fatal("could not read section %d from executable", i);
	floc = ftell(fobj);

	switch (MD_SWAPW(shdr.s_flags))
	  {
	  case ECOFF_STYP_TEXT:
	    p = calloc(MD_SWAPQ(shdr.s_size), sizeof(char));
	    if (!p)
	      fatal("out of virtual memory");

	    if (fseek(fobj, MD_SWAPQ(shdr.s_scnptr), 0) == -1)
	      fatal("could not read `.text' from executable", i);
	    if (fread(p, MD_SWAPQ(shdr.s_size), 1, fobj) < 1)
	      fatal("could not read text section from executable");

	    /* copy program section into simulator target memory */
	    mem_bcopy(mem_access, mem, Write,
		      MD_SWAPQ(shdr.s_vaddr), p, MD_SWAPQ(shdr.s_size));

#if 0
	    /* create tail padding and copy into simulator target memory */
	    mem_bzero(mem_access, mem,
		      MD_SWAPQ(shdr.s_vaddr) + MD_SWAPQ(shdr.s_size),
		      TEXT_TAIL_PADDING);
#endif

	    /* release the section buffer */
	    free(p);

#if 0
	    Text_seek = MD_SWAPQ(shdr.s_scnptr);
	    Text_start = MD_SWAPQ(shdr.s_vaddr);
	    Text_size = MD_SWAPQ(shdr.s_size) / 4;
	    /* there is a null routine after the supposed end of text */
	    Text_size += 10;
	    Text_end = Text_start + Text_size * 4;
	    /* create_text_reloc(shdr.s_relptr, shdr.s_nreloc); */
#endif
	    break;

	  case ECOFF_STYP_INIT:
	  case ECOFF_STYP_FINI:
	    if (MD_SWAPQ(shdr.s_size) > 0)
	      {
		p = calloc(MD_SWAPQ(shdr.s_size), sizeof(char));
		if (!p)
		  fatal("out of virtual memory");

		if (fseek(fobj, MD_SWAPQ(shdr.s_scnptr), 0) == -1)
		  fatal("could not read `.text' from executable", i);
		if (fread(p, MD_SWAPQ(shdr.s_size), 1, fobj) < 1)
		  fatal("could not read text section from executable");
		
		/* copy program section into simulator target memory */
		mem_bcopy(mem_access, mem,
			  Write, MD_SWAPQ(shdr.s_vaddr),
			  p, MD_SWAPQ(shdr.s_size));

		/* release the section buffer */
		free(p);
	      }
	    else
	      warn("section `%s' is empty...", shdr.s_name);
	    break;

	  case ECOFF_STYP_LITA:
	  case ECOFF_STYP_LIT8:
	  case ECOFF_STYP_LIT4:
	  case ECOFF_STYP_XDATA:
	  case ECOFF_STYP_PDATA:
	  case ECOFF_STYP_RCONST:
	    /* fall through */

	  case ECOFF_STYP_RDATA:
	    /* The .rdata section is sometimes placed before the text
	     * section instead of being contiguous with the .data section.
	     */
#if 0
	    Rdata_start = MD_SWAPQ(shdr.s_vaddr);
	    Rdata_size = MD_SWAPQ(shdr.s_size);
	    Rdata_seek = MD_SWAPQ(shdr.s_scnptr);
#endif
	    /* fall through */
	  case ECOFF_STYP_DATA:
#if 0
	    Data_seek = MD_SWAPQ(shdr.s_scnptr);
#endif
	    /* fall through */
	  case ECOFF_STYP_SDATA:
#if 0
	    Sdata_seek = MD_SWAPQ(shdr.s_scnptr);
#endif
	    if (MD_SWAPQ(shdr.s_size) > 0)
	      {
		p = calloc(MD_SWAPQ(shdr.s_size), sizeof(char));
		if (!p)
		  fatal("out of virtual memory");

		if (fseek(fobj, MD_SWAPQ(shdr.s_scnptr), 0) == -1)
		  fatal("could not read `.text' from executable", i);
		if (fread(p, MD_SWAPQ(shdr.s_size), 1, fobj) < 1)
		  fatal("could not read text section from executable");

		/* copy program section it into simulator target memory */
		mem_bcopy(mem_access, mem,
			  Write, MD_SWAPQ(shdr.s_vaddr),
			  p, MD_SWAPQ(shdr.s_size));

		/* release the section buffer */
		free(p);
	      }
	    else
	      warn("section `%s' is empty...", shdr.s_name);
	  break;

	  case ECOFF_STYP_BSS:
	  case ECOFF_STYP_SBSS:
	    /* no data to read... */
	    break;

	  default:
	    warn("section `%s' ignored...", shdr.s_name);
	  }
      }

    /* done with the executable, close it */
    if (fclose(fobj))
      fatal("could not close executable `%s'", argv[0]);
  }

#endif /* BFD_LOADER */

  /* perform sanity checks on segment ranges */
  if (!ld_text_base || !ld_text_size)
    fatal("executable is missing a `.text' section");
  if (!ld_data_base || !ld_data_size)
    fatal("executable is missing a `.data' section");
  if (!ld_prog_entry)
    fatal("program entry point not specified");

  /* determine byte/words swapping required to execute on this host */
  sim_swap_bytes = (endian_host_byte_order() != endian_target_byte_order());
  if (sim_swap_bytes)
    {
#if 0 /* FIXME: disabled until further notice... */
      /* cross-endian is never reliable, why this is so is beyond the scope
	 of this comment, e-mail me for details... */
      fprintf(stderr, "sim: *WARNING*: swapping bytes to match host...\n");
      fprintf(stderr, "sim: *WARNING*: swapping may break your program!\n");
      /* #else */
      fatal("binary endian does not match host endian");
#endif
    }
  sim_swap_words = (endian_host_word_order() != endian_target_word_order());
  if (sim_swap_words)
    {
#if 0 /* FIXME: disabled until further notice... */
      /* cross-endian is never reliable, why this is so is beyond the scope
	 of this comment, e-mail me for details... */
      fprintf(stderr, "sim: *WARNING*: swapping words to match host...\n");
      fprintf(stderr, "sim: *WARNING*: swapping may break your program!\n");
      /* #else */
      fatal("binary endian does not match host endian");
#endif
    }

  /* set up a local stack pointer, this is where the argv and envp
     data is written into program memory */
  ld_stack_base = ld_text_base - (409600+4096);
#if 0
  sp = ROUND_DOWN(ld_stack_base - MD_MAX_ENVIRON, sizeof(MD_DOUBLE_TYPE));
#endif
  sp = ld_stack_base - MD_MAX_ENVIRON;
  ld_stack_size = ld_stack_base - sp;
    printf("Thread 0 stack size (4)%d\n",  current->ld_stack_size);

  /* initial stack pointer value */
  ld_environ_base = sp;

  /* write [argc] to stack */
  temp = MD_SWAPQ(argc);
  mem_access(mem, Write, sp, &temp, sizeof(qword_t));
  regs->regs_R[MD_REG_A0] = temp;
  sp += sizeof(qword_t);

  /* skip past argv array and NULL */
  argv_addr = sp;
  regs->regs_R[MD_REG_A1] = argv_addr;
  sp = sp + (argc + 1) * sizeof(md_addr_t);

  /* save space for envp array and NULL */
  envp_addr = sp;
  for (i=0; envp[i]; i++)
    sp += sizeof(md_addr_t);
  sp += sizeof(md_addr_t);

  /* fill in the argv pointer array and data */
  for (i=0; i<argc; i++)
    {
      /* write the argv pointer array entry */
      temp = MD_SWAPQ(sp);
      mem_access(mem, Write, argv_addr + i*sizeof(md_addr_t),
		 &temp, sizeof(md_addr_t));
      /* and the data */
      mem_strcpy(mem_access, mem, Write, sp, argv[i]);
      sp += strlen(argv[i])+1;
    }
  /* terminate argv array with a NULL */
  mem_access(mem, Write, argv_addr + i*sizeof(md_addr_t),
	     &null_ptr, sizeof(md_addr_t));

  /* write envp pointer array and data to stack */
  for (i = 0; envp[i]; i++)
    {
      /* write the envp pointer array entry */
      temp = MD_SWAPQ(sp);
      mem_access(mem, Write, envp_addr + i*sizeof(md_addr_t),
		 &temp, sizeof(md_addr_t));
      /* and the data */
      mem_strcpy(mem_access, mem, Write, sp, envp[i]);
      sp += strlen(envp[i]) + 1;
    }
  /* terminate the envp array with a NULL */
  mem_access(mem, Write, envp_addr + i*sizeof(md_addr_t),
	     &null_ptr, sizeof(md_addr_t));

  /* did we tromp off the stop of the stack? */
  if (sp > ld_stack_base)
    {
      /* we did, indicate to the user that MD_MAX_ENVIRON must be increased,
	 alternatively, you can use a smaller environment, or fewer
	 command line arguments */
      fatal("environment overflow, increase MD_MAX_ENVIRON in alpha.h");
    }

  /* initialize the bottom of heap to top of data segment */
  ld_brk_point = ROUND_UP(ld_data_base + ld_data_size, MD_PAGE_SIZE);

  /* set initial minimum stack pointer value to initial stack value */
  ld_stack_min = regs->regs_R[MD_REG_SP];

  regs->regs_R[MD_REG_SP] = ld_environ_base;
  regs->regs_PC = ld_prog_entry;

  printf("ld_text_base: 0x%08x  ld_text_size: 0x%08x",
	ld_text_base, ld_text_size);
  printf("ld_data_base: 0x%08x  ld_data_size: 0x%08x",
	ld_data_base, ld_data_size);
  printf("ld_stack_base: 0x%08x  ld_stack_size: 0x%08x",
	ld_stack_base, ld_stack_size);
  printf("ld_prog_entry: 0x%08x", ld_prog_entry);

  debug("ld_text_base: 0x%08x  ld_text_size: 0x%08x",
	ld_text_base, ld_text_size);
  debug("ld_data_base: 0x%08x  ld_data_size: 0x%08x",
	ld_data_base, ld_data_size);
  debug("ld_stack_base: 0x%08x  ld_stack_size: 0x%08x",
	ld_stack_base, ld_stack_size);
  debug("ld_prog_entry: 0x%08x", ld_prog_entry);
}
Пример #26
0
static void
restore_section_callback(bfd *ibfd, asection *isec, void *args)
{
  struct callback_data *data = (struct callback_data *)args;
  bfd_vma sec_start = bfd_section_vma(ibfd, isec);
  bfd_size_type size = bfd_section_size(ibfd, isec);
  bfd_vma sec_end = (sec_start + size);
  bfd_size_type sec_offset = 0UL;
  bfd_size_type sec_load_count = size;
  struct cleanup *old_chain;
  gdb_byte *buf;
  int ret;

  /* Ignore non-loadable sections, eg. from elf files: */
  if (!(bfd_get_section_flags(ibfd, isec) & SEC_LOAD))
    return;

  /* Does the section overlap with the desired restore range? */
  if ((sec_end <= data->load_start)
      || ((data->load_end > 0) && (sec_start >= data->load_end)))
    {
      /* No, no useable data in this section. */
      printf_filtered(_("skipping section %s...\n"),
		      bfd_section_name(ibfd, isec));
      return;
    }

  /* Compare section address range with user-requested
     address range (if any).  Compute where the actual
     transfer should start and end.  */
  if (sec_start < data->load_start)
    sec_offset = (data->load_start - sec_start);
  /* Size of a partial transfer: */
  sec_load_count -= sec_offset;
  if ((data->load_end > 0) && (sec_end > data->load_end))
    sec_load_count -= (sec_end - data->load_end);

  /* Get the data.  */
  buf = (gdb_byte *)xmalloc((size_t)size);
  old_chain = make_cleanup(xfree, buf);
  if (!bfd_get_section_contents(ibfd, isec, buf, 0, size))
    error(_("Failed to read bfd file %s: '%s'."), bfd_get_filename(ibfd),
	  bfd_errmsg(bfd_get_error()));

  printf_filtered("Restoring section %s (0x%lx to 0x%lx)",
		  bfd_section_name(ibfd, isec),
		  (unsigned long)sec_start, (unsigned long)sec_end);

  if ((data->load_offset != 0) || (data->load_start != 0) || (data->load_end != 0))
    printf_filtered(" into memory (0x%s to 0x%s)\n",
		    paddr_nz((unsigned long)sec_start
                             + sec_offset + data->load_offset),
		    paddr_nz((unsigned long)sec_start + sec_offset
                             + data->load_offset + sec_load_count));
  else
    puts_filtered("\n");

  /* Write the data: */
  ret = target_write_memory((sec_start + sec_offset + data->load_offset),
			    (buf + sec_offset), (int)sec_load_count);
  if (ret != 0)
    warning(_("restore: memory write failed (%s)."), safe_strerror(ret));
  do_cleanups(old_chain);
  return;
}
Пример #27
0
static int
derive_heap_segment (bfd *abfd, bfd_vma *bottom, bfd_vma *top)
{
  bfd_vma top_of_data_memory = 0;
  bfd_vma top_of_heap = 0;
  bfd_size_type sec_size;
  struct value *zero, *sbrk;
  bfd_vma sec_vaddr;
  asection *sec;

  gdb_assert (bottom);
  gdb_assert (top);

  /* This function depends on being able to call a function in the
     inferior.  */
  if (!target_has_execution)
    return 0;

  /* The following code assumes that the link map is arranged as
     follows (low to high addresses):

     ---------------------------------
     | text sections                 |
     ---------------------------------
     | data sections (including bss) |
     ---------------------------------
     | heap                          |
     --------------------------------- */

  for (sec = abfd->sections; sec; sec = sec->next)
    {
      if (bfd_get_section_flags (abfd, sec) & SEC_DATA
	  || strcmp (".bss", bfd_section_name (abfd, sec)) == 0)
	{
	  sec_vaddr = bfd_get_section_vma (abfd, sec);
	  sec_size = bfd_get_section_size (sec);
	  if (sec_vaddr + sec_size > top_of_data_memory)
	    top_of_data_memory = sec_vaddr + sec_size;
	}
    }

  /* Now get the top-of-heap by calling sbrk in the inferior.  */
  if (lookup_minimal_symbol ("sbrk", NULL, NULL) != NULL)
    {
      sbrk = find_function_in_inferior ("sbrk");
      if (sbrk == NULL)
	return 0;
    }
  else if (lookup_minimal_symbol ("_sbrk", NULL, NULL) != NULL)
    {
      sbrk = find_function_in_inferior ("_sbrk");
      if (sbrk == NULL)
	return 0;
    }
  else
    return 0;

  zero = value_from_longest (builtin_type_int, 0);
  gdb_assert (zero);
  sbrk = call_function_by_hand (sbrk, 1, &zero);
  if (sbrk == NULL)
    return 0;
  top_of_heap = value_as_long (sbrk);

  /* Return results.  */
  if (top_of_heap > top_of_data_memory)
    {
      *bottom = top_of_data_memory;
      *top = top_of_heap;
      return 1;
    }

  /* No additional heap space needs to be saved.  */
  return 0;
}
Пример #28
0
static int
ppc_linux_spu_section (bfd *abfd, asection *asect, void *user_data)
{
  return strncmp (bfd_section_name (abfd, asect), "SPU/", 4) == 0;
}