This is the mail archive of the
gdb-patches@sources.redhat.com
mailing list for the GDB project.
Re: [rfa:solib] Handle start-address descriptors
- From: Andrew Cagney <ac131313 at redhat dot com>
- To: Andrew Cagney <ac131313 at redhat dot com>
- Cc: gdb-patches at sources dot redhat dot com
- Date: Fri, 31 Oct 2003 16:15:35 -0500
- Subject: Re: [rfa:solib] Handle start-address descriptors
- References: <3F9D67D7.2090003@redhat.com>
Hello,
The attached patch modifies the solib's computation of the exec's entry-point address so that it applies convert_from_func_ptr_addr() to the bfd start-address. That way, when the bfd's start-address points at a descriptor, the true exec entry point is still obtained.
Fixes ppc64's ability to debug shared libraries.
Attached is the patch as committed. PPC64 GNU/Linux is now "useable".
Andrew
PS: Ref
http://sources.redhat.com/ml/gdb-patches/2003-10/msg00670.html
2003-10-31 Andrew Cagney <cagney@redhat.com>
* solib-svr4.c: Update copyright. Include "bfd-target.h" and
"exec.h".
(exec_entry_point): New function.
(enable_break): Create a "tmp_bfd_target", use that and
entry_point_address when computing the relocation offset.
(svr4_relocate_main_executable): Ditto with exec_bfd and exec_ops.
* Makefile.in (solib-svr4.o): Update dependencies.
Index: Makefile.in
===================================================================
RCS file: /cvs/src/src/gdb/Makefile.in,v
retrieving revision 1.465
diff -u -r1.465 Makefile.in
--- Makefile.in 31 Oct 2003 19:19:51 -0000 1.465
+++ Makefile.in 31 Oct 2003 21:09:54 -0000
@@ -2298,7 +2298,8 @@
$(bcache_h) $(regcache_h)
solib-svr4.o: solib-svr4.c $(defs_h) $(elf_external_h) $(elf_common_h) \
$(elf_mips_h) $(symtab_h) $(bfd_h) $(symfile_h) $(objfiles_h) \
- $(gdbcore_h) $(target_h) $(inferior_h) $(solist_h) $(solib_svr4_h)
+ $(gdbcore_h) $(target_h) $(inferior_h) $(solist_h) $(solib_svr4_h) \
+ $(bfd_target_h) $(exec_h)
sol-thread.o: sol-thread.c $(defs_h) $(gdbthread_h) $(target_h) \
$(inferior_h) $(gdb_stat_h) $(gdbcmd_h) $(gdbcore_h) $(regcache_h) \
$(symfile_h) $(gdb_string_h) $(gregset_h)
Index: solib-svr4.c
===================================================================
RCS file: /cvs/src/src/gdb/solib-svr4.c,v
retrieving revision 1.37
diff -u -r1.37 solib-svr4.c
--- solib-svr4.c 26 Aug 2003 23:35:19 -0000 1.37
+++ solib-svr4.c 31 Oct 2003 21:09:54 -0000
@@ -1,7 +1,7 @@
/* Handle SVR4 shared libraries for GDB, the GNU Debugger.
- Copyright 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000,
- 2001
- Free Software Foundation, Inc.
+
+ Copyright 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1998, 1999,
+ 2000, 2001, 2003 Free Software Foundation, Inc.
This file is part of GDB.
@@ -37,6 +37,9 @@
#include "solist.h"
#include "solib-svr4.h"
+#include "bfd-target.h"
+#include "exec.h"
+
#ifndef SVR4_FETCH_LINK_MAP_OFFSETS
#define SVR4_FETCH_LINK_MAP_OFFSETS() svr4_fetch_link_map_offsets ()
#endif
@@ -911,6 +914,24 @@
|| in_plt_section (pc, NULL));
}
+/* Given an executable's ABFD and target, compute the entry-point
+ address. */
+
+static CORE_ADDR
+exec_entry_point (struct bfd *abfd, struct target_ops *targ)
+{
+ /* KevinB wrote ... for most targets, the address returned by
+ bfd_get_start_address() is the entry point for the start
+ function. But, for some targets, bfd_get_start_address() returns
+ the address of a function descriptor from which the entry point
+ address may be extracted. This address is extracted by
+ gdbarch_convert_from_func_ptr_addr(). The method
+ gdbarch_convert_from_func_ptr_addr() is the merely the identify
+ function for targets which don't use function descriptors. */
+ return gdbarch_convert_from_func_ptr_addr (current_gdbarch,
+ bfd_get_start_address (abfd),
+ targ);
+}
/*
@@ -984,6 +1005,7 @@
int load_addr_found = 0;
struct so_list *inferior_sos;
bfd *tmp_bfd = NULL;
+ struct target_ops *tmp_bfd_target;
int tmp_fd = -1;
char *tmp_pathname = NULL;
CORE_ADDR sym_addr = 0;
@@ -1019,6 +1041,11 @@
goto bkpt_at_symbol;
}
+ /* Now convert the TMP_BFD into a target. That way target, as
+ well as BFD operations can be used. Note that closing the
+ target will also close the underlying bfd. */
+ tmp_bfd_target = target_bfd_reopen (tmp_bfd);
+
/* If the entry in _DYNAMIC for the dynamic linker has already
been filled in, we can read its base address from there. */
inferior_sos = svr4_current_sos ();
@@ -1042,7 +1069,8 @@
the current pc (which should point at the entry point for the
dynamic linker) and subtracting the offset of the entry point. */
if (!load_addr_found)
- load_addr = read_pc () - tmp_bfd->start_address;
+ load_addr = (read_pc ()
+ - exec_entry_point (tmp_bfd, tmp_bfd_target));
/* Record the relocated start and end address of the dynamic linker
text and plt section for svr4_in_dynsym_resolve_code. */
@@ -1080,8 +1108,9 @@
break;
}
- /* We're done with the temporary bfd. */
- bfd_close (tmp_bfd);
+ /* We're done with both the temporary bfd and target. Remember,
+ closing the target closes the underlying bfd. */
+ target_close (tmp_bfd_target, 0);
if (sym_addr != 0)
{
@@ -1200,7 +1229,7 @@
interp_sect = bfd_get_section_by_name (exec_bfd, ".interp");
if (interp_sect == NULL
&& (bfd_get_file_flags (exec_bfd) & DYNAMIC) != 0
- && bfd_get_start_address (exec_bfd) != pc)
+ && (exec_entry_point (exec_bfd, &exec_ops) != pc))
{
struct cleanup *old_chain;
struct section_offsets *new_offsets;
@@ -1232,7 +1261,7 @@
The same language also appears in Edition 4.0 of the System V
ABI and is left unspecified in some of the earlier editions. */
- displacement = pc - bfd_get_start_address (exec_bfd);
+ displacement = pc - exec_entry_point (exec_bfd, &exec_ops);
changed = 0;
new_offsets = xcalloc (symfile_objfile->num_sections,