FreeBSD/libexec/rtld-elf/powerpc/reloc.c
/*
 * Initialise a PLT slot to the resolving trampoline
 */
Initialise a PLT slot to the resolving trampoline
Initialise a PLT slot to the resolving trampoline
static int
reloc_plt_object(Obj_Entry *obj, const Elf_Rela *rela)
{
	Elf_Word *where = (Elf_Word *)(obj->relocbase + rela->r_offset);
	Elf_Addr *pltresolve, *pltlongresolve, *jmptab;
	Elf_Addr distance;
	int N = obj->pltrelasize / sizeof(Elf_Rela);
	int reloff;
	reloff = rela - obj->pltrela;
	if (reloff < 0)
		return (-1);
	pltlongresolve = obj->pltgot + 5;
	pltresolve = pltlongresolve + 5;
	distance = (Elf_Addr)pltresolve - (Elf_Addr)(where + 1);
	dbg(" reloc_plt_object: where=%p,pltres=%p,reloff=%x,distance=%x",
	    (void *)where, (void *)pltresolve, reloff, distance);
	if (reloff < PLT_EXTENDED_BEGIN) {
		where[0] = 0x39600000 | reloff;
		where[1] = 0x48000000 | (distance & 0x03fffffc);
	} else {
		jmptab = obj->pltgot + JMPTAB_BASE(N);
		jmptab[reloff] = (u_int)pltlongresolve;
		where[0] = 0x3d600000 | _ppc_ha(&jmptab[reloff]);
		where[1] = 0x858b0000 | _ppc_la(&jmptab[reloff]);
		where[2] = 0x7d8903a6;
		where[3] = 0x4e800420;
	}
	return (0);
}
static int reloc_plt_object ( Obj_Entry * obj , const Elf_Rela * rela ) { Elf_Word * where = ( Elf_Word * ) ( obj -> relocbase + rela -> r_offset ) ; Elf_Addr * pltresolve , * pltlongresolve , * jmptab ; Elf_Addr distance ; int N = obj -> pltrelasize / sizeof ( Elf_Rela ) ; int reloff ; reloff = rela - obj -> pltrela ; if ( reloff < 0 ) return ( -1 ) ; pltlongresolve = obj -> pltgot + 5 ; pltresolve = pltlongresolve + 5 ; distance = ( Elf_Addr ) pltresolve - ( Elf_Addr ) ( where + 1 ) ; dbg ( " " , ( void * ) where , ( void * ) pltresolve , reloff , distance ) ; if ( reloff < PLT_EXTENDED_BEGIN ) { where [ 0 ] = 0x39600000 | reloff ; where [ 1 ] = 0x48000000 | ( distance & 0x03fffffc ) ; } else { jmptab = obj -> pltgot + JMPTAB_BASE ( N ) ; jmptab [ reloff ] = ( u_int ) pltlongresolve ; where [ 0 ] = 0x3d600000 | _ppc_ha ( & jmptab [ reloff ] ) ; where [ 1 ] = 0x858b0000 | _ppc_la ( & jmptab [ reloff ] ) ; where [ 2 ] = 0x7d8903a6 ; where [ 3 ] = 0x4e800420 ; } return ( 0 ) ; }
Initialise a PLT slot to the resolving trampoline
Initialise a PLT slot to the resolving trampoline
/* li   r11,reloff  */ /* b    pltresolve  */ /* lis	r11,jmptab[reloff]@ha */ /* lwzu	r12,jmptab[reloff]@l(r11) */ /* mtctr r12 */ /* bctr */ /*
	 * The icache will be sync'd in reloc_plt, which is called
	 * after all the slots have been updated
	 */