Fix MIPS build failure: 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). Contributors: James Cowgill <jcowgill@debian.org>
This commit is contained in:
parent
f502ccbcb5
commit
a33c1082da
@ -268,14 +268,14 @@ bool TYPBLK<TYPE>::Init(PGLOBAL g, bool check)
|
|||||||
template <class TYPE>
|
template <class TYPE>
|
||||||
char *TYPBLK<TYPE>::GetCharString(char *p, int n)
|
char *TYPBLK<TYPE>::GetCharString(char *p, int n)
|
||||||
{
|
{
|
||||||
sprintf(p, Fmt, Typp[n]);
|
sprintf(p, Fmt, UnalignedRead(n));
|
||||||
return p;
|
return p;
|
||||||
} // end of GetCharString
|
} // end of GetCharString
|
||||||
|
|
||||||
template <>
|
template <>
|
||||||
char *TYPBLK<double>::GetCharString(char *p, int n)
|
char *TYPBLK<double>::GetCharString(char *p, int n)
|
||||||
{
|
{
|
||||||
sprintf(p, Fmt, Prec, Typp[n]);
|
sprintf(p, Fmt, Prec, UnalignedRead(n));
|
||||||
return p;
|
return p;
|
||||||
} // end of GetCharString
|
} // end of GetCharString
|
||||||
|
|
||||||
@ -291,7 +291,7 @@ void TYPBLK<TYPE>::SetValue(PVAL valp, int n)
|
|||||||
ChkTyp(valp);
|
ChkTyp(valp);
|
||||||
|
|
||||||
if (!(b = valp->IsNull()))
|
if (!(b = valp->IsNull()))
|
||||||
Typp[n] = GetTypedValue(valp);
|
UnalignedWrite(n, GetTypedValue(valp));
|
||||||
else
|
else
|
||||||
Reset(n);
|
Reset(n);
|
||||||
|
|
||||||
@ -353,9 +353,9 @@ void TYPBLK<TYPE>::SetValue(PCSZ p, int n)
|
|||||||
ulonglong val = CharToNumber(p, strlen(p), maxval, Unsigned, &minus);
|
ulonglong val = CharToNumber(p, strlen(p), maxval, Unsigned, &minus);
|
||||||
|
|
||||||
if (minus && val < maxval)
|
if (minus && val < maxval)
|
||||||
Typp[n] = (TYPE)(-(signed)val);
|
UnalignedWrite(n, (TYPE)(-(signed)val));
|
||||||
else
|
else
|
||||||
Typp[n] = (TYPE)val;
|
UnalignedWrite(n, (TYPE)val);
|
||||||
|
|
||||||
SetNull(n, false);
|
SetNull(n, false);
|
||||||
} // end of SetValue
|
} // end of SetValue
|
||||||
@ -398,7 +398,7 @@ void TYPBLK<double>::SetValue(PCSZ p, int n)
|
|||||||
throw Type;
|
throw Type;
|
||||||
} // endif Check
|
} // endif Check
|
||||||
|
|
||||||
Typp[n] = atof(p);
|
UnalignedWrite(n, atof(p));
|
||||||
SetNull(n, false);
|
SetNull(n, false);
|
||||||
} // end of SetValue
|
} // end of SetValue
|
||||||
|
|
||||||
@ -430,7 +430,7 @@ void TYPBLK<TYPE>::SetValue(PVBLK pv, int n1, int n2)
|
|||||||
ChkTyp(pv);
|
ChkTyp(pv);
|
||||||
|
|
||||||
if (!(b = pv->IsNull(n2) && Nullable))
|
if (!(b = pv->IsNull(n2) && Nullable))
|
||||||
Typp[n1] = GetTypedValue(pv, n2);
|
UnalignedWrite(n1, GetTypedValue(pv, n2));
|
||||||
else
|
else
|
||||||
Reset(n1);
|
Reset(n1);
|
||||||
|
|
||||||
@ -481,10 +481,10 @@ void TYPBLK<TYPE>::SetMin(PVAL valp, int n)
|
|||||||
{
|
{
|
||||||
CheckParms(valp, n)
|
CheckParms(valp, n)
|
||||||
TYPE tval = GetTypedValue(valp);
|
TYPE tval = GetTypedValue(valp);
|
||||||
TYPE& tmin = Typp[n];
|
TYPE tmin = UnalignedRead(n);
|
||||||
|
|
||||||
if (tval < tmin)
|
if (tval < tmin)
|
||||||
tmin = tval;
|
UnalignedWrite(n, tval);
|
||||||
|
|
||||||
} // end of SetMin
|
} // end of SetMin
|
||||||
|
|
||||||
@ -496,10 +496,10 @@ void TYPBLK<TYPE>::SetMax(PVAL valp, int n)
|
|||||||
{
|
{
|
||||||
CheckParms(valp, n)
|
CheckParms(valp, n)
|
||||||
TYPE tval = GetTypedValue(valp);
|
TYPE tval = GetTypedValue(valp);
|
||||||
TYPE& tmin = Typp[n];
|
TYPE tmin = UnalignedRead(n);
|
||||||
|
|
||||||
if (tval > tmin)
|
if (tval > tmin)
|
||||||
tmin = tval;
|
UnalignedWrite(n, tval);
|
||||||
|
|
||||||
} // end of SetMax
|
} // end of SetMax
|
||||||
|
|
||||||
@ -513,8 +513,7 @@ void TYPBLK<TYPE>::SetValues(PVBLK pv, int k, int n)
|
|||||||
CheckType(pv)
|
CheckType(pv)
|
||||||
TYPE *lp = ((TYPBLK*)pv)->Typp;
|
TYPE *lp = ((TYPBLK*)pv)->Typp;
|
||||||
|
|
||||||
for (int i = k; i < n; i++) // TODO
|
memcpy(Typp + k, lp + k, sizeof(TYPE) * n);
|
||||||
Typp[i] = lp[i];
|
|
||||||
|
|
||||||
} // end of SetValues
|
} // end of SetValues
|
||||||
#endif // 0
|
#endif // 0
|
||||||
@ -525,7 +524,7 @@ void TYPBLK<TYPE>::SetValues(PVBLK pv, int k, int n)
|
|||||||
template <class TYPE>
|
template <class TYPE>
|
||||||
void TYPBLK<TYPE>::Move(int i, int j)
|
void TYPBLK<TYPE>::Move(int i, int j)
|
||||||
{
|
{
|
||||||
Typp[j] = Typp[i];
|
UnalignedWrite(j, UnalignedRead(i));
|
||||||
MoveNull(i, j);
|
MoveNull(i, j);
|
||||||
} // end of Move
|
} // end of Move
|
||||||
|
|
||||||
@ -539,7 +538,7 @@ int TYPBLK<TYPE>::CompVal(PVAL vp, int n)
|
|||||||
ChkIndx(n);
|
ChkIndx(n);
|
||||||
ChkTyp(vp);
|
ChkTyp(vp);
|
||||||
#endif // _DEBUG
|
#endif // _DEBUG
|
||||||
TYPE mlv = Typp[n];
|
TYPE mlv = UnalignedRead(n);
|
||||||
TYPE vlv = GetTypedValue(vp);
|
TYPE vlv = GetTypedValue(vp);
|
||||||
|
|
||||||
return (vlv > mlv) ? 1 : (vlv < mlv) ? (-1) : 0;
|
return (vlv > mlv) ? 1 : (vlv < mlv) ? (-1) : 0;
|
||||||
@ -551,8 +550,8 @@ int TYPBLK<TYPE>::CompVal(PVAL vp, int n)
|
|||||||
template <class TYPE>
|
template <class TYPE>
|
||||||
int TYPBLK<TYPE>::CompVal(int i1, int i2)
|
int TYPBLK<TYPE>::CompVal(int i1, int i2)
|
||||||
{
|
{
|
||||||
TYPE lv1 = Typp[i1];
|
TYPE lv1 = UnalignedRead(i1);
|
||||||
TYPE lv2 = Typp[i2];
|
TYPE lv2 = UnalignedRead(i2);
|
||||||
|
|
||||||
return (lv1 > lv2) ? 1 : (lv1 < lv2) ? (-1) : 0;
|
return (lv1 > lv2) ? 1 : (lv1 < lv2) ? (-1) : 0;
|
||||||
} // end of CompVal
|
} // end of CompVal
|
||||||
@ -589,7 +588,7 @@ int TYPBLK<TYPE>::Find(PVAL vp)
|
|||||||
TYPE n = GetTypedValue(vp);
|
TYPE n = GetTypedValue(vp);
|
||||||
|
|
||||||
for (i = 0; i < Nval; i++)
|
for (i = 0; i < Nval; i++)
|
||||||
if (n == Typp[i])
|
if (n == UnalignedRead(i))
|
||||||
break;
|
break;
|
||||||
|
|
||||||
return (i < Nval) ? i : (-1);
|
return (i < Nval) ? i : (-1);
|
||||||
@ -605,7 +604,7 @@ int TYPBLK<TYPE>::GetMaxLength(void)
|
|||||||
int i, n, m;
|
int i, n, m;
|
||||||
|
|
||||||
for (i = n = 0; i < Nval; i++) {
|
for (i = n = 0; i < Nval; i++) {
|
||||||
m = sprintf(buf, Fmt, Typp[i]);
|
m = sprintf(buf, Fmt, UnalignedRead(i));
|
||||||
n = MY_MAX(n, m);
|
n = MY_MAX(n, m);
|
||||||
} // endfor i
|
} // endfor i
|
||||||
|
|
||||||
@ -1335,7 +1334,7 @@ char *DATBLK::GetCharString(char *p, int n)
|
|||||||
char *vp;
|
char *vp;
|
||||||
|
|
||||||
if (Dvalp) {
|
if (Dvalp) {
|
||||||
Dvalp->SetValue(Typp[n]);
|
Dvalp->SetValue(UnalignedRead(n));
|
||||||
vp = Dvalp->GetCharString(p);
|
vp = Dvalp->GetCharString(p);
|
||||||
} else
|
} else
|
||||||
vp = TYPBLK<int>::GetCharString(p, n);
|
vp = TYPBLK<int>::GetCharString(p, n);
|
||||||
@ -1351,7 +1350,7 @@ void DATBLK::SetValue(PCSZ p, int n)
|
|||||||
if (Dvalp) {
|
if (Dvalp) {
|
||||||
// Decode the string according to format
|
// Decode the string according to format
|
||||||
Dvalp->SetValue_psz(p);
|
Dvalp->SetValue_psz(p);
|
||||||
Typp[n] = Dvalp->GetIntValue();
|
UnalignedWrite(n, Dvalp->GetIntValue());
|
||||||
} else
|
} else
|
||||||
TYPBLK<int>::SetValue(p, n);
|
TYPBLK<int>::SetValue(p, n);
|
||||||
|
|
||||||
|
@ -151,40 +151,41 @@ class TYPBLK : public VALBLK {
|
|||||||
// Implementation
|
// Implementation
|
||||||
virtual bool Init(PGLOBAL g, bool check);
|
virtual bool Init(PGLOBAL g, bool check);
|
||||||
virtual int GetVlen(void) {return sizeof(TYPE);}
|
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 char GetTinyValue(int n) {return (char)UnalignedRead(n);}
|
||||||
virtual short GetShortValue(int n) {return (short)Typp[n];}
|
virtual uchar GetUTinyValue(int n) {return (uchar)UnalignedRead(n);}
|
||||||
virtual ushort GetUShortValue(int n) {return (ushort)Typp[n];}
|
virtual short GetShortValue(int n) {return (short)UnalignedRead(n);}
|
||||||
virtual int GetIntValue(int n) {return (int)Typp[n];}
|
virtual ushort GetUShortValue(int n) {return (ushort)UnalignedRead(n);}
|
||||||
virtual uint GetUIntValue(int n) {return (uint)Typp[n];}
|
virtual int GetIntValue(int n) {return (int)UnalignedRead(n);}
|
||||||
virtual longlong GetBigintValue(int n) {return (longlong)Typp[n];}
|
virtual uint GetUIntValue(int n) {return (uint)UnalignedRead(n);}
|
||||||
virtual ulonglong GetUBigintValue(int n) {return (ulonglong)Typp[n];}
|
virtual longlong GetBigintValue(int n) {return (longlong)UnalignedRead(n);}
|
||||||
virtual double GetFloatValue(int n) {return (double)Typp[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 char *GetCharString(char *p, int n);
|
||||||
virtual void Reset(int n) {Typp[n] = 0;}
|
virtual void Reset(int n) {UnalignedWrite(n, 0);}
|
||||||
|
|
||||||
// Methods
|
// Methods
|
||||||
using VALBLK::SetValue;
|
using VALBLK::SetValue;
|
||||||
virtual void SetValue(PCSZ sp, int n);
|
virtual void SetValue(PCSZ sp, int n);
|
||||||
virtual void SetValue(const char *sp, uint len, int n);
|
virtual void SetValue(const char *sp, uint len, int n);
|
||||||
virtual void SetValue(short sval, 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)
|
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)
|
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)
|
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)
|
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)
|
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)
|
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)
|
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)
|
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(PVAL valp, int n);
|
||||||
virtual void SetValue(PVBLK pv, int n1, int n2);
|
virtual void SetValue(PVBLK pv, int n1, int n2);
|
||||||
virtual void SetMin(PVAL valp, int n);
|
virtual void SetMin(PVAL valp, int n);
|
||||||
@ -206,6 +207,17 @@ class TYPBLK : public VALBLK {
|
|||||||
// Members
|
// Members
|
||||||
TYPE* const &Typp;
|
TYPE* const &Typp;
|
||||||
const char *Fmt;
|
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
|
}; // end of class TYPBLK
|
||||||
|
|
||||||
/***********************************************************************/
|
/***********************************************************************/
|
||||||
|
Loading…
x
Reference in New Issue
Block a user