Re: [RFC 3/6] objtool: arm64: Adapt the stack frame checks and the section analysis for the arm architecture

From: Peter Zijlstra
Date: Thu Apr 25 2019 - 04:33:27 EST


On Thu, Apr 25, 2019 at 08:12:24AM +0000, Raphael Gault wrote:
> The motivation behind this is that the `br <Xn>` instruction is a
> dynamic jump (jump to the address contained in the provided register).
> This instruction is used for sibling calls but can also be used for
> switch table. I use this to differentiate these two cases from one another:
>
> Generally the `adr/adrp` instruction is used prior to `br` in order to
> load the address into the register. What I do here is go back throught
> the instructions and try to identify if the address loaded.

Yikes, be very careful with simply going back on the instruction stream.

The problem case would be something like:

adr ...
b 1f

...

b ...
1: br ...

In that case, simply going backwards from 1 will not yield the desired
result.

At some point I did a pass storing all the fwd jumps in their
destination and used that to 'rewind' the instruction stream, but that
wasn't very pretty either.

The best way might be to, while doing validate_branch() keep a state
table of all most recent ADR(P) instructions and when encountering BR
check that state to see what it really is.

We currently don't do dynamic insn->type, but it shouldn't be too hard
(famous last words of course).