diff --git a/libpkg/Makefile.autosetup b/libpkg/Makefile.autosetup index 95764b2cf7..4e4606d5f6 100644 --- a/libpkg/Makefile.autosetup +++ b/libpkg/Makefile.autosetup @@ -36,7 +36,8 @@ SRCS= backup_lib.c \ pkg_elf.c \ pkg_abi_macho.c \ binfmt_macho.c \ - ssh.c elfhints.c \ + ssh.c \ + system_shlibs.c \ pkg_arch.c \ pkg_cudf.c \ pkg_jobs_universe.c pkg_printf.c \ diff --git a/libpkg/elfhints.c b/libpkg/elfhints.c deleted file mode 100644 index ce61ffb93c..0000000000 --- a/libpkg/elfhints.c +++ /dev/null @@ -1,559 +0,0 @@ -/*- - * Copyright (c) 1998 John D. Polstra - * Copyright (c) 2012 Matthew Seaman - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * $FreeBSD: stable/8/sbin/ldconfig/elfhints.c 76224 2001-05-02 23:56:21Z obrien $ - */ - -#include -#include "private/pkg_abi.h" -#include -#include -#ifdef HAVE_SYS_ENDIAN_H -#include -#elif HAVE_ENDIAN_H -#include -#elif HAVE_MACHINE_ENDIAN_H -#include -#endif - -#ifdef __APPLE__ -#include -#define be32toh(n) OSSwapBigToHostInt32(n) -#define le32toh(n) OSSwapLittleToHostInt32(n) -#endif - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "pkg.h" -#include "private/pkg.h" -#include "private/ldconfig.h" - -#define MAXDIRS 1024 /* Maximum directories in path */ -#define MAXFILESIZE (16*1024) /* Maximum hints file size */ - -struct shlib { - const char *name; - char path[]; -}; - -static int shlib_list_add(pkghash **shlib_list, - const char *dir, const char *shlib_file); -static int scan_dirs_for_shlibs(pkghash **shlib_list, - int numdirs, const char **dirlist, - bool strictnames); -static void add_dir(const char *, const char *, int); -static void read_dirs_from_file(const char *, const char *); -static void read_elf_hints(const char *, int); -static void write_elf_hints(const char *); - -static const char *dirs[MAXDIRS]; -static int ndirs; -static int is_be; -int insecure; - -#define COND_SWAP(n) (is_be ? be32toh(n) : le32toh(n)) - -/* Known shlibs on the standard system search path. Persistent, - common to all applications */ -static pkghash *shlibs = NULL; - -/* Known shlibs on the specific RPATH or RUNPATH of one binary. - Evanescent. */ -static pkghash *rpath = NULL; - -void -shlib_list_init(void) -{ - assert(pkghash_count(shlibs) == 0); -} - -void -rpath_list_init(void) -{ - assert(pkghash_count(rpath) == 0); -} - -static int -shlib_list_add(pkghash **shlib_list, const char *dir, - const char *shlib_file) -{ - struct shlib *sl; - size_t path_len, dir_len; - - /* If shlib_file is already in the shlib_list table, don't try - * and add it again */ - if (pkghash_get(*shlib_list, shlib_file) != NULL) - return (EPKG_OK); - - path_len = strlen(dir) + strlen(shlib_file) + 2; - - sl = xcalloc(1, sizeof(struct shlib) + path_len); - - strlcpy(sl->path, dir, path_len); - dir_len = strlcat(sl->path, "/", path_len); - strlcat(sl->path, shlib_file, path_len); - - sl->name = sl->path + dir_len; - - pkghash_safe_add(*shlib_list, sl->name, sl, free); - - return (EPKG_OK); -} - -const char * -shlib_list_find_by_name(const char *shlib_file) -{ - struct shlib *sl; - - sl = pkghash_get_value(rpath, shlib_file); - if (sl != NULL) - return (sl->path); - - sl = pkghash_get_value(shlibs, shlib_file); - if (sl != NULL) - return (sl->path); - - return (NULL); -} - -void -shlib_list_free(void) -{ - - pkghash_destroy(shlibs); - shlibs = NULL; -} - -void -rpath_list_free(void) -{ - - pkghash_destroy(rpath); - rpath = NULL; -} - -static void -add_dir(const char *hintsfile, const char *name, int trusted) -{ - struct stat stbuf; - int i; - - /* Do some security checks */ - if (!trusted && !insecure) { - if (stat(name, &stbuf) == -1) { - warn("%s", name); - return; - } - if (stbuf.st_uid != 0) { - warnx("%s: ignoring directory not owned by root", name); - return; - } - if ((stbuf.st_mode & S_IWOTH) != 0) { - warnx("%s: ignoring world-writable directory", name); - return; - } - if ((stbuf.st_mode & S_IWGRP) != 0) { - warnx("%s: ignoring group-writable directory", name); - return; - } - } - - for (i = 0; i < ndirs; i++) - if (STREQ(dirs[i], name)) - return; - if (ndirs >= MAXDIRS) - errx(1, "\"%s\": Too many directories in path", hintsfile); - dirs[ndirs++] = name; -} - -static int -scan_dirs_for_shlibs(pkghash **shlib_list, int numdirs, - const char **dirlist, bool strictnames) -{ - int i; - - /* Expect shlibs to follow the name pattern libfoo.so.N if - strictnames is true -- ie. when searching the default - library search path. - - Otherwise, allow any name ending in .so or .so.N -- - ie. when searching RPATH or RUNPATH and assuming it - contains private shared libraries which can follow just - about any naming convention */ - - for (i = 0; i < numdirs; i++) { - DIR *dirp; - struct dirent *dp; - - if ((dirp = opendir(dirlist[i])) == NULL) - continue; - while ((dp = readdir(dirp)) != NULL) { - int len; - int ret; - const char *vers; - - /* Only regular files and sym-links. On some - filesystems d_type is not set, on these the d_type - field will be DT_UNKNOWN. */ - if (dp->d_type != DT_REG && dp->d_type != DT_LNK && - dp->d_type != DT_UNKNOWN) - continue; - - len = strlen(dp->d_name); - if (strictnames) { - /* Name can't be shorter than "libx.so" */ - if (len < 7 || - strncmp(dp->d_name, "lib", 3) != 0) - continue; - } - - vers = dp->d_name + len; - while (vers > dp->d_name && - (isdigit(*(vers-1)) || *(vers-1) == '.')) - vers--; - if (vers == dp->d_name + len) { - if (strncmp(vers - 3, ".so", 3) != 0) - continue; - } else if (vers < dp->d_name + 3 || - strncmp(vers - 3, ".so.", 4) != 0) - continue; - - /* We have a valid shared library name. */ - ret = shlib_list_add(shlib_list, dirlist[i], - dp->d_name); - if (ret != EPKG_OK) { - closedir(dirp); - return ret; - } - } - closedir(dirp); - } - return 0; -} - -#define ORIGIN "$ORIGIN" - -int shlib_list_from_rpath(const char *rpath_str, const char *dirpath) -{ - const char **dirlist; - char *buf; - size_t buflen; - int i, numdirs; - int ret; - const char *c, *cstart; - - /* 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 * numdirs; - - dirlist = xcalloc(1, buflen); - buf = (char *)dirlist + numdirs * sizeof(char *); - - buf[0] = '\0'; - cstart = rpath_str; - while ( (c = strstr(cstart, ORIGIN)) != NULL ) { - strncat(buf, cstart, c - cstart); - strlcat(buf, dirpath, buflen); - cstart = c + strlen(ORIGIN); - } - strlcat(buf, cstart, buflen); - - i = 0; - while ((c = strsep(&buf, ":")) != NULL) { - if (strlen(c) > 0) - dirlist[i++] = c; - } - - assert(i <= numdirs); - - ret = scan_dirs_for_shlibs(&rpath, i, dirlist, false); - - free(dirlist); - - return (ret); -} - -int -shlib_list_from_elf_hints(const char *hintsfile) -{ - if (ctx.abi.os == PKG_OS_FREEBSD || ctx.abi.os == PKG_OS_DRAGONFLY) - read_elf_hints(hintsfile, false); - - return (scan_dirs_for_shlibs(&shlibs, ndirs, dirs, true)); -} - -static const char *stage_dirs[] = { - "/lib", - "/usr/lib", -}; - -void -shlib_list_from_stage(const char *stage) -{ - int i; - char *dir; - - if (stage == NULL) - return; - - for (i = 0; i < NELEM(stage_dirs); i++) { - xasprintf(&dir, "%s%s", stage, stage_dirs[i]); - scan_dirs_for_shlibs(&shlibs, 1, (const char **)&dir, true); - free(dir); - } -} - -void -list_elf_hints(const char *hintsfile) -{ - int i; - int nlibs; - - read_elf_hints(hintsfile, 1); - printf("%s:\n", hintsfile); - printf("\tsearch directories:"); - for (i = 0; i < ndirs; i++) - printf("%c%s", i == 0 ? ' ' : ':', dirs[i]); - putchar('\n'); - - nlibs = 0; - for (i = 0; i < ndirs; i++) { - DIR *dirp; - struct dirent *dp; - - if ((dirp = opendir(dirs[i])) == NULL) - continue; - while ((dp = readdir(dirp)) != NULL) { - int len; - int namelen; - const char *name; - const char *vers; - - /* Name can't be shorter than "libx.so.0" */ - if ((len = strlen(dp->d_name)) < 9 || - strncmp(dp->d_name, "lib", 3) != 0) - continue; - name = dp->d_name + 3; - vers = dp->d_name + len; - while (vers > dp->d_name && isdigit(*(vers-1))) - vers--; - if (vers == dp->d_name + len) - continue; - if (vers < dp->d_name + 4 || - strncmp(vers - 4, ".so.", 4) != 0) - continue; - - /* We have a valid shared library name. */ - namelen = (vers - 4) - name; - printf("\t%d:-l%.*s.%s => %s/%s\n", nlibs, - namelen, name, vers, dirs[i], dp->d_name); - nlibs++; - } - closedir(dirp); - } -} - -static void -read_dirs_from_file(const char *hintsfile, const char *listfile) -{ - FILE *fp; - char buf[MAXPATHLEN]; - int linenum; - - if ((fp = fopen(listfile, "re")) == NULL) - err(1, "%s", listfile); - - linenum = 0; - while (fgets(buf, sizeof buf, fp) != NULL) { - char *cp, *sp; - - linenum++; - cp = buf; - /* Skip leading white space. */ - while (isspace(*cp)) - cp++; - if (*cp == '#' || *cp == '\0') - continue; - sp = cp; - /* Advance over the directory name. */ - while (!isspace(*cp) && *cp != '\0') - cp++; - /* Terminate the string and skip trailing white space. */ - if (*cp != '\0') { - *cp++ = '\0'; - while (isspace(*cp)) - cp++; - } - /* Now we had better be at the end of the line. */ - if (*cp != '\0') - warnx("%s:%d: trailing characters ignored", - listfile, linenum); - - sp = xstrdup(sp); - add_dir(hintsfile, sp, 0); - } - - fclose(fp); -} - -static void -read_elf_hints(const char *hintsfile, int must_exist) -{ - int fd; - struct stat s; - void *mapbase; - struct elfhints_hdr *hdr; - char *strtab; - char *dirlist; - char *p; - - if ((fd = open(hintsfile, O_RDONLY)) == -1) { - if (errno == ENOENT && !must_exist) - return; - err(1, "Cannot open \"%s\"", hintsfile); - } - if (fstat(fd, &s) == -1) - err(1, "Cannot stat \"%s\"", hintsfile); - if (s.st_size > MAXFILESIZE) - errx(1, "\"%s\" is unreasonably large", hintsfile); - /* - * We use a read-write, private mapping so that we can null-terminate - * some strings in it without affecting the underlying file. - */ - mapbase = mmap(NULL, s.st_size, PROT_READ|PROT_WRITE, - MAP_PRIVATE, fd, 0); - if (mapbase == MAP_FAILED) - err(1, "Cannot mmap \"%s\"", hintsfile); - close(fd); - - hdr = (struct elfhints_hdr *)mapbase; - is_be = be32toh(hdr->magic) == ELFHINTS_MAGIC; - if (COND_SWAP(hdr->magic) != ELFHINTS_MAGIC) - errx(1, "\"%s\": invalid file format", hintsfile); - if (COND_SWAP(hdr->version) != 1) - errx(1, "\"%s\": unrecognized file version (%d)", hintsfile, - COND_SWAP(hdr->version)); - - strtab = (char *)mapbase + COND_SWAP(hdr->strtab); - dirlist = strtab + COND_SWAP(hdr->dirlist); - - if (*dirlist != '\0') - while ((p = strsep(&dirlist, ":")) != NULL) - add_dir(hintsfile, p, 1); -} - -void -update_elf_hints(const char *hintsfile, int argc, char **argv, int merge) -{ - int i; - - if (merge) - read_elf_hints(hintsfile, 0); - else - // remove when FreeBSD switches to LE for all architectures - is_be = be32toh(1) == 1; - for (i = 0; i < argc; i++) { - struct stat s; - - if (stat(argv[i], &s) == -1) - warn("warning: %s", argv[i]); - else if (S_ISREG(s.st_mode)) - read_dirs_from_file(hintsfile, argv[i]); - else - add_dir(hintsfile, argv[i], 0); - } - write_elf_hints(hintsfile); -} - -static void -write_elf_hints(const char *hintsfile) -{ - struct elfhints_hdr hdr; - char *tempname; - int fd; - FILE *fp; - int i; - - xasprintf(&tempname, "%s.XXXXXX", hintsfile); - if ((fd = mkstemp(tempname)) == -1) - err(1, "mkstemp(%s)", tempname); - if (fchmod(fd, 0444) == -1) - err(1, "fchmod(%s)", tempname); - if ((fp = fdopen(fd, "wb")) == NULL) - err(1, "fdopen(%s)", tempname); - - hdr.magic = COND_SWAP(ELFHINTS_MAGIC); - hdr.version = COND_SWAP(1); - hdr.strtab = COND_SWAP(sizeof hdr); - hdr.strsize = 0; - hdr.dirlist = 0; - memset(hdr.spare, 0, sizeof hdr.spare); - - /* Count up the size of the string table. */ - if (ndirs > 0) { - hdr.strsize += strlen(dirs[0]); - for (i = 1; i < ndirs; i++) - hdr.strsize += 1 + strlen(dirs[i]); - } - hdr.dirlistlen = COND_SWAP(hdr.strsize); - hdr.strsize++; /* For the null terminator */ - hdr.strsize = COND_SWAP(hdr.strsize); - - /* Write the header. */ - if (fwrite(&hdr, 1, sizeof hdr, fp) != sizeof hdr) - err(1, "%s: write error", tempname); - /* Write the strings. */ - if (ndirs > 0) { - if (fputs(dirs[0], fp) == EOF) - err(1, "%s: write error", tempname); - for (i = 1; i < ndirs; i++) - if (fprintf(fp, ":%s", dirs[i]) < 0) - err(1, "%s: write error", tempname); - } - if (putc('\0', fp) == EOF || fclose(fp) == EOF) - err(1, "%s: write error", tempname); - - if (rename(tempname, hintsfile) == -1) - err(1, "rename %s to %s", tempname, hintsfile); - free(tempname); -} diff --git a/libpkg/pkg_abi.c b/libpkg/pkg_abi.c index aba7db2932..f7c672eeab 100644 --- a/libpkg/pkg_abi.c +++ b/libpkg/pkg_abi.c @@ -448,8 +448,7 @@ pkg_analyse_files(struct pkgdb *db __unused, struct pkg *pkg, const char *stage) bool failures = false; int (*pkg_analyse_init)(const char *stage); - int (*pkg_analyse)(const bool developer_mode, struct pkg *pkg, - const char *fpath); + int (*pkg_analyse)(const bool developer_mode, struct pkg *pkg, const char *fpath); int (*pkg_analyse_close)(); if (0 == strncmp(pkg->abi, "Darwin", 6)) { diff --git a/libpkg/pkg_abi_macho.c b/libpkg/pkg_abi_macho.c index bd2ca1842d..bb3548cb7c 100644 --- a/libpkg/pkg_abi_macho.c +++ b/libpkg/pkg_abi_macho.c @@ -6,6 +6,7 @@ #include +#include "private/binfmt.h" #include "private/binfmt_macho.h" #include "private/pkg.h" #include "private/event.h" @@ -13,7 +14,7 @@ /** * Routines to support pkg_abi.c functions when dealing with Mach-O files. - * Supports getting struct pkg_abi from the binary's load commands. + * Supports getting struct pkg_abi from the binary's load commands. * Supports getting shared libary information (needed, provided & loader). * Picks right binary in Universal binary based on ABI. */ @@ -299,28 +300,8 @@ pkg_macho_abi_from_fd(int fd, struct pkg_abi *abi, enum pkg_arch arch_hint) return ret; } -static const char * const system_dylib_prefixes[] = { - "/System/", - "/usr/lib/", - "/lib/", -}; - -static bool -system_dylib(const char *libname) -{ - const char * const *p = system_dylib_prefixes; - const char * const *p_end = p + NELEM(system_dylib_prefixes); - while (p < p_end) { - if (strncmp(libname, *p, strlen(*p)) == 0) { - return true; - } - p++; - } - return false; -} - static int -analyse_macho(int fd, struct pkg *pkg, const bool baselibs) +analyse_macho(int fd, struct pkg *pkg) { ssize_t x; pkg_error_t ret = EPKG_END; @@ -378,45 +359,33 @@ analyse_macho(int fd, struct pkg *pkg, const bool baselibs) goto cleanup; } n += x; - if (!baselibs && system_dylib(dylib->path)) { - pkg_debug(3, - "Skipping System dynamic library path: %s ts %"PRIu32" current(%"PRIuFAST16", %"PRIuFAST16", %"PRIuFAST16") compat(%"PRIuFAST16", %"PRIuFAST16", %"PRIuFAST16")\n", - dylib->path, dylib->timestamp, - dylib->current_version.major, - dylib->current_version.minor, - dylib->current_version.patch, - dylib->compatibility_version.major, - dylib->compatibility_version.minor, - dylib->compatibility_version.patch); + // while under Darwin full path references are recommended and ubiquitous, + // we align with pkg native environment and use only the basename + // this also strips off any @executable_path, @loader_path, @rpath components + const char * basename = strrchr(dylib->path, '/'); + basename = basename ? basename + 1 : dylib->path; + pkg_debug(3, + "Adding dynamic library path: %s ts %"PRIu32" current(%"PRIuFAST16", %"PRIuFAST16", %"PRIuFAST16") compat(%"PRIuFAST16", %"PRIuFAST16", %"PRIuFAST16")\n", + dylib->path, dylib->timestamp, + dylib->current_version.major, + dylib->current_version.minor, + dylib->current_version.patch, + dylib->compatibility_version.major, + dylib->compatibility_version.minor, + dylib->compatibility_version.patch); + + char *lib_with_version; + if (dylib->current_version.patch) { + xasprintf(&lib_with_version, "%s-%"PRIuFAST16".%"PRIuFAST16".%"PRIuFAST16, basename, dylib->current_version.major, dylib->current_version.minor, dylib->current_version.patch); } else { - // while under Darwin full path references are recommended and ubiquitous, - // we align with pkg native environment and use only the basename - // this also strips off any @executable_path, @loader_path, @rpath components - const char * basename = strrchr(dylib->path, '/'); - basename = basename ? basename + 1 : dylib->path; - pkg_debug(3, - "Adding dynamic library path: %s ts %"PRIu32" current(%"PRIuFAST16", %"PRIuFAST16", %"PRIuFAST16") compat(%"PRIuFAST16", %"PRIuFAST16", %"PRIuFAST16")\n", - dylib->path, dylib->timestamp, - dylib->current_version.major, - dylib->current_version.minor, - dylib->current_version.patch, - dylib->compatibility_version.major, - dylib->compatibility_version.minor, - dylib->compatibility_version.patch); - - char *lib_with_version; - if (dylib->current_version.patch) { - xasprintf(&lib_with_version, "%s-%"PRIuFAST16".%"PRIuFAST16".%"PRIuFAST16, basename, dylib->current_version.major, dylib->current_version.minor, dylib->current_version.patch); - } else { - xasprintf(&lib_with_version, "%s-%"PRIuFAST16".%"PRIuFAST16, basename, dylib->current_version.major, dylib->current_version.minor); - } - if (LC_ID_DYLIB == loadcmd) { - pkg_addshlib_provided(pkg, lib_with_version); - } else { - pkg_addshlib_required(pkg, lib_with_version); - } - free(lib_with_version); + xasprintf(&lib_with_version, "%s-%"PRIuFAST16".%"PRIuFAST16, basename, dylib->current_version.major, dylib->current_version.minor); + } + if (LC_ID_DYLIB == loadcmd) { + pkg_addshlib_provided(pkg, lib_with_version); + } else { + pkg_addshlib_required(pkg, lib_with_version); } + free(lib_with_version); free(dylib); break; default: @@ -450,8 +419,7 @@ int pkg_analyse_macho(const bool developer_mode, struct pkg *pkg, const char *fpath) { int ret = EPKG_OK; - bool baselibs = pkg_object_bool(pkg_config_get("ALLOW_BASE_SHLIBS")); - pkg_debug(1, "Analysing Mach-O %s %d", fpath, baselibs); + pkg_debug(1, "Analysing Mach-O %s", fpath); int fd = open(fpath, O_RDONLY); if (-1 == fd) { @@ -460,7 +428,7 @@ pkg_analyse_macho(const bool developer_mode, struct pkg *pkg, const char *fpath) // Be consistent with analyse_elf and return no error if fpath cannot be opened return ret; } else { - ret = analyse_macho(fd, pkg, baselibs); + ret = analyse_macho(fd, pkg); if (-1 == close(fd)) { pkg_emit_errno("close_pkg_analyse_macho", fpath); ret = EPKG_FATAL; diff --git a/libpkg/pkg_config.c b/libpkg/pkg_config.c index c6ea23b06e..cd808a3b38 100644 --- a/libpkg/pkg_config.c +++ b/libpkg/pkg_config.c @@ -352,11 +352,6 @@ static struct config_entry c[] = { "VALID_URL_SCHEME", "pkg+http,pkg+https,https,http,file,ssh,tcp", }, - { - PKG_BOOL, - "ALLOW_BASE_SHLIBS", - "NO", - }, { PKG_INT, "WARN_SIZE_LIMIT", diff --git a/libpkg/pkg_elf.c b/libpkg/pkg_elf.c index 6f2a8e864b..166cd59a23 100644 --- a/libpkg/pkg_elf.c +++ b/libpkg/pkg_elf.c @@ -44,7 +44,6 @@ #include "private/pkg.h" #include "private/pkg_abi.h" #include "private/event.h" -#include "private/ldconfig.h" #include "private/binfmt.h" #ifndef NT_ABI_TAG @@ -55,82 +54,12 @@ #define NT_ARCH 2 #define NT_GNU_ABI_TAG 1 -/* FFR: when we support installing a 32bit package on a 64bit host */ -#define _PATH_ELF32_HINTS "/var/run/ld-elf32.so.hints" - #ifndef roundup2 #define roundup2(x, y) (((x)+((y)-1))&(~((y)-1))) /* if y is powers of two */ #endif static enum pkg_arch elf_parse_arch(Elf *elf, GElf_Ehdr *ehdr); -static int -filter_system_shlibs(const char *name, char *path, size_t pathlen) -{ - const char *shlib_path; - - shlib_path = shlib_list_find_by_name(name); - if (shlib_path == NULL) { - /* dynamic linker could not resolve */ - return (EPKG_FATAL); - } - - if (pkg_object_bool(pkg_config_get("ALLOW_BASE_SHLIBS"))) { - if (strstr(shlib_path, "/lib32/") != NULL) - return (EPKG_END); - } else { - /* match /lib, /lib32, /usr/lib and /usr/lib32 */ - if (strncmp(shlib_path, "/lib", 4) == 0 || - strncmp(shlib_path, "/usr/lib", 8) == 0) - return (EPKG_END); /* ignore libs from base */ - } - - if (path != NULL) - strncpy(path, shlib_path, pathlen); - - return (EPKG_OK); -} - -/* ARGSUSED */ -static int -add_shlibs_to_pkg(struct pkg *pkg, const char *fpath, const char *name, - bool is_shlib) -{ - struct pkg_file *file = NULL; - const char *filepath; - size_t fsz, nsz; - - switch(filter_system_shlibs(name, NULL, 0)) { - case EPKG_OK: /* A non-system library */ - pkg_addshlib_required(pkg, name); - return (EPKG_OK); - case EPKG_END: /* A system library */ - return (EPKG_OK); - default: - /* Ignore link resolution errors if we're analysing a - shared library. */ - if (is_shlib) - return (EPKG_OK); - - while (pkg_files(pkg, &file) == EPKG_OK) { - filepath = file->path; - fsz = strlen(filepath); - nsz = strlen(name); - - if (fsz >= nsz && - STREQ(&filepath[fsz - nsz], name)) { - pkg_addshlib_required(pkg, name); - return (EPKG_OK); - } - } - - pkg_emit_notice("(%s-%s) %s - required shared library %s not " - "found", pkg->name, pkg->version, fpath, name); - - return (EPKG_FATAL); - } -} - #ifdef __FreeBSD__ static bool is_old_freebsd_armheader(const GElf_Ehdr *e) @@ -173,10 +102,6 @@ analyse_elf(struct pkg *pkg, const char *fpath) size_t numdyn = 0; size_t sh_link = 0; size_t dynidx; - const char *shlib; - char *rpath = NULL; - - bool is_shlib = false; int fd; @@ -289,19 +214,6 @@ analyse_elf(struct pkg *pkg, const char *fpath) goto cleanup; } - /* First, scan through the data from the .dynamic section to - find any RPATH or RUNPATH settings. These are colon - separated paths to prepend to the ld.so search paths from - the ELF hints file. These always seem to come right after - the NEEDED shared library entries. - - NEEDED entries should resolve to a filename for installed - executables, but need not resolve for installed shared - libraries -- additional info from the apps that link - against them would be required. Shared libraries are - distinguished by a DT_SONAME tag */ - - rpath_list_init(); for (dynidx = 0; dynidx < numdyn; dynidx++) { if ((dyn = gelf_getdyn(data, dynidx, &dyn_mem)) == NULL) { ret = EPKG_FATAL; @@ -310,48 +222,19 @@ analyse_elf(struct pkg *pkg, const char *fpath) goto cleanup; } - if (dyn->d_tag == DT_SONAME) { - is_shlib = true; - - /* The file being scanned is a shared library - *provided* by the package. Record this if - appropriate */ - shlib = elf_strptr(e, sh_link, dyn->d_un.d_val); - if (shlib != NULL && *shlib != '\0') - pkg_addshlib_provided(pkg, shlib); + const char *shlib = elf_strptr(e, sh_link, dyn->d_un.d_val); + if (shlib == NULL || *shlib == '\0') { + continue; } - if ((dyn->d_tag == DT_RPATH || dyn->d_tag == DT_RUNPATH) && - rpath == NULL) - rpath = elf_strptr(e, sh_link, dyn->d_un.d_val); - } - if (rpath != NULL) { - char *p = xstrdup(fpath); - shlib_list_from_rpath(rpath, get_dirname(p)); - free(p); - } - - /* Now find all of the NEEDED shared libraries. */ - - for (dynidx = 0; dynidx < numdyn; dynidx++) { - if ((dyn = gelf_getdyn(data, dynidx, &dyn_mem)) == NULL) { - ret = EPKG_FATAL; - pkg_emit_error("getdyn() failed for %s: %s", fpath, - elf_errmsg(-1)); - goto cleanup; + if (dyn->d_tag == DT_SONAME) { + pkg_addshlib_provided(pkg, shlib); + } else if (dyn->d_tag == DT_NEEDED) { + pkg_addshlib_required(pkg, shlib); } - - if (dyn->d_tag != DT_NEEDED) - continue; - - shlib = elf_strptr(e, sh_link, dyn->d_un.d_val); - - add_shlibs_to_pkg(pkg, fpath, shlib, is_shlib); } cleanup: - rpath_list_free(); - if (e != NULL) elf_end(e); close(fd); @@ -753,33 +636,24 @@ pkg_elf_abi_from_fd(int fd, struct pkg_abi *abi) return (ret); } -int pkg_analyse_init_elf(const char* stage) { +int pkg_analyse_init_elf(__unused const char* stage) { if (elf_version(EV_CURRENT) == EV_NONE) return (EPKG_FATAL); - - shlib_list_init(); - - if (stage != NULL && pkg_object_bool(pkg_config_get("ALLOW_BASE_SHLIBS"))) { - /* Do not check the return */ - shlib_list_from_stage(stage); - } - - int ret = shlib_list_from_elf_hints(_PATH_ELF_HINTS); - return ret; + return (EPKG_OK); } -int pkg_analyse_elf(const bool developer_mode, struct pkg *pkg, const char *fpath) { - int ret = analyse_elf(pkg, fpath); - if (developer_mode) { - if (ret != EPKG_OK && ret != EPKG_END) { - return EPKG_WARN; - } - analyse_fpath(pkg, fpath); +int pkg_analyse_elf(const bool developer_mode, struct pkg *pkg, const char *fpath) +{ + int ret = analyse_elf(pkg, fpath); + if (developer_mode) { + if (ret != EPKG_OK && ret != EPKG_END) { + return EPKG_WARN; } - return ret; + analyse_fpath(pkg, fpath); + } + return ret; } int pkg_analyse_close_elf() { - shlib_list_free(); return EPKG_OK; } diff --git a/libpkg/pkg_jobs.c b/libpkg/pkg_jobs.c index d5cee05fae..bbc459b315 100644 --- a/libpkg/pkg_jobs.c +++ b/libpkg/pkg_jobs.c @@ -219,6 +219,7 @@ pkg_jobs_free(struct pkg_jobs *j) ucl_object_unref(j->triggers.schema); pkghash_destroy(j->orphaned); pkghash_destroy(j->notorphaned); + pkghash_destroy(j->system_shlibs); free(j); } @@ -1915,8 +1916,21 @@ pkg_jobs_check_and_solve_conflicts(struct pkg_jobs *j, bool *found_conflicts) int pkg_jobs_solve(struct pkg_jobs *j) { - int ret = pkg_jobs_run_solver(j); + int ret; + + assert(j->system_shlibs == NULL); + + /* If /usr/bin/uname is in the pkg database, we are targeting + * a pkgbase system and should rely on the pkgbase packages to + * provide system shlibs. */ + if (!pkgdb_file_exists(j->db, "/usr/bin/uname")) { + ret = scan_system_shlibs(&j->system_shlibs, ctx.pkg_rootdir); + if (ret != EPKG_OK) { + return (ret); + } + } + ret = pkg_jobs_run_solver(j); if (ret != EPKG_OK) return (ret); diff --git a/libpkg/pkg_solve.c b/libpkg/pkg_solve.c index 0b7668c43a..cb3c43f83f 100644 --- a/libpkg/pkg_solve.c +++ b/libpkg/pkg_solve.c @@ -40,6 +40,7 @@ #include #include "pkg.h" +#include "pkghash.h" #include "private/event.h" #include "private/pkg.h" #include "private/pkgdb.h" @@ -671,6 +672,10 @@ pkg_solve_process_universe_variable(struct pkg_solve_problem *problem, /* Shlibs */ tll_foreach(pkg->shlibs_required, s) { + if (pkghash_get(j->system_shlibs, s->item) != NULL) { + /* The shlib is provided by the system */ + continue; + } if (pkg_solve_add_require_rule(problem, cur_var, s->item, cur_var->assumed_reponame) != EPKG_OK) { continue; diff --git a/libpkg/private/binfmt.h b/libpkg/private/binfmt.h index fda509a3e3..91b5444cfe 100644 --- a/libpkg/private/binfmt.h +++ b/libpkg/private/binfmt.h @@ -8,6 +8,13 @@ #include "private/pkg.h" +/* In the future this will be extended to include + e.g. PKG_PROVIDE_SHLIB_COMPAT_32 */ +enum pkg_provide_flags { + PKG_PROVIDE_NONE = 0, + PKG_PROVIDE_SHLIB_NATIVE = 1 << 0, +}; + int pkg_elf_abi_from_fd(int fd, struct pkg_abi *abi); int pkg_analyse_init_elf(const char* stage); int pkg_analyse_elf(const bool developer_mode, struct pkg *pkg, const char *fpath); diff --git a/libpkg/private/ldconfig.h b/libpkg/private/ldconfig.h deleted file mode 100644 index bbcbc7238f..0000000000 --- a/libpkg/private/ldconfig.h +++ /dev/null @@ -1,81 +0,0 @@ -/*- - * Copyright (c) 1998 John D. Polstra - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * $FreeBSD: stable/8/sbin/ldconfig/ldconfig.h 92882 2002-03-21 13:14:21Z imp $ - */ - -#ifndef LDCONFIG_H -#define LDCONFIG_H 1 - -#ifdef HAVE_CONFIG_H -#include "pkg_config.h" -#endif - -#include - -#ifdef HAVE_ELF_HINTS_H -#include -#else -/* - * Hints file produced by ldconfig. - */ -struct elfhints_hdr -{ - u_int32_t magic; /* Magic number */ - u_int32_t version; /* File version (1) */ - u_int32_t strtab; /* Offset of string table in file */ - u_int32_t strsize; /* Size of string table */ - u_int32_t dirlist; /* Offset of directory list in - string table */ - u_int32_t dirlistlen; /* strlen(dirlist) */ - u_int32_t spare[26]; /* Room for expansion */ -}; - -#define ELFHINTS_MAGIC 0x746e6845 - -# ifdef __NetBSD__ -#define _PATH_ELF_HINTS "/var/run/ld.so.hints" -# else -#define _PATH_ELF_HINTS "/var/run/ld-elf.so.hints" -# endif -#endif - -extern int insecure; /* -i flag, needed here for elfhints.c */ - -__BEGIN_DECLS -void shlib_list_init(void); -void rpath_list_init(void); -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 *, const char *); -void shlib_list_from_stage(const char *); - -void list_elf_hints(const char *); -void update_elf_hints(const char *, int, char **, int); -__END_DECLS - -#endif diff --git a/libpkg/private/pkg.h b/libpkg/private/pkg.h index 1b53eb51a0..79db5c1da6 100644 --- a/libpkg/private/pkg.h +++ b/libpkg/private/pkg.h @@ -844,4 +844,6 @@ int pkg_parse_manifest_ucl(struct pkg *pkg, ucl_object_t *o); int pkg_get_reposdirfd(void); char * expand_plist_variables(const char *in, kvlist_t *vars); +int scan_system_shlibs(pkghash **system_shlibs, const char *rootdir); + #endif diff --git a/libpkg/private/pkg_jobs.h b/libpkg/private/pkg_jobs.h index 5cfda59309..e67d8d1791 100644 --- a/libpkg/private/pkg_jobs.h +++ b/libpkg/private/pkg_jobs.h @@ -142,6 +142,7 @@ struct pkg_jobs { struct triggers triggers; struct pkghash *orphaned; struct pkghash *notorphaned; + struct pkghash *system_shlibs; }; #define PKG_PATTERN_FLAG_FILE (1 << 0) diff --git a/libpkg/system_shlibs.c b/libpkg/system_shlibs.c new file mode 100644 index 0000000000..31f3c0180c --- /dev/null +++ b/libpkg/system_shlibs.c @@ -0,0 +1,92 @@ +/*- + * Copyright (c) 1998 John D. Polstra + * Copyright (c) 2012 Matthew Seaman + * Copyright (c) 2024 The FreeBSD Foundation + * + * This software was developed in part by Isaac Freund + * under sponsorship from the FreeBSD Foundation. + * + * SPDX-License-Identifier: BSD-2-Clause + */ + +#include +#include +#include +#include +#include + +#include "pkg.h" +#include "pkghash.h" +#include "private/event.h" +#include "xmalloc.h" + +static int +scan_dir_for_shlibs(pkghash **shlib_list, const char *dir) +{ + DIR *dirp= opendir(dir); + if (dirp == NULL) { + if (errno == ENOENT) { + return (EPKG_OK); + } + pkg_errno("Failed to open '%s' to scan for shared libraries", dir); + return (EPKG_FATAL); + } + + struct dirent *dp; + while ((dp = readdir(dirp)) != NULL) { + /* Only regular files and sym-links. On some + filesystems d_type is not set, on these the d_type + field will be DT_UNKNOWN. */ + if (dp->d_type != DT_REG && dp->d_type != DT_LNK && + dp->d_type != DT_UNKNOWN) + continue; + + int len = strlen(dp->d_name); + /* Name can't be shorter than "libx.so" */ + if (len < 7 || strncmp(dp->d_name, "lib", 3) != 0) + continue; + + const char *vers = dp->d_name + len; + while (vers > dp->d_name && + (isdigit(*(vers-1)) || *(vers-1) == '.')) + vers--; + if (vers == dp->d_name + len) { + if (strncmp(vers - 3, ".so", 3) != 0) + continue; + } else if (vers < dp->d_name + 3 || + strncmp(vers - 3, ".so.", 4) != 0) + continue; + + /* We have a valid shared library name. */ + pkghash_safe_add(*shlib_list, dp->d_name, NULL, NULL); + } + + closedir(dirp); + + return (EPKG_OK); +} + +static const char *system_shlib_dirs[] = { + "/lib", + "/usr/lib", +}; + +int +scan_system_shlibs(pkghash **system_shlibs, const char *rootdir) +{ + for (int i = 0; i < NELEM(system_shlib_dirs); i++) { + char *dir; + if (rootdir != NULL) { + xasprintf(&dir, "%s%s", rootdir, system_shlib_dirs[i]); + } else { + dir = xstrdup(system_shlib_dirs[i]); + } + int ret = scan_dir_for_shlibs(system_shlibs, dir); + free(dir); + if (ret != EPKG_OK) { + return (ret); + } + } + + return (EPKG_OK); +} diff --git a/scripts/completion/_pkg.in b/scripts/completion/_pkg.in index 6a13055440..af16962c57 100644 --- a/scripts/completion/_pkg.in +++ b/scripts/completion/_pkg.in @@ -108,7 +108,6 @@ _pkg_config_opts() { _values 'configuration option' \ 'ABI[ABI of package you want to install]:string' \ 'ALIAS[define local aliases for various pkg(8) standard command lines]:key/value list' \ - 'ALLOW_BASE_SHLIBS[enable base libraries analysis]:boolean:(yes no)' \ 'AUTOCLEAN[cleanout content of cache directory after upgrades or installations]:boolean:(yes no)' \ 'AUTOMERGE[automatically merge configuration files]:boolean:(yes no)' \ 'DEFAULT_ALWAYS_YES[default to "yes" for all questions requiring user confirmation]:boolean:(yes no)' \ diff --git a/tests/frontend/create-parsebin.sh b/tests/frontend/create-parsebin.sh index d46e6ae359..264dc28808 100644 --- a/tests/frontend/create-parsebin.sh +++ b/tests/frontend/create-parsebin.sh @@ -3,9 +3,7 @@ . $(atf_get_srcdir)/test_environment.sh tests_init \ - create_from_bin \ - create_from_machobinbase \ - create_from_elfbinbase + create_from_bin genmanifest() { local PKG_NAME="$1" @@ -64,9 +62,6 @@ categories [ "test", ] EOF - if [ x"${ALLOW_BASE_SHLIBS}" = xyes ]; then - Xshlibs_required="${Xshlibs_required_base}" - fi if [ -n "${Xshlibs_required}" ]; then echo "shlibs_required [" >> ${PKG_NAME}.expected for i in ${Xshlibs_required}; do @@ -97,22 +92,17 @@ EOF } do_check() { - ALLOW_BASE_SHLIBS=$1 - local PKG_NAME=$2 - local file1=$(atf_get_srcdir)/$3 + local PKG_NAME=$1 + local file1=$(atf_get_srcdir)/$2 genmanifest ${PKG_NAME} ${file1} - atf_check \ - -o inline:"${ALLOW_BASE_SHLIBS}\n" \ - pkg -o IGNORE_OSMAJOR=1 -o ABI_FILE=${file1} -o ALLOW_BASE_SHLIBS=${ALLOW_BASE_SHLIBS} config allow_base_shlibs - # cat ${PKG_NAME}.manifest atf_check \ -o empty \ -e empty \ -s exit:0 \ - pkg -o IGNORE_OSMAJOR=1 -o ABI_FILE=${file1} -o ALLOW_BASE_SHLIBS=${ALLOW_BASE_SHLIBS} create -M ./${PKG_NAME}.manifest -r ${TMPDIR} + pkg -o IGNORE_OSMAJOR=1 -o ABI_FILE=${file1} create -M ./${PKG_NAME}.manifest -r ${TMPDIR} # cat ${PKG_NAME}.expected atf_check \ @@ -131,31 +121,6 @@ create_from_bin_body() { macosfat.bin "macosfat.bin#x86_64" "macosfat.bin#aarch64" \ macosfatlib.bin "macosfatlib.bin#x86_64" "macosfatlib.bin#aarch64" do - do_check no testbin $bin + do_check testbin $bin done } - -create_from_machobinbase_body() { - for bin in \ - macos.bin macos106.bin macos150.bin \ - macosfat.bin "macosfat.bin#x86_64" "macosfat.bin#aarch64" \ - macosfatlib.bin "macosfatlib.bin#x86_64" "macosfatlib.bin#aarch64" - do - do_check yes machobinbase $bin - done -} - -create_from_elfbinbase_body() { - atf_skip_on Linux Test fails on Linux - atf_skip_on Darwin Test fails on Darwin - - # FIXME: All ELF readers are failing on non-native runs. - for bin in \ - freebsd-aarch64.bin freebsd-amd64.bin freebsd-armv6.bin freebsd-armv7.bin \ - freebsd-i386.bin freebsd-powerpc.bin freebsd-powerpc64.bin freebsd-powerpc64le.bin \ - freebsd-riscv64.bin \ - linux.bin dfly.bin - do - do_check yes elfbinbase $bin - done -} \ No newline at end of file diff --git a/tests/frontend/test_environment.sh.in b/tests/frontend/test_environment.sh.in index fe97ff1422..f02a5e0419 100755 --- a/tests/frontend/test_environment.sh.in +++ b/tests/frontend/test_environment.sh.in @@ -58,103 +58,102 @@ bin_meta() { XFreeBSD_version="" Xshlibs_provided="" Xshlibs_required="" - Xshlibs_required_base="" case "${file}" in *freebsd-aarch64.bin) XABI=FreeBSD:14:aarch64 XALTABI=freebsd:14:aarch64:64 XFreeBSD_version=1401000 - Xshlibs_required_base="libc.so.7" + Xshlibs_required="libc.so.7" ;; *freebsd-amd64.bin) XABI=FreeBSD:14:amd64 XALTABI=freebsd:14:x86:64 XFreeBSD_version=1401000 - Xshlibs_required_base="libc.so.7" + Xshlibs_required="libc.so.7" ;; *freebsd-armv6.bin) XABI=FreeBSD:13:armv6 XALTABI=freebsd:13:armv6:32:el:eabi:hardfp XFreeBSD_version=1304000 - Xshlibs_required_base="libgcc_s.so.1 libc.so.7" + Xshlibs_required="libgcc_s.so.1 libc.so.7" ;; *freebsd-armv7.bin) XABI=FreeBSD:14:armv7 XALTABI=freebsd:14:armv7:32:el:eabi:hardfp XFreeBSD_version=1401000 - Xshlibs_required_base="libgcc_s.so.1 libc.so.7" + Xshlibs_required="libgcc_s.so.1 libc.so.7" ;; *freebsd-i386.bin) XABI=FreeBSD:14:i386 XALTABI=freebsd:14:x86:32 XFreeBSD_version=1401000 - Xshlibs_required_base="libc.so.7" + Xshlibs_required="libc.so.7" ;; *freebsd-powerpc.bin) XABI=FreeBSD:14:powerpc XALTABI=freebsd:14:powerpc:32:eb XFreeBSD_version=1401000 - Xshlibs_required_base="libc.so.7" + Xshlibs_required="libc.so.7" ;; *freebsd-powerpc64.bin) XABI=FreeBSD:14:powerpc64 XALTABI=freebsd:14:powerpc:64:eb XFreeBSD_version=1401000 - Xshlibs_required_base="libc.so.7" + Xshlibs_required="libc.so.7" ;; *freebsd-powerpc64le.bin) XABI=FreeBSD:14:powerpc64le XALTABI=freebsd:14:powerpc:64:el XFreeBSD_version=1401000 - Xshlibs_required_base="libc.so.7" + Xshlibs_required="libc.so.7" ;; *freebsd-riscv64.bin) XABI=FreeBSD:14:riscv64 XALTABI=freebsd:14:riscv:64:hf XFreeBSD_version=1401000 -# Xshlibs_required_base="libc.so.7" +# This riscv64 binary does not have the OS set to FreeBSD in its ELF header +# TODO: handle this in pkg_elf.c +# Xshlibs_required="libc.so.7" ;; *dfly.bin) XABI=dragonfly:5.10:x86:64 XALTABI=dragonfly:5.10:x86:64 -# Xshlibs_required_base="libc.so.8" + Xshlibs_required="libc.so.8" ;; *linux.bin) XABI=Linux:3.2:x86_64 XALTABI=linux:3.2:x86_64 -# Xshlibs_required_base="libc.so.6" + Xshlibs_required="libc.so.6" ;; *macos.bin) XABI=Darwin:24:aarch64 XALTABI=darwin:24:aarch64:64 - Xshlibs_required_base="libSystem.B.dylib-1351.0" + Xshlibs_required="libSystem.B.dylib-1351.0" ;; *macos106.bin) XABI=Darwin:10:x86_64 XALTABI=darwin:10:x86_64 - Xshlibs_required_base="libSystem.B.dylib-125.2.11" + Xshlibs_required="libSystem.B.dylib-125.2.11" ;; *macos150.bin) XABI=Darwin:24:x86_64 XALTABI=darwin:24:x86_64 - Xshlibs_required_base="libSystem.B.dylib-1351.0" + Xshlibs_required="libSystem.B.dylib-1351.0" ;; # macosfat.bin has x86_64 as its first entry *macosfat.bin|*macosfat.bin#x86_64) XABI=Darwin:17:x86_64 XALTABI=darwin:17:x86_64 - Xshlibs_required="libAnswer.A.dylib-1.2" - Xshlibs_required_base="libAnswer.A.dylib-1.2 libSystem.B.dylib-1319.0" + Xshlibs_required="libAnswer.A.dylib-1.2 libSystem.B.dylib-1319.0" ;; # macosfat also has an aarch64 entry *macosfat.bin#aarch64) XABI=Darwin:20:aarch64 XALTABI=darwin:20:aarch64:64 - Xshlibs_required="libAnswer.A.dylib-1.1" - Xshlibs_required_base="libAnswer.A.dylib-1.1 libSystem.B.dylib-1319.0" + Xshlibs_required="libAnswer.A.dylib-1.1 libSystem.B.dylib-1319.0" ;; # macosfatlib.bin has x86_64 as its first entry @@ -162,14 +161,14 @@ bin_meta() { XABI=Darwin:17:x86_64 XALTABI=darwin:17:x86_64 Xshlibs_provided="libAnswer.A.dylib-1.2" - Xshlibs_required_base="libSystem.B.dylib-1319.0" + Xshlibs_required="libSystem.B.dylib-1319.0" ;; *macosfatlib.bin#aarch64) XABI=Darwin:20:aarch64 XALTABI=darwin:20:aarch64:64 Xshlibs_provided="libAnswer.A.dylib-1.1" - Xshlibs_required_base="libSystem.B.dylib-1319.0" + Xshlibs_required="libSystem.B.dylib-1319.0" ;; *) diff --git a/tests/lib/pkg_elf.c b/tests/lib/pkg_elf.c index c26b4b03fc..6af751f667 100644 --- a/tests/lib/pkg_elf.c +++ b/tests/lib/pkg_elf.c @@ -61,22 +61,25 @@ ATF_TC_BODY(analyse_elf, tc) ATF_REQUIRE_EQ(pkg_analyse_elf(false, p, binpath), EPKG_OK); ATF_REQUIRE_EQ(tll_length(p->shlibs_provided), 1); ATF_REQUIRE_STREQ(tll_front(p->shlibs_provided), "libtestfbsd.so.1"); + ATF_REQUIRE_EQ(tll_length(p->shlibs_required), 1); + ATF_REQUIRE_STREQ(tll_front(p->shlibs_required), "libc.so.7"); free(binpath); xasprintf(&binpath, "%s/Makefile", atf_tc_get_config_var(tc, "srcdir")); ATF_REQUIRE_EQ(pkg_analyse_elf(false, p, binpath), EPKG_END); ATF_REQUIRE_EQ(tll_length(p->shlibs_provided), 1); + ATF_REQUIRE_EQ(tll_length(p->shlibs_required), 1); free(binpath); - ATF_REQUIRE_EQ(tll_length(p->shlibs_required), 0); xasprintf(&binpath, "%s/frontend/libtest2fbsd.so.1", atf_tc_get_config_var(tc, "srcdir")); ATF_REQUIRE_EQ(pkg_analyse_elf(false, p, binpath), EPKG_OK); ATF_REQUIRE_EQ(tll_length(p->shlibs_provided), 2); ATF_REQUIRE_STREQ(tll_back(p->shlibs_provided), "libtest2fbsd.so.1"); - ATF_REQUIRE_EQ(tll_length(p->shlibs_required), 1); - ATF_REQUIRE_STREQ(tll_front(p->shlibs_required), "libfoo.so.1"); + ATF_REQUIRE_EQ(tll_length(p->shlibs_required), 2); + ATF_REQUIRE_STREQ(tll_front(p->shlibs_required), "libc.so.7"); + ATF_REQUIRE_STREQ(tll_back(p->shlibs_required), "libfoo.so.1"); free(binpath); - + pkg_free(p); }