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:
21
tccelf.c
21
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)
|
||||
|
||||
Reference in New Issue
Block a user