<html>
<head>
<base href="https://llvm.org/bugs/" />
</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: relocation records generated for non-map data"
href="https://llvm.org/bugs/show_bug.cgi?id=26243">26243</a>
</td>
</tr>
<tr>
<th>Summary</th>
<td>BPF target: relocation records generated for non-map data
</td>
</tr>
<tr>
<th>Product</th>
<td>new-bugs
</td>
</tr>
<tr>
<th>Version</th>
<td>unspecified
</td>
</tr>
<tr>
<th>Hardware</th>
<td>PC
</td>
</tr>
<tr>
<th>OS</th>
<td>Linux
</td>
</tr>
<tr>
<th>Status</th>
<td>NEW
</td>
</tr>
<tr>
<th>Severity</th>
<td>normal
</td>
</tr>
<tr>
<th>Priority</th>
<td>P
</td>
</tr>
<tr>
<th>Component</th>
<td>new bugs
</td>
</tr>
<tr>
<th>Assignee</th>
<td>unassignedbugs@nondot.org
</td>
</tr>
<tr>
<th>Reporter</th>
<td>daniel@iogearbox.net
</td>
</tr>
<tr>
<th>CC</th>
<td>llvm-bugs@lists.llvm.org
</td>
</tr>
<tr>
<th>Classification</th>
<td>Unclassified
</td>
</tr></table>
<p>
<div>
<pre>I've noticed tc loader inserting map relocations where there are actually
none. I believe also other loaders might be affected (libbpf, etc).
Debugging this issue further shows that the ELF file I was working with had
couple of other relocations besides maps. I have some test cases attached
below.
# llc --version
LLVM (<a href="http://llvm.org/">http://llvm.org/</a>):
LLVM version 3.8.0svn
Optimized build.
Built Jan 9 2016 (02:08:10).
Default target: x86_64-unknown-linux-gnu
Host CPU: ivybridge
Registered Targets:
bpf - BPF (host endian)
bpfeb - BPF (big endian)
bpfel - BPF (little endian)
x86 - 32-bit X86: Pentium-Pro and above
x86-64 - 64-bit X86: EM64T and AMD64
*** Test case:
#include <iproute2/bpf_api.h>
union v6addr {
struct {
__u32 p1;
__u32 p2;
__u32 p3;
__u32 p4;
};
__u8 addr[16];
};
static void (*data_barrier)(void *key) = (void *) 42;
#define X { .addr = { 0xef, 0xab, 0xef, 0xab, 0xef, 0xab, 0xef, 0xab, 0xef,
0xcb, 0, 0, 0, 0, 0, 0xff } }
__section("foo") int bar(struct __sk_buff *skb)
{
union v6addr x = X;
data_barrier(&x);
return -1;
}
BPF_LICENSE("GPL");
*** Disassembly:
The code generated the relocation record of .Lbar.x:
# clang -O2 -target bpf -c foo.c -S -o -
.text
.section foo,"ax",@progbits
.globl bar
.align 8
bar: # @bar
# BB#0:
ld_64 r1, <MCOperand Expr:(.Lbar.x)>
ldw r2, 0(r1)
ldw r1, 4(r1)
slli r1, 32
or r1, r2
std -8(r10), r1
std -16(r10), r1
mov r1, r10
addi r1, -16
call 42
ld_64 r0, 4294967295
ret
.section .rodata.cst16,"aM",@progbits,16
.align 4 # @bar.x
.Lbar.x:
.ascii
"\357\253\357\253\357\253\357\253\357\313\000\000\000\000\000\377"
.section license,"aw",@progbits
.globl ____license # @____license
____license:
.asciz "GPL"
*** ELF data:
# readelf -a foo.o
[...]
Section Headers:
[Nr] Name Type Address Offset
Size EntSize Flags Link Info Align
[ 0] NULL 0000000000000000 00000000
0000000000000000 0000000000000000 0 0 0
[ 1] .strtab STRTAB 0000000000000000 00000138
0000000000000045 0000000000000000 0 0 1
[ 2] .text PROGBITS 0000000000000000 00000040
0000000000000000 0000000000000000 AX 0 0 4
[ 3] foo PROGBITS 0000000000000000 00000040
0000000000000070 0000000000000000 AX 0 0 8
[ 4] .relfoo REL 0000000000000000 00000128
0000000000000010 0000000000000010 7 3 8
[ 5] .rodata.cst16 PROGBITS 0000000000000000 000000b0
0000000000000010 0000000000000010 AM 0 0 4
[ 6] license PROGBITS 0000000000000000 000000c0
0000000000000004 0000000000000000 WA 0 0 1
[ 7] .symtab SYMTAB 0000000000000000 000000c8
0000000000000060 0000000000000018 1 2 8
[...]
Relocation section '.relfoo' at offset 0x128 contains 1 entries:
Offset Info Type Sym. Value Sym. Name
000000000000 000100000001 unrecognized: 1 0000000000000000 .Lbar.x
The decoding of unwind sections for machine type None is not currently
supported.
Symbol table '.symtab' contains 4 entries:
Num: Value Size Type Bind Vis Ndx Name
0: 0000000000000000 0 NOTYPE LOCAL DEFAULT UND
1: 0000000000000000 0 NOTYPE LOCAL DEFAULT 5 .Lbar.x
2: 0000000000000000 0 NOTYPE GLOBAL DEFAULT 6 ____license
3: 0000000000000000 0 NOTYPE GLOBAL DEFAULT 3 bar
# readelf -x 5 foo.o
Hex dump of section '.rodata.cst16':
0x00000000 efabefab efabefab efcb0000 000000ff ................
I could probably change the tc loader to handle such cases and fix up the
ld_64 instruction from the relocation information. But something else seems
still odd to me, if I do:
#include <iproute2/bpf_api.h>
union v6addr {
struct {
__u32 p1;
__u32 p2;
__u32 p3;
__u32 p4;
};
__u8 addr[16];
};
static void (*data_barrier)(void *key) = (void *) 42;
#define X { .addr = { 0xef, 0xab, 0xef, 0xab, 0xef, 0xab, 0xef, 0xab, 0xef,
0xcb, 0, 0, 0, 0, 0, 0xff } }
__section("foo") int bar(struct __sk_buff *skb)
{
char fmt[] =
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa";
union v6addr x = X;
data_barrier(&x);
data_barrier(fmt);
return -1;
}
BPF_LICENSE("GPL");
Then the disassembly looks:
# clang -O2 -target bpf -c test.c -S -o -
.text
.section foo,"ax",@progbits
.globl bar
.align 8
bar: # @bar
# BB#0:
mov r1, 97
sth -4(r10), r1
mov r1, 1633771873
stw -8(r10), r1
ld_64 r1, 7016996765293437281
std -16(r10), r1
std -24(r10), r1
std -32(r10), r1
std -40(r10), r1
std -48(r10), r1
std -56(r10), r1
std -64(r10), r1
ld_64 r1, <MCOperand Expr:(.Lbar.x)>
ldw r2, 0(r1)
ldw r1, 4(r1)
slli r1, 32
or r1, r2
std -72(r10), r1
std -80(r10), r1
mov r1, r10
addi r1, -80
call 42
mov r1, r10
addi r1, -64
call 42
ld_64 r0, 4294967295
ret
.section .rodata.str1.1,"aMS",@progbits,1
.Lbar.fmt: # @bar.fmt
.asciz "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
.section .rodata.cst16,"aM",@progbits,16
.align 4 # @bar.x
.Lbar.x:
.ascii
"\357\253\357\253\357\253\357\253\357\313\000\000\000\000\000\377"
.section license,"aw",@progbits
.globl ____license # @____license
____license:
.asciz "GPL"
So, Lbar.fmt doesn't seem to be referenced. It seems this is a bug?
There's just one relocation record, which is for Lbar.x:
Section Headers:
[Nr] Name Type Address Offset
Size EntSize Flags Link Info Align
[ 0] NULL 0000000000000000 00000000
0000000000000000 0000000000000000 0 0 0
[ 1] .strtab STRTAB 0000000000000000 000001f8
0000000000000054 0000000000000000 0 0 1
[ 2] .text PROGBITS 0000000000000000 00000040
0000000000000000 0000000000000000 AX 0 0 4
[ 3] foo PROGBITS 0000000000000000 00000040
00000000000000f0 0000000000000000 AX 0 0 8
[ 4] .relfoo REL 0000000000000000 000001e8
0000000000000010 0000000000000010 8 3 8
[ 5] .rodata.str1.1 PROGBITS 0000000000000000 00000130
000000000000003e 0000000000000001 AMS 0 0 1
[ 6] .rodata.cst16 PROGBITS 0000000000000000 00000170
0000000000000010 0000000000000010 AM 0 0 4
[ 7] license PROGBITS 0000000000000000 00000180
0000000000000004 0000000000000000 WA 0 0 1
[ 8] .symtab SYMTAB 0000000000000000 00000188
0000000000000060 0000000000000018 1 2 8
Key to Flags:
W (write), A (alloc), X (execute), M (merge), S (strings)
I (info), L (link order), G (group), T (TLS), E (exclude), x (unknown)
O (extra OS processing required) o (OS specific), p (processor specific)
There are no section groups in this file.
There are no program headers in this file.
Relocation section '.relfoo' at offset 0x1e8 contains 1 entries:
Offset Info Type Sym. Value Sym. Name
000000000068 000100000001 unrecognized: 1 0000000000000000 .Lbar.x
The decoding of unwind sections for machine type None is not currently
supported.
Symbol table '.symtab' contains 4 entries:
Num: Value Size Type Bind Vis Ndx Name
0: 0000000000000000 0 NOTYPE LOCAL DEFAULT UND
1: 0000000000000000 0 NOTYPE LOCAL DEFAULT 6 .Lbar.x
2: 0000000000000000 0 NOTYPE GLOBAL DEFAULT 7 ____license
3: 0000000000000000 0 NOTYPE GLOBAL DEFAULT 3 bar
But nevertheless, .Lbar.fmt shouldn't be a relocation record, because fixing
this up in the loader seems like a huge headache. That data can only be stored
in the eBPF stack, so the loader would need to start dissecting this string
data into eBPF instructions and mess with the actual eBPF program code to place
this into the stack manually. While it could work for ld_64 relocs, I believe
this seems not intended for strings at least.
There seems to be even stranger stuff (or, perhaps it's expected and I only
haven't seen it before):
I have another object file generated by clang which is similar to union
v6addr x = X; kind of initialization, where we get a .rodata section without
postfix name, it looks like:
[...]
Section Headers:
[Nr] Name Type Address Offset
Size EntSize Flags Link Info Align
[ 0] NULL 0000000000000000 00000000
0000000000000000 0000000000000000 0 0 0
[ 1] .strtab STRTAB 0000000000000000 000008e8
000000000000009b 0000000000000000 0 0 1
[ 2] .text PROGBITS 0000000000000000 00000040
0000000000000000 0000000000000000 AX 0 0 4
[ 3] from-p1 PROGBITS 0000000000000000 00000040
0000000000000728 0000000000000000 AX 0 0 8
[ 4] .relfrom-p1 REL 0000000000000000 000008c8
0000000000000020 0000000000000010 8 3 8
[ 5] maps PROGBITS 0000000000000000 00000768
0000000000000018 0000000000000000 WA 0 0 4
[ 6] license PROGBITS 0000000000000000 00000780
0000000000000004 0000000000000000 WA 0 0 1
[ 7] .rodata PROGBITS 0000000000000000 00000784
0000000000000006 0000000000000000 A 0 0 1
[ 8] .symtab SYMTAB 0000000000000000 00000790
0000000000000138 0000000000000018 1 10 8
Key to Flags:
W (write), A (alloc), X (execute), M (merge), S (strings)
I (info), L (link order), G (group), T (TLS), E (exclude), x (unknown)
O (extra OS processing required) o (OS specific), p (processor specific)
There are no section groups in this file.
There are no program headers in this file.
Relocation section '.relfrom-p1' at offset 0x8c8 contains 2 entries:
Offset Info Type Sym. Value Sym. Name
000000000070 000900000001 unrecognized: 1 0000000000000000 .rodata
000000000628 000b00000001 unrecognized: 1 0000000000000000 mymap
The decoding of unwind sections for machine type None is not currently
supported.
Symbol table '.symtab' contains 13 entries:
Num: Value Size Type Bind Vis Ndx Name
0: 0000000000000000 0 NOTYPE LOCAL DEFAULT UND
1: 00000000000004b8 0 NOTYPE LOCAL DEFAULT 3 LBB0_10
2: 00000000000004e8 0 NOTYPE LOCAL DEFAULT 3 LBB0_12
3: 0000000000000588 0 NOTYPE LOCAL DEFAULT 3 LBB0_15
4: 0000000000000708 0 NOTYPE LOCAL DEFAULT 3 LBB0_20
5: 0000000000000358 0 NOTYPE LOCAL DEFAULT 3 LBB0_21
6: 0000000000000718 0 NOTYPE LOCAL DEFAULT 3 LBB0_22
7: 0000000000000378 0 NOTYPE LOCAL DEFAULT 3 LBB0_4
8: 0000000000000410 0 NOTYPE LOCAL DEFAULT 3 LBB0_6
9: 0000000000000000 0 SECTION LOCAL DEFAULT 7
10: 0000000000000000 0 NOTYPE GLOBAL DEFAULT 6 ____license
11: 0000000000000000 0 NOTYPE GLOBAL DEFAULT 5 mymap
12: 0000000000000000 0 NOTYPE GLOBAL DEFAULT 3 handle_ingress
# readelf -x 7 foo.o
Hex dump of section '.rodata':
0x00000000 deadbeef c0de ......
Note, the deadbeef c0de is not part of the C program itself, so this seems to
come from llvm somehow.</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>