Skip to content

dlopen utility #2337

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 1 commit into
base: dev
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions bin/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ SUBDIR= cat \
date \
dd \
df \
dlopen \
domainname \
echo \
ed \
Expand Down
6 changes: 6 additions & 0 deletions bin/dlopen/Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
PACKAGE=runtime
PROG= dlopen

LIBADD= util

.include <bsd.prog.mk>
66 changes: 66 additions & 0 deletions bin/dlopen/dlopen.1
Original file line number Diff line number Diff line change
@@ -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 .
91 changes: 91 additions & 0 deletions bin/dlopen/dlopen.c
Original file line number Diff line number Diff line change
@@ -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 <sys/cdefs.h>

#include <dlfcn.h>
#include <err.h>
#include <libutil.h>
#include <limits.h>
#include <stdbool.h>
#include <stdlib.h>
#include <stdio.h>
#include <unistd.h>

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 <seconds>] [-v] <lib> [...]\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);
}

Check warning on line 91 in bin/dlopen/dlopen.c

View workflow job for this annotation

GitHub Actions / Style Checker

Missing Signed-off-by: line

Check warning on line 91 in bin/dlopen/dlopen.c

View workflow job for this annotation

GitHub Actions / Style Checker

Missing Signed-off-by: line

Check warning on line 91 in bin/dlopen/dlopen.c

View workflow job for this annotation

GitHub Actions / Style Checker

Missing Signed-off-by: line

Check warning on line 91 in bin/dlopen/dlopen.c

View workflow job for this annotation

GitHub Actions / Style Checker

Missing Signed-off-by: line
Loading