glibc:测试 lib 是否作为 DF_1_NODELETE 标志或 lib 是否具有唯一符号

glibc : Test if lib as DF_1_NODELETE flag or if lib has unique symbol

我正在使用 dlopen / dlclose 加载带有 glibc 2.21 的库。

是否有 C++ 调用来将库检查为 DF_1_NODELETE 标志集? readelf 似乎可以做到。

或者至少如果一个库中定义了唯一符号? nm绝对可以做到。

理想情况下,我想要这样的东西:

CloseLib( libHandle lib)
{
  if( checkIfLibIsClosable(lib) )
  {
     dlclose(lib)
  }
}

这是为了避免在带有 DF_1_NODELETE 标志的 lib 上调用 dlclose,因为调用它会失败并出现断言错误:

Inconsistency detected by ld.so: dl-close.c: 764: _dl_close: Assertion `map->l_init_called' failed!

这是由DF_1_NODELETE flag set in dl-close.c:762引起的,The flag is set in dl-lookup.c:332

关于 DF_1_NODELETE 标志和唯一符号的信息:

DF_1_NODELETE

Unique Symbol

This is in order to avoid calling dlclose on lib with DF_1_NODELETE flag, as calling it will fails with an assert error :

Inconsistency detected by ld.so: dl-close.c: 764: _dl_close: \
  Assertion `map->l_init_called' failed!

如果在这样的库上调用 dlclose 导致上述断言,那是 GLIBC 中的错误,您应该在 glibc bugzilla 中报告它。

至于检测 DF_1_NODELETE(或任何其他)标志,是的,您可以通过从库的开头 reading Elf{32,64}_Ehdr,然后阅读 Elf{32,64}_Phdrs 从 .e_phoff 偏移直到你找到一个 .p_type == PT_DYNAMIC,然后从它的 .p_offset 读取 Elf{32,64}_Dyns 直到你找到一个 .d_type == DT_FLAGS,并且最后检查它的 .d_un.d_val & DF_1_NODELETE 是否非零。