Browse Source

Remove indirect function table patching

Fabian 3 years ago
parent
commit
6298da7d34
2 changed files with 2 additions and 187 deletions
  1. 2 2
      Makefile
  2. 0 185
      tools/wasm-patch-indirect-function-table.js

+ 2 - 2
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:

+ 0 - 185
tools/wasm-patch-indirect-function-table.js

@@ -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;) <initial> <maximum> anyfunc))
-//
-// Remove the <maximum> 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();