From 93a57060b7845887707fb5d6865e96cfdca888d0 Mon Sep 17 00:00:00 2001 From: Daniel Jacobowitz Date: Tue, 3 Jun 2008 12:59:37 +0000 Subject: [PATCH] * solib-svr4.c (struct lm_info): Add lm_addr. (main_lm_addr): New. (svr4_default_sos): Set lm_addr. (svr4_current_sos): Set lm_addr and main_lm_addr. (svr4_fetch_objfile_link_map): Rewrite. (svr4_clear_solib): Clear main_lm_addr. --- gdb/ChangeLog | 9 +++++ gdb/solib-svr4.c | 90 +++++++++++++++--------------------------------- 2 files changed, 36 insertions(+), 63 deletions(-) diff --git a/gdb/ChangeLog b/gdb/ChangeLog index 5f4fbba5f9..c21daf0c7a 100644 --- a/gdb/ChangeLog +++ b/gdb/ChangeLog @@ -1,3 +1,12 @@ +2008-06-03 Daniel Jacobowitz + + * solib-svr4.c (struct lm_info): Add lm_addr. + (main_lm_addr): New. + (svr4_default_sos): Set lm_addr. + (svr4_current_sos): Set lm_addr and main_lm_addr. + (svr4_fetch_objfile_link_map): Rewrite. + (svr4_clear_solib): Clear main_lm_addr. + 2008-06-03 Michael Snyder Joseph Myers diff --git a/gdb/solib-svr4.c b/gdb/solib-svr4.c index 5a0135b088..70e8802666 100644 --- a/gdb/solib-svr4.c +++ b/gdb/solib-svr4.c @@ -61,6 +61,9 @@ struct lm_info address changes, we may need a different offset, we want to warn about the difference and compute it only once. */ CORE_ADDR l_addr; + + /* The target location of lm. */ + CORE_ADDR lm_addr; }; /* On SVR4 systems, a list of symbols in the dynamic linker where @@ -278,6 +281,9 @@ static CORE_ADDR debug_loader_offset; /* Name of the dynamic linker, valid if debug_loader_offset_p. */ static char *debug_loader_name; +/* Load map address for the main executable. */ +static CORE_ADDR main_lm_addr; + /* Local function prototypes */ static int match_main (char *); @@ -708,6 +714,7 @@ svr4_default_sos (void) /* 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_addr = 0; new->lm_info->lm = NULL; strncpy (new->so_name, debug_loader_name, SO_NAME_MAX_PATH_SIZE - 1); @@ -771,6 +778,7 @@ svr4_current_sos (void) make_cleanup (xfree, new->lm_info); new->lm_info->l_addr = (CORE_ADDR)-1; + new->lm_info->lm_addr = lm; new->lm_info->lm = xzalloc (lmo->link_map_size); make_cleanup (xfree, new->lm_info->lm); @@ -784,7 +792,10 @@ svr4_current_sos (void) does have a name, so we can no longer use a missing name to decide when to ignore it. */ if (IGNORE_FIRST_LINK_MAP_ENTRY (new) && ldsomap == 0) - free_so (new); + { + main_lm_addr = new->lm_info->lm_addr; + free_so (new); + } else { int errcode; @@ -833,76 +844,28 @@ svr4_current_sos (void) return head; } -/* Get the address of the link_map for a given OBJFILE. Loop through - the link maps, and return the address of the one corresponding to - the given objfile. Note that this function takes into account that - objfile can be the main executable, not just a shared library. The - main executable has always an empty name field in the linkmap. */ +/* Get the address of the link_map for a given OBJFILE. */ CORE_ADDR svr4_fetch_objfile_link_map (struct objfile *objfile) { - CORE_ADDR lm; + struct so_list *so; - if (locate_base () == 0) - return 0; /* failed somehow... */ + /* Cause svr4_current_sos() to be run if it hasn't been already. */ + if (main_lm_addr == 0) + solib_add (NULL, 0, ¤t_target, auto_solib_add); - /* Position ourselves on the first link map. */ - lm = solib_svr4_r_map (); - while (lm) - { - /* Get info on the layout of the r_debug and link_map structures. */ - struct link_map_offsets *lmo = svr4_fetch_link_map_offsets (); - int errcode; - char *buffer; - struct lm_info objfile_lm_info; - struct cleanup *old_chain; - CORE_ADDR name_address; - int l_name_size = TYPE_LENGTH (builtin_type_void_data_ptr); - gdb_byte *l_name_buf = xmalloc (l_name_size); - old_chain = make_cleanup (xfree, l_name_buf); + /* svr4_current_sos() will set main_lm_addr for the main executable. */ + if (objfile == symfile_objfile) + return main_lm_addr; - /* Set up the buffer to contain the portion of the link_map - structure that gdb cares about. Note that this is not the - whole link_map structure. */ - objfile_lm_info.lm = xzalloc (lmo->link_map_size); - make_cleanup (xfree, objfile_lm_info.lm); + /* The other link map addresses may be found by examining the list + of shared libraries. */ + for (so = master_so_list (); so; so = so->next) + if (so->objfile == objfile) + return so->lm_info->lm_addr; - /* Read the link map into our internal structure. */ - read_memory (lm, objfile_lm_info.lm, lmo->link_map_size); - - /* Read address of name from target memory to GDB. */ - read_memory (lm + lmo->l_name_offset, l_name_buf, l_name_size); - - /* Extract this object's name. */ - name_address = extract_typed_address (l_name_buf, - builtin_type_void_data_ptr); - target_read_string (name_address, &buffer, - SO_NAME_MAX_PATH_SIZE - 1, &errcode); - make_cleanup (xfree, buffer); - if (errcode != 0) - warning (_("Can't read pathname for load map: %s."), - safe_strerror (errcode)); - else - { - /* Is this the linkmap for the file we want? */ - /* If the file is not a shared library and has no name, - we are sure it is the main executable, so we return that. */ - - if (buffer - && ((strcmp (buffer, objfile->name) == 0) - || (!(objfile->flags & OBJF_SHARED) - && (strcmp (buffer, "") == 0)))) - { - do_cleanups (old_chain); - return lm; - } - } - /* Not the file we wanted, continue checking. */ - lm = extract_typed_address (objfile_lm_info.lm + lmo->l_next_offset, - builtin_type_void_data_ptr); - do_cleanups (old_chain); - } + /* Not found! */ return 0; } @@ -1476,6 +1439,7 @@ svr4_clear_solib (void) debug_loader_offset = 0; xfree (debug_loader_name); debug_loader_name = NULL; + main_lm_addr = 0; } static void