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]

[RFA] Convert CONVERT_FROM_FUNC_PTR_ADDR to multi-arch


I intend to submit a patch for better printing of function pointers on
RS/6000 targets, which would need more uses of the CONVERT_FROM_FUNC_PTR_ADDR
macro in c-valprint.c.

Assuming that I will never get approval to clutter a generic file with more
ifdefs, the attached patch converts the CONVERT_FROM_FUNC_PTR_ADDR macro into
a multi-arch runtime call first.

PS: Please bare with me if I got something wrong, this is my first try ever
to convert a macro to multi-arch.

	* arch-utils.c, arch-utils.h (default_convert_from_func_ptr_addr):
	New function.
	* gdbarch.sh (CONVERT_FROM_FUNC_PTR_ADDR):  Add.
	* gdbarch.c, gdbarch.h:  Regenerate.
	* valops.c (find_function_addr):  Use CONVERT_FROM_FUNC_PTR_ADDR
	unconditionally.

	* config/rs6000/tm-rs6000.h (CONVERT_FROM_FUNC_PTR_ADDR):  Delete
	definition.
	* config/powerpc/tm-linux.h (CONVERT_FROM_FUNC_PTR_ADDR):  Remove
	undef.
	* rs6000-tdep.c (rs6000_convert_from_func_ptr_addr):  Fix comment.
	(rs6000_gdbarch_init):  Register rs6000_convert_from_func_ptr_addr
	if not ELFOSABI_LINUX.

*** ./arch-utils.c.orig	Fri Sep 15 21:26:54 2000
--- ./arch-utils.c	Sun Oct  1 12:20:21 2000
***************
*** 226,231 ****
--- 226,238 ----
    return num;
  }
  
+ 
+ CORE_ADDR
+ default_convert_from_func_ptr_addr (CORE_ADDR addr)
+ {
+   return addr;
+ }
+ 
  /* Functions to manipulate the endianness of the target.  */
  
  #ifdef TARGET_BYTE_ORDER_SELECTABLE
*** ./arch-utils.h.orig	Fri Sep 15 21:26:54 2000
--- ./arch-utils.h	Sun Oct  1 12:19:35 2000
***************
*** 93,96 ****
--- 93,100 ----
  
  extern int default_register_sim_regno (int reg_nr);
  
+ /* Default conversion of function pointer address - returns address.  */
+ 
+ extern CORE_ADDR default_convert_from_func_ptr_addr (CORE_ADDR addr);
+ 
  #endif
*** ./config/powerpc/tm-linux.h.orig	Sat Aug  5 11:38:26 2000
--- ./config/powerpc/tm-linux.h	Sun Oct  1 13:44:38 2000
***************
*** 55,63 ****
  #define CANNOT_STORE_REGISTER(regno) ((regno) >= MQ_REGNUM)
  #endif
  
- /* Linux doesn't use the PowerOpen ABI for function pointer representation */
- #undef CONVERT_FROM_FUNC_PTR_ADDR
- 
  #if 0 /* If skip_prologue() isn't too greedy, we don't need this */
  /* There is some problem with the debugging symbols generated by the
     compiler such that the debugging symbol for the first line of a
--- 55,60 ----
*** ./config/rs6000/tm-rs6000.h.orig	Sat Aug  5 11:38:28 2000
--- ./config/rs6000/tm-rs6000.h	Sun Oct  1 12:25:53 2000
***************
*** 97,119 ****
  /* Default offset from SP where the LR is stored */
  #define	DEFAULT_LR_SAVE 8
  
- /* Usually a function pointer's representation is simply the address
-    of the function. On the RS/6000 however, a function pointer is
-    represented by a pointer to a TOC entry. This TOC entry contains
-    three words, the first word is the address of the function, the
-    second word is the TOC pointer (r2), and the third word is the
-    static chain value.  Throughout GDB it is currently assumed that a
-    function pointer contains the address of the function, which is not
-    easy to fix.  In addition, the conversion of a function address to
-    a function pointer would require allocation of a TOC entry in the
-    inferior's memory space, with all its drawbacks.  To be able to
-    call C++ virtual methods in the inferior (which are called via
-    function pointers), find_function_addr uses this macro to get the
-    function address from a function pointer.  */
- 
- #define CONVERT_FROM_FUNC_PTR_ADDR rs6000_convert_from_func_ptr_addr
- extern CORE_ADDR rs6000_convert_from_func_ptr_addr (CORE_ADDR);
- 
  /* Flag for machine-specific stuff in shared files.  FIXME */
  #define IBM6000_TARGET
  
--- 97,102 ----
*** ./gdbarch.c.orig	Fri Sep 15 21:27:05 2000
--- ./gdbarch.c	Sun Oct  1 12:16:00 2000
***************
*** 232,237 ****
--- 232,238 ----
    const struct floatformat * float_format;
    const struct floatformat * double_format;
    const struct floatformat * long_double_format;
+   gdbarch_convert_from_func_ptr_addr_ftype *convert_from_func_ptr_addr;
  };
  
  
***************
*** 354,359 ****
--- 355,361 ----
    0,
    0,
    0,
+   0,
    /* startup_gdbarch() */
  };
  
***************
*** 429,434 ****
--- 431,437 ----
    gdbarch->frame_args_skip = -1;
    gdbarch->frameless_function_invocation = generic_frameless_function_invocation_not;
    gdbarch->extra_stack_alignment_needed = 1;
+   gdbarch->convert_from_func_ptr_addr = default_convert_from_func_ptr_addr;
    /* gdbarch_alloc() */
  
    return gdbarch;
***************
*** 665,670 ****
--- 668,674 ----
      gdbarch->double_format = default_double_format (gdbarch);
    if (gdbarch->long_double_format == 0)
      gdbarch->long_double_format = &floatformat_unknown;
+   /* Skip verify of convert_from_func_ptr_addr, invalid_p == 0 */
  }
  
  
***************
*** 1293,1298 ****
--- 1297,1308 ----
                        "gdbarch_dump: TARGET_LONG_DOUBLE_FORMAT # %s\n",
                        XSTRING (TARGET_LONG_DOUBLE_FORMAT));
  #endif
+ #ifdef CONVERT_FROM_FUNC_PTR_ADDR
+   fprintf_unfiltered (file,
+                       "gdbarch_dump: %s # %s\n",
+                       "CONVERT_FROM_FUNC_PTR_ADDR(addr)",
+                       XSTRING (CONVERT_FROM_FUNC_PTR_ADDR (addr)));
+ #endif
  #ifdef TARGET_ARCHITECTURE
    if (TARGET_ARCHITECTURE != NULL)
      fprintf_unfiltered (file,
***************
*** 1949,1954 ****
--- 1959,1971 ----
                        "gdbarch_dump: TARGET_LONG_DOUBLE_FORMAT = %ld\n",
                        (long) TARGET_LONG_DOUBLE_FORMAT);
  #endif
+ #ifdef CONVERT_FROM_FUNC_PTR_ADDR
+   if (GDB_MULTI_ARCH)
+     fprintf_unfiltered (file,
+                         "gdbarch_dump: CONVERT_FROM_FUNC_PTR_ADDR = 0x%08lx\n",
+                         (long) current_gdbarch->convert_from_func_ptr_addr
+                         /*CONVERT_FROM_FUNC_PTR_ADDR ()*/);
+ #endif
    if (current_gdbarch->dump_tdep != NULL)
      current_gdbarch->dump_tdep (current_gdbarch, file);
  }
***************
*** 3737,3742 ****
--- 3754,3776 ----
    gdbarch->long_double_format = long_double_format;
  }
  
+ CORE_ADDR
+ gdbarch_convert_from_func_ptr_addr (struct gdbarch *gdbarch, CORE_ADDR addr)
+ {
+   if (gdbarch->convert_from_func_ptr_addr == 0)
+     internal_error ("gdbarch: gdbarch_convert_from_func_ptr_addr invalid");
+   if (gdbarch_debug >= 2)
+     fprintf_unfiltered (gdb_stdlog, "gdbarch_convert_from_func_ptr_addr called\n");
+   return gdbarch->convert_from_func_ptr_addr (addr);
+ }
+ 
+ void
+ set_gdbarch_convert_from_func_ptr_addr (struct gdbarch *gdbarch,
+                                         gdbarch_convert_from_func_ptr_addr_ftype convert_from_func_ptr_addr)
+ {
+   gdbarch->convert_from_func_ptr_addr = convert_from_func_ptr_addr;
+ }
+ 
  
  /* Keep a registrary of per-architecture data-pointers required by GDB
     modules. */
*** ./gdbarch.h.orig	Fri Sep 15 21:27:05 2000
--- ./gdbarch.h	Sun Oct  1 12:16:00 2000
***************
*** 1338,1343 ****
--- 1338,1357 ----
  #endif
  #endif
  
+ /* Default (function) for non- multi-arch platforms. */
+ #if (!GDB_MULTI_ARCH) && !defined (CONVERT_FROM_FUNC_PTR_ADDR)
+ #define CONVERT_FROM_FUNC_PTR_ADDR(addr) (default_convert_from_func_ptr_addr (addr))
+ #endif
+ 
+ typedef CORE_ADDR (gdbarch_convert_from_func_ptr_addr_ftype) (CORE_ADDR addr);
+ extern CORE_ADDR gdbarch_convert_from_func_ptr_addr (struct gdbarch *gdbarch, CORE_ADDR addr);
+ extern void set_gdbarch_convert_from_func_ptr_addr (struct gdbarch *gdbarch, gdbarch_convert_from_func_ptr_addr_ftype *convert_from_func_ptr_addr);
+ #if GDB_MULTI_ARCH
+ #if (GDB_MULTI_ARCH > GDB_MULTI_ARCH_PARTIAL) || !defined (CONVERT_FROM_FUNC_PTR_ADDR)
+ #define CONVERT_FROM_FUNC_PTR_ADDR(addr) (gdbarch_convert_from_func_ptr_addr (current_gdbarch, addr))
+ #endif
+ #endif
+ 
  extern struct gdbarch_tdep *gdbarch_tdep (struct gdbarch *gdbarch);
  
  
*** ./gdbarch.sh.orig	Fri Sep 15 21:27:06 2000
--- ./gdbarch.sh	Sun Oct  1 12:16:00 2000
***************
*** 472,477 ****
--- 472,478 ----
  v:2:TARGET_FLOAT_FORMAT:const struct floatformat *:float_format::::::default_float_format (gdbarch)
  v:2:TARGET_DOUBLE_FORMAT:const struct floatformat *:double_format::::::default_double_format (gdbarch)
  v:2:TARGET_LONG_DOUBLE_FORMAT:const struct floatformat *:long_double_format::::::&floatformat_unknown
+ f:2:CONVERT_FROM_FUNC_PTR_ADDR:CORE_ADDR:convert_from_func_ptr_addr:CORE_ADDR addr:addr:::default_convert_from_func_ptr_addr::0
  EOF
  }
  
*** ./rs6000-tdep.c.orig	Fri Sep 22 20:26:45 2000
--- ./rs6000-tdep.c	Sun Oct  1 12:28:30 2000
***************
*** 1540,1550 ****
     a function pointer would require allocation of a TOC entry in the
     inferior's memory space, with all its drawbacks.  To be able to
     call C++ virtual methods in the inferior (which are called via
!    function pointers), find_function_addr uses this macro to get the
     function address from a function pointer.  */
  
! /* Return nonzero if ADDR (a function pointer) is in the data space and
!    is therefore a special function pointer.  */
  
  CORE_ADDR
  rs6000_convert_from_func_ptr_addr (CORE_ADDR addr)
--- 1540,1550 ----
     a function pointer would require allocation of a TOC entry in the
     inferior's memory space, with all its drawbacks.  To be able to
     call C++ virtual methods in the inferior (which are called via
!    function pointers), find_function_addr uses this function to get the
     function address from a function pointer.  */
  
! /* Return real function address if ADDR (a function pointer) is in the data
!    space and is therefore a special function pointer.  */
  
  CORE_ADDR
  rs6000_convert_from_func_ptr_addr (CORE_ADDR addr)
***************
*** 2195,2200 ****
--- 2195,2204 ----
  
        set_gdbarch_frame_init_saved_regs (gdbarch, rs6000_frame_init_saved_regs);
        set_gdbarch_init_extra_frame_info (gdbarch, rs6000_init_extra_frame_info);
+ 
+       /* Handle RS/6000 function pointers.  */
+       set_gdbarch_convert_from_func_ptr_addr (gdbarch,
+ 	rs6000_convert_from_func_ptr_addr);
      }
    set_gdbarch_frame_args_address (gdbarch, rs6000_frame_args_address);
    set_gdbarch_frame_locals_address (gdbarch, rs6000_frame_args_address);
*** ./valops.c.orig	Fri Sep 15 21:27:34 2000
--- ./valops.c	Sun Oct  1 12:21:46 2000
***************
*** 1249,1260 ****
        if (TYPE_CODE (ftype) == TYPE_CODE_FUNC
  	  || TYPE_CODE (ftype) == TYPE_CODE_METHOD)
  	{
- #ifdef CONVERT_FROM_FUNC_PTR_ADDR
- 	  /* FIXME: This is a workaround for the unusual function
- 	     pointer representation on the RS/6000, see comment
- 	     in config/rs6000/tm-rs6000.h  */
  	  funaddr = CONVERT_FROM_FUNC_PTR_ADDR (funaddr);
- #endif
  	  value_type = TYPE_TARGET_TYPE (ftype);
  	}
        else
--- 1249,1255 ----

-- 
Peter Schauer			pes@regent.e-technik.tu-muenchen.de

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