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

How to make a custom section executable (other than .text)

之前在 x86_64 上多次看到的基本 Hello World 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

我当前的 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
}

调用方式:

nasm -f elf64 assembly.asm -o assembly.o
ld -T linker.ld assembly.o -o assembly

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

我的评估(至少 x86_64 Linux 和 NASM):

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