diff -urN tcc-0.9.23/tcc.c tcc-0.9.23-lepton/tcc.c --- tcc-0.9.23/tcc.c 2005-06-29 09:57:03.000000000 +0800 +++ tcc-0.9.23-lepton/tcc.c 2005-06-29 10:17:34.000000000 +0800 @@ -491,6 +491,11 @@ /* pack stack */ int pack_stack[PACK_STACK_SIZE]; int *pack_stack_ptr; + + /* for weak alias symbol reslove */ + int *dynsymtab_index_bold; + int dynsymtab_max_bold; + int dynsymtab_alloc_bold; }; /* The current value can be: */ @@ -9773,6 +9778,10 @@ /* XXX: currently the PE linker is not ready to support that */ s->leading_underscore = 1; #endif + s->dynsymtab_alloc_bold = 16; + s->dynsymtab_index_bold = tcc_malloc(sizeof(int)*s->dynsymtab_alloc_bold); + s->dynsymtab_index_bold[0]=0; + s->dynsymtab_max_bold=0; return s; } @@ -9823,6 +9832,7 @@ for(i = 0; i < s1->nb_sysinclude_paths; i++) tcc_free(s1->sysinclude_paths[i]); tcc_free(s1->sysinclude_paths); + tcc_free(s1->dynsymtab_index_bold); tcc_free(s1); } diff -urN tcc-0.9.23/tccelf.c tcc-0.9.23-lepton/tccelf.c --- tcc-0.9.23/tccelf.c 2005-06-18 06:09:15.000000000 +0800 +++ tcc-0.9.23-lepton/tccelf.c 2005-06-29 10:17:47.000000000 +0800 @@ -1089,6 +1089,24 @@ } } +Elf32_Sym * try_find_orig_sym(TCCState *s1, int index, int st_value) +{ + int *index_bold=s1->dynsymtab_index_bold; + int i, m=s1->dynsymtab_max_bold; + Elf32_Sym *e; + for(i=1;idynsymtab_section->data)[i]; + if(e->st_value == st_value && ELF32_ST_BIND(e->st_info) == STB_GLOBAL) + return e; + } + return NULL; +} + /* output an ELF file */ /* XXX: suppress unneeded sections */ int tcc_output_file(TCCState *s1, const char *filename) @@ -1182,14 +1200,49 @@ sym - (Elf32_Sym *)symtab_section->data); } else if (type == STT_OBJECT) { unsigned long offset; + Elf32_Sym *e=NULL; offset = bss_section->data_offset; /* XXX: which alignment ? */ offset = (offset + 16 - 1) & -16; - index = put_elf_sym(s1->dynsym, offset, esym->st_size, + if(ELF32_ST_BIND(esym->st_info)==STB_WEAK && esym->st_value + && (e = try_find_orig_sym(s1 ,sym_index, esym->st_value))){ + char *name2; + name2 = s1->dynsymtab_section->link->data + e->st_name; + index=find_elf_sym(s1->dynsym, name2); + if(!index){ + index = put_elf_sym(s1->dynsym, offset, e->st_size, + e->st_info, 0, + bss_section->sh_num, name2); + put_elf_reloc(s1->dynsym, bss_section, + offset, R_COPY, index); + put_elf_sym(s1->dynsym, offset, esym->st_size, + esym->st_info, 0, + bss_section->sh_num, name); + + index=find_elf_sym(symtab_section, name2); + if(index){ + e = &((Elf32_Sym *)symtab_section->data)[index]; + if(ELF32_ST_BIND(e->st_info)==STB_GLOBAL && e->st_shndx == SHN_UNDEF) + /* we just use 0xFFFFFFFF to identify this symbol has been reloc */ + e->st_value = 0xFFFFFFFF; + } + + }else { + e = &((Elf32_Sym *)s1->dynsym->data)[index]; + put_elf_sym(s1->dynsym, e->st_value, esym->st_size, + esym->st_info, 0, + bss_section->sh_num, name); + continue; + } + } else if(ELF32_ST_BIND(esym->st_info)==STB_GLOBAL && sym->st_value == 0xFFFFFFFF) + continue; + else { + index=put_elf_sym(s1->dynsym, offset, esym->st_size, esym->st_info, 0, bss_section->sh_num, name); - put_elf_reloc(s1->dynsym, bss_section, + put_elf_reloc(s1->dynsym, bss_section, offset, R_COPY, index); + } offset += esym->st_size; bss_section->data_offset = offset; } @@ -2178,6 +2231,14 @@ add_elf_sym(s1->dynsymtab_section, sym->st_value, sym->st_size, sym->st_info, sym->st_other, sym->st_shndx, name); } + i=s1->dynsymtab_section->data_offset/sizeof(Elf32_Sym); + if(i>s1->dynsymtab_index_bold[s1->dynsymtab_max_bold]){ + s1->dynsymtab_index_bold[++(s1->dynsymtab_max_bold)]=i; + if(s1->dynsymtab_max_bold==s1->dynsymtab_alloc_bold - 1){ + s1->dynsymtab_alloc_bold=s1->dynsymtab_alloc_bold * 2; + s1->dynsymtab_index_bold=tcc_realloc(s1->dynsymtab_index_bold, s1->dynsymtab_alloc_bold); + } + } /* load all referenced DLLs */ for(i = 0, dt = dynamic; i < nb_dts; i++, dt++) {