diff --git a/tools/elfdeps.c b/tools/elfdeps.c index 52fda172fe..eea289ac2e 100644 --- a/tools/elfdeps.c +++ b/tools/elfdeps.c @@ -2,6 +2,7 @@ #include #include +#include #include #include #include @@ -46,7 +47,7 @@ static char *getLibtoolVer(const char *filename) const char *so; char dest[PATH_MAX]; int destsize = 0; - int found_digit, found_dot = 0; + int found_digit = 0, found_dot = 0; destsize = readlink(filename, dest, PATH_MAX); if (destsize > 0) { @@ -101,6 +102,7 @@ static char *getLibtoolVerFromShLink(const char *filename) void *dl_handle; struct link_map *linkmap; char *version = NULL; + ssize_t len; close(pipefd[0]); dl_handle = dlmopen(LM_ID_NEWLM, filename, RTLD_LAZY); @@ -108,7 +110,7 @@ static char *getLibtoolVerFromShLink(const char *filename) if (dlinfo(dl_handle, RTLD_DI_LINKMAP, &linkmap) != -1) { version = getLibtoolVer(linkmap->l_name); } - write(pipefd[1], version, strlen(version)); + len = write(pipefd[1], version, strlen(version)); close(pipefd[1]); free(version); dlclose(dl_handle); @@ -190,6 +192,14 @@ static const char *mkmarker(GElf_Ehdr *ehdr) return marker; } +static int findSonameInDeps(ARGV_t deps, const char *soname) +{ + for (ARGV_t dep = deps; *dep; dep++) { + if (strncmp(*dep, soname, strlen(soname)) == 0) return 1; + } + return 0; +} + static void addDep(ARGV_t *deps, const char *soname, const char *ver, const char *marker, const char *compare_op, const char *fallback_ver) @@ -326,7 +336,10 @@ static void processDynamic(Elf_Scn *scn, GElf_Shdr *shdr, elfInfo *ei) s = elf_strptr(ei->elf, shdr->sh_link, dyn->d_un.d_val); if (s) { char *libtool_ver = NULL; - if (libtool_version_fallback) { + // If soname matches an item already in the deps, then + // it had versioned symbols and doesn't require fallback. + if (libtool_version_fallback && + !findSonameInDeps(ei->requires, s)) { libtool_ver = getLibtoolVerFromShLink(s); } addDep(&ei->requires, s, NULL, ei->marker, ">=", libtool_ver);