diff options
| author | mob <mob> | 2012-02-26 19:02:51 -0600 |
|---|---|---|
| committer | mob <mob> | 2012-02-26 19:02:51 -0600 |
| commit | d7a7c3769d0a1dcb8400258cd8adf78a8566de61 (patch) | |
| tree | 1333ad336c0626f41ec5690ea9e34c908c967d60 /tccelf.c | |
| parent | 6e13c35334200e7ef918308aeb820404d7b35283 (diff) | |
| download | tinycc-d7a7c3769d0a1dcb8400258cd8adf78a8566de61.tar.gz tinycc-d7a7c3769d0a1dcb8400258cd8adf78a8566de61.tar.bz2 | |
Multiple fixes for 64 bit sections
This changeset attempts to fix a few problems when giving using
the high 32bits of a 64bit section offset. There are likely more
issues (or perhaps regressions) lurking in the muck here. In general,
this moves a few data type declarations to use uplong. Also, add
support for 64bit mingw32 building under cygwin. Because native
types are used for 64 bit offsets, this won't fix challenges with
cross compiling from 32bit -> 64bit.
Tested under cygwin, against binary compiled with
-Wl,-Ttext=0xffffff8000000000
Signed-off-by: Andrew Mulbrook <andrew262@gmail.com>
Diffstat (limited to 'tccelf.c')
| -rw-r--r-- | tccelf.c | 21 |
1 files changed, 13 insertions, 8 deletions
@@ -1153,7 +1153,7 @@ ST_FUNC Section *new_symtab(TCCState *s1, } /* put dynamic tag */ -static void put_dt(Section *dynamic, int dt, unsigned long val) +static void put_dt(Section *dynamic, int dt, uplong val) { ElfW(Dyn) *dyn; dyn = section_ptr_add(dynamic, sizeof(ElfW(Dyn))); @@ -1381,7 +1381,7 @@ ST_FUNC void fill_got_entry(TCCState *s1, ElfW_Rel *rel) section_reserve(s1->got, offset + PTR_SIZE); #ifdef TCC_TARGET_X86_64 /* only works for x86-64 */ - put32(s1->got->data + offset, sym->st_value >> 32); + put32(s1->got->data + offset + 4, sym->st_value >> 32); #endif put32(s1->got->data + offset, sym->st_value & 0xffffffff); } @@ -1421,8 +1421,9 @@ static int elf_output_file(TCCState *s1, const char *filename) FILE *f; int fd, mode, ret; int *section_order; - int shnum, i, phnum, file_offset, offset, size, j, tmp, sh_order_index, k; - unsigned long addr; + int shnum, i, phnum, file_offset, offset, size, j, sh_order_index, k; + long long tmp; + uplong addr; Section *strsec, *s; ElfW(Shdr) shdr, *sh; ElfW(Phdr) *phdr, *ph; @@ -1430,9 +1431,9 @@ static int elf_output_file(TCCState *s1, const char *filename) unsigned long saved_dynamic_data_offset; ElfW(Sym) *sym; int type, file_type; - unsigned long rel_addr, rel_size; + uplong rel_addr, rel_size; #if defined(__FreeBSD__) || defined(__FreeBSD_kernel__) - unsigned long bss_addr, bss_size; + uplong bss_addr, bss_size; #endif file_type = s1->output_type; @@ -1747,7 +1748,7 @@ static int elf_output_file(TCCState *s1, const char *filename) addr = s1->text_addr; /* we ensure that (addr % ELF_PAGE_SIZE) == file_offset % ELF_PAGE_SIZE */ - a_offset = addr & (s1->section_align - 1); + a_offset = ((int) addr) & (s1->section_align - 1); p_offset = file_offset & (s1->section_align - 1); if (a_offset < p_offset) a_offset += s1->section_align; @@ -1821,7 +1822,7 @@ static int elf_output_file(TCCState *s1, const char *filename) tmp = addr; addr = (addr + s->sh_addralign - 1) & ~(s->sh_addralign - 1); - file_offset += addr - tmp; + file_offset += (int) ( addr - tmp ); s->sh_offset = file_offset; s->sh_addr = addr; @@ -1915,8 +1916,12 @@ static int elf_output_file(TCCState *s1, const char *filename) ph->p_align = dynamic->sh_addralign; /* put GOT dynamic section address */ +#if defined(TCC_TARGET_X86_64) + put32(s1->got->data + 4, dynamic->sh_addr >> 32 ); +#endif put32(s1->got->data, dynamic->sh_addr); + /* relocate the PLT */ if (file_type == TCC_OUTPUT_EXE #if defined(TCC_OUTPUT_DLL_WITH_PLT) |
