/* Dynamic architecture support for GDB, the GNU debugger.
- Copyright 1998, 1999, 2000, 2001 Free Software Foundation, Inc.
+
+ Copyright 1998, 1999, 2000, 2001, 2002 Free Software Foundation,
+ Inc.
This file is part of GDB.
#else
/* Just include everything in sight so that the every old definition
of macro is visible. */
-#include "gdb_string.h"
#include "symtab.h"
#include "frame.h"
#include "inferior.h"
#include "target.h"
#include "annotate.h"
#endif
+#include "gdb_string.h"
#include "regcache.h"
#include "gdb_assert.h"
+#include "sim-regno.h"
#include "version.h"
and optionally adjust the pc to point to the correct memory location
for inserting the breakpoint. */
-unsigned char *
+const unsigned char *
legacy_breakpoint_from_pc (CORE_ADDR * pcptr, int *lenptr)
{
/* {BIG_,LITTLE_}BREAKPOINT is the sequence of bytes we insert for a
breakpoint. On some machines, breakpoints are handled by the
target environment and we don't have to worry about them here. */
#ifdef BIG_BREAKPOINT
- if (TARGET_BYTE_ORDER == BIG_ENDIAN)
+ if (TARGET_BYTE_ORDER == BFD_ENDIAN_BIG)
{
static unsigned char big_break_insn[] = BIG_BREAKPOINT;
*lenptr = sizeof (big_break_insn);
}
#endif
#ifdef LITTLE_BREAKPOINT
- if (TARGET_BYTE_ORDER != BIG_ENDIAN)
+ if (TARGET_BYTE_ORDER != BFD_ENDIAN_BIG)
{
static unsigned char little_break_insn[] = LITTLE_BREAKPOINT;
*lenptr = sizeof (little_break_insn);
return NULL;
}
+/* Implementation of extract return value that grubs around in the
+ register cache. */
+void
+legacy_extract_return_value (struct type *type, struct regcache *regcache,
+ void *valbuf)
+{
+ char *registers = deprecated_grub_regcache_for_registers (regcache);
+ bfd_byte *buf = valbuf;
+ DEPRECATED_EXTRACT_RETURN_VALUE (type, registers, buf);
+}
+
+/* Implementation of store return value that grubs the register cache.
+ Takes a local copy of the buffer to avoid const problems. */
+void
+legacy_store_return_value (struct type *type, struct regcache *regcache,
+ const void *buf)
+{
+ bfd_byte *b = alloca (TYPE_LENGTH (type));
+ gdb_assert (regcache == current_regcache);
+ memcpy (b, buf, TYPE_LENGTH (type));
+ DEPRECATED_STORE_RETURN_VALUE (type, b);
+}
+
+
+int
+legacy_register_sim_regno (int regnum)
+{
+ /* Only makes sense to supply raw registers. */
+ gdb_assert (regnum >= 0 && regnum < NUM_REGS);
+ /* NOTE: cagney/2002-05-13: The old code did it this way and it is
+ suspected that some GDB/SIM combinations may rely on this
+ behavour. The default should be one2one_register_sim_regno
+ (below). */
+ if (REGISTER_NAME (regnum) != NULL
+ && REGISTER_NAME (regnum)[0] != '\0')
+ return regnum;
+ else
+ return LEGACY_SIM_REGNO_IGNORE;
+}
+
int
generic_frameless_function_invocation_not (struct frame_info *fi)
{
return 0;
}
+int
+generic_in_solib_return_trampoline (CORE_ADDR pc, char *name)
+{
+ return 0;
+}
+
int
generic_in_function_epilogue_p (struct gdbarch *gdbarch, CORE_ADDR pc)
{
return 0;
}
-char *
+const char *
legacy_register_name (int i)
{
#ifdef REGISTER_NAMES
int
generic_prologue_frameless_p (CORE_ADDR ip)
{
-#ifdef SKIP_PROLOGUE_FRAMELESS_P
- return ip == SKIP_PROLOGUE_FRAMELESS_P (ip);
-#else
return ip == SKIP_PROLOGUE (ip);
-#endif
}
/* New/multi-arched targets should use the correct gdbarch field
#endif
switch (byte_order)
{
- case BIG_ENDIAN:
+ case BFD_ENDIAN_BIG:
return &floatformat_ieee_single_big;
case BFD_ENDIAN_LITTLE:
return &floatformat_ieee_single_little;
#endif
switch (byte_order)
{
- case BIG_ENDIAN:
+ case BFD_ENDIAN_BIG:
return &floatformat_ieee_double_big;
case BFD_ENDIAN_LITTLE:
return &floatformat_ieee_double_little;
return 0;
}
-int
-default_register_sim_regno (int num)
-{
- return num;
-}
-
-
CORE_ADDR
core_addr_identity (CORE_ADDR addr)
{
flush_cached_frames ();
registers_changed ();
stop_pc = wait_pc;
- select_frame (get_current_frame (), 0);
+ select_frame (get_current_frame ());
}
/* We return 1 to indicate that there is a breakpoint here,
so we need to step over it before continuing to avoid
prev->pc = read_pc ();
}
+void
+default_elf_make_msymbol_special (asymbol *sym, struct minimal_symbol *msym)
+{
+ return;
+}
+
+void
+default_coff_make_msymbol_special (int val, struct minimal_symbol *msym)
+{
+ return;
+}
+
int
cannot_register_not (int regnum)
{
*frame_offset = 0;
}
-/* Assume the world is flat. Every register is large enough to fit a
- target integer. */
+/* Assume the world is sane, every register's virtual and real size
+ is identical. */
+
+int
+generic_register_size (int regnum)
+{
+ gdb_assert (regnum >= 0 && regnum < NUM_REGS + NUM_PSEUDO_REGS);
+ return TYPE_LENGTH (REGISTER_VIRTUAL_TYPE (regnum));
+}
+
+#if !defined (IN_SIGTRAMP)
+#if defined (SIGTRAMP_START)
+#define IN_SIGTRAMP(pc, name) \
+ ((pc) >= SIGTRAMP_START(pc) \
+ && (pc) < SIGTRAMP_END(pc) \
+ )
+#else
+#define IN_SIGTRAMP(pc, name) \
+ (name && STREQ ("_sigtramp", name))
+#endif
+#endif
+
+/* Assume all registers are adjacent. */
int
-generic_register_raw_size (int regnum)
+generic_register_byte (int regnum)
{
+ int byte;
+ int i;
gdb_assert (regnum >= 0 && regnum < NUM_REGS + NUM_PSEUDO_REGS);
- return TARGET_INT_BIT / HOST_CHAR_BIT;
+ byte = 0;
+ for (i = 0; i < regnum; i++)
+ {
+ byte += TYPE_LENGTH (REGISTER_VIRTUAL_TYPE (i));
+ }
+ return byte;
}
-/* Assume the virtual size corresponds to the virtual type. */
+\f
+int
+legacy_pc_in_sigtramp (CORE_ADDR pc, char *name)
+{
+ return IN_SIGTRAMP(pc, name);
+}
int
-generic_register_virtual_size (int regnum)
+legacy_convert_register_p (int regnum)
{
- return TYPE_LENGTH (REGISTER_VIRTUAL_TYPE (regnum));
+ return REGISTER_CONVERTIBLE (regnum);
+}
+
+void
+legacy_register_to_value (int regnum, struct type *type,
+ char *from, char *to)
+{
+ REGISTER_CONVERT_TO_VIRTUAL (regnum, type, from, to);
+}
+
+void
+legacy_value_to_register (struct type *type, int regnum,
+ char *from, char *to)
+{
+ REGISTER_CONVERT_TO_RAW (type, regnum, from, to);
}
\f
/* Functions to manipulate the endianness of the target. */
-#ifdef TARGET_BYTE_ORDER_SELECTABLE
-/* compat - Catch old targets that expect a selectable byte-order to
- default to BIG_ENDIAN */
-#ifndef TARGET_BYTE_ORDER_DEFAULT
-#define TARGET_BYTE_ORDER_DEFAULT BIG_ENDIAN
-#endif
-#endif
-#if !TARGET_BYTE_ORDER_SELECTABLE_P
-#ifndef TARGET_BYTE_ORDER_DEFAULT
-/* compat - Catch old non byte-order selectable targets that do not
- define TARGET_BYTE_ORDER_DEFAULT and instead expect
- TARGET_BYTE_ORDER to be used as the default. For targets that
- defined neither TARGET_BYTE_ORDER nor TARGET_BYTE_ORDER_DEFAULT the
- below will get a strange compiler warning. */
-#define TARGET_BYTE_ORDER_DEFAULT TARGET_BYTE_ORDER
-#endif
-#endif
-#ifndef TARGET_BYTE_ORDER_DEFAULT
-#define TARGET_BYTE_ORDER_DEFAULT BIG_ENDIAN /* arbitrary */
-#endif
/* ``target_byte_order'' is only used when non- multi-arch.
- Multi-arch targets obtain the current byte order using
- TARGET_BYTE_ORDER which is controlled by gdbarch.*. */
-int target_byte_order = TARGET_BYTE_ORDER_DEFAULT;
+ Multi-arch targets obtain the current byte order using the
+ TARGET_BYTE_ORDER gdbarch method.
+
+ The choice of initial value is entirely arbitrary. During startup,
+ the function initialize_current_architecture() updates this value
+ based on default byte-order information extracted from BFD. */
+int target_byte_order = BFD_ENDIAN_BIG;
int target_byte_order_auto = 1;
static const char endian_big[] = "big";
{
if (TARGET_BYTE_ORDER_AUTO)
printf_unfiltered ("The target endianness is set automatically (currently %s endian)\n",
- (TARGET_BYTE_ORDER == BIG_ENDIAN ? "big" : "little"));
+ (TARGET_BYTE_ORDER == BFD_ENDIAN_BIG ? "big" : "little"));
else
printf_unfiltered ("The target is assumed to be %s endian\n",
- (TARGET_BYTE_ORDER == BIG_ENDIAN ? "big" : "little"));
+ (TARGET_BYTE_ORDER == BFD_ENDIAN_BIG ? "big" : "little"));
}
static void
set_endian (char *ignore_args, int from_tty, struct cmd_list_element *c)
{
- if (!TARGET_BYTE_ORDER_SELECTABLE_P)
- {
- printf_unfiltered ("Byte order is not selectable.");
- }
- else if (set_endian_string == endian_auto)
+ if (set_endian_string == endian_auto)
{
target_byte_order_auto = 1;
}
{
struct gdbarch_info info;
gdbarch_info_init (&info);
- info.byte_order = BIG_ENDIAN;
+ info.byte_order = BFD_ENDIAN_BIG;
if (! gdbarch_update_p (info))
{
printf_unfiltered ("Big endian target not supported by GDB\n");
}
else
{
- target_byte_order = BIG_ENDIAN;
+ target_byte_order = BFD_ENDIAN_BIG;
}
}
else
static void
set_endian_from_file (bfd *abfd)
{
+ int want;
if (GDB_MULTI_ARCH)
internal_error (__FILE__, __LINE__,
"set_endian_from_file: not for multi-arch");
- if (TARGET_BYTE_ORDER_SELECTABLE_P)
- {
- int want;
-
- if (bfd_big_endian (abfd))
- want = BIG_ENDIAN;
- else
- want = BFD_ENDIAN_LITTLE;
- if (TARGET_BYTE_ORDER_AUTO)
- target_byte_order = want;
- else if (TARGET_BYTE_ORDER != want)
- warning ("%s endian file does not match %s endian target.",
- want == BIG_ENDIAN ? "big" : "little",
- TARGET_BYTE_ORDER == BIG_ENDIAN ? "big" : "little");
- }
+ if (bfd_big_endian (abfd))
+ want = BFD_ENDIAN_BIG;
else
- {
- if (bfd_big_endian (abfd)
- ? TARGET_BYTE_ORDER != BIG_ENDIAN
- : TARGET_BYTE_ORDER == BIG_ENDIAN)
- warning ("%s endian file does not match %s endian target.",
- bfd_big_endian (abfd) ? "big" : "little",
- TARGET_BYTE_ORDER == BIG_ENDIAN ? "big" : "little");
- }
+ want = BFD_ENDIAN_LITTLE;
+ if (TARGET_BYTE_ORDER_AUTO)
+ target_byte_order = want;
+ else if (TARGET_BYTE_ORDER != want)
+ warning ("%s endian file does not match %s endian target.",
+ want == BFD_ENDIAN_BIG ? "big" : "little",
+ TARGET_BYTE_ORDER == BFD_ENDIAN_BIG ? "big" : "little");
}
"initialize_current_architecture: Arch not found");
}
- /* take several guesses at a byte order. */
- /* NB: can't use TARGET_BYTE_ORDER_DEFAULT as its definition is
- forced above. */
+ /* Take several guesses at a byte order. */
if (info.byte_order == BFD_ENDIAN_UNKNOWN
&& default_bfd_vec != NULL)
{
switch (default_bfd_vec->byteorder)
{
case BFD_ENDIAN_BIG:
- info.byte_order = BIG_ENDIAN;
+ info.byte_order = BFD_ENDIAN_BIG;
break;
case BFD_ENDIAN_LITTLE:
info.byte_order = BFD_ENDIAN_LITTLE;
if (info.byte_order == BFD_ENDIAN_UNKNOWN)
{
/* Wire it to big-endian!!! */
- info.byte_order = BIG_ENDIAN;
+ info.byte_order = BFD_ENDIAN_BIG;
}
if (GDB_MULTI_ARCH)
}
}
else
- initialize_non_multiarch ();
+ {
+ /* If the multi-arch logic comes up with a byte-order (from BFD)
+ use it for the non-multi-arch case. */
+ if (info.byte_order != BFD_ENDIAN_UNKNOWN)
+ target_byte_order = info.byte_order;
+ initialize_non_multiarch ();
+ }
/* Create the ``set architecture'' command appending ``auto'' to the
list of architectures. */
arches, &set_architecture_string,
"Set architecture of target.",
&setlist);
- c->function.sfunc = set_architecture;
+ set_cmd_sfunc (c, set_architecture);
add_alias_cmd ("processor", "architecture", class_support, 1, &setlist);
/* Don't use set_from_show - need to print both auto/manual and
current setting. */
endian_enum, &set_endian_string,
"Set endianness of target.",
&setlist);
- c->function.sfunc = set_endian;
+ set_cmd_sfunc (c, set_endian);
/* Don't use set_from_show - need to print both auto/manual and
current setting. */
add_cmd ("endian", class_support, show_endian,