Skip to content

Instantly share code, notes, and snippets.

@appcypher
Created January 30, 2019 15:26
Show Gist options
  • Save appcypher/e42c865696d8d8b8e2702337c04ba94d to your computer and use it in GitHub Desktop.
Save appcypher/e42c865696d8d8b8e2702337c04ba94d to your computer and use it in GitHub Desktop.
A syscall webassembly example
(module
(type $t1 (func (param i32)))
(type $t2 (func (param i32 i32 i32) (result i32)))
(type $t3 (func (param i32) (result i32)))
(type $t4 (func (param i32 i32) (result i32)))
(func $putchar (import "env" "putchar") (type $t1))
(func $printf (import "env" "printf") (type $t4))
(func $sys_open (import "env" "sys_open") (type $t2))
(func $sys_read (import "env" "sys_read") (type $t2))
(func $sys_close (import "env" "sys_close") (type $t3))
(func $sys_exit (import "env" "sys_exit") (type $t1))
(memory 1)
(data $filename (i32.const 0) "/Users/xxxx/Desktop/hello.txt\00")
(func $main (export "_main")
;; declare variables
(local $string_buf_addr i32)
(local $string_buf_len i32)
(local $file_access_flag i32)
(local $file_permission_flag i32)
(local $file_descriptor i32)
;; set variables
(set_local $string_buf_addr (i32.const 72)) ;; string_buf_addr at offset 72
(set_local $string_buf_len (i32.const 10)) ;; string_buf_len is 5
(set_local $file_access_flag (i32.const 02)) ;; file_access_flag has O_RDWR permission
(set_local $file_permission_flag (i32.const 700)) ;; file_permission_flag has S_IRWXU permission
;; open file
(call $sys_open (i32.const 0) (get_local $file_access_flag) (get_local $file_permission_flag)) ;; (path: u32, flags: c_int, mode: c_int) -> c_int
(set_local $file_descriptor) ;; set file_descriptor to the value returned by sys_open
;; read file content
(call $sys_read (get_local $file_descriptor) (get_local $string_buf_addr) (get_local $string_buf_len)) ;; (fd: c_int, buf: u32, count: size_t) -> ssize_t
(drop) ;; ignoring errors
;; close file
(call $sys_close (get_local $file_descriptor)) ;; (fd: c_int) -> c_int
(drop) ;; ignoring errors
;; print file content
(call $printf (get_local $string_buf_addr) (i32.const 0))
(drop) ;; ignoring errors
;; exit
(call $exit (i32.const 0))
)
)
@appcypher
Copy link
Author

appcypher commented Jan 30, 2019

This is one of the webassembly files I wrote from scratch and it characterizes the situation I found myself in while trying to create an Emscripten-compatible host binding for Wasmer.

This code is interesting to me because it is one of the wasm code I wrote to interface with low-level ABIs (syscalls). Here I exposed the bare minimum functions for opening, reading, printing, and closing a file and it was an eureka moment when I got that working. It was the first step towards figuring out how to implement Emscripten APIs.

A week later this code became obsolete because I found out Emscripten has a totally different calling convention but the code is still there today. It is a foot mark in the history of the runtime's development.

You can still use this code today by exposing the right libc functions. Most notably read, open, close, printf, putchar and exit.

Another interesting code would be the implementation of is_canonical_nan based on WebAssembly's specification.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment