diff --git a/libpkg/elfhints.c b/libpkg/elfhints.c index 4b5ac857c1..41d4f1b0b4 100644 --- a/libpkg/elfhints.c +++ b/libpkg/elfhints.c @@ -244,7 +244,9 @@ scan_dirs_for_shlibs(struct shlib_list *shlib_list, int numdirs, return 0; } -int shlib_list_from_rpath(const char *rpath_str) +#define ORIGIN "$ORIGIN" + +int shlib_list_from_rpath(const char *rpath_str, const char *dirpath) { const char **dirlist; char *buf; @@ -253,18 +255,32 @@ int shlib_list_from_rpath(const char *rpath_str) int ret; const char *c; + /* The special token $ORIGIN should be replaced by the + dirpath: adjust buflen calculation to account for this */ + numdirs = 1; for (c = rpath_str; *c != '\0'; c++) if (*c == ':') numdirs++; buflen = numdirs * sizeof(char *) + strlen(rpath_str) + 1; + i = strlen(dirpath) - strlen(ORIGIN); + if (i > 0) + buflen += i; + dirlist = calloc(1, buflen); if (dirlist == NULL) { warnx("Out of memory"); return (EPKG_FATAL); } buf = (char *)dirlist + numdirs * sizeof(char *); - strcpy(buf, rpath_str); + + c = strstr(rpath_str, ORIGIN); + if ( c != NULL ) { + strncpy(buf, rpath_str, c - rpath_str); + strlcat(buf, dirpath, buflen); + strlcat(buf, c + strlen(ORIGIN), buflen); + } else + strlcpy(buf, rpath_str, buflen); i = 0; while ((c = strsep(&buf, ":")) != NULL) { diff --git a/libpkg/pkg_elf.c b/libpkg/pkg_elf.c index 2488e2f5f0..0947881939 100644 --- a/libpkg/pkg_elf.c +++ b/libpkg/pkg_elf.c @@ -39,6 +39,7 @@ #include #include #include +#include #ifndef BUNDLED_LIBELF #include #endif @@ -295,8 +296,9 @@ analyse_elf(struct pkg *pkg, const char *fpath, if (dyn->d_tag != DT_RPATH && dyn->d_tag != DT_RUNPATH) continue; - - shlib_list_from_rpath(elf_strptr(e, sh_link, dyn->d_un.d_val)); + + shlib_list_from_rpath(elf_strptr(e, sh_link, dyn->d_un.d_val), + dirname(fpath)); break; } @@ -355,7 +357,7 @@ pkg_analyse_files(struct pkgdb *db, struct pkg *pkg) bool shlibs = false; bool autodeps = false; bool developer = false; - int (*action)(void *, struct pkg *, const char *); + int (*action)(void *, struct pkg *, const char *, const char *); pkg_config_bool(PKG_CONFIG_SHLIBS, &shlibs); pkg_config_bool(PKG_CONFIG_AUTODEPS, &autodeps); diff --git a/libpkg/private/ldconfig.h b/libpkg/private/ldconfig.h index 55e06711a3..c4d119dc51 100644 --- a/libpkg/private/ldconfig.h +++ b/libpkg/private/ldconfig.h @@ -41,7 +41,7 @@ const char *shlib_list_find_by_name(const char *); void shlib_list_free(void); void rpath_list_free(void); int shlib_list_from_elf_hints(const char *); -int shlib_list_from_rpath(const char *); +int shlib_list_from_rpath(const char *, const char *); void list_elf_hints(const char *); void update_elf_hints(const char *, int, char **, int);