diff --git a/lang/gcc/16/patches/patch-gcc_config_openbsd_h b/lang/gcc/16/patches/patch-gcc_config_openbsd_h index 5a4a31ef3db..5b197588e42 100644 --- a/lang/gcc/16/patches/patch-gcc_config_openbsd_h +++ b/lang/gcc/16/patches/patch-gcc_config_openbsd_h @@ -1,18 +1,20 @@ Index: gcc/config/openbsd.h --- gcc/config/openbsd.h.orig +++ gcc/config/openbsd.h -@@ -40,6 +40,10 @@ along with GCC; see the file COPYING3. If not see +@@ -40,6 +40,12 @@ along with GCC; see the file COPYING3. If not see intended as common ground for arch that don't provide anything suitable. */ +/* Make sure that gcc will not look for .h files in /usr/local/include + unless user explicitly requests it. */ +#undef LOCAL_INCLUDE_DIR ++ ++#define OPENBSD_VERSIONED_SHLIBS + /* OPENBSD_NATIVE is defined only when gcc is configured as part of the OpenBSD source tree, specifically through Makefile.bsd-wrapper. -@@ -108,9 +112,9 @@ while (0) +@@ -108,9 +114,9 @@ while (0) This two-stage defines makes it easy to pick that for targets that have subspecs. */ #ifdef CPP_CPU_SPEC @@ -24,7 +26,7 @@ Index: gcc/config/openbsd.h #endif #undef LIB_SPEC -@@ -273,6 +277,12 @@ do { \ +@@ -273,6 +279,12 @@ do { \ #endif /* Storage layout. */ diff --git a/lang/gcc/16/patches/patch-gcc_gcc_cc b/lang/gcc/16/patches/patch-gcc_gcc_cc index 54351afa0c0..d6428388285 100644 --- a/lang/gcc/16/patches/patch-gcc_gcc_cc +++ b/lang/gcc/16/patches/patch-gcc_gcc_cc @@ -1,7 +1,17 @@ Index: gcc/gcc.cc --- gcc/gcc.cc.orig +++ gcc/gcc.cc -@@ -1078,7 +1078,7 @@ proper position among the other output files. */ +@@ -37,6 +37,9 @@ compilation is specified by a string called a "spec". + #include "coretypes.h" + #include "multilib.h" /* before tm.h */ + #include "tm.h" ++#ifdef OPENBSD_VERSIONED_SHLIBS ++#include ++#endif + #include "xregex.h" + #include "obstack.h" + #include "intl.h" +@@ -1078,7 +1081,7 @@ proper position among the other output files. */ #else #define LD_PIE_SPEC "" #endif @@ -10,3 +20,96 @@ Index: gcc/gcc.cc #endif #ifndef LINK_BUILDID_SPEC +@@ -3049,7 +3052,34 @@ access_check (const char *name, int mode) + return access (name, mode); + } + ++#ifdef OPENBSD_VERSIONED_SHLIBS ++static bool ++openbsd_shlib_version (const char *suffix, unsigned long *major, ++ unsigned long *minor) ++{ ++ char *end; + ++ if (*suffix != '.') ++ return false; ++ ++suffix; ++ if (!ISDIGIT (*suffix)) ++ return false; ++ ++ errno = 0; ++ *major = strtoul (suffix, &end, 10); ++ if (errno || *end != '.') ++ return false; ++ ++ suffix = end + 1; ++ if (!ISDIGIT (*suffix)) ++ return false; ++ ++ errno = 0; ++ *minor = strtoul (suffix, &end, 10); ++ return !errno && *end == '\0'; ++} ++#endif ++ + /* Search for NAME using the prefix list PREFIXES. MODE is passed to + access to check permissions. If DO_MULTI is true, search multilib + paths then non-multilib paths, otherwise do not search multilib paths. +@@ -3073,6 +3103,57 @@ find_a_file (const struct path_prefix *pprefix, const + const int name_len = strlen (name); + const int suffix_len = strlen (suffix); + ++#ifdef OPENBSD_VERSIONED_SHLIBS ++ if (pprefix == &startfile_prefixes && mode == R_OK ++ && endswith (name, ".so") && lbasename (name) == name) ++ return for_each_path (pprefix, do_multi, 0, ++ [=](char *path) -> char* ++ { ++ DIR *dir = opendir (*path ? path : "."); ++ struct dirent *entry; ++ char *best = NULL; ++ unsigned long best_major = 0; ++ unsigned long best_minor = 0; ++ size_t path_len = strlen (path); ++ const char *sep = path_len && !IS_DIR_SEPARATOR (path[path_len - 1]) ++ ? dir_separator_str : ""; ++ ++ if (!dir) ++ return NULL; ++ ++ while ((entry = readdir (dir)) != NULL) ++ { ++ unsigned long major; ++ unsigned long minor; ++ char *candidate; ++ ++ if (strncmp (entry->d_name, name, name_len) != 0 ++ || !openbsd_shlib_version (entry->d_name + name_len, ++ &major, &minor)) ++ continue; ++ ++ if (best != NULL ++ && (major < best_major ++ || (major == best_major && minor <= best_minor))) ++ continue; ++ ++ candidate = concat (path, sep, entry->d_name, NULL); ++ if (access_check (candidate, mode) != 0) ++ { ++ free (candidate); ++ continue; ++ } ++ ++ free (best); ++ best = candidate; ++ best_major = major; ++ best_minor = minor; ++ } ++ ++ closedir (dir); ++ return best; ++ }); ++#endif + + /* Callback appends the file name to the directory path. If the + resulting file exists in the right mode, return the full pathname