From ec1efe71130f5b049e53828281204b50d89d4cf6 Mon Sep 17 00:00:00 2001 From: Ayke van Laethem Date: Tue, 4 Feb 2020 16:29:01 +0100 Subject: [PATCH] [LLDB] Let DataExtractor deal with two-byte addresses AVR usually uses two byte addresses. By making DataExtractor deal with this, it is possible to load AVR binaries that don't have debug info associated with them. Differential Revision: https://reviews.llvm.org/D73969 --- lldb/source/Utility/DataExtractor.cpp | 14 ++++++------ lldb/unittests/Utility/DataExtractorTest.cpp | 33 ++++++++++++++++++++++++++++ 2 files changed, 40 insertions(+), 7 deletions(-) diff --git a/lldb/source/Utility/DataExtractor.cpp b/lldb/source/Utility/DataExtractor.cpp index fd4b764..40819f1 100644 --- a/lldb/source/Utility/DataExtractor.cpp +++ b/lldb/source/Utility/DataExtractor.cpp @@ -133,7 +133,7 @@ DataExtractor::DataExtractor(const void *data, offset_t length, m_end(const_cast(static_cast(data)) + length), m_byte_order(endian), m_addr_size(addr_size), m_data_sp(), m_target_byte_size(target_byte_size) { - assert(addr_size == 4 || addr_size == 8); + assert(addr_size >= 1 && addr_size <= 8); } // Make a shared pointer reference to the shared data in "data_sp" and set the @@ -146,7 +146,7 @@ DataExtractor::DataExtractor(const DataBufferSP &data_sp, ByteOrder endian, : m_start(nullptr), m_end(nullptr), m_byte_order(endian), m_addr_size(addr_size), m_data_sp(), m_target_byte_size(target_byte_size) { - assert(addr_size == 4 || addr_size == 8); + assert(addr_size >= 1 && addr_size <= 8); SetData(data_sp); } @@ -160,7 +160,7 @@ DataExtractor::DataExtractor(const DataExtractor &data, offset_t offset, : m_start(nullptr), m_end(nullptr), m_byte_order(data.m_byte_order), m_addr_size(data.m_addr_size), m_data_sp(), m_target_byte_size(target_byte_size) { - assert(m_addr_size == 4 || m_addr_size == 8); + assert(m_addr_size >= 1 && m_addr_size <= 8); if (data.ValidOffset(offset)) { offset_t bytes_available = data.GetByteSize() - offset; if (length > bytes_available) @@ -173,7 +173,7 @@ DataExtractor::DataExtractor(const DataExtractor &rhs) : m_start(rhs.m_start), m_end(rhs.m_end), m_byte_order(rhs.m_byte_order), m_addr_size(rhs.m_addr_size), m_data_sp(rhs.m_data_sp), m_target_byte_size(rhs.m_target_byte_size) { - assert(m_addr_size == 4 || m_addr_size == 8); + assert(m_addr_size >= 1 && m_addr_size <= 8); } // Assignment operator @@ -251,7 +251,7 @@ lldb::offset_t DataExtractor::SetData(const DataExtractor &data, offset_t data_offset, offset_t data_length) { m_addr_size = data.m_addr_size; - assert(m_addr_size == 4 || m_addr_size == 8); + assert(m_addr_size >= 1 && m_addr_size <= 8); // If "data" contains shared pointer to data, then we can use that if (data.m_data_sp) { m_byte_order = data.m_byte_order; @@ -680,12 +680,12 @@ long double DataExtractor::GetLongDouble(offset_t *offset_ptr) const { // // RETURNS the address that was extracted, or zero on failure. uint64_t DataExtractor::GetAddress(offset_t *offset_ptr) const { - assert(m_addr_size == 4 || m_addr_size == 8); + assert(m_addr_size >= 1 && m_addr_size <= 8); return GetMaxU64(offset_ptr, m_addr_size); } uint64_t DataExtractor::GetAddress_unchecked(offset_t *offset_ptr) const { - assert(m_addr_size == 4 || m_addr_size == 8); + assert(m_addr_size >= 1 && m_addr_size <= 8); return GetMaxU64_unchecked(offset_ptr, m_addr_size); } diff --git a/lldb/unittests/Utility/DataExtractorTest.cpp b/lldb/unittests/Utility/DataExtractorTest.cpp index 0b08324..f412ab8 100644 --- a/lldb/unittests/Utility/DataExtractorTest.cpp +++ b/lldb/unittests/Utility/DataExtractorTest.cpp @@ -112,6 +112,39 @@ TEST(DataExtractorTest, GetCStrAtNullOffset) { EXPECT_EQ(4U, offset); } +TEST(DataExtractorTest, UncommonAddressSize) { + uint8_t buffer[] = {0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08}; + DataExtractor E2(buffer, sizeof buffer, lldb::eByteOrderLittle, 2); + DataExtractor E5(buffer, sizeof buffer, lldb::eByteOrderLittle, 5); + DataExtractor E7(buffer, sizeof buffer, lldb::eByteOrderLittle, 7); + + lldb::offset_t offset; + + // Test 2-byte addresses (for AVR). + offset = 0; + EXPECT_EQ(0x0201U, E2.GetMaxU64(&offset, 2)); + EXPECT_EQ(2U, offset); + offset = 0; + EXPECT_EQ(0x0201U, E2.GetAddress(&offset)); + EXPECT_EQ(2U, offset); + + // Test 5-byte addresses. + offset = 0; + EXPECT_EQ(0x030201U, E5.GetMaxU64(&offset, 3)); + EXPECT_EQ(3U, offset); + offset = 3; + EXPECT_EQ(0x0807060504U, E5.GetAddress(&offset)); + EXPECT_EQ(8U, offset); + + // Test 7-byte addresses. + offset = 0; + EXPECT_EQ(0x0504030201U, E7.GetMaxU64(&offset, 5)); + EXPECT_EQ(5U, offset); + offset = 0; + EXPECT_EQ(0x07060504030201U, E7.GetAddress(&offset)); + EXPECT_EQ(7U, offset); +} + TEST(DataExtractorTest, GetMaxU64) { uint8_t buffer[] = {0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08}; DataExtractor LE(buffer, sizeof(buffer), lldb::eByteOrderLittle, -- 2.7.4