如何使自定义部分可执行(.text 除外)

Rya*_*lue 5 linux x86-64 nasm ld linker-scripts

基本的 Hello World 就像之前在 x86_64 Linux 上多次看到的那样:

global my_start_symbol 

section .my_section

my_start_symbol:
        mov rax, 1
        mov rdi, 1 
        mov rsi, msg
        mov rdx, msg_len
        syscall 

        mov rax, 60
        xor rdi, rdi
        syscall

section .rodata:
msg: db "Hello, world!", 10 
msg_len: equ $ - msg
Run Code Online (Sandbox Code Playgroud)

我当前的ld链接器脚本:

__linux_mmap_min_addr = 0x10000;

ENTRY(my_start_symbol)

MEMORY
{
  rom (rx) : ORIGIN = 0, LENGTH = 512K
}

SECTIONS 
{
  . = __linux_mmap_min_addr;
  .my_section : 
  { 
    *(.my_section*) 
  } > rom
  .rodata : 
  {
    *(.rodata*) 
  } > rom
}
Run Code Online (Sandbox Code Playgroud)

调用方式:

nasm -f elf64 assembly.asm -o assembly.o
ld -T linker.ld assembly.o -o assembly
Run Code Online (Sandbox Code Playgroud)

我目前遇到了段错误。检查输出,readelf -a我可以看到它my_section没有可执行权限。我相信这是导致段错误的原因。如果我用它替换.text : { *(.my_section*) } > rom它仍然不会被设置为可执行文件。只有当我恢复.text按惯例在任何地方使用时,它才会将其设置为可执行文件。

Rya*_*lue 1

我的评估(至少在带有 NASM 的 x86_64 Linux 上):

  1. 定义中设置的标志ld MEMORY与将该节设置为可执行无关。NASM ELF 部分扩展是最重要的,section .my_section exec即即使MEMORY没有x标志也可以工作(感谢@peter-cordes)。
  2. 如果您有ld MEMORY正在使用的特定定义,则原点不能是0,但必须至少是(有关更多信息,0x10000请参阅此SO 问答. = 0x10000;)在本节开头使用是不够的。