Import some changesets from Rob Landley's fork (part 1)

This commit is contained in:
grischka 2007-11-14 17:34:30 +00:00
parent 2bcc187b1b
commit 54bf8c0556
5 changed files with 137 additions and 85 deletions

View file

@ -1,7 +1,21 @@
version 0.9.24: version 0.9.24:
- Fix "invalid relocation entry" problem on ubuntu - from Bernhard Fischer - Import some changesets from Rob Landley's fork (part 1):
http://lists.gnu.org/archive/html/tinycc-devel/2005-09/msg00051.html 462: Use LGPL with bcheck.c and il-gen.c
458: Fix global compound literals (in unary: case '&':) (Andrew Johnson)
456: Use return code from tcc_output_file in main() (Michael Somos)
442: Fix indirections with function pointers (***fn)() (grischka)
441: Fix LL left shift in libtcc1.c:__shldi3 (grischka)
440: Pass structures and function ptrs through ?: (grischka)
439: Keep rvalue in bit assignment (bit2 = bit1 = x) (grischka)
438: Degrade nonportable pointer assignment to warning (grischka)
437: Call 'saveregs()' before jumping with logical and/or/not (grischka)
435: Put local static variables into global memory (grischka)
432/434: Cast double and ptr to bool (grischka)
420: Zero pad x87 tenbyte long doubles (Felix Nawothnig)
417: Make 'sizeof' unsigned (Rob Landley)
397: Fix save_reg for longlongs (Daniel Glöckner)
396: Fix "invalid relocation entry" problem on ubuntu - (Bernhard Fischer)
- ignore AS_NEEDED ld command - ignore AS_NEEDED ld command
- mark executable sections as executable when running in memory - mark executable sections as executable when running in memory

View file

@ -3,19 +3,19 @@
* *
* Copyright (c) 2002 Fabrice Bellard * Copyright (c) 2002 Fabrice Bellard
* *
* This program is free software; you can redistribute it and/or modify * This library is free software; you can redistribute it and/or
* it under the terms of the GNU General Public License as published by * modify it under the terms of the GNU Lesser General Public
* the Free Software Foundation; either version 2 of the License, or * License as published by the Free Software Foundation; either
* (at your option) any later version. * version 2 of the License, or (at your option) any later version.
* *
* This program is distributed in the hope that it will be useful, * This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of * but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* GNU General Public License for more details. * Lesser General Public License for more details.
* *
* You should have received a copy of the GNU General Public License * You should have received a copy of the GNU Lesser General Public
* along with this program; if not, write to the Free Software * License along with this library; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/ */
#include <stdlib.h> #include <stdlib.h>
#include <stdio.h> #include <stdio.h>

View file

@ -3,19 +3,19 @@
* *
* Copyright (c) 2002 Fabrice Bellard * Copyright (c) 2002 Fabrice Bellard
* *
* This program is free software; you can redistribute it and/or modify * This library is free software; you can redistribute it and/or
* it under the terms of the GNU General Public License as published by * modify it under the terms of the GNU Lesser General Public
* the Free Software Foundation; either version 2 of the License, or * License as published by the Free Software Foundation; either
* (at your option) any later version. * version 2 of the License, or (at your option) any later version.
* *
* This program is distributed in the hope that it will be useful, * This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of * but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* GNU General Public License for more details. * Lesser General Public License for more details.
* *
* You should have received a copy of the GNU General Public License * You should have received a copy of the GNU Lesser General Public
* along with this program; if not, write to the Free Software * License along with this library; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/ */
/* number of available registers */ /* number of available registers */

View file

@ -466,7 +466,7 @@ long long __shldi3(long long a, int b)
u.s.high = (unsigned)u.s.low << (b - 32); u.s.high = (unsigned)u.s.low << (b - 32);
u.s.low = 0; u.s.low = 0;
} else if (b != 0) { } else if (b != 0) {
u.s.high = ((unsigned)u.s.high << b) | (u.s.low >> (32 - b)); u.s.high = ((unsigned)u.s.high << b) | ((unsigned)u.s.low >> (32 - b));
u.s.low = (unsigned)u.s.low << b; u.s.low = (unsigned)u.s.low << b;
} }
return u.ll; return u.ll;

74
tcc.c
View file

@ -40,7 +40,7 @@
#include <time.h> #include <time.h>
#ifdef WIN32 #ifdef WIN32
#include <sys/timeb.h> #include <sys/timeb.h>
#include <windows.h> // #include <windows.h>
#endif #endif
#ifndef WIN32 #ifndef WIN32
#include <sys/time.h> #include <sys/time.h>
@ -725,6 +725,8 @@ void *__stdcall GetProcAddress(void *, const char *);
void *__stdcall GetModuleHandleA(const char *); void *__stdcall GetModuleHandleA(const char *);
void *__stdcall LoadLibraryA(const char *); void *__stdcall LoadLibraryA(const char *);
int __stdcall FreeConsole(void); int __stdcall FreeConsole(void);
int __stdcall VirtualProtect(void*,unsigned long,unsigned long,unsigned long*);
#define PAGE_EXECUTE_READWRITE 0x0040
#define snprintf _snprintf #define snprintf _snprintf
#define vsnprintf _vsnprintf #define vsnprintf _vsnprintf
@ -751,7 +753,7 @@ extern long double strtold (const char *__nptr, char **__endptr);
static char *pstrcpy(char *buf, int buf_size, const char *s); static char *pstrcpy(char *buf, int buf_size, const char *s);
static char *pstrcat(char *buf, int buf_size, const char *s); static char *pstrcat(char *buf, int buf_size, const char *s);
static const char *tcc_basename(const char *name); static char *tcc_basename(const char *name);
static void next(void); static void next(void);
static void next_nomacro(void); static void next_nomacro(void);
@ -4596,7 +4598,7 @@ void save_reg(int r)
l = 0; l = 0;
for(p=vstack;p<=vtop;p++) { for(p=vstack;p<=vtop;p++) {
if ((p->r & VT_VALMASK) == r || if ((p->r & VT_VALMASK) == r ||
(p->r2 & VT_VALMASK) == r) { ((p->type.t & VT_BTYPE) == VT_LLONG && (p->r2 & VT_VALMASK) == r)) {
/* must save value on stack if not already done */ /* must save value on stack if not already done */
if (!saved) { if (!saved) {
/* NOTE: must reload 'r' because r might be equal to r2 */ /* NOTE: must reload 'r' because r might be equal to r2 */
@ -4803,6 +4805,11 @@ int gv(int rc)
offset = (data_section->data_offset + align - 1) & -align; offset = (data_section->data_offset + align - 1) & -align;
data_section->data_offset = offset; data_section->data_offset = offset;
/* XXX: not portable yet */ /* XXX: not portable yet */
#ifdef __i386__
/* Zero pad x87 tenbyte long doubles */
if (size == 12)
vtop->c.tab[2] &= 0xffff;
#endif
ptr = section_ptr_add(data_section, size); ptr = section_ptr_add(data_section, size);
size = size >> 2; size = size >> 2;
for(i=0;i<size;i++) for(i=0;i<size;i++)
@ -5852,6 +5859,10 @@ static void gen_cast(CType *type)
} }
} else if (sf) { } else if (sf) {
/* convert fp to int */ /* convert fp to int */
if (dbt == VT_BOOL) {
vpushi(0);
gen_op(TOK_NE);
} else {
/* we handle char/short/etc... with generic code */ /* we handle char/short/etc... with generic code */
if (dbt != (VT_INT | VT_UNSIGNED) && if (dbt != (VT_INT | VT_UNSIGNED) &&
dbt != (VT_LLONG | VT_UNSIGNED) && dbt != (VT_LLONG | VT_UNSIGNED) &&
@ -5884,10 +5895,11 @@ static void gen_cast(CType *type)
gen_cvt_ftoi1(dbt); gen_cvt_ftoi1(dbt);
} }
if (dbt == VT_INT && (type->t & (VT_BTYPE | VT_UNSIGNED)) != dbt) { if (dbt == VT_INT && (type->t & (VT_BTYPE | VT_UNSIGNED)) != dbt) {
/* additional cast for char/short/bool... */ /* additional cast for char/short... */
vtop->type.t = dbt; vtop->type.t = dbt;
gen_cast(type); gen_cast(type);
} }
}
} else if ((dbt & VT_BTYPE) == VT_LLONG) { } else if ((dbt & VT_BTYPE) == VT_LLONG) {
if ((sbt & VT_BTYPE) != VT_LLONG) { if ((sbt & VT_BTYPE) != VT_LLONG) {
/* scalar to long long */ /* scalar to long long */
@ -5919,6 +5931,10 @@ static void gen_cast(CType *type)
gen_op(TOK_NE); gen_op(TOK_NE);
} else if ((dbt & VT_BTYPE) == VT_BYTE || } else if ((dbt & VT_BTYPE) == VT_BYTE ||
(dbt & VT_BTYPE) == VT_SHORT) { (dbt & VT_BTYPE) == VT_SHORT) {
if (sbt == VT_PTR) {
vtop->type.t = VT_INT;
warning("nonportable conversion from pointer to char/short");
}
force_charshort_cast(dbt); force_charshort_cast(dbt);
} else if ((dbt & VT_BTYPE) == VT_INT) { } else if ((dbt & VT_BTYPE) == VT_INT) {
/* scalar to int */ /* scalar to int */
@ -6214,7 +6230,7 @@ static void gen_assign_cast(CType *dt)
tmp_type1.t &= ~(VT_UNSIGNED | VT_CONSTANT | VT_VOLATILE); tmp_type1.t &= ~(VT_UNSIGNED | VT_CONSTANT | VT_VOLATILE);
tmp_type2.t &= ~(VT_UNSIGNED | VT_CONSTANT | VT_VOLATILE); tmp_type2.t &= ~(VT_UNSIGNED | VT_CONSTANT | VT_VOLATILE);
if (!is_compatible_types(&tmp_type1, &tmp_type2)) if (!is_compatible_types(&tmp_type1, &tmp_type2))
goto error; warning("assignment from incompatible pointer type");
} }
/* check const and volatile */ /* check const and volatile */
if ((!(type1->t & VT_CONSTANT) && (type2->t & VT_CONSTANT)) || if ((!(type1->t & VT_CONSTANT) && (type2->t & VT_CONSTANT)) ||
@ -6304,6 +6320,11 @@ void vstore(void)
/* remove bit field info to avoid loops */ /* remove bit field info to avoid loops */
vtop[-1].type.t = ft & ~(VT_BITFIELD | (-1 << VT_STRUCT_SHIFT)); vtop[-1].type.t = ft & ~(VT_BITFIELD | (-1 << VT_STRUCT_SHIFT));
/* duplicate source into other register */
gv_dup();
vswap();
vrott(3);
/* duplicate destination */ /* duplicate destination */
vdup(); vdup();
vtop[-1] = vtop[-2]; vtop[-1] = vtop[-2];
@ -6320,6 +6341,10 @@ void vstore(void)
gen_op('|'); gen_op('|');
/* store result */ /* store result */
vstore(); vstore();
/* pop off shifted source from "duplicate source..." above */
vpop();
} else { } else {
#ifdef CONFIG_TCC_BCHECK #ifdef CONFIG_TCC_BCHECK
/* bound check case */ /* bound check case */
@ -7066,13 +7091,17 @@ static int lvalue_type(int t)
/* indirection with full error checking and bound check */ /* indirection with full error checking and bound check */
static void indir(void) static void indir(void)
{ {
if ((vtop->type.t & VT_BTYPE) != VT_PTR) if ((vtop->type.t & VT_BTYPE) != VT_PTR) {
if ((vtop->type.t & VT_BTYPE) == VT_FUNC)
return;
expect("pointer"); expect("pointer");
}
if ((vtop->r & VT_LVAL) && !nocode_wanted) if ((vtop->r & VT_LVAL) && !nocode_wanted)
gv(RC_INT); gv(RC_INT);
vtop->type = *pointed_type(&vtop->type); vtop->type = *pointed_type(&vtop->type);
/* an array is never an lvalue */ /* Arrays and functions are never lvalues */
if (!(vtop->type.t & VT_ARRAY)) { if (!(vtop->type.t & VT_ARRAY)
&& (vtop->type.t & VT_BTYPE) != VT_FUNC) {
vtop->r |= lvalue_type(vtop->type.t); vtop->r |= lvalue_type(vtop->type.t);
/* if bound checking, the referenced pointer must be checked */ /* if bound checking, the referenced pointer must be checked */
if (do_bounds_check) if (do_bounds_check)
@ -7269,7 +7298,7 @@ static void unary(void)
there and in function calls. */ there and in function calls. */
/* arrays can also be used although they are not lvalues */ /* arrays can also be used although they are not lvalues */
if ((vtop->type.t & VT_BTYPE) != VT_FUNC && if ((vtop->type.t & VT_BTYPE) != VT_FUNC &&
!(vtop->type.t & VT_ARRAY)) !(vtop->type.t & VT_ARRAY) && !(vtop->type.t & VT_LLOCAL))
test_lvalue(); test_lvalue();
mk_pointer(&vtop->type); mk_pointer(&vtop->type);
gaddrof(); gaddrof();
@ -7281,8 +7310,10 @@ static void unary(void)
vtop->c.i = !vtop->c.i; vtop->c.i = !vtop->c.i;
else if ((vtop->r & VT_VALMASK) == VT_CMP) else if ((vtop->r & VT_VALMASK) == VT_CMP)
vtop->c.i = vtop->c.i ^ 1; vtop->c.i = vtop->c.i ^ 1;
else else {
save_regs(1);
vseti(VT_JMP, gtst(1, 0)); vseti(VT_JMP, gtst(1, 0));
}
break; break;
case '~': case '~':
next(); next();
@ -7317,6 +7348,7 @@ static void unary(void)
} else { } else {
vpushi(align); vpushi(align);
} }
vtop->type.t |= VT_UNSIGNED;
break; break;
case TOK_builtin_types_compatible_p: case TOK_builtin_types_compatible_p:
@ -7694,6 +7726,7 @@ static void expr_land(void)
expr_or(); expr_or();
if (tok == TOK_LAND) { if (tok == TOK_LAND) {
t = 0; t = 0;
save_regs(1);
for(;;) { for(;;) {
t = gtst(1, t); t = gtst(1, t);
if (tok != TOK_LAND) { if (tok != TOK_LAND) {
@ -7713,6 +7746,7 @@ static void expr_lor(void)
expr_land(); expr_land();
if (tok == TOK_LOR) { if (tok == TOK_LOR) {
t = 0; t = 0;
save_regs(1);
for(;;) { for(;;) {
t = gtst(0, t); t = gtst(0, t);
if (tok != TOK_LOR) { if (tok != TOK_LOR) {
@ -7824,6 +7858,8 @@ static void expr_eq(void)
/* now we convert second operand */ /* now we convert second operand */
gen_cast(&type); gen_cast(&type);
if (VT_STRUCT == (vtop->type.t & VT_BTYPE))
gaddrof();
rc = RC_INT; rc = RC_INT;
if (is_float(type.t)) { if (is_float(type.t)) {
rc = RC_FLOAT; rc = RC_FLOAT;
@ -7841,6 +7877,8 @@ static void expr_eq(void)
/* put again first value and cast it */ /* put again first value and cast it */
*vtop = sv; *vtop = sv;
gen_cast(&type); gen_cast(&type);
if (VT_STRUCT == (vtop->type.t & VT_BTYPE))
gaddrof();
r1 = gv(rc); r1 = gv(rc);
move_reg(r2, r1); move_reg(r2, r1);
vtop->r = r2; vtop->r = r2;
@ -8440,7 +8478,7 @@ static void init_putv(CType *type, Section *sec, unsigned long c,
} }
vtop--; vtop--;
} else { } else {
vset(&dtype, VT_LOCAL, c); vset(&dtype, VT_LOCAL|VT_LVAL, c);
vswap(); vswap();
vstore(); vstore();
vpop(); vpop();
@ -9192,6 +9230,7 @@ static void decl(int l)
extern */ extern */
external_sym(v, &type, r); external_sym(v, &type, r);
} else { } else {
type.t |= (btype.t & VT_STATIC); /* Retain "static". */
if (type.t & VT_STATIC) if (type.t & VT_STATIC)
r |= VT_CONST; r |= VT_CONST;
else else
@ -9749,7 +9788,7 @@ int tcc_relocate(TCCState *s1)
(SHF_ALLOC | SHF_EXECINSTR)) { (SHF_ALLOC | SHF_EXECINSTR)) {
#ifdef WIN32 #ifdef WIN32
{ {
DWORD old_protect; unsigned long old_protect;
VirtualProtect(s->data, s->data_offset, VirtualProtect(s->data, s->data_offset,
PAGE_EXECUTE_READWRITE, &old_protect); PAGE_EXECUTE_READWRITE, &old_protect);
} }
@ -10313,10 +10352,8 @@ int tcc_set_flag(TCCState *s, const char *flag_name, int value)
flag_name, value); flag_name, value);
} }
#if !defined(LIBTCC)
/* extract the basename of a file */ /* extract the basename of a file */
static const char *tcc_basename(const char *name) static char *tcc_basename(const char *name)
{ {
const char *p; const char *p;
p = strrchr(name, '/'); p = strrchr(name, '/');
@ -10328,9 +10365,11 @@ static const char *tcc_basename(const char *name)
p = name; p = name;
else else
p++; p++;
return p; return (char*)p;
} }
#if !defined(LIBTCC)
static int64_t getclock_us(void) static int64_t getclock_us(void)
{ {
#ifdef WIN32 #ifdef WIN32
@ -10851,8 +10890,7 @@ int main(int argc, char **argv)
} else } else
#endif #endif
{ {
tcc_output_file(s, outfile); ret = tcc_output_file(s, outfile) ? 1 : 0;
ret = 0;
} }
the_end: the_end:
/* XXX: cannot do it with bound checking because of the malloc hooks */ /* XXX: cannot do it with bound checking because of the malloc hooks */