gpt4 book ai didi

无法使用 ld 链接目标文件 - Mac OS X

转载 作者:太空狗 更新时间:2023-10-29 15:50:52 39 4
gpt4 key购买 nike

/*********
exit.asm
*/

[SECTION .text]

global _start


_start:
xor eax, eax
xor ebx, ebx
mov al, 1
int 0x80

//****************************

首先我使用 nasm -f elf exit.asm 生成目标文件。

然后我在我的 Mac OS X 10.7 上运行了以下“ld”命令,它有这些输出和警告,我试着在我的 32 位 linux 机器上运行它,一切都很好,你能解释一下为什么链接器不能在我的 Mac 上工作吗?

谢谢!

Alfred says: ld -o exiter exit.o
ld: warning: -arch not specified
ld: warning: -macosx_version_min not specified, assuming 10.7
ld: warning: ignoring file exit.o, file was built for unsupported file format ( 0x7f 0x45 0x4c 0x46 0x 1 0x 1 0x 1 0x 0 0x 0 0x 0 0x 0 0x 0 0x 0 0x 0 0x 0 0x 0 ) which is not the architecture being linked (x86_64): exit.o
Undefined symbols for architecture x86_64:
"start", referenced from:
implicit entry/start for main executable
ld: symbol(s) not found for inferred architecture x86_64

在指定架构和版本后,我得到:

Alfred says: ld -arch x86_64 -macosx_version_min 10.7 -o exiter exit.o
ld: warning: ignoring file exit.o, file was built for unsupported file format ( 0x7f 0x45 0x4c 0x46 0x 1 0x 1 0x 1 0x 0 0x 0 0x 0 0x 0 0x 0 0x 0 0x 0 0x 0 0x 0 ) which is not the architecture being linked (x86_64): exit.o
Undefined symbols for architecture x86_64:
"start", referenced from:
implicit entry/start for main executable
ld: symbol(s) not found for architecture x86_64

最佳答案

让程序链接起来很容易:

  • _start 更改为 start
  • $ nasm -f macho exit.asm
  • $ ld -arch i386 -o exiter exit.o

问题是 exit.asm 正在调用 i386 Linux exit() 系统调用 (EAX = 1) 并且程序会NOT 在 OS X 上以零状态退出。

系统调用

系统调用 是对内核的请求。 exit()sqrt() 不同,它必须向在其实现中具有更高权限的软件组件发出请求,因为它会终止正在运行的程序。应用程序无法自行创建或终止进程。系统调用为应用程序提供了一种请求内核代表它们执行操作的方法。

进行系统调用是这样的:

  • 应用通过将数据放入 CPU 寄存器(或寄存器指向的内存)来描述它们想要执行的操作,例如
    • EAX中的值1exit的系统调用号。
    • EBX 中的值 0(EBX 已被 xor 清除)是系统调用的第一个参数, 退出状态。
  • 应用程序发出一条指令,使控制权转移到内核,例如
    • int 80 在 i386 上
    • sycall 在 x86-64 上
    • svc 在 ARMv7 上采用 Thumb 模式
  • 内核检查请求并决定执行或拒绝它。
  • 内核将控制权转移回应用程序,返回值位于商定的位置,例如EAX 在 i386 上。

Linux 和 OS X 都为 C 程序提供了一个 void exit(int) 函数,但是对于如何向内核描述这个请求的细节没有达成一致。 exit.asm中的代码与libc_exit()函数的实现处于同一层次。

即使在运行 Linux 的不同架构之间,系统调用编号和调用约定也不同。例如在 x86-64 Linux 上,exit(0) 通常是这样发出的:

xor rdi, rdi
mov al, 60
syscall

你可以通过反汇编 /lib64/libc.so.6 中的 _exit 来看到这一点。

我们不能直接从 libc 调用 exit() 吗?

可以。但是您必须将程序与 libc 链接起来。这是将上面的 exit.asm 与以下链接之间的区别:

$ cc -m32 -nostdlib exit.o -o exiter

exit-libc.asm

extern exit
global main
main:
push 0
call exit

必须链接到:

$ cc -m32 exit-libc.o -o exit-libc

试试看文件大小。

关于无法使用 ld 链接目标文件 - Mac OS X,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16801432/

39 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com