Skip-trampoline for PowerPC reverse-stepping.
This commit is contained in:
parent
b4cdae6fe5
commit
cf90fd9a07
3 changed files with 105 additions and 47 deletions
|
@ -1,3 +1,9 @@
|
||||||
|
2015-01-17 Wei-cheng Wang <cole945@gmail.com>
|
||||||
|
|
||||||
|
* ppc-linux-tdep.c (ppc_skip_trampoline_code):
|
||||||
|
Scan PLT stub backward for reverse debugging.
|
||||||
|
* ppc64-tdep.c (ppc64_skip_trampoline_code): Likewise.
|
||||||
|
|
||||||
2015-01-17 Wei-cheng Wang <cole945@gmail.com>
|
2015-01-17 Wei-cheng Wang <cole945@gmail.com>
|
||||||
Ulrich Weigand <uweigand@de.ibm.com>
|
Ulrich Weigand <uweigand@de.ibm.com>
|
||||||
|
|
||||||
|
|
|
@ -51,6 +51,7 @@
|
||||||
#include "linux-tdep.h"
|
#include "linux-tdep.h"
|
||||||
#include "linux-record.h"
|
#include "linux-record.h"
|
||||||
#include "record-full.h"
|
#include "record-full.h"
|
||||||
|
#include "infrun.h"
|
||||||
|
|
||||||
#include "stap-probe.h"
|
#include "stap-probe.h"
|
||||||
#include "ax.h"
|
#include "ax.h"
|
||||||
|
@ -314,7 +315,16 @@ ppc_skip_trampoline_code (struct frame_info *frame, CORE_ADDR pc)
|
||||||
struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
|
struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
|
||||||
enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
|
enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
|
||||||
CORE_ADDR target = 0;
|
CORE_ADDR target = 0;
|
||||||
|
int scan_limit, i;
|
||||||
|
|
||||||
|
scan_limit = 1;
|
||||||
|
/* When reverse-debugging, scan backward to check whether we are
|
||||||
|
in the middle of trampoline code. */
|
||||||
|
if (execution_direction == EXEC_REVERSE)
|
||||||
|
scan_limit = 4; /* At more 4 instructions. */
|
||||||
|
|
||||||
|
for (i = 0; i < scan_limit; i++)
|
||||||
|
{
|
||||||
if (ppc_insns_match_pattern (frame, pc, powerpc32_plt_stub, insnbuf))
|
if (ppc_insns_match_pattern (frame, pc, powerpc32_plt_stub, insnbuf))
|
||||||
{
|
{
|
||||||
/* Insn pattern is
|
/* Insn pattern is
|
||||||
|
@ -326,21 +336,31 @@ ppc_skip_trampoline_code (struct frame_info *frame, CORE_ADDR pc)
|
||||||
| ppc_insn_d_field (insnbuf[1]);
|
| ppc_insn_d_field (insnbuf[1]);
|
||||||
target = read_memory_unsigned_integer (target, 4, byte_order);
|
target = read_memory_unsigned_integer (target, 4, byte_order);
|
||||||
}
|
}
|
||||||
|
else if (ppc_insns_match_pattern (frame, pc, powerpc32_plt_stub_so,
|
||||||
if (ppc_insns_match_pattern (frame, pc, powerpc32_plt_stub_so, insnbuf))
|
insnbuf))
|
||||||
{
|
{
|
||||||
/* Insn pattern is
|
/* Insn pattern is
|
||||||
lwz r11, xxxx(r30)
|
lwz r11, xxxx(r30)
|
||||||
Branch target is in r11. */
|
Branch target is in r11. */
|
||||||
|
|
||||||
target = get_frame_register_unsigned (frame, tdep->ppc_gp0_regnum + 30)
|
target = get_frame_register_unsigned (frame,
|
||||||
|
tdep->ppc_gp0_regnum + 30)
|
||||||
+ ppc_insn_d_field (insnbuf[0]);
|
+ ppc_insn_d_field (insnbuf[0]);
|
||||||
target = read_memory_unsigned_integer (target, 4, byte_order);
|
target = read_memory_unsigned_integer (target, 4, byte_order);
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* Scan backward one more instructions if doesn't match. */
|
||||||
|
pc -= 4;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
return target;
|
return target;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
/* Wrappers to handle Linux-only registers. */
|
/* Wrappers to handle Linux-only registers. */
|
||||||
|
|
||||||
static void
|
static void
|
||||||
|
|
|
@ -20,6 +20,7 @@
|
||||||
#include "defs.h"
|
#include "defs.h"
|
||||||
#include "frame.h"
|
#include "frame.h"
|
||||||
#include "gdbcore.h"
|
#include "gdbcore.h"
|
||||||
|
#include "infrun.h"
|
||||||
#include "ppc-tdep.h"
|
#include "ppc-tdep.h"
|
||||||
#include "ppc64-tdep.h"
|
#include "ppc64-tdep.h"
|
||||||
#include "elf-bfd.h"
|
#include "elf-bfd.h"
|
||||||
|
@ -464,29 +465,57 @@ ppc64_skip_trampoline_code (struct frame_info *frame, CORE_ADDR pc)
|
||||||
ARRAY_SIZE (ppc64_standard_linkage8))))
|
ARRAY_SIZE (ppc64_standard_linkage8))))
|
||||||
- 1];
|
- 1];
|
||||||
CORE_ADDR target;
|
CORE_ADDR target;
|
||||||
|
int scan_limit, i;
|
||||||
|
|
||||||
if (ppc_insns_match_pattern (frame, pc, ppc64_standard_linkage8, insns))
|
scan_limit = 1;
|
||||||
|
/* When reverse-debugging, scan backward to check whether we are
|
||||||
|
in the middle of trampoline code. */
|
||||||
|
if (execution_direction == EXEC_REVERSE)
|
||||||
|
scan_limit = ARRAY_SIZE (insns) - 1;
|
||||||
|
|
||||||
|
for (i = 0; i < scan_limit; i++)
|
||||||
|
{
|
||||||
|
if (i < ARRAY_SIZE (ppc64_standard_linkage8) - 1
|
||||||
|
&& ppc_insns_match_pattern (frame, pc, ppc64_standard_linkage8, insns))
|
||||||
pc = ppc64_standard_linkage4_target (frame, pc, insns);
|
pc = ppc64_standard_linkage4_target (frame, pc, insns);
|
||||||
else if (ppc_insns_match_pattern (frame, pc, ppc64_standard_linkage7, insns))
|
else if (i < ARRAY_SIZE (ppc64_standard_linkage7) - 1
|
||||||
|
&& ppc_insns_match_pattern (frame, pc, ppc64_standard_linkage7,
|
||||||
|
insns))
|
||||||
pc = ppc64_standard_linkage3_target (frame, pc, insns);
|
pc = ppc64_standard_linkage3_target (frame, pc, insns);
|
||||||
else if (ppc_insns_match_pattern (frame, pc, ppc64_standard_linkage6, insns))
|
else if (i < ARRAY_SIZE (ppc64_standard_linkage6) - 1
|
||||||
|
&& ppc_insns_match_pattern (frame, pc, ppc64_standard_linkage6,
|
||||||
|
insns))
|
||||||
pc = ppc64_standard_linkage4_target (frame, pc, insns);
|
pc = ppc64_standard_linkage4_target (frame, pc, insns);
|
||||||
else if (ppc_insns_match_pattern (frame, pc, ppc64_standard_linkage5, insns)
|
else if (i < ARRAY_SIZE (ppc64_standard_linkage5) - 1
|
||||||
|
&& ppc_insns_match_pattern (frame, pc, ppc64_standard_linkage5,
|
||||||
|
insns)
|
||||||
&& (insns[8] != 0 || insns[9] != 0))
|
&& (insns[8] != 0 || insns[9] != 0))
|
||||||
pc = ppc64_standard_linkage3_target (frame, pc, insns);
|
pc = ppc64_standard_linkage3_target (frame, pc, insns);
|
||||||
else if (ppc_insns_match_pattern (frame, pc, ppc64_standard_linkage4, insns)
|
else if (i < ARRAY_SIZE (ppc64_standard_linkage4) - 1
|
||||||
|
&& ppc_insns_match_pattern (frame, pc, ppc64_standard_linkage4,
|
||||||
|
insns)
|
||||||
&& (insns[9] != 0 || insns[10] != 0))
|
&& (insns[9] != 0 || insns[10] != 0))
|
||||||
pc = ppc64_standard_linkage4_target (frame, pc, insns);
|
pc = ppc64_standard_linkage4_target (frame, pc, insns);
|
||||||
else if (ppc_insns_match_pattern (frame, pc, ppc64_standard_linkage3, insns)
|
else if (i < ARRAY_SIZE (ppc64_standard_linkage3) - 1
|
||||||
|
&& ppc_insns_match_pattern (frame, pc, ppc64_standard_linkage3,
|
||||||
|
insns)
|
||||||
&& (insns[8] != 0 || insns[9] != 0))
|
&& (insns[8] != 0 || insns[9] != 0))
|
||||||
pc = ppc64_standard_linkage3_target (frame, pc, insns);
|
pc = ppc64_standard_linkage3_target (frame, pc, insns);
|
||||||
else if (ppc_insns_match_pattern (frame, pc, ppc64_standard_linkage2, insns)
|
else if (i < ARRAY_SIZE (ppc64_standard_linkage2) - 1
|
||||||
|
&& ppc_insns_match_pattern (frame, pc, ppc64_standard_linkage2,
|
||||||
|
insns)
|
||||||
&& (insns[10] != 0 || insns[11] != 0))
|
&& (insns[10] != 0 || insns[11] != 0))
|
||||||
pc = ppc64_standard_linkage2_target (frame, pc, insns);
|
pc = ppc64_standard_linkage2_target (frame, pc, insns);
|
||||||
else if (ppc_insns_match_pattern (frame, pc, ppc64_standard_linkage1, insns))
|
else if (i < ARRAY_SIZE (ppc64_standard_linkage1) - 1
|
||||||
|
&& ppc_insns_match_pattern (frame, pc, ppc64_standard_linkage1,
|
||||||
|
insns))
|
||||||
pc = ppc64_standard_linkage1_target (frame, pc, insns);
|
pc = ppc64_standard_linkage1_target (frame, pc, insns);
|
||||||
else
|
else
|
||||||
return 0;
|
{
|
||||||
|
/* Scan backward one more instructions if doesn't match. */
|
||||||
|
pc -= 4;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
/* The PLT descriptor will either point to the already resolved target
|
/* The PLT descriptor will either point to the already resolved target
|
||||||
address, or else to a glink stub. As the latter carry synthetic @plt
|
address, or else to a glink stub. As the latter carry synthetic @plt
|
||||||
|
@ -495,6 +524,9 @@ ppc64_skip_trampoline_code (struct frame_info *frame, CORE_ADDR pc)
|
||||||
return target ? target : pc;
|
return target ? target : pc;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
/* Support for convert_from_func_ptr_addr (ARCH, ADDR, TARG) on PPC64
|
/* Support for convert_from_func_ptr_addr (ARCH, ADDR, TARG) on PPC64
|
||||||
GNU/Linux.
|
GNU/Linux.
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue