From b88abb6c753874d53adae4c22b7fd2b33da32954 Mon Sep 17 00:00:00 2001 From: =?utf8?q?Arkadiusz=20Mi=C5=9Bkiewicz?= Date: Mon, 7 Jun 2004 21:25:24 +0000 Subject: [PATCH] - new Changed files: XFree86-elfloader-linux-non-exec-stack.patch -> 1.1 XFree86-exec-shield-GNU-stack.patch -> 1.1 XFree86-libGL-exec-shield-fixes-v2.patch -> 1.1 --- XFree86-elfloader-linux-non-exec-stack.patch | 41 ++ XFree86-exec-shield-GNU-stack.patch | 314 ++++++++++ XFree86-libGL-exec-shield-fixes-v2.patch | 627 +++++++++++++++++++ 3 files changed, 982 insertions(+) create mode 100644 XFree86-elfloader-linux-non-exec-stack.patch create mode 100644 XFree86-exec-shield-GNU-stack.patch create mode 100644 XFree86-libGL-exec-shield-fixes-v2.patch diff --git a/XFree86-elfloader-linux-non-exec-stack.patch b/XFree86-elfloader-linux-non-exec-stack.patch new file mode 100644 index 0000000..a9fc6f1 --- /dev/null +++ b/XFree86-elfloader-linux-non-exec-stack.patch @@ -0,0 +1,41 @@ +diff -urN xc-old/programs/Xserver/hw/xfree86/loader/elfloader.c xc/programs/Xserver/hw/xfree86/loader/elfloader.c +--- xc-old/programs/Xserver/hw/xfree86/loader/elfloader.c 2003-11-02 03:16:18.000000000 -0500 ++++ xc/programs/Xserver/hw/xfree86/loader/elfloader.c 2003-11-02 03:21:53.000000000 -0500 +@@ -921,7 +921,7 @@ + ErrorF("ELFCreateGOT() Unable to reallocate memory!!!!\n"); + return FALSE; + } +-# if defined(linux) && defined(__ia64__) || defined(__OpenBSD__) ++# if defined(linux) || defined(__OpenBSD__) + { + unsigned long page_size = getpagesize(); + unsigned long round; +@@ -2761,10 +2761,16 @@ + elffile->lsection[j].size = SecSize(i); + elffile->lsection[j].flags = flags; + switch (SecType(i)) { +-#ifdef __OpenBSD__ ++#if defined(linux) || defined(__OpenBSD__) + case SHT_PROGBITS: +- mprotect(elffile->lsection[j].saddr, SecSize(i), +- PROT_READ | PROT_WRITE | PROT_EXEC); ++ { ++ unsigned long page_size = getpagesize(); ++ unsigned long round; ++ ++ round = (unsigned long)elffile->lsection[j].saddr & (page_size -1); ++ mprotect( (char *)elffile->lsection[j].saddr - round, ++ SecSize(i) + round, PROT_READ|PROT_WRITE|PROT_EXEC); ++ } + break; + #endif + case SHT_SYMTAB: +@@ -2959,7 +2965,7 @@ + ErrorF("Unable to allocate ELF sections\n"); + return NULL; + } +-# if defined(linux) && defined(__ia64__) || defined(__OpenBSD__) ++# if defined(linux) || defined(__OpenBSD__) + { + unsigned long page_size = getpagesize(); + unsigned long round; diff --git a/XFree86-exec-shield-GNU-stack.patch b/XFree86-exec-shield-GNU-stack.patch new file mode 100644 index 0000000..3410b11 --- /dev/null +++ b/XFree86-exec-shield-GNU-stack.patch @@ -0,0 +1,314 @@ +diff -urN xc.org/extras/Mesa/src/X86/3dnow_normal.S xc/extras/Mesa/src/X86/3dnow_normal.S +--- xc.org/extras/Mesa/src/X86/3dnow_normal.S 2004-06-07 22:15:49.043413960 +0200 ++++ xc/extras/Mesa/src/X86/3dnow_normal.S 2004-06-07 22:18:46.409450224 +0200 +@@ -834,3 +834,6 @@ + POP_L ( ESI ) + POP_L ( EDI ) + RET ++ ++.section .note.GNU-stack, "", @progbits ++.previous +diff -urN xc.org/extras/Mesa/src/X86/3dnow_xform1.S xc/extras/Mesa/src/X86/3dnow_xform1.S +--- xc.org/extras/Mesa/src/X86/3dnow_xform1.S 2004-06-07 22:15:49.049413048 +0200 ++++ xc/extras/Mesa/src/X86/3dnow_xform1.S 2004-06-07 22:18:46.423448096 +0200 +@@ -420,3 +420,7 @@ + POP_L ( EDI ) + POP_L ( ESI ) + RET ++ ++.section .note.GNU-stack, "", @progbits ++.previous ++ +diff -urN xc.org/extras/Mesa/src/X86/3dnow_xform2.S xc/extras/Mesa/src/X86/3dnow_xform2.S +--- xc.org/extras/Mesa/src/X86/3dnow_xform2.S 2004-06-07 22:15:49.054412288 +0200 ++++ xc/extras/Mesa/src/X86/3dnow_xform2.S 2004-06-07 22:18:46.440445512 +0200 +@@ -461,3 +461,6 @@ + POP_L ( EDI ) + POP_L ( ESI ) + RET ++ ++.section .note.GNU-stack, "", @progbits ++.previous +diff -urN xc.org/extras/Mesa/src/X86/3dnow_xform3.S xc/extras/Mesa/src/X86/3dnow_xform3.S +--- xc.org/extras/Mesa/src/X86/3dnow_xform3.S 2004-06-07 22:15:49.080408336 +0200 ++++ xc/extras/Mesa/src/X86/3dnow_xform3.S 2004-06-07 22:18:46.450443992 +0200 +@@ -545,3 +545,6 @@ + POP_L ( EDI ) + POP_L ( ESI ) + RET ++ ++.section .note.GNU-stack, "", @progbits ++.previous +diff -urN xc.org/extras/Mesa/src/X86/3dnow_xform4.S xc/extras/Mesa/src/X86/3dnow_xform4.S +--- xc.org/extras/Mesa/src/X86/3dnow_xform4.S 2004-06-07 22:15:49.099405448 +0200 ++++ xc/extras/Mesa/src/X86/3dnow_xform4.S 2004-06-07 22:18:46.467441408 +0200 +@@ -554,3 +554,6 @@ + POP_L ( EDI ) + POP_L ( ESI ) + RET ++ ++.section .note.GNU-stack, "", @progbits ++.previous +diff -urN xc.org/extras/Mesa/src/X86/common_x86_asm.S xc/extras/Mesa/src/X86/common_x86_asm.S +--- xc.org/extras/Mesa/src/X86/common_x86_asm.S 2004-06-07 22:15:49.149397848 +0200 ++++ xc/extras/Mesa/src/X86/common_x86_asm.S 2004-06-07 22:18:46.480439432 +0200 +@@ -235,3 +235,6 @@ + RET + + #endif ++ ++.section .note.GNU-stack, "", @progbits ++.previous +diff -urN xc.org/extras/Mesa/src/X86/glapi_x86.S xc/extras/Mesa/src/X86/glapi_x86.S +--- xc.org/extras/Mesa/src/X86/glapi_x86.S 2004-06-07 22:15:49.180393136 +0200 ++++ xc/extras/Mesa/src/X86/glapi_x86.S 2004-06-07 22:18:46.512434568 +0200 +@@ -4859,3 +4859,6 @@ + + + #endif /* __WIN32__ */ ++ ++.section .note.GNU-stack, "", @progbits ++.previous +diff -urN xc.org/extras/Mesa/src/X86/mmx_blend.S xc/extras/Mesa/src/X86/mmx_blend.S +--- xc.org/extras/Mesa/src/X86/mmx_blend.S 2004-06-07 22:15:49.182392832 +0200 ++++ xc/extras/Mesa/src/X86/mmx_blend.S 2004-06-07 22:26:26.487507728 +0200 +@@ -363,3 +363,6 @@ + + #include "mmx_blendtmp.h" + ++.section .note.GNU-stack, "", @progbits ++.previous ++ +diff -urN xc.org/extras/Mesa/src/X86/sse_normal.S xc/extras/Mesa/src/X86/sse_normal.S +--- xc.org/extras/Mesa/src/X86/sse_normal.S 2004-06-07 22:15:49.260380976 +0200 ++++ xc/extras/Mesa/src/X86/sse_normal.S 2004-06-07 22:18:46.527432288 +0200 +@@ -249,3 +249,6 @@ + POP_L ( ESI ) + RET + #undef FRAME_OFFSET ++ ++.section .note.GNU-stack, "", @progbits ++.previous +diff -urN xc.org/extras/Mesa/src/X86/sse_xform1.S xc/extras/Mesa/src/X86/sse_xform1.S +--- xc.org/extras/Mesa/src/X86/sse_xform1.S 2004-06-07 22:15:49.267379912 +0200 ++++ xc/extras/Mesa/src/X86/sse_xform1.S 2004-06-07 22:18:46.578424536 +0200 +@@ -430,3 +430,6 @@ + POP_L( ESI ) + RET + #undef FRAME_OFFSET ++ ++.section .note.GNU-stack, "", @progbits ++.previous +diff -urN xc.org/extras/Mesa/src/X86/sse_xform2.S xc/extras/Mesa/src/X86/sse_xform2.S +--- xc.org/extras/Mesa/src/X86/sse_xform2.S 2004-06-07 22:15:49.269379608 +0200 ++++ xc/extras/Mesa/src/X86/sse_xform2.S 2004-06-07 22:18:46.604420584 +0200 +@@ -449,3 +449,6 @@ + POP_L( ESI ) + RET + #undef FRAME_OFFSET ++ ++.section .note.GNU-stack, "", @progbits ++.previous +diff -urN xc.org/extras/Mesa/src/X86/sse_xform3.S xc/extras/Mesa/src/X86/sse_xform3.S +--- xc.org/extras/Mesa/src/X86/sse_xform3.S 2004-06-07 22:15:49.284377328 +0200 ++++ xc/extras/Mesa/src/X86/sse_xform3.S 2004-06-07 22:18:46.612419368 +0200 +@@ -495,3 +495,6 @@ + POP_L( ESI ) + RET + #undef FRAME_OFFSET ++ ++.section .note.GNU-stack, "", @progbits ++.previous +diff -urN xc.org/extras/Mesa/src/X86/sse_xform4.S xc/extras/Mesa/src/X86/sse_xform4.S +--- xc.org/extras/Mesa/src/X86/sse_xform4.S 2004-06-07 22:15:49.285377176 +0200 ++++ xc/extras/Mesa/src/X86/sse_xform4.S 2004-06-07 22:18:46.617418608 +0200 +@@ -223,3 +223,6 @@ + POP_L( EDI ) + POP_L( ESI ) + RET ++ ++.section .note.GNU-stack, "", @progbits ++.previous +diff -urN xc.org/extras/Mesa/src/X86/x86_cliptest.S xc/extras/Mesa/src/X86/x86_cliptest.S +--- xc.org/extras/Mesa/src/X86/x86_cliptest.S 2004-06-07 22:15:49.303374440 +0200 ++++ xc/extras/Mesa/src/X86/x86_cliptest.S 2004-06-07 22:18:46.621418000 +0200 +@@ -398,3 +398,6 @@ + POP_L( ESI ) + + RET ++ ++.section .note.GNU-stack, "", @progbits ++.previous +diff -urN xc.org/extras/Mesa/src/X86/x86_xform2.S xc/extras/Mesa/src/X86/x86_xform2.S +--- xc.org/extras/Mesa/src/X86/x86_xform2.S 2004-06-07 22:15:49.304374288 +0200 ++++ xc/extras/Mesa/src/X86/x86_xform2.S 2004-06-07 22:18:46.626417240 +0200 +@@ -560,3 +560,6 @@ + POP_L( ESI ) + RET + #undef FRAME_OFFSET ++ ++.section .note.GNU-stack, "", @progbits ++.previous +diff -urN xc.org/extras/Mesa/src/X86/x86_xform3.S xc/extras/Mesa/src/X86/x86_xform3.S +--- xc.org/extras/Mesa/src/X86/x86_xform3.S 2004-06-07 22:15:49.328370640 +0200 ++++ xc/extras/Mesa/src/X86/x86_xform3.S 2004-06-07 22:18:46.641414960 +0200 +@@ -630,3 +630,6 @@ + POP_L( EDI ) + POP_L( ESI ) + RET ++ ++.section .note.GNU-stack, "", @progbits ++.previous +diff -urN xc.org/extras/Mesa/src/X86/x86_xform4.S xc/extras/Mesa/src/X86/x86_xform4.S +--- xc.org/extras/Mesa/src/X86/x86_xform4.S 2004-06-07 22:15:49.358366080 +0200 ++++ xc/extras/Mesa/src/X86/x86_xform4.S 2004-06-07 22:18:46.645414352 +0200 +@@ -663,3 +663,6 @@ + POP_L( EDI ) + POP_L( ESI ) + RET ++ ++.section .note.GNU-stack, "", @progbits ++.previous +diff -urN xc.org/lib/GL/mesa/src/drv/r200/r200_vtxtmp_x86.S xc/lib/GL/mesa/src/drv/r200/r200_vtxtmp_x86.S +--- xc.org/lib/GL/mesa/src/drv/r200/r200_vtxtmp_x86.S 2004-06-07 22:15:15.358534840 +0200 ++++ xc/lib/GL/mesa/src/drv/r200/r200_vtxtmp_x86.S 2004-06-07 22:23:33.798760408 +0200 +@@ -492,3 +492,7 @@ + ret + GLOBL( _sse_MultiTexCoord2f_2_end ) + #endif ++ ++.section .note.GNU-stack, "", @progbits ++.previous ++ +diff -urN xc.org/lib/GL/mesa/src/drv/radeon/radeon_vtxtmp_x86.S xc/lib/GL/mesa/src/drv/radeon/radeon_vtxtmp_x86.S +--- xc.org/lib/GL/mesa/src/drv/radeon/radeon_vtxtmp_x86.S 2004-06-07 22:15:16.372380712 +0200 ++++ xc/lib/GL/mesa/src/drv/radeon/radeon_vtxtmp_x86.S 2004-06-07 22:23:57.166208016 +0200 +@@ -492,3 +492,7 @@ + ret + GLOBL( _sse_MultiTexCoord2f_2_end ) + #endif ++ ++.section .note.GNU-stack, "", @progbits ++.previous ++ +diff -urN xc.org/lib/GL/mesa/src/drv/tdfx/X86/fx_3dnow_fastpath.S xc/lib/GL/mesa/src/drv/tdfx/X86/fx_3dnow_fastpath.S +--- xc.org/lib/GL/mesa/src/drv/tdfx/X86/fx_3dnow_fastpath.S 2004-06-07 22:15:16.909299088 +0200 ++++ xc/lib/GL/mesa/src/drv/tdfx/X86/fx_3dnow_fastpath.S 2004-06-07 22:24:30.021213296 +0200 +@@ -81,4 +81,6 @@ + #define TAG(x) x##_RGBA_TMU1 + #include "fx_3dnow_fasttmp.h" + ++.section .note.GNU-stack, "", @progbits ++.previous + +diff -urN xc.org/LOG xc/LOG +--- xc.org/LOG 1970-01-01 01:00:00.000000000 +0100 ++++ xc/LOG 2004-06-07 22:18:46.677409488 +0200 +@@ -0,0 +1,57 @@ ++patching file extras/Mesa/src/X86/3dnow_normal.S ++patching file extras/Mesa/src/X86/3dnow_xform1.S ++patching file extras/Mesa/src/X86/3dnow_xform2.S ++patching file extras/Mesa/src/X86/3dnow_xform3.S ++patching file extras/Mesa/src/X86/3dnow_xform4.S ++patching file extras/Mesa/src/X86/common_x86_asm.S ++Hunk #1 succeeded at 235 (offset -2 lines). ++patching file extras/Mesa/src/X86/glapi_x86.S ++Hunk #1 succeeded at 4859 with fuzz 1 (offset 4085 lines). ++patching file extras/Mesa/src/X86/mmx_blend.S ++Hunk #1 FAILED at 416. ++1 out of 1 hunk FAILED -- saving rejects to file extras/Mesa/src/X86/mmx_blend.S.rej ++patching file extras/Mesa/src/X86/sse_normal.S ++can't find file to patch at input line 85 ++Perhaps you used the wrong -p or --strip option? ++The text leading up to this was: ++-------------------------- ++|--- xc/extras/Mesa/src/X86/sse_vertex.S.exec-shield-GNU-stack 2003-10-23 17:49:41.000000000 -0400 ++|+++ xc/extras/Mesa/src/X86/sse_vertex.S 2003-10-23 17:51:50.000000000 -0400 ++-------------------------- ++File to patch: ++Skip this patch? [y] ++Skipping patch. ++1 out of 1 hunk ignored ++patching file extras/Mesa/src/X86/sse_xform1.S ++patching file extras/Mesa/src/X86/sse_xform2.S ++patching file extras/Mesa/src/X86/sse_xform3.S ++patching file extras/Mesa/src/X86/sse_xform4.S ++patching file extras/Mesa/src/X86/x86_cliptest.S ++Hunk #1 succeeded at 398 (offset -1 lines). ++can't find file to patch at input line 139 ++Perhaps you used the wrong -p or --strip option? ++The text leading up to this was: ++-------------------------- ++|--- xc/extras/Mesa/src/X86/x86_vertex.S.exec-shield-GNU-stack 2003-10-23 17:49:41.000000000 -0400 ++|+++ xc/extras/Mesa/src/X86/x86_vertex.S 2003-10-23 17:52:30.000000000 -0400 ++-------------------------- ++File to patch: ++Skip this patch? [y] ++Skipping patch. ++1 out of 1 hunk ignored ++patching file extras/Mesa/src/X86/x86_xform2.S ++Hunk #1 succeeded at 560 (offset -1 lines). ++patching file extras/Mesa/src/X86/x86_xform3.S ++Hunk #1 succeeded at 630 (offset -1 lines). ++patching file extras/Mesa/src/X86/x86_xform4.S ++Hunk #1 succeeded at 663 (offset -1 lines). ++patching file lib/GL/mesa/src/drv/r200/r200_vtxtmp_x86.S ++Hunk #1 FAILED at 408. ++1 out of 1 hunk FAILED -- saving rejects to file lib/GL/mesa/src/drv/r200/r200_vtxtmp_x86.S.rej ++patching file lib/GL/mesa/src/drv/radeon/radeon_vtxtmp_x86.S ++Hunk #1 FAILED at 408. ++1 out of 1 hunk FAILED -- saving rejects to file lib/GL/mesa/src/drv/radeon/radeon_vtxtmp_x86.S.rej ++patching file programs/Xserver/hw/xfree86/drivers/nsc/nsc_msr_asm.S ++patching file programs/Xserver/hw/xfree86/os-support/misc/IODelay.S ++patching file programs/Xserver/hw/xfree86/os-support/misc/SlowBcopy.S ++patching file programs/Xserver/hw/xfree86/os-support/misc/BUSmemcpy.S +diff -urN xc.org/programs/Xserver/hw/xfree86/drivers/nsc/nsc_msr_asm.S xc/programs/Xserver/hw/xfree86/drivers/nsc/nsc_msr_asm.S +--- xc.org/programs/Xserver/hw/xfree86/drivers/nsc/nsc_msr_asm.S 2004-06-07 22:17:39.610605192 +0200 ++++ xc/programs/Xserver/hw/xfree86/drivers/nsc/nsc_msr_asm.S 2004-06-07 22:18:46.673410096 +0200 +@@ -225,5 +225,8 @@ + LEAVE + RET + ++.section .note.GNU-stack, "", @progbits ++.previous ++ + /*###################################*/ + +diff -urN xc.org/programs/Xserver/hw/xfree86/os-support/misc/BUSmemcpy.S xc/programs/Xserver/hw/xfree86/os-support/misc/BUSmemcpy.S +--- xc.org/programs/Xserver/hw/xfree86/os-support/misc/BUSmemcpy.S 2004-06-07 22:17:59.337606232 +0200 ++++ xc/programs/Xserver/hw/xfree86/os-support/misc/BUSmemcpy.S 2004-06-07 22:18:46.678409336 +0200 +@@ -154,3 +154,5 @@ + MOV_L (EDX, EDI) + RET + ++.section .note.GNU-stack, "", @progbits ++.previous +diff -urN xc.org/programs/Xserver/hw/xfree86/os-support/misc/IODelay.S xc/programs/Xserver/hw/xfree86/os-support/misc/IODelay.S +--- xc.org/programs/Xserver/hw/xfree86/os-support/misc/IODelay.S 2004-06-07 22:17:59.350604256 +0200 ++++ xc/programs/Xserver/hw/xfree86/os-support/misc/IODelay.S 2004-06-07 22:18:46.675409792 +0200 +@@ -51,3 +51,5 @@ + JNE (delay_it) + RET + ++.section .note.GNU-stack, "", @progbits ++.previous +diff -urN xc.org/programs/Xserver/hw/xfree86/os-support/misc/PortIO.S xc/programs/Xserver/hw/xfree86/os-support/misc/PortIO.S +--- xc.org/programs/Xserver/hw/xfree86/os-support/misc/PortIO.S 2004-06-07 22:17:59.366601824 +0200 ++++ xc/programs/Xserver/hw/xfree86/os-support/misc/PortIO.S 2004-06-07 22:28:31.581490552 +0200 +@@ -54,4 +54,6 @@ + MOV_L (REGOFF(4,ESP), EDX) + IN_L + RET ++.section .note.GNU-stack, "", @progbits ++.previous + +diff -urN xc.org/programs/Xserver/hw/xfree86/os-support/misc/SlowBcopy.S xc/programs/Xserver/hw/xfree86/os-support/misc/SlowBcopy.S +--- xc.org/programs/Xserver/hw/xfree86/os-support/misc/SlowBcopy.S 2004-06-07 22:17:59.367601672 +0200 ++++ xc/programs/Xserver/hw/xfree86/os-support/misc/SlowBcopy.S 2004-06-07 22:18:46.676409640 +0200 +@@ -106,3 +106,6 @@ + POP_L (EBP) + RET + ++.section .note.GNU-stack, "", @progbits ++.previous ++ diff --git a/XFree86-libGL-exec-shield-fixes-v2.patch b/XFree86-libGL-exec-shield-fixes-v2.patch new file mode 100644 index 0000000..53868be --- /dev/null +++ b/XFree86-libGL-exec-shield-fixes-v2.patch @@ -0,0 +1,627 @@ +diff -urN xc.org/extras/Mesa/src/glapi.c xc/extras/Mesa/src/glapi.c +--- xc.org/extras/Mesa/src/glapi.c 2004-06-07 22:45:05.571381120 +0200 ++++ xc/extras/Mesa/src/glapi.c 2004-06-07 23:11:34.201872576 +0200 +@@ -57,6 +57,7 @@ + #include "glapioffsets.h" + #include "glapitable.h" + #include "glthread.h" ++#include "mem.h" + + /***** BEGIN NO-OP DISPATCH *****/ + +@@ -546,7 +547,7 @@ + 0xe8, 0x00, 0x00, 0x00, 0x00, + 0xff, 0xa0, 0x00, 0x00, 0x00, 0x00 + }; +- unsigned char *code = (unsigned char *) malloc(sizeof(insn_template)); ++ unsigned char *code = EXEC_MALLOC(sizeof(insn_template), 16); + unsigned int next_insn; + if (code) { + memcpy(code, insn_template, sizeof(insn_template)); +@@ -587,7 +588,7 @@ + 0x01000000 /* nop */ + }; + #endif +- unsigned int *code = (unsigned int *) malloc(sizeof(insn_template)); ++ unsigned int *code = EXEC_MALLOC(sizeof(insn_template), 16); + unsigned long glapi_addr = (unsigned long) &_glapi_Dispatch; + if (code) { + memcpy(code, insn_template, sizeof(insn_template)); +diff -urN xc.org/extras/Mesa/src/imports.c xc/extras/Mesa/src/imports.c +--- xc.org/extras/Mesa/src/imports.c 2004-06-07 22:45:05.943324576 +0200 ++++ xc/extras/Mesa/src/imports.c 2004-06-07 23:08:05.289632064 +0200 +@@ -59,6 +59,19 @@ + extern int vsnprintf(char *str, size_t count, const char *fmt, va_list arg); + #endif + ++/* Define a struct for our private data. This is preferred over pointer ++ * arithmetic to access individual pieces of our private data because the ++ * compiler will help us get alignment correct in a portable way and it ++ * makes it much easier to add or remove items from our private data */ ++ ++typedef struct align_malloc_header { ++ void *alloc_ptr; /* actual allocation ptr */ ++ size_t alloc_size; /* actual allocation size */ ++ void *user_ptr; /* ptr returned to caller */ ++ size_t user_size; /* size caller requested */ ++} align_malloc_header; ++ ++static unsigned long RoundUpPowerOf2(unsigned long val); + + /**********************************************************************/ + /* Wrappers for standard C library functions */ +@@ -175,6 +188,310 @@ + #endif + } + ++/* ++ * Execute permission implementation notes: ++ * John Dennis - jdennis@redhat.com - Red Hat Inc. ++ * ++ * Overview: ++ * ++ * Various parts of Mesa generate machine code during run time and ++ * then executes that code. We will use the term code gen to refer to ++ * this process. Some operating systems in an attempt to achieve ++ * better security enforce restrictions on which memory areas may ++ * contain executable code. In general execute permission is granted ++ * to .text sections and removed on stack or heap memory. It's the ++ * heap (and possibly the stack) where code is run time ++ * generated. This means on systems that enforce execute memory ++ * security you will get either a SEGV or SIGBUS exception when run ++ * time generated code executes and the process will be terminated. ++ * ++ * Implementation: ++ * ++ * The solution is to provide unique malloc/free functions which ++ * return memory with execute permission and to make sure these ++ * allocation functions are called for code gen. ++ * ++ * There are 3 possible implementation solutions. ++ * ++ * Solution A: use mprotect on malloc block. ++ * ++ * In this scenario after a block is allocated via malloc we call ++ * mprotect on the pages containing the block and add execute ++ * permission. In theory a free of the block removes the execute ++ * permission. ++ * ++ * Pros: Simple to implement ++ * ++ * Cons: Because execute permission is granted memory pages when ++ * mprotect is called on the page containing the malloc block ++ * every other malloc block in that page also receives execute ++ * permission, this is insecure. ++ * ++ * When a malloc block is freed that had been allocated for ++ * execute permission we should remove the execute permission ++ * from that block so that when the heap manager resuses that ++ * memory it will not be executable. But Because exectue ++ * permission is granted to memory pages and a page may have ++ * more than one malloc block with execute permission we ++ * cannot remove execute permission because that would remove ++ * execute permission on any executable malloc blocks still in ++ * that page. By not removing the execution permission on free ++ * we will tend to "leak" executable memory as more and more ++ * heap pages accumulate execute permission, possible without ++ * needing it. ++ * ++ * Solution B: use mmap to allocate block ++ * ++ * In this scenario every call to alloc an executable block is ++ * performed with anonymous mmap. Mmap always allocates pages of ++ * memory. When free is called we unmap the pages. ++ * ++ * Pros: This is much more secure. The kernel places the allocation ++ * in special pages that have additional protection. These ++ * pages are not near any other pages. ++ * ++ * The pages used do not contain any heap allocation that is ++ * not susposed to be executable, therefore we are not ++ * inadvertantly granting execute permission to a malloc block ++ * that happens to live in the same page as a execute malloc ++ * block. ++ * ++ * The allocation can be freed without affecting anyother ++ * allocation and it will be reused by the kernel. ++ * ++ * Its simple to implement. As simple as solution A. ++ * ++ * Cons: Mmap only allocates in units of pages. Thus even a small ++ * allocation will use an entire page. However note, only a ++ * small number exec malloc's are done so the wasted memory ++ * is not likely to be an issue. ++ * ++ * Because every code generated function will live alone in ++ * its own page this will probably introduce more cache misses ++ * and page faults than if the all the code coalesced together ++ * into one or more pages as would be the case with regular ++ * .text sections. ++ * ++ * Solution C: use separate malloc implementation using mmap'ed heap arena ++ * ++ * In this scenario a new heap manager is introduced which manages a ++ * heap arena usning anonymous mmap with execute permission. All ++ * executable allocations are provided using only this heap arena. ++ * ++ * Pros: This is the ideal solution. As in Solution B executable and ++ * non-executable allocations are never mixed. Executable ++ * allocations are provided using the most secure pages the ++ * kernel manages. ++ * ++ * Pages will likely contain multiple allocations as opposed ++ * to Solution B where pages will be sparsely used. This ++ * improves cache and page fault behavior. ++ * ++ * Cons: This is the most involved implementation and requires the ++ * introduction of a heap manger implementation that has been ++ * modified to work with anonymous mmap. However, note that ++ * the GNU malloc implementation has been modified to work ++ * with anonymous mmap. ++ */ ++ ++#if 1 ++#define EXEC_ALLOC_USE_MMAP ++#else ++#define EXEC_ALLOC_USE_MALLOC ++#endif ++ ++/* If input is power of 2 return that, else round up to next power of 2 */ ++static unsigned long RoundUpPowerOf2(unsigned long val) ++{ ++ int i, setBits; ++ ++ if (val == 0) return(1UL); ++ if (val > (1UL << (sizeof(unsigned long) * 8 - 1))) { ++ /* out of range, should be fatal error?, for now return max power of 2 */ ++ return (1UL << (sizeof(unsigned long) * 8 - 1)); ++ } ++ ++ for (i = setBits = 0; val && i < sizeof(unsigned long) * 8; i++, val >>= 1) { ++ if (val & 1UL) setBits++; ++ } ++ if (setBits > 1) ++ return (1UL << i); /* input was not power of 2 */ ++ else ++ return (1UL << (i-1)); /* input was power of 2 */ ++} ++ ++/* ++ * Allocate N-byte aligned memory in executable region (uninitialized) ++ */ ++ ++#ifdef EXEC_ALLOC_USE_MALLOC ++void * ++_mesa_exec_malloc(size_t user_size, unsigned long user_align) ++{ ++ unsigned long alloc_ptr, user_ptr, alloc_size, alloc_align; ++ align_malloc_header *pHeader; ++ ++ ASSERT( user_align > 0 ); ++ ++ /* We store the pointer to the acutal address and size in a private ++ * header before the address the client sees. We need the actual ++ * pointer to free with and we need the size to remove execute permission ++ * on the block */ ++ ++ if (user_align < sizeof(align_malloc_header)) ++ alloc_align = RoundUpPowerOf2(sizeof(align_malloc_header)); ++ else ++ alloc_align = user_align; ++ alloc_size = user_size + alloc_align; ++ ++ alloc_ptr = (unsigned long) MALLOC(alloc_size); ++ ++ if (!alloc_ptr) return(NULL); ++ ++ user_ptr = (alloc_ptr + alloc_align) & ~(unsigned long)(alloc_align - 1); ++ pHeader = (align_malloc_header *) (user_ptr - sizeof(align_malloc_header)); ++ pHeader->alloc_ptr = (void *) alloc_ptr; ++ pHeader->alloc_size = alloc_size; ++ pHeader->user_ptr = (void *) user_ptr; ++ pHeader->user_size = user_size; ++ ++ { ++ unsigned page_size, round; ++ ++ page_size = getpagesize(); ++ round = user_ptr & (page_size-1); ++ mprotect((void *)(user_ptr - round), (user_size + round + page_size-1) & ~(page_size-1), ++ PROT_READ | PROT_WRITE | PROT_EXEC); ++ } ++ ++#ifdef DEBUG ++ { ++ unsigned char *p = (unsigned char *) alloc_ptr; ++ unsigned char *stop = (unsigned char *) pHeader; ++ ++ /* mark the non-aligned area */ ++ for(; p < stop; p++) { ++ *p = 0xcd; ++ } ++ } ++#endif ++ ++ return (void *)user_ptr; ++} ++ ++/* ++ * Free N-byte executable aligned memory ++ */ ++void ++_mesa_exec_free(void *user_ptr) ++{ ++ /* The header giving the real address and size is just prior to the address the client sees. */ ++ align_malloc_header *pHeader; ++ void *alloc_ptr; ++ size_t user_size; ++ ++ pHeader = (align_malloc_header *)((char *)user_ptr - sizeof(align_malloc_header)); ++ alloc_ptr = pHeader->alloc_ptr; ++ user_size = pHeader->user_size; ++ ++#if 0 ++ /* ++ * Unfortunately we cannot remove the execute permission on this ++ * malloc block because execute permission is granted on a page ++ * basis. If the page containing this malloc block also contained ++ * another malloc block with execute permission that was still in ++ * effect then we will remove execute permission on a malloc block ++ * that should still be enforce. This does mean we will tend to ++ * "leak" execute permission in the heap. See above block comment ++ * on implementation issues. ++ * ++ * Note, we could keep a ref count on each page and when the ref count ++ * fell to zero we could remove the execute permission. ++ * ++ * If we did remove the execute permission this is how it would be done. ++ */ ++ { ++ unsigned page_size, round; ++ ++ page_size = getpagesize(); ++ round = (unsigned long)user_ptr & (page_size-1); ++ mprotect((char *)user_ptr - round, (user_size + round + page_size-1) & ~(page_size-1), ++ PROT_READ | PROT_WRITE); ++ } ++#endif ++ FREE(alloc_ptr); ++} ++ ++#elif defined(EXEC_ALLOC_USE_MMAP) ++ ++void * ++_mesa_exec_malloc(size_t user_size, unsigned long user_align) ++{ ++ unsigned long alloc_ptr, user_ptr, alloc_size, alloc_align; ++ align_malloc_header *pHeader; ++ ++ ASSERT( user_align > 0 ); ++ ++ /* We store the pointer to the acutal address and size in a private ++ * header before the address the client sees. We need the actual ++ * pointer to free with and we need the size to unmap the region */ ++ ++ if (user_align < sizeof(align_malloc_header)) ++ alloc_align = RoundUpPowerOf2(sizeof(align_malloc_header)); ++ else ++ alloc_align = user_align; ++ alloc_size = user_size + alloc_align; ++ ++ /* Note, I'm not sure how portable MAP_ANONYMOUS with fd=0 is, on some POSIX ++ * systems you may need to remove the MAP_ANONYMOUS flag and pass the ++ * result of posix_typed_mem_open with POSIX_TYPED_MEM_ALLOCATE as the fd. */ ++ ++ alloc_ptr = (unsigned long) mmap(0, alloc_size, ++ PROT_READ | PROT_WRITE | PROT_EXEC, MAP_PRIVATE | MAP_ANONYMOUS, 0, 0); ++ if ((void *)alloc_ptr == MAP_FAILED) { ++ return(NULL); ++ } ++ ++ user_ptr = (alloc_ptr + alloc_align) & ~(unsigned long)(alloc_align - 1); ++ pHeader = (align_malloc_header *) (user_ptr - sizeof(align_malloc_header)); ++ pHeader->alloc_ptr = (void *) alloc_ptr; ++ pHeader->alloc_size = alloc_size; ++ pHeader->user_ptr = (void *) user_ptr; ++ pHeader->user_size = user_size; ++ ++#ifdef DEBUG ++ { ++ unsigned char *p = (unsigned char *) alloc_ptr; ++ unsigned char *stop = (unsigned char *) pHeader; ++ ++ /* mark the non-aligned area */ ++ for(; p < stop; p++) { ++ *p = 0xcd; ++ } ++ } ++#endif ++ ++ return (void *)user_ptr; ++} ++ ++/* ++ * Free N-byte executable aligned memory ++ */ ++void ++_mesa_exec_free(void *user_ptr) ++{ ++ /* The header giving the real address and size is just prior to the address the client sees. */ ++ align_malloc_header *pHeader; ++ void *alloc_ptr; ++ size_t alloc_size; ++ ++ pHeader = (align_malloc_header *)((char *)user_ptr - sizeof(align_malloc_header)); ++ alloc_ptr = pHeader->alloc_ptr; ++ alloc_size = pHeader->alloc_size; ++ ++ munmap(alloc_ptr, alloc_size); ++} ++#endif + + void * + _mesa_memcpy(void *dest, const void *src, size_t n) +diff -urN xc.org/extras/Mesa/src/imports.h xc/extras/Mesa/src/imports.h +--- xc.org/extras/Mesa/src/imports.h 2004-06-07 22:45:05.944324424 +0200 ++++ xc/extras/Mesa/src/imports.h 2004-06-07 23:04:42.561451432 +0200 +@@ -50,6 +50,9 @@ + #define ALIGN_MALLOC_STRUCT(T, N) (struct T *) _mesa_align_malloc(sizeof(struct T), N) + #define ALIGN_CALLOC_STRUCT(T, N) (struct T *) _mesa_align_calloc(sizeof(struct T), N) + #define ALIGN_FREE(PTR) _mesa_align_free(PTR) ++/* These allocate aligned memory in a area with execute permission, used for code generation. */ ++#define EXEC_MALLOC(BYTES, N) (void *) _mesa_exec_malloc(BYTES, N) ++#define EXEC_FREE(PTR) _mesa_exec_free(PTR) + + #define MEMCPY( DST, SRC, BYTES) _mesa_memcpy(DST, SRC, BYTES) + #define MEMSET( DST, VAL, N ) _mesa_memset(DST, VAL, N) +@@ -120,6 +123,11 @@ + _mesa_align_free( void *ptr ); + + extern void * ++_mesa_exec_malloc(size_t bytes, unsigned long alignment); ++extern void ++_mesa_exec_free(void *ptr); ++ ++extern void * + _mesa_memcpy( void *dest, const void *src, size_t n ); + + extern void +diff -urN xc.org/extras/Mesa/src/mtypes.h xc/extras/Mesa/src/mtypes.h +--- xc.org/extras/Mesa/src/mtypes.h 2004-06-07 22:45:05.956322600 +0200 ++++ xc/extras/Mesa/src/mtypes.h 2004-06-07 23:05:35.023475992 +0200 +@@ -31,7 +31,8 @@ + #ifndef TYPES_H + #define TYPES_H + +- ++#include ++#include + #include "glheader.h" + #include "config.h" /* Hardwired parameters */ + #include "glapitable.h" +diff -urN xc.org/extras/Mesa/src/tnl/t_vtx_exec.c xc/extras/Mesa/src/tnl/t_vtx_exec.c +--- xc.org/extras/Mesa/src/tnl/t_vtx_exec.c 2004-06-07 22:45:06.597225168 +0200 ++++ xc/extras/Mesa/src/tnl/t_vtx_exec.c 2004-06-07 23:17:12.494444288 +0200 +@@ -593,7 +593,7 @@ + struct dynfn *f, *tmp; + foreach_s (f, tmp, l) { + remove_from_list( f ); +- ALIGN_FREE( f->code ); ++ EXEC_FREE( f->code ); + FREE( f ); + } + } +diff -urN xc.org/extras/Mesa/src/tnl/t_vtx_x86.c xc/extras/Mesa/src/tnl/t_vtx_x86.c +--- xc.org/extras/Mesa/src/tnl/t_vtx_x86.c 2004-06-07 22:45:06.608223496 +0200 ++++ xc/extras/Mesa/src/tnl/t_vtx_x86.c 2004-06-07 23:16:32.268559552 +0200 +@@ -75,7 +75,7 @@ + 0xff, 0x25, 0, 0, 0, 0 /* jmp NOTIFY */ + }; + +- dfn->code = ALIGN_MALLOC( sizeof(temp), 16 ); ++ dfn->code = EXEC_MALLOC( sizeof(temp), 16 ); + memcpy (dfn->code, temp, sizeof(temp)); + FIXUP(dfn->code, 3, 0x0, (int)&tnl->vertex[2]); + FIXUP(dfn->code, 9, 0x0, (int)&tnl->dmaptr); +@@ -126,7 +126,7 @@ + 0xff, 0x25, 0,0,0,0 /* jmp *NOTIFY */ + }; + +- dfn->code = ALIGN_MALLOC( sizeof(temp), 16 ); ++ dfn->code = EXEC_MALLOC( sizeof(temp), 16 ); + memcpy (dfn->code, temp, sizeof(temp)); + FIXUP(dfn->code, 2, 0x0, (int)&tnl->dmaptr); + FIXUP(dfn->code, 25, 0x0, (int)&tnl->vertex[3]); +@@ -163,7 +163,7 @@ + 0xff, 0x25, 0,0,0,0, /* jmp *NOTIFY */ + }; + +- dfn->code = ALIGN_MALLOC( sizeof(temp), 16 ); ++ dfn->code = EXEC_MALLOC( sizeof(temp), 16 ); + memcpy (dfn->code, temp, sizeof(temp)); + FIXUP(dfn->code, 3, 0x0, (int)&tnl->dmaptr); + FIXUP(dfn->code, 28, 0x0, (int)&tnl->vertex[3]); +@@ -205,7 +205,7 @@ + 0xff, 0x25, 0, 0, 0, 0 /* jmp NOTIFY */ + }; + +- dfn->code = ALIGN_MALLOC( sizeof(temp), 16 ); ++ dfn->code = EXEC_MALLOC( sizeof(temp), 16 ); + memcpy (dfn->code, temp, sizeof(temp)); + FIXUP(dfn->code, 3, 0x0, (int)&tnl->vertex[3]); + FIXUP(dfn->code, 9, 0x0, (int)&tnl->dmaptr); +@@ -259,7 +259,7 @@ + 0xff, 0x25, 0x08, 0, 0, 0, /* jmp *0x8 */ + }; + +- dfn->code = ALIGN_MALLOC( sizeof(temp), 16 ); ++ dfn->code = EXEC_MALLOC( sizeof(temp), 16 ); + memcpy (dfn->code, temp, sizeof(temp)); + FIXUP(dfn->code, 1, 0x00000000, (int)&tnl->dmaptr); + FIXUP(dfn->code, 27, 0x0000001c, (int)&tnl->vertex[3]); +@@ -303,7 +303,7 @@ + 0xff, 0x25, 0x08, 0, 0, 0, /* jmp *0x8 */ + }; + +- dfn->code = ALIGN_MALLOC( sizeof(temp), 16 ); ++ dfn->code = EXEC_MALLOC( sizeof(temp), 16 ); + memcpy (dfn->code, temp, sizeof(temp)); + FIXUP(dfn->code, 1, 0x00000000, (int)&tnl->dmaptr); + FIXUP(dfn->code, 27, 0x0000001c, (int)&tnl->vertex[3]); +@@ -351,7 +351,7 @@ + 0xff, 0x25, 0, 0, 0, 0 /* jmp NOTIFY */ + }; + +- dfn->code = ALIGN_MALLOC( sizeof(temp), 16 ); ++ dfn->code = EXEC_MALLOC( sizeof(temp), 16 ); + memcpy (dfn->code, temp, sizeof(temp)); + FIXUP(dfn->code, 8, 0x01010101, (int)&tnl->dmaptr); + FIXUP(dfn->code, 32, 0x00000006, tnl->vertex_size-3); +@@ -393,7 +393,7 @@ + + insert_at_head( &tnl->dfn_cache.Normal3fv, dfn ); + dfn->key = key; +- dfn->code = ALIGN_MALLOC( sizeof(temp), 16 ); ++ dfn->code = EXEC_MALLOC( sizeof(temp), 16 ); + memcpy (dfn->code, temp, sizeof(temp)); + FIXUP(dfn->code, 5, 0x0, (int)tnl->normalptr); + return dfn; +@@ -421,7 +421,7 @@ + + insert_at_head( &tnl->dfn_cache.Normal3f, dfn ); + dfn->key = key; +- dfn->code = ALIGN_MALLOC( sizeof(temp), 16 ); ++ dfn->code = EXEC_MALLOC( sizeof(temp), 16 ); + memcpy (dfn->code, temp, sizeof(temp)); + FIXUP(dfn->code, 1, 0x12345678, (int)tnl->normalptr); + return dfn; +@@ -449,7 +449,7 @@ + + insert_at_head( &tnl->dfn_cache.Normal3fv, dfn ); + dfn->key = key; +- dfn->code = ALIGN_MALLOC( sizeof(temp), 16 ); ++ dfn->code = EXEC_MALLOC( sizeof(temp), 16 ); + memcpy (dfn->code, temp, sizeof(temp)); + FIXUP(dfn->code, 5, 0x0, (int)tnl->normalptr); + return dfn; +@@ -475,7 +475,7 @@ + + insert_at_head( &tnl->dfn_cache.Normal3f, dfn ); + dfn->key = key; +- dfn->code = ALIGN_MALLOC( sizeof(temp), 16 ); ++ dfn->code = EXEC_MALLOC( sizeof(temp), 16 ); + memcpy (dfn->code, temp, sizeof(temp)); + FIXUP(dfn->code, 1, 0x12345678, (int)tnl->normalptr); + return dfn; +@@ -499,7 +499,7 @@ + 0xc3, /* ret */ + }; + +- dfn->code = ALIGN_MALLOC( sizeof(temp), 16 ); ++ dfn->code = EXEC_MALLOC( sizeof(temp), 16 ); + memcpy (dfn->code, temp, sizeof(temp)); + FIXUP(dfn->code, 5, 0x12345678, (int)tnl->ubytecolorptr); + return dfn; +@@ -531,7 +531,7 @@ + 0xc3, /* ret */ + }; + +- dfn->code = ALIGN_MALLOC( sizeof(temp), 16 ); ++ dfn->code = EXEC_MALLOC( sizeof(temp), 16 ); + memcpy (dfn->code, temp, sizeof(temp)); + FIXUP(dfn->code, 2, 0x00000000, (int)_mesa_ubyte_to_float_color_tab); + FIXUP(dfn->code, 27, 0xdeadbeaf, (int)tnl->floatcolorptr); +@@ -567,7 +567,7 @@ + insert_at_head( &tnl->dfn_cache.Color4ub, dfn ); + dfn->key = key; + +- dfn->code = ALIGN_MALLOC( sizeof(temp), 16 ); ++ dfn->code = EXEC_MALLOC( sizeof(temp), 16 ); + memcpy (dfn->code, temp, sizeof(temp)); + FIXUP(dfn->code, 18, 0x0, (int)tnl->ubytecolorptr); + FIXUP(dfn->code, 24, 0x0, (int)tnl->ubytecolorptr+1); +@@ -600,7 +600,7 @@ + + insert_at_head( &tnl->dfn_cache.TexCoord2fv, dfn ); + dfn->key = key; +- dfn->code = ALIGN_MALLOC( sizeof(temp), 16 ); ++ dfn->code = EXEC_MALLOC( sizeof(temp), 16 ); + memcpy (dfn->code, temp, sizeof(temp)); + FIXUP(dfn->code, 5, 0x12345678, (int)tnl->texcoordptr[0]); + return dfn; +@@ -624,7 +624,7 @@ + + insert_at_head( &tnl->dfn_cache.TexCoord2f, dfn ); + dfn->key = key; +- dfn->code = ALIGN_MALLOC( sizeof(temp), 16 ); ++ dfn->code = EXEC_MALLOC( sizeof(temp), 16 ); + memcpy (dfn->code, temp, sizeof(temp)); + FIXUP(dfn->code, 1, 0x12345678, (int)tnl->texcoordptr[0]); + return dfn; +@@ -648,7 +648,7 @@ + + insert_at_head( &tnl->dfn_cache.TexCoord2fv, dfn ); + dfn->key = key; +- dfn->code = ALIGN_MALLOC( sizeof(temp), 16 ); ++ dfn->code = EXEC_MALLOC( sizeof(temp), 16 ); + memcpy (dfn->code, temp, sizeof(temp)); + FIXUP(dfn->code, 5, 0x12345678, (int)tnl->texcoordptr[0]); + return dfn; +@@ -670,7 +670,7 @@ + + insert_at_head( &tnl->dfn_cache.TexCoord2f, dfn ); + dfn->key = key; +- dfn->code = ALIGN_MALLOC( sizeof(temp), 16 ); ++ dfn->code = EXEC_MALLOC( sizeof(temp), 16 ); + memcpy (dfn->code, temp, sizeof(temp)); + FIXUP(dfn->code, 1, 0x12345678, (int)tnl->texcoordptr[0]); + return dfn; +diff -urN xc.org/lib/GL/mesa/src/drv/r200/r200_vtxfmt.c xc/lib/GL/mesa/src/drv/r200/r200_vtxfmt.c +--- xc.org/lib/GL/mesa/src/drv/r200/r200_vtxfmt.c 2004-06-07 22:44:55.376930912 +0200 ++++ xc/lib/GL/mesa/src/drv/r200/r200_vtxfmt.c 2004-06-07 22:48:38.196057256 +0200 +@@ -1074,7 +1074,7 @@ + struct dynfn *f, *tmp; + foreach_s (f, tmp, l) { + remove_from_list( f ); +- ALIGN_FREE( f->code ); ++ EXEC_FREE( f->code ); + FREE( f ); + } + } +diff -urN xc.org/lib/GL/mesa/src/drv/r200/r200_vtxfmt.h xc/lib/GL/mesa/src/drv/r200/r200_vtxfmt.h +--- xc.org/lib/GL/mesa/src/drv/r200/r200_vtxfmt.h 2004-06-07 22:44:55.377930760 +0200 ++++ xc/lib/GL/mesa/src/drv/r200/r200_vtxfmt.h 2004-06-07 22:48:38.192057864 +0200 +@@ -60,7 +60,7 @@ + insert_at_head( &CACHE, dfn ); \ + dfn->key[0] = key[0]; \ + dfn->key[1] = key[1]; \ +- dfn->code = ALIGN_MALLOC( end - start, 16 ); \ ++ dfn->code = EXEC_MALLOC( end - start, 16 ); \ + memcpy (dfn->code, start, end - start); \ + } \ + while ( 0 ) +diff -urN xc.org/lib/GL/mesa/src/drv/radeon/radeon_vtxfmt.c xc/lib/GL/mesa/src/drv/radeon/radeon_vtxfmt.c +--- xc.org/lib/GL/mesa/src/drv/radeon/radeon_vtxfmt.c 2004-06-07 22:44:55.473916168 +0200 ++++ xc/lib/GL/mesa/src/drv/radeon/radeon_vtxfmt.c 2004-06-07 22:48:38.218053912 +0200 +@@ -1042,7 +1042,7 @@ + struct dynfn *f, *tmp; + foreach_s (f, tmp, l) { + remove_from_list( f ); +- ALIGN_FREE( f->code ); ++ EXEC_FREE( f->code ); + FREE( f ); + } + } +diff -urN xc.org/lib/GL/mesa/src/drv/radeon/radeon_vtxfmt.h xc/lib/GL/mesa/src/drv/radeon/radeon_vtxfmt.h +--- xc.org/lib/GL/mesa/src/drv/radeon/radeon_vtxfmt.h 2004-06-07 22:44:55.473916168 +0200 ++++ xc/lib/GL/mesa/src/drv/radeon/radeon_vtxfmt.h 2004-06-07 22:48:38.214054520 +0200 +@@ -58,7 +58,7 @@ + char *end = (char *)&FUNC##_end; \ + insert_at_head( &CACHE, dfn ); \ + dfn->key = key; \ +- dfn->code = ALIGN_MALLOC( end - start, 16 ); \ ++ dfn->code = EXEC_MALLOC( end - start, 16 ); \ + memcpy (dfn->code, start, end - start); \ + } \ + while ( 0 ) + -- 2.44.0