diff options
Diffstat (limited to 'libexec/rtld-aout')
-rw-r--r-- | libexec/rtld-aout/rtld.1 | 24 | ||||
-rw-r--r-- | libexec/rtld-aout/rtld.1aout | 24 | ||||
-rw-r--r-- | libexec/rtld-aout/rtld.c | 53 |
3 files changed, 71 insertions, 30 deletions
diff --git a/libexec/rtld-aout/rtld.1 b/libexec/rtld-aout/rtld.1 index 699738c..2f0cb5a 100644 --- a/libexec/rtld-aout/rtld.1 +++ b/libexec/rtld-aout/rtld.1 @@ -1,4 +1,4 @@ -.\" $Id: rtld.1,v 1.6 1996/10/18 04:49:43 jdp Exp $ +.\" $Id: rtld.1,v 1.7 1996/12/26 21:51:09 swallace Exp $ .\" .\" Copyright (c) 1995 Paul Kranenburg .\" All rights reserved. @@ -117,15 +117,25 @@ other shared libraries. If the directory is not specified then the directories specified by LD_LIBRARY_PATH will be searched first followed by the set of built-in standard directories. This is ignored for set-user-ID and set-group-ID programs. +.It Ev LD_BIND_NOW +When set to a nonempty string, causes +.Nm +to relocate all external function calls before starting execution of the +program. Normally, function calls are bound lazily, at the first call +of each function. +.Ev LD_BIND_NOW +increases the start-up time of a program, but it avoids run-time +surprises caused by unexpectedly undefined functions. .It Ev LD_WARN_NON_PURE_CODE -When set, issue a warning whenever a link-editing operation requires -modification of the text segment of some loaded object. This is usually -indicative of an incorrectly built library. +When set to a nonempty string, issue a warning whenever a link-editing +operation requires modification of the text segment of some loaded +object. This is usually indicative of an incorrectly built library. .It Ev LD_SUPPRESS_WARNINGS -When set, no warning messages of any kind are issued. Normally, a warning -is given if satisfactorily versioned library could not be found. +When set to a nonempty string, no warning messages of any kind are +issued. Normally, a warning is given if satisfactorily versioned +library could not be found. .It Ev LD_TRACE_LOADED_OBJECTS -When set, causes +When set to a nonempty string, causes .Nm to exit after loading the shared objects and printing a summary which includes the absolute pathnames of all objects, to standard output. diff --git a/libexec/rtld-aout/rtld.1aout b/libexec/rtld-aout/rtld.1aout index 699738c..2f0cb5a 100644 --- a/libexec/rtld-aout/rtld.1aout +++ b/libexec/rtld-aout/rtld.1aout @@ -1,4 +1,4 @@ -.\" $Id: rtld.1,v 1.6 1996/10/18 04:49:43 jdp Exp $ +.\" $Id: rtld.1,v 1.7 1996/12/26 21:51:09 swallace Exp $ .\" .\" Copyright (c) 1995 Paul Kranenburg .\" All rights reserved. @@ -117,15 +117,25 @@ other shared libraries. If the directory is not specified then the directories specified by LD_LIBRARY_PATH will be searched first followed by the set of built-in standard directories. This is ignored for set-user-ID and set-group-ID programs. +.It Ev LD_BIND_NOW +When set to a nonempty string, causes +.Nm +to relocate all external function calls before starting execution of the +program. Normally, function calls are bound lazily, at the first call +of each function. +.Ev LD_BIND_NOW +increases the start-up time of a program, but it avoids run-time +surprises caused by unexpectedly undefined functions. .It Ev LD_WARN_NON_PURE_CODE -When set, issue a warning whenever a link-editing operation requires -modification of the text segment of some loaded object. This is usually -indicative of an incorrectly built library. +When set to a nonempty string, issue a warning whenever a link-editing +operation requires modification of the text segment of some loaded +object. This is usually indicative of an incorrectly built library. .It Ev LD_SUPPRESS_WARNINGS -When set, no warning messages of any kind are issued. Normally, a warning -is given if satisfactorily versioned library could not be found. +When set to a nonempty string, no warning messages of any kind are +issued. Normally, a warning is given if satisfactorily versioned +library could not be found. .It Ev LD_TRACE_LOADED_OBJECTS -When set, causes +When set to a nonempty string, causes .Nm to exit after loading the shared objects and printing a summary which includes the absolute pathnames of all objects, to standard output. diff --git a/libexec/rtld-aout/rtld.c b/libexec/rtld-aout/rtld.c index 9353721..88e5b27 100644 --- a/libexec/rtld-aout/rtld.c +++ b/libexec/rtld-aout/rtld.c @@ -27,7 +27,7 @@ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * - * $Id: rtld.c,v 1.39 1996/10/10 23:16:50 jdp Exp $ + * $Id: rtld.c,v 1.40 1996/10/24 16:24:19 jdp Exp $ */ #include <sys/param.h> @@ -186,6 +186,7 @@ static gid_t gid, egid; static int careful; static int anon_fd = -1; +static char *ld_bind_now; static char *ld_library_path; static char *ld_preload; static char *ld_tracing; @@ -212,7 +213,7 @@ static struct so_map *map_object __P(( char *, struct so_map *)); static int map_preload __P((void)); static int map_sods __P((struct so_map *)); -static int reloc_and_init __P((struct so_map *)); +static int reloc_and_init __P((struct so_map *, int)); static void unmap_object __P((struct so_map *, int)); static struct so_map *alloc_link_map __P(( char *, struct sod *, struct so_map *, caddr_t, @@ -221,7 +222,7 @@ static void free_link_map __P((struct so_map *)); static inline int check_text_reloc __P(( struct relocation_info *, struct so_map *, caddr_t)); -static int reloc_map __P((struct so_map *)); +static int reloc_map __P((struct so_map *, int)); static void reloc_copy __P((struct so_map *)); static void init_object __P((struct so_map *)); static void init_sods __P((struct so_list *)); @@ -305,6 +306,10 @@ struct _dynamic *dp; if (version >= CRT_VERSION_BSD_3) main_progname = crtp->crt_prog; + /* Some buggy versions of crt0.o have crt_ldso filled in as NULL. */ + if (__progname == NULL) + __progname = us; + /* Fill in some fields in _DYNAMIC or crt structure */ if (version >= CRT_VERSION_BSD_4) crtp->crt_ldentry = &ld_entry; /* crt */ @@ -356,7 +361,7 @@ struct _dynamic *dp; /* Map in LD_PRELOADs before the main program's shared objects so we can intercept those calls */ - if (ld_preload != NULL && *ld_preload != '\0') { + if (ld_preload != NULL) { if(map_preload() == -1) /* Failed */ die(); } @@ -373,7 +378,7 @@ struct _dynamic *dp; crtp->crt_dp->d_un.d_sdt->sdt_loaded = link_map_head->som_next; /* Relocate and initialize all mapped objects */ - if(reloc_and_init(main_map) == -1) /* Failed */ + if(reloc_and_init(main_map, ld_bind_now != NULL) == -1) /* Failed */ die(); ddp = crtp->crt_dp->d_debug; @@ -903,8 +908,9 @@ map_sods(parent) * an error message can be retrieved via dlerror(). */ static int -reloc_and_init(root) +reloc_and_init(root, bind_now) struct so_map *root; + int bind_now; { struct so_map *smp; @@ -925,7 +931,7 @@ reloc_and_init(root) */ for(smp = root; smp != NULL; smp = smp->som_next) { if(!(LM_PRIVATE(smp)->spd_flags & RTLD_RTLD)) { - if(reloc_map(smp) < 0) + if(reloc_map(smp, bind_now) < 0) return -1; } } @@ -1066,8 +1072,9 @@ caddr_t addr; } static int -reloc_map(smp) +reloc_map(smp, bind_now) struct so_map *smp; + int bind_now; { /* * Caching structure for reducing the number of calls to @@ -1140,7 +1147,7 @@ reloc_map(smp) struct nzlist *p, *np; long relocation; - if (RELOC_LAZY_P(r)) + if (RELOC_JMPTAB_P(r) && !bind_now) continue; p = (struct nzlist *) @@ -1159,7 +1166,7 @@ reloc_map(smp) if(np != NULL) /* Symbol already cached */ src_map = symcache[RELOC_SYMBOL(r)].src_map; else { /* Symbol not cached yet */ - np = lookup(sym, &src_map, 0/*XXX-jumpslots!*/); + np = lookup(sym, &src_map, RELOC_JMPTAB_P(r)); /* * Record the needed information about * the symbol in the caching vector, @@ -1184,11 +1191,17 @@ reloc_map(smp) * Otherwise it's a run-time allocated common * whose value is already up-to-date. */ - relocation = md_get_addend(r, addr); - relocation += np->nz_value; + relocation = np->nz_value; if (src_map) relocation += (long)src_map->som_addr; + if (RELOC_JMPTAB_P(r)) { + md_bind_jmpslot(relocation, addr); + continue; + } + + relocation += md_get_addend(r, addr); + if (RELOC_PCREL_P(r)) relocation -= (long)smp->som_addr; @@ -1200,8 +1213,8 @@ reloc_map(smp) np->nz_size, src_map); continue; } - md_relocate(r, relocation, addr, 0); + md_relocate(r, relocation, addr, 0); } else { md_relocate(r, #ifdef SUN_COMPAT @@ -1817,6 +1830,9 @@ __dlopen(path, mode) { struct so_map *old_tail = link_map_tail; struct so_map *smp; + int bind_now = mode == 2; + /* XXX - s/2/RTLD_NOW/ in the above line, after putting the necessary + defines into <dlfcn.h> and testing for problems. */ /* * path == NULL is handled by map_object() @@ -1832,7 +1848,7 @@ __dlopen(path, mode) /* Relocate and initialize all newly-mapped objects */ if(link_map_tail != old_tail) { /* We have mapped some new objects */ - if(reloc_and_init(smp) == -1) /* Failed */ + if(reloc_and_init(smp, bind_now) == -1) /* Failed */ return NULL; } @@ -1989,6 +2005,9 @@ char *fmt; * except that the environment is scanned once only to pick up all * known variables, rather than scanned multiple times for each * variable. + * + * If an environment variable of interest is set to the empty string, we + * treat it as if it were unset. */ #define L(n, u, v) { n, sizeof(n) - 1, u, v }, @@ -2001,13 +2020,14 @@ struct env_scan_tab { L("LD_LIBRARY_PATH=", 1, &ld_library_path) L("LD_PRELOAD=", 1, &ld_preload) L("LD_TRACE_LOADED_OBJECTS=", 0, &ld_tracing) + L("LD_BIND_NOW=", 0, &ld_bind_now) L("LD_SUPPRESS_WARNINGS=", 0, &ld_suppress_warnings) L("LD_WARN_NON_PURE_CODE=", 0, &ld_warn_non_pure_code) { NULL, 0, NULL } }; #undef L -void +static void rt_readenv() { char **p = environ; @@ -2025,7 +2045,8 @@ rt_readenv() if (careful && t->unsafe) continue; /* skip for set[ug]id */ if (strncmp(t->name, v, t->len) == 0) { - *t->value = v + t->len; + if (*(v + t->len) != '\0') /* Not empty */ + *t->value = v + t->len; break; } } |