From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 5351 invoked by alias); 24 Sep 2009 20:10:37 -0000 Received: (qmail 5341 invoked by uid 22791); 24 Sep 2009 20:10:36 -0000 X-SWARE-Spam-Status: No, hits=-1.5 required=5.0 tests=AWL,BAYES_00,MIME_QP_LONG_LINE,SPF_PASS X-Spam-Check-By: sourceware.org Received: from mail-px0-f185.google.com (HELO mail-px0-f185.google.com) (209.85.216.185) by sourceware.org (qpsmtpd/0.43rc1) with ESMTP; Thu, 24 Sep 2009 20:10:30 +0000 Received: by pxi15 with SMTP id 15so2094320pxi.25 for ; Thu, 24 Sep 2009 13:10:29 -0700 (PDT) Received: by 10.114.248.20 with SMTP id v20mr5643748wah.132.1253823029196; Thu, 24 Sep 2009 13:10:29 -0700 (PDT) Received: from xpjpn (pool-71-111-147-240.ptldor.dsl-w.verizon.net [71.111.147.240]) by mx.google.com with ESMTPS id 20sm1325953pxi.8.2009.09.24.13.10.28 (version=SSLv3 cipher=RC4-MD5); Thu, 24 Sep 2009 13:10:28 -0700 (PDT) From: Caz Yokoyama To: Subject: patch to eliminate ADDR on loading symbols of Linux module Date: Thu, 24 Sep 2009 20:10:00 -0000 Message-ID: <4D3A256890A9458FB055F19527A022A2@xpjpn> MIME-Version: 1.0 Content-Type: multipart/mixed; boundary="----=_NextPart_000_0246_01CA3D18.781F3120" X-IsSubscribed: yes Mailing-List: contact gdb-patches-help@sourceware.org; run by ezmlm Precedence: bulk List-Id: List-Subscribe: List-Archive: List-Post: List-Help: , Sender: gdb-patches-owner@sourceware.org X-SW-Source: 2009-09/txt/msg00757.txt.bz2 This is a multi-part message in MIME format. ------=_NextPart_000_0246_01CA3D18.781F3120 Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: 7bit Content-length: 1155 Hello, When we debug a loadable module of Linux kernel, we use the command, add-symbol-file to read its symbols. We have to specify its loaded address like (gdb) add-symbol-file drivers/net/e1000e/e1000e.ko 0xfffffffffa008000 The address is appeared in /proc/modules. Someone said several months ago that the address is taken by python script. But I don't know how. Therefore, I did by my way. When we develop kernel module, we are interested in several module at most which we are developing. We don't care the symbols of nfs for example. Therefore, extending add-symbol-file may be a best way. So the syntax of add-symbol-file is Usage: add-symbol-file FILE [ADDR [-s -s ...] ] I.e. ADDR becomes optional. In add_symbol_file(), it checks to see there is only one parameter, FILE. Then searching the module in the linked list of kernel modules and getting loaded address. Construct new string which has FILE and ADDR and pass to original add_symbol_file(). It assumes the modification of http://sourceware.org/ml/gdb-patches/2009-08/msg00115.html Thank you. -Caz Yokoyama, caz at caztech dot com. 503-804-1028(m). ------=_NextPart_000_0246_01CA3D18.781F3120 Content-Type: application/octet-stream; name="LinuxModuleSymbolLoad.patch" Content-Transfer-Encoding: quoted-printable Content-Disposition: attachment; filename="LinuxModuleSymbolLoad.patch" Content-length: 8398 Index: gdb/symfile.c=0A= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=0A= RCS file: /cvs/src/src/gdb/symfile.c,v=0A= retrieving revision 1.246=0A= diff -u -r1.246 symfile.c=0A= --- gdb/symfile.c 18 Sep 2009 17:33:51 -0000 1.246=0A= +++ gdb/symfile.c 24 Sep 2009 19:27:58 -0000=0A= @@ -2068,6 +2068,194 @@=0A= ui_out_text (uiout, ".\n");=0A= }=0A= =20=0A= +/*=0A= + Read symboles of a module file(.ko) of Linux kernel=0A= +*/=0A= +/* taken from kernel source code */=0A= +struct list_head {=0A= + CORE_ADDR next;=0A= + CORE_ADDR prev;=0A= +};=0A= +struct module;=0A= +typedef unsigned int __kernel_mode_t;=0A= +typedef __kernel_mode_t mode_t;=0A= +=0A= +struct attribute {=0A= + const char *name;=0A= + struct module *owner;=0A= + mode_t mode;=0A= +};=0A= +=0A= +struct module_attribute {=0A= + struct attribute attr;=0A= + ssize_t (*show)(struct module_attribute *, struct module *, char *);=0A= + ssize_t (*store)(struct module_attribute *, struct module *,=0A= + const char *, size_t count);=0A= + void (*setup)(struct module *, const char *);=0A= + int (*test)(struct module *);=0A= + void (*free)(struct module *);=0A= +};=0A= +=0A= +struct attribute_group {=0A= + const char *name;=0A= + mode_t (*is_visible)();=0A= + struct attribute **attrs;=0A= +};=0A= +=0A= +struct module_sect_attr=0A= +{=0A= + struct module_attribute mattr;=0A= + char *name;=0A= + unsigned long address;=0A= +};=0A= +=0A= +struct module_sect_attrs=0A= +{=0A= + struct attribute_group grp;=0A= + unsigned int nsections;=0A= + struct module_sect_attr attrs[0];=0A= +};=0A= +=0A= +#define MODULE_NAME_LEN (64 - sizeof(CORE_ADDR))=0A= +struct module=0A= +{=0A= + CORE_ADDR unused_state;=0A= + struct list_head list;=0A= + char name[MODULE_NAME_LEN];=0A= +};=0A= +#define OFFSET(structure, field) ((CORE_ADDR)(&((struct structure *)0)->fi= eld))=0A= +=0A= +static char *=0A= +add_addr_on_linux_module (char *module_name)=0A= +{=0A= + char *module_base_name, *s;=0A= + struct expression *expr;=0A= + struct value *val;=0A= + int offset_sect_attrs, ret, n;=0A= + struct symbol *modules;=0A= + struct module module;=0A= + CORE_ADDR module_addr, _msas;=0A= + struct module_sect_attrs msas;=0A= + struct module_sect_attr *kmsas;=0A= + char section_name[MODULE_NAME_LEN], *arg_str;=0A= +=0A= + /* Get base name of module. */=0A= + s =3D strrchr (module_name, '/');=0A= + if (s =3D=3D NULL) /* not found */=0A= + s =3D module_name;=0A= + else=0A= + s++;=0A= + module_base_name =3D xmalloc (strlen(s) + 1);=0A= + if (module_base_name =3D=3D NULL)=0A= + {=0A= + warning ("can't allocate module_base_name");=0A= + return NULL;=0A= + }=0A= + make_cleanup (xfree, module_base_name);=0A= + strcpy(module_base_name, s);=0A= + /* Discard .ko */=0A= + s =3D strchr(module_base_name, '.');=0A= + if (s !=3D NULL)=0A= + *s =3D '\0';=0A= +=0A= + /* Find whether the module is loaded. */=0A= + /* Check to see if Linux is the supported version. */=0A= + expr =3D parse_expression ("&((struct module *)0)->sect_attrs");=0A= + val =3D evaluate_expression (expr);=0A= + offset_sect_attrs =3D unpack_long (value_type(val), value_contents_all(v= al));=0A= + expr =3D parse_expression ("&((struct module_sect_attrs *)0)->attrs[1]")= ;=0A= + val =3D evaluate_expression (expr);=0A= + if (unpack_long (value_type(val), value_contents_all(val)) !=3D=0A= + (long)&((struct module_sect_attrs *)0)->attrs[1]) {=0A= + warning ("your target kernel has difference struct module_sect_attrs")= ;=0A= + return NULL;=0A= + }=0A= +=0A= + /* Modules are in the linked list pointed by "modules" */=0A= + modules =3D lookup_symbol ("modules", NULL, VAR_DOMAIN, NULL);=0A= + if (modules =3D=3D NULL) {=0A= + warning ("can't find the address of modules");=0A= + return NULL;=0A= + }=0A= + module_addr =3D SYMBOL_VALUE_ADDRESS(modules) - OFFSET(module, list.next= );=0A= + do {=0A= + ret =3D target_read_memory(module_addr,=0A= + (gdb_byte *)&module, sizeof(module));=0A= + if (ret !=3D 0)=0A= + {=0A= + warning("can't read module");=0A= + return NULL;=0A= + }=0A= + if (strcmp(module_base_name, module.name) =3D=3D 0) /* found the modul= e */=0A= + break;=0A= + module_addr =3D module.list.next - OFFSET(module, list.next);=0A= + } while (module_addr + OFFSET(module, list.next) !=3D=0A= + SYMBOL_VALUE_ADDRESS(modules));=0A= + if (module_addr + OFFSET(module, list.next) =3D=3D=0A= + SYMBOL_VALUE_ADDRESS(modules)) /* not found the module */=0A= + {=0A= + warning("can't find %s in the linked list of Linux modules",=0A= + module_base_name);=0A= + return NULL;=0A= + }=0A= +=0A= + ret =3D target_read_memory (module_addr + offset_sect_attrs,=0A= + (gdb_byte *)&_msas, sizeof(_msas));=0A= + if (ret !=3D 0)=0A= + {=0A= + warning("can't read _msas on %s", module.name);=0A= + return NULL;=0A= + }=0A= + ret =3D target_read_memory (_msas,=0A= + (gdb_byte *)&msas, sizeof(msas));=0A= + if (ret !=3D 0)=0A= + {=0A= + warning("can't read msas on %s", module.name);=0A= + return NULL;=0A= + }=0A= + kmsas =3D xmalloc (sizeof(struct module_sect_attr) * msas.nsections);=0A= + if (kmsas =3D=3D NULL)=0A= + {=0A= + warning ("can't allocate kmsas");=0A= + return NULL;=0A= + }=0A= + make_cleanup (xfree, kmsas);=0A= + ret =3D target_read_memory (_msas + OFFSET(module_sect_attrs, attrs[0]),= =0A= + (char *)kmsas,=0A= + sizeof(*kmsas) * msas.nsections);=0A= + if (ret !=3D 0)=0A= + {=0A= + warning ("can't read kmsas");=0A= + return NULL;=0A= + }=0A= + /* Look for .text section */=0A= + for (n =3D 0; n < msas.nsections; n++, kmsas++)=0A= + {=0A= + ret =3D target_read_memory((CORE_ADDR)kmsas->name,=0A= + section_name, MODULE_NAME_LEN);=0A= + if (ret !=3D 0)=0A= + {=0A= + warning ("can't read kmsas->name");=0A= + return NULL;=0A= + }=0A= + if (strcmp(section_name, ".text") =3D=3D 0)=0A= + break;=0A= + }=0A= + if (n < msas.nsections) /* found .text section */=0A= + {=0A= + /* " 0x%016lx" + terminating '\0' */=0A= + arg_str =3D xmalloc (strlen(module_name) + 1 + 2 + 16 + 1);=0A= + if (arg_str =3D=3D NULL) {=0A= + warning ("can't allocate arg_str");=0A= + return NULL;=0A= + }=0A= + sprintf (arg_str, "%s 0x%016lx", module_name, kmsas->address);=0A= + /* No need to free arg_str. make_cleanup_freeargv() takes care. */= =0A= + }=0A= +=0A= + return arg_str;=0A= +}=0A= +=0A= /* This function allows the addition of incrementally linked object files.= =0A= It does not modify any state in the target, only in the debugger. */= =0A= /* Note: ezannoni 2000-04-13 This function/command used to have a=0A= @@ -2110,12 +2298,25 @@=0A= =20=0A= dont_repeat ();=0A= =20=0A= - if (args =3D=3D NULL)=0A= - error (_("add-symbol-file takes a file name and an address"));=0A= + if (args =3D=3D NULL || *args =3D=3D '\0')=0A= + error (_("Usage: add-symbol-file FILE [ADDR [-s -s = ...] ]"));=0A= =20=0A= argv =3D gdb_buildargv (args);=0A= make_cleanup_freeargv (argv);=0A= =20=0A= + if (argv[1] =3D=3D NULL) /* no ADDR */=0A= + {=0A= + if (remote_break_mode !=3D remote_break_sysrq_g)=0A= + {=0A= + error (_("Don't you forget \"set remotebreak sysrq-g\"?"));=0A= + }=0A= + args =3D add_addr_on_linux_module (args);=0A= + if (args =3D=3D NULL)=0A= + return;=0A= + argv =3D gdb_buildargv (args);=0A= + make_cleanup_freeargv (argv);=0A= + }=0A= +=0A= for (arg =3D argv[0], argcnt =3D 0; arg !=3D NULL; arg =3D argv[++argcnt= ])=0A= {=0A= /* Process the argument. */=0A= @@ -2222,8 +2423,11 @@=0A= so we can't determine what section names are valid. */=0A= }=0A= =20=0A= - if (from_tty && (!query ("%s", "")))=0A= - error (_("Not confirmed."));=0A= + if (remote_break_mode !=3D remote_break_sysrq_g) /* Not module loading *= /=0A= + {=0A= + if (from_tty && (!query ("%s", "")))=0A= + error (_("Not confirmed."));=0A= + }=0A= =20=0A= symbol_file_add (filename, from_tty ? SYMFILE_VERBOSE : 0,=0A= section_addrs, flags);=0A= ------=_NextPart_000_0246_01CA3D18.781F3120--