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

@ -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)
{