访问位置无关代码中的.data部分 [英] Access .data section in Position Independent Code

查看:78
本文介绍了访问位置无关代码中的.data部分的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在与NASM建立共享库.在该库中的某些函数中,我需要在C中称为静态变量的东西.基本上,我认为它在.data节中有一定的空间:

I'm building a shared library with NASM. In that library, in some function, I need what we'd call a static variable in C. Basically, I think it is some space in the .data section:

    SECTION .data
last_tok:       dq 0 ; Define a QWORD

当我尝试在函数中访问 last_tok 时出现问题.

The problem arises when I try to access last_tok in my function.

我阅读了 NASM手册:8.2编写Linux/ELF共享库解释了问题并给出了解决方案.

I read the NASM Manual: 8.2 Writing Linux/ELF Shared Libraries which explains the problem and gives the solution.

    SECTION .data
last_tok:              dq 0     ; Define a QWORD

    SECTION .text
    EXTERN _GLOBAL_OFFSET_TABLE_
    GLOBAL strtok:function
strtok:
    enter    0, 0
    push     rbx
    call     .get_GOT
.get_GOT:
    pop      rbx
    add      rbx, _GLOBAL_OFFSET_TABLE_ + $$ - .get_GOT wrt ..gotpc

    mov      [rbx + last_tok wrt ..gotoff], rdi ; Store the contents of RDI at last_tok

    mov      rbx, [rbp - 8]
    leave
    ret

它可能与ELF32一起使用,但与ELF64一起出现以下错误:

It may work with ELF32, but with ELF64 I get the following error:

nasm -f elf64  -o strtok.o strtok.s
strtok:15: error: ELF64 requires ..gotoff references to be qword
<builtin>: recipe for target 'strtok.o' failed
make: *** [strtok.o] Error 1

我在做什么错了?

推荐答案

有效的地址格式仅允许32位位移,并将其符号扩展为64位.根据错误消息,您需要完整的64位.您可以通过寄存器将其添加,例如:

The effective address format only allows for 32 bit displacement that is sign extended to 64 bit. According to the error message, you need full 64 bits. You can add it via a register, such as:

mov      rax,  last_tok wrt ..gotoff
mov      [rbx + rax], rdi 

此外,call .get_GOT是32位解决方案,在64位模式下,您可以在其中使用rip相对寻址.虽然上面可以编译,但是我不确定它是否可以工作.幸运的是,简单的解决方案是使用提及的rip相对地址来访问您的变量,这样:

Also, the call .get_GOT is a 32 bit solution, in 64 bit mode you have rip relative addressing which you can use there. While the above may compile, but I am not sure it will work. Luckily the simple solution is to use the mentioned rip relative addressing to access your variable thus:

    SECTION .data
    GLOBAL last_tok
last_tok:              dq 0     ; Define a QWORD

    SECTION .text
    GLOBAL strtok:function
strtok:
    mov      [rel last_tok wrt ..gotpc], rdi ; Store the contents of RDI at last_tok
    ret

请注意,对于私有(静态)变量,您可以只使用[rel last_tok]而不用完全搞定gett.

Note that for a private (static) variable you can just use [rel last_tok] without having to mess with the got at all.

这篇关于访问位置无关代码中的.data部分的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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