This is the mail archive of the gdb-patches@sources.redhat.com mailing list for the GDB project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: [ppc64-linux] gdbarch hook to find true execution entry point


Kevin Buettner <kevinb@redhat.com> 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  <jimb@redhat.com>
> > 
> > 	* 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  <jimb@redhat.com>

	* 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. */


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]