Skip site navigation (1)Skip section navigation (2)
Date:      Sun, 16 Jun 2002 13:42:05 -0700 (PDT)
From:      Matthew Dillon <dillon@apollo.backplane.com>
To:        freebsd-current@freebsd.org, freebsd-hackers@freebsd.org
Cc:        jdp@polstra.com, obrien@freebsd.org
Subject:   rtld-elf patches for non-i386 architectures (review / test request)
Message-ID:  <200206162042.g5GKg5JW041655@apollo.backplane.com>

next in thread | raw e-mail | index | archive | help
    These are the rtld-elf patches for -current for non-i386 architectures.
    Since I can't test these I would appreciate it if people could 
    review them, and test if possible on alpha, ia64, sparc64, and alpha.
    The ia64 patch is the most complex.  The rest are essentially the
    same as i386.

    I will email the one remaining patch for -stable (for alpha) to David
    directly.

						Thanks,

						-Matt

Index: rtld-elf/alpha/reloc.c
===================================================================
RCS file: /home/ncvs/src/libexec/rtld-elf/alpha/reloc.c,v
retrieving revision 1.15
diff -u -r1.15 reloc.c
--- rtld-elf/alpha/reloc.c	18 Feb 2002 02:24:10 -0000	1.15
+++ rtld-elf/alpha/reloc.c	16 Jun 2002 20:24:52 -0000
@@ -152,10 +152,18 @@
 	const Elf_Rela *relalim;
 	const Elf_Rela *rela;
 	SymCache *cache;
+	int bytes = obj->nchains * sizeof(SymCache);
+	int r = -1;
 
-	cache = (SymCache *)alloca(obj->nchains * sizeof(SymCache));
+	/*
+	 * The dynamic loader may be called from a thread, we have
+	 * limited amounts of stack available so we cannot use alloca().
+	 */
+	cache = mmap(NULL, bytes, PROT_READ|PROT_WRITE, MAP_ANON, -1, 0);
+	if (cache == MAP_FAILED)
+	    cache = NULL;
 	if (cache != NULL)
-	    memset(cache, 0, obj->nchains * sizeof(SymCache));
+	    memset(cache, 0, bytes);
 
 	/* Perform relocations without addend if there are any: */
 	rellim = (const Elf_Rel *) ((caddr_t) obj->rel + obj->relsize);
@@ -166,16 +174,20 @@
 		locrela.r_offset = rel->r_offset;
 		locrela.r_addend = 0;
 		if (reloc_non_plt_obj(obj_rtld, obj, &locrela, cache))
-			return -1;
+			goto done;
 	}
 
 	/* Perform relocations with addend if there are any: */
 	relalim = (const Elf_Rela *) ((caddr_t) obj->rela + obj->relasize);
 	for (rela = obj->rela;  obj->rela != NULL && rela < relalim;  rela++) {
 		if (reloc_non_plt_obj(obj_rtld, obj, rela, cache))
-			return -1;
+			goto done;
 	}
-    return 0;
+	r = 0;
+done:
+	if (cache)
+	    munmap(cache, bytes);
+	return(r);
 }
 
 /* Process the PLT relocations. */
Index: rtld-elf/ia64/reloc.c
===================================================================
RCS file: /home/ncvs/src/libexec/rtld-elf/ia64/reloc.c,v
retrieving revision 1.6
diff -u -r1.6 reloc.c
--- rtld-elf/ia64/reloc.c	21 May 2002 00:04:08 -0000	1.6
+++ rtld-elf/ia64/reloc.c	16 Jun 2002 20:35:05 -0000
@@ -190,24 +190,35 @@
 	const Elf_Rela *rela;
 	SymCache *cache;
 	struct fptr **fptrs;
+	int bytes = obj->nchains * sizeof(SymCache);
+	int fbytes = obj->nchains * sizeof(struct fptr *);
+	int r = -1;
 
-	cache = (SymCache *)alloca(obj->nchains * sizeof(SymCache));
+	/*
+	 * The dynamic loader may be called from a thread, we have
+	 * limited amounts of stack available so we cannot use alloca().
+	 */
+	cache = mmap(NULL, bytes, PROT_READ|PROT_WRITE, MAP_ANON, -1, 0);
+	if (cache == MAP_FAILED)
+		cache = NULL;
 	if (cache != NULL)
-		memset(cache, 0, obj->nchains * sizeof(SymCache));
+		memset(cache, 0, bytes);
 
 	/*
 	 * When relocating rtld itself, we need to avoid using malloc.
 	 */
-        if (obj == obj_rtld)
-		fptrs = (struct fptr **)
-			alloca(obj->nchains * sizeof(struct fptr *));
-	else
+        if (obj == obj_rtld) {
+		fptrs = mmap(NULL, fbytes, PROT_READ|PROT_WRITE, 
+			    MAP_ANON, -1, 0);
+		if (fptrs == MAP_FAILED)
+			fptrs = NULL;
+	} else {
 		fptrs = (struct fptr **)
 			malloc(obj->nchains * sizeof(struct fptr *));
-
+	}
 	if (fptrs == NULL)
-		return -1;
-	memset(fptrs, 0, obj->nchains * sizeof(struct fptr *));
+		goto done;
+	memset(fptrs, 0, fbytes);
 
 	/* Perform relocations without addend if there are any: */
 	rellim = (const Elf_Rel *) ((caddr_t) obj->rel + obj->relsize);
@@ -218,28 +229,43 @@
 		locrela.r_offset = rel->r_offset;
 		locrela.r_addend = 0;
 		if (reloc_non_plt_obj(obj_rtld, obj, &locrela, cache, fptrs))
-			return -1;
+			goto done;
 	}
 
 	/* Perform relocations with addend if there are any: */
 	relalim = (const Elf_Rela *) ((caddr_t) obj->rela + obj->relasize);
 	for (rela = obj->rela;  obj->rela != NULL && rela < relalim;  rela++) {
 		if (reloc_non_plt_obj(obj_rtld, obj, rela, cache, fptrs))
-			return -1;
+			goto done;
 	}
 
 	/*
 	 * Remember the fptrs in case of later calls to dlsym(). Don't 
 	 * bother for rtld - we will lazily create a table in
-	 * make_function_pointer(). At this point we still can't risk
-	 * calling malloc().
+	 * make_function_pointer().  We still can't risk calling malloc()
+	 * in the rtld case.
+	 *
+	 * When remembering fptrs, NULL out our local fptrs variable so we
+	 * do not free it.
 	 */
-	if (obj != obj_rtld)
-		obj->priv = fptrs;
-	else
+	if (obj == obj_rtld) {
 		obj->priv = NULL;
+	} else {
+		obj->priv = fptrs;
+		fptrs = NULL;
+	}
 
-	return 0;
+	r = 0;
+done:
+	if (cache)
+		munmap(cache, bytes);
+	if (fptrs) {
+		if (obj == obj_rtld)
+			munmap(fptrs, fbytes);
+		else
+			free(fptrs);
+	}
+	return (r);
 }
 
 /* Process the PLT relocations. */
Index: rtld-elf/sparc64/reloc.c
===================================================================
RCS file: /home/ncvs/src/libexec/rtld-elf/sparc64/reloc.c,v
retrieving revision 1.1
diff -u -r1.1 reloc.c
--- rtld-elf/sparc64/reloc.c	13 Mar 2002 02:40:39 -0000	1.1
+++ rtld-elf/sparc64/reloc.c	16 Jun 2002 20:27:15 -0000
@@ -249,18 +249,29 @@
 	const Elf_Rela *relalim;
 	const Elf_Rela *rela;
 	SymCache *cache;
+	int bytes = obj->nchains * sizeof(SymCache);
+	int r = -1;
 
-	cache = (SymCache *)alloca(obj->nchains * sizeof(SymCache));
+	/*
+	 * The dynamic loader may be called from a thread, we have
+	 * limited amounts of stack available so we cannot use alloca().
+	 */
+	cache = mmap(NULL, bytes, PROT_READ|PROT_WRITE, MAP_ANON, -1, 0);
+	if (cache == MAP_FAILED)
+		cache = NULL;
 	if (cache != NULL)
 		memset(cache, 0, obj->nchains * sizeof(SymCache));
 
 	relalim = (const Elf_Rela *)((caddr_t)obj->rela + obj->relasize);
 	for (rela = obj->rela; rela < relalim; rela++) {
 		if (reloc_nonplt_object(obj, rela, cache) < 0)
-			return (-1);
+			goto done;
 	}
-
-	return (0);
+	r = 0;
+done:
+	if (cache)
+		munmap(cache, bytes);
+	return (r);
 }
 
 static int

To Unsubscribe: send mail to majordomo@FreeBSD.org
with "unsubscribe freebsd-current" in the body of the message




Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200206162042.g5GKg5JW041655>