Revert "Fix wrong handling of strings..." (almost)
See commite588b65390
. Was not "wrong" really, just different. But appears to be outdated. Now disabled by default (top of tccpp.c: ACCEPT_LF_IN_STRINGS) Also, in skipped code, just warn. Also: cleanup "Optimize small structure copying on x86_64" (commit3715f1d7ee
) - remove some copy&paste coding (tccgen.c) - RSI/RDI need to be preserved on windows - simply don't use under bcheck (this is tinycc)
This commit is contained in:
parent
e588b65390
commit
af1abf1f45
8 changed files with 100 additions and 131 deletions
13
lib/bcheck.c
13
lib/bcheck.c
|
@ -294,7 +294,6 @@ DLL_EXPORT int __bound_strncmp(const char *s1, const char *s2, size_t n);
|
|||
DLL_EXPORT char *__bound_strcat(char *dest, const char *src);
|
||||
DLL_EXPORT char *__bound_strchr(const char *string, int ch);
|
||||
DLL_EXPORT char *__bound_strdup(const char *s);
|
||||
DLL_EXPORT void __bound_struct_copy(void *dst,void *src,size_t size);
|
||||
|
||||
#if defined(__arm__) && defined(__ARM_EABI__)
|
||||
DLL_EXPORT void *__bound___aeabi_memcpy(void *dst, const void *src, size_t size);
|
||||
|
@ -427,7 +426,6 @@ static unsigned long long bound_strncmp_count;
|
|||
static unsigned long long bound_strcat_count;
|
||||
static unsigned long long bound_strchr_count;
|
||||
static unsigned long long bound_strdup_count;
|
||||
static unsigned long long bound_struct_copy_count;
|
||||
static unsigned long long bound_not_found;
|
||||
#define INCR_COUNT(x) ++x
|
||||
#else
|
||||
|
@ -1262,7 +1260,6 @@ void __attribute__((destructor)) __bound_exit(void)
|
|||
fprintf (stderr, "bound_strcat_count %llu\n", bound_strcat_count);
|
||||
fprintf (stderr, "bound_strchr_count %llu\n", bound_strchr_count);
|
||||
fprintf (stderr, "bound_strdup_count %llu\n", bound_strdup_count);
|
||||
fprintf (stderr, "bound_struct_copy_count %llu\n", bound_struct_copy_count);
|
||||
fprintf (stderr, "bound_not_found %llu\n", bound_not_found);
|
||||
#endif
|
||||
#if BOUND_STATISTIC_SPLAY
|
||||
|
@ -1786,16 +1783,6 @@ void *__bound_memset(void *s, int c, size_t n)
|
|||
return memset(s, c, n);
|
||||
}
|
||||
|
||||
void __bound_struct_copy(void *dst,void *src,size_t size)
|
||||
{
|
||||
dprintf(stderr, "Copy struct from %p to %p,size %lx\n",
|
||||
src,dst,size);
|
||||
INCR_COUNT(bound_struct_copy_count);
|
||||
__bound_check(dst,size,"struct copy destination");
|
||||
__bound_check(src,size,"struct copy source");
|
||||
return;
|
||||
}
|
||||
|
||||
#if defined(__arm__) && defined(__ARM_EABI__)
|
||||
void *__bound___aeabi_memcpy(void *dest, const void *src, size_t n)
|
||||
{
|
||||
|
|
3
tcc.h
3
tcc.h
|
@ -1644,8 +1644,6 @@ ST_FUNC void gen_increment_tcov (SValue *sv);
|
|||
|
||||
/* ------------ x86_64-gen.c ------------ */
|
||||
#ifdef TCC_TARGET_X86_64
|
||||
#define TCC_TARGET_NATIVE_STRUCT_COPY
|
||||
ST_FUNC void gen_struct_copy(int size);
|
||||
ST_FUNC void gen_addr64(int r, Sym *sym, int64_t c);
|
||||
ST_FUNC void gen_opl(int op);
|
||||
#ifdef TCC_TARGET_PE
|
||||
|
@ -1691,7 +1689,6 @@ ST_FUNC void gen_increment_tcov (SValue *sv);
|
|||
#endif
|
||||
|
||||
/* ------------ tcccoff.c ------------ */
|
||||
|
||||
#ifdef TCC_TARGET_COFF
|
||||
ST_FUNC int tcc_output_coff(TCCState *s1, FILE *f);
|
||||
ST_FUNC int tcc_load_coff(TCCState * s1, int fd);
|
||||
|
|
84
tccgen.c
84
tccgen.c
|
@ -3468,54 +3468,42 @@ ST_FUNC void vstore(void)
|
|||
ft = vtop[-1].type.t;
|
||||
sbt = vtop->type.t & VT_BTYPE;
|
||||
dbt = ft & VT_BTYPE;
|
||||
|
||||
verify_assign_cast(&vtop[-1].type);
|
||||
|
||||
if (sbt == VT_STRUCT) {
|
||||
/* if structure, only generate pointer */
|
||||
/* structure assignment : generate memcpy */
|
||||
size = type_size(&vtop->type, &align);
|
||||
size = type_size(&vtop->type, &align);
|
||||
/* destination, keep on stack() as result */
|
||||
vpushv(vtop - 1);
|
||||
#ifdef CONFIG_TCC_BCHECK
|
||||
if (vtop->r & VT_MUSTBOUND)
|
||||
gbound(); /* check would be wrong after gaddrof() */
|
||||
#endif
|
||||
vtop->type.t = VT_PTR;
|
||||
gaddrof();
|
||||
/* source */
|
||||
vswap();
|
||||
#ifdef CONFIG_TCC_BCHECK
|
||||
if (vtop->r & VT_MUSTBOUND)
|
||||
gbound();
|
||||
#endif
|
||||
vtop->type.t = VT_PTR;
|
||||
gaddrof();
|
||||
|
||||
#ifdef TCC_TARGET_NATIVE_STRUCT_COPY
|
||||
if (size <= (PTR_SIZE << 4)) {
|
||||
vswap();
|
||||
if (1
|
||||
#ifdef CONFIG_TCC_BCHECK
|
||||
if (vtop->r & VT_MUSTBOUND)
|
||||
gbound();
|
||||
&& !tcc_state->do_bounds_check
|
||||
#endif
|
||||
vtop->type.t = VT_PTR;
|
||||
gaddrof();
|
||||
|
||||
vpushv(vtop - 1);
|
||||
#ifdef CONFIG_TCC_BCHECK
|
||||
if (vtop->r & VT_MUSTBOUND)
|
||||
gbound();
|
||||
) {
|
||||
gen_struct_copy(size);
|
||||
} else
|
||||
#endif
|
||||
vtop->type.t = VT_PTR;
|
||||
gaddrof(); /* src dest src */
|
||||
#ifdef CONFIG_TCC_BCHECK
|
||||
if (tcc_state->do_bounds_check) {
|
||||
vpush_helper_func(TOK___bound_struct_copy);
|
||||
vpushv(vtop - 2);
|
||||
vpushv(vtop - 2);
|
||||
vpushi(size);
|
||||
gfunc_call(3);
|
||||
}
|
||||
#endif
|
||||
|
||||
gen_struct_copy(size);
|
||||
} else {
|
||||
#endif
|
||||
/* destination */
|
||||
vswap();
|
||||
#ifdef CONFIG_TCC_BCHECK
|
||||
if (vtop->r & VT_MUSTBOUND)
|
||||
gbound(); /* check would be wrong after gaddrof() */
|
||||
#endif
|
||||
vtop->type.t = VT_PTR;
|
||||
gaddrof();
|
||||
|
||||
/* address of memcpy() */
|
||||
{
|
||||
/* type size */
|
||||
vpushi(size);
|
||||
/* Use memmove, rather than memcpy, as dest and src may be same: */
|
||||
#ifdef TCC_ARM_EABI
|
||||
if(!(align & 7))
|
||||
vpush_helper_func(TOK_memmove8);
|
||||
|
@ -3523,25 +3511,11 @@ ST_FUNC void vstore(void)
|
|||
vpush_helper_func(TOK_memmove4);
|
||||
else
|
||||
#endif
|
||||
/* Use memmove, rather than memcpy, as dest and src may be same: */
|
||||
vpush_helper_func(TOK_memmove);
|
||||
|
||||
vswap();
|
||||
/* source */
|
||||
vpushv(vtop - 2);
|
||||
#ifdef CONFIG_TCC_BCHECK
|
||||
if (vtop->r & VT_MUSTBOUND)
|
||||
gbound();
|
||||
#endif
|
||||
vtop->type.t = VT_PTR;
|
||||
gaddrof();
|
||||
/* type size */
|
||||
vpushi(size);
|
||||
vrott(4);
|
||||
gfunc_call(3);
|
||||
/* leave source on stack */
|
||||
#ifdef TCC_TARGET_NATIVE_STRUCT_COPY
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
} else if (ft & VT_BITFIELD) {
|
||||
/* bitfield store handling */
|
||||
|
||||
|
|
18
tccpp.c
18
tccpp.c
|
@ -21,6 +21,9 @@
|
|||
#define USING_GLOBALS
|
||||
#include "tcc.h"
|
||||
|
||||
/* #define to 1 to enable (see parse_pp_string()) */
|
||||
#define ACCEPT_LF_IN_STRINGS 0
|
||||
|
||||
/********************************************************/
|
||||
/* global variables */
|
||||
|
||||
|
@ -944,16 +947,26 @@ static uint8_t *parse_pp_string(uint8_t *p,
|
|||
}
|
||||
}
|
||||
} else if (c == '\n') {
|
||||
tcc_error("missing terminating %c character",sep);
|
||||
add_lf:
|
||||
if (ACCEPT_LF_IN_STRINGS) {
|
||||
file->line_num++;
|
||||
goto add_char;
|
||||
} else if (str) { /* not skipping */
|
||||
goto unterminated_string;
|
||||
} else {
|
||||
tcc_warning("missing terminating %c character", sep);
|
||||
return p;
|
||||
}
|
||||
} else if (c == '\r') {
|
||||
PEEKC_EOB(c, p);
|
||||
if (c != '\n') {
|
||||
if (str)
|
||||
cstr_ccat(str, '\r');
|
||||
} else {
|
||||
tcc_error("missing terminating %c character",sep);
|
||||
goto add_lf;
|
||||
}
|
||||
} else {
|
||||
add_char:
|
||||
if (str)
|
||||
cstr_ccat(str, c);
|
||||
p++;
|
||||
|
@ -1006,6 +1019,7 @@ redo_start:
|
|||
case '\'':
|
||||
if (in_warn_or_error)
|
||||
goto _default;
|
||||
tok_flags &= ~TOK_FLAG_BOL;
|
||||
p = parse_pp_string(p, c, NULL);
|
||||
break;
|
||||
/* skip comments */
|
||||
|
|
1
tcctok.h
1
tcctok.h
|
@ -330,7 +330,6 @@
|
|||
DEF(TOK___bound_setjmp, "__bound_setjmp")
|
||||
DEF(TOK___bound_longjmp, "__bound_longjmp")
|
||||
DEF(TOK___bound_new_region, "__bound_new_region")
|
||||
DEF(TOK___bound_struct_copy,"__bound_struct_copy")
|
||||
# ifdef TCC_TARGET_PE
|
||||
# ifdef TCC_TARGET_X86_64
|
||||
DEF(TOK___bound_alloca_nr, "__bound_alloca_nr")
|
||||
|
|
|
@ -1519,8 +1519,6 @@ struct structa1 {
|
|||
char f2;
|
||||
};
|
||||
|
||||
struct structa1 ssta1;
|
||||
|
||||
void struct_assign_test1(struct structa1 s1, int t, float f)
|
||||
{
|
||||
printf("%d %d %d %f\n", s1.f1, s1.f2, t, f);
|
||||
|
@ -1538,22 +1536,12 @@ void struct_assign_test(void)
|
|||
struct S {
|
||||
struct structa1 lsta1, lsta2;
|
||||
int i;
|
||||
} s, *ps;
|
||||
} s = {{1,2}, {3,4}}, *ps;
|
||||
|
||||
ps = &s;
|
||||
ps->i = 4;
|
||||
#if 0
|
||||
s.lsta1.f1 = 1;
|
||||
s.lsta1.f2 = 2;
|
||||
printf("%d %d\n", s.lsta1.f1, s.lsta1.f2);
|
||||
s.lsta2 = s.lsta1;
|
||||
printf("%d %d\n", s.lsta2.f1, s.lsta2.f2);
|
||||
#else
|
||||
s.lsta2.f1 = 1;
|
||||
s.lsta2.f2 = 2;
|
||||
#endif
|
||||
|
||||
struct_assign_test1(ps->lsta2, 3, 4.5);
|
||||
|
||||
printf("before call: %d %d\n", s.lsta2.f1, s.lsta2.f2);
|
||||
ps->lsta2 = struct_assign_test2(ps->lsta2, ps->i);
|
||||
printf("after call: %d %d\n", ps->lsta2.f1, ps->lsta2.f2);
|
||||
|
@ -1565,6 +1553,9 @@ void struct_assign_test(void)
|
|||
{ struct_assign_test }
|
||||
};
|
||||
printf("%d\n", struct_assign_test == t[0].elem);
|
||||
|
||||
s.lsta1 = s.lsta2 = struct_assign_test2(s.lsta1, 1);
|
||||
printf("%d %d\n", s.lsta1.f1, s.lsta1.f2);
|
||||
}
|
||||
|
||||
/* casts to short/char */
|
||||
|
@ -4253,6 +4244,12 @@ void func_arg_test(void)
|
|||
/* gcc 2.95.3 does not handle correctly CR in strings or after strays */
|
||||
#define CORRECT_CR_HANDLING
|
||||
|
||||
/* deprecated and no longer supported in gcc 3.3 */
|
||||
/* no longer supported by default in TinyCC */
|
||||
#ifdef __TINYC__
|
||||
/* # define ACCEPT_LF_IN_STRINGS */
|
||||
#endif
|
||||
|
||||
/* keep this as the last test because GCC messes up line-numbers
|
||||
with the ^L^K^M characters below */
|
||||
void whitespace_test(void)
|
||||
|
@ -4274,6 +4271,20 @@ ntf("aaa=%d\n", 3);
|
|||
\
|
||||
ntf("min=%d\n", 4);
|
||||
|
||||
#ifdef ACCEPT_LF_IN_STRINGS
|
||||
printf("len1=%d\n", strlen("
|
||||
"));
|
||||
#ifdef CORRECT_CR_HANDLING
|
||||
str = "
|
||||
";
|
||||
printf("len1=%d str[0]=%d\n", strlen(str), str[0]);
|
||||
#endif
|
||||
printf("len1=%d\n", strlen("
a
|
||||
"));
|
||||
#else
|
||||
printf("len1=1\nlen1=1 str[0]=10\nlen1=3\n");
|
||||
#endif /* ACCEPT_LF_IN_STRINGS */
|
||||
|
||||
#ifdef __LINE__
|
||||
printf("__LINE__ defined\n");
|
||||
#endif
|
||||
|
|
|
@ -105,8 +105,7 @@ GEN-ALWAYS =
|
|||
112_backtrace.test: FLAGS += -dt -b
|
||||
112_backtrace.test 113_btdll.test 126_bound_global.test: FILTER += \
|
||||
-e 's;[0-9A-Fa-fx]\{5,\};........;g' \
|
||||
-e 's;0x[0-9A-Fa-f]\{1,\};0x?;g' \
|
||||
-e 's;struct copy destination;memmove dest;g' \
|
||||
-e 's;0x[0-9A-Fa-f]\{1,\};0x?;g'
|
||||
|
||||
# this test creates two DLLs and an EXE
|
||||
113_btdll.test: T1 = \
|
||||
|
|
70
x86_64-gen.c
70
x86_64-gen.c
|
@ -35,6 +35,8 @@
|
|||
#define RC_RAX 0x0004
|
||||
#define RC_RCX 0x0008
|
||||
#define RC_RDX 0x0010
|
||||
#define RC_RSI 0x0020
|
||||
#define RC_RDI 0x0040
|
||||
#define RC_ST0 0x0080 /* only for long double */
|
||||
#define RC_R8 0x0100
|
||||
#define RC_R9 0x0200
|
||||
|
@ -105,6 +107,10 @@ enum {
|
|||
/* define if return values need to be extended explicitely
|
||||
at caller side (for interfacing with non-TCC compilers) */
|
||||
#define PROMOTE_RET
|
||||
|
||||
#define TCC_TARGET_NATIVE_STRUCT_COPY
|
||||
ST_FUNC void gen_struct_copy(int size);
|
||||
|
||||
/******************************************************/
|
||||
#else /* ! TARGET_DEFS_ONLY */
|
||||
/******************************************************/
|
||||
|
@ -124,8 +130,8 @@ ST_DATA const int reg_classes[NB_REGS] = {
|
|||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
RC_RSI,
|
||||
RC_RDI,
|
||||
RC_R8,
|
||||
RC_R9,
|
||||
RC_R10,
|
||||
|
@ -2228,7 +2234,7 @@ ST_FUNC void gen_increment_tcov (SValue *sv)
|
|||
}
|
||||
|
||||
/* computed goto support */
|
||||
void ggoto(void)
|
||||
ST_FUNC void ggoto(void)
|
||||
{
|
||||
gcall_or_jmp(1);
|
||||
vtop--;
|
||||
|
@ -2286,53 +2292,35 @@ ST_FUNC void gen_vla_alloc(CType *type, int align) {
|
|||
* Assmuing the top part of the stack looks like below,
|
||||
* src dest src
|
||||
*/
|
||||
void gen_struct_copy(int size)
|
||||
ST_FUNC void gen_struct_copy(int size)
|
||||
{
|
||||
save_reg(TREG_RSI);
|
||||
load(TREG_RSI,vtop);
|
||||
vtop->r = TREG_RSI;
|
||||
vswap(); /* dest src src */
|
||||
save_reg(TREG_RDI);
|
||||
load(TREG_RDI,vtop);
|
||||
vtop->r = TREG_RDI;
|
||||
/* Not aligned by 8bytes */
|
||||
if (size & 0x04) {
|
||||
o(0xa5);
|
||||
}
|
||||
if (size & 0x02) {
|
||||
o(0xa566);
|
||||
}
|
||||
if (size & 0x01) {
|
||||
o(0xa4);
|
||||
}
|
||||
|
||||
size >>= 3;
|
||||
if (!size)
|
||||
goto done;
|
||||
/* Although this function is only called when the struct is smaller */
|
||||
/* than 32 bytes(4 * PTR_SIZE),a common implementation is included */
|
||||
if (size <= 4 && size) {
|
||||
switch (size) {
|
||||
case 4: o(0xa548);
|
||||
case 3: o(0xa548);
|
||||
case 2: o(0xa548);
|
||||
case 1: o(0xa548);
|
||||
}
|
||||
int n = size / PTR_SIZE;
|
||||
#ifdef TCC_TARGET_PE
|
||||
o(0x5756); /* push rsi, rdi */
|
||||
#endif
|
||||
gv2(RC_RDI, RC_RSI);
|
||||
if (n <= 4) {
|
||||
while (n)
|
||||
o(0xa548), --n;
|
||||
} else {
|
||||
save_reg(TREG_RCX);
|
||||
vpushi(size);
|
||||
load(TREG_RCX,vtop);
|
||||
vtop->r = TREG_RCX;
|
||||
vpushi(n);
|
||||
gv(RC_RCX);
|
||||
o(0xa548f3);
|
||||
vpop();
|
||||
}
|
||||
done:
|
||||
if (size & 0x04)
|
||||
o(0xa5);
|
||||
if (size & 0x02)
|
||||
o(0xa566);
|
||||
if (size & 0x01)
|
||||
o(0xa4);
|
||||
#ifdef TCC_TARGET_PE
|
||||
o(0x5e5f); /* pop rdi, rsi */
|
||||
#endif
|
||||
vpop();
|
||||
vpop();
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
/* end of x86-64 code generator */
|
||||
/*************************************************************/
|
||||
#endif /* ! TARGET_DEFS_ONLY */
|
||||
|
|
Loading…
Reference in a new issue