blob: aed75bf9da2ed84b82ce1eca3f0901bcc86c2d31 [file] [log] [blame]
Christopher Ferris723cf9b2017-01-19 20:08:48 -08001/*
2 * Copyright (C) 2016 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17#include <stdint.h>
18
19#include <deque>
20#include <vector>
21
22#include <gtest/gtest.h>
23
24#include "ArmExidx.h"
25#include "Log.h"
26
27#include "LogFake.h"
28#include "MemoryFake.h"
29
30class ArmExidxExtractTest : public ::testing::Test {
31 protected:
32 void SetUp() override {
33 ResetLogs();
34 elf_memory_.Clear();
35 exidx_ = new ArmExidx(nullptr, &elf_memory_, nullptr);
36 data_ = exidx_->data();
37 data_->clear();
38 }
39
40 void TearDown() override {
41 delete exidx_;
42 }
43
44 ArmExidx* exidx_ = nullptr;
45 std::deque<uint8_t>* data_;
46 MemoryFake elf_memory_;
47};
48
49TEST_F(ArmExidxExtractTest, bad_alignment) {
50 ASSERT_FALSE(exidx_->ExtractEntryData(0x1001));
51 ASSERT_EQ(ARM_STATUS_INVALID_ALIGNMENT, exidx_->status());
52 ASSERT_TRUE(data_->empty());
53}
54
55TEST_F(ArmExidxExtractTest, cant_unwind) {
Christopher Ferris3958f802017-02-01 15:44:40 -080056 elf_memory_.SetData32(0x1000, 0x7fff2340);
57 elf_memory_.SetData32(0x1004, 1);
Christopher Ferris723cf9b2017-01-19 20:08:48 -080058 ASSERT_FALSE(exidx_->ExtractEntryData(0x1000));
59 ASSERT_EQ(ARM_STATUS_NO_UNWIND, exidx_->status());
60 ASSERT_TRUE(data_->empty());
61}
62
63TEST_F(ArmExidxExtractTest, compact) {
Christopher Ferris3958f802017-02-01 15:44:40 -080064 elf_memory_.SetData32(0x4000, 0x7ffa3000);
65 elf_memory_.SetData32(0x4004, 0x80a8b0b0);
Christopher Ferris723cf9b2017-01-19 20:08:48 -080066 ASSERT_TRUE(exidx_->ExtractEntryData(0x4000));
67 ASSERT_EQ(3U, data_->size());
68 ASSERT_EQ(0xa8, data_->at(0));
69 ASSERT_EQ(0xb0, data_->at(1));
70 ASSERT_EQ(0xb0, data_->at(2));
71
72 // Missing finish gets added.
73 elf_memory_.Clear();
Christopher Ferris3958f802017-02-01 15:44:40 -080074 elf_memory_.SetData32(0x534, 0x7ffa3000);
75 elf_memory_.SetData32(0x538, 0x80a1a2a3);
Christopher Ferris723cf9b2017-01-19 20:08:48 -080076 ASSERT_TRUE(exidx_->ExtractEntryData(0x534));
77 ASSERT_EQ(4U, data_->size());
78 ASSERT_EQ(0xa1, data_->at(0));
79 ASSERT_EQ(0xa2, data_->at(1));
80 ASSERT_EQ(0xa3, data_->at(2));
81 ASSERT_EQ(0xb0, data_->at(3));
82}
83
84TEST_F(ArmExidxExtractTest, compact_non_zero_personality) {
Christopher Ferris3958f802017-02-01 15:44:40 -080085 elf_memory_.SetData32(0x4000, 0x7ffa3000);
Christopher Ferris723cf9b2017-01-19 20:08:48 -080086
87 uint32_t compact_value = 0x80a8b0b0;
88 for (size_t i = 1; i < 16; i++) {
Christopher Ferris3958f802017-02-01 15:44:40 -080089 elf_memory_.SetData32(0x4004, compact_value | (i << 24));
Christopher Ferris723cf9b2017-01-19 20:08:48 -080090 ASSERT_FALSE(exidx_->ExtractEntryData(0x4000));
91 ASSERT_EQ(ARM_STATUS_INVALID_PERSONALITY, exidx_->status());
92 }
93}
94
95TEST_F(ArmExidxExtractTest, second_read_compact_personality_1_2) {
Christopher Ferris3958f802017-02-01 15:44:40 -080096 elf_memory_.SetData32(0x5000, 0x1234);
97 elf_memory_.SetData32(0x5004, 0x00001230);
98 elf_memory_.SetData32(0x6234, 0x8100f3b0);
Christopher Ferris723cf9b2017-01-19 20:08:48 -080099 ASSERT_TRUE(exidx_->ExtractEntryData(0x5000));
100 ASSERT_EQ(2U, data_->size());
101 ASSERT_EQ(0xf3, data_->at(0));
102 ASSERT_EQ(0xb0, data_->at(1));
103
104 elf_memory_.Clear();
Christopher Ferris3958f802017-02-01 15:44:40 -0800105 elf_memory_.SetData32(0x5000, 0x1234);
106 elf_memory_.SetData32(0x5004, 0x00001230);
107 elf_memory_.SetData32(0x6234, 0x8200f3f4);
Christopher Ferris723cf9b2017-01-19 20:08:48 -0800108 ASSERT_TRUE(exidx_->ExtractEntryData(0x5000));
109 ASSERT_EQ(3U, data_->size());
110 ASSERT_EQ(0xf3, data_->at(0));
111 ASSERT_EQ(0xf4, data_->at(1));
112 ASSERT_EQ(0xb0, data_->at(2));
113
114 elf_memory_.Clear();
Christopher Ferris3958f802017-02-01 15:44:40 -0800115 elf_memory_.SetData32(0x5000, 0x1234);
116 elf_memory_.SetData32(0x5004, 0x00001230);
117 elf_memory_.SetData32(0x6234, 0x8201f3f4);
118 elf_memory_.SetData32(0x6238, 0x102030b0);
Christopher Ferris723cf9b2017-01-19 20:08:48 -0800119 ASSERT_TRUE(exidx_->ExtractEntryData(0x5000));
120 ASSERT_EQ(6U, data_->size());
121 ASSERT_EQ(0xf3, data_->at(0));
122 ASSERT_EQ(0xf4, data_->at(1));
123 ASSERT_EQ(0x10, data_->at(2));
124 ASSERT_EQ(0x20, data_->at(3));
125 ASSERT_EQ(0x30, data_->at(4));
126 ASSERT_EQ(0xb0, data_->at(5));
127
128 elf_memory_.Clear();
Christopher Ferris3958f802017-02-01 15:44:40 -0800129 elf_memory_.SetData32(0x5000, 0x1234);
130 elf_memory_.SetData32(0x5004, 0x00001230);
131 elf_memory_.SetData32(0x6234, 0x8103f3f4);
132 elf_memory_.SetData32(0x6238, 0x10203040);
133 elf_memory_.SetData32(0x623c, 0x50607080);
134 elf_memory_.SetData32(0x6240, 0x90a0c0d0);
Christopher Ferris723cf9b2017-01-19 20:08:48 -0800135 ASSERT_TRUE(exidx_->ExtractEntryData(0x5000));
136 ASSERT_EQ(15U, data_->size());
137 ASSERT_EQ(0xf3, data_->at(0));
138 ASSERT_EQ(0xf4, data_->at(1));
139 ASSERT_EQ(0x10, data_->at(2));
140 ASSERT_EQ(0x20, data_->at(3));
141 ASSERT_EQ(0x30, data_->at(4));
142 ASSERT_EQ(0x40, data_->at(5));
143 ASSERT_EQ(0x50, data_->at(6));
144 ASSERT_EQ(0x60, data_->at(7));
145 ASSERT_EQ(0x70, data_->at(8));
146 ASSERT_EQ(0x80, data_->at(9));
147 ASSERT_EQ(0x90, data_->at(10));
148 ASSERT_EQ(0xa0, data_->at(11));
149 ASSERT_EQ(0xc0, data_->at(12));
150 ASSERT_EQ(0xd0, data_->at(13));
151 ASSERT_EQ(0xb0, data_->at(14));
152}
153
154TEST_F(ArmExidxExtractTest, second_read_compact_personality_illegal) {
Christopher Ferris3958f802017-02-01 15:44:40 -0800155 elf_memory_.SetData32(0x5000, 0x7ffa1e48);
156 elf_memory_.SetData32(0x5004, 0x1230);
157 elf_memory_.SetData32(0x6234, 0x832132b0);
Christopher Ferris723cf9b2017-01-19 20:08:48 -0800158 ASSERT_FALSE(exidx_->ExtractEntryData(0x5000));
159 ASSERT_EQ(ARM_STATUS_INVALID_PERSONALITY, exidx_->status());
160
161 elf_memory_.Clear();
Christopher Ferris3958f802017-02-01 15:44:40 -0800162 elf_memory_.SetData32(0x5000, 0x7ffa1e48);
163 elf_memory_.SetData32(0x5004, 0x1230);
164 elf_memory_.SetData32(0x6234, 0x842132b0);
Christopher Ferris723cf9b2017-01-19 20:08:48 -0800165 ASSERT_FALSE(exidx_->ExtractEntryData(0x5000));
166 ASSERT_EQ(ARM_STATUS_INVALID_PERSONALITY, exidx_->status());
167}
168
169TEST_F(ArmExidxExtractTest, second_read_offset_is_negative) {
Christopher Ferris3958f802017-02-01 15:44:40 -0800170 elf_memory_.SetData32(0x5000, 0x7ffa1e48);
171 elf_memory_.SetData32(0x5004, 0x7fffb1e0);
172 elf_memory_.SetData32(0x1e4, 0x842132b0);
Christopher Ferris723cf9b2017-01-19 20:08:48 -0800173 ASSERT_FALSE(exidx_->ExtractEntryData(0x5000));
174 ASSERT_EQ(ARM_STATUS_INVALID_PERSONALITY, exidx_->status());
175}
176
177TEST_F(ArmExidxExtractTest, second_read_not_compact) {
Christopher Ferris3958f802017-02-01 15:44:40 -0800178 elf_memory_.SetData32(0x5000, 0x1234);
179 elf_memory_.SetData32(0x5004, 0x00001230);
180 elf_memory_.SetData32(0x6234, 0x1);
181 elf_memory_.SetData32(0x6238, 0x001122b0);
Christopher Ferris723cf9b2017-01-19 20:08:48 -0800182 ASSERT_TRUE(exidx_->ExtractEntryData(0x5000));
183 ASSERT_EQ(3U, data_->size());
184 ASSERT_EQ(0x11, data_->at(0));
185 ASSERT_EQ(0x22, data_->at(1));
186 ASSERT_EQ(0xb0, data_->at(2));
187
188 elf_memory_.Clear();
Christopher Ferris3958f802017-02-01 15:44:40 -0800189 elf_memory_.SetData32(0x5000, 0x1234);
190 elf_memory_.SetData32(0x5004, 0x00001230);
191 elf_memory_.SetData32(0x6234, 0x2);
192 elf_memory_.SetData32(0x6238, 0x00112233);
Christopher Ferris723cf9b2017-01-19 20:08:48 -0800193 ASSERT_TRUE(exidx_->ExtractEntryData(0x5000));
194 ASSERT_EQ(4U, data_->size());
195 ASSERT_EQ(0x11, data_->at(0));
196 ASSERT_EQ(0x22, data_->at(1));
197 ASSERT_EQ(0x33, data_->at(2));
198 ASSERT_EQ(0xb0, data_->at(3));
199
200 elf_memory_.Clear();
Christopher Ferris3958f802017-02-01 15:44:40 -0800201 elf_memory_.SetData32(0x5000, 0x1234);
202 elf_memory_.SetData32(0x5004, 0x00001230);
203 elf_memory_.SetData32(0x6234, 0x3);
204 elf_memory_.SetData32(0x6238, 0x01112233);
205 elf_memory_.SetData32(0x623c, 0x445566b0);
Christopher Ferris723cf9b2017-01-19 20:08:48 -0800206 ASSERT_TRUE(exidx_->ExtractEntryData(0x5000));
207 ASSERT_EQ(7U, data_->size());
208 ASSERT_EQ(0x11, data_->at(0));
209 ASSERT_EQ(0x22, data_->at(1));
210 ASSERT_EQ(0x33, data_->at(2));
211 ASSERT_EQ(0x44, data_->at(3));
212 ASSERT_EQ(0x55, data_->at(4));
213 ASSERT_EQ(0x66, data_->at(5));
214 ASSERT_EQ(0xb0, data_->at(6));
215
216 elf_memory_.Clear();
Christopher Ferris3958f802017-02-01 15:44:40 -0800217 elf_memory_.SetData32(0x5000, 0x1234);
218 elf_memory_.SetData32(0x5004, 0x00001230);
219 elf_memory_.SetData32(0x6234, 0x3);
220 elf_memory_.SetData32(0x6238, 0x05112233);
221 elf_memory_.SetData32(0x623c, 0x01020304);
222 elf_memory_.SetData32(0x6240, 0x05060708);
223 elf_memory_.SetData32(0x6244, 0x090a0b0c);
224 elf_memory_.SetData32(0x6248, 0x0d0e0f10);
225 elf_memory_.SetData32(0x624c, 0x11121314);
Christopher Ferris723cf9b2017-01-19 20:08:48 -0800226 ASSERT_TRUE(exidx_->ExtractEntryData(0x5000));
227 ASSERT_EQ(24U, data_->size());
228 ASSERT_EQ(0x11, data_->at(0));
229 ASSERT_EQ(0x22, data_->at(1));
230 ASSERT_EQ(0x33, data_->at(2));
231 ASSERT_EQ(0x01, data_->at(3));
232 ASSERT_EQ(0x02, data_->at(4));
233 ASSERT_EQ(0x03, data_->at(5));
234 ASSERT_EQ(0x04, data_->at(6));
235 ASSERT_EQ(0x05, data_->at(7));
236 ASSERT_EQ(0x06, data_->at(8));
237 ASSERT_EQ(0x07, data_->at(9));
238 ASSERT_EQ(0x08, data_->at(10));
239 ASSERT_EQ(0x09, data_->at(11));
240 ASSERT_EQ(0x0a, data_->at(12));
241 ASSERT_EQ(0x0b, data_->at(13));
242 ASSERT_EQ(0x0c, data_->at(14));
243 ASSERT_EQ(0x0d, data_->at(15));
244 ASSERT_EQ(0x0e, data_->at(16));
245 ASSERT_EQ(0x0f, data_->at(17));
246 ASSERT_EQ(0x10, data_->at(18));
247 ASSERT_EQ(0x11, data_->at(19));
248 ASSERT_EQ(0x12, data_->at(20));
249 ASSERT_EQ(0x13, data_->at(21));
250 ASSERT_EQ(0x14, data_->at(22));
251 ASSERT_EQ(0xb0, data_->at(23));
252}
253
254TEST_F(ArmExidxExtractTest, read_failures) {
255 ASSERT_FALSE(exidx_->ExtractEntryData(0x5000));
256 ASSERT_EQ(ARM_STATUS_READ_FAILED, exidx_->status());
257
Christopher Ferris3958f802017-02-01 15:44:40 -0800258 elf_memory_.SetData32(0x5000, 0x100);
Christopher Ferris723cf9b2017-01-19 20:08:48 -0800259 ASSERT_FALSE(exidx_->ExtractEntryData(0x5000));
260 ASSERT_EQ(ARM_STATUS_READ_FAILED, exidx_->status());
261
Christopher Ferris3958f802017-02-01 15:44:40 -0800262 elf_memory_.SetData32(0x5004, 0x100);
Christopher Ferris723cf9b2017-01-19 20:08:48 -0800263 ASSERT_FALSE(exidx_->ExtractEntryData(0x5000));
264 ASSERT_EQ(ARM_STATUS_READ_FAILED, exidx_->status());
265
Christopher Ferris3958f802017-02-01 15:44:40 -0800266 elf_memory_.SetData32(0x5104, 0x1);
Christopher Ferris723cf9b2017-01-19 20:08:48 -0800267 ASSERT_FALSE(exidx_->ExtractEntryData(0x5000));
268 ASSERT_EQ(ARM_STATUS_READ_FAILED, exidx_->status());
269
Christopher Ferris3958f802017-02-01 15:44:40 -0800270 elf_memory_.SetData32(0x5108, 0x01010203);
Christopher Ferris723cf9b2017-01-19 20:08:48 -0800271 ASSERT_FALSE(exidx_->ExtractEntryData(0x5000));
272 ASSERT_EQ(ARM_STATUS_READ_FAILED, exidx_->status());
273}
274
275TEST_F(ArmExidxExtractTest, malformed) {
Christopher Ferris3958f802017-02-01 15:44:40 -0800276 elf_memory_.SetData32(0x5000, 0x100);
277 elf_memory_.SetData32(0x5004, 0x100);
278 elf_memory_.SetData32(0x5104, 0x1);
279 elf_memory_.SetData32(0x5108, 0x06010203);
Christopher Ferris723cf9b2017-01-19 20:08:48 -0800280 ASSERT_FALSE(exidx_->ExtractEntryData(0x5000));
281 ASSERT_EQ(ARM_STATUS_MALFORMED, exidx_->status());
282
283 elf_memory_.Clear();
Christopher Ferris3958f802017-02-01 15:44:40 -0800284 elf_memory_.SetData32(0x5000, 0x100);
285 elf_memory_.SetData32(0x5004, 0x100);
286 elf_memory_.SetData32(0x5104, 0x1);
287 elf_memory_.SetData32(0x5108, 0x81060203);
Christopher Ferris723cf9b2017-01-19 20:08:48 -0800288 ASSERT_FALSE(exidx_->ExtractEntryData(0x5000));
289 ASSERT_EQ(ARM_STATUS_MALFORMED, exidx_->status());
290}
291
292TEST_F(ArmExidxExtractTest, cant_unwind_log) {
Christopher Ferris3958f802017-02-01 15:44:40 -0800293 elf_memory_.SetData32(0x1000, 0x7fff2340);
294 elf_memory_.SetData32(0x1004, 1);
Christopher Ferris723cf9b2017-01-19 20:08:48 -0800295
296 exidx_->set_log(true);
297 exidx_->set_log_indent(0);
298 exidx_->set_log_skip_execution(false);
299
300 ASSERT_FALSE(exidx_->ExtractEntryData(0x1000));
301 ASSERT_EQ(ARM_STATUS_NO_UNWIND, exidx_->status());
302
303 ASSERT_EQ("4 unwind Raw Data: 0x00 0x00 0x00 0x01\n"
304 "4 unwind [cantunwind]\n", GetFakeLogPrint());
305}
306
307TEST_F(ArmExidxExtractTest, raw_data_compact) {
Christopher Ferris3958f802017-02-01 15:44:40 -0800308 elf_memory_.SetData32(0x4000, 0x7ffa3000);
309 elf_memory_.SetData32(0x4004, 0x80a8b0b0);
Christopher Ferris723cf9b2017-01-19 20:08:48 -0800310
311 exidx_->set_log(true);
312 exidx_->set_log_indent(0);
313 exidx_->set_log_skip_execution(false);
314
315 ASSERT_TRUE(exidx_->ExtractEntryData(0x4000));
316 ASSERT_EQ("4 unwind Raw Data: 0xa8 0xb0 0xb0\n", GetFakeLogPrint());
317}
318
319TEST_F(ArmExidxExtractTest, raw_data_non_compact) {
Christopher Ferris3958f802017-02-01 15:44:40 -0800320 elf_memory_.SetData32(0x5000, 0x1234);
321 elf_memory_.SetData32(0x5004, 0x00001230);
322 elf_memory_.SetData32(0x6234, 0x2);
323 elf_memory_.SetData32(0x6238, 0x00112233);
Christopher Ferris723cf9b2017-01-19 20:08:48 -0800324
325 exidx_->set_log(true);
326 exidx_->set_log_indent(0);
327 exidx_->set_log_skip_execution(false);
328
329 ASSERT_TRUE(exidx_->ExtractEntryData(0x5000));
330 ASSERT_EQ("4 unwind Raw Data: 0x11 0x22 0x33 0xb0\n", GetFakeLogPrint());
331}