From e4cd0d6a2669159e399359ff2cb59dd93668f056 Mon Sep 17 00:00:00 2001 From: Mark Kettenis Date: Thu, 2 Feb 2006 22:15:01 +0000 Subject: [PATCH] * solib-svr4.h (struct link_map_offsets): Remove r_debug_size and r_map_size members. Add r_version_offset, r_version_size and r_ldsomap_offset members. * solib-svr4.c (solib_svr4_r_map): Renamed from fetch_link_map_member. Simplify using read_memory_typed_address. (solib_svr4_r_ldsomap): New function. (open_symbol_file_object): Use solib_svr_r_map. (svr4_current_sos): Use solib_svr4_r_map and look for the dynamic linker by using solib_svr4_r_ldsomap. (svr4_ilp32_fetch_link_map_offsets) (svr4_lp64_fetch_link_map_offsets): Adjust for changes to `struct link_map_offsets'. * solib-legacy.c (legacy_svr4_fetch_link_map_offsets): Adjust for changes to `struct link_map_offsets'. * mipsnbsd-tdep.c (mipsnbsd_ilp32_fetch_link_map_offsets) (mipsnbsd_lp64_fetch_link_map_offsets): Adjust for changes to `struct link_map_offsets'. --- gdb/ChangeLog | 20 +++++++++ gdb/mipsnbsd-tdep.c | 33 +++++++-------- gdb/solib-legacy.c | 15 +++---- gdb/solib-svr4.c | 98 ++++++++++++++++++++++++--------------------- gdb/solib-svr4.h | 13 +++--- 5 files changed, 103 insertions(+), 76 deletions(-) diff --git a/gdb/ChangeLog b/gdb/ChangeLog index 468e8bb88b..a419107acf 100644 --- a/gdb/ChangeLog +++ b/gdb/ChangeLog @@ -1,3 +1,23 @@ +2006-02-02 Mark Kettenis + + * solib-svr4.h (struct link_map_offsets): Remove r_debug_size and + r_map_size members. Add r_version_offset, r_version_size and + r_ldsomap_offset members. + * solib-svr4.c (solib_svr4_r_map): Renamed from + fetch_link_map_member. Simplify using read_memory_typed_address. + (solib_svr4_r_ldsomap): New function. + (open_symbol_file_object): Use solib_svr_r_map. + (svr4_current_sos): Use solib_svr4_r_map and look for the dynamic + linker by using solib_svr4_r_ldsomap. + (svr4_ilp32_fetch_link_map_offsets) + (svr4_lp64_fetch_link_map_offsets): Adjust for changes to `struct + link_map_offsets'. + * solib-legacy.c (legacy_svr4_fetch_link_map_offsets): Adjust for + changes to `struct link_map_offsets'. + * mipsnbsd-tdep.c (mipsnbsd_ilp32_fetch_link_map_offsets) + (mipsnbsd_lp64_fetch_link_map_offsets): Adjust for changes to + `struct link_map_offsets'. + 2006-02-01 Daniel Jacobowitz * linux-nat.c (struct saved_ptids, threads_to_delete) diff --git a/gdb/mipsnbsd-tdep.c b/gdb/mipsnbsd-tdep.c index d878bcec07..dfdc01d8b9 100644 --- a/gdb/mipsnbsd-tdep.c +++ b/gdb/mipsnbsd-tdep.c @@ -1,6 +1,7 @@ /* Target-dependent code for NetBSD/mips. - Copyright (C) 2002, 2003, 2004 Free Software Foundation, Inc. + Copyright (C) 2002, 2003, 2004, 2006 Free Software Foundation, Inc. + Contributed by Wasabi Systems, Inc. This file is part of GDB. @@ -327,21 +328,21 @@ mipsnbsd_ilp32_fetch_link_map_offsets (void) { lmp = &lmo; - /* Everything we need is in the first 8 bytes. */ - lmo.r_debug_size = 8; + lmo.r_version_offset = 0; + lmo.r_version_size = 4; lmo.r_map_offset = 4; - lmo.r_map_size = 4; + lmo.r_ldsomap_offset = -1; /* Everything we need is in the first 24 bytes. */ lmo.link_map_size = 24; lmo.l_addr_offset = 4; - lmo.l_addr_size = 4; + lmo.l_addr_size = 4; lmo.l_name_offset = 8; - lmo.l_name_size = 4; + lmo.l_name_size = 4; lmo.l_next_offset = 16; - lmo.l_next_size = 4; + lmo.l_next_size = 4; lmo.l_prev_offset = 20; - lmo.l_prev_size = 4; + lmo.l_prev_size = 4; } return lmp; @@ -357,21 +358,21 @@ mipsnbsd_lp64_fetch_link_map_offsets (void) { lmp = &lmo; - /* Everything we need is in the first 16 bytes. */ - lmo.r_debug_size = 16; - lmo.r_map_offset = 8; - lmo.r_map_size = 8; + lmo.r_version_offset = 0; + lmo.r_version_size = 4; + lmo.r_map_offset = 8; + lmo.r_ldsomap_offset = -1; /* Everything we need is in the first 40 bytes. */ lmo.link_map_size = 48; lmo.l_addr_offset = 0; - lmo.l_addr_size = 8; + lmo.l_addr_size = 8; lmo.l_name_offset = 16; - lmo.l_name_size = 8; + lmo.l_name_size = 8; lmo.l_next_offset = 32; - lmo.l_next_size = 8; + lmo.l_next_size = 8; lmo.l_prev_offset = 40; - lmo.l_prev_size = 8; + lmo.l_prev_size = 8; } return lmp; diff --git a/gdb/solib-legacy.c b/gdb/solib-legacy.c index 237df349d0..6789993326 100644 --- a/gdb/solib-legacy.c +++ b/gdb/solib-legacy.c @@ -1,5 +1,6 @@ /* Provide legacy r_debug and link_map support for SVR4-like native targets. - Copyright (C) 2000, 2001 + + Copyright (C) 2000, 2001, 2006 Free Software Foundation, Inc. This file is part of GDB. @@ -55,10 +56,10 @@ legacy_svr4_fetch_link_map_offsets (void) lmp = &lmo; #ifdef HAVE_STRUCT_LINK_MAP_WITH_L_MEMBERS - lmo.r_debug_size = sizeof (struct r_debug); - + lmo.r_version_offset = offsetof (struct r_debug, r_version); + lmo.r_version_size = fieldsize (struct r_debug, r_version); lmo.r_map_offset = offsetof (struct r_debug, r_map); - lmo.r_map_size = fieldsize (struct r_debug, r_map); + lmo.r_ldsomap_offset = -1; lmo.link_map_size = sizeof (struct link_map); @@ -107,10 +108,10 @@ legacy_svr4_fetch_link_map_offsets (void) { lmp32 = &lmo32; - lmo32.r_debug_size = sizeof (struct r_debug32); - + lmo32.r_version_offset = offsetof (struct r_debug32, r_version); + lmo32.r_version_size = fieldsize (struct r_debug32, r_version); lmo32.r_map_offset = offsetof (struct r_debug32, r_map); - lmo32.r_map_size = fieldsize (struct r_debug32, r_map); + lmo32.r_ldsomap_offset = -1; lmo32.link_map_size = sizeof (struct link_map32); diff --git a/gdb/solib-svr4.c b/gdb/solib-svr4.c index 0a19b4a78f..caadb4a26d 100644 --- a/gdb/solib-svr4.c +++ b/gdb/solib-svr4.c @@ -1,7 +1,7 @@ /* Handle SVR4 shared libraries for GDB, the GNU Debugger. Copyright (C) 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1998, 1999, - 2000, 2001, 2003, 2004, 2005 + 2000, 2001, 2003, 2004, 2005, 2006 Free Software Foundation, Inc. This file is part of GDB. @@ -447,43 +447,40 @@ locate_base (void) return (debug_base); } -/* +/* Find the first element in the inferior's dynamic link map, and + return its address in the inferior. - LOCAL FUNCTION - - first_link_map_member -- locate first member in dynamic linker's map - - SYNOPSIS - - static CORE_ADDR first_link_map_member (void) - - DESCRIPTION - - Find the first element in the inferior's dynamic link map, and - return its address in the inferior. This function doesn't copy the - link map entry itself into our address space; current_sos actually - does the reading. */ + FIXME: Perhaps we should validate the info somehow, perhaps by + checking r_version for a known version number, or r_state for + RT_CONSISTENT. */ static CORE_ADDR -first_link_map_member (void) +solib_svr4_r_map (void) { - CORE_ADDR lm = 0; struct link_map_offsets *lmo = svr4_fetch_link_map_offsets (); - gdb_byte *r_map_buf = xmalloc (lmo->r_map_size); - struct cleanup *cleanups = make_cleanup (xfree, r_map_buf); - read_memory (debug_base + lmo->r_map_offset, r_map_buf, lmo->r_map_size); + return read_memory_typed_address (debug_base + lmo->r_map_offset, + builtin_type_void_data_ptr); +} - /* Assume that the address is unsigned. */ - lm = extract_unsigned_integer (r_map_buf, lmo->r_map_size); +/* Find the link map for the dynamic linker (if it is not in the + normal list of loaded shared objects). */ - /* FIXME: Perhaps we should validate the info somehow, perhaps by - checking r_version for a known version number, or r_state for - RT_CONSISTENT. */ +static CORE_ADDR +solib_svr4_r_ldsomap (void) +{ + struct link_map_offsets *lmo = svr4_fetch_link_map_offsets (); + ULONGEST version; - do_cleanups (cleanups); + /* Check version, and return zero if `struct r_debug' doesn't have + the r_ldsomap member. */ + version = read_memory_unsigned_integer (debug_base + lmo->r_version_offset, + lmo->r_version_size); + if (version < 2 || lmo->r_ldsomap_offset == -1) + return 0; - return (lm); + return read_memory_typed_address (debug_base + lmo->r_ldsomap_offset, + builtin_type_void_data_ptr); } /* @@ -527,7 +524,8 @@ open_symbol_file_object (void *from_ttyp) return 0; /* failed somehow... */ /* First link map member should be the executable. */ - if ((lm = first_link_map_member ()) == 0) + lm = solib_svr4_r_map (); + if (lm == 0) return 0; /* failed somehow... */ /* Read address of name from target memory to GDB. */ @@ -585,6 +583,7 @@ svr4_current_sos (void) CORE_ADDR lm; struct so_list *head = 0; struct so_list **link_ptr = &head; + CORE_ADDR ldsomap = 0; /* Make sure we've looked up the inferior's dynamic linker's base structure. */ @@ -600,7 +599,7 @@ svr4_current_sos (void) /* Walk the inferior's link map list, and build our list of `struct so_list' nodes. */ - lm = first_link_map_member (); + lm = solib_svr4_r_map (); while (lm) { struct link_map_offsets *lmo = svr4_fetch_link_map_offsets (); @@ -622,7 +621,7 @@ svr4_current_sos (void) 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_LINK_MAP_ENTRY (new)) + if (IGNORE_FIRST_LINK_MAP_ENTRY (new) && ldsomap == 0) free_so (new); else { @@ -656,6 +655,13 @@ svr4_current_sos (void) } } + /* On Solaris, the dynamic linker is not in the normal list of + shared objects, so make sure we pick it up too. Having + symbol information for the dynamic linker is quite crucial + for skipping dynamic linker resolver code. */ + if (lm == 0 && ldsomap == 0) + lm = ldsomap = solib_svr4_r_ldsomap (); + discard_cleanups (old_chain); } @@ -677,7 +683,7 @@ svr4_fetch_objfile_link_map (struct objfile *objfile) return 0; /* failed somehow... */ /* Position ourselves on the first link map. */ - lm = first_link_map_member (); + lm = solib_svr4_r_map (); while (lm) { /* Get info on the layout of the r_debug and link_map structures. */ @@ -1345,21 +1351,21 @@ svr4_ilp32_fetch_link_map_offsets (void) { lmp = &lmo; - /* Everything we need is in the first 8 bytes. */ - lmo.r_debug_size = 8; + lmo.r_version_offset = 0; + lmo.r_version_size = 4; lmo.r_map_offset = 4; - lmo.r_map_size = 4; + lmo.r_ldsomap_offset = 20; /* Everything we need is in the first 20 bytes. */ lmo.link_map_size = 20; lmo.l_addr_offset = 0; - lmo.l_addr_size = 4; + lmo.l_addr_size = 4; lmo.l_name_offset = 4; - lmo.l_name_size = 4; + lmo.l_name_size = 4; lmo.l_next_offset = 12; - lmo.l_next_size = 4; + lmo.l_next_size = 4; lmo.l_prev_offset = 16; - lmo.l_prev_size = 4; + lmo.l_prev_size = 4; } return lmp; @@ -1378,21 +1384,21 @@ svr4_lp64_fetch_link_map_offsets (void) { lmp = &lmo; - /* Everything we need is in the first 16 bytes. */ - lmo.r_debug_size = 16; + lmo.r_version_offset = 0; + lmo.r_version_size = 4; lmo.r_map_offset = 8; - lmo.r_map_size = 8; + lmo.r_ldsomap_offset = 40; /* Everything we need is in the first 40 bytes. */ lmo.link_map_size = 40; lmo.l_addr_offset = 0; - lmo.l_addr_size = 8; + lmo.l_addr_size = 8; lmo.l_name_offset = 8; - lmo.l_name_size = 8; + lmo.l_name_size = 8; lmo.l_next_offset = 24; - lmo.l_next_size = 8; + lmo.l_next_size = 8; lmo.l_prev_offset = 32; - lmo.l_prev_size = 8; + lmo.l_prev_size = 8; } return lmp; diff --git a/gdb/solib-svr4.h b/gdb/solib-svr4.h index 082b3e25fe..ae2740e0de 100644 --- a/gdb/solib-svr4.h +++ b/gdb/solib-svr4.h @@ -1,6 +1,6 @@ /* Handle shared libraries for GDB, the GNU Debugger. - Copyright (C) 2000, 2004 + Copyright (C) 2000, 2004, 2006 Free Software Foundation, Inc. This file is part of GDB. @@ -31,15 +31,14 @@ struct objfile; struct link_map_offsets { - /* Size of struct r_debug (or equivalent), or at least enough of it to - be able to obtain the r_map field. */ - int r_debug_size; + /* Offset and size of r_debug.r_version. */ + int r_version_offset, r_version_size; - /* Offset to the r_map field in struct r_debug. */ + /* Offset of r_debug.r_map. */ int r_map_offset; - /* Size of the r_map field in struct r_debug. */ - int r_map_size; + /* Offset of r_debug.r_ldsomap. */ + int r_ldsomap_offset; /* Size of struct link_map (or equivalent), or at least enough of it to be able to obtain the fields below. */