diff options
| author | Paul Eggert | 2014-11-29 23:30:22 -0800 |
|---|---|---|
| committer | Paul Eggert | 2014-11-29 23:32:29 -0800 |
| commit | 3517da701ea5d16c296745d6678988b06bee615d (patch) | |
| tree | aa890d2a3915c69ce9a6a41714bc8cad9c6c3b70 /src | |
| parent | 70723e5107fd92c31e5b395d58be0b20b13c322d (diff) | |
| download | emacs-3517da701ea5d16c296745d6678988b06bee615d.tar.gz emacs-3517da701ea5d16c296745d6678988b06bee615d.zip | |
Port better to AddressSanitizer.
These changes suffice for temacs on x86-64 with GCC 4.9.2 and
-fsanitize=address.
* alloc.c (valid_pointer_p) [ADDRESS_SANITIZER]:
Return -1 or 0, as the pipe trick doesn't work.
* alloc.c (relocatable_string_data_p, mark_object, sweep_symbols):
* data.c (Ffset):
* print.c (print_object):
When a pointer-check primitive returns -1, do not assume this
means the pointer is valid or that the underlying system has failed.
It could just be that addresses are being sanitized so Emacs can't
test for pointer validity.
* lisp.h (defined_GC_CHECK_STRING_BYTES): New constant.
(USE_STACK_STRING) [GC_CHECK_STRING_BYTES]: Now false, since the
string validity checker doesn't work on stack-based strings.
Diffstat (limited to 'src')
| -rw-r--r-- | src/ChangeLog | 18 | ||||
| -rw-r--r-- | src/alloc.c | 14 | ||||
| -rw-r--r-- | src/data.c | 2 | ||||
| -rw-r--r-- | src/lisp.h | 7 | ||||
| -rw-r--r-- | src/print.c | 6 |
5 files changed, 39 insertions, 8 deletions
diff --git a/src/ChangeLog b/src/ChangeLog index 668c3e809f6..c977eb490f5 100644 --- a/src/ChangeLog +++ b/src/ChangeLog | |||
| @@ -1,3 +1,21 @@ | |||
| 1 | 2014-11-30 Paul Eggert <eggert@cs.ucla.edu> | ||
| 2 | |||
| 3 | Port better to AddressSanitizer. | ||
| 4 | These changes suffice for temacs on x86-64 with GCC 4.9.2 and | ||
| 5 | -fsanitize=address. | ||
| 6 | * alloc.c (valid_pointer_p) [ADDRESS_SANITIZER]: | ||
| 7 | Return -1 or 0, as the pipe trick doesn't work. | ||
| 8 | * alloc.c (relocatable_string_data_p, mark_object, sweep_symbols): | ||
| 9 | * data.c (Ffset): | ||
| 10 | * print.c (print_object): | ||
| 11 | When a pointer-check primitive returns -1, do not assume this | ||
| 12 | means the pointer is valid or that the underlying system has failed. | ||
| 13 | It could just be that addresses are being sanitized so Emacs can't | ||
| 14 | test for pointer validity. | ||
| 15 | * lisp.h (defined_GC_CHECK_STRING_BYTES): New constant. | ||
| 16 | (USE_STACK_STRING) [GC_CHECK_STRING_BYTES]: Now false, since the | ||
| 17 | string validity checker doesn't work on stack-based strings. | ||
| 18 | |||
| 1 | 2014-11-29 Paul Eggert <eggert@cs.ucla.edu> | 19 | 2014-11-29 Paul Eggert <eggert@cs.ucla.edu> |
| 2 | 20 | ||
| 3 | Improve clarity of USE_LSB_TAG definition. | 21 | Improve clarity of USE_LSB_TAG definition. |
diff --git a/src/alloc.c b/src/alloc.c index faad0b59c87..1019c2af6cc 100644 --- a/src/alloc.c +++ b/src/alloc.c | |||
| @@ -4934,6 +4934,10 @@ valid_pointer_p (void *p) | |||
| 4934 | #ifdef WINDOWSNT | 4934 | #ifdef WINDOWSNT |
| 4935 | return w32_valid_pointer_p (p, 16); | 4935 | return w32_valid_pointer_p (p, 16); |
| 4936 | #else | 4936 | #else |
| 4937 | |||
| 4938 | if (ADDRESS_SANITIZER) | ||
| 4939 | return p ? -1 : 0; | ||
| 4940 | |||
| 4937 | int fd[2]; | 4941 | int fd[2]; |
| 4938 | 4942 | ||
| 4939 | /* Obviously, we cannot just access it (we would SEGV trying), so we | 4943 | /* Obviously, we cannot just access it (we would SEGV trying), so we |
| @@ -4949,7 +4953,7 @@ valid_pointer_p (void *p) | |||
| 4949 | return valid; | 4953 | return valid; |
| 4950 | } | 4954 | } |
| 4951 | 4955 | ||
| 4952 | return -1; | 4956 | return -1; |
| 4953 | #endif | 4957 | #endif |
| 4954 | } | 4958 | } |
| 4955 | 4959 | ||
| @@ -5048,8 +5052,8 @@ relocatable_string_data_p (const char *str) | |||
| 5048 | struct sdata *sdata | 5052 | struct sdata *sdata |
| 5049 | = (struct sdata *) (str - offsetof (struct sdata, data)); | 5053 | = (struct sdata *) (str - offsetof (struct sdata, data)); |
| 5050 | 5054 | ||
| 5051 | if (valid_pointer_p (sdata) | 5055 | if (0 < valid_pointer_p (sdata) |
| 5052 | && valid_pointer_p (sdata->string) | 5056 | && 0 < valid_pointer_p (sdata->string) |
| 5053 | && maybe_lisp_pointer (sdata->string)) | 5057 | && maybe_lisp_pointer (sdata->string)) |
| 5054 | return (valid_lisp_object_p | 5058 | return (valid_lisp_object_p |
| 5055 | (make_lisp_ptr (sdata->string, Lisp_String)) | 5059 | (make_lisp_ptr (sdata->string, Lisp_String)) |
| @@ -6364,7 +6368,7 @@ mark_object (Lisp_Object arg) | |||
| 6364 | CHECK_ALLOCATED_AND_LIVE (live_symbol_p); | 6368 | CHECK_ALLOCATED_AND_LIVE (live_symbol_p); |
| 6365 | ptr->gcmarkbit = 1; | 6369 | ptr->gcmarkbit = 1; |
| 6366 | /* Attempt to catch bogus objects. */ | 6370 | /* Attempt to catch bogus objects. */ |
| 6367 | eassert (valid_lisp_object_p (ptr->function) >= 1); | 6371 | eassert (valid_lisp_object_p (ptr->function)); |
| 6368 | mark_object (ptr->function); | 6372 | mark_object (ptr->function); |
| 6369 | mark_object (ptr->plist); | 6373 | mark_object (ptr->plist); |
| 6370 | switch (ptr->redirect) | 6374 | switch (ptr->redirect) |
| @@ -6749,7 +6753,7 @@ sweep_symbols (void) | |||
| 6749 | ++num_used; | 6753 | ++num_used; |
| 6750 | sym->s.gcmarkbit = 0; | 6754 | sym->s.gcmarkbit = 0; |
| 6751 | /* Attempt to catch bogus objects. */ | 6755 | /* Attempt to catch bogus objects. */ |
| 6752 | eassert (valid_lisp_object_p (sym->s.function) >= 1); | 6756 | eassert (valid_lisp_object_p (sym->s.function)); |
| 6753 | } | 6757 | } |
| 6754 | } | 6758 | } |
| 6755 | 6759 | ||
diff --git a/src/data.c b/src/data.c index 9977a3aaadd..b48dbbebabc 100644 --- a/src/data.c +++ b/src/data.c | |||
| @@ -729,7 +729,7 @@ DEFUN ("fset", Ffset, Sfset, 2, 2, 0, | |||
| 729 | 729 | ||
| 730 | /* Convert to eassert or remove after GC bug is found. In the | 730 | /* Convert to eassert or remove after GC bug is found. In the |
| 731 | meantime, check unconditionally, at a slight perf hit. */ | 731 | meantime, check unconditionally, at a slight perf hit. */ |
| 732 | if (valid_lisp_object_p (definition) < 1) | 732 | if (! valid_lisp_object_p (definition)) |
| 733 | emacs_abort (); | 733 | emacs_abort (); |
| 734 | 734 | ||
| 735 | set_symbol_function (symbol, definition); | 735 | set_symbol_function (symbol, definition); |
diff --git a/src/lisp.h b/src/lisp.h index 42bb33704fa..a56c4a73bf8 100644 --- a/src/lisp.h +++ b/src/lisp.h | |||
| @@ -4604,6 +4604,12 @@ lisp_word_count (ptrdiff_t nbytes) | |||
| 4604 | # define USE_STACK_LISP_OBJECTS false | 4604 | # define USE_STACK_LISP_OBJECTS false |
| 4605 | #endif | 4605 | #endif |
| 4606 | 4606 | ||
| 4607 | #ifdef GC_CHECK_STRING_BYTES | ||
| 4608 | enum { defined_GC_CHECK_STRING_BYTES = true }; | ||
| 4609 | #else | ||
| 4610 | enum { defined_GC_CHECK_STRING_BYTES = false }; | ||
| 4611 | #endif | ||
| 4612 | |||
| 4607 | /* Struct inside unions that are typically no larger and aligned enough. */ | 4613 | /* Struct inside unions that are typically no larger and aligned enough. */ |
| 4608 | 4614 | ||
| 4609 | union Aligned_Cons | 4615 | union Aligned_Cons |
| @@ -4628,6 +4634,7 @@ enum | |||
| 4628 | USE_STACK_CONS = (USE_STACK_LISP_OBJECTS | 4634 | USE_STACK_CONS = (USE_STACK_LISP_OBJECTS |
| 4629 | && alignof (union Aligned_Cons) % GCALIGNMENT == 0), | 4635 | && alignof (union Aligned_Cons) % GCALIGNMENT == 0), |
| 4630 | USE_STACK_STRING = (USE_STACK_CONS | 4636 | USE_STACK_STRING = (USE_STACK_CONS |
| 4637 | && !defined_GC_CHECK_STRING_BYTES | ||
| 4631 | && alignof (union Aligned_String) % GCALIGNMENT == 0) | 4638 | && alignof (union Aligned_String) % GCALIGNMENT == 0) |
| 4632 | }; | 4639 | }; |
| 4633 | 4640 | ||
diff --git a/src/print.c b/src/print.c index 49331ef0984..7723b98348a 100644 --- a/src/print.c +++ b/src/print.c | |||
| @@ -2098,14 +2098,16 @@ print_object (Lisp_Object obj, Lisp_Object printcharfun, bool escapeflag) | |||
| 2098 | for (i = 0; i < limit; i++) | 2098 | for (i = 0; i < limit; i++) |
| 2099 | { | 2099 | { |
| 2100 | Lisp_Object maybe = area[i]; | 2100 | Lisp_Object maybe = area[i]; |
| 2101 | int valid = valid_lisp_object_p (maybe); | ||
| 2101 | 2102 | ||
| 2102 | if (valid_lisp_object_p (maybe) > 0) | 2103 | if (0 < valid) |
| 2103 | { | 2104 | { |
| 2104 | PRINTCHAR (' '); | 2105 | PRINTCHAR (' '); |
| 2105 | print_object (maybe, printcharfun, escapeflag); | 2106 | print_object (maybe, printcharfun, escapeflag); |
| 2106 | } | 2107 | } |
| 2107 | else | 2108 | else |
| 2108 | strout (" <invalid>", -1, -1, printcharfun); | 2109 | strout (valid ? " <some>" : " <invalid>", |
| 2110 | -1, -1, printcharfun); | ||
| 2109 | } | 2111 | } |
| 2110 | if (i == limit && i < amount) | 2112 | if (i == limit && i < amount) |
| 2111 | strout (" ...", 4, 4, printcharfun); | 2113 | strout (" ...", 4, 4, printcharfun); |