On 10/9/23 22:13, Kito Cheng wrote:
The target attribute which proposed in [1], target attribute allow user
to specify a local setting per-function basis.

The syntax of target attribute is `__attribute__((target("<ATTR-STRING>")))`.

and the syntax of `<ATTR-STRING>` describes below:
```
ATTR-STRING := ATTR-STRING ';' ATTR
              | ATTR

ATTR        := ARCH-ATTR
              | CPU-ATTR
              | TUNE-ATTR

ARCH-ATTR   := 'arch=' EXTENSIONS-OR-FULLARCH

EXTENSIONS-OR-FULLARCH := <EXTENSIONS>
                         | <FULLARCHSTR>

EXTENSIONS             := <EXTENSION> ',' <EXTENSIONS>
                         | <EXTENSION>

FULLARCHSTR            := <full-arch-string>

EXTENSION              := <OP> <EXTENSION-NAME> <VERSION>

OP                     := '+'

VERSION                := [0-9]+ 'p' [0-9]+
                         | [1-9][0-9]*
                         |

EXTENSION-NAME         := Naming rule is defined in RISC-V ISA manual

CPU-ATTR    := 'cpu=' <valid-cpu-name>
TUNE-ATTR   := 'tune=' <valid-tune-name>
```

[1] https://github.com/riscv-non-isa/riscv-c-api-doc/pull/35

gcc/ChangeLog:

        * config.gcc (riscv): Add riscv-target-attr.o.
        * config/riscv/riscv-opts.h (TARGET_MIN_VLEN_OPTS): New.
        * config/riscv/riscv-protos.h (riscv_declare_function_size) New.
        (riscv_option_valid_attribute_p): New.
        (riscv_override_options_internal): New.
        (struct riscv_tune_info): New.
        (riscv_parse_tune): New.
        * config/riscv/riscv-target-attr.cc
        (class riscv_target_attr_parser): New.
        (struct riscv_attribute_info): New.
        (riscv_attributes): New.
        (riscv_target_attr_parser::parse_arch):
        (riscv_target_attr_parser::handle_arch):
        (riscv_target_attr_parser::handle_cpu):
        (riscv_target_attr_parser::handle_tune):
        (riscv_target_attr_parser::update_settings):
        (riscv_process_one_target_attr):
        (num_occurences_in_str):
        (riscv_process_target_attr):
        (riscv_option_valid_attribute_p):
        * config/riscv/riscv.cc: Include target-globals.h and
        riscv-subset.h.
        (struct riscv_tune_info): Move to riscv-protos.h.
        (get_tune_str):
        (riscv_parse_tune):
        (riscv_declare_function_size):
        (riscv_option_override): Build target_option_default_node and
        target_option_current_node.
        (riscv_save_restore_target_globals):
        (riscv_option_restore):
        (riscv_previous_fndecl):
        (riscv_set_current_function): Apply the target attribute.
        (TARGET_OPTION_RESTORE): Define.
        (TARGET_OPTION_VALID_ATTRIBUTE_P): Ditto.
        * config/riscv/riscv.h (SWITCHABLE_TARGET): Define to 1.
        (ASM_DECLARE_FUNCTION_SIZE) Define.
        * config/riscv/riscv.opt (mtune=): Add Save attribute.
        (mcpu=): Ditto.
        (mcmodel=): Ditto.
        * config/riscv/t-riscv: Add build rule for riscv-target-attr.o
        * doc/extend.texi: Add doc for target attribute.

gcc/testsuite/ChangeLog:

        * gcc.target/riscv/target-attr-01.c: New.
        * gcc.target/riscv/target-attr-02.c: Ditto.
        * gcc.target/riscv/target-attr-03.c: Ditto.
        * gcc.target/riscv/target-attr-04.c: Ditto.
        * gcc.target/riscv/target-attr-05.c: Ditto.
        * gcc.target/riscv/target-attr-06.c: Ditto.
        * gcc.target/riscv/target-attr-07.c: Ditto.
        * gcc.target/riscv/target-attr-bad-01.c: Ditto.
        * gcc.target/riscv/target-attr-bad-02.c: Ditto.
        * gcc.target/riscv/target-attr-bad-03.c: Ditto.
        * gcc.target/riscv/target-attr-bad-04.c: Ditto.
        * gcc.target/riscv/target-attr-bad-05.c: Ditto.
        * gcc.target/riscv/target-attr-bad-06.c: Ditto.
        * gcc.target/riscv/target-attr-bad-07.c: Ditto.
        * gcc.target/riscv/target-attr-warning-01.c: Ditto.
        * gcc.target/riscv/target-attr-warning-02.c: Ditto.
        * gcc.target/riscv/target-attr-warning-03.c: Ditto.
I probably would have split the save/restore state out as a separate patch, but it's not a big deal. A bit surprised we didn't already have that (and thus SWITCHABLE_TARGET) enabled already. But no worries about that.



And just so I can do the right thing WRT RISE, what's the state of an implementation for LLVM?




diff --git a/gcc/config/riscv/riscv-target-attr.cc 
b/gcc/config/riscv/riscv-target-attr.cc
new file mode 100644
index 00000000000..33cff2c222f
--- /dev/null
+++ b/gcc/config/riscv/riscv-target-attr.cc

+      /* Parsing the extension list like "+<ext>[,+<ext>]*".  */
+      size_t len = strlen (str);
+      char *str_to_check = (char *) alloca (len + 1);
If STR is under user control, then this could be a potential security issue if they were to provide a crazy long string (at least until we implement stack-clash protection -- next year).

In general we should avoid alloca unless we know the amount of memory consumed is relatively small and we have a high degree of confidence the code isn't going to be called inside a loop (and not inlined into a loop in the caller). I might even go so far as to say no programmer should ever use alloca.

Clearly I spent way too much time in my life fighting security issues resulting from code mis-using alloca, even by folks who write pretty good code in general.




+
+/* Parse ARG_STR which contains the definition of one target attribute.
+   Show appropriate errors if any or return true if the attribute is valid.  */
+
+static bool
+riscv_process_one_target_attr (char *arg_str,
+                              location_t loc,
+                              riscv_target_attr_parser &attr_parser)
+{
+  size_t len = strlen (arg_str);
+
+  if (len == 0)
+    {
+      error_at (loc, "malformed %<target()%> attribute");
+      return false;
+    }
+
+  char *str_to_check = (char *) alloca (len + 1);
alloca again :-)

Generally OK. I would suggest avoiding the allocas. malloc is orders of magnitude slower, but nowhere near as bad from a security standpoint.

Assuming you're agreeable to adjusting the code to avoid alloca, we'll do a quick turnaround on the v3 -- I'll just audit the return paths to make sure we don't leak and we'll be good to go.

jeff

Reply via email to