mirror of
https://sourceware.org/git/binutils-gdb.git
synced 2025-02-23 13:21:43 +08:00
gdb/
* 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:
parent
aacbb8a556
commit
3582629f2d
@ -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>
|
||||
|
||||
* ppc-linux-nat.c (ppc_linux_new_thread): Clear the new thread's
|
||||
|
155
gdb/solib-dsbt.c
155
gdb/solib-dsbt.c
@ -408,7 +408,7 @@ fetch_loadmap (CORE_ADDR ldmaddr)
|
||||
}
|
||||
|
||||
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
|
||||
returned and the corresponding PTR is set. */
|
||||
@ -754,8 +754,6 @@ dsbt_current_sos (void)
|
||||
sizeof (lm_buf.l_next), byte_order);
|
||||
}
|
||||
|
||||
enable_break2 ();
|
||||
|
||||
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
|
||||
the shared libraries. This function enables that breakpoint.
|
||||
|
||||
On the TIC6X, using the shared library (DSBT), the symbol
|
||||
_dl_debug_addr points to the r_debug struct which contains
|
||||
a field called r_brk. r_brk is the address of the function
|
||||
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. */
|
||||
On the TIC6X, using the shared library (DSBT), GDB can try to place
|
||||
a breakpoint on '_dl_debug_state' to monitor the shared library
|
||||
event. */
|
||||
|
||||
static int
|
||||
enable_break2 (void)
|
||||
enable_break (void)
|
||||
{
|
||||
enum bfd_endian byte_order = gdbarch_byte_order (target_gdbarch ());
|
||||
int success = 0;
|
||||
char **bkpt_namep;
|
||||
asection *interp_sect;
|
||||
struct dsbt_info *info = get_dsbt_info ();
|
||||
struct dsbt_info *info;
|
||||
|
||||
if (exec_bfd == NULL)
|
||||
return 0;
|
||||
@ -826,6 +810,8 @@ enable_break2 (void)
|
||||
if (!target_has_execution)
|
||||
return 0;
|
||||
|
||||
info = get_dsbt_info ();
|
||||
|
||||
if (info->enable_break2_done)
|
||||
return 1;
|
||||
|
||||
@ -846,6 +832,7 @@ enable_break2 (void)
|
||||
gdb_byte addr_buf[TIC6X_PTR_SIZE];
|
||||
struct int_elf32_dsbt_loadmap *ldm;
|
||||
volatile struct gdb_exception ex;
|
||||
int ret;
|
||||
|
||||
/* Read the contents of the .interp section into a local buffer;
|
||||
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);
|
||||
}
|
||||
|
||||
addr = gdb_bfd_lookup_symbol (tmp_bfd, cmp_name, "_dl_debug_addr");
|
||||
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)
|
||||
addr = gdb_bfd_lookup_symbol (tmp_bfd, cmp_name, "_dl_debug_state");
|
||||
if (addr != 0)
|
||||
{
|
||||
if (solib_dsbt_debug)
|
||||
fprintf_unfiltered (gdb_stdlog,
|
||||
"enable_break: ldso not yet initialized\n");
|
||||
/* Do not warn, but mark to run again. */
|
||||
return 0;
|
||||
}
|
||||
"enable_break: _dl_debug_state (prior to relocation) = %s\n",
|
||||
hex_string_custom (addr, 8));
|
||||
addr += displacement_from_map (ldm, addr);
|
||||
|
||||
/* Fetch the r_brk field. It's 8 bytes from the start of
|
||||
_dl_debug_addr. */
|
||||
if (target_read_memory (addr + 8, addr_buf, sizeof addr_buf) != 0)
|
||||
{
|
||||
warning (_("Unable to fetch _dl_debug_addr->r_brk "
|
||||
"(at address %s) from dynamic linker"),
|
||||
hex_string_custom (addr + 8, 8));
|
||||
enable_break_failure_warning ();
|
||||
gdb_bfd_unref (tmp_bfd);
|
||||
return 0;
|
||||
if (solib_dsbt_debug)
|
||||
fprintf_unfiltered (gdb_stdlog,
|
||||
"enable_break: _dl_debug_state (after relocation) = %s\n",
|
||||
hex_string_custom (addr, 8));
|
||||
|
||||
/* Now (finally!) create the solib breakpoint. */
|
||||
create_solib_event_breakpoint (target_gdbarch (), addr);
|
||||
|
||||
info->enable_break2_done = 1;
|
||||
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. */
|
||||
gdb_bfd_unref (tmp_bfd);
|
||||
@ -960,16 +916,7 @@ enable_break2 (void)
|
||||
/* We're also done with the loadmap. */
|
||||
xfree (ldm);
|
||||
|
||||
/* Remove all the solib event breakpoints. Their addresses
|
||||
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;
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* Tell the user we couldn't set a dynamic linker breakpoint. */
|
||||
@ -979,44 +926,6 @@ enable_break2 (void)
|
||||
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
|
||||
way, we are called to do any system specific symbol handling that
|
||||
is needed. */
|
||||
|
Loading…
Reference in New Issue
Block a user