Detect potential misalignment in modern

This commit is contained in:
Martin Griffin
2023-07-24 19:04:23 +01:00
parent b53cca1a06
commit 31a3ada7de
30 changed files with 142 additions and 45 deletions

View File

@@ -3,7 +3,7 @@
#include "sprite.h"
extern u8 gDecompressionBuffer[0x4000];
extern u8 ALIGNED(4) gDecompressionBuffer[0x4000];
void LZDecompressWram(const u32 *src, void *dest);
void LZDecompressVram(const u32 *src, void *dest);

View File

@@ -213,7 +213,7 @@ struct SoundInfo
ExtVolPitFunc ExtVolPit;
u8 gap2[16];
struct SoundChannel chans[MAX_DIRECTSOUND_CHANNELS];
s8 pcmBuffer[PCM_DMA_BUF_SIZE * 2];
s8 ALIGNED(4) pcmBuffer[PCM_DMA_BUF_SIZE * 2];
};
struct SongHeader

View File

@@ -1,7 +1,7 @@
#ifndef GUARD_GBA_MACRO_H
#define GUARD_GBA_MACRO_H
#define CPU_FILL(value, dest, size, bit) \
#define CPU_FILL_UNCHECKED(value, dest, size, bit) \
{ \
vu##bit tmp = (vu##bit)(value); \
CpuSet((void *)&tmp, \
@@ -9,10 +9,33 @@
CPU_SET_##bit##BIT | CPU_SET_SRC_FIXED | ((size)/(bit/8) & 0x1FFFFF)); \
}
#if MODERN
#define CPU_FILL(value, dest, size, bit) \
do \
{ \
_Static_assert(_Alignof(dest) >= (bit / 8), "destination potentially unaligned"); \
CPU_FILL_UNCHECKED(value, dest, size, bit); \
} while (0)
#else
#define CPU_FILL(value, dest, size, bit) CPU_FILL_UNCHECKED(value, dest, size, bit)
#endif
#define CpuFill16(value, dest, size) CPU_FILL(value, dest, size, 16)
#define CpuFill32(value, dest, size) CPU_FILL(value, dest, size, 32)
#define CPU_COPY(src, dest, size, bit) CpuSet(src, dest, CPU_SET_##bit##BIT | ((size)/(bit/8) & 0x1FFFFF))
#define CPU_COPY_UNCHECKED(src, dest, size, bit) CpuSet(src, dest, CPU_SET_##bit##BIT | ((size)/(bit/8) & 0x1FFFFF))
#if MODERN
#define CPU_COPY(src, dest, size, bit) \
do \
{ \
_Static_assert(_Alignof(src) >= (bit / 8), "source potentially unaligned"); \
_Static_assert(_Alignof(dest) >= (bit / 8), "destination potentially unaligned"); \
CPU_COPY_UNCHECKED(src, dest, size, bit); \
} while (0)
#else
#define CPU_COPY(src, dest, size, bit) CPU_COPY_UNCHECKED(src, dest, size, bit)
#endif
#define CpuCopy16(src, dest, size) CPU_COPY(src, dest, size, 16)
#define CpuCopy32(src, dest, size) CPU_COPY(src, dest, size, 32)
@@ -31,7 +54,7 @@
#define CpuFastCopy(src, dest, size) CpuFastSet(src, dest, ((size)/(32/8) & 0x1FFFFF))
#define DmaSet(dmaNum, src, dest, control) \
#define DmaSetUnchecked(dmaNum, src, dest, control) \
{ \
vu32 *dmaRegs = (vu32 *)REG_ADDR_DMA##dmaNum; \
dmaRegs[0] = (vu32)(src); \
@@ -40,7 +63,21 @@
dmaRegs[2]; \
}
#define DMA_FILL(dmaNum, value, dest, size, bit) \
#if MODERN
// NOTE: Assumes 16-bit DMAs.
#define DmaSet(dmaNum, src, dest, control) \
do \
{ \
_Static_assert(_Alignof(src) >= __builtin_choose_expr(__builtin_constant_p(control), ((control) & (DMA_32BIT << 16)) ? 4 : 2, 2), "source potentially unaligned"); \
_Static_assert(_Alignof(dest) >= __builtin_choose_expr(__builtin_constant_p(control), ((control) & (DMA_32BIT << 16)) ? 4 : 2, 2), "destination potentially unaligned"); \
DmaSetUnchecked(dmaNum, src, dest, control); \
} while (0)
#else
#define DmaSet(dmaNum, src, dest, control) \
DmaSetUnchecked(dmaNum, src, dest, control)
#endif
#define DMA_FILL_UNCHECKED(dmaNum, value, dest, size, bit) \
{ \
vu##bit tmp = (vu##bit)(value); \
DmaSet(dmaNum, \
@@ -50,6 +87,17 @@
| ((size)/(bit/8))); \
}
#if MODERN
#define DMA_FILL(dmaNum, value, dest, size, bit) \
do \
{ \
_Static_assert(_Alignof(dest) >= (bit / 8), "destination potentially unaligned"); \
DMA_FILL_UNCHECKED(dmaNum, value, dest, size, bit); \
} while (0)
#else
#define DMA_FILL(dmaNum, value, dest, size, bit) DMA_FILL_UNCHECKED(dmaNum, value, dest, size, bit)
#endif
#define DmaFill16(dmaNum, value, dest, size) DMA_FILL(dmaNum, value, dest, size, 16)
#define DmaFill32(dmaNum, value, dest, size) DMA_FILL(dmaNum, value, dest, size, 32)
@@ -58,23 +106,46 @@
// unit size (2 or 4 bytes) and then combined with the DMA control flags using a
// bitwise OR operation.
#define DMA_CLEAR(dmaNum, dest, size, bit) \
#define DMA_CLEAR_UNCHECKED(dmaNum, dest, size, bit) \
{ \
vu##bit *_dest = (vu##bit *)(dest); \
u32 _size = size; \
DmaFill##bit(dmaNum, 0, _dest, _size); \
}
#if MODERN
#define DMA_CLEAR(dmaNum, dest, size, bit) \
do \
{ \
_Static_assert(_Alignof(dest) >= (bit / 8), "destination potentially unaligned"); \
DMA_CLEAR_UNCHECKED(dmaNum, dest, size, bit); \
} while (0)
#else
#define DMA_CLEAR(dmaNum, dest, size, bit) DMA_CLEAR_UNCHECKED(dmaNum, dest, size, bit)
#endif
#define DmaClear16(dmaNum, dest, size) DMA_CLEAR(dmaNum, dest, size, 16)
#define DmaClear32(dmaNum, dest, size) DMA_CLEAR(dmaNum, dest, size, 32)
#define DMA_COPY(dmaNum, src, dest, size, bit) \
#define DMA_COPY_UNCHECKED(dmaNum, src, dest, size, bit) \
DmaSet(dmaNum, \
src, \
dest, \
(DMA_ENABLE | DMA_START_NOW | DMA_##bit##BIT | DMA_SRC_INC | DMA_DEST_INC) << 16 \
| ((size)/(bit/8)))
#if MODERN
#define DMA_COPY(dmaNum, src, dest, size, bit) \
do \
{ \
_Static_assert(_Alignof(src) >= (bit / 8), "source potentially unaligned"); \
_Static_assert(_Alignof(dest) >= (bit / 8), "destination potentially unaligned"); \
DMA_COPY_UNCHECKED(dmaNum, src, dest, size, bit); \
} while (0)
#else
#define DMA_COPY(dmaNum, src, dest, size, bit) DMA_COPY_UNCHECKED(dmaNum, src, dest, size, bit)
#endif
#define DmaCopy16(dmaNum, src, dest, size) DMA_COPY(dmaNum, src, dest, size, 16)
#define DmaCopy32(dmaNum, src, dest, size) DMA_COPY(dmaNum, src, dest, size, 32)

View File

@@ -27,10 +27,32 @@ u16 ArcTan2(s16 x, s16 y);
void CpuSet(const void *src, void *dest, u32 control);
#if MODERN
// NOTE: Assumes 16-bit CpuSets unless control is a constant and has
// CPU_SET_32BIT set.
#define CpuSet(src, dest, control) \
do \
{ \
_Static_assert(_Alignof(src) >= __builtin_choose_expr(__builtin_constant_p(control), ((control) & CPU_SET_32BIT) ? 4 : 2, 2), "source potentially unaligned"); \
_Static_assert(_Alignof(dest) >= __builtin_choose_expr(__builtin_constant_p(control), ((control) & CPU_SET_32BIT) ? 4 : 2, 2), "destination potentially unaligned"); \
CpuSet(src, dest, control); \
} while (0)
#endif
#define CPU_FAST_SET_SRC_FIXED 0x01000000
void CpuFastSet(const void *src, void *dest, u32 control);
#if MODERN
#define CpuFastSet(src, dest, control) \
do \
{ \
_Static_assert(_Alignof(src) >= 4, "source potentially unaligned"); \
_Static_assert(_Alignof(dest) >= 4, "destination potentially unaligned"); \
CpuFastSet(src, dest, control); \
} while (0)
#endif
void BgAffineSet(struct BgAffineSrcData *src, struct BgAffineDstData *dest, s32 count);
void ObjAffineSet(struct ObjAffineSrcData *src, void *dest, s32 count, s32 offset);

View File

@@ -845,7 +845,7 @@ struct WaldaPhrase
struct TrainerNameRecord
{
u32 trainerId;
u8 trainerName[PLAYER_NAME_LENGTH + 1];
u8 ALIGNED(2) trainerName[PLAYER_NAME_LENGTH + 1];
};
struct TrainerHillSave

View File

@@ -3893,7 +3893,7 @@ extern const u32 gIntroGroudon_Gfx[];
extern const u32 gIntroGroudon_Tilemap[];
extern const u32 gIntroLegendBg_Gfx[];
extern const u32 gIntroGroudonBg_Tilemap[];
extern const u8 gIntro3Bg_Pal[0x200];
extern const u8 ALIGNED(2) gIntro3Bg_Pal[0x200];
extern const u32 gIntroKyogre_Gfx[];
extern const u32 gIntroKyogre_Tilemap[];
extern const u32 gIntroKyogreBg_Tilemap[];
@@ -5018,8 +5018,8 @@ extern const u32 gPokenavOptions_Gfx[];
extern const u16 gPokenavOptions_Pal[];
// Battle Factory Screen
extern const u8 gFrontierFactorySelectMenu_Gfx[];
extern const u8 gFrontierFactorySelectMenu_Tilemap[];
extern const u16 gFrontierFactorySelectMenu_Gfx[];
extern const u16 gFrontierFactorySelectMenu_Tilemap[];
extern const u16 gFrontierFactorySelectMenu_Pal[];
// Object event pals

View File

@@ -78,7 +78,7 @@ struct BagMenu
u8 numShownItems[POCKETS_COUNT];
s16 graphicsLoadState;
u8 unused2[14];
u8 pocketNameBuffer[32][32];
u8 ALIGNED(4) pocketNameBuffer[32][32];
u8 unused3[4];
};

View File

@@ -329,7 +329,7 @@ struct RfuIntrStruct
{
union RfuPacket rxPacketAlloc;
union RfuPacket txPacketAlloc;
u8 block1[0x960]; // size of librfu_intr.s binary
u8 ALIGNED(2) block1[0x960]; // size of librfu_intr.s binary
struct STWIStatus block2;
};

View File

@@ -238,7 +238,7 @@ struct BlockRequest
};
extern struct Link gLink;
extern u16 gRecvCmds[MAX_RFU_PLAYERS][CMD_LENGTH];
extern u16 ALIGNED(4) gRecvCmds[MAX_RFU_PLAYERS][CMD_LENGTH];
extern u8 gBlockSendBuffer[BLOCK_BUFFER_SIZE];
extern u16 gLinkType;
extern u32 gLinkStatus;

View File

@@ -18,7 +18,7 @@ struct MonMarkingsMenu
struct Sprite *textSprite;
const u8 *frameTiles;
const u16 *framePalette;
u8 windowSpriteTiles[0x1000];
u8 ALIGNED(2) windowSpriteTiles[0x1000];
u8 unused[0x80];
u8 tileLoadState;
};

View File

@@ -54,9 +54,9 @@ struct PaletteFadeControl
extern struct PaletteFadeControl gPaletteFade;
extern u32 gPlttBufferTransferPending;
extern u8 gPaletteDecompressionBuffer[];
extern u16 gPlttBufferUnfaded[PLTT_BUFFER_SIZE];
extern u16 gPlttBufferFaded[PLTT_BUFFER_SIZE];
extern u8 ALIGNED(4) gPaletteDecompressionBuffer[];
extern u16 ALIGNED(4) gPlttBufferUnfaded[PLTT_BUFFER_SIZE];
extern u16 ALIGNED(4) gPlttBufferFaded[PLTT_BUFFER_SIZE];
void LoadCompressedPalette(const u32 *src, u16 offset, u16 size);
void LoadPalette(const void *src, u16 offset, u16 size);

View File

@@ -37,7 +37,7 @@ struct ScanlineEffect
extern struct ScanlineEffect gScanlineEffect;
extern u16 gScanlineEffectRegBuffers[2][0x3C0];
extern u16 ALIGNED(4) gScanlineEffectRegBuffers[2][0x3C0];
void ScanlineEffect_Stop(void);
void ScanlineEffect_Clear(void);