| OLD | NEW |
| (Empty) |
| 1 // Copyright 2016 the V8 project authors. All rights reserved. | |
| 2 // Use of this source code is governed by a BSD-style license that can be | |
| 3 // found in the LICENSE file. | |
| 4 | |
| 5 #include "src/eh-frame.h" | |
| 6 #include "test/unittests/test-utils.h" | |
| 7 | |
| 8 // Test enabled only on supported architectures. | |
| 9 #if defined(V8_TARGET_ARCH_X64) || defined(V8_TARGET_ARCH_ARM) || \ | |
| 10 defined(V8_TARGET_ARCH_ARM64) | |
| 11 | |
| 12 using namespace v8::internal; | |
| 13 | |
| 14 namespace { | |
| 15 | |
| 16 class EhFrameWriterTest : public TestWithZone { | |
| 17 protected: | |
| 18 // Being a 7bit positive integer, this also serves as its ULEB128 encoding. | |
| 19 static const int kTestRegisterCode = 0; | |
| 20 | |
| 21 static EhFrameIterator MakeIterator(EhFrameWriter* writer) { | |
| 22 CodeDesc desc; | |
| 23 writer->GetEhFrame(&desc); | |
| 24 DCHECK_GT(desc.unwinding_info_size, 0); | |
| 25 return EhFrameIterator(desc.unwinding_info, | |
| 26 desc.unwinding_info + desc.unwinding_info_size); | |
| 27 } | |
| 28 }; | |
| 29 | |
| 30 STATIC_CONST_MEMBER_DEFINITION const int EhFrameWriterTest::kTestRegisterCode; | |
| 31 | |
| 32 } // namespace | |
| 33 | |
| 34 TEST_F(EhFrameWriterTest, Alignment) { | |
| 35 EhFrameWriter writer(zone()); | |
| 36 writer.Initialize(); | |
| 37 writer.AdvanceLocation(42 * EhFrameConstants::kCodeAlignmentFactor); | |
| 38 writer.Finish(100); | |
| 39 | |
| 40 EhFrameIterator iterator = MakeIterator(&writer); | |
| 41 ASSERT_EQ(0, EhFrameConstants::kEhFrameHdrSize % 4); | |
| 42 ASSERT_EQ(0, EhFrameConstants::kEhFrameTerminatorSize % 4); | |
| 43 EXPECT_EQ(0, (iterator.GetBufferSize() - EhFrameConstants::kEhFrameHdrSize - | |
| 44 EhFrameConstants::kEhFrameTerminatorSize) % | |
| 45 8); | |
| 46 } | |
| 47 | |
| 48 TEST_F(EhFrameWriterTest, FDEHeader) { | |
| 49 static const int kProcedureSize = 0x5678abcd; | |
| 50 | |
| 51 EhFrameWriter writer(zone()); | |
| 52 writer.Initialize(); | |
| 53 writer.Finish(kProcedureSize); | |
| 54 | |
| 55 EhFrameIterator iterator = MakeIterator(&writer); | |
| 56 int cie_size = iterator.GetNextUInt32(); | |
| 57 iterator.Skip(cie_size); | |
| 58 | |
| 59 int fde_size = iterator.GetNextUInt32(); | |
| 60 EXPECT_EQ(iterator.GetBufferSize(), | |
| 61 fde_size + cie_size + EhFrameConstants::kEhFrameTerminatorSize + | |
| 62 EhFrameConstants::kEhFrameHdrSize + 2 * kInt32Size); | |
| 63 | |
| 64 int backwards_offset_to_cie_offset = iterator.GetCurrentOffset(); | |
| 65 int backwards_offset_to_cie = iterator.GetNextUInt32(); | |
| 66 EXPECT_EQ(backwards_offset_to_cie_offset, backwards_offset_to_cie); | |
| 67 | |
| 68 int procedure_address_offset = iterator.GetCurrentOffset(); | |
| 69 int procedure_address = iterator.GetNextUInt32(); | |
| 70 EXPECT_EQ(-(procedure_address_offset + RoundUp(kProcedureSize, 8)), | |
| 71 procedure_address); | |
| 72 | |
| 73 int procedure_size = iterator.GetNextUInt32(); | |
| 74 EXPECT_EQ(kProcedureSize, procedure_size); | |
| 75 } | |
| 76 | |
| 77 TEST_F(EhFrameWriterTest, SetOffset) { | |
| 78 static const int kOffset = 0x0badc0de; | |
| 79 | |
| 80 EhFrameWriter writer(zone()); | |
| 81 writer.Initialize(); | |
| 82 writer.SetBaseAddressOffset(kOffset); | |
| 83 writer.Finish(100); | |
| 84 | |
| 85 EhFrameIterator iterator = MakeIterator(&writer); | |
| 86 iterator.SkipToFdeDirectives(); | |
| 87 | |
| 88 EXPECT_EQ(EhFrameConstants::DwarfOpcodes::kDefCfaOffset, | |
| 89 iterator.GetNextOpcode()); | |
| 90 EXPECT_EQ(kOffset, iterator.GetNextULeb128()); | |
| 91 } | |
| 92 | |
| 93 TEST_F(EhFrameWriterTest, IncreaseOffset) { | |
| 94 static const int kFirstOffset = 121; | |
| 95 static const int kSecondOffset = 16; | |
| 96 | |
| 97 EhFrameWriter writer(zone()); | |
| 98 writer.Initialize(); | |
| 99 writer.SetBaseAddressOffset(kFirstOffset); | |
| 100 writer.IncreaseBaseAddressOffset(kSecondOffset); | |
| 101 writer.Finish(100); | |
| 102 | |
| 103 EhFrameIterator iterator = MakeIterator(&writer); | |
| 104 iterator.SkipToFdeDirectives(); | |
| 105 | |
| 106 EXPECT_EQ(EhFrameConstants::DwarfOpcodes::kDefCfaOffset, | |
| 107 iterator.GetNextOpcode()); | |
| 108 EXPECT_EQ(kFirstOffset, iterator.GetNextULeb128()); | |
| 109 | |
| 110 EXPECT_EQ(EhFrameConstants::DwarfOpcodes::kDefCfaOffset, | |
| 111 iterator.GetNextOpcode()); | |
| 112 EXPECT_EQ(kFirstOffset + kSecondOffset, iterator.GetNextULeb128()); | |
| 113 } | |
| 114 | |
| 115 TEST_F(EhFrameWriterTest, SetRegister) { | |
| 116 Register test_register = Register::from_code(kTestRegisterCode); | |
| 117 | |
| 118 EhFrameWriter writer(zone()); | |
| 119 writer.Initialize(); | |
| 120 writer.SetBaseAddressRegister(test_register); | |
| 121 writer.Finish(100); | |
| 122 | |
| 123 EhFrameIterator iterator = MakeIterator(&writer); | |
| 124 iterator.SkipToFdeDirectives(); | |
| 125 | |
| 126 EXPECT_EQ(EhFrameConstants::DwarfOpcodes::kDefCfaRegister, | |
| 127 iterator.GetNextOpcode()); | |
| 128 EXPECT_EQ(kTestRegisterCode, iterator.GetNextULeb128()); | |
| 129 } | |
| 130 | |
| 131 TEST_F(EhFrameWriterTest, SetRegisterAndOffset) { | |
| 132 Register test_register = Register::from_code(kTestRegisterCode); | |
| 133 static const int kOffset = 0x0badc0de; | |
| 134 | |
| 135 EhFrameWriter writer(zone()); | |
| 136 writer.Initialize(); | |
| 137 writer.SetBaseAddressRegisterAndOffset(test_register, kOffset); | |
| 138 writer.Finish(100); | |
| 139 | |
| 140 EhFrameIterator iterator = MakeIterator(&writer); | |
| 141 iterator.SkipToFdeDirectives(); | |
| 142 | |
| 143 EXPECT_EQ(EhFrameConstants::DwarfOpcodes::kDefCfa, iterator.GetNextOpcode()); | |
| 144 EXPECT_EQ(kTestRegisterCode, iterator.GetNextULeb128()); | |
| 145 EXPECT_EQ(kOffset, iterator.GetNextULeb128()); | |
| 146 } | |
| 147 | |
| 148 TEST_F(EhFrameWriterTest, PcOffsetEncoding6bit) { | |
| 149 static const int kOffset = 42; | |
| 150 | |
| 151 EhFrameWriter writer(zone()); | |
| 152 writer.Initialize(); | |
| 153 writer.AdvanceLocation(kOffset * EhFrameConstants::kCodeAlignmentFactor); | |
| 154 writer.Finish(100); | |
| 155 | |
| 156 EhFrameIterator iterator = MakeIterator(&writer); | |
| 157 iterator.SkipToFdeDirectives(); | |
| 158 | |
| 159 EXPECT_EQ((1 << 6) | kOffset, iterator.GetNextByte()); | |
| 160 } | |
| 161 | |
| 162 TEST_F(EhFrameWriterTest, PcOffsetEncoding6bitDelta) { | |
| 163 static const int kFirstOffset = 42; | |
| 164 static const int kSecondOffset = 62; | |
| 165 | |
| 166 EhFrameWriter writer(zone()); | |
| 167 writer.Initialize(); | |
| 168 writer.AdvanceLocation(kFirstOffset * EhFrameConstants::kCodeAlignmentFactor); | |
| 169 writer.AdvanceLocation(kSecondOffset * | |
| 170 EhFrameConstants::kCodeAlignmentFactor); | |
| 171 writer.Finish(100); | |
| 172 | |
| 173 EhFrameIterator iterator = MakeIterator(&writer); | |
| 174 iterator.SkipToFdeDirectives(); | |
| 175 | |
| 176 EXPECT_EQ((1 << 6) | kFirstOffset, iterator.GetNextByte()); | |
| 177 EXPECT_EQ((1 << 6) | (kSecondOffset - kFirstOffset), iterator.GetNextByte()); | |
| 178 } | |
| 179 | |
| 180 TEST_F(EhFrameWriterTest, PcOffsetEncoding8bit) { | |
| 181 static const int kOffset = 0x42; | |
| 182 | |
| 183 EhFrameWriter writer(zone()); | |
| 184 writer.Initialize(); | |
| 185 writer.AdvanceLocation(kOffset * EhFrameConstants::kCodeAlignmentFactor); | |
| 186 writer.Finish(100); | |
| 187 | |
| 188 EhFrameIterator iterator = MakeIterator(&writer); | |
| 189 iterator.SkipToFdeDirectives(); | |
| 190 | |
| 191 EXPECT_EQ(EhFrameConstants::DwarfOpcodes::kAdvanceLoc1, | |
| 192 iterator.GetNextOpcode()); | |
| 193 EXPECT_EQ(kOffset, iterator.GetNextByte()); | |
| 194 } | |
| 195 | |
| 196 TEST_F(EhFrameWriterTest, PcOffsetEncoding8bitDelta) { | |
| 197 static const int kFirstOffset = 0x10; | |
| 198 static const int kSecondOffset = 0x70; | |
| 199 static const int kThirdOffset = 0xb5; | |
| 200 | |
| 201 EhFrameWriter writer(zone()); | |
| 202 writer.Initialize(); | |
| 203 writer.AdvanceLocation(kFirstOffset * EhFrameConstants::kCodeAlignmentFactor); | |
| 204 writer.AdvanceLocation(kSecondOffset * | |
| 205 EhFrameConstants::kCodeAlignmentFactor); | |
| 206 writer.AdvanceLocation(kThirdOffset * EhFrameConstants::kCodeAlignmentFactor); | |
| 207 writer.Finish(100); | |
| 208 | |
| 209 EhFrameIterator iterator = MakeIterator(&writer); | |
| 210 iterator.SkipToFdeDirectives(); | |
| 211 | |
| 212 EXPECT_EQ((1 << 6) | kFirstOffset, iterator.GetNextByte()); | |
| 213 | |
| 214 EXPECT_EQ(EhFrameConstants::DwarfOpcodes::kAdvanceLoc1, | |
| 215 iterator.GetNextOpcode()); | |
| 216 EXPECT_EQ(kSecondOffset - kFirstOffset, iterator.GetNextByte()); | |
| 217 | |
| 218 EXPECT_EQ(EhFrameConstants::DwarfOpcodes::kAdvanceLoc1, | |
| 219 iterator.GetNextOpcode()); | |
| 220 EXPECT_EQ(kThirdOffset - kSecondOffset, iterator.GetNextByte()); | |
| 221 } | |
| 222 | |
| 223 TEST_F(EhFrameWriterTest, PcOffsetEncoding16bit) { | |
| 224 static const int kOffset = kMaxUInt8 + 42; | |
| 225 ASSERT_LT(kOffset, kMaxUInt16); | |
| 226 | |
| 227 EhFrameWriter writer(zone()); | |
| 228 writer.Initialize(); | |
| 229 writer.AdvanceLocation(kOffset * EhFrameConstants::kCodeAlignmentFactor); | |
| 230 writer.Finish(100); | |
| 231 | |
| 232 EhFrameIterator iterator = MakeIterator(&writer); | |
| 233 iterator.SkipToFdeDirectives(); | |
| 234 | |
| 235 EXPECT_EQ(EhFrameConstants::DwarfOpcodes::kAdvanceLoc2, | |
| 236 iterator.GetNextOpcode()); | |
| 237 EXPECT_EQ(kOffset, iterator.GetNextUInt16()); | |
| 238 } | |
| 239 | |
| 240 TEST_F(EhFrameWriterTest, PcOffsetEncoding16bitDelta) { | |
| 241 static const int kFirstOffset = 0x41; | |
| 242 static const int kSecondOffset = kMaxUInt8 + 0x42; | |
| 243 | |
| 244 EhFrameWriter writer(zone()); | |
| 245 writer.Initialize(); | |
| 246 writer.AdvanceLocation(kFirstOffset * EhFrameConstants::kCodeAlignmentFactor); | |
| 247 writer.AdvanceLocation(kSecondOffset * | |
| 248 EhFrameConstants::kCodeAlignmentFactor); | |
| 249 writer.Finish(100); | |
| 250 | |
| 251 EhFrameIterator iterator = MakeIterator(&writer); | |
| 252 iterator.SkipToFdeDirectives(); | |
| 253 | |
| 254 EXPECT_EQ(EhFrameConstants::DwarfOpcodes::kAdvanceLoc1, | |
| 255 iterator.GetNextOpcode()); | |
| 256 EXPECT_EQ(kFirstOffset, iterator.GetNextByte()); | |
| 257 | |
| 258 EXPECT_EQ(EhFrameConstants::DwarfOpcodes::kAdvanceLoc2, | |
| 259 iterator.GetNextOpcode()); | |
| 260 EXPECT_EQ(kSecondOffset - kFirstOffset, iterator.GetNextUInt16()); | |
| 261 } | |
| 262 | |
| 263 TEST_F(EhFrameWriterTest, PcOffsetEncoding32bit) { | |
| 264 static const int kOffset = kMaxUInt16 + 42; | |
| 265 | |
| 266 EhFrameWriter writer(zone()); | |
| 267 writer.Initialize(); | |
| 268 writer.AdvanceLocation(kOffset * EhFrameConstants::kCodeAlignmentFactor); | |
| 269 writer.Finish(100); | |
| 270 | |
| 271 EhFrameIterator iterator = MakeIterator(&writer); | |
| 272 iterator.SkipToFdeDirectives(); | |
| 273 | |
| 274 EXPECT_EQ(EhFrameConstants::DwarfOpcodes::kAdvanceLoc4, | |
| 275 iterator.GetNextOpcode()); | |
| 276 EXPECT_EQ(kOffset, iterator.GetNextUInt32()); | |
| 277 } | |
| 278 | |
| 279 TEST_F(EhFrameWriterTest, PcOffsetEncoding32bitDelta) { | |
| 280 static const int kFirstOffset = kMaxUInt16 + 0x42; | |
| 281 static const int kSecondOffset = kMaxUInt16 + 0x67; | |
| 282 | |
| 283 EhFrameWriter writer(zone()); | |
| 284 writer.Initialize(); | |
| 285 writer.AdvanceLocation(kFirstOffset * EhFrameConstants::kCodeAlignmentFactor); | |
| 286 writer.AdvanceLocation(kSecondOffset * | |
| 287 EhFrameConstants::kCodeAlignmentFactor); | |
| 288 writer.Finish(100); | |
| 289 | |
| 290 EhFrameIterator iterator = MakeIterator(&writer); | |
| 291 iterator.SkipToFdeDirectives(); | |
| 292 | |
| 293 EXPECT_EQ(EhFrameConstants::DwarfOpcodes::kAdvanceLoc4, | |
| 294 iterator.GetNextOpcode()); | |
| 295 EXPECT_EQ(kFirstOffset, iterator.GetNextUInt32()); | |
| 296 | |
| 297 EXPECT_EQ((1 << 6) | (kSecondOffset - kFirstOffset), iterator.GetNextByte()); | |
| 298 } | |
| 299 | |
| 300 TEST_F(EhFrameWriterTest, SaveRegisterUnsignedOffset) { | |
| 301 Register test_register = Register::from_code(kTestRegisterCode); | |
| 302 static const int kOffset = | |
| 303 EhFrameConstants::kDataAlignmentFactor > 0 ? 12344 : -12344; | |
| 304 | |
| 305 EhFrameWriter writer(zone()); | |
| 306 writer.Initialize(); | |
| 307 writer.RecordRegisterSavedToStack(test_register, kOffset); | |
| 308 writer.Finish(100); | |
| 309 | |
| 310 EhFrameIterator iterator = MakeIterator(&writer); | |
| 311 iterator.SkipToFdeDirectives(); | |
| 312 | |
| 313 EXPECT_EQ((2 << 6) | kTestRegisterCode, iterator.GetNextByte()); | |
| 314 EXPECT_EQ(kOffset / EhFrameConstants::kDataAlignmentFactor, | |
| 315 iterator.GetNextULeb128()); | |
| 316 } | |
| 317 | |
| 318 TEST_F(EhFrameWriterTest, SaveRegisterSignedOffset) { | |
| 319 Register test_register = Register::from_code(kTestRegisterCode); | |
| 320 static const int kOffset = | |
| 321 EhFrameConstants::kDataAlignmentFactor < 0 ? 12344 : -12344; | |
| 322 | |
| 323 ASSERT_EQ(kOffset % EhFrameConstants::kDataAlignmentFactor, 0); | |
| 324 | |
| 325 EhFrameWriter writer(zone()); | |
| 326 writer.Initialize(); | |
| 327 writer.RecordRegisterSavedToStack(test_register, kOffset); | |
| 328 writer.Finish(100); | |
| 329 | |
| 330 EhFrameIterator iterator = MakeIterator(&writer); | |
| 331 iterator.SkipToFdeDirectives(); | |
| 332 | |
| 333 EXPECT_EQ(EhFrameConstants::DwarfOpcodes::kOffsetExtendedSf, | |
| 334 iterator.GetNextOpcode()); | |
| 335 EXPECT_EQ(kTestRegisterCode, iterator.GetNextULeb128()); | |
| 336 EXPECT_EQ(kOffset / EhFrameConstants::kDataAlignmentFactor, | |
| 337 iterator.GetNextSLeb128()); | |
| 338 } | |
| 339 | |
| 340 TEST_F(EhFrameWriterTest, RegisterNotModified) { | |
| 341 Register test_register = Register::from_code(kTestRegisterCode); | |
| 342 | |
| 343 EhFrameWriter writer(zone()); | |
| 344 writer.Initialize(); | |
| 345 writer.RecordRegisterNotModified(test_register); | |
| 346 writer.Finish(100); | |
| 347 | |
| 348 EhFrameIterator iterator = MakeIterator(&writer); | |
| 349 iterator.SkipToFdeDirectives(); | |
| 350 | |
| 351 EXPECT_EQ(EhFrameConstants::DwarfOpcodes::kSameValue, | |
| 352 iterator.GetNextOpcode()); | |
| 353 EXPECT_EQ(kTestRegisterCode, iterator.GetNextULeb128()); | |
| 354 } | |
| 355 | |
| 356 TEST_F(EhFrameWriterTest, RegisterFollowsInitialRule) { | |
| 357 Register test_register = Register::from_code(kTestRegisterCode); | |
| 358 | |
| 359 EhFrameWriter writer(zone()); | |
| 360 writer.Initialize(); | |
| 361 writer.RecordRegisterFollowsInitialRule(test_register); | |
| 362 writer.Finish(100); | |
| 363 | |
| 364 EhFrameIterator iterator = MakeIterator(&writer); | |
| 365 iterator.SkipToFdeDirectives(); | |
| 366 | |
| 367 EXPECT_EQ((3 << 6) | kTestRegisterCode, iterator.GetNextByte()); | |
| 368 } | |
| 369 | |
| 370 TEST_F(EhFrameWriterTest, EhFrameHdrLayout) { | |
| 371 static const int kCodeSize = 10; | |
| 372 static const int kPaddingSize = 6; | |
| 373 | |
| 374 EhFrameWriter writer(zone()); | |
| 375 writer.Initialize(); | |
| 376 writer.Finish(kCodeSize); | |
| 377 | |
| 378 EhFrameIterator iterator = MakeIterator(&writer); | |
| 379 | |
| 380 // Skip the .eh_frame. | |
| 381 | |
| 382 int encoded_cie_size = iterator.GetNextUInt32(); | |
| 383 iterator.Skip(encoded_cie_size); | |
| 384 int cie_size = encoded_cie_size + kInt32Size; | |
| 385 | |
| 386 int encoded_fde_size = iterator.GetNextUInt32(); | |
| 387 iterator.Skip(encoded_fde_size); | |
| 388 int fde_size = encoded_fde_size + kInt32Size; | |
| 389 | |
| 390 iterator.Skip(EhFrameConstants::kEhFrameTerminatorSize); | |
| 391 | |
| 392 int eh_frame_size = | |
| 393 cie_size + fde_size + EhFrameConstants::kEhFrameTerminatorSize; | |
| 394 | |
| 395 // | |
| 396 // Plugging some numbers in the DSO layout shown in eh-frame.cc: | |
| 397 // | |
| 398 // | ... | | |
| 399 // +---------------+ <-- (E) --------- | |
| 400 // | | ^ | |
| 401 // | Instructions | 10 bytes | .text | |
| 402 // | | v | |
| 403 // +---------------+ <---------------- | |
| 404 // |///////////////| | |
| 405 // |////Padding////| 6 bytes | |
| 406 // |///////////////| | |
| 407 // +---------------+ <---(D)---------- | |
| 408 // | | ^ | |
| 409 // | CIE | cie_size bytes* | | |
| 410 // | | | | |
| 411 // +---------------+ <-- (C) | | |
| 412 // | | | .eh_frame | |
| 413 // | FDE | fde_size bytes | | |
| 414 // | | | | |
| 415 // +---------------+ | | |
| 416 // | terminator | 4 bytes v | |
| 417 // +---------------+ <-- (B) --------- | |
| 418 // | version | ^ | |
| 419 // +---------------+ 4 bytes | | |
| 420 // | encoding | | | |
| 421 // | specifiers | | | |
| 422 // +---------------+ <---(A) | .eh_frame_hdr | |
| 423 // | offset to | | | |
| 424 // | .eh_frame | | | |
| 425 // +---------------+ | | |
| 426 // | ... | ... | |
| 427 // | |
| 428 // (*) the size of the CIE is platform dependent. | |
| 429 // | |
| 430 | |
| 431 int eh_frame_hdr_version = iterator.GetNextByte(); | |
| 432 EXPECT_EQ(EhFrameConstants::kEhFrameHdrVersion, eh_frame_hdr_version); | |
| 433 | |
| 434 // .eh_frame pointer encoding specifier. | |
| 435 EXPECT_EQ(EhFrameConstants::kSData4 | EhFrameConstants::kPcRel, | |
| 436 iterator.GetNextByte()); | |
| 437 | |
| 438 // Lookup table size encoding specifier. | |
| 439 EXPECT_EQ(EhFrameConstants::kUData4, iterator.GetNextByte()); | |
| 440 | |
| 441 // Lookup table pointers encoding specifier. | |
| 442 EXPECT_EQ(EhFrameConstants::kSData4 | EhFrameConstants::kDataRel, | |
| 443 iterator.GetNextByte()); | |
| 444 | |
| 445 // A -> D | |
| 446 int offset_to_eh_frame = iterator.GetNextUInt32(); | |
| 447 EXPECT_EQ(-(EhFrameConstants::kFdeVersionSize + | |
| 448 EhFrameConstants::kFdeEncodingSpecifiersSize + eh_frame_size), | |
| 449 offset_to_eh_frame); | |
| 450 | |
| 451 int lut_entries = iterator.GetNextUInt32(); | |
| 452 EXPECT_EQ(1, lut_entries); | |
| 453 | |
| 454 // B -> E | |
| 455 int offset_to_procedure = iterator.GetNextUInt32(); | |
| 456 EXPECT_EQ(-(eh_frame_size + kPaddingSize + kCodeSize), offset_to_procedure); | |
| 457 | |
| 458 // B -> C | |
| 459 int offset_to_fde = iterator.GetNextUInt32(); | |
| 460 EXPECT_EQ(-(fde_size + EhFrameConstants::kEhFrameTerminatorSize), | |
| 461 offset_to_fde); | |
| 462 } | |
| 463 | |
| 464 #endif | |
| OLD | NEW |