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 <vector> 18 19 #include <android-base/logging.h> 20 #include "dex/compact_offset_table.h" 21 #include "gtest/gtest.h" 22 23 namespace art { 24 25 TEST(CompactOffsetTableTest, TestBuildAndAccess) { 26 const size_t kDebugInfoMinOffset = 1234567; 27 std::vector<uint32_t> offsets = { 28 0, 17, 2, 3, 11, 0, 0, 0, 0, 1, 0, 1552, 100, 122, 44, 1234567, 0, 0, 29 std::numeric_limits<uint32_t>::max() - kDebugInfoMinOffset, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 30 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 12, 31 }; 32 // Add some large offset since the debug info section will never be that close to the beginning 33 // of the file. 34 for (uint32_t& offset : offsets) { 35 if (offset != 0u) { 36 offset += kDebugInfoMinOffset; 37 } 38 } 39 40 std::vector<uint8_t> data; 41 uint32_t min_offset = 0; 42 uint32_t table_offset = 0; 43 CompactOffsetTable::Build(offsets, /*out*/ &data, /*out*/ &min_offset, /*out*/ &table_offset); 44 EXPECT_GE(min_offset, kDebugInfoMinOffset); 45 EXPECT_LT(table_offset, data.size()); 46 ASSERT_GT(data.size(), 0u); 47 const size_t before_size = offsets.size() * sizeof(offsets.front()); 48 EXPECT_LT(data.size(), before_size); 49 50 // Note that the accessor requires the data to be aligned. Use memmap to accomplish this. 51 std::string error_msg; 52 // Leave some extra room since we don't copy the table at the start (for testing). 53 constexpr size_t kExtraOffset = 4 * 128; 54 std::vector<uint8_t> fake_dex(data.size() + kExtraOffset); 55 std::copy(data.begin(), data.end(), fake_dex.data() + kExtraOffset); 56 57 CompactOffsetTable::Accessor accessor(fake_dex.data() + kExtraOffset, min_offset, table_offset); 58 for (size_t i = 0; i < offsets.size(); ++i) { 59 EXPECT_EQ(offsets[i], accessor.GetOffset(i)); 60 } 61 62 // Sort to produce a try and produce a smaller table. This happens because the leb diff is smaller 63 // for sorted increasing order. 64 std::sort(offsets.begin(), offsets.end()); 65 std::vector<uint8_t> sorted_data; 66 CompactOffsetTable::Build(offsets, 67 /*out*/ &sorted_data, 68 /*out*/ &min_offset, 69 /*out*/ &table_offset); 70 EXPECT_LT(sorted_data.size(), data.size()); 71 { 72 android::base::ScopedLogSeverity sls(android::base::LogSeverity::INFO); 73 LOG(INFO) << "raw size " << before_size 74 << " table size " << data.size() 75 << " sorted table size " << sorted_data.size(); 76 } 77 78 // Test constructor and accessor that serialize/read offsets. 79 { 80 std::vector<uint8_t> data2; 81 CompactOffsetTable::Build(offsets, /*out*/ &data2); 82 CompactOffsetTable::Accessor accessor2(&data2[0]); 83 for (size_t i = 0; i < offsets.size(); ++i) { 84 EXPECT_EQ(offsets[i], accessor2.GetOffset(i)); 85 } 86 } 87 } 88 89 } // namespace art 90