libbpf: Support initialized global variables
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
This commit is contained in:
parent
8983b731ce
commit
393cdfbee8
|
@ -1835,8 +1835,8 @@ static int bpf_program__record_reloc(struct bpf_program *prog,
|
||||||
return -LIBBPF_ERRNO__RELOC;
|
return -LIBBPF_ERRNO__RELOC;
|
||||||
}
|
}
|
||||||
if (!shdr_idx || shdr_idx >= SHN_LORESERVE) {
|
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",
|
pr_warn("invalid relo for \'%s\' in special section 0x%x; forgot to initialize global var?..\n",
|
||||||
name, shdr_idx, insn_idx, insn->code);
|
name, shdr_idx);
|
||||||
return -LIBBPF_ERRNO__RELOC;
|
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);
|
pr_warn("bad data relo against section %u\n", shdr_idx);
|
||||||
return -LIBBPF_ERRNO__RELOC;
|
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) {
|
if (!obj->caps.global_data) {
|
||||||
pr_warn("relocation: kernel does not support global \'%s\' variable access in insns[%d]\n",
|
pr_warn("relocation: kernel does not support global \'%s\' variable access in insns[%d]\n",
|
||||||
name, insn_idx);
|
name, insn_idx);
|
||||||
|
|
|
@ -8,10 +8,10 @@
|
||||||
|
|
||||||
char _license[] SEC("license") = "GPL";
|
char _license[] SEC("license") = "GPL";
|
||||||
|
|
||||||
static volatile struct data {
|
struct {
|
||||||
char in[256];
|
char in[256];
|
||||||
char out[256];
|
char out[256];
|
||||||
} data;
|
} data = {};
|
||||||
|
|
||||||
struct core_reloc_arrays_output {
|
struct core_reloc_arrays_output {
|
||||||
int a2;
|
int a2;
|
||||||
|
|
|
@ -8,10 +8,10 @@
|
||||||
|
|
||||||
char _license[] SEC("license") = "GPL";
|
char _license[] SEC("license") = "GPL";
|
||||||
|
|
||||||
static volatile struct data {
|
struct {
|
||||||
char in[256];
|
char in[256];
|
||||||
char out[256];
|
char out[256];
|
||||||
} data;
|
} data = {};
|
||||||
|
|
||||||
struct core_reloc_bitfields {
|
struct core_reloc_bitfields {
|
||||||
/* unsigned bitfields */
|
/* unsigned bitfields */
|
||||||
|
|
|
@ -8,10 +8,10 @@
|
||||||
|
|
||||||
char _license[] SEC("license") = "GPL";
|
char _license[] SEC("license") = "GPL";
|
||||||
|
|
||||||
static volatile struct data {
|
struct {
|
||||||
char in[256];
|
char in[256];
|
||||||
char out[256];
|
char out[256];
|
||||||
} data;
|
} data = {};
|
||||||
|
|
||||||
struct core_reloc_bitfields {
|
struct core_reloc_bitfields {
|
||||||
/* unsigned bitfields */
|
/* unsigned bitfields */
|
||||||
|
|
|
@ -8,10 +8,10 @@
|
||||||
|
|
||||||
char _license[] SEC("license") = "GPL";
|
char _license[] SEC("license") = "GPL";
|
||||||
|
|
||||||
static volatile struct data {
|
struct {
|
||||||
char in[256];
|
char in[256];
|
||||||
char out[256];
|
char out[256];
|
||||||
} data;
|
} data = {};
|
||||||
|
|
||||||
struct core_reloc_existence_output {
|
struct core_reloc_existence_output {
|
||||||
int a_exists;
|
int a_exists;
|
||||||
|
|
|
@ -8,10 +8,10 @@
|
||||||
|
|
||||||
char _license[] SEC("license") = "GPL";
|
char _license[] SEC("license") = "GPL";
|
||||||
|
|
||||||
static volatile struct data {
|
struct {
|
||||||
char in[256];
|
char in[256];
|
||||||
char out[256];
|
char out[256];
|
||||||
} data;
|
} data = {};
|
||||||
|
|
||||||
struct core_reloc_flavors {
|
struct core_reloc_flavors {
|
||||||
int a;
|
int a;
|
||||||
|
|
|
@ -8,10 +8,10 @@
|
||||||
|
|
||||||
char _license[] SEC("license") = "GPL";
|
char _license[] SEC("license") = "GPL";
|
||||||
|
|
||||||
static volatile struct data {
|
struct {
|
||||||
char in[256];
|
char in[256];
|
||||||
char out[256];
|
char out[256];
|
||||||
} data;
|
} data = {};
|
||||||
|
|
||||||
struct core_reloc_ints {
|
struct core_reloc_ints {
|
||||||
uint8_t u8_field;
|
uint8_t u8_field;
|
||||||
|
|
|
@ -8,10 +8,10 @@
|
||||||
|
|
||||||
char _license[] SEC("license") = "GPL";
|
char _license[] SEC("license") = "GPL";
|
||||||
|
|
||||||
static volatile struct data {
|
struct {
|
||||||
char in[256];
|
char in[256];
|
||||||
char out[256];
|
char out[256];
|
||||||
} data;
|
} data = {};
|
||||||
|
|
||||||
struct core_reloc_kernel_output {
|
struct core_reloc_kernel_output {
|
||||||
int valid[10];
|
int valid[10];
|
||||||
|
|
|
@ -8,10 +8,10 @@
|
||||||
|
|
||||||
char _license[] SEC("license") = "GPL";
|
char _license[] SEC("license") = "GPL";
|
||||||
|
|
||||||
static volatile struct data {
|
struct {
|
||||||
char in[256];
|
char in[256];
|
||||||
char out[256];
|
char out[256];
|
||||||
} data;
|
} data = {};
|
||||||
|
|
||||||
struct core_reloc_misc_output {
|
struct core_reloc_misc_output {
|
||||||
int a, b, c;
|
int a, b, c;
|
||||||
|
|
|
@ -8,10 +8,10 @@
|
||||||
|
|
||||||
char _license[] SEC("license") = "GPL";
|
char _license[] SEC("license") = "GPL";
|
||||||
|
|
||||||
static volatile struct data {
|
struct {
|
||||||
char in[256];
|
char in[256];
|
||||||
char out[256];
|
char out[256];
|
||||||
} data;
|
} data = {};
|
||||||
|
|
||||||
struct core_reloc_mods_output {
|
struct core_reloc_mods_output {
|
||||||
int a, b, c, d, e, f, g, h;
|
int a, b, c, d, e, f, g, h;
|
||||||
|
|
|
@ -8,10 +8,10 @@
|
||||||
|
|
||||||
char _license[] SEC("license") = "GPL";
|
char _license[] SEC("license") = "GPL";
|
||||||
|
|
||||||
static volatile struct data {
|
struct {
|
||||||
char in[256];
|
char in[256];
|
||||||
char out[256];
|
char out[256];
|
||||||
} data;
|
} data = {};
|
||||||
|
|
||||||
struct core_reloc_nesting_substruct {
|
struct core_reloc_nesting_substruct {
|
||||||
int a;
|
int a;
|
||||||
|
|
|
@ -8,10 +8,10 @@
|
||||||
|
|
||||||
char _license[] SEC("license") = "GPL";
|
char _license[] SEC("license") = "GPL";
|
||||||
|
|
||||||
static volatile struct data {
|
struct {
|
||||||
char in[256];
|
char in[256];
|
||||||
char out[256];
|
char out[256];
|
||||||
} data;
|
} data = {};
|
||||||
|
|
||||||
enum core_reloc_primitives_enum {
|
enum core_reloc_primitives_enum {
|
||||||
A = 0,
|
A = 0,
|
||||||
|
|
|
@ -8,10 +8,10 @@
|
||||||
|
|
||||||
char _license[] SEC("license") = "GPL";
|
char _license[] SEC("license") = "GPL";
|
||||||
|
|
||||||
static volatile struct data {
|
struct {
|
||||||
char in[256];
|
char in[256];
|
||||||
char out[256];
|
char out[256];
|
||||||
} data;
|
} data = {};
|
||||||
|
|
||||||
struct core_reloc_ptr_as_arr {
|
struct core_reloc_ptr_as_arr {
|
||||||
int a;
|
int a;
|
||||||
|
|
|
@ -8,10 +8,10 @@
|
||||||
|
|
||||||
char _license[] SEC("license") = "GPL";
|
char _license[] SEC("license") = "GPL";
|
||||||
|
|
||||||
static volatile struct data {
|
struct {
|
||||||
char in[256];
|
char in[256];
|
||||||
char out[256];
|
char out[256];
|
||||||
} data;
|
} data = {};
|
||||||
|
|
||||||
struct core_reloc_size_output {
|
struct core_reloc_size_output {
|
||||||
int int_sz;
|
int int_sz;
|
||||||
|
|
Loading…
Reference in New Issue