blob: cb721af7540cd4586b51aec8ecfc0303b091df25 [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
Andreas Gamped4901292017-05-30 18:41:34 -070019#include <sys/mman.h>
20
Ian Rogers700a4022014-05-19 16:49:03 -070021#include <memory>
22
David Sehr013fd802018-01-11 22:55:24 -080023#include "art_dex_file_loader.h"
Ian Rogerse63db272014-07-15 15:36:11 -070024#include "base/stl_util.h"
25#include "base/unix_file/fd_file.h"
Mathieu Chartier808c7a52017-12-15 11:19:33 -080026#include "code_item_accessors-inl.h"
Brian Carlstroma1ce1fe2014-02-24 23:23:58 -080027#include "common_runtime_test.h"
Elliott Hughes956af0f2014-12-11 14:34:28 -080028#include "dex_file-inl.h"
Mathieu Chartier79c87da2017-10-10 11:54:29 -070029#include "dex_file_loader.h"
Orion Hodsona4c2a052016-08-17 10:51:42 +010030#include "mem_map.h"
Ian Rogerse63db272014-07-15 15:36:11 -070031#include "os.h"
Mathieu Chartier0795f232016-09-27 18:43:30 -070032#include "scoped_thread_state_change-inl.h"
Andreas Gampeb486a982017-06-01 13:45:54 -070033#include "thread-current-inl.h"
Alex Light9c20a142016-08-23 15:05:12 -070034#include "utils.h"
Elliott Hughes90a33692011-08-30 13:27:07 -070035
Carl Shapiro1fb86202011-06-27 17:43:13 -070036namespace art {
37
Brian Carlstroma1ce1fe2014-02-24 23:23:58 -080038class DexFileTest : public CommonRuntimeTest {};
Brian Carlstrom9f30b382011-08-28 22:41:38 -070039
40TEST_F(DexFileTest, Open) {
Ian Rogers33e95662013-05-20 20:29:14 -070041 ScopedObjectAccess soa(Thread::Current());
Richard Uhlerfbef44d2014-12-23 09:48:51 -080042 std::unique_ptr<const DexFile> dex(OpenTestDexFile("Nested"));
Mathieu Chartier2cebb242015-04-21 16:50:40 -070043 ASSERT_TRUE(dex.get() != nullptr);
Brian Carlstrom7e49dca2011-07-22 18:07:34 -070044}
Brian Carlstrom578bbdc2011-07-21 14:07:47 -070045
Alex Light9c20a142016-08-23 15:05:12 -070046static inline std::vector<uint8_t> DecodeBase64Vec(const char* src) {
47 std::vector<uint8_t> res;
48 size_t size;
49 std::unique_ptr<uint8_t[]> data(DecodeBase64(src, &size));
50 res.resize(size);
51 memcpy(res.data(), data.get(), size);
52 return res;
Brian Carlstroma1ce1fe2014-02-24 23:23:58 -080053}
54
Brian Carlstrom9f30b382011-08-28 22:41:38 -070055// Although this is the same content logically as the Nested test dex,
56// the DexFileHeader test is sensitive to subtle changes in the
57// contents due to the checksum etc, so we embed the exact input here.
58//
59// class Nested {
60// class Inner {
61// }
62// }
63static const char kRawDex[] =
64 "ZGV4CjAzNQAQedgAe7gM1B/WHsWJ6L7lGAISGC7yjD2IAwAAcAAAAHhWNBIAAAAAAAAAAMQCAAAP"
65 "AAAAcAAAAAcAAACsAAAAAgAAAMgAAAABAAAA4AAAAAMAAADoAAAAAgAAAAABAABIAgAAQAEAAK4B"
66 "AAC2AQAAvQEAAM0BAADXAQAA+wEAABsCAAA+AgAAUgIAAF8CAABiAgAAZgIAAHMCAAB5AgAAgQIA"
67 "AAIAAAADAAAABAAAAAUAAAAGAAAABwAAAAkAAAAJAAAABgAAAAAAAAAKAAAABgAAAKgBAAAAAAEA"
68 "DQAAAAAAAQAAAAAAAQAAAAAAAAAFAAAAAAAAAAAAAAAAAAAABQAAAAAAAAAIAAAAiAEAAKsCAAAA"
69 "AAAAAQAAAAAAAAAFAAAAAAAAAAgAAACYAQAAuAIAAAAAAAACAAAAlAIAAJoCAAABAAAAowIAAAIA"
70 "AgABAAAAiAIAAAYAAABbAQAAcBACAAAADgABAAEAAQAAAI4CAAAEAAAAcBACAAAADgBAAQAAAAAA"
71 "AAAAAAAAAAAATAEAAAAAAAAAAAAAAAAAAAEAAAABAAY8aW5pdD4ABUlubmVyAA5MTmVzdGVkJElu"
72 "bmVyOwAITE5lc3RlZDsAIkxkYWx2aWsvYW5ub3RhdGlvbi9FbmNsb3NpbmdDbGFzczsAHkxkYWx2"
73 "aWsvYW5ub3RhdGlvbi9Jbm5lckNsYXNzOwAhTGRhbHZpay9hbm5vdGF0aW9uL01lbWJlckNsYXNz"
74 "ZXM7ABJMamF2YS9sYW5nL09iamVjdDsAC05lc3RlZC5qYXZhAAFWAAJWTAALYWNjZXNzRmxhZ3MA"
75 "BG5hbWUABnRoaXMkMAAFdmFsdWUAAgEABw4AAQAHDjwAAgIBDhgBAgMCCwQADBcBAgQBDhwBGAAA"
76 "AQEAAJAgAICABNQCAAABAAGAgATwAgAAEAAAAAAAAAABAAAAAAAAAAEAAAAPAAAAcAAAAAIAAAAH"
77 "AAAArAAAAAMAAAACAAAAyAAAAAQAAAABAAAA4AAAAAUAAAADAAAA6AAAAAYAAAACAAAAAAEAAAMQ"
78 "AAACAAAAQAEAAAEgAAACAAAAVAEAAAYgAAACAAAAiAEAAAEQAAABAAAAqAEAAAIgAAAPAAAArgEA"
79 "AAMgAAACAAAAiAIAAAQgAAADAAAAlAIAAAAgAAACAAAAqwIAAAAQAAABAAAAxAIAAA==";
80
Orion Hodson2e599942017-09-22 16:17:41 +010081// kRawDex{38,39,40,41} are dex'ed versions of the following Java source :
Narayan Kamath52e66502016-08-01 14:20:31 +010082//
83// public class Main {
84// public static void main(String[] foo) {
85// }
86// }
87//
88// The dex file was manually edited to change its dex version code to 38
89// or 39, respectively.
90static const char kRawDex38[] =
91 "ZGV4CjAzOAC4OovJlJ1089ikzK6asMf/f8qp3Kve5VsgAgAAcAAAAHhWNBIAAAAAAAAAAIwBAAAI"
92 "AAAAcAAAAAQAAACQAAAAAgAAAKAAAAAAAAAAAAAAAAMAAAC4AAAAAQAAANAAAAAwAQAA8AAAACIB"
93 "AAAqAQAAMgEAAEYBAABRAQAAVAEAAFgBAABtAQAAAQAAAAIAAAAEAAAABgAAAAQAAAACAAAAAAAA"
94 "AAUAAAACAAAAHAEAAAAAAAAAAAAAAAABAAcAAAABAAAAAAAAAAAAAAABAAAAAQAAAAAAAAADAAAA"
95 "AAAAAH4BAAAAAAAAAQABAAEAAABzAQAABAAAAHAQAgAAAA4AAQABAAAAAAB4AQAAAQAAAA4AAAAB"
96 "AAAAAwAGPGluaXQ+AAZMTWFpbjsAEkxqYXZhL2xhbmcvT2JqZWN0OwAJTWFpbi5qYXZhAAFWAAJW"
97 "TAATW0xqYXZhL2xhbmcvU3RyaW5nOwAEbWFpbgABAAcOAAMBAAcOAAAAAgAAgYAE8AEBCYgCDAAA"
98 "AAAAAAABAAAAAAAAAAEAAAAIAAAAcAAAAAIAAAAEAAAAkAAAAAMAAAACAAAAoAAAAAUAAAADAAAA"
99 "uAAAAAYAAAABAAAA0AAAAAEgAAACAAAA8AAAAAEQAAABAAAAHAEAAAIgAAAIAAAAIgEAAAMgAAAC"
100 "AAAAcwEAAAAgAAABAAAAfgEAAAAQAAABAAAAjAEAAA==";
101
102static const char kRawDex39[] =
103 "ZGV4CjAzOQC4OovJlJ1089ikzK6asMf/f8qp3Kve5VsgAgAAcAAAAHhWNBIAAAAAAAAAAIwBAAAI"
104 "AAAAcAAAAAQAAACQAAAAAgAAAKAAAAAAAAAAAAAAAAMAAAC4AAAAAQAAANAAAAAwAQAA8AAAACIB"
105 "AAAqAQAAMgEAAEYBAABRAQAAVAEAAFgBAABtAQAAAQAAAAIAAAAEAAAABgAAAAQAAAACAAAAAAAA"
106 "AAUAAAACAAAAHAEAAAAAAAAAAAAAAAABAAcAAAABAAAAAAAAAAAAAAABAAAAAQAAAAAAAAADAAAA"
107 "AAAAAH4BAAAAAAAAAQABAAEAAABzAQAABAAAAHAQAgAAAA4AAQABAAAAAAB4AQAAAQAAAA4AAAAB"
108 "AAAAAwAGPGluaXQ+AAZMTWFpbjsAEkxqYXZhL2xhbmcvT2JqZWN0OwAJTWFpbi5qYXZhAAFWAAJW"
109 "TAATW0xqYXZhL2xhbmcvU3RyaW5nOwAEbWFpbgABAAcOAAMBAAcOAAAAAgAAgYAE8AEBCYgCDAAA"
110 "AAAAAAABAAAAAAAAAAEAAAAIAAAAcAAAAAIAAAAEAAAAkAAAAAMAAAACAAAAoAAAAAUAAAADAAAA"
111 "uAAAAAYAAAABAAAA0AAAAAEgAAACAAAA8AAAAAEQAAABAAAAHAEAAAIgAAAIAAAAIgEAAAMgAAAC"
112 "AAAAcwEAAAAgAAABAAAAfgEAAAAQAAABAAAAjAEAAA==";
113
Orion Hodson2e599942017-09-22 16:17:41 +0100114static const char kRawDex40[] =
115 "ZGV4CjA0MAC4OovJlJ1089ikzK6asMf/f8qp3Kve5VsgAgAAcAAAAHhWNBIAAAAAAAAAAIwBAAAI"
116 "AAAAcAAAAAQAAACQAAAAAgAAAKAAAAAAAAAAAAAAAAMAAAC4AAAAAQAAANAAAAAwAQAA8AAAACIB"
117 "AAAqAQAAMgEAAEYBAABRAQAAVAEAAFgBAABtAQAAAQAAAAIAAAAEAAAABgAAAAQAAAACAAAAAAAA"
118 "AAUAAAACAAAAHAEAAAAAAAAAAAAAAAABAAcAAAABAAAAAAAAAAAAAAABAAAAAQAAAAAAAAADAAAA"
119 "AAAAAH4BAAAAAAAAAQABAAEAAABzAQAABAAAAHAQAgAAAA4AAQABAAAAAAB4AQAAAQAAAA4AAAAB"
120 "AAAAAwAGPGluaXQ+AAZMTWFpbjsAEkxqYXZhL2xhbmcvT2JqZWN0OwAJTWFpbi5qYXZhAAFWAAJW"
121 "TAATW0xqYXZhL2xhbmcvU3RyaW5nOwAEbWFpbgABAAcOAAMBAAcOAAAAAgAAgYAE8AEBCYgCDAAA"
122 "AAAAAAABAAAAAAAAAAEAAAAIAAAAcAAAAAIAAAAEAAAAkAAAAAMAAAACAAAAoAAAAAUAAAADAAAA"
123 "uAAAAAYAAAABAAAA0AAAAAEgAAACAAAA8AAAAAEQAAABAAAAHAEAAAIgAAAIAAAAIgEAAAMgAAAC"
124 "AAAAcwEAAAAgAAABAAAAfgEAAAAQAAABAAAAjAEAAA==";
125
126static const char kRawDex41[] =
127 "ZGV4CjA0MQC4OovJlJ1089ikzK6asMf/f8qp3Kve5VsgAgAAcAAAAHhWNBIAAAAAAAAAAIwBAAAI"
128 "AAAAcAAAAAQAAACQAAAAAgAAAKAAAAAAAAAAAAAAAAMAAAC4AAAAAQAAANAAAAAwAQAA8AAAACIB"
129 "AAAqAQAAMgEAAEYBAABRAQAAVAEAAFgBAABtAQAAAQAAAAIAAAAEAAAABgAAAAQAAAACAAAAAAAA"
130 "AAUAAAACAAAAHAEAAAAAAAAAAAAAAAABAAcAAAABAAAAAAAAAAAAAAABAAAAAQAAAAAAAAADAAAA"
131 "AAAAAH4BAAAAAAAAAQABAAEAAABzAQAABAAAAHAQAgAAAA4AAQABAAAAAAB4AQAAAQAAAA4AAAAB"
132 "AAAAAwAGPGluaXQ+AAZMTWFpbjsAEkxqYXZhL2xhbmcvT2JqZWN0OwAJTWFpbi5qYXZhAAFWAAJW"
133 "TAATW0xqYXZhL2xhbmcvU3RyaW5nOwAEbWFpbgABAAcOAAMBAAcOAAAAAgAAgYAE8AEBCYgCDAAA"
134 "AAAAAAABAAAAAAAAAAEAAAAIAAAAcAAAAAIAAAAEAAAAkAAAAAMAAAACAAAAoAAAAAUAAAADAAAA"
135 "uAAAAAYAAAABAAAA0AAAAAEgAAACAAAA8AAAAAEQAAABAAAAHAEAAAIgAAAIAAAAIgEAAAMgAAAC"
136 "AAAAcwEAAAAgAAABAAAAfgEAAAAQAAABAAAAjAEAAA==";
137
ganxiaolincd16d0a2016-07-18 11:21:44 +0800138static const char kRawDexZeroLength[] =
139 "UEsDBAoAAAAAAOhxAkkAAAAAAAAAAAAAAAALABwAY2xhc3Nlcy5kZXhVVAkAA2QNoVdnDaFXdXgL"
140 "AAEE5AMBAASIEwAAUEsBAh4DCgAAAAAA6HECSQAAAAAAAAAAAAAAAAsAGAAAAAAAAAAAAKCBAAAA"
141 "AGNsYXNzZXMuZGV4VVQFAANkDaFXdXgLAAEE5AMBAASIEwAAUEsFBgAAAAABAAEAUQAAAEUAAAAA"
142 "AA==";
143
David Sehr9fddd362016-09-22 14:05:37 -0700144static const char kRawZipClassesDexPresent[] =
145 "UEsDBBQAAAAIANVRN0ms99lIMQEAACACAAALABwAY2xhc3Nlcy5kZXhVVAkAAwFj5VcUY+VXdXgL"
146 "AAEE5AMBAASIEwAAS0mt4DIwtmDYYdV9csrcks83lpxZN2vD8f/1p1beWX3vabQCEwNDAQMDQ0WY"
147 "iRADFPQwMjBwMEDEWYB4AhADlTEsYEAAZiDeAcRApQwXgNgAyPgApJWAtBYQGwGxGxAHAnEIEEcA"
148 "cS4jRD0T1Fw2KM0ENZMVypZhRLIIqIMdag9CBMFnhtJ1jDA5RrBcMSPE7AIBkIl8UFGgP6Fu4IOa"
149 "wczAZpOZl1lix8Dm45uYmWfNIOSTlViWqJ+TmJeu75+UlZpcYs3ACZLSA4kzMIYxMIX5MAhHIykL"
150 "LinKzEu3ZmDJBSoDOZiPgRlMgv3T2MDygZGRs4OJB8n9MBoWzrAwmQD1Eyy8WZHCmg0pvBkVIGpA"
151 "Yc4oABEHhRuTAsRMUDwwQ9WAwoJBAaIGHE5Q9aB4BgBQSwECHgMUAAAACADVUTdJrPfZSDEBAAAg"
152 "AgAACwAYAAAAAAAAAAAAoIEAAAAAY2xhc3Nlcy5kZXhVVAUAAwFj5Vd1eAsAAQTkAwEABIgTAABQ"
153 "SwUGAAAAAAEAAQBRAAAAdgEAAAAA";
154
155static const char kRawZipClassesDexAbsent[] =
156 "UEsDBBQAAAAIANVRN0ms99lIMQEAACACAAAOABwAbm90Y2xhc3Nlcy5kZXhVVAkAAwFj5VcUY+VX"
157 "dXgLAAEE5AMBAASIEwAAS0mt4DIwtmDYYdV9csrcks83lpxZN2vD8f/1p1beWX3vabQCEwNDAQMD"
158 "Q0WYiRADFPQwMjBwMEDEWYB4AhADlTEsYEAAZiDeAcRApQwXgNgAyPgApJWAtBYQGwGxGxAHAnEI"
159 "EEcAcS4jRD0T1Fw2KM0ENZMVypZhRLIIqIMdag9CBMFnhtJ1jDA5RrBcMSPE7AIBkIl8UFGgP6Fu"
160 "4IOawczAZpOZl1lix8Dm45uYmWfNIOSTlViWqJ+TmJeu75+UlZpcYs3ACZLSA4kzMIYxMIX5MAhH"
161 "IykLLinKzEu3ZmDJBSoDOZiPgRlMgv3T2MDygZGRs4OJB8n9MBoWzrAwmQD1Eyy8WZHCmg0pvBkV"
162 "IGpAYc4oABEHhRuTAsRMUDwwQ9WAwoJBAaIGHE5Q9aB4BgBQSwECHgMUAAAACADVUTdJrPfZSDEB"
163 "AAAgAgAADgAYAAAAAAAAAAAAoIEAAAAAbm90Y2xhc3Nlcy5kZXhVVAUAAwFj5Vd1eAsAAQTkAwEA"
164 "BIgTAABQSwUGAAAAAAEAAQBUAAAAeQEAAAAA";
165
166static const char kRawZipThreeDexFiles[] =
167 "UEsDBBQAAAAIAP1WN0ms99lIMQEAACACAAAMABwAY2xhc3NlczIuZGV4VVQJAAOtbOVXrWzlV3V4"
168 "CwABBOQDAQAEiBMAAEtJreAyMLZg2GHVfXLK3JLPN5acWTdrw/H/9adW3ll972m0AhMDQwEDA0NF"
169 "mIkQAxT0MDIwcDBAxFmAeAIQA5UxLGBAAGYg3gHEQKUMF4DYAMj4AKSVgLQWEBsBsRsQBwJxCBBH"
170 "AHEuI0Q9E9RcNijNBDWTFcqWYUSyCKiDHWoPQgTBZ4bSdYwwOUawXDEjxOwCAZCJfFBRoD+hbuCD"
171 "msHMwGaTmZdZYsfA5uObmJlnzSDkk5VYlqifk5iXru+flJWaXGLNwAmS0gOJMzCGMTCF+TAIRyMp"
172 "Cy4pysxLt2ZgyQUqAzmYj4EZTIL909jA8oGRkbODiQfJ/TAaFs6wMJkA9RMsvFmRwpoNKbwZFSBq"
173 "QGHOKAARB4UbkwLETFA8MEPVgMKCQQGiBhxOUPWgeAYAUEsDBBQAAAAIAABXN0ms99lIMQEAACAC"
174 "AAAMABwAY2xhc3NlczMuZGV4VVQJAAOvbOVXr2zlV3V4CwABBOQDAQAEiBMAAEtJreAyMLZg2GHV"
175 "fXLK3JLPN5acWTdrw/H/9adW3ll972m0AhMDQwEDA0NFmIkQAxT0MDIwcDBAxFmAeAIQA5UxLGBA"
176 "AGYg3gHEQKUMF4DYAMj4AKSVgLQWEBsBsRsQBwJxCBBHAHEuI0Q9E9RcNijNBDWTFcqWYUSyCKiD"
177 "HWoPQgTBZ4bSdYwwOUawXDEjxOwCAZCJfFBRoD+hbuCDmsHMwGaTmZdZYsfA5uObmJlnzSDkk5VY"
178 "lqifk5iXru+flJWaXGLNwAmS0gOJMzCGMTCF+TAIRyMpCy4pysxLt2ZgyQUqAzmYj4EZTIL909jA"
179 "8oGRkbODiQfJ/TAaFs6wMJkA9RMsvFmRwpoNKbwZFSBqQGHOKAARB4UbkwLETFA8MEPVgMKCQQGi"
180 "BhxOUPWgeAYAUEsDBBQAAAAIANVRN0ms99lIMQEAACACAAALABwAY2xhc3Nlcy5kZXhVVAkAAwFj"
181 "5VetbOVXdXgLAAEE5AMBAASIEwAAS0mt4DIwtmDYYdV9csrcks83lpxZN2vD8f/1p1beWX3vabQC"
182 "EwNDAQMDQ0WYiRADFPQwMjBwMEDEWYB4AhADlTEsYEAAZiDeAcRApQwXgNgAyPgApJWAtBYQGwGx"
183 "GxAHAnEIEEcAcS4jRD0T1Fw2KM0ENZMVypZhRLIIqIMdag9CBMFnhtJ1jDA5RrBcMSPE7AIBkIl8"
184 "UFGgP6Fu4IOawczAZpOZl1lix8Dm45uYmWfNIOSTlViWqJ+TmJeu75+UlZpcYs3ACZLSA4kzMIYx"
185 "MIX5MAhHIykLLinKzEu3ZmDJBSoDOZiPgRlMgv3T2MDygZGRs4OJB8n9MBoWzrAwmQD1Eyy8WZHC"
186 "mg0pvBkVIGpAYc4oABEHhRuTAsRMUDwwQ9WAwoJBAaIGHE5Q9aB4BgBQSwECHgMUAAAACAD9VjdJ"
187 "rPfZSDEBAAAgAgAADAAYAAAAAAAAAAAAoIEAAAAAY2xhc3NlczIuZGV4VVQFAAOtbOVXdXgLAAEE"
188 "5AMBAASIEwAAUEsBAh4DFAAAAAgAAFc3Saz32UgxAQAAIAIAAAwAGAAAAAAAAAAAAKCBdwEAAGNs"
189 "YXNzZXMzLmRleFVUBQADr2zlV3V4CwABBOQDAQAEiBMAAFBLAQIeAxQAAAAIANVRN0ms99lIMQEA"
190 "ACACAAALABgAAAAAAAAAAACgge4CAABjbGFzc2VzLmRleFVUBQADAWPlV3V4CwABBOQDAQAEiBMA"
191 "AFBLBQYAAAAAAwADAPUAAABkBAAAAAA=";
192
Jeff Haoa4cd6772017-04-13 14:36:29 -0700193static const char kRawDexBadMapOffset[] =
194 "ZGV4CjAzNQAZKGSz85r+tXJ1I24FYi+FpQtWbXtelAmoAQAAcAAAAHhWNBIAAAAAAAAAAEAwIBAF"
195 "AAAAcAAAAAMAAACEAAAAAQAAAJAAAAAAAAAAAAAAAAIAAACcAAAAAQAAAKwAAADcAAAAzAAAAOQA"
196 "AADsAAAA9AAAAPkAAAANAQAAAgAAAAMAAAAEAAAABAAAAAIAAAAAAAAAAAAAAAAAAAABAAAAAAAA"
197 "AAAAAAABAAAAAQAAAAAAAAABAAAAAAAAABUBAAAAAAAAAQABAAEAAAAQAQAABAAAAHAQAQAAAA4A"
198 "Bjxpbml0PgAGQS5qYXZhAANMQTsAEkxqYXZhL2xhbmcvT2JqZWN0OwABVgABAAcOAAAAAQAAgYAE"
199 "zAEACwAAAAAAAAABAAAAAAAAAAEAAAAFAAAAcAAAAAIAAAADAAAAhAAAAAMAAAABAAAAkAAAAAUA"
200 "AAACAAAAnAAAAAYAAAABAAAArAAAAAEgAAABAAAAzAAAAAIgAAAFAAAA5AAAAAMgAAABAAAAEAEA"
201 "AAAgAAABAAAAFQEAAAAQAAABAAAAIAEAAA==";
202
Jeff Haoc1225362017-05-01 17:29:35 -0700203static const char kRawDexDebugInfoLocalNullType[] =
204 "ZGV4CjAzNQA+Kwj2g6OZMH88OvK9Ey6ycdIsFCt18ED8AQAAcAAAAHhWNBIAAAAAAAAAAHQBAAAI"
205 "AAAAcAAAAAQAAACQAAAAAgAAAKAAAAAAAAAAAAAAAAMAAAC4AAAAAQAAANAAAAAMAQAA8AAAABwB"
206 "AAAkAQAALAEAAC8BAAA0AQAASAEAAEsBAABOAQAAAgAAAAMAAAAEAAAABQAAAAIAAAAAAAAAAAAA"
207 "AAUAAAADAAAAAAAAAAEAAQAAAAAAAQAAAAYAAAACAAEAAAAAAAEAAAABAAAAAgAAAAAAAAABAAAA"
208 "AAAAAGMBAAAAAAAAAQABAAEAAABUAQAABAAAAHAQAgAAAA4AAgABAAAAAABZAQAAAgAAABIQDwAG"
209 "PGluaXQ+AAZBLmphdmEAAUkAA0xBOwASTGphdmEvbGFuZy9PYmplY3Q7AAFWAAFhAAR0aGlzAAEA"
210 "Bw4AAwAHDh4DAAcAAAAAAQEAgYAE8AEBAIgCAAAACwAAAAAAAAABAAAAAAAAAAEAAAAIAAAAcAAA"
211 "AAIAAAAEAAAAkAAAAAMAAAACAAAAoAAAAAUAAAADAAAAuAAAAAYAAAABAAAA0AAAAAEgAAACAAAA"
212 "8AAAAAIgAAAIAAAAHAEAAAMgAAACAAAAVAEAAAAgAAABAAAAYwEAAAAQAAABAAAAdAEAAA==";
213
Narayan Kamath52e66502016-08-01 14:20:31 +0100214static void DecodeAndWriteDexFile(const char* base64, const char* location) {
Ian Rogers33e95662013-05-20 20:29:14 -0700215 // decode base64
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700216 CHECK(base64 != nullptr);
Alex Light9c20a142016-08-23 15:05:12 -0700217 std::vector<uint8_t> dex_bytes = DecodeBase64Vec(base64);
Orion Hodsona4c2a052016-08-17 10:51:42 +0100218 CHECK_NE(dex_bytes.size(), 0u);
Ian Rogers33e95662013-05-20 20:29:14 -0700219
220 // write to provided file
Ian Rogers700a4022014-05-19 16:49:03 -0700221 std::unique_ptr<File> file(OS::CreateEmptyFile(location));
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700222 CHECK(file.get() != nullptr);
Orion Hodsona4c2a052016-08-17 10:51:42 +0100223 if (!file->WriteFully(dex_bytes.data(), dex_bytes.size())) {
Ian Rogers33e95662013-05-20 20:29:14 -0700224 PLOG(FATAL) << "Failed to write base64 as dex file";
225 }
Andreas Gampe4303ba92014-11-06 01:00:46 -0800226 if (file->FlushCloseOrErase() != 0) {
227 PLOG(FATAL) << "Could not flush and close test file.";
228 }
Narayan Kamath52e66502016-08-01 14:20:31 +0100229}
230
David Sehr9fddd362016-09-22 14:05:37 -0700231static bool OpenDexFilesBase64(const char* base64,
232 const char* location,
233 std::vector<std::unique_ptr<const DexFile>>* dex_files,
234 std::string* error_msg) {
Narayan Kamath52e66502016-08-01 14:20:31 +0100235 DecodeAndWriteDexFile(base64, location);
Ian Rogers33e95662013-05-20 20:29:14 -0700236
David Sehr9fddd362016-09-22 14:05:37 -0700237 // read dex file(s)
Ian Rogers33e95662013-05-20 20:29:14 -0700238 ScopedObjectAccess soa(Thread::Current());
Aart Bik37d6a3b2016-06-21 18:30:10 -0700239 static constexpr bool kVerifyChecksum = true;
Richard Uhlerfbef44d2014-12-23 09:48:51 -0800240 std::vector<std::unique_ptr<const DexFile>> tmp;
David Sehr013fd802018-01-11 22:55:24 -0800241 const ArtDexFileLoader dex_file_loader;
242 bool success = dex_file_loader.Open(
Nicolas Geoffray095c6c92017-10-19 13:59:55 +0100243 location, location, /* verify */ true, kVerifyChecksum, error_msg, &tmp);
David Sehr9fddd362016-09-22 14:05:37 -0700244 if (success) {
245 for (std::unique_ptr<const DexFile>& dex_file : tmp) {
246 EXPECT_EQ(PROT_READ, dex_file->GetPermissions());
247 EXPECT_TRUE(dex_file->IsReadOnly());
248 }
249 *dex_files = std::move(tmp);
250 }
251 return success;
252}
253
254static std::unique_ptr<const DexFile> OpenDexFileBase64(const char* base64,
255 const char* location) {
256 // read dex files.
257 std::string error_msg;
258 std::vector<std::unique_ptr<const DexFile>> dex_files;
259 bool success = OpenDexFilesBase64(base64, location, &dex_files, &error_msg);
Andreas Gampe833a4852014-05-21 18:46:59 -0700260 CHECK(success) << error_msg;
David Sehr9fddd362016-09-22 14:05:37 -0700261 EXPECT_EQ(1U, dex_files.size());
262 return std::move(dex_files[0]);
Ian Rogers33e95662013-05-20 20:29:14 -0700263}
264
Orion Hodsona4c2a052016-08-17 10:51:42 +0100265static std::unique_ptr<const DexFile> OpenDexFileInMemoryBase64(const char* base64,
266 const char* location,
Jeff Haoa4cd6772017-04-13 14:36:29 -0700267 uint32_t location_checksum,
268 bool expect_success) {
Orion Hodsona4c2a052016-08-17 10:51:42 +0100269 CHECK(base64 != nullptr);
Alex Light9c20a142016-08-23 15:05:12 -0700270 std::vector<uint8_t> dex_bytes = DecodeBase64Vec(base64);
Orion Hodsona4c2a052016-08-17 10:51:42 +0100271 CHECK_NE(dex_bytes.size(), 0u);
272
273 std::string error_message;
274 std::unique_ptr<MemMap> region(MemMap::MapAnonymous("test-region",
275 nullptr,
276 dex_bytes.size(),
277 PROT_READ | PROT_WRITE,
278 /* low_4gb */ false,
279 /* reuse */ false,
280 &error_message));
281 memcpy(region->Begin(), dex_bytes.data(), dex_bytes.size());
David Sehr013fd802018-01-11 22:55:24 -0800282 const ArtDexFileLoader dex_file_loader;
283 std::unique_ptr<const DexFile> dex_file(dex_file_loader.Open(location,
284 location_checksum,
285 std::move(region),
286 /* verify */ true,
287 /* verify_checksum */ true,
288 &error_message));
Jeff Haoa4cd6772017-04-13 14:36:29 -0700289 if (expect_success) {
290 CHECK(dex_file != nullptr) << error_message;
291 } else {
292 CHECK(dex_file == nullptr) << "Expected dex file open to fail.";
293 }
Orion Hodsona4c2a052016-08-17 10:51:42 +0100294 return dex_file;
295}
296
Orion Hodsoncffc5292016-09-05 13:43:11 +0100297static void ValidateDexFileHeader(std::unique_ptr<const DexFile> dex_file) {
298 static const uint8_t kExpectedDexFileMagic[8] = {
299 /* d */ 0x64, /* e */ 0x64, /* x */ 0x78, /* \n */ 0x0d,
300 /* 0 */ 0x30, /* 3 */ 0x33, /* 5 */ 0x35, /* \0 */ 0x00
301 };
302 static const uint8_t kExpectedSha1[DexFile::kSha1DigestSize] = {
303 0x7b, 0xb8, 0x0c, 0xd4, 0x1f, 0xd6, 0x1e, 0xc5,
304 0x89, 0xe8, 0xbe, 0xe5, 0x18, 0x02, 0x12, 0x18,
305 0x2e, 0xf2, 0x8c, 0x3d,
306 };
Orion Hodsona4c2a052016-08-17 10:51:42 +0100307
Orion Hodsoncffc5292016-09-05 13:43:11 +0100308 const DexFile::Header& header = dex_file->GetHeader();
309 EXPECT_EQ(*kExpectedDexFileMagic, *header.magic_);
Orion Hodsona4c2a052016-08-17 10:51:42 +0100310 EXPECT_EQ(0x00d87910U, header.checksum_);
Orion Hodsoncffc5292016-09-05 13:43:11 +0100311 EXPECT_EQ(*kExpectedSha1, *header.signature_);
Orion Hodsona4c2a052016-08-17 10:51:42 +0100312 EXPECT_EQ(904U, header.file_size_);
313 EXPECT_EQ(112U, header.header_size_);
314 EXPECT_EQ(0U, header.link_size_);
315 EXPECT_EQ(0U, header.link_off_);
316 EXPECT_EQ(15U, header.string_ids_size_);
317 EXPECT_EQ(112U, header.string_ids_off_);
318 EXPECT_EQ(7U, header.type_ids_size_);
319 EXPECT_EQ(172U, header.type_ids_off_);
320 EXPECT_EQ(2U, header.proto_ids_size_);
321 EXPECT_EQ(200U, header.proto_ids_off_);
322 EXPECT_EQ(1U, header.field_ids_size_);
323 EXPECT_EQ(224U, header.field_ids_off_);
324 EXPECT_EQ(3U, header.method_ids_size_);
325 EXPECT_EQ(232U, header.method_ids_off_);
326 EXPECT_EQ(2U, header.class_defs_size_);
327 EXPECT_EQ(256U, header.class_defs_off_);
328 EXPECT_EQ(584U, header.data_size_);
329 EXPECT_EQ(320U, header.data_off_);
330
Orion Hodsoncffc5292016-09-05 13:43:11 +0100331 EXPECT_EQ(header.checksum_, dex_file->GetLocationChecksum());
332}
333
334TEST_F(DexFileTest, Header) {
335 ScratchFile tmp;
336 std::unique_ptr<const DexFile> raw(OpenDexFileBase64(kRawDex, tmp.GetFilename().c_str()));
337 ValidateDexFileHeader(std::move(raw));
Orion Hodsona4c2a052016-08-17 10:51:42 +0100338}
339
340TEST_F(DexFileTest, HeaderInMemory) {
341 ScratchFile tmp;
342 std::unique_ptr<const DexFile> raw =
Jeff Haoa4cd6772017-04-13 14:36:29 -0700343 OpenDexFileInMemoryBase64(kRawDex, tmp.GetFilename().c_str(), 0x00d87910U, true);
Orion Hodsoncffc5292016-09-05 13:43:11 +0100344 ValidateDexFileHeader(std::move(raw));
Brian Carlstrom5b332c82012-02-01 15:02:31 -0800345}
346
Narayan Kamath52e66502016-08-01 14:20:31 +0100347TEST_F(DexFileTest, Version38Accepted) {
348 ScratchFile tmp;
349 std::unique_ptr<const DexFile> raw(OpenDexFileBase64(kRawDex38, tmp.GetFilename().c_str()));
350 ASSERT_TRUE(raw.get() != nullptr);
351
352 const DexFile::Header& header = raw->GetHeader();
353 EXPECT_EQ(38u, header.GetVersion());
354}
355
Orion Hodson2e599942017-09-22 16:17:41 +0100356TEST_F(DexFileTest, Version39Accepted) {
357 ScratchFile tmp;
358 std::unique_ptr<const DexFile> raw(OpenDexFileBase64(kRawDex39, tmp.GetFilename().c_str()));
359 ASSERT_TRUE(raw.get() != nullptr);
360
361 const DexFile::Header& header = raw->GetHeader();
362 EXPECT_EQ(39u, header.GetVersion());
363}
364
365TEST_F(DexFileTest, Version40Rejected) {
Narayan Kamath52e66502016-08-01 14:20:31 +0100366 ScratchFile tmp;
367 const char* location = tmp.GetFilename().c_str();
Orion Hodson2e599942017-09-22 16:17:41 +0100368 DecodeAndWriteDexFile(kRawDex40, location);
369
370 ScopedObjectAccess soa(Thread::Current());
371 static constexpr bool kVerifyChecksum = true;
372 std::string error_msg;
373 std::vector<std::unique_ptr<const DexFile>> dex_files;
David Sehr013fd802018-01-11 22:55:24 -0800374 const ArtDexFileLoader dex_file_loader;
375 ASSERT_FALSE(dex_file_loader.Open(
Nicolas Geoffray095c6c92017-10-19 13:59:55 +0100376 location, location, /* verify */ true, kVerifyChecksum, &error_msg, &dex_files));
Orion Hodson2e599942017-09-22 16:17:41 +0100377}
378
379TEST_F(DexFileTest, Version41Rejected) {
380 ScratchFile tmp;
381 const char* location = tmp.GetFilename().c_str();
382 DecodeAndWriteDexFile(kRawDex41, location);
Narayan Kamath52e66502016-08-01 14:20:31 +0100383
384 ScopedObjectAccess soa(Thread::Current());
385 static constexpr bool kVerifyChecksum = true;
386 std::string error_msg;
387 std::vector<std::unique_ptr<const DexFile>> dex_files;
David Sehr013fd802018-01-11 22:55:24 -0800388 const ArtDexFileLoader dex_file_loader;
389 ASSERT_FALSE(dex_file_loader.Open(
Nicolas Geoffray095c6c92017-10-19 13:59:55 +0100390 location, location, /* verify */ true, kVerifyChecksum, &error_msg, &dex_files));
Narayan Kamath52e66502016-08-01 14:20:31 +0100391}
392
ganxiaolincd16d0a2016-07-18 11:21:44 +0800393TEST_F(DexFileTest, ZeroLengthDexRejected) {
394 ScratchFile tmp;
395 const char* location = tmp.GetFilename().c_str();
396 DecodeAndWriteDexFile(kRawDexZeroLength, location);
397
398 ScopedObjectAccess soa(Thread::Current());
399 static constexpr bool kVerifyChecksum = true;
400 std::string error_msg;
401 std::vector<std::unique_ptr<const DexFile>> dex_files;
David Sehr013fd802018-01-11 22:55:24 -0800402 const ArtDexFileLoader dex_file_loader;
403 ASSERT_FALSE(dex_file_loader.Open(
Nicolas Geoffray095c6c92017-10-19 13:59:55 +0100404 location, location, /* verify */ true, kVerifyChecksum, &error_msg, &dex_files));
ganxiaolincd16d0a2016-07-18 11:21:44 +0800405}
406
Brian Carlstrom5b332c82012-02-01 15:02:31 -0800407TEST_F(DexFileTest, GetLocationChecksum) {
Ian Rogers33e95662013-05-20 20:29:14 -0700408 ScopedObjectAccess soa(Thread::Current());
Richard Uhlerfbef44d2014-12-23 09:48:51 -0800409 std::unique_ptr<const DexFile> raw(OpenTestDexFile("Main"));
Brian Carlstrom5b332c82012-02-01 15:02:31 -0800410 EXPECT_NE(raw->GetHeader().checksum_, raw->GetLocationChecksum());
411}
412
413TEST_F(DexFileTest, GetChecksum) {
Richard Uhler84f50ae2017-02-06 15:12:45 +0000414 std::vector<uint32_t> checksums;
Ian Rogers33e95662013-05-20 20:29:14 -0700415 ScopedObjectAccess soa(Thread::Current());
Ian Rogers8d31bbd2013-10-13 10:44:14 -0700416 std::string error_msg;
David Sehr013fd802018-01-11 22:55:24 -0800417 const ArtDexFileLoader dex_file_loader;
418 EXPECT_TRUE(dex_file_loader.GetMultiDexChecksums(GetLibCoreDexFileNames()[0].c_str(),
419 &checksums,
420 &error_msg))
Ian Rogers8d31bbd2013-10-13 10:44:14 -0700421 << error_msg;
Richard Uhler84f50ae2017-02-06 15:12:45 +0000422 ASSERT_EQ(1U, checksums.size());
423 EXPECT_EQ(java_lang_dex_file_->GetLocationChecksum(), checksums[0]);
Brian Carlstrom7e49dca2011-07-22 18:07:34 -0700424}
425
Richard Uhler69bcf2c2017-01-24 10:25:21 +0000426TEST_F(DexFileTest, GetMultiDexChecksums) {
427 std::string error_msg;
428 std::vector<uint32_t> checksums;
429 std::string multidex_file = GetTestDexFileName("MultiDex");
David Sehr013fd802018-01-11 22:55:24 -0800430 const ArtDexFileLoader dex_file_loader;
431 EXPECT_TRUE(dex_file_loader.GetMultiDexChecksums(multidex_file.c_str(),
432 &checksums,
433 &error_msg)) << error_msg;
Richard Uhler69bcf2c2017-01-24 10:25:21 +0000434
Richard Uhler84f50ae2017-02-06 15:12:45 +0000435 std::vector<std::unique_ptr<const DexFile>> dexes = OpenTestDexFiles("MultiDex");
436 ASSERT_EQ(2U, dexes.size());
437 ASSERT_EQ(2U, checksums.size());
Richard Uhler69bcf2c2017-01-24 10:25:21 +0000438
Mathieu Chartier79c87da2017-10-10 11:54:29 -0700439 EXPECT_EQ(dexes[0]->GetLocation(), DexFileLoader::GetMultiDexLocation(0, multidex_file.c_str()));
Richard Uhler84f50ae2017-02-06 15:12:45 +0000440 EXPECT_EQ(dexes[0]->GetLocationChecksum(), checksums[0]);
Richard Uhler69bcf2c2017-01-24 10:25:21 +0000441
Mathieu Chartier79c87da2017-10-10 11:54:29 -0700442 EXPECT_EQ(dexes[1]->GetLocation(), DexFileLoader::GetMultiDexLocation(1, multidex_file.c_str()));
Richard Uhler84f50ae2017-02-06 15:12:45 +0000443 EXPECT_EQ(dexes[1]->GetLocationChecksum(), checksums[1]);
Richard Uhler69bcf2c2017-01-24 10:25:21 +0000444}
445
Brian Carlstrom9f30b382011-08-28 22:41:38 -0700446TEST_F(DexFileTest, ClassDefs) {
Ian Rogers33e95662013-05-20 20:29:14 -0700447 ScopedObjectAccess soa(Thread::Current());
Richard Uhlerfbef44d2014-12-23 09:48:51 -0800448 std::unique_ptr<const DexFile> raw(OpenTestDexFile("Nested"));
449 ASSERT_TRUE(raw.get() != nullptr);
Andreas Gampeae78c262017-02-01 20:40:44 -0800450 EXPECT_EQ(3U, raw->NumClassDefs());
Brian Carlstrom7e49dca2011-07-22 18:07:34 -0700451
Brian Carlstromf615a612011-07-23 12:50:34 -0700452 const DexFile::ClassDef& c0 = raw->GetClassDef(0);
Andreas Gampeae78c262017-02-01 20:40:44 -0800453 EXPECT_STREQ("LNested$1;", raw->GetClassDescriptor(c0));
Brian Carlstrom7e49dca2011-07-22 18:07:34 -0700454
Brian Carlstromf615a612011-07-23 12:50:34 -0700455 const DexFile::ClassDef& c1 = raw->GetClassDef(1);
Andreas Gampeae78c262017-02-01 20:40:44 -0800456 EXPECT_STREQ("LNested$Inner;", raw->GetClassDescriptor(c1));
457
458 const DexFile::ClassDef& c2 = raw->GetClassDef(2);
459 EXPECT_STREQ("LNested;", raw->GetClassDescriptor(c2));
Carl Shapiro1fb86202011-06-27 17:43:13 -0700460}
461
Ian Rogersd91d6d62013-09-25 20:26:14 -0700462TEST_F(DexFileTest, GetMethodSignature) {
Ian Rogers33e95662013-05-20 20:29:14 -0700463 ScopedObjectAccess soa(Thread::Current());
Richard Uhlerfbef44d2014-12-23 09:48:51 -0800464 std::unique_ptr<const DexFile> raw(OpenTestDexFile("GetMethodSignature"));
465 ASSERT_TRUE(raw.get() != nullptr);
Carl Shapiro419ec7b2011-08-03 14:48:33 -0700466 EXPECT_EQ(1U, raw->NumClassDefs());
467
468 const DexFile::ClassDef& class_def = raw->GetClassDef(0);
Ian Rogersd91d6d62013-09-25 20:26:14 -0700469 ASSERT_STREQ("LGetMethodSignature;", raw->GetClassDescriptor(class_def));
Carl Shapiro419ec7b2011-08-03 14:48:33 -0700470
Ian Rogers13735952014-10-08 12:43:28 -0700471 const uint8_t* class_data = raw->GetClassData(class_def);
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700472 ASSERT_TRUE(class_data != nullptr);
Elliott Hughes4d6850c2012-01-18 15:55:06 -0800473 ClassDataItemIterator it(*raw, class_data);
Carl Shapiro419ec7b2011-08-03 14:48:33 -0700474
Ian Rogers0571d352011-11-03 19:51:38 -0700475 EXPECT_EQ(1u, it.NumDirectMethods());
Carl Shapiro419ec7b2011-08-03 14:48:33 -0700476
Ian Rogers0571d352011-11-03 19:51:38 -0700477 // Check the signature for the static initializer.
Carl Shapiro419ec7b2011-08-03 14:48:33 -0700478 {
Ian Rogers0571d352011-11-03 19:51:38 -0700479 ASSERT_EQ(1U, it.NumDirectMethods());
480 const DexFile::MethodId& method_id = raw->GetMethodId(it.GetMemberIndex());
Ian Rogers0571d352011-11-03 19:51:38 -0700481 const char* name = raw->StringDataByIdx(method_id.name_idx_);
Carl Shapiro419ec7b2011-08-03 14:48:33 -0700482 ASSERT_STREQ("<init>", name);
Ian Rogersd91d6d62013-09-25 20:26:14 -0700483 std::string signature(raw->GetMethodSignature(method_id).ToString());
Ian Rogers0571d352011-11-03 19:51:38 -0700484 ASSERT_EQ("()V", signature);
Carl Shapiro419ec7b2011-08-03 14:48:33 -0700485 }
486
Vladimir Markob8a55f82017-09-21 16:21:43 +0100487 // Check all virtual methods.
488 struct Result {
489 const char* name;
490 const char* signature;
491 const char* pretty_method;
492 };
493 static const Result results[] = {
494 {
495 "m1",
496 "(IDJLjava/lang/Object;)Ljava/lang/Float;",
497 "java.lang.Float GetMethodSignature.m1(int, double, long, java.lang.Object)"
498 },
Igor Murashkin5573c372017-11-16 13:34:30 -0800499 {
Vladimir Markob8a55f82017-09-21 16:21:43 +0100500 "m2",
501 "(ZSC)LGetMethodSignature;",
502 "GetMethodSignature GetMethodSignature.m2(boolean, short, char)"
503 },
Igor Murashkin5573c372017-11-16 13:34:30 -0800504 {
Vladimir Markob8a55f82017-09-21 16:21:43 +0100505 "m3",
506 "()V",
507 "void GetMethodSignature.m3()"
508 },
Igor Murashkin5573c372017-11-16 13:34:30 -0800509 {
Vladimir Markob8a55f82017-09-21 16:21:43 +0100510 "m4",
511 "(I)V",
512 "void GetMethodSignature.m4(int)"
513 },
Igor Murashkin5573c372017-11-16 13:34:30 -0800514 {
Vladimir Markob8a55f82017-09-21 16:21:43 +0100515 "m5",
516 "(II)V",
517 "void GetMethodSignature.m5(int, int)"
518 },
Igor Murashkin5573c372017-11-16 13:34:30 -0800519 {
Vladimir Markob8a55f82017-09-21 16:21:43 +0100520 "m6",
521 "(II[[I)V",
522 "void GetMethodSignature.m6(int, int, int[][])"
523 },
Igor Murashkin5573c372017-11-16 13:34:30 -0800524 {
Vladimir Markob8a55f82017-09-21 16:21:43 +0100525 "m7",
526 "(II[[ILjava/lang/Object;)V",
527 "void GetMethodSignature.m7(int, int, int[][], java.lang.Object)"
528 },
Igor Murashkin5573c372017-11-16 13:34:30 -0800529 {
Vladimir Markob8a55f82017-09-21 16:21:43 +0100530 "m8",
531 "(II[[ILjava/lang/Object;[[Ljava/lang/Object;)V",
532 "void GetMethodSignature.m8(int, int, int[][], java.lang.Object, java.lang.Object[][])"
533 },
Igor Murashkin5573c372017-11-16 13:34:30 -0800534 {
Vladimir Markob8a55f82017-09-21 16:21:43 +0100535 "m9",
536 "()I",
537 "int GetMethodSignature.m9()"
538 },
Igor Murashkin5573c372017-11-16 13:34:30 -0800539 {
Vladimir Markob8a55f82017-09-21 16:21:43 +0100540 "mA",
541 "()[[I",
542 "int[][] GetMethodSignature.mA()"
543 },
Igor Murashkin5573c372017-11-16 13:34:30 -0800544 {
Vladimir Markob8a55f82017-09-21 16:21:43 +0100545 "mB",
546 "()[[Ljava/lang/Object;",
547 "java.lang.Object[][] GetMethodSignature.mB()"
548 },
549 };
550 ASSERT_EQ(arraysize(results), it.NumVirtualMethods());
551 for (const Result& r : results) {
Ian Rogers0571d352011-11-03 19:51:38 -0700552 it.Next();
553 const DexFile::MethodId& method_id = raw->GetMethodId(it.GetMemberIndex());
Carl Shapiro419ec7b2011-08-03 14:48:33 -0700554
Ian Rogers0571d352011-11-03 19:51:38 -0700555 const char* name = raw->StringDataByIdx(method_id.name_idx_);
Vladimir Markob8a55f82017-09-21 16:21:43 +0100556 ASSERT_STREQ(r.name, name);
Carl Shapiro419ec7b2011-08-03 14:48:33 -0700557
Ian Rogersd91d6d62013-09-25 20:26:14 -0700558 std::string signature(raw->GetMethodSignature(method_id).ToString());
Vladimir Markob8a55f82017-09-21 16:21:43 +0100559 ASSERT_EQ(r.signature, signature);
Carl Shapiro419ec7b2011-08-03 14:48:33 -0700560
Vladimir Markob8a55f82017-09-21 16:21:43 +0100561 std::string plain_method = std::string("GetMethodSignature.") + r.name;
562 ASSERT_EQ(plain_method, raw->PrettyMethod(it.GetMemberIndex(), /* with_signature */ false));
563 ASSERT_EQ(r.pretty_method, raw->PrettyMethod(it.GetMemberIndex(), /* with_signature */ true));
Ian Rogers0571d352011-11-03 19:51:38 -0700564 }
565}
566
567TEST_F(DexFileTest, FindStringId) {
Ian Rogers33e95662013-05-20 20:29:14 -0700568 ScopedObjectAccess soa(Thread::Current());
Richard Uhlerfbef44d2014-12-23 09:48:51 -0800569 std::unique_ptr<const DexFile> raw(OpenTestDexFile("GetMethodSignature"));
570 ASSERT_TRUE(raw.get() != nullptr);
Ian Rogers0571d352011-11-03 19:51:38 -0700571 EXPECT_EQ(1U, raw->NumClassDefs());
572
Ian Rogersd91d6d62013-09-25 20:26:14 -0700573 const char* strings[] = { "LGetMethodSignature;", "Ljava/lang/Float;", "Ljava/lang/Object;",
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700574 "D", "I", "J", nullptr };
575 for (size_t i = 0; strings[i] != nullptr; i++) {
Ian Rogers0571d352011-11-03 19:51:38 -0700576 const char* str = strings[i];
577 const DexFile::StringId* str_id = raw->FindStringId(str);
578 const char* dex_str = raw->GetStringData(*str_id);
579 EXPECT_STREQ(dex_str, str);
580 }
581}
582
583TEST_F(DexFileTest, FindTypeId) {
584 for (size_t i = 0; i < java_lang_dex_file_->NumTypeIds(); i++) {
Andreas Gampea5b09a62016-11-17 15:21:22 -0800585 const char* type_str = java_lang_dex_file_->StringByTypeIdx(dex::TypeIndex(i));
Ian Rogers0571d352011-11-03 19:51:38 -0700586 const DexFile::StringId* type_str_id = java_lang_dex_file_->FindStringId(type_str);
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700587 ASSERT_TRUE(type_str_id != nullptr);
Andreas Gampe8a0128a2016-11-28 07:38:35 -0800588 dex::StringIndex type_str_idx = java_lang_dex_file_->GetIndexForStringId(*type_str_id);
Ian Rogers0571d352011-11-03 19:51:38 -0700589 const DexFile::TypeId* type_id = java_lang_dex_file_->FindTypeId(type_str_idx);
Mathieu Chartier9507fa22015-10-29 15:08:57 -0700590 ASSERT_EQ(type_id, java_lang_dex_file_->FindTypeId(type_str));
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700591 ASSERT_TRUE(type_id != nullptr);
Andreas Gampea5b09a62016-11-17 15:21:22 -0800592 EXPECT_EQ(java_lang_dex_file_->GetIndexForTypeId(*type_id).index_, i);
Ian Rogers0571d352011-11-03 19:51:38 -0700593 }
594}
595
596TEST_F(DexFileTest, FindProtoId) {
597 for (size_t i = 0; i < java_lang_dex_file_->NumProtoIds(); i++) {
598 const DexFile::ProtoId& to_find = java_lang_dex_file_->GetProtoId(i);
599 const DexFile::TypeList* to_find_tl = java_lang_dex_file_->GetProtoParameters(to_find);
Andreas Gampea5b09a62016-11-17 15:21:22 -0800600 std::vector<dex::TypeIndex> to_find_types;
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700601 if (to_find_tl != nullptr) {
Ian Rogers0571d352011-11-03 19:51:38 -0700602 for (size_t j = 0; j < to_find_tl->Size(); j++) {
603 to_find_types.push_back(to_find_tl->GetTypeItem(j).type_idx_);
604 }
605 }
606 const DexFile::ProtoId* found =
607 java_lang_dex_file_->FindProtoId(to_find.return_type_idx_, to_find_types);
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700608 ASSERT_TRUE(found != nullptr);
Ian Rogers0571d352011-11-03 19:51:38 -0700609 EXPECT_EQ(java_lang_dex_file_->GetIndexForProtoId(*found), i);
610 }
611}
612
613TEST_F(DexFileTest, FindMethodId) {
614 for (size_t i = 0; i < java_lang_dex_file_->NumMethodIds(); i++) {
615 const DexFile::MethodId& to_find = java_lang_dex_file_->GetMethodId(i);
616 const DexFile::TypeId& klass = java_lang_dex_file_->GetTypeId(to_find.class_idx_);
617 const DexFile::StringId& name = java_lang_dex_file_->GetStringId(to_find.name_idx_);
618 const DexFile::ProtoId& signature = java_lang_dex_file_->GetProtoId(to_find.proto_idx_);
619 const DexFile::MethodId* found = java_lang_dex_file_->FindMethodId(klass, name, signature);
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700620 ASSERT_TRUE(found != nullptr) << "Didn't find method " << i << ": "
Ian Rogers0571d352011-11-03 19:51:38 -0700621 << java_lang_dex_file_->StringByTypeIdx(to_find.class_idx_) << "."
622 << java_lang_dex_file_->GetStringData(name)
Ian Rogersd91d6d62013-09-25 20:26:14 -0700623 << java_lang_dex_file_->GetMethodSignature(to_find);
Ian Rogers0571d352011-11-03 19:51:38 -0700624 EXPECT_EQ(java_lang_dex_file_->GetIndexForMethodId(*found), i);
Carl Shapiro419ec7b2011-08-03 14:48:33 -0700625 }
Carl Shapiro419ec7b2011-08-03 14:48:33 -0700626}
627
Ian Rogers9b1a4f42011-11-14 18:35:10 -0800628TEST_F(DexFileTest, FindFieldId) {
629 for (size_t i = 0; i < java_lang_dex_file_->NumFieldIds(); i++) {
630 const DexFile::FieldId& to_find = java_lang_dex_file_->GetFieldId(i);
631 const DexFile::TypeId& klass = java_lang_dex_file_->GetTypeId(to_find.class_idx_);
632 const DexFile::StringId& name = java_lang_dex_file_->GetStringId(to_find.name_idx_);
633 const DexFile::TypeId& type = java_lang_dex_file_->GetTypeId(to_find.type_idx_);
634 const DexFile::FieldId* found = java_lang_dex_file_->FindFieldId(klass, name, type);
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700635 ASSERT_TRUE(found != nullptr) << "Didn't find field " << i << ": "
Ian Rogers9b1a4f42011-11-14 18:35:10 -0800636 << java_lang_dex_file_->StringByTypeIdx(to_find.type_idx_) << " "
637 << java_lang_dex_file_->StringByTypeIdx(to_find.class_idx_) << "."
638 << java_lang_dex_file_->GetStringData(name);
639 EXPECT_EQ(java_lang_dex_file_->GetIndexForFieldId(*found), i);
640 }
641}
642
Calin Juravle4e1d5792014-07-15 23:56:47 +0100643TEST_F(DexFileTest, GetMultiDexClassesDexName) {
Mathieu Chartier79c87da2017-10-10 11:54:29 -0700644 ASSERT_EQ("classes.dex", DexFileLoader::GetMultiDexClassesDexName(0));
645 ASSERT_EQ("classes2.dex", DexFileLoader::GetMultiDexClassesDexName(1));
646 ASSERT_EQ("classes3.dex", DexFileLoader::GetMultiDexClassesDexName(2));
647 ASSERT_EQ("classes100.dex", DexFileLoader::GetMultiDexClassesDexName(99));
Andreas Gampe90e34042015-04-27 20:01:52 -0700648}
649
650TEST_F(DexFileTest, GetMultiDexLocation) {
Calin Juravle4e1d5792014-07-15 23:56:47 +0100651 std::string dex_location_str = "/system/app/framework.jar";
652 const char* dex_location = dex_location_str.c_str();
Mathieu Chartier79c87da2017-10-10 11:54:29 -0700653 ASSERT_EQ("/system/app/framework.jar", DexFileLoader::GetMultiDexLocation(0, dex_location));
Calin Juravlea308a322017-07-18 16:51:51 -0700654 ASSERT_EQ("/system/app/framework.jar!classes2.dex",
Mathieu Chartier79c87da2017-10-10 11:54:29 -0700655 DexFileLoader::GetMultiDexLocation(1, dex_location));
Calin Juravlea308a322017-07-18 16:51:51 -0700656 ASSERT_EQ("/system/app/framework.jar!classes101.dex",
Mathieu Chartier79c87da2017-10-10 11:54:29 -0700657 DexFileLoader::GetMultiDexLocation(100, dex_location));
Calin Juravle4e1d5792014-07-15 23:56:47 +0100658}
659
660TEST_F(DexFileTest, GetDexCanonicalLocation) {
661 ScratchFile file;
Vladimir Markoaa4497d2014-09-05 14:01:17 +0100662 UniqueCPtr<const char[]> dex_location_real(realpath(file.GetFilename().c_str(), nullptr));
663 std::string dex_location(dex_location_real.get());
Calin Juravle4e1d5792014-07-15 23:56:47 +0100664
Mathieu Chartier79c87da2017-10-10 11:54:29 -0700665 ASSERT_EQ(dex_location, DexFileLoader::GetDexCanonicalLocation(dex_location.c_str()));
666 std::string multidex_location = DexFileLoader::GetMultiDexLocation(1, dex_location.c_str());
667 ASSERT_EQ(multidex_location, DexFileLoader::GetDexCanonicalLocation(multidex_location.c_str()));
Calin Juravle4e1d5792014-07-15 23:56:47 +0100668
669 std::string dex_location_sym = dex_location + "symlink";
670 ASSERT_EQ(0, symlink(dex_location.c_str(), dex_location_sym.c_str()));
671
Mathieu Chartier79c87da2017-10-10 11:54:29 -0700672 ASSERT_EQ(dex_location, DexFileLoader::GetDexCanonicalLocation(dex_location_sym.c_str()));
Calin Juravle4e1d5792014-07-15 23:56:47 +0100673
Mathieu Chartier79c87da2017-10-10 11:54:29 -0700674 std::string multidex_location_sym = DexFileLoader::GetMultiDexLocation(
675 1, dex_location_sym.c_str());
676 ASSERT_EQ(multidex_location,
677 DexFileLoader::GetDexCanonicalLocation(multidex_location_sym.c_str()));
Calin Juravle4e1d5792014-07-15 23:56:47 +0100678
679 ASSERT_EQ(0, unlink(dex_location_sym.c_str()));
680}
681
Richard Uhlere5fed032015-03-18 08:21:11 -0700682TEST(DexFileUtilsTest, GetBaseLocationAndMultiDexSuffix) {
Mathieu Chartier79c87da2017-10-10 11:54:29 -0700683 EXPECT_EQ("/foo/bar/baz.jar", DexFileLoader::GetBaseLocation("/foo/bar/baz.jar"));
684 EXPECT_EQ("/foo/bar/baz.jar", DexFileLoader::GetBaseLocation("/foo/bar/baz.jar!classes2.dex"));
685 EXPECT_EQ("/foo/bar/baz.jar", DexFileLoader::GetBaseLocation("/foo/bar/baz.jar!classes8.dex"));
686 EXPECT_EQ("", DexFileLoader::GetMultiDexSuffix("/foo/bar/baz.jar"));
687 EXPECT_EQ("!classes2.dex", DexFileLoader::GetMultiDexSuffix("/foo/bar/baz.jar!classes2.dex"));
688 EXPECT_EQ("!classes8.dex", DexFileLoader::GetMultiDexSuffix("/foo/bar/baz.jar!classes8.dex"));
Richard Uhlere5fed032015-03-18 08:21:11 -0700689}
690
David Sehr9fddd362016-09-22 14:05:37 -0700691TEST_F(DexFileTest, ZipOpenClassesPresent) {
692 ScratchFile tmp;
693 std::vector<std::unique_ptr<const DexFile>> dex_files;
694 std::string error_msg;
695 ASSERT_TRUE(OpenDexFilesBase64(kRawZipClassesDexPresent, tmp.GetFilename().c_str(), &dex_files,
696 &error_msg));
697 EXPECT_EQ(dex_files.size(), 1u);
698}
699
700TEST_F(DexFileTest, ZipOpenClassesAbsent) {
701 ScratchFile tmp;
702 std::vector<std::unique_ptr<const DexFile>> dex_files;
703 std::string error_msg;
704 ASSERT_FALSE(OpenDexFilesBase64(kRawZipClassesDexAbsent, tmp.GetFilename().c_str(), &dex_files,
705 &error_msg));
706 EXPECT_EQ(dex_files.size(), 0u);
707}
708
709TEST_F(DexFileTest, ZipOpenThreeDexFiles) {
710 ScratchFile tmp;
711 std::vector<std::unique_ptr<const DexFile>> dex_files;
712 std::string error_msg;
713 ASSERT_TRUE(OpenDexFilesBase64(kRawZipThreeDexFiles, tmp.GetFilename().c_str(), &dex_files,
714 &error_msg));
715 EXPECT_EQ(dex_files.size(), 3u);
716}
717
Jeff Haoa4cd6772017-04-13 14:36:29 -0700718TEST_F(DexFileTest, OpenDexBadMapOffset) {
719 ScratchFile tmp;
720 std::unique_ptr<const DexFile> raw =
721 OpenDexFileInMemoryBase64(kRawDexBadMapOffset, tmp.GetFilename().c_str(), 0xb3642819U, false);
722 EXPECT_EQ(raw, nullptr);
723}
724
Jeff Hao120504f2017-04-14 14:33:52 -0700725TEST_F(DexFileTest, GetStringWithNoIndex) {
726 ScratchFile tmp;
727 std::unique_ptr<const DexFile> raw(OpenDexFileBase64(kRawDex, tmp.GetFilename().c_str()));
728 dex::TypeIndex idx;
729 EXPECT_EQ(raw->StringByTypeIdx(idx), nullptr);
730}
731
Jeff Haoc1225362017-05-01 17:29:35 -0700732static void Callback(void* context ATTRIBUTE_UNUSED,
733 const DexFile::LocalInfo& entry ATTRIBUTE_UNUSED) {
734}
735
736TEST_F(DexFileTest, OpenDexDebugInfoLocalNullType) {
737 ScratchFile tmp;
738 std::unique_ptr<const DexFile> raw = OpenDexFileInMemoryBase64(
739 kRawDexDebugInfoLocalNullType, tmp.GetFilename().c_str(), 0xf25f2b38U, true);
740 const DexFile::ClassDef& class_def = raw->GetClassDef(0);
Mathieu Chartier8892c6b2018-01-09 15:10:17 -0800741 constexpr uint32_t kMethodIdx = 1;
742 const DexFile::CodeItem* code_item = raw->GetCodeItem(raw->FindCodeItemOffset(class_def,
743 kMethodIdx));
744 CodeItemDebugInfoAccessor accessor(*raw, code_item, kMethodIdx);
Mathieu Chartier808c7a52017-12-15 11:19:33 -0800745 ASSERT_TRUE(accessor.DecodeDebugLocalInfo(true, 1, Callback, nullptr));
Jeff Haoc1225362017-05-01 17:29:35 -0700746}
747
Carl Shapiro1fb86202011-06-27 17:43:13 -0700748} // namespace art