15796c8dcSSimon Schubert /* Handle SVR4 shared libraries for GDB, the GNU Debugger.
25796c8dcSSimon Schubert
3*ef5ccd6cSJohn Marino Copyright (C) 1990-2013 Free Software Foundation, Inc.
45796c8dcSSimon Schubert
55796c8dcSSimon Schubert This file is part of GDB.
65796c8dcSSimon Schubert
75796c8dcSSimon Schubert This program is free software; you can redistribute it and/or modify
85796c8dcSSimon Schubert it under the terms of the GNU General Public License as published by
95796c8dcSSimon Schubert the Free Software Foundation; either version 3 of the License, or
105796c8dcSSimon Schubert (at your option) any later version.
115796c8dcSSimon Schubert
125796c8dcSSimon Schubert This program is distributed in the hope that it will be useful,
135796c8dcSSimon Schubert but WITHOUT ANY WARRANTY; without even the implied warranty of
145796c8dcSSimon Schubert MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
155796c8dcSSimon Schubert GNU General Public License for more details.
165796c8dcSSimon Schubert
175796c8dcSSimon Schubert You should have received a copy of the GNU General Public License
185796c8dcSSimon Schubert along with this program. If not, see <http://www.gnu.org/licenses/>. */
195796c8dcSSimon Schubert
205796c8dcSSimon Schubert #include "defs.h"
215796c8dcSSimon Schubert
225796c8dcSSimon Schubert #include "elf/external.h"
235796c8dcSSimon Schubert #include "elf/common.h"
245796c8dcSSimon Schubert #include "elf/mips.h"
255796c8dcSSimon Schubert
265796c8dcSSimon Schubert #include "symtab.h"
275796c8dcSSimon Schubert #include "bfd.h"
285796c8dcSSimon Schubert #include "symfile.h"
295796c8dcSSimon Schubert #include "objfiles.h"
305796c8dcSSimon Schubert #include "gdbcore.h"
315796c8dcSSimon Schubert #include "target.h"
325796c8dcSSimon Schubert #include "inferior.h"
335796c8dcSSimon Schubert #include "regcache.h"
345796c8dcSSimon Schubert #include "gdbthread.h"
355796c8dcSSimon Schubert #include "observer.h"
365796c8dcSSimon Schubert
375796c8dcSSimon Schubert #include "gdb_assert.h"
385796c8dcSSimon Schubert
395796c8dcSSimon Schubert #include "solist.h"
405796c8dcSSimon Schubert #include "solib.h"
415796c8dcSSimon Schubert #include "solib-svr4.h"
425796c8dcSSimon Schubert
435796c8dcSSimon Schubert #include "bfd-target.h"
445796c8dcSSimon Schubert #include "elf-bfd.h"
455796c8dcSSimon Schubert #include "exec.h"
465796c8dcSSimon Schubert #include "auxv.h"
475796c8dcSSimon Schubert #include "exceptions.h"
48*ef5ccd6cSJohn Marino #include "gdb_bfd.h"
495796c8dcSSimon Schubert
505796c8dcSSimon Schubert static struct link_map_offsets *svr4_fetch_link_map_offsets (void);
515796c8dcSSimon Schubert static int svr4_have_link_map_offsets (void);
52cf7f2e2dSJohn Marino static void svr4_relocate_main_executable (void);
535796c8dcSSimon Schubert
54c50c785cSJohn Marino /* Link map info to include in an allocated so_list entry. */
555796c8dcSSimon Schubert
565796c8dcSSimon Schubert struct lm_info
575796c8dcSSimon Schubert {
585796c8dcSSimon Schubert /* Amount by which addresses in the binary should be relocated to
59a45ae5f8SJohn Marino match the inferior. The direct inferior value is L_ADDR_INFERIOR.
60a45ae5f8SJohn Marino When prelinking is involved and the prelink base address changes,
61a45ae5f8SJohn Marino we may need a different offset - the recomputed offset is in L_ADDR.
62a45ae5f8SJohn Marino It is commonly the same value. It is cached as we want to warn about
63a45ae5f8SJohn Marino the difference and compute it only once. L_ADDR is valid
64a45ae5f8SJohn Marino iff L_ADDR_P. */
65a45ae5f8SJohn Marino CORE_ADDR l_addr, l_addr_inferior;
66a45ae5f8SJohn Marino unsigned int l_addr_p : 1;
675796c8dcSSimon Schubert
685796c8dcSSimon Schubert /* The target location of lm. */
695796c8dcSSimon Schubert CORE_ADDR lm_addr;
70a45ae5f8SJohn Marino
71a45ae5f8SJohn Marino /* Values read in from inferior's fields of the same name. */
72a45ae5f8SJohn Marino CORE_ADDR l_ld, l_next, l_prev, l_name;
735796c8dcSSimon Schubert };
745796c8dcSSimon Schubert
755796c8dcSSimon Schubert /* On SVR4 systems, a list of symbols in the dynamic linker where
765796c8dcSSimon Schubert GDB can try to place a breakpoint to monitor shared library
775796c8dcSSimon Schubert events.
785796c8dcSSimon Schubert
795796c8dcSSimon Schubert If none of these symbols are found, or other errors occur, then
805796c8dcSSimon Schubert SVR4 systems will fall back to using a symbol as the "startup
815796c8dcSSimon Schubert mapping complete" breakpoint address. */
825796c8dcSSimon Schubert
83c50c785cSJohn Marino static const char * const solib_break_names[] =
845796c8dcSSimon Schubert {
855796c8dcSSimon Schubert "r_debug_state",
865796c8dcSSimon Schubert "_r_debug_state",
875796c8dcSSimon Schubert "_dl_debug_state",
885796c8dcSSimon Schubert "rtld_db_dlactivity",
89cf7f2e2dSJohn Marino "__dl_rtld_db_dlactivity",
905796c8dcSSimon Schubert "_rtld_debug_state",
915796c8dcSSimon Schubert
925796c8dcSSimon Schubert NULL
935796c8dcSSimon Schubert };
945796c8dcSSimon Schubert
95c50c785cSJohn Marino static const char * const bkpt_names[] =
965796c8dcSSimon Schubert {
975796c8dcSSimon Schubert "_start",
985796c8dcSSimon Schubert "__start",
995796c8dcSSimon Schubert "main",
1005796c8dcSSimon Schubert NULL
1015796c8dcSSimon Schubert };
1025796c8dcSSimon Schubert
103c50c785cSJohn Marino static const char * const main_name_list[] =
1045796c8dcSSimon Schubert {
1055796c8dcSSimon Schubert "main_$main",
1065796c8dcSSimon Schubert NULL
1075796c8dcSSimon Schubert };
1085796c8dcSSimon Schubert
1095796c8dcSSimon Schubert /* Return non-zero if GDB_SO_NAME and INFERIOR_SO_NAME represent
1105796c8dcSSimon Schubert the same shared library. */
1115796c8dcSSimon Schubert
1125796c8dcSSimon Schubert static int
svr4_same_1(const char * gdb_so_name,const char * inferior_so_name)1135796c8dcSSimon Schubert svr4_same_1 (const char *gdb_so_name, const char *inferior_so_name)
1145796c8dcSSimon Schubert {
1155796c8dcSSimon Schubert if (strcmp (gdb_so_name, inferior_so_name) == 0)
1165796c8dcSSimon Schubert return 1;
1175796c8dcSSimon Schubert
1185796c8dcSSimon Schubert /* On Solaris, when starting inferior we think that dynamic linker is
1195796c8dcSSimon Schubert /usr/lib/ld.so.1, but later on, the table of loaded shared libraries
1205796c8dcSSimon Schubert contains /lib/ld.so.1. Sometimes one file is a link to another, but
1215796c8dcSSimon Schubert sometimes they have identical content, but are not linked to each
1225796c8dcSSimon Schubert other. We don't restrict this check for Solaris, but the chances
1235796c8dcSSimon Schubert of running into this situation elsewhere are very low. */
1245796c8dcSSimon Schubert if (strcmp (gdb_so_name, "/usr/lib/ld.so.1") == 0
1255796c8dcSSimon Schubert && strcmp (inferior_so_name, "/lib/ld.so.1") == 0)
1265796c8dcSSimon Schubert return 1;
1275796c8dcSSimon Schubert
1285796c8dcSSimon Schubert /* Similarly, we observed the same issue with sparc64, but with
1295796c8dcSSimon Schubert different locations. */
1305796c8dcSSimon Schubert if (strcmp (gdb_so_name, "/usr/lib/sparcv9/ld.so.1") == 0
1315796c8dcSSimon Schubert && strcmp (inferior_so_name, "/lib/sparcv9/ld.so.1") == 0)
1325796c8dcSSimon Schubert return 1;
1335796c8dcSSimon Schubert
1345796c8dcSSimon Schubert return 0;
1355796c8dcSSimon Schubert }
1365796c8dcSSimon Schubert
1375796c8dcSSimon Schubert static int
svr4_same(struct so_list * gdb,struct so_list * inferior)1385796c8dcSSimon Schubert svr4_same (struct so_list *gdb, struct so_list *inferior)
1395796c8dcSSimon Schubert {
1405796c8dcSSimon Schubert return (svr4_same_1 (gdb->so_original_name, inferior->so_original_name));
1415796c8dcSSimon Schubert }
1425796c8dcSSimon Schubert
143a45ae5f8SJohn Marino static struct lm_info *
lm_info_read(CORE_ADDR lm_addr)144a45ae5f8SJohn Marino lm_info_read (CORE_ADDR lm_addr)
1455796c8dcSSimon Schubert {
1465796c8dcSSimon Schubert struct link_map_offsets *lmo = svr4_fetch_link_map_offsets ();
147a45ae5f8SJohn Marino gdb_byte *lm;
148a45ae5f8SJohn Marino struct lm_info *lm_info;
149a45ae5f8SJohn Marino struct cleanup *back_to;
150a45ae5f8SJohn Marino
151a45ae5f8SJohn Marino lm = xmalloc (lmo->link_map_size);
152a45ae5f8SJohn Marino back_to = make_cleanup (xfree, lm);
153a45ae5f8SJohn Marino
154a45ae5f8SJohn Marino if (target_read_memory (lm_addr, lm, lmo->link_map_size) != 0)
155a45ae5f8SJohn Marino {
156a45ae5f8SJohn Marino warning (_("Error reading shared library list entry at %s"),
157*ef5ccd6cSJohn Marino paddress (target_gdbarch (), lm_addr)),
158a45ae5f8SJohn Marino lm_info = NULL;
159a45ae5f8SJohn Marino }
160a45ae5f8SJohn Marino else
161a45ae5f8SJohn Marino {
162*ef5ccd6cSJohn Marino struct type *ptr_type = builtin_type (target_gdbarch ())->builtin_data_ptr;
1635796c8dcSSimon Schubert
164a45ae5f8SJohn Marino lm_info = xzalloc (sizeof (*lm_info));
165a45ae5f8SJohn Marino lm_info->lm_addr = lm_addr;
166a45ae5f8SJohn Marino
167a45ae5f8SJohn Marino lm_info->l_addr_inferior = extract_typed_address (&lm[lmo->l_addr_offset],
168a45ae5f8SJohn Marino ptr_type);
169a45ae5f8SJohn Marino lm_info->l_ld = extract_typed_address (&lm[lmo->l_ld_offset], ptr_type);
170a45ae5f8SJohn Marino lm_info->l_next = extract_typed_address (&lm[lmo->l_next_offset],
171a45ae5f8SJohn Marino ptr_type);
172a45ae5f8SJohn Marino lm_info->l_prev = extract_typed_address (&lm[lmo->l_prev_offset],
173a45ae5f8SJohn Marino ptr_type);
174a45ae5f8SJohn Marino lm_info->l_name = extract_typed_address (&lm[lmo->l_name_offset],
1755796c8dcSSimon Schubert ptr_type);
1765796c8dcSSimon Schubert }
1775796c8dcSSimon Schubert
178a45ae5f8SJohn Marino do_cleanups (back_to);
179a45ae5f8SJohn Marino
180a45ae5f8SJohn Marino return lm_info;
181a45ae5f8SJohn Marino }
182a45ae5f8SJohn Marino
1835796c8dcSSimon Schubert static int
has_lm_dynamic_from_link_map(void)184a45ae5f8SJohn Marino has_lm_dynamic_from_link_map (void)
1855796c8dcSSimon Schubert {
1865796c8dcSSimon Schubert struct link_map_offsets *lmo = svr4_fetch_link_map_offsets ();
1875796c8dcSSimon Schubert
1885796c8dcSSimon Schubert return lmo->l_ld_offset >= 0;
1895796c8dcSSimon Schubert }
1905796c8dcSSimon Schubert
1915796c8dcSSimon Schubert static CORE_ADDR
lm_addr_check(struct so_list * so,bfd * abfd)192a45ae5f8SJohn Marino lm_addr_check (struct so_list *so, bfd *abfd)
1935796c8dcSSimon Schubert {
194a45ae5f8SJohn Marino if (!so->lm_info->l_addr_p)
1955796c8dcSSimon Schubert {
1965796c8dcSSimon Schubert struct bfd_section *dyninfo_sect;
197cf7f2e2dSJohn Marino CORE_ADDR l_addr, l_dynaddr, dynaddr;
1985796c8dcSSimon Schubert
199a45ae5f8SJohn Marino l_addr = so->lm_info->l_addr_inferior;
2005796c8dcSSimon Schubert
201a45ae5f8SJohn Marino if (! abfd || ! has_lm_dynamic_from_link_map ())
2025796c8dcSSimon Schubert goto set_addr;
2035796c8dcSSimon Schubert
204a45ae5f8SJohn Marino l_dynaddr = so->lm_info->l_ld;
2055796c8dcSSimon Schubert
2065796c8dcSSimon Schubert dyninfo_sect = bfd_get_section_by_name (abfd, ".dynamic");
2075796c8dcSSimon Schubert if (dyninfo_sect == NULL)
2085796c8dcSSimon Schubert goto set_addr;
2095796c8dcSSimon Schubert
2105796c8dcSSimon Schubert dynaddr = bfd_section_vma (abfd, dyninfo_sect);
2115796c8dcSSimon Schubert
2125796c8dcSSimon Schubert if (dynaddr + l_addr != l_dynaddr)
2135796c8dcSSimon Schubert {
214cf7f2e2dSJohn Marino CORE_ADDR align = 0x1000;
215cf7f2e2dSJohn Marino CORE_ADDR minpagesize = align;
216cf7f2e2dSJohn Marino
2175796c8dcSSimon Schubert if (bfd_get_flavour (abfd) == bfd_target_elf_flavour)
2185796c8dcSSimon Schubert {
2195796c8dcSSimon Schubert Elf_Internal_Ehdr *ehdr = elf_tdata (abfd)->elf_header;
2205796c8dcSSimon Schubert Elf_Internal_Phdr *phdr = elf_tdata (abfd)->phdr;
2215796c8dcSSimon Schubert int i;
2225796c8dcSSimon Schubert
2235796c8dcSSimon Schubert align = 1;
2245796c8dcSSimon Schubert
2255796c8dcSSimon Schubert for (i = 0; i < ehdr->e_phnum; i++)
2265796c8dcSSimon Schubert if (phdr[i].p_type == PT_LOAD && phdr[i].p_align > align)
2275796c8dcSSimon Schubert align = phdr[i].p_align;
228cf7f2e2dSJohn Marino
229cf7f2e2dSJohn Marino minpagesize = get_elf_backend_data (abfd)->minpagesize;
2305796c8dcSSimon Schubert }
2315796c8dcSSimon Schubert
2325796c8dcSSimon Schubert /* Turn it into a mask. */
2335796c8dcSSimon Schubert align--;
2345796c8dcSSimon Schubert
2355796c8dcSSimon Schubert /* If the changes match the alignment requirements, we
2365796c8dcSSimon Schubert assume we're using a core file that was generated by the
2375796c8dcSSimon Schubert same binary, just prelinked with a different base offset.
2385796c8dcSSimon Schubert If it doesn't match, we may have a different binary, the
2395796c8dcSSimon Schubert same binary with the dynamic table loaded at an unrelated
2405796c8dcSSimon Schubert location, or anything, really. To avoid regressions,
2415796c8dcSSimon Schubert don't adjust the base offset in the latter case, although
2425796c8dcSSimon Schubert odds are that, if things really changed, debugging won't
243cf7f2e2dSJohn Marino quite work.
244cf7f2e2dSJohn Marino
245cf7f2e2dSJohn Marino One could expect more the condition
246cf7f2e2dSJohn Marino ((l_addr & align) == 0 && ((l_dynaddr - dynaddr) & align) == 0)
247cf7f2e2dSJohn Marino but the one below is relaxed for PPC. The PPC kernel supports
248cf7f2e2dSJohn Marino either 4k or 64k page sizes. To be prepared for 64k pages,
249cf7f2e2dSJohn Marino PPC ELF files are built using an alignment requirement of 64k.
250cf7f2e2dSJohn Marino However, when running on a kernel supporting 4k pages, the memory
251cf7f2e2dSJohn Marino mapping of the library may not actually happen on a 64k boundary!
252cf7f2e2dSJohn Marino
253cf7f2e2dSJohn Marino (In the usual case where (l_addr & align) == 0, this check is
254cf7f2e2dSJohn Marino equivalent to the possibly expected check above.)
255cf7f2e2dSJohn Marino
256cf7f2e2dSJohn Marino Even on PPC it must be zero-aligned at least for MINPAGESIZE. */
257cf7f2e2dSJohn Marino
258a45ae5f8SJohn Marino l_addr = l_dynaddr - dynaddr;
259a45ae5f8SJohn Marino
260cf7f2e2dSJohn Marino if ((l_addr & (minpagesize - 1)) == 0
261cf7f2e2dSJohn Marino && (l_addr & align) == ((l_dynaddr - dynaddr) & align))
2625796c8dcSSimon Schubert {
263cf7f2e2dSJohn Marino if (info_verbose)
264cf7f2e2dSJohn Marino printf_unfiltered (_("Using PIC (Position Independent Code) "
265cf7f2e2dSJohn Marino "prelink displacement %s for \"%s\".\n"),
266*ef5ccd6cSJohn Marino paddress (target_gdbarch (), l_addr),
267cf7f2e2dSJohn Marino so->so_name);
2685796c8dcSSimon Schubert }
2695796c8dcSSimon Schubert else
270a45ae5f8SJohn Marino {
271a45ae5f8SJohn Marino /* There is no way to verify the library file matches. prelink
272a45ae5f8SJohn Marino can during prelinking of an unprelinked file (or unprelinking
273a45ae5f8SJohn Marino of a prelinked file) shift the DYNAMIC segment by arbitrary
274a45ae5f8SJohn Marino offset without any page size alignment. There is no way to
275a45ae5f8SJohn Marino find out the ELF header and/or Program Headers for a limited
276a45ae5f8SJohn Marino verification if it they match. One could do a verification
277a45ae5f8SJohn Marino of the DYNAMIC segment. Still the found address is the best
278a45ae5f8SJohn Marino one GDB could find. */
279a45ae5f8SJohn Marino
2805796c8dcSSimon Schubert warning (_(".dynamic section for \"%s\" "
2815796c8dcSSimon Schubert "is not at the expected address "
2825796c8dcSSimon Schubert "(wrong library or version mismatch?)"), so->so_name);
2835796c8dcSSimon Schubert }
284a45ae5f8SJohn Marino }
2855796c8dcSSimon Schubert
2865796c8dcSSimon Schubert set_addr:
2875796c8dcSSimon Schubert so->lm_info->l_addr = l_addr;
288a45ae5f8SJohn Marino so->lm_info->l_addr_p = 1;
2895796c8dcSSimon Schubert }
2905796c8dcSSimon Schubert
2915796c8dcSSimon Schubert return so->lm_info->l_addr;
2925796c8dcSSimon Schubert }
2935796c8dcSSimon Schubert
294cf7f2e2dSJohn Marino /* Per pspace SVR4 specific data. */
2955796c8dcSSimon Schubert
2965796c8dcSSimon Schubert struct svr4_info
2975796c8dcSSimon Schubert {
298c50c785cSJohn Marino CORE_ADDR debug_base; /* Base of dynamic linker structures. */
2995796c8dcSSimon Schubert
3005796c8dcSSimon Schubert /* Validity flag for debug_loader_offset. */
3015796c8dcSSimon Schubert int debug_loader_offset_p;
3025796c8dcSSimon Schubert
3035796c8dcSSimon Schubert /* Load address for the dynamic linker, inferred. */
3045796c8dcSSimon Schubert CORE_ADDR debug_loader_offset;
3055796c8dcSSimon Schubert
3065796c8dcSSimon Schubert /* Name of the dynamic linker, valid if debug_loader_offset_p. */
3075796c8dcSSimon Schubert char *debug_loader_name;
3085796c8dcSSimon Schubert
3095796c8dcSSimon Schubert /* Load map address for the main executable. */
3105796c8dcSSimon Schubert CORE_ADDR main_lm_addr;
311cf7f2e2dSJohn Marino
312cf7f2e2dSJohn Marino CORE_ADDR interp_text_sect_low;
313cf7f2e2dSJohn Marino CORE_ADDR interp_text_sect_high;
314cf7f2e2dSJohn Marino CORE_ADDR interp_plt_sect_low;
315cf7f2e2dSJohn Marino CORE_ADDR interp_plt_sect_high;
3165796c8dcSSimon Schubert };
3175796c8dcSSimon Schubert
318cf7f2e2dSJohn Marino /* Per-program-space data key. */
319cf7f2e2dSJohn Marino static const struct program_space_data *solib_svr4_pspace_data;
3205796c8dcSSimon Schubert
3215796c8dcSSimon Schubert static void
svr4_pspace_data_cleanup(struct program_space * pspace,void * arg)322cf7f2e2dSJohn Marino svr4_pspace_data_cleanup (struct program_space *pspace, void *arg)
3235796c8dcSSimon Schubert {
324cf7f2e2dSJohn Marino struct svr4_info *info;
3255796c8dcSSimon Schubert
326cf7f2e2dSJohn Marino info = program_space_data (pspace, solib_svr4_pspace_data);
327cf7f2e2dSJohn Marino xfree (info);
3285796c8dcSSimon Schubert }
3295796c8dcSSimon Schubert
330cf7f2e2dSJohn Marino /* Get the current svr4 data. If none is found yet, add it now. This
331cf7f2e2dSJohn Marino function always returns a valid object. */
3325796c8dcSSimon Schubert
333cf7f2e2dSJohn Marino static struct svr4_info *
get_svr4_info(void)334cf7f2e2dSJohn Marino get_svr4_info (void)
3355796c8dcSSimon Schubert {
336cf7f2e2dSJohn Marino struct svr4_info *info;
337cf7f2e2dSJohn Marino
338cf7f2e2dSJohn Marino info = program_space_data (current_program_space, solib_svr4_pspace_data);
339cf7f2e2dSJohn Marino if (info != NULL)
340cf7f2e2dSJohn Marino return info;
341cf7f2e2dSJohn Marino
342cf7f2e2dSJohn Marino info = XZALLOC (struct svr4_info);
343cf7f2e2dSJohn Marino set_program_space_data (current_program_space, solib_svr4_pspace_data, info);
344cf7f2e2dSJohn Marino return info;
3455796c8dcSSimon Schubert }
3465796c8dcSSimon Schubert
3475796c8dcSSimon Schubert /* Local function prototypes */
3485796c8dcSSimon Schubert
349c50c785cSJohn Marino static int match_main (const char *);
3505796c8dcSSimon Schubert
3515796c8dcSSimon Schubert /* Read program header TYPE from inferior memory. The header is found
3525796c8dcSSimon Schubert by scanning the OS auxillary vector.
3535796c8dcSSimon Schubert
354cf7f2e2dSJohn Marino If TYPE == -1, return the program headers instead of the contents of
355cf7f2e2dSJohn Marino one program header.
356cf7f2e2dSJohn Marino
3575796c8dcSSimon Schubert Return a pointer to allocated memory holding the program header contents,
3585796c8dcSSimon Schubert or NULL on failure. If sucessful, and unless P_SECT_SIZE is NULL, the
3595796c8dcSSimon Schubert size of those contents is returned to P_SECT_SIZE. Likewise, the target
3605796c8dcSSimon Schubert architecture size (32-bit or 64-bit) is returned to P_ARCH_SIZE. */
3615796c8dcSSimon Schubert
3625796c8dcSSimon Schubert static gdb_byte *
read_program_header(int type,int * p_sect_size,int * p_arch_size)3635796c8dcSSimon Schubert read_program_header (int type, int *p_sect_size, int *p_arch_size)
3645796c8dcSSimon Schubert {
365*ef5ccd6cSJohn Marino enum bfd_endian byte_order = gdbarch_byte_order (target_gdbarch ());
366a45ae5f8SJohn Marino CORE_ADDR at_phdr, at_phent, at_phnum, pt_phdr = 0;
3675796c8dcSSimon Schubert int arch_size, sect_size;
3685796c8dcSSimon Schubert CORE_ADDR sect_addr;
3695796c8dcSSimon Schubert gdb_byte *buf;
370a45ae5f8SJohn Marino int pt_phdr_p = 0;
3715796c8dcSSimon Schubert
3725796c8dcSSimon Schubert /* Get required auxv elements from target. */
3735796c8dcSSimon Schubert if (target_auxv_search (¤t_target, AT_PHDR, &at_phdr) <= 0)
3745796c8dcSSimon Schubert return 0;
3755796c8dcSSimon Schubert if (target_auxv_search (¤t_target, AT_PHENT, &at_phent) <= 0)
3765796c8dcSSimon Schubert return 0;
3775796c8dcSSimon Schubert if (target_auxv_search (¤t_target, AT_PHNUM, &at_phnum) <= 0)
3785796c8dcSSimon Schubert return 0;
3795796c8dcSSimon Schubert if (!at_phdr || !at_phnum)
3805796c8dcSSimon Schubert return 0;
3815796c8dcSSimon Schubert
3825796c8dcSSimon Schubert /* Determine ELF architecture type. */
3835796c8dcSSimon Schubert if (at_phent == sizeof (Elf32_External_Phdr))
3845796c8dcSSimon Schubert arch_size = 32;
3855796c8dcSSimon Schubert else if (at_phent == sizeof (Elf64_External_Phdr))
3865796c8dcSSimon Schubert arch_size = 64;
3875796c8dcSSimon Schubert else
3885796c8dcSSimon Schubert return 0;
3895796c8dcSSimon Schubert
390cf7f2e2dSJohn Marino /* Find the requested segment. */
391cf7f2e2dSJohn Marino if (type == -1)
392cf7f2e2dSJohn Marino {
393cf7f2e2dSJohn Marino sect_addr = at_phdr;
394cf7f2e2dSJohn Marino sect_size = at_phent * at_phnum;
395cf7f2e2dSJohn Marino }
396cf7f2e2dSJohn Marino else if (arch_size == 32)
3975796c8dcSSimon Schubert {
3985796c8dcSSimon Schubert Elf32_External_Phdr phdr;
3995796c8dcSSimon Schubert int i;
4005796c8dcSSimon Schubert
4015796c8dcSSimon Schubert /* Search for requested PHDR. */
4025796c8dcSSimon Schubert for (i = 0; i < at_phnum; i++)
4035796c8dcSSimon Schubert {
404a45ae5f8SJohn Marino int p_type;
405a45ae5f8SJohn Marino
4065796c8dcSSimon Schubert if (target_read_memory (at_phdr + i * sizeof (phdr),
4075796c8dcSSimon Schubert (gdb_byte *)&phdr, sizeof (phdr)))
4085796c8dcSSimon Schubert return 0;
4095796c8dcSSimon Schubert
410a45ae5f8SJohn Marino p_type = extract_unsigned_integer ((gdb_byte *) phdr.p_type,
411a45ae5f8SJohn Marino 4, byte_order);
412a45ae5f8SJohn Marino
413a45ae5f8SJohn Marino if (p_type == PT_PHDR)
414a45ae5f8SJohn Marino {
415a45ae5f8SJohn Marino pt_phdr_p = 1;
416a45ae5f8SJohn Marino pt_phdr = extract_unsigned_integer ((gdb_byte *) phdr.p_vaddr,
417a45ae5f8SJohn Marino 4, byte_order);
418a45ae5f8SJohn Marino }
419a45ae5f8SJohn Marino
420a45ae5f8SJohn Marino if (p_type == type)
4215796c8dcSSimon Schubert break;
4225796c8dcSSimon Schubert }
4235796c8dcSSimon Schubert
4245796c8dcSSimon Schubert if (i == at_phnum)
4255796c8dcSSimon Schubert return 0;
4265796c8dcSSimon Schubert
4275796c8dcSSimon Schubert /* Retrieve address and size. */
4285796c8dcSSimon Schubert sect_addr = extract_unsigned_integer ((gdb_byte *)phdr.p_vaddr,
4295796c8dcSSimon Schubert 4, byte_order);
4305796c8dcSSimon Schubert sect_size = extract_unsigned_integer ((gdb_byte *)phdr.p_memsz,
4315796c8dcSSimon Schubert 4, byte_order);
4325796c8dcSSimon Schubert }
4335796c8dcSSimon Schubert else
4345796c8dcSSimon Schubert {
4355796c8dcSSimon Schubert Elf64_External_Phdr phdr;
4365796c8dcSSimon Schubert int i;
4375796c8dcSSimon Schubert
4385796c8dcSSimon Schubert /* Search for requested PHDR. */
4395796c8dcSSimon Schubert for (i = 0; i < at_phnum; i++)
4405796c8dcSSimon Schubert {
441a45ae5f8SJohn Marino int p_type;
442a45ae5f8SJohn Marino
4435796c8dcSSimon Schubert if (target_read_memory (at_phdr + i * sizeof (phdr),
4445796c8dcSSimon Schubert (gdb_byte *)&phdr, sizeof (phdr)))
4455796c8dcSSimon Schubert return 0;
4465796c8dcSSimon Schubert
447a45ae5f8SJohn Marino p_type = extract_unsigned_integer ((gdb_byte *) phdr.p_type,
448a45ae5f8SJohn Marino 4, byte_order);
449a45ae5f8SJohn Marino
450a45ae5f8SJohn Marino if (p_type == PT_PHDR)
451a45ae5f8SJohn Marino {
452a45ae5f8SJohn Marino pt_phdr_p = 1;
453a45ae5f8SJohn Marino pt_phdr = extract_unsigned_integer ((gdb_byte *) phdr.p_vaddr,
454a45ae5f8SJohn Marino 8, byte_order);
455a45ae5f8SJohn Marino }
456a45ae5f8SJohn Marino
457a45ae5f8SJohn Marino if (p_type == type)
4585796c8dcSSimon Schubert break;
4595796c8dcSSimon Schubert }
4605796c8dcSSimon Schubert
4615796c8dcSSimon Schubert if (i == at_phnum)
4625796c8dcSSimon Schubert return 0;
4635796c8dcSSimon Schubert
4645796c8dcSSimon Schubert /* Retrieve address and size. */
4655796c8dcSSimon Schubert sect_addr = extract_unsigned_integer ((gdb_byte *)phdr.p_vaddr,
4665796c8dcSSimon Schubert 8, byte_order);
4675796c8dcSSimon Schubert sect_size = extract_unsigned_integer ((gdb_byte *)phdr.p_memsz,
4685796c8dcSSimon Schubert 8, byte_order);
4695796c8dcSSimon Schubert }
4705796c8dcSSimon Schubert
471a45ae5f8SJohn Marino /* PT_PHDR is optional, but we really need it
472a45ae5f8SJohn Marino for PIE to make this work in general. */
473a45ae5f8SJohn Marino
474a45ae5f8SJohn Marino if (pt_phdr_p)
475a45ae5f8SJohn Marino {
476a45ae5f8SJohn Marino /* at_phdr is real address in memory. pt_phdr is what pheader says it is.
477a45ae5f8SJohn Marino Relocation offset is the difference between the two. */
478a45ae5f8SJohn Marino sect_addr = sect_addr + (at_phdr - pt_phdr);
479a45ae5f8SJohn Marino }
480a45ae5f8SJohn Marino
4815796c8dcSSimon Schubert /* Read in requested program header. */
4825796c8dcSSimon Schubert buf = xmalloc (sect_size);
4835796c8dcSSimon Schubert if (target_read_memory (sect_addr, buf, sect_size))
4845796c8dcSSimon Schubert {
4855796c8dcSSimon Schubert xfree (buf);
4865796c8dcSSimon Schubert return NULL;
4875796c8dcSSimon Schubert }
4885796c8dcSSimon Schubert
4895796c8dcSSimon Schubert if (p_arch_size)
4905796c8dcSSimon Schubert *p_arch_size = arch_size;
4915796c8dcSSimon Schubert if (p_sect_size)
4925796c8dcSSimon Schubert *p_sect_size = sect_size;
4935796c8dcSSimon Schubert
4945796c8dcSSimon Schubert return buf;
4955796c8dcSSimon Schubert }
4965796c8dcSSimon Schubert
4975796c8dcSSimon Schubert
4985796c8dcSSimon Schubert /* Return program interpreter string. */
4995796c8dcSSimon Schubert static gdb_byte *
find_program_interpreter(void)5005796c8dcSSimon Schubert find_program_interpreter (void)
5015796c8dcSSimon Schubert {
5025796c8dcSSimon Schubert gdb_byte *buf = NULL;
5035796c8dcSSimon Schubert
5045796c8dcSSimon Schubert /* If we have an exec_bfd, use its section table. */
5055796c8dcSSimon Schubert if (exec_bfd
5065796c8dcSSimon Schubert && bfd_get_flavour (exec_bfd) == bfd_target_elf_flavour)
5075796c8dcSSimon Schubert {
5085796c8dcSSimon Schubert struct bfd_section *interp_sect;
5095796c8dcSSimon Schubert
5105796c8dcSSimon Schubert interp_sect = bfd_get_section_by_name (exec_bfd, ".interp");
5115796c8dcSSimon Schubert if (interp_sect != NULL)
5125796c8dcSSimon Schubert {
5135796c8dcSSimon Schubert int sect_size = bfd_section_size (exec_bfd, interp_sect);
5145796c8dcSSimon Schubert
5155796c8dcSSimon Schubert buf = xmalloc (sect_size);
5165796c8dcSSimon Schubert bfd_get_section_contents (exec_bfd, interp_sect, buf, 0, sect_size);
5175796c8dcSSimon Schubert }
5185796c8dcSSimon Schubert }
5195796c8dcSSimon Schubert
5205796c8dcSSimon Schubert /* If we didn't find it, use the target auxillary vector. */
5215796c8dcSSimon Schubert if (!buf)
5225796c8dcSSimon Schubert buf = read_program_header (PT_INTERP, NULL, NULL);
5235796c8dcSSimon Schubert
5245796c8dcSSimon Schubert return buf;
5255796c8dcSSimon Schubert }
5265796c8dcSSimon Schubert
5275796c8dcSSimon Schubert
5285796c8dcSSimon Schubert /* Scan for DYNTAG in .dynamic section of ABFD. If DYNTAG is found 1 is
5295796c8dcSSimon Schubert returned and the corresponding PTR is set. */
5305796c8dcSSimon Schubert
5315796c8dcSSimon Schubert static int
scan_dyntag(int dyntag,bfd * abfd,CORE_ADDR * ptr)5325796c8dcSSimon Schubert scan_dyntag (int dyntag, bfd *abfd, CORE_ADDR *ptr)
5335796c8dcSSimon Schubert {
5345796c8dcSSimon Schubert int arch_size, step, sect_size;
5355796c8dcSSimon Schubert long dyn_tag;
5365796c8dcSSimon Schubert CORE_ADDR dyn_ptr, dyn_addr;
5375796c8dcSSimon Schubert gdb_byte *bufend, *bufstart, *buf;
5385796c8dcSSimon Schubert Elf32_External_Dyn *x_dynp_32;
5395796c8dcSSimon Schubert Elf64_External_Dyn *x_dynp_64;
5405796c8dcSSimon Schubert struct bfd_section *sect;
541cf7f2e2dSJohn Marino struct target_section *target_section;
5425796c8dcSSimon Schubert
5435796c8dcSSimon Schubert if (abfd == NULL)
5445796c8dcSSimon Schubert return 0;
5455796c8dcSSimon Schubert
5465796c8dcSSimon Schubert if (bfd_get_flavour (abfd) != bfd_target_elf_flavour)
5475796c8dcSSimon Schubert return 0;
5485796c8dcSSimon Schubert
5495796c8dcSSimon Schubert arch_size = bfd_get_arch_size (abfd);
5505796c8dcSSimon Schubert if (arch_size == -1)
5515796c8dcSSimon Schubert return 0;
5525796c8dcSSimon Schubert
5535796c8dcSSimon Schubert /* Find the start address of the .dynamic section. */
5545796c8dcSSimon Schubert sect = bfd_get_section_by_name (abfd, ".dynamic");
5555796c8dcSSimon Schubert if (sect == NULL)
5565796c8dcSSimon Schubert return 0;
557cf7f2e2dSJohn Marino
558cf7f2e2dSJohn Marino for (target_section = current_target_sections->sections;
559cf7f2e2dSJohn Marino target_section < current_target_sections->sections_end;
560cf7f2e2dSJohn Marino target_section++)
561cf7f2e2dSJohn Marino if (sect == target_section->the_bfd_section)
562cf7f2e2dSJohn Marino break;
563cf7f2e2dSJohn Marino if (target_section < current_target_sections->sections_end)
564cf7f2e2dSJohn Marino dyn_addr = target_section->addr;
565cf7f2e2dSJohn Marino else
566cf7f2e2dSJohn Marino {
567cf7f2e2dSJohn Marino /* ABFD may come from OBJFILE acting only as a symbol file without being
568cf7f2e2dSJohn Marino loaded into the target (see add_symbol_file_command). This case is
569cf7f2e2dSJohn Marino such fallback to the file VMA address without the possibility of
570cf7f2e2dSJohn Marino having the section relocated to its actual in-memory address. */
571cf7f2e2dSJohn Marino
5725796c8dcSSimon Schubert dyn_addr = bfd_section_vma (abfd, sect);
573cf7f2e2dSJohn Marino }
5745796c8dcSSimon Schubert
5755796c8dcSSimon Schubert /* Read in .dynamic from the BFD. We will get the actual value
5765796c8dcSSimon Schubert from memory later. */
5775796c8dcSSimon Schubert sect_size = bfd_section_size (abfd, sect);
5785796c8dcSSimon Schubert buf = bufstart = alloca (sect_size);
5795796c8dcSSimon Schubert if (!bfd_get_section_contents (abfd, sect,
5805796c8dcSSimon Schubert buf, 0, sect_size))
5815796c8dcSSimon Schubert return 0;
5825796c8dcSSimon Schubert
5835796c8dcSSimon Schubert /* Iterate over BUF and scan for DYNTAG. If found, set PTR and return. */
5845796c8dcSSimon Schubert step = (arch_size == 32) ? sizeof (Elf32_External_Dyn)
5855796c8dcSSimon Schubert : sizeof (Elf64_External_Dyn);
5865796c8dcSSimon Schubert for (bufend = buf + sect_size;
5875796c8dcSSimon Schubert buf < bufend;
5885796c8dcSSimon Schubert buf += step)
5895796c8dcSSimon Schubert {
5905796c8dcSSimon Schubert if (arch_size == 32)
5915796c8dcSSimon Schubert {
5925796c8dcSSimon Schubert x_dynp_32 = (Elf32_External_Dyn *) buf;
5935796c8dcSSimon Schubert dyn_tag = bfd_h_get_32 (abfd, (bfd_byte *) x_dynp_32->d_tag);
5945796c8dcSSimon Schubert dyn_ptr = bfd_h_get_32 (abfd, (bfd_byte *) x_dynp_32->d_un.d_ptr);
5955796c8dcSSimon Schubert }
5965796c8dcSSimon Schubert else
5975796c8dcSSimon Schubert {
5985796c8dcSSimon Schubert x_dynp_64 = (Elf64_External_Dyn *) buf;
5995796c8dcSSimon Schubert dyn_tag = bfd_h_get_64 (abfd, (bfd_byte *) x_dynp_64->d_tag);
6005796c8dcSSimon Schubert dyn_ptr = bfd_h_get_64 (abfd, (bfd_byte *) x_dynp_64->d_un.d_ptr);
6015796c8dcSSimon Schubert }
6025796c8dcSSimon Schubert if (dyn_tag == DT_NULL)
6035796c8dcSSimon Schubert return 0;
6045796c8dcSSimon Schubert if (dyn_tag == dyntag)
6055796c8dcSSimon Schubert {
6065796c8dcSSimon Schubert /* If requested, try to read the runtime value of this .dynamic
6075796c8dcSSimon Schubert entry. */
6085796c8dcSSimon Schubert if (ptr)
6095796c8dcSSimon Schubert {
6105796c8dcSSimon Schubert struct type *ptr_type;
6115796c8dcSSimon Schubert gdb_byte ptr_buf[8];
6125796c8dcSSimon Schubert CORE_ADDR ptr_addr;
6135796c8dcSSimon Schubert
614*ef5ccd6cSJohn Marino ptr_type = builtin_type (target_gdbarch ())->builtin_data_ptr;
6155796c8dcSSimon Schubert ptr_addr = dyn_addr + (buf - bufstart) + arch_size / 8;
6165796c8dcSSimon Schubert if (target_read_memory (ptr_addr, ptr_buf, arch_size / 8) == 0)
6175796c8dcSSimon Schubert dyn_ptr = extract_typed_address (ptr_buf, ptr_type);
6185796c8dcSSimon Schubert *ptr = dyn_ptr;
6195796c8dcSSimon Schubert }
6205796c8dcSSimon Schubert return 1;
6215796c8dcSSimon Schubert }
6225796c8dcSSimon Schubert }
6235796c8dcSSimon Schubert
6245796c8dcSSimon Schubert return 0;
6255796c8dcSSimon Schubert }
6265796c8dcSSimon Schubert
6275796c8dcSSimon Schubert /* Scan for DYNTAG in .dynamic section of the target's main executable,
6285796c8dcSSimon Schubert found by consulting the OS auxillary vector. If DYNTAG is found 1 is
6295796c8dcSSimon Schubert returned and the corresponding PTR is set. */
6305796c8dcSSimon Schubert
6315796c8dcSSimon Schubert static int
scan_dyntag_auxv(int dyntag,CORE_ADDR * ptr)6325796c8dcSSimon Schubert scan_dyntag_auxv (int dyntag, CORE_ADDR *ptr)
6335796c8dcSSimon Schubert {
634*ef5ccd6cSJohn Marino enum bfd_endian byte_order = gdbarch_byte_order (target_gdbarch ());
6355796c8dcSSimon Schubert int sect_size, arch_size, step;
6365796c8dcSSimon Schubert long dyn_tag;
6375796c8dcSSimon Schubert CORE_ADDR dyn_ptr;
6385796c8dcSSimon Schubert gdb_byte *bufend, *bufstart, *buf;
6395796c8dcSSimon Schubert
6405796c8dcSSimon Schubert /* Read in .dynamic section. */
6415796c8dcSSimon Schubert buf = bufstart = read_program_header (PT_DYNAMIC, §_size, &arch_size);
6425796c8dcSSimon Schubert if (!buf)
6435796c8dcSSimon Schubert return 0;
6445796c8dcSSimon Schubert
6455796c8dcSSimon Schubert /* Iterate over BUF and scan for DYNTAG. If found, set PTR and return. */
6465796c8dcSSimon Schubert step = (arch_size == 32) ? sizeof (Elf32_External_Dyn)
6475796c8dcSSimon Schubert : sizeof (Elf64_External_Dyn);
6485796c8dcSSimon Schubert for (bufend = buf + sect_size;
6495796c8dcSSimon Schubert buf < bufend;
6505796c8dcSSimon Schubert buf += step)
6515796c8dcSSimon Schubert {
6525796c8dcSSimon Schubert if (arch_size == 32)
6535796c8dcSSimon Schubert {
6545796c8dcSSimon Schubert Elf32_External_Dyn *dynp = (Elf32_External_Dyn *) buf;
655cf7f2e2dSJohn Marino
6565796c8dcSSimon Schubert dyn_tag = extract_unsigned_integer ((gdb_byte *) dynp->d_tag,
6575796c8dcSSimon Schubert 4, byte_order);
6585796c8dcSSimon Schubert dyn_ptr = extract_unsigned_integer ((gdb_byte *) dynp->d_un.d_ptr,
6595796c8dcSSimon Schubert 4, byte_order);
6605796c8dcSSimon Schubert }
6615796c8dcSSimon Schubert else
6625796c8dcSSimon Schubert {
6635796c8dcSSimon Schubert Elf64_External_Dyn *dynp = (Elf64_External_Dyn *) buf;
664cf7f2e2dSJohn Marino
6655796c8dcSSimon Schubert dyn_tag = extract_unsigned_integer ((gdb_byte *) dynp->d_tag,
6665796c8dcSSimon Schubert 8, byte_order);
6675796c8dcSSimon Schubert dyn_ptr = extract_unsigned_integer ((gdb_byte *) dynp->d_un.d_ptr,
6685796c8dcSSimon Schubert 8, byte_order);
6695796c8dcSSimon Schubert }
6705796c8dcSSimon Schubert if (dyn_tag == DT_NULL)
6715796c8dcSSimon Schubert break;
6725796c8dcSSimon Schubert
6735796c8dcSSimon Schubert if (dyn_tag == dyntag)
6745796c8dcSSimon Schubert {
6755796c8dcSSimon Schubert if (ptr)
6765796c8dcSSimon Schubert *ptr = dyn_ptr;
6775796c8dcSSimon Schubert
6785796c8dcSSimon Schubert xfree (bufstart);
6795796c8dcSSimon Schubert return 1;
6805796c8dcSSimon Schubert }
6815796c8dcSSimon Schubert }
6825796c8dcSSimon Schubert
6835796c8dcSSimon Schubert xfree (bufstart);
6845796c8dcSSimon Schubert return 0;
6855796c8dcSSimon Schubert }
6865796c8dcSSimon Schubert
687a45ae5f8SJohn Marino /* Locate the base address of dynamic linker structs for SVR4 elf
688a45ae5f8SJohn Marino targets.
6895796c8dcSSimon Schubert
6905796c8dcSSimon Schubert For SVR4 elf targets the address of the dynamic linker's runtime
6915796c8dcSSimon Schubert structure is contained within the dynamic info section in the
6925796c8dcSSimon Schubert executable file. The dynamic section is also mapped into the
6935796c8dcSSimon Schubert inferior address space. Because the runtime loader fills in the
6945796c8dcSSimon Schubert real address before starting the inferior, we have to read in the
6955796c8dcSSimon Schubert dynamic info section from the inferior address space.
6965796c8dcSSimon Schubert If there are any errors while trying to find the address, we
697a45ae5f8SJohn Marino silently return 0, otherwise the found address is returned. */
6985796c8dcSSimon Schubert
6995796c8dcSSimon Schubert static CORE_ADDR
elf_locate_base(void)7005796c8dcSSimon Schubert elf_locate_base (void)
7015796c8dcSSimon Schubert {
7025796c8dcSSimon Schubert struct minimal_symbol *msymbol;
7035796c8dcSSimon Schubert CORE_ADDR dyn_ptr;
7045796c8dcSSimon Schubert
7055796c8dcSSimon Schubert /* Look for DT_MIPS_RLD_MAP first. MIPS executables use this
7065796c8dcSSimon Schubert instead of DT_DEBUG, although they sometimes contain an unused
7075796c8dcSSimon Schubert DT_DEBUG. */
7085796c8dcSSimon Schubert if (scan_dyntag (DT_MIPS_RLD_MAP, exec_bfd, &dyn_ptr)
7095796c8dcSSimon Schubert || scan_dyntag_auxv (DT_MIPS_RLD_MAP, &dyn_ptr))
7105796c8dcSSimon Schubert {
711*ef5ccd6cSJohn Marino struct type *ptr_type = builtin_type (target_gdbarch ())->builtin_data_ptr;
7125796c8dcSSimon Schubert gdb_byte *pbuf;
7135796c8dcSSimon Schubert int pbuf_size = TYPE_LENGTH (ptr_type);
714cf7f2e2dSJohn Marino
7155796c8dcSSimon Schubert pbuf = alloca (pbuf_size);
7165796c8dcSSimon Schubert /* DT_MIPS_RLD_MAP contains a pointer to the address
7175796c8dcSSimon Schubert of the dynamic link structure. */
7185796c8dcSSimon Schubert if (target_read_memory (dyn_ptr, pbuf, pbuf_size))
7195796c8dcSSimon Schubert return 0;
7205796c8dcSSimon Schubert return extract_typed_address (pbuf, ptr_type);
7215796c8dcSSimon Schubert }
7225796c8dcSSimon Schubert
7235796c8dcSSimon Schubert /* Find DT_DEBUG. */
7245796c8dcSSimon Schubert if (scan_dyntag (DT_DEBUG, exec_bfd, &dyn_ptr)
7255796c8dcSSimon Schubert || scan_dyntag_auxv (DT_DEBUG, &dyn_ptr))
7265796c8dcSSimon Schubert return dyn_ptr;
7275796c8dcSSimon Schubert
7285796c8dcSSimon Schubert /* This may be a static executable. Look for the symbol
7295796c8dcSSimon Schubert conventionally named _r_debug, as a last resort. */
7305796c8dcSSimon Schubert msymbol = lookup_minimal_symbol ("_r_debug", NULL, symfile_objfile);
7315796c8dcSSimon Schubert if (msymbol != NULL)
7325796c8dcSSimon Schubert return SYMBOL_VALUE_ADDRESS (msymbol);
7335796c8dcSSimon Schubert
7345796c8dcSSimon Schubert /* DT_DEBUG entry not found. */
7355796c8dcSSimon Schubert return 0;
7365796c8dcSSimon Schubert }
7375796c8dcSSimon Schubert
738a45ae5f8SJohn Marino /* Locate the base address of dynamic linker structs.
7395796c8dcSSimon Schubert
7405796c8dcSSimon Schubert For both the SunOS and SVR4 shared library implementations, if the
7415796c8dcSSimon Schubert inferior executable has been linked dynamically, there is a single
7425796c8dcSSimon Schubert address somewhere in the inferior's data space which is the key to
7435796c8dcSSimon Schubert locating all of the dynamic linker's runtime structures. This
7445796c8dcSSimon Schubert address is the value of the debug base symbol. The job of this
7455796c8dcSSimon Schubert function is to find and return that address, or to return 0 if there
7465796c8dcSSimon Schubert is no such address (the executable is statically linked for example).
7475796c8dcSSimon Schubert
7485796c8dcSSimon Schubert For SunOS, the job is almost trivial, since the dynamic linker and
7495796c8dcSSimon Schubert all of it's structures are statically linked to the executable at
7505796c8dcSSimon Schubert link time. Thus the symbol for the address we are looking for has
7515796c8dcSSimon Schubert already been added to the minimal symbol table for the executable's
7525796c8dcSSimon Schubert objfile at the time the symbol file's symbols were read, and all we
7535796c8dcSSimon Schubert have to do is look it up there. Note that we explicitly do NOT want
7545796c8dcSSimon Schubert to find the copies in the shared library.
7555796c8dcSSimon Schubert
7565796c8dcSSimon Schubert The SVR4 version is a bit more complicated because the address
7575796c8dcSSimon Schubert is contained somewhere in the dynamic info section. We have to go
7585796c8dcSSimon Schubert to a lot more work to discover the address of the debug base symbol.
7595796c8dcSSimon Schubert Because of this complexity, we cache the value we find and return that
7605796c8dcSSimon Schubert value on subsequent invocations. Note there is no copy in the
761a45ae5f8SJohn Marino executable symbol tables. */
7625796c8dcSSimon Schubert
7635796c8dcSSimon Schubert static CORE_ADDR
locate_base(struct svr4_info * info)7645796c8dcSSimon Schubert locate_base (struct svr4_info *info)
7655796c8dcSSimon Schubert {
7665796c8dcSSimon Schubert /* Check to see if we have a currently valid address, and if so, avoid
7675796c8dcSSimon Schubert doing all this work again and just return the cached address. If
7685796c8dcSSimon Schubert we have no cached address, try to locate it in the dynamic info
7695796c8dcSSimon Schubert section for ELF executables. There's no point in doing any of this
7705796c8dcSSimon Schubert though if we don't have some link map offsets to work with. */
7715796c8dcSSimon Schubert
7725796c8dcSSimon Schubert if (info->debug_base == 0 && svr4_have_link_map_offsets ())
7735796c8dcSSimon Schubert info->debug_base = elf_locate_base ();
7745796c8dcSSimon Schubert return info->debug_base;
7755796c8dcSSimon Schubert }
7765796c8dcSSimon Schubert
7775796c8dcSSimon Schubert /* Find the first element in the inferior's dynamic link map, and
778cf7f2e2dSJohn Marino return its address in the inferior. Return zero if the address
779cf7f2e2dSJohn Marino could not be determined.
7805796c8dcSSimon Schubert
7815796c8dcSSimon Schubert FIXME: Perhaps we should validate the info somehow, perhaps by
7825796c8dcSSimon Schubert checking r_version for a known version number, or r_state for
7835796c8dcSSimon Schubert RT_CONSISTENT. */
7845796c8dcSSimon Schubert
7855796c8dcSSimon Schubert static CORE_ADDR
solib_svr4_r_map(struct svr4_info * info)7865796c8dcSSimon Schubert solib_svr4_r_map (struct svr4_info *info)
7875796c8dcSSimon Schubert {
7885796c8dcSSimon Schubert struct link_map_offsets *lmo = svr4_fetch_link_map_offsets ();
789*ef5ccd6cSJohn Marino struct type *ptr_type = builtin_type (target_gdbarch ())->builtin_data_ptr;
790cf7f2e2dSJohn Marino CORE_ADDR addr = 0;
791cf7f2e2dSJohn Marino volatile struct gdb_exception ex;
7925796c8dcSSimon Schubert
793cf7f2e2dSJohn Marino TRY_CATCH (ex, RETURN_MASK_ERROR)
794cf7f2e2dSJohn Marino {
795cf7f2e2dSJohn Marino addr = read_memory_typed_address (info->debug_base + lmo->r_map_offset,
7965796c8dcSSimon Schubert ptr_type);
7975796c8dcSSimon Schubert }
798cf7f2e2dSJohn Marino exception_print (gdb_stderr, ex);
799cf7f2e2dSJohn Marino return addr;
800cf7f2e2dSJohn Marino }
8015796c8dcSSimon Schubert
8025796c8dcSSimon Schubert /* Find r_brk from the inferior's debug base. */
8035796c8dcSSimon Schubert
8045796c8dcSSimon Schubert static CORE_ADDR
solib_svr4_r_brk(struct svr4_info * info)8055796c8dcSSimon Schubert solib_svr4_r_brk (struct svr4_info *info)
8065796c8dcSSimon Schubert {
8075796c8dcSSimon Schubert struct link_map_offsets *lmo = svr4_fetch_link_map_offsets ();
808*ef5ccd6cSJohn Marino struct type *ptr_type = builtin_type (target_gdbarch ())->builtin_data_ptr;
8095796c8dcSSimon Schubert
8105796c8dcSSimon Schubert return read_memory_typed_address (info->debug_base + lmo->r_brk_offset,
8115796c8dcSSimon Schubert ptr_type);
8125796c8dcSSimon Schubert }
8135796c8dcSSimon Schubert
8145796c8dcSSimon Schubert /* Find the link map for the dynamic linker (if it is not in the
8155796c8dcSSimon Schubert normal list of loaded shared objects). */
8165796c8dcSSimon Schubert
8175796c8dcSSimon Schubert static CORE_ADDR
solib_svr4_r_ldsomap(struct svr4_info * info)8185796c8dcSSimon Schubert solib_svr4_r_ldsomap (struct svr4_info *info)
8195796c8dcSSimon Schubert {
8205796c8dcSSimon Schubert struct link_map_offsets *lmo = svr4_fetch_link_map_offsets ();
821*ef5ccd6cSJohn Marino struct type *ptr_type = builtin_type (target_gdbarch ())->builtin_data_ptr;
822*ef5ccd6cSJohn Marino enum bfd_endian byte_order = gdbarch_byte_order (target_gdbarch ());
8235796c8dcSSimon Schubert ULONGEST version;
8245796c8dcSSimon Schubert
8255796c8dcSSimon Schubert /* Check version, and return zero if `struct r_debug' doesn't have
8265796c8dcSSimon Schubert the r_ldsomap member. */
8275796c8dcSSimon Schubert version
8285796c8dcSSimon Schubert = read_memory_unsigned_integer (info->debug_base + lmo->r_version_offset,
8295796c8dcSSimon Schubert lmo->r_version_size, byte_order);
8305796c8dcSSimon Schubert if (version < 2 || lmo->r_ldsomap_offset == -1)
8315796c8dcSSimon Schubert return 0;
8325796c8dcSSimon Schubert
8335796c8dcSSimon Schubert return read_memory_typed_address (info->debug_base + lmo->r_ldsomap_offset,
8345796c8dcSSimon Schubert ptr_type);
8355796c8dcSSimon Schubert }
8365796c8dcSSimon Schubert
837cf7f2e2dSJohn Marino /* On Solaris systems with some versions of the dynamic linker,
838cf7f2e2dSJohn Marino ld.so's l_name pointer points to the SONAME in the string table
839cf7f2e2dSJohn Marino rather than into writable memory. So that GDB can find shared
840cf7f2e2dSJohn Marino libraries when loading a core file generated by gcore, ensure that
841cf7f2e2dSJohn Marino memory areas containing the l_name string are saved in the core
842cf7f2e2dSJohn Marino file. */
843cf7f2e2dSJohn Marino
844cf7f2e2dSJohn Marino static int
svr4_keep_data_in_core(CORE_ADDR vaddr,unsigned long size)845cf7f2e2dSJohn Marino svr4_keep_data_in_core (CORE_ADDR vaddr, unsigned long size)
846cf7f2e2dSJohn Marino {
847cf7f2e2dSJohn Marino struct svr4_info *info;
848cf7f2e2dSJohn Marino CORE_ADDR ldsomap;
849cf7f2e2dSJohn Marino struct so_list *new;
850cf7f2e2dSJohn Marino struct cleanup *old_chain;
851a45ae5f8SJohn Marino CORE_ADDR name_lm;
852cf7f2e2dSJohn Marino
853cf7f2e2dSJohn Marino info = get_svr4_info ();
854cf7f2e2dSJohn Marino
855cf7f2e2dSJohn Marino info->debug_base = 0;
856cf7f2e2dSJohn Marino locate_base (info);
857cf7f2e2dSJohn Marino if (!info->debug_base)
858cf7f2e2dSJohn Marino return 0;
859cf7f2e2dSJohn Marino
860cf7f2e2dSJohn Marino ldsomap = solib_svr4_r_ldsomap (info);
861cf7f2e2dSJohn Marino if (!ldsomap)
862cf7f2e2dSJohn Marino return 0;
863cf7f2e2dSJohn Marino
864cf7f2e2dSJohn Marino new = XZALLOC (struct so_list);
865cf7f2e2dSJohn Marino old_chain = make_cleanup (xfree, new);
866a45ae5f8SJohn Marino new->lm_info = lm_info_read (ldsomap);
867cf7f2e2dSJohn Marino make_cleanup (xfree, new->lm_info);
868a45ae5f8SJohn Marino name_lm = new->lm_info ? new->lm_info->l_name : 0;
869cf7f2e2dSJohn Marino do_cleanups (old_chain);
870cf7f2e2dSJohn Marino
871a45ae5f8SJohn Marino return (name_lm >= vaddr && name_lm < vaddr + size);
872cf7f2e2dSJohn Marino }
873cf7f2e2dSJohn Marino
874a45ae5f8SJohn Marino /* Implement the "open_symbol_file_object" target_so_ops method.
8755796c8dcSSimon Schubert
8765796c8dcSSimon Schubert If no open symbol file, attempt to locate and open the main symbol
8775796c8dcSSimon Schubert file. On SVR4 systems, this is the first link map entry. If its
8785796c8dcSSimon Schubert name is here, we can open it. Useful when attaching to a process
879a45ae5f8SJohn Marino without first loading its symbol file. */
8805796c8dcSSimon Schubert
8815796c8dcSSimon Schubert static int
open_symbol_file_object(void * from_ttyp)8825796c8dcSSimon Schubert open_symbol_file_object (void *from_ttyp)
8835796c8dcSSimon Schubert {
8845796c8dcSSimon Schubert CORE_ADDR lm, l_name;
8855796c8dcSSimon Schubert char *filename;
8865796c8dcSSimon Schubert int errcode;
8875796c8dcSSimon Schubert int from_tty = *(int *)from_ttyp;
8885796c8dcSSimon Schubert struct link_map_offsets *lmo = svr4_fetch_link_map_offsets ();
889*ef5ccd6cSJohn Marino struct type *ptr_type = builtin_type (target_gdbarch ())->builtin_data_ptr;
8905796c8dcSSimon Schubert int l_name_size = TYPE_LENGTH (ptr_type);
8915796c8dcSSimon Schubert gdb_byte *l_name_buf = xmalloc (l_name_size);
8925796c8dcSSimon Schubert struct cleanup *cleanups = make_cleanup (xfree, l_name_buf);
893cf7f2e2dSJohn Marino struct svr4_info *info = get_svr4_info ();
8945796c8dcSSimon Schubert
8955796c8dcSSimon Schubert if (symfile_objfile)
8965796c8dcSSimon Schubert if (!query (_("Attempt to reload symbols from process? ")))
897a45ae5f8SJohn Marino {
898a45ae5f8SJohn Marino do_cleanups (cleanups);
8995796c8dcSSimon Schubert return 0;
900a45ae5f8SJohn Marino }
9015796c8dcSSimon Schubert
9025796c8dcSSimon Schubert /* Always locate the debug struct, in case it has moved. */
9035796c8dcSSimon Schubert info->debug_base = 0;
9045796c8dcSSimon Schubert if (locate_base (info) == 0)
905a45ae5f8SJohn Marino {
906a45ae5f8SJohn Marino do_cleanups (cleanups);
9075796c8dcSSimon Schubert return 0; /* failed somehow... */
908a45ae5f8SJohn Marino }
9095796c8dcSSimon Schubert
9105796c8dcSSimon Schubert /* First link map member should be the executable. */
9115796c8dcSSimon Schubert lm = solib_svr4_r_map (info);
9125796c8dcSSimon Schubert if (lm == 0)
913a45ae5f8SJohn Marino {
914a45ae5f8SJohn Marino do_cleanups (cleanups);
9155796c8dcSSimon Schubert return 0; /* failed somehow... */
916a45ae5f8SJohn Marino }
9175796c8dcSSimon Schubert
9185796c8dcSSimon Schubert /* Read address of name from target memory to GDB. */
9195796c8dcSSimon Schubert read_memory (lm + lmo->l_name_offset, l_name_buf, l_name_size);
9205796c8dcSSimon Schubert
9215796c8dcSSimon Schubert /* Convert the address to host format. */
9225796c8dcSSimon Schubert l_name = extract_typed_address (l_name_buf, ptr_type);
9235796c8dcSSimon Schubert
9245796c8dcSSimon Schubert if (l_name == 0)
925a45ae5f8SJohn Marino {
926a45ae5f8SJohn Marino do_cleanups (cleanups);
9275796c8dcSSimon Schubert return 0; /* No filename. */
928a45ae5f8SJohn Marino }
9295796c8dcSSimon Schubert
9305796c8dcSSimon Schubert /* Now fetch the filename from target memory. */
9315796c8dcSSimon Schubert target_read_string (l_name, &filename, SO_NAME_MAX_PATH_SIZE - 1, &errcode);
9325796c8dcSSimon Schubert make_cleanup (xfree, filename);
9335796c8dcSSimon Schubert
9345796c8dcSSimon Schubert if (errcode)
9355796c8dcSSimon Schubert {
9365796c8dcSSimon Schubert warning (_("failed to read exec filename from attached file: %s"),
9375796c8dcSSimon Schubert safe_strerror (errcode));
938a45ae5f8SJohn Marino do_cleanups (cleanups);
9395796c8dcSSimon Schubert return 0;
9405796c8dcSSimon Schubert }
9415796c8dcSSimon Schubert
9425796c8dcSSimon Schubert /* Have a pathname: read the symbol file. */
9435796c8dcSSimon Schubert symbol_file_add_main (filename, from_tty);
9445796c8dcSSimon Schubert
945a45ae5f8SJohn Marino do_cleanups (cleanups);
9465796c8dcSSimon Schubert return 1;
9475796c8dcSSimon Schubert }
9485796c8dcSSimon Schubert
949a45ae5f8SJohn Marino /* Data exchange structure for the XML parser as returned by
950a45ae5f8SJohn Marino svr4_current_sos_via_xfer_libraries. */
951a45ae5f8SJohn Marino
952a45ae5f8SJohn Marino struct svr4_library_list
953a45ae5f8SJohn Marino {
954a45ae5f8SJohn Marino struct so_list *head, **tailp;
955a45ae5f8SJohn Marino
956a45ae5f8SJohn Marino /* Inferior address of struct link_map used for the main executable. It is
957a45ae5f8SJohn Marino NULL if not known. */
958a45ae5f8SJohn Marino CORE_ADDR main_lm;
959a45ae5f8SJohn Marino };
960a45ae5f8SJohn Marino
961a45ae5f8SJohn Marino /* Implementation for target_so_ops.free_so. */
962a45ae5f8SJohn Marino
963a45ae5f8SJohn Marino static void
svr4_free_so(struct so_list * so)964a45ae5f8SJohn Marino svr4_free_so (struct so_list *so)
965a45ae5f8SJohn Marino {
966a45ae5f8SJohn Marino xfree (so->lm_info);
967a45ae5f8SJohn Marino }
968a45ae5f8SJohn Marino
969a45ae5f8SJohn Marino /* Free so_list built so far (called via cleanup). */
970a45ae5f8SJohn Marino
971a45ae5f8SJohn Marino static void
svr4_free_library_list(void * p_list)972a45ae5f8SJohn Marino svr4_free_library_list (void *p_list)
973a45ae5f8SJohn Marino {
974a45ae5f8SJohn Marino struct so_list *list = *(struct so_list **) p_list;
975a45ae5f8SJohn Marino
976a45ae5f8SJohn Marino while (list != NULL)
977a45ae5f8SJohn Marino {
978a45ae5f8SJohn Marino struct so_list *next = list->next;
979a45ae5f8SJohn Marino
980*ef5ccd6cSJohn Marino free_so (list);
981a45ae5f8SJohn Marino list = next;
982a45ae5f8SJohn Marino }
983a45ae5f8SJohn Marino }
984a45ae5f8SJohn Marino
985a45ae5f8SJohn Marino #ifdef HAVE_LIBEXPAT
986a45ae5f8SJohn Marino
987a45ae5f8SJohn Marino #include "xml-support.h"
988a45ae5f8SJohn Marino
989a45ae5f8SJohn Marino /* Handle the start of a <library> element. Note: new elements are added
990a45ae5f8SJohn Marino at the tail of the list, keeping the list in order. */
991a45ae5f8SJohn Marino
992a45ae5f8SJohn Marino static void
library_list_start_library(struct gdb_xml_parser * parser,const struct gdb_xml_element * element,void * user_data,VEC (gdb_xml_value_s)* attributes)993a45ae5f8SJohn Marino library_list_start_library (struct gdb_xml_parser *parser,
994a45ae5f8SJohn Marino const struct gdb_xml_element *element,
995a45ae5f8SJohn Marino void *user_data, VEC(gdb_xml_value_s) *attributes)
996a45ae5f8SJohn Marino {
997a45ae5f8SJohn Marino struct svr4_library_list *list = user_data;
998a45ae5f8SJohn Marino const char *name = xml_find_attribute (attributes, "name")->value;
999a45ae5f8SJohn Marino ULONGEST *lmp = xml_find_attribute (attributes, "lm")->value;
1000a45ae5f8SJohn Marino ULONGEST *l_addrp = xml_find_attribute (attributes, "l_addr")->value;
1001a45ae5f8SJohn Marino ULONGEST *l_ldp = xml_find_attribute (attributes, "l_ld")->value;
1002a45ae5f8SJohn Marino struct so_list *new_elem;
1003a45ae5f8SJohn Marino
1004a45ae5f8SJohn Marino new_elem = XZALLOC (struct so_list);
1005a45ae5f8SJohn Marino new_elem->lm_info = XZALLOC (struct lm_info);
1006a45ae5f8SJohn Marino new_elem->lm_info->lm_addr = *lmp;
1007a45ae5f8SJohn Marino new_elem->lm_info->l_addr_inferior = *l_addrp;
1008a45ae5f8SJohn Marino new_elem->lm_info->l_ld = *l_ldp;
1009a45ae5f8SJohn Marino
1010a45ae5f8SJohn Marino strncpy (new_elem->so_name, name, sizeof (new_elem->so_name) - 1);
1011a45ae5f8SJohn Marino new_elem->so_name[sizeof (new_elem->so_name) - 1] = 0;
1012a45ae5f8SJohn Marino strcpy (new_elem->so_original_name, new_elem->so_name);
1013a45ae5f8SJohn Marino
1014a45ae5f8SJohn Marino *list->tailp = new_elem;
1015a45ae5f8SJohn Marino list->tailp = &new_elem->next;
1016a45ae5f8SJohn Marino }
1017a45ae5f8SJohn Marino
1018a45ae5f8SJohn Marino /* Handle the start of a <library-list-svr4> element. */
1019a45ae5f8SJohn Marino
1020a45ae5f8SJohn Marino static void
svr4_library_list_start_list(struct gdb_xml_parser * parser,const struct gdb_xml_element * element,void * user_data,VEC (gdb_xml_value_s)* attributes)1021a45ae5f8SJohn Marino svr4_library_list_start_list (struct gdb_xml_parser *parser,
1022a45ae5f8SJohn Marino const struct gdb_xml_element *element,
1023a45ae5f8SJohn Marino void *user_data, VEC(gdb_xml_value_s) *attributes)
1024a45ae5f8SJohn Marino {
1025a45ae5f8SJohn Marino struct svr4_library_list *list = user_data;
1026a45ae5f8SJohn Marino const char *version = xml_find_attribute (attributes, "version")->value;
1027a45ae5f8SJohn Marino struct gdb_xml_value *main_lm = xml_find_attribute (attributes, "main-lm");
1028a45ae5f8SJohn Marino
1029a45ae5f8SJohn Marino if (strcmp (version, "1.0") != 0)
1030a45ae5f8SJohn Marino gdb_xml_error (parser,
1031a45ae5f8SJohn Marino _("SVR4 Library list has unsupported version \"%s\""),
1032a45ae5f8SJohn Marino version);
1033a45ae5f8SJohn Marino
1034a45ae5f8SJohn Marino if (main_lm)
1035a45ae5f8SJohn Marino list->main_lm = *(ULONGEST *) main_lm->value;
1036a45ae5f8SJohn Marino }
1037a45ae5f8SJohn Marino
1038a45ae5f8SJohn Marino /* The allowed elements and attributes for an XML library list.
1039a45ae5f8SJohn Marino The root element is a <library-list>. */
1040a45ae5f8SJohn Marino
1041a45ae5f8SJohn Marino static const struct gdb_xml_attribute svr4_library_attributes[] =
1042a45ae5f8SJohn Marino {
1043a45ae5f8SJohn Marino { "name", GDB_XML_AF_NONE, NULL, NULL },
1044a45ae5f8SJohn Marino { "lm", GDB_XML_AF_NONE, gdb_xml_parse_attr_ulongest, NULL },
1045a45ae5f8SJohn Marino { "l_addr", GDB_XML_AF_NONE, gdb_xml_parse_attr_ulongest, NULL },
1046a45ae5f8SJohn Marino { "l_ld", GDB_XML_AF_NONE, gdb_xml_parse_attr_ulongest, NULL },
1047a45ae5f8SJohn Marino { NULL, GDB_XML_AF_NONE, NULL, NULL }
1048a45ae5f8SJohn Marino };
1049a45ae5f8SJohn Marino
1050a45ae5f8SJohn Marino static const struct gdb_xml_element svr4_library_list_children[] =
1051a45ae5f8SJohn Marino {
1052a45ae5f8SJohn Marino {
1053a45ae5f8SJohn Marino "library", svr4_library_attributes, NULL,
1054a45ae5f8SJohn Marino GDB_XML_EF_REPEATABLE | GDB_XML_EF_OPTIONAL,
1055a45ae5f8SJohn Marino library_list_start_library, NULL
1056a45ae5f8SJohn Marino },
1057a45ae5f8SJohn Marino { NULL, NULL, NULL, GDB_XML_EF_NONE, NULL, NULL }
1058a45ae5f8SJohn Marino };
1059a45ae5f8SJohn Marino
1060a45ae5f8SJohn Marino static const struct gdb_xml_attribute svr4_library_list_attributes[] =
1061a45ae5f8SJohn Marino {
1062a45ae5f8SJohn Marino { "version", GDB_XML_AF_NONE, NULL, NULL },
1063a45ae5f8SJohn Marino { "main-lm", GDB_XML_AF_OPTIONAL, gdb_xml_parse_attr_ulongest, NULL },
1064a45ae5f8SJohn Marino { NULL, GDB_XML_AF_NONE, NULL, NULL }
1065a45ae5f8SJohn Marino };
1066a45ae5f8SJohn Marino
1067a45ae5f8SJohn Marino static const struct gdb_xml_element svr4_library_list_elements[] =
1068a45ae5f8SJohn Marino {
1069a45ae5f8SJohn Marino { "library-list-svr4", svr4_library_list_attributes, svr4_library_list_children,
1070a45ae5f8SJohn Marino GDB_XML_EF_NONE, svr4_library_list_start_list, NULL },
1071a45ae5f8SJohn Marino { NULL, NULL, NULL, GDB_XML_EF_NONE, NULL, NULL }
1072a45ae5f8SJohn Marino };
1073a45ae5f8SJohn Marino
1074a45ae5f8SJohn Marino /* Parse qXfer:libraries:read packet into *SO_LIST_RETURN. Return 1 if
1075a45ae5f8SJohn Marino
1076a45ae5f8SJohn Marino Return 0 if packet not supported, *SO_LIST_RETURN is not modified in such
1077a45ae5f8SJohn Marino case. Return 1 if *SO_LIST_RETURN contains the library list, it may be
1078a45ae5f8SJohn Marino empty, caller is responsible for freeing all its entries. */
1079a45ae5f8SJohn Marino
1080a45ae5f8SJohn Marino static int
svr4_parse_libraries(const char * document,struct svr4_library_list * list)1081a45ae5f8SJohn Marino svr4_parse_libraries (const char *document, struct svr4_library_list *list)
1082a45ae5f8SJohn Marino {
1083a45ae5f8SJohn Marino struct cleanup *back_to = make_cleanup (svr4_free_library_list,
1084a45ae5f8SJohn Marino &list->head);
1085a45ae5f8SJohn Marino
1086a45ae5f8SJohn Marino memset (list, 0, sizeof (*list));
1087a45ae5f8SJohn Marino list->tailp = &list->head;
1088a45ae5f8SJohn Marino if (gdb_xml_parse_quick (_("target library list"), "library-list.dtd",
1089a45ae5f8SJohn Marino svr4_library_list_elements, document, list) == 0)
1090a45ae5f8SJohn Marino {
1091a45ae5f8SJohn Marino /* Parsed successfully, keep the result. */
1092a45ae5f8SJohn Marino discard_cleanups (back_to);
1093a45ae5f8SJohn Marino return 1;
1094a45ae5f8SJohn Marino }
1095a45ae5f8SJohn Marino
1096a45ae5f8SJohn Marino do_cleanups (back_to);
1097a45ae5f8SJohn Marino return 0;
1098a45ae5f8SJohn Marino }
1099a45ae5f8SJohn Marino
1100a45ae5f8SJohn Marino /* Attempt to get so_list from target via qXfer:libraries:read packet.
1101a45ae5f8SJohn Marino
1102a45ae5f8SJohn Marino Return 0 if packet not supported, *SO_LIST_RETURN is not modified in such
1103a45ae5f8SJohn Marino case. Return 1 if *SO_LIST_RETURN contains the library list, it may be
1104a45ae5f8SJohn Marino empty, caller is responsible for freeing all its entries. */
1105a45ae5f8SJohn Marino
1106a45ae5f8SJohn Marino static int
svr4_current_sos_via_xfer_libraries(struct svr4_library_list * list)1107a45ae5f8SJohn Marino svr4_current_sos_via_xfer_libraries (struct svr4_library_list *list)
1108a45ae5f8SJohn Marino {
1109a45ae5f8SJohn Marino char *svr4_library_document;
1110a45ae5f8SJohn Marino int result;
1111a45ae5f8SJohn Marino struct cleanup *back_to;
1112a45ae5f8SJohn Marino
1113a45ae5f8SJohn Marino /* Fetch the list of shared libraries. */
1114a45ae5f8SJohn Marino svr4_library_document = target_read_stralloc (¤t_target,
1115a45ae5f8SJohn Marino TARGET_OBJECT_LIBRARIES_SVR4,
1116a45ae5f8SJohn Marino NULL);
1117a45ae5f8SJohn Marino if (svr4_library_document == NULL)
1118a45ae5f8SJohn Marino return 0;
1119a45ae5f8SJohn Marino
1120a45ae5f8SJohn Marino back_to = make_cleanup (xfree, svr4_library_document);
1121a45ae5f8SJohn Marino result = svr4_parse_libraries (svr4_library_document, list);
1122a45ae5f8SJohn Marino do_cleanups (back_to);
1123a45ae5f8SJohn Marino
1124a45ae5f8SJohn Marino return result;
1125a45ae5f8SJohn Marino }
1126a45ae5f8SJohn Marino
1127a45ae5f8SJohn Marino #else
1128a45ae5f8SJohn Marino
1129a45ae5f8SJohn Marino static int
svr4_current_sos_via_xfer_libraries(struct svr4_library_list * list)1130a45ae5f8SJohn Marino svr4_current_sos_via_xfer_libraries (struct svr4_library_list *list)
1131a45ae5f8SJohn Marino {
1132a45ae5f8SJohn Marino return 0;
1133a45ae5f8SJohn Marino }
1134a45ae5f8SJohn Marino
1135a45ae5f8SJohn Marino #endif
1136a45ae5f8SJohn Marino
11375796c8dcSSimon Schubert /* If no shared library information is available from the dynamic
11385796c8dcSSimon Schubert linker, build a fallback list from other sources. */
11395796c8dcSSimon Schubert
11405796c8dcSSimon Schubert static struct so_list *
svr4_default_sos(void)11415796c8dcSSimon Schubert svr4_default_sos (void)
11425796c8dcSSimon Schubert {
1143cf7f2e2dSJohn Marino struct svr4_info *info = get_svr4_info ();
1144a45ae5f8SJohn Marino struct so_list *new;
11455796c8dcSSimon Schubert
1146a45ae5f8SJohn Marino if (!info->debug_loader_offset_p)
1147a45ae5f8SJohn Marino return NULL;
11485796c8dcSSimon Schubert
1149a45ae5f8SJohn Marino new = XZALLOC (struct so_list);
11505796c8dcSSimon Schubert
1151a45ae5f8SJohn Marino new->lm_info = xzalloc (sizeof (struct lm_info));
11525796c8dcSSimon Schubert
1153a45ae5f8SJohn Marino /* Nothing will ever check the other fields if we set l_addr_p. */
11545796c8dcSSimon Schubert new->lm_info->l_addr = info->debug_loader_offset;
1155a45ae5f8SJohn Marino new->lm_info->l_addr_p = 1;
11565796c8dcSSimon Schubert
1157a45ae5f8SJohn Marino strncpy (new->so_name, info->debug_loader_name, SO_NAME_MAX_PATH_SIZE - 1);
11585796c8dcSSimon Schubert new->so_name[SO_NAME_MAX_PATH_SIZE - 1] = '\0';
11595796c8dcSSimon Schubert strcpy (new->so_original_name, new->so_name);
11605796c8dcSSimon Schubert
1161a45ae5f8SJohn Marino return new;
11625796c8dcSSimon Schubert }
11635796c8dcSSimon Schubert
1164a45ae5f8SJohn Marino /* Read the whole inferior libraries chain starting at address LM. Add the
1165a45ae5f8SJohn Marino entries to the tail referenced by LINK_PTR_PTR. Ignore the first entry if
1166a45ae5f8SJohn Marino IGNORE_FIRST and set global MAIN_LM_ADDR according to it. */
1167a45ae5f8SJohn Marino
1168a45ae5f8SJohn Marino static void
svr4_read_so_list(CORE_ADDR lm,struct so_list *** link_ptr_ptr,int ignore_first)1169a45ae5f8SJohn Marino svr4_read_so_list (CORE_ADDR lm, struct so_list ***link_ptr_ptr,
1170a45ae5f8SJohn Marino int ignore_first)
1171a45ae5f8SJohn Marino {
1172a45ae5f8SJohn Marino CORE_ADDR prev_lm = 0, next_lm;
1173a45ae5f8SJohn Marino
1174a45ae5f8SJohn Marino for (; lm != 0; prev_lm = lm, lm = next_lm)
1175a45ae5f8SJohn Marino {
1176a45ae5f8SJohn Marino struct so_list *new;
1177a45ae5f8SJohn Marino struct cleanup *old_chain;
1178a45ae5f8SJohn Marino int errcode;
1179a45ae5f8SJohn Marino char *buffer;
1180a45ae5f8SJohn Marino
1181a45ae5f8SJohn Marino new = XZALLOC (struct so_list);
1182a45ae5f8SJohn Marino old_chain = make_cleanup_free_so (new);
1183a45ae5f8SJohn Marino
1184a45ae5f8SJohn Marino new->lm_info = lm_info_read (lm);
1185a45ae5f8SJohn Marino if (new->lm_info == NULL)
1186a45ae5f8SJohn Marino {
1187a45ae5f8SJohn Marino do_cleanups (old_chain);
1188a45ae5f8SJohn Marino break;
11895796c8dcSSimon Schubert }
11905796c8dcSSimon Schubert
1191a45ae5f8SJohn Marino next_lm = new->lm_info->l_next;
11925796c8dcSSimon Schubert
1193a45ae5f8SJohn Marino if (new->lm_info->l_prev != prev_lm)
1194a45ae5f8SJohn Marino {
1195a45ae5f8SJohn Marino warning (_("Corrupted shared library list: %s != %s"),
1196*ef5ccd6cSJohn Marino paddress (target_gdbarch (), prev_lm),
1197*ef5ccd6cSJohn Marino paddress (target_gdbarch (), new->lm_info->l_prev));
1198a45ae5f8SJohn Marino do_cleanups (old_chain);
1199a45ae5f8SJohn Marino break;
1200a45ae5f8SJohn Marino }
12015796c8dcSSimon Schubert
1202a45ae5f8SJohn Marino /* For SVR4 versions, the first entry in the link map is for the
1203a45ae5f8SJohn Marino inferior executable, so we must ignore it. For some versions of
1204a45ae5f8SJohn Marino SVR4, it has no name. For others (Solaris 2.3 for example), it
1205a45ae5f8SJohn Marino does have a name, so we can no longer use a missing name to
1206a45ae5f8SJohn Marino decide when to ignore it. */
1207a45ae5f8SJohn Marino if (ignore_first && new->lm_info->l_prev == 0)
1208a45ae5f8SJohn Marino {
1209a45ae5f8SJohn Marino struct svr4_info *info = get_svr4_info ();
12105796c8dcSSimon Schubert
1211a45ae5f8SJohn Marino info->main_lm_addr = new->lm_info->lm_addr;
1212a45ae5f8SJohn Marino do_cleanups (old_chain);
1213a45ae5f8SJohn Marino continue;
1214a45ae5f8SJohn Marino }
12155796c8dcSSimon Schubert
1216a45ae5f8SJohn Marino /* Extract this shared object's name. */
1217a45ae5f8SJohn Marino target_read_string (new->lm_info->l_name, &buffer,
1218a45ae5f8SJohn Marino SO_NAME_MAX_PATH_SIZE - 1, &errcode);
1219a45ae5f8SJohn Marino if (errcode != 0)
1220a45ae5f8SJohn Marino {
1221a45ae5f8SJohn Marino warning (_("Can't read pathname for load map: %s."),
1222a45ae5f8SJohn Marino safe_strerror (errcode));
1223a45ae5f8SJohn Marino do_cleanups (old_chain);
1224a45ae5f8SJohn Marino continue;
1225a45ae5f8SJohn Marino }
12265796c8dcSSimon Schubert
1227a45ae5f8SJohn Marino strncpy (new->so_name, buffer, SO_NAME_MAX_PATH_SIZE - 1);
1228a45ae5f8SJohn Marino new->so_name[SO_NAME_MAX_PATH_SIZE - 1] = '\0';
1229a45ae5f8SJohn Marino strcpy (new->so_original_name, new->so_name);
1230a45ae5f8SJohn Marino xfree (buffer);
12315796c8dcSSimon Schubert
1232a45ae5f8SJohn Marino /* If this entry has no name, or its name matches the name
1233a45ae5f8SJohn Marino for the main executable, don't include it in the list. */
1234a45ae5f8SJohn Marino if (! new->so_name[0] || match_main (new->so_name))
1235a45ae5f8SJohn Marino {
1236a45ae5f8SJohn Marino do_cleanups (old_chain);
1237a45ae5f8SJohn Marino continue;
1238a45ae5f8SJohn Marino }
1239a45ae5f8SJohn Marino
1240a45ae5f8SJohn Marino discard_cleanups (old_chain);
1241a45ae5f8SJohn Marino new->next = 0;
1242a45ae5f8SJohn Marino **link_ptr_ptr = new;
1243a45ae5f8SJohn Marino *link_ptr_ptr = &new->next;
1244a45ae5f8SJohn Marino }
1245a45ae5f8SJohn Marino }
1246a45ae5f8SJohn Marino
1247a45ae5f8SJohn Marino /* Implement the "current_sos" target_so_ops method. */
12485796c8dcSSimon Schubert
12495796c8dcSSimon Schubert static struct so_list *
svr4_current_sos(void)12505796c8dcSSimon Schubert svr4_current_sos (void)
12515796c8dcSSimon Schubert {
1252a45ae5f8SJohn Marino CORE_ADDR lm;
1253a45ae5f8SJohn Marino struct so_list *head = NULL;
12545796c8dcSSimon Schubert struct so_list **link_ptr = &head;
12555796c8dcSSimon Schubert struct svr4_info *info;
1256a45ae5f8SJohn Marino struct cleanup *back_to;
1257a45ae5f8SJohn Marino int ignore_first;
1258a45ae5f8SJohn Marino struct svr4_library_list library_list;
1259a45ae5f8SJohn Marino
1260*ef5ccd6cSJohn Marino /* Fall back to manual examination of the target if the packet is not
1261*ef5ccd6cSJohn Marino supported or gdbserver failed to find DT_DEBUG. gdb.server/solib-list.exp
1262*ef5ccd6cSJohn Marino tests a case where gdbserver cannot find the shared libraries list while
1263*ef5ccd6cSJohn Marino GDB itself is able to find it via SYMFILE_OBJFILE.
1264*ef5ccd6cSJohn Marino
1265*ef5ccd6cSJohn Marino Unfortunately statically linked inferiors will also fall back through this
1266*ef5ccd6cSJohn Marino suboptimal code path. */
1267*ef5ccd6cSJohn Marino
1268a45ae5f8SJohn Marino if (svr4_current_sos_via_xfer_libraries (&library_list))
1269a45ae5f8SJohn Marino {
1270a45ae5f8SJohn Marino if (library_list.main_lm)
1271a45ae5f8SJohn Marino {
1272a45ae5f8SJohn Marino info = get_svr4_info ();
1273a45ae5f8SJohn Marino info->main_lm_addr = library_list.main_lm;
1274a45ae5f8SJohn Marino }
1275a45ae5f8SJohn Marino
1276a45ae5f8SJohn Marino return library_list.head ? library_list.head : svr4_default_sos ();
1277a45ae5f8SJohn Marino }
12785796c8dcSSimon Schubert
1279cf7f2e2dSJohn Marino info = get_svr4_info ();
12805796c8dcSSimon Schubert
12815796c8dcSSimon Schubert /* Always locate the debug struct, in case it has moved. */
12825796c8dcSSimon Schubert info->debug_base = 0;
12835796c8dcSSimon Schubert locate_base (info);
12845796c8dcSSimon Schubert
12855796c8dcSSimon Schubert /* If we can't find the dynamic linker's base structure, this
12865796c8dcSSimon Schubert must not be a dynamically linked executable. Hmm. */
12875796c8dcSSimon Schubert if (! info->debug_base)
12885796c8dcSSimon Schubert return svr4_default_sos ();
12895796c8dcSSimon Schubert
1290a45ae5f8SJohn Marino /* Assume that everything is a library if the dynamic loader was loaded
1291a45ae5f8SJohn Marino late by a static executable. */
1292a45ae5f8SJohn Marino if (exec_bfd && bfd_get_section_by_name (exec_bfd, ".dynamic") == NULL)
1293a45ae5f8SJohn Marino ignore_first = 0;
1294a45ae5f8SJohn Marino else
1295a45ae5f8SJohn Marino ignore_first = 1;
1296a45ae5f8SJohn Marino
1297a45ae5f8SJohn Marino back_to = make_cleanup (svr4_free_library_list, &head);
1298a45ae5f8SJohn Marino
12995796c8dcSSimon Schubert /* Walk the inferior's link map list, and build our list of
13005796c8dcSSimon Schubert `struct so_list' nodes. */
13015796c8dcSSimon Schubert lm = solib_svr4_r_map (info);
1302a45ae5f8SJohn Marino if (lm)
1303a45ae5f8SJohn Marino svr4_read_so_list (lm, &link_ptr, ignore_first);
1304cf7f2e2dSJohn Marino
13055796c8dcSSimon Schubert /* On Solaris, the dynamic linker is not in the normal list of
13065796c8dcSSimon Schubert shared objects, so make sure we pick it up too. Having
13075796c8dcSSimon Schubert symbol information for the dynamic linker is quite crucial
13085796c8dcSSimon Schubert for skipping dynamic linker resolver code. */
1309a45ae5f8SJohn Marino lm = solib_svr4_r_ldsomap (info);
1310a45ae5f8SJohn Marino if (lm)
1311a45ae5f8SJohn Marino svr4_read_so_list (lm, &link_ptr, 0);
13125796c8dcSSimon Schubert
1313a45ae5f8SJohn Marino discard_cleanups (back_to);
13145796c8dcSSimon Schubert
13155796c8dcSSimon Schubert if (head == NULL)
13165796c8dcSSimon Schubert return svr4_default_sos ();
13175796c8dcSSimon Schubert
13185796c8dcSSimon Schubert return head;
13195796c8dcSSimon Schubert }
13205796c8dcSSimon Schubert
13215796c8dcSSimon Schubert /* Get the address of the link_map for a given OBJFILE. */
13225796c8dcSSimon Schubert
13235796c8dcSSimon Schubert CORE_ADDR
svr4_fetch_objfile_link_map(struct objfile * objfile)13245796c8dcSSimon Schubert svr4_fetch_objfile_link_map (struct objfile *objfile)
13255796c8dcSSimon Schubert {
13265796c8dcSSimon Schubert struct so_list *so;
1327cf7f2e2dSJohn Marino struct svr4_info *info = get_svr4_info ();
13285796c8dcSSimon Schubert
13295796c8dcSSimon Schubert /* Cause svr4_current_sos() to be run if it hasn't been already. */
13305796c8dcSSimon Schubert if (info->main_lm_addr == 0)
13315796c8dcSSimon Schubert solib_add (NULL, 0, ¤t_target, auto_solib_add);
13325796c8dcSSimon Schubert
13335796c8dcSSimon Schubert /* svr4_current_sos() will set main_lm_addr for the main executable. */
13345796c8dcSSimon Schubert if (objfile == symfile_objfile)
13355796c8dcSSimon Schubert return info->main_lm_addr;
13365796c8dcSSimon Schubert
13375796c8dcSSimon Schubert /* The other link map addresses may be found by examining the list
13385796c8dcSSimon Schubert of shared libraries. */
13395796c8dcSSimon Schubert for (so = master_so_list (); so; so = so->next)
13405796c8dcSSimon Schubert if (so->objfile == objfile)
13415796c8dcSSimon Schubert return so->lm_info->lm_addr;
13425796c8dcSSimon Schubert
13435796c8dcSSimon Schubert /* Not found! */
13445796c8dcSSimon Schubert return 0;
13455796c8dcSSimon Schubert }
13465796c8dcSSimon Schubert
13475796c8dcSSimon Schubert /* On some systems, the only way to recognize the link map entry for
13485796c8dcSSimon Schubert the main executable file is by looking at its name. Return
13495796c8dcSSimon Schubert non-zero iff SONAME matches one of the known main executable names. */
13505796c8dcSSimon Schubert
13515796c8dcSSimon Schubert static int
match_main(const char * soname)1352c50c785cSJohn Marino match_main (const char *soname)
13535796c8dcSSimon Schubert {
1354c50c785cSJohn Marino const char * const *mainp;
13555796c8dcSSimon Schubert
13565796c8dcSSimon Schubert for (mainp = main_name_list; *mainp != NULL; mainp++)
13575796c8dcSSimon Schubert {
13585796c8dcSSimon Schubert if (strcmp (soname, *mainp) == 0)
13595796c8dcSSimon Schubert return (1);
13605796c8dcSSimon Schubert }
13615796c8dcSSimon Schubert
13625796c8dcSSimon Schubert return (0);
13635796c8dcSSimon Schubert }
13645796c8dcSSimon Schubert
13655796c8dcSSimon Schubert /* Return 1 if PC lies in the dynamic symbol resolution code of the
13665796c8dcSSimon Schubert SVR4 run time loader. */
13675796c8dcSSimon Schubert
13685796c8dcSSimon Schubert int
svr4_in_dynsym_resolve_code(CORE_ADDR pc)13695796c8dcSSimon Schubert svr4_in_dynsym_resolve_code (CORE_ADDR pc)
13705796c8dcSSimon Schubert {
1371cf7f2e2dSJohn Marino struct svr4_info *info = get_svr4_info ();
1372cf7f2e2dSJohn Marino
1373cf7f2e2dSJohn Marino return ((pc >= info->interp_text_sect_low
1374cf7f2e2dSJohn Marino && pc < info->interp_text_sect_high)
1375cf7f2e2dSJohn Marino || (pc >= info->interp_plt_sect_low
1376cf7f2e2dSJohn Marino && pc < info->interp_plt_sect_high)
1377c50c785cSJohn Marino || in_plt_section (pc, NULL)
1378c50c785cSJohn Marino || in_gnu_ifunc_stub (pc));
13795796c8dcSSimon Schubert }
13805796c8dcSSimon Schubert
13815796c8dcSSimon Schubert /* Given an executable's ABFD and target, compute the entry-point
13825796c8dcSSimon Schubert address. */
13835796c8dcSSimon Schubert
13845796c8dcSSimon Schubert static CORE_ADDR
exec_entry_point(struct bfd * abfd,struct target_ops * targ)13855796c8dcSSimon Schubert exec_entry_point (struct bfd *abfd, struct target_ops *targ)
13865796c8dcSSimon Schubert {
1387*ef5ccd6cSJohn Marino CORE_ADDR addr;
1388*ef5ccd6cSJohn Marino
13895796c8dcSSimon Schubert /* KevinB wrote ... for most targets, the address returned by
13905796c8dcSSimon Schubert bfd_get_start_address() is the entry point for the start
13915796c8dcSSimon Schubert function. But, for some targets, bfd_get_start_address() returns
13925796c8dcSSimon Schubert the address of a function descriptor from which the entry point
13935796c8dcSSimon Schubert address may be extracted. This address is extracted by
13945796c8dcSSimon Schubert gdbarch_convert_from_func_ptr_addr(). The method
13955796c8dcSSimon Schubert gdbarch_convert_from_func_ptr_addr() is the merely the identify
13965796c8dcSSimon Schubert function for targets which don't use function descriptors. */
1397*ef5ccd6cSJohn Marino addr = gdbarch_convert_from_func_ptr_addr (target_gdbarch (),
13985796c8dcSSimon Schubert bfd_get_start_address (abfd),
13995796c8dcSSimon Schubert targ);
1400*ef5ccd6cSJohn Marino return gdbarch_addr_bits_remove (target_gdbarch (), addr);
14015796c8dcSSimon Schubert }
14025796c8dcSSimon Schubert
1403a45ae5f8SJohn Marino /* Helper function for gdb_bfd_lookup_symbol. */
14045796c8dcSSimon Schubert
1405a45ae5f8SJohn Marino static int
cmp_name_and_sec_flags(asymbol * sym,void * data)1406a45ae5f8SJohn Marino cmp_name_and_sec_flags (asymbol *sym, void *data)
1407a45ae5f8SJohn Marino {
1408a45ae5f8SJohn Marino return (strcmp (sym->name, (const char *) data) == 0
1409a45ae5f8SJohn Marino && (sym->section->flags & (SEC_CODE | SEC_DATA)) != 0);
1410a45ae5f8SJohn Marino }
1411a45ae5f8SJohn Marino /* Arrange for dynamic linker to hit breakpoint.
14125796c8dcSSimon Schubert
14135796c8dcSSimon Schubert Both the SunOS and the SVR4 dynamic linkers have, as part of their
14145796c8dcSSimon Schubert debugger interface, support for arranging for the inferior to hit
14155796c8dcSSimon Schubert a breakpoint after mapping in the shared libraries. This function
14165796c8dcSSimon Schubert enables that breakpoint.
14175796c8dcSSimon Schubert
14185796c8dcSSimon Schubert For SunOS, there is a special flag location (in_debugger) which we
14195796c8dcSSimon Schubert set to 1. When the dynamic linker sees this flag set, it will set
14205796c8dcSSimon Schubert a breakpoint at a location known only to itself, after saving the
14215796c8dcSSimon Schubert original contents of that place and the breakpoint address itself,
14225796c8dcSSimon Schubert in it's own internal structures. When we resume the inferior, it
14235796c8dcSSimon Schubert will eventually take a SIGTRAP when it runs into the breakpoint.
14245796c8dcSSimon Schubert We handle this (in a different place) by restoring the contents of
14255796c8dcSSimon Schubert the breakpointed location (which is only known after it stops),
14265796c8dcSSimon Schubert chasing around to locate the shared libraries that have been
14275796c8dcSSimon Schubert loaded, then resuming.
14285796c8dcSSimon Schubert
14295796c8dcSSimon Schubert For SVR4, the debugger interface structure contains a member (r_brk)
14305796c8dcSSimon Schubert which is statically initialized at the time the shared library is
14315796c8dcSSimon Schubert built, to the offset of a function (_r_debug_state) which is guaran-
14325796c8dcSSimon Schubert teed to be called once before mapping in a library, and again when
14335796c8dcSSimon Schubert the mapping is complete. At the time we are examining this member,
14345796c8dcSSimon Schubert it contains only the unrelocated offset of the function, so we have
14355796c8dcSSimon Schubert to do our own relocation. Later, when the dynamic linker actually
14365796c8dcSSimon Schubert runs, it relocates r_brk to be the actual address of _r_debug_state().
14375796c8dcSSimon Schubert
14385796c8dcSSimon Schubert The debugger interface structure also contains an enumeration which
14395796c8dcSSimon Schubert is set to either RT_ADD or RT_DELETE prior to changing the mapping,
14405796c8dcSSimon Schubert depending upon whether or not the library is being mapped or unmapped,
1441a45ae5f8SJohn Marino and then set to RT_CONSISTENT after the library is mapped/unmapped. */
14425796c8dcSSimon Schubert
14435796c8dcSSimon Schubert static int
enable_break(struct svr4_info * info,int from_tty)1444cf7f2e2dSJohn Marino enable_break (struct svr4_info *info, int from_tty)
14455796c8dcSSimon Schubert {
14465796c8dcSSimon Schubert struct minimal_symbol *msymbol;
1447c50c785cSJohn Marino const char * const *bkpt_namep;
14485796c8dcSSimon Schubert asection *interp_sect;
14495796c8dcSSimon Schubert gdb_byte *interp_name;
14505796c8dcSSimon Schubert CORE_ADDR sym_addr;
14515796c8dcSSimon Schubert
1452cf7f2e2dSJohn Marino info->interp_text_sect_low = info->interp_text_sect_high = 0;
1453cf7f2e2dSJohn Marino info->interp_plt_sect_low = info->interp_plt_sect_high = 0;
14545796c8dcSSimon Schubert
14555796c8dcSSimon Schubert /* If we already have a shared library list in the target, and
14565796c8dcSSimon Schubert r_debug contains r_brk, set the breakpoint there - this should
14575796c8dcSSimon Schubert mean r_brk has already been relocated. Assume the dynamic linker
14585796c8dcSSimon Schubert is the object containing r_brk. */
14595796c8dcSSimon Schubert
1460cf7f2e2dSJohn Marino solib_add (NULL, from_tty, ¤t_target, auto_solib_add);
14615796c8dcSSimon Schubert sym_addr = 0;
14625796c8dcSSimon Schubert if (info->debug_base && solib_svr4_r_map (info) != 0)
14635796c8dcSSimon Schubert sym_addr = solib_svr4_r_brk (info);
14645796c8dcSSimon Schubert
14655796c8dcSSimon Schubert if (sym_addr != 0)
14665796c8dcSSimon Schubert {
14675796c8dcSSimon Schubert struct obj_section *os;
14685796c8dcSSimon Schubert
14695796c8dcSSimon Schubert sym_addr = gdbarch_addr_bits_remove
1470*ef5ccd6cSJohn Marino (target_gdbarch (), gdbarch_convert_from_func_ptr_addr (target_gdbarch (),
14715796c8dcSSimon Schubert sym_addr,
14725796c8dcSSimon Schubert ¤t_target));
14735796c8dcSSimon Schubert
1474cf7f2e2dSJohn Marino /* On at least some versions of Solaris there's a dynamic relocation
1475cf7f2e2dSJohn Marino on _r_debug.r_brk and SYM_ADDR may not be relocated yet, e.g., if
1476cf7f2e2dSJohn Marino we get control before the dynamic linker has self-relocated.
1477cf7f2e2dSJohn Marino Check if SYM_ADDR is in a known section, if it is assume we can
1478cf7f2e2dSJohn Marino trust its value. This is just a heuristic though, it could go away
1479cf7f2e2dSJohn Marino or be replaced if it's getting in the way.
1480cf7f2e2dSJohn Marino
1481cf7f2e2dSJohn Marino On ARM we need to know whether the ISA of rtld_db_dlactivity (or
1482cf7f2e2dSJohn Marino however it's spelled in your particular system) is ARM or Thumb.
1483cf7f2e2dSJohn Marino That knowledge is encoded in the address, if it's Thumb the low bit
1484cf7f2e2dSJohn Marino is 1. However, we've stripped that info above and it's not clear
1485cf7f2e2dSJohn Marino what all the consequences are of passing a non-addr_bits_remove'd
1486cf7f2e2dSJohn Marino address to create_solib_event_breakpoint. The call to
1487cf7f2e2dSJohn Marino find_pc_section verifies we know about the address and have some
1488cf7f2e2dSJohn Marino hope of computing the right kind of breakpoint to use (via
1489cf7f2e2dSJohn Marino symbol info). It does mean that GDB needs to be pointed at a
1490cf7f2e2dSJohn Marino non-stripped version of the dynamic linker in order to obtain
1491cf7f2e2dSJohn Marino information it already knows about. Sigh. */
1492cf7f2e2dSJohn Marino
14935796c8dcSSimon Schubert os = find_pc_section (sym_addr);
14945796c8dcSSimon Schubert if (os != NULL)
14955796c8dcSSimon Schubert {
14965796c8dcSSimon Schubert /* Record the relocated start and end address of the dynamic linker
14975796c8dcSSimon Schubert text and plt section for svr4_in_dynsym_resolve_code. */
14985796c8dcSSimon Schubert bfd *tmp_bfd;
14995796c8dcSSimon Schubert CORE_ADDR load_addr;
15005796c8dcSSimon Schubert
15015796c8dcSSimon Schubert tmp_bfd = os->objfile->obfd;
15025796c8dcSSimon Schubert load_addr = ANOFFSET (os->objfile->section_offsets,
1503*ef5ccd6cSJohn Marino SECT_OFF_TEXT (os->objfile));
15045796c8dcSSimon Schubert
15055796c8dcSSimon Schubert interp_sect = bfd_get_section_by_name (tmp_bfd, ".text");
15065796c8dcSSimon Schubert if (interp_sect)
15075796c8dcSSimon Schubert {
1508cf7f2e2dSJohn Marino info->interp_text_sect_low =
15095796c8dcSSimon Schubert bfd_section_vma (tmp_bfd, interp_sect) + load_addr;
1510cf7f2e2dSJohn Marino info->interp_text_sect_high =
1511cf7f2e2dSJohn Marino info->interp_text_sect_low
1512cf7f2e2dSJohn Marino + bfd_section_size (tmp_bfd, interp_sect);
15135796c8dcSSimon Schubert }
15145796c8dcSSimon Schubert interp_sect = bfd_get_section_by_name (tmp_bfd, ".plt");
15155796c8dcSSimon Schubert if (interp_sect)
15165796c8dcSSimon Schubert {
1517cf7f2e2dSJohn Marino info->interp_plt_sect_low =
15185796c8dcSSimon Schubert bfd_section_vma (tmp_bfd, interp_sect) + load_addr;
1519cf7f2e2dSJohn Marino info->interp_plt_sect_high =
1520cf7f2e2dSJohn Marino info->interp_plt_sect_low
1521cf7f2e2dSJohn Marino + bfd_section_size (tmp_bfd, interp_sect);
15225796c8dcSSimon Schubert }
15235796c8dcSSimon Schubert
1524*ef5ccd6cSJohn Marino create_solib_event_breakpoint (target_gdbarch (), sym_addr);
15255796c8dcSSimon Schubert return 1;
15265796c8dcSSimon Schubert }
15275796c8dcSSimon Schubert }
15285796c8dcSSimon Schubert
15295796c8dcSSimon Schubert /* Find the program interpreter; if not found, warn the user and drop
15305796c8dcSSimon Schubert into the old breakpoint at symbol code. */
15315796c8dcSSimon Schubert interp_name = find_program_interpreter ();
15325796c8dcSSimon Schubert if (interp_name)
15335796c8dcSSimon Schubert {
15345796c8dcSSimon Schubert CORE_ADDR load_addr = 0;
15355796c8dcSSimon Schubert int load_addr_found = 0;
15365796c8dcSSimon Schubert int loader_found_in_list = 0;
15375796c8dcSSimon Schubert struct so_list *so;
15385796c8dcSSimon Schubert bfd *tmp_bfd = NULL;
15395796c8dcSSimon Schubert struct target_ops *tmp_bfd_target;
15405796c8dcSSimon Schubert volatile struct gdb_exception ex;
15415796c8dcSSimon Schubert
15425796c8dcSSimon Schubert sym_addr = 0;
15435796c8dcSSimon Schubert
15445796c8dcSSimon Schubert /* Now we need to figure out where the dynamic linker was
15455796c8dcSSimon Schubert loaded so that we can load its symbols and place a breakpoint
15465796c8dcSSimon Schubert in the dynamic linker itself.
15475796c8dcSSimon Schubert
15485796c8dcSSimon Schubert This address is stored on the stack. However, I've been unable
15495796c8dcSSimon Schubert to find any magic formula to find it for Solaris (appears to
15505796c8dcSSimon Schubert be trivial on GNU/Linux). Therefore, we have to try an alternate
15515796c8dcSSimon Schubert mechanism to find the dynamic linker's base address. */
15525796c8dcSSimon Schubert
15535796c8dcSSimon Schubert TRY_CATCH (ex, RETURN_MASK_ALL)
15545796c8dcSSimon Schubert {
15555796c8dcSSimon Schubert tmp_bfd = solib_bfd_open (interp_name);
15565796c8dcSSimon Schubert }
15575796c8dcSSimon Schubert if (tmp_bfd == NULL)
15585796c8dcSSimon Schubert goto bkpt_at_symbol;
15595796c8dcSSimon Schubert
15605796c8dcSSimon Schubert /* Now convert the TMP_BFD into a target. That way target, as
1561*ef5ccd6cSJohn Marino well as BFD operations can be used. */
15625796c8dcSSimon Schubert tmp_bfd_target = target_bfd_reopen (tmp_bfd);
1563*ef5ccd6cSJohn Marino /* target_bfd_reopen acquired its own reference, so we can
1564*ef5ccd6cSJohn Marino release ours now. */
1565*ef5ccd6cSJohn Marino gdb_bfd_unref (tmp_bfd);
15665796c8dcSSimon Schubert
15675796c8dcSSimon Schubert /* On a running target, we can get the dynamic linker's base
15685796c8dcSSimon Schubert address from the shared library table. */
15695796c8dcSSimon Schubert so = master_so_list ();
15705796c8dcSSimon Schubert while (so)
15715796c8dcSSimon Schubert {
15725796c8dcSSimon Schubert if (svr4_same_1 (interp_name, so->so_original_name))
15735796c8dcSSimon Schubert {
15745796c8dcSSimon Schubert load_addr_found = 1;
15755796c8dcSSimon Schubert loader_found_in_list = 1;
1576a45ae5f8SJohn Marino load_addr = lm_addr_check (so, tmp_bfd);
15775796c8dcSSimon Schubert break;
15785796c8dcSSimon Schubert }
15795796c8dcSSimon Schubert so = so->next;
15805796c8dcSSimon Schubert }
15815796c8dcSSimon Schubert
15825796c8dcSSimon Schubert /* If we were not able to find the base address of the loader
15835796c8dcSSimon Schubert from our so_list, then try using the AT_BASE auxilliary entry. */
15845796c8dcSSimon Schubert if (!load_addr_found)
15855796c8dcSSimon Schubert if (target_auxv_search (¤t_target, AT_BASE, &load_addr) > 0)
1586cf7f2e2dSJohn Marino {
1587*ef5ccd6cSJohn Marino int addr_bit = gdbarch_addr_bit (target_gdbarch ());
1588cf7f2e2dSJohn Marino
1589cf7f2e2dSJohn Marino /* Ensure LOAD_ADDR has proper sign in its possible upper bits so
1590cf7f2e2dSJohn Marino that `+ load_addr' will overflow CORE_ADDR width not creating
1591cf7f2e2dSJohn Marino invalid addresses like 0x101234567 for 32bit inferiors on 64bit
1592cf7f2e2dSJohn Marino GDB. */
1593cf7f2e2dSJohn Marino
1594cf7f2e2dSJohn Marino if (addr_bit < (sizeof (CORE_ADDR) * HOST_CHAR_BIT))
1595cf7f2e2dSJohn Marino {
1596cf7f2e2dSJohn Marino CORE_ADDR space_size = (CORE_ADDR) 1 << addr_bit;
1597cf7f2e2dSJohn Marino CORE_ADDR tmp_entry_point = exec_entry_point (tmp_bfd,
1598cf7f2e2dSJohn Marino tmp_bfd_target);
1599cf7f2e2dSJohn Marino
1600cf7f2e2dSJohn Marino gdb_assert (load_addr < space_size);
1601cf7f2e2dSJohn Marino
1602cf7f2e2dSJohn Marino /* TMP_ENTRY_POINT exceeding SPACE_SIZE would be for prelinked
1603cf7f2e2dSJohn Marino 64bit ld.so with 32bit executable, it should not happen. */
1604cf7f2e2dSJohn Marino
1605cf7f2e2dSJohn Marino if (tmp_entry_point < space_size
1606cf7f2e2dSJohn Marino && tmp_entry_point + load_addr >= space_size)
1607cf7f2e2dSJohn Marino load_addr -= space_size;
1608cf7f2e2dSJohn Marino }
1609cf7f2e2dSJohn Marino
16105796c8dcSSimon Schubert load_addr_found = 1;
1611cf7f2e2dSJohn Marino }
16125796c8dcSSimon Schubert
16135796c8dcSSimon Schubert /* Otherwise we find the dynamic linker's base address by examining
16145796c8dcSSimon Schubert the current pc (which should point at the entry point for the
16155796c8dcSSimon Schubert dynamic linker) and subtracting the offset of the entry point.
16165796c8dcSSimon Schubert
16175796c8dcSSimon Schubert This is more fragile than the previous approaches, but is a good
16185796c8dcSSimon Schubert fallback method because it has actually been working well in
16195796c8dcSSimon Schubert most cases. */
16205796c8dcSSimon Schubert if (!load_addr_found)
16215796c8dcSSimon Schubert {
16225796c8dcSSimon Schubert struct regcache *regcache
1623*ef5ccd6cSJohn Marino = get_thread_arch_regcache (inferior_ptid, target_gdbarch ());
1624cf7f2e2dSJohn Marino
16255796c8dcSSimon Schubert load_addr = (regcache_read_pc (regcache)
16265796c8dcSSimon Schubert - exec_entry_point (tmp_bfd, tmp_bfd_target));
16275796c8dcSSimon Schubert }
16285796c8dcSSimon Schubert
16295796c8dcSSimon Schubert if (!loader_found_in_list)
16305796c8dcSSimon Schubert {
16315796c8dcSSimon Schubert info->debug_loader_name = xstrdup (interp_name);
16325796c8dcSSimon Schubert info->debug_loader_offset_p = 1;
16335796c8dcSSimon Schubert info->debug_loader_offset = load_addr;
1634cf7f2e2dSJohn Marino solib_add (NULL, from_tty, ¤t_target, auto_solib_add);
16355796c8dcSSimon Schubert }
16365796c8dcSSimon Schubert
16375796c8dcSSimon Schubert /* Record the relocated start and end address of the dynamic linker
16385796c8dcSSimon Schubert text and plt section for svr4_in_dynsym_resolve_code. */
16395796c8dcSSimon Schubert interp_sect = bfd_get_section_by_name (tmp_bfd, ".text");
16405796c8dcSSimon Schubert if (interp_sect)
16415796c8dcSSimon Schubert {
1642cf7f2e2dSJohn Marino info->interp_text_sect_low =
16435796c8dcSSimon Schubert bfd_section_vma (tmp_bfd, interp_sect) + load_addr;
1644cf7f2e2dSJohn Marino info->interp_text_sect_high =
1645cf7f2e2dSJohn Marino info->interp_text_sect_low
1646cf7f2e2dSJohn Marino + bfd_section_size (tmp_bfd, interp_sect);
16475796c8dcSSimon Schubert }
16485796c8dcSSimon Schubert interp_sect = bfd_get_section_by_name (tmp_bfd, ".plt");
16495796c8dcSSimon Schubert if (interp_sect)
16505796c8dcSSimon Schubert {
1651cf7f2e2dSJohn Marino info->interp_plt_sect_low =
16525796c8dcSSimon Schubert bfd_section_vma (tmp_bfd, interp_sect) + load_addr;
1653cf7f2e2dSJohn Marino info->interp_plt_sect_high =
1654cf7f2e2dSJohn Marino info->interp_plt_sect_low
1655cf7f2e2dSJohn Marino + bfd_section_size (tmp_bfd, interp_sect);
16565796c8dcSSimon Schubert }
16575796c8dcSSimon Schubert
16585796c8dcSSimon Schubert /* Now try to set a breakpoint in the dynamic linker. */
16595796c8dcSSimon Schubert for (bkpt_namep = solib_break_names; *bkpt_namep != NULL; bkpt_namep++)
16605796c8dcSSimon Schubert {
1661a45ae5f8SJohn Marino sym_addr = gdb_bfd_lookup_symbol (tmp_bfd, cmp_name_and_sec_flags,
1662a45ae5f8SJohn Marino (void *) *bkpt_namep);
16635796c8dcSSimon Schubert if (sym_addr != 0)
16645796c8dcSSimon Schubert break;
16655796c8dcSSimon Schubert }
16665796c8dcSSimon Schubert
16675796c8dcSSimon Schubert if (sym_addr != 0)
16685796c8dcSSimon Schubert /* Convert 'sym_addr' from a function pointer to an address.
16695796c8dcSSimon Schubert Because we pass tmp_bfd_target instead of the current
16705796c8dcSSimon Schubert target, this will always produce an unrelocated value. */
1671*ef5ccd6cSJohn Marino sym_addr = gdbarch_convert_from_func_ptr_addr (target_gdbarch (),
16725796c8dcSSimon Schubert sym_addr,
16735796c8dcSSimon Schubert tmp_bfd_target);
16745796c8dcSSimon Schubert
1675*ef5ccd6cSJohn Marino /* We're done with both the temporary bfd and target. Closing
1676*ef5ccd6cSJohn Marino the target closes the underlying bfd, because it holds the
1677*ef5ccd6cSJohn Marino only remaining reference. */
16785796c8dcSSimon Schubert target_close (tmp_bfd_target, 0);
16795796c8dcSSimon Schubert
16805796c8dcSSimon Schubert if (sym_addr != 0)
16815796c8dcSSimon Schubert {
1682*ef5ccd6cSJohn Marino create_solib_event_breakpoint (target_gdbarch (), load_addr + sym_addr);
16835796c8dcSSimon Schubert xfree (interp_name);
16845796c8dcSSimon Schubert return 1;
16855796c8dcSSimon Schubert }
16865796c8dcSSimon Schubert
16875796c8dcSSimon Schubert /* For whatever reason we couldn't set a breakpoint in the dynamic
16885796c8dcSSimon Schubert linker. Warn and drop into the old code. */
16895796c8dcSSimon Schubert bkpt_at_symbol:
16905796c8dcSSimon Schubert xfree (interp_name);
16915796c8dcSSimon Schubert warning (_("Unable to find dynamic linker breakpoint function.\n"
16925796c8dcSSimon Schubert "GDB will be unable to debug shared library initializers\n"
16935796c8dcSSimon Schubert "and track explicitly loaded dynamic code."));
16945796c8dcSSimon Schubert }
16955796c8dcSSimon Schubert
16965796c8dcSSimon Schubert /* Scan through the lists of symbols, trying to look up the symbol and
16975796c8dcSSimon Schubert set a breakpoint there. Terminate loop when we/if we succeed. */
16985796c8dcSSimon Schubert
16995796c8dcSSimon Schubert for (bkpt_namep = solib_break_names; *bkpt_namep != NULL; bkpt_namep++)
17005796c8dcSSimon Schubert {
17015796c8dcSSimon Schubert msymbol = lookup_minimal_symbol (*bkpt_namep, NULL, symfile_objfile);
17025796c8dcSSimon Schubert if ((msymbol != NULL) && (SYMBOL_VALUE_ADDRESS (msymbol) != 0))
17035796c8dcSSimon Schubert {
1704cf7f2e2dSJohn Marino sym_addr = SYMBOL_VALUE_ADDRESS (msymbol);
1705*ef5ccd6cSJohn Marino sym_addr = gdbarch_convert_from_func_ptr_addr (target_gdbarch (),
1706cf7f2e2dSJohn Marino sym_addr,
1707cf7f2e2dSJohn Marino ¤t_target);
1708*ef5ccd6cSJohn Marino create_solib_event_breakpoint (target_gdbarch (), sym_addr);
17095796c8dcSSimon Schubert return 1;
17105796c8dcSSimon Schubert }
17115796c8dcSSimon Schubert }
17125796c8dcSSimon Schubert
1713*ef5ccd6cSJohn Marino if (interp_name != NULL && !current_inferior ()->attach_flag)
1714c50c785cSJohn Marino {
17155796c8dcSSimon Schubert for (bkpt_namep = bkpt_names; *bkpt_namep != NULL; bkpt_namep++)
17165796c8dcSSimon Schubert {
17175796c8dcSSimon Schubert msymbol = lookup_minimal_symbol (*bkpt_namep, NULL, symfile_objfile);
17185796c8dcSSimon Schubert if ((msymbol != NULL) && (SYMBOL_VALUE_ADDRESS (msymbol) != 0))
17195796c8dcSSimon Schubert {
1720cf7f2e2dSJohn Marino sym_addr = SYMBOL_VALUE_ADDRESS (msymbol);
1721*ef5ccd6cSJohn Marino sym_addr = gdbarch_convert_from_func_ptr_addr (target_gdbarch (),
1722cf7f2e2dSJohn Marino sym_addr,
1723cf7f2e2dSJohn Marino ¤t_target);
1724*ef5ccd6cSJohn Marino create_solib_event_breakpoint (target_gdbarch (), sym_addr);
17255796c8dcSSimon Schubert return 1;
17265796c8dcSSimon Schubert }
17275796c8dcSSimon Schubert }
1728c50c785cSJohn Marino }
17295796c8dcSSimon Schubert return 0;
17305796c8dcSSimon Schubert }
17315796c8dcSSimon Schubert
1732a45ae5f8SJohn Marino /* Implement the "special_symbol_handling" target_so_ops method. */
17335796c8dcSSimon Schubert
17345796c8dcSSimon Schubert static void
svr4_special_symbol_handling(void)17355796c8dcSSimon Schubert svr4_special_symbol_handling (void)
17365796c8dcSSimon Schubert {
1737a45ae5f8SJohn Marino /* Nothing to do. */
17385796c8dcSSimon Schubert }
17395796c8dcSSimon Schubert
1740cf7f2e2dSJohn Marino /* Read the ELF program headers from ABFD. Return the contents and
1741cf7f2e2dSJohn Marino set *PHDRS_SIZE to the size of the program headers. */
17425796c8dcSSimon Schubert
1743cf7f2e2dSJohn Marino static gdb_byte *
read_program_headers_from_bfd(bfd * abfd,int * phdrs_size)1744cf7f2e2dSJohn Marino read_program_headers_from_bfd (bfd *abfd, int *phdrs_size)
17455796c8dcSSimon Schubert {
1746cf7f2e2dSJohn Marino Elf_Internal_Ehdr *ehdr;
1747cf7f2e2dSJohn Marino gdb_byte *buf;
17485796c8dcSSimon Schubert
1749cf7f2e2dSJohn Marino ehdr = elf_elfheader (abfd);
17505796c8dcSSimon Schubert
1751cf7f2e2dSJohn Marino *phdrs_size = ehdr->e_phnum * ehdr->e_phentsize;
1752cf7f2e2dSJohn Marino if (*phdrs_size == 0)
1753cf7f2e2dSJohn Marino return NULL;
17545796c8dcSSimon Schubert
1755cf7f2e2dSJohn Marino buf = xmalloc (*phdrs_size);
1756cf7f2e2dSJohn Marino if (bfd_seek (abfd, ehdr->e_phoff, SEEK_SET) != 0
1757cf7f2e2dSJohn Marino || bfd_bread (buf, *phdrs_size, abfd) != *phdrs_size)
17585796c8dcSSimon Schubert {
1759cf7f2e2dSJohn Marino xfree (buf);
1760cf7f2e2dSJohn Marino return NULL;
1761cf7f2e2dSJohn Marino }
17625796c8dcSSimon Schubert
1763cf7f2e2dSJohn Marino return buf;
1764cf7f2e2dSJohn Marino }
1765cf7f2e2dSJohn Marino
1766cf7f2e2dSJohn Marino /* Return 1 and fill *DISPLACEMENTP with detected PIE offset of inferior
1767cf7f2e2dSJohn Marino exec_bfd. Otherwise return 0.
17685796c8dcSSimon Schubert
17695796c8dcSSimon Schubert We relocate all of the sections by the same amount. This
17705796c8dcSSimon Schubert behavior is mandated by recent editions of the System V ABI.
17715796c8dcSSimon Schubert According to the System V Application Binary Interface,
17725796c8dcSSimon Schubert Edition 4.1, page 5-5:
17735796c8dcSSimon Schubert
17745796c8dcSSimon Schubert ... Though the system chooses virtual addresses for
17755796c8dcSSimon Schubert individual processes, it maintains the segments' relative
17765796c8dcSSimon Schubert positions. Because position-independent code uses relative
17775796c8dcSSimon Schubert addressesing between segments, the difference between
17785796c8dcSSimon Schubert virtual addresses in memory must match the difference
17795796c8dcSSimon Schubert between virtual addresses in the file. The difference
17805796c8dcSSimon Schubert between the virtual address of any segment in memory and
17815796c8dcSSimon Schubert the corresponding virtual address in the file is thus a
17825796c8dcSSimon Schubert single constant value for any one executable or shared
17835796c8dcSSimon Schubert object in a given process. This difference is the base
17845796c8dcSSimon Schubert address. One use of the base address is to relocate the
17855796c8dcSSimon Schubert memory image of the program during dynamic linking.
17865796c8dcSSimon Schubert
17875796c8dcSSimon Schubert The same language also appears in Edition 4.0 of the System V
1788cf7f2e2dSJohn Marino ABI and is left unspecified in some of the earlier editions.
17895796c8dcSSimon Schubert
1790cf7f2e2dSJohn Marino Decide if the objfile needs to be relocated. As indicated above, we will
1791cf7f2e2dSJohn Marino only be here when execution is stopped. But during attachment PC can be at
1792cf7f2e2dSJohn Marino arbitrary address therefore regcache_read_pc can be misleading (contrary to
1793cf7f2e2dSJohn Marino the auxv AT_ENTRY value). Moreover for executable with interpreter section
1794cf7f2e2dSJohn Marino regcache_read_pc would point to the interpreter and not the main executable.
17955796c8dcSSimon Schubert
1796cf7f2e2dSJohn Marino So, to summarize, relocations are necessary when the start address obtained
1797cf7f2e2dSJohn Marino from the executable is different from the address in auxv AT_ENTRY entry.
17985796c8dcSSimon Schubert
1799cf7f2e2dSJohn Marino [ The astute reader will note that we also test to make sure that
1800cf7f2e2dSJohn Marino the executable in question has the DYNAMIC flag set. It is my
1801cf7f2e2dSJohn Marino opinion that this test is unnecessary (undesirable even). It
1802cf7f2e2dSJohn Marino was added to avoid inadvertent relocation of an executable
1803cf7f2e2dSJohn Marino whose e_type member in the ELF header is not ET_DYN. There may
1804cf7f2e2dSJohn Marino be a time in the future when it is desirable to do relocations
1805cf7f2e2dSJohn Marino on other types of files as well in which case this condition
1806cf7f2e2dSJohn Marino should either be removed or modified to accomodate the new file
1807cf7f2e2dSJohn Marino type. - Kevin, Nov 2000. ] */
1808cf7f2e2dSJohn Marino
1809cf7f2e2dSJohn Marino static int
svr4_exec_displacement(CORE_ADDR * displacementp)1810cf7f2e2dSJohn Marino svr4_exec_displacement (CORE_ADDR *displacementp)
18115796c8dcSSimon Schubert {
1812cf7f2e2dSJohn Marino /* ENTRY_POINT is a possible function descriptor - before
1813cf7f2e2dSJohn Marino a call to gdbarch_convert_from_func_ptr_addr. */
1814cf7f2e2dSJohn Marino CORE_ADDR entry_point, displacement;
1815cf7f2e2dSJohn Marino
1816cf7f2e2dSJohn Marino if (exec_bfd == NULL)
1817cf7f2e2dSJohn Marino return 0;
1818cf7f2e2dSJohn Marino
1819cf7f2e2dSJohn Marino /* Therefore for ELF it is ET_EXEC and not ET_DYN. Both shared libraries
1820cf7f2e2dSJohn Marino being executed themselves and PIE (Position Independent Executable)
1821cf7f2e2dSJohn Marino executables are ET_DYN. */
1822cf7f2e2dSJohn Marino
1823cf7f2e2dSJohn Marino if ((bfd_get_file_flags (exec_bfd) & DYNAMIC) == 0)
1824cf7f2e2dSJohn Marino return 0;
1825cf7f2e2dSJohn Marino
1826cf7f2e2dSJohn Marino if (target_auxv_search (¤t_target, AT_ENTRY, &entry_point) <= 0)
1827cf7f2e2dSJohn Marino return 0;
1828cf7f2e2dSJohn Marino
1829cf7f2e2dSJohn Marino displacement = entry_point - bfd_get_start_address (exec_bfd);
1830cf7f2e2dSJohn Marino
1831cf7f2e2dSJohn Marino /* Verify the DISPLACEMENT candidate complies with the required page
1832cf7f2e2dSJohn Marino alignment. It is cheaper than the program headers comparison below. */
1833cf7f2e2dSJohn Marino
1834cf7f2e2dSJohn Marino if (bfd_get_flavour (exec_bfd) == bfd_target_elf_flavour)
1835cf7f2e2dSJohn Marino {
1836cf7f2e2dSJohn Marino const struct elf_backend_data *elf = get_elf_backend_data (exec_bfd);
1837cf7f2e2dSJohn Marino
1838cf7f2e2dSJohn Marino /* p_align of PT_LOAD segments does not specify any alignment but
1839cf7f2e2dSJohn Marino only congruency of addresses:
1840cf7f2e2dSJohn Marino p_offset % p_align == p_vaddr % p_align
1841cf7f2e2dSJohn Marino Kernel is free to load the executable with lower alignment. */
1842cf7f2e2dSJohn Marino
1843cf7f2e2dSJohn Marino if ((displacement & (elf->minpagesize - 1)) != 0)
1844cf7f2e2dSJohn Marino return 0;
18455796c8dcSSimon Schubert }
18465796c8dcSSimon Schubert
1847cf7f2e2dSJohn Marino /* Verify that the auxilliary vector describes the same file as exec_bfd, by
1848cf7f2e2dSJohn Marino comparing their program headers. If the program headers in the auxilliary
1849cf7f2e2dSJohn Marino vector do not match the program headers in the executable, then we are
1850cf7f2e2dSJohn Marino looking at a different file than the one used by the kernel - for
1851cf7f2e2dSJohn Marino instance, "gdb program" connected to "gdbserver :PORT ld.so program". */
18525796c8dcSSimon Schubert
1853cf7f2e2dSJohn Marino if (bfd_get_flavour (exec_bfd) == bfd_target_elf_flavour)
1854cf7f2e2dSJohn Marino {
1855cf7f2e2dSJohn Marino /* Be optimistic and clear OK only if GDB was able to verify the headers
1856cf7f2e2dSJohn Marino really do not match. */
1857cf7f2e2dSJohn Marino int phdrs_size, phdrs2_size, ok = 1;
1858cf7f2e2dSJohn Marino gdb_byte *buf, *buf2;
1859cf7f2e2dSJohn Marino int arch_size;
1860cf7f2e2dSJohn Marino
1861cf7f2e2dSJohn Marino buf = read_program_header (-1, &phdrs_size, &arch_size);
1862cf7f2e2dSJohn Marino buf2 = read_program_headers_from_bfd (exec_bfd, &phdrs2_size);
1863cf7f2e2dSJohn Marino if (buf != NULL && buf2 != NULL)
1864cf7f2e2dSJohn Marino {
1865*ef5ccd6cSJohn Marino enum bfd_endian byte_order = gdbarch_byte_order (target_gdbarch ());
1866cf7f2e2dSJohn Marino
1867cf7f2e2dSJohn Marino /* We are dealing with three different addresses. EXEC_BFD
1868cf7f2e2dSJohn Marino represents current address in on-disk file. target memory content
1869cf7f2e2dSJohn Marino may be different from EXEC_BFD as the file may have been prelinked
1870cf7f2e2dSJohn Marino to a different address after the executable has been loaded.
1871cf7f2e2dSJohn Marino Moreover the address of placement in target memory can be
1872c50c785cSJohn Marino different from what the program headers in target memory say -
1873c50c785cSJohn Marino this is the goal of PIE.
1874cf7f2e2dSJohn Marino
1875cf7f2e2dSJohn Marino Detected DISPLACEMENT covers both the offsets of PIE placement and
1876cf7f2e2dSJohn Marino possible new prelink performed after start of the program. Here
1877cf7f2e2dSJohn Marino relocate BUF and BUF2 just by the EXEC_BFD vs. target memory
1878cf7f2e2dSJohn Marino content offset for the verification purpose. */
1879cf7f2e2dSJohn Marino
1880cf7f2e2dSJohn Marino if (phdrs_size != phdrs2_size
1881cf7f2e2dSJohn Marino || bfd_get_arch_size (exec_bfd) != arch_size)
1882cf7f2e2dSJohn Marino ok = 0;
1883c50c785cSJohn Marino else if (arch_size == 32
1884c50c785cSJohn Marino && phdrs_size >= sizeof (Elf32_External_Phdr)
1885cf7f2e2dSJohn Marino && phdrs_size % sizeof (Elf32_External_Phdr) == 0)
1886cf7f2e2dSJohn Marino {
1887cf7f2e2dSJohn Marino Elf_Internal_Ehdr *ehdr2 = elf_tdata (exec_bfd)->elf_header;
1888cf7f2e2dSJohn Marino Elf_Internal_Phdr *phdr2 = elf_tdata (exec_bfd)->phdr;
1889cf7f2e2dSJohn Marino CORE_ADDR displacement = 0;
1890cf7f2e2dSJohn Marino int i;
1891cf7f2e2dSJohn Marino
1892cf7f2e2dSJohn Marino /* DISPLACEMENT could be found more easily by the difference of
1893cf7f2e2dSJohn Marino ehdr2->e_entry. But we haven't read the ehdr yet, and we
1894cf7f2e2dSJohn Marino already have enough information to compute that displacement
1895cf7f2e2dSJohn Marino with what we've read. */
1896cf7f2e2dSJohn Marino
1897cf7f2e2dSJohn Marino for (i = 0; i < ehdr2->e_phnum; i++)
1898cf7f2e2dSJohn Marino if (phdr2[i].p_type == PT_LOAD)
1899cf7f2e2dSJohn Marino {
1900cf7f2e2dSJohn Marino Elf32_External_Phdr *phdrp;
1901cf7f2e2dSJohn Marino gdb_byte *buf_vaddr_p, *buf_paddr_p;
1902cf7f2e2dSJohn Marino CORE_ADDR vaddr, paddr;
1903cf7f2e2dSJohn Marino CORE_ADDR displacement_vaddr = 0;
1904cf7f2e2dSJohn Marino CORE_ADDR displacement_paddr = 0;
1905cf7f2e2dSJohn Marino
1906cf7f2e2dSJohn Marino phdrp = &((Elf32_External_Phdr *) buf)[i];
1907cf7f2e2dSJohn Marino buf_vaddr_p = (gdb_byte *) &phdrp->p_vaddr;
1908cf7f2e2dSJohn Marino buf_paddr_p = (gdb_byte *) &phdrp->p_paddr;
1909cf7f2e2dSJohn Marino
1910cf7f2e2dSJohn Marino vaddr = extract_unsigned_integer (buf_vaddr_p, 4,
1911cf7f2e2dSJohn Marino byte_order);
1912cf7f2e2dSJohn Marino displacement_vaddr = vaddr - phdr2[i].p_vaddr;
1913cf7f2e2dSJohn Marino
1914cf7f2e2dSJohn Marino paddr = extract_unsigned_integer (buf_paddr_p, 4,
1915cf7f2e2dSJohn Marino byte_order);
1916cf7f2e2dSJohn Marino displacement_paddr = paddr - phdr2[i].p_paddr;
1917cf7f2e2dSJohn Marino
1918cf7f2e2dSJohn Marino if (displacement_vaddr == displacement_paddr)
1919cf7f2e2dSJohn Marino displacement = displacement_vaddr;
1920cf7f2e2dSJohn Marino
1921cf7f2e2dSJohn Marino break;
1922cf7f2e2dSJohn Marino }
1923cf7f2e2dSJohn Marino
1924cf7f2e2dSJohn Marino /* Now compare BUF and BUF2 with optional DISPLACEMENT. */
1925cf7f2e2dSJohn Marino
1926cf7f2e2dSJohn Marino for (i = 0; i < phdrs_size / sizeof (Elf32_External_Phdr); i++)
1927cf7f2e2dSJohn Marino {
1928cf7f2e2dSJohn Marino Elf32_External_Phdr *phdrp;
1929cf7f2e2dSJohn Marino Elf32_External_Phdr *phdr2p;
1930cf7f2e2dSJohn Marino gdb_byte *buf_vaddr_p, *buf_paddr_p;
1931cf7f2e2dSJohn Marino CORE_ADDR vaddr, paddr;
1932c50c785cSJohn Marino asection *plt2_asect;
1933cf7f2e2dSJohn Marino
1934cf7f2e2dSJohn Marino phdrp = &((Elf32_External_Phdr *) buf)[i];
1935cf7f2e2dSJohn Marino buf_vaddr_p = (gdb_byte *) &phdrp->p_vaddr;
1936cf7f2e2dSJohn Marino buf_paddr_p = (gdb_byte *) &phdrp->p_paddr;
1937cf7f2e2dSJohn Marino phdr2p = &((Elf32_External_Phdr *) buf2)[i];
1938cf7f2e2dSJohn Marino
1939cf7f2e2dSJohn Marino /* PT_GNU_STACK is an exception by being never relocated by
1940cf7f2e2dSJohn Marino prelink as its addresses are always zero. */
1941cf7f2e2dSJohn Marino
1942cf7f2e2dSJohn Marino if (memcmp (phdrp, phdr2p, sizeof (*phdrp)) == 0)
1943cf7f2e2dSJohn Marino continue;
1944cf7f2e2dSJohn Marino
1945cf7f2e2dSJohn Marino /* Check also other adjustment combinations - PR 11786. */
1946cf7f2e2dSJohn Marino
1947c50c785cSJohn Marino vaddr = extract_unsigned_integer (buf_vaddr_p, 4,
1948c50c785cSJohn Marino byte_order);
1949cf7f2e2dSJohn Marino vaddr -= displacement;
1950cf7f2e2dSJohn Marino store_unsigned_integer (buf_vaddr_p, 4, byte_order, vaddr);
1951cf7f2e2dSJohn Marino
1952c50c785cSJohn Marino paddr = extract_unsigned_integer (buf_paddr_p, 4,
1953c50c785cSJohn Marino byte_order);
1954cf7f2e2dSJohn Marino paddr -= displacement;
1955cf7f2e2dSJohn Marino store_unsigned_integer (buf_paddr_p, 4, byte_order, paddr);
1956cf7f2e2dSJohn Marino
1957cf7f2e2dSJohn Marino if (memcmp (phdrp, phdr2p, sizeof (*phdrp)) == 0)
1958cf7f2e2dSJohn Marino continue;
1959cf7f2e2dSJohn Marino
1960c50c785cSJohn Marino /* prelink can convert .plt SHT_NOBITS to SHT_PROGBITS. */
1961c50c785cSJohn Marino plt2_asect = bfd_get_section_by_name (exec_bfd, ".plt");
1962c50c785cSJohn Marino if (plt2_asect)
1963c50c785cSJohn Marino {
1964c50c785cSJohn Marino int content2;
1965c50c785cSJohn Marino gdb_byte *buf_filesz_p = (gdb_byte *) &phdrp->p_filesz;
1966c50c785cSJohn Marino CORE_ADDR filesz;
1967c50c785cSJohn Marino
1968c50c785cSJohn Marino content2 = (bfd_get_section_flags (exec_bfd, plt2_asect)
1969c50c785cSJohn Marino & SEC_HAS_CONTENTS) != 0;
1970c50c785cSJohn Marino
1971c50c785cSJohn Marino filesz = extract_unsigned_integer (buf_filesz_p, 4,
1972c50c785cSJohn Marino byte_order);
1973c50c785cSJohn Marino
1974c50c785cSJohn Marino /* PLT2_ASECT is from on-disk file (exec_bfd) while
1975c50c785cSJohn Marino FILESZ is from the in-memory image. */
1976c50c785cSJohn Marino if (content2)
1977c50c785cSJohn Marino filesz += bfd_get_section_size (plt2_asect);
1978c50c785cSJohn Marino else
1979c50c785cSJohn Marino filesz -= bfd_get_section_size (plt2_asect);
1980c50c785cSJohn Marino
1981c50c785cSJohn Marino store_unsigned_integer (buf_filesz_p, 4, byte_order,
1982c50c785cSJohn Marino filesz);
1983c50c785cSJohn Marino
1984c50c785cSJohn Marino if (memcmp (phdrp, phdr2p, sizeof (*phdrp)) == 0)
1985c50c785cSJohn Marino continue;
1986c50c785cSJohn Marino }
1987c50c785cSJohn Marino
1988cf7f2e2dSJohn Marino ok = 0;
1989cf7f2e2dSJohn Marino break;
1990cf7f2e2dSJohn Marino }
1991cf7f2e2dSJohn Marino }
1992c50c785cSJohn Marino else if (arch_size == 64
1993c50c785cSJohn Marino && phdrs_size >= sizeof (Elf64_External_Phdr)
1994cf7f2e2dSJohn Marino && phdrs_size % sizeof (Elf64_External_Phdr) == 0)
1995cf7f2e2dSJohn Marino {
1996cf7f2e2dSJohn Marino Elf_Internal_Ehdr *ehdr2 = elf_tdata (exec_bfd)->elf_header;
1997cf7f2e2dSJohn Marino Elf_Internal_Phdr *phdr2 = elf_tdata (exec_bfd)->phdr;
1998cf7f2e2dSJohn Marino CORE_ADDR displacement = 0;
1999cf7f2e2dSJohn Marino int i;
2000cf7f2e2dSJohn Marino
2001cf7f2e2dSJohn Marino /* DISPLACEMENT could be found more easily by the difference of
2002cf7f2e2dSJohn Marino ehdr2->e_entry. But we haven't read the ehdr yet, and we
2003cf7f2e2dSJohn Marino already have enough information to compute that displacement
2004cf7f2e2dSJohn Marino with what we've read. */
2005cf7f2e2dSJohn Marino
2006cf7f2e2dSJohn Marino for (i = 0; i < ehdr2->e_phnum; i++)
2007cf7f2e2dSJohn Marino if (phdr2[i].p_type == PT_LOAD)
2008cf7f2e2dSJohn Marino {
2009cf7f2e2dSJohn Marino Elf64_External_Phdr *phdrp;
2010cf7f2e2dSJohn Marino gdb_byte *buf_vaddr_p, *buf_paddr_p;
2011cf7f2e2dSJohn Marino CORE_ADDR vaddr, paddr;
2012cf7f2e2dSJohn Marino CORE_ADDR displacement_vaddr = 0;
2013cf7f2e2dSJohn Marino CORE_ADDR displacement_paddr = 0;
2014cf7f2e2dSJohn Marino
2015cf7f2e2dSJohn Marino phdrp = &((Elf64_External_Phdr *) buf)[i];
2016cf7f2e2dSJohn Marino buf_vaddr_p = (gdb_byte *) &phdrp->p_vaddr;
2017cf7f2e2dSJohn Marino buf_paddr_p = (gdb_byte *) &phdrp->p_paddr;
2018cf7f2e2dSJohn Marino
2019cf7f2e2dSJohn Marino vaddr = extract_unsigned_integer (buf_vaddr_p, 8,
2020cf7f2e2dSJohn Marino byte_order);
2021cf7f2e2dSJohn Marino displacement_vaddr = vaddr - phdr2[i].p_vaddr;
2022cf7f2e2dSJohn Marino
2023cf7f2e2dSJohn Marino paddr = extract_unsigned_integer (buf_paddr_p, 8,
2024cf7f2e2dSJohn Marino byte_order);
2025cf7f2e2dSJohn Marino displacement_paddr = paddr - phdr2[i].p_paddr;
2026cf7f2e2dSJohn Marino
2027cf7f2e2dSJohn Marino if (displacement_vaddr == displacement_paddr)
2028cf7f2e2dSJohn Marino displacement = displacement_vaddr;
2029cf7f2e2dSJohn Marino
2030cf7f2e2dSJohn Marino break;
2031cf7f2e2dSJohn Marino }
2032cf7f2e2dSJohn Marino
2033cf7f2e2dSJohn Marino /* Now compare BUF and BUF2 with optional DISPLACEMENT. */
2034cf7f2e2dSJohn Marino
2035cf7f2e2dSJohn Marino for (i = 0; i < phdrs_size / sizeof (Elf64_External_Phdr); i++)
2036cf7f2e2dSJohn Marino {
2037cf7f2e2dSJohn Marino Elf64_External_Phdr *phdrp;
2038cf7f2e2dSJohn Marino Elf64_External_Phdr *phdr2p;
2039cf7f2e2dSJohn Marino gdb_byte *buf_vaddr_p, *buf_paddr_p;
2040cf7f2e2dSJohn Marino CORE_ADDR vaddr, paddr;
2041c50c785cSJohn Marino asection *plt2_asect;
2042cf7f2e2dSJohn Marino
2043cf7f2e2dSJohn Marino phdrp = &((Elf64_External_Phdr *) buf)[i];
2044cf7f2e2dSJohn Marino buf_vaddr_p = (gdb_byte *) &phdrp->p_vaddr;
2045cf7f2e2dSJohn Marino buf_paddr_p = (gdb_byte *) &phdrp->p_paddr;
2046cf7f2e2dSJohn Marino phdr2p = &((Elf64_External_Phdr *) buf2)[i];
2047cf7f2e2dSJohn Marino
2048cf7f2e2dSJohn Marino /* PT_GNU_STACK is an exception by being never relocated by
2049cf7f2e2dSJohn Marino prelink as its addresses are always zero. */
2050cf7f2e2dSJohn Marino
2051cf7f2e2dSJohn Marino if (memcmp (phdrp, phdr2p, sizeof (*phdrp)) == 0)
2052cf7f2e2dSJohn Marino continue;
2053cf7f2e2dSJohn Marino
2054cf7f2e2dSJohn Marino /* Check also other adjustment combinations - PR 11786. */
2055cf7f2e2dSJohn Marino
2056c50c785cSJohn Marino vaddr = extract_unsigned_integer (buf_vaddr_p, 8,
2057c50c785cSJohn Marino byte_order);
2058cf7f2e2dSJohn Marino vaddr -= displacement;
2059cf7f2e2dSJohn Marino store_unsigned_integer (buf_vaddr_p, 8, byte_order, vaddr);
2060cf7f2e2dSJohn Marino
2061c50c785cSJohn Marino paddr = extract_unsigned_integer (buf_paddr_p, 8,
2062c50c785cSJohn Marino byte_order);
2063cf7f2e2dSJohn Marino paddr -= displacement;
2064cf7f2e2dSJohn Marino store_unsigned_integer (buf_paddr_p, 8, byte_order, paddr);
2065cf7f2e2dSJohn Marino
2066cf7f2e2dSJohn Marino if (memcmp (phdrp, phdr2p, sizeof (*phdrp)) == 0)
2067cf7f2e2dSJohn Marino continue;
2068cf7f2e2dSJohn Marino
2069c50c785cSJohn Marino /* prelink can convert .plt SHT_NOBITS to SHT_PROGBITS. */
2070c50c785cSJohn Marino plt2_asect = bfd_get_section_by_name (exec_bfd, ".plt");
2071c50c785cSJohn Marino if (plt2_asect)
2072c50c785cSJohn Marino {
2073c50c785cSJohn Marino int content2;
2074c50c785cSJohn Marino gdb_byte *buf_filesz_p = (gdb_byte *) &phdrp->p_filesz;
2075c50c785cSJohn Marino CORE_ADDR filesz;
2076c50c785cSJohn Marino
2077c50c785cSJohn Marino content2 = (bfd_get_section_flags (exec_bfd, plt2_asect)
2078c50c785cSJohn Marino & SEC_HAS_CONTENTS) != 0;
2079c50c785cSJohn Marino
2080c50c785cSJohn Marino filesz = extract_unsigned_integer (buf_filesz_p, 8,
2081c50c785cSJohn Marino byte_order);
2082c50c785cSJohn Marino
2083c50c785cSJohn Marino /* PLT2_ASECT is from on-disk file (exec_bfd) while
2084c50c785cSJohn Marino FILESZ is from the in-memory image. */
2085c50c785cSJohn Marino if (content2)
2086c50c785cSJohn Marino filesz += bfd_get_section_size (plt2_asect);
2087c50c785cSJohn Marino else
2088c50c785cSJohn Marino filesz -= bfd_get_section_size (plt2_asect);
2089c50c785cSJohn Marino
2090c50c785cSJohn Marino store_unsigned_integer (buf_filesz_p, 8, byte_order,
2091c50c785cSJohn Marino filesz);
2092c50c785cSJohn Marino
2093c50c785cSJohn Marino if (memcmp (phdrp, phdr2p, sizeof (*phdrp)) == 0)
2094c50c785cSJohn Marino continue;
2095c50c785cSJohn Marino }
2096c50c785cSJohn Marino
2097cf7f2e2dSJohn Marino ok = 0;
2098cf7f2e2dSJohn Marino break;
2099cf7f2e2dSJohn Marino }
2100cf7f2e2dSJohn Marino }
2101cf7f2e2dSJohn Marino else
2102cf7f2e2dSJohn Marino ok = 0;
2103cf7f2e2dSJohn Marino }
2104cf7f2e2dSJohn Marino
2105cf7f2e2dSJohn Marino xfree (buf);
2106cf7f2e2dSJohn Marino xfree (buf2);
2107cf7f2e2dSJohn Marino
2108cf7f2e2dSJohn Marino if (!ok)
2109cf7f2e2dSJohn Marino return 0;
2110cf7f2e2dSJohn Marino }
2111cf7f2e2dSJohn Marino
2112cf7f2e2dSJohn Marino if (info_verbose)
2113cf7f2e2dSJohn Marino {
2114cf7f2e2dSJohn Marino /* It can be printed repeatedly as there is no easy way to check
2115cf7f2e2dSJohn Marino the executable symbols/file has been already relocated to
2116cf7f2e2dSJohn Marino displacement. */
2117cf7f2e2dSJohn Marino
2118cf7f2e2dSJohn Marino printf_unfiltered (_("Using PIE (Position Independent Executable) "
2119cf7f2e2dSJohn Marino "displacement %s for \"%s\".\n"),
2120*ef5ccd6cSJohn Marino paddress (target_gdbarch (), displacement),
2121cf7f2e2dSJohn Marino bfd_get_filename (exec_bfd));
2122cf7f2e2dSJohn Marino }
2123cf7f2e2dSJohn Marino
2124cf7f2e2dSJohn Marino *displacementp = displacement;
2125cf7f2e2dSJohn Marino return 1;
2126cf7f2e2dSJohn Marino }
2127cf7f2e2dSJohn Marino
2128cf7f2e2dSJohn Marino /* Relocate the main executable. This function should be called upon
2129cf7f2e2dSJohn Marino stopping the inferior process at the entry point to the program.
2130cf7f2e2dSJohn Marino The entry point from BFD is compared to the AT_ENTRY of AUXV and if they are
2131cf7f2e2dSJohn Marino different, the main executable is relocated by the proper amount. */
2132cf7f2e2dSJohn Marino
2133cf7f2e2dSJohn Marino static void
svr4_relocate_main_executable(void)2134cf7f2e2dSJohn Marino svr4_relocate_main_executable (void)
2135cf7f2e2dSJohn Marino {
2136cf7f2e2dSJohn Marino CORE_ADDR displacement;
2137cf7f2e2dSJohn Marino
2138cf7f2e2dSJohn Marino /* If we are re-running this executable, SYMFILE_OBJFILE->SECTION_OFFSETS
2139cf7f2e2dSJohn Marino probably contains the offsets computed using the PIE displacement
2140cf7f2e2dSJohn Marino from the previous run, which of course are irrelevant for this run.
2141cf7f2e2dSJohn Marino So we need to determine the new PIE displacement and recompute the
2142cf7f2e2dSJohn Marino section offsets accordingly, even if SYMFILE_OBJFILE->SECTION_OFFSETS
2143cf7f2e2dSJohn Marino already contains pre-computed offsets.
2144cf7f2e2dSJohn Marino
2145cf7f2e2dSJohn Marino If we cannot compute the PIE displacement, either:
2146cf7f2e2dSJohn Marino
2147cf7f2e2dSJohn Marino - The executable is not PIE.
2148cf7f2e2dSJohn Marino
2149cf7f2e2dSJohn Marino - SYMFILE_OBJFILE does not match the executable started in the target.
2150cf7f2e2dSJohn Marino This can happen for main executable symbols loaded at the host while
2151cf7f2e2dSJohn Marino `ld.so --ld-args main-executable' is loaded in the target.
2152cf7f2e2dSJohn Marino
2153cf7f2e2dSJohn Marino Then we leave the section offsets untouched and use them as is for
2154cf7f2e2dSJohn Marino this run. Either:
2155cf7f2e2dSJohn Marino
2156cf7f2e2dSJohn Marino - These section offsets were properly reset earlier, and thus
2157cf7f2e2dSJohn Marino already contain the correct values. This can happen for instance
2158cf7f2e2dSJohn Marino when reconnecting via the remote protocol to a target that supports
2159cf7f2e2dSJohn Marino the `qOffsets' packet.
2160cf7f2e2dSJohn Marino
2161cf7f2e2dSJohn Marino - The section offsets were not reset earlier, and the best we can
2162c50c785cSJohn Marino hope is that the old offsets are still applicable to the new run. */
2163cf7f2e2dSJohn Marino
2164cf7f2e2dSJohn Marino if (! svr4_exec_displacement (&displacement))
2165cf7f2e2dSJohn Marino return;
2166cf7f2e2dSJohn Marino
2167cf7f2e2dSJohn Marino /* Even DISPLACEMENT 0 is a valid new difference of in-memory vs. in-file
2168cf7f2e2dSJohn Marino addresses. */
2169cf7f2e2dSJohn Marino
2170cf7f2e2dSJohn Marino if (symfile_objfile)
2171cf7f2e2dSJohn Marino {
2172cf7f2e2dSJohn Marino struct section_offsets *new_offsets;
2173cf7f2e2dSJohn Marino int i;
2174cf7f2e2dSJohn Marino
2175cf7f2e2dSJohn Marino new_offsets = alloca (symfile_objfile->num_sections
2176cf7f2e2dSJohn Marino * sizeof (*new_offsets));
2177cf7f2e2dSJohn Marino
2178cf7f2e2dSJohn Marino for (i = 0; i < symfile_objfile->num_sections; i++)
2179cf7f2e2dSJohn Marino new_offsets->offsets[i] = displacement;
2180cf7f2e2dSJohn Marino
2181cf7f2e2dSJohn Marino objfile_relocate (symfile_objfile, new_offsets);
2182cf7f2e2dSJohn Marino }
2183cf7f2e2dSJohn Marino else if (exec_bfd)
2184cf7f2e2dSJohn Marino {
2185cf7f2e2dSJohn Marino asection *asect;
2186cf7f2e2dSJohn Marino
2187cf7f2e2dSJohn Marino for (asect = exec_bfd->sections; asect != NULL; asect = asect->next)
2188cf7f2e2dSJohn Marino exec_set_section_address (bfd_get_filename (exec_bfd), asect->index,
2189cf7f2e2dSJohn Marino (bfd_section_vma (exec_bfd, asect)
2190cf7f2e2dSJohn Marino + displacement));
21915796c8dcSSimon Schubert }
21925796c8dcSSimon Schubert }
21935796c8dcSSimon Schubert
2194a45ae5f8SJohn Marino /* Implement the "create_inferior_hook" target_solib_ops method.
21955796c8dcSSimon Schubert
21965796c8dcSSimon Schubert For SVR4 executables, this first instruction is either the first
21975796c8dcSSimon Schubert instruction in the dynamic linker (for dynamically linked
21985796c8dcSSimon Schubert executables) or the instruction at "start" for statically linked
21995796c8dcSSimon Schubert executables. For dynamically linked executables, the system
22005796c8dcSSimon Schubert first exec's /lib/libc.so.N, which contains the dynamic linker,
22015796c8dcSSimon Schubert and starts it running. The dynamic linker maps in any needed
22025796c8dcSSimon Schubert shared libraries, maps in the actual user executable, and then
22035796c8dcSSimon Schubert jumps to "start" in the user executable.
22045796c8dcSSimon Schubert
2205a45ae5f8SJohn Marino We can arrange to cooperate with the dynamic linker to discover the
2206a45ae5f8SJohn Marino names of shared libraries that are dynamically linked, and the base
2207a45ae5f8SJohn Marino addresses to which they are linked.
22085796c8dcSSimon Schubert
22095796c8dcSSimon Schubert This function is responsible for discovering those names and
22105796c8dcSSimon Schubert addresses, and saving sufficient information about them to allow
2211*ef5ccd6cSJohn Marino their symbols to be read at a later time. */
22125796c8dcSSimon Schubert
22135796c8dcSSimon Schubert static void
svr4_solib_create_inferior_hook(int from_tty)2214cf7f2e2dSJohn Marino svr4_solib_create_inferior_hook (int from_tty)
22155796c8dcSSimon Schubert {
22165796c8dcSSimon Schubert struct svr4_info *info;
22175796c8dcSSimon Schubert
2218cf7f2e2dSJohn Marino info = get_svr4_info ();
22195796c8dcSSimon Schubert
22205796c8dcSSimon Schubert /* Relocate the main executable if necessary. */
22215796c8dcSSimon Schubert svr4_relocate_main_executable ();
22225796c8dcSSimon Schubert
2223c50c785cSJohn Marino /* No point setting a breakpoint in the dynamic linker if we can't
2224c50c785cSJohn Marino hit it (e.g., a core file, or a trace file). */
2225c50c785cSJohn Marino if (!target_has_execution)
2226c50c785cSJohn Marino return;
2227c50c785cSJohn Marino
22285796c8dcSSimon Schubert if (!svr4_have_link_map_offsets ())
22295796c8dcSSimon Schubert return;
22305796c8dcSSimon Schubert
2231cf7f2e2dSJohn Marino if (!enable_break (info, from_tty))
22325796c8dcSSimon Schubert return;
22335796c8dcSSimon Schubert }
22345796c8dcSSimon Schubert
22355796c8dcSSimon Schubert static void
svr4_clear_solib(void)22365796c8dcSSimon Schubert svr4_clear_solib (void)
22375796c8dcSSimon Schubert {
2238cf7f2e2dSJohn Marino struct svr4_info *info;
2239cf7f2e2dSJohn Marino
2240cf7f2e2dSJohn Marino info = get_svr4_info ();
2241cf7f2e2dSJohn Marino info->debug_base = 0;
2242cf7f2e2dSJohn Marino info->debug_loader_offset_p = 0;
2243cf7f2e2dSJohn Marino info->debug_loader_offset = 0;
2244cf7f2e2dSJohn Marino xfree (info->debug_loader_name);
2245cf7f2e2dSJohn Marino info->debug_loader_name = NULL;
22465796c8dcSSimon Schubert }
22475796c8dcSSimon Schubert
22485796c8dcSSimon Schubert /* Clear any bits of ADDR that wouldn't fit in a target-format
22495796c8dcSSimon Schubert data pointer. "Data pointer" here refers to whatever sort of
22505796c8dcSSimon Schubert address the dynamic linker uses to manage its sections. At the
22515796c8dcSSimon Schubert moment, we don't support shared libraries on any processors where
22525796c8dcSSimon Schubert code and data pointers are different sizes.
22535796c8dcSSimon Schubert
22545796c8dcSSimon Schubert This isn't really the right solution. What we really need here is
22555796c8dcSSimon Schubert a way to do arithmetic on CORE_ADDR values that respects the
22565796c8dcSSimon Schubert natural pointer/address correspondence. (For example, on the MIPS,
22575796c8dcSSimon Schubert converting a 32-bit pointer to a 64-bit CORE_ADDR requires you to
22585796c8dcSSimon Schubert sign-extend the value. There, simply truncating the bits above
22595796c8dcSSimon Schubert gdbarch_ptr_bit, as we do below, is no good.) This should probably
22605796c8dcSSimon Schubert be a new gdbarch method or something. */
22615796c8dcSSimon Schubert static CORE_ADDR
svr4_truncate_ptr(CORE_ADDR addr)22625796c8dcSSimon Schubert svr4_truncate_ptr (CORE_ADDR addr)
22635796c8dcSSimon Schubert {
2264*ef5ccd6cSJohn Marino if (gdbarch_ptr_bit (target_gdbarch ()) == sizeof (CORE_ADDR) * 8)
22655796c8dcSSimon Schubert /* We don't need to truncate anything, and the bit twiddling below
22665796c8dcSSimon Schubert will fail due to overflow problems. */
22675796c8dcSSimon Schubert return addr;
22685796c8dcSSimon Schubert else
2269*ef5ccd6cSJohn Marino return addr & (((CORE_ADDR) 1 << gdbarch_ptr_bit (target_gdbarch ())) - 1);
22705796c8dcSSimon Schubert }
22715796c8dcSSimon Schubert
22725796c8dcSSimon Schubert
22735796c8dcSSimon Schubert static void
svr4_relocate_section_addresses(struct so_list * so,struct target_section * sec)22745796c8dcSSimon Schubert svr4_relocate_section_addresses (struct so_list *so,
22755796c8dcSSimon Schubert struct target_section *sec)
22765796c8dcSSimon Schubert {
2277a45ae5f8SJohn Marino sec->addr = svr4_truncate_ptr (sec->addr + lm_addr_check (so,
22785796c8dcSSimon Schubert sec->bfd));
2279a45ae5f8SJohn Marino sec->endaddr = svr4_truncate_ptr (sec->endaddr + lm_addr_check (so,
22805796c8dcSSimon Schubert sec->bfd));
22815796c8dcSSimon Schubert }
22825796c8dcSSimon Schubert
22835796c8dcSSimon Schubert
22845796c8dcSSimon Schubert /* Architecture-specific operations. */
22855796c8dcSSimon Schubert
22865796c8dcSSimon Schubert /* Per-architecture data key. */
22875796c8dcSSimon Schubert static struct gdbarch_data *solib_svr4_data;
22885796c8dcSSimon Schubert
22895796c8dcSSimon Schubert struct solib_svr4_ops
22905796c8dcSSimon Schubert {
22915796c8dcSSimon Schubert /* Return a description of the layout of `struct link_map'. */
22925796c8dcSSimon Schubert struct link_map_offsets *(*fetch_link_map_offsets)(void);
22935796c8dcSSimon Schubert };
22945796c8dcSSimon Schubert
22955796c8dcSSimon Schubert /* Return a default for the architecture-specific operations. */
22965796c8dcSSimon Schubert
22975796c8dcSSimon Schubert static void *
solib_svr4_init(struct obstack * obstack)22985796c8dcSSimon Schubert solib_svr4_init (struct obstack *obstack)
22995796c8dcSSimon Schubert {
23005796c8dcSSimon Schubert struct solib_svr4_ops *ops;
23015796c8dcSSimon Schubert
23025796c8dcSSimon Schubert ops = OBSTACK_ZALLOC (obstack, struct solib_svr4_ops);
23035796c8dcSSimon Schubert ops->fetch_link_map_offsets = NULL;
23045796c8dcSSimon Schubert return ops;
23055796c8dcSSimon Schubert }
23065796c8dcSSimon Schubert
23075796c8dcSSimon Schubert /* Set the architecture-specific `struct link_map_offsets' fetcher for
23085796c8dcSSimon Schubert GDBARCH to FLMO. Also, install SVR4 solib_ops into GDBARCH. */
23095796c8dcSSimon Schubert
23105796c8dcSSimon Schubert void
set_solib_svr4_fetch_link_map_offsets(struct gdbarch * gdbarch,struct link_map_offsets * (* flmo)(void))23115796c8dcSSimon Schubert set_solib_svr4_fetch_link_map_offsets (struct gdbarch *gdbarch,
23125796c8dcSSimon Schubert struct link_map_offsets *(*flmo) (void))
23135796c8dcSSimon Schubert {
23145796c8dcSSimon Schubert struct solib_svr4_ops *ops = gdbarch_data (gdbarch, solib_svr4_data);
23155796c8dcSSimon Schubert
23165796c8dcSSimon Schubert ops->fetch_link_map_offsets = flmo;
23175796c8dcSSimon Schubert
23185796c8dcSSimon Schubert set_solib_ops (gdbarch, &svr4_so_ops);
23195796c8dcSSimon Schubert }
23205796c8dcSSimon Schubert
23215796c8dcSSimon Schubert /* Fetch a link_map_offsets structure using the architecture-specific
23225796c8dcSSimon Schubert `struct link_map_offsets' fetcher. */
23235796c8dcSSimon Schubert
23245796c8dcSSimon Schubert static struct link_map_offsets *
svr4_fetch_link_map_offsets(void)23255796c8dcSSimon Schubert svr4_fetch_link_map_offsets (void)
23265796c8dcSSimon Schubert {
2327*ef5ccd6cSJohn Marino struct solib_svr4_ops *ops = gdbarch_data (target_gdbarch (), solib_svr4_data);
23285796c8dcSSimon Schubert
23295796c8dcSSimon Schubert gdb_assert (ops->fetch_link_map_offsets);
23305796c8dcSSimon Schubert return ops->fetch_link_map_offsets ();
23315796c8dcSSimon Schubert }
23325796c8dcSSimon Schubert
23335796c8dcSSimon Schubert /* Return 1 if a link map offset fetcher has been defined, 0 otherwise. */
23345796c8dcSSimon Schubert
23355796c8dcSSimon Schubert static int
svr4_have_link_map_offsets(void)23365796c8dcSSimon Schubert svr4_have_link_map_offsets (void)
23375796c8dcSSimon Schubert {
2338*ef5ccd6cSJohn Marino struct solib_svr4_ops *ops = gdbarch_data (target_gdbarch (), solib_svr4_data);
2339cf7f2e2dSJohn Marino
23405796c8dcSSimon Schubert return (ops->fetch_link_map_offsets != NULL);
23415796c8dcSSimon Schubert }
23425796c8dcSSimon Schubert
23435796c8dcSSimon Schubert
23445796c8dcSSimon Schubert /* Most OS'es that have SVR4-style ELF dynamic libraries define a
23455796c8dcSSimon Schubert `struct r_debug' and a `struct link_map' that are binary compatible
23465796c8dcSSimon Schubert with the origional SVR4 implementation. */
23475796c8dcSSimon Schubert
23485796c8dcSSimon Schubert /* Fetch (and possibly build) an appropriate `struct link_map_offsets'
23495796c8dcSSimon Schubert for an ILP32 SVR4 system. */
23505796c8dcSSimon Schubert
23515796c8dcSSimon Schubert struct link_map_offsets *
svr4_ilp32_fetch_link_map_offsets(void)23525796c8dcSSimon Schubert svr4_ilp32_fetch_link_map_offsets (void)
23535796c8dcSSimon Schubert {
23545796c8dcSSimon Schubert static struct link_map_offsets lmo;
23555796c8dcSSimon Schubert static struct link_map_offsets *lmp = NULL;
23565796c8dcSSimon Schubert
23575796c8dcSSimon Schubert if (lmp == NULL)
23585796c8dcSSimon Schubert {
23595796c8dcSSimon Schubert lmp = &lmo;
23605796c8dcSSimon Schubert
23615796c8dcSSimon Schubert lmo.r_version_offset = 0;
23625796c8dcSSimon Schubert lmo.r_version_size = 4;
23635796c8dcSSimon Schubert lmo.r_map_offset = 4;
23645796c8dcSSimon Schubert lmo.r_brk_offset = 8;
23655796c8dcSSimon Schubert lmo.r_ldsomap_offset = 20;
23665796c8dcSSimon Schubert
23675796c8dcSSimon Schubert /* Everything we need is in the first 20 bytes. */
23685796c8dcSSimon Schubert lmo.link_map_size = 20;
23695796c8dcSSimon Schubert lmo.l_addr_offset = 0;
23705796c8dcSSimon Schubert lmo.l_name_offset = 4;
23715796c8dcSSimon Schubert lmo.l_ld_offset = 8;
23725796c8dcSSimon Schubert lmo.l_next_offset = 12;
23735796c8dcSSimon Schubert lmo.l_prev_offset = 16;
23745796c8dcSSimon Schubert }
23755796c8dcSSimon Schubert
23765796c8dcSSimon Schubert return lmp;
23775796c8dcSSimon Schubert }
23785796c8dcSSimon Schubert
23795796c8dcSSimon Schubert /* Fetch (and possibly build) an appropriate `struct link_map_offsets'
23805796c8dcSSimon Schubert for an LP64 SVR4 system. */
23815796c8dcSSimon Schubert
23825796c8dcSSimon Schubert struct link_map_offsets *
svr4_lp64_fetch_link_map_offsets(void)23835796c8dcSSimon Schubert svr4_lp64_fetch_link_map_offsets (void)
23845796c8dcSSimon Schubert {
23855796c8dcSSimon Schubert static struct link_map_offsets lmo;
23865796c8dcSSimon Schubert static struct link_map_offsets *lmp = NULL;
23875796c8dcSSimon Schubert
23885796c8dcSSimon Schubert if (lmp == NULL)
23895796c8dcSSimon Schubert {
23905796c8dcSSimon Schubert lmp = &lmo;
23915796c8dcSSimon Schubert
23925796c8dcSSimon Schubert lmo.r_version_offset = 0;
23935796c8dcSSimon Schubert lmo.r_version_size = 4;
23945796c8dcSSimon Schubert lmo.r_map_offset = 8;
23955796c8dcSSimon Schubert lmo.r_brk_offset = 16;
23965796c8dcSSimon Schubert lmo.r_ldsomap_offset = 40;
23975796c8dcSSimon Schubert
23985796c8dcSSimon Schubert /* Everything we need is in the first 40 bytes. */
23995796c8dcSSimon Schubert lmo.link_map_size = 40;
24005796c8dcSSimon Schubert lmo.l_addr_offset = 0;
24015796c8dcSSimon Schubert lmo.l_name_offset = 8;
24025796c8dcSSimon Schubert lmo.l_ld_offset = 16;
24035796c8dcSSimon Schubert lmo.l_next_offset = 24;
24045796c8dcSSimon Schubert lmo.l_prev_offset = 32;
24055796c8dcSSimon Schubert }
24065796c8dcSSimon Schubert
24075796c8dcSSimon Schubert return lmp;
24085796c8dcSSimon Schubert }
24095796c8dcSSimon Schubert
24105796c8dcSSimon Schubert
24115796c8dcSSimon Schubert struct target_so_ops svr4_so_ops;
24125796c8dcSSimon Schubert
24135796c8dcSSimon Schubert /* Lookup global symbol for ELF DSOs linked with -Bsymbolic. Those DSOs have a
24145796c8dcSSimon Schubert different rule for symbol lookup. The lookup begins here in the DSO, not in
24155796c8dcSSimon Schubert the main executable. */
24165796c8dcSSimon Schubert
24175796c8dcSSimon Schubert static struct symbol *
elf_lookup_lib_symbol(const struct objfile * objfile,const char * name,const domain_enum domain)24185796c8dcSSimon Schubert elf_lookup_lib_symbol (const struct objfile *objfile,
24195796c8dcSSimon Schubert const char *name,
24205796c8dcSSimon Schubert const domain_enum domain)
24215796c8dcSSimon Schubert {
2422cf7f2e2dSJohn Marino bfd *abfd;
2423cf7f2e2dSJohn Marino
2424cf7f2e2dSJohn Marino if (objfile == symfile_objfile)
2425cf7f2e2dSJohn Marino abfd = exec_bfd;
2426cf7f2e2dSJohn Marino else
2427cf7f2e2dSJohn Marino {
2428cf7f2e2dSJohn Marino /* OBJFILE should have been passed as the non-debug one. */
2429cf7f2e2dSJohn Marino gdb_assert (objfile->separate_debug_objfile_backlink == NULL);
2430cf7f2e2dSJohn Marino
2431cf7f2e2dSJohn Marino abfd = objfile->obfd;
2432cf7f2e2dSJohn Marino }
2433cf7f2e2dSJohn Marino
2434cf7f2e2dSJohn Marino if (abfd == NULL || scan_dyntag (DT_SYMBOLIC, abfd, NULL) != 1)
24355796c8dcSSimon Schubert return NULL;
24365796c8dcSSimon Schubert
2437cf7f2e2dSJohn Marino return lookup_global_symbol_from_objfile (objfile, name, domain);
24385796c8dcSSimon Schubert }
24395796c8dcSSimon Schubert
24405796c8dcSSimon Schubert extern initialize_file_ftype _initialize_svr4_solib; /* -Wmissing-prototypes */
24415796c8dcSSimon Schubert
24425796c8dcSSimon Schubert void
_initialize_svr4_solib(void)24435796c8dcSSimon Schubert _initialize_svr4_solib (void)
24445796c8dcSSimon Schubert {
24455796c8dcSSimon Schubert solib_svr4_data = gdbarch_data_register_pre_init (solib_svr4_init);
2446cf7f2e2dSJohn Marino solib_svr4_pspace_data
2447*ef5ccd6cSJohn Marino = register_program_space_data_with_cleanup (NULL, svr4_pspace_data_cleanup);
24485796c8dcSSimon Schubert
24495796c8dcSSimon Schubert svr4_so_ops.relocate_section_addresses = svr4_relocate_section_addresses;
24505796c8dcSSimon Schubert svr4_so_ops.free_so = svr4_free_so;
24515796c8dcSSimon Schubert svr4_so_ops.clear_solib = svr4_clear_solib;
24525796c8dcSSimon Schubert svr4_so_ops.solib_create_inferior_hook = svr4_solib_create_inferior_hook;
24535796c8dcSSimon Schubert svr4_so_ops.special_symbol_handling = svr4_special_symbol_handling;
24545796c8dcSSimon Schubert svr4_so_ops.current_sos = svr4_current_sos;
24555796c8dcSSimon Schubert svr4_so_ops.open_symbol_file_object = open_symbol_file_object;
24565796c8dcSSimon Schubert svr4_so_ops.in_dynsym_resolve_code = svr4_in_dynsym_resolve_code;
24575796c8dcSSimon Schubert svr4_so_ops.bfd_open = solib_bfd_open;
24585796c8dcSSimon Schubert svr4_so_ops.lookup_lib_global_symbol = elf_lookup_lib_symbol;
24595796c8dcSSimon Schubert svr4_so_ops.same = svr4_same;
2460cf7f2e2dSJohn Marino svr4_so_ops.keep_data_in_core = svr4_keep_data_in_core;
24615796c8dcSSimon Schubert }
2462