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:
mdodd 2005-02-04 02:46:41 +00:00
parent fea9122ea2
commit 07c084eb10
4 changed files with 93 additions and 13 deletions

View File

@ -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;
}

View File

@ -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

View File

@ -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.

View File

@ -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)