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
28262826
28272827 // TODO: Check non-E ABI.
28282828 // 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 };
28302830
28312831 /* mark all used registers */
28322832 memcpy(regs_allocated, clobber_regs, sizeof(regs_allocated));
arm-gen.c+1−1
@@ -141,7 +141,7 @@ enum { · 140 unmodified lines
141141 #define USING_GLOBALS
142142 #include "tcc.h"
143143
144−ST_DATA const char *target_machine_defs =
144+ST_DATA const char * const target_machine_defs =
145145 "__arm__\0"
146146 "__arm\0"
147147 "arm\0"
arm64-gen.c+1−1
@@ -50,7 +50,7 @@ · 49 unmodified lines
5050 #include "tcc.h"
5151 #include <assert.h>
5252
53−ST_DATA const char *target_machine_defs =
53+ST_DATA const char * const target_machine_defs =
5454 "__aarch64__\0"
5555 ;
5656
c67-gen.c+2−2
@@ -116,7 +116,7 @@ enum { · 115 unmodified lines
116116 #define USING_GLOBALS
117117 #include "tcc.h"
118118
119−ST_DATA const char *target_machine_defs =
119+ST_DATA const char * const target_machine_defs =
120120 "__C67__\0"
121121 ;
122122
@@ -371,7 +371,7 @@ int C67_map_D12(char *s) · 248 unmodified lines
371371
372372
373373
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)
375375 {
376376 BOOL xpath;
377377
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
638638 }
639639 #endif
640640
641+
641642 static void maybe_print_stats (void)
642643 {
643− static int already = 1;
644− if (!already)
644+ static int already;
645+
646+ if (0 && !already)
645647 /* print stats about opcodes */
646648 {
647649 const struct ASMInstr *pa;
@@ -1604,12 +1606,12 @@ ST_FUNC void asm_gen_code(ASMOperand *operands, int nb_operands, · 956 unmodified lines
16041606 call-preserved registers, but currently it doesn't matter. */
16051607 #ifdef TCC_TARGET_X86_64
16061608 #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 };
16081610 #else
1609− static uint8_t reg_saved[] = { 3, 12, 13, 14, 15 };
1611+ static const uint8_t reg_saved[] = { 3, 12, 13, 14, 15 };
16101612 #endif
16111613 #else
1612− static uint8_t reg_saved[] = { 3, 6, 7 };
1614+ static const uint8_t reg_saved[] = { 3, 6, 7 };
16131615 #endif
16141616
16151617 /* mark all used registers */
i386-gen.c+5−5
@@ -81,7 +81,7 @@ enum { · 80 unmodified lines
8181 #define USING_GLOBALS
8282 #include "tcc.h"
8383
84−ST_DATA const char *target_machine_defs =
84+ST_DATA const char * const target_machine_defs =
8585 "__i386__\0"
8686 "__i386\0"
8787 ;
@@ -372,8 +372,8 @@ static void gcall_or_jmp(int is_jmp) · 284 unmodified lines
372372 }
373373 }
374374
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 };
377377
378378 /* Return the number of registers needed to return the struct, or 0 if
379379 returning via struct pointer. */
@@ -479,7 +479,7 @@ ST_FUNC void gfunc_call(int nb_args) · 99 unmodified lines
479479 if ((func_call >= FUNC_FASTCALL1 && func_call <= FUNC_FASTCALL3) ||
480480 func_call == FUNC_FASTCALLW) {
481481 int fastcall_nb_regs;
482− uint8_t *fastcall_regs_ptr;
482+ const uint8_t *fastcall_regs_ptr;
483483 if (func_call == FUNC_FASTCALLW) {
484484 fastcall_regs_ptr = fastcallw_regs;
485485 fastcall_nb_regs = 2;
@@ -519,7 +519,7 @@ ST_FUNC void gfunc_prolog(Sym *func_sym) · 33 unmodified lines
519519 CType *func_type = &func_sym->type;
520520 int addr, align, size, func_call, fastcall_nb_regs;
521521 int param_index, param_addr;
522− uint8_t *fastcall_regs_ptr;
522+ const uint8_t *fastcall_regs_ptr;
523523 Sym *sym;
524524 CType *type;
525525
libtcc.c+7−3
@@ -1580,7 +1580,7 @@ static const TCCOption tcc_options[] = { · 1579 unmodified lines
15801580 static const FlagDef options_W[] = {
15811581 { 0, 0, "all" },
15821582 { 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" },
15841584 { offsetof(TCCState, warn_error), 0, "error" },
15851585 { offsetof(TCCState, warn_gcc_compat), 0, "gcc-compat" },
15861586 { 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
19971997 (double)total_time/1000,
19981998 (unsigned)total_lines*1000/total_time,
19991999 (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+ );
20022006 #ifdef MEM_DEBUG
20032007 fprintf(stderr, "* %d bytes memory used\n", mem_max_size);
20042008 #endif
riscv64-gen.c+1−1
@@ -36,7 +36,7 @@ · 35 unmodified lines
3636 #include "tcc.h"
3737 #include <assert.h>
3838
39−ST_DATA const char *target_machine_defs =
39+ST_DATA const char * const target_machine_defs =
4040 "__riscv\0"
4141 "__riscv_xlen 64\0"
4242 "__riscv_flen 64\0"
tcc.h+4−4
@@ -885,7 +885,7 @@ struct TCCState { · 884 unmodified lines
885885 Section *plt;
886886
887887 /* predefined sections */
888− Section *text_section, *data_section, *data_ro_section, *bss_section;
888+ Section *text_section, *data_section, *rodata_section, *bss_section;
889889 Section *common_section;
890890 Section *cur_text_section; /* current section where function code is generated */
891891 #ifdef CONFIG_TCC_BCHECK
@@ -960,7 +960,7 @@ struct TCCState { · 68 unmodified lines
960960 int total_idents;
961961 int total_lines;
962962 int total_bytes;
963− int total_output[3];
963+ int total_output[4];
964964
965965 /* option -dnum (for general development purposes) */
966966 int g_debug;
@@ -1639,7 +1639,7 @@ ST_FUNC void relocate_plt(TCCState *s1); · 672 unmodified lines
16391639 ST_FUNC void relocate(TCCState *s1, ElfW_Rel *rel, int type, unsigned char *ptr, addr_t addr, addr_t val);
16401640
16411641 /* ------------ xxx-gen.c ------------ */
1642−ST_DATA const char *target_machine_defs;
1642+ST_DATA const char * const target_machine_defs;
16431643 ST_DATA const int reg_classes[NB_REGS];
16441644
16451645 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
18421842
18431843 #define text_section TCC_STATE_VAR(text_section)
18441844 #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)
18461846 #define bss_section TCC_STATE_VAR(bss_section)
18471847 #define common_section TCC_STATE_VAR(common_section)
18481848 #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
5858 /* create standard sections */
5959 text_section = new_section(s, ".text", SHT_PROGBITS, SHF_ALLOC | SHF_EXECINSTR);
6060 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
6164 /* 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
6367 bss_section = new_section(s, ".bss", SHT_NOBITS, SHF_ALLOC | SHF_WRITE);
6468 common_section = new_section(s, ".common", SHT_NOBITS, SHF_PRIVATE);
6569 common_section->sh_num = SHN_COMMON;
@@ -206,7 +210,7 @@ ST_FUNC void tccelf_end_file(TCCState *s1) · 140 unmodified lines
206210 tcc_free(tr);
207211
208212 /* record text/data/bss output for -bench info */
209− for (i = 0; i < 3; ++i) {
213+ for (i = 0; i < 4; ++i) {
210214 s = s1->sections[i + 1];
211215 s1->total_output[i] += s->data_offset - s->sh_offset;
212216 }
@@ -1255,11 +1259,16 @@ redo: · 1042 unmodified lines
12551259 && ELFW(ST_TYPE)(sym->st_info) == STT_FUNC)))
12561260 goto jmp_slot;
12571261 }
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;
12591265 #ifndef TCC_TARGET_ARM
1260− && PTR_SIZE == 8
1266+ if (PTR_SIZE != 8)
1267+ continue;
12611268 #endif
1262− ))
1269+ /* from tcc_add_symbol(): on 64 bit platforms these
1270+ need to go through .got */
1271+ } else
12631272 continue;
12641273 }
12651274
@@ -1314,7 +1323,7 @@ redo: · 48 unmodified lines
13141323
13151324 ST_FUNC int set_global_sym(TCCState *s1, const char *name, Section *sec, addr_t offs)
13161325 {
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;
13181327 if (sec && offs == -1)
13191328 offs = sec->data_offset;
13201329 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
13261335 Section *s;
13271336 addr_t end_offset;
13281337 char buf[1024];
1329− s = find_section(s1, section_name);
1338+ s = find_section_create(s1, section_name, 0);
13301339 if (!s) {
13311340 end_offset = 0;
13321341 s = data_section;
@@ -1407,12 +1416,8 @@ ST_FUNC void tcc_add_btstub(TCCState *s1) · 74 unmodified lines
14071416 put_ptr(s1, stab_section, -1);
14081417 put_ptr(s1, stab_section->link, 0);
14091418 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);
14161421 n = 2 * PTR_SIZE;
14171422 #ifdef CONFIG_TCC_BCHECK
14181423 if (s1->do_bounds_check) {
@@ -1421,10 +1426,10 @@ ST_FUNC void tcc_add_btstub(TCCState *s1) · 2 unmodified lines
14211426 }
14221427 #endif
14231428 section_ptr_add(s, n);
1424−
14251429 cstr_new(&cstr);
14261430 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[];"
14281433 "__attribute__((constructor)) static void __bt_init_rt(){");
14291434 #ifdef TCC_TARGET_PE
14301435 if (s1->output_type == TCC_OUTPUT_DLL)
@@ -1526,8 +1531,9 @@ ST_FUNC void tcc_add_runtime(TCCState *s1) · 95 unmodified lines
15261531 tcc_add_btstub(s1);
15271532 }
15281533 #endif
1529− if (strlen(TCC_LIBTCC1) > 0)
1534+ if (TCC_LIBTCC1[0])
15301535 tcc_add_support(s1, TCC_LIBTCC1);
1536+
15311537 #if TARGETOS_OpenBSD || TARGETOS_FreeBSD || TARGETOS_NetBSD
15321538 /* add crt end if not memory output */
15331539 if (s1->output_type != TCC_OUTPUT_MEMORY) {
@@ -1568,7 +1574,9 @@ static void tcc_add_linker_symbols(TCCState *s1) · 34 unmodified lines
15681574 set_global_sym(s1, "__global_pointer$", data_section, 0x800);
15691575 #endif
15701576 /* horrible new standard ldscript defines */
1577+#ifndef TCC_TARGET_PE
15711578 add_init_array_defines(s1, ".preinit_array");
1579+#endif
15721580 add_init_array_defines(s1, ".init_array");
15731581 add_init_array_defines(s1, ".fini_array");
15741582 /* 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
19962004 } else if (s->sh_type == SHT_NOBITS) {
19972005 if (k != 6)
19982006 continue;
1999− } else if (s == data_ro_section ||
2007+ } else if ((s == rodata_section
20002008 #ifdef CONFIG_TCC_BCHECK
2001− s == bounds_section ||
2002− s == lbounds_section ||
2009+ || s == bounds_section
2010+ || s == lbounds_section
20032011 #endif
2004− 0) {
2012+ ) && (s->sh_flags & SHF_WRITE)) {
20052013 if (k != 4)
20062014 continue;
20072015 /* Align next section on page size.
@@ -2029,18 +2037,15 @@ static int layout_sections(TCCState *s1, ElfW(Phdr) *phdr, · 21 unmodified lines
20292037 ph->p_vaddr = addr;
20302038 ph->p_paddr = ph->p_vaddr;
20312039 }
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) {
20382042 if (roinf->sh_size == 0) {
20392043 roinf->sh_offset = s->sh_offset;
20402044 roinf->sh_addr = s->sh_addr;
20412045 }
20422046 roinf->sh_size = (addr - roinf->sh_addr) + s->sh_size;
20432047 }
2048+
20442049 addr += s->sh_size;
20452050 if (s->sh_type != SHT_NOBITS)
20462051 file_offset += s->sh_size;
tccgen.c+23−12
@@ -2356,7 +2356,7 @@ ST_FUNC int gv(int rc) · 2355 unmodified lines
23562356 (vtop->r & (VT_VALMASK | VT_LVAL)) == VT_CONST) {
23572357 /* CPUs usually cannot use float constants, so we store them
23582358 generically in data segment */
2359− init_params p = { data_section };
2359+ init_params p = { rodata_section };
23602360 unsigned long offset;
23612361 size = type_size(&vtop->type, &align);
23622362 if (NODATA_WANTED)
@@ -3095,11 +3095,12 @@ static void type_to_str(char *buf, int buf_size, · 732 unmodified lines
30953095 pstrcat(buf, buf_size, "typedef ");
30963096 if (t & VT_INLINE)
30973097 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+ }
31033104 if (((t & VT_DEFSIGN) && bt == VT_BYTE)
31043105 || ((t & VT_UNSIGNED)
31053106 && (bt == VT_SHORT || bt == VT_INT || bt == VT_LLONG)
@@ -5932,18 +5933,22 @@ ST_FUNC void unary(void) · 2826 unmodified lines
59325933 /* fall thru */
59335934 case TOK___FUNC__:
59345935 {
5936+ Section *sec;
59355937 void *ptr;
59365938 int len;
59375939 /* special function name identifier */
59385940 len = strlen(funcname) + 1;
59395941 /* generate char[len] type */
59405942 type.t = VT_BYTE;
5943+ if (tcc_state->warn_write_strings)
5944+ type.t |= VT_CONSTANT;
59415945 mk_pointer(&type);
59425946 type.t |= VT_ARRAY;
59435947 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);
59455950 if (!NODATA_WANTED) {
5946− ptr = section_ptr_add(data_section, len);
5951+ ptr = section_ptr_add(sec, len);
59475952 memcpy(ptr, funcname, len);
59485953 }
59495954 next();
@@ -5968,6 +5973,7 @@ ST_FUNC void unary(void) · 18 unmodified lines
59685973 mk_pointer(&type);
59695974 type.t |= VT_ARRAY;
59705975 memset(&ad, 0, sizeof(AttributeDef));
5976+ ad.section = rodata_section;
59715977 decl_initializer_alloc(&type, &ad, VT_CONST, 2, 0, 0);
59725978 break;
59735979 case '(':
@@ -8526,11 +8532,16 @@ static void decl_initializer_alloc(CType *type, AttributeDef *ad, int r, · 2552 unmodified lines
85268532 /* allocate symbol in corresponding section */
85278533 sec = ad->section;
85288534 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) {
85328541 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)
85348545 sec = bss_section;
85358546 }
85368547
tccmacho.c+4−4
@@ -259,7 +259,7 @@ static void * add_lc(struct macho *mo, uint32_t cmd, uint32_t cmdsize) · 258 unmodified lines
259259 return lc;
260260 }
261261
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)
263263 {
264264 struct segment_command_64 *sc = add_lc(mo, LC_SEGMENT_64, sizeof(*sc));
265265 strncpy(sc->segname, name, 16);
@@ -272,7 +272,7 @@ static struct segment_command_64 * get_segment(struct macho *mo, int i) · 6 unmodified lines
272272 return (struct segment_command_64 *) (mo->lc[mo->seg2lc[i]]);
273273 }
274274
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)
276276 {
277277 struct segment_command_64 *seg = *_seg;
278278 int ret = seg->nsects;
@@ -525,10 +525,10 @@ static void create_symtab(TCCState *s1, struct macho *mo) · 246 unmodified lines
525525 }
526526 }
527527
528−struct {
528+const struct {
529529 int seg;
530530 uint32_t flags;
531− char *name;
531+ const char *name;
532532 } skinfo[sk_last] = {
533533 /*[sk_unknown] =*/ { 0 },
534534 /*[sk_discard] =*/ { 0 },
tccpe.c+25−19
@@ -20,8 +20,8 @@ · 19 unmodified lines
2020
2121 #include "tcc.h"
2222
23−#define PE_MERGE_DATA
24−/* #define PE_PRINT_SECTIONS */
23+#define PE_MERGE_DATA 1
24+#define PE_PRINT_SECTIONS 0
2525
2626 #ifndef _WIN32
2727 #define stricmp strcasecmp
@@ -294,6 +294,7 @@ struct pe_rsrc_reloc { · 266 unmodified lines
294294
295295 enum {
296296 sec_text = 0,
297+ sec_rdata ,
297298 sec_data ,
298299 sec_bss ,
299300 sec_idata ,
@@ -725,6 +726,8 @@ static int pe_write(struct pe_info *pe) · 425 unmodified lines
725726 for (i = 0; i < pe->sec_count; ++i) {
726727 Section *s;
727728 si = pe->sec_info[i];
729+ if (!si->data_size)
730+ continue;
728731 for (s = si->sec; s; s = s->prev) {
729732 pe_fpad(&pf, file_offset);
730733 pe_fwrite(s->data, s->data_offset, &pf);
@@ -1084,6 +1087,7 @@ static int pe_section_class(Section *s) · 353 unmodified lines
10841087 return sec_idata;
10851088 if (0 == strcmp(name, ".pdata"))
10861089 return sec_pdata;
1090+ return sec_rdata;
10871091 } else if (type == SHT_NOBITS) {
10881092 if (flags & SHF_WRITE)
10891093 return sec_bss;
@@ -1106,6 +1110,7 @@ static int pe_assign_addresses (struct pe_info *pe) · 16 unmodified lines
11061110 int *section_order;
11071111 struct section_info *si;
11081112 Section *s;
1113+ TCCState *s1 = pe->s1;
11091114
11101115 if (PE_DLL == pe->type)
11111116 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
11131118
11141119 section_order = tcc_malloc(pe->s1->nb_sections * sizeof (int));
11151120 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];
11181123 if (k == pe_section_class(s))
11191124 section_order[o++] = i;
11201125 }
@@ -1125,16 +1130,15 @@ static int pe_assign_addresses (struct pe_info *pe) · 4 unmodified lines
11251130
11261131 for (i = 0; i < o; ++i) {
11271132 k = section_order[i];
1128− s = pe->s1->sections[k];
1133+ s = s1->sections[k];
11291134 c = pe_section_class(s);
11301135
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)
11321137 continue;
11331138
1134−#ifdef PE_MERGE_DATA
1135− if (c == sec_bss)
1139+ if (PE_MERGE_DATA && c == sec_bss)
11361140 c = sec_data;
1137−#endif
1141+
11381142 if (si && c == si->cls) {
11391143 /* merge with previous section */
11401144 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
11431147 s->sh_addr = addr = pe_virtual_align(pe, addr);
11441148 }
11451149
1146− if (c == sec_data && NULL == pe->thunk)
1150+ if (NULL == pe->thunk
1151+ && c == (data_section == rodata_section ? sec_data : sec_rdata))
11471152 pe->thunk = s;
11481153
11491154 if (s == pe->thunk) {
@@ -1192,8 +1197,8 @@ add_section: · 42 unmodified lines
11921197 }
11931198 tcc_free(section_order);
11941199 #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];
11971202 int type = s->sh_type;
11981203 int flags = s->sh_flags;
11991204 printf("section %-16s %-10s %08x %04x %s,%s,%s\n",
@@ -1210,7 +1215,7 @@ add_section: · 10 unmodified lines
12101215 flags & SHF_EXECINSTR ? "exec" : ""
12111216 );
12121217 }
1213− pe->s1->verbose = 2;
1218+ s1->verbose = 2;
12141219 #endif
12151220 return 0;
12161221 }
@@ -1345,7 +1350,7 @@ static int pe_check_symbols(struct pe_info *pe) · 128 unmodified lines
13451350 }
13461351
13471352 /*----------------------------------------------------------------------------*/
1348−#ifdef PE_PRINT_SECTIONS
1353+#if PE_PRINT_SECTIONS
13491354 static void pe_print_section(FILE * f, Section * s)
13501355 {
13511356 /* just if you're curious */
@@ -1923,11 +1928,11 @@ static void pe_add_runtime(TCCState *s1, struct pe_info *pe) · 571 unmodified lines
19231928 set_global_sym(s1, start_symbol, NULL, 0);
19241929
19251930 if (0 == s1->nostdlib) {
1926− static const char *libs[] = {
1931+ static const char * const libs[] = {
19271932 "msvcrt", "kernel32", "", "user32", "gdi32", NULL
19281933 };
1929− const char **pp, *p;
1930− if (strlen(TCC_LIBTCC1) > 0)
1934+ const char * const *pp, *p;
1935+ if (TCC_LIBTCC1[0])
19311936 tcc_add_support(s1, TCC_LIBTCC1);
19321937 for (pp = libs; 0 != (p = *pp); ++pp) {
19331938 if (*p)
@@ -2038,8 +2043,9 @@ ST_FUNC int pe_output_file(TCCState *s1, const char *filename) · 104 unmodified lines
20382043
20392044 pe_free_imports(&pe);
20402045
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");
20432049 #endif
20442050 return ret;
20452051 }
tccpp.c+1−1
@@ -3669,7 +3669,7 @@ ST_INLN void unget_tok(int last_tok) · 3668 unmodified lines
36693669 /* ------------------------------------------------------------------------- */
36703670 /* init preprocessor */
36713671
3672−static const char *target_os_defs =
3672+static const char * const target_os_defs =
36733673 #ifdef TCC_TARGET_PE
36743674 "_WIN32\0"
36753675 # if PTR_SIZE == 8
tccrun.c+104−56
@@ -55,7 +55,7 @@ static void rt_exit(int code); · 54 unmodified lines
5555 # include <sys/mman.h>
5656 #endif
5757
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);
5959 static int tcc_relocate_ex(TCCState *s1, void *ptr, addr_t ptr_diff);
6060
6161 #ifdef _WIN64
@@ -94,7 +94,6 @@ LIBTCCAPI int tcc_relocate(TCCState *s1, void *ptr) · 32 unmodified lines
9494 prx = mmap((char*)ptr + size, size, PROT_READ|PROT_EXEC, MAP_SHARED|MAP_FIXED, fd, 0);
9595 if (ptr == MAP_FAILED || prx == MAP_FAILED)
9696 tcc_error("tccrun: could not map memory");
97− dynarray_add(&s1->runtime_mem, &s1->nb_runtime_mem, (void*)(addr_t)(size*2));
9897 ptr_diff = (char*)prx - (char*)ptr;
9998 close(fd);
10099 //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
103102 ptr = tcc_malloc(size);
104103 #endif
105104 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);
106106 dynarray_add(&s1->runtime_mem, &s1->nb_runtime_mem, ptr);
107107 return 0;
108108 }
@@ -111,15 +111,18 @@ ST_FUNC void tcc_run_free(TCCState *s1) · 2 unmodified lines
111111 {
112112 int i;
113113
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];
115117 #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);
118119 #else
120+ /* unprotect memory to make it usable for malloc again */
121+ set_pages_executable(s1, 2, ptr, size);
119122 #ifdef _WIN64
120− win64_del_function_table(*(void**)s1->runtime_mem[i]);
123+ win64_del_function_table(*(void**)ptr);
121124 #endif
122− tcc_free(s1->runtime_mem[i]);
125+ tcc_free(ptr);
123126 #endif
124127 }
125128 tcc_free(s1->runtime_mem);
@@ -182,8 +185,9 @@ LIBTCCAPI int tcc_run(TCCState *s1, int argc, char **argv) · 56 unmodified lines
182185 *(void**)p = _rt_error;
183186 #ifdef CONFIG_TCC_BCHECK
184187 if (s1->do_bounds_check) {
188+ rc->bounds_start = (void*)bounds_section->sh_addr;
185189 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);
187191 }
188192 #endif
189193 set_exception_handler();
@@ -207,13 +211,20 @@ LIBTCCAPI int tcc_run(TCCState *s1, int argc, char **argv) · 17 unmodified lines
207211 return ret;
208212 }
209213
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
211222 /* To avoid that x86 processors would reload cached instructions
212223 each time when data is written in the near, we need to make
213224 sure that code and data do not share the same 64 byte unit */
214− #define RUN_SECTION_ALIGNMENT 63
225+# define PAGE_ALIGN 64
215226 #else
216− #define RUN_SECTION_ALIGNMENT 0
227+# define PAGE_ALIGN 1
217228 #endif
218229
219230 /* 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
222233 {
223234 Section *s;
224235 unsigned offset, length, align, max_align, i, k, f;
236+ unsigned n, copy;
225237 addr_t mem, addr;
226238
227239 if (NULL == ptr) {
@@ -241,35 +253,80 @@ static int tcc_relocate_ex(TCCState *s1, void *ptr, addr_t ptr_diff) · 13 unmodified lines
241253 #ifdef _WIN64
242254 offset += sizeof (void*); /* space for function_table pointer */
243255 #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;
246260 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+ };
247264 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)))
249266 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;
251289 continue;
290+ }
252291 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);
255294 if (max_align < align)
256295 max_align = align;
296+ addr = k ? mem : mem + ptr_diff;
257297 offset += -(addr + offset) & align;
258298 s->sh_addr = mem ? addr + offset : 0;
259− offset += s->data_offset;
260−#if 0
299+ offset += length;
300+#if DEBUG_RUNMEN
261301 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);
264317 #endif
318+ if (n)
319+ set_pages_executable(s1, f, (void*)addr, n);
265320 }
266321 }
267322
323+ if (copy)
324+ return 0;
325+
268326 /* relocate symbols */
269327 relocate_syms(s1, s1->symtab, !(s1->nostdlib));
270328 if (s1->nb_errors)
271329 return -1;
272−
273330 if (0 == mem)
274331 return offset + max_align;
275332
@@ -282,55 +339,46 @@ static int tcc_relocate_ex(TCCState *s1, void *ptr, addr_t ptr_diff) · 6 unmodified lines
282339 relocate_plt(s1);
283340 #endif
284341 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;
308344 }
309345
310346 /* ------------------------------------------------------------- */
311347 /* allow to run code in memory */
312348
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)
314350 {
315351 #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);
318360 #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+ };
321367 addr_t start, end;
322368 start = (addr_t)ptr & ~(PAGESIZE - 1);
323369 end = (addr_t)ptr + length;
324370 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]))
326372 tcc_error("mprotect failed: did you mean to configure --with-selinux?");
327−# endif
373+
328374 /* 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+ }
333380 # endif
381+
334382 #endif
335383 }
336384
tcctools.c+5−12
@@ -68,7 +68,7 @@ static int ar_usage(int ret) { · 67 unmodified lines
6868
6969 ST_FUNC int tcc_tool_ar(TCCState *s1, int argc, char **argv)
7070 {
71− static ArHdr arhdr = {
71+ static const ArHdr arhdr_init = {
7272 "/ ",
7373 " ",
7474 "0 ",
@@ -78,15 +78,8 @@ ST_FUNC int tcc_tool_ar(TCCState *s1, int argc, char **argv) · 3 unmodified lines
7878 ARFMAG
7979 };
8080
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;
9083
9184 FILE *fi, *fh = NULL, *fo = NULL;
9285 ElfW(Ehdr) *ehdr;
@@ -506,9 +499,9 @@ ST_FUNC void tcc_tool_cross(TCCState *s1, char **argv, int target) · 413 unmodified lines
506499 /* enable commandline wildcard expansion (tcc -o x.exe *.c) */
507500
508501 #ifdef _WIN32
509−int _CRT_glob = 1;
502+const int _CRT_glob = 1;
510503 #ifndef _CRT_glob
511−int _dowildcard = 1;
504+const int _dowildcard = 1;
512505 #endif
513506 #endif
514507
tests/tests2/96_nodata_wanted.c+4−4
@@ -42,8 +42,8 @@ int main() · 41 unmodified lines
4242 __label__ ts0, te0, ts1, te1;
4343 int tl, dl;
4444
45− static char ds0 = 0;
46− static char de0 = 0;
45+ static const char ds0 = 0;
46+ static const char de0 = 0;
4747 /* get reference size of empty jmp */
4848 ts0:;
4949 if (!SKIP) {}
@@ -52,7 +52,7 @@ te0:; · 2 unmodified lines
5252 tl = -(&&te0 - &&ts0);
5353
5454 /* test data and code suppression */
55− static char ds1 = 0;
55+ static const char ds1 = 0;
5656 ts1:;
5757 if (!SKIP) {
5858 void *p = (void*)&main;
@@ -75,7 +75,7 @@ ts1:; · 16 unmodified lines
7575 s.x, s.y, s.z, s.a, s.b);
7676 }
7777 te1:;
78− static char de1 = 0;
78+ static const char de1 = 0;
7979
8080 dl += &de1 - &ds1;
8181 tl += &&te1 - &&ts1;
x86_64-gen.c+4−2
@@ -112,7 +112,7 @@ enum { · 111 unmodified lines
112112 #include "tcc.h"
113113 #include <assert.h>
114114
115−ST_DATA const char *target_machine_defs =
115+ST_DATA const char * const target_machine_defs =
116116 "__x86_64__\0"
117117 "__amd64__\0"
118118 ;
@@ -575,7 +575,9 @@ void store(int r, SValue *v) · 456 unmodified lines
575575
576576 #ifndef TCC_TARGET_PE
577577 /* 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)) {
579581 /* mov xx(%rip), %r11 */
580582 o(0x1d8b4c);
581583 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