有没有一种方法可以使用dlopen()指定共享库的基址?

时间:2020-05-28 12:33:05

标签: dynamic-linking dlopen

似乎当我们对某些库进行dlopen()时,它们将被加载到某些首选的(但不是固定的)地址中。我已经检查了dlopen()的源代码,并且有一个核心函数说

static __always_inline const char *
_dl_map_segments (struct link_map *l, int fd,
                  const ElfW(Ehdr) *header, int type,
                  const struct loadcmd loadcmds[], size_t nloadcmds,
                  const size_t maplength, bool has_holes,
                  struct link_map *loader)
{
  const struct loadcmd *c = loadcmds;
  if (__glibc_likely (type == ET_DYN))
    {
      /* This is a position-independent shared object.  We can let the
         kernel map it anywhere it likes, but we must have space for all
         the segments in their specified positions relative to the first.
         So we map the first segment without MAP_FIXED, but with its
         extent increased to cover all the segments.  Then we remove
         access from excess portion, and there is known sufficient space
         there to remap from the later segments.
         As a refinement, sometimes we have an address that we would
         prefer to map such objects at; but this is only a preference,
         the OS can do whatever it likes. */
      ElfW(Addr) mappref
        = (ELF_PREFERRED_ADDRESS (loader, maplength,
                                  c->mapstart & GLRO(dl_use_load_bias))
           - MAP_BASE_ADDR (l));
      /* Remember which part of the address space this object uses.  */
      l->l_map_start = (ElfW(Addr)) __mmap ((void *) mappref, maplength,
                                            c->prot,
                                            MAP_COPY|MAP_FILE,
                                            fd, c->mapoff);
      if (__glibc_unlikely ((void *) l->l_map_start == MAP_FAILED))
        return DL_MAP_SEGMENTS_ERROR_MAP_SEGMENT;
...
}

该评论说您可以指定首选地址,但是操作系统将确定是否使用它。

问题

  1. 有什么方法可以指定每个倾斜模块的基址吗?
  2. ELF_PREFERRED_ADDRESSS默认情况下设置为0,但是此宏似乎可以推断出可以更改首选地址,例如通过环境变量?但是,即使只有一个库,我也怀疑是否可以为每个倾斜的库进行更改。
  3. 如果我想自己实现此功能,似乎我需要包装一个新的dlopen函数并将首选地址传递给上述核心函数(并可能使用MAP_FIXED)。正确吗?

谢谢!

1 个答案:

答案 0 :(得分:0)

有什么方法可以指定每个倾斜模块的基地址吗?

否。

ELF_PREFERRED_ADDRESSS默认情况下设置为0,但是此宏似乎可以推断出可以通过环境变量来更改首选地址?但是,即使有一个库,我也怀疑是否可以为每个倾斜的库进行更改。

此代码已编译到动态加载器ld-linux.so中,并且在编译后无法更改。

如果我想自己实现此功能,似乎我需要包装一个新的dlopen函数并将首选地址传递给上述核心函数(也许使用MAP_FIXED)。正确吗?

该功能是ld-linux private 。您将无法包装它,也无法从ld-linux外部调用它。

P.S。您可能正在寻找的是prelink命令。