From 5b6baaa645a1ed9c0e237ee19c7c14c6a12b4d2e Mon Sep 17 00:00:00 2001 From: Eric Andersen Date: Tue, 11 Nov 2003 21:50:11 +0000 Subject: Joakim Tjernlund writes: Comparing glibc with uClibc makes me think that the delta calculations are wrong here. Comparing some more I still think there are a data_words[index] assignments missing. Here is a path that has both the data_words[index] and the above delta calclations. This also fixes a terribly obvious bug, also spotted by Joakim, which Erik introduced when he copied things from the i386 ldso code. With this patch applied, things now seem to be working perfectly! --- ldso/ldso/powerpc/elfinterp.c | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) (limited to 'ldso/ldso') diff --git a/ldso/ldso/powerpc/elfinterp.c b/ldso/ldso/powerpc/elfinterp.c index 219c512d5..b27d2119d 100644 --- a/ldso/ldso/powerpc/elfinterp.c +++ b/ldso/ldso/powerpc/elfinterp.c @@ -231,14 +231,14 @@ unsigned long _dl_linux_resolver(struct elf_resolve *tpnt, int reloc_entry) }else{ /* Warning: we don't handle double-sized PLT entries */ unsigned long plt_addr; - unsigned long lbranch_addr; unsigned long *ptr; int index; plt_addr = (unsigned long)tpnt->dynamic_info[DT_PLTGOT] + (unsigned long)tpnt->loadaddr; - lbranch_addr = plt_addr + PLT_LONGBRANCH_ENTRY_WORDS*4; - delta = lbranch_addr - insn_addr; + + delta = PLT_LONGBRANCH_ENTRY_WORDS*4 - (insn_addr-plt_addr+4); + index = (insn_addr - plt_addr - PLT_INITIAL_ENTRY_WORDS*4)/8; ptr = (unsigned long *)tpnt->data_words; @@ -426,7 +426,7 @@ _dl_do_reloc (struct elf_resolve *tpnt,struct dyn_elf *scope, if (symtab_index) { symbol_addr = (unsigned long) _dl_find_hash(symname, scope, - (reloc_type == R_386_JMP_SLOT ? tpnt : NULL), symbolrel); + (reloc_type == R_PPC_JMP_SLOT ? tpnt : NULL), symbolrel); /* * We want to allow undefined references to weak symbols - this might @@ -495,10 +495,10 @@ _dl_do_reloc (struct elf_resolve *tpnt,struct dyn_elf *scope, { int delta; int index; - unsigned long *plt; + unsigned long *plt, *ptr; plt = (unsigned long *)(tpnt->dynamic_info[DT_PLTGOT] + tpnt->loadaddr); - delta = (unsigned long)(plt+PLT_TRAMPOLINE_ENTRY_WORDS+2) + delta = (unsigned long)(plt+PLT_LONGBRANCH_ENTRY_WORDS) - (unsigned long)(reloc_addr+1); index = ((unsigned long)reloc_addr - @@ -506,6 +506,8 @@ _dl_do_reloc (struct elf_resolve *tpnt,struct dyn_elf *scope, /sizeof(unsigned long); index /= 2; //DPRINTF(" index %x delta %x\n",index,delta); + ptr = (unsigned long *)tpnt->data_words; + ptr[index] = targ_addr; reloc_addr[0] = OPCODE_LI(11,index*4); reloc_addr[1] = OPCODE_B(delta); @@ -570,7 +572,7 @@ _dl_do_copy (struct elf_resolve *tpnt, struct dyn_elf *scope, reloc_addr = (unsigned long *)(intptr_t) (tpnt->loadaddr + (unsigned long) rpnt->r_offset); reloc_type = ELF32_R_TYPE(rpnt->r_info); - if (reloc_type != R_386_COPY) + if (reloc_type != R_PPC_COPY) return 0; symtab_index = ELF32_R_SYM(rpnt->r_info); symbol_addr = 0; -- cgit v1.2.3