Unified · Split
| @@ -292,6 +292,7 @@ DLL_EXPORT int __bound_strncmp(const char *s1, const char *s2, size_t n); · 291 unmodified lines | ||
| 292 | 292 | DLL_EXPORT char *__bound_strcat(char *dest, const char *src); |
| 293 | 293 | DLL_EXPORT char *__bound_strchr(const char *string, int ch); |
| 294 | 294 | DLL_EXPORT char *__bound_strdup(const char *s); |
| 295 | +DLL_EXPORT void __bound_struct_copy(void *dst,void *src,size_t size); | |
| 295 | 296 | |
| 296 | 297 | #if defined(__arm__) && defined(__ARM_EABI__) |
| 297 | 298 | DLL_EXPORT void *__bound___aeabi_memcpy(void *dst, const void *src, size_t size); |
| @@ -424,6 +425,7 @@ static unsigned long long bound_strncmp_count; · 126 unmodified lines | ||
| 424 | 425 | static unsigned long long bound_strcat_count; |
| 425 | 426 | static unsigned long long bound_strchr_count; |
| 426 | 427 | static unsigned long long bound_strdup_count; |
| 428 | +static unsigned long long bound_struct_copy_count; | |
| 427 | 429 | static unsigned long long bound_not_found; |
| 428 | 430 | #define INCR_COUNT(x) ++x |
| 429 | 431 | #else |
| @@ -1765,6 +1767,16 @@ void *__bound_memset(void *s, int c, size_t n) · 1335 unmodified lines | ||
| 1765 | 1767 | return memset(s, c, n); |
| 1766 | 1768 | } |
| 1767 | 1769 | |
| 1770 | +void __bound_struct_copy(void *dst,void *src,size_t size) | |
| 1771 | +{ | |
| 1772 | + dprintf(stderr, "Copy struct from %p to %p,size %lx\n", | |
| 1773 | + src,dst,size); | |
| 1774 | + INCR_COUNT(bound_struct_copy_count); | |
| 1775 | + __bound_check(dst,size,"struct copy destination"); | |
| 1776 | + __bound_check(src,size,"struct copy source"); | |
| 1777 | + return; | |
| 1778 | +} | |
| 1779 | + | |
| 1768 | 1780 | #if defined(__arm__) && defined(__ARM_EABI__) |
| 1769 | 1781 | void *__bound___aeabi_memcpy(void *dest, const void *src, size_t n) |
| 1770 | 1782 | { |
| @@ -1644,6 +1644,8 @@ ST_FUNC void gen_increment_tcov (SValue *sv); · 1643 unmodified lines | ||
| 1644 | 1644 | |
| 1645 | 1645 | /* ------------ x86_64-gen.c ------------ */ |
| 1646 | 1646 | #ifdef TCC_TARGET_X86_64 |
| 1647 | +#define TCC_TARGET_NATIVE_STRUCT_COPY | |
| 1648 | +ST_FUNC void gen_struct_copy(int size); | |
| 1647 | 1649 | ST_FUNC void gen_addr64(int r, Sym *sym, int64_t c); |
| 1648 | 1650 | ST_FUNC void gen_opl(int op); |
| 1649 | 1651 | #ifdef TCC_TARGET_PE |
| @@ -3474,9 +3474,38 @@ ST_FUNC void vstore(void) · 3473 unmodified lines | ||
| 3474 | 3474 | if (sbt == VT_STRUCT) { |
| 3475 | 3475 | /* if structure, only generate pointer */ |
| 3476 | 3476 | /* structure assignment : generate memcpy */ |
| 3477 | − /* XXX: optimize if small size */ | |
| 3478 | 3477 | size = type_size(&vtop->type, &align); |
| 3479 | 3478 | |
| 3479 | +#ifdef TCC_TARGET_NATIVE_STRUCT_COPY | |
| 3480 | + if (size <= (PTR_SIZE << 4)) { | |
| 3481 | + vswap(); | |
| 3482 | +#ifdef CONFIG_TCC_BCHECK | |
| 3483 | + if (vtop->r & VT_MUSTBOUND) | |
| 3484 | + gbound(); | |
| 3485 | +#endif | |
| 3486 | + vtop->type.t = VT_PTR; | |
| 3487 | + gaddrof(); | |
| 3488 | + | |
| 3489 | + vpushv(vtop - 1); | |
| 3490 | +#ifdef CONFIG_TCC_BCHECK | |
| 3491 | + if (vtop->r & VT_MUSTBOUND) | |
| 3492 | + gbound(); | |
| 3493 | +#endif | |
| 3494 | + vtop->type.t = VT_PTR; | |
| 3495 | + gaddrof(); /* src dest src */ | |
| 3496 | +#ifdef CONFIG_TCC_BCHECK | |
| 3497 | + if (tcc_state->do_bounds_check) { | |
| 3498 | + vpush_helper_func(TOK___bound_struct_copy); | |
| 3499 | + vpushv(vtop - 2); | |
| 3500 | + vpushv(vtop - 2); | |
| 3501 | + vpushi(size); | |
| 3502 | + gfunc_call(3); | |
| 3503 | + } | |
| 3504 | +#endif | |
| 3505 | + | |
| 3506 | + gen_struct_copy(size); | |
| 3507 | + } else { | |
| 3508 | +#endif | |
| 3480 | 3509 | /* destination */ |
| 3481 | 3510 | vswap(); |
| 3482 | 3511 | #ifdef CONFIG_TCC_BCHECK |
| @@ -3510,7 +3539,9 @@ ST_FUNC void vstore(void) · 27 unmodified lines | ||
| 3510 | 3539 | vpushi(size); |
| 3511 | 3540 | gfunc_call(3); |
| 3512 | 3541 | /* leave source on stack */ |
| 3513 | − | |
| 3542 | +#ifdef TCC_TARGET_NATIVE_STRUCT_COPY | |
| 3543 | + } | |
| 3544 | +#endif | |
| 3514 | 3545 | } else if (ft & VT_BITFIELD) { |
| 3515 | 3546 | /* bitfield store handling */ |
| 3516 | 3547 | |
| @@ -330,6 +330,7 @@ · 329 unmodified lines | ||
| 330 | 330 | DEF(TOK___bound_setjmp, "__bound_setjmp") |
| 331 | 331 | DEF(TOK___bound_longjmp, "__bound_longjmp") |
| 332 | 332 | DEF(TOK___bound_new_region, "__bound_new_region") |
| 333 | + DEF(TOK___bound_struct_copy,"__bound_struct_copy") | |
| 333 | 334 | # ifdef TCC_TARGET_PE |
| 334 | 335 | # ifdef TCC_TARGET_X86_64 |
| 335 | 336 | DEF(TOK___bound_alloca_nr, "__bound_alloca_nr") |
| @@ -2282,6 +2282,56 @@ ST_FUNC void gen_vla_alloc(CType *type, int align) { · 2281 unmodified lines | ||
| 2282 | 2282 | } |
| 2283 | 2283 | } |
| 2284 | 2284 | |
| 2285 | +/* | |
| 2286 | + * Assmuing the top part of the stack looks like below, | |
| 2287 | + * src dest src | |
| 2288 | + */ | |
| 2289 | +void gen_struct_copy(int size) | |
| 2290 | +{ | |
| 2291 | + save_reg(TREG_RSI); | |
| 2292 | + load(TREG_RSI,vtop); | |
| 2293 | + vtop->r = TREG_RSI; | |
| 2294 | + vswap(); /* dest src src */ | |
| 2295 | + save_reg(TREG_RDI); | |
| 2296 | + load(TREG_RDI,vtop); | |
| 2297 | + vtop->r = TREG_RDI; | |
| 2298 | + /* Not aligned by 8bytes */ | |
| 2299 | + if (size & 0x04) { | |
| 2300 | + o(0xa5); | |
| 2301 | + } | |
| 2302 | + if (size & 0x02) { | |
| 2303 | + o(0xa566); | |
| 2304 | + } | |
| 2305 | + if (size & 0x01) { | |
| 2306 | + o(0xa4); | |
| 2307 | + } | |
| 2308 | + | |
| 2309 | + size >>= 3; | |
| 2310 | + if (!size) | |
| 2311 | + goto done; | |
| 2312 | + /* Although this function is only called when the struct is smaller */ | |
| 2313 | + /* than 32 bytes(4 * PTR_SIZE),a common implementation is included */ | |
| 2314 | + if (size <= 4 && size) { | |
| 2315 | + switch (size) { | |
| 2316 | + case 4: o(0xa548); | |
| 2317 | + case 3: o(0xa548); | |
| 2318 | + case 2: o(0xa548); | |
| 2319 | + case 1: o(0xa548); | |
| 2320 | + } | |
| 2321 | + } else { | |
| 2322 | + save_reg(TREG_RCX); | |
| 2323 | + vpushi(size); | |
| 2324 | + load(TREG_RCX,vtop); | |
| 2325 | + vtop->r = TREG_RCX; | |
| 2326 | + o(0xa548f3); | |
| 2327 | + vpop(); | |
| 2328 | + } | |
| 2329 | +done: | |
| 2330 | + vpop(); | |
| 2331 | + vpop(); | |
| 2332 | + return; | |
| 2333 | +} | |
| 2334 | + | |
| 2285 | 2335 | |
| 2286 | 2336 | /* end of x86-64 code generator */ |
| 2287 | 2337 | /*************************************************************/ |