blob: d0c5603cc4089f4935bcb719e37983a101a3a602 [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"
Ian Rogerse63db272014-07-15 15:36:11 -070024#include "os.h"
25#include "scoped_thread_state_change.h"
26#include "thread-inl.h"
Elliott Hughes90a33692011-08-30 13:27:07 -070027
Carl Shapiro1fb86202011-06-27 17:43:13 -070028namespace art {
29
Brian Carlstroma1ce1fe2014-02-24 23:23:58 -080030class DexFileTest : public CommonRuntimeTest {};
Brian Carlstrom9f30b382011-08-28 22:41:38 -070031
32TEST_F(DexFileTest, Open) {
Ian Rogers33e95662013-05-20 20:29:14 -070033 ScopedObjectAccess soa(Thread::Current());
Elliott Hughes4d6850c2012-01-18 15:55:06 -080034 const DexFile* dex(OpenTestDexFile("Nested"));
35 ASSERT_TRUE(dex != NULL);
Brian Carlstrom7e49dca2011-07-22 18:07:34 -070036}
Brian Carlstrom578bbdc2011-07-21 14:07:47 -070037
Brian Carlstroma1ce1fe2014-02-24 23:23:58 -080038static const byte kBase64Map[256] = {
39 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
40 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, 62, 255, 255, 255, 63,
43 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 255, 255,
44 255, 254, 255, 255, 255, 0, 1, 2, 3, 4, 5, 6,
45 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, // NOLINT
46 19, 20, 21, 22, 23, 24, 25, 255, 255, 255, 255, 255, // NOLINT
47 255, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36,
48 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, // NOLINT
49 49, 50, 51, 255, 255, 255, 255, 255, 255, 255, 255, 255, // NOLINT
50 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
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
61};
62
63static inline byte* DecodeBase64(const char* src, size_t* dst_size) {
64 std::vector<byte> tmp;
65 uint32_t t = 0, y = 0;
66 int g = 3;
67 for (size_t i = 0; src[i] != '\0'; ++i) {
68 byte c = kBase64Map[src[i] & 0xFF];
69 if (c == 255) continue;
70 // the final = symbols are read and used to trim the remaining bytes
71 if (c == 254) {
72 c = 0;
73 // prevent g < 0 which would potentially allow an overflow later
74 if (--g < 0) {
75 *dst_size = 0;
76 return nullptr;
77 }
78 } else if (g != 3) {
79 // we only allow = to be at the end
80 *dst_size = 0;
81 return nullptr;
82 }
83 t = (t << 6) | c;
84 if (++y == 4) {
85 tmp.push_back((t >> 16) & 255);
86 if (g > 1) {
87 tmp.push_back((t >> 8) & 255);
88 }
89 if (g > 2) {
90 tmp.push_back(t & 255);
91 }
92 y = t = 0;
93 }
94 }
95 if (y != 0) {
96 *dst_size = 0;
97 return nullptr;
98 }
Ian Rogers700a4022014-05-19 16:49:03 -070099 std::unique_ptr<byte[]> dst(new byte[tmp.size()]);
Brian Carlstroma1ce1fe2014-02-24 23:23:58 -0800100 if (dst_size != nullptr) {
101 *dst_size = tmp.size();
102 } else {
103 *dst_size = 0;
104 }
105 std::copy(tmp.begin(), tmp.end(), dst.get());
106 return dst.release();
107}
108
Brian Carlstrom9f30b382011-08-28 22:41:38 -0700109// Although this is the same content logically as the Nested test dex,
110// the DexFileHeader test is sensitive to subtle changes in the
111// contents due to the checksum etc, so we embed the exact input here.
112//
113// class Nested {
114// class Inner {
115// }
116// }
117static const char kRawDex[] =
118 "ZGV4CjAzNQAQedgAe7gM1B/WHsWJ6L7lGAISGC7yjD2IAwAAcAAAAHhWNBIAAAAAAAAAAMQCAAAP"
119 "AAAAcAAAAAcAAACsAAAAAgAAAMgAAAABAAAA4AAAAAMAAADoAAAAAgAAAAABAABIAgAAQAEAAK4B"
120 "AAC2AQAAvQEAAM0BAADXAQAA+wEAABsCAAA+AgAAUgIAAF8CAABiAgAAZgIAAHMCAAB5AgAAgQIA"
121 "AAIAAAADAAAABAAAAAUAAAAGAAAABwAAAAkAAAAJAAAABgAAAAAAAAAKAAAABgAAAKgBAAAAAAEA"
122 "DQAAAAAAAQAAAAAAAQAAAAAAAAAFAAAAAAAAAAAAAAAAAAAABQAAAAAAAAAIAAAAiAEAAKsCAAAA"
123 "AAAAAQAAAAAAAAAFAAAAAAAAAAgAAACYAQAAuAIAAAAAAAACAAAAlAIAAJoCAAABAAAAowIAAAIA"
124 "AgABAAAAiAIAAAYAAABbAQAAcBACAAAADgABAAEAAQAAAI4CAAAEAAAAcBACAAAADgBAAQAAAAAA"
125 "AAAAAAAAAAAATAEAAAAAAAAAAAAAAAAAAAEAAAABAAY8aW5pdD4ABUlubmVyAA5MTmVzdGVkJElu"
126 "bmVyOwAITE5lc3RlZDsAIkxkYWx2aWsvYW5ub3RhdGlvbi9FbmNsb3NpbmdDbGFzczsAHkxkYWx2"
127 "aWsvYW5ub3RhdGlvbi9Jbm5lckNsYXNzOwAhTGRhbHZpay9hbm5vdGF0aW9uL01lbWJlckNsYXNz"
128 "ZXM7ABJMamF2YS9sYW5nL09iamVjdDsAC05lc3RlZC5qYXZhAAFWAAJWTAALYWNjZXNzRmxhZ3MA"
129 "BG5hbWUABnRoaXMkMAAFdmFsdWUAAgEABw4AAQAHDjwAAgIBDhgBAgMCCwQADBcBAgQBDhwBGAAA"
130 "AQEAAJAgAICABNQCAAABAAGAgATwAgAAEAAAAAAAAAABAAAAAAAAAAEAAAAPAAAAcAAAAAIAAAAH"
131 "AAAArAAAAAMAAAACAAAAyAAAAAQAAAABAAAA4AAAAAUAAAADAAAA6AAAAAYAAAACAAAAAAEAAAMQ"
132 "AAACAAAAQAEAAAEgAAACAAAAVAEAAAYgAAACAAAAiAEAAAEQAAABAAAAqAEAAAIgAAAPAAAArgEA"
133 "AAMgAAACAAAAiAIAAAQgAAADAAAAlAIAAAAgAAACAAAAqwIAAAAQAAABAAAAxAIAAA==";
134
Ian Rogers33e95662013-05-20 20:29:14 -0700135static const DexFile* OpenDexFileBase64(const char* base64,
Ian Rogers8d31bbd2013-10-13 10:44:14 -0700136 const char* location) {
Ian Rogers33e95662013-05-20 20:29:14 -0700137 // decode base64
138 CHECK(base64 != NULL);
139 size_t length;
Ian Rogers700a4022014-05-19 16:49:03 -0700140 std::unique_ptr<byte[]> dex_bytes(DecodeBase64(base64, &length));
Ian Rogers33e95662013-05-20 20:29:14 -0700141 CHECK(dex_bytes.get() != NULL);
142
143 // write to provided file
Ian Rogers700a4022014-05-19 16:49:03 -0700144 std::unique_ptr<File> file(OS::CreateEmptyFile(location));
Ian Rogers33e95662013-05-20 20:29:14 -0700145 CHECK(file.get() != NULL);
146 if (!file->WriteFully(dex_bytes.get(), length)) {
147 PLOG(FATAL) << "Failed to write base64 as dex file";
148 }
149 file.reset();
150
151 // read dex file
152 ScopedObjectAccess soa(Thread::Current());
Ian Rogers8d31bbd2013-10-13 10:44:14 -0700153 std::string error_msg;
Andreas Gampe833a4852014-05-21 18:46:59 -0700154 std::vector<const DexFile*> tmp;
155 bool success = DexFile::Open(location, location, &error_msg, &tmp);
156 CHECK(success) << error_msg;
157 EXPECT_EQ(1U, tmp.size());
158 const DexFile* dex_file = tmp[0];
Brian Carlstrome0948e12013-08-29 09:36:15 -0700159 EXPECT_EQ(PROT_READ, dex_file->GetPermissions());
160 EXPECT_TRUE(dex_file->IsReadOnly());
Ian Rogers33e95662013-05-20 20:29:14 -0700161 return dex_file;
162}
163
Brian Carlstrom9f30b382011-08-28 22:41:38 -0700164TEST_F(DexFileTest, Header) {
Brian Carlstrom33f741e2011-10-03 11:24:05 -0700165 ScratchFile tmp;
Ian Rogers700a4022014-05-19 16:49:03 -0700166 std::unique_ptr<const DexFile> raw(OpenDexFileBase64(kRawDex, tmp.GetFilename().c_str()));
Elliott Hughes90a33692011-08-30 13:27:07 -0700167 ASSERT_TRUE(raw.get() != NULL);
Brian Carlstrom578bbdc2011-07-21 14:07:47 -0700168
Brian Carlstromf615a612011-07-23 12:50:34 -0700169 const DexFile::Header& header = raw->GetHeader();
Brian Carlstrom7e49dca2011-07-22 18:07:34 -0700170 // TODO: header.magic_
171 EXPECT_EQ(0x00d87910U, header.checksum_);
172 // TODO: header.signature_
173 EXPECT_EQ(904U, header.file_size_);
174 EXPECT_EQ(112U, header.header_size_);
175 EXPECT_EQ(0U, header.link_size_);
176 EXPECT_EQ(0U, header.link_off_);
177 EXPECT_EQ(15U, header.string_ids_size_);
178 EXPECT_EQ(112U, header.string_ids_off_);
179 EXPECT_EQ(7U, header.type_ids_size_);
180 EXPECT_EQ(172U, header.type_ids_off_);
181 EXPECT_EQ(2U, header.proto_ids_size_);
182 EXPECT_EQ(200U, header.proto_ids_off_);
183 EXPECT_EQ(1U, header.field_ids_size_);
184 EXPECT_EQ(224U, header.field_ids_off_);
185 EXPECT_EQ(3U, header.method_ids_size_);
186 EXPECT_EQ(232U, header.method_ids_off_);
187 EXPECT_EQ(2U, header.class_defs_size_);
188 EXPECT_EQ(256U, header.class_defs_off_);
189 EXPECT_EQ(584U, header.data_size_);
190 EXPECT_EQ(320U, header.data_off_);
Brian Carlstrom5b332c82012-02-01 15:02:31 -0800191
192 EXPECT_EQ(header.checksum_, raw->GetLocationChecksum());
193}
194
195TEST_F(DexFileTest, GetLocationChecksum) {
Ian Rogers33e95662013-05-20 20:29:14 -0700196 ScopedObjectAccess soa(Thread::Current());
Brian Carlstrom5b332c82012-02-01 15:02:31 -0800197 const DexFile* raw(OpenTestDexFile("Main"));
198 EXPECT_NE(raw->GetHeader().checksum_, raw->GetLocationChecksum());
199}
200
201TEST_F(DexFileTest, GetChecksum) {
202 uint32_t checksum;
Ian Rogers33e95662013-05-20 20:29:14 -0700203 ScopedObjectAccess soa(Thread::Current());
Ian Rogers8d31bbd2013-10-13 10:44:14 -0700204 std::string error_msg;
205 EXPECT_TRUE(DexFile::GetChecksum(GetLibCoreDexFileName().c_str(), &checksum, &error_msg))
206 << error_msg;
Brian Carlstrom5b332c82012-02-01 15:02:31 -0800207 EXPECT_EQ(java_lang_dex_file_->GetLocationChecksum(), checksum);
Brian Carlstrom7e49dca2011-07-22 18:07:34 -0700208}
209
Brian Carlstrom9f30b382011-08-28 22:41:38 -0700210TEST_F(DexFileTest, ClassDefs) {
Ian Rogers33e95662013-05-20 20:29:14 -0700211 ScopedObjectAccess soa(Thread::Current());
Elliott Hughes4d6850c2012-01-18 15:55:06 -0800212 const DexFile* raw(OpenTestDexFile("Nested"));
213 ASSERT_TRUE(raw != NULL);
Brian Carlstrom7e49dca2011-07-22 18:07:34 -0700214 EXPECT_EQ(2U, raw->NumClassDefs());
215
Brian Carlstromf615a612011-07-23 12:50:34 -0700216 const DexFile::ClassDef& c0 = raw->GetClassDef(0);
Brian Carlstrom7e49dca2011-07-22 18:07:34 -0700217 EXPECT_STREQ("LNested$Inner;", raw->GetClassDescriptor(c0));
218
Brian Carlstromf615a612011-07-23 12:50:34 -0700219 const DexFile::ClassDef& c1 = raw->GetClassDef(1);
Brian Carlstrom7e49dca2011-07-22 18:07:34 -0700220 EXPECT_STREQ("LNested;", raw->GetClassDescriptor(c1));
Carl Shapiro1fb86202011-06-27 17:43:13 -0700221}
222
Ian Rogersd91d6d62013-09-25 20:26:14 -0700223TEST_F(DexFileTest, GetMethodSignature) {
Ian Rogers33e95662013-05-20 20:29:14 -0700224 ScopedObjectAccess soa(Thread::Current());
Ian Rogersd91d6d62013-09-25 20:26:14 -0700225 const DexFile* raw(OpenTestDexFile("GetMethodSignature"));
Elliott Hughes4d6850c2012-01-18 15:55:06 -0800226 ASSERT_TRUE(raw != NULL);
Carl Shapiro419ec7b2011-08-03 14:48:33 -0700227 EXPECT_EQ(1U, raw->NumClassDefs());
228
229 const DexFile::ClassDef& class_def = raw->GetClassDef(0);
Ian Rogersd91d6d62013-09-25 20:26:14 -0700230 ASSERT_STREQ("LGetMethodSignature;", raw->GetClassDescriptor(class_def));
Carl Shapiro419ec7b2011-08-03 14:48:33 -0700231
232 const byte* class_data = raw->GetClassData(class_def);
233 ASSERT_TRUE(class_data != NULL);
Elliott Hughes4d6850c2012-01-18 15:55:06 -0800234 ClassDataItemIterator it(*raw, class_data);
Carl Shapiro419ec7b2011-08-03 14:48:33 -0700235
Ian Rogers0571d352011-11-03 19:51:38 -0700236 EXPECT_EQ(1u, it.NumDirectMethods());
Carl Shapiro419ec7b2011-08-03 14:48:33 -0700237
Ian Rogers0571d352011-11-03 19:51:38 -0700238 // Check the signature for the static initializer.
Carl Shapiro419ec7b2011-08-03 14:48:33 -0700239 {
Ian Rogers0571d352011-11-03 19:51:38 -0700240 ASSERT_EQ(1U, it.NumDirectMethods());
241 const DexFile::MethodId& method_id = raw->GetMethodId(it.GetMemberIndex());
Ian Rogers0571d352011-11-03 19:51:38 -0700242 const char* name = raw->StringDataByIdx(method_id.name_idx_);
Carl Shapiro419ec7b2011-08-03 14:48:33 -0700243 ASSERT_STREQ("<init>", name);
Ian Rogersd91d6d62013-09-25 20:26:14 -0700244 std::string signature(raw->GetMethodSignature(method_id).ToString());
Ian Rogers0571d352011-11-03 19:51:38 -0700245 ASSERT_EQ("()V", signature);
Carl Shapiro419ec7b2011-08-03 14:48:33 -0700246 }
247
248 // Check both virtual methods.
Ian Rogers0571d352011-11-03 19:51:38 -0700249 ASSERT_EQ(2U, it.NumVirtualMethods());
Carl Shapiro419ec7b2011-08-03 14:48:33 -0700250 {
Ian Rogers0571d352011-11-03 19:51:38 -0700251 it.Next();
252 const DexFile::MethodId& method_id = raw->GetMethodId(it.GetMemberIndex());
Carl Shapiro419ec7b2011-08-03 14:48:33 -0700253
Ian Rogers0571d352011-11-03 19:51:38 -0700254 const char* name = raw->StringDataByIdx(method_id.name_idx_);
Carl Shapiro419ec7b2011-08-03 14:48:33 -0700255 ASSERT_STREQ("m1", name);
256
Ian Rogersd91d6d62013-09-25 20:26:14 -0700257 std::string signature(raw->GetMethodSignature(method_id).ToString());
Ian Rogers0571d352011-11-03 19:51:38 -0700258 ASSERT_EQ("(IDJLjava/lang/Object;)Ljava/lang/Float;", signature);
Carl Shapiro419ec7b2011-08-03 14:48:33 -0700259 }
260
261 {
Ian Rogers0571d352011-11-03 19:51:38 -0700262 it.Next();
263 const DexFile::MethodId& method_id = raw->GetMethodId(it.GetMemberIndex());
Carl Shapiro419ec7b2011-08-03 14:48:33 -0700264
Ian Rogers0571d352011-11-03 19:51:38 -0700265 const char* name = raw->StringDataByIdx(method_id.name_idx_);
Carl Shapiro419ec7b2011-08-03 14:48:33 -0700266 ASSERT_STREQ("m2", name);
267
Ian Rogersd91d6d62013-09-25 20:26:14 -0700268 std::string signature(raw->GetMethodSignature(method_id).ToString());
269 ASSERT_EQ("(ZSC)LGetMethodSignature;", signature);
Ian Rogers0571d352011-11-03 19:51:38 -0700270 }
271}
272
273TEST_F(DexFileTest, FindStringId) {
Ian Rogers33e95662013-05-20 20:29:14 -0700274 ScopedObjectAccess soa(Thread::Current());
Ian Rogersd91d6d62013-09-25 20:26:14 -0700275 const DexFile* raw(OpenTestDexFile("GetMethodSignature"));
Elliott Hughes4d6850c2012-01-18 15:55:06 -0800276 ASSERT_TRUE(raw != NULL);
Ian Rogers0571d352011-11-03 19:51:38 -0700277 EXPECT_EQ(1U, raw->NumClassDefs());
278
Ian Rogersd91d6d62013-09-25 20:26:14 -0700279 const char* strings[] = { "LGetMethodSignature;", "Ljava/lang/Float;", "Ljava/lang/Object;",
Ian Rogers0571d352011-11-03 19:51:38 -0700280 "D", "I", "J", NULL };
281 for (size_t i = 0; strings[i] != NULL; i++) {
282 const char* str = strings[i];
283 const DexFile::StringId* str_id = raw->FindStringId(str);
284 const char* dex_str = raw->GetStringData(*str_id);
285 EXPECT_STREQ(dex_str, str);
286 }
287}
288
289TEST_F(DexFileTest, FindTypeId) {
290 for (size_t i = 0; i < java_lang_dex_file_->NumTypeIds(); i++) {
291 const char* type_str = java_lang_dex_file_->StringByTypeIdx(i);
292 const DexFile::StringId* type_str_id = java_lang_dex_file_->FindStringId(type_str);
293 ASSERT_TRUE(type_str_id != NULL);
294 uint32_t type_str_idx = java_lang_dex_file_->GetIndexForStringId(*type_str_id);
295 const DexFile::TypeId* type_id = java_lang_dex_file_->FindTypeId(type_str_idx);
296 ASSERT_TRUE(type_id != NULL);
297 EXPECT_EQ(java_lang_dex_file_->GetIndexForTypeId(*type_id), i);
298 }
299}
300
301TEST_F(DexFileTest, FindProtoId) {
302 for (size_t i = 0; i < java_lang_dex_file_->NumProtoIds(); i++) {
303 const DexFile::ProtoId& to_find = java_lang_dex_file_->GetProtoId(i);
304 const DexFile::TypeList* to_find_tl = java_lang_dex_file_->GetProtoParameters(to_find);
305 std::vector<uint16_t> to_find_types;
306 if (to_find_tl != NULL) {
307 for (size_t j = 0; j < to_find_tl->Size(); j++) {
308 to_find_types.push_back(to_find_tl->GetTypeItem(j).type_idx_);
309 }
310 }
311 const DexFile::ProtoId* found =
312 java_lang_dex_file_->FindProtoId(to_find.return_type_idx_, to_find_types);
313 ASSERT_TRUE(found != NULL);
314 EXPECT_EQ(java_lang_dex_file_->GetIndexForProtoId(*found), i);
315 }
316}
317
318TEST_F(DexFileTest, FindMethodId) {
319 for (size_t i = 0; i < java_lang_dex_file_->NumMethodIds(); i++) {
320 const DexFile::MethodId& to_find = java_lang_dex_file_->GetMethodId(i);
321 const DexFile::TypeId& klass = java_lang_dex_file_->GetTypeId(to_find.class_idx_);
322 const DexFile::StringId& name = java_lang_dex_file_->GetStringId(to_find.name_idx_);
323 const DexFile::ProtoId& signature = java_lang_dex_file_->GetProtoId(to_find.proto_idx_);
324 const DexFile::MethodId* found = java_lang_dex_file_->FindMethodId(klass, name, signature);
Ian Rogers0571d352011-11-03 19:51:38 -0700325 ASSERT_TRUE(found != NULL) << "Didn't find method " << i << ": "
326 << java_lang_dex_file_->StringByTypeIdx(to_find.class_idx_) << "."
327 << java_lang_dex_file_->GetStringData(name)
Ian Rogersd91d6d62013-09-25 20:26:14 -0700328 << java_lang_dex_file_->GetMethodSignature(to_find);
Ian Rogers0571d352011-11-03 19:51:38 -0700329 EXPECT_EQ(java_lang_dex_file_->GetIndexForMethodId(*found), i);
Carl Shapiro419ec7b2011-08-03 14:48:33 -0700330 }
Carl Shapiro419ec7b2011-08-03 14:48:33 -0700331}
332
Ian Rogers9b1a4f42011-11-14 18:35:10 -0800333TEST_F(DexFileTest, FindFieldId) {
334 for (size_t i = 0; i < java_lang_dex_file_->NumFieldIds(); i++) {
335 const DexFile::FieldId& to_find = java_lang_dex_file_->GetFieldId(i);
336 const DexFile::TypeId& klass = java_lang_dex_file_->GetTypeId(to_find.class_idx_);
337 const DexFile::StringId& name = java_lang_dex_file_->GetStringId(to_find.name_idx_);
338 const DexFile::TypeId& type = java_lang_dex_file_->GetTypeId(to_find.type_idx_);
339 const DexFile::FieldId* found = java_lang_dex_file_->FindFieldId(klass, name, type);
340 ASSERT_TRUE(found != NULL) << "Didn't find field " << i << ": "
341 << java_lang_dex_file_->StringByTypeIdx(to_find.type_idx_) << " "
342 << java_lang_dex_file_->StringByTypeIdx(to_find.class_idx_) << "."
343 << java_lang_dex_file_->GetStringData(name);
344 EXPECT_EQ(java_lang_dex_file_->GetIndexForFieldId(*found), i);
345 }
346}
347
Calin Juravle4e1d5792014-07-15 23:56:47 +0100348TEST_F(DexFileTest, GetMultiDexClassesDexName) {
349 std::string dex_location_str = "/system/app/framework.jar";
350 const char* dex_location = dex_location_str.c_str();
351 ASSERT_EQ("/system/app/framework.jar", DexFile::GetMultiDexClassesDexName(0, dex_location));
352 ASSERT_EQ("/system/app/framework.jar:classes2.dex", DexFile::GetMultiDexClassesDexName(1, dex_location));
353 ASSERT_EQ("/system/app/framework.jar:classes101.dex", DexFile::GetMultiDexClassesDexName(100, dex_location));
354}
355
356TEST_F(DexFileTest, GetDexCanonicalLocation) {
357 ScratchFile file;
Vladimir Markoaa4497d2014-09-05 14:01:17 +0100358 UniqueCPtr<const char[]> dex_location_real(realpath(file.GetFilename().c_str(), nullptr));
359 std::string dex_location(dex_location_real.get());
Calin Juravle4e1d5792014-07-15 23:56:47 +0100360
Calin Juravle61281dc2014-08-07 11:54:36 +0100361 ASSERT_EQ(dex_location, DexFile::GetDexCanonicalLocation(dex_location.c_str()));
Calin Juravle4e1d5792014-07-15 23:56:47 +0100362 std::string multidex_location = DexFile::GetMultiDexClassesDexName(1, dex_location.c_str());
363 ASSERT_EQ(multidex_location, DexFile::GetDexCanonicalLocation(multidex_location.c_str()));
364
365 std::string dex_location_sym = dex_location + "symlink";
366 ASSERT_EQ(0, symlink(dex_location.c_str(), dex_location_sym.c_str()));
367
368 ASSERT_EQ(dex_location, DexFile::GetDexCanonicalLocation(dex_location_sym.c_str()));
369
370 std::string multidex_location_sym = DexFile::GetMultiDexClassesDexName(1, dex_location_sym.c_str());
371 ASSERT_EQ(multidex_location, DexFile::GetDexCanonicalLocation(multidex_location_sym.c_str()));
372
373 ASSERT_EQ(0, unlink(dex_location_sym.c_str()));
374}
375
Carl Shapiro1fb86202011-06-27 17:43:13 -0700376} // namespace art