Author: branden Date: 2003-08-27 04:18:11 -0500 (Wed, 27 Aug 2003) New Revision: 445
Modified: trunk/debian/changelog trunk/debian/patches/000_stolen_from_HEAD.diff trunk/debian/patches/067_nonexecutable_malloced_mem.diff Log: Backport support for new IA-64 relocation types from post-4.3.0 CVS HEAD (thanks, Matthew Wilcox). (Closes: #206929) - debian/patches/000_stolen_from_HEAD.diff: updated - debian/patches/067_nonexecutable_malloced_mem.diff: resync Modified: trunk/debian/changelog =================================================================== --- trunk/debian/changelog 2003-08-27 07:53:29 UTC (rev 444) +++ trunk/debian/changelog 2003-08-27 09:18:11 UTC (rev 445) @@ -58,8 +58,13 @@ * debian/po/fr.po: updated French translations (thanks, Christian Perrier) (Closes: #207239) - -- Branden Robinson <[EMAIL PROTECTED]> Wed, 27 Aug 2003 02:50:39 -0500 + * Backport support for new IA-64 relocation types from post-4.3.0 CVS + HEAD (thanks, Matthew Wilcox). (Closes: #206929) + - patch #000_stolen_from_HEAD: updated + - patch #067: resync + -- Branden Robinson <[EMAIL PROTECTED]> Wed, 27 Aug 2003 04:16:02 -0500 + xfree86 (4.2.1-10) unstable; urgency=medium * patch #000_stolen_from_HEAD_xlib: fix for buffer overflow in Modified: trunk/debian/patches/000_stolen_from_HEAD.diff =================================================================== --- trunk/debian/patches/000_stolen_from_HEAD.diff 2003-08-27 07:53:29 UTC (rev 444) +++ trunk/debian/patches/000_stolen_from_HEAD.diff 2003-08-27 09:18:11 UTC (rev 445) @@ -232,6 +232,10 @@ + Skip unexpected data in QueryFormats. Deal with broken X servers a bit better. (Keith Packard) +(xc/programs/Xserver/hw/xfree86/loader/elfloader.c): + + Backport support for new IA-64 relocation types from post-4.3.0 CVS + HEAD. (Matthew Wilcox) + Index: xc/nls/XI18N_OBJS/Imakefile =================================================================== RCS file: /cvs/xc/nls/XI18N_OBJS/Imakefile,v @@ -3035,91 +3039,6 @@ #define R_ALPHA_IMMED_GP_HI32 20 #define R_ALPHA_IMMED_SCN_HI32 21 #define R_ALPHA_IMMED_BR_HI32 22 ---- xc/programs/Xserver/hw/xfree86/loader/elfloader.c.orig 2002-01-14 13:16:52.000000000 -0500 -+++ xc/programs/Xserver/hw/xfree86/loader/elfloader.c 2003-02-20 01:06:05.000000000 -0500 -@@ -1103,7 +1106,9 @@ - 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 -@@ -1113,6 +1118,7 @@ - #if defined(__alpha__) - unsigned int *dest32h; /* address of the high 32 bit place being modified */ - unsigned long *dest64; -+ unsigned short *dest16; - #endif - #if defined(__ia64__) - unsigned long *dest64; -@@ -1376,6 +1382,51 @@ - ELFDEBUG( "*dest32=%8.8x\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_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__) -@@ -2834,9 +2897,11 @@ - ELFCollectSections(elffile, 0, &totalsize, &maxalign); - - if( elffile->straddr == NULL || elffile->strsize == 0 ) { -+#if 0 - ErrorF("No symbols found in this module\n"); -+#endif - ELFUnloadModule(elffile); -- return NULL; -+ return (void *) -1L; - } - - /* --- xc/programs/Xserver/hw/xfree86/loader/loader.c.orig 2001-10-27 22:33:59.000000000 -0500 +++ xc/programs/Xserver/hw/xfree86/loader/loader.c 2003-02-20 01:06:07.000000000 -0500 @@ -838,6 +887,7 @@ @@ -4937,3 +4856,333 @@ UnlockDisplay (dpy); SyncHandle (); Xfree (xData); +--- xc/programs/Xserver/hw/xfree86/loader/elfloader.c~ 2003-08-27 01:52:53.000000000 -0500 ++++ xc/programs/Xserver/hw/xfree86/loader/elfloader.c 2003-08-27 01:53:10.000000000 -0500 +@@ -54,6 +54,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 [EMAIL PROTECTED](var),gp ==> addl [EMAIL PROTECTED](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 +@@ -289,7 +352,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 +@@ -1072,6 +1136,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"); + } +@@ -1103,7 +1186,9 @@ + 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 +@@ -1113,6 +1198,7 @@ + #if defined(__alpha__) + unsigned int *dest32h; /* address of the high 32 bit place being modified */ + unsigned long *dest64; ++ unsigned short *dest16; + #endif + #if defined(__ia64__) + unsigned long *dest64; +@@ -1376,6 +1462,51 @@ + ELFDEBUG( "*dest32=%8.8x\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_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__) +@@ -1903,6 +2034,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)); +@@ -2028,6 +2162,18 @@ + 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 +@@ -2043,6 +2189,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 + + #if defined(__arm__) +@@ -2127,7 +2357,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]); + } +@@ -2271,7 +2501,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; +@@ -2834,9 +3065,11 @@ + ELFCollectSections(elffile, 0, &totalsize, &maxalign); + + if( elffile->straddr == NULL || elffile->strsize == 0 ) { ++#if 0 + ErrorF("No symbols found in this module\n"); ++#endif + ELFUnloadModule(elffile); +- return NULL; ++ return (void *) -1L; + } + + /* Modified: trunk/debian/patches/067_nonexecutable_malloced_mem.diff =================================================================== --- trunk/debian/patches/067_nonexecutable_malloced_mem.diff 2003-08-27 07:53:29 UTC (rev 444) +++ trunk/debian/patches/067_nonexecutable_malloced_mem.diff 2003-08-27 09:18:11 UTC (rev 445) @@ -12,8 +12,8 @@ Not submitted upstream yet. ---- xc/programs/Xserver/hw/xfree86/loader/elfloader.c.orig Mon Apr 8 14:19:55 2002 -+++ xc/programs/Xserver/hw/xfree86/loader/elfloader.c Mon Apr 8 14:19:57 2002 +--- xc/programs/Xserver/hw/xfree86/loader/elfloader.c~ 2003-08-27 01:56:18.000000000 -0500 ++++ xc/programs/Xserver/hw/xfree86/loader/elfloader.c 2003-08-27 01:56:25.000000000 -0500 @@ -23,6 +23,9 @@ * PERFORMANCE OF THIS SOFTWARE. */ @@ -24,7 +24,7 @@ #include <unistd.h> #include <stdlib.h> #ifdef __QNX__ -@@ -2378,6 +2381,18 @@ +@@ -2561,6 +2564,18 @@ ELFDEBUG(".text starts at %lx\n", elffile->text ); #endif elffile->txtsize=SecSize(i); -- To UNSUBSCRIBE, email to [EMAIL PROTECTED] with a subject of "unsubscribe". Trouble? Contact [EMAIL PROTECTED]