History

Undo part of incr_offset patch.

The incr_offset offset code was not working with bounds checking. So I reverted part of tccgen.c. See new test code 132. Also added some debugging code that prints location of bounds checking calls. Needed this to find the problem. See lib/bcheck.c, lib/bt-dll.c, lib/bt-exe.c, lib/bt-log.c, tccrun.c

herman ten brugge committed 3 years ago

Commit 598134f1 parent d1c10778 files · +96 −5Browse files

Unified · Split

8 files
  1. lib/bcheck.c +9 −1
  2. lib/bt-dll.c +1 −0
  3. lib/bt-exe.c +2 −0
  4. lib/bt-log.c +10 −0
  5. tccgen.c +6 −4
  6. tccrun.c +38 −0
  7. tests/tests2/132_bound_test.c +29 −0
  8. tests/tests2/132_bound_test.expect +1 −0
lib/bcheck.c+9−1
@@ -41,7 +41,7 @@ · 40 unmodified lines
4141 #define BOUND_STATISTIC (1)
4242
4343 #if BOUND_DEBUG
44− #define dprintf(a...) if (print_calls) fprintf(a)
44+ #define dprintf(a...) if (print_calls) { bounds_loc; fprintf(a); }
4545 #else
4646 #define dprintf(a...)
4747 #endif
@@ -446,6 +446,7 @@ static unsigned long long bound_splay_delete; · 398 unmodified lines
446446 #endif
447447
448448 int tcc_backtrace(const char *fmt, ...);
449+void tcc_location(const char *fmt);
449450
450451 /* print a bound error message */
451452 #define bound_warning(...) \
@@ -462,6 +463,13 @@ int tcc_backtrace(const char *fmt, ...); · 10 unmodified lines
462463 exit(255); \
463464 } while (0)
464465
466+#define bounds_loc \
467+ do { \
468+ WAIT_SEM (); \
469+ tcc_location("^bcheck.c^"); \
470+ POST_SEM (); \
471+ } while (0)
472+
465473 static void bound_alloc_error(const char *s)
466474 {
467475 fprintf(stderr,"FATAL: %s\n",s);
lib/bt-dll.c+1−0
@@ -8,6 +8,7 @@ · 7 unmodified lines
88 REDIR(__bt_init) \
99 REDIR(__bt_exit) \
1010 REDIR(tcc_backtrace) \
11+ REDIR(tcc_location) \
1112 \
1213 REDIR(__bound_ptr_add) \
1314 REDIR(__bound_ptr_indir1) \
lib/bt-exe.c+2−0
@@ -8,6 +8,7 @@ · 7 unmodified lines
88 #include "../tccrun.c"
99
1010 int (*__rt_error)(void*, void*, const char *, va_list);
11+void (*__rt_location)(void*, void*, const char *);
1112 __attribute__((weak)) void __bound_checking_lock(void);
1213 __attribute__((weak)) void __bound_checking_unlock(void);
1314
@@ -33,6 +34,7 @@ void __bt_init(rt_context *p, int num_callers) · 19 unmodified lines
3334 rc->num_callers = num_callers - 1;
3435 rc->top_func = main;
3536 __rt_error = _rt_error;
37+ __rt_location = _rt_location;
3638 set_exception_handler();
3739 } else {
3840 p->next = rc->next, rc->next = p;
lib/bt-log.c+10−0
@@ -6,6 +6,7 @@ · 5 unmodified lines
66 #include <string.h>
77
88 int (*__rt_error)(void*, void*, const char *, va_list);
9+void (*__rt_location)(void*, void*, const char *);
910
1011 #ifdef _WIN32
1112 # define DLL_EXPORT __declspec(dllexport)
@@ -42,6 +43,15 @@ DLL_EXPORT int tcc_backtrace(const char *fmt, ...) · 30 unmodified lines
4243 return ret;
4344 }
4445
46+DLL_EXPORT void tcc_location(const char *fmt)
47+{
48+ if (__rt_location) {
49+ void *fp = __builtin_frame_address(1);
50+ void *ip = __builtin_return_address(0);
51+ __rt_location(fp, ip, fmt);
52+ }
53+}
54+
4555 #if (defined(__GNUC__) && (__GNUC__ >= 6)) || defined(__clang__)
4656 #pragma GCC diagnostic pop
4757 #endif
tccgen.c+6−4
@@ -6010,6 +6010,7 @@ special_math_val: · 6009 unmodified lines
60106010 indir();
60116011 qualifiers = vtop->type.t & (VT_CONSTANT | VT_VOLATILE);
60126012 test_lvalue();
6013+ gaddrof();
60136014 /* expect pointer on structure */
60146015 if ((vtop->type.t & VT_BTYPE) != VT_STRUCT)
60156016 expect("struct or union");
@@ -6020,15 +6021,16 @@ special_math_val: · 4 unmodified lines
60206021 expect("field name");
60216022 s = find_field(&vtop->type, tok, &cumofs);
60226023 /* add field offset to pointer */
6023− incr_offset(cumofs);
6024+ vtop->type = char_pointer_type; /* change type to 'char *' */
6025+ vpushi(cumofs);
6026+ gen_op('+');
60246027 /* change type to field type, and set to lvalue */
60256028 vtop->type = s->type;
60266029 vtop->type.t |= qualifiers;
60276030 /* an array is never an lvalue */
6028− if (vtop->type.t & VT_ARRAY) {
6029− vtop->r &= ~VT_LVAL;
6031+ if (!(vtop->type.t & VT_ARRAY)) {
6032+ vtop->r |= VT_LVAL;
60306033 #ifdef CONFIG_TCC_BCHECK
6031− } else {
60326034 /* if bound checking, the referenced pointer must be checked */
60336035 if (tcc_state->do_bounds_check)
60346036 vtop->r |= VT_MUSTBOUND;
tccrun.c+38−0
@@ -53,6 +53,7 @@ typedef struct rt_context · 52 unmodified lines
5353 static rt_context g_rtctxt;
5454 static void set_exception_handler(void);
5555 static int _rt_error(void *fp, void *ip, const char *fmt, va_list ap);
56+static void _rt_location(void *fp, void *ip, const char *fmt);
5657 static void rt_exit(int code);
5758 #endif /* CONFIG_TCC_BACKTRACE */
5859
@@ -274,6 +275,8 @@ LIBTCCAPI int tcc_run(TCCState *s1, int argc, char **argv) · 215 unmodified lines
274275 rc->do_jmp = 1;
275276 if ((p = tcc_get_symbol(s1, "__rt_error")))
276277 *(void**)p = _rt_error;
278+ if ((p = tcc_get_symbol(s1, "__rt_location")))
279+ *(void**)p = _rt_location;
277280 #ifdef CONFIG_TCC_BCHECK
278281 if (s1->do_bounds_check) {
279282 rc->bounds_start = (void*)bounds_section->sh_addr;
@@ -1089,6 +1092,41 @@ static int _rt_error(void *fp, void *ip, const char *fmt, va_list ap) · 809 unmodified lines
10891092 return 0;
10901093 }
10911094
1095+static void _rt_location(void *fp, void *ip, const char *fmt)
1096+{
1097+ rt_context *rc = &g_rtctxt;
1098+ addr_t pc = 0;
1099+ char skip[100];
1100+ int i, ret;
1101+ const char *a, *b;
1102+
1103+ rc->fp = (addr_t)fp;
1104+ rc->ip = (addr_t)ip;
1105+
1106+ skip[0] = 0;
1107+ /* If fmt is like "^file.c^..." then skip calls from 'file.c' */
1108+ if (fmt[0] == '^' && (b = strchr(a = fmt + 1, fmt[0])))
1109+ memcpy(skip, a, b - a), skip[b - a] = 0;
1110+
1111+ for (i = 0; ; i++) {
1112+ ret = rt_get_caller_pc(&pc, rc, i);
1113+ a = "";
1114+ if (ret != -1) {
1115+ if (rc->dwarf)
1116+ pc = rt_printline_dwarf(rc, pc, "at", skip);
1117+ else
1118+ pc = rt_printline(rc, pc, "at", skip);
1119+ if (pc == (addr_t)-1)
1120+ continue;
1121+ a = ": ";
1122+ }
1123+ rt_printf(a);
1124+ break;
1125+ }
1126+
1127+ rc->ip = rc->fp = 0;
1128+}
1129+
10921130 /* emit a run time error at position 'pc' */
10931131 static int rt_error(const char *fmt, ...)
10941132 {
tests/tests2/132_bound_test.c+29−0
@@ -0,0 +1,29 @@
1+#include <stdio.h>
2+#include <float.h>
3+
4+union ieee_double_extract
5+{
6+ struct {
7+ unsigned int manl:32;
8+ unsigned int manh:20;
9+ unsigned int exp:11;
10+ unsigned int sig:1;
11+ } s;
12+ double d;
13+};
14+
15+double scale(double d)
16+{
17+ union ieee_double_extract x;
18+
19+ x.d = d;
20+ x.d *= 1000;
21+ return x.d;
22+}
23+
24+int
25+main(void)
26+{
27+ printf("%g\n", scale(42));
28+ return 0;
29+}
tests/tests2/132_bound_test.expect+1−0
@@ -0,0 +1 @@
1+42000

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