as: How to determine the section of symbols

Peter Zijlstra peterz@infradead.org
Tue Jul 16 08:43:00 GMT 2019


On Mon, Jul 15, 2019 at 01:10:42PM -0700, H.J. Lu wrote:
> On Mon, Jul 15, 2019 at 7:48 AM Peter Zijlstra <peterz@infradead.org> wrote:
> >
> > Hi all,
> >
> > I'm trying to 'optimize' the Linux Kernel x86 jump_label support. That
> > is; jump_label or static_branch() is a Linux Kernel construct build upon
> > GCC asm goto and provides for self-modifying code based branches.
> > Regular execution will only see unconditional branches or nops.
> >
> > Currently, on x86, we patch between jmp.d32 or nop5 and this works well.
> >
> > The quest is to also allow usage of jmp.d8 (and the matching nop2) where
> > the displacement allows for this.
> >
> > The below patch is the last of a series that implements this and
> > contains all the relevant bits to this discussion, and is subtly broken.
> >
> > The problem is that the labels GCC hands to the asm goto () can be in
> > different sections (namely .text and .text.unlikely), and the GAS manual
> > sayeth:
> >
> >  [ https://sourceware.org/binutils/docs-2.27/as/Infix-Ops.html#Infix-Ops ]
> >
> >  - Subtraction. If the right argument is absolute, the result has the
> >    section of the left argument. If both arguments are in the same
> >    section, the result is absolute. You may not subtract arguments from
> >    different sections.
> >
> > Funnily this does not result in a compile/assemble time error :-(, it
> > seems to emit a MOP5 but then at runtime explodes because the actual
> > displacement (after linking etc..) ends up fitting in a d8 and then the
> > actual code and the expected code don't match up at code patching time
> > and we BUG.
> >
> > If I were to be able to reliably detect this section mismatch I could
> > encode it in the JUMP_TABLE_ENTRY (__jump_table section).
> >
> > Any clues on how I can (best) fix this; even if it involves writing a
> > GAS patch that'd be fine, we can have this functionality depend on a
> > binutils version.
> >
> 
> .d8 is only a hint.  Is that possible to use the new ".nops SIZE" directive
> where SIZE can be an expression.

The problem appears to be constructing an expression that yields the
exact same semantics as jmp. Given that GCC might provide us with a
label into another section, we cannot (per the above as documentation)
compute a displacement. Or ever detect this case.

Also, is there any control over what NOPs are emitted with .nops ? There
is a hard requirement the nop5 and nop2 are single instructions.



More information about the Binutils mailing list