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
957957 return 0;
958958 }
959959
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)
961962 {
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));
963979 strcpy(ref->name, dllname);
964980 dynarray_add(&s1->loaded_dlls, &s1->nb_loaded_dlls, ref);
981+ ref->level = level;
982+ ref->index = s1->nb_loaded_dlls;
965983 return ref;
966984 }
967985
@@ -1042,7 +1060,7 @@ ST_FUNC int tcc_add_file_internal(TCCState *s1, const char *filename, int flags) · 74 unmodified lines
10421060 soname = macho_tbd_soname(filename);
10431061 dl = dlopen(soname, RTLD_GLOBAL | RTLD_LAZY);
10441062 if (dl)
1045− tcc_add_dllref(s1, soname)->handle = dl, ret = 0;
1063+ tcc_add_dllref(s1, soname, 0)->handle = dl, ret = 0;
10461064 if (filename != soname)
10471065 tcc_free((void *)soname);
10481066 #endif
@@ -1070,7 +1088,7 @@ ST_FUNC int tcc_add_file_internal(TCCState *s1, const char *filename, int flags) · 21 unmodified lines
10701088 #ifdef TCC_IS_NATIVE
10711089 void* dl = dlopen(filename, RTLD_GLOBAL | RTLD_LAZY);
10721090 if (dl)
1073− tcc_add_dllref(s1, filename)->handle = dl, ret = 0;
1091+ tcc_add_dllref(s1, filename, 0)->handle = dl, ret = 0;
10741092 #endif
10751093 } else
10761094 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
609609 typedef struct DLLReference {
610610 int level;
611611 void *handle;
612+ unsigned char found, index;
612613 char name[1];
613614 } DLLReference;
614615
@@ -1279,7 +1280,7 @@ PUB_FUNC int tcc_parse_args(TCCState *s, int *argc, char ***argv, int optind); · 664 unmodified lines
12791280 #ifdef _WIN32
12801281 ST_FUNC char *normalize_slashes(char *path);
12811282 #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);
12831284 ST_FUNC char *tcc_load_text(int fd);
12841285
12851286 /* 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
547547 static void
548548 version_add (TCCState *s1)
549549 {
550− int i, j;
550+ int i;
551551 ElfW(Sym) *sym;
552552 ElfW(Verneed) *vn = NULL;
553553 Section *symtab;
@@ -594,14 +594,8 @@ version_add (TCCState *s1) · 40 unmodified lines
594594 ElfW(Vernaux) *vna = 0;
595595 if (sv->out_index < 1)
596596 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);
605599 vnofs = section_add(verneed_section, sizeof(*vn), 1);
606600 vn = (ElfW(Verneed)*)(verneed_section->data + vnofs);
607601 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
34253419 {
34263420 ElfW(Ehdr) ehdr;
34273421 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;
34293423 ElfW(Sym) *sym, *dynsym;
34303424 ElfW(Dyn) *dt, *dynamic;
34313425
34323426 char *dynstr;
34333427 int sym_index;
34343428 const char *name, *soname;
3435− DLLReference *dllref;
34363429 struct versym_info v;
34373430
34383431 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
34823475 }
34833476 }
34843477
3478+ if (!dynamic)
3479+ goto the_end;
3480+
34853481 /* compute the real library name */
34863482 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)
34903485 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− }
34953486
34963487 /* 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;
35073490
35083491 if (v.nb_versyms != nb_syms)
35093492 tcc_free (v.versym), v.versym = NULL;
35103493 else
35113494 store_version(s1, &v, dynstr);
35123495
3513− /* add the dll and its level */
3514− tcc_add_dllref(s1, soname)->level = level;
3515−
35163496 /* add dynamic symbols in dynsym_section */
35173497 for(i = 1, sym = dynsym + 1; i < nb_syms; i++, sym++) {
35183498 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
35283508 }
35293509 }
35303510
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+
35313515 /* load all referenced DLLs */
35323516 for(i = 0, dt = dynamic; i < nb_dts; i++, dt++) {
35333517 switch(dt->d_tag) {
35343518 case DT_NEEDED:
35353519 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;
35413522 if (tcc_add_dll(s1, name, AFF_REFERENCED_DLL) < 0) {
35423523 tcc_error_noabort("referenced dll '%s' not found", name);
3543− ret = -1;
35443524 goto the_end;
35453525 }
3546− already_loaded:
3547− break;
35483526 }
35493527 }
3528+
3529+ ret_success:
35503530 ret = 0;
35513531 the_end:
35523532 tcc_free(dynstr);
tccmacho.c+3−21
@@ -835,25 +835,6 @@ static uint32_t macho_swap32(uint32_t x) · 834 unmodified lines
835835 return (x >> 24) | (x << 24) | ((x >> 8) & 0xff00) | ((x & 0xff00) << 8);
836836 }
837837 #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−
857838 #define tbd_parse_movepast(s) \
858839 (pos = (pos = strstr(pos, s)) ? pos + strlen(s) : NULL)
859840 #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
925906 if (!tbd_parse_movetoany("\n \"'")) goto the_end;
926907 tbd_parse_trample;
927908 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;
929911 while(pos) {
930912 char* sym = NULL;
931913 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
10471029 lc = (struct load_command*) ((char*)lc + lc->cmdsize);
10481030 }
10491031
1050− if (0 != macho_add_dllref(s1, lev, soname))
1032+ if (tcc_add_dllref(s1, soname, lev)->found)
10511033 goto the_end;
10521034
10531035 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
15331533 );
15341534 }
15351535
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−
15461536 static int read_mem(int fd, unsigned offset, void *buffer, unsigned len)
15471537 {
15481538 lseek(fd, offset, SEEK_SET);
@@ -1732,7 +1722,7 @@ static int pe_load_def(TCCState *s1, int fd) · 183 unmodified lines
17321722 ++state;
17331723 break;
17341724 case 2:
1735− dllindex = pe_add_dllref(s1, dllname);
1725+ dllindex = tcc_add_dllref(s1, dllname, 0)->index;
17361726 ++state;
17371727 /* fall through */
17381728 default:
@@ -1769,7 +1759,7 @@ static int pe_load_dll(TCCState *s1, int fd, const char *filename) · 30 unmodified lines
17691759 if (ret) {
17701760 return -1;
17711761 } else if (p) {
1772− index = pe_add_dllref(s1, filename);
1762+ index = tcc_add_dllref(s1, filename, 0)->index;
17731763 for (q = p; *q; q += 1 + strlen(q))
17741764 pe_putimport(s1, index, q, 0);
17751765 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