History

tccelf: use rodata_section, use more rodata in tcc itself

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

grischka committed 5 years ago

Commit 72f1dea1 parent 027951018 files · +230 −159Browse files

Unified · Split

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

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t