Index: gdb/gdb/breakpoint.c diff -u gdb/gdb/breakpoint.c:1.1.1.6 gdb/gdb/breakpoint.c:1.1.1.6.2.2 --- gdb/gdb/breakpoint.c:1.1.1.6 Sat Jan 14 17:06:52 2006 +++ gdb/gdb/breakpoint.c Mon Jan 23 15:17:07 2006 @@ -1,3 +1,4 @@ +/* $XOZ: gdb/gdb/breakpoint.c,v 1.1.1.6.2.2 2006/01/23 20:17:07 dawes Exp $ */ /* Everything about breakpoints, for GDB. Copyright 1986, 1987, 1988, 1989, 1990, 1991, 1992, 1993, 1994, @@ -235,6 +236,8 @@ extern int addressprint; /* Print machine addresses? */ +static int internal_breakpoint_number = -1; + /* Are we executing breakpoint commands? */ static int executing_breakpoint_commands; @@ -1264,7 +1267,7 @@ ALL_BREAKPOINTS_SAFE (b, temp) { /* Solib breakpoints must be explicitly reset after an exec(). */ - if (b->type == bp_shlib_event) + if (b->type == bp_shlib_event || b->type == bp_xfree86mod_event) { delete_breakpoint (b); continue; @@ -2130,6 +2133,14 @@ return PRINT_NOTHING; break; + case bp_xfree86mod_event: + /* Did we stop because the user set the stop_on_solib_events + variable? (If so, we report this as a generic, "Stopped due + to shlib event" message.) */ + printf_filtered ("Stopped due to XFree86 module event\n"); + return PRINT_NOTHING; + break; + case bp_thread_event: /* Not sure how we will get here. GDB should not stop for these breakpoints. */ @@ -3136,6 +3147,7 @@ bs_class = bp_nostop; break; case bp_shlib_event: + case bp_xfree86mod_event: bs_class = shlib_event; break; case bp_thread_event: @@ -3321,7 +3333,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_xfree86mod_event, "XFree86 module events"} }; static char *bpdisps[] = @@ -3477,6 +3490,7 @@ case bp_shlib_event: case bp_thread_event: case bp_overlay_event: + case bp_xfree86mod_event: if (addressprint) { annotate_field (4); @@ -4016,6 +4030,7 @@ case bp_watchpoint_scope: case bp_call_dummy: case bp_shlib_event: + case bp_xfree86mod_event: case bp_thread_event: case bp_overlay_event: case bp_catch_load: @@ -4142,7 +4157,6 @@ static struct breakpoint * create_internal_breakpoint (CORE_ADDR address, enum bptype type) { - static int internal_breakpoint_number = -1; struct symtab_and_line sal; struct breakpoint *b; @@ -4349,6 +4363,32 @@ return rc; } +#ifdef XFREE86_MODULE_SUPPORT +void remove_xfree86mod_event_breakpoints (void) +{ + register struct breakpoint *b, *temp; + + ALL_BREAKPOINTS_SAFE (b, temp) + if (b->type == bp_xfree86mod_event) + delete_breakpoint (b); +} + +void create_xfree86mod_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_xfree86mod_event); + b->number = internal_breakpoint_number--; + b->disposition = disp_donttouch; + b->type = bp_xfree86mod_event; + +} +#endif + void remove_solib_event_breakpoints (void) { @@ -4879,6 +4919,7 @@ case bp_shlib_event: case bp_thread_event: case bp_overlay_event: + case bp_xfree86mod_event: break; } @@ -6955,6 +6996,7 @@ b->type != bp_shlib_event && b->type != bp_thread_event && b->type != bp_overlay_event && + b->type != bp_xfree86mod_event && b->number >= 0) breaks_to_delete = 1; } @@ -6969,6 +7011,7 @@ b->type != bp_shlib_event && b->type != bp_thread_event && b->type != bp_overlay_event && + b->type != bp_xfree86mod_event && b->number >= 0) delete_breakpoint (b); } @@ -7200,6 +7243,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_xfree86mod_event: /* Like bp_shlib_event, this breakpoint type is special. Once it is set up, we do not want to touch it. */ Index: gdb/gdb/breakpoint.h diff -u gdb/gdb/breakpoint.h:1.1.1.4 gdb/gdb/breakpoint.h:1.1.1.4.2.1 --- gdb/gdb/breakpoint.h:1.1.1.4 Sat Jan 14 17:06:53 2006 +++ gdb/gdb/breakpoint.h Mon Jan 23 11:47:35 2006 @@ -1,3 +1,4 @@ +/* $XOZ: gdb/gdb/breakpoint.h,v 1.1.1.4.2.1 2006/01/23 16:47:35 dawes Exp $ */ /* Data structures associated with breakpoints in GDB. Copyright 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004 @@ -138,7 +139,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_xfree86mod_event + }; @@ -759,10 +765,14 @@ extern struct breakpoint *create_thread_event_breakpoint (CORE_ADDR); +extern void create_xfree86mod_event_breakpoint (CORE_ADDR); + extern void remove_solib_event_breakpoints (void); extern void remove_thread_event_breakpoints (void); +extern void remove_xfree86mod_event_breakpoints (void); + extern void disable_breakpoints_in_shlibs (int silent); extern void re_enable_breakpoints_in_shlibs (void); Index: gdb/gdb/dbxread.c diff -u gdb/gdb/dbxread.c:1.1.1.5 gdb/gdb/dbxread.c:1.1.1.5.2.1 --- gdb/gdb/dbxread.c:1.1.1.5 Sat Jan 14 17:07:00 2006 +++ gdb/gdb/dbxread.c Mon Jan 23 11:47:35 2006 @@ -1,3 +1,4 @@ +/* $XOZ: gdb/gdb/dbxread.c,v 1.1.1.5.2.1 2006/01/23 16:47:35 dawes Exp $ */ /* Read dbx symbol tables and convert to internal format, for GDB. Copyright 1986, 1987, 1988, 1989, 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004. @@ -1118,7 +1119,7 @@ do_cleanups (back_to); } -#ifdef SOFUN_ADDRESS_MAYBE_MISSING +#if defined(SOFUN_ADDRESS_MAYBE_MISSING) || defined(XFREE86_MODULE_SUPPORT) static CORE_ADDR find_stab_function_addr (char *namestring, char *filename, struct objfile *objfile) @@ -3095,7 +3096,7 @@ case 'F': function_stab_type = type; -#ifdef SOFUN_ADDRESS_MAYBE_MISSING +#if defined(SOFUN_ADDRESS_MAYBE_MISSING) || defined(XFREE86_MODULE_SUPPORT) /* Deal with the SunPRO 3.0 compiler which omits the address from N_FUN symbols. */ if (type == N_FUN Index: gdb/gdb/elfread.c diff -u gdb/gdb/elfread.c:1.1.1.5 gdb/gdb/elfread.c:1.1.1.5.2.1 --- gdb/gdb/elfread.c:1.1.1.5 Sat Jan 14 17:07:03 2006 +++ gdb/gdb/elfread.c Mon Jan 23 11:47:36 2006 @@ -1,3 +1,4 @@ +/* $XOZ: gdb/gdb/elfread.c,v 1.1.1.5.2.1 2006/01/23 16:47:36 dawes Exp $ */ /* Read ELF (Executable and Linking Format) object files for GDB. Copyright 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, @@ -194,7 +195,7 @@ symaddr = sym->value; if (symaddr == 0) continue; - symaddr += offset; + symaddr += ANOFFSET (objfile->section_offsets, 0); msym = record_minimal_symbol ((char *) sym->name, symaddr, mst_solib_trampoline, sym->section, objfile); @@ -238,10 +239,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 (strcmp (sym->section->name, ".text") == 0) { - symaddr += offset; + symaddr += ANOFFSET (objfile->section_offsets, SECT_OFF_TEXT(objfile)); + } + else if (strcmp (sym->section->name, ".data") == 0) + { + symaddr += ANOFFSET (objfile->section_offsets, SECT_OFF_DATA(objfile)); + } + else if (strcmp (sym->section->name, ".bss") == 0) + { + symaddr += ANOFFSET (objfile->section_offsets, SECT_OFF_BSS(objfile)); + } + else if (strcmp (sym->section->name, ".rodata") == 0) + { + 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 @@ -275,7 +292,7 @@ { if (sym->name[0] == '.') continue; - symaddr += offset; + symaddr += ANOFFSET (objfile->section_offsets, 0); } } else if (sym->section->flags & SEC_CODE) @@ -376,7 +393,7 @@ /* Relocate non-absolute symbols by the section offset. */ if (sym->section != &bfd_abs_section) - symaddr += offset; + symaddr += ANOFFSET (objfile->section_offsets, 0); sectinfo->sections[special_local_sect] = symaddr; /* The special local symbols don't go in the minimal symbol table, so ignore this one. */ Index: gdb/gdb/fork-child.c diff -u gdb/gdb/fork-child.c:1.1.1.3 gdb/gdb/fork-child.c:1.1.1.3.2.1 --- gdb/gdb/fork-child.c:1.1.1.3 Sat Jan 14 17:07:06 2006 +++ gdb/gdb/fork-child.c Mon Jan 23 11:47:36 2006 @@ -1,3 +1,4 @@ +/* $XOZ: gdb/gdb/fork-child.c,v 1.1.1.3.2.1 2006/01/23 16:47:36 dawes Exp $ */ /* Fork a Unix child process, and set up to debug it, for GDB. Copyright 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1998, 1999, @@ -409,6 +410,9 @@ #else solib_create_inferior_hook (); #endif +#ifdef XFREE86_MODULE_SUPPORT + xfree86mod_create_inferior_hook(pid); +#endif } /* Accept NTRAPS traps from the inferior. */ Index: gdb/gdb/infrun.c diff -u gdb/gdb/infrun.c:1.1.1.5 gdb/gdb/infrun.c:1.1.1.5.2.1 --- gdb/gdb/infrun.c:1.1.1.5 Sat Jan 14 17:07:20 2006 +++ gdb/gdb/infrun.c Mon Jan 23 11:47:36 2006 @@ -1,3 +1,4 @@ +/* $XOZ: gdb/gdb/infrun.c,v 1.1.1.5.2.1 2006/01/23 16:47:36 dawes Exp $ */ /* Target-struct-independent code to start (run) and stop an inferior process. @@ -1316,9 +1317,9 @@ if (breakpoints_inserted) remove_breakpoints (); - /* Check for any newly added shared libraries if we're - supposed to be adding them automatically. Switch - terminal for any messages produced by + /* Check for any newly added shared libraries or XFree86 + modules if we're supposed to be adding them automatically. + Switch terminal for any messages produced by breakpoint_re_set. */ target_terminal_ours_for_output (); /* NOTE: cagney/2003-11-25: Make certain that the target @@ -1337,6 +1338,9 @@ to propagate relevant changes (stop, section table changed, ...) up to other layers. */ SOLIB_ADD (NULL, 0, ¤t_target, auto_solib_add); +#ifdef XFREE86_MODULE_SUPPORT + xfree86mod_add (NULL, 0, NULL); +#endif target_terminal_inferior (); /* Reinsert breakpoints and continue. */ @@ -2171,6 +2175,9 @@ #else solib_add (NULL, 0, ¤t_target, auto_solib_add); #endif +#ifdef XFREE86_MODULE_SUPPORT + xfree86mod_add (NULL, 0, NULL); +#endif target_terminal_inferior (); /* Try to reenable shared library breakpoints, additional Index: gdb/gdb/symfile.c diff -u gdb/gdb/symfile.c:1.1.1.5 gdb/gdb/symfile.c:1.1.1.5.2.1 --- gdb/gdb/symfile.c:1.1.1.5 Sat Jan 14 17:07:47 2006 +++ gdb/gdb/symfile.c Mon Jan 23 11:47:36 2006 @@ -1,3 +1,4 @@ +/* $XOZ: gdb/gdb/symfile.c,v 1.1.1.5.2.1 2006/01/23 16:47:36 dawes Exp $ */ /* Generic symbol file reading for the GNU debugger, GDB. Copyright 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998, @@ -103,8 +104,6 @@ static void cashier_psymtab (struct partial_symtab *); -bfd *symfile_bfd_open (char *); - int get_section_index (struct objfile *, char *); static void find_sym_fns (struct objfile *); @@ -563,7 +562,7 @@ struct other_sections *osp ; osp = &addrs->other[i] ; - if (osp->addr == 0) + if (osp->addr == 0 || osp->sectindex < 0) continue; /* Record all sections in offsets */ @@ -727,17 +726,17 @@ for (i = 0; i < addrs->num_sections && addrs->other[i].name; i++) { + sect = bfd_get_section_by_name (objfile->obfd, addrs->other[i].name); + /* This is the index used by BFD. */ + addrs->other[i].sectindex = sect ? sect->index : -1 ; + if (addrs->other[i].addr != 0) { - sect = bfd_get_section_by_name (objfile->obfd, - addrs->other[i].name); if (sect) { addrs->other[i].addr -= bfd_section_vma (objfile->obfd, sect); lower_offset = addrs->other[i].addr; - /* This is the index used by BFD. */ - addrs->other[i].sectindex = sect->index ; } else { @@ -1049,8 +1048,73 @@ symbol_file_add (char *name, int from_tty, struct section_addr_info *addrs, int mainline, int flags) { - return symbol_file_add_from_bfd (symfile_bfd_open (name), from_tty, - addrs, mainline, flags); +#ifdef XFREE86_MODULE_SUPPORT + char *p; + struct cleanup *my_cleanups; + bfd *abfd; + struct objfile *ret; + + /* Make a copy of the string that we can safely write into. */ + name = xstrdup(name); + my_cleanups = make_cleanup (xfree, 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); + } +#if 0 + printf_unfiltered("%s %s\n", abfd->filename, component_name); +#endif + 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) = xstrdup (bfd_get_filename (abfd)); + ret = symbol_file_add_from_bfd (abfd, from_tty, addrs, mainline, flags); + do_cleanups (my_cleanups); + return ret; + } + else +#endif + return symbol_file_add_from_bfd (symfile_bfd_open (name, bfd_object), + from_tty, addrs, mainline, flags); } @@ -1345,7 +1409,7 @@ absolute). 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; @@ -1386,7 +1450,7 @@ } bfd_set_cacheable (sym_bfd, 1); - 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 @@ -2185,7 +2249,7 @@ Preserve the flags from objfile that make sense. */ objfile->separate_debug_objfile = (symbol_file_add_with_addrs_or_offsets - (symfile_bfd_open (debug_file), + (symfile_bfd_open (debug_file, bfd_object), info_verbose, /* from_tty: Don't override the default. */ 0, /* No addr table. */ objfile->section_offsets, objfile->num_sections, Index: gdb/gdb/symfile.h diff -u gdb/gdb/symfile.h:1.1.1.4 gdb/gdb/symfile.h:1.1.1.4.2.1 --- gdb/gdb/symfile.h:1.1.1.4 Sat Jan 14 16:44:41 2006 +++ gdb/gdb/symfile.h Mon Jan 23 11:47:36 2006 @@ -1,3 +1,4 @@ +/* $XOZ: gdb/gdb/symfile.h,v 1.1.1.4.2.1 2006/01/23 16:47:36 dawes Exp $ */ /* Definitions for reading symbol files into GDB. Copyright 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998, @@ -267,7 +268,7 @@ extern void find_lowest_section (bfd *, asection *, void *); -extern bfd *symfile_bfd_open (char *); +extern bfd *symfile_bfd_open (char *, bfd_format); extern int get_section_index (struct objfile *, char *); Index: gdb/gdb/xfree86mod.c diff -u /dev/null gdb/gdb/xfree86mod.c:1.1.6.3 --- /dev/null Mon Jan 23 15:18:12 2006 +++ gdb/gdb/xfree86mod.c Mon Jan 23 14:59:23 2006 @@ -0,0 +1,341 @@ +/* $XOZ: gdb/gdb/xfree86mod.c,v 1.1.6.3 2006/01/23 19:59:23 dawes Exp $ */ +/* Handle XFree86 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. */ + +/* + * The XFree86 module support for gdb was written by Paul Flinders + * for gdb 4.17, and later updated for gdb 5.1. + * See http://www.dawa.demon.co.uk/xfree-gdb for Paul's patches. + * + * Paul's work was updated for gdb 6.0 by Michal Ludvig . + * + * Further updates/fixes by David Dawes : + * + * - Add support for building on some other ELF platforms (Solaris/x86, + * FreeBSD). + * - Adapt for gdb 6.4. + * - Fixed a bug that prevented auto-reading of module symbols. + * + * TODO: + * + * - Add support for other XFree86 platforms. + * - Add support for unloaded and reloaded modules. + * - Autoload modules symbols when debugging a core that has modules loaded. + */ + + +#include "defs.h" + +#include "exceptions.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 "gdb_regex.h" + +/* The XFree86 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 *xfree86mod_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 +xfree86mod_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_xfree86mod_event_breakpoints (); + + /* And our copy of the inferior's modules */ + for (mod = mod_list_head; mod; mod = next_mod) + { + next_mod = mod->next; + xfree (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 = xfree86mod_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_xfree86mod_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 ((unsigned long) commons[i].name, + name, commons[i].namelen + 1); + prim_record_minimal_symbol (name, (unsigned long) commons[i].addr, + mst_bss, mod->objfile); + xfree (name); + } + install_minimal_symbols (mod->objfile); + xfree (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) + { + /* + * sizeof(void *) assumes native operation. The previous behaviour + * of using sizeof(CORE_ADDR) was incorrect, as evidenced by the + * default behaviour on Solaris/x86 of enabling 64-bit support. + */ + + int status = target_read_memory (SYMBOL_VALUE_ADDRESS (msymbol), + (char *) &modrec_addr, + sizeof (void *)); + 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 ((unsigned long) 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; + /* + * Fix signed/unsigned problem that shows up with the default + * Solaris build that uses a 64-bit CORE_ADDR. This assumes + * that sizeof(void *) <= sizeof(unsigned long). + */ + mod->text_addr = (unsigned long) ldr_rec.text; + mod->data_addr = (unsigned long) ldr_rec.data; + mod->rodata_addr = (unsigned long) ldr_rec.rodata; + mod->bss_addr = (unsigned long) ldr_rec.bss; + mod->commons = (unsigned long) ldr_rec.commons; + mod->commonslen = ldr_rec.commonslen; + mod->next = mod_list_head; + mod_list_head = mod; + + } + else + xfree (mod_name); + modrec_addr = (unsigned long) ldr_rec.next; + } + } +} + +/* A small stub to get us past the arg-passing pinhole of catch_errors. */ +static int +module_add_stub (void *arg) +{ + struct mod_list *mod = (struct mod_list *) arg; + struct section_addr_info *text_addr; + + text_addr = alloc_section_addr_info (4); + + text_addr->other[0].name = ".text"; + text_addr->other[0].addr = mod->text_addr; + text_addr->other[1].name = ".data"; + text_addr->other[1].addr = mod->data_addr; + text_addr->other[2].name = ".rodata"; + text_addr->other[2].addr = mod->rodata_addr; + text_addr->other[3].name = ".bss"; + text_addr->other[3].addr = mod->bss_addr; + + mod->objfile = symbol_file_add (mod->mod_name, mod->from_tty, + text_addr, 0, OBJF_SHARED); + return (1); +} + +void +xfree86mod_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 (); + xfree86mod_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; +#else + addr_width = 16; +#endif + + for (mod = mod_list_head; mod; mod = mod->next) + { + if (!header_done) + { + printf_unfiltered ("%-*s%-*s%-12s%s\n", addr_width + 4, "Text", + addr_width + 4, "Data", + "Syms Read", "Module File"); + header_done++; + } + printf_unfiltered ("%-*s", addr_width + 4, + hex_string_custom (mod->text_addr, addr_width)); + printf_unfiltered ("%-*s", addr_width + 4, + hex_string_custom (mod->data_addr, addr_width)); + 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_xfree86mod (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."); +} Index: gdb/gdb/xfree86mod.h diff -u /dev/null gdb/gdb/xfree86mod.h:1.1.6.1 --- /dev/null Mon Jan 23 15:18:12 2006 +++ gdb/gdb/xfree86mod.h Mon Jan 23 11:47:37 2006 @@ -0,0 +1,66 @@ +/* $XOZ: gdb/gdb/xfree86mod.h,v 1.1.6.1 2006/01/23 16:47:37 dawes Exp $ */ +/* Handle XFree86 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 + +#define XFREE86_MODULE_SUPPORT + +#ifdef __STDC__ /* Forward decl's for prototypes */ +struct target_ops; +#endif + +/* XFree86 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 xfree86mod_create_inferior_hook(); +extern void xfree86mod_add PARAMS ((char *, int, struct target_ops *)); + Index: gdb/gdb/config/nm-linux.h diff -u gdb/gdb/config/nm-linux.h:1.1.1.5 gdb/gdb/config/nm-linux.h:1.1.1.5.2.1 --- gdb/gdb/config/nm-linux.h:1.1.1.5 Sat Jan 14 17:08:09 2006 +++ gdb/gdb/config/nm-linux.h Mon Jan 23 11:47:40 2006 @@ -1,3 +1,4 @@ +/* $XOZ: gdb/gdb/config/nm-linux.h,v 1.1.1.5.2.1 2006/01/23 16:47:40 dawes Exp $ */ /* Native support for GNU/Linux. Copyright 1999, 2000, 2001, 2002, 2003, 2004, 2005 @@ -40,6 +41,7 @@ #ifdef HAVE_LINK_H #include "solib.h" /* Support for shared libraries. */ +#include "xfree86mod.h" /* Support for XFree86 modules. */ #endif Index: gdb/gdb/config/i386/fbsd.mh diff -u gdb/gdb/config/i386/fbsd.mh:1.1.1.4 gdb/gdb/config/i386/fbsd.mh:1.1.1.4.2.1 --- gdb/gdb/config/i386/fbsd.mh:1.1.1.4 Sat Jan 14 16:46:23 2006 +++ gdb/gdb/config/i386/fbsd.mh Mon Jan 23 11:47:45 2006 @@ -1,7 +1,8 @@ +# $XOZ: gdb/gdb/config/i386/fbsd.mh,v 1.1.1.4.2.1 2006/01/23 16:47:45 dawes Exp $ # Host: FreeBSD/i386 NATDEPFILES= fork-child.o inf-ptrace.o \ fbsd-nat.o i386-nat.o i386bsd-nat.o i386fbsd-nat.o \ - gcore.o bsd-kvm.o + gcore.o bsd-kvm.o xfree86mod.o NAT_FILE= nm-fbsd.h LOADLIBES= -lkvm Index: gdb/gdb/config/i386/i386sol2.mh diff -u gdb/gdb/config/i386/i386sol2.mh:1.1.1.5 gdb/gdb/config/i386/i386sol2.mh:1.1.1.5.2.1 --- gdb/gdb/config/i386/i386sol2.mh:1.1.1.5 Sat Jan 14 17:08:13 2006 +++ gdb/gdb/config/i386/i386sol2.mh Mon Jan 23 11:47:45 2006 @@ -1,4 +1,6 @@ +# $XOZ: gdb/gdb/config/i386/i386sol2.mh,v 1.1.1.5.2.1 2006/01/23 16:47:45 dawes Exp $ # Host: Solaris x86 NATDEPFILES= fork-child.o i386v4-nat.o i386-sol2-nat.o \ - procfs.o proc-api.o proc-events.o proc-flags.o proc-why.o gcore.o + procfs.o proc-api.o proc-events.o proc-flags.o proc-why.o gcore.o \ + xfree86mod.o NAT_FILE= nm-i386sol2.h Index: gdb/gdb/config/i386/i386v4.mh diff -u gdb/gdb/config/i386/i386v4.mh:1.1.1.2 gdb/gdb/config/i386/i386v4.mh:1.1.1.2.2.1 --- gdb/gdb/config/i386/i386v4.mh:1.1.1.2 Sat Jan 14 16:46:21 2006 +++ gdb/gdb/config/i386/i386v4.mh Mon Jan 23 11:47:45 2006 @@ -1,6 +1,7 @@ +# $XOZ: gdb/gdb/config/i386/i386v4.mh,v 1.1.1.2.2.1 2006/01/23 16:47:45 dawes Exp $ # Host: Intel 386 running SVR4 NAT_FILE= nm-i386v4.h -NATDEPFILES= corelow.o core-regset.o fork-child.o i386v4-nat.o \ +NATDEPFILES= corelow.o core-regset.o fork-child.o i386v4-nat.o xfree86mod.o \ solib.o solib-svr4.o solib-legacy.o \ procfs.o proc-api.o proc-events.o proc-flags.o proc-why.o Index: gdb/gdb/config/i386/linux.mh diff -u gdb/gdb/config/i386/linux.mh:1.1.1.3 gdb/gdb/config/i386/linux.mh:1.1.1.3.2.1 --- gdb/gdb/config/i386/linux.mh:1.1.1.3 Sat Jan 14 17:08:13 2006 +++ gdb/gdb/config/i386/linux.mh Mon Jan 23 11:47:45 2006 @@ -1,10 +1,11 @@ +# $XOZ: gdb/gdb/config/i386/linux.mh,v 1.1.1.3.2.1 2006/01/23 16:47:45 dawes Exp $ # Host: Intel 386 running GNU/Linux. NAT_FILE= nm-linux.h NATDEPFILES= inf-ptrace.o fork-child.o corelow.o \ core-aout.o i386-nat.o i386-linux-nat.o \ proc-service.o linux-thread-db.o gcore.o \ - linux-nat.o + linux-nat.o xfree86mod.o # The dynamically loaded libthread_db needs access to symbols in the # gdb executable. Index: gdb/gdb/config/i386/nbsdelf.mh diff -u gdb/gdb/config/i386/nbsdelf.mh:1.1.1.4 gdb/gdb/config/i386/nbsdelf.mh:1.1.1.4.2.1 --- gdb/gdb/config/i386/nbsdelf.mh:1.1.1.4 Sat Jan 14 16:46:23 2006 +++ gdb/gdb/config/i386/nbsdelf.mh Mon Jan 23 11:47:45 2006 @@ -1,6 +1,6 @@ # Host: NetBSD/i386 ELF NATDEPFILES= fork-child.o inf-ptrace.o \ - i386bsd-nat.o i386nbsd-nat.o bsd-kvm.o -NAT_FILE= solib.h + i386bsd-nat.o i386nbsd-nat.o bsd-kvm.o xfree86mod.o +NAT_FILE= nm-nbsd.h LOADLIBES= -lkvm Index: gdb/gdb/config/i386/nm-fbsd.h diff -u gdb/gdb/config/i386/nm-fbsd.h:1.1.1.5 gdb/gdb/config/i386/nm-fbsd.h:1.1.1.5.2.1 --- gdb/gdb/config/i386/nm-fbsd.h:1.1.1.5 Sat Jan 14 17:08:14 2006 +++ gdb/gdb/config/i386/nm-fbsd.h Mon Jan 23 11:47:45 2006 @@ -1,3 +1,4 @@ +/* $XOZ: gdb/gdb/config/i386/nm-fbsd.h,v 1.1.1.5.2.1 2006/01/23 16:47:45 dawes Exp $ */ /* Native-dependent definitions for FreeBSD/i386. Copyright 1986, 1987, 1989, 1992, 1994, 1996, 1997, 2000, 2001, @@ -55,5 +56,6 @@ /* Shared library support. */ #include "solib.h" +#include "xfree86mod.h" /* Support for XFree86 modules. */ #endif /* nm-fbsd.h */ Index: gdb/gdb/config/i386/nm-i386sol2.h diff -u gdb/gdb/config/i386/nm-i386sol2.h:1.1.1.2 gdb/gdb/config/i386/nm-i386sol2.h:1.1.1.2.2.1 --- gdb/gdb/config/i386/nm-i386sol2.h:1.1.1.2 Sat Jan 14 17:08:14 2006 +++ gdb/gdb/config/i386/nm-i386sol2.h Mon Jan 23 11:47:45 2006 @@ -21,6 +21,7 @@ /* Use SVR4 style shared library support */ #include "solib.h" +#include "xfree86mod.h" /* Support for XFree86 modules. */ /* SVR4 has /proc support, so use it instead of ptrace. */ Index: gdb/gdb/config/i386/nm-i386v4.h diff -u gdb/gdb/config/i386/nm-i386v4.h:1.1.1.3 gdb/gdb/config/i386/nm-i386v4.h:1.1.1.3.2.1 --- gdb/gdb/config/i386/nm-i386v4.h:1.1.1.3 Sat Jan 14 17:08:14 2006 +++ gdb/gdb/config/i386/nm-i386v4.h Mon Jan 23 11:47:45 2006 @@ -23,6 +23,7 @@ /* Use SVR4 style shared library support */ #include "solib.h" +#include "xfree86mod.h" /* Support for XFree86 modules. */ /* SVR4 has /proc support, so use it instead of ptrace. */ Index: gdb/gdb/config/i386/nm-nbsd.h diff -u /dev/null gdb/gdb/config/i386/nm-nbsd.h:1.1.1.2.2.1 --- /dev/null Mon Jan 23 15:18:12 2006 +++ gdb/gdb/config/i386/nm-nbsd.h Mon Jan 23 11:47:45 2006 @@ -0,0 +1,32 @@ +/* $XOZ: gdb/gdb/config/i386/nm-nbsd.h,v 1.1.1.2.2.1 2006/01/23 16:47:45 dawes Exp $ */ +/* Native-dependent definitions for NetBSD/i386. + + Copyright 1986, 1987, 1989, 1992, 1994, 1996, 1997, 2000, 2001, + 2004, 2005 Free Software Foundation, Inc. + + This file is 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. */ + +#ifndef NM_NBSD_H +#define NM_NBSD_H + +/* Shared library support. */ + +#include "solib.h" +#include "xfree86mod.h" /* Support for XFree86 modules. */ + +#endif /* nm-nbsd.h */ Index: gdb/gdb/config/i386/obsd.mh diff -u gdb/gdb/config/i386/obsd.mh:1.1.1.5 gdb/gdb/config/i386/obsd.mh:1.1.1.5.2.1 --- gdb/gdb/config/i386/obsd.mh:1.1.1.5 Sat Jan 14 17:08:15 2006 +++ gdb/gdb/config/i386/obsd.mh Mon Jan 23 11:47:45 2006 @@ -1,5 +1,5 @@ # Host: OpenBSD/i386 ELF NATDEPFILES= fork-child.o inf-ptrace.o \ - i386bsd-nat.o i386obsd-nat.o i386nbsd-nat.o bsd-kvm.o + i386bsd-nat.o i386obsd-nat.o i386nbsd-nat.o bsd-kvm.o xfree86mod.o LOADLIBES= -lkvm Index: gdb/gdb/gdbserver/remote-utils.c diff -u gdb/gdb/gdbserver/remote-utils.c:1.1.1.4 gdb/gdb/gdbserver/remote-utils.c:1.1.1.4.2.1 --- gdb/gdb/gdbserver/remote-utils.c:1.1.1.4 Sat Jan 14 17:08:23 2006 +++ gdb/gdb/gdbserver/remote-utils.c Mon Jan 23 11:47:50 2006 @@ -681,9 +681,9 @@ if (using_threads) { + unsigned int gdb_id_from_wait = thread_to_gdb_id (current_inferior); /* FIXME right place to set this? */ thread_from_wait = ((struct inferior_list_entry *)current_inferior)->id; - unsigned int gdb_id_from_wait = thread_to_gdb_id (current_inferior); if (debug_threads) fprintf (stderr, "Writing resume reply for %ld\n\n", thread_from_wait);