From 0d45550a184cc5a9f10187a97b9ef8dc7fa13f31 Mon Sep 17 00:00:00 2001
From: Serhei Makarov <smakarov@redhat.com>
Date: Fri, 2 Nov 2018 16:49:23 -0400
Subject: [PATCH 19/32] PR23829 :: fallback defines __BPF_FUNC_MAPPER and
BPF_J{LT,LE,SLT,SLE} for older kernels
---
bpf-base.cxx | 59 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
bpf-internal.h | 11 +++++++++++
2 files changed, 70 insertions(+)
diff --git a/bpf-base.cxx b/bpf-base.cxx
index 277927b72..210efa9aa 100644
--- a/bpf-base.cxx
+++ b/bpf-base.cxx
@@ -140,6 +140,65 @@ is_commutative(opcode code)
std::map<unsigned, const char *> bpf_func_name_map;
std::map<std::string, bpf_func_id> bpf_func_id_map;
+/* PR23829: On older kernels, bpf.h does not define __BPF_FUNC_MAPPER.
+ As a fallback, use the *earliest* __BPF_FUNC_MAPPER, so stapbpf
+ will not try helpers that only exist on subsequent kernels.
+
+ TODO: This isn't perfect since even older kernels don't have
+ some of these helpers.
+
+ XXX: Note the build limitation in that SystemTap must be compiled
+ against a recent kernel to be able to use the helpers from that
+ kernel. That's also the case when building against recent bpf.h
+ with __BPF_FUNC_MAPPER, so this workaround is not the source of the
+ problem. */
+#ifndef __BPF_FUNC_MAPPER
+#define __BPF_FUNC_MAPPER(FN) \
+ FN(unspec), \
+ FN(map_lookup_elem), \
+ FN(map_update_elem), \
+ FN(map_delete_elem), \
+ FN(probe_read), \
+ FN(ktime_get_ns), \
+ FN(trace_printk), \
+ FN(get_prandom_u32), \
+ FN(get_smp_processor_id), \
+ FN(skb_store_bytes), \
+ FN(l3_csum_replace), \
+ FN(l4_csum_replace), \
+ FN(tail_call), \
+ FN(clone_redirect), \
+ FN(get_current_pid_tgid), \
+ FN(get_current_uid_gid), \
+ FN(get_current_comm), \
+ FN(get_cgroup_classid), \
+ FN(skb_vlan_push), \
+ FN(skb_vlan_pop), \
+ FN(skb_get_tunnel_key), \
+ FN(skb_set_tunnel_key), \
+ FN(perf_event_read), \
+ FN(redirect), \
+ FN(get_route_realm), \
+ FN(perf_event_output), \
+ FN(skb_load_bytes), \
+ FN(get_stackid), \
+ FN(csum_diff), \
+ FN(skb_get_tunnel_opt), \
+ FN(skb_set_tunnel_opt), \
+ FN(skb_change_proto), \
+ FN(skb_change_type), \
+ FN(skb_under_cgroup), \
+ FN(get_hash_recalc), \
+ FN(get_current_task), \
+ FN(probe_write_user), \
+ FN(current_task_under_cgroup), \
+ FN(skb_change_tail), \
+ FN(skb_pull_data), \
+ FN(csum_update), \
+ FN(set_hash_invalid), \
+
+#endif
+
void
init_bpf_helper_tables () // TODO call before script translation
{
diff --git a/bpf-internal.h b/bpf-internal.h
index 3041bbdf5..82cba2c79 100644
--- a/bpf-internal.h
+++ b/bpf-internal.h
@@ -21,6 +21,17 @@ extern "C" {
#include <linux/bpf.h>
}
+/* PR23829: These eBPF opcodes were added in recent kernels, and the
+ following 'ad hoc' defines are only used by the embedded-code
+ assembler. The code generator will convert these opcodes to
+ equivalent operations valid for earlier eBPF. */
+#ifndef BPF_JLT
+#define BPF_JLT 0xa0 /* LT is unsigned, '<' */
+#define BPF_JLE 0xb0 /* LE is unsigned, '<=' */
+#define BPF_JSLT 0xc0 /* SLT is signed, '<' */
+#define BPF_JSLE 0xd0 /* SLE is signed, '<=' */
+#endif
+
struct systemtap_session;
struct derived_probe;
struct vardecl;
--
2.14.5