Skip to content

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

Open
@airlsyn

Description

@airlsyn

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.

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions