mirror of
				https://github.com/MariaDB/server.git
				synced 2025-11-04 04:46:15 +01:00 
			
		
		
		
	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>
		
			
				
	
	
		
			375 lines
		
	
	
	
		
			15 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
			
		
		
	
	
			375 lines
		
	
	
	
		
			15 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
/*************** Valblk H Declares Source Code File (.H) ***************/
 | 
						|
/*  Name: VALBLK.H    Version 2.1                                      */
 | 
						|
/*                                                                     */
 | 
						|
/*  (C) Copyright to the author Olivier BERTRAND          2005-2014    */
 | 
						|
/*                                                                     */
 | 
						|
/*  This file contains the VALBLK and derived classes declares.        */
 | 
						|
/***********************************************************************/
 | 
						|
 | 
						|
/***********************************************************************/
 | 
						|
/*  Include required application header files                          */
 | 
						|
/*  assert.h     is header required when using the assert function.    */
 | 
						|
/*  block.h      is header containing Block    global declarations.    */
 | 
						|
/***********************************************************************/
 | 
						|
#ifndef __VALBLK__H__
 | 
						|
#define __VALBLK__H__
 | 
						|
#include "value.h"
 | 
						|
 | 
						|
/***********************************************************************/
 | 
						|
/*  Utility used to allocate value blocks.                             */
 | 
						|
/***********************************************************************/
 | 
						|
DllExport PVBLK AllocValBlock(PGLOBAL, void*, int, int, int, int,
 | 
						|
                                              bool, bool, bool);
 | 
						|
const char *GetFmt(int type, bool un = false);
 | 
						|
 | 
						|
/***********************************************************************/
 | 
						|
/*  DB static external variables.                                      */
 | 
						|
/***********************************************************************/
 | 
						|
extern MBLOCK Nmblk;                /* Used to initialize MBLOCK's     */
 | 
						|
 | 
						|
/***********************************************************************/
 | 
						|
/*  Class MBVALS is a utility class for (re)allocating VALBLK's.       */
 | 
						|
/***********************************************************************/
 | 
						|
class MBVALS : public BLOCK {
 | 
						|
//friend class LSTBLK;
 | 
						|
  friend class ARRAY;
 | 
						|
 public:
 | 
						|
  // Constructors
 | 
						|
  MBVALS(void) {Vblk = NULL; Mblk = Nmblk;}
 | 
						|
 | 
						|
  // Methods
 | 
						|
  void  *GetMemp(void) {return Mblk.Memp;}
 | 
						|
  PVBLK  Allocate(PGLOBAL g, int type, int len, int prec,
 | 
						|
                             int n, bool sub = false);
 | 
						|
  bool   ReAllocate(PGLOBAL g, int n);
 | 
						|
  void   Free(void);
 | 
						|
 | 
						|
 protected:
 | 
						|
  // Members
 | 
						|
  PVBLK  Vblk;                    // Pointer to VALBLK
 | 
						|
  MBLOCK Mblk;                    // The memory block
 | 
						|
  }; // end of class MBVALS
 | 
						|
 | 
						|
typedef class MBVALS *PMBV;
 | 
						|
 | 
						|
/***********************************************************************/
 | 
						|
/*  Class VALBLK represent a base class for variable blocks.           */
 | 
						|
/***********************************************************************/
 | 
						|
class VALBLK : public BLOCK {
 | 
						|
 public:
 | 
						|
  // Constructors
 | 
						|
  VALBLK(void *mp, int type, int nval, bool un = false);
 | 
						|
 | 
						|
  // Implementation
 | 
						|
          int    GetNval(void) {return Nval;}
 | 
						|
          void   SetNval(int n) {Nval = n;}
 | 
						|
          void  *GetValPointer(void) {return Blkp;}
 | 
						|
          void   SetValPointer(void *mp) {Blkp = mp;}
 | 
						|
          int    GetType(void) {return Type;}
 | 
						|
          int    GetPrec(void) {return Prec;}
 | 
						|
          void   SetCheck(bool b) {Check = b;}
 | 
						|
          void   MoveNull(int i, int j)
 | 
						|
                  {if (To_Nulls) To_Nulls[j] = To_Nulls[i];}
 | 
						|
  virtual void   SetNull(int n, bool b)
 | 
						|
                  {if (To_Nulls) {To_Nulls[n] = (b) ? '*' : 0;}}
 | 
						|
  virtual bool   IsNull(int n) {return To_Nulls && To_Nulls[n];}
 | 
						|
	virtual bool   IsNullable(void) {return Nullable;}
 | 
						|
	virtual void   SetNullable(bool b);
 | 
						|
  virtual bool   IsUnsigned(void) {return Unsigned;}
 | 
						|
  virtual bool   Init(PGLOBAL g, bool check) = 0;
 | 
						|
  virtual int    GetVlen(void) = 0;
 | 
						|
  virtual PSZ    GetCharValue(int n);
 | 
						|
  virtual char   GetTinyValue(int n) = 0;
 | 
						|
  virtual uchar  GetUTinyValue(int n) = 0;
 | 
						|
  virtual short  GetShortValue(int n) = 0;
 | 
						|
  virtual ushort GetUShortValue(int n) = 0;
 | 
						|
  virtual int    GetIntValue(int n) = 0;
 | 
						|
  virtual uint   GetUIntValue(int n) = 0;
 | 
						|
  virtual longlong GetBigintValue(int n) = 0;
 | 
						|
  virtual ulonglong GetUBigintValue(int n) = 0;
 | 
						|
  virtual double GetFloatValue(int n) = 0;
 | 
						|
  virtual char  *GetCharString(char *p, int n) = 0;
 | 
						|
  virtual void   ReAlloc(void *mp, int n) {Blkp = mp; Nval = n;}
 | 
						|
  virtual void   Reset(int n) = 0;
 | 
						|
  virtual bool   SetFormat(PGLOBAL g, PCSZ fmt, int len, int year = 0);
 | 
						|
  virtual void   SetPrec(int p) {}
 | 
						|
  virtual bool   IsCi(void) {return false;}
 | 
						|
 | 
						|
  // Methods
 | 
						|
  virtual void   SetValue(short, int) {assert(false);}
 | 
						|
  virtual void   SetValue(ushort, int) {assert(false);}
 | 
						|
  virtual void   SetValue(int, int) {assert(false);}
 | 
						|
  virtual void   SetValue(uint, int) {assert(false);}
 | 
						|
  virtual void   SetValue(longlong, int) {assert(false);}
 | 
						|
  virtual void   SetValue(ulonglong, int) {assert(false);}
 | 
						|
  virtual void   SetValue(double, int) {assert(false);}
 | 
						|
  virtual void   SetValue(char, int) {assert(false);}
 | 
						|
  virtual void   SetValue(uchar, int) {assert(false);}
 | 
						|
  virtual void   SetValue(PCSZ, int) {assert(false);}
 | 
						|
  virtual void   SetValue(const char *, uint, int) {assert(false);}
 | 
						|
  virtual void   SetValue(PVAL valp, int n) = 0;
 | 
						|
  virtual void   SetValue(PVBLK pv, int n1, int n2) = 0;
 | 
						|
  virtual void   SetMin(PVAL valp, int n) = 0;
 | 
						|
  virtual void   SetMax(PVAL valp, int n) = 0;
 | 
						|
  virtual void   Move(int i, int j) = 0;
 | 
						|
  virtual int    CompVal(PVAL vp, int n) = 0;
 | 
						|
  virtual int    CompVal(int i1, int i2) = 0;
 | 
						|
  virtual void  *GetValPtr(int n) = 0;
 | 
						|
  virtual void  *GetValPtrEx(int n) = 0;
 | 
						|
  virtual int    Find(PVAL vp) = 0;
 | 
						|
  virtual int    GetMaxLength(void) = 0;
 | 
						|
          bool   Locate(PVAL vp, int& i);
 | 
						|
 | 
						|
 protected:
 | 
						|
  bool AllocBuff(PGLOBAL g, size_t size);
 | 
						|
  void ChkIndx(int n);
 | 
						|
  void ChkTyp(PVAL v);
 | 
						|
  void ChkTyp(PVBLK vb);
 | 
						|
 | 
						|
  // Members
 | 
						|
  PGLOBAL Global;           // Used for messages and allocation
 | 
						|
  MBLOCK  Mblk;             // Used to allocate buffer
 | 
						|
  char   *To_Nulls;         // Null values array
 | 
						|
  void   *Blkp;             // To value block
 | 
						|
  bool    Check;            // If true SetValue types must match
 | 
						|
  bool    Nullable;         // True if values can be null
 | 
						|
  bool    Unsigned;         // True if values are unsigned
 | 
						|
  int     Type;             // Type of individual values
 | 
						|
  int     Nval;             // Max number of values in block
 | 
						|
  int     Prec;             // Precision of float values
 | 
						|
  }; // end of class VALBLK
 | 
						|
 | 
						|
/***********************************************************************/
 | 
						|
/*  Class TYPBLK: represents a block of typed values.                  */
 | 
						|
/***********************************************************************/
 | 
						|
template <class TYPE>
 | 
						|
class TYPBLK : public VALBLK {
 | 
						|
 public:
 | 
						|
  // Constructors
 | 
						|
  TYPBLK(void *mp, int size, int type, int prec = 0, bool un = false);
 | 
						|
 | 
						|
  // Implementation
 | 
						|
  virtual bool   Init(PGLOBAL g, bool check);
 | 
						|
  virtual int    GetVlen(void) {return sizeof(TYPE);}
 | 
						|
 | 
						|
  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) {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)
 | 
						|
                  {UnalignedWrite(n, (TYPE)sval); SetNull(n, false);}
 | 
						|
  virtual void   SetValue(ushort sval, int n)
 | 
						|
                  {UnalignedWrite(n, (TYPE)sval); SetNull(n, false);}
 | 
						|
  virtual void   SetValue(int lval, int n)
 | 
						|
                  {UnalignedWrite(n, (TYPE)lval); SetNull(n, false);}
 | 
						|
  virtual void   SetValue(uint lval, int n)
 | 
						|
                  {UnalignedWrite(n, (TYPE)lval); SetNull(n, false);}
 | 
						|
  virtual void   SetValue(longlong lval, int n)
 | 
						|
                  {UnalignedWrite(n, (TYPE)lval); SetNull(n, false);}
 | 
						|
  virtual void   SetValue(ulonglong lval, int n)
 | 
						|
                  {UnalignedWrite(n, (TYPE)lval); SetNull(n, false);}
 | 
						|
  virtual void   SetValue(double fval, int n)
 | 
						|
                  {UnalignedWrite(n, (TYPE)fval); SetNull(n, false);}
 | 
						|
  virtual void   SetValue(char cval, int n)
 | 
						|
                  {UnalignedWrite(n, (TYPE)cval); SetNull(n, false);}
 | 
						|
  virtual void   SetValue(uchar cval, int n)
 | 
						|
                  {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);
 | 
						|
  virtual void   SetMax(PVAL valp, int n);
 | 
						|
  virtual void   Move(int i, int j);
 | 
						|
  virtual int    CompVal(PVAL vp, int n);
 | 
						|
  virtual int    CompVal(int i1, int i2);
 | 
						|
  virtual void  *GetValPtr(int n);
 | 
						|
  virtual void  *GetValPtrEx(int n);
 | 
						|
  virtual int    Find(PVAL vp);
 | 
						|
  virtual int    GetMaxLength(void);
 | 
						|
 | 
						|
 protected:
 | 
						|
  // Specialized functions
 | 
						|
  static ulonglong MaxVal(void);
 | 
						|
  TYPE GetTypedValue(PVAL vp);
 | 
						|
  TYPE GetTypedValue(PVBLK blk, int n);
 | 
						|
 | 
						|
  // 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
 | 
						|
 | 
						|
/***********************************************************************/
 | 
						|
/*  Class CHRBLK: represent a block of fixed length strings.           */
 | 
						|
/***********************************************************************/
 | 
						|
class CHRBLK : public VALBLK {
 | 
						|
 public:
 | 
						|
  // Constructors
 | 
						|
  CHRBLK(void *mp, int size, int type, int len, int prec, bool b);
 | 
						|
 | 
						|
  // Implementation
 | 
						|
  virtual bool   Init(PGLOBAL g, bool check);
 | 
						|
  virtual int    GetVlen(void) {return Long;}
 | 
						|
  virtual PSZ    GetCharValue(int n);
 | 
						|
  virtual char   GetTinyValue(int n);
 | 
						|
  virtual uchar  GetUTinyValue(int n);
 | 
						|
  virtual short  GetShortValue(int n);
 | 
						|
  virtual ushort GetUShortValue(int n);
 | 
						|
  virtual int    GetIntValue(int n);
 | 
						|
  virtual uint   GetUIntValue(int n);
 | 
						|
  virtual longlong GetBigintValue(int n);
 | 
						|
  virtual ulonglong GetUBigintValue(int n);
 | 
						|
  virtual double GetFloatValue(int n);
 | 
						|
  virtual char  *GetCharString(char *p, int n);
 | 
						|
  virtual void   Reset(int n);
 | 
						|
  virtual void   SetPrec(int p) {Ci = (p != 0);}
 | 
						|
  virtual bool   IsCi(void) {return Ci;}
 | 
						|
 | 
						|
  // Methods
 | 
						|
  using VALBLK::SetValue;
 | 
						|
  virtual void   SetValue(PCSZ sp, int n);
 | 
						|
  virtual void   SetValue(const char *sp, uint len, int n);
 | 
						|
  virtual void   SetValue(PVAL valp, int n);
 | 
						|
  virtual void   SetValue(PVBLK pv, int n1, int n2);
 | 
						|
  virtual void   SetMin(PVAL valp, int n);
 | 
						|
  virtual void   SetMax(PVAL valp, int n);
 | 
						|
  virtual void   Move(int i, int j);
 | 
						|
  virtual int    CompVal(PVAL vp, int n);
 | 
						|
  virtual int    CompVal(int i1, int i2);
 | 
						|
  virtual void  *GetValPtr(int n);
 | 
						|
  virtual void  *GetValPtrEx(int n);
 | 
						|
  virtual int    Find(PVAL vp);
 | 
						|
  virtual int    GetMaxLength(void);
 | 
						|
 | 
						|
 protected:
 | 
						|
  // Members
 | 
						|
  char* const &Chrp;             // Pointer to char buffer
 | 
						|
  PSZ   Valp;                    // Used to make a zero ended value
 | 
						|
  bool  Blanks;                  // True for right filling with blanks
 | 
						|
  bool  Ci;                      // True if case insensitive
 | 
						|
  int   Long;                    // Length of each string
 | 
						|
  }; // end of class CHRBLK
 | 
						|
 | 
						|
/***********************************************************************/
 | 
						|
/*  Class STRBLK: represent a block of string pointers.                */
 | 
						|
/*  Currently this class is used only by the DECODE scalar function    */
 | 
						|
/*  and by the MyColumn function to store date formats.                */
 | 
						|
/***********************************************************************/
 | 
						|
class STRBLK : public VALBLK {
 | 
						|
 public:
 | 
						|
  // Constructors
 | 
						|
  STRBLK(PGLOBAL g, void *mp, int size, int type);
 | 
						|
 | 
						|
  // Implementation
 | 
						|
  virtual void   SetNull(int n, bool b) {if (b) {Strp[n] = NULL;}}
 | 
						|
  virtual bool   IsNull(int n) {return Strp[n] == NULL;}
 | 
						|
  virtual void   SetNullable(bool) {}      // Always nullable
 | 
						|
  virtual bool   Init(PGLOBAL g, bool check);
 | 
						|
  virtual int    GetVlen(void) {return sizeof(PSZ);}
 | 
						|
  virtual PSZ    GetCharValue(int n) {return Strp[n];}
 | 
						|
  virtual char   GetTinyValue(int n);
 | 
						|
  virtual uchar  GetUTinyValue(int n);
 | 
						|
  virtual short  GetShortValue(int n);
 | 
						|
  virtual ushort GetUShortValue(int n);
 | 
						|
  virtual int    GetIntValue(int n);
 | 
						|
  virtual uint   GetUIntValue(int n);
 | 
						|
  virtual longlong GetBigintValue(int n);
 | 
						|
  virtual ulonglong GetUBigintValue(int n);
 | 
						|
  virtual double GetFloatValue(int n) {return atof(Strp[n]);}
 | 
						|
  virtual char  *GetCharString(char *, int n) {return Strp[n];}
 | 
						|
  virtual void   Reset(int n) {Strp[n] = NULL;}
 | 
						|
 | 
						|
  // Methods
 | 
						|
  using VALBLK::SetValue;
 | 
						|
  virtual void   SetValue(PCSZ sp, int n);
 | 
						|
  virtual void   SetValue(const char *sp, uint len, int n);
 | 
						|
  virtual void   SetValue(PVAL valp, int n);
 | 
						|
  virtual void   SetValue(PVBLK pv, int n1, int n2);
 | 
						|
  virtual void   SetMin(PVAL valp, int n);
 | 
						|
  virtual void   SetMax(PVAL valp, int n);
 | 
						|
  virtual void   Move(int i, int j);
 | 
						|
  virtual int    CompVal(PVAL vp, int n);
 | 
						|
  virtual int    CompVal(int i1, int i2);
 | 
						|
  virtual void  *GetValPtr(int n);
 | 
						|
  virtual void  *GetValPtrEx(int n);
 | 
						|
  virtual int    Find(PVAL vp);
 | 
						|
  virtual int    GetMaxLength(void);
 | 
						|
 | 
						|
  // Specific
 | 
						|
          void   SetSorted(bool b) {Sorted = b;}
 | 
						|
 | 
						|
 protected:
 | 
						|
  // Members
 | 
						|
  PSZ* const &Strp;              // Pointer to PSZ buffer
 | 
						|
  bool        Sorted;            // Values are (semi?) sorted
 | 
						|
  }; // end of class STRBLK
 | 
						|
 | 
						|
/***********************************************************************/
 | 
						|
/*  Class DATBLK: represents a block of time stamp values.             */
 | 
						|
/***********************************************************************/
 | 
						|
class DATBLK : public TYPBLK<int> {
 | 
						|
 public:
 | 
						|
  // Constructor
 | 
						|
  DATBLK(void *mp, int size);
 | 
						|
 | 
						|
  // Implementation
 | 
						|
  virtual bool  SetFormat(PGLOBAL g, PCSZ fmt, int len, int year = 0);
 | 
						|
  virtual char *GetCharString(char *p, int n);
 | 
						|
 | 
						|
  // Methods
 | 
						|
  using TYPBLK<int>::SetValue;
 | 
						|
  virtual void  SetValue(PCSZ sp, int n);
 | 
						|
 | 
						|
 protected:
 | 
						|
  // Members
 | 
						|
  PVAL Dvalp;                    // Date value used to convert string
 | 
						|
  }; // end of class DATBLK
 | 
						|
 | 
						|
/***********************************************************************/
 | 
						|
/*  Class PTRBLK: represent a block of char pointers.                  */
 | 
						|
/*  Currently this class is used only by the ARRAY class to make and   */
 | 
						|
/*  sort a list of char pointers.                                      */
 | 
						|
/***********************************************************************/
 | 
						|
class PTRBLK : public STRBLK {
 | 
						|
  friend class ARRAY;
 | 
						|
  friend PVBLK AllocValBlock(PGLOBAL, void *, int, int, int, int,
 | 
						|
                                              bool, bool, bool);
 | 
						|
 protected:
 | 
						|
  // Constructors
 | 
						|
  PTRBLK(PGLOBAL g, void *mp, int size) : STRBLK(g, mp, size, TYPE_PCHAR) {}
 | 
						|
 | 
						|
  // Implementation
 | 
						|
 | 
						|
  // Methods
 | 
						|
  using STRBLK::SetValue;
 | 
						|
  using STRBLK::CompVal;
 | 
						|
  virtual void   SetValue(PCSZ p, int n) {Strp[n] = (char*)p;}
 | 
						|
  virtual int    CompVal(int i1, int i2);
 | 
						|
 | 
						|
 protected:
 | 
						|
  // Members
 | 
						|
  }; // end of class PTRBLK
 | 
						|
 | 
						|
#endif // __VALBLK__H__
 | 
						|
 |