portability: fix void* <-> target address conversion confusion

- #define addr_t as ElfW(Addr)
- replace uplong by addr_t
- #define TCC_HAS_RUNTIME_PLTGOT and use it
This commit is contained in:
grischka 2013-02-04 16:08:06 +01:00
parent 3186455599
commit 82bcbd027f
6 changed files with 136 additions and 130 deletions

View File

@ -423,7 +423,7 @@ ST_FUNC Section *find_section(TCCState *s1, const char *name)
/* update sym->c so that it points to an external symbol in section /* update sym->c so that it points to an external symbol in section
'section' with value 'value' */ 'section' with value 'value' */
ST_FUNC void put_extern_sym2(Sym *sym, Section *section, ST_FUNC void put_extern_sym2(Sym *sym, Section *section,
uplong value, unsigned long size, addr_t value, unsigned long size,
int can_add_underscore) int can_add_underscore)
{ {
int sym_type, sym_bind, sh_num, info, other; int sym_type, sym_bind, sh_num, info, other;
@ -527,7 +527,7 @@ ST_FUNC void put_extern_sym2(Sym *sym, Section *section,
} }
ST_FUNC void put_extern_sym(Sym *sym, Section *section, ST_FUNC void put_extern_sym(Sym *sym, Section *section,
uplong value, unsigned long size) addr_t value, unsigned long size)
{ {
put_extern_sym2(sym, section, value, size, 1); put_extern_sym2(sym, section, value, size, 1);
} }
@ -1279,11 +1279,11 @@ LIBTCCAPI int tcc_add_library(TCCState *s, const char *libraryname)
LIBTCCAPI int tcc_add_symbol(TCCState *s, const char *name, const void *val) LIBTCCAPI int tcc_add_symbol(TCCState *s, const char *name, const void *val)
{ {
#ifdef TCC_TARGET_PE #ifdef TCC_TARGET_PE
pe_putimport(s, 0, name, val); pe_putimport(s, 0, name, (uintptr_t)val);
#else #else
add_elf_sym(symtab_section, (uplong)val, 0, add_elf_sym(symtab_section, (uintptr_t)val, 0,
ELFW(ST_INFO)(STB_GLOBAL, STT_NOTYPE), 0, ELFW(ST_INFO)(STB_GLOBAL, STT_NOTYPE), 0,
SHN_ABS, name); SHN_ABS, name);
#endif #endif
return 0; return 0;
} }

115
tcc.h
View File

@ -42,25 +42,28 @@
#include <setjmp.h> #include <setjmp.h>
#include <time.h> #include <time.h>
#ifdef _WIN32
#include <windows.h>
#include <sys/timeb.h>
#include <io.h> /* open, close etc. */
#include <direct.h> /* getcwd */
#define inline __inline
#define inp next_inp
#ifdef LIBTCC_AS_DLL
# define LIBTCCAPI __declspec(dllexport)
# define PUB_FUNC LIBTCCAPI
#endif
#endif
#ifndef _WIN32 #ifndef _WIN32
#include <unistd.h> # include <unistd.h>
#include <sys/time.h> # include <sys/time.h>
#include <sys/ucontext.h> # include <sys/ucontext.h>
#include <sys/mman.h> # include <sys/mman.h>
#include <dlfcn.h> # include <dlfcn.h>
#else
# include <windows.h>
# include <sys/timeb.h>
# include <io.h> /* open, close etc. */
# include <direct.h> /* getcwd */
# ifdef __GNUC__
# include <stdint.h>
# else
typedef UINT_PTR uintptr_t;
# endif
# define inline __inline
# define inp next_inp
# ifdef LIBTCC_AS_DLL
# define LIBTCCAPI __declspec(dllexport)
# define PUB_FUNC LIBTCCAPI
# endif
#endif #endif
#endif /* !CONFIG_TCCBOOT */ #endif /* !CONFIG_TCCBOOT */
@ -78,6 +81,27 @@
#endif #endif
#include "elf.h" #include "elf.h"
#ifdef TCC_TARGET_X86_64
# define ELFCLASSW ELFCLASS64
# define ElfW(type) Elf##64##_##type
# define ELFW(type) ELF##64##_##type
# define ElfW_Rel ElfW(Rela)
# define SHT_RELX SHT_RELA
# define REL_SECTION_FMT ".rela%s"
/* XXX: DLL with PLT would only work with x86-64 for now */
# define TCC_OUTPUT_DLL_WITH_PLT
#else
# define ELFCLASSW ELFCLASS32
# define ElfW(type) Elf##32##_##type
# define ELFW(type) ELF##32##_##type
# define ElfW_Rel ElfW(Rel)
# define SHT_RELX SHT_REL
# define REL_SECTION_FMT ".rel%s"
#endif
/* target address type */
#define addr_t ElfW(Addr)
#include "stab.h" #include "stab.h"
#include "libtcc.h" #include "libtcc.h"
@ -139,13 +163,6 @@
# define CONFIG_TCC_BACKTRACE # define CONFIG_TCC_BACKTRACE
#endif #endif
/* target address type */
#if defined TCC_TARGET_X86_64 && (!defined __x86_64__ || defined _WIN32)
# define uplong unsigned long long
#else
# define uplong unsigned long
#endif
/* ------------ path configuration ------------ */ /* ------------ path configuration ------------ */
#ifndef CONFIG_SYSROOT #ifndef CONFIG_SYSROOT
@ -327,7 +344,7 @@ typedef struct Section {
int sh_addralign; /* elf section alignment */ int sh_addralign; /* elf section alignment */
int sh_entsize; /* elf entry size */ int sh_entsize; /* elf entry size */
unsigned long sh_size; /* section size (only used during output) */ unsigned long sh_size; /* section size (only used during output) */
uplong sh_addr; /* address at which the section is relocated */ addr_t sh_addr; /* address at which the section is relocated */
unsigned long sh_offset; /* file offset */ unsigned long sh_offset; /* file offset */
int nb_hashed_syms; /* used to resize the hash table */ int nb_hashed_syms; /* used to resize the hash table */
struct Section *link; /* link to another section */ struct Section *link; /* link to another section */
@ -552,7 +569,7 @@ struct TCCState {
int alacarte_link; int alacarte_link;
/* address of text section */ /* address of text section */
uplong text_addr; addr_t text_addr;
int has_text_addr; int has_text_addr;
/* symbols to call at load-time / unload-time */ /* symbols to call at load-time / unload-time */
@ -644,12 +661,12 @@ struct TCCState {
#endif #endif
#endif #endif
#ifndef TCC_TARGET_PE #if defined TCC_IS_NATIVE && !defined TCC_TARGET_PE \
#if defined TCC_TARGET_X86_64 || defined TCC_TARGET_ARM && (defined TCC_TARGET_X86_64 || defined TCC_TARGET_ARM)
/* write PLT and GOT here */ /* write PLT and GOT here */
char *runtime_plt_and_got; char *runtime_plt_and_got;
unsigned int runtime_plt_and_got_offset; unsigned int runtime_plt_and_got_offset;
#endif # define TCC_HAS_RUNTIME_PLTGOT
#endif #endif
}; };
@ -1007,8 +1024,8 @@ ST_FUNC void *section_ptr_add(Section *sec, unsigned long size);
ST_FUNC void section_reserve(Section *sec, unsigned long size); ST_FUNC void section_reserve(Section *sec, unsigned long size);
ST_FUNC Section *find_section(TCCState *s1, const char *name); ST_FUNC Section *find_section(TCCState *s1, const char *name);
ST_FUNC void put_extern_sym2(Sym *sym, Section *section, uplong value, unsigned long size, int can_add_underscore); ST_FUNC void put_extern_sym2(Sym *sym, Section *section, addr_t value, unsigned long size, int can_add_underscore);
ST_FUNC void put_extern_sym(Sym *sym, Section *section, uplong value, unsigned long size); ST_FUNC void put_extern_sym(Sym *sym, Section *section, addr_t value, unsigned long size);
ST_FUNC void greloc(Section *s, Sym *sym, unsigned long offset, int type); ST_FUNC void greloc(Section *s, Sym *sym, unsigned long offset, int type);
ST_INLN void sym_free(Sym *sym); ST_INLN void sym_free(Sym *sym);
@ -1187,8 +1204,8 @@ typedef struct {
ST_FUNC Section *new_symtab(TCCState *s1, const char *symtab_name, int sh_type, int sh_flags, const char *strtab_name, const char *hash_name, int hash_sh_flags); ST_FUNC Section *new_symtab(TCCState *s1, const char *symtab_name, int sh_type, int sh_flags, const char *strtab_name, const char *hash_name, int hash_sh_flags);
ST_FUNC int put_elf_str(Section *s, const char *sym); ST_FUNC int put_elf_str(Section *s, const char *sym);
ST_FUNC int put_elf_sym(Section *s, uplong value, unsigned long size, int info, int other, int shndx, const char *name); ST_FUNC int put_elf_sym(Section *s, addr_t value, unsigned long size, int info, int other, int shndx, const char *name);
ST_FUNC int add_elf_sym(Section *s, uplong value, unsigned long size, int info, int other, int sh_num, const char *name); ST_FUNC int add_elf_sym(Section *s, addr_t value, unsigned long size, int info, int other, int sh_num, const char *name);
ST_FUNC int find_elf_sym(Section *s, const char *name); ST_FUNC int find_elf_sym(Section *s, const char *name);
ST_FUNC void put_elf_reloc(Section *symtab, Section *s, unsigned long offset, int type, int symbol); ST_FUNC void put_elf_reloc(Section *symtab, Section *s, unsigned long offset, int type, int symbol);
@ -1204,12 +1221,16 @@ ST_FUNC void relocate_section(TCCState *s1, Section *s);
ST_FUNC void tcc_add_linker_symbols(TCCState *s1); ST_FUNC void tcc_add_linker_symbols(TCCState *s1);
ST_FUNC int tcc_load_object_file(TCCState *s1, int fd, unsigned long file_offset); ST_FUNC int tcc_load_object_file(TCCState *s1, int fd, unsigned long file_offset);
ST_FUNC int tcc_load_archive(TCCState *s1, int fd); ST_FUNC int tcc_load_archive(TCCState *s1, int fd);
ST_FUNC void *tcc_get_symbol_err(TCCState *s, const char *name);
ST_FUNC void tcc_add_bcheck(TCCState *s1); ST_FUNC void tcc_add_bcheck(TCCState *s1);
ST_FUNC void build_got_entries(TCCState *s1); ST_FUNC void build_got_entries(TCCState *s1);
ST_FUNC void tcc_add_runtime(TCCState *s1); ST_FUNC void tcc_add_runtime(TCCState *s1);
ST_FUNC addr_t get_elf_sym_addr(TCCState *s, const char *name, int err);
#ifdef TCC_IS_NATIVE
ST_FUNC void *tcc_get_symbol_err(TCCState *s, const char *name);
#endif
#ifndef TCC_TARGET_PE #ifndef TCC_TARGET_PE
ST_FUNC int tcc_load_dll(TCCState *s1, int fd, const char *filename, int level); ST_FUNC int tcc_load_dll(TCCState *s1, int fd, const char *filename, int level);
ST_FUNC int tcc_load_ldscript(TCCState *s1); ST_FUNC int tcc_load_ldscript(TCCState *s1);
@ -1219,24 +1240,6 @@ ST_INLN void inp(void);
ST_FUNC int handle_eob(void); ST_FUNC int handle_eob(void);
#endif #endif
#ifdef TCC_TARGET_X86_64
# define ELFCLASSW ELFCLASS64
# define ElfW(type) Elf##64##_##type
# define ELFW(type) ELF##64##_##type
# define ElfW_Rel ElfW(Rela)
# define SHT_RELX SHT_RELA
# define REL_SECTION_FMT ".rela%s"
/* XXX: DLL with PLT would only work with x86-64 for now */
# define TCC_OUTPUT_DLL_WITH_PLT
#else
# define ELFCLASSW ELFCLASS32
# define ElfW(type) Elf##32##_##type
# define ELFW(type) ELF##32##_##type
# define ElfW_Rel ElfW(Rel)
# define SHT_RELX SHT_REL
# define REL_SECTION_FMT ".rel%s"
#endif
/* ------------ xxx-gen.c ------------ */ /* ------------ xxx-gen.c ------------ */
ST_FUNC void gsym_addr(int t, int a); ST_FUNC void gsym_addr(int t, int a);
@ -1319,7 +1322,7 @@ ST_FUNC void asm_clobber(uint8_t *clobber_regs, const char *str);
#ifdef TCC_TARGET_PE #ifdef TCC_TARGET_PE
ST_FUNC int pe_load_file(struct TCCState *s1, const char *filename, int fd); ST_FUNC int pe_load_file(struct TCCState *s1, const char *filename, int fd);
ST_FUNC int pe_output_file(TCCState * s1, const char *filename); ST_FUNC int pe_output_file(TCCState * s1, const char *filename);
ST_FUNC int pe_putimport(TCCState *s1, int dllindex, const char *name, const void *value); ST_FUNC int pe_putimport(TCCState *s1, int dllindex, const char *name, addr_t value);
ST_FUNC SValue *pe_getimport(SValue *sv, SValue *v2); ST_FUNC SValue *pe_getimport(SValue *sv, SValue *v2);
/* tiny_impdef.c */ /* tiny_impdef.c */
ST_FUNC char *get_export_names(FILE *fp); ST_FUNC char *get_export_names(FILE *fp);
@ -1329,6 +1332,7 @@ ST_FUNC void pe_add_unwind_data(unsigned start, unsigned end, unsigned stack);
#endif #endif
/* ------------ tccrun.c ----------------- */ /* ------------ tccrun.c ----------------- */
#ifdef TCC_IS_NATIVE
#ifdef CONFIG_TCC_STATIC #ifdef CONFIG_TCC_STATIC
#define RTLD_LAZY 0x001 #define RTLD_LAZY 0x001
#define RTLD_NOW 0x002 #define RTLD_NOW 0x002
@ -1339,7 +1343,7 @@ ST_FUNC void *dlopen(const char *filename, int flag);
ST_FUNC void dlclose(void *p); ST_FUNC void dlclose(void *p);
//ST_FUNC const char *dlerror(void); //ST_FUNC const char *dlerror(void);
ST_FUNC void *resolve_sym(TCCState *s1, const char *symbol); ST_FUNC void *resolve_sym(TCCState *s1, const char *symbol);
#elif !defined TCC_TARGET_PE || !defined _WIN32 #elif !defined _WIN32
ST_FUNC void *resolve_sym(TCCState *s1, const char *symbol); ST_FUNC void *resolve_sym(TCCState *s1, const char *symbol);
#endif #endif
@ -1349,6 +1353,7 @@ ST_DATA const char **rt_bound_error_msg;
ST_DATA void *rt_prog_main; ST_DATA void *rt_prog_main;
PUB_FUNC void tcc_set_num_callers(int n); PUB_FUNC void tcc_set_num_callers(int n);
#endif #endif
#endif
/********************************************************/ /********************************************************/
/* include the target specific definitions */ /* include the target specific definitions */

View File

@ -933,7 +933,7 @@ ST_FUNC int tcc_load_coff(TCCState * s1, int fd)
if (name[0] == '_' && strcmp(name, "_main") != 0) if (name[0] == '_' && strcmp(name, "_main") != 0)
name++; name++;
tcc_add_symbol(s1, name, (void*)(uplong)csym.n_value); tcc_add_symbol(s1, name, (void*)(uintptr_t)csym.n_value);
} }
// skip any aux records // skip any aux records

View File

@ -84,7 +84,7 @@ static void rebuild_hash(Section *s, unsigned int nb_buckets)
} }
/* return the symbol number */ /* return the symbol number */
ST_FUNC int put_elf_sym(Section *s, uplong value, unsigned long size, ST_FUNC int put_elf_sym(Section *s, addr_t value, unsigned long size,
int info, int other, int shndx, const char *name) int info, int other, int shndx, const char *name)
{ {
int name_offset, sym_index; int name_offset, sym_index;
@ -157,7 +157,7 @@ ST_FUNC int find_elf_sym(Section *s, const char *name)
} }
/* return elf symbol value, signal error if 'err' is nonzero */ /* return elf symbol value, signal error if 'err' is nonzero */
static void *get_elf_sym_addr(TCCState *s, const char *name, int err) ST_FUNC addr_t get_elf_sym_addr(TCCState *s, const char *name, int err)
{ {
int sym_index; int sym_index;
ElfW(Sym) *sym; ElfW(Sym) *sym;
@ -167,26 +167,28 @@ static void *get_elf_sym_addr(TCCState *s, const char *name, int err)
if (!sym_index || sym->st_shndx == SHN_UNDEF) { if (!sym_index || sym->st_shndx == SHN_UNDEF) {
if (err) if (err)
tcc_error("%s not defined", name); tcc_error("%s not defined", name);
return NULL; return 0;
} }
return (void*)(uplong)sym->st_value; return sym->st_value;
} }
#ifdef TCC_IS_NATIVE
/* return elf symbol value */ /* return elf symbol value */
LIBTCCAPI void *tcc_get_symbol(TCCState *s, const char *name) LIBTCCAPI void *tcc_get_symbol(TCCState *s, const char *name)
{ {
return get_elf_sym_addr(s, name, 0); return (void*)get_elf_sym_addr(s, name, 0);
} }
/* return elf symbol value or error */ /* return elf symbol value or error */
ST_FUNC void *tcc_get_symbol_err(TCCState *s, const char *name) ST_FUNC void* tcc_get_symbol_err(TCCState *s, const char *name)
{ {
return get_elf_sym_addr(s, name, 1); return (void*)get_elf_sym_addr(s, name, 1);
} }
#endif
/* add an elf symbol : check if it is already defined and patch /* add an elf symbol : check if it is already defined and patch
it. Return symbol index. NOTE that sh_num can be SHN_UNDEF. */ it. Return symbol index. NOTE that sh_num can be SHN_UNDEF. */
ST_FUNC int add_elf_sym(Section *s, uplong value, unsigned long size, ST_FUNC int add_elf_sym(Section *s, addr_t value, unsigned long size,
int info, int other, int sh_num, const char *name) int info, int other, int sh_num, const char *name)
{ {
ElfW(Sym) *esym; ElfW(Sym) *esym;
@ -431,12 +433,12 @@ ST_FUNC void relocate_syms(TCCState *s1, int do_resolve)
if (sh_num == SHN_UNDEF) { if (sh_num == SHN_UNDEF) {
name = strtab_section->data + sym->st_name; name = strtab_section->data + sym->st_name;
if (do_resolve) { if (do_resolve) {
#if !defined TCC_TARGET_PE || !defined _WIN32 #if defined TCC_IS_NATIVE && !defined _WIN32
void *addr; void *addr;
name = symtab_section->link->data + sym->st_name; name = symtab_section->link->data + sym->st_name;
addr = resolve_sym(s1, name); addr = resolve_sym(s1, name);
if (addr) { if (addr) {
sym->st_value = (uplong)addr; sym->st_value = (addr_t)addr;
goto found; goto found;
} }
#endif #endif
@ -469,10 +471,10 @@ ST_FUNC void relocate_syms(TCCState *s1, int do_resolve)
} }
} }
#ifndef TCC_TARGET_PE #ifdef TCC_HAS_RUNTIME_PLTGOT
#ifdef TCC_TARGET_X86_64 #ifdef TCC_TARGET_X86_64
#define JMP_TABLE_ENTRY_SIZE 14 #define JMP_TABLE_ENTRY_SIZE 14
static uplong add_jmp_table(TCCState *s1, uplong val) static addr_t add_jmp_table(TCCState *s1, addr_t val)
{ {
char *p = s1->runtime_plt_and_got + s1->runtime_plt_and_got_offset; char *p = s1->runtime_plt_and_got + s1->runtime_plt_and_got_offset;
s1->runtime_plt_and_got_offset += JMP_TABLE_ENTRY_SIZE; s1->runtime_plt_and_got_offset += JMP_TABLE_ENTRY_SIZE;
@ -480,30 +482,30 @@ static uplong add_jmp_table(TCCState *s1, uplong val)
p[0] = 0xff; p[0] = 0xff;
p[1] = 0x25; p[1] = 0x25;
*(int *)(p + 2) = 0; *(int *)(p + 2) = 0;
*(uplong *)(p + 6) = val; *(addr_t *)(p + 6) = val;
return (uplong)p; return (addr_t)p;
} }
static uplong add_got_table(TCCState *s1, uplong val) static addr_t add_got_table(TCCState *s1, addr_t val)
{ {
uplong *p = (uplong *)(s1->runtime_plt_and_got + s1->runtime_plt_and_got_offset); addr_t *p = (addr_t *)(s1->runtime_plt_and_got + s1->runtime_plt_and_got_offset);
s1->runtime_plt_and_got_offset += sizeof(uplong); s1->runtime_plt_and_got_offset += sizeof(addr_t);
*p = val; *p = val;
return (uplong)p; return (addr_t)p;
} }
#elif defined TCC_TARGET_ARM #elif defined TCC_TARGET_ARM
#define JMP_TABLE_ENTRY_SIZE 8 #define JMP_TABLE_ENTRY_SIZE 8
static uplong add_jmp_table(TCCState *s1, int val) static addr_t add_jmp_table(TCCState *s1, int val)
{ {
uint32_t *p = (uint32_t *)(s1->runtime_plt_and_got + s1->runtime_plt_and_got_offset); uint32_t *p = (uint32_t *)(s1->runtime_plt_and_got + s1->runtime_plt_and_got_offset);
s1->runtime_plt_and_got_offset += JMP_TABLE_ENTRY_SIZE; s1->runtime_plt_and_got_offset += JMP_TABLE_ENTRY_SIZE;
/* ldr pc, [pc, #-4] */ /* ldr pc, [pc, #-4] */
p[0] = 0xE51FF004; p[0] = 0xE51FF004;
p[1] = val; p[1] = val;
return (uplong)p; return (addr_t)p;
} }
#endif #endif
#endif #endif /* def TCC_HAS_RUNTIME_PLTGOT */
/* relocate a given section (CPU dependent) */ /* relocate a given section (CPU dependent) */
ST_FUNC void relocate_section(TCCState *s1, Section *s) ST_FUNC void relocate_section(TCCState *s1, Section *s)
@ -513,7 +515,7 @@ ST_FUNC void relocate_section(TCCState *s1, Section *s)
ElfW(Sym) *sym; ElfW(Sym) *sym;
int type, sym_index; int type, sym_index;
unsigned char *ptr; unsigned char *ptr;
uplong val, addr; addr_t val, addr;
#if defined TCC_TARGET_I386 || defined TCC_TARGET_X86_64 #if defined TCC_TARGET_I386 || defined TCC_TARGET_X86_64
int esym_index; int esym_index;
#endif #endif
@ -612,13 +614,14 @@ ST_FUNC void relocate_section(TCCState *s1, Section *s)
is_call = (type == R_ARM_CALL); is_call = (type == R_ARM_CALL);
x += val - addr; x += val - addr;
h = x & 2; h = x & 2;
#ifndef TCC_TARGET_PE #ifdef TCC_HAS_RUNTIME_PLTGOT
if ((x & 3) || x >= 0x2000000 || x < -0x2000000) if (s1->output_type == TCC_OUTPUT_MEMORY) {
if (!(x & 3) || !blx_avail || !is_call) if ((x & 3) || x >= 0x2000000 || x < -0x2000000)
if (s1->output_type == TCC_OUTPUT_MEMORY) { if (!(x & 3) || !blx_avail || !is_call) {
x += add_jmp_table(s1, val) - val; /* add veneer */ x += add_jmp_table(s1, val) - val; /* add veneer */
is_thumb = 0; /* Veneer uses ARM instructions */ is_thumb = 0; /* Veneer uses ARM instructions */
} }
}
#endif #endif
if ((x & 3) || x >= 0x2000000 || x < -0x2000000) if ((x & 3) || x >= 0x2000000 || x < -0x2000000)
if (!(x & 3) || !blx_avail || !is_call) if (!(x & 3) || !blx_avail || !is_call)
@ -770,8 +773,8 @@ ST_FUNC void relocate_section(TCCState *s1, Section *s)
*(int*)ptr ^= 0xE12FFF10 ^ 0xE1A0F000; /* BX Rm -> MOV PC, Rm */ *(int*)ptr ^= 0xE12FFF10 ^ 0xE1A0F000; /* BX Rm -> MOV PC, Rm */
break; break;
default: default:
fprintf(stderr,"FIXME: handle reloc type %x at %x [%.8x] to %x\n", fprintf(stderr,"FIXME: handle reloc type %x at %x [%p] to %x\n",
type, (unsigned)addr, (unsigned)(uplong)ptr, (unsigned)val); type, (unsigned)addr, ptr, (unsigned)val);
break; break;
#elif defined(TCC_TARGET_C67) #elif defined(TCC_TARGET_C67)
case R_C60_32: case R_C60_32:
@ -796,8 +799,8 @@ ST_FUNC void relocate_section(TCCState *s1, Section *s)
case R_C60HI16: case R_C60HI16:
break; break;
default: default:
fprintf(stderr,"FIXME: handle reloc type %x at %x [%.8x] to %x\n", fprintf(stderr,"FIXME: handle reloc type %x at %x [%p] to %x\n",
type, (unsigned)addr, (unsigned)(uplong)ptr, (unsigned)val); type, (unsigned)addr, ptr, (unsigned)val);
break; break;
#elif defined(TCC_TARGET_X86_64) #elif defined(TCC_TARGET_X86_64)
case R_X86_64_64: case R_X86_64_64:
@ -837,7 +840,7 @@ ST_FUNC void relocate_section(TCCState *s1, Section *s)
long long diff; long long diff;
diff = (long long)val - addr; diff = (long long)val - addr;
if (diff <= -2147483647 || diff > 2147483647) { if (diff <= -2147483647 || diff > 2147483647) {
#ifndef TCC_TARGET_PE #ifdef TCC_HAS_RUNTIME_PLTGOT
/* XXX: naive support for over 32bit jump */ /* XXX: naive support for over 32bit jump */
if (s1->output_type == TCC_OUTPUT_MEMORY) { if (s1->output_type == TCC_OUTPUT_MEMORY) {
val = (add_jmp_table(s1, val - rel->r_addend) + val = (add_jmp_table(s1, val - rel->r_addend) +
@ -858,7 +861,7 @@ ST_FUNC void relocate_section(TCCState *s1, Section *s)
*(int *)ptr = val - rel->r_addend; *(int *)ptr = val - rel->r_addend;
break; break;
case R_X86_64_GOTPCREL: case R_X86_64_GOTPCREL:
#ifndef TCC_TARGET_PE #ifdef TCC_HAS_RUNTIME_PLTGOT
if (s1->output_type == TCC_OUTPUT_MEMORY) { if (s1->output_type == TCC_OUTPUT_MEMORY) {
val = add_got_table(s1, val - rel->r_addend) + rel->r_addend; val = add_got_table(s1, val - rel->r_addend) + rel->r_addend;
*(int *)ptr += val - addr; *(int *)ptr += val - addr;
@ -1275,7 +1278,7 @@ ST_FUNC Section *new_symtab(TCCState *s1,
} }
/* put dynamic tag */ /* put dynamic tag */
static void put_dt(Section *dynamic, int dt, uplong val) static void put_dt(Section *dynamic, int dt, addr_t val)
{ {
ElfW(Dyn) *dyn; ElfW(Dyn) *dyn;
dyn = section_ptr_add(dynamic, sizeof(ElfW(Dyn))); dyn = section_ptr_add(dynamic, sizeof(ElfW(Dyn)));
@ -1545,7 +1548,7 @@ static int elf_output_file(TCCState *s1, const char *filename)
int *section_order; int *section_order;
int shnum, i, phnum, file_offset, offset, size, j, sh_order_index, k; int shnum, i, phnum, file_offset, offset, size, j, sh_order_index, k;
long long tmp; long long tmp;
uplong addr; addr_t addr;
Section *strsec, *s; Section *strsec, *s;
ElfW(Shdr) shdr, *sh; ElfW(Shdr) shdr, *sh;
ElfW(Phdr) *phdr, *ph; ElfW(Phdr) *phdr, *ph;
@ -1553,9 +1556,9 @@ static int elf_output_file(TCCState *s1, const char *filename)
unsigned long saved_dynamic_data_offset; unsigned long saved_dynamic_data_offset;
ElfW(Sym) *sym; ElfW(Sym) *sym;
int type, file_type; int type, file_type;
uplong rel_addr, rel_size; addr_t rel_addr, rel_size;
#if defined(__FreeBSD__) || defined(__FreeBSD_kernel__) #if defined(__FreeBSD__) || defined(__FreeBSD_kernel__)
uplong bss_addr, bss_size; addr_t bss_addr, bss_size;
#endif #endif
file_type = s1->output_type; file_type = s1->output_type;
@ -2191,7 +2194,7 @@ static int elf_output_file(TCCState *s1, const char *filename)
/* get entry point address */ /* get entry point address */
if (file_type == TCC_OUTPUT_EXE) if (file_type == TCC_OUTPUT_EXE)
ehdr.e_entry = (uplong)tcc_get_symbol_err(s1, "_start"); ehdr.e_entry = get_elf_sym_addr(s1, "_start", 1);
else else
ehdr.e_entry = text_section->sh_addr; /* XXX: is it correct ? */ ehdr.e_entry = text_section->sh_addr; /* XXX: is it correct ? */
} }

14
tccpe.c
View File

@ -1,4 +1,4 @@
/* /*
* TCCPE.C - PE file output for the Tiny C Compiler * TCCPE.C - PE file output for the Tiny C Compiler
* *
* Copyright (c) 2005-2007 grischka * Copyright (c) 2005-2007 grischka
@ -1480,11 +1480,11 @@ ST_FUNC SValue *pe_getimport(SValue *sv, SValue *v2)
return v2; return v2;
} }
ST_FUNC int pe_putimport(TCCState *s1, int dllindex, const char *name, const void *value) ST_FUNC int pe_putimport(TCCState *s1, int dllindex, const char *name, addr_t value)
{ {
return add_elf_sym( return add_elf_sym(
s1->dynsymtab_section, s1->dynsymtab_section,
(uplong)value, value,
dllindex, /* st_size */ dllindex, /* st_size */
ELFW(ST_INFO)(STB_GLOBAL, STT_NOTYPE), ELFW(ST_INFO)(STB_GLOBAL, STT_NOTYPE),
0, 0,
@ -1613,7 +1613,7 @@ static int pe_load_def(TCCState *s1, FILE *fp)
++state; ++state;
default: default:
pe_putimport(s1, dllindex, p, NULL); pe_putimport(s1, dllindex, p, 0);
continue; continue;
} }
} }
@ -1635,7 +1635,7 @@ static int pe_load_dll(TCCState *s1, const char *dllname, FILE *fp)
return -1; return -1;
index = add_dllref(s1, dllname); index = add_dllref(s1, dllname);
for (q = p; *q; q += 1 + strlen(q)) for (q = p; *q; q += 1 + strlen(q))
pe_putimport(s1, index, q, NULL); pe_putimport(s1, index, q, 0);
tcc_free(p); tcc_free(p);
return 0; return 0;
} }
@ -1729,7 +1729,7 @@ ST_FUNC void pe_add_unwind_data(unsigned start, unsigned end, unsigned stack)
static void pe_add_runtime_ex(TCCState *s1, struct pe_info *pe) static void pe_add_runtime_ex(TCCState *s1, struct pe_info *pe)
{ {
const char *start_symbol; const char *start_symbol;
unsigned long addr = 0; ADDR3264 addr = 0;
int pe_type = 0; int pe_type = 0;
if (find_elf_sym(symtab_section, PE_STDSYM("WinMain","@16"))) if (find_elf_sym(symtab_section, PE_STDSYM("WinMain","@16")))
@ -1781,7 +1781,7 @@ static void pe_add_runtime_ex(TCCState *s1, struct pe_info *pe)
pe_type = PE_RUN; pe_type = PE_RUN;
if (start_symbol) { if (start_symbol) {
addr = (uplong)tcc_get_symbol_err(s1, start_symbol); addr = get_elf_sym_addr(s1, start_symbol, 1);
if (PE_RUN == pe_type && addr) if (PE_RUN == pe_type && addr)
/* for -run GUI's, put '_runwinmain' instead of 'main' */ /* for -run GUI's, put '_runwinmain' instead of 'main' */
add_elf_sym(symtab_section, add_elf_sym(symtab_section,

View File

@ -35,7 +35,7 @@ ST_DATA void *rt_prog_main;
static void set_pages_executable(void *ptr, unsigned long length); static void set_pages_executable(void *ptr, unsigned long length);
static void set_exception_handler(void); static void set_exception_handler(void);
static int rt_get_caller_pc(uplong *paddr, ucontext_t *uc, int level); static int rt_get_caller_pc(addr_t *paddr, ucontext_t *uc, int level);
static void rt_error(ucontext_t *uc, const char *fmt, ...); static void rt_error(ucontext_t *uc, const char *fmt, ...);
static int tcc_relocate_ex(TCCState *s1, void *ptr); static int tcc_relocate_ex(TCCState *s1, void *ptr);
@ -127,7 +127,7 @@ static int tcc_relocate_ex(TCCState *s1, void *ptr)
{ {
Section *s; Section *s;
unsigned long offset, length; unsigned long offset, length;
uplong mem; addr_t mem;
int i; int i;
if (0 == s1->runtime_added) { if (0 == s1->runtime_added) {
@ -145,7 +145,7 @@ static int tcc_relocate_ex(TCCState *s1, void *ptr)
return -1; return -1;
} }
offset = 0, mem = (uplong)ptr; offset = 0, mem = (addr_t)ptr;
for(i = 1; i < s1->nb_sections; i++) { for(i = 1; i < s1->nb_sections; i++) {
s = s1->sections[i]; s = s1->sections[i];
if (0 == (s->sh_flags & SHF_ALLOC)) if (0 == (s->sh_flags & SHF_ALLOC))
@ -161,7 +161,7 @@ static int tcc_relocate_ex(TCCState *s1, void *ptr)
if (s1->nb_errors) if (s1->nb_errors)
return -1; return -1;
#if (defined TCC_TARGET_X86_64 || defined TCC_TARGET_ARM) && !defined TCC_TARGET_PE #ifdef TCC_HAS_RUNTIME_PLTGOT
s1->runtime_plt_and_got_offset = 0; s1->runtime_plt_and_got_offset = 0;
s1->runtime_plt_and_got = (char *)(mem + offset); s1->runtime_plt_and_got = (char *)(mem + offset);
/* double the size of the buffer for got and plt entries /* double the size of the buffer for got and plt entries
@ -185,7 +185,7 @@ static int tcc_relocate_ex(TCCState *s1, void *ptr)
continue; continue;
length = s->data_offset; length = s->data_offset;
// printf("%-12s %08x %04x\n", s->name, s->sh_addr, length); // printf("%-12s %08x %04x\n", s->name, s->sh_addr, length);
ptr = (void*)(uplong)s->sh_addr; ptr = (void*)s->sh_addr;
if (NULL == s->data || s->sh_type == SHT_NOBITS) if (NULL == s->data || s->sh_type == SHT_NOBITS)
memset(ptr, 0, length); memset(ptr, 0, length);
else else
@ -195,7 +195,7 @@ static int tcc_relocate_ex(TCCState *s1, void *ptr)
set_pages_executable(ptr, length); set_pages_executable(ptr, length);
} }
#if (defined TCC_TARGET_X86_64 || defined TCC_TARGET_ARM) && !defined TCC_TARGET_PE #ifdef TCC_HAS_RUNTIME_PLTGOT
set_pages_executable(s1->runtime_plt_and_got, set_pages_executable(s1->runtime_plt_and_got,
s1->runtime_plt_and_got_offset); s1->runtime_plt_and_got_offset);
#endif #endif
@ -215,17 +215,15 @@ static void set_pages_executable(void *ptr, unsigned long length)
unsigned long old_protect; unsigned long old_protect;
VirtualProtect(ptr, length, PAGE_EXECUTE_READWRITE, &old_protect); VirtualProtect(ptr, length, PAGE_EXECUTE_READWRITE, &old_protect);
#else #else
unsigned long start, end; addr_t start, end;
start = (uplong)ptr & ~(PAGESIZE - 1); start = (addr_t)ptr & ~(PAGESIZE - 1);
end = (uplong)ptr + length; end = (addr_t)ptr + length;
end = (end + PAGESIZE - 1) & ~(PAGESIZE - 1); end = (end + PAGESIZE - 1) & ~(PAGESIZE - 1);
mprotect((void *)start, end - start, PROT_READ | PROT_WRITE | PROT_EXEC); mprotect((void *)start, end - start, PROT_READ | PROT_WRITE | PROT_EXEC);
#endif #endif
} }
/* ------------------------------------------------------------- */ /* ------------------------------------------------------------- */
#endif /* TCC_IS_NATIVE */
#ifdef CONFIG_TCC_BACKTRACE #ifdef CONFIG_TCC_BACKTRACE
PUB_FUNC void tcc_set_num_callers(int n) PUB_FUNC void tcc_set_num_callers(int n)
@ -235,10 +233,10 @@ PUB_FUNC void tcc_set_num_callers(int n)
/* print the position in the source file of PC value 'pc' by reading /* print the position in the source file of PC value 'pc' by reading
the stabs debug information */ the stabs debug information */
static uplong rt_printline(uplong wanted_pc, const char *msg) static addr_t rt_printline(addr_t wanted_pc, const char *msg)
{ {
char func_name[128], last_func_name[128]; char func_name[128], last_func_name[128];
uplong func_addr, last_pc, pc; addr_t func_addr, last_pc, pc;
const char *incl_files[INCLUDE_STACK_SIZE]; const char *incl_files[INCLUDE_STACK_SIZE];
int incl_index, len, last_line_num, i; int incl_index, len, last_line_num, i;
const char *str, *p; const char *str, *p;
@ -257,7 +255,7 @@ static uplong rt_printline(uplong wanted_pc, const char *msg)
func_addr = 0; func_addr = 0;
incl_index = 0; incl_index = 0;
last_func_name[0] = '\0'; last_func_name[0] = '\0';
last_pc = (uplong)-1; last_pc = (addr_t)-1;
last_line_num = 1; last_line_num = 1;
if (!stab_sym) if (!stab_sym)
@ -380,7 +378,7 @@ no_stabs:
static void rt_error(ucontext_t *uc, const char *fmt, ...) static void rt_error(ucontext_t *uc, const char *fmt, ...)
{ {
va_list ap; va_list ap;
uplong pc; addr_t pc;
int i; int i;
fprintf(stderr, "Runtime error: "); fprintf(stderr, "Runtime error: ");
@ -393,7 +391,7 @@ static void rt_error(ucontext_t *uc, const char *fmt, ...)
if (rt_get_caller_pc(&pc, uc, i) < 0) if (rt_get_caller_pc(&pc, uc, i) < 0)
break; break;
pc = rt_printline(pc, i ? "by" : "at"); pc = rt_printline(pc, i ? "by" : "at");
if (pc == (uplong)rt_prog_main && pc) if (pc == (addr_t)rt_prog_main && pc)
break; break;
} }
} }
@ -464,7 +462,7 @@ static void set_exception_handler(void)
#endif #endif
/* return the PC at frame level 'level'. Return non zero if not found */ /* return the PC at frame level 'level'. Return non zero if not found */
static int rt_get_caller_pc(unsigned long *paddr, ucontext_t *uc, int level) static int rt_get_caller_pc(addr_t *paddr, ucontext_t *uc, int level)
{ {
unsigned long fp; unsigned long fp;
int i; int i;
@ -634,17 +632,17 @@ static void set_exception_handler(void)
static void win64_add_function_table(TCCState *s1) static void win64_add_function_table(TCCState *s1)
{ {
RtlAddFunctionTable( RtlAddFunctionTable(
(RUNTIME_FUNCTION*)(uplong)s1->uw_pdata->sh_addr, (RUNTIME_FUNCTION*)s1->uw_pdata->sh_addr,
s1->uw_pdata->data_offset / sizeof (RUNTIME_FUNCTION), s1->uw_pdata->data_offset / sizeof (RUNTIME_FUNCTION),
(uplong)text_section->sh_addr text_section->sh_addr
); );
} }
#endif #endif
/* return the PC at frame level 'level'. Return non zero if not found */ /* return the PC at frame level 'level'. Return non zero if not found */
static int rt_get_caller_pc(uplong *paddr, CONTEXT *uc, int level) static int rt_get_caller_pc(addr_t *paddr, CONTEXT *uc, int level)
{ {
uplong fp, pc; addr_t fp, pc;
int i; int i;
#ifdef _WIN64 #ifdef _WIN64
pc = uc->Rip; pc = uc->Rip;
@ -658,9 +656,9 @@ static int rt_get_caller_pc(uplong *paddr, CONTEXT *uc, int level)
/* XXX: check address validity with program info */ /* XXX: check address validity with program info */
if (fp <= 0x1000 || fp >= 0xc0000000) if (fp <= 0x1000 || fp >= 0xc0000000)
return -1; return -1;
fp = ((uplong*)fp)[0]; fp = ((addr_t*)fp)[0];
} }
pc = ((uplong*)fp)[1]; pc = ((addr_t*)fp)[1];
} }
*paddr = pc; *paddr = pc;
return 0; return 0;
@ -730,5 +728,5 @@ ST_FUNC void *resolve_sym(TCCState *s1, const char *sym)
} }
#endif /* CONFIG_TCC_STATIC */ #endif /* CONFIG_TCC_STATIC */
#endif /* TCC_IS_NATIVE */
/* ------------------------------------------------------------- */ /* ------------------------------------------------------------- */