1 /*
2 * Copyright (C) 2018 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17 #include <stdint.h>
18
19 #include <vector>
20
21 #include <gtest/gtest.h>
22
23 #include "MemoryRange.h"
24 #include "utils/MemoryFake.h"
25
26 namespace unwindstack {
27
28 class MemoryRangesTest : public ::testing::Test {
29 protected:
SetUp()30 void SetUp() override {
31 MemoryFake* memory = new MemoryFake;
32 process_memory_.reset(memory);
33 memory->SetMemoryBlock(1000, 5000, 0x15);
34 memory->SetMemoryBlock(6000, 12000, 0x26);
35 memory->SetMemoryBlock(14000, 20000, 0x37);
36 memory->SetMemoryBlock(20000, 22000, 0x48);
37
38 ranges_.reset(new MemoryRanges);
39 ranges_->Insert(new MemoryRange(process_memory_, 15000, 100, 4000));
40 ranges_->Insert(new MemoryRange(process_memory_, 10000, 2000, 2000));
41 ranges_->Insert(new MemoryRange(process_memory_, 3000, 1000, 0));
42 ranges_->Insert(new MemoryRange(process_memory_, 19000, 1000, 6000));
43 ranges_->Insert(new MemoryRange(process_memory_, 20000, 1000, 7000));
44 }
45
46 std::shared_ptr<Memory> process_memory_;
47 std::unique_ptr<MemoryRanges> ranges_;
48 };
49
TEST_F(MemoryRangesTest,read)50 TEST_F(MemoryRangesTest, read) {
51 std::vector<uint8_t> dst(2000);
52 size_t bytes = ranges_->Read(0, dst.data(), dst.size());
53 ASSERT_EQ(1000UL, bytes);
54 for (size_t i = 0; i < bytes; i++) {
55 ASSERT_EQ(0x15U, dst[i]) << "Failed at byte " << i;
56 }
57
58 bytes = ranges_->Read(2000, dst.data(), dst.size());
59 ASSERT_EQ(2000UL, bytes);
60 for (size_t i = 0; i < bytes; i++) {
61 ASSERT_EQ(0x26U, dst[i]) << "Failed at byte " << i;
62 }
63
64 bytes = ranges_->Read(4000, dst.data(), dst.size());
65 ASSERT_EQ(100UL, bytes);
66 for (size_t i = 0; i < bytes; i++) {
67 ASSERT_EQ(0x37U, dst[i]) << "Failed at byte " << i;
68 }
69 }
70
TEST_F(MemoryRangesTest,read_fail)71 TEST_F(MemoryRangesTest, read_fail) {
72 std::vector<uint8_t> dst(4096);
73 ASSERT_EQ(0UL, ranges_->Read(1000, dst.data(), dst.size()));
74 ASSERT_EQ(0UL, ranges_->Read(5000, dst.data(), dst.size()));
75 ASSERT_EQ(0UL, ranges_->Read(8000, dst.data(), dst.size()));
76 }
77
TEST_F(MemoryRangesTest,read_across_ranges)78 TEST_F(MemoryRangesTest, read_across_ranges) {
79 // The MemoryRanges object does not support reading across a range,
80 // so this will only read in the first range.
81 std::vector<uint8_t> dst(4096);
82 size_t bytes = ranges_->Read(6000, dst.data(), dst.size());
83 ASSERT_EQ(1000UL, bytes);
84 for (size_t i = 0; i < bytes; i++) {
85 ASSERT_EQ(0x37U, dst[i]) << "Failed at byte " << i;
86 }
87 }
88
TEST_F(MemoryRangesTest,duplicate_last_addr)89 TEST_F(MemoryRangesTest, duplicate_last_addr) {
90 MemoryRanges ranges;
91 ASSERT_TRUE(ranges.Insert(new MemoryRange(nullptr, 0x1000, 0x2000, 0x1000)));
92 ASSERT_FALSE(ranges.Insert(new MemoryRange(nullptr, 0x2000, 0x1000, 0x2000)));
93 }
94
95 } // namespace unwindstack
96