History

bcheck cleanup

- revert Makefiles to state before last bcheck additions Instead, just load bcheck.o explicitly if that is what is wanted. - move tcc_add_bcheck() to the <target>-link.c files and remove revently added arguments. This function is to support tccelf.c with linking, not for tccgen.c to support compilation. - remove -ba option: It said: "-ba Enable better address checking with bounds checker" Okay, if it is better then to have it is not an option. - remove va_copy. It is C99 and we try to stay C89 in tinycc when possible. For example, MS compilers do not have va_copy. - win64: revert any 'fixes' to alloca It was correct as it was before, except for bound_checking where it was not implemented. This should now work too. - remove parasitic filename:linenum features Such feature is already present with rt_printline in tccrun.c. If it doesn't work it can be fixed. - revert changes to gen_bounded_ptr_add() gen_bounded_ptr_add() was working as it should before (mostly). For the sake of simplicity I switched it to CDECL. Anyway, FASTCALL means SLOWCALL with tinycc. In exchange you get one addition which is required for bounds_cnecking function arguments. The important thing is to check them *BEFORE* they are loaded into registers. New function gbound_args() does that. In any case, code instrumentation with the bounds-check functions as such now seems to work flawlessly again, which means when they are inserted as NOPs, any code that tcc can compile, seems to behave just the same as without them. What these functions then do when fully enabled, is a differnt story. I did not touch this.

grischka committed 6 years ago

Commit 56db0921 parent a86f47819 files · +324 −506Browse files

Unified · Split

19 files
  1. Makefile +7 −16
  2. i386-gen.c +23 −115
  3. i386-link.c +75 −0
  4. lib/Makefile +17 −32
  5. lib/alloca86_64-bt.S +9 −28
  6. lib/alloca86_64.S +0 −4
  7. lib/bcheck.c +17 −14
  8. lib/dummy.c +0 −1
  9. libtcc.c +0 −4
  10. tcc.c +0 −1
  11. tcc.h +4 −5
  12. tccelf.c +2 −2
  13. tccgen.c +21 −20
  14. tccpe.c +14 −22
  15. tccpp.c +3 −4
  16. tcctok.h +3 −0
  17. tests/Makefile +7 −8
  18. x86_64-gen.c +37 −230
  19. x86_64-link.c +85 −0
Makefile+7−16
@@ -16,7 +16,6 @@ endif · 15 unmodified lines
1616
1717 LIBTCC = libtcc.a
1818 LIBTCC1 = libtcc1.a
19−LIBTCCB1 = libtccb1.a
2019 LINK_LIBTCC =
2120 LIBS =
2221 CFLAGS += -I$(TOP)
@@ -87,7 +86,7 @@ ifeq ($(INCLUDED),no) · 64 unmodified lines
8786 # running top Makefile
8887
8988 PROGS = tcc$(EXESUF)
90−TCCLIBS = $(LIBTCC1) $(LIBTCCB1) $(LIBTCC) $(LIBTCCDEF)
89+TCCLIBS = $(LIBTCC1) $(LIBTCC) $(LIBTCCDEF)
9190 TCCDOCS = tcc.1 tcc-doc.html tcc-doc.info
9291
9392 all: $(PROGS) $(TCCLIBS) $(TCCDOCS)
@@ -101,15 +100,11 @@ TCC_X += riscv64 · 7 unmodified lines
101100 LIBTCC1_X = i386 x86_64 i386-win32 x86_64-win32 x86_64-osx arm arm64 arm-wince
102101 LIBTCC1_X += riscv64
103102
104−# cross libtccb1.a targets to build
105−LIBTCCB1_X = i386 x86_64 i386-win32 x86_64-win32
106−
107103 PROGS_CROSS = $(foreach X,$(TCC_X),$X-tcc$(EXESUF))
108104 LIBTCC1_CROSS = $(foreach X,$(LIBTCC1_X),$X-libtcc1.a)
109−LIBTCCB1_CROSS = $(foreach X,$(LIBTCCB1_X),$X-libtcc1.a)
110105
111106 # build cross compilers & libs
112−cross: $(LIBTCC1_CROSS) $(LIBTCCB1_CROSS) $(PROGS_CROSS)
107+cross: $(LIBTCC1_CROSS) $(PROGS_CROSS)
113108
114109 # build specific cross compiler & lib
115110 cross-%: %-tcc$(EXESUF) %-libtcc1.a ;
@@ -153,10 +148,10 @@ DEFINES += $(DEF-$(or $(findstring win,$T),unx)) · 37 unmodified lines
153148
154149 ifneq ($(X),)
155150 ifeq ($(CONFIG_WIN32),yes)
156−DEF-win += -DTCC_LIBTCC1="\"$(X)libtcc1.a\"" -DTCC_LIBTCCB1="\"$(X)libtccb1.a\""
157−DEF-unx += -DTCC_LIBTCC1="\"lib/$(X)libtcc1.a\"" -DTCC_LIBTCCB1="\"lib/$(X)libtccb1.a\""
151+DEF-win += -DTCC_LIBTCC1="\"$(X)libtcc1.a\""
152+DEF-unx += -DTCC_LIBTCC1="\"lib/$(X)libtcc1.a\""
158153 else
159−DEF-all += -DTCC_LIBTCC1="\"$(X)libtcc1.a\"" -DTCC_LIBTCCB1="\"$(X)libtccb1.a\""
154+DEF-all += -DTCC_LIBTCC1="\"$(X)libtcc1.a\""
160155 DEF-win += -DCONFIG_TCCDIR="\"$(tccdir)/win32\""
161156 endif
162157 endif
@@ -281,8 +276,6 @@ STRIP_yes = -s · 118 unmodified lines
281276
282277 LIBTCC1_W = $(filter %-win32-libtcc1.a %-wince-libtcc1.a,$(LIBTCC1_CROSS))
283278 LIBTCC1_U = $(filter-out $(LIBTCC1_W),$(LIBTCC1_CROSS))
284−LIBTCCB1_W = $(filter %-win32-libtccb1.a %-wince-libtccb1.a,$(LIBTCCB1_CROSS))
285−LIBTCCB1_U = $(filter-out $(LIBTCCB1_W),$(LIBTCCB1_CROSS))
286279 IB = $(if $1,mkdir -p $2 && $(INSTALLBIN) $1 $2)
287280 IBw = $(call IB,$(wildcard $1),$2)
288281 IF = $(if $1,mkdir -p $2 && $(INSTALL) $1 $2)
@@ -292,8 +285,7 @@ IR = mkdir -p $2 && cp -r $1/. $2 · 3 unmodified lines
292285 # install progs & libs
293286 install-unx:
294287 $(call IBw,$(PROGS) $(PROGS_CROSS),"$(bindir)")
295− $(call IFw,$(LIBTCC1) $(LIBTCC1_U),"$(tccdir)")
296− $(call IFw,$(LIBTCCB1) $(LIBTCCB1_U),"$(tccdir)")
288+ $(call IFw,$(LIBTCC1) bcheck.o $(LIBTCC1_U),"$(tccdir)")
297289 $(call IF,$(TOPSRC)/include/*.h $(TOPSRC)/tcclib.h,"$(tccdir)/include")
298290 $(call $(if $(findstring .so,$(LIBTCC)),IBw,IFw),$(LIBTCC),"$(libdir)")
299291 $(call IF,$(TOPSRC)/libtcc.h,"$(includedir)")
@@ -318,8 +310,7 @@ uninstall-unx: · 18 unmodified lines
318310 install-win:
319311 $(call IBw,$(PROGS) $(PROGS_CROSS) $(subst libtcc.a,,$(LIBTCC)),"$(bindir)")
320312 $(call IF,$(TOPSRC)/win32/lib/*.def,"$(tccdir)/lib")
321− $(call IFw,libtcc1.a $(LIBTCC1_W),"$(tccdir)/lib")
322− $(call IFw,libtccb1.a $(LIBTCCB1_W),"$(tccdir)/lib")
313+ $(call IFw,libtcc1.a bcheck.o $(LIBTCC1_W),"$(tccdir)/lib")
323314 $(call IF,$(TOPSRC)/include/*.h $(TOPSRC)/tcclib.h,"$(tccdir)/include")
324315 $(call IR,$(TOPSRC)/win32/include,"$(tccdir)/include")
325316 $(call IR,$(TOPSRC)/win32/examples,"$(tccdir)/examples")
i386-gen.c+23−115
@@ -425,6 +425,11 @@ ST_FUNC void gfunc_call(int nb_args) · 424 unmodified lines
425425 int size, align, r, args_size, i, func_call;
426426 Sym *func_sym;
427427
428+#ifdef CONFIG_TCC_BCHECK
429+ if (tcc_state->do_bounds_check)
430+ gbound_args(nb_args);
431+#endif
432+
428433 args_size = 0;
429434 for(i = 0;i < nb_args; i++) {
430435 if ((vtop->type.t & VT_BTYPE) == VT_STRUCT) {
@@ -1051,119 +1056,18 @@ ST_FUNC void ggoto(void) · 620 unmodified lines
10511056
10521057 /* bound check support functions */
10531058 #ifdef CONFIG_TCC_BCHECK
1054−
1055−ST_FUNC void tcc_add_bcheck(TCCState *s1, Section *bound_sec, Section *sym_sec)
1056−{
1057− addr_t *ptr;
1058− int loc_glob;
1059− int sym_index;
1060− int bsym_index;
1061−
1062− if (0 == s1->do_bounds_check)
1063− return;
1064− /* XXX: add an object file to do that */
1065− ptr = section_ptr_add(bound_sec, sizeof(*ptr));
1066− *ptr = 0;
1067− loc_glob = s1->output_type != TCC_OUTPUT_MEMORY ? STB_LOCAL : STB_GLOBAL;
1068− bsym_index = set_elf_sym(sym_sec, 0, 0,
1069− ELFW(ST_INFO)(loc_glob, STT_NOTYPE), 0,
1070− bound_sec->sh_num, "__bounds_start");
1071− /* pull bcheck.o from libtcc1.a */
1072− sym_index = set_elf_sym(sym_sec, 0, 0,
1073− ELFW(ST_INFO)(STB_GLOBAL, STT_NOTYPE), 0,
1074− SHN_UNDEF, "__bound_init");
1075− if (s1->output_type != TCC_OUTPUT_MEMORY) {
1076− /* add 'call __bound_init()' in .init section */
1077− Section *init_section = find_section(s1, ".init");
1078− unsigned char *pinit;
1079−#ifdef TCC_TARGET_PE
1080− pinit = section_ptr_add(init_section, 3);
1081− pinit[0] = 0x55; /* push %rbp */
1082− pinit[1] = 0x89; /* mov %esp,%ebp */
1083− pinit[2] = 0xe5;
1084−#endif
1085− pinit = section_ptr_add(init_section, 5);
1086− pinit[0] = 0xe8;
1087− write32le(pinit + 1, -4);
1088− put_elf_reloc(sym_sec, init_section,
1089− init_section->data_offset - 4, R_386_PC32, sym_index);
1090− /* R_386_PC32 = R_X86_64_PC32 = 2 */
1091− pinit = section_ptr_add(init_section, 6);
1092− pinit[0] = 0xb8; /* mov xx,%eax */
1093− write32le(pinit + 1, 0);
1094− pinit[5] = 0x50; /* push %eax */
1095− put_elf_reloc(sym_sec, init_section,
1096− init_section->data_offset - 5, R_386_32, bsym_index);
1097− sym_index = set_elf_sym(sym_sec, 0, 0,
1098− ELFW(ST_INFO)(STB_GLOBAL, STT_NOTYPE), 0,
1099− SHN_UNDEF, "__bounds_add_static_var");
1100− pinit = section_ptr_add(init_section, 5);
1101− pinit[0] = 0xe8;
1102− write32le(pinit + 1, -4);
1103− put_elf_reloc(sym_sec, init_section,
1104− init_section->data_offset - 4, R_386_PC32, sym_index);
1105− /* R_386_PC32 = R_X86_64_PC32 = 2 */
1106− pinit = section_ptr_add(init_section, 3);
1107− pinit[0] = 0x83; /* add $0x4,%esp */
1108− pinit[1] = 0xc4;
1109− pinit[2] = 0x04;
1110−#ifdef TCC_TARGET_PE
1111− {
1112− int init_index = set_elf_sym(sym_sec,
1113− 0, 0,
1114− ELFW(ST_INFO)(STB_GLOBAL, STT_NOTYPE), 0,
1115− init_section->sh_num, "__init_start");
1116− Sym sym;
1117− init_section->sh_flags |= SHF_EXECINSTR;
1118− pinit = section_ptr_add(init_section, 2);
1119− pinit[0] = 0xc9; /* leave */
1120− pinit[1] = 0xc3; /* ret */
1121− sym.c = init_index;
1122− add_init_array (s1, &sym);
1123− }
1124−#endif
1125− }
1126−}
1127−
11281059 /* generate a bounded pointer addition */
11291060 ST_FUNC void gen_bounded_ptr_add(void)
11301061 {
1131− /* save all temporary registers */
1132− save_regs(0);
1133− /* prepare fast i386 function call (args in eax and edx) */
1134− gv2(RC_EAX, RC_EDX);
1135− vtop -= 2;
1136− /* add line, filename */
1137− {
1138− static addr_t offset;
1139− static char last_filename[1024];
1140− Sym *sym_data;
1141−
1142− if (strcmp (last_filename, file->filename) != 0) {
1143− void *ptr;
1144− int len = strlen (file->filename) + 1;
1145−
1146− offset = data_section->data_offset;
1147− ptr = section_ptr_add(data_section, len);
1148− memcpy (ptr, file->filename, len);
1149− memcpy (last_filename, file->filename, len);
1150− }
1151− o(0xb9); /* mov $xx,%ecx */
1152− gen_le32 (0);
1153− sym_data = get_sym_ref(&char_pointer_type, data_section,
1154− offset, data_section->data_offset);
1155− greloca(cur_text_section, sym_data, ind - 4, R_386_32, 0);
1156− o(0x51); /* push %ecx */
1157− }
1158− o(0xb9); /* mov $xx,%ecx */
1159− gen_le32 (file->line_num);
1160− /* do a fast function call */
1161− gen_static_call(TOK___bound_ptr_add);
1162− o(0x04c483); /* add $4,%esp */
1062+ vpush_global_sym(&func_old_type, TOK___bound_ptr_add);
1063+ vrott(3);
1064+ gfunc_call(2);
1065+ vpushi(0);
11631066 /* returned pointer is in eax */
1164− vtop++;
11651067 vtop->r = TREG_EAX | VT_BOUNDED;
1166− /* address of bounding function call point */
1068+ if (nocode_wanted)
1069+ return;
1070+ /* relocation offset of the bounding function call point */
11671071 vtop->c.i = (cur_text_section->reloc->data_offset - sizeof(Elf32_Rel));
11681072 }
11691073
@@ -1176,6 +1080,9 @@ ST_FUNC void gen_bounded_ptr_deref(void) · 6 unmodified lines
11761080 Elf32_Rel *rel;
11771081 Sym *sym;
11781082
1083+ if (nocode_wanted)
1084+ return;
1085+
11791086 size = 0;
11801087 /* XXX: put that code in generic part of tcc */
11811088 if (!is_float(vtop->type.t)) {
@@ -1194,17 +1101,18 @@ ST_FUNC void gen_bounded_ptr_deref(void) · 12 unmodified lines
11941101 case 12: func = TOK___bound_ptr_indir12; break;
11951102 case 16: func = TOK___bound_ptr_indir16; break;
11961103 default:
1197− tcc_error("unhandled size when dereferencing bounded pointer");
1198− func = 0;
1199− break;
1104+ /* may happen with struct member access */
1105+ return;
1106+ //tcc_error("unhandled size when dereferencing bounded pointer");
1107+ //func = 0;
1108+ //break;
12001109 }
1201−
1202− /* patch relocation */
1203− /* XXX: find a better solution ? */
1204− rel = (Elf32_Rel *)(cur_text_section->reloc->data + vtop->c.i);
12051110 sym = external_global_sym(func, &func_old_type);
12061111 if (!sym->c)
12071112 put_extern_sym(sym, NULL, 0, 0);
1113+ /* patch relocation */
1114+ /* XXX: find a better solution ? */
1115+ rel = (Elf32_Rel *)(cur_text_section->reloc->data + vtop->c.i);
12081116 rel->r_info = ELF32_R_INFO(sym->c, ELF32_R_TYPE(rel->r_info));
12091117 }
12101118 #endif
i386-link.c+75−0
@@ -235,4 +235,79 @@ void relocate(TCCState *s1, ElfW_Rel *rel, int type, unsigned char *ptr, addr_t · 234 unmodified lines
235235 }
236236 }
237237
238+#ifdef CONFIG_TCC_BCHECK
239+ST_FUNC void tcc_add_bcheck(TCCState *s1)
240+{
241+ addr_t *ptr;
242+ int loc_glob;
243+ int sym_index;
244+ int bsym_index;
245+
246+ if (0 == s1->do_bounds_check)
247+ return;
248+ /* XXX: add an object file to do that */
249+ ptr = section_ptr_add(bounds_section, sizeof(*ptr));
250+ *ptr = 0;
251+ loc_glob = s1->output_type != TCC_OUTPUT_MEMORY ? STB_LOCAL : STB_GLOBAL;
252+ bsym_index = set_elf_sym(symtab_section, 0, 0,
253+ ELFW(ST_INFO)(loc_glob, STT_NOTYPE), 0,
254+ bounds_section->sh_num, "__bounds_start");
255+ /* pull bcheck.o from libtcc1.a */
256+ sym_index = set_elf_sym(symtab_section, 0, 0,
257+ ELFW(ST_INFO)(STB_GLOBAL, STT_NOTYPE), 0,
258+ SHN_UNDEF, "__bound_init");
259+ if (s1->output_type != TCC_OUTPUT_MEMORY) {
260+ /* add 'call __bound_init()' in .init section */
261+ Section *init_section = find_section(s1, ".init");
262+ unsigned char *pinit;
263+#ifdef TCC_TARGET_PE
264+ pinit = section_ptr_add(init_section, 3);
265+ pinit[0] = 0x55; /* push %rbp */
266+ pinit[1] = 0x89; /* mov %esp,%ebp */
267+ pinit[2] = 0xe5;
268+#endif
269+ pinit = section_ptr_add(init_section, 5);
270+ pinit[0] = 0xe8;
271+ write32le(pinit + 1, -4);
272+ put_elf_reloc(symtab_section, init_section,
273+ init_section->data_offset - 4, R_386_PC32, sym_index);
274+ /* R_386_PC32 = R_X86_64_PC32 = 2 */
275+ pinit = section_ptr_add(init_section, 6);
276+ pinit[0] = 0xb8; /* mov xx,%eax */
277+ write32le(pinit + 1, 0);
278+ pinit[5] = 0x50; /* push %eax */
279+ put_elf_reloc(symtab_section, init_section,
280+ init_section->data_offset - 5, R_386_32, bsym_index);
281+ sym_index = set_elf_sym(symtab_section, 0, 0,
282+ ELFW(ST_INFO)(STB_GLOBAL, STT_NOTYPE), 0,
283+ SHN_UNDEF, "__bounds_add_static_var");
284+ pinit = section_ptr_add(init_section, 5);
285+ pinit[0] = 0xe8;
286+ write32le(pinit + 1, -4);
287+ put_elf_reloc(symtab_section, init_section,
288+ init_section->data_offset - 4, R_386_PC32, sym_index);
289+ /* R_386_PC32 = R_X86_64_PC32 = 2 */
290+ pinit = section_ptr_add(init_section, 3);
291+ pinit[0] = 0x83; /* add $0x4,%esp */
292+ pinit[1] = 0xc4;
293+ pinit[2] = 0x04;
294+#ifdef TCC_TARGET_PE
295+ {
296+ int init_index = set_elf_sym(symtab_section,
297+ 0, 0,
298+ ELFW(ST_INFO)(STB_GLOBAL, STT_NOTYPE), 0,
299+ init_section->sh_num, "__init_start");
300+ Sym sym;
301+ init_section->sh_flags |= SHF_EXECINSTR;
302+ pinit = section_ptr_add(init_section, 2);
303+ pinit[0] = 0xc9; /* leave */
304+ pinit[1] = 0xc3; /* ret */
305+ sym.c = init_index;
306+ add_init_array (s1, &sym);
307+ }
308+#endif
309+ }
310+}
311+#endif
312+
238313 #endif /* !TARGET_DEFS_ONLY */
lib/Makefile+17−32
@@ -7,8 +7,6 @@ include $(TOP)/Makefile · 6 unmodified lines
77 VPATH = $(TOPSRC)/lib $(TOPSRC)/win32/lib
88 T = $(or $(CROSS_TARGET),$(NATIVE_TARGET),unknown)
99 X = $(if $(CROSS_TARGET),$(CROSS_TARGET)-)
10−BIN = $(TOP)/$(X)libtcc1.a
11−BINB = $(TOP)/$(X)libtccb1.a
1210
1311 XTCC ?= $(TOP)/$(X)tcc$(EXESUF)
1412 XCC = $(XTCC)
@@ -20,8 +18,6 @@ XCFG = $(or $(findstring -win,$T),-unx) · 5 unmodified lines
2018
2119 # in order to use gcc, tyoe: make <target>-libtcc1-usegcc=yes
2220 arm-libtcc1-usegcc ?= no
23−x86_64-libtcc1-usegcc ?= no
24−i386-libtcc1-usegcc ?= no
2521
2622 ifeq "$($(T)-libtcc1-usegcc)" "yes"
2723 XCC = $(CC)
@@ -42,8 +38,6 @@ ifdef CONFIG_OSX · 14 unmodified lines
4238 XFLAGS += -D_ANSI_SOURCE
4339 endif
4440
45−XFLAGS += -g
46−
4741 I386_O = libtcc1.o alloca86.o alloca86-bt.o
4842 X86_64_O = libtcc1.o alloca86_64.o alloca86_64-bt.o
4943 ARM_O = libtcc1.o armeabi.o alloca-arm.o armflush.o
@@ -51,11 +45,11 @@ ARM64_O = lib-arm64.o · 1 unmodified line
5145 RISCV64_O = lib-arm64.o
5246 WIN_O = crt1.o crt1w.o wincrt1.o wincrt1w.o dllcrt1.o dllmain.o
5347
54−OBJ-i386 = $(I386_O) $(DSO_O)
55−OBJ-x86_64 = $(X86_64_O) va_list.o $(DSO_O)
48+OBJ-i386 = $(I386_O) $(BCHECK_O) $(DSO_O)
49+OBJ-x86_64 = $(X86_64_O) va_list.o $(BCHECK_O) $(DSO_O)
5650 OBJ-x86_64-osx = $(X86_64_O) va_list.o
57−OBJ-i386-win32 = $(I386_O) chkstk.o $(WIN_O)
58−OBJ-x86_64-win32 = $(X86_64_O) chkstk.o (WIN_O)
51+OBJ-i386-win32 = $(I386_O) chkstk.o bcheck.o $(WIN_O)
52+OBJ-x86_64-win32 = $(X86_64_O) chkstk.o bcheck.o $(WIN_O)
5953 OBJ-arm64 = $(ARM64_O) $(DSO_O)
6054 OBJ-arm = $(ARM_O) $(DSO_O)
6155 OBJ-arm-fpa = $(ARM_O) $(DSO_O)
@@ -66,27 +60,14 @@ OBJ-arm-eabihf = $(ARM_O) $(DSO_O) · 4 unmodified lines
6660 OBJ-arm-wince = $(ARM_O) $(WIN_O)
6761 OBJ-riscv64 = $(RISCV64_O) $(DSO_O)
6862
69−OBJB-i386 = $(BCHECK_O)
70−OBJB-x86_64 = $(BCHECK_O)
71−OBJB-x86_64-osx = dummy.o
72−OBJB-i386-win32 = bcheck.o
73−OBJB-x86_64-win32 = bcheck.o
74−OBJB-arm64 = dummy.o
75−OBJB-arm = dummy.o
76−OBJB-arm-fpa = dummy.o
77−OBJB-arm-fpa-ld = dummy.o
78−OBJB-arm-vfp = dummy.o
79−OBJB-arm-eabi = dummy.o
80−OBJB-arm-eabihf = dummy.o
81−OBJB-arm-wince = dummy.o
82−OBJB-riscv64 = dummy.o
83−
84−all: $(BIN) $(BINB)
85−
86−$(BIN) : $(patsubst %.o,$(X)%.o,$(OBJ-$T))
87− $(XAR) rcs $@ $^
63+OBJ-extra = $(filter bcheck.o,$(OBJ-$T))
64+OBJ-libtcc1 = $(addprefix $(X),$(filter-out $(OBJ-extra),$(OBJ-$T)))
65+
66+ALL = $(addprefix $(TOP)/,$(X)libtcc1.a $(OBJ-extra))
67+
68+all: $(ALL)
8869
89−$(BINB) : $(patsubst %.o,$(X)%.o,$(OBJB-$T))
70+$(TOP)/$(X)libtcc1.a : $(OBJ-libtcc1)
9071 $(XAR) rcs $@ $^
9172
9273 $(X)%.o : %.c
@@ -95,8 +76,12 @@ $(X)%.o : %.c · 2 unmodified lines
9576 $(X)%.o : %.S
9677 $(XCC) -c $< -o $@ $(XFLAGS)
9778
79+$(TOP)/%.o : %.c
80+ $(XCC) -c $< -o $@ $(XFLAGS)
81+
82+$(TOP)/bcheck.o : XFLAGS += -g
83+
9884 $(X)crt1w.o : crt1.c
9985 $(X)wincrt1w.o : wincrt1.c
100−
10186 clean :
102− rm -f *.a *.o $(BIN) $(BINB)
87+ rm -f *.a *.o $(ALL)
lib/alloca86_64-bt.S+9−28
@@ -5,44 +5,25 @@ · 4 unmodified lines
55 __bound_alloca:
66
77 #ifdef _WIN32
8− pop %rdx
9− mov %rcx,%rax
10− add $15,%rax
11− and $-16,%rax
12− jz p3
13−
14−p1:
15− cmp $4096,%rax
16− jbe p2
17− test %rax,-4096(%rsp)
18− sub $4096,%rsp
19− sub $4096,%rax
20− jmp p1
21−p2:
22−
23− sub %rax,%rsp
24− mov %rsp,%rax
25−
26− push %rdx
8+ inc %rcx # add one extra to separate regions
9+ jmp alloca
10+.globl __bound_alloca_nr
11+__bound_alloca_nr:
12+ dec %rcx
2713 push %rax
2814 mov %rcx,%rdx
2915 mov %rax,%rcx
30− sub $20,%rsp
31− call __bound_new_region
32− add $20,%rsp
16+ sub $32,%rsp
17+ call __bound_new_region
18+ add $32,%rsp
3319 pop %rax
34− pop %rdx
35−
36− add $32,%rax
37−p3:
38− push %rdx
3920 ret
4021 #else
4122 pop %rdx
4223 mov %rdi,%rax
4324 mov %rax,%rsi # size, a second parm to the __bound_new_region
4425
45− add $15,%rax
26+ add $15 + 1,%rax # add one extra to separate regions
4627 and $-16,%rax
4728 jz p3
4829
lib/alloca86_64.S+0−4
@@ -24,12 +24,8 @@ p1: · 23 unmodified lines
2424 jmp p1
2525 p2:
2626 #endif
27−
2827 sub %rax,%rsp
2928 mov %rsp,%rax
30−#ifdef _WIN32
31− add $32,%rax
32−#endif
3329 p3:
3430 push %rdx
3531 ret
lib/bcheck.c+17−14
@@ -205,6 +205,9 @@ void __bound_checking (int no_check) · 204 unmodified lines
205205 no_checking = no_check;
206206 }
207207
208+#define no_FASTCALL
209+//#define no_checking 1
210+
208211 /* print a bound error message */
209212 static void bound_error(const char *fmt, ...)
210213 {
@@ -221,8 +224,7 @@ static void bound_alloc_error(void) · 10 unmodified lines
221224
222225 /* return '(p + offset)' for pointer arithmetic (a pointer can reach
223226 the end of a region in this case */
224−void * FASTCALL __bound_ptr_add(void *p, size_t offset,
225− size_t line, const char *filename)
227+void * no_FASTCALL __bound_ptr_add(void *p, size_t offset)
226228 {
227229 size_t addr = (size_t)p;
228230
@@ -230,8 +232,8 @@ void * FASTCALL __bound_ptr_add(void *p, size_t offset, · 1 unmodified line
230232 return p + offset;
231233 }
232234
233− dprintf(stderr, "%s %s (%s:%u): %p 0x%x\n",
234− __FILE__, __FUNCTION__, filename, line, p, (unsigned)offset);
235+ dprintf(stderr, "%s %s : %p 0x%x\n",
236+ __FILE__, __FUNCTION__, p, (unsigned)offset);
235237
236238 WAIT_SEM ();
237239 INCR_COUNT(bound_ptr_add_count);
@@ -250,8 +252,10 @@ void * FASTCALL __bound_ptr_add(void *p, size_t offset, · 12 unmodified lines
250252 if (addr <= tree->size) {
251253 addr += offset;
252254 if (tree->is_invalid || addr > tree->size) {
253− fprintf(stderr,"%s %s (%s:%u): %p is outside of the region\n",
254− __FILE__, __FUNCTION__, filename, line, p + offset);
255+ #if 0
256+ fprintf(stderr,"%s %s : %p is outside of the region\n",
257+ __FILE__, __FUNCTION__, p + offset);
258+ #endif
255259 if (never_fatal == 0) {
256260 POST_SEM ();
257261 return INVALID_POINTER; /* return an invalid pointer */
@@ -266,16 +270,15 @@ void * FASTCALL __bound_ptr_add(void *p, size_t offset, · 8 unmodified lines
266270 /* return '(p + offset)' for pointer indirection (the resulting must
267271 be strictly inside the region */
268272 #define BOUND_PTR_INDIR(dsize) \
269−void * FASTCALL __bound_ptr_indir ## dsize (void *p, size_t offset, \
270− size_t line, const char *filename) \
273+void * no_FASTCALL __bound_ptr_indir ## dsize (void *p, size_t offset) \
271274 { \
272275 size_t addr = (size_t)p; \
273276 \
274277 if (no_checking) { \
275278 return p + offset; \
276279 } \
277− dprintf(stderr, "%s %s (%s:%u): %p 0x%x start\n", \
278− __FILE__, __FUNCTION__, filename, line, p, (unsigned)offset); \
280+ dprintf(stderr, "%s %s : %p 0x%x start\n", \
281+ __FILE__, __FUNCTION__, p, (unsigned)offset); \
279282 WAIT_SEM (); \
280283 INCR_COUNT(bound_ptr_indir ## dsize ## _count); \
281284 if (tree) { \
@@ -293,8 +296,8 @@ void * FASTCALL __bound_ptr_indir ## dsize (void *p, size_t offset, \ · 11 unmodified lines
293296 if (addr <= tree->size) { \
294297 addr += offset + dsize; \
295298 if (tree->is_invalid || addr > tree->size) { \
296− fprintf(stderr,"%s %s (%s:%u): %p is outside of the region\n", \
297− __FILE__, __FUNCTION__, filename, line, p + offset); \
299+ fprintf(stderr,"%s %s : %p is outside of the region\n", \
300+ __FILE__, __FUNCTION__, p + offset); \
298301 if (never_fatal == 0) { \
299302 POST_SEM (); \
300303 return INVALID_POINTER; /* return an invalid pointer */ \
@@ -907,7 +910,7 @@ static void __bound_check(const void *p, size_t size, const char *function) · 606 unmodified lines
907910 return;
908911 if (size == 0)
909912 return;
910− p = __bound_ptr_add((void *)p, size, 0, function);
913+ p = __bound_ptr_add((void *)p, size);
911914 if (p == INVALID_POINTER)
912915 bound_error("invalid pointer");
913916 }
@@ -959,7 +962,7 @@ int __bound_strlen(const char *s) · 45 unmodified lines
959962 INCR_COUNT(bound_strlen_count);
960963 while (*p++);
961964 len = (p - s) - 1;
962− p = __bound_ptr_indir1((char *)s, len, 0, "strlen");
965+ p = __bound_ptr_indir1((char *)s, len);
963966 if (p == INVALID_POINTER)
964967 bound_error("bad pointer in strlen()");
965968 return len;
lib/dummy.c+0−1
@@ -1 +0,0 @@
1−static char dummy;
libtcc.c+0−4
@@ -1545,7 +1545,6 @@ static const TCCOption tcc_options[] = { · 1544 unmodified lines
15451545 #endif
15461546 #ifdef CONFIG_TCC_BCHECK
15471547 { "b", TCC_OPTION_b, 0 },
1548− { "ba", TCC_OPTION_ba, 0 },
15491548 #endif
15501549 { "g", TCC_OPTION_g, TCC_OPTION_HAS_ARG | TCC_OPTION_NOSEP },
15511550 { "c", TCC_OPTION_c, 0 },
@@ -1802,9 +1801,6 @@ reparse: · 250 unmodified lines
18021801 s->do_bounds_check = 1;
18031802 s->do_debug = 1;
18041803 break;
1805− case TCC_OPTION_ba:
1806− s->do_bounds_check_address = 1;
1807− break;
18081804 #endif
18091805 case TCC_OPTION_g:
18101806 s->do_debug = 1;
tcc.c+0−1
@@ -59,7 +59,6 @@ static const char help[] = · 58 unmodified lines
5959 " -g generate runtime debug info\n"
6060 #ifdef CONFIG_TCC_BCHECK
6161 " -b compile with built-in memory and bounds checker (implies -g)\n"
62− " -ba Enable better address checking with bounds checker\n"
6362 #endif
6463 #ifdef CONFIG_TCC_BACKTRACE
6564 " -bt N show N callers in stack traces\n"
tcc.h+4−5
@@ -292,9 +292,6 @@ extern long double strtold (const char *__nptr, char **__endptr); · 291 unmodified lines
292292 #ifndef TCC_LIBTCC1
293293 # define TCC_LIBTCC1 "libtcc1.a"
294294 #endif
295−#ifndef TCC_LIBTCCB1
296−# define TCC_LIBTCCB1 "libtccb1.a"
297−#endif
298295
299296 /* library to use with CONFIG_USE_LIBGCC instead of libtcc1.a */
300297 #if defined CONFIG_USE_LIBGCC && !defined TCC_LIBGCC
@@ -720,7 +717,6 @@ struct TCCState { · 419 unmodified lines
720717 #ifdef CONFIG_TCC_BCHECK
721718 /* compile with built-in memory and bounds checker */
722719 unsigned char do_bounds_check;
723− unsigned char do_bounds_check_address;
724720 #endif
725721 #ifdef TCC_TARGET_ARM
726722 enum float_abi float_abi; /* float ABI of the generated code*/
@@ -1250,7 +1246,7 @@ ST_FUNC int tcc_add_crt(TCCState *s, const char *filename); · 523 unmodified lines
12501246 #endif
12511247 ST_FUNC int tcc_add_dll(TCCState *s, const char *filename, int flags);
12521248 #ifdef CONFIG_TCC_BCHECK
1253−ST_FUNC void tcc_add_bcheck(TCCState *s1, Section *bound_sec, Section *sym_sec);
1249+ST_FUNC void tcc_add_bcheck(TCCState *s1);
12541250 #endif
12551251 ST_FUNC void tcc_add_pragma_libs(TCCState *s1);
12561252 PUB_FUNC int tcc_add_library_err(TCCState *s, const char *f);
@@ -1437,6 +1433,9 @@ ST_FUNC Sym *get_sym_ref(CType *type, Section *sec, unsigned long offset, unsign · 180 unmodified lines
14371433 #if defined TCC_TARGET_X86_64 && !defined TCC_TARGET_PE
14381434 ST_FUNC int classify_x86_64_va_arg(CType *ty);
14391435 #endif
1436+#ifdef CONFIG_TCC_BCHECK
1437+ST_FUNC void gbound_args(int nb_args);
1438+#endif
14401439
14411440 /* ------------ tccelf.c ------------ */
14421441
tccelf.c+2−2
@@ -1321,7 +1321,7 @@ ST_FUNC void tcc_add_runtime(TCCState *s1) · 1320 unmodified lines
13211321 {
13221322 s1->filetype = 0;
13231323 #ifdef CONFIG_TCC_BCHECK
1324− tcc_add_bcheck(s1, bounds_section, symtab_section);
1324+ tcc_add_bcheck(s1);
13251325 #endif
13261326 tcc_add_pragma_libs(s1);
13271327 #ifndef TCC_TARGET_PE
@@ -1340,7 +1340,7 @@ ST_FUNC void tcc_add_runtime(TCCState *s1) · 12 unmodified lines
13401340 if (s1->do_bounds_check && s1->output_type != TCC_OUTPUT_DLL) {
13411341 tcc_add_library_err(s1, "pthread");
13421342 tcc_add_library_err(s1, "dl");
1343− tcc_add_support(s1, TCC_LIBTCCB1);
1343+ tcc_add_support(s1, "bcheck.o");
13441344 }
13451345 #endif
13461346 tcc_add_support(s1, TCC_LIBTCC1);
tccgen.c+21−20
@@ -1230,6 +1230,11 @@ ST_FUNC void save_reg_upstack(int r, int n) · 1229 unmodified lines
12301230 type = &int_type;
12311231 #endif
12321232 size = type_size(type, &align);
1233+#ifdef CONFIG_TCC_BCHECK
1234+ if (tcc_state->do_bounds_check)
1235+ l = loc = (loc - size) & -align;
1236+ else
1237+#endif
12331238 l=get_temp_local_var(size,align);
12341239 sv.type.t = type->t;
12351240 sv.r = VT_LOCAL | VT_LVAL;
@@ -1417,7 +1422,7 @@ static void gbound(void) · 181 unmodified lines
14171422
14181423 vtop->r &= ~VT_MUSTBOUND;
14191424 /* if lvalue, then use checking code before dereferencing */
1420− if ((vtop->r & VT_LVAL) && !nocode_wanted) {
1425+ if (vtop->r & VT_LVAL) {
14211426 /* if not VT_BOUNDED value, then make one */
14221427 if (!(vtop->r & VT_BOUNDED)) {
14231428 lval_type = vtop->r & (VT_LVAL_TYPE | VT_LVAL);
@@ -1434,6 +1439,19 @@ static void gbound(void) · 10 unmodified lines
14341439 gen_bounded_ptr_deref();
14351440 }
14361441 }
1442+
1443+/* we need to call __bound_ptr_add before we start to load function
1444+ args into registers */
1445+ST_FUNC void gbound_args(int nb_args)
1446+{
1447+ int i;
1448+ for (i = 1; i <= nb_args; ++i)
1449+ if (vtop[1 - i].r & VT_MUSTBOUND) {
1450+ vrotb(i);
1451+ gbound();
1452+ vrott(i);
1453+ }
1454+}
14371455 #endif
14381456
14391457 static void incr_bf_adr(int o)
@@ -2499,25 +2517,7 @@ redo: · 1059 unmodified lines
24992517 }
25002518 gen_op('*');
25012519 #ifdef CONFIG_TCC_BCHECK
2502− /* The main reason to removing this code:
2503− #include <stdio.h>
2504− int main ()
2505− {
2506− int v[10];
2507− int i = 10;
2508− int j = 9;
2509− fprintf(stderr, "v+i-j = %p\n", v+i-j);
2510− fprintf(stderr, "v+(i-j) = %p\n", v+(i-j));
2511− }
2512− When this code is on. then the output looks like
2513− v+i-j = 0xfffffffe
2514− v+(i-j) = 0xbff84000
2515− This should now work in updated bcheck.c version.
2516− */
2517− /* if evaluating constant expression, no code should be
2518− generated, so no bound check */
2519− if (tcc_state->do_bounds_check && tcc_state->do_bounds_check_address
2520− && !const_wanted && !nocode_wanted) {
2520+ if (tcc_state->do_bounds_check && !const_wanted) {
25212521 /* if bounded pointers, we generate a special code to
25222522 test bounds */
25232523 if (op == '-') {
@@ -2525,6 +2525,7 @@ redo: · 1 unmodified line
25252525 vswap();
25262526 gen_op('-');
25272527 }
2528+ vtop[-1].r &= ~VT_MUSTBOUND;
25282529 gen_bounded_ptr_add();
25292530 } else
25302531 #endif
tccpe.c+14−22
@@ -1836,6 +1836,12 @@ ST_FUNC void pe_add_unwind_data(unsigned start, unsigned end, unsigned stack) · 1835 unmodified lines
18361836 #define PE_STDSYM(n,s) "_" n s
18371837 #endif
18381838
1839+static void tcc_add_support(TCCState *s1, const char *filename)
1840+{
1841+ if (tcc_add_dll(s1, filename, 0) < 0)
1842+ tcc_error_noabort("%s not found", filename);
1843+}
1844+
18391845 static void pe_add_runtime(TCCState *s1, struct pe_info *pe)
18401846 {
18411847 const char *start_symbol;
@@ -1884,35 +1890,21 @@ static void pe_add_runtime(TCCState *s1, struct pe_info *pe) · 42 unmodified lines
18841890
18851891 if (0 == s1->nostdlib) {
18861892 static const char *libs[] = {
1887− TCC_LIBTCC1,
1888−#ifdef CONFIG_TCC_BCHECK
1889− TCC_LIBTCCB1,
1890−#endif
18911893 "msvcrt", "kernel32", "", "user32", "gdi32", NULL
18921894 };
18931895 const char **pp, *p;
1894− for (pp = libs; 0 != (p = *pp); ++pp) {
1895−#ifdef CONFIG_TCC_BCHECK
1896− if (pp == libs + 1 &&
1897− (s1->do_bounds_check == 0 || s1->output_type == TCC_OUTPUT_DLL)) {
1898− continue;
1899− }
1900−#endif
1901− if (0 == *p) {
1902− if (PE_DLL != pe_type && PE_GUI != pe_type)
1903− break;
1904− } else if (pp == libs && tcc_add_dll(s1, p, 0) >= 0) {
1905− continue;
1906−#ifdef CONFIG_TCC_BCHECK
1907− } else if (pp == libs + 1 && tcc_add_dll(s1, p, 0) >= 0) {
1908− continue;
1896+#ifdef TCC_IS_NATIVE
1897+ if (s1->do_bounds_check)
1898+ tcc_add_support(s1, "bcheck.o");
19091899 #endif
1910− } else {
1900+ tcc_add_support(s1, TCC_LIBTCC1);
1901+ for (pp = libs; 0 != (p = *pp); ++pp) {
1902+ if (*p)
19111903 tcc_add_library_err(s1, p);
1912− }
1904+ else if (PE_DLL != pe_type && PE_GUI != pe_type)
1905+ break;
19131906 }
19141907 }
1915−
19161908 if (TCC_OUTPUT_MEMORY == s1->output_type)
19171909 pe_type = PE_RUN;
19181910 pe->type = pe_type;
tccpp.c+3−4
@@ -392,16 +392,15 @@ ST_FUNC void cstr_reset(CString *cstr) · 391 unmodified lines
392392 ST_FUNC int cstr_printf(CString *cstr, const char *fmt, ...)
393393 {
394394 va_list v;
395− va_list vc;
396395 int len, size;
397396
398397 va_start(v, fmt);
399− va_copy (vc, v);
400− len = vsnprintf(NULL, 0, fmt, vc);
401− va_end(vc);
398+ len = vsnprintf(NULL, 0, fmt, v);
399+ va_end(v);
402400 size = cstr->size + len + 1;
403401 if (size > cstr->size_allocated)
404402 cstr_realloc(cstr, size);
403+ va_start(v, fmt);
405404 vsnprintf((char*)cstr->data + cstr->size, size, fmt, v);
406405 va_end(v);
407406 cstr->size += len;
tcctok.h+3−0
@@ -306,6 +306,9 @@ · 305 unmodified lines
306306 DEF(TOK___bound_local_new, "__bound_local_new")
307307 DEF(TOK___bound_local_delete, "__bound_local_delete")
308308 # ifdef TCC_TARGET_PE
309+# ifdef TCC_TARGET_X86_64
310+ DEF(TOK___bound_alloca_nr, "__bound_alloca_nr")
311+# endif
309312 DEF(TOK_malloc, "malloc")
310313 DEF(TOK_free, "free")
311314 DEF(TOK_realloc, "realloc")
tests/Makefile+7−8
@@ -23,7 +23,7 @@ TESTS = \ · 22 unmodified lines
2323 tests2-dir \
2424 pp-dir
2525
26−BTESTS = test1b test3b btest test4
26+BTESTS = btest test2b
2727
2828 # test4_static -- Not all relocation types are implemented yet.
2929 # asmtest / asmtest2 -- minor differences with gcc
@@ -115,7 +115,7 @@ test3 test3b: tcctest.c test.ref · 85 unmodified lines
115115 $(TCC) $(RUN_TCC) $(RUN_TCC) $(RUN_TCC) -run $< > test.out3
116116 @diff -u test.ref test.out3 && echo "Auto Test3 OK"
117117
118−test%b : TCCFLAGS += -b -ba
118+test%b : TCCFLAGS += -b
119119
120120 # binary output test
121121 test4: tcctest.c test.ref
@@ -130,7 +130,7 @@ test4: tcctest.c test.ref · 8 unmodified lines
130130 ./tcctest1 > test1.out
131131 @if diff -u test.ref test1.out ; then echo "Dynamic Auto Test OK"; fi
132132 # dynamic output + bound check
133− $(TCC) -b -ba -o tcctest4 $<
133+ $(TCC) -b -o tcctest4 $<
134134 ./tcctest4 > test4.out
135135 @if diff -u test.ref test4.out ; then echo "BCheck Auto Test OK"; fi
136136
@@ -163,15 +163,14 @@ memtest: · 26 unmodified lines
163163
164164
165165 # memory and bound check auto test
166−BOUNDS_OK = 1 3 4 8 10 14 16
166+BOUNDS_OK = 1 4 8 10 14 16
167167 BOUNDS_FAIL= 2 5 6 7 9 11 12 13 15 17
168168
169169 btest: boundtest.c
170170 @echo ------------ $@ ------------
171− @ulimit -c 0; \
172− for i in $(BOUNDS_OK); do \
171+ @for i in $(BOUNDS_OK); do \
173172 echo ; echo --- boundtest $$i ---; \
174− if $(TCC) -b -ba -run $< $$i ; then \
173+ if $(TCC) -b -run $< $$i ; then \
175174 echo succeeded as expected; \
176175 else\
177176 echo Failed positive test $$i ; exit 1 ; \
@@ -179,7 +178,7 @@ btest: boundtest.c · 1 unmodified line
179178 done ;\
180179 for i in $(BOUNDS_FAIL); do \
181180 echo ; echo --- boundtest $$i ---; \
182− if $(TCC) -b -ba -run $< $$i ; then \
181+ if $(TCC) -b -run $< $$i ; then \
183182 echo Failed negative test $$i ; exit 1 ;\
184183 else\
185184 echo failed as expected; \
x86_64-gen.c+37−230
@@ -142,9 +142,6 @@ ST_DATA const int reg_classes[NB_REGS] = { · 141 unmodified lines
142142
143143 static unsigned long func_sub_sp_offset;
144144 static int func_ret_sub;
145−static int nested_call;
146−static int call_used_nr_reg;
147−static int call_used_regs[20];
148145
149146 /* XXX: make it faster ? */
150147 ST_FUNC void g(int c)
@@ -654,218 +651,19 @@ static void gen_bounds_call(int v) · 503 unmodified lines
654651 #endif
655652 }
656653
657−ST_FUNC void tcc_add_bcheck(TCCState *s1, Section *bound_sec, Section *sym_sec)
658−{
659− addr_t *ptr;
660− int loc_glob;
661− int sym_index;
662− int bsym_index;
663−
664− if (0 == s1->do_bounds_check)
665− return;
666− /* XXX: add an object file to do that */
667− ptr = section_ptr_add(bound_sec, sizeof(*ptr));
668− *ptr = 0;
669− loc_glob = s1->output_type != TCC_OUTPUT_MEMORY ? STB_LOCAL : STB_GLOBAL;
670− bsym_index = set_elf_sym(sym_sec, 0, 0,
671− ELFW(ST_INFO)(loc_glob, STT_NOTYPE), 0,
672− bound_sec->sh_num, "__bounds_start");
673− /* pull bcheck.o from libtcc1.a */
674− sym_index = set_elf_sym(sym_sec, 0, 0,
675− ELFW(ST_INFO)(STB_GLOBAL, STT_NOTYPE), 0,
676− SHN_UNDEF, "__bound_init");
677− if (s1->output_type != TCC_OUTPUT_MEMORY) {
678− /* add 'call __bound_init()' in .init section */
679− Section *init_section = find_section(s1, ".init");
680− unsigned char *pinit;
681−#ifdef TCC_TARGET_PE
682− pinit = section_ptr_add(init_section, 8);
683− pinit[0] = 0x55; /* push %rbp */
684− pinit[1] = 0x48; /* mov %rsp,%rpb */
685− pinit[2] = 0x89;
686− pinit[3] = 0xe5;
687− pinit[4] = 0x48; /* sub $0x10,%rsp */
688− pinit[5] = 0x83;
689− pinit[6] = 0xec;
690− pinit[7] = 0x10;
691−#endif
692− pinit = section_ptr_add(init_section, 5);
693− pinit[0] = 0xe8;
694− write32le(pinit + 1, -4);
695− put_elf_reloc(sym_sec, init_section,
696− init_section->data_offset - 4, R_386_PC32, sym_index);
697− /* R_386_PC32 = R_X86_64_PC32 = 2 */
698− pinit = section_ptr_add(init_section, 13);
699− pinit[0] = 0x48; /* mov xx,%rax */
700− pinit[1] = 0xb8;
701− write64le(pinit + 2, 0);
702−#ifdef TCC_TARGET_PE
703− pinit[10] = 0x48; /* mov %rax,%rcx */
704− pinit[11] = 0x89;
705− pinit[12] = 0xc1;
706−#else
707− pinit[10] = 0x48; /* mov %rax,%rdi */
708− pinit[11] = 0x89;
709− pinit[12] = 0xc7;
710−#endif
711− put_elf_reloc(sym_sec, init_section,
712− init_section->data_offset - 11, R_X86_64_64, bsym_index);
713− sym_index = set_elf_sym(sym_sec, 0, 0,
714− ELFW(ST_INFO)(STB_GLOBAL, STT_NOTYPE), 0,
715− SHN_UNDEF, "__bounds_add_static_var");
716− pinit = section_ptr_add(init_section, 5);
717− pinit[0] = 0xe8;
718− write32le(pinit + 1, -4);
719− put_elf_reloc(sym_sec, init_section,
720− init_section->data_offset - 4, R_386_PC32, sym_index);
721− /* R_386_PC32 = R_X86_64_PC32 = 2 */
722−#ifdef TCC_TARGET_PE
723− {
724− int init_index = set_elf_sym(sym_sec,
725− 0, 0,
726− ELFW(ST_INFO)(STB_GLOBAL, STT_NOTYPE), 0,
727− init_section->sh_num, "__init_start");
728− Sym sym;
729− init_section->sh_flags |= SHF_EXECINSTR;
730− pinit = section_ptr_add(init_section, 2);
731− pinit[0] = 0xc9; /* leave */
732− pinit[1] = 0xc3; /* ret */
733− sym.c = init_index;
734− add_init_array (s1, &sym);
735− }
736−#endif
737− }
738−}
739−
740654 /* generate a bounded pointer addition */
741655 ST_FUNC void gen_bounded_ptr_add(void)
742656 {
743− int i;
744−
745− nested_call++;
746−
747− /* save all temporary registers */
748− save_regs(0);
749−
750− for (i = 0; i < call_used_nr_reg; i++) {
751− switch (call_used_regs[i]) {
752− case TREG_RAX: case TREG_RCX: case TREG_RDX: case TREG_RSP:
753− case TREG_RSI: case TREG_RDI:
754− o(0x50 + call_used_regs[i]); /* push reg */
755− break;
756− case TREG_R8: case TREG_R9: case TREG_R10: case TREG_R11:
757− o(0x5041 + (call_used_regs[i] - TREG_R8) * 0x100); /* push reg */
758− break;
759− case TREG_XMM0: case TREG_XMM1: case TREG_XMM2: case TREG_XMM3:
760− case TREG_XMM4: case TREG_XMM5: case TREG_XMM6: case TREG_XMM7:
761− o(0x10ec8348); /* sub $10,%rsp */
762− /* vmovdqu %xmmx,(%rsp) */
763− o(0x047ffac5 + (call_used_regs[i] - TREG_XMM0) * 0x8000000); o(0x24);
764− break;
765− }
766− }
767−
768− if (nested_call > 1) {
769−#ifdef TCC_TARGET_PE
770− o(0x5152); /* push %rdx/%rcx */
771− o(0x51415041); /* push %r8/%r9 */
772−#else
773− o(0x51525657); /* push %rdi/%rsi/%rdx/%rcx */
774−#endif
775− }
776− /* prepare fast x86_64 function call */
777− gv(RC_RAX);
778−#ifdef TCC_TARGET_PE
779− o(0xc28948); // mov %rax,%rdx ## second arg in %rdx, this must be size
780−#else
781− o(0xc68948); // mov %rax,%rsi ## second arg in %rsi, this must be size
782−#endif
783− vtop--;
784−
785− gv(RC_RAX);
786−#ifdef TCC_TARGET_PE
787− o(0xc18948); // mov %rax,%rcx ## first arg in %rcx, this must be ptr
788−#else
789− o(0xc78948); // mov %rax,%rdi ## first arg in %rdi, this must be ptr
790−#endif
791− vtop--;
792−
793− /* add line, filename */
794−#ifdef TCC_TARGET_PE
795− o(0xc0c749); /* mov $xx,%r8 */
796−#else
797− o(0xba); /* mov $xx,%edx */
798−#endif
799− gen_le32 (file->line_num);
800− {
801− static addr_t offset;
802− static char last_filename[1024];
803− Sym *sym_data;
804−
805− if (strcmp (last_filename, file->filename) != 0) {
806− void *ptr;
807− int len = strlen (file->filename) + 1;
808−
809− offset = data_section->data_offset;
810− ptr = section_ptr_add(data_section, len);
811− memcpy (ptr, file->filename, len);
812− memcpy (last_filename, file->filename, len);
813− }
814−#ifdef TCC_TARGET_PE
815− o(0xb949); /* mov $xx,%r9 */
816−#else
817− o(0xb948); /* mov $xx,%rcx */
818−#endif
819− gen_le64 (0);
820− sym_data = get_sym_ref(&char_pointer_type, data_section,
821− offset, data_section->data_offset);
822− greloca(cur_text_section, sym_data, ind - 8, R_X86_64_64, 0);
823− }
824−
825−#ifdef TCC_TARGET_PE
826− o(0x20ec8348); /* sub $20, %rsp */
827−#endif
828−
829− /* do a fast function call */
830− gen_bounds_call(TOK___bound_ptr_add);
831−
832−#ifdef TCC_TARGET_PE
833− o(0x20c48348); /* add $20, %rsp */
834−#endif
835−
836− if (nested_call > 1) {
837−#ifdef TCC_TARGET_PE
838− o(0x58415941); /* pop %r9/%r8 */
839− o(0x5a59); /* pop %rcx/%rdx */
840−#else
841− o(0x5f5e5a59); /* pop $rcx/%rdx/%rsi/%rdi */
842−#endif
843− }
657+ vpush_global_sym(&func_old_type, TOK___bound_ptr_add);
658+ vrott(3);
659+ gfunc_call(2);
660+ vpushi(0);
844661 /* returned pointer is in rax */
845− vtop++;
846662 vtop->r = TREG_RAX | VT_BOUNDED;
847−
848− for (i = call_used_nr_reg - 1; i >= 0; i--) {
849− switch (call_used_regs[i]) {
850− case TREG_RAX: case TREG_RCX: case TREG_RDX: case TREG_RSP:
851− case TREG_RSI: case TREG_RDI:
852− o(0x58 + call_used_regs[i]); /* pop reg */
853− break;
854− case TREG_R8: case TREG_R9: case TREG_R10: case TREG_R11:
855− o(0x5841 + (call_used_regs[i] - TREG_R8) * 0x100); /* pop reg */
856− break;
857− case TREG_XMM0: case TREG_XMM1: case TREG_XMM2: case TREG_XMM3:
858− case TREG_XMM4: case TREG_XMM5: case TREG_XMM6: case TREG_XMM7:
859− /* vmovdqu (%rsp),%xmmx */
860− o(0x046ffac5 + (call_used_regs[i] - TREG_XMM0) * 0x8000000); o(0x24);
861− o(0x10c48348); /* add $10,%rsp */
862− break;
863− }
864− }
865−
663+ if (nocode_wanted)
664+ return;
866665 /* relocation offset of the bounding function call point */
867666 vtop->c.i = (cur_text_section->reloc->data_offset - sizeof(ElfW(Rela)));
868− nested_call--;
869667 }
870668
871669 /* patch pointer addition in vtop so that pointer dereferencing is
@@ -877,6 +675,9 @@ ST_FUNC void gen_bounded_ptr_deref(void) · 5 unmodified lines
877675 ElfW(Rela) *rel;
878676 Sym *sym;
879677
678+ if (nocode_wanted)
679+ return;
680+
880681 size = 0;
881682 /* XXX: put that code in generic part of tcc */
882683 if (!is_float(vtop->type.t)) {
@@ -886,7 +687,7 @@ ST_FUNC void gen_bounded_ptr_deref(void) · 3 unmodified lines
886687 size = 2;
887688 }
888689 if (!size)
889− size = type_size(&vtop->type, &align);
690+ size = type_size(&vtop->type, &align);
890691 switch(size) {
891692 case 1: func = TOK___bound_ptr_indir1; break;
892693 case 2: func = TOK___bound_ptr_indir2; break;
@@ -895,18 +696,17 @@ ST_FUNC void gen_bounded_ptr_deref(void) · 2 unmodified lines
895696 case 12: func = TOK___bound_ptr_indir12; break;
896697 case 16: func = TOK___bound_ptr_indir16; break;
897698 default:
898− tcc_error("unhandled size when dereferencing bounded pointer");
899− func = 0;
900− break;
699+ /* may happen with struct member access */
700+ return;
701+ //tcc_error("unhandled size when dereferencing bounded pointer");
702+ //func = 0;
703+ //break;
901704 }
902−
903705 sym = external_global_sym(func, &func_old_type);
904706 if (!sym->c)
905707 put_extern_sym(sym, NULL, 0, 0);
906−
907708 /* patch relocation */
908709 /* XXX: find a better solution ? */
909−
910710 rel = (ElfW(Rela) *)(cur_text_section->reloc->data + vtop->c.i);
911711 rel->r_info = ELF64_R_INFO(sym->c, ELF64_R_TYPE(rel->r_info));
912712 }
@@ -992,6 +792,11 @@ void gfunc_call(int nb_args) · 79 unmodified lines
992792 int size, r, args_size, i, d, bt, struct_size;
993793 int arg;
994794
795+#ifdef CONFIG_TCC_BCHECK
796+ if (tcc_state->do_bounds_check)
797+ gbound_args(nb_args);
798+#endif
799+
995800 args_size = (nb_args < REGN ? REGN : nb_args) * PTR_SIZE;
996801 arg = nb_args;
997802
@@ -1051,7 +856,6 @@ void gfunc_call(int nb_args) · 53 unmodified lines
1051856 } else {
1052857 d = arg_prepare_reg(arg);
1053858 gen_offs_sp(0x8d, d, struct_size);
1054− call_used_regs[call_used_nr_reg++] = d;
1055859 }
1056860 struct_size += size;
1057861 } else {
@@ -1070,7 +874,6 @@ void gfunc_call(int nb_args) · 12 unmodified lines
1070874 o(0x66);
1071875 orex(1,d,0, 0x7e0f);
1072876 o(0xc0 + arg*8 + REG_VALUE(d));
1073− call_used_regs[call_used_nr_reg++] = d;
1074877 }
1075878 } else {
1076879 if (bt == VT_STRUCT) {
@@ -1086,7 +889,6 @@ void gfunc_call(int nb_args) · 9 unmodified lines
1086889 d = arg_prepare_reg(arg);
1087890 orex(1,d,r,0x89); /* mov */
1088891 o(0xc0 + REG_VALUE(r) * 8 + REG_VALUE(d));
1089− call_used_regs[call_used_nr_reg++] = d;
1090892 }
1091893 }
1092894 }
@@ -1105,7 +907,12 @@ void gfunc_call(int nb_args) · 12 unmodified lines
1105907
1106908 if ((vtop->r & VT_SYM) && vtop->sym->v == TOK_alloca) {
1107909 /* need to add the "func_scratch" area after alloca */
1108− o(0x48); func_alloca = oad(0x2d, func_alloca); /* sub $NN, %rax */
910+ o(0x48); func_alloca = oad(0x05, func_alloca); /* add $NN, %rax */
911+#ifdef CONFIG_TCC_BCHECK
912+ if (tcc_state->do_bounds_check)
913+ gen_bounds_call(TOK___bound_alloca_nr); /* new region */
914+#endif
915+
1109916 }
1110917
1111918 /* other compilers don't clear the upper bits when returning char/short */
@@ -1125,7 +932,6 @@ void gfunc_call(int nb_args) · 13 unmodified lines
1125932 o(0xc089); /* mov %eax,%eax */
1126933 #endif
1127934 vtop--;
1128− call_used_nr_reg = 0;
1129935 }
1130936
1131937
@@ -1141,7 +947,7 @@ void gfunc_prolog(Sym *func_sym) · 9 unmodified lines
1141947 int n_arg = 0;
1142948
1143949 func_ret_sub = 0;
1144− func_scratch = 0;
950+ func_scratch = 32;
1145951 func_alloca = 0;
1146952 loc = 0;
1147953
@@ -1228,6 +1034,10 @@ void gfunc_epilog(void) · 80 unmodified lines
12281034 {
12291035 int v, saved_ind;
12301036
1037+ /* align local size to word & save local variables */
1038+ func_scratch = (func_scratch + 15) & -16;
1039+ loc = (loc & -16) - func_scratch;
1040+
12311041 #ifdef CONFIG_TCC_BCHECK
12321042 if (tcc_state->do_bounds_check
12331043 && func_bound_offset != lbounds_section->data_offset)
@@ -1273,9 +1083,7 @@ void gfunc_epilog(void) · 39 unmodified lines
12731083
12741084 saved_ind = ind;
12751085 ind = func_sub_sp_offset - FUNC_PROLOG_SIZE;
1276− /* align local size to word & save local variables */
1277− func_scratch = (func_scratch + 15) & -16;
1278− v = (func_scratch + -loc + 15) & -16;
1086+ v = -loc;
12791087
12801088 if (v >= 4096) {
12811089 Sym *sym = external_global_sym(TOK___chkstk, &func_old_type);
@@ -1479,6 +1287,11 @@ void gfunc_call(int nb_args) · 197 unmodified lines
14791287 int sse_reg, gen_reg;
14801288 char _onstack[nb_args ? nb_args : 1], *onstack = _onstack;
14811289
1290+#ifdef CONFIG_TCC_BCHECK
1291+ if (tcc_state->do_bounds_check)
1292+ gbound_args(nb_args);
1293+#endif
1294+
14821295 /* calculate the number of integer/float register arguments, remember
14831296 arguments to be passed via stack (in onstack[]), and also remember
14841297 if we have to align the stack pointer to 16 (onstack[i] == 2). Needs
@@ -1611,14 +1424,11 @@ void gfunc_call(int nb_args) · 126 unmodified lines
16111424 o(0x280f);
16121425 o(0xc0 + (sse_reg << 3));
16131426 }
1614− call_used_regs[call_used_nr_reg++] = sse_reg + TREG_XMM0;
1615− call_used_regs[call_used_nr_reg++] = sse_reg + 1 + TREG_XMM0;
16161427 } else {
16171428 assert(reg_count == 1);
16181429 --sse_reg;
16191430 /* Load directly to register */
16201431 gv(RC_XMM0 << sse_reg);
1621− call_used_regs[call_used_nr_reg++] = sse_reg + TREG_XMM0;
16221432 }
16231433 } else if (mode == x86_64_mode_integer) {
16241434 /* simple type */
@@ -1629,12 +1439,10 @@ void gfunc_call(int nb_args) · 4 unmodified lines
16291439 d = arg_prepare_reg(gen_reg);
16301440 orex(1,d,r,0x89); /* mov */
16311441 o(0xc0 + REG_VALUE(r) * 8 + REG_VALUE(d));
1632− call_used_regs[call_used_nr_reg++] = d;
16331442 if (reg_count == 2) {
16341443 d = arg_prepare_reg(gen_reg+1);
16351444 orex(1,d,vtop->r2,0x89); /* mov */
16361445 o(0xc0 + REG_VALUE(vtop->r2) * 8 + REG_VALUE(d));
1637− call_used_regs[call_used_nr_reg++] = d;
16381446 }
16391447 }
16401448 vtop--;
@@ -1677,7 +1485,6 @@ void gfunc_call(int nb_args) · 36 unmodified lines
16771485 else if (bt == (VT_SHORT | VT_UNSIGNED))
16781486 o(0xc0b70f); /* movzwl %al, %eax */
16791487 vtop--;
1680− call_used_nr_reg = 0;
16811488 }
16821489
16831490
x86_64-link.c+85−0
@@ -287,4 +287,89 @@ void relocate(TCCState *s1, ElfW_Rel *rel, int type, unsigned char *ptr, addr_t · 286 unmodified lines
287287 }
288288 }
289289
290+#ifdef CONFIG_TCC_BCHECK
291+ST_FUNC void tcc_add_bcheck(TCCState *s1)
292+{
293+ addr_t *ptr;
294+ int loc_glob;
295+ int sym_index;
296+ int bsym_index;
297+
298+ if (0 == s1->do_bounds_check)
299+ return;
300+ /* XXX: add an object file to do that */
301+ ptr = section_ptr_add(bounds_section, sizeof(*ptr));
302+ *ptr = 0;
303+ loc_glob = s1->output_type != TCC_OUTPUT_MEMORY ? STB_LOCAL : STB_GLOBAL;
304+ bsym_index = set_elf_sym(symtab_section, 0, 0,
305+ ELFW(ST_INFO)(loc_glob, STT_NOTYPE), 0,
306+ bounds_section->sh_num, "__bounds_start");
307+ /* pull bcheck.o from libtcc1.a */
308+ sym_index = set_elf_sym(symtab_section, 0, 0,
309+ ELFW(ST_INFO)(STB_GLOBAL, STT_NOTYPE), 0,
310+ SHN_UNDEF, "__bound_init");
311+ if (s1->output_type != TCC_OUTPUT_MEMORY) {
312+ /* add 'call __bound_init()' in .init section */
313+ Section *init_section = find_section(s1, ".init");
314+ unsigned char *pinit;
315+#ifdef TCC_TARGET_PE
316+ pinit = section_ptr_add(init_section, 8);
317+ pinit[0] = 0x55; /* push %rbp */
318+ pinit[1] = 0x48; /* mov %rsp,%rpb */
319+ pinit[2] = 0x89;
320+ pinit[3] = 0xe5;
321+ pinit[4] = 0x48; /* sub $0x10,%rsp */
322+ pinit[5] = 0x83;
323+ pinit[6] = 0xec;
324+ pinit[7] = 0x10;
325+#endif
326+ pinit = section_ptr_add(init_section, 5);
327+ pinit[0] = 0xe8;
328+ write32le(pinit + 1, -4);
329+ put_elf_reloc(symtab_section, init_section,
330+ init_section->data_offset - 4, R_386_PC32, sym_index);
331+ /* R_386_PC32 = R_X86_64_PC32 = 2 */
332+ pinit = section_ptr_add(init_section, 13);
333+ pinit[0] = 0x48; /* mov xx,%rax */
334+ pinit[1] = 0xb8;
335+ write64le(pinit + 2, 0);
336+#ifdef TCC_TARGET_PE
337+ pinit[10] = 0x48; /* mov %rax,%rcx */
338+ pinit[11] = 0x89;
339+ pinit[12] = 0xc1;
340+#else
341+ pinit[10] = 0x48; /* mov %rax,%rdi */
342+ pinit[11] = 0x89;
343+ pinit[12] = 0xc7;
344+#endif
345+ put_elf_reloc(symtab_section, init_section,
346+ init_section->data_offset - 11, R_X86_64_64, bsym_index);
347+ sym_index = set_elf_sym(symtab_section, 0, 0,
348+ ELFW(ST_INFO)(STB_GLOBAL, STT_NOTYPE), 0,
349+ SHN_UNDEF, "__bounds_add_static_var");
350+ pinit = section_ptr_add(init_section, 5);
351+ pinit[0] = 0xe8;
352+ write32le(pinit + 1, -4);
353+ put_elf_reloc(symtab_section, init_section,
354+ init_section->data_offset - 4, R_386_PC32, sym_index);
355+ /* R_386_PC32 = R_X86_64_PC32 = 2 */
356+#ifdef TCC_TARGET_PE
357+ {
358+ int init_index = set_elf_sym(symtab_section,
359+ 0, 0,
360+ ELFW(ST_INFO)(STB_GLOBAL, STT_NOTYPE), 0,
361+ init_section->sh_num, "__init_start");
362+ Sym sym;
363+ init_section->sh_flags |= SHF_EXECINSTR;
364+ pinit = section_ptr_add(init_section, 2);
365+ pinit[0] = 0xc9; /* leave */
366+ pinit[1] = 0xc3; /* ret */
367+ sym.c = init_index;
368+ add_init_array (s1, &sym);
369+ }
370+#endif
371+ }
372+}
373+#endif
374+
290375 #endif /* !TARGET_DEFS_ONLY */

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