summaryrefslogtreecommitdiff
path: root/ldso/ldso/ldso.c
diff options
context:
space:
mode:
Diffstat (limited to 'ldso/ldso/ldso.c')
-rw-r--r--ldso/ldso/ldso.c46
1 files changed, 36 insertions, 10 deletions
diff --git a/ldso/ldso/ldso.c b/ldso/ldso/ldso.c
index 456205adc..3a479caf5 100644
--- a/ldso/ldso/ldso.c
+++ b/ldso/ldso/ldso.c
@@ -20,11 +20,8 @@
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
-/* Enable this to turn on debugging noise */
-//#define DL_DEBUG
-
-/* Enable mprotect protection munging. ARM Linux needs this it seems,
- * so leave this enabled by default */
+/* Enable mprotect protection munging. ARM and MIPS Linux needs this
+ * it seems, so leave this enabled by default */
#define DO_MPROTECT_HACKS
// Support a list of library preloads in /etc/ld.so.preload
@@ -209,10 +206,16 @@ DL_BOOT(unsigned long args)
Elf32_auxv_t auxvt[AT_EGID + 1];
unsigned char *malloc_buffer, *mmap_zero;
Elf32_Dyn *dpnt;
+ Elf32_Dyn *dpnt_debug = NULL;
unsigned long *hash_addr;
struct r_debug *debug_addr;
int indx;
int status;
+#if defined(__mips__)
+ unsigned long mips_gotsym = 0;
+ unsigned long mips_local_gotno = 0;
+ unsigned long mips_symtabno = 0;
+#endif
/* WARNING! -- we cannot make _any_ funtion calls until we have
@@ -223,7 +226,7 @@ DL_BOOT(unsigned long args)
/* First obtain the information on the stack that tells us more about
what binary is loaded, where it is loaded, etc, etc */
GET_ARGV(aux_dat, args);
-#if defined(__arm__) || defined(__mips__)
+#if defined (__arm__) || defined (__mips__)
aux_dat += 1;
#endif
argc = *(aux_dat - 1);
@@ -267,7 +270,7 @@ DL_BOOT(unsigned long args)
_dl_exit(0);
}
#ifdef DL_DEBUG
- SEND_STDERR("ELF header =");
+ SEND_STDERR("ELF header=");
SEND_ADDRESS_STDERR(load_addr, 1);
#endif
@@ -287,7 +290,7 @@ DL_BOOT(unsigned long args)
#elif defined(__powerpc__)
__asm__("\tbl _GLOBAL_OFFSET_TABLE_-4@local\n\t":"=l"(got));
#elif defined(__mips__)
- __asm__("\tmove %0, $28\n\t":"=r"(got));
+ __asm__("\tmove %0, $28\n\tsubu %0,%0,0x7ff0\n\t":"=r"(got));
#else
/* Do things the slow way in C */
{
@@ -334,7 +337,7 @@ DL_BOOT(unsigned long args)
_dl_exit(0);
found_got:
- got = (unsigned long *) (dynamic->d_un.d_val - tx_reloc +
+ got = (unsigned long *) (dynamic->d_un.d_val - tx_reloc +
(char *) header);
}
#endif
@@ -376,6 +379,14 @@ DL_BOOT(unsigned long args)
tpnt->dynamic_info[DT_TEXTREL] = 1;
}
}
+#if defined(__mips__)
+ if (dpnt->d_tag == DT_MIPS_GOTSYM)
+ mips_gotsym = (unsigned long) dpnt->d_un.d_val;
+ if (dpnt->d_tag == DT_MIPS_LOCAL_GOTNO)
+ mips_local_gotno = (unsigned long) dpnt->d_un.d_val;
+ if (dpnt->d_tag == DT_MIPS_SYMTABNO)
+ mips_symtabno = (unsigned long) dpnt->d_un.d_val;
+#endif
dpnt++;
}
@@ -394,7 +405,11 @@ DL_BOOT(unsigned long args)
}
app_tpnt->dynamic_info[dpnt->d_tag] = dpnt->d_un.d_val;
if (dpnt->d_tag == DT_DEBUG)
+#ifndef DO_MPROTECT_HACKS
dpnt->d_un.d_val = (unsigned long) debug_addr;
+#else
+ dpnt_debug = dpnt;
+#endif
if (dpnt->d_tag == DT_TEXTREL || SVR4_BUGCOMPAT)
app_tpnt->dynamic_info[DT_TEXTREL] = 1;
dpnt++;
@@ -446,6 +461,16 @@ DL_BOOT(unsigned long args)
}
}
}
+
+ /* Now we can store the debug structure address */
+ dpnt_debug->d_un.d_val = (unsigned long) debug_addr;
+#endif
+
+
+ /* For MIPS, we have to do special stuff to the GOT before we do
+ any relocations. */
+#if defined(__mips__)
+ PERFORM_BOOTSTRAP_GOT(got);
#endif
@@ -454,6 +479,7 @@ DL_BOOT(unsigned long args)
#ifdef DL_DEBUG
SEND_STDERR("About to do library loader relocations.\n");
#endif
+
goof = 0;
for (indx = 0; indx < 2; indx++) {
int i;
@@ -476,7 +502,6 @@ DL_BOOT(unsigned long args)
dynamic_info[DT_RELSZ]);
#endif
-
if (!rel_addr)
continue;
@@ -499,6 +524,7 @@ DL_BOOT(unsigned long args)
if (!_dl_symbol(strtab + symtab[symtab_index].st_name))
continue;
symbol_addr = load_addr + symtab[symtab_index].st_value;
+ SEND_NUMBER_STDERR(symbol_addr,1);
if (!symbol_addr) {
/* This will segfault - you cannot call a function until