位置独立代码指向错误的地址 [英] Position Independent Code pointing to wrong address

查看:95
本文介绍了位置独立代码指向错误的地址的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个用NASM(2.11.08)编写的,针对macho64体系结构的小示例程序.我正在运行OSX 10.10.3:

I have a small example program written in NASM(2.11.08) targeting the macho64 architecture. I'm running OSX 10.10.3:

bits 64

section .data

    msg1    db 'Message One', 10, 0
    msg1len equ $-msg1
    msg2    db 'Message Two', 10, 0
    msg2len equ $-msg2

section .text
    global  _main
    extern  _printf

_main:
    sub     rsp, 8  ; align

    lea     rdi, [rel msg1]
    xor     rax, rax
    call    _printf

    lea     rdi, [rel msg2]
    xor     rax, rax
    call    _printf

    add rsp, 8
    ret

我正在使用以下命令行进行编译和链接:

I'm compiling and linking using the following command line:

/usr/local/bin/nasm -f macho64 test2.s
ld -macosx_version_min 10.10.0 -lSystem -o test2 test2.o

当我在test2可执行文件上执行对象转储时,这是相关的代码段(如果我输入错了,我可以发布更多内容!):

When I do an object dump on the test2 executable, this is the relevant snippet(I can post more if I'm wrong!):

0000000000001fb7 <_main>:
1fb7:   48 83 ec 08             sub    $0x8,%rsp
1fbb:   48 8d 3d 56 01 00 00    lea    0x156(%rip),%rdi        # 2118 <msg2+0xf3>
1fc2:   48 31 c0                xor    %rax,%rax
1fc5:   e8 14 00 00 00          callq  1fde <_printf$stub>
1fca:   48 8d 3d 54 00 00 00    lea    0x54(%rip),%rdi        # 2025 <msg2>
1fd1:   48 31 c0                xor    %rax,%rax
1fd4:   e8 05 00 00 00          callq  1fde <_printf$stub>
1fd9:   48 83 c4 08             add    $0x8,%rsp
1fdd:   c3                      retq  

...

0000000000002018 <msg1>:
0000000000002025 <msg2>:

最后,输出:

$ ./test2
Message Two
$

我的问题是,味精1发生了什么事?

My question is, what happened to msg1?

我假设未打印msg1,因为0x14f(%rip)不是正确的地址(只是null).

I'm assuming msg1 isn't printed because 0x14f(%rip) is not the correct address (just nulls).

为什么lea edi, [rel msg2]指向正确的地址,而lea edi, [rel msg1]则指向经过msg2的空值?

Why is lea edi, [rel msg2] pointing to the correct address, while lea edi, [rel msg1] is pointing past msg2, into NULLs?

看起来0x14f(%rip)的偏移量正好比msg1在内存中的位置偏移0x100(在对这个问题的许多测试中都是如此).

It looks like the 0x14f(%rip) offset is exactly 0x100 beyond where msg1 lies in memory (this is true throughout many tests of this problem).

我在这里想念什么?

.data部分最后出现的消息(msg1或msg2)是唯一打印的消息.

Whichever message (msg1 or msg2) appears last in the .data section is the only message that gets printed.

推荐答案

关于Mach-o ABI的IDK,但是如果它与GNU/Linux使用的SystemV x86-64 ABI相同,那么我认为您的问题是您需要清除eax来告诉像printf这样的varargs函数FP为零.

IDK about the Mach-o ABI, but if it's the same as the SystemV x86-64 ABI GNU/Linux uses, then I think your problem is that you need to clear eax to tell a varargs function like printf that there are zero FP.

此外,lea rdi, [rel msg1]是一个更好的选择.就目前而言,您的代码仅在虚拟地址空间的低32位内与位置无关,因为您要截断指向32位的指针.

Also, lea rdi, [rel msg1] would be a much better choice. As it stands, your code is only position-independent within the low 32bits of virtual address space, because you're truncating the pointers to 32bits.

NASM似乎有错误.再次出现相同的问题: NASM 2行的db(初始化数据)似乎不起作用.在那里,OP确认存在数据,但标签有误,并希望向上游报告.

It appears NASM has a bug. This same problem came up again: NASM 2 lines of db (initialized data) seemingly not working. There, the OP confirmed that the data was present, but labels were wrong, and is hopefully reporting it upstream.

这篇关于位置独立代码指向错误的地址的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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