5

次のアセンブリプログラムを実行しようとした場合:

.globl start

start:
    pushq $0x0 
    movq $0x1, %rax
    subq $0x8, %rsp
    int $0x80

次のエラーが発生します。

dyld: no writable segment
Trace/BPT trap

これを引き起こしている可能性のあるアイデアはありますか?32ビットアセンブリの類似プログラムは正常に実行されます。

4

2 に答える 2

10

OSXでは、実行可能ファイルにコンテンツを含む書き込み可能なデータセグメントが必要になるため、コードを動的に再配置およびリンクできます。なぜ、おそらくセキュリティ上の理由で、おそらく新しいRIPレジスタが原因です。そこに.dataセグメントを(偽のコンテンツを含めて)配置すると、「書き込み可能なセグメントがありません」というエラーを回避できます。IMOこれはldバグです。

64ビットのシステムコールに関しては、2つの方法で実行できます。libSystem.dylib、またはrawからの_syscallPROCEDUREを使用するGCCスタイル。Rawは、トラップsyscallではなく命令を使用します。64ビットでの不正な命令です。int 0x80int 0x80

「GCCメソッド」がsyscallの分類を処理するため、sys/syscall.hにあるのと同じ32ビットの数値を使用できます。ただし、生の場合は、タイプIDとORをとって、どのようなシステムコールであるかを分類する必要があります。これが両方の例です。呼び出し規約が異なることに注意してください!(これは私を悩ませるNASMので構文です)gas

; assemble with
; nasm -f macho64 -o syscall64.o syscall64.asm && ld -lc -ldylib1.o -e start -o syscall64 syscall64.o
extern _syscall
global start

[section .text align=16]
start:
    ; do it gcc-style
    mov rdi, 0x4 ; sys_write
    mov rsi, 1 ; file descriptor
    mov rdx, hello
    mov rcx, size
    call _syscall ; we're calling a procedure, not trapping.
    
    ;now let's do it raw
    mov rax, 0x2000001 ; SYS_exit = 1 and is type 2 (bsd call)
    mov rdi, 0 ; Exit success = 0
    syscall ; faster than int 0x80, and legal!
    
    
[section .data align=16]
hello: db "hello 64-bit syscall!", 0x0a
size: equ $-hello

システムコールの入力方法の詳細については、http: //www.opensource.apple.com/source/xnu/xnu-792.13.8/osfmk/mach/i386/syscall_sw.hを確認してください。

于 2012-03-28T10:37:42.797 に答える
2

システムコールインターフェイスは、32ビットと64ビットで異なります。まず、int $80に置き換えられsyscall、システムコール番号が異なります。システムコールの64ビットバージョンのドキュメントを検索する必要があります。これは、64ビットプログラムがどのように見えるかの例です

于 2012-03-27T02:07:53.160 に答える