summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--ldso/ldso/mips/elfinterp.c20
-rw-r--r--libc/sysdeps/linux/mips/crt1.S46
2 files changed, 27 insertions, 39 deletions
diff --git a/ldso/ldso/mips/elfinterp.c b/ldso/ldso/mips/elfinterp.c
index b49f09d36..40c3e0939 100644
--- a/ldso/ldso/mips/elfinterp.c
+++ b/ldso/ldso/mips/elfinterp.c
@@ -148,7 +148,7 @@ int _dl_parse_relocation_information(struct dyn_elf *xpnt,
unsigned long rel_addr, unsigned long rel_size)
{
ElfW(Sym) *symtab;
- ElfW(Rel) *rpnt;
+ ELF_RELOC *rpnt;
char *strtab;
unsigned long i;
unsigned long *got;
@@ -162,7 +162,7 @@ int _dl_parse_relocation_information(struct dyn_elf *xpnt,
/* Now parse the relocation information */
rel_size = rel_size / sizeof(ElfW(Rel));
- rpnt = (ElfW(Rel) *) rel_addr;
+ rpnt = (ELF_RELOC *) rel_addr;
symtab = (ElfW(Sym) *) tpnt->dynamic_info[DT_SYMTAB];
strtab = (char *) tpnt->dynamic_info[DT_STRTAB];
@@ -172,8 +172,8 @@ int _dl_parse_relocation_information(struct dyn_elf *xpnt,
char *symname = NULL;
reloc_addr = (unsigned long *) (tpnt->loadaddr +
(unsigned long) rpnt->r_offset);
- reloc_type = ELF_R_TYPE(rpnt->r_info);
- symtab_index = ELF_R_SYM(rpnt->r_info);
+ reloc_type = ELF32_R_TYPE(rpnt->r_info);
+ symtab_index = ELF32_R_SYM(rpnt->r_info);
symbol_addr = 0;
debug_sym(symtab,strtab,symtab_index);
@@ -206,12 +206,20 @@ int _dl_parse_relocation_information(struct dyn_elf *xpnt,
# endif
{
ElfW(Sym) *sym_tls = &symtab[symtab_index];
- struct elf_resolve *tpnt_tls = tpnt;
+ struct elf_resolve *tpnt_tls = NULL;
if (ELF32_ST_BIND(symtab[symtab_index].st_info) != STB_LOCAL) {
_dl_find_hash((strtab + symtab[symtab_index].st_name),
- _dl_symbol_tables, tpnt_tls, 1, &sym_tls);
+ _dl_symbol_tables, tpnt,
+ elf_machine_type_class(reloc_type), &tpnt_tls);
}
+#if USE_TLS
+ /* In case of a TLS reloc, tpnt_tls NULL means we have an 'anonymous'
+ symbol. This is the case for a static tls variable, so the lookup
+ module is just that one is referencing the tls variable. */
+ if (!tpnt_tls)
+ tpnt_tls = tpnt;
+#endif
switch (reloc_type) {
case R_MIPS_TLS_DTPMOD64:
diff --git a/libc/sysdeps/linux/mips/crt1.S b/libc/sysdeps/linux/mips/crt1.S
index e851d52d2..6a804125e 100644
--- a/libc/sysdeps/linux/mips/crt1.S
+++ b/libc/sysdeps/linux/mips/crt1.S
@@ -85,29 +85,10 @@
__start:
#ifdef __PIC__
-#if _MIPS_SIM == _MIPS_SIM_ABI32
- .frame sp, 24, sp
- .set noreorder
- move $0, $31 /* Save old ra. */
- bal 10f /* Find addr of cpload. */
- nop
-10:
- .cpload $31
- move $31, $0
- .set reorder
- .cprestore 16
-#else
- move $0, $31; /* Save old ra. */
- .set noreorder
- bal 10f /* Find addr of .cpsetup. */
- nop
-10:
- .set reorder
- .cpsetup $31, $25, 10b
- move $31, $0
-#endif
+ SETUP_GPX($0)
+ SETUP_GPX64($25,$0)
#else
- la $28, _gp /* Setup GP correctly if we're non-PIC. */
+ PTR_LA $28, _gp /* Setup GP correctly if we're non-PIC. */
move $31, $0
#endif
@@ -118,18 +99,18 @@ __start:
/* Allocate space on the stack for seven arguments and
* make sure the stack is aligned to double words (8 bytes) */
+ and $29, -2 * SZREG
+
#if _MIPS_SIM == _MIPS_SIM_ABI32
- and $29, -2 * 4
- subu $29, 32
- la $7, _init /* init */
- la $8, _fini
- sw $8, 16($29) /* fini */
- sw $2, 20($29) /* rtld_fini */
- sw $29, 24($29) /* stack_end */
-#else
- and $29, -2 * PTRSIZE
+ PTR_SUBIU $29, 32
+#endif
PTR_LA $7, _init /* init */
- PTR_LA $8, _fini /* fini */
+ PTR_LA $8, _fini
+#if _MIPS_SIM == _MIPS_SIM_ABI32
+ PTR_S $8, 16($29) /* fini */
+ PTR_S $2, 20($29) /* rtld_fini */
+ PTR_S $29, 24($29) /* stack_end */
+#else
move $9, $2 /* rtld_fini */
move $10, $29 /* stack_end */
#endif
@@ -148,4 +129,3 @@ __data_start:
.weak data_start
data_start = __data_start
-