Josef “Jeff” Sipek

z/VOS - running x86 code on z

Earlier this year, I heard of a company that tried to make a product out of dynamic binary translation of x86 code to Wikipedia article: z/Architecture. Recently, I decided to look at what they do.

The company is called Mantissa Corporation, and their binary translation product is called z/VOS.

Much like VMWARE, they cache the translated code, in z/VOS’s case it’s really a must otherwise I’d guess the cost of traslation would make the result unusable. I like how they used VNC (see the demo mentioned below) to give the virtual x86 box a display.

There is an official blog that has some interesting bits of information. For example, they hint at how they use multiple address spaces to give a the x86 code the illusion of virtual memory. I am not quite sure why they list Wikipedia article: Decimal Floating Point facility as a requirement. Unfortunately, it has been a few months since the last update.

Their website also happens to have a demo of a small x86 assembly operating system starting up and running under z/VOS. I find this fascinating.

Binary Translation is Hard

I spend most of yesterday reading the x86 Intel books, and the equivalent book for the z/Architecture (by IBM). That alone wouldn’t be much out of the ordinary — what I did with the information gathered was fun. I made a sample, proof of concept harness in C that would do “dynamic” binary translation of zArch machine code to x86_64. (I quoted the word “dynamic” because this test program doesn’t execute the code, it just translates what it is given.)

I took the approach of hand assembling the x86 code, which made things a whole lot slower to develop. For instance, I managed to get most of the zArch AR (Add Registers) translating. The original is a 2-byte instruction, and the resulting x86_64 code is about 40 bytes, and I’m still missing a few bits and pieces.

Output from my test program translating AR 5,6:

TRACE, idx = 2, inst = 1, AR
TRACE, R1 == GPR5 == r128
TRACE, R2 == GPR6 == r128
TRACE, about to allocate reg for GPR5, protect r128
Register map:  (z: x86)
GPR:
0: 80  1: 80  2: 80  3: 80  4: 80  5: 80  6: 80  7: 80  
8: 80  9: 80  a: 80  b: 80  c: 80  d: 80  e: 80  f: 80  
TRACE, allocated r8 for GPR5
TRACE, about to allocate reg for GPR6, protect r8
Register map:  (z: x86)
GPR:
0: 80  1: 80  2: 80  3: 80  4: 80  5:  8  6: 80  7: 80  
8: 80  9: 80  a: 80  b: 80  c: 80  d: 80  e: 80  f: 80  
TRACE, allocated r9 for GPR6
TRACE, R1 == GPR5 == r8
TRACE, R2 == GPR6 == r9
TRACE, return 1, 1
block 0x7fffd1e71720
  1 S/3x0 instructions in 2 bytes
  256 bytes for x86 code
  S/3x0 code:
    1a 56 
  x86 code:
    4d 01 c8 49 c7 c7 02 00 00 00 49 c7 c7 00 00 00 
    00 49 c7 c7 03 00 00 00 79 07 49 c7 c7 01 00 00 
    00 49 c1 e7 12 4d 09 fe 00 00 00 00 00 00 00 00 
    00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 
    00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 
    00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 
    00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 
    00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 
    00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 
    00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 
    00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 
    00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 
    00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 
    00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 
    00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 
    00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 

Kernel Hacking

So, I moved my Unionfs development from a bunch of i386 boxes, to 2 x86_64 servers. They are sweet :) I still have to get used to looking in arch/x86_64/ and include/asm-x86_64/ instead of their i386 equivalents which I have used for years.

Powered by blahgd