summaryrefslogtreecommitdiff
path: root/test
diff options
context:
space:
mode:
authorDominic Chen <d.c.ddcc@gmail.com>2016-08-02 18:01:26 -0700
committerDerek Schuff <dschuff@chromium.org>2016-08-02 18:01:26 -0700
commit959bc7638aebb27fcdf7079daf0d0cafe845f56a (patch)
treeb828306bed585ccda4102219c187fd8dbbe08eaf /test
parent4268555dfd7887ff1110fb02717807f42616125e (diff)
downloadbinaryen-959bc7638aebb27fcdf7079daf0d0cafe845f56a.tar.gz
binaryen-959bc7638aebb27fcdf7079daf0d0cafe845f56a.tar.bz2
binaryen-959bc7638aebb27fcdf7079daf0d0cafe845f56a.zip
support pre-assigning indexes for functions that are called indirectly (#616)
This patch adds support for an ".indidx" primitive that pre-assigns table indexes for functions that are called indirectly. It is used by the upstream LLVM WebAssembly backend to support fine-grained control-flow integrity for indirect function calls by emitting instrumentation at each indirect call site to check that the destination index is within certain ranges that correspond to disjoint equivalence classes of indirect call targets. The reason that this primitive is necessary is because the layout of the table section isn't determined until the WebAssembly linker is executed, but indirect function to table index mappings need to be known when opt is executed to generate the correct range checking in the LLVM IR.
Diffstat (limited to 'test')
-rw-r--r--test/dot_s/indidx.s93
-rw-r--r--test/dot_s/indidx.wast57
2 files changed, 150 insertions, 0 deletions
diff --git a/test/dot_s/indidx.s b/test/dot_s/indidx.s
new file mode 100644
index 000000000..4ebd28af1
--- /dev/null
+++ b/test/dot_s/indidx.s
@@ -0,0 +1,93 @@
+ .text
+ .file "cfi-wasm.bs.bc"
+ .type a,@function
+a: # @a
+ .indidx 3
+ .result i32
+# BB#0: # %entry
+ i32.const $push0=, 0
+ # fallthrough-return: $pop0
+ .endfunc
+.Lfunc_end0:
+ .size a, .Lfunc_end0-a
+
+ .type b,@function
+b: # @b
+ .indidx 1
+ .result i32
+# BB#0: # %entry
+ i32.const $push0=, 1
+ # fallthrough-return: $pop0
+ .endfunc
+.Lfunc_end1:
+ .size b, .Lfunc_end1-b
+
+ .type c,@function
+c: # @c
+ .indidx 0
+ .result i32
+# BB#0: # %entry
+ i32.const $push0=, 2
+ # fallthrough-return: $pop0
+ .endfunc
+.Lfunc_end2:
+ .size c, .Lfunc_end2-c
+
+ .type d,@function
+d: # @d
+ .indidx 2
+ .result i32
+# BB#0: # %entry
+ i32.const $push0=, 3
+ # fallthrough-return: $pop0
+ .endfunc
+.Lfunc_end3:
+ .size d, .Lfunc_end3-d
+
+ .hidden main
+ .globl main
+ .type main,@function
+main: # @main
+ .param i32, i32
+ .result i32
+ .local i32
+# BB#0: # %entry
+ block
+ i32.call $push1=, getchar@FUNCTION
+ i32.const $push0=, 2
+ i32.shl $push2=, $pop1, $pop0
+ i32.const $push3=, .Lmain.fp-192
+ i32.add $push4=, $pop2, $pop3
+ i32.load $push9=, 0($pop4)
+ tee_local $push8=, $2=, $pop9
+ i32.const $push5=, 4
+ i32.ge_u $push6=, $pop8, $pop5
+ br_if 0, $pop6 # 0: down to label0
+# BB#1: # %cont
+ i32.call_indirect $push7=, $2
+ return $pop7
+.LBB4_2: # %trap
+ end_block # label0:
+ unreachable
+ unreachable
+ .endfunc
+.Lfunc_end4:
+ .size main, .Lfunc_end4-main
+
+ .type .Lmain.fp,@object # @main.fp
+ .section .data.rel.ro,"aw",@progbits
+ .p2align 4
+.Lmain.fp:
+ .int32 a@FUNCTION
+ .int32 b@FUNCTION
+ .int32 c@FUNCTION
+ .int32 d@FUNCTION
+ .size .Lmain.fp, 16
+
+ .type .L__unnamed_1,@object # @0
+ .section .rodata,"a",@progbits
+.L__unnamed_1:
+ .size .L__unnamed_1, 0
+
+
+ .ident "clang version 3.9.0 (trunk 271314) (llvm/trunk 271322)"
diff --git a/test/dot_s/indidx.wast b/test/dot_s/indidx.wast
new file mode 100644
index 000000000..7d0a56f66
--- /dev/null
+++ b/test/dot_s/indidx.wast
@@ -0,0 +1,57 @@
+(module
+ (memory 1
+ (segment 16 "\03\00\00\00\01\00\00\00\00\00\00\00\02\00\00\00")
+ )
+ (export "memory" memory)
+ (type $FUNCSIG$i (func (result i32)))
+ (import $getchar "env" "getchar" (result i32))
+ (export "main" $main)
+ (export "dynCall_i" $dynCall_i)
+ (table $c $b $d $a)
+ (func $a (type $FUNCSIG$i) (result i32)
+ (i32.const 0)
+ )
+ (func $b (type $FUNCSIG$i) (result i32)
+ (i32.const 1)
+ )
+ (func $c (type $FUNCSIG$i) (result i32)
+ (i32.const 2)
+ )
+ (func $d (type $FUNCSIG$i) (result i32)
+ (i32.const 3)
+ )
+ (func $main (param $0 i32) (param $1 i32) (result i32)
+ (local $2 i32)
+ (block $label$0
+ (br_if $label$0
+ (i32.ge_u
+ (set_local $2
+ (i32.load
+ (i32.add
+ (i32.shl
+ (call_import $getchar)
+ (i32.const 2)
+ )
+ (i32.const -176)
+ )
+ )
+ )
+ (i32.const 4)
+ )
+ )
+ (return
+ (call_indirect $FUNCSIG$i
+ (get_local $2)
+ )
+ )
+ )
+ (unreachable)
+ (unreachable)
+ )
+ (func $dynCall_i (param $fptr i32) (result i32)
+ (call_indirect $FUNCSIG$i
+ (get_local $fptr)
+ )
+ )
+)
+;; METADATA: { "asmConsts": {},"staticBump": 32, "initializers": [] }