【问题标题】:what is segment 00 in my Linux executable program (64 bits)我的 Linux 可执行程序中的段 00 是什么(64 位)
【发布时间】:2021-03-17 22:14:30
【问题描述】:

这里是一个很简单的汇编程序,执行后返回12即可。

$ cat a.asm
        global _start

        section .text
_start: mov rax, 60    ; system call for exit
        mov rdi, 12    ; exit code 12
        syscall

可以正确构建和执行:

$ nasm -f elf64 a.asm && ld a.o && ./a.out || echo $?
12

但是a.out的大小很大,超过4k:

$ wc -c a.out
4664 a.out

我尝试通过阅读精灵内容来理解它:

$ readelf -l a.out

Elf file type is EXEC (Executable file)
Entry point 0x401000
There are 2 program headers, starting at offset 64

Program Headers:
  Type           Offset             VirtAddr           PhysAddr
                 FileSiz            MemSiz              Flags  Align
  LOAD           0x0000000000000000 0x0000000000400000 0x0000000000400000
                 0x00000000000000b0 0x00000000000000b0  R      0x1000
  LOAD           0x0000000000001000 0x0000000000401000 0x0000000000401000
                 0x000000000000000c 0x000000000000000c  R E    0x1000

 Section to Segment mapping:
  Segment Sections...
   00     
   01     .text 

很奇怪,段00是按0x1000对齐的,我想这意味着这样的段至少会占用4096字节。

我的问题是这个段 00 是什么?

(nasm 版本 2.14.02,ld 版本 2.34,os 是 Ubuntu 20.04.1)

【问题讨论】:

    标签: linux assembly linker ld elf


    【解决方案1】:

    由于它从文件偏移量零开始,它可能是为了使 ELF 的加载更有效而引入的“填充”段。 实际上,.text 段已经在文件中对齐,因为它应该在内存中。

    您可以强制 ld not 将内存中的部分和 文件中的部分与-n 对齐。您也可以使用 -s 去除符号。
    这会将大小减少到大约 352 字节。

    现在 ELF 包含:

    • ELF 标头(需要)
    • 程序头表(需要)
    • 代码(需要)
    • 字符串表(可能不需要)
    • 节表(可能不需要)

    字符串表可以删除,但显然strips 不能这样做。 我已经手动删除了.shstrtab 部分数据和所有部分标题,以将大小缩小到 144 字节。 考虑到 64 个字节来自 ELF 标头,60 个来自单个程序标头,12 个来自您的代码;总共 136 个字节。
    额外的 8 个字节是填充,4 个字节在代码段的末尾(易于删除),一个在程序头的末尾(需要一些补丁)。

    【讨论】:

    • 我相信如果您取消引用 NULL 指针,它会创建一个段错误。 (包括p->member,当p 为NULL 并且member 在结构内的某个适度偏移时。)
    • 你在想zero page吗? ELF 没有加载到虚拟地址 0 并且段存在于内存中。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-11-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-09-23
    • 2018-08-10
    • 1970-01-01
    相关资源
    最近更新 更多