“ so”如何用固定地址加载一个so?

问题描述 投票:0回答:1

在我的程序中,两个“ so”-libcpss.so和libhelper.so必须加载到固定的虚拟地址中,它是由ld脚本完成的,

SECTIONS
{
/* Code section, access rights RX */
. = 0x14600000;
…
}

readelf -l libhelper.so |更少

Elf文件类型为DYN(共享对象文件)入口点0x14607ad8从偏移量64开始有8个程序头。

Program Headers:
  Type           Offset             VirtAddr           PhysAddr
                 FileSiz            MemSiz              Flags  Align
  LOAD           0x0000000000010000 0x0000000014600000 0x0000000014600000
                 0x000000000001aaec 0x000000000001aaec  R E    0x10000

与这两个“ .so”链接的elf程序,我们可以看到这两个确实被加载到了预期的固定地址中,

ldd ./appDemo

linux-vdso.so.1 => (0x0000ffff917ec000)
libcpss.so => ./libcpss.so (0x0000000010000000)
libhelper.so => ./libhelper.so (0x0000000014600000)
libpthread.so.0 => /lib/aarch64-linux-gnu/libpthread.so.0 (0x0000ffff917b5000)
librt.so.1 => /lib/aarch64-linux-gnu/librt.so.1 (0x0000ffff9179d000)
libdl.so.2 => /lib/aarch64-linux-gnu/libdl.so.2 (0x0000ffff91789000)
libm.so.6 => /lib/aarch64-linux-gnu/libm.so.6 (0x0000ffff916d7000)
libc.so.6 => /lib/aarch64-linux-gnu/libc.so.6 (0x0000ffff91583000)
/lib/ld-linux-aarch64.so.1 (0x0000aaaadd94f000)

但是,我建立了另一个“ so”,因此链接(取决于)这两个,因此似乎无法将这两个加载到正确的固定地址中,请参见下文-

ldd ./libtestScript.so

linux-vdso.so.1 => (0x0000ffff8d87c000)
libcpss.so => ./libcpss.so (0x0000ffff89d50000)
libhelper.so => ./libhelper.so (0x0000ffff5e350000)
libpthread.so.0 => /lib/aarch64-linux-gnu/libpthread.so.0 (0x0000ffff5e31c000)
librt.so.1 => /lib/aarch64-linux-gnu/librt.so.1 (0x0000ffff5e304000)
libdl.so.2 => /lib/aarch64-linux-gnu/libdl.so.2 (0x0000ffff5e2f0000)
libm.so.6 => /lib/aarch64-linux-gnu/libm.so.6 (0x0000ffff5e23e000)
libc.so.6 => /lib/aarch64-linux-gnu/libc.so.6 (0x0000ffff5e0ea000)
/lib/ld-linux-aarch64.so.1 (0x0000aaaae0958000)

我在构建“联合.so”期间是否错过了任何LD标志?我看到elf主程序和“ joint”之间的唯一区别是“ shared”标志,所以为什么“ joint .so”错过了两个从属so的加载地址的信息?似乎是当ld.so加载“ joint .so”并尝试解析并加载两个“ .so”依赖项时,但并没有将它们加载到固定地址(0x10000000 / 0x14600000)

NOK:LD_DEBUG =所有ldd ./libtestScript.so

  2349:     file=libhelper.so [0];  generating link map
  2349:       dynamic: 0x0000ffff5d581ba0  base: 0x0000ffff48f57000   size: 0x000000002b9ff004
  2349:         entry: 0x0000ffff5d55ead8  phdr: 0x0000ffff8ca6fcc0  phnum:                  8

确定:LD_DEBUG =全部ldd ./appDemo

  2289:       trying file=./libhelper.so
  2289:
  2289:     file=libhelper.so [0];  generating link map
  2289:       dynamic: 0x000000001462aba0  base: 0x0000000000000000   size: 0x000000002b9ff004
  2289:         entry: 0x0000000014607ad8  phdr: 0x0000ffffb2e24cc0  phnum:                  8

readelf -h ./libhelper.so

ELF Header:
  Magic:   7f 45 4c 46 02 01 01 00 00 00 00 00 00 00 00 00 
  Class:                             ELF64
  Data:                              2's complement, little endian
  Version:                           1 (current)
  OS/ABI:                            UNIX - System V
  ABI Version:                       0
  Type:                              DYN (Shared object file)
  Machine:                           AArch64
  Version:                           0x1
  Entry point address:               0x14607ad8
  Start of program headers:          64 (bytes into file)
  Start of section headers:          228680 (bytes into file)
  Flags:                             0x0
  Size of this header:               64 (bytes)
  Size of program headers:           56 (bytes)
  Number of program headers:         8
  Size of section headers:           64 (bytes)
  Number of section headers:         34
  Section header string table index: 31

非常感谢您能帮助我。最好的祝福陈兴豪

在我的程序中,必须将两个“ so”-libcpss.so和libhelper.so加载到固定的虚拟地址中,这是通过ld脚本SECTIONS {/ *代码段,访问权限RX * /来完成的。 = 0x14600000; …} ...

shared-libraries ld
1个回答
0
投票

[在生成libtestScript.so时添加-Wl,-Ttext-segment = 0xXXXXXXXX(例如0x70000000)的标志后,结果按预期显示:

© www.soinside.com 2019 - 2024. All rights reserved.