summaryrefslogtreecommitdiffstats
path: root/libexec
diff options
context:
space:
mode:
authormdodd <mdodd@FreeBSD.org>2005-02-04 02:46:41 +0000
committermdodd <mdodd@FreeBSD.org>2005-02-04 02:46:41 +0000
commit07c084eb10cae71165395fe42ad03c46ab5f2b60 (patch)
treec66bf0274c69dcd44063d0c245221d5b1fbf7132 /libexec
parentfea9122ea28421face363e607278a3bdd16acdc1 (diff)
downloadFreeBSD-src-07c084eb10cae71165395fe42ad03c46ab5f2b60.zip
FreeBSD-src-07c084eb10cae71165395fe42ad03c46ab5f2b60.tar.gz
Description from Dan:
Another handy libmap patch. Lets you do stuff like this: LD_LIBMAP="libpthread.so.1=libthr.so.1" mythreadedapp If you already have a program-specific override in libmap.conf, note that you must use a program-specific override in LD_LIBMAP: LD_LIBMAP="[mythreadedapp],libpthread.so.1=libthr.so.1" mythreadedapp PR: bin/74471 Submitted by: Dan Nelson <dnelson AT allantgroup.com> MFC after: 2 weeks
Diffstat (limited to 'libexec')
-rw-r--r--libexec/rtld-elf/libmap.c85
-rw-r--r--libexec/rtld-elf/libmap.h2
-rw-r--r--libexec/rtld-elf/rtld.115
-rw-r--r--libexec/rtld-elf/rtld.c4
4 files changed, 93 insertions, 13 deletions
diff --git a/libexec/rtld-elf/libmap.c b/libexec/rtld-elf/libmap.c
index d683fdb..cb72f03 100644
--- a/libexec/rtld-elf/libmap.c
+++ b/libexec/rtld-elf/libmap.c
@@ -38,32 +38,70 @@ struct lmp {
TAILQ_ENTRY(lmp) lmp_link;
};
+static int lm_count;
+
+static void lmc_parse (FILE *);
static void lm_add (const char *, const char *, const char *);
static void lm_free (struct lm_list *);
static char * lml_find (struct lm_list *, const char *);
static struct lm_list * lmp_find (const char *);
static struct lm_list * lmp_init (char *);
static const char * quickbasename (const char *);
+static int readstrfn (void * cookie, char *buf, int len);
+static int closestrfn (void * cookie);
#define iseol(c) (((c) == '#') || ((c) == '\0') || \
((c) == '\n') || ((c) == '\r'))
int
-lm_init (void)
+lm_init (char *libmap_override)
{
FILE *fp;
- char *cp;
- char *f, *t, *p, *c;
- char prog[MAXPATHLEN];
- char line[MAXPATHLEN + 2];
- dbg("%s()", __func__);
+ dbg("%s(\"%s\")", __func__, libmap_override);
TAILQ_INIT(&lmp_head);
- if ((fp = fopen(_PATH_LIBMAP_CONF, "r")) == NULL)
- return (1);
+ fp = fopen(_PATH_LIBMAP_CONF, "r");
+ if (fp) {
+ lmc_parse(fp);
+ fclose(fp);
+ }
+
+ if (libmap_override) {
+ char *p;
+ /* do some character replacement to make $LIBMAP look like a
+ text file, then "open" it with funopen */
+ libmap_override = xstrdup(libmap_override);
+
+ for (p = libmap_override; *p; p++) {
+ switch (*p) {
+ case '=':
+ *p = ' '; break;
+ case ',':
+ *p = '\n'; break;
+ }
+ }
+ fp = funopen(libmap_override, readstrfn, NULL, NULL, closestrfn);
+ if (fp) {
+ lmc_parse(fp);
+ fclose(fp);
+ }
+ }
+
+ return (lm_count == 0);
+}
+
+static void
+lmc_parse (FILE *fp)
+{
+ char *cp;
+ char *f, *t, *c, *p;
+ char prog[MAXPATHLEN];
+ char line[MAXPATHLEN + 2];
+ dbg("%s(%p)", __func__, fp);
+
p = NULL;
while ((cp = fgets(line, MAXPATHLEN + 1, fp)) != NULL) {
t = f = c = NULL;
@@ -134,8 +172,6 @@ lm_init (void)
*cp = '\0';
lm_add(p, f, t);
}
- fclose(fp);
- return (0);
}
static void
@@ -190,6 +226,7 @@ lm_add (const char *p, const char *f, const char *t)
lm->f = xstrdup(f);
lm->t = xstrdup(t);
TAILQ_INSERT_HEAD(lml, lm, lm_link);
+ lm_count++;
}
char *
@@ -304,3 +341,31 @@ quickbasename (const char *path)
}
return (p);
}
+
+static int
+readstrfn(void * cookie, char *buf, int len)
+{
+ static char *current;
+ static int left;
+ int copied;
+
+ copied = 0;
+ if (!current) {
+ current = cookie;
+ left = strlen(cookie);
+ }
+ while (*current && left && len) {
+ *buf++ = *current++;
+ left--;
+ len--;
+ copied++;
+ }
+ return copied;
+}
+
+static int
+closestrfn(void * cookie)
+{
+ free(cookie);
+ return 0;
+}
diff --git a/libexec/rtld-elf/libmap.h b/libexec/rtld-elf/libmap.h
index e4bd0ae..53b2ba1 100644
--- a/libexec/rtld-elf/libmap.h
+++ b/libexec/rtld-elf/libmap.h
@@ -2,7 +2,7 @@
* $FreeBSD$
*/
-int lm_init (void);
+int lm_init (char *);
void lm_fini (void);
char * lm_find (const char *, const char *);
#ifdef COMPAT_32BIT
diff --git a/libexec/rtld-elf/rtld.1 b/libexec/rtld-elf/rtld.1
index a73bec3..17c007d 100644
--- a/libexec/rtld-elf/rtld.1
+++ b/libexec/rtld-elf/rtld.1
@@ -93,9 +93,22 @@ If set
.Nm
will print a table containing all relocations before symbol
binding and relocation.
+.It Ev LD_LIBMAP
+A library replacement list in the same format as
+.Xr libmap.conf 5 .
+For convenience, the characters
+.Ql =
+and
+.Ql \&,
+can be used instead of a space and a newline.
+This variable is parsed after
+.Xr libmap.conf 5 ,
+and will override its entries.
.It Ev LD_LIBMAP_DISABLE
If set, disables the use of
-.Xr libmap.conf 5 .
+.Xr libmap.conf 5
+and
+.Ev LD_LIBMAP .
.It Ev LD_LIBRARY_PATH
A colon separated list of directories, overriding the default search path
for shared libraries.
diff --git a/libexec/rtld-elf/rtld.c b/libexec/rtld-elf/rtld.c
index 2741c13..6fc64dd 100644
--- a/libexec/rtld-elf/rtld.c
+++ b/libexec/rtld-elf/rtld.c
@@ -137,6 +137,7 @@ void r_debug_state(struct r_debug*, struct link_map*);
static char *error_message; /* Message for dlerror(), or NULL */
struct r_debug r_debug; /* for GDB; */
static bool libmap_disable; /* Disable libmap */
+static char *libmap_override; /* Maps to use in addition to libmap.conf */
static bool trust; /* False for setuid and setgid programs */
static char *ld_bind_now; /* Environment variable for immediate binding */
static char *ld_debug; /* Environment variable for debugging */
@@ -289,6 +290,7 @@ _rtld(Elf_Addr *sp, func_ptr_type *exit_proc, Obj_Entry **objp)
if (trust) {
ld_debug = getenv(LD_ "DEBUG");
libmap_disable = getenv(LD_ "LIBMAP_DISABLE") != NULL;
+ libmap_override = getenv(LD_ "LIBMAP");
ld_library_path = getenv(LD_ "LIBRARY_PATH");
ld_preload = getenv(LD_ "PRELOAD");
}
@@ -363,7 +365,7 @@ _rtld(Elf_Addr *sp, func_ptr_type *exit_proc, Obj_Entry **objp)
sym_zero.st_shndx = SHN_UNDEF;
if (!libmap_disable)
- libmap_disable = (bool)lm_init();
+ libmap_disable = (bool)lm_init(libmap_override);
dbg("loading LD_PRELOAD libraries");
if (load_preload_objects() == -1)
OpenPOWER on IntegriCloud