X-Git-Url: http://drtracing.org/?a=blobdiff_plain;f=gdb%2Fia64-linux-tdep.c;h=49d5b721ad59f0ceab16c82d3277bf9f3e041748;hb=5a7c5e86304d6298cbeee81f07b626b194980073;hp=12f0c18c112777edd448a5f781517a722a72f031;hpb=9fc9f5e2ecd67988f90cc897ea1b62ad909aa5bd;p=deliverable%2Fbinutils-gdb.git diff --git a/gdb/ia64-linux-tdep.c b/gdb/ia64-linux-tdep.c index 12f0c18c11..49d5b721ad 100644 --- a/gdb/ia64-linux-tdep.c +++ b/gdb/ia64-linux-tdep.c @@ -1,12 +1,13 @@ /* Target-dependent code for the IA-64 for GDB, the GNU debugger. - Copyright 2000, 2004 Free Software Foundation, Inc. + Copyright (C) 2000, 2004, 2005, 2007, 2008, 2009 + 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, @@ -15,14 +16,16 @@ 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., 59 Temple Place - Suite 330, - Boston, MA 02111-1307, USA. */ + along with this program. If not, see . */ #include "defs.h" #include "ia64-tdep.h" #include "arch-utils.h" #include "gdbcore.h" +#include "regcache.h" +#include "osabi.h" +#include "solib-svr4.h" +#include "symtab.h" /* The sigtramp code is in a non-readable (executable-only) region of memory called the ``gate page''. The addresses in question @@ -35,8 +38,8 @@ /* Offset to sigcontext structure from frame of handler */ #define IA64_LINUX_SIGCONTEXT_OFFSET 192 -int -ia64_linux_in_sigtramp (CORE_ADDR pc, char *func_name) +static int +ia64_linux_pc_in_sigtramp (CORE_ADDR pc) { return (pc >= (CORE_ADDR) GATE_AREA_START && pc < (CORE_ADDR) GATE_AREA_END); } @@ -46,7 +49,7 @@ ia64_linux_in_sigtramp (CORE_ADDR pc, char *func_name) found. 0 is returned for registers which aren't stored in the the sigcontext structure. */ -CORE_ADDR +static CORE_ADDR ia64_linux_sigcontext_register_address (CORE_ADDR sp, int regno) { char buf[8]; @@ -94,3 +97,51 @@ ia64_linux_sigcontext_register_address (CORE_ADDR sp, int regno) return 0; } } + +static void +ia64_linux_write_pc (struct regcache *regcache, CORE_ADDR pc) +{ + ia64_write_pc (regcache, pc); + + /* We must be careful with modifying the instruction-pointer: if we + just interrupt a system call, the kernel would ordinarily try to + restart it when we resume the inferior, which typically results + in SIGSEGV or SIGILL. We prevent this by clearing r10, which + will tell the kernel that r8 does NOT contain a valid error code + and hence it will skip system-call restart. + + The clearing of r10 is safe as long as ia64_write_pc() is only + called as part of setting up an inferior call. */ + regcache_cooked_write_unsigned (regcache, IA64_GR10_REGNUM, 0); +} + +static void +ia64_linux_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch) +{ + struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch); + + /* Set the method of obtaining the sigcontext addresses at which + registers are saved. */ + tdep->sigcontext_register_address = ia64_linux_sigcontext_register_address; + + /* Set the pc_in_sigtramp method. */ + tdep->pc_in_sigtramp = ia64_linux_pc_in_sigtramp; + + set_gdbarch_write_pc (gdbarch, ia64_linux_write_pc); + + set_gdbarch_skip_trampoline_code (gdbarch, find_solib_trampoline_target); + + set_solib_svr4_fetch_link_map_offsets + (gdbarch, svr4_lp64_fetch_link_map_offsets); + + /* Enable TLS support. */ + set_gdbarch_fetch_tls_load_module_address (gdbarch, + svr4_fetch_objfile_link_map); +} + +void +_initialize_ia64_linux_tdep (void) +{ + gdbarch_register_osabi (bfd_arch_ia64, 0, GDB_OSABI_LINUX, + ia64_linux_init_abi); +}