1139 lines
38 KiB
Diff
1139 lines
38 KiB
Diff
|
--- gdb-6.3/gdb/dwarf2read.c.fix Mon Jan 10 14:36:22 2005
|
|||
|
+++ gdb-6.3/gdb/dwarf2read.c Mon Jan 10 14:39:34 2005
|
|||
|
@@ -1201,7 +1201,7 @@ dwarf2_build_psymtabs (struct objfile *o
|
|||
|
else
|
|||
|
dwarf2_per_objfile->loc_buffer = NULL;
|
|||
|
|
|||
|
- if (mainline
|
|||
|
+ if ((mainline == 1)
|
|||
|
|| (objfile->global_psymbols.size == 0
|
|||
|
&& objfile->static_psymbols.size == 0))
|
|||
|
{
|
|||
|
--- gdb-6.3/gdb/auxv.c.fix Mon Jan 10 14:36:34 2005
|
|||
|
+++ gdb-6.3/gdb/auxv.c Mon Jan 10 14:39:34 2005
|
|||
|
@@ -119,7 +119,7 @@ target_auxv_read (struct target_ops *ops
|
|||
|
Return 1 if an entry was read into *TYPEP and *VALP. */
|
|||
|
int
|
|||
|
target_auxv_parse (struct target_ops *ops, char **readptr, char *endptr,
|
|||
|
- CORE_ADDR *typep, CORE_ADDR *valp)
|
|||
|
+ ULONGEST *typep, CORE_ADDR *valp)
|
|||
|
{
|
|||
|
const int sizeof_auxv_field = TYPE_LENGTH (builtin_type_void_data_ptr);
|
|||
|
char *ptr = *readptr;
|
|||
|
@@ -144,9 +144,10 @@ target_auxv_parse (struct target_ops *op
|
|||
|
an error getting the information. On success, return 1 after
|
|||
|
storing the entry's value field in *VALP. */
|
|||
|
int
|
|||
|
-target_auxv_search (struct target_ops *ops, CORE_ADDR match, CORE_ADDR *valp)
|
|||
|
+target_auxv_search (struct target_ops *ops, ULONGEST match, CORE_ADDR *valp)
|
|||
|
{
|
|||
|
- CORE_ADDR type, val;
|
|||
|
+ CORE_ADDR val;
|
|||
|
+ ULONGEST at_type;
|
|||
|
char *data;
|
|||
|
int n = target_auxv_read (ops, &data);
|
|||
|
char *ptr = data;
|
|||
|
@@ -156,10 +157,10 @@ target_auxv_search (struct target_ops *o
|
|||
|
return n;
|
|||
|
|
|||
|
while (1)
|
|||
|
- switch (target_auxv_parse (ops, &ptr, data + n, &type, &val))
|
|||
|
+ switch (target_auxv_parse (ops, &ptr, data + n, &at_type, &val))
|
|||
|
{
|
|||
|
case 1: /* Here's an entry, check it. */
|
|||
|
- if (type == match)
|
|||
|
+ if (at_type == match)
|
|||
|
{
|
|||
|
xfree (data);
|
|||
|
*valp = val;
|
|||
|
@@ -182,7 +183,8 @@ target_auxv_search (struct target_ops *o
|
|||
|
int
|
|||
|
fprint_target_auxv (struct ui_file *file, struct target_ops *ops)
|
|||
|
{
|
|||
|
- CORE_ADDR type, val;
|
|||
|
+ CORE_ADDR val;
|
|||
|
+ ULONGEST at_type;
|
|||
|
char *data;
|
|||
|
int len = target_auxv_read (ops, &data);
|
|||
|
char *ptr = data;
|
|||
|
@@ -191,14 +193,14 @@ fprint_target_auxv (struct ui_file *file
|
|||
|
if (len <= 0)
|
|||
|
return len;
|
|||
|
|
|||
|
- while (target_auxv_parse (ops, &ptr, data + len, &type, &val) > 0)
|
|||
|
+ while (target_auxv_parse (ops, &ptr, data + len, &at_type, &val) > 0)
|
|||
|
{
|
|||
|
extern int addressprint;
|
|||
|
const char *name = "???";
|
|||
|
const char *description = "";
|
|||
|
enum { dec, hex, str } flavor = hex;
|
|||
|
|
|||
|
- switch (type)
|
|||
|
+ switch (at_type)
|
|||
|
{
|
|||
|
#define TAG(tag, text, kind) \
|
|||
|
case tag: name = #tag; description = text; flavor = kind; break
|
|||
|
@@ -249,7 +251,7 @@ fprint_target_auxv (struct ui_file *file
|
|||
|
}
|
|||
|
|
|||
|
fprintf_filtered (file, "%-4s %-20s %-30s ",
|
|||
|
- paddr_d (type), name, description);
|
|||
|
+ paddr_d (at_type), name, description);
|
|||
|
switch (flavor)
|
|||
|
{
|
|||
|
case dec:
|
|||
|
--- gdb-6.3/gdb/auxv.h.fix Mon Jan 10 14:36:39 2005
|
|||
|
+++ gdb-6.3/gdb/auxv.h Mon Jan 10 14:39:34 2005
|
|||
|
@@ -43,14 +43,14 @@ extern LONGEST target_auxv_read (struct
|
|||
|
Return 1 if an entry was read into *TYPEP and *VALP. */
|
|||
|
extern int target_auxv_parse (struct target_ops *ops,
|
|||
|
char **readptr, char *endptr,
|
|||
|
- CORE_ADDR *typep, CORE_ADDR *valp);
|
|||
|
+ ULONGEST *typep, CORE_ADDR *valp);
|
|||
|
|
|||
|
/* Extract the auxiliary vector entry with a_type matching MATCH.
|
|||
|
Return zero if no such entry was found, or -1 if there was
|
|||
|
an error getting the information. On success, return 1 after
|
|||
|
storing the entry's value field in *VALP. */
|
|||
|
extern int target_auxv_search (struct target_ops *ops,
|
|||
|
- CORE_ADDR match, CORE_ADDR *valp);
|
|||
|
+ ULONGEST match, CORE_ADDR *valp);
|
|||
|
|
|||
|
/* Print the contents of the target's AUXV on the specified file. */
|
|||
|
extern int fprint_target_auxv (struct ui_file *file, struct target_ops *ops);
|
|||
|
--- gdb-6.3/gdb/breakpoint.h.fix Mon Jan 10 14:36:45 2005
|
|||
|
+++ gdb-6.3/gdb/breakpoint.h Mon Jan 10 14:39:34 2005
|
|||
|
@@ -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
|
|||
|
@@ -778,8 +779,12 @@ extern void remove_thread_event_breakpoi
|
|||
|
|
|||
|
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,
|
|||
|
--- gdb-6.3/gdb/symfile-mem.c.fix Mon Jan 10 14:36:15 2005
|
|||
|
+++ gdb-6.3/gdb/symfile-mem.c Mon Jan 10 14:39:34 2005
|
|||
|
@@ -103,7 +103,7 @@ symbol_file_add_from_memory (struct bfd
|
|||
|
}
|
|||
|
|
|||
|
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 ();
|
|||
|
--- gdb-6.3/gdb/infrun.c.fix Mon Jan 10 14:36:50 2005
|
|||
|
+++ gdb-6.3/gdb/infrun.c Mon Jan 10 14:39:34 2005
|
|||
|
@@ -2203,6 +2203,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
|
|||
|
--- gdb-6.3/gdb/objfiles.c.fix Mon Jan 10 14:37:04 2005
|
|||
|
+++ gdb-6.3/gdb/objfiles.c Mon Jan 10 14:39:34 2005
|
|||
|
@@ -46,6 +46,8 @@
|
|||
|
#include "block.h"
|
|||
|
#include "dictionary.h"
|
|||
|
|
|||
|
+#include "elf/common.h"
|
|||
|
+
|
|||
|
/* Prototypes for local functions */
|
|||
|
|
|||
|
static void objfile_alloc_data (struct objfile *objfile);
|
|||
|
@@ -257,7 +259,19 @@ init_entry_point_info (struct objfile *o
|
|||
|
CORE_ADDR
|
|||
|
entry_point_address (void)
|
|||
|
{
|
|||
|
- return symfile_objfile ? symfile_objfile->ei.entry_point : 0;
|
|||
|
+ int ret;
|
|||
|
+ CORE_ADDR entry_addr;
|
|||
|
+
|
|||
|
+ /* Find the address of the entry point of the program from the
|
|||
|
+ auxv vector. */
|
|||
|
+ ret = target_auxv_search (¤t_target, AT_ENTRY, &entry_addr);
|
|||
|
+ if (ret == 1)
|
|||
|
+ return entry_addr;
|
|||
|
+ /*if (ret == 0 || ret == -1)*/
|
|||
|
+ else
|
|||
|
+ {
|
|||
|
+ return symfile_objfile ? symfile_objfile->ei.entry_point : 0;
|
|||
|
+ }
|
|||
|
}
|
|||
|
|
|||
|
/* Create the terminating entry of OBJFILE's minimal symbol table.
|
|||
|
--- gdb-6.3/gdb/solib-svr4.c.fix Mon Jan 10 14:37:15 2005
|
|||
|
+++ gdb-6.3/gdb/solib-svr4.c Mon Jan 10 14:39:34 2005
|
|||
|
@@ -34,6 +34,7 @@
|
|||
|
#include "gdbcore.h"
|
|||
|
#include "target.h"
|
|||
|
#include "inferior.h"
|
|||
|
+#include "command.h"
|
|||
|
|
|||
|
#include "solist.h"
|
|||
|
#include "solib-svr4.h"
|
|||
|
@@ -168,7 +169,9 @@ static CORE_ADDR breakpoint_addr; /* Add
|
|||
|
|
|||
|
/* Local function prototypes */
|
|||
|
|
|||
|
+#if 0
|
|||
|
static int match_main (char *);
|
|||
|
+#endif
|
|||
|
|
|||
|
static CORE_ADDR bfd_lookup_symbol (bfd *, char *, flagword);
|
|||
|
|
|||
|
@@ -290,22 +293,79 @@ 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;
|
|||
|
+ int ret;
|
|||
|
+
|
|||
|
+ /* Find the address of the entry point of the program from the
|
|||
|
+ auxv vector. */
|
|||
|
+ ret = target_auxv_search (¤t_target, AT_ENTRY, &entry_addr);
|
|||
|
+
|
|||
|
+ if (ret == 0 || ret == -1)
|
|||
|
+ {
|
|||
|
+ /* No auxv info, maybe an older kernel. Fake our way through. */
|
|||
|
+ entry_addr = bfd_get_start_address (exec_bfd);
|
|||
|
+
|
|||
|
+ if (debug_solib)
|
|||
|
+ fprintf_unfiltered (gdb_stdlog,
|
|||
|
+ "elf_locate_base: program entry address not found. Using bfd's 0x%s for %s\n",
|
|||
|
+ paddr_nz (entry_addr), exec_bfd->filename);
|
|||
|
+ }
|
|||
|
+ else
|
|||
|
+ {
|
|||
|
+ if (debug_solib)
|
|||
|
+ fprintf_unfiltered (gdb_stdlog,
|
|||
|
+ "elf_locate_base: found program entry address 0x%s for %s\n",
|
|||
|
+ paddr_nz (entry_addr), exec_bfd->filename);
|
|||
|
+ }
|
|||
|
|
|||
|
/* Find the start address of the .dynamic section. */
|
|||
|
dyninfo_sect = bfd_get_section_by_name (exec_bfd, ".dynamic");
|
|||
|
if (dyninfo_sect == NULL)
|
|||
|
- return 0;
|
|||
|
+ {
|
|||
|
+ if (debug_solib)
|
|||
|
+ fprintf_unfiltered (gdb_stdlog,
|
|||
|
+ "elf_locate_base: .dynamic section not found in %s -- return now\n",
|
|||
|
+ exec_bfd->filename);
|
|||
|
+ return 0;
|
|||
|
+ }
|
|||
|
+ else
|
|||
|
+ {
|
|||
|
+ if (debug_solib)
|
|||
|
+ fprintf_unfiltered (gdb_stdlog,
|
|||
|
+ "elf_locate_base: .dynamic section found in %s\n",
|
|||
|
+ exec_bfd->filename);
|
|||
|
+ }
|
|||
|
+
|
|||
|
dyninfo_addr = bfd_section_vma (exec_bfd, dyninfo_sect);
|
|||
|
+ if (debug_solib)
|
|||
|
+ fprintf_unfiltered (gdb_stdlog,
|
|||
|
+ "elf_locate_base: unrelocated .dynamic addr 0x%s\n",
|
|||
|
+ paddr_nz (dyninfo_addr));
|
|||
|
+
|
|||
|
+ relocated_dyninfo_addr = dyninfo_addr
|
|||
|
+ + entry_addr - bfd_get_start_address(exec_bfd);
|
|||
|
+ if (debug_solib)
|
|||
|
+ fprintf_unfiltered (gdb_stdlog,
|
|||
|
+ "elf_locate_base: relocated .dyn addr 0x%s for %s\n",
|
|||
|
+ paddr_nz(relocated_dyninfo_addr), exec_bfd->filename);
|
|||
|
|
|||
|
/* 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))
|
|||
|
- return 0;
|
|||
|
+ if (debug_solib)
|
|||
|
+ fprintf_unfiltered (gdb_stdlog,
|
|||
|
+ "elf_locate_base: read in .dynamic section\n");
|
|||
|
+ if (target_read_memory (relocated_dyninfo_addr, buf, dyninfo_sect_size))
|
|||
|
+ {
|
|||
|
+ if (debug_solib)
|
|||
|
+ fprintf_unfiltered (gdb_stdlog,
|
|||
|
+ "elf_locate_base: couldn't read .dynamic section at 0x%s -- return now\n",
|
|||
|
+ paddr_nz (relocated_dyninfo_addr));
|
|||
|
+ return 0;
|
|||
|
+ }
|
|||
|
|
|||
|
/* Find the DT_DEBUG entry in the the .dynamic section.
|
|||
|
For mips elf we look for DT_MIPS_RLD_MAP, mips elf apparently has
|
|||
|
@@ -332,6 +392,10 @@ elf_locate_base (void)
|
|||
|
{
|
|||
|
dyn_ptr = bfd_h_get_32 (exec_bfd,
|
|||
|
(bfd_byte *) x_dynp->d_un.d_ptr);
|
|||
|
+ if (debug_solib)
|
|||
|
+ fprintf_unfiltered (gdb_stdlog,
|
|||
|
+ "elf_locate_base: DT_DEBUG entry has value 0x%s -- return now\n",
|
|||
|
+ paddr_nz (dyn_ptr));
|
|||
|
return dyn_ptr;
|
|||
|
}
|
|||
|
else if (dyn_tag == DT_MIPS_RLD_MAP)
|
|||
|
@@ -470,6 +534,10 @@ first_link_map_member (void)
|
|||
|
char *r_map_buf = xmalloc (lmo->r_map_size);
|
|||
|
struct cleanup *cleanups = make_cleanup (xfree, r_map_buf);
|
|||
|
|
|||
|
+ if (debug_solib)
|
|||
|
+ fprintf_unfiltered (gdb_stdlog,
|
|||
|
+ "first_link_map_member: read at 0x%s\n",
|
|||
|
+ paddr_nz (debug_base + lmo->r_map_offset));
|
|||
|
read_memory (debug_base + lmo->r_map_offset, r_map_buf, lmo->r_map_size);
|
|||
|
|
|||
|
/* Assume that the address is unsigned. */
|
|||
|
@@ -583,6 +651,10 @@ svr4_current_sos (void)
|
|||
|
CORE_ADDR lm;
|
|||
|
struct so_list *head = 0;
|
|||
|
struct so_list **link_ptr = &head;
|
|||
|
+ if (debug_solib)
|
|||
|
+ fprintf_unfiltered (gdb_stdlog,
|
|||
|
+ "svr4_current_sos: exec_bfd %s\n",
|
|||
|
+ exec_bfd->filename);
|
|||
|
|
|||
|
/* Make sure we've looked up the inferior's dynamic linker's base
|
|||
|
structure. */
|
|||
|
@@ -593,12 +665,22 @@ svr4_current_sos (void)
|
|||
|
/* If we can't find the dynamic linker's base structure, this
|
|||
|
must not be a dynamically linked executable. Hmm. */
|
|||
|
if (! debug_base)
|
|||
|
- return 0;
|
|||
|
+ {
|
|||
|
+ if (debug_solib)
|
|||
|
+ fprintf_unfiltered (gdb_stdlog,
|
|||
|
+ "svr4_current_sos: no DT_DEBUG found in %s -- return now\n",
|
|||
|
+ exec_bfd->filename);
|
|||
|
+ return 0;
|
|||
|
+ }
|
|||
|
}
|
|||
|
|
|||
|
/* Walk the inferior's link map list, and build our list of
|
|||
|
`struct so_list' nodes. */
|
|||
|
- lm = first_link_map_member ();
|
|||
|
+ if (debug_solib)
|
|||
|
+ fprintf_unfiltered (gdb_stdlog,
|
|||
|
+ "svr4_current_sos: walk link map in %s\n",
|
|||
|
+ exec_bfd->filename);
|
|||
|
+ lm = first_link_map_member ();
|
|||
|
while (lm)
|
|||
|
{
|
|||
|
struct link_map_offsets *lmo = SVR4_FETCH_LINK_MAP_OFFSETS ();
|
|||
|
@@ -615,54 +697,156 @@ svr4_current_sos (void)
|
|||
|
make_cleanup (xfree, new->lm_info->lm);
|
|||
|
memset (new->lm_info->lm, 0, lmo->link_map_size);
|
|||
|
|
|||
|
+ if (debug_solib)
|
|||
|
+ fprintf_unfiltered (gdb_stdlog,
|
|||
|
+ "svr4_current_sos: read lm at 0x%s\n", paddr_nz(lm));
|
|||
|
read_memory (lm, new->lm_info->lm, lmo->link_map_size);
|
|||
|
|
|||
|
lm = LM_NEXT (new);
|
|||
|
|
|||
|
+ if (debug_solib)
|
|||
|
+ fprintf_unfiltered (gdb_stdlog,
|
|||
|
+ "svr4_current_sos: is first link entry? %d\n",
|
|||
|
+ IGNORE_FIRST_LINK_MAP_ENTRY (new));
|
|||
|
+
|
|||
|
/* For SVR4 versions, the first entry in the link map is for the
|
|||
|
inferior executable, so we must ignore it. For some versions of
|
|||
|
SVR4, it has no name. For others (Solaris 2.3 for example), it
|
|||
|
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;
|
|||
|
+
|
|||
|
+ if (debug_solib)
|
|||
|
+ fprintf_unfiltered (gdb_stdlog,
|
|||
|
+ "svr4_current_sos: Processing first link map entry\n");
|
|||
|
+ 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 = 1;*/
|
|||
|
+ new->main_relocated = 0;
|
|||
|
+
|
|||
|
+ if (debug_solib)
|
|||
|
+ {
|
|||
|
+ fprintf_unfiltered (gdb_stdlog,
|
|||
|
+ "svr4_current_sos: Processing nameless DSO\n");
|
|||
|
+ fprintf_unfiltered (gdb_stdlog,
|
|||
|
+ "svr4_current_sos: adding name %s\n",
|
|||
|
+ new->so_name);
|
|||
|
+ }
|
|||
|
+
|
|||
|
+ for (gdb_solib = master_so_list ();
|
|||
|
+ gdb_solib;
|
|||
|
+ gdb_solib = gdb_solib->next)
|
|||
|
+ {
|
|||
|
+ if (debug_solib)
|
|||
|
+ fprintf_unfiltered (gdb_stdlog,
|
|||
|
+ "svr4_current_sos: compare gdb %s and new %s\n",
|
|||
|
+ gdb_solib->so_name, new->so_name);
|
|||
|
+ if (strcmp (gdb_solib->so_name, new->so_name) == 0)
|
|||
|
+ if (gdb_solib->main_relocated)
|
|||
|
+ {
|
|||
|
+ if (debug_solib)
|
|||
|
+ fprintf_unfiltered (gdb_stdlog,
|
|||
|
+ "svr4_current_sos: found main relocated\n");
|
|||
|
+ 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
|
|||
|
{
|
|||
|
+ /* This is not the first link map entry, i.e. is not the main
|
|||
|
+ executable. Note however that it could be the DSO supplied on
|
|||
|
+ certain systems (i.e. Linux 2.6) containing information about
|
|||
|
+ the vsyscall page. We must ignore such entry. This entry is
|
|||
|
+ nameless (just like the one for the main executable, sigh). */
|
|||
|
+
|
|||
|
int errcode;
|
|||
|
char *buffer;
|
|||
|
|
|||
|
/* Extract this shared object's name. */
|
|||
|
+ if (debug_solib)
|
|||
|
+ fprintf_unfiltered (gdb_stdlog,
|
|||
|
+ "svr4_current_sos: read LM_NAME\n");
|
|||
|
+
|
|||
|
target_read_string (LM_NAME (new), &buffer,
|
|||
|
SO_NAME_MAX_PATH_SIZE - 1, &errcode);
|
|||
|
if (errcode != 0)
|
|||
|
{
|
|||
|
- warning ("current_sos: Can't read pathname for load map: %s\n",
|
|||
|
+ warning ("svr4_current_sos: Can't read pathname for load map: %s\n",
|
|||
|
safe_strerror (errcode));
|
|||
|
}
|
|||
|
else
|
|||
|
{
|
|||
|
+ if (debug_solib)
|
|||
|
+ fprintf_unfiltered (gdb_stdlog,
|
|||
|
+ "svr4_current_sos: LM_NAME is <%s>\n",
|
|||
|
+ buffer);
|
|||
|
+ /* The name could be empty, in which case it is the
|
|||
|
+ system supplied DSO. */
|
|||
|
+ if (strcmp (buffer, "") == 0)
|
|||
|
+ {
|
|||
|
+ xfree (buffer);
|
|||
|
+ free_so (new);
|
|||
|
+ }
|
|||
|
+
|
|||
|
+ else
|
|||
|
+ {
|
|||
|
strncpy (new->so_name, buffer, SO_NAME_MAX_PATH_SIZE - 1);
|
|||
|
new->so_name[SO_NAME_MAX_PATH_SIZE - 1] = '\0';
|
|||
|
xfree (buffer);
|
|||
|
strcpy (new->so_original_name, new->so_name);
|
|||
|
- }
|
|||
|
+ if (debug_solib)
|
|||
|
+ {
|
|||
|
+ fprintf_unfiltered (gdb_stdlog,
|
|||
|
+ "svr4_current_sos: Processing DSO: %s\n",
|
|||
|
+ new->so_name);
|
|||
|
+ fprintf_unfiltered (gdb_stdlog,
|
|||
|
+ "svr4_current_sos: first link entry %d\n",
|
|||
|
+ IGNORE_FIRST_LINK_MAP_ENTRY (new));
|
|||
|
+ }
|
|||
|
+
|
|||
|
+ new->next = 0;
|
|||
|
+ *link_ptr = new;
|
|||
|
+ link_ptr = &new->next;
|
|||
|
|
|||
|
- /* 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;
|
|||
|
- }
|
|||
|
+ }
|
|||
|
+ }
|
|||
|
}
|
|||
|
|
|||
|
discard_cleanups (old_chain);
|
|||
|
}
|
|||
|
|
|||
|
+ if (debug_solib)
|
|||
|
+ fprintf_unfiltered (gdb_stdlog,
|
|||
|
+ "svr4_current_sos: ENDS %s\n",
|
|||
|
+ exec_bfd->filename);
|
|||
|
+
|
|||
|
return head;
|
|||
|
}
|
|||
|
|
|||
|
@@ -681,7 +865,7 @@ svr4_fetch_objfile_link_map (struct objf
|
|||
|
return 0; /* failed somehow... */
|
|||
|
|
|||
|
/* Position ourselves on the first link map. */
|
|||
|
- lm = first_link_map_member ();
|
|||
|
+ lm = first_link_map_member ();
|
|||
|
while (lm)
|
|||
|
{
|
|||
|
/* Get info on the layout of the r_debug and link_map structures. */
|
|||
|
@@ -742,7 +926,7 @@ svr4_fetch_objfile_link_map (struct objf
|
|||
|
/* On some systems, the only way to recognize the link map entry for
|
|||
|
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)
|
|||
|
{
|
|||
|
@@ -756,6 +940,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. */
|
|||
|
@@ -855,6 +1040,11 @@ enable_break (void)
|
|||
|
/* Find the .interp section; if not found, warn the user and drop
|
|||
|
into the old breakpoint at symbol code. */
|
|||
|
interp_sect = bfd_get_section_by_name (exec_bfd, ".interp");
|
|||
|
+
|
|||
|
+ if (debug_solib)
|
|||
|
+ fprintf_unfiltered (gdb_stdlog,
|
|||
|
+ "enable_break: search for .interp in %s\n",
|
|||
|
+ exec_bfd->filename);
|
|||
|
if (interp_sect)
|
|||
|
{
|
|||
|
unsigned int interp_sect_size;
|
|||
|
@@ -888,6 +1078,9 @@ enable_break (void)
|
|||
|
if (tmp_fd >= 0)
|
|||
|
tmp_bfd = bfd_fdopenr (tmp_pathname, gnutarget, tmp_fd);
|
|||
|
|
|||
|
+ if (debug_solib)
|
|||
|
+ fprintf_unfiltered (gdb_stdlog,
|
|||
|
+ "enable_break: opening %s\n", tmp_pathname);
|
|||
|
if (tmp_bfd == NULL)
|
|||
|
goto bkpt_at_symbol;
|
|||
|
|
|||
|
@@ -968,6 +1161,9 @@ enable_break (void)
|
|||
|
if (sym_addr != 0)
|
|||
|
{
|
|||
|
create_solib_event_breakpoint (load_addr + sym_addr);
|
|||
|
+ if (debug_solib)
|
|||
|
+ fprintf_unfiltered (gdb_stdlog,
|
|||
|
+ "enable_break: solib bp set\n");
|
|||
|
return 1;
|
|||
|
}
|
|||
|
|
|||
|
@@ -1227,6 +1423,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
|
|||
|
@@ -1430,6 +1628,75 @@ svr4_lp64_fetch_link_map_offsets (void)
|
|||
|
|
|||
|
return lmp;
|
|||
|
}
|
|||
|
+void
|
|||
|
+info_linkmap_command (char *cmd, int from_tty)
|
|||
|
+{
|
|||
|
+ CORE_ADDR lm;
|
|||
|
+
|
|||
|
+ /* Make sure we've looked up the inferior's dynamic linker's base
|
|||
|
+ structure. */
|
|||
|
+ if (! debug_base)
|
|||
|
+ {
|
|||
|
+ debug_base = locate_base ();
|
|||
|
+
|
|||
|
+ /* If we can't find the dynamic linker's base structure, this
|
|||
|
+ must not be a dynamically linked executable. Hmm. */
|
|||
|
+ if (! debug_base)
|
|||
|
+ {
|
|||
|
+ if (debug_solib)
|
|||
|
+ fprintf_unfiltered (gdb_stdlog,
|
|||
|
+ "svr4_print_linkmap: no DT_DEBUG found in %s -- return now\n",
|
|||
|
+ exec_bfd->filename);
|
|||
|
+ return;
|
|||
|
+ }
|
|||
|
+ }
|
|||
|
+
|
|||
|
+ /* Walk the inferior's link map list, and print the info. */
|
|||
|
+
|
|||
|
+ lm = first_link_map_member ();
|
|||
|
+ while (lm)
|
|||
|
+ {
|
|||
|
+ int errcode;
|
|||
|
+ char *buffer;
|
|||
|
+ CORE_ADDR load_addr;
|
|||
|
+
|
|||
|
+ struct link_map_offsets *lmo = SVR4_FETCH_LINK_MAP_OFFSETS ();
|
|||
|
+ struct so_list *new
|
|||
|
+ = (struct so_list *) xmalloc (sizeof (struct so_list));
|
|||
|
+ struct cleanup *old_chain = make_cleanup (xfree, new);
|
|||
|
+
|
|||
|
+ memset (new, 0, sizeof (*new));
|
|||
|
+
|
|||
|
+ new->lm_info = xmalloc (sizeof (struct lm_info));
|
|||
|
+ make_cleanup (xfree, new->lm_info);
|
|||
|
+
|
|||
|
+ new->lm_info->lm = xmalloc (lmo->link_map_size);
|
|||
|
+ make_cleanup (xfree, new->lm_info->lm);
|
|||
|
+ memset (new->lm_info->lm, 0, lmo->link_map_size);
|
|||
|
+
|
|||
|
+ if (debug_solib)
|
|||
|
+ fprintf_unfiltered (gdb_stdlog,
|
|||
|
+ "svr4_print_linkmap: read lm at 0x%s\n", paddr_nz(lm));
|
|||
|
+ read_memory (lm, new->lm_info->lm, lmo->link_map_size);
|
|||
|
+
|
|||
|
+ lm = LM_NEXT (new);
|
|||
|
+
|
|||
|
+ /* Load address. */
|
|||
|
+ load_addr = LM_ADDR (new);
|
|||
|
+ /* Shared object's name. */
|
|||
|
+ target_read_string (LM_NAME (new), &buffer,
|
|||
|
+ SO_NAME_MAX_PATH_SIZE - 1, &errcode);
|
|||
|
+ make_cleanup (xfree, buffer);
|
|||
|
+ if (errcode != 0)
|
|||
|
+ {
|
|||
|
+ warning ("svr4_print_linkmap: Can't read pathname for load map: %s\n",
|
|||
|
+ safe_strerror (errcode));
|
|||
|
+ }
|
|||
|
+ fprintf_filtered (gdb_stdout, "%-8s %-30s\n", paddr(load_addr), buffer);
|
|||
|
+ do_cleanups (old_chain);
|
|||
|
+ }
|
|||
|
+}
|
|||
|
+
|
|||
|
|
|||
|
|
|||
|
static struct target_so_ops svr4_so_ops;
|
|||
|
@@ -1453,4 +1720,8 @@ _initialize_svr4_solib (void)
|
|||
|
|
|||
|
/* FIXME: Don't do this here. *_gdbarch_init() should set so_ops. */
|
|||
|
current_target_so_ops = &svr4_so_ops;
|
|||
|
+
|
|||
|
+ add_info ("linkmap", info_linkmap_command,
|
|||
|
+ "Display the inferior's linkmap.");
|
|||
|
+
|
|||
|
}
|
|||
|
--- gdb-6.3/gdb/varobj.c.fix Mon Jan 10 14:38:00 2005
|
|||
|
+++ gdb-6.3/gdb/varobj.c Mon Jan 10 14:39:35 2005
|
|||
|
@@ -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
|
|||
|
--- gdb-6.3/gdb/solist.h.fix Mon Jan 10 14:37:45 2005
|
|||
|
+++ gdb-6.3/gdb/solist.h Mon Jan 10 14:39:35 2005
|
|||
|
@@ -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;
|
|||
|
@@ -113,9 +115,15 @@ 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;
|
|||
|
|
|||
|
@@ -135,4 +143,6 @@ extern struct target_so_ops *current_tar
|
|||
|
#define TARGET_SO_FIND_AND_OPEN_SOLIB \
|
|||
|
(current_target_so_ops->find_and_open_solib)
|
|||
|
|
|||
|
+/* Controls the printing of debugging output. */
|
|||
|
+extern int debug_solib;
|
|||
|
#endif
|
|||
|
--- gdb-6.3/gdb/varobj.h.fix Mon Jan 10 14:38:06 2005
|
|||
|
+++ gdb-6.3/gdb/varobj.h Mon Jan 10 14:39:35 2005
|
|||
|
@@ -97,4 +97,6 @@ extern int varobj_list (struct varobj **
|
|||
|
|
|||
|
extern int varobj_update (struct varobj **varp, struct varobj ***changelist);
|
|||
|
|
|||
|
+extern void varobj_refresh(void);
|
|||
|
+
|
|||
|
#endif /* VAROBJ_H */
|
|||
|
--- gdb-6.3/gdb/symfile.c.fix Mon Jan 10 14:38:16 2005
|
|||
|
+++ gdb-6.3/gdb/symfile.c Mon Jan 10 14:39:35 2005
|
|||
|
@@ -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>
|
|||
|
@@ -558,7 +559,7 @@ syms_from_objfile (struct objfile *objfi
|
|||
|
|
|||
|
/* Now either addrs or offsets is non-zero. */
|
|||
|
|
|||
|
- if (mainline)
|
|||
|
+ if (mainline == 1)
|
|||
|
{
|
|||
|
/* We will modify the main symbol table, make sure that all its users
|
|||
|
will be cleaned up if an error occurs during symbol reading. */
|
|||
|
@@ -586,7 +587,7 @@ syms_from_objfile (struct objfile *objfi
|
|||
|
|
|||
|
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 (/*!mainline &&*/ addrs && addrs->other[0].name)
|
|||
|
{
|
|||
|
asection *lower_sect;
|
|||
|
asection *sect;
|
|||
|
@@ -755,17 +756,21 @@ new_symfile_objfile (struct objfile *obj
|
|||
|
/* If this is the main symbol file we have to clean up all users of the
|
|||
|
old main symbol file. Otherwise it is sufficient to fixup all the
|
|||
|
breakpoints that may have been redefined by this symbol file. */
|
|||
|
- if (mainline)
|
|||
|
+ if (mainline == 1)
|
|||
|
{
|
|||
|
/* OK, make it the "real" symbol file. */
|
|||
|
symfile_objfile = objfile;
|
|||
|
|
|||
|
clear_symtab_users ();
|
|||
|
}
|
|||
|
- else
|
|||
|
+ else if (mainline == 0)
|
|||
|
{
|
|||
|
breakpoint_re_set ();
|
|||
|
}
|
|||
|
+ else
|
|||
|
+ {
|
|||
|
+ /* Don't reset breakpoints or it will screw up PIE. */
|
|||
|
+ }
|
|||
|
|
|||
|
/* We're done reading the symbol file; finish off complaints. */
|
|||
|
clear_complaints (&symfile_complaints, 0, verbo);
|
|||
|
@@ -808,7 +813,7 @@ symbol_file_add_with_addrs_or_offsets (b
|
|||
|
interactively wiping out any existing symbols. */
|
|||
|
|
|||
|
if ((have_full_symbols () || have_partial_symbols ())
|
|||
|
- && mainline
|
|||
|
+ && (mainline == 1)
|
|||
|
&& from_tty
|
|||
|
&& !query ("Load new symbol table from \"%s\"? ", name))
|
|||
|
error ("Not confirmed.");
|
|||
|
@@ -987,6 +992,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 +1988,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 +2349,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
|
|||
|
--- gdb-6.3/gdb/breakpoint.c.fix Mon Jan 10 14:38:20 2005
|
|||
|
+++ gdb-6.3/gdb/breakpoint.c Mon Jan 10 14:39:35 2005
|
|||
|
@@ -3900,6 +3900,7 @@ describe_other_breakpoints (CORE_ADDR pc
|
|||
|
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
|
|||
|
@@ -4575,6 +4576,62 @@ 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->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)
|
|||
|
+ {
|
|||
|
+ /*printf ("enabling breakpoint at 0x%s\n", paddr_nz(b->loc->address));*/
|
|||
|
+ 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)
|
|||
|
@@ -6915,6 +6972,7 @@ delete_breakpoint (struct breakpoint *bp
|
|||
|
&& !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)
|
|||
|
{
|
|||
|
@@ -7128,7 +7186,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_shlib_disabled)
|
|||
|
b->enable_state = bp_disabled;
|
|||
|
else
|
|||
|
/* If resetting a shlib-disabled breakpoint, we don't want to
|
|||
|
--- gdb-6.3/gdb/solib.c.fix Mon Jan 10 14:38:26 2005
|
|||
|
+++ gdb-6.3/gdb/solib.c Mon Jan 10 15:04:59 2005
|
|||
|
@@ -47,6 +47,8 @@
|
|||
|
|
|||
|
/* external data declarations */
|
|||
|
|
|||
|
+int debug_solib;
|
|||
|
+
|
|||
|
/* FIXME: gdbarch needs to control this variable */
|
|||
|
struct target_so_ops *current_target_so_ops;
|
|||
|
|
|||
|
@@ -69,6 +71,8 @@ static char *solib_absolute_prefix = NUL
|
|||
|
and LD_LIBRARY_PATH. */
|
|||
|
static char *solib_search_path = NULL;
|
|||
|
|
|||
|
+void add_to_target_sections (int, struct target_ops *, struct so_list *);
|
|||
|
+
|
|||
|
/*
|
|||
|
|
|||
|
GLOBAL FUNCTION
|
|||
|
@@ -335,7 +339,6 @@ free_so (struct so_list *so)
|
|||
|
xfree (so);
|
|||
|
}
|
|||
|
|
|||
|
-
|
|||
|
/* Return address of first so_list entry in master shared object list. */
|
|||
|
struct so_list *
|
|||
|
master_so_list (void)
|
|||
|
@@ -343,7 +346,6 @@ master_so_list (void)
|
|||
|
return so_list_head;
|
|||
|
}
|
|||
|
|
|||
|
-
|
|||
|
/* A small stub to get us past the arg-passing pinhole of catch_errors. */
|
|||
|
|
|||
|
static int
|
|||
|
@@ -355,15 +357,40 @@ 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)
|
|||
|
+ {
|
|||
|
+ if (debug_solib)
|
|||
|
+ fprintf_unfiltered (gdb_stdlog,
|
|||
|
+ "symbol_add_stub: adding symbols for main\n");
|
|||
|
+ 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);
|
|||
|
@@ -458,6 +485,10 @@ update_solib_list (int from_tty, struct
|
|||
|
the inferior's current list. */
|
|||
|
while (i)
|
|||
|
{
|
|||
|
+ if (debug_solib)
|
|||
|
+ fprintf_unfiltered (gdb_stdlog,
|
|||
|
+ "update_solib_list: compare gdb:%s and inferior:%s\n",
|
|||
|
+ gdb->so_original_name, i->so_original_name);
|
|||
|
if (! strcmp (gdb->so_original_name, i->so_original_name))
|
|||
|
break;
|
|||
|
|
|||
|
@@ -511,32 +542,46 @@ update_solib_list (int from_tty, struct
|
|||
|
/* 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]));
|
|||
|
- }
|
|||
|
- }
|
|||
|
+ 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);
|
|||
|
+ if (debug_solib)
|
|||
|
+ fprintf_unfiltered (gdb_stdlog,
|
|||
|
+ "add_to_target_sections: add %s to to_sections\n",
|
|||
|
+ solib->so_original_name);
|
|||
|
+ memcpy (target->to_sections + space,
|
|||
|
+ solib->sections,
|
|||
|
+ count * sizeof (solib->sections[0]));
|
|||
|
+ }
|
|||
|
+ }
|
|||
|
+}
|
|||
|
|
|||
|
/* GLOBAL FUNCTION
|
|||
|
|
|||
|
@@ -917,4 +962,10 @@ This takes precedence over the environme
|
|||
|
deprecated_add_show_from_set (c, &showlist);
|
|||
|
set_cmd_cfunc (c, reload_shared_libraries);
|
|||
|
set_cmd_completer (c, filename_completer);
|
|||
|
+
|
|||
|
+ c = add_set_cmd ("solib", no_class, var_zinteger,
|
|||
|
+ (char *) &debug_solib,
|
|||
|
+ "Set debugging of GNU/Linux shlib module.\n\
|
|||
|
+Enables printf debugging output.\n", &setdebuglist);
|
|||
|
+ deprecated_add_show_from_set (c, &showdebuglist);
|
|||
|
}
|
|||
|
--- gdb-6.3/gdb/elfread.c.fix Mon Jan 10 14:38:32 2005
|
|||
|
+++ gdb-6.3/gdb/elfread.c Mon Jan 10 14:39:35 2005
|
|||
|
@@ -528,7 +528,7 @@ elf_symfile_read (struct objfile *objfil
|
|||
|
/* If we are reinitializing, or if we have never loaded syms yet,
|
|||
|
set table to empty. MAINLINE is cleared so that *_read_psymtab
|
|||
|
functions do not all also re-initialize the psymbol table. */
|
|||
|
- if (mainline)
|
|||
|
+ if (mainline == 1)
|
|||
|
{
|
|||
|
init_psymbol_list (objfile, 0);
|
|||
|
mainline = 0;
|