From d7a7c3769d0a1dcb8400258cd8adf78a8566de61 Mon Sep 17 00:00:00 2001 From: mob Date: Sun, 26 Feb 2012 19:02:51 -0600 Subject: 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 --- tccelf.c | 21 +++++++++++++-------- 1 file changed, 13 insertions(+), 8 deletions(-) (limited to 'tccelf.c') diff --git a/tccelf.c b/tccelf.c index 40c88ab..2b4b0ab 100644 --- a/tccelf.c +++ b/tccelf.c @@ -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) -- cgit v1.3.1