/* Motorola m68k target-dependent support for GNU/Linux.
- Copyright (C) 1996, 1998, 2000, 2001, 2002, 2003, 2004, 2007
- Free Software Foundation, Inc.
+ Copyright (C) 1996, 1998, 2000, 2001, 2002, 2003, 2004, 2007, 2008, 2009,
+ 2010 Free Software Foundation, Inc.
This file is part of GDB.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
+ the Free Software Foundation; either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
GNU General Public License for more details.
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., 51 Franklin Street, Fifth Floor,
- Boston, MA 02110-1301, USA. */
+ along with this program. If not, see <http://www.gnu.org/licenses/>. */
#include "defs.h"
#include "gdbcore.h"
/* moveq #82,d0; notb d0; trap #0 */ \
|| (insn1 == 0x70524600 && (insn2 >> 16) == 0x4e40))
-/* Return non-zero if PC points into the signal trampoline. For the
- sake of m68k_linux_get_sigtramp_info we also distinguish between
+/* Return non-zero if THIS_FRAME corresponds to a signal trampoline. For
+ the sake of m68k_linux_get_sigtramp_info we also distinguish between
non-RT and RT signal trampolines. */
static int
-m68k_linux_pc_in_sigtramp (CORE_ADDR pc, char *name)
+m68k_linux_pc_in_sigtramp (struct frame_info *this_frame)
{
+ struct gdbarch *gdbarch = get_frame_arch (this_frame);
+ enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
CORE_ADDR sp;
- char buf[12];
+ gdb_byte buf[12];
unsigned long insn0, insn1, insn2;
+ CORE_ADDR pc = get_frame_pc (this_frame);
- if (read_memory_nobpt (pc - 4, buf, sizeof (buf)))
+ if (!safe_frame_unwind_memory (this_frame, pc - 4, buf, sizeof (buf)))
return 0;
- insn1 = extract_unsigned_integer (buf + 4, 4);
- insn2 = extract_unsigned_integer (buf + 8, 4);
+ insn1 = extract_unsigned_integer (buf + 4, 4, byte_order);
+ insn2 = extract_unsigned_integer (buf + 8, 4, byte_order);
if (IS_SIGTRAMP (insn1, insn2))
return 1;
if (IS_RT_SIGTRAMP (insn1, insn2))
return 2;
- insn0 = extract_unsigned_integer (buf, 4);
+ insn0 = extract_unsigned_integer (buf, 4, byte_order);
if (IS_SIGTRAMP (insn0, insn1))
return 1;
if (IS_RT_SIGTRAMP (insn0, insn1))
static void
m68k_linux_inferior_created (struct target_ops *objfile, int from_tty)
{
- /* Record that we will need to re-evaluate whether we are running on
- a uClinux or normal Linux target (see m68k_linux_get_sigtramp_info). */
+ /* Record that we will need to re-evaluate whether we are running on a
+ uClinux or normal GNU/Linux target (see m68k_linux_get_sigtramp_info). */
target_is_uclinux = -1;
}
static struct m68k_linux_sigtramp_info
-m68k_linux_get_sigtramp_info (struct frame_info *next_frame)
+m68k_linux_get_sigtramp_info (struct frame_info *this_frame)
{
+ struct gdbarch *gdbarch = get_frame_arch (this_frame);
+ enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
CORE_ADDR sp;
- char buf[4];
struct m68k_linux_sigtramp_info info;
if (target_is_uclinux == -1)
{
- /* Determine whether we are running on a uClinux or normal Linux
+ /* Determine whether we are running on a uClinux or normal GNU/Linux
target so we can use the correct sigcontext layouts. */
-
CORE_ADDR dummy;
-
+
target_is_uclinux
- = target_auxv_search (¤t_target, AT_NULL, &dummy) > 0
- && target_auxv_search (¤t_target, AT_PAGESZ, &dummy) == 0;
+ = (target_auxv_search (¤t_target, AT_NULL, &dummy) > 0
+ && target_auxv_search (¤t_target, AT_PAGESZ, &dummy) == 0);
}
- frame_unwind_register (next_frame, M68K_SP_REGNUM, buf);
- sp = extract_unsigned_integer (buf, 4);
+ sp = get_frame_register_unsigned (this_frame, M68K_SP_REGNUM);
/* Get sigcontext address, it is the third parameter on the stack. */
- info.sigcontext_addr = read_memory_unsigned_integer (sp + 8, 4);
+ info.sigcontext_addr = read_memory_unsigned_integer (sp + 8, 4, byte_order);
- if (m68k_linux_pc_in_sigtramp (frame_pc_unwind (next_frame), 0) == 2)
+ if (m68k_linux_pc_in_sigtramp (this_frame) == 2)
info.sc_reg_offset = m68k_linux_ucontext_reg_offset;
else
- info.sc_reg_offset
- = target_is_uclinux ? m68k_uclinux_sigcontext_reg_offset
- : m68k_linux_sigcontext_reg_offset;
+ info.sc_reg_offset = (target_is_uclinux
+ ? m68k_uclinux_sigcontext_reg_offset
+ : m68k_linux_sigcontext_reg_offset);
return info;
}
/* Signal trampolines. */
static struct trad_frame_cache *
-m68k_linux_sigtramp_frame_cache (struct frame_info *next_frame,
+m68k_linux_sigtramp_frame_cache (struct frame_info *this_frame,
void **this_cache)
{
struct frame_id this_id;
struct trad_frame_cache *cache;
- struct gdbarch_tdep *tdep = gdbarch_tdep (current_gdbarch);
+ struct gdbarch *gdbarch = get_frame_arch (this_frame);
+ struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
+ enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
struct m68k_linux_sigtramp_info info;
- char buf[4];
+ gdb_byte buf[4];
int i;
if (*this_cache)
return *this_cache;
- cache = trad_frame_cache_zalloc (next_frame);
+ cache = trad_frame_cache_zalloc (this_frame);
/* FIXME: cagney/2004-05-01: This is is long standing broken code.
The frame ID's code address should be the start-address of the
signal trampoline and not the current PC within that
trampoline. */
- frame_unwind_register (next_frame, M68K_SP_REGNUM, buf);
+ get_frame_register (this_frame, M68K_SP_REGNUM, buf);
/* See the end of m68k_push_dummy_call. */
- this_id = frame_id_build (extract_unsigned_integer (buf, 4) - 4 + 8,
- frame_pc_unwind (next_frame));
+ this_id = frame_id_build (extract_unsigned_integer (buf, 4, byte_order)
+ - 4 + 8, get_frame_pc (this_frame));
trad_frame_set_id (cache, this_id);
- info = m68k_linux_get_sigtramp_info (next_frame);
+ info = m68k_linux_get_sigtramp_info (this_frame);
for (i = 0; i < M68K_NUM_REGS; i++)
if (info.sc_reg_offset[i] != -1)
}
static void
-m68k_linux_sigtramp_frame_this_id (struct frame_info *next_frame,
+m68k_linux_sigtramp_frame_this_id (struct frame_info *this_frame,
void **this_cache,
struct frame_id *this_id)
{
struct trad_frame_cache *cache =
- m68k_linux_sigtramp_frame_cache (next_frame, this_cache);
+ m68k_linux_sigtramp_frame_cache (this_frame, this_cache);
trad_frame_get_id (cache, this_id);
}
-static void
-m68k_linux_sigtramp_frame_prev_register (struct frame_info *next_frame,
+static struct value *
+m68k_linux_sigtramp_frame_prev_register (struct frame_info *this_frame,
void **this_cache,
- int regnum, int *optimizedp,
- enum lval_type *lvalp,
- CORE_ADDR *addrp,
- int *realnump, gdb_byte *valuep)
+ int regnum)
{
/* Make sure we've initialized the cache. */
struct trad_frame_cache *cache =
- m68k_linux_sigtramp_frame_cache (next_frame, this_cache);
- trad_frame_get_register (cache, next_frame, regnum, optimizedp, lvalp,
- addrp, realnump, valuep);
+ m68k_linux_sigtramp_frame_cache (this_frame, this_cache);
+ return trad_frame_get_register (cache, this_frame, regnum);
+}
+
+static int
+m68k_linux_sigtramp_frame_sniffer (const struct frame_unwind *self,
+ struct frame_info *this_frame,
+ void **this_prologue_cache)
+{
+ return m68k_linux_pc_in_sigtramp (this_frame);
}
static const struct frame_unwind m68k_linux_sigtramp_frame_unwind =
{
SIGTRAMP_FRAME,
m68k_linux_sigtramp_frame_this_id,
- m68k_linux_sigtramp_frame_prev_register
+ m68k_linux_sigtramp_frame_prev_register,
+ NULL,
+ m68k_linux_sigtramp_frame_sniffer
};
-static const struct frame_unwind *
-m68k_linux_sigtramp_frame_sniffer (struct frame_info *next_frame)
-{
- CORE_ADDR pc = frame_pc_unwind (next_frame);
- char *name;
-
- find_pc_partial_function (pc, &name, NULL, NULL);
- if (m68k_linux_pc_in_sigtramp (pc, name))
- return &m68k_linux_sigtramp_frame_unwind;
-
- return NULL;
-}
-
static void
m68k_linux_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch)
{
set_gdbarch_decr_pc_after_break (gdbarch, 2);
- frame_unwind_append_sniffer (gdbarch, m68k_linux_sigtramp_frame_sniffer);
+ frame_unwind_append_unwinder (gdbarch, &m68k_linux_sigtramp_frame_unwind);
/* Shared library handling. */
svr4_fetch_objfile_link_map);
}
+/* Provide a prototype to silence -Wmissing-prototypes. */
+extern initialize_file_ftype _initialize_m68k_linux_tdep;
+
void
_initialize_m68k_linux_tdep (void)
{