diff options
author | Joel Brobecker <brobecker@gnat.com> | 2002-11-08 03:35:47 +0000 |
---|---|---|
committer | Joel Brobecker <brobecker@gnat.com> | 2002-11-08 03:35:47 +0000 |
commit | d709c0200723c8e71df58cc6df48c2116bb5e733 (patch) | |
tree | 6ad63b1c1493f5528c782726d45dadc0fbde44f3 /gdb/hppa-tdep.c | |
parent | 83c31e7d1e6077d2802d8906453622471b72de8d (diff) | |
download | gdb-d709c0200723c8e71df58cc6df48c2116bb5e733.zip gdb-d709c0200723c8e71df58cc6df48c2116bb5e733.tar.gz gdb-d709c0200723c8e71df58cc6df48c2116bb5e733.tar.bz2 |
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.
Diffstat (limited to 'gdb/hppa-tdep.c')
-rw-r--r-- | gdb/hppa-tdep.c | 167 |
1 files changed, 167 insertions, 0 deletions
diff --git a/gdb/hppa-tdep.c b/gdb/hppa-tdep.c index c64f6f7..c7d9c38 100644 --- a/gdb/hppa-tdep.c +++ b/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) { |