/* Target-dependent code for GDB, the GNU debugger.
- Copyright 2001, 2002, 2003, 2004, 2005 Free Software Foundation,
- Inc.
+ Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006
+ Free Software Foundation, Inc.
Contributed by D.J. Barrow (djbarrow@de.ibm.com,barrow_dj@yahoo.com)
for IBM Deutschland Entwicklung GmbH, IBM Corporation.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
- Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
- 02111-1307, USA. */
+ Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ Boston, MA 02110-1301, USA. */
#include "defs.h"
#include "arch-utils.h"
#include "gdbcore.h"
#include "gdbcmd.h"
#include "objfiles.h"
-#include "tm.h"
-#include "../bfd/bfd.h"
#include "floatformat.h"
#include "regcache.h"
#include "trad-frame.h"
#include "value.h"
#include "gdb_assert.h"
#include "dis-asm.h"
-#include "solib-svr4.h" /* For struct link_map_offsets. */
+#include "solib-svr4.h"
#include "s390-tdep.h"
static void
s390_pseudo_register_read (struct gdbarch *gdbarch, struct regcache *regcache,
- int regnum, void *buf)
+ int regnum, gdb_byte *buf)
{
ULONGEST val;
static void
s390_pseudo_register_write (struct gdbarch *gdbarch, struct regcache *regcache,
- int regnum, const void *buf)
+ int regnum, const gdb_byte *buf)
{
ULONGEST val, psw;
static void
s390x_pseudo_register_read (struct gdbarch *gdbarch, struct regcache *regcache,
- int regnum, void *buf)
+ int regnum, gdb_byte *buf)
{
ULONGEST val;
static void
s390x_pseudo_register_write (struct gdbarch *gdbarch, struct regcache *regcache,
- int regnum, const void *buf)
+ int regnum, const gdb_byte *buf)
{
ULONGEST val, psw;
static void
s390_register_to_value (struct frame_info *frame, int regnum,
- struct type *valtype, void *out)
+ struct type *valtype, gdb_byte *out)
{
- char in[8];
+ gdb_byte in[8];
int len = TYPE_LENGTH (valtype);
gdb_assert (len < 8);
static void
s390_value_to_register (struct frame_info *frame, int regnum,
- struct type *valtype, const void *in)
+ struct type *valtype, const gdb_byte *in)
{
- char out[8];
+ gdb_byte out[8];
int len = TYPE_LENGTH (valtype);
gdb_assert (len < 8);
{
op1_lhi = 0xa7, op2_lhi = 0x08,
op1_lghi = 0xa7, op2_lghi = 0x09,
+ op1_lgfi = 0xc0, op2_lgfi = 0x01,
op_lr = 0x18,
op_lgr = 0xb904,
op_l = 0x58,
op1_stmg = 0xeb, op2_stmg = 0x24,
op1_aghi = 0xa7, op2_aghi = 0x0b,
op1_ahi = 0xa7, op2_ahi = 0x0a,
+ op1_agfi = 0xc2, op2_agfi = 0x08,
+ op1_afi = 0xc2, op2_afi = 0x09,
+ op1_algfi= 0xc2, op2_algfi= 0x0a,
+ op1_alfi = 0xc2, op2_alfi = 0x0b,
op_ar = 0x1a,
op_agr = 0xb908,
op_a = 0x5a,
op1_ay = 0xe3, op2_ay = 0x5a,
op1_ag = 0xe3, op2_ag = 0x08,
+ op1_slgfi= 0xc2, op2_slgfi= 0x04,
+ op1_slfi = 0xc2, op2_slfi = 0x05,
op_sr = 0x1b,
op_sgr = 0xb909,
op_s = 0x5b,
&& is_ri (insn, op1_lghi, op2_lghi, &r1, &i2))
pv_set_to_constant (&data->gpr[r1], i2);
+ /* LGFI r1, i2 --- load fullword immediate */
+ else if (is_ril (insn, op1_lgfi, op2_lgfi, &r1, &i2))
+ pv_set_to_constant (&data->gpr[r1], i2);
+
/* LR r1, r2 --- load from register */
else if (word_size == 4
&& is_rr (insn, op_lr, &r1, &r2))
&& is_ri (insn, op1_aghi, op2_aghi, &r1, &i2))
pv_add_constant (&data->gpr[r1], i2);
+ /* AFI r1, i2 --- add fullword immediate */
+ else if (word_size == 4
+ && is_ril (insn, op1_afi, op2_afi, &r1, &i2))
+ pv_add_constant (&data->gpr[r1], i2);
+
+ /* AGFI r1, i2 --- add fullword immediate (64-bit version) */
+ else if (word_size == 8
+ && is_ril (insn, op1_agfi, op2_agfi, &r1, &i2))
+ pv_add_constant (&data->gpr[r1], i2);
+
+ /* ALFI r1, i2 --- add logical immediate */
+ else if (word_size == 4
+ && is_ril (insn, op1_alfi, op2_alfi, &r1, &i2))
+ pv_add_constant (&data->gpr[r1], (CORE_ADDR)i2 & 0xffffffff);
+
+ /* ALGFI r1, i2 --- add logical immediate (64-bit version) */
+ else if (word_size == 8
+ && is_ril (insn, op1_algfi, op2_algfi, &r1, &i2))
+ pv_add_constant (&data->gpr[r1], (CORE_ADDR)i2 & 0xffffffff);
+
/* AR r1, r2 -- add register */
else if (word_size == 4
&& is_rr (insn, op_ar, &r1, &r2))
pv_add (&data->gpr[r1], &data->gpr[r1], &value);
}
+ /* SLFI r1, i2 --- subtract logical immediate */
+ else if (word_size == 4
+ && is_ril (insn, op1_slfi, op2_slfi, &r1, &i2))
+ pv_add_constant (&data->gpr[r1], -((CORE_ADDR)i2 & 0xffffffff));
+
+ /* SLGFI r1, i2 --- subtract logical immediate (64-bit version) */
+ else if (word_size == 8
+ && is_ril (insn, op1_slgfi, op2_slgfi, &r1, &i2))
+ pv_add_constant (&data->gpr[r1], -((CORE_ADDR)i2 & 0xffffffff));
+
/* SR r1, r2 -- subtract register */
else if (word_size == 4
&& is_rr (insn, op_sr, &r1, &r2))
void **this_prologue_cache,
int regnum, int *optimizedp,
enum lval_type *lvalp, CORE_ADDR *addrp,
- int *realnump, void *bufferp)
+ int *realnump, gdb_byte *bufferp)
{
struct s390_unwind_cache *info
= s390_frame_unwind_cache (next_frame, this_prologue_cache);
void **this_prologue_cache,
int regnum, int *optimizedp,
enum lval_type *lvalp, CORE_ADDR *addrp,
- int *realnump, void *bufferp)
+ int *realnump, gdb_byte *bufferp)
{
struct s390_stub_unwind_cache *info
= s390_stub_frame_unwind_cache (next_frame, this_prologue_cache);
void **this_prologue_cache,
int regnum, int *optimizedp,
enum lval_type *lvalp, CORE_ADDR *addrp,
- int *realnump, void *bufferp)
+ int *realnump, gdb_byte *bufferp)
{
struct s390_sigtramp_unwind_cache *info
= s390_sigtramp_frame_unwind_cache (next_frame, this_prologue_cache);
static enum return_value_convention
s390_return_value (struct gdbarch *gdbarch, struct type *type,
- struct regcache *regcache, void *out, const void *in)
+ struct regcache *regcache, gdb_byte *out,
+ const gdb_byte *in)
{
int word_size = gdbarch_ptr_bit (gdbarch) / 8;
int length = TYPE_LENGTH (type);
else if (length == 2*word_size)
{
regcache_cooked_write (regcache, S390_R2_REGNUM, in);
- regcache_cooked_write (regcache, S390_R3_REGNUM,
- (const char *)in + word_size);
+ regcache_cooked_write (regcache, S390_R3_REGNUM, in + word_size);
}
else
internal_error (__FILE__, __LINE__, _("invalid return type"));
else if (length == 2*word_size)
{
regcache_cooked_read (regcache, S390_R2_REGNUM, out);
- regcache_cooked_read (regcache, S390_R3_REGNUM,
- (char *)out + word_size);
+ regcache_cooked_read (regcache, S390_R3_REGNUM, out + word_size);
}
else
internal_error (__FILE__, __LINE__, _("invalid return type"));
/* Breakpoints. */
-static const unsigned char *
+static const gdb_byte *
s390_breakpoint_from_pc (CORE_ADDR *pcptr, int *lenptr)
{
- static unsigned char breakpoint[] = { 0x0, 0x1 };
+ static const gdb_byte breakpoint[] = { 0x0, 0x1 };
*lenptr = sizeof (breakpoint);
return breakpoint;
return 0;
}
-
-/* Link map offsets. */
-
-static struct link_map_offsets *
-s390_svr4_fetch_link_map_offsets (void)
-{
- static struct link_map_offsets lmo;
- static struct link_map_offsets *lmp = NULL;
-
- if (lmp == NULL)
- {
- lmp = &lmo;
-
- lmo.r_debug_size = 8;
-
- lmo.r_map_offset = 4;
- lmo.r_map_size = 4;
-
- lmo.link_map_size = 20;
-
- lmo.l_addr_offset = 0;
- lmo.l_addr_size = 4;
-
- lmo.l_name_offset = 4;
- lmo.l_name_size = 4;
-
- lmo.l_next_offset = 12;
- lmo.l_next_size = 4;
-
- lmo.l_prev_offset = 16;
- lmo.l_prev_size = 4;
- }
-
- return lmp;
-}
-
-static struct link_map_offsets *
-s390x_svr4_fetch_link_map_offsets (void)
-{
- static struct link_map_offsets lmo;
- static struct link_map_offsets *lmp = NULL;
-
- if (lmp == NULL)
- {
- lmp = &lmo;
-
- lmo.r_debug_size = 16; /* All we need. */
-
- lmo.r_map_offset = 8;
- lmo.r_map_size = 8;
-
- lmo.link_map_size = 40; /* All we need. */
-
- lmo.l_addr_offset = 0;
- lmo.l_addr_size = 8;
-
- lmo.l_name_offset = 8;
- lmo.l_name_size = 8;
-
- lmo.l_next_offset = 24;
- lmo.l_next_size = 8;
-
- lmo.l_prev_offset = 32;
- lmo.l_prev_size = 8;
- }
-
- return lmp;
-}
-
-
/* Set up gdbarch struct. */
static struct gdbarch *
set_gdbarch_addr_bits_remove (gdbarch, s390_addr_bits_remove);
set_gdbarch_pseudo_register_read (gdbarch, s390_pseudo_register_read);
set_gdbarch_pseudo_register_write (gdbarch, s390_pseudo_register_write);
- set_solib_svr4_fetch_link_map_offsets (gdbarch,
- s390_svr4_fetch_link_map_offsets);
+ set_solib_svr4_fetch_link_map_offsets
+ (gdbarch, svr4_ilp32_fetch_link_map_offsets);
break;
case bfd_mach_s390_64:
set_gdbarch_ptr_bit (gdbarch, 64);
set_gdbarch_pseudo_register_read (gdbarch, s390x_pseudo_register_read);
set_gdbarch_pseudo_register_write (gdbarch, s390x_pseudo_register_write);
- set_solib_svr4_fetch_link_map_offsets (gdbarch,
- s390x_svr4_fetch_link_map_offsets);
+ set_solib_svr4_fetch_link_map_offsets
+ (gdbarch, svr4_lp64_fetch_link_map_offsets);
set_gdbarch_address_class_type_flags (gdbarch,
s390_address_class_type_flags);
set_gdbarch_address_class_type_flags_to_name (gdbarch,