* mips-linux-tdep.c: Include "frame.h".
(mips_linux_in_dynsym_stub, mips_linux_in_dynsym_resolve_code) (mips_linux_skip_resolver): New functions. (mips_linux_init_abi): Call set_gdbarch_skip_solib_resolver and set_gdbarch_in_solib_call_trampoline. * mips-tdep.c (mips_gdbarch_init): Move gdbarch_init_osabi call to after set_gdbarch_in_solib_return_trampoline. Only set the solib hooks to mips16 functions if the OS ABI is unknown. * config/mips/tm-linux.h (IN_SOLIB_CALL_TRAMPOLINE): Undefine after including "config/tm-linux.h". (IN_SOLIB_DYNSYM_RESOLVE_CODE): Define. * Makefile.in (mips-linux-tdep.o): Update.
This commit is contained in:
parent
87b3ede8af
commit
6de918a6f5
@ -1,3 +1,18 @@
|
||||
2004-02-11 Daniel Jacobowitz <drow@mvista.com>
|
||||
|
||||
* mips-linux-tdep.c: Include "frame.h".
|
||||
(mips_linux_in_dynsym_stub, mips_linux_in_dynsym_resolve_code)
|
||||
(mips_linux_skip_resolver): New functions.
|
||||
(mips_linux_init_abi): Call set_gdbarch_skip_solib_resolver
|
||||
and set_gdbarch_in_solib_call_trampoline.
|
||||
* mips-tdep.c (mips_gdbarch_init): Move gdbarch_init_osabi call
|
||||
to after set_gdbarch_in_solib_return_trampoline. Only set the
|
||||
solib hooks to mips16 functions if the OS ABI is unknown.
|
||||
* config/mips/tm-linux.h (IN_SOLIB_CALL_TRAMPOLINE): Undefine after
|
||||
including "config/tm-linux.h".
|
||||
(IN_SOLIB_DYNSYM_RESOLVE_CODE): Define.
|
||||
* Makefile.in (mips-linux-tdep.o): Update.
|
||||
|
||||
2004-02-11 David Carlton <carlton@kealia.com>
|
||||
|
||||
* linespec.c (decode_compound): Only look for a class symbol when
|
||||
|
@ -2064,7 +2064,7 @@ mips-irix-tdep.o: mips-irix-tdep.c $(defs_h) $(osabi_h) $(elf_bfd_h)
|
||||
mips-linux-nat.o: mips-linux-nat.c $(defs_h) $(mips_tdep_h)
|
||||
mips-linux-tdep.o: mips-linux-tdep.c $(defs_h) $(gdbcore_h) $(target_h) \
|
||||
$(solib_svr4_h) $(osabi_h) $(mips_tdep_h) $(gdb_string_h) \
|
||||
$(gdb_assert_h)
|
||||
$(gdb_assert_h) $(frame_h)
|
||||
mips-nat.o: mips-nat.c $(defs_h) $(inferior_h) $(gdbcore_h) $(regcache_h)
|
||||
mipsnbsd-nat.o: mipsnbsd-nat.c $(defs_h) $(inferior_h) $(regcache_h) \
|
||||
$(mipsnbsd_tdep_h)
|
||||
|
@ -1,6 +1,6 @@
|
||||
/* Target-dependent definitions for GNU/Linux MIPS.
|
||||
|
||||
Copyright 2001, 2002 Free Software Foundation, Inc.
|
||||
Copyright 2001, 2002, 2004 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GDB.
|
||||
|
||||
@ -26,7 +26,6 @@
|
||||
|
||||
/* We don't want to inherit tm-mips.h's shared library trampoline code. */
|
||||
|
||||
#undef IN_SOLIB_CALL_TRAMPOLINE
|
||||
#undef IN_SOLIB_RETURN_TRAMPOLINE
|
||||
#undef SKIP_TRAMPOLINE_CODE
|
||||
#undef IGNORE_HELPER_CALL
|
||||
@ -50,4 +49,14 @@
|
||||
#undef IN_SIGTRAMP
|
||||
#define IN_SIGTRAMP(pc, name) (0)
|
||||
|
||||
#undef IN_SOLIB_DYNSYM_RESOLVE_CODE
|
||||
#define IN_SOLIB_DYNSYM_RESOLVE_CODE(PC) mips_linux_in_dynsym_resolve_code (PC)
|
||||
int mips_linux_in_dynsym_resolve_code (CORE_ADDR pc);
|
||||
|
||||
/* We don't want all of tm-sysv4.h's shared library trampoline code either.
|
||||
Note that by undefining IN_SOLIB_CALL_TRAMPOLINE here we will use the
|
||||
gdbarch vector's version instead. */
|
||||
|
||||
#undef IN_SOLIB_CALL_TRAMPOLINE
|
||||
|
||||
#endif /* TM_MIPSLINUX_H */
|
||||
|
@ -27,6 +27,7 @@
|
||||
#include "mips-tdep.h"
|
||||
#include "gdb_string.h"
|
||||
#include "gdb_assert.h"
|
||||
#include "frame.h"
|
||||
|
||||
/* Copied from <asm/elf.h>. */
|
||||
#define ELF_NGREG 45
|
||||
@ -676,6 +677,125 @@ init_register_addr_data (struct gdbarch *gdbarch)
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Check the code at PC for a dynamic linker lazy resolution stub. Because
|
||||
they aren't in the .plt section, we pattern-match on the code generated
|
||||
by GNU ld. They look like this:
|
||||
|
||||
lw t9,0x8010(gp)
|
||||
addu t7,ra
|
||||
jalr t9,ra
|
||||
addiu t8,zero,INDEX
|
||||
|
||||
(with the appropriate doubleword instructions for N64). Also return the
|
||||
dynamic symbol index used in the last instruction. */
|
||||
|
||||
static int
|
||||
mips_linux_in_dynsym_stub (CORE_ADDR pc, char *name)
|
||||
{
|
||||
unsigned char buf[28], *p;
|
||||
ULONGEST insn, insn1;
|
||||
int n64 = (mips_abi (current_gdbarch) == MIPS_ABI_N64);
|
||||
|
||||
read_memory (pc - 12, buf, 28);
|
||||
|
||||
if (n64)
|
||||
{
|
||||
/* ld t9,0x8010(gp) */
|
||||
insn1 = 0xdf998010;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* lw t9,0x8010(gp) */
|
||||
insn1 = 0x8f998010;
|
||||
}
|
||||
|
||||
p = buf + 12;
|
||||
while (p >= buf)
|
||||
{
|
||||
insn = extract_unsigned_integer (p, 4);
|
||||
if (insn == insn1)
|
||||
break;
|
||||
p -= 4;
|
||||
}
|
||||
if (p < buf)
|
||||
return 0;
|
||||
|
||||
insn = extract_unsigned_integer (p + 4, 4);
|
||||
if (n64)
|
||||
{
|
||||
/* daddu t7,ra */
|
||||
if (insn != 0x03e0782d)
|
||||
return 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* addu t7,ra */
|
||||
if (insn != 0x03e07821)
|
||||
return 0;
|
||||
}
|
||||
|
||||
insn = extract_unsigned_integer (p + 8, 4);
|
||||
/* jalr t9,ra */
|
||||
if (insn != 0x0320f809)
|
||||
return 0;
|
||||
|
||||
insn = extract_unsigned_integer (p + 12, 4);
|
||||
if (n64)
|
||||
{
|
||||
/* daddiu t8,zero,0 */
|
||||
if ((insn & 0xffff0000) != 0x64180000)
|
||||
return 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* addiu t8,zero,0 */
|
||||
if ((insn & 0xffff0000) != 0x24180000)
|
||||
return 0;
|
||||
}
|
||||
|
||||
return (insn & 0xffff);
|
||||
}
|
||||
|
||||
/* Return non-zero iff PC belongs to the dynamic linker resolution code
|
||||
or to a stub. */
|
||||
|
||||
int
|
||||
mips_linux_in_dynsym_resolve_code (CORE_ADDR pc)
|
||||
{
|
||||
/* Check whether PC is in the dynamic linker. This also checks whether
|
||||
it is in the .plt section, which MIPS does not use. */
|
||||
if (in_solib_dynsym_resolve_code (pc))
|
||||
return 1;
|
||||
|
||||
/* Pattern match for the stub. It would be nice if there were a more
|
||||
efficient way to avoid this check. */
|
||||
if (mips_linux_in_dynsym_stub (pc, NULL))
|
||||
return 1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* See the comments for SKIP_SOLIB_RESOLVER at the top of infrun.c,
|
||||
and glibc_skip_solib_resolver in glibc-tdep.c. The normal glibc
|
||||
implementation of this triggers at "fixup" from the same objfile as
|
||||
"_dl_runtime_resolve"; MIPS/Linux can trigger at "__dl_runtime_resolve"
|
||||
directly. An unresolved PLT entry will point to _dl_runtime_resolve,
|
||||
which will first call __dl_runtime_resolve, and then pass control to
|
||||
the resolved function. */
|
||||
|
||||
static CORE_ADDR
|
||||
mips_linux_skip_resolver (struct gdbarch *gdbarch, CORE_ADDR pc)
|
||||
{
|
||||
struct minimal_symbol *resolver;
|
||||
|
||||
resolver = lookup_minimal_symbol ("__dl_runtime_resolve", NULL, NULL);
|
||||
|
||||
if (resolver && SYMBOL_VALUE_ADDRESS (resolver) == pc)
|
||||
return frame_pc_unwind (get_current_frame ());
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void
|
||||
mips_linux_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch)
|
||||
{
|
||||
@ -709,6 +829,12 @@ mips_linux_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch)
|
||||
internal_error (__FILE__, __LINE__, "can't handle ABI");
|
||||
break;
|
||||
}
|
||||
|
||||
set_gdbarch_skip_solib_resolver (gdbarch, mips_linux_skip_resolver);
|
||||
|
||||
/* This overrides the MIPS16 stub support from mips-tdep. But no one uses
|
||||
MIPS16 on Linux yet, so this isn't much of a loss. */
|
||||
set_gdbarch_in_solib_call_trampoline (gdbarch, mips_linux_in_dynsym_stub);
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -5815,13 +5815,22 @@ mips_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
|
||||
is sitting on? */
|
||||
set_gdbarch_have_nonsteppable_watchpoint (gdbarch, 1);
|
||||
|
||||
/* Hook in OS ABI-specific overrides, if they have been registered. */
|
||||
gdbarch_init_osabi (info, gdbarch);
|
||||
|
||||
set_gdbarch_skip_trampoline_code (gdbarch, mips_skip_stub);
|
||||
|
||||
set_gdbarch_in_solib_call_trampoline (gdbarch, mips_in_call_stub);
|
||||
set_gdbarch_in_solib_return_trampoline (gdbarch, mips_in_return_stub);
|
||||
/* NOTE drow/2004-02-11: We overload the core solib trampoline code
|
||||
to support MIPS16. This is a bad thing. Make sure not to do it
|
||||
if we have an OS ABI that actually supports shared libraries, since
|
||||
shared library support is more important. If we have an OS someday
|
||||
that supports both shared libraries and MIPS16, we'll have to find
|
||||
a better place for these. */
|
||||
if (info.osabi == GDB_OSABI_UNKNOWN)
|
||||
{
|
||||
set_gdbarch_in_solib_call_trampoline (gdbarch, mips_in_call_stub);
|
||||
set_gdbarch_in_solib_return_trampoline (gdbarch, mips_in_return_stub);
|
||||
}
|
||||
|
||||
/* Hook in OS ABI-specific overrides, if they have been registered. */
|
||||
gdbarch_init_osabi (info, gdbarch);
|
||||
|
||||
return gdbarch;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user