|
|
@ -1,109 +1,15 @@ |
|
|
|
Description: Handle unaligned buffers in connect's TYPBLK class |
|
|
|
On MIPS platforms (and probably others) unaligned memory access results in a |
|
|
|
bus error. In the connect storage engine, block data for some data formats is |
|
|
|
stored packed in memory and the TYPBLK class is used to read values from it. |
|
|
|
Since TYPBLK does not have special handling for this packed memory, it can |
|
|
|
quite easily result in unaligned memory accesses. |
|
|
|
. |
|
|
|
The simple way to fix this is to perform all accesses to the main buffer |
|
|
|
through memcpy. With GCC and optimizations turned on, this call to memcpy is |
|
|
|
completely optimized away on architectures where unaligned accesses are ok |
|
|
|
(like x86). |
|
|
|
Author: James Cowgill <jcowgill@debian.org> |
|
|
|
From: Debian MySQL Maintainers <pkg-mysql-maint@lists.alioth.debian.org> |
|
|
|
Date: Thu, 10 Aug 2017 20:40:28 +0200 |
|
|
|
Subject: mips-connect-unaligned |
|
|
|
|
|
|
|
---
|
|
|
|
This patch header follows DEP-3: http://dep.debian.net/deps/dep3/ |
|
|
|
--- a/storage/connect/valblk.h
|
|
|
|
+++ b/storage/connect/valblk.h
|
|
|
|
@@ -139,6 +139,7 @@ class VALBLK : public BLOCK {
|
|
|
|
int Prec; // Precision of float values |
|
|
|
}; // end of class VALBLK |
|
|
|
|
|
|
|
+
|
|
|
|
/***********************************************************************/ |
|
|
|
/* Class TYPBLK: represents a block of typed values. */ |
|
|
|
/***********************************************************************/ |
|
|
|
@@ -151,40 +152,41 @@ class TYPBLK : public VALBLK {
|
|
|
|
// Implementation |
|
|
|
virtual bool Init(PGLOBAL g, bool check); |
|
|
|
virtual int GetVlen(void) {return sizeof(TYPE);} |
|
|
|
- virtual char GetTinyValue(int n) {return (char)Typp[n];}
|
|
|
|
- virtual uchar GetUTinyValue(int n) {return (uchar)Typp[n];}
|
|
|
|
- virtual short GetShortValue(int n) {return (short)Typp[n];}
|
|
|
|
- virtual ushort GetUShortValue(int n) {return (ushort)Typp[n];}
|
|
|
|
- virtual int GetIntValue(int n) {return (int)Typp[n];}
|
|
|
|
- virtual uint GetUIntValue(int n) {return (uint)Typp[n];}
|
|
|
|
- virtual longlong GetBigintValue(int n) {return (longlong)Typp[n];}
|
|
|
|
- virtual ulonglong GetUBigintValue(int n) {return (ulonglong)Typp[n];}
|
|
|
|
- virtual double GetFloatValue(int n) {return (double)Typp[n];}
|
|
|
|
+
|
|
|
|
+ virtual char GetTinyValue(int n) {return (char)UnalignedRead(n);}
|
|
|
|
+ virtual uchar GetUTinyValue(int n) {return (uchar)UnalignedRead(n);}
|
|
|
|
+ virtual short GetShortValue(int n) {return (short)UnalignedRead(n);}
|
|
|
|
+ virtual ushort GetUShortValue(int n) {return (ushort)UnalignedRead(n);}
|
|
|
|
+ virtual int GetIntValue(int n) {return (int)UnalignedRead(n);}
|
|
|
|
+ virtual uint GetUIntValue(int n) {return (uint)UnalignedRead(n);}
|
|
|
|
+ virtual longlong GetBigintValue(int n) {return (longlong)UnalignedRead(n);}
|
|
|
|
+ virtual ulonglong GetUBigintValue(int n) {return (ulonglong)UnalignedRead(n);}
|
|
|
|
+ virtual double GetFloatValue(int n) {return (double)UnalignedRead(n);}
|
|
|
|
virtual char *GetCharString(char *p, int n); |
|
|
|
- virtual void Reset(int n) {Typp[n] = 0;}
|
|
|
|
+ virtual void Reset(int n) {UnalignedWrite(n, 0);}
|
|
|
|
|
|
|
|
// Methods |
|
|
|
using VALBLK::SetValue; |
|
|
|
virtual void SetValue(PCSZ sp, int n); |
|
|
|
virtual void SetValue(const char *sp, uint len, int n); |
|
|
|
virtual void SetValue(short sval, int n) |
|
|
|
- {Typp[n] = (TYPE)sval; SetNull(n, false);}
|
|
|
|
+ {UnalignedWrite(n, (TYPE)sval); SetNull(n, false);}
|
|
|
|
virtual void SetValue(ushort sval, int n) |
|
|
|
- {Typp[n] = (TYPE)sval; SetNull(n, false);}
|
|
|
|
+ {UnalignedWrite(n, (TYPE)sval); SetNull(n, false);}
|
|
|
|
virtual void SetValue(int lval, int n) |
|
|
|
- {Typp[n] = (TYPE)lval; SetNull(n, false);}
|
|
|
|
+ {UnalignedWrite(n, (TYPE)lval); SetNull(n, false);}
|
|
|
|
virtual void SetValue(uint lval, int n) |
|
|
|
- {Typp[n] = (TYPE)lval; SetNull(n, false);}
|
|
|
|
+ {UnalignedWrite(n, (TYPE)lval); SetNull(n, false);}
|
|
|
|
virtual void SetValue(longlong lval, int n) |
|
|
|
- {Typp[n] = (TYPE)lval; SetNull(n, false);}
|
|
|
|
+ {UnalignedWrite(n, (TYPE)lval); SetNull(n, false);}
|
|
|
|
virtual void SetValue(ulonglong lval, int n) |
|
|
|
- {Typp[n] = (TYPE)lval; SetNull(n, false);}
|
|
|
|
+ {UnalignedWrite(n, (TYPE)lval); SetNull(n, false);}
|
|
|
|
virtual void SetValue(double fval, int n) |
|
|
|
- {Typp[n] = (TYPE)fval; SetNull(n, false);}
|
|
|
|
+ {UnalignedWrite(n, (TYPE)fval); SetNull(n, false);}
|
|
|
|
virtual void SetValue(char cval, int n) |
|
|
|
- {Typp[n] = (TYPE)cval; SetNull(n, false);}
|
|
|
|
+ {UnalignedWrite(n, (TYPE)cval); SetNull(n, false);}
|
|
|
|
virtual void SetValue(uchar cval, int n) |
|
|
|
- {Typp[n] = (TYPE)cval; SetNull(n, false);}
|
|
|
|
+ {UnalignedWrite(n, (TYPE)cval); SetNull(n, false);}
|
|
|
|
virtual void SetValue(PVAL valp, int n); |
|
|
|
virtual void SetValue(PVBLK pv, int n1, int n2); |
|
|
|
virtual void SetMin(PVAL valp, int n); |
|
|
|
@@ -206,6 +208,17 @@ class TYPBLK : public VALBLK {
|
|
|
|
// Members |
|
|
|
TYPE* const &Typp; |
|
|
|
const char *Fmt; |
|
|
|
+
|
|
|
|
+ // Unaligned access
|
|
|
|
+ TYPE UnalignedRead(int n) const {
|
|
|
|
+ TYPE result;
|
|
|
|
+ memcpy(&result, Typp + n, sizeof(TYPE));
|
|
|
|
+ return result;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ void UnalignedWrite(int n, TYPE value) {
|
|
|
|
+ memcpy(Typp + n, &value, sizeof(TYPE));
|
|
|
|
+ }
|
|
|
|
}; // end of class TYPBLK |
|
|
|
|
|
|
|
/***********************************************************************/ |
|
|
|
storage/connect/valblk.cpp | 41 ++++++++++++++++++------------------- |
|
|
|
storage/connect/valblk.h | 51 +++++++++++++++++++++++++++++----------------- |
|
|
|
2 files changed, 52 insertions(+), 40 deletions(-) |
|
|
|
|
|
|
|
--- a/storage/connect/valblk.cpp
|
|
|
|
+++ b/storage/connect/valblk.cpp
|
|
|
|
@@ -266,14 +266,14 @@ bool TYPBLK<TYPE>::Init(PGLOBAL g, bool
|
|
|
|
@@ -268,14 +268,14 @@ bool TYPBLK<TYPE>::Init(PGLOBAL g, bool
|
|
|
|
template <class TYPE> |
|
|
|
char *TYPBLK<TYPE>::GetCharString(char *p, int n) |
|
|
|
{ |
|
|
@ -120,7 +26,7 @@ This patch header follows DEP-3: http://dep.debian.net/deps/dep3/ |
|
|
|
return p; |
|
|
|
} // end of GetCharString |
|
|
|
|
|
|
|
@@ -289,7 +289,7 @@ void TYPBLK<TYPE>::SetValue(PVAL valp, i
|
|
|
|
@@ -291,7 +291,7 @@ void TYPBLK<TYPE>::SetValue(PVAL valp, i
|
|
|
|
ChkTyp(valp); |
|
|
|
|
|
|
|
if (!(b = valp->IsNull())) |
|
|
@ -129,7 +35,7 @@ This patch header follows DEP-3: http://dep.debian.net/deps/dep3/ |
|
|
|
else |
|
|
|
Reset(n); |
|
|
|
|
|
|
|
@@ -351,9 +351,9 @@ void TYPBLK<TYPE>::SetValue(PCSZ p, int
|
|
|
|
@@ -353,9 +353,9 @@ void TYPBLK<TYPE>::SetValue(PCSZ p, int
|
|
|
|
ulonglong val = CharToNumber(p, strlen(p), maxval, Unsigned, &minus); |
|
|
|
|
|
|
|
if (minus && val < maxval) |
|
|
@ -141,7 +47,7 @@ This patch header follows DEP-3: http://dep.debian.net/deps/dep3/ |
|
|
|
|
|
|
|
SetNull(n, false); |
|
|
|
} // end of SetValue |
|
|
|
@@ -396,7 +396,7 @@ void TYPBLK<double>::SetValue(PCSZ p, in
|
|
|
|
@@ -398,7 +398,7 @@ void TYPBLK<double>::SetValue(PCSZ p, in
|
|
|
|
throw Type; |
|
|
|
} // endif Check |
|
|
|
|
|
|
@ -150,7 +56,7 @@ This patch header follows DEP-3: http://dep.debian.net/deps/dep3/ |
|
|
|
SetNull(n, false); |
|
|
|
} // end of SetValue |
|
|
|
|
|
|
|
@@ -428,7 +428,7 @@ void TYPBLK<TYPE>::SetValue(PVBLK pv, in
|
|
|
|
@@ -430,7 +430,7 @@ void TYPBLK<TYPE>::SetValue(PVBLK pv, in
|
|
|
|
ChkTyp(pv); |
|
|
|
|
|
|
|
if (!(b = pv->IsNull(n2) && Nullable)) |
|
|
@ -159,7 +65,7 @@ This patch header follows DEP-3: http://dep.debian.net/deps/dep3/ |
|
|
|
else |
|
|
|
Reset(n1); |
|
|
|
|
|
|
|
@@ -479,10 +479,10 @@ void TYPBLK<TYPE>::SetMin(PVAL valp, int
|
|
|
|
@@ -481,10 +481,10 @@ void TYPBLK<TYPE>::SetMin(PVAL valp, int
|
|
|
|
{ |
|
|
|
CheckParms(valp, n) |
|
|
|
TYPE tval = GetTypedValue(valp); |
|
|
@ -172,7 +78,7 @@ This patch header follows DEP-3: http://dep.debian.net/deps/dep3/ |
|
|
|
|
|
|
|
} // end of SetMin |
|
|
|
|
|
|
|
@@ -494,10 +494,10 @@ void TYPBLK<TYPE>::SetMax(PVAL valp, int
|
|
|
|
@@ -496,10 +496,10 @@ void TYPBLK<TYPE>::SetMax(PVAL valp, int
|
|
|
|
{ |
|
|
|
CheckParms(valp, n) |
|
|
|
TYPE tval = GetTypedValue(valp); |
|
|
@ -185,7 +91,7 @@ This patch header follows DEP-3: http://dep.debian.net/deps/dep3/ |
|
|
|
|
|
|
|
} // end of SetMax |
|
|
|
|
|
|
|
@@ -511,8 +511,7 @@ void TYPBLK<TYPE>::SetValues(PVBLK pv, i
|
|
|
|
@@ -513,8 +513,7 @@ void TYPBLK<TYPE>::SetValues(PVBLK pv, i
|
|
|
|
CheckType(pv) |
|
|
|
TYPE *lp = ((TYPBLK*)pv)->Typp; |
|
|
|
|
|
|
@ -195,7 +101,7 @@ This patch header follows DEP-3: http://dep.debian.net/deps/dep3/ |
|
|
|
|
|
|
|
} // end of SetValues |
|
|
|
#endif // 0 |
|
|
|
@@ -523,7 +522,7 @@ void TYPBLK<TYPE>::SetValues(PVBLK pv, i
|
|
|
|
@@ -525,7 +524,7 @@ void TYPBLK<TYPE>::SetValues(PVBLK pv, i
|
|
|
|
template <class TYPE> |
|
|
|
void TYPBLK<TYPE>::Move(int i, int j) |
|
|
|
{ |
|
|
@ -204,7 +110,7 @@ This patch header follows DEP-3: http://dep.debian.net/deps/dep3/ |
|
|
|
MoveNull(i, j); |
|
|
|
} // end of Move |
|
|
|
|
|
|
|
@@ -537,7 +536,7 @@ int TYPBLK<TYPE>::CompVal(PVAL vp, int n
|
|
|
|
@@ -539,7 +538,7 @@ int TYPBLK<TYPE>::CompVal(PVAL vp, int n
|
|
|
|
ChkIndx(n); |
|
|
|
ChkTyp(vp); |
|
|
|
#endif // _DEBUG |
|
|
@ -213,7 +119,7 @@ This patch header follows DEP-3: http://dep.debian.net/deps/dep3/ |
|
|
|
TYPE vlv = GetTypedValue(vp); |
|
|
|
|
|
|
|
return (vlv > mlv) ? 1 : (vlv < mlv) ? (-1) : 0; |
|
|
|
@@ -549,8 +548,8 @@ int TYPBLK<TYPE>::CompVal(PVAL vp, int n
|
|
|
|
@@ -551,8 +550,8 @@ int TYPBLK<TYPE>::CompVal(PVAL vp, int n
|
|
|
|
template <class TYPE> |
|
|
|
int TYPBLK<TYPE>::CompVal(int i1, int i2) |
|
|
|
{ |
|
|
@ -224,7 +130,7 @@ This patch header follows DEP-3: http://dep.debian.net/deps/dep3/ |
|
|
|
|
|
|
|
return (lv1 > lv2) ? 1 : (lv1 < lv2) ? (-1) : 0; |
|
|
|
} // end of CompVal |
|
|
|
@@ -587,7 +586,7 @@ int TYPBLK<TYPE>::Find(PVAL vp)
|
|
|
|
@@ -589,7 +588,7 @@ int TYPBLK<TYPE>::Find(PVAL vp)
|
|
|
|
TYPE n = GetTypedValue(vp); |
|
|
|
|
|
|
|
for (i = 0; i < Nval; i++) |
|
|
@ -233,7 +139,7 @@ This patch header follows DEP-3: http://dep.debian.net/deps/dep3/ |
|
|
|
break; |
|
|
|
|
|
|
|
return (i < Nval) ? i : (-1); |
|
|
|
@@ -603,7 +602,7 @@ int TYPBLK<TYPE>::GetMaxLength(void)
|
|
|
|
@@ -605,7 +604,7 @@ int TYPBLK<TYPE>::GetMaxLength(void)
|
|
|
|
int i, n, m; |
|
|
|
|
|
|
|
for (i = n = 0; i < Nval; i++) { |
|
|
@ -242,7 +148,7 @@ This patch header follows DEP-3: http://dep.debian.net/deps/dep3/ |
|
|
|
n = MY_MAX(n, m); |
|
|
|
} // endfor i |
|
|
|
|
|
|
|
@@ -1333,7 +1332,7 @@ char *DATBLK::GetCharString(char *p, int
|
|
|
|
@@ -1335,7 +1334,7 @@ char *DATBLK::GetCharString(char *p, int
|
|
|
|
char *vp; |
|
|
|
|
|
|
|
if (Dvalp) { |
|
|
@ -251,7 +157,7 @@ This patch header follows DEP-3: http://dep.debian.net/deps/dep3/ |
|
|
|
vp = Dvalp->GetCharString(p); |
|
|
|
} else |
|
|
|
vp = TYPBLK<int>::GetCharString(p, n); |
|
|
|
@@ -1349,7 +1348,7 @@ void DATBLK::SetValue(PCSZ p, int n)
|
|
|
|
@@ -1351,7 +1350,7 @@ void DATBLK::SetValue(PCSZ p, int n)
|
|
|
|
if (Dvalp) { |
|
|
|
// Decode the string according to format |
|
|
|
Dvalp->SetValue_psz(p); |
|
|
@ -260,3 +166,92 @@ This patch header follows DEP-3: http://dep.debian.net/deps/dep3/ |
|
|
|
} else |
|
|
|
TYPBLK<int>::SetValue(p, n); |
|
|
|
|
|
|
|
--- a/storage/connect/valblk.h
|
|
|
|
+++ b/storage/connect/valblk.h
|
|
|
|
@@ -139,6 +139,7 @@ class VALBLK : public BLOCK {
|
|
|
|
int Prec; // Precision of float values |
|
|
|
}; // end of class VALBLK |
|
|
|
|
|
|
|
+
|
|
|
|
/***********************************************************************/ |
|
|
|
/* Class TYPBLK: represents a block of typed values. */ |
|
|
|
/***********************************************************************/ |
|
|
|
@@ -151,40 +152,41 @@ class TYPBLK : public VALBLK {
|
|
|
|
// Implementation |
|
|
|
virtual bool Init(PGLOBAL g, bool check); |
|
|
|
virtual int GetVlen(void) {return sizeof(TYPE);} |
|
|
|
- virtual char GetTinyValue(int n) {return (char)Typp[n];}
|
|
|
|
- virtual uchar GetUTinyValue(int n) {return (uchar)Typp[n];}
|
|
|
|
- virtual short GetShortValue(int n) {return (short)Typp[n];}
|
|
|
|
- virtual ushort GetUShortValue(int n) {return (ushort)Typp[n];}
|
|
|
|
- virtual int GetIntValue(int n) {return (int)Typp[n];}
|
|
|
|
- virtual uint GetUIntValue(int n) {return (uint)Typp[n];}
|
|
|
|
- virtual longlong GetBigintValue(int n) {return (longlong)Typp[n];}
|
|
|
|
- virtual ulonglong GetUBigintValue(int n) {return (ulonglong)Typp[n];}
|
|
|
|
- virtual double GetFloatValue(int n) {return (double)Typp[n];}
|
|
|
|
+
|
|
|
|
+ virtual char GetTinyValue(int n) {return (char)UnalignedRead(n);}
|
|
|
|
+ virtual uchar GetUTinyValue(int n) {return (uchar)UnalignedRead(n);}
|
|
|
|
+ virtual short GetShortValue(int n) {return (short)UnalignedRead(n);}
|
|
|
|
+ virtual ushort GetUShortValue(int n) {return (ushort)UnalignedRead(n);}
|
|
|
|
+ virtual int GetIntValue(int n) {return (int)UnalignedRead(n);}
|
|
|
|
+ virtual uint GetUIntValue(int n) {return (uint)UnalignedRead(n);}
|
|
|
|
+ virtual longlong GetBigintValue(int n) {return (longlong)UnalignedRead(n);}
|
|
|
|
+ virtual ulonglong GetUBigintValue(int n) {return (ulonglong)UnalignedRead(n);}
|
|
|
|
+ virtual double GetFloatValue(int n) {return (double)UnalignedRead(n);}
|
|
|
|
virtual char *GetCharString(char *p, int n); |
|
|
|
- virtual void Reset(int n) {Typp[n] = 0;}
|
|
|
|
+ virtual void Reset(int n) {UnalignedWrite(n, 0);}
|
|
|
|
|
|
|
|
// Methods |
|
|
|
using VALBLK::SetValue; |
|
|
|
virtual void SetValue(PCSZ sp, int n); |
|
|
|
virtual void SetValue(const char *sp, uint len, int n); |
|
|
|
virtual void SetValue(short sval, int n) |
|
|
|
- {Typp[n] = (TYPE)sval; SetNull(n, false);}
|
|
|
|
+ {UnalignedWrite(n, (TYPE)sval); SetNull(n, false);}
|
|
|
|
virtual void SetValue(ushort sval, int n) |
|
|
|
- {Typp[n] = (TYPE)sval; SetNull(n, false);}
|
|
|
|
+ {UnalignedWrite(n, (TYPE)sval); SetNull(n, false);}
|
|
|
|
virtual void SetValue(int lval, int n) |
|
|
|
- {Typp[n] = (TYPE)lval; SetNull(n, false);}
|
|
|
|
+ {UnalignedWrite(n, (TYPE)lval); SetNull(n, false);}
|
|
|
|
virtual void SetValue(uint lval, int n) |
|
|
|
- {Typp[n] = (TYPE)lval; SetNull(n, false);}
|
|
|
|
+ {UnalignedWrite(n, (TYPE)lval); SetNull(n, false);}
|
|
|
|
virtual void SetValue(longlong lval, int n) |
|
|
|
- {Typp[n] = (TYPE)lval; SetNull(n, false);}
|
|
|
|
+ {UnalignedWrite(n, (TYPE)lval); SetNull(n, false);}
|
|
|
|
virtual void SetValue(ulonglong lval, int n) |
|
|
|
- {Typp[n] = (TYPE)lval; SetNull(n, false);}
|
|
|
|
+ {UnalignedWrite(n, (TYPE)lval); SetNull(n, false);}
|
|
|
|
virtual void SetValue(double fval, int n) |
|
|
|
- {Typp[n] = (TYPE)fval; SetNull(n, false);}
|
|
|
|
+ {UnalignedWrite(n, (TYPE)fval); SetNull(n, false);}
|
|
|
|
virtual void SetValue(char cval, int n) |
|
|
|
- {Typp[n] = (TYPE)cval; SetNull(n, false);}
|
|
|
|
+ {UnalignedWrite(n, (TYPE)cval); SetNull(n, false);}
|
|
|
|
virtual void SetValue(uchar cval, int n) |
|
|
|
- {Typp[n] = (TYPE)cval; SetNull(n, false);}
|
|
|
|
+ {UnalignedWrite(n, (TYPE)cval); SetNull(n, false);}
|
|
|
|
virtual void SetValue(PVAL valp, int n); |
|
|
|
virtual void SetValue(PVBLK pv, int n1, int n2); |
|
|
|
virtual void SetMin(PVAL valp, int n); |
|
|
|
@@ -206,6 +208,17 @@ class TYPBLK : public VALBLK {
|
|
|
|
// Members |
|
|
|
TYPE* const &Typp; |
|
|
|
const char *Fmt; |
|
|
|
+
|
|
|
|
+ // Unaligned access
|
|
|
|
+ TYPE UnalignedRead(int n) const {
|
|
|
|
+ TYPE result;
|
|
|
|
+ memcpy(&result, Typp + n, sizeof(TYPE));
|
|
|
|
+ return result;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ void UnalignedWrite(int n, TYPE value) {
|
|
|
|
+ memcpy(Typp + n, &value, sizeof(TYPE));
|
|
|
|
+ }
|
|
|
|
}; // end of class TYPBLK |
|
|
|
|
|
|
|
/***********************************************************************/ |