* 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:
Daniel Jacobowitz 2004-02-11 18:47:27 +00:00
parent 87b3ede8af
commit 6de918a6f5
5 changed files with 167 additions and 8 deletions

View File

@ -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

View File

@ -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)

View File

@ -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 */

View File

@ -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

View File

@ -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;
}