diff options
Diffstat (limited to 'gdb/mips-linux-tdep.c')
-rw-r--r-- | gdb/mips-linux-tdep.c | 29 |
1 files changed, 20 insertions, 9 deletions
diff --git a/gdb/mips-linux-tdep.c b/gdb/mips-linux-tdep.c index 1628645..484b39f 100644 --- a/gdb/mips-linux-tdep.c +++ b/gdb/mips-linux-tdep.c @@ -30,6 +30,7 @@ #include "trad-frame.h" #include "tramp-frame.h" #include "gdbtypes.h" +#include "objfiles.h" #include "solib.h" #include "solib-svr4.h" #include "solist.h" @@ -666,25 +667,34 @@ mips_linux_core_read_description (struct gdbarch *gdbarch, /* 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: + GNU ld for MIPS has put lazy resolution stubs into a ".MIPS.stubs" + section uniformly since version 2.15. If the pc is in that section, + then we are in such a stub. Before that ".stub" was used in 32-bit + ELF binaries, however we do not bother checking for that since we + have never had and that case should be extremely rare these days. + Instead 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. */ + (with the appropriate doubleword instructions for N64). As any lazy + resolution stubs in microMIPS binaries will always be in a + ".MIPS.stubs" section we only ever verify standard MIPS patterns. */ static int -mips_linux_in_dynsym_stub (CORE_ADDR pc, char *name) +mips_linux_in_dynsym_stub (CORE_ADDR pc) { gdb_byte buf[28], *p; ULONGEST insn, insn1; int n64 = (mips_abi (target_gdbarch ()) == MIPS_ABI_N64); enum bfd_endian byte_order = gdbarch_byte_order (target_gdbarch ()); + if (in_mips_stubs_section (pc)) + return 1; + read_memory (pc - 12, buf, 28); if (n64) @@ -742,7 +752,7 @@ mips_linux_in_dynsym_stub (CORE_ADDR pc, char *name) return 0; } - return (insn & 0xffff); + return 1; } /* Return non-zero iff PC belongs to the dynamic linker resolution @@ -756,9 +766,10 @@ mips_linux_in_dynsym_resolve_code (CORE_ADDR pc) if (svr4_in_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)) + /* Likewise for the stubs. They live in the .MIPS.stubs section these + days, so we check if the PC is within, than fall back to a pattern + match. */ + if (mips_linux_in_dynsym_stub (pc)) return 1; return 0; |