Mac OS X 上的 64 位程序集运行时错误:“dyld:无可写段";和“跟踪/BPT陷阱" [英] 64 bit assembly on Mac OS X runtime errors: "dyld: no writable segment" and "Trace/BPT trap"
问题描述
尝试运行以下汇编程序时:
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
知道是什么原因造成的吗?32 位汇编中的类似程序运行良好.
Any idea what could be causing this? The analogous program in 32 bit assembly runs fine.
推荐答案
OSX 现在要求您的可执行文件具有包含内容的可写数据段,以便它可以动态地重新定位和链接您的代码.不知道为什么,也许是安全原因,也许是由于新的 RIP 寄存器.如果您在其中放置一个 .data 段(带有一些虚假内容),您将避免无可写段"错误.IMO 这是一个 ld 错误.
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 使用 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 方法"将负责为您分类系统调用,因此您可以使用在 sys/syscall.h 中找到的相同 32 位数字.但是,如果您采用原始方法,则必须通过将其与类型 ID 进行 ORing 来对它是哪种系统调用进行分类.这是两者的示例.请注意,调用约定是不同的!(为 NASM 语法道歉;gas 惹恼了我)
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
查看 http://www.opensource.apple.com/source/xnu/xnu-792.13.8/osfmk/mach/i386/syscall_sw.h 了解有关如何键入系统调用的更多信息.
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:无可写段";和“跟踪/BPT陷阱"的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!