@ -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 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 */
static int match_main ( char * ) ;
@ -657,6 +666,37 @@ open_symbol_file_object (void *from_ttyp)
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
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
must not be a dynamically linked executable . Hmm . */
if ( ! debug_base )
return 0 ;
return svr4_default_sos ( ) ;
}
/* Walk the inferior's link map list, and build our list of
` struct so_list ' nodes . */
lm = solib_svr4_r_map ( ) ;
while ( lm )
{
struct link_map_offsets * lmo = svr4_fetch_link_map_offsets ( ) ;
@ -765,6 +806,9 @@ svr4_current_sos (void)
discard_cleanups ( old_chain ) ;
}
if ( head = = NULL )
return svr4_default_sos ( ) ;
return head ;
}
@ -983,7 +1027,12 @@ enable_break (void)
be trivial on GNU / Linux ) . Therefore , we have to try an alternate
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 )
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
dynamic linker ) and subtracting the offset of the entry point . */
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
text and plt section for svr4_in_dynsym_resolve_code . */
@ -1335,6 +1390,10 @@ static void
svr4_clear_solib ( void )
{
debug_base = 0 ;
debug_loader_offset_p = 0 ;
debug_loader_offset = 0 ;
xfree ( debug_loader_name ) ;
debug_loader_name = NULL ;
}
static void