Refactor the DwarfSection classes.
Modify the code for the no header sections because it turns out that
it is not okay to assume that the fdes are non-overlapping. It's necessary
to read the fdes in order and match as you go.
Modify the code so that it only reads until it finds the given pc rather than
reading all of the cie/fde entries at once.
Rewrote the tests to verify the new behavior.
Bug: 68998033
Bug: 110235461
Test: Ran libbacktrace/libunwindstack unit tests.
Test: Unwind the mediaserver process on a walleye and verify it
Test: unwinds properly.
Change-Id: I7bb59d1db72c13fa34caa9735ec34c1a60e20ed2
diff --git a/libunwindstack/tests/DwarfDebugFrameTest.cpp b/libunwindstack/tests/DwarfDebugFrameTest.cpp
index 3a52044..d620934 100644
--- a/libunwindstack/tests/DwarfDebugFrameTest.cpp
+++ b/libunwindstack/tests/DwarfDebugFrameTest.cpp
@@ -16,7 +16,8 @@
#include <stdint.h>
-#include <gmock/gmock.h>
+#include <vector>
+
#include <gtest/gtest.h>
#include <unwindstack/DwarfError.h>
@@ -30,480 +31,377 @@
namespace unwindstack {
template <typename TypeParam>
-class MockDwarfDebugFrame : public DwarfDebugFrame<TypeParam> {
- public:
- MockDwarfDebugFrame(Memory* memory) : DwarfDebugFrame<TypeParam>(memory) {}
- ~MockDwarfDebugFrame() = default;
-
- void TestSetFdeCount(uint64_t count) { this->fde_count_ = count; }
- void TestSetOffset(uint64_t offset) { this->entries_offset_ = offset; }
- void TestSetEndOffset(uint64_t offset) { this->entries_end_ = offset; }
- void TestPushFdeInfo(const typename DwarfDebugFrame<TypeParam>::FdeInfo& info) {
- this->fdes_.push_back(info);
- }
-
- uint64_t TestGetFdeCount() { return this->fde_count_; }
- uint8_t TestGetOffset() { return this->offset_; }
- uint8_t TestGetEndOffset() { return this->end_offset_; }
- void TestGetFdeInfo(size_t index, typename DwarfDebugFrame<TypeParam>::FdeInfo* info) {
- *info = this->fdes_[index];
- }
-};
-
-template <typename TypeParam>
class DwarfDebugFrameTest : public ::testing::Test {
protected:
void SetUp() override {
memory_.Clear();
- debug_frame_ = new MockDwarfDebugFrame<TypeParam>(&memory_);
+ debug_frame_ = new DwarfDebugFrame<TypeParam>(&memory_);
ResetLogs();
}
void TearDown() override { delete debug_frame_; }
MemoryFake memory_;
- MockDwarfDebugFrame<TypeParam>* debug_frame_ = nullptr;
+ DwarfDebugFrame<TypeParam>* debug_frame_ = nullptr;
};
TYPED_TEST_CASE_P(DwarfDebugFrameTest);
// NOTE: All test class variables need to be referenced as this->.
-TYPED_TEST_P(DwarfDebugFrameTest, Init32) {
- // CIE 32 information.
- this->memory_.SetData32(0x5000, 0xfc);
- this->memory_.SetData32(0x5004, 0xffffffff);
- this->memory_.SetData8(0x5008, 1);
- this->memory_.SetData8(0x5009, '\0');
+static void SetCie32(MemoryFake* memory, uint64_t offset, uint32_t length,
+ std::vector<uint8_t> data) {
+ memory->SetData32(offset, length);
+ offset += 4;
+ // Indicates this is a cie.
+ memory->SetData32(offset, 0xffffffff);
+ offset += 4;
+ memory->SetMemory(offset, data);
+}
+
+static void SetCie64(MemoryFake* memory, uint64_t offset, uint64_t length,
+ std::vector<uint8_t> data) {
+ memory->SetData32(offset, 0xffffffff);
+ offset += 4;
+ memory->SetData64(offset, length);
+ offset += 8;
+ // Indicates this is a cie.
+ memory->SetData64(offset, 0xffffffffffffffffUL);
+ offset += 8;
+ memory->SetMemory(offset, data);
+}
+
+static void SetFde32(MemoryFake* memory, uint64_t offset, uint32_t length, uint64_t cie_offset,
+ uint32_t pc_start, uint32_t pc_length, uint64_t segment_length = 0,
+ std::vector<uint8_t>* data = nullptr) {
+ memory->SetData32(offset, length);
+ offset += 4;
+ memory->SetData32(offset, cie_offset);
+ offset += 4 + segment_length;
+ memory->SetData32(offset, pc_start);
+ offset += 4;
+ memory->SetData32(offset, pc_length);
+ if (data != nullptr) {
+ offset += 4;
+ memory->SetMemory(offset, *data);
+ }
+}
+
+static void SetFde64(MemoryFake* memory, uint64_t offset, uint64_t length, uint64_t cie_offset,
+ uint64_t pc_start, uint64_t pc_length, uint64_t segment_length = 0,
+ std::vector<uint8_t>* data = nullptr) {
+ memory->SetData32(offset, 0xffffffff);
+ offset += 4;
+ memory->SetData64(offset, length);
+ offset += 8;
+ memory->SetData64(offset, cie_offset);
+ offset += 8 + segment_length;
+ memory->SetData64(offset, pc_start);
+ offset += 8;
+ memory->SetData64(offset, pc_length);
+ if (data != nullptr) {
+ offset += 8;
+ memory->SetMemory(offset, *data);
+ }
+}
+
+static void SetFourFdes32(MemoryFake* memory) {
+ SetCie32(memory, 0x5000, 0xfc, std::vector<uint8_t>{1, '\0', 0, 0, 1});
// FDE 32 information.
- this->memory_.SetData32(0x5100, 0xfc);
- this->memory_.SetData32(0x5104, 0);
- this->memory_.SetData32(0x5108, 0x1500);
- this->memory_.SetData32(0x510c, 0x200);
-
- this->memory_.SetData32(0x5200, 0xfc);
- this->memory_.SetData32(0x5204, 0);
- this->memory_.SetData32(0x5208, 0x2500);
- this->memory_.SetData32(0x520c, 0x300);
+ SetFde32(memory, 0x5100, 0xfc, 0, 0x1500, 0x200);
+ SetFde32(memory, 0x5200, 0xfc, 0, 0x2500, 0x300);
// CIE 32 information.
- this->memory_.SetData32(0x5300, 0xfc);
- this->memory_.SetData32(0x5304, 0xffffffff);
- this->memory_.SetData8(0x5308, 1);
- this->memory_.SetData8(0x5309, '\0');
+ SetCie32(memory, 0x5300, 0xfc, std::vector<uint8_t>{1, '\0', 0, 0, 1});
// FDE 32 information.
- this->memory_.SetData32(0x5400, 0xfc);
- this->memory_.SetData32(0x5404, 0x300);
- this->memory_.SetData32(0x5408, 0x3500);
- this->memory_.SetData32(0x540c, 0x400);
+ SetFde32(memory, 0x5400, 0xfc, 0x300, 0x3500, 0x400);
+ SetFde32(memory, 0x5500, 0xfc, 0x300, 0x4500, 0x500);
+}
- this->memory_.SetData32(0x5500, 0xfc);
- this->memory_.SetData32(0x5504, 0x300);
- this->memory_.SetData32(0x5508, 0x4500);
- this->memory_.SetData32(0x550c, 0x500);
-
+TYPED_TEST_P(DwarfDebugFrameTest, GetFdes32) {
+ SetFourFdes32(&this->memory_);
ASSERT_TRUE(this->debug_frame_->Init(0x5000, 0x600, 0));
- ASSERT_EQ(4U, this->debug_frame_->TestGetFdeCount());
- typename DwarfDebugFrame<TypeParam>::FdeInfo info(0, 0, 0);
+ std::vector<const DwarfFde*> fdes;
+ this->debug_frame_->GetFdes(&fdes);
- this->debug_frame_->TestGetFdeInfo(0, &info);
- EXPECT_EQ(0x5100U, info.offset);
- EXPECT_EQ(0x1500U, info.start);
- EXPECT_EQ(0x1700U, info.end);
+ ASSERT_EQ(4U, fdes.size());
- this->debug_frame_->TestGetFdeInfo(1, &info);
- EXPECT_EQ(0x5200U, info.offset);
- EXPECT_EQ(0x2500U, info.start);
- EXPECT_EQ(0x2800U, info.end);
+ EXPECT_EQ(0x5000U, fdes[0]->cie_offset);
+ EXPECT_EQ(0x5110U, fdes[0]->cfa_instructions_offset);
+ EXPECT_EQ(0x5200U, fdes[0]->cfa_instructions_end);
+ EXPECT_EQ(0x1500U, fdes[0]->pc_start);
+ EXPECT_EQ(0x1700U, fdes[0]->pc_end);
+ EXPECT_EQ(0U, fdes[0]->lsda_address);
+ EXPECT_TRUE(fdes[0]->cie != nullptr);
- this->debug_frame_->TestGetFdeInfo(2, &info);
- EXPECT_EQ(0x5400U, info.offset);
- EXPECT_EQ(0x3500U, info.start);
- EXPECT_EQ(0x3900U, info.end);
+ EXPECT_EQ(0x5000U, fdes[1]->cie_offset);
+ EXPECT_EQ(0x5210U, fdes[1]->cfa_instructions_offset);
+ EXPECT_EQ(0x5300U, fdes[1]->cfa_instructions_end);
+ EXPECT_EQ(0x2500U, fdes[1]->pc_start);
+ EXPECT_EQ(0x2800U, fdes[1]->pc_end);
+ EXPECT_EQ(0U, fdes[1]->lsda_address);
+ EXPECT_TRUE(fdes[1]->cie != nullptr);
- this->debug_frame_->TestGetFdeInfo(3, &info);
- EXPECT_EQ(0x5500U, info.offset);
- EXPECT_EQ(0x4500U, info.start);
- EXPECT_EQ(0x4a00U, info.end);
+ EXPECT_EQ(0x5300U, fdes[2]->cie_offset);
+ EXPECT_EQ(0x5410U, fdes[2]->cfa_instructions_offset);
+ EXPECT_EQ(0x5500U, fdes[2]->cfa_instructions_end);
+ EXPECT_EQ(0x3500U, fdes[2]->pc_start);
+ EXPECT_EQ(0x3900U, fdes[2]->pc_end);
+ EXPECT_EQ(0U, fdes[2]->lsda_address);
+ EXPECT_TRUE(fdes[2]->cie != nullptr);
+
+ EXPECT_EQ(0x5300U, fdes[3]->cie_offset);
+ EXPECT_EQ(0x5510U, fdes[3]->cfa_instructions_offset);
+ EXPECT_EQ(0x5600U, fdes[3]->cfa_instructions_end);
+ EXPECT_EQ(0x4500U, fdes[3]->pc_start);
+ EXPECT_EQ(0x4a00U, fdes[3]->pc_end);
+ EXPECT_EQ(0U, fdes[3]->lsda_address);
+ EXPECT_TRUE(fdes[3]->cie != nullptr);
}
-TYPED_TEST_P(DwarfDebugFrameTest, Init32_fde_not_following_cie) {
- // CIE 32 information.
- this->memory_.SetData32(0x5000, 0xfc);
- this->memory_.SetData32(0x5004, 0xffffffff);
- this->memory_.SetData8(0x5008, 1);
- this->memory_.SetData8(0x5009, '\0');
-
- // FDE 32 information.
- this->memory_.SetData32(0x5100, 0xfc);
- this->memory_.SetData32(0x5104, 0x1000);
- this->memory_.SetData32(0x5108, 0x1500);
- this->memory_.SetData32(0x510c, 0x200);
-
- ASSERT_FALSE(this->debug_frame_->Init(0x5000, 0x600, 0));
- ASSERT_EQ(DWARF_ERROR_ILLEGAL_VALUE, this->debug_frame_->LastErrorCode());
-}
-
-TYPED_TEST_P(DwarfDebugFrameTest, Init32_do_not_fail_on_bad_next_entry) {
- // CIE 32 information.
- this->memory_.SetData32(0x5000, 0xfc);
- this->memory_.SetData32(0x5004, 0xffffffff);
- this->memory_.SetData8(0x5008, 1);
- this->memory_.SetData8(0x5009, '\0');
-
- // FDE 32 information.
- this->memory_.SetData32(0x5100, 0xfc);
- this->memory_.SetData32(0x5104, 0);
- this->memory_.SetData32(0x5108, 0x1500);
- this->memory_.SetData32(0x510c, 0x200);
-
- this->memory_.SetData32(0x5200, 0xfc);
- this->memory_.SetData32(0x5204, 0);
- this->memory_.SetData32(0x5208, 0x2500);
- this->memory_.SetData32(0x520c, 0x300);
-
- // CIE 32 information.
- this->memory_.SetData32(0x5300, 0);
- this->memory_.SetData32(0x5304, 0xffffffff);
- this->memory_.SetData8(0x5308, 1);
- this->memory_.SetData8(0x5309, '\0');
-
- // FDE 32 information.
- this->memory_.SetData32(0x5400, 0xfc);
- this->memory_.SetData32(0x5404, 0x300);
- this->memory_.SetData32(0x5408, 0x3500);
- this->memory_.SetData32(0x540c, 0x400);
-
- this->memory_.SetData32(0x5500, 0xfc);
- this->memory_.SetData32(0x5504, 0x300);
- this->memory_.SetData32(0x5508, 0x4500);
- this->memory_.SetData32(0x550c, 0x500);
-
+TYPED_TEST_P(DwarfDebugFrameTest, GetFdes32_after_GetFdeFromPc) {
+ SetFourFdes32(&this->memory_);
ASSERT_TRUE(this->debug_frame_->Init(0x5000, 0x600, 0));
- ASSERT_EQ(2U, this->debug_frame_->TestGetFdeCount());
+
+ const DwarfFde* fde = this->debug_frame_->GetFdeFromPc(0x3600);
+ ASSERT_TRUE(fde != nullptr);
+ EXPECT_EQ(0x3500U, fde->pc_start);
+ EXPECT_EQ(0x3900U, fde->pc_end);
+
+ std::vector<const DwarfFde*> fdes;
+ this->debug_frame_->GetFdes(&fdes);
+ ASSERT_EQ(4U, fdes.size());
+
+ // Verify that they got added in the correct order.
+ EXPECT_EQ(0x1500U, fdes[0]->pc_start);
+ EXPECT_EQ(0x1700U, fdes[0]->pc_end);
+ EXPECT_EQ(0x2500U, fdes[1]->pc_start);
+ EXPECT_EQ(0x2800U, fdes[1]->pc_end);
+ EXPECT_EQ(0x3500U, fdes[2]->pc_start);
+ EXPECT_EQ(0x3900U, fdes[2]->pc_end);
+ EXPECT_EQ(0x4500U, fdes[3]->pc_start);
+ EXPECT_EQ(0x4a00U, fdes[3]->pc_end);
}
-TYPED_TEST_P(DwarfDebugFrameTest, Init64) {
- // CIE 64 information.
- this->memory_.SetData32(0x5000, 0xffffffff);
- this->memory_.SetData64(0x5004, 0xf4);
- this->memory_.SetData64(0x500c, 0xffffffffffffffffULL);
- this->memory_.SetData8(0x5014, 1);
- this->memory_.SetData8(0x5015, '\0');
+TYPED_TEST_P(DwarfDebugFrameTest, GetFdes32_not_in_section) {
+ SetFourFdes32(&this->memory_);
+ ASSERT_TRUE(this->debug_frame_->Init(0x5000, 0x500, 0));
- // FDE 64 information.
- this->memory_.SetData32(0x5100, 0xffffffff);
- this->memory_.SetData64(0x5104, 0xf4);
- this->memory_.SetData64(0x510c, 0);
- this->memory_.SetData64(0x5114, 0x1500);
- this->memory_.SetData64(0x511c, 0x200);
+ std::vector<const DwarfFde*> fdes;
+ this->debug_frame_->GetFdes(&fdes);
- this->memory_.SetData32(0x5200, 0xffffffff);
- this->memory_.SetData64(0x5204, 0xf4);
- this->memory_.SetData64(0x520c, 0);
- this->memory_.SetData64(0x5214, 0x2500);
- this->memory_.SetData64(0x521c, 0x300);
+ ASSERT_EQ(3U, fdes.size());
+}
- // CIE 64 information.
- this->memory_.SetData32(0x5300, 0xffffffff);
- this->memory_.SetData64(0x5304, 0xf4);
- this->memory_.SetData64(0x530c, 0xffffffffffffffffULL);
- this->memory_.SetData8(0x5314, 1);
- this->memory_.SetData8(0x5315, '\0');
-
- // FDE 64 information.
- this->memory_.SetData32(0x5400, 0xffffffff);
- this->memory_.SetData64(0x5404, 0xf4);
- this->memory_.SetData64(0x540c, 0x300);
- this->memory_.SetData64(0x5414, 0x3500);
- this->memory_.SetData64(0x541c, 0x400);
-
- this->memory_.SetData32(0x5500, 0xffffffff);
- this->memory_.SetData64(0x5504, 0xf4);
- this->memory_.SetData64(0x550c, 0x300);
- this->memory_.SetData64(0x5514, 0x4500);
- this->memory_.SetData64(0x551c, 0x500);
-
+TYPED_TEST_P(DwarfDebugFrameTest, GetFdeFromPc32) {
+ SetFourFdes32(&this->memory_);
ASSERT_TRUE(this->debug_frame_->Init(0x5000, 0x600, 0));
- ASSERT_EQ(4U, this->debug_frame_->TestGetFdeCount());
- typename DwarfDebugFrame<TypeParam>::FdeInfo info(0, 0, 0);
+ const DwarfFde* fde = this->debug_frame_->GetFdeFromPc(0x1600);
+ ASSERT_TRUE(fde != nullptr);
+ EXPECT_EQ(0x1500U, fde->pc_start);
- this->debug_frame_->TestGetFdeInfo(0, &info);
- EXPECT_EQ(0x5100U, info.offset);
- EXPECT_EQ(0x1500U, info.start);
- EXPECT_EQ(0x1700U, info.end);
-
- this->debug_frame_->TestGetFdeInfo(1, &info);
- EXPECT_EQ(0x5200U, info.offset);
- EXPECT_EQ(0x2500U, info.start);
- EXPECT_EQ(0x2800U, info.end);
-
- this->debug_frame_->TestGetFdeInfo(2, &info);
- EXPECT_EQ(0x5400U, info.offset);
- EXPECT_EQ(0x3500U, info.start);
- EXPECT_EQ(0x3900U, info.end);
-
- this->debug_frame_->TestGetFdeInfo(3, &info);
- EXPECT_EQ(0x5500U, info.offset);
- EXPECT_EQ(0x4500U, info.start);
- EXPECT_EQ(0x4a00U, info.end);
-}
-
-TYPED_TEST_P(DwarfDebugFrameTest, Init64_fde_not_following_cie) {
- // CIE 64 information.
- this->memory_.SetData32(0x5000, 0xffffffff);
- this->memory_.SetData64(0x5004, 0xf4);
- this->memory_.SetData64(0x500c, 0xffffffffffffffffULL);
- this->memory_.SetData8(0x5014, 1);
- this->memory_.SetData8(0x5015, '\0');
-
- // FDE 64 information.
- this->memory_.SetData32(0x5100, 0xffffffff);
- this->memory_.SetData64(0x5104, 0xf4);
- this->memory_.SetData64(0x510c, 0x1000);
- this->memory_.SetData64(0x5114, 0x1500);
- this->memory_.SetData64(0x511c, 0x200);
-
- ASSERT_FALSE(this->debug_frame_->Init(0x5000, 0x600, 0));
- ASSERT_EQ(DWARF_ERROR_ILLEGAL_VALUE, this->debug_frame_->LastErrorCode());
-}
-
-TYPED_TEST_P(DwarfDebugFrameTest, Init64_do_not_fail_on_bad_next_entry) {
- // CIE 64 information.
- this->memory_.SetData32(0x5000, 0xffffffff);
- this->memory_.SetData64(0x5004, 0xf4);
- this->memory_.SetData64(0x500c, 0xffffffffffffffffULL);
- this->memory_.SetData8(0x5014, 1);
- this->memory_.SetData8(0x5015, '\0');
-
- // FDE 64 information.
- this->memory_.SetData32(0x5100, 0xffffffff);
- this->memory_.SetData64(0x5104, 0xf4);
- this->memory_.SetData64(0x510c, 0);
- this->memory_.SetData64(0x5114, 0x1500);
- this->memory_.SetData64(0x511c, 0x200);
-
- this->memory_.SetData32(0x5200, 0xffffffff);
- this->memory_.SetData64(0x5204, 0xf4);
- this->memory_.SetData64(0x520c, 0);
- this->memory_.SetData64(0x5214, 0x2500);
- this->memory_.SetData64(0x521c, 0x300);
-
- // CIE 64 information.
- this->memory_.SetData32(0x5300, 0xffffffff);
- this->memory_.SetData64(0x5304, 0);
- this->memory_.SetData64(0x530c, 0xffffffffffffffffULL);
- this->memory_.SetData8(0x5314, 1);
- this->memory_.SetData8(0x5315, '\0');
-
- // FDE 64 information.
- this->memory_.SetData32(0x5400, 0xffffffff);
- this->memory_.SetData64(0x5404, 0xf4);
- this->memory_.SetData64(0x540c, 0x300);
- this->memory_.SetData64(0x5414, 0x3500);
- this->memory_.SetData64(0x541c, 0x400);
-
- this->memory_.SetData32(0x5500, 0xffffffff);
- this->memory_.SetData64(0x5504, 0xf4);
- this->memory_.SetData64(0x550c, 0x300);
- this->memory_.SetData64(0x5514, 0x4500);
- this->memory_.SetData64(0x551c, 0x500);
-
- ASSERT_TRUE(this->debug_frame_->Init(0x5000, 0x600, 0));
- ASSERT_EQ(2U, this->debug_frame_->TestGetFdeCount());
-}
-
-TYPED_TEST_P(DwarfDebugFrameTest, Init_non_zero_load_bias) {
- // CIE 32 information.
- this->memory_.SetData32(0x5000, 0xfc);
- this->memory_.SetData32(0x5004, 0xffffffff);
- this->memory_.SetData8(0x5008, 1);
- this->memory_.SetData8(0x5009, 'z');
- this->memory_.SetData8(0x500a, 'R');
- this->memory_.SetData8(0x500b, '\0');
- this->memory_.SetData8(0x500c, 0);
- this->memory_.SetData8(0x500d, 0);
- this->memory_.SetData8(0x500e, 0);
- this->memory_.SetData8(0x500f, 0);
- this->memory_.SetData8(0x5010, 0x1b);
-
- // FDE 32 information.
- this->memory_.SetData32(0x5100, 0xfc);
- this->memory_.SetData32(0x5104, 0);
- this->memory_.SetData32(0x5108, 0x1500);
- this->memory_.SetData32(0x510c, 0x200);
- this->memory_.SetData8(0x5110, 0);
- this->memory_.SetData8(0x5111, 0);
-
- ASSERT_TRUE(this->debug_frame_->Init(0x5000, 0x200, 0x1000));
- ASSERT_EQ(1U, this->debug_frame_->TestGetFdeCount());
-
- typename DwarfDebugFrame<TypeParam>::FdeInfo info(0, 0, 0);
-
- this->debug_frame_->TestGetFdeInfo(0, &info);
- EXPECT_EQ(0x5100U, info.offset);
- EXPECT_EQ(0x2500U, info.start);
- EXPECT_EQ(0x2700U, info.end);
-
- const DwarfFde* fde = this->debug_frame_->GetFdeFromPc(0x2504);
+ fde = this->debug_frame_->GetFdeFromPc(0x2600);
ASSERT_TRUE(fde != nullptr);
EXPECT_EQ(0x2500U, fde->pc_start);
- EXPECT_EQ(0x2700U, fde->pc_end);
+
+ fde = this->debug_frame_->GetFdeFromPc(0x3600);
+ ASSERT_TRUE(fde != nullptr);
+ EXPECT_EQ(0x3500U, fde->pc_start);
+
+ fde = this->debug_frame_->GetFdeFromPc(0x4600);
+ ASSERT_TRUE(fde != nullptr);
+ EXPECT_EQ(0x4500U, fde->pc_start);
+
+ fde = this->debug_frame_->GetFdeFromPc(0);
+ ASSERT_TRUE(fde == nullptr);
}
-TYPED_TEST_P(DwarfDebugFrameTest, Init_version1) {
- // CIE 32 information.
- this->memory_.SetData32(0x5000, 0xfc);
- this->memory_.SetData32(0x5004, 0xffffffff);
- this->memory_.SetData8(0x5008, 1);
- // Augment string.
- this->memory_.SetMemory(0x5009, std::vector<uint8_t>{'z', 'R', 'P', 'L', '\0'});
- // Code alignment factor.
- this->memory_.SetMemory(0x500e, std::vector<uint8_t>{0x80, 0x00});
- // Data alignment factor.
- this->memory_.SetMemory(0x5010, std::vector<uint8_t>{0x81, 0x80, 0x80, 0x00});
- // Return address register
- this->memory_.SetData8(0x5014, 0x84);
- // Augmentation length
- this->memory_.SetMemory(0x5015, std::vector<uint8_t>{0x84, 0x00});
- // R data.
- this->memory_.SetData8(0x5017, DW_EH_PE_pcrel | DW_EH_PE_udata2);
+TYPED_TEST_P(DwarfDebugFrameTest, GetFdeFromPc32_reverse) {
+ SetFourFdes32(&this->memory_);
+ ASSERT_TRUE(this->debug_frame_->Init(0x5000, 0x600, 0));
- // FDE 32 information.
- this->memory_.SetData32(0x5100, 0xfc);
- this->memory_.SetData32(0x5104, 0);
- this->memory_.SetData16(0x5108, 0x1500);
- this->memory_.SetData16(0x510a, 0x200);
+ const DwarfFde* fde = this->debug_frame_->GetFdeFromPc(0x4600);
+ ASSERT_TRUE(fde != nullptr);
+ EXPECT_EQ(0x4500U, fde->pc_start);
- ASSERT_TRUE(this->debug_frame_->Init(0x5000, 0x200, 0));
- ASSERT_EQ(1U, this->debug_frame_->TestGetFdeCount());
+ fde = this->debug_frame_->GetFdeFromPc(0x3600);
+ ASSERT_TRUE(fde != nullptr);
+ EXPECT_EQ(0x3500U, fde->pc_start);
- typename DwarfDebugFrame<TypeParam>::FdeInfo info(0, 0, 0);
- this->debug_frame_->TestGetFdeInfo(0, &info);
- EXPECT_EQ(0x5100U, info.offset);
- EXPECT_EQ(0x1500U, info.start);
- EXPECT_EQ(0x1700U, info.end);
+ fde = this->debug_frame_->GetFdeFromPc(0x2600);
+ ASSERT_TRUE(fde != nullptr);
+ EXPECT_EQ(0x2500U, fde->pc_start);
+
+ fde = this->debug_frame_->GetFdeFromPc(0x1600);
+ ASSERT_TRUE(fde != nullptr);
+ EXPECT_EQ(0x1500U, fde->pc_start);
+
+ fde = this->debug_frame_->GetFdeFromPc(0);
+ ASSERT_TRUE(fde == nullptr);
}
-TYPED_TEST_P(DwarfDebugFrameTest, Init_version4) {
- // CIE 32 information.
- this->memory_.SetData32(0x5000, 0xfc);
- this->memory_.SetData32(0x5004, 0xffffffff);
- this->memory_.SetData8(0x5008, 4);
- // Augment string.
- this->memory_.SetMemory(0x5009, std::vector<uint8_t>{'z', 'L', 'P', 'R', '\0'});
- // Address size.
- this->memory_.SetData8(0x500e, 4);
- // Segment size.
- this->memory_.SetData8(0x500f, 0);
- // Code alignment factor.
- this->memory_.SetMemory(0x5010, std::vector<uint8_t>{0x80, 0x00});
- // Data alignment factor.
- this->memory_.SetMemory(0x5012, std::vector<uint8_t>{0x81, 0x80, 0x80, 0x00});
- // Return address register
- this->memory_.SetMemory(0x5016, std::vector<uint8_t>{0x85, 0x10});
- // Augmentation length
- this->memory_.SetMemory(0x5018, std::vector<uint8_t>{0x84, 0x00});
- // L data.
- this->memory_.SetData8(0x501a, 0x10);
- // P data.
- this->memory_.SetData8(0x501b, DW_EH_PE_udata4);
- this->memory_.SetData32(0x501c, 0x100);
- // R data.
- this->memory_.SetData8(0x5020, DW_EH_PE_pcrel | DW_EH_PE_udata2);
+TYPED_TEST_P(DwarfDebugFrameTest, GetFdeFromPc32_not_in_section) {
+ SetFourFdes32(&this->memory_);
+ ASSERT_TRUE(this->debug_frame_->Init(0x5000, 0x500, 0));
- // FDE 32 information.
- this->memory_.SetData32(0x5100, 0xfc);
- this->memory_.SetData32(0x5104, 0);
- this->memory_.SetData16(0x5108, 0x1500);
- this->memory_.SetData16(0x510a, 0x200);
-
- ASSERT_TRUE(this->debug_frame_->Init(0x5000, 0x200, 0));
- ASSERT_EQ(1U, this->debug_frame_->TestGetFdeCount());
-
- typename DwarfDebugFrame<TypeParam>::FdeInfo info(0, 0, 0);
- this->debug_frame_->TestGetFdeInfo(0, &info);
- EXPECT_EQ(0x5100U, info.offset);
- EXPECT_EQ(0x1500U, info.start);
- EXPECT_EQ(0x1700U, info.end);
+ const DwarfFde* fde = this->debug_frame_->GetFdeFromPc(0x4600);
+ ASSERT_TRUE(fde == nullptr);
}
-TYPED_TEST_P(DwarfDebugFrameTest, GetFdeOffsetFromPc) {
- typename DwarfDebugFrame<TypeParam>::FdeInfo info(0, 0, 0);
- for (size_t i = 0; i < 9; i++) {
- info.start = 0x1000 * (i + 1);
- info.end = 0x1000 * (i + 2) - 0x10;
- info.offset = 0x5000 + i * 0x20;
- this->debug_frame_->TestPushFdeInfo(info);
- }
+static void SetFourFdes64(MemoryFake* memory) {
+ // CIE 64 information.
+ SetCie64(memory, 0x5000, 0xf4, std::vector<uint8_t>{1, '\0', 0, 0, 1});
- this->debug_frame_->TestSetFdeCount(0);
- uint64_t fde_offset;
- ASSERT_FALSE(this->debug_frame_->GetFdeOffsetFromPc(0x1000, &fde_offset));
- ASSERT_EQ(DWARF_ERROR_NONE, this->debug_frame_->LastErrorCode());
+ // FDE 64 information.
+ SetFde64(memory, 0x5100, 0xf4, 0, 0x1500, 0x200);
+ SetFde64(memory, 0x5200, 0xf4, 0, 0x2500, 0x300);
- this->debug_frame_->TestSetFdeCount(9);
- ASSERT_FALSE(this->debug_frame_->GetFdeOffsetFromPc(0x100, &fde_offset));
- ASSERT_EQ(DWARF_ERROR_NONE, this->debug_frame_->LastErrorCode());
- // Odd number of elements.
- for (size_t i = 0; i < 9; i++) {
- TypeParam pc = 0x1000 * (i + 1);
- ASSERT_TRUE(this->debug_frame_->GetFdeOffsetFromPc(pc, &fde_offset)) << "Failed at index " << i;
- EXPECT_EQ(0x5000 + i * 0x20, fde_offset) << "Failed at index " << i;
- ASSERT_TRUE(this->debug_frame_->GetFdeOffsetFromPc(pc + 1, &fde_offset)) << "Failed at index "
- << i;
- EXPECT_EQ(0x5000 + i * 0x20, fde_offset) << "Failed at index " << i;
- ASSERT_TRUE(this->debug_frame_->GetFdeOffsetFromPc(pc + 0xeff, &fde_offset))
- << "Failed at index " << i;
- EXPECT_EQ(0x5000 + i * 0x20, fde_offset) << "Failed at index " << i;
- ASSERT_FALSE(this->debug_frame_->GetFdeOffsetFromPc(pc + 0xfff, &fde_offset))
- << "Failed at index " << i;
- ASSERT_EQ(DWARF_ERROR_NONE, this->debug_frame_->LastErrorCode());
- }
+ // CIE 64 information.
+ SetCie64(memory, 0x5300, 0xf4, std::vector<uint8_t>{1, '\0', 0, 0, 1});
- // Even number of elements.
- this->debug_frame_->TestSetFdeCount(10);
- info.start = 0xa000;
- info.end = 0xaff0;
- info.offset = 0x5120;
- this->debug_frame_->TestPushFdeInfo(info);
+ // FDE 64 information.
+ SetFde64(memory, 0x5400, 0xf4, 0x300, 0x3500, 0x400);
+ SetFde64(memory, 0x5500, 0xf4, 0x300, 0x4500, 0x500);
+}
- for (size_t i = 0; i < 10; i++) {
- TypeParam pc = 0x1000 * (i + 1);
- ASSERT_TRUE(this->debug_frame_->GetFdeOffsetFromPc(pc, &fde_offset)) << "Failed at index " << i;
- EXPECT_EQ(0x5000 + i * 0x20, fde_offset) << "Failed at index " << i;
- ASSERT_TRUE(this->debug_frame_->GetFdeOffsetFromPc(pc + 1, &fde_offset)) << "Failed at index "
- << i;
- EXPECT_EQ(0x5000 + i * 0x20, fde_offset) << "Failed at index " << i;
- ASSERT_TRUE(this->debug_frame_->GetFdeOffsetFromPc(pc + 0xeff, &fde_offset))
- << "Failed at index " << i;
- EXPECT_EQ(0x5000 + i * 0x20, fde_offset) << "Failed at index " << i;
- ASSERT_FALSE(this->debug_frame_->GetFdeOffsetFromPc(pc + 0xfff, &fde_offset))
- << "Failed at index " << i;
- ASSERT_EQ(DWARF_ERROR_NONE, this->debug_frame_->LastErrorCode());
- }
+TYPED_TEST_P(DwarfDebugFrameTest, GetFdes64) {
+ SetFourFdes64(&this->memory_);
+ ASSERT_TRUE(this->debug_frame_->Init(0x5000, 0x600, 0));
+
+ std::vector<const DwarfFde*> fdes;
+ this->debug_frame_->GetFdes(&fdes);
+
+ ASSERT_EQ(4U, fdes.size());
+
+ EXPECT_EQ(0x5000U, fdes[0]->cie_offset);
+ EXPECT_EQ(0x5124U, fdes[0]->cfa_instructions_offset);
+ EXPECT_EQ(0x5200U, fdes[0]->cfa_instructions_end);
+ EXPECT_EQ(0x1500U, fdes[0]->pc_start);
+ EXPECT_EQ(0x1700U, fdes[0]->pc_end);
+ EXPECT_EQ(0U, fdes[0]->lsda_address);
+ EXPECT_TRUE(fdes[0]->cie != nullptr);
+
+ EXPECT_EQ(0x5000U, fdes[1]->cie_offset);
+ EXPECT_EQ(0x5224U, fdes[1]->cfa_instructions_offset);
+ EXPECT_EQ(0x5300U, fdes[1]->cfa_instructions_end);
+ EXPECT_EQ(0x2500U, fdes[1]->pc_start);
+ EXPECT_EQ(0x2800U, fdes[1]->pc_end);
+ EXPECT_EQ(0U, fdes[1]->lsda_address);
+ EXPECT_TRUE(fdes[1]->cie != nullptr);
+
+ EXPECT_EQ(0x5300U, fdes[2]->cie_offset);
+ EXPECT_EQ(0x5424U, fdes[2]->cfa_instructions_offset);
+ EXPECT_EQ(0x5500U, fdes[2]->cfa_instructions_end);
+ EXPECT_EQ(0x3500U, fdes[2]->pc_start);
+ EXPECT_EQ(0x3900U, fdes[2]->pc_end);
+ EXPECT_EQ(0U, fdes[2]->lsda_address);
+ EXPECT_TRUE(fdes[2]->cie != nullptr);
+
+ EXPECT_EQ(0x5300U, fdes[3]->cie_offset);
+ EXPECT_EQ(0x5524U, fdes[3]->cfa_instructions_offset);
+ EXPECT_EQ(0x5600U, fdes[3]->cfa_instructions_end);
+ EXPECT_EQ(0x4500U, fdes[3]->pc_start);
+ EXPECT_EQ(0x4a00U, fdes[3]->pc_end);
+ EXPECT_EQ(0U, fdes[3]->lsda_address);
+ EXPECT_TRUE(fdes[3]->cie != nullptr);
+}
+
+TYPED_TEST_P(DwarfDebugFrameTest, GetFdes64_after_GetFdeFromPc) {
+ SetFourFdes64(&this->memory_);
+ ASSERT_TRUE(this->debug_frame_->Init(0x5000, 0x600, 0));
+
+ const DwarfFde* fde = this->debug_frame_->GetFdeFromPc(0x2600);
+ ASSERT_TRUE(fde != nullptr);
+ EXPECT_EQ(0x2500U, fde->pc_start);
+ EXPECT_EQ(0x2800U, fde->pc_end);
+
+ std::vector<const DwarfFde*> fdes;
+ this->debug_frame_->GetFdes(&fdes);
+ ASSERT_EQ(4U, fdes.size());
+
+ // Verify that they got added in the correct order.
+ EXPECT_EQ(0x1500U, fdes[0]->pc_start);
+ EXPECT_EQ(0x1700U, fdes[0]->pc_end);
+ EXPECT_EQ(0x2500U, fdes[1]->pc_start);
+ EXPECT_EQ(0x2800U, fdes[1]->pc_end);
+ EXPECT_EQ(0x3500U, fdes[2]->pc_start);
+ EXPECT_EQ(0x3900U, fdes[2]->pc_end);
+ EXPECT_EQ(0x4500U, fdes[3]->pc_start);
+ EXPECT_EQ(0x4a00U, fdes[3]->pc_end);
+}
+
+TYPED_TEST_P(DwarfDebugFrameTest, GetFdes64_not_in_section) {
+ SetFourFdes64(&this->memory_);
+ ASSERT_TRUE(this->debug_frame_->Init(0x5000, 0x500, 0));
+
+ std::vector<const DwarfFde*> fdes;
+ this->debug_frame_->GetFdes(&fdes);
+
+ ASSERT_EQ(3U, fdes.size());
+}
+
+TYPED_TEST_P(DwarfDebugFrameTest, GetFdeFromPc64) {
+ SetFourFdes64(&this->memory_);
+ ASSERT_TRUE(this->debug_frame_->Init(0x5000, 0x600, 0));
+
+ const DwarfFde* fde = this->debug_frame_->GetFdeFromPc(0x1600);
+ ASSERT_TRUE(fde != nullptr);
+ EXPECT_EQ(0x1500U, fde->pc_start);
+
+ fde = this->debug_frame_->GetFdeFromPc(0x2600);
+ ASSERT_TRUE(fde != nullptr);
+ EXPECT_EQ(0x2500U, fde->pc_start);
+
+ fde = this->debug_frame_->GetFdeFromPc(0x3600);
+ ASSERT_TRUE(fde != nullptr);
+ EXPECT_EQ(0x3500U, fde->pc_start);
+
+ fde = this->debug_frame_->GetFdeFromPc(0x4600);
+ ASSERT_TRUE(fde != nullptr);
+ EXPECT_EQ(0x4500U, fde->pc_start);
+
+ fde = this->debug_frame_->GetFdeFromPc(0);
+ ASSERT_TRUE(fde == nullptr);
+}
+
+TYPED_TEST_P(DwarfDebugFrameTest, GetFdeFromPc64_reverse) {
+ SetFourFdes64(&this->memory_);
+ ASSERT_TRUE(this->debug_frame_->Init(0x5000, 0x600, 0));
+
+ const DwarfFde* fde = this->debug_frame_->GetFdeFromPc(0x4600);
+ ASSERT_TRUE(fde != nullptr);
+ EXPECT_EQ(0x4500U, fde->pc_start);
+
+ fde = this->debug_frame_->GetFdeFromPc(0x3600);
+ ASSERT_TRUE(fde != nullptr);
+ EXPECT_EQ(0x3500U, fde->pc_start);
+
+ fde = this->debug_frame_->GetFdeFromPc(0x2600);
+ ASSERT_TRUE(fde != nullptr);
+ EXPECT_EQ(0x2500U, fde->pc_start);
+
+ fde = this->debug_frame_->GetFdeFromPc(0x1600);
+ ASSERT_TRUE(fde != nullptr);
+ EXPECT_EQ(0x1500U, fde->pc_start);
+
+ fde = this->debug_frame_->GetFdeFromPc(0);
+ ASSERT_TRUE(fde == nullptr);
+}
+
+TYPED_TEST_P(DwarfDebugFrameTest, GetFdeFromPc64_not_in_section) {
+ SetFourFdes64(&this->memory_);
+ ASSERT_TRUE(this->debug_frame_->Init(0x5000, 0x500, 0));
+
+ const DwarfFde* fde = this->debug_frame_->GetFdeFromPc(0x4600);
+ ASSERT_TRUE(fde == nullptr);
}
TYPED_TEST_P(DwarfDebugFrameTest, GetCieFde32) {
- this->debug_frame_->TestSetOffset(0x4000);
-
- // CIE 32 information.
- this->memory_.SetData32(0xf000, 0x100);
- this->memory_.SetData32(0xf004, 0xffffffff);
- this->memory_.SetData8(0xf008, 0x1);
- this->memory_.SetData8(0xf009, '\0');
- this->memory_.SetData8(0xf00a, 4);
- this->memory_.SetData8(0xf00b, 8);
- this->memory_.SetData8(0xf00c, 0x20);
-
- // FDE 32 information.
- this->memory_.SetData32(0x14000, 0x20);
- this->memory_.SetData32(0x14004, 0xb000);
- this->memory_.SetData32(0x14008, 0x9000);
- this->memory_.SetData32(0x1400c, 0x100);
+ SetCie32(&this->memory_, 0xf000, 0x100, std::vector<uint8_t>{1, '\0', 4, 8, 0x20});
+ SetFde32(&this->memory_, 0x14000, 0x20, 0xf000, 0x9000, 0x100);
const DwarfFde* fde = this->debug_frame_->GetFdeFromOffset(0x14000);
ASSERT_TRUE(fde != nullptr);
@@ -530,24 +428,8 @@
}
TYPED_TEST_P(DwarfDebugFrameTest, GetCieFde64) {
- this->debug_frame_->TestSetOffset(0x2000);
-
- // CIE 64 information.
- this->memory_.SetData32(0x6000, 0xffffffff);
- this->memory_.SetData64(0x6004, 0x100);
- this->memory_.SetData64(0x600c, 0xffffffffffffffffULL);
- this->memory_.SetData8(0x6014, 0x1);
- this->memory_.SetData8(0x6015, '\0');
- this->memory_.SetData8(0x6016, 4);
- this->memory_.SetData8(0x6017, 8);
- this->memory_.SetData8(0x6018, 0x20);
-
- // FDE 64 information.
- this->memory_.SetData32(0x8000, 0xffffffff);
- this->memory_.SetData64(0x8004, 0x200);
- this->memory_.SetData64(0x800c, 0x4000);
- this->memory_.SetData64(0x8014, 0x5000);
- this->memory_.SetData64(0x801c, 0x300);
+ SetCie64(&this->memory_, 0x6000, 0x100, std::vector<uint8_t>{1, '\0', 4, 8, 0x20});
+ SetFde64(&this->memory_, 0x8000, 0x200, 0x6000, 0x5000, 0x300);
const DwarfFde* fde = this->debug_frame_->GetFdeFromOffset(0x8000);
ASSERT_TRUE(fde != nullptr);
@@ -573,11 +455,357 @@
EXPECT_EQ(0x20U, fde->cie->return_address_register);
}
-REGISTER_TYPED_TEST_CASE_P(DwarfDebugFrameTest, Init32, Init32_fde_not_following_cie,
- Init32_do_not_fail_on_bad_next_entry, Init64,
- Init64_do_not_fail_on_bad_next_entry, Init64_fde_not_following_cie,
- Init_non_zero_load_bias, Init_version1, Init_version4,
- GetFdeOffsetFromPc, GetCieFde32, GetCieFde64);
+static void VerifyCieVersion(const DwarfCie* cie, uint8_t version, uint8_t segment_size,
+ uint8_t fde_encoding, uint64_t return_address, uint64_t start_offset,
+ uint64_t end_offset) {
+ EXPECT_EQ(version, cie->version);
+ EXPECT_EQ(fde_encoding, cie->fde_address_encoding);
+ EXPECT_EQ(DW_EH_PE_omit, cie->lsda_encoding);
+ EXPECT_EQ(segment_size, cie->segment_size);
+ EXPECT_EQ(1U, cie->augmentation_string.size());
+ EXPECT_EQ('\0', cie->augmentation_string[0]);
+ EXPECT_EQ(0U, cie->personality_handler);
+ EXPECT_EQ(4U, cie->code_alignment_factor);
+ EXPECT_EQ(8, cie->data_alignment_factor);
+ EXPECT_EQ(return_address, cie->return_address_register);
+ EXPECT_EQ(0x5000U + start_offset, cie->cfa_instructions_offset);
+ EXPECT_EQ(0x5000U + end_offset, cie->cfa_instructions_end);
+}
+
+TYPED_TEST_P(DwarfDebugFrameTest, GetCieFromOffset32_cie_cached) {
+ SetCie32(&this->memory_, 0x5000, 0x100, std::vector<uint8_t>{1, '\0', 4, 8, 0x20});
+ const DwarfCie* cie = this->debug_frame_->GetCieFromOffset(0x5000);
+ EXPECT_EQ(DWARF_ERROR_NONE, this->debug_frame_->LastErrorCode());
+ ASSERT_TRUE(cie != nullptr);
+ VerifyCieVersion(cie, 1, 0, DW_EH_PE_sdata4, 0x20, 0xd, 0x104);
+
+ std::vector<uint8_t> zero(0x100, 0);
+ this->memory_.SetMemory(0x5000, zero);
+ cie = this->debug_frame_->GetCieFromOffset(0x5000);
+ EXPECT_EQ(DWARF_ERROR_NONE, this->debug_frame_->LastErrorCode());
+ ASSERT_TRUE(cie != nullptr);
+ VerifyCieVersion(cie, 1, 0, DW_EH_PE_sdata4, 0x20, 0xd, 0x104);
+}
+
+TYPED_TEST_P(DwarfDebugFrameTest, GetCieFromOffset64_cie_cached) {
+ SetCie64(&this->memory_, 0x5000, 0x100, std::vector<uint8_t>{1, '\0', 4, 8, 0x20});
+ const DwarfCie* cie = this->debug_frame_->GetCieFromOffset(0x5000);
+ EXPECT_EQ(DWARF_ERROR_NONE, this->debug_frame_->LastErrorCode());
+ ASSERT_TRUE(cie != nullptr);
+ VerifyCieVersion(cie, 1, 0, DW_EH_PE_sdata8, 0x20, 0x19, 0x10c);
+
+ std::vector<uint8_t> zero(0x100, 0);
+ this->memory_.SetMemory(0x5000, zero);
+ cie = this->debug_frame_->GetCieFromOffset(0x5000);
+ EXPECT_EQ(DWARF_ERROR_NONE, this->debug_frame_->LastErrorCode());
+ ASSERT_TRUE(cie != nullptr);
+ VerifyCieVersion(cie, 1, 0, DW_EH_PE_sdata8, 0x20, 0x19, 0x10c);
+}
+
+TYPED_TEST_P(DwarfDebugFrameTest, GetCieFromOffset32_version1) {
+ SetCie32(&this->memory_, 0x5000, 0x100, std::vector<uint8_t>{1, '\0', 4, 8, 0x20});
+ const DwarfCie* cie = this->debug_frame_->GetCieFromOffset(0x5000);
+ EXPECT_EQ(DWARF_ERROR_NONE, this->debug_frame_->LastErrorCode());
+ ASSERT_TRUE(cie != nullptr);
+ VerifyCieVersion(cie, 1, 0, DW_EH_PE_sdata4, 0x20, 0xd, 0x104);
+}
+
+TYPED_TEST_P(DwarfDebugFrameTest, GetCieFromOffset64_version1) {
+ SetCie64(&this->memory_, 0x5000, 0x100, std::vector<uint8_t>{1, '\0', 4, 8, 0x20});
+ const DwarfCie* cie = this->debug_frame_->GetCieFromOffset(0x5000);
+ EXPECT_EQ(DWARF_ERROR_NONE, this->debug_frame_->LastErrorCode());
+ ASSERT_TRUE(cie != nullptr);
+ VerifyCieVersion(cie, 1, 0, DW_EH_PE_sdata8, 0x20, 0x19, 0x10c);
+}
+
+TYPED_TEST_P(DwarfDebugFrameTest, GetCieFromOffset32_version3) {
+ SetCie32(&this->memory_, 0x5000, 0x100, std::vector<uint8_t>{3, '\0', 4, 8, 0x81, 3});
+ const DwarfCie* cie = this->debug_frame_->GetCieFromOffset(0x5000);
+ EXPECT_EQ(DWARF_ERROR_NONE, this->debug_frame_->LastErrorCode());
+ ASSERT_TRUE(cie != nullptr);
+ VerifyCieVersion(cie, 3, 0, DW_EH_PE_sdata4, 0x181, 0xe, 0x104);
+}
+
+TYPED_TEST_P(DwarfDebugFrameTest, GetCieFromOffset64_version3) {
+ SetCie64(&this->memory_, 0x5000, 0x100, std::vector<uint8_t>{3, '\0', 4, 8, 0x81, 3});
+ const DwarfCie* cie = this->debug_frame_->GetCieFromOffset(0x5000);
+ EXPECT_EQ(DWARF_ERROR_NONE, this->debug_frame_->LastErrorCode());
+ ASSERT_TRUE(cie != nullptr);
+ VerifyCieVersion(cie, 3, 0, DW_EH_PE_sdata8, 0x181, 0x1a, 0x10c);
+}
+
+TYPED_TEST_P(DwarfDebugFrameTest, GetCieFromOffset32_version4) {
+ SetCie32(&this->memory_, 0x5000, 0x100, std::vector<uint8_t>{4, '\0', 0, 10, 4, 8, 0x81, 3});
+ const DwarfCie* cie = this->debug_frame_->GetCieFromOffset(0x5000);
+ EXPECT_EQ(DWARF_ERROR_NONE, this->debug_frame_->LastErrorCode());
+ ASSERT_TRUE(cie != nullptr);
+ VerifyCieVersion(cie, 4, 10, DW_EH_PE_sdata4, 0x181, 0x10, 0x104);
+}
+
+TYPED_TEST_P(DwarfDebugFrameTest, GetCieFromOffset64_version4) {
+ SetCie64(&this->memory_, 0x5000, 0x100, std::vector<uint8_t>{4, '\0', 0, 10, 4, 8, 0x81, 3});
+ const DwarfCie* cie = this->debug_frame_->GetCieFromOffset(0x5000);
+ EXPECT_EQ(DWARF_ERROR_NONE, this->debug_frame_->LastErrorCode());
+ ASSERT_TRUE(cie != nullptr);
+ VerifyCieVersion(cie, 4, 10, DW_EH_PE_sdata8, 0x181, 0x1c, 0x10c);
+}
+
+TYPED_TEST_P(DwarfDebugFrameTest, GetCieFromOffset_version_invalid) {
+ SetCie32(&this->memory_, 0x5000, 0x100, std::vector<uint8_t>{0, '\0', 1, 2, 3, 4, 5, 6, 7});
+ ASSERT_TRUE(this->debug_frame_->GetCieFromOffset(0x5000) == nullptr);
+ EXPECT_EQ(DWARF_ERROR_UNSUPPORTED_VERSION, this->debug_frame_->LastErrorCode());
+ SetCie64(&this->memory_, 0x6000, 0x100, std::vector<uint8_t>{0, '\0', 1, 2, 3, 4, 5, 6, 7});
+ ASSERT_TRUE(this->debug_frame_->GetCieFromOffset(0x6000) == nullptr);
+ EXPECT_EQ(DWARF_ERROR_UNSUPPORTED_VERSION, this->debug_frame_->LastErrorCode());
+
+ SetCie32(&this->memory_, 0x7000, 0x100, std::vector<uint8_t>{5, '\0', 1, 2, 3, 4, 5, 6, 7});
+ ASSERT_TRUE(this->debug_frame_->GetCieFromOffset(0x7000) == nullptr);
+ EXPECT_EQ(DWARF_ERROR_UNSUPPORTED_VERSION, this->debug_frame_->LastErrorCode());
+ SetCie64(&this->memory_, 0x8000, 0x100, std::vector<uint8_t>{5, '\0', 1, 2, 3, 4, 5, 6, 7});
+ ASSERT_TRUE(this->debug_frame_->GetCieFromOffset(0x8000) == nullptr);
+ EXPECT_EQ(DWARF_ERROR_UNSUPPORTED_VERSION, this->debug_frame_->LastErrorCode());
+}
+
+static void VerifyCieAugment(const DwarfCie* cie, uint64_t inst_offset, uint64_t inst_end) {
+ EXPECT_EQ(1U, cie->version);
+ EXPECT_EQ(DW_EH_PE_udata2, cie->fde_address_encoding);
+ EXPECT_EQ(DW_EH_PE_textrel | DW_EH_PE_udata2, cie->lsda_encoding);
+ EXPECT_EQ(0U, cie->segment_size);
+ EXPECT_EQ(5U, cie->augmentation_string.size());
+ EXPECT_EQ('z', cie->augmentation_string[0]);
+ EXPECT_EQ('L', cie->augmentation_string[1]);
+ EXPECT_EQ('P', cie->augmentation_string[2]);
+ EXPECT_EQ('R', cie->augmentation_string[3]);
+ EXPECT_EQ('\0', cie->augmentation_string[4]);
+ EXPECT_EQ(0x12345678U, cie->personality_handler);
+ EXPECT_EQ(4U, cie->code_alignment_factor);
+ EXPECT_EQ(8, cie->data_alignment_factor);
+ EXPECT_EQ(0x10U, cie->return_address_register);
+ EXPECT_EQ(inst_offset, cie->cfa_instructions_offset);
+ EXPECT_EQ(inst_end, cie->cfa_instructions_end);
+}
+
+TYPED_TEST_P(DwarfDebugFrameTest, GetCieFromOffset32_augment) {
+ SetCie32(&this->memory_, 0x5000, 0x100,
+ std::vector<uint8_t>{/* version */ 1,
+ /* augment string */ 'z', 'L', 'P', 'R', '\0',
+ /* code alignment factor */ 4,
+ /* data alignment factor */ 8,
+ /* return address register */ 0x10,
+ /* augment length */ 0xf,
+ /* L data */ DW_EH_PE_textrel | DW_EH_PE_udata2,
+ /* P data */ DW_EH_PE_udata4, 0x78, 0x56, 0x34, 0x12,
+ /* R data */ DW_EH_PE_udata2});
+
+ const DwarfCie* cie = this->debug_frame_->GetCieFromOffset(0x5000);
+ ASSERT_TRUE(cie != nullptr);
+ VerifyCieAugment(cie, 0x5021, 0x5104);
+}
+
+TYPED_TEST_P(DwarfDebugFrameTest, GetCieFromOffset64_augment) {
+ SetCie64(&this->memory_, 0x5000, 0x100,
+ std::vector<uint8_t>{/* version */ 1,
+ /* augment string */ 'z', 'L', 'P', 'R', '\0',
+ /* code alignment factor */ 4,
+ /* data alignment factor */ 8,
+ /* return address register */ 0x10,
+ /* augment length */ 0xf,
+ /* L data */ DW_EH_PE_textrel | DW_EH_PE_udata2,
+ /* P data */ DW_EH_PE_udata4, 0x78, 0x56, 0x34, 0x12,
+ /* R data */ DW_EH_PE_udata2});
+
+ const DwarfCie* cie = this->debug_frame_->GetCieFromOffset(0x5000);
+ ASSERT_TRUE(cie != nullptr);
+ VerifyCieAugment(cie, 0x502d, 0x510c);
+}
+
+TYPED_TEST_P(DwarfDebugFrameTest, GetFdeFromOffset32_augment) {
+ SetCie32(&this->memory_, 0x5000, 0xfc,
+ std::vector<uint8_t>{/* version */ 4,
+ /* augment string */ 'z', '\0',
+ /* address size */ 8,
+ /* segment size */ 0x10,
+ /* code alignment factor */ 16,
+ /* data alignment factor */ 32,
+ /* return address register */ 10,
+ /* augment length */ 0x0});
+
+ std::vector<uint8_t> data{/* augment length */ 0x80, 0x3};
+ SetFde32(&this->memory_, 0x5200, 0x300, 0x5000, 0x4300, 0x300, 0x10, &data);
+
+ const DwarfFde* fde = this->debug_frame_->GetFdeFromOffset(0x5200);
+ ASSERT_TRUE(fde != nullptr);
+ ASSERT_TRUE(fde->cie != nullptr);
+ EXPECT_EQ(4U, fde->cie->version);
+ EXPECT_EQ(0x5000U, fde->cie_offset);
+ EXPECT_EQ(0x53a2U, fde->cfa_instructions_offset);
+ EXPECT_EQ(0x5504U, fde->cfa_instructions_end);
+ EXPECT_EQ(0x4300U, fde->pc_start);
+ EXPECT_EQ(0x4600U, fde->pc_end);
+ EXPECT_EQ(0U, fde->lsda_address);
+}
+
+TYPED_TEST_P(DwarfDebugFrameTest, GetFdeFromOffset64_augment) {
+ SetCie64(&this->memory_, 0x5000, 0xfc,
+ std::vector<uint8_t>{/* version */ 4,
+ /* augment string */ 'z', '\0',
+ /* address size */ 8,
+ /* segment size */ 0x10,
+ /* code alignment factor */ 16,
+ /* data alignment factor */ 32,
+ /* return address register */ 10,
+ /* augment length */ 0x0});
+
+ std::vector<uint8_t> data{/* augment length */ 0x80, 0x3};
+ SetFde64(&this->memory_, 0x5200, 0x300, 0x5000, 0x4300, 0x300, 0x10, &data);
+
+ const DwarfFde* fde = this->debug_frame_->GetFdeFromOffset(0x5200);
+ ASSERT_TRUE(fde != nullptr);
+ ASSERT_TRUE(fde->cie != nullptr);
+ EXPECT_EQ(4U, fde->cie->version);
+ EXPECT_EQ(0x5000U, fde->cie_offset);
+ EXPECT_EQ(0x53b6U, fde->cfa_instructions_offset);
+ EXPECT_EQ(0x550cU, fde->cfa_instructions_end);
+ EXPECT_EQ(0x4300U, fde->pc_start);
+ EXPECT_EQ(0x4600U, fde->pc_end);
+ EXPECT_EQ(0U, fde->lsda_address);
+}
+
+TYPED_TEST_P(DwarfDebugFrameTest, GetFdeFromOffset32_lsda_address) {
+ SetCie32(&this->memory_, 0x5000, 0xfc,
+ std::vector<uint8_t>{/* version */ 1,
+ /* augment string */ 'z', 'L', '\0',
+ /* address size */ 8,
+ /* code alignment factor */ 16,
+ /* data alignment factor */ 32,
+ /* return address register */ 10,
+ /* augment length */ 0x2,
+ /* L data */ DW_EH_PE_udata2});
+
+ std::vector<uint8_t> data{/* augment length */ 0x80, 0x3,
+ /* lsda address */ 0x20, 0x45};
+ SetFde32(&this->memory_, 0x5200, 0x300, 0x5000, 0x4300, 0x300, 0, &data);
+
+ const DwarfFde* fde = this->debug_frame_->GetFdeFromOffset(0x5200);
+ ASSERT_TRUE(fde != nullptr);
+ ASSERT_TRUE(fde->cie != nullptr);
+ EXPECT_EQ(1U, fde->cie->version);
+ EXPECT_EQ(0x5000U, fde->cie_offset);
+ EXPECT_EQ(0x5392U, fde->cfa_instructions_offset);
+ EXPECT_EQ(0x5504U, fde->cfa_instructions_end);
+ EXPECT_EQ(0x4300U, fde->pc_start);
+ EXPECT_EQ(0x4600U, fde->pc_end);
+ EXPECT_EQ(0x4520U, fde->lsda_address);
+}
+
+TYPED_TEST_P(DwarfDebugFrameTest, GetFdeFromOffset64_lsda_address) {
+ SetCie64(&this->memory_, 0x5000, 0xfc,
+ std::vector<uint8_t>{/* version */ 1,
+ /* augment string */ 'z', 'L', '\0',
+ /* address size */ 8,
+ /* code alignment factor */ 16,
+ /* data alignment factor */ 32,
+ /* return address register */ 10,
+ /* augment length */ 0x2,
+ /* L data */ DW_EH_PE_udata2});
+
+ std::vector<uint8_t> data{/* augment length */ 0x80, 0x3,
+ /* lsda address */ 0x20, 0x45};
+ SetFde64(&this->memory_, 0x5200, 0x300, 0x5000, 0x4300, 0x300, 0, &data);
+
+ const DwarfFde* fde = this->debug_frame_->GetFdeFromOffset(0x5200);
+ ASSERT_TRUE(fde != nullptr);
+ ASSERT_TRUE(fde->cie != nullptr);
+ EXPECT_EQ(1U, fde->cie->version);
+ EXPECT_EQ(0x5000U, fde->cie_offset);
+ EXPECT_EQ(0x53a6U, fde->cfa_instructions_offset);
+ EXPECT_EQ(0x550cU, fde->cfa_instructions_end);
+ EXPECT_EQ(0x4300U, fde->pc_start);
+ EXPECT_EQ(0x4600U, fde->pc_end);
+ EXPECT_EQ(0x4520U, fde->lsda_address);
+}
+
+TYPED_TEST_P(DwarfDebugFrameTest, GetFdeFromPc_interleaved) {
+ SetCie32(&this->memory_, 0x5000, 0xfc, std::vector<uint8_t>{1, '\0', 0, 0, 1});
+
+ // FDE 0 (0x100 - 0x200)
+ SetFde32(&this->memory_, 0x5100, 0xfc, 0, 0x100, 0x100);
+ // FDE 1 (0x300 - 0x500)
+ SetFde32(&this->memory_, 0x5200, 0xfc, 0, 0x300, 0x200);
+ // FDE 2 (0x700 - 0x800)
+ SetFde32(&this->memory_, 0x5300, 0xfc, 0, 0x700, 0x100);
+ // FDE 3 (0xa00 - 0xb00)
+ SetFde32(&this->memory_, 0x5400, 0xfc, 0, 0xa00, 0x100);
+ // FDE 4 (0x100 - 0xb00)
+ SetFde32(&this->memory_, 0x5500, 0xfc, 0, 0x150, 0xa00);
+ // FDE 5 (0x0 - 0x50)
+ SetFde32(&this->memory_, 0x5600, 0xfc, 0, 0, 0x50);
+
+ this->debug_frame_->Init(0x5000, 0x700, 0);
+
+ // Force reading all entries so no entries are found.
+ const DwarfFde* fde = this->debug_frame_->GetFdeFromPc(0xfffff);
+ ASSERT_TRUE(fde == nullptr);
+
+ // 0x0 - 0x50 FDE 5
+ fde = this->debug_frame_->GetFdeFromPc(0x10);
+ ASSERT_TRUE(fde != nullptr);
+ EXPECT_EQ(0U, fde->pc_start);
+ EXPECT_EQ(0x50U, fde->pc_end);
+
+ // 0x100 - 0x200 FDE 0
+ fde = this->debug_frame_->GetFdeFromPc(0x170);
+ ASSERT_TRUE(fde != nullptr);
+ EXPECT_EQ(0x100U, fde->pc_start);
+ EXPECT_EQ(0x200U, fde->pc_end);
+
+ // 0x200 - 0x300 FDE 4
+ fde = this->debug_frame_->GetFdeFromPc(0x210);
+ ASSERT_TRUE(fde != nullptr);
+ EXPECT_EQ(0x150U, fde->pc_start);
+ EXPECT_EQ(0xb50U, fde->pc_end);
+
+ // 0x300 - 0x500 FDE 1
+ fde = this->debug_frame_->GetFdeFromPc(0x310);
+ ASSERT_TRUE(fde != nullptr);
+ EXPECT_EQ(0x300U, fde->pc_start);
+ EXPECT_EQ(0x500U, fde->pc_end);
+
+ // 0x700 - 0x800 FDE 2
+ fde = this->debug_frame_->GetFdeFromPc(0x790);
+ ASSERT_TRUE(fde != nullptr);
+ EXPECT_EQ(0x700U, fde->pc_start);
+ EXPECT_EQ(0x800U, fde->pc_end);
+
+ // 0x800 - 0x900 FDE 4
+ fde = this->debug_frame_->GetFdeFromPc(0x850);
+ ASSERT_TRUE(fde != nullptr);
+ EXPECT_EQ(0x150U, fde->pc_start);
+ EXPECT_EQ(0xb50U, fde->pc_end);
+
+ // 0xa00 - 0xb00 FDE 3
+ fde = this->debug_frame_->GetFdeFromPc(0xa35);
+ ASSERT_TRUE(fde != nullptr);
+ EXPECT_EQ(0xa00U, fde->pc_start);
+ EXPECT_EQ(0xb00U, fde->pc_end);
+
+ // 0xb00 - 0xb50 FDE 4
+ fde = this->debug_frame_->GetFdeFromPc(0xb20);
+ ASSERT_TRUE(fde != nullptr);
+ EXPECT_EQ(0x150U, fde->pc_start);
+ EXPECT_EQ(0xb50U, fde->pc_end);
+}
+
+REGISTER_TYPED_TEST_CASE_P(
+ DwarfDebugFrameTest, GetFdes32, GetFdes32_after_GetFdeFromPc, GetFdes32_not_in_section,
+ GetFdeFromPc32, GetFdeFromPc32_reverse, GetFdeFromPc32_not_in_section, GetFdes64,
+ GetFdes64_after_GetFdeFromPc, GetFdes64_not_in_section, GetFdeFromPc64, GetFdeFromPc64_reverse,
+ GetFdeFromPc64_not_in_section, GetCieFde32, GetCieFde64, GetCieFromOffset32_cie_cached,
+ GetCieFromOffset64_cie_cached, GetCieFromOffset32_version1, GetCieFromOffset64_version1,
+ GetCieFromOffset32_version3, GetCieFromOffset64_version3, GetCieFromOffset32_version4,
+ GetCieFromOffset64_version4, GetCieFromOffset_version_invalid, GetCieFromOffset32_augment,
+ GetCieFromOffset64_augment, GetFdeFromOffset32_augment, GetFdeFromOffset64_augment,
+ GetFdeFromOffset32_lsda_address, GetFdeFromOffset64_lsda_address, GetFdeFromPc_interleaved);
typedef ::testing::Types<uint32_t, uint64_t> DwarfDebugFrameTestTypes;
INSTANTIATE_TYPED_TEST_CASE_P(, DwarfDebugFrameTest, DwarfDebugFrameTestTypes);
diff --git a/libunwindstack/tests/DwarfEhFrameTest.cpp b/libunwindstack/tests/DwarfEhFrameTest.cpp
index e8d53e6..9cac6e8 100644
--- a/libunwindstack/tests/DwarfEhFrameTest.cpp
+++ b/libunwindstack/tests/DwarfEhFrameTest.cpp
@@ -16,7 +16,6 @@
#include <stdint.h>
-#include <gmock/gmock.h>
#include <gtest/gtest.h>
#include <unwindstack/DwarfError.h>
@@ -30,50 +29,32 @@
namespace unwindstack {
template <typename TypeParam>
-class MockDwarfEhFrame : public DwarfEhFrame<TypeParam> {
- public:
- MockDwarfEhFrame(Memory* memory) : DwarfEhFrame<TypeParam>(memory) {}
- ~MockDwarfEhFrame() = default;
-
- void TestSetFdeCount(uint64_t count) { this->fde_count_ = count; }
- void TestSetOffset(uint64_t offset) { this->entries_offset_ = offset; }
- void TestSetEndOffset(uint64_t offset) { this->entries_end_ = offset; }
- void TestPushFdeInfo(const typename DwarfEhFrame<TypeParam>::FdeInfo& info) {
- this->fdes_.push_back(info);
- }
-
- uint64_t TestGetFdeCount() { return this->fde_count_; }
- uint8_t TestGetOffset() { return this->offset_; }
- uint8_t TestGetEndOffset() { return this->end_offset_; }
- void TestGetFdeInfo(size_t index, typename DwarfEhFrame<TypeParam>::FdeInfo* info) {
- *info = this->fdes_[index];
- }
-};
-
-template <typename TypeParam>
class DwarfEhFrameTest : public ::testing::Test {
protected:
void SetUp() override {
memory_.Clear();
- eh_frame_ = new MockDwarfEhFrame<TypeParam>(&memory_);
+ eh_frame_ = new DwarfEhFrame<TypeParam>(&memory_);
ResetLogs();
}
void TearDown() override { delete eh_frame_; }
MemoryFake memory_;
- MockDwarfEhFrame<TypeParam>* eh_frame_ = nullptr;
+ DwarfEhFrame<TypeParam>* eh_frame_ = nullptr;
};
TYPED_TEST_CASE_P(DwarfEhFrameTest);
// NOTE: All test class variables need to be referenced as this->.
-TYPED_TEST_P(DwarfEhFrameTest, Init32) {
+// Only verify different cie/fde format. All other DwarfSection corner
+// cases are tested in DwarfDebugFrameTest.cpp.
+
+TYPED_TEST_P(DwarfEhFrameTest, GetFdeCieFromOffset32) {
// CIE 32 information.
this->memory_.SetData32(0x5000, 0xfc);
+ // Indicates this is a cie for eh_frame.
this->memory_.SetData32(0x5004, 0);
- this->memory_.SetData8(0x5008, 1);
- this->memory_.SetData8(0x5009, '\0');
+ this->memory_.SetMemory(0x5008, std::vector<uint8_t>{1, '\0', 16, 32, 1});
// FDE 32 information.
this->memory_.SetData32(0x5100, 0xfc);
@@ -81,415 +62,70 @@
this->memory_.SetData32(0x5108, 0x1500);
this->memory_.SetData32(0x510c, 0x200);
- this->memory_.SetData32(0x5200, 0xfc);
- this->memory_.SetData32(0x5204, 0x204);
- this->memory_.SetData32(0x5208, 0x2500);
- this->memory_.SetData32(0x520c, 0x300);
+ const DwarfFde* fde = this->eh_frame_->GetFdeFromOffset(0x5100);
+ ASSERT_TRUE(fde != nullptr);
+ EXPECT_EQ(0x5000U, fde->cie_offset);
+ EXPECT_EQ(0x5110U, fde->cfa_instructions_offset);
+ EXPECT_EQ(0x5200U, fde->cfa_instructions_end);
+ EXPECT_EQ(0x6608U, fde->pc_start);
+ EXPECT_EQ(0x6808U, fde->pc_end);
+ EXPECT_EQ(0U, fde->lsda_address);
- // CIE 32 information.
- this->memory_.SetData32(0x5300, 0xfc);
- this->memory_.SetData32(0x5304, 0);
- this->memory_.SetData8(0x5308, 1);
- this->memory_.SetData8(0x5309, '\0');
-
- // FDE 32 information.
- this->memory_.SetData32(0x5400, 0xfc);
- this->memory_.SetData32(0x5404, 0x104);
- this->memory_.SetData32(0x5408, 0x3500);
- this->memory_.SetData32(0x540c, 0x400);
-
- this->memory_.SetData32(0x5500, 0xfc);
- this->memory_.SetData32(0x5504, 0x204);
- this->memory_.SetData32(0x5508, 0x4500);
- this->memory_.SetData32(0x550c, 0x500);
-
- ASSERT_TRUE(this->eh_frame_->Init(0x5000, 0x600, 0));
- ASSERT_EQ(4U, this->eh_frame_->TestGetFdeCount());
-
- typename DwarfEhFrame<TypeParam>::FdeInfo info(0, 0, 0);
-
- this->eh_frame_->TestGetFdeInfo(0, &info);
- EXPECT_EQ(0x5100U, info.offset);
- EXPECT_EQ(0x6608U, info.start);
- EXPECT_EQ(0x6808U, info.end);
-
- this->eh_frame_->TestGetFdeInfo(1, &info);
- EXPECT_EQ(0x5200U, info.offset);
- EXPECT_EQ(0x7708U, info.start);
- EXPECT_EQ(0x7a08U, info.end);
-
- this->eh_frame_->TestGetFdeInfo(2, &info);
- EXPECT_EQ(0x5400U, info.offset);
- EXPECT_EQ(0x8908U, info.start);
- EXPECT_EQ(0x8d08U, info.end);
-
- this->eh_frame_->TestGetFdeInfo(3, &info);
- EXPECT_EQ(0x5500U, info.offset);
- EXPECT_EQ(0x9a08U, info.start);
- EXPECT_EQ(0x9f08U, info.end);
+ const DwarfCie* cie = fde->cie;
+ ASSERT_TRUE(cie != nullptr);
+ EXPECT_EQ(1U, cie->version);
+ EXPECT_EQ(DW_EH_PE_sdata4, cie->fde_address_encoding);
+ EXPECT_EQ(DW_EH_PE_omit, cie->lsda_encoding);
+ EXPECT_EQ(0U, cie->segment_size);
+ EXPECT_EQ('\0', cie->augmentation_string[0]);
+ EXPECT_EQ(0U, cie->personality_handler);
+ EXPECT_EQ(0x500dU, cie->cfa_instructions_offset);
+ EXPECT_EQ(0x5100U, cie->cfa_instructions_end);
+ EXPECT_EQ(16U, cie->code_alignment_factor);
+ EXPECT_EQ(32U, cie->data_alignment_factor);
+ EXPECT_EQ(1U, cie->return_address_register);
}
-TYPED_TEST_P(DwarfEhFrameTest, Init32_fde_not_following_cie) {
- // CIE 32 information.
- this->memory_.SetData32(0x5000, 0xfc);
- this->memory_.SetData32(0x5004, 0);
- this->memory_.SetData8(0x5008, 1);
- this->memory_.SetData8(0x5009, '\0');
-
- // FDE 32 information.
- this->memory_.SetData32(0x5100, 0xfc);
- this->memory_.SetData32(0x5104, 0x1000);
- this->memory_.SetData32(0x5108, 0x1500);
- this->memory_.SetData32(0x510c, 0x200);
-
- ASSERT_FALSE(this->eh_frame_->Init(0x5000, 0x600, 0));
- ASSERT_EQ(DWARF_ERROR_ILLEGAL_VALUE, this->eh_frame_->LastErrorCode());
-}
-
-TYPED_TEST_P(DwarfEhFrameTest, Init64) {
+TYPED_TEST_P(DwarfEhFrameTest, GetFdeCieFromOffset64) {
// CIE 64 information.
this->memory_.SetData32(0x5000, 0xffffffff);
- this->memory_.SetData64(0x5004, 0xf4);
+ this->memory_.SetData64(0x5004, 0xfc);
+ // Indicates this is a cie for eh_frame.
this->memory_.SetData64(0x500c, 0);
- this->memory_.SetData8(0x5014, 1);
- this->memory_.SetData8(0x5015, '\0');
+ this->memory_.SetMemory(0x5014, std::vector<uint8_t>{1, '\0', 16, 32, 1});
// FDE 64 information.
this->memory_.SetData32(0x5100, 0xffffffff);
- this->memory_.SetData64(0x5104, 0xf4);
+ this->memory_.SetData64(0x5104, 0xfc);
this->memory_.SetData64(0x510c, 0x10c);
this->memory_.SetData64(0x5114, 0x1500);
this->memory_.SetData64(0x511c, 0x200);
- this->memory_.SetData32(0x5200, 0xffffffff);
- this->memory_.SetData64(0x5204, 0xf4);
- this->memory_.SetData64(0x520c, 0x20c);
- this->memory_.SetData64(0x5214, 0x2500);
- this->memory_.SetData64(0x521c, 0x300);
-
- // CIE 64 information.
- this->memory_.SetData32(0x5300, 0xffffffff);
- this->memory_.SetData64(0x5304, 0xf4);
- this->memory_.SetData64(0x530c, 0);
- this->memory_.SetData8(0x5314, 1);
- this->memory_.SetData8(0x5315, '\0');
-
- // FDE 64 information.
- this->memory_.SetData32(0x5400, 0xffffffff);
- this->memory_.SetData64(0x5404, 0xf4);
- this->memory_.SetData64(0x540c, 0x10c);
- this->memory_.SetData64(0x5414, 0x3500);
- this->memory_.SetData64(0x541c, 0x400);
-
- this->memory_.SetData32(0x5500, 0xffffffff);
- this->memory_.SetData64(0x5504, 0xf4);
- this->memory_.SetData64(0x550c, 0x20c);
- this->memory_.SetData64(0x5514, 0x4500);
- this->memory_.SetData64(0x551c, 0x500);
-
- ASSERT_TRUE(this->eh_frame_->Init(0x5000, 0x600, 0));
- ASSERT_EQ(4U, this->eh_frame_->TestGetFdeCount());
-
- typename DwarfEhFrame<TypeParam>::FdeInfo info(0, 0, 0);
-
- this->eh_frame_->TestGetFdeInfo(0, &info);
- EXPECT_EQ(0x5100U, info.offset);
- EXPECT_EQ(0x6618U, info.start);
- EXPECT_EQ(0x6818U, info.end);
-
- this->eh_frame_->TestGetFdeInfo(1, &info);
- EXPECT_EQ(0x5200U, info.offset);
- EXPECT_EQ(0x7718U, info.start);
- EXPECT_EQ(0x7a18U, info.end);
-
- this->eh_frame_->TestGetFdeInfo(2, &info);
- EXPECT_EQ(0x5400U, info.offset);
- EXPECT_EQ(0x8918U, info.start);
- EXPECT_EQ(0x8d18U, info.end);
-
- this->eh_frame_->TestGetFdeInfo(3, &info);
- EXPECT_EQ(0x5500U, info.offset);
- EXPECT_EQ(0x9a18U, info.start);
- EXPECT_EQ(0x9f18U, info.end);
-}
-
-TYPED_TEST_P(DwarfEhFrameTest, Init64_fde_not_following_cie) {
- // CIE 64 information.
- this->memory_.SetData32(0x5000, 0xffffffff);
- this->memory_.SetData64(0x5004, 0xf4);
- this->memory_.SetData64(0x500c, 0);
- this->memory_.SetData8(0x5014, 1);
- this->memory_.SetData8(0x5015, '\0');
-
- // FDE 64 information.
- this->memory_.SetData32(0x5100, 0xffffffff);
- this->memory_.SetData64(0x5104, 0xf4);
- this->memory_.SetData64(0x510c, 0x1000);
- this->memory_.SetData64(0x5114, 0x1500);
- this->memory_.SetData64(0x511c, 0x200);
-
- ASSERT_FALSE(this->eh_frame_->Init(0x5000, 0x600, 0));
- ASSERT_EQ(DWARF_ERROR_ILLEGAL_VALUE, this->eh_frame_->LastErrorCode());
-}
-
-TYPED_TEST_P(DwarfEhFrameTest, Init_non_zero_load_bias) {
- // CIE 32 information.
- this->memory_.SetData32(0x5000, 0xfc);
- this->memory_.SetData32(0x5004, 0);
- this->memory_.SetData8(0x5008, 1);
- this->memory_.SetData8(0x5009, 'z');
- this->memory_.SetData8(0x500a, 'R');
- this->memory_.SetData8(0x500b, '\0');
- this->memory_.SetData8(0x500c, 0);
- this->memory_.SetData8(0x500d, 0);
- this->memory_.SetData8(0x500e, 0);
- this->memory_.SetData8(0x500f, 0);
- this->memory_.SetData8(0x5010, 0x1b);
-
- // FDE 32 information.
- this->memory_.SetData32(0x5100, 0xfc);
- this->memory_.SetData32(0x5104, 0x104);
- this->memory_.SetData32(0x5108, 0x1500);
- this->memory_.SetData32(0x510c, 0x200);
- this->memory_.SetData8(0x5110, 0);
- this->memory_.SetData8(0x5111, 0);
-
- ASSERT_TRUE(this->eh_frame_->Init(0x5000, 0x200, 0x2000));
- ASSERT_EQ(1U, this->eh_frame_->TestGetFdeCount());
-
- typename DwarfEhFrame<TypeParam>::FdeInfo info(0, 0, 0);
-
- this->eh_frame_->TestGetFdeInfo(0, &info);
- EXPECT_EQ(0x5100U, info.offset);
- EXPECT_EQ(0x8608U, info.start);
- EXPECT_EQ(0x8808U, info.end);
-
- const DwarfFde* fde = this->eh_frame_->GetFdeFromPc(0x8700);
+ const DwarfFde* fde = this->eh_frame_->GetFdeFromOffset(0x5100);
ASSERT_TRUE(fde != nullptr);
- EXPECT_EQ(0x8608U, fde->pc_start);
- EXPECT_EQ(0x8808U, fde->pc_end);
-}
-
-TYPED_TEST_P(DwarfEhFrameTest, Init_version1) {
- // CIE 32 information.
- this->memory_.SetData32(0x5000, 0xfc);
- this->memory_.SetData32(0x5004, 0);
- this->memory_.SetData8(0x5008, 1);
- // Augment string.
- this->memory_.SetMemory(0x5009, std::vector<uint8_t>{'z', 'R', 'P', 'L', '\0'});
- // Code alignment factor.
- this->memory_.SetMemory(0x500e, std::vector<uint8_t>{0x80, 0x00});
- // Data alignment factor.
- this->memory_.SetMemory(0x5010, std::vector<uint8_t>{0x81, 0x80, 0x80, 0x00});
- // Return address register
- this->memory_.SetData8(0x5014, 0x84);
- // Augmentation length
- this->memory_.SetMemory(0x5015, std::vector<uint8_t>{0x84, 0x00});
- // R data.
- this->memory_.SetData8(0x5017, DW_EH_PE_pcrel | DW_EH_PE_udata2);
-
- // FDE 32 information.
- this->memory_.SetData32(0x5100, 0xfc);
- this->memory_.SetData32(0x5104, 0x104);
- this->memory_.SetData16(0x5108, 0x1500);
- this->memory_.SetData16(0x510a, 0x200);
-
- ASSERT_TRUE(this->eh_frame_->Init(0x5000, 0x200, 0));
- ASSERT_EQ(1U, this->eh_frame_->TestGetFdeCount());
-
- typename DwarfEhFrame<TypeParam>::FdeInfo info(0, 0, 0);
- this->eh_frame_->TestGetFdeInfo(0, &info);
- EXPECT_EQ(0x5100U, info.offset);
- EXPECT_EQ(0x6606U, info.start);
- EXPECT_EQ(0x6806U, info.end);
-}
-
-TYPED_TEST_P(DwarfEhFrameTest, Init_version4) {
- // CIE 32 information.
- this->memory_.SetData32(0x5000, 0xfc);
- this->memory_.SetData32(0x5004, 0);
- this->memory_.SetData8(0x5008, 4);
- // Augment string.
- this->memory_.SetMemory(0x5009, std::vector<uint8_t>{'z', 'L', 'P', 'R', '\0'});
- // Address size.
- this->memory_.SetData8(0x500e, 4);
- // Segment size.
- this->memory_.SetData8(0x500f, 0);
- // Code alignment factor.
- this->memory_.SetMemory(0x5010, std::vector<uint8_t>{0x80, 0x00});
- // Data alignment factor.
- this->memory_.SetMemory(0x5012, std::vector<uint8_t>{0x81, 0x80, 0x80, 0x00});
- // Return address register
- this->memory_.SetMemory(0x5016, std::vector<uint8_t>{0x85, 0x10});
- // Augmentation length
- this->memory_.SetMemory(0x5018, std::vector<uint8_t>{0x84, 0x00});
- // L data.
- this->memory_.SetData8(0x501a, 0x10);
- // P data.
- this->memory_.SetData8(0x501b, DW_EH_PE_udata4);
- this->memory_.SetData32(0x501c, 0x100);
- // R data.
- this->memory_.SetData8(0x5020, DW_EH_PE_pcrel | DW_EH_PE_udata2);
-
- // FDE 32 information.
- this->memory_.SetData32(0x5100, 0xfc);
- this->memory_.SetData32(0x5104, 0x104);
- this->memory_.SetData16(0x5108, 0x1500);
- this->memory_.SetData16(0x510a, 0x200);
-
- ASSERT_TRUE(this->eh_frame_->Init(0x5000, 0x200, 0));
- ASSERT_EQ(1U, this->eh_frame_->TestGetFdeCount());
-
- typename DwarfEhFrame<TypeParam>::FdeInfo info(0, 0, 0);
- this->eh_frame_->TestGetFdeInfo(0, &info);
- EXPECT_EQ(0x5100U, info.offset);
- EXPECT_EQ(0x6606U, info.start);
- EXPECT_EQ(0x6806U, info.end);
-}
-
-TYPED_TEST_P(DwarfEhFrameTest, GetFdeOffsetFromPc) {
- typename DwarfEhFrame<TypeParam>::FdeInfo info(0, 0, 0);
- for (size_t i = 0; i < 9; i++) {
- info.start = 0x1000 * (i + 1);
- info.end = 0x1000 * (i + 2) - 0x10;
- info.offset = 0x5000 + i * 0x20;
- this->eh_frame_->TestPushFdeInfo(info);
- }
-
- this->eh_frame_->TestSetFdeCount(0);
- uint64_t fde_offset;
- ASSERT_FALSE(this->eh_frame_->GetFdeOffsetFromPc(0x1000, &fde_offset));
- ASSERT_EQ(DWARF_ERROR_NONE, this->eh_frame_->LastErrorCode());
-
- this->eh_frame_->TestSetFdeCount(9);
- ASSERT_FALSE(this->eh_frame_->GetFdeOffsetFromPc(0x100, &fde_offset));
- ASSERT_EQ(DWARF_ERROR_NONE, this->eh_frame_->LastErrorCode());
- // Odd number of elements.
- for (size_t i = 0; i < 9; i++) {
- TypeParam pc = 0x1000 * (i + 1);
- ASSERT_TRUE(this->eh_frame_->GetFdeOffsetFromPc(pc, &fde_offset)) << "Failed at index " << i;
- EXPECT_EQ(0x5000 + i * 0x20, fde_offset) << "Failed at index " << i;
- ASSERT_TRUE(this->eh_frame_->GetFdeOffsetFromPc(pc + 1, &fde_offset)) << "Failed at index " << i;
- EXPECT_EQ(0x5000 + i * 0x20, fde_offset) << "Failed at index " << i;
- ASSERT_TRUE(this->eh_frame_->GetFdeOffsetFromPc(pc + 0xeff, &fde_offset))
- << "Failed at index " << i;
- EXPECT_EQ(0x5000 + i * 0x20, fde_offset) << "Failed at index " << i;
- ASSERT_FALSE(this->eh_frame_->GetFdeOffsetFromPc(pc + 0xfff, &fde_offset))
- << "Failed at index " << i;
- ASSERT_EQ(DWARF_ERROR_NONE, this->eh_frame_->LastErrorCode());
- }
-
- // Even number of elements.
- this->eh_frame_->TestSetFdeCount(10);
- info.start = 0xa000;
- info.end = 0xaff0;
- info.offset = 0x5120;
- this->eh_frame_->TestPushFdeInfo(info);
-
- for (size_t i = 0; i < 10; i++) {
- TypeParam pc = 0x1000 * (i + 1);
- ASSERT_TRUE(this->eh_frame_->GetFdeOffsetFromPc(pc, &fde_offset)) << "Failed at index " << i;
- EXPECT_EQ(0x5000 + i * 0x20, fde_offset) << "Failed at index " << i;
- ASSERT_TRUE(this->eh_frame_->GetFdeOffsetFromPc(pc + 1, &fde_offset)) << "Failed at index " << i;
- EXPECT_EQ(0x5000 + i * 0x20, fde_offset) << "Failed at index " << i;
- ASSERT_TRUE(this->eh_frame_->GetFdeOffsetFromPc(pc + 0xeff, &fde_offset))
- << "Failed at index " << i;
- EXPECT_EQ(0x5000 + i * 0x20, fde_offset) << "Failed at index " << i;
- ASSERT_FALSE(this->eh_frame_->GetFdeOffsetFromPc(pc + 0xfff, &fde_offset))
- << "Failed at index " << i;
- ASSERT_EQ(DWARF_ERROR_NONE, this->eh_frame_->LastErrorCode());
- }
-}
-
-TYPED_TEST_P(DwarfEhFrameTest, GetCieFde32) {
- this->eh_frame_->TestSetOffset(0x4000);
-
- // CIE 32 information.
- this->memory_.SetData32(0xf000, 0x100);
- this->memory_.SetData32(0xf004, 0);
- this->memory_.SetData8(0xf008, 0x1);
- this->memory_.SetData8(0xf009, '\0');
- this->memory_.SetData8(0xf00a, 4);
- this->memory_.SetData8(0xf00b, 8);
- this->memory_.SetData8(0xf00c, 0x20);
-
- // FDE 32 information.
- this->memory_.SetData32(0x14000, 0x20);
- this->memory_.SetData32(0x14004, 0x5004);
- this->memory_.SetData32(0x14008, 0x9000);
- this->memory_.SetData32(0x1400c, 0x100);
-
- const DwarfFde* fde = this->eh_frame_->GetFdeFromOffset(0x14000);
- ASSERT_TRUE(fde != nullptr);
- EXPECT_EQ(0x14010U, fde->cfa_instructions_offset);
- EXPECT_EQ(0x14024U, fde->cfa_instructions_end);
- EXPECT_EQ(0x1d008U, fde->pc_start);
- EXPECT_EQ(0x1d108U, fde->pc_end);
- EXPECT_EQ(0xf000U, fde->cie_offset);
+ EXPECT_EQ(0x5000U, fde->cie_offset);
+ EXPECT_EQ(0x5124U, fde->cfa_instructions_offset);
+ EXPECT_EQ(0x5208U, fde->cfa_instructions_end);
+ EXPECT_EQ(0x6618U, fde->pc_start);
+ EXPECT_EQ(0x6818U, fde->pc_end);
EXPECT_EQ(0U, fde->lsda_address);
- ASSERT_TRUE(fde->cie != nullptr);
- EXPECT_EQ(1U, fde->cie->version);
- EXPECT_EQ(DW_EH_PE_sdata4, fde->cie->fde_address_encoding);
- EXPECT_EQ(DW_EH_PE_omit, fde->cie->lsda_encoding);
- EXPECT_EQ(0U, fde->cie->segment_size);
- EXPECT_EQ(1U, fde->cie->augmentation_string.size());
- EXPECT_EQ('\0', fde->cie->augmentation_string[0]);
- EXPECT_EQ(0U, fde->cie->personality_handler);
- EXPECT_EQ(0xf00dU, fde->cie->cfa_instructions_offset);
- EXPECT_EQ(0xf104U, fde->cie->cfa_instructions_end);
- EXPECT_EQ(4U, fde->cie->code_alignment_factor);
- EXPECT_EQ(8, fde->cie->data_alignment_factor);
- EXPECT_EQ(0x20U, fde->cie->return_address_register);
+ const DwarfCie* cie = fde->cie;
+ ASSERT_TRUE(cie != nullptr);
+ EXPECT_EQ(1U, cie->version);
+ EXPECT_EQ(DW_EH_PE_sdata8, cie->fde_address_encoding);
+ EXPECT_EQ(DW_EH_PE_omit, cie->lsda_encoding);
+ EXPECT_EQ(0U, cie->segment_size);
+ EXPECT_EQ('\0', cie->augmentation_string[0]);
+ EXPECT_EQ(0U, cie->personality_handler);
+ EXPECT_EQ(0x5019U, cie->cfa_instructions_offset);
+ EXPECT_EQ(0x5108U, cie->cfa_instructions_end);
+ EXPECT_EQ(16U, cie->code_alignment_factor);
+ EXPECT_EQ(32U, cie->data_alignment_factor);
+ EXPECT_EQ(1U, cie->return_address_register);
}
-TYPED_TEST_P(DwarfEhFrameTest, GetCieFde64) {
- this->eh_frame_->TestSetOffset(0x2000);
-
- // CIE 64 information.
- this->memory_.SetData32(0x6000, 0xffffffff);
- this->memory_.SetData64(0x6004, 0x100);
- this->memory_.SetData64(0x600c, 0);
- this->memory_.SetData8(0x6014, 0x1);
- this->memory_.SetData8(0x6015, '\0');
- this->memory_.SetData8(0x6016, 4);
- this->memory_.SetData8(0x6017, 8);
- this->memory_.SetData8(0x6018, 0x20);
-
- // FDE 64 information.
- this->memory_.SetData32(0x8000, 0xffffffff);
- this->memory_.SetData64(0x8004, 0x200);
- this->memory_.SetData64(0x800c, 0x200c);
- this->memory_.SetData64(0x8014, 0x5000);
- this->memory_.SetData64(0x801c, 0x300);
-
- const DwarfFde* fde = this->eh_frame_->GetFdeFromOffset(0x8000);
- ASSERT_TRUE(fde != nullptr);
- EXPECT_EQ(0x8024U, fde->cfa_instructions_offset);
- EXPECT_EQ(0x820cU, fde->cfa_instructions_end);
- EXPECT_EQ(0xd018U, fde->pc_start);
- EXPECT_EQ(0xd318U, fde->pc_end);
- EXPECT_EQ(0x6000U, fde->cie_offset);
- EXPECT_EQ(0U, fde->lsda_address);
-
- ASSERT_TRUE(fde->cie != nullptr);
- EXPECT_EQ(1U, fde->cie->version);
- EXPECT_EQ(DW_EH_PE_sdata8, fde->cie->fde_address_encoding);
- EXPECT_EQ(DW_EH_PE_omit, fde->cie->lsda_encoding);
- EXPECT_EQ(0U, fde->cie->segment_size);
- EXPECT_EQ(1U, fde->cie->augmentation_string.size());
- EXPECT_EQ('\0', fde->cie->augmentation_string[0]);
- EXPECT_EQ(0U, fde->cie->personality_handler);
- EXPECT_EQ(0x6019U, fde->cie->cfa_instructions_offset);
- EXPECT_EQ(0x610cU, fde->cie->cfa_instructions_end);
- EXPECT_EQ(4U, fde->cie->code_alignment_factor);
- EXPECT_EQ(8, fde->cie->data_alignment_factor);
- EXPECT_EQ(0x20U, fde->cie->return_address_register);
-}
-
-REGISTER_TYPED_TEST_CASE_P(DwarfEhFrameTest, Init32, Init32_fde_not_following_cie, Init64,
- Init64_fde_not_following_cie, Init_non_zero_load_bias, Init_version1,
- Init_version4, GetFdeOffsetFromPc, GetCieFde32, GetCieFde64);
+REGISTER_TYPED_TEST_CASE_P(DwarfEhFrameTest, GetFdeCieFromOffset32, GetFdeCieFromOffset64);
typedef ::testing::Types<uint32_t, uint64_t> DwarfEhFrameTestTypes;
INSTANTIATE_TYPED_TEST_CASE_P(, DwarfEhFrameTest, DwarfEhFrameTestTypes);
diff --git a/libunwindstack/tests/DwarfEhFrameWithHdrTest.cpp b/libunwindstack/tests/DwarfEhFrameWithHdrTest.cpp
index 19c7b98..910ae36 100644
--- a/libunwindstack/tests/DwarfEhFrameWithHdrTest.cpp
+++ b/libunwindstack/tests/DwarfEhFrameWithHdrTest.cpp
@@ -30,10 +30,10 @@
namespace unwindstack {
template <typename TypeParam>
-class MockDwarfEhFrameWithHdr : public DwarfEhFrameWithHdr<TypeParam> {
+class TestDwarfEhFrameWithHdr : public DwarfEhFrameWithHdr<TypeParam> {
public:
- MockDwarfEhFrameWithHdr(Memory* memory) : DwarfEhFrameWithHdr<TypeParam>(memory) {}
- ~MockDwarfEhFrameWithHdr() = default;
+ TestDwarfEhFrameWithHdr(Memory* memory) : DwarfEhFrameWithHdr<TypeParam>(memory) {}
+ ~TestDwarfEhFrameWithHdr() = default;
void TestSetTableEncoding(uint8_t encoding) { this->table_encoding_ = encoding; }
void TestSetEntriesOffset(uint64_t offset) { this->entries_offset_ = offset; }
@@ -64,14 +64,14 @@
protected:
void SetUp() override {
memory_.Clear();
- eh_frame_ = new MockDwarfEhFrameWithHdr<TypeParam>(&memory_);
+ eh_frame_ = new TestDwarfEhFrameWithHdr<TypeParam>(&memory_);
ResetLogs();
}
void TearDown() override { delete eh_frame_; }
MemoryFake memory_;
- MockDwarfEhFrameWithHdr<TypeParam>* eh_frame_ = nullptr;
+ TestDwarfEhFrameWithHdr<TypeParam>* eh_frame_ = nullptr;
};
TYPED_TEST_CASE_P(DwarfEhFrameWithHdrTest);
@@ -121,23 +121,14 @@
// CIE 32 information.
this->memory_.SetData32(0x1300, 0xfc);
this->memory_.SetData32(0x1304, 0);
- this->memory_.SetData8(0x1308, 1);
- this->memory_.SetData8(0x1309, 'z');
- this->memory_.SetData8(0x130a, 'R');
- this->memory_.SetData8(0x130b, '\0');
- this->memory_.SetData8(0x130c, 0);
- this->memory_.SetData8(0x130d, 0);
- this->memory_.SetData8(0x130e, 0);
- this->memory_.SetData8(0x130f, 0);
- this->memory_.SetData8(0x1310, 0x1b);
+ this->memory_.SetMemory(0x1308, std::vector<uint8_t>{1, 'z', 'R', '\0', 0, 0, 0, 0, 0x1b});
// FDE 32 information.
this->memory_.SetData32(0x1400, 0xfc);
this->memory_.SetData32(0x1404, 0x104);
this->memory_.SetData32(0x1408, 0x10f8);
this->memory_.SetData32(0x140c, 0x200);
- this->memory_.SetData8(0x1410, 0);
- this->memory_.SetData8(0x1411, 0);
+ this->memory_.SetData16(0x1410, 0);
ASSERT_TRUE(this->eh_frame_->Init(0x1000, 0x100, 0x2000));
EXPECT_EQ(1U, this->eh_frame_->TestGetVersion());
@@ -157,6 +148,68 @@
EXPECT_EQ(0x4700U, fde->pc_end);
}
+TYPED_TEST_P(DwarfEhFrameWithHdrTest, GetFdes) {
+ this->memory_.SetMemory(
+ 0x1000, std::vector<uint8_t>{1, DW_EH_PE_udata2, DW_EH_PE_udata4, DW_EH_PE_sdata4});
+ this->memory_.SetData16(0x1004, 0x500);
+ this->memory_.SetData32(0x1006, 4);
+
+ // Header information.
+ this->memory_.SetData32(0x100a, 0x4600);
+ this->memory_.SetData32(0x100e, 0x1500);
+ this->memory_.SetData32(0x1012, 0x5500);
+ this->memory_.SetData32(0x1016, 0x1400);
+ this->memory_.SetData32(0x101a, 0x6800);
+ this->memory_.SetData32(0x101e, 0x1700);
+ this->memory_.SetData32(0x1022, 0x7700);
+ this->memory_.SetData32(0x1026, 0x1600);
+
+ // CIE 32 information.
+ this->memory_.SetData32(0x1300, 0xfc);
+ this->memory_.SetData32(0x1304, 0);
+ this->memory_.SetMemory(0x1308, std::vector<uint8_t>{1, '\0', 0, 0, 0});
+
+ // FDE 32 information.
+ // pc 0x5500 - 0x5700
+ this->memory_.SetData32(0x1400, 0xfc);
+ this->memory_.SetData32(0x1404, 0x104);
+ this->memory_.SetData32(0x1408, 0x40f8);
+ this->memory_.SetData32(0x140c, 0x200);
+
+ // pc 0x4600 - 0x4800
+ this->memory_.SetData32(0x1500, 0xfc);
+ this->memory_.SetData32(0x1504, 0x204);
+ this->memory_.SetData32(0x1508, 0x30f8);
+ this->memory_.SetData32(0x150c, 0x200);
+
+ // pc 0x7700 - 0x7900
+ this->memory_.SetData32(0x1600, 0xfc);
+ this->memory_.SetData32(0x1604, 0x304);
+ this->memory_.SetData32(0x1608, 0x60f8);
+ this->memory_.SetData32(0x160c, 0x200);
+
+ // pc 0x6800 - 0x6a00
+ this->memory_.SetData32(0x1700, 0xfc);
+ this->memory_.SetData32(0x1704, 0x404);
+ this->memory_.SetData32(0x1708, 0x50f8);
+ this->memory_.SetData32(0x170c, 0x200);
+
+ ASSERT_TRUE(this->eh_frame_->Init(0x1000, 0x100, 0));
+
+ std::vector<const DwarfFde*> fdes;
+ this->eh_frame_->GetFdes(&fdes);
+ ASSERT_EQ(4U, fdes.size());
+
+ EXPECT_EQ(0x4600U, fdes[0]->pc_start);
+ EXPECT_EQ(0x4800U, fdes[0]->pc_end);
+ EXPECT_EQ(0x5500U, fdes[1]->pc_start);
+ EXPECT_EQ(0x5700U, fdes[1]->pc_end);
+ EXPECT_EQ(0x6800U, fdes[2]->pc_start);
+ EXPECT_EQ(0x6a00U, fdes[2]->pc_end);
+ EXPECT_EQ(0x7700U, fdes[3]->pc_start);
+ EXPECT_EQ(0x7900U, fdes[3]->pc_end);
+}
+
TYPED_TEST_P(DwarfEhFrameWithHdrTest, GetFdeInfoFromIndex_expect_cache_fail) {
this->eh_frame_->TestSetTableEntrySize(0x10);
this->eh_frame_->TestSetTableEncoding(DW_EH_PE_udata4);
@@ -388,11 +441,7 @@
// CIE 32 information.
this->memory_.SetData32(0xf000, 0x100);
this->memory_.SetData32(0xf004, 0);
- this->memory_.SetData8(0xf008, 0x1);
- this->memory_.SetData8(0xf009, '\0');
- this->memory_.SetData8(0xf00a, 4);
- this->memory_.SetData8(0xf00b, 8);
- this->memory_.SetData8(0xf00c, 0x20);
+ this->memory_.SetMemory(0xf008, std::vector<uint8_t>{1, '\0', 4, 8, 0x20});
// FDE 32 information.
this->memory_.SetData32(0x14000, 0x20);
@@ -429,11 +478,7 @@
this->memory_.SetData32(0x6000, 0xffffffff);
this->memory_.SetData64(0x6004, 0x100);
this->memory_.SetData64(0x600c, 0);
- this->memory_.SetData8(0x6014, 0x1);
- this->memory_.SetData8(0x6015, '\0');
- this->memory_.SetData8(0x6016, 4);
- this->memory_.SetData8(0x6017, 8);
- this->memory_.SetData8(0x6018, 0x20);
+ this->memory_.SetMemory(0x6014, std::vector<uint8_t>{1, '\0', 4, 8, 0x20});
// FDE 64 information.
this->memory_.SetData32(0x8000, 0xffffffff);
@@ -478,7 +523,7 @@
ASSERT_EQ(nullptr, this->eh_frame_->GetFdeFromPc(0x800));
}
-REGISTER_TYPED_TEST_CASE_P(DwarfEhFrameWithHdrTest, Init, Init_non_zero_load_bias,
+REGISTER_TYPED_TEST_CASE_P(DwarfEhFrameWithHdrTest, Init, Init_non_zero_load_bias, GetFdes,
GetFdeInfoFromIndex_expect_cache_fail, GetFdeInfoFromIndex_read_pcrel,
GetFdeInfoFromIndex_read_datarel, GetFdeInfoFromIndex_cached,
GetFdeOffsetBinary_verify, GetFdeOffsetBinary_index_fail,
diff --git a/libunwindstack/tests/DwarfSectionImplTest.cpp b/libunwindstack/tests/DwarfSectionImplTest.cpp
index 414f2f2..46f555a 100644
--- a/libunwindstack/tests/DwarfSectionImplTest.cpp
+++ b/libunwindstack/tests/DwarfSectionImplTest.cpp
@@ -16,7 +16,6 @@
#include <stdint.h>
-#include <gmock/gmock.h>
#include <gtest/gtest.h>
#include <unwindstack/DwarfError.h>
@@ -31,42 +30,27 @@
namespace unwindstack {
template <typename TypeParam>
-class MockDwarfSectionImpl : public DwarfSectionImpl<TypeParam> {
+class TestDwarfSectionImpl : public DwarfSectionImpl<TypeParam> {
public:
- MockDwarfSectionImpl(Memory* memory) : DwarfSectionImpl<TypeParam>(memory) {}
- virtual ~MockDwarfSectionImpl() = default;
+ TestDwarfSectionImpl(Memory* memory) : DwarfSectionImpl<TypeParam>(memory) {}
+ virtual ~TestDwarfSectionImpl() = default;
- MOCK_METHOD3(Init, bool(uint64_t, uint64_t, uint64_t));
+ bool Init(uint64_t, uint64_t, uint64_t) override { return false; }
- MOCK_METHOD2(GetFdeOffsetFromPc, bool(uint64_t, uint64_t*));
+ void GetFdes(std::vector<const DwarfFde*>*) override {}
- MOCK_METHOD1(GetFdeFromIndex, const DwarfFde*(size_t));
+ const DwarfFde* GetFdeFromPc(uint64_t) override { return nullptr; }
- MOCK_METHOD1(GetCieOffsetFromFde32, uint64_t(uint32_t));
+ uint64_t GetCieOffsetFromFde32(uint32_t) { return 0; }
- MOCK_METHOD1(GetCieOffsetFromFde64, uint64_t(uint64_t));
+ uint64_t GetCieOffsetFromFde64(uint64_t) { return 0; }
- MOCK_METHOD1(AdjustPcFromFde, uint64_t(uint64_t));
-
- void TestSetCie32Value(uint32_t value32) { this->cie32_value_ = value32; }
-
- void TestSetCie64Value(uint64_t value64) { this->cie64_value_ = value64; }
-
- void TestSetCachedCieEntry(uint64_t offset, const DwarfCie& cie) {
- this->cie_entries_[offset] = cie;
- }
- void TestClearCachedCieEntry() { this->cie_entries_.clear(); }
-
- void TestSetCachedFdeEntry(uint64_t offset, const DwarfFde& fde) {
- this->fde_entries_[offset] = fde;
- }
- void TestClearCachedFdeEntry() { this->fde_entries_.clear(); }
+ uint64_t AdjustPcFromFde(uint64_t) override { return 0; }
void TestSetCachedCieLocRegs(uint64_t offset, const dwarf_loc_regs_t& loc_regs) {
this->cie_loc_regs_[offset] = loc_regs;
}
void TestClearCachedCieLocRegs() { this->cie_loc_regs_.clear(); }
-
void TestClearError() { this->last_error_.code = DWARF_ERROR_NONE; }
};
@@ -75,21 +59,41 @@
protected:
void SetUp() override {
memory_.Clear();
- section_ = new MockDwarfSectionImpl<TypeParam>(&memory_);
+ section_ = new TestDwarfSectionImpl<TypeParam>(&memory_);
ResetLogs();
- section_->TestSetCie32Value(static_cast<uint32_t>(-1));
- section_->TestSetCie64Value(static_cast<uint64_t>(-1));
}
void TearDown() override { delete section_; }
MemoryFake memory_;
- MockDwarfSectionImpl<TypeParam>* section_ = nullptr;
+ TestDwarfSectionImpl<TypeParam>* section_ = nullptr;
};
TYPED_TEST_CASE_P(DwarfSectionImplTest);
// NOTE: All test class variables need to be referenced as this->.
+TYPED_TEST_P(DwarfSectionImplTest, GetCieFromOffset_fail_should_not_cache) {
+ ASSERT_TRUE(this->section_->GetCieFromOffset(0x4000) == nullptr);
+ EXPECT_EQ(DWARF_ERROR_MEMORY_INVALID, this->section_->LastErrorCode());
+ EXPECT_EQ(0x4000U, this->section_->LastErrorAddress());
+
+ this->section_->TestClearError();
+ ASSERT_TRUE(this->section_->GetCieFromOffset(0x4000) == nullptr);
+ EXPECT_EQ(DWARF_ERROR_MEMORY_INVALID, this->section_->LastErrorCode());
+ EXPECT_EQ(0x4000U, this->section_->LastErrorAddress());
+}
+
+TYPED_TEST_P(DwarfSectionImplTest, GetFdeFromOffset_fail_should_not_cache) {
+ ASSERT_TRUE(this->section_->GetFdeFromOffset(0x4000) == nullptr);
+ EXPECT_EQ(DWARF_ERROR_MEMORY_INVALID, this->section_->LastErrorCode());
+ EXPECT_EQ(0x4000U, this->section_->LastErrorAddress());
+
+ this->section_->TestClearError();
+ ASSERT_TRUE(this->section_->GetFdeFromOffset(0x4000) == nullptr);
+ EXPECT_EQ(DWARF_ERROR_MEMORY_INVALID, this->section_->LastErrorCode());
+ EXPECT_EQ(0x4000U, this->section_->LastErrorAddress());
+}
+
TYPED_TEST_P(DwarfSectionImplTest, Eval_cfa_expr_eval_fail) {
DwarfCie cie{.version = 3, .return_address_register = 5};
RegsImplFake<TypeParam> regs(10);
@@ -487,334 +491,6 @@
EXPECT_EQ(0x80000000U, regs.pc());
}
-TYPED_TEST_P(DwarfSectionImplTest, GetCie_fail_should_not_cache) {
- ASSERT_TRUE(this->section_->GetCie(0x4000) == nullptr);
- EXPECT_EQ(DWARF_ERROR_MEMORY_INVALID, this->section_->LastErrorCode());
- EXPECT_EQ(0x4000U, this->section_->LastErrorAddress());
- this->section_->TestClearError();
- ASSERT_TRUE(this->section_->GetCie(0x4000) == nullptr);
- EXPECT_EQ(DWARF_ERROR_MEMORY_INVALID, this->section_->LastErrorCode());
- EXPECT_EQ(0x4000U, this->section_->LastErrorAddress());
-}
-
-TYPED_TEST_P(DwarfSectionImplTest, GetCie_32_version_check) {
- this->memory_.SetData32(0x5000, 0x100);
- this->memory_.SetData32(0x5004, 0xffffffff);
- this->memory_.SetData8(0x5008, 0x1);
- this->memory_.SetData8(0x5009, '\0');
- this->memory_.SetData8(0x500a, 4);
- this->memory_.SetData8(0x500b, 8);
- this->memory_.SetData8(0x500c, 0x20);
-
- const DwarfCie* cie = this->section_->GetCie(0x5000);
- ASSERT_TRUE(cie != nullptr);
- EXPECT_EQ(1U, cie->version);
- EXPECT_EQ(DW_EH_PE_sdata4, cie->fde_address_encoding);
- EXPECT_EQ(DW_EH_PE_omit, cie->lsda_encoding);
- EXPECT_EQ(0U, cie->segment_size);
- EXPECT_EQ(1U, cie->augmentation_string.size());
- EXPECT_EQ('\0', cie->augmentation_string[0]);
- EXPECT_EQ(0U, cie->personality_handler);
- EXPECT_EQ(0x500dU, cie->cfa_instructions_offset);
- EXPECT_EQ(0x5104U, cie->cfa_instructions_end);
- EXPECT_EQ(4U, cie->code_alignment_factor);
- EXPECT_EQ(8, cie->data_alignment_factor);
- EXPECT_EQ(0x20U, cie->return_address_register);
- EXPECT_EQ(DWARF_ERROR_NONE, this->section_->LastErrorCode());
-
- this->section_->TestClearCachedCieEntry();
- // Set version to 0, 2, 5 and verify we fail.
- this->memory_.SetData8(0x5008, 0x0);
- this->section_->TestClearError();
- ASSERT_TRUE(this->section_->GetCie(0x5000) == nullptr);
- EXPECT_EQ(DWARF_ERROR_UNSUPPORTED_VERSION, this->section_->LastErrorCode());
-
- this->memory_.SetData8(0x5008, 0x2);
- this->section_->TestClearError();
- ASSERT_TRUE(this->section_->GetCie(0x5000) == nullptr);
- EXPECT_EQ(DWARF_ERROR_UNSUPPORTED_VERSION, this->section_->LastErrorCode());
-
- this->memory_.SetData8(0x5008, 0x5);
- this->section_->TestClearError();
- ASSERT_TRUE(this->section_->GetCie(0x5000) == nullptr);
- EXPECT_EQ(DWARF_ERROR_UNSUPPORTED_VERSION, this->section_->LastErrorCode());
-}
-
-TYPED_TEST_P(DwarfSectionImplTest, GetCie_negative_data_alignment_factor) {
- this->memory_.SetData32(0x5000, 0x100);
- this->memory_.SetData32(0x5004, 0xffffffff);
- this->memory_.SetData8(0x5008, 0x1);
- this->memory_.SetData8(0x5009, '\0');
- this->memory_.SetData8(0x500a, 4);
- this->memory_.SetMemory(0x500b, std::vector<uint8_t>{0xfc, 0xff, 0xff, 0xff, 0x7f});
- this->memory_.SetData8(0x5010, 0x20);
-
- const DwarfCie* cie = this->section_->GetCie(0x5000);
- ASSERT_TRUE(cie != nullptr);
- EXPECT_EQ(1U, cie->version);
- EXPECT_EQ(DW_EH_PE_sdata4, cie->fde_address_encoding);
- EXPECT_EQ(DW_EH_PE_omit, cie->lsda_encoding);
- EXPECT_EQ(0U, cie->segment_size);
- EXPECT_EQ(1U, cie->augmentation_string.size());
- EXPECT_EQ('\0', cie->augmentation_string[0]);
- EXPECT_EQ(0U, cie->personality_handler);
- EXPECT_EQ(0x5011U, cie->cfa_instructions_offset);
- EXPECT_EQ(0x5104U, cie->cfa_instructions_end);
- EXPECT_EQ(4U, cie->code_alignment_factor);
- EXPECT_EQ(-4, cie->data_alignment_factor);
- EXPECT_EQ(0x20U, cie->return_address_register);
-}
-
-TYPED_TEST_P(DwarfSectionImplTest, GetCie_64_no_augment) {
- this->memory_.SetData32(0x8000, 0xffffffff);
- this->memory_.SetData64(0x8004, 0x200);
- this->memory_.SetData64(0x800c, 0xffffffffffffffffULL);
- this->memory_.SetData8(0x8014, 0x1);
- this->memory_.SetData8(0x8015, '\0');
- this->memory_.SetData8(0x8016, 4);
- this->memory_.SetData8(0x8017, 8);
- this->memory_.SetData8(0x8018, 0x20);
-
- const DwarfCie* cie = this->section_->GetCie(0x8000);
- ASSERT_TRUE(cie != nullptr);
- EXPECT_EQ(1U, cie->version);
- EXPECT_EQ(DW_EH_PE_sdata8, cie->fde_address_encoding);
- EXPECT_EQ(DW_EH_PE_omit, cie->lsda_encoding);
- EXPECT_EQ(0U, cie->segment_size);
- EXPECT_EQ(1U, cie->augmentation_string.size());
- EXPECT_EQ('\0', cie->augmentation_string[0]);
- EXPECT_EQ(0U, cie->personality_handler);
- EXPECT_EQ(0x8019U, cie->cfa_instructions_offset);
- EXPECT_EQ(0x820cU, cie->cfa_instructions_end);
- EXPECT_EQ(4U, cie->code_alignment_factor);
- EXPECT_EQ(8, cie->data_alignment_factor);
- EXPECT_EQ(0x20U, cie->return_address_register);
-}
-
-TYPED_TEST_P(DwarfSectionImplTest, GetCie_augment) {
- this->memory_.SetData32(0x5000, 0x100);
- this->memory_.SetData32(0x5004, 0xffffffff);
- this->memory_.SetData8(0x5008, 0x1);
- this->memory_.SetMemory(0x5009, std::vector<uint8_t>{'z', 'L', 'P', 'R', '\0'});
- this->memory_.SetData8(0x500e, 4);
- this->memory_.SetData8(0x500f, 8);
- this->memory_.SetData8(0x5010, 0x10);
- // Augment length.
- this->memory_.SetData8(0x5011, 0xf);
- // L data.
- this->memory_.SetData8(0x5012, DW_EH_PE_textrel | DW_EH_PE_udata2);
- // P data.
- this->memory_.SetData8(0x5013, DW_EH_PE_udata4);
- this->memory_.SetData32(0x5014, 0x12345678);
- // R data.
- this->memory_.SetData8(0x5018, DW_EH_PE_udata2);
-
- const DwarfCie* cie = this->section_->GetCie(0x5000);
- ASSERT_TRUE(cie != nullptr);
- EXPECT_EQ(1U, cie->version);
- EXPECT_EQ(DW_EH_PE_udata2, cie->fde_address_encoding);
- EXPECT_EQ(DW_EH_PE_textrel | DW_EH_PE_udata2, cie->lsda_encoding);
- EXPECT_EQ(0U, cie->segment_size);
- EXPECT_EQ(5U, cie->augmentation_string.size());
- EXPECT_EQ('z', cie->augmentation_string[0]);
- EXPECT_EQ('L', cie->augmentation_string[1]);
- EXPECT_EQ('P', cie->augmentation_string[2]);
- EXPECT_EQ('R', cie->augmentation_string[3]);
- EXPECT_EQ('\0', cie->augmentation_string[4]);
- EXPECT_EQ(0x12345678U, cie->personality_handler);
- EXPECT_EQ(0x5021U, cie->cfa_instructions_offset);
- EXPECT_EQ(0x5104U, cie->cfa_instructions_end);
- EXPECT_EQ(4U, cie->code_alignment_factor);
- EXPECT_EQ(8, cie->data_alignment_factor);
- EXPECT_EQ(0x10U, cie->return_address_register);
-}
-
-TYPED_TEST_P(DwarfSectionImplTest, GetCie_version_3) {
- this->memory_.SetData32(0x5000, 0x100);
- this->memory_.SetData32(0x5004, 0xffffffff);
- this->memory_.SetData8(0x5008, 0x3);
- this->memory_.SetData8(0x5009, '\0');
- this->memory_.SetData8(0x500a, 4);
- this->memory_.SetData8(0x500b, 8);
- this->memory_.SetMemory(0x500c, std::vector<uint8_t>{0x81, 0x03});
-
- const DwarfCie* cie = this->section_->GetCie(0x5000);
- ASSERT_TRUE(cie != nullptr);
- EXPECT_EQ(3U, cie->version);
- EXPECT_EQ(DW_EH_PE_sdata4, cie->fde_address_encoding);
- EXPECT_EQ(DW_EH_PE_omit, cie->lsda_encoding);
- EXPECT_EQ(0U, cie->segment_size);
- EXPECT_EQ(1U, cie->augmentation_string.size());
- EXPECT_EQ('\0', cie->augmentation_string[0]);
- EXPECT_EQ(0U, cie->personality_handler);
- EXPECT_EQ(0x500eU, cie->cfa_instructions_offset);
- EXPECT_EQ(0x5104U, cie->cfa_instructions_end);
- EXPECT_EQ(4U, cie->code_alignment_factor);
- EXPECT_EQ(8, cie->data_alignment_factor);
- EXPECT_EQ(0x181U, cie->return_address_register);
-}
-
-TYPED_TEST_P(DwarfSectionImplTest, GetCie_version_4) {
- this->memory_.SetData32(0x5000, 0x100);
- this->memory_.SetData32(0x5004, 0xffffffff);
- this->memory_.SetData8(0x5008, 0x4);
- this->memory_.SetData8(0x5009, '\0');
- this->memory_.SetData8(0x500a, 4);
- this->memory_.SetData8(0x500b, 0x13);
- this->memory_.SetData8(0x500c, 4);
- this->memory_.SetData8(0x500d, 8);
- this->memory_.SetMemory(0x500e, std::vector<uint8_t>{0x81, 0x03});
-
- const DwarfCie* cie = this->section_->GetCie(0x5000);
- ASSERT_TRUE(cie != nullptr);
- EXPECT_EQ(4U, cie->version);
- EXPECT_EQ(DW_EH_PE_sdata4, cie->fde_address_encoding);
- EXPECT_EQ(DW_EH_PE_omit, cie->lsda_encoding);
- EXPECT_EQ(0x13U, cie->segment_size);
- EXPECT_EQ(1U, cie->augmentation_string.size());
- EXPECT_EQ('\0', cie->augmentation_string[0]);
- EXPECT_EQ(0U, cie->personality_handler);
- EXPECT_EQ(0x5010U, cie->cfa_instructions_offset);
- EXPECT_EQ(0x5104U, cie->cfa_instructions_end);
- EXPECT_EQ(4U, cie->code_alignment_factor);
- EXPECT_EQ(8, cie->data_alignment_factor);
- EXPECT_EQ(0x181U, cie->return_address_register);
-}
-
-TYPED_TEST_P(DwarfSectionImplTest, GetFdeFromOffset_fail_should_not_cache) {
- ASSERT_TRUE(this->section_->GetFdeFromOffset(0x4000) == nullptr);
- EXPECT_EQ(DWARF_ERROR_MEMORY_INVALID, this->section_->LastErrorCode());
- EXPECT_EQ(0x4000U, this->section_->LastErrorAddress());
- this->section_->TestClearError();
- ASSERT_TRUE(this->section_->GetFdeFromOffset(0x4000) == nullptr);
- EXPECT_EQ(DWARF_ERROR_MEMORY_INVALID, this->section_->LastErrorCode());
- EXPECT_EQ(0x4000U, this->section_->LastErrorAddress());
-}
-
-TYPED_TEST_P(DwarfSectionImplTest, GetFdeFromOffset_32_no_augment) {
- this->memory_.SetData32(0x4000, 0x20);
- this->memory_.SetData32(0x4004, 0x8000);
- this->memory_.SetData32(0x4008, 0x5000);
- this->memory_.SetData32(0x400c, 0x100);
-
- EXPECT_CALL(*this->section_, GetCieOffsetFromFde32(0x8000)).WillOnce(::testing::Return(0x8000));
- DwarfCie cie{};
- cie.fde_address_encoding = DW_EH_PE_udata4;
- this->section_->TestSetCachedCieEntry(0x8000, cie);
- EXPECT_CALL(*this->section_, AdjustPcFromFde(0x5000)).WillOnce(::testing::Return(0x5000));
-
- const DwarfFde* fde = this->section_->GetFdeFromOffset(0x4000);
- ASSERT_TRUE(fde != nullptr);
- ASSERT_TRUE(fde->cie != nullptr);
- EXPECT_EQ(0x4010U, fde->cfa_instructions_offset);
- EXPECT_EQ(0x4024U, fde->cfa_instructions_end);
- EXPECT_EQ(0x5000U, fde->pc_start);
- EXPECT_EQ(0x5100U, fde->pc_end);
- EXPECT_EQ(0x8000U, fde->cie_offset);
- EXPECT_EQ(0U, fde->lsda_address);
-}
-
-TYPED_TEST_P(DwarfSectionImplTest, GetFdeFromOffset_32_no_augment_non_zero_segment_size) {
- this->memory_.SetData32(0x4000, 0x30);
- this->memory_.SetData32(0x4004, 0x8000);
- this->memory_.SetData32(0x4018, 0x5000);
- this->memory_.SetData32(0x401c, 0x100);
-
- EXPECT_CALL(*this->section_, GetCieOffsetFromFde32(0x8000)).WillOnce(::testing::Return(0x8000));
- DwarfCie cie{};
- cie.fde_address_encoding = DW_EH_PE_udata4;
- cie.segment_size = 0x10;
- this->section_->TestSetCachedCieEntry(0x8000, cie);
- EXPECT_CALL(*this->section_, AdjustPcFromFde(0x5000)).WillOnce(::testing::Return(0x5000));
-
- const DwarfFde* fde = this->section_->GetFdeFromOffset(0x4000);
- ASSERT_TRUE(fde != nullptr);
- ASSERT_TRUE(fde->cie != nullptr);
- EXPECT_EQ(0x4020U, fde->cfa_instructions_offset);
- EXPECT_EQ(0x4034U, fde->cfa_instructions_end);
- EXPECT_EQ(0x5000U, fde->pc_start);
- EXPECT_EQ(0x5100U, fde->pc_end);
- EXPECT_EQ(0x8000U, fde->cie_offset);
- EXPECT_EQ(0U, fde->lsda_address);
-}
-
-TYPED_TEST_P(DwarfSectionImplTest, GetFdeFromOffset_32_augment) {
- this->memory_.SetData32(0x4000, 0x100);
- this->memory_.SetData32(0x4004, 0x8000);
- this->memory_.SetData32(0x4008, 0x5000);
- this->memory_.SetData32(0x400c, 0x100);
- this->memory_.SetMemory(0x4010, std::vector<uint8_t>{0x82, 0x01});
- this->memory_.SetData16(0x4012, 0x1234);
-
- EXPECT_CALL(*this->section_, GetCieOffsetFromFde32(0x8000)).WillOnce(::testing::Return(0x8000));
- DwarfCie cie{};
- cie.fde_address_encoding = DW_EH_PE_udata4;
- cie.augmentation_string.push_back('z');
- cie.lsda_encoding = DW_EH_PE_udata2;
- this->section_->TestSetCachedCieEntry(0x8000, cie);
- EXPECT_CALL(*this->section_, AdjustPcFromFde(0x5000)).WillOnce(::testing::Return(0x5000));
-
- const DwarfFde* fde = this->section_->GetFdeFromOffset(0x4000);
- ASSERT_TRUE(fde != nullptr);
- ASSERT_TRUE(fde->cie != nullptr);
- EXPECT_EQ(0x4094U, fde->cfa_instructions_offset);
- EXPECT_EQ(0x4104U, fde->cfa_instructions_end);
- EXPECT_EQ(0x5000U, fde->pc_start);
- EXPECT_EQ(0x5100U, fde->pc_end);
- EXPECT_EQ(0x8000U, fde->cie_offset);
- EXPECT_EQ(0x1234U, fde->lsda_address);
-}
-
-TYPED_TEST_P(DwarfSectionImplTest, GetFdeFromOffset_64_no_augment) {
- this->memory_.SetData32(0x4000, 0xffffffff);
- this->memory_.SetData64(0x4004, 0x100);
- this->memory_.SetData64(0x400c, 0x12345678);
- this->memory_.SetData32(0x4014, 0x5000);
- this->memory_.SetData32(0x4018, 0x100);
-
- EXPECT_CALL(*this->section_, GetCieOffsetFromFde64(0x12345678))
- .WillOnce(::testing::Return(0x12345678));
- DwarfCie cie{};
- cie.fde_address_encoding = DW_EH_PE_udata4;
- this->section_->TestSetCachedCieEntry(0x12345678, cie);
- EXPECT_CALL(*this->section_, AdjustPcFromFde(0x5000)).WillOnce(::testing::Return(0x5000));
-
- const DwarfFde* fde = this->section_->GetFdeFromOffset(0x4000);
- ASSERT_TRUE(fde != nullptr);
- ASSERT_TRUE(fde->cie != nullptr);
- EXPECT_EQ(0x401cU, fde->cfa_instructions_offset);
- EXPECT_EQ(0x410cU, fde->cfa_instructions_end);
- EXPECT_EQ(0x5000U, fde->pc_start);
- EXPECT_EQ(0x5100U, fde->pc_end);
- EXPECT_EQ(0x12345678U, fde->cie_offset);
- EXPECT_EQ(0U, fde->lsda_address);
-}
-
-TYPED_TEST_P(DwarfSectionImplTest, GetFdeFromOffset_cached) {
- DwarfCie cie{};
- cie.fde_address_encoding = DW_EH_PE_udata4;
- cie.augmentation_string.push_back('z');
- cie.lsda_encoding = DW_EH_PE_udata2;
-
- DwarfFde fde_cached{};
- fde_cached.cfa_instructions_offset = 0x1000;
- fde_cached.cfa_instructions_end = 0x1100;
- fde_cached.pc_start = 0x9000;
- fde_cached.pc_end = 0x9400;
- fde_cached.cie_offset = 0x30000;
- fde_cached.cie = &cie;
- this->section_->TestSetCachedFdeEntry(0x6000, fde_cached);
-
- const DwarfFde* fde = this->section_->GetFdeFromOffset(0x6000);
- ASSERT_TRUE(fde != nullptr);
- ASSERT_EQ(&cie, fde->cie);
- EXPECT_EQ(0x1000U, fde->cfa_instructions_offset);
- EXPECT_EQ(0x1100U, fde->cfa_instructions_end);
- EXPECT_EQ(0x9000U, fde->pc_start);
- EXPECT_EQ(0x9400U, fde->pc_end);
- EXPECT_EQ(0x30000U, fde->cie_offset);
-}
-
TYPED_TEST_P(DwarfSectionImplTest, GetCfaLocationInfo_cie_not_cached) {
DwarfCie cie{};
cie.cfa_instructions_offset = 0x3000;
@@ -895,18 +571,16 @@
ASSERT_EQ("", GetFakeLogBuf());
}
-REGISTER_TYPED_TEST_CASE_P(
- DwarfSectionImplTest, Eval_cfa_expr_eval_fail, Eval_cfa_expr_no_stack,
- Eval_cfa_expr_is_register, Eval_cfa_expr, Eval_cfa_val_expr, Eval_bad_regs, Eval_no_cfa,
- Eval_cfa_bad, Eval_cfa_register_prev, Eval_cfa_register_from_value, Eval_double_indirection,
- Eval_register_reference_chain, Eval_dex_pc, Eval_invalid_register, Eval_different_reg_locations,
- Eval_return_address_undefined, Eval_pc_zero, Eval_return_address, Eval_ignore_large_reg_loc,
- Eval_reg_expr, Eval_reg_val_expr, GetCie_fail_should_not_cache, GetCie_32_version_check,
- GetCie_negative_data_alignment_factor, GetCie_64_no_augment, GetCie_augment, GetCie_version_3,
- GetCie_version_4, GetFdeFromOffset_fail_should_not_cache, GetFdeFromOffset_32_no_augment,
- GetFdeFromOffset_32_no_augment_non_zero_segment_size, GetFdeFromOffset_32_augment,
- GetFdeFromOffset_64_no_augment, GetFdeFromOffset_cached, GetCfaLocationInfo_cie_not_cached,
- GetCfaLocationInfo_cie_cached, Log);
+REGISTER_TYPED_TEST_CASE_P(DwarfSectionImplTest, GetCieFromOffset_fail_should_not_cache,
+ GetFdeFromOffset_fail_should_not_cache, Eval_cfa_expr_eval_fail,
+ Eval_cfa_expr_no_stack, Eval_cfa_expr_is_register, Eval_cfa_expr,
+ Eval_cfa_val_expr, Eval_bad_regs, Eval_no_cfa, Eval_cfa_bad,
+ Eval_cfa_register_prev, Eval_cfa_register_from_value,
+ Eval_double_indirection, Eval_register_reference_chain, Eval_dex_pc,
+ Eval_invalid_register, Eval_different_reg_locations,
+ Eval_return_address_undefined, Eval_pc_zero, Eval_return_address,
+ Eval_ignore_large_reg_loc, Eval_reg_expr, Eval_reg_val_expr,
+ GetCfaLocationInfo_cie_not_cached, GetCfaLocationInfo_cie_cached, Log);
typedef ::testing::Types<uint32_t, uint64_t> DwarfSectionImplTestTypes;
INSTANTIATE_TYPED_TEST_CASE_P(, DwarfSectionImplTest, DwarfSectionImplTestTypes);
diff --git a/libunwindstack/tests/DwarfSectionTest.cpp b/libunwindstack/tests/DwarfSectionTest.cpp
index 2c6c879..d754fcc 100644
--- a/libunwindstack/tests/DwarfSectionTest.cpp
+++ b/libunwindstack/tests/DwarfSectionTest.cpp
@@ -30,24 +30,18 @@
MockDwarfSection(Memory* memory) : DwarfSection(memory) {}
virtual ~MockDwarfSection() = default;
- MOCK_METHOD3(Log, bool(uint8_t, uint64_t, const DwarfFde*));
+ MOCK_METHOD3(Init, bool(uint64_t, uint64_t, uint64_t));
MOCK_METHOD5(Eval, bool(const DwarfCie*, Memory*, const dwarf_loc_regs_t&, Regs*, bool*));
+ MOCK_METHOD3(Log, bool(uint8_t, uint64_t, const DwarfFde*));
+
+ MOCK_METHOD1(GetFdes, void(std::vector<const DwarfFde*>*));
+
+ MOCK_METHOD1(GetFdeFromPc, const DwarfFde*(uint64_t));
+
MOCK_METHOD3(GetCfaLocationInfo, bool(uint64_t, const DwarfFde*, dwarf_loc_regs_t*));
- MOCK_METHOD3(Init, bool(uint64_t, uint64_t, uint64_t));
-
- MOCK_METHOD2(GetFdeOffsetFromPc, bool(uint64_t, uint64_t*));
-
- MOCK_METHOD1(GetFdeFromOffset, const DwarfFde*(uint64_t));
-
- MOCK_METHOD1(GetFdeFromIndex, const DwarfFde*(size_t));
-
- MOCK_METHOD1(IsCie32, bool(uint32_t));
-
- MOCK_METHOD1(IsCie64, bool(uint64_t));
-
MOCK_METHOD1(GetCieOffsetFromFde32, uint64_t(uint32_t));
MOCK_METHOD1(GetCieOffsetFromFde64, uint64_t(uint64_t));
@@ -57,112 +51,60 @@
class DwarfSectionTest : public ::testing::Test {
protected:
+ void SetUp() override { section_.reset(new MockDwarfSection(&memory_)); }
+
MemoryFake memory_;
+ std::unique_ptr<MockDwarfSection> section_;
};
-TEST_F(DwarfSectionTest, GetFdeOffsetFromPc_fail_from_pc) {
- MockDwarfSection mock_section(&memory_);
-
- EXPECT_CALL(mock_section, GetFdeOffsetFromPc(0x1000, ::testing::_))
- .WillOnce(::testing::Return(false));
-
- // Verify nullptr when GetFdeOffsetFromPc fails.
- ASSERT_TRUE(mock_section.GetFdeFromPc(0x1000) == nullptr);
-}
-
-TEST_F(DwarfSectionTest, GetFdeOffsetFromPc_fail_fde_pc_end) {
- MockDwarfSection mock_section(&memory_);
-
- DwarfFde fde{};
- fde.pc_end = 0x500;
-
- EXPECT_CALL(mock_section, GetFdeOffsetFromPc(0x1000, ::testing::_))
- .WillOnce(::testing::Return(true));
- EXPECT_CALL(mock_section, GetFdeFromOffset(::testing::_)).WillOnce(::testing::Return(&fde));
-
- // Verify nullptr when GetFdeOffsetFromPc fails.
- ASSERT_TRUE(mock_section.GetFdeFromPc(0x1000) == nullptr);
-}
-
-TEST_F(DwarfSectionTest, GetFdeOffsetFromPc_pass) {
- MockDwarfSection mock_section(&memory_);
-
- DwarfFde fde{};
- fde.pc_end = 0x2000;
-
- EXPECT_CALL(mock_section, GetFdeOffsetFromPc(0x1000, ::testing::_))
- .WillOnce(::testing::Return(true));
- EXPECT_CALL(mock_section, GetFdeFromOffset(::testing::_)).WillOnce(::testing::Return(&fde));
-
- // Verify nullptr when GetFdeOffsetFromPc fails.
- ASSERT_EQ(&fde, mock_section.GetFdeFromPc(0x1000));
-}
-
TEST_F(DwarfSectionTest, Step_fail_fde) {
- MockDwarfSection mock_section(&memory_);
-
- EXPECT_CALL(mock_section, GetFdeOffsetFromPc(0x1000, ::testing::_))
- .WillOnce(::testing::Return(false));
+ EXPECT_CALL(*section_, GetFdeFromPc(0x1000)).WillOnce(::testing::Return(nullptr));
bool finished;
- ASSERT_FALSE(mock_section.Step(0x1000, nullptr, nullptr, &finished));
+ ASSERT_FALSE(section_->Step(0x1000, nullptr, nullptr, &finished));
}
TEST_F(DwarfSectionTest, Step_fail_cie_null) {
- MockDwarfSection mock_section(&memory_);
-
DwarfFde fde{};
fde.pc_end = 0x2000;
fde.cie = nullptr;
- EXPECT_CALL(mock_section, GetFdeOffsetFromPc(0x1000, ::testing::_))
- .WillOnce(::testing::Return(true));
- EXPECT_CALL(mock_section, GetFdeFromOffset(::testing::_)).WillOnce(::testing::Return(&fde));
+ EXPECT_CALL(*section_, GetFdeFromPc(0x1000)).WillOnce(::testing::Return(&fde));
bool finished;
- ASSERT_FALSE(mock_section.Step(0x1000, nullptr, nullptr, &finished));
+ ASSERT_FALSE(section_->Step(0x1000, nullptr, nullptr, &finished));
}
TEST_F(DwarfSectionTest, Step_fail_cfa_location) {
- MockDwarfSection mock_section(&memory_);
-
DwarfCie cie{};
DwarfFde fde{};
fde.pc_end = 0x2000;
fde.cie = &cie;
- EXPECT_CALL(mock_section, GetFdeOffsetFromPc(0x1000, ::testing::_))
- .WillOnce(::testing::Return(true));
- EXPECT_CALL(mock_section, GetFdeFromOffset(::testing::_)).WillOnce(::testing::Return(&fde));
-
- EXPECT_CALL(mock_section, GetCfaLocationInfo(0x1000, &fde, ::testing::_))
+ EXPECT_CALL(*section_, GetFdeFromPc(0x1000)).WillOnce(::testing::Return(&fde));
+ EXPECT_CALL(*section_, GetCfaLocationInfo(0x1000, &fde, ::testing::_))
.WillOnce(::testing::Return(false));
bool finished;
- ASSERT_FALSE(mock_section.Step(0x1000, nullptr, nullptr, &finished));
+ ASSERT_FALSE(section_->Step(0x1000, nullptr, nullptr, &finished));
}
TEST_F(DwarfSectionTest, Step_pass) {
- MockDwarfSection mock_section(&memory_);
-
DwarfCie cie{};
DwarfFde fde{};
fde.pc_end = 0x2000;
fde.cie = &cie;
- EXPECT_CALL(mock_section, GetFdeOffsetFromPc(0x1000, ::testing::_))
- .WillOnce(::testing::Return(true));
- EXPECT_CALL(mock_section, GetFdeFromOffset(::testing::_)).WillOnce(::testing::Return(&fde));
-
- EXPECT_CALL(mock_section, GetCfaLocationInfo(0x1000, &fde, ::testing::_))
+ EXPECT_CALL(*section_, GetFdeFromPc(0x1000)).WillOnce(::testing::Return(&fde));
+ EXPECT_CALL(*section_, GetCfaLocationInfo(0x1000, &fde, ::testing::_))
.WillOnce(::testing::Return(true));
MemoryFake process;
- EXPECT_CALL(mock_section, Eval(&cie, &process, ::testing::_, nullptr, ::testing::_))
+ EXPECT_CALL(*section_, Eval(&cie, &process, ::testing::_, nullptr, ::testing::_))
.WillOnce(::testing::Return(true));
bool finished;
- ASSERT_TRUE(mock_section.Step(0x1000, nullptr, &process, &finished));
+ ASSERT_TRUE(section_->Step(0x1000, nullptr, &process, &finished));
}
static bool MockGetCfaLocationInfo(::testing::Unused, const DwarfFde* fde,
@@ -173,64 +115,53 @@
}
TEST_F(DwarfSectionTest, Step_cache) {
- MockDwarfSection mock_section(&memory_);
-
DwarfCie cie{};
DwarfFde fde{};
fde.pc_start = 0x500;
fde.pc_end = 0x2000;
fde.cie = &cie;
- EXPECT_CALL(mock_section, GetFdeOffsetFromPc(0x1000, ::testing::_))
- .WillOnce(::testing::Return(true));
- EXPECT_CALL(mock_section, GetFdeFromOffset(::testing::_)).WillOnce(::testing::Return(&fde));
-
- EXPECT_CALL(mock_section, GetCfaLocationInfo(0x1000, &fde, ::testing::_))
+ EXPECT_CALL(*section_, GetFdeFromPc(0x1000)).WillOnce(::testing::Return(&fde));
+ EXPECT_CALL(*section_, GetCfaLocationInfo(0x1000, &fde, ::testing::_))
.WillOnce(::testing::Invoke(MockGetCfaLocationInfo));
MemoryFake process;
- EXPECT_CALL(mock_section, Eval(&cie, &process, ::testing::_, nullptr, ::testing::_))
+ EXPECT_CALL(*section_, Eval(&cie, &process, ::testing::_, nullptr, ::testing::_))
.WillRepeatedly(::testing::Return(true));
bool finished;
- ASSERT_TRUE(mock_section.Step(0x1000, nullptr, &process, &finished));
- ASSERT_TRUE(mock_section.Step(0x1000, nullptr, &process, &finished));
- ASSERT_TRUE(mock_section.Step(0x1500, nullptr, &process, &finished));
+ ASSERT_TRUE(section_->Step(0x1000, nullptr, &process, &finished));
+ ASSERT_TRUE(section_->Step(0x1000, nullptr, &process, &finished));
+ ASSERT_TRUE(section_->Step(0x1500, nullptr, &process, &finished));
}
TEST_F(DwarfSectionTest, Step_cache_not_in_pc) {
- MockDwarfSection mock_section(&memory_);
-
DwarfCie cie{};
DwarfFde fde0{};
fde0.pc_start = 0x1000;
fde0.pc_end = 0x2000;
fde0.cie = &cie;
- EXPECT_CALL(mock_section, GetFdeOffsetFromPc(0x1000, ::testing::_))
- .WillOnce(::testing::Return(true));
- EXPECT_CALL(mock_section, GetFdeFromOffset(::testing::_)).WillOnce(::testing::Return(&fde0));
- EXPECT_CALL(mock_section, GetCfaLocationInfo(0x1000, &fde0, ::testing::_))
+ EXPECT_CALL(*section_, GetFdeFromPc(0x1000)).WillOnce(::testing::Return(&fde0));
+ EXPECT_CALL(*section_, GetCfaLocationInfo(0x1000, &fde0, ::testing::_))
.WillOnce(::testing::Invoke(MockGetCfaLocationInfo));
MemoryFake process;
- EXPECT_CALL(mock_section, Eval(&cie, &process, ::testing::_, nullptr, ::testing::_))
+ EXPECT_CALL(*section_, Eval(&cie, &process, ::testing::_, nullptr, ::testing::_))
.WillRepeatedly(::testing::Return(true));
bool finished;
- ASSERT_TRUE(mock_section.Step(0x1000, nullptr, &process, &finished));
+ ASSERT_TRUE(section_->Step(0x1000, nullptr, &process, &finished));
DwarfFde fde1{};
fde1.pc_start = 0x500;
fde1.pc_end = 0x800;
fde1.cie = &cie;
- EXPECT_CALL(mock_section, GetFdeOffsetFromPc(0x600, ::testing::_))
- .WillOnce(::testing::Return(true));
- EXPECT_CALL(mock_section, GetFdeFromOffset(::testing::_)).WillOnce(::testing::Return(&fde1));
- EXPECT_CALL(mock_section, GetCfaLocationInfo(0x600, &fde1, ::testing::_))
+ EXPECT_CALL(*section_, GetFdeFromPc(0x600)).WillOnce(::testing::Return(&fde1));
+ EXPECT_CALL(*section_, GetCfaLocationInfo(0x600, &fde1, ::testing::_))
.WillOnce(::testing::Invoke(MockGetCfaLocationInfo));
- ASSERT_TRUE(mock_section.Step(0x600, nullptr, &process, &finished));
- ASSERT_TRUE(mock_section.Step(0x700, nullptr, &process, &finished));
+ ASSERT_TRUE(section_->Step(0x600, nullptr, &process, &finished));
+ ASSERT_TRUE(section_->Step(0x700, nullptr, &process, &finished));
}
} // namespace unwindstack
diff --git a/libunwindstack/tests/ElfInterfaceTest.cpp b/libunwindstack/tests/ElfInterfaceTest.cpp
index 487d39c..aa6df84 100644
--- a/libunwindstack/tests/ElfInterfaceTest.cpp
+++ b/libunwindstack/tests/ElfInterfaceTest.cpp
@@ -656,8 +656,7 @@
memory_.SetData32(0x5000, 0xfc);
memory_.SetData32(0x5004, 0xffffffff);
- memory_.SetData8(0x5008, 1);
- memory_.SetData8(0x5009, '\0');
+ memory_.SetMemory(0x5008, std::vector<uint8_t>{1, '\0', 4, 8, 2});
memory_.SetData32(0x5100, 0xfc);
memory_.SetData32(0x5104, 0);
@@ -678,56 +677,6 @@
InitHeadersDebugFrame<ElfInterface64Fake>();
}
-template <typename ElfType>
-void ElfInterfaceTest::InitHeadersEhFrameFail() {
- ElfType elf(&memory_);
-
- elf.FakeSetEhFrameOffset(0x1000);
- elf.FakeSetEhFrameSize(0x100);
- elf.FakeSetDebugFrameOffset(0);
- elf.FakeSetDebugFrameSize(0);
-
- elf.InitHeaders(0);
-
- EXPECT_TRUE(elf.eh_frame() == nullptr);
- EXPECT_EQ(0U, elf.eh_frame_offset());
- EXPECT_EQ(static_cast<uint64_t>(-1), elf.eh_frame_size());
- EXPECT_TRUE(elf.debug_frame() == nullptr);
-}
-
-TEST_F(ElfInterfaceTest, init_headers_eh_frame32_fail) {
- InitHeadersEhFrameFail<ElfInterface32Fake>();
-}
-
-TEST_F(ElfInterfaceTest, init_headers_eh_frame64_fail) {
- InitHeadersEhFrameFail<ElfInterface64Fake>();
-}
-
-template <typename ElfType>
-void ElfInterfaceTest::InitHeadersDebugFrameFail() {
- ElfType elf(&memory_);
-
- elf.FakeSetEhFrameOffset(0);
- elf.FakeSetEhFrameSize(0);
- elf.FakeSetDebugFrameOffset(0x1000);
- elf.FakeSetDebugFrameSize(0x100);
-
- elf.InitHeaders(0);
-
- EXPECT_TRUE(elf.eh_frame() == nullptr);
- EXPECT_TRUE(elf.debug_frame() == nullptr);
- EXPECT_EQ(0U, elf.debug_frame_offset());
- EXPECT_EQ(static_cast<uint64_t>(-1), elf.debug_frame_size());
-}
-
-TEST_F(ElfInterfaceTest, init_headers_debug_frame32_fail) {
- InitHeadersDebugFrameFail<ElfInterface32Fake>();
-}
-
-TEST_F(ElfInterfaceTest, init_headers_debug_frame64_fail) {
- InitHeadersDebugFrameFail<ElfInterface64Fake>();
-}
-
template <typename Ehdr, typename Shdr, typename ElfInterfaceType>
void ElfInterfaceTest::InitSectionHeadersMalformed() {
std::unique_ptr<ElfInterfaceType> elf(new ElfInterfaceType(&memory_));
@@ -1024,11 +973,7 @@
// CIE 32.
memory_.SetData32(0x600, 0xfc);
memory_.SetData32(0x604, 0xffffffff);
- memory_.SetData8(0x608, 1);
- memory_.SetData8(0x609, '\0');
- memory_.SetData8(0x60a, 0x4);
- memory_.SetData8(0x60b, 0x4);
- memory_.SetData8(0x60c, 0x1);
+ memory_.SetMemory(0x608, std::vector<uint8_t>{1, '\0', 4, 4, 1});
// FDE 32.
memory_.SetData32(0x700, 0xfc);
@@ -1085,11 +1030,7 @@
// CIE 32.
memory_.SetData32(0x600, 0xfc);
memory_.SetData32(0x604, 0);
- memory_.SetData8(0x608, 1);
- memory_.SetData8(0x609, '\0');
- memory_.SetData8(0x60a, 0x4);
- memory_.SetData8(0x60b, 0x4);
- memory_.SetData8(0x60c, 0x1);
+ memory_.SetMemory(0x608, std::vector<uint8_t>{1, '\0', 4, 4, 1});
// FDE 32.
memory_.SetData32(0x700, 0xfc);