libmms-prevent-unaligned-dereferences.patch 3.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384
  1. From 4fd16633a8c379971425f7fd482152f163b09158 Mon Sep 17 00:00:00 2001
  2. From: Paul Burton <Paul.Burton@imgtec.com>
  3. Date: Fri, 17 Sep 2010 14:08:57 +0100
  4. Subject: [PATCH] Endianness macros should not dereference unaligned pointers
  5. The LE_*/BE_* macros previously worked by casting the pointer passed to them to a pointer to the correct integer type, then dereferencing it. This will not work on architectures which don't allow unaligned data access. Instead, access one byte at a time and shift to form the value.
  6. ---
  7. src/bswap.h | 59 +++++++++++++++++++++++++++++++++++++++++++----------------
  8. 1 files changed, 43 insertions(+), 16 deletions(-)
  9. diff --git a/src/bswap.h b/src/bswap.h
  10. index b731da7..59e8716 100644
  11. --- a/src/bswap.h
  12. +++ b/src/bswap.h
  13. @@ -21,23 +21,50 @@
  14. */
  15. -/* Go cheap now, will rip out glib later. *Sigh* */
  16. -#include <glib.h>
  17. -
  18. -/* NOTE:
  19. - * Now, to clear up confusion: LE_XX means "from LE to native, XX bits wide"
  20. - * I know it's not very clear naming (tell me about it, I
  21. - * misinterpreted in first version and caused bad nasty bug, *sigh*),
  22. - * but that's inherited code, will clean up as things go
  23. - * Oh, and one more thing -- they take *pointers*, not actual ints
  24. - */
  25. +#include <stdint.h>
  26. +
  27. +#define SWAP_ENDIAN_16(val) \
  28. + (val[1] | (val[0] << 8))
  29. +#define SWAP_ENDIAN_32(val) \
  30. + (val[3] | (val[2] << 8) | (val[1] << 16) | (val[0] << 24))
  31. +#define SWAP_ENDIAN_64(val) \
  32. + (val[7] | (val[6] << 8) | (val[5] << 16) | (val[4] << 24) | \
  33. + ((uint64_t)val[3] << 32) | ((uint64_t)val[2] << 40) | \
  34. + ((uint64_t)val[1] << 48) | ((uint64_t)val[0] << 56))
  35. +
  36. +#define SAME_ENDIAN_16(val) \
  37. + (val[0] | (val[1] << 8))
  38. +#define SAME_ENDIAN_32(val) \
  39. + (val[0] | (val[1] << 8) | (val[2] << 16) | (val[3] << 24))
  40. +#define SAME_ENDIAN_64(val) \
  41. + (val[0] | (val[1] << 8) | (val[2] << 16) | (val[3] << 24) | \
  42. + ((uint64_t)val[4] << 32) | ((uint64_t)val[5] << 40) | \
  43. + ((uint64_t)val[6] << 48) | ((uint64_t)val[7] << 56))
  44. +
  45. +#ifndef WORDS_BIGENDIAN
  46. +
  47. +/* Little endian */
  48. +
  49. +#define LE_16(val) SAME_ENDIAN_16(((uint8_t *)(val)))
  50. +#define LE_32(val) SAME_ENDIAN_32(((uint8_t *)(val)))
  51. +#define LE_64(val) SAME_ENDIAN_64(((uint8_t *)(val)))
  52. +#define BE_16(val) SWAP_ENDIAN_16(((uint8_t *)(val)))
  53. +#define BE_32(val) SWAP_ENDIAN_32(((uint8_t *)(val)))
  54. +#define BE_64(val) SWAP_ENDIAN_64(((uint8_t *)(val)))
  55. +
  56. +#elif WORDS_BIGENDIAN == 1
  57. +
  58. +/* Big endian */
  59. -#define LE_16(val) (GINT16_FROM_LE (*((u_int16_t*)(val))))
  60. -#define BE_16(val) (GINT16_FROM_BE (*((u_int16_t*)(val))))
  61. -#define LE_32(val) (GINT32_FROM_LE (*((u_int32_t*)(val))))
  62. -#define BE_32(val) (GINT32_FROM_BE (*((u_int32_t*)(val))))
  63. +#define LE_16(val) SWAP_ENDIAN_16(((uint8_t *)(val)))
  64. +#define LE_32(val) SWAP_ENDIAN_32(((uint8_t *)(val)))
  65. +#define LE_64(val) SWAP_ENDIAN_64(((uint8_t *)(val)))
  66. +#define BE_16(val) SAME_ENDIAN_16(((uint8_t *)(val)))
  67. +#define BE_32(val) SAME_ENDIAN_32(((uint8_t *)(val)))
  68. +#define BE_64(val) SAME_ENDIAN_64(((uint8_t *)(val)))
  69. -#define LE_64(val) (GINT64_FROM_LE (*((u_int64_t*)(val))))
  70. -#define BE_64(val) (GINT64_FROM_BE (*((u_int64_t*)(val))))
  71. +#else
  72. +#error Unknown endianness!
  73. +#endif
  74. #endif /* BSWAP_H_INCLUDED */
  75. --
  76. 1.7.2.2