LCOV - code coverage report
Current view: top level - libpkg - pkg_abi.c (source / functions) Hit Total Coverage
Test: plop Lines: 196 262 74.8 %
Date: 2024-12-28 18:40:32 Functions: 13 13 100.0 %
Legend: Lines: hit not hit | Branches: + taken - not taken # not executed Branches: 119 196 60.7 %

           Branch data     Line data    Source code
       1                 :            : /*-
       2                 :            :  * Copyright (c) 2011-2012 Baptiste Daroussin <bapt@FreeBSD.org>
       3                 :            :  * Copyright (c) 2012-2013 Matthew Seaman <matthew@FreeBSD.org>
       4                 :            :  * Copyright (c) 2024 The FreeBSD Foundation
       5                 :            :  *
       6                 :            :  * This software was developed in part by Isaac Freund <ifreund@freebsdfoundation.org>
       7                 :            :  * under sponsorship from the FreeBSD Foundation.
       8                 :            :  *
       9                 :            :  * SPDX-License-Identifier: BSD-2-Clause
      10                 :            :  */
      11                 :            : #ifdef HAVE_CONFIG_H
      12                 :            : #include "pkg_config.h"
      13                 :            : #endif
      14                 :            : 
      15                 :            : #include <ctype.h>
      16                 :            : #include <paths.h>
      17                 :            : #include <string.h>
      18                 :            : #include <unistd.h>
      19                 :            : 
      20                 :            : #include "pkg.h"
      21                 :            : #include "private/pkg_abi.h"
      22                 :            : #include "private/binfmt.h"
      23                 :            : #include "private/event.h"
      24                 :            : #include "private/pkg.h"
      25                 :            : #include "xmalloc.h"
      26                 :            : 
      27                 :            : #define _PATH_UNAME "/usr/bin/uname"
      28                 :            : 
      29                 :            : /* All possibilities on FreeBSD as of 5/26/2014 */
      30                 :            : struct arch_trans {
      31                 :            :         const char *elftype;
      32                 :            :         const char *archid;
      33                 :            : };
      34                 :            : 
      35                 :            : static struct arch_trans machine_arch_translation[] = { { "x86:32", "i386" },
      36                 :            :         { "x86:64", "amd64" }, { "powerpc:32:eb", "powerpc" },
      37                 :            :         { "powerpc:64:eb", "powerpc64" }, { "powerpc:64:el", "powerpc64le" },
      38                 :            :         { "sparc64:64", "sparc64" }, { "ia64:64", "ia64" },
      39                 :            :         /* All the ARM stuff */
      40                 :            :         { "armv6:32:el:eabi:hardfp", "armv6" },
      41                 :            :         { "armv7:32:el:eabi:hardfp", "armv7" }, { "aarch64:64", "aarch64" },
      42                 :            :         /* And now MIPS */
      43                 :            :         { "mips:32:el:o32", "mipsel" }, { "mips:32:el:n32", "mipsn32el" },
      44                 :            :         { "mips:32:eb:o32", "mips" }, { "mips:32:eb:n32", "mipsn32" },
      45                 :            :         { "mips:64:el:n64", "mips64el" }, { "mips:64:eb:n64", "mips64" },
      46                 :            :         /* And RISC-V */
      47                 :            :         { "riscv:32:hf", "riscv32" }, { "riscv:32:sf", "riscv32sf" },
      48                 :            :         { "riscv:64:hf", "riscv64" }, { "riscv:64:sf", "riscv64sf" },
      49                 :            : 
      50                 :            :         { NULL, NULL } };
      51                 :            : 
      52                 :            : static struct {
      53                 :            :         enum pkg_os os;
      54                 :            :         const char *string;
      55                 :            : } os_string_table[] = {
      56                 :            :         { PKG_OS_UNKNOWN, "Unknown" },
      57                 :            :         { PKG_OS_FREEBSD, "FreeBSD" },
      58                 :            :         { PKG_OS_NETBSD, "NetBSD" },
      59                 :            :         { PKG_OS_DRAGONFLY, "dragonfly" },
      60                 :            :         { PKG_OS_LINUX, "Linux" },
      61                 :            :         { PKG_OS_DARWIN, "Darwin" },
      62                 :            :         { -1, NULL },
      63                 :            : };
      64                 :            : 
      65                 :            : /* This table does not include PKG_ARCH_AMD64 as the string translation of
      66                 :            :    that arch is os-dependent. */
      67                 :            : static struct {
      68                 :            :         enum pkg_arch arch;
      69                 :            :         const char *string;
      70                 :            : } arch_string_table[] = {
      71                 :            :         { PKG_ARCH_UNKNOWN, "unknown"},
      72                 :            :         { PKG_ARCH_I386, "i386"},
      73                 :            :         { PKG_ARCH_ARMV6, "armv6"},
      74                 :            :         { PKG_ARCH_ARMV7, "armv7"},
      75                 :            :         { PKG_ARCH_AARCH64, "aarch64"},
      76                 :            :         { PKG_ARCH_POWERPC, "powerpc"},
      77                 :            :         { PKG_ARCH_POWERPC64, "powerpc64"},
      78                 :            :         { PKG_ARCH_POWERPC64LE, "powerpc64le"},
      79                 :            :         { PKG_ARCH_RISCV32, "riscv32"},
      80                 :            :         { PKG_ARCH_RISCV64, "riscv64"},
      81                 :            :         { -1, NULL },
      82                 :            : };
      83                 :            : 
      84                 :            : const char *
      85                 :       7389 : pkg_os_to_string(enum pkg_os os)
      86                 :            : {
      87         [ +  - ]:      16070 :         for (size_t i = 0; os_string_table[i].string != NULL; i++) {
      88         [ +  + ]:      16070 :                 if (os == os_string_table[i].os) {
      89                 :       7389 :                         return os_string_table[i].string;
      90                 :            :                 }
      91                 :       8681 :         }
      92                 :          0 :         assert(0);
      93                 :            : }
      94                 :            : 
      95                 :            : enum pkg_os
      96                 :          2 : pkg_os_from_string(const char *string)
      97                 :            : {
      98         [ +  - ]:          4 :         for (size_t i = 0; os_string_table[i].string != NULL; i++) {
      99         [ +  + ]:          4 :                 if (STREQ(string, os_string_table[i].string)) {
     100                 :          2 :                         return os_string_table[i].os;
     101                 :            :                 }
     102                 :          2 :         }
     103                 :          0 :         return (PKG_OS_UNKNOWN);
     104                 :          2 : }
     105                 :            : 
     106                 :            : /* Returns true if the OS uses "amd64" rather than "x86_64" */
     107                 :            : static bool
     108                 :       7047 : pkg_os_uses_amd64_name(enum pkg_os os)
     109                 :            : {
     110   [ +  +  +  -  :       7047 :         switch (os) {
                -  -  - ]
     111                 :            :         case PKG_OS_FREEBSD:
     112                 :       7047 :                 return (true);
     113                 :            :         case PKG_OS_DARWIN:
     114                 :            :         case PKG_OS_NETBSD:
     115                 :            :         case PKG_OS_LINUX:
     116                 :        242 :                 return (false);
     117                 :            :         case PKG_OS_DRAGONFLY:
     118                 :          0 :         case PKG_OS_UNKNOWN:
     119                 :            :         default:
     120                 :          0 :                 assert(0);
     121                 :            :         }
     122                 :       7047 : }
     123                 :            : 
     124                 :            : const char *
     125                 :       7421 : pkg_arch_to_string(enum pkg_os os, enum pkg_arch arch)
     126                 :            : {
     127         [ +  + ]:       7421 :         if (arch == PKG_ARCH_AMD64) {
     128         [ +  + ]:       7055 :                 if (os == PKG_OS_DRAGONFLY) {
     129                 :         28 :                         return ("x86:64");
     130         [ +  + ]:       7027 :                 } else if (pkg_os_uses_amd64_name(os)) {
     131                 :       6803 :                         return ("amd64");
     132                 :            :                 } else {
     133                 :        224 :                         return ("x86_64");
     134                 :            :                 }
     135                 :            :         }
     136                 :            : 
     137         [ +  - ]:       1958 :         for (size_t i = 0; arch_string_table[i].string != NULL; i++) {
     138         [ +  + ]:       1958 :                 if (arch == arch_string_table[i].arch) {
     139                 :        366 :                         return arch_string_table[i].string;
     140                 :            :                 }
     141                 :       1592 :         }
     142                 :            : 
     143                 :          0 :         assert(0);
     144                 :       7421 : }
     145                 :            : 
     146                 :            : enum pkg_arch
     147                 :         20 : pkg_arch_from_string(enum pkg_os os, const char *string)
     148                 :            : {
     149         [ -  + ]:         20 :         if (os == PKG_OS_DRAGONFLY) {
     150         [ #  # ]:          0 :                 if (STREQ(string, "x86:64")) {
     151                 :          0 :                         return (PKG_ARCH_AMD64);
     152                 :            :                 }
     153         [ +  + ]:         20 :         } else if (pkg_os_uses_amd64_name(os)) {
     154         [ +  - ]:          2 :                 if (STREQ(string, "amd64")) {
     155                 :          0 :                         return (PKG_ARCH_AMD64);
     156                 :            :                 }
     157                 :          2 :         } else {
     158         [ +  + ]:         18 :                 if (STREQ(string, "x86_64")) {
     159                 :          6 :                         return (PKG_ARCH_AMD64);
     160                 :            :                 }
     161                 :            :         }
     162                 :            : 
     163         [ +  + ]:         72 :         for (size_t i = 0; arch_string_table[i].string != NULL; i++) {
     164         [ +  + ]:         70 :                 if (STREQ(string, arch_string_table[i].string)) {
     165                 :         12 :                         return arch_string_table[i].arch;
     166                 :            :                 }
     167                 :         58 :         }
     168                 :            : 
     169                 :          2 :         return (PKG_ARCH_UNKNOWN);
     170                 :         20 : }
     171                 :            : 
     172                 :            : bool
     173                 :       7391 : pkg_abi_string_only_major_version(enum pkg_os os)
     174                 :            : {
     175   [ +  -  +  -  :       7391 :         switch (os) {
                +  +  - ]
     176                 :            :         case PKG_OS_FREEBSD:
     177                 :            :         case PKG_OS_NETBSD:
     178                 :            :         case PKG_OS_DARWIN:
     179                 :       7391 :                 return (true);
     180                 :            :         case PKG_OS_DRAGONFLY:
     181                 :            :         case PKG_OS_LINUX:
     182                 :         56 :                 return (false);
     183                 :          0 :         case PKG_OS_UNKNOWN:
     184                 :            :         default:
     185                 :          0 :                 assert (0);
     186                 :            :         }
     187                 :       7391 : }
     188                 :            : 
     189                 :            : char *
     190                 :       4266 : pkg_abi_to_string(const struct pkg_abi *abi)
     191                 :            : {
     192                 :            :         char *ret;
     193         [ +  + ]:       4266 :         if (pkg_abi_string_only_major_version(abi->os)) {
     194                 :       8468 :                 xasprintf(&ret, "%s:%d:%s", pkg_os_to_string(abi->os),
     195                 :       4234 :                     abi->major, pkg_arch_to_string(abi->os, abi->arch));
     196                 :       4234 :         } else {
     197                 :         64 :                 xasprintf(&ret, "%s:%d.%d:%s", pkg_os_to_string(abi->os),
     198                 :         32 :                     abi->major, abi->minor,
     199                 :         32 :                     pkg_arch_to_string(abi->os, abi->arch));
     200                 :            :         }
     201                 :       4266 :         return (ret);
     202                 :            : }
     203                 :            : 
     204                 :            : bool
     205                 :          2 : pkg_abi_from_string(struct pkg_abi *abi, const char *string)
     206                 :            : {
     207                 :          2 :         *abi = (struct pkg_abi){0};
     208                 :            : 
     209                 :          2 :         bool ret = false;
     210                 :            : 
     211                 :          2 :         char *copy = xstrdup(string);
     212                 :            : 
     213                 :          2 :         char *iter = copy;
     214                 :          2 :         char *os = strsep(&iter, ":");
     215         [ +  - ]:          2 :         assert(os != NULL);
     216                 :          2 :         abi->os = pkg_os_from_string(os);
     217         [ +  - ]:          2 :         if (abi->os == PKG_OS_UNKNOWN) {
     218                 :          0 :                 pkg_emit_error("Unknown OS '%s' in ABI string", os);
     219                 :          0 :                 goto out;
     220                 :            :         }
     221                 :            : 
     222                 :          2 :         char *version = strsep(&iter, ":");
     223         [ +  - ]:          2 :         if (version == NULL) {
     224                 :          0 :                 pkg_emit_error("Invalid ABI string '%s', "
     225                 :          0 :                     "missing version and architecture", string);
     226                 :          0 :                 goto out;
     227                 :            :         }
     228                 :          2 :         const char *errstr = NULL;
     229         [ +  - ]:          2 :         if (pkg_abi_string_only_major_version(abi->os)) {
     230                 :          2 :                 abi->major = strtonum(version, 1, INT_MAX, &errstr);
     231                 :          2 :         } else {
     232                 :            :                 /* XXX add tests for this */
     233                 :          0 :                 char *major = strsep(&version, ".");
     234                 :          0 :                 char *minor = strsep(&version, ".");
     235                 :            : 
     236         [ #  # ]:          0 :                 assert(major != NULL);
     237         [ #  # ]:          0 :                 if (minor == NULL) {
     238                 :          0 :                         pkg_emit_error("Invalid ABI string %s, "
     239                 :          0 :                             "missing minor OS version", string);
     240                 :          0 :                         goto out;
     241                 :            :                 }
     242                 :            : 
     243                 :          0 :                 abi->major = strtonum(major, 1, INT_MAX, &errstr);
     244         [ #  # ]:          0 :                 if (errstr != NULL) {
     245                 :          0 :                         abi->minor = strtonum(minor, 1, INT_MAX, &errstr);
     246                 :          0 :                 }
     247                 :            :         }
     248         [ -  + ]:          2 :         if (errstr != NULL) {
     249                 :          0 :                 pkg_emit_error("Invalid version in ABI string '%s'", string);
     250                 :          0 :                 goto out;
     251                 :            :         }
     252                 :            : 
     253                 :            :         /* DragonFlyBSD continues to use the legacy/altabi format.
     254                 :            :            For example: dragonfly:5.10:x86:64
     255                 :            :            This means we can't use strsep again since that would split the arch
     256                 :            :            string for dragonfly. */
     257                 :          2 :         char *arch = iter;
     258         [ +  - ]:          2 :         if (arch == NULL) {
     259                 :          0 :                 pkg_emit_error("Invalid ABI string '%s', "
     260                 :          0 :                     "missing architecture", string);
     261                 :          0 :                 goto out;
     262                 :            :         }
     263                 :            : 
     264                 :          2 :         abi->arch = pkg_arch_from_string(abi->os, arch);
     265         [ +  - ]:          2 :         if (abi->arch == PKG_ARCH_UNKNOWN) {
     266                 :          0 :                 pkg_emit_error("Unknown architecture '%s' in ABI string", arch);
     267                 :          0 :                 goto out;
     268                 :            :         }
     269                 :            : 
     270   [ -  +  #  # ]:          2 :         if (abi->os == PKG_OS_DRAGONFLY && abi->arch != PKG_ARCH_AMD64) {
     271                 :          0 :                 pkg_emit_error("Invalid ABI string '%s', "
     272                 :          0 :                     "only x86:64 is supported on dragonfly.", string);
     273                 :          0 :                 goto out;
     274                 :            :         }
     275                 :            : 
     276                 :          2 :         ret = true;
     277                 :            : out:
     278                 :          2 :         free(copy);
     279                 :          2 :         return (ret);
     280                 :            : }
     281                 :            : 
     282                 :            : void
     283                 :        907 : pkg_abi_set_freebsd_osversion(struct pkg_abi *abi, int osversion)
     284                 :            : {
     285         [ +  - ]:        907 :         assert(abi->os == PKG_OS_FREEBSD);
     286                 :            : 
     287                 :        907 :         abi->major = osversion / 100000;
     288                 :        907 :         abi->minor = (osversion / 1000) % 100;
     289                 :        907 :         abi->patch = osversion % 1000;
     290                 :        907 : }
     291                 :            : 
     292                 :            : int
     293                 :       4192 : pkg_abi_get_freebsd_osversion(struct pkg_abi *abi)
     294                 :            : {
     295         [ +  - ]:       4192 :         assert(abi->os == PKG_OS_FREEBSD);
     296                 :            : 
     297                 :       4192 :         return (abi->major * 100000) + (abi->minor * 1000) + abi->patch;
     298                 :            : }
     299                 :            : 
     300                 :            : int
     301                 :        925 : pkg_abi_from_file(struct pkg_abi *abi)
     302                 :            : {
     303                 :            :         char rooted_abi_file[PATH_MAX];
     304                 :        925 :         const char *abi_files[] = {
     305                 :        925 :                 getenv("ABI_FILE"),
     306                 :            :                 _PATH_UNAME,
     307                 :            :                 _PATH_BSHELL,
     308                 :            :         };
     309                 :            :         char work_abi_file[PATH_MAX];
     310                 :            :         char work_arch_hint[PATH_MAX];
     311                 :            : 
     312                 :            :         int i, fd;
     313                 :            : 
     314                 :            :         /*
     315                 :            :          * Perhaps not yet needed, but it may be in the future that there's no
     316                 :            :          * need to check root under some conditions where there is a rootdir.
     317                 :            :          * This also helps alleviate some excessive wrapping later.
     318                 :            :          */
     319                 :        925 :         bool checkroot = ctx.pkg_rootdir != NULL;
     320         [ -  + ]:       1780 :         for (fd = -1, i = 0; i < NELEM(abi_files); i++) {
     321         [ +  + ]:       1780 :                 if (abi_files[i] == NULL)
     322                 :        855 :                         continue;
     323                 :            : 
     324                 :        925 :                 const char *sep = strrchr(abi_files[i], '#');
     325         [ +  + ]:        925 :                 if (sep) {
     326                 :         36 :                         strlcpy(work_abi_file, abi_files[i],
     327         [ +  - ]:         18 :                             MIN(sep - abi_files[i] + 1, sizeof(work_abi_file)));
     328                 :         18 :                         strlcpy(work_arch_hint, sep + 1,
     329                 :            :                             sizeof(work_arch_hint));
     330                 :         18 :                 } else {
     331                 :        907 :                         strlcpy(work_abi_file, abi_files[i],
     332                 :            :                             sizeof(work_abi_file));
     333                 :        907 :                         work_arch_hint[0] = '\0';
     334                 :            :                 }
     335                 :            : 
     336                 :            :                 /*
     337                 :            :                  * Try prepending rootdir and using that if it exists.  If
     338                 :            :                  * ABI_FILE is specified, assume that the consumer didn't want
     339                 :            :                  * it mangled by rootdir.
     340                 :            :                  */
     341   [ +  +  +  +  :        925 :                 if (i > 0 && checkroot &&
                   -  + ]
     342                 :        190 :                     snprintf(rooted_abi_file, PATH_MAX, "%s/%s",
     343                 :        190 :                         ctx.pkg_rootdir, work_abi_file) < PATH_MAX) {
     344         [ +  - ]:         95 :                         if ((fd = open(rooted_abi_file, O_RDONLY)) >= 0) {
     345                 :          0 :                                 strlcpy(work_abi_file, rooted_abi_file,
     346                 :            :                                     sizeof(work_abi_file));
     347                 :          0 :                                 break;
     348                 :            :                         }
     349                 :         95 :                 }
     350         [ +  - ]:        925 :                 if ((fd = open(work_abi_file, O_RDONLY)) >= 0) {
     351                 :        925 :                         break;
     352                 :            :                 }
     353                 :            :                 /* if the ABI_FILE was provided we only care about it */
     354         [ #  # ]:          0 :                 if (i == 0)
     355                 :          0 :                         break;
     356                 :          0 :         }
     357         [ +  - ]:        925 :         if (fd == -1) {
     358                 :          0 :                 pkg_emit_error(
     359                 :            :                     "Unable to determine the ABI, none of the ABI_FILEs can be read.");
     360                 :          0 :                 return EPKG_FATAL;
     361                 :            :         }
     362                 :            : 
     363                 :            : 
     364                 :        925 :         int ret = pkg_elf_abi_from_fd(fd, abi);
     365         [ +  + ]:        956 :         if (EPKG_OK != ret) {
     366         [ -  + ]:         37 :                 if (-1 == lseek(fd, 0, SEEK_SET)) {
     367                 :          0 :                         pkg_emit_errno("Error seeking file", work_abi_file);
     368                 :          0 :                         ret = EPKG_FATAL;
     369                 :          0 :                         goto close_out;
     370                 :            :                 }
     371                 :            : 
     372                 :         37 :                 enum pkg_arch arch_hint = PKG_ARCH_UNKNOWN;
     373         [ +  + ]:         37 :                 if (work_arch_hint[0]) {
     374                 :         18 :                         arch_hint = pkg_arch_from_string(PKG_OS_DARWIN, work_arch_hint);
     375         [ +  + ]:         18 :                         if (arch_hint == PKG_ARCH_UNKNOWN) {
     376                 :          2 :                                 pkg_emit_error("Invalid ABI_FILE architecture hint %s",
     377                 :          2 :                                     work_arch_hint);
     378                 :          2 :                                 ret = EPKG_FATAL;
     379                 :          2 :                                 goto close_out;
     380                 :            :                         }
     381                 :         16 :                 }
     382                 :            : 
     383                 :         35 :                 ret = pkg_macho_abi_from_fd(fd, abi, arch_hint);
     384         [ +  + ]:         35 :                 if (EPKG_OK != ret) {
     385                 :          4 :                         pkg_emit_error(
     386                 :            :                             "Unable to determine ABI, %s cannot be parsed.",
     387                 :          4 :                             work_abi_file);
     388                 :          4 :                         ret = EPKG_FATAL;
     389                 :          4 :                         goto close_out;
     390                 :            :                 }
     391                 :         31 :         }
     392                 :            : 
     393                 :            : close_out:
     394         [ +  - ]:        925 :         if (close(fd)) {
     395                 :          0 :                 pkg_emit_errno("Error closing file", work_abi_file);
     396                 :          0 :                 ret = EPKG_FATAL;
     397                 :          0 :         }
     398                 :        925 :         return ret;
     399                 :        925 : }
     400                 :            : 
     401                 :            : int
     402                 :       5757 : pkg_arch_to_legacy(const char *arch, char *dest, size_t sz)
     403                 :            : {
     404                 :       5757 :         int i = 0;
     405                 :            :         struct arch_trans *arch_trans;
     406                 :            : 
     407                 :       5757 :         memset(dest, '\0', sz);
     408                 :            :         /* Lower case the OS */
     409   [ +  +  +  +  :      42814 :         while (arch[i] != ':' && arch[i] != '\0') {
                   +  + ]
     410                 :      37057 :                 dest[i] = tolower(arch[i]);
     411                 :      37057 :                 i++;
     412                 :            :         }
     413         [ +  + ]:       5757 :         if (arch[i] == '\0')
     414                 :        510 :                 return (0);
     415                 :            : 
     416                 :       5247 :         dest[i++] = ':';
     417                 :            : 
     418                 :            :         /* Copy the version */
     419   [ +  +  -  +  :      15795 :         while (arch[i] != ':' && arch[i] != '\0') {
                   +  + ]
     420                 :      10548 :                 dest[i] = arch[i];
     421                 :      10548 :                 i++;
     422                 :            :         }
     423         [ +  - ]:       5247 :         if (arch[i] == '\0')
     424                 :          0 :                 return (0);
     425                 :            : 
     426                 :       5247 :         dest[i++] = ':';
     427                 :            : 
     428         [ +  + ]:      14716 :         for (arch_trans = machine_arch_translation; arch_trans->elftype != NULL;
     429                 :       9469 :             arch_trans++) {
     430         [ +  + ]:      14562 :                 if (STREQ(arch + i, arch_trans->archid)) {
     431                 :      10186 :                         strlcpy(dest + i, arch_trans->elftype,
     432                 :       5093 :                             sz - (arch + i - dest));
     433                 :       5093 :                         return (0);
     434                 :            :                 }
     435                 :       9469 :         }
     436                 :        154 :         strlcpy(dest + i, arch + i, sz - (arch + i - dest));
     437                 :            : 
     438                 :        154 :         return (0);
     439                 :       5757 : }
     440                 :            : 
     441                 :            : int
     442                 :        332 : pkg_analyse_files(struct pkgdb *db __unused, struct pkg *pkg, const char *stage)
     443                 :            : {
     444                 :        332 :         struct pkg_file *file = NULL;
     445                 :        332 :         int ret = EPKG_OK;
     446                 :            :         char fpath[MAXPATHLEN + 1];
     447                 :            :         const char *lib;
     448                 :        332 :         bool failures = false;
     449                 :            : 
     450                 :            :         int (*pkg_analyse_init)(const char *stage);
     451                 :            :         int (*pkg_analyse)(const bool developer_mode, struct pkg *pkg, const char *fpath);
     452                 :            :         int (*pkg_analyse_close)();
     453                 :            : 
     454         [ +  + ]:        332 :         if (0 == strncmp(pkg->abi, "Darwin", 6)) {
     455                 :          9 :                 pkg_analyse_init=pkg_analyse_init_macho;
     456                 :          9 :                 pkg_analyse=pkg_analyse_macho;
     457                 :          9 :                 pkg_analyse_close=pkg_analyse_close_macho;
     458                 :          9 :         } else {
     459                 :        323 :                 pkg_analyse_init=pkg_analyse_init_elf;
     460                 :        323 :                 pkg_analyse=pkg_analyse_elf;
     461                 :        323 :                 pkg_analyse_close=pkg_analyse_close_elf;
     462                 :            :         }
     463                 :            : 
     464         [ +  + ]:        332 :         if (tll_length(pkg->shlibs_required) != 0) {
     465   [ +  -  +  +  :          4 :                 tll_free_and_free(pkg->shlibs_required, free);
                   -  + ]
     466                 :          2 :         }
     467                 :            : 
     468         [ +  + ]:        332 :         if (tll_length(pkg->shlibs_provided) != 0) {
     469   [ +  -  +  +  :         10 :                 tll_free_and_free(pkg->shlibs_provided, free);
                   -  + ]
     470                 :          5 :         }
     471                 :            : 
     472                 :        332 :         ret = pkg_analyse_init(stage);
     473         [ -  + ]:        332 :         if (ret != EPKG_OK) {
     474                 :          0 :                 goto cleanup;
     475                 :            :         }
     476                 :            : 
     477                 :            :         /* Assume no architecture dependence, for contradiction */
     478         [ +  - ]:        332 :         if (ctx.developer_mode)
     479                 :          0 :                 pkg->flags &= ~(PKG_CONTAINS_ELF_OBJECTS |
     480                 :            :                     PKG_CONTAINS_STATIC_LIBS | PKG_CONTAINS_LA);
     481                 :            : 
     482         [ +  + ]:        588 :         while (pkg_files(pkg, &file) == EPKG_OK) {
     483         [ +  + ]:        256 :                 if (stage != NULL)
     484                 :        136 :                         snprintf(fpath, sizeof(fpath), "%s/%s", stage,
     485                 :         68 :                             file->path);
     486                 :            :                 else
     487                 :        188 :                         strlcpy(fpath, file->path, sizeof(fpath));
     488                 :            : 
     489                 :        256 :                 ret = pkg_analyse(ctx.developer_mode, pkg, fpath);
     490         [ +  - ]:        256 :                 if (EPKG_WARN == ret) {
     491                 :          0 :                         failures = true;
     492                 :          0 :                 }
     493                 :            :         }
     494                 :            : 
     495                 :            :         /*
     496                 :            :          * Do not depend on libraries that a package provides itself
     497                 :            :          */
     498   [ +  +  +  +  :        372 :         tll_foreach(pkg->shlibs_required, s)
                   +  + ]
     499                 :            :         {
     500         [ -  + ]:         40 :                 if (stringlist_contains(&pkg->shlibs_provided, s->item)) {
     501                 :          0 :                         pkg_debug(2,
     502                 :            :                             "remove %s from required shlibs as the "
     503                 :            :                             "package %s provides this library itself",
     504                 :          0 :                             s->item, pkg->name);
     505   [ #  #  #  #  :          0 :                         tll_remove_and_free(pkg->shlibs_required, s, free);
                   #  # ]
     506                 :          0 :                         continue;
     507                 :            :                 }
     508                 :         40 :                 file = NULL;
     509         [ +  + ]:         84 :                 while (pkg_files(pkg, &file) == EPKG_OK) {
     510   [ -  +  #  # ]:         44 :                         if ((lib = strstr(file->path, s->item)) != NULL &&
     511         [ #  # ]:          0 :                             strlen(lib) == strlen(s->item) && lib[-1] == '/') {
     512                 :          0 :                                 pkg_debug(2,
     513                 :            :                                     "remove %s from required shlibs as "
     514                 :            :                                     "the package %s provides this file itself",
     515                 :          0 :                                     s->item, pkg->name);
     516                 :            : 
     517   [ #  #  #  #  :          0 :                                 tll_remove_and_free(pkg->shlibs_required, s,
                   #  # ]
     518                 :            :                                     free);
     519                 :          0 :                                 break;
     520                 :            :                         }
     521                 :            :                 }
     522                 :         40 :         }
     523                 :            : 
     524                 :            :         /*
     525                 :            :          * if the package is not supposed to provide share libraries then
     526                 :            :          * drop the provided one
     527                 :            :          */
     528         [ +  - ]:        332 :         if (pkg_kv_get(&pkg->annotations, "no_provide_shlib") != NULL) {
     529   [ #  #  #  #  :          0 :                 tll_free_and_free(pkg->shlibs_provided, free);
                   #  # ]
     530                 :          0 :         }
     531                 :            : 
     532         [ -  + ]:        332 :         if (failures)
     533                 :          0 :                 goto cleanup;
     534                 :            : 
     535                 :        332 :         ret = EPKG_OK;
     536                 :            : 
     537                 :            : cleanup:
     538                 :        332 :         ret = pkg_analyse_close();
     539                 :            : 
     540                 :        332 :         return (ret);
     541                 :            : }

Generated by: LCOV version 1.15