/* GNU/Linux on ARM target support.
- Copyright 1999, 2000, 2001 Free Software Foundation, Inc.
+ Copyright 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
This file is part of GDB.
#include "regcache.h"
#include "doublest.h"
+#include "arm-tdep.h"
+
/* For arm_linux_skip_solib_resolver. */
#include "symtab.h"
#include "symfile.h"
#include "objfiles.h"
+/* CALL_DUMMY_WORDS:
+ This sequence of words is the instructions
+
+ mov lr, pc
+ mov pc, r4
+ swi bkpt_swi
+
+ Note this is 12 bytes. */
+
+LONGEST arm_linux_call_dummy_words[] =
+{
+ 0xe1a0e00f, 0xe1a0f004, 0xef9f001
+};
+
#ifdef GET_LONGJMP_TARGET
/* Figure out where the longjmp will land. We expect that we have
just entered longjmp and haven't yet altered r0, r1, so the
- arguments are still in the registers. (A1_REGNUM) points at the
- jmp_buf structure from which we extract the pc (JB_PC) that we will
- land at. The pc is copied into ADDR. This routine returns true on
- success. */
+ arguments are still in the registers. (ARM_A1_REGNUM) points at
+ the jmp_buf structure from which we extract the pc (JB_PC) that we
+ will land at. The pc is copied into ADDR. This routine returns
+ true on success. */
#define LONGJMP_TARGET_SIZE sizeof(int)
#define JB_ELEMENT_SIZE sizeof(int)
CORE_ADDR jb_addr;
char buf[LONGJMP_TARGET_SIZE];
- jb_addr = read_register (A1_REGNUM);
+ jb_addr = read_register (ARM_A1_REGNUM);
if (target_read_memory (jb_addr + JB_PC * JB_ELEMENT_SIZE, buf,
LONGJMP_TARGET_SIZE))
GDB. I suspect this won't handle NWFPE registers correctly, nor
will the default ARM version (arm_extract_return_value()). */
- int regnum = (TYPE_CODE_FLT == TYPE_CODE (type)) ? F0_REGNUM : A1_REGNUM;
+ int regnum = ((TYPE_CODE_FLT == TYPE_CODE (type))
+ ? ARM_F0_REGNUM : ARM_A1_REGNUM);
memcpy (valbuf, ®buf[REGISTER_BYTE (regnum)], TYPE_LENGTH (type));
}
}
/* Initialize the integer argument register pointer. */
- argreg = A1_REGNUM;
+ argreg = ARM_A1_REGNUM;
/* The struct_return pointer occupies the first parameter passing
register. */
{
int len;
char *val;
- double dbl_arg;
CORE_ADDR regval;
enum type_code typecode;
struct type *arg_type, *target_type;
calling the function. */
if (TYPE_CODE_FLT == typecode && REGISTER_SIZE == len)
{
- /* Float argument in buffer is in host format. Read it and
- convert to DOUBLEST, and store it in target double. */
DOUBLEST dblval;
-
+ dblval = extract_floating (val, len);
len = TARGET_DOUBLE_BIT / TARGET_CHAR_BIT;
- floatformat_to_doublest (HOST_FLOAT_FORMAT, val, &dblval);
- store_floating (&dbl_arg, len, dblval);
- val = (char *) &dbl_arg;
+ val = alloca (len);
+ store_floating (val, len, dblval);
}
/* If the argument is a pointer to a function, and it is a Thumb
if (resolver)
{
struct minimal_symbol *fixup
- = lookup_minimal_symbol ("fixup", 0, objfile);
+ = lookup_minimal_symbol ("fixup", NULL, objfile);
if (fixup && SYMBOL_VALUE_ADDRESS (fixup) == pc)
return (SAVED_PC_AFTER_CALL (get_current_frame ()));
PSR value follows the sixteen registers which accounts for
the constant 19 below. */
- if (0 <= regno && regno <= PC_REGNUM)
+ if (0 <= regno && regno <= ARM_PC_REGNUM)
reg_addr = sigcontext_addr + 12 + (4 * regno);
- else if (regno == PS_REGNUM)
+ else if (regno == ARM_PS_REGNUM)
reg_addr = sigcontext_addr + 19 * 4;
}
return reg_addr;
}
+static void
+arm_linux_init_abi (struct gdbarch_info info,
+ struct gdbarch *gdbarch)
+{
+ struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
+
+ tdep->lowest_pc = 0x8000;
+}
+
void
_initialize_arm_linux_tdep (void)
{
+ arm_gdbarch_register_os_abi (ARM_ABI_LINUX, arm_linux_init_abi);
}