From 5f2e2ef32a9606c7fa9ccd7411c5232a792ff7bf Mon Sep 17 00:00:00 2001 From: Darkvater Date: Sat, 18 Mar 2006 15:12:24 +0000 Subject: [PATCH] (svn r3948) - Fix: [ 1415782 ] crash in string code with openbsd/zaurus; alignment issues (thanks Tron for the help). Backport of r3529, r3553 from trunk --- gfx.c | 18 +++++++++--------- macros.h | 18 ++++++++++++------ smallmap_gui.c | 2 +- stdafx.h | 11 +++++------ strings.c | 3 ++- 5 files changed, 29 insertions(+), 23 deletions(-) diff --git a/gfx.c b/gfx.c index 7cf3f2dbbc..0d39984672 100644 --- a/gfx.c +++ b/gfx.c @@ -698,7 +698,7 @@ static void GfxBlitTileZoomIn(BlitterParams *bp) const byte* ctab; if (bp->mode & 1) { - src_o += READ_LE_UINT16(src_o + bp->start_y * 2); + src_o += ReadLE16Aligned(src_o + bp->start_y * 2); do { do { @@ -741,7 +741,7 @@ static void GfxBlitTileZoomIn(BlitterParams *bp) bp->dst += bp->pitch; } while (--bp->height != 0); } else if (bp->mode & 2) { - src_o += READ_LE_UINT16(src_o + bp->start_y * 2); + src_o += ReadLE16Aligned(src_o + bp->start_y * 2); do { do { done = src_o[0]; @@ -775,7 +775,7 @@ static void GfxBlitTileZoomIn(BlitterParams *bp) bp->dst += bp->pitch; } while (--bp->height != 0); } else { - src_o += READ_LE_UINT16(src_o + bp->start_y * 2); + src_o += ReadLE16Aligned(src_o + bp->start_y * 2); do { do { done = src_o[0]; @@ -900,7 +900,7 @@ static void GfxBlitTileZoomMedium(BlitterParams *bp) const byte* ctab; if (bp->mode & 1) { - src_o += READ_LE_UINT16(src_o + bp->start_y * 2); + src_o += ReadLE16Aligned(src_o + bp->start_y * 2); do { do { done = src_o[0]; @@ -949,7 +949,7 @@ static void GfxBlitTileZoomMedium(BlitterParams *bp) } while (!(done & 0x80)); } while (--bp->height != 0); } else if (bp->mode & 2) { - src_o += READ_LE_UINT16(src_o + bp->start_y * 2); + src_o += ReadLE16Aligned(src_o + bp->start_y * 2); do { do { done = src_o[0]; @@ -994,7 +994,7 @@ static void GfxBlitTileZoomMedium(BlitterParams *bp) } while (!(done & 0x80)); } while (--bp->height != 0); } else { - src_o += READ_LE_UINT16(src_o + bp->start_y * 2); + src_o += ReadLE16Aligned(src_o + bp->start_y * 2); do { do { done = src_o[0]; @@ -1105,7 +1105,7 @@ static void GfxBlitTileZoomOut(BlitterParams *bp) const byte* ctab; if (bp->mode & 1) { - src_o += READ_LE_UINT16(src_o + bp->start_y * 2); + src_o += ReadLE16Aligned(src_o + bp->start_y * 2); for(;;) { do { done = src_o[0]; @@ -1174,7 +1174,7 @@ static void GfxBlitTileZoomOut(BlitterParams *bp) if (--bp->height == 0) return; } } else if (bp->mode & 2) { - src_o += READ_LE_UINT16(src_o + bp->start_y * 2); + src_o += ReadLE16Aligned(src_o + bp->start_y * 2); for(;;) { do { done = src_o[0]; @@ -1239,7 +1239,7 @@ static void GfxBlitTileZoomOut(BlitterParams *bp) if (--bp->height == 0) return; } } else { - src_o += READ_LE_UINT16(src_o + bp->start_y * 2); + src_o += ReadLE16Aligned(src_o + bp->start_y * 2); for(;;) { do { done = src_o[0]; diff --git a/macros.h b/macros.h index b9faad6b2a..e4fce51d3b 100644 --- a/macros.h +++ b/macros.h @@ -142,14 +142,20 @@ static inline void swap_int32(int32 *a, int32 *b) { int32 t = *a; *a = *b; *b = static inline void swap_tile(TileIndex *a, TileIndex *b) { TileIndex t = *a; *a = *b; *b = t; } +static inline uint16 ReadLE16Aligned(const void* x) +{ + return FROM_LE16(*(const uint16*)x); +} -#if defined(TTD_LITTLE_ENDIAN) -# define READ_LE_UINT16(b) (*(const uint16*)(b)) -#elif defined(TTD_BIG_ENDIAN) - static inline uint16 READ_LE_UINT16(const void *b) { - return ((const byte*)b)[0] + (((const byte*)b)[1] << 8); - } +static inline uint16 ReadLE16Unaligned(const void* x) +{ +#ifdef OTTD_ALIGNMENT + return ((const byte*)x)[0] | ((const byte*)x)[1] << 8; +#else + return FROM_LE16(*(const uint16*)x); #endif +} + /** * ROtate x Left/Right by n (must be >= 0) diff --git a/smallmap_gui.c b/smallmap_gui.c index 2cad09a724..93881fd996 100644 --- a/smallmap_gui.c +++ b/smallmap_gui.c @@ -193,7 +193,7 @@ static const uint16 * const _legend_table[] = { _legend_industries_candy, }; -#if defined(TTD_ALIGNMENT_4) +#if defined(OTTD_ALIGNMENT) static inline void WRITE_PIXELS(Pixel* d, uint32 val) { # if defined(TTD_BIG_ENDIAN) diff --git a/stdafx.h b/stdafx.h index 0589002a67..0ff1e55c85 100644 --- a/stdafx.h +++ b/stdafx.h @@ -82,8 +82,6 @@ # define CDECL # define NOT_REACHED() assert(0) # define GCC_PACK -# undef TTD_ALIGNMENT_4 -# undef TTD_ALIGNMENT_2 # include #endif /* __WATCOMC__ */ @@ -133,8 +131,6 @@ # endif # endif /* _MSC_VER < 1300 */ -# undef TTD_ALIGNMENT_4 -# undef TTD_ALIGNMENT_2 # define GCC_PACK // This is needed to zlib uses the stdcall calling convention on visual studio, also used with libpng (VS6 warning) @@ -193,10 +189,13 @@ typedef unsigned char byte; typedef unsigned __int64 uint64; #endif /* __BEOS__ */ +#if defined(ARM) || defined(__arm__) || defined(__alpha__) +# define OTTD_ALIGNMENT +#endif + // Setup alignment and conversion macros #if defined(TTD_BIG_ENDIAN) -# define TTD_ALIGNMENT_2 -# define TTD_ALIGNMENT_4 +# define OTTD_ALIGNMENT static inline uint32 TO_LE32(uint32 x) { return BSWAP32(x); } static inline uint16 TO_LE16(uint16 x) { return BSWAP16(x); } static inline uint32 FROM_LE32(uint32 x) { return BSWAP32(x); } diff --git a/strings.c b/strings.c index 4db8d29aca..f7c584e008 100644 --- a/strings.c +++ b/strings.c @@ -499,6 +499,7 @@ static char *FormatString(char *buff, const char *str, const int32 *argv, uint c break; case 0x81: // {STRINL} + buff = GetStringWithArgs(buff, ReadLE16Unaligned(str), argv); str += 2; buff = GetStringWithArgs(buff, READ_LE_UINT16(str-2), argv); break; @@ -1013,7 +1014,7 @@ bool ReadLanguagePack(int lang_index) #if defined(TTD_BIG_ENDIAN) for (i = 0; i != 32; i++) { - lang_pack->offsets[i] = READ_LE_UINT16(&lang_pack->offsets[i]); + lang_pack->offsets[i] = ReadLE16Aligned(&lang_pack->offsets[i]); } #endif