<div dir="ltr">On 29 June 2016 at 04:48, Dave Anderson <<a href="mailto:anderson@redhat.com">anderson@redhat.com</a>> wrote:<br>><br>> > On arm64, the link register (LR) holds a return address, which is the one<br>> > just after a branch instruction. So using a saved lr as PC for backtracing<br>> > might cause some confusion.<br>> > For example, in kernel/entry.S,<br>> > work_resched:<br>> >     ...<br>> >     bl schedule<br>> ><br>> > ret_to_user:<br>> >     ...<br>> ><br>> > The current code shows "ret_o_user", instead of "work_resched",<br>> > as a caller of schedule().<br>><br>> I see...<br><br><div class="gmail_default" style="font-family:monospace,monospace">​FYI, this can potentially be seen in the kernel's ftrace-based stack tracer or</div><div class="gmail_default" style="font-family:monospace,monospace">panic dump.</div><div class="gmail_default" style="font-family:monospace,monospace">In the past, ​PC calculation was modified to be "LR-4", but this patch</div><div class="gmail_default" style="font-family:monospace,monospace">was reverted. See</div><div class="gmail_default" style=""><span style="font-family:monospace,monospace">    </span><font face="monospace, monospace">commit 9702970c7bd3(</font><span style="font-family:monospace,monospace">Revert "ARM64: unwind: Fix PC calculation")</span></div><div><br></div><div class="gmail_default" style="font-family:monospace,monospace">​So I said that adding this patch was a discussion topic.​</div><br>> ><br>> > This patch corrects a PC by decrementing it by 4.<br>> > But please note that this change may also make people a bit confused<br>> > because a value of LR in the stack dump of "bt -f" doesn't match with<br>> > an address in one-line summary.<br>> ><br>> >  #2 [ffffcc7511407eb0] schedule at ffff0000d628aee0<br>> >     ffffcc7511407eb0: ffffcc6d22f23080 ffff0000d5b44d6c  <= LR<br>> >     ffffcc7511407ec0: ffffcc7511407ed0 0000000000000000<br>> >  #3 [ffffcc7511407ed0] work_resched at ffff0000d5b44d68  <= correcrted PC<br>><br>> That's probably OK -- and at least "bt -F" would clarify it somewhat.<br><br><div class="gmail_default" style="font-family:monospace,monospace">​and "bt -Fs"​</div><div><br></div><div class="gmail_default" style="font-family:monospace,monospace">​-Takahiro AKASHI​</div><br><br>> Thanks,<br>>   Dave<br>><br>><br>> ><br>> > Signed-off-by: AKASHI Takahiro <<a href="mailto:takahiro.akashi@linaro.org">takahiro.akashi@linaro.org</a>><br>> > ---<br>> >  arm64.c | 23 ++++++++++++++---------<br>> >  1 file changed, 14 insertions(+), 9 deletions(-)<br>> ><br>> > diff --git a/arm64.c b/arm64.c<br>> > index b74d2c4..bad36aa 100644<br>> > --- a/arm64.c<br>> > +++ b/arm64.c<br>> > @@ -1504,35 +1504,40 @@ static int<br>> >  arm64_print_stackframe_entry(struct bt_info *bt, int level, struct<br>> >  arm64_stackframe *frame, FILE *ofp)<br>> >  {<br>> >       char *name, *name_plus_offset;<br>> > -     ulong symbol_offset;<br>> > +     ulong pc, symbol_offset;<br>> >       struct syment *sp;<br>> >       struct load_module *lm;<br>> >       char buf[BUFSIZE];<br>> ><br>> > -        name = closest_symbol(frame->pc);<br>> > +     /*<br>> > +      * if pc comes from a saved lr, it actually points to an instruction<br>> > +      * after branch. To avoid any confusion, decrement pc by 4.<br>> > +      * See, for example, "bl schedule" before ret_to_user().<br>> > +      */<br>> > +     pc = frame->pc - 0x4;<br>> > +     name = closest_symbol(pc);<br>> >          name_plus_offset = NULL;<br>> ><br>> >          if (bt->flags & BT_SYMBOL_OFFSET) {<br>> > -                sp = value_search(frame->pc, &symbol_offset);<br>> > +             sp = value_search(pc, &symbol_offset);<br>> >                  if (sp && symbol_offset)<br>> > -                        name_plus_offset =<br>> > -                                value_to_symstr(frame->pc, buf, bt->radix);<br>> > +                     name_plus_offset = value_to_symstr(pc, buf, bt->radix);<br>> >          }<br>> ><br>> >          fprintf(ofp, "%s#%d [%8lx] %s at %lx", level < 10 ? " " : "", level,<br>> >                  frame->fp ? frame->fp : bt->stacktop - USER_EFRAME_OFFSET,<br>> > -             name_plus_offset ? name_plus_offset : name, frame->pc);<br>> > +             name_plus_offset ? name_plus_offset : name, pc);<br>> ><br>> >       if (BT_REFERENCE_CHECK(bt))<br>> > -             arm64_do_bt_reference_check(bt, frame->pc, name);<br>> > +             arm64_do_bt_reference_check(bt, pc, name);<br>> ><br>> > -     if (module_symbol(frame->pc, NULL, &lm, NULL, 0))<br>> > +     if (module_symbol(pc, NULL, &lm, NULL, 0))<br>> >               fprintf(ofp, " [%s]", lm->mod_name);<br>> ><br>> >       fprintf(ofp, "\n");<br>> ><br>> >       if (bt->flags & BT_LINE_NUMBERS) {<br>> > -             get_line_number(frame->pc, buf, FALSE);<br>> > +             get_line_number(pc, buf, FALSE);<br>> >               if (strlen(buf))<br>> >                       fprintf(ofp, "    %s\n", buf);<br>> >       }<br>> > --<br>> > 2.9.0<br>> ><br>> > --<br>> > Crash-utility mailing list<br>> > <a href="mailto:Crash-utility@redhat.com">Crash-utility@redhat.com</a><br>> > <a href="https://www.redhat.com/mailman/listinfo/crash-utility">https://www.redhat.com/mailman/listinfo/crash-utility</a><br>> ><br>><br>> --<br>> Crash-utility mailing list<br>> <a href="mailto:Crash-utility@redhat.com">Crash-utility@redhat.com</a><br>> <a href="https://www.redhat.com/mailman/listinfo/crash-utility">https://www.redhat.com/mailman/listinfo/crash-utility</a></div>