diff options
author | Jan Kratochvil <jan.kratochvil@redhat.com> | 2011-10-14 07:58:58 +0000 |
---|---|---|
committer | Jan Kratochvil <jan.kratochvil@redhat.com> | 2011-10-14 07:58:58 +0000 |
commit | 3957565a968c5eacb611940a2146fd4491d584c1 (patch) | |
tree | 0df3597b7bfb69dd311af6ca681bfd02815bb223 /gdb/solib-svr4.c | |
parent | cb08cc53a94b7b878df56545bddfff940bb90d20 (diff) | |
download | gdb-3957565a968c5eacb611940a2146fd4491d584c1.zip gdb-3957565a968c5eacb611940a2146fd4491d584c1.tar.gz gdb-3957565a968c5eacb611940a2146fd4491d584c1.tar.bz2 |
gdb/
Drop lazy lm_info reading.
* solib-svr4.c (struct lm_info): Remove field lm. New fields l_addr_p,
l_addr_inferior, l_ld, l_next, l_prev and l_name.
(lm_info_read): New function.
(lm_addr_from_link_map, lm_dynamic_from_link_map): Remove.
(lm_addr_check): Use l_addr_p. No longer use lm_addr_from_link_map and
lm_dynamic_from_link_map.
(lm_next, lm_prev, lm_name): Remove.
(svr4_keep_data_in_core): Use lm_info_read, drop the lm_info entries
initialization incl. read_memory. No longer use lm_name.
(svr4_free_so): Drop lm_info->lm freeing.
(svr4_default_sos): Initialize lminfo with zeroes. Use l_addr_p. Drop
explicit lm_addr and lm initialization.
(svr4_read_so_list): Use lm_info_read, drop the initailization of
fields by hand, incl. read_memory. No longer use lm_next, lm_prev and
lm_name.
Diffstat (limited to 'gdb/solib-svr4.c')
-rw-r--r-- | gdb/solib-svr4.c | 149 |
1 files changed, 65 insertions, 84 deletions
diff --git a/gdb/solib-svr4.c b/gdb/solib-svr4.c index 554a1e3..2bb31a9 100644 --- a/gdb/solib-svr4.c +++ b/gdb/solib-svr4.c @@ -56,20 +56,21 @@ static void svr4_relocate_main_executable (void); struct lm_info { - /* Pointer to copy of link map from inferior. The type is char * - rather than void *, so that we may use byte offsets to find the - various fields without the need for a cast. */ - gdb_byte *lm; - /* Amount by which addresses in the binary should be relocated to - match the inferior. This could most often be taken directly - from lm, but when prelinking is involved and the prelink base - address changes, we may need a different offset, we want to - warn about the difference and compute it only once. */ - CORE_ADDR l_addr; + match the inferior. The direct inferior value is L_ADDR_INFERIOR. + When prelinking is involved and the prelink base address changes, + we may need a different offset - the recomputed offset is in L_ADDR. + It is commonly the same value. It is cached as we want to warn about + the difference and compute it only once. L_ADDR is valid + iff L_ADDR_P. */ + CORE_ADDR l_addr, l_addr_inferior; + unsigned int l_addr_p : 1; /* The target location of lm. */ CORE_ADDR lm_addr; + + /* Values read in from inferior's fields of the same name. */ + CORE_ADDR l_ld, l_next, l_prev, l_name; }; /* On SVR4 systems, a list of symbols in the dynamic linker where @@ -140,16 +141,44 @@ svr4_same (struct so_list *gdb, struct so_list *inferior) return (svr4_same_1 (gdb->so_original_name, inferior->so_original_name)); } -/* link map access functions. */ - -static CORE_ADDR -lm_addr_from_link_map (struct so_list *so) +static struct lm_info * +lm_info_read (CORE_ADDR lm_addr) { struct link_map_offsets *lmo = svr4_fetch_link_map_offsets (); - struct type *ptr_type = builtin_type (target_gdbarch)->builtin_data_ptr; + gdb_byte *lm; + struct lm_info *lm_info; + struct cleanup *back_to; + + lm = xmalloc (lmo->link_map_size); + back_to = make_cleanup (xfree, lm); + + if (target_read_memory (lm_addr, lm, lmo->link_map_size) != 0) + { + warning (_("Error reading shared library list entry at %s"), + paddress (target_gdbarch, lm_addr)), + lm_info = NULL; + } + else + { + struct type *ptr_type = builtin_type (target_gdbarch)->builtin_data_ptr; - return extract_typed_address (so->lm_info->lm + lmo->l_addr_offset, - ptr_type); + lm_info = xzalloc (sizeof (*lm_info)); + lm_info->lm_addr = lm_addr; + + lm_info->l_addr_inferior = extract_typed_address (&lm[lmo->l_addr_offset], + ptr_type); + lm_info->l_ld = extract_typed_address (&lm[lmo->l_ld_offset], ptr_type); + lm_info->l_next = extract_typed_address (&lm[lmo->l_next_offset], + ptr_type); + lm_info->l_prev = extract_typed_address (&lm[lmo->l_prev_offset], + ptr_type); + lm_info->l_name = extract_typed_address (&lm[lmo->l_name_offset], + ptr_type); + } + + do_cleanups (back_to); + + return lm_info; } static int @@ -161,29 +190,19 @@ has_lm_dynamic_from_link_map (void) } static CORE_ADDR -lm_dynamic_from_link_map (struct so_list *so) -{ - struct link_map_offsets *lmo = svr4_fetch_link_map_offsets (); - struct type *ptr_type = builtin_type (target_gdbarch)->builtin_data_ptr; - - return extract_typed_address (so->lm_info->lm + lmo->l_ld_offset, - ptr_type); -} - -static CORE_ADDR lm_addr_check (struct so_list *so, bfd *abfd) { - if (so->lm_info->l_addr == (CORE_ADDR)-1) + if (!so->lm_info->l_addr_p) { struct bfd_section *dyninfo_sect; CORE_ADDR l_addr, l_dynaddr, dynaddr; - l_addr = lm_addr_from_link_map (so); + l_addr = so->lm_info->l_addr_inferior; if (! abfd || ! has_lm_dynamic_from_link_map ()) goto set_addr; - l_dynaddr = lm_dynamic_from_link_map (so); + l_dynaddr = so->lm_info->l_ld; dyninfo_sect = bfd_get_section_by_name (abfd, ".dynamic"); if (dyninfo_sect == NULL) @@ -267,41 +286,12 @@ lm_addr_check (struct so_list *so, bfd *abfd) set_addr: so->lm_info->l_addr = l_addr; + so->lm_info->l_addr_p = 1; } return so->lm_info->l_addr; } -static CORE_ADDR -lm_next (struct so_list *so) -{ - struct link_map_offsets *lmo = svr4_fetch_link_map_offsets (); - struct type *ptr_type = builtin_type (target_gdbarch)->builtin_data_ptr; - - return extract_typed_address (so->lm_info->lm + lmo->l_next_offset, - ptr_type); -} - -static CORE_ADDR -lm_prev (struct so_list *so) -{ - struct link_map_offsets *lmo = svr4_fetch_link_map_offsets (); - struct type *ptr_type = builtin_type (target_gdbarch)->builtin_data_ptr; - - return extract_typed_address (so->lm_info->lm + lmo->l_prev_offset, - ptr_type); -} - -static CORE_ADDR -lm_name (struct so_list *so) -{ - struct link_map_offsets *lmo = svr4_fetch_link_map_offsets (); - struct type *ptr_type = builtin_type (target_gdbarch)->builtin_data_ptr; - - return extract_typed_address (so->lm_info->lm + lmo->l_name_offset, - ptr_type); -} - /* Per pspace SVR4 specific data. */ struct svr4_info @@ -843,14 +833,9 @@ svr4_keep_data_in_core (CORE_ADDR vaddr, unsigned long size) lmo = svr4_fetch_link_map_offsets (); new = XZALLOC (struct so_list); old_chain = make_cleanup (xfree, new); - new->lm_info = xmalloc (sizeof (struct lm_info)); + new->lm_info = lm_info_read (ldsomap); make_cleanup (xfree, new->lm_info); - new->lm_info->l_addr = (CORE_ADDR)-1; - new->lm_info->lm_addr = ldsomap; - new->lm_info->lm = xzalloc (lmo->link_map_size); - make_cleanup (xfree, new->lm_info->lm); - read_memory (ldsomap, new->lm_info->lm, lmo->link_map_size); - name_lm = lm_name (new); + name_lm = new->lm_info ? new->lm_info->l_name : 0; do_cleanups (old_chain); return (name_lm >= vaddr && name_lm < vaddr + size); @@ -936,8 +921,6 @@ open_symbol_file_object (void *from_ttyp) static void svr4_free_so (struct so_list *so) { - if (so->lm_info) - xfree (so->lm_info->lm); xfree (so->lm_info); } @@ -971,13 +954,11 @@ svr4_default_sos (void) new = XZALLOC (struct so_list); - new->lm_info = xmalloc (sizeof (struct lm_info)); + new->lm_info = xzalloc (sizeof (struct lm_info)); - /* Nothing will ever check the cached copy of the link - map if we set l_addr. */ + /* Nothing will ever check the other fields if we set l_addr_p. */ new->lm_info->l_addr = info->debug_loader_offset; - new->lm_info->lm_addr = 0; - new->lm_info->lm = NULL; + new->lm_info->l_addr_p = 1; strncpy (new->so_name, info->debug_loader_name, SO_NAME_MAX_PATH_SIZE - 1); new->so_name[SO_NAME_MAX_PATH_SIZE - 1] = '\0'; @@ -1007,16 +988,16 @@ svr4_read_so_list (CORE_ADDR lm, struct so_list ***link_ptr_ptr, new = XZALLOC (struct so_list); old_chain = make_cleanup_free_so (new); - new->lm_info = xmalloc (sizeof (struct 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); - - read_memory (lm, new->lm_info->lm, lmo->link_map_size); + new->lm_info = lm_info_read (lm); + if (new->lm_info == NULL) + { + do_cleanups (old_chain); + break; + } - next_lm = lm_next (new); + next_lm = new->lm_info->l_next; - if (lm_prev (new) != prev_lm) + if (new->lm_info->l_prev != prev_lm) { warning (_("Corrupted shared library list")); do_cleanups (old_chain); @@ -1028,7 +1009,7 @@ svr4_read_so_list (CORE_ADDR lm, struct so_list ***link_ptr_ptr, SVR4, it has no name. For others (Solaris 2.3 for example), it does have a name, so we can no longer use a missing name to decide when to ignore it. */ - if (ignore_first && lm_prev (new) == 0) + if (ignore_first && new->lm_info->l_prev == 0) { struct svr4_info *info = get_svr4_info (); @@ -1038,7 +1019,7 @@ svr4_read_so_list (CORE_ADDR lm, struct so_list ***link_ptr_ptr, } /* Extract this shared object's name. */ - target_read_string (lm_name (new), &buffer, + target_read_string (new->lm_info->l_name, &buffer, SO_NAME_MAX_PATH_SIZE - 1, &errcode); if (errcode != 0) { |