mirror of
https://github.com/mirror/tinycc.git
synced 2025-04-01 12:30:08 +08:00
Add support for runtime selection of float ABI
This commit is contained in:
parent
70a088af87
commit
b6247d1f3c
@ -18,6 +18,7 @@ Features:
|
|||||||
- improved variable length array support (James Lyon)
|
- improved variable length array support (James Lyon)
|
||||||
- add the possibility to use noname functions by ordinal (YX Hao)
|
- add the possibility to use noname functions by ordinal (YX Hao)
|
||||||
- add a install-strip target to install tcc (Thomas Preud'homme)
|
- add a install-strip target to install tcc (Thomas Preud'homme)
|
||||||
|
- add runtime selection of float ABI on ARM (Thomas Preud'homme)
|
||||||
|
|
||||||
Platforms:
|
Platforms:
|
||||||
- support Debian GNU/kfreeBSD 64bit userspace (Thomas Preud'homme)
|
- support Debian GNU/kfreeBSD 64bit userspace (Thomas Preud'homme)
|
||||||
|
131
arm-gen.c
131
arm-gen.c
@ -141,6 +141,13 @@ enum {
|
|||||||
#define ELF_START_ADDR 0x00008000
|
#define ELF_START_ADDR 0x00008000
|
||||||
#define ELF_PAGE_SIZE 0x1000
|
#define ELF_PAGE_SIZE 0x1000
|
||||||
|
|
||||||
|
enum float_abi {
|
||||||
|
ARM_SOFTFP_FLOAT,
|
||||||
|
ARM_HARD_FLOAT,
|
||||||
|
};
|
||||||
|
|
||||||
|
enum float_abi float_abi;
|
||||||
|
|
||||||
/******************************************************/
|
/******************************************************/
|
||||||
#else /* ! TARGET_DEFS_ONLY */
|
#else /* ! TARGET_DEFS_ONLY */
|
||||||
/******************************************************/
|
/******************************************************/
|
||||||
@ -169,7 +176,7 @@ static int leaffunc;
|
|||||||
|
|
||||||
#if defined(TCC_ARM_EABI) && defined(TCC_ARM_VFP)
|
#if defined(TCC_ARM_EABI) && defined(TCC_ARM_VFP)
|
||||||
static CType float_type, double_type, func_float_type, func_double_type;
|
static CType float_type, double_type, func_float_type, func_double_type;
|
||||||
ST_FUNC void arm_init_types(void)
|
ST_FUNC void arm_init(struct TCCState *s)
|
||||||
{
|
{
|
||||||
float_type.t = VT_FLOAT;
|
float_type.t = VT_FLOAT;
|
||||||
double_type.t = VT_DOUBLE;
|
double_type.t = VT_DOUBLE;
|
||||||
@ -177,12 +184,14 @@ ST_FUNC void arm_init_types(void)
|
|||||||
func_float_type.ref = sym_push(SYM_FIELD, &float_type, FUNC_CDECL, FUNC_OLD);
|
func_float_type.ref = sym_push(SYM_FIELD, &float_type, FUNC_CDECL, FUNC_OLD);
|
||||||
func_double_type.t = VT_FUNC;
|
func_double_type.t = VT_FUNC;
|
||||||
func_double_type.ref = sym_push(SYM_FIELD, &double_type, FUNC_CDECL, FUNC_OLD);
|
func_double_type.ref = sym_push(SYM_FIELD, &double_type, FUNC_CDECL, FUNC_OLD);
|
||||||
|
|
||||||
|
float_abi = s->float_abi;
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
#define func_float_type func_old_type
|
#define func_float_type func_old_type
|
||||||
#define func_double_type func_old_type
|
#define func_double_type func_old_type
|
||||||
#define func_ldouble_type func_old_type
|
#define func_ldouble_type func_old_type
|
||||||
ST_FUNC void arm_init_types(void) {}
|
ST_FUNC void arm_init(void) {}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
static int two2mask(int a,int b) {
|
static int two2mask(int a,int b) {
|
||||||
@ -195,6 +204,16 @@ static int regmask(int r) {
|
|||||||
|
|
||||||
/******************************************************/
|
/******************************************************/
|
||||||
|
|
||||||
|
#ifdef TCC_ARM_EABI
|
||||||
|
char *default_elfinterp(struct TCCState *s)
|
||||||
|
{
|
||||||
|
if (s->float_abi == ARM_HARD_FLOAT)
|
||||||
|
return "/lib/ld-linux-armhf.so.3";
|
||||||
|
else
|
||||||
|
return "/lib/ld-linux.so.3";
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
void o(uint32_t i)
|
void o(uint32_t i)
|
||||||
{
|
{
|
||||||
/* this is a good place to start adding big-endian support*/
|
/* this is a good place to start adding big-endian support*/
|
||||||
@ -841,22 +860,19 @@ ST_FUNC int gfunc_sret(CType *vt, int variadic, CType *ret, int *ret_align) {
|
|||||||
#ifdef TCC_ARM_EABI
|
#ifdef TCC_ARM_EABI
|
||||||
int size, align;
|
int size, align;
|
||||||
size = type_size(vt, &align);
|
size = type_size(vt, &align);
|
||||||
#ifdef TCC_ARM_HARDFLOAT
|
if (float_abi == ARM_HARD_FLOAT && !variadic &&
|
||||||
if (!variadic && (is_float(vt->t) || is_hgen_float_aggr(vt))) {
|
(is_float(vt->t) || is_hgen_float_aggr(vt))) {
|
||||||
*ret_align = 8;
|
*ret_align = 8;
|
||||||
ret->ref = NULL;
|
ret->ref = NULL;
|
||||||
ret->t = VT_DOUBLE;
|
ret->t = VT_DOUBLE;
|
||||||
return (size + 7) >> 3;
|
return (size + 7) >> 3;
|
||||||
} else
|
} else if (size <= 4) {
|
||||||
#endif
|
|
||||||
if (size > 4) {
|
|
||||||
return 0;
|
|
||||||
} else {
|
|
||||||
*ret_align = 4;
|
*ret_align = 4;
|
||||||
ret->ref = NULL;
|
ret->ref = NULL;
|
||||||
ret->t = VT_INT;
|
ret->t = VT_INT;
|
||||||
return 1;
|
return 1;
|
||||||
}
|
} else
|
||||||
|
return 0;
|
||||||
#else
|
#else
|
||||||
return 0;
|
return 0;
|
||||||
#endif
|
#endif
|
||||||
@ -1171,9 +1187,11 @@ void gfunc_call(int nb_args)
|
|||||||
int todo;
|
int todo;
|
||||||
struct plan plan;
|
struct plan plan;
|
||||||
|
|
||||||
#ifdef TCC_ARM_HARDFLOAT
|
#ifdef TCC_ARM_EABI
|
||||||
variadic = (vtop[-nb_args].type.ref->c == FUNC_ELLIPSIS);
|
if (float_abi == ARM_HARD_FLOAT) {
|
||||||
corefloat = variadic || floats_in_core_regs(&vtop[-nb_args]);
|
variadic = (vtop[-nb_args].type.ref->c == FUNC_ELLIPSIS);
|
||||||
|
corefloat = variadic || floats_in_core_regs(&vtop[-nb_args]);
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
/* cannot let cpu flags if other instruction are generated. Also avoid leaving
|
/* cannot let cpu flags if other instruction are generated. Also avoid leaving
|
||||||
VT_JMP anywhere except on the top of the stack because it would complicate
|
VT_JMP anywhere except on the top of the stack because it would complicate
|
||||||
@ -1199,9 +1217,9 @@ void gfunc_call(int nb_args)
|
|||||||
gcall_or_jmp(0);
|
gcall_or_jmp(0);
|
||||||
if (args_size)
|
if (args_size)
|
||||||
gadd_sp(args_size); /* pop all parameters passed on the stack */
|
gadd_sp(args_size); /* pop all parameters passed on the stack */
|
||||||
#ifdef TCC_ARM_EABI
|
#if defined(TCC_ARM_EABI) && defined(TCC_ARM_VFP)
|
||||||
#ifdef TCC_ARM_VFP
|
if(float_abi == ARM_SOFTFP_FLOAT && corefloat &&
|
||||||
if(corefloat && is_float(vtop->type.ref->type.t)) {
|
is_float(vtop->type.ref->type.t)) {
|
||||||
if((vtop->type.ref->type.t & VT_BTYPE) == VT_FLOAT) {
|
if((vtop->type.ref->type.t & VT_BTYPE) == VT_FLOAT) {
|
||||||
o(0xEE000A10); /*vmov s0, r0 */
|
o(0xEE000A10); /*vmov s0, r0 */
|
||||||
} else {
|
} else {
|
||||||
@ -1209,7 +1227,6 @@ void gfunc_call(int nb_args)
|
|||||||
o(0xEE201B10); /* vmov.32 d0[1], r1 */
|
o(0xEE201B10); /* vmov.32 d0[1], r1 */
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
#endif
|
#endif
|
||||||
vtop -= nb_args + 1; /* Pop all params and fct address from value stack */
|
vtop -= nb_args + 1; /* Pop all params and fct address from value stack */
|
||||||
leaffunc = 0; /* we are calling a function, so we aren't in a leaf function */
|
leaffunc = 0; /* we are calling a function, so we aren't in a leaf function */
|
||||||
@ -1220,9 +1237,8 @@ void gfunc_prolog(CType *func_type)
|
|||||||
{
|
{
|
||||||
Sym *sym,*sym2;
|
Sym *sym,*sym2;
|
||||||
int n, nf, size, align, struct_ret = 0;
|
int n, nf, size, align, struct_ret = 0;
|
||||||
#ifdef TCC_ARM_HARDFLOAT
|
int addr, pn, sn; /* pn=core, sn=stack */
|
||||||
struct avail_regs avregs = AVAIL_REGS_INITIALIZER;
|
struct avail_regs avregs = AVAIL_REGS_INITIALIZER;
|
||||||
#endif
|
|
||||||
CType ret_type;
|
CType ret_type;
|
||||||
|
|
||||||
sym = func_type->ref;
|
sym = func_type->ref;
|
||||||
@ -1237,11 +1253,11 @@ void gfunc_prolog(CType *func_type)
|
|||||||
struct_ret = 1;
|
struct_ret = 1;
|
||||||
func_vc = 12; /* Offset from fp of the place to store the result */
|
func_vc = 12; /* Offset from fp of the place to store the result */
|
||||||
}
|
}
|
||||||
for(sym2=sym->next;sym2 && (n<4 || nf<16);sym2=sym2->next) {
|
for(sym2 = sym->next; sym2 && (n < 4 || nf < 16); sym2 = sym2->next) {
|
||||||
size = type_size(&sym2->type, &align);
|
size = type_size(&sym2->type, &align);
|
||||||
#ifdef TCC_ARM_HARDFLOAT
|
#ifdef TCC_ARM_EABI
|
||||||
if (!func_var && (is_float(sym2->type.t)
|
if (float_abi == ARM_HARD_FLOAT && !func_var &&
|
||||||
|| is_hgen_float_aggr(&sym2->type))) {
|
(is_float(sym2->type.t) || is_hgen_float_aggr(&sym2->type))) {
|
||||||
int tmpnf = assign_vfpreg(&avregs, align, size);
|
int tmpnf = assign_vfpreg(&avregs, align, size);
|
||||||
tmpnf += (size + 3) / 4;
|
tmpnf += (size + 3) / 4;
|
||||||
nf = (tmpnf > nf) ? tmpnf : nf;
|
nf = (tmpnf > nf) ? tmpnf : nf;
|
||||||
@ -1270,50 +1286,49 @@ void gfunc_prolog(CType *func_type)
|
|||||||
o(0xE92D5800); /* save fp, ip, lr */
|
o(0xE92D5800); /* save fp, ip, lr */
|
||||||
o(0xE1A0B00D); /* mov fp, sp */
|
o(0xE1A0B00D); /* mov fp, sp */
|
||||||
func_sub_sp_offset = ind;
|
func_sub_sp_offset = ind;
|
||||||
o(0xE1A00000); /* nop, leave space for stack adjustment in epilogue */
|
o(0xE1A00000); /* nop, leave space for stack adjustment in epilog */
|
||||||
{
|
|
||||||
int addr, pn = struct_ret, sn = 0; /* pn=core, sn=stack */
|
|
||||||
|
|
||||||
#ifdef TCC_ARM_HARDFLOAT
|
#ifdef TCC_ARM_EABI
|
||||||
|
if (float_abi == ARM_HARD_FLOAT) {
|
||||||
func_vc += nf * 4;
|
func_vc += nf * 4;
|
||||||
avregs = AVAIL_REGS_INITIALIZER;
|
avregs = AVAIL_REGS_INITIALIZER;
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
while ((sym = sym->next)) {
|
pn = struct_ret, sn = 0;
|
||||||
CType *type;
|
while ((sym = sym->next)) {
|
||||||
type = &sym->type;
|
CType *type;
|
||||||
size = type_size(type, &align);
|
type = &sym->type;
|
||||||
size = (size + 3) >> 2;
|
size = type_size(type, &align);
|
||||||
align = (align + 3) & ~3;
|
size = (size + 3) >> 2;
|
||||||
#ifdef TCC_ARM_HARDFLOAT
|
align = (align + 3) & ~3;
|
||||||
if (!func_var && (is_float(sym->type.t)
|
#ifdef TCC_ARM_EABI
|
||||||
|| is_hgen_float_aggr(&sym->type))) {
|
if (float_abi == ARM_HARD_FLOAT && !func_var && (is_float(sym->type.t)
|
||||||
int fpn = assign_vfpreg(&avregs, align, size << 2);
|
|| is_hgen_float_aggr(&sym->type))) {
|
||||||
if (fpn >= 0) {
|
int fpn = assign_vfpreg(&avregs, align, size << 2);
|
||||||
addr = fpn * 4;
|
if (fpn >= 0)
|
||||||
} else
|
addr = fpn * 4;
|
||||||
goto from_stack;
|
else
|
||||||
} else
|
goto from_stack;
|
||||||
|
} else
|
||||||
#endif
|
#endif
|
||||||
if (pn < 4) {
|
if (pn < 4) {
|
||||||
#ifdef TCC_ARM_EABI
|
#ifdef TCC_ARM_EABI
|
||||||
pn = (pn + (align-1)/4) & -(align/4);
|
pn = (pn + (align-1)/4) & -(align/4);
|
||||||
#endif
|
#endif
|
||||||
addr = (nf + pn) * 4;
|
addr = (nf + pn) * 4;
|
||||||
pn += size;
|
pn += size;
|
||||||
if (!sn && pn > 4)
|
if (!sn && pn > 4)
|
||||||
sn = (pn - 4);
|
sn = (pn - 4);
|
||||||
} else {
|
} else {
|
||||||
#ifdef TCC_ARM_HARDFLOAT
|
|
||||||
from_stack:
|
from_stack:
|
||||||
#endif
|
|
||||||
#ifdef TCC_ARM_EABI
|
#ifdef TCC_ARM_EABI
|
||||||
sn = (sn + (align-1)/4) & -(align/4);
|
sn = (sn + (align-1)/4) & -(align/4);
|
||||||
#endif
|
#endif
|
||||||
addr = (n + nf + sn) * 4;
|
addr = (n + nf + sn) * 4;
|
||||||
sn += size;
|
sn += size;
|
||||||
}
|
|
||||||
sym_push(sym->v & ~SYM_FIELD, type, VT_LOCAL | lvalue_type(type->t), addr+12);
|
|
||||||
}
|
}
|
||||||
|
sym_push(sym->v & ~SYM_FIELD, type, VT_LOCAL | lvalue_type(type->t),
|
||||||
|
addr + 12);
|
||||||
}
|
}
|
||||||
last_itod_magic=0;
|
last_itod_magic=0;
|
||||||
leaffunc = 1;
|
leaffunc = 1;
|
||||||
@ -1327,12 +1342,8 @@ void gfunc_epilog(void)
|
|||||||
int diff;
|
int diff;
|
||||||
/* Copy float return value to core register if base standard is used and
|
/* Copy float return value to core register if base standard is used and
|
||||||
float computation is made with VFP */
|
float computation is made with VFP */
|
||||||
#ifdef TCC_ARM_EABI
|
#if defined(TCC_ARM_EABI) && defined(TCC_ARM_VFP)
|
||||||
if (
|
if ((float_abi == ARM_SOFTFP_FLOAT || func_var) && is_float(func_vt.t)) {
|
||||||
#ifdef TCC_ARM_HARDFLOAT
|
|
||||||
func_var &&
|
|
||||||
#endif
|
|
||||||
is_float(func_vt.t)) {
|
|
||||||
if((func_vt.t & VT_BTYPE) == VT_FLOAT)
|
if((func_vt.t & VT_BTYPE) == VT_FLOAT)
|
||||||
o(0xEE100A10); /* fmrs r0, s0 */
|
o(0xEE100A10); /* fmrs r0, s0 */
|
||||||
else {
|
else {
|
||||||
|
25
libtcc.c
25
libtcc.c
@ -757,7 +757,7 @@ static int tcc_compile(TCCState *s1)
|
|||||||
func_old_type.t = VT_FUNC;
|
func_old_type.t = VT_FUNC;
|
||||||
func_old_type.ref = sym_push(SYM_FIELD, &int_type, FUNC_CDECL, FUNC_OLD);
|
func_old_type.ref = sym_push(SYM_FIELD, &int_type, FUNC_CDECL, FUNC_OLD);
|
||||||
#ifdef TCC_TARGET_ARM
|
#ifdef TCC_TARGET_ARM
|
||||||
arm_init_types();
|
arm_init(s1);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if 0
|
#if 0
|
||||||
@ -945,9 +945,12 @@ LIBTCCAPI TCCState *tcc_new(void)
|
|||||||
tcc_define_symbol(s, "__ARMEL__", NULL);
|
tcc_define_symbol(s, "__ARMEL__", NULL);
|
||||||
#if defined(TCC_ARM_EABI)
|
#if defined(TCC_ARM_EABI)
|
||||||
tcc_define_symbol(s, "__ARM_EABI__", NULL);
|
tcc_define_symbol(s, "__ARM_EABI__", NULL);
|
||||||
#if defined(TCC_ARM_HARDFLOAT)
|
|
||||||
tcc_define_symbol(s, "__ARM_PCS_VFP", NULL);
|
|
||||||
#endif
|
#endif
|
||||||
|
#if defined(TCC_ARM_HARDFLOAT)
|
||||||
|
s->float_abi = ARM_HARD_FLOAT;
|
||||||
|
tcc_define_symbol(s, "__ARM_PCS_VFP", NULL);
|
||||||
|
#else
|
||||||
|
s->float_abi = ARM_SOFTFP_FLOAT;
|
||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@ -1628,6 +1631,7 @@ enum {
|
|||||||
TCC_OPTION_b,
|
TCC_OPTION_b,
|
||||||
TCC_OPTION_g,
|
TCC_OPTION_g,
|
||||||
TCC_OPTION_c,
|
TCC_OPTION_c,
|
||||||
|
TCC_OPTION_float_abi,
|
||||||
TCC_OPTION_static,
|
TCC_OPTION_static,
|
||||||
TCC_OPTION_shared,
|
TCC_OPTION_shared,
|
||||||
TCC_OPTION_soname,
|
TCC_OPTION_soname,
|
||||||
@ -1680,6 +1684,9 @@ static const TCCOption tcc_options[] = {
|
|||||||
#endif
|
#endif
|
||||||
{ "g", TCC_OPTION_g, TCC_OPTION_HAS_ARG | TCC_OPTION_NOSEP },
|
{ "g", TCC_OPTION_g, TCC_OPTION_HAS_ARG | TCC_OPTION_NOSEP },
|
||||||
{ "c", TCC_OPTION_c, 0 },
|
{ "c", TCC_OPTION_c, 0 },
|
||||||
|
#ifdef TCC_TARGET_ARM
|
||||||
|
{ "mfloat-abi", TCC_OPTION_float_abi, TCC_OPTION_HAS_ARG },
|
||||||
|
#endif
|
||||||
{ "static", TCC_OPTION_static, 0 },
|
{ "static", TCC_OPTION_static, 0 },
|
||||||
{ "shared", TCC_OPTION_shared, 0 },
|
{ "shared", TCC_OPTION_shared, 0 },
|
||||||
{ "soname", TCC_OPTION_soname, TCC_OPTION_HAS_ARG },
|
{ "soname", TCC_OPTION_soname, TCC_OPTION_HAS_ARG },
|
||||||
@ -1817,6 +1824,18 @@ PUB_FUNC int tcc_parse_args(TCCState *s, int argc, char **argv)
|
|||||||
case TCC_OPTION_c:
|
case TCC_OPTION_c:
|
||||||
s->output_type = TCC_OUTPUT_OBJ;
|
s->output_type = TCC_OUTPUT_OBJ;
|
||||||
break;
|
break;
|
||||||
|
#ifdef TCC_TARGET_ARM
|
||||||
|
case TCC_OPTION_float_abi:
|
||||||
|
/* tcc doesn't support soft float yet */
|
||||||
|
if (!strcmp(optarg, "softfp")) {
|
||||||
|
s->float_abi = ARM_SOFTFP_FLOAT;
|
||||||
|
tcc_undefine_symbol(s, "__ARM_PCS_VFP");
|
||||||
|
} else if (!strcmp(optarg, "hard"))
|
||||||
|
s->float_abi = ARM_HARD_FLOAT;
|
||||||
|
else
|
||||||
|
tcc_error("unsupported float abi '%s'", optarg);
|
||||||
|
break;
|
||||||
|
#endif
|
||||||
case TCC_OPTION_static:
|
case TCC_OPTION_static:
|
||||||
s->static_link = 1;
|
s->static_link = 1;
|
||||||
break;
|
break;
|
||||||
|
@ -176,6 +176,9 @@ In a script, it gives the following header:
|
|||||||
#!/usr/local/bin/tcc -run -L/usr/X11R6/lib -lX11
|
#!/usr/local/bin/tcc -run -L/usr/X11R6/lib -lX11
|
||||||
@end example
|
@end example
|
||||||
|
|
||||||
|
@item -mfloat-abi (ARM only)
|
||||||
|
Select the float ABI. Possible values: @code{softfp} and @code{hard}
|
||||||
|
|
||||||
@item -dumpversion
|
@item -dumpversion
|
||||||
Print only the compiler version and nothing else.
|
Print only the compiler version and nothing else.
|
||||||
|
|
||||||
|
2
tcc.c
2
tcc.c
@ -224,7 +224,7 @@ static void display_info(TCCState *s, int what)
|
|||||||
print_paths("crt", s->crt_paths, s->nb_crt_paths);
|
print_paths("crt", s->crt_paths, s->nb_crt_paths);
|
||||||
print_paths("libraries", s->library_paths, s->nb_library_paths);
|
print_paths("libraries", s->library_paths, s->nb_library_paths);
|
||||||
print_paths("include", s->sysinclude_paths, s->nb_sysinclude_paths);
|
print_paths("include", s->sysinclude_paths, s->nb_sysinclude_paths);
|
||||||
printf("elfinterp:\n %s\n", CONFIG_TCC_ELFINTERP);
|
printf("elfinterp:\n %s\n", DEFAULT_ELFINTERP(s));
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
21
tcc.h
21
tcc.h
@ -221,21 +221,24 @@
|
|||||||
# endif
|
# endif
|
||||||
# elif defined __GNU__
|
# elif defined __GNU__
|
||||||
# define CONFIG_TCC_ELFINTERP "/lib/ld.so"
|
# define CONFIG_TCC_ELFINTERP "/lib/ld.so"
|
||||||
# elif defined TCC_ARM_HARDFLOAT
|
|
||||||
# define CONFIG_TCC_ELFINTERP "/lib/ld-linux-armhf.so.3"
|
|
||||||
# elif defined TCC_ARM_EABI
|
|
||||||
# define CONFIG_TCC_ELFINTERP "/lib/ld-linux.so.3"
|
|
||||||
# elif defined(TCC_TARGET_X86_64)
|
# elif defined(TCC_TARGET_X86_64)
|
||||||
# define CONFIG_TCC_ELFINTERP "/lib64/ld-linux-x86-64.so.2"
|
# define CONFIG_TCC_ELFINTERP "/lib64/ld-linux-x86-64.so.2"
|
||||||
# elif defined(TCC_UCLIBC)
|
# elif defined(TCC_UCLIBC)
|
||||||
# define CONFIG_TCC_ELFINTERP "/lib/ld-uClibc.so.0"
|
# define CONFIG_TCC_ELFINTERP "/lib/ld-uClibc.so.0"
|
||||||
# elif defined(TCC_TARGET_PE)
|
# elif defined(TCC_TARGET_PE)
|
||||||
# define CONFIG_TCC_ELFINTERP "-"
|
# define CONFIG_TCC_ELFINTERP "-"
|
||||||
# else
|
# elif !defined(TCC_ARM_EABI)
|
||||||
# define CONFIG_TCC_ELFINTERP "/lib/ld-linux.so.2"
|
# define CONFIG_TCC_ELFINTERP "/lib/ld-linux.so.2"
|
||||||
# endif
|
# endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
/* var elf_interp dans *-gen.c */
|
||||||
|
#ifdef CONFIG_TCC_ELFINTERP
|
||||||
|
# define DEFAULT_ELFINTERP(s) CONFIG_TCC_ELFINTERP
|
||||||
|
#else
|
||||||
|
# define DEFAULT_ELFINTERP(s) default_elfinterp(s)
|
||||||
|
#endif
|
||||||
|
|
||||||
/* library to use with CONFIG_USE_LIBGCC instead of libtcc1.a */
|
/* library to use with CONFIG_USE_LIBGCC instead of libtcc1.a */
|
||||||
#define TCC_LIBGCC USE_MUADIR(CONFIG_SYSROOT "/" CONFIG_LDDIR) "/libgcc_s.so.1"
|
#define TCC_LIBGCC USE_MUADIR(CONFIG_SYSROOT "/" CONFIG_LDDIR) "/libgcc_s.so.1"
|
||||||
|
|
||||||
@ -561,6 +564,9 @@ struct TCCState {
|
|||||||
/* compile with built-in memory and bounds checker */
|
/* compile with built-in memory and bounds checker */
|
||||||
int do_bounds_check;
|
int do_bounds_check;
|
||||||
#endif
|
#endif
|
||||||
|
#ifdef TCC_TARGET_ARM
|
||||||
|
enum float_abi float_abi; /* float ABI of the generated code*/
|
||||||
|
#endif
|
||||||
|
|
||||||
addr_t text_addr; /* address of text section */
|
addr_t text_addr; /* address of text section */
|
||||||
int has_text_addr;
|
int has_text_addr;
|
||||||
@ -1329,7 +1335,10 @@ ST_FUNC void gen_opl(int op);
|
|||||||
|
|
||||||
/* ------------ arm-gen.c ------------ */
|
/* ------------ arm-gen.c ------------ */
|
||||||
#ifdef TCC_TARGET_ARM
|
#ifdef TCC_TARGET_ARM
|
||||||
ST_FUNC void arm_init_types(void);
|
#ifdef TCC_ARM_EABI
|
||||||
|
ST_FUNC char *default_elfinterp(struct TCCState *s);
|
||||||
|
#endif
|
||||||
|
ST_FUNC void arm_init(struct TCCState *s);
|
||||||
ST_FUNC uint32_t encbranch(int pos, int addr, int fail);
|
ST_FUNC uint32_t encbranch(int pos, int addr, int fail);
|
||||||
ST_FUNC void gen_cvt_itof1(int t);
|
ST_FUNC void gen_cvt_itof1(int t);
|
||||||
#endif
|
#endif
|
||||||
|
2
tccelf.c
2
tccelf.c
@ -1592,7 +1592,7 @@ static int elf_output_file(TCCState *s1, const char *filename)
|
|||||||
/* allow override the dynamic loader */
|
/* allow override the dynamic loader */
|
||||||
const char *elfint = getenv("LD_SO");
|
const char *elfint = getenv("LD_SO");
|
||||||
if (elfint == NULL)
|
if (elfint == NULL)
|
||||||
elfint = CONFIG_TCC_ELFINTERP;
|
elfint = DEFAULT_ELFINTERP(s1);
|
||||||
/* add interpreter section only if executable */
|
/* add interpreter section only if executable */
|
||||||
interp = new_section(s1, ".interp", SHT_PROGBITS, SHF_ALLOC);
|
interp = new_section(s1, ".interp", SHT_PROGBITS, SHF_ALLOC);
|
||||||
interp->sh_addralign = 1;
|
interp->sh_addralign = 1;
|
||||||
|
Loading…
Reference in New Issue
Block a user