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

无.interp段的libonload.so为何具备可执行性?

为什么无.interp段的libonload.so可直接执行?

我了解libc.so可执行的原因如下:

  • libc.so拥有入口点函数
  • libc.so中存在.interp段

查阅资料得知,.interp段被认为是可执行共享对象的必要条件,但我发现libonload.so(SolarFlare网卡驱动)可直接执行,而readelf显示其无.interp段,无法理解其运行机制。

执行libonload.so的结果

[root@localhost onload-7.1.1.75]# /usr/lib64/libonload.so 
Onload 7.1.1.75
Copyright 2019-2021 Xilinx, 2006-2019 Solarflare Communications, 2002-2005 Level 5 Networks
Built: Mar  4 2024 15:49:30 (release)
Build profile header: <ci/internal/transport_config_opt_extra.h>

readelf -l /usr/lib64/libonload.so的输出

[root@localhost onload-7.1.1.75]# readelf -l /usr/lib64/libonload.so 

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

Program Headers:
  Type           Offset             VirtAddr           PhysAddr
                 FileSiz            MemSiz              Flags  Align
  LOAD           0x0000000000000000 0x0000000000000000 0x0000000000000000
                 0x00000000000a5ff0 0x00000000000a5ff0  R E    200000
  LOAD           0x00000000000a6818 0x00000000002a6818 0x00000000002a6818
                 0x0000000000002770 0x0000000000003060  RW     200000
  DYNAMIC        0x00000000000a6d90 0x00000000002a6d90 0x00000000002a6d90
                 0x00000000000001f0 0x00000000000001f0  RW     8
  NOTE           0x0000000000000200 0x0000000000000200 0x00000000000000200
                 0x0000000000000024 0x0000000000000024  R      4
  TLS            0x00000000000a6818 0x00000000002a6818 0x00000000002a6818
                 0x0000000000000000 0x0000000000000bec  R      8
  GNU_EH_FRAME   0x0000000000094684 0x0000000000094684 0x0000000000094684
                 0x000000000000245c 0x000000000000245c  R      4
  GNU_STACK      0x0000000000000000 0x0000000000000000 0x0000000000000000
                 0x0000000000000000 0x0000000000000000  RW     10
  GNU_RELRO      0x00000000000a6818 0x00000000002a6818 0x00000000002a6818
                 0x00000000000007e8 0x00000000000007e8  R      1

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

我的测试过程

参照onload源码编写了示例程序:

#include <sys/uio.h>                                                                                                         
#include <linux/unistd.h>
#include <unistd.h>
int my_do_syscall3(int num, long a1, long a2, long a3)
{
  int rc;
  __asm__ __volatile__(

   "syscall"
   : "=a" (rc)
   : "0"((long)num), "D"(a1), "S"(a2), "d"(a3)
   : "r11","rcx","memory"

  );

  return rc;
}

#define my_syscall3(call, a1, a2, a3) \
        my_do_syscall3(__NR_##call, (a1), (a2), (a3))
extern "C" int func()
{
        struct iovec v[1];
        static const char msg0[] = "Hello so\n";

        v[0].iov_base = (void*) msg0;
        v[0].iov_len  = sizeof(msg0)-1;

        my_syscall3(writev, STDOUT_FILENO, (long) v, 1);
        my_syscall3(exit, 0, 0, 0);

        return 0;
}

编译命令:

gcc -fPIC -shared -e func test.cpp -o libtest.so     

执行./libtest.so时出现段错误。随后添加.interp段:

extern const char elf_interpreter[] __attribute__((section(".interp"))) = "/lib64/ld-linux-x86-64.so.2";

重新编译后程序正常运行。最后给my_do_syscall3添加static修饰符后,程序无需.interp段也能正常运行。想了解libonload.so无需.interp段即可执行的原理。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.28 15:24:53