}
 
 static int dso__load_sym(struct dso *self, struct map *map, const char *name,
-                        int fd, symbol_filter_t filter, int kmodule)
+                        int fd, symbol_filter_t filter, int kmodule,
+                        int want_symtab)
 {
        struct kmap *kmap = self->kernel ? map__kmap(map) : NULL;
        struct map *curr_map = map;
                goto out_elf_end;
        }
 
+       /* Always reject images with a mismatched build-id: */
        if (self->has_build_id) {
                u8 build_id[BUILD_ID_SIZE];
 
 
        sec = elf_section_by_name(elf, &ehdr, &shdr, ".symtab", NULL);
        if (sec == NULL) {
+               if (want_symtab)
+                       goto out_elf_end;
+
                sec = elf_section_by_name(elf, &ehdr, &shdr, ".dynsym", NULL);
                if (sec == NULL)
                        goto out_elf_end;
        int fd;
        struct machine *machine;
        const char *root_dir;
+       int want_symtab;
 
        dso__set_loaded(self, map->type);
 
                return ret;
        }
 
-       self->origin = DSO__ORIG_BUILD_ID_CACHE;
-       if (dso__build_id_filename(self, name, size) != NULL)
-               goto open_file;
-more:
-       do {
-               self->origin++;
+       /* Iterate over candidate debug images.
+        * On the first pass, only load images if they have a full symtab.
+        * Failing that, do a second pass where we accept .dynsym also
+        */
+       for (self->origin = DSO__ORIG_BUILD_ID_CACHE, want_symtab = 1;
+            self->origin != DSO__ORIG_NOT_FOUND;
+            self->origin++) {
                switch (self->origin) {
+               case DSO__ORIG_BUILD_ID_CACHE:
+                       if (dso__build_id_filename(self, name, size) == NULL)
+                               continue;
+                       break;
                case DSO__ORIG_FEDORA:
                        snprintf(name, size, "/usr/lib/debug%s.debug",
                                 self->long_name);
                        snprintf(name, size, "/usr/lib/debug%s",
                                 self->long_name);
                        break;
-               case DSO__ORIG_BUILDID:
-                       if (self->has_build_id) {
-                               char build_id_hex[BUILD_ID_SIZE * 2 + 1];
-                               build_id__sprintf(self->build_id,
-                                                 sizeof(self->build_id),
-                                                 build_id_hex);
-                               snprintf(name, size,
-                                        "/usr/lib/debug/.build-id/%.2s/%s.debug",
-                                       build_id_hex, build_id_hex + 2);
-                               break;
+               case DSO__ORIG_BUILDID: {
+                       char build_id_hex[BUILD_ID_SIZE * 2 + 1];
+
+                       if (!self->has_build_id)
+                               continue;
+
+                       build_id__sprintf(self->build_id,
+                                         sizeof(self->build_id),
+                                         build_id_hex);
+                       snprintf(name, size,
+                                "/usr/lib/debug/.build-id/%.2s/%s.debug",
+                                build_id_hex, build_id_hex + 2);
                        }
-                       self->origin++;
-                       /* Fall thru */
+                       break;
                case DSO__ORIG_DSO:
                        snprintf(name, size, "%s", self->long_name);
                        break;
                        break;
 
                default:
-                       goto out;
+                       /*
+                        * If we wanted a full symtab but no image had one,
+                        * relax our requirements and repeat the search.
+                        */
+                       if (want_symtab) {
+                               want_symtab = 0;
+                               self->origin = DSO__ORIG_BUILD_ID_CACHE;
+                       } else
+                               continue;
                }
-open_file:
+
+               /* Name is now the name of the next image to try */
                fd = open(name, O_RDONLY);
-       } while (fd < 0);
+               if (fd < 0)
+                       continue;
 
-       ret = dso__load_sym(self, map, name, fd, filter, 0);
-       close(fd);
+               ret = dso__load_sym(self, map, name, fd, filter, 0,
+                                   want_symtab);
+               close(fd);
 
-       /*
-        * Some people seem to have debuginfo files _WITHOUT_ debug info!?!?
-        */
-       if (!ret)
-               goto more;
+               /*
+                * Some people seem to have debuginfo files _WITHOUT_ debug
+                * info!?!?
+                */
+               if (!ret)
+                       continue;
 
-       if (ret > 0) {
-               int nr_plt = dso__synthesize_plt_symbols(self, map, filter);
-               if (nr_plt > 0)
-                       ret += nr_plt;
+               if (ret > 0) {
+                       int nr_plt = dso__synthesize_plt_symbols(self, map, filter);
+                       if (nr_plt > 0)
+                               ret += nr_plt;
+                       break;
+               }
        }
-out:
+
        free(name);
        if (ret < 0 && strstr(self->name, " (deleted)") != NULL)
                return 0;
                return -1;
 
        dso__set_loaded(self, map->type);
-       err = dso__load_sym(self, map, vmlinux, fd, filter, 0);
+       err = dso__load_sym(self, map, vmlinux, fd, filter, 0, 0);
        close(fd);
 
        if (err > 0)