1 /* 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 <unwindstack/Log.h> 25 26 #include "ArmExidx.h" 27 28 #include "LogFake.h" 29 #include "MemoryFake.h" 30 31 namespace unwindstack { 32 33 class ArmExidxExtractTest : public ::testing::Test { 34 protected: 35 void SetUp() override { 36 ResetLogs(); 37 elf_memory_.Clear(); 38 exidx_ = new ArmExidx(nullptr, &elf_memory_, nullptr); 39 data_ = exidx_->data(); 40 data_->clear(); 41 } 42 43 void TearDown() override { 44 delete exidx_; 45 } 46 47 ArmExidx* exidx_ = nullptr; 48 std::deque<uint8_t>* data_; 49 MemoryFake elf_memory_; 50 }; 51 52 TEST_F(ArmExidxExtractTest, bad_alignment) { 53 ASSERT_FALSE(exidx_->ExtractEntryData(0x1001)); 54 ASSERT_EQ(ARM_STATUS_INVALID_ALIGNMENT, exidx_->status()); 55 ASSERT_TRUE(data_->empty()); 56 } 57 58 TEST_F(ArmExidxExtractTest, cant_unwind) { 59 elf_memory_.SetData32(0x1000, 0x7fff2340); 60 elf_memory_.SetData32(0x1004, 1); 61 ASSERT_FALSE(exidx_->ExtractEntryData(0x1000)); 62 ASSERT_EQ(ARM_STATUS_NO_UNWIND, exidx_->status()); 63 ASSERT_TRUE(data_->empty()); 64 } 65 66 TEST_F(ArmExidxExtractTest, compact) { 67 elf_memory_.SetData32(0x4000, 0x7ffa3000); 68 elf_memory_.SetData32(0x4004, 0x80a8b0b0); 69 ASSERT_TRUE(exidx_->ExtractEntryData(0x4000)); 70 ASSERT_EQ(3U, data_->size()); 71 ASSERT_EQ(0xa8, data_->at(0)); 72 ASSERT_EQ(0xb0, data_->at(1)); 73 ASSERT_EQ(0xb0, data_->at(2)); 74 75 // Missing finish gets added. 76 elf_memory_.Clear(); 77 elf_memory_.SetData32(0x534, 0x7ffa3000); 78 elf_memory_.SetData32(0x538, 0x80a1a2a3); 79 ASSERT_TRUE(exidx_->ExtractEntryData(0x534)); 80 ASSERT_EQ(4U, data_->size()); 81 ASSERT_EQ(0xa1, data_->at(0)); 82 ASSERT_EQ(0xa2, data_->at(1)); 83 ASSERT_EQ(0xa3, data_->at(2)); 84 ASSERT_EQ(0xb0, data_->at(3)); 85 } 86 87 TEST_F(ArmExidxExtractTest, compact_non_zero_personality) { 88 elf_memory_.SetData32(0x4000, 0x7ffa3000); 89 90 uint32_t compact_value = 0x80a8b0b0; 91 for (size_t i = 1; i < 16; i++) { 92 elf_memory_.SetData32(0x4004, compact_value | (i << 24)); 93 ASSERT_FALSE(exidx_->ExtractEntryData(0x4000)); 94 ASSERT_EQ(ARM_STATUS_INVALID_PERSONALITY, exidx_->status()); 95 } 96 } 97 98 TEST_F(ArmExidxExtractTest, second_read_compact_personality_1_2) { 99 elf_memory_.SetData32(0x5000, 0x1234); 100 elf_memory_.SetData32(0x5004, 0x00001230); 101 elf_memory_.SetData32(0x6234, 0x8100f3b0); 102 ASSERT_TRUE(exidx_->ExtractEntryData(0x5000)); 103 ASSERT_EQ(2U, data_->size()); 104 ASSERT_EQ(0xf3, data_->at(0)); 105 ASSERT_EQ(0xb0, data_->at(1)); 106 107 elf_memory_.Clear(); 108 elf_memory_.SetData32(0x5000, 0x1234); 109 elf_memory_.SetData32(0x5004, 0x00001230); 110 elf_memory_.SetData32(0x6234, 0x8200f3f4); 111 ASSERT_TRUE(exidx_->ExtractEntryData(0x5000)); 112 ASSERT_EQ(3U, data_->size()); 113 ASSERT_EQ(0xf3, data_->at(0)); 114 ASSERT_EQ(0xf4, data_->at(1)); 115 ASSERT_EQ(0xb0, data_->at(2)); 116 117 elf_memory_.Clear(); 118 elf_memory_.SetData32(0x5000, 0x1234); 119 elf_memory_.SetData32(0x5004, 0x00001230); 120 elf_memory_.SetData32(0x6234, 0x8201f3f4); 121 elf_memory_.SetData32(0x6238, 0x102030b0); 122 ASSERT_TRUE(exidx_->ExtractEntryData(0x5000)); 123 ASSERT_EQ(6U, data_->size()); 124 ASSERT_EQ(0xf3, data_->at(0)); 125 ASSERT_EQ(0xf4, data_->at(1)); 126 ASSERT_EQ(0x10, data_->at(2)); 127 ASSERT_EQ(0x20, data_->at(3)); 128 ASSERT_EQ(0x30, data_->at(4)); 129 ASSERT_EQ(0xb0, data_->at(5)); 130 131 elf_memory_.Clear(); 132 elf_memory_.SetData32(0x5000, 0x1234); 133 elf_memory_.SetData32(0x5004, 0x00001230); 134 elf_memory_.SetData32(0x6234, 0x8103f3f4); 135 elf_memory_.SetData32(0x6238, 0x10203040); 136 elf_memory_.SetData32(0x623c, 0x50607080); 137 elf_memory_.SetData32(0x6240, 0x90a0c0d0); 138 ASSERT_TRUE(exidx_->ExtractEntryData(0x5000)); 139 ASSERT_EQ(15U, data_->size()); 140 ASSERT_EQ(0xf3, data_->at(0)); 141 ASSERT_EQ(0xf4, data_->at(1)); 142 ASSERT_EQ(0x10, data_->at(2)); 143 ASSERT_EQ(0x20, data_->at(3)); 144 ASSERT_EQ(0x30, data_->at(4)); 145 ASSERT_EQ(0x40, data_->at(5)); 146 ASSERT_EQ(0x50, data_->at(6)); 147 ASSERT_EQ(0x60, data_->at(7)); 148 ASSERT_EQ(0x70, data_->at(8)); 149 ASSERT_EQ(0x80, data_->at(9)); 150 ASSERT_EQ(0x90, data_->at(10)); 151 ASSERT_EQ(0xa0, data_->at(11)); 152 ASSERT_EQ(0xc0, data_->at(12)); 153 ASSERT_EQ(0xd0, data_->at(13)); 154 ASSERT_EQ(0xb0, data_->at(14)); 155 } 156 157 TEST_F(ArmExidxExtractTest, second_read_compact_personality_illegal) { 158 elf_memory_.SetData32(0x5000, 0x7ffa1e48); 159 elf_memory_.SetData32(0x5004, 0x1230); 160 elf_memory_.SetData32(0x6234, 0x832132b0); 161 ASSERT_FALSE(exidx_->ExtractEntryData(0x5000)); 162 ASSERT_EQ(ARM_STATUS_INVALID_PERSONALITY, exidx_->status()); 163 164 elf_memory_.Clear(); 165 elf_memory_.SetData32(0x5000, 0x7ffa1e48); 166 elf_memory_.SetData32(0x5004, 0x1230); 167 elf_memory_.SetData32(0x6234, 0x842132b0); 168 ASSERT_FALSE(exidx_->ExtractEntryData(0x5000)); 169 ASSERT_EQ(ARM_STATUS_INVALID_PERSONALITY, exidx_->status()); 170 } 171 172 TEST_F(ArmExidxExtractTest, second_read_offset_is_negative) { 173 elf_memory_.SetData32(0x5000, 0x7ffa1e48); 174 elf_memory_.SetData32(0x5004, 0x7fffb1e0); 175 elf_memory_.SetData32(0x1e4, 0x842132b0); 176 ASSERT_FALSE(exidx_->ExtractEntryData(0x5000)); 177 ASSERT_EQ(ARM_STATUS_INVALID_PERSONALITY, exidx_->status()); 178 } 179 180 TEST_F(ArmExidxExtractTest, second_read_not_compact) { 181 elf_memory_.SetData32(0x5000, 0x1234); 182 elf_memory_.SetData32(0x5004, 0x00001230); 183 elf_memory_.SetData32(0x6234, 0x1); 184 elf_memory_.SetData32(0x6238, 0x001122b0); 185 ASSERT_TRUE(exidx_->ExtractEntryData(0x5000)); 186 ASSERT_EQ(3U, data_->size()); 187 ASSERT_EQ(0x11, data_->at(0)); 188 ASSERT_EQ(0x22, data_->at(1)); 189 ASSERT_EQ(0xb0, data_->at(2)); 190 191 elf_memory_.Clear(); 192 elf_memory_.SetData32(0x5000, 0x1234); 193 elf_memory_.SetData32(0x5004, 0x00001230); 194 elf_memory_.SetData32(0x6234, 0x2); 195 elf_memory_.SetData32(0x6238, 0x00112233); 196 ASSERT_TRUE(exidx_->ExtractEntryData(0x5000)); 197 ASSERT_EQ(4U, data_->size()); 198 ASSERT_EQ(0x11, data_->at(0)); 199 ASSERT_EQ(0x22, data_->at(1)); 200 ASSERT_EQ(0x33, data_->at(2)); 201 ASSERT_EQ(0xb0, data_->at(3)); 202 203 elf_memory_.Clear(); 204 elf_memory_.SetData32(0x5000, 0x1234); 205 elf_memory_.SetData32(0x5004, 0x00001230); 206 elf_memory_.SetData32(0x6234, 0x3); 207 elf_memory_.SetData32(0x6238, 0x01112233); 208 elf_memory_.SetData32(0x623c, 0x445566b0); 209 ASSERT_TRUE(exidx_->ExtractEntryData(0x5000)); 210 ASSERT_EQ(7U, data_->size()); 211 ASSERT_EQ(0x11, data_->at(0)); 212 ASSERT_EQ(0x22, data_->at(1)); 213 ASSERT_EQ(0x33, data_->at(2)); 214 ASSERT_EQ(0x44, data_->at(3)); 215 ASSERT_EQ(0x55, data_->at(4)); 216 ASSERT_EQ(0x66, data_->at(5)); 217 ASSERT_EQ(0xb0, data_->at(6)); 218 219 elf_memory_.Clear(); 220 elf_memory_.SetData32(0x5000, 0x1234); 221 elf_memory_.SetData32(0x5004, 0x00001230); 222 elf_memory_.SetData32(0x6234, 0x3); 223 elf_memory_.SetData32(0x6238, 0x05112233); 224 elf_memory_.SetData32(0x623c, 0x01020304); 225 elf_memory_.SetData32(0x6240, 0x05060708); 226 elf_memory_.SetData32(0x6244, 0x090a0b0c); 227 elf_memory_.SetData32(0x6248, 0x0d0e0f10); 228 elf_memory_.SetData32(0x624c, 0x11121314); 229 ASSERT_TRUE(exidx_->ExtractEntryData(0x5000)); 230 ASSERT_EQ(24U, data_->size()); 231 ASSERT_EQ(0x11, data_->at(0)); 232 ASSERT_EQ(0x22, data_->at(1)); 233 ASSERT_EQ(0x33, data_->at(2)); 234 ASSERT_EQ(0x01, data_->at(3)); 235 ASSERT_EQ(0x02, data_->at(4)); 236 ASSERT_EQ(0x03, data_->at(5)); 237 ASSERT_EQ(0x04, data_->at(6)); 238 ASSERT_EQ(0x05, data_->at(7)); 239 ASSERT_EQ(0x06, data_->at(8)); 240 ASSERT_EQ(0x07, data_->at(9)); 241 ASSERT_EQ(0x08, data_->at(10)); 242 ASSERT_EQ(0x09, data_->at(11)); 243 ASSERT_EQ(0x0a, data_->at(12)); 244 ASSERT_EQ(0x0b, data_->at(13)); 245 ASSERT_EQ(0x0c, data_->at(14)); 246 ASSERT_EQ(0x0d, data_->at(15)); 247 ASSERT_EQ(0x0e, data_->at(16)); 248 ASSERT_EQ(0x0f, data_->at(17)); 249 ASSERT_EQ(0x10, data_->at(18)); 250 ASSERT_EQ(0x11, data_->at(19)); 251 ASSERT_EQ(0x12, data_->at(20)); 252 ASSERT_EQ(0x13, data_->at(21)); 253 ASSERT_EQ(0x14, data_->at(22)); 254 ASSERT_EQ(0xb0, data_->at(23)); 255 } 256 257 TEST_F(ArmExidxExtractTest, read_failures) { 258 ASSERT_FALSE(exidx_->ExtractEntryData(0x5000)); 259 ASSERT_EQ(ARM_STATUS_READ_FAILED, exidx_->status()); 260 EXPECT_EQ(0x5004U, exidx_->status_address()); 261 262 elf_memory_.SetData32(0x5000, 0x100); 263 ASSERT_FALSE(exidx_->ExtractEntryData(0x5000)); 264 ASSERT_EQ(ARM_STATUS_READ_FAILED, exidx_->status()); 265 EXPECT_EQ(0x5004U, exidx_->status_address()); 266 267 elf_memory_.SetData32(0x5004, 0x100); 268 ASSERT_FALSE(exidx_->ExtractEntryData(0x5000)); 269 ASSERT_EQ(ARM_STATUS_READ_FAILED, exidx_->status()); 270 EXPECT_EQ(0x5104U, exidx_->status_address()); 271 272 elf_memory_.SetData32(0x5104, 0x1); 273 ASSERT_FALSE(exidx_->ExtractEntryData(0x5000)); 274 ASSERT_EQ(ARM_STATUS_READ_FAILED, exidx_->status()); 275 EXPECT_EQ(0x5108U, exidx_->status_address()); 276 277 elf_memory_.SetData32(0x5108, 0x01010203); 278 ASSERT_FALSE(exidx_->ExtractEntryData(0x5000)); 279 ASSERT_EQ(ARM_STATUS_READ_FAILED, exidx_->status()); 280 EXPECT_EQ(0x510cU, exidx_->status_address()); 281 } 282 283 TEST_F(ArmExidxExtractTest, malformed) { 284 elf_memory_.SetData32(0x5000, 0x100); 285 elf_memory_.SetData32(0x5004, 0x100); 286 elf_memory_.SetData32(0x5104, 0x1); 287 elf_memory_.SetData32(0x5108, 0x06010203); 288 ASSERT_FALSE(exidx_->ExtractEntryData(0x5000)); 289 ASSERT_EQ(ARM_STATUS_MALFORMED, exidx_->status()); 290 291 elf_memory_.Clear(); 292 elf_memory_.SetData32(0x5000, 0x100); 293 elf_memory_.SetData32(0x5004, 0x100); 294 elf_memory_.SetData32(0x5104, 0x1); 295 elf_memory_.SetData32(0x5108, 0x81060203); 296 ASSERT_FALSE(exidx_->ExtractEntryData(0x5000)); 297 ASSERT_EQ(ARM_STATUS_MALFORMED, exidx_->status()); 298 } 299 300 TEST_F(ArmExidxExtractTest, cant_unwind_log) { 301 elf_memory_.SetData32(0x1000, 0x7fff2340); 302 elf_memory_.SetData32(0x1004, 1); 303 304 exidx_->set_log(true); 305 exidx_->set_log_indent(0); 306 exidx_->set_log_skip_execution(false); 307 308 ASSERT_FALSE(exidx_->ExtractEntryData(0x1000)); 309 ASSERT_EQ(ARM_STATUS_NO_UNWIND, exidx_->status()); 310 311 ASSERT_EQ("4 unwind Raw Data: 0x00 0x00 0x00 0x01\n" 312 "4 unwind [cantunwind]\n", GetFakeLogPrint()); 313 } 314 315 TEST_F(ArmExidxExtractTest, raw_data_compact) { 316 elf_memory_.SetData32(0x4000, 0x7ffa3000); 317 elf_memory_.SetData32(0x4004, 0x80a8b0b0); 318 319 exidx_->set_log(true); 320 exidx_->set_log_indent(0); 321 exidx_->set_log_skip_execution(false); 322 323 ASSERT_TRUE(exidx_->ExtractEntryData(0x4000)); 324 ASSERT_EQ("4 unwind Raw Data: 0xa8 0xb0 0xb0\n", GetFakeLogPrint()); 325 } 326 327 TEST_F(ArmExidxExtractTest, raw_data_non_compact) { 328 elf_memory_.SetData32(0x5000, 0x1234); 329 elf_memory_.SetData32(0x5004, 0x00001230); 330 elf_memory_.SetData32(0x6234, 0x2); 331 elf_memory_.SetData32(0x6238, 0x00112233); 332 333 exidx_->set_log(true); 334 exidx_->set_log_indent(0); 335 exidx_->set_log_skip_execution(false); 336 337 ASSERT_TRUE(exidx_->ExtractEntryData(0x5000)); 338 ASSERT_EQ("4 unwind Raw Data: 0x11 0x22 0x33 0xb0\n", GetFakeLogPrint()); 339 } 340 341 } // namespace unwindstack 342