|
|
2c2fa1 |
Message-ID: <5491BE7E.2060708@gmail.com>
|
|
|
2c2fa1 |
Date: Thu, 18 Dec 2014 01:33:50 +0800
|
|
|
2c2fa1 |
From: Wei-cheng Wang <cole945 at gmail dot com>
|
|
|
2c2fa1 |
To: Ulrich Weigand <uweigand at de dot ibm dot com>
|
|
|
2c2fa1 |
CC: gdb-patches at sourceware dot org
|
|
|
2c2fa1 |
Subject: Re: [PATCH 3/3 v2] Process record support for PowerPC
|
|
|
2c2fa1 |
|
|
|
2c2fa1 |
On 2014/12/9 上午 03:13, Ulrich Weigand wrote:
|
|
|
2c2fa1 |
> Wei-cheng Wang wrote:
|
|
|
2c2fa1 |
>> * ppc-linux-tdep.c (powerpc_linux_in_dynsym_resolve_code):
|
|
|
2c2fa1 |
>> Scan PLT stub backward for reverse debugging.
|
|
|
2c2fa1 |
>> (ppc_linux_init_abi): set powerpc_linux_in_dynsym_resolve_code
|
|
|
2c2fa1 |
>> for both 32-bit and 64-bit.
|
|
|
2c2fa1 |
>
|
|
|
2c2fa1 |
> As I said in the reply to the 0/3 mail, I really think it would be
|
|
|
2c2fa1 |
> better to handle this within the PPC skip_trampoline_code implementation,
|
|
|
2c2fa1 |
> instead of having in_dynsym_resolve_code suddenly also cover the
|
|
|
2c2fa1 |
> trampolines ...
|
|
|
2c2fa1 |
|
|
|
2c2fa1 |
Hi,
|
|
|
2c2fa1 |
|
|
|
2c2fa1 |
See the new patch, I moved the for-loop into skip_trampoline_code,
|
|
|
2c2fa1 |
and removed in_dynsym_resolve_code.
|
|
|
2c2fa1 |
|
|
|
2c2fa1 |
> It seems odd to have in_dynsym_resolve_code call into
|
|
|
2c2fa1 |
> skip_trampoline_code. Is there a reason why the skip_trampoline_code
|
|
|
2c2fa1 |
> implementation cannot accept a PC in the middle of the sequence?
|
|
|
2c2fa1 |
|
|
|
2c2fa1 |
I thought skip-trampoline is used to find the target address for
|
|
|
2c2fa1 |
inserting step-resume breakpoint, so it doesn't make sense for
|
|
|
2c2fa1 |
reverse-stepping, because we are just stepping from the target address.
|
|
|
2c2fa1 |
And for forward-stepping, when we reach the very first instruction of
|
|
|
2c2fa1 |
trampoline code, we can just skip the resolving code by inserting
|
|
|
2c2fa1 |
a step-resume breakpoint, so we don't have to step through the resolving
|
|
|
2c2fa1 |
code and check whether we are in the middle of trampoline code.
|
|
|
2c2fa1 |
|
|
|
2c2fa1 |
in_dynsym_resolve_code is used to check whether we are in (the middle of)
|
|
|
2c2fa1 |
the resolving code, so we can keep going to step though the resolving code.
|
|
|
2c2fa1 |
Therefor I thought in_dynsym_resolve_code is the proper place to implement.
|
|
|
2c2fa1 |
|
|
|
2c2fa1 |
Since skip-trampoline-code had implemented the plt-stub pattern-match code
|
|
|
2c2fa1 |
we need, by calling it in in-dynsym-resolve-code, we don't need to have
|
|
|
2c2fa1 |
duplicate pattern-match code in both functions.
|
|
|
2c2fa1 |
|
|
|
2c2fa1 |
Wei-cheng,
|
|
|
2c2fa1 |
Thanks
|
|
|
2c2fa1 |
|
|
|
2c2fa1 |
--
|
|
|
2c2fa1 |
|
|
|
2c2fa1 |
2014-12-06 Wei-cheng Wang <cole945@gmail.com>
|
|
|
2c2fa1 |
|
|
|
2c2fa1 |
* ppc-linux-tdep.c (ppc_skip_trampoline_code):
|
|
|
2c2fa1 |
Scan PLT stub backward for reverse debugging.
|
|
|
2c2fa1 |
* ppc64-tdep.c (ppc64_skip_trampoline_code): Likewise.
|
|
|
2c2fa1 |
|
|
|
2c2fa1 |
|
|
|
2c2fa1 |
commit cf90fd9a07e8998540bf74f293d348a6653ac120
|
|
|
2c2fa1 |
Author: Wei-cheng Wang <cole945@gmail.com>
|
|
|
2c2fa1 |
Date: Sat Jan 17 14:30:59 2015 +0800
|
|
|
2c2fa1 |
|
|
|
2c2fa1 |
Skip-trampoline for PowerPC reverse-stepping.
|
|
|
2c2fa1 |
|
|
|
2c2fa1 |
Index: gdb-7.6.1/gdb/ppc64-tdep.c
|
|
|
2c2fa1 |
===================================================================
|
|
|
2c2fa1 |
--- gdb-7.6.1.orig/gdb/ppc64-tdep.c
|
|
|
2c2fa1 |
+++ gdb-7.6.1/gdb/ppc64-tdep.c
|
|
|
2c2fa1 |
@@ -20,6 +20,7 @@
|
|
|
2c2fa1 |
#include "defs.h"
|
|
|
2c2fa1 |
#include "frame.h"
|
|
|
2c2fa1 |
#include "gdbcore.h"
|
|
|
2c2fa1 |
+#include "inferior.h"
|
|
|
2c2fa1 |
#include "ppc-tdep.h"
|
|
|
2c2fa1 |
#include "ppc64-tdep.h"
|
|
|
2c2fa1 |
#include "elf-bfd.h"
|
|
|
2c2fa1 |
@@ -464,35 +465,66 @@ ppc64_skip_trampoline_code (struct frame
|
|
|
2c2fa1 |
ARRAY_SIZE (ppc64_standard_linkage8))))
|
|
|
2c2fa1 |
- 1];
|
|
|
2c2fa1 |
CORE_ADDR target;
|
|
|
2c2fa1 |
+ int scan_limit, i;
|
|
|
2c2fa1 |
|
|
|
2c2fa1 |
- if (ppc_insns_match_pattern (frame, pc, ppc64_standard_linkage8, insns))
|
|
|
2c2fa1 |
- pc = ppc64_standard_linkage4_target (frame, pc, insns);
|
|
|
2c2fa1 |
- else if (ppc_insns_match_pattern (frame, pc, ppc64_standard_linkage7, insns))
|
|
|
2c2fa1 |
- pc = ppc64_standard_linkage3_target (frame, pc, insns);
|
|
|
2c2fa1 |
- else if (ppc_insns_match_pattern (frame, pc, ppc64_standard_linkage6, insns))
|
|
|
2c2fa1 |
- pc = ppc64_standard_linkage4_target (frame, pc, insns);
|
|
|
2c2fa1 |
- else if (ppc_insns_match_pattern (frame, pc, ppc64_standard_linkage5, insns)
|
|
|
2c2fa1 |
- && (insns[8] != 0 || insns[9] != 0))
|
|
|
2c2fa1 |
- pc = ppc64_standard_linkage3_target (frame, pc, insns);
|
|
|
2c2fa1 |
- else if (ppc_insns_match_pattern (frame, pc, ppc64_standard_linkage4, insns)
|
|
|
2c2fa1 |
- && (insns[9] != 0 || insns[10] != 0))
|
|
|
2c2fa1 |
- pc = ppc64_standard_linkage4_target (frame, pc, insns);
|
|
|
2c2fa1 |
- else if (ppc_insns_match_pattern (frame, pc, ppc64_standard_linkage3, insns)
|
|
|
2c2fa1 |
- && (insns[8] != 0 || insns[9] != 0))
|
|
|
2c2fa1 |
- pc = ppc64_standard_linkage3_target (frame, pc, insns);
|
|
|
2c2fa1 |
- else if (ppc_insns_match_pattern (frame, pc, ppc64_standard_linkage2, insns)
|
|
|
2c2fa1 |
- && (insns[10] != 0 || insns[11] != 0))
|
|
|
2c2fa1 |
- pc = ppc64_standard_linkage2_target (frame, pc, insns);
|
|
|
2c2fa1 |
- else if (ppc_insns_match_pattern (frame, pc, ppc64_standard_linkage1, insns))
|
|
|
2c2fa1 |
- pc = ppc64_standard_linkage1_target (frame, pc, insns);
|
|
|
2c2fa1 |
- else
|
|
|
2c2fa1 |
- return 0;
|
|
|
2c2fa1 |
-
|
|
|
2c2fa1 |
- /* The PLT descriptor will either point to the already resolved target
|
|
|
2c2fa1 |
- address, or else to a glink stub. As the latter carry synthetic @plt
|
|
|
2c2fa1 |
- symbols, find_solib_trampoline_target should be able to resolve them. */
|
|
|
2c2fa1 |
- target = find_solib_trampoline_target (frame, pc);
|
|
|
2c2fa1 |
- return target ? target : pc;
|
|
|
2c2fa1 |
+ scan_limit = 1;
|
|
|
2c2fa1 |
+ /* When reverse-debugging, scan backward to check whether we are
|
|
|
2c2fa1 |
+ in the middle of trampoline code. */
|
|
|
2c2fa1 |
+ if (execution_direction == EXEC_REVERSE)
|
|
|
2c2fa1 |
+ scan_limit = ARRAY_SIZE (insns) - 1;
|
|
|
2c2fa1 |
+
|
|
|
2c2fa1 |
+ for (i = 0; i < scan_limit; i++)
|
|
|
2c2fa1 |
+ {
|
|
|
2c2fa1 |
+ if (i < ARRAY_SIZE (ppc64_standard_linkage8) - 1
|
|
|
2c2fa1 |
+ && ppc_insns_match_pattern (frame, pc, ppc64_standard_linkage8, insns))
|
|
|
2c2fa1 |
+ pc = ppc64_standard_linkage4_target (frame, pc, insns);
|
|
|
2c2fa1 |
+ else if (i < ARRAY_SIZE (ppc64_standard_linkage7) - 1
|
|
|
2c2fa1 |
+ && ppc_insns_match_pattern (frame, pc, ppc64_standard_linkage7,
|
|
|
2c2fa1 |
+ insns))
|
|
|
2c2fa1 |
+ pc = ppc64_standard_linkage3_target (frame, pc, insns);
|
|
|
2c2fa1 |
+ else if (i < ARRAY_SIZE (ppc64_standard_linkage6) - 1
|
|
|
2c2fa1 |
+ && ppc_insns_match_pattern (frame, pc, ppc64_standard_linkage6,
|
|
|
2c2fa1 |
+ insns))
|
|
|
2c2fa1 |
+ pc = ppc64_standard_linkage4_target (frame, pc, insns);
|
|
|
2c2fa1 |
+ else if (i < ARRAY_SIZE (ppc64_standard_linkage5) - 1
|
|
|
2c2fa1 |
+ && ppc_insns_match_pattern (frame, pc, ppc64_standard_linkage5,
|
|
|
2c2fa1 |
+ insns)
|
|
|
2c2fa1 |
+ && (insns[8] != 0 || insns[9] != 0))
|
|
|
2c2fa1 |
+ pc = ppc64_standard_linkage3_target (frame, pc, insns);
|
|
|
2c2fa1 |
+ else if (i < ARRAY_SIZE (ppc64_standard_linkage4) - 1
|
|
|
2c2fa1 |
+ && ppc_insns_match_pattern (frame, pc, ppc64_standard_linkage4,
|
|
|
2c2fa1 |
+ insns)
|
|
|
2c2fa1 |
+ && (insns[9] != 0 || insns[10] != 0))
|
|
|
2c2fa1 |
+ pc = ppc64_standard_linkage4_target (frame, pc, insns);
|
|
|
2c2fa1 |
+ else if (i < ARRAY_SIZE (ppc64_standard_linkage3) - 1
|
|
|
2c2fa1 |
+ && ppc_insns_match_pattern (frame, pc, ppc64_standard_linkage3,
|
|
|
2c2fa1 |
+ insns)
|
|
|
2c2fa1 |
+ && (insns[8] != 0 || insns[9] != 0))
|
|
|
2c2fa1 |
+ pc = ppc64_standard_linkage3_target (frame, pc, insns);
|
|
|
2c2fa1 |
+ else if (i < ARRAY_SIZE (ppc64_standard_linkage2) - 1
|
|
|
2c2fa1 |
+ && ppc_insns_match_pattern (frame, pc, ppc64_standard_linkage2,
|
|
|
2c2fa1 |
+ insns)
|
|
|
2c2fa1 |
+ && (insns[10] != 0 || insns[11] != 0))
|
|
|
2c2fa1 |
+ pc = ppc64_standard_linkage2_target (frame, pc, insns);
|
|
|
2c2fa1 |
+ else if (i < ARRAY_SIZE (ppc64_standard_linkage1) - 1
|
|
|
2c2fa1 |
+ && ppc_insns_match_pattern (frame, pc, ppc64_standard_linkage1,
|
|
|
2c2fa1 |
+ insns))
|
|
|
2c2fa1 |
+ pc = ppc64_standard_linkage1_target (frame, pc, insns);
|
|
|
2c2fa1 |
+ else
|
|
|
2c2fa1 |
+ {
|
|
|
2c2fa1 |
+ /* Scan backward one more instructions if doesn't match. */
|
|
|
2c2fa1 |
+ pc -= 4;
|
|
|
2c2fa1 |
+ continue;
|
|
|
2c2fa1 |
+ }
|
|
|
2c2fa1 |
+
|
|
|
2c2fa1 |
+ /* The PLT descriptor will either point to the already resolved target
|
|
|
2c2fa1 |
+ address, or else to a glink stub. As the latter carry synthetic @plt
|
|
|
2c2fa1 |
+ symbols, find_solib_trampoline_target should be able to resolve them. */
|
|
|
2c2fa1 |
+ target = find_solib_trampoline_target (frame, pc);
|
|
|
2c2fa1 |
+ return target ? target : pc;
|
|
|
2c2fa1 |
+ }
|
|
|
2c2fa1 |
+
|
|
|
2c2fa1 |
+ return 0;
|
|
|
2c2fa1 |
}
|
|
|
2c2fa1 |
|
|
|
2c2fa1 |
/* Support for convert_from_func_ptr_addr (ARCH, ADDR, TARG) on PPC64
|
|
|
2c2fa1 |
Index: gdb-7.6.1/gdb/ppc-linux-tdep.c
|
|
|
2c2fa1 |
===================================================================
|
|
|
2c2fa1 |
--- gdb-7.6.1.orig/gdb/ppc-linux-tdep.c
|
|
|
2c2fa1 |
+++ gdb-7.6.1/gdb/ppc-linux-tdep.c
|
|
|
2c2fa1 |
@@ -52,6 +52,7 @@
|
|
|
2c2fa1 |
#include "linux-tdep.h"
|
|
|
2c2fa1 |
#include "linux-record.h"
|
|
|
2c2fa1 |
#include "record-full.h"
|
|
|
2c2fa1 |
+#include "inferior.h"
|
|
|
2c2fa1 |
|
|
|
2c2fa1 |
#include "stap-probe.h"
|
|
|
2c2fa1 |
#include "ax.h"
|
|
|
2c2fa1 |
@@ -362,31 +363,50 @@ ppc_skip_trampoline_code (struct frame_i
|
|
|
2c2fa1 |
struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
|
|
|
2c2fa1 |
enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
|
|
|
2c2fa1 |
CORE_ADDR target = 0;
|
|
|
2c2fa1 |
+ int scan_limit, i;
|
|
|
2c2fa1 |
|
|
|
2c2fa1 |
- if (ppc_insns_match_pattern (frame, pc, powerpc32_plt_stub, insnbuf))
|
|
|
2c2fa1 |
- {
|
|
|
2c2fa1 |
- /* Insn pattern is
|
|
|
2c2fa1 |
- lis r11, xxxx
|
|
|
2c2fa1 |
- lwz r11, xxxx(r11)
|
|
|
2c2fa1 |
- Branch target is in r11. */
|
|
|
2c2fa1 |
-
|
|
|
2c2fa1 |
- target = (ppc_insn_d_field (insnbuf[0]) << 16)
|
|
|
2c2fa1 |
- | ppc_insn_d_field (insnbuf[1]);
|
|
|
2c2fa1 |
- target = read_memory_unsigned_integer (target, 4, byte_order);
|
|
|
2c2fa1 |
- }
|
|
|
2c2fa1 |
+ scan_limit = 1;
|
|
|
2c2fa1 |
+ /* When reverse-debugging, scan backward to check whether we are
|
|
|
2c2fa1 |
+ in the middle of trampoline code. */
|
|
|
2c2fa1 |
+ if (execution_direction == EXEC_REVERSE)
|
|
|
2c2fa1 |
+ scan_limit = 4; /* At more 4 instructions. */
|
|
|
2c2fa1 |
|
|
|
2c2fa1 |
- if (ppc_insns_match_pattern (frame, pc, powerpc32_plt_stub_so, insnbuf))
|
|
|
2c2fa1 |
+ for (i = 0; i < scan_limit; i++)
|
|
|
2c2fa1 |
{
|
|
|
2c2fa1 |
- /* Insn pattern is
|
|
|
2c2fa1 |
- lwz r11, xxxx(r30)
|
|
|
2c2fa1 |
- Branch target is in r11. */
|
|
|
2c2fa1 |
-
|
|
|
2c2fa1 |
- target = get_frame_register_unsigned (frame, tdep->ppc_gp0_regnum + 30)
|
|
|
2c2fa1 |
- + ppc_insn_d_field (insnbuf[0]);
|
|
|
2c2fa1 |
- target = read_memory_unsigned_integer (target, 4, byte_order);
|
|
|
2c2fa1 |
+ if (ppc_insns_match_pattern (frame, pc, powerpc32_plt_stub, insnbuf))
|
|
|
2c2fa1 |
+ {
|
|
|
2c2fa1 |
+ /* Insn pattern is
|
|
|
2c2fa1 |
+ lis r11, xxxx
|
|
|
2c2fa1 |
+ lwz r11, xxxx(r11)
|
|
|
2c2fa1 |
+ Branch target is in r11. */
|
|
|
2c2fa1 |
+
|
|
|
2c2fa1 |
+ target = (ppc_insn_d_field (insnbuf[0]) << 16)
|
|
|
2c2fa1 |
+ | ppc_insn_d_field (insnbuf[1]);
|
|
|
2c2fa1 |
+ target = read_memory_unsigned_integer (target, 4, byte_order);
|
|
|
2c2fa1 |
+ }
|
|
|
2c2fa1 |
+ else if (ppc_insns_match_pattern (frame, pc, powerpc32_plt_stub_so,
|
|
|
2c2fa1 |
+ insnbuf))
|
|
|
2c2fa1 |
+ {
|
|
|
2c2fa1 |
+ /* Insn pattern is
|
|
|
2c2fa1 |
+ lwz r11, xxxx(r30)
|
|
|
2c2fa1 |
+ Branch target is in r11. */
|
|
|
2c2fa1 |
+
|
|
|
2c2fa1 |
+ target = get_frame_register_unsigned (frame,
|
|
|
2c2fa1 |
+ tdep->ppc_gp0_regnum + 30)
|
|
|
2c2fa1 |
+ + ppc_insn_d_field (insnbuf[0]);
|
|
|
2c2fa1 |
+ target = read_memory_unsigned_integer (target, 4, byte_order);
|
|
|
2c2fa1 |
+ }
|
|
|
2c2fa1 |
+ else
|
|
|
2c2fa1 |
+ {
|
|
|
2c2fa1 |
+ /* Scan backward one more instructions if doesn't match. */
|
|
|
2c2fa1 |
+ pc -= 4;
|
|
|
2c2fa1 |
+ continue;
|
|
|
2c2fa1 |
+ }
|
|
|
2c2fa1 |
+
|
|
|
2c2fa1 |
+ return target;
|
|
|
2c2fa1 |
}
|
|
|
2c2fa1 |
|
|
|
2c2fa1 |
- return target;
|
|
|
2c2fa1 |
+ return 0;
|
|
|
2c2fa1 |
}
|
|
|
2c2fa1 |
|
|
|
2c2fa1 |
/* Wrappers to handle Linux-only registers. */
|