0

I have been playing around with a WebAssembly program . I wanted to get the x86 equivalent of the WebAssembly program . By googling I found that objdump can be used for doing so for any object file using the command

objdump -M intel <file_name>

However the disaasembler for wasm file wasm-objdump doesn't have the flag m for dissassembling the code in x86 format for the obvious reason that it is a web assembly application .

Is there a (easy) way for mapping a instruction given in WebAssembly to an equivalent x86 instruction without explicitly matching each instruction ?

Apoorv Jain
  • 113
  • 9
  • 1
    This question is unclear. If by equivalent instruction you mean an instruction that is conceptually equivalent, then just look at the two instructions sets and find it. If you are interested in finding out what is the equivalent x86 instruction sequence a particular compiler is emitting for high-level code it emits a particular instruction for in WebAssembly, you will have to specify what language and compiler are you interested in. – The Wayward Developer Nov 02 '19 at 12:42
  • Yes I by equal I mean the instruction that is conceptually equivalent . Yes I can look at the instruction sets of both of them and find the corresponding instructions, however is it possible to do so without explicitly mapping the corresponding sets . – Apoorv Jain Nov 02 '19 at 14:19
  • Mapping of instructions between WebAssembly and x86 is not formally defined, it is up to each individual compiler to decide. So you can either look at the instruction sets and decide for yourself what instructions you consider equivalent, or you can look at the code generated by a specific compiler to see what the authors of that compiler consider equivalent, but there is no definitive answer. – The Wayward Developer Nov 02 '19 at 16:48

2 Answers2

0

The online WasmExplorer compiles C code to both WebAssembly and FireFox x86, using the SpiderMonkey compiler. Given the following simple function:

int testFunction(int* input, int length) {
  int sum = 0;
  for (int i = 0; i < length; ++i) {
    sum += input[i];
  }
  return sum;
}

Here is the x86 output:

wasm-function[0]:
  sub rsp, 8                            ; 0x000000 48 83 ec 08
  cmp esi, 1                            ; 0x000004 83 fe 01
  jge 0x14                              ; 0x000007 0f 8d 07 00 00 00
 0x00000d:                              
  xor eax, eax                          ; 0x00000d 33 c0
  jmp 0x26                              ; 0x00000f e9 12 00 00 00
 0x000014:                              
  xor eax, eax                          ; 0x000014 33 c0
 0x000016:                              ; 0x000016 from: [0x000024]
  mov ecx, dword ptr [r15 + rdi]        ; 0x000016 41 8b 0c 3f
  add eax, ecx                          ; 0x00001a 03 c1
  add edi, 4                            ; 0x00001c 83 c7 04
  add esi, -1                           ; 0x00001f 83 c6 ff
  test esi, esi                         ; 0x000022 85 f6
  jne 0x16                              ; 0x000024 75 f0
 0x000026:                              
  nop                                   ; 0x000026 66 90
  add rsp, 8                            ; 0x000028 48 83 c4 08
  ret 

You can view this example online.

WasmExplorer compiles code into wasm / x86 via a service - you can see the scripts that are run on Github - you should be able to use these to construct a command-line tool yourself.

ColinE
  • 68,894
  • 15
  • 164
  • 232
  • Yes I got that but how do I map one instruction from WebAssembly to x86 (without explicit matching ) . – Apoorv Jain Nov 03 '19 at 13:48
  • I do not think that is actually the x86 of a wasm file. Its the x86 of the C file. You can get the x86 instructions for a javascript file using the d8 executable when you compile v8 from source. However, it doesn't appear that you can actually get asm instructions for wasm. – gautam1168 Feb 05 '23 at 12:44
  • For what its worth, I think the wasm files are compiled to the same bytecode that js files are. So its probably going to be very similar. – gautam1168 Feb 05 '23 at 12:45
0

It appears there is no way to do that. You can get the x86 instructions that will be made from a javascript file by running

d8.exe javascriptfile.js --print-code

Note that d8 is a debug executable created when you compile v8 from source. But you can do the same using nodejs as well.

However, even if you put the entire wasm binary as a string in a javascript file and then ran this command it will still not print out the x86 instructions. For example the below screenshot is created using this javascript file

let bytes = new Uint8Array([
    0x00, 0x61, 0x73, 0x6d, 0x01, 0x00, 0x00, 0x00, 0x01, 0x07, 0x01,
    0x60, 0x02, 0x7f, 0x7f, 0x01, 0x7f, 0x03, 0x02, 0x01, 0x00, 0x07,
    0x07, 0x01, 0x03, 0x61, 0x64, 0x64, 0x00, 0x00, 0x0a, 0x09, 0x01,
    0x07, 0x00, 0x20, 0x00, 0x20, 0x01, 0x6a, 0x0b
]);
let module = new WebAssembly.Module(bytes);
let instance = new WebAssembly.Instance(module);
instance.exports.add(1234, 5678);

enter image description here

In the above the Uint8Array has a wasm binary with a simple add function in it.

You can see that the printed instructions simply skip the wasm part.

However, for what its worth, the wasm instructions are compiled to the same bytecode instrctions as javascript is. You can see this by running some wasm code in v8 and stepping through it as it executes that.

So... I wouldn't expect the x86 to be anywhere close to what you wrote in C.

gautam1168
  • 641
  • 7
  • 15