[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Tinycc-devel] [bug fix] do with weak alias in shared lib
From: |
lepton |
Subject: |
[Tinycc-devel] [bug fix] do with weak alias in shared lib |
Date: |
Wed, 29 Jun 2005 02:54:49 +0800 |
in libc6, at least in glibc-2.3.2, some variable is weak alias of another global
variable, for example, "environ" is a weak alias of "__environ".
now tcc don't do with weak alias in share lib.
so the following program will run incorrectly when compiled with tcc.
//test.c
extern char **environ;
extern char **__environ;
int main()
{
printf("%08x %08x\n", &environ,environ);
printf("%08x %08x\n", &__environ, __environ);
}
//end
when compiled with gcc, the run result is:
08049654 bffff9fc
08049654 bffff9fc
when compiled with tcc, the result changed to:
080494c0 00000000
080494d0 bffff9fc
the following patch should fix this.
--- tcc-0.9.23/tcc.c 2005-06-29 00:34:07.000000000 +0800
+++ tcc-0.9.23-lepton/tcc.c 2005-06-29 00:36:07.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;
}
--- tcc-0.9.23/tccelf.c 2005-06-18 06:09:15.000000000 +0800
+++ tcc-0.9.23-lepton/tccelf.c 2005-06-29 00:38:09.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;i<m;i++){
+ if(index<index_bold[i])
+ break;
+ }
+ m=i;
+ for(i=index_bold[m-1]; i<index_bold[m]; i++){
+ e=&((Elf32_Sym *)s1->dynsymtab_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,51 @@
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){
+ printf("here!\n");
+ 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 {
+ printf("%s %d\n", name, sym->st_value);
+ 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 +2233,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){
+ 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++) {
weak_alias.diff
Description: Text Data
[Prev in Thread] |
Current Thread |
[Next in Thread] |
- [Tinycc-devel] [bug fix] do with weak alias in shared lib,
lepton <=