From 54bf8c05566a34f4d578ed6d33d6262dc924a703 Mon Sep 17 00:00:00 2001 From: grischka Date: Wed, 14 Nov 2007 17:34:30 +0000 Subject: [PATCH] Import some changesets from Rob Landley's fork (part 1) --- Changelog | 18 +++++++- bcheck.c | 22 ++++----- il-gen.c | 22 ++++----- libtcc1.c | 2 +- tcc.c | 156 ++++++++++++++++++++++++++++++++++++++------------------------ 5 files changed, 136 insertions(+), 84 deletions(-) diff --git a/Changelog b/Changelog index 57d3ad8b..56604af0 100644 --- a/Changelog +++ b/Changelog @@ -1,7 +1,21 @@ version 0.9.24: -- Fix "invalid relocation entry" problem on ubuntu - from Bernhard Fischer - http://lists.gnu.org/archive/html/tinycc-devel/2005-09/msg00051.html +- Import some changesets from Rob Landley's fork (part 1): + 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 - mark executable sections as executable when running in memory diff --git a/bcheck.c b/bcheck.c index 7da8402f..d13abf59 100644 --- a/bcheck.c +++ b/bcheck.c @@ -3,19 +3,19 @@ * * Copyright (c) 2002 Fabrice Bellard * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include #include diff --git a/il-gen.c b/il-gen.c index 5e3a24ba..fef6194a 100644 --- a/il-gen.c +++ b/il-gen.c @@ -3,19 +3,19 @@ * * Copyright (c) 2002 Fabrice Bellard * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ /* number of available registers */ diff --git a/libtcc1.c b/libtcc1.c index a06016e4..747cb12d 100644 --- a/libtcc1.c +++ b/libtcc1.c @@ -466,7 +466,7 @@ long long __shldi3(long long a, int b) u.s.high = (unsigned)u.s.low << (b - 32); u.s.low = 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; } return u.ll; diff --git a/tcc.c b/tcc.c index f6e3babd..d8a02308 100644 --- a/tcc.c +++ b/tcc.c @@ -40,7 +40,7 @@ #include #ifdef WIN32 #include -#include +// #include #endif #ifndef WIN32 #include @@ -725,6 +725,8 @@ void *__stdcall GetProcAddress(void *, const char *); void *__stdcall GetModuleHandleA(const char *); void *__stdcall LoadLibraryA(const char *); int __stdcall FreeConsole(void); +int __stdcall VirtualProtect(void*,unsigned long,unsigned long,unsigned long*); +#define PAGE_EXECUTE_READWRITE 0x0040 #define snprintf _snprintf #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 *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_nomacro(void); @@ -4596,7 +4598,7 @@ void save_reg(int r) l = 0; for(p=vstack;p<=vtop;p++) { 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 */ if (!saved) { /* 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; data_section->data_offset = offset; /* 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); size = size >> 2; for(i=0;ic.ui = (unsigned int)vtop->c.d; break; - case VT_DOUBLE: vtop->c.ui = (unsigned int)vtop->c.d; break; - case VT_LDOUBLE: vtop->c.ui = (unsigned int)vtop->c.d; break; - } - break; - default: - /* int case */ - switch(sbt) { - case VT_FLOAT: vtop->c.i = (int)vtop->c.d; break; - case VT_DOUBLE: vtop->c.i = (int)vtop->c.d; break; - case VT_LDOUBLE: vtop->c.i = (int)vtop->c.d; break; + if (dbt == VT_BOOL) { + vpushi(0); + gen_op(TOK_NE); + } else { + /* we handle char/short/etc... with generic code */ + if (dbt != (VT_INT | VT_UNSIGNED) && + dbt != (VT_LLONG | VT_UNSIGNED) && + dbt != VT_LLONG) + dbt = VT_INT; + if (c) { + switch(dbt) { + case VT_LLONG | VT_UNSIGNED: + case VT_LLONG: + /* XXX: add const cases for long long */ + goto do_ftoi; + case VT_INT | VT_UNSIGNED: + switch(sbt) { + case VT_FLOAT: vtop->c.ui = (unsigned int)vtop->c.d; break; + case VT_DOUBLE: vtop->c.ui = (unsigned int)vtop->c.d; break; + case VT_LDOUBLE: vtop->c.ui = (unsigned int)vtop->c.d; break; + } + break; + default: + /* int case */ + switch(sbt) { + case VT_FLOAT: vtop->c.i = (int)vtop->c.d; break; + case VT_DOUBLE: vtop->c.i = (int)vtop->c.d; break; + case VT_LDOUBLE: vtop->c.i = (int)vtop->c.d; break; + } + break; } - break; + } else { + do_ftoi: + gen_cvt_ftoi1(dbt); + } + if (dbt == VT_INT && (type->t & (VT_BTYPE | VT_UNSIGNED)) != dbt) { + /* additional cast for char/short... */ + vtop->type.t = dbt; + gen_cast(type); } - } else { - do_ftoi: - gen_cvt_ftoi1(dbt); - } - if (dbt == VT_INT && (type->t & (VT_BTYPE | VT_UNSIGNED)) != dbt) { - /* additional cast for char/short/bool... */ - vtop->type.t = dbt; - gen_cast(type); } } else if ((dbt & VT_BTYPE) == VT_LLONG) { if ((sbt & VT_BTYPE) != VT_LLONG) { @@ -5919,6 +5931,10 @@ static void gen_cast(CType *type) gen_op(TOK_NE); } else if ((dbt & VT_BTYPE) == VT_BYTE || (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); } else if ((dbt & VT_BTYPE) == VT_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_type2.t &= ~(VT_UNSIGNED | VT_CONSTANT | VT_VOLATILE); if (!is_compatible_types(&tmp_type1, &tmp_type2)) - goto error; + warning("assignment from incompatible pointer type"); } /* check const and volatile */ if ((!(type1->t & VT_CONSTANT) && (type2->t & VT_CONSTANT)) || @@ -6304,6 +6320,11 @@ void vstore(void) /* remove bit field info to avoid loops */ vtop[-1].type.t = ft & ~(VT_BITFIELD | (-1 << VT_STRUCT_SHIFT)); + /* duplicate source into other register */ + gv_dup(); + vswap(); + vrott(3); + /* duplicate destination */ vdup(); vtop[-1] = vtop[-2]; @@ -6320,6 +6341,10 @@ void vstore(void) gen_op('|'); /* store result */ vstore(); + + /* pop off shifted source from "duplicate source..." above */ + vpop(); + } else { #ifdef CONFIG_TCC_BCHECK /* bound check case */ @@ -7066,13 +7091,17 @@ static int lvalue_type(int t) /* indirection with full error checking and bound check */ 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"); + } if ((vtop->r & VT_LVAL) && !nocode_wanted) gv(RC_INT); vtop->type = *pointed_type(&vtop->type); - /* an array is never an lvalue */ - if (!(vtop->type.t & VT_ARRAY)) { + /* Arrays and functions are never lvalues */ + if (!(vtop->type.t & VT_ARRAY) + && (vtop->type.t & VT_BTYPE) != VT_FUNC) { vtop->r |= lvalue_type(vtop->type.t); /* if bound checking, the referenced pointer must be checked */ if (do_bounds_check) @@ -7269,7 +7298,7 @@ static void unary(void) there and in function calls. */ /* arrays can also be used although they are not lvalues */ 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(); mk_pointer(&vtop->type); gaddrof(); @@ -7281,8 +7310,10 @@ static void unary(void) vtop->c.i = !vtop->c.i; else if ((vtop->r & VT_VALMASK) == VT_CMP) vtop->c.i = vtop->c.i ^ 1; - else + else { + save_regs(1); vseti(VT_JMP, gtst(1, 0)); + } break; case '~': next(); @@ -7317,6 +7348,7 @@ static void unary(void) } else { vpushi(align); } + vtop->type.t |= VT_UNSIGNED; break; case TOK_builtin_types_compatible_p: @@ -7694,6 +7726,7 @@ static void expr_land(void) expr_or(); if (tok == TOK_LAND) { t = 0; + save_regs(1); for(;;) { t = gtst(1, t); if (tok != TOK_LAND) { @@ -7713,6 +7746,7 @@ static void expr_lor(void) expr_land(); if (tok == TOK_LOR) { t = 0; + save_regs(1); for(;;) { t = gtst(0, t); if (tok != TOK_LOR) { @@ -7824,6 +7858,8 @@ static void expr_eq(void) /* now we convert second operand */ gen_cast(&type); + if (VT_STRUCT == (vtop->type.t & VT_BTYPE)) + gaddrof(); rc = RC_INT; if (is_float(type.t)) { rc = RC_FLOAT; @@ -7841,6 +7877,8 @@ static void expr_eq(void) /* put again first value and cast it */ *vtop = sv; gen_cast(&type); + if (VT_STRUCT == (vtop->type.t & VT_BTYPE)) + gaddrof(); r1 = gv(rc); move_reg(r2, r1); vtop->r = r2; @@ -8440,7 +8478,7 @@ static void init_putv(CType *type, Section *sec, unsigned long c, } vtop--; } else { - vset(&dtype, VT_LOCAL, c); + vset(&dtype, VT_LOCAL|VT_LVAL, c); vswap(); vstore(); vpop(); @@ -9192,6 +9230,7 @@ static void decl(int l) extern */ external_sym(v, &type, r); } else { + type.t |= (btype.t & VT_STATIC); /* Retain "static". */ if (type.t & VT_STATIC) r |= VT_CONST; else @@ -9749,7 +9788,7 @@ int tcc_relocate(TCCState *s1) (SHF_ALLOC | SHF_EXECINSTR)) { #ifdef WIN32 { - DWORD old_protect; + unsigned long old_protect; VirtualProtect(s->data, s->data_offset, PAGE_EXECUTE_READWRITE, &old_protect); } @@ -10313,10 +10352,8 @@ int tcc_set_flag(TCCState *s, const char *flag_name, int value) flag_name, value); } -#if !defined(LIBTCC) - /* extract the basename of a file */ -static const char *tcc_basename(const char *name) +static char *tcc_basename(const char *name) { const char *p; p = strrchr(name, '/'); @@ -10328,9 +10365,11 @@ static const char *tcc_basename(const char *name) p = name; else p++; - return p; + return (char*)p; } +#if !defined(LIBTCC) + static int64_t getclock_us(void) { #ifdef WIN32 @@ -10357,7 +10396,7 @@ void help(void) " -o outfile set output filename\n" " -Bdir set tcc internal library path\n" " -bench output compilation statistics\n" - " -run run compiled source\n" + " -run run compiled source\n" " -fflag set or reset (with 'no-' prefix) 'flag' (see man page)\n" " -Wwarning set or reset (with 'no-' prefix) 'warning' (see man page)\n" " -w disable all warnings\n" @@ -10773,7 +10812,7 @@ int main(int argc, char **argv) } } else if (output_type != TCC_OUTPUT_MEMORY) { if (!outfile) { - /* compute default outfile name */ + /* compute default outfile name */ pstrcpy(objfilename, sizeof(objfilename) - 1, /* strip path */ tcc_basename(files[0])); @@ -10782,16 +10821,16 @@ int main(int argc, char **argv) #else if (output_type == TCC_OUTPUT_OBJ && !reloc_output) { char *ext = strrchr(objfilename, '.'); - if (!ext) - goto default_outfile; + if (!ext) + goto default_outfile; /* add .o extension */ - strcpy(ext + 1, "o"); - } else { + strcpy(ext + 1, "o"); + } else { default_outfile: - pstrcpy(objfilename, sizeof(objfilename), "a.out"); - } + pstrcpy(objfilename, sizeof(objfilename), "a.out"); + } #endif - outfile = objfilename; + outfile = objfilename; } } @@ -10851,8 +10890,7 @@ int main(int argc, char **argv) } else #endif { - tcc_output_file(s, outfile); - ret = 0; + ret = tcc_output_file(s, outfile) ? 1 : 0; } the_end: /* XXX: cannot do it with bound checking because of the malloc hooks */ -- 2.11.4.GIT