blob: 3dffc400118befbb04f3e9c027b78b613d537681 [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"
Orion Hodsona4c2a052016-08-17 10:51:42 +010025#include "mem_map.h"
Ian Rogerse63db272014-07-15 15:36:11 -070026#include "os.h"
27#include "scoped_thread_state_change.h"
28#include "thread-inl.h"
Alex Light9c20a142016-08-23 15:05:12 -070029#include "utils.h"
Elliott Hughes90a33692011-08-30 13:27:07 -070030
Carl Shapiro1fb86202011-06-27 17:43:13 -070031namespace art {
32
Brian Carlstroma1ce1fe2014-02-24 23:23:58 -080033class DexFileTest : public CommonRuntimeTest {};
Brian Carlstrom9f30b382011-08-28 22:41:38 -070034
35TEST_F(DexFileTest, Open) {
Ian Rogers33e95662013-05-20 20:29:14 -070036 ScopedObjectAccess soa(Thread::Current());
Richard Uhlerfbef44d2014-12-23 09:48:51 -080037 std::unique_ptr<const DexFile> dex(OpenTestDexFile("Nested"));
Mathieu Chartier2cebb242015-04-21 16:50:40 -070038 ASSERT_TRUE(dex.get() != nullptr);
Brian Carlstrom7e49dca2011-07-22 18:07:34 -070039}
Brian Carlstrom578bbdc2011-07-21 14:07:47 -070040
Alex Light9c20a142016-08-23 15:05:12 -070041static inline std::vector<uint8_t> DecodeBase64Vec(const char* src) {
42 std::vector<uint8_t> res;
43 size_t size;
44 std::unique_ptr<uint8_t[]> data(DecodeBase64(src, &size));
45 res.resize(size);
46 memcpy(res.data(), data.get(), size);
47 return res;
Brian Carlstroma1ce1fe2014-02-24 23:23:58 -080048}
49
Brian Carlstrom9f30b382011-08-28 22:41:38 -070050// Although this is the same content logically as the Nested test dex,
51// the DexFileHeader test is sensitive to subtle changes in the
52// contents due to the checksum etc, so we embed the exact input here.
53//
54// class Nested {
55// class Inner {
56// }
57// }
58static const char kRawDex[] =
59 "ZGV4CjAzNQAQedgAe7gM1B/WHsWJ6L7lGAISGC7yjD2IAwAAcAAAAHhWNBIAAAAAAAAAAMQCAAAP"
60 "AAAAcAAAAAcAAACsAAAAAgAAAMgAAAABAAAA4AAAAAMAAADoAAAAAgAAAAABAABIAgAAQAEAAK4B"
61 "AAC2AQAAvQEAAM0BAADXAQAA+wEAABsCAAA+AgAAUgIAAF8CAABiAgAAZgIAAHMCAAB5AgAAgQIA"
62 "AAIAAAADAAAABAAAAAUAAAAGAAAABwAAAAkAAAAJAAAABgAAAAAAAAAKAAAABgAAAKgBAAAAAAEA"
63 "DQAAAAAAAQAAAAAAAQAAAAAAAAAFAAAAAAAAAAAAAAAAAAAABQAAAAAAAAAIAAAAiAEAAKsCAAAA"
64 "AAAAAQAAAAAAAAAFAAAAAAAAAAgAAACYAQAAuAIAAAAAAAACAAAAlAIAAJoCAAABAAAAowIAAAIA"
65 "AgABAAAAiAIAAAYAAABbAQAAcBACAAAADgABAAEAAQAAAI4CAAAEAAAAcBACAAAADgBAAQAAAAAA"
66 "AAAAAAAAAAAATAEAAAAAAAAAAAAAAAAAAAEAAAABAAY8aW5pdD4ABUlubmVyAA5MTmVzdGVkJElu"
67 "bmVyOwAITE5lc3RlZDsAIkxkYWx2aWsvYW5ub3RhdGlvbi9FbmNsb3NpbmdDbGFzczsAHkxkYWx2"
68 "aWsvYW5ub3RhdGlvbi9Jbm5lckNsYXNzOwAhTGRhbHZpay9hbm5vdGF0aW9uL01lbWJlckNsYXNz"
69 "ZXM7ABJMamF2YS9sYW5nL09iamVjdDsAC05lc3RlZC5qYXZhAAFWAAJWTAALYWNjZXNzRmxhZ3MA"
70 "BG5hbWUABnRoaXMkMAAFdmFsdWUAAgEABw4AAQAHDjwAAgIBDhgBAgMCCwQADBcBAgQBDhwBGAAA"
71 "AQEAAJAgAICABNQCAAABAAGAgATwAgAAEAAAAAAAAAABAAAAAAAAAAEAAAAPAAAAcAAAAAIAAAAH"
72 "AAAArAAAAAMAAAACAAAAyAAAAAQAAAABAAAA4AAAAAUAAAADAAAA6AAAAAYAAAACAAAAAAEAAAMQ"
73 "AAACAAAAQAEAAAEgAAACAAAAVAEAAAYgAAACAAAAiAEAAAEQAAABAAAAqAEAAAIgAAAPAAAArgEA"
74 "AAMgAAACAAAAiAIAAAQgAAADAAAAlAIAAAAgAAACAAAAqwIAAAAQAAABAAAAxAIAAA==";
75
Narayan Kamath52e66502016-08-01 14:20:31 +010076// kRawDex38 and 39 are dex'ed versions of the following Java source :
77//
78// public class Main {
79// public static void main(String[] foo) {
80// }
81// }
82//
83// The dex file was manually edited to change its dex version code to 38
84// or 39, respectively.
85static const char kRawDex38[] =
86 "ZGV4CjAzOAC4OovJlJ1089ikzK6asMf/f8qp3Kve5VsgAgAAcAAAAHhWNBIAAAAAAAAAAIwBAAAI"
87 "AAAAcAAAAAQAAACQAAAAAgAAAKAAAAAAAAAAAAAAAAMAAAC4AAAAAQAAANAAAAAwAQAA8AAAACIB"
88 "AAAqAQAAMgEAAEYBAABRAQAAVAEAAFgBAABtAQAAAQAAAAIAAAAEAAAABgAAAAQAAAACAAAAAAAA"
89 "AAUAAAACAAAAHAEAAAAAAAAAAAAAAAABAAcAAAABAAAAAAAAAAAAAAABAAAAAQAAAAAAAAADAAAA"
90 "AAAAAH4BAAAAAAAAAQABAAEAAABzAQAABAAAAHAQAgAAAA4AAQABAAAAAAB4AQAAAQAAAA4AAAAB"
91 "AAAAAwAGPGluaXQ+AAZMTWFpbjsAEkxqYXZhL2xhbmcvT2JqZWN0OwAJTWFpbi5qYXZhAAFWAAJW"
92 "TAATW0xqYXZhL2xhbmcvU3RyaW5nOwAEbWFpbgABAAcOAAMBAAcOAAAAAgAAgYAE8AEBCYgCDAAA"
93 "AAAAAAABAAAAAAAAAAEAAAAIAAAAcAAAAAIAAAAEAAAAkAAAAAMAAAACAAAAoAAAAAUAAAADAAAA"
94 "uAAAAAYAAAABAAAA0AAAAAEgAAACAAAA8AAAAAEQAAABAAAAHAEAAAIgAAAIAAAAIgEAAAMgAAAC"
95 "AAAAcwEAAAAgAAABAAAAfgEAAAAQAAABAAAAjAEAAA==";
96
97static const char kRawDex39[] =
98 "ZGV4CjAzOQC4OovJlJ1089ikzK6asMf/f8qp3Kve5VsgAgAAcAAAAHhWNBIAAAAAAAAAAIwBAAAI"
99 "AAAAcAAAAAQAAACQAAAAAgAAAKAAAAAAAAAAAAAAAAMAAAC4AAAAAQAAANAAAAAwAQAA8AAAACIB"
100 "AAAqAQAAMgEAAEYBAABRAQAAVAEAAFgBAABtAQAAAQAAAAIAAAAEAAAABgAAAAQAAAACAAAAAAAA"
101 "AAUAAAACAAAAHAEAAAAAAAAAAAAAAAABAAcAAAABAAAAAAAAAAAAAAABAAAAAQAAAAAAAAADAAAA"
102 "AAAAAH4BAAAAAAAAAQABAAEAAABzAQAABAAAAHAQAgAAAA4AAQABAAAAAAB4AQAAAQAAAA4AAAAB"
103 "AAAAAwAGPGluaXQ+AAZMTWFpbjsAEkxqYXZhL2xhbmcvT2JqZWN0OwAJTWFpbi5qYXZhAAFWAAJW"
104 "TAATW0xqYXZhL2xhbmcvU3RyaW5nOwAEbWFpbgABAAcOAAMBAAcOAAAAAgAAgYAE8AEBCYgCDAAA"
105 "AAAAAAABAAAAAAAAAAEAAAAIAAAAcAAAAAIAAAAEAAAAkAAAAAMAAAACAAAAoAAAAAUAAAADAAAA"
106 "uAAAAAYAAAABAAAA0AAAAAEgAAACAAAA8AAAAAEQAAABAAAAHAEAAAIgAAAIAAAAIgEAAAMgAAAC"
107 "AAAAcwEAAAAgAAABAAAAfgEAAAAQAAABAAAAjAEAAA==";
108
ganxiaolincd16d0a2016-07-18 11:21:44 +0800109static const char kRawDexZeroLength[] =
110 "UEsDBAoAAAAAAOhxAkkAAAAAAAAAAAAAAAALABwAY2xhc3Nlcy5kZXhVVAkAA2QNoVdnDaFXdXgL"
111 "AAEE5AMBAASIEwAAUEsBAh4DCgAAAAAA6HECSQAAAAAAAAAAAAAAAAsAGAAAAAAAAAAAAKCBAAAA"
112 "AGNsYXNzZXMuZGV4VVQFAANkDaFXdXgLAAEE5AMBAASIEwAAUEsFBgAAAAABAAEAUQAAAEUAAAAA"
113 "AA==";
114
Narayan Kamath52e66502016-08-01 14:20:31 +0100115static void DecodeAndWriteDexFile(const char* base64, const char* location) {
Ian Rogers33e95662013-05-20 20:29:14 -0700116 // decode base64
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700117 CHECK(base64 != nullptr);
Alex Light9c20a142016-08-23 15:05:12 -0700118 std::vector<uint8_t> dex_bytes = DecodeBase64Vec(base64);
Orion Hodsona4c2a052016-08-17 10:51:42 +0100119 CHECK_NE(dex_bytes.size(), 0u);
Ian Rogers33e95662013-05-20 20:29:14 -0700120
121 // write to provided file
Ian Rogers700a4022014-05-19 16:49:03 -0700122 std::unique_ptr<File> file(OS::CreateEmptyFile(location));
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700123 CHECK(file.get() != nullptr);
Orion Hodsona4c2a052016-08-17 10:51:42 +0100124 if (!file->WriteFully(dex_bytes.data(), dex_bytes.size())) {
Ian Rogers33e95662013-05-20 20:29:14 -0700125 PLOG(FATAL) << "Failed to write base64 as dex file";
126 }
Andreas Gampe4303ba92014-11-06 01:00:46 -0800127 if (file->FlushCloseOrErase() != 0) {
128 PLOG(FATAL) << "Could not flush and close test file.";
129 }
Narayan Kamath52e66502016-08-01 14:20:31 +0100130}
131
132static std::unique_ptr<const DexFile> OpenDexFileBase64(const char* base64,
133 const char* location) {
134 DecodeAndWriteDexFile(base64, location);
Ian Rogers33e95662013-05-20 20:29:14 -0700135
136 // read dex file
137 ScopedObjectAccess soa(Thread::Current());
Aart Bik37d6a3b2016-06-21 18:30:10 -0700138 static constexpr bool kVerifyChecksum = true;
Ian Rogers8d31bbd2013-10-13 10:44:14 -0700139 std::string error_msg;
Richard Uhlerfbef44d2014-12-23 09:48:51 -0800140 std::vector<std::unique_ptr<const DexFile>> tmp;
Aart Bik37d6a3b2016-06-21 18:30:10 -0700141 bool success = DexFile::Open(location, location, kVerifyChecksum, &error_msg, &tmp);
Andreas Gampe833a4852014-05-21 18:46:59 -0700142 CHECK(success) << error_msg;
143 EXPECT_EQ(1U, tmp.size());
Richard Uhlerfbef44d2014-12-23 09:48:51 -0800144 std::unique_ptr<const DexFile> dex_file = std::move(tmp[0]);
Brian Carlstrome0948e12013-08-29 09:36:15 -0700145 EXPECT_EQ(PROT_READ, dex_file->GetPermissions());
146 EXPECT_TRUE(dex_file->IsReadOnly());
Ian Rogers33e95662013-05-20 20:29:14 -0700147 return dex_file;
148}
149
Orion Hodsona4c2a052016-08-17 10:51:42 +0100150static std::unique_ptr<const DexFile> OpenDexFileInMemoryBase64(const char* base64,
151 const char* location,
152 uint32_t location_checksum) {
153 CHECK(base64 != nullptr);
Alex Light9c20a142016-08-23 15:05:12 -0700154 std::vector<uint8_t> dex_bytes = DecodeBase64Vec(base64);
Orion Hodsona4c2a052016-08-17 10:51:42 +0100155 CHECK_NE(dex_bytes.size(), 0u);
156
157 std::string error_message;
158 std::unique_ptr<MemMap> region(MemMap::MapAnonymous("test-region",
159 nullptr,
160 dex_bytes.size(),
161 PROT_READ | PROT_WRITE,
162 /* low_4gb */ false,
163 /* reuse */ false,
164 &error_message));
165 memcpy(region->Begin(), dex_bytes.data(), dex_bytes.size());
166 std::unique_ptr<const DexFile> dex_file(DexFile::Open(location,
167 location_checksum,
168 std::move(region),
169 /* verify */ true,
170 /* verify_checksum */ true,
171 &error_message));
172 CHECK(dex_file != nullptr) << error_message;
173 return dex_file;
174}
175
Orion Hodsoncffc5292016-09-05 13:43:11 +0100176static void ValidateDexFileHeader(std::unique_ptr<const DexFile> dex_file) {
177 static const uint8_t kExpectedDexFileMagic[8] = {
178 /* d */ 0x64, /* e */ 0x64, /* x */ 0x78, /* \n */ 0x0d,
179 /* 0 */ 0x30, /* 3 */ 0x33, /* 5 */ 0x35, /* \0 */ 0x00
180 };
181 static const uint8_t kExpectedSha1[DexFile::kSha1DigestSize] = {
182 0x7b, 0xb8, 0x0c, 0xd4, 0x1f, 0xd6, 0x1e, 0xc5,
183 0x89, 0xe8, 0xbe, 0xe5, 0x18, 0x02, 0x12, 0x18,
184 0x2e, 0xf2, 0x8c, 0x3d,
185 };
Orion Hodsona4c2a052016-08-17 10:51:42 +0100186
Orion Hodsoncffc5292016-09-05 13:43:11 +0100187 const DexFile::Header& header = dex_file->GetHeader();
188 EXPECT_EQ(*kExpectedDexFileMagic, *header.magic_);
Orion Hodsona4c2a052016-08-17 10:51:42 +0100189 EXPECT_EQ(0x00d87910U, header.checksum_);
Orion Hodsoncffc5292016-09-05 13:43:11 +0100190 EXPECT_EQ(*kExpectedSha1, *header.signature_);
Orion Hodsona4c2a052016-08-17 10:51:42 +0100191 EXPECT_EQ(904U, header.file_size_);
192 EXPECT_EQ(112U, header.header_size_);
193 EXPECT_EQ(0U, header.link_size_);
194 EXPECT_EQ(0U, header.link_off_);
195 EXPECT_EQ(15U, header.string_ids_size_);
196 EXPECT_EQ(112U, header.string_ids_off_);
197 EXPECT_EQ(7U, header.type_ids_size_);
198 EXPECT_EQ(172U, header.type_ids_off_);
199 EXPECT_EQ(2U, header.proto_ids_size_);
200 EXPECT_EQ(200U, header.proto_ids_off_);
201 EXPECT_EQ(1U, header.field_ids_size_);
202 EXPECT_EQ(224U, header.field_ids_off_);
203 EXPECT_EQ(3U, header.method_ids_size_);
204 EXPECT_EQ(232U, header.method_ids_off_);
205 EXPECT_EQ(2U, header.class_defs_size_);
206 EXPECT_EQ(256U, header.class_defs_off_);
207 EXPECT_EQ(584U, header.data_size_);
208 EXPECT_EQ(320U, header.data_off_);
209
Orion Hodsoncffc5292016-09-05 13:43:11 +0100210 EXPECT_EQ(header.checksum_, dex_file->GetLocationChecksum());
211}
212
213TEST_F(DexFileTest, Header) {
214 ScratchFile tmp;
215 std::unique_ptr<const DexFile> raw(OpenDexFileBase64(kRawDex, tmp.GetFilename().c_str()));
216 ValidateDexFileHeader(std::move(raw));
Orion Hodsona4c2a052016-08-17 10:51:42 +0100217}
218
219TEST_F(DexFileTest, HeaderInMemory) {
220 ScratchFile tmp;
221 std::unique_ptr<const DexFile> raw =
222 OpenDexFileInMemoryBase64(kRawDex, tmp.GetFilename().c_str(), 0x00d87910U);
Orion Hodsoncffc5292016-09-05 13:43:11 +0100223 ValidateDexFileHeader(std::move(raw));
Brian Carlstrom5b332c82012-02-01 15:02:31 -0800224}
225
Narayan Kamath52e66502016-08-01 14:20:31 +0100226TEST_F(DexFileTest, Version38Accepted) {
227 ScratchFile tmp;
228 std::unique_ptr<const DexFile> raw(OpenDexFileBase64(kRawDex38, tmp.GetFilename().c_str()));
229 ASSERT_TRUE(raw.get() != nullptr);
230
231 const DexFile::Header& header = raw->GetHeader();
232 EXPECT_EQ(38u, header.GetVersion());
233}
234
235TEST_F(DexFileTest, Version39Rejected) {
236 ScratchFile tmp;
237 const char* location = tmp.GetFilename().c_str();
238 DecodeAndWriteDexFile(kRawDex39, location);
239
240 ScopedObjectAccess soa(Thread::Current());
241 static constexpr bool kVerifyChecksum = true;
242 std::string error_msg;
243 std::vector<std::unique_ptr<const DexFile>> dex_files;
244 ASSERT_FALSE(DexFile::Open(location, location, kVerifyChecksum, &error_msg, &dex_files));
245}
246
ganxiaolincd16d0a2016-07-18 11:21:44 +0800247TEST_F(DexFileTest, ZeroLengthDexRejected) {
248 ScratchFile tmp;
249 const char* location = tmp.GetFilename().c_str();
250 DecodeAndWriteDexFile(kRawDexZeroLength, location);
251
252 ScopedObjectAccess soa(Thread::Current());
253 static constexpr bool kVerifyChecksum = true;
254 std::string error_msg;
255 std::vector<std::unique_ptr<const DexFile>> dex_files;
256 ASSERT_FALSE(DexFile::Open(location, location, kVerifyChecksum, &error_msg, &dex_files));
257}
258
Brian Carlstrom5b332c82012-02-01 15:02:31 -0800259TEST_F(DexFileTest, GetLocationChecksum) {
Ian Rogers33e95662013-05-20 20:29:14 -0700260 ScopedObjectAccess soa(Thread::Current());
Richard Uhlerfbef44d2014-12-23 09:48:51 -0800261 std::unique_ptr<const DexFile> raw(OpenTestDexFile("Main"));
Brian Carlstrom5b332c82012-02-01 15:02:31 -0800262 EXPECT_NE(raw->GetHeader().checksum_, raw->GetLocationChecksum());
263}
264
265TEST_F(DexFileTest, GetChecksum) {
266 uint32_t checksum;
Ian Rogers33e95662013-05-20 20:29:14 -0700267 ScopedObjectAccess soa(Thread::Current());
Ian Rogers8d31bbd2013-10-13 10:44:14 -0700268 std::string error_msg;
Przemyslaw Szczepaniak5b8e6e32015-09-30 14:40:33 +0100269 EXPECT_TRUE(DexFile::GetChecksum(GetLibCoreDexFileNames()[0].c_str(), &checksum, &error_msg))
Ian Rogers8d31bbd2013-10-13 10:44:14 -0700270 << error_msg;
Brian Carlstrom5b332c82012-02-01 15:02:31 -0800271 EXPECT_EQ(java_lang_dex_file_->GetLocationChecksum(), checksum);
Brian Carlstrom7e49dca2011-07-22 18:07:34 -0700272}
273
Brian Carlstrom9f30b382011-08-28 22:41:38 -0700274TEST_F(DexFileTest, ClassDefs) {
Ian Rogers33e95662013-05-20 20:29:14 -0700275 ScopedObjectAccess soa(Thread::Current());
Richard Uhlerfbef44d2014-12-23 09:48:51 -0800276 std::unique_ptr<const DexFile> raw(OpenTestDexFile("Nested"));
277 ASSERT_TRUE(raw.get() != nullptr);
Brian Carlstrom7e49dca2011-07-22 18:07:34 -0700278 EXPECT_EQ(2U, raw->NumClassDefs());
279
Brian Carlstromf615a612011-07-23 12:50:34 -0700280 const DexFile::ClassDef& c0 = raw->GetClassDef(0);
Brian Carlstrom7e49dca2011-07-22 18:07:34 -0700281 EXPECT_STREQ("LNested$Inner;", raw->GetClassDescriptor(c0));
282
Brian Carlstromf615a612011-07-23 12:50:34 -0700283 const DexFile::ClassDef& c1 = raw->GetClassDef(1);
Brian Carlstrom7e49dca2011-07-22 18:07:34 -0700284 EXPECT_STREQ("LNested;", raw->GetClassDescriptor(c1));
Carl Shapiro1fb86202011-06-27 17:43:13 -0700285}
286
Ian Rogersd91d6d62013-09-25 20:26:14 -0700287TEST_F(DexFileTest, GetMethodSignature) {
Ian Rogers33e95662013-05-20 20:29:14 -0700288 ScopedObjectAccess soa(Thread::Current());
Richard Uhlerfbef44d2014-12-23 09:48:51 -0800289 std::unique_ptr<const DexFile> raw(OpenTestDexFile("GetMethodSignature"));
290 ASSERT_TRUE(raw.get() != nullptr);
Carl Shapiro419ec7b2011-08-03 14:48:33 -0700291 EXPECT_EQ(1U, raw->NumClassDefs());
292
293 const DexFile::ClassDef& class_def = raw->GetClassDef(0);
Ian Rogersd91d6d62013-09-25 20:26:14 -0700294 ASSERT_STREQ("LGetMethodSignature;", raw->GetClassDescriptor(class_def));
Carl Shapiro419ec7b2011-08-03 14:48:33 -0700295
Ian Rogers13735952014-10-08 12:43:28 -0700296 const uint8_t* class_data = raw->GetClassData(class_def);
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700297 ASSERT_TRUE(class_data != nullptr);
Elliott Hughes4d6850c2012-01-18 15:55:06 -0800298 ClassDataItemIterator it(*raw, class_data);
Carl Shapiro419ec7b2011-08-03 14:48:33 -0700299
Ian Rogers0571d352011-11-03 19:51:38 -0700300 EXPECT_EQ(1u, it.NumDirectMethods());
Carl Shapiro419ec7b2011-08-03 14:48:33 -0700301
Ian Rogers0571d352011-11-03 19:51:38 -0700302 // Check the signature for the static initializer.
Carl Shapiro419ec7b2011-08-03 14:48:33 -0700303 {
Ian Rogers0571d352011-11-03 19:51:38 -0700304 ASSERT_EQ(1U, it.NumDirectMethods());
305 const DexFile::MethodId& method_id = raw->GetMethodId(it.GetMemberIndex());
Ian Rogers0571d352011-11-03 19:51:38 -0700306 const char* name = raw->StringDataByIdx(method_id.name_idx_);
Carl Shapiro419ec7b2011-08-03 14:48:33 -0700307 ASSERT_STREQ("<init>", name);
Ian Rogersd91d6d62013-09-25 20:26:14 -0700308 std::string signature(raw->GetMethodSignature(method_id).ToString());
Ian Rogers0571d352011-11-03 19:51:38 -0700309 ASSERT_EQ("()V", signature);
Carl Shapiro419ec7b2011-08-03 14:48:33 -0700310 }
311
312 // Check both virtual methods.
Ian Rogers0571d352011-11-03 19:51:38 -0700313 ASSERT_EQ(2U, it.NumVirtualMethods());
Carl Shapiro419ec7b2011-08-03 14:48:33 -0700314 {
Ian Rogers0571d352011-11-03 19:51:38 -0700315 it.Next();
316 const DexFile::MethodId& method_id = raw->GetMethodId(it.GetMemberIndex());
Carl Shapiro419ec7b2011-08-03 14:48:33 -0700317
Ian Rogers0571d352011-11-03 19:51:38 -0700318 const char* name = raw->StringDataByIdx(method_id.name_idx_);
Carl Shapiro419ec7b2011-08-03 14:48:33 -0700319 ASSERT_STREQ("m1", name);
320
Ian Rogersd91d6d62013-09-25 20:26:14 -0700321 std::string signature(raw->GetMethodSignature(method_id).ToString());
Ian Rogers0571d352011-11-03 19:51:38 -0700322 ASSERT_EQ("(IDJLjava/lang/Object;)Ljava/lang/Float;", signature);
Carl Shapiro419ec7b2011-08-03 14:48:33 -0700323 }
324
325 {
Ian Rogers0571d352011-11-03 19:51:38 -0700326 it.Next();
327 const DexFile::MethodId& method_id = raw->GetMethodId(it.GetMemberIndex());
Carl Shapiro419ec7b2011-08-03 14:48:33 -0700328
Ian Rogers0571d352011-11-03 19:51:38 -0700329 const char* name = raw->StringDataByIdx(method_id.name_idx_);
Carl Shapiro419ec7b2011-08-03 14:48:33 -0700330 ASSERT_STREQ("m2", name);
331
Ian Rogersd91d6d62013-09-25 20:26:14 -0700332 std::string signature(raw->GetMethodSignature(method_id).ToString());
333 ASSERT_EQ("(ZSC)LGetMethodSignature;", signature);
Ian Rogers0571d352011-11-03 19:51:38 -0700334 }
335}
336
337TEST_F(DexFileTest, FindStringId) {
Ian Rogers33e95662013-05-20 20:29:14 -0700338 ScopedObjectAccess soa(Thread::Current());
Richard Uhlerfbef44d2014-12-23 09:48:51 -0800339 std::unique_ptr<const DexFile> raw(OpenTestDexFile("GetMethodSignature"));
340 ASSERT_TRUE(raw.get() != nullptr);
Ian Rogers0571d352011-11-03 19:51:38 -0700341 EXPECT_EQ(1U, raw->NumClassDefs());
342
Ian Rogersd91d6d62013-09-25 20:26:14 -0700343 const char* strings[] = { "LGetMethodSignature;", "Ljava/lang/Float;", "Ljava/lang/Object;",
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700344 "D", "I", "J", nullptr };
345 for (size_t i = 0; strings[i] != nullptr; i++) {
Ian Rogers0571d352011-11-03 19:51:38 -0700346 const char* str = strings[i];
347 const DexFile::StringId* str_id = raw->FindStringId(str);
348 const char* dex_str = raw->GetStringData(*str_id);
349 EXPECT_STREQ(dex_str, str);
350 }
351}
352
353TEST_F(DexFileTest, FindTypeId) {
354 for (size_t i = 0; i < java_lang_dex_file_->NumTypeIds(); i++) {
355 const char* type_str = java_lang_dex_file_->StringByTypeIdx(i);
356 const DexFile::StringId* type_str_id = java_lang_dex_file_->FindStringId(type_str);
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700357 ASSERT_TRUE(type_str_id != nullptr);
Ian Rogers0571d352011-11-03 19:51:38 -0700358 uint32_t type_str_idx = java_lang_dex_file_->GetIndexForStringId(*type_str_id);
359 const DexFile::TypeId* type_id = java_lang_dex_file_->FindTypeId(type_str_idx);
Mathieu Chartier9507fa22015-10-29 15:08:57 -0700360 ASSERT_EQ(type_id, java_lang_dex_file_->FindTypeId(type_str));
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700361 ASSERT_TRUE(type_id != nullptr);
Ian Rogers0571d352011-11-03 19:51:38 -0700362 EXPECT_EQ(java_lang_dex_file_->GetIndexForTypeId(*type_id), i);
363 }
364}
365
366TEST_F(DexFileTest, FindProtoId) {
367 for (size_t i = 0; i < java_lang_dex_file_->NumProtoIds(); i++) {
368 const DexFile::ProtoId& to_find = java_lang_dex_file_->GetProtoId(i);
369 const DexFile::TypeList* to_find_tl = java_lang_dex_file_->GetProtoParameters(to_find);
370 std::vector<uint16_t> to_find_types;
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700371 if (to_find_tl != nullptr) {
Ian Rogers0571d352011-11-03 19:51:38 -0700372 for (size_t j = 0; j < to_find_tl->Size(); j++) {
373 to_find_types.push_back(to_find_tl->GetTypeItem(j).type_idx_);
374 }
375 }
376 const DexFile::ProtoId* found =
377 java_lang_dex_file_->FindProtoId(to_find.return_type_idx_, to_find_types);
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700378 ASSERT_TRUE(found != nullptr);
Ian Rogers0571d352011-11-03 19:51:38 -0700379 EXPECT_EQ(java_lang_dex_file_->GetIndexForProtoId(*found), i);
380 }
381}
382
383TEST_F(DexFileTest, FindMethodId) {
384 for (size_t i = 0; i < java_lang_dex_file_->NumMethodIds(); i++) {
385 const DexFile::MethodId& to_find = java_lang_dex_file_->GetMethodId(i);
386 const DexFile::TypeId& klass = java_lang_dex_file_->GetTypeId(to_find.class_idx_);
387 const DexFile::StringId& name = java_lang_dex_file_->GetStringId(to_find.name_idx_);
388 const DexFile::ProtoId& signature = java_lang_dex_file_->GetProtoId(to_find.proto_idx_);
389 const DexFile::MethodId* found = java_lang_dex_file_->FindMethodId(klass, name, signature);
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700390 ASSERT_TRUE(found != nullptr) << "Didn't find method " << i << ": "
Ian Rogers0571d352011-11-03 19:51:38 -0700391 << java_lang_dex_file_->StringByTypeIdx(to_find.class_idx_) << "."
392 << java_lang_dex_file_->GetStringData(name)
Ian Rogersd91d6d62013-09-25 20:26:14 -0700393 << java_lang_dex_file_->GetMethodSignature(to_find);
Ian Rogers0571d352011-11-03 19:51:38 -0700394 EXPECT_EQ(java_lang_dex_file_->GetIndexForMethodId(*found), i);
Carl Shapiro419ec7b2011-08-03 14:48:33 -0700395 }
Carl Shapiro419ec7b2011-08-03 14:48:33 -0700396}
397
Ian Rogers9b1a4f42011-11-14 18:35:10 -0800398TEST_F(DexFileTest, FindFieldId) {
399 for (size_t i = 0; i < java_lang_dex_file_->NumFieldIds(); i++) {
400 const DexFile::FieldId& to_find = java_lang_dex_file_->GetFieldId(i);
401 const DexFile::TypeId& klass = java_lang_dex_file_->GetTypeId(to_find.class_idx_);
402 const DexFile::StringId& name = java_lang_dex_file_->GetStringId(to_find.name_idx_);
403 const DexFile::TypeId& type = java_lang_dex_file_->GetTypeId(to_find.type_idx_);
404 const DexFile::FieldId* found = java_lang_dex_file_->FindFieldId(klass, name, type);
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700405 ASSERT_TRUE(found != nullptr) << "Didn't find field " << i << ": "
Ian Rogers9b1a4f42011-11-14 18:35:10 -0800406 << java_lang_dex_file_->StringByTypeIdx(to_find.type_idx_) << " "
407 << java_lang_dex_file_->StringByTypeIdx(to_find.class_idx_) << "."
408 << java_lang_dex_file_->GetStringData(name);
409 EXPECT_EQ(java_lang_dex_file_->GetIndexForFieldId(*found), i);
410 }
411}
412
Calin Juravle4e1d5792014-07-15 23:56:47 +0100413TEST_F(DexFileTest, GetMultiDexClassesDexName) {
Andreas Gampe90e34042015-04-27 20:01:52 -0700414 ASSERT_EQ("classes.dex", DexFile::GetMultiDexClassesDexName(0));
415 ASSERT_EQ("classes2.dex", DexFile::GetMultiDexClassesDexName(1));
416 ASSERT_EQ("classes3.dex", DexFile::GetMultiDexClassesDexName(2));
417 ASSERT_EQ("classes100.dex", DexFile::GetMultiDexClassesDexName(99));
418}
419
420TEST_F(DexFileTest, GetMultiDexLocation) {
Calin Juravle4e1d5792014-07-15 23:56:47 +0100421 std::string dex_location_str = "/system/app/framework.jar";
422 const char* dex_location = dex_location_str.c_str();
Andreas Gampe90e34042015-04-27 20:01:52 -0700423 ASSERT_EQ("/system/app/framework.jar", DexFile::GetMultiDexLocation(0, dex_location));
424 ASSERT_EQ("/system/app/framework.jar:classes2.dex",
425 DexFile::GetMultiDexLocation(1, dex_location));
426 ASSERT_EQ("/system/app/framework.jar:classes101.dex",
427 DexFile::GetMultiDexLocation(100, dex_location));
Calin Juravle4e1d5792014-07-15 23:56:47 +0100428}
429
430TEST_F(DexFileTest, GetDexCanonicalLocation) {
431 ScratchFile file;
Vladimir Markoaa4497d2014-09-05 14:01:17 +0100432 UniqueCPtr<const char[]> dex_location_real(realpath(file.GetFilename().c_str(), nullptr));
433 std::string dex_location(dex_location_real.get());
Calin Juravle4e1d5792014-07-15 23:56:47 +0100434
Calin Juravle61281dc2014-08-07 11:54:36 +0100435 ASSERT_EQ(dex_location, DexFile::GetDexCanonicalLocation(dex_location.c_str()));
Andreas Gampe90e34042015-04-27 20:01:52 -0700436 std::string multidex_location = DexFile::GetMultiDexLocation(1, dex_location.c_str());
Calin Juravle4e1d5792014-07-15 23:56:47 +0100437 ASSERT_EQ(multidex_location, DexFile::GetDexCanonicalLocation(multidex_location.c_str()));
438
439 std::string dex_location_sym = dex_location + "symlink";
440 ASSERT_EQ(0, symlink(dex_location.c_str(), dex_location_sym.c_str()));
441
442 ASSERT_EQ(dex_location, DexFile::GetDexCanonicalLocation(dex_location_sym.c_str()));
443
Andreas Gampe90e34042015-04-27 20:01:52 -0700444 std::string multidex_location_sym = DexFile::GetMultiDexLocation(1, dex_location_sym.c_str());
Calin Juravle4e1d5792014-07-15 23:56:47 +0100445 ASSERT_EQ(multidex_location, DexFile::GetDexCanonicalLocation(multidex_location_sym.c_str()));
446
447 ASSERT_EQ(0, unlink(dex_location_sym.c_str()));
448}
449
Richard Uhlere5fed032015-03-18 08:21:11 -0700450TEST(DexFileUtilsTest, GetBaseLocationAndMultiDexSuffix) {
451 EXPECT_EQ("/foo/bar/baz.jar", DexFile::GetBaseLocation("/foo/bar/baz.jar"));
452 EXPECT_EQ("/foo/bar/baz.jar", DexFile::GetBaseLocation("/foo/bar/baz.jar:classes2.dex"));
453 EXPECT_EQ("/foo/bar/baz.jar", DexFile::GetBaseLocation("/foo/bar/baz.jar:classes8.dex"));
454 EXPECT_EQ("", DexFile::GetMultiDexSuffix("/foo/bar/baz.jar"));
455 EXPECT_EQ(":classes2.dex", DexFile::GetMultiDexSuffix("/foo/bar/baz.jar:classes2.dex"));
456 EXPECT_EQ(":classes8.dex", DexFile::GetMultiDexSuffix("/foo/bar/baz.jar:classes8.dex"));
457}
458
Carl Shapiro1fb86202011-06-27 17:43:13 -0700459} // namespace art