patchelf icon indicating copy to clipboard operation
patchelf copied to clipboard

--remove-needed does not update .gnu.version_r table

Open airlsyn opened this issue 5 years ago • 2 comments

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

  1. remove libs
$ patchelf --remove-needed libcublas.so.10.0 libonnxruntime.so
  1. 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.

airlsyn avatar Jun 19 '20 03:06 airlsyn

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:

  1. Download AM2R_Server_1.4_lin.zip from https://github.com/milesthenerd/AM2R-Server/releases/tag/v1.4-real

  2. Extract the zip somewhere, navigate into the AM2R_Server dir

  3. 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"

  4. 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: grafik

Miepee avatar Sep 17 '22 19:09 Miepee

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.

leofang avatar Aug 31 '23 03:08 leofang