aboutsummaryrefslogtreecommitdiff
path: root/tccelf.c
diff options
context:
space:
mode:
authormob <mob>2012-02-26 19:02:51 -0600
committermob <mob>2012-02-26 19:02:51 -0600
commitd7a7c3769d0a1dcb8400258cd8adf78a8566de61 (patch)
tree1333ad336c0626f41ec5690ea9e34c908c967d60 /tccelf.c
parent6e13c35334200e7ef918308aeb820404d7b35283 (diff)
downloadtinycc-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.c21
1 files changed, 13 insertions, 8 deletions
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)