* solib-svr4.c (debug_loader_offset_p, debug_loader_offset)

(debug_loader_name, svr4_default_sos): New.
	(svr4_current_sos): Call svr4_default_sos.
	(enable_break): Add a comment about AT_BASE.  Set the new
	variables and retry solib_add.
	(svr4_clear_solib): Clear the new variables.
This commit is contained in:
Daniel Jacobowitz
2006-10-18 15:34:39 +00:00
parent 7d3d3ece84
commit 3443977099
2 changed files with 73 additions and 5 deletions

View File

@ -1,4 +1,13 @@
2006-10-17 Daniel Jacobowitz <dan@codesourcery.com> 2006-10-18 Daniel Jacobowitz <dan@codesourcery.com>
* solib-svr4.c (debug_loader_offset_p, debug_loader_offset)
(debug_loader_name, svr4_default_sos): New.
(svr4_current_sos): Call svr4_default_sos.
(enable_break): Add a comment about AT_BASE. Set the new
variables and retry solib_add.
(svr4_clear_solib): Clear the new variables.
2006-10-18 Daniel Jacobowitz <dan@codesourcery.com>
* NEWS: Mention support for TLS without debugging information. * NEWS: Mention support for TLS without debugging information.

View File

@ -267,6 +267,15 @@ IGNORE_FIRST_LINK_MAP_ENTRY (struct so_list *so)
static CORE_ADDR debug_base; /* Base of dynamic linker structures */ static CORE_ADDR debug_base; /* Base of dynamic linker structures */
static CORE_ADDR breakpoint_addr; /* Address where end bkpt is set */ static CORE_ADDR breakpoint_addr; /* Address where end bkpt is set */
/* Validity flag for debug_loader_offset. */
static int debug_loader_offset_p;
/* Load address for the dynamic linker, inferred. */
static CORE_ADDR debug_loader_offset;
/* Name of the dynamic linker, valid if debug_loader_offset_p. */
static char *debug_loader_name;
/* Local function prototypes */ /* Local function prototypes */
static int match_main (char *); static int match_main (char *);
@ -657,6 +666,37 @@ open_symbol_file_object (void *from_ttyp)
return 1; return 1;
} }
/* If no shared library information is available from the dynamic
linker, build a fallback list from other sources. */
static struct so_list *
svr4_default_sos (void)
{
struct so_list *head = NULL;
struct so_list **link_ptr = &head;
if (debug_loader_offset_p)
{
struct so_list *new = XZALLOC (struct so_list);
new->lm_info = xmalloc (sizeof (struct lm_info));
/* Nothing will ever check the cached copy of the link
map if we set l_addr. */
new->lm_info->l_addr = debug_loader_offset;
new->lm_info->lm = NULL;
strncpy (new->so_name, debug_loader_name, SO_NAME_MAX_PATH_SIZE - 1);
new->so_name[SO_NAME_MAX_PATH_SIZE - 1] = '\0';
strcpy (new->so_original_name, new->so_name);
*link_ptr = new;
link_ptr = &new->next;
}
return head;
}
/* LOCAL FUNCTION /* LOCAL FUNCTION
current_sos -- build a list of currently loaded shared objects current_sos -- build a list of currently loaded shared objects
@ -693,12 +733,13 @@ svr4_current_sos (void)
/* If we can't find the dynamic linker's base structure, this /* If we can't find the dynamic linker's base structure, this
must not be a dynamically linked executable. Hmm. */ must not be a dynamically linked executable. Hmm. */
if (! debug_base) if (! debug_base)
return 0; return svr4_default_sos ();
} }
/* Walk the inferior's link map list, and build our list of /* Walk the inferior's link map list, and build our list of
`struct so_list' nodes. */ `struct so_list' nodes. */
lm = solib_svr4_r_map (); lm = solib_svr4_r_map ();
while (lm) while (lm)
{ {
struct link_map_offsets *lmo = svr4_fetch_link_map_offsets (); struct link_map_offsets *lmo = svr4_fetch_link_map_offsets ();
@ -765,6 +806,9 @@ svr4_current_sos (void)
discard_cleanups (old_chain); discard_cleanups (old_chain);
} }
if (head == NULL)
return svr4_default_sos ();
return head; return head;
} }
@ -983,7 +1027,12 @@ enable_break (void)
be trivial on GNU/Linux). Therefore, we have to try an alternate be trivial on GNU/Linux). Therefore, we have to try an alternate
mechanism to find the dynamic linker's base address. */ mechanism to find the dynamic linker's base address. */
tmp_fd = solib_open (buf, &tmp_pathname); /* TODO drow/2006-09-12: This is somewhat fragile, because it
relies on read_pc. On both Solaris and GNU/Linux we can use
the AT_BASE auxilliary entry, which GDB now knows how to
access, to find the base address. */
tmp_fd = solib_open (buf, &tmp_pathname);
if (tmp_fd >= 0) if (tmp_fd >= 0)
tmp_bfd = bfd_fopen (tmp_pathname, gnutarget, FOPEN_RB, tmp_fd); tmp_bfd = bfd_fopen (tmp_pathname, gnutarget, FOPEN_RB, tmp_fd);
@ -1022,8 +1071,14 @@ enable_break (void)
the current pc (which should point at the entry point for the the current pc (which should point at the entry point for the
dynamic linker) and subtracting the offset of the entry point. */ dynamic linker) and subtracting the offset of the entry point. */
if (!load_addr_found) if (!load_addr_found)
load_addr = (read_pc () {
- exec_entry_point (tmp_bfd, tmp_bfd_target)); load_addr = (read_pc ()
- exec_entry_point (tmp_bfd, tmp_bfd_target));
debug_loader_name = xstrdup (buf);
debug_loader_offset_p = 1;
debug_loader_offset = load_addr;
solib_add (NULL, 0, NULL, auto_solib_add);
}
/* Record the relocated start and end address of the dynamic linker /* Record the relocated start and end address of the dynamic linker
text and plt section for svr4_in_dynsym_resolve_code. */ text and plt section for svr4_in_dynsym_resolve_code. */
@ -1335,6 +1390,10 @@ static void
svr4_clear_solib (void) svr4_clear_solib (void)
{ {
debug_base = 0; debug_base = 0;
debug_loader_offset_p = 0;
debug_loader_offset = 0;
xfree (debug_loader_name);
debug_loader_name = NULL;
} }
static void static void