break;
 
                case STT_SECTION:
-                       func = find_symbol_by_offset(rela->sym->sec, rela->addend);
-                       if (!func || func->type != STT_FUNC)
+                       func = find_func_by_offset(rela->sym->sec, rela->addend);
+                       if (!func)
                                continue;
                        break;
 
                                               insn->len);
                if (!rela) {
                        dest_off = insn->offset + insn->len + insn->immediate;
-                       insn->call_dest = find_symbol_by_offset(insn->sec,
-                                                               dest_off);
+                       insn->call_dest = find_func_by_offset(insn->sec, dest_off);
+                       if (!insn->call_dest)
+                               insn->call_dest = find_symbol_by_offset(insn->sec, dest_off);
 
-                       if (!insn->call_dest && !insn->ignore) {
+                       if (insn->ignore)
+                               continue;
+
+                       if (!insn->call_dest) {
                                WARN_FUNC("unsupported intra-function call",
                                          insn->sec, insn->offset);
                                if (retpoline)
                                return -1;
                        }
 
+                       if (insn->func && insn->call_dest->type != STT_FUNC) {
+                               WARN_FUNC("unsupported call to non-function",
+                                         insn->sec, insn->offset);
+                               return -1;
+                       }
+
                } else if (rela->sym->type == STT_SECTION) {
-                       insn->call_dest = find_symbol_by_offset(rela->sym->sec,
-                                                               rela->addend+4);
-                       if (!insn->call_dest ||
-                           insn->call_dest->type != STT_FUNC) {
+                       insn->call_dest = find_func_by_offset(rela->sym->sec,
+                                                             rela->addend+4);
+                       if (!insn->call_dest) {
                                WARN_FUNC("can't find call dest symbol at %s+0x%x",
                                          insn->sec, insn->offset,
                                          rela->sym->sec->name,
 
        struct symbol *sym;
 
        list_for_each_entry(sym, &sec->symbol_list, list)
-               if (sym->type != STT_SECTION &&
-                   sym->offset == offset)
+               if (sym->type != STT_SECTION && sym->offset == offset)
+                       return sym;
+
+       return NULL;
+}
+
+struct symbol *find_func_by_offset(struct section *sec, unsigned long offset)
+{
+       struct symbol *sym;
+
+       list_for_each_entry(sym, &sec->symbol_list, list)
+               if (sym->type == STT_FUNC && sym->offset == offset)
                        return sym;
 
        return NULL;
 
 
 struct elf *elf_read(const char *name, int flags);
 struct section *find_section_by_name(struct elf *elf, const char *name);
+struct symbol *find_func_by_offset(struct section *sec, unsigned long offset);
 struct symbol *find_symbol_by_offset(struct section *sec, unsigned long offset);
 struct symbol *find_symbol_by_name(struct elf *elf, const char *name);
 struct symbol *find_symbol_containing(struct section *sec, unsigned long offset);