Пример #1
0
static int
enable_break2 (void)
{
  enum bfd_endian byte_order = gdbarch_byte_order (target_gdbarch);
  int success = 0;
  char **bkpt_namep;
  asection *interp_sect;

  if (enable_break2_done)
    return 1;

  interp_text_sect_low = interp_text_sect_high = 0;
  interp_plt_sect_low = interp_plt_sect_high = 0;

  /* Find the .interp section; if not found, warn the user and drop
     into the old breakpoint at symbol code.  */
  interp_sect = bfd_get_section_by_name (exec_bfd, ".interp");
  if (interp_sect)
    {
      unsigned int interp_sect_size;
      gdb_byte *buf;
      bfd *tmp_bfd = NULL;
      int status;
      CORE_ADDR addr, interp_loadmap_addr;
      gdb_byte addr_buf[FRV_PTR_SIZE];
      struct int_elf32_fdpic_loadmap *ldm;
      volatile struct gdb_exception ex;

      /* Read the contents of the .interp section into a local buffer;
         the contents specify the dynamic linker this program uses.  */
      interp_sect_size = bfd_section_size (exec_bfd, interp_sect);
      buf = alloca (interp_sect_size);
      bfd_get_section_contents (exec_bfd, interp_sect,
				buf, 0, interp_sect_size);

      /* Now we need to figure out where the dynamic linker was
         loaded so that we can load its symbols and place a breakpoint
         in the dynamic linker itself.

         This address is stored on the stack.  However, I've been unable
         to find any magic formula to find it for Solaris (appears to
         be trivial on GNU/Linux).  Therefore, we have to try an alternate
         mechanism to find the dynamic linker's base address.  */

      TRY_CATCH (ex, RETURN_MASK_ALL)
        {
          tmp_bfd = solib_bfd_open (buf);
        }
      if (tmp_bfd == NULL)
	{
	  enable_break_failure_warning ();
	  return 0;
	}

      status = frv_fdpic_loadmap_addresses (target_gdbarch,
                                            &interp_loadmap_addr, 0);
      if (status < 0)
	{
	  warning (_("Unable to determine dynamic linker loadmap address."));
	  enable_break_failure_warning ();
	  bfd_close (tmp_bfd);
	  return 0;
	}

      if (solib_frv_debug)
	fprintf_unfiltered (gdb_stdlog,
	                    "enable_break: interp_loadmap_addr = %s\n",
			    hex_string_custom (interp_loadmap_addr, 8));

      ldm = fetch_loadmap (interp_loadmap_addr);
      if (ldm == NULL)
	{
	  warning (_("Unable to load dynamic linker loadmap at address %s."),
	           hex_string_custom (interp_loadmap_addr, 8));
	  enable_break_failure_warning ();
	  bfd_close (tmp_bfd);
	  return 0;
	}

      /* Record the relocated start and end address of the dynamic linker
         text and plt section for svr4_in_dynsym_resolve_code.  */
      interp_sect = bfd_get_section_by_name (tmp_bfd, ".text");
      if (interp_sect)
	{
	  interp_text_sect_low
	    = bfd_section_vma (tmp_bfd, interp_sect);
	  interp_text_sect_low
	    += displacement_from_map (ldm, interp_text_sect_low);
	  interp_text_sect_high
	    = interp_text_sect_low + bfd_section_size (tmp_bfd, interp_sect);
	}
      interp_sect = bfd_get_section_by_name (tmp_bfd, ".plt");
      if (interp_sect)
	{
	  interp_plt_sect_low =
	    bfd_section_vma (tmp_bfd, interp_sect);
	  interp_plt_sect_low
	    += displacement_from_map (ldm, interp_plt_sect_low);
	  interp_plt_sect_high =
	    interp_plt_sect_low + bfd_section_size (tmp_bfd, interp_sect);
	}

      addr = bfd_lookup_symbol (tmp_bfd, "_dl_debug_addr");
      if (addr == 0)
	{
	  warning (_("Could not find symbol _dl_debug_addr in dynamic linker"));
	  enable_break_failure_warning ();
	  bfd_close (tmp_bfd);
	  return 0;
	}

      if (solib_frv_debug)
	fprintf_unfiltered (gdb_stdlog,
	                    "enable_break: _dl_debug_addr (prior to relocation) = %s\n",
			    hex_string_custom (addr, 8));

      addr += displacement_from_map (ldm, addr);

      if (solib_frv_debug)
	fprintf_unfiltered (gdb_stdlog,
	                    "enable_break: _dl_debug_addr (after relocation) = %s\n",
			    hex_string_custom (addr, 8));

      /* Fetch the address of the r_debug struct.  */
      if (target_read_memory (addr, addr_buf, sizeof addr_buf) != 0)
	{
	  warning (_("Unable to fetch contents of _dl_debug_addr (at address %s) from dynamic linker"),
	           hex_string_custom (addr, 8));
	}
      addr = extract_unsigned_integer (addr_buf, sizeof addr_buf, byte_order);

      if (solib_frv_debug)
	fprintf_unfiltered (gdb_stdlog,
	                    "enable_break: _dl_debug_addr[0..3] = %s\n",
	                    hex_string_custom (addr, 8));

      /* If it's zero, then the ldso hasn't initialized yet, and so
         there are no shared libs yet loaded.  */
      if (addr == 0)
	{
	  if (solib_frv_debug)
	    fprintf_unfiltered (gdb_stdlog,
	                        "enable_break: ldso not yet initialized\n");
	  /* Do not warn, but mark to run again.  */
	  return 0;
	}

      /* Fetch the r_brk field.  It's 8 bytes from the start of
         _dl_debug_addr.  */
      if (target_read_memory (addr + 8, addr_buf, sizeof addr_buf) != 0)
	{
	  warning (_("Unable to fetch _dl_debug_addr->r_brk (at address %s) from dynamic linker"),
	           hex_string_custom (addr + 8, 8));
	  enable_break_failure_warning ();
	  bfd_close (tmp_bfd);
	  return 0;
	}
      addr = extract_unsigned_integer (addr_buf, sizeof addr_buf, byte_order);

      /* Now fetch the function entry point.  */
      if (target_read_memory (addr, addr_buf, sizeof addr_buf) != 0)
	{
	  warning (_("Unable to fetch _dl_debug_addr->.r_brk entry point (at address %s) from dynamic linker"),
	           hex_string_custom (addr, 8));
	  enable_break_failure_warning ();
	  bfd_close (tmp_bfd);
	  return 0;
	}
      addr = extract_unsigned_integer (addr_buf, sizeof addr_buf, byte_order);

      /* We're done with the temporary bfd.  */
      bfd_close (tmp_bfd);

      /* We're also done with the loadmap.  */
      xfree (ldm);

      /* Remove all the solib event breakpoints.  Their addresses
         may have changed since the last time we ran the program.  */
      remove_solib_event_breakpoints ();

      /* Now (finally!) create the solib breakpoint.  */
      create_solib_event_breakpoint (target_gdbarch, addr);

      enable_break2_done = 1;

      return 1;
    }
Пример #2
0
static struct so_list *
dsbt_current_sos (void)
{
  enum bfd_endian byte_order = gdbarch_byte_order (target_gdbarch);
  CORE_ADDR lm_addr;
  struct so_list *sos_head = NULL;
  struct so_list **sos_next_ptr = &sos_head;
  struct dsbt_info *info = get_dsbt_info ();

  /* Make sure that the main executable has been relocated.  This is
     required in order to find the address of the global offset table,
     which in turn is used to find the link map info.  (See lm_base
     for details.)

     Note that the relocation of the main executable is also performed
     by SOLIB_CREATE_INFERIOR_HOOK, however, in the case of core
     files, this hook is called too late in order to be of benefit to
     SOLIB_ADD.  SOLIB_ADD eventually calls this function,
     dsbt_current_sos, and also precedes the call to
     SOLIB_CREATE_INFERIOR_HOOK.   (See post_create_inferior in
     infcmd.c.)  */
  if (info->main_executable_lm_info == 0 && core_bfd != NULL)
    dsbt_relocate_main_executable ();

  /* Locate the address of the first link map struct.  */
  lm_addr = lm_base ();

  /* We have at least one link map entry.  Fetch the the lot of them,
     building the solist chain.  */
  while (lm_addr)
    {
      struct ext_link_map lm_buf;
      ext_Elf32_Word indexword;
      CORE_ADDR map_addr;
      int dsbt_index;
      int ret;

      if (solib_dsbt_debug)
	fprintf_unfiltered (gdb_stdlog,
			    "current_sos: reading link_map entry at %s\n",
			    hex_string_custom (lm_addr, 8));

      ret = target_read_memory (lm_addr, (gdb_byte *) &lm_buf, sizeof (lm_buf));
      if (ret)
	{
	  warning (_("dsbt_current_sos: Unable to read link map entry."
		     "  Shared object chain may be incomplete."));
	  break;
	}

      /* Fetch the load map address.  */
      map_addr = extract_unsigned_integer (lm_buf.l_addr.map,
					   sizeof lm_buf.l_addr.map,
					   byte_order);

      ret = target_read_memory (map_addr + 12, (gdb_byte *) &indexword,
				sizeof indexword);
      if (ret)
	{
	  warning (_("dsbt_current_sos: Unable to read dsbt index."
		     "  Shared object chain may be incomplete."));
	  break;
	}
      dsbt_index = extract_unsigned_integer (indexword, sizeof indexword,
					     byte_order);

      /* If the DSBT index is zero, then we're looking at the entry
	 for the main executable.  By convention, we don't include
	 this in the list of shared objects.  */
      if (dsbt_index != 0)
	{
	  int errcode;
	  char *name_buf;
	  struct int_elf32_dsbt_loadmap *loadmap;
	  struct so_list *sop;
	  CORE_ADDR addr;

	  loadmap = fetch_loadmap (map_addr);
	  if (loadmap == NULL)
	    {
	      warning (_("dsbt_current_sos: Unable to fetch load map."
			 "  Shared object chain may be incomplete."));
	      break;
	    }

	  sop = xcalloc (1, sizeof (struct so_list));
	  sop->lm_info = xcalloc (1, sizeof (struct lm_info));
	  sop->lm_info->map = loadmap;
	  /* Fetch the name.  */
	  addr = extract_unsigned_integer (lm_buf.l_name,
					   sizeof (lm_buf.l_name),
					   byte_order);
	  target_read_string (addr, &name_buf, SO_NAME_MAX_PATH_SIZE - 1,
			      &errcode);

	  if (errcode != 0)
	    warning (_("Can't read pathname for link map entry: %s."),
		     safe_strerror (errcode));
	  else
	    {
	      if (solib_dsbt_debug)
		fprintf_unfiltered (gdb_stdlog, "current_sos: name = %s\n",
				    name_buf);

	      strncpy (sop->so_name, name_buf, SO_NAME_MAX_PATH_SIZE - 1);
	      sop->so_name[SO_NAME_MAX_PATH_SIZE - 1] = '\0';
	      xfree (name_buf);
	      strcpy (sop->so_original_name, sop->so_name);
	    }

	  *sos_next_ptr = sop;
	  sos_next_ptr = &sop->next;
	}
      else
	{
	  info->main_lm_addr = lm_addr;
	}

      lm_addr = extract_unsigned_integer (lm_buf.l_next,
					  sizeof (lm_buf.l_next), byte_order);
    }

  enable_break2 ();

  return sos_head;
}
Пример #3
0
static struct so_list *
frv_current_sos (void)
{
  enum bfd_endian byte_order = gdbarch_byte_order (target_gdbarch ());
  CORE_ADDR lm_addr, mgot;
  struct so_list *sos_head = NULL;
  struct so_list **sos_next_ptr = &sos_head;

  /* Make sure that the main executable has been relocated.  This is
     required in order to find the address of the global offset table,
     which in turn is used to find the link map info.  (See lm_base()
     for details.)

     Note that the relocation of the main executable is also performed
     by solib_create_inferior_hook(), however, in the case of core
     files, this hook is called too late in order to be of benefit to
     solib_add.  solib_add eventually calls this this function,
     frv_current_sos, and also precedes the call to
     solib_create_inferior_hook().   (See post_create_inferior() in
     infcmd.c.)  */
  if (main_executable_lm_info == 0 && core_bfd != NULL)
    frv_relocate_main_executable ();

  /* Fetch the GOT corresponding to the main executable.  */
  mgot = main_got ();

  /* Locate the address of the first link map struct.  */
  lm_addr = lm_base ();

  /* We have at least one link map entry.  Fetch the lot of them,
     building the solist chain.  */
  while (lm_addr)
    {
      struct ext_link_map lm_buf;
      CORE_ADDR got_addr;

      if (solib_frv_debug)
	fprintf_unfiltered (gdb_stdlog,
			    "current_sos: reading link_map entry at %s\n",
			    hex_string_custom (lm_addr, 8));

      if (target_read_memory (lm_addr, (gdb_byte *) &lm_buf,
			      sizeof (lm_buf)) != 0)
	{
	  warning (_("frv_current_sos: Unable to read link map entry.  "
		     "Shared object chain may be incomplete."));
	  break;
	}

      got_addr
	= extract_unsigned_integer (lm_buf.l_addr.got_value,
				    sizeof (lm_buf.l_addr.got_value),
				    byte_order);
      /* If the got_addr is the same as mgotr, then we're looking at the
	 entry for the main executable.  By convention, we don't include
	 this in the list of shared objects.  */
      if (got_addr != mgot)
	{
	  int errcode;
	  char *name_buf;
	  struct int_elf32_fdpic_loadmap *loadmap;
	  struct so_list *sop;
	  CORE_ADDR addr;

	  /* Fetch the load map address.  */
	  addr = extract_unsigned_integer (lm_buf.l_addr.map,
					   sizeof lm_buf.l_addr.map,
					   byte_order);
	  loadmap = fetch_loadmap (addr);
	  if (loadmap == NULL)
	    {
	      warning (_("frv_current_sos: Unable to fetch load map.  "
			 "Shared object chain may be incomplete."));
	      break;
	    }

	  sop = XCNEW (struct so_list);
	  sop->lm_info = XCNEW (struct lm_info);
	  sop->lm_info->map = loadmap;
	  sop->lm_info->got_value = got_addr;
	  sop->lm_info->lm_addr = lm_addr;
	  /* Fetch the name.  */
	  addr = extract_unsigned_integer (lm_buf.l_name,
					   sizeof (lm_buf.l_name),
					   byte_order);
	  target_read_string (addr, &name_buf, SO_NAME_MAX_PATH_SIZE - 1,
			      &errcode);

	  if (solib_frv_debug)
	    fprintf_unfiltered (gdb_stdlog, "current_sos: name = %s\n",
	                        name_buf);
	  
	  if (errcode != 0)
	    warning (_("Can't read pathname for link map entry: %s."),
		     safe_strerror (errcode));
	  else
	    {
	      strncpy (sop->so_name, name_buf, SO_NAME_MAX_PATH_SIZE - 1);
	      sop->so_name[SO_NAME_MAX_PATH_SIZE - 1] = '\0';
	      xfree (name_buf);
	      strcpy (sop->so_original_name, sop->so_name);
	    }

	  *sos_next_ptr = sop;
	  sos_next_ptr = &sop->next;
	}
      else
	{