From: "Amit S. Kale" <amitkale@emsyssoft.com>
To: Linux Kernel <linux-kernel@vger.kernel.org>,
KGDB bugreports <kgdb-bugreport@lists.sourceforge.net>
Cc: Tom Rini <trini@kernel.crashing.org>
Subject: module scanning in kgdb 2.x
Date: Fri, 12 Mar 2004 12:06:16 +0530 [thread overview]
Message-ID: <200403121206.16130.amitkale@emsyssoft.com> (raw)
Hi,
Here is code to scan modules in kgdb for 2.6 kernels. It's been contributed by
TimeSys Corporation.
It does following things:
1. Adds MODULE_STATE_GONE to indicate that a module was removed. This is
differnent from MODULE_STATE_GOING. gdb needs to be notified of a module
event _after_ a module has been removed. Or else it'll still find the module
during a module list scan and will not remove it from its core.
2. Defines a structure mod_section which stores module section names and
offsets preserved during loading of a module.
3. Adds a couple of fields to struct module to keep module section
information.
4. Adds a few notifications for gdb to know module related events.
5. Saves module section names and offsets in load_module.
-Amit
Index: linux-2.6.3-kgdb/include/linux/module.h
===================================================================
--- linux-2.6.3-kgdb.orig/include/linux/module.h 2004-02-24 10:44:47.000000000
+0530
+++ linux-2.6.3-kgdb/include/linux/module.h 2004-03-04 18:58:47.116645760
+0530
@@ -186,8 +186,17 @@
MODULE_STATE_LIVE,
MODULE_STATE_COMING,
MODULE_STATE_GOING,
+ MODULE_STATE_GONE,
};
+#ifdef CONFIG_KGDB
+#define MAX_SECTNAME 31
+struct mod_section {
+ void *address;
+ char name[MAX_SECTNAME + 1];
+};
+#endif
+
struct module
{
enum module_state state;
@@ -198,6 +207,13 @@
/* Unique handle for this module */
char name[MODULE_NAME_LEN];
+#ifdef CONFIG_KGDB
+ /* keep kgdb info at the begining so that gdb doesn't have a chance to
+ * miss out any fields */
+ unsigned long num_sections;
+ struct mod_section *mod_sections;
+#endif
+
/* Exported symbols */
const struct kernel_symbol *syms;
unsigned int num_syms;
Index: linux-2.6.3-kgdb/kernel/module.c
===================================================================
--- linux-2.6.3-kgdb.orig/kernel/module.c 2004-02-24 10:44:56.000000000 +0530
+++ linux-2.6.3-kgdb/kernel/module.c 2004-03-04 18:55:59.136182672 +0530
@@ -727,6 +727,11 @@
mod->state = MODULE_STATE_GOING;
restart_refcounts();
+ down(¬ify_mutex);
+ notifier_call_chain(&module_notify_list, MODULE_STATE_GOING,
+ mod);
+ up(¬ify_mutex);
+
/* Never wait if forced. */
if (!forced && module_refcount(mod) != 0)
wait_for_zero_refcount(mod);
@@ -734,6 +739,10 @@
/* Final destruction now noone is using it. */
mod->exit();
free_module(mod);
+ down(¬ify_mutex);
+ notifier_call_chain(&module_notify_list, MODULE_STATE_GONE,
+ NULL);
+ up(¬ify_mutex);
out:
up(&module_mutex);
@@ -1087,6 +1096,11 @@
/* Arch-specific cleanup. */
module_arch_cleanup(mod);
+#ifdef CONFIG_KGDB
+ /* kgdb info */
+ vfree(mod->mod_sections);
+#endif
+
/* Module unload stuff */
module_unload_free(mod);
@@ -1302,6 +1316,30 @@
return NULL;
}
+#ifdef CONFIG_KGDB
+int add_modsects (struct module *mod, Elf_Ehdr *hdr, Elf_Shdr *sechdrs, const
+ char *secstrings)
+{
+ int i;
+
+ mod->num_sections = hdr->e_shnum - 1;
+ mod->mod_sections = vmalloc((hdr->e_shnum - 1)* sizeof (struct
mod_section));
+
+ if (mod->mod_sections == NULL) {
+ return -ENOMEM;
+ }
+
+ for (i = 1; i < hdr->e_shnum; i++) {
+ mod->mod_sections[i - 1].address = (void *)sechdrs[i].sh_addr;
+ strncpy(mod->mod_sections[i - 1].name, secstrings +
+ sechdrs[i].sh_name, MAX_SECTNAME);
+ mod->mod_sections[i - 1].name[MAX_SECTNAME] = '\0';
+ }
+
+ return 0;
+}
+#endif
+
#ifdef CONFIG_KALLSYMS
int is_exported(const char *name, const struct module *mod)
{
@@ -1650,6 +1688,12 @@
percpu_modcopy(mod->percpu, (void *)sechdrs[pcpuindex].sh_addr,
sechdrs[pcpuindex].sh_size);
+#ifdef CONFIG_KGDB
+ if ((err = add_modsects(mod, hdr, sechdrs, secstrings)) < 0) {
+ goto nomodsectinfo;
+ }
+#endif
+
err = module_finalize(hdr, sechdrs, mod);
if (err < 0)
goto cleanup;
@@ -1688,6 +1732,11 @@
arch_cleanup:
module_arch_cleanup(mod);
cleanup:
+
+#ifdef CONFIG_KGDB
+nomodsectinfo:
+ vfree(mod->mod_sections);
+#endif
module_unload_free(mod);
module_free(mod, mod->module_init);
free_core:
@@ -1758,7 +1807,12 @@
if (ret < 0) {
/* Init routine failed: abort. Try to protect us from
buggy refcounters. */
+
mod->state = MODULE_STATE_GOING;
+ down(¬ify_mutex);
+ notifier_call_chain(&module_notify_list, MODULE_STATE_GOING,
+ mod);
+ up(¬ify_mutex);
synchronize_kernel();
if (mod->unsafe)
printk(KERN_ERR "%s: module is now stuck!\n",
next reply other threads:[~2004-03-12 6:36 UTC|newest]
Thread overview: 6+ messages / expand[flat|nested] mbox.gz Atom feed top
2004-03-12 6:36 Amit S. Kale [this message]
2004-03-12 7:00 ` [Kgdb-bugreport] module scanning in kgdb 2.x Amit S. Kale
2004-03-19 15:01 ` Amit S. Kale
2004-03-16 21:18 ` Rusty Russell
2004-03-19 15:06 ` Amit S. Kale
2004-03-19 23:49 ` Rusty Russell
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=200403121206.16130.amitkale@emsyssoft.com \
--to=amitkale@emsyssoft.com \
--cc=kgdb-bugreport@lists.sourceforge.net \
--cc=linux-kernel@vger.kernel.org \
--cc=trini@kernel.crashing.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.