OSDN Git Service

Use DT_RELCONT_IDX to optimize the relocation of R_PPC_RELATIVE
authorJoakim Tjernlund <joakim.tjernlund@transmode.se>
Thu, 10 Mar 2005 16:29:22 +0000 (16:29 -0000)
committerJoakim Tjernlund <joakim.tjernlund@transmode.se>
Thu, 10 Mar 2005 16:29:22 +0000 (16:29 -0000)
relocs. All RELA arches can probably copy this. REL archs
will have to delete the "+ rpnt->r_addend" from the loop.

ldso/ldso/powerpc/elfinterp.c

index 8175a01..d3dd269 100644 (file)
@@ -421,7 +421,7 @@ _dl_parse(struct elf_resolve *tpnt, struct dyn_elf *scope,
          int (*reloc_fnc) (struct elf_resolve *tpnt, struct dyn_elf *scope,
                            ELF_RELOC *rpnt, Elf32_Sym *symtab, char *strtab))
 {
-       unsigned int i;
+       unsigned int i, relative_count;
        char *strtab;
        Elf32_Sym *symtab;
        ELF_RELOC *rpnt;
@@ -433,6 +433,18 @@ _dl_parse(struct elf_resolve *tpnt, struct dyn_elf *scope,
 
        symtab = (Elf32_Sym *)(intptr_t) (tpnt->dynamic_info[DT_SYMTAB] + tpnt->loadaddr);
        strtab = (char *) (tpnt->dynamic_info[DT_STRTAB] + tpnt->loadaddr);
+       
+       relative_count = tpnt->dynamic_info[DT_RELCONT_IDX];
+       if (relative_count) { /* Optimize the  R_PPC_RELATIVE relocations if possible */
+               Elf32_Addr loadaddr = tpnt->loadaddr;
+               rel_size -= relative_count;
+               --rpnt;
+               do {     /* PowerPC handles pre increment/decrement better */ 
+                       Elf32_Addr *const reloc_addr = (void *) (loadaddr + (++rpnt)->r_offset);
+
+                       *reloc_addr =  loadaddr + rpnt->r_addend;
+               } while (--relative_count);
+       }
 
          for (i = 0; i < rel_size; i++, rpnt++) {
                int res;