diff options
author | Eric Andersen <andersen@codepoet.org> | 2003-11-11 21:50:11 +0000 |
---|---|---|
committer | Eric Andersen <andersen@codepoet.org> | 2003-11-11 21:50:11 +0000 |
commit | 5b6baaa645a1ed9c0e237ee19c7c14c6a12b4d2e (patch) | |
tree | 545d3c4acd36d7268c478a232d544b9e9bcb765f /ldso | |
parent | e4c119fe8a0e486ad7f7a52767b16b2c7d0823ac (diff) |
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!
Diffstat (limited to 'ldso')
-rw-r--r-- | ldso/ldso/powerpc/elfinterp.c | 16 |
1 files changed, 9 insertions, 7 deletions
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; |