[llvm-bugs] [Bug 26243] New: BPF target: relocation records generated for non-map data

via llvm-bugs llvm-bugs at lists.llvm.org
Thu Jan 21 11:11:40 PST 2016


https://llvm.org/bugs/show_bug.cgi?id=26243

            Bug ID: 26243
           Summary: BPF target: relocation records generated for non-map
                    data
           Product: new-bugs
           Version: unspecified
          Hardware: PC
                OS: Linux
            Status: NEW
          Severity: normal
          Priority: P
         Component: new bugs
          Assignee: unassignedbugs at nondot.org
          Reporter: daniel at iogearbox.net
                CC: llvm-bugs at lists.llvm.org
    Classification: Unclassified

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 (http://llvm.org/):
  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", at 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", at 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", at 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", at 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", at progbits,1
.Lbar.fmt:                              # @bar.fmt
    .asciz    "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"

    .section    .rodata.cst16,"aM", at 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", at 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.

-- 
You are receiving this mail because:
You are on the CC list for the bug.
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/llvm-bugs/attachments/20160121/a145a469/attachment-0001.html>


More information about the llvm-bugs mailing list