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
16 16
17LIBTCC = libtcc.a17LIBTCC = libtcc.a
18LIBTCC1 = libtcc1.a18LIBTCC1 = libtcc1.a
19LIBTCCB1 = libtccb1.a
20LINK_LIBTCC =19LINK_LIBTCC =
21LIBS =20LIBS =
22CFLAGS += -I$(TOP)21CFLAGS += -I$(TOP)
@@ -87,7 +86,7 @@ ifeq ($(INCLUDED),no) · 64 unmodified lines
87# running top Makefile86# running top Makefile
88 87
89PROGS = tcc$(EXESUF)88PROGS = tcc$(EXESUF)
90TCCLIBS = $(LIBTCC1) $(LIBTCCB1) $(LIBTCC) $(LIBTCCDEF)89TCCLIBS = $(LIBTCC1) $(LIBTCC) $(LIBTCCDEF)
91TCCDOCS = tcc.1 tcc-doc.html tcc-doc.info90TCCDOCS = tcc.1 tcc-doc.html tcc-doc.info
92 91
93all: $(PROGS) $(TCCLIBS) $(TCCDOCS)92all: $(PROGS) $(TCCLIBS) $(TCCDOCS)
@@ -101,15 +100,11 @@ TCC_X += riscv64 · 7 unmodified lines
101LIBTCC1_X = i386 x86_64 i386-win32 x86_64-win32 x86_64-osx arm arm64 arm-wince100LIBTCC1_X = i386 x86_64 i386-win32 x86_64-win32 x86_64-osx arm arm64 arm-wince
102LIBTCC1_X += riscv64101LIBTCC1_X += riscv64
103 102
104# cross libtccb1.a targets to build
105LIBTCCB1_X = i386 x86_64 i386-win32 x86_64-win32
106
107PROGS_CROSS = $(foreach X,$(TCC_X),$X-tcc$(EXESUF))103PROGS_CROSS = $(foreach X,$(TCC_X),$X-tcc$(EXESUF))
108LIBTCC1_CROSS = $(foreach X,$(LIBTCC1_X),$X-libtcc1.a)104LIBTCC1_CROSS = $(foreach X,$(LIBTCC1_X),$X-libtcc1.a)
109LIBTCCB1_CROSS = $(foreach X,$(LIBTCCB1_X),$X-libtcc1.a)
110 105
111# build cross compilers & libs106# build cross compilers & libs
112cross: $(LIBTCC1_CROSS) $(LIBTCCB1_CROSS) $(PROGS_CROSS)107cross: $(LIBTCC1_CROSS) $(PROGS_CROSS)
113 108
114# build specific cross compiler & lib109# build specific cross compiler & lib
115cross-%: %-tcc$(EXESUF) %-libtcc1.a ;110cross-%: %-tcc$(EXESUF) %-libtcc1.a ;
@@ -153,10 +148,10 @@ DEFINES += $(DEF-$(or $(findstring win,$T),unx)) · 37 unmodified lines
153 148
154ifneq ($(X),)149ifneq ($(X),)
155ifeq ($(CONFIG_WIN32),yes)150ifeq ($(CONFIG_WIN32),yes)
156DEF-win += -DTCC_LIBTCC1="\"$(X)libtcc1.a\"" -DTCC_LIBTCCB1="\"$(X)libtccb1.a\""151DEF-win += -DTCC_LIBTCC1="\"$(X)libtcc1.a\""
157DEF-unx += -DTCC_LIBTCC1="\"lib/$(X)libtcc1.a\"" -DTCC_LIBTCCB1="\"lib/$(X)libtccb1.a\""152DEF-unx += -DTCC_LIBTCC1="\"lib/$(X)libtcc1.a\""
158else153else
159DEF-all += -DTCC_LIBTCC1="\"$(X)libtcc1.a\"" -DTCC_LIBTCCB1="\"$(X)libtccb1.a\""154DEF-all += -DTCC_LIBTCC1="\"$(X)libtcc1.a\""
160DEF-win += -DCONFIG_TCCDIR="\"$(tccdir)/win32\""155DEF-win += -DCONFIG_TCCDIR="\"$(tccdir)/win32\""
161endif156endif
162endif157endif
@@ -281,8 +276,6 @@ STRIP_yes = -s · 118 unmodified lines
281 276
282LIBTCC1_W = $(filter %-win32-libtcc1.a %-wince-libtcc1.a,$(LIBTCC1_CROSS))277LIBTCC1_W = $(filter %-win32-libtcc1.a %-wince-libtcc1.a,$(LIBTCC1_CROSS))
283LIBTCC1_U = $(filter-out $(LIBTCC1_W),$(LIBTCC1_CROSS))278LIBTCC1_U = $(filter-out $(LIBTCC1_W),$(LIBTCC1_CROSS))
284LIBTCCB1_W = $(filter %-win32-libtccb1.a %-wince-libtccb1.a,$(LIBTCCB1_CROSS))
285LIBTCCB1_U = $(filter-out $(LIBTCCB1_W),$(LIBTCCB1_CROSS))
286IB = $(if $1,mkdir -p $2 && $(INSTALLBIN) $1 $2)279IB = $(if $1,mkdir -p $2 && $(INSTALLBIN) $1 $2)
287IBw = $(call IB,$(wildcard $1),$2)280IBw = $(call IB,$(wildcard $1),$2)
288IF = $(if $1,mkdir -p $2 && $(INSTALL) $1 $2)281IF = $(if $1,mkdir -p $2 && $(INSTALL) $1 $2)
@@ -292,8 +285,7 @@ IR = mkdir -p $2 && cp -r $1/. $2 · 3 unmodified lines
292# install progs & libs285# install progs & libs
293install-unx:286install-unx:
294 $(call IBw,$(PROGS) $(PROGS_CROSS),"$(bindir)")287 $(call IBw,$(PROGS) $(PROGS_CROSS),"$(bindir)")
295 $(call IFw,$(LIBTCC1) $(LIBTCC1_U),"$(tccdir)")288 $(call IFw,$(LIBTCC1) bcheck.o $(LIBTCC1_U),"$(tccdir)")
296 $(call IFw,$(LIBTCCB1) $(LIBTCCB1_U),"$(tccdir)")
297 $(call IF,$(TOPSRC)/include/*.h $(TOPSRC)/tcclib.h,"$(tccdir)/include")289 $(call IF,$(TOPSRC)/include/*.h $(TOPSRC)/tcclib.h,"$(tccdir)/include")
298 $(call $(if $(findstring .so,$(LIBTCC)),IBw,IFw),$(LIBTCC),"$(libdir)")290 $(call $(if $(findstring .so,$(LIBTCC)),IBw,IFw),$(LIBTCC),"$(libdir)")
299 $(call IF,$(TOPSRC)/libtcc.h,"$(includedir)")291 $(call IF,$(TOPSRC)/libtcc.h,"$(includedir)")
@@ -318,8 +310,7 @@ uninstall-unx: · 18 unmodified lines
318install-win:310install-win:
319 $(call IBw,$(PROGS) $(PROGS_CROSS) $(subst libtcc.a,,$(LIBTCC)),"$(bindir)")311 $(call IBw,$(PROGS) $(PROGS_CROSS) $(subst libtcc.a,,$(LIBTCC)),"$(bindir)")
320 $(call IF,$(TOPSRC)/win32/lib/*.def,"$(tccdir)/lib")312 $(call IF,$(TOPSRC)/win32/lib/*.def,"$(tccdir)/lib")
321 $(call IFw,libtcc1.a $(LIBTCC1_W),"$(tccdir)/lib")313 $(call IFw,libtcc1.a bcheck.o $(LIBTCC1_W),"$(tccdir)/lib")
322 $(call IFw,libtccb1.a $(LIBTCCB1_W),"$(tccdir)/lib")
323 $(call IF,$(TOPSRC)/include/*.h $(TOPSRC)/tcclib.h,"$(tccdir)/include")314 $(call IF,$(TOPSRC)/include/*.h $(TOPSRC)/tcclib.h,"$(tccdir)/include")
324 $(call IR,$(TOPSRC)/win32/include,"$(tccdir)/include")315 $(call IR,$(TOPSRC)/win32/include,"$(tccdir)/include")
325 $(call IR,$(TOPSRC)/win32/examples,"$(tccdir)/examples")316 $(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
425 int size, align, r, args_size, i, func_call;425 int size, align, r, args_size, i, func_call;
426 Sym *func_sym;426 Sym *func_sym;
427 427
428#ifdef CONFIG_TCC_BCHECK
429 if (tcc_state->do_bounds_check)
430 gbound_args(nb_args);
431#endif
432
428 args_size = 0;433 args_size = 0;
429 for(i = 0;i < nb_args; i++) {434 for(i = 0;i < nb_args; i++) {
430 if ((vtop->type.t & VT_BTYPE) == VT_STRUCT) {435 if ((vtop->type.t & VT_BTYPE) == VT_STRUCT) {
@@ -1051,119 +1056,18 @@ ST_FUNC void ggoto(void) · 620 unmodified lines
1051 1056
1052/* bound check support functions */1057/* bound check support functions */
1053#ifdef CONFIG_TCC_BCHECK1058#ifdef CONFIG_TCC_BCHECK
1054
1055ST_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
1128/* generate a bounded pointer addition */1059/* generate a bounded pointer addition */
1129ST_FUNC void gen_bounded_ptr_add(void)1060ST_FUNC void gen_bounded_ptr_add(void)
1130{1061{
1131 /* save all temporary registers */1062 vpush_global_sym(&func_old_type, TOK___bound_ptr_add);
1132 save_regs(0);1063 vrott(3);
1133 /* prepare fast i386 function call (args in eax and edx) */1064 gfunc_call(2);
1134 gv2(RC_EAX, RC_EDX);1065 vpushi(0);
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 */
1163 /* returned pointer is in eax */1066 /* returned pointer is in eax */
1164 vtop++;
1165 vtop->r = TREG_EAX | VT_BOUNDED;1067 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 */
1167 vtop->c.i = (cur_text_section->reloc->data_offset - sizeof(Elf32_Rel));1071 vtop->c.i = (cur_text_section->reloc->data_offset - sizeof(Elf32_Rel));
1168}1072}
1169 1073
@@ -1176,6 +1080,9 @@ ST_FUNC void gen_bounded_ptr_deref(void) · 6 unmodified lines
1176 Elf32_Rel *rel;1080 Elf32_Rel *rel;
1177 Sym *sym;1081 Sym *sym;
1178 1082
1083 if (nocode_wanted)
1084 return;
1085
1179 size = 0;1086 size = 0;
1180 /* XXX: put that code in generic part of tcc */1087 /* XXX: put that code in generic part of tcc */
1181 if (!is_float(vtop->type.t)) {1088 if (!is_float(vtop->type.t)) {
@@ -1194,17 +1101,18 @@ ST_FUNC void gen_bounded_ptr_deref(void) · 12 unmodified lines
1194 case 12: func = TOK___bound_ptr_indir12; break;1101 case 12: func = TOK___bound_ptr_indir12; break;
1195 case 16: func = TOK___bound_ptr_indir16; break;1102 case 16: func = TOK___bound_ptr_indir16; break;
1196 default:1103 default:
1197 tcc_error("unhandled size when dereferencing bounded pointer");1104 /* may happen with struct member access */
1198 func = 0;1105 return;
1199 break;1106 //tcc_error("unhandled size when dereferencing bounded pointer");
1107 //func = 0;
1108 //break;
1200 }1109 }
1201
1202 /* patch relocation */
1203 /* XXX: find a better solution ? */
1204 rel = (Elf32_Rel *)(cur_text_section->reloc->data + vtop->c.i);
1205 sym = external_global_sym(func, &func_old_type);1110 sym = external_global_sym(func, &func_old_type);
1206 if (!sym->c)1111 if (!sym->c)
1207 put_extern_sym(sym, NULL, 0, 0);1112 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);
1208 rel->r_info = ELF32_R_INFO(sym->c, ELF32_R_TYPE(rel->r_info));1116 rel->r_info = ELF32_R_INFO(sym->c, ELF32_R_TYPE(rel->r_info));
1209}1117}
1210#endif1118#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
235 }235 }
236}236}
237 237
238#ifdef CONFIG_TCC_BCHECK
239ST_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
238#endif /* !TARGET_DEFS_ONLY */313#endif /* !TARGET_DEFS_ONLY */
lib/Makefile+17−32
@@ -7,8 +7,6 @@ include $(TOP)/Makefile · 6 unmodified lines
7VPATH = $(TOPSRC)/lib $(TOPSRC)/win32/lib7VPATH = $(TOPSRC)/lib $(TOPSRC)/win32/lib
8T = $(or $(CROSS_TARGET),$(NATIVE_TARGET),unknown)8T = $(or $(CROSS_TARGET),$(NATIVE_TARGET),unknown)
9X = $(if $(CROSS_TARGET),$(CROSS_TARGET)-)9X = $(if $(CROSS_TARGET),$(CROSS_TARGET)-)
10BIN = $(TOP)/$(X)libtcc1.a
11BINB = $(TOP)/$(X)libtccb1.a
12 10
13XTCC ?= $(TOP)/$(X)tcc$(EXESUF)11XTCC ?= $(TOP)/$(X)tcc$(EXESUF)
14XCC = $(XTCC)12XCC = $(XTCC)
@@ -20,8 +18,6 @@ XCFG = $(or $(findstring -win,$T),-unx) · 5 unmodified lines
20 18
21# in order to use gcc, tyoe: make <target>-libtcc1-usegcc=yes19# in order to use gcc, tyoe: make <target>-libtcc1-usegcc=yes
22arm-libtcc1-usegcc ?= no20arm-libtcc1-usegcc ?= no
23x86_64-libtcc1-usegcc ?= no
24i386-libtcc1-usegcc ?= no
25 21
26ifeq "$($(T)-libtcc1-usegcc)" "yes"22ifeq "$($(T)-libtcc1-usegcc)" "yes"
27 XCC = $(CC)23 XCC = $(CC)
@@ -42,8 +38,6 @@ ifdef CONFIG_OSX · 14 unmodified lines
42 XFLAGS += -D_ANSI_SOURCE38 XFLAGS += -D_ANSI_SOURCE
43endif39endif
44 40
45XFLAGS += -g
46
47I386_O = libtcc1.o alloca86.o alloca86-bt.o41I386_O = libtcc1.o alloca86.o alloca86-bt.o
48X86_64_O = libtcc1.o alloca86_64.o alloca86_64-bt.o42X86_64_O = libtcc1.o alloca86_64.o alloca86_64-bt.o
49ARM_O = libtcc1.o armeabi.o alloca-arm.o armflush.o43ARM_O = libtcc1.o armeabi.o alloca-arm.o armflush.o
@@ -51,11 +45,11 @@ ARM64_O = lib-arm64.o · 1 unmodified line
51RISCV64_O = lib-arm64.o45RISCV64_O = lib-arm64.o
52WIN_O = crt1.o crt1w.o wincrt1.o wincrt1w.o dllcrt1.o dllmain.o46WIN_O = crt1.o crt1w.o wincrt1.o wincrt1w.o dllcrt1.o dllmain.o
53 47
54OBJ-i386 = $(I386_O) $(DSO_O)48OBJ-i386 = $(I386_O) $(BCHECK_O) $(DSO_O)
55OBJ-x86_64 = $(X86_64_O) va_list.o $(DSO_O)49OBJ-x86_64 = $(X86_64_O) va_list.o $(BCHECK_O) $(DSO_O)
56OBJ-x86_64-osx = $(X86_64_O) va_list.o50OBJ-x86_64-osx = $(X86_64_O) va_list.o
57OBJ-i386-win32 = $(I386_O) chkstk.o $(WIN_O)51OBJ-i386-win32 = $(I386_O) chkstk.o bcheck.o $(WIN_O)
58OBJ-x86_64-win32 = $(X86_64_O) chkstk.o (WIN_O)52OBJ-x86_64-win32 = $(X86_64_O) chkstk.o bcheck.o $(WIN_O)
59OBJ-arm64 = $(ARM64_O) $(DSO_O)53OBJ-arm64 = $(ARM64_O) $(DSO_O)
60OBJ-arm = $(ARM_O) $(DSO_O)54OBJ-arm = $(ARM_O) $(DSO_O)
61OBJ-arm-fpa = $(ARM_O) $(DSO_O)55OBJ-arm-fpa = $(ARM_O) $(DSO_O)
@@ -66,27 +60,14 @@ OBJ-arm-eabihf = $(ARM_O) $(DSO_O) · 4 unmodified lines
66OBJ-arm-wince = $(ARM_O) $(WIN_O)60OBJ-arm-wince = $(ARM_O) $(WIN_O)
67OBJ-riscv64 = $(RISCV64_O) $(DSO_O)61OBJ-riscv64 = $(RISCV64_O) $(DSO_O)
68 62
69OBJB-i386 = $(BCHECK_O)63OBJ-extra = $(filter bcheck.o,$(OBJ-$T))
70OBJB-x86_64 = $(BCHECK_O)64OBJ-libtcc1 = $(addprefix $(X),$(filter-out $(OBJ-extra),$(OBJ-$T)))
71OBJB-x86_64-osx = dummy.o65
72OBJB-i386-win32 = bcheck.o66ALL = $(addprefix $(TOP)/,$(X)libtcc1.a $(OBJ-extra))
73OBJB-x86_64-win32 = bcheck.o67
74OBJB-arm64 = dummy.o68all: $(ALL)
75OBJB-arm = dummy.o
76OBJB-arm-fpa = dummy.o
77OBJB-arm-fpa-ld = dummy.o
78OBJB-arm-vfp = dummy.o
79OBJB-arm-eabi = dummy.o
80OBJB-arm-eabihf = dummy.o
81OBJB-arm-wince = dummy.o
82OBJB-riscv64 = dummy.o
83
84all: $(BIN) $(BINB)
85
86$(BIN) : $(patsubst %.o,$(X)%.o,$(OBJ-$T))
87 $(XAR) rcs $@ $^
88 69
89$(BINB) : $(patsubst %.o,$(X)%.o,$(OBJB-$T))70$(TOP)/$(X)libtcc1.a : $(OBJ-libtcc1)
90 $(XAR) rcs $@ $^71 $(XAR) rcs $@ $^
91 72
92$(X)%.o : %.c73$(X)%.o : %.c
@@ -95,8 +76,12 @@ $(X)%.o : %.c · 2 unmodified lines
95$(X)%.o : %.S76$(X)%.o : %.S
96 $(XCC) -c $< -o $@ $(XFLAGS)77 $(XCC) -c $< -o $@ $(XFLAGS)
97 78
79$(TOP)/%.o : %.c
80 $(XCC) -c $< -o $@ $(XFLAGS)
81
82$(TOP)/bcheck.o : XFLAGS += -g
83
98$(X)crt1w.o : crt1.c84$(X)crt1w.o : crt1.c
99$(X)wincrt1w.o : wincrt1.c85$(X)wincrt1w.o : wincrt1.c
100
101clean :86clean :
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
5__bound_alloca:5__bound_alloca:
6 6
7#ifdef _WIN327#ifdef _WIN32
8 pop %rdx8 inc %rcx # add one extra to separate regions
9 mov %rcx,%rax9 jmp alloca
10 add $15,%rax10.globl __bound_alloca_nr
11 and $-16,%rax11__bound_alloca_nr:
12 jz p312 dec %rcx
13
14p1:
15 cmp $4096,%rax
16 jbe p2
17 test %rax,-4096(%rsp)
18 sub $4096,%rsp
19 sub $4096,%rax
20 jmp p1
21p2:
22
23 sub %rax,%rsp
24 mov %rsp,%rax
25
26 push %rdx
27 push %rax13 push %rax
28 mov %rcx,%rdx14 mov %rcx,%rdx
29 mov %rax,%rcx15 mov %rax,%rcx
30 sub $20,%rsp16 sub $32,%rsp
31 call __bound_new_region17 call __bound_new_region
32 add $20,%rsp18 add $32,%rsp
33 pop %rax19 pop %rax
34 pop %rdx
35
36 add $32,%rax
37p3:
38 push %rdx
39 ret20 ret
40#else21#else
41 pop %rdx22 pop %rdx
42 mov %rdi,%rax23 mov %rdi,%rax
43 mov %rax,%rsi # size, a second parm to the __bound_new_region24 mov %rax,%rsi # size, a second parm to the __bound_new_region
44 25
45 add $15,%rax26 add $15 + 1,%rax # add one extra to separate regions
46 and $-16,%rax27 and $-16,%rax
47 jz p328 jz p3
48 29
lib/alloca86_64.S+0−4
@@ -24,12 +24,8 @@ p1: · 23 unmodified lines
24 jmp p124 jmp p1
25p2:25p2:
26#endif26#endif
27
28 sub %rax,%rsp27 sub %rax,%rsp
29 mov %rsp,%rax28 mov %rsp,%rax
30#ifdef _WIN32
31 add $32,%rax
32#endif
33p3:29p3:
34 push %rdx30 push %rdx
35 ret31 ret
lib/bcheck.c+17−14
@@ -205,6 +205,9 @@ void __bound_checking (int no_check) · 204 unmodified lines
205 no_checking = no_check;205 no_checking = no_check;
206}206}
207 207
208#define no_FASTCALL
209//#define no_checking 1
210
208/* print a bound error message */211/* print a bound error message */
209static void bound_error(const char *fmt, ...)212static void bound_error(const char *fmt, ...)
210{213{
@@ -221,8 +224,7 @@ static void bound_alloc_error(void) · 10 unmodified lines
221 224
222/* return '(p + offset)' for pointer arithmetic (a pointer can reach225/* return '(p + offset)' for pointer arithmetic (a pointer can reach
223 the end of a region in this case */226 the end of a region in this case */
224void * FASTCALL __bound_ptr_add(void *p, size_t offset,227void * no_FASTCALL __bound_ptr_add(void *p, size_t offset)
225 size_t line, const char *filename)
226{228{
227 size_t addr = (size_t)p;229 size_t addr = (size_t)p;
228 230
@@ -230,8 +232,8 @@ void * FASTCALL __bound_ptr_add(void *p, size_t offset, · 1 unmodified line
230 return p + offset;232 return p + offset;
231 }233 }
232 234
233 dprintf(stderr, "%s %s (%s:%u): %p 0x%x\n",235 dprintf(stderr, "%s %s : %p 0x%x\n",
234 __FILE__, __FUNCTION__, filename, line, p, (unsigned)offset);236 __FILE__, __FUNCTION__, p, (unsigned)offset);
235 237
236 WAIT_SEM ();238 WAIT_SEM ();
237 INCR_COUNT(bound_ptr_add_count);239 INCR_COUNT(bound_ptr_add_count);
@@ -250,8 +252,10 @@ void * FASTCALL __bound_ptr_add(void *p, size_t offset, · 12 unmodified lines
250 if (addr <= tree->size) {252 if (addr <= tree->size) {
251 addr += offset;253 addr += offset;
252 if (tree->is_invalid || addr > tree->size) {254 if (tree->is_invalid || addr > tree->size) {
253 fprintf(stderr,"%s %s (%s:%u): %p is outside of the region\n",255 #if 0
254 __FILE__, __FUNCTION__, filename, line, p + offset);256 fprintf(stderr,"%s %s : %p is outside of the region\n",
257 __FILE__, __FUNCTION__, p + offset);
258 #endif
255 if (never_fatal == 0) {259 if (never_fatal == 0) {
256 POST_SEM ();260 POST_SEM ();
257 return INVALID_POINTER; /* return an invalid pointer */261 return INVALID_POINTER; /* return an invalid pointer */
@@ -266,16 +270,15 @@ void * FASTCALL __bound_ptr_add(void *p, size_t offset, · 8 unmodified lines
266/* return '(p + offset)' for pointer indirection (the resulting must270/* return '(p + offset)' for pointer indirection (the resulting must
267 be strictly inside the region */271 be strictly inside the region */
268#define BOUND_PTR_INDIR(dsize) \272#define BOUND_PTR_INDIR(dsize) \
269void * FASTCALL __bound_ptr_indir ## dsize (void *p, size_t offset, \273void * no_FASTCALL __bound_ptr_indir ## dsize (void *p, size_t offset) \
270 size_t line, const char *filename) \
271{ \274{ \
272 size_t addr = (size_t)p; \275 size_t addr = (size_t)p; \
273 \276 \
274 if (no_checking) { \277 if (no_checking) { \
275 return p + offset; \278 return p + offset; \
276 } \279 } \
277 dprintf(stderr, "%s %s (%s:%u): %p 0x%x start\n", \280 dprintf(stderr, "%s %s : %p 0x%x start\n", \
278 __FILE__, __FUNCTION__, filename, line, p, (unsigned)offset); \281 __FILE__, __FUNCTION__, p, (unsigned)offset); \
279 WAIT_SEM (); \282 WAIT_SEM (); \
280 INCR_COUNT(bound_ptr_indir ## dsize ## _count); \283 INCR_COUNT(bound_ptr_indir ## dsize ## _count); \
281 if (tree) { \284 if (tree) { \
@@ -293,8 +296,8 @@ void * FASTCALL __bound_ptr_indir ## dsize (void *p, size_t offset, \ · 11 unmodified lines
293 if (addr <= tree->size) { \296 if (addr <= tree->size) { \
294 addr += offset + dsize; \297 addr += offset + dsize; \
295 if (tree->is_invalid || addr > tree->size) { \298 if (tree->is_invalid || addr > tree->size) { \
296 fprintf(stderr,"%s %s (%s:%u): %p is outside of the region\n", \299 fprintf(stderr,"%s %s : %p is outside of the region\n", \
297 __FILE__, __FUNCTION__, filename, line, p + offset); \300 __FILE__, __FUNCTION__, p + offset); \
298 if (never_fatal == 0) { \301 if (never_fatal == 0) { \
299 POST_SEM (); \302 POST_SEM (); \
300 return INVALID_POINTER; /* return an invalid pointer */ \303 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
907 return;910 return;
908 if (size == 0)911 if (size == 0)
909 return;912 return;
910 p = __bound_ptr_add((void *)p, size, 0, function);913 p = __bound_ptr_add((void *)p, size);
911 if (p == INVALID_POINTER)914 if (p == INVALID_POINTER)
912 bound_error("invalid pointer");915 bound_error("invalid pointer");
913}916}
@@ -959,7 +962,7 @@ int __bound_strlen(const char *s) · 45 unmodified lines
959 INCR_COUNT(bound_strlen_count);962 INCR_COUNT(bound_strlen_count);
960 while (*p++);963 while (*p++);
961 len = (p - s) - 1;964 len = (p - s) - 1;
962 p = __bound_ptr_indir1((char *)s, len, 0, "strlen");965 p = __bound_ptr_indir1((char *)s, len);
963 if (p == INVALID_POINTER)966 if (p == INVALID_POINTER)
964 bound_error("bad pointer in strlen()");967 bound_error("bad pointer in strlen()");
965 return len;968 return len;
lib/dummy.c+0−1
@@ -1 +0,0 @@
1static char dummy;
libtcc.c+0−4
@@ -1545,7 +1545,6 @@ static const TCCOption tcc_options[] = { · 1544 unmodified lines
1545#endif1545#endif
1546#ifdef CONFIG_TCC_BCHECK1546#ifdef CONFIG_TCC_BCHECK
1547 { "b", TCC_OPTION_b, 0 },1547 { "b", TCC_OPTION_b, 0 },
1548 { "ba", TCC_OPTION_ba, 0 },
1549#endif1548#endif
1550 { "g", TCC_OPTION_g, TCC_OPTION_HAS_ARG | TCC_OPTION_NOSEP },1549 { "g", TCC_OPTION_g, TCC_OPTION_HAS_ARG | TCC_OPTION_NOSEP },
1551 { "c", TCC_OPTION_c, 0 },1550 { "c", TCC_OPTION_c, 0 },
@@ -1802,9 +1801,6 @@ reparse: · 250 unmodified lines
1802 s->do_bounds_check = 1;1801 s->do_bounds_check = 1;
1803 s->do_debug = 1;1802 s->do_debug = 1;
1804 break;1803 break;
1805 case TCC_OPTION_ba:
1806 s->do_bounds_check_address = 1;
1807 break;
1808#endif1804#endif
1809 case TCC_OPTION_g:1805 case TCC_OPTION_g:
1810 s->do_debug = 1;1806 s->do_debug = 1;
tcc.c+0−1
@@ -59,7 +59,6 @@ static const char help[] = · 58 unmodified lines
59 " -g generate runtime debug info\n"59 " -g generate runtime debug info\n"
60#ifdef CONFIG_TCC_BCHECK60#ifdef CONFIG_TCC_BCHECK
61 " -b compile with built-in memory and bounds checker (implies -g)\n"61 " -b compile with built-in memory and bounds checker (implies -g)\n"
62 " -ba Enable better address checking with bounds checker\n"
63#endif62#endif
64#ifdef CONFIG_TCC_BACKTRACE63#ifdef CONFIG_TCC_BACKTRACE
65 " -bt N show N callers in stack traces\n"64 " -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
292#ifndef TCC_LIBTCC1292#ifndef TCC_LIBTCC1
293# define TCC_LIBTCC1 "libtcc1.a"293# define TCC_LIBTCC1 "libtcc1.a"
294#endif294#endif
295#ifndef TCC_LIBTCCB1
296# define TCC_LIBTCCB1 "libtccb1.a"
297#endif
298 295
299/* library to use with CONFIG_USE_LIBGCC instead of libtcc1.a */296/* library to use with CONFIG_USE_LIBGCC instead of libtcc1.a */
300#if defined CONFIG_USE_LIBGCC && !defined TCC_LIBGCC297#if defined CONFIG_USE_LIBGCC && !defined TCC_LIBGCC
@@ -720,7 +717,6 @@ struct TCCState { · 419 unmodified lines
720#ifdef CONFIG_TCC_BCHECK717#ifdef CONFIG_TCC_BCHECK
721 /* compile with built-in memory and bounds checker */718 /* compile with built-in memory and bounds checker */
722 unsigned char do_bounds_check;719 unsigned char do_bounds_check;
723 unsigned char do_bounds_check_address;
724#endif720#endif
725#ifdef TCC_TARGET_ARM721#ifdef TCC_TARGET_ARM
726 enum float_abi float_abi; /* float ABI of the generated code*/722 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
1250#endif1246#endif
1251ST_FUNC int tcc_add_dll(TCCState *s, const char *filename, int flags);1247ST_FUNC int tcc_add_dll(TCCState *s, const char *filename, int flags);
1252#ifdef CONFIG_TCC_BCHECK1248#ifdef CONFIG_TCC_BCHECK
1253ST_FUNC void tcc_add_bcheck(TCCState *s1, Section *bound_sec, Section *sym_sec);1249ST_FUNC void tcc_add_bcheck(TCCState *s1);
1254#endif1250#endif
1255ST_FUNC void tcc_add_pragma_libs(TCCState *s1);1251ST_FUNC void tcc_add_pragma_libs(TCCState *s1);
1256PUB_FUNC int tcc_add_library_err(TCCState *s, const char *f);1252PUB_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
1437#if defined TCC_TARGET_X86_64 && !defined TCC_TARGET_PE1433#if defined TCC_TARGET_X86_64 && !defined TCC_TARGET_PE
1438ST_FUNC int classify_x86_64_va_arg(CType *ty);1434ST_FUNC int classify_x86_64_va_arg(CType *ty);
1439#endif1435#endif
1436#ifdef CONFIG_TCC_BCHECK
1437ST_FUNC void gbound_args(int nb_args);
1438#endif
1440 1439
1441/* ------------ tccelf.c ------------ */1440/* ------------ tccelf.c ------------ */
1442 1441
tccelf.c+2−2
@@ -1321,7 +1321,7 @@ ST_FUNC void tcc_add_runtime(TCCState *s1) · 1320 unmodified lines
1321{1321{
1322 s1->filetype = 0;1322 s1->filetype = 0;
1323#ifdef CONFIG_TCC_BCHECK1323#ifdef CONFIG_TCC_BCHECK
1324 tcc_add_bcheck(s1, bounds_section, symtab_section);1324 tcc_add_bcheck(s1);
1325#endif1325#endif
1326 tcc_add_pragma_libs(s1);1326 tcc_add_pragma_libs(s1);
1327#ifndef TCC_TARGET_PE1327#ifndef TCC_TARGET_PE
@@ -1340,7 +1340,7 @@ ST_FUNC void tcc_add_runtime(TCCState *s1) · 12 unmodified lines
1340 if (s1->do_bounds_check && s1->output_type != TCC_OUTPUT_DLL) {1340 if (s1->do_bounds_check && s1->output_type != TCC_OUTPUT_DLL) {
1341 tcc_add_library_err(s1, "pthread");1341 tcc_add_library_err(s1, "pthread");
1342 tcc_add_library_err(s1, "dl");1342 tcc_add_library_err(s1, "dl");
1343 tcc_add_support(s1, TCC_LIBTCCB1);1343 tcc_add_support(s1, "bcheck.o");
1344 }1344 }
1345#endif1345#endif
1346 tcc_add_support(s1, TCC_LIBTCC1);1346 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
1230 type = &int_type;1230 type = &int_type;
1231#endif1231#endif
1232 size = type_size(type, &align);1232 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
1233 l=get_temp_local_var(size,align);1238 l=get_temp_local_var(size,align);
1234 sv.type.t = type->t;1239 sv.type.t = type->t;
1235 sv.r = VT_LOCAL | VT_LVAL;1240 sv.r = VT_LOCAL | VT_LVAL;
@@ -1417,7 +1422,7 @@ static void gbound(void) · 181 unmodified lines
1417 1422
1418 vtop->r &= ~VT_MUSTBOUND;1423 vtop->r &= ~VT_MUSTBOUND;
1419 /* if lvalue, then use checking code before dereferencing */1424 /* if lvalue, then use checking code before dereferencing */
1420 if ((vtop->r & VT_LVAL) && !nocode_wanted) {1425 if (vtop->r & VT_LVAL) {
1421 /* if not VT_BOUNDED value, then make one */1426 /* if not VT_BOUNDED value, then make one */
1422 if (!(vtop->r & VT_BOUNDED)) {1427 if (!(vtop->r & VT_BOUNDED)) {
1423 lval_type = vtop->r & (VT_LVAL_TYPE | VT_LVAL);1428 lval_type = vtop->r & (VT_LVAL_TYPE | VT_LVAL);
@@ -1434,6 +1439,19 @@ static void gbound(void) · 10 unmodified lines
1434 gen_bounded_ptr_deref();1439 gen_bounded_ptr_deref();
1435 }1440 }
1436}1441}
1442
1443/* we need to call __bound_ptr_add before we start to load function
1444 args into registers */
1445ST_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}
1437#endif1455#endif
1438 1456
1439static void incr_bf_adr(int o)1457static void incr_bf_adr(int o)
@@ -2499,25 +2517,7 @@ redo: · 1059 unmodified lines
2499 }2517 }
2500 gen_op('*');2518 gen_op('*');
2501#ifdef CONFIG_TCC_BCHECK2519#ifdef CONFIG_TCC_BCHECK
2502 /* The main reason to removing this code:2520 if (tcc_state->do_bounds_check && !const_wanted) {
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) {
2521 /* if bounded pointers, we generate a special code to2521 /* if bounded pointers, we generate a special code to
2522 test bounds */2522 test bounds */
2523 if (op == '-') {2523 if (op == '-') {
@@ -2525,6 +2525,7 @@ redo: · 1 unmodified line
2525 vswap();2525 vswap();
2526 gen_op('-');2526 gen_op('-');
2527 }2527 }
2528 vtop[-1].r &= ~VT_MUSTBOUND;
2528 gen_bounded_ptr_add();2529 gen_bounded_ptr_add();
2529 } else2530 } else
2530#endif2531#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
1836#define PE_STDSYM(n,s) "_" n s1836#define PE_STDSYM(n,s) "_" n s
1837#endif1837#endif
1838 1838
1839static 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
1839static void pe_add_runtime(TCCState *s1, struct pe_info *pe)1845static void pe_add_runtime(TCCState *s1, struct pe_info *pe)
1840{1846{
1841 const char *start_symbol;1847 const char *start_symbol;
@@ -1884,35 +1890,21 @@ static void pe_add_runtime(TCCState *s1, struct pe_info *pe) · 42 unmodified lines
1884 1890
1885 if (0 == s1->nostdlib) {1891 if (0 == s1->nostdlib) {
1886 static const char *libs[] = {1892 static const char *libs[] = {
1887 TCC_LIBTCC1,
1888#ifdef CONFIG_TCC_BCHECK
1889 TCC_LIBTCCB1,
1890#endif
1891 "msvcrt", "kernel32", "", "user32", "gdi32", NULL1893 "msvcrt", "kernel32", "", "user32", "gdi32", NULL
1892 };1894 };
1893 const char **pp, *p;1895 const char **pp, *p;
1894 for (pp = libs; 0 != (p = *pp); ++pp) {1896#ifdef TCC_IS_NATIVE
1895#ifdef CONFIG_TCC_BCHECK1897 if (s1->do_bounds_check)
1896 if (pp == libs + 1 &&1898 tcc_add_support(s1, "bcheck.o");
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;
1909#endif1899#endif
1910 } else {1900 tcc_add_support(s1, TCC_LIBTCC1);
1901 for (pp = libs; 0 != (p = *pp); ++pp) {
1902 if (*p)
1911 tcc_add_library_err(s1, p);1903 tcc_add_library_err(s1, p);
1912 }1904 else if (PE_DLL != pe_type && PE_GUI != pe_type)
1905 break;
1913 }1906 }
1914 }1907 }
1915
1916 if (TCC_OUTPUT_MEMORY == s1->output_type)1908 if (TCC_OUTPUT_MEMORY == s1->output_type)
1917 pe_type = PE_RUN;1909 pe_type = PE_RUN;
1918 pe->type = pe_type;1910 pe->type = pe_type;
tccpp.c+3−4
@@ -392,16 +392,15 @@ ST_FUNC void cstr_reset(CString *cstr) · 391 unmodified lines
392ST_FUNC int cstr_printf(CString *cstr, const char *fmt, ...)392ST_FUNC int cstr_printf(CString *cstr, const char *fmt, ...)
393{393{
394 va_list v;394 va_list v;
395 va_list vc;
396 int len, size;395 int len, size;
397 396
398 va_start(v, fmt);397 va_start(v, fmt);
399 va_copy (vc, v);398 len = vsnprintf(NULL, 0, fmt, v);
400 len = vsnprintf(NULL, 0, fmt, vc);399 va_end(v);
401 va_end(vc);
402 size = cstr->size + len + 1;400 size = cstr->size + len + 1;
403 if (size > cstr->size_allocated)401 if (size > cstr->size_allocated)
404 cstr_realloc(cstr, size);402 cstr_realloc(cstr, size);
403 va_start(v, fmt);
405 vsnprintf((char*)cstr->data + cstr->size, size, fmt, v);404 vsnprintf((char*)cstr->data + cstr->size, size, fmt, v);
406 va_end(v);405 va_end(v);
407 cstr->size += len;406 cstr->size += len;
tcctok.h+3−0
@@ -306,6 +306,9 @@ · 305 unmodified lines
306 DEF(TOK___bound_local_new, "__bound_local_new")306 DEF(TOK___bound_local_new, "__bound_local_new")
307 DEF(TOK___bound_local_delete, "__bound_local_delete")307 DEF(TOK___bound_local_delete, "__bound_local_delete")
308# ifdef TCC_TARGET_PE308# ifdef TCC_TARGET_PE
309# ifdef TCC_TARGET_X86_64
310 DEF(TOK___bound_alloca_nr, "__bound_alloca_nr")
311# endif
309 DEF(TOK_malloc, "malloc")312 DEF(TOK_malloc, "malloc")
310 DEF(TOK_free, "free")313 DEF(TOK_free, "free")
311 DEF(TOK_realloc, "realloc")314 DEF(TOK_realloc, "realloc")
tests/Makefile+7−8
@@ -23,7 +23,7 @@ TESTS = \ · 22 unmodified lines
23 tests2-dir \23 tests2-dir \
24 pp-dir24 pp-dir
25 25
26BTESTS = test1b test3b btest test426BTESTS = btest test2b
27 27
28# test4_static -- Not all relocation types are implemented yet.28# test4_static -- Not all relocation types are implemented yet.
29# asmtest / asmtest2 -- minor differences with gcc29# asmtest / asmtest2 -- minor differences with gcc
@@ -115,7 +115,7 @@ test3 test3b: tcctest.c test.ref · 85 unmodified lines
115 $(TCC) $(RUN_TCC) $(RUN_TCC) $(RUN_TCC) -run $< > test.out3115 $(TCC) $(RUN_TCC) $(RUN_TCC) $(RUN_TCC) -run $< > test.out3
116 @diff -u test.ref test.out3 && echo "Auto Test3 OK"116 @diff -u test.ref test.out3 && echo "Auto Test3 OK"
117 117
118test%b : TCCFLAGS += -b -ba118test%b : TCCFLAGS += -b
119 119
120# binary output test120# binary output test
121test4: tcctest.c test.ref121test4: tcctest.c test.ref
@@ -130,7 +130,7 @@ test4: tcctest.c test.ref · 8 unmodified lines
130 ./tcctest1 > test1.out130 ./tcctest1 > test1.out
131 @if diff -u test.ref test1.out ; then echo "Dynamic Auto Test OK"; fi131 @if diff -u test.ref test1.out ; then echo "Dynamic Auto Test OK"; fi
132# dynamic output + bound check132# dynamic output + bound check
133 $(TCC) -b -ba -o tcctest4 $<133 $(TCC) -b -o tcctest4 $<
134 ./tcctest4 > test4.out134 ./tcctest4 > test4.out
135 @if diff -u test.ref test4.out ; then echo "BCheck Auto Test OK"; fi135 @if diff -u test.ref test4.out ; then echo "BCheck Auto Test OK"; fi
136 136
@@ -163,15 +163,14 @@ memtest: · 26 unmodified lines
163 163
164 164
165# memory and bound check auto test165# memory and bound check auto test
166BOUNDS_OK = 1 3 4 8 10 14 16166BOUNDS_OK = 1 4 8 10 14 16
167BOUNDS_FAIL= 2 5 6 7 9 11 12 13 15 17167BOUNDS_FAIL= 2 5 6 7 9 11 12 13 15 17
168 168
169btest: boundtest.c169btest: boundtest.c
170 @echo ------------ $@ ------------170 @echo ------------ $@ ------------
171 @ulimit -c 0; \171 @for i in $(BOUNDS_OK); do \
172 for i in $(BOUNDS_OK); do \
173 echo ; echo --- boundtest $$i ---; \172 echo ; echo --- boundtest $$i ---; \
174 if $(TCC) -b -ba -run $< $$i ; then \173 if $(TCC) -b -run $< $$i ; then \
175 echo succeeded as expected; \174 echo succeeded as expected; \
176 else\175 else\
177 echo Failed positive test $$i ; exit 1 ; \176 echo Failed positive test $$i ; exit 1 ; \
@@ -179,7 +178,7 @@ btest: boundtest.c · 1 unmodified line
179 done ;\178 done ;\
180 for i in $(BOUNDS_FAIL); do \179 for i in $(BOUNDS_FAIL); do \
181 echo ; echo --- boundtest $$i ---; \180 echo ; echo --- boundtest $$i ---; \
182 if $(TCC) -b -ba -run $< $$i ; then \181 if $(TCC) -b -run $< $$i ; then \
183 echo Failed negative test $$i ; exit 1 ;\182 echo Failed negative test $$i ; exit 1 ;\
184 else\183 else\
185 echo failed as expected; \184 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
142 142
143static unsigned long func_sub_sp_offset;143static unsigned long func_sub_sp_offset;
144static int func_ret_sub;144static int func_ret_sub;
145static int nested_call;
146static int call_used_nr_reg;
147static int call_used_regs[20];
148 145
149/* XXX: make it faster ? */146/* XXX: make it faster ? */
150ST_FUNC void g(int c)147ST_FUNC void g(int c)
@@ -654,218 +651,19 @@ static void gen_bounds_call(int v) · 503 unmodified lines
654#endif651#endif
655}652}
656 653
657ST_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
740/* generate a bounded pointer addition */654/* generate a bounded pointer addition */
741ST_FUNC void gen_bounded_ptr_add(void)655ST_FUNC void gen_bounded_ptr_add(void)
742{656{
743 int i;657 vpush_global_sym(&func_old_type, TOK___bound_ptr_add);
744 658 vrott(3);
745 nested_call++;659 gfunc_call(2);
746 660 vpushi(0);
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 }
844 /* returned pointer is in rax */661 /* returned pointer is in rax */
845 vtop++;
846 vtop->r = TREG_RAX | VT_BOUNDED;662 vtop->r = TREG_RAX | VT_BOUNDED;
847 663 if (nocode_wanted)
848 for (i = call_used_nr_reg - 1; i >= 0; i--) {664 return;
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
866 /* relocation offset of the bounding function call point */665 /* relocation offset of the bounding function call point */
867 vtop->c.i = (cur_text_section->reloc->data_offset - sizeof(ElfW(Rela)));666 vtop->c.i = (cur_text_section->reloc->data_offset - sizeof(ElfW(Rela)));
868 nested_call--;
869}667}
870 668
871/* patch pointer addition in vtop so that pointer dereferencing is669/* 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
877 ElfW(Rela) *rel;675 ElfW(Rela) *rel;
878 Sym *sym;676 Sym *sym;
879 677
678 if (nocode_wanted)
679 return;
680
880 size = 0;681 size = 0;
881 /* XXX: put that code in generic part of tcc */682 /* XXX: put that code in generic part of tcc */
882 if (!is_float(vtop->type.t)) {683 if (!is_float(vtop->type.t)) {
@@ -886,7 +687,7 @@ ST_FUNC void gen_bounded_ptr_deref(void) · 3 unmodified lines
886 size = 2;687 size = 2;
887 }688 }
888 if (!size)689 if (!size)
889 size = type_size(&vtop->type, &align);690 size = type_size(&vtop->type, &align);
890 switch(size) {691 switch(size) {
891 case 1: func = TOK___bound_ptr_indir1; break;692 case 1: func = TOK___bound_ptr_indir1; break;
892 case 2: func = TOK___bound_ptr_indir2; break;693 case 2: func = TOK___bound_ptr_indir2; break;
@@ -895,18 +696,17 @@ ST_FUNC void gen_bounded_ptr_deref(void) · 2 unmodified lines
895 case 12: func = TOK___bound_ptr_indir12; break;696 case 12: func = TOK___bound_ptr_indir12; break;
896 case 16: func = TOK___bound_ptr_indir16; break;697 case 16: func = TOK___bound_ptr_indir16; break;
897 default:698 default:
898 tcc_error("unhandled size when dereferencing bounded pointer");699 /* may happen with struct member access */
899 func = 0;700 return;
900 break;701 //tcc_error("unhandled size when dereferencing bounded pointer");
702 //func = 0;
703 //break;
901 }704 }
902
903 sym = external_global_sym(func, &func_old_type);705 sym = external_global_sym(func, &func_old_type);
904 if (!sym->c)706 if (!sym->c)
905 put_extern_sym(sym, NULL, 0, 0);707 put_extern_sym(sym, NULL, 0, 0);
906
907 /* patch relocation */708 /* patch relocation */
908 /* XXX: find a better solution ? */709 /* XXX: find a better solution ? */
909
910 rel = (ElfW(Rela) *)(cur_text_section->reloc->data + vtop->c.i);710 rel = (ElfW(Rela) *)(cur_text_section->reloc->data + vtop->c.i);
911 rel->r_info = ELF64_R_INFO(sym->c, ELF64_R_TYPE(rel->r_info));711 rel->r_info = ELF64_R_INFO(sym->c, ELF64_R_TYPE(rel->r_info));
912}712}
@@ -992,6 +792,11 @@ void gfunc_call(int nb_args) · 79 unmodified lines
992 int size, r, args_size, i, d, bt, struct_size;792 int size, r, args_size, i, d, bt, struct_size;
993 int arg;793 int arg;
994 794
795#ifdef CONFIG_TCC_BCHECK
796 if (tcc_state->do_bounds_check)
797 gbound_args(nb_args);
798#endif
799
995 args_size = (nb_args < REGN ? REGN : nb_args) * PTR_SIZE;800 args_size = (nb_args < REGN ? REGN : nb_args) * PTR_SIZE;
996 arg = nb_args;801 arg = nb_args;
997 802
@@ -1051,7 +856,6 @@ void gfunc_call(int nb_args) · 53 unmodified lines
1051 } else {856 } else {
1052 d = arg_prepare_reg(arg);857 d = arg_prepare_reg(arg);
1053 gen_offs_sp(0x8d, d, struct_size);858 gen_offs_sp(0x8d, d, struct_size);
1054 call_used_regs[call_used_nr_reg++] = d;
1055 }859 }
1056 struct_size += size;860 struct_size += size;
1057 } else {861 } else {
@@ -1070,7 +874,6 @@ void gfunc_call(int nb_args) · 12 unmodified lines
1070 o(0x66);874 o(0x66);
1071 orex(1,d,0, 0x7e0f);875 orex(1,d,0, 0x7e0f);
1072 o(0xc0 + arg*8 + REG_VALUE(d));876 o(0xc0 + arg*8 + REG_VALUE(d));
1073 call_used_regs[call_used_nr_reg++] = d;
1074 }877 }
1075 } else {878 } else {
1076 if (bt == VT_STRUCT) {879 if (bt == VT_STRUCT) {
@@ -1086,7 +889,6 @@ void gfunc_call(int nb_args) · 9 unmodified lines
1086 d = arg_prepare_reg(arg);889 d = arg_prepare_reg(arg);
1087 orex(1,d,r,0x89); /* mov */890 orex(1,d,r,0x89); /* mov */
1088 o(0xc0 + REG_VALUE(r) * 8 + REG_VALUE(d));891 o(0xc0 + REG_VALUE(r) * 8 + REG_VALUE(d));
1089 call_used_regs[call_used_nr_reg++] = d;
1090 }892 }
1091 }893 }
1092 }894 }
@@ -1105,7 +907,12 @@ void gfunc_call(int nb_args) · 12 unmodified lines
1105 907
1106 if ((vtop->r & VT_SYM) && vtop->sym->v == TOK_alloca) {908 if ((vtop->r & VT_SYM) && vtop->sym->v == TOK_alloca) {
1107 /* need to add the "func_scratch" area after alloca */909 /* 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
1109 }916 }
1110 917
1111 /* other compilers don't clear the upper bits when returning char/short */918 /* 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
1125 o(0xc089); /* mov %eax,%eax */932 o(0xc089); /* mov %eax,%eax */
1126#endif933#endif
1127 vtop--;934 vtop--;
1128 call_used_nr_reg = 0;
1129}935}
1130 936
1131 937
@@ -1141,7 +947,7 @@ void gfunc_prolog(Sym *func_sym) · 9 unmodified lines
1141 int n_arg = 0;947 int n_arg = 0;
1142 948
1143 func_ret_sub = 0;949 func_ret_sub = 0;
1144 func_scratch = 0;950 func_scratch = 32;
1145 func_alloca = 0;951 func_alloca = 0;
1146 loc = 0;952 loc = 0;
1147 953
@@ -1228,6 +1034,10 @@ void gfunc_epilog(void) · 80 unmodified lines
1228{1034{
1229 int v, saved_ind;1035 int v, saved_ind;
1230 1036
1037 /* align local size to word & save local variables */
1038 func_scratch = (func_scratch + 15) & -16;
1039 loc = (loc & -16) - func_scratch;
1040
1231#ifdef CONFIG_TCC_BCHECK1041#ifdef CONFIG_TCC_BCHECK
1232 if (tcc_state->do_bounds_check1042 if (tcc_state->do_bounds_check
1233 && func_bound_offset != lbounds_section->data_offset)1043 && func_bound_offset != lbounds_section->data_offset)
@@ -1273,9 +1083,7 @@ void gfunc_epilog(void) · 39 unmodified lines
1273 1083
1274 saved_ind = ind;1084 saved_ind = ind;
1275 ind = func_sub_sp_offset - FUNC_PROLOG_SIZE;1085 ind = func_sub_sp_offset - FUNC_PROLOG_SIZE;
1276 /* align local size to word & save local variables */1086 v = -loc;
1277 func_scratch = (func_scratch + 15) & -16;
1278 v = (func_scratch + -loc + 15) & -16;
1279 1087
1280 if (v >= 4096) {1088 if (v >= 4096) {
1281 Sym *sym = external_global_sym(TOK___chkstk, &func_old_type);1089 Sym *sym = external_global_sym(TOK___chkstk, &func_old_type);
@@ -1479,6 +1287,11 @@ void gfunc_call(int nb_args) · 197 unmodified lines
1479 int sse_reg, gen_reg;1287 int sse_reg, gen_reg;
1480 char _onstack[nb_args ? nb_args : 1], *onstack = _onstack;1288 char _onstack[nb_args ? nb_args : 1], *onstack = _onstack;
1481 1289
1290#ifdef CONFIG_TCC_BCHECK
1291 if (tcc_state->do_bounds_check)
1292 gbound_args(nb_args);
1293#endif
1294
1482 /* calculate the number of integer/float register arguments, remember1295 /* calculate the number of integer/float register arguments, remember
1483 arguments to be passed via stack (in onstack[]), and also remember1296 arguments to be passed via stack (in onstack[]), and also remember
1484 if we have to align the stack pointer to 16 (onstack[i] == 2). Needs1297 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
1611 o(0x280f);1424 o(0x280f);
1612 o(0xc0 + (sse_reg << 3));1425 o(0xc0 + (sse_reg << 3));
1613 }1426 }
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;
1616 } else {1427 } else {
1617 assert(reg_count == 1);1428 assert(reg_count == 1);
1618 --sse_reg;1429 --sse_reg;
1619 /* Load directly to register */1430 /* Load directly to register */
1620 gv(RC_XMM0 << sse_reg);1431 gv(RC_XMM0 << sse_reg);
1621 call_used_regs[call_used_nr_reg++] = sse_reg + TREG_XMM0;
1622 }1432 }
1623 } else if (mode == x86_64_mode_integer) {1433 } else if (mode == x86_64_mode_integer) {
1624 /* simple type */1434 /* simple type */
@@ -1629,12 +1439,10 @@ void gfunc_call(int nb_args) · 4 unmodified lines
1629 d = arg_prepare_reg(gen_reg);1439 d = arg_prepare_reg(gen_reg);
1630 orex(1,d,r,0x89); /* mov */1440 orex(1,d,r,0x89); /* mov */
1631 o(0xc0 + REG_VALUE(r) * 8 + REG_VALUE(d));1441 o(0xc0 + REG_VALUE(r) * 8 + REG_VALUE(d));
1632 call_used_regs[call_used_nr_reg++] = d;
1633 if (reg_count == 2) {1442 if (reg_count == 2) {
1634 d = arg_prepare_reg(gen_reg+1);1443 d = arg_prepare_reg(gen_reg+1);
1635 orex(1,d,vtop->r2,0x89); /* mov */1444 orex(1,d,vtop->r2,0x89); /* mov */
1636 o(0xc0 + REG_VALUE(vtop->r2) * 8 + REG_VALUE(d));1445 o(0xc0 + REG_VALUE(vtop->r2) * 8 + REG_VALUE(d));
1637 call_used_regs[call_used_nr_reg++] = d;
1638 }1446 }
1639 }1447 }
1640 vtop--;1448 vtop--;
@@ -1677,7 +1485,6 @@ void gfunc_call(int nb_args) · 36 unmodified lines
1677 else if (bt == (VT_SHORT | VT_UNSIGNED))1485 else if (bt == (VT_SHORT | VT_UNSIGNED))
1678 o(0xc0b70f); /* movzwl %al, %eax */1486 o(0xc0b70f); /* movzwl %al, %eax */
1679 vtop--;1487 vtop--;
1680 call_used_nr_reg = 0;
1681}1488}
1682 1489
1683 1490
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
287 }287 }
288}288}
289 289
290#ifdef CONFIG_TCC_BCHECK
291ST_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
290#endif /* !TARGET_DEFS_ONLY */375#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