libbpf: Support initialized global variables
authorAndrii Nakryiko <andriin@fb.com>
Thu, 21 Nov 2019 07:07:43 +0000 (23:07 -0800)
committerAlexei Starovoitov <ast@kernel.org>
Mon, 25 Nov 2019 00:58:45 +0000 (16:58 -0800)
Initialized global variables are no different in ELF from static variables,
and don't require any extra support from libbpf. But they are matching
semantics of global data (backed by BPF maps) more closely, preventing
LLVM/Clang from aggressively inlining constant values and not requiring
volatile incantations to prevent those. This patch enables global variables.
It still disables uninitialized variables, which will be put into special COM
(common) ELF section, because BPF doesn't allow uninitialized data to be
accessed.

Signed-off-by: Andrii Nakryiko <andriin@fb.com>
Signed-off-by: Alexei Starovoitov <ast@kernel.org>
Link: https://lore.kernel.org/bpf/20191121070743.1309473-5-andriin@fb.com
14 files changed:
tools/lib/bpf/libbpf.c
tools/testing/selftests/bpf/progs/test_core_reloc_arrays.c
tools/testing/selftests/bpf/progs/test_core_reloc_bitfields_direct.c
tools/testing/selftests/bpf/progs/test_core_reloc_bitfields_probed.c
tools/testing/selftests/bpf/progs/test_core_reloc_existence.c
tools/testing/selftests/bpf/progs/test_core_reloc_flavors.c
tools/testing/selftests/bpf/progs/test_core_reloc_ints.c
tools/testing/selftests/bpf/progs/test_core_reloc_kernel.c
tools/testing/selftests/bpf/progs/test_core_reloc_misc.c
tools/testing/selftests/bpf/progs/test_core_reloc_mods.c
tools/testing/selftests/bpf/progs/test_core_reloc_nesting.c
tools/testing/selftests/bpf/progs/test_core_reloc_primitives.c
tools/testing/selftests/bpf/progs/test_core_reloc_ptr_as_arr.c
tools/testing/selftests/bpf/progs/test_core_reloc_size.c

index 64bc75f..a4e250a 100644 (file)
@@ -1835,8 +1835,8 @@ static int bpf_program__record_reloc(struct bpf_program *prog,
                return -LIBBPF_ERRNO__RELOC;
        }
        if (!shdr_idx || shdr_idx >= SHN_LORESERVE) {
-               pr_warn("relocation: not yet supported relo for non-static global \'%s\' variable in special section (0x%x) found in insns[%d].code 0x%x\n",
-                       name, shdr_idx, insn_idx, insn->code);
+               pr_warn("invalid relo for \'%s\' in special section 0x%x; forgot to initialize global var?..\n",
+                       name, shdr_idx);
                return -LIBBPF_ERRNO__RELOC;
        }
 
@@ -1876,11 +1876,6 @@ static int bpf_program__record_reloc(struct bpf_program *prog,
                pr_warn("bad data relo against section %u\n", shdr_idx);
                return -LIBBPF_ERRNO__RELOC;
        }
-       if (GELF_ST_BIND(sym->st_info) == STB_GLOBAL) {
-               pr_warn("relocation: not yet supported relo for non-static global \'%s\' variable found in insns[%d].code 0x%x\n",
-                       name, insn_idx, insn->code);
-               return -LIBBPF_ERRNO__RELOC;
-       }
        if (!obj->caps.global_data) {
                pr_warn("relocation: kernel does not support global \'%s\' variable access in insns[%d]\n",
                        name, insn_idx);
index 96b1f5f..89951b6 100644 (file)
@@ -8,10 +8,10 @@
 
 char _license[] SEC("license") = "GPL";
 
-static volatile struct data {
+struct {
        char in[256];
        char out[256];
-} data;
+} data = {};
 
 struct core_reloc_arrays_output {
        int a2;
index 738b34b..edc0f7c 100644 (file)
@@ -8,10 +8,10 @@
 
 char _license[] SEC("license") = "GPL";
 
-static volatile struct data {
+struct {
        char in[256];
        char out[256];
-} data;
+} data = {};
 
 struct core_reloc_bitfields {
        /* unsigned bitfields */
index e466e3a..6c20e43 100644 (file)
@@ -8,10 +8,10 @@
 
 char _license[] SEC("license") = "GPL";
 
-static volatile struct data {
+struct {
        char in[256];
        char out[256];
-} data;
+} data = {};
 
 struct core_reloc_bitfields {
        /* unsigned bitfields */
index c3cac95..1b7f0ae 100644 (file)
@@ -8,10 +8,10 @@
 
 char _license[] SEC("license") = "GPL";
 
-static volatile struct data {
+struct {
        char in[256];
        char out[256];
-} data;
+} data = {};
 
 struct core_reloc_existence_output {
        int a_exists;
index 71fd7ce..b5dbeef 100644 (file)
@@ -8,10 +8,10 @@
 
 char _license[] SEC("license") = "GPL";
 
-static volatile struct data {
+struct {
        char in[256];
        char out[256];
-} data;
+} data = {};
 
 struct core_reloc_flavors {
        int a;
index ad5c3f5..c78ab6d 100644 (file)
@@ -8,10 +8,10 @@
 
 char _license[] SEC("license") = "GPL";
 
-static volatile struct data {
+struct {
        char in[256];
        char out[256];
-} data;
+} data = {};
 
 struct core_reloc_ints {
        uint8_t         u8_field;
index a4b5e05..5d499eb 100644 (file)
@@ -8,10 +8,10 @@
 
 char _license[] SEC("license") = "GPL";
 
-static volatile struct data {
+struct {
        char in[256];
        char out[256];
-} data;
+} data = {};
 
 struct core_reloc_kernel_output {
        int valid[10];
index 1a36b08..292a5c4 100644 (file)
@@ -8,10 +8,10 @@
 
 char _license[] SEC("license") = "GPL";
 
-static volatile struct data {
+struct {
        char in[256];
        char out[256];
-} data;
+} data = {};
 
 struct core_reloc_misc_output {
        int a, b, c;
index 3199faf..0b28bfa 100644 (file)
@@ -8,10 +8,10 @@
 
 char _license[] SEC("license") = "GPL";
 
-static volatile struct data {
+struct {
        char in[256];
        char out[256];
-} data;
+} data = {};
 
 struct core_reloc_mods_output {
        int a, b, c, d, e, f, g, h;
index 98238cb..39279bf 100644 (file)
@@ -8,10 +8,10 @@
 
 char _license[] SEC("license") = "GPL";
 
-static volatile struct data {
+struct {
        char in[256];
        char out[256];
-} data;
+} data = {};
 
 struct core_reloc_nesting_substruct {
        int a;
index 4f3ecb9..ea57973 100644 (file)
@@ -8,10 +8,10 @@
 
 char _license[] SEC("license") = "GPL";
 
-static volatile struct data {
+struct {
        char in[256];
        char out[256];
-} data;
+} data = {};
 
 enum core_reloc_primitives_enum {
        A = 0,
index 27f602f..d1eb59d 100644 (file)
@@ -8,10 +8,10 @@
 
 char _license[] SEC("license") = "GPL";
 
-static volatile struct data {
+struct {
        char in[256];
        char out[256];
-} data;
+} data = {};
 
 struct core_reloc_ptr_as_arr {
        int a;
index 9a92998..9e09112 100644 (file)
@@ -8,10 +8,10 @@
 
 char _license[] SEC("license") = "GPL";
 
-static volatile struct data {
+struct {
        char in[256];
        char out[256];
-} data;
+} data = {};
 
 struct core_reloc_size_output {
        int int_sz;