Saturday, December 14, 2013

64 bit diaries

Part 1

Wanting to be a little more educated on the 64 bit front I have been doing some research, first up is the definitive architecture manual:

  AMD64 Architecture Programmer’s Manual Volume 3

After some reading it was time to start performing some BlitzMax experiments based on building a new bmk64 tool on OSX. 

Today's hypothesis is that given x86_64 is a superset of x86 then creating a 64 bit binary in BlitzMax should be possible by tweaking output of the x86 bcc tool.

Without access to the bcc compiler source my initial plan is to see how far I can get building 64 bit binaries just by tweaking the bmk tool.

My first iteration of bmk64 hardcodes the architecture to x86_64 and modifies bmk_util.bmx to build with the correct flags to produce 64 bit binary code on OSX.

After a couple of hours I now have bmk64 makemods producing the following type of errors:
  • /blitz.mod/.bmx/blitz.bmx.release.macos.amd64.s:55:suffix or operands invalid for `push'
  • /blitz.mod/.bmx/blitz.bmx.release.macos.amd64.s:58:32-bit absolute addressing is not supported for x86-64 
  • /blitz.mod/.bmx/blitz.bmx.release.macos.amd64.s:58:cannot do signed 4 byte relocation
Modifying bcc x86 output to use the stack in 64 bit mode sounds scary, learning about the new absolute addressing modes and reloc rules sounds quite educational...

[edit]

OK, not that scary. Stack usage just needs to use 64 bit register names:

src=src.Replace("~tpush~te","~tpush~tr")
src=src.Replace("~tpop~te","~tpop~tr")

And then pooh learns about the Relative Instruction Pointer mode, more commonly known as ($PC)

src=src.Replace("_112","_112(%rip)")

And then, oh no, a snag....

src=src.Replace("calll~t*","call~t")


Part 2

After blaming a missing out.Close in fasm2as it seems bcc mistreats any -o argument. Now fasm2as is embedded in bmk64 anyways which revealed an out of bounds array error with it's op[0] so that's fixed also.

The stack frame is pretty interesting in parts, address types need 8 bytes so the temptation is just to double every offset and rename all 32 bit registers to their 64 bit counterpart, offset->offset*2 etc. but that's obviously nuts and as an academic exercise I was hoping for more cheese.

The current prelog and epilog code bcc is generating to back up esp may also be deprecated, this will be confirmed when in part 3 we park bmk64 and start hand coding our own x86_64 .s files.



thanks to http://thexploit.com/secdev/mac-os-x-64-bit-assembly-system-calls we have an interesting starting point, nasm style:


 section .data

msg:
 db "shit hot!", 0x0a
eom:

 section .text

 global start

start:
 mov rax, 0x2000004   ; system:write = 4
 mov rdi, 1           ; stdout is 1
 mov rsi, msg         ; our message
 mov rdx, eom-msg     ; and size
 syscall              ; bang!
 mov rax, 0x2000001   ; system:exit = 1
 mov rdi, 0           ; success is 0
 syscall              ; bang!



oh, and todays hypothesis is - "the less we care about yesterdays hypothesis the better"