On Tue, Aug 25, 2020 at 9:34 AM Kevin Sheldrake <Kevin.Sheldrake@xxxxxxxxxxxxx> wrote: > > Hello > > I've got some odd behaviour and I'd like to ask if anyone could spare a few moments to offer suggestions of what my error might be? Maybe there is a different mailing list that this would be more appropriate to send to? > > I'm building a relatively complex eBPF program that attaches to the raw tracepoints, sys_enter and sys_exit, compiled with clang and llc using the same switches and includes as the kernel samples (kernel v5.3 on ubuntu 18.04), loaded using the latest libbpf git sources. The sys_exit program is quite big at 55045 instructions (unrolled loops so the same code will run on kernel v5.1) and contains illegal jumps. Everything is inlined - using __attribute__((always_inline)) - and the programs themselves have the __attribute__((flatten)) applied. The verifier complains: > jump out of range from insn 15 to -10500 > > If I remove one section of code, unrelated to where the illegal jumps are, reducing the overall size to 24480 instructions, the illegal jumps disappear. If I reenable that section of code and remove a different section of code, also unrelated to the illegal jumps, reducing the overall size to 47444 instructions, the illegal jumps disappear again. I suspect it's a bug in llvm. It doesn't have a check that the branch target fits into 16-bits. It simply does: llvm/lib/Target/BPF/MCTargetDesc/BPFAsmBackend.cpp Value = (uint16_t)((Value - 8) / 8); support::endian::write<uint16_t>(&Data[Fixup.getOffset() + 2], Value, Endian); Could you add a log around that line to double check that's the case? May be you could send a patch to add an assert there? It will help others avoid this debugging. In the past we've talked about extending BPF ISA with 32-bit unconditional jump instruction. But no one didn't come around to actually implementing it. Once we have such insn llvm should be able to detect this 16-bit overflow and use this new jmp insn.