diff --git a/libtcc.c b/libtcc.c
index 59f846cd..f446cdf8 100644
--- a/libtcc.c
+++ b/libtcc.c
@@ -957,11 +957,29 @@ LIBTCCAPI int tcc_add_sysinclude_path(TCCState *s, const char *pathname)
     return 0;
 }
 
-ST_FUNC DLLReference *tcc_add_dllref(TCCState *s1, const char *dllname)
+/* add/update a 'DLLReference', Just find if level == -1  */
+ST_FUNC DLLReference *tcc_add_dllref(TCCState *s1, const char *dllname, int level)
 {
-    DLLReference *ref = tcc_mallocz(sizeof(DLLReference) + strlen(dllname));
+    DLLReference *ref = NULL;
+    int i;
+    for (i = 0; i < s1->nb_loaded_dlls; i++)
+        if (0 == strcmp(s1->loaded_dlls[i]->name, dllname)) {
+            ref = s1->loaded_dlls[i];
+            break;
+        }
+    if (level == -1)
+        return ref;
+    if (ref) {
+        if (level < ref->level)
+            ref->level = level;
+        ref->found = 1;
+        return ref;
+    }
+    ref = tcc_mallocz(sizeof(DLLReference) + strlen(dllname));
     strcpy(ref->name, dllname);
     dynarray_add(&s1->loaded_dlls, &s1->nb_loaded_dlls, ref);
+    ref->level = level;
+    ref->index = s1->nb_loaded_dlls;
     return ref;
 }
 
@@ -1042,7 +1060,7 @@ ST_FUNC int tcc_add_file_internal(TCCState *s1, const char *filename, int flags)
                     soname = macho_tbd_soname(filename);
                 dl = dlopen(soname, RTLD_GLOBAL | RTLD_LAZY);
                 if (dl)
-                    tcc_add_dllref(s1, soname)->handle = dl, ret = 0;
+                    tcc_add_dllref(s1, soname, 0)->handle = dl, ret = 0;
 	        if (filename != soname)
 		    tcc_free((void *)soname);
 #endif
@@ -1070,7 +1088,7 @@ ST_FUNC int tcc_add_file_internal(TCCState *s1, const char *filename, int flags)
 #ifdef TCC_IS_NATIVE
                 void* dl = dlopen(filename, RTLD_GLOBAL | RTLD_LAZY);
                 if (dl)
-                    tcc_add_dllref(s1, filename)->handle = dl, ret = 0;
+                    tcc_add_dllref(s1, filename, 0)->handle = dl, ret = 0;
 #endif
             } else
                 ret = tcc_load_dll(s1, fd, filename, (flags & AFF_REFERENCED_DLL) != 0);
diff --git a/tcc.h b/tcc.h
index d4708bbd..67218089 100644
--- a/tcc.h
+++ b/tcc.h
@@ -609,6 +609,7 @@ typedef struct Section {
 typedef struct DLLReference {
     int level;
     void *handle;
+    unsigned char found, index;
     char name[1];
 } DLLReference;
 
@@ -1279,7 +1280,7 @@ PUB_FUNC int tcc_parse_args(TCCState *s, int *argc, char ***argv, int optind);
 #ifdef _WIN32
 ST_FUNC char *normalize_slashes(char *path);
 #endif
-ST_FUNC DLLReference *tcc_add_dllref(TCCState *s1, const char *dllname);
+ST_FUNC DLLReference *tcc_add_dllref(TCCState *s1, const char *dllname, int level);
 ST_FUNC char *tcc_load_text(int fd);
 
 /* tcc_parse_args return codes: */
diff --git a/tccelf.c b/tccelf.c
index 078e98d7..a72d0466 100644
--- a/tccelf.c
+++ b/tccelf.c
@@ -547,7 +547,7 @@ LIBTCCAPI void tcc_list_symbols(TCCState *s, void *ctx,
 static void
 version_add (TCCState *s1)
 {
-    int i, j;
+    int i;
     ElfW(Sym) *sym;
     ElfW(Verneed) *vn = NULL;
     Section *symtab;
@@ -594,14 +594,8 @@ version_add (TCCState *s1)
             ElfW(Vernaux) *vna = 0;
             if (sv->out_index < 1)
               continue;
-	    /* If present in verneed it should be in DT_NEEDED */
-	    for (j = 0; j < s1->nb_loaded_dlls; j++) {
-		DLLReference *dllref = s1->loaded_dlls[j];
-		if (!strcmp(sv->lib, dllref->name)) {
-		    dllref->level = 0;
-		    break;
-		}
-	    }
+            /* make sure that a DT_NEEDED tag is put */
+            tcc_add_dllref(s1, sv->lib, 0);
             vnofs = section_add(verneed_section, sizeof(*vn), 1);
             vn = (ElfW(Verneed)*)(verneed_section->data + vnofs);
             vn->vn_version = 1;
@@ -3425,14 +3419,13 @@ ST_FUNC int tcc_load_dll(TCCState *s1, int fd, const char *filename, int level)
 {
     ElfW(Ehdr) ehdr;
     ElfW(Shdr) *shdr, *sh, *sh1;
-    int i, j, nb_syms, nb_dts, sym_bind, ret;
+    int i, nb_syms, nb_dts, sym_bind, ret = -1;
     ElfW(Sym) *sym, *dynsym;
     ElfW(Dyn) *dt, *dynamic;
 
     char *dynstr;
     int sym_index;
     const char *name, *soname;
-    DLLReference *dllref;
     struct versym_info v;
 
     full_read(fd, &ehdr, sizeof(ehdr));
@@ -3482,37 +3475,24 @@ ST_FUNC int tcc_load_dll(TCCState *s1, int fd, const char *filename, int level)
         }
     }
 
+    if (!dynamic)
+        goto the_end;
+
     /* compute the real library name */
     soname = tcc_basename(filename);
-
-    for(i = 0, dt = dynamic; i < nb_dts; i++, dt++) {
-        if (dt->d_tag == DT_SONAME) {
+    for(i = 0, dt = dynamic; i < nb_dts; i++, dt++)
+        if (dt->d_tag == DT_SONAME)
             soname = dynstr + dt->d_un.d_val;
-        } else if (dt->d_tag == DT_RPATH) {
-            tcc_add_library_path(s1, dynstr + dt->d_un.d_val);
-        }
-    }
 
     /* if the dll is already loaded, do not load it */
-    for(i = 0; i < s1->nb_loaded_dlls; i++) {
-        dllref = s1->loaded_dlls[i];
-        if (!strcmp(soname, dllref->name)) {
-            /* but update level if needed */
-            if (level < dllref->level)
-                dllref->level = level;
-            ret = 0;
-            goto the_end;
-        }
-    }
+    if (tcc_add_dllref(s1, soname, level)->found)
+        goto ret_success;
 
     if (v.nb_versyms != nb_syms)
         tcc_free (v.versym), v.versym = NULL;
     else
         store_version(s1, &v, dynstr);
 
-    /* add the dll and its level */
-    tcc_add_dllref(s1, soname)->level = level;
-
     /* add dynamic symbols in dynsym_section */
     for(i = 1, sym = dynsym + 1; i < nb_syms; i++, sym++) {
         sym_bind = ELFW(ST_BIND)(sym->st_info);
@@ -3528,25 +3508,25 @@ ST_FUNC int tcc_load_dll(TCCState *s1, int fd, const char *filename, int level)
         }
     }
 
+    for(i = 0, dt = dynamic; i < nb_dts; i++, dt++)
+        if (dt->d_tag == DT_RPATH)
+            tcc_add_library_path(s1, dynstr + dt->d_un.d_val);
+
     /* load all referenced DLLs */
     for(i = 0, dt = dynamic; i < nb_dts; i++, dt++) {
         switch(dt->d_tag) {
         case DT_NEEDED:
             name = dynstr + dt->d_un.d_val;
-            for(j = 0; j < s1->nb_loaded_dlls; j++) {
-                dllref = s1->loaded_dlls[j];
-                if (!strcmp(name, dllref->name))
-                    goto already_loaded;
-            }
+            if (tcc_add_dllref(s1, name, -1))
+                continue;
             if (tcc_add_dll(s1, name, AFF_REFERENCED_DLL) < 0) {
                 tcc_error_noabort("referenced dll '%s' not found", name);
-                ret = -1;
                 goto the_end;
             }
-        already_loaded:
-            break;
         }
     }
+
+ ret_success:
     ret = 0;
  the_end:
     tcc_free(dynstr);
diff --git a/tccmacho.c b/tccmacho.c
index 8e86b75f..f9048ea3 100644
--- a/tccmacho.c
+++ b/tccmacho.c
@@ -835,25 +835,6 @@ static uint32_t macho_swap32(uint32_t x)
   return (x >> 24) | (x << 24) | ((x >> 8) & 0xff00) | ((x & 0xff00) << 8);
 }
 #define SWAP(x) (swap ? macho_swap32(x) : (x))
-
-ST_FUNC int macho_add_dllref(TCCState* s1, int lev, const char* soname)
-{
-     /* if the dll is already loaded, do not load it */
-    DLLReference *dllref;
-    int i;
-    for(i = 0; i < s1->nb_loaded_dlls; i++) {
-        dllref = s1->loaded_dlls[i];
-        if (!strcmp(soname, dllref->name)) {
-            /* but update level if needed */
-            if (lev < dllref->level)
-                dllref->level = lev;
-            return -1;
-        }
-    }
-    tcc_add_dllref(s1, soname)->level = lev;
-    return 0;
-}
-
 #define tbd_parse_movepast(s) \
     (pos = (pos = strstr(pos, s)) ? pos + strlen(s) : NULL)
 #define tbd_parse_movetoany(cs) (pos = strpbrk(pos, cs))
@@ -925,7 +906,8 @@ ST_FUNC int macho_load_tbd(TCCState* s1, int fd, const char* filename, int lev)
     if (!tbd_parse_movetoany("\n \"'")) goto the_end;
     tbd_parse_trample;
     ret = 0;
-    if (macho_add_dllref(s1, lev, soname) != 0) goto the_end;
+    if (tcc_add_dllref(s1, soname, lev)->found)
+        goto the_end;
     while(pos) {
         char* sym = NULL;
         int cont = 1;
@@ -1047,7 +1029,7 @@ ST_FUNC int macho_load_dll(TCCState * s1, int fd, const char* filename, int lev)
         lc = (struct load_command*) ((char*)lc + lc->cmdsize);
     }
 
-    if (0 != macho_add_dllref(s1, lev, soname))
+    if (tcc_add_dllref(s1, soname, lev)->found)
         goto the_end;
 
     if (!nsyms || !nextdef)
diff --git a/tccpe.c b/tccpe.c
index 07501a96..f70c8b99 100644
--- a/tccpe.c
+++ b/tccpe.c
@@ -1533,16 +1533,6 @@ ST_FUNC int pe_putimport(TCCState *s1, int dllindex, const char *name, addr_t va
         );
 }
 
-static int pe_add_dllref(TCCState *s1, const char *dllname)
-{
-    int i;
-    for (i = 0; i < s1->nb_loaded_dlls; ++i)
-        if (0 == strcmp(s1->loaded_dlls[i]->name, dllname))
-            return i + 1;
-    tcc_add_dllref(s1, dllname);
-    return s1->nb_loaded_dlls;
-}
-
 static int read_mem(int fd, unsigned offset, void *buffer, unsigned len)
 {
     lseek(fd, offset, SEEK_SET);
@@ -1732,7 +1722,7 @@ static int pe_load_def(TCCState *s1, int fd)
             ++state;
             break;
         case 2:
-            dllindex = pe_add_dllref(s1, dllname);
+            dllindex = tcc_add_dllref(s1, dllname, 0)->index;
             ++state;
             /* fall through */
         default:
@@ -1769,7 +1759,7 @@ static int pe_load_dll(TCCState *s1, int fd, const char *filename)
     if (ret) {
         return -1;
     } else if (p) {
-        index = pe_add_dllref(s1, filename);
+        index = tcc_add_dllref(s1, filename, 0)->index;
         for (q = p; *q; q += 1 + strlen(q))
             pe_putimport(s1, index, q, 0);
         tcc_free(p);