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
How Do the Likely/Unlikely Macros in the Linux Kernel Work and What Is Their Benefit
What Is Rss and Vsz in Linux Memory Management
Adding a New Entry to the Path Variable in Zsh
Linux Default Behavior of Executable .Data Section Changed Between 5.4 and 5.9
How to Redirect Output of Systemd Service to a File
Modify Qt Gui from Background Worker Thread
Pipe Only Stderr Through a Filter
How Is the System Call in Linux Implemented
32-Bit Absolute Addresses No Longer Allowed in X86-64 Linux
How to Write Standard Error to a File While Using "Tee" With a Pipe
Understanding Linux /Proc/Pid/Maps or /Proc/Self/Maps
How to Join Multiple Lines of File Names into One With Custom Delimiter
Why Do You Need to Put #!/Bin/Bash At the Beginning of a Script File
How to Find the Last Field Using 'Cut'