-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)
{
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()))
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)
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
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))
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);
} // 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);
} // 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;
} // 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)
{
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
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)
{
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++)
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++) {
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) {
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);
} 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
+
+ /***********************************************************************/