Bug 120052 - devel-/sdl12 - SDL macro on x86 violates GCC and SYS V ABI assumptions
Summary: devel-/sdl12 - SDL macro on x86 violates GCC and SYS V ABI assumptions
Status: Closed FIXED
Alias: None
Product: Ports & Packages
Classification: Unclassified
Component: Individual Port(s) (show other bugs)
Version: Latest
Hardware: Any Any
: Normal Affects Only Me
Assignee: Diane Bruce
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2008-01-27 17:20 UTC by Christoph Mallon
Modified: 2008-01-27 21:40 UTC (History)
0 users

See Also:


Attachments
file.diff (345 bytes, patch)
2008-01-27 17:20 UTC, Christoph Mallon
no flags Details | Diff

Note You need to log in before you can comment on or make changes to this bug.
Description Christoph Mallon 2008-01-27 17:20:01 UTC
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

Fix: Add a "cld" in the macro SDL_revcpy(), see attached patch.

Patch attached with submission follows:
How-To-Repeat: This program demonstrates the problem (compile with "cc -O `sdl-config --cflags --libs` $FILENAME"):

#include <SDL.h>
#include <stdio.h>
#include <stdlib.h>

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;
}
Comment 1 Mark Linimon 2008-01-27 17:23:52 UTC
To which port does this PR apply?

mcl
Comment 2 Diane Bruce freebsd_committer 2008-01-27 17:30:20 UTC
Responsible Changed
From-To: freebsd-ports-bugs->db

I'll take it
Comment 3 dfilter service freebsd_committer 2008-01-27 21:38:02 UTC
db          2008-01-27 21:37:56 UTC

  FreeBSD ports repository

  Added files:
    devel/sdl12/files    patch-include_SDL_stdinc.h 
  Log:
  - 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. [1]
  - Give maintaintership to submitter (as discussed on irc)
  
  PR:     ports/120052 [1]
  
  Revision  Changes    Path
  1.1       +10 -0     ports/devel/sdl12/files/patch-include_SDL_stdinc.h (new)
_______________________________________________
cvs-all@freebsd.org mailing list
http://lists.freebsd.org/mailman/listinfo/cvs-all
To unsubscribe, send any mail to "cvs-all-unsubscribe@freebsd.org"
Comment 4 Diane Bruce freebsd_committer 2008-01-27 21:38:23 UTC
State Changed
From-To: open->closed

Committed. Thanks!