From 70d0d2a966eefb682a676e38f5dc6e606017f380 Mon Sep 17 00:00:00 2001
From: BogDan Vatra <bogdan@kde.org>
Date: Sun, 28 Dec 2014 11:34:54 +0200
Subject: [PATCH 09/11] FIX SIGBUS: Don't read unaligned on ARM.
Add readUnAligned function, update XeroXMB
---
source/lib/alignment.h | 12 +++++++++
source/ps/XML/XeroXMB.cpp | 62 +++++++++++++++++++++++------------------------
2 files changed, 43 insertions(+), 31 deletions(-)
diff --git a/source/lib/alignment.h b/source/lib/alignment.h
index a294a0f..799e800 100644
a
|
b
|
inline size_t Align(size_t n)
|
18 | 18 | } |
19 | 19 | |
20 | 20 | |
| 21 | template<typename T> |
| 22 | inline T readUnaligned(const void *ptr) |
| 23 | { |
| 24 | #if ARCH_ARM |
| 25 | T ret; |
| 26 | memcpy(&ret, ptr, sizeof(T)); |
| 27 | return ret; |
| 28 | #else |
| 29 | return *(T*)(ptr); |
| 30 | #endif |
| 31 | } |
| 32 | |
21 | 33 | // bridge the differences between MSC and GCC alignment definitions. |
22 | 34 | // example: ALIGNED(int, 8) myAlignedVariable = 0; |
23 | 35 | #if MSC_VERSION |
diff --git a/source/ps/XML/XeroXMB.cpp b/source/ps/XML/XeroXMB.cpp
index 35b4712..0460cf4 100644
a
|
b
|
bool XMBFile::Initialise(const char* FileData)
|
41 | 41 | return false; |
42 | 42 | ENSURE(!strcmp(Header, HeaderMagicStr) && "Invalid XMB header!"); |
43 | 43 | |
44 | | u32 Version = *(u32*)m_Pointer; |
| 44 | u32 Version = readUnaligned<u32>(m_Pointer); |
45 | 45 | m_Pointer += 4; |
46 | 46 | if (Version != XMBVersion) |
47 | 47 | return false; |
… |
… |
bool XMBFile::Initialise(const char* FileData)
|
55 | 55 | |
56 | 56 | #ifdef XERO_USEMAP |
57 | 57 | // Build a std::map of all the names->ids |
58 | | u32 ElementNameCount = *(u32*)m_Pointer; m_Pointer += 4; |
| 58 | u32 ElementNameCount = readUnAligned<u32>(m_Pointer); m_Pointer += 4; |
59 | 59 | for (i = 0; i < ElementNameCount; ++i) |
60 | 60 | m_ElementNames[ReadZStr8()] = i; |
61 | 61 | |
62 | | u32 AttributeNameCount = *(u32*)m_Pointer; m_Pointer += 4; |
| 62 | u32 AttributeNameCount = readUnAligned<u32>(m_Pointer); m_Pointer += 4; |
63 | 63 | for (i = 0; i < AttributeNameCount; ++i) |
64 | 64 | m_AttributeNames[ReadZStr8()] = i; |
65 | 65 | #else |
66 | 66 | // Ignore all the names for now, and skip over them |
67 | 67 | // (remembering the position of the first) |
68 | | m_ElementNameCount = *(int*)m_Pointer; m_Pointer += 4; |
| 68 | m_ElementNameCount = readUnaligned<int>(m_Pointer); m_Pointer += 4; |
69 | 69 | m_ElementPointer = m_Pointer; |
70 | 70 | for (i = 0; i < m_ElementNameCount; ++i) |
71 | | m_Pointer += 4 + *(int*)m_Pointer; // skip over the string |
| 71 | m_Pointer += 4 + readUnaligned<int>(m_Pointer); // skip over the string |
72 | 72 | |
73 | | m_AttributeNameCount = *(int*)m_Pointer; m_Pointer += 4; |
| 73 | m_AttributeNameCount = readUnaligned<int>(m_Pointer); m_Pointer += 4; |
74 | 74 | m_AttributePointer = m_Pointer; |
75 | 75 | for (i = 0; i < m_AttributeNameCount; ++i) |
76 | | m_Pointer += 4 + *(int*)m_Pointer; // skip over the string |
| 76 | m_Pointer += 4 + readUnaligned<int>(m_Pointer); // skip over the string |
77 | 77 | #endif |
78 | 78 | |
79 | 79 | return true; // success |
… |
… |
bool XMBFile::Initialise(const char* FileData)
|
81 | 81 | |
82 | 82 | std::string XMBFile::ReadZStr8() |
83 | 83 | { |
84 | | int Length = *(int*)m_Pointer; |
| 84 | int Length = readUnaligned<int>(m_Pointer); |
85 | 85 | m_Pointer += 4; |
86 | 86 | std::string String (m_Pointer); // reads up until the first NULL |
87 | 87 | m_Pointer += Length; |
… |
… |
int XMBFile::GetElementID(const char* Name) const
|
119 | 119 | { |
120 | 120 | // See if this could be the right string, checking its |
121 | 121 | // length and then its contents |
122 | | if (*(int*)Pos == len && strncasecmp(Pos+4, Name, len) == 0) |
| 122 | if (readUnaligned<int>(Pos) == len && strncasecmp(Pos+4, Name, len) == 0) |
123 | 123 | return i; |
124 | 124 | // If not, jump to the next string |
125 | | Pos += 4 + *(int*)Pos; |
| 125 | Pos += 4 + readUnaligned<int>(Pos); |
126 | 126 | } |
127 | 127 | // Failed |
128 | 128 | return -1; |
… |
… |
int XMBFile::GetAttributeID(const char* Name) const
|
139 | 139 | { |
140 | 140 | // See if this could be the right string, checking its |
141 | 141 | // length and then its contents |
142 | | if (*(int*)Pos == len && strncasecmp(Pos+4, Name, len) == 0) |
| 142 | if (readUnaligned<int>(Pos) == len && strncasecmp(Pos+4, Name, len) == 0) |
143 | 143 | return i; |
144 | 144 | // If not, jump to the next string |
145 | | Pos += 4 + *(int*)Pos; |
| 145 | Pos += 4 + readUnaligned<int>(Pos); |
146 | 146 | } |
147 | 147 | // Failed |
148 | 148 | return -1; |
… |
… |
std::string XMBFile::GetElementString(const int ID) const
|
156 | 156 | { |
157 | 157 | const char* Pos = m_ElementPointer; |
158 | 158 | for (int i = 0; i < ID; ++i) |
159 | | Pos += 4 + *(int*)Pos; |
| 159 | Pos += 4 + readUnaligned<int>(Pos); |
160 | 160 | return std::string(Pos+4); |
161 | 161 | } |
162 | 162 | |
… |
… |
std::string XMBFile::GetAttributeString(const int ID) const
|
164 | 164 | { |
165 | 165 | const char* Pos = m_AttributePointer; |
166 | 166 | for (int i = 0; i < ID; ++i) |
167 | | Pos += 4 + *(int*)Pos; |
| 167 | Pos += 4 + readUnaligned<int>(Pos); |
168 | 168 | return std::string(Pos+4); |
169 | 169 | } |
170 | 170 | |
… |
… |
int XMBElement::GetNodeName() const
|
175 | 175 | if (m_Pointer == NULL) |
176 | 176 | return -1; |
177 | 177 | |
178 | | return *(int*)(m_Pointer + 4); // == ElementName |
| 178 | return readUnaligned<int>(m_Pointer + 4); // == ElementName |
179 | 179 | } |
180 | 180 | |
181 | 181 | XMBElementList XMBElement::GetChildNodes() const |
… |
… |
XMBElementList XMBElement::GetChildNodes() const
|
184 | 184 | return XMBElementList(NULL, 0); |
185 | 185 | |
186 | 186 | return XMBElementList( |
187 | | m_Pointer + 20 + *(int*)(m_Pointer + 16), // == Children[] |
188 | | *(int*)(m_Pointer + 12) // == ChildCount |
| 187 | m_Pointer + 20 + readUnaligned<int>(m_Pointer + 16), // == Children[] |
| 188 | readUnaligned<int>(m_Pointer + 12) // == ChildCount |
189 | 189 | ); |
190 | 190 | } |
191 | 191 | |
… |
… |
XMBAttributeList XMBElement::GetAttributes() const
|
195 | 195 | return XMBAttributeList(NULL, 0); |
196 | 196 | |
197 | 197 | return XMBAttributeList( |
198 | | m_Pointer + 24 + *(int*)(m_Pointer + 20), // == Attributes[] |
199 | | *(int*)(m_Pointer + 8) // == AttributeCount |
| 198 | m_Pointer + 24 + readUnaligned<int>(m_Pointer + 20), // == Attributes[] |
| 199 | readUnaligned<int>(m_Pointer + 8) // == AttributeCount |
200 | 200 | ); |
201 | 201 | } |
202 | 202 | |
203 | 203 | CStr8 XMBElement::GetText() const |
204 | 204 | { |
205 | 205 | // Return empty string if there's no text |
206 | | if (m_Pointer == NULL || *(int*)(m_Pointer + 20) == 0) |
| 206 | if (m_Pointer == NULL || readUnaligned<int>(m_Pointer + 20) == 0) |
207 | 207 | return CStr8(); |
208 | 208 | |
209 | 209 | return CStr8(m_Pointer + 28); |
… |
… |
CStr8 XMBElement::GetText() const
|
212 | 212 | int XMBElement::GetLineNumber() const |
213 | 213 | { |
214 | 214 | // Make sure there actually was some text to record the line of |
215 | | if (m_Pointer == NULL || *(int*)(m_Pointer + 20) == 0) |
| 215 | if (m_Pointer == NULL || readUnaligned<int>(m_Pointer + 20) == 0) |
216 | 216 | return -1; |
217 | 217 | else |
218 | | return *(int*)(m_Pointer + 24); |
| 218 | return readUnaligned<int>(m_Pointer + 24); |
219 | 219 | } |
220 | 220 | |
221 | 221 | XMBElement XMBElementList::GetFirstNamedItem(const int ElementName) const |
… |
… |
XMBElement XMBElementList::GetFirstNamedItem(const int ElementName) const
|
226 | 226 | // fast enough with half a dozen attributes: |
227 | 227 | for (int i = 0; i < Count; ++i) |
228 | 228 | { |
229 | | int Length = *(int*)Pos; |
230 | | int Name = *(int*)(Pos+4); |
| 229 | int Length = readUnaligned<int>(Pos); |
| 230 | int Name = readUnaligned<int>(Pos+4); |
231 | 231 | if (Name == ElementName) |
232 | 232 | return XMBElement(Pos); |
233 | 233 | Pos += Length; |
… |
… |
XMBElement XMBElementList::Item(const int id)
|
247 | 247 | if (id == m_LastItemID+1) |
248 | 248 | { |
249 | 249 | Pos = m_LastPointer; |
250 | | Pos += *(int*)Pos; // skip over the last node |
| 250 | Pos += readUnaligned<int>(Pos); // skip over the last node |
251 | 251 | } |
252 | 252 | else |
253 | 253 | { |
254 | 254 | Pos = m_Pointer; |
255 | 255 | // Skip over each preceding node |
256 | 256 | for (int i=0; i<id; ++i) |
257 | | Pos += *(int*)Pos; |
| 257 | Pos += readUnaligned<int>(Pos); |
258 | 258 | } |
259 | 259 | // Cache information about this node |
260 | 260 | m_LastItemID = id; |
… |
… |
CStr8 XMBAttributeList::GetNamedItem(const int AttributeName) const
|
271 | 271 | // fast enough with half a dozen attributes: |
272 | 272 | for (int i = 0; i < Count; ++i) |
273 | 273 | { |
274 | | if (*(int*)Pos == AttributeName) |
| 274 | if (readUnaligned<int>(Pos) == AttributeName) |
275 | 275 | return CStr8(Pos+8); |
276 | | Pos += 8 + *(int*)(Pos+4); // Skip over the string |
| 276 | Pos += 8 + readUnaligned<int>(Pos+4); // Skip over the string |
277 | 277 | } |
278 | 278 | |
279 | 279 | // Can't find attribute |
… |
… |
XMBAttribute XMBAttributeList::Item(const int id)
|
291 | 291 | { |
292 | 292 | Pos = m_LastPointer; |
293 | 293 | // Skip over the last attribute |
294 | | Pos += 8 + *(int*)(Pos+4); |
| 294 | Pos += 8 + readUnaligned<int>(Pos+4); |
295 | 295 | } |
296 | 296 | else |
297 | 297 | { |
298 | 298 | Pos = m_Pointer; |
299 | 299 | // Skip over each preceding attribute |
300 | 300 | for (int i=0; i<id; ++i) |
301 | | Pos += 8 + *(int*)(Pos+4); // skip ID, length, and string data |
| 301 | Pos += 8 + readUnaligned<int>(Pos+4); // skip ID, length, and string data |
302 | 302 | } |
303 | 303 | // Cache information about this attribute |
304 | 304 | m_LastItemID = id; |
305 | 305 | m_LastPointer = Pos; |
306 | 306 | |
307 | | return XMBAttribute(*(int*)Pos, CStr8(Pos+8)); |
| 307 | return XMBAttribute(readUnaligned<int>(Pos), CStr8(Pos+8)); |
308 | 308 | } |