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>
This commit is contained in:
mob
2012-02-26 19:02:51 -06:00
parent 6e13c35334
commit d7a7c3769d
6 changed files with 41 additions and 24 deletions

View File

@ -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)