about summary refs log tree commit diff
path: root/elf
diff options
context:
space:
mode:
Diffstat (limited to 'elf')
-rw-r--r--elf/dl-load.c3
-rw-r--r--elf/dl-support.c1
-rw-r--r--elf/rtld.c18
3 files changed, 21 insertions, 1 deletions
diff --git a/elf/dl-load.c b/elf/dl-load.c
index ecf2ee87eb..c7e3716cb6 100644
--- a/elf/dl-load.c
+++ b/elf/dl-load.c
@@ -1096,7 +1096,8 @@ cannot allocate TLS data structures for initial thread");
 	   prefer to map such objects at; but this is only a preference,
 	   the OS can do whatever it likes. */
 	ElfW(Addr) mappref;
-	mappref = (ELF_PREFERRED_ADDRESS (loader, maplength, c->mapstart)
+	mappref = (ELF_PREFERRED_ADDRESS (loader, maplength,
+					  c->mapstart & GL(dl_use_load_bias))
 		   - MAP_BASE_ADDR (l));
 
 	/* Remember which part of the address space this object uses.  */
diff --git a/elf/dl-support.c b/elf/dl-support.c
index 448f4c6848..f13fd058a3 100644
--- a/elf/dl-support.c
+++ b/elf/dl-support.c
@@ -41,6 +41,7 @@ size_t _dl_platformlen;
 
 int _dl_debug_mask;
 int _dl_lazy;
+ElfW(Addr) _dl_use_load_bias = -2;
 int _dl_dynamic_weak;
 
 /* If nonzero print warnings about problematic situations.  */
diff --git a/elf/rtld.c b/elf/rtld.c
index e92149a667..82f7ed3fc2 100644
--- a/elf/rtld.c
+++ b/elf/rtld.c
@@ -95,6 +95,7 @@ struct rtld_global _rtld_global =
     ._dl_sysinfo = DL_SYSINFO_DEFAULT,
 #endif
     ._dl_lazy = 1,
+    ._dl_use_load_bias = -2,
     ._dl_fpu_control = _FPU_DEFAULT,
     ._dl_correct_cache_id = _DL_CACHE_DEFAULT_ID,
     ._dl_hwcap_mask = HWCAP_IMPORTANT,
@@ -996,6 +997,12 @@ of this helper program; chances are you did not intend to run this program.\n\
   GL(dl_rtld_map).l_prev = GL(dl_loaded);
   ++GL(dl_nloaded);
 
+  /* If LD_USE_LOAD_BIAS env variable has not been seen, default
+     to not using bias for non-prelinked PIEs and libraries
+     and using it for executables or prelinked PIEs or libraries.  */
+  if (GL(dl_use_load_bias) == (ElfW(Addr)) -2)
+    GL(dl_use_load_bias) = (GL(dl_loaded)->l_addr == 0) ? -1 : 0;
+
   /* Set up the program header information for the dynamic linker
      itself.  It is needed in the dl_iterate_phdr() callbacks.  */
   ElfW(Ehdr) *rtld_ehdr = (ElfW(Ehdr) *) GL(dl_rtld_map).l_map_start;
@@ -1992,6 +1999,17 @@ process_envvars (enum mode *modep)
 	    GL(dl_dynamic_weak) = 1;
 	  break;
 
+	case 13:
+	  /* We might have some extra environment variable with length 13
+	     to handle.  */
+#ifdef EXTRA_LD_ENVVARS_13
+	  EXTRA_LD_ENVVARS_13
+#endif
+	  if (!INTUSE(__libc_enable_secure)
+	      && memcmp (envline, "USE_LOAD_BIAS", 13) == 0)
+	    GL(dl_use_load_bias) = envline[14] == '1' ? -1 : 0;
+	  break;
+
 	case 14:
 	  /* Where to place the profiling data file.  */
 	  if (!INTUSE(__libc_enable_secure)