File gcc7-aarch64-sls-miti-2.patch of Package cross-i386-gcc7.17759

Backport of below commit for bsc#1172798
Also adds the AARCH64_FL_SB support, not originally part of 
this commit.  And the added test sls-miti-retbr.c has -mbranch-protection
removed as that's not supported by our gcc7.

commit dc586a749228ecfb71f72ec2ca10e6f7b6874af3
Author: Matthew Malcomson <matthew.malcomson@arm.com>
Date:   Thu Jul 9 09:11:59 2020 +0100

    aarch64: Introduce SLS mitigation for RET and BR instructions
    
    Instructions following RET or BR are not necessarily executed.  In order
    to avoid speculation past RET and BR we can simply append a speculation
    barrier.
    
    Since these speculation barriers will not be architecturally executed,
    they are not expected to add a high performance penalty.
    
    The speculation barrier is to be SB when targeting architectures which
    have this enabled, and DSB SY + ISB otherwise.
    
    We add tests for each of the cases where such an instruction was seen.
    
    This is implemented by modifying each machine description pattern that
    emits either a RET or a BR instruction.  We choose not to use something
    like `TARGET_ASM_FUNCTION_EPILOGUE` since it does not affect the
    `indirect_jump`, `jump`, `sibcall_insn` and `sibcall_value_insn`
    patterns and we find it preferable to implement the functionality in the
    same way for every pattern.
    
    There is one particular case which is slightly tricky.  The
    implementation of TARGET_ASM_TRAMPOLINE_TEMPLATE uses a BR which needs
    to be mitigated against.  The trampoline template is used *once* per
    compilation unit, and the TRAMPOLINE_SIZE is exposed to the user via the
    builtin macro __LIBGCC_TRAMPOLINE_SIZE__.
    In the future we may implement function specific attributes to turn on
    and off hardening on a per-function basis.
    The fixed nature of the trampoline described above implies it will be
    safer to ensure this speculation barrier is always used.
    
    Testing:
      Bootstrap and regtest done on aarch64-none-linux
      Used a temporary hack(1) to use these options on every test in the
      testsuite and a script to check that the output never emitted an
      unmitigated RET or BR.
    
    1) Temporary hack was a change to the testsuite to always use
    `-save-temps` and run a script on the assembly output of those
    compilations which produced one to ensure every RET or BR is immediately
    followed by a speculation barrier.
    
    (cherry picked from be178ecd5ac1fe1510d960ff95c66d0ff831afe1)
    
    gcc/ChangeLog:
    
            * config/aarch64/aarch64-protos.h (aarch64_sls_barrier): New.
            * config/aarch64/aarch64.c (aarch64_output_casesi): Emit
            speculation barrier after BR instruction if needs be.
            (aarch64_trampoline_init): Handle ptr_mode value & adjust size
            of code copied.
            (aarch64_sls_barrier): New.
            (aarch64_asm_trampoline_template): Add needed barriers.
            * config/aarch64/aarch64.h (AARCH64_ISA_SB): New.
            (TARGET_SB): New.
            (TRAMPOLINE_SIZE): Account for barrier.
            * config/aarch64/aarch64.md (indirect_jump, *casesi_dispatch,
            simple_return, *do_return, *sibcall_insn, *sibcall_value_insn):
            Emit barrier if needs be, also account for possible barrier using
            "sls_length" attribute.
            (sls_length): New attribute.
            (length): Determine default using any non-default sls_length
            value.
    
    gcc/testsuite/ChangeLog:
    
            * gcc.target/aarch64/sls-mitigation/sls-miti-retbr.c: New test.
            * gcc.target/aarch64/sls-mitigation/sls-miti-retbr-pacret.c:
            New test.
            * gcc.target/aarch64/sls-mitigation/sls-mitigation.exp: New file.
            * lib/target-supports.exp (check_effective_target_aarch64_asm_sb_ok):
            New proc.

Index: gcc-7.5.0+r278197/gcc/config/aarch64/aarch64-protos.h
===================================================================
--- gcc-7.5.0+r278197.orig/gcc/config/aarch64/aarch64-protos.h
+++ gcc-7.5.0+r278197/gcc/config/aarch64/aarch64-protos.h
@@ -485,6 +485,7 @@ extern const atomic_ool_names aarch64_oo
 extern const atomic_ool_names aarch64_ool_ldclr_names;
 extern const atomic_ool_names aarch64_ool_ldeor_names;
 
+const char *aarch64_sls_barrier (int);
 extern bool aarch64_harden_sls_retbr_p (void);
 extern bool aarch64_harden_sls_blr_p (void);
 
Index: gcc-7.5.0+r278197/gcc/config/aarch64/aarch64.c
===================================================================
--- gcc-7.5.0+r278197.orig/gcc/config/aarch64/aarch64.c
+++ gcc-7.5.0+r278197/gcc/config/aarch64/aarch64.c
@@ -5736,15 +5736,28 @@ aarch64_asm_trampoline_template (FILE *f
 {
   if (TARGET_ILP32)
     {
-      asm_fprintf (f, "\tldr\tw%d, .+16\n", IP1_REGNUM - R0_REGNUM);
-      asm_fprintf (f, "\tldr\tw%d, .+16\n", STATIC_CHAIN_REGNUM - R0_REGNUM);
+      asm_fprintf (f, "\tldr\tw%d, .+24\n", IP1_REGNUM - R0_REGNUM);
+      asm_fprintf (f, "\tldr\tw%d, .+24\n", STATIC_CHAIN_REGNUM - R0_REGNUM);
     }
   else
     {
-      asm_fprintf (f, "\tldr\t%s, .+16\n", reg_names [IP1_REGNUM]);
-      asm_fprintf (f, "\tldr\t%s, .+20\n", reg_names [STATIC_CHAIN_REGNUM]);
+      asm_fprintf (f, "\tldr\t%s, .+24\n", reg_names [IP1_REGNUM]);
+      asm_fprintf (f, "\tldr\t%s, .+28\n", reg_names [STATIC_CHAIN_REGNUM]);
     }
   asm_fprintf (f, "\tbr\t%s\n", reg_names [IP1_REGNUM]);
+
+  /* We always emit a speculation barrier.
+     This is because the same trampoline template is used for every nested
+     function.  Since nested functions are not particularly common or
+     performant we don't worry too much about the extra instructions to copy
+     around.
+     This is not yet a problem, since we have not yet implemented function
+     specific attributes to choose between hardening against straight line
+     speculation or not, but such function specific attributes are likely to
+     happen in the future.  */
+  asm_fprintf (f, "\tdsb\tsy\n\tisb\n");
+
+  /* Padding for BTI at the beginning, which our gcc-7 backports don't do */
   assemble_aligned_integer (4, const0_rtx);
   assemble_aligned_integer (POINTER_BYTES, const0_rtx);
   assemble_aligned_integer (POINTER_BYTES, const0_rtx);
@@ -5754,10 +5767,14 @@ static void
 aarch64_trampoline_init (rtx m_tramp, tree fndecl, rtx chain_value)
 {
   rtx fnaddr, mem, a_tramp;
-  const int tramp_code_sz = 16;
+  const int tramp_code_sz = 24;
 
   /* Don't need to copy the trailing D-words, we fill those in below.  */
-  emit_block_move (m_tramp, assemble_trampoline_template (),
+  /* We create our own memory address in Pmode so that `emit_block_move` can
+     use parts of the backend which expect Pmode addresses.  */
+  rtx temp = convert_memory_address (Pmode, XEXP (m_tramp, 0));
+  emit_block_move (gen_rtx_MEM (BLKmode, temp),
+		   assemble_trampoline_template (),
 		   GEN_INT (tramp_code_sz), BLOCK_OP_NORMAL);
   mem = adjust_address (m_tramp, ptr_mode, tramp_code_sz);
   fnaddr = XEXP (DECL_RTL (fndecl), 0);
@@ -5936,6 +5953,8 @@ aarch64_output_casesi (rtx *operands)
   output_asm_insn (buf, operands);
   output_asm_insn (patterns[index][1], operands);
   output_asm_insn ("br\t%3", operands);
+  output_asm_insn (aarch64_sls_barrier (aarch64_harden_sls_retbr_p ()),
+		   operands);
   assemble_label (asm_out_file, label);
   return "";
 }
@@ -14664,6 +14683,22 @@ aarch64_sched_can_speculate_insn (rtx_in
     }
 }
 
+/* Helper function for straight line speculation.
+   Return what barrier should be emitted for straight line speculation
+   mitigation.
+   When not mitigating against straight line speculation this function returns
+   an empty string.
+   When mitigating against straight line speculation, use:
+   * SB when the v8.5-A SB extension is enabled.
+   * DSB+ISB otherwise.  */
+const char *
+aarch64_sls_barrier (int mitigation_required)
+{
+  return mitigation_required
+    ? (TARGET_SB ? "sb" : "dsb\tsy\n\tisb")
+    : "";
+}
+
 /* Target-specific selftests.  */
 
 #if CHECKING_P
Index: gcc-7.5.0+r278197/gcc/config/aarch64/aarch64.h
===================================================================
--- gcc-7.5.0+r278197.orig/gcc/config/aarch64/aarch64.h
+++ gcc-7.5.0+r278197/gcc/config/aarch64/aarch64.h
@@ -141,6 +141,9 @@ extern unsigned aarch64_architecture_ver
 /* ARMv8.3-A architecture extensions.  */
 #define AARCH64_FL_V8_3	      (1 << 10)  /* Has ARMv8.3-A features.  */
 
+/* Speculation Barrier instruction supported.  */
+#define AARCH64_FL_SB         (1 << 25)
+
 /* Has FP and SIMD.  */
 #define AARCH64_FL_FPSIMD     (AARCH64_FL_FP | AARCH64_FL_SIMD)
 
@@ -168,6 +171,8 @@ extern unsigned aarch64_architecture_ver
 #define AARCH64_ISA_F16		   (aarch64_isa_flags & AARCH64_FL_F16)
 #define AARCH64_ISA_V8_3	   (aarch64_isa_flags & AARCH64_FL_V8_3)
 
+#define AARCH64_ISA_SB		   (aarch64_isa_flags & AARCH64_FL_SB)
+
 /* Crypto is an optional extension to AdvSIMD.  */
 #define TARGET_CRYPTO (TARGET_SIMD && AARCH64_ISA_CRYPTO)
 
@@ -193,6 +198,9 @@ extern unsigned aarch64_architecture_ver
 #define TARGET_FIX_ERR_A53_835769_DEFAULT 1
 #endif
 
+/* SB instruction is enabled through +sb.  */
+#define TARGET_SB (AARCH64_ISA_SB)
+
 /* Apply the workaround for Cortex-A53 erratum 835769.  */
 #define TARGET_FIX_ERR_A53_835769	\
   ((aarch64_fix_a53_err835769 == 2)	\
@@ -805,8 +813,10 @@ typedef struct
 
 #define RETURN_ADDR_RTX aarch64_return_addr
 
-/* 3 insns + padding + 2 pointer-sized entries.  */
-#define TRAMPOLINE_SIZE	(TARGET_ILP32 ? 24 : 32)
+/* BTI c + 3 insns
+   + sls barrier of DSB + ISB.
+   + 2 pointer-sized entries.  */
+#define TRAMPOLINE_SIZE	(24 + (TARGET_ILP32 ? 8 : 16))
 
 /* Trampolines contain dwords, so must be dword aligned.  */
 #define TRAMPOLINE_ALIGNMENT 64
Index: gcc-7.5.0+r278197/gcc/config/aarch64/aarch64.md
===================================================================
--- gcc-7.5.0+r278197.orig/gcc/config/aarch64/aarch64.md
+++ gcc-7.5.0+r278197/gcc/config/aarch64/aarch64.md
@@ -187,8 +187,23 @@
 ;; will be disabled when !TARGET_SIMD.
 (define_attr "simd" "no,yes" (const_string "no"))
 
+;; Attribute to specify that an alternative has the length of a single
+;; instruction plus a speculation barrier.
+(define_attr "sls_length" "none,retbr,casesi" (const_string "none"))
+
 (define_attr "length" ""
-  (const_int 4))
+  (cond [
+	 (eq_attr "sls_length" "retbr")
+	   (cond [(match_test "!aarch64_harden_sls_retbr_p ()") (const_int 4)
+		  (match_test "TARGET_SB") (const_int 8)]
+		 (const_int 12))
+
+	 (eq_attr "sls_length" "casesi")
+	   (cond [(match_test "!aarch64_harden_sls_retbr_p ()") (const_int 16)
+		  (match_test "TARGET_SB") (const_int 20)]
+		 (const_int 24))
+	]
+	  (const_int 4)))
 
 ;; Attribute that controls whether an alternative is enabled or not.
 ;; Currently it is only used to disable alternatives which touch fp or simd
@@ -235,8 +250,12 @@
 (define_insn "indirect_jump"
   [(set (pc) (match_operand:DI 0 "register_operand" "r"))]
   ""
-  "br\\t%0"
-  [(set_attr "type" "branch")]
+  {
+    output_asm_insn ("br\\t%0", operands);
+    return aarch64_sls_barrier (aarch64_harden_sls_retbr_p ());
+  }
+  [(set_attr "type" "branch")
+   (set_attr "sls_length" "retbr")]
 )
 
 (define_insn "jump"
@@ -508,7 +527,7 @@
   "*
   return aarch64_output_casesi (operands);
   "
-  [(set_attr "length" "16")
+  [(set_attr "sls_length" "casesi")
    (set_attr "type" "branch")]
 )
 
@@ -583,14 +602,18 @@
   [(return)]
   ""
   {
+    const char *ret = NULL;
     if (aarch64_return_address_signing_enabled ()
 	&& TARGET_ARMV8_3
 	&& !crtl->calls_eh_return)
-      return "retaa";
-
-    return "ret";
+      ret = "retaa";
+    else
+      ret = "ret";
+    output_asm_insn (ret, operands);
+    return aarch64_sls_barrier (aarch64_harden_sls_retbr_p ());
   }
-  [(set_attr "type" "branch")]
+  [(set_attr "type" "branch")
+   (set_attr "sls_length" "retbr")]
 )
 
 (define_expand "return"
@@ -602,8 +625,12 @@
 (define_insn "simple_return"
   [(simple_return)]
   ""
-  "ret"
-  [(set_attr "type" "branch")]
+  {
+    output_asm_insn ("ret", operands);
+    return aarch64_sls_barrier (aarch64_harden_sls_retbr_p ());
+  }
+  [(set_attr "type" "branch")
+   (set_attr "sls_length" "retbr")]
 )
 
 (define_insn "*cb<optab><mode>1"
@@ -903,10 +930,16 @@
    (return)
    (use (match_operand 2 "" ""))]
   "SIBLING_CALL_P (insn)"
-  "@
-   br\\t%0
-   b\\t%a0"
-  [(set_attr "type" "branch, branch")]
+  {
+    if (which_alternative == 0)
+      {
+	output_asm_insn ("br\\t%0", operands);
+	return aarch64_sls_barrier (aarch64_harden_sls_retbr_p ());
+      }
+    return "b\\t%c0";
+  }
+  [(set_attr "type" "branch, branch")
+   (set_attr "sls_length" "retbr,none")]
 )
 
 (define_insn "*sibcall_value_insn"
@@ -917,10 +950,16 @@
    (return)
    (use (match_operand 3 "" ""))]
   "SIBLING_CALL_P (insn)"
-  "@
-   br\\t%1
-   b\\t%a1"
-  [(set_attr "type" "branch, branch")]
+  {
+    if (which_alternative == 0)
+      {
+	output_asm_insn ("br\\t%1", operands);
+	return aarch64_sls_barrier (aarch64_harden_sls_retbr_p ());
+      }
+    return "b\\t%c1";
+  }
+  [(set_attr "type" "branch, branch")
+   (set_attr "sls_length" "retbr,none")]
 )
 
 ;; Call subroutine returning any type.
Index: gcc-7.5.0+r278197/gcc/testsuite/gcc.target/aarch64/sls-mitigation/sls-miti-retbr-pacret.c
===================================================================
--- /dev/null
+++ gcc-7.5.0+r278197/gcc/testsuite/gcc.target/aarch64/sls-mitigation/sls-miti-retbr-pacret.c
@@ -0,0 +1,15 @@
+/* Avoid ILP32 since pacret is only available for LP64 */
+/* { dg-do compile { target { ! ilp32 } } } */
+/* { dg-additional-options "-mharden-sls=retbr -march=armv8.3-a" } */
+
+/* Testing the do_return pattern for retaa.  */
+long retbr_subcall(void);
+long retbr_do_return_retaa(void)
+{
+    return retbr_subcall()+1;
+}
+
+/* Ensure there are no BR or RET instructions which are not directly followed
+   by a speculation barrier.  */
+/* { dg-final { scan-assembler-not {\t(br|ret|retaa)\tx[0-9][0-9]?\n\t(?!dsb\tsy\n\tisb)} } } */
+/* { dg-final { scan-assembler-not {ret\t} } } */
Index: gcc-7.5.0+r278197/gcc/testsuite/gcc.target/aarch64/sls-mitigation/sls-miti-retbr.c
===================================================================
--- /dev/null
+++ gcc-7.5.0+r278197/gcc/testsuite/gcc.target/aarch64/sls-mitigation/sls-miti-retbr.c
@@ -0,0 +1,119 @@
+/* We ensure that -Wpedantic is off since it complains about the trampolines
+   we explicitly want to test.  */
+/* { dg-additional-options "-mharden-sls=retbr -Wno-pedantic " } */
+/*
+   Ensure that the SLS hardening of RET and BR leaves no unprotected RET/BR
+   instructions.
+  */
+typedef int (foo) (int, int);
+typedef void (bar) (int, int);
+struct sls_testclass {
+    foo *x;
+    bar *y;
+    int left;
+    int right;
+};
+
+int
+retbr_sibcall_value_insn (struct sls_testclass x)
+{
+  return x.x(x.left, x.right);
+}
+
+void
+retbr_sibcall_insn (struct sls_testclass x)
+{
+  x.y(x.left, x.right);
+}
+
+/* Aim to test two different returns.
+   One that introduces a tail call in the middle of the function, and one that
+   has a normal return.  */
+int
+retbr_multiple_returns (struct sls_testclass x)
+{
+  int temp;
+  if (x.left % 10)
+    return x.x(x.left, 100);
+  else if (x.right % 20)
+    {
+      return x.x(x.left * x.right, 100);
+    }
+  temp = x.left % x.right;
+  temp *= 100;
+  temp /= 2;
+  return temp % 3;
+}
+
+void
+retbr_multiple_returns_void (struct sls_testclass x)
+{
+  if (x.left % 10)
+    {
+      x.y(x.left, 100);
+    }
+  else if (x.right % 20)
+    {
+      x.y(x.left * x.right, 100);
+    }
+  return;
+}
+
+/* Testing the casesi jump via register.  */
+__attribute__ ((optimize ("Os")))
+int
+retbr_casesi_dispatch (struct sls_testclass x)
+{
+  switch (x.left)
+    {
+    case -5:
+      return -2;
+    case -3:
+      return -1;
+    case 0:
+      return 0;
+    case 3:
+      return 1;
+    case 5:
+      break;
+    default:
+      __builtin_unreachable ();
+    }
+  return x.right;
+}
+
+/* Testing the BR in trampolines is mitigated against.  */
+void f1 (void *);
+void f3 (void *, void (*)(void *));
+void f2 (void *);
+
+int
+retbr_trampolines (void *a, int b)
+{
+  if (!b)
+    {
+      f1 (a);
+      return 1;
+    }
+  if (b)
+    {
+      void retbr_tramp_internal (void *c)
+      {
+	if (c == a)
+	  f2 (c);
+      }
+      f3 (a, retbr_tramp_internal);
+    }
+  return 0;
+}
+
+/* Testing the indirect_jump pattern.  */
+void
+retbr_indirect_jump (int *buf)
+{
+  __builtin_longjmp(buf, 1);
+}
+
+/* Ensure there are no BR or RET instructions which are not directly followed
+   by a speculation barrier.  */
+/* { dg-final { scan-assembler-not {\t(br|ret|retaa)\tx[0-9][0-9]?\n\t(?!dsb\tsy\n\tisb|sb)} } } */
Index: gcc-7.5.0+r278197/gcc/testsuite/gcc.target/aarch64/sls-mitigation/sls-mitigation.exp
===================================================================
--- /dev/null
+++ gcc-7.5.0+r278197/gcc/testsuite/gcc.target/aarch64/sls-mitigation/sls-mitigation.exp
@@ -0,0 +1,73 @@
+#  Regression driver for SLS mitigation on AArch64.
+#  Copyright (C) 2020 Free Software Foundation, Inc.
+#  Contributed by ARM Ltd.
+#
+#  This file is part of GCC.
+#
+#  GCC 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 3, or (at your option)
+#  any later version.
+#
+#  GCC 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 GCC; see the file COPYING3.  If not see
+#  <http://www.gnu.org/licenses/>.  */
+
+# Exit immediately if this isn't an AArch64 target.
+if {![istarget aarch64*-*-*] } then {
+  return
+}
+
+# Load support procs.
+load_lib gcc-dg.exp
+load_lib torture-options.exp
+
+# If a testcase doesn't have special options, use these.
+global DEFAULT_CFLAGS
+if ![info exists DEFAULT_CFLAGS] then {
+    set DEFAULT_CFLAGS " "
+}
+
+# Initialize `dg'.
+dg-init
+torture-init
+
+# Use different architectures as well as the normal optimisation options.
+# (i.e. use both SB and DSB+ISB barriers).
+
+set save-dg-do-what-default ${dg-do-what-default}
+# Main loop.
+# Run with torture tests (i.e. a bunch of different optimisation levels) just
+# to increase test coverage.
+set dg-do-what-default assemble
+gcc-dg-runtest [lsort [glob -nocomplain $srcdir/$subdir/*.\[cCS\]]] \
+	"-save-temps" $DEFAULT_CFLAGS
+
+# Run the same tests but this time with SB extension.
+# Since not all supported assemblers will support that extension we decide
+# whether to assemble or just compile based on whether the extension is
+# supported for the available assembler.
+
+set templist {}
+foreach x $DG_TORTURE_OPTIONS {
+  lappend templist "$x -march=armv8.3-a+sb "
+  lappend templist "$x -march=armv8-a+sb "
+}
+set-torture-options $templist
+if { [check_effective_target_aarch64_asm_sb_ok] } {
+    set dg-do-what-default assemble
+} else {
+    set dg-do-what-default compile
+}
+gcc-dg-runtest [lsort [glob -nocomplain $srcdir/$subdir/*.\[cCS\]]] \
+	"-save-temps" $DEFAULT_CFLAGS
+set dg-do-what-default ${save-dg-do-what-default}
+
+# All done.
+torture-finish
+dg-finish
Index: gcc-7.5.0+r278197/gcc/testsuite/lib/target-supports.exp
===================================================================
--- gcc-7.5.0+r278197.orig/gcc/testsuite/lib/target-supports.exp
+++ gcc-7.5.0+r278197/gcc/testsuite/lib/target-supports.exp
@@ -7929,7 +7929,7 @@ proc check_effective_target_aarch64_tiny
 # Create functions to check that the AArch64 assembler supports the
 # various architecture extensions via the .arch_extension pseudo-op.
 
-foreach { aarch64_ext } { "fp" "simd" "crypto" "crc" "lse"} {
+foreach { aarch64_ext } { "fp" "simd" "crypto" "crc" "lse" "sb"} {
     eval [string map [list FUNC $aarch64_ext] {
 	proc check_effective_target_aarch64_asm_FUNC_ok { } {
 	  if { [istarget aarch64*-*-*] } {
Index: gcc-7.5.0+r278197/gcc/config/aarch64/aarch64-option-extensions.def
===================================================================
--- gcc-7.5.0+r278197.orig/gcc/config/aarch64/aarch64-option-extensions.def
+++ gcc-7.5.0+r278197/gcc/config/aarch64/aarch64-option-extensions.def
@@ -60,4 +60,7 @@ AARCH64_OPT_EXTENSION("lse", AARCH64_FL_
    Disabling "fp16" just disables "fp16".  */
 AARCH64_OPT_EXTENSION("fp16", AARCH64_FL_F16, AARCH64_FL_FP, 0, "fphp asimdhp")
 
+/* Enabling/Disabling "sb" only changes "sb".  */
+AARCH64_OPT_EXTENSION("sb", AARCH64_FL_SB, 0, 0, "sb")
+
 #undef AARCH64_OPT_EXTENSION
openSUSE Build Service is sponsored by