ErrorF("Elf_RelocateEntry() Unsupported relocation type %d\n", (int)ELF_R_TYPE(rel->r_info));
ErrorF("Elf_RelocateEntry() \"%s\" Unsupported relocation " "type %d (0x%x)\n", ElfGetSymbolName(elffile, ELF_R_SYM(rel->r_info)), (int)ELF_R_TYPE(rel->r_info), (int)ELF_R_TYPE(rel->r_info));
Elf_RelocateEntry(ELFModulePtr elffile, Elf_Word secn, Elf_Rel_t *rel,		  int force){    unsigned char *secp = elffile->saddr[secn];#if !defined(__ia64__)    unsigned int *dest32;	/* address of the 32 bit place being modified */#endif#if defined(__powerpc__) || defined(__sparc__)    unsigned short *dest16;	/* address of the 16 bit place being modified */#endif#if defined(__sparc__)    unsigned char *dest8;	/* address of the 8 bit place being modified */    unsigned long *dest64;#endif#if defined(__alpha__)    unsigned int *dest32h;	/* address of the high 32 bit place being modified */    unsigned long *dest64;    unsigned short *dest16;#endif#if  defined(__AMD64__)    unsigned long *dest64;    int *dest32s;#endif#if defined(__ia64__)    unsigned long *dest64;    unsigned long *dest128;#endif    Elf_Addr symval = 0;	/* value of the indicated symbol */#ifdef ELFDEBUG    ELFDEBUG("%lx %d %d\n", (unsigned long)rel->r_offset,	     ELF_R_SYM(rel->r_info), ELF_R_TYPE(rel->r_info));# if defined(__powerpc__) || \    defined(__mc68000__) || \    defined(__alpha__) || \    defined(__sparc__) || \    defined(__ia64__) || \    defined(__AMD64__)    ELFDEBUG("%lx", rel->r_addend);# endif    ELFDEBUG("\n");#endif /*ELFDEBUG*/#if defined(__alpha__)	    if (ELF_R_SYM(rel->r_info)		&& ELF_R_TYPE(rel->r_info) != R_ALPHA_GPDISP)#else	    if (ELF_R_SYM(rel->r_info))#endif    {	symval = ElfGetSymbolValue(elffile, ELF_R_SYM(rel->r_info));	if (symval == 0) {	    if (force) {		symval = (Elf_Addr) & LoaderDefaultFunc;	    } else {#ifdef ELFDEBUG		ELFDEBUG("***Unable to resolve symbol %s\n",			 ElfGetSymbolName(elffile, ELF_R_SYM(rel->r_info)));#endif		return ElfDelayRelocation(elffile, secn, rel);	    }	}    }    switch (ELF_R_TYPE(rel->r_info)) {#if defined(i386)    case R_386_32:	dest32 = (unsigned int *)(secp + rel->r_offset);# ifdef ELFDEBUG	ELFDEBUG("R_386_32\t");	ELFDEBUG("dest32=%p\t", (void *)dest32);	ELFDEBUG("*dest32=%8.8x\t", (unsigned int)*dest32);# endif	*dest32 = symval + (*dest32);	/* S + A */# ifdef ELFDEBUG	ELFDEBUG("*dest32=%8.8x\n", (unsigned int)*dest32);# endif	break;    case R_386_PC32:	dest32 = (unsigned int *)(secp + rel->r_offset);# ifdef ELFDEBUG	ELFDEBUG("R_386_PC32 %s\t",		 ElfGetSymbolName(elffile, ELF_R_SYM(rel->r_info)));	ELFDEBUG("secp=%p\t", secp);	ELFDEBUG("symval=%lx\t", (unsigned long)symval);	ELFDEBUG("dest32=%p\t", (void *)dest32);	ELFDEBUG("*dest32=%8.8x\t", (unsigned int)*dest32);# endif	*dest32 = symval + (*dest32) - (Elf_Addr) dest32;	/* S + A - P */# ifdef ELFDEBUG	ELFDEBUG("*dest32=%8.8x\n", (unsigned int)*dest32);# endif	break;#endif /* i386 */#if defined(__AMD64__)    case R_X86_64_32:	dest32 = (unsigned int *)(secp + rel->r_offset);# ifdef ELFDEBUG	ELFDEBUG("R_X86_32\t");	ELFDEBUG("dest32=%x\t", dest32);	ELFDEBUG("*dest32=%8.8lx\t", *dest32);	ELFDEBUG("r_addend=%lx\t", rel->r_addend);# endif	*dest32 = symval + rel->r_addend + (*dest32);	/* S + A */# ifdef ELFDEBUG	ELFDEBUG("*dest32=%8.8lx\n", *dest32);# endif	break;    case R_X86_64_32S:	dest32s = (int *)(secp + rel->r_offset);# ifdef ELFDEBUG	ELFDEBUG("R_X86_64_32\t");	ELFDEBUG("dest32s=%x\t", dest32s);	ELFDEBUG("*dest32s=%8.8lx\t", *dest32s);	ELFDEBUG("r_addend=%lx\t", rel->r_addend);# endif	*dest32s = symval + rel->r_addend + (*dest32s);	/* S + A */# ifdef ELFDEBUG	ELFDEBUG("*dest32s=%8.8lx\n", *dest32s);# endif	break;    case R_X86_64_PC32:	dest32 = (unsigned int *)(secp + rel->r_offset);# ifdef ELFDEBUG	ELFDEBUG("R_X86_64_PC32 %s\t",		 ElfGetSymbolName(elffile, ELF_R_SYM(rel->r_info)));	ELFDEBUG("secp=%x\t", secp);	ELFDEBUG("symval=%lx\t", symval);	ELFDEBUG("dest32=%x\t", dest32);	ELFDEBUG("*dest32=%8.8lx\t", *dest32);	ELFDEBUG("r_addend=%lx\t", rel->r_addend);# endif	*dest32 = symval + rel->r_addend + (*dest32) - (Elf_Addr) dest32;	/* S + A - P */# ifdef ELFDEBUG	ELFDEBUG("*dest32=%8.8lx\n", *dest32);# endif	break;    case R_X86_64_64:	dest64 = (unsigned long *)(secp + rel->r_offset);# ifdef ELFDEBUG	ELFDEBUG("R_AMD64_64\t");	ELFDEBUG("dest64=%x\t", dest64);	ELFDEBUG("*dest64=%8.8lx\t", *dest64);	ELFDEBUG("r_addend=%lx\t", rel->r_addend);# endif	*dest64 = symval + rel->r_addend + (*dest64);	/* S + A */# ifdef ELFDEBUG	ELFDEBUG("*dest64=%8.8lx\n", *dest64);# endif	break;#endif /* __AMD64__ */#if defined(__alpha__)    case R_ALPHA_NONE:    case R_ALPHA_LITUSE:	break;    case R_ALPHA_REFQUAD:	dest64 = (unsigned long *)(secp + rel->r_offset);	symval = ElfGetSymbolValue(elffile, ELF_R_SYM(rel->r_info));# ifdef ELFDEBUG	ELFDEBUG("R_ALPHA_REFQUAD\t");	ELFDEBUG("dest64=%lx\t", dest64);	ELFDEBUG("*dest64=%8.8lx\t", *dest64);# endif	*dest64 = symval + rel->r_addend + (*dest64);	/* S + A + P */# ifdef ELFDEBUG	ELFDEBUG("*dest64=%8.8lx\n", *dest64);# endif	break;    case R_ALPHA_GPREL32:	{	    dest64 = (unsigned long *)(secp + rel->r_offset);	    dest32 = (unsigned int *)dest64;# ifdef ELFDEBUG	    ELFDEBUG("R_ALPHA_GPREL32 %s\t",		     ElfGetSymbolName(elffile, ELF_R_SYM(rel->r_info)));	    ELFDEBUG("secp=%lx\t", secp);	    ELFDEBUG("symval=%lx\t", symval);	    ELFDEBUG("dest32=%lx\t", dest32);	    ELFDEBUG("*dest32=%8.8x\t", *dest32);# endif	    symval += rel->r_addend;	    symval = ((unsigned char *)symval) -		    ((unsigned char *)elffile->got);# ifdef ELFDEBUG	    ELFDEBUG("symval=%lx\t", symval);# endif	    if ((symval & 0xffffffff00000000) != 0x0000000000000000 &&		(symval & 0xffffffff00000000) != 0xffffffff00000000) {		FatalError("R_ALPHA_GPREL32 symval-got is too large for %s\n",			   ElfGetSymbolName(elffile, ELF_R_SYM(rel->r_info)));	    }	    *dest32 = symval;# ifdef ELFDEBUG	    ELFDEBUG("*dest32=%x\n", *dest32);# endif	    break;	}    case R_ALPHA_GPRELLOW:	{	    dest64 = (unsigned long *)(secp + rel->r_offset);	    dest16 = (unsigned short *)dest64;	    symval += rel->r_addend;	    symval = ((unsigned char *)symval) -		    ((unsigned char *)elffile->got);	    *dest16 = symval;	    break;	}    case R_ALPHA_GPRELHIGH:	{	    dest64 = (unsigned long *)(secp + rel->r_offset);	    dest16 = (unsigned short *)dest64;	    symval += rel->r_addend;	    symval = ((unsigned char *)symval) -		    ((unsigned char *)elffile->got);	    symval = ((long)symval >> 16) + ((symval >> 15) & 1);	    if ((long)symval > 0x7fff || (long)symval < -(long)0x8000) {		FatalError			("R_ALPHA_GPRELHIGH symval-got is too large for %s:%lx\n",			 ElfGetSymbolName(elffile, ELF_R_SYM(rel->r_info)),			 symval);	    }	    *dest16 = symval;	    break;	}    case R_ALPHA_LITERAL:	{	    ELFGotEntryPtr gotent;	    dest32 = (unsigned int *)(secp + rel->r_offset);# ifdef ELFDEBUG	    ELFDEBUG("R_ALPHA_LITERAL %s\t",		     ElfGetSymbolName(elffile, ELF_R_SYM(rel->r_info)));	    ELFDEBUG("secp=%lx\t", secp);	    ELFDEBUG("symval=%lx\t", symval);	    ELFDEBUG("dest32=%lx\t", dest32);	    ELFDEBUG("*dest32=%8.8x\t", *dest32);# endif	    for (gotent = elffile->got_entries; gotent; gotent = gotent->next) {		if (ELF_R_SYM(gotent->rel->r_info) == ELF_R_SYM(rel->r_info)		    && gotent->rel->r_addend == rel->r_addend)		    break;	    }	    /* Set the address in the GOT */	    if (gotent) {		*(unsigned long *)(elffile->got + gotent->offset) =			symval + rel->r_addend;# ifdef ELFDEBUG		ELFDEBUG("Setting gotent[%x]=%lx\t",			 gotent->offset, symval + rel->r_addend);# endif		if ((gotent->offset & 0xffff0000) != 0)		    FatalError("\nR_ALPHA_LITERAL offset %x too large\n",			       gotent->offset);		(*dest32) |= (gotent->offset);	/* The address part is always 0 */	    } else {		unsigned long val;		/* S + A - P >> 2 */		val = ((symval + (rel->r_addend) - (Elf_Addr) dest32));# ifdef ELFDEBUG		ELFDEBUG("S+A-P=%x\t", val);# endif		if ((val & 0xffff0000) != 0xffff0000 &&		    (val & 0xffff0000) != 0x00000000) {		    ErrorF("\nR_ALPHA_LITERAL offset %x too large\n", val);		    break;		}		val &= 0x0000ffff;		(*dest32) |= (val);	/* The address part is always 0 */	    }# ifdef ELFDEBUG	    ELFDEBUG("*dest32=%8.8x\n", *dest32);# endif	    break;	}    case R_ALPHA_GPDISP:	{	    long offset;	    dest32h = (unsigned int *)(secp + rel->r_offset);	    dest32 = (unsigned int *)((secp + rel->r_offset) + rel->r_addend);# ifdef ELFDEBUG	    ELFDEBUG("R_ALPHA_GPDISP %s\t",		     ElfGetSymbolName(elffile, ELF_R_SYM(rel->r_info)));	    ELFDEBUG("secp=%lx\t", secp);	    ELFDEBUG("got=%lx\t", elffile->got);	    ELFDEBUG("dest32=%lx\t", dest32);	    ELFDEBUG("*dest32=%8.8x\t", *dest32);	    ELFDEBUG("dest32h=%lx\t", dest32h);	    ELFDEBUG("*dest32h=%8.8x\t", *dest32h);# endif	    if ((*dest32h >> 26) != 9 || (*dest32 >> 26) != 8) {		ErrorF("***Bad instructions in relocating %s\n",		       ElfGetSymbolName(elffile, ELF_R_SYM(rel->r_info)));	    }	    symval = (*dest32h & 0xffff) << 16 | (*dest32 & 0xffff);	    symval = (symval ^ 0x80008000) - 0x80008000;	    offset = ((unsigned char *)elffile->got -		      (unsigned char *)dest32h);# ifdef ELFDEBUG	    ELFDEBUG("symval=%lx\t", symval);	    ELFDEBUG("got-dest32=%lx\t", offset);# endif	    if ((offset >= 0x7fff8000L) || (offset < -0x80000000L)) {		FatalError("Offset overflow for R_ALPHA_GPDISP\n");	    }	    symval += (unsigned long)offset;# ifdef ELFDEBUG	    ELFDEBUG("symval=%lx\t", symval);# endif	    *dest32 = (*dest32 & 0xffff0000) | (symval & 0xffff);	    *dest32h = (*dest32h & 0xffff0000) |		    (((symval >> 16) + ((symval >> 15) & 1)) & 0xffff);# ifdef ELFDEBUG	    ELFDEBUG("*dest32=%8.8x\t", *dest32);	    ELFDEBUG("*dest32h=%8.8x\n", *dest32h);# endif	    break;	}    case R_ALPHA_HINT:	dest32 = (unsigned int *)((secp + rel->r_offset) + rel->r_addend);# ifdef ELFDEBUG	ELFDEBUG("R_ALPHA_HINT %s\t",		 ElfGetSymbolName(elffile, ELF_R_SYM(rel->r_info)));	ELFDEBUG("secp=%lx\t", secp);	ELFDEBUG("symval=%lx\t", symval);	ELFDEBUG("dest32=%lx\t", dest32);	ELFDEBUG("*dest32=%8.8x\t", *dest32);# endif# ifdef ELFDEBUG	ELFDEBUG("symval=%lx\t", symval);# endif	symval -= (Elf_Addr) (((unsigned char *)dest32) + 4);	if (symval % 4) {	    ErrorF("R_ALPHA_HINT bad alignment of offset\n");	}	symval = symval >> 2;# ifdef ELFDEBUG	ELFDEBUG("symval=%lx\t", symval);# endif	if (symval & 0xffff8000) {# ifdef ELFDEBUG	    ELFDEBUG("R_ALPHA_HINT symval too large\n");# endif	}	*dest32 = (*dest32 & ~0x3fff) | (symval & 0x3fff);# ifdef ELFDEBUG	ELFDEBUG("*dest32=%8.8x\n", *dest32);# endif	break;    case R_ALPHA_GPREL16:	{	    dest64 = (unsigned long *)(secp + rel->r_offset);	    dest16 = (unsigned short *)dest64;	    symval += rel->r_addend;	    symval = ((unsigned char *)symval) -		    ((unsigned char *)elffile->got);	    if ((long)symval > 0x7fff || (long)symval < -(long)0x8000) {		FatalError			("R_ALPHA_GPREL16 symval-got is too large for %s:%lx\n",			 ElfGetSymbolName(elffile, ELF_R_SYM(rel->r_info)),			 symval);	    }	    *dest16 = symval;	    break;	}#endif /* alpha */#if defined(__mc68000__)    case R_68K_32:	dest32 = (unsigned int *)(secp + rel->r_offset);# ifdef ELFDEBUG	ELFDEBUG("R_68K_32\t");	ELFDEBUG("secp=%x\t", secp);	ELFDEBUG("symval=%x\t", symval);	ELFDEBUG("r_addend=%x\t", rel->r_addend);	ELFDEBUG("dest32=%8.8x\t", dest32);	ELFDEBUG("*dest32=%8.8x\n", *dest32);# endif	{	    unsigned long val;	    /* S + A */	    val = symval + (rel->r_addend);# ifdef ELFDEBUG	    ELFDEBUG("S+A=%x\t", val);# endif	    *dest32 = val;	/* S + A */	}# ifdef ELFDEBUG	ELFDEBUG("*dest32=%8.8x\n", *dest32);# endif	break;    case R_68K_PC32:	dest32 = (unsigned int *)(secp + rel->r_offset);# ifdef ELFDEBUG	ELFDEBUG("R_68K_PC32\t");	ELFDEBUG("secp=%x\t", secp);	ELFDEBUG("symval=%x\t", symval);	ELFDEBUG("r_addend=%x\t", rel->r_addend);	ELFDEBUG("dest32=%8.8x\t", dest32);	ELFDEBUG("*dest32=%8.8x\n", *dest32);# endif	{	    unsigned long val;	    /* S + A - P */	    val = symval + (rel->r_addend);	    val -= *dest32;# ifdef ELFDEBUG	    ELFDEBUG("S+A=%x\t", val);	    ELFDEBUG("S+A-P=%x\t", val + (*dest32) - (Elf_Addr) dest32);# endif	    *dest32 = val + (*dest32) - (Elf_Addr) dest32;	/* S + A - P */	}# ifdef ELFDEBUG	ELFDEBUG("*dest32=%8.8x\n", *dest32);# endif	break;#endif /* __mc68000__ */#if defined(__powerpc__)# if defined(PowerMAX_OS)    case R_PPC_DISP24:		/* 11 */	dest32 = (unsigned long *)(secp + rel->r_offset);#  ifdef ELFDEBUG	ELFDEBUG("R_PPC_DISP24 %s\t",		 ElfGetSymbolName(elffile, ELF_R_SYM(rel->r_info)));	ELFDEBUG("secp=%x\t", secp);	ELFDEBUG("symval=%x\t", symval);	ELFDEBUG("dest32=%x\t", dest32);	ELFDEBUG("*dest32=%8.8x\t", *dest32);#  endif	{	    unsigned long val;	    /* S + A - P >> 2 */	    val = ((symval + (rel->r_addend) - (Elf_Addr) dest32));#  ifdef ELFDEBUG	    ELFDEBUG("S+A-P=%x\t", val);#  endif	    val = val >> 2;	    if ((val & 0x3f000000) != 0x3f000000 &&		(val & 0x3f000000) != 0x00000000) {#  ifdef ELFDEBUG		ELFDEBUG("R_PPC_DISP24 offset %x too large\n", val << 2);#  endif		symval = ElfGetPltAddr(elffile, ELF_R_SYM(rel->r_info));		val = ((symval + (rel->r_addend) - (Elf_Addr) dest32));#  ifdef ELFDEBUG		ELFDEBUG("PLT offset is %x\n", val);#  endif		val = val >> 2;		if ((val & 0x3f000000) != 0x3f000000 &&		    (val & 0x3f000000) != 0x00000000)		    FatalError("R_PPC_DISP24 PLT offset %x too large\n",			       val << 2);	    }	    val &= 0x00ffffff;	    (*dest32) |= (val << 2);	/* The address part is always 0 */	    ppc_flush_icache(dest32);	}#  ifdef ELFDEBUG	ELFDEBUG("*dest32=%8.8x\n", *dest32);#  endif	break;    case R_PPC_16HU:		/* 31 */	dest16 = (unsigned short *)(secp + rel->r_offset);#  ifdef ELFDEBUG	dest32 = (unsigned long *)(dest16 - 1);#  endif#  ifdef ELFDEBUG	ELFDEBUG("R_PPC_16HU\t");	ELFDEBUG("secp=%x\t", secp);	ELFDEBUG("symval=%x\t", symval);	ELFDEBUG("r_addend=%x\t", rel->r_addend);	ELFDEBUG("dest16=%x\t", dest16);	ELFDEBUG("*dest16=%8.8x\t", *dest16);	ELFDEBUG("dest32=%8.8x\t", dest32);	ELFDEBUG("*dest32=%8.8x\n", *dest32);#  endif	{	    unsigned short val;	    /* S + A */	    val = ((symval + (rel->r_addend)) & 0xffff0000) >> 16;#  ifdef ELFDEBUG	    ELFDEBUG("uhi16(S+A)=%x\t", val);#  endif	    *dest16 = val;	/* S + A */	    ppc_flush_icache(dest16);	}#  ifdef ELFDEBUG	ELFDEBUG("*dest16=%8.8x\t", *dest16);	ELFDEBUG("*dest32=%8.8x\n", *dest32);#  endif	break;    case R_PPC_32:		/* 32 */	dest32 = (unsigned long *)(secp + rel->r_offset);#  ifdef ELFDEBUG	ELFDEBUG("R_PPC_32\t");	ELFDEBUG("secp=%x\t", secp);	ELFDEBUG("symval=%x\t", symval);	ELFDEBUG("r_addend=%x\t", rel->r_addend);	ELFDEBUG("dest32=%8.8x\t", dest32);	ELFDEBUG("*dest32=%8.8x\n", *dest32);#  endif	{	    unsigned long val;	    /* S + A */	    val = symval + (rel->r_addend);#  ifdef ELFDEBUG	    ELFDEBUG("S+A=%x\t", val);#  endif	    *dest32 = val;	/* S + A */	    ppc_flush_icache(dest32);	}#  ifdef ELFDEBUG	ELFDEBUG("*dest32=%8.8x\n", *dest32);#  endif	break;    case R_PPC_32UA:		/* 33 */	dest32 = (unsigned long *)(secp + rel->r_offset);#  ifdef ELFDEBUG	ELFDEBUG("R_PPC_32UA\t");	ELFDEBUG("secp=%x\t", secp);	ELFDEBUG("symval=%x\t", symval);	ELFDEBUG("r_addend=%x\t", rel->r_addend);	ELFDEBUG("dest32=%8.8x\t", dest32);	ELFDEBUG("*dest32=%8.8x\n", *dest32);#  endif	{	    unsigned long val;	    unsigned char *dest8 = (unsigned char *)dest32;	    /* S + A */	    val = symval + (rel->r_addend);#  ifdef ELFDEBUG	    ELFDEBUG("S+A=%x\t", val);#  endif	    *dest8++ = (val & 0xff000000) >> 24;	    *dest8++ = (val & 0x00ff0000) >> 16;	    *dest8++ = (val & 0x0000ff00) >> 8;	    *dest8++ = (val & 0x000000ff);	    ppc_flush_icache(dest32);	}#  ifdef ELFDEBUG	ELFDEBUG("*dest32=%8.8x\n", *dest32);#  endif	break;    case R_PPC_16H:		/* 34 */	dest16 = (unsigned short *)(secp + rel->r_offset);#  ifdef ELFDEBUG	dest32 = (unsigned long *)(dest16 - 1);#  endif#  ifdef ELFDEBUG	ELFDEBUG("R_PPC_16H\t");	ELFDEBUG("secp=%x\t", secp);	ELFDEBUG("symbol=%s\t",		 ElfGetSymbolName(elffile, ELF_R_SYM(rel->r_info)));	ELFDEBUG("symval=%x\t", symval);	ELFDEBUG("r_addend=%x\t", rel->r_addend);	ELFDEBUG("dest16=%x\t", dest16);	ELFDEBUG("*dest16=%8.8x\t", *dest16);	ELFDEBUG("dest32=%8.8x\t", dest32);	ELFDEBUG("*dest32=%8.8x\n", *dest32);#  endif	{	    unsigned short val;	    unsigned short loval;	    /* S + A */	    val = ((symval + (rel->r_addend)) & 0xffff0000) >> 16;	    loval = (symval + (rel->r_addend)) & 0xffff;	    if (loval & 0x8000) {		/*		 * This is hi16(), instead of uhi16(). Because of this,		 * if the lo16() will produce a negative offset, then		 * we have to increment this part of the address to get		 * the correct final result.		 */		val++;	    }#  ifdef ELFDEBUG	    ELFDEBUG("hi16(S+A)=%x\t", val);#  endif	    *dest16 = val;	/* S + A */	    ppc_flush_icache(dest16);	}#  ifdef ELFDEBUG	ELFDEBUG("*dest16=%8.8x\t", *dest16);	ELFDEBUG("*dest32=%8.8x\n", *dest32);#  endif	break;    case R_PPC_16L:		/* 35 */	dest16 = (unsigned short *)(secp + rel->r_offset);#  ifdef ELFDEBUG	dest32 = (unsigned long *)(dest16 - 1);#  endif#  ifdef ELFDEBUG	ELFDEBUG("R_PPC_16L\t");	ELFDEBUG("secp=%x\t", secp);	ELFDEBUG("symval=%x\t", symval);	ELFDEBUG("r_addend=%x\t", rel->r_addend);	ELFDEBUG("dest16=%x\t", dest16);	ELFDEBUG("*dest16=%8.8x\t", *dest16);	ELFDEBUG("dest32=%8.8x\t", dest32);	ELFDEBUG("*dest32=%8.8x\n", *dest32);#  endif	{	    unsigned short val;	    /* S + A */	    val = (symval + (rel->r_addend)) & 0xffff;#  ifdef ELFDEBUG	    ELFDEBUG("lo16(S+A)=%x\t", val);#  endif	    *dest16 = val;	/* S + A */	    ppc_flush_icache(dest16);	}#  ifdef ELFDEBUG	ELFDEBUG("*dest16=%8.8x\t", *dest16);	ELFDEBUG("*dest32=%8.8x\n", *dest32);#  endif	break;# else /* PowerMAX_OS */	/* Linux PPC */    case R_PPC_ADDR32:		/* 1 */	dest32 = (unsigned int *)(secp + rel->r_offset);	symval = ElfGetSymbolValue(elffile, ELF_R_SYM(rel->r_info));#  ifdef ELFDEBUG	ELFDEBUG("R_PPC_ADDR32\t");	ELFDEBUG("secp=%x\t", secp);	ELFDEBUG("symval=%x\t", symval);	ELFDEBUG("r_addend=%x\t", rel->r_addend);	ELFDEBUG("dest32=%8.8x\t", dest32);	ELFDEBUG("*dest32=%8.8x\n", *dest32);#  endif	{	    unsigned long val;	    /* S + A */	    val = symval + (rel->r_addend);#  ifdef ELFDEBUG	    ELFDEBUG("S+A=%x\t", val);#  endif	    *dest32 = val;	/* S + A */	    ppc_flush_icache(dest32);	}#  ifdef ELFDEBUG	ELFDEBUG("*dest32=%8.8x\n", *dest32);#  endif	break;    case R_PPC_ADDR16_LO:	/* 4 */	dest16 = (unsigned short *)(secp + rel->r_offset);#  ifdef ELFDEBUG	dest32 = (unsigned long *)(dest16 - 1);#  endif#  ifdef ELFDEBUG	ELFDEBUG("R_PPC_ADDR16_LO\t");	ELFDEBUG("secp=%x\t", secp);	ELFDEBUG("symval=%x\t", symval);	ELFDEBUG("r_addend=%x\t", rel->r_addend);	ELFDEBUG("dest16=%x\t", dest16);	ELFDEBUG("*dest16=%8.8x\t", *dest16);#  endif	{	    unsigned short val;	    /* S + A */	    val = (symval + (rel->r_addend)) & 0xffff;#  ifdef ELFDEBUG	    ELFDEBUG("lo16(S+A)=%x\t", val);#  endif	    *dest16 = val;	/* S + A */	    ppc_flush_icache(dest16);	}#  ifdef ELFDEBUG	ELFDEBUG("*dest16=%8.8x\t", *dest16);	ELFDEBUG("*dest32=%8.8x\n", *dest32);#  endif	break;    case R_PPC_ADDR16_HA:	/* 6 */	dest16 = (unsigned short *)(secp + rel->r_offset);#  ifdef ELFDEBUG	dest32 = (unsigned long *)(dest16 - 1);#  endif#  ifdef ELFDEBUG	ELFDEBUG("R_PPC_ADDR16_HA\t");	ELFDEBUG("secp=%x\t", secp);	ELFDEBUG("symval=%x\t", symval);	ELFDEBUG("r_addend=%x\t", rel->r_addend);	ELFDEBUG("dest16=%x\t", dest16);	ELFDEBUG("*dest16=%8.8x\t", *dest16);#  endif	{	    unsigned short val;	    unsigned short loval;	    /* S + A */	    val = ((symval + (rel->r_addend)) & 0xffff0000) >> 16;	    loval = (symval + (rel->r_addend)) & 0xffff;	    if (loval & 0x8000) {		/*		 * This is hi16(), instead of uhi16(). Because of this,		 * if the lo16() will produce a negative offset, then		 * we have to increment this part of the address to get		 * the correct final result.		 */		val++;	    }#  ifdef ELFDEBUG	    ELFDEBUG("hi16(S+A)=%x\t", val);#  endif	    *dest16 = val;	/* S + A */	    ppc_flush_icache(dest16);	}#  ifdef ELFDEBUG	ELFDEBUG("*dest16=%8.8x\t", *dest16);	ELFDEBUG("*dest32=%8.8x\n", *dest32);#  endif	break;    case R_PPC_REL24:		/* 10 */	dest32 = (unsigned int *)(secp + rel->r_offset);#  ifdef ELFDEBUG	ELFDEBUG("R_PPC_REL24 %s\t",		 ElfGetSymbolName(elffile, ELF_R_SYM(rel->r_info)));	ELFDEBUG("secp=%x\t", secp);	ELFDEBUG("symval=%x\t", symval);	ELFDEBUG("dest32=%x\t", dest32);	ELFDEBUG("*dest32=%8.8x\t", *dest32);#  endif	{	    unsigned long val;	    /* S + A - P >> 2 */	    val = ((symval + (rel->r_addend) - (Elf_Addr) dest32));#  ifdef ELFDEBUG	    ELFDEBUG("S+A-P=%x\t", val);#  endif	    val = val >> 2;	    if ((val & 0x3f000000) != 0x3f000000 &&		(val & 0x3f000000) != 0x00000000) {#  ifdef ELFDEBUG		ELFDEBUG("R_PPC_REL24 offset %x too large\n", val << 2);#  endif		symval = ElfGetPltAddr(elffile, ELF_R_SYM(rel->r_info));		val = ((symval + (rel->r_addend) - (Elf_Addr) dest32));#  ifdef ELFDEBUG		ELFDEBUG("PLT offset is %x\n", val);#  endif		val = val >> 2;		if ((val & 0x3f000000) != 0x3f000000 &&		    (val & 0x3f000000) != 0x00000000)		    FatalError("R_PPC_REL24 PLT offset %x too large\n",			       val << 2);	    }	    val &= 0x00ffffff;	    (*dest32) |= (val << 2);	/* The address part is always 0 */	    ppc_flush_icache(dest32);	}#  ifdef ELFDEBUG	ELFDEBUG("*dest32=%8.8x\n", *dest32);#  endif	break;    case R_PPC_REL32:		/* 26 */	dest32 = (unsigned int *)(secp + rel->r_offset);#  ifdef ELFDEBUG	ELFDEBUG("R_PPC_REL32\t");	ELFDEBUG("secp=%x\t", secp);	ELFDEBUG("symval=%x\t", symval);	ELFDEBUG("r_addend=%x\t", rel->r_addend);	ELFDEBUG("dest32=%8.8x\t", dest32);	ELFDEBUG("*dest32=%8.8x\n", *dest32);#  endif	{	    unsigned long val;	    /* S + A - P */	    val = symval + (rel->r_addend);	    val -= *dest32;#  ifdef ELFDEBUG	    ELFDEBUG("S+A=%x\t", val);	    ELFDEBUG("S+A-P=%x\t", val + (*dest32) - (Elf_Addr) dest32);#  endif	    *dest32 = val + (*dest32) - (Elf_Addr) dest32;	/* S + A - P */	    ppc_flush_icache(dest32);	}#  ifdef ELFDEBUG	ELFDEBUG("*dest32=%8.8x\n", *dest32);#  endif	break;# endif	/* PowerMAX_OS */#endif /* __powerpc__ */#ifdef __sparc__    case R_SPARC_NONE:		/*  0 */	break;    case R_SPARC_8:		/*  1 */	dest8 = (unsigned char *)(secp + rel->r_offset);	symval += rel->r_addend;	*dest8 = symval;	break;    case R_SPARC_16:		/*  2 */	dest16 = (unsigned short *)(secp + rel->r_offset);	symval += rel->r_addend;	*dest16 = symval;	break;    case R_SPARC_32:		/*  3 */    case R_SPARC_UA32:		/* 23 */	dest32 = (unsigned int *)(secp + rel->r_offset);	symval += rel->r_addend;	((unsigned char *)dest32)[0] = (unsigned char)(symval >> 24);	((unsigned char *)dest32)[1] = (unsigned char)(symval >> 16);	((unsigned char *)dest32)[2] = (unsigned char)(symval >> 8);	((unsigned char *)dest32)[3] = (unsigned char)(symval);	break;    case R_SPARC_GLOB_DAT:	/* 20 */    case R_SPARC_64:		/* 32 */	dest64 = (unsigned long *)(secp + rel->r_offset);	symval += rel->r_addend;	*dest64 = symval;	break;    case R_SPARC_DISP8:	/*  4 */	dest8 = (unsigned char *)(secp + rel->r_offset);	symval += rel->r_addend;	*dest8 = (symval - (Elf_Addr) dest8);	break;    case R_SPARC_DISP16:	/*  5 */	dest16 = (unsigned short *)(secp + rel->r_offset);	symval += rel->r_addend;	*dest16 = (symval - (Elf_Addr) dest16);	break;    case R_SPARC_DISP32:	/*  6 */	dest32 = (unsigned int *)(secp + rel->r_offset);	symval += rel->r_addend;	*dest32 = (symval - (Elf_Addr) dest32);	break;    case R_SPARC_WDISP30:	/*  7 */	dest32 = (unsigned int *)(secp + rel->r_offset);	symval += rel->r_addend;	*dest32 = ((*dest32 & 0xc0000000) |		   (((symval - (Elf_Addr) dest32) >> 2) & 0x3fffffff));	break;    case R_SPARC_HI22:		/*  9 */	dest32 = (unsigned int *)(secp + rel->r_offset);	symval += rel->r_addend;	*dest32 = (*dest32 & 0xffc00000) | (symval >> 10);	break;    case R_SPARC_LO10:		/* 12 */	dest32 = (unsigned int *)(secp + rel->r_offset);	symval += rel->r_addend;	*dest32 = (*dest32 & ~0x3ff) | (symval & 0x3ff);	break;    case R_SPARC_COPY:		/* 19 */	/* Fix your code...  I'd rather dish out an error here	 * so people will not link together PIC and non-PIC	 * code into a final driver object file.	 */	ErrorF("Elf_RelocateEntry():"	       "  Copy relocs not supported on Sparc.\n");	break;    case R_SPARC_JMP_SLOT:	/* 21 */	dest32 = (unsigned int *)(secp + rel->r_offset);	/* Before we change it the PLT entry looks like:	 *	 * pltent:      sethi   %hi(rela_plt_offset), %g1	 *              b,a     PLT0	 *              nop	 *	 * We change it into:	 *	 * pltent:      sethi   %hi(rela_plt_offset), %g1	 *              sethi   %hi(symval), %g1	 *              jmp     %g1 + %lo(symval), %g0	 */	symval += rel->r_addend;	dest32[2] = 0x81c06000 | (symval & 0x3ff);	__asm __volatile("flush %0 + 0x8"::"r"(dest32));	dest32[1] = 0x03000000 | (symval >> 10);	__asm __volatile("flush %0 + 0x4"::"r"(dest32));	break;    case R_SPARC_RELATIVE:	/* 22 */	dest64 = (unsigned long *)(secp + rel->r_offset);	*dest64 = (unsigned long)secp + rel->r_addend;	break;#endif /*__sparc__*/#ifdef __ia64__    case R_IA64_NONE:	break;    case R_IA64_LTOFF_FPTR22:	if (rel->r_addend)	    FatalError("\nAddend for R_IA64_LTOFF_FPTR22 not supported\n");# ifdef ELFDEBUG	ELFDEBUG("opd=%016lx.%016lx\n",		 ((long *)symval)[0], ((long *)symval)[1]);# endif	/* FALLTHROUGH */    case R_IA64_LTOFF22:#ifndef IA64_LDX_OPTIMIZATION    case R_IA64_LTOFF22X:	/* If not implementing LDXMOV optimization treat LTOFF22X as LTOFF22 */#endif	{	    ELFGotEntryPtr gotent;	    dest128 = (unsigned long *)(secp + (rel->r_offset & ~3));# ifdef ELFDEBUG	    ELFDEBUG("%s %s\t", ELF_R_TYPE(rel->r_info) == R_IA64_LTOFF22 ?		     "R_IA64_LTOFF22" : "R_IA64_LTOFF_FPTR22",		     ElfGetSymbolName(elffile, ELF_R_SYM(rel->r_info)));	    ELFDEBUG("secp=%lx\t", secp);	    ELFDEBUG("symval=%lx\t", symval);	    ELFDEBUG("dest128=%lx\t", dest128);	    ELFDEBUG("slot=%d\n", rel->r_offset & 3);	    ELFDEBUG("*dest128=[%016lx%016lx]\n", dest128[1], dest128[0]);# endif	    for (gotent = elffile->got_entries; gotent; gotent = gotent->next) {		if (ELF_R_SYM(gotent->rel->r_info) == ELF_R_SYM(rel->r_info)		    && gotent->rel->r_addend == rel->r_addend)		    break;	    }	    /* Set the address in the GOT */	    if (gotent) {		*(unsigned long *)(elffile->got + gotent->offset) =			symval + rel->r_addend;# ifdef ELFDEBUG		ELFDEBUG("Setting gotent[%x]=%lx\n",			 gotent->offset, symval + rel->r_addend);# endif		if ((gotent->offset & 0xffe00000) != 0)		    FatalError("\nR_IA64_LTOFF22 offset %x too large\n",			       gotent->offset);		IA64InstallReloc(dest128, rel->r_offset & 3, IA64_OPND_IMM22,				 gotent->offset);	    } else		FatalError("\nCould not find GOT entry\n");	}	break;    case R_IA64_PCREL21B:	{	    ELFPltEntryPtr pltent;	    dest128 = (unsigned long *)(secp + (rel->r_offset & ~3));# ifdef ELFDEBUG	    ELFDEBUG("R_IA64_PCREL21B %s\t",		     ElfGetSymbolName(elffile, ELF_R_SYM(rel->r_info)));	    ELFDEBUG("secp=%lx\t", secp);	    ELFDEBUG("symval=%lx\t", symval);	    ELFDEBUG("opd=%lx.%lx\t", ((long *)symval)[0],		     ((long *)symval)[1]);	    ELFDEBUG("dest128=%lx\t", dest128);	    ELFDEBUG("slot=%d\n", rel->r_offset & 3);	    ELFDEBUG("*dest128=[%016lx%016lx]\n", dest128[1], dest128[0]);# endif	    if (rel->r_addend)		FatalError("\nAddend for PCREL21B not supported\n");	    if (((long *)symval)[1] == (long)elffile->got		&& (((unsigned long)dest128 - ((unsigned long *)symval)[0]) +		    0x2000000 < 0x4000000)) {		/* We can save the travel through PLT */		IA64InstallReloc(dest128, rel->r_offset & 3, IA64_OPND_TGT25C,				 ((unsigned long *)symval)[0] -				 (unsigned long)dest128);		break;	    }	    for (pltent = elffile->plt_entries; pltent; pltent = pltent->next) {		if (ELF_R_SYM(pltent->rel->r_info) == ELF_R_SYM(rel->r_info)		    && pltent->rel->r_addend == rel->r_addend)		    break;	    }	    /* Set the address in the PLT */	    if (pltent == NULL)		FatalError("\nCould not find PLT entry\n");	    else {		unsigned long *p =			(unsigned long *)(elffile->plt + pltent->offset);		unsigned long r =			(unsigned long)symval - (unsigned long)elffile->got;		if (r + 0x200000 >= 0x400000) {		    /* Too far from gp to use the official function descriptor,		     * so we have to make a local one.		     */		    r = pltent->gotoffset;		    memcpy(elffile->got + r, (char *)symval, 16);		}		/* [MMI] addl r15=NNN,r1;; ld8 r16=[r15],8; mov r14=r1;; */		p[0] = 0x410024000200780bUL;		p[1] = 0x84000801c028303cUL;		/* [MIB] ld8 r1=[r15]; mov b6=r16; br.few b6;; */		p[2] = 0x806010181e000811UL;		p[3] = 0x0080006000038004UL;		IA64InstallReloc(p, 0, IA64_OPND_IMM22, r);		IA64InstallReloc(dest128, rel->r_offset & 3, IA64_OPND_TGT25C,				 (unsigned long)p - (unsigned long)dest128);	    }	}	break;    case R_IA64_FPTR64LSB:	dest64 = (unsigned long *)(secp + rel->r_offset);# ifdef ELFDEBUG	ELFDEBUG("R_IA64_FPTR64LSB %s\t",		 ElfGetSymbolName(elffile, ELF_R_SYM(rel->r_info)));	ELFDEBUG("secp=%lx\t", secp);	ELFDEBUG("symval=%lx\t", symval);	ELFDEBUG("dest64=%lx\t", dest64);	ELFDEBUG("opd=%016lx.%016lx\n", ((long *)symval)[0],		 ((long *)symval)[1]);# endif	if (rel->r_addend)	    FatalError("\nAddend not supported for R_IA64_FPTR64LSB\n");	*dest64 = symval;	ia64_flush_cache(dest64);	break;    case R_IA64_DIR64LSB:	dest64 = (unsigned long *)(secp + rel->r_offset);# ifdef ELFDEBUG	ELFDEBUG("R_IA64_DIR64LSB %s\t",		 ElfGetSymbolName(elffile, ELF_R_SYM(rel->r_info)));	ELFDEBUG("secp=%lx\t", secp);	ELFDEBUG("symval=%lx\t", symval);	ELFDEBUG("dest64=%lx\n", dest64);# endif	*dest64 = symval + rel->r_addend;	ia64_flush_cache(dest64);	break;    case R_IA64_PCREL64LSB:	dest64 = (unsigned long *)(secp + rel->r_offset);#ifdef ELFDEBUG	ELFDEBUG("R_IA64_PCREL64LSB %s\t",		 ElfGetSymbolName(elffile, ELF_R_SYM(rel->r_info)));	ELFDEBUG("secp=%lx\t", secp);	ELFDEBUG("symval=%lx\t", symval);	ELFDEBUG("dest64=%lx\n", dest64);#endif	*dest64 = symval + rel->r_addend - (unsigned long)dest64;	break;    case R_IA64_GPREL22:	dest128 = (unsigned long *)(secp + (rel->r_offset & ~3));# ifdef ELFDEBUG	ELFDEBUG("R_IA64_GPREL22 %s\t",		 ElfGetSymbolName(elffile, ELF_R_SYM(rel->r_info)));	ELFDEBUG("secp=%lx\t", secp);	ELFDEBUG("symval=%lx\t", symval);	ELFDEBUG("dest128=%lx\t", dest128);	ELFDEBUG("slot=%d\n", rel->r_offset & 3);	ELFDEBUG("*dest128=[%016lx%016lx]\n", dest128[1], dest128[0]);# endif	IA64InstallReloc(dest128, rel->r_offset & 3, IA64_OPND_IMM22,			 symval + rel->r_addend - (long)elffile->got);	break;#ifdef IA64_LDX_OPTIMIZATION    case R_IA64_LTOFF22X:	{	    ELFGotEntryPtr gotent;	    long gp_offset = symval + rel->r_addend - (long)elffile->got;	    dest128 = (unsigned long *)(secp + (rel->r_offset & ~3));# ifdef ELFDEBUG	    ELFDEBUG("R_IA64_LTOFF22X %s\t",		     ElfGetSymbolName(elffile, ELF_R_SYM(rel->r_info)));	    ELFDEBUG("secp=%lx\t", secp);	    ELFDEBUG("symval=%lx\t", symval);	    ELFDEBUG("dest128=%lx\t", dest128);	    ELFDEBUG("slot=%d\n", rel->r_offset & 3);# endif	    if (gp_offset << 42 >> 42 != gp_offset) {		/* Offset is too large for LTOFF22X, 		 * fallback to using GOT lookup, e.g. LTOFF22. 		 * Note: LDXMOV will fail the same test and will be ignored. */# ifdef ELFDEBUG		ELFDEBUG("gp_offset=%ld too large, using GOT instead (LTOFF22)\n", gp_offset);# endif		for (gotent = elffile->got_entries; gotent;		     gotent = gotent->next) {		    if (ELF_R_SYM(gotent->rel->r_info) ==			ELF_R_SYM(rel->r_info)			&& gotent->rel->r_addend == rel->r_addend)			break;		}		/* Set the address in the GOT */		if (gotent) {		    *(unsigned long *)(elffile->got + gotent->offset) =			    symval + rel->r_addend;# ifdef ELFDEBUG		    ELFDEBUG("Setting gotent[%x]=%lx\n", gotent->offset,			     symval + rel->r_addend);# endif		    if ((gotent->offset & 0xffe00000) != 0)			FatalError("\nR_IA64_LTOFF22 offset %x too large\n",				   gotent->offset);		} else {		    FatalError("\nCould not find GOT entry\n");		}		gp_offset = gotent->offset;	/* Use GOT lookup */	    } else {# ifdef ELFDEBUG		ELFDEBUG("using gp_offset=%ld (LTOFF22X)", gp_offset);# endif	    }	    IA64InstallReloc(dest128, rel->r_offset & 3, IA64_OPND_IMM22,			     gp_offset);	}	break;#endif    case R_IA64_LDXMOV:# ifdef ELFDEBUG	ELFDEBUG("R_IA64_LDXMOV %s\t",		 ElfGetSymbolName(elffile, ELF_R_SYM(rel->r_info)));# endif#ifdef IA64_LDX_OPTIMIZATION	{	    long gp_offset = symval + rel->r_addend - (long)elffile->got;	    dest128 = (unsigned long *)(secp + (rel->r_offset & ~3));	    if (gp_offset << 42 >> 42 != gp_offset) {		/* Offset is too large for LTOFF22X, ignore this relocation */# ifdef ELFDEBUG		ELFDEBUG("offset = %ld too large, ignoring\n", gp_offset);# endif	    } else {# ifdef ELFDEBUG		ELFDEBUG("secp=%lx\t", secp);		ELFDEBUG("symval=%lx\t", symval);		ELFDEBUG("dest128=%lx\t", dest128);		ELFDEBUG("slot=%d\n", rel->r_offset & 3);		ELFDEBUG("offset=%ld\n", gp_offset);		ELFDEBUG("*dest128=[%016lx%016lx]\n", dest128[1], dest128[0]);# endif		IA64InstallReloc(dest128, rel->r_offset & 3, IA64_OPND_LDXMOV,				 0);	    }	}#endif	break;#endif /*__ia64__*/#if defined(__arm__)    case R_ARM_ABS32:	dest32 = (unsigned int *)(secp + rel->r_offset);# ifdef ELFDEBUG	ELFDEBUG("R_ARM_ABS32\t");	ELFDEBUG("dest32=%x\t", dest32);	ELFDEBUG("*dest32=%8.8lx\t", *dest32);# endif	*dest32 = symval + (*dest32);	/* S + A */# ifdef ELFDEBUG	ELFDEBUG("*dest32=%8.8lx\n", *dest32);# endif#if defined(__NetBSD__)            arm_sync_icache(dest32, 4);#endif	break;    case R_ARM_REL32:	dest32 = (unsigned int *)(secp + rel->r_offset);# ifdef ELFDEBUG	{	    char *namestr;	    ELFDEBUG("R_ARM_REL32 %s\t",		     namestr =		     ElfGetSymbolName(elffile, ELF_R_SYM(rel->r_info)));	    xf86loaderfree(namestr);	    ELFDEBUG("secp=%x\t", secp);	    ELFDEBUG("symval=%lx\t", symval);	    ELFDEBUG("dest32=%x\t", dest32);	    ELFDEBUG("*dest32=%8.8lx\t", *dest32);	}# endif	*dest32 = symval + (*dest32) - (Elf_Addr) dest32;	/* S + A - P */# ifdef ELFDEBUG	ELFDEBUG("*dest32=%8.8lx\n", *dest32);# endif#if defined(__NetBSD__)            arm_sync_icache(dest32, 4);#endif	break;    case R_ARM_PC24:	{	    unsigned long val;	    dest32 = (unsigned int *)(secp + rel->r_offset);	    val = (*dest32 & 0x00ffffff) << 2;	    val = symval - (unsigned long)dest32 + val;	    val >>= 2;	    *dest32 = (*dest32 & 0xff000000) | (val & 0x00ffffff);#ifdef NOTYET	    arm_flush_cache(dest32);#else#if defined(__NetBSD__)            arm_sync_icache(dest32, 4);#endif#endif	}	break;#endif /* (__arm__) */    default:	ErrorF("Elf_RelocateEntry() Unsupported relocation type %d\n",	       (int)ELF_R_TYPE(rel->r_info));	break;    }    return 0;}