summaryrefslogtreecommitdiffstats
path: root/libexec/rtld-aout/rtld.c
diff options
context:
space:
mode:
authornate <nate@FreeBSD.org>1995-03-04 17:49:20 +0000
committernate <nate@FreeBSD.org>1995-03-04 17:49:20 +0000
commitb9aa930e449daf128eaaacfe2814dbb378708094 (patch)
treeb4f43ec68fa745cd1357a92fb82d40f827150f50 /libexec/rtld-aout/rtld.c
parent44a74d9438343e917536adbb0ef1d2da66f7f761 (diff)
downloadFreeBSD-src-b9aa930e449daf128eaaacfe2814dbb378708094.zip
FreeBSD-src-b9aa930e449daf128eaaacfe2814dbb378708094.tar.gz
Weak symbol support from NetBSD. This should bring us in sync with the
NetBSD ld code except for local changes for dlopen() and friends and the hashing on the minor value of the shlibs. We should be binary compatible now with all their libraries. Obtained from: NetBSD
Diffstat (limited to 'libexec/rtld-aout/rtld.c')
-rw-r--r--libexec/rtld-aout/rtld.c110
1 files changed, 56 insertions, 54 deletions
diff --git a/libexec/rtld-aout/rtld.c b/libexec/rtld-aout/rtld.c
index 6332911..c2e6021 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.20 1995/01/12 19:12:29 joerg Exp $
+ * $Id: rtld.c,v 1.21 1995/02/07 13:33:42 jkh Exp $
*/
#include <sys/param.h>
@@ -38,9 +38,8 @@
#include <sys/resource.h>
#include <sys/errno.h>
#include <sys/mman.h>
-#ifndef BSD
+#ifndef MAP_COPY
#define MAP_COPY MAP_PRIVATE
-#define MAP_ANON 0
#endif
#include <err.h>
#include <fcntl.h>
@@ -58,8 +57,19 @@
#include "ld.h"
-#ifndef BSD /* Need do better than this */
-#define NEED_DEV_ZERO 1
+#ifndef MAP_ANON
+#define MAP_ANON 0
+#define anon_open() do { \
+ if ((anon_fd = open("/dev/zero", O_RDWR, 0)) == -1) \
+ err("open: %s", "/dev/zero"); \
+} while (0)
+#define anon_close() do { \
+ (void)close(anon_fd); \
+ anon_fd = -1; \
+} while (0)
+#else
+#define anon_open()
+#define anon_close()
#endif
/*
@@ -135,6 +145,7 @@ static int careful;
static char __main_progname[] = "main";
static char *main_progname = __main_progname;
static char us[] = "/usr/libexec/ld.so";
+static int anon_fd = -1;
struct so_map *link_map_head, *main_map;
struct so_map **link_map_tail = &link_map_head;
@@ -166,14 +177,15 @@ static void init_map __P((struct so_map *, char *));
static char *rtfindlib __P((char *, int, int, int *));
void binder_entry __P((void));
long binder __P((jmpslot_t *));
-static void maphints __P((void));
-static void unmaphints __P((void));
static struct nzlist *lookup __P((char *, struct so_map **, int));
static inline struct rt_symbol *lookup_rts __P((char *));
static struct rt_symbol *enter_rts __P((char *, long, int, caddr_t,
long, struct so_map *));
static void generror __P((char *, ...));
+static void maphints __P((void));
+static void unmaphints __P((void));
+
static inline int
strcmp (register const char *s1, register const char *s2)
{
@@ -251,6 +263,7 @@ struct _dynamic *dp;
if (getenv("LD_NOSTD_PATH") == NULL)
std_search_path();
+ anon_open();
/* Load required objects into the process address space */
load_objects(crtp, dp);
@@ -301,11 +314,12 @@ struct _dynamic *dp;
ddp->dd_sym_loaded = 1;
}
- /* Forget hints so that hints file can go away if it is unlinked */
+ /* Close the hints file */
unmaphints();
/* Close our file descriptor */
(void)close(crtp->crt_ldfd);
+ anon_close();
return 0;
}
@@ -511,9 +525,9 @@ again:
return NULL;
}
- if ((addr = mmap(0, hdr.a_text + hdr.a_data,
- PROT_READ|PROT_EXEC,
- MAP_COPY, fd, 0)) == (caddr_t)-1) {
+ if ((addr = mmap(0, hdr.a_text + hdr.a_data + hdr.a_bss,
+ PROT_READ|PROT_EXEC,
+ MAP_COPY, fd, 0)) == (caddr_t)-1) {
generror ("mmap failed for \"%s\" : %s",
path, strerror (errno));
(void)close(fd);
@@ -528,29 +542,17 @@ again:
return NULL;
}
- (void)close(fd);
-
- fd = -1;
-#ifdef NEED_DEV_ZERO
- if ((fd = open("/dev/zero", O_RDWR, 0)) == -1) {
- generror ("open failed for \"/dev/zero\" : %s",
- strerror (errno));
- return NULL;
- }
-#endif
- if (hdr.a_bss && mmap(addr + hdr.a_text + hdr.a_data, hdr.a_bss,
- PROT_READ|PROT_WRITE|PROT_EXEC,
- MAP_ANON|MAP_FIXED|MAP_COPY,
- fd, hdr.a_text + hdr.a_data) == (caddr_t)-1) {
+ if (mmap(addr + hdr.a_text + hdr.a_data, hdr.a_bss,
+ PROT_READ|PROT_WRITE|PROT_EXEC,
+ MAP_ANON|MAP_COPY|MAP_FIXED,
+ anon_fd, 0) == (caddr_t)-1) {
generror ("mmap failed for \"%s\" : %s",
path, strerror (errno));
(void)close(fd);
return NULL;
- }
+ }
-#ifdef NEED_DEV_ZERO
- close(fd);
-#endif
+ (void)close(fd);
/* Assume _DYNAMIC is the first data item */
dp = (struct _dynamic *)(addr+hdr.a_text);
@@ -634,7 +636,7 @@ caddr_t addr;
if (getenv("LD_SUPPRESS_WARNINGS") == NULL &&
getenv("LD_WARN_NON_PURE_CODE") != NULL)
- warnx("ld.so: warning: non pure code in %s at %x (%s)\n",
+ warnx("warning: non pure code in %s at %x (%s)",
smp->som_path, r->r_address, sym);
if (smp->som_write == 0 &&
@@ -884,7 +886,7 @@ lookup(name, src_map, strong)
* Search all maps for a definition of NAME
*/
for (smp = link_map_head; smp; smp = smp->som_next) {
- int buckets = LD_BUCKETS(smp->som_dynamic);
+ int buckets;
long hashval;
struct rrs_hash *hp;
char *cp;
@@ -896,10 +898,13 @@ lookup(name, src_map, strong)
char *stringbase;
int symsize;
- if (LM_PRIVATE(smp)->spd_flags & RTLD_RTLD)
+ if (*src_map && smp != *src_map)
continue;
- if (*src_map && smp != *src_map)
+ if ((buckets = LD_BUCKETS(smp->som_dynamic)) == 0)
+ continue;
+
+ if (LM_PRIVATE(smp)->spd_flags & RTLD_RTLD)
continue;
restart:
@@ -1042,8 +1047,9 @@ binder(jsp)
}
+static int hfd;
+static long hsize;
static struct hints_header *hheader;
-static long hmsize;
static struct hints_bucket *hbuckets;
static char *hstrtab;
@@ -1053,52 +1059,47 @@ static char *hstrtab;
maphints __P((void))
{
caddr_t addr;
- long msize;
- int fd;
- if ((fd = open(_PATH_LD_HINTS, O_RDONLY, 0)) == -1) {
+ if ((hfd = open(_PATH_LD_HINTS, O_RDONLY, 0)) == -1) {
hheader = (struct hints_header *)-1;
return;
}
- msize = PAGSIZ;
- addr = mmap(0, msize, PROT_READ, MAP_COPY, fd, 0);
+ hsize = PAGSIZ;
+ addr = mmap(0, hsize, PROT_READ, MAP_COPY, hfd, 0);
if (addr == (caddr_t)-1) {
- close(fd);
+ close(hfd);
hheader = (struct hints_header *)-1;
return;
}
hheader = (struct hints_header *)addr;
if (HH_BADMAG(*hheader)) {
- munmap(addr, msize);
- close(fd);
+ munmap(addr, hsize);
+ close(hfd);
hheader = (struct hints_header *)-1;
return;
}
if (hheader->hh_version != LD_HINTS_VERSION_1) {
- munmap(addr, msize);
- close(fd);
+ munmap(addr, hsize);
+ close(hfd);
hheader = (struct hints_header *)-1;
return;
}
- hmsize = msize;
- if (hheader->hh_ehints > msize) {
- hmsize = hheader->hh_ehints;
- if (mmap(addr+msize, hheader->hh_ehints - msize,
+ if (hheader->hh_ehints > hsize) {
+ if (mmap(addr+hsize, hheader->hh_ehints - hsize,
PROT_READ, MAP_COPY|MAP_FIXED,
- fd, msize) != (caddr_t)(addr+msize)) {
+ hfd, hsize) != (caddr_t)(addr+hsize)) {
- munmap((caddr_t)hheader, msize);
- close(fd);
+ munmap((caddr_t)hheader, hsize);
+ close(hfd);
hheader = (struct hints_header *)-1;
return;
}
}
- close(fd);
hbuckets = (struct hints_bucket *)(addr + hheader->hh_hashtab);
hstrtab = (char *)(addr + hheader->hh_strtab);
@@ -1107,8 +1108,10 @@ maphints __P((void))
static void
unmaphints()
{
+
if (HINTS_VALID) {
- munmap((caddr_t)hheader, hmsize);
+ munmap((caddr_t)hheader, hsize);
+ close(hfd);
hheader = NULL;
}
}
@@ -1404,4 +1407,3 @@ char *fmt;
(void)write(1, buf, strlen(buf));
va_end(ap);
}
-
OpenPOWER on IntegriCloud