本文介绍了Mac OS X运行时错误的64位汇编:“ dyld:no writable segment”和“跟踪/ BPT陷阱”;的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

尝试运行以下汇编程序时:

When attempting to run the following assembly program:

.globl start

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

我收到以下错误:

dyld: no writable segment
Trace/BPT trap

任何人都知道是什么原因引起的吗?

Any idea what could be causing this? The analogous program in 32 bit assembly runs fine.

推荐答案

OSX现在要求您的可执行文件具有包含内容的可写数据段,因此,该程序运行良好。它可以动态地重新定位和链接您的代码。 Dunno为什么,也许是安全原因,也许是由于新的RIP寄存器。如果在其中放置.data段(内容有些虚假),则可以避免出现 no writable segment错误。 IMO,这是一个ld bug。

OSX now requires your executable to have a writable data segment with content, so it can relocate and link your code dynamically. Dunno why, maybe security reasons, maybe due to the new RIP register. If you put a .data segment in there (with some bogus content), you'll avoid the "no writable segment" error. IMO this is an ld bug.

对于64位系统调用,您可以使用两种方法来实现。 GCC样式,它使用来自libSystem.dylib的_syscall PROCEDURE或raw。 Raw使用syscall指令,而不是int 0x80陷阱。 int 0x80是64位上的非法指令。

Regarding the 64-bit syscall, you can do it 2 ways. GCC-style, which uses the _syscall PROCEDURE from libSystem.dylib, or raw. Raw uses the syscall instruction, not the int 0x80 trap. "int 0x80" is an illegal instruction in 64-bit.

GCC方法将为您对syscall进行分类,因此您可以使用相同的32位sys / syscall.h中找到的位数。但是,如果您一无所获,则必须通过将其与类型ID进行或运算来对它进行分类。这是两个例子。请注意,调用约定是不同的! (对NASM语法表示歉意;气体使我烦恼)

The "GCC method" will take care of categorizing the syscall for you, so you can use the same 32-bit numbers found in sys/syscall.h. But if you go raw, you'll have to classify what kind of syscall it is by ORing it with a type id. Here is an example of both. Note that the calling convention is different! (apologies for NASM syntax; gas annoys me)

; 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

签出有关如何键入系统调用的更多信息。

check out http://www.opensource.apple.com/source/xnu/xnu-792.13.8/osfmk/mach/i386/syscall_sw.h for more info on how a syscall is typed.

这篇关于Mac OS X运行时错误的64位汇编:“ dyld:no writable segment”和“跟踪/ BPT陷阱”;的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

10-22 08:57