# # This patch adds XFree86 module support # to GDB's CVS snapshot of 2002-11-07. # # Ported from original patch found somewhere # on the internet that was made for GDB 4.18. # # Tested for i386 and x86-64 architectures # with XFree86 v4.x.x on SuSE Linux. # # Michal Ludvig (c) 2002 # Index: breakpoint.c =================================================================== RCS file: /cvs/src/src/gdb/breakpoint.c,v retrieving revision 1.92 diff -u -p -r1.92 breakpoint.c --- breakpoint.c 24 Oct 2002 21:02:53 -0000 1.92 +++ breakpoint.c 7 Nov 2002 15:40:35 -0000 @@ -216,6 +216,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; @@ -3036,6 +3038,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: @@ -3223,7 +3226,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[] = @@ -3374,6 +3378,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); @@ -3880,7 +3885,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; @@ -4029,6 +4033,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) @@ -4506,6 +4536,7 @@ mention (struct breakpoint *b) case bp_shlib_event: case bp_thread_event: case bp_overlay_event: + case bp_xfreemod_event: break; } if (say_where) Index: breakpoint.h =================================================================== RCS file: /cvs/src/src/gdb/breakpoint.h,v retrieving revision 1.13 diff -u -p -r1.13 breakpoint.h --- breakpoint.h 16 Aug 2002 15:37:54 -0000 1.13 +++ breakpoint.h 7 Nov 2002 15:40:36 -0000 @@ -136,7 +136,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 + }; @@ -669,9 +674,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.36 diff -u -p -r1.36 dbxread.c --- dbxread.c 25 Oct 2002 22:25:55 -0000 1.36 +++ dbxread.c 7 Nov 2002 15:40:36 -0000 @@ -1210,7 +1210,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) CORE_ADDR find_stab_function_addr (char *namestring, char *filename, struct objfile *objfile) @@ -3144,7 +3144,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: dwarf2cfi.c =================================================================== RCS file: /cvs/src/src/gdb/dwarf2cfi.c,v retrieving revision 1.20 diff -u -p -r1.20 dwarf2cfi.c --- dwarf2cfi.c 2 Nov 2002 14:59:10 -0000 1.20 +++ dwarf2cfi.c 7 Nov 2002 15:40:36 -0000 @@ -1701,8 +1701,10 @@ cfi_write_fp (CORE_ADDR val) void cfi_pop_frame (struct frame_info *fi) { - char *regbuf = alloca (MAX_REGISTER_RAW_SIZE); + char regbuf[MAX_REGISTER_RAW_SIZE]; int regnum; + + fi = get_current_frame (); for (regnum = 0; regnum < NUM_REGS; regnum++) { Index: elfread.c =================================================================== RCS file: /cvs/src/src/gdb/elfread.c,v retrieving revision 1.26 diff -u -p -r1.26 elfread.c --- elfread.c 25 Oct 2002 22:25:55 -0000 1.26 +++ elfread.c 7 Nov 2002 15:40:36 -0000 @@ -265,7 +265,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); @@ -307,10 +307,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 @@ -344,7 +360,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) @@ -440,7 +456,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); } if (index != -1) sectinfo->sections[index] = symaddr; Index: fork-child.c =================================================================== RCS file: /cvs/src/src/gdb/fork-child.c,v retrieving revision 1.17 diff -u -p -r1.17 fork-child.c --- fork-child.c 7 Feb 2002 06:11:55 -0000 1.17 +++ fork-child.c 7 Nov 2002 15:40:36 -0000 @@ -377,6 +377,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 } /* An inferior Unix process CHILD_PID has been created by a call to Index: gdb_indent.sh =================================================================== RCS file: /cvs/src/src/gdb/gdb_indent.sh,v retrieving revision 1.4 diff -u -p -r1.4 gdb_indent.sh --- gdb_indent.sh 24 Oct 2002 01:37:40 -0000 1.4 +++ gdb_indent.sh 7 Nov 2002 15:40:36 -0000 @@ -42,16 +42,6 @@ case `${indent} --version 2>/dev/null < * ) echo "Indent is not GNU" 1>&2 ;; esac - -# Check that we're in the GDB source directory - -case `pwd` in - */gdb ) ;; - */sim/* ) ;; - * ) echo "Not in GDB directory" 1>&2 ; exit 1 ;; -esac - - # Run indent per GDB specs types="\ Index: infrun.c =================================================================== RCS file: /cvs/src/src/gdb/infrun.c,v retrieving revision 1.74 diff -u -p -r1.74 infrun.c --- infrun.c 24 Oct 2002 21:02:53 -0000 1.74 +++ infrun.c 7 Nov 2002 15:40:36 -0000 @@ -1482,12 +1482,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. */ @@ -2426,6 +2430,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.71 diff -u -p -r1.71 symfile.c --- symfile.c 17 Oct 2002 21:16:12 -0000 1.71 +++ symfile.c 7 Nov 2002 15:40:36 -0000 @@ -54,6 +54,8 @@ #define O_BINARY 0 #endif +char oldname[100]; + #ifdef HPUXHPPA /* Some HP-UX related globals to clear when a new "main" @@ -105,7 +107,7 @@ static void add_shared_symbol_files_comm static void cashier_psymtab (struct partial_symtab *); -bfd *symfile_bfd_open (char *); +/*bfd *symfile_bfd_open (char *);*/ int get_section_index (struct objfile *, char *); @@ -498,7 +500,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 */ @@ -665,15 +667,16 @@ syms_from_objfile (struct objfile *objfi /* Calculate offsets for sections. */ for (i=0 ; i < MAX_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 { @@ -828,10 +831,70 @@ symbol_file_add (char *name, int from_tt 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 @@ -870,9 +933,12 @@ symbol_file_add (char *name, int from_tt 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...", name); + wrap_here (""); + gdb_flush (gdb_stdout); + } } } syms_from_objfile (objfile, addrs, mainline, from_tty); @@ -906,11 +972,16 @@ symbol_file_add (char *name, int from_tt post_add_symbol_hook (); else { - printf_filtered ("done.\n"); - gdb_flush (gdb_stdout); + if(strcmp(name, oldname) != 0) + { + printf_filtered ("done.\n"); + gdb_flush (gdb_stdout); + } } } + snprintf(oldname, 99, "%s", name); + if (objfile->sf == NULL) return objfile; /* No symbols. */ @@ -919,6 +990,9 @@ symbol_file_add (char *name, int from_tt if (target_new_objfile_hook) target_new_objfile_hook (objfile); +#ifdef XFREE_MODULE_SUPPORT + do_cleanups(old_chain); +#endif return (objfile); } @@ -1079,7 +1153,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; @@ -1119,7 +1193,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.14 diff -u -p -r1.14 symfile.h --- symfile.h 17 Oct 2002 21:16:12 -0000 1.14 +++ symfile.h 7 Nov 2002 15:40:36 -0000 @@ -254,7 +254,7 @@ extern void discard_psymtab (struct part extern void find_lowest_section (bfd *, asection *, PTR); -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 7 Nov 2002 15:40:36 -0000 @@ -0,0 +1,306 @@ +/* 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 (char *arg) +{ + struct mod_list *mod = (struct mod_list *) arg; + struct section_addr_info text_addr; + + memset (&text_addr, '\0', sizeof (text_addr)); + 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 7 Nov 2002 15:40:36 -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 + +#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.12 diff -u -p -r1.12 nm-linux.h --- config/nm-linux.h 24 Feb 2002 22:56:04 -0000 1.12 +++ config/nm-linux.h 7 Nov 2002 15:40:36 -0000 @@ -41,6 +41,7 @@ #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.12 diff -u -p -r1.12 linux.mh --- config/i386/linux.mh 11 May 2002 17:22:27 -0000 1.12 +++ config/i386/linux.mh 7 Nov 2002 15:40:37 -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 # The dynamically loaded libthread_db needs access to symbols in the Index: config/i386/x86-64linux.mh =================================================================== RCS file: /cvs/src/src/gdb/config/i386/x86-64linux.mh,v retrieving revision 1.7 diff -u -p -r1.7 x86-64linux.mh --- config/i386/x86-64linux.mh 1 Jul 2002 22:09:52 -0000 1.7 +++ config/i386/x86-64linux.mh 7 Nov 2002 15:40:37 -0000 @@ -6,6 +6,6 @@ NAT_FILE= nm-x86-64linux.h NATDEPFILES= infptrace.o inftarg.o fork-child.o corelow.o \ core-aout.o i386-nat.o x86-64-linux-nat.o \ proc-service.o thread-db.o lin-lwp.o \ - linux-proc.o gcore.o + linux-proc.o gcore.o xfreemod.o LOADLIBES = -ldl -rdynamic