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:
parent
83c31e7d1e
commit
d709c02007
4 changed files with 241 additions and 96 deletions
|
@ -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.
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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)
|
||||
|
|
167
gdb/hppa-tdep.c
167
gdb/hppa-tdep.c
|
@ -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)
|
||||
{
|
||||
|
|
Loading…
Reference in a new issue