This is the mail archive of the gdb-patches@sources.redhat.com mailing list for the GDB project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

kgdb support for gdb


Hi,

Attached patches add kgdb support to gdb. They define two new targets i386-lk 
and x86_64-lk. Because of the definition of these targets, one can build a 
gdb with does not contain the linux operating environment specific things 
which are inappropriate for the kernel, like signal trampoline frame parsing.

Linux operating environment specific things create problems while debugging 
the kernel. e.g. On ppc processors modules are loaded above the kernel stack. 
This causes gdb to think that it's executing a code in the stack and it 
interprets it as a signal handler.

These patches have been tested on i386 kgdb and found to work as expected. The 
x86_64 support is still being fixed.

I have written a short description for both these patches below.

Could the gdb gurus please look at these patches and let me know whether they 
are appropriate for inclusion in mainline gdb? Any feedback/comments are most 
welcome.

Thanks.
-Amit


lk.patch: This patch adds basic support for targets i386-lk and x86_64-lk. 
Lets a user connect to a kgdb kernel. 

It increases the minimum value of the size of remote_patcket_size from 399 to 
1023 since kgdb packets can potentially send that packets that long.


context.patch: This patch defines a frame CONTEXT_FRAME. This frame is used to 
represent the context switch in a kernel. A context frame appears very much 
like an inline function. It convers the switch_to code and reports the 
previous frame to begin at the place where switch_to ends (inside schedule). 
It also makes adjustments for PC and SP since PC and SP are modified inside 
switch_to code before the control goes to schedule. Without this support gdb 
has real problems when showing a backtrace that begins from switch_to.

This patch also suppresses printing of CONTEXT_FRAMES and frames that contain 
scheduling functions in info threads listing. This is very similar to 
reporting of the WCHAN field in ps output, where scheduling functions are not 
reported. This supressing doesn't apply to backtrace command, so that full 
backtrace can be obtained by switching to a thread.

Suppressing of scheduling frames should be useful for multithread applications 
too. I have seen threads sleeping in libc_nanosleep too many times in the 
info threads output. We can tweak this code so that info threads listing 
shows the caller of libc_nanosleep.
Index: src/config.sub
===================================================================
--- src.orig/config.sub	2004-09-04 13:23:53.000000000 +0530
+++ src/config.sub	2004-10-01 12:58:49.000000000 +0530
@@ -1297,6 +1297,9 @@
 	-kaos*)
 		os=-kaos
 		;;
+	-lk*)
+		os=-lk
+		;;
 	-none)
 		;;
 	*)
Index: src/bfd/config.bfd
===================================================================
--- src.orig/bfd/config.bfd	2004-09-03 22:45:31.000000000 +0530
+++ src/bfd/config.bfd	2004-10-01 12:58:49.000000000 +0530
@@ -521,6 +521,11 @@
     targ_selvecs="i386linux_vec bfd_efi_app_ia32_vec"
     targ64_selvecs=bfd_elf64_x86_64_vec
     ;;
+  i[3-7]86-*-lk*)
+    targ_defvec=bfd_elf32_i386_vec
+    targ_selvecs="i386linux_vec bfd_efi_app_ia32_vec"
+    targ64_selvecs=bfd_elf64_x86_64_vec
+    ;;
 #ifdef BFD64
   x86_64-*-freebsd* | x86_64-*-kfreebsd*-gnu)
     targ_defvec=bfd_elf64_x86_64_vec
@@ -534,6 +539,10 @@
     targ_defvec=bfd_elf64_x86_64_vec
     targ_selvecs="bfd_elf32_i386_vec i386linux_vec bfd_efi_app_ia32_vec"
     ;;
+  x86_64-*-lk*)
+    targ_defvec=bfd_elf64_x86_64_vec
+    targ_selvecs="bfd_elf32_i386_vec i386linux_vec bfd_efi_app_ia32_vec"
+    ;;
 #endif
   i[3-7]86-*-lynxos*)
     targ_defvec=bfd_elf32_i386_vec
Index: src/gdb/configure.tgt
===================================================================
--- src.orig/gdb/configure.tgt	2004-09-29 02:09:17.000000000 +0530
+++ src/gdb/configure.tgt	2004-10-01 12:59:23.000000000 +0530
@@ -93,6 +93,7 @@
 i[34567]86-*-linux*)	gdb_target=linux
 			build_gdbserver=yes
 			;;
+i[34567]86-*-lk*)	gdb_target=lk ;;
 i[34567]86-*-gnu*)	gdb_target=i386gnu ;;
 i[34567]86-*-netware*)	gdb_target=i386
 			configdirs="${configdirs} nlm" ;;
@@ -212,6 +213,7 @@
 			* ) ;;
 			esac
 			;;
+x86_64-*-lk*)		gdb_target=x86-64lk ;;
 
 x86_64-*-linux*)	gdb_target=linux64
 			build_gdbserver=yes
@@ -232,4 +234,5 @@
 *-*-solaris*)	gdb_osabi=GDB_OSABI_SOLARIS ;;
 *-*-*-gnu*)	;; # prevent non-GNU kernels to match the Hurd rule below
 *-*-gnu*)	gdb_osabi=GDB_OSABI_HURD ;;
+*-*-lk*)	gdb_osabi=GDB_OSABI_LK ;;
 esac
Index: src/gdb/defs.h
===================================================================
--- src.orig/gdb/defs.h	2004-10-01 01:27:54.000000000 +0530
+++ src/gdb/defs.h	2004-10-01 12:58:49.000000000 +0530
@@ -1046,6 +1046,8 @@
 
   GDB_OSABI_CYGWIN,
 
+  GDB_OSABI_LK,
+
   GDB_OSABI_INVALID		/* keep this last */
 };
 
Index: src/gdb/osabi.c
===================================================================
--- src.orig/gdb/osabi.c	2004-07-03 02:57:17.000000000 +0530
+++ src/gdb/osabi.c	2004-10-01 12:58:49.000000000 +0530
@@ -78,6 +78,8 @@
 
   "Cygwin",
 
+  "Linux kernel",
+
   "<invalid>"
 };
 
Index: src/gdb/config/i386/lk.mt
===================================================================
--- src.orig/gdb/config/i386/lk.mt	2003-01-30 15:54:37.000000000 +0530
+++ src/gdb/config/i386/lk.mt	2004-10-01 12:58:49.000000000 +0530
@@ -0,0 +1,3 @@
+# Target: Intel i386 running Linux kernel
+TDEPFILES = i386-tdep.o i386-lk-tdep.o i387-tdep.o
+TM_FILE= tm-lk.h
Index: src/gdb/config/i386/tm-lk.h
===================================================================
--- src.orig/gdb/config/i386/tm-lk.h	2003-01-30 15:54:37.000000000 +0530
+++ src/gdb/config/i386/tm-lk.h	2004-10-01 12:58:49.000000000 +0530
@@ -0,0 +1,6 @@
+#ifndef TM_LK_H
+#define TM_LK_H
+
+#include "config/tm-lk.h"
+
+#endif /* #ifndef TM_LK_H */
Index: src/gdb/config/i386/tm-x86-64lk.h
===================================================================
--- src.orig/gdb/config/i386/tm-x86-64lk.h	2003-01-30 15:54:37.000000000 +0530
+++ src/gdb/config/i386/tm-x86-64lk.h	2004-10-01 12:58:49.000000000 +0530
@@ -0,0 +1,25 @@
+/* Definitions to target GDB to Linux Kernel on x86-64.
+
+   Copyright 2004 LinSysSoft Technologies Pvt. Ltd.
+
+   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
+   (at your option) any later version.
+
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   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.  */
+
+#ifndef TM_X86_64LK_H
+#define TM_X86_64LK_H
+
+/* Nothing as yet */
+
+#endif /* #ifndef TM_X86_64LK_H */
Index: src/gdb/config/i386/x86-64lk.mt
===================================================================
--- src.orig/gdb/config/i386/x86-64lk.mt	2003-01-30 15:54:37.000000000 +0530
+++ src/gdb/config/i386/x86-64lk.mt	2004-10-01 12:58:49.000000000 +0530
@@ -0,0 +1,7 @@
+# Target: AMD x86-64 running Linux Kernel
+TDEPFILES= x86-64-tdep.o x86-64-lk-tdep.o \
+	i386-tdep.o i387-tdep.o i386-lk-tdep.o
+
+GDB_MULTI_ARCH=GDB_MULTI_ARCH_TM
+
+TM_FILE=tm-x86-64lk.h
Index: src/gdb/config/tm-lk.h
===================================================================
--- src.orig/gdb/config/tm-lk.h	2003-01-30 15:54:37.000000000 +0530
+++ src/gdb/config/tm-lk.h	2004-10-01 12:58:49.000000000 +0530
@@ -0,0 +1,19 @@
+/* Native support for Linux kernel, for GDB, the GNU debugger.
+   Copyright 2004 LinSysSoft Technologies Pvt. Ltd.
+
+   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
+   (at your option) any later version.
+
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   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.  */
+
+/* Nothing */
Index: src/gdb/i386-lk-tdep.c
===================================================================
--- src.orig/gdb/i386-lk-tdep.c	2003-01-30 15:54:37.000000000 +0530
+++ src/gdb/i386-lk-tdep.c	2004-10-01 12:58:49.000000000 +0530
@@ -0,0 +1,49 @@
+/* Target-dependent code for Linux kernel running on i386's, for GDB.
+
+   Copyright 2004 LinSysSoft Technologies Pvt. Ltd.
+
+   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
+   (at your option) any later version.
+
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   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.  */
+  
+#include "defs.h"
+
+#include "osabi.h"
+
+#include "i386-tdep.h"
+#include "i386-linux-tdep.h"
+
+static void
+i386_lk_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch)
+{
+  struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
+
+  /* Linux kernel has an elf vmlinux file and uses elf format modules. */
+  i386_elf_init_abi (info, gdbarch);
+
+  set_gdbarch_num_regs (gdbarch, I386_NUM_GREGS);
+  set_gdbarch_register_name (gdbarch, i386_register_name);
+  set_gdbarch_register_reggroup_p (gdbarch, i386_register_reggroup_p);
+
+  tdep->jb_pc_offset = 20;	/* From <bits/setjmp.h>.  */
+}
+
+/* Provide a prototype to silence -Wmissing-prototypes.  */
+extern void _initialize_i386_lk_tdep (void);
+
+void
+_initialize_i386_lk_tdep (void)
+{
+  gdbarch_register_osabi (bfd_arch_i386, 0, GDB_OSABI_LK, i386_lk_init_abi);
+}
Index: src/gdb/x86-64-lk-tdep.c
===================================================================
--- src.orig/gdb/x86-64-lk-tdep.c	2003-01-30 15:54:37.000000000 +0530
+++ src/gdb/x86-64-lk-tdep.c	2004-10-01 12:58:49.000000000 +0530
@@ -0,0 +1,43 @@
+/* Target-dependent code for Linux kernel running on x86_64's, for GDB.
+
+   Copyright 2004 LinSysSoft Technologies Pvt. Ltd.
+
+   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
+   (at your option) any later version.
+
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   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.  */
+
+#include "defs.h"
+
+#include "osabi.h"
+
+#include "x86-64-tdep.h"
+#include "x86-64-linux-tdep.h"
+
+
+static void
+x86_64_lk_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch)
+{
+  struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
+  x86_64_init_abi (info, gdbarch);
+}
+  
+/* Provide a prototype to silence -Wmissing-prototypes.  */
+extern void _initialize_x86_64_lk_tdep (void);
+
+void
+_initialize_x86_64_lk_tdep (void)
+{
+  gdbarch_register_osabi (bfd_arch_i386, bfd_mach_x86_64, GDB_OSABI_LK,
+			  x86_64_lk_init_abi);
+}
Index: src/gdb/remote.c
===================================================================
--- src.orig/gdb/remote.c	2004-09-25 01:21:18.000000000 +0530
+++ src/gdb/remote.c	2004-10-01 12:58:49.000000000 +0530
@@ -271,12 +271,13 @@
 
   /* Default maximum number of characters in a packet body. Many
      remote stubs have a hardwired buffer size of 400 bytes
-     (c.f. BUFMAX in m68k-stub.c and i386-stub.c).  BUFMAX-1 is used
+     (c.f. BUFMAX in m68k-stub.c and i386-stub.c). 
+     BUFMAX is defined as 1024 in most kgdb stubs. BUFMAX-1 is used
      as the maximum packet-size to ensure that the packet and an extra
      NUL character can always fit in the buffer.  This stops GDB
      trashing stubs that try to squeeze an extra NUL into what is
      already a full buffer (As of 1999-12-04 that was most stubs. */
-  rs->remote_packet_size = 400 - 1;
+  rs->remote_packet_size = 1024 - 1;
 
   /* Should rs->sizeof_g_packet needs more space than the
      default, adjust the size accordingly. Remember that each byte is
Index: src/gdb/frame.h
===================================================================
--- src.orig/gdb/frame.h	2004-09-08 10:26:20.000000000 +0530
+++ src/gdb/frame.h	2004-10-01 12:59:38.000000000 +0530
@@ -382,7 +382,10 @@
   SIGTRAMP_FRAME,
   /* Sentinel or registers frame.  This frame obtains register values
      direct from the inferior's registers.  */
-  SENTINEL_FRAME
+  SENTINEL_FRAME,
+  /* Kernel context switch frame. Shouldn't be printed in info threads
+   * listing. */
+  CONTEXT_FRAME
 };
 extern enum frame_type get_frame_type (struct frame_info *);
 
Index: src/gdb/stack.c
===================================================================
--- src.orig/gdb/stack.c	2004-08-03 06:27:26.000000000 +0530
+++ src/gdb/stack.c	2004-10-01 12:59:38.000000000 +0530
@@ -45,6 +45,7 @@
 #include "dictionary.h"
 #include "reggroups.h"
 #include "regcache.h"
+#include "objfiles.h"
 
 /* Prototypes for exported functions. */
 
@@ -420,9 +421,14 @@
   struct symtab_and_line sal;
   int source_print;
   int location_print;
+  CORE_ADDR pc;
+  struct frame_id fid;
+  struct minimal_symbol *schedbegin;
+  struct minimal_symbol *schedend;
 
   if (get_frame_type (fi) == DUMMY_FRAME
-      || get_frame_type (fi) == SIGTRAMP_FRAME)
+      || get_frame_type (fi) == SIGTRAMP_FRAME
+      || (get_frame_type (fi) == CONTEXT_FRAME && print_level != 0))
     {
       struct cleanup *uiout_cleanup
 	= make_cleanup_ui_out_tuple_begin_end (uiout, "frame");
@@ -455,12 +461,38 @@
 	  annotate_signal_handler_caller ();
           ui_out_field_string (uiout, "func", "<signal handler called>");
         }
+      else if (get_frame_type (fi) == CONTEXT_FRAME)
+        {
+	  annotate_context_entry ();
+          ui_out_field_string (uiout, "func", "<context switch>");
+        }
       ui_out_text (uiout, "\n");
       annotate_frame_end ();
 
       do_cleanups (uiout_cleanup);
       return;
     }
+  /* Don't print context switch and scheduler frames if we are at level 0. */
+  if (get_frame_type (fi) == CONTEXT_FRAME)
+    {
+      schedbegin = lookup_minimal_symbol("__sched_text_start", NULL,
+					 symfile_objfile);
+      schedend = lookup_minimal_symbol("__sched_text_end", NULL,
+				       symfile_objfile);
+      if (schedbegin && schedend)
+	while ((fi = get_prev_frame(fi)) != NULL)
+	  {
+	    fid = get_frame_id(fi);
+	    pc = 0;
+	    if (!fid.code_addr_p)
+	      break;
+	    pc = get_frame_id(fi).code_addr; 
+	    if (SYMBOL_VALUE_ADDRESS(schedbegin) >= pc)
+	      break;
+	    if (SYMBOL_VALUE_ADDRESS(schedend) <= pc)
+	      break;
+	  }
+    }
 
   /* If fi is not the innermost frame, that normally means that fi->pc
      points to *after* the call instruction, and we want to get the
Index: src/gdb/annotate.c
===================================================================
--- src.orig/gdb/annotate.c	2004-04-22 05:22:19.000000000 +0530
+++ src/gdb/annotate.c	2004-10-01 12:59:38.000000000 +0530
@@ -453,6 +453,13 @@
 }
 
 void
+annotate_context_entry (void)
+{
+  if (annotation_level == 2)
+    printf_filtered ("\n\032\032context-switch\n");
+}
+
+void
 annotate_frame_address (void)
 {
   if (annotation_level == 2)
Index: src/gdb/annotate.h
===================================================================
--- src.orig/gdb/annotate.h	2004-04-22 05:22:19.000000000 +0530
+++ src/gdb/annotate.h	2004-10-01 12:59:38.000000000 +0530
@@ -81,6 +81,7 @@
 extern void annotate_frame_begin (int, CORE_ADDR);
 extern void annotate_function_call (void);
 extern void annotate_signal_handler_caller (void);
+extern void annotate_context_entry (void);
 extern void annotate_frame_address (void);
 extern void annotate_frame_address_end (void);
 extern void annotate_frame_function_name (void);
Index: src/gdb/i386-lk-tdep.c
===================================================================
--- src.orig/gdb/i386-lk-tdep.c	2004-10-01 12:58:49.000000000 +0530
+++ src/gdb/i386-lk-tdep.c	2004-10-01 12:59:38.000000000 +0530
@@ -20,14 +20,16 @@
 #include "defs.h"
 
 #include "osabi.h"
+#include "frame-unwind.h"
 
 #include "i386-tdep.h"
-#include "i386-linux-tdep.h"
+#include "lk-tdep.h"
 
 static void
 i386_lk_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch)
 {
   struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
+  struct context_unwind_data *unwind_data;
 
   /* Linux kernel has an elf vmlinux file and uses elf format modules. */
   i386_elf_init_abi (info, gdbarch);
@@ -37,6 +39,12 @@
   set_gdbarch_register_reggroup_p (gdbarch, i386_register_reggroup_p);
 
   tdep->jb_pc_offset = 20;	/* From <bits/setjmp.h>.  */
+  unwind_data = (struct context_unwind_data *)
+		context_frame_unwinder.unwind_data;
+  /* From kernel/include/asm-i386/system.h */
+  unwind_data->pcshift = 2;
+  unwind_data->spshift = 8;
+  frame_unwind_prepend_unwinder (gdbarch, &context_frame_unwinder);
 }
 
 /* Provide a prototype to silence -Wmissing-prototypes.  */
Index: src/gdb/lk-tdep.c
===================================================================
--- src.orig/gdb/lk-tdep.c	2003-01-30 15:54:37.000000000 +0530
+++ src/gdb/lk-tdep.c	2004-10-01 12:59:38.000000000 +0530
@@ -0,0 +1,120 @@
+/* Target-dependent code for Linux kernel.
+
+   Copyright 2004 LinSysSoft Technologies Pvt. Ltd.
+
+   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
+   (at your option) any later version.
+
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   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.  */
+  
+#include "defs.h"
+#include "frame.h"
+#include "gdbarch.h"
+#include "frame-unwind.h"
+#include "gdb_assert.h"
+#include "symtab.h"
+#include "objfiles.h"
+#include "lk-tdep.h"
+
+/* Identifier for a context frame is composed of simply the sp and pc derived
+ * from next frame, which is a sentinel frame */
+static void
+context_frame_this_id (struct frame_info *next_frame, void **this_cache,
+		      struct frame_id *this_id)
+{
+  int optimized;
+  enum lval_type lvalp;
+  CORE_ADDR addr;
+  int realnum;
+  CORE_ADDR ipaddr;
+  CORE_ADDR spaddr;
+
+  frame_register_unwind(next_frame, SP_REGNUM, &optimized, &lvalp, &addr,
+			&realnum, &spaddr);
+  frame_register_unwind(next_frame, PC_REGNUM, &optimized, &lvalp, &addr,
+			&realnum, &ipaddr);
+  (*this_id) = frame_id_build(spaddr, ipaddr);
+}
+
+/*
+ * The pc of the frame previous to a context frame is reported at the
+ * instruction just past the last instruction of switch_to kernel macro. The
+ * sp may also need some adjustments because the switch_to macro may contain
+ * code that changes sp
+ */
+static void
+context_frame_prev_register (struct frame_info *next_frame, void **this_cache,
+			    int regnum, int *optimizedp,
+			    enum lval_type *lvalp, CORE_ADDR *addrp,
+			    int *realnump, void *valuep)
+{
+  struct context_unwind_data *unwind_dat = (struct context_unwind_data *)
+			context_frame_unwinder.unwind_data;
+  frame_register_unwind(next_frame, regnum, optimizedp, lvalp, addrp,
+			realnump, valuep);
+  if (regnum == PC_REGNUM)
+    {
+      *addrp = 0;
+      if (valuep)
+	(*(CORE_ADDR*)valuep) += unwind_data->pcshift;
+    }
+  else if (regnum == SP_REGNUM)
+    {
+      *addrp = 0;
+      if (valuep)
+	(*(CORE_ADDR*)valuep) += unwind_data->spshift;
+    }
+}
+
+/* If pc is in the section .sched.text and if the next frame is a sentinel
+ * frame, it has to be a context switch call frame */
+static const struct frame_unwind *
+context_frame_sniffer (struct frame_unwind *self,
+			 struct frame_info *next_frame,
+			 void **this_prologue_cache)
+{
+  CORE_ADDR pc;
+  struct minimal_symbol *s;
+
+  if (get_frame_type(next_frame) == SENTINEL_FRAME)
+    {
+      pc = frame_pc_unwind(next_frame);
+      s = lookup_minimal_symbol("__sched_text_start", NULL, symfile_objfile);
+      if (s && SYMBOL_VALUE_ADDRESS(s) >= pc)
+	return NULL;
+      s = lookup_minimal_symbol("__sched_text_end", NULL, symfile_objfile);
+      if (s && SYMBOL_VALUE_ADDRESS(s) <= pc)
+	return NULL;
+      return &context_frame_unwinder;
+    }
+  return NULL;
+}
+
+static struct context_unwind_data context_unwind_data;
+
+const struct frame_unwind context_frame_unwinder =
+{
+  CONTEXT_FRAME,
+  context_frame_this_id,
+  context_frame_prev_register,
+  (struct frame_data *)&context_unwind_data,
+  context_frame_sniffer
+};
+
+/* Provide a prototype to silence -Wmissing-prototypes.  */
+extern void _initialize_lk_tdep (void);
+
+void
+_initialize_lk_tdep (void)
+{
+}
Index: src/gdb/config/i386/lk.mt
===================================================================
--- src.orig/gdb/config/i386/lk.mt	2004-10-01 12:58:49.000000000 +0530
+++ src/gdb/config/i386/lk.mt	2004-10-01 12:59:38.000000000 +0530
@@ -1,3 +1,3 @@
 # Target: Intel i386 running Linux kernel
-TDEPFILES = i386-tdep.o i386-lk-tdep.o i387-tdep.o
+TDEPFILES = i386-tdep.o i386-lk-tdep.o i387-tdep.o lk-tdep.o
 TM_FILE= tm-lk.h
Index: src/gdb/config/i386/x86-64lk.mt
===================================================================
--- src.orig/gdb/config/i386/x86-64lk.mt	2004-10-01 12:58:49.000000000 +0530
+++ src/gdb/config/i386/x86-64lk.mt	2004-10-01 12:59:38.000000000 +0530
@@ -1,5 +1,5 @@
 # Target: AMD x86-64 running Linux Kernel
-TDEPFILES= x86-64-tdep.o x86-64-lk-tdep.o \
+TDEPFILES= x86-64-tdep.o x86-64-lk-tdep.o lk-tdep.o \
 	i386-tdep.o i387-tdep.o i386-lk-tdep.o
 
 GDB_MULTI_ARCH=GDB_MULTI_ARCH_TM
Index: src/gdb/lk-tdep.h
===================================================================
--- src.orig/gdb/lk-tdep.h	2003-01-30 15:54:37.000000000 +0530
+++ src/gdb/lk-tdep.h	2004-10-01 12:59:38.000000000 +0530
@@ -0,0 +1,38 @@
+/* Target-dependent code for Linux kernel.
+
+   Copyright 2004 LinSysSoft Technologies Pvt. Ltd.
+
+   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
+   (at your option) any later version.
+
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   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.  */
+  
+#ifndef LK_TDEP_H
+#define LK_TDEP_H
+
+/* CONTEXT_FRAME unwind data */
+struct context_unwind_data
+{
+	/* These two fields record the difference between pc and sp of context
+	 * and the previous frame (the schedule kernel function)
+	 * We use these fields and the pc and sp of the frame next to the
+	 * context frame (sentinel frame) to figure out the pc and sp of the
+	 * schedule function frame.
+	 */
+	int pcshift;
+	int spshift;
+};
+
+extern const struct frame_unwind context_frame_unwinder;
+
+#endif /* #ifndef LK_TDEP_H */
Index: src/gdb/x86-64-lk-tdep.c
===================================================================
--- src.orig/gdb/x86-64-lk-tdep.c	2004-10-01 12:58:49.000000000 +0530
+++ src/gdb/x86-64-lk-tdep.c	2004-10-01 12:59:38.000000000 +0530
@@ -22,14 +22,22 @@
 #include "osabi.h"
 
 #include "x86-64-tdep.h"
-#include "x86-64-linux-tdep.h"
-
+#include "lk-tdep.h"
 
 static void
 x86_64_lk_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch)
 {
   struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
+  struct context_unwind_data *unwind_data;
+
   x86_64_init_abi (info, gdbarch);
+
+  unwind_data = (struct context_unwind_data *)
+		context_frame_unwinder->unwind_data;
+  /* From kernel/include/asm-x86_64/system.h */
+  unwind_data->pcshift = 33;
+  unwind_data->spshift = TODO;
+  frame_unwind_prepend_unwinder (gdbarch, &context_frame_unwinder);
 }
   
 /* Provide a prototype to silence -Wmissing-prototypes.  */

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]