diff options
author | Kurt Miller <kurt@cvs.openbsd.org> | 2008-11-11 22:57:49 +0000 |
---|---|---|
committer | Kurt Miller <kurt@cvs.openbsd.org> | 2008-11-11 22:57:49 +0000 |
commit | e2c9af9ae9cffcad67d0c6845a64bf54ca71a713 (patch) | |
tree | 19db35e56679a5415105c7e780c8f3e33c183a7c /gnu/usr.bin/binutils/gdb | |
parent | fdb019932caa27a3f61876da2ab864908b74ee31 (diff) |
Enable support for debugging pie programs. Code from Elena Zannoni's
<ezannoni at redhat dot com> pie branch in gdb cvs, less extraneous
parts and with some bug fixes. Debugging w/core files for pie programs
isn't working yet since AUXV data isn't included in our core files at
the moment.
feedback and ok kettenis@
Diffstat (limited to 'gnu/usr.bin/binutils/gdb')
-rw-r--r-- | gnu/usr.bin/binutils/gdb/Makefile.in | 6 | ||||
-rw-r--r-- | gnu/usr.bin/binutils/gdb/breakpoint.c | 59 | ||||
-rw-r--r-- | gnu/usr.bin/binutils/gdb/breakpoint.h | 5 | ||||
-rw-r--r-- | gnu/usr.bin/binutils/gdb/infrun.c | 5 | ||||
-rw-r--r-- | gnu/usr.bin/binutils/gdb/objfiles.c | 10 | ||||
-rw-r--r-- | gnu/usr.bin/binutils/gdb/solib-svr4.c | 238 | ||||
-rw-r--r-- | gnu/usr.bin/binutils/gdb/solib.c | 92 | ||||
-rw-r--r-- | gnu/usr.bin/binutils/gdb/solist.h | 12 | ||||
-rw-r--r-- | gnu/usr.bin/binutils/gdb/symfile-mem.c | 2 | ||||
-rw-r--r-- | gnu/usr.bin/binutils/gdb/symfile.c | 10 | ||||
-rw-r--r-- | gnu/usr.bin/binutils/gdb/varobj.c | 68 | ||||
-rw-r--r-- | gnu/usr.bin/binutils/gdb/varobj.h | 2 |
12 files changed, 306 insertions, 203 deletions
diff --git a/gnu/usr.bin/binutils/gdb/Makefile.in b/gnu/usr.bin/binutils/gdb/Makefile.in index 24aaabf1fcd..c516d042896 100644 --- a/gnu/usr.bin/binutils/gdb/Makefile.in +++ b/gnu/usr.bin/binutils/gdb/Makefile.in @@ -2289,7 +2289,7 @@ objc-lang.o: objc-lang.c $(defs_h) $(symtab_h) $(gdbtypes_h) $(expression_h) \ objfiles.o: objfiles.c $(defs_h) $(bfd_h) $(symtab_h) $(symfile_h) \ $(objfiles_h) $(gdb_stabs_h) $(target_h) $(bcache_h) $(gdb_assert_h) \ $(gdb_stat_h) $(gdb_obstack_h) $(gdb_string_h) $(hashtab_h) \ - $(breakpoint_h) $(block_h) $(dictionary_h) + $(breakpoint_h) $(block_h) $(dictionary_h) $(auxv_h) $(elf_common_h) observer.o: observer.c $(defs_h) $(observer_h) $(command_h) $(gdbcmd_h) \ $(observer_inc) obsd-tdep.o: obsd-tdep.c $(defs_h) $(frame_h) $(symtab_h) $(obsd_tdep_h) @@ -2511,7 +2511,7 @@ solib-sunos.o: solib-sunos.c $(defs_h) $(gdb_string_h) $(symtab_h) $(bfd_h) \ solib-svr4.o: solib-svr4.c $(defs_h) $(elf_external_h) $(elf_common_h) \ $(elf_mips_h) $(symtab_h) $(bfd_h) $(symfile_h) $(objfiles_h) \ $(gdbcore_h) $(target_h) $(inferior_h) $(solist_h) $(solib_svr4_h) \ - $(bfd_target_h) $(exec_h) + $(bfd_target_h) $(exec_h) $(auxv_h) $(command_h) sol-thread.o: sol-thread.c $(defs_h) $(gdbthread_h) $(target_h) \ $(inferior_h) $(gdb_stat_h) $(gdbcmd_h) $(gdbcore_h) $(regcache_h) \ $(symfile_h) $(gdb_string_h) $(gregset_h) @@ -2603,7 +2603,7 @@ symfile.o: symfile.c $(defs_h) $(bfdlink_h) $(symtab_h) $(gdbtypes_h) \ $(complaints_h) $(demangle_h) $(inferior_h) $(filenames_h) \ $(gdb_stabs_h) $(gdb_obstack_h) $(completer_h) $(bcache_h) \ $(hashtab_h) $(readline_h) $(gdb_assert_h) $(block_h) \ - $(gdb_string_h) $(gdb_stat_h) + $(gdb_string_h) $(gdb_stat_h) $(varobj_h) symfile-mem.o: symfile-mem.c $(defs_h) $(symtab_h) $(gdbcore_h) \ $(objfiles_h) $(gdbcmd_h) $(target_h) $(value_h) $(symfile_h) symmisc.o: symmisc.c $(defs_h) $(symtab_h) $(gdbtypes_h) $(bfd_h) \ diff --git a/gnu/usr.bin/binutils/gdb/breakpoint.c b/gnu/usr.bin/binutils/gdb/breakpoint.c index eac34b8534f..50b5f59c820 100644 --- a/gnu/usr.bin/binutils/gdb/breakpoint.c +++ b/gnu/usr.bin/binutils/gdb/breakpoint.c @@ -3783,6 +3783,7 @@ describe_other_breakpoints (CORE_ADDR pc, asection *section) b->number, ((b->enable_state == bp_disabled || b->enable_state == bp_shlib_disabled || + b->enable_state == bp_startup_disabled || b->enable_state == bp_call_disabled) ? " (disabled)" : b->enable_state == bp_permanent @@ -4457,6 +4458,60 @@ re_enable_breakpoints_in_shlibs (void) #endif +void +disable_breakpoints_at_startup (int silent) +{ + struct breakpoint *b; + int disabled_startup_breaks = 0; + + if (bfd_get_start_address (exec_bfd) != entry_point_address ()) + { + ALL_BREAKPOINTS (b) + { + if (((b->type == bp_breakpoint) || + (b->type == bp_hardware_breakpoint)) && + b->enable_state == bp_enabled && + !b->loc->duplicate && + !b->pending) + { + b->enable_state = bp_startup_disabled; + if (!silent) + { + if (!disabled_startup_breaks) + { + target_terminal_ours_for_output (); + warning ("Temporarily disabling breakpoints:"); + } + disabled_startup_breaks = 1; + warning ("breakpoint #%d addr 0x%s", b->number, paddr_nz(b->loc->address)); + } + } + } + } +} + +/* Try to reenable any breakpoints after startup. */ +void +re_enable_breakpoints_at_startup (void) +{ + struct breakpoint *b; + + if (bfd_get_start_address (exec_bfd) != entry_point_address ()) + { + ALL_BREAKPOINTS (b) + if (b->enable_state == bp_startup_disabled) + { + char buf[1]; + + /* Do not reenable the breakpoint if the shared library + is still not mapped in. */ + if (target_read_memory (b->loc->address, buf, 1) == 0) + b->enable_state = bp_enabled; + } + } +} + + static void solib_load_unload_1 (char *hookname, int tempflag, char *dll_pathname, char *cond_string, enum bptype bp_kind) @@ -6978,6 +7033,7 @@ delete_breakpoint (struct breakpoint *bpt) && !b->loc->duplicate && b->enable_state != bp_disabled && b->enable_state != bp_shlib_disabled + && b->enable_state != bp_startup_disabled && !b->pending && b->enable_state != bp_call_disabled) { @@ -7191,7 +7247,8 @@ breakpoint_re_set_one (void *bint) break; save_enable = b->enable_state; - if (b->enable_state != bp_shlib_disabled) + if (b->enable_state != bp_shlib_disabled + && b->enable_state != bp_startup_disabled) b->enable_state = bp_disabled; else /* If resetting a shlib-disabled breakpoint, we don't want to diff --git a/gnu/usr.bin/binutils/gdb/breakpoint.h b/gnu/usr.bin/binutils/gdb/breakpoint.h index 67a67e34054..06f4e59cd22 100644 --- a/gnu/usr.bin/binutils/gdb/breakpoint.h +++ b/gnu/usr.bin/binutils/gdb/breakpoint.h @@ -159,6 +159,7 @@ enum enable_state automatically enabled and reset when the call "lands" (either completes, or stops at another eventpoint). */ + bp_startup_disabled, bp_permanent /* There is a breakpoint instruction hard-wired into the target's code. Don't try to write another breakpoint instruction on top of it, or restore @@ -765,8 +766,12 @@ extern void remove_thread_event_breakpoints (void); extern void disable_breakpoints_in_shlibs (int silent); +extern void disable_breakpoints_at_startup (int silent); + extern void re_enable_breakpoints_in_shlibs (void); +void re_enable_breakpoints_at_startup (void); + extern void create_solib_load_event_breakpoint (char *, int, char *, char *); extern void create_solib_unload_event_breakpoint (char *, int, diff --git a/gnu/usr.bin/binutils/gdb/infrun.c b/gnu/usr.bin/binutils/gdb/infrun.c index 7cf9953044a..aba6f8ca16e 100644 --- a/gnu/usr.bin/binutils/gdb/infrun.c +++ b/gnu/usr.bin/binutils/gdb/infrun.c @@ -2120,6 +2120,11 @@ process_event_stop_test: code segments in shared libraries might be mapped in now. */ re_enable_breakpoints_in_shlibs (); + /* For PIE executables, we dont really know where the + breakpoints are going to be until we start up the + inferior. */ + re_enable_breakpoints_at_startup (); + /* If requested, stop when the dynamic linker notifies gdb of events. This allows the user to get control and place breakpoints in initializer routines for diff --git a/gnu/usr.bin/binutils/gdb/objfiles.c b/gnu/usr.bin/binutils/gdb/objfiles.c index 3c4e0b402b0..46bc4a8a5c7 100644 --- a/gnu/usr.bin/binutils/gdb/objfiles.c +++ b/gnu/usr.bin/binutils/gdb/objfiles.c @@ -45,6 +45,9 @@ #include "breakpoint.h" #include "block.h" #include "dictionary.h" +#include "auxv.h" + +#include "elf/common.h" /* Prototypes for local functions */ @@ -257,7 +260,12 @@ init_entry_point_info (struct objfile *objfile) CORE_ADDR entry_point_address (void) { - return symfile_objfile ? symfile_objfile->ei.entry_point : 0; + CORE_ADDR entry_addr = symfile_objfile ? symfile_objfile->ei.entry_point : 0; + + /* Find the address of the entry point of the program from the + auxv vector. */ + target_auxv_search (¤t_target, AT_ENTRY, &entry_addr); + return entry_addr; } /* Create the terminating entry of OBJFILE's minimal symbol table. diff --git a/gnu/usr.bin/binutils/gdb/solib-svr4.c b/gnu/usr.bin/binutils/gdb/solib-svr4.c index 4f4664cc017..eebeddda489 100644 --- a/gnu/usr.bin/binutils/gdb/solib-svr4.c +++ b/gnu/usr.bin/binutils/gdb/solib-svr4.c @@ -27,6 +27,7 @@ #include "elf/common.h" #include "elf/mips.h" +#include "auxv.h" #include "symtab.h" #include "bfd.h" #include "symfile.h" @@ -34,6 +35,7 @@ #include "gdbcore.h" #include "target.h" #include "inferior.h" +#include "command.h" #include "solist.h" #include "solib-svr4.h" @@ -179,7 +181,9 @@ static CORE_ADDR breakpoint_addr; /* Address where end bkpt is set */ /* Local function prototypes */ +#if 0 static int match_main (char *); +#endif static CORE_ADDR bfd_lookup_symbol (bfd *, char *, flagword); @@ -272,133 +276,6 @@ bfd_lookup_symbol (bfd *abfd, char *symname, flagword sect_flags) return symaddr; } -#ifdef HANDLE_SVR4_EXEC_EMULATORS - -/* - Solaris BCP (the part of Solaris which allows it to run SunOS4 - a.out files) throws in another wrinkle. Solaris does not fill - in the usual a.out link map structures when running BCP programs, - the only way to get at them is via groping around in the dynamic - linker. - The dynamic linker and it's structures are located in the shared - C library, which gets run as the executable's "interpreter" by - the kernel. - - Note that we can assume nothing about the process state at the time - we need to find these structures. We may be stopped on the first - instruction of the interpreter (C shared library), the first - instruction of the executable itself, or somewhere else entirely - (if we attached to the process for example). - */ - -static char *debug_base_symbols[] = -{ - "r_debug", /* Solaris 2.3 */ - "_r_debug", /* Solaris 2.1, 2.2 */ - NULL -}; - -static int look_for_base (int, CORE_ADDR); - -/* - - LOCAL FUNCTION - - look_for_base -- examine file for each mapped address segment - - SYNOPSYS - - static int look_for_base (int fd, CORE_ADDR baseaddr) - - DESCRIPTION - - This function is passed to proc_iterate_over_mappings, which - causes it to get called once for each mapped address space, with - an open file descriptor for the file mapped to that space, and the - base address of that mapped space. - - Our job is to find the debug base symbol in the file that this - fd is open on, if it exists, and if so, initialize the dynamic - linker structure base address debug_base. - - Note that this is a computationally expensive proposition, since - we basically have to open a bfd on every call, so we specifically - avoid opening the exec file. - */ - -static int -look_for_base (int fd, CORE_ADDR baseaddr) -{ - bfd *interp_bfd; - CORE_ADDR address = 0; - char **symbolp; - - /* If the fd is -1, then there is no file that corresponds to this - mapped memory segment, so skip it. Also, if the fd corresponds - to the exec file, skip it as well. */ - - if (fd == -1 - || (exec_bfd != NULL - && fdmatch (fileno ((FILE *) (exec_bfd->iostream)), fd))) - { - return (0); - } - - /* Try to open whatever random file this fd corresponds to. Note that - we have no way currently to find the filename. Don't gripe about - any problems we might have, just fail. */ - - if ((interp_bfd = bfd_fdopenr ("unnamed", gnutarget, fd)) == NULL) - { - return (0); - } - if (!bfd_check_format (interp_bfd, bfd_object)) - { - /* FIXME-leak: on failure, might not free all memory associated with - interp_bfd. */ - bfd_close (interp_bfd); - return (0); - } - - /* Now try to find our debug base symbol in this file, which we at - least know to be a valid ELF executable or shared library. */ - - for (symbolp = debug_base_symbols; *symbolp != NULL; symbolp++) - { - address = bfd_lookup_symbol (interp_bfd, *symbolp, 0); - if (address != 0) - { - break; - } - } - if (address == 0) - { - /* FIXME-leak: on failure, might not free all memory associated with - interp_bfd. */ - bfd_close (interp_bfd); - return (0); - } - - /* Eureka! We found the symbol. But now we may need to relocate it - by the base address. If the symbol's value is less than the base - address of the shared library, then it hasn't yet been relocated - by the dynamic linker, and we have to do it ourself. FIXME: Note - that we make the assumption that the first segment that corresponds - to the shared library has the base address to which the library - was relocated. */ - - if (address < baseaddr) - { - address += baseaddr; - } - debug_base = address; - /* FIXME-leak: on failure, might not free all memory associated with - interp_bfd. */ - bfd_close (interp_bfd); - return (1); -} -#endif /* HANDLE_SVR4_EXEC_EMULATORS */ - /* LOCAL FUNCTION @@ -428,21 +305,32 @@ elf_locate_base (void) { struct bfd_section *dyninfo_sect; int dyninfo_sect_size; - CORE_ADDR dyninfo_addr; + CORE_ADDR dyninfo_addr, relocated_dyninfo_addr, entry_addr; char *buf; char *bufend; int arch_size; + /* Find the address of the entry point of the program from the + auxv vector. */ + if (target_auxv_search (¤t_target, AT_ENTRY, &entry_addr) != 1) + { + /* No auxv info, maybe an older kernel. Fake our way through. */ + entry_addr = bfd_get_start_address (exec_bfd); + } + /* Find the start address of the .dynamic section. */ dyninfo_sect = bfd_get_section_by_name (exec_bfd, ".dynamic"); if (dyninfo_sect == NULL) return 0; dyninfo_addr = bfd_section_vma (exec_bfd, dyninfo_sect); + relocated_dyninfo_addr = dyninfo_addr + + entry_addr - bfd_get_start_address(exec_bfd); + /* Read in .dynamic section, silently ignore errors. */ dyninfo_sect_size = bfd_section_size (exec_bfd, dyninfo_sect); buf = alloca (dyninfo_sect_size); - if (target_read_memory (dyninfo_addr, buf, dyninfo_sect_size)) + if (target_read_memory (relocated_dyninfo_addr, buf, dyninfo_sect_size)) return 0; /* Find the DT_DEBUG entry in the the .dynamic section. @@ -579,11 +467,6 @@ locate_base (void) if (exec_bfd != NULL && bfd_get_flavour (exec_bfd) == bfd_target_elf_flavour) debug_base = elf_locate_base (); -#ifdef HANDLE_SVR4_EXEC_EMULATORS - /* Try it the hard way for emulated executables. */ - else if (!ptid_equal (inferior_ptid, null_ptid) && target_has_execution) - proc_iterate_over_mappings (look_for_base); -#endif } return (debug_base); } @@ -768,7 +651,47 @@ svr4_current_sos (void) does have a name, so we can no longer use a missing name to decide when to ignore it. */ if (IGNORE_FIRST_LINK_MAP_ENTRY (new)) - free_so (new); + { + /* It is the first link map entry, i.e. it is the main executable. */ + + if (bfd_get_start_address (exec_bfd) == entry_point_address ()) + { + /* Non-pie case, main executable has not been relocated. */ + free_so (new); + } + else + { + /* Pie case, main executable has been relocated. */ + struct so_list *gdb_solib; + + strncpy (new->so_name, exec_bfd->filename, + SO_NAME_MAX_PATH_SIZE - 1); + new->so_name[SO_NAME_MAX_PATH_SIZE - 1] = '\0'; + strcpy (new->so_original_name, new->so_name); + new->main_relocated = 0; + + for (gdb_solib = master_so_list (); + gdb_solib; + gdb_solib = gdb_solib->next) + { + if (strcmp (gdb_solib->so_name, new->so_name) == 0) + if (gdb_solib->main_relocated) + break; + } + + if ((gdb_solib && !gdb_solib->main_relocated) || (!gdb_solib)) + { + add_to_target_sections (0 /*from_tty*/, ¤t_target, new); + new->main = 1; + } + + /* We need this in the list of shared libs we return because + solib_add_stub will loop through it and add the symbol file. */ + new->next = 0; + *link_ptr = new; + link_ptr = &new->next; + } + } /* End of IGNORE_FIRST_LINK_MAP_ENTRY */ else { int errcode; @@ -790,17 +713,10 @@ svr4_current_sos (void) strcpy (new->so_original_name, new->so_name); } - /* If this entry has no name, or its name matches the name - for the main executable, don't include it in the list. */ - if (! new->so_name[0] - || match_main (new->so_name)) - free_so (new); - else - { - new->next = 0; - *link_ptr = new; - link_ptr = &new->next; - } + new->next = 0; + *link_ptr = new; + link_ptr = &new->next; + } discard_cleanups (old_chain); @@ -886,6 +802,7 @@ svr4_fetch_objfile_link_map (struct objfile *objfile) the main executable file is by looking at its name. Return non-zero iff SONAME matches one of the known main executable names. */ +#if 0 static int match_main (char *soname) { @@ -899,6 +816,7 @@ match_main (char *soname) return (0); } +#endif /* Return 1 if PC lies in the dynamic symbol resolution code of the SVR4 run time loader. */ @@ -1004,7 +922,7 @@ enable_break (void) char *buf; CORE_ADDR load_addr = 0; int load_addr_found = 0; - struct so_list *inferior_sos; + struct so_list *so; bfd *tmp_bfd = NULL; struct target_ops *tmp_bfd_target; int tmp_fd = -1; @@ -1047,23 +965,19 @@ enable_break (void) target will also close the underlying bfd. */ tmp_bfd_target = target_bfd_reopen (tmp_bfd); - /* If the entry in _DYNAMIC for the dynamic linker has already - been filled in, we can read its base address from there. */ - inferior_sos = svr4_current_sos (); - if (inferior_sos) - { - /* Connected to a running target. Update our shared library table. */ - solib_add (NULL, 0, NULL, auto_solib_add); - } - while (inferior_sos) + /* On a running target, we can get the dynamic linker's base + address from the shared library table. */ + solib_add (NULL, 0, NULL, auto_solib_add); + so = master_so_list (); + while (so) { - if (strcmp (buf, inferior_sos->so_original_name) == 0) + if (strcmp (buf, so->so_original_name) == 0) { load_addr_found = 1; - load_addr = LM_ADDR (inferior_sos); + load_addr = LM_ADDR (so); break; } - inferior_sos = inferior_sos->next; + so = so->next; } /* Otherwise we find the dynamic linker's base address by examining @@ -1375,6 +1289,8 @@ svr4_solib_create_inferior_hook (void) while (stop_signal != TARGET_SIGNAL_TRAP); stop_soon = NO_STOP_QUIETLY; #endif /* defined(_SCO_DS) */ + + disable_breakpoints_at_startup (1); } static void @@ -1490,7 +1406,7 @@ void set_solib_svr4_fetch_link_map_offsets (struct gdbarch *gdbarch, struct link_map_offsets *(*flmo) (void)) { - set_gdbarch_data (gdbarch, fetch_link_map_offsets_gdbarch_data, flmo); + deprecated_set_gdbarch_data (gdbarch, fetch_link_map_offsets_gdbarch_data, flmo); } /* Initialize the architecture-specific link_map_offsets fetcher. @@ -1588,7 +1504,7 @@ void _initialize_svr4_solib (void) { fetch_link_map_offsets_gdbarch_data = - register_gdbarch_data (init_fetch_link_map_offsets); + gdbarch_data_register_post_init (init_fetch_link_map_offsets); svr4_so_ops.relocate_section_addresses = svr4_relocate_section_addresses; svr4_so_ops.free_so = svr4_free_so; diff --git a/gnu/usr.bin/binutils/gdb/solib.c b/gnu/usr.bin/binutils/gdb/solib.c index b0885fb9cae..d27da27e59a 100644 --- a/gnu/usr.bin/binutils/gdb/solib.c +++ b/gnu/usr.bin/binutils/gdb/solib.c @@ -69,6 +69,8 @@ static char *solib_absolute_prefix = NULL; and LD_LIBRARY_PATH. */ static char *solib_search_path = NULL; +void add_to_target_sections (int, struct target_ops *, struct so_list *); + /* GLOBAL FUNCTION @@ -355,15 +357,37 @@ symbol_add_stub (void *arg) /* Have we already loaded this shared object? */ ALL_OBJFILES (so->objfile) { - if (strcmp (so->objfile->name, so->so_name) == 0) + /* Found an already loaded shared library. */ + if (strcmp (so->objfile->name, so->so_name) == 0 + && !so->main) return 1; + /* Found an already loaded main executable. This could happen in + two circumstances. + First case: the main file has already been read in + as the first thing that gdb does at startup, and the file + hasn't been relocated properly yet. Therefor we need to read + it in with the proper section info. + Second case: it has been read in with the correct relocation, + and therefore we need to skip it. */ + if (strcmp (so->objfile->name, so->so_name) == 0 + && so->main + && so->main_relocated) + return 1; } sap = build_section_addr_info_from_section_table (so->sections, so->sections_end); - so->objfile = symbol_file_add (so->so_name, so->from_tty, - sap, 0, OBJF_SHARED); + if (so->main) + { + so->objfile = symbol_file_add (so->so_name, /*so->from_tty*/ 0, + sap, 1, 0); + so->main_relocated = 1; + } + else + so->objfile = symbol_file_add (so->so_name, so->from_tty, + sap, 0, OBJF_SHARED); + free_section_addr_info (sap); return (1); @@ -538,36 +562,46 @@ update_solib_list (int from_tty, struct target_ops *target) /* Fill in the rest of each of the `struct so_list' nodes. */ for (i = inferior; i; i = i->next) { - i->from_tty = from_tty; - - /* Fill in the rest of the `struct so_list' node. */ - catch_errors (solib_map_sections, i, - "Error while mapping shared library sections:\n", - RETURN_MASK_ALL); - - /* If requested, add the shared object's sections to the TARGET's - section table. Do this immediately after mapping the object so - that later nodes in the list can query this object, as is needed - in solib-osf.c. */ - if (target) - { - int count = (i->sections_end - i->sections); - if (count > 0) - { - int space = target_resize_to_sections (target, count); - memcpy (target->to_sections + space, - i->sections, - count * sizeof (i->sections[0])); - } - } - - /* Notify any observer that the shared object has been - loaded now that we've added it to GDB's tables. */ - observer_notify_solib_loaded (i); + add_to_target_sections (from_tty, target, i); } } } +void +add_to_target_sections (int from_tty, struct target_ops *target, struct so_list *solib) +{ + /* If this is set, then the sections have been already added to the + target list. */ + if (solib->main) + return; + + solib->from_tty = from_tty; + + /* Fill in the rest of the `struct so_list' node. */ + catch_errors (solib_map_sections, solib, + "Error while mapping shared library sections:\n", + RETURN_MASK_ALL); + + /* If requested, add the shared object's sections to the TARGET's + section table. Do this immediately after mapping the object so + that later nodes in the list can query this object, as is needed + in solib-osf.c. */ + if (target) + { + int count = (solib->sections_end - solib->sections); + if (count > 0) + { + int space = target_resize_to_sections (target, count); + memcpy (target->to_sections + space, + solib->sections, + count * sizeof (solib->sections[0])); + } + } + /* Notify any observer that the shared object has been + loaded now that we've added it to GDB's tables. */ + observer_notify_solib_loaded (solib); +} + /* GLOBAL FUNCTION diff --git a/gnu/usr.bin/binutils/gdb/solist.h b/gnu/usr.bin/binutils/gdb/solist.h index 8e5c4321855..5bcc1f2b67e 100644 --- a/gnu/usr.bin/binutils/gdb/solist.h +++ b/gnu/usr.bin/binutils/gdb/solist.h @@ -62,6 +62,8 @@ struct so_list bfd *abfd; char symbols_loaded; /* flag: symbols read in yet? */ char from_tty; /* flag: print msgs? */ + char main; /* flag: is this the main executable? */ + char main_relocated; /* flag: has it been relocated yet? */ struct objfile *objfile; /* objfile for loaded lib */ struct section_table *sections; struct section_table *sections_end; @@ -107,11 +109,21 @@ struct target_so_ops }; +/* Free the memory associated with a (so_list *). */ void free_so (struct so_list *so); +/* Return address of first so_list entry in master shared object list. */ +struct so_list *master_so_list (void); + +/* Return address of first so_list entry in master shared object list. */ +struct so_list *master_so_list (void); + /* Find solib binary file and open it. */ extern int solib_open (char *in_pathname, char **found_pathname); +/* Add the list of sections in so_list to the target to_sections. */ +extern void add_to_target_sections (int, struct target_ops *, struct so_list *); + /* FIXME: gdbarch needs to control this variable */ extern struct target_so_ops *current_target_so_ops; diff --git a/gnu/usr.bin/binutils/gdb/symfile-mem.c b/gnu/usr.bin/binutils/gdb/symfile-mem.c index 71991cffdef..33f9a450a1d 100644 --- a/gnu/usr.bin/binutils/gdb/symfile-mem.c +++ b/gnu/usr.bin/binutils/gdb/symfile-mem.c @@ -100,7 +100,7 @@ symbol_file_add_from_memory (struct bfd *templ, CORE_ADDR addr, int from_tty) } objf = symbol_file_add_from_bfd (nbfd, from_tty, - sai, 0, OBJF_SHARED); + sai, 2, OBJF_SHARED); /* This might change our ideas about frames already looked at. */ reinit_frame_cache (); diff --git a/gnu/usr.bin/binutils/gdb/symfile.c b/gnu/usr.bin/binutils/gdb/symfile.c index ee9336d30e7..160e2c464dd 100644 --- a/gnu/usr.bin/binutils/gdb/symfile.c +++ b/gnu/usr.bin/binutils/gdb/symfile.c @@ -48,6 +48,7 @@ #include "readline/readline.h" #include "gdb_assert.h" #include "block.h" +#include "varobj.h" #include <sys/types.h> #include <fcntl.h> @@ -586,7 +587,7 @@ syms_from_objfile (struct objfile *objfile, We no longer warn if the lowest section is not a text segment (as happens for the PA64 port. */ - if (!mainline && addrs && addrs->other[0].name) + if (addrs && addrs->other[0].name) { asection *lower_sect; asection *sect; @@ -987,6 +988,10 @@ symbol_file_clear (int from_tty) && !query ("Discard symbol table from `%s'? ", symfile_objfile->name)) error ("Not confirmed."); +#ifdef CLEAR_SOLIB + CLEAR_SOLIB (); +#endif + free_all_objfiles (); /* solib descriptors may have handles to objfiles. Since their @@ -1979,6 +1984,8 @@ reread_symbols (void) /* Discard cleanups as symbol reading was successful. */ discard_cleanups (old_cleanups); + init_entry_point_info (objfile); + /* If the mtime has changed between the time we set new_modtime and now, we *want* this to be out of date, so don't call stat again now. */ @@ -2338,6 +2345,7 @@ clear_symtab_users (void) clear_pc_function_cache (); if (deprecated_target_new_objfile_hook) deprecated_target_new_objfile_hook (NULL); + varobj_refresh (); } static void diff --git a/gnu/usr.bin/binutils/gdb/varobj.c b/gnu/usr.bin/binutils/gdb/varobj.c index c662518c82f..dfc733874f4 100644 --- a/gnu/usr.bin/binutils/gdb/varobj.c +++ b/gnu/usr.bin/binutils/gdb/varobj.c @@ -549,7 +549,7 @@ varobj_gen_name (void) /* generate a name for this object */ id++; - xasprintf (&obj_name, "var%d", id); + obj_name = xstrprintf ("var%d", id); return obj_name; } @@ -854,6 +854,62 @@ varobj_list (struct varobj ***varlist) return rootcount; } +void +varobj_refresh (void) +{ + struct varobj *var; + struct varobj_root *croot; + int mycount = rootcount; + char * name; + + croot = rootlist; + while ((croot != NULL) && (mycount > 0)) + { + var = croot->rootvar; + + /* Get rid of the memory for the old expression. This also + leaves var->root->exp == NULL, which is ok for the parsing + below. */ + free_current_contents ((char **) &var->root->exp); + + value_free (var->value); + var->type = NULL; + + name = xstrdup (var->name); + + /* Reparse the expression. Wrap the call to parse expression, + so we can return a sensible error. */ + if (!gdb_parse_exp_1 (&name, var->root->valid_block, 0, &var->root->exp)) + { + return; + } + + /* We definitively need to catch errors here. + If evaluate_expression succeeds we got the value we wanted. + But if it fails, we still go on with a call to evaluate_type() */ + if (gdb_evaluate_expression (var->root->exp, &var->value)) + { + /* no error */ + release_value (var->value); + if (VALUE_LAZY (var->value)) + gdb_value_fetch_lazy (var->value); + } + else + var->value = evaluate_type (var->root->exp); + + var->type = VALUE_TYPE (var->value); + + mycount--; + croot = croot->next; + } + + if (mycount || (croot != NULL)) + warning + ("varobj_refresh: assertion failed - wrong tally of root vars (%d:%d)", + rootcount, mycount); +} + + /* Update the values for a variable and its children. This is a two-pronged attack. First, re-parse the value for the root's expression to see if it's changed. Then go all the way @@ -1254,7 +1310,7 @@ create_child (struct varobj *parent, int index, char *name) child->error = 1; child->parent = parent; child->root = parent->root; - xasprintf (&childs_name, "%s.%s", parent->obj_name, name); + childs_name = xstrprintf ("%s.%s", parent->obj_name, name); child->obj_name = childs_name; install_variable (child); @@ -1837,7 +1893,7 @@ c_name_of_child (struct varobj *parent, int index) switch (TYPE_CODE (type)) { case TYPE_CODE_ARRAY: - xasprintf (&name, "%d", index); + name = xstrprintf ("%d", index); break; case TYPE_CODE_STRUCT: @@ -1856,7 +1912,7 @@ c_name_of_child (struct varobj *parent, int index) break; default: - xasprintf (&name, "*%s", parent->name); + name = xstrprintf ("*%s", parent->name); break; } break; @@ -2070,7 +2126,7 @@ c_value_of_variable (struct varobj *var) case TYPE_CODE_ARRAY: { char *number; - xasprintf (&number, "[%d]", var->num_children); + number = xstrprintf ("[%d]", var->num_children); return (number); } /* break; */ @@ -2558,7 +2614,7 @@ _initialize_varobj (void) varobj_table = xmalloc (sizeof_table); memset (varobj_table, 0, sizeof_table); - add_show_from_set (add_set_cmd ("debugvarobj", class_maintenance, var_zinteger, (char *) &varobjdebug, "Set varobj debugging.\n\ + deprecated_add_show_from_set (add_set_cmd ("debugvarobj", class_maintenance, var_zinteger, (char *) &varobjdebug, "Set varobj debugging.\n\ When non-zero, varobj debugging is enabled.", &setlist), &showlist); } diff --git a/gnu/usr.bin/binutils/gdb/varobj.h b/gnu/usr.bin/binutils/gdb/varobj.h index cd3023310a6..484d60ecf1f 100644 --- a/gnu/usr.bin/binutils/gdb/varobj.h +++ b/gnu/usr.bin/binutils/gdb/varobj.h @@ -97,4 +97,6 @@ extern int varobj_list (struct varobj ***rootlist); extern int varobj_update (struct varobj **varp, struct varobj ***changelist); +extern void varobj_refresh(void); + #endif /* VAROBJ_H */ |