X-Git-Url: http://git.efficios.com/?a=blobdiff_plain;f=gdb%2Fi386-linux-tdep.c;h=81c8d31c9b432bde0e942c60383366b902a29194;hb=72ee87972ebc7459e26d7d73fbacd7483dacacd5;hp=296a35dca73c015429b82b364926c36e83255deb;hpb=a9762ec78a53fbe9209fe1654db42df0cd328d50;p=deliverable%2Fbinutils-gdb.git diff --git a/gdb/i386-linux-tdep.c b/gdb/i386-linux-tdep.c index 296a35dca7..81c8d31c9b 100644 --- a/gdb/i386-linux-tdep.c +++ b/gdb/i386-linux-tdep.c @@ -1,6 +1,6 @@ /* Target-dependent code for GNU/Linux i386. - Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005, 2007 + Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005, 2007, 2008, 2009 Free Software Foundation, Inc. This file is part of GDB. @@ -34,17 +34,28 @@ #include "glibc-tdep.h" #include "solib-svr4.h" #include "symtab.h" +#include "arch-utils.h" +#include "regset.h" + +/* Supported register note sections. */ +static struct core_regset_section i386_linux_regset_sections[] = +{ + { ".reg", 144 }, + { ".reg2", 108 }, + { ".reg-xfp", 512 }, + { NULL, 0 } +}; /* Return the name of register REG. */ static const char * -i386_linux_register_name (int reg) +i386_linux_register_name (struct gdbarch *gdbarch, int reg) { /* Deal with the extra "orig_eax" pseudo register. */ if (reg == I386_LINUX_ORIG_EAX_REGNUM) return "orig_eax"; - return i386_register_name (reg); + return i386_register_name (gdbarch, reg); } /* Return non-zero, when the register is in the corresponding register @@ -115,13 +126,13 @@ static const gdb_byte linux_sigtramp_code[] = #define LINUX_SIGTRAMP_LEN (sizeof linux_sigtramp_code) -/* If NEXT_FRAME unwinds into a sigtramp routine, return the address - of the start of the routine. Otherwise, return 0. */ +/* If THIS_FRAME is a sigtramp routine, return the address of the + start of the routine. Otherwise, return 0. */ static CORE_ADDR -i386_linux_sigtramp_start (struct frame_info *next_frame) +i386_linux_sigtramp_start (struct frame_info *this_frame) { - CORE_ADDR pc = frame_pc_unwind (next_frame); + CORE_ADDR pc = get_frame_pc (this_frame); gdb_byte buf[LINUX_SIGTRAMP_LEN]; /* We only recognize a signal trampoline if PC is at the start of @@ -131,7 +142,7 @@ i386_linux_sigtramp_start (struct frame_info *next_frame) PC is not at the start of the instruction sequence, there will be a few trailing readable bytes on the stack. */ - if (!safe_frame_unwind_memory (next_frame, pc, buf, LINUX_SIGTRAMP_LEN)) + if (!safe_frame_unwind_memory (this_frame, pc, buf, LINUX_SIGTRAMP_LEN)) return 0; if (buf[0] != LINUX_SIGTRAMP_INSN0) @@ -152,7 +163,7 @@ i386_linux_sigtramp_start (struct frame_info *next_frame) pc -= adjust; - if (!safe_frame_unwind_memory (next_frame, pc, buf, LINUX_SIGTRAMP_LEN)) + if (!safe_frame_unwind_memory (this_frame, pc, buf, LINUX_SIGTRAMP_LEN)) return 0; } @@ -183,13 +194,13 @@ static const gdb_byte linux_rt_sigtramp_code[] = #define LINUX_RT_SIGTRAMP_LEN (sizeof linux_rt_sigtramp_code) -/* If NEXT_FRAME unwinds into an RT sigtramp routine, return the - address of the start of the routine. Otherwise, return 0. */ +/* If THIS_FRAME is an RT sigtramp routine, return the address of the + start of the routine. Otherwise, return 0. */ static CORE_ADDR -i386_linux_rt_sigtramp_start (struct frame_info *next_frame) +i386_linux_rt_sigtramp_start (struct frame_info *this_frame) { - CORE_ADDR pc = frame_pc_unwind (next_frame); + CORE_ADDR pc = get_frame_pc (this_frame); gdb_byte buf[LINUX_RT_SIGTRAMP_LEN]; /* We only recognize a signal trampoline if PC is at the start of @@ -199,7 +210,7 @@ i386_linux_rt_sigtramp_start (struct frame_info *next_frame) PC is not at the start of the instruction sequence, there will be a few trailing readable bytes on the stack. */ - if (!safe_frame_unwind_memory (next_frame, pc, buf, LINUX_RT_SIGTRAMP_LEN)) + if (!safe_frame_unwind_memory (this_frame, pc, buf, LINUX_RT_SIGTRAMP_LEN)) return 0; if (buf[0] != LINUX_RT_SIGTRAMP_INSN0) @@ -209,7 +220,7 @@ i386_linux_rt_sigtramp_start (struct frame_info *next_frame) pc -= LINUX_RT_SIGTRAMP_OFFSET1; - if (!safe_frame_unwind_memory (next_frame, pc, buf, + if (!safe_frame_unwind_memory (this_frame, pc, buf, LINUX_RT_SIGTRAMP_LEN)) return 0; } @@ -220,13 +231,13 @@ i386_linux_rt_sigtramp_start (struct frame_info *next_frame) return pc; } -/* Return whether the frame preceding NEXT_FRAME corresponds to a - GNU/Linux sigtramp routine. */ +/* Return whether THIS_FRAME corresponds to a GNU/Linux sigtramp + routine. */ static int -i386_linux_sigtramp_p (struct frame_info *next_frame) +i386_linux_sigtramp_p (struct frame_info *this_frame) { - CORE_ADDR pc = frame_pc_unwind (next_frame); + CORE_ADDR pc = get_frame_pc (this_frame); char *name; find_pc_partial_function (pc, &name, NULL, NULL); @@ -237,21 +248,21 @@ i386_linux_sigtramp_p (struct frame_info *next_frame) be part of the preceding function. This should always be sigaction, __sigaction, or __libc_sigaction (all aliases to the same function). */ if (name == NULL || strstr (name, "sigaction") != NULL) - return (i386_linux_sigtramp_start (next_frame) != 0 - || i386_linux_rt_sigtramp_start (next_frame) != 0); + return (i386_linux_sigtramp_start (this_frame) != 0 + || i386_linux_rt_sigtramp_start (this_frame) != 0); return (strcmp ("__restore", name) == 0 || strcmp ("__restore_rt", name) == 0); } -/* Return one if the unwound PC from NEXT_FRAME is in a signal trampoline - which may have DWARF-2 CFI. */ +/* Return one if the PC of THIS_FRAME is in a signal trampoline which + may have DWARF-2 CFI. */ static int i386_linux_dwarf_signal_frame_p (struct gdbarch *gdbarch, - struct frame_info *next_frame) + struct frame_info *this_frame) { - CORE_ADDR pc = frame_pc_unwind (next_frame); + CORE_ADDR pc = get_frame_pc (this_frame); char *name; find_pc_partial_function (pc, &name, NULL, NULL); @@ -268,20 +279,20 @@ i386_linux_dwarf_signal_frame_p (struct gdbarch *gdbarch, /* Offset to struct sigcontext in ucontext, from . */ #define I386_LINUX_UCONTEXT_SIGCONTEXT_OFFSET 20 -/* Assuming NEXT_FRAME is a frame following a GNU/Linux sigtramp - routine, return the address of the associated sigcontext structure. */ +/* Assuming THIS_FRAME is a GNU/Linux sigtramp routine, return the + address of the associated sigcontext structure. */ static CORE_ADDR -i386_linux_sigcontext_addr (struct frame_info *next_frame) +i386_linux_sigcontext_addr (struct frame_info *this_frame) { CORE_ADDR pc; CORE_ADDR sp; gdb_byte buf[4]; - frame_unwind_register (next_frame, I386_ESP_REGNUM, buf); + get_frame_register (this_frame, I386_ESP_REGNUM, buf); sp = extract_unsigned_integer (buf, 4); - pc = i386_linux_sigtramp_start (next_frame); + pc = i386_linux_sigtramp_start (this_frame); if (pc) { /* The sigcontext structure lives on the stack, right after @@ -290,12 +301,12 @@ i386_linux_sigcontext_addr (struct frame_info *next_frame) pointer. Keep in mind that the first instruction of the sigtramp code is "pop %eax". If the PC is after this instruction, adjust the returned value accordingly. */ - if (pc == frame_pc_unwind (next_frame)) + if (pc == get_frame_pc (this_frame)) return sp + 4; return sp; } - pc = i386_linux_rt_sigtramp_start (next_frame); + pc = i386_linux_rt_sigtramp_start (this_frame); if (pc) { CORE_ADDR ucontext_addr; @@ -429,6 +440,10 @@ i386_linux_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch) tdep->sc_reg_offset = i386_linux_sc_reg_offset; tdep->sc_num_regs = ARRAY_SIZE (i386_linux_sc_reg_offset); + /* N_FUN symbols in shared libaries have 0 for their values and need + to be relocated. */ + set_gdbarch_sofun_address_maybe_missing (gdbarch, 1); + /* GNU/Linux uses SVR4-style shared libraries. */ set_gdbarch_skip_trampoline_code (gdbarch, find_solib_trampoline_target); set_solib_svr4_fetch_link_map_offsets @@ -442,6 +457,18 @@ i386_linux_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch) /* Enable TLS support. */ set_gdbarch_fetch_tls_load_module_address (gdbarch, svr4_fetch_objfile_link_map); + + /* Install supported register note sections. */ + set_gdbarch_core_regset_sections (gdbarch, i386_linux_regset_sections); + + /* Displaced stepping. */ + set_gdbarch_displaced_step_copy_insn (gdbarch, + simple_displaced_step_copy_insn); + set_gdbarch_displaced_step_fixup (gdbarch, i386_displaced_step_fixup); + set_gdbarch_displaced_step_free_closure (gdbarch, + simple_displaced_step_free_closure); + set_gdbarch_displaced_step_location (gdbarch, + displaced_step_at_entry_point); } /* Provide a prototype to silence -Wmissing-prototypes. */