summaryrefslogtreecommitdiffstats
path: root/package/multimedia/libmms/libmms-prevent-unaligned-dereferences.patch
blob: 9c606eb29e837f0ba65907ac4913ee04a176d74c (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
From 4fd16633a8c379971425f7fd482152f163b09158 Mon Sep 17 00:00:00 2001
From: Paul Burton <Paul.Burton@imgtec.com>
Date: Fri, 17 Sep 2010 14:08:57 +0100
Subject: [PATCH] Endianness macros should not dereference unaligned pointers

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.
---
 src/bswap.h |   59 +++++++++++++++++++++++++++++++++++++++++++----------------
 1 files changed, 43 insertions(+), 16 deletions(-)

diff --git a/src/bswap.h b/src/bswap.h
index b731da7..59e8716 100644
--- a/src/bswap.h
+++ b/src/bswap.h
@@ -21,23 +21,50 @@
  */
 
 
-/* Go cheap now, will rip out glib later. *Sigh* */
-#include <glib.h>
-
-/* NOTE:
- * Now, to clear up confusion: LE_XX means "from LE to native, XX bits wide"
- * I know it's not very clear naming (tell me about it, I
- * misinterpreted in first version and caused bad nasty bug, *sigh*),
- * but that's inherited code, will clean up as things go
- * Oh, and one more thing -- they take *pointers*, not actual ints
- */
+#include <stdint.h>
+
+#define SWAP_ENDIAN_16(val) \
+	(val[1] | (val[0] << 8))
+#define SWAP_ENDIAN_32(val) \
+	(val[3] | (val[2] << 8) | (val[1] << 16) | (val[0] << 24))
+#define SWAP_ENDIAN_64(val) \
+	(val[7] | (val[6] << 8) | (val[5] << 16) | (val[4] << 24) | \
+	((uint64_t)val[3] << 32) | ((uint64_t)val[2] << 40) | \
+	((uint64_t)val[1] << 48) | ((uint64_t)val[0] << 56))
+
+#define SAME_ENDIAN_16(val) \
+	(val[0] | (val[1] << 8))
+#define SAME_ENDIAN_32(val) \
+	(val[0] | (val[1] << 8) | (val[2] << 16) | (val[3] << 24))
+#define SAME_ENDIAN_64(val) \
+	(val[0] | (val[1] << 8) | (val[2] << 16) | (val[3] << 24) | \
+	((uint64_t)val[4] << 32) | ((uint64_t)val[5] << 40) | \
+	((uint64_t)val[6] << 48) | ((uint64_t)val[7] << 56))
+
+#ifndef WORDS_BIGENDIAN
+
+/* Little endian */
+
+#define LE_16(val) SAME_ENDIAN_16(((uint8_t *)(val)))
+#define LE_32(val) SAME_ENDIAN_32(((uint8_t *)(val)))
+#define LE_64(val) SAME_ENDIAN_64(((uint8_t *)(val)))
+#define BE_16(val) SWAP_ENDIAN_16(((uint8_t *)(val)))
+#define BE_32(val) SWAP_ENDIAN_32(((uint8_t *)(val)))
+#define BE_64(val) SWAP_ENDIAN_64(((uint8_t *)(val)))
+
+#elif WORDS_BIGENDIAN == 1
+
+/* Big endian */
 
-#define LE_16(val) (GINT16_FROM_LE (*((u_int16_t*)(val))))
-#define BE_16(val) (GINT16_FROM_BE (*((u_int16_t*)(val))))
-#define LE_32(val) (GINT32_FROM_LE (*((u_int32_t*)(val))))
-#define BE_32(val) (GINT32_FROM_BE (*((u_int32_t*)(val))))
+#define LE_16(val) SWAP_ENDIAN_16(((uint8_t *)(val)))
+#define LE_32(val) SWAP_ENDIAN_32(((uint8_t *)(val)))
+#define LE_64(val) SWAP_ENDIAN_64(((uint8_t *)(val)))
+#define BE_16(val) SAME_ENDIAN_16(((uint8_t *)(val)))
+#define BE_32(val) SAME_ENDIAN_32(((uint8_t *)(val)))
+#define BE_64(val) SAME_ENDIAN_64(((uint8_t *)(val)))
 
-#define LE_64(val) (GINT64_FROM_LE (*((u_int64_t*)(val))))
-#define BE_64(val) (GINT64_FROM_BE (*((u_int64_t*)(val))))
+#else
+#error Unknown endianness!
+#endif
 
 #endif /* BSWAP_H_INCLUDED */
-- 
1.7.2.2