使用自定义链接描述文件了解简单的"Hello World"的分段错误-段名称或基址低于64k [英] Understanding Segmentation Faults with a custom linker script for a simple 'Hello World' - section names or base address below 64k
问题描述
x86_64 Linux上多次见过的基本Hello World:
Basic Hello World as seen many times before on x86_64 Linux:
global my_start_symbol
section .text
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
链接描述文件:
My working ld
linker script:
ENTRY(my_start_symbol)
SECTIONS
{
. = 0x10000;
.text : { *(.text*) }
.rodata : { *(.rodata*) }
}
调用者:
nasm -f elf64 assembly.asm -o assembly.o
ld -T linker.ld assembly.o -o assembly
尝试以下更改时会遇到各种细分错误:
I get various segmentation faults when I experiment with the following changes:
- 如果我删除了
.= 0x10000
在我的链接描述文件中,或者使其小于0x10000
的任何值,我都会遇到段错误.我以为这可能是由于页面大小所致,但是getconf PAGE_SIZE
返回4K,所以我不知道为什么8K是必要的. - 如果我在程序集文件中将
.text
部分更改为.my_section_name
并更新链接器以显示.my_section_name:{*(.my_section_name *)}
我遇到了段错误.我认为像.text
,.data
等这样的节名称是按惯例编写的,您可以根据需要将其设置为任意名称.如果我错了,为什么.text:{*(.my_section_name *)}
也会出现段错误?
- If I remove the
. = 0x10000
inside of my linker script or make it anything less than0x10000
I get a segfault. I thought this may be due to page size, howevergetconf PAGE_SIZE
returns 4K, so I don't know why 8K is necessary. - If I change the
.text
section in my assembly file to say.my_section_name
and update the linker to say.my_section_name : { *(.my_section_name*) }
I get a segfault. I thought the section names like.text
,.data
etc. were by convention, and that you could make them anything you wanted. If I'm wrong, why would.text : { *(.my_section_name*) }
give a segfault also?
推荐答案
0x10000
的最小值可能是由于 vm.mmap_min_addr = 65536
( ptr [i]
之类的代码具有中等索引的情况下,也能确保NULL-deref发出错误的声音.
The 0x10000
minimum is probably due to the default setting of vm.mmap_min_addr = 65536
(https://wiki.debian.org/mmap_min_addr), preventing user-space from mapping any low-address pages to make sure that NULL-deref faults noisily, even for code like ptr[i]
with some medium-sized index.
一些名称,例如 .text
是特殊的(对于NASM和/或ld),并且具有一组默认的权限(在这种情况下为read + exec).一些随机名称可能是不带exec的读写.检查 readelf -a a.out
,尤其是程序标头(控制内核如何将可执行程序映射到内存中).
A few names like .text
are special (for NASM and/or ld), and have a default set of permissions (in this case read + exec). Some random name is probably read + write without exec. Check with readelf -a a.out
, epsecially the Program Headers (which govern how an executable is mapped into memory by the kernel).
看看 readelf -a hello.o
来检查NASM输出中的节头可能也很有趣.
Also probably interesting to have a look at readelf -a hello.o
to check the section headers in the NASM output.
这篇关于使用自定义链接描述文件了解简单的"Hello World"的分段错误-段名称或基址低于64k的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!