version 1.40, 1995/10/09 09:24:59 |
version 1.40.2.1, 1996/02/16 23:07:27 |
Line 177 static struct ld_entry ld_entry = { |
|
Line 177 static struct ld_entry ld_entry = { |
|
void binder_entry __P((void)); |
void binder_entry __P((void)); |
long binder __P((jmpslot_t *)); |
long binder __P((jmpslot_t *)); |
static int load_subs __P((struct so_map *)); |
static int load_subs __P((struct so_map *)); |
static struct so_map *map_object __P((char *, struct sod *, |
static struct so_map *map_object __P((struct sod *, struct so_map *)); |
struct so_map *)); |
|
static struct so_map *alloc_link_map __P(( char *, struct sod *, |
static struct so_map *alloc_link_map __P(( char *, struct sod *, |
struct so_map *, caddr_t, |
struct so_map *, caddr_t, |
struct _dynamic *)); |
struct _dynamic *)); |
|
|
|
|
while (next) { |
while (next) { |
struct so_map *newmap; |
struct so_map *newmap; |
char *name; |
|
|
|
sodp = (struct sod *)(LM_LDBASE(smp) + next); |
sodp = (struct sod *)(LM_LDBASE(smp) + next); |
name = (char *)(sodp->sod_name + LM_LDBASE(smp)); |
|
|
|
if ((newmap = map_object(name, sodp, smp)) == NULL) { |
if ((newmap = map_object(sodp, smp)) == NULL) { |
if (!ld_tracing) { |
if (!ld_tracing) { |
char *fmt = sodp->sod_library ? |
char *fmt = sodp->sod_library ? |
"%s: lib%s.so.%d.%d" : |
"%s: lib%s.so.%d.%d" : |
"%s: %s"; |
"%s: %s"; |
err(1, fmt, main_progname, name, |
err(1, fmt, main_progname, |
|
sodp->sod_name+LM_LDBASE(smp), |
sodp->sod_major, |
sodp->sod_major, |
sodp->sod_minor); |
sodp->sod_minor); |
} |
} |
newmap = alloc_link_map(NULL, sodp, smp, 0, 0); |
newmap = alloc_link_map(NULL, sodp, smp, 0, 0); |
} |
} |
LM_PRIVATE(newmap)->spd_refcount++; |
LM_PRIVATE(newmap)->spd_refcount++; |
LM_PARENT(newmap) = smp; |
|
next = sodp->sod_next; |
next = sodp->sod_next; |
} |
} |
} |
} |
|
|
if ((sodp = smp->som_sod) == NULL) |
if ((sodp = smp->som_sod) == NULL) |
continue; |
continue; |
|
|
name = sodp->sod_name + LM_LDBASE(LM_PARENT(smp)); |
name = (char *)sodp->sod_name; |
|
if (LM_PARENT(smp)) |
|
name += (long)LM_LDBASE(LM_PARENT(smp)); |
|
|
if ((path = smp->som_path) == NULL) |
if ((path = smp->som_path) == NULL) |
path = "not found"; |
path = "not found"; |
Line 525 alloc_link_map(path, sodp, parent, addr, |
|
Line 524 alloc_link_map(path, sodp, parent, addr, |
|
* in link map SMP. |
* in link map SMP. |
*/ |
*/ |
static struct so_map * |
static struct so_map * |
map_object(name, sodp, smp) |
map_object(sodp, smp) |
char *name; |
|
struct sod *sodp; |
struct sod *sodp; |
struct so_map *smp; |
struct so_map *smp; |
{ |
{ |
|
char *name; |
struct _dynamic *dp; |
struct _dynamic *dp; |
char *path, *ipath; |
char *path, *ipath; |
int fd; |
int fd; |
Line 538 map_object(name, sodp, smp) |
|
Line 537 map_object(name, sodp, smp) |
|
int usehints = 0; |
int usehints = 0; |
struct so_map *p; |
struct so_map *p; |
|
|
|
name = (char *)sodp->sod_name; |
|
if (smp) |
|
name += (long)LM_LDBASE(smp); |
|
|
if (sodp->sod_library) { |
if (sodp->sod_library) { |
usehints = 1; |
usehints = 1; |
again: |
again: |
|
|
LD_PATHS(smp->som_dynamic) == 0) { |
LD_PATHS(smp->som_dynamic) == 0) { |
ipath = NULL; |
ipath = NULL; |
} else { |
} else { |
ipath = LM_PATHS(smp); |
ipath = LM_PATHS(smp); |
add_search_path(ipath); |
add_search_path(ipath); |
} |
} |
|
|
Line 1083 static long hsize; |
|
Line 1086 static long hsize; |
|
static struct hints_header *hheader; |
static struct hints_header *hheader; |
static struct hints_bucket *hbuckets; |
static struct hints_bucket *hbuckets; |
static char *hstrtab; |
static char *hstrtab; |
|
static char *hint_search_path = ""; |
|
|
#define HINTS_VALID (hheader != NULL && hheader != (struct hints_header *)-1) |
#define HINTS_VALID (hheader != NULL && hheader != (struct hints_header *)-1) |
|
|
|
|
return; |
return; |
} |
} |
|
|
if (hheader->hh_version != LD_HINTS_VERSION_1) { |
if (hheader->hh_version != LD_HINTS_VERSION_1 && |
|
hheader->hh_version != LD_HINTS_VERSION_2) { |
munmap(addr, hsize); |
munmap(addr, hsize); |
close(hfd); |
close(hfd); |
hheader = (struct hints_header *)-1; |
hheader = (struct hints_header *)-1; |
|
|
|
|
hbuckets = (struct hints_bucket *)(addr + hheader->hh_hashtab); |
hbuckets = (struct hints_bucket *)(addr + hheader->hh_hashtab); |
hstrtab = (char *)(addr + hheader->hh_strtab); |
hstrtab = (char *)(addr + hheader->hh_strtab); |
|
if (hheader->hh_version >= LD_HINTS_VERSION_2) |
|
hint_search_path = hstrtab + hheader->hh_dirlist; |
} |
} |
|
|
static void |
static void |
Line 1158 hinthash(cp, vmajor, vminor) |
|
Line 1165 hinthash(cp, vmajor, vminor) |
|
k = (((k << 1) + (k >> 14)) ^ (*cp++)) & 0x3fff; |
k = (((k << 1) + (k >> 14)) ^ (*cp++)) & 0x3fff; |
|
|
k = (((k << 1) + (k >> 14)) ^ (vmajor*257)) & 0x3fff; |
k = (((k << 1) + (k >> 14)) ^ (vmajor*257)) & 0x3fff; |
k = (((k << 1) + (k >> 14)) ^ (vminor*167)) & 0x3fff; |
if (hheader->hh_version == LD_HINTS_VERSION_1) |
|
k = (((k << 1) + (k >> 14)) ^ (vminor*167)) & 0x3fff; |
|
|
return k; |
return k; |
} |
} |
Line 1190 findhint(name, major, minor, prefered_pa |
|
Line 1198 findhint(name, major, minor, prefered_pa |
|
if (strcmp(name, hstrtab + bp->hi_namex) == 0) { |
if (strcmp(name, hstrtab + bp->hi_namex) == 0) { |
/* It's `name', check version numbers */ |
/* It's `name', check version numbers */ |
if (bp->hi_major == major && |
if (bp->hi_major == major && |
(bp->hi_ndewey < 2 || bp->hi_minor == minor)) { |
(bp->hi_ndewey < 2 || bp->hi_minor >= minor)) { |
if (prefered_path == NULL || |
if (prefered_path == NULL || |
strncmp(prefered_path, |
strncmp(prefered_path, |
hstrtab + bp->hi_pathx, |
hstrtab + bp->hi_pathx, |
|
|
/* No hints available for name */ |
/* No hints available for name */ |
*usehints = 0; |
*usehints = 0; |
realminor = -1; |
realminor = -1; |
|
add_search_path(hint_search_path); |
cp = (char *)findshlib(name, &major, &realminor, 0); |
cp = (char *)findshlib(name, &major, &realminor, 0); |
|
remove_search_path(hint_search_path); |
if (cp) { |
if (cp) { |
if (realminor < minor && !ld_suppress_warnings) |
if (realminor < minor && !ld_suppress_warnings) |
warnx("warning: lib%s.so.%d.%d: " |
warnx("warning: lib%s.so.%d.%d: " |
|
|
sodp->sod_library = 0; |
sodp->sod_library = 0; |
sodp->sod_major = sodp->sod_minor = 0; |
sodp->sod_major = sodp->sod_minor = 0; |
|
|
if ((nsmp = map_object(cp, sodp, 0)) == NULL) { |
if ((nsmp = map_object(sodp, 0)) == NULL) { |
errx(1, "preload: %s: cannot map object", cp); |
errx(1, "preload: %s: cannot map object", cp); |
} |
} |
LM_PRIVATE(nsmp)->spd_refcount++; |
LM_PRIVATE(nsmp)->spd_refcount++; |
Line 1331 static struct so_map dlmap = { |
|
Line 1341 static struct so_map dlmap = { |
|
}; |
}; |
static int dlerrno; |
static int dlerrno; |
|
|
|
/* |
|
* Populate sod struct for dlopen's call to map_obj |
|
*/ |
|
void |
|
build_sod(name, sodp) |
|
char *name; |
|
struct sod *sodp; |
|
{ |
|
unsigned int tuplet; |
|
int major, minor; |
|
char *realname, *tok, *etok, *cp; |
|
|
|
/* default is an absolute or relative path */ |
|
sodp->sod_name = (long)strdup(name); /* strtok is destructive */ |
|
sodp->sod_library = 0; |
|
sodp->sod_major = sodp->sod_minor = 0; |
|
|
|
/* asking for lookup? */ |
|
if (strncmp((char *)sodp->sod_name, "lib", 3) != 0) |
|
return; |
|
|
|
/* skip over 'lib' */ |
|
cp = (char *)sodp->sod_name + 3; |
|
|
|
/* dot guardian */ |
|
if ((strchr(cp, '.') == NULL) || (*(cp+strlen(cp)-1) == '.')) |
|
return; |
|
|
|
/* default */ |
|
major = minor = -1; |
|
|
|
/* loop through name - parse skipping name */ |
|
for (tuplet = 0; (tok = strsep(&cp, ".")) != NULL; tuplet++) { |
|
switch (tuplet) { |
|
case 0: |
|
/* removed 'lib' and extensions from name */ |
|
realname = tok; |
|
break; |
|
case 1: |
|
/* 'so' extension */ |
|
if (strcmp(tok, "so") != 0) |
|
goto backout; |
|
break; |
|
case 2: |
|
/* major version extension */ |
|
major = strtol(tok, &etok, 10); |
|
if (*tok == '\0' || *etok != '\0') |
|
goto backout; |
|
break; |
|
case 3: |
|
/* minor version extension */ |
|
minor = strtol(tok, &etok, 10); |
|
if (*tok == '\0' || *etok != '\0') |
|
goto backout; |
|
break; |
|
/* if we get here, it must be weird */ |
|
default: |
|
goto backout; |
|
} |
|
} |
|
cp = (char *)sodp->sod_name; |
|
sodp->sod_name = (long)strdup(realname); |
|
free(cp); |
|
sodp->sod_library = 1; |
|
sodp->sod_major = major; |
|
sodp->sod_minor = minor; |
|
return; |
|
|
|
backout: |
|
free((char *)sodp->sod_name); |
|
sodp->sod_name = (long)strdup(name); |
|
} |
|
|
static void * |
static void * |
__dlopen(name, mode) |
__dlopen(name, mode) |
char *name; |
char *name; |
Line 1352 __dlopen(name, mode) |
|
Line 1435 __dlopen(name, mode) |
|
return NULL; |
return NULL; |
} |
} |
|
|
sodp->sod_name = (long)strdup(name); |
build_sod(name, sodp); |
sodp->sod_library = 0; |
|
sodp->sod_major = sodp->sod_minor = 0; |
|
|
|
if ((smp = map_object(name, sodp, 0)) == NULL) { |
if ((smp = map_object(sodp, 0)) == NULL) { |
#ifdef DEBUG |
#ifdef DEBUG |
xprintf("%s: %s\n", name, strerror(errno)); |
xprintf("%s: %s\n", name, strerror(errno)); |
#endif |
#endif |