#define STRERR_BUFSIZE  128
 
-#define CHECK_ERR(action, err, out) do {       \
-       err = action;                   \
-       if (err)                        \
-               goto out;               \
-} while (0)
-
-
 /* Copied from tools/perf/util/util.h */
 #ifndef zfree
 # define zfree(ptr) ({ free(*ptr); *ptr = NULL; })
        def->value_size = data->d_size;
        def->max_entries = 1;
        def->map_flags = type == LIBBPF_MAP_RODATA ? BPF_F_RDONLY_PROG : 0;
-       if (obj->caps.array_mmap)
-               def->map_flags |= BPF_F_MMAPABLE;
+       def->map_flags |= BPF_F_MMAPABLE;
 
        pr_debug("map '%s' (global data): at sec_idx %d, offset %zu, flags %x.\n",
                 map_name, map->sec_idx, map->sec_offset, def->map_flags);
 {
        int err;
 
-       if (!obj->caps.global_data)
-               return 0;
        /*
         * Populate obj->maps with libbpf internal maps.
         */
        return 0;
 }
 
-static int bpf_object__init_maps(struct bpf_object *obj, bool relaxed_maps,
-                                const char *pin_root_path)
+static int bpf_object__init_maps(struct bpf_object *obj,
+                                struct bpf_object_open_opts *opts)
 {
-       bool strict = !relaxed_maps;
+       const char *pin_root_path = OPTS_GET(opts, pin_root_path, NULL);
+       bool strict = !OPTS_GET(opts, relaxed_maps, false);
        int err;
 
        err = bpf_object__init_user_maps(obj, strict);
        return 0;
 }
 
-static int bpf_object__elf_collect(struct bpf_object *obj, bool relaxed_maps,
-                                  const char *pin_root_path)
+static int bpf_object__elf_collect(struct bpf_object *obj)
 {
        Elf *elf = obj->efile.elf;
        GElf_Ehdr *ep = &obj->efile.ehdr;
                pr_warn("Corrupted ELF file: index of strtab invalid\n");
                return -LIBBPF_ERRNO__FORMAT;
        }
-       err = bpf_object__init_btf(obj, btf_data, btf_ext_data);
-       if (!err)
-               err = bpf_object__init_maps(obj, relaxed_maps, pin_root_path);
-       if (!err)
-               err = bpf_object__sanitize_and_load_btf(obj);
-       if (!err)
-               err = bpf_object__init_prog_names(obj);
-       return err;
+       return bpf_object__init_btf(obj, btf_data, btf_ext_data);
 }
 
 static struct bpf_program *
                pr_warn("bad data relo against section %u\n", shdr_idx);
                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);
-               return -LIBBPF_ERRNO__RELOC;
-       }
        for (map_idx = 0; map_idx < nr_maps; map_idx++) {
                map = &obj->maps[map_idx];
                if (map->libbpf_type != type)
 __bpf_object__open(const char *path, const void *obj_buf, size_t obj_buf_sz,
                   struct bpf_object_open_opts *opts)
 {
-       const char *pin_root_path;
        struct bpf_program *prog;
        struct bpf_object *obj;
        const char *obj_name;
        char tmp_name[64];
-       bool relaxed_maps;
        __u32 attach_prog_fd;
        int err;
 
                return obj;
 
        obj->relaxed_core_relocs = OPTS_GET(opts, relaxed_core_relocs, false);
-       relaxed_maps = OPTS_GET(opts, relaxed_maps, false);
-       pin_root_path = OPTS_GET(opts, pin_root_path, NULL);
        attach_prog_fd = OPTS_GET(opts, attach_prog_fd, 0);
 
-       CHECK_ERR(bpf_object__elf_init(obj), err, out);
-       CHECK_ERR(bpf_object__check_endianness(obj), err, out);
-       CHECK_ERR(bpf_object__probe_caps(obj), err, out);
-       CHECK_ERR(bpf_object__elf_collect(obj, relaxed_maps, pin_root_path),
-                 err, out);
-       CHECK_ERR(bpf_object__collect_reloc(obj), err, out);
+       err = bpf_object__elf_init(obj);
+       err = err ? : bpf_object__check_endianness(obj);
+       err = err ? : bpf_object__elf_collect(obj);
+       err = err ? : bpf_object__init_maps(obj, opts);
+       err = err ? : bpf_object__init_prog_names(obj);
+       err = err ? : bpf_object__collect_reloc(obj);
+       if (err)
+               goto out;
        bpf_object__elf_finish(obj);
 
        bpf_object__for_each_program(prog, obj) {
        return 0;
 }
 
+static int bpf_object__sanitize_maps(struct bpf_object *obj)
+{
+       struct bpf_map *m;
+
+       bpf_object__for_each_map(m, obj) {
+               if (!bpf_map__is_internal(m))
+                       continue;
+               if (!obj->caps.global_data) {
+                       pr_warn("kernel doesn't support global data\n");
+                       return -ENOTSUP;
+               }
+               if (!obj->caps.array_mmap)
+                       m->def.map_flags ^= BPF_F_MMAPABLE;
+       }
+
+       return 0;
+}
+
 int bpf_object__load_xattr(struct bpf_object_load_attr *attr)
 {
        struct bpf_object *obj;
 
        obj->loaded = true;
 
-       CHECK_ERR(bpf_object__create_maps(obj), err, out);
-       CHECK_ERR(bpf_object__relocate(obj, attr->target_btf_path), err, out);
-       CHECK_ERR(bpf_object__load_progs(obj, attr->log_level), err, out);
+       err = bpf_object__probe_caps(obj);
+       err = err ? : bpf_object__sanitize_and_load_btf(obj);
+       err = err ? : bpf_object__sanitize_maps(obj);
+       err = err ? : bpf_object__create_maps(obj);
+       err = err ? : bpf_object__relocate(obj, attr->target_btf_path);
+       err = err ? : bpf_object__load_progs(obj, attr->log_level);
+       if (err)
+               goto out;
 
        return 0;
 out: