static int elf_sec_hdr(const struct bpf_object *obj, Elf_Scn *scn, GElf_Shdr *hdr);
 static const char *elf_sec_name(const struct bpf_object *obj, Elf_Scn *scn);
 static Elf_Data *elf_sec_data(const struct bpf_object *obj, Elf_Scn *scn);
-static int elf_sym_by_sec_off(const struct bpf_object *obj, size_t sec_idx,
-                             size_t off, __u32 sym_type, GElf_Sym *sym);
 
 void bpf_program__unload(struct bpf_program *prog)
 {
 bpf_object__add_programs(struct bpf_object *obj, Elf_Data *sec_data,
                         const char *sec_name, int sec_idx)
 {
+       Elf_Data *symbols = obj->efile.symbols;
        struct bpf_program *prog, *progs;
        void *data = sec_data->d_buf;
-       size_t sec_sz = sec_data->d_size, sec_off, prog_sz;
-       int nr_progs, err;
+       size_t sec_sz = sec_data->d_size, sec_off, prog_sz, nr_syms;
+       int nr_progs, err, i;
        const char *name;
        GElf_Sym sym;
 
        progs = obj->programs;
        nr_progs = obj->nr_programs;
+       nr_syms = symbols->d_size / sizeof(GElf_Sym);
        sec_off = 0;
 
-       while (sec_off < sec_sz) {
-               if (elf_sym_by_sec_off(obj, sec_idx, sec_off, STT_FUNC, &sym)) {
-                       pr_warn("sec '%s': failed to find program symbol at offset %zu\n",
-                               sec_name, sec_off);
-                       return -LIBBPF_ERRNO__FORMAT;
-               }
+       for (i = 0; i < nr_syms; i++) {
+               if (!gelf_getsym(symbols, i, &sym))
+                       continue;
+               if (sym.st_shndx != sec_idx)
+                       continue;
+               if (GELF_ST_TYPE(sym.st_info) != STT_FUNC)
+                       continue;
 
                prog_sz = sym.st_size;
+               sec_off = sym.st_value;
 
                name = elf_sym_str(obj, sym.st_name);
                if (!name) {
 
                nr_progs++;
                obj->nr_programs = nr_progs;
-
-               sec_off += prog_sz;
        }
 
        return 0;
        return data;
 }
 
-static int elf_sym_by_sec_off(const struct bpf_object *obj, size_t sec_idx,
-                             size_t off, __u32 sym_type, GElf_Sym *sym)
-{
-       Elf_Data *symbols = obj->efile.symbols;
-       size_t n = symbols->d_size / sizeof(GElf_Sym);
-       int i;
-
-       for (i = 0; i < n; i++) {
-               if (!gelf_getsym(symbols, i, sym))
-                       continue;
-               if (sym->st_shndx != sec_idx || sym->st_value != off)
-                       continue;
-               if (GELF_ST_TYPE(sym->st_info) != sym_type)
-                       continue;
-               return 0;
-       }
-
-       return -ENOENT;
-}
-
 static bool is_sec_name_dwarf(const char *name)
 {
        /* approximation, but the actual list is too long */
        int err, i, nrels;
        const char *sym_name;
        __u32 insn_idx;
+       Elf_Scn *scn;
+       Elf_Data *scn_data;
        GElf_Sym sym;
        GElf_Rel rel;
 
+       scn = elf_sec_by_idx(obj, sec_idx);
+       scn_data = elf_sec_data(obj, scn);
+
        relo_sec_name = elf_sec_str(obj, shdr->sh_name);
-       sec_name = elf_sec_name(obj, elf_sec_by_idx(obj, sec_idx));
+       sec_name = elf_sec_name(obj, scn);
        if (!relo_sec_name || !sec_name)
                return -EINVAL;
 
                                relo_sec_name, (size_t)GELF_R_SYM(rel.r_info), i);
                        return -LIBBPF_ERRNO__FORMAT;
                }
-               if (rel.r_offset % BPF_INSN_SZ) {
+
+               if (rel.r_offset % BPF_INSN_SZ || rel.r_offset >= scn_data->d_size) {
                        pr_warn("sec '%s': invalid offset 0x%zx for relo #%d\n",
                                relo_sec_name, (size_t)GELF_R_SYM(rel.r_info), i);
                        return -LIBBPF_ERRNO__FORMAT;
 
                prog = find_prog_by_sec_insn(obj, sec_idx, insn_idx);
                if (!prog) {
-                       pr_warn("sec '%s': relo #%d: program not found in section '%s' for insn #%u\n",
+                       pr_debug("sec '%s': relo #%d: couldn't find program in section '%s' for insn #%u, probably overridden weak function, skipping...\n",
                                relo_sec_name, i, sec_name, insn_idx);
-                       return -LIBBPF_ERRNO__RELOC;
+                       continue;
                }
 
                relos = libbpf_reallocarray(prog->reloc_desc,