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 64bc75fc67230a4294043863a7390e854fde0bd3..a4e250a369c616d71a21bdebe28120e4ac215e9f 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 96b1f5f3b07a2b23763d5d112db45b962b24979e..89951b684282d0fd3bc276ce51fa7dacacaff7b5 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 738b34b72655f75f3f56b6aa3999dc27d66c4884..edc0f7c9e56d7a555050b46d5bd5c6a6279d189e 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 e466e3ab7de4562810377f76c8de6f46d483a8c4..6c20e433558be96a7d71a97ba7c0209daabd5b87 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 c3cac95a19f18d5a5d7c3927f0be8dd93bc40d54..1b7f0ae49cfbb314a4170123b6fc55a2248e864b 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 71fd7cebc9d7907bfb02b6bcc40754954b5e8518..b5dbeef540fdfcae73f6087d0e6e2f639315328a 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 ad5c3f59c9c69431737de47eeebab06cc75112f0..c78ab6d28a14d81f6734f9ed42755dfd266ac63b 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 a4b5e0562ed547927b954c92bfefe41f4e591eb8..5d499ebdc4bdab27826618ac7fe1e0ef4ddbfab3 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 1a36b0856653851f34583f50561357fd88bd5d18..292a5c4ee76a159bbc8109d74e0991d10125896c 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 3199fafede2cd4dab3daa9013a259a82529ae339..0b28bfacc8fd304f8d55b94602adbc63d533bed9 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 98238cb64fbd74b964924a8c68a34f37d06fb7b9..39279bf0c9db9271c03ea280d942bdd65c38f496 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 4f3ecb9127bb24f159fda18c0bd0d919a2ceda09..ea57973cdd19e47b2d5023b88fc408f5541a084b 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 27f602f00419357a158c06c39b799f09416fd0a2..d1eb59d4ea64ae2fe4a45b813385d0868ef2fbbf 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 9a92998d910779f5f577548b220a0e7634507460..9e091124d3bd8b938772db5a5eaab3e3166986d7 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;