This patch utilizes bpf_object__load() provided by libbpf to load all
objects into kernel.
Committer notes:
Testing it:
When using an incorrect kernel version number, i.e., having this in your
eBPF proggie:
  int _version __attribute__((section("version"), used)) = 0x40100;
For a 4.3.0-rc6+ kernel, say, this happens and needs checking at event
parsing time, to provide a better error report to the user:
  # perf record --event /tmp/foo.o sleep 1
  libbpf: load bpf program failed: Invalid argument
  libbpf: -- BEGIN DUMP LOG ---
  libbpf:
  libbpf: -- END LOG --
  libbpf: failed to load program 'fork=_do_fork'
  libbpf: failed to load object '/tmp/foo.o'
  event syntax error: '/tmp/foo.o'
                       \___ Invalid argument: Are you root and runing a CONFIG_BPF_SYSCALL kernel?
  (add -v to see detail)
  Run 'perf list' for a list of valid events
   Usage: perf record [<options>] [<command>]
      or: perf record [<options>] -- <command> [<options>]
      -e, --event <event>   event selector. use 'perf list' to list available events
If we instead make it match, i.e. use 0x40300 on this v4.3.0-rc6+
kernel, the whole process goes thru:
  # perf record --event /tmp/foo.o -a usleep 1
  [ perf record: Woken up 1 times to write data ]
  [ perf record: Captured and wrote 0.202 MB perf.data ]
  # perf evlist -v
  /tmp/foo.o: type: 1, size: 112, config: 0x9, { sample_period,
  sample_freq }: 4000, sample_type: IP|TID|TIME|CPU|PERIOD, disabled: 1,
  inherit: 1, mmap: 1, comm: 1, freq: 1, task: 1, sample_id_all: 1,
  exclude_guest: 1, mmap2: 1, comm_exec: 1
  #
Signed-off-by: Wang Nan <wangnan0@huawei.com>
Tested-by: Arnaldo Carvalho de Melo <acme@redhat.com>
Cc: Alexei Starovoitov <ast@plumgrid.com>
Cc: Brendan Gregg <brendan.d.gregg@gmail.com>
Cc: Daniel Borkmann <daniel@iogearbox.net>
Cc: David Ahern <dsahern@gmail.com>
Cc: He Kuang <hekuang@huawei.com>
Cc: Jiri Olsa <jolsa@kernel.org>
Cc: Kaixu Xia <xiakaixu@huawei.com>
Cc: Masami Hiramatsu <masami.hiramatsu.pt@hitachi.com>
Cc: Namhyung Kim <namhyung@kernel.org>
Cc: Paul Mackerras <paulus@samba.org>
Cc: Peter Zijlstra <a.p.zijlstra@chello.nl>
Cc: Zefan Li <lizefan@huawei.com>
Cc: pi3orama@163.com
Link: http://lkml.kernel.org/r/1444826502-49291-6-git-send-email-wangnan0@huawei.com
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
 
        return ret;
 }
 
+int bpf__load(struct bpf_object *obj)
+{
+       int err;
+
+       err = bpf_object__load(obj);
+       if (err) {
+               pr_debug("bpf: load objects failed\n");
+               return err;
+       }
+       return 0;
+}
+
 #define bpf__strerror_head(err, buf, size) \
        char sbuf[STRERR_BUFSIZE], *emsg;\
        if (!size)\
        bpf__strerror_end(buf, size);
        return 0;
 }
+
+int bpf__strerror_load(struct bpf_object *obj __maybe_unused,
+                      int err, char *buf, size_t size)
+{
+       bpf__strerror_head(err, buf, size);
+       bpf__strerror_entry(EINVAL, "%s: Are you root and runing a CONFIG_BPF_SYSCALL kernel?",
+                           emsg)
+       bpf__strerror_end(buf, size);
+       return 0;
+}
 
 int bpf__strerror_probe(struct bpf_object *obj, int err,
                        char *buf, size_t size);
 
+int bpf__load(struct bpf_object *obj);
+int bpf__strerror_load(struct bpf_object *obj, int err,
+                      char *buf, size_t size);
 #else
 static inline struct bpf_object *
 bpf__prepare_load(const char *filename __maybe_unused)
 
 static inline int bpf__probe(struct bpf_object *obj __maybe_unused) { return 0;}
 static inline int bpf__unprobe(struct bpf_object *obj __maybe_unused) { return 0;}
+static inline int bpf__load(struct bpf_object *obj __maybe_unused) { return 0; }
 
 static inline int
 __bpf_strerror(char *buf, size_t size)
 {
        return __bpf_strerror(buf, size);
 }
+
+static inline int bpf__strerror_load(struct bpf_object *obj __maybe_unused,
+                                    int err __maybe_unused,
+                                    char *buf, size_t size)
+{
+       return __bpf_strerror(buf, size);
+}
 #endif
 #endif
 
                goto errout;
        }
 
+       err = bpf__load(obj);
+       if (err) {
+               bpf__strerror_load(obj, err, errbuf, sizeof(errbuf));
+               goto errout;
+       }
+
        /*
         * Temporary add a dummy event here so we can check whether
         * basic bpf loader works. Following patches will replace