From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 28641 invoked by alias); 13 Jun 2003 22:31:54 -0000 Mailing-List: contact gdb-patches-help@sources.redhat.com; run by ezmlm Precedence: bulk List-Subscribe: List-Archive: List-Post: List-Help: , Sender: gdb-patches-owner@sources.redhat.com Received: (qmail 28408 invoked from network); 13 Jun 2003 22:31:50 -0000 Received: from unknown (HELO zenia.home) (12.223.225.216) by sources.redhat.com with SMTP; 13 Jun 2003 22:31:50 -0000 Received: by zenia.home (Postfix, from userid 5433) id 3D53E20D85; Fri, 13 Jun 2003 17:32:10 -0500 (EST) To: Kevin Buettner Cc: gdb-patches@sources.redhat.com Subject: Re: [ppc64-linux] gdbarch hook to find true execution entry point References: <1030611231105.ZM27287@localhost.localdomain> From: Jim Blandy Date: Fri, 13 Jun 2003 22:31:00 -0000 In-Reply-To: <1030611231105.ZM27287@localhost.localdomain> Message-ID: User-Agent: Gnus/5.09 (Gnus v5.9.0) Emacs/21.3 MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii X-SW-Source: 2003-06/txt/msg00482.txt.bz2 Kevin Buettner writes: > On Jun 11, 8:22am, Jim Blandy wrote: > > Subject: [ppc64-linux] gdbarch hook to find true execution entry point > > > > 2003-06-11 Jim Blandy > > > > * gdbarch.sh (gdbarch_bfd_entry_point): New gdbarch method. > > * arch-utils.c (generic_bfd_entry_point): New function. > > * arch-utils.h (generic_bfd_entry_point): New declaration. > > * gdbarch.c, gdbarch.h: Regenerated. > > * solib-svr4.c (enable_break): Call it, instead of accessing > > tmp_bfd->start_address directly. > > > [...] > > Index: gdb/solib-svr4.c > > =================================================================== > > RCS file: /cvs/src/src/gdb/solib-svr4.c,v > > retrieving revision 1.32.8.2 > > diff -c -r1.32.8.2 solib-svr4.c > > *** gdb/solib-svr4.c 11 Jun 2003 13:00:34 -0000 1.32.8.2 > > --- gdb/solib-svr4.c 11 Jun 2003 13:16:32 -0000 > > *************** > > *** 1022,1028 **** > > 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; > > > > /* Record the relocated start and end address of the dynamic linker > > text and plt section for svr4_in_dynsym_resolve_code. */ > > --- 1022,1029 ---- > > 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 () > > ! - generic_bfd_entry_point (current_gdbarch, tmp_bfd)); > > > > /* Record the relocated start and end address of the dynamic linker > > text and plt section for svr4_in_dynsym_resolve_code. */ > > Shouldn't enable_break() in solib-svr4.c be calling > gdbarch_bfd_entry_point()? Actually, the overhead of the indirect function call would be a serious performance problem here. And since using any target other than PPC64 indicates major pilot error to begin with, I think it's better that we catch that problem early by having GDB fail at this point than just paper over the problem by allowing other targets to function properly. Allowing GDB to run "correctly" on those systems only creates the illusion that they are adequate for real work. (Um, yes, thanks for catching that.) > What cases do you know of where calling bfd_get_start_address() is > insufficient for finding the start address? I'm wondering if we > need a gdbarch hook at all... The comment on the gdbarch.sh entry is supposed to explain why it's necessary. I've expanded it a bit; is it clearer? Is there someplace else I should put it? + # The actual instruction address at which ABFD would begin execution. + # If ABFD is position-independent code, this address is not relocated; + # it's the address at which execution would begin if the file were + # loaded at its sections' vmas. + # + # On most architectures, this is simply bfd_get_start_address. But on + # some (like 64-bit PPC), that points to a function descriptor, not an + # instruction. The descriptor contains the actual entry point, and + # other pointers needed to call the function. + m:1::CORE_ADDR:bfd_entry_point:bfd *abfd:abfd:::generic_bfd_entry_point::0 Revised patch: 2003-06-11 Jim Blandy * gdbarch.sh (gdbarch_bfd_entry_point): New gdbarch method. * arch-utils.c (generic_bfd_entry_point): New function. * arch-utils.h (generic_bfd_entry_point): New declaration. * gdbarch.c, gdbarch.h: Regenerated. * solib-svr4.c (enable_break): Call it, instead of accessing tmp_bfd->start_address directly. Index: gdb/gdbarch.sh =================================================================== RCS file: /cvs/src/src/gdb/gdbarch.sh,v retrieving revision 1.247 diff -c -r1.247 gdbarch.sh *** gdb/gdbarch.sh 13 Jun 2003 04:40:32 -0000 1.247 --- gdb/gdbarch.sh 13 Jun 2003 22:29:35 -0000 *************** *** 666,671 **** --- 666,681 ---- f:2:TARGET_PRINT_INSN:int:print_insn:bfd_vma vma, disassemble_info *info:vma, info:::legacy_print_insn::0 f:2:SKIP_TRAMPOLINE_CODE:CORE_ADDR:skip_trampoline_code:CORE_ADDR pc:pc:::generic_skip_trampoline_code::0 + # The actual instruction address at which ABFD would begin execution. + # If ABFD is position-independent code, this address is not relocated; + # it's the address at which execution would begin if the file were + # loaded at its sections' vmas. + # + # On most architectures, this is simply bfd_get_start_address. But on + # some (like 64-bit PPC), that points to a function descriptor, not an + # instruction. The descriptor contains the actual entry point, and + # other pointers needed to call the function. + m:1::CORE_ADDR:bfd_entry_point:bfd *abfd:abfd:::generic_bfd_entry_point::0 # For SVR4 shared libraries, each call goes through a small piece of # trampoline code in the ".plt" section. IN_SOLIB_CALL_TRAMPOLINE evaluates Index: gdb/arch-utils.c =================================================================== RCS file: /cvs/src/src/gdb/arch-utils.c,v retrieving revision 1.87 diff -c -r1.87 arch-utils.c *** gdb/arch-utils.c 12 Jun 2003 23:25:37 -0000 1.87 --- gdb/arch-utils.c 13 Jun 2003 22:29:29 -0000 *************** *** 368,373 **** --- 368,379 ---- return 0; } + CORE_ADDR + generic_bfd_entry_point (struct gdbarch *gdbarch, bfd *abfd) + { + return bfd_get_start_address (abfd); + } + /* Legacy version of target_virtual_frame_pointer(). Assumes that there is an DEPRECATED_FP_REGNUM and that it is the same, cooked or raw. */ Index: gdb/arch-utils.h =================================================================== RCS file: /cvs/src/src/gdb/arch-utils.h,v retrieving revision 1.49 diff -c -r1.49 arch-utils.h *** gdb/arch-utils.h 12 Jun 2003 23:25:37 -0000 1.49 --- gdb/arch-utils.h 13 Jun 2003 22:29:30 -0000 *************** *** 81,86 **** --- 81,90 ---- extern const struct floatformat *default_float_format (struct gdbarch *gdbarch); extern const struct floatformat *default_double_format (struct gdbarch *gdbarch); + /* Return the start address of ABFD. This is exactly like + bfd_get_start_address, except that it's a gdbarch function. */ + extern CORE_ADDR generic_bfd_entry_point (struct gdbarch *gdbarch, bfd *abfd); + /* The following DEPRECATED interfaces are for pre- multi-arch legacy targets. */ Index: gdb/solib-svr4.c =================================================================== RCS file: /cvs/src/src/gdb/solib-svr4.c,v retrieving revision 1.35 diff -c -r1.35 solib-svr4.c *** gdb/solib-svr4.c 13 Jun 2003 21:56:27 -0000 1.35 --- gdb/solib-svr4.c 13 Jun 2003 22:29:36 -0000 *************** *** 1036,1042 **** 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; /* Record the relocated start and end address of the dynamic linker text and plt section for svr4_in_dynsym_resolve_code. */ --- 1036,1043 ---- 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 () ! - gdbarch_bfd_entry_point (current_gdbarch, tmp_bfd)); /* Record the relocated start and end address of the dynamic linker text and plt section for svr4_in_dynsym_resolve_code. */ Index: gdb/gdbarch.c =================================================================== RCS file: /cvs/src/src/gdb/gdbarch.c,v retrieving revision 1.225 diff -c -r1.225 gdbarch.c *** gdb/gdbarch.c 13 Jun 2003 04:40:31 -0000 1.225 --- gdb/gdbarch.c 13 Jun 2003 22:29:32 -0000 *************** *** 264,269 **** --- 264,270 ---- gdbarch_software_single_step_ftype *software_single_step; gdbarch_print_insn_ftype *print_insn; gdbarch_skip_trampoline_code_ftype *skip_trampoline_code; + gdbarch_bfd_entry_point_ftype *bfd_entry_point; gdbarch_in_solib_call_trampoline_ftype *in_solib_call_trampoline; gdbarch_in_solib_return_trampoline_ftype *in_solib_return_trampoline; gdbarch_pc_in_sigtramp_ftype *pc_in_sigtramp; *************** *** 432,437 **** --- 433,439 ---- 0, /* software_single_step */ 0, /* print_insn */ 0, /* skip_trampoline_code */ + generic_bfd_entry_point, /* bfd_entry_point */ 0, /* in_solib_call_trampoline */ 0, /* in_solib_return_trampoline */ 0, /* pc_in_sigtramp */ *************** *** 557,562 **** --- 559,565 ---- current_gdbarch->smash_text_address = core_addr_identity; current_gdbarch->print_insn = legacy_print_insn; current_gdbarch->skip_trampoline_code = generic_skip_trampoline_code; + current_gdbarch->bfd_entry_point = generic_bfd_entry_point; current_gdbarch->in_solib_call_trampoline = generic_in_solib_call_trampoline; current_gdbarch->in_solib_return_trampoline = generic_in_solib_return_trampoline; current_gdbarch->pc_in_sigtramp = legacy_pc_in_sigtramp; *************** *** 746,751 **** --- 749,755 ---- /* Skip verify of software_single_step, has predicate */ /* Skip verify of print_insn, invalid_p == 0 */ /* Skip verify of skip_trampoline_code, invalid_p == 0 */ + /* Skip verify of bfd_entry_point, invalid_p == 0 */ /* Skip verify of in_solib_call_trampoline, invalid_p == 0 */ /* Skip verify of in_solib_return_trampoline, invalid_p == 0 */ /* Skip verify of pc_in_sigtramp, invalid_p == 0 */ *************** *** 790,795 **** --- 794,803 ---- GDB_MULTI_ARCH); if (GDB_MULTI_ARCH) fprintf_unfiltered (file, + "gdbarch_dump: bfd_entry_point = 0x%08lx\n", + (long) current_gdbarch->bfd_entry_point); + if (GDB_MULTI_ARCH) + fprintf_unfiltered (file, "gdbarch_dump: gdbarch_frame_align_p() = %d\n", gdbarch_frame_align_p (current_gdbarch)); if (GDB_MULTI_ARCH) *************** *** 5434,5439 **** --- 5442,5466 ---- gdbarch_skip_trampoline_code_ftype skip_trampoline_code) { gdbarch->skip_trampoline_code = skip_trampoline_code; + } + + CORE_ADDR + gdbarch_bfd_entry_point (struct gdbarch *gdbarch, bfd *abfd) + { + gdb_assert (gdbarch != NULL); + if (gdbarch->bfd_entry_point == 0) + internal_error (__FILE__, __LINE__, + "gdbarch: gdbarch_bfd_entry_point invalid"); + if (gdbarch_debug >= 2) + fprintf_unfiltered (gdb_stdlog, "gdbarch_bfd_entry_point called\n"); + return gdbarch->bfd_entry_point (gdbarch, abfd); + } + + void + set_gdbarch_bfd_entry_point (struct gdbarch *gdbarch, + gdbarch_bfd_entry_point_ftype bfd_entry_point) + { + gdbarch->bfd_entry_point = bfd_entry_point; } int Index: gdb/gdbarch.h =================================================================== RCS file: /cvs/src/src/gdb/gdbarch.h,v retrieving revision 1.194 diff -c -r1.194 gdbarch.h *** gdb/gdbarch.h 13 Jun 2003 04:40:32 -0000 1.194 --- gdb/gdbarch.h 13 Jun 2003 22:29:33 -0000 *************** *** 2699,2704 **** --- 2699,2718 ---- #define SKIP_TRAMPOLINE_CODE(pc) (gdbarch_skip_trampoline_code (current_gdbarch, pc)) #endif + /* The actual instruction address at which ABFD would begin execution. + If ABFD is position-independent code, this address is not relocated; + it's the address at which execution would begin if the file were + loaded at its sections' vmas. + + On most architectures, this is simply bfd_get_start_address. But on + some (like 64-bit PPC), that points to a function descriptor, not an + instruction. The descriptor contains the actual entry point, and + other pointers needed to call the function. */ + + typedef CORE_ADDR (gdbarch_bfd_entry_point_ftype) (struct gdbarch *gdbarch, bfd *abfd); + extern CORE_ADDR gdbarch_bfd_entry_point (struct gdbarch *gdbarch, bfd *abfd); + extern void set_gdbarch_bfd_entry_point (struct gdbarch *gdbarch, gdbarch_bfd_entry_point_ftype *bfd_entry_point); + /* For SVR4 shared libraries, each call goes through a small piece of trampoline code in the ".plt" section. IN_SOLIB_CALL_TRAMPOLINE evaluates to nonzero if we are currently stopped in one of these. */