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

问题描述

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

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 时,它才会将其设置为可执行文件

解决方法

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

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