X-Git-Url: http://drtracing.org/?a=blobdiff_plain;f=gdb%2Fsolib-svr4.c;h=e2026388860ba18ff32ec1a1ec9aeb592ddcb227;hb=513f590324f1b11a36acbad0ebf40f800f5e52f7;hp=828ec7c316896b6ccbef4fc58b4cfe86f61423d3;hpb=9f76c2cd1768b3125949139c0c9a745a5ec5205b;p=deliverable%2Fbinutils-gdb.git diff --git a/gdb/solib-svr4.c b/gdb/solib-svr4.c index 828ec7c316..e202638886 100644 --- a/gdb/solib-svr4.c +++ b/gdb/solib-svr4.c @@ -1,8 +1,7 @@ /* Handle SVR4 shared libraries for GDB, the GNU Debugger. - Copyright 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1998, 1999, - 2000, 2001, 2003, 2004, 2005 - Free Software Foundation, Inc. + Copyright (C) 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000, + 2001, 2003, 2004, 2005, 2006, 2007 Free Software Foundation, Inc. This file is part of GDB. @@ -18,8 +17,8 @@ You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place - Suite 330, - Boston, MA 02111-1307, USA. */ + Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. */ #include "defs.h" @@ -38,9 +37,11 @@ #include "gdb_assert.h" #include "solist.h" +#include "solib.h" #include "solib-svr4.h" #include "bfd-target.h" +#include "elf-bfd.h" #include "exec.h" static struct link_map_offsets *svr4_fetch_link_map_offsets (void); @@ -58,6 +59,13 @@ struct lm_info 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; }; /* On SVR4 systems, a list of symbols in the dynamic linker where @@ -110,28 +118,102 @@ static char *main_name_list[] = NULL }; -/* Macro to extract an address from a solib structure. When GDB is - configured for some 32-bit targets (e.g. Solaris 2.7 sparc), BFD is - configured to handle 64-bit targets, so CORE_ADDR is 64 bits. We - have to extract only the significant bits of addresses to get the - right address when accessing the core file BFD. +/* link map access functions */ - Assume that the address is unsigned. */ +static CORE_ADDR +LM_ADDR_FROM_LINK_MAP (struct so_list *so) +{ + struct link_map_offsets *lmo = svr4_fetch_link_map_offsets (); -#define SOLIB_EXTRACT_ADDRESS(MEMBER) \ - extract_unsigned_integer (&(MEMBER), sizeof (MEMBER)) + return extract_typed_address (so->lm_info->lm + lmo->l_addr_offset, + builtin_type_void_data_ptr); +} -/* local data declarations */ +static int +HAS_LM_DYNAMIC_FROM_LINK_MAP () +{ + struct link_map_offsets *lmo = svr4_fetch_link_map_offsets (); -/* link map access functions */ + return lmo->l_ld_offset >= 0; +} static CORE_ADDR -LM_ADDR (struct so_list *so) +LM_DYNAMIC_FROM_LINK_MAP (struct so_list *so) { struct link_map_offsets *lmo = svr4_fetch_link_map_offsets (); - return (CORE_ADDR) extract_signed_integer (so->lm_info->lm + lmo->l_addr_offset, - lmo->l_addr_size); + return extract_typed_address (so->lm_info->lm + lmo->l_ld_offset, + builtin_type_void_data_ptr); +} + +static CORE_ADDR +LM_ADDR_CHECK (struct so_list *so, bfd *abfd) +{ + if (so->lm_info->l_addr == (CORE_ADDR)-1) + { + struct bfd_section *dyninfo_sect; + CORE_ADDR l_addr, l_dynaddr, dynaddr, align = 0x1000; + + l_addr = LM_ADDR_FROM_LINK_MAP (so); + + if (! abfd || ! HAS_LM_DYNAMIC_FROM_LINK_MAP ()) + goto set_addr; + + l_dynaddr = LM_DYNAMIC_FROM_LINK_MAP (so); + + dyninfo_sect = bfd_get_section_by_name (abfd, ".dynamic"); + if (dyninfo_sect == NULL) + goto set_addr; + + dynaddr = bfd_section_vma (abfd, dyninfo_sect); + + if (dynaddr + l_addr != l_dynaddr) + { + if (bfd_get_flavour (abfd) == bfd_target_elf_flavour) + { + Elf_Internal_Ehdr *ehdr = elf_tdata (abfd)->elf_header; + Elf_Internal_Phdr *phdr = elf_tdata (abfd)->phdr; + int i; + + align = 1; + + for (i = 0; i < ehdr->e_phnum; i++) + if (phdr[i].p_type == PT_LOAD && phdr[i].p_align > align) + align = phdr[i].p_align; + } + + /* Turn it into a mask. */ + align--; + + /* If the changes match the alignment requirements, we + assume we're using a core file that was generated by the + same binary, just prelinked with a different base offset. + If it doesn't match, we may have a different binary, the + same binary with the dynamic table loaded at an unrelated + location, or anything, really. To avoid regressions, + don't adjust the base offset in the latter case, although + odds are that, if things really changed, debugging won't + quite work. */ + if ((l_addr & align) == 0 && ((dynaddr - l_dynaddr) & align) == 0) + { + l_addr = l_dynaddr - dynaddr; + + warning (_(".dynamic section for \"%s\" " + "is not at the expected address"), so->so_name); + warning (_("difference appears to be caused by prelink, " + "adjusting expectations")); + } + else + warning (_(".dynamic section for \"%s\" " + "is not at the expected address " + "(wrong library or version mismatch?)"), so->so_name); + } + + set_addr: + so->lm_info->l_addr = l_addr; + } + + return so->lm_info->l_addr; } static CORE_ADDR @@ -139,9 +221,8 @@ LM_NEXT (struct so_list *so) { struct link_map_offsets *lmo = svr4_fetch_link_map_offsets (); - /* Assume that the address is unsigned. */ - return extract_unsigned_integer (so->lm_info->lm + lmo->l_next_offset, - lmo->l_next_size); + return extract_typed_address (so->lm_info->lm + lmo->l_next_offset, + builtin_type_void_data_ptr); } static CORE_ADDR @@ -149,9 +230,8 @@ LM_NAME (struct so_list *so) { struct link_map_offsets *lmo = svr4_fetch_link_map_offsets (); - /* Assume that the address is unsigned. */ - return extract_unsigned_integer (so->lm_info->lm + lmo->l_name_offset, - lmo->l_name_size); + return extract_typed_address (so->lm_info->lm + lmo->l_name_offset, + builtin_type_void_data_ptr); } static int @@ -159,13 +239,25 @@ IGNORE_FIRST_LINK_MAP_ENTRY (struct so_list *so) { struct link_map_offsets *lmo = svr4_fetch_link_map_offsets (); - /* Assume that the address is unsigned. */ - return extract_unsigned_integer (so->lm_info->lm + lmo->l_prev_offset, - lmo->l_prev_size) == 0; + /* Assume that everything is a library if the dynamic loader was loaded + late by a static executable. */ + if (bfd_get_section_by_name (exec_bfd, ".dynamic") == NULL) + return 0; + + return extract_typed_address (so->lm_info->lm + lmo->l_prev_offset, + builtin_type_void_data_ptr) == 0; } 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 */ @@ -299,7 +391,18 @@ elf_locate_base (void) /* Find the start address of the .dynamic section. */ dyninfo_sect = bfd_get_section_by_name (exec_bfd, ".dynamic"); if (dyninfo_sect == NULL) - return 0; + { + /* This may be a static executable. Look for the symbol + conventionally named _r_debug, as a last resort. */ + struct minimal_symbol *msymbol; + + msymbol = lookup_minimal_symbol ("_r_debug", NULL, symfile_objfile); + if (msymbol != NULL) + return SYMBOL_VALUE_ADDRESS (msymbol); + else + return 0; + } + dyninfo_addr = bfd_section_vma (exec_bfd, dyninfo_sect); /* Read in .dynamic section, silently ignore errors. */ @@ -338,7 +441,7 @@ elf_locate_base (void) else if (dyn_tag == DT_MIPS_RLD_MAP) { gdb_byte *pbuf; - int pbuf_size = TARGET_PTR_BIT / HOST_CHAR_BIT; + int pbuf_size = TYPE_LENGTH (builtin_type_void_data_ptr); pbuf = alloca (pbuf_size); /* DT_MIPS_RLD_MAP contains a pointer to the address @@ -347,7 +450,7 @@ elf_locate_base (void) (bfd_byte *) x_dynp->d_un.d_ptr); if (target_read_memory (dyn_ptr, pbuf, pbuf_size)) return 0; - return extract_unsigned_integer (pbuf, pbuf_size); + return extract_typed_address (pbuf, builtin_type_void_data_ptr); } } } @@ -373,7 +476,7 @@ elf_locate_base (void) else if (dyn_tag == DT_MIPS_RLD_MAP) { gdb_byte *pbuf; - int pbuf_size = TARGET_PTR_BIT / HOST_CHAR_BIT; + int pbuf_size = TYPE_LENGTH (builtin_type_void_data_ptr); pbuf = alloca (pbuf_size); /* DT_MIPS_RLD_MAP contains a pointer to the address @@ -382,7 +485,7 @@ elf_locate_base (void) (bfd_byte *) x_dynp->d_un.d_ptr); if (target_read_memory (dyn_ptr, pbuf, pbuf_size)) return 0; - return extract_unsigned_integer (pbuf, pbuf_size); + return extract_typed_address (pbuf, builtin_type_void_data_ptr); } } } @@ -446,43 +549,40 @@ locate_base (void) return (debug_base); } -/* - - 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. - 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); } /* @@ -515,7 +615,8 @@ open_symbol_file_object (void *from_ttyp) int errcode; int from_tty = *(int *)from_ttyp; struct link_map_offsets *lmo = svr4_fetch_link_map_offsets (); - gdb_byte *l_name_buf = xmalloc (lmo->l_name_size); + int l_name_size = TYPE_LENGTH (builtin_type_void_data_ptr); + gdb_byte *l_name_buf = xmalloc (l_name_size); struct cleanup *cleanups = make_cleanup (xfree, l_name_buf); if (symfile_objfile) @@ -526,15 +627,15 @@ 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. */ - read_memory (lm + lmo->l_name_offset, l_name_buf, lmo->l_name_size); + read_memory (lm + lmo->l_name_offset, l_name_buf, l_name_size); - /* Convert the address to host format. Assume that the address is - unsigned. */ - l_name = extract_unsigned_integer (l_name_buf, lmo->l_name_size); + /* Convert the address to host format. */ + l_name = extract_typed_address (l_name_buf, builtin_type_void_data_ptr); /* Free l_name_buf. */ do_cleanups (cleanups); @@ -559,6 +660,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 @@ -584,6 +716,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. */ @@ -594,27 +727,25 @@ 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 = first_link_map_member (); + lm = solib_svr4_r_map (); + while (lm) { struct link_map_offsets *lmo = svr4_fetch_link_map_offsets (); - struct so_list *new - = (struct so_list *) xmalloc (sizeof (struct so_list)); + struct so_list *new = XZALLOC (struct so_list); struct cleanup *old_chain = make_cleanup (xfree, new); - memset (new, 0, sizeof (*new)); - new->lm_info = xmalloc (sizeof (struct lm_info)); make_cleanup (xfree, new->lm_info); - new->lm_info->lm = xmalloc (lmo->link_map_size); + new->lm_info->l_addr = (CORE_ADDR)-1; + new->lm_info->lm = xzalloc (lmo->link_map_size); make_cleanup (xfree, new->lm_info->lm); - memset (new->lm_info->lm, 0, lmo->link_map_size); read_memory (lm, new->lm_info->lm, lmo->link_map_size); @@ -625,7 +756,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 { @@ -659,9 +790,19 @@ 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); } + if (head == NULL) + return svr4_default_sos (); + return head; } @@ -680,7 +821,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. */ @@ -690,25 +831,25 @@ svr4_fetch_objfile_link_map (struct objfile *objfile) struct lm_info objfile_lm_info; struct cleanup *old_chain; CORE_ADDR name_address; - gdb_byte *l_name_buf = xmalloc (lmo->l_name_size); + 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); /* 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 = xmalloc (lmo->link_map_size); + objfile_lm_info.lm = xzalloc (lmo->link_map_size); make_cleanup (xfree, objfile_lm_info.lm); - memset (objfile_lm_info.lm, 0, lmo->link_map_size); /* 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, lmo->l_name_size); + read_memory (lm + lmo->l_name_offset, l_name_buf, l_name_size); - /* Extract this object's name. Assume that the address is - unsigned. */ - name_address = extract_unsigned_integer (l_name_buf, lmo->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); @@ -727,10 +868,9 @@ svr4_fetch_objfile_link_map (struct objfile *objfile) return lm; } } - /* Not the file we wanted, continue checking. Assume that the - address is unsigned. */ - lm = extract_unsigned_integer (objfile_lm_info.lm + lmo->l_next_offset, - lmo->l_next_size); + /* 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); } return 0; @@ -761,7 +901,7 @@ static CORE_ADDR interp_text_sect_high; static CORE_ADDR interp_plt_sect_low; static CORE_ADDR interp_plt_sect_high; -static int +int svr4_in_dynsym_resolve_code (CORE_ADDR pc) { return ((pc >= interp_text_sect_low && pc < interp_text_sect_high) @@ -834,8 +974,6 @@ exec_entry_point (struct bfd *abfd, struct target_ops *targ) static int enable_break (void) { - int success = 0; - #ifdef BKPT_AT_SYMBOL struct minimal_symbol *msymbol; @@ -881,7 +1019,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); @@ -910,7 +1053,7 @@ enable_break (void) if (strcmp (buf, so->so_original_name) == 0) { load_addr_found = 1; - load_addr = LM_ADDR (so); + load_addr = LM_ADDR_CHECK (so, tmp_bfd); break; } so = so->next; @@ -920,8 +1063,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. */ @@ -972,14 +1121,15 @@ enable_break (void) /* For whatever reason we couldn't set a breakpoint in the dynamic linker. Warn and drop into the old code. */ bkpt_at_symbol: - warning (_("Unable to find dynamic linker breakpoint function.\nGDB will be unable to debug shared library initializers\nand track explicitly loaded dynamic code.")); + warning (_("Unable to find dynamic linker breakpoint function.\n" + "GDB will be unable to debug shared library initializers\n" + "and track explicitly loaded dynamic code.")); } - /* Scan through the list of symbols, trying to look up the symbol and - set a breakpoint there. Terminate loop when we/if we succeed. */ + /* Scan through the lists of symbols, trying to look up the symbol and + set a breakpoint there. Terminate loop when we/if we succeed. */ - breakpoint_addr = 0; - for (bkpt_namep = bkpt_names; *bkpt_namep != NULL; bkpt_namep++) + for (bkpt_namep = solib_break_names; *bkpt_namep != NULL; bkpt_namep++) { msymbol = lookup_minimal_symbol (*bkpt_namep, NULL, symfile_objfile); if ((msymbol != NULL) && (SYMBOL_VALUE_ADDRESS (msymbol) != 0)) @@ -989,12 +1139,18 @@ enable_break (void) } } - /* Nothing good happened. */ - success = 0; - + for (bkpt_namep = bkpt_names; *bkpt_namep != NULL; bkpt_namep++) + { + msymbol = lookup_minimal_symbol (*bkpt_namep, NULL, symfile_objfile); + if ((msymbol != NULL) && (SYMBOL_VALUE_ADDRESS (msymbol) != 0)) + { + create_solib_event_breakpoint (SYMBOL_VALUE_ADDRESS (msymbol)); + return 1; + } + } #endif /* BKPT_AT_SYMBOL */ - return (success); + return 0; } /* @@ -1192,17 +1348,10 @@ svr4_solib_create_inferior_hook (void) svr4_relocate_main_executable (); if (!svr4_have_link_map_offsets ()) - { - warning (_("no shared library support for this OS / ABI")); - return; - - } + return; if (!enable_break ()) - { - warning (_("shared library handler failed to enable breakpoint")); - return; - } + return; #if defined(_SCO_DS) /* SCO needs the loop below, other systems should be using the @@ -1231,6 +1380,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 @@ -1270,8 +1423,10 @@ static void svr4_relocate_section_addresses (struct so_list *so, struct section_table *sec) { - sec->addr = svr4_truncate_ptr (sec->addr + LM_ADDR (so)); - sec->endaddr = svr4_truncate_ptr (sec->endaddr + LM_ADDR (so)); + sec->addr = svr4_truncate_ptr (sec->addr + LM_ADDR_CHECK (so, + sec->bfd)); + sec->endaddr = svr4_truncate_ptr (sec->endaddr + LM_ADDR_CHECK (so, + sec->bfd)); } @@ -1349,21 +1504,18 @@ 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_name_offset = 4; - lmo.l_name_size = 4; + lmo.l_ld_offset = 8; lmo.l_next_offset = 12; - lmo.l_next_size = 4; lmo.l_prev_offset = 16; - lmo.l_prev_size = 4; } return lmp; @@ -1382,28 +1534,25 @@ 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_name_offset = 8; - lmo.l_name_size = 8; + lmo.l_ld_offset = 16; lmo.l_next_offset = 24; - lmo.l_next_size = 8; lmo.l_prev_offset = 32; - lmo.l_prev_size = 8; } return lmp; } -static struct target_so_ops svr4_so_ops; +struct target_so_ops svr4_so_ops; extern initialize_file_ftype _initialize_svr4_solib; /* -Wmissing-prototypes */