* solib-dsbt.c (enable_break): Declare.
	(dsbt_current_sos): Remove call to enable_break2.
	(enable_break2): Rename to enable_break.  Set solib breakpoint
	on '_dl_debug_state'.
	(enable_break): Remove.
This commit is contained in:
Yao Qi 2013-05-07 09:23:28 +00:00
parent aacbb8a556
commit 3582629f2d
2 changed files with 40 additions and 123 deletions

View file

@ -1,3 +1,11 @@
2013-05-07 Yao Qi <yao@codesourcery.com>
* solib-dsbt.c (enable_break): Declare.
(dsbt_current_sos): Remove call to enable_break2.
(enable_break2): Rename to enable_break. Set solib breakpoint
on '_dl_debug_state'.
(enable_break): Remove.
2013-05-07 Luis Machado <lgustavo@codesourcery.com> 2013-05-07 Luis Machado <lgustavo@codesourcery.com>
* ppc-linux-nat.c (ppc_linux_new_thread): Clear the new thread's * ppc-linux-nat.c (ppc_linux_new_thread): Clear the new thread's

View file

@ -408,7 +408,7 @@ fetch_loadmap (CORE_ADDR ldmaddr)
} }
static void dsbt_relocate_main_executable (void); static void dsbt_relocate_main_executable (void);
static int enable_break2 (void); static int enable_break (void);
/* Scan for DYNTAG in .dynamic section of ABFD. If DYNTAG is found 1 is /* Scan for DYNTAG in .dynamic section of ABFD. If DYNTAG is found 1 is
returned and the corresponding PTR is set. */ returned and the corresponding PTR is set. */
@ -754,8 +754,6 @@ dsbt_current_sos (void)
sizeof (lm_buf.l_next), byte_order); sizeof (lm_buf.l_next), byte_order);
} }
enable_break2 ();
return sos_head; return sos_head;
} }
@ -795,30 +793,16 @@ cmp_name (asymbol *sym, void *data)
for arranging for the inferior to hit a breakpoint after mapping in for arranging for the inferior to hit a breakpoint after mapping in
the shared libraries. This function enables that breakpoint. the shared libraries. This function enables that breakpoint.
On the TIC6X, using the shared library (DSBT), the symbol On the TIC6X, using the shared library (DSBT), GDB can try to place
_dl_debug_addr points to the r_debug struct which contains a breakpoint on '_dl_debug_state' to monitor the shared library
a field called r_brk. r_brk is the address of the function event. */
descriptor upon which a breakpoint must be placed. Being a
function descriptor, we must extract the entry point in order
to set the breakpoint.
Our strategy will be to get the .interp section from the
executable. This section will provide us with the name of the
interpreter. We'll open the interpreter and then look up
the address of _dl_debug_addr. We then relocate this address
using the interpreter's loadmap. Once the relocated address
is known, we fetch the value (address) corresponding to r_brk
and then use that value to fetch the entry point of the function
we're interested in. */
static int static int
enable_break2 (void) enable_break (void)
{ {
enum bfd_endian byte_order = gdbarch_byte_order (target_gdbarch ()); enum bfd_endian byte_order = gdbarch_byte_order (target_gdbarch ());
int success = 0;
char **bkpt_namep;
asection *interp_sect; asection *interp_sect;
struct dsbt_info *info = get_dsbt_info (); struct dsbt_info *info;
if (exec_bfd == NULL) if (exec_bfd == NULL)
return 0; return 0;
@ -826,6 +810,8 @@ enable_break2 (void)
if (!target_has_execution) if (!target_has_execution)
return 0; return 0;
info = get_dsbt_info ();
if (info->enable_break2_done) if (info->enable_break2_done)
return 1; return 1;
@ -846,6 +832,7 @@ enable_break2 (void)
gdb_byte addr_buf[TIC6X_PTR_SIZE]; gdb_byte addr_buf[TIC6X_PTR_SIZE];
struct int_elf32_dsbt_loadmap *ldm; struct int_elf32_dsbt_loadmap *ldm;
volatile struct gdb_exception ex; volatile struct gdb_exception ex;
int ret;
/* Read the contents of the .interp section into a local buffer; /* Read the contents of the .interp section into a local buffer;
the contents specify the dynamic linker this program uses. */ the contents specify the dynamic linker this program uses. */
@ -895,64 +882,33 @@ enable_break2 (void)
info->interp_plt_sect_low + bfd_section_size (tmp_bfd, interp_sect); info->interp_plt_sect_low + bfd_section_size (tmp_bfd, interp_sect);
} }
addr = gdb_bfd_lookup_symbol (tmp_bfd, cmp_name, "_dl_debug_addr"); addr = gdb_bfd_lookup_symbol (tmp_bfd, cmp_name, "_dl_debug_state");
if (addr == 0) if (addr != 0)
{
warning (_("Could not find symbol _dl_debug_addr in dynamic linker"));
enable_break_failure_warning ();
gdb_bfd_unref (tmp_bfd);
return 0;
}
if (solib_dsbt_debug)
fprintf_unfiltered (gdb_stdlog,
"enable_break: _dl_debug_addr (prior to relocation) = %s\n",
hex_string_custom (addr, 8));
addr += displacement_from_map (ldm, addr);
if (solib_dsbt_debug)
fprintf_unfiltered (gdb_stdlog,
"enable_break: _dl_debug_addr (after relocation) = %s\n",
hex_string_custom (addr, 8));
/* Fetch the address of the r_debug struct. */
if (target_read_memory (addr, addr_buf, sizeof addr_buf) != 0)
{
warning (_("Unable to fetch contents of _dl_debug_addr "
"(at address %s) from dynamic linker"),
hex_string_custom (addr, 8));
}
addr = extract_unsigned_integer (addr_buf, sizeof addr_buf, byte_order);
if (solib_dsbt_debug)
fprintf_unfiltered (gdb_stdlog,
"enable_break: _dl_debug_addr[0..3] = %s\n",
hex_string_custom (addr, 8));
/* If it's zero, then the ldso hasn't initialized yet, and so
there are no shared libs yet loaded. */
if (addr == 0)
{ {
if (solib_dsbt_debug) if (solib_dsbt_debug)
fprintf_unfiltered (gdb_stdlog, fprintf_unfiltered (gdb_stdlog,
"enable_break: ldso not yet initialized\n"); "enable_break: _dl_debug_state (prior to relocation) = %s\n",
/* Do not warn, but mark to run again. */ hex_string_custom (addr, 8));
return 0; addr += displacement_from_map (ldm, addr);
}
/* Fetch the r_brk field. It's 8 bytes from the start of if (solib_dsbt_debug)
_dl_debug_addr. */ fprintf_unfiltered (gdb_stdlog,
if (target_read_memory (addr + 8, addr_buf, sizeof addr_buf) != 0) "enable_break: _dl_debug_state (after relocation) = %s\n",
{ hex_string_custom (addr, 8));
warning (_("Unable to fetch _dl_debug_addr->r_brk "
"(at address %s) from dynamic linker"), /* Now (finally!) create the solib breakpoint. */
hex_string_custom (addr + 8, 8)); create_solib_event_breakpoint (target_gdbarch (), addr);
enable_break_failure_warning ();
gdb_bfd_unref (tmp_bfd); info->enable_break2_done = 1;
return 0; ret = 1;
}
else
{
if (solib_dsbt_debug)
fprintf_unfiltered (gdb_stdlog,
"enable_break: _dl_debug_state is not found\n");
ret = 0;
} }
addr = extract_unsigned_integer (addr_buf, sizeof addr_buf, byte_order);
/* We're done with the temporary bfd. */ /* We're done with the temporary bfd. */
gdb_bfd_unref (tmp_bfd); gdb_bfd_unref (tmp_bfd);
@ -960,16 +916,7 @@ enable_break2 (void)
/* We're also done with the loadmap. */ /* We're also done with the loadmap. */
xfree (ldm); xfree (ldm);
/* Remove all the solib event breakpoints. Their addresses return ret;
may have changed since the last time we ran the program. */
remove_solib_event_breakpoints ();
/* Now (finally!) create the solib breakpoint. */
create_solib_event_breakpoint (target_gdbarch (), addr);
info->enable_break2_done = 1;
return 1;
} }
/* Tell the user we couldn't set a dynamic linker breakpoint. */ /* Tell the user we couldn't set a dynamic linker breakpoint. */
@ -979,44 +926,6 @@ enable_break2 (void)
return 0; return 0;
} }
static int
enable_break (void)
{
asection *interp_sect;
struct minimal_symbol *start;
/* Check for the presence of a .interp section. If there is no
such section, the executable is statically linked. */
interp_sect = bfd_get_section_by_name (exec_bfd, ".interp");
if (interp_sect == NULL)
{
if (solib_dsbt_debug)
fprintf_unfiltered (gdb_stdlog,
"enable_break: No .interp section found.\n");
return 0;
}
start = lookup_minimal_symbol ("_start", NULL, symfile_objfile);
if (start == NULL)
{
if (solib_dsbt_debug)
fprintf_unfiltered (gdb_stdlog,
"enable_break: symbol _start is not found.\n");
return 0;
}
create_solib_event_breakpoint (target_gdbarch (),
SYMBOL_VALUE_ADDRESS (start));
if (solib_dsbt_debug)
fprintf_unfiltered (gdb_stdlog,
"enable_break: solib event breakpoint placed at : %s\n",
hex_string_custom (SYMBOL_VALUE_ADDRESS (start), 8));
return 1;
}
/* Once the symbols from a shared object have been loaded in the usual /* Once the symbols from a shared object have been loaded in the usual
way, we are called to do any system specific symbol handling that way, we are called to do any system specific symbol handling that
is needed. */ is needed. */