Is this related to the general panic discussed in freebsd-current?
Andrew Turner
andrew at fubar.geek.nz
Fri May 10 08:51:57 UTC 2013
On Thu, 9 May 2013 22:17:09 -0700
Tim Kientzle <kientzle at 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 at 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
More information about the freebsd-arm
mailing list