I am trying to get the following code to assemble and run however I am getting an error from the linker. The error message is:
ld: warning: pointer not aligned at address 0x100003FA3 (_main + 7 from print.o)`
ld: unaligned pointer(s) for architecture x86_64
This code works on Debian however when I try and compile it on Mac it fails. I get a similar error from nasm when I change the mov instructions for lea. The error is error: Mach-O 64-bit format does not support 32-bit absolute addresses
How do I resolve these errors?
In the code below any instruction after mov rcx, msg1 (including nops, other mov instructions or just anythging) will cause LD to throw the above error. I have used a call instruction in this instance but any instruction will cause this error.
The later mov instruction (mov rax, 0x2000001) does not seem to cause the issue. As such if the call instruction is commented out and everything else left the same LD will not throw an error.
bits 64
section .text
global _main ;must be declared for linker (ld)
global _print
_print:
mov rbx, 1 ;file descriptor (stdout)
mov rax, 0x4 ;system call number (sys_write)
bts rax, 25
syscall
ret
_main:
mov rdx, len1
mov rcx, msg1
call _print ;will not compile if this is not commented out
; <any instruction between mov rcx, msg1 and mov rax, 0x2000001
; causes LD to throw a pointer misalignment error
; ld: warning: pointer not aligned at address 0x100003FA3 (_main + 7 from print.o)
; ld: unaligned pointer(s) for architecture x86_64
mov rax, 0x2000001 ; system call 0x1 with 0x2000000 offset
mov rbx, 0x0 ; set the exit code to be 0x0
syscall
section .data
msg1 db 'here 1', 0xa
len1 equ $ - msg1
msg2 db 'here 2', 0xa
len2 equ $ - msg2
msg3 db 'here 3', 0xa
len3 equ $ - msg3
msg4 db 'here 4', 0xa
len4 equ $ - msg4
msg5 db 'here 5', 0xa
len5 equ $ - msg5
NASM command: nasm -f macho64 print.asm.
ld command: ld -L /Library/Developer/CommandLineTools/SDKs/MacOSX.sdk/usr/lib -lSystem print.o -o print
Follow up:
In the end the following code worked as intended and printed the string to std out:
bits 64
default rel
section .text
global _main ;must be declared for linker (ld)
global _print
_print:
mov rdi, 1 ;file descriptor (stdout)
mov rax, 0x4 ;system call number (sys_write)
bts rax, 25
syscall
ret
_main:
lea rsi, [rel msg1]
lea rdx, [rel len1]
call _print
nop
nop
nop
mov rax, 0x2000001 ; system call 0x1 with 0x2000000 offset
mov rbx, 0x0 ; set the exit code to be 0x0
syscall
section .data
msg1 db 'here 1', 0xa
len1 equ $ - msg1
msg2 db 'here 2', 0xa
len2 equ $ - msg2
msg3 db 'here 3', 0xa
len3 equ $ - msg3
msg4 db 'here 4', 0xa
len4 equ $ - msg4
msg5 db 'here 5', 0xa
len5 equ $ - msg5
When I run objdump -dx print I get an error stating:
print: file format mach-o 64-bit x86-64
/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/objdump: error: 'print': Invalid/Unsupported object file format
However when I run objdump -d print I get:
print: file format mach-o 64-bit x86-64
Disassembly of section __TEXT,__text:
0000000100003f83 <_print>:
100003f83: bf 01 00 00 00 movl $1, %edi
100003f88: b8 04 00 00 00 movl $4, %eax
100003f8d: 48 0f ba e8 19 btsq $25, %rax
100003f92: 0f 05 syscall
100003f94: c3 retq
0000000100003f95 <_main>:
100003f95: 48 8d 35 64 00 00 00 leaq 100(%rip), %rsi ## 0x100004000 <msg1>
100003f9c: 48 8d 14 25 07 00 00 00 leaq 7, %rdx
100003fa4: e8 da ff ff ff callq 0x100003f83 <_print>
100003fa9: 90 nop
100003faa: 90 nop
100003fab: 90 nop
100003fac: b8 01 00 00 02 movl $33554433, %eax ## imm = 0x2000001
100003fb1: bb 00 00 00 00 movl $0, %ebx
100003fb6: 0f 05 syscall
Adding otool -dtvr print.o output:
% otool -dtvr print.o
test.o:
Relocation information (__TEXT,__text) 1 entries
address pcrel length extern type scattered symbolnum/value
0000000f False quad True UNSIGND False msg1
(__TEXT,__text) section
_print:
0000000000000000 movl $0x1, %edi
0000000000000005 movl $0x2000004, %eax ## imm = 0x2000004
000000000000000a syscall
000000000000000c retq
_main:
000000000000000d movabsq $0x0, %rsi
0000000000000017 movl $0x7, %edx
000000000000001c callq 0x0
0000000000000021 movl $0x2000001, %eax ## imm = 0x2000001
0000000000000026 movl $0x0, %ebx
000000000000002b syscall
(__DATA,__data) section
000000000000002d 68 65 72 65 20 31 0a 68 65 72 65 20 32 0a 68 65
000000000000003d 72 65 20 33 0a 68 65 72 65 20 34 0a 68 65 72 65
000000000000004d 20 35 0a