libtcc.c: add -Wwrite-strings to -Wall tccgen.c: ro float-consts, string-consts, ro arrays if base type is tccpe.c: merge IAT with rodata tccrun.c: mprotect rodata accordingly. free section data after copy x86_64.c: do not use got for static data. tcc -bench: show data.rw/ro Probably STB_LOCAL should never get to put_got_entry(), and currently it doesn't seem to happen (See "Hack Alarm" there) Other files: use more ro-data in tinycc
Unified · Split
| @@ -2826,7 +2826,7 @@ ST_FUNC void asm_gen_code(ASMOperand *operands, int nb_operands, · 2825 unmodified lines | ||
| 2826 | 2826 | |
| 2827 | 2827 | // TODO: Check non-E ABI. |
| 2828 | 2828 | // Note: Technically, r13 (sp) is also callee-saved--but that does not matter yet |
| 2829 | − static uint8_t reg_saved[] = { 4, 5, 6, 7, 8, 9 /* Note: sometimes special reg "sb" */ , 10, 11 }; | |
| 2829 | + static const uint8_t reg_saved[] = { 4, 5, 6, 7, 8, 9 /* Note: sometimes special reg "sb" */ , 10, 11 }; | |
| 2830 | 2830 | |
| 2831 | 2831 | /* mark all used registers */ |
| 2832 | 2832 | memcpy(regs_allocated, clobber_regs, sizeof(regs_allocated)); |
| @@ -141,7 +141,7 @@ enum { · 140 unmodified lines | ||
| 141 | 141 | #define USING_GLOBALS |
| 142 | 142 | #include "tcc.h" |
| 143 | 143 | |
| 144 | −ST_DATA const char *target_machine_defs = | |
| 144 | +ST_DATA const char * const target_machine_defs = | |
| 145 | 145 | "__arm__\0" |
| 146 | 146 | "__arm\0" |
| 147 | 147 | "arm\0" |
| @@ -50,7 +50,7 @@ · 49 unmodified lines | ||
| 50 | 50 | #include "tcc.h" |
| 51 | 51 | #include <assert.h> |
| 52 | 52 | |
| 53 | −ST_DATA const char *target_machine_defs = | |
| 53 | +ST_DATA const char * const target_machine_defs = | |
| 54 | 54 | "__aarch64__\0" |
| 55 | 55 | ; |
| 56 | 56 | |
| @@ -116,7 +116,7 @@ enum { · 115 unmodified lines | ||
| 116 | 116 | #define USING_GLOBALS |
| 117 | 117 | #include "tcc.h" |
| 118 | 118 | |
| 119 | −ST_DATA const char *target_machine_defs = | |
| 119 | +ST_DATA const char * const target_machine_defs = | |
| 120 | 120 | "__C67__\0" |
| 121 | 121 | ; |
| 122 | 122 | |
| @@ -371,7 +371,7 @@ int C67_map_D12(char *s) · 248 unmodified lines | ||
| 371 | 371 | |
| 372 | 372 | |
| 373 | 373 | |
| 374 | −void C67_asm(char *s, int a, int b, int c) | |
| 374 | +void C67_asm(const char *s, int a, int b, int c) | |
| 375 | 375 | { |
| 376 | 376 | BOOL xpath; |
| 377 | 377 | |
| @@ -638,10 +638,12 @@ static void asm_rex(int width64, Operand *ops, int nb_ops, int *op_type, · 637 unmodified lines | ||
| 638 | 638 | } |
| 639 | 639 | #endif |
| 640 | 640 | |
| 641 | + | |
| 641 | 642 | static void maybe_print_stats (void) |
| 642 | 643 | { |
| 643 | − static int already = 1; | |
| 644 | − if (!already) | |
| 644 | + static int already; | |
| 645 | + | |
| 646 | + if (0 && !already) | |
| 645 | 647 | /* print stats about opcodes */ |
| 646 | 648 | { |
| 647 | 649 | const struct ASMInstr *pa; |
| @@ -1604,12 +1606,12 @@ ST_FUNC void asm_gen_code(ASMOperand *operands, int nb_operands, · 956 unmodified lines | ||
| 1604 | 1606 | call-preserved registers, but currently it doesn't matter. */ |
| 1605 | 1607 | #ifdef TCC_TARGET_X86_64 |
| 1606 | 1608 | #ifdef TCC_TARGET_PE |
| 1607 | − static uint8_t reg_saved[] = { 3, 6, 7, 12, 13, 14, 15 }; | |
| 1609 | + static const uint8_t reg_saved[] = { 3, 6, 7, 12, 13, 14, 15 }; | |
| 1608 | 1610 | #else |
| 1609 | − static uint8_t reg_saved[] = { 3, 12, 13, 14, 15 }; | |
| 1611 | + static const uint8_t reg_saved[] = { 3, 12, 13, 14, 15 }; | |
| 1610 | 1612 | #endif |
| 1611 | 1613 | #else |
| 1612 | − static uint8_t reg_saved[] = { 3, 6, 7 }; | |
| 1614 | + static const uint8_t reg_saved[] = { 3, 6, 7 }; | |
| 1613 | 1615 | #endif |
| 1614 | 1616 | |
| 1615 | 1617 | /* mark all used registers */ |
| @@ -81,7 +81,7 @@ enum { · 80 unmodified lines | ||
| 81 | 81 | #define USING_GLOBALS |
| 82 | 82 | #include "tcc.h" |
| 83 | 83 | |
| 84 | −ST_DATA const char *target_machine_defs = | |
| 84 | +ST_DATA const char * const target_machine_defs = | |
| 85 | 85 | "__i386__\0" |
| 86 | 86 | "__i386\0" |
| 87 | 87 | ; |
| @@ -372,8 +372,8 @@ static void gcall_or_jmp(int is_jmp) · 284 unmodified lines | ||
| 372 | 372 | } |
| 373 | 373 | } |
| 374 | 374 | |
| 375 | −static uint8_t fastcall_regs[3] = { TREG_EAX, TREG_EDX, TREG_ECX }; | |
| 376 | −static uint8_t fastcallw_regs[2] = { TREG_ECX, TREG_EDX }; | |
| 375 | +static const uint8_t fastcall_regs[3] = { TREG_EAX, TREG_EDX, TREG_ECX }; | |
| 376 | +static const uint8_t fastcallw_regs[2] = { TREG_ECX, TREG_EDX }; | |
| 377 | 377 | |
| 378 | 378 | /* Return the number of registers needed to return the struct, or 0 if |
| 379 | 379 | returning via struct pointer. */ |
| @@ -479,7 +479,7 @@ ST_FUNC void gfunc_call(int nb_args) · 99 unmodified lines | ||
| 479 | 479 | if ((func_call >= FUNC_FASTCALL1 && func_call <= FUNC_FASTCALL3) || |
| 480 | 480 | func_call == FUNC_FASTCALLW) { |
| 481 | 481 | int fastcall_nb_regs; |
| 482 | − uint8_t *fastcall_regs_ptr; | |
| 482 | + const uint8_t *fastcall_regs_ptr; | |
| 483 | 483 | if (func_call == FUNC_FASTCALLW) { |
| 484 | 484 | fastcall_regs_ptr = fastcallw_regs; |
| 485 | 485 | fastcall_nb_regs = 2; |
| @@ -519,7 +519,7 @@ ST_FUNC void gfunc_prolog(Sym *func_sym) · 33 unmodified lines | ||
| 519 | 519 | CType *func_type = &func_sym->type; |
| 520 | 520 | int addr, align, size, func_call, fastcall_nb_regs; |
| 521 | 521 | int param_index, param_addr; |
| 522 | − uint8_t *fastcall_regs_ptr; | |
| 522 | + const uint8_t *fastcall_regs_ptr; | |
| 523 | 523 | Sym *sym; |
| 524 | 524 | CType *type; |
| 525 | 525 | |
| @@ -1580,7 +1580,7 @@ static const TCCOption tcc_options[] = { · 1579 unmodified lines | ||
| 1580 | 1580 | static const FlagDef options_W[] = { |
| 1581 | 1581 | { 0, 0, "all" }, |
| 1582 | 1582 | { offsetof(TCCState, warn_unsupported), 0, "unsupported" }, |
| 1583 | − { offsetof(TCCState, warn_write_strings), 0, "write-strings" }, | |
| 1583 | + { offsetof(TCCState, warn_write_strings), WD_ALL, "write-strings" }, | |
| 1584 | 1584 | { offsetof(TCCState, warn_error), 0, "error" }, |
| 1585 | 1585 | { offsetof(TCCState, warn_gcc_compat), 0, "gcc-compat" }, |
| 1586 | 1586 | { offsetof(TCCState, warn_implicit_function_declaration), WD_ALL, |
| @@ -1997,8 +1997,12 @@ PUB_FUNC void tcc_print_stats(TCCState *s1, unsigned total_time) · 410 unmodified lines | ||
| 1997 | 1997 | (double)total_time/1000, |
| 1998 | 1998 | (unsigned)total_lines*1000/total_time, |
| 1999 | 1999 | (double)total_bytes/1000/total_time); |
| 2000 | − fprintf(stderr, "* text %d, data %d, bss %d bytes\n", | |
| 2001 | − s1->total_output[0], s1->total_output[1], s1->total_output[2]); | |
| 2000 | + fprintf(stderr, "* text %d, data.rw %d, data.ro %d, bss %d bytes\n", | |
| 2001 | + s1->total_output[0], | |
| 2002 | + s1->total_output[1], | |
| 2003 | + s1->total_output[2], | |
| 2004 | + s1->total_output[3] | |
| 2005 | + ); | |
| 2002 | 2006 | #ifdef MEM_DEBUG |
| 2003 | 2007 | fprintf(stderr, "* %d bytes memory used\n", mem_max_size); |
| 2004 | 2008 | #endif |
| @@ -36,7 +36,7 @@ · 35 unmodified lines | ||
| 36 | 36 | #include "tcc.h" |
| 37 | 37 | #include <assert.h> |
| 38 | 38 | |
| 39 | −ST_DATA const char *target_machine_defs = | |
| 39 | +ST_DATA const char * const target_machine_defs = | |
| 40 | 40 | "__riscv\0" |
| 41 | 41 | "__riscv_xlen 64\0" |
| 42 | 42 | "__riscv_flen 64\0" |
| @@ -885,7 +885,7 @@ struct TCCState { · 884 unmodified lines | ||
| 885 | 885 | Section *plt; |
| 886 | 886 | |
| 887 | 887 | /* predefined sections */ |
| 888 | − Section *text_section, *data_section, *data_ro_section, *bss_section; | |
| 888 | + Section *text_section, *data_section, *rodata_section, *bss_section; | |
| 889 | 889 | Section *common_section; |
| 890 | 890 | Section *cur_text_section; /* current section where function code is generated */ |
| 891 | 891 | #ifdef CONFIG_TCC_BCHECK |
| @@ -960,7 +960,7 @@ struct TCCState { · 68 unmodified lines | ||
| 960 | 960 | int total_idents; |
| 961 | 961 | int total_lines; |
| 962 | 962 | int total_bytes; |
| 963 | − int total_output[3]; | |
| 963 | + int total_output[4]; | |
| 964 | 964 | |
| 965 | 965 | /* option -dnum (for general development purposes) */ |
| 966 | 966 | int g_debug; |
| @@ -1639,7 +1639,7 @@ ST_FUNC void relocate_plt(TCCState *s1); · 672 unmodified lines | ||
| 1639 | 1639 | ST_FUNC void relocate(TCCState *s1, ElfW_Rel *rel, int type, unsigned char *ptr, addr_t addr, addr_t val); |
| 1640 | 1640 | |
| 1641 | 1641 | /* ------------ xxx-gen.c ------------ */ |
| 1642 | −ST_DATA const char *target_machine_defs; | |
| 1642 | +ST_DATA const char * const target_machine_defs; | |
| 1643 | 1643 | ST_DATA const int reg_classes[NB_REGS]; |
| 1644 | 1644 | |
| 1645 | 1645 | ST_FUNC void gsym_addr(int t, int a); |
| @@ -1842,7 +1842,7 @@ ST_FUNC void gen_makedeps(TCCState *s, const char *target, const char *filename) · 196 unmodified lines | ||
| 1842 | 1842 | |
| 1843 | 1843 | #define text_section TCC_STATE_VAR(text_section) |
| 1844 | 1844 | #define data_section TCC_STATE_VAR(data_section) |
| 1845 | −#define data_ro_section TCC_STATE_VAR(data_ro_section) | |
| 1845 | +#define rodata_section TCC_STATE_VAR(rodata_section) | |
| 1846 | 1846 | #define bss_section TCC_STATE_VAR(bss_section) |
| 1847 | 1847 | #define common_section TCC_STATE_VAR(common_section) |
| 1848 | 1848 | #define cur_text_section TCC_STATE_VAR(cur_text_section) |
| @@ -58,8 +58,12 @@ ST_FUNC void tccelf_new(TCCState *s) · 57 unmodified lines | ||
| 58 | 58 | /* create standard sections */ |
| 59 | 59 | text_section = new_section(s, ".text", SHT_PROGBITS, SHF_ALLOC | SHF_EXECINSTR); |
| 60 | 60 | data_section = new_section(s, ".data", SHT_PROGBITS, SHF_ALLOC | SHF_WRITE); |
| 61 | +#ifdef TCC_TARGET_PE | |
| 62 | + rodata_section = new_section(s, ".rdata", SHT_PROGBITS, SHF_ALLOC); | |
| 63 | +#else | |
| 61 | 64 | /* create ro data section (make ro after relocation done with GNU_RELRO) */ |
| 62 | − data_ro_section = new_section(s, ".data.ro", SHT_PROGBITS, SHF_ALLOC | SHF_WRITE); | |
| 65 | + rodata_section = new_section(s, ".data.ro", SHT_PROGBITS, SHF_ALLOC | SHF_WRITE); | |
| 66 | +#endif | |
| 63 | 67 | bss_section = new_section(s, ".bss", SHT_NOBITS, SHF_ALLOC | SHF_WRITE); |
| 64 | 68 | common_section = new_section(s, ".common", SHT_NOBITS, SHF_PRIVATE); |
| 65 | 69 | common_section->sh_num = SHN_COMMON; |
| @@ -206,7 +210,7 @@ ST_FUNC void tccelf_end_file(TCCState *s1) · 140 unmodified lines | ||
| 206 | 210 | tcc_free(tr); |
| 207 | 211 | |
| 208 | 212 | /* record text/data/bss output for -bench info */ |
| 209 | − for (i = 0; i < 3; ++i) { | |
| 213 | + for (i = 0; i < 4; ++i) { | |
| 210 | 214 | s = s1->sections[i + 1]; |
| 211 | 215 | s1->total_output[i] += s->data_offset - s->sh_offset; |
| 212 | 216 | } |
| @@ -1255,11 +1259,16 @@ redo: · 1042 unmodified lines | ||
| 1255 | 1259 | && ELFW(ST_TYPE)(sym->st_info) == STT_FUNC))) |
| 1256 | 1260 | goto jmp_slot; |
| 1257 | 1261 | } |
| 1258 | − } else if (!(sym->st_shndx == SHN_ABS | |
| 1262 | + } else if (sym->st_shndx == SHN_ABS) { | |
| 1263 | + if (sym->st_value == 0) /* from tcc_add_btstub() */ | |
| 1264 | + continue; | |
| 1259 | 1265 | #ifndef TCC_TARGET_ARM |
| 1260 | − && PTR_SIZE == 8 | |
| 1266 | + if (PTR_SIZE != 8) | |
| 1267 | + continue; | |
| 1261 | 1268 | #endif |
| 1262 | − )) | |
| 1269 | + /* from tcc_add_symbol(): on 64 bit platforms these | |
| 1270 | + need to go through .got */ | |
| 1271 | + } else | |
| 1263 | 1272 | continue; |
| 1264 | 1273 | } |
| 1265 | 1274 | |
| @@ -1314,7 +1323,7 @@ redo: · 48 unmodified lines | ||
| 1314 | 1323 | |
| 1315 | 1324 | ST_FUNC int set_global_sym(TCCState *s1, const char *name, Section *sec, addr_t offs) |
| 1316 | 1325 | { |
| 1317 | − int shn = sec ? sec->sh_num : offs ? SHN_ABS : SHN_UNDEF; | |
| 1326 | + int shn = sec ? sec->sh_num : offs || !name ? SHN_ABS : SHN_UNDEF; | |
| 1318 | 1327 | if (sec && offs == -1) |
| 1319 | 1328 | offs = sec->data_offset; |
| 1320 | 1329 | return set_elf_sym(symtab_section, offs, 0, |
| @@ -1326,7 +1335,7 @@ static void add_init_array_defines(TCCState *s1, const char *section_name) · 5 unmodified lines | ||
| 1326 | 1335 | Section *s; |
| 1327 | 1336 | addr_t end_offset; |
| 1328 | 1337 | char buf[1024]; |
| 1329 | − s = find_section(s1, section_name); | |
| 1338 | + s = find_section_create(s1, section_name, 0); | |
| 1330 | 1339 | if (!s) { |
| 1331 | 1340 | end_offset = 0; |
| 1332 | 1341 | s = data_section; |
| @@ -1407,12 +1416,8 @@ ST_FUNC void tcc_add_btstub(TCCState *s1) · 74 unmodified lines | ||
| 1407 | 1416 | put_ptr(s1, stab_section, -1); |
| 1408 | 1417 | put_ptr(s1, stab_section->link, 0); |
| 1409 | 1418 | section_ptr_add(s, 3 * PTR_SIZE); |
| 1410 | − /* prog_base */ | |
| 1411 | −#ifndef TCC_TARGET_MACHO | |
| 1412 | − /* XXX this relocation is wrong, it uses sym-index 0 (local,undef) */ | |
| 1413 | − put_elf_reloc(s1->symtab, s, s->data_offset, R_DATA_PTR, 0); | |
| 1414 | −#endif | |
| 1415 | − section_ptr_add(s, PTR_SIZE); | |
| 1419 | + /* prog_base : local nameless symbol with offset 0 at SHN_ABS */ | |
| 1420 | + put_ptr(s1, NULL, 0); | |
| 1416 | 1421 | n = 2 * PTR_SIZE; |
| 1417 | 1422 | #ifdef CONFIG_TCC_BCHECK |
| 1418 | 1423 | if (s1->do_bounds_check) { |
| @@ -1421,10 +1426,10 @@ ST_FUNC void tcc_add_btstub(TCCState *s1) · 2 unmodified lines | ||
| 1421 | 1426 | } |
| 1422 | 1427 | #endif |
| 1423 | 1428 | section_ptr_add(s, n); |
| 1424 | − | |
| 1425 | 1429 | cstr_new(&cstr); |
| 1426 | 1430 | cstr_printf(&cstr, |
| 1427 | − " extern void __bt_init(),*__rt_info[],__bt_init_dll();" | |
| 1431 | + "extern void __bt_init(),__bt_init_dll();" | |
| 1432 | + "static void *__rt_info[];" | |
| 1428 | 1433 | "__attribute__((constructor)) static void __bt_init_rt(){"); |
| 1429 | 1434 | #ifdef TCC_TARGET_PE |
| 1430 | 1435 | if (s1->output_type == TCC_OUTPUT_DLL) |
| @@ -1526,8 +1531,9 @@ ST_FUNC void tcc_add_runtime(TCCState *s1) · 95 unmodified lines | ||
| 1526 | 1531 | tcc_add_btstub(s1); |
| 1527 | 1532 | } |
| 1528 | 1533 | #endif |
| 1529 | − if (strlen(TCC_LIBTCC1) > 0) | |
| 1534 | + if (TCC_LIBTCC1[0]) | |
| 1530 | 1535 | tcc_add_support(s1, TCC_LIBTCC1); |
| 1536 | + | |
| 1531 | 1537 | #if TARGETOS_OpenBSD || TARGETOS_FreeBSD || TARGETOS_NetBSD |
| 1532 | 1538 | /* add crt end if not memory output */ |
| 1533 | 1539 | if (s1->output_type != TCC_OUTPUT_MEMORY) { |
| @@ -1568,7 +1574,9 @@ static void tcc_add_linker_symbols(TCCState *s1) · 34 unmodified lines | ||
| 1568 | 1574 | set_global_sym(s1, "__global_pointer$", data_section, 0x800); |
| 1569 | 1575 | #endif |
| 1570 | 1576 | /* horrible new standard ldscript defines */ |
| 1577 | +#ifndef TCC_TARGET_PE | |
| 1571 | 1578 | add_init_array_defines(s1, ".preinit_array"); |
| 1579 | +#endif | |
| 1572 | 1580 | add_init_array_defines(s1, ".init_array"); |
| 1573 | 1581 | add_init_array_defines(s1, ".fini_array"); |
| 1574 | 1582 | /* add start and stop symbols for sections whose name can be |
| @@ -1996,12 +2004,12 @@ static int layout_sections(TCCState *s1, ElfW(Phdr) *phdr, · 421 unmodified lines | ||
| 1996 | 2004 | } else if (s->sh_type == SHT_NOBITS) { |
| 1997 | 2005 | if (k != 6) |
| 1998 | 2006 | continue; |
| 1999 | − } else if (s == data_ro_section || | |
| 2007 | + } else if ((s == rodata_section | |
| 2000 | 2008 | #ifdef CONFIG_TCC_BCHECK |
| 2001 | − s == bounds_section || | |
| 2002 | − s == lbounds_section || | |
| 2009 | + || s == bounds_section | |
| 2010 | + || s == lbounds_section | |
| 2003 | 2011 | #endif |
| 2004 | − 0) { | |
| 2012 | + ) && (s->sh_flags & SHF_WRITE)) { | |
| 2005 | 2013 | if (k != 4) |
| 2006 | 2014 | continue; |
| 2007 | 2015 | /* Align next section on page size. |
| @@ -2029,18 +2037,15 @@ static int layout_sections(TCCState *s1, ElfW(Phdr) *phdr, · 21 unmodified lines | ||
| 2029 | 2037 | ph->p_vaddr = addr; |
| 2030 | 2038 | ph->p_paddr = ph->p_vaddr; |
| 2031 | 2039 | } |
| 2032 | − if (s == data_ro_section || | |
| 2033 | −#ifdef CONFIG_TCC_BCHECK | |
| 2034 | − s == bounds_section || | |
| 2035 | − s == lbounds_section || | |
| 2036 | −#endif | |
| 2037 | − 0) { | |
| 2040 | + | |
| 2041 | + if (k == 4) { | |
| 2038 | 2042 | if (roinf->sh_size == 0) { |
| 2039 | 2043 | roinf->sh_offset = s->sh_offset; |
| 2040 | 2044 | roinf->sh_addr = s->sh_addr; |
| 2041 | 2045 | } |
| 2042 | 2046 | roinf->sh_size = (addr - roinf->sh_addr) + s->sh_size; |
| 2043 | 2047 | } |
| 2048 | + | |
| 2044 | 2049 | addr += s->sh_size; |
| 2045 | 2050 | if (s->sh_type != SHT_NOBITS) |
| 2046 | 2051 | file_offset += s->sh_size; |
| @@ -2356,7 +2356,7 @@ ST_FUNC int gv(int rc) · 2355 unmodified lines | ||
| 2356 | 2356 | (vtop->r & (VT_VALMASK | VT_LVAL)) == VT_CONST) { |
| 2357 | 2357 | /* CPUs usually cannot use float constants, so we store them |
| 2358 | 2358 | generically in data segment */ |
| 2359 | − init_params p = { data_section }; | |
| 2359 | + init_params p = { rodata_section }; | |
| 2360 | 2360 | unsigned long offset; |
| 2361 | 2361 | size = type_size(&vtop->type, &align); |
| 2362 | 2362 | if (NODATA_WANTED) |
| @@ -3095,11 +3095,12 @@ static void type_to_str(char *buf, int buf_size, · 732 unmodified lines | ||
| 3095 | 3095 | pstrcat(buf, buf_size, "typedef "); |
| 3096 | 3096 | if (t & VT_INLINE) |
| 3097 | 3097 | pstrcat(buf, buf_size, "inline "); |
| 3098 | − if (t & VT_VOLATILE) | |
| 3099 | − pstrcat(buf, buf_size, "volatile "); | |
| 3100 | − if (t & VT_CONSTANT) | |
| 3101 | − pstrcat(buf, buf_size, "const "); | |
| 3102 | − | |
| 3098 | + if (bt != VT_PTR) { | |
| 3099 | + if (t & VT_VOLATILE) | |
| 3100 | + pstrcat(buf, buf_size, "volatile "); | |
| 3101 | + if (t & VT_CONSTANT) | |
| 3102 | + pstrcat(buf, buf_size, "const "); | |
| 3103 | + } | |
| 3103 | 3104 | if (((t & VT_DEFSIGN) && bt == VT_BYTE) |
| 3104 | 3105 | || ((t & VT_UNSIGNED) |
| 3105 | 3106 | && (bt == VT_SHORT || bt == VT_INT || bt == VT_LLONG) |
| @@ -5932,18 +5933,22 @@ ST_FUNC void unary(void) · 2826 unmodified lines | ||
| 5932 | 5933 | /* fall thru */ |
| 5933 | 5934 | case TOK___FUNC__: |
| 5934 | 5935 | { |
| 5936 | + Section *sec; | |
| 5935 | 5937 | void *ptr; |
| 5936 | 5938 | int len; |
| 5937 | 5939 | /* special function name identifier */ |
| 5938 | 5940 | len = strlen(funcname) + 1; |
| 5939 | 5941 | /* generate char[len] type */ |
| 5940 | 5942 | type.t = VT_BYTE; |
| 5943 | + if (tcc_state->warn_write_strings) | |
| 5944 | + type.t |= VT_CONSTANT; | |
| 5941 | 5945 | mk_pointer(&type); |
| 5942 | 5946 | type.t |= VT_ARRAY; |
| 5943 | 5947 | type.ref->c = len; |
| 5944 | − vpush_ref(&type, data_section, data_section->data_offset, len); | |
| 5948 | + sec = rodata_section; | |
| 5949 | + vpush_ref(&type, sec, sec->data_offset, len); | |
| 5945 | 5950 | if (!NODATA_WANTED) { |
| 5946 | − ptr = section_ptr_add(data_section, len); | |
| 5951 | + ptr = section_ptr_add(sec, len); | |
| 5947 | 5952 | memcpy(ptr, funcname, len); |
| 5948 | 5953 | } |
| 5949 | 5954 | next(); |
| @@ -5968,6 +5973,7 @@ ST_FUNC void unary(void) · 18 unmodified lines | ||
| 5968 | 5973 | mk_pointer(&type); |
| 5969 | 5974 | type.t |= VT_ARRAY; |
| 5970 | 5975 | memset(&ad, 0, sizeof(AttributeDef)); |
| 5976 | + ad.section = rodata_section; | |
| 5971 | 5977 | decl_initializer_alloc(&type, &ad, VT_CONST, 2, 0, 0); |
| 5972 | 5978 | break; |
| 5973 | 5979 | case '(': |
| @@ -8526,11 +8532,16 @@ static void decl_initializer_alloc(CType *type, AttributeDef *ad, int r, · 2552 unmodified lines | ||
| 8526 | 8532 | /* allocate symbol in corresponding section */ |
| 8527 | 8533 | sec = ad->section; |
| 8528 | 8534 | if (!sec) { |
| 8529 | − if (type->t & VT_CONSTANT) | |
| 8530 | − sec = data_ro_section; | |
| 8531 | − else if (has_init) | |
| 8535 | + CType *tp = type; | |
| 8536 | + while ((tp->t & (VT_BTYPE|VT_ARRAY)) == (VT_PTR|VT_ARRAY)) | |
| 8537 | + tp = &tp->ref->type; | |
| 8538 | + if (tp->t & VT_CONSTANT) { | |
| 8539 | + sec = rodata_section; | |
| 8540 | + } else if (has_init) { | |
| 8532 | 8541 | sec = data_section; |
| 8533 | − else if (tcc_state->nocommon) | |
| 8542 | + /*if (tcc_state->g_debug & 4) | |
| 8543 | + tcc_warning("rw data: %s", get_tok_str(v, 0));*/ | |
| 8544 | + } else if (tcc_state->nocommon) | |
| 8534 | 8545 | sec = bss_section; |
| 8535 | 8546 | } |
| 8536 | 8547 | |
| @@ -259,7 +259,7 @@ static void * add_lc(struct macho *mo, uint32_t cmd, uint32_t cmdsize) · 258 unmodified lines | ||
| 259 | 259 | return lc; |
| 260 | 260 | } |
| 261 | 261 | |
| 262 | −static struct segment_command_64 * add_segment(struct macho *mo, char *name) | |
| 262 | +static struct segment_command_64 * add_segment(struct macho *mo, const char *name) | |
| 263 | 263 | { |
| 264 | 264 | struct segment_command_64 *sc = add_lc(mo, LC_SEGMENT_64, sizeof(*sc)); |
| 265 | 265 | strncpy(sc->segname, name, 16); |
| @@ -272,7 +272,7 @@ static struct segment_command_64 * get_segment(struct macho *mo, int i) · 6 unmodified lines | ||
| 272 | 272 | return (struct segment_command_64 *) (mo->lc[mo->seg2lc[i]]); |
| 273 | 273 | } |
| 274 | 274 | |
| 275 | −static int add_section(struct macho *mo, struct segment_command_64 **_seg, char *name) | |
| 275 | +static int add_section(struct macho *mo, struct segment_command_64 **_seg, const char *name) | |
| 276 | 276 | { |
| 277 | 277 | struct segment_command_64 *seg = *_seg; |
| 278 | 278 | int ret = seg->nsects; |
| @@ -525,10 +525,10 @@ static void create_symtab(TCCState *s1, struct macho *mo) · 246 unmodified lines | ||
| 525 | 525 | } |
| 526 | 526 | } |
| 527 | 527 | |
| 528 | −struct { | |
| 528 | +const struct { | |
| 529 | 529 | int seg; |
| 530 | 530 | uint32_t flags; |
| 531 | − char *name; | |
| 531 | + const char *name; | |
| 532 | 532 | } skinfo[sk_last] = { |
| 533 | 533 | /*[sk_unknown] =*/ { 0 }, |
| 534 | 534 | /*[sk_discard] =*/ { 0 }, |
| @@ -20,8 +20,8 @@ · 19 unmodified lines | ||
| 20 | 20 | |
| 21 | 21 | #include "tcc.h" |
| 22 | 22 | |
| 23 | −#define PE_MERGE_DATA | |
| 24 | −/* #define PE_PRINT_SECTIONS */ | |
| 23 | +#define PE_MERGE_DATA 1 | |
| 24 | +#define PE_PRINT_SECTIONS 0 | |
| 25 | 25 | |
| 26 | 26 | #ifndef _WIN32 |
| 27 | 27 | #define stricmp strcasecmp |
| @@ -294,6 +294,7 @@ struct pe_rsrc_reloc { · 266 unmodified lines | ||
| 294 | 294 | |
| 295 | 295 | enum { |
| 296 | 296 | sec_text = 0, |
| 297 | + sec_rdata , | |
| 297 | 298 | sec_data , |
| 298 | 299 | sec_bss , |
| 299 | 300 | sec_idata , |
| @@ -725,6 +726,8 @@ static int pe_write(struct pe_info *pe) · 425 unmodified lines | ||
| 725 | 726 | for (i = 0; i < pe->sec_count; ++i) { |
| 726 | 727 | Section *s; |
| 727 | 728 | si = pe->sec_info[i]; |
| 729 | + if (!si->data_size) | |
| 730 | + continue; | |
| 728 | 731 | for (s = si->sec; s; s = s->prev) { |
| 729 | 732 | pe_fpad(&pf, file_offset); |
| 730 | 733 | pe_fwrite(s->data, s->data_offset, &pf); |
| @@ -1084,6 +1087,7 @@ static int pe_section_class(Section *s) · 353 unmodified lines | ||
| 1084 | 1087 | return sec_idata; |
| 1085 | 1088 | if (0 == strcmp(name, ".pdata")) |
| 1086 | 1089 | return sec_pdata; |
| 1090 | + return sec_rdata; | |
| 1087 | 1091 | } else if (type == SHT_NOBITS) { |
| 1088 | 1092 | if (flags & SHF_WRITE) |
| 1089 | 1093 | return sec_bss; |
| @@ -1106,6 +1110,7 @@ static int pe_assign_addresses (struct pe_info *pe) · 16 unmodified lines | ||
| 1106 | 1110 | int *section_order; |
| 1107 | 1111 | struct section_info *si; |
| 1108 | 1112 | Section *s; |
| 1113 | + TCCState *s1 = pe->s1; | |
| 1109 | 1114 | |
| 1110 | 1115 | if (PE_DLL == pe->type) |
| 1111 | 1116 | pe->reloc = new_section(pe->s1, ".reloc", SHT_PROGBITS, 0); |
| @@ -1113,8 +1118,8 @@ static int pe_assign_addresses (struct pe_info *pe) · 1 unmodified line | ||
| 1113 | 1118 | |
| 1114 | 1119 | section_order = tcc_malloc(pe->s1->nb_sections * sizeof (int)); |
| 1115 | 1120 | for (o = k = 0 ; k < sec_last; ++k) { |
| 1116 | − for (i = 1; i < pe->s1->nb_sections; ++i) { | |
| 1117 | − s = pe->s1->sections[i]; | |
| 1121 | + for (i = 1; i < s1->nb_sections; ++i) { | |
| 1122 | + s = s1->sections[i]; | |
| 1118 | 1123 | if (k == pe_section_class(s)) |
| 1119 | 1124 | section_order[o++] = i; |
| 1120 | 1125 | } |
| @@ -1125,16 +1130,15 @@ static int pe_assign_addresses (struct pe_info *pe) · 4 unmodified lines | ||
| 1125 | 1130 | |
| 1126 | 1131 | for (i = 0; i < o; ++i) { |
| 1127 | 1132 | k = section_order[i]; |
| 1128 | − s = pe->s1->sections[k]; | |
| 1133 | + s = s1->sections[k]; | |
| 1129 | 1134 | c = pe_section_class(s); |
| 1130 | 1135 | |
| 1131 | − if ((c == sec_stab || c == sec_stabstr) && 0 == pe->s1->do_debug) | |
| 1136 | + if ((c == sec_stab || c == sec_stabstr) && 0 == s1->do_debug) | |
| 1132 | 1137 | continue; |
| 1133 | 1138 | |
| 1134 | −#ifdef PE_MERGE_DATA | |
| 1135 | − if (c == sec_bss) | |
| 1139 | + if (PE_MERGE_DATA && c == sec_bss) | |
| 1136 | 1140 | c = sec_data; |
| 1137 | −#endif | |
| 1141 | + | |
| 1138 | 1142 | if (si && c == si->cls) { |
| 1139 | 1143 | /* merge with previous section */ |
| 1140 | 1144 | s->sh_addr = addr = ((addr - 1) | (16 - 1)) + 1; |
| @@ -1143,7 +1147,8 @@ static int pe_assign_addresses (struct pe_info *pe) · 2 unmodified lines | ||
| 1143 | 1147 | s->sh_addr = addr = pe_virtual_align(pe, addr); |
| 1144 | 1148 | } |
| 1145 | 1149 | |
| 1146 | − if (c == sec_data && NULL == pe->thunk) | |
| 1150 | + if (NULL == pe->thunk | |
| 1151 | + && c == (data_section == rodata_section ? sec_data : sec_rdata)) | |
| 1147 | 1152 | pe->thunk = s; |
| 1148 | 1153 | |
| 1149 | 1154 | if (s == pe->thunk) { |
| @@ -1192,8 +1197,8 @@ add_section: · 42 unmodified lines | ||
| 1192 | 1197 | } |
| 1193 | 1198 | tcc_free(section_order); |
| 1194 | 1199 | #if 0 |
| 1195 | − for (i = 1; i < pe->s1->nb_sections; ++i) { | |
| 1196 | − Section *s = pe->s1->sections[i]; | |
| 1200 | + for (i = 1; i < s1->nb_sections; ++i) { | |
| 1201 | + Section *s = s1->sections[i]; | |
| 1197 | 1202 | int type = s->sh_type; |
| 1198 | 1203 | int flags = s->sh_flags; |
| 1199 | 1204 | printf("section %-16s %-10s %08x %04x %s,%s,%s\n", |
| @@ -1210,7 +1215,7 @@ add_section: · 10 unmodified lines | ||
| 1210 | 1215 | flags & SHF_EXECINSTR ? "exec" : "" |
| 1211 | 1216 | ); |
| 1212 | 1217 | } |
| 1213 | − pe->s1->verbose = 2; | |
| 1218 | + s1->verbose = 2; | |
| 1214 | 1219 | #endif |
| 1215 | 1220 | return 0; |
| 1216 | 1221 | } |
| @@ -1345,7 +1350,7 @@ static int pe_check_symbols(struct pe_info *pe) · 128 unmodified lines | ||
| 1345 | 1350 | } |
| 1346 | 1351 | |
| 1347 | 1352 | /*----------------------------------------------------------------------------*/ |
| 1348 | −#ifdef PE_PRINT_SECTIONS | |
| 1353 | +#if PE_PRINT_SECTIONS | |
| 1349 | 1354 | static void pe_print_section(FILE * f, Section * s) |
| 1350 | 1355 | { |
| 1351 | 1356 | /* just if you're curious */ |
| @@ -1923,11 +1928,11 @@ static void pe_add_runtime(TCCState *s1, struct pe_info *pe) · 571 unmodified lines | ||
| 1923 | 1928 | set_global_sym(s1, start_symbol, NULL, 0); |
| 1924 | 1929 | |
| 1925 | 1930 | if (0 == s1->nostdlib) { |
| 1926 | − static const char *libs[] = { | |
| 1931 | + static const char * const libs[] = { | |
| 1927 | 1932 | "msvcrt", "kernel32", "", "user32", "gdi32", NULL |
| 1928 | 1933 | }; |
| 1929 | − const char **pp, *p; | |
| 1930 | − if (strlen(TCC_LIBTCC1) > 0) | |
| 1934 | + const char * const *pp, *p; | |
| 1935 | + if (TCC_LIBTCC1[0]) | |
| 1931 | 1936 | tcc_add_support(s1, TCC_LIBTCC1); |
| 1932 | 1937 | for (pp = libs; 0 != (p = *pp); ++pp) { |
| 1933 | 1938 | if (*p) |
| @@ -2038,8 +2043,9 @@ ST_FUNC int pe_output_file(TCCState *s1, const char *filename) · 104 unmodified lines | ||
| 2038 | 2043 | |
| 2039 | 2044 | pe_free_imports(&pe); |
| 2040 | 2045 | |
| 2041 | −#ifdef PE_PRINT_SECTIONS | |
| 2042 | − pe_print_sections(s1, "tcc.log"); | |
| 2046 | +#if PE_PRINT_SECTIONS | |
| 2047 | + if (s1->g_debug & 8) | |
| 2048 | + pe_print_sections(s1, "tcc.log"); | |
| 2043 | 2049 | #endif |
| 2044 | 2050 | return ret; |
| 2045 | 2051 | } |
| @@ -3669,7 +3669,7 @@ ST_INLN void unget_tok(int last_tok) · 3668 unmodified lines | ||
| 3669 | 3669 | /* ------------------------------------------------------------------------- */ |
| 3670 | 3670 | /* init preprocessor */ |
| 3671 | 3671 | |
| 3672 | −static const char *target_os_defs = | |
| 3672 | +static const char * const target_os_defs = | |
| 3673 | 3673 | #ifdef TCC_TARGET_PE |
| 3674 | 3674 | "_WIN32\0" |
| 3675 | 3675 | # if PTR_SIZE == 8 |
| @@ -55,7 +55,7 @@ static void rt_exit(int code); · 54 unmodified lines | ||
| 55 | 55 | # include <sys/mman.h> |
| 56 | 56 | #endif |
| 57 | 57 | |
| 58 | −static void set_pages_executable(TCCState *s1, void *ptr, unsigned long length); | |
| 58 | +static void set_pages_executable(TCCState *s1, int mode, void *ptr, unsigned long length); | |
| 59 | 59 | static int tcc_relocate_ex(TCCState *s1, void *ptr, addr_t ptr_diff); |
| 60 | 60 | |
| 61 | 61 | #ifdef _WIN64 |
| @@ -94,7 +94,6 @@ LIBTCCAPI int tcc_relocate(TCCState *s1, void *ptr) · 32 unmodified lines | ||
| 94 | 94 | prx = mmap((char*)ptr + size, size, PROT_READ|PROT_EXEC, MAP_SHARED|MAP_FIXED, fd, 0); |
| 95 | 95 | if (ptr == MAP_FAILED || prx == MAP_FAILED) |
| 96 | 96 | tcc_error("tccrun: could not map memory"); |
| 97 | − dynarray_add(&s1->runtime_mem, &s1->nb_runtime_mem, (void*)(addr_t)(size*2)); | |
| 98 | 97 | ptr_diff = (char*)prx - (char*)ptr; |
| 99 | 98 | close(fd); |
| 100 | 99 | //printf("map %p %p %p\n", ptr, prx, (void*)ptr_diff); |
| @@ -103,6 +102,7 @@ LIBTCCAPI int tcc_relocate(TCCState *s1, void *ptr) · 2 unmodified lines | ||
| 103 | 102 | ptr = tcc_malloc(size); |
| 104 | 103 | #endif |
| 105 | 104 | tcc_relocate_ex(s1, ptr, ptr_diff); /* no more errors expected */ |
| 105 | + dynarray_add(&s1->runtime_mem, &s1->nb_runtime_mem, (void*)(addr_t)size); | |
| 106 | 106 | dynarray_add(&s1->runtime_mem, &s1->nb_runtime_mem, ptr); |
| 107 | 107 | return 0; |
| 108 | 108 | } |
| @@ -111,15 +111,18 @@ ST_FUNC void tcc_run_free(TCCState *s1) · 2 unmodified lines | ||
| 111 | 111 | { |
| 112 | 112 | int i; |
| 113 | 113 | |
| 114 | − for (i = 0; i < s1->nb_runtime_mem; ++i) { | |
| 114 | + for (i = 0; i < s1->nb_runtime_mem; i += 2) { | |
| 115 | + unsigned size = (unsigned)(addr_t)s1->runtime_mem[i]; | |
| 116 | + void *ptr = s1->runtime_mem[i+1]; | |
| 115 | 117 | #ifdef HAVE_SELINUX |
| 116 | − unsigned size = (unsigned)(addr_t)s1->runtime_mem[i++]; | |
| 117 | − munmap(s1->runtime_mem[i], size); | |
| 118 | + munmap(ptr, size * 2); | |
| 118 | 119 | #else |
| 120 | + /* unprotect memory to make it usable for malloc again */ | |
| 121 | + set_pages_executable(s1, 2, ptr, size); | |
| 119 | 122 | #ifdef _WIN64 |
| 120 | − win64_del_function_table(*(void**)s1->runtime_mem[i]); | |
| 123 | + win64_del_function_table(*(void**)ptr); | |
| 121 | 124 | #endif |
| 122 | − tcc_free(s1->runtime_mem[i]); | |
| 125 | + tcc_free(ptr); | |
| 123 | 126 | #endif |
| 124 | 127 | } |
| 125 | 128 | tcc_free(s1->runtime_mem); |
| @@ -182,8 +185,9 @@ LIBTCCAPI int tcc_run(TCCState *s1, int argc, char **argv) · 56 unmodified lines | ||
| 182 | 185 | *(void**)p = _rt_error; |
| 183 | 186 | #ifdef CONFIG_TCC_BCHECK |
| 184 | 187 | if (s1->do_bounds_check) { |
| 188 | + rc->bounds_start = (void*)bounds_section->sh_addr; | |
| 185 | 189 | if ((p = tcc_get_symbol(s1, "__bound_init"))) |
| 186 | − ((void(*)(addr_t, int))p)(bounds_section->sh_addr, 1); | |
| 190 | + ((void(*)(void*,int))p)(rc->bounds_start, 1); | |
| 187 | 191 | } |
| 188 | 192 | #endif |
| 189 | 193 | set_exception_handler(); |
| @@ -207,13 +211,20 @@ LIBTCCAPI int tcc_run(TCCState *s1, int argc, char **argv) · 17 unmodified lines | ||
| 207 | 211 | return ret; |
| 208 | 212 | } |
| 209 | 213 | |
| 210 | −#if defined TCC_TARGET_I386 || defined TCC_TARGET_X86_64 | |
| 214 | +#define DEBUG_RUNMEN 0 | |
| 215 | + | |
| 216 | +/* enable rx/ro/rw permissions */ | |
| 217 | +#define CONFIG_RUNMEM_RO 1 | |
| 218 | + | |
| 219 | +#if CONFIG_RUNMEM_RO | |
| 220 | +# define PAGE_ALIGN PAGESIZE | |
| 221 | +#elif defined TCC_TARGET_I386 || defined TCC_TARGET_X86_64 | |
| 211 | 222 | /* To avoid that x86 processors would reload cached instructions |
| 212 | 223 | each time when data is written in the near, we need to make |
| 213 | 224 | sure that code and data do not share the same 64 byte unit */ |
| 214 | − #define RUN_SECTION_ALIGNMENT 63 | |
| 225 | +# define PAGE_ALIGN 64 | |
| 215 | 226 | #else |
| 216 | − #define RUN_SECTION_ALIGNMENT 0 | |
| 227 | +# define PAGE_ALIGN 1 | |
| 217 | 228 | #endif |
| 218 | 229 | |
| 219 | 230 | /* relocate code. Return -1 on error, required size if ptr is NULL, |
| @@ -222,6 +233,7 @@ static int tcc_relocate_ex(TCCState *s1, void *ptr, addr_t ptr_diff) · 2 unmodified lines | ||
| 222 | 233 | { |
| 223 | 234 | Section *s; |
| 224 | 235 | unsigned offset, length, align, max_align, i, k, f; |
| 236 | + unsigned n, copy; | |
| 225 | 237 | addr_t mem, addr; |
| 226 | 238 | |
| 227 | 239 | if (NULL == ptr) { |
| @@ -241,35 +253,80 @@ static int tcc_relocate_ex(TCCState *s1, void *ptr, addr_t ptr_diff) · 13 unmodified lines | ||
| 241 | 253 | #ifdef _WIN64 |
| 242 | 254 | offset += sizeof (void*); /* space for function_table pointer */ |
| 243 | 255 | #endif |
| 244 | − for (k = 0; k < 2; ++k) { | |
| 245 | − f = 0, addr = k ? mem : mem + ptr_diff; | |
| 256 | + copy = 0; | |
| 257 | +redo: | |
| 258 | + for (k = 0; k < 3; ++k) { /* 0:rx, 1:ro, 2:rw sections */ | |
| 259 | + n = 0; addr = 0; | |
| 246 | 260 | for(i = 1; i < s1->nb_sections; i++) { |
| 261 | + static const char shf[] = { | |
| 262 | + SHF_ALLOC|SHF_EXECINSTR, SHF_ALLOC, SHF_ALLOC|SHF_WRITE | |
| 263 | + }; | |
| 247 | 264 | s = s1->sections[i]; |
| 248 | − if (0 == (s->sh_flags & SHF_ALLOC)) | |
| 265 | + if (shf[k] != (s->sh_flags & (SHF_ALLOC|SHF_WRITE|SHF_EXECINSTR))) | |
| 249 | 266 | continue; |
| 250 | − if (k != !(s->sh_flags & SHF_EXECINSTR)) | |
| 267 | + length = s->data_offset; | |
| 268 | + if (copy) { | |
| 269 | + if (addr == 0) | |
| 270 | + addr = s->sh_addr; | |
| 271 | + n = (s->sh_addr - addr) + length; | |
| 272 | + ptr = (void*)s->sh_addr; | |
| 273 | + if (k == 0) | |
| 274 | + ptr = (void*)(s->sh_addr - ptr_diff); | |
| 275 | + if (NULL == s->data || s->sh_type == SHT_NOBITS) | |
| 276 | + memset(ptr, 0, length); | |
| 277 | + else | |
| 278 | + memcpy(ptr, s->data, length); | |
| 279 | +#ifdef _WIN64 | |
| 280 | + if (s == s1->uw_pdata) | |
| 281 | + *(void**)mem = win64_add_function_table(s1); | |
| 282 | +#endif | |
| 283 | + if (s->data) { | |
| 284 | + tcc_free(s->data); | |
| 285 | + s->data = NULL; | |
| 286 | + s->data_allocated = 0; | |
| 287 | + } | |
| 288 | + s->data_offset = 0; | |
| 251 | 289 | continue; |
| 290 | + } | |
| 252 | 291 | align = s->sh_addralign - 1; |
| 253 | − if (++f == 1 && align < RUN_SECTION_ALIGNMENT) | |
| 254 | − align = RUN_SECTION_ALIGNMENT; | |
| 292 | + if (++n == 1 && align < (PAGE_ALIGN - 1)) | |
| 293 | + align = (PAGE_ALIGN - 1); | |
| 255 | 294 | if (max_align < align) |
| 256 | 295 | max_align = align; |
| 296 | + addr = k ? mem : mem + ptr_diff; | |
| 257 | 297 | offset += -(addr + offset) & align; |
| 258 | 298 | s->sh_addr = mem ? addr + offset : 0; |
| 259 | − offset += s->data_offset; | |
| 260 | −#if 0 | |
| 299 | + offset += length; | |
| 300 | +#if DEBUG_RUNMEN | |
| 261 | 301 | if (mem) |
| 262 | − printf("%-16s %p len %04x align %2d\n", | |
| 263 | − s->name, (void*)s->sh_addr, (unsigned)s->data_offset, align + 1); | |
| 302 | + printf("%d: %-16s %p len %04x align %04x\n", | |
| 303 | + k, s->name, (void*)s->sh_addr, length, align + 1); | |
| 304 | +#endif | |
| 305 | + } | |
| 306 | + if (copy) { /* set permissions */ | |
| 307 | + if (k == 0 && ptr_diff) | |
| 308 | + continue; /* not with HAVE_SELINUX */ | |
| 309 | + f = k; | |
| 310 | +#if !CONFIG_RUNMEM_RO | |
| 311 | + if (f != 0) | |
| 312 | + continue; | |
| 313 | + f = 3; /* change only SHF_EXECINSTR to rwx */ | |
| 314 | +#endif | |
| 315 | +#if DEBUG_RUNMEN | |
| 316 | + printf("protect %d %p %04x\n", f, (void*)addr, n); | |
| 264 | 317 | #endif |
| 318 | + if (n) | |
| 319 | + set_pages_executable(s1, f, (void*)addr, n); | |
| 265 | 320 | } |
| 266 | 321 | } |
| 267 | 322 | |
| 323 | + if (copy) | |
| 324 | + return 0; | |
| 325 | + | |
| 268 | 326 | /* relocate symbols */ |
| 269 | 327 | relocate_syms(s1, s1->symtab, !(s1->nostdlib)); |
| 270 | 328 | if (s1->nb_errors) |
| 271 | 329 | return -1; |
| 272 | − | |
| 273 | 330 | if (0 == mem) |
| 274 | 331 | return offset + max_align; |
| 275 | 332 | |
| @@ -282,55 +339,46 @@ static int tcc_relocate_ex(TCCState *s1, void *ptr, addr_t ptr_diff) · 6 unmodified lines | ||
| 282 | 339 | relocate_plt(s1); |
| 283 | 340 | #endif |
| 284 | 341 | relocate_sections(s1); |
| 285 | − | |
| 286 | − for(i = 1; i < s1->nb_sections; i++) { | |
| 287 | − s = s1->sections[i]; | |
| 288 | − if (0 == (s->sh_flags & SHF_ALLOC)) | |
| 289 | − continue; | |
| 290 | − length = s->data_offset; | |
| 291 | − ptr = (void*)s->sh_addr; | |
| 292 | − if (s->sh_flags & SHF_EXECINSTR) | |
| 293 | − ptr = (char*)((addr_t)ptr - ptr_diff); | |
| 294 | − if (NULL == s->data || s->sh_type == SHT_NOBITS) | |
| 295 | − memset(ptr, 0, length); | |
| 296 | − else | |
| 297 | − memcpy(ptr, s->data, length); | |
| 298 | − /* mark executable sections as executable in memory */ | |
| 299 | − if (s->sh_flags & SHF_EXECINSTR) | |
| 300 | − set_pages_executable(s1, (char*)((addr_t)ptr + ptr_diff), length); | |
| 301 | − } | |
| 302 | − | |
| 303 | −#ifdef _WIN64 | |
| 304 | − *(void**)mem = win64_add_function_table(s1); | |
| 305 | −#endif | |
| 306 | − | |
| 307 | − return 0; | |
| 342 | + copy = 1; | |
| 343 | + goto redo; | |
| 308 | 344 | } |
| 309 | 345 | |
| 310 | 346 | /* ------------------------------------------------------------- */ |
| 311 | 347 | /* allow to run code in memory */ |
| 312 | 348 | |
| 313 | −static void set_pages_executable(TCCState *s1, void *ptr, unsigned long length) | |
| 349 | +static void set_pages_executable(TCCState *s1, int mode, void *ptr, unsigned long length) | |
| 314 | 350 | { |
| 315 | 351 | #ifdef _WIN32 |
| 316 | − unsigned long old_protect; | |
| 317 | − VirtualProtect(ptr, length, PAGE_EXECUTE_READWRITE, &old_protect); | |
| 352 | + static const unsigned char protect[] = { | |
| 353 | + PAGE_EXECUTE_READ, | |
| 354 | + PAGE_READONLY, | |
| 355 | + PAGE_READWRITE, | |
| 356 | + PAGE_EXECUTE_READWRITE | |
| 357 | + }; | |
| 358 | + DWORD old; | |
| 359 | + VirtualProtect(ptr, length, protect[mode], &old); | |
| 318 | 360 | #else |
| 319 | − void __clear_cache(void *beginning, void *end); | |
| 320 | −# ifndef HAVE_SELINUX | |
| 361 | + static const unsigned char protect[] = { | |
| 362 | + PROT_READ | PROT_EXEC, | |
| 363 | + PROT_READ, | |
| 364 | + PROT_READ | PROT_WRITE, | |
| 365 | + PROT_READ | PROT_WRITE | PROT_EXEC | |
| 366 | + }; | |
| 321 | 367 | addr_t start, end; |
| 322 | 368 | start = (addr_t)ptr & ~(PAGESIZE - 1); |
| 323 | 369 | end = (addr_t)ptr + length; |
| 324 | 370 | end = (end + PAGESIZE - 1) & ~(PAGESIZE - 1); |
| 325 | − if (mprotect((void *)start, end - start, PROT_READ | PROT_WRITE | PROT_EXEC)) | |
| 371 | + if (mprotect((void *)start, end - start, protect[mode])) | |
| 326 | 372 | tcc_error("mprotect failed: did you mean to configure --with-selinux?"); |
| 327 | −# endif | |
| 373 | + | |
| 328 | 374 | /* XXX: BSD sometimes dump core with bad system call */ |
| 329 | −# if (defined(TCC_TARGET_ARM) && \ | |
| 330 | − !defined(__FreeBSD__) && !defined(__OpenBSD__) && !defined(__NetBSD__)) || \ | |
| 331 | − defined(TCC_TARGET_ARM64) | |
| 332 | − __clear_cache(ptr, (char *)ptr + length); | |
| 375 | +# if (TCC_TARGET_ARM && !TARGETOS_BSD) || TCC_TARGET_ARM64 | |
| 376 | + if (mode == 0 || mode == 3) { | |
| 377 | + void __clear_cache(void *beginning, void *end); | |
| 378 | + __clear_cache(ptr, (char *)ptr + length); | |
| 379 | + } | |
| 333 | 380 | # endif |
| 381 | + | |
| 334 | 382 | #endif |
| 335 | 383 | } |
| 336 | 384 | |
| @@ -68,7 +68,7 @@ static int ar_usage(int ret) { · 67 unmodified lines | ||
| 68 | 68 | |
| 69 | 69 | ST_FUNC int tcc_tool_ar(TCCState *s1, int argc, char **argv) |
| 70 | 70 | { |
| 71 | − static ArHdr arhdr = { | |
| 71 | + static const ArHdr arhdr_init = { | |
| 72 | 72 | "/ ", |
| 73 | 73 | " ", |
| 74 | 74 | "0 ", |
| @@ -78,15 +78,8 @@ ST_FUNC int tcc_tool_ar(TCCState *s1, int argc, char **argv) · 3 unmodified lines | ||
| 78 | 78 | ARFMAG |
| 79 | 79 | }; |
| 80 | 80 | |
| 81 | − static ArHdr arhdro = { | |
| 82 | − " ", | |
| 83 | − " ", | |
| 84 | − "0 ", | |
| 85 | − "0 ", | |
| 86 | − "0 ", | |
| 87 | − " ", | |
| 88 | − ARFMAG | |
| 89 | − }; | |
| 81 | + ArHdr arhdr = arhdr_init; | |
| 82 | + ArHdr arhdro = arhdr_init; | |
| 90 | 83 | |
| 91 | 84 | FILE *fi, *fh = NULL, *fo = NULL; |
| 92 | 85 | ElfW(Ehdr) *ehdr; |
| @@ -506,9 +499,9 @@ ST_FUNC void tcc_tool_cross(TCCState *s1, char **argv, int target) · 413 unmodified lines | ||
| 506 | 499 | /* enable commandline wildcard expansion (tcc -o x.exe *.c) */ |
| 507 | 500 | |
| 508 | 501 | #ifdef _WIN32 |
| 509 | −int _CRT_glob = 1; | |
| 502 | +const int _CRT_glob = 1; | |
| 510 | 503 | #ifndef _CRT_glob |
| 511 | −int _dowildcard = 1; | |
| 504 | +const int _dowildcard = 1; | |
| 512 | 505 | #endif |
| 513 | 506 | #endif |
| 514 | 507 | |
| @@ -42,8 +42,8 @@ int main() · 41 unmodified lines | ||
| 42 | 42 | __label__ ts0, te0, ts1, te1; |
| 43 | 43 | int tl, dl; |
| 44 | 44 | |
| 45 | − static char ds0 = 0; | |
| 46 | − static char de0 = 0; | |
| 45 | + static const char ds0 = 0; | |
| 46 | + static const char de0 = 0; | |
| 47 | 47 | /* get reference size of empty jmp */ |
| 48 | 48 | ts0:; |
| 49 | 49 | if (!SKIP) {} |
| @@ -52,7 +52,7 @@ te0:; · 2 unmodified lines | ||
| 52 | 52 | tl = -(&&te0 - &&ts0); |
| 53 | 53 | |
| 54 | 54 | /* test data and code suppression */ |
| 55 | − static char ds1 = 0; | |
| 55 | + static const char ds1 = 0; | |
| 56 | 56 | ts1:; |
| 57 | 57 | if (!SKIP) { |
| 58 | 58 | void *p = (void*)&main; |
| @@ -75,7 +75,7 @@ ts1:; · 16 unmodified lines | ||
| 75 | 75 | s.x, s.y, s.z, s.a, s.b); |
| 76 | 76 | } |
| 77 | 77 | te1:; |
| 78 | − static char de1 = 0; | |
| 78 | + static const char de1 = 0; | |
| 79 | 79 | |
| 80 | 80 | dl += &de1 - &ds1; |
| 81 | 81 | tl += &&te1 - &&ts1; |
| @@ -112,7 +112,7 @@ enum { · 111 unmodified lines | ||
| 112 | 112 | #include "tcc.h" |
| 113 | 113 | #include <assert.h> |
| 114 | 114 | |
| 115 | −ST_DATA const char *target_machine_defs = | |
| 115 | +ST_DATA const char * const target_machine_defs = | |
| 116 | 116 | "__x86_64__\0" |
| 117 | 117 | "__amd64__\0" |
| 118 | 118 | ; |
| @@ -575,7 +575,9 @@ void store(int r, SValue *v) · 456 unmodified lines | ||
| 575 | 575 | |
| 576 | 576 | #ifndef TCC_TARGET_PE |
| 577 | 577 | /* we need to access the variable via got */ |
| 578 | − if (fr == VT_CONST && (v->r & VT_SYM)) { | |
| 578 | + if (fr == VT_CONST | |
| 579 | + && (v->r & VT_SYM) | |
| 580 | + && !(v->sym->type.t & VT_STATIC)) { | |
| 579 | 581 | /* mov xx(%rip), %r11 */ |
| 580 | 582 | o(0x1d8b4c); |
| 581 | 583 | gen_gotpcrel(TREG_R11, v->sym, v->c.i); |