Skip site navigation (1)Skip section navigation (2)
Date:      Fri, 10 May 2013 09:51:50 +0100
From:      Andrew Turner <andrew@fubar.geek.nz>
To:        Tim Kientzle <kientzle@freebsd.org>
Cc:        freebsd-arm@freebsd.org
Subject:   Re: Is this related to the general panic discussed in freebsd-current?
Message-ID:  <20130510095150.481feca7@bender.lan>
In-Reply-To: <F8AB4C38-CE15-4C77-8E84-959F2D8167D7@freebsd.org>
References:  <51835891.4050409@thieprojects.ch> <03971BD1-4ADE-4435-BDD0-B94B62634F1D@bsdimp.com> <5183BF8C.4040406@thieprojects.ch> <CCABA43A-6D7E-4310-9F68-AEE54C88F431@kientzle.com> <6D0E82C9-79D1-4804-9B39-3440F99AA8FE@kientzle.com> <20130505140006.0d671ba5@bender> <D0B02568-E7AB-410E-8717-E9F9C745E6ED@kientzle.com> <20130505233729.63ac23bc@bender.lan> <B5B4C509-5CEC-4155-90BF-B40D7395F09B@kientzle.com> <724191A9-57F4-4D66-9E4A-EBBC13BDC0D1@freebsd.org> <20130506124711.23978ec8@bender.lan> <F8AB4C38-CE15-4C77-8E84-959F2D8167D7@freebsd.org>

next in thread | previous in thread | raw e-mail | index | archive | help
On Thu, 9 May 2013 22:17:09 -0700
Tim Kientzle <kientzle@freebsd.org> wrote:

> 
> On May 6, 2013, at 4:47 AM, Andrew Turner wrote:
> 
> > On Sun, 5 May 2013 22:39:56 -0700
> > Tim Kientzle <kientzle@freebsd.org> wrote:
> >> Here's a version of stack_capture that allows a Clang-built
> >> OABI kernel with WITNESS enabled to boot:
> >> 
> >> /* In sys/arm/arm/stack_machdep.c */
> >> static void
> >> stack_capture(struct stack *st, u_int32_t *frame)
> >> {
> >>        vm_offset_t callpc;
> >> 
> >>        stack_zero(st);
> >>        while (INKERNEL(frame)) {
> >>                callpc = frame[1];
> >>                if (stack_put(st, callpc) == -1)
> >>                        break;
> >>                frame = (u_int32_t *)(frame[0]);
> >>        }
> >> }
> > It looks like this should work in most cases where fp and lr are
> > next to each other (ip and sp are between them but doesn't need to
> > be saved).
> 
> Disassembling an EABI kernel, there are 7930 'push' instructions with
> fp and lr next to each other and only 220 without, so it looks like
> the EABI kernel uses this frame convention as well.
It looks like this is a product of cang/llvm. There is no mention of
the frame pointer that I can find in the EABI documentation and gcc
doesn't appear to generate the 'push' instruction with fp.

We can't rely on fp being stored or valid on EABI.

> So what do you think of the following?

I suspect we need to call stack_zero in all cases. I would thing the
following would work:

static void
stack_capture(struct stack *st, u_int32_t *frame)
{
#if !defined(__ARM_EABI__) && !defined(__clang__)
        vm_offset_t callpc;
#endif

        stack_zero(st);
#if !defined(__ARM_EABI__) && !defined(__clang__)
        while (1) {
                if (!INKERNEL(frame))
                        break;
                callpc = frame[FR_SCP];
                if (stack_put(st, callpc) == -1)
                        break;
                frame = (u_int32_t *)(frame[FR_RFP]);
        }
#endif
}

Alternatively the call to stack_zero could be pushed up into the two
functions that call stack_capture.

Looking at the code it appears stack_save_td also uses the frame
pointer to get the stack location, however as this would be unused this
is less of an issue.

Andrew



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?20130510095150.481feca7>