Matthew Malcomson <matthew.malcom...@arm.com> writes:
> diff --git a/gcc/doc/invoke.texi b/gcc/doc/invoke.texi
> index 
> 5320e6c1e1e3c8d1482c20590049f763e11f8ff0..84050058be8eaa306b07655737e49ea8b6eb21a9
>  100644
> --- a/gcc/doc/invoke.texi
> +++ b/gcc/doc/invoke.texi
> @@ -13709,6 +13709,53 @@ is greater or equal to this number, use callbacks 
> instead of inline checks.
>  E.g. to disable inline code use
>  @option{--param asan-instrumentation-with-call-threshold=0}.
>  
> +@item hwasan-instrument-stack
> +Enable hwasan instrumentation of statically sized stack-allocated variables.
> +This kind of instrumentation is enabled by default when using
> +@option{-fsanitize=hwaddress} and disabled by default when using
> +@option{-fsanitize=kernel-hwaddress}.
> +To disable stack instrumentation use
> +@option{--param hwasan-instrument-stack=0}, and to enable it use
> +@option{--param hwasan-instrument-stack=1}.
> +
> +@item hwasan-random-frame-tag
> +When using stack instrumentation, decide tags for stack variables using a
> +deterministic sequence beginning at a random tag for each frame.  Usually 
> tags
> +are chosen using the same sequence beginning from 1.
> +This is enabled by default for @option{-fsanitize=hwaddress} and unavailable
> +for @option{-fsanitize=kernel-hwaddress}.
> +To disable it use @option{--param hwasan-random-frame-tag=0}.

I think it would be worth clarifying this.  I wasn't sure whether
“Usually tags are chosen…” was describing the “determinstic random
sequence” or whether it was describing the behaviour of
hwasan-random-frame-tag=0.  If it's describing the behaviour of
hwasan-random-frame-tag=0, then I'm not sure “usually” applies,
given that hwasan-random-frame-tag=1 is the default.

> […]
> +@item -fsanitize=kernel-hwaddress
> +@opindex fsanitize=kernel-hwaddress
> +Enable Hardware-assisted AddressSanitizer for compilation of the Linux 
> kernel.
> +Similar to @option{-fsanitize=kernel-address} but using an alternate
> +instrumentation method, and similar to @option{-fsanitize=hwaddress} but with
> +instrumentation differences necessary for compiling the Linux kernel.
> +These differences are to avoid hwasan library initialisation calls and to

initialization

> +account for the stack pointer having a different value in its top byte.
> +Note: This option has different defaults to the 
> @option{-fsanitize=hwaddress}.

texinfo has:

  @quotation Note
  @end quotation

for this, but we don't seem to use it.  Still, I think it would be better
to break the paragraph before Note: and use:

  @emph{Note:}

which seems to be the preferred style in the GCC manual.

> +Instrumenting the stack and alloca calls are not on by default but is still

@code{alloca}
s/is still/are still/

> +possible by specifying it on the command line with

maybe s/it on the command line with/specifying the command-line options/?
Just a suggestion: would be happy with alternatives.

> +@option{--param hwasan-instrument-stack=1} and
> +@option{--param hwasan-instrument-allocas=1}. Using a random frame tag is not

and maybe add a “respectively” at the end of this sentence.

> +implemented for kernel instrumentation.
> +
>  @item -fsanitize=pointer-compare
>  @opindex fsanitize=pointer-compare
>  Instrument comparison operation (<, <=, >, >=) with pointer operands.
> […]
> diff --git a/gcc/opts.c b/gcc/opts.c
> index 
> ac9972d9c386247af3482e07a94c76da3e1abb4d..f3662062c421e1c58c3243109891900eb2dc84bc
>  100644
> --- a/gcc/opts.c
> +++ b/gcc/opts.c
> @@ -823,6 +823,51 @@ control_options_for_live_patching (struct gcc_options 
> *opts,
>  /* --help option argument if set.  */
>  vec<const char *> help_option_arguments;
>  
> +/* Return the string name describing the argument provided on the command 
> line
> +    which has set this particular flag.  */
> +const char *
> +find_argument (struct gcc_options *opts, unsigned int flags)
> +{

I think either (a) the name and comment need to mention the
sanitiser more explicitly or (b) this should be a lambda function
in report_conflicting_sanitizer_options:

  auto find_argument = [&](unsigned int flags)
    {
      …
    };

(in which case the implementation and comments above are fine as-is).

> +  for (int i = 0; sanitizer_opts[i].name != NULL; ++i)
> +    {
> +      /* Need to find the sanitizer_opts element which:
> +      a) Could have set the flags requested.
> +      b) Has been set on the command line.
> +
> +      Can have (a) without (b) if the flag requested is e.g.
> +      SANITIZE_ADDRESS, since both -fsanitize=address and
> +      -fsanitize=kernel-address set this flag.
> +
> +      Can have (b) without (a) by requesting more than one sanitizer on the
> +      command line.  */
> +      if ((sanitizer_opts[i].flag & opts->x_flag_sanitize)
> +       != sanitizer_opts[i].flag)
> +     continue;
> +      if ((sanitizer_opts[i].flag & flags) != flags)
> +     continue;
> +      return sanitizer_opts[i].name;
> +    }
> +  return NULL;
> +}
> +
> +
> +/* Report any conflicting sanitizer options requested.  */
> +static void
> +report_conflicting_sanitizer_options (struct gcc_options *opts, location_t 
> loc,
> +                                   unsigned int left, unsigned int right)

The comment needs to describe at least the “LEFT” and “RIGHT” parameters

> +{
> +  unsigned int left_seen = (opts->x_flag_sanitize & left);
> +  unsigned int right_seen = (opts->x_flag_sanitize & right);
> +  if (left_seen && right_seen)
> +    {
> +      const char* left_arg = find_argument (opts, left_seen);
> +      const char* right_arg = find_argument (opts, right_seen);
> +      gcc_assert (left_arg && right_arg);
> +      error_at (loc,
> +             "%<-fsanitize=%s%> is incompatible with %<-fsanitize=%s%>",
> +             left_arg, right_arg);
> +    }
> +}
>  
>  /* After all options at LOC have been read into OPTS and OPTS_SET,
>     finalize settings of those options and diagnose incompatible
> @@ -1074,22 +1119,21 @@ finish_options (struct gcc_options *opts, struct 
> gcc_options *opts_set,
>                 "%<-fsanitize=address%> or %<-fsanitize=kernel-address%>");
>      }
>  
> -  /* Userspace and kernel ASan conflict with each other.  */
> -  if ((opts->x_flag_sanitize & SANITIZE_USER_ADDRESS)
> -      && (opts->x_flag_sanitize & SANITIZE_KERNEL_ADDRESS))
> -    error_at (loc, "%qs is incompatible with %qs",
> -           "-fsanitize=address", "-fsanitize=kernel-address");
> +  /* Address sanitizers conflict with the thread sanitizer.  */
> +  report_conflicting_sanitizer_options (opts, loc, SANITIZE_THREAD,
> +                                     SANITIZE_ADDRESS | SANITIZE_HWADDRESS);
> +  /* The leak sanitizer conflicts with the thread sanitizer.  */
> +  report_conflicting_sanitizer_options (opts, loc, SANITIZE_LEAK, 
> SANITIZE_THREAD);

Nit: long line.

> […]
> +-param=hwasan-instrument-allocas=
> +Common Joined UInteger Var(param_hwasan_protect_allocas) Init(1) 
> IntegerRange(0, 1) Param Optimization
> +Enable hwasan instrumentation of allocas/VLAs.

It would be good to keep the variable name in sync with the parameter,
so s/protect/instrument/ there too.

> […]
> @@ -6850,6 +6850,17 @@ DEFHOOK
>  HOOK_VECTOR_END (mode_switching)
>  
>  #undef HOOK_PREFIX
> +#define HOOK_PREFIX "TARGET_MEMTAG_"
> +HOOK_VECTOR (TARGET_MEMTAG_, memtag)
> +
> +DEFHOOK
> +(can_tag_addresses,
> + "True if backend architecture naturally supports ignoring some region of\n\
> +pointers.  This feature means that @option{-fsanitize=hwaddress} can work.",

“…if the backend architecture…”

LGTM otherwise, thanks.

Richard

Reply via email to