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
This commit is contained in:
parent
fea9122ea2
commit
07c084eb10
@ -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;
|
||||
}
|
||||
|
@ -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
|
||||
|
@ -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.
|
||||
|
@ -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)
|
||||
|
Loading…
Reference in New Issue
Block a user