summaryrefslogtreecommitdiff
path: root/ldso/ldso/powerpc/elfinterp.c
diff options
context:
space:
mode:
authorEric Andersen <andersen@codepoet.org>2003-11-11 21:50:11 +0000
committerEric Andersen <andersen@codepoet.org>2003-11-11 21:50:11 +0000
commit5b6baaa645a1ed9c0e237ee19c7c14c6a12b4d2e (patch)
tree545d3c4acd36d7268c478a232d544b9e9bcb765f /ldso/ldso/powerpc/elfinterp.c
parente4c119fe8a0e486ad7f7a52767b16b2c7d0823ac (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/ldso/powerpc/elfinterp.c')
-rw-r--r--ldso/ldso/powerpc/elfinterp.c16
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;