This is the mail archive of the
gdb-patches@sources.redhat.com
mailing list for the GDB project.
kgdb support for gdb
- From: "Amit S. Kale" <amitkale at linsyssoft dot com>
- To: gdb-patches at sources dot redhat dot com
- Date: Fri, 1 Oct 2004 13:14:33 +0530
- Subject: kgdb support for gdb
- Organization: LinSysSoft Technologies Pvt Ltd
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. */