patchelf
patchelf copied to clipboard
--remove-needed does not update .gnu.version_r table
Describe the bug
with the newest version of patchelf (pathelf-0.11 and master branch), remove so will cause a bug
Inconsistency detected by ld.so: dl-version.c: 205: _dl_check_map_versions: Assertion `needed != NULL' failed!
Steps To Reproduce
deps: libonnxruntime.so https://drive.google.com/file/d/1rQZYIkzOu4UGJ4Cczm-FVM2LrxYw1Xc0/view?usp=sharing
- remove libs
$ patchelf --remove-needed libcublas.so.10.0 libonnxruntime.so
- read so
$ ldd libonnxruntime.so
Inconsistency detected by ld.so: dl-version.c: 205: _dl_check_map_versions: Assertion `needed != NULL' failed!
other
the problem here, looks like things in replaceNeeded, updating the .gnu.version_r section
one more thing
I tried to modify the removeNeeded with the following:
.....
unsigned int verNeedNum = 0;
Elf_Dyn * dyn = (Elf_Dyn *) (contents + rdi(shdrDynamic.sh_offset));
Elf_Dyn * last = dyn;
for ( ; rdi(dyn->d_tag) != DT_NULL; dyn++) {
if (rdi(dyn->d_tag) == DT_NEEDED) {
char * name = strTab + rdi(dyn->d_un.d_val);
if (libs.find(name) != libs.end()) {
debug("removing DT_NEEDED entry '%s'\n", name);
changed = true;
} else {
debug("keeping DT_NEEDED entry '%s'\n", name);
*last++ = *dyn;
}
} else
*last++ = *dyn;
// this is what i add
if (rdi(dyn->d_tag) == DT_VERNEEDNUM) {
verNeedNum = rdi(dyn->d_un.d_val);
}
}
memset(last, 0, sizeof(Elf_Dyn) * (dyn - last));
// these are what I add
if (verNeedNum) {
auto shdrVersionR = findSection(".gnu.version_r");
Elf_Shdr & shdrVersionRStrings = shdrs[rdi(shdrVersionR.sh_link)];
char * verStrTab = (char *) contents + rdi(shdrVersionRStrings.sh_offset);
std::string versionRStringsSName = getSectionName(shdrVersionRStrings);
debug("found .gnu.version_r with %i entries, strings in %s\n", verNeedNum, versionRStringsSName.c_str());
unsigned int verStrAddedBytes = 0;
Elf_Verneed * need = (Elf_Verneed *) (contents + rdi(shdrVersionR.sh_offset));
while (verNeedNum > 0) {
char * file = verStrTab + rdi(need->vn_file);
auto i = libs.find(file);
if (i != libs.end()) {
debug("removing .gnu.version_r entry '%s'\n", file);
debug("resizing string section %s ...\n", versionRStringsSName.c_str());
// THIS COULD BE WRONG
wri(need->vn_file, rdi(shdrVersionRStrings.sh_size));
changed = true;
}
// the Elf_Verneed structures form a linked list, so jump to next entry
need = (Elf_Verneed *) (((char *) need) + rdi(need->vn_next));
--verNeedNum;
}
}
this could led to another problem
$ ldd libonnxruntime.so
./libonnxruntime.so: ./libonnxruntime.so: version `libcublas.so.10.0' not found (required by ./libonnxruntime.so)
and when use libonnxruntime.so :
java.lang.UnsatisfiedLinkError: /tmp/onnxruntime-java3138521611266514151/libonnxruntime.so: java: version `libcublas.so.10.0' not found (required by /tmp/onnxruntime-java3138521611266514151/libonnxruntime.so)
Any clue to solve this problem will be highly appreciated.
I'm having this issue too getting while trying to get an old game to run. The original file / test case doesn't seem to work anymore, so I'll add mine:
-
Download
AM2R_Server_1.4_lin.zipfrom https://github.com/milesthenerd/AM2R-Server/releases/tag/v1.4-real -
Extract the zip somewhere, navigate into the
AM2R_Serverdir -
Try to patch out libssl-1-1-0 and libcrypto-1-1-0 via
patchelf ./runner --remove-needed "libcrypto.so.1.0.0" --remove-needed "libssl.so.1.0.0" -
Launch
runner(set as executable before if not already one)
Result: Inconsistency detected by ld.so: dl-version.c: 204: _dl_check_map_versions: Assertion 'needed != NULL' failed! instead of the game launching.
The above was done with patchelf 0.15.0 on Arch Linux.
I also tried using --clear-symbol-version as well as use #394 and the patch from the comments . All leading to the same result.
When using objdump -p ./runner one still sees libssl referenced in there:

Can we please have attention to this issue? --replace-needed is fixed (#84), but not --add-needed or --remove-needed and lack of parity is a source of confusion.