Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
W
wasm-watermarker
Project
Project
Details
Activity
Releases
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
nagayama15
wasm-watermarker
Commits
2f00c44f
Commit
2f00c44f
authored
Mar 18, 2019
by
nagayama15
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Implement a side effect checker.
parent
bf248ea9
Changes
5
Show whitespace changes
Inline
Side-by-side
Showing
5 changed files
with
355 additions
and
5 deletions
+355
-5
add.wast
example/add.wast
+19
-0
CMakeLists.txt
src/CMakeLists.txt
+1
-0
kyut.cpp
src/kyut.cpp
+12
-5
operand_swapping_watermarker.cpp
src/kyut/pass/operand_swapping_watermarker.cpp
+313
-0
operand_swapping_watermarker.hpp
src/kyut/pass/operand_swapping_watermarker.hpp
+10
-0
No files found.
example/add.wast
0 → 100644
View file @
2f00c44f
(module
(export "add2" (func $add2))
(export "add3" (func $add3))
(func $add2 (param $a i32) (param $b i32) (result i32)
(i32.add
(local.get $a)
(local.get $b)
)
)
(func $add3 (param $a i32) (param $b i32) (param $c i32) (result i32)
(i32.add
(i32.add
(local.get $a)
(local.get $b)
)
(local.get $c)
)
)
)
src/CMakeLists.txt
View file @
2f00c44f
add_executable
(
kyut
add_executable
(
kyut
kyut.cpp
kyut.cpp
kyut/pass/operand_swapping_watermarker.cpp
)
)
target_link_libraries
(
kyut
target_link_libraries
(
kyut
...
...
src/kyut.cpp
View file @
2f00c44f
#include <
cstdio
>
#include <
iostream
>
#include <fmt/
format
.h>
#include <fmt/
ostream
.h>
#include <wasm-io.h>
#include <wasm-io.h>
#include "kyut/pass/operand_swapping_watermarker.hpp"
int
main
(
int
argc
,
char
*
argv
[])
{
int
main
(
int
argc
,
char
*
argv
[])
{
try
{
try
{
if
(
argc
!=
3
)
{
if
(
argc
!=
3
)
{
fmt
::
print
(
stderr
,
fmt
::
print
(
std
::
c
err
,
"WebAssembly digital watermarker.
\n
"
"WebAssembly digital watermarker.
\n
"
"usage: kyut <input file> <watermark>
\n
"
);
"usage: kyut <input file> <watermark>
\n
"
);
...
@@ -14,9 +16,14 @@ int main(int argc, char *argv[]) {
...
@@ -14,9 +16,14 @@ int main(int argc, char *argv[]) {
}
}
wasm
::
Module
module
;
wasm
::
Module
module
;
wasm
::
ModuleReader
{}.
readBinary
(
argv
[
1
],
module
);
wasm
::
ModuleReader
{}.
read
(
argv
[
1
],
module
);
kyut
::
pass
::
embedWatermarkOperandSwapping
(
module
);
}
catch
(
wasm
::
ParseException
&
e
)
{
fmt
::
print
(
std
::
cerr
,
"parse error
\n
"
);
e
.
dump
(
std
::
cerr
);
}
catch
(
const
std
::
exception
&
e
)
{
}
catch
(
const
std
::
exception
&
e
)
{
fmt
::
print
(
stderr
,
"error: {}
\n
"
,
e
.
what
());
fmt
::
print
(
std
::
c
err
,
"error: {}
\n
"
,
e
.
what
());
return
1
;
return
1
;
}
}
...
...
src/kyut/pass/operand_swapping_watermarker.cpp
0 → 100644
View file @
2f00c44f
#include "operand_swapping_watermarker.hpp"
#include <pass.h>
namespace
kyut
::
pass
{
class
OperandSwappingWatermarkingVisitor
:
public
wasm
::
OverriddenVisitor
<
OperandSwappingWatermarkingVisitor
,
bool
>
{
public
:
explicit
OperandSwappingWatermarkingVisitor
()
=
default
;
OperandSwappingWatermarkingVisitor
(
const
OperandSwappingWatermarkingVisitor
&
)
=
delete
;
OperandSwappingWatermarkingVisitor
(
OperandSwappingWatermarkingVisitor
&&
)
=
delete
;
OperandSwappingWatermarkingVisitor
&
operator
=
(
const
OperandSwappingWatermarkingVisitor
&
)
=
delete
;
OperandSwappingWatermarkingVisitor
&
operator
=
(
OperandSwappingWatermarkingVisitor
&&
)
=
delete
;
~
OperandSwappingWatermarkingVisitor
()
noexcept
=
default
;
bool
visitBlock
(
wasm
::
Block
*
curr
)
{
bool
has_side_effect
=
false
;
for
(
const
auto
&
expr
:
curr
->
list
)
{
has_side_effect
=
visit
(
expr
)
||
has_side_effect
;
}
return
has_side_effect
;
}
bool
visitIf
(
wasm
::
If
*
curr
)
{
bool
has_side_effect
=
false
;
has_side_effect
=
visit
(
curr
->
condition
)
||
has_side_effect
;
has_side_effect
=
visit
(
curr
->
ifTrue
)
||
has_side_effect
;
if
(
curr
->
ifFalse
)
{
has_side_effect
=
visit
(
curr
->
ifFalse
)
||
has_side_effect
;
}
return
has_side_effect
;
}
bool
visitLoop
(
wasm
::
Loop
*
curr
)
{
return
visit
(
curr
->
body
);
}
bool
visitBreak
(
wasm
::
Break
*
curr
)
{
if
(
curr
->
condition
)
{
visit
(
curr
->
condition
);
}
if
(
curr
->
value
)
{
visit
(
curr
->
value
);
}
return
true
;
}
bool
visitSwitch
(
wasm
::
Switch
*
curr
)
{
visit
(
curr
->
condition
);
if
(
curr
->
value
)
{
visit
(
curr
->
value
);
}
return
true
;
}
bool
visitCall
(
wasm
::
Call
*
curr
)
{
for
(
const
auto
&
expr
:
curr
->
operands
)
{
visit
(
expr
);
}
return
true
;
}
bool
visitCallIndirect
(
wasm
::
CallIndirect
*
curr
)
{
visit
(
curr
->
target
);
for
(
const
auto
&
expr
:
curr
->
operands
)
{
visit
(
expr
);
}
return
true
;
}
bool
visitGetLocal
([[
maybe_unused
]]
wasm
::
GetLocal
*
curr
)
{
return
false
;
}
bool
visitSetLocal
(
wasm
::
SetLocal
*
curr
)
{
visit
(
curr
->
value
);
return
true
;
}
bool
visitGetGlobal
([[
maybe_unused
]]
wasm
::
GetGlobal
*
curr
)
{
return
false
;
}
bool
visitSetGlobal
(
wasm
::
SetGlobal
*
curr
)
{
visit
(
curr
->
value
);
return
true
;
}
bool
visitLoad
(
wasm
::
Load
*
curr
)
{
return
visit
(
curr
->
ptr
);
}
bool
visitStore
(
wasm
::
Store
*
curr
)
{
visit
(
curr
->
ptr
);
visit
(
curr
->
value
);
return
true
;
}
bool
visitAtomicRMW
(
wasm
::
AtomicRMW
*
curr
)
{
visit
(
curr
->
ptr
);
visit
(
curr
->
value
);
return
true
;
}
bool
visitAtomicCmpxchg
(
wasm
::
AtomicCmpxchg
*
curr
)
{
visit
(
curr
->
ptr
);
visit
(
curr
->
expected
);
visit
(
curr
->
replacement
);
return
true
;
}
bool
visitAtomicWait
(
wasm
::
AtomicWait
*
curr
)
{
visit
(
curr
->
ptr
);
visit
(
curr
->
expected
);
visit
(
curr
->
timeout
);
return
true
;
}
bool
visitAtomicWake
(
wasm
::
AtomicWake
*
curr
)
{
visit
(
curr
->
ptr
);
visit
(
curr
->
wakeCount
);
return
true
;
}
bool
visitSIMDExtract
(
wasm
::
SIMDExtract
*
curr
)
{
return
visit
(
curr
->
vec
);
}
bool
visitSIMDReplace
(
wasm
::
SIMDReplace
*
curr
)
{
bool
has_side_effect
=
false
;
has_side_effect
=
visit
(
curr
->
vec
)
||
has_side_effect
;
has_side_effect
=
visit
(
curr
->
value
)
||
has_side_effect
;
return
has_side_effect
;
}
bool
visitSIMDShuffle
(
wasm
::
SIMDShuffle
*
curr
)
{
bool
has_side_effect
=
false
;
has_side_effect
=
visit
(
curr
->
left
)
||
has_side_effect
;
has_side_effect
=
visit
(
curr
->
right
)
||
has_side_effect
;
return
has_side_effect
;
}
bool
visitSIMDBitselect
(
wasm
::
SIMDBitselect
*
curr
)
{
bool
has_side_effect
=
false
;
has_side_effect
=
visit
(
curr
->
cond
)
||
has_side_effect
;
has_side_effect
=
visit
(
curr
->
left
)
||
has_side_effect
;
has_side_effect
=
visit
(
curr
->
right
)
||
has_side_effect
;
return
has_side_effect
;
}
bool
visitSIMDShift
(
wasm
::
SIMDShift
*
curr
)
{
bool
has_side_effect
=
false
;
has_side_effect
=
visit
(
curr
->
vec
)
||
has_side_effect
;
has_side_effect
=
visit
(
curr
->
shift
)
||
has_side_effect
;
return
has_side_effect
;
}
bool
visitMemoryInit
(
wasm
::
MemoryInit
*
curr
)
{
visit
(
curr
->
dest
);
visit
(
curr
->
offset
);
visit
(
curr
->
size
);
return
true
;
}
bool
visitDataDrop
([[
maybe_unused
]]
wasm
::
DataDrop
*
curr
)
{
return
true
;
}
bool
visitMemoryCopy
(
wasm
::
MemoryCopy
*
curr
)
{
visit
(
curr
->
dest
);
visit
(
curr
->
source
);
visit
(
curr
->
size
);
return
true
;
}
bool
visitMemoryFill
(
wasm
::
MemoryFill
*
curr
)
{
visit
(
curr
->
dest
);
visit
(
curr
->
value
);
visit
(
curr
->
size
);
return
true
;
}
bool
visitConst
([[
maybe_unused
]]
wasm
::
Const
*
curr
)
{
return
false
;
}
bool
visitUnary
(
wasm
::
Unary
*
curr
)
{
return
visit
(
curr
->
value
);
}
bool
visitBinary
(
wasm
::
Binary
*
curr
)
{
bool
has_side_effect
=
false
;
has_side_effect
=
visit
(
curr
->
left
)
||
has_side_effect
;
has_side_effect
=
visit
(
curr
->
right
)
||
has_side_effect
;
return
has_side_effect
;
}
bool
visitSelect
(
wasm
::
Select
*
curr
)
{
bool
has_side_effect
=
false
;
has_side_effect
=
visit
(
curr
->
condition
)
||
has_side_effect
;
has_side_effect
=
visit
(
curr
->
ifTrue
)
||
has_side_effect
;
has_side_effect
=
visit
(
curr
->
ifFalse
)
||
has_side_effect
;
return
has_side_effect
;
}
bool
visitDrop
(
wasm
::
Drop
*
curr
)
{
return
visit
(
curr
->
value
);
}
bool
visitReturn
(
wasm
::
Return
*
curr
)
{
if
(
curr
->
value
)
{
visit
(
curr
->
value
);
}
return
true
;
}
bool
visitHost
(
wasm
::
Host
*
curr
)
{
for
(
const
auto
&
expr
:
curr
->
operands
)
{
visit
(
expr
);
}
return
curr
->
op
!=
wasm
::
HostOp
::
CurrentMemory
;
}
bool
visitNop
([[
maybe_unused
]]
wasm
::
Nop
*
curr
)
{
return
false
;
}
bool
visitUnreachable
([[
maybe_unused
]]
wasm
::
Unreachable
*
curr
)
{
WASM_UNREACHABLE
();
}
bool
visitFunctionType
([[
maybe_unused
]]
wasm
::
FunctionType
*
curr
)
{
WASM_UNREACHABLE
();
}
bool
visitExport
([[
maybe_unused
]]
wasm
::
Export
*
curr
)
{
WASM_UNREACHABLE
();
}
bool
visitGlobal
([[
maybe_unused
]]
wasm
::
Global
*
curr
)
{
WASM_UNREACHABLE
();
}
bool
visitFunction
([[
maybe_unused
]]
wasm
::
Function
*
curr
)
{
WASM_UNREACHABLE
();
}
bool
visitTable
([[
maybe_unused
]]
wasm
::
Table
*
curr
)
{
WASM_UNREACHABLE
();
}
bool
visitMemory
([[
maybe_unused
]]
wasm
::
Memory
*
curr
)
{
WASM_UNREACHABLE
();
}
bool
visitModule
([[
maybe_unused
]]
wasm
::
Module
*
curr
)
{
WASM_UNREACHABLE
();
}
};
class
OperandSwappingWatermarkingPass
:
public
wasm
::
Pass
{
public
:
explicit
OperandSwappingWatermarkingPass
()
=
default
;
OperandSwappingWatermarkingPass
(
const
OperandSwappingWatermarkingPass
&
)
=
delete
;
OperandSwappingWatermarkingPass
(
OperandSwappingWatermarkingPass
&&
)
=
delete
;
OperandSwappingWatermarkingPass
&
operator
=
(
const
OperandSwappingWatermarkingPass
&
)
=
delete
;
OperandSwappingWatermarkingPass
&
operator
=
(
OperandSwappingWatermarkingPass
&&
)
=
delete
;
~
OperandSwappingWatermarkingPass
()
noexcept
=
default
;
bool
modifiesBinaryenIR
()
noexcept
override
{
return
true
;
}
void
run
([[
maybe_unused
]]
wasm
::
PassRunner
*
runner
,
wasm
::
Module
*
module
)
override
{
OperandSwappingWatermarkingVisitor
visitor
{};
for
(
const
auto
&
func
:
module
->
functions
)
{
visitor
.
visit
(
func
->
body
);
}
}
};
void
embedWatermarkOperandSwapping
(
wasm
::
Module
&
module
)
{
wasm
::
PassRunner
runner
{
&
module
};
runner
.
add
<
OperandSwappingWatermarkingPass
>
();
runner
.
run
();
}
}
// namespace kyut::pass
src/kyut/pass/operand_swapping_watermarker.hpp
0 → 100644
View file @
2f00c44f
#ifndef INCLUDE_kyut_pass_operand_swapping_watermarker_hpp
#define INCLUDE_kyut_pass_operand_swapping_watermarker_hpp
#include <wasm.h>
namespace
kyut
::
pass
{
void
embedWatermarkOperandSwapping
(
wasm
::
Module
&
module
);
}
#endif // INCLUDE_kyut_pass_operand_swapping_watermarker_hpp
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment