return sys_bpf(BPF_ENABLE_STATS, &attr, sizeof(attr));
 }
+
+int bpf_prog_bind_map(int prog_fd, int map_fd,
+                     const struct bpf_prog_bind_opts *opts)
+{
+       union bpf_attr attr;
+
+       if (!OPTS_VALID(opts, bpf_prog_bind_opts))
+               return -EINVAL;
+
+       memset(&attr, 0, sizeof(attr));
+       attr.prog_bind_map.prog_fd = prog_fd;
+       attr.prog_bind_map.map_fd = map_fd;
+       attr.prog_bind_map.flags = OPTS_GET(opts, flags, 0);
+
+       return sys_bpf(BPF_PROG_BIND_MAP, &attr, sizeof(attr));
+}
 
        FEAT_EXP_ATTACH_TYPE,
        /* bpf_probe_read_{kernel,user}[_str] helpers */
        FEAT_PROBE_READ_KERN,
+       /* BPF_PROG_BIND_MAP is supported */
+       FEAT_PROG_BIND_MAP,
        __FEAT_CNT,
 };
 
        struct extern_desc *externs;
        int nr_extern;
        int kconfig_map_idx;
+       int rodata_map_idx;
 
        bool loaded;
        bool has_subcalls;
        obj->efile.bss_shndx = -1;
        obj->efile.st_ops_shndx = -1;
        obj->kconfig_map_idx = -1;
+       obj->rodata_map_idx = -1;
 
        obj->kern_version = get_kernel_version();
        obj->loaded = false;
                                                    obj->efile.rodata->d_size);
                if (err)
                        return err;
+
+               obj->rodata_map_idx = obj->nr_maps - 1;
        }
        if (obj->efile.bss_shndx >= 0) {
                err = bpf_object__init_internal_map(obj, LIBBPF_MAP_BSS,
        return probe_fd(bpf_load_program_xattr(&attr, NULL, 0));
 }
 
+static int probe_prog_bind_map(void)
+{
+       struct bpf_load_program_attr prg_attr;
+       struct bpf_create_map_attr map_attr;
+       char *cp, errmsg[STRERR_BUFSIZE];
+       struct bpf_insn insns[] = {
+               BPF_MOV64_IMM(BPF_REG_0, 0),
+               BPF_EXIT_INSN(),
+       };
+       int ret, map, prog;
+
+       memset(&map_attr, 0, sizeof(map_attr));
+       map_attr.map_type = BPF_MAP_TYPE_ARRAY;
+       map_attr.key_size = sizeof(int);
+       map_attr.value_size = 32;
+       map_attr.max_entries = 1;
+
+       map = bpf_create_map_xattr(&map_attr);
+       if (map < 0) {
+               ret = -errno;
+               cp = libbpf_strerror_r(ret, errmsg, sizeof(errmsg));
+               pr_warn("Error in %s():%s(%d). Couldn't create simple array map.\n",
+                       __func__, cp, -ret);
+               return ret;
+       }
+
+       memset(&prg_attr, 0, sizeof(prg_attr));
+       prg_attr.prog_type = BPF_PROG_TYPE_SOCKET_FILTER;
+       prg_attr.insns = insns;
+       prg_attr.insns_cnt = ARRAY_SIZE(insns);
+       prg_attr.license = "GPL";
+
+       prog = bpf_load_program_xattr(&prg_attr, NULL, 0);
+       if (prog < 0) {
+               close(map);
+               return 0;
+       }
+
+       ret = bpf_prog_bind_map(prog, map, NULL);
+
+       close(map);
+       close(prog);
+
+       return ret >= 0;
+}
+
 enum kern_feature_result {
        FEAT_UNKNOWN = 0,
        FEAT_SUPPORTED = 1,
        },
        [FEAT_PROBE_READ_KERN] = {
                "bpf_probe_read_kernel() helper", probe_kern_probe_read_kernel,
+       },
+       [FEAT_PROG_BIND_MAP] = {
+               "BPF_PROG_BIND_MAP support", probe_prog_bind_map,
        }
 };
 
        if (ret >= 0) {
                if (log_buf && load_attr.log_level)
                        pr_debug("verifier log:\n%s", log_buf);
+
+               if (prog->obj->rodata_map_idx >= 0 &&
+                   kernel_supports(FEAT_PROG_BIND_MAP)) {
+                       struct bpf_map *rodata_map =
+                               &prog->obj->maps[prog->obj->rodata_map_idx];
+
+                       if (bpf_prog_bind_map(ret, bpf_map__fd(rodata_map), NULL)) {
+                               cp = libbpf_strerror_r(errno, errmsg, sizeof(errmsg));
+                               pr_warn("prog '%s': failed to bind .rodata map: %s\n",
+                                       prog->name, cp);
+                               /* Don't fail hard if can't bind rodata. */
+                       }
+               }
+
                *pfd = ret;
                ret = 0;
                goto out;