Preparation work to convert the hppa targets to multiarch partial.

* hppa-tdep.c: Add new functions replacing macro bodies from
        config/pa/tm-hppa.h. These function will be used to initialize
        the gdbarch structure. Import some comments from tm-hppa.h,
        and place them where appropriate, to avoid loosing them when
        we cleanup this file.
        (hppa_reg_struct_has_addr): New function.
        (hppa_inner_than): New function.
        (hppa_stack_align): New function.
        (hppa_pc_requires_run_before_use): New function.
        (hppa_instruction_nullified): New function.
        (hppa_register_byte): New function.
        (hppa_register_virtual_type): New function.
        (hppa_store_struct_return): New function.
        (hppa_cannot_store_register): New function.
        (hppa_frame_args_address): New function.
        (hppa_frame_locals_address): New function.
        (hppa_smash_text_address): New function.
        (hppa_coerce_float_to_double): New function. Requires the inclusion
        of "language.h".

        * Makefile.in (hppa-tdep.o): Add dependency on language.h.

        * tm-hppa.h (REG_STRUCT_HAS_ADDR): Change the definition of this
        gdbarch-eligible macro to a call to the new associated function
        created in hppa-tdep.c.
        (INNER_THAN): Likewise.
        (STACK_ALIGN): Likewise.
        (PC_REQUIRES_RUN_BEFORE_USE): Likewise.
        (INSTRUCTION_NULLIFIED): Likewise.
        (REGISTER_BYTE): Likewise.
        (REGISTER_VIRTUAL_TYPE): Likewise.
        (STORE_STRUCT_RETURN): Likewise.
        (CANNOT_STORE_REGISTER): Likewise.
        (FRAME_ARGS_ADDRESS): Likewise.
        (FRAME_LOCALS_ADDRESS): Likewise.
        (SMASH_TEXT_ADDRESS): Likewise.
        (COERCE_FLOAT_TO_DOUBLE): Likewise.
        (ABOUT_TO_RETURN): Delete, as no longer used.
This commit is contained in:
Joel Brobecker 2002-11-08 03:35:47 +00:00
parent 83c31e7d1e
commit d709c02007
4 changed files with 241 additions and 96 deletions

View File

@ -1,3 +1,46 @@
2002-11-07 Joel Brobecker <brobecker@gnat.com>
Preparation work to convert the hppa targets to multiarch partial.
* hppa-tdep.c: Add new functions replacing macro bodies from
config/pa/tm-hppa.h. These function will be used to initialize
the gdbarch structure. Import some comments from tm-hppa.h,
and place them where appropriate, to avoid loosing them when
we cleanup this file.
(hppa_reg_struct_has_addr): New function.
(hppa_inner_than): New function.
(hppa_stack_align): New function.
(hppa_pc_requires_run_before_use): New function.
(hppa_instruction_nullified): New function.
(hppa_register_byte): New function.
(hppa_register_virtual_type): New function.
(hppa_store_struct_return): New function.
(hppa_cannot_store_register): New function.
(hppa_frame_args_address): New function.
(hppa_frame_locals_address): New function.
(hppa_smash_text_address): New function.
(hppa_coerce_float_to_double): New function. Requires the inclusion
of "language.h".
* Makefile.in (hppa-tdep.o): Add dependency on language.h.
* tm-hppa.h (REG_STRUCT_HAS_ADDR): Change the definition of this
gdbarch-eligible macro to a call to the new associated function
created in hppa-tdep.c.
(INNER_THAN): Likewise.
(STACK_ALIGN): Likewise.
(PC_REQUIRES_RUN_BEFORE_USE): Likewise.
(INSTRUCTION_NULLIFIED): Likewise.
(REGISTER_BYTE): Likewise.
(REGISTER_VIRTUAL_TYPE): Likewise.
(STORE_STRUCT_RETURN): Likewise.
(CANNOT_STORE_REGISTER): Likewise.
(FRAME_ARGS_ADDRESS): Likewise.
(FRAME_LOCALS_ADDRESS): Likewise.
(SMASH_TEXT_ADDRESS): Likewise.
(COERCE_FLOAT_TO_DOUBLE): Likewise.
(ABOUT_TO_RETURN): Delete, as no longer used.
2002-11-07 Fernando Nasser <fnasser@redhat.com>
* printcmd.c (disassemble_command): Remove obsolete function.

View File

@ -1717,7 +1717,7 @@ hpacc-abi.o: hpacc-abi.c $(defs_h) $(value_h) $(gdb_regex_h) $(gdb_string_h) \
hppa-tdep.o: hppa-tdep.c $(defs_h) $(frame_h) $(bfd_h) $(inferior_h) \
$(value_h) $(regcache_h) $(completer_h) $(symtab_h) $(a_out_encap_h) \
$(gdb_stat_h) $(gdb_wait_h) $(gdbcore_h) $(gdbcmd_h) $(target_h) \
$(symfile_h) $(objfiles_h)
$(symfile_h) $(objfiles_h) $(language_h)
hppab-nat.o: hppab-nat.c $(defs_h) $(inferior_h) $(target_h) $(regcache_h)
hppah-nat.o: hppah-nat.c $(defs_h) $(inferior_h) $(target_h) $(gdbcore_h) \
$(gdb_wait_h) $(regcache_h)

View File

@ -52,12 +52,8 @@ struct inferior_status;
((X) >> (31 - (TO)) & ((1 << ((TO) - (FROM) + 1)) - 1))
#endif
/* On the PA, any pass-by-value structure > 8 bytes is actually
passed via a pointer regardless of its type or the compiler
used. */
#define REG_STRUCT_HAS_ADDR(gcc_p,type) \
(TYPE_LENGTH (type) > 8)
extern int hppa_reg_struct_has_addr (int gcc_p, struct type *type);
#define REG_STRUCT_HAS_ADDR(gcc_p,type) hppa_reg_struct_has_addr (gcc_p,type)
/* Offset from address of function to start of its code.
Zero on most machines. */
@ -86,23 +82,16 @@ extern int in_solib_call_trampoline (CORE_ADDR, char *);
in_solib_return_trampoline (pc, name)
extern int in_solib_return_trampoline (CORE_ADDR, char *);
/* Immediately after a function call, return the saved pc.
Can't go through the frames for this because on some machines
the new frame is not set up until the new function executes
some instructions. */
#undef SAVED_PC_AFTER_CALL
#define SAVED_PC_AFTER_CALL(frame) saved_pc_after_call (frame)
extern CORE_ADDR saved_pc_after_call (struct frame_info *);
/* Stack grows upward */
#define INNER_THAN(lhs,rhs) ((lhs) > (rhs))
extern int hppa_inner_than (CORE_ADDR lhs, CORE_ADDR rhs);
#define INNER_THAN(lhs,rhs) hppa_inner_than(lhs,rhs)
/* elz: adjust the quantity to the next highest value which is 64-bit aligned.
This is used in valops.c, when the sp is adjusted.
On hppa the sp must always be kept 64-bit aligned */
extern CORE_ADDR hppa_stack_align (CORE_ADDR sp);
#define STACK_ALIGN(sp) hppa_stack_align (sp)
#define STACK_ALIGN(arg) ( ((arg)%8) ? (((arg)+7)&-8) : (arg))
#define EXTRA_STACK_ALIGNMENT_NEEDED 0
/* Sequence of bytes for breakpoint instruction. */
@ -118,35 +107,8 @@ extern CORE_ADDR saved_pc_after_call (struct frame_info *);
#define DECR_PC_AFTER_BREAK 0
/* Sometimes we may pluck out a minimal symbol that has a negative
address.
An example of this occurs when an a.out is linked against a foo.sl.
The foo.sl defines a global bar(), and the a.out declares a signature
for bar(). However, the a.out doesn't directly call bar(), but passes
its address in another call.
If you have this scenario and attempt to "break bar" before running,
gdb will find a minimal symbol for bar() in the a.out. But that
symbol's address will be negative. What this appears to denote is
an index backwards from the base of the procedure linkage table (PLT)
into the data linkage table (DLT), the end of which is contiguous
with the start of the PLT. This is clearly not a valid address for
us to set a breakpoint on.
Note that one must be careful in how one checks for a negative address.
0xc0000000 is a legitimate address of something in a shared text
segment, for example. Since I don't know what the possible range
is of these "really, truly negative" addresses that come from the
minimal symbols, I'm resorting to the gross hack of checking the
top byte of the address for all 1's. Sigh.
*/
#define PC_REQUIRES_RUN_BEFORE_USE(pc) \
(! target_has_stack && (pc & 0xFF000000))
/* return instruction is bv r0(rp) or bv,n r0(rp) */
#define ABOUT_TO_RETURN(pc) ((read_memory_integer (pc, 4) | 0x2) == 0xE840C002)
extern int hppa_pc_requires_run_before_use (CORE_ADDR pc);
#define PC_REQUIRES_RUN_BEFORE_USE(pc) hppa_pc_requires_run_before_use (pc)
/* Say how long (ordinary) registers are. This is a piece of bogosity
used in push_word and a few other places; REGISTER_RAW_SIZE is the
@ -264,9 +226,8 @@ extern void pa_do_strcat_registers_info (int, int, struct ui_file *, enum precis
/* PA specific macro to see if the current instruction is nullified. */
#ifndef INSTRUCTION_NULLIFIED
#define INSTRUCTION_NULLIFIED \
(((int)read_register (IPSW_REGNUM) & 0x00200000) && \
!((int)read_register (FLAGS_REGNUM) & 0x2))
extern int hppa_instruction_nullified (void);
#define INSTRUCTION_NULLIFIED hppa_instruction_nullified ()
#endif
/* Number of bytes of storage in the actual machine representation
@ -279,10 +240,8 @@ extern void pa_do_strcat_registers_info (int, int, struct ui_file *, enum precis
register state, the array `registers'. */
#define REGISTER_BYTES (NUM_REGS * 4)
/* Index within `registers' of the first byte of the space for
register N. */
#define REGISTER_BYTE(N) (N) * 4
extern int hppa_register_byte (int reg_nr);
#define REGISTER_BYTE(N) hppa_register_byte (N)
/* Number of bytes of storage in the program's representation
for register N. */
@ -297,16 +256,11 @@ extern void pa_do_strcat_registers_info (int, int, struct ui_file *, enum precis
#define MAX_REGISTER_VIRTUAL_SIZE 8
/* Return the GDB type object for the "standard" data type
of data in register N. */
extern struct type * hppa_register_virtual_type (int reg_nr);
#define REGISTER_VIRTUAL_TYPE(N) hppa_register_virtual_type (N)
#define REGISTER_VIRTUAL_TYPE(N) \
((N) < FP4_REGNUM ? builtin_type_int : builtin_type_float)
/* Store the address of the place in which to copy the structure the
subroutine will return. This is called from call_function. */
#define STORE_STRUCT_RETURN(ADDR, SP) {write_register (28, (ADDR)); }
extern void hppa_store_struct_return (CORE_ADDR addr, CORE_ADDR sp);
#define STORE_STRUCT_RETURN(ADDR, SP) hppa_store_struct_return (ADDR, SP)
/* Extract from an array REGBUF containing the (raw) register state
a function return value of type TYPE, and copy that, in virtual format,
@ -360,21 +314,8 @@ struct value *hppa_value_returned_from_stack (register struct type *valtype,
#define VALUE_RETURNED_FROM_STACK(valtype,addr) \
hppa_value_returned_from_stack (valtype, addr)
/*
* This macro defines the register numbers (from REGISTER_NAMES) that
* are effectively unavailable to the user through ptrace(). It allows
* us to include the whole register set in REGISTER_NAMES (inorder to
* better support remote debugging). If it is used in
* fetch/store_inferior_registers() gdb will not complain about I/O errors
* on fetching these registers. If all registers in REGISTER_NAMES
* are available, then return false (0).
*/
#define CANNOT_STORE_REGISTER(regno) \
((regno) == 0) || \
((regno) == PCSQ_HEAD_REGNUM) || \
((regno) >= PCSQ_TAIL_REGNUM && (regno) < IPSW_REGNUM) || \
((regno) > IPSW_REGNUM && (regno) < FP4_REGNUM)
extern int hppa_cannot_store_register (int regnum);
#define CANNOT_STORE_REGISTER(regno) hppa_cannot_store_register (regno)
#define INIT_EXTRA_FRAME_INFO(fromleaf, frame) init_extra_frame_info (fromleaf, frame)
extern void init_extra_frame_info (int, struct frame_info *);
@ -407,9 +348,12 @@ extern int frameless_function_invocation (struct frame_info *);
extern CORE_ADDR hppa_frame_saved_pc (struct frame_info *frame);
#define FRAME_SAVED_PC(FRAME) hppa_frame_saved_pc (FRAME)
#define FRAME_ARGS_ADDRESS(fi) ((fi)->frame)
extern CORE_ADDR hppa_frame_args_address (struct frame_info *fi);
#define FRAME_ARGS_ADDRESS(fi) hppa_frame_args_address (fi)
extern CORE_ADDR hppa_frame_locals_address (struct frame_info *fi);
#define FRAME_LOCALS_ADDRESS(fi) hppa_frame_locals_address (fi)
#define FRAME_LOCALS_ADDRESS(fi) ((fi)->frame)
/* Set VAL to the number of args passed to frame described by FI.
Can set VAL to -1, meaning no way to tell. */
@ -591,13 +535,8 @@ hppa_fix_call_dummy (char *, CORE_ADDR, CORE_ADDR, int,
extern CORE_ADDR
hppa_push_arguments (int, struct value **, CORE_ADDR, int, CORE_ADDR);
/* The low two bits of the PC on the PA contain the privilege level. Some
genius implementing a (non-GCC) compiler apparently decided this means
that "addresses" in a text section therefore include a privilege level,
and thus symbol tables should contain these bits. This seems like a
bonehead thing to do--anyway, it seems to work for our purposes to just
ignore those bits. */
#define SMASH_TEXT_ADDRESS(addr) ((addr) &= ~0x3)
extern CORE_ADDR hppa_smash_text_address (CORE_ADDR addr);
#define SMASH_TEXT_ADDRESS(addr) hppa_smash_text_address (addr)
#define GDB_TARGET_IS_HPPA
@ -746,16 +685,12 @@ extern int hpread_adjust_stack_address (CORE_ADDR);
/* If the current gcc for for this target does not produce correct debugging
information for float parameters, both prototyped and unprototyped, then
define this macro. This forces gdb to always assume that floats are
passed as doubles and then converted in the callee.
passed as doubles and then converted in the callee. */
For the pa, it appears that the debug info marks the parameters as
floats regardless of whether the function is prototyped, but the actual
values are passed as doubles for the non-prototyped case and floats for
the prototyped case. Thus we choose to make the non-prototyped case work
for C and break the prototyped case, since the non-prototyped case is
probably much more common. (FIXME). */
#define COERCE_FLOAT_TO_DOUBLE(formal, actual) (current_language -> la_language == language_c)
extern int hppa_coerce_float_to_double (struct type *formal,
struct type *actual);
#define COERCE_FLOAT_TO_DOUBLE(formal, actual) \
hppa_coerce_float_to_double (formal, actual)
/* Here's how to step off a permanent breakpoint. */
#define SKIP_PERMANENT_BREAKPOINT (hppa_skip_permanent_breakpoint)

View File

@ -30,6 +30,7 @@
#include "value.h"
#include "regcache.h"
#include "completer.h"
#include "language.h"
/* For argument passing to the inferior */
#include "symtab.h"
@ -130,6 +131,21 @@ static void pa_register_look_aside (char *, int, long *);
static void pa_print_fp_reg (int);
static void pa_strcat_fp_reg (int, struct ui_file *, enum precision_type);
static void record_text_segment_lowaddr (bfd *, asection *, void *);
/* FIXME: brobecker 2002-11-07: We will likely be able to make the
following functions static, once we hppa is partially multiarched. */
int hppa_reg_struct_has_addr (int gcc_p, struct type *type);
int hppa_inner_than (CORE_ADDR lhs, CORE_ADDR rhs);
CORE_ADDR hppa_stack_align (CORE_ADDR sp);
int hppa_pc_requires_run_before_use (CORE_ADDR pc);
int hppa_instruction_nullified (void);
int hppa_register_byte (int reg_nr);
struct type * hppa_register_virtual_type (int reg_nr);
void hppa_store_struct_return (CORE_ADDR addr, CORE_ADDR sp);
int hppa_cannot_store_register (int regnum);
CORE_ADDR hppa_frame_args_address (struct frame_info *fi);
CORE_ADDR hppa_frame_locals_address (struct frame_info *fi);
CORE_ADDR hppa_smash_text_address (CORE_ADDR addr);
int hppa_coerce_float_to_double (struct type *formal, struct type *actual);
typedef struct
{
@ -150,6 +166,7 @@ extern int hp_som_som_object_present;
extern int exception_catchpoints_are_fragile;
/* Should call_function allocate stack space for a struct return? */
int
hppa_use_struct_convention (int gcc_p, struct type *type)
{
@ -810,6 +827,11 @@ frameless_function_invocation (struct frame_info *frame)
return (u->Total_frame_size == 0 && u->stub_unwind.stub_type == 0);
}
/* Immediately after a function call, return the saved pc.
Can't go through the frames for this because on some machines
the new frame is not set up until the new function executes
some instructions. */
CORE_ADDR
saved_pc_after_call (struct frame_info *frame)
{
@ -4724,6 +4746,151 @@ hppa_extract_return_value (struct type *type, char *regbuf, char *valbuf)
TYPE_LENGTH (type));
}
int
hppa_reg_struct_has_addr (int gcc_p, struct type *type)
{
/* On the PA, any pass-by-value structure > 8 bytes is actually passed
via a pointer regardless of its type or the compiler used. */
return (TYPE_LENGTH (type) > 8);
}
int
hppa_inner_than (CORE_ADDR lhs, CORE_ADDR rhs)
{
/* Stack grows upward */
return (lhs > rhs);
}
CORE_ADDR
hppa_stack_align (CORE_ADDR sp)
{
/* elz: adjust the quantity to the next highest value which is
64-bit aligned. This is used in valops.c, when the sp is adjusted.
On hppa the sp must always be kept 64-bit aligned */
return ((sp % 8) ? (sp + 7) & -8 : sp);
}
int
hppa_pc_requires_run_before_use (CORE_ADDR pc)
{
/* Sometimes we may pluck out a minimal symbol that has a negative address.
An example of this occurs when an a.out is linked against a foo.sl.
The foo.sl defines a global bar(), and the a.out declares a signature
for bar(). However, the a.out doesn't directly call bar(), but passes
its address in another call.
If you have this scenario and attempt to "break bar" before running,
gdb will find a minimal symbol for bar() in the a.out. But that
symbol's address will be negative. What this appears to denote is
an index backwards from the base of the procedure linkage table (PLT)
into the data linkage table (DLT), the end of which is contiguous
with the start of the PLT. This is clearly not a valid address for
us to set a breakpoint on.
Note that one must be careful in how one checks for a negative address.
0xc0000000 is a legitimate address of something in a shared text
segment, for example. Since I don't know what the possible range
is of these "really, truly negative" addresses that come from the
minimal symbols, I'm resorting to the gross hack of checking the
top byte of the address for all 1's. Sigh. */
return (!target_has_stack && (pc & 0xFF000000));
}
int
hppa_instruction_nullified (void)
{
/* brobecker 2002/11/07: Couldn't we use a ULONGEST here? It would
avoid the type cast. I'm leaving it as is for now as I'm doing
semi-mechanical multiarching-related changes. */
const int ipsw = (int) read_register (IPSW_REGNUM);
const int flags = (int) read_register (FLAGS_REGNUM);
return ((ipsw & 0x00200000) && !(flags & 0x2));
}
/* Index within the register vector of the first byte of the space i
used for register REG_NR. */
int
hppa_register_byte (int reg_nr)
{
return reg_nr * 4;
}
/* Return the GDB type object for the "standard" data type of data
in register N. */
struct type *
hppa_register_virtual_type (int reg_nr)
{
if (reg_nr < FP4_REGNUM)
return builtin_type_int;
else
return builtin_type_float;
}
/* Store the address of the place in which to copy the structure the
subroutine will return. This is called from call_function. */
void
hppa_store_struct_return (CORE_ADDR addr, CORE_ADDR sp)
{
write_register (28, addr);
}
/* Return True if REGNUM is not a register available to the user
through ptrace(). */
int
hppa_cannot_store_register (int regnum)
{
return (regnum == 0
|| regnum == PCSQ_HEAD_REGNUM
|| (regnum >= PCSQ_TAIL_REGNUM && regnum < IPSW_REGNUM)
|| (regnum > IPSW_REGNUM && regnum < FP4_REGNUM));
}
CORE_ADDR
hppa_frame_args_address (struct frame_info *fi)
{
return fi->frame;
}
CORE_ADDR
hppa_frame_locals_address (struct frame_info *fi)
{
return fi->frame;
}
CORE_ADDR
hppa_smash_text_address (CORE_ADDR addr)
{
/* The low two bits of the PC on the PA contain the privilege level.
Some genius implementing a (non-GCC) compiler apparently decided
this means that "addresses" in a text section therefore include a
privilege level, and thus symbol tables should contain these bits.
This seems like a bonehead thing to do--anyway, it seems to work
for our purposes to just ignore those bits. */
return (addr &= ~0x3);
}
int
hppa_coerce_float_to_double (struct type *formal, struct type *actual)
{
/* FIXME: For the pa, it appears that the debug info marks the
parameters as floats regardless of whether the function is
prototyped, but the actual values are passed as doubles for the
non-prototyped case and floats for the prototyped case. Thus we
choose to make the non-prototyped case work for C and break the
prototyped case, since the non-prototyped case is probably much
more common. */
return (current_language -> la_language == language_c);
}
static struct gdbarch *
hppa_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
{