You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

为何部分ELF节会被映射到多个程序段?(Android NDK场景)

ELF节被映射到多个程序段的原因解析

在对一个简单的Android NDK二进制文件执行readelf命令时,发现部分ELF节(比如.note.gnu.build-id、.note.android.ident、.eh_frame_hdr、.dynamic、.got等)被映射到多个程序段,请问该现象的原因是什么?

对应的readelf输出信息如下:

readelf libhellondk.so -lW

Elf file type is DYN (Shared object file)
Entry point 0xef30
There are 8 program headers, starting at offset 64

Program Headers:
  Type           Offset   VirtAddr           PhysAddr           FileSiz  MemSiz   Flg Align
  LOAD           0x000000 0x0000000000000000 0x0000000000000000 0x0301d8 0x0301d8 R E 0x1000
  LOAD           0x030d48 0x0000000000031d48 0x0000000000031d48 0x0032e0 0x003768 RW  0x1000
  DYNAMIC        0x033aa0 0x0000000000034aa0 0x0000000000034aa0 0x0001f0 0x0001f0 RW  0x8
  NOTE           0x000200 0x0000000000000200 0x0000000000000200 0x000024 0x000024 R   0x4
  NOTE           0x030140 0x0000000000030140 0x0000000000030140 0x000098 0x000098 R   0x4
  GNU_EH_FRAME   0x02b144 0x000000000002b144 0x000000000002b144 0x000e34 0x000e34 R   0x4
  GNU_STACK      0x000000 0x0000000000000000 0x0000000000000000 0x000000 0x000000 RW  0x10
  GNU_RELRO      0x030d48 0x0000000000031d48 0x0000000000031d48 0x0032b8 0x0032b8 R   0x1

 Section to Segment mapping:
  Segment Sections...
   00     .note.gnu.build-id .hash .gnu.hash .dynsym .dynstr .gnu.version .gnu.version_r .rela.dyn .rela.plt .plt .text .rodata .eh_frame_hdr .eh_frame .gcc_except_table .note.android.ident
   01     .fini_array .data.rel.ro .dynamic .got .data .bss
   02     .dynamic
   03     .note.gnu.build-id
   04     .note.android.ident
   05     .eh_frame_hdr
   06
   07     .fini_array .data.rel.ro .dynamic .got

原因解析

  • LOAD段是内存加载的基础:LOAD类型的程序段负责把ELF文件中的内容实际加载到内存中,所有需要驻留内存的节都会被包含在至少一个LOAD段里。比如.note.gnu.build-id属于只读可执行的LOAD0段,.dynamic属于读写的LOAD1段,这是程序运行的基本要求。
  • 专用程序段是元信息标记:那些重复映射的段(NOTE、DYNAMIC、GNU_EH_FRAME、GNU_RELRO)并不是重复加载内容,而是给系统加载器/动态链接器提供快速定位关键信息的标记:
    • NOTE段:直接标记.note.gnu.build-id、.note.android.ident这类元数据节,让加载器不用遍历整个LOAD段就能获取构建ID、平台标识等信息。
    • DYNAMIC段:专门指向.dynamic节,动态链接器需要靠这个节处理依赖库加载、符号重定位等核心逻辑,单独标记能提升访问效率。
    • GNU_EH_FRAME段:标记.eh_frame_hdr节,这是C++异常处理的关键元数据,调试器或异常处理机制可以快速定位它。
    • GNU_RELRO段:标记.dynamic、.got等需要设置只读保护的区域,这是一种安全机制,加载器初始化完成后会把这段内存设为只读,防止恶意篡改。
  • 无内存冗余:这些"重复映射"只是逻辑上的段标记,物理内存中对应的节内容只会被加载一次,多个程序段只是指向同一块内存地址,不会浪费内存空间。

内容的提问来源于stack exchange,提问作者Fee

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.18 20:54:53