[BPF] Fix CORE optimization bug in BPFMISimplifyPatchable (#183446)
Commit ffd57408efd4 ("[BPF] Enable relocation location for
load/store/shifts") enabled CORE relocation for load/store/shirts. In
particular, the commit did optimization to have load/store/shift insn
itself having the relocation. For the load and store, the optimization
has the following:
rX = *(rY + <relocation>) and *(rX + <relocation>) = rY
There is no value-range check for the above '<relocation>'. For example,
if the original `<relocation>` is 0x10006 due to a large struct, the
insn encoding of `<relocaiton>` will be truncated into '6' and incorrect
result will happen.
This patch fixed the issue by checking the value range of
'<relocation>'. If the `<relocation>` is more than INT16_MAX,
optimization will be skipped.
Even llvm side is fixed, libbpf side may still have issues with the
current approach since libbpf may change the value of <relocation>. If
the <relocation> value is more than INT16_MAX, libbpf will either fail
or need to patch insns.
Let us say we have
rX = *(rY + <relocation>) and *(rX + <relocation>) = rY
libbpf will modify `<relocation>` value depending on the actual offset
in kernel data structure. If `<relocation>` is more than INT16_MAX, more
than one insn will be necessary. llvm can add nop instructions for patch
purpose (see [1]).
The following are major patching cases:
case 1: rX = *(rY + <relocation>) // rX and rY are different
rX = <relocation>
rX += rY
rX = *(rX + 0)
case 2: rX = *(rX + <relocation>)
rX += <relocation>
rX = *(rX + 0)
case 3: *(rX + <relocation>) = imm
rX += <relocation>
*(rX + 0) = imm
rX -= <relocation>
case 4: *(rX + <relocation>) = rY // rX and rY are different
rX += <relocation>
*(rX + 0) = rY
rX -= <relocation>
case 5: *(rX + <relocation>) = rX
// We are not able to resolve this issue.
A llvm option (-disable-bpf-core-optimization) is implemented to
disable bpf core optimizaiton, which means the relocation will not
be in load/store insns. This can workaround the above case 5.
[1] https://github.com/llvm/llvm-project/compare/main...yonghong-song:llvm-project:fix-core-overflow-debug