summaryrefslogtreecommitdiff
path: root/ldso
diff options
context:
space:
mode:
Diffstat (limited to 'ldso')
-rw-r--r--ldso/ldso/dl-elf.c14
-rw-r--r--ldso/ldso/ldso.c15
-rw-r--r--ldso/ldso/mips/boot1_arch.h5
-rw-r--r--ldso/ldso/mips/dl-startup.h5
-rw-r--r--ldso/ldso/mips/dl-sysdep.h41
-rw-r--r--ldso/ldso/mips/elfinterp.c59
-rw-r--r--ldso/ldso/mips/ld_sysdep.h41
-rw-r--r--ldso/ldso/readelflib1.c14
8 files changed, 91 insertions, 103 deletions
diff --git a/ldso/ldso/dl-elf.c b/ldso/ldso/dl-elf.c
index ebb0aec56..1bbb79364 100644
--- a/ldso/ldso/dl-elf.c
+++ b/ldso/ldso/dl-elf.c
@@ -527,14 +527,14 @@ struct elf_resolve *_dl_load_elf_shared_library(int secure,
#if defined(__mips__)
{
- int i = 1;
- Elf32_Dyn *dpnt = (Elf32_Dyn *) dynamic_addr;
+ int i = 1;
+ Elf32_Dyn *dpnt = (Elf32_Dyn *) dynamic_addr;
- while(dpnt->d_tag) {
- dpnt++;
- i++;
- }
- dynamic_size = i * sizeof(Elf32_Dyn);
+ while(dpnt->d_tag) {
+ dpnt++;
+ i++;
+ }
+ dynamic_size = i;
}
#endif
diff --git a/ldso/ldso/ldso.c b/ldso/ldso/ldso.c
index d2eee0555..5c3f38d30 100644
--- a/ldso/ldso/ldso.c
+++ b/ldso/ldso/ldso.c
@@ -709,12 +709,10 @@ static void _dl_get_ready_to_run(struct elf_resolve *tpnt, struct elf_resolve *a
app_tpnt->usage_count++;
app_tpnt->symbol_scope = _dl_symbol_tables;
lpnt = (unsigned long *) (app_tpnt->dynamic_info[DT_PLTGOT]);
-#ifndef __mips__
#ifdef ALLOW_ZERO_PLTGOT
if (lpnt)
#endif
INIT_GOT(lpnt, _dl_loaded_modules);
-#endif
}
/* OK, fill this in - we did not have this before */
@@ -1046,6 +1044,14 @@ static void _dl_get_ready_to_run(struct elf_resolve *tpnt, struct elf_resolve *a
}
#endif
+#ifdef __mips__
+ /*
+ * Relocation of the GOT entries for MIPS have to be done
+ * after all the libraries have been loaded.
+ */
+ _dl_perform_mips_global_got_relocations(_dl_loaded_modules);
+#endif
+
#ifdef DL_DEBUG
_dl_dprintf(2, "Beginning relocation fixups\n");
#endif
@@ -1091,11 +1097,6 @@ static void _dl_get_ready_to_run(struct elf_resolve *tpnt, struct elf_resolve *a
*_dl_envp = (unsigned long) envp;
}
-#ifdef __mips__
- lpnt = (unsigned long *) (app_tpnt->dynamic_info[DT_PLTGOT]);
- INIT_GOT(lpnt, _dl_loaded_modules);
-#endif
-
#ifdef DO_MPROTECT_HACKS
{
int i;
diff --git a/ldso/ldso/mips/boot1_arch.h b/ldso/ldso/mips/boot1_arch.h
index 05aaf9ebb..6dda467e8 100644
--- a/ldso/ldso/mips/boot1_arch.h
+++ b/ldso/ldso/mips/boot1_arch.h
@@ -16,8 +16,11 @@ _dl_boot:
sw $4, -0x7ff0($28)
move $4, $29
la $8, coff
- bltzal $8, coff
+ .set noreorder
+ bltzal $0, coff
+ nop
coff: subu $8, $31, $8
+ .set reorder
la $25, _dl_boot2
addu $25, $8
jalr $25
diff --git a/ldso/ldso/mips/dl-startup.h b/ldso/ldso/mips/dl-startup.h
index 05aaf9ebb..6dda467e8 100644
--- a/ldso/ldso/mips/dl-startup.h
+++ b/ldso/ldso/mips/dl-startup.h
@@ -16,8 +16,11 @@ _dl_boot:
sw $4, -0x7ff0($28)
move $4, $29
la $8, coff
- bltzal $8, coff
+ .set noreorder
+ bltzal $0, coff
+ nop
coff: subu $8, $31, $8
+ .set reorder
la $25, _dl_boot2
addu $25, $8
jalr $25
diff --git a/ldso/ldso/mips/dl-sysdep.h b/ldso/ldso/mips/dl-sysdep.h
index 9d48d8f73..a669bba67 100644
--- a/ldso/ldso/mips/dl-sysdep.h
+++ b/ldso/ldso/mips/dl-sysdep.h
@@ -20,12 +20,10 @@
/*
- * Initialization sequence for the application or library GOT.
+ * Initialization sequence for the application/library GOT.
*/
#define INIT_GOT(GOT_BASE,MODULE) \
do { \
- Elf32_Sym *sym; \
- char *strtab; \
unsigned long i; \
\
/* Check if this is the dynamic linker itself */ \
@@ -41,43 +39,6 @@ do { \
while (i < MODULE->mips_local_gotno) \
GOT_BASE[i++] += (unsigned long) MODULE->loadaddr; \
\
- /* Handle global GOT entries */ \
- GOT_BASE += MODULE->mips_local_gotno; \
- sym = (Elf32_Sym *) (MODULE->dynamic_info[DT_SYMTAB] + \
- (unsigned long) MODULE->loadaddr) + MODULE->mips_gotsym; \
- strtab = (char *) (MODULE->dynamic_info[DT_STRTAB] + \
- (unsigned long) MODULE->loadaddr); \
- i = MODULE->mips_symtabno - MODULE->mips_gotsym; \
- while (i--) { \
- if (sym->st_shndx == SHN_UNDEF) { \
- if (ELF32_ST_TYPE(sym->st_info) == STT_FUNC && \
- sym->st_value) \
- *GOT_BASE = sym->st_value + \
- (unsigned long) MODULE->loadaddr; \
- else { \
- *GOT_BASE = (unsigned long) _dl_find_hash(strtab + \
- sym->st_name, MODULE->symbol_scope, NULL, 1); \
- } \
- } \
- else if (sym->st_shndx == SHN_COMMON) { \
- *GOT_BASE = (unsigned long) _dl_find_hash(strtab + \
- sym->st_name, MODULE->symbol_scope, NULL, 1); \
- } \
- else if (ELF32_ST_TYPE(sym->st_info) == STT_FUNC && \
- *GOT_BASE != sym->st_value) \
- *GOT_BASE += (unsigned long) MODULE->loadaddr; \
- else if (ELF32_ST_TYPE(sym->st_info) == STT_SECTION) { \
- if (sym->st_other == 0) \
- *GOT_BASE += (unsigned long) MODULE->loadaddr; \
- } \
- else { \
- *GOT_BASE = (unsigned long) _dl_find_hash(strtab + \
- sym->st_name, MODULE->symbol_scope, NULL, 1); \
- } \
- \
- ++GOT_BASE; \
- ++sym; \
- } \
} while (0)
diff --git a/ldso/ldso/mips/elfinterp.c b/ldso/ldso/mips/elfinterp.c
index e6c3781b8..5b1192169 100644
--- a/ldso/ldso/mips/elfinterp.c
+++ b/ldso/ldso/mips/elfinterp.c
@@ -142,3 +142,62 @@ int _dl_parse_relocation_information(struct elf_resolve *tpnt,
};
return 0;
}
+
+void _dl_perform_mips_global_got_relocations(struct elf_resolve *tpnt)
+{
+ Elf32_Sym *sym;
+ char *strtab;
+ unsigned long i;
+ unsigned long *got_entry;
+
+ for (; tpnt ; tpnt = tpnt->next) {
+
+ /* We don't touch the dynamic linker */
+ if (tpnt->libtype == program_interpreter)
+ continue;
+
+ /* Setup the loop variables */
+ got_entry = (unsigned long *) (tpnt->loadaddr +
+ tpnt->dynamic_info[DT_PLTGOT]) + tpnt->mips_local_gotno;
+ sym = (Elf32_Sym *) (tpnt->dynamic_info[DT_SYMTAB] +
+ (unsigned long) tpnt->loadaddr) + tpnt->mips_gotsym;
+ strtab = (char *) (tpnt->dynamic_info[DT_STRTAB] +
+ (unsigned long) tpnt->loadaddr);
+ i = tpnt->mips_symtabno - tpnt->mips_gotsym;
+
+ /* Relocate the global GOT entries for the object */
+ while(i--) {
+ if (sym->st_shndx == SHN_UNDEF) {
+ if (ELF32_ST_TYPE(sym->st_info) == STT_FUNC && sym->st_value)
+ *got_entry = sym->st_value + (unsigned long) tpnt->loadaddr;
+ else {
+ *got_entry = (unsigned long) _dl_find_hash(strtab +
+ sym->st_name, tpnt->symbol_scope, NULL, 1);
+ }
+ }
+ else if (sym->st_shndx == SHN_COMMON) {
+ *got_entry = (unsigned long) _dl_find_hash(strtab +
+ sym->st_name, tpnt->symbol_scope, NULL, 1);
+ }
+ else if (ELF32_ST_TYPE(sym->st_info) == STT_FUNC &&
+ *got_entry != sym->st_value)
+ *got_entry += (unsigned long) tpnt->loadaddr;
+ else if (ELF32_ST_TYPE(sym->st_info) == STT_SECTION) {
+ if (sym->st_other == 0)
+ *got_entry += (unsigned long) tpnt->loadaddr;
+ }
+ else {
+ *got_entry = (unsigned long) _dl_find_hash(strtab +
+ sym->st_name, tpnt->symbol_scope, NULL, 1);
+ }
+
+#ifdef DL_DEBUG
+ if (*got_entry == 0)
+ _dl_dprintf(2,"ZERO: %s\n", strtab + sym->st_name);
+#endif
+
+ got_entry++;
+ sym++;
+ }
+ }
+}
diff --git a/ldso/ldso/mips/ld_sysdep.h b/ldso/ldso/mips/ld_sysdep.h
index 9d48d8f73..a669bba67 100644
--- a/ldso/ldso/mips/ld_sysdep.h
+++ b/ldso/ldso/mips/ld_sysdep.h
@@ -20,12 +20,10 @@
/*
- * Initialization sequence for the application or library GOT.
+ * Initialization sequence for the application/library GOT.
*/
#define INIT_GOT(GOT_BASE,MODULE) \
do { \
- Elf32_Sym *sym; \
- char *strtab; \
unsigned long i; \
\
/* Check if this is the dynamic linker itself */ \
@@ -41,43 +39,6 @@ do { \
while (i < MODULE->mips_local_gotno) \
GOT_BASE[i++] += (unsigned long) MODULE->loadaddr; \
\
- /* Handle global GOT entries */ \
- GOT_BASE += MODULE->mips_local_gotno; \
- sym = (Elf32_Sym *) (MODULE->dynamic_info[DT_SYMTAB] + \
- (unsigned long) MODULE->loadaddr) + MODULE->mips_gotsym; \
- strtab = (char *) (MODULE->dynamic_info[DT_STRTAB] + \
- (unsigned long) MODULE->loadaddr); \
- i = MODULE->mips_symtabno - MODULE->mips_gotsym; \
- while (i--) { \
- if (sym->st_shndx == SHN_UNDEF) { \
- if (ELF32_ST_TYPE(sym->st_info) == STT_FUNC && \
- sym->st_value) \
- *GOT_BASE = sym->st_value + \
- (unsigned long) MODULE->loadaddr; \
- else { \
- *GOT_BASE = (unsigned long) _dl_find_hash(strtab + \
- sym->st_name, MODULE->symbol_scope, NULL, 1); \
- } \
- } \
- else if (sym->st_shndx == SHN_COMMON) { \
- *GOT_BASE = (unsigned long) _dl_find_hash(strtab + \
- sym->st_name, MODULE->symbol_scope, NULL, 1); \
- } \
- else if (ELF32_ST_TYPE(sym->st_info) == STT_FUNC && \
- *GOT_BASE != sym->st_value) \
- *GOT_BASE += (unsigned long) MODULE->loadaddr; \
- else if (ELF32_ST_TYPE(sym->st_info) == STT_SECTION) { \
- if (sym->st_other == 0) \
- *GOT_BASE += (unsigned long) MODULE->loadaddr; \
- } \
- else { \
- *GOT_BASE = (unsigned long) _dl_find_hash(strtab + \
- sym->st_name, MODULE->symbol_scope, NULL, 1); \
- } \
- \
- ++GOT_BASE; \
- ++sym; \
- } \
} while (0)
diff --git a/ldso/ldso/readelflib1.c b/ldso/ldso/readelflib1.c
index ebb0aec56..1bbb79364 100644
--- a/ldso/ldso/readelflib1.c
+++ b/ldso/ldso/readelflib1.c
@@ -527,14 +527,14 @@ struct elf_resolve *_dl_load_elf_shared_library(int secure,
#if defined(__mips__)
{
- int i = 1;
- Elf32_Dyn *dpnt = (Elf32_Dyn *) dynamic_addr;
+ int i = 1;
+ Elf32_Dyn *dpnt = (Elf32_Dyn *) dynamic_addr;
- while(dpnt->d_tag) {
- dpnt++;
- i++;
- }
- dynamic_size = i * sizeof(Elf32_Dyn);
+ while(dpnt->d_tag) {
+ dpnt++;
+ i++;
+ }
+ dynamic_size = i;
}
#endif