用LD不能链接对象文件 - 的Mac OS X [英] Can't link object file using ld - Mac OS X

查看:781
本文介绍了用LD不能链接对象文件 - 的Mac OS X的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

  / *********
exit.asm
* /[.text段]全球_start
_开始:
XOR EAX,EAX
XOR EBX,EBX
MOV人,1
INT 0x80的// ************

首先,我用NASM -f精灵exit.asm生成对象文件。

然后我跑到下面的LD命令,在我的Mac OS X 10.7,它有这些输出,并警告,我想我的32位Linux机器上运行它,一切都通过就好了,
你能解释一下为什么不上我的Mac连接器的工作?

感谢您!

 阿尔弗雷德说:LD -o exiter exit.o
LD:警告:-ARCH没有指定
LD:警告:-macosx_version_min没有指定,假定10.7
LD:警告:忽略文件exit.o,文件是专为不支持的文件格式(到0x7f 0x4c×45 0X的0x46 1 0X 1 0X 1 0X 0 0X 0 0X 0 0X 0 0X 0 0X 0 0X 0 0X 0 0X 0),这是不该架构被链接(x86_64的):exit.o
适用于建筑x86_64的未定义符号:
  开始,从引用:
    隐进入/启动主可执行
LD:符号(S)未找到推断架构的x86_64

在我指定我的弓和版本,我得到了:

 阿尔弗雷德说:LD -arch x86_64的-macosx_version_min 10.7 -o exiter exit.o
LD:警告:忽略文件exit.o,文件是专为不支持的文件格式(到0x7f 0x4c×45 0X的0x46 1 0X 1 0X 1 0X 0 0X 0 0X 0 0X 0 0X 0 0X 0 0X 0 0X 0 0X 0),这是不该架构被链接(x86_64的):exit.o
 适用于建筑x86_64的未定义符号:
 开始,从引用:
    隐进入/启动主可执行
 LD:符号(S)未找到x86_64的架构


解决方案

获取程序链接是比较容易的部分:


  • 更改 _start 启动

  • $ NASM -f男子气exit.asm

  • $ LD -arch i386的-o exiter exit.o

问题是, exit.asm 正在调用的i386平台Linux的退出()系统调用( EAX = 1),程序会的的使用按预期在OS X零状态退出。

系统调用

A 系统调用的是内核的请求。 退出(),不像的sqrt(),必须在其执行更高的权限,因为一个软件组件的请求它终止正在运行的程序。应用无法创建或自行终止进程。系统调用为应用程序请求内核代表他们执行的操作的方式。

制作一个系统调用是这样的:


  • 应用程序描述他们要执行的操作是将数据置于CPU寄存器(或存储器由寄存器指向的),例如

    • 1 EAX 退出系统调用号

    • 0 EBX EBX 被清零 XOR )是第一个参数的系统调用,退出状态。


  • 应用程序的问题,导致控制转移到内核的指令,例如

    • 80 INT 在i386

    • sycall 上的x86-64

    • SVC 在Thumb模式的ARMv7


  • 内核检查的请求,并决定执行或拒绝它。

  • 内核将控制权转移回与返回值的应用程序在对的位置一致,例如 EAX 在i386。

Linux和OS X都提供了无效出口(INT)对C程序功能,但不上该怎么形容这个请求给内核的细节达成一致。在 exit.asm 的code是在同一水平 _exit()功能的实现的libc

即使运行Linux系统调用号和调用约定不同,不同的架构之间。例如在X86-64的Linux,退出(0)更常用这样的发出:

 异或偏下,偏下
MOV人,60
系统调用

您可以通过拆卸 _exit /lib64/libc.so.6 看到这一点。

我们不能只从调用的libc相反的exit()?

您可以。但你不得不计划与的libc 链接。它是连接之间的差异 exit.asm 上面:

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

退出-libc.asm

 退出的extern
全球主要
主要:
推0
调用exit

这必须与被链接:

  $ CC -m32退出-libc.o -o退出-libc中

试试这个,看看文件的大小。

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

[SECTION .text]

global _start


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

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

First I used nasm -f elf exit.asm to generate the object file.

then I ran the following "ld" command on my Mac OS X 10.7, it has the these outputs and warning, I tried to run it on my 32 bit linux machine, everything went through just fine, Could you please explain why would not the linker work on my Mac?

Thank you!

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

after I specify my arch and version, I got:

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

解决方案

Getting the program to link is the easy part:

  • Change _start to start
  • $ nasm -f macho exit.asm
  • $ ld -arch i386 -o exiter exit.o

The problem is that exit.asm is calling the i386 Linux exit() system call (EAX = 1) and the program would NOT exit with a zero status as intended on OS X.

System Calls

A system call is a request to the kernel. exit(), unlike sqrt(), must make a request to a software component with higher privileges in its implementation since it terminates a running program. Apps can't create or terminate processes by themselves. System calls provide a way for apps to ask the kernel to perform actions on their behalf.

Making a syscall goes something like this:

  • Apps describe the operation they want to perform by placing data in CPU registers (or memory pointed to by registers), e.g.
    • The value 1 in EAX is the system call number of exit.
    • The value 0 in EBX (EBX was cleared by xor) is the first argument to the syscall, the exit status.
  • Apps issue an instruction that causes control to transfer to the kernel, e.g.
    • int 80 on i386
    • sycall on x86-64
    • svc in Thumb mode on ARMv7
  • The kernel inspects the request and decides to perform or deny it.
  • The kernel transfers control back to the app with the return value in an agreed upon location, e.g. EAX on i386.

Linux and OS X both provide a void exit(int) function for C programs but don't agree on the details on how to describe this request to the kernel. The code in exit.asm is at the same level as the implementation of the _exit() function in libc.

Even between different architectures running Linux the syscall numbers and calling convention differ. e.g. On x86-64 Linux, exit(0) is more commonly issued like this:

xor rdi, rdi
mov al, 60
syscall

You can see this by disassembling _exit in /lib64/libc.so.6.

Can't We Just Call exit() from libc Instead?

You can. But you'd have to link the program with libc. It's the difference between linking exit.asm above with:

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

and

exit-libc.asm

extern exit
global main
main:
push 0
call exit

which has to be linked with:

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

Try this and take a look at the file size.

这篇关于用LD不能链接对象文件 - 的Mac OS X的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆