From 33e1b3f8f7af981256bf26c7eb6285f0d550f520 Mon Sep 17 00:00:00 2001 From: Fred Wright <fw@fwright.net> Date: Fri, 18 Oct 2024 20:12:10 -0700 Subject: [PATCH] Rewrite symbol aliases test. The old symbol aliases test relied on looking up symbols with dlsym(), which doesn't work with a statically-linked library. This rewrites it to use ordinary external references, which will fail if the referenced symbols are missing. This means that any errors are build-time errors rather than runtime errors. As noted in the comment, there's theoretically a way to avoid that by using weak references, but we don't bother to wrestle with the added complications of that approach. TESTED: This version passes with both static and dynamic libraries. --- test/test_symbol_aliases.c | 81 +++++++++++++++++++++++++++++--------- 1 file changed, 63 insertions(+), 18 deletions(-) diff --git a/test/test_symbol_aliases.c b/test/test_symbol_aliases.c index 5d88b96..a6e0084 100644 --- a/test/test_symbol_aliases.c +++ b/test/test_symbol_aliases.c @@ -1,26 +1,71 @@ -#include <dlfcn.h> -#include <assert.h> -#include <stdio.h> +/* + * Copyright (c) 2024 Frederick H. G. Wright II <fw@fwright.net> + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ -int main() -{ - void (*fptr)(); +/* + * This provides tests to verify that certain symbol aliases are present. + * + * Although there is probably a way to exploit weak references to defer + * errors until runtime, there are some complications with that approach, + * so we settle for simple external references, where failures are build + * errors rather than runtime errors. + */ - // void __bzero(void *s, size_t n); - fptr = dlsym(RTLD_DEFAULT, "__bzero"); - assert( fptr!=0 && "__bzero symbol does not exist"); +#include <stdio.h> +#include <string.h> + +/* Macro to avoid warnings converting pointer to ULL */ +#if defined(__LP64__) && __LP64__ +#define PTR2ULL(x) ((unsigned long long) (x)) +#else +#define PTR2ULL(x) ((unsigned long long) (unsigned int) (x)) +#endif - // int dirfd(DIR *dirp); - fptr = dlsym(RTLD_DEFAULT, "dirfd"); - assert( fptr!=0 && "dirfd symbol does not exist"); +#define BASE_SYMS \ + SYM_MAC(__bzero) \ + SYM_MAC(dirfd) -#if __ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__ >= 1050 && !defined(__arm64__) - // int fstatat$INODE64(int dirfd, const char *pathname, struct stat64 *buf, int flags); - fptr = dlsym(RTLD_DEFAULT, "fstatat$INODE64"); - assert( fptr!=0 && "fstatat$INODE64 symbol does not exist"); +#if defined(__ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__) \ + && __ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__ >= 1050 \ + && !defined(__arm64__) + #define CHECK_SYMS BASE_SYMS \ + SYM_MAC(fstatat$INODE64) +#else + #define CHECK_SYMS BASE_SYMS #endif - printf("All symbol aliases found\n"); +#define SYM_MAC(name) \ + extern void name(); \ + void *name##_adr = &name; +CHECK_SYMS +#undef SYM_MAC + +int +main(int argc, char *argv[]) +{ + int verbose = 0; + + if (argc > 1 && !strcmp(argv[1], "-v")) verbose = 1; + + if (verbose) { + #define SYM_MAC(name) \ + printf(" " #name " = %llX\n", PTR2ULL(name##_adr)); + CHECK_SYMS + #undef SYM_MAC + } - return 0; + printf("symbol aliases test passed.\n"); + return 0; } -- GitLab