2009-07-01 Tristan Gingold <gingold@adacore.com>
[deliverable/binutils-gdb.git] / gdb / arm-wince-tdep.c
index 7ec5b15d0f513a2a76de1817fa3434753b37cbeb..ad34fb25c71ff859b30d4af41bd5ee35ce8c75b2 100644 (file)
@@ -1,13 +1,13 @@
 /* Target-dependent code for Windows CE running on ARM processors,
    for GDB.
 
-   Copyright (C) 2007 Free Software Foundation, Inc.
+   Copyright (C) 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,
    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 "osabi.h"
-#include "solib-svr4.h"
+#include "gdbcore.h"
 #include "target.h"
+#include "solib.h"
+#include "solib-target.h"
 
 #include "gdb_string.h"
 
@@ -34,7 +34,45 @@ static const char arm_wince_thumb_le_breakpoint[] = { 0xfe, 0xdf };
 
 /* Description of the longjmp buffer.  */
 #define ARM_WINCE_JB_ELEMENT_SIZE      INT_REGISTER_SIZE
-#define ARM_WINCE_JB_PC                        21
+#define ARM_WINCE_JB_PC                        10
+
+static CORE_ADDR
+arm_pe_skip_trampoline_code (struct frame_info *frame, CORE_ADDR pc)
+{
+  ULONGEST indirect;
+  struct minimal_symbol *indsym;
+  char *symname;
+  CORE_ADDR next_pc;
+
+  /* The format of an ARM DLL trampoline is:
+       ldr  ip, [pc]
+       ldr  pc, [ip]
+       .dw __imp_<func>  */
+
+  if (pc == 0
+      || read_memory_unsigned_integer (pc + 0, 4) != 0xe59fc000
+      || read_memory_unsigned_integer (pc + 4, 4) != 0xe59cf000)
+    return 0;
+
+  indirect = read_memory_unsigned_integer (pc + 8, 4);
+  if (indirect == 0)
+    return 0;
+
+  indsym = lookup_minimal_symbol_by_pc (indirect);
+  if (indsym == NULL)
+    return 0;
+
+  symname = SYMBOL_LINKAGE_NAME (indsym);
+  if (symname == NULL || strncmp (symname, "__imp_", 6) != 0)
+    return 0;
+
+  next_pc = read_memory_unsigned_integer (indirect, 4);
+  if (next_pc != 0)
+    return next_pc;
+
+  /* Check with the default arm gdbarch_skip_trampoline.  */
+  return arm_skip_stub (frame, pc);
+}
 
 static void
 arm_wince_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch)
@@ -56,7 +94,8 @@ arm_wince_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch)
   set_gdbarch_char_signed (gdbarch, 1);
 
   /* Shared library handling.  */
-  set_gdbarch_skip_trampoline_code (gdbarch, find_solib_trampoline_target);
+  set_solib_ops (gdbarch, &solib_target_so_ops);
+  set_gdbarch_skip_trampoline_code (gdbarch, arm_pe_skip_trampoline_code);
 
   /* Single stepping.  */
   set_gdbarch_software_single_step (gdbarch, arm_software_single_step);
This page took 0.0247 seconds and 4 git commands to generate.