我的Linux可执行程序中的段00是什么(64位)

这是一个很简单的汇编程序,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)

回答

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

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

现在 ELF 包含:

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

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


以上是我的Linux可执行程序中的段00是什么(64位)的全部内容。
THE END
分享
二维码
< <上一篇
下一篇>>