FreeBSD/libexec/rtld-elf/powerpc/reloc.c
/*
 * Update the value of a PLT jump slot. Branch directly to the target if
 * it is within +/- 32Mb, otherwise go indirectly via the pltcall
 * trampoline call and jump table.
 */
Update the value of a PLT jump slot. Branch directly to the target if
it is within +/- 32Mb, otherwise go indirectly via the pltcall
trampoline call and jump table.
Update the value of a PLT jump slot . Branch directly to the target if it is within + / - 32Mb otherwise go indirectly via the pltcall trampoline call and jump table .
Elf_Addr
reloc_jmpslot(Elf_Addr *wherep, Elf_Addr target, const Obj_Entry *defobj,
	      const Obj_Entry *obj, const Elf_Rel *rel)
{
	Elf_Addr offset;
	const Elf_Rela *rela = (const Elf_Rela *) rel;
	dbg(" reloc_jmpslot: where=%p, target=%p",
	    (void *)wherep, (void *)target);
	offset = target - (Elf_Addr)wherep;
	if (abs((int)offset) < 32*1024*1024) {     
		*wherep = 0x48000000 | (offset & 0x03fffffc);
		__syncicache(wherep, 4);
	} else {
		Elf_Addr *pltcall, *jmptab;
		int distance;
		int N = obj->pltrelasize / sizeof(Elf_Rela);
		int reloff = rela - obj->pltrela;
		if (reloff < 0)
			return (-1);
		pltcall = obj->pltgot;
		dbg(" reloc_jmpslot: indir, reloff=%x, N=%x\n",
		    reloff, N);
		jmptab = obj->pltgot + JMPTAB_BASE(N);
		jmptab[reloff] = target;
		mb(); 
		if (reloff < PLT_EXTENDED_BEGIN) {
			distance = (Elf_Addr)pltcall - (Elf_Addr)(wherep + 1);
			wherep[1] = 0x48000000 | (distance & 0x03fffffc);
			__syncicache(wherep, 8);
		}
	}
	return (target);
}
Elf_Addr reloc_jmpslot ( Elf_Addr * wherep , Elf_Addr target , const Obj_Entry * defobj , const Obj_Entry * obj , const Elf_Rel * rel ) { Elf_Addr offset ; const Elf_Rela * rela = ( const Elf_Rela * ) rel ; dbg ( " " , ( void * ) wherep , ( void * ) target ) ; offset = target - ( Elf_Addr ) wherep ; if ( abs ( ( int ) offset ) < 32 * 1024 * 1024 ) { * wherep = 0x48000000 | ( offset & 0x03fffffc ) ; __syncicache ( wherep , 4 ) ; } else { Elf_Addr * pltcall , * jmptab ; int distance ; int N = obj -> pltrelasize / sizeof ( Elf_Rela ) ; int reloff = rela - obj -> pltrela ; if ( reloff < 0 ) return ( -1 ) ; pltcall = obj -> pltgot ; dbg ( " \n " , reloff , N ) ; jmptab = obj -> pltgot + JMPTAB_BASE ( N ) ; jmptab [ reloff ] = target ; mb ( ) ; if ( reloff < PLT_EXTENDED_BEGIN ) { distance = ( Elf_Addr ) pltcall - ( Elf_Addr ) ( wherep + 1 ) ; wherep [ 1 ] = 0x48000000 | ( distance & 0x03fffffc ) ; __syncicache ( wherep , 8 ) ; } } return ( target ) ; }
Update the value of a PLT jump slot.
Update the value of a PLT jump slot .
/*
	 * At the PLT entry pointed at by `wherep', construct
	 * a direct transfer to the now fully resolved function
	 * address.
	 */ /* inside 32MB? */ /* b    value   # branch directly */ /* Order jmptab update before next changes */ /* for extended PLT entries, we keep the old code */ /* li   r11,reloff */ /* b    pltcall  # use indirect pltcall routine */ /* first instruction same as before */