Skip to content

Commit d0abd53

Browse files
committed
mariadb: handle unaligned buffers in TYPBLK class
Signed-off-by: Mathieu Malaterre <malat@debian.org>
1 parent bcc6bc1 commit d0abd53

1 file changed

Lines changed: 251 additions & 0 deletions

File tree

Lines changed: 251 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,251 @@
1+
Description: Handle unaligned buffers in connect's TYPBLK class
2+
On MIPS platforms (and probably others) unaligned memory access results in a
3+
bus error. In the connect storage engine, block data for some data formats is
4+
stored packed in memory and the TYPBLK class is used to read values from it.
5+
Since TYPBLK does not have special handling for this packed memory, it can
6+
quite easily result in unaligned memory accesses.
7+
.
8+
The simple way to fix this is to perform all accesses to the main buffer
9+
through memcpy. With GCC and optimizations turned on, this call to memcpy is
10+
completely optimized away on architectures where unaligned accesses are ok
11+
(like x86).
12+
Author: James Cowgill <jcowgill@debian.org>
13+
---
14+
This patch header follows DEP-3: http://dep.debian.net/deps/dep3/
15+
--- a/storage/connect/valblk.h
16+
+++ b/storage/connect/valblk.h
17+
@@ -139,6 +139,7 @@ class VALBLK : public BLOCK {
18+
int Prec; // Precision of float values
19+
}; // end of class VALBLK
20+
21+
+
22+
/***********************************************************************/
23+
/* Class TYPBLK: represents a block of typed values. */
24+
/***********************************************************************/
25+
@@ -151,40 +152,40 @@ class TYPBLK : public VALBLK {
26+
// Implementation
27+
virtual bool Init(PGLOBAL g, bool check);
28+
virtual int GetVlen(void) {return sizeof(TYPE);}
29+
- virtual char GetTinyValue(int n) {return (char)Typp[n];}
30+
- virtual uchar GetUTinyValue(int n) {return (uchar)Typp[n];}
31+
- virtual short GetShortValue(int n) {return (short)Typp[n];}
32+
- virtual ushort GetUShortValue(int n) {return (ushort)Typp[n];}
33+
- virtual int GetIntValue(int n) {return (int)Typp[n];}
34+
- virtual uint GetUIntValue(int n) {return (uint)Typp[n];}
35+
- virtual longlong GetBigintValue(int n) {return (longlong)Typp[n];}
36+
- virtual ulonglong GetUBigintValue(int n) {return (ulonglong)Typp[n];}
37+
- virtual double GetFloatValue(int n) {return (double)Typp[n];}
38+
+ virtual char GetTinyValue(int n) {return (char)UnalignedRead(n);}
39+
+ virtual uchar GetUTinyValue(int n) {return (uchar)UnalignedRead(n);}
40+
+ virtual short GetShortValue(int n) {return (short)UnalignedRead(n);}
41+
+ virtual ushort GetUShortValue(int n) {return (ushort)UnalignedRead(n);}
42+
+ virtual int GetIntValue(int n) {return (int)UnalignedRead(n);}
43+
+ virtual uint GetUIntValue(int n) {return (uint)UnalignedRead(n);}
44+
+ virtual longlong GetBigintValue(int n) {return (longlong)UnalignedRead(n);}
45+
+ virtual ulonglong GetUBigintValue(int n) {return (ulonglong)UnalignedRead(n);}
46+
+ virtual double GetFloatValue(int n) {return (double)UnalignedRead(n);}
47+
virtual char *GetCharString(char *p, int n);
48+
- virtual void Reset(int n) {Typp[n] = 0;}
49+
+ virtual void Reset(int n) {UnalignedWrite(n, 0);}
50+
51+
// Methods
52+
using VALBLK::SetValue;
53+
virtual void SetValue(PSZ sp, int n);
54+
virtual void SetValue(char *sp, uint len, int n);
55+
virtual void SetValue(short sval, int n)
56+
- {Typp[n] = (TYPE)sval; SetNull(n, false);}
57+
+ {UnalignedWrite(n, (TYPE)sval); SetNull(n, false);}
58+
virtual void SetValue(ushort sval, int n)
59+
- {Typp[n] = (TYPE)sval; SetNull(n, false);}
60+
+ {UnalignedWrite(n, (TYPE)sval); SetNull(n, false);}
61+
virtual void SetValue(int lval, int n)
62+
- {Typp[n] = (TYPE)lval; SetNull(n, false);}
63+
+ {UnalignedWrite(n, (TYPE)lval); SetNull(n, false);}
64+
virtual void SetValue(uint lval, int n)
65+
- {Typp[n] = (TYPE)lval; SetNull(n, false);}
66+
+ {UnalignedWrite(n, (TYPE)lval); SetNull(n, false);}
67+
virtual void SetValue(longlong lval, int n)
68+
- {Typp[n] = (TYPE)lval; SetNull(n, false);}
69+
+ {UnalignedWrite(n, (TYPE)lval); SetNull(n, false);}
70+
virtual void SetValue(ulonglong lval, int n)
71+
- {Typp[n] = (TYPE)lval; SetNull(n, false);}
72+
+ {UnalignedWrite(n, (TYPE)lval); SetNull(n, false);}
73+
virtual void SetValue(double fval, int n)
74+
- {Typp[n] = (TYPE)fval; SetNull(n, false);}
75+
+ {UnalignedWrite(n, (TYPE)fval); SetNull(n, false);}
76+
virtual void SetValue(char cval, int n)
77+
- {Typp[n] = (TYPE)cval; SetNull(n, false);}
78+
+ {UnalignedWrite(n, (TYPE)cval); SetNull(n, false);}
79+
virtual void SetValue(uchar cval, int n)
80+
- {Typp[n] = (TYPE)cval; SetNull(n, false);}
81+
+ {UnalignedWrite(n, (TYPE)cval); SetNull(n, false);}
82+
virtual void SetValue(PVAL valp, int n);
83+
virtual void SetValue(PVBLK pv, int n1, int n2);
84+
virtual void SetMin(PVAL valp, int n);
85+
@@ -206,6 +207,17 @@ class TYPBLK : public VALBLK {
86+
// Members
87+
TYPE* const &Typp;
88+
const char *Fmt;
89+
+
90+
+ // Unaligned access
91+
+ TYPE UnalignedRead(int n) const {
92+
+ TYPE result;
93+
+ memcpy(&result, Typp + n, sizeof(TYPE));
94+
+ return result;
95+
+ }
96+
+
97+
+ void UnalignedWrite(int n, TYPE value) {
98+
+ memcpy(Typp + n, &value, sizeof(TYPE));
99+
+ }
100+
}; // end of class TYPBLK
101+
102+
/***********************************************************************/
103+
--- a/storage/connect/valblk.cpp
104+
+++ b/storage/connect/valblk.cpp
105+
@@ -265,14 +265,14 @@ bool TYPBLK<TYPE>::Init(PGLOBAL g, bool
106+
template <class TYPE>
107+
char *TYPBLK<TYPE>::GetCharString(char *p, int n)
108+
{
109+
- sprintf(p, Fmt, Typp[n]);
110+
+ sprintf(p, Fmt, UnalignedRead(n));
111+
return p;
112+
} // end of GetCharString
113+
114+
template <>
115+
char *TYPBLK<double>::GetCharString(char *p, int n)
116+
{
117+
- sprintf(p, Fmt, Prec, Typp[n]);
118+
+ sprintf(p, Fmt, Prec, UnalignedRead(n));
119+
return p;
120+
} // end of GetCharString
121+
122+
@@ -288,7 +288,7 @@ void TYPBLK<TYPE>::SetValue(PVAL valp, i
123+
ChkTyp(valp);
124+
125+
if (!(b = valp->IsNull()))
126+
- Typp[n] = GetTypedValue(valp);
127+
+ UnalignedWrite(n, GetTypedValue(valp));
128+
else
129+
Reset(n);
130+
131+
@@ -350,9 +350,9 @@ void TYPBLK<TYPE>::SetValue(PSZ p, int n
132+
ulonglong val = CharToNumber(p, strlen(p), maxval, Unsigned, &minus);
133+
134+
if (minus && val < maxval)
135+
- Typp[n] = (TYPE)(-(signed)val);
136+
+ UnalignedWrite(n, (TYPE)(-(signed)val));
137+
else
138+
- Typp[n] = (TYPE)val;
139+
+ UnalignedWrite(n, (TYPE)val);
140+
141+
SetNull(n, false);
142+
} // end of SetValue
143+
@@ -395,7 +395,7 @@ void TYPBLK<double>::SetValue(PSZ p, int
144+
longjmp(g->jumper[g->jump_level], Type);
145+
} // endif Check
146+
147+
- Typp[n] = atof(p);
148+
+ UnalignedWrite(n, atof(p));
149+
SetNull(n, false);
150+
} // end of SetValue
151+
152+
@@ -427,7 +427,7 @@ void TYPBLK<TYPE>::SetValue(PVBLK pv, in
153+
ChkTyp(pv);
154+
155+
if (!(b = pv->IsNull(n2) && Nullable))
156+
- Typp[n1] = GetTypedValue(pv, n2);
157+
+ UnalignedWrite(n1, GetTypedValue(pv, n2));
158+
else
159+
Reset(n1);
160+
161+
@@ -478,10 +478,10 @@ void TYPBLK<TYPE>::SetMin(PVAL valp, int
162+
{
163+
CheckParms(valp, n)
164+
TYPE tval = GetTypedValue(valp);
165+
- TYPE& tmin = Typp[n];
166+
+ TYPE tmin = UnalignedRead(n);
167+
168+
if (tval < tmin)
169+
- tmin = tval;
170+
+ UnalignedWrite(n, tval);
171+
172+
} // end of SetMin
173+
174+
@@ -493,10 +493,10 @@ void TYPBLK<TYPE>::SetMax(PVAL valp, int
175+
{
176+
CheckParms(valp, n)
177+
TYPE tval = GetTypedValue(valp);
178+
- TYPE& tmin = Typp[n];
179+
+ TYPE tmin = UnalignedRead(n);
180+
181+
if (tval > tmin)
182+
- tmin = tval;
183+
+ UnalignedWrite(n, tval);
184+
185+
} // end of SetMax
186+
187+
@@ -522,7 +522,7 @@ void TYPBLK<TYPE>::SetValues(PVBLK pv, i
188+
template <class TYPE>
189+
void TYPBLK<TYPE>::Move(int i, int j)
190+
{
191+
- Typp[j] = Typp[i];
192+
+ UnalignedWrite(j, UnalignedRead(i));
193+
MoveNull(i, j);
194+
} // end of Move
195+
196+
@@ -536,7 +536,7 @@ int TYPBLK<TYPE>::CompVal(PVAL vp, int n
197+
ChkIndx(n);
198+
ChkTyp(vp);
199+
#endif // _DEBUG
200+
- TYPE mlv = Typp[n];
201+
+ TYPE mlv = UnalignedRead(n);
202+
TYPE vlv = GetTypedValue(vp);
203+
204+
return (vlv > mlv) ? 1 : (vlv < mlv) ? (-1) : 0;
205+
@@ -548,8 +548,8 @@ int TYPBLK<TYPE>::CompVal(PVAL vp, int n
206+
template <class TYPE>
207+
int TYPBLK<TYPE>::CompVal(int i1, int i2)
208+
{
209+
- TYPE lv1 = Typp[i1];
210+
- TYPE lv2 = Typp[i2];
211+
+ TYPE lv1 = UnalignedRead(i1);
212+
+ TYPE lv2 = UnalignedRead(i2);
213+
214+
return (lv1 > lv2) ? 1 : (lv1 < lv2) ? (-1) : 0;
215+
} // end of CompVal
216+
@@ -586,7 +586,7 @@ int TYPBLK<TYPE>::Find(PVAL vp)
217+
TYPE n = GetTypedValue(vp);
218+
219+
for (i = 0; i < Nval; i++)
220+
- if (n == Typp[i])
221+
+ if (n == UnalignedRead(i))
222+
break;
223+
224+
return (i < Nval) ? i : (-1);
225+
@@ -602,7 +602,7 @@ int TYPBLK<TYPE>::GetMaxLength(void)
226+
int i, n, m;
227+
228+
for (i = n = 0; i < Nval; i++) {
229+
- m = sprintf(buf, Fmt, Typp[i]);
230+
+ m = sprintf(buf, Fmt, UnalignedRead(i));
231+
n = MY_MAX(n, m);
232+
} // endfor i
233+
234+
@@ -1332,7 +1332,7 @@ char *DATBLK::GetCharString(char *p, int
235+
char *vp;
236+
237+
if (Dvalp) {
238+
- Dvalp->SetValue(Typp[n]);
239+
+ Dvalp->SetValue(UnalignedRead(n));
240+
vp = Dvalp->GetCharString(p);
241+
} else
242+
vp = TYPBLK<int>::GetCharString(p, n);
243+
@@ -1348,7 +1348,7 @@ void DATBLK::SetValue(PSZ p, int n)
244+
if (Dvalp) {
245+
// Decode the string according to format
246+
Dvalp->SetValue_psz(p);
247+
- Typp[n] = Dvalp->GetIntValue();
248+
+ UnalignedWrite(n, Dvalp->GetIntValue());
249+
} else
250+
TYPBLK<int>::SetValue(p, n);
251+

0 commit comments

Comments
 (0)