libtcc.c: - integrate find_dllref loop into tcc_add_dllref() tccelf.c: - make sure a DT_NEEDED tag is put for versions even when the dll was not previously loaded. Related commit 4c82b003420fabbb95e077866784badc1a49189b 48 insertions(+), 77 deletions(-)
Unified · Split
| @@ -957,11 +957,29 @@ LIBTCCAPI int tcc_add_sysinclude_path(TCCState *s, const char *pathname) · 956 unmodified lines | ||
| 957 | 957 | return 0; |
| 958 | 958 | } |
| 959 | 959 | |
| 960 | −ST_FUNC DLLReference *tcc_add_dllref(TCCState *s1, const char *dllname) | |
| 960 | +/* add/update a 'DLLReference', Just find if level == -1 */ | |
| 961 | +ST_FUNC DLLReference *tcc_add_dllref(TCCState *s1, const char *dllname, int level) | |
| 961 | 962 | { |
| 962 | − DLLReference *ref = tcc_mallocz(sizeof(DLLReference) + strlen(dllname)); | |
| 963 | + DLLReference *ref = NULL; | |
| 964 | + int i; | |
| 965 | + for (i = 0; i < s1->nb_loaded_dlls; i++) | |
| 966 | + if (0 == strcmp(s1->loaded_dlls[i]->name, dllname)) { | |
| 967 | + ref = s1->loaded_dlls[i]; | |
| 968 | + break; | |
| 969 | + } | |
| 970 | + if (level == -1) | |
| 971 | + return ref; | |
| 972 | + if (ref) { | |
| 973 | + if (level < ref->level) | |
| 974 | + ref->level = level; | |
| 975 | + ref->found = 1; | |
| 976 | + return ref; | |
| 977 | + } | |
| 978 | + ref = tcc_mallocz(sizeof(DLLReference) + strlen(dllname)); | |
| 963 | 979 | strcpy(ref->name, dllname); |
| 964 | 980 | dynarray_add(&s1->loaded_dlls, &s1->nb_loaded_dlls, ref); |
| 981 | + ref->level = level; | |
| 982 | + ref->index = s1->nb_loaded_dlls; | |
| 965 | 983 | return ref; |
| 966 | 984 | } |
| 967 | 985 | |
| @@ -1042,7 +1060,7 @@ ST_FUNC int tcc_add_file_internal(TCCState *s1, const char *filename, int flags) · 74 unmodified lines | ||
| 1042 | 1060 | soname = macho_tbd_soname(filename); |
| 1043 | 1061 | dl = dlopen(soname, RTLD_GLOBAL | RTLD_LAZY); |
| 1044 | 1062 | if (dl) |
| 1045 | − tcc_add_dllref(s1, soname)->handle = dl, ret = 0; | |
| 1063 | + tcc_add_dllref(s1, soname, 0)->handle = dl, ret = 0; | |
| 1046 | 1064 | if (filename != soname) |
| 1047 | 1065 | tcc_free((void *)soname); |
| 1048 | 1066 | #endif |
| @@ -1070,7 +1088,7 @@ ST_FUNC int tcc_add_file_internal(TCCState *s1, const char *filename, int flags) · 21 unmodified lines | ||
| 1070 | 1088 | #ifdef TCC_IS_NATIVE |
| 1071 | 1089 | void* dl = dlopen(filename, RTLD_GLOBAL | RTLD_LAZY); |
| 1072 | 1090 | if (dl) |
| 1073 | − tcc_add_dllref(s1, filename)->handle = dl, ret = 0; | |
| 1091 | + tcc_add_dllref(s1, filename, 0)->handle = dl, ret = 0; | |
| 1074 | 1092 | #endif |
| 1075 | 1093 | } else |
| 1076 | 1094 | ret = tcc_load_dll(s1, fd, filename, (flags & AFF_REFERENCED_DLL) != 0); |
| @@ -609,6 +609,7 @@ typedef struct Section { · 608 unmodified lines | ||
| 609 | 609 | typedef struct DLLReference { |
| 610 | 610 | int level; |
| 611 | 611 | void *handle; |
| 612 | + unsigned char found, index; | |
| 612 | 613 | char name[1]; |
| 613 | 614 | } DLLReference; |
| 614 | 615 | |
| @@ -1279,7 +1280,7 @@ PUB_FUNC int tcc_parse_args(TCCState *s, int *argc, char ***argv, int optind); · 664 unmodified lines | ||
| 1279 | 1280 | #ifdef _WIN32 |
| 1280 | 1281 | ST_FUNC char *normalize_slashes(char *path); |
| 1281 | 1282 | #endif |
| 1282 | −ST_FUNC DLLReference *tcc_add_dllref(TCCState *s1, const char *dllname); | |
| 1283 | +ST_FUNC DLLReference *tcc_add_dllref(TCCState *s1, const char *dllname, int level); | |
| 1283 | 1284 | ST_FUNC char *tcc_load_text(int fd); |
| 1284 | 1285 | |
| 1285 | 1286 | /* tcc_parse_args return codes: */ |
| @@ -547,7 +547,7 @@ LIBTCCAPI void tcc_list_symbols(TCCState *s, void *ctx, · 546 unmodified lines | ||
| 547 | 547 | static void |
| 548 | 548 | version_add (TCCState *s1) |
| 549 | 549 | { |
| 550 | − int i, j; | |
| 550 | + int i; | |
| 551 | 551 | ElfW(Sym) *sym; |
| 552 | 552 | ElfW(Verneed) *vn = NULL; |
| 553 | 553 | Section *symtab; |
| @@ -594,14 +594,8 @@ version_add (TCCState *s1) · 40 unmodified lines | ||
| 594 | 594 | ElfW(Vernaux) *vna = 0; |
| 595 | 595 | if (sv->out_index < 1) |
| 596 | 596 | continue; |
| 597 | − /* If present in verneed it should be in DT_NEEDED */ | |
| 598 | − for (j = 0; j < s1->nb_loaded_dlls; j++) { | |
| 599 | − DLLReference *dllref = s1->loaded_dlls[j]; | |
| 600 | − if (!strcmp(sv->lib, dllref->name)) { | |
| 601 | − dllref->level = 0; | |
| 602 | − break; | |
| 603 | − } | |
| 604 | − } | |
| 597 | + /* make sure that a DT_NEEDED tag is put */ | |
| 598 | + tcc_add_dllref(s1, sv->lib, 0); | |
| 605 | 599 | vnofs = section_add(verneed_section, sizeof(*vn), 1); |
| 606 | 600 | vn = (ElfW(Verneed)*)(verneed_section->data + vnofs); |
| 607 | 601 | vn->vn_version = 1; |
| @@ -3425,14 +3419,13 @@ ST_FUNC int tcc_load_dll(TCCState *s1, int fd, const char *filename, int level) · 2817 unmodified lines | ||
| 3425 | 3419 | { |
| 3426 | 3420 | ElfW(Ehdr) ehdr; |
| 3427 | 3421 | ElfW(Shdr) *shdr, *sh, *sh1; |
| 3428 | − int i, j, nb_syms, nb_dts, sym_bind, ret; | |
| 3422 | + int i, nb_syms, nb_dts, sym_bind, ret = -1; | |
| 3429 | 3423 | ElfW(Sym) *sym, *dynsym; |
| 3430 | 3424 | ElfW(Dyn) *dt, *dynamic; |
| 3431 | 3425 | |
| 3432 | 3426 | char *dynstr; |
| 3433 | 3427 | int sym_index; |
| 3434 | 3428 | const char *name, *soname; |
| 3435 | − DLLReference *dllref; | |
| 3436 | 3429 | struct versym_info v; |
| 3437 | 3430 | |
| 3438 | 3431 | 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) · 43 unmodified lines | ||
| 3482 | 3475 | } |
| 3483 | 3476 | } |
| 3484 | 3477 | |
| 3478 | + if (!dynamic) | |
| 3479 | + goto the_end; | |
| 3480 | + | |
| 3485 | 3481 | /* compute the real library name */ |
| 3486 | 3482 | soname = tcc_basename(filename); |
| 3487 | − | |
| 3488 | − for(i = 0, dt = dynamic; i < nb_dts; i++, dt++) { | |
| 3489 | − if (dt->d_tag == DT_SONAME) { | |
| 3483 | + for(i = 0, dt = dynamic; i < nb_dts; i++, dt++) | |
| 3484 | + if (dt->d_tag == DT_SONAME) | |
| 3490 | 3485 | soname = dynstr + dt->d_un.d_val; |
| 3491 | − } else if (dt->d_tag == DT_RPATH) { | |
| 3492 | − tcc_add_library_path(s1, dynstr + dt->d_un.d_val); | |
| 3493 | − } | |
| 3494 | − } | |
| 3495 | 3486 | |
| 3496 | 3487 | /* if the dll is already loaded, do not load it */ |
| 3497 | − for(i = 0; i < s1->nb_loaded_dlls; i++) { | |
| 3498 | − dllref = s1->loaded_dlls[i]; | |
| 3499 | − if (!strcmp(soname, dllref->name)) { | |
| 3500 | − /* but update level if needed */ | |
| 3501 | − if (level < dllref->level) | |
| 3502 | − dllref->level = level; | |
| 3503 | − ret = 0; | |
| 3504 | − goto the_end; | |
| 3505 | − } | |
| 3506 | − } | |
| 3488 | + if (tcc_add_dllref(s1, soname, level)->found) | |
| 3489 | + goto ret_success; | |
| 3507 | 3490 | |
| 3508 | 3491 | if (v.nb_versyms != nb_syms) |
| 3509 | 3492 | tcc_free (v.versym), v.versym = NULL; |
| 3510 | 3493 | else |
| 3511 | 3494 | store_version(s1, &v, dynstr); |
| 3512 | 3495 | |
| 3513 | − /* add the dll and its level */ | |
| 3514 | − tcc_add_dllref(s1, soname)->level = level; | |
| 3515 | − | |
| 3516 | 3496 | /* add dynamic symbols in dynsym_section */ |
| 3517 | 3497 | for(i = 1, sym = dynsym + 1; i < nb_syms; i++, sym++) { |
| 3518 | 3498 | 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) · 9 unmodified lines | ||
| 3528 | 3508 | } |
| 3529 | 3509 | } |
| 3530 | 3510 | |
| 3511 | + for(i = 0, dt = dynamic; i < nb_dts; i++, dt++) | |
| 3512 | + if (dt->d_tag == DT_RPATH) | |
| 3513 | + tcc_add_library_path(s1, dynstr + dt->d_un.d_val); | |
| 3514 | + | |
| 3531 | 3515 | /* load all referenced DLLs */ |
| 3532 | 3516 | for(i = 0, dt = dynamic; i < nb_dts; i++, dt++) { |
| 3533 | 3517 | switch(dt->d_tag) { |
| 3534 | 3518 | case DT_NEEDED: |
| 3535 | 3519 | name = dynstr + dt->d_un.d_val; |
| 3536 | − for(j = 0; j < s1->nb_loaded_dlls; j++) { | |
| 3537 | − dllref = s1->loaded_dlls[j]; | |
| 3538 | − if (!strcmp(name, dllref->name)) | |
| 3539 | − goto already_loaded; | |
| 3540 | − } | |
| 3520 | + if (tcc_add_dllref(s1, name, -1)) | |
| 3521 | + continue; | |
| 3541 | 3522 | if (tcc_add_dll(s1, name, AFF_REFERENCED_DLL) < 0) { |
| 3542 | 3523 | tcc_error_noabort("referenced dll '%s' not found", name); |
| 3543 | − ret = -1; | |
| 3544 | 3524 | goto the_end; |
| 3545 | 3525 | } |
| 3546 | − already_loaded: | |
| 3547 | − break; | |
| 3548 | 3526 | } |
| 3549 | 3527 | } |
| 3528 | + | |
| 3529 | + ret_success: | |
| 3550 | 3530 | ret = 0; |
| 3551 | 3531 | the_end: |
| 3552 | 3532 | tcc_free(dynstr); |
| @@ -835,25 +835,6 @@ static uint32_t macho_swap32(uint32_t x) · 834 unmodified lines | ||
| 835 | 835 | return (x >> 24) | (x << 24) | ((x >> 8) & 0xff00) | ((x & 0xff00) << 8); |
| 836 | 836 | } |
| 837 | 837 | #define SWAP(x) (swap ? macho_swap32(x) : (x)) |
| 838 | − | |
| 839 | −ST_FUNC int macho_add_dllref(TCCState* s1, int lev, const char* soname) | |
| 840 | −{ | |
| 841 | − /* if the dll is already loaded, do not load it */ | |
| 842 | − DLLReference *dllref; | |
| 843 | − int i; | |
| 844 | − for(i = 0; i < s1->nb_loaded_dlls; i++) { | |
| 845 | − dllref = s1->loaded_dlls[i]; | |
| 846 | − if (!strcmp(soname, dllref->name)) { | |
| 847 | − /* but update level if needed */ | |
| 848 | − if (lev < dllref->level) | |
| 849 | − dllref->level = lev; | |
| 850 | − return -1; | |
| 851 | − } | |
| 852 | − } | |
| 853 | − tcc_add_dllref(s1, soname)->level = lev; | |
| 854 | − return 0; | |
| 855 | −} | |
| 856 | − | |
| 857 | 838 | #define tbd_parse_movepast(s) \ |
| 858 | 839 | (pos = (pos = strstr(pos, s)) ? pos + strlen(s) : NULL) |
| 859 | 840 | #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) · 65 unmodified lines | ||
| 925 | 906 | if (!tbd_parse_movetoany("\n \"'")) goto the_end; |
| 926 | 907 | tbd_parse_trample; |
| 927 | 908 | ret = 0; |
| 928 | − if (macho_add_dllref(s1, lev, soname) != 0) goto the_end; | |
| 909 | + if (tcc_add_dllref(s1, soname, lev)->found) | |
| 910 | + goto the_end; | |
| 929 | 911 | while(pos) { |
| 930 | 912 | char* sym = NULL; |
| 931 | 913 | int cont = 1; |
| @@ -1047,7 +1029,7 @@ ST_FUNC int macho_load_dll(TCCState * s1, int fd, const char* filename, int lev) · 115 unmodified lines | ||
| 1047 | 1029 | lc = (struct load_command*) ((char*)lc + lc->cmdsize); |
| 1048 | 1030 | } |
| 1049 | 1031 | |
| 1050 | − if (0 != macho_add_dllref(s1, lev, soname)) | |
| 1032 | + if (tcc_add_dllref(s1, soname, lev)->found) | |
| 1051 | 1033 | goto the_end; |
| 1052 | 1034 | |
| 1053 | 1035 | if (!nsyms || !nextdef) |
| @@ -1533,16 +1533,6 @@ ST_FUNC int pe_putimport(TCCState *s1, int dllindex, const char *name, addr_t va · 1532 unmodified lines | ||
| 1533 | 1533 | ); |
| 1534 | 1534 | } |
| 1535 | 1535 | |
| 1536 | −static int pe_add_dllref(TCCState *s1, const char *dllname) | |
| 1537 | −{ | |
| 1538 | − int i; | |
| 1539 | − for (i = 0; i < s1->nb_loaded_dlls; ++i) | |
| 1540 | − if (0 == strcmp(s1->loaded_dlls[i]->name, dllname)) | |
| 1541 | − return i + 1; | |
| 1542 | − tcc_add_dllref(s1, dllname); | |
| 1543 | − return s1->nb_loaded_dlls; | |
| 1544 | −} | |
| 1545 | − | |
| 1546 | 1536 | static int read_mem(int fd, unsigned offset, void *buffer, unsigned len) |
| 1547 | 1537 | { |
| 1548 | 1538 | lseek(fd, offset, SEEK_SET); |
| @@ -1732,7 +1722,7 @@ static int pe_load_def(TCCState *s1, int fd) · 183 unmodified lines | ||
| 1732 | 1722 | ++state; |
| 1733 | 1723 | break; |
| 1734 | 1724 | case 2: |
| 1735 | − dllindex = pe_add_dllref(s1, dllname); | |
| 1725 | + dllindex = tcc_add_dllref(s1, dllname, 0)->index; | |
| 1736 | 1726 | ++state; |
| 1737 | 1727 | /* fall through */ |
| 1738 | 1728 | default: |
| @@ -1769,7 +1759,7 @@ static int pe_load_dll(TCCState *s1, int fd, const char *filename) · 30 unmodified lines | ||
| 1769 | 1759 | if (ret) { |
| 1770 | 1760 | return -1; |
| 1771 | 1761 | } else if (p) { |
| 1772 | − index = pe_add_dllref(s1, filename); | |
| 1762 | + index = tcc_add_dllref(s1, filename, 0)->index; | |
| 1773 | 1763 | for (q = p; *q; q += 1 + strlen(q)) |
| 1774 | 1764 | pe_putimport(s1, index, q, 0); |
| 1775 | 1765 | tcc_free(p); |