tinycc-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Tinycc-devel] tcc -static is broken


From: Ali Gholami Rudi
Subject: [Tinycc-devel] tcc -static is broken
Date: Thu, 04 Feb 2010 23:55:17 +0330
User-agent: git://repo.or.cz/mailx.git

Hi,

Currently static linking is broken (tried linking with dietlibc).
I think the problem is tcc uses the GOT table but since it is
linked statically, dynamic linker no longer fills it.  I'm not sure
if this is the correct way of fixing it; I've attached a patch to
fill the GOT after linking (only for x86-64).

        Ali

From: Ali Gholami Rudi <address@hidden>
Subject: [PATCH] fill got table for static linking

---
 libtcc.c |    9 +++++++++
 tcc.h    |    1 +
 tccelf.c |   44 ++++++++++++++++++++++++++++++++++++++++++++
 3 files changed, 54 insertions(+), 0 deletions(-)

diff --git a/libtcc.c b/libtcc.c
index 520abfd..7fb245d 100644
--- a/libtcc.c
+++ b/libtcc.c
@@ -372,6 +372,15 @@ ST_FUNC void *section_ptr_add(Section *sec, unsigned long 
size)
     return sec->data + offset;
 }
 
+/* reserve at least 'size' bytes from section start */
+ST_FUNC void section_reserve(Section *sec, unsigned long size)
+{
+    if (size > sec->data_allocated)
+        section_realloc(sec, size);
+    if (size > sec->data_offset)
+        sec->data_offset = size;
+}
+
 /* return a reference to a section, and create it if it does not
    exists */
 ST_FUNC Section *find_section(TCCState *s1, const char *name)
diff --git a/tcc.h b/tcc.h
index 3481f64..4b8111c 100644
--- a/tcc.h
+++ b/tcc.h
@@ -891,6 +891,7 @@ ST_FUNC void add_char(CString *cstr, int c);
 ST_FUNC Section *new_section(TCCState *s1, const char *name, int sh_type, int 
sh_flags);
 ST_FUNC void section_realloc(Section *sec, unsigned long new_size);
 ST_FUNC void *section_ptr_add(Section *sec, unsigned long size);
+ST_FUNC void section_reserve(Section *sec, unsigned long size);
 ST_FUNC Section *find_section(TCCState *s1, const char *name);
 
 ST_FUNC void put_extern_sym2(Sym *sym, Section *section, unsigned long value, 
unsigned long size, int can_add_underscore);
diff --git a/tccelf.c b/tccelf.c
index a5385b1..2323a6b 100644
--- a/tccelf.c
+++ b/tccelf.c
@@ -1361,6 +1361,48 @@ void patch_dynsym_undef(TCCState *s1, Section *s)
 #define        EXTRA_RELITEMS  9
 #endif
 
+ST_FUNC void fill_got_entry(TCCState *s1, ElfW_Rel *rel)
+{
+       int sym_index = ELFW(R_SYM) (rel->r_info);
+       ElfW(Sym) *sym = &((ElfW(Sym) *) symtab_section->data)[sym_index];
+       unsigned long offset;
+
+       if (sym_index >= s1->nb_got_offsets)
+               return;
+       offset = s1->got_offsets[sym_index];
+       section_reserve(s1->got, offset + PTR_SIZE);
+       /* only works for x86-64 */
+       put32(s1->got->data + offset, sym->st_value >> 32);
+       put32(s1->got->data + offset, sym->st_value & 0xffffffff);
+}
+
+ST_FUNC void fill_got(TCCState *s1)
+{
+       Section *s;
+       ElfW_Rel *rel, *rel_end;
+       int i;
+
+       for(i = 1; i < s1->nb_sections; i++) {
+               s = s1->sections[i];
+               if (s->sh_type != SHT_RELX)
+                       continue;
+               /* no need to handle got relocations */
+               if (s->link != symtab_section)
+                       continue;
+               rel_end = (ElfW_Rel *) (s->data + s->data_offset);
+               for(rel = (ElfW_Rel *) s->data; rel < rel_end; rel++) {
+                       switch (ELFW(R_TYPE) (rel->r_info)) {
+                       case R_X86_64_GOT32:
+                       case R_X86_64_GOTPCREL:
+                       case R_X86_64_PLT32:
+                               fill_got_entry(s1, rel);
+                               break;
+                       }
+               }
+       }
+}
+
+
 /* output an ELF file */
 /* XXX: suppress unneeded sections */
 static int elf_output_file(TCCState *s1, const char *filename)
@@ -1977,6 +2019,8 @@ static int elf_output_file(TCCState *s1, const char 
*filename)
         else
             ehdr.e_entry = text_section->sh_addr; /* XXX: is it correct ? */
     }
+    if (file_type == TCC_OUTPUT_EXE && s1->static_link)
+        fill_got(s1);
 
     /* write elf file */
     if (file_type == TCC_OUTPUT_OBJ)





reply via email to

[Prev in Thread] Current Thread [Next in Thread]