This is the mail archive of the
mailing list for the elfutils project.
Re: [PATCH 5/5] Add frame pointer unwinding for aarch64
- From: Ulf Hermann <ulf dot hermann at qt dot io>
- To: Mark Wielaard <mark at klomp dot org>, <elfutils-devel at sourceware dot org>
- Date: Tue, 25 Apr 2017 15:38:23 +0200
- Subject: Re: [PATCH 5/5] Add frame pointer unwinding for aarch64
- Authentication-results: sourceware.org; auth=none
- Authentication-results: sourceware.org; dkim=none (message not signed) header.d=none;sourceware.org; dmarc=none action=none header.from=qt.io;
- Dkim-signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=qtcompany.onmicrosoft.com; s=selector1-qt-io; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version; bh=vSkRZnmbPeQEuHm++xjD7HAKNtdEpgBOMVCnnef+byo=; b=XQTUVWcwDRqs8ErsjnNnreRDEOBfHubLj4R0oSMqU+PqieIFwH2YAztpQUf8JxbWMz+I1o9VLdBhYeJTCbMRtkvvOLFoMPHxR4QKfGe8ySMbenoN4w4n7ZCLrKbJJn1v4l1INYLkA4qCeJhENakjbujyNV2U944ys8oPt0jG6sA=
- References: <email@example.com> <firstname.lastname@example.org> <email@example.com> <firstname.lastname@example.org>
- Spamdiagnosticmetadata: NSPM
- Spamdiagnosticoutput: 1:99
> My question is about this "initial frame". In our testcase we don't have
> this case since the backtrace starts in a function that has some CFI.
> But I assume you have some tests that rely on this behavior.
Actually the test I provided does exercise this code. The initial __libc_do_syscall() frame does not have CFI. Only raise() has. You can check that by dropping the code for pc & 0x1.
> The first question is how/why the (pc & 0x1) == 0 check works?
> Why is that the correct check?
> Secondly, if it really is the initial (or signal frame) we are after,
> should we pass in into bool *signal_framep argument. Currently we don't
We have this piece of code in __libdwfl_frame_unwind, in frame_unwind.c:
if (! state->initial_frame && ! state->signal_frame)
AArch64 has a fixed instruction width of 32bit. So, normally the pc is aligned to 4 bytes. Except if we decrement it, then we are guaranteed to have an odd number, which we can then test to see if the frame in question is the initial or a signal frame. Of course it would be nicer to pass this information directly, but the signal_frame parameter is supposed to be an output parameter. After all we do the following after calling ebl_unwind():
state->unwound->signal_frame = signal_frame;
> Lastly could you instead of returning the frame itself with just the pc
> adjusted do that directly?
> if ((pc & 0x1) == 0)
> lr = lr & (~0x1);
If I dig up the first frame after the initial one from the stack, then we drop whatever we initially had in LR. Apparently, on aarch64 PC is always one frame "ahead" of the other registers. To establish that, we have to set PC to the value of LR on the initial frame, without actually unwinding.