From d0060dd6e1f673e1af7b4c6408842a36734bbc4d Mon Sep 17 00:00:00 2001 From: Brooks Davis Date: Sat, 22 Feb 2025 01:15:51 +0000 Subject: [PATCH] dlopen(1): a program that dlopens its arguments Attempts to dlopen each command line argument then sleeps. This allows trivial demonstration of the impact of loading various libraries without the need to write custom code. --- bin/Makefile | 1 + bin/dlopen/Makefile | 6 +++ bin/dlopen/dlopen.1 | 66 ++++++++++++++++++++++++++++++++ bin/dlopen/dlopen.c | 91 +++++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 164 insertions(+) create mode 100644 bin/dlopen/Makefile create mode 100644 bin/dlopen/dlopen.1 create mode 100644 bin/dlopen/dlopen.c diff --git a/bin/Makefile b/bin/Makefile index 1c5c4af7f301..fa361f1c53fd 100644 --- a/bin/Makefile +++ b/bin/Makefile @@ -9,6 +9,7 @@ SUBDIR= cat \ date \ dd \ df \ + dlopen \ domainname \ echo \ ed \ diff --git a/bin/dlopen/Makefile b/bin/dlopen/Makefile new file mode 100644 index 000000000000..deaaaca79b42 --- /dev/null +++ b/bin/dlopen/Makefile @@ -0,0 +1,6 @@ +PACKAGE=runtime +PROG= dlopen + +LIBADD= util + +.include diff --git a/bin/dlopen/dlopen.1 b/bin/dlopen/dlopen.1 new file mode 100644 index 000000000000..a51ce61729a8 --- /dev/null +++ b/bin/dlopen/dlopen.1 @@ -0,0 +1,66 @@ +.\"- +.\" SPDX-License-Identifier: BSD-2-Clause +.\" +.\" Copyright (c) 2025 (holder) +.\" +.\" This software was developed by SRI International, the University of +.\" Cambridge Computer Laboratory (Department of Computer Science and +.\" Technology), and Capabilities Limited under Defense Advanced Research +.\" Projects Agency (DARPA) Contract No. FA8750-24-C-B047 ("DEC"). +.\" +.Dd April 23, 2025 +.Dt DLOPEN 1 +.Os +.Sh Name +.Nm dlopen +.Nd load libraries with dlopen(3) and sleep for analysis +.Sh SYNOPSIS +.Nm +.Op Brq Fl L | Fl N +.Op Brq Fl g | Fl l +.Op Fl v +.Op Fl s Ar seconds +.Ar library ... +.Sh DESCRIPTION +The +.Nm +utility supports analysis of the linkage and loading behavior of dynamiclly +loaded libraries without the need for custom software. +It loads each library listed on the command line and then waits for +input on stdin unless the +.Fl s +flag use used to pass a positive number of seconds to sleep. +.Pp +The +.Fl L +and +.Fl N +flags control the use of +.Dv RTLD_LAZY +versus +.Dv RTLD_NOW +flags. +.Dv RTLD_NOW is +the +.Nm +utility's default. +Likewise +.Fl g +and +.Fl l +control the use of +.Dv RTLD_GLOBAL +or +.Dv RTLD_LOCAL . +The +.Fl v +flag enables verbose mode. +.Sh EXIT STATUS +.Ex -std +.Sh AUTHORS +This software and this manual page were +developed by SRI International, the University of Cambridge Computer +Laboratory (Department of Computer Science and Technology), and +Capabilities Limited under contract +.Pq FA8750-24-C-B047 +.Pq Do DEC Dc . diff --git a/bin/dlopen/dlopen.c b/bin/dlopen/dlopen.c new file mode 100644 index 000000000000..3617189146f9 --- /dev/null +++ b/bin/dlopen/dlopen.c @@ -0,0 +1,91 @@ +/*- + * SPDX-License-Identifier: BSD-2-Clause + * + * Copyright (c) 2025 SRI International + * + * This software was developed by SRI International, the University of + * Cambridge Computer Laboratory (Department of Computer Science and + * Technology), and Capabilities Limited under Defense Advanced Research + * Projects Agency (DARPA) Contract No. FA8750-24-C-B047 ("DEC"). + */ + +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +static bool verbose = false; +static int seconds = -1; +static int dlopen_mode = RTLD_NOW; +static int dlopen_local_global = 0; /* dlopen(3)'s default is RTLD_LOCAL */ + +static void _Noreturn +usage(void) +{ + printf("usage: dlopen [-L|N] [-g|l] [-s ] [-v] [...]\n"); + exit(1); +} + +int +main(int argc, char **argv) +{ + int ch; + uint64_t num; + + while ((ch = getopt(argc, argv, "gLlNs:v")) != -1) { + switch (ch) { + case 'g': + dlopen_local_global = RTLD_GLOBAL; + break; + case 'l': + dlopen_local_global = RTLD_LOCAL; + break; + case 'L': + dlopen_mode = RTLD_LAZY; + break; + case 'N': + dlopen_mode = RTLD_NOW; + break; + case 's': + if (expand_number(optarg, &num) != 0) + err(1, "bad number '%s'", optarg); + if (num > INT_MAX) + seconds = INT_MAX; + else + seconds = num; + break; + case 'v': + verbose = true; + break; + case '?': + default: + usage(); + } + } + argc -= optind; + argv += optind; + + for (int i = 0; i < argc; i++) { + if (dlopen(argv[i], dlopen_mode | dlopen_local_global) == NULL) + errx(1, "dlopen(%s)", argv[i]); + if (verbose) + printf("loaded %s\n", argv[i]); + } + + if (seconds < 0) { + if (verbose) + printf("waiting for input\n"); + (void)getchar(); + } else { + if (seconds != 0 && verbose) + printf("sleeping for %d seconds\n", seconds); + sleep(seconds); + } + return (0); +}