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]

Patching gdb 5.0 for XFree86 module support


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.

My goal is to get this patch sync'd with current gdb that will 
ship with the next version of Red Hat Linux, and provide it on 
ftp://people.redhat.com/mharris and elsewhere for people to snag 
a copy.

When I started this the other day, I had never looked at gdb 
source before, so bear with me.  ;o)

I first ported the patch to at least apply cleanly to current
source, making some guesses along the way when not 100% sure what
was correct.  I've fixed all compilation warnings and all
compilation errors but one now, which I'm not yet sure how to
resolve as I'm not too familiar with gdb internals.

gcc -c -O2 -march=i386 -mcpu=i686 -DXFREE_MODULE_SUPPORT    -I. 
-I. -I./config -DHAVE_CONFIG_H -I./../include/opcode 
-I./../readline/.. -I../bfd -I./../bfd  -I./../include -I../intl 
-I./../intl  -DMI_OUT=1 -DUI_OUT=1 -Wimplicit -Wreturn-type 
-Wcomment -Wtrigraphs -Wformat -Wparentheses -Wpointer-arith 
-Wuninitialized  xfreemod.c
xfreemod.c: In function `module_add_stub':
xfreemod.c:241: too many arguments to function `symbol_file_add'
make[1]: *** [xfreemod.o] Error 1
make[1]: Leaving directory 
`/home/mharris/rpmbuild/BUILD/gdb+dejagnu-20010813/gdb'
make: *** [all-gdb] Error 2
Bad exit status from /home/mharris/rpmbuild/tmp/rpm-tmp.60784 
(%build)

For those willing to help, or offer advice, I've put my SRPM at:

ftp://people.redhat.com/mharris/hacks/gdb-5.0rh-15.4xfree.src.rpm

The patch is also attached to this message as well, and contains 
further comments on my progress, etc.

I'd be greatful for any suggestions anyone may have that help get
this working.  Also, what is the best list for such discussion?

Thanks in advance for any help.


----------------------------------------------------------------------
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 0.5

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 non-functional,
but applies cleanly to gdb sources.  It fails compilation at:

xfreemod.c: In function `module_add_stub':
xfreemod.c:241: too many arguments to function `symbol_file_add'
make[1]: *** [xfreemod.o] Error 1

I've investigated this somewhat, and the xfreemod.c file is calling
symbol_file_add() with 8 arguments.  The current gdb 5.0rh function
has only 5 args, and the gdb 4.18 source the patch was originally against,
aparently has only 7 args.  It is not yet clear to me what the proper
way of fixing this is, as I'm not a gdb expert.  Checking the gdb
changelogs shows various changes have occured to symbol_file_add(), and
suggests that symbol_file_add_main_1() might be what we need now...

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"

I can supply my specfile or a src.rpm to anyone interested, please email
me if you want to help get this going.  Once this works, I plan on
releasing 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 07:53:12 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 07:53:12 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 07:53:12 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 07:53:12 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 07:53:12 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 07:53:12 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 07:53:12 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 07:53:12 2001
+++ gdb/xfreemod.c	Sun Sep 23 08:01:57 2001
@@ -0,0 +1,341 @@
+/* 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;
+    
+    CORE_ADDR text_addr = mod->text_addr;
+    
+    mod->objfile =
+	symbol_file_add (mod->mod_name, mod->from_tty, 0, 0, 0, 0, 0, 1);
+    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 07:53:12 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 07:53:12 2001
@@ -74,7 +74,7 @@
 
 static void elf_symfile_finish (struct objfile *);
 
-static void elf_symtab_read (struct objfile *, int);
+static void elf_symtab_read (bfd *, struct section_offsets *, struct objfile *, int);
 
 static void free_elfinfo (PTR);
 
@@ -207,7 +207,7 @@
  */
 
 static void
-elf_symtab_read (struct objfile *objfile, int dynamic)
+elf_symtab_read (bfd *abfd, struct section_offsets *section_offsets, struct objfile *objfile, int dynamic)
 {
   long storage_needed;
   asymbol *sym;
@@ -289,7 +289,7 @@
 	      symaddr = sym->value;
 	      if (symaddr == 0)
 		continue;
-	      symaddr += offset;
+	      symaddr += ANOFFSET (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 (section_offsets, SECT_OFF_TEXT);
+		}
+	      else if (STREQ (sym->section->name, ".data"))
+		{
+		  symaddr += ANOFFSET (section_offsets, SECT_OFF_DATA);
+		}
+	      else if (STREQ (sym->section->name, ".bss"))
+		{
+		  symaddr += ANOFFSET (section_offsets, SECT_OFF_BSS);
+		}
+	      else if (STREQ (sym->section->name, ".rodata"))
+		{
+		  symaddr += ANOFFSET (section_offsets, SECT_OFF_RODATA);
+		}
+	      else if (sym->section != &bfd_abs_section)
+		{
+		  symaddr += ANOFFSET (section_offsets, SECT_OFF_TEXT);
 		}
 	      /* 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 (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 (section_offsets, 0);
 			    }
 			  if (index != -1)
 			    sectinfo->sections[index] = symaddr;
@@ -582,11 +598,11 @@
      chain of info into the dbx_symfile_info in objfile->sym_stab_info,
      which can later be used by elfstab_offset_sections.  */
 
-  elf_symtab_read (objfile, 0);
+  elf_symtab_read (abfd, section_offsets, objfile, 0);
 
   /* Add the dynamic symbols.  */
 
-  elf_symtab_read (objfile, 1);
+  elf_symtab_read (abfd, section_offsets, objfile, 1);
 
   /* Now process debugging information, which is contained in
      special ELF sections. */
--- gdb/xfreemod.h.xfree86-modules	Sun Sep 23 07:53:12 2001
+++ gdb/xfreemod.h	Sun Sep 23 07:53:12 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 07:53:12 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]