On Tue, 2017-04-25 at 14:49 +0200, Mark Wielaard wrote: > +bool > +EBLHOOK(unwind) (Ebl *ebl __attribute__ ((unused)), Dwarf_Addr pc > __attribute__ ((unused)), > + ebl_tid_registers_t *setfunc, ebl_tid_registers_get_t > *getfunc, > + ebl_pid_memory_read_t *readfunc, void *arg, > + bool *signal_framep __attribute__ ((unused))) > +{ > + Dwarf_Word fp, lr, sp; > + > + if (!getfunc(LR_REG, 1, &lr, arg)) > + return false; > + > + if (!getfunc(FP_REG, 1, &fp, arg)) > + fp = 0; > + > + if (!getfunc(SP_REG, 1, &sp, arg)) > + sp = 0; > + > + Dwarf_Word newPc, newLr, newFp, newSp; > + > + // The initial frame is special. We are expected to return lr directly in > this case, and we'll > + // come back to the same frame again in the next round. > + if ((pc & 0x1) == 0) > + { > + newLr = lr; > + newFp = fp; > + newSp = sp; > + } > + else > + { > + if (!readfunc(fp + LR_OFFSET, &newLr, arg)) > + newLr = 0; > + > + if (!readfunc(fp + FP_OFFSET, &newFp, arg)) > + newFp = 0; > + > + newSp = fp + SP_OFFSET; > + } > + > + newPc = newLr & (~0x1); > + if (!setfunc(-1, 1, &newPc, arg)) > + return false;
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. 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 Lastly could you instead of returning the frame itself with just the pc adjusted do that directly? if ((pc & 0x1) == 0) lr = lr & (~0x1); And then use the code in the else clause always? All the above might simply be me not understanding the significance of the initial frame. Cheers, Mark