diff options
author | Randolph Chung <tausq@debian.org> | 2004-06-07 02:08:07 +0000 |
---|---|---|
committer | Randolph Chung <tausq@debian.org> | 2004-06-07 02:08:07 +0000 |
commit | d49771efb59f489ecc7ece815583f57ffebbb523 (patch) | |
tree | 965a6fab6595c6c1bbd711a633a1d2cea0a39703 /gdb/hppa-tdep.c | |
parent | 7d9b040b53ba0e94d46774491ec01dd919af6587 (diff) | |
download | gdb-d49771efb59f489ecc7ece815583f57ffebbb523.zip gdb-d49771efb59f489ecc7ece815583f57ffebbb523.tar.gz gdb-d49771efb59f489ecc7ece815583f57ffebbb523.tar.bz2 |
2004-06-06 Randolph Chung <tausq@debian.org>
* hppa-tdep.h (struct value): Forward declaration.
(gdbarch_tdep): Define tdep find_global_pointer method.
* hppa-tdep.c (hppa32_push_dummy_call): Find the global pointer
associated with the function we are trying to call, and write it
to the gp register.
(hppa32_convert_from_funct_ptr_addr): New function.
(hppa_find_global_pointer): New function.
(hppa_gdbarch_init): Set default find_global_pointer method; set
convert_from_func_ptr_addr method.
* hppa-linux-tdep.c (hppa_linux_find_global_pointer): New function.
(hppa_linux_init_abi): Set find_global_pointer method.
* Makefile.in (hppa-linux-tdep.o): Add value.h dependency.
Diffstat (limited to 'gdb/hppa-tdep.c')
-rw-r--r-- | gdb/hppa-tdep.c | 37 |
1 files changed, 37 insertions, 0 deletions
diff --git a/gdb/hppa-tdep.c b/gdb/hppa-tdep.c index 4af061f..a5b2f85 100644 --- a/gdb/hppa-tdep.c +++ b/gdb/hppa-tdep.c @@ -727,6 +727,12 @@ hppa32_push_dummy_call (struct gdbarch *gdbarch, struct value *function, /* Two passes. First pass computes the location of everything, second pass writes the bytes out. */ int write_pass; + + /* Global pointer (r19) of the function we are trying to call. */ + CORE_ADDR gp; + + struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch); + for (write_pass = 0; write_pass < 2; write_pass++) { CORE_ADDR struct_ptr = 0; @@ -847,6 +853,11 @@ hppa32_push_dummy_call (struct gdbarch *gdbarch, struct value *function, if (struct_return) write_register (28, struct_addr); + gp = tdep->find_global_pointer (function); + + if (gp != 0) + write_register (19, gp); + /* Set the return address. */ regcache_cooked_write_unsigned (regcache, HPPA_RP_REGNUM, bp_addr); @@ -980,6 +991,22 @@ hppa64_push_dummy_call (struct gdbarch *gdbarch, struct value *function, } static CORE_ADDR +hppa32_convert_from_func_ptr_addr (struct gdbarch *gdbarch, + CORE_ADDR addr, + struct target_ops *targ) +{ + if (addr & 2) + { + CORE_ADDR plabel; + + plabel = addr & ~3; + target_read_memory(plabel, (char *)&addr, 4); + } + + return addr; +} + +static CORE_ADDR hppa32_frame_align (struct gdbarch *gdbarch, CORE_ADDR addr) { /* HP frames are 64-byte (or cache line) aligned (yes that's _byte_ @@ -2309,6 +2336,12 @@ hppa_pseudo_register_read (struct gdbarch *gdbarch, struct regcache *regcache, store_unsigned_integer (buf, sizeof(tmp), tmp); } +static CORE_ADDR +hppa_find_global_pointer (struct value *function) +{ + return 0; +} + void hppa_frame_prev_register_helper (struct frame_info *next_frame, struct trad_frame_saved_reg saved_regs[], @@ -2410,6 +2443,8 @@ hppa_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches) else tdep->bytes_per_address = 4; + tdep->find_global_pointer = hppa_find_global_pointer; + /* Some parts of the gdbarch vector depend on whether we are running on a 32 bits or 64 bits target. */ switch (tdep->bytes_per_address) @@ -2469,6 +2504,8 @@ hppa_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches) case 4: set_gdbarch_push_dummy_call (gdbarch, hppa32_push_dummy_call); set_gdbarch_frame_align (gdbarch, hppa32_frame_align); + set_gdbarch_convert_from_func_ptr_addr + (gdbarch, hppa32_convert_from_func_ptr_addr); break; case 8: set_gdbarch_push_dummy_call (gdbarch, hppa64_push_dummy_call); |