summaryrefslogtreecommitdiff
path: root/gnu/usr.bin/binutils/gdb
diff options
context:
space:
mode:
authorKurt Miller <kurt@cvs.openbsd.org>2008-11-11 22:57:49 +0000
committerKurt Miller <kurt@cvs.openbsd.org>2008-11-11 22:57:49 +0000
commite2c9af9ae9cffcad67d0c6845a64bf54ca71a713 (patch)
tree19db35e56679a5415105c7e780c8f3e33c183a7c /gnu/usr.bin/binutils/gdb
parentfdb019932caa27a3f61876da2ab864908b74ee31 (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.in6
-rw-r--r--gnu/usr.bin/binutils/gdb/breakpoint.c59
-rw-r--r--gnu/usr.bin/binutils/gdb/breakpoint.h5
-rw-r--r--gnu/usr.bin/binutils/gdb/infrun.c5
-rw-r--r--gnu/usr.bin/binutils/gdb/objfiles.c10
-rw-r--r--gnu/usr.bin/binutils/gdb/solib-svr4.c238
-rw-r--r--gnu/usr.bin/binutils/gdb/solib.c92
-rw-r--r--gnu/usr.bin/binutils/gdb/solist.h12
-rw-r--r--gnu/usr.bin/binutils/gdb/symfile-mem.c2
-rw-r--r--gnu/usr.bin/binutils/gdb/symfile.c10
-rw-r--r--gnu/usr.bin/binutils/gdb/varobj.c68
-rw-r--r--gnu/usr.bin/binutils/gdb/varobj.h2
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 (&current_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 (&current_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*/, &current_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 */