From: "Ulrich Weigand" <uweigand@de.ibm.com>
To: cole945@gmail.com (Wei-cheng Wang)
Cc: gdb-patches@sourceware.org
Subject: Re: [PATCH 2/7 v3] Tracepoint for ppc64.
Date: Wed, 08 Apr 2015 16:57:00 -0000 [thread overview]
Message-ID: <20150408165700.E9630CF20@oc7340732750.ibm.com> (raw)
In-Reply-To: <1427733032-64989-2-git-send-email-cole945@gmail.com> from "Wei-cheng Wang" at Mar 31, 2015 12:30:27 AM
Wei-cheng Wang wrote:
> The fail cases in gdb-unavailable are caused by inaccessible vtable for object
> For x86, such structures (_ZVTxxx) are put in .rodata section, so gdb can read
> them in local file if not collected by tracepoint action, but for PowerpPC,
> they are put in .rel.ro sections. Technically they not read-only, so gdb won't
> read them in file if not collected.
Is this really a difference between Intel and PowerPC, or this is rather
a difference between different binutils levels? I don't see off-hand
why this should be Power-specific ... Do you have example assembler
code that shows the difference?
> +/* Generate a sequence of instructions to load IMM in the register REG.
> + Write the instructions in BUF and return the number of bytes written. */
> +
> +static int
> +gen_limm (uint32_t *buf, int reg, uint64_t imm)
> +{
> + uint32_t *p = buf;
> +
> + if ((imm + 32768) < 65536)
> + {
> + /* li reg, imm[7:0] */
> + p += GEN_LI (p, reg, imm);
> + }
> + else if ((imm >> 16) == 0)
> + {
> + /* li reg, 0
> + ori reg, reg, imm[15:0] */
> + p += GEN_LI (p, reg, 0);
> + p += GEN_ORI (p, reg, reg, imm);
> + }
> + else if ((imm >> 32) == 0)
> + {
> + /* lis reg, imm[31:16]
> + ori reg, reg, imm[15:0]
> + rldicl reg, reg, 0, 32 */
> + p += GEN_LIS (p, reg, (imm >> 16) & 0xffff);
> + p += GEN_ORI (p, reg, reg, imm & 0xffff);
Ah, you just took that RLDICL out completely, that's also not correct.
You don't need the RLDICL if and only if the high bit of imm is zero.
The problem is that LIS will fill all the upper 32 bits of the target
register with copies of the high bit of the lower 32 bits.
(You could in theory also use the LIS/ORI pair to load up negative
values where all the high bits are *supposed* to be set, just like
you did for the LI case.)
> +/* Implement install_fast_tracepoint_jump_pad of target_ops.
> + See target.h for details. */
> +
> +static int
> +ppc_install_fast_tracepoint_jump_pad (CORE_ADDR tpoint, CORE_ADDR tpaddr,
> + CORE_ADDR collector,
> + CORE_ADDR lockaddr,
> + ULONGEST orig_size,
> + CORE_ADDR *jump_entry,
> + CORE_ADDR *trampoline,
> + ULONGEST *trampoline_size,
> + unsigned char *jjump_pad_insn,
> + ULONGEST *jjump_pad_insn_size,
> + CORE_ADDR *adjusted_insn_addr,
> + CORE_ADDR *adjusted_insn_addr_end,
> + char *err)
> +{
> + uint32_t buf[256];
> + uint32_t *p = buf;
> + int j, offset;
> + CORE_ADDR buildaddr = *jump_entry;
> + const CORE_ADDR entryaddr = *jump_entry;
> +#if __PPC64__
The more usual check is
#ifdef __powerpc64__
(here and elsewhere)
> + const int rsz = 8;
> +#else
> + const int rsz = 4;
> +#endif
> + /* Minimum frame size is 32 bytes for ELFv2, and 112 bytes for ELFv1. */
> + const int min_frame = 112;
Since this is known at compile time anyway, you might as well do
#ifdef __powerpc64__
#if _CALL_ELF == 2
const int min_frame = 32;
#else
const int min_frame = 112;
#endif
#else
const int min_frame = 8;
#endif
> + /* Adjust stack pointer. */
> + p += GEN_STDU (p, 1, 1, -frame_size); /* stdu r1,-frame_size(r1) */
OK, this fixes the ABI violation, but now it's valid only for 64-bit.
For 32-bit, you need to use STWU instead.
> + p += gen_atomic_xchg (p, lockaddr, 0, 1);
> + /* Call to collector. */
> + p += gen_call (p, collector);
> + p += gen_atomic_xchg (p, lockaddr, 1, 0);
See other email thread about the lockaddr problem.
> + p += GEN_LOAD (p, 6, 1, min_frame + 35 * rsz); /* ld r6, 35(r1) */
> + p += GEN_MTCR (p, 3); /* mtcr r3 */
> + p += GEN_MTSPR (p, 4, 1); /* mtxer r4 */
> + p += GEN_MTSPR (p, 5, 8); /* mtlr r5 */
> + p += GEN_MTSPR (p, 6, 9); /* mtctr r6 */
> +
> + /* Restore GPRs. */
> + for (j = 2; j < 32; j++)
> + p += GEN_LOAD (p, j, 1, min_frame + j * rsz);
> + p += GEN_LOAD (p, 0, 1, min_frame + 0 * rsz);
> + p += GEN_LOAD (p, 1, 1, min_frame + 1 * rsz);
Ah, this is wrong now: note that above, you first decremented
the stack pointer, and *then* stored the *modified* value to
the stack. So this final load is now a no-op.
Instead of attempting to restore, I'd simply use
p += GEN_ADDI (p, 1, 1, frame_size);
*here* to get back to the original stack pointer value.
> +static void
> +ppc64_emit_stack_adjust (int n)
> +{
> + uint32_t buf[4];
> + uint32_t *p = buf;
> +
> + n = n << 3;
> + if ((n >> 7) != 0)
ADDI supports up to 15-bit unsigned operands,
so this seems overly strict.
> + if (newrel < (1 << 15) && newrel >= -(1 << 15))
> + insn = (insn & ~0xfffc) | (newrel & 0xfffc);
> + else if ((PPC_BO (insn) & 0x14) == 0x4 || (PPC_BO (insn) & 0x14) == 0x10)
> + {
> + newrel -= 4;
> +
> + /* Out of range. Cannot relocate instruction. */
> + if (newrel >= (1 << 25) || newrel < -(1 << 25))
> + return;
> +
> + if ((PPC_BO (insn) & 0x14) == 0x4)
> + insn ^= (1 << 24);
> + else if ((PPC_BO (insn) & 0x14) == 0x10)
> + insn ^= (1 << 22);
> +
> + /* Jump over the unconditional branch. */
> + insn = (insn & ~0xfffc) | 0x8;
> + write_memory_unsigned_integer (*to, 4, byte_order, insn);
> + *to += 4;
> +
> + /* Build a unconditional branch and copy LK bit. */
> + insn = (18 << 26) | (0x3fffffc & newrel) | (insn & 0x3);
> + write_memory_unsigned_integer (*to, 4, byte_order, insn);
> + *to += 4;
> +
> + return;
> + }
> + else
This should check for (PPC_BO (insn) & 0x14) == 0.
Note that (PPC_BO (insn) & 0x14) == 0x14 is the "branch always"
case, which should be replaced simply by an unconditional branch.
> + {
> + uint32_t bdnz_insn = (16 << 26) | (0x10 << 21) | 12;
> + uint32_t bf_insn = (16 << 26) | (0x4 << 21) | 8;
> +
> + newrel -= 12;
That should be -= 8, shouldn't it?
Bye,
Ulrich
--
Dr. Ulrich Weigand
GNU/Linux compilers and toolchain
Ulrich.Weigand@de.ibm.com
next prev parent reply other threads:[~2015-04-08 16:57 UTC|newest]
Thread overview: 21+ messages / expand[flat|nested] mbox.gz Atom feed top
2015-03-30 16:31 [PATCH 1/7 v3] powerpc: Support z-point type in gdbserver Wei-cheng Wang
2015-03-30 16:31 ` [PATCH 6/7 v3] Build unavailable-stack frames for tracepoint Wei-cheng Wang
2015-04-08 17:07 ` Ulrich Weigand
2016-02-22 5:28 ` Marcin Kościelnicki
2016-02-23 18:58 ` Ulrich Weigand
2016-02-24 3:18 ` Marcin Kościelnicki
2016-02-24 20:44 ` Sergio Durigan Junior
2016-02-24 21:06 ` [PATCH] [OBV] gdb/rs6000: Fix maybe-uninitialized warning Marcin Kościelnicki
2015-03-30 16:31 ` [PATCH 5/7 v3] Replace write_inferior_data_ptr with write_inferior_data_pointer Wei-cheng Wang
2015-04-08 17:06 ` Ulrich Weigand
2015-03-30 16:31 ` [PATCH 2/7 v3] Tracepoint for ppc64 Wei-cheng Wang
2015-04-08 16:57 ` Ulrich Weigand [this message]
2015-06-27 17:48 ` Wei-cheng Wang
2015-07-03 16:42 ` Ulrich Weigand
2015-03-30 16:31 ` [PATCH 3/7 v3] Add testcases for ppc64 tracepoint Wei-cheng Wang
2015-04-08 17:02 ` Ulrich Weigand
2015-03-30 16:31 ` [PATCH 7/7 v3] Remove tracepoint_action ops Wei-cheng Wang
2015-04-08 17:09 ` Ulrich Weigand
2015-03-30 16:31 ` [PATCH 4/7 v3] Allow target to decide where to map jump-pad Wei-cheng Wang
2015-04-08 17:04 ` Ulrich Weigand
2015-04-08 16:56 ` [PATCH 1/7 v3] powerpc: Support z-point type in gdbserver Ulrich Weigand
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20150408165700.E9630CF20@oc7340732750.ibm.com \
--to=uweigand@de.ibm.com \
--cc=cole945@gmail.com \
--cc=gdb-patches@sourceware.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).