<html>
<head>
<base href="https://bugs.llvm.org/">
</head>
<body><table border="1" cellspacing="0" cellpadding="8">
<tr>
<th>Bug ID</th>
<td><a class="bz_bug_link
bz_status_NEW "
title="NEW - BPF target: emits invalid jump offsets in large programs"
href="https://bugs.llvm.org/show_bug.cgi?id=49165">49165</a>
</td>
</tr>
<tr>
<th>Summary</th>
<td>BPF target: emits invalid jump offsets in large programs
</td>
</tr>
<tr>
<th>Product</th>
<td>libraries
</td>
</tr>
<tr>
<th>Version</th>
<td>11.0
</td>
</tr>
<tr>
<th>Hardware</th>
<td>PC
</td>
</tr>
<tr>
<th>OS</th>
<td>All
</td>
</tr>
<tr>
<th>Status</th>
<td>NEW
</td>
</tr>
<tr>
<th>Severity</th>
<td>enhancement
</td>
</tr>
<tr>
<th>Priority</th>
<td>P
</td>
</tr>
<tr>
<th>Component</th>
<td>Backend: BPF
</td>
</tr>
<tr>
<th>Assignee</th>
<td>unassignedbugs@nondot.org
</td>
</tr>
<tr>
<th>Reporter</th>
<td>evanthmp@amazon.com
</td>
</tr>
<tr>
<th>CC</th>
<td>llvm-bugs@lists.llvm.org
</td>
</tr></table>
<p>
<div>
<pre>Created <span class=""><a href="attachment.cgi?id=24521" name="attach_24521" title="LLVM miscompiles this program">attachment 24521</a> <a href="attachment.cgi?id=24521&action=edit" title="LLVM miscompiles this program">[details]</a></span>
LLVM miscompiles this program
The BPF instruction set uses a signed 16-bit jump offset. For large programs (>
32k instructions), LLVM emits incorrect jumps outside the program bounds or to
the wrong location.
I have attached a minimal reproduction program, emits_illegal_jump.c
When the attached test program is compiled:
% /usr/local/opt/llvm/bin/clang -target bpf -Wall -O3 -c emits_illegal_jump.c
-o objfile.o
We can see an incorrect jump at address 0x46718:
% /usr/local/opt/binutils/bin/objdump -S objfile.o
...
46718: 55 04 30 73 04 00 00 00 jne %r4,4,29488
0000000000046720 <LBB0_11>:
46720: b7 00 00 00 04 00 00 00 mov %r0,4
46728: 05 00 03 00 00 00 00 00 ja 3
0000000000046730 <LBB0_13>:
46730: b7 00 00 00 02 00 00 00 mov %r0,2
46738: 05 00 01 00 00 00 00 00 ja 1
0000000000046740 <LBB0_12>:
46740: bf 30 00 00 00 00 00 00 mov %r0,%r3
0000000000046748 <LBB0_14>:
46748: 95 00 00 00 00 00 00 00 exit
0x46748 is the end of the program, so at 0x46718, jumping forward by 29488
takes us well outside the bounds of the program.
29488 is 0x7330. I am guessing this instruction was actually supposed to be a
jump by -33056, or 0xffff7330 in 2's complement. It appears that LLVM
calculates a jump offset with larger-than-16-bit integer math, and then stuffs
the lower 16 bits into the BPF jump offset field without considering whether
the value can actually be represented by a signed 16-bit integer.
The correct behavior would be to emit an error and fail to compile the program
in this case. Or even better (but more complicated), emit a series of multiple
valid jumps, or a trampoline (bpf / ebpf doesn't have an indirect jump
instruction so this may be tough).
Other details: I am using LLVM 11.0.1 from homebrew
% /usr/local/opt/llvm/bin/clang --version
clang version 11.0.1
Target: x86_64-apple-darwin19.6.0
Thread model: posix
InstalledDir: /usr/local/opt/llvm/bin</pre>
</div>
</p>
<hr>
<span>You are receiving this mail because:</span>
<ul>
<li>You are on the CC list for the bug.</li>
</ul>
</body>
</html>