# # This patch adds XFree86 module support to GDB 6.0 # # Ported from original patch found somewhere # on the internet that was made for GDB 4.18. # # Tested for i386 and amd64 architectures # with XFree86 v4.x.x on SuSE Linux. # # Ported to GDB 6.0 by Michal Ludvig <michal@logix.cz> # http://www.logix.cz/michal/devel/gdb-xfreemod/ # Index: breakpoint.c =================================================================== RCS file: /cvs/src/src/gdb/breakpoint.c,v retrieving revision 1.124.2.1 diff -u -p -r1.124.2.1 breakpoint.c --- breakpoint.c 2 Jul 2003 16:24:30 -0000 1.124.2.1 +++ breakpoint.c 17 Sep 2003 12:22:31 -0000 @@ -214,6 +214,8 @@ void _initialize_breakpoint (void); extern int addressprint; /* Print machine addresses? */ +static int internal_breakpoint_number = -1; + /* Are we executing breakpoint commands? */ static int executing_breakpoint_commands; @@ -3051,6 +3053,7 @@ bpstat_what (bpstat bs) bs_class = bp_nostop; break; case bp_shlib_event: + case bp_xfreemod_event: bs_class = shlib_event; break; case bp_thread_event: @@ -3238,7 +3241,8 @@ print_one_breakpoint (struct breakpoint {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[] = @@ -3394,6 +3398,7 @@ print_one_breakpoint (struct breakpoint case bp_shlib_event: case bp_thread_event: case bp_overlay_event: + case bp_xfreemod_event: if (addressprint) { annotate_field (4); @@ -3910,7 +3915,6 @@ make_breakpoint_permanent (struct breakp 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; @@ -4057,6 +4061,32 @@ remove_thread_event_breakpoints (void) 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) @@ -4534,6 +4564,7 @@ mention (struct breakpoint *b) case bp_shlib_event: case bp_thread_event: case bp_overlay_event: + case bp_xfreemod_event: break; } Index: breakpoint.h =================================================================== RCS file: /cvs/src/src/gdb/breakpoint.h,v retrieving revision 1.21 diff -u -p -r1.21 breakpoint.h --- breakpoint.h 27 Apr 2003 01:11:10 -0000 1.21 +++ breakpoint.h 17 Sep 2003 12:22:31 -0000 @@ -137,7 +137,12 @@ enum bptype /* 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 + }; @@ -693,9 +698,13 @@ extern struct breakpoint *create_solib_e 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); Index: dbxread.c =================================================================== RCS file: /cvs/src/src/gdb/dbxread.c,v retrieving revision 1.48 diff -u -p -r1.48 dbxread.c --- dbxread.c 11 Jun 2003 22:27:10 -0000 1.48 +++ dbxread.c 17 Sep 2003 12:22:31 -0000 @@ -1231,7 +1231,7 @@ read_dbx_dynamic_symtab (struct objfile do_cleanups (back_to); } -#ifdef SOFUN_ADDRESS_MAYBE_MISSING +#if defined(SOFUN_ADDRESS_MAYBE_MISSING) || defined(XFREE_MODULE_SUPPORT) static CORE_ADDR find_stab_function_addr (char *namestring, char *filename, struct objfile *objfile) @@ -3214,7 +3214,7 @@ process_one_symbol (int type, int desc, 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 Index: elfread.c =================================================================== RCS file: /cvs/src/src/gdb/elfread.c,v retrieving revision 1.33 diff -u -p -r1.33 elfread.c --- elfread.c 7 Jun 2003 15:51:05 -0000 1.33 +++ elfread.c 17 Sep 2003 12:22:31 -0000 @@ -251,7 +251,7 @@ elf_symtab_read (struct objfile *objfile 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); @@ -293,10 +293,26 @@ elf_symtab_read (struct objfile *objfile 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 @@ -330,7 +346,7 @@ elf_symtab_read (struct objfile *objfile { if (sym->name[0] == '.') continue; - symaddr += offset; + symaddr += ANOFFSET (objfile->section_offsets, 0); } } else if (sym->section->flags & SEC_CODE) @@ -426,7 +442,7 @@ elf_symtab_read (struct objfile *objfile /* 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: fork-child.c =================================================================== RCS file: /cvs/src/src/gdb/fork-child.c,v retrieving revision 1.22 diff -u -p -r1.22 fork-child.c --- fork-child.c 8 May 2003 18:08:57 -0000 1.22 +++ fork-child.c 17 Sep 2003 12:22:32 -0000 @@ -401,6 +401,9 @@ fork_inferior (char *exec_file_arg, char #ifdef SOLIB_CREATE_INFERIOR_HOOK SOLIB_CREATE_INFERIOR_HOOK (pid); #endif +#ifdef XFREE_MODULE_SUPPORT + xfreemod_create_inferior_hook(pid); +#endif } /* Accept NTRAPS traps from the inferior. */ Index: infrun.c =================================================================== RCS file: /cvs/src/src/gdb/infrun.c,v retrieving revision 1.110 diff -u -p -r1.110 infrun.c --- infrun.c 19 Jun 2003 15:04:57 -0000 1.110 +++ infrun.c 17 Sep 2003 12:22:33 -0000 @@ -1362,12 +1362,16 @@ handle_inferior_event (struct execution_ 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 - breakpoint_re_set. */ + /* Check for any newly added shared libraries or xfree + 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 (); SOLIB_ADD (NULL, 0, NULL, auto_solib_add); +#ifdef XFREE_MODULE_SUPPORT + xfreemod_add (NULL, 0, NULL); +#endif target_terminal_inferior (); /* Reinsert breakpoints and continue. */ @@ -2191,6 +2195,10 @@ process_event_stop_test: breakpoint_re_set. */ target_terminal_ours_for_output (); SOLIB_ADD (NULL, 0, NULL, auto_solib_add); +#ifdef XFREE_MODULE_SUPPORT + xfreemod_add (NULL, 0, NULL); +#endif + target_terminal_inferior (); /* Try to reenable shared library breakpoints, additional Index: symfile.c =================================================================== RCS file: /cvs/src/src/gdb/symfile.c,v retrieving revision 1.100.2.2 diff -u -p -r1.100.2.2 symfile.c --- symfile.c 14 Aug 2003 20:12:31 -0000 1.100.2.2 +++ symfile.c 17 Sep 2003 12:22:33 -0000 @@ -60,6 +60,8 @@ #define O_BINARY 0 #endif +char oldname[100]; + #ifdef HPUXHPPA /* Some HP-UX related globals to clear when a new "main" @@ -113,7 +115,7 @@ static void reread_separate_symbols (str static void cashier_psymtab (struct partial_symtab *); -bfd *symfile_bfd_open (char *); +/*bfd *symfile_bfd_open (char *);*/ int get_section_index (struct objfile *, char *); @@ -511,7 +513,7 @@ default_symfile_offsets (struct objfile 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 */ @@ -662,17 +664,17 @@ syms_from_objfile (struct objfile *objfi 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 { @@ -837,11 +839,72 @@ symbol_file_add_with_addrs_or_offsets (c bfd *abfd; struct section_addr_info *orig_addrs; struct cleanup *my_cleanups; + char *component_name = NULL; + +#ifdef XFREE_MODULE_SUPPORT + struct cleanup *old_chain; + char *p; + /* Make a copy of the string that we can safely write into. */ - /* Open a bfd for the file, and give user a chance to burp if we'd be - interactively wiping out any existing symbols. */ + name = strdup (name); + old_chain = make_cleanup(free, name); + + p = strstr(name, ".a:"); + if (p) + { + bfd *archive_bfd; + 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)); + } + else +#endif + { + /* 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 @@ -890,9 +953,13 @@ symbol_file_add_with_addrs_or_offsets (c pre_add_symbol_hook (name); else { - printf_filtered ("Reading symbols from %s...", name); - wrap_here (""); - gdb_flush (gdb_stdout); + if(strcmp(name, oldname) != 0) + { + printf_filtered ("Reading symbols from %s...", + component_name ? component_name : name); + wrap_here (""); + gdb_flush (gdb_stdout); + } } } syms_from_objfile (objfile, addrs, offsets, num_offsets, @@ -976,6 +1043,9 @@ symbol_file_add_with_addrs_or_offsets (c if (target_new_objfile_hook) target_new_objfile_hook (objfile); +#ifdef XFREE_MODULE_SUPPORT + do_cleanups(old_chain); +#endif return (objfile); } @@ -1287,7 +1357,7 @@ set_initial_language (void) 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; @@ -1327,7 +1397,7 @@ symfile_bfd_open (char *name) } sym_bfd->cacheable = 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 with the Index: symfile.h =================================================================== RCS file: /cvs/src/src/gdb/symfile.h,v retrieving revision 1.24 diff -u -p -r1.24 symfile.h --- symfile.h 11 Jun 2003 22:27:13 -0000 1.24 +++ symfile.h 17 Sep 2003 12:22:33 -0000 @@ -259,7 +259,7 @@ extern void discard_psymtab (struct part 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: xfreemod.c =================================================================== RCS file: xfreemod.c diff -N xfreemod.c --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ xfreemod.c 17 Sep 2003 12:22:33 -0000 @@ -0,0 +1,307 @@ +/* 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 "gdb_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; + } + } +} + +/* 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 +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."); +} Index: xfreemod.h =================================================================== RCS file: xfreemod.h diff -N xfreemod.h --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ xfreemod.h 17 Sep 2003 12:22:33 -0000 @@ -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 *)); + Index: config/nm-linux.h =================================================================== RCS file: /cvs/src/src/gdb/config/nm-linux.h,v retrieving revision 1.18.2.1 diff -u -p -r1.18.2.1 nm-linux.h --- config/nm-linux.h 17 Aug 2003 18:22:33 -0000 1.18.2.1 +++ config/nm-linux.h 17 Sep 2003 12:22:33 -0000 @@ -43,6 +43,7 @@ struct target_ops; #ifdef HAVE_LINK_H #define SVR4_SHARED_LIBS #include "solib.h" /* Support for shared libraries. */ +#include "xfreemod.h" /* Support for XFree86 modules. */ #endif
Index: config/i386/linux.mh =================================================================== RCS file: /cvs/src/src/gdb/config/i386/linux.mh,v retrieving revision 1.13 diff -u -p -r1.13 linux.mh --- config/i386/linux.mh 15 Jun 2003 20:56:47 -0000 1.13 +++ config/i386/linux.mh 17 Sep 2003 12:22:33 -0000 @@ -4,7 +4,7 @@ XM_FILE= xm-i386.h NAT_FILE= nm-linux.h NATDEPFILES= infptrace.o inftarg.o fork-child.o corelow.o linux-proc.o \ - core-aout.o i386-nat.o i386-linux-nat.o \ + core-aout.o i386-nat.o i386-linux-nat.o xfreemod.o \ proc-service.o thread-db.o lin-lwp.o linux-proc.o gcore.o \ linux-nat.o Index: config/i386/x86-64linux.mh =================================================================== RCS file: /cvs/src/src/gdb/config/i386/x86-64linux.mh,v retrieving revision 1.9.2.1 diff -u -p -r1.9.2.1 x86-64linux.mh --- config/i386/x86-64linux.mh 15 Jul 2003 11:30:59 -0000 1.9.2.1 +++ config/i386/x86-64linux.mh 17 Sep 2003 12:22:33 -0000 @@ -5,7 +5,7 @@ XM_FILE= xm-i386.h NAT_FILE= nm-x86-64linux.h NATDEPFILES= infptrace.o inftarg.o fork-child.o \ i386-nat.o x86-64-linux-nat.o \ - linux-nat.o \ + linux-nat.o xfreemod.o \ proc-service.o thread-db.o lin-lwp.o linux-proc.o gcore.o # The dynamically loaded libthread_db needs access to symbols in the