android_system_core/libunwindstack/tests/DwarfMemoryTest.cpp
Christopher Ferris a39aaf91eb Remove CHECK in AdjustEncodedValue.
The CHECK(encoding != DW_EH_PE_aligned) can trip given the right
arguments. This check isn't necessary, since the code will return
false in that case.

Add new unit test that tries all values to make sure no CHECK fires.

Bug: 120968571

Test: Passes new unit test, and passes fuzzing that failed before.
Change-Id: I062bcd18508c75cd3a4ca9dd12f922e25aafda8a
2018-12-20 08:40:58 -08:00

545 lines
16 KiB
C++

/*
* Copyright (C) 2017 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include <stdint.h>
#include <ios>
#include <vector>
#include <gtest/gtest.h>
#include <unwindstack/DwarfMemory.h>
#include "MemoryFake.h"
namespace unwindstack {
class DwarfMemoryTest : public ::testing::Test {
protected:
void SetUp() override {
memory_.Clear();
dwarf_mem_.reset(new DwarfMemory(&memory_));
}
template <typename AddressType>
void GetEncodedSizeTest(uint8_t value, size_t expected);
template <typename AddressType>
void ReadEncodedValue_omit();
template <typename AddressType>
void ReadEncodedValue_leb128();
template <typename AddressType>
void ReadEncodedValue_data1();
template <typename AddressType>
void ReadEncodedValue_data2();
template <typename AddressType>
void ReadEncodedValue_data4();
template <typename AddressType>
void ReadEncodedValue_data8();
template <typename AddressType>
void ReadEncodedValue_non_zero_adjust();
template <typename AddressType>
void ReadEncodedValue_overflow();
template <typename AddressType>
void ReadEncodedValue_high_bit_set();
template <typename AddressType>
void ReadEncodedValue_all();
MemoryFake memory_;
std::unique_ptr<DwarfMemory> dwarf_mem_;
};
TEST_F(DwarfMemoryTest, ReadBytes) {
memory_.SetMemory(0, std::vector<uint8_t>{0x10, 0x18, 0xff, 0xfe});
uint8_t byte;
ASSERT_TRUE(dwarf_mem_->ReadBytes(&byte, 1));
ASSERT_EQ(0x10U, byte);
ASSERT_TRUE(dwarf_mem_->ReadBytes(&byte, 1));
ASSERT_EQ(0x18U, byte);
ASSERT_TRUE(dwarf_mem_->ReadBytes(&byte, 1));
ASSERT_EQ(0xffU, byte);
ASSERT_TRUE(dwarf_mem_->ReadBytes(&byte, 1));
ASSERT_EQ(0xfeU, byte);
ASSERT_EQ(4U, dwarf_mem_->cur_offset());
dwarf_mem_->set_cur_offset(2);
ASSERT_TRUE(dwarf_mem_->ReadBytes(&byte, 1));
ASSERT_EQ(0xffU, byte);
ASSERT_EQ(3U, dwarf_mem_->cur_offset());
}
TEST_F(DwarfMemoryTest, ReadSigned_check) {
uint64_t value;
// Signed 8 byte reads.
memory_.SetData8(0, static_cast<uint8_t>(-10));
memory_.SetData8(1, 200);
ASSERT_TRUE(dwarf_mem_->ReadSigned<int8_t>(&value));
ASSERT_EQ(static_cast<int8_t>(-10), static_cast<int8_t>(value));
ASSERT_TRUE(dwarf_mem_->ReadSigned<int8_t>(&value));
ASSERT_EQ(static_cast<int8_t>(200), static_cast<int8_t>(value));
// Signed 16 byte reads.
memory_.SetData16(0x10, static_cast<uint16_t>(-1000));
memory_.SetData16(0x12, 50100);
dwarf_mem_->set_cur_offset(0x10);
ASSERT_TRUE(dwarf_mem_->ReadSigned<int16_t>(&value));
ASSERT_EQ(static_cast<int16_t>(-1000), static_cast<int16_t>(value));
ASSERT_TRUE(dwarf_mem_->ReadSigned<int16_t>(&value));
ASSERT_EQ(static_cast<int16_t>(50100), static_cast<int16_t>(value));
// Signed 32 byte reads.
memory_.SetData32(0x100, static_cast<uint32_t>(-1000000000));
memory_.SetData32(0x104, 3000000000);
dwarf_mem_->set_cur_offset(0x100);
ASSERT_TRUE(dwarf_mem_->ReadSigned<int32_t>(&value));
ASSERT_EQ(static_cast<int32_t>(-1000000000), static_cast<int32_t>(value));
ASSERT_TRUE(dwarf_mem_->ReadSigned<int32_t>(&value));
ASSERT_EQ(static_cast<int32_t>(3000000000), static_cast<int32_t>(value));
// Signed 64 byte reads.
memory_.SetData64(0x200, static_cast<uint64_t>(-2000000000000LL));
memory_.SetData64(0x208, 5000000000000LL);
dwarf_mem_->set_cur_offset(0x200);
ASSERT_TRUE(dwarf_mem_->ReadSigned<int64_t>(&value));
ASSERT_EQ(static_cast<int64_t>(-2000000000000), static_cast<int64_t>(value));
ASSERT_TRUE(dwarf_mem_->ReadSigned<int64_t>(&value));
ASSERT_EQ(static_cast<int64_t>(5000000000000), static_cast<int64_t>(value));
}
TEST_F(DwarfMemoryTest, ReadULEB128) {
memory_.SetMemory(0, std::vector<uint8_t>{0x01, 0x80, 0x24, 0xff, 0xc3, 0xff, 0x7f});
uint64_t value;
ASSERT_TRUE(dwarf_mem_->ReadULEB128(&value));
ASSERT_EQ(1U, dwarf_mem_->cur_offset());
ASSERT_EQ(1U, value);
ASSERT_TRUE(dwarf_mem_->ReadULEB128(&value));
ASSERT_EQ(3U, dwarf_mem_->cur_offset());
ASSERT_EQ(0x1200U, value);
ASSERT_TRUE(dwarf_mem_->ReadULEB128(&value));
ASSERT_EQ(7U, dwarf_mem_->cur_offset());
ASSERT_EQ(0xfffe1ffU, value);
}
TEST_F(DwarfMemoryTest, ReadSLEB128) {
memory_.SetMemory(0, std::vector<uint8_t>{0x06, 0x40, 0x82, 0x34, 0x89, 0x64, 0xf9, 0xc3, 0x8f,
0x2f, 0xbf, 0xc3, 0xf7, 0x5f});
int64_t value;
ASSERT_TRUE(dwarf_mem_->ReadSLEB128(&value));
ASSERT_EQ(1U, dwarf_mem_->cur_offset());
ASSERT_EQ(6U, value);
ASSERT_TRUE(dwarf_mem_->ReadSLEB128(&value));
ASSERT_EQ(2U, dwarf_mem_->cur_offset());
ASSERT_EQ(0xffffffffffffffc0ULL, static_cast<uint64_t>(value));
ASSERT_TRUE(dwarf_mem_->ReadSLEB128(&value));
ASSERT_EQ(4U, dwarf_mem_->cur_offset());
ASSERT_EQ(0x1a02U, value);
ASSERT_TRUE(dwarf_mem_->ReadSLEB128(&value));
ASSERT_EQ(6U, dwarf_mem_->cur_offset());
ASSERT_EQ(0xfffffffffffff209ULL, static_cast<uint64_t>(value));
ASSERT_TRUE(dwarf_mem_->ReadSLEB128(&value));
ASSERT_EQ(10U, dwarf_mem_->cur_offset());
ASSERT_EQ(0x5e3e1f9U, value);
ASSERT_TRUE(dwarf_mem_->ReadSLEB128(&value));
ASSERT_EQ(14U, dwarf_mem_->cur_offset());
ASSERT_EQ(0xfffffffffbfde1bfULL, static_cast<uint64_t>(value));
}
template <typename AddressType>
void DwarfMemoryTest::GetEncodedSizeTest(uint8_t value, size_t expected) {
for (size_t i = 0; i < 16; i++) {
uint8_t encoding = (i << 4) | value;
ASSERT_EQ(expected, dwarf_mem_->GetEncodedSize<AddressType>(encoding))
<< "encoding 0x" << std::hex << static_cast<uint32_t>(encoding) << " test value 0x"
<< static_cast<size_t>(value);
}
}
TEST_F(DwarfMemoryTest, GetEncodedSize_absptr_uint32_t) {
GetEncodedSizeTest<uint32_t>(0, sizeof(uint32_t));
}
TEST_F(DwarfMemoryTest, GetEncodedSize_absptr_uint64_t) {
GetEncodedSizeTest<uint64_t>(0, sizeof(uint64_t));
}
TEST_F(DwarfMemoryTest, GetEncodedSize_data1) {
// udata1
GetEncodedSizeTest<uint32_t>(0x0d, 1);
GetEncodedSizeTest<uint64_t>(0x0d, 1);
// sdata1
GetEncodedSizeTest<uint32_t>(0x0e, 1);
GetEncodedSizeTest<uint64_t>(0x0e, 1);
}
TEST_F(DwarfMemoryTest, GetEncodedSize_data2) {
// udata2
GetEncodedSizeTest<uint32_t>(0x02, 2);
GetEncodedSizeTest<uint64_t>(0x02, 2);
// sdata2
GetEncodedSizeTest<uint32_t>(0x0a, 2);
GetEncodedSizeTest<uint64_t>(0x0a, 2);
}
TEST_F(DwarfMemoryTest, GetEncodedSize_data4) {
// udata4
GetEncodedSizeTest<uint32_t>(0x03, 4);
GetEncodedSizeTest<uint64_t>(0x03, 4);
// sdata4
GetEncodedSizeTest<uint32_t>(0x0b, 4);
GetEncodedSizeTest<uint64_t>(0x0b, 4);
}
TEST_F(DwarfMemoryTest, GetEncodedSize_data8) {
// udata8
GetEncodedSizeTest<uint32_t>(0x04, 8);
GetEncodedSizeTest<uint64_t>(0x04, 8);
// sdata8
GetEncodedSizeTest<uint32_t>(0x0c, 8);
GetEncodedSizeTest<uint64_t>(0x0c, 8);
}
TEST_F(DwarfMemoryTest, GetEncodedSize_unknown) {
GetEncodedSizeTest<uint32_t>(0x01, 0);
GetEncodedSizeTest<uint64_t>(0x01, 0);
GetEncodedSizeTest<uint32_t>(0x09, 0);
GetEncodedSizeTest<uint64_t>(0x09, 0);
GetEncodedSizeTest<uint32_t>(0x0f, 0);
GetEncodedSizeTest<uint64_t>(0x0f, 0);
}
template <typename AddressType>
void DwarfMemoryTest::ReadEncodedValue_omit() {
uint64_t value = 123;
ASSERT_TRUE(dwarf_mem_->ReadEncodedValue<AddressType>(0xff, &value));
ASSERT_EQ(0U, value);
}
TEST_F(DwarfMemoryTest, ReadEncodedValue_omit_uint32_t) {
ReadEncodedValue_omit<uint32_t>();
}
TEST_F(DwarfMemoryTest, ReadEncodedValue_omit_uint64_t) {
ReadEncodedValue_omit<uint64_t>();
}
TEST_F(DwarfMemoryTest, ReadEncodedValue_absptr_uint32_t) {
uint64_t value = 100;
ASSERT_FALSE(dwarf_mem_->ReadEncodedValue<uint32_t>(0x00, &value));
memory_.SetData32(0, 0x12345678);
ASSERT_TRUE(dwarf_mem_->ReadEncodedValue<uint32_t>(0x00, &value));
ASSERT_EQ(4U, dwarf_mem_->cur_offset());
ASSERT_EQ(0x12345678U, value);
}
TEST_F(DwarfMemoryTest, ReadEncodedValue_absptr_uint64_t) {
uint64_t value = 100;
ASSERT_FALSE(dwarf_mem_->ReadEncodedValue<uint64_t>(0x00, &value));
memory_.SetData64(0, 0x12345678f1f2f3f4ULL);
ASSERT_TRUE(dwarf_mem_->ReadEncodedValue<uint64_t>(0x00, &value));
ASSERT_EQ(8U, dwarf_mem_->cur_offset());
ASSERT_EQ(0x12345678f1f2f3f4ULL, value);
}
TEST_F(DwarfMemoryTest, ReadEncodedValue_aligned_uint32_t) {
uint64_t value = 100;
dwarf_mem_->set_cur_offset(1);
ASSERT_FALSE(dwarf_mem_->ReadEncodedValue<uint32_t>(0x50, &value));
memory_.SetData32(4, 0x12345678);
ASSERT_TRUE(dwarf_mem_->ReadEncodedValue<uint32_t>(0x50, &value));
ASSERT_EQ(8U, dwarf_mem_->cur_offset());
ASSERT_EQ(0x12345678U, value);
}
TEST_F(DwarfMemoryTest, ReadEncodedValue_aligned_uint64_t) {
uint64_t value = 100;
dwarf_mem_->set_cur_offset(1);
ASSERT_FALSE(dwarf_mem_->ReadEncodedValue<uint64_t>(0x50, &value));
memory_.SetData64(8, 0x12345678f1f2f3f4ULL);
ASSERT_TRUE(dwarf_mem_->ReadEncodedValue<uint64_t>(0x50, &value));
ASSERT_EQ(16U, dwarf_mem_->cur_offset());
ASSERT_EQ(0x12345678f1f2f3f4ULL, value);
}
template <typename AddressType>
void DwarfMemoryTest::ReadEncodedValue_leb128() {
memory_.SetMemory(0, std::vector<uint8_t>{0x80, 0x42});
uint64_t value = 100;
// uleb128
ASSERT_TRUE(dwarf_mem_->ReadEncodedValue<AddressType>(0x01, &value));
ASSERT_EQ(0x2100U, value);
dwarf_mem_->set_cur_offset(0);
// sleb128
ASSERT_TRUE(dwarf_mem_->ReadEncodedValue<AddressType>(0x09, &value));
ASSERT_EQ(0xffffffffffffe100ULL, value);
}
TEST_F(DwarfMemoryTest, ReadEncodedValue_leb128_uint32_t) {
ReadEncodedValue_leb128<uint32_t>();
}
TEST_F(DwarfMemoryTest, ReadEncodedValue_leb128_uint64_t) {
ReadEncodedValue_leb128<uint64_t>();
}
template <typename AddressType>
void DwarfMemoryTest::ReadEncodedValue_data1() {
memory_.SetData8(0, 0xe0);
uint64_t value = 0;
ASSERT_TRUE(dwarf_mem_->ReadEncodedValue<AddressType>(0x0d, &value));
ASSERT_EQ(0xe0U, value);
dwarf_mem_->set_cur_offset(0);
ASSERT_TRUE(dwarf_mem_->ReadEncodedValue<AddressType>(0x0e, &value));
ASSERT_EQ(0xffffffffffffffe0ULL, value);
}
TEST_F(DwarfMemoryTest, ReadEncodedValue_data1_uint32_t) {
ReadEncodedValue_data1<uint32_t>();
}
TEST_F(DwarfMemoryTest, ReadEncodedValue_data1_uint64_t) {
ReadEncodedValue_data1<uint64_t>();
}
template <typename AddressType>
void DwarfMemoryTest::ReadEncodedValue_data2() {
memory_.SetData16(0, 0xe000);
uint64_t value = 0;
ASSERT_TRUE(dwarf_mem_->ReadEncodedValue<AddressType>(0x02, &value));
ASSERT_EQ(0xe000U, value);
dwarf_mem_->set_cur_offset(0);
ASSERT_TRUE(dwarf_mem_->ReadEncodedValue<AddressType>(0x0a, &value));
ASSERT_EQ(0xffffffffffffe000ULL, value);
}
TEST_F(DwarfMemoryTest, ReadEncodedValue_data2_uint32_t) {
ReadEncodedValue_data2<uint32_t>();
}
TEST_F(DwarfMemoryTest, ReadEncodedValue_data2_uint64_t) {
ReadEncodedValue_data2<uint64_t>();
}
template <typename AddressType>
void DwarfMemoryTest::ReadEncodedValue_data4() {
memory_.SetData32(0, 0xe0000000);
uint64_t value = 0;
ASSERT_TRUE(dwarf_mem_->ReadEncodedValue<AddressType>(0x03, &value));
ASSERT_EQ(0xe0000000U, value);
dwarf_mem_->set_cur_offset(0);
ASSERT_TRUE(dwarf_mem_->ReadEncodedValue<AddressType>(0x0b, &value));
ASSERT_EQ(0xffffffffe0000000ULL, value);
}
TEST_F(DwarfMemoryTest, ReadEncodedValue_data4_uint32_t) {
ReadEncodedValue_data4<uint32_t>();
}
TEST_F(DwarfMemoryTest, ReadEncodedValue_data4_uint64_t) {
ReadEncodedValue_data4<uint64_t>();
}
template <typename AddressType>
void DwarfMemoryTest::ReadEncodedValue_data8() {
memory_.SetData64(0, 0xe000000000000000ULL);
uint64_t value = 0;
ASSERT_TRUE(dwarf_mem_->ReadEncodedValue<AddressType>(0x04, &value));
ASSERT_EQ(0xe000000000000000ULL, value);
dwarf_mem_->set_cur_offset(0);
ASSERT_TRUE(dwarf_mem_->ReadEncodedValue<AddressType>(0x0c, &value));
ASSERT_EQ(0xe000000000000000ULL, value);
}
TEST_F(DwarfMemoryTest, ReadEncodedValue_data8_uint32_t) {
ReadEncodedValue_data8<uint32_t>();
}
TEST_F(DwarfMemoryTest, ReadEncodedValue_data8_uint64_t) {
ReadEncodedValue_data8<uint64_t>();
}
template <typename AddressType>
void DwarfMemoryTest::ReadEncodedValue_non_zero_adjust() {
memory_.SetData64(0, 0xe000000000000000ULL);
uint64_t value = 0;
dwarf_mem_->set_pc_offset(0x2000);
ASSERT_TRUE(dwarf_mem_->ReadEncodedValue<AddressType>(0x14, &value));
ASSERT_EQ(0xe000000000002000ULL, value);
}
TEST_F(DwarfMemoryTest, ReadEncodedValue_non_zero_adjust_uint32_t) {
ReadEncodedValue_non_zero_adjust<uint32_t>();
}
TEST_F(DwarfMemoryTest, ReadEncodedValue_non_zero_adjust_uint64_t) {
ReadEncodedValue_non_zero_adjust<uint64_t>();
}
template <typename AddressType>
void DwarfMemoryTest::ReadEncodedValue_overflow() {
memory_.SetData64(0, 0);
uint64_t value = 0;
dwarf_mem_->set_cur_offset(UINT64_MAX);
ASSERT_FALSE(dwarf_mem_->ReadEncodedValue<AddressType>(0x50, &value));
}
TEST_F(DwarfMemoryTest, ReadEncodedValue_overflow_uint32_t) {
ReadEncodedValue_overflow<uint32_t>();
}
TEST_F(DwarfMemoryTest, ReadEncodedValue_overflow_uint64_t) {
ReadEncodedValue_overflow<uint64_t>();
}
template <typename AddressType>
void DwarfMemoryTest::ReadEncodedValue_high_bit_set() {
uint64_t value;
memory_.SetData32(0, 0x15234);
ASSERT_FALSE(dwarf_mem_->ReadEncodedValue<AddressType>(0xc3, &value));
dwarf_mem_->set_func_offset(0x60000);
dwarf_mem_->set_cur_offset(0);
ASSERT_TRUE(dwarf_mem_->ReadEncodedValue<AddressType>(0xc3, &value));
ASSERT_EQ(0x75234U, value);
}
TEST_F(DwarfMemoryTest, ReadEncodedValue_high_bit_set_uint32_t) {
ReadEncodedValue_high_bit_set<uint32_t>();
}
TEST_F(DwarfMemoryTest, ReadEncodedValue_high_bit_set_uint64_t) {
ReadEncodedValue_high_bit_set<uint64_t>();
}
template <typename AddressType>
void DwarfMemoryTest::ReadEncodedValue_all() {
MemoryFakeAlwaysReadZero memory;
DwarfMemory dwarf_mem(&memory);
for (size_t i = 0; i <= 0xff; i++) {
uint64_t value;
if (dwarf_mem.ReadEncodedValue<AddressType>(static_cast<uint8_t>(i), &value)) {
ASSERT_EQ(0U, value);
}
}
}
TEST_F(DwarfMemoryTest, ReadEncodedValue_all_uint32_t) {
ReadEncodedValue_all<uint32_t>();
}
TEST_F(DwarfMemoryTest, ReadEncodedValue_all_uint64_t) {
ReadEncodedValue_all<uint64_t>();
}
TEST_F(DwarfMemoryTest, AdjustEncodedValue_absptr) {
uint64_t value = 0x1234;
ASSERT_TRUE(dwarf_mem_->AdjustEncodedValue(0x00, &value));
ASSERT_EQ(0x1234U, value);
}
TEST_F(DwarfMemoryTest, AdjustEncodedValue_pcrel) {
uint64_t value = 0x1234;
ASSERT_FALSE(dwarf_mem_->AdjustEncodedValue(0x10, &value));
dwarf_mem_->set_pc_offset(0x2000);
ASSERT_TRUE(dwarf_mem_->AdjustEncodedValue(0x10, &value));
ASSERT_EQ(0x3234U, value);
dwarf_mem_->set_pc_offset(static_cast<uint64_t>(-4));
value = 0x1234;
ASSERT_TRUE(dwarf_mem_->AdjustEncodedValue(0x10, &value));
ASSERT_EQ(0x1230U, value);
}
TEST_F(DwarfMemoryTest, AdjustEncodedValue_textrel) {
uint64_t value = 0x8234;
ASSERT_FALSE(dwarf_mem_->AdjustEncodedValue(0x20, &value));
dwarf_mem_->set_text_offset(0x1000);
ASSERT_TRUE(dwarf_mem_->AdjustEncodedValue(0x20, &value));
ASSERT_EQ(0x9234U, value);
dwarf_mem_->set_text_offset(static_cast<uint64_t>(-16));
value = 0x8234;
ASSERT_TRUE(dwarf_mem_->AdjustEncodedValue(0x20, &value));
ASSERT_EQ(0x8224U, value);
}
TEST_F(DwarfMemoryTest, AdjustEncodedValue_datarel) {
uint64_t value = 0xb234;
ASSERT_FALSE(dwarf_mem_->AdjustEncodedValue(0x30, &value));
dwarf_mem_->set_data_offset(0x1200);
ASSERT_TRUE(dwarf_mem_->AdjustEncodedValue(0x30, &value));
ASSERT_EQ(0xc434U, value);
dwarf_mem_->set_data_offset(static_cast<uint64_t>(-256));
value = 0xb234;
ASSERT_TRUE(dwarf_mem_->AdjustEncodedValue(0x30, &value));
ASSERT_EQ(0xb134U, value);
}
TEST_F(DwarfMemoryTest, AdjustEncodedValue_funcrel) {
uint64_t value = 0x15234;
ASSERT_FALSE(dwarf_mem_->AdjustEncodedValue(0x40, &value));
dwarf_mem_->set_func_offset(0x60000);
ASSERT_TRUE(dwarf_mem_->AdjustEncodedValue(0x40, &value));
ASSERT_EQ(0x75234U, value);
dwarf_mem_->set_func_offset(static_cast<uint64_t>(-4096));
value = 0x15234;
ASSERT_TRUE(dwarf_mem_->AdjustEncodedValue(0x40, &value));
ASSERT_EQ(0x14234U, value);
}
} // namespace unwindstack