Skip to content

Commit

Permalink
elf_reader: support referencing weak variables
Browse files Browse the repository at this point in the history
Our existing tests included a weak symbol, but it wasn't referenced
in code and it ended up in .bss where other symbols sit at the same
index. This confused the loader into thinking the symbol was referenced,
though there were no actual symbol references to it in bpf code.

Signed-off-by: Timo Beckers <[email protected]>
  • Loading branch information
ti-mo committed Oct 1, 2024
1 parent a22a1cd commit b8fd6de
Show file tree
Hide file tree
Showing 9 changed files with 16 additions and 6 deletions.
2 changes: 1 addition & 1 deletion elf_reader.go
Original file line number Diff line number Diff line change
Expand Up @@ -519,7 +519,7 @@ func (ec *elfCode) relocateInstruction(ins *asm.Instruction, rel elf.Symbol) err

case elf.STT_OBJECT:
// LLVM 9 emits OBJECT-LOCAL symbols for anonymous constants.
if bind != elf.STB_GLOBAL && bind != elf.STB_LOCAL {
if bind != elf.STB_GLOBAL && bind != elf.STB_LOCAL && bind != elf.STB_WEAK {
return fmt.Errorf("direct load: %s: %w: %s", name, errUnsupportedBinding, bind)
}

Expand Down
11 changes: 9 additions & 2 deletions elf_reader_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -100,7 +100,7 @@ func TestLoadCollectionSpec(t *testing.T) {
Name: SanitizeName(".bss", -1),
Type: Array,
KeySize: 4,
ValueSize: 12,
ValueSize: 8,
MaxEntries: 1,
},
".data": {
Expand All @@ -117,6 +117,13 @@ func TestLoadCollectionSpec(t *testing.T) {
ValueSize: 4,
MaxEntries: 1,
},
".data.weak": {
Name: SanitizeName(".data.weak", -1),
Type: Array,
KeySize: 4,
ValueSize: 4,
MaxEntries: 1,
},
".data.struct": {
Name: SanitizeName(".data.struct", -1),
Type: Array,
Expand Down Expand Up @@ -209,7 +216,7 @@ func TestLoadCollectionSpec(t *testing.T) {
"neg": {name: "neg", offset: 12, size: 4},
"struct_var": {name: "struct_var", offset: 0, size: 16},
"uneg": {name: "uneg", offset: 8, size: 4},
"weak": {name: "weak", offset: 8, size: 4},
"weak": {name: "weak", offset: 0, size: 4},
},
}

Expand Down
Binary file modified testdata/loader-clang-11-eb.elf
Binary file not shown.
Binary file modified testdata/loader-clang-11-el.elf
Binary file not shown.
Binary file modified testdata/loader-clang-14-eb.elf
Binary file not shown.
Binary file modified testdata/loader-clang-14-el.elf
Binary file not shown.
Binary file modified testdata/loader-clang-17-eb.elf
Binary file not shown.
Binary file modified testdata/loader-clang-17-el.elf
Binary file not shown.
9 changes: 6 additions & 3 deletions testdata/loader.c
Original file line number Diff line number Diff line change
Expand Up @@ -151,7 +151,9 @@ __hidden volatile uint32_t hidden;

// Weak variables can be overridden by non-weak symbols when linking BPF
// programs using bpftool. Make sure they appear in CollectionSpec.Variables.
__weak volatile uint32_t weak;
// Emit to its own section to avoid collisions with other symbols in .bss that
// accidentally increase its refcount.
__weak volatile uint32_t weak __section(".data.weak");

struct struct_var_t {
uint64_t a;
Expand All @@ -161,8 +163,9 @@ volatile struct struct_var_t struct_var __section(".data.struct");

__section("socket") int set_vars() {
hidden = 0xbeef1;
struct_var.a = 0xbeef2;
struct_var.b = 0xbeef3;
weak = 0xbeef2;
struct_var.a = 0xbeef3;
struct_var.b = 0xbeef4;
return 0;
}

Expand Down

0 comments on commit b8fd6de

Please sign in to comment.