blob: 0149a42c7c9f5b4e9f347391a8e2dad988457c7e [file] [log] [blame]
Christopher Ferris0b06a592018-01-19 10:26:36 -08001/*
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#include <sys/types.h>
19#include <unistd.h>
20
21#include <unordered_map>
22
Mark Salyzyn9f1cf252018-11-12 12:45:59 -080023#include <android-base/file.h>
Martin Stjernholmbb4f2b42018-12-19 14:28:33 +000024#include <gtest/gtest.h>
Christopher Ferris0b06a592018-01-19 10:26:36 -080025#include <unwindstack/MapInfo.h>
26#include <unwindstack/Memory.h>
27
Christopher Ferrisd70ea5e2018-01-30 19:47:24 -080028#include "DexFile.h"
Christopher Ferris7747b602018-01-31 19:05:19 -080029#include "DexFileData.h"
Christopher Ferrisd70ea5e2018-01-30 19:47:24 -080030#include "MemoryFake.h"
Christopher Ferris0b06a592018-01-19 10:26:36 -080031
Christopher Ferrisd70ea5e2018-01-30 19:47:24 -080032namespace unwindstack {
Christopher Ferris0b06a592018-01-19 10:26:36 -080033
Christopher Ferrisd70ea5e2018-01-30 19:47:24 -080034TEST(DexFileTest, from_file_open_non_exist) {
Martin Stjernholmbb4f2b42018-12-19 14:28:33 +000035 EXPECT_TRUE(DexFileFromFile::Create(0, "/file/does/not/exist") == nullptr);
Christopher Ferris0b06a592018-01-19 10:26:36 -080036}
37
Christopher Ferrisd70ea5e2018-01-30 19:47:24 -080038TEST(DexFileTest, from_file_open_too_small) {
Christopher Ferris0b06a592018-01-19 10:26:36 -080039 TemporaryFile tf;
40 ASSERT_TRUE(tf.fd != -1);
41
Martin Stjernholm2677b802019-01-09 23:26:33 +000042 ASSERT_EQ(size_t{10}, static_cast<size_t>(TEMP_FAILURE_RETRY(write(tf.fd, kDexData, 10))));
Christopher Ferris0b06a592018-01-19 10:26:36 -080043
44 // Header too small.
Martin Stjernholmbb4f2b42018-12-19 14:28:33 +000045 EXPECT_TRUE(DexFileFromFile::Create(0, tf.path) == nullptr);
Christopher Ferris0b06a592018-01-19 10:26:36 -080046
47 // Header correct, file too small.
48 ASSERT_EQ(0, lseek(tf.fd, 0, SEEK_SET));
Martin Stjernholm2677b802019-01-09 23:26:33 +000049 ASSERT_EQ(sizeof(kDexData) - 1,
50 static_cast<size_t>(TEMP_FAILURE_RETRY(write(tf.fd, kDexData, sizeof(kDexData) - 1))));
Martin Stjernholmbb4f2b42018-12-19 14:28:33 +000051 EXPECT_TRUE(DexFileFromFile::Create(0, tf.path) == nullptr);
Christopher Ferris0b06a592018-01-19 10:26:36 -080052}
53
Christopher Ferrisd70ea5e2018-01-30 19:47:24 -080054TEST(DexFileTest, from_file_open) {
Christopher Ferris0b06a592018-01-19 10:26:36 -080055 TemporaryFile tf;
56 ASSERT_TRUE(tf.fd != -1);
57
58 ASSERT_EQ(sizeof(kDexData),
59 static_cast<size_t>(TEMP_FAILURE_RETRY(write(tf.fd, kDexData, sizeof(kDexData)))));
60
Martin Stjernholmbb4f2b42018-12-19 14:28:33 +000061 EXPECT_TRUE(DexFileFromFile::Create(0, tf.path) != nullptr);
Christopher Ferris0b06a592018-01-19 10:26:36 -080062}
63
Christopher Ferrisd70ea5e2018-01-30 19:47:24 -080064TEST(DexFileTest, from_file_open_non_zero_offset) {
Christopher Ferris0b06a592018-01-19 10:26:36 -080065 TemporaryFile tf;
66 ASSERT_TRUE(tf.fd != -1);
67
68 ASSERT_EQ(0x100, lseek(tf.fd, 0x100, SEEK_SET));
69 ASSERT_EQ(sizeof(kDexData),
70 static_cast<size_t>(TEMP_FAILURE_RETRY(write(tf.fd, kDexData, sizeof(kDexData)))));
71
Martin Stjernholmbb4f2b42018-12-19 14:28:33 +000072 EXPECT_TRUE(DexFileFromFile::Create(0x100, tf.path) != nullptr);
Christopher Ferris0b06a592018-01-19 10:26:36 -080073}
74
Christopher Ferrisd70ea5e2018-01-30 19:47:24 -080075TEST(DexFileTest, from_memory_fail_too_small_for_header) {
Christopher Ferris0b06a592018-01-19 10:26:36 -080076 MemoryFake memory;
77
Martin Stjernholm2677b802019-01-09 23:26:33 +000078 memory.SetMemory(0x1000, kDexData, 10);
Christopher Ferris0b06a592018-01-19 10:26:36 -080079
Martin Stjernholmbb4f2b42018-12-19 14:28:33 +000080 EXPECT_TRUE(DexFileFromMemory::Create(0x1000, &memory, "") == nullptr);
Christopher Ferris0b06a592018-01-19 10:26:36 -080081}
82
Christopher Ferrisd70ea5e2018-01-30 19:47:24 -080083TEST(DexFileTest, from_memory_fail_too_small_for_data) {
Christopher Ferris0b06a592018-01-19 10:26:36 -080084 MemoryFake memory;
85
86 memory.SetMemory(0x1000, kDexData, sizeof(kDexData) - 2);
Christopher Ferris0b06a592018-01-19 10:26:36 -080087
Martin Stjernholmbb4f2b42018-12-19 14:28:33 +000088 EXPECT_TRUE(DexFileFromMemory::Create(0x1000, &memory, "") == nullptr);
Christopher Ferris0b06a592018-01-19 10:26:36 -080089}
90
Christopher Ferrisd70ea5e2018-01-30 19:47:24 -080091TEST(DexFileTest, from_memory_open) {
Christopher Ferris0b06a592018-01-19 10:26:36 -080092 MemoryFake memory;
93
94 memory.SetMemory(0x1000, kDexData, sizeof(kDexData));
Christopher Ferris0b06a592018-01-19 10:26:36 -080095
Martin Stjernholmbb4f2b42018-12-19 14:28:33 +000096 EXPECT_TRUE(DexFileFromMemory::Create(0x1000, &memory, "") != nullptr);
Christopher Ferris0b06a592018-01-19 10:26:36 -080097}
98
Christopher Ferrisd70ea5e2018-01-30 19:47:24 -080099TEST(DexFileTest, create_using_file) {
Christopher Ferris0b06a592018-01-19 10:26:36 -0800100 TemporaryFile tf;
101 ASSERT_TRUE(tf.fd != -1);
102
103 ASSERT_EQ(0x500, lseek(tf.fd, 0x500, SEEK_SET));
104 ASSERT_EQ(sizeof(kDexData),
105 static_cast<size_t>(TEMP_FAILURE_RETRY(write(tf.fd, kDexData, sizeof(kDexData)))));
106
107 MemoryFake memory;
Christopher Ferris9d5712c2018-10-01 21:01:09 -0700108 MapInfo info(nullptr, 0, 0x10000, 0, 0x5, tf.path);
Martin Stjernholmbb4f2b42018-12-19 14:28:33 +0000109 EXPECT_TRUE(DexFile::Create(0x500, &memory, &info) != nullptr);
Christopher Ferris0b06a592018-01-19 10:26:36 -0800110}
111
Christopher Ferrisd70ea5e2018-01-30 19:47:24 -0800112TEST(DexFileTest, create_using_file_non_zero_start) {
Christopher Ferris0b06a592018-01-19 10:26:36 -0800113 TemporaryFile tf;
114 ASSERT_TRUE(tf.fd != -1);
115
116 ASSERT_EQ(0x500, lseek(tf.fd, 0x500, SEEK_SET));
117 ASSERT_EQ(sizeof(kDexData),
118 static_cast<size_t>(TEMP_FAILURE_RETRY(write(tf.fd, kDexData, sizeof(kDexData)))));
119
120 MemoryFake memory;
Christopher Ferris9d5712c2018-10-01 21:01:09 -0700121 MapInfo info(nullptr, 0x100, 0x10000, 0, 0x5, tf.path);
Martin Stjernholmbb4f2b42018-12-19 14:28:33 +0000122 EXPECT_TRUE(DexFile::Create(0x600, &memory, &info) != nullptr);
Christopher Ferris0b06a592018-01-19 10:26:36 -0800123}
124
Christopher Ferrisd70ea5e2018-01-30 19:47:24 -0800125TEST(DexFileTest, create_using_file_non_zero_offset) {
Christopher Ferris0b06a592018-01-19 10:26:36 -0800126 TemporaryFile tf;
127 ASSERT_TRUE(tf.fd != -1);
128
129 ASSERT_EQ(0x500, lseek(tf.fd, 0x500, SEEK_SET));
130 ASSERT_EQ(sizeof(kDexData),
131 static_cast<size_t>(TEMP_FAILURE_RETRY(write(tf.fd, kDexData, sizeof(kDexData)))));
132
133 MemoryFake memory;
Christopher Ferris9d5712c2018-10-01 21:01:09 -0700134 MapInfo info(nullptr, 0x100, 0x10000, 0x200, 0x5, tf.path);
Martin Stjernholmbb4f2b42018-12-19 14:28:33 +0000135 EXPECT_TRUE(DexFile::Create(0x400, &memory, &info) != nullptr);
Christopher Ferris0b06a592018-01-19 10:26:36 -0800136}
137
Christopher Ferrisd70ea5e2018-01-30 19:47:24 -0800138TEST(DexFileTest, create_using_memory_empty_file) {
Christopher Ferris0b06a592018-01-19 10:26:36 -0800139 MemoryFake memory;
140 memory.SetMemory(0x4000, kDexData, sizeof(kDexData));
Christopher Ferris9d5712c2018-10-01 21:01:09 -0700141 MapInfo info(nullptr, 0x100, 0x10000, 0x200, 0x5, "");
Martin Stjernholmbb4f2b42018-12-19 14:28:33 +0000142 EXPECT_TRUE(DexFile::Create(0x4000, &memory, &info) != nullptr);
Christopher Ferris0b06a592018-01-19 10:26:36 -0800143}
144
Christopher Ferrisd70ea5e2018-01-30 19:47:24 -0800145TEST(DexFileTest, create_using_memory_file_does_not_exist) {
Christopher Ferris0b06a592018-01-19 10:26:36 -0800146 MemoryFake memory;
147 memory.SetMemory(0x4000, kDexData, sizeof(kDexData));
Christopher Ferris9d5712c2018-10-01 21:01:09 -0700148 MapInfo info(nullptr, 0x100, 0x10000, 0x200, 0x5, "/does/not/exist");
Martin Stjernholmbb4f2b42018-12-19 14:28:33 +0000149 EXPECT_TRUE(DexFile::Create(0x4000, &memory, &info) != nullptr);
Christopher Ferris0b06a592018-01-19 10:26:36 -0800150}
151
Christopher Ferrisd70ea5e2018-01-30 19:47:24 -0800152TEST(DexFileTest, create_using_memory_file_is_malformed) {
Christopher Ferris0b06a592018-01-19 10:26:36 -0800153 TemporaryFile tf;
154 ASSERT_TRUE(tf.fd != -1);
155
156 ASSERT_EQ(sizeof(kDexData) - 10,
157 static_cast<size_t>(TEMP_FAILURE_RETRY(write(tf.fd, kDexData, sizeof(kDexData) - 10))));
158
159 MemoryFake memory;
160 memory.SetMemory(0x4000, kDexData, sizeof(kDexData));
Christopher Ferris9d5712c2018-10-01 21:01:09 -0700161 MapInfo info(nullptr, 0x4000, 0x10000, 0x200, 0x5, "/does/not/exist");
Martin Stjernholmbb4f2b42018-12-19 14:28:33 +0000162 std::unique_ptr<DexFile> dex_file = DexFile::Create(0x4000, &memory, &info);
Christopher Ferris0b06a592018-01-19 10:26:36 -0800163 ASSERT_TRUE(dex_file != nullptr);
164
165 // Check it came from memory by clearing memory and verifying it fails.
166 memory.Clear();
Martin Stjernholmbb4f2b42018-12-19 14:28:33 +0000167 dex_file = DexFile::Create(0x4000, &memory, &info);
168 EXPECT_TRUE(dex_file == nullptr);
Christopher Ferris0b06a592018-01-19 10:26:36 -0800169}
170
Christopher Ferrisd70ea5e2018-01-30 19:47:24 -0800171TEST(DexFileTest, get_method) {
Christopher Ferris0b06a592018-01-19 10:26:36 -0800172 MemoryFake memory;
173 memory.SetMemory(0x4000, kDexData, sizeof(kDexData));
Christopher Ferris9d5712c2018-10-01 21:01:09 -0700174 MapInfo info(nullptr, 0x100, 0x10000, 0x200, 0x5, "");
Christopher Ferrisd70ea5e2018-01-30 19:47:24 -0800175 std::unique_ptr<DexFile> dex_file(DexFile::Create(0x4000, &memory, &info));
Christopher Ferris0b06a592018-01-19 10:26:36 -0800176 ASSERT_TRUE(dex_file != nullptr);
177
178 std::string method;
179 uint64_t method_offset;
David Srbeckyb9cc4fb2019-04-05 18:23:32 +0000180 ASSERT_TRUE(dex_file->GetMethodInformation(0x102, &method, &method_offset));
Christopher Ferris0b06a592018-01-19 10:26:36 -0800181 EXPECT_EQ("Main.<init>", method);
182 EXPECT_EQ(2U, method_offset);
183
David Srbeckyb9cc4fb2019-04-05 18:23:32 +0000184 ASSERT_TRUE(dex_file->GetMethodInformation(0x118, &method, &method_offset));
David Srbecky02d0f792018-03-24 00:29:14 +0000185 EXPECT_EQ("Main.main", method);
186 EXPECT_EQ(0U, method_offset);
David Srbecky02d0f792018-03-24 00:29:14 +0000187}
188
189TEST(DexFileTest, get_method_empty) {
190 MemoryFake memory;
191 memory.SetMemory(0x4000, kDexData, sizeof(kDexData));
Christopher Ferris9d5712c2018-10-01 21:01:09 -0700192 MapInfo info(nullptr, 0x100, 0x10000, 0x200, 0x5, "");
David Srbecky02d0f792018-03-24 00:29:14 +0000193 std::unique_ptr<DexFile> dex_file(DexFile::Create(0x4000, &memory, &info));
194 ASSERT_TRUE(dex_file != nullptr);
195
196 std::string method;
197 uint64_t method_offset;
David Srbeckyb9cc4fb2019-04-05 18:23:32 +0000198 EXPECT_FALSE(dex_file->GetMethodInformation(0x100000, &method, &method_offset));
David Srbecky02d0f792018-03-24 00:29:14 +0000199
David Srbeckyb9cc4fb2019-04-05 18:23:32 +0000200 EXPECT_FALSE(dex_file->GetMethodInformation(0x98, &method, &method_offset));
Christopher Ferris0b06a592018-01-19 10:26:36 -0800201}
Christopher Ferrisd70ea5e2018-01-30 19:47:24 -0800202
203} // namespace unwindstack