diff options
author | Joshua Watt <jpewhacker@gmail.com> | 2018-10-29 12:23:01 -0500 |
---|---|---|
committer | Armin Kuster <akuster808@gmail.com> | 2019-01-07 08:26:53 -0800 |
commit | 091808f08a1a988c117f68e14a26a4670bad918e (patch) | |
tree | 114ab37f4da13f6f11f314ccf4e8f0874481824f | |
parent | 8760facba1bceb299b3613b8955621ddaa3d4c3f (diff) | |
download | meta-openembedded-091808f08a1a988c117f68e14a26a4670bad918e.tar.gz |
rapidjson: Fix data abort on ARM
The internal memory allocator that RapidJSON uses wasn't correctly
aligning memory in all cases, which resulted in data aborts when running
on ARM-based processors.
This was fixed upstream in 748a652f04cd3a202ce3639770238bd9473b300c
Signed-off-by: Joshua Watt <JPEWhacker@gmail.com>
Signed-off-by: Armin Kuster <akuster808@gmail.com>
-rw-r--r-- | meta-oe/recipes-devtools/rapidjson/rapidjson/0001-Fix-SIGBUS-due-to-unaligned-access.patch | 100 | ||||
-rw-r--r-- | meta-oe/recipes-devtools/rapidjson/rapidjson_git.bb | 1 |
2 files changed, 101 insertions, 0 deletions
diff --git a/meta-oe/recipes-devtools/rapidjson/rapidjson/0001-Fix-SIGBUS-due-to-unaligned-access.patch b/meta-oe/recipes-devtools/rapidjson/rapidjson/0001-Fix-SIGBUS-due-to-unaligned-access.patch new file mode 100644 index 000000000..0299fc81a --- /dev/null +++ b/meta-oe/recipes-devtools/rapidjson/rapidjson/0001-Fix-SIGBUS-due-to-unaligned-access.patch | |||
@@ -0,0 +1,100 @@ | |||
1 | From 748a652f04cd3a202ce3639770238bd9473b300c Mon Sep 17 00:00:00 2001 | ||
2 | From: Veselin Georgiev <veselin.georgiev@garmin.com> | ||
3 | Date: Fri, 27 Jul 2018 13:33:09 -0500 | ||
4 | Subject: [PATCH] Fix SIGBUS due to unaligned access | ||
5 | |||
6 | Update RAPIDJSON_ALIGN() to always align on an 8-byte boundary | ||
7 | unless otherwise overridden. | ||
8 | |||
9 | On some platforms (such as ARM), 64-bit items (such as doubles and | ||
10 | 64-bit integers) must be aligned to an 8 byte address, even though the | ||
11 | architecture is only 32-bits. On these platforms, MemoryPoolAllocator | ||
12 | must match the malloc() behavior and return a 8 byte aligned allocation. | ||
13 | This eliminates any alignment issues that may occur at the expense of | ||
14 | additional memory overhead. | ||
15 | |||
16 | Failure to do so caused a SIGBUS signal when calling | ||
17 | GenericValue::SetNull(). The size of the data_ member of the | ||
18 | GenericValue class is 16 bytes in 32-bit mode and its constructor | ||
19 | requires an 8-byte aligned access. | ||
20 | |||
21 | While parsing a JSON formatted string using Document::ParseStream(), a | ||
22 | stack object containing GenericValue items was constructed. Since the | ||
23 | stack was 8-byte aligned, the constructor calls would succeed. When the | ||
24 | lifetime of the object ends, SetObjectRaw() is invoked. This triggered | ||
25 | an allocation with 4-byte alignment to which the previously 8-byte | ||
26 | aligned GenericValue array was copied. After this, any call to a | ||
27 | GenericValue API that triggered the constructor and thus the placement | ||
28 | new operation on the Data type member would trigger a SIGBUS. | ||
29 | |||
30 | Signed-off-by: Veselin Georgiev <veselin.georgiev@garmin.com> | ||
31 | Signed-off-by: Joshua Watt <Joshua.Watt@garmin.com> | ||
32 | Upstream-Status: Accepted 748a652f04cd3a202ce3639770238bd9473b300c | ||
33 | --- | ||
34 | include/rapidjson/rapidjson.h | 9 ++------- | ||
35 | test/unittest/allocatorstest.cpp | 26 ++++++++++++-------------- | ||
36 | 2 files changed, 14 insertions(+), 21 deletions(-) | ||
37 | |||
38 | diff --git a/include/rapidjson/rapidjson.h b/include/rapidjson/rapidjson.h | ||
39 | index a256c86e7..8cff38c2d 100644 | ||
40 | --- a/include/rapidjson/rapidjson.h | ||
41 | +++ b/include/rapidjson/rapidjson.h | ||
42 | @@ -269,16 +269,11 @@ | ||
43 | /*! \ingroup RAPIDJSON_CONFIG | ||
44 | \param x pointer to align | ||
45 | |||
46 | - Some machines require strict data alignment. Currently the default uses 4 bytes | ||
47 | - alignment on 32-bit platforms and 8 bytes alignment for 64-bit platforms. | ||
48 | + Some machines require strict data alignment. The default is 8 bytes. | ||
49 | User can customize by defining the RAPIDJSON_ALIGN function macro. | ||
50 | */ | ||
51 | #ifndef RAPIDJSON_ALIGN | ||
52 | -#if RAPIDJSON_64BIT == 1 | ||
53 | -#define RAPIDJSON_ALIGN(x) (((x) + static_cast<uint64_t>(7u)) & ~static_cast<uint64_t>(7u)) | ||
54 | -#else | ||
55 | -#define RAPIDJSON_ALIGN(x) (((x) + 3u) & ~3u) | ||
56 | -#endif | ||
57 | +#define RAPIDJSON_ALIGN(x) (((x) + static_cast<size_t>(7u)) & ~static_cast<size_t>(7u)) | ||
58 | #endif | ||
59 | |||
60 | /////////////////////////////////////////////////////////////////////////////// | ||
61 | diff --git a/test/unittest/allocatorstest.cpp b/test/unittest/allocatorstest.cpp | ||
62 | index a5958de19..2202c11f6 100644 | ||
63 | --- a/test/unittest/allocatorstest.cpp | ||
64 | +++ b/test/unittest/allocatorstest.cpp | ||
65 | @@ -63,23 +63,21 @@ TEST(Allocator, MemoryPoolAllocator) { | ||
66 | } | ||
67 | |||
68 | TEST(Allocator, Alignment) { | ||
69 | -#if RAPIDJSON_64BIT == 1 | ||
70 | - EXPECT_EQ(RAPIDJSON_UINT64_C2(0x00000000, 0x00000000), RAPIDJSON_ALIGN(0)); | ||
71 | - for (uint64_t i = 1; i < 8; i++) { | ||
72 | - EXPECT_EQ(RAPIDJSON_UINT64_C2(0x00000000, 0x00000008), RAPIDJSON_ALIGN(i)); | ||
73 | - EXPECT_EQ(RAPIDJSON_UINT64_C2(0x00000000, 0x00000010), RAPIDJSON_ALIGN(RAPIDJSON_UINT64_C2(0x00000000, 0x00000008) + i)); | ||
74 | - EXPECT_EQ(RAPIDJSON_UINT64_C2(0x00000001, 0x00000000), RAPIDJSON_ALIGN(RAPIDJSON_UINT64_C2(0x00000000, 0xFFFFFFF8) + i)); | ||
75 | - EXPECT_EQ(RAPIDJSON_UINT64_C2(0xFFFFFFFF, 0xFFFFFFF8), RAPIDJSON_ALIGN(RAPIDJSON_UINT64_C2(0xFFFFFFFF, 0xFFFFFFF0) + i)); | ||
76 | + if (sizeof(size_t) >= 8) { | ||
77 | + EXPECT_EQ(RAPIDJSON_UINT64_C2(0x00000000, 0x00000000), RAPIDJSON_ALIGN(0)); | ||
78 | + for (uint64_t i = 1; i < 8; i++) { | ||
79 | + EXPECT_EQ(RAPIDJSON_UINT64_C2(0x00000000, 0x00000008), RAPIDJSON_ALIGN(i)); | ||
80 | + EXPECT_EQ(RAPIDJSON_UINT64_C2(0x00000000, 0x00000010), RAPIDJSON_ALIGN(RAPIDJSON_UINT64_C2(0x00000000, 0x00000008) + i)); | ||
81 | + EXPECT_EQ(RAPIDJSON_UINT64_C2(0x00000001, 0x00000000), RAPIDJSON_ALIGN(RAPIDJSON_UINT64_C2(0x00000000, 0xFFFFFFF8) + i)); | ||
82 | + EXPECT_EQ(RAPIDJSON_UINT64_C2(0xFFFFFFFF, 0xFFFFFFF8), RAPIDJSON_ALIGN(RAPIDJSON_UINT64_C2(0xFFFFFFFF, 0xFFFFFFF0) + i)); | ||
83 | + } | ||
84 | } | ||
85 | -#else | ||
86 | + | ||
87 | EXPECT_EQ(0u, RAPIDJSON_ALIGN(0u)); | ||
88 | - for (uint32_t i = 1; i < 4; i++) { | ||
89 | - EXPECT_EQ(4u, RAPIDJSON_ALIGN(i)); | ||
90 | - EXPECT_EQ(8u, RAPIDJSON_ALIGN(4u + i)); | ||
91 | - EXPECT_EQ(0xFFFFFFF8u, RAPIDJSON_ALIGN(0xFFFFFFF4u + i)); | ||
92 | - EXPECT_EQ(0xFFFFFFFCu, RAPIDJSON_ALIGN(0xFFFFFFF8u + i)); | ||
93 | + for (uint32_t i = 1; i < 8; i++) { | ||
94 | + EXPECT_EQ(8u, RAPIDJSON_ALIGN(i)); | ||
95 | + EXPECT_EQ(0xFFFFFFF8u, RAPIDJSON_ALIGN(0xFFFFFFF0u + i)); | ||
96 | } | ||
97 | -#endif | ||
98 | } | ||
99 | |||
100 | TEST(Allocator, Issue399) { | ||
diff --git a/meta-oe/recipes-devtools/rapidjson/rapidjson_git.bb b/meta-oe/recipes-devtools/rapidjson/rapidjson_git.bb index 8ab35d224..6fcdf8d84 100644 --- a/meta-oe/recipes-devtools/rapidjson/rapidjson_git.bb +++ b/meta-oe/recipes-devtools/rapidjson/rapidjson_git.bb | |||
@@ -6,6 +6,7 @@ LIC_FILES_CHKSUM = "file://license.txt;md5=ba04aa8f65de1396a7e59d1d746c2125" | |||
6 | 6 | ||
7 | SRC_URI = "git://github.com/miloyip/rapidjson.git;nobranch=1 \ | 7 | SRC_URI = "git://github.com/miloyip/rapidjson.git;nobranch=1 \ |
8 | file://remove-march-native-from-CMAKE_CXX_FLAGS.patch \ | 8 | file://remove-march-native-from-CMAKE_CXX_FLAGS.patch \ |
9 | file://0001-Fix-SIGBUS-due-to-unaligned-access.patch \ | ||
9 | " | 10 | " |
10 | 11 | ||
11 | SRCREV = "e5635fb27feab7f6e8d7b916aa20ad799045a641" | 12 | SRCREV = "e5635fb27feab7f6e8d7b916aa20ad799045a641" |