History

libtcc: extend tcc_add_dllref()

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(-)

grischka committed 4 years ago

Commit e8adc641 parent 7d319045 files · +48 −77Browse files

Unified · Split

5 files
  1. libtcc.c +22 −4
  2. tcc.h +2 −1
  3. tccelf.c +19 −39
  4. tccmacho.c +3 −21
  5. tccpe.c +2 −12
libtcc.c+22−4
@@ -957,11 +957,29 @@ LIBTCCAPI int tcc_add_sysinclude_path(TCCState *s, const char *pathname) · 956 unmodified lines
957 return 0;957 return 0;
958}958}
959 959
960ST_FUNC DLLReference *tcc_add_dllref(TCCState *s1, const char *dllname)960/* add/update a 'DLLReference', Just find if level == -1 */
961ST_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 strcpy(ref->name, dllname);979 strcpy(ref->name, dllname);
964 dynarray_add(&s1->loaded_dlls, &s1->nb_loaded_dlls, ref);980 dynarray_add(&s1->loaded_dlls, &s1->nb_loaded_dlls, ref);
981 ref->level = level;
982 ref->index = s1->nb_loaded_dlls;
965 return ref;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 soname = macho_tbd_soname(filename);1060 soname = macho_tbd_soname(filename);
1043 dl = dlopen(soname, RTLD_GLOBAL | RTLD_LAZY);1061 dl = dlopen(soname, RTLD_GLOBAL | RTLD_LAZY);
1044 if (dl)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 if (filename != soname)1064 if (filename != soname)
1047 tcc_free((void *)soname);1065 tcc_free((void *)soname);
1048#endif1066#endif
@@ -1070,7 +1088,7 @@ ST_FUNC int tcc_add_file_internal(TCCState *s1, const char *filename, int flags) · 21 unmodified lines
1070#ifdef TCC_IS_NATIVE1088#ifdef TCC_IS_NATIVE
1071 void* dl = dlopen(filename, RTLD_GLOBAL | RTLD_LAZY);1089 void* dl = dlopen(filename, RTLD_GLOBAL | RTLD_LAZY);
1072 if (dl)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#endif1092#endif
1075 } else1093 } else
1076 ret = tcc_load_dll(s1, fd, filename, (flags & AFF_REFERENCED_DLL) != 0);1094 ret = tcc_load_dll(s1, fd, filename, (flags & AFF_REFERENCED_DLL) != 0);
tcc.h+2−1
@@ -609,6 +609,7 @@ typedef struct Section { · 608 unmodified lines
609typedef struct DLLReference {609typedef struct DLLReference {
610 int level;610 int level;
611 void *handle;611 void *handle;
612 unsigned char found, index;
612 char name[1];613 char name[1];
613} DLLReference;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#ifdef _WIN321280#ifdef _WIN32
1280ST_FUNC char *normalize_slashes(char *path);1281ST_FUNC char *normalize_slashes(char *path);
1281#endif1282#endif
1282ST_FUNC DLLReference *tcc_add_dllref(TCCState *s1, const char *dllname);1283ST_FUNC DLLReference *tcc_add_dllref(TCCState *s1, const char *dllname, int level);
1283ST_FUNC char *tcc_load_text(int fd);1284ST_FUNC char *tcc_load_text(int fd);
1284 1285
1285/* tcc_parse_args return codes: */1286/* tcc_parse_args return codes: */
tccelf.c+19−39
@@ -547,7 +547,7 @@ LIBTCCAPI void tcc_list_symbols(TCCState *s, void *ctx, · 546 unmodified lines
547static void547static void
548version_add (TCCState *s1)548version_add (TCCState *s1)
549{549{
550 int i, j;550 int i;
551 ElfW(Sym) *sym;551 ElfW(Sym) *sym;
552 ElfW(Verneed) *vn = NULL;552 ElfW(Verneed) *vn = NULL;
553 Section *symtab;553 Section *symtab;
@@ -594,14 +594,8 @@ version_add (TCCState *s1) · 40 unmodified lines
594 ElfW(Vernaux) *vna = 0;594 ElfW(Vernaux) *vna = 0;
595 if (sv->out_index < 1)595 if (sv->out_index < 1)
596 continue;596 continue;
597 /* If present in verneed it should be in DT_NEEDED */597 /* make sure that a DT_NEEDED tag is put */
598 for (j = 0; j < s1->nb_loaded_dlls; j++) {598 tcc_add_dllref(s1, sv->lib, 0);
599 DLLReference *dllref = s1->loaded_dlls[j];
600 if (!strcmp(sv->lib, dllref->name)) {
601 dllref->level = 0;
602 break;
603 }
604 }
605 vnofs = section_add(verneed_section, sizeof(*vn), 1);599 vnofs = section_add(verneed_section, sizeof(*vn), 1);
606 vn = (ElfW(Verneed)*)(verneed_section->data + vnofs);600 vn = (ElfW(Verneed)*)(verneed_section->data + vnofs);
607 vn->vn_version = 1;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 ElfW(Ehdr) ehdr;3420 ElfW(Ehdr) ehdr;
3427 ElfW(Shdr) *shdr, *sh, *sh1;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 ElfW(Sym) *sym, *dynsym;3423 ElfW(Sym) *sym, *dynsym;
3430 ElfW(Dyn) *dt, *dynamic;3424 ElfW(Dyn) *dt, *dynamic;
3431 3425
3432 char *dynstr;3426 char *dynstr;
3433 int sym_index;3427 int sym_index;
3434 const char *name, *soname;3428 const char *name, *soname;
3435 DLLReference *dllref;
3436 struct versym_info v;3429 struct versym_info v;
3437 3430
3438 full_read(fd, &ehdr, sizeof(ehdr));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 /* compute the real library name */3481 /* compute the real library name */
3486 soname = tcc_basename(filename);3482 soname = tcc_basename(filename);
3487 3483 for(i = 0, dt = dynamic; i < nb_dts; i++, dt++)
3488 for(i = 0, dt = dynamic; i < nb_dts; i++, dt++) {3484 if (dt->d_tag == DT_SONAME)
3489 if (dt->d_tag == DT_SONAME) {
3490 soname = dynstr + dt->d_un.d_val;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 /* if the dll is already loaded, do not load it */3487 /* if the dll is already loaded, do not load it */
3497 for(i = 0; i < s1->nb_loaded_dlls; i++) {3488 if (tcc_add_dllref(s1, soname, level)->found)
3498 dllref = s1->loaded_dlls[i];3489 goto ret_success;
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 }
3507 3490
3508 if (v.nb_versyms != nb_syms)3491 if (v.nb_versyms != nb_syms)
3509 tcc_free (v.versym), v.versym = NULL;3492 tcc_free (v.versym), v.versym = NULL;
3510 else3493 else
3511 store_version(s1, &v, dynstr);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 /* add dynamic symbols in dynsym_section */3496 /* add dynamic symbols in dynsym_section */
3517 for(i = 1, sym = dynsym + 1; i < nb_syms; i++, sym++) {3497 for(i = 1, sym = dynsym + 1; i < nb_syms; i++, sym++) {
3518 sym_bind = ELFW(ST_BIND)(sym->st_info);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 /* load all referenced DLLs */3515 /* load all referenced DLLs */
3532 for(i = 0, dt = dynamic; i < nb_dts; i++, dt++) {3516 for(i = 0, dt = dynamic; i < nb_dts; i++, dt++) {
3533 switch(dt->d_tag) {3517 switch(dt->d_tag) {
3534 case DT_NEEDED:3518 case DT_NEEDED:
3535 name = dynstr + dt->d_un.d_val;3519 name = dynstr + dt->d_un.d_val;
3536 for(j = 0; j < s1->nb_loaded_dlls; j++) {3520 if (tcc_add_dllref(s1, name, -1))
3537 dllref = s1->loaded_dlls[j];3521 continue;
3538 if (!strcmp(name, dllref->name))
3539 goto already_loaded;
3540 }
3541 if (tcc_add_dll(s1, name, AFF_REFERENCED_DLL) < 0) {3522 if (tcc_add_dll(s1, name, AFF_REFERENCED_DLL) < 0) {
3542 tcc_error_noabort("referenced dll '%s' not found", name);3523 tcc_error_noabort("referenced dll '%s' not found", name);
3543 ret = -1;
3544 goto the_end;3524 goto the_end;
3545 }3525 }
3546 already_loaded:
3547 break;
3548 }3526 }
3549 }3527 }
3528
3529 ret_success:
3550 ret = 0;3530 ret = 0;
3551 the_end:3531 the_end:
3552 tcc_free(dynstr);3532 tcc_free(dynstr);
tccmacho.c+3−21
@@ -835,25 +835,6 @@ static uint32_t macho_swap32(uint32_t x) · 834 unmodified lines
835 return (x >> 24) | (x << 24) | ((x >> 8) & 0xff00) | ((x & 0xff00) << 8);835 return (x >> 24) | (x << 24) | ((x >> 8) & 0xff00) | ((x & 0xff00) << 8);
836}836}
837#define SWAP(x) (swap ? macho_swap32(x) : (x))837#define SWAP(x) (swap ? macho_swap32(x) : (x))
838
839ST_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#define tbd_parse_movepast(s) \838#define tbd_parse_movepast(s) \
858 (pos = (pos = strstr(pos, s)) ? pos + strlen(s) : NULL)839 (pos = (pos = strstr(pos, s)) ? pos + strlen(s) : NULL)
859#define tbd_parse_movetoany(cs) (pos = strpbrk(pos, cs))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 if (!tbd_parse_movetoany("\n \"'")) goto the_end;906 if (!tbd_parse_movetoany("\n \"'")) goto the_end;
926 tbd_parse_trample;907 tbd_parse_trample;
927 ret = 0;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 while(pos) {911 while(pos) {
930 char* sym = NULL;912 char* sym = NULL;
931 int cont = 1;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 lc = (struct load_command*) ((char*)lc + lc->cmdsize);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 goto the_end;1033 goto the_end;
1052 1034
1053 if (!nsyms || !nextdef)1035 if (!nsyms || !nextdef)
tccpe.c+2−12
@@ -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
1536static 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
1546static int read_mem(int fd, unsigned offset, void *buffer, unsigned len)1536static int read_mem(int fd, unsigned offset, void *buffer, unsigned len)
1547{1537{
1548 lseek(fd, offset, SEEK_SET);1538 lseek(fd, offset, SEEK_SET);
@@ -1732,7 +1722,7 @@ static int pe_load_def(TCCState *s1, int fd) · 183 unmodified lines
1732 ++state;1722 ++state;
1733 break;1723 break;
1734 case 2:1724 case 2:
1735 dllindex = pe_add_dllref(s1, dllname);1725 dllindex = tcc_add_dllref(s1, dllname, 0)->index;
1736 ++state;1726 ++state;
1737 /* fall through */1727 /* fall through */
1738 default:1728 default:
@@ -1769,7 +1759,7 @@ static int pe_load_dll(TCCState *s1, int fd, const char *filename) · 30 unmodified lines
1769 if (ret) {1759 if (ret) {
1770 return -1;1760 return -1;
1771 } else if (p) {1761 } else if (p) {
1772 index = pe_add_dllref(s1, filename);1762 index = tcc_add_dllref(s1, filename, 0)->index;
1773 for (q = p; *q; q += 1 + strlen(q))1763 for (q = p; *q; q += 1 + strlen(q))
1774 pe_putimport(s1, index, q, 0);1764 pe_putimport(s1, index, q, 0);
1775 tcc_free(p);1765 tcc_free(p);

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t