aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
Diffstat (limited to 'gcc')
-rw-r--r--gcc/ChangeLog14
-rw-r--r--gcc/asan.c70
-rw-r--r--gcc/asan.h1
-rw-r--r--gcc/final.c4
-rw-r--r--gcc/sanitizer.def2
-rw-r--r--gcc/testsuite/ChangeLog6
-rw-r--r--gcc/testsuite/c-c++-common/asan/stack-overflow-1.c3
-rw-r--r--gcc/testsuite/g++.dg/asan/asan_test.cc46
8 files changed, 77 insertions, 69 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index f858406..e891778 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,17 @@
+2013-11-04 Kostya Serebryany <kcc@google.com>
+
+ Update to match the changed asan API.
+ * asan.c (asan_function_start): New function.
+ (asan_emit_stack_protection): Update the string stored in the
+ stack red zone to match new API. Store the PC of the current
+ function in the red zone.
+ (asan_global_struct): Update the __asan_global definition to match
+ the new API.
+ (asan_add_global): Ditto.
+ * asan.h (asan_function_start): New prototype.
+ * final.c (final_start_function): Call asan_function_start.
+ * sanitizer.def (BUILT_IN_ASAN_INIT): Rename __asan_init_v1 to __asan_init_v3.
+
2013-11-04 Wei Mi <wmi@google.com>
* gcc/config/i386/i386-c.c (ix86_target_macros_internal): Separate
diff --git a/gcc/asan.c b/gcc/asan.c
index 763c59a..fdca377 100644
--- a/gcc/asan.c
+++ b/gcc/asan.c
@@ -59,11 +59,13 @@ along with GCC; see the file COPYING3. If not see
if ((X & 7) + N - 1 > ShadowValue)
__asan_report_loadN(X);
Stores are instrumented similarly, but using __asan_report_storeN functions.
- A call too __asan_init() is inserted to the list of module CTORs.
+ A call too __asan_init_vN() is inserted to the list of module CTORs.
+ N is the version number of the AddressSanitizer API. The changes between the
+ API versions are listed in libsanitizer/asan/asan_interface_internal.h.
The run-time library redefines malloc (so that redzone are inserted around
the allocated memory) and free (so that reuse of free-ed memory is delayed),
- provides __asan_report* and __asan_init functions.
+ provides __asan_report* and __asan_init_vN functions.
Read more:
http://code.google.com/p/address-sanitizer/wiki/AddressSanitizerAlgorithm
@@ -125,9 +127,11 @@ along with GCC; see the file COPYING3. If not see
where '(...){n}' means the content inside the parenthesis occurs 'n'
times, with 'n' being the number of variables on the stack.
+
+ 3/ The following 8 bytes contain the PC of the current function which
+ will be used by the run-time library to print an error message.
- 3/ The following 16 bytes of the red zone have no particular
- format.
+ 4/ The following 8 bytes are reserved for internal use by the run-time.
The shadow memory for that stack layout is going to look like this:
@@ -205,6 +209,9 @@ along with GCC; see the file COPYING3. If not see
// Name of the global variable.
const void *__name;
+ // Name of the module where the global variable is declared.
+ const void *__module_name;
+
// This is always set to NULL for now.
uptr __has_dynamic_init;
}
@@ -914,6 +921,15 @@ asan_clear_shadow (rtx shadow_mem, HOST_WIDE_INT len)
add_int_reg_note (jump, REG_BR_PROB, REG_BR_PROB_BASE * 80 / 100);
}
+void
+asan_function_start (void)
+{
+ section *fnsec = function_section (current_function_decl);
+ switch_to_section (fnsec);
+ ASM_OUTPUT_DEBUG_LABEL (asm_out_file, "LASANPC",
+ current_function_funcdef_no);
+}
+
/* Insert code to protect stack vars. The prologue sequence should be emitted
directly, epilogue sequence returned. BASE is the register holding the
stack base, against which OFFSETS array offsets are relative to, OFFSETS
@@ -929,12 +945,13 @@ asan_emit_stack_protection (rtx base, HOST_WIDE_INT *offsets, tree *decls,
int length)
{
rtx shadow_base, shadow_mem, ret, mem;
+ char buf[30];
unsigned char shadow_bytes[4];
HOST_WIDE_INT base_offset = offsets[length - 1], offset, prev_offset;
HOST_WIDE_INT last_offset, last_size;
int l;
unsigned char cur_shadow_byte = ASAN_STACK_MAGIC_LEFT;
- tree str_cst;
+ tree str_cst, decl, id;
if (shadow_ptr_types[0] == NULL_TREE)
asan_init_shadow_ptr_types ();
@@ -942,11 +959,6 @@ asan_emit_stack_protection (rtx base, HOST_WIDE_INT *offsets, tree *decls,
/* First of all, prepare the description string. */
pretty_printer asan_pp;
- if (DECL_NAME (current_function_decl))
- pp_tree_identifier (&asan_pp, DECL_NAME (current_function_decl));
- else
- pp_string (&asan_pp, "<unknown>");
- pp_space (&asan_pp);
pp_decimal_int (&asan_pp, length / 2 - 1);
pp_space (&asan_pp);
for (l = length - 2; l; l -= 2)
@@ -976,6 +988,20 @@ asan_emit_stack_protection (rtx base, HOST_WIDE_INT *offsets, tree *decls,
emit_move_insn (mem, gen_int_mode (ASAN_STACK_FRAME_MAGIC, ptr_mode));
mem = adjust_address (mem, VOIDmode, GET_MODE_SIZE (ptr_mode));
emit_move_insn (mem, expand_normal (str_cst));
+ mem = adjust_address (mem, VOIDmode, GET_MODE_SIZE (ptr_mode));
+ ASM_GENERATE_INTERNAL_LABEL (buf, "LASANPC", current_function_funcdef_no);
+ id = get_identifier (buf);
+ decl = build_decl (DECL_SOURCE_LOCATION (current_function_decl),
+ VAR_DECL, id, char_type_node);
+ SET_DECL_ASSEMBLER_NAME (decl, id);
+ TREE_ADDRESSABLE (decl) = 1;
+ TREE_READONLY (decl) = 1;
+ DECL_ARTIFICIAL (decl) = 1;
+ DECL_IGNORED_P (decl) = 1;
+ TREE_STATIC (decl) = 1;
+ TREE_PUBLIC (decl) = 0;
+ TREE_USED (decl) = 1;
+ emit_move_insn (mem, expand_normal (build_fold_addr_expr (decl)));
shadow_base = expand_binop (Pmode, lshr_optab, base,
GEN_INT (ASAN_SHADOW_SHIFT),
NULL_RTX, 1, OPTAB_DIRECT);
@@ -1924,20 +1950,21 @@ transform_statements (void)
uptr __size;
uptr __size_with_redzone;
const void *__name;
+ const void *__module_name;
uptr __has_dynamic_init;
} type. */
static tree
asan_global_struct (void)
{
- static const char *field_names[5]
+ static const char *field_names[6]
= { "__beg", "__size", "__size_with_redzone",
- "__name", "__has_dynamic_init" };
- tree fields[5], ret;
+ "__name", "__module_name", "__has_dynamic_init" };
+ tree fields[6], ret;
int i;
ret = make_node (RECORD_TYPE);
- for (i = 0; i < 5; i++)
+ for (i = 0; i < 6; i++)
{
fields[i]
= build_decl (UNKNOWN_LOCATION, FIELD_DECL,
@@ -1962,21 +1989,20 @@ asan_add_global (tree decl, tree type, vec<constructor_elt, va_gc> *v)
{
tree init, uptr = TREE_TYPE (DECL_CHAIN (TYPE_FIELDS (type)));
unsigned HOST_WIDE_INT size;
- tree str_cst, refdecl = decl;
+ tree str_cst, module_name_cst, refdecl = decl;
vec<constructor_elt, va_gc> *vinner = NULL;
- pretty_printer asan_pp;
+ pretty_printer asan_pp, module_name_pp;
if (DECL_NAME (decl))
pp_tree_identifier (&asan_pp, DECL_NAME (decl));
else
pp_string (&asan_pp, "<unknown>");
- pp_space (&asan_pp);
- pp_left_paren (&asan_pp);
- pp_string (&asan_pp, main_input_filename);
- pp_right_paren (&asan_pp);
str_cst = asan_pp_string (&asan_pp);
+ pp_string (&module_name_pp, main_input_filename);
+ module_name_cst = asan_pp_string (&module_name_pp);
+
if (asan_needs_local_alias (decl))
{
char buf[20];
@@ -2004,6 +2030,8 @@ asan_add_global (tree decl, tree type, vec<constructor_elt, va_gc> *v)
CONSTRUCTOR_APPEND_ELT (vinner, NULL_TREE, build_int_cst (uptr, size));
CONSTRUCTOR_APPEND_ELT (vinner, NULL_TREE,
fold_convert (const_ptr_type_node, str_cst));
+ CONSTRUCTOR_APPEND_ELT (vinner, NULL_TREE,
+ fold_convert (const_ptr_type_node, module_name_cst));
CONSTRUCTOR_APPEND_ELT (vinner, NULL_TREE, build_int_cst (uptr, 0));
init = build_constructor (type, vinner);
CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, init);
@@ -2158,7 +2186,7 @@ add_string_csts (void **slot, void *data)
static GTY(()) tree asan_ctor_statements;
/* Module-level instrumentation.
- - Insert __asan_init() into the list of CTORs.
+ - Insert __asan_init_vN() into the list of CTORs.
- TODO: insert redzones around globals.
*/
diff --git a/gcc/asan.h b/gcc/asan.h
index 62dbe98..e564684 100644
--- a/gcc/asan.h
+++ b/gcc/asan.h
@@ -21,6 +21,7 @@ along with GCC; see the file COPYING3. If not see
#ifndef TREE_ASAN
#define TREE_ASAN
+extern void asan_function_start (void);
extern void asan_finish_file (void);
extern rtx asan_emit_stack_protection (rtx, HOST_WIDE_INT *, tree *, int);
extern bool asan_protect_global (tree);
diff --git a/gcc/final.c b/gcc/final.c
index efefe1a..3994732 100644
--- a/gcc/final.c
+++ b/gcc/final.c
@@ -78,6 +78,7 @@ along with GCC; see the file COPYING3. If not see
#include "cfgloop.h"
#include "params.h"
#include "tree-pretty-print.h" /* for dump_function_header */
+#include "asan.h"
#ifdef XCOFF_DEBUGGING_INFO
#include "xcoffout.h" /* Needed for external data
@@ -1738,6 +1739,9 @@ final_start_function (rtx first, FILE *file,
high_block_linenum = high_function_linenum = last_linenum;
+ if (flag_sanitize & SANITIZE_ADDRESS)
+ asan_function_start ();
+
if (!DECL_IGNORED_P (current_function_decl))
debug_hooks->begin_prologue (last_linenum, last_filename);
diff --git a/gcc/sanitizer.def b/gcc/sanitizer.def
index c7c7809..0f45e9e 100644
--- a/gcc/sanitizer.def
+++ b/gcc/sanitizer.def
@@ -27,7 +27,7 @@ along with GCC; see the file COPYING3. If not see
for other FEs by asan.c. */
/* Address Sanitizer */
-DEF_SANITIZER_BUILTIN(BUILT_IN_ASAN_INIT, "__asan_init_v1",
+DEF_SANITIZER_BUILTIN(BUILT_IN_ASAN_INIT, "__asan_init_v3",
BT_FN_VOID, ATTR_NOTHROW_LEAF_LIST)
/* Do not reorder the BUILT_IN_ASAN_REPORT* builtins, e.g. cfgcleanup.c
relies on this order. */
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index d007b02..8483842 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,3 +1,9 @@
+2013-11-04 Kostya Serebryany <kcc@google.com>
+
+ * g++.dg/asan/asan_test.cc: Update the test
+ to match the fresh asan run-time.
+ * c-c++-common/asan/stack-overflow-1.c: Ditto.
+
2013-11-04 Ian Lance Taylor <iant@google.com>
* g++.dg/ext/sync-4.C: New test.
diff --git a/gcc/testsuite/c-c++-common/asan/stack-overflow-1.c b/gcc/testsuite/c-c++-common/asan/stack-overflow-1.c
index 5f56356..c717650 100644
--- a/gcc/testsuite/c-c++-common/asan/stack-overflow-1.c
+++ b/gcc/testsuite/c-c++-common/asan/stack-overflow-1.c
@@ -19,4 +19,5 @@ int main() {
/* { dg-output "READ of size 1 at 0x\[0-9a-f\]+ thread T0\[^\n\r]*(\n|\r\n|\r)" } */
/* { dg-output " #0 0x\[0-9a-f\]+ (in _*main (\[^\n\r]*stack-overflow-1.c:16|\[^\n\r]*:0)|\[(\]).*(\n|\r\n|\r)" } */
-/* { dg-output "\[^\n\r]*Address 0x\[0-9a-f\]+ is\[^\n\r]*frame <main>" } */
+/* { dg-output "\[^\n\r]*Address 0x\[0-9a-f\]+ is located in stack of thread T0.*(\n|\r\n|\r)" */
+/* { dg-output "\[^\n\r]*in main.*stack-overflow-1.c.*(\n|\r\n|\r)" */
diff --git a/gcc/testsuite/g++.dg/asan/asan_test.cc b/gcc/testsuite/g++.dg/asan/asan_test.cc
index 76b6e69..2df8c62 100644
--- a/gcc/testsuite/g++.dg/asan/asan_test.cc
+++ b/gcc/testsuite/g++.dg/asan/asan_test.cc
@@ -204,16 +204,6 @@ TEST(AddressSanitizer, BitFieldNegativeTest) {
delete Ident(x);
}
-TEST(AddressSanitizer, OutOfMemoryTest) {
- size_t size = SANITIZER_WORDSIZE == 64 ? (size_t)(1ULL << 48) : (0xf0000000);
- EXPECT_EQ(0, realloc(0, size));
- EXPECT_EQ(0, realloc(0, ~Ident(0)));
- EXPECT_EQ(0, malloc(size));
- EXPECT_EQ(0, malloc(~Ident(0)));
- EXPECT_EQ(0, calloc(1, size));
- EXPECT_EQ(0, calloc(1, ~Ident(0)));
-}
-
#if ASAN_NEEDS_SEGV
namespace {
@@ -497,42 +487,6 @@ TEST(AddressSanitizer, ManyStackObjectsTest) {
EXPECT_DEATH(Ident(ZZZ)[-1] = 0, ASAN_PCRE_DOTALL "XXX.*YYY.*ZZZ");
}
-NOINLINE static void Frame0(int frame, char *a, char *b, char *c) {
- char d[4] = {0};
- char *D = Ident(d);
- switch (frame) {
- case 3: a[5]++; break;
- case 2: b[5]++; break;
- case 1: c[5]++; break;
- case 0: D[5]++; break;
- }
-}
-NOINLINE static void Frame1(int frame, char *a, char *b) {
- char c[4] = {0}; Frame0(frame, a, b, c);
- break_optimization(0);
-}
-NOINLINE static void Frame2(int frame, char *a) {
- char b[4] = {0}; Frame1(frame, a, b);
- break_optimization(0);
-}
-NOINLINE static void Frame3(int frame) {
- char a[4] = {0}; Frame2(frame, a);
- break_optimization(0);
-}
-
-TEST(AddressSanitizer, GuiltyStackFrame0Test) {
- EXPECT_DEATH(Frame3(0), "located .*in frame <.*Frame0");
-}
-TEST(AddressSanitizer, GuiltyStackFrame1Test) {
- EXPECT_DEATH(Frame3(1), "located .*in frame <.*Frame1");
-}
-TEST(AddressSanitizer, GuiltyStackFrame2Test) {
- EXPECT_DEATH(Frame3(2), "located .*in frame <.*Frame2");
-}
-TEST(AddressSanitizer, GuiltyStackFrame3Test) {
- EXPECT_DEATH(Frame3(3), "located .*in frame <.*Frame3");
-}
-
NOINLINE void LongJmpFunc1(jmp_buf buf) {
// create three red zones for these two stack objects.
int a;