Re: [PATCH 7/9] x86/unwind/orc: Fall back to using frame pointers for generated code

From: Josh Poimboeuf
Date: Thu Jun 13 2019 - 21:35:43 EST


On Thu, Jun 13, 2019 at 03:00:55PM -0700, Alexei Starovoitov wrote:
> > @@ -392,8 +402,16 @@ bool unwind_next_frame(struct unwind_state *state)
> > * calls and calls to noreturn functions.
> > */
> > orc = orc_find(state->signal ? state->ip : state->ip - 1);
> > - if (!orc)
> > - goto err;
> > + if (!orc) {
> > + /*
> > + * As a fallback, try to assume this code uses a frame pointer.
> > + * This is useful for generated code, like BPF, which ORC
> > + * doesn't know about. This is just a guess, so the rest of
> > + * the unwind is no longer considered reliable.
> > + */
> > + orc = &orc_fp_entry;
> > + state->error = true;
>
> That seems fragile.

I don't think so. The unwinder has sanity checks to make sure it
doesn't go off the rails. And it works just fine. The beauty is that
it should work for all generated code (not just BPF).

> Can't we populate orc_unwind tables after JIT ?

As I mentioned it would introduce a lot more complexity. For each JIT
function, BPF would have to tell ORC the following:

- where the BPF function lives
- how big the stack frame is
- where RBP and other callee-saved regs are on the stack

There's a lot more fragility lurking there, compared to the above.

Not to mention the unwinder would need BPF-specific knowledge, unless we
created some generic abstraction for generated code to register their
functions (which we have actually considered in the past). But the
above approach is much simpler: just have all generated code use frame
pointers.

--
Josh