[Pdbg] [PATCH v2] stack: guess endian for stack frame walking
Alistair Popple
alistair at popple.id.au
Fri Sep 21 15:17:45 AEST 2018
Nice! Must admit I haven't read the code in depth but what condition does the
haphazard endian detection use to detemine endianess?
- Alistair
On Friday, 21 September 2018 2:34:17 PM AEST Nicholas Piggin wrote:
> The stack unwinder currently does not do any endian conversion, which
> means it won't work correctly if the stack does not match pdbg endian.
>
> This patch attempts an endian flip if the stack looks wrong, and goes
> with that if it's an improvement. This was nice for debugging skiboot.
>
> Signed-off-by: Nicholas Piggin <npiggin at gmail.com>
> ---
> v2: Improve ugly code slightly
>
> src/thread.c | 60 +++++++++++++++++++++++++++++++++++++++++++++++-----
> 1 file changed, 55 insertions(+), 5 deletions(-)
>
> diff --git a/src/thread.c b/src/thread.c
> index d282307..b53dccd 100644
> --- a/src/thread.c
> +++ b/src/thread.c
> @@ -105,6 +105,15 @@ static int load8(struct pdbg_target *target, uint64_t addr, uint64_t *value)
> return 1;
> }
>
> +uint64_t flip_endian(uint64_t v)
> +{
> +#if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
> + return be64toh(v);
> +#else
> + return le64toh(v);
> +#endif
> +}
> +
> static int dump_stack(struct thread_regs *regs)
> {
> struct pdbg_target *target;
> @@ -117,24 +126,65 @@ static int dump_stack(struct thread_regs *regs)
> break;
> }
>
> - printf("STACK:\n");
> + printf("STACK: SP NIA\n");
> if (!target)
> pdbg_log(PDBG_ERROR, "Unable to read memory (no ADU found)\n");
>
> if (sp && is_real_address(regs, sp)) {
> - if (!load8(target, sp, &sp))
> + uint64_t tmp;
> + bool flip = false;
> +#if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
> + bool be = false;
> +#else
> + bool be = true;
> +#endif
> +
> + if (!load8(target, sp, &tmp))
> return 1;
> - while (sp && is_real_address(regs, sp)) {
> +
> + if (!tmp) {
> +badstack:
> + printf("SP:0x%016" PRIx64 " points to 0x%016" PRIx64 ", not decoding\n", sp, tmp);
> + return 0;
> + }
> +
> + /* Haphazard endian detection */
> + if (tmp < sp || (tmp - sp > (1024*1024*1024))) {
> + uint64_t tmp2;
> + tmp2 = flip_endian(tmp);
> + if (tmp2 < sp || (tmp2 - sp > (1024*1024*1024)))
> + goto badstack;
> + sp = tmp2;
> + flip = true;
> + be = !be;
> + } else {
> + sp = tmp;
> + }
> +
> + if (be)
> + printf("Looks like big-endian\n");
> + else
> + printf("Looks like little-endian\n");
> +
> + while (sp) {
> + if (!is_real_address(regs, sp))
> + break;
> +
> if (!load8(target, sp + 16, &pc))
> return 1;
> + if (flip)
> + pc = flip_endian(pc);
>
> - printf(" 0x%016" PRIx64 " 0x%16" PRIx64 "\n", sp, pc);
> + printf(" 0x%016" PRIx64 " 0x%016" PRIx64 "\n", sp, pc);
>
> if (!load8(target, sp, &sp))
> return 1;
> + if (flip)
> + sp = flip_endian(sp);
> }
> + } else {
> + printf("SP:0x%016" PRIx64 " does not appear to be a stack\n", sp);
> }
> -
> return 0;
> }
>
>
More information about the Pdbg
mailing list