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]

Re: Patching gdb 5.0 for XFree86 module support


On Mon, 24 Sep 2001, Andrew Cagney wrote:

>> I've been working the last few days on porting an older gdb 
>> 4.18 patch that adds support to gdb for debugging XFree86 
>> loadable modules in place without requiring a static server 
>> build.  This has several advantages for an XFree86 developer, as 
>> well as for the more technical user out there who is capable of 
>> debugging a problem, but not necessarily willing or capable to 
>> rebuild XFree86 from source as a static server.
>
>Just FYI, shared library support in current GDB is very different to 
>that found in 5.0.  It was overhalled and made far far more modular.

Just to clarify, what do you mean by 'current GDB'?  Do you mean 
current CVS of gdb, or current Rawhide GDB?  My testing is with 
Rawhide GDB since I'm wanting to use the gdb supplied with the 
distro.

>Looking at this patch and especially the comment:
>
[SNIP]
>>> + * just tidy up after the last run, tell the inferior that we're
>>> + * around and insert a breakpoint so we get chance to do something
>>> + * when a module is loaded.
>>> + *
>>> + */
>
>the basic idea is sound.  Per Daniel J's comment several people have 
>proposed similar things while makig the observation that the current 
>shlib implementation should be generalized.

Ok, sounds good.

>Andrew
>
>PS: Since the patch is very old, I'll just add a heads up that I'll need 
>to run the usual checks.

Ok, I have actually got it running now.  I'm attaching the latest 
patch, which is partially functional anyway.

The full src.rpm of gdb with loadable XFree86 module support is 
at:  ftp://people.redhat.com/mharris/hacks/gdb-5.0rh-15.6xfree.src.rpm

I can load symbols from .o modules manually, but aparently not 
from .a's.

Ultimately, what I would like is for gdb to load the modules for 
the whole shebang all at once.  Possible?  Am I totally insane?

1Gb of RAM should suffice no?  ;o)

TIA


----------------------------------------------------------------------
Mike A. Harris                  Shipping/mailing address:
OS Systems Engineer             190 Pittsburgh Ave., Sault Ste. Marie,
XFree86 maintainer              Ontario, Canada, P6C 5B3
Red Hat Inc.                    Phone: (705)949-2136
http://www.redhat.com           ftp://people.redhat.com/mharris

Red Hat XFree86 mailing list:   xfree86-list@redhat.com
IRC:  #redhat-xfree86 on irc.openprojects.org
----------------------------------------------------------------------
root@dod.usarmy.gov:~#  rm -f /bin/laden
gdb-5.0rh-xfree86-modules.patch version 1.0
 
gdb patch to add ability to debug XFree86 loadable modules.
This patch is based upon the original patch for gdb 4.18 floating
around, but is heavily modified.  Currently, it is partially
functional, works with .o modules, but not .a modules.
 
The patch is against the Red Hat Rawhide version of gdb:
gdb-5.0rh-15.src.rpm, and is dropped in as Patch0.  The specfile
is tweaked to call make as:
 
        make CFLAGS="$RPM_OPT_FLAGS -DXFREE_MODULE_SUPPORT"
 

Any help with fixing this up, improving it, etc. would be very
greatly appreciated.  Please include me in all correspondance
related to this.

gdb src.rpm available at:

ftp://people.redhat.com/mharris/hacks

I also am making debuggable RPM's of XFree86 as well, which should
simplify greatly the effort needed to debug X.

                       Sunday, September 23, 2001
                       Mike A. Harris <mharris@redhat.com>

--- gdb/config/i386/linux.mh.xfree86-modules	Wed Mar 21 16:22:49 2001
+++ gdb/config/i386/linux.mh	Sun Sep 23 14:32:17 2001
@@ -4,7 +4,7 @@
 XDEPFILES=
 
 NAT_FILE= nm-linux.h
-NATDEPFILES= infptrace.o inftarg.o fork-child.o corelow.o \
+NATDEPFILES= infptrace.o xfreemod.o inftarg.o fork-child.o corelow.o \
 	core-aout.o i386-nat.o i386-linux-nat.o i387-nat.o \
 	proc-service.o thread-db.o lin-lwp.o
 
--- gdb/config/i386/nm-linux.h.xfree86-modules	Sat Jul 14 07:55:29 2001
+++ gdb/config/i386/nm-linux.h	Sun Sep 23 14:32:17 2001
@@ -70,6 +70,7 @@
 #ifdef HAVE_LINK_H
 #define SVR4_SHARED_LIBS
 #include "solib.h"		/* Support for shared libraries.  */
+#include "xfreemod.h"		/* Support for XFree86 modules.   */
 #endif
 
 /* Override copies of {fetch,store}_inferior_registers in `infptrace.c'.  */
--- gdb/breakpoint.c.xfree86-modules	Thu Aug  2 08:05:56 2001
+++ gdb/breakpoint.c	Sun Sep 23 14:32:17 2001
@@ -2940,6 +2940,7 @@
 	  bs_class = bp_nostop;
 	  break;
 	case bp_shlib_event:
+	case bp_xfreemod_event:
 	  bs_class = shlib_event;
 	  break;
 	case bp_thread_event:
@@ -3125,7 +3126,8 @@
     {bp_catch_vfork, "catch vfork"},
     {bp_catch_exec, "catch exec"},
     {bp_catch_catch, "catch catch"},
-    {bp_catch_throw, "catch throw"}
+    {bp_catch_throw, "catch throw"},
+    {bp_xfreemod_event, "XFree86 module events"}
   };
   
   static char *bpdisps[] =
@@ -3331,6 +3333,7 @@
     case bp_call_dummy:
     case bp_shlib_event:
     case bp_thread_event:
+    case bp_xfreemod_event:
 #ifdef UI_OUT
       if (addressprint)
 	{
@@ -4053,6 +4056,32 @@
       delete_breakpoint (b);
 }
 
+#ifdef XFREE_MODULE_SUPPORT
+void remove_xfreemod_event_breakpoints (void)
+{
+  register struct breakpoint *b, *temp;
+
+  ALL_BREAKPOINTS_SAFE (b, temp)
+    if (b->type == bp_xfreemod_event)
+      delete_breakpoint (b);
+}
+
+void create_xfreemod_event_breakpoint (CORE_ADDR address)
+{
+  struct breakpoint *b;
+  struct symtab_and_line sal;
+
+  INIT_SAL (&sal);	/* initialize to zeroes */
+  sal.pc = address;
+  sal.section = find_pc_overlay (sal.pc);
+  b = set_raw_breakpoint (sal, bp_xfreemod_event);
+  b->number = internal_breakpoint_number--;
+  b->disposition = disp_donttouch;
+  b->type = bp_xfreemod_event;
+
+}
+#endif
+
 #ifdef SOLIB_ADD
 void
 remove_solib_event_breakpoints (void)
@@ -4565,6 +4594,7 @@
     case bp_watchpoint_scope:
     case bp_shlib_event:
     case bp_thread_event:
+    case bp_xfreemod_event:
       break;
     }
   if (say_where)
@@ -7140,6 +7170,7 @@
       /* This breakpoint is special, it's set up when the inferior
          starts and we really don't want to touch it.  */
     case bp_shlib_event:
+    case bp_xfreemod_event:
 
       /* Like bp_shlib_event, this breakpoint type is special.
 	 Once it is set up, we do not want to touch it.  */
--- gdb/breakpoint.h.xfree86-modules	Thu Aug  2 08:05:57 2001
+++ gdb/breakpoint.h	Sun Sep 23 14:32:17 2001
@@ -126,7 +126,12 @@
     /* These are catchpoints to implement "catch catch" and "catch throw"
        commands for C++ exception handling. */
     bp_catch_catch,
-    bp_catch_throw
+    bp_catch_throw,
+
+    /* As for bp_shlib_event but when the xfree module loader informs
+       us that a module has been loaded */
+    bp_xfreemod_event
+
 
 
   };
@@ -658,9 +663,13 @@
 
 extern struct breakpoint *create_thread_event_breakpoint (CORE_ADDR);
 
+extern void create_xfreemod_event_breakpoint (CORE_ADDR);
+
 extern void remove_solib_event_breakpoints (void);
 
 extern void remove_thread_event_breakpoints (void);
+
+extern void remove_xfreemod_event_breakpoints (void);
 
 extern void disable_breakpoints_in_shlibs (int silent);
 
--- gdb/dbxread.c.xfree86-modules	Sat Jul  7 13:19:50 2001
+++ gdb/dbxread.c	Sun Sep 23 14:32:17 2001
@@ -2272,7 +2272,7 @@
 	    case 'F':
 	      function_stab_type = type;
 
-#ifdef SOFUN_ADDRESS_MAYBE_MISSING
+#if defined(SOFUN_ADDRESS_MAYBE_MISSING) || defined(XFREE_MODULE_SUPPORT)
 	      /* Deal with the SunPRO 3.0 compiler which omits the address
 	         from N_FUN symbols.  */
 	      if (type == N_FUN
--- gdb/fork-child.c.xfree86-modules	Fri May  4 00:15:24 2001
+++ gdb/fork-child.c	Sun Sep 23 14:32:17 2001
@@ -374,6 +374,9 @@
 #ifdef SOLIB_CREATE_INFERIOR_HOOK
   SOLIB_CREATE_INFERIOR_HOOK (pid);
 #endif
+#ifdef XFREE_MODULE_SUPPORT
+   xfreemod_create_inferior_hook(pid);
+#endif
 }
 
 /* An inferior Unix process CHILD_PID has been created by a call to
--- gdb/infrun.c.xfree86-modules	Mon Jul 16 10:46:34 2001
+++ gdb/infrun.c	Sun Sep 23 14:32:17 2001
@@ -1532,14 +1532,18 @@
 	    if (breakpoints_inserted)
 	      remove_breakpoints ();
 
-	    /* Check for any newly added shared libraries if we're
-	       supposed to be adding them automatically.  */
+	    /* Check for any newly added shared libraries or xfree
+	       modules if we're supposed to be adding them
+	       automatically.  */
 	    if (auto_solib_add)
 	      {
 		/* Switch terminal for any messages produced by
 		   breakpoint_re_set.  */
 		target_terminal_ours_for_output ();
 		SOLIB_ADD (NULL, 0, NULL);
+#ifdef XFREE_MODULE_SUPPORT
+		xfreemod_add (NULL, 0, NULL);
+#endif
 		target_terminal_inferior ();
 	      }
 
@@ -2468,6 +2472,10 @@
 		   breakpoint_re_set.  */
 		target_terminal_ours_for_output ();
 		SOLIB_ADD (NULL, 0, NULL);
+#ifdef XFREE_MODULE_SUPPORT
+		xfreemod_add (NULL, 0, NULL);
+#endif
+
 		target_terminal_inferior ();
 	      }
 
--- gdb/xfreemod.c.xfree86-modules	Sun Sep 23 14:32:17 2001
+++ gdb/xfreemod.c	Sun Sep 23 14:32:17 2001
@@ -0,0 +1,343 @@
+/* Handle XFree dynamically loaded modules
+   
+This file is not an official 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
+(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 "symtab.h"
+#include "bfd.h"
+#include "symfile.h"
+#include "objfiles.h"
+#include "gdbcore.h"
+#include "gdb-stabs.h"
+#include "target.h"
+#include "breakpoint.h"
+#include "language.h"
+#include "command.h"
+#include "gnu-regex.h"
+
+/* The XFree server has its own dynamic load mechanism. Unlike shared
+ * libraries it loads regular .o (or even .a) files. GDB support for
+ * tracking loaded modules is very similar to shared libraries however
+ * (in fact much of this code originated in solib.c).
+ *
+ * There are a few differences. We don't need to do very much in the
+ * create_inferior hook as no modules are loaded at that point so we
+ * just tidy up after the last run, tell the inferior that we're
+ * around and insert a breakpoint so we get chance to do something
+ * when a module is loaded.
+ *
+ */
+
+static char *xfreemod_break_names[] = {
+  "_loader_debug_state",
+  NULL
+};
+
+#define MOD_LIST "ModList"
+
+static struct mod_list *mod_list_head;	/* List of known modules */
+
+/* Called when the inferior starts, just after the shared library hook */
+void xfreemod_create_inferior_hook(void)
+{
+  struct mod_list *mod;
+  struct mod_list *next_mod;
+  struct minimal_symbol *msymbol;
+  char **bkpt_namep;
+
+  /* First, remove any existing breakpoints.  Their addresses
+     may have changed since the last time we ran the program.  */
+  remove_xfreemod_event_breakpoints ();
+
+  /* And our copy of the inferior's modules */
+  for (mod = mod_list_head; mod; mod = next_mod)
+  {
+      next_mod = mod->next;
+      free(mod);
+  }
+  mod_list_head = 0;
+
+  msymbol = lookup_minimal_symbol ("DebuggerPresent", NULL, symfile_objfile);
+  if (msymbol)
+  {
+      char flag = 1;
+      
+      int status = target_write_memory (SYMBOL_VALUE_ADDRESS (msymbol),
+					&flag,
+					sizeof(flag));
+  }
+
+  /* Scan through the list of symbols, trying to look up the symbol and
+     set a breakpoint there. */
+  for (bkpt_namep = xfreemod_break_names; *bkpt_namep != NULL; bkpt_namep++)
+  {
+    msymbol = lookup_minimal_symbol (*bkpt_namep, NULL, symfile_objfile);
+    if ((msymbol != NULL) && (SYMBOL_VALUE_ADDRESS (msymbol) != 0))
+    {
+      create_xfreemod_event_breakpoint (SYMBOL_VALUE_ADDRESS (msymbol));
+    }
+  }
+}
+
+/* Common symbols are not given addresses until the final link - which
+ * in this case is when the module is loaded so we need to read the
+ * addresses for these symbols from the inferior.
+ */
+void add_common_symbols (struct mod_list *mod)
+{
+  LDRCommonPtr commons;
+  int i;
+  int status;
+
+  if (mod->commonslen)
+  {
+    init_minimal_symbol_collection ();
+    make_cleanup_discard_minimal_symbols ();
+    
+    commons = xmalloc (mod->commonslen * sizeof(LDRCommon));
+    
+    status = target_read_memory (mod->commons, 
+				 (char *)commons,
+				 mod->commonslen * sizeof(LDRCommon));
+    for (i = 0; i <mod->commonslen; i++)
+    {
+      char *name = xmalloc(commons[i].namelen + 1);
+      status = target_read_memory ((CORE_ADDR)commons[i].name, 
+			  name,
+			  commons[i].namelen + 1);
+      prim_record_minimal_symbol (name, (CORE_ADDR)commons[i].addr,
+				  mst_bss, mod->objfile);
+      free(name);
+    } 
+    install_minimal_symbols (mod->objfile);
+    free(commons);
+  }
+}
+
+
+/* Read the list of loaded modules from the inferior and add any new
+ * ones to our local copy
+ */
+void add_modules(int from_tty)
+{
+  struct minimal_symbol *msymbol;
+  CORE_ADDR modrec_addr = 0;
+  LDRModuleRec ldr_rec;
+  char *mod_name;
+  struct mod_list *mod;
+
+  msymbol = lookup_minimal_symbol (MOD_LIST, NULL, symfile_objfile);
+  if (msymbol)
+  {
+    int status = target_read_memory (SYMBOL_VALUE_ADDRESS (msymbol),
+				     (char *)&modrec_addr,
+				     sizeof (CORE_ADDR));
+    while(modrec_addr != 0)
+    {
+      status = target_read_memory (modrec_addr,
+				   (char *)&ldr_rec,
+				   sizeof (LDRModuleRec));
+      mod_name = xmalloc (ldr_rec.namelen + 1);
+      status = target_read_memory ((CORE_ADDR)ldr_rec.name,
+				   mod_name,
+				   ldr_rec.namelen + 1);
+      
+      for (mod = mod_list_head; mod; mod = mod->next)
+      {
+	  if (strcmp(mod_name, mod->mod_name) == 0)
+	      break;
+      }
+      if (!mod)
+      {
+	  mod = xmalloc(sizeof(struct mod_list));
+	  mod->mod_name = mod_name;
+	  mod->symbols_loaded = 0;
+	  mod->objfile = 0;
+	  mod->from_tty = from_tty;
+	  mod->text_addr = (CORE_ADDR)ldr_rec.text;
+	  mod->data_addr = (CORE_ADDR)ldr_rec.data;
+	  mod->rodata_addr = (CORE_ADDR)ldr_rec.rodata;
+	  mod->bss_addr = (CORE_ADDR)ldr_rec.bss;
+	  mod->commons = (CORE_ADDR)ldr_rec.commons;
+	  mod->commonslen = ldr_rec.commonslen;
+	  mod->next = mod_list_head;
+	  mod_list_head = mod;
+
+      } else
+      {
+	  free(mod_name);
+      }
+      modrec_addr = (CORE_ADDR)ldr_rec.next;
+    }
+  }
+}
+
+/*
+ * This is a bit of a hack - but I can't see a way around it at the moment
+ *
+ * The loader in the X server may obtain space for the loadable sections of the
+ * module using malloc - this means that you can't relocate things from a
+ * single load address and we must supply correct section ofsets.
+ *
+ * som_symfile_offsets does more-or-less the same thing.
+ * 
+ * The default default_symfile_offsets is #if'ed out if module support
+ * is compiled in
+ */
+
+/*struct section_offsets * */
+/*
+void default_symfile_offsets (struct objfile *objfile, CORE_ADDR addr)
+{
+  struct section_offsets *section_offsets;
+  struct mod_list *mod;
+
+  int i;
+
+  objfile->num_sections = SECT_OFF_MAX;
+  section_offsets = (struct section_offsets *)
+    obstack_alloc (&objfile->psymbol_obstack, SIZEOF_SECTION_OFFSETS);
+
+  for (i = 0; i < SECT_OFF_MAX; i++)
+    ANOFFSET (section_offsets, i) = addr;
+  
+  for (mod = mod_list_head; mod; mod = mod->next)
+      if  (mod->being_read)
+      {
+	  ANOFFSET (section_offsets, SECT_OFF_TEXT) = mod->text_addr;
+	  ANOFFSET (section_offsets, SECT_OFF_DATA) = mod->data_addr;
+	  ANOFFSET (section_offsets, SECT_OFF_RODATA) = mod->rodata_addr;
+	  ANOFFSET (section_offsets, SECT_OFF_BSS) = mod->bss_addr;
+	  break;
+      }
+
+  return section_offsets;
+}
+*/
+
+/* A small stub to get us past the arg-passing pinhole of catch_errors.  */
+static int module_add_stub (char *arg)
+{
+    struct mod_list *mod = (struct mod_list *) arg;
+    struct section_addr_info text_addr;
+
+    text_addr.other[0].name = mod->mod_name;
+    text_addr.other[0].addr = mod->text_addr;
+    
+    mod->objfile = symbol_file_add (mod->mod_name, mod->from_tty,
+                                    &text_addr, 0, OBJF_SHARED);
+    return (1);
+}
+
+void
+xfreemod_add (arg_string, from_tty, target)
+char *arg_string;
+int from_tty;
+struct target_ops *target;
+{
+  struct mod_list *mod;
+  char *re_err;
+  
+  if ((re_err = re_comp (arg_string ? arg_string : ".")) != NULL)
+  {
+    error ("Invalid regexp: %s", re_err);
+  }
+
+  add_modules(from_tty);
+  for (mod = mod_list_head; mod; mod = mod->next)
+    if (mod->mod_name[0] && re_exec (mod->mod_name))
+    {
+      mod->from_tty = from_tty;
+      if (mod->symbols_loaded)
+      {
+	if (from_tty)
+	{
+	  printf_unfiltered ("Symbols already loaded for %s\n", mod->mod_name);
+	}
+      }
+      else
+      {
+	mod->being_read = 1;
+	if ((mod->symbols_loaded =
+	     catch_errors((catch_errors_ftype *)module_add_stub, (char *) mod,
+	     "Error while reading server module symbols:\n",
+	     RETURN_MASK_ALL)))
+	  add_common_symbols(mod);
+	mod->being_read = 0;
+      }
+    }
+}
+
+/* Request reading of module's symbols */
+static void module_command (char *args, int from_tty)
+{
+  dont_repeat ();
+  xfreemod_add(args, from_tty, (struct target_ops *) 0);
+}
+
+/* List currently known modules and the status of each */
+static void info_modules_command (char *ignore, int from_tty)
+{
+  struct mod_list *mod;
+  int header_done = 0;
+  int addr_width;
+  char *addr_fmt;
+
+  if (exec_bfd == NULL)
+  {
+    printf_unfiltered ("No exec file.\n");
+    return;
+  }
+
+#ifndef TARGET_ELF64
+  addr_width = 8+4;
+  addr_fmt = "08l";
+#else
+  addr_width = 16+4;
+  addr_fmt = "016l";
+#endif
+
+  for (mod = mod_list_head; mod; mod = mod->next)
+  {
+    if (!header_done)
+    {
+      printf_unfiltered("%-*s%-*s%-12s%s\n", addr_width, "Text",
+			addr_width, "Data", "Syms Read",
+			"Module File");
+      header_done++;
+    }
+    printf_unfiltered ("%-*s", addr_width,
+		       local_hex_string_custom (mod->text_addr, addr_fmt));
+    printf_unfiltered ("%-*s", addr_width,
+		       local_hex_string_custom (mod->data_addr, addr_fmt));
+    printf_unfiltered ("%-12s", mod->symbols_loaded ? "Yes" : "No");
+    printf_unfiltered ("%s\n",  mod->mod_name);
+  }
+  if (mod_list_head == NULL)
+  {
+    printf_unfiltered ("No modules loaded at this time.\n");	
+  }
+}
+
+void _initialize_xfreemod(void)
+{
+  add_com ("module", class_files, module_command,
+	   "Load shared object library symbols for files matching REGEXP.");
+  add_info ("modules", info_modules_command, 
+	    "Status of loaded shared object libraries.");
+}
--- gdb/symfile.h.xfree86-modules	Tue Mar  6 03:21:17 2001
+++ gdb/symfile.h	Sun Sep 23 14:32:17 2001
@@ -241,7 +241,7 @@
 
 extern void find_lowest_section (bfd *, asection *, PTR);
 
-extern bfd *symfile_bfd_open (char *);
+extern bfd *symfile_bfd_open (char *, bfd_format);
 
 /* Utility functions for overlay sections: */
 extern int overlay_debugging;
--- gdb/elfread.c.xfree86-modules	Tue May 29 06:45:10 2001
+++ gdb/elfread.c	Sun Sep 23 14:51:22 2001
@@ -289,7 +289,7 @@
 	      symaddr = sym->value;
 	      if (symaddr == 0)
 		continue;
-	      symaddr += offset;
+	      symaddr += ANOFFSET (objfile->section_offsets, 0);
 	      msym = record_minimal_symbol_and_info
 		((char *) sym->name, symaddr,
 		 mst_solib_trampoline, NULL, sym->section, objfile);
@@ -331,10 +331,26 @@
 	         interested in will have a section. */
 	      /* Bfd symbols are section relative. */
 	      symaddr = sym->value + sym->section->vma;
-	      /* Relocate all non-absolute symbols by the section offset.  */
-	      if (sym->section != &bfd_abs_section)
+	      /* Relocate all non-absolute symbols.  */
+	      if (STREQ (sym->section->name, ".text"))
 		{
-		  symaddr += offset;
+		  symaddr += ANOFFSET (objfile->section_offsets, SECT_OFF_TEXT(objfile));
+		}
+	      else if (STREQ (sym->section->name, ".data"))
+		{
+		  symaddr += ANOFFSET (objfile->section_offsets, SECT_OFF_DATA(objfile));
+		}
+	      else if (STREQ (sym->section->name, ".bss"))
+		{
+		  symaddr += ANOFFSET (objfile->section_offsets, SECT_OFF_BSS(objfile));
+		}
+	      else if (STREQ (sym->section->name, ".rodata"))
+		{
+		  symaddr += ANOFFSET (objfile->section_offsets, SECT_OFF_RODATA(objfile));
+		}
+	      else if (sym->section != &bfd_abs_section)
+		{
+		  symaddr += ANOFFSET (objfile->section_offsets, SECT_OFF_TEXT(objfile));
 		}
 	      /* For non-absolute symbols, use the type of the section
 	         they are relative to, to intuit text/data.  Bfd provides
@@ -368,7 +384,7 @@
 		    {
 		      if (sym->name[0] == '.')
 			continue;
-		      symaddr += offset;
+		      symaddr += ANOFFSET (objfile->section_offsets, 0);
 		    }
 		}
 	      else if (sym->section->flags & SEC_CODE)
@@ -473,7 +489,7 @@
 			  /* Relocate non-absolute symbols by the section offset. */
 			  if (sym->section != &bfd_abs_section)
 			    {
-			      symaddr += offset;
+			      symaddr += ANOFFSET (objfile->section_offsets, 0);
 			    }
 			  if (index != -1)
 			    sectinfo->sections[index] = symaddr;
--- gdb/xfreemod.h.xfree86-modules	Sun Sep 23 14:32:17 2001
+++ gdb/xfreemod.h	Sun Sep 23 14:32:17 2001
@@ -0,0 +1,69 @@
+/* Handle XFree dynamically loaded modules
+   
+This file is not an official 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
+(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 <sys/types.h>
+
+#ifndef SOLIB_ADD
+#error  XFree module support requires shared library support
+#endif
+
+#define XFREE_MODULE_SUPPORT
+
+#ifdef __STDC__		/* Forward decl's for prototypes */
+struct target_ops;
+#endif
+
+/* XFree loader Interface to GDB */
+typedef	struct {
+	unsigned char *name;       /* Name of this symbol */
+	unsigned int  namelen;     /* Name of this module */
+	void          *addr;	   /* Start address of the .text section */
+} LDRCommon, *LDRCommonPtr;
+
+typedef	struct {
+	unsigned int  version;     /* Version of this struct */
+	unsigned char *name;       /* Name of this module */
+	unsigned int  namelen;     /* Length of name */
+	void          *text;	   /* Start address of the .text section */
+	void          *data;	   /* Start address of the .data section */
+	void          *rodata;	   /* Start address of the .rodata section */
+	void          *bss;	   /* Start address of the .bss section */
+        LDRCommonPtr  commons;     /* List of commmon symbols */
+        int           commonslen;  /* Number of common symbols */
+	struct LDRModuleRec *next; /* Next module record in chain */
+} LDRModuleRec, *LDRModulePtr;
+
+/* Local copy of above */
+struct mod_list {
+    struct mod_list *next;	/* next structure in linked list */
+    char *mod_name;		/* module name */
+    char symbols_loaded;	/* flag: symbols read in yet? */
+    char from_tty;		/* flag: print msgs? */
+    struct objfile *objfile;	/* objfile for loaded module */
+    CORE_ADDR text_addr;	/* Address at which text was loaded */
+    CORE_ADDR data_addr;	/* Address at which data was loaded */
+    CORE_ADDR rodata_addr;	/* Address at which read-only data was loaded */
+    CORE_ADDR bss_addr;		/* Address at which bss was loaded */
+    CORE_ADDR commons;		/* List of commmon symbols */
+    int commonslen;		/* Number of common symbols */
+    int being_read;             /* Somewhat hacky, used to identify module for offsets */
+};
+
+extern void xfreemod_create_inferior_hook();
+extern void xfreemod_add PARAMS ((char *, int, struct target_ops *));
+
--- gdb/symfile.c.xfree86-modules	Sun Jul 15 14:57:06 2001
+++ gdb/symfile.c	Sun Sep 23 14:32:17 2001
@@ -118,7 +118,7 @@
 
 static void cashier_psymtab (struct partial_symtab *);
 
-bfd *symfile_bfd_open (char *);
+/*bfd *symfile_bfd_open (char *);*/
 
 static void find_sym_fns (struct objfile *);
 
@@ -804,10 +804,70 @@
   struct partial_symtab *psymtab;
   bfd *abfd;
 
-  /* Open a bfd for the file, and give user a chance to burp if we'd be
-     interactively wiping out any existing symbols.  */
+#ifdef XFREE_MODULE_SUPPORT
+  struct cleanup *old_chain;
+  char *p;
+  /* Make a copy of the string that we can safely write into. */
+
+  name = strdup (name);
+  old_chain = make_cleanup(free, name);
+
+  p = strstr(name, ".a:");
+  if (p)
+  {
+      bfd *archive_bfd;
+      char *component_name = p + 3;
+      *(p+2) = 0;
+      archive_bfd = symfile_bfd_open (name, bfd_archive);
+
+      /* Look for the archive member that we want
+       *
+       * FIXME - we will be invoked several times for the same archive
+       * all this opening, closing and scanning is going to be dreadfully
+       * slow.
+       */
+      for (abfd = bfd_openr_next_archived_file (archive_bfd, NULL);
+	   abfd;
+	   abfd = bfd_openr_next_archived_file (archive_bfd, abfd))
+      {
+	  if (abfd->filename == NULL)
+	  {
+	      /* Some archive formats don't get the filenames filled in
+		 until the elements are opened.  */
+	      struct stat buf;
+	      bfd_stat_arch_elt (abfd, &buf);
+	  }
+	  /* printf_unfiltered("%s %s\n", abfd->filename, component_name); */
+	  if ((abfd->filename != NULL) &&
+	      (!strcmp (component_name, abfd->filename)))
+	  {
+	      break;
+	  }
+	  make_cleanup(bfd_close, abfd);
+	}
+      if (!bfd_check_format (abfd, bfd_object))
+      {
+	  /* FIXME: should be checking for errors from bfd_close (for one thing,
+	     on error it does not free all the storage associated with the
+	     bfd).  */
+	  bfd_close (archive_bfd);
+	  error ("\"%s\": can't read symbols: %s:%s.", name, component_name,
+		 bfd_errmsg (bfd_get_error ()));
+      }
+      /* The bfd filename points into the bfd's internal storage,
+	 not to a block obtained directly from malloc.
+	 Replace it with a copy so that free_objfile does not
+	 pass a bogus pointer to free */
+      bfd_get_filename (abfd) = strdup(bfd_get_filename (abfd));
+  }
+#endif
+  else
+  {
+      /* Open a bfd for the file, and give user a chance to burp if we'd be
+	 interactively wiping out any existing symbols.  */
 
-  abfd = symfile_bfd_open (name);
+      abfd = symfile_bfd_open (name, bfd_object);
+  }
 
   if ((have_full_symbols () || have_partial_symbols ())
       && mainline
@@ -892,6 +952,9 @@
   if (target_new_objfile_hook)
     target_new_objfile_hook (objfile);
 
+#ifdef XFREE_MODULE_SUPPORT
+  do_cleanups(old_chain);
+#endif
   return (objfile);
 }
 
@@ -1052,7 +1115,7 @@
    In case of trouble, error() is called.  */
 
 bfd *
-symfile_bfd_open (char *name)
+symfile_bfd_open (char *name, bfd_format format)
 {
   bfd *sym_bfd;
   int desc;
@@ -1092,7 +1155,7 @@
     }
   sym_bfd->cacheable = true;
 
-  if (!bfd_check_format (sym_bfd, bfd_object))
+  if (!bfd_check_format (sym_bfd, format))
     {
       /* FIXME: should be checking for errors from bfd_close (for one thing,
          on error it does not free all the storage associated with the

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