Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

avoid unaligned loads / stores #93

Open
wants to merge 2 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
21 changes: 18 additions & 3 deletions src/libmodplug/sndfile.h
Original file line number Diff line number Diff line change
Expand Up @@ -804,9 +804,6 @@ class MODPLUG_EXPORT CSoundFile
};


// inline DWORD BigEndian(DWORD x) { return ((x & 0xFF) << 24) | ((x & 0xFF00) << 8) | ((x & 0xFF0000) >> 8) | ((x & 0xFF000000) >> 24); }
// inline WORD BigEndianW(WORD x) { return (WORD)(((x >> 8) & 0xFF) | ((x << 8) & 0xFF00)); }


//////////////////////////////////////////////////////////
// WAVE format information
Expand Down Expand Up @@ -958,6 +955,24 @@ int _muldiv(long a, long b, long c);
int _muldivr(long a, long b, long c);


// Functions to read 16 and 32 bits endian-specific data and return in native format:

inline WORD READ_LE16(LPCBYTE b) {
return (WORD)b[0] | ((WORD)b[1] << 8);
}

inline WORD READ_BE16(LPCBYTE b) {
return (WORD)b[1] | ((WORD)b[0] << 8);
}

inline DWORD READ_LE32(LPCBYTE b) {
return (DWORD)b[0] | ((DWORD)b[1] << 8) | ((DWORD)b[2] << 16) | ((DWORD)b[3] << 24);
}

inline DWORD READ_BE32(LPCBYTE b) {
return (DWORD)b[3] | ((DWORD)b[2] << 8) | ((DWORD)b[1] << 16) | ((DWORD)b[0] << 24);
}

// Byte swapping functions from the GNU C Library and libsdl

/* Swap bytes in 16 bit value. */
Expand Down
18 changes: 9 additions & 9 deletions src/load_amf.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ VOID AMF_Unpack(MODCOMMAND *pPat, const BYTE *pTrack, UINT nRows, UINT nChannels
//-------------------------------------------------------------------------------
{
UINT lastinstr = 0;
UINT nTrkSize = bswapLE16(*(USHORT *)pTrack);
UINT nTrkSize = READ_LE16(pTrack);
nTrkSize += (UINT)pTrack[2] << 16;
pTrack += 3;
while (nTrkSize--)
Expand Down Expand Up @@ -203,9 +203,9 @@ BOOL CSoundFile::ReadAMF(LPCBYTE lpStream, const DWORD dwMemLength)
psmp->nGlobalVol = 64;
if (psmp->nVolume > 0x40) psmp->nVolume = 0x40;
psmp->nVolume <<= 2;
psmp->nLength = bswapLE32(*((LPDWORD)(lpStream+dwMemPos+25)));
psmp->nLoopStart = bswapLE32(*((LPDWORD)(lpStream+dwMemPos+29)));
psmp->nLoopEnd = psmp->nLoopStart + bswapLE32(*((LPDWORD)(lpStream+dwMemPos+33)));
psmp->nLength = READ_LE32(lpStream+dwMemPos+25);
psmp->nLoopStart = READ_LE32(lpStream+dwMemPos+29);
psmp->nLoopEnd = psmp->nLoopStart + READ_LE32(lpStream+dwMemPos+33);
if ((psmp->nLoopEnd > psmp->nLoopStart) && (psmp->nLoopEnd <= psmp->nLength))
{
psmp->uFlags = CHN_LOOP;
Expand Down Expand Up @@ -319,7 +319,7 @@ BOOL CSoundFile::ReadAMF(LPCBYTE lpStream, const DWORD dwMemLength)
if (pfh->version >= 14)
{
if (dwMemPos + m_nChannels * sizeof(USHORT) + 2 > dwMemLength) return FALSE;
PatternSize[iOrd] = bswapLE16(*(USHORT *)(lpStream+dwMemPos));
PatternSize[iOrd] = READ_LE16(lpStream+dwMemPos);
dwMemPos += 2;
} else
{
Expand Down Expand Up @@ -348,12 +348,12 @@ BOOL CSoundFile::ReadAMF(LPCBYTE lpStream, const DWORD dwMemLength)
pins->nVolume = psh->volume * 4;
if (pfh->version >= 11)
{
pins->nLoopStart = bswapLE32(*(DWORD *)(lpStream+dwMemPos));
pins->nLoopEnd = bswapLE32(*(DWORD *)(lpStream+dwMemPos+4));
pins->nLoopStart = READ_LE32(lpStream+dwMemPos);
pins->nLoopEnd = READ_LE32(lpStream+dwMemPos+4);
dwMemPos += 8;
} else
{
pins->nLoopStart = bswapLE16(*(WORD *)(lpStream+dwMemPos));
pins->nLoopStart = READ_LE16(lpStream+dwMemPos);
pins->nLoopEnd = pins->nLength;
dwMemPos += 2;
}
Expand Down Expand Up @@ -383,7 +383,7 @@ BOOL CSoundFile::ReadAMF(LPCBYTE lpStream, const DWORD dwMemLength)
memset(pTrackData, 0, sizeof(BYTE *) * realtrackcnt);
for (UINT iTrack=0; iTrack<realtrackcnt; iTrack++) if (dwMemPos <= dwMemLength - 3)
{
UINT nTrkSize = bswapLE16(*(USHORT *)(lpStream+dwMemPos));
UINT nTrkSize = READ_LE16(lpStream+dwMemPos);
nTrkSize += (UINT)lpStream[dwMemPos+2] << 16;
if (dwMemPos + nTrkSize * 3 + 3 <= dwMemLength)
{
Expand Down
12 changes: 6 additions & 6 deletions src/load_ams.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -118,7 +118,7 @@ BOOL CSoundFile::ReadAMS(LPCBYTE lpStream, DWORD dwMemLength)
}
// Read Song Comments
if (dwMemPos + 2 > dwMemLength) return TRUE;
tmp = *((WORD *)(lpStream+dwMemPos));
tmp = READ_LE16(lpStream+dwMemPos);
dwMemPos += 2;
if (tmp >= dwMemLength || dwMemPos > dwMemLength - tmp) return TRUE;
if (tmp)
Expand All @@ -133,14 +133,14 @@ BOOL CSoundFile::ReadAMS(LPCBYTE lpStream, DWORD dwMemLength)
if (2*pfh->orders >= dwMemLength || dwMemPos > dwMemLength - 2*pfh->orders) return TRUE;
for (UINT iOrd=0; iOrd<pfh->orders; iOrd++, dwMemPos += 2)
{
UINT n = *((WORD *)(lpStream+dwMemPos));
UINT n = READ_LE16(lpStream+dwMemPos);
Order[iOrd] = (BYTE)n;
}
// Read Patterns
for (UINT iPat=0; iPat<pfh->patterns; iPat++)
{
if (dwMemPos + 4 >= dwMemLength) return TRUE;
UINT len = *((DWORD *)(lpStream + dwMemPos));
UINT len = READ_LE32(lpStream + dwMemPos);
dwMemPos += 4;
if ((len >= dwMemLength) || (dwMemPos > dwMemLength - len)) return TRUE;
PatternSize[iPat] = 64;
Expand Down Expand Up @@ -466,7 +466,7 @@ BOOL CSoundFile::ReadAMS2(LPCBYTE lpStream, DWORD dwMemLength)
if (dwMemPos + chnnamlen + 256 >= dwMemLength) return TRUE;
}
// packed comments (ignored)
UINT songtextlen = *((LPDWORD)(lpStream+dwMemPos));
UINT songtextlen = READ_LE32(lpStream+dwMemPos);
dwMemPos += songtextlen;
if (dwMemPos + 256 >= dwMemLength) return TRUE;
}
Expand All @@ -487,7 +487,7 @@ BOOL CSoundFile::ReadAMS2(LPCBYTE lpStream, DWORD dwMemLength)
for (UINT ipat=0; ipat<psh->patterns; ipat++)
{
if (dwMemPos+8 >= dwMemLength) return TRUE;
UINT packedlen = *((LPDWORD)(lpStream+dwMemPos));
UINT packedlen = READ_LE32(lpStream+dwMemPos);
UINT numrows = 1 + (UINT)(lpStream[dwMemPos+4]);
//UINT patchn = 1 + (UINT)(lpStream[dwMemPos+5] & 0x1F);
//UINT patcmds = 1 + (UINT)(lpStream[dwMemPos+5] >> 5);
Expand Down Expand Up @@ -579,7 +579,7 @@ static BOOL AMSUnpackCheck(const BYTE *lpStream, DWORD dwMemLength, MODINSTRUMEN
// -----------------------------------------------------------------------------------
{
if (dwMemLength < 9) return FALSE;
DWORD packedbytes = *((DWORD *)(lpStream + 4));
DWORD packedbytes = READ_LE32(lpStream + 4);

DWORD samplebytes = ins->nLength;
if (samplebytes > MAX_SAMPLE_LENGTH) samplebytes = MAX_SAMPLE_LENGTH;
Expand Down
6 changes: 3 additions & 3 deletions src/load_dmf.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -106,7 +106,7 @@ BOOL CSoundFile::ReadDMF(const BYTE *lpStream, DWORD dwMemLength)
#endif
while (dwMemPos < dwMemLength - 7)
{
DWORD id = *((LPDWORD)(lpStream+dwMemPos));
DWORD id = READ_LE32(lpStream+dwMemPos);

switch(id)
{
Expand Down Expand Up @@ -456,10 +456,10 @@ BOOL CSoundFile::ReadDMF(const BYTE *lpStream, DWORD dwMemLength)
#endif
break;
}
pksize = *((LPDWORD)(lpStream+dwPos));
pksize = READ_LE32(lpStream+dwPos);
#ifdef DMFLOG
Log("sample %d: pos=0x%X pksize=%d ", iSmp, dwPos, pksize);
Log("len=%d flags=0x%X [%08X]\n", Ins[iSmp].nLength, smplflags[ismpd], *((LPDWORD)(lpStream+dwPos+4)));
Log("len=%d flags=0x%X [%08X]\n", Ins[iSmp].nLength, smplflags[ismpd], READ_LE32(lpStream+dwPos+4));
#endif
dwPos += 4;
if (pksize > dwMemLength - dwPos)
Expand Down
30 changes: 15 additions & 15 deletions src/load_it.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -259,7 +259,7 @@ BOOL CSoundFile::ReadIT(const BYTE *lpStream, DWORD dwMemLength)
// Reading IT Extra Info
if (dwMemPos + 2 < dwMemLength)
{
UINT nflt = bswapLE16(*((WORD *)(lpStream + dwMemPos)));
UINT nflt = READ_LE16(lpStream + dwMemPos);
dwMemPos += 2;
if (dwMemPos + nflt * 8 < dwMemLength) dwMemPos += nflt * 8;
}
Expand All @@ -273,9 +273,9 @@ BOOL CSoundFile::ReadIT(const BYTE *lpStream, DWORD dwMemLength)
}
}
// Read pattern names: "PNAM"
if ((dwMemPos + 8 < dwMemLength) && (bswapLE32(*((DWORD *)(lpStream+dwMemPos))) == 0x4d414e50))
if ((dwMemPos + 8 < dwMemLength) && (READ_LE32(lpStream+dwMemPos) == 0x4d414e50))
{
UINT len = bswapLE32(*((DWORD *)(lpStream+dwMemPos+4)));
UINT len = READ_LE32(lpStream+dwMemPos+4);
dwMemPos += 8;
if ((dwMemPos + len <= dwMemLength) && (len <= MAX_PATTERNS*MAX_PATTERNNAME) && (len >= MAX_PATTERNNAME))
{
Expand All @@ -291,9 +291,9 @@ BOOL CSoundFile::ReadIT(const BYTE *lpStream, DWORD dwMemLength)
// 4-channels minimum
m_nChannels = 4;
// Read channel names: "CNAM"
if ((dwMemPos + 8 < dwMemLength) && (bswapLE32(*((DWORD *)(lpStream+dwMemPos))) == 0x4d414e43))
if ((dwMemPos + 8 < dwMemLength) && (READ_LE32(lpStream+dwMemPos) == 0x4d414e43))
{
UINT len = bswapLE32(*((DWORD *)(lpStream+dwMemPos+4)));
UINT len = READ_LE32(lpStream+dwMemPos+4);
dwMemPos += 8;
if ((dwMemPos + len <= dwMemLength) && (len <= 64*MAX_CHANNELNAME))
{
Expand All @@ -319,8 +319,8 @@ BOOL CSoundFile::ReadIT(const BYTE *lpStream, DWORD dwMemLength)
{
memset(chnmask, 0, sizeof(chnmask));
if ((!patpos[patchk]) || ((DWORD)patpos[patchk] >= dwMemLength - 4)) continue;
UINT len = bswapLE16(*((WORD *)(lpStream+patpos[patchk])));
UINT rows = bswapLE16(*((WORD *)(lpStream+patpos[patchk]+2)));
UINT len = READ_LE16(lpStream+patpos[patchk]);
UINT rows = READ_LE16(lpStream+patpos[patchk]+2);
if ((rows < 4) || (rows > 256)) continue;
if (8+len > dwMemLength || patpos[patchk] > dwMemLength - (8+len)) continue;
UINT i = 0;
Expand Down Expand Up @@ -451,8 +451,8 @@ BOOL CSoundFile::ReadIT(const BYTE *lpStream, DWORD dwMemLength)
continue;
}

UINT len = bswapLE16(*((WORD *)(lpStream+patpos[npat])));
UINT rows = bswapLE16(*((WORD *)(lpStream+patpos[npat]+2)));
UINT len = READ_LE16(lpStream+patpos[npat]);
UINT rows = READ_LE16(lpStream+patpos[npat]+2);
if ((rows < 4) || (rows > 256)) continue;
if (8+len > dwMemLength || patpos[npat] > dwMemLength - (8+len)) continue;
PatternSize[npat] = rows;
Expand Down Expand Up @@ -1233,7 +1233,7 @@ DWORD ITUnpack8Bit(signed char *pSample, DWORD dwLen, LPBYTE lpMemFile, DWORD dw
if (!wCount)
{
wCount = 0x8000;
// wHdr = bswapLE16(*((LPWORD)pSrc));
// wHdr = READ_LE16(pSrc);
pSrc += 2;
bLeft = 9;
bTemp = bTemp2 = 0;
Expand Down Expand Up @@ -1320,7 +1320,7 @@ DWORD ITUnpack16Bit(signed char *pSample, DWORD dwLen, LPBYTE lpMemFile, DWORD d
if (!wCount)
{
wCount = 0x4000;
// wHdr = bswapLE16(*((LPWORD)pSrc));
// wHdr = READ_LE16(pSrc);
pSrc += 2;
bLeft = 17;
wTemp = wTemp2 = 0;
Expand Down Expand Up @@ -1482,13 +1482,13 @@ UINT CSoundFile::LoadMixPlugins(const void *pData, UINT nLen)
DWORD nPluginSize;
UINT nPlugin;

nPluginSize = bswapLE32(*(DWORD *)(p+nPos+4));
nPluginSize = READ_LE32(p+nPos+4);
if (nPluginSize > nLen-nPos-8) break;;
if ((bswapLE32(*(DWORD *)(p+nPos))) == 0x58464843)
if (READ_LE32(p+nPos) == 0x58464843)
{
for (UINT ch=0; ch<64; ch++) if (ch*4 < nPluginSize)
{
ChnSettings[ch].nMixPlugin = bswapLE32(*(DWORD *)(p+nPos+8+ch*4));
ChnSettings[ch].nMixPlugin = READ_LE32(p+nPos+8+ch*4);
}
} else
{
Expand All @@ -1500,7 +1500,7 @@ UINT CSoundFile::LoadMixPlugins(const void *pData, UINT nLen)
nPlugin = (p[nPos+2]-'0')*10 + (p[nPos+3]-'0');
if ((nPlugin < MAX_MIXPLUGINS) && (nPluginSize >= sizeof(SNDMIXPLUGININFO)+4))
{
DWORD dwExtra = bswapLE32(*(DWORD *)(p+nPos+8+sizeof(SNDMIXPLUGININFO)));
DWORD dwExtra = READ_LE32(p+nPos+8+sizeof(SNDMIXPLUGININFO));
m_MixPlugins[nPlugin].Info = *(const SNDMIXPLUGININFO *)(p+nPos+8);
m_MixPlugins[nPlugin].Info.dwPluginId1 = bswapLE32(m_MixPlugins[nPlugin].Info.dwPluginId1);
m_MixPlugins[nPlugin].Info.dwPluginId2 = bswapLE32(m_MixPlugins[nPlugin].Info.dwPluginId2);
Expand Down
Loading