From 6298da7d3468cd3d0340a715fc0fbf9e2ae9a2c6 Mon Sep 17 00:00:00 2001 From: Fabian Date: Thu, 31 Dec 2020 19:14:30 -0600 Subject: [PATCH] Remove indirect function table patching --- Makefile | 4 +- tools/wasm-patch-indirect-function-table.js | 185 -------------------- 2 files changed, 2 insertions(+), 187 deletions(-) delete mode 100755 tools/wasm-patch-indirect-function-table.js diff --git a/Makefile b/Makefile index a8b3f9dc..519c92a3 100644 --- a/Makefile +++ b/Makefile @@ -178,14 +178,14 @@ build/v86.wasm: $(RUST_FILES) Cargo.toml mkdir -p build/ -ls -lh build/v86.wasm cargo +nightly rustc --release $(CARGO_FLAGS) - ./tools/wasm-patch-indirect-function-table.js < build/wasm32-unknown-unknown/release/v86.wasm > build/v86.wasm + mv build/wasm32-unknown-unknown/release/v86.wasm build/v86.wasm ls -lh build/v86.wasm build/v86-debug.wasm: $(RUST_FILES) Cargo.toml mkdir -p build/ -ls -lh build/v86-debug.wasm cargo +nightly rustc $(CARGO_FLAGS) - ./tools/wasm-patch-indirect-function-table.js < build/wasm32-unknown-unknown/debug/v86.wasm > build/v86-debug.wasm + mv build/wasm32-unknown-unknown/debug/v86.wasm build/v86-debug.wasm ls -lh build/v86-debug.wasm clean: diff --git a/tools/wasm-patch-indirect-function-table.js b/tools/wasm-patch-indirect-function-table.js deleted file mode 100755 index f28b51ec..00000000 --- a/tools/wasm-patch-indirect-function-table.js +++ /dev/null @@ -1,185 +0,0 @@ -#!/usr/bin/env node -"use strict"; - -// Read a wasm module in binary format from stdin, find table import entries, i.e.: -// -// (import "env" "table" (table (;0;) anyfunc)) -// -// Remove the and write the patched wasm module to stdout. - -process.on("unhandledRejection", exn => { throw exn; }); - -const assert = require("assert").strict; -const fs = require("fs"); - -const SECTION_IMPORT = 2; - -const IMPORT_KIND_FUNCTION = 0; -const IMPORT_KIND_TABLE = 1; -const IMPORT_KIND_MEMORY = 2; -const IMPORT_KIND_GLOBAL = 3; - -function main() -{ - const wasm = fs.readFileSync("/dev/stdin"); - const view = new DataView(wasm.buffer); - var ptr = 0; - - // magic - assert(view.getUint32(ptr, true) === 0x6d736100); - ptr += 4; - - // version - assert(view.getUint32(ptr, true) === 1); - ptr += 4; - - while(ptr < view.byteLength) - { - const section_id = view.getUint8(ptr); - ptr++; - var { ptr, value: size } = read_leb_u32(ptr, view); - const section_end = ptr + size; - - if(section_id === SECTION_IMPORT) - { - patch_import_section(ptr, view); - } - - ptr = section_end; - } - - // sanity check - const module = new WebAssembly.Module(view.buffer); - - process.stdout.write(wasm); -} - -function patch_import_section(ptr, view) -{ - var { ptr, value: section_entry_count } = read_leb_u32(ptr, view); - - for(let i = 0; i < section_entry_count; i++) - { - var { ptr, value: module_str_length } = read_leb_u32(ptr, view); - ptr += module_str_length; - var { ptr, value: field_str_length } = read_leb_u32(ptr, view); - ptr += field_str_length; - - const kind = view.getUint8(ptr); - ptr++; - - if(kind === IMPORT_KIND_FUNCTION) - { - var { ptr, value: function_signature_index } = read_leb_u32(ptr, view); - } - else if(kind === IMPORT_KIND_TABLE) - { - const table_offset = ptr; - var { ptr, value: table_element_type } = read_leb_u32(ptr, view); - assert(table_element_type === 0x70); - - const maximum_present = new Uint8Array(view.buffer, ptr, 1); - assert(maximum_present[0] === 0 || maximum_present[0] === 1); - ptr++; - - var { ptr, value: initial_table_size, leb_view: initial_table_size_view } = read_leb_u32(ptr, view); - - if(maximum_present[0]) - { - var { ptr, value: maximum_table_size, leb_view: maximum_table_size_view } = read_leb_u32(ptr, view); - } - else - { - maximum_table_size = -1; - } - - console.error(`Found table import at offset` + - ` ${table_offset}` + - ` maximum_present=${maximum_present[0]}` + - ` initial=${initial_table_size}` + - ` maximum=${maximum_table_size}`); - - if(maximum_present[0]) - { - patch_maximum_limit(maximum_present, initial_table_size_view, maximum_table_size_view); - console.error("Patched!"); - } - else - { - console.error("No maximum present, skipped"); - } - } - else if(kind === IMPORT_KIND_MEMORY) - { - const maximum_present = view.getUint8(ptr); - assert(maximum_present === 0 || maximum_present === 1); - ptr++; - - var { ptr, value: initial_memory_size } = read_leb_u32(ptr, view); - - if(maximum_present) - { - var { ptr, value: maximum_memory_size } = read_leb_u32(ptr, view); - } - } - else if(kind === IMPORT_KIND_GLOBAL) - { - const content_type = view.getUint8(ptr); - ptr++; - const mutability = view.getUint8(ptr); - assert(mutability === 0 || mutability === 1); - ptr++; - } - else - { - assert(false, `Unexpected import kind: 0x${kind.toString(16)} at offset ${ptr - 1}`); - } - } -} - -function patch_maximum_limit(maximum_present, initial_size, maximum_size) -{ - // clear the maximum present bit - maximum_present[0] = 0; - - // set the highest bit of the initial size, in order to use it to pad the existing maximum size bytes - const last_byte_initial_size = initial_size[initial_size.length - 1]; - assert((last_byte_initial_size & 0x80) === 0); - initial_size[initial_size.length - 1] = last_byte_initial_size | 0x80; - - for(let i = 0; i < maximum_size.length - 1; i++) - { - // pad maximum value with 0x80 bytes - maximum_size[i] = 0x80; - } - - // pad the last byte of the maximum value with 0x00 - maximum_size[maximum_size.length - 1] = 0x00; -} - -function read_leb_u32(ptr, view) -{ - let value = 0; - let byte_length = 0; - - while(true) - { - let byte = view.getUint8(ptr++); - - value |= (byte & 0x7f) << (byte_length * 7); - byte_length++; - - if((byte & 0x80) === 0) - { - break; - } - } - - assert(byte_length <= 4); - - const leb_view = new Uint8Array(view.buffer, ptr - byte_length, byte_length); - - return { ptr, value, leb_view }; -} - -main();