blob: 616c2a0c392a07dc6b1d14d8d100f6a696b2cff1 [file] [log] [blame]
Elliott Hughes2faa5f12012-01-30 14:42:07 -08001/*
2 * Copyright (C) 2011 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 */
Carl Shapiro1fb86202011-06-27 17:43:13 -070016
Brian Carlstrom578bbdc2011-07-21 14:07:47 -070017#include "dex_file.h"
Carl Shapiro1fb86202011-06-27 17:43:13 -070018
Ian Rogers700a4022014-05-19 16:49:03 -070019#include <memory>
20
Ian Rogerse63db272014-07-15 15:36:11 -070021#include "base/stl_util.h"
22#include "base/unix_file/fd_file.h"
Brian Carlstroma1ce1fe2014-02-24 23:23:58 -080023#include "common_runtime_test.h"
Elliott Hughes956af0f2014-12-11 14:34:28 -080024#include "dex_file-inl.h"
Ian Rogerse63db272014-07-15 15:36:11 -070025#include "os.h"
26#include "scoped_thread_state_change.h"
27#include "thread-inl.h"
Elliott Hughes90a33692011-08-30 13:27:07 -070028
Carl Shapiro1fb86202011-06-27 17:43:13 -070029namespace art {
30
Brian Carlstroma1ce1fe2014-02-24 23:23:58 -080031class DexFileTest : public CommonRuntimeTest {};
Brian Carlstrom9f30b382011-08-28 22:41:38 -070032
33TEST_F(DexFileTest, Open) {
Ian Rogers33e95662013-05-20 20:29:14 -070034 ScopedObjectAccess soa(Thread::Current());
Richard Uhlerfbef44d2014-12-23 09:48:51 -080035 std::unique_ptr<const DexFile> dex(OpenTestDexFile("Nested"));
Mathieu Chartier2cebb242015-04-21 16:50:40 -070036 ASSERT_TRUE(dex.get() != nullptr);
Brian Carlstrom7e49dca2011-07-22 18:07:34 -070037}
Brian Carlstrom578bbdc2011-07-21 14:07:47 -070038
Ian Rogers13735952014-10-08 12:43:28 -070039static const uint8_t kBase64Map[256] = {
Brian Carlstroma1ce1fe2014-02-24 23:23:58 -080040 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
41 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
42 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
43 255, 255, 255, 255, 255, 255, 255, 62, 255, 255, 255, 63,
44 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 255, 255,
45 255, 254, 255, 255, 255, 0, 1, 2, 3, 4, 5, 6,
46 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, // NOLINT
47 19, 20, 21, 22, 23, 24, 25, 255, 255, 255, 255, 255, // NOLINT
48 255, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36,
49 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, // NOLINT
50 49, 50, 51, 255, 255, 255, 255, 255, 255, 255, 255, 255, // NOLINT
51 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
52 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
53 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
54 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
55 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
56 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
57 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
58 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
59 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
60 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
61 255, 255, 255, 255
62};
63
Ian Rogers13735952014-10-08 12:43:28 -070064static inline uint8_t* DecodeBase64(const char* src, size_t* dst_size) {
65 std::vector<uint8_t> tmp;
Brian Carlstroma1ce1fe2014-02-24 23:23:58 -080066 uint32_t t = 0, y = 0;
67 int g = 3;
68 for (size_t i = 0; src[i] != '\0'; ++i) {
Ian Rogers13735952014-10-08 12:43:28 -070069 uint8_t c = kBase64Map[src[i] & 0xFF];
Brian Carlstroma1ce1fe2014-02-24 23:23:58 -080070 if (c == 255) continue;
71 // the final = symbols are read and used to trim the remaining bytes
72 if (c == 254) {
73 c = 0;
74 // prevent g < 0 which would potentially allow an overflow later
75 if (--g < 0) {
76 *dst_size = 0;
77 return nullptr;
78 }
79 } else if (g != 3) {
80 // we only allow = to be at the end
81 *dst_size = 0;
82 return nullptr;
83 }
84 t = (t << 6) | c;
85 if (++y == 4) {
86 tmp.push_back((t >> 16) & 255);
87 if (g > 1) {
88 tmp.push_back((t >> 8) & 255);
89 }
90 if (g > 2) {
91 tmp.push_back(t & 255);
92 }
93 y = t = 0;
94 }
95 }
96 if (y != 0) {
97 *dst_size = 0;
98 return nullptr;
99 }
Ian Rogers13735952014-10-08 12:43:28 -0700100 std::unique_ptr<uint8_t[]> dst(new uint8_t[tmp.size()]);
Brian Carlstroma1ce1fe2014-02-24 23:23:58 -0800101 if (dst_size != nullptr) {
102 *dst_size = tmp.size();
103 } else {
104 *dst_size = 0;
105 }
106 std::copy(tmp.begin(), tmp.end(), dst.get());
107 return dst.release();
108}
109
Brian Carlstrom9f30b382011-08-28 22:41:38 -0700110// Although this is the same content logically as the Nested test dex,
111// the DexFileHeader test is sensitive to subtle changes in the
112// contents due to the checksum etc, so we embed the exact input here.
113//
114// class Nested {
115// class Inner {
116// }
117// }
118static const char kRawDex[] =
119 "ZGV4CjAzNQAQedgAe7gM1B/WHsWJ6L7lGAISGC7yjD2IAwAAcAAAAHhWNBIAAAAAAAAAAMQCAAAP"
120 "AAAAcAAAAAcAAACsAAAAAgAAAMgAAAABAAAA4AAAAAMAAADoAAAAAgAAAAABAABIAgAAQAEAAK4B"
121 "AAC2AQAAvQEAAM0BAADXAQAA+wEAABsCAAA+AgAAUgIAAF8CAABiAgAAZgIAAHMCAAB5AgAAgQIA"
122 "AAIAAAADAAAABAAAAAUAAAAGAAAABwAAAAkAAAAJAAAABgAAAAAAAAAKAAAABgAAAKgBAAAAAAEA"
123 "DQAAAAAAAQAAAAAAAQAAAAAAAAAFAAAAAAAAAAAAAAAAAAAABQAAAAAAAAAIAAAAiAEAAKsCAAAA"
124 "AAAAAQAAAAAAAAAFAAAAAAAAAAgAAACYAQAAuAIAAAAAAAACAAAAlAIAAJoCAAABAAAAowIAAAIA"
125 "AgABAAAAiAIAAAYAAABbAQAAcBACAAAADgABAAEAAQAAAI4CAAAEAAAAcBACAAAADgBAAQAAAAAA"
126 "AAAAAAAAAAAATAEAAAAAAAAAAAAAAAAAAAEAAAABAAY8aW5pdD4ABUlubmVyAA5MTmVzdGVkJElu"
127 "bmVyOwAITE5lc3RlZDsAIkxkYWx2aWsvYW5ub3RhdGlvbi9FbmNsb3NpbmdDbGFzczsAHkxkYWx2"
128 "aWsvYW5ub3RhdGlvbi9Jbm5lckNsYXNzOwAhTGRhbHZpay9hbm5vdGF0aW9uL01lbWJlckNsYXNz"
129 "ZXM7ABJMamF2YS9sYW5nL09iamVjdDsAC05lc3RlZC5qYXZhAAFWAAJWTAALYWNjZXNzRmxhZ3MA"
130 "BG5hbWUABnRoaXMkMAAFdmFsdWUAAgEABw4AAQAHDjwAAgIBDhgBAgMCCwQADBcBAgQBDhwBGAAA"
131 "AQEAAJAgAICABNQCAAABAAGAgATwAgAAEAAAAAAAAAABAAAAAAAAAAEAAAAPAAAAcAAAAAIAAAAH"
132 "AAAArAAAAAMAAAACAAAAyAAAAAQAAAABAAAA4AAAAAUAAAADAAAA6AAAAAYAAAACAAAAAAEAAAMQ"
133 "AAACAAAAQAEAAAEgAAACAAAAVAEAAAYgAAACAAAAiAEAAAEQAAABAAAAqAEAAAIgAAAPAAAArgEA"
134 "AAMgAAACAAAAiAIAAAQgAAADAAAAlAIAAAAgAAACAAAAqwIAAAAQAAABAAAAxAIAAA==";
135
Narayan Kamath52e66502016-08-01 14:20:31 +0100136// kRawDex38 and 39 are dex'ed versions of the following Java source :
137//
138// public class Main {
139// public static void main(String[] foo) {
140// }
141// }
142//
143// The dex file was manually edited to change its dex version code to 38
144// or 39, respectively.
145static const char kRawDex38[] =
146 "ZGV4CjAzOAC4OovJlJ1089ikzK6asMf/f8qp3Kve5VsgAgAAcAAAAHhWNBIAAAAAAAAAAIwBAAAI"
147 "AAAAcAAAAAQAAACQAAAAAgAAAKAAAAAAAAAAAAAAAAMAAAC4AAAAAQAAANAAAAAwAQAA8AAAACIB"
148 "AAAqAQAAMgEAAEYBAABRAQAAVAEAAFgBAABtAQAAAQAAAAIAAAAEAAAABgAAAAQAAAACAAAAAAAA"
149 "AAUAAAACAAAAHAEAAAAAAAAAAAAAAAABAAcAAAABAAAAAAAAAAAAAAABAAAAAQAAAAAAAAADAAAA"
150 "AAAAAH4BAAAAAAAAAQABAAEAAABzAQAABAAAAHAQAgAAAA4AAQABAAAAAAB4AQAAAQAAAA4AAAAB"
151 "AAAAAwAGPGluaXQ+AAZMTWFpbjsAEkxqYXZhL2xhbmcvT2JqZWN0OwAJTWFpbi5qYXZhAAFWAAJW"
152 "TAATW0xqYXZhL2xhbmcvU3RyaW5nOwAEbWFpbgABAAcOAAMBAAcOAAAAAgAAgYAE8AEBCYgCDAAA"
153 "AAAAAAABAAAAAAAAAAEAAAAIAAAAcAAAAAIAAAAEAAAAkAAAAAMAAAACAAAAoAAAAAUAAAADAAAA"
154 "uAAAAAYAAAABAAAA0AAAAAEgAAACAAAA8AAAAAEQAAABAAAAHAEAAAIgAAAIAAAAIgEAAAMgAAAC"
155 "AAAAcwEAAAAgAAABAAAAfgEAAAAQAAABAAAAjAEAAA==";
156
157static const char kRawDex39[] =
158 "ZGV4CjAzOQC4OovJlJ1089ikzK6asMf/f8qp3Kve5VsgAgAAcAAAAHhWNBIAAAAAAAAAAIwBAAAI"
159 "AAAAcAAAAAQAAACQAAAAAgAAAKAAAAAAAAAAAAAAAAMAAAC4AAAAAQAAANAAAAAwAQAA8AAAACIB"
160 "AAAqAQAAMgEAAEYBAABRAQAAVAEAAFgBAABtAQAAAQAAAAIAAAAEAAAABgAAAAQAAAACAAAAAAAA"
161 "AAUAAAACAAAAHAEAAAAAAAAAAAAAAAABAAcAAAABAAAAAAAAAAAAAAABAAAAAQAAAAAAAAADAAAA"
162 "AAAAAH4BAAAAAAAAAQABAAEAAABzAQAABAAAAHAQAgAAAA4AAQABAAAAAAB4AQAAAQAAAA4AAAAB"
163 "AAAAAwAGPGluaXQ+AAZMTWFpbjsAEkxqYXZhL2xhbmcvT2JqZWN0OwAJTWFpbi5qYXZhAAFWAAJW"
164 "TAATW0xqYXZhL2xhbmcvU3RyaW5nOwAEbWFpbgABAAcOAAMBAAcOAAAAAgAAgYAE8AEBCYgCDAAA"
165 "AAAAAAABAAAAAAAAAAEAAAAIAAAAcAAAAAIAAAAEAAAAkAAAAAMAAAACAAAAoAAAAAUAAAADAAAA"
166 "uAAAAAYAAAABAAAA0AAAAAEgAAACAAAA8AAAAAEQAAABAAAAHAEAAAIgAAAIAAAAIgEAAAMgAAAC"
167 "AAAAcwEAAAAgAAABAAAAfgEAAAAQAAABAAAAjAEAAA==";
168
169static void DecodeAndWriteDexFile(const char* base64, const char* location) {
Ian Rogers33e95662013-05-20 20:29:14 -0700170 // decode base64
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700171 CHECK(base64 != nullptr);
Ian Rogers33e95662013-05-20 20:29:14 -0700172 size_t length;
Ian Rogers13735952014-10-08 12:43:28 -0700173 std::unique_ptr<uint8_t[]> dex_bytes(DecodeBase64(base64, &length));
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700174 CHECK(dex_bytes.get() != nullptr);
Ian Rogers33e95662013-05-20 20:29:14 -0700175
176 // write to provided file
Ian Rogers700a4022014-05-19 16:49:03 -0700177 std::unique_ptr<File> file(OS::CreateEmptyFile(location));
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700178 CHECK(file.get() != nullptr);
Ian Rogers33e95662013-05-20 20:29:14 -0700179 if (!file->WriteFully(dex_bytes.get(), length)) {
180 PLOG(FATAL) << "Failed to write base64 as dex file";
181 }
Andreas Gampe4303ba92014-11-06 01:00:46 -0800182 if (file->FlushCloseOrErase() != 0) {
183 PLOG(FATAL) << "Could not flush and close test file.";
184 }
Narayan Kamath52e66502016-08-01 14:20:31 +0100185}
186
187static std::unique_ptr<const DexFile> OpenDexFileBase64(const char* base64,
188 const char* location) {
189 DecodeAndWriteDexFile(base64, location);
Ian Rogers33e95662013-05-20 20:29:14 -0700190
191 // read dex file
192 ScopedObjectAccess soa(Thread::Current());
Aart Bik37d6a3b2016-06-21 18:30:10 -0700193 static constexpr bool kVerifyChecksum = true;
Ian Rogers8d31bbd2013-10-13 10:44:14 -0700194 std::string error_msg;
Richard Uhlerfbef44d2014-12-23 09:48:51 -0800195 std::vector<std::unique_ptr<const DexFile>> tmp;
Aart Bik37d6a3b2016-06-21 18:30:10 -0700196 bool success = DexFile::Open(location, location, kVerifyChecksum, &error_msg, &tmp);
Andreas Gampe833a4852014-05-21 18:46:59 -0700197 CHECK(success) << error_msg;
198 EXPECT_EQ(1U, tmp.size());
Richard Uhlerfbef44d2014-12-23 09:48:51 -0800199 std::unique_ptr<const DexFile> dex_file = std::move(tmp[0]);
Brian Carlstrome0948e12013-08-29 09:36:15 -0700200 EXPECT_EQ(PROT_READ, dex_file->GetPermissions());
201 EXPECT_TRUE(dex_file->IsReadOnly());
Ian Rogers33e95662013-05-20 20:29:14 -0700202 return dex_file;
203}
204
Brian Carlstrom9f30b382011-08-28 22:41:38 -0700205TEST_F(DexFileTest, Header) {
Brian Carlstrom33f741e2011-10-03 11:24:05 -0700206 ScratchFile tmp;
Ian Rogers700a4022014-05-19 16:49:03 -0700207 std::unique_ptr<const DexFile> raw(OpenDexFileBase64(kRawDex, tmp.GetFilename().c_str()));
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700208 ASSERT_TRUE(raw.get() != nullptr);
Brian Carlstrom578bbdc2011-07-21 14:07:47 -0700209
Brian Carlstromf615a612011-07-23 12:50:34 -0700210 const DexFile::Header& header = raw->GetHeader();
Brian Carlstrom7e49dca2011-07-22 18:07:34 -0700211 // TODO: header.magic_
212 EXPECT_EQ(0x00d87910U, header.checksum_);
213 // TODO: header.signature_
214 EXPECT_EQ(904U, header.file_size_);
215 EXPECT_EQ(112U, header.header_size_);
216 EXPECT_EQ(0U, header.link_size_);
217 EXPECT_EQ(0U, header.link_off_);
218 EXPECT_EQ(15U, header.string_ids_size_);
219 EXPECT_EQ(112U, header.string_ids_off_);
220 EXPECT_EQ(7U, header.type_ids_size_);
221 EXPECT_EQ(172U, header.type_ids_off_);
222 EXPECT_EQ(2U, header.proto_ids_size_);
223 EXPECT_EQ(200U, header.proto_ids_off_);
224 EXPECT_EQ(1U, header.field_ids_size_);
225 EXPECT_EQ(224U, header.field_ids_off_);
226 EXPECT_EQ(3U, header.method_ids_size_);
227 EXPECT_EQ(232U, header.method_ids_off_);
228 EXPECT_EQ(2U, header.class_defs_size_);
229 EXPECT_EQ(256U, header.class_defs_off_);
230 EXPECT_EQ(584U, header.data_size_);
231 EXPECT_EQ(320U, header.data_off_);
Brian Carlstrom5b332c82012-02-01 15:02:31 -0800232
233 EXPECT_EQ(header.checksum_, raw->GetLocationChecksum());
234}
235
Narayan Kamath52e66502016-08-01 14:20:31 +0100236TEST_F(DexFileTest, Version38Accepted) {
237 ScratchFile tmp;
238 std::unique_ptr<const DexFile> raw(OpenDexFileBase64(kRawDex38, tmp.GetFilename().c_str()));
239 ASSERT_TRUE(raw.get() != nullptr);
240
241 const DexFile::Header& header = raw->GetHeader();
242 EXPECT_EQ(38u, header.GetVersion());
243}
244
245TEST_F(DexFileTest, Version39Rejected) {
246 ScratchFile tmp;
247 const char* location = tmp.GetFilename().c_str();
248 DecodeAndWriteDexFile(kRawDex39, location);
249
250 ScopedObjectAccess soa(Thread::Current());
251 static constexpr bool kVerifyChecksum = true;
252 std::string error_msg;
253 std::vector<std::unique_ptr<const DexFile>> dex_files;
254 ASSERT_FALSE(DexFile::Open(location, location, kVerifyChecksum, &error_msg, &dex_files));
255}
256
Brian Carlstrom5b332c82012-02-01 15:02:31 -0800257TEST_F(DexFileTest, GetLocationChecksum) {
Ian Rogers33e95662013-05-20 20:29:14 -0700258 ScopedObjectAccess soa(Thread::Current());
Richard Uhlerfbef44d2014-12-23 09:48:51 -0800259 std::unique_ptr<const DexFile> raw(OpenTestDexFile("Main"));
Brian Carlstrom5b332c82012-02-01 15:02:31 -0800260 EXPECT_NE(raw->GetHeader().checksum_, raw->GetLocationChecksum());
261}
262
263TEST_F(DexFileTest, GetChecksum) {
264 uint32_t checksum;
Ian Rogers33e95662013-05-20 20:29:14 -0700265 ScopedObjectAccess soa(Thread::Current());
Ian Rogers8d31bbd2013-10-13 10:44:14 -0700266 std::string error_msg;
Przemyslaw Szczepaniak5b8e6e32015-09-30 14:40:33 +0100267 EXPECT_TRUE(DexFile::GetChecksum(GetLibCoreDexFileNames()[0].c_str(), &checksum, &error_msg))
Ian Rogers8d31bbd2013-10-13 10:44:14 -0700268 << error_msg;
Brian Carlstrom5b332c82012-02-01 15:02:31 -0800269 EXPECT_EQ(java_lang_dex_file_->GetLocationChecksum(), checksum);
Brian Carlstrom7e49dca2011-07-22 18:07:34 -0700270}
271
Brian Carlstrom9f30b382011-08-28 22:41:38 -0700272TEST_F(DexFileTest, ClassDefs) {
Ian Rogers33e95662013-05-20 20:29:14 -0700273 ScopedObjectAccess soa(Thread::Current());
Richard Uhlerfbef44d2014-12-23 09:48:51 -0800274 std::unique_ptr<const DexFile> raw(OpenTestDexFile("Nested"));
275 ASSERT_TRUE(raw.get() != nullptr);
Brian Carlstrom7e49dca2011-07-22 18:07:34 -0700276 EXPECT_EQ(2U, raw->NumClassDefs());
277
Brian Carlstromf615a612011-07-23 12:50:34 -0700278 const DexFile::ClassDef& c0 = raw->GetClassDef(0);
Brian Carlstrom7e49dca2011-07-22 18:07:34 -0700279 EXPECT_STREQ("LNested$Inner;", raw->GetClassDescriptor(c0));
280
Brian Carlstromf615a612011-07-23 12:50:34 -0700281 const DexFile::ClassDef& c1 = raw->GetClassDef(1);
Brian Carlstrom7e49dca2011-07-22 18:07:34 -0700282 EXPECT_STREQ("LNested;", raw->GetClassDescriptor(c1));
Carl Shapiro1fb86202011-06-27 17:43:13 -0700283}
284
Ian Rogersd91d6d62013-09-25 20:26:14 -0700285TEST_F(DexFileTest, GetMethodSignature) {
Ian Rogers33e95662013-05-20 20:29:14 -0700286 ScopedObjectAccess soa(Thread::Current());
Richard Uhlerfbef44d2014-12-23 09:48:51 -0800287 std::unique_ptr<const DexFile> raw(OpenTestDexFile("GetMethodSignature"));
288 ASSERT_TRUE(raw.get() != nullptr);
Carl Shapiro419ec7b2011-08-03 14:48:33 -0700289 EXPECT_EQ(1U, raw->NumClassDefs());
290
291 const DexFile::ClassDef& class_def = raw->GetClassDef(0);
Ian Rogersd91d6d62013-09-25 20:26:14 -0700292 ASSERT_STREQ("LGetMethodSignature;", raw->GetClassDescriptor(class_def));
Carl Shapiro419ec7b2011-08-03 14:48:33 -0700293
Ian Rogers13735952014-10-08 12:43:28 -0700294 const uint8_t* class_data = raw->GetClassData(class_def);
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700295 ASSERT_TRUE(class_data != nullptr);
Elliott Hughes4d6850c2012-01-18 15:55:06 -0800296 ClassDataItemIterator it(*raw, class_data);
Carl Shapiro419ec7b2011-08-03 14:48:33 -0700297
Ian Rogers0571d352011-11-03 19:51:38 -0700298 EXPECT_EQ(1u, it.NumDirectMethods());
Carl Shapiro419ec7b2011-08-03 14:48:33 -0700299
Ian Rogers0571d352011-11-03 19:51:38 -0700300 // Check the signature for the static initializer.
Carl Shapiro419ec7b2011-08-03 14:48:33 -0700301 {
Ian Rogers0571d352011-11-03 19:51:38 -0700302 ASSERT_EQ(1U, it.NumDirectMethods());
303 const DexFile::MethodId& method_id = raw->GetMethodId(it.GetMemberIndex());
Ian Rogers0571d352011-11-03 19:51:38 -0700304 const char* name = raw->StringDataByIdx(method_id.name_idx_);
Carl Shapiro419ec7b2011-08-03 14:48:33 -0700305 ASSERT_STREQ("<init>", name);
Ian Rogersd91d6d62013-09-25 20:26:14 -0700306 std::string signature(raw->GetMethodSignature(method_id).ToString());
Ian Rogers0571d352011-11-03 19:51:38 -0700307 ASSERT_EQ("()V", signature);
Carl Shapiro419ec7b2011-08-03 14:48:33 -0700308 }
309
310 // Check both virtual methods.
Ian Rogers0571d352011-11-03 19:51:38 -0700311 ASSERT_EQ(2U, it.NumVirtualMethods());
Carl Shapiro419ec7b2011-08-03 14:48:33 -0700312 {
Ian Rogers0571d352011-11-03 19:51:38 -0700313 it.Next();
314 const DexFile::MethodId& method_id = raw->GetMethodId(it.GetMemberIndex());
Carl Shapiro419ec7b2011-08-03 14:48:33 -0700315
Ian Rogers0571d352011-11-03 19:51:38 -0700316 const char* name = raw->StringDataByIdx(method_id.name_idx_);
Carl Shapiro419ec7b2011-08-03 14:48:33 -0700317 ASSERT_STREQ("m1", name);
318
Ian Rogersd91d6d62013-09-25 20:26:14 -0700319 std::string signature(raw->GetMethodSignature(method_id).ToString());
Ian Rogers0571d352011-11-03 19:51:38 -0700320 ASSERT_EQ("(IDJLjava/lang/Object;)Ljava/lang/Float;", signature);
Carl Shapiro419ec7b2011-08-03 14:48:33 -0700321 }
322
323 {
Ian Rogers0571d352011-11-03 19:51:38 -0700324 it.Next();
325 const DexFile::MethodId& method_id = raw->GetMethodId(it.GetMemberIndex());
Carl Shapiro419ec7b2011-08-03 14:48:33 -0700326
Ian Rogers0571d352011-11-03 19:51:38 -0700327 const char* name = raw->StringDataByIdx(method_id.name_idx_);
Carl Shapiro419ec7b2011-08-03 14:48:33 -0700328 ASSERT_STREQ("m2", name);
329
Ian Rogersd91d6d62013-09-25 20:26:14 -0700330 std::string signature(raw->GetMethodSignature(method_id).ToString());
331 ASSERT_EQ("(ZSC)LGetMethodSignature;", signature);
Ian Rogers0571d352011-11-03 19:51:38 -0700332 }
333}
334
335TEST_F(DexFileTest, FindStringId) {
Ian Rogers33e95662013-05-20 20:29:14 -0700336 ScopedObjectAccess soa(Thread::Current());
Richard Uhlerfbef44d2014-12-23 09:48:51 -0800337 std::unique_ptr<const DexFile> raw(OpenTestDexFile("GetMethodSignature"));
338 ASSERT_TRUE(raw.get() != nullptr);
Ian Rogers0571d352011-11-03 19:51:38 -0700339 EXPECT_EQ(1U, raw->NumClassDefs());
340
Ian Rogersd91d6d62013-09-25 20:26:14 -0700341 const char* strings[] = { "LGetMethodSignature;", "Ljava/lang/Float;", "Ljava/lang/Object;",
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700342 "D", "I", "J", nullptr };
343 for (size_t i = 0; strings[i] != nullptr; i++) {
Ian Rogers0571d352011-11-03 19:51:38 -0700344 const char* str = strings[i];
345 const DexFile::StringId* str_id = raw->FindStringId(str);
346 const char* dex_str = raw->GetStringData(*str_id);
347 EXPECT_STREQ(dex_str, str);
348 }
349}
350
351TEST_F(DexFileTest, FindTypeId) {
352 for (size_t i = 0; i < java_lang_dex_file_->NumTypeIds(); i++) {
353 const char* type_str = java_lang_dex_file_->StringByTypeIdx(i);
354 const DexFile::StringId* type_str_id = java_lang_dex_file_->FindStringId(type_str);
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700355 ASSERT_TRUE(type_str_id != nullptr);
Ian Rogers0571d352011-11-03 19:51:38 -0700356 uint32_t type_str_idx = java_lang_dex_file_->GetIndexForStringId(*type_str_id);
357 const DexFile::TypeId* type_id = java_lang_dex_file_->FindTypeId(type_str_idx);
Mathieu Chartier9507fa22015-10-29 15:08:57 -0700358 ASSERT_EQ(type_id, java_lang_dex_file_->FindTypeId(type_str));
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700359 ASSERT_TRUE(type_id != nullptr);
Ian Rogers0571d352011-11-03 19:51:38 -0700360 EXPECT_EQ(java_lang_dex_file_->GetIndexForTypeId(*type_id), i);
361 }
362}
363
364TEST_F(DexFileTest, FindProtoId) {
365 for (size_t i = 0; i < java_lang_dex_file_->NumProtoIds(); i++) {
366 const DexFile::ProtoId& to_find = java_lang_dex_file_->GetProtoId(i);
367 const DexFile::TypeList* to_find_tl = java_lang_dex_file_->GetProtoParameters(to_find);
368 std::vector<uint16_t> to_find_types;
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700369 if (to_find_tl != nullptr) {
Ian Rogers0571d352011-11-03 19:51:38 -0700370 for (size_t j = 0; j < to_find_tl->Size(); j++) {
371 to_find_types.push_back(to_find_tl->GetTypeItem(j).type_idx_);
372 }
373 }
374 const DexFile::ProtoId* found =
375 java_lang_dex_file_->FindProtoId(to_find.return_type_idx_, to_find_types);
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700376 ASSERT_TRUE(found != nullptr);
Ian Rogers0571d352011-11-03 19:51:38 -0700377 EXPECT_EQ(java_lang_dex_file_->GetIndexForProtoId(*found), i);
378 }
379}
380
381TEST_F(DexFileTest, FindMethodId) {
382 for (size_t i = 0; i < java_lang_dex_file_->NumMethodIds(); i++) {
383 const DexFile::MethodId& to_find = java_lang_dex_file_->GetMethodId(i);
384 const DexFile::TypeId& klass = java_lang_dex_file_->GetTypeId(to_find.class_idx_);
385 const DexFile::StringId& name = java_lang_dex_file_->GetStringId(to_find.name_idx_);
386 const DexFile::ProtoId& signature = java_lang_dex_file_->GetProtoId(to_find.proto_idx_);
387 const DexFile::MethodId* found = java_lang_dex_file_->FindMethodId(klass, name, signature);
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700388 ASSERT_TRUE(found != nullptr) << "Didn't find method " << i << ": "
Ian Rogers0571d352011-11-03 19:51:38 -0700389 << java_lang_dex_file_->StringByTypeIdx(to_find.class_idx_) << "."
390 << java_lang_dex_file_->GetStringData(name)
Ian Rogersd91d6d62013-09-25 20:26:14 -0700391 << java_lang_dex_file_->GetMethodSignature(to_find);
Ian Rogers0571d352011-11-03 19:51:38 -0700392 EXPECT_EQ(java_lang_dex_file_->GetIndexForMethodId(*found), i);
Carl Shapiro419ec7b2011-08-03 14:48:33 -0700393 }
Carl Shapiro419ec7b2011-08-03 14:48:33 -0700394}
395
Ian Rogers9b1a4f42011-11-14 18:35:10 -0800396TEST_F(DexFileTest, FindFieldId) {
397 for (size_t i = 0; i < java_lang_dex_file_->NumFieldIds(); i++) {
398 const DexFile::FieldId& to_find = java_lang_dex_file_->GetFieldId(i);
399 const DexFile::TypeId& klass = java_lang_dex_file_->GetTypeId(to_find.class_idx_);
400 const DexFile::StringId& name = java_lang_dex_file_->GetStringId(to_find.name_idx_);
401 const DexFile::TypeId& type = java_lang_dex_file_->GetTypeId(to_find.type_idx_);
402 const DexFile::FieldId* found = java_lang_dex_file_->FindFieldId(klass, name, type);
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700403 ASSERT_TRUE(found != nullptr) << "Didn't find field " << i << ": "
Ian Rogers9b1a4f42011-11-14 18:35:10 -0800404 << java_lang_dex_file_->StringByTypeIdx(to_find.type_idx_) << " "
405 << java_lang_dex_file_->StringByTypeIdx(to_find.class_idx_) << "."
406 << java_lang_dex_file_->GetStringData(name);
407 EXPECT_EQ(java_lang_dex_file_->GetIndexForFieldId(*found), i);
408 }
409}
410
Calin Juravle4e1d5792014-07-15 23:56:47 +0100411TEST_F(DexFileTest, GetMultiDexClassesDexName) {
Andreas Gampe90e34042015-04-27 20:01:52 -0700412 ASSERT_EQ("classes.dex", DexFile::GetMultiDexClassesDexName(0));
413 ASSERT_EQ("classes2.dex", DexFile::GetMultiDexClassesDexName(1));
414 ASSERT_EQ("classes3.dex", DexFile::GetMultiDexClassesDexName(2));
415 ASSERT_EQ("classes100.dex", DexFile::GetMultiDexClassesDexName(99));
416}
417
418TEST_F(DexFileTest, GetMultiDexLocation) {
Calin Juravle4e1d5792014-07-15 23:56:47 +0100419 std::string dex_location_str = "/system/app/framework.jar";
420 const char* dex_location = dex_location_str.c_str();
Andreas Gampe90e34042015-04-27 20:01:52 -0700421 ASSERT_EQ("/system/app/framework.jar", DexFile::GetMultiDexLocation(0, dex_location));
422 ASSERT_EQ("/system/app/framework.jar:classes2.dex",
423 DexFile::GetMultiDexLocation(1, dex_location));
424 ASSERT_EQ("/system/app/framework.jar:classes101.dex",
425 DexFile::GetMultiDexLocation(100, dex_location));
Calin Juravle4e1d5792014-07-15 23:56:47 +0100426}
427
428TEST_F(DexFileTest, GetDexCanonicalLocation) {
429 ScratchFile file;
Vladimir Markoaa4497d2014-09-05 14:01:17 +0100430 UniqueCPtr<const char[]> dex_location_real(realpath(file.GetFilename().c_str(), nullptr));
431 std::string dex_location(dex_location_real.get());
Calin Juravle4e1d5792014-07-15 23:56:47 +0100432
Calin Juravle61281dc2014-08-07 11:54:36 +0100433 ASSERT_EQ(dex_location, DexFile::GetDexCanonicalLocation(dex_location.c_str()));
Andreas Gampe90e34042015-04-27 20:01:52 -0700434 std::string multidex_location = DexFile::GetMultiDexLocation(1, dex_location.c_str());
Calin Juravle4e1d5792014-07-15 23:56:47 +0100435 ASSERT_EQ(multidex_location, DexFile::GetDexCanonicalLocation(multidex_location.c_str()));
436
437 std::string dex_location_sym = dex_location + "symlink";
438 ASSERT_EQ(0, symlink(dex_location.c_str(), dex_location_sym.c_str()));
439
440 ASSERT_EQ(dex_location, DexFile::GetDexCanonicalLocation(dex_location_sym.c_str()));
441
Andreas Gampe90e34042015-04-27 20:01:52 -0700442 std::string multidex_location_sym = DexFile::GetMultiDexLocation(1, dex_location_sym.c_str());
Calin Juravle4e1d5792014-07-15 23:56:47 +0100443 ASSERT_EQ(multidex_location, DexFile::GetDexCanonicalLocation(multidex_location_sym.c_str()));
444
445 ASSERT_EQ(0, unlink(dex_location_sym.c_str()));
446}
447
Richard Uhlere5fed032015-03-18 08:21:11 -0700448TEST(DexFileUtilsTest, GetBaseLocationAndMultiDexSuffix) {
449 EXPECT_EQ("/foo/bar/baz.jar", DexFile::GetBaseLocation("/foo/bar/baz.jar"));
450 EXPECT_EQ("/foo/bar/baz.jar", DexFile::GetBaseLocation("/foo/bar/baz.jar:classes2.dex"));
451 EXPECT_EQ("/foo/bar/baz.jar", DexFile::GetBaseLocation("/foo/bar/baz.jar:classes8.dex"));
452 EXPECT_EQ("", DexFile::GetMultiDexSuffix("/foo/bar/baz.jar"));
453 EXPECT_EQ(":classes2.dex", DexFile::GetMultiDexSuffix("/foo/bar/baz.jar:classes2.dex"));
454 EXPECT_EQ(":classes8.dex", DexFile::GetMultiDexSuffix("/foo/bar/baz.jar:classes8.dex"));
455}
456
Carl Shapiro1fb86202011-06-27 17:43:13 -0700457} // namespace art