diff options
-rw-r--r-- | ldso/ldso/powerpc/dl-sysdep.h | 2 | ||||
-rw-r--r-- | ldso/ldso/powerpc/elfinterp.c | 112 | ||||
-rw-r--r-- | ldso/ldso/powerpc/ld_sysdep.h | 2 | ||||
-rw-r--r-- | ldso/ldso/powerpc/sysdep.h | 2 |
4 files changed, 56 insertions, 62 deletions
diff --git a/ldso/ldso/powerpc/dl-sysdep.h b/ldso/ldso/powerpc/dl-sysdep.h index 16b853ce3..9e532b486 100644 --- a/ldso/ldso/powerpc/dl-sysdep.h +++ b/ldso/ldso/powerpc/dl-sysdep.h @@ -117,7 +117,7 @@ #define START() \ __asm__ volatile ("mtlr %0\n\t" \ "blrl\n\t" \ - : "=r" (status) : "r" (_dl_elf_main)) + : : "r" (_dl_elf_main)) diff --git a/ldso/ldso/powerpc/elfinterp.c b/ldso/ldso/powerpc/elfinterp.c index 81b10c778..5fedaa267 100644 --- a/ldso/ldso/powerpc/elfinterp.c +++ b/ldso/ldso/powerpc/elfinterp.c @@ -1,3 +1,4 @@ +#define DEBUG /* Run an ELF binary on a linux system. Copyright (C) 1993, Eric Youngdale. @@ -101,35 +102,14 @@ _dl_fdprintf(2,"data_words %08x\n",data_words); tramp[8] = OPCODE_ADDIS_HI(12,12,(unsigned long)tpnt); tramp[9] = OPCODE_BCTR(); -#if 0 - offset = PLT_INITIAL_ENTRY_WORDS; - i = 0; - if(n_plt_entries >= PLT_DOUBLE_SIZE){ - _dl_fdprintf(2,"PLT table too large (%d>=%d)\n", - n_plt_entries,PLT_DOUBLE_SIZE); - _dl_exit(1); - } - for(i=0;i<n_plt_entries;i++){ - plt[offset] = OPCODE_LI (11,i*4); - plt[offset+1] = OPCODE_B ((PLT_TRAMPOLINE_ENTRY_WORDS + 2 - - (offset + 1)) *4); - offset+=2; - } - - for(i=0;i<rel_offset_words;i+=4){ -_dl_fdprintf(2,"%d %08lx\n",i,(unsigned long)(plt+i)); - //PPC_DCBST(plt+i); - //PPC_SYNC; - //PPC_ICBI(plt+i); - } -#if 0 - PPC_DCBST(plt + rel_offset_words - 1); + PPC_DCBST(plt); + PPC_DCBST(plt+4); + PPC_DCBST(plt+8); PPC_SYNC; PPC_ICBI(plt); - PPC_ICBI(plt+rel_offset_words-1); -#endif - //PPC_ISYNC; -#endif + PPC_ICBI(plt+4); + PPC_ICBI(plt+8); + PPC_ISYNC; } unsigned long _dl_linux_resolver(struct elf_resolve *tpnt, int reloc_entry) @@ -167,10 +147,11 @@ _dl_fdprintf(2,"linux_resolver tpnt=%08x reloc_entry=%08x\n",tpnt,reloc_entry); (unsigned long) tpnt->loadaddr); got_addr = (char **) instr_addr; -//#ifdef DEBUG - _dl_fdprintf(2, "Resolving symbol %s\n", - strtab + symtab[symtab_index].st_name); -//#endif +#ifdef DEBUG + _dl_fdprintf(2, "Resolving symbol %s %08x --> ", + strtab + symtab[symtab_index].st_name, + instr_addr); +#endif /* Get the address of the GOT entry */ new_addr = _dl_find_hash(strtab + symtab[symtab_index].st_name, @@ -180,6 +161,10 @@ _dl_fdprintf(2,"linux_resolver tpnt=%08x reloc_entry=%08x\n",tpnt,reloc_entry); _dl_progname, strtab + symtab[symtab_index].st_name); _dl_exit(1); }; +#ifdef DEBUG + _dl_fdprintf(2, "%08x\n", new_addr); +#endif + /* #define DEBUG_LIBRARY */ #ifdef DEBUG_LIBRARY if ((unsigned long) got_addr < 0x40000000) { @@ -207,8 +192,10 @@ void _dl_parse_lazy_relocation_information(struct elf_resolve *tpnt, unsigned long *plt; int index; -_dl_fdprintf(2,"parse_lazy tpnt=%08x rel_addr=%08x rel_size=%08x, type=%d\n", +#ifdef DEBUG +_dl_fdprintf(2,"_dl_parse_lazy_relocation_information(tpnt=%08x, rel_addr=%08x, rel_size=%08x, type=%d)\n", tpnt,rel_addr,rel_size,type); +#endif /* Now parse the relocation information */ rpnt = (ELF_RELOC *) (rel_addr + tpnt->loadaddr); rel_size = rel_size / sizeof(ELF_RELOC); @@ -231,12 +218,10 @@ _dl_fdprintf(2,"parse_lazy tpnt=%08x rel_addr=%08x rel_size=%08x, type=%d\n", _dl_symbol(strtab + symtab[symtab_index].st_name)) continue; -#if 0 -_dl_fdprintf(2, "(lazy) resolving "); - if (symtab_index) - _dl_fdprintf(2, "'%s'\n", strtab + symtab[symtab_index].st_name); -_dl_fdprintf(2, "reloc_addr %08x addr %08x old %08x\n", reloc_addr, symtab[symtab_index].st_value, *reloc_addr); -_dl_fdprintf(2, "plt %08x\n",(unsigned long)plt); +#ifdef DEBUG +_dl_fdprintf(2, "L %08x %-16s %-20s %08x %08x\n", + reloc_addr, _dl_reltypes[reloc_type], + symtab_index?strtab + symtab[symtab_index].st_name:"",0,0); #endif @@ -254,8 +239,9 @@ _dl_fdprintf(2, "plt %08x\n",(unsigned long)plt); (unsigned long)(plt+PLT_INITIAL_ENTRY_WORDS)) /sizeof(unsigned long); index /= 2; -//_dl_fdprintf(2, "index %08x\n",index); -//_dl_fdprintf(2, "delta %08x\n",delta); +#ifdef DEBUG +_dl_fdprintf(2, " index %08x delta %08x\n",index,delta); +#endif reloc_addr[0] = OPCODE_LI(11,index*4); reloc_addr[1] = OPCODE_B(delta); break; @@ -293,29 +279,24 @@ int _dl_parse_relocation_information(struct elf_resolve *tpnt, unsigned long addend; unsigned long *plt; -//_dl_fdprintf(2,"parse_reloc tpnt=%08x rel_addr=%08x rel_size=%08x, type=%d\n", -// tpnt,rel_addr,rel_size,type); +#ifdef DEBUG +_dl_fdprintf(2,"_dl_parse_relocation_information(tpnt=%08x, rel_addr=%08x, rel_size=%08x, type=%d)\n", + tpnt,rel_addr,rel_size,type); +#endif /* Now parse the relocation information */ rpnt = (ELF_RELOC *) (rel_addr + tpnt->loadaddr); rel_size = rel_size / sizeof(ELF_RELOC); -//_dl_fdprintf(2,"rpnt=%08x\n",rpnt); symtab = (Elf32_Sym *) (tpnt->dynamic_info[DT_SYMTAB] + tpnt->loadaddr); strtab = (char *) (tpnt->dynamic_info[DT_STRTAB] + tpnt->loadaddr); -//_dl_fdprintf(2,"symtab=%08x\n",symtab); -//_dl_fdprintf(2,"strtab=%08x\n",strtab); plt = (unsigned long *)(tpnt->dynamic_info[DT_PLTGOT] + tpnt->loadaddr); for (i = 0; i < rel_size; i++, rpnt++) { reloc_addr = (unsigned long *) (tpnt->loadaddr + (unsigned long) rpnt->r_offset); -//_dl_fdprintf(2,"reloc_addr=%08x\n",reloc_addr); reloc_type = ELF32_R_TYPE(rpnt->r_info); -//_dl_fdprintf(2,"reloc_type=%08x\n",reloc_type); symtab_index = ELF32_R_SYM(rpnt->r_info); -//_dl_fdprintf(2,"symtab_index=%08x\n",symtab_index); addend = rpnt->r_addend; -//_dl_fdprintf(2,"addend=%08x\n",rpnt->r_addend); symbol_addr = 0; if (!symtab_index && tpnt->libtype == program_interpreter) @@ -343,12 +324,22 @@ int _dl_parse_relocation_information(struct elf_resolve *tpnt, goof++; } } +#ifdef DEBUG +_dl_fdprintf(2, " %08x %-16s %-20s %08x %08x\n", + reloc_addr, _dl_reltypes[reloc_type], + symtab_index?strtab + symtab[symtab_index].st_name:"", + symbol_addr, addend); +#endif switch (reloc_type) { case R_PPC_NONE: break; case R_PPC_REL24: { int delta = symbol_addr - (unsigned long)reloc_addr; + if(delta<<6>>6 != delta){ + _dl_fdprintf(2,"R_PPC_REL24: Reloc out of range\n"); + _dl_exit(1); + } *reloc_addr &= 0xfc000003; *reloc_addr |= delta&0x03fffffc; } @@ -359,6 +350,16 @@ int _dl_parse_relocation_information(struct elf_resolve *tpnt, case R_PPC_ADDR32: *reloc_addr += symbol_addr; break; + case R_PPC_ADDR16_HA: + /* XXX is this correct? */ + *(short *)reloc_addr += (symbol_addr+0x8000)>>16; + break; + case R_PPC_ADDR16_HI: + *(short *)reloc_addr += symbol_addr>>16; + break; + case R_PPC_ADDR16_LO: + *(short *)reloc_addr += symbol_addr; + break; case R_PPC_JMP_SLOT: { unsigned long targ_addr = (unsigned long)_dl_linux_resolve; @@ -379,18 +380,11 @@ int _dl_parse_relocation_information(struct elf_resolve *tpnt, (unsigned long)(plt+PLT_INITIAL_ENTRY_WORDS)) /sizeof(unsigned long); index /= 2; -//_dl_fdprintf(2, "index %08x\n",index); -//_dl_fdprintf(2, "delta %08x\n",delta); +#ifdef DEBUG +_dl_fdprintf(2, " index %08x delta %08x\n",index,delta); +#endif reloc_addr[0] = OPCODE_LI(11,index*4); reloc_addr[1] = OPCODE_B(delta); -#if 0 -_dl_fdprintf(2, "resolving "); - if (symtab_index) - _dl_fdprintf(2, "'%s'\n", strtab + symtab[symtab_index].st_name); -_dl_fdprintf(2, "type %d reloc_addr %08x addr %08x addend %08x old %08x\n", - reloc_type, reloc_addr, symbol_addr, addend, *reloc_addr); - _dl_fdprintf(2, "need to create PLT\n"); -#endif } } break; diff --git a/ldso/ldso/powerpc/ld_sysdep.h b/ldso/ldso/powerpc/ld_sysdep.h index 16b853ce3..9e532b486 100644 --- a/ldso/ldso/powerpc/ld_sysdep.h +++ b/ldso/ldso/powerpc/ld_sysdep.h @@ -117,7 +117,7 @@ #define START() \ __asm__ volatile ("mtlr %0\n\t" \ "blrl\n\t" \ - : "=r" (status) : "r" (_dl_elf_main)) + : : "r" (_dl_elf_main)) diff --git a/ldso/ldso/powerpc/sysdep.h b/ldso/ldso/powerpc/sysdep.h index 16b853ce3..9e532b486 100644 --- a/ldso/ldso/powerpc/sysdep.h +++ b/ldso/ldso/powerpc/sysdep.h @@ -117,7 +117,7 @@ #define START() \ __asm__ volatile ("mtlr %0\n\t" \ "blrl\n\t" \ - : "=r" (status) : "r" (_dl_elf_main)) + : : "r" (_dl_elf_main)) |