blob: 7f5a181d405b287e924daf63c494c7e165ffbf6d [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"));
36 ASSERT_TRUE(dex.get() != NULL);
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
139 CHECK(base64 != NULL);
140 size_t length;
Ian Rogers13735952014-10-08 12:43:28 -0700141 std::unique_ptr<uint8_t[]> dex_bytes(DecodeBase64(base64, &length));
Ian Rogers33e95662013-05-20 20:29:14 -0700142 CHECK(dex_bytes.get() != NULL);
143
144 // write to provided file
Ian Rogers700a4022014-05-19 16:49:03 -0700145 std::unique_ptr<File> file(OS::CreateEmptyFile(location));
Ian Rogers33e95662013-05-20 20:29:14 -0700146 CHECK(file.get() != NULL);
147 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());
Ian Rogers8d31bbd2013-10-13 10:44:14 -0700157 std::string error_msg;
Richard Uhlerfbef44d2014-12-23 09:48:51 -0800158 std::vector<std::unique_ptr<const DexFile>> tmp;
Andreas Gampe833a4852014-05-21 18:46:59 -0700159 bool success = DexFile::Open(location, location, &error_msg, &tmp);
160 CHECK(success) << error_msg;
161 EXPECT_EQ(1U, tmp.size());
Richard Uhlerfbef44d2014-12-23 09:48:51 -0800162 std::unique_ptr<const DexFile> dex_file = std::move(tmp[0]);
Brian Carlstrome0948e12013-08-29 09:36:15 -0700163 EXPECT_EQ(PROT_READ, dex_file->GetPermissions());
164 EXPECT_TRUE(dex_file->IsReadOnly());
Ian Rogers33e95662013-05-20 20:29:14 -0700165 return dex_file;
166}
167
Brian Carlstrom9f30b382011-08-28 22:41:38 -0700168TEST_F(DexFileTest, Header) {
Brian Carlstrom33f741e2011-10-03 11:24:05 -0700169 ScratchFile tmp;
Ian Rogers700a4022014-05-19 16:49:03 -0700170 std::unique_ptr<const DexFile> raw(OpenDexFileBase64(kRawDex, tmp.GetFilename().c_str()));
Elliott Hughes90a33692011-08-30 13:27:07 -0700171 ASSERT_TRUE(raw.get() != NULL);
Brian Carlstrom578bbdc2011-07-21 14:07:47 -0700172
Brian Carlstromf615a612011-07-23 12:50:34 -0700173 const DexFile::Header& header = raw->GetHeader();
Brian Carlstrom7e49dca2011-07-22 18:07:34 -0700174 // TODO: header.magic_
175 EXPECT_EQ(0x00d87910U, header.checksum_);
176 // TODO: header.signature_
177 EXPECT_EQ(904U, header.file_size_);
178 EXPECT_EQ(112U, header.header_size_);
179 EXPECT_EQ(0U, header.link_size_);
180 EXPECT_EQ(0U, header.link_off_);
181 EXPECT_EQ(15U, header.string_ids_size_);
182 EXPECT_EQ(112U, header.string_ids_off_);
183 EXPECT_EQ(7U, header.type_ids_size_);
184 EXPECT_EQ(172U, header.type_ids_off_);
185 EXPECT_EQ(2U, header.proto_ids_size_);
186 EXPECT_EQ(200U, header.proto_ids_off_);
187 EXPECT_EQ(1U, header.field_ids_size_);
188 EXPECT_EQ(224U, header.field_ids_off_);
189 EXPECT_EQ(3U, header.method_ids_size_);
190 EXPECT_EQ(232U, header.method_ids_off_);
191 EXPECT_EQ(2U, header.class_defs_size_);
192 EXPECT_EQ(256U, header.class_defs_off_);
193 EXPECT_EQ(584U, header.data_size_);
194 EXPECT_EQ(320U, header.data_off_);
Brian Carlstrom5b332c82012-02-01 15:02:31 -0800195
196 EXPECT_EQ(header.checksum_, raw->GetLocationChecksum());
197}
198
199TEST_F(DexFileTest, GetLocationChecksum) {
Ian Rogers33e95662013-05-20 20:29:14 -0700200 ScopedObjectAccess soa(Thread::Current());
Richard Uhlerfbef44d2014-12-23 09:48:51 -0800201 std::unique_ptr<const DexFile> raw(OpenTestDexFile("Main"));
Brian Carlstrom5b332c82012-02-01 15:02:31 -0800202 EXPECT_NE(raw->GetHeader().checksum_, raw->GetLocationChecksum());
203}
204
205TEST_F(DexFileTest, GetChecksum) {
206 uint32_t checksum;
Ian Rogers33e95662013-05-20 20:29:14 -0700207 ScopedObjectAccess soa(Thread::Current());
Ian Rogers8d31bbd2013-10-13 10:44:14 -0700208 std::string error_msg;
209 EXPECT_TRUE(DexFile::GetChecksum(GetLibCoreDexFileName().c_str(), &checksum, &error_msg))
210 << error_msg;
Brian Carlstrom5b332c82012-02-01 15:02:31 -0800211 EXPECT_EQ(java_lang_dex_file_->GetLocationChecksum(), checksum);
Brian Carlstrom7e49dca2011-07-22 18:07:34 -0700212}
213
Brian Carlstrom9f30b382011-08-28 22:41:38 -0700214TEST_F(DexFileTest, ClassDefs) {
Ian Rogers33e95662013-05-20 20:29:14 -0700215 ScopedObjectAccess soa(Thread::Current());
Richard Uhlerfbef44d2014-12-23 09:48:51 -0800216 std::unique_ptr<const DexFile> raw(OpenTestDexFile("Nested"));
217 ASSERT_TRUE(raw.get() != nullptr);
Brian Carlstrom7e49dca2011-07-22 18:07:34 -0700218 EXPECT_EQ(2U, raw->NumClassDefs());
219
Brian Carlstromf615a612011-07-23 12:50:34 -0700220 const DexFile::ClassDef& c0 = raw->GetClassDef(0);
Brian Carlstrom7e49dca2011-07-22 18:07:34 -0700221 EXPECT_STREQ("LNested$Inner;", raw->GetClassDescriptor(c0));
222
Brian Carlstromf615a612011-07-23 12:50:34 -0700223 const DexFile::ClassDef& c1 = raw->GetClassDef(1);
Brian Carlstrom7e49dca2011-07-22 18:07:34 -0700224 EXPECT_STREQ("LNested;", raw->GetClassDescriptor(c1));
Carl Shapiro1fb86202011-06-27 17:43:13 -0700225}
226
Ian Rogersd91d6d62013-09-25 20:26:14 -0700227TEST_F(DexFileTest, GetMethodSignature) {
Ian Rogers33e95662013-05-20 20:29:14 -0700228 ScopedObjectAccess soa(Thread::Current());
Richard Uhlerfbef44d2014-12-23 09:48:51 -0800229 std::unique_ptr<const DexFile> raw(OpenTestDexFile("GetMethodSignature"));
230 ASSERT_TRUE(raw.get() != nullptr);
Carl Shapiro419ec7b2011-08-03 14:48:33 -0700231 EXPECT_EQ(1U, raw->NumClassDefs());
232
233 const DexFile::ClassDef& class_def = raw->GetClassDef(0);
Ian Rogersd91d6d62013-09-25 20:26:14 -0700234 ASSERT_STREQ("LGetMethodSignature;", raw->GetClassDescriptor(class_def));
Carl Shapiro419ec7b2011-08-03 14:48:33 -0700235
Ian Rogers13735952014-10-08 12:43:28 -0700236 const uint8_t* class_data = raw->GetClassData(class_def);
Carl Shapiro419ec7b2011-08-03 14:48:33 -0700237 ASSERT_TRUE(class_data != NULL);
Elliott Hughes4d6850c2012-01-18 15:55:06 -0800238 ClassDataItemIterator it(*raw, class_data);
Carl Shapiro419ec7b2011-08-03 14:48:33 -0700239
Ian Rogers0571d352011-11-03 19:51:38 -0700240 EXPECT_EQ(1u, it.NumDirectMethods());
Carl Shapiro419ec7b2011-08-03 14:48:33 -0700241
Ian Rogers0571d352011-11-03 19:51:38 -0700242 // Check the signature for the static initializer.
Carl Shapiro419ec7b2011-08-03 14:48:33 -0700243 {
Ian Rogers0571d352011-11-03 19:51:38 -0700244 ASSERT_EQ(1U, it.NumDirectMethods());
245 const DexFile::MethodId& method_id = raw->GetMethodId(it.GetMemberIndex());
Ian Rogers0571d352011-11-03 19:51:38 -0700246 const char* name = raw->StringDataByIdx(method_id.name_idx_);
Carl Shapiro419ec7b2011-08-03 14:48:33 -0700247 ASSERT_STREQ("<init>", name);
Ian Rogersd91d6d62013-09-25 20:26:14 -0700248 std::string signature(raw->GetMethodSignature(method_id).ToString());
Ian Rogers0571d352011-11-03 19:51:38 -0700249 ASSERT_EQ("()V", signature);
Carl Shapiro419ec7b2011-08-03 14:48:33 -0700250 }
251
252 // Check both virtual methods.
Ian Rogers0571d352011-11-03 19:51:38 -0700253 ASSERT_EQ(2U, it.NumVirtualMethods());
Carl Shapiro419ec7b2011-08-03 14:48:33 -0700254 {
Ian Rogers0571d352011-11-03 19:51:38 -0700255 it.Next();
256 const DexFile::MethodId& method_id = raw->GetMethodId(it.GetMemberIndex());
Carl Shapiro419ec7b2011-08-03 14:48:33 -0700257
Ian Rogers0571d352011-11-03 19:51:38 -0700258 const char* name = raw->StringDataByIdx(method_id.name_idx_);
Carl Shapiro419ec7b2011-08-03 14:48:33 -0700259 ASSERT_STREQ("m1", name);
260
Ian Rogersd91d6d62013-09-25 20:26:14 -0700261 std::string signature(raw->GetMethodSignature(method_id).ToString());
Ian Rogers0571d352011-11-03 19:51:38 -0700262 ASSERT_EQ("(IDJLjava/lang/Object;)Ljava/lang/Float;", signature);
Carl Shapiro419ec7b2011-08-03 14:48:33 -0700263 }
264
265 {
Ian Rogers0571d352011-11-03 19:51:38 -0700266 it.Next();
267 const DexFile::MethodId& method_id = raw->GetMethodId(it.GetMemberIndex());
Carl Shapiro419ec7b2011-08-03 14:48:33 -0700268
Ian Rogers0571d352011-11-03 19:51:38 -0700269 const char* name = raw->StringDataByIdx(method_id.name_idx_);
Carl Shapiro419ec7b2011-08-03 14:48:33 -0700270 ASSERT_STREQ("m2", name);
271
Ian Rogersd91d6d62013-09-25 20:26:14 -0700272 std::string signature(raw->GetMethodSignature(method_id).ToString());
273 ASSERT_EQ("(ZSC)LGetMethodSignature;", signature);
Ian Rogers0571d352011-11-03 19:51:38 -0700274 }
275}
276
277TEST_F(DexFileTest, FindStringId) {
Ian Rogers33e95662013-05-20 20:29:14 -0700278 ScopedObjectAccess soa(Thread::Current());
Richard Uhlerfbef44d2014-12-23 09:48:51 -0800279 std::unique_ptr<const DexFile> raw(OpenTestDexFile("GetMethodSignature"));
280 ASSERT_TRUE(raw.get() != nullptr);
Ian Rogers0571d352011-11-03 19:51:38 -0700281 EXPECT_EQ(1U, raw->NumClassDefs());
282
Ian Rogersd91d6d62013-09-25 20:26:14 -0700283 const char* strings[] = { "LGetMethodSignature;", "Ljava/lang/Float;", "Ljava/lang/Object;",
Ian Rogers0571d352011-11-03 19:51:38 -0700284 "D", "I", "J", NULL };
285 for (size_t i = 0; strings[i] != NULL; i++) {
286 const char* str = strings[i];
287 const DexFile::StringId* str_id = raw->FindStringId(str);
288 const char* dex_str = raw->GetStringData(*str_id);
289 EXPECT_STREQ(dex_str, str);
290 }
291}
292
293TEST_F(DexFileTest, FindTypeId) {
294 for (size_t i = 0; i < java_lang_dex_file_->NumTypeIds(); i++) {
295 const char* type_str = java_lang_dex_file_->StringByTypeIdx(i);
296 const DexFile::StringId* type_str_id = java_lang_dex_file_->FindStringId(type_str);
297 ASSERT_TRUE(type_str_id != NULL);
298 uint32_t type_str_idx = java_lang_dex_file_->GetIndexForStringId(*type_str_id);
299 const DexFile::TypeId* type_id = java_lang_dex_file_->FindTypeId(type_str_idx);
300 ASSERT_TRUE(type_id != NULL);
301 EXPECT_EQ(java_lang_dex_file_->GetIndexForTypeId(*type_id), i);
302 }
303}
304
305TEST_F(DexFileTest, FindProtoId) {
306 for (size_t i = 0; i < java_lang_dex_file_->NumProtoIds(); i++) {
307 const DexFile::ProtoId& to_find = java_lang_dex_file_->GetProtoId(i);
308 const DexFile::TypeList* to_find_tl = java_lang_dex_file_->GetProtoParameters(to_find);
309 std::vector<uint16_t> to_find_types;
310 if (to_find_tl != NULL) {
311 for (size_t j = 0; j < to_find_tl->Size(); j++) {
312 to_find_types.push_back(to_find_tl->GetTypeItem(j).type_idx_);
313 }
314 }
315 const DexFile::ProtoId* found =
316 java_lang_dex_file_->FindProtoId(to_find.return_type_idx_, to_find_types);
317 ASSERT_TRUE(found != NULL);
318 EXPECT_EQ(java_lang_dex_file_->GetIndexForProtoId(*found), i);
319 }
320}
321
322TEST_F(DexFileTest, FindMethodId) {
323 for (size_t i = 0; i < java_lang_dex_file_->NumMethodIds(); i++) {
324 const DexFile::MethodId& to_find = java_lang_dex_file_->GetMethodId(i);
325 const DexFile::TypeId& klass = java_lang_dex_file_->GetTypeId(to_find.class_idx_);
326 const DexFile::StringId& name = java_lang_dex_file_->GetStringId(to_find.name_idx_);
327 const DexFile::ProtoId& signature = java_lang_dex_file_->GetProtoId(to_find.proto_idx_);
328 const DexFile::MethodId* found = java_lang_dex_file_->FindMethodId(klass, name, signature);
Ian Rogers0571d352011-11-03 19:51:38 -0700329 ASSERT_TRUE(found != NULL) << "Didn't find method " << i << ": "
330 << java_lang_dex_file_->StringByTypeIdx(to_find.class_idx_) << "."
331 << java_lang_dex_file_->GetStringData(name)
Ian Rogersd91d6d62013-09-25 20:26:14 -0700332 << java_lang_dex_file_->GetMethodSignature(to_find);
Ian Rogers0571d352011-11-03 19:51:38 -0700333 EXPECT_EQ(java_lang_dex_file_->GetIndexForMethodId(*found), i);
Carl Shapiro419ec7b2011-08-03 14:48:33 -0700334 }
Carl Shapiro419ec7b2011-08-03 14:48:33 -0700335}
336
Ian Rogers9b1a4f42011-11-14 18:35:10 -0800337TEST_F(DexFileTest, FindFieldId) {
338 for (size_t i = 0; i < java_lang_dex_file_->NumFieldIds(); i++) {
339 const DexFile::FieldId& to_find = java_lang_dex_file_->GetFieldId(i);
340 const DexFile::TypeId& klass = java_lang_dex_file_->GetTypeId(to_find.class_idx_);
341 const DexFile::StringId& name = java_lang_dex_file_->GetStringId(to_find.name_idx_);
342 const DexFile::TypeId& type = java_lang_dex_file_->GetTypeId(to_find.type_idx_);
343 const DexFile::FieldId* found = java_lang_dex_file_->FindFieldId(klass, name, type);
344 ASSERT_TRUE(found != NULL) << "Didn't find field " << i << ": "
345 << java_lang_dex_file_->StringByTypeIdx(to_find.type_idx_) << " "
346 << java_lang_dex_file_->StringByTypeIdx(to_find.class_idx_) << "."
347 << java_lang_dex_file_->GetStringData(name);
348 EXPECT_EQ(java_lang_dex_file_->GetIndexForFieldId(*found), i);
349 }
350}
351
Calin Juravle4e1d5792014-07-15 23:56:47 +0100352TEST_F(DexFileTest, GetMultiDexClassesDexName) {
353 std::string dex_location_str = "/system/app/framework.jar";
354 const char* dex_location = dex_location_str.c_str();
355 ASSERT_EQ("/system/app/framework.jar", DexFile::GetMultiDexClassesDexName(0, dex_location));
356 ASSERT_EQ("/system/app/framework.jar:classes2.dex", DexFile::GetMultiDexClassesDexName(1, dex_location));
357 ASSERT_EQ("/system/app/framework.jar:classes101.dex", DexFile::GetMultiDexClassesDexName(100, dex_location));
358}
359
360TEST_F(DexFileTest, GetDexCanonicalLocation) {
361 ScratchFile file;
Vladimir Markoaa4497d2014-09-05 14:01:17 +0100362 UniqueCPtr<const char[]> dex_location_real(realpath(file.GetFilename().c_str(), nullptr));
363 std::string dex_location(dex_location_real.get());
Calin Juravle4e1d5792014-07-15 23:56:47 +0100364
Calin Juravle61281dc2014-08-07 11:54:36 +0100365 ASSERT_EQ(dex_location, DexFile::GetDexCanonicalLocation(dex_location.c_str()));
Calin Juravle4e1d5792014-07-15 23:56:47 +0100366 std::string multidex_location = DexFile::GetMultiDexClassesDexName(1, dex_location.c_str());
367 ASSERT_EQ(multidex_location, DexFile::GetDexCanonicalLocation(multidex_location.c_str()));
368
369 std::string dex_location_sym = dex_location + "symlink";
370 ASSERT_EQ(0, symlink(dex_location.c_str(), dex_location_sym.c_str()));
371
372 ASSERT_EQ(dex_location, DexFile::GetDexCanonicalLocation(dex_location_sym.c_str()));
373
374 std::string multidex_location_sym = DexFile::GetMultiDexClassesDexName(1, dex_location_sym.c_str());
375 ASSERT_EQ(multidex_location, DexFile::GetDexCanonicalLocation(multidex_location_sym.c_str()));
376
377 ASSERT_EQ(0, unlink(dex_location_sym.c_str()));
378}
379
Carl Shapiro1fb86202011-06-27 17:43:13 -0700380} // namespace art