From owner-freebsd-ports-bugs@FreeBSD.ORG Sun Jan 27 17:20:02 2008 Return-Path: Delivered-To: freebsd-ports-bugs@hub.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id 2376216A41A for ; Sun, 27 Jan 2008 17:20:02 +0000 (UTC) (envelope-from gnats@FreeBSD.org) Received: from freefall.freebsd.org (freefall.freebsd.org [IPv6:2001:4f8:fff6::28]) by mx1.freebsd.org (Postfix) with ESMTP id 03FE613C461 for ; Sun, 27 Jan 2008 17:20:02 +0000 (UTC) (envelope-from gnats@FreeBSD.org) Received: from freefall.freebsd.org (gnats@localhost [127.0.0.1]) by freefall.freebsd.org (8.14.2/8.14.2) with ESMTP id m0RHK18O024089 for ; Sun, 27 Jan 2008 17:20:01 GMT (envelope-from gnats@freefall.freebsd.org) Received: (from gnats@localhost) by freefall.freebsd.org (8.14.2/8.14.1/Submit) id m0RHK1dN024088; Sun, 27 Jan 2008 17:20:01 GMT (envelope-from gnats) Resent-Date: Sun, 27 Jan 2008 17:20:01 GMT Resent-Message-Id: <200801271720.m0RHK1dN024088@freefall.freebsd.org> Resent-From: FreeBSD-gnats-submit@FreeBSD.org (GNATS Filer) Resent-To: freebsd-ports-bugs@FreeBSD.org Resent-Reply-To: FreeBSD-gnats-submit@FreeBSD.org, Christoph Mallon Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id 5CCBC16A418 for ; Sun, 27 Jan 2008 17:13:55 +0000 (UTC) (envelope-from nobody@FreeBSD.org) Received: from www.freebsd.org (www.freebsd.org [IPv6:2001:4f8:fff6::21]) by mx1.freebsd.org (Postfix) with ESMTP id 4CD4413C458 for ; Sun, 27 Jan 2008 17:13:55 +0000 (UTC) (envelope-from nobody@FreeBSD.org) Received: from www.freebsd.org (localhost [127.0.0.1]) by www.freebsd.org (8.14.2/8.14.2) with ESMTP id m0RHCDtM029551 for ; Sun, 27 Jan 2008 17:12:13 GMT (envelope-from nobody@www.freebsd.org) Received: (from nobody@localhost) by www.freebsd.org (8.14.2/8.14.1/Submit) id m0RHCDCL029550; Sun, 27 Jan 2008 17:12:13 GMT (envelope-from nobody) Message-Id: <200801271712.m0RHCDCL029550@www.freebsd.org> Date: Sun, 27 Jan 2008 17:12:13 GMT From: Christoph Mallon To: freebsd-gnats-submit@FreeBSD.org X-Send-Pr-Version: www-3.1 Cc: Subject: ports/120052: SDL macro on x86 violates GCC and SYS V ABI assumptions X-BeenThere: freebsd-ports-bugs@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: Ports bug reports List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Sun, 27 Jan 2008 17:20:02 -0000 >Number: 120052 >Category: ports >Synopsis: SDL macro on x86 violates GCC and SYS V ABI assumptions >Confidential: no >Severity: non-critical >Priority: medium >Responsible: freebsd-ports-bugs >State: open >Quarter: >Keywords: >Date-Required: >Class: sw-bug >Submitter-Id: current-users >Arrival-Date: Sun Jan 27 17:20:01 UTC 2008 >Closed-Date: >Last-Modified: >Originator: Christoph Mallon >Release: n/a >Organization: - >Environment: n/a >Description: The x86 inline assembler version of the SDL macro SDL_revcpy() sets the direction flag ("std"), but does not clear it ("cld"). This is invalid according to GCC (inline assembler, which sets the direction flag, must reset it[0]) and the SYS V ABI (functions must leave with the direction flag cleared[1]). The macro is (indirectly, exact call sequence below) used in SDL_BlitSurface(), so this call sometimes returns with the direction flag set. This happens for bliting a surface onto itself with the destination coordinates set right/down of the source coordinates (typical use of this is scrolling left/up). Later on other parts of the code (like inlined memcpy()) cause memory corruption. Call sequence: SDL_BlitSurface() (#define SDL_Blit_Surface SDL_BlitUpper) SDL_BlitUpper() SDL_BlitLower() src->map->sw_blit() (function pointer to SDL_SoftBlit()) SDL_SoftBlit() src->map->sw_data->blit() (function pointer to SDL_BlitCopyOverlap()) SDL_BlitCopyOverlap() SDL_revcpy() [0] http://gcc.gnu.org/gcc-4.3/changes.html - "IA-32/x86-64", fourth bullet [1] http://www.sco.com/developers/devspecs/abi386-4.pdf - page 38 EFLAGS >How-To-Repeat: This program demonstrates the problem (compile with "cc -O `sdl-config --cflags --libs` $FILENAME"): #include #include #include static inline int TestDirectionFlag(void) { unsigned eflags; __asm__ __volatile__("pushf\n\tpop %0" : "=r" (eflags)); return (eflags & 0x400) != 0; } int main(void) { SDL_Init(SDL_INIT_VIDEO); SDL_Surface* const s = SDL_SetVideoMode(640, 480, 16, SDL_SWSURFACE); SDL_Rect src_rect = { 0, 0, 630, 470 }; SDL_Rect dst_rect = { 10, 10, 630, 470 }; if (TestDirectionFlag()) { fputs("direction flag set BEFORE SDL_BlitSurface()\n", stderr); abort(); } SDL_BlitSurface(s, &src_rect, s, &dst_rect); if (TestDirectionFlag()) { fputs("direction flag set AFTER SDL_BlitSurface()\n", stderr); abort(); } SDL_Quit(); return 0; } >Fix: Add a "cld" in the macro SDL_revcpy(), see attached patch. Patch attached with submission follows: --- include/SDL_stdinc.h.orig 2006-06-27 06:48:32.000000000 +0200 +++ include/SDL_stdinc.h 2008-01-27 16:39:16.000000000 +0100 @@ -319,6 +319,7 @@ __asm__ __volatile__ ( \ "std\n\t" \ "rep ; movsl\n\t" \ + "cld\n\t" \ : "=&c" (u0), "=&D" (u1), "=&S" (u2) \ : "0" (n >> 2), \ "1" (dstp+(n-4)), "2" (srcp+(n-4)) \ >Release-Note: >Audit-Trail: >Unformatted: