about summary refs log tree commit diff
diff options
context:
space:
mode:
authorRich Felker <dalias@aerifal.cx>2013-01-23 22:07:45 -0500
committerRich Felker <dalias@aerifal.cx>2013-01-23 22:07:45 -0500
commit4d07e5521ea811278f00f434fe2b8345ea1d8832 (patch)
tree58f357a961a50b9ee2d19372bcaaca564ccb686b
parent637dd2d383cc1f63bf02a732f03786857b22c7bd (diff)
downloadmusl-4d07e5521ea811278f00f434fe2b8345ea1d8832.tar.gz
musl-4d07e5521ea811278f00f434fe2b8345ea1d8832.tar.xz
musl-4d07e5521ea811278f00f434fe2b8345ea1d8832.zip
add support for RTLD_NOLOAD to dlopen
based on patch by Pierre Carrier <pierre@gcarrier.fr> that just added
the flag constant, but with minimal additional code so that it
actually works as documented. this is a nonstandard option but some
major software (reportedly, Firefox) uses it and it was easy to add
anyway.
-rw-r--r--include/dlfcn.h1
-rw-r--r--src/ldso/dynlink.c10
2 files changed, 8 insertions, 3 deletions
diff --git a/include/dlfcn.h b/include/dlfcn.h
index 46c4e185..5b57e8ac 100644
--- a/include/dlfcn.h
+++ b/include/dlfcn.h
@@ -9,6 +9,7 @@ extern "C" {
 
 #define RTLD_LAZY   1
 #define RTLD_NOW    2
+#define RTLD_NOLOAD 4
 #define RTLD_GLOBAL 256
 #define RTLD_LOCAL  0
 
diff --git a/src/ldso/dynlink.c b/src/ldso/dynlink.c
index e73806cd..b1a4409d 100644
--- a/src/ldso/dynlink.c
+++ b/src/ldso/dynlink.c
@@ -99,6 +99,7 @@ static int ssp_used;
 static int runtime;
 static int ldd_mode;
 static int ldso_fail;
+static int noload;
 static jmp_buf rtld_fail;
 static pthread_rwlock_t lock;
 static struct debug debug;
@@ -508,7 +509,7 @@ static struct dso *load_library(const char *name)
 			return p;
 		}
 	}
-	map = map_library(fd, &temp_dso);
+	map = noload ? 0 : map_library(fd, &temp_dso);
 	close(fd);
 	if (!map) return 0;
 
@@ -1027,6 +1028,7 @@ void *dlopen(const char *file, int mode)
 	orig_tls_offset = tls_offset;
 	orig_tls_align = tls_align;
 	orig_tail = tail;
+	noload = mode & RTLD_NOLOAD;
 
 	if (setjmp(rtld_fail)) {
 		/* Clean up anything new that was (partially) loaded */
@@ -1050,8 +1052,10 @@ void *dlopen(const char *file, int mode)
 	} else p = load_library(file);
 
 	if (!p) {
-		snprintf(errbuf, sizeof errbuf,
-			"Error loading shared library %s: %m", file);
+		snprintf(errbuf, sizeof errbuf, noload ?
+			"Library %s is not already loaded" :
+			"Error loading shared library %s: %m",
+			file);
 		errflag = 1;
 		goto end;
 	}