blob: 4f8e6f1fc0bcbf511ac3a2f707cf599c1d625eac [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
Richard Uhlerfbef44d2014-12-23 09:48:51 -0800136static std::unique_ptr<const DexFile> OpenDexFileBase64(const char* base64,
137 const char* location) {
Ian Rogers33e95662013-05-20 20:29:14 -0700138 // decode base64
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700139 CHECK(base64 != nullptr);
Ian Rogers33e95662013-05-20 20:29:14 -0700140 size_t length;
Ian Rogers13735952014-10-08 12:43:28 -0700141 std::unique_ptr<uint8_t[]> dex_bytes(DecodeBase64(base64, &length));
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700142 CHECK(dex_bytes.get() != nullptr);
Ian Rogers33e95662013-05-20 20:29:14 -0700143
144 // write to provided file
Ian Rogers700a4022014-05-19 16:49:03 -0700145 std::unique_ptr<File> file(OS::CreateEmptyFile(location));
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700146 CHECK(file.get() != nullptr);
Ian Rogers33e95662013-05-20 20:29:14 -0700147 if (!file->WriteFully(dex_bytes.get(), length)) {
148 PLOG(FATAL) << "Failed to write base64 as dex file";
149 }
Andreas Gampe4303ba92014-11-06 01:00:46 -0800150 if (file->FlushCloseOrErase() != 0) {
151 PLOG(FATAL) << "Could not flush and close test file.";
152 }
Ian Rogers33e95662013-05-20 20:29:14 -0700153 file.reset();
154
155 // read dex file
156 ScopedObjectAccess soa(Thread::Current());
Aart Bik37d6a3b2016-06-21 18:30:10 -0700157 static constexpr bool kVerifyChecksum = true;
Ian Rogers8d31bbd2013-10-13 10:44:14 -0700158 std::string error_msg;
Richard Uhlerfbef44d2014-12-23 09:48:51 -0800159 std::vector<std::unique_ptr<const DexFile>> tmp;
Aart Bik37d6a3b2016-06-21 18:30:10 -0700160 bool success = DexFile::Open(location, location, kVerifyChecksum, &error_msg, &tmp);
Andreas Gampe833a4852014-05-21 18:46:59 -0700161 CHECK(success) << error_msg;
162 EXPECT_EQ(1U, tmp.size());
Richard Uhlerfbef44d2014-12-23 09:48:51 -0800163 std::unique_ptr<const DexFile> dex_file = std::move(tmp[0]);
Brian Carlstrome0948e12013-08-29 09:36:15 -0700164 EXPECT_EQ(PROT_READ, dex_file->GetPermissions());
165 EXPECT_TRUE(dex_file->IsReadOnly());
Ian Rogers33e95662013-05-20 20:29:14 -0700166 return dex_file;
167}
168
Brian Carlstrom9f30b382011-08-28 22:41:38 -0700169TEST_F(DexFileTest, Header) {
Brian Carlstrom33f741e2011-10-03 11:24:05 -0700170 ScratchFile tmp;
Ian Rogers700a4022014-05-19 16:49:03 -0700171 std::unique_ptr<const DexFile> raw(OpenDexFileBase64(kRawDex, tmp.GetFilename().c_str()));
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700172 ASSERT_TRUE(raw.get() != nullptr);
Brian Carlstrom578bbdc2011-07-21 14:07:47 -0700173
Brian Carlstromf615a612011-07-23 12:50:34 -0700174 const DexFile::Header& header = raw->GetHeader();
Brian Carlstrom7e49dca2011-07-22 18:07:34 -0700175 // TODO: header.magic_
176 EXPECT_EQ(0x00d87910U, header.checksum_);
177 // TODO: header.signature_
178 EXPECT_EQ(904U, header.file_size_);
179 EXPECT_EQ(112U, header.header_size_);
180 EXPECT_EQ(0U, header.link_size_);
181 EXPECT_EQ(0U, header.link_off_);
182 EXPECT_EQ(15U, header.string_ids_size_);
183 EXPECT_EQ(112U, header.string_ids_off_);
184 EXPECT_EQ(7U, header.type_ids_size_);
185 EXPECT_EQ(172U, header.type_ids_off_);
186 EXPECT_EQ(2U, header.proto_ids_size_);
187 EXPECT_EQ(200U, header.proto_ids_off_);
188 EXPECT_EQ(1U, header.field_ids_size_);
189 EXPECT_EQ(224U, header.field_ids_off_);
190 EXPECT_EQ(3U, header.method_ids_size_);
191 EXPECT_EQ(232U, header.method_ids_off_);
192 EXPECT_EQ(2U, header.class_defs_size_);
193 EXPECT_EQ(256U, header.class_defs_off_);
194 EXPECT_EQ(584U, header.data_size_);
195 EXPECT_EQ(320U, header.data_off_);
Brian Carlstrom5b332c82012-02-01 15:02:31 -0800196
197 EXPECT_EQ(header.checksum_, raw->GetLocationChecksum());
198}
199
200TEST_F(DexFileTest, GetLocationChecksum) {
Ian Rogers33e95662013-05-20 20:29:14 -0700201 ScopedObjectAccess soa(Thread::Current());
Richard Uhlerfbef44d2014-12-23 09:48:51 -0800202 std::unique_ptr<const DexFile> raw(OpenTestDexFile("Main"));
Brian Carlstrom5b332c82012-02-01 15:02:31 -0800203 EXPECT_NE(raw->GetHeader().checksum_, raw->GetLocationChecksum());
204}
205
206TEST_F(DexFileTest, GetChecksum) {
207 uint32_t checksum;
Ian Rogers33e95662013-05-20 20:29:14 -0700208 ScopedObjectAccess soa(Thread::Current());
Ian Rogers8d31bbd2013-10-13 10:44:14 -0700209 std::string error_msg;
Przemyslaw Szczepaniak5b8e6e32015-09-30 14:40:33 +0100210 EXPECT_TRUE(DexFile::GetChecksum(GetLibCoreDexFileNames()[0].c_str(), &checksum, &error_msg))
Ian Rogers8d31bbd2013-10-13 10:44:14 -0700211 << error_msg;
Brian Carlstrom5b332c82012-02-01 15:02:31 -0800212 EXPECT_EQ(java_lang_dex_file_->GetLocationChecksum(), checksum);
Brian Carlstrom7e49dca2011-07-22 18:07:34 -0700213}
214
Brian Carlstrom9f30b382011-08-28 22:41:38 -0700215TEST_F(DexFileTest, ClassDefs) {
Ian Rogers33e95662013-05-20 20:29:14 -0700216 ScopedObjectAccess soa(Thread::Current());
Richard Uhlerfbef44d2014-12-23 09:48:51 -0800217 std::unique_ptr<const DexFile> raw(OpenTestDexFile("Nested"));
218 ASSERT_TRUE(raw.get() != nullptr);
Brian Carlstrom7e49dca2011-07-22 18:07:34 -0700219 EXPECT_EQ(2U, raw->NumClassDefs());
220
Brian Carlstromf615a612011-07-23 12:50:34 -0700221 const DexFile::ClassDef& c0 = raw->GetClassDef(0);
Brian Carlstrom7e49dca2011-07-22 18:07:34 -0700222 EXPECT_STREQ("LNested$Inner;", raw->GetClassDescriptor(c0));
223
Brian Carlstromf615a612011-07-23 12:50:34 -0700224 const DexFile::ClassDef& c1 = raw->GetClassDef(1);
Brian Carlstrom7e49dca2011-07-22 18:07:34 -0700225 EXPECT_STREQ("LNested;", raw->GetClassDescriptor(c1));
Carl Shapiro1fb86202011-06-27 17:43:13 -0700226}
227
Ian Rogersd91d6d62013-09-25 20:26:14 -0700228TEST_F(DexFileTest, GetMethodSignature) {
Ian Rogers33e95662013-05-20 20:29:14 -0700229 ScopedObjectAccess soa(Thread::Current());
Richard Uhlerfbef44d2014-12-23 09:48:51 -0800230 std::unique_ptr<const DexFile> raw(OpenTestDexFile("GetMethodSignature"));
231 ASSERT_TRUE(raw.get() != nullptr);
Carl Shapiro419ec7b2011-08-03 14:48:33 -0700232 EXPECT_EQ(1U, raw->NumClassDefs());
233
234 const DexFile::ClassDef& class_def = raw->GetClassDef(0);
Ian Rogersd91d6d62013-09-25 20:26:14 -0700235 ASSERT_STREQ("LGetMethodSignature;", raw->GetClassDescriptor(class_def));
Carl Shapiro419ec7b2011-08-03 14:48:33 -0700236
Ian Rogers13735952014-10-08 12:43:28 -0700237 const uint8_t* class_data = raw->GetClassData(class_def);
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700238 ASSERT_TRUE(class_data != nullptr);
Elliott Hughes4d6850c2012-01-18 15:55:06 -0800239 ClassDataItemIterator it(*raw, class_data);
Carl Shapiro419ec7b2011-08-03 14:48:33 -0700240
Ian Rogers0571d352011-11-03 19:51:38 -0700241 EXPECT_EQ(1u, it.NumDirectMethods());
Carl Shapiro419ec7b2011-08-03 14:48:33 -0700242
Ian Rogers0571d352011-11-03 19:51:38 -0700243 // Check the signature for the static initializer.
Carl Shapiro419ec7b2011-08-03 14:48:33 -0700244 {
Ian Rogers0571d352011-11-03 19:51:38 -0700245 ASSERT_EQ(1U, it.NumDirectMethods());
246 const DexFile::MethodId& method_id = raw->GetMethodId(it.GetMemberIndex());
Ian Rogers0571d352011-11-03 19:51:38 -0700247 const char* name = raw->StringDataByIdx(method_id.name_idx_);
Carl Shapiro419ec7b2011-08-03 14:48:33 -0700248 ASSERT_STREQ("<init>", name);
Ian Rogersd91d6d62013-09-25 20:26:14 -0700249 std::string signature(raw->GetMethodSignature(method_id).ToString());
Ian Rogers0571d352011-11-03 19:51:38 -0700250 ASSERT_EQ("()V", signature);
Carl Shapiro419ec7b2011-08-03 14:48:33 -0700251 }
252
253 // Check both virtual methods.
Ian Rogers0571d352011-11-03 19:51:38 -0700254 ASSERT_EQ(2U, it.NumVirtualMethods());
Carl Shapiro419ec7b2011-08-03 14:48:33 -0700255 {
Ian Rogers0571d352011-11-03 19:51:38 -0700256 it.Next();
257 const DexFile::MethodId& method_id = raw->GetMethodId(it.GetMemberIndex());
Carl Shapiro419ec7b2011-08-03 14:48:33 -0700258
Ian Rogers0571d352011-11-03 19:51:38 -0700259 const char* name = raw->StringDataByIdx(method_id.name_idx_);
Carl Shapiro419ec7b2011-08-03 14:48:33 -0700260 ASSERT_STREQ("m1", name);
261
Ian Rogersd91d6d62013-09-25 20:26:14 -0700262 std::string signature(raw->GetMethodSignature(method_id).ToString());
Ian Rogers0571d352011-11-03 19:51:38 -0700263 ASSERT_EQ("(IDJLjava/lang/Object;)Ljava/lang/Float;", signature);
Carl Shapiro419ec7b2011-08-03 14:48:33 -0700264 }
265
266 {
Ian Rogers0571d352011-11-03 19:51:38 -0700267 it.Next();
268 const DexFile::MethodId& method_id = raw->GetMethodId(it.GetMemberIndex());
Carl Shapiro419ec7b2011-08-03 14:48:33 -0700269
Ian Rogers0571d352011-11-03 19:51:38 -0700270 const char* name = raw->StringDataByIdx(method_id.name_idx_);
Carl Shapiro419ec7b2011-08-03 14:48:33 -0700271 ASSERT_STREQ("m2", name);
272
Ian Rogersd91d6d62013-09-25 20:26:14 -0700273 std::string signature(raw->GetMethodSignature(method_id).ToString());
274 ASSERT_EQ("(ZSC)LGetMethodSignature;", signature);
Ian Rogers0571d352011-11-03 19:51:38 -0700275 }
276}
277
278TEST_F(DexFileTest, FindStringId) {
Ian Rogers33e95662013-05-20 20:29:14 -0700279 ScopedObjectAccess soa(Thread::Current());
Richard Uhlerfbef44d2014-12-23 09:48:51 -0800280 std::unique_ptr<const DexFile> raw(OpenTestDexFile("GetMethodSignature"));
281 ASSERT_TRUE(raw.get() != nullptr);
Ian Rogers0571d352011-11-03 19:51:38 -0700282 EXPECT_EQ(1U, raw->NumClassDefs());
283
Ian Rogersd91d6d62013-09-25 20:26:14 -0700284 const char* strings[] = { "LGetMethodSignature;", "Ljava/lang/Float;", "Ljava/lang/Object;",
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700285 "D", "I", "J", nullptr };
286 for (size_t i = 0; strings[i] != nullptr; i++) {
Ian Rogers0571d352011-11-03 19:51:38 -0700287 const char* str = strings[i];
288 const DexFile::StringId* str_id = raw->FindStringId(str);
289 const char* dex_str = raw->GetStringData(*str_id);
290 EXPECT_STREQ(dex_str, str);
291 }
292}
293
294TEST_F(DexFileTest, FindTypeId) {
295 for (size_t i = 0; i < java_lang_dex_file_->NumTypeIds(); i++) {
296 const char* type_str = java_lang_dex_file_->StringByTypeIdx(i);
297 const DexFile::StringId* type_str_id = java_lang_dex_file_->FindStringId(type_str);
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700298 ASSERT_TRUE(type_str_id != nullptr);
Ian Rogers0571d352011-11-03 19:51:38 -0700299 uint32_t type_str_idx = java_lang_dex_file_->GetIndexForStringId(*type_str_id);
300 const DexFile::TypeId* type_id = java_lang_dex_file_->FindTypeId(type_str_idx);
Mathieu Chartier9507fa22015-10-29 15:08:57 -0700301 ASSERT_EQ(type_id, java_lang_dex_file_->FindTypeId(type_str));
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700302 ASSERT_TRUE(type_id != nullptr);
Ian Rogers0571d352011-11-03 19:51:38 -0700303 EXPECT_EQ(java_lang_dex_file_->GetIndexForTypeId(*type_id), i);
304 }
305}
306
307TEST_F(DexFileTest, FindProtoId) {
308 for (size_t i = 0; i < java_lang_dex_file_->NumProtoIds(); i++) {
309 const DexFile::ProtoId& to_find = java_lang_dex_file_->GetProtoId(i);
310 const DexFile::TypeList* to_find_tl = java_lang_dex_file_->GetProtoParameters(to_find);
311 std::vector<uint16_t> to_find_types;
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700312 if (to_find_tl != nullptr) {
Ian Rogers0571d352011-11-03 19:51:38 -0700313 for (size_t j = 0; j < to_find_tl->Size(); j++) {
314 to_find_types.push_back(to_find_tl->GetTypeItem(j).type_idx_);
315 }
316 }
317 const DexFile::ProtoId* found =
318 java_lang_dex_file_->FindProtoId(to_find.return_type_idx_, to_find_types);
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700319 ASSERT_TRUE(found != nullptr);
Ian Rogers0571d352011-11-03 19:51:38 -0700320 EXPECT_EQ(java_lang_dex_file_->GetIndexForProtoId(*found), i);
321 }
322}
323
324TEST_F(DexFileTest, FindMethodId) {
325 for (size_t i = 0; i < java_lang_dex_file_->NumMethodIds(); i++) {
326 const DexFile::MethodId& to_find = java_lang_dex_file_->GetMethodId(i);
327 const DexFile::TypeId& klass = java_lang_dex_file_->GetTypeId(to_find.class_idx_);
328 const DexFile::StringId& name = java_lang_dex_file_->GetStringId(to_find.name_idx_);
329 const DexFile::ProtoId& signature = java_lang_dex_file_->GetProtoId(to_find.proto_idx_);
330 const DexFile::MethodId* found = java_lang_dex_file_->FindMethodId(klass, name, signature);
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700331 ASSERT_TRUE(found != nullptr) << "Didn't find method " << i << ": "
Ian Rogers0571d352011-11-03 19:51:38 -0700332 << java_lang_dex_file_->StringByTypeIdx(to_find.class_idx_) << "."
333 << java_lang_dex_file_->GetStringData(name)
Ian Rogersd91d6d62013-09-25 20:26:14 -0700334 << java_lang_dex_file_->GetMethodSignature(to_find);
Ian Rogers0571d352011-11-03 19:51:38 -0700335 EXPECT_EQ(java_lang_dex_file_->GetIndexForMethodId(*found), i);
Carl Shapiro419ec7b2011-08-03 14:48:33 -0700336 }
Carl Shapiro419ec7b2011-08-03 14:48:33 -0700337}
338
Ian Rogers9b1a4f42011-11-14 18:35:10 -0800339TEST_F(DexFileTest, FindFieldId) {
340 for (size_t i = 0; i < java_lang_dex_file_->NumFieldIds(); i++) {
341 const DexFile::FieldId& to_find = java_lang_dex_file_->GetFieldId(i);
342 const DexFile::TypeId& klass = java_lang_dex_file_->GetTypeId(to_find.class_idx_);
343 const DexFile::StringId& name = java_lang_dex_file_->GetStringId(to_find.name_idx_);
344 const DexFile::TypeId& type = java_lang_dex_file_->GetTypeId(to_find.type_idx_);
345 const DexFile::FieldId* found = java_lang_dex_file_->FindFieldId(klass, name, type);
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700346 ASSERT_TRUE(found != nullptr) << "Didn't find field " << i << ": "
Ian Rogers9b1a4f42011-11-14 18:35:10 -0800347 << java_lang_dex_file_->StringByTypeIdx(to_find.type_idx_) << " "
348 << java_lang_dex_file_->StringByTypeIdx(to_find.class_idx_) << "."
349 << java_lang_dex_file_->GetStringData(name);
350 EXPECT_EQ(java_lang_dex_file_->GetIndexForFieldId(*found), i);
351 }
352}
353
Calin Juravle4e1d5792014-07-15 23:56:47 +0100354TEST_F(DexFileTest, GetMultiDexClassesDexName) {
Andreas Gampe90e34042015-04-27 20:01:52 -0700355 ASSERT_EQ("classes.dex", DexFile::GetMultiDexClassesDexName(0));
356 ASSERT_EQ("classes2.dex", DexFile::GetMultiDexClassesDexName(1));
357 ASSERT_EQ("classes3.dex", DexFile::GetMultiDexClassesDexName(2));
358 ASSERT_EQ("classes100.dex", DexFile::GetMultiDexClassesDexName(99));
359}
360
361TEST_F(DexFileTest, GetMultiDexLocation) {
Calin Juravle4e1d5792014-07-15 23:56:47 +0100362 std::string dex_location_str = "/system/app/framework.jar";
363 const char* dex_location = dex_location_str.c_str();
Andreas Gampe90e34042015-04-27 20:01:52 -0700364 ASSERT_EQ("/system/app/framework.jar", DexFile::GetMultiDexLocation(0, dex_location));
365 ASSERT_EQ("/system/app/framework.jar:classes2.dex",
366 DexFile::GetMultiDexLocation(1, dex_location));
367 ASSERT_EQ("/system/app/framework.jar:classes101.dex",
368 DexFile::GetMultiDexLocation(100, dex_location));
Calin Juravle4e1d5792014-07-15 23:56:47 +0100369}
370
371TEST_F(DexFileTest, GetDexCanonicalLocation) {
372 ScratchFile file;
Vladimir Markoaa4497d2014-09-05 14:01:17 +0100373 UniqueCPtr<const char[]> dex_location_real(realpath(file.GetFilename().c_str(), nullptr));
374 std::string dex_location(dex_location_real.get());
Calin Juravle4e1d5792014-07-15 23:56:47 +0100375
Calin Juravle61281dc2014-08-07 11:54:36 +0100376 ASSERT_EQ(dex_location, DexFile::GetDexCanonicalLocation(dex_location.c_str()));
Andreas Gampe90e34042015-04-27 20:01:52 -0700377 std::string multidex_location = DexFile::GetMultiDexLocation(1, dex_location.c_str());
Calin Juravle4e1d5792014-07-15 23:56:47 +0100378 ASSERT_EQ(multidex_location, DexFile::GetDexCanonicalLocation(multidex_location.c_str()));
379
380 std::string dex_location_sym = dex_location + "symlink";
381 ASSERT_EQ(0, symlink(dex_location.c_str(), dex_location_sym.c_str()));
382
383 ASSERT_EQ(dex_location, DexFile::GetDexCanonicalLocation(dex_location_sym.c_str()));
384
Andreas Gampe90e34042015-04-27 20:01:52 -0700385 std::string multidex_location_sym = DexFile::GetMultiDexLocation(1, dex_location_sym.c_str());
Calin Juravle4e1d5792014-07-15 23:56:47 +0100386 ASSERT_EQ(multidex_location, DexFile::GetDexCanonicalLocation(multidex_location_sym.c_str()));
387
388 ASSERT_EQ(0, unlink(dex_location_sym.c_str()));
389}
390
Richard Uhlere5fed032015-03-18 08:21:11 -0700391TEST(DexFileUtilsTest, GetBaseLocationAndMultiDexSuffix) {
392 EXPECT_EQ("/foo/bar/baz.jar", DexFile::GetBaseLocation("/foo/bar/baz.jar"));
393 EXPECT_EQ("/foo/bar/baz.jar", DexFile::GetBaseLocation("/foo/bar/baz.jar:classes2.dex"));
394 EXPECT_EQ("/foo/bar/baz.jar", DexFile::GetBaseLocation("/foo/bar/baz.jar:classes8.dex"));
395 EXPECT_EQ("", DexFile::GetMultiDexSuffix("/foo/bar/baz.jar"));
396 EXPECT_EQ(":classes2.dex", DexFile::GetMultiDexSuffix("/foo/bar/baz.jar:classes2.dex"));
397 EXPECT_EQ(":classes8.dex", DexFile::GetMultiDexSuffix("/foo/bar/baz.jar:classes8.dex"));
398}
399
Carl Shapiro1fb86202011-06-27 17:43:13 -0700400} // namespace art