[Date Prev][Date Next] [Thread Prev][Thread Next] [Date Index] [Thread Index]

X Strike Force SVN commit: rev 452 - branches/4.3.0/sid/debian/patches



Author: daniel
Date: 2003-08-28 02:36:42 -0500 (Thu, 28 Aug 2003)
New Revision: 452

Modified:
   branches/4.3.0/sid/debian/patches/000_stolen_from_HEAD.diff
Log:
* debian/patches/000_stolen_from_HEAD.diff: add support for missing ia64
  relocations 134 and 135, thus uncrippling the ELF module loader.

debian/changelog entry should get pulled back with the rest of the -11 stuff,
so I'm not logging it here. Matt tells me that pre1v1 + this change works, but
4.2.1-x doesn't. Wa-hey.


Modified: branches/4.3.0/sid/debian/patches/000_stolen_from_HEAD.diff
===================================================================
--- branches/4.3.0/sid/debian/patches/000_stolen_from_HEAD.diff	2003-08-28 03:19:37 UTC (rev 451)
+++ branches/4.3.0/sid/debian/patches/000_stolen_from_HEAD.diff	2003-08-28 07:36:42 UTC (rev 452)
@@ -4,6 +4,7 @@
   * Fix segfaults in rendition and trident drivers.
   * Drivers shouldn't have to care about recolouring ARGB cursors.
   * Fix Xv regression in trident driver.
+  * Implement two missing relocations in the ia64 module loader.
 
 diff -urN xc.orig/config/imake/imake.c xc/config/imake/imake.c
 --- xc.orig/config/imake/imake.c	2002-12-17 09:48:27.000000000 +1100
@@ -330,3 +331,232 @@
      if (ScreenPriv->PalettedCursor) {
  	xColorItem sourceColor, maskColor;
  	ColormapPtr pmap = ScreenPriv->pInstalledMap;
+diff -u -r1.49 -r1.55
+--- xc/programs/Xserver/hw/xfree86/loader/elfloader.c	2003/01/24 17:26:35	1.49
++++ xc/programs/Xserver/hw/xfree86/loader/elfloader.c	2003/06/18 16:17:41	1.55
+@@ -60,6 +60,69 @@
+ #endif
+ */
+ 
++#if defined(__ia64__)
++
++/*
++ * R_IA64_LTOFF22X and R_IA64_LDXMOV are relocation optimizations for
++ * IA64. Conforming implementations must recognize them and may either
++ * implement the optimization or may fallback to previous
++ * non-optimized behavior by treating R_IA64_LTOFF22X as a
++ * R_IA64_LTOFF22 and ignoring R_IA64_LDXMOV. The
++ * IA64_LDX_OPTIMIZATION conditional controls the fallback behavior,
++ * if defined the optimizations are performed.
++ *
++ * To implement the optimization we want to change is the sequence on
++ * the left to that on the right, without regard to any intervening
++ * instructions:
++ * 
++ * 1)  addl    t1=@ltoff(var),gp    ==>    addl    t1=@gprel(var),gp
++ * 2)  ld8     t2=[t1]              ==>    mov     t2=t1
++ * 3)  ld8     loc0=[t2]            ==>    ld8     loc0=[t2]
++ * 
++ * The relocations that match the above instructions are:
++ * 
++ * 1)  R_IA64_LTOFF22               ==>    R_IA64_LTOFF22X
++ * 2)  --                           ==>    R_IA64_LDXMOV
++ * 3)  --                           ==>    --
++ *
++ * First lets look at left hand column to understand the original
++ * mechanism. The virtual address of a symbol is stored in the GOT,
++ * when that symbol is referenced the following sequence occurs,
++ * instruction 1 loads the address of the GOT entry containing the
++ * virtural address of the symbol into t1. Instruction 2 loads the
++ * virtual address of the symbol into t2 by dereferencing t1. Finally
++ * the symbol is loaded in instruction 3 by dereferencing its virtual
++ * address in t2.
++ * 
++ * The optimization that LTOFF22X/LDXMOV introduces is based on the
++ * observation we are doing an extra load (instruction 2) if we can
++ * generate the virtual address for the symbol without doing a lookup in
++ * the GOT. This is possible if the virtual address of the symbol can be
++ * computed via GP relative addressing. In other words the virtual
++ * address of the symbol is a fixed offset from the GP. This fixed offset
++ * must be within the limits of the signed 22 bit immediate offset in the
++ * ld8 instruction, otherwise the original indirect GOT lookup must be
++ * performed (LTOFF22).
++ * 
++ * If we can use GP relative addressing for the symbol then the
++ * instruction that loaded the virtual address of the symbol into t2 must
++ * also be patched, hence the introduction of the LDXMOV relocation. The
++ * LDXMOV essentially turns the GOT lookup into a no-op by changing the
++ * ld8 into a register move that preserves the register location of the
++ * symbol's virtual address (e.g. t2).
++ * 
++ * The important point to recognize when implementing the LTOFF22X/LDXMOV
++ * optimization is that relocations are interdependent, the LDXMOV is
++ * only applied if the LTOFF22X is applied. It is also worth noting that
++ * there is no relationship between LDXMOV relocations and LTOFF22X in
++ * the ELF relocation section other than they share the same
++ * symbol+addend value.
++ */
++
++#define IA64_LDX_OPTIMIZATION 1
++#endif
++
++
+ #ifndef UseMMAP
+ # if defined (__ia64__) || defined (__sparc__)
+ #  define MergeSectionAlloc
+@@ -296,7 +359,8 @@
+ static void ELFCreatePLT(ELFModulePtr);
+ enum ia64_operand {
+     IA64_OPND_IMM22,
+-    IA64_OPND_TGT25C
++    IA64_OPND_TGT25C,
++    IA64_OPND_LDXMOV
+ };
+ static void IA64InstallReloc(unsigned long *, int, enum ia64_operand, long);
+ #endif /*__ia64__*/
+@@ -1110,6 +1174,25 @@
+ 	if (value << 39 >> 39 != value || (value & 0xf))
+ 	    ErrorF("Relocation %016lx truncated to fit into TGT25C\n", value);
+ 	break;
++#ifdef IA64_LDX_OPTIMIZATION
++    case IA64_OPND_LDXMOV:
++        /*
++         * Convert "ld8 t2=[t1]" to "mov t2=t1" which is really "add t2=0,t1"
++         * Mask all but the r3,r1,qp fields, 
++	 * then OR in the ALU opcode = 8 into the opcode field [40:37]
++	 * 
++	 * Mask for the r3,r1,qp bit fields [26:20][12:6][5:0] = 0x7f01fff,
++	 * This mask negated only within the 41 bit wide instruction and
++	 * shifted left by 5 for the bundle template is 0x3FFF01FC0000
++	 *
++	 * opcode field [40:37] with a value of 8 is 0x10000000000
++	 * shifted left by 5 for the bundle template is 0x200000000000
++	 *
++	 */
++        data &= ~(0x3FFF01FC0000 << slot);
++        data |=  (0x200000000000 << slot);
++        break;
++#endif
+     default:
+ 	FatalError("Unhandled operand in IA64InstallReloc()\n");
+     }
+@@ -2055,6 +2138,9 @@
+ # 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));
+@@ -2207,6 +2293,90 @@
+ 		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__)
+@@ -2293,7 +2463,7 @@
+ 	}   
+ #endif
+ #if defined(__ia64__)
+-	if (ELF_R_TYPE(rel[i].r_info) == R_IA64_LTOFF22
++	if (ELF_R_TYPE(rel[i].r_info) == R_IA64_LTOFF22 || ELF_R_TYPE(rel[i].r_info) == R_IA64_LTOFF22X
+ 	    || ELF_R_TYPE(rel[i].r_info) == R_IA64_LTOFF_FPTR22) {
+ 	    ElfAddGOT(elffile,&rel[i]);
+ 	}
+@@ -2437,7 +2607,8 @@
+ 	       || !strcmp(lookup[i].symName, ".comment")
+ 	       || !strcmp(lookup[i].symName, ".note")
+ 	       ) {
+-	    memmove(&(lookup[i]), &(lookup[i+1]), (l-- - i) * sizeof (LOOKUP));
++	    memmove(&(lookup[i]), &(lookup[i+1]), (l - i) * sizeof (LOOKUP));
++	    memmove(&(secttable[i]), &(secttable[i+1]), (l-- - i) * sizeof (unsigned short));
+ 	}
+     }
+     return lookup;



Reply to: