public inbox for gcc-patches@gcc.gnu.org
 help / color / mirror / Atom feed
* [PATCH][Kasan] Allow to override Asan shadow offset from command line
@ 2014-09-08 14:29 Yury Gribov
  2014-09-15  9:46 ` [PATCH][Kasan][PING] " Yury Gribov
  0 siblings, 1 reply; 18+ messages in thread
From: Yury Gribov @ 2014-09-08 14:29 UTC (permalink / raw)
  To: GCC Patches; +Cc: Konstantin Serebryany, Dmitry Vyukov, Andrey Ryabinin

[-- Attachment #1: Type: text/plain, Size: 246 bytes --]

Hi all,

Kasan developers has asked for an option to override offset of Asan 
shadow memory region. This should simplify experimenting with memory 
layouts on 64-bit architectures.

I've bootstrapped and regtested this on x64.

Ok to commit?

-Y

[-- Attachment #2: asan-shadow-offset-1.c --]
[-- Type: text/x-csrc, Size: 7068 bytes --]

commit 95d37bbfcb9f7e35c64f3b708b120d70f220e1d2
Author: Yury Gribov <y.gribov@samsung.com>
Date:   Fri Aug 29 11:58:03 2014 +0400

    Allow to override Asan shadow offset.
    
    2014-09-08  Yury Gribov  <y.gribov@samsung.com>
    
    gcc/
    	* asan.c (set_asan_shadow_offset): New function.
    	(asan_shadow_offset): Likewise.
    	(asan_emit_stack_protection): Call asan_shadow_offset.
    	(build_shadow_mem_access): Likewise.
    	* asan.h (set_asan_shadow_offset): Declare.
    	* common.opt (fasan-shadow-offset): New option.
    	* doc/invoke.texi (fasan-shadow-offset): Describe new option.
    	* opts-global.c (handle_common_deferred_options): Handle
    	-fasan-shadow-offset.
    	* opts.c (common_handle_option): Likewise.
    
    gcc/testsuite/
    	* c-c++-common/asan/shadow-offset-1.c: New test.

diff --git a/gcc/asan.c b/gcc/asan.c
index cf5de27..e6820ea 100644
--- a/gcc/asan.c
+++ b/gcc/asan.c
@@ -235,6 +235,39 @@ along with GCC; see the file COPYING3.  If not see
    A destructor function that calls the runtime asan library function
    _asan_unregister_globals is also installed.  */
 
+static unsigned HOST_WIDE_INT asan_shadow_offset_value;
+static bool asan_shadow_offset_computed;
+
+/* Sets shadow offset to value in string VAL.  */
+
+bool
+set_asan_shadow_offset (const char *val)
+{
+  char *endp;
+  
+  errno = 0;
+  asan_shadow_offset_value = strtoul (val, &endp, 0);
+  if (!(*val != '\0' && *endp == '\0' && errno == 0))
+    return false;
+
+  asan_shadow_offset_computed = true;
+
+  return true;
+}
+
+/* Returns Asan shadow offset.  */
+
+static unsigned HOST_WIDE_INT
+asan_shadow_offset ()
+{
+  if (!asan_shadow_offset_computed)
+    {
+      asan_shadow_offset_computed = true;
+      asan_shadow_offset_value = targetm.asan_shadow_offset ();
+    }
+  return asan_shadow_offset_value;
+}
+
 alias_set_type asan_shadow_set = -1;
 
 /* Pointer types to 1 resp. 2 byte integers in shadow memory.  A separate
@@ -1121,7 +1154,7 @@ asan_emit_stack_protection (rtx base, rtx pbase, unsigned int alignb,
 			      NULL_RTX, 1, OPTAB_DIRECT);
   shadow_base
     = plus_constant (Pmode, shadow_base,
-		     targetm.asan_shadow_offset ()
+		     asan_shadow_offset ()
 		     + (base_align_bias >> ASAN_SHADOW_SHIFT));
   gcc_assert (asan_shadow_set != -1
 	      && (ASAN_RED_ZONE_SIZE >> ASAN_SHADOW_SHIFT) == 4);
@@ -1499,7 +1532,7 @@ insert_if_then_before_iter (gimple cond,
 }
 
 /* Build
-   (base_addr >> ASAN_SHADOW_SHIFT) + targetm.asan_shadow_offset ().  */
+   (base_addr >> ASAN_SHADOW_SHIFT) + asan_shadow_offset ().  */
 
 static tree
 build_shadow_mem_access (gimple_stmt_iterator *gsi, location_t location,
@@ -1516,7 +1549,7 @@ build_shadow_mem_access (gimple_stmt_iterator *gsi, location_t location,
   gimple_set_location (g, location);
   gsi_insert_after (gsi, g, GSI_NEW_STMT);
 
-  t = build_int_cst (uintptr_type, targetm.asan_shadow_offset ());
+  t = build_int_cst (uintptr_type, asan_shadow_offset ());
   g = gimple_build_assign_with_ops (PLUS_EXPR,
 				    make_ssa_name (uintptr_type, NULL),
 				    gimple_assign_lhs (g), t);
diff --git a/gcc/asan.h b/gcc/asan.h
index 198433f..eadf029 100644
--- a/gcc/asan.h
+++ b/gcc/asan.h
@@ -36,7 +36,7 @@ extern gimple_stmt_iterator create_cond_insert_point
 extern alias_set_type asan_shadow_set;
 
 /* Shadow memory is found at
-   (address >> ASAN_SHADOW_SHIFT) + targetm.asan_shadow_offset ().  */
+   (address >> ASAN_SHADOW_SHIFT) + asan_shadow_offset ().  */
 #define ASAN_SHADOW_SHIFT	3
 
 /* Red zone size, stack and global variables are padded by ASAN_RED_ZONE_SIZE
@@ -76,4 +76,6 @@ asan_red_zone_size (unsigned int size)
   return c ? 2 * ASAN_RED_ZONE_SIZE - c : ASAN_RED_ZONE_SIZE;
 }
 
+extern bool set_asan_shadow_offset (const char *);
+
 #endif /* TREE_ASAN */
diff --git a/gcc/common.opt b/gcc/common.opt
index 7d78803..36c8310 100644
--- a/gcc/common.opt
+++ b/gcc/common.opt
@@ -879,6 +879,10 @@ fsanitize=
 Common Driver Report Joined
 Select what to sanitize
 
+fasan-shadow-offset=
+Common Joined RejectNegative Var(common_deferred_options) Defer
+-fasan-shadow-offset=<string>	Use custom shadow memory offset.
+
 fsanitize-recover
 Common Report Var(flag_sanitize_recover) Init(1)
 After diagnosing undefined behavior attempt to continue execution
diff --git a/gcc/doc/invoke.texi b/gcc/doc/invoke.texi
index 55e6d56..98e3eab 100644
--- a/gcc/doc/invoke.texi
+++ b/gcc/doc/invoke.texi
@@ -296,7 +296,7 @@ Objective-C and Objective-C++ Dialects}.
 @xref{Debugging Options,,Options for Debugging Your Program or GCC}.
 @gccoptlist{-d@var{letters}  -dumpspecs  -dumpmachine  -dumpversion @gol
 -fsanitize=@var{style} -fsanitize-recover @gol
--fsanitize-undefined-trap-on-error @gol
+-fasan-shadow-offset=@var{string} -fsanitize-undefined-trap-on-error @gol
 -fdbg-cnt-list -fdbg-cnt=@var{counter-value-list} @gol
 -fdisable-ipa-@var{pass_name} @gol
 -fdisable-rtl-@var{pass_name} @gol
@@ -5584,6 +5584,12 @@ While @option{-ftrapv} causes traps for signed overflows to be emitted,
 @option{-fsanitize=undefined} gives a diagnostic message.
 This currently works only for the C family of languages.
 
+@item -fasan-shadow-offset=@var{string}
+@opindex fasan-shadow-offset
+This option forces GCC to use custom shadow offset in AddressSanitizer checks.
+It is useful for experimenting with different shadow memory layouts in
+kernel AddressSanitizer.
+
 @item -fsanitize-recover
 @opindex fsanitize-recover
 By default @option{-fsanitize=undefined} sanitization (and its suboptions
diff --git a/gcc/opts-global.c b/gcc/opts-global.c
index 111884b..6ce8612 100644
--- a/gcc/opts-global.c
+++ b/gcc/opts-global.c
@@ -42,6 +42,7 @@ along with GCC; see the file COPYING3.  If not see
 #include "toplev.h"
 #include "tree-pass.h"
 #include "context.h"
+#include "asan.h"
 
 typedef const char *const_char_p; /* For DEF_VEC_P.  */
 
@@ -426,6 +427,11 @@ handle_common_deferred_options (void)
 	  stack_limit_rtx = gen_rtx_SYMBOL_REF (Pmode, ggc_strdup (opt->arg));
 	  break;
 
+	case OPT_fasan_shadow_offset_:
+	  if (!set_asan_shadow_offset (opt->arg))
+	     error ("unrecognized shadow offset %qs", opt->arg);
+	  break;
+
 	default:
 	  gcc_unreachable ();
 	}
diff --git a/gcc/opts.c b/gcc/opts.c
index 337e6cc..496c073 100644
--- a/gcc/opts.c
+++ b/gcc/opts.c
@@ -1566,6 +1566,10 @@ common_handle_option (struct gcc_options *opts,
 	break;
       }
 
+    case OPT_fasan_shadow_offset_:
+      /* Deferred.  */
+      break;
+
     case OPT_O:
     case OPT_Os:
     case OPT_Ofast:
diff --git a/gcc/testsuite/c-c++-common/asan/shadow-offset-1.c b/gcc/testsuite/c-c++-common/asan/shadow-offset-1.c
new file mode 100644
index 0000000..3b642bf
--- /dev/null
+++ b/gcc/testsuite/c-c++-common/asan/shadow-offset-1.c
@@ -0,0 +1,11 @@
+/* { dg-do compile } */
+/* { dg-options "-fasan-shadow-offset=12345 -fdump-tree-sanopt" } */
+/* { dg-skip-if "" { *-*-* } { "-flto" } { "" } } */
+ 
+int f (int *p)
+{
+  return *p;
+}
+
+/* { dg-final { scan-tree-dump "12345" "sanopt" }  } */
+/* { dg-final { cleanup-tree-dump "sanopt" } } */

^ permalink raw reply	[flat|nested] 18+ messages in thread

* [PATCH][Kasan][PING] Allow to override Asan shadow offset from command line
  2014-09-08 14:29 [PATCH][Kasan] Allow to override Asan shadow offset from command line Yury Gribov
@ 2014-09-15  9:46 ` Yury Gribov
  2014-09-18 11:01   ` Jakub Jelinek
  2014-09-29 17:21   ` [PATCHv3][Kasan][PING] " Yury Gribov
  0 siblings, 2 replies; 18+ messages in thread
From: Yury Gribov @ 2014-09-15  9:46 UTC (permalink / raw)
  To: GCC Patches; +Cc: Konstantin Serebryany, Dmitry Vyukov, Andrey Ryabinin

[-- Attachment #1: Type: text/plain, Size: 306 bytes --]

On 09/08/2014 06:29 PM, Yury Gribov wrote:
> Hi all,
>
> Kasan developers has asked for an option to override offset of Asan
> shadow memory region. This should simplify experimenting with memory
> layouts on 64-bit architectures.
>
> I've bootstrapped and regtested this on x64.
>
> Ok to commit?
>
> -Y


[-- Attachment #2: asan-shadow-offset-1.c --]
[-- Type: text/x-csrc, Size: 7068 bytes --]

commit 95d37bbfcb9f7e35c64f3b708b120d70f220e1d2
Author: Yury Gribov <y.gribov@samsung.com>
Date:   Fri Aug 29 11:58:03 2014 +0400

    Allow to override Asan shadow offset.
    
    2014-09-08  Yury Gribov  <y.gribov@samsung.com>
    
    gcc/
    	* asan.c (set_asan_shadow_offset): New function.
    	(asan_shadow_offset): Likewise.
    	(asan_emit_stack_protection): Call asan_shadow_offset.
    	(build_shadow_mem_access): Likewise.
    	* asan.h (set_asan_shadow_offset): Declare.
    	* common.opt (fasan-shadow-offset): New option.
    	* doc/invoke.texi (fasan-shadow-offset): Describe new option.
    	* opts-global.c (handle_common_deferred_options): Handle
    	-fasan-shadow-offset.
    	* opts.c (common_handle_option): Likewise.
    
    gcc/testsuite/
    	* c-c++-common/asan/shadow-offset-1.c: New test.

diff --git a/gcc/asan.c b/gcc/asan.c
index cf5de27..e6820ea 100644
--- a/gcc/asan.c
+++ b/gcc/asan.c
@@ -235,6 +235,39 @@ along with GCC; see the file COPYING3.  If not see
    A destructor function that calls the runtime asan library function
    _asan_unregister_globals is also installed.  */
 
+static unsigned HOST_WIDE_INT asan_shadow_offset_value;
+static bool asan_shadow_offset_computed;
+
+/* Sets shadow offset to value in string VAL.  */
+
+bool
+set_asan_shadow_offset (const char *val)
+{
+  char *endp;
+  
+  errno = 0;
+  asan_shadow_offset_value = strtoul (val, &endp, 0);
+  if (!(*val != '\0' && *endp == '\0' && errno == 0))
+    return false;
+
+  asan_shadow_offset_computed = true;
+
+  return true;
+}
+
+/* Returns Asan shadow offset.  */
+
+static unsigned HOST_WIDE_INT
+asan_shadow_offset ()
+{
+  if (!asan_shadow_offset_computed)
+    {
+      asan_shadow_offset_computed = true;
+      asan_shadow_offset_value = targetm.asan_shadow_offset ();
+    }
+  return asan_shadow_offset_value;
+}
+
 alias_set_type asan_shadow_set = -1;
 
 /* Pointer types to 1 resp. 2 byte integers in shadow memory.  A separate
@@ -1121,7 +1154,7 @@ asan_emit_stack_protection (rtx base, rtx pbase, unsigned int alignb,
 			      NULL_RTX, 1, OPTAB_DIRECT);
   shadow_base
     = plus_constant (Pmode, shadow_base,
-		     targetm.asan_shadow_offset ()
+		     asan_shadow_offset ()
 		     + (base_align_bias >> ASAN_SHADOW_SHIFT));
   gcc_assert (asan_shadow_set != -1
 	      && (ASAN_RED_ZONE_SIZE >> ASAN_SHADOW_SHIFT) == 4);
@@ -1499,7 +1532,7 @@ insert_if_then_before_iter (gimple cond,
 }
 
 /* Build
-   (base_addr >> ASAN_SHADOW_SHIFT) + targetm.asan_shadow_offset ().  */
+   (base_addr >> ASAN_SHADOW_SHIFT) + asan_shadow_offset ().  */
 
 static tree
 build_shadow_mem_access (gimple_stmt_iterator *gsi, location_t location,
@@ -1516,7 +1549,7 @@ build_shadow_mem_access (gimple_stmt_iterator *gsi, location_t location,
   gimple_set_location (g, location);
   gsi_insert_after (gsi, g, GSI_NEW_STMT);
 
-  t = build_int_cst (uintptr_type, targetm.asan_shadow_offset ());
+  t = build_int_cst (uintptr_type, asan_shadow_offset ());
   g = gimple_build_assign_with_ops (PLUS_EXPR,
 				    make_ssa_name (uintptr_type, NULL),
 				    gimple_assign_lhs (g), t);
diff --git a/gcc/asan.h b/gcc/asan.h
index 198433f..eadf029 100644
--- a/gcc/asan.h
+++ b/gcc/asan.h
@@ -36,7 +36,7 @@ extern gimple_stmt_iterator create_cond_insert_point
 extern alias_set_type asan_shadow_set;
 
 /* Shadow memory is found at
-   (address >> ASAN_SHADOW_SHIFT) + targetm.asan_shadow_offset ().  */
+   (address >> ASAN_SHADOW_SHIFT) + asan_shadow_offset ().  */
 #define ASAN_SHADOW_SHIFT	3
 
 /* Red zone size, stack and global variables are padded by ASAN_RED_ZONE_SIZE
@@ -76,4 +76,6 @@ asan_red_zone_size (unsigned int size)
   return c ? 2 * ASAN_RED_ZONE_SIZE - c : ASAN_RED_ZONE_SIZE;
 }
 
+extern bool set_asan_shadow_offset (const char *);
+
 #endif /* TREE_ASAN */
diff --git a/gcc/common.opt b/gcc/common.opt
index 7d78803..36c8310 100644
--- a/gcc/common.opt
+++ b/gcc/common.opt
@@ -879,6 +879,10 @@ fsanitize=
 Common Driver Report Joined
 Select what to sanitize
 
+fasan-shadow-offset=
+Common Joined RejectNegative Var(common_deferred_options) Defer
+-fasan-shadow-offset=<string>	Use custom shadow memory offset.
+
 fsanitize-recover
 Common Report Var(flag_sanitize_recover) Init(1)
 After diagnosing undefined behavior attempt to continue execution
diff --git a/gcc/doc/invoke.texi b/gcc/doc/invoke.texi
index 55e6d56..98e3eab 100644
--- a/gcc/doc/invoke.texi
+++ b/gcc/doc/invoke.texi
@@ -296,7 +296,7 @@ Objective-C and Objective-C++ Dialects}.
 @xref{Debugging Options,,Options for Debugging Your Program or GCC}.
 @gccoptlist{-d@var{letters}  -dumpspecs  -dumpmachine  -dumpversion @gol
 -fsanitize=@var{style} -fsanitize-recover @gol
--fsanitize-undefined-trap-on-error @gol
+-fasan-shadow-offset=@var{string} -fsanitize-undefined-trap-on-error @gol
 -fdbg-cnt-list -fdbg-cnt=@var{counter-value-list} @gol
 -fdisable-ipa-@var{pass_name} @gol
 -fdisable-rtl-@var{pass_name} @gol
@@ -5584,6 +5584,12 @@ While @option{-ftrapv} causes traps for signed overflows to be emitted,
 @option{-fsanitize=undefined} gives a diagnostic message.
 This currently works only for the C family of languages.
 
+@item -fasan-shadow-offset=@var{string}
+@opindex fasan-shadow-offset
+This option forces GCC to use custom shadow offset in AddressSanitizer checks.
+It is useful for experimenting with different shadow memory layouts in
+kernel AddressSanitizer.
+
 @item -fsanitize-recover
 @opindex fsanitize-recover
 By default @option{-fsanitize=undefined} sanitization (and its suboptions
diff --git a/gcc/opts-global.c b/gcc/opts-global.c
index 111884b..6ce8612 100644
--- a/gcc/opts-global.c
+++ b/gcc/opts-global.c
@@ -42,6 +42,7 @@ along with GCC; see the file COPYING3.  If not see
 #include "toplev.h"
 #include "tree-pass.h"
 #include "context.h"
+#include "asan.h"
 
 typedef const char *const_char_p; /* For DEF_VEC_P.  */
 
@@ -426,6 +427,11 @@ handle_common_deferred_options (void)
 	  stack_limit_rtx = gen_rtx_SYMBOL_REF (Pmode, ggc_strdup (opt->arg));
 	  break;
 
+	case OPT_fasan_shadow_offset_:
+	  if (!set_asan_shadow_offset (opt->arg))
+	     error ("unrecognized shadow offset %qs", opt->arg);
+	  break;
+
 	default:
 	  gcc_unreachable ();
 	}
diff --git a/gcc/opts.c b/gcc/opts.c
index 337e6cc..496c073 100644
--- a/gcc/opts.c
+++ b/gcc/opts.c
@@ -1566,6 +1566,10 @@ common_handle_option (struct gcc_options *opts,
 	break;
       }
 
+    case OPT_fasan_shadow_offset_:
+      /* Deferred.  */
+      break;
+
     case OPT_O:
     case OPT_Os:
     case OPT_Ofast:
diff --git a/gcc/testsuite/c-c++-common/asan/shadow-offset-1.c b/gcc/testsuite/c-c++-common/asan/shadow-offset-1.c
new file mode 100644
index 0000000..3b642bf
--- /dev/null
+++ b/gcc/testsuite/c-c++-common/asan/shadow-offset-1.c
@@ -0,0 +1,11 @@
+/* { dg-do compile } */
+/* { dg-options "-fasan-shadow-offset=12345 -fdump-tree-sanopt" } */
+/* { dg-skip-if "" { *-*-* } { "-flto" } { "" } } */
+ 
+int f (int *p)
+{
+  return *p;
+}
+
+/* { dg-final { scan-tree-dump "12345" "sanopt" }  } */
+/* { dg-final { cleanup-tree-dump "sanopt" } } */

^ permalink raw reply	[flat|nested] 18+ messages in thread

* Re: [PATCH][Kasan][PING] Allow to override Asan shadow offset from command line
  2014-09-15  9:46 ` [PATCH][Kasan][PING] " Yury Gribov
@ 2014-09-18 11:01   ` Jakub Jelinek
  2014-09-18 11:05     ` Yury Gribov
  2014-09-29 17:21   ` [PATCHv3][Kasan][PING] " Yury Gribov
  1 sibling, 1 reply; 18+ messages in thread
From: Jakub Jelinek @ 2014-09-18 11:01 UTC (permalink / raw)
  To: Yury Gribov
  Cc: GCC Patches, Konstantin Serebryany, Dmitry Vyukov, Andrey Ryabinin

On Mon, Sep 15, 2014 at 01:46:14PM +0400, Yury Gribov wrote:
> On 09/08/2014 06:29 PM, Yury Gribov wrote:
> >Kasan developers has asked for an option to override offset of Asan
> >shadow memory region. This should simplify experimenting with memory
> >layouts on 64-bit architectures.
> >
> >I've bootstrapped and regtested this on x64.
> >
> >Ok to commit?

I don't like it at all.  For the kernel-address perhaps it might make sense
as a param, but for userland, as it is an ABI changing option, I'm afraid
people would start to create objects/shared libraries/binaries with
ABI incompatible values.
So, if you need it for kernel, use a param that can be eventually dropped,
and limit it to kernel-address mode only.

	Jakub

^ permalink raw reply	[flat|nested] 18+ messages in thread

* Re: [PATCH][Kasan][PING] Allow to override Asan shadow offset from command line
  2014-09-18 11:01   ` Jakub Jelinek
@ 2014-09-18 11:05     ` Yury Gribov
  0 siblings, 0 replies; 18+ messages in thread
From: Yury Gribov @ 2014-09-18 11:05 UTC (permalink / raw)
  To: Jakub Jelinek
  Cc: GCC Patches, Konstantin Serebryany, Dmitry Vyukov, Andrey Ryabinin

On 09/18/2014 03:01 PM, Jakub Jelinek wrote:
> On Mon, Sep 15, 2014 at 01:46:14PM +0400, Yury Gribov wrote:
>> On 09/08/2014 06:29 PM, Yury Gribov wrote:
>>> Kasan developers has asked for an option to override offset of Asan
>>> shadow memory region. This should simplify experimenting with memory
>>> layouts on 64-bit architectures.
>>>
>>> I've bootstrapped and regtested this on x64.
>>>
>>> Ok to commit?
>
> I don't like it at all.  For the kernel-address perhaps it might make sense
> as a param, but for userland, as it is an ABI changing option, I'm afraid
> people would start to create objects/shared libraries/binaries with
> ABI incompatible values.
> So, if you need it for kernel, use a param that can be eventually dropped,
> and limit it to kernel-address mode only.

Problem with params is that they are ints so won't work for 64-bit 
platforms. How about aborting if -fasan-shadow-offset is supplied 
without -fsanitize=kernel-address?

-Y

^ permalink raw reply	[flat|nested] 18+ messages in thread

* [PATCHv3][Kasan][PING] Allow to override Asan shadow offset from command line
  2014-09-15  9:46 ` [PATCH][Kasan][PING] " Yury Gribov
  2014-09-18 11:01   ` Jakub Jelinek
@ 2014-09-29 17:21   ` Yury Gribov
  2014-10-06 11:06     ` [PATCHv3][Kasan][PING^2] " Yury Gribov
  2014-10-17  7:59     ` [PATCHv4][Kasan] " Yury Gribov
  1 sibling, 2 replies; 18+ messages in thread
From: Yury Gribov @ 2014-09-29 17:21 UTC (permalink / raw)
  To: GCC Patches; +Cc: Konstantin Serebryany, Dmitry Vyukov, Andrey Ryabinin

[-- Attachment #1: Type: text/plain, Size: 405 bytes --]

Hi all,

>> Kasan developers has asked for an option to override offset of Asan
>> shadow memory region. This should simplify experimenting with memory
>> layouts on 64-bit architectures.

New patch which checks that -fasan-shadow-offset is only enabled for 
-fsanitize=kernel-address. I (unfortunately) can't make this --param 
because this can be a 64-bit value.

Bootstrapped and regtested on x64.

-Y

[-- Attachment #2: asan-shadow-offset-3.diff --]
[-- Type: text/x-diff, Size: 7319 bytes --]

commit 05829f7922915b075c0f4275d3613947aa793a9c
Author: Yury Gribov <y.gribov@samsung.com>
Date:   Fri Aug 29 11:58:03 2014 +0400

    Allow to override Asan shadow offset.
    
    2014-09-26  Yury Gribov  <y.gribov@samsung.com>
    
    gcc/
    	* asan.c (set_asan_shadow_offset): New function.
    	(asan_shadow_offset): Likewise.
    	(asan_emit_stack_protection): Call asan_shadow_offset.
    	(build_shadow_mem_access): Likewise.
    	* asan.h (set_asan_shadow_offset): Declare.
    	* common.opt (fasan-shadow-offset): New option.
    	* doc/invoke.texi (fasan-shadow-offset): Describe new option.
    	* opts-global.c (handle_common_deferred_options): Handle
    	-fasan-shadow-offset.
    	* opts.c (common_handle_option): Likewise.
    
    gcc/testsuite/
    	* c-c++-common/asan/shadow-offset-1.c: New test.

diff --git a/gcc/asan.c b/gcc/asan.c
index f520eab..63f99f5 100644
--- a/gcc/asan.c
+++ b/gcc/asan.c
@@ -238,6 +238,39 @@ along with GCC; see the file COPYING3.  If not see
    A destructor function that calls the runtime asan library function
    _asan_unregister_globals is also installed.  */
 
+static unsigned HOST_WIDE_INT asan_shadow_offset_value;
+static bool asan_shadow_offset_computed;
+
+/* Sets shadow offset to value in string VAL.  */
+
+bool
+set_asan_shadow_offset (const char *val)
+{
+  char *endp;
+  
+  errno = 0;
+  asan_shadow_offset_value = strtoul (val, &endp, 0);
+  if (!(*val != '\0' && *endp == '\0' && errno == 0))
+    return false;
+
+  asan_shadow_offset_computed = true;
+
+  return true;
+}
+
+/* Returns Asan shadow offset.  */
+
+static unsigned HOST_WIDE_INT
+asan_shadow_offset ()
+{
+  if (!asan_shadow_offset_computed)
+    {
+      asan_shadow_offset_computed = true;
+      asan_shadow_offset_value = targetm.asan_shadow_offset ();
+    }
+  return asan_shadow_offset_value;
+}
+
 alias_set_type asan_shadow_set = -1;
 
 /* Pointer types to 1 resp. 2 byte integers in shadow memory.  A separate
@@ -1124,7 +1157,7 @@ asan_emit_stack_protection (rtx base, rtx pbase, unsigned int alignb,
 			      NULL_RTX, 1, OPTAB_DIRECT);
   shadow_base
     = plus_constant (Pmode, shadow_base,
-		     targetm.asan_shadow_offset ()
+		     asan_shadow_offset ()
 		     + (base_align_bias >> ASAN_SHADOW_SHIFT));
   gcc_assert (asan_shadow_set != -1
 	      && (ASAN_RED_ZONE_SIZE >> ASAN_SHADOW_SHIFT) == 4);
@@ -1502,7 +1535,7 @@ insert_if_then_before_iter (gimple cond,
 }
 
 /* Build
-   (base_addr >> ASAN_SHADOW_SHIFT) + targetm.asan_shadow_offset ().  */
+   (base_addr >> ASAN_SHADOW_SHIFT) + asan_shadow_offset ().  */
 
 static tree
 build_shadow_mem_access (gimple_stmt_iterator *gsi, location_t location,
@@ -1519,7 +1552,7 @@ build_shadow_mem_access (gimple_stmt_iterator *gsi, location_t location,
   gimple_set_location (g, location);
   gsi_insert_after (gsi, g, GSI_NEW_STMT);
 
-  t = build_int_cst (uintptr_type, targetm.asan_shadow_offset ());
+  t = build_int_cst (uintptr_type, asan_shadow_offset ());
   g = gimple_build_assign_with_ops (PLUS_EXPR,
 				    make_ssa_name (uintptr_type, NULL),
 				    gimple_assign_lhs (g), t);
diff --git a/gcc/asan.h b/gcc/asan.h
index 198433f..eadf029 100644
--- a/gcc/asan.h
+++ b/gcc/asan.h
@@ -36,7 +36,7 @@ extern gimple_stmt_iterator create_cond_insert_point
 extern alias_set_type asan_shadow_set;
 
 /* Shadow memory is found at
-   (address >> ASAN_SHADOW_SHIFT) + targetm.asan_shadow_offset ().  */
+   (address >> ASAN_SHADOW_SHIFT) + asan_shadow_offset ().  */
 #define ASAN_SHADOW_SHIFT	3
 
 /* Red zone size, stack and global variables are padded by ASAN_RED_ZONE_SIZE
@@ -76,4 +76,6 @@ asan_red_zone_size (unsigned int size)
   return c ? 2 * ASAN_RED_ZONE_SIZE - c : ASAN_RED_ZONE_SIZE;
 }
 
+extern bool set_asan_shadow_offset (const char *);
+
 #endif /* TREE_ASAN */
diff --git a/gcc/common.opt b/gcc/common.opt
index b4f0ed4..90f6bd4 100644
--- a/gcc/common.opt
+++ b/gcc/common.opt
@@ -879,6 +879,10 @@ fsanitize=
 Common Driver Report Joined
 Select what to sanitize
 
+fasan-shadow-offset=
+Common Joined RejectNegative Var(common_deferred_options) Defer
+-fasan-shadow-offset=<string>	Use custom shadow memory offset.
+
 fsanitize-recover
 Common Report Var(flag_sanitize_recover) Init(1)
 After diagnosing undefined behavior attempt to continue execution
diff --git a/gcc/doc/invoke.texi b/gcc/doc/invoke.texi
index f6c3b42..d9bd1f7 100644
--- a/gcc/doc/invoke.texi
+++ b/gcc/doc/invoke.texi
@@ -297,7 +297,7 @@ Objective-C and Objective-C++ Dialects}.
 @xref{Debugging Options,,Options for Debugging Your Program or GCC}.
 @gccoptlist{-d@var{letters}  -dumpspecs  -dumpmachine  -dumpversion @gol
 -fsanitize=@var{style} -fsanitize-recover @gol
--fsanitize-undefined-trap-on-error @gol
+-fasan-shadow-offset=@var{string} -fsanitize-undefined-trap-on-error @gol
 -fdbg-cnt-list -fdbg-cnt=@var{counter-value-list} @gol
 -fdisable-ipa-@var{pass_name} @gol
 -fdisable-rtl-@var{pass_name} @gol
@@ -5610,6 +5610,12 @@ While @option{-ftrapv} causes traps for signed overflows to be emitted,
 @option{-fsanitize=undefined} gives a diagnostic message.
 This currently works only for the C family of languages.
 
+@item -fasan-shadow-offset=@var{string}
+@opindex fasan-shadow-offset
+This option forces GCC to use custom shadow offset in AddressSanitizer checks.
+It is useful for experimenting with different shadow memory layouts in
+kernel AddressSanitizer.
+
 @item -fsanitize-recover
 @opindex fsanitize-recover
 By default @option{-fsanitize=undefined} sanitization (and its suboptions
diff --git a/gcc/opts-global.c b/gcc/opts-global.c
index 111884b..81c899c 100644
--- a/gcc/opts-global.c
+++ b/gcc/opts-global.c
@@ -42,6 +42,7 @@ along with GCC; see the file COPYING3.  If not see
 #include "toplev.h"
 #include "tree-pass.h"
 #include "context.h"
+#include "asan.h"
 
 typedef const char *const_char_p; /* For DEF_VEC_P.  */
 
@@ -426,6 +427,14 @@ handle_common_deferred_options (void)
 	  stack_limit_rtx = gen_rtx_SYMBOL_REF (Pmode, ggc_strdup (opt->arg));
 	  break;
 
+	case OPT_fasan_shadow_offset_:
+	  if (!(flag_sanitize & SANITIZE_KERNEL_ADDRESS))
+	    error ("-fasan-shadow-offset should only be used "
+		   "with -fsanitize=kernel-address");
+	  if (!set_asan_shadow_offset (opt->arg))
+	     error ("unrecognized shadow offset %qs", opt->arg);
+	  break;
+
 	default:
 	  gcc_unreachable ();
 	}
diff --git a/gcc/opts.c b/gcc/opts.c
index 0a49bc0..774a599 100644
--- a/gcc/opts.c
+++ b/gcc/opts.c
@@ -1572,6 +1572,10 @@ common_handle_option (struct gcc_options *opts,
 	break;
       }
 
+    case OPT_fasan_shadow_offset_:
+      /* Deferred.  */
+      break;
+
     case OPT_O:
     case OPT_Os:
     case OPT_Ofast:
diff --git a/gcc/testsuite/c-c++-common/asan/shadow-offset-1.c b/gcc/testsuite/c-c++-common/asan/shadow-offset-1.c
new file mode 100644
index 0000000..2ca0fd6
--- /dev/null
+++ b/gcc/testsuite/c-c++-common/asan/shadow-offset-1.c
@@ -0,0 +1,11 @@
+/* { dg-do compile } */
+/* { dg-options "-fno-sanitize=address -fsanitize=kernel-address --param asan-instrumentation-with-call-threshold=100 -fasan-shadow-offset=12345 -fdump-tree-sanopt" } */
+/* { dg-skip-if "" { *-*-* } { "-flto" } { "" } } */
+ 
+int f (int *p)
+{
+  return *p;
+}
+
+/* { dg-final { scan-tree-dump "12345" "sanopt" }  } */
+/* { dg-final { cleanup-tree-dump "sanopt" } } */

^ permalink raw reply	[flat|nested] 18+ messages in thread

* [PATCHv3][Kasan][PING^2] Allow to override Asan shadow offset from command line
  2014-09-29 17:21   ` [PATCHv3][Kasan][PING] " Yury Gribov
@ 2014-10-06 11:06     ` Yury Gribov
  2014-10-06 11:17       ` Yury Gribov
  2014-10-17  7:59     ` [PATCHv4][Kasan] " Yury Gribov
  1 sibling, 1 reply; 18+ messages in thread
From: Yury Gribov @ 2014-10-06 11:06 UTC (permalink / raw)
  To: GCC Patches; +Cc: Konstantin Serebryany, Dmitry Vyukov, Andrey Ryabinin

[-- Attachment #1: Type: text/plain, Size: 466 bytes --]

On 09/29/2014 09:21 PM, Yury Gribov wrote:
> Hi all,
>
>>> Kasan developers has asked for an option to override offset of Asan
>>> shadow memory region. This should simplify experimenting with memory
>>> layouts on 64-bit architectures.
>
> New patch which checks that -fasan-shadow-offset is only enabled for
> -fsanitize=kernel-address. I (unfortunately) can't make this --param
> because this can be a 64-bit value.
>
> Bootstrapped and regtested on x64.
>
> -Y


[-- Attachment #2: asan-shadow-offset-3.diff --]
[-- Type: text/x-patch, Size: 7319 bytes --]

commit 05829f7922915b075c0f4275d3613947aa793a9c
Author: Yury Gribov <y.gribov@samsung.com>
Date:   Fri Aug 29 11:58:03 2014 +0400

    Allow to override Asan shadow offset.
    
    2014-09-26  Yury Gribov  <y.gribov@samsung.com>
    
    gcc/
    	* asan.c (set_asan_shadow_offset): New function.
    	(asan_shadow_offset): Likewise.
    	(asan_emit_stack_protection): Call asan_shadow_offset.
    	(build_shadow_mem_access): Likewise.
    	* asan.h (set_asan_shadow_offset): Declare.
    	* common.opt (fasan-shadow-offset): New option.
    	* doc/invoke.texi (fasan-shadow-offset): Describe new option.
    	* opts-global.c (handle_common_deferred_options): Handle
    	-fasan-shadow-offset.
    	* opts.c (common_handle_option): Likewise.
    
    gcc/testsuite/
    	* c-c++-common/asan/shadow-offset-1.c: New test.

diff --git a/gcc/asan.c b/gcc/asan.c
index f520eab..63f99f5 100644
--- a/gcc/asan.c
+++ b/gcc/asan.c
@@ -238,6 +238,39 @@ along with GCC; see the file COPYING3.  If not see
    A destructor function that calls the runtime asan library function
    _asan_unregister_globals is also installed.  */
 
+static unsigned HOST_WIDE_INT asan_shadow_offset_value;
+static bool asan_shadow_offset_computed;
+
+/* Sets shadow offset to value in string VAL.  */
+
+bool
+set_asan_shadow_offset (const char *val)
+{
+  char *endp;
+  
+  errno = 0;
+  asan_shadow_offset_value = strtoul (val, &endp, 0);
+  if (!(*val != '\0' && *endp == '\0' && errno == 0))
+    return false;
+
+  asan_shadow_offset_computed = true;
+
+  return true;
+}
+
+/* Returns Asan shadow offset.  */
+
+static unsigned HOST_WIDE_INT
+asan_shadow_offset ()
+{
+  if (!asan_shadow_offset_computed)
+    {
+      asan_shadow_offset_computed = true;
+      asan_shadow_offset_value = targetm.asan_shadow_offset ();
+    }
+  return asan_shadow_offset_value;
+}
+
 alias_set_type asan_shadow_set = -1;
 
 /* Pointer types to 1 resp. 2 byte integers in shadow memory.  A separate
@@ -1124,7 +1157,7 @@ asan_emit_stack_protection (rtx base, rtx pbase, unsigned int alignb,
 			      NULL_RTX, 1, OPTAB_DIRECT);
   shadow_base
     = plus_constant (Pmode, shadow_base,
-		     targetm.asan_shadow_offset ()
+		     asan_shadow_offset ()
 		     + (base_align_bias >> ASAN_SHADOW_SHIFT));
   gcc_assert (asan_shadow_set != -1
 	      && (ASAN_RED_ZONE_SIZE >> ASAN_SHADOW_SHIFT) == 4);
@@ -1502,7 +1535,7 @@ insert_if_then_before_iter (gimple cond,
 }
 
 /* Build
-   (base_addr >> ASAN_SHADOW_SHIFT) + targetm.asan_shadow_offset ().  */
+   (base_addr >> ASAN_SHADOW_SHIFT) + asan_shadow_offset ().  */
 
 static tree
 build_shadow_mem_access (gimple_stmt_iterator *gsi, location_t location,
@@ -1519,7 +1552,7 @@ build_shadow_mem_access (gimple_stmt_iterator *gsi, location_t location,
   gimple_set_location (g, location);
   gsi_insert_after (gsi, g, GSI_NEW_STMT);
 
-  t = build_int_cst (uintptr_type, targetm.asan_shadow_offset ());
+  t = build_int_cst (uintptr_type, asan_shadow_offset ());
   g = gimple_build_assign_with_ops (PLUS_EXPR,
 				    make_ssa_name (uintptr_type, NULL),
 				    gimple_assign_lhs (g), t);
diff --git a/gcc/asan.h b/gcc/asan.h
index 198433f..eadf029 100644
--- a/gcc/asan.h
+++ b/gcc/asan.h
@@ -36,7 +36,7 @@ extern gimple_stmt_iterator create_cond_insert_point
 extern alias_set_type asan_shadow_set;
 
 /* Shadow memory is found at
-   (address >> ASAN_SHADOW_SHIFT) + targetm.asan_shadow_offset ().  */
+   (address >> ASAN_SHADOW_SHIFT) + asan_shadow_offset ().  */
 #define ASAN_SHADOW_SHIFT	3
 
 /* Red zone size, stack and global variables are padded by ASAN_RED_ZONE_SIZE
@@ -76,4 +76,6 @@ asan_red_zone_size (unsigned int size)
   return c ? 2 * ASAN_RED_ZONE_SIZE - c : ASAN_RED_ZONE_SIZE;
 }
 
+extern bool set_asan_shadow_offset (const char *);
+
 #endif /* TREE_ASAN */
diff --git a/gcc/common.opt b/gcc/common.opt
index b4f0ed4..90f6bd4 100644
--- a/gcc/common.opt
+++ b/gcc/common.opt
@@ -879,6 +879,10 @@ fsanitize=
 Common Driver Report Joined
 Select what to sanitize
 
+fasan-shadow-offset=
+Common Joined RejectNegative Var(common_deferred_options) Defer
+-fasan-shadow-offset=<string>	Use custom shadow memory offset.
+
 fsanitize-recover
 Common Report Var(flag_sanitize_recover) Init(1)
 After diagnosing undefined behavior attempt to continue execution
diff --git a/gcc/doc/invoke.texi b/gcc/doc/invoke.texi
index f6c3b42..d9bd1f7 100644
--- a/gcc/doc/invoke.texi
+++ b/gcc/doc/invoke.texi
@@ -297,7 +297,7 @@ Objective-C and Objective-C++ Dialects}.
 @xref{Debugging Options,,Options for Debugging Your Program or GCC}.
 @gccoptlist{-d@var{letters}  -dumpspecs  -dumpmachine  -dumpversion @gol
 -fsanitize=@var{style} -fsanitize-recover @gol
--fsanitize-undefined-trap-on-error @gol
+-fasan-shadow-offset=@var{string} -fsanitize-undefined-trap-on-error @gol
 -fdbg-cnt-list -fdbg-cnt=@var{counter-value-list} @gol
 -fdisable-ipa-@var{pass_name} @gol
 -fdisable-rtl-@var{pass_name} @gol
@@ -5610,6 +5610,12 @@ While @option{-ftrapv} causes traps for signed overflows to be emitted,
 @option{-fsanitize=undefined} gives a diagnostic message.
 This currently works only for the C family of languages.
 
+@item -fasan-shadow-offset=@var{string}
+@opindex fasan-shadow-offset
+This option forces GCC to use custom shadow offset in AddressSanitizer checks.
+It is useful for experimenting with different shadow memory layouts in
+kernel AddressSanitizer.
+
 @item -fsanitize-recover
 @opindex fsanitize-recover
 By default @option{-fsanitize=undefined} sanitization (and its suboptions
diff --git a/gcc/opts-global.c b/gcc/opts-global.c
index 111884b..81c899c 100644
--- a/gcc/opts-global.c
+++ b/gcc/opts-global.c
@@ -42,6 +42,7 @@ along with GCC; see the file COPYING3.  If not see
 #include "toplev.h"
 #include "tree-pass.h"
 #include "context.h"
+#include "asan.h"
 
 typedef const char *const_char_p; /* For DEF_VEC_P.  */
 
@@ -426,6 +427,14 @@ handle_common_deferred_options (void)
 	  stack_limit_rtx = gen_rtx_SYMBOL_REF (Pmode, ggc_strdup (opt->arg));
 	  break;
 
+	case OPT_fasan_shadow_offset_:
+	  if (!(flag_sanitize & SANITIZE_KERNEL_ADDRESS))
+	    error ("-fasan-shadow-offset should only be used "
+		   "with -fsanitize=kernel-address");
+	  if (!set_asan_shadow_offset (opt->arg))
+	     error ("unrecognized shadow offset %qs", opt->arg);
+	  break;
+
 	default:
 	  gcc_unreachable ();
 	}
diff --git a/gcc/opts.c b/gcc/opts.c
index 0a49bc0..774a599 100644
--- a/gcc/opts.c
+++ b/gcc/opts.c
@@ -1572,6 +1572,10 @@ common_handle_option (struct gcc_options *opts,
 	break;
       }
 
+    case OPT_fasan_shadow_offset_:
+      /* Deferred.  */
+      break;
+
     case OPT_O:
     case OPT_Os:
     case OPT_Ofast:
diff --git a/gcc/testsuite/c-c++-common/asan/shadow-offset-1.c b/gcc/testsuite/c-c++-common/asan/shadow-offset-1.c
new file mode 100644
index 0000000..2ca0fd6
--- /dev/null
+++ b/gcc/testsuite/c-c++-common/asan/shadow-offset-1.c
@@ -0,0 +1,11 @@
+/* { dg-do compile } */
+/* { dg-options "-fno-sanitize=address -fsanitize=kernel-address --param asan-instrumentation-with-call-threshold=100 -fasan-shadow-offset=12345 -fdump-tree-sanopt" } */
+/* { dg-skip-if "" { *-*-* } { "-flto" } { "" } } */
+ 
+int f (int *p)
+{
+  return *p;
+}
+
+/* { dg-final { scan-tree-dump "12345" "sanopt" }  } */
+/* { dg-final { cleanup-tree-dump "sanopt" } } */

^ permalink raw reply	[flat|nested] 18+ messages in thread

* Re: [PATCHv3][Kasan][PING^2] Allow to override Asan shadow offset from command line
  2014-10-06 11:06     ` [PATCHv3][Kasan][PING^2] " Yury Gribov
@ 2014-10-06 11:17       ` Yury Gribov
  2014-10-15 16:19         ` [PATCHv3][Kasan][PING^3] " Yury Gribov
  0 siblings, 1 reply; 18+ messages in thread
From: Yury Gribov @ 2014-10-06 11:17 UTC (permalink / raw)
  To: GCC Patches
  Cc: Konstantin Serebryany, Dmitry Vyukov, Andrey Ryabinin, Jakub Jelinek

On 10/06/2014 03:06 PM, Yury Gribov wrote:
> On 09/29/2014 09:21 PM, Yury Gribov wrote:
>> Hi all,
>>
>>>> Kasan developers has asked for an option to override offset of Asan
>>>> shadow memory region. This should simplify experimenting with memory
>>>> layouts on 64-bit architectures.
>>
>> New patch which checks that -fasan-shadow-offset is only enabled for
>> -fsanitize=kernel-address. I (unfortunately) can't make this --param
>> because this can be a 64-bit value.
>>
>> Bootstrapped and regtested on x64.
>>
>> -Y

Added Jakub.

^ permalink raw reply	[flat|nested] 18+ messages in thread

* [PATCHv3][Kasan][PING^3] Allow to override Asan shadow offset from command line
  2014-10-06 11:17       ` Yury Gribov
@ 2014-10-15 16:19         ` Yury Gribov
  2014-10-15 16:54           ` Jakub Jelinek
  0 siblings, 1 reply; 18+ messages in thread
From: Yury Gribov @ 2014-10-15 16:19 UTC (permalink / raw)
  To: GCC Patches
  Cc: Konstantin Serebryany, Dmitry Vyukov, Andrey Ryabinin, Jakub Jelinek

[-- Attachment #1: Type: text/plain, Size: 604 bytes --]

On 10/06/2014 03:17 PM, Yury Gribov wrote:
> On 10/06/2014 03:06 PM, Yury Gribov wrote:
>> On 09/29/2014 09:21 PM, Yury Gribov wrote:
>>> Hi all,
>>>
>>>>> Kasan developers has asked for an option to override offset of Asan
>>>>> shadow memory region. This should simplify experimenting with memory
>>>>> layouts on 64-bit architectures.
>>>
>>> New patch which checks that -fasan-shadow-offset is only enabled for
>>> -fsanitize=kernel-address. I (unfortunately) can't make this --param
>>> because this can be a 64-bit value.
>>>
>>> Bootstrapped and regtested on x64.
>>>
>>> -Y
>
> Added Jakub.
>
>


[-- Attachment #2: asan-shadow-offset-3.diff --]
[-- Type: text/x-patch, Size: 7319 bytes --]

commit 05829f7922915b075c0f4275d3613947aa793a9c
Author: Yury Gribov <y.gribov@samsung.com>
Date:   Fri Aug 29 11:58:03 2014 +0400

    Allow to override Asan shadow offset.
    
    2014-09-26  Yury Gribov  <y.gribov@samsung.com>
    
    gcc/
    	* asan.c (set_asan_shadow_offset): New function.
    	(asan_shadow_offset): Likewise.
    	(asan_emit_stack_protection): Call asan_shadow_offset.
    	(build_shadow_mem_access): Likewise.
    	* asan.h (set_asan_shadow_offset): Declare.
    	* common.opt (fasan-shadow-offset): New option.
    	* doc/invoke.texi (fasan-shadow-offset): Describe new option.
    	* opts-global.c (handle_common_deferred_options): Handle
    	-fasan-shadow-offset.
    	* opts.c (common_handle_option): Likewise.
    
    gcc/testsuite/
    	* c-c++-common/asan/shadow-offset-1.c: New test.

diff --git a/gcc/asan.c b/gcc/asan.c
index f520eab..63f99f5 100644
--- a/gcc/asan.c
+++ b/gcc/asan.c
@@ -238,6 +238,39 @@ along with GCC; see the file COPYING3.  If not see
    A destructor function that calls the runtime asan library function
    _asan_unregister_globals is also installed.  */
 
+static unsigned HOST_WIDE_INT asan_shadow_offset_value;
+static bool asan_shadow_offset_computed;
+
+/* Sets shadow offset to value in string VAL.  */
+
+bool
+set_asan_shadow_offset (const char *val)
+{
+  char *endp;
+  
+  errno = 0;
+  asan_shadow_offset_value = strtoul (val, &endp, 0);
+  if (!(*val != '\0' && *endp == '\0' && errno == 0))
+    return false;
+
+  asan_shadow_offset_computed = true;
+
+  return true;
+}
+
+/* Returns Asan shadow offset.  */
+
+static unsigned HOST_WIDE_INT
+asan_shadow_offset ()
+{
+  if (!asan_shadow_offset_computed)
+    {
+      asan_shadow_offset_computed = true;
+      asan_shadow_offset_value = targetm.asan_shadow_offset ();
+    }
+  return asan_shadow_offset_value;
+}
+
 alias_set_type asan_shadow_set = -1;
 
 /* Pointer types to 1 resp. 2 byte integers in shadow memory.  A separate
@@ -1124,7 +1157,7 @@ asan_emit_stack_protection (rtx base, rtx pbase, unsigned int alignb,
 			      NULL_RTX, 1, OPTAB_DIRECT);
   shadow_base
     = plus_constant (Pmode, shadow_base,
-		     targetm.asan_shadow_offset ()
+		     asan_shadow_offset ()
 		     + (base_align_bias >> ASAN_SHADOW_SHIFT));
   gcc_assert (asan_shadow_set != -1
 	      && (ASAN_RED_ZONE_SIZE >> ASAN_SHADOW_SHIFT) == 4);
@@ -1502,7 +1535,7 @@ insert_if_then_before_iter (gimple cond,
 }
 
 /* Build
-   (base_addr >> ASAN_SHADOW_SHIFT) + targetm.asan_shadow_offset ().  */
+   (base_addr >> ASAN_SHADOW_SHIFT) + asan_shadow_offset ().  */
 
 static tree
 build_shadow_mem_access (gimple_stmt_iterator *gsi, location_t location,
@@ -1519,7 +1552,7 @@ build_shadow_mem_access (gimple_stmt_iterator *gsi, location_t location,
   gimple_set_location (g, location);
   gsi_insert_after (gsi, g, GSI_NEW_STMT);
 
-  t = build_int_cst (uintptr_type, targetm.asan_shadow_offset ());
+  t = build_int_cst (uintptr_type, asan_shadow_offset ());
   g = gimple_build_assign_with_ops (PLUS_EXPR,
 				    make_ssa_name (uintptr_type, NULL),
 				    gimple_assign_lhs (g), t);
diff --git a/gcc/asan.h b/gcc/asan.h
index 198433f..eadf029 100644
--- a/gcc/asan.h
+++ b/gcc/asan.h
@@ -36,7 +36,7 @@ extern gimple_stmt_iterator create_cond_insert_point
 extern alias_set_type asan_shadow_set;
 
 /* Shadow memory is found at
-   (address >> ASAN_SHADOW_SHIFT) + targetm.asan_shadow_offset ().  */
+   (address >> ASAN_SHADOW_SHIFT) + asan_shadow_offset ().  */
 #define ASAN_SHADOW_SHIFT	3
 
 /* Red zone size, stack and global variables are padded by ASAN_RED_ZONE_SIZE
@@ -76,4 +76,6 @@ asan_red_zone_size (unsigned int size)
   return c ? 2 * ASAN_RED_ZONE_SIZE - c : ASAN_RED_ZONE_SIZE;
 }
 
+extern bool set_asan_shadow_offset (const char *);
+
 #endif /* TREE_ASAN */
diff --git a/gcc/common.opt b/gcc/common.opt
index b4f0ed4..90f6bd4 100644
--- a/gcc/common.opt
+++ b/gcc/common.opt
@@ -879,6 +879,10 @@ fsanitize=
 Common Driver Report Joined
 Select what to sanitize
 
+fasan-shadow-offset=
+Common Joined RejectNegative Var(common_deferred_options) Defer
+-fasan-shadow-offset=<string>	Use custom shadow memory offset.
+
 fsanitize-recover
 Common Report Var(flag_sanitize_recover) Init(1)
 After diagnosing undefined behavior attempt to continue execution
diff --git a/gcc/doc/invoke.texi b/gcc/doc/invoke.texi
index f6c3b42..d9bd1f7 100644
--- a/gcc/doc/invoke.texi
+++ b/gcc/doc/invoke.texi
@@ -297,7 +297,7 @@ Objective-C and Objective-C++ Dialects}.
 @xref{Debugging Options,,Options for Debugging Your Program or GCC}.
 @gccoptlist{-d@var{letters}  -dumpspecs  -dumpmachine  -dumpversion @gol
 -fsanitize=@var{style} -fsanitize-recover @gol
--fsanitize-undefined-trap-on-error @gol
+-fasan-shadow-offset=@var{string} -fsanitize-undefined-trap-on-error @gol
 -fdbg-cnt-list -fdbg-cnt=@var{counter-value-list} @gol
 -fdisable-ipa-@var{pass_name} @gol
 -fdisable-rtl-@var{pass_name} @gol
@@ -5610,6 +5610,12 @@ While @option{-ftrapv} causes traps for signed overflows to be emitted,
 @option{-fsanitize=undefined} gives a diagnostic message.
 This currently works only for the C family of languages.
 
+@item -fasan-shadow-offset=@var{string}
+@opindex fasan-shadow-offset
+This option forces GCC to use custom shadow offset in AddressSanitizer checks.
+It is useful for experimenting with different shadow memory layouts in
+kernel AddressSanitizer.
+
 @item -fsanitize-recover
 @opindex fsanitize-recover
 By default @option{-fsanitize=undefined} sanitization (and its suboptions
diff --git a/gcc/opts-global.c b/gcc/opts-global.c
index 111884b..81c899c 100644
--- a/gcc/opts-global.c
+++ b/gcc/opts-global.c
@@ -42,6 +42,7 @@ along with GCC; see the file COPYING3.  If not see
 #include "toplev.h"
 #include "tree-pass.h"
 #include "context.h"
+#include "asan.h"
 
 typedef const char *const_char_p; /* For DEF_VEC_P.  */
 
@@ -426,6 +427,14 @@ handle_common_deferred_options (void)
 	  stack_limit_rtx = gen_rtx_SYMBOL_REF (Pmode, ggc_strdup (opt->arg));
 	  break;
 
+	case OPT_fasan_shadow_offset_:
+	  if (!(flag_sanitize & SANITIZE_KERNEL_ADDRESS))
+	    error ("-fasan-shadow-offset should only be used "
+		   "with -fsanitize=kernel-address");
+	  if (!set_asan_shadow_offset (opt->arg))
+	     error ("unrecognized shadow offset %qs", opt->arg);
+	  break;
+
 	default:
 	  gcc_unreachable ();
 	}
diff --git a/gcc/opts.c b/gcc/opts.c
index 0a49bc0..774a599 100644
--- a/gcc/opts.c
+++ b/gcc/opts.c
@@ -1572,6 +1572,10 @@ common_handle_option (struct gcc_options *opts,
 	break;
       }
 
+    case OPT_fasan_shadow_offset_:
+      /* Deferred.  */
+      break;
+
     case OPT_O:
     case OPT_Os:
     case OPT_Ofast:
diff --git a/gcc/testsuite/c-c++-common/asan/shadow-offset-1.c b/gcc/testsuite/c-c++-common/asan/shadow-offset-1.c
new file mode 100644
index 0000000..2ca0fd6
--- /dev/null
+++ b/gcc/testsuite/c-c++-common/asan/shadow-offset-1.c
@@ -0,0 +1,11 @@
+/* { dg-do compile } */
+/* { dg-options "-fno-sanitize=address -fsanitize=kernel-address --param asan-instrumentation-with-call-threshold=100 -fasan-shadow-offset=12345 -fdump-tree-sanopt" } */
+/* { dg-skip-if "" { *-*-* } { "-flto" } { "" } } */
+ 
+int f (int *p)
+{
+  return *p;
+}
+
+/* { dg-final { scan-tree-dump "12345" "sanopt" }  } */
+/* { dg-final { cleanup-tree-dump "sanopt" } } */

^ permalink raw reply	[flat|nested] 18+ messages in thread

* Re: [PATCHv3][Kasan][PING^3] Allow to override Asan shadow offset from command line
  2014-10-15 16:19         ` [PATCHv3][Kasan][PING^3] " Yury Gribov
@ 2014-10-15 16:54           ` Jakub Jelinek
  0 siblings, 0 replies; 18+ messages in thread
From: Jakub Jelinek @ 2014-10-15 16:54 UTC (permalink / raw)
  To: Yury Gribov
  Cc: GCC Patches, Konstantin Serebryany, Dmitry Vyukov, Andrey Ryabinin

On Wed, Oct 15, 2014 at 08:17:39PM +0400, Yury Gribov wrote:
> +static unsigned HOST_WIDE_INT asan_shadow_offset_value;
> +static bool asan_shadow_offset_computed;
> +
> +/* Sets shadow offset to value in string VAL.  */
> +
> +bool
> +set_asan_shadow_offset (const char *val)
> +{
> +  char *endp;
> +  
> +  errno = 0;
> +  asan_shadow_offset_value = strtoul (val, &endp, 0);

This will not really work well e.g. for 32-bit cross-compilers
to 64-bit.
I'm afraid you need to use strtoull here, libiberty has strtoul.c
already, perhaps just copying that to strtoull.c and adjusting types
etc. (and guarding it whole with HAVE_LONG_LONG)?
Then just use strtoull here if either HAVE_LONG_LONG instead
of strtoul.

	Jakub

^ permalink raw reply	[flat|nested] 18+ messages in thread

* [PATCHv4][Kasan] Allow to override Asan shadow offset from command line
  2014-09-29 17:21   ` [PATCHv3][Kasan][PING] " Yury Gribov
  2014-10-06 11:06     ` [PATCHv3][Kasan][PING^2] " Yury Gribov
@ 2014-10-17  7:59     ` Yury Gribov
  2014-10-17 11:25       ` Jakub Jelinek
  2014-10-24 13:58       ` [PATCHv5][Kasan] " Yury Gribov
  1 sibling, 2 replies; 18+ messages in thread
From: Yury Gribov @ 2014-10-17  7:59 UTC (permalink / raw)
  To: GCC Patches; +Cc: Konstantin Serebryany, Dmitry Vyukov, Andrey Ryabinin

[-- Attachment #1: Type: text/plain, Size: 701 bytes --]

Hi all,

On 09/29/2014 09:21 PM, Yury Gribov wrote:
>>> Kasan developers has asked for an option to override offset of Asan
>>> shadow memory region. This should simplify experimenting with memory
>>> layouts on 64-bit architectures.
>
> New patch which checks that -fasan-shadow-offset is only enabled for
> -fsanitize=kernel-address. I (unfortunately) can't make this --param
> because this can be a 64-bit value.
>
> Bootstrapped and regtested on x64.

New patchset that adds strtoull to libiberty (blind copy-paste of 
already existing strtoul.c) and uses it to parse -fasan-shadow-offset 
(to avoid problem with compiling for 64-bit target a 32-bit host).

Bootstrapped and regtested on x64.

-Y

[-- Attachment #2: 0001-Add-strtoull-to-libiberty.patch --]
[-- Type: text/x-patch, Size: 4174 bytes --]

From 0225b7878bbb5b803814646d089824d016316fef Mon Sep 17 00:00:00 2001
From: Yury Gribov <y.gribov@samsung.com>
Date: Thu, 16 Oct 2014 18:31:10 +0400
Subject: [PATCH 1/2] Add strtoull to libiberty.

2014-10-17  Yury Gribov  <y.gribov@samsung.com>

libiberty/
	* strtoull.c: New file.
---
 libiberty/strtoull.c |  119 ++++++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 119 insertions(+)
 create mode 100644 libiberty/strtoull.c

diff --git a/libiberty/strtoull.c b/libiberty/strtoull.c
new file mode 100644
index 0000000..c92a4a3
--- /dev/null
+++ b/libiberty/strtoull.c
@@ -0,0 +1,119 @@
+/*
+ * Copyright (c) 2014 Regents of the University of California.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. [rescinded 22 July 1999]
+ * 4. Neither the name of the University nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+#ifdef HAVE_LIMITS_H
+#include <limits.h>
+#endif
+#ifdef HAVE_SYS_PARAM_H
+#include <sys/param.h>
+#endif
+#include <errno.h>
+#ifdef NEED_DECLARATION_ERRNO
+extern int errno;
+#endif
+#if 0
+#include <stdlib.h>
+#endif
+#include "ansidecl.h"
+#include "safe-ctype.h"
+
+#ifdef HAVE_LONG_LONG
+
+#ifndef ULLONG_MAX
+#define ULLONG_MAX ((unsigned long long)(~0L)) /* 0xFFFFFFFFFFFFFFFF */
+#endif
+
+/*
+ * Convert a string to an unsigned long long integer.
+ *
+ * Ignores `locale' stuff.  Assumes that the upper and lower case
+ * alphabets and digits are each contiguous.
+ */
+unsigned long long
+strtoull(const char *nptr, char **endptr, register int base)
+{
+	register const char *s = nptr;
+	register unsigned long long acc;
+	register int c;
+	register unsigned long long cutoff;
+	register int neg = 0, any, cutlim;
+
+	/*
+	 * See strtol for comments as to the logic used.
+	 */
+	do {
+		c = *s++;
+	} while (ISSPACE(c));
+	if (c == '-') {
+		neg = 1;
+		c = *s++;
+	} else if (c == '+')
+		c = *s++;
+	if ((base == 0 || base == 16) &&
+	    c == '0' && (*s == 'x' || *s == 'X')) {
+		c = s[1];
+		s += 2;
+		base = 16;
+	}
+	if (base == 0)
+		base = c == '0' ? 8 : 10;
+	cutoff = (unsigned long long)ULLONG_MAX / (unsigned long long)base;
+	cutlim = (unsigned long long)ULLONG_MAX % (unsigned long long)base;
+	for (acc = 0, any = 0;; c = *s++) {
+		if (ISDIGIT(c))
+			c -= '0';
+		else if (ISALPHA(c))
+			c -= ISUPPER(c) ? 'A' - 10 : 'a' - 10;
+		else
+			break;
+		if (c >= base)
+			break;
+		if (any < 0 || acc > cutoff || (acc == cutoff && c > cutlim))
+			any = -1;
+		else {
+			any = 1;
+			acc *= base;
+			acc += c;
+		}
+	}
+	if (any < 0) {
+		acc = ULLONG_MAX;
+		errno = ERANGE;
+	} else if (neg)
+		acc = -acc;
+	if (endptr != 0)
+		*endptr = (char *) (any ? s - 1 : nptr);
+	return (acc);
+}
+
+#endif /* ifdef HAVE_LONG_LONG */
-- 
1.7.9.5


[-- Attachment #3: 0002-Allow-to-override-Asan-shadow-offset.patch --]
[-- Type: text/x-patch, Size: 7974 bytes --]

From 6c9ad20bdcfc0fbf7ccb8e2700ef7dce52a34c64 Mon Sep 17 00:00:00 2001
From: Yury Gribov <y.gribov@samsung.com>
Date: Fri, 29 Aug 2014 11:58:03 +0400
Subject: [PATCH 2/2] Allow to override Asan shadow offset.

2014-10-17  Yury Gribov  <y.gribov@samsung.com>

gcc/
	* asan.c (set_asan_shadow_offset): New function.
	(asan_shadow_offset): Likewise.
	(asan_emit_stack_protection): Call asan_shadow_offset.
	(build_shadow_mem_access): Likewise.
	* asan.h (set_asan_shadow_offset): Declare.
	* common.opt (fasan-shadow-offset): New option.
	* doc/invoke.texi (fasan-shadow-offset): Describe new option.
	* opts-global.c (handle_common_deferred_options): Handle
	-fasan-shadow-offset.
	* opts.c (common_handle_option): Likewise.

gcc/testsuite/
	* c-c++-common/asan/shadow-offset-1.c: New test.
---
 gcc/asan.c                                        |   43 +++++++++++++++++++--
 gcc/asan.h                                        |    4 +-
 gcc/common.opt                                    |    4 ++
 gcc/doc/invoke.texi                               |    8 +++-
 gcc/opts-global.c                                 |    9 +++++
 gcc/opts.c                                        |    4 ++
 gcc/testsuite/c-c++-common/asan/shadow-offset-1.c |   11 ++++++
 7 files changed, 78 insertions(+), 5 deletions(-)
 create mode 100644 gcc/testsuite/c-c++-common/asan/shadow-offset-1.c

diff --git a/gcc/asan.c b/gcc/asan.c
index 2a61a82..8bd4db9 100644
--- a/gcc/asan.c
+++ b/gcc/asan.c
@@ -238,6 +238,43 @@ along with GCC; see the file COPYING3.  If not see
    A destructor function that calls the runtime asan library function
    _asan_unregister_globals is also installed.  */
 
+static unsigned HOST_WIDE_INT asan_shadow_offset_value;
+static bool asan_shadow_offset_computed;
+
+/* Sets shadow offset to value in string VAL.  */
+
+bool
+set_asan_shadow_offset (const char *val)
+{
+  char *endp;
+  
+  errno = 0;
+#ifdef HAVE_LONG_LONG
+  asan_shadow_offset_value = strtoull (val, &endp, 0);
+#else
+  asan_shadow_offset_value = strtoul (val, &endp, 0);
+#endif
+  if (!(*val != '\0' && *endp == '\0' && errno == 0))
+    return false;
+
+  asan_shadow_offset_computed = true;
+
+  return true;
+}
+
+/* Returns Asan shadow offset.  */
+
+static unsigned HOST_WIDE_INT
+asan_shadow_offset ()
+{
+  if (!asan_shadow_offset_computed)
+    {
+      asan_shadow_offset_computed = true;
+      asan_shadow_offset_value = targetm.asan_shadow_offset ();
+    }
+  return asan_shadow_offset_value;
+}
+
 alias_set_type asan_shadow_set = -1;
 
 /* Pointer types to 1 resp. 2 byte integers in shadow memory.  A separate
@@ -1124,7 +1161,7 @@ asan_emit_stack_protection (rtx base, rtx pbase, unsigned int alignb,
 			      NULL_RTX, 1, OPTAB_DIRECT);
   shadow_base
     = plus_constant (Pmode, shadow_base,
-		     targetm.asan_shadow_offset ()
+		     asan_shadow_offset ()
 		     + (base_align_bias >> ASAN_SHADOW_SHIFT));
   gcc_assert (asan_shadow_set != -1
 	      && (ASAN_RED_ZONE_SIZE >> ASAN_SHADOW_SHIFT) == 4);
@@ -1503,7 +1540,7 @@ insert_if_then_before_iter (gimple cond,
 }
 
 /* Build
-   (base_addr >> ASAN_SHADOW_SHIFT) + targetm.asan_shadow_offset ().  */
+   (base_addr >> ASAN_SHADOW_SHIFT) + asan_shadow_offset ().  */
 
 static tree
 build_shadow_mem_access (gimple_stmt_iterator *gsi, location_t location,
@@ -1520,7 +1557,7 @@ build_shadow_mem_access (gimple_stmt_iterator *gsi, location_t location,
   gimple_set_location (g, location);
   gsi_insert_after (gsi, g, GSI_NEW_STMT);
 
-  t = build_int_cst (uintptr_type, targetm.asan_shadow_offset ());
+  t = build_int_cst (uintptr_type, asan_shadow_offset ());
   g = gimple_build_assign_with_ops (PLUS_EXPR,
 				    make_ssa_name (uintptr_type, NULL),
 				    gimple_assign_lhs (g), t);
diff --git a/gcc/asan.h b/gcc/asan.h
index 198433f..eadf029 100644
--- a/gcc/asan.h
+++ b/gcc/asan.h
@@ -36,7 +36,7 @@ extern gimple_stmt_iterator create_cond_insert_point
 extern alias_set_type asan_shadow_set;
 
 /* Shadow memory is found at
-   (address >> ASAN_SHADOW_SHIFT) + targetm.asan_shadow_offset ().  */
+   (address >> ASAN_SHADOW_SHIFT) + asan_shadow_offset ().  */
 #define ASAN_SHADOW_SHIFT	3
 
 /* Red zone size, stack and global variables are padded by ASAN_RED_ZONE_SIZE
@@ -76,4 +76,6 @@ asan_red_zone_size (unsigned int size)
   return c ? 2 * ASAN_RED_ZONE_SIZE - c : ASAN_RED_ZONE_SIZE;
 }
 
+extern bool set_asan_shadow_offset (const char *);
+
 #endif /* TREE_ASAN */
diff --git a/gcc/common.opt b/gcc/common.opt
index 5db5e1e..5492d0d 100644
--- a/gcc/common.opt
+++ b/gcc/common.opt
@@ -879,6 +879,10 @@ fsanitize=
 Common Driver Report Joined
 Select what to sanitize
 
+fasan-shadow-offset=
+Common Joined RejectNegative Var(common_deferred_options) Defer
+-fasan-shadow-offset=<string>	Use custom shadow memory offset.
+
 fsanitize-recover
 Common Report Var(flag_sanitize_recover) Init(1)
 After diagnosing undefined behavior attempt to continue execution
diff --git a/gcc/doc/invoke.texi b/gcc/doc/invoke.texi
index 6bc09d6..3b53dfa 100644
--- a/gcc/doc/invoke.texi
+++ b/gcc/doc/invoke.texi
@@ -297,7 +297,7 @@ Objective-C and Objective-C++ Dialects}.
 @xref{Debugging Options,,Options for Debugging Your Program or GCC}.
 @gccoptlist{-d@var{letters}  -dumpspecs  -dumpmachine  -dumpversion @gol
 -fsanitize=@var{style} -fsanitize-recover @gol
--fsanitize-undefined-trap-on-error @gol
+-fasan-shadow-offset=@var{string} -fsanitize-undefined-trap-on-error @gol
 -fdbg-cnt-list -fdbg-cnt=@var{counter-value-list} @gol
 -fdisable-ipa-@var{pass_name} @gol
 -fdisable-rtl-@var{pass_name} @gol
@@ -5629,6 +5629,12 @@ While @option{-ftrapv} causes traps for signed overflows to be emitted,
 @option{-fsanitize=undefined} gives a diagnostic message.
 This currently works only for the C family of languages.
 
+@item -fasan-shadow-offset=@var{string}
+@opindex fasan-shadow-offset
+This option forces GCC to use custom shadow offset in AddressSanitizer checks.
+It is useful for experimenting with different shadow memory layouts in
+Kernel AddressSanitizer.
+
 @item -fsanitize-recover
 @opindex fsanitize-recover
 By default @option{-fsanitize=undefined} sanitization (and its suboptions
diff --git a/gcc/opts-global.c b/gcc/opts-global.c
index 111884b..81c899c 100644
--- a/gcc/opts-global.c
+++ b/gcc/opts-global.c
@@ -42,6 +42,7 @@ along with GCC; see the file COPYING3.  If not see
 #include "toplev.h"
 #include "tree-pass.h"
 #include "context.h"
+#include "asan.h"
 
 typedef const char *const_char_p; /* For DEF_VEC_P.  */
 
@@ -426,6 +427,14 @@ handle_common_deferred_options (void)
 	  stack_limit_rtx = gen_rtx_SYMBOL_REF (Pmode, ggc_strdup (opt->arg));
 	  break;
 
+	case OPT_fasan_shadow_offset_:
+	  if (!(flag_sanitize & SANITIZE_KERNEL_ADDRESS))
+	    error ("-fasan-shadow-offset should only be used "
+		   "with -fsanitize=kernel-address");
+	  if (!set_asan_shadow_offset (opt->arg))
+	     error ("unrecognized shadow offset %qs", opt->arg);
+	  break;
+
 	default:
 	  gcc_unreachable ();
 	}
diff --git a/gcc/opts.c b/gcc/opts.c
index dc8ddf4..89d4f0e 100644
--- a/gcc/opts.c
+++ b/gcc/opts.c
@@ -1584,6 +1584,10 @@ common_handle_option (struct gcc_options *opts,
 	break;
       }
 
+    case OPT_fasan_shadow_offset_:
+      /* Deferred.  */
+      break;
+
     case OPT_O:
     case OPT_Os:
     case OPT_Ofast:
diff --git a/gcc/testsuite/c-c++-common/asan/shadow-offset-1.c b/gcc/testsuite/c-c++-common/asan/shadow-offset-1.c
new file mode 100644
index 0000000..2ca0fd6
--- /dev/null
+++ b/gcc/testsuite/c-c++-common/asan/shadow-offset-1.c
@@ -0,0 +1,11 @@
+/* { dg-do compile } */
+/* { dg-options "-fno-sanitize=address -fsanitize=kernel-address --param asan-instrumentation-with-call-threshold=100 -fasan-shadow-offset=12345 -fdump-tree-sanopt" } */
+/* { dg-skip-if "" { *-*-* } { "-flto" } { "" } } */
+ 
+int f (int *p)
+{
+  return *p;
+}
+
+/* { dg-final { scan-tree-dump "12345" "sanopt" }  } */
+/* { dg-final { cleanup-tree-dump "sanopt" } } */
-- 
1.7.9.5


^ permalink raw reply	[flat|nested] 18+ messages in thread

* Re: [PATCHv4][Kasan] Allow to override Asan shadow offset from command line
  2014-10-17  7:59     ` [PATCHv4][Kasan] " Yury Gribov
@ 2014-10-17 11:25       ` Jakub Jelinek
  2014-10-17 12:32         ` Ian Lance Taylor
  2014-10-24 13:58       ` [PATCHv5][Kasan] " Yury Gribov
  1 sibling, 1 reply; 18+ messages in thread
From: Jakub Jelinek @ 2014-10-17 11:25 UTC (permalink / raw)
  To: Yury Gribov, Ian Lance Taylor
  Cc: GCC Patches, Konstantin Serebryany, Dmitry Vyukov, Andrey Ryabinin

On Fri, Oct 17, 2014 at 11:53:01AM +0400, Yury Gribov wrote:
> >From 0225b7878bbb5b803814646d089824d016316fef Mon Sep 17 00:00:00 2001
> From: Yury Gribov <y.gribov@samsung.com>
> Date: Thu, 16 Oct 2014 18:31:10 +0400
> Subject: [PATCH 1/2] Add strtoull to libiberty.
> 
> 2014-10-17  Yury Gribov  <y.gribov@samsung.com>
> 
> libiberty/
> 	* strtoull.c: New file.

Just putting a file in there won't magically make it be part of libiberty.
Please read libiberty/README on how to add an optional file.
strtoul is also optional as strotoull should be, so you can also just
grep for strtoul in libiberty/* and add on similar spots.

Not sure if there aren't extra steps to make strtoull prototype available
in system.h, libiberty.h etc. for systems that don't have strtoull in their
headers.

CCing Ian as libiberty maintainer.

	Jakub

^ permalink raw reply	[flat|nested] 18+ messages in thread

* Re: [PATCHv4][Kasan] Allow to override Asan shadow offset from command line
  2014-10-17 11:25       ` Jakub Jelinek
@ 2014-10-17 12:32         ` Ian Lance Taylor
  2014-10-21 10:02           ` Yury Gribov
  0 siblings, 1 reply; 18+ messages in thread
From: Ian Lance Taylor @ 2014-10-17 12:32 UTC (permalink / raw)
  To: Jakub Jelinek
  Cc: Yury Gribov, GCC Patches, Konstantin Serebryany, Dmitry Vyukov,
	Andrey Ryabinin

Jakub Jelinek <jakub@redhat.com> writes:

> Not sure if there aren't extra steps to make strtoull prototype available
> in system.h, libiberty.h etc. for systems that don't have strtoull in their
> headers.

See the

#if defined(HAVE_DECL_XXX) && !HAVE_DECL_XXX

lines in include/libiberty.h.  Although strtol is missing there as well.

Ian

^ permalink raw reply	[flat|nested] 18+ messages in thread

* Re: [PATCHv4][Kasan] Allow to override Asan shadow offset from command line
  2014-10-17 12:32         ` Ian Lance Taylor
@ 2014-10-21 10:02           ` Yury Gribov
  0 siblings, 0 replies; 18+ messages in thread
From: Yury Gribov @ 2014-10-21 10:02 UTC (permalink / raw)
  To: Ian Lance Taylor, Jakub Jelinek
  Cc: GCC Patches, Konstantin Serebryany, Dmitry Vyukov, Andrey Ryabinin

[-- Attachment #1: Type: text/plain, Size: 1126 bytes --]

On 10/17/2014 04:32 PM, Ian Lance Taylor wrote:
> Jakub Jelinek <jakub@redhat.com> writes:
>
>> Not sure if there aren't extra steps to make strtoull prototype available
>> in system.h, libiberty.h etc. for systems that don't have strtoull in their
>> headers.
>
> See the
>
> #if defined(HAVE_DECL_XXX) && !HAVE_DECL_XXX
>
> lines in include/libiberty.h.  Although strtol is missing there as well.

Thanks, here is a new version of patch which adds support for strtoll 
and strtoull and also a small test for strtol family.

There some open questions though:

1) how am  to test libiberty patches like this? Glibc obviously has 
strtoll and strtoull so I won't get it in my libiberty.a by default. For 
now I manually embed strtoll.o/strtoull.o into libiberty.a and run tests 
by hand but that doesn't sound quite robust and also just x64 is 
probably not enough as well.

2) I had to use __extension__ keyword to hide warnings from -Wlong-long. 
Unfortunately it does not fix spurious warnings for long long constants 
in older versions of GCC 
(https://gcc.gnu.org/bugzilla/show_bug.cgi?id=7263). I guess that's fine.

-Y


[-- Attachment #2: libiberty-strtoll-2.diff --]
[-- Type: text/x-patch, Size: 32986 bytes --]

commit d78d8daeec19531014c703894dc67db1430f6cbb
Author: Yury Gribov <y.gribov@samsung.com>
Date:   Thu Oct 16 18:31:10 2014 +0400

    Add strtoll and strtoull to libiberty.
    
    2014-10-20  Yury Gribov  <y.gribov@samsung.com>
    
    include/
    	* libiberty.h (strtol, strtoul, strtoll, strtoull): New prototypes.
    
    libiberty/
    	* strtoll.c: New file.
    	* strtoull.c: New file.
    	* configure.ac: Add long long checks. Add harness for strtoll and
    	strtoull. Check decls for strtol, strtoul, strtoll, strtoull.
    	* Makefile.in (CFILES, CONFIGURED_OFILES): Added strtoll and strtoull.
    	* config.in: Regenerate.
    	* configure: Regenerate.
    	* functions.texi: Regenerate.
    	* testsuite/Makefile.in (check-strtol): New rule.
    	(test-strtol): Likewise.
    	(mostlyclean): Clean up strtol test.
    	* testsuite/test-strtol.c: New test.

diff --git a/include/libiberty.h b/include/libiberty.h
index d09c9a5..26355a9 100644
--- a/include/libiberty.h
+++ b/include/libiberty.h
@@ -655,6 +655,33 @@ extern size_t strnlen (const char *, size_t);
 extern int strverscmp (const char *, const char *);
 #endif
 
+#if defined(HAVE_DECL_STRTOL) && !HAVE_DECL_STRTOL
+extern long int strtol (const char *nptr,
+                        char **endptr, int base);
+#endif
+
+#if defined(HAVE_DECL_STRTOUL) && !HAVE_DECL_STRTOUL
+extern unsigned long int strtoul (const char *nptr,
+                                  char **endptr, int base);
+#endif
+
+#if defined(HAVE_DECL_STRTOLL) && !HAVE_DECL_STRTOLL
+__extension__
+extern long long int strtoll (const char *nptr,
+                              char **endptr, int base);
+#endif
+
+#if defined(HAVE_DECL_STRTOULL) && !HAVE_DECL_STRTOULL
+__extension__
+extern unsigned long long int strtoull (const char *nptr,
+                                        char **endptr, int base);
+#endif
+
+#if defined(HAVE_DECL_STRVERSCMP) && !HAVE_DECL_STRVERSCMP
+/* Compare version strings.  */
+extern int strverscmp (const char *, const char *);
+#endif
+
 /* Set the title of a process */
 extern void setproctitle (const char *name, ...);
 
diff --git a/libiberty/Makefile.in b/libiberty/Makefile.in
index 9b87720..1b0d8ae 100644
--- a/libiberty/Makefile.in
+++ b/libiberty/Makefile.in
@@ -152,8 +152,8 @@ CFILES = alloca.c argv.c asprintf.c atexit.c				\
 	 spaces.c splay-tree.c stack-limit.c stpcpy.c stpncpy.c		\
 	 strcasecmp.c strchr.c strdup.c strerror.c strncasecmp.c	\
 	 strncmp.c strrchr.c strsignal.c strstr.c strtod.c strtol.c	\
-	 strtoul.c strndup.c strnlen.c strverscmp.c			\
-	timeval-utils.c tmpnam.c					\
+	 strtoll.c strtoul.c strtoull.c strndup.c strnlen.c             \
+	 strverscmp.c timeval-utils.c tmpnam.c				\
 	unlink-if-ordinary.c						\
 	vasprintf.c vfork.c vfprintf.c vprintf.c vsnprintf.c vsprintf.c	\
 	waitpid.c							\
@@ -219,8 +219,8 @@ CONFIGURED_OFILES = ./asprintf.$(objext) ./atexit.$(objext)		\
 	 ./strchr.$(objext) ./strdup.$(objext) ./strncasecmp.$(objext)	\
 	 ./strncmp.$(objext) ./strndup.$(objext) ./strnlen.$(objext)	\
 	 ./strrchr.$(objext) ./strstr.$(objext) ./strtod.$(objext)	\
-	 ./strtol.$(objext) ./strtoul.$(objext) ./strverscmp.$(objext)	\
-	./tmpnam.$(objext)						\
+	 ./strtol.$(objext) ./strtoul.$(objext) strtoll.$(objext)	\
+	./strtoull.$(objext) ./tmpnam.$(objext) ./strverscmp.$(objext)	\
 	./vasprintf.$(objext) ./vfork.$(objext) ./vfprintf.$(objext)	\
 	 ./vprintf.$(objext) ./vsnprintf.$(objext) ./vsprintf.$(objext)	\
 	./waitpid.$(objext)
@@ -694,6 +694,17 @@ $(CONFIGURED_OFILES): stamp-picdir stamp-noasandir
 	else true; fi
 	$(COMPILE.c) $(srcdir)/crc32.c $(OUTPUT_OPTION)
 
+./d-demangle.$(objext): $(srcdir)/d-demangle.c config.h $(INCDIR)/ansidecl.h \
+	$(INCDIR)/demangle.h $(INCDIR)/libiberty.h \
+	$(INCDIR)/safe-ctype.h
+	if [ x"$(PICFLAG)" != x ]; then \
+	  $(COMPILE.c) $(PICFLAG) $(srcdir)/d-demangle.c -o pic/$@; \
+	else true; fi
+	if [ x"$(NOASANFLAG)" != x ]; then \
+	  $(COMPILE.c) $(PICFLAG) $(NOASANFLAG) $(srcdir)/d-demangle.c -o noasan/$@; \
+	else true; fi
+	$(COMPILE.c) $(srcdir)/d-demangle.c $(OUTPUT_OPTION)
+
 ./dwarfnames.$(objext): $(srcdir)/dwarfnames.c $(INCDIR)/dwarf2.def \
 	$(INCDIR)/dwarf2.h
 	if [ x"$(PICFLAG)" != x ]; then \
@@ -714,14 +725,6 @@ $(CONFIGURED_OFILES): stamp-picdir stamp-noasandir
 	else true; fi
 	$(COMPILE.c) $(srcdir)/dyn-string.c $(OUTPUT_OPTION)
 
-./d-demangle.$(objext): $(srcdir)/d-demangle.c config.h $(INCDIR)/ansidecl.h \
-	$(srcdir)/cp-demangle.h $(INCDIR)/demangle.h \
-	$(INCDIR)/dyn-string.h $(INCDIR)/getopt.h $(INCDIR)/libiberty.h
-	if [ x"$(PICFLAG)" != x ]; then \
-	  $(COMPILE.c) $(PICFLAG) $(srcdir)/d-demangle.c -o pic/$@; \
-	else true; fi
-	$(COMPILE.c) $(srcdir)/d-demangle.c $(OUTPUT_OPTION)
-
 ./fdmatch.$(objext): $(srcdir)/fdmatch.c config.h $(INCDIR)/ansidecl.h \
 	$(INCDIR)/libiberty.h
 	if [ x"$(PICFLAG)" != x ]; then \
@@ -1471,6 +1474,15 @@ $(CONFIGURED_OFILES): stamp-picdir stamp-noasandir
 	else true; fi
 	$(COMPILE.c) $(srcdir)/strtol.c $(OUTPUT_OPTION)
 
+./strtoll.$(objext): $(srcdir)/strtoll.c config.h $(INCDIR)/safe-ctype.h
+	if [ x"$(PICFLAG)" != x ]; then \
+	  $(COMPILE.c) $(PICFLAG) $(srcdir)/strtoll.c -o pic/$@; \
+	else true; fi
+	if [ x"$(NOASANFLAG)" != x ]; then \
+	  $(COMPILE.c) $(PICFLAG) $(NOASANFLAG) $(srcdir)/strtoll.c -o noasan/$@; \
+	else true; fi
+	$(COMPILE.c) $(srcdir)/strtoll.c $(OUTPUT_OPTION)
+
 ./strtoul.$(objext): $(srcdir)/strtoul.c config.h $(INCDIR)/ansidecl.h \
 	$(INCDIR)/safe-ctype.h
 	if [ x"$(PICFLAG)" != x ]; then \
@@ -1481,6 +1493,16 @@ $(CONFIGURED_OFILES): stamp-picdir stamp-noasandir
 	else true; fi
 	$(COMPILE.c) $(srcdir)/strtoul.c $(OUTPUT_OPTION)
 
+./strtoull.$(objext): $(srcdir)/strtoull.c config.h $(INCDIR)/ansidecl.h \
+	$(INCDIR)/safe-ctype.h
+	if [ x"$(PICFLAG)" != x ]; then \
+	  $(COMPILE.c) $(PICFLAG) $(srcdir)/strtoull.c -o pic/$@; \
+	else true; fi
+	if [ x"$(NOASANFLAG)" != x ]; then \
+	  $(COMPILE.c) $(PICFLAG) $(NOASANFLAG) $(srcdir)/strtoull.c -o noasan/$@; \
+	else true; fi
+	$(COMPILE.c) $(srcdir)/strtoull.c $(OUTPUT_OPTION)
+
 ./strverscmp.$(objext): $(srcdir)/strverscmp.c $(INCDIR)/ansidecl.h \
 	$(INCDIR)/libiberty.h $(INCDIR)/safe-ctype.h
 	if [ x"$(PICFLAG)" != x ]; then \
diff --git a/libiberty/config.in b/libiberty/config.in
index 1cf9c11..7c05b9d 100644
--- a/libiberty/config.in
+++ b/libiberty/config.in
@@ -79,6 +79,22 @@
    don't. */
 #undef HAVE_DECL_SNPRINTF
 
+/* Define to 1 if you have the declaration of `strtol', and to 0 if you don't.
+   */
+#undef HAVE_DECL_STRTOL
+
+/* Define to 1 if you have the declaration of `strtoll', and to 0 if you
+   don't. */
+#undef HAVE_DECL_STRTOLL
+
+/* Define to 1 if you have the declaration of `strtoul', and to 0 if you
+   don't. */
+#undef HAVE_DECL_STRTOUL
+
+/* Define to 1 if you have the declaration of `strtoull', and to 0 if you
+   don't. */
+#undef HAVE_DECL_STRTOULL
+
 /* Define to 1 if you have the declaration of `strverscmp', and to 0 if you
    don't. */
 #undef HAVE_DECL_STRVERSCMP
@@ -136,6 +152,9 @@
 /* Define to 1 if you have the <limits.h> header file. */
 #undef HAVE_LIMITS_H
 
+/* Define if you have the `long long' type. */
+#undef HAVE_LONG_LONG
+
 /* Define to 1 if you have the <machine/hal_sysinfo.h> header file. */
 #undef HAVE_MACHINE_HAL_SYSINFO_H
 
@@ -280,9 +299,15 @@
 /* Define to 1 if you have the `strtol' function. */
 #undef HAVE_STRTOL
 
+/* Define to 1 if you have the `strtoll' function. */
+#undef HAVE_STRTOLL
+
 /* Define to 1 if you have the `strtoul' function. */
 #undef HAVE_STRTOUL
 
+/* Define to 1 if you have the `strtoull' function. */
+#undef HAVE_STRTOULL
+
 /* Define to 1 if you have the `strverscmp' function. */
 #undef HAVE_STRVERSCMP
 
@@ -439,6 +464,12 @@
 /* The size of `int', as computed by sizeof. */
 #undef SIZEOF_INT
 
+/* The size of `long', as computed by sizeof. */
+#undef SIZEOF_LONG
+
+/* The size of `long long', as computed by sizeof. */
+#undef SIZEOF_LONG_LONG
+
 /* Define if you know the direction of stack growth for your system; otherwise
    it will be automatically deduced at run-time. STACK_DIRECTION > 0 => grows
    toward higher addresses STACK_DIRECTION < 0 => grows toward lower addresses
diff --git a/libiberty/configure b/libiberty/configure
index 96feaed..4a5e40a 100755
--- a/libiberty/configure
+++ b/libiberty/configure
@@ -5124,7 +5124,7 @@ $as_echo "#define NEED_DECLARATION_ERRNO 1" >>confdefs.h
 fi
 
 
-# Determine the size of an int for struct fibnode.
+# Determine sizes of some types.
 # The cast to long int works around a bug in the HP C Compiler
 # version HP92453-01 B.11.11.23709.GP, which incorrectly rejects
 # declarations like `int a3[[(sizeof (unsigned char)) >= 0]];'.
@@ -5159,6 +5159,82 @@ cat >>confdefs.h <<_ACEOF
 _ACEOF
 
 
+# The cast to long int works around a bug in the HP C Compiler
+# version HP92453-01 B.11.11.23709.GP, which incorrectly rejects
+# declarations like `int a3[[(sizeof (unsigned char)) >= 0]];'.
+# This bug is HP SR number 8606223364.
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking size of long" >&5
+$as_echo_n "checking size of long... " >&6; }
+if test "${ac_cv_sizeof_long+set}" = set; then :
+  $as_echo_n "(cached) " >&6
+else
+  if ac_fn_c_compute_int "$LINENO" "(long int) (sizeof (long))" "ac_cv_sizeof_long"        "$ac_includes_default"; then :
+
+else
+  if test "$ac_cv_type_long" = yes; then
+     { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
+$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
+{ as_fn_set_status 77
+as_fn_error "cannot compute sizeof (long)
+See \`config.log' for more details." "$LINENO" 5; }; }
+   else
+     ac_cv_sizeof_long=0
+   fi
+fi
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_sizeof_long" >&5
+$as_echo "$ac_cv_sizeof_long" >&6; }
+
+
+
+cat >>confdefs.h <<_ACEOF
+#define SIZEOF_LONG $ac_cv_sizeof_long
+_ACEOF
+
+
+
+# Check for presense of long long
+ac_fn_c_check_type "$LINENO" "long long" "ac_cv_type_long_long" "$ac_includes_default"
+if test "x$ac_cv_type_long_long" = x""yes; then :
+
+$as_echo "#define HAVE_LONG_LONG 1" >>confdefs.h
+ # The cast to long int works around a bug in the HP C Compiler
+# version HP92453-01 B.11.11.23709.GP, which incorrectly rejects
+# declarations like `int a3[[(sizeof (unsigned char)) >= 0]];'.
+# This bug is HP SR number 8606223364.
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking size of long long" >&5
+$as_echo_n "checking size of long long... " >&6; }
+if test "${ac_cv_sizeof_long_long+set}" = set; then :
+  $as_echo_n "(cached) " >&6
+else
+  if ac_fn_c_compute_int "$LINENO" "(long int) (sizeof (long long))" "ac_cv_sizeof_long_long"        "$ac_includes_default"; then :
+
+else
+  if test "$ac_cv_type_long_long" = yes; then
+     { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
+$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
+{ as_fn_set_status 77
+as_fn_error "cannot compute sizeof (long long)
+See \`config.log' for more details." "$LINENO" 5; }; }
+   else
+     ac_cv_sizeof_long_long=0
+   fi
+fi
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_sizeof_long_long" >&5
+$as_echo "$ac_cv_sizeof_long_long" >&6; }
+
+
+
+cat >>confdefs.h <<_ACEOF
+#define SIZEOF_LONG_LONG $ac_cv_sizeof_long_long
+_ACEOF
+
+
+fi
+
 
 # Look for a 64-bit type.
 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for a 64-bit type" >&5
@@ -5387,6 +5463,8 @@ funcs="$funcs strstr"
 funcs="$funcs strtod"
 funcs="$funcs strtol"
 funcs="$funcs strtoul"
+funcs="$funcs strtoll"
+funcs="$funcs strtoull"
 funcs="$funcs strverscmp"
 funcs="$funcs tmpnam"
 funcs="$funcs vasprintf"
@@ -5423,7 +5501,7 @@ if test "x" = "y"; then
     sbrk setenv setproctitle setrlimit sigsetmask snprintf spawnve spawnvpe \
      stpcpy stpncpy strcasecmp strchr strdup \
      strerror strncasecmp strndup strnlen strrchr strsignal strstr strtod \
-     strtol strtoul strverscmp sysconf sysctl sysmp \
+     strtol strtoul strtoll strtoull strverscmp sysconf sysctl sysmp \
     table times tmpnam \
     vasprintf vfprintf vprintf vsprintf \
     wait3 wait4 waitpid
@@ -5499,6 +5577,46 @@ fi
 cat >>confdefs.h <<_ACEOF
 #define HAVE_DECL_VSNPRINTF $ac_have_decl
 _ACEOF
+ac_fn_c_check_decl "$LINENO" "strtol" "ac_cv_have_decl_strtol" "$ac_includes_default"
+if test "x$ac_cv_have_decl_strtol" = x""yes; then :
+  ac_have_decl=1
+else
+  ac_have_decl=0
+fi
+
+cat >>confdefs.h <<_ACEOF
+#define HAVE_DECL_STRTOL $ac_have_decl
+_ACEOF
+ac_fn_c_check_decl "$LINENO" "strtoul" "ac_cv_have_decl_strtoul" "$ac_includes_default"
+if test "x$ac_cv_have_decl_strtoul" = x""yes; then :
+  ac_have_decl=1
+else
+  ac_have_decl=0
+fi
+
+cat >>confdefs.h <<_ACEOF
+#define HAVE_DECL_STRTOUL $ac_have_decl
+_ACEOF
+ac_fn_c_check_decl "$LINENO" "strtoll" "ac_cv_have_decl_strtoll" "$ac_includes_default"
+if test "x$ac_cv_have_decl_strtoll" = x""yes; then :
+  ac_have_decl=1
+else
+  ac_have_decl=0
+fi
+
+cat >>confdefs.h <<_ACEOF
+#define HAVE_DECL_STRTOLL $ac_have_decl
+_ACEOF
+ac_fn_c_check_decl "$LINENO" "strtoull" "ac_cv_have_decl_strtoull" "$ac_includes_default"
+if test "x$ac_cv_have_decl_strtoull" = x""yes; then :
+  ac_have_decl=1
+else
+  ac_have_decl=0
+fi
+
+cat >>confdefs.h <<_ACEOF
+#define HAVE_DECL_STRTOULL $ac_have_decl
+_ACEOF
 
 
 $as_echo "#define HAVE_SYS_ERRLIST 1" >>confdefs.h
diff --git a/libiberty/configure.ac b/libiberty/configure.ac
index 3380819..90adaea 100644
--- a/libiberty/configure.ac
+++ b/libiberty/configure.ac
@@ -272,8 +272,14 @@ AC_HEADER_TIME
 
 libiberty_AC_DECLARE_ERRNO
 
-# Determine the size of an int for struct fibnode.
+# Determine sizes of some types.
 AC_CHECK_SIZEOF([int])
+AC_CHECK_SIZEOF([long])
+
+# Check for presense of long long
+AC_CHECK_TYPE([long long],
+  [AC_DEFINE(HAVE_LONG_LONG, 1, [Define if you have the `long long' type.]) AC_CHECK_SIZEOF([long long])],
+  [])
 
 # Look for a 64-bit type.
 AC_MSG_CHECKING([for a 64-bit type])
@@ -365,6 +371,8 @@ funcs="$funcs strstr"
 funcs="$funcs strtod"
 funcs="$funcs strtol"
 funcs="$funcs strtoul"
+funcs="$funcs strtoll"
+funcs="$funcs strtoull"
 funcs="$funcs strverscmp"
 funcs="$funcs tmpnam"
 funcs="$funcs vasprintf"
@@ -401,11 +409,11 @@ if test "x" = "y"; then
     sbrk setenv setproctitle setrlimit sigsetmask snprintf spawnve spawnvpe \
      stpcpy stpncpy strcasecmp strchr strdup \
      strerror strncasecmp strndup strnlen strrchr strsignal strstr strtod \
-     strtol strtoul strverscmp sysconf sysctl sysmp \
+     strtol strtoul strtoll strtoull strverscmp sysconf sysctl sysmp \
     table times tmpnam \
     vasprintf vfprintf vprintf vsprintf \
     wait3 wait4 waitpid)
-  AC_CHECK_DECLS([basename(char *), ffs, asprintf, vasprintf, snprintf, vsnprintf])
+  AC_CHECK_DECLS([basename(char *), ffs, asprintf, vasprintf, snprintf, vsnprintf, strtol, strtoul, strtoll, strtoull])
   AC_DEFINE(HAVE_SYS_ERRLIST, 1, [Define if you have the sys_errlist variable.])
   AC_DEFINE(HAVE_SYS_NERR,    1, [Define if you have the sys_nerr variable.])
   AC_DEFINE(HAVE_SYS_SIGLIST, 1, [Define if you have the sys_siglist variable.])
diff --git a/libiberty/functions.texi b/libiberty/functions.texi
index 387aee0..3627285 100644
--- a/libiberty/functions.texi
+++ b/libiberty/functions.texi
@@ -1714,6 +1714,24 @@ that the converted value is unsigned.
 
 @end deftypefn
 
+@c strtoll.c:33
+@deftypefn Supplemental {long long int} strtoll (const char *@var{string}, @
+  char **@var{endptr}, int @var{base})
+@deftypefnx Supplemental {unsigned long long int} strtoul (@
+  const char *@var{string}, char **@var{endptr}, int @var{base})
+
+The @code{strtoll} function converts the string in @var{string} to a
+long long integer value according to the given @var{base}, which must be
+between 2 and 36 inclusive, or be the special value 0.  If @var{base}
+is 0, @code{strtoll} will look for the prefixes @code{0} and @code{0x}
+to indicate bases 8 and 16, respectively, else default to base 10.
+When the base is 16 (either explicitly or implicitly), a prefix of
+@code{0x} is allowed.  The handling of @var{endptr} is as that of
+@code{strtod} above.  The @code{strtoull} function is the same, except
+that the converted value is unsigned.
+
+@end deftypefn
+
 @c strsignal.c:502
 @deftypefn Extension int strtosigno (const char *@var{name})
 
diff --git a/libiberty/strtoll.c b/libiberty/strtoll.c
new file mode 100644
index 0000000..37ff8cd
--- /dev/null
+++ b/libiberty/strtoll.c
@@ -0,0 +1,175 @@
+/*-
+ * Copyright (c) 2014 The Regents of the University of California.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. [rescinded 22 July 1999]
+ * 4. Neither the name of the University nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+/*
+
+@deftypefn Supplemental {long long int} strtoll (const char *@var{string}, @
+  char **@var{endptr}, int @var{base})
+@deftypefnx Supplemental {unsigned long long int} strtoul (@
+  const char *@var{string}, char **@var{endptr}, int @var{base})
+
+The @code{strtoll} function converts the string in @var{string} to a
+long long integer value according to the given @var{base}, which must be
+between 2 and 36 inclusive, or be the special value 0.  If @var{base}
+is 0, @code{strtoll} will look for the prefixes @code{0} and @code{0x}
+to indicate bases 8 and 16, respectively, else default to base 10.
+When the base is 16 (either explicitly or implicitly), a prefix of
+@code{0x} is allowed.  The handling of @var{endptr} is as that of
+@code{strtod} above.  The @code{strtoull} function is the same, except
+that the converted value is unsigned.
+
+@end deftypefn
+
+*/
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+#ifdef HAVE_LIMITS_H
+#include <limits.h>
+#endif
+#ifdef HAVE_SYS_PARAM_H
+#include <sys/param.h>
+#endif
+#include <errno.h>
+#ifdef NEED_DECLARATION_ERRNO
+extern int errno;
+#endif
+#include "safe-ctype.h"
+
+#ifdef HAVE_LONG_LONG
+
+__extension__
+typedef unsigned long long ullong_type;
+
+__extension__
+typedef long long llong_type;
+
+/* FIXME: It'd be nice to configure around these, but the include files are too
+   painful.  These macros should at least be more portable than hardwired hex
+   constants. */
+
+#ifndef ULLONG_MAX
+#define ULLONG_MAX (~(ullong_type)0) /* 0xFFFFFFFFFFFFFFFF */
+#endif
+
+#ifndef LLONG_MAX
+#define LLONG_MAX ((llong_type)(ULLONG_MAX >> 1)) /* 0x7FFFFFFFFFFFFFFF */
+#endif
+
+#ifndef LLONG_MIN
+#define LLONG_MIN (~LLONG_MAX) /* 0x8000000000000000 */
+#endif
+
+/*
+ * Convert a string to a long long integer.
+ *
+ * Ignores `locale' stuff.  Assumes that the upper and lower case
+ * alphabets and digits are each contiguous.
+ */
+llong_type
+strtoll(const char *nptr, char **endptr, register int base)
+{
+	register const char *s = nptr;
+	register ullong_type acc;
+	register int c;
+	register ullong_type cutoff;
+	register int neg = 0, any, cutlim;
+
+	/*
+	 * Skip white space and pick up leading +/- sign if any.
+	 * If base is 0, allow 0x for hex and 0 for octal, else
+	 * assume decimal; if base is already 16, allow 0x.
+	 */
+	do {
+		c = *s++;
+	} while (ISSPACE(c));
+	if (c == '-') {
+		neg = 1;
+		c = *s++;
+	} else if (c == '+')
+		c = *s++;
+	if ((base == 0 || base == 16) &&
+	    c == '0' && (*s == 'x' || *s == 'X')) {
+		c = s[1];
+		s += 2;
+		base = 16;
+	}
+	if (base == 0)
+		base = c == '0' ? 8 : 10;
+
+	/*
+	 * Compute the cutoff value between legal numbers and illegal
+	 * numbers.  That is the largest legal value, divided by the
+	 * base.  An input number that is greater than this value, if
+	 * followed by a legal input character, is too big.  One that
+	 * is equal to this value may be valid or not; the limit
+	 * between valid and invalid numbers is then based on the last
+	 * digit.  For instance, if the range for longs is
+	 * [-2147483648..2147483647] and the input base is 10,
+	 * cutoff will be set to 214748364 and cutlim to either
+	 * 7 (neg==0) or 8 (neg==1), meaning that if we have accumulated
+	 * a value > 214748364, or equal but the next digit is > 7 (or 8),
+	 * the number is too big, and we will return a range error.
+	 *
+	 * Set any if any `digits' consumed; make it negative to indicate
+	 * overflow.
+	 */
+	cutoff = neg ? -(ullong_type)LLONG_MIN : LLONG_MAX;
+	cutlim = cutoff % (ullong_type)base;
+	cutoff /= (ullong_type)base;
+	for (acc = 0, any = 0;; c = *s++) {
+		if (ISDIGIT(c))
+			c -= '0';
+		else if (ISALPHA(c))
+			c -= ISUPPER(c) ? 'A' - 10 : 'a' - 10;
+		else
+			break;
+		if (c >= base)
+			break;
+		if (any < 0 || acc > cutoff || (acc == cutoff && c > cutlim))
+			any = -1;
+		else {
+			any = 1;
+			acc *= base;
+			acc += c;
+		}
+	}
+	if (any < 0) {
+		acc = neg ? LLONG_MIN : LLONG_MAX;
+		errno = ERANGE;
+	} else if (neg)
+		acc = -acc;
+	if (endptr != 0)
+		*endptr = (char *) (any ? s - 1 : nptr);
+	return (acc);
+}
+
+#endif /* ifdef HAVE_LONG_LONG */
diff --git a/libiberty/strtoull.c b/libiberty/strtoull.c
new file mode 100644
index 0000000..2f580fb
--- /dev/null
+++ b/libiberty/strtoull.c
@@ -0,0 +1,122 @@
+/*
+ * Copyright (c) 2014 Regents of the University of California.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. [rescinded 22 July 1999]
+ * 4. Neither the name of the University nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+#ifdef HAVE_LIMITS_H
+#include <limits.h>
+#endif
+#ifdef HAVE_SYS_PARAM_H
+#include <sys/param.h>
+#endif
+#include <errno.h>
+#ifdef NEED_DECLARATION_ERRNO
+extern int errno;
+#endif
+#if 0
+#include <stdlib.h>
+#endif
+#include "ansidecl.h"
+#include "safe-ctype.h"
+
+#ifdef HAVE_LONG_LONG
+
+__extension__
+typedef unsigned long long ullong_type;
+
+#ifndef ULLONG_MAX
+#define ULLONG_MAX (~(ullong_type)0) /* 0xFFFFFFFFFFFFFFFF */
+#endif
+
+/*
+ * Convert a string to an unsigned long long integer.
+ *
+ * Ignores `locale' stuff.  Assumes that the upper and lower case
+ * alphabets and digits are each contiguous.
+ */
+ullong_type
+strtoull(const char *nptr, char **endptr, register int base)
+{
+	register const char *s = nptr;
+	register ullong_type acc;
+	register int c;
+	register ullong_type cutoff;
+	register int neg = 0, any, cutlim;
+
+	/*
+	 * See strtol for comments as to the logic used.
+	 */
+	do {
+		c = *s++;
+	} while (ISSPACE(c));
+	if (c == '-') {
+		neg = 1;
+		c = *s++;
+	} else if (c == '+')
+		c = *s++;
+	if ((base == 0 || base == 16) &&
+	    c == '0' && (*s == 'x' || *s == 'X')) {
+		c = s[1];
+		s += 2;
+		base = 16;
+	}
+	if (base == 0)
+		base = c == '0' ? 8 : 10;
+	cutoff = (ullong_type)ULLONG_MAX / (ullong_type)base;
+	cutlim = (ullong_type)ULLONG_MAX % (ullong_type)base;
+	for (acc = 0, any = 0;; c = *s++) {
+		if (ISDIGIT(c))
+			c -= '0';
+		else if (ISALPHA(c))
+			c -= ISUPPER(c) ? 'A' - 10 : 'a' - 10;
+		else
+			break;
+		if (c >= base)
+			break;
+		if (any < 0 || acc > cutoff || (acc == cutoff && c > cutlim))
+			any = -1;
+		else {
+			any = 1;
+			acc *= base;
+			acc += c;
+		}
+	}
+	if (any < 0) {
+		acc = ULLONG_MAX;
+		errno = ERANGE;
+	} else if (neg)
+		acc = -acc;
+	if (endptr != 0)
+		*endptr = (char *) (any ? s - 1 : nptr);
+	return (acc);
+}
+
+#endif /* ifdef HAVE_LONG_LONG */
diff --git a/libiberty/testsuite/Makefile.in b/libiberty/testsuite/Makefile.in
index bb2db67..4324a8f 100644
--- a/libiberty/testsuite/Makefile.in
+++ b/libiberty/testsuite/Makefile.in
@@ -45,7 +45,8 @@ all:
 # CHECK is set to "really_check" or the empty string by configure.
 check: @CHECK@
 
-really-check: check-cplus-dem check-d-demangle check-pexecute check-expandargv
+really-check: check-cplus-dem check-d-demangle check-pexecute check-expandargv \
+		check-strtol
 
 # Run some tests of the demangler.
 check-cplus-dem: test-demangle $(srcdir)/demangle-expected
@@ -62,6 +63,10 @@ check-pexecute: test-pexecute
 check-expandargv: test-expandargv
 	./test-expandargv
 
+# Check the strtol functionality
+check-strtol: test-strtol
+	./test-strtol
+
 # Run the demangler fuzzer
 fuzz-demangler: demangler-fuzzer
 	./demangler-fuzzer
@@ -79,6 +84,10 @@ test-expandargv: $(srcdir)/test-expandargv.c ../libiberty.a
 	$(TEST_COMPILE) -DHAVE_CONFIG_H -I.. -o test-expandargv \
 		$(srcdir)/test-expandargv.c ../libiberty.a
 
+test-strtol: $(srcdir)/test-strtol.c ../libiberty.a
+	$(TEST_COMPILE) -DHAVE_CONFIG_H -I.. -o test-strtol \
+		$(srcdir)/test-strtol.c ../libiberty.a
+
 demangler-fuzzer: $(srcdir)/demangler-fuzzer.c ../libiberty.a
 	$(TEST_COMPILE) -o demangler-fuzzer \
 		$(srcdir)/demangler-fuzzer.c ../libiberty.a
@@ -92,6 +101,7 @@ mostlyclean:
 	rm -f test-demangle
 	rm -f test-pexecute
 	rm -f test-expandargv
+	rm -f test-strtol
 	rm -f demangler-fuzzer
 	rm -f core
 clean: mostlyclean
diff --git a/libiberty/testsuite/test-strtol.c b/libiberty/testsuite/test-strtol.c
new file mode 100644
index 0000000..e797c47
--- /dev/null
+++ b/libiberty/testsuite/test-strtol.c
@@ -0,0 +1,182 @@
+/* Test program for strtol family of funtions,
+   Copyright (C) 2014 Free Software Foundation, Inc.
+   Written by Yury Gribov <y.gribov@samsung.com>
+
+   This file is part of the libiberty library, which is part of GCC.
+
+   This file is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2 of the License, or
+   (at your option) any later version.
+
+   In addition to the permissions in the GNU General Public License, the
+   Free Software Foundation gives you unlimited permission to link the
+   compiled version of this file into combinations with other programs,
+   and to distribute those combinations without any restriction coming
+   from the use of this file.  (The General Public License restrictions
+   do apply in other respects; for example, they cover modification of
+   the file, and distribution when not linked into a combined
+   executable.)
+
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program; if not, write to the Free Software
+   Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA. 
+*/
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+#include "libiberty.h"
+#include <stdio.h>
+#include <errno.h>
+#ifdef HAVE_STDLIB_H
+#include <stdlib.h>
+#endif
+#ifdef HAVE_STRING_H
+#include <string.h>
+#endif
+#ifdef HAVE_UNISTD_H
+#include <unistd.h>
+#endif
+
+#ifndef EXIT_SUCCESS
+#define EXIT_SUCCESS 0
+#endif
+
+#ifndef EXIT_FAILURE
+#define EXIT_FAILURE 1
+#endif
+
+
+/* Test input data. */
+
+enum conversion_fun
+{
+  STRTOL,
+  STRTOLL,
+  STRTOUL,
+  STRTOULL,
+};
+
+#ifdef HAVE_LONG_LONG
+typedef unsigned long long integer_type;
+#else
+typedef unsigned long integer_type;
+#endif
+
+struct test_data_t
+{
+  enum conversion_fun fun;
+  const char *nptr;
+  int base;
+  integer_type res;
+  int errnum;
+};
+
+const struct test_data_t test_data[] = {
+  { STRTOL,  "0x123",       0, 0x123L,        0      },
+  { STRTOL,  "123",         0, 123L,          0      },
+  { STRTOL,  "0123",        0, 0123L,         0      },
+  { STRTOL,  "0x7FFFFFFF",  0, 0x7fffffffL,   0      },
+  { STRTOL,  "-0x80000000", 0, -0x80000000L,  0      },
+  { STRTOUL, "0x123",       0, 0x123UL,       0      },
+  { STRTOUL, "123",         0, 123UL,         0      },
+  { STRTOUL, "0123",        0, 0123UL,        0      },
+  { STRTOUL, "0xFFFFFFFF",  0, 0xffffffffUL,  0      },
+#if SIZEOF_LONG == 4
+  { STRTOL,  "0x80000000",  0, 0x7fffffffL,   ERANGE },
+  { STRTOL,  "-0x80000001", 0, -0x80000000L,  ERANGE },
+  { STRTOUL, "0x100000000", 0, 0xffffffffUL,  ERANGE },
+#endif
+#ifdef HAVE_LONG_LONG
+  { STRTOLL,  "0x123",               0, 0x123LL,               0      },
+  { STRTOLL,  "123",                 0, 123LL,                 0      },
+  { STRTOLL,  "0123",                0, 0123LL,                0      },
+  { STRTOLL,  "0x7FFFFFFFFFFFFFFF",  0, 0x7fffffffffffffffLL,  0      },
+  { STRTOLL,  "-0x8000000000000000", 0, -0x8000000000000000LL, 0      },
+  { STRTOULL, "0x123",               0, 0x123ULL,              0      },
+  { STRTOULL, "123",                 0, 123ULL,                0      },
+  { STRTOULL, "0123",                0, 0123ULL,               0      },
+  { STRTOULL, "0xFFFFFFFFFFFFFFFF",  0, 0xffffffffffffffffULL, 0      },
+#if SIZEOF_LONG_LONG == 8
+  { STRTOLL,  "0x8000000000000000",  0, 0x7fffffffffffffffLL,  ERANGE },
+  { STRTOLL,  "-0x8000000000000001", 0, -0x8000000000000000LL, ERANGE },
+  { STRTOULL, "0x10000000000000000", 0, 0xffffffffffffffffULL, ERANGE },
+#endif
+#endif
+};
+
+/* run_tests:
+    Run conversion function
+    Compare results
+    Return number of fails */
+
+int
+run_tests (const struct test_data_t *test_data, size_t ntests)
+{
+  int fails = 0, failed;
+  size_t i;
+
+  for (i = 0; i < ntests; ++i)
+    {
+      integer_type res;
+      int saved_errno;
+
+      errno = 0;
+
+      switch (test_data[i].fun)
+	{
+	case STRTOL:
+	  res = strtol (test_data[i].nptr, 0, test_data[i].base);
+	  break;
+	case STRTOUL:
+	  res = strtoul (test_data[i].nptr, 0, test_data[i].base);
+	  break;
+	case STRTOLL:
+	  res = strtoll (test_data[i].nptr, 0, test_data[i].base);
+	  break;
+	case STRTOULL:
+	  res = strtoull (test_data[i].nptr, 0, test_data[i].base);
+	  break;
+	}
+
+      saved_errno = errno;
+
+      failed = 0;
+
+      /* Compare result */
+      if (res != test_data[i].res)
+        {
+          printf ("FAIL: test-strtol-%zd. Results don't match.\n", i);
+	  failed++;
+        }
+
+      /* Compare errno */
+      if (saved_errno != test_data[i].errnum)
+        {
+          printf ("FAIL: test-strtol-%zd. Errnos don't match.\n", i);
+	  failed++;
+        }
+
+      if (!failed)
+        printf ("PASS: test-strtol-%zd.\n", i);
+      else
+        fails++;
+    }
+
+  return fails;
+}
+
+int 
+main(int argc, char **argv)
+{
+  int fails;
+  fails = run_tests (test_data, sizeof (test_data) / sizeof (test_data[0]));
+  exit (fails ? EXIT_FAILURE : EXIT_SUCCESS);
+}
+

^ permalink raw reply	[flat|nested] 18+ messages in thread

* [PATCHv5][Kasan] Allow to override Asan shadow offset from command line
  2014-10-17  7:59     ` [PATCHv4][Kasan] " Yury Gribov
  2014-10-17 11:25       ` Jakub Jelinek
@ 2014-10-24 13:58       ` Yury Gribov
  2014-10-24 14:09         ` Jakub Jelinek
                           ` (2 more replies)
  1 sibling, 3 replies; 18+ messages in thread
From: Yury Gribov @ 2014-10-24 13:58 UTC (permalink / raw)
  To: GCC Patches
  Cc: Konstantin Serebryany, Dmitry Vyukov, Andrey Ryabinin, Ian Lance Taylor

[-- Attachment #1: Type: text/plain, Size: 1130 bytes --]

Hi all,

On 10/17/2014 11:53 AM, Yury Gribov wrote:
> On 09/29/2014 09:21 PM, Yury Gribov wrote:
>>>> Kasan developers has asked for an option to override offset of Asan
>>>> shadow memory region. This should simplify experimenting with memory
>>>> layouts on 64-bit architectures.
>>
>> New patch which checks that -fasan-shadow-offset is only enabled for
>> -fsanitize=kernel-address. I (unfortunately) can't make this --param
>> because this can be a 64-bit value.
>
> New patchset that adds strtoull to libiberty (blind copy-paste of
> already existing strtoul.c) and uses it to parse -fasan-shadow-offset
> (to avoid problem with compiling for 64-bit target a 32-bit host).

A new version of patchset which does a proper implementation of 
strtoll/strtoull in libiberty (with tests, docs and stuff).

Bootstrapped and regtested on x64.

As mentioned previously, I'm not sure how to properly test strtoll 
implementation (strtoll is already part of Linux glibc so my 
implementation is not compiled in by default).  I've manually embedded 
strtoll.o/strtoull.o into libiberty.a and verified that regression tests 
passed.

-Y

[-- Attachment #2: 0001-Add-strtoll-and-strtoull-to-libiberty.patch --]
[-- Type: text/x-patch, Size: 33766 bytes --]

From 1882c41de6c8ae53b7e199b3cc655b6f4b31e8fb Mon Sep 17 00:00:00 2001
From: Yury Gribov <y.gribov@samsung.com>
Date: Thu, 16 Oct 2014 18:31:10 +0400
Subject: [PATCH 1/2] Add strtoll and strtoull to libiberty.

2014-10-20  Yury Gribov  <y.gribov@samsung.com>

include/
	* libiberty.h (strtol, strtoul, strtoll, strtoull): New prototypes.

libiberty/
	* strtoll.c: New file.
	* strtoull.c: New file.
	* configure.ac: Add long long checks. Add harness for strtoll and
	strtoull. Check decls for strtol, strtoul, strtoll, strtoull.
	* Makefile.in (CFILES, CONFIGURED_OFILES): Added strtoll and strtoull.
	* config.in: Regenerate.
	* configure: Regenerate.
	* functions.texi: Regenerate.
	* testsuite/Makefile.in (check-strtol): New rule.
	(test-strtol): Likewise.
	(mostlyclean): Clean up strtol test.
	* testsuite/test-strtol.c: New test.
---
 include/libiberty.h               |   27 ++++++
 libiberty/Makefile.in             |   46 +++++++---
 libiberty/config.in               |   31 +++++++
 libiberty/configure               |  122 +++++++++++++++++++++++-
 libiberty/configure.ac            |   14 ++-
 libiberty/functions.texi          |   18 ++++
 libiberty/strtoll.c               |  175 +++++++++++++++++++++++++++++++++++
 libiberty/strtoull.c              |  122 ++++++++++++++++++++++++
 libiberty/testsuite/Makefile.in   |   12 ++-
 libiberty/testsuite/test-strtol.c |  184 +++++++++++++++++++++++++++++++++++++
 10 files changed, 733 insertions(+), 18 deletions(-)
 create mode 100644 libiberty/strtoll.c
 create mode 100644 libiberty/strtoull.c
 create mode 100644 libiberty/testsuite/test-strtol.c

diff --git a/include/libiberty.h b/include/libiberty.h
index d09c9a5..26355a9 100644
--- a/include/libiberty.h
+++ b/include/libiberty.h
@@ -655,6 +655,33 @@ extern size_t strnlen (const char *, size_t);
 extern int strverscmp (const char *, const char *);
 #endif
 
+#if defined(HAVE_DECL_STRTOL) && !HAVE_DECL_STRTOL
+extern long int strtol (const char *nptr,
+                        char **endptr, int base);
+#endif
+
+#if defined(HAVE_DECL_STRTOUL) && !HAVE_DECL_STRTOUL
+extern unsigned long int strtoul (const char *nptr,
+                                  char **endptr, int base);
+#endif
+
+#if defined(HAVE_DECL_STRTOLL) && !HAVE_DECL_STRTOLL
+__extension__
+extern long long int strtoll (const char *nptr,
+                              char **endptr, int base);
+#endif
+
+#if defined(HAVE_DECL_STRTOULL) && !HAVE_DECL_STRTOULL
+__extension__
+extern unsigned long long int strtoull (const char *nptr,
+                                        char **endptr, int base);
+#endif
+
+#if defined(HAVE_DECL_STRVERSCMP) && !HAVE_DECL_STRVERSCMP
+/* Compare version strings.  */
+extern int strverscmp (const char *, const char *);
+#endif
+
 /* Set the title of a process */
 extern void setproctitle (const char *name, ...);
 
diff --git a/libiberty/Makefile.in b/libiberty/Makefile.in
index 9b87720..1b0d8ae 100644
--- a/libiberty/Makefile.in
+++ b/libiberty/Makefile.in
@@ -152,8 +152,8 @@ CFILES = alloca.c argv.c asprintf.c atexit.c				\
 	 spaces.c splay-tree.c stack-limit.c stpcpy.c stpncpy.c		\
 	 strcasecmp.c strchr.c strdup.c strerror.c strncasecmp.c	\
 	 strncmp.c strrchr.c strsignal.c strstr.c strtod.c strtol.c	\
-	 strtoul.c strndup.c strnlen.c strverscmp.c			\
-	timeval-utils.c tmpnam.c					\
+	 strtoll.c strtoul.c strtoull.c strndup.c strnlen.c             \
+	 strverscmp.c timeval-utils.c tmpnam.c				\
 	unlink-if-ordinary.c						\
 	vasprintf.c vfork.c vfprintf.c vprintf.c vsnprintf.c vsprintf.c	\
 	waitpid.c							\
@@ -219,8 +219,8 @@ CONFIGURED_OFILES = ./asprintf.$(objext) ./atexit.$(objext)		\
 	 ./strchr.$(objext) ./strdup.$(objext) ./strncasecmp.$(objext)	\
 	 ./strncmp.$(objext) ./strndup.$(objext) ./strnlen.$(objext)	\
 	 ./strrchr.$(objext) ./strstr.$(objext) ./strtod.$(objext)	\
-	 ./strtol.$(objext) ./strtoul.$(objext) ./strverscmp.$(objext)	\
-	./tmpnam.$(objext)						\
+	 ./strtol.$(objext) ./strtoul.$(objext) strtoll.$(objext)	\
+	./strtoull.$(objext) ./tmpnam.$(objext) ./strverscmp.$(objext)	\
 	./vasprintf.$(objext) ./vfork.$(objext) ./vfprintf.$(objext)	\
 	 ./vprintf.$(objext) ./vsnprintf.$(objext) ./vsprintf.$(objext)	\
 	./waitpid.$(objext)
@@ -694,6 +694,17 @@ $(CONFIGURED_OFILES): stamp-picdir stamp-noasandir
 	else true; fi
 	$(COMPILE.c) $(srcdir)/crc32.c $(OUTPUT_OPTION)
 
+./d-demangle.$(objext): $(srcdir)/d-demangle.c config.h $(INCDIR)/ansidecl.h \
+	$(INCDIR)/demangle.h $(INCDIR)/libiberty.h \
+	$(INCDIR)/safe-ctype.h
+	if [ x"$(PICFLAG)" != x ]; then \
+	  $(COMPILE.c) $(PICFLAG) $(srcdir)/d-demangle.c -o pic/$@; \
+	else true; fi
+	if [ x"$(NOASANFLAG)" != x ]; then \
+	  $(COMPILE.c) $(PICFLAG) $(NOASANFLAG) $(srcdir)/d-demangle.c -o noasan/$@; \
+	else true; fi
+	$(COMPILE.c) $(srcdir)/d-demangle.c $(OUTPUT_OPTION)
+
 ./dwarfnames.$(objext): $(srcdir)/dwarfnames.c $(INCDIR)/dwarf2.def \
 	$(INCDIR)/dwarf2.h
 	if [ x"$(PICFLAG)" != x ]; then \
@@ -714,14 +725,6 @@ $(CONFIGURED_OFILES): stamp-picdir stamp-noasandir
 	else true; fi
 	$(COMPILE.c) $(srcdir)/dyn-string.c $(OUTPUT_OPTION)
 
-./d-demangle.$(objext): $(srcdir)/d-demangle.c config.h $(INCDIR)/ansidecl.h \
-	$(srcdir)/cp-demangle.h $(INCDIR)/demangle.h \
-	$(INCDIR)/dyn-string.h $(INCDIR)/getopt.h $(INCDIR)/libiberty.h
-	if [ x"$(PICFLAG)" != x ]; then \
-	  $(COMPILE.c) $(PICFLAG) $(srcdir)/d-demangle.c -o pic/$@; \
-	else true; fi
-	$(COMPILE.c) $(srcdir)/d-demangle.c $(OUTPUT_OPTION)
-
 ./fdmatch.$(objext): $(srcdir)/fdmatch.c config.h $(INCDIR)/ansidecl.h \
 	$(INCDIR)/libiberty.h
 	if [ x"$(PICFLAG)" != x ]; then \
@@ -1471,6 +1474,15 @@ $(CONFIGURED_OFILES): stamp-picdir stamp-noasandir
 	else true; fi
 	$(COMPILE.c) $(srcdir)/strtol.c $(OUTPUT_OPTION)
 
+./strtoll.$(objext): $(srcdir)/strtoll.c config.h $(INCDIR)/safe-ctype.h
+	if [ x"$(PICFLAG)" != x ]; then \
+	  $(COMPILE.c) $(PICFLAG) $(srcdir)/strtoll.c -o pic/$@; \
+	else true; fi
+	if [ x"$(NOASANFLAG)" != x ]; then \
+	  $(COMPILE.c) $(PICFLAG) $(NOASANFLAG) $(srcdir)/strtoll.c -o noasan/$@; \
+	else true; fi
+	$(COMPILE.c) $(srcdir)/strtoll.c $(OUTPUT_OPTION)
+
 ./strtoul.$(objext): $(srcdir)/strtoul.c config.h $(INCDIR)/ansidecl.h \
 	$(INCDIR)/safe-ctype.h
 	if [ x"$(PICFLAG)" != x ]; then \
@@ -1481,6 +1493,16 @@ $(CONFIGURED_OFILES): stamp-picdir stamp-noasandir
 	else true; fi
 	$(COMPILE.c) $(srcdir)/strtoul.c $(OUTPUT_OPTION)
 
+./strtoull.$(objext): $(srcdir)/strtoull.c config.h $(INCDIR)/ansidecl.h \
+	$(INCDIR)/safe-ctype.h
+	if [ x"$(PICFLAG)" != x ]; then \
+	  $(COMPILE.c) $(PICFLAG) $(srcdir)/strtoull.c -o pic/$@; \
+	else true; fi
+	if [ x"$(NOASANFLAG)" != x ]; then \
+	  $(COMPILE.c) $(PICFLAG) $(NOASANFLAG) $(srcdir)/strtoull.c -o noasan/$@; \
+	else true; fi
+	$(COMPILE.c) $(srcdir)/strtoull.c $(OUTPUT_OPTION)
+
 ./strverscmp.$(objext): $(srcdir)/strverscmp.c $(INCDIR)/ansidecl.h \
 	$(INCDIR)/libiberty.h $(INCDIR)/safe-ctype.h
 	if [ x"$(PICFLAG)" != x ]; then \
diff --git a/libiberty/config.in b/libiberty/config.in
index 1cf9c11..7c05b9d 100644
--- a/libiberty/config.in
+++ b/libiberty/config.in
@@ -79,6 +79,22 @@
    don't. */
 #undef HAVE_DECL_SNPRINTF
 
+/* Define to 1 if you have the declaration of `strtol', and to 0 if you don't.
+   */
+#undef HAVE_DECL_STRTOL
+
+/* Define to 1 if you have the declaration of `strtoll', and to 0 if you
+   don't. */
+#undef HAVE_DECL_STRTOLL
+
+/* Define to 1 if you have the declaration of `strtoul', and to 0 if you
+   don't. */
+#undef HAVE_DECL_STRTOUL
+
+/* Define to 1 if you have the declaration of `strtoull', and to 0 if you
+   don't. */
+#undef HAVE_DECL_STRTOULL
+
 /* Define to 1 if you have the declaration of `strverscmp', and to 0 if you
    don't. */
 #undef HAVE_DECL_STRVERSCMP
@@ -136,6 +152,9 @@
 /* Define to 1 if you have the <limits.h> header file. */
 #undef HAVE_LIMITS_H
 
+/* Define if you have the `long long' type. */
+#undef HAVE_LONG_LONG
+
 /* Define to 1 if you have the <machine/hal_sysinfo.h> header file. */
 #undef HAVE_MACHINE_HAL_SYSINFO_H
 
@@ -280,9 +299,15 @@
 /* Define to 1 if you have the `strtol' function. */
 #undef HAVE_STRTOL
 
+/* Define to 1 if you have the `strtoll' function. */
+#undef HAVE_STRTOLL
+
 /* Define to 1 if you have the `strtoul' function. */
 #undef HAVE_STRTOUL
 
+/* Define to 1 if you have the `strtoull' function. */
+#undef HAVE_STRTOULL
+
 /* Define to 1 if you have the `strverscmp' function. */
 #undef HAVE_STRVERSCMP
 
@@ -439,6 +464,12 @@
 /* The size of `int', as computed by sizeof. */
 #undef SIZEOF_INT
 
+/* The size of `long', as computed by sizeof. */
+#undef SIZEOF_LONG
+
+/* The size of `long long', as computed by sizeof. */
+#undef SIZEOF_LONG_LONG
+
 /* Define if you know the direction of stack growth for your system; otherwise
    it will be automatically deduced at run-time. STACK_DIRECTION > 0 => grows
    toward higher addresses STACK_DIRECTION < 0 => grows toward lower addresses
diff --git a/libiberty/configure b/libiberty/configure
index 96feaed..4a5e40a 100755
--- a/libiberty/configure
+++ b/libiberty/configure
@@ -5124,7 +5124,7 @@ $as_echo "#define NEED_DECLARATION_ERRNO 1" >>confdefs.h
 fi
 
 
-# Determine the size of an int for struct fibnode.
+# Determine sizes of some types.
 # The cast to long int works around a bug in the HP C Compiler
 # version HP92453-01 B.11.11.23709.GP, which incorrectly rejects
 # declarations like `int a3[[(sizeof (unsigned char)) >= 0]];'.
@@ -5159,6 +5159,82 @@ cat >>confdefs.h <<_ACEOF
 _ACEOF
 
 
+# The cast to long int works around a bug in the HP C Compiler
+# version HP92453-01 B.11.11.23709.GP, which incorrectly rejects
+# declarations like `int a3[[(sizeof (unsigned char)) >= 0]];'.
+# This bug is HP SR number 8606223364.
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking size of long" >&5
+$as_echo_n "checking size of long... " >&6; }
+if test "${ac_cv_sizeof_long+set}" = set; then :
+  $as_echo_n "(cached) " >&6
+else
+  if ac_fn_c_compute_int "$LINENO" "(long int) (sizeof (long))" "ac_cv_sizeof_long"        "$ac_includes_default"; then :
+
+else
+  if test "$ac_cv_type_long" = yes; then
+     { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
+$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
+{ as_fn_set_status 77
+as_fn_error "cannot compute sizeof (long)
+See \`config.log' for more details." "$LINENO" 5; }; }
+   else
+     ac_cv_sizeof_long=0
+   fi
+fi
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_sizeof_long" >&5
+$as_echo "$ac_cv_sizeof_long" >&6; }
+
+
+
+cat >>confdefs.h <<_ACEOF
+#define SIZEOF_LONG $ac_cv_sizeof_long
+_ACEOF
+
+
+
+# Check for presense of long long
+ac_fn_c_check_type "$LINENO" "long long" "ac_cv_type_long_long" "$ac_includes_default"
+if test "x$ac_cv_type_long_long" = x""yes; then :
+
+$as_echo "#define HAVE_LONG_LONG 1" >>confdefs.h
+ # The cast to long int works around a bug in the HP C Compiler
+# version HP92453-01 B.11.11.23709.GP, which incorrectly rejects
+# declarations like `int a3[[(sizeof (unsigned char)) >= 0]];'.
+# This bug is HP SR number 8606223364.
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking size of long long" >&5
+$as_echo_n "checking size of long long... " >&6; }
+if test "${ac_cv_sizeof_long_long+set}" = set; then :
+  $as_echo_n "(cached) " >&6
+else
+  if ac_fn_c_compute_int "$LINENO" "(long int) (sizeof (long long))" "ac_cv_sizeof_long_long"        "$ac_includes_default"; then :
+
+else
+  if test "$ac_cv_type_long_long" = yes; then
+     { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
+$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
+{ as_fn_set_status 77
+as_fn_error "cannot compute sizeof (long long)
+See \`config.log' for more details." "$LINENO" 5; }; }
+   else
+     ac_cv_sizeof_long_long=0
+   fi
+fi
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_sizeof_long_long" >&5
+$as_echo "$ac_cv_sizeof_long_long" >&6; }
+
+
+
+cat >>confdefs.h <<_ACEOF
+#define SIZEOF_LONG_LONG $ac_cv_sizeof_long_long
+_ACEOF
+
+
+fi
+
 
 # Look for a 64-bit type.
 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for a 64-bit type" >&5
@@ -5387,6 +5463,8 @@ funcs="$funcs strstr"
 funcs="$funcs strtod"
 funcs="$funcs strtol"
 funcs="$funcs strtoul"
+funcs="$funcs strtoll"
+funcs="$funcs strtoull"
 funcs="$funcs strverscmp"
 funcs="$funcs tmpnam"
 funcs="$funcs vasprintf"
@@ -5423,7 +5501,7 @@ if test "x" = "y"; then
     sbrk setenv setproctitle setrlimit sigsetmask snprintf spawnve spawnvpe \
      stpcpy stpncpy strcasecmp strchr strdup \
      strerror strncasecmp strndup strnlen strrchr strsignal strstr strtod \
-     strtol strtoul strverscmp sysconf sysctl sysmp \
+     strtol strtoul strtoll strtoull strverscmp sysconf sysctl sysmp \
     table times tmpnam \
     vasprintf vfprintf vprintf vsprintf \
     wait3 wait4 waitpid
@@ -5499,6 +5577,46 @@ fi
 cat >>confdefs.h <<_ACEOF
 #define HAVE_DECL_VSNPRINTF $ac_have_decl
 _ACEOF
+ac_fn_c_check_decl "$LINENO" "strtol" "ac_cv_have_decl_strtol" "$ac_includes_default"
+if test "x$ac_cv_have_decl_strtol" = x""yes; then :
+  ac_have_decl=1
+else
+  ac_have_decl=0
+fi
+
+cat >>confdefs.h <<_ACEOF
+#define HAVE_DECL_STRTOL $ac_have_decl
+_ACEOF
+ac_fn_c_check_decl "$LINENO" "strtoul" "ac_cv_have_decl_strtoul" "$ac_includes_default"
+if test "x$ac_cv_have_decl_strtoul" = x""yes; then :
+  ac_have_decl=1
+else
+  ac_have_decl=0
+fi
+
+cat >>confdefs.h <<_ACEOF
+#define HAVE_DECL_STRTOUL $ac_have_decl
+_ACEOF
+ac_fn_c_check_decl "$LINENO" "strtoll" "ac_cv_have_decl_strtoll" "$ac_includes_default"
+if test "x$ac_cv_have_decl_strtoll" = x""yes; then :
+  ac_have_decl=1
+else
+  ac_have_decl=0
+fi
+
+cat >>confdefs.h <<_ACEOF
+#define HAVE_DECL_STRTOLL $ac_have_decl
+_ACEOF
+ac_fn_c_check_decl "$LINENO" "strtoull" "ac_cv_have_decl_strtoull" "$ac_includes_default"
+if test "x$ac_cv_have_decl_strtoull" = x""yes; then :
+  ac_have_decl=1
+else
+  ac_have_decl=0
+fi
+
+cat >>confdefs.h <<_ACEOF
+#define HAVE_DECL_STRTOULL $ac_have_decl
+_ACEOF
 
 
 $as_echo "#define HAVE_SYS_ERRLIST 1" >>confdefs.h
diff --git a/libiberty/configure.ac b/libiberty/configure.ac
index 3380819..90adaea 100644
--- a/libiberty/configure.ac
+++ b/libiberty/configure.ac
@@ -272,8 +272,14 @@ AC_HEADER_TIME
 
 libiberty_AC_DECLARE_ERRNO
 
-# Determine the size of an int for struct fibnode.
+# Determine sizes of some types.
 AC_CHECK_SIZEOF([int])
+AC_CHECK_SIZEOF([long])
+
+# Check for presense of long long
+AC_CHECK_TYPE([long long],
+  [AC_DEFINE(HAVE_LONG_LONG, 1, [Define if you have the `long long' type.]) AC_CHECK_SIZEOF([long long])],
+  [])
 
 # Look for a 64-bit type.
 AC_MSG_CHECKING([for a 64-bit type])
@@ -365,6 +371,8 @@ funcs="$funcs strstr"
 funcs="$funcs strtod"
 funcs="$funcs strtol"
 funcs="$funcs strtoul"
+funcs="$funcs strtoll"
+funcs="$funcs strtoull"
 funcs="$funcs strverscmp"
 funcs="$funcs tmpnam"
 funcs="$funcs vasprintf"
@@ -401,11 +409,11 @@ if test "x" = "y"; then
     sbrk setenv setproctitle setrlimit sigsetmask snprintf spawnve spawnvpe \
      stpcpy stpncpy strcasecmp strchr strdup \
      strerror strncasecmp strndup strnlen strrchr strsignal strstr strtod \
-     strtol strtoul strverscmp sysconf sysctl sysmp \
+     strtol strtoul strtoll strtoull strverscmp sysconf sysctl sysmp \
     table times tmpnam \
     vasprintf vfprintf vprintf vsprintf \
     wait3 wait4 waitpid)
-  AC_CHECK_DECLS([basename(char *), ffs, asprintf, vasprintf, snprintf, vsnprintf])
+  AC_CHECK_DECLS([basename(char *), ffs, asprintf, vasprintf, snprintf, vsnprintf, strtol, strtoul, strtoll, strtoull])
   AC_DEFINE(HAVE_SYS_ERRLIST, 1, [Define if you have the sys_errlist variable.])
   AC_DEFINE(HAVE_SYS_NERR,    1, [Define if you have the sys_nerr variable.])
   AC_DEFINE(HAVE_SYS_SIGLIST, 1, [Define if you have the sys_siglist variable.])
diff --git a/libiberty/functions.texi b/libiberty/functions.texi
index 387aee0..3627285 100644
--- a/libiberty/functions.texi
+++ b/libiberty/functions.texi
@@ -1714,6 +1714,24 @@ that the converted value is unsigned.
 
 @end deftypefn
 
+@c strtoll.c:33
+@deftypefn Supplemental {long long int} strtoll (const char *@var{string}, @
+  char **@var{endptr}, int @var{base})
+@deftypefnx Supplemental {unsigned long long int} strtoul (@
+  const char *@var{string}, char **@var{endptr}, int @var{base})
+
+The @code{strtoll} function converts the string in @var{string} to a
+long long integer value according to the given @var{base}, which must be
+between 2 and 36 inclusive, or be the special value 0.  If @var{base}
+is 0, @code{strtoll} will look for the prefixes @code{0} and @code{0x}
+to indicate bases 8 and 16, respectively, else default to base 10.
+When the base is 16 (either explicitly or implicitly), a prefix of
+@code{0x} is allowed.  The handling of @var{endptr} is as that of
+@code{strtod} above.  The @code{strtoull} function is the same, except
+that the converted value is unsigned.
+
+@end deftypefn
+
 @c strsignal.c:502
 @deftypefn Extension int strtosigno (const char *@var{name})
 
diff --git a/libiberty/strtoll.c b/libiberty/strtoll.c
new file mode 100644
index 0000000..37ff8cd
--- /dev/null
+++ b/libiberty/strtoll.c
@@ -0,0 +1,175 @@
+/*-
+ * Copyright (c) 2014 The Regents of the University of California.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. [rescinded 22 July 1999]
+ * 4. Neither the name of the University nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+/*
+
+@deftypefn Supplemental {long long int} strtoll (const char *@var{string}, @
+  char **@var{endptr}, int @var{base})
+@deftypefnx Supplemental {unsigned long long int} strtoul (@
+  const char *@var{string}, char **@var{endptr}, int @var{base})
+
+The @code{strtoll} function converts the string in @var{string} to a
+long long integer value according to the given @var{base}, which must be
+between 2 and 36 inclusive, or be the special value 0.  If @var{base}
+is 0, @code{strtoll} will look for the prefixes @code{0} and @code{0x}
+to indicate bases 8 and 16, respectively, else default to base 10.
+When the base is 16 (either explicitly or implicitly), a prefix of
+@code{0x} is allowed.  The handling of @var{endptr} is as that of
+@code{strtod} above.  The @code{strtoull} function is the same, except
+that the converted value is unsigned.
+
+@end deftypefn
+
+*/
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+#ifdef HAVE_LIMITS_H
+#include <limits.h>
+#endif
+#ifdef HAVE_SYS_PARAM_H
+#include <sys/param.h>
+#endif
+#include <errno.h>
+#ifdef NEED_DECLARATION_ERRNO
+extern int errno;
+#endif
+#include "safe-ctype.h"
+
+#ifdef HAVE_LONG_LONG
+
+__extension__
+typedef unsigned long long ullong_type;
+
+__extension__
+typedef long long llong_type;
+
+/* FIXME: It'd be nice to configure around these, but the include files are too
+   painful.  These macros should at least be more portable than hardwired hex
+   constants. */
+
+#ifndef ULLONG_MAX
+#define ULLONG_MAX (~(ullong_type)0) /* 0xFFFFFFFFFFFFFFFF */
+#endif
+
+#ifndef LLONG_MAX
+#define LLONG_MAX ((llong_type)(ULLONG_MAX >> 1)) /* 0x7FFFFFFFFFFFFFFF */
+#endif
+
+#ifndef LLONG_MIN
+#define LLONG_MIN (~LLONG_MAX) /* 0x8000000000000000 */
+#endif
+
+/*
+ * Convert a string to a long long integer.
+ *
+ * Ignores `locale' stuff.  Assumes that the upper and lower case
+ * alphabets and digits are each contiguous.
+ */
+llong_type
+strtoll(const char *nptr, char **endptr, register int base)
+{
+	register const char *s = nptr;
+	register ullong_type acc;
+	register int c;
+	register ullong_type cutoff;
+	register int neg = 0, any, cutlim;
+
+	/*
+	 * Skip white space and pick up leading +/- sign if any.
+	 * If base is 0, allow 0x for hex and 0 for octal, else
+	 * assume decimal; if base is already 16, allow 0x.
+	 */
+	do {
+		c = *s++;
+	} while (ISSPACE(c));
+	if (c == '-') {
+		neg = 1;
+		c = *s++;
+	} else if (c == '+')
+		c = *s++;
+	if ((base == 0 || base == 16) &&
+	    c == '0' && (*s == 'x' || *s == 'X')) {
+		c = s[1];
+		s += 2;
+		base = 16;
+	}
+	if (base == 0)
+		base = c == '0' ? 8 : 10;
+
+	/*
+	 * Compute the cutoff value between legal numbers and illegal
+	 * numbers.  That is the largest legal value, divided by the
+	 * base.  An input number that is greater than this value, if
+	 * followed by a legal input character, is too big.  One that
+	 * is equal to this value may be valid or not; the limit
+	 * between valid and invalid numbers is then based on the last
+	 * digit.  For instance, if the range for longs is
+	 * [-2147483648..2147483647] and the input base is 10,
+	 * cutoff will be set to 214748364 and cutlim to either
+	 * 7 (neg==0) or 8 (neg==1), meaning that if we have accumulated
+	 * a value > 214748364, or equal but the next digit is > 7 (or 8),
+	 * the number is too big, and we will return a range error.
+	 *
+	 * Set any if any `digits' consumed; make it negative to indicate
+	 * overflow.
+	 */
+	cutoff = neg ? -(ullong_type)LLONG_MIN : LLONG_MAX;
+	cutlim = cutoff % (ullong_type)base;
+	cutoff /= (ullong_type)base;
+	for (acc = 0, any = 0;; c = *s++) {
+		if (ISDIGIT(c))
+			c -= '0';
+		else if (ISALPHA(c))
+			c -= ISUPPER(c) ? 'A' - 10 : 'a' - 10;
+		else
+			break;
+		if (c >= base)
+			break;
+		if (any < 0 || acc > cutoff || (acc == cutoff && c > cutlim))
+			any = -1;
+		else {
+			any = 1;
+			acc *= base;
+			acc += c;
+		}
+	}
+	if (any < 0) {
+		acc = neg ? LLONG_MIN : LLONG_MAX;
+		errno = ERANGE;
+	} else if (neg)
+		acc = -acc;
+	if (endptr != 0)
+		*endptr = (char *) (any ? s - 1 : nptr);
+	return (acc);
+}
+
+#endif /* ifdef HAVE_LONG_LONG */
diff --git a/libiberty/strtoull.c b/libiberty/strtoull.c
new file mode 100644
index 0000000..2f580fb
--- /dev/null
+++ b/libiberty/strtoull.c
@@ -0,0 +1,122 @@
+/*
+ * Copyright (c) 2014 Regents of the University of California.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. [rescinded 22 July 1999]
+ * 4. Neither the name of the University nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+#ifdef HAVE_LIMITS_H
+#include <limits.h>
+#endif
+#ifdef HAVE_SYS_PARAM_H
+#include <sys/param.h>
+#endif
+#include <errno.h>
+#ifdef NEED_DECLARATION_ERRNO
+extern int errno;
+#endif
+#if 0
+#include <stdlib.h>
+#endif
+#include "ansidecl.h"
+#include "safe-ctype.h"
+
+#ifdef HAVE_LONG_LONG
+
+__extension__
+typedef unsigned long long ullong_type;
+
+#ifndef ULLONG_MAX
+#define ULLONG_MAX (~(ullong_type)0) /* 0xFFFFFFFFFFFFFFFF */
+#endif
+
+/*
+ * Convert a string to an unsigned long long integer.
+ *
+ * Ignores `locale' stuff.  Assumes that the upper and lower case
+ * alphabets and digits are each contiguous.
+ */
+ullong_type
+strtoull(const char *nptr, char **endptr, register int base)
+{
+	register const char *s = nptr;
+	register ullong_type acc;
+	register int c;
+	register ullong_type cutoff;
+	register int neg = 0, any, cutlim;
+
+	/*
+	 * See strtol for comments as to the logic used.
+	 */
+	do {
+		c = *s++;
+	} while (ISSPACE(c));
+	if (c == '-') {
+		neg = 1;
+		c = *s++;
+	} else if (c == '+')
+		c = *s++;
+	if ((base == 0 || base == 16) &&
+	    c == '0' && (*s == 'x' || *s == 'X')) {
+		c = s[1];
+		s += 2;
+		base = 16;
+	}
+	if (base == 0)
+		base = c == '0' ? 8 : 10;
+	cutoff = (ullong_type)ULLONG_MAX / (ullong_type)base;
+	cutlim = (ullong_type)ULLONG_MAX % (ullong_type)base;
+	for (acc = 0, any = 0;; c = *s++) {
+		if (ISDIGIT(c))
+			c -= '0';
+		else if (ISALPHA(c))
+			c -= ISUPPER(c) ? 'A' - 10 : 'a' - 10;
+		else
+			break;
+		if (c >= base)
+			break;
+		if (any < 0 || acc > cutoff || (acc == cutoff && c > cutlim))
+			any = -1;
+		else {
+			any = 1;
+			acc *= base;
+			acc += c;
+		}
+	}
+	if (any < 0) {
+		acc = ULLONG_MAX;
+		errno = ERANGE;
+	} else if (neg)
+		acc = -acc;
+	if (endptr != 0)
+		*endptr = (char *) (any ? s - 1 : nptr);
+	return (acc);
+}
+
+#endif /* ifdef HAVE_LONG_LONG */
diff --git a/libiberty/testsuite/Makefile.in b/libiberty/testsuite/Makefile.in
index bb2db67..4324a8f 100644
--- a/libiberty/testsuite/Makefile.in
+++ b/libiberty/testsuite/Makefile.in
@@ -45,7 +45,8 @@ all:
 # CHECK is set to "really_check" or the empty string by configure.
 check: @CHECK@
 
-really-check: check-cplus-dem check-d-demangle check-pexecute check-expandargv
+really-check: check-cplus-dem check-d-demangle check-pexecute check-expandargv \
+		check-strtol
 
 # Run some tests of the demangler.
 check-cplus-dem: test-demangle $(srcdir)/demangle-expected
@@ -62,6 +63,10 @@ check-pexecute: test-pexecute
 check-expandargv: test-expandargv
 	./test-expandargv
 
+# Check the strtol functionality
+check-strtol: test-strtol
+	./test-strtol
+
 # Run the demangler fuzzer
 fuzz-demangler: demangler-fuzzer
 	./demangler-fuzzer
@@ -79,6 +84,10 @@ test-expandargv: $(srcdir)/test-expandargv.c ../libiberty.a
 	$(TEST_COMPILE) -DHAVE_CONFIG_H -I.. -o test-expandargv \
 		$(srcdir)/test-expandargv.c ../libiberty.a
 
+test-strtol: $(srcdir)/test-strtol.c ../libiberty.a
+	$(TEST_COMPILE) -DHAVE_CONFIG_H -I.. -o test-strtol \
+		$(srcdir)/test-strtol.c ../libiberty.a
+
 demangler-fuzzer: $(srcdir)/demangler-fuzzer.c ../libiberty.a
 	$(TEST_COMPILE) -o demangler-fuzzer \
 		$(srcdir)/demangler-fuzzer.c ../libiberty.a
@@ -92,6 +101,7 @@ mostlyclean:
 	rm -f test-demangle
 	rm -f test-pexecute
 	rm -f test-expandargv
+	rm -f test-strtol
 	rm -f demangler-fuzzer
 	rm -f core
 clean: mostlyclean
diff --git a/libiberty/testsuite/test-strtol.c b/libiberty/testsuite/test-strtol.c
new file mode 100644
index 0000000..96d6871
--- /dev/null
+++ b/libiberty/testsuite/test-strtol.c
@@ -0,0 +1,184 @@
+/* Test program for strtol family of funtions,
+   Copyright (C) 2014 Free Software Foundation, Inc.
+   Written by Yury Gribov <y.gribov@samsung.com>
+
+   This file is part of the libiberty library, which is part of GCC.
+
+   This file is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2 of the License, or
+   (at your option) any later version.
+
+   In addition to the permissions in the GNU General Public License, the
+   Free Software Foundation gives you unlimited permission to link the
+   compiled version of this file into combinations with other programs,
+   and to distribute those combinations without any restriction coming
+   from the use of this file.  (The General Public License restrictions
+   do apply in other respects; for example, they cover modification of
+   the file, and distribution when not linked into a combined
+   executable.)
+
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program; if not, write to the Free Software
+   Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA. 
+*/
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+#include "libiberty.h"
+#include <stdio.h>
+#include <errno.h>
+#ifdef HAVE_STDLIB_H
+#include <stdlib.h>
+#endif
+#ifdef HAVE_STRING_H
+#include <string.h>
+#endif
+#ifdef HAVE_UNISTD_H
+#include <unistd.h>
+#endif
+
+#ifndef EXIT_SUCCESS
+#define EXIT_SUCCESS 0
+#endif
+
+#ifndef EXIT_FAILURE
+#define EXIT_FAILURE 1
+#endif
+
+
+/* Test input data. */
+
+enum conversion_fun
+{
+  STRTOL,
+  STRTOLL,
+  STRTOUL,
+  STRTOULL,
+};
+
+#ifdef HAVE_LONG_LONG
+typedef unsigned long long integer_type;
+#else
+typedef unsigned long integer_type;
+#endif
+
+struct test_data_t
+{
+  enum conversion_fun fun;
+  const char *nptr;
+  int base;
+  integer_type res;
+  int errnum;
+};
+
+const struct test_data_t test_data[] = {
+  { STRTOL,  "0x123",       0, 0x123L,        0      },
+  { STRTOL,  "123",         0, 123L,          0      },
+  { STRTOL,  "0123",        0, 0123L,         0      },
+  { STRTOL,  "0x7FFFFFFF",  0, 0x7fffffffL,   0      },
+  { STRTOL,  "-0x80000000", 0, -0x80000000L,  0      },
+  { STRTOUL, "0x123",       0, 0x123UL,       0      },
+  { STRTOUL, "123",         0, 123UL,         0      },
+  { STRTOUL, "0123",        0, 0123UL,        0      },
+  { STRTOUL, "0xFFFFFFFF",  0, 0xffffffffUL,  0      },
+#if SIZEOF_LONG == 4
+  { STRTOL,  "0x80000000",  0, 0x7fffffffL,   ERANGE },
+  { STRTOL,  "-0x80000001", 0, -0x80000000L,  ERANGE },
+  { STRTOUL, "0x100000000", 0, 0xffffffffUL,  ERANGE },
+#endif
+#ifdef HAVE_LONG_LONG
+  { STRTOLL,  "0x123",               0, 0x123LL,               0      },
+  { STRTOLL,  "123",                 0, 123LL,                 0      },
+  { STRTOLL,  "0123",                0, 0123LL,                0      },
+  { STRTOLL,  "0x7FFFFFFFFFFFFFFF",  0, 0x7fffffffffffffffLL,  0      },
+  { STRTOLL,  "-0x8000000000000000", 0, -0x8000000000000000LL, 0      },
+  { STRTOULL, "0x123",               0, 0x123ULL,              0      },
+  { STRTOULL, "123",                 0, 123ULL,                0      },
+  { STRTOULL, "0123",                0, 0123ULL,               0      },
+  { STRTOULL, "0xFFFFFFFFFFFFFFFF",  0, 0xffffffffffffffffULL, 0      },
+#if SIZEOF_LONG_LONG == 8
+  { STRTOLL,  "0x8000000000000000",  0, 0x7fffffffffffffffLL,  ERANGE },
+  { STRTOLL,  "-0x8000000000000001", 0, -0x8000000000000000LL, ERANGE },
+  { STRTOULL, "0x10000000000000000", 0, 0xffffffffffffffffULL, ERANGE },
+#endif
+#endif
+};
+
+/* run_tests:
+    Run conversion function
+    Compare results
+    Return number of fails */
+
+int
+run_tests (const struct test_data_t *test_data, size_t ntests)
+{
+  int fails = 0, failed;
+  size_t i;
+
+  for (i = 0; i < ntests; ++i)
+    {
+      integer_type res;
+      int saved_errno;
+
+      errno = 0;
+
+      switch (test_data[i].fun)
+	{
+	case STRTOL:
+	  res = strtol (test_data[i].nptr, 0, test_data[i].base);
+	  break;
+	case STRTOUL:
+	  res = strtoul (test_data[i].nptr, 0, test_data[i].base);
+	  break;
+#ifdef HAVE_LONG_LONG
+	case STRTOLL:
+	  res = strtoll (test_data[i].nptr, 0, test_data[i].base);
+	  break;
+	case STRTOULL:
+	  res = strtoull (test_data[i].nptr, 0, test_data[i].base);
+	  break;
+#endif
+	}
+
+      saved_errno = errno;
+
+      failed = 0;
+
+      /* Compare result */
+      if (res != test_data[i].res)
+        {
+          printf ("FAIL: test-strtol-%zd. Results don't match.\n", i);
+	  failed++;
+        }
+
+      /* Compare errno */
+      if (saved_errno != test_data[i].errnum)
+        {
+          printf ("FAIL: test-strtol-%zd. Errnos don't match.\n", i);
+	  failed++;
+        }
+
+      if (!failed)
+        printf ("PASS: test-strtol-%zd.\n", i);
+      else
+        fails++;
+    }
+
+  return fails;
+}
+
+int 
+main(int argc, char **argv)
+{
+  int fails;
+  fails = run_tests (test_data, sizeof (test_data) / sizeof (test_data[0]));
+  exit (fails ? EXIT_FAILURE : EXIT_SUCCESS);
+}
+
-- 
1.7.9.5


[-- Attachment #3: 0002-Allow-to-override-Asan-shadow-offset.patch --]
[-- Type: text/x-patch, Size: 7982 bytes --]

From f5a6525be7b7e37ce1c34ca538001fc2b8e6194e Mon Sep 17 00:00:00 2001
From: Yury Gribov <y.gribov@samsung.com>
Date: Fri, 29 Aug 2014 11:58:03 +0400
Subject: [PATCH 2/2] Allow to override Asan shadow offset.

2014-10-17  Yury Gribov  <y.gribov@samsung.com>

gcc/
	* asan.c (set_asan_shadow_offset): New function.
	(asan_shadow_offset): Likewise.
	(asan_emit_stack_protection): Call asan_shadow_offset.
	(build_shadow_mem_access): Likewise.
	* asan.h (set_asan_shadow_offset): Declare.
	* common.opt (fasan-shadow-offset): New option.
	* doc/invoke.texi (fasan-shadow-offset): Describe new option.
	* opts-global.c (handle_common_deferred_options): Handle
	-fasan-shadow-offset.
	* opts.c (common_handle_option): Likewise.

gcc/testsuite/
	* c-c++-common/asan/shadow-offset-1.c: New test.
---
 gcc/asan.c                                        |   43 +++++++++++++++++++--
 gcc/asan.h                                        |    4 +-
 gcc/common.opt                                    |    4 ++
 gcc/doc/invoke.texi                               |    8 +++-
 gcc/opts-global.c                                 |    9 +++++
 gcc/opts.c                                        |    4 ++
 gcc/testsuite/c-c++-common/asan/shadow-offset-1.c |   11 ++++++
 7 files changed, 78 insertions(+), 5 deletions(-)
 create mode 100644 gcc/testsuite/c-c++-common/asan/shadow-offset-1.c

diff --git a/gcc/asan.c b/gcc/asan.c
index 97f0b4c..b4ef022 100644
--- a/gcc/asan.c
+++ b/gcc/asan.c
@@ -238,6 +238,43 @@ along with GCC; see the file COPYING3.  If not see
    A destructor function that calls the runtime asan library function
    _asan_unregister_globals is also installed.  */
 
+static unsigned HOST_WIDE_INT asan_shadow_offset_value;
+static bool asan_shadow_offset_computed;
+
+/* Sets shadow offset to value in string VAL.  */
+
+bool
+set_asan_shadow_offset (const char *val)
+{
+  char *endp;
+  
+  errno = 0;
+#ifdef HAVE_LONG_LONG
+  asan_shadow_offset_value = strtoull (val, &endp, 0);
+#else
+  asan_shadow_offset_value = strtoul (val, &endp, 0);
+#endif
+  if (!(*val != '\0' && *endp == '\0' && errno == 0))
+    return false;
+
+  asan_shadow_offset_computed = true;
+
+  return true;
+}
+
+/* Returns Asan shadow offset.  */
+
+static unsigned HOST_WIDE_INT
+asan_shadow_offset ()
+{
+  if (!asan_shadow_offset_computed)
+    {
+      asan_shadow_offset_computed = true;
+      asan_shadow_offset_value = targetm.asan_shadow_offset ();
+    }
+  return asan_shadow_offset_value;
+}
+
 alias_set_type asan_shadow_set = -1;
 
 /* Pointer types to 1 resp. 2 byte integers in shadow memory.  A separate
@@ -1124,7 +1161,7 @@ asan_emit_stack_protection (rtx base, rtx pbase, unsigned int alignb,
 			      NULL_RTX, 1, OPTAB_DIRECT);
   shadow_base
     = plus_constant (Pmode, shadow_base,
-		     targetm.asan_shadow_offset ()
+		     asan_shadow_offset ()
 		     + (base_align_bias >> ASAN_SHADOW_SHIFT));
   gcc_assert (asan_shadow_set != -1
 	      && (ASAN_RED_ZONE_SIZE >> ASAN_SHADOW_SHIFT) == 4);
@@ -1503,7 +1540,7 @@ insert_if_then_before_iter (gimple cond,
 }
 
 /* Build
-   (base_addr >> ASAN_SHADOW_SHIFT) + targetm.asan_shadow_offset ().  */
+   (base_addr >> ASAN_SHADOW_SHIFT) + asan_shadow_offset ().  */
 
 static tree
 build_shadow_mem_access (gimple_stmt_iterator *gsi, location_t location,
@@ -1520,7 +1557,7 @@ build_shadow_mem_access (gimple_stmt_iterator *gsi, location_t location,
   gimple_set_location (g, location);
   gsi_insert_after (gsi, g, GSI_NEW_STMT);
 
-  t = build_int_cst (uintptr_type, targetm.asan_shadow_offset ());
+  t = build_int_cst (uintptr_type, asan_shadow_offset ());
   g = gimple_build_assign_with_ops (PLUS_EXPR,
 				    make_ssa_name (uintptr_type, NULL),
 				    gimple_assign_lhs (g), t);
diff --git a/gcc/asan.h b/gcc/asan.h
index 198433f..eadf029 100644
--- a/gcc/asan.h
+++ b/gcc/asan.h
@@ -36,7 +36,7 @@ extern gimple_stmt_iterator create_cond_insert_point
 extern alias_set_type asan_shadow_set;
 
 /* Shadow memory is found at
-   (address >> ASAN_SHADOW_SHIFT) + targetm.asan_shadow_offset ().  */
+   (address >> ASAN_SHADOW_SHIFT) + asan_shadow_offset ().  */
 #define ASAN_SHADOW_SHIFT	3
 
 /* Red zone size, stack and global variables are padded by ASAN_RED_ZONE_SIZE
@@ -76,4 +76,6 @@ asan_red_zone_size (unsigned int size)
   return c ? 2 * ASAN_RED_ZONE_SIZE - c : ASAN_RED_ZONE_SIZE;
 }
 
+extern bool set_asan_shadow_offset (const char *);
+
 #endif /* TREE_ASAN */
diff --git a/gcc/common.opt b/gcc/common.opt
index da5250b..ac4e48e 100644
--- a/gcc/common.opt
+++ b/gcc/common.opt
@@ -883,6 +883,10 @@ fsanitize=
 Common Driver Report Joined
 Select what to sanitize
 
+fasan-shadow-offset=
+Common Joined RejectNegative Var(common_deferred_options) Defer
+-fasan-shadow-offset=<string>	Use custom shadow memory offset.
+
 fsanitize-recover=
 Common Report Joined
 After diagnosing undefined behavior attempt to continue execution
diff --git a/gcc/doc/invoke.texi b/gcc/doc/invoke.texi
index c9ca404..a9e4b9c 100644
--- a/gcc/doc/invoke.texi
+++ b/gcc/doc/invoke.texi
@@ -297,7 +297,7 @@ Objective-C and Objective-C++ Dialects}.
 @xref{Debugging Options,,Options for Debugging Your Program or GCC}.
 @gccoptlist{-d@var{letters}  -dumpspecs  -dumpmachine  -dumpversion @gol
 -fsanitize=@var{style} -fsanitize-recover -fsanitize-recover=@var{style} @gol
--fsanitize-undefined-trap-on-error @gol
+-fasan-shadow-offset=@var{string} -fsanitize-undefined-trap-on-error @gol
 -fdbg-cnt-list -fdbg-cnt=@var{counter-value-list} @gol
 -fdisable-ipa-@var{pass_name} @gol
 -fdisable-rtl-@var{pass_name} @gol
@@ -5642,6 +5642,12 @@ While @option{-ftrapv} causes traps for signed overflows to be emitted,
 @option{-fsanitize=undefined} gives a diagnostic message.
 This currently works only for the C family of languages.
 
+@item -fasan-shadow-offset=@var{string}
+@opindex fasan-shadow-offset
+This option forces GCC to use custom shadow offset in AddressSanitizer checks.
+It is useful for experimenting with different shadow memory layouts in
+Kernel AddressSanitizer.
+
 @item -fsanitize-recover@r{[}=@var{opts}@r{]}
 @opindex fsanitize-recover
 @opindex fno-sanitize-recover
diff --git a/gcc/opts-global.c b/gcc/opts-global.c
index 111884b..81c899c 100644
--- a/gcc/opts-global.c
+++ b/gcc/opts-global.c
@@ -42,6 +42,7 @@ along with GCC; see the file COPYING3.  If not see
 #include "toplev.h"
 #include "tree-pass.h"
 #include "context.h"
+#include "asan.h"
 
 typedef const char *const_char_p; /* For DEF_VEC_P.  */
 
@@ -426,6 +427,14 @@ handle_common_deferred_options (void)
 	  stack_limit_rtx = gen_rtx_SYMBOL_REF (Pmode, ggc_strdup (opt->arg));
 	  break;
 
+	case OPT_fasan_shadow_offset_:
+	  if (!(flag_sanitize & SANITIZE_KERNEL_ADDRESS))
+	    error ("-fasan-shadow-offset should only be used "
+		   "with -fsanitize=kernel-address");
+	  if (!set_asan_shadow_offset (opt->arg))
+	     error ("unrecognized shadow offset %qs", opt->arg);
+	  break;
+
 	default:
 	  gcc_unreachable ();
 	}
diff --git a/gcc/opts.c b/gcc/opts.c
index 25f5235..db30b65 100644
--- a/gcc/opts.c
+++ b/gcc/opts.c
@@ -1646,6 +1646,10 @@ common_handle_option (struct gcc_options *opts,
 	break;
       }
 
+    case OPT_fasan_shadow_offset_:
+      /* Deferred.  */
+      break;
+
     case OPT_fsanitize_recover:
       if (value)
 	opts->x_flag_sanitize_recover
diff --git a/gcc/testsuite/c-c++-common/asan/shadow-offset-1.c b/gcc/testsuite/c-c++-common/asan/shadow-offset-1.c
new file mode 100644
index 0000000..2ca0fd6
--- /dev/null
+++ b/gcc/testsuite/c-c++-common/asan/shadow-offset-1.c
@@ -0,0 +1,11 @@
+/* { dg-do compile } */
+/* { dg-options "-fno-sanitize=address -fsanitize=kernel-address --param asan-instrumentation-with-call-threshold=100 -fasan-shadow-offset=12345 -fdump-tree-sanopt" } */
+/* { dg-skip-if "" { *-*-* } { "-flto" } { "" } } */
+ 
+int f (int *p)
+{
+  return *p;
+}
+
+/* { dg-final { scan-tree-dump "12345" "sanopt" }  } */
+/* { dg-final { cleanup-tree-dump "sanopt" } } */
-- 
1.7.9.5


^ permalink raw reply	[flat|nested] 18+ messages in thread

* Re: [PATCHv5][Kasan] Allow to override Asan shadow offset from command line
  2014-10-24 13:58       ` [PATCHv5][Kasan] " Yury Gribov
@ 2014-10-24 14:09         ` Jakub Jelinek
  2014-10-27 16:02         ` Ian Lance Taylor
  2014-11-05 14:50         ` Kirill Yukhin
  2 siblings, 0 replies; 18+ messages in thread
From: Jakub Jelinek @ 2014-10-24 14:09 UTC (permalink / raw)
  To: Yury Gribov, Ian Lance Taylor
  Cc: GCC Patches, Konstantin Serebryany, Dmitry Vyukov, Andrey Ryabinin

On Fri, Oct 24, 2014 at 05:56:37PM +0400, Yury Gribov wrote:
> >From 1882c41de6c8ae53b7e199b3cc655b6f4b31e8fb Mon Sep 17 00:00:00 2001
> From: Yury Gribov <y.gribov@samsung.com>
> Date: Thu, 16 Oct 2014 18:31:10 +0400
> Subject: [PATCH 1/2] Add strtoll and strtoull to libiberty.
> 
> 2014-10-20  Yury Gribov  <y.gribov@samsung.com>
> 
> include/
> 	* libiberty.h (strtol, strtoul, strtoll, strtoull): New prototypes.
> 
> libiberty/
> 	* strtoll.c: New file.
> 	* strtoull.c: New file.
> 	* configure.ac: Add long long checks. Add harness for strtoll and
> 	strtoull. Check decls for strtol, strtoul, strtoll, strtoull.
> 	* Makefile.in (CFILES, CONFIGURED_OFILES): Added strtoll and strtoull.
> 	* config.in: Regenerate.
> 	* configure: Regenerate.
> 	* functions.texi: Regenerate.
> 	* testsuite/Makefile.in (check-strtol): New rule.
> 	(test-strtol): Likewise.
> 	(mostlyclean): Clean up strtol test.
> 	* testsuite/test-strtol.c: New test.

Ian, can you please review this?

> --- a/gcc/common.opt
> +++ b/gcc/common.opt
> @@ -883,6 +883,10 @@ fsanitize=
>  Common Driver Report Joined
>  Select what to sanitize
>  
> +fasan-shadow-offset=
> +Common Joined RejectNegative Var(common_deferred_options) Defer
> +-fasan-shadow-offset=<string>	Use custom shadow memory offset.

Shouldn't that be =<number> or =<address> instead of string?

> --- a/gcc/doc/invoke.texi
> +++ b/gcc/doc/invoke.texi
> @@ -297,7 +297,7 @@ Objective-C and Objective-C++ Dialects}.
>  @xref{Debugging Options,,Options for Debugging Your Program or GCC}.
>  @gccoptlist{-d@var{letters}  -dumpspecs  -dumpmachine  -dumpversion @gol
>  -fsanitize=@var{style} -fsanitize-recover -fsanitize-recover=@var{style} @gol
> --fsanitize-undefined-trap-on-error @gol
> +-fasan-shadow-offset=@var{string} -fsanitize-undefined-trap-on-error @gol

Likewise here, @var{number} instead.

>  -fdbg-cnt-list -fdbg-cnt=@var{counter-value-list} @gol
>  -fdisable-ipa-@var{pass_name} @gol
>  -fdisable-rtl-@var{pass_name} @gol
> @@ -5642,6 +5642,12 @@ While @option{-ftrapv} causes traps for signed overflows to be emitted,
>  @option{-fsanitize=undefined} gives a diagnostic message.
>  This currently works only for the C family of languages.
>  
> +@item -fasan-shadow-offset=@var{string}

And here.

Otherwise looks good to me.

	Jakub

^ permalink raw reply	[flat|nested] 18+ messages in thread

* Re: [PATCHv5][Kasan] Allow to override Asan shadow offset from command line
  2014-10-24 13:58       ` [PATCHv5][Kasan] " Yury Gribov
  2014-10-24 14:09         ` Jakub Jelinek
@ 2014-10-27 16:02         ` Ian Lance Taylor
  2014-11-05 14:50         ` Kirill Yukhin
  2 siblings, 0 replies; 18+ messages in thread
From: Ian Lance Taylor @ 2014-10-27 16:02 UTC (permalink / raw)
  To: Yury Gribov
  Cc: GCC Patches, Konstantin Serebryany, Dmitry Vyukov, Andrey Ryabinin

Yury Gribov <y.gribov@samsung.com> writes:

> --- a/include/libiberty.h
> +++ b/include/libiberty.h
> @@ -655,6 +655,33 @@ extern size_t strnlen (const char *, size_t);
>  extern int strverscmp (const char *, const char *);
>  #endif
>  
> +#if defined(HAVE_DECL_STRTOL) && !HAVE_DECL_STRTOL
> +extern long int strtol (const char *nptr,
> +                        char **endptr, int base);
> +#endif
> +
> +#if defined(HAVE_DECL_STRTOUL) && !HAVE_DECL_STRTOUL
> +extern unsigned long int strtoul (const char *nptr,
> +                                  char **endptr, int base);
> +#endif
> +
> +#if defined(HAVE_DECL_STRTOLL) && !HAVE_DECL_STRTOLL
> +__extension__
> +extern long long int strtoll (const char *nptr,
> +                              char **endptr, int base);
> +#endif
> +
> +#if defined(HAVE_DECL_STRTOULL) && !HAVE_DECL_STRTOULL
> +__extension__
> +extern unsigned long long int strtoull (const char *nptr,
> +                                        char **endptr, int base);
> +#endif


Your patch is otherwise careful to check that only use "long long" if
the compiler supports it.  Here you are not.  I think you need to wrap
the declarations of strtoll and strtoull in

#ifdef HAVE_LONG_LONG

With that change the libiberty/include patch is OK.

Thanks.

Ian

^ permalink raw reply	[flat|nested] 18+ messages in thread

* Re: [PATCHv5][Kasan] Allow to override Asan shadow offset from command line
  2014-10-24 13:58       ` [PATCHv5][Kasan] " Yury Gribov
  2014-10-24 14:09         ` Jakub Jelinek
  2014-10-27 16:02         ` Ian Lance Taylor
@ 2014-11-05 14:50         ` Kirill Yukhin
  2014-11-12 16:22           ` H.J. Lu
  2 siblings, 1 reply; 18+ messages in thread
From: Kirill Yukhin @ 2014-11-05 14:50 UTC (permalink / raw)
  To: Yury Gribov
  Cc: GCC Patches, Konstantin Serebryany, Dmitry Vyukov,
	Andrey Ryabinin, Ian Lance Taylor

Hello,
On 24 Oct 17:56, Yury Gribov wrote:
...
> +const struct test_data_t test_data[] = {
> +  { STRTOL,  "-0x80000000", 0, -0x80000000L,  0      },
...
> +      switch (test_data[i].fun)
> +	{
> +	case STRTOL:
> +	  res = strtol (test_data[i].nptr, 0, test_data[i].base);
> +	  break;
As far as we might have `long long int' on 32-bit, `res' will fail
to compare with corresponding `test_data[i].base'.

Tiny patch fixes it.

--
Thanks, K

diff --git a/libiberty/testsuite/test-strtol.c b/libiberty/testsuite/test-strtol.c
index 96d6871..6faf81b 100644
--- a/libiberty/testsuite/test-strtol.c
+++ b/libiberty/testsuite/test-strtol.c
@@ -132,7 +132,8 @@ run_tests (const struct test_data_t *test_data, size_t ntests)
       switch (test_data[i].fun)
 	{
 	case STRTOL:
-	  res = strtol (test_data[i].nptr, 0, test_data[i].base);
+	  res = (unsigned long) strtol (test_data[i].nptr,
+					0, test_data[i].base);
 	  break;
 	case STRTOUL:
 	  res = strtoul (test_data[i].nptr, 0, test_data[i].base);

^ permalink raw reply	[flat|nested] 18+ messages in thread

* Re: [PATCHv5][Kasan] Allow to override Asan shadow offset from command line
  2014-11-05 14:50         ` Kirill Yukhin
@ 2014-11-12 16:22           ` H.J. Lu
  0 siblings, 0 replies; 18+ messages in thread
From: H.J. Lu @ 2014-11-12 16:22 UTC (permalink / raw)
  To: Kirill Yukhin
  Cc: Yury Gribov, GCC Patches, Konstantin Serebryany, Dmitry Vyukov,
	Andrey Ryabinin, Ian Lance Taylor

On Wed, Nov 5, 2014 at 6:50 AM, Kirill Yukhin <kirill.yukhin@gmail.com> wrote:
> Hello,
> On 24 Oct 17:56, Yury Gribov wrote:
> ...
>> +const struct test_data_t test_data[] = {
>> +  { STRTOL,  "-0x80000000", 0, -0x80000000L,  0      },
> ...
>> +      switch (test_data[i].fun)
>> +     {
>> +     case STRTOL:
>> +       res = strtol (test_data[i].nptr, 0, test_data[i].base);
>> +       break;
> As far as we might have `long long int' on 32-bit, `res' will fail
> to compare with corresponding `test_data[i].base'.
>
> Tiny patch fixes it.
>
> --
> Thanks, K
>
> diff --git a/libiberty/testsuite/test-strtol.c b/libiberty/testsuite/test-strtol.c
> index 96d6871..6faf81b 100644
> --- a/libiberty/testsuite/test-strtol.c
> +++ b/libiberty/testsuite/test-strtol.c
> @@ -132,7 +132,8 @@ run_tests (const struct test_data_t *test_data, size_t ntests)
>        switch (test_data[i].fun)
>         {
>         case STRTOL:
> -         res = strtol (test_data[i].nptr, 0, test_data[i].base);
> +         res = (unsigned long) strtol (test_data[i].nptr,
> +                                       0, test_data[i].base);
>           break;
>         case STRTOUL:
>           res = strtoul (test_data[i].nptr, 0, test_data[i].base);

I am checking it in as an obvious fix.

-- 
H.J.

^ permalink raw reply	[flat|nested] 18+ messages in thread

end of thread, other threads:[~2014-11-12 16:20 UTC | newest]

Thread overview: 18+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2014-09-08 14:29 [PATCH][Kasan] Allow to override Asan shadow offset from command line Yury Gribov
2014-09-15  9:46 ` [PATCH][Kasan][PING] " Yury Gribov
2014-09-18 11:01   ` Jakub Jelinek
2014-09-18 11:05     ` Yury Gribov
2014-09-29 17:21   ` [PATCHv3][Kasan][PING] " Yury Gribov
2014-10-06 11:06     ` [PATCHv3][Kasan][PING^2] " Yury Gribov
2014-10-06 11:17       ` Yury Gribov
2014-10-15 16:19         ` [PATCHv3][Kasan][PING^3] " Yury Gribov
2014-10-15 16:54           ` Jakub Jelinek
2014-10-17  7:59     ` [PATCHv4][Kasan] " Yury Gribov
2014-10-17 11:25       ` Jakub Jelinek
2014-10-17 12:32         ` Ian Lance Taylor
2014-10-21 10:02           ` Yury Gribov
2014-10-24 13:58       ` [PATCHv5][Kasan] " Yury Gribov
2014-10-24 14:09         ` Jakub Jelinek
2014-10-27 16:02         ` Ian Lance Taylor
2014-11-05 14:50         ` Kirill Yukhin
2014-11-12 16:22           ` H.J. Lu

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).