#include "frame.h"
#include "regcache.h"
#include "doublest.h"
+#include "solib-svr4.h"
#include "osabi.h"
#include "arm-tdep.h"
is to execute a particular software interrupt, rather than use a
particular undefined instruction to provoke a trap. Upon exection
of the software interrupt the kernel stops the inferior with a
- SIGTRAP, and wakes the debugger. Since ARM GNU/Linux is little
- endian, and doesn't support Thumb at the moment we only override
- the ARM little-endian breakpoint. */
+ SIGTRAP, and wakes the debugger. Since ARM GNU/Linux doesn't support
+ Thumb at the moment we only override the ARM breakpoints. */
-static const char arm_linux_arm_le_breakpoint[] = {0x01,0x00,0x9f,0xef};
+static const char arm_linux_arm_le_breakpoint[] = { 0x01, 0x00, 0x9f, 0xef };
+
+static const char arm_linux_arm_be_breakpoint[] = { 0xef, 0x9f, 0x00, 0x01 };
/* DEPRECATED_CALL_DUMMY_WORDS:
This sequence of words is the instructions
hidden behind the regcache abstraction. */
static void
arm_linux_extract_return_value (struct type *type,
- char regbuf[REGISTER_BYTES],
+ char regbuf[],
char *valbuf)
{
/* ScottB: This needs to be looked at to handle the different
int regnum = ((TYPE_CODE_FLT == TYPE_CODE (type))
? ARM_F0_REGNUM : ARM_A1_REGNUM);
- memcpy (valbuf, ®buf[REGISTER_BYTE (regnum)], TYPE_LENGTH (type));
+ memcpy (valbuf, ®buf[DEPRECATED_REGISTER_BYTE (regnum)], TYPE_LENGTH (type));
}
/* Note: ScottB
&& NULL != target_type
&& TYPE_CODE_FUNC == TYPE_CODE (target_type))
{
- CORE_ADDR regval = extract_address (val, len);
+ CORE_ADDR regval = extract_unsigned_integer (val, len);
if (arm_pc_is_thumb (regval))
- store_address (val, len, MAKE_THUMB_ADDR (regval));
+ store_unsigned_integer (val, len, MAKE_THUMB_ADDR (regval));
}
/* Copy the argument to general registers or the stack in
if (argreg <= ARM_LAST_ARG_REGNUM)
{
/* It's an argument being passed in a general register. */
- regval = extract_address (val, partial_len);
+ regval = extract_unsigned_integer (val, partial_len);
write_register (argreg++, regval);
}
else
}
+/* Fetch, and possibly build, an appropriate link_map_offsets structure
+ for ARM linux targets using the struct offsets defined in <link.h>.
+ Note, however, that link.h is not actually referred to in this file.
+ Instead, the relevant structs offsets were obtained from examining
+ link.h. (We can't refer to link.h from this file because the host
+ system won't necessarily have it, or if it does, the structs which
+ it defines will refer to the host system, not the target). */
+
+static struct link_map_offsets *
+arm_linux_svr4_fetch_link_map_offsets (void)
+{
+ static struct link_map_offsets lmo;
+ static struct link_map_offsets *lmp = 0;
+
+ if (lmp == 0)
+ {
+ lmp = &lmo;
+
+ lmo.r_debug_size = 8; /* Actual size is 20, but this is all we
+ need. */
+
+ lmo.r_map_offset = 4;
+ lmo.r_map_size = 4;
+
+ lmo.link_map_size = 20; /* Actual size is 552, but this is all we
+ need. */
+
+ 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 CORE_ADDR
skip_hurd_resolver (CORE_ADDR pc)
{
struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
tdep->lowest_pc = 0x8000;
- tdep->arm_breakpoint = arm_linux_arm_le_breakpoint;
+ if (info.byte_order == BFD_ENDIAN_BIG)
+ tdep->arm_breakpoint = arm_linux_arm_be_breakpoint;
+ else
+ tdep->arm_breakpoint = arm_linux_arm_le_breakpoint;
tdep->arm_breakpoint_size = sizeof (arm_linux_arm_le_breakpoint);
tdep->fp_model = ARM_FLOAT_FPA;
tdep->jb_pc = ARM_LINUX_JB_PC;
tdep->jb_elt_size = ARM_LINUX_JB_ELEMENT_SIZE;
+ set_solib_svr4_fetch_link_map_offsets
+ (gdbarch, arm_linux_svr4_fetch_link_map_offsets);
+
set_gdbarch_deprecated_call_dummy_words (gdbarch, arm_linux_call_dummy_words);
set_gdbarch_deprecated_sizeof_call_dummy_words (gdbarch, sizeof (arm_linux_call_dummy_words));