32-Bit Absolute Addresses No Longer Allowed in X86-64 Linux

Mach-O 64-bit format does not support 32-bit absolute addresses. NASM

Mac OS X, like other UNIX/POSIX systems, uses a different calling convention for 64-bit code. Instead of pushing all the arguments to the stack, it uses RDI, RSI, RDX, RCX, R8, and R9 for the first 6 arguments. So instead of using push msg, you'll need to use something like mov RDI, msg.

Absolute addressing for runtime code replacement in x86_64

Try using the large code model for x86_64. In gcc this can be selected with -mcmodel=large. The compiler will use 64 bit absolute addressing for both code and data.

You could also add -fno-pic to disallow the generation of position independent code.

Edit: I built a small test app with -mcmodel=large and the resulting binary contains sequences like

400b81:       48 b9 f0 30 60 00 00    movabs $0x6030f0,%rcx
400b88: 00 00 00
400b8b: 49 b9 d0 09 40 00 00 movabs $0x4009d0,%r9
400b92: 00 00 00
400b95: 48 8b 39 mov (%rcx),%rdi
400b98: 41 ff d1 callq *%r9

which is a load of an absolute 64 bit immediate (in this case an address) followed by an indirect call or an indirect load. The instruction sequence

moveabs $variable, %rbx
addq %rax, %rbx

is the equivalent to a "leaq offset64bit(%rax), %rbx" (which doesn't exist), with some side effects like flag changing etc.

Unable to compile program:CMach-O 64-bit format does not support 32-bit absolute addresses

The addressing space used for macho64 is x86-64, so the registers are a different size which can handle 64-bit addressing. ECX for example is 32 bits, and you try to load it with a 64 bit address, causing the error.

This is what the Hello World code looks like for x86-64:

global _main

SECTION .data
msg db 'Hello World!', 0x0A ; assign msg variable

SECTION .text

_main:

mov rdx, 13 ; number of bytes to write - one for each letter plus LF char.
lea rsi, [rel msg] ; move the memory address of our message string into rsi
mov rdi, 1 ; write to the STDOUT file
mov rax, 0x2000004 ; invoke SYS_WRITE (kernel opcode 4)
syscall

mov rax, 0x2000001 ; exit
mov rdi, 0
syscall

Compiled, linked, executed:

% nasm -f macho64 -o helloworld.o helloworld.asm
% ld helloworld.o -o hello -lSystem -L/Library/Developer/CommandLineTools/SDKs/MacOSX.sdk/usr/lib
% ./hello
Hello World!


Related Topics



Leave a reply



Submit