X-Git-Url: http://drtracing.org/?a=blobdiff_plain;f=gdb%2Fia64-linux-tdep.c;h=128924e102ce0d88fb9544e3f57b65a01bda7e59;hb=9f1b45b0da430a7a7abf9e54acbe6f2ef9d3a763;hp=10de3ddf39f95ab59fd0ae0bc9058e624007bdfe;hpb=01f0fe5e0450edf168c1f612feb93cf588e4e7ea;p=deliverable%2Fbinutils-gdb.git diff --git a/gdb/ia64-linux-tdep.c b/gdb/ia64-linux-tdep.c index 10de3ddf39..128924e102 100644 --- a/gdb/ia64-linux-tdep.c +++ b/gdb/ia64-linux-tdep.c @@ -1,12 +1,12 @@ /* Target-dependent code for the IA-64 for GDB, the GNU debugger. - Copyright (C) 2000, 2004, 2005 Free Software Foundation, Inc. + Copyright (C) 2000-2014 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,9 +15,7 @@ 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 . */ #include "defs.h" #include "ia64-tdep.h" @@ -26,38 +24,45 @@ #include "regcache.h" #include "osabi.h" #include "solib-svr4.h" +#include "symtab.h" +#include "linux-tdep.h" + +#include /* The sigtramp code is in a non-readable (executable-only) region of memory called the ``gate page''. The addresses in question were determined by examining the system headers. They are - overly generous to allow for different pages sizes. */ + overly generous to allow for different pages sizes. */ #define GATE_AREA_START 0xa000000000000100LL #define GATE_AREA_END 0xa000000000020000LL -/* Offset to sigcontext structure from frame of handler */ +/* 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); } /* IA-64 GNU/Linux specific function which, given a frame address and a register number, returns the address at which that register may be - found. 0 is returned for registers which aren't stored in the the - sigcontext structure. */ + found. 0 is returned for registers which aren't stored in the + sigcontext structure. */ static CORE_ADDR -ia64_linux_sigcontext_register_address (CORE_ADDR sp, int regno) +ia64_linux_sigcontext_register_address (struct gdbarch *gdbarch, + CORE_ADDR sp, int regno) { - char buf[8]; + enum bfd_endian byte_order = gdbarch_byte_order (gdbarch); + gdb_byte buf[8]; CORE_ADDR sigcontext_addr = 0; - /* The address of the sigcontext area is found at offset 16 in the sigframe. */ + /* The address of the sigcontext area is found at offset 16 in the + sigframe. */ read_memory (sp + 16, buf, 8); - sigcontext_addr = extract_unsigned_integer (buf, 8); + sigcontext_addr = extract_unsigned_integer (buf, 8, byte_order); if (IA64_GR0_REGNUM <= regno && regno <= IA64_GR31_REGNUM) return sigcontext_addr + 200 + 8 * (regno - IA64_GR0_REGNUM); @@ -76,7 +81,7 @@ ia64_linux_sigcontext_register_address (CORE_ADDR sp, int regno) return sigcontext_addr + 56; /* user mask only */ /* sc_ar_rsc is provided, from which we could compute bspstore, but I don't think it's worth it. Anyway, if we want it, it's at offset - 64 */ + 64. */ case IA64_BSP_REGNUM : return sigcontext_addr + 72; case IA64_RNAT_REGNUM : @@ -99,9 +104,9 @@ ia64_linux_sigcontext_register_address (CORE_ADDR sp, int regno) } static void -ia64_linux_write_pc (CORE_ADDR pc, ptid_t ptid) +ia64_linux_write_pc (struct regcache *regcache, CORE_ADDR pc) { - ia64_write_pc (pc, ptid); + 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 @@ -112,25 +117,64 @@ ia64_linux_write_pc (CORE_ADDR pc, ptid_t ptid) The clearing of r10 is safe as long as ia64_write_pc() is only called as part of setting up an inferior call. */ - write_register_pid (IA64_GR10_REGNUM, 0, ptid); + regcache_cooked_write_unsigned (regcache, IA64_GR10_REGNUM, 0); +} + +/* Implementation of `gdbarch_stap_is_single_operand', as defined in + gdbarch.h. */ + +static int +ia64_linux_stap_is_single_operand (struct gdbarch *gdbarch, const char *s) +{ + return ((isdigit (*s) && s[1] == '[' && s[2] == 'r') /* Displacement. */ + || *s == 'r' /* Register value. */ + || isdigit (*s)); /* Literal number. */ } static void ia64_linux_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch) { struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch); + static const char *const stap_register_prefixes[] = { "r", NULL }; + static const char *const stap_register_indirection_prefixes[] = { "[", + NULL }; + static const char *const stap_register_indirection_suffixes[] = { "]", + NULL }; + + linux_init_abi (info, 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); + + /* SystemTap related. */ + set_gdbarch_stap_register_prefixes (gdbarch, stap_register_prefixes); + set_gdbarch_stap_register_indirection_prefixes (gdbarch, + stap_register_indirection_prefixes); + set_gdbarch_stap_register_indirection_suffixes (gdbarch, + stap_register_indirection_suffixes); + set_gdbarch_stap_gdb_register_prefix (gdbarch, "r"); + set_gdbarch_stap_is_single_operand (gdbarch, + ia64_linux_stap_is_single_operand); } +/* Provide a prototype to silence -Wmissing-prototypes. */ +extern initialize_file_ftype _initialize_ia64_linux_tdep; + void _initialize_ia64_linux_tdep (void) {