[Pkg-sdl-commits] r26 - in unstable/libsdl1.2/debian: . patches

Sam Hocevar sho at costa.debian.org
Wed Mar 1 19:02:50 UTC 2006


Author: sho
Date: 2006-03-01 19:02:50 +0000 (Wed, 01 Mar 2006)
New Revision: 26

Added:
   unstable/libsdl1.2/debian/patches/011_mprotect.diff
Modified:
   unstable/libsdl1.2/debian/changelog
Log:
  * debian/patches/011_mprotect.diff:
    + SDL_stretch.c: use mprotect() on the pages storing dynamically generated
      code so that we still work on systems that enforce W^X.


Modified: unstable/libsdl1.2/debian/changelog
===================================================================
--- unstable/libsdl1.2/debian/changelog	2006-03-01 18:52:36 UTC (rev 25)
+++ unstable/libsdl1.2/debian/changelog	2006-03-01 19:02:50 UTC (rev 26)
@@ -30,6 +30,10 @@
     + New patch: "dst_w == last.src_w" should be "dst_w == last.dst_w" in
       src/video/SDL_stretch.c.
 
+  * debian/patches/011_mprotect.diff:
+    + SDL_stretch.c: use mprotect() on the pages storing dynamically generated
+      code so that we still work on systems that enforce W^X.
+
   * debian/patches/012_gnu_stack.diff:
     + Add ".note.GNU-stack" sections to all NASM files so that gcc does not
       think these files need an executable stack.

Added: unstable/libsdl1.2/debian/patches/011_mprotect.diff
===================================================================
--- unstable/libsdl1.2/debian/patches/011_mprotect.diff	2006-03-01 18:52:36 UTC (rev 25)
+++ unstable/libsdl1.2/debian/patches/011_mprotect.diff	2006-03-01 19:02:50 UTC (rev 26)
@@ -0,0 +1,134 @@
+diff -puriN SDL-1.2.9.orig/src/video/SDL_stretch.c SDL-1.2.9/src/video/SDL_stretch.c
+--- SDL-1.2.9.orig/src/video/SDL_stretch.c	2004-05-16 23:08:55 +0200
++++ SDL-1.2.9/src/video/SDL_stretch.c	2006-03-01 13:28:46 +0100
+@@ -43,10 +43,23 @@ static char rcsid =
+      !defined(__WATCOMC__) && !defined(__LCC__) && !defined(__FREEBCC__)) || \
+     (defined(i386) && defined(__GNUC__) && defined(USE_ASMBLIT))
+ #define USE_ASM_STRETCH
++#if defined(__linux__)
++#define USE_MPROTECT
++#endif
+ #endif
+ 
+ #ifdef USE_ASM_STRETCH
+ 
++#ifdef USE_MPROTECT
++#include <stdlib.h>
++#include <stdint.h>
++#include <limits.h>
++#ifndef PAGESIZE
++#define PAGESIZE 4096
++#endif
++#include <sys/mman.h>
++#endif
++
+ #if defined(WIN32) || defined(i386)
+ #define PREFIX16	0x66
+ #define STORE_BYTE	0xAA
+@@ -58,10 +71,16 @@ static char rcsid =
+ #error Need assembly opcodes for this architecture
+ #endif
+ 
++#define MAX_CODE_LENGTH 4096
++
+ #if defined(__ELF__) && defined(__GNUC__)
+-extern unsigned char _copy_row[4096] __attribute__ ((alias ("copy_row")));
++extern unsigned char *_copy_row __attribute__ ((alias ("copy_row")));
++#endif
++#ifdef USE_MPROTECT
++static unsigned char *copy_row;
++#else
++static unsigned char copy_row[MAX_CODE_LENGTH];
+ #endif
+-static unsigned char copy_row[4096];
+ 
+ static int generate_rowbytes(int src_w, int dst_w, int bpp)
+ {
+@@ -70,12 +89,25 @@ static int generate_rowbytes(int src_w, 
+ 		int src_w;
+ 		int dst_w;
+ 	} last;
++#ifdef USE_MPROTECT
++	static unsigned char *code_buffer;
++#endif
+ 
+ 	int i;
+ 	int pos, inc;
+ 	unsigned char *eip;
+ 	unsigned char load, store;
+ 
++#ifdef USE_MPROTECT
++	if ( ! copy_row ) {
++		code_buffer = malloc(MAX_CODE_LENGTH + PAGESIZE - 1);
++		if ( ! code_buffer ) {
++			return(-1);
++		}
++		copy_row = (unsigned char *)(((uintptr_t)code_buffer + PAGESIZE - 1) & ~(uintptr_t)(PAGESIZE - 1));
++	}
++#endif
++
+ 	/* See if we need to regenerate the copy buffer */
+ 	if ( (src_w == last.src_w) &&
+ 	     (dst_w == last.dst_w) && (bpp == last.bpp) ) {
+@@ -99,6 +131,9 @@ static int generate_rowbytes(int src_w, 
+ 		SDL_SetError("ASM stretch of %d bytes isn't supported\n", bpp);
+ 		return(-1);
+ 	}
++#ifdef USE_MPROTECT
++	mprotect(copy_row, MAX_CODE_LENGTH, PROT_READ|PROT_WRITE);
++#endif
+ 	pos = 0x10000;
+ 	inc = (src_w << 16) / dst_w;
+ 	eip = copy_row;
+@@ -119,10 +154,13 @@ static int generate_rowbytes(int src_w, 
+ 	*eip++ = RETURN;
+ 
+ 	/* Verify that we didn't overflow (too late) */
+-	if ( eip > (copy_row+sizeof(copy_row)) ) {
++	if ( eip > (copy_row+MAX_CODE_LENGTH) ) {
+ 		SDL_SetError("Copy buffer overflow");
+ 		return(-1);
+ 	}
++#ifdef USE_MPROTECT
++	mprotect(copy_row, MAX_CODE_LENGTH, PROT_READ|PROT_EXEC);
++#endif
+ 	return(0);
+ }
+ 
+@@ -284,15 +322,20 @@ int SDL_SoftStretch(SDL_Surface *src, SD
+ 			copy_row3(srcp, srcrect->w, dstp, dstrect->w);
+ 			break;
+ 		    default:
++		{
++#ifdef USE_MPROTECT
++			void *code = copy_row;
++#else
++			void *code = &copy_row;
++#endif
+ #ifdef __GNUC__
+ 			__asm__ __volatile__ (
+-			"call _copy_row"
++			"call %4"
+ 			: "=&D" (u1), "=&S" (u2)
+-			: "0" (dstp), "1" (srcp)
++			: "0" (dstp), "1" (srcp), "r" (code)
+ 			: "memory" );
+ #else
+ #ifdef WIN32
+-		{ void *code = &copy_row;
+ 			__asm {
+ 				push edi
+ 				push esi
+@@ -304,11 +347,11 @@ int SDL_SoftStretch(SDL_Surface *src, SD
+ 				pop esi
+ 				pop edi
+ 			}
+-		}
+ #else
+ #error Need inline assembly for this compiler
+ #endif
+ #endif /* __GNUC__ */
++		}
+ 			break;
+ 		}
+ #else




More information about the Pkg-sdl-commits mailing list