summaryrefslogtreecommitdiff
path: root/gdb/solib-svr4.c
diff options
context:
space:
mode:
authorJan Kratochvil <jan.kratochvil@redhat.com>2011-10-14 07:58:58 +0000
committerJan Kratochvil <jan.kratochvil@redhat.com>2011-10-14 07:58:58 +0000
commit507771e3475acbc34a276ffe1c1721124af05f66 (patch)
tree11a84015087d0b8a95e27dc4357a354bf0597745 /gdb/solib-svr4.c
parent9ff715d4c2c05fd51ee9adf328f77b9112ce10d2 (diff)
downloadgdb-507771e3475acbc34a276ffe1c1721124af05f66.tar.gz
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.c149
1 files changed, 65 insertions, 84 deletions
diff --git a/gdb/solib-svr4.c b/gdb/solib-svr4.c
index 554a1e31dee..2bb31a9829d 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)
{