// dynhello: the smallest honest test of dynamic linking. // // Linked against libc.so and libdynhello.so, with /lib/ld-musl-x86_64.so.1 as // its interpreter, so nothing here works unless the kernel loaded the // interpreter and the interpreter mapped both libraries. It then checks the // three things a dynamic program leans on that a static one hides: thread- // local storage (errno), the heap, and a fork whose child still has its // libraries. #include #include #include #include #include #include int dynhello_greet(const char *who); int main(int argc, char **argv) { int bad = 0; dynhello_greet(argc > 1 ? argv[1] : "world"); errno = 0; if (close(-1) == 0 || errno != EBADF) { printf("dynhello: FAIL errno is %d, not EBADF\n", errno); bad++; } char *p = malloc(1 << 20); if (!p) { printf("dynhello: FAIL malloc\n"); bad++; } else { memset(p, 0x5a, 1 << 20); free(p); } pid_t pid = fork(); if (pid == 0) { dynhello_greet("child"); _exit(0); } int st = 0; if (pid < 0 || waitpid(pid, &st, 0) != pid || !WIFEXITED(st) || WEXITSTATUS(st) != 0) { printf("dynhello: FAIL fork child status %d\n", st); bad++; } printf("dynhello: %s\n", bad ? "FAILED" : "ok"); return bad != 0; }