• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 #include <sys/types.h>
19 #include <unistd.h>
20 
21 #include <unordered_map>
22 
23 #include <android-base/file.h>
24 #include <gtest/gtest.h>
25 #include <unwindstack/MapInfo.h>
26 #include <unwindstack/Memory.h>
27 
28 #include "DexFile.h"
29 #include "DexFileData.h"
30 #include "MemoryFake.h"
31 
32 namespace unwindstack {
33 
TEST(DexFileTest,from_file_open_non_exist)34 TEST(DexFileTest, from_file_open_non_exist) {
35   EXPECT_TRUE(DexFileFromFile::Create(0, "/file/does/not/exist") == nullptr);
36 }
37 
TEST(DexFileTest,from_file_open_too_small)38 TEST(DexFileTest, from_file_open_too_small) {
39   TemporaryFile tf;
40   ASSERT_TRUE(tf.fd != -1);
41 
42   ASSERT_EQ(size_t{10}, static_cast<size_t>(TEMP_FAILURE_RETRY(write(tf.fd, kDexData, 10))));
43 
44   // Header too small.
45   EXPECT_TRUE(DexFileFromFile::Create(0, tf.path) == nullptr);
46 
47   // Header correct, file too small.
48   ASSERT_EQ(0, lseek(tf.fd, 0, SEEK_SET));
49   ASSERT_EQ(sizeof(kDexData) - 1,
50             static_cast<size_t>(TEMP_FAILURE_RETRY(write(tf.fd, kDexData, sizeof(kDexData) - 1))));
51   EXPECT_TRUE(DexFileFromFile::Create(0, tf.path) == nullptr);
52 }
53 
TEST(DexFileTest,from_file_open)54 TEST(DexFileTest, from_file_open) {
55   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 
61   EXPECT_TRUE(DexFileFromFile::Create(0, tf.path) != nullptr);
62 }
63 
TEST(DexFileTest,from_file_open_non_zero_offset)64 TEST(DexFileTest, from_file_open_non_zero_offset) {
65   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 
72   EXPECT_TRUE(DexFileFromFile::Create(0x100, tf.path) != nullptr);
73 }
74 
TEST(DexFileTest,from_memory_fail_too_small_for_header)75 TEST(DexFileTest, from_memory_fail_too_small_for_header) {
76   MemoryFake memory;
77 
78   memory.SetMemory(0x1000, kDexData, 10);
79 
80   EXPECT_TRUE(DexFileFromMemory::Create(0x1000, &memory, "") == nullptr);
81 }
82 
TEST(DexFileTest,from_memory_fail_too_small_for_data)83 TEST(DexFileTest, from_memory_fail_too_small_for_data) {
84   MemoryFake memory;
85 
86   memory.SetMemory(0x1000, kDexData, sizeof(kDexData) - 2);
87 
88   EXPECT_TRUE(DexFileFromMemory::Create(0x1000, &memory, "") == nullptr);
89 }
90 
TEST(DexFileTest,from_memory_open)91 TEST(DexFileTest, from_memory_open) {
92   MemoryFake memory;
93 
94   memory.SetMemory(0x1000, kDexData, sizeof(kDexData));
95 
96   EXPECT_TRUE(DexFileFromMemory::Create(0x1000, &memory, "") != nullptr);
97 }
98 
TEST(DexFileTest,create_using_file)99 TEST(DexFileTest, create_using_file) {
100   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;
108   MapInfo info(nullptr, 0, 0x10000, 0, 0x5, tf.path);
109   EXPECT_TRUE(DexFile::Create(0x500, &memory, &info) != nullptr);
110 }
111 
TEST(DexFileTest,create_using_file_non_zero_start)112 TEST(DexFileTest, create_using_file_non_zero_start) {
113   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;
121   MapInfo info(nullptr, 0x100, 0x10000, 0, 0x5, tf.path);
122   EXPECT_TRUE(DexFile::Create(0x600, &memory, &info) != nullptr);
123 }
124 
TEST(DexFileTest,create_using_file_non_zero_offset)125 TEST(DexFileTest, create_using_file_non_zero_offset) {
126   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;
134   MapInfo info(nullptr, 0x100, 0x10000, 0x200, 0x5, tf.path);
135   EXPECT_TRUE(DexFile::Create(0x400, &memory, &info) != nullptr);
136 }
137 
TEST(DexFileTest,create_using_memory_empty_file)138 TEST(DexFileTest, create_using_memory_empty_file) {
139   MemoryFake memory;
140   memory.SetMemory(0x4000, kDexData, sizeof(kDexData));
141   MapInfo info(nullptr, 0x100, 0x10000, 0x200, 0x5, "");
142   EXPECT_TRUE(DexFile::Create(0x4000, &memory, &info) != nullptr);
143 }
144 
TEST(DexFileTest,create_using_memory_file_does_not_exist)145 TEST(DexFileTest, create_using_memory_file_does_not_exist) {
146   MemoryFake memory;
147   memory.SetMemory(0x4000, kDexData, sizeof(kDexData));
148   MapInfo info(nullptr, 0x100, 0x10000, 0x200, 0x5, "/does/not/exist");
149   EXPECT_TRUE(DexFile::Create(0x4000, &memory, &info) != nullptr);
150 }
151 
TEST(DexFileTest,create_using_memory_file_is_malformed)152 TEST(DexFileTest, create_using_memory_file_is_malformed) {
153   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));
161   MapInfo info(nullptr, 0x4000, 0x10000, 0x200, 0x5, "/does/not/exist");
162   std::unique_ptr<DexFile> dex_file = DexFile::Create(0x4000, &memory, &info);
163   ASSERT_TRUE(dex_file != nullptr);
164 
165   // Check it came from memory by clearing memory and verifying it fails.
166   memory.Clear();
167   dex_file = DexFile::Create(0x4000, &memory, &info);
168   EXPECT_TRUE(dex_file == nullptr);
169 }
170 
TEST(DexFileTest,get_method)171 TEST(DexFileTest, get_method) {
172   MemoryFake memory;
173   memory.SetMemory(0x4000, kDexData, sizeof(kDexData));
174   MapInfo info(nullptr, 0x100, 0x10000, 0x200, 0x5, "");
175   std::unique_ptr<DexFile> dex_file(DexFile::Create(0x4000, &memory, &info));
176   ASSERT_TRUE(dex_file != nullptr);
177 
178   std::string method;
179   uint64_t method_offset;
180   ASSERT_TRUE(dex_file->GetMethodInformation(0x102, &method, &method_offset));
181   EXPECT_EQ("Main.<init>", method);
182   EXPECT_EQ(2U, method_offset);
183 
184   ASSERT_TRUE(dex_file->GetMethodInformation(0x118, &method, &method_offset));
185   EXPECT_EQ("Main.main", method);
186   EXPECT_EQ(0U, method_offset);
187 }
188 
TEST(DexFileTest,get_method_empty)189 TEST(DexFileTest, get_method_empty) {
190   MemoryFake memory;
191   memory.SetMemory(0x4000, kDexData, sizeof(kDexData));
192   MapInfo info(nullptr, 0x100, 0x10000, 0x200, 0x5, "");
193   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;
198   EXPECT_FALSE(dex_file->GetMethodInformation(0x100000, &method, &method_offset));
199 
200   EXPECT_FALSE(dex_file->GetMethodInformation(0x98, &method, &method_offset));
201 }
202 
203 }  // namespace unwindstack
204