You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

262 lines
9.1 KiB

  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. /* Class TYPBLK: represents a block of typed values. */
  23. /***********************************************************************/
  24. @@ -151,40 +152,41 @@ class TYPBLK : public VALBLK {
  25. // Implementation
  26. virtual bool Init(PGLOBAL g, bool check);
  27. virtual int GetVlen(void) {return sizeof(TYPE);}
  28. - virtual char GetTinyValue(int n) {return (char)Typp[n];}
  29. - virtual uchar GetUTinyValue(int n) {return (uchar)Typp[n];}
  30. - virtual short GetShortValue(int n) {return (short)Typp[n];}
  31. - virtual ushort GetUShortValue(int n) {return (ushort)Typp[n];}
  32. - virtual int GetIntValue(int n) {return (int)Typp[n];}
  33. - virtual uint GetUIntValue(int n) {return (uint)Typp[n];}
  34. - virtual longlong GetBigintValue(int n) {return (longlong)Typp[n];}
  35. - virtual ulonglong GetUBigintValue(int n) {return (ulonglong)Typp[n];}
  36. - virtual double GetFloatValue(int n) {return (double)Typp[n];}
  37. +
  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. // Methods
  51. using VALBLK::SetValue;
  52. virtual void SetValue(PCSZ sp, int n);
  53. virtual void SetValue(const char *sp, uint len, int n);
  54. virtual void SetValue(short sval, int n)
  55. - {Typp[n] = (TYPE)sval; SetNull(n, false);}
  56. + {UnalignedWrite(n, (TYPE)sval); SetNull(n, false);}
  57. virtual void SetValue(ushort sval, int n)
  58. - {Typp[n] = (TYPE)sval; SetNull(n, false);}
  59. + {UnalignedWrite(n, (TYPE)sval); SetNull(n, false);}
  60. virtual void SetValue(int lval, int n)
  61. - {Typp[n] = (TYPE)lval; SetNull(n, false);}
  62. + {UnalignedWrite(n, (TYPE)lval); SetNull(n, false);}
  63. virtual void SetValue(uint lval, int n)
  64. - {Typp[n] = (TYPE)lval; SetNull(n, false);}
  65. + {UnalignedWrite(n, (TYPE)lval); SetNull(n, false);}
  66. virtual void SetValue(longlong lval, int n)
  67. - {Typp[n] = (TYPE)lval; SetNull(n, false);}
  68. + {UnalignedWrite(n, (TYPE)lval); SetNull(n, false);}
  69. virtual void SetValue(ulonglong lval, int n)
  70. - {Typp[n] = (TYPE)lval; SetNull(n, false);}
  71. + {UnalignedWrite(n, (TYPE)lval); SetNull(n, false);}
  72. virtual void SetValue(double fval, int n)
  73. - {Typp[n] = (TYPE)fval; SetNull(n, false);}
  74. + {UnalignedWrite(n, (TYPE)fval); SetNull(n, false);}
  75. virtual void SetValue(char cval, int n)
  76. - {Typp[n] = (TYPE)cval; SetNull(n, false);}
  77. + {UnalignedWrite(n, (TYPE)cval); SetNull(n, false);}
  78. virtual void SetValue(uchar cval, int n)
  79. - {Typp[n] = (TYPE)cval; SetNull(n, false);}
  80. + {UnalignedWrite(n, (TYPE)cval); SetNull(n, false);}
  81. virtual void SetValue(PVAL valp, int n);
  82. virtual void SetValue(PVBLK pv, int n1, int n2);
  83. virtual void SetMin(PVAL valp, int n);
  84. @@ -206,6 +208,17 @@ class TYPBLK : public VALBLK {
  85. // Members
  86. TYPE* const &Typp;
  87. const char *Fmt;
  88. +
  89. + // Unaligned access
  90. + TYPE UnalignedRead(int n) const {
  91. + TYPE result;
  92. + memcpy(&result, Typp + n, sizeof(TYPE));
  93. + return result;
  94. + }
  95. +
  96. + void UnalignedWrite(int n, TYPE value) {
  97. + memcpy(Typp + n, &value, sizeof(TYPE));
  98. + }
  99. }; // end of class TYPBLK
  100. /***********************************************************************/
  101. --- a/storage/connect/valblk.cpp
  102. +++ b/storage/connect/valblk.cpp
  103. @@ -266,14 +266,14 @@ bool TYPBLK<TYPE>::Init(PGLOBAL g, bool
  104. template <class TYPE>
  105. char *TYPBLK<TYPE>::GetCharString(char *p, int n)
  106. {
  107. - sprintf(p, Fmt, Typp[n]);
  108. + sprintf(p, Fmt, UnalignedRead(n));
  109. return p;
  110. } // end of GetCharString
  111. template <>
  112. char *TYPBLK<double>::GetCharString(char *p, int n)
  113. {
  114. - sprintf(p, Fmt, Prec, Typp[n]);
  115. + sprintf(p, Fmt, Prec, UnalignedRead(n));
  116. return p;
  117. } // end of GetCharString
  118. @@ -289,7 +289,7 @@ void TYPBLK<TYPE>::SetValue(PVAL valp, i
  119. ChkTyp(valp);
  120. if (!(b = valp->IsNull()))
  121. - Typp[n] = GetTypedValue(valp);
  122. + UnalignedWrite(n, GetTypedValue(valp));
  123. else
  124. Reset(n);
  125. @@ -351,9 +351,9 @@ void TYPBLK<TYPE>::SetValue(PCSZ p, int
  126. ulonglong val = CharToNumber(p, strlen(p), maxval, Unsigned, &minus);
  127. if (minus && val < maxval)
  128. - Typp[n] = (TYPE)(-(signed)val);
  129. + UnalignedWrite(n, (TYPE)(-(signed)val));
  130. else
  131. - Typp[n] = (TYPE)val;
  132. + UnalignedWrite(n, (TYPE)val);
  133. SetNull(n, false);
  134. } // end of SetValue
  135. @@ -396,7 +396,7 @@ void TYPBLK<double>::SetValue(PCSZ p, in
  136. throw Type;
  137. } // endif Check
  138. - Typp[n] = atof(p);
  139. + UnalignedWrite(n, atof(p));
  140. SetNull(n, false);
  141. } // end of SetValue
  142. @@ -428,7 +428,7 @@ void TYPBLK<TYPE>::SetValue(PVBLK pv, in
  143. ChkTyp(pv);
  144. if (!(b = pv->IsNull(n2) && Nullable))
  145. - Typp[n1] = GetTypedValue(pv, n2);
  146. + UnalignedWrite(n1, GetTypedValue(pv, n2));
  147. else
  148. Reset(n1);
  149. @@ -479,10 +479,10 @@ void TYPBLK<TYPE>::SetMin(PVAL valp, int
  150. {
  151. CheckParms(valp, n)
  152. TYPE tval = GetTypedValue(valp);
  153. - TYPE& tmin = Typp[n];
  154. + TYPE tmin = UnalignedRead(n);
  155. if (tval < tmin)
  156. - tmin = tval;
  157. + UnalignedWrite(n, tval);
  158. } // end of SetMin
  159. @@ -494,10 +494,10 @@ void TYPBLK<TYPE>::SetMax(PVAL valp, int
  160. {
  161. CheckParms(valp, n)
  162. TYPE tval = GetTypedValue(valp);
  163. - TYPE& tmin = Typp[n];
  164. + TYPE tmin = UnalignedRead(n);
  165. if (tval > tmin)
  166. - tmin = tval;
  167. + UnalignedWrite(n, tval);
  168. } // end of SetMax
  169. @@ -511,8 +511,7 @@ void TYPBLK<TYPE>::SetValues(PVBLK pv, i
  170. CheckType(pv)
  171. TYPE *lp = ((TYPBLK*)pv)->Typp;
  172. - for (int i = k; i < n; i++) // TODO
  173. - Typp[i] = lp[i];
  174. + memcpy(Typp + k, lp + k, sizeof(TYPE) * n);
  175. } // end of SetValues
  176. #endif // 0
  177. @@ -523,7 +522,7 @@ void TYPBLK<TYPE>::SetValues(PVBLK pv, i
  178. template <class TYPE>
  179. void TYPBLK<TYPE>::Move(int i, int j)
  180. {
  181. - Typp[j] = Typp[i];
  182. + UnalignedWrite(j, UnalignedRead(i));
  183. MoveNull(i, j);
  184. } // end of Move
  185. @@ -537,7 +536,7 @@ int TYPBLK<TYPE>::CompVal(PVAL vp, int n
  186. ChkIndx(n);
  187. ChkTyp(vp);
  188. #endif // _DEBUG
  189. - TYPE mlv = Typp[n];
  190. + TYPE mlv = UnalignedRead(n);
  191. TYPE vlv = GetTypedValue(vp);
  192. return (vlv > mlv) ? 1 : (vlv < mlv) ? (-1) : 0;
  193. @@ -549,8 +548,8 @@ int TYPBLK<TYPE>::CompVal(PVAL vp, int n
  194. template <class TYPE>
  195. int TYPBLK<TYPE>::CompVal(int i1, int i2)
  196. {
  197. - TYPE lv1 = Typp[i1];
  198. - TYPE lv2 = Typp[i2];
  199. + TYPE lv1 = UnalignedRead(i1);
  200. + TYPE lv2 = UnalignedRead(i2);
  201. return (lv1 > lv2) ? 1 : (lv1 < lv2) ? (-1) : 0;
  202. } // end of CompVal
  203. @@ -587,7 +586,7 @@ int TYPBLK<TYPE>::Find(PVAL vp)
  204. TYPE n = GetTypedValue(vp);
  205. for (i = 0; i < Nval; i++)
  206. - if (n == Typp[i])
  207. + if (n == UnalignedRead(i))
  208. break;
  209. return (i < Nval) ? i : (-1);
  210. @@ -603,7 +602,7 @@ int TYPBLK<TYPE>::GetMaxLength(void)
  211. int i, n, m;
  212. for (i = n = 0; i < Nval; i++) {
  213. - m = sprintf(buf, Fmt, Typp[i]);
  214. + m = sprintf(buf, Fmt, UnalignedRead(i));
  215. n = MY_MAX(n, m);
  216. } // endfor i
  217. @@ -1333,7 +1332,7 @@ char *DATBLK::GetCharString(char *p, int
  218. char *vp;
  219. if (Dvalp) {
  220. - Dvalp->SetValue(Typp[n]);
  221. + Dvalp->SetValue(UnalignedRead(n));
  222. vp = Dvalp->GetCharString(p);
  223. } else
  224. vp = TYPBLK<int>::GetCharString(p, n);
  225. @@ -1349,7 +1348,7 @@ void DATBLK::SetValue(PCSZ p, int n)
  226. if (Dvalp) {
  227. // Decode the string according to format
  228. Dvalp->SetValue_psz(p);
  229. - Typp[n] = Dvalp->GetIntValue();
  230. + UnalignedWrite(n, Dvalp->GetIntValue());
  231. } else
  232. TYPBLK<int>::SetValue(p, n);