mirror of
https://github.com/MariaDB/server.git
synced 2025-08-08 11:22:35 +03:00
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:
@@ -268,14 +268,14 @@ bool TYPBLK<TYPE>::Init(PGLOBAL g, bool check)
|
||||
template <class TYPE>
|
||||
char *TYPBLK<TYPE>::GetCharString(char *p, int n)
|
||||
{
|
||||
sprintf(p, Fmt, Typp[n]);
|
||||
sprintf(p, Fmt, UnalignedRead(n));
|
||||
return p;
|
||||
} // end of GetCharString
|
||||
|
||||
template <>
|
||||
char *TYPBLK<double>::GetCharString(char *p, int n)
|
||||
{
|
||||
sprintf(p, Fmt, Prec, Typp[n]);
|
||||
sprintf(p, Fmt, Prec, UnalignedRead(n));
|
||||
return p;
|
||||
} // end of GetCharString
|
||||
|
||||
@@ -291,7 +291,7 @@ void TYPBLK<TYPE>::SetValue(PVAL valp, int n)
|
||||
ChkTyp(valp);
|
||||
|
||||
if (!(b = valp->IsNull()))
|
||||
Typp[n] = GetTypedValue(valp);
|
||||
UnalignedWrite(n, GetTypedValue(valp));
|
||||
else
|
||||
Reset(n);
|
||||
|
||||
@@ -353,9 +353,9 @@ void TYPBLK<TYPE>::SetValue(PCSZ p, int n)
|
||||
ulonglong val = CharToNumber(p, strlen(p), maxval, Unsigned, &minus);
|
||||
|
||||
if (minus && val < maxval)
|
||||
Typp[n] = (TYPE)(-(signed)val);
|
||||
UnalignedWrite(n, (TYPE)(-(signed)val));
|
||||
else
|
||||
Typp[n] = (TYPE)val;
|
||||
UnalignedWrite(n, (TYPE)val);
|
||||
|
||||
SetNull(n, false);
|
||||
} // end of SetValue
|
||||
@@ -398,7 +398,7 @@ void TYPBLK<double>::SetValue(PCSZ p, int n)
|
||||
throw Type;
|
||||
} // endif Check
|
||||
|
||||
Typp[n] = atof(p);
|
||||
UnalignedWrite(n, atof(p));
|
||||
SetNull(n, false);
|
||||
} // end of SetValue
|
||||
|
||||
@@ -430,7 +430,7 @@ void TYPBLK<TYPE>::SetValue(PVBLK pv, int n1, int n2)
|
||||
ChkTyp(pv);
|
||||
|
||||
if (!(b = pv->IsNull(n2) && Nullable))
|
||||
Typp[n1] = GetTypedValue(pv, n2);
|
||||
UnalignedWrite(n1, GetTypedValue(pv, n2));
|
||||
else
|
||||
Reset(n1);
|
||||
|
||||
@@ -481,10 +481,10 @@ void TYPBLK<TYPE>::SetMin(PVAL valp, int n)
|
||||
{
|
||||
CheckParms(valp, n)
|
||||
TYPE tval = GetTypedValue(valp);
|
||||
TYPE& tmin = Typp[n];
|
||||
TYPE tmin = UnalignedRead(n);
|
||||
|
||||
if (tval < tmin)
|
||||
tmin = tval;
|
||||
UnalignedWrite(n, tval);
|
||||
|
||||
} // end of SetMin
|
||||
|
||||
@@ -496,10 +496,10 @@ void TYPBLK<TYPE>::SetMax(PVAL valp, int n)
|
||||
{
|
||||
CheckParms(valp, n)
|
||||
TYPE tval = GetTypedValue(valp);
|
||||
TYPE& tmin = Typp[n];
|
||||
TYPE tmin = UnalignedRead(n);
|
||||
|
||||
if (tval > tmin)
|
||||
tmin = tval;
|
||||
UnalignedWrite(n, tval);
|
||||
|
||||
} // end of SetMax
|
||||
|
||||
@@ -513,8 +513,7 @@ void TYPBLK<TYPE>::SetValues(PVBLK pv, int k, int n)
|
||||
CheckType(pv)
|
||||
TYPE *lp = ((TYPBLK*)pv)->Typp;
|
||||
|
||||
for (int i = k; i < n; i++) // TODO
|
||||
Typp[i] = lp[i];
|
||||
memcpy(Typp + k, lp + k, sizeof(TYPE) * n);
|
||||
|
||||
} // end of SetValues
|
||||
#endif // 0
|
||||
@@ -525,7 +524,7 @@ void TYPBLK<TYPE>::SetValues(PVBLK pv, int k, int n)
|
||||
template <class TYPE>
|
||||
void TYPBLK<TYPE>::Move(int i, int j)
|
||||
{
|
||||
Typp[j] = Typp[i];
|
||||
UnalignedWrite(j, UnalignedRead(i));
|
||||
MoveNull(i, j);
|
||||
} // end of Move
|
||||
|
||||
@@ -539,7 +538,7 @@ int TYPBLK<TYPE>::CompVal(PVAL vp, int n)
|
||||
ChkIndx(n);
|
||||
ChkTyp(vp);
|
||||
#endif // _DEBUG
|
||||
TYPE mlv = Typp[n];
|
||||
TYPE mlv = UnalignedRead(n);
|
||||
TYPE vlv = GetTypedValue(vp);
|
||||
|
||||
return (vlv > mlv) ? 1 : (vlv < mlv) ? (-1) : 0;
|
||||
@@ -551,8 +550,8 @@ int TYPBLK<TYPE>::CompVal(PVAL vp, int n)
|
||||
template <class TYPE>
|
||||
int TYPBLK<TYPE>::CompVal(int i1, int i2)
|
||||
{
|
||||
TYPE lv1 = Typp[i1];
|
||||
TYPE lv2 = Typp[i2];
|
||||
TYPE lv1 = UnalignedRead(i1);
|
||||
TYPE lv2 = UnalignedRead(i2);
|
||||
|
||||
return (lv1 > lv2) ? 1 : (lv1 < lv2) ? (-1) : 0;
|
||||
} // end of CompVal
|
||||
@@ -589,7 +588,7 @@ int TYPBLK<TYPE>::Find(PVAL vp)
|
||||
TYPE n = GetTypedValue(vp);
|
||||
|
||||
for (i = 0; i < Nval; i++)
|
||||
if (n == Typp[i])
|
||||
if (n == UnalignedRead(i))
|
||||
break;
|
||||
|
||||
return (i < Nval) ? i : (-1);
|
||||
@@ -605,7 +604,7 @@ int TYPBLK<TYPE>::GetMaxLength(void)
|
||||
int i, n, m;
|
||||
|
||||
for (i = n = 0; i < Nval; i++) {
|
||||
m = sprintf(buf, Fmt, Typp[i]);
|
||||
m = sprintf(buf, Fmt, UnalignedRead(i));
|
||||
n = MY_MAX(n, m);
|
||||
} // endfor i
|
||||
|
||||
@@ -1335,7 +1334,7 @@ char *DATBLK::GetCharString(char *p, int n)
|
||||
char *vp;
|
||||
|
||||
if (Dvalp) {
|
||||
Dvalp->SetValue(Typp[n]);
|
||||
Dvalp->SetValue(UnalignedRead(n));
|
||||
vp = Dvalp->GetCharString(p);
|
||||
} else
|
||||
vp = TYPBLK<int>::GetCharString(p, n);
|
||||
@@ -1351,7 +1350,7 @@ void DATBLK::SetValue(PCSZ p, int n)
|
||||
if (Dvalp) {
|
||||
// Decode the string according to format
|
||||
Dvalp->SetValue_psz(p);
|
||||
Typp[n] = Dvalp->GetIntValue();
|
||||
UnalignedWrite(n, Dvalp->GetIntValue());
|
||||
} else
|
||||
TYPBLK<int>::SetValue(p, n);
|
||||
|
||||
|
Reference in New Issue
Block a user