blob: 3ee115c01b00ae729720eeb7bdedc501a90fbfc3 [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
Ian Rogerse63db272014-07-15 15:36:11 -070023#include "base/stl_util.h"
24#include "base/unix_file/fd_file.h"
Mathieu Chartier808c7a52017-12-15 11:19:33 -080025#include "code_item_accessors-inl.h"
Brian Carlstroma1ce1fe2014-02-24 23:23:58 -080026#include "common_runtime_test.h"
Elliott Hughes956af0f2014-12-11 14:34:28 -080027#include "dex_file-inl.h"
Mathieu Chartier79c87da2017-10-10 11:54:29 -070028#include "dex_file_loader.h"
Orion Hodsona4c2a052016-08-17 10:51:42 +010029#include "mem_map.h"
Ian Rogerse63db272014-07-15 15:36:11 -070030#include "os.h"
Mathieu Chartier0795f232016-09-27 18:43:30 -070031#include "scoped_thread_state_change-inl.h"
Andreas Gampeb486a982017-06-01 13:45:54 -070032#include "thread-current-inl.h"
Alex Light9c20a142016-08-23 15:05:12 -070033#include "utils.h"
Elliott Hughes90a33692011-08-30 13:27:07 -070034
Carl Shapiro1fb86202011-06-27 17:43:13 -070035namespace art {
36
Brian Carlstroma1ce1fe2014-02-24 23:23:58 -080037class DexFileTest : public CommonRuntimeTest {};
Brian Carlstrom9f30b382011-08-28 22:41:38 -070038
39TEST_F(DexFileTest, Open) {
Ian Rogers33e95662013-05-20 20:29:14 -070040 ScopedObjectAccess soa(Thread::Current());
Richard Uhlerfbef44d2014-12-23 09:48:51 -080041 std::unique_ptr<const DexFile> dex(OpenTestDexFile("Nested"));
Mathieu Chartier2cebb242015-04-21 16:50:40 -070042 ASSERT_TRUE(dex.get() != nullptr);
Brian Carlstrom7e49dca2011-07-22 18:07:34 -070043}
Brian Carlstrom578bbdc2011-07-21 14:07:47 -070044
Alex Light9c20a142016-08-23 15:05:12 -070045static inline std::vector<uint8_t> DecodeBase64Vec(const char* src) {
46 std::vector<uint8_t> res;
47 size_t size;
48 std::unique_ptr<uint8_t[]> data(DecodeBase64(src, &size));
49 res.resize(size);
50 memcpy(res.data(), data.get(), size);
51 return res;
Brian Carlstroma1ce1fe2014-02-24 23:23:58 -080052}
53
Brian Carlstrom9f30b382011-08-28 22:41:38 -070054// Although this is the same content logically as the Nested test dex,
55// the DexFileHeader test is sensitive to subtle changes in the
56// contents due to the checksum etc, so we embed the exact input here.
57//
58// class Nested {
59// class Inner {
60// }
61// }
62static const char kRawDex[] =
63 "ZGV4CjAzNQAQedgAe7gM1B/WHsWJ6L7lGAISGC7yjD2IAwAAcAAAAHhWNBIAAAAAAAAAAMQCAAAP"
64 "AAAAcAAAAAcAAACsAAAAAgAAAMgAAAABAAAA4AAAAAMAAADoAAAAAgAAAAABAABIAgAAQAEAAK4B"
65 "AAC2AQAAvQEAAM0BAADXAQAA+wEAABsCAAA+AgAAUgIAAF8CAABiAgAAZgIAAHMCAAB5AgAAgQIA"
66 "AAIAAAADAAAABAAAAAUAAAAGAAAABwAAAAkAAAAJAAAABgAAAAAAAAAKAAAABgAAAKgBAAAAAAEA"
67 "DQAAAAAAAQAAAAAAAQAAAAAAAAAFAAAAAAAAAAAAAAAAAAAABQAAAAAAAAAIAAAAiAEAAKsCAAAA"
68 "AAAAAQAAAAAAAAAFAAAAAAAAAAgAAACYAQAAuAIAAAAAAAACAAAAlAIAAJoCAAABAAAAowIAAAIA"
69 "AgABAAAAiAIAAAYAAABbAQAAcBACAAAADgABAAEAAQAAAI4CAAAEAAAAcBACAAAADgBAAQAAAAAA"
70 "AAAAAAAAAAAATAEAAAAAAAAAAAAAAAAAAAEAAAABAAY8aW5pdD4ABUlubmVyAA5MTmVzdGVkJElu"
71 "bmVyOwAITE5lc3RlZDsAIkxkYWx2aWsvYW5ub3RhdGlvbi9FbmNsb3NpbmdDbGFzczsAHkxkYWx2"
72 "aWsvYW5ub3RhdGlvbi9Jbm5lckNsYXNzOwAhTGRhbHZpay9hbm5vdGF0aW9uL01lbWJlckNsYXNz"
73 "ZXM7ABJMamF2YS9sYW5nL09iamVjdDsAC05lc3RlZC5qYXZhAAFWAAJWTAALYWNjZXNzRmxhZ3MA"
74 "BG5hbWUABnRoaXMkMAAFdmFsdWUAAgEABw4AAQAHDjwAAgIBDhgBAgMCCwQADBcBAgQBDhwBGAAA"
75 "AQEAAJAgAICABNQCAAABAAGAgATwAgAAEAAAAAAAAAABAAAAAAAAAAEAAAAPAAAAcAAAAAIAAAAH"
76 "AAAArAAAAAMAAAACAAAAyAAAAAQAAAABAAAA4AAAAAUAAAADAAAA6AAAAAYAAAACAAAAAAEAAAMQ"
77 "AAACAAAAQAEAAAEgAAACAAAAVAEAAAYgAAACAAAAiAEAAAEQAAABAAAAqAEAAAIgAAAPAAAArgEA"
78 "AAMgAAACAAAAiAIAAAQgAAADAAAAlAIAAAAgAAACAAAAqwIAAAAQAAABAAAAxAIAAA==";
79
Orion Hodson2e599942017-09-22 16:17:41 +010080// kRawDex{38,39,40,41} are dex'ed versions of the following Java source :
Narayan Kamath52e66502016-08-01 14:20:31 +010081//
82// public class Main {
83// public static void main(String[] foo) {
84// }
85// }
86//
87// The dex file was manually edited to change its dex version code to 38
88// or 39, respectively.
89static const char kRawDex38[] =
90 "ZGV4CjAzOAC4OovJlJ1089ikzK6asMf/f8qp3Kve5VsgAgAAcAAAAHhWNBIAAAAAAAAAAIwBAAAI"
91 "AAAAcAAAAAQAAACQAAAAAgAAAKAAAAAAAAAAAAAAAAMAAAC4AAAAAQAAANAAAAAwAQAA8AAAACIB"
92 "AAAqAQAAMgEAAEYBAABRAQAAVAEAAFgBAABtAQAAAQAAAAIAAAAEAAAABgAAAAQAAAACAAAAAAAA"
93 "AAUAAAACAAAAHAEAAAAAAAAAAAAAAAABAAcAAAABAAAAAAAAAAAAAAABAAAAAQAAAAAAAAADAAAA"
94 "AAAAAH4BAAAAAAAAAQABAAEAAABzAQAABAAAAHAQAgAAAA4AAQABAAAAAAB4AQAAAQAAAA4AAAAB"
95 "AAAAAwAGPGluaXQ+AAZMTWFpbjsAEkxqYXZhL2xhbmcvT2JqZWN0OwAJTWFpbi5qYXZhAAFWAAJW"
96 "TAATW0xqYXZhL2xhbmcvU3RyaW5nOwAEbWFpbgABAAcOAAMBAAcOAAAAAgAAgYAE8AEBCYgCDAAA"
97 "AAAAAAABAAAAAAAAAAEAAAAIAAAAcAAAAAIAAAAEAAAAkAAAAAMAAAACAAAAoAAAAAUAAAADAAAA"
98 "uAAAAAYAAAABAAAA0AAAAAEgAAACAAAA8AAAAAEQAAABAAAAHAEAAAIgAAAIAAAAIgEAAAMgAAAC"
99 "AAAAcwEAAAAgAAABAAAAfgEAAAAQAAABAAAAjAEAAA==";
100
101static const char kRawDex39[] =
102 "ZGV4CjAzOQC4OovJlJ1089ikzK6asMf/f8qp3Kve5VsgAgAAcAAAAHhWNBIAAAAAAAAAAIwBAAAI"
103 "AAAAcAAAAAQAAACQAAAAAgAAAKAAAAAAAAAAAAAAAAMAAAC4AAAAAQAAANAAAAAwAQAA8AAAACIB"
104 "AAAqAQAAMgEAAEYBAABRAQAAVAEAAFgBAABtAQAAAQAAAAIAAAAEAAAABgAAAAQAAAACAAAAAAAA"
105 "AAUAAAACAAAAHAEAAAAAAAAAAAAAAAABAAcAAAABAAAAAAAAAAAAAAABAAAAAQAAAAAAAAADAAAA"
106 "AAAAAH4BAAAAAAAAAQABAAEAAABzAQAABAAAAHAQAgAAAA4AAQABAAAAAAB4AQAAAQAAAA4AAAAB"
107 "AAAAAwAGPGluaXQ+AAZMTWFpbjsAEkxqYXZhL2xhbmcvT2JqZWN0OwAJTWFpbi5qYXZhAAFWAAJW"
108 "TAATW0xqYXZhL2xhbmcvU3RyaW5nOwAEbWFpbgABAAcOAAMBAAcOAAAAAgAAgYAE8AEBCYgCDAAA"
109 "AAAAAAABAAAAAAAAAAEAAAAIAAAAcAAAAAIAAAAEAAAAkAAAAAMAAAACAAAAoAAAAAUAAAADAAAA"
110 "uAAAAAYAAAABAAAA0AAAAAEgAAACAAAA8AAAAAEQAAABAAAAHAEAAAIgAAAIAAAAIgEAAAMgAAAC"
111 "AAAAcwEAAAAgAAABAAAAfgEAAAAQAAABAAAAjAEAAA==";
112
Orion Hodson2e599942017-09-22 16:17:41 +0100113static const char kRawDex40[] =
114 "ZGV4CjA0MAC4OovJlJ1089ikzK6asMf/f8qp3Kve5VsgAgAAcAAAAHhWNBIAAAAAAAAAAIwBAAAI"
115 "AAAAcAAAAAQAAACQAAAAAgAAAKAAAAAAAAAAAAAAAAMAAAC4AAAAAQAAANAAAAAwAQAA8AAAACIB"
116 "AAAqAQAAMgEAAEYBAABRAQAAVAEAAFgBAABtAQAAAQAAAAIAAAAEAAAABgAAAAQAAAACAAAAAAAA"
117 "AAUAAAACAAAAHAEAAAAAAAAAAAAAAAABAAcAAAABAAAAAAAAAAAAAAABAAAAAQAAAAAAAAADAAAA"
118 "AAAAAH4BAAAAAAAAAQABAAEAAABzAQAABAAAAHAQAgAAAA4AAQABAAAAAAB4AQAAAQAAAA4AAAAB"
119 "AAAAAwAGPGluaXQ+AAZMTWFpbjsAEkxqYXZhL2xhbmcvT2JqZWN0OwAJTWFpbi5qYXZhAAFWAAJW"
120 "TAATW0xqYXZhL2xhbmcvU3RyaW5nOwAEbWFpbgABAAcOAAMBAAcOAAAAAgAAgYAE8AEBCYgCDAAA"
121 "AAAAAAABAAAAAAAAAAEAAAAIAAAAcAAAAAIAAAAEAAAAkAAAAAMAAAACAAAAoAAAAAUAAAADAAAA"
122 "uAAAAAYAAAABAAAA0AAAAAEgAAACAAAA8AAAAAEQAAABAAAAHAEAAAIgAAAIAAAAIgEAAAMgAAAC"
123 "AAAAcwEAAAAgAAABAAAAfgEAAAAQAAABAAAAjAEAAA==";
124
125static const char kRawDex41[] =
126 "ZGV4CjA0MQC4OovJlJ1089ikzK6asMf/f8qp3Kve5VsgAgAAcAAAAHhWNBIAAAAAAAAAAIwBAAAI"
127 "AAAAcAAAAAQAAACQAAAAAgAAAKAAAAAAAAAAAAAAAAMAAAC4AAAAAQAAANAAAAAwAQAA8AAAACIB"
128 "AAAqAQAAMgEAAEYBAABRAQAAVAEAAFgBAABtAQAAAQAAAAIAAAAEAAAABgAAAAQAAAACAAAAAAAA"
129 "AAUAAAACAAAAHAEAAAAAAAAAAAAAAAABAAcAAAABAAAAAAAAAAAAAAABAAAAAQAAAAAAAAADAAAA"
130 "AAAAAH4BAAAAAAAAAQABAAEAAABzAQAABAAAAHAQAgAAAA4AAQABAAAAAAB4AQAAAQAAAA4AAAAB"
131 "AAAAAwAGPGluaXQ+AAZMTWFpbjsAEkxqYXZhL2xhbmcvT2JqZWN0OwAJTWFpbi5qYXZhAAFWAAJW"
132 "TAATW0xqYXZhL2xhbmcvU3RyaW5nOwAEbWFpbgABAAcOAAMBAAcOAAAAAgAAgYAE8AEBCYgCDAAA"
133 "AAAAAAABAAAAAAAAAAEAAAAIAAAAcAAAAAIAAAAEAAAAkAAAAAMAAAACAAAAoAAAAAUAAAADAAAA"
134 "uAAAAAYAAAABAAAA0AAAAAEgAAACAAAA8AAAAAEQAAABAAAAHAEAAAIgAAAIAAAAIgEAAAMgAAAC"
135 "AAAAcwEAAAAgAAABAAAAfgEAAAAQAAABAAAAjAEAAA==";
136
ganxiaolincd16d0a2016-07-18 11:21:44 +0800137static const char kRawDexZeroLength[] =
138 "UEsDBAoAAAAAAOhxAkkAAAAAAAAAAAAAAAALABwAY2xhc3Nlcy5kZXhVVAkAA2QNoVdnDaFXdXgL"
139 "AAEE5AMBAASIEwAAUEsBAh4DCgAAAAAA6HECSQAAAAAAAAAAAAAAAAsAGAAAAAAAAAAAAKCBAAAA"
140 "AGNsYXNzZXMuZGV4VVQFAANkDaFXdXgLAAEE5AMBAASIEwAAUEsFBgAAAAABAAEAUQAAAEUAAAAA"
141 "AA==";
142
David Sehr9fddd362016-09-22 14:05:37 -0700143static const char kRawZipClassesDexPresent[] =
144 "UEsDBBQAAAAIANVRN0ms99lIMQEAACACAAALABwAY2xhc3Nlcy5kZXhVVAkAAwFj5VcUY+VXdXgL"
145 "AAEE5AMBAASIEwAAS0mt4DIwtmDYYdV9csrcks83lpxZN2vD8f/1p1beWX3vabQCEwNDAQMDQ0WY"
146 "iRADFPQwMjBwMEDEWYB4AhADlTEsYEAAZiDeAcRApQwXgNgAyPgApJWAtBYQGwGxGxAHAnEIEEcA"
147 "cS4jRD0T1Fw2KM0ENZMVypZhRLIIqIMdag9CBMFnhtJ1jDA5RrBcMSPE7AIBkIl8UFGgP6Fu4IOa"
148 "wczAZpOZl1lix8Dm45uYmWfNIOSTlViWqJ+TmJeu75+UlZpcYs3ACZLSA4kzMIYxMIX5MAhHIykL"
149 "LinKzEu3ZmDJBSoDOZiPgRlMgv3T2MDygZGRs4OJB8n9MBoWzrAwmQD1Eyy8WZHCmg0pvBkVIGpA"
150 "Yc4oABEHhRuTAsRMUDwwQ9WAwoJBAaIGHE5Q9aB4BgBQSwECHgMUAAAACADVUTdJrPfZSDEBAAAg"
151 "AgAACwAYAAAAAAAAAAAAoIEAAAAAY2xhc3Nlcy5kZXhVVAUAAwFj5Vd1eAsAAQTkAwEABIgTAABQ"
152 "SwUGAAAAAAEAAQBRAAAAdgEAAAAA";
153
154static const char kRawZipClassesDexAbsent[] =
155 "UEsDBBQAAAAIANVRN0ms99lIMQEAACACAAAOABwAbm90Y2xhc3Nlcy5kZXhVVAkAAwFj5VcUY+VX"
156 "dXgLAAEE5AMBAASIEwAAS0mt4DIwtmDYYdV9csrcks83lpxZN2vD8f/1p1beWX3vabQCEwNDAQMD"
157 "Q0WYiRADFPQwMjBwMEDEWYB4AhADlTEsYEAAZiDeAcRApQwXgNgAyPgApJWAtBYQGwGxGxAHAnEI"
158 "EEcAcS4jRD0T1Fw2KM0ENZMVypZhRLIIqIMdag9CBMFnhtJ1jDA5RrBcMSPE7AIBkIl8UFGgP6Fu"
159 "4IOawczAZpOZl1lix8Dm45uYmWfNIOSTlViWqJ+TmJeu75+UlZpcYs3ACZLSA4kzMIYxMIX5MAhH"
160 "IykLLinKzEu3ZmDJBSoDOZiPgRlMgv3T2MDygZGRs4OJB8n9MBoWzrAwmQD1Eyy8WZHCmg0pvBkV"
161 "IGpAYc4oABEHhRuTAsRMUDwwQ9WAwoJBAaIGHE5Q9aB4BgBQSwECHgMUAAAACADVUTdJrPfZSDEB"
162 "AAAgAgAADgAYAAAAAAAAAAAAoIEAAAAAbm90Y2xhc3Nlcy5kZXhVVAUAAwFj5Vd1eAsAAQTkAwEA"
163 "BIgTAABQSwUGAAAAAAEAAQBUAAAAeQEAAAAA";
164
165static const char kRawZipThreeDexFiles[] =
166 "UEsDBBQAAAAIAP1WN0ms99lIMQEAACACAAAMABwAY2xhc3NlczIuZGV4VVQJAAOtbOVXrWzlV3V4"
167 "CwABBOQDAQAEiBMAAEtJreAyMLZg2GHVfXLK3JLPN5acWTdrw/H/9adW3ll972m0AhMDQwEDA0NF"
168 "mIkQAxT0MDIwcDBAxFmAeAIQA5UxLGBAAGYg3gHEQKUMF4DYAMj4AKSVgLQWEBsBsRsQBwJxCBBH"
169 "AHEuI0Q9E9RcNijNBDWTFcqWYUSyCKiDHWoPQgTBZ4bSdYwwOUawXDEjxOwCAZCJfFBRoD+hbuCD"
170 "msHMwGaTmZdZYsfA5uObmJlnzSDkk5VYlqifk5iXru+flJWaXGLNwAmS0gOJMzCGMTCF+TAIRyMp"
171 "Cy4pysxLt2ZgyQUqAzmYj4EZTIL909jA8oGRkbODiQfJ/TAaFs6wMJkA9RMsvFmRwpoNKbwZFSBq"
172 "QGHOKAARB4UbkwLETFA8MEPVgMKCQQGiBhxOUPWgeAYAUEsDBBQAAAAIAABXN0ms99lIMQEAACAC"
173 "AAAMABwAY2xhc3NlczMuZGV4VVQJAAOvbOVXr2zlV3V4CwABBOQDAQAEiBMAAEtJreAyMLZg2GHV"
174 "fXLK3JLPN5acWTdrw/H/9adW3ll972m0AhMDQwEDA0NFmIkQAxT0MDIwcDBAxFmAeAIQA5UxLGBA"
175 "AGYg3gHEQKUMF4DYAMj4AKSVgLQWEBsBsRsQBwJxCBBHAHEuI0Q9E9RcNijNBDWTFcqWYUSyCKiD"
176 "HWoPQgTBZ4bSdYwwOUawXDEjxOwCAZCJfFBRoD+hbuCDmsHMwGaTmZdZYsfA5uObmJlnzSDkk5VY"
177 "lqifk5iXru+flJWaXGLNwAmS0gOJMzCGMTCF+TAIRyMpCy4pysxLt2ZgyQUqAzmYj4EZTIL909jA"
178 "8oGRkbODiQfJ/TAaFs6wMJkA9RMsvFmRwpoNKbwZFSBqQGHOKAARB4UbkwLETFA8MEPVgMKCQQGi"
179 "BhxOUPWgeAYAUEsDBBQAAAAIANVRN0ms99lIMQEAACACAAALABwAY2xhc3Nlcy5kZXhVVAkAAwFj"
180 "5VetbOVXdXgLAAEE5AMBAASIEwAAS0mt4DIwtmDYYdV9csrcks83lpxZN2vD8f/1p1beWX3vabQC"
181 "EwNDAQMDQ0WYiRADFPQwMjBwMEDEWYB4AhADlTEsYEAAZiDeAcRApQwXgNgAyPgApJWAtBYQGwGx"
182 "GxAHAnEIEEcAcS4jRD0T1Fw2KM0ENZMVypZhRLIIqIMdag9CBMFnhtJ1jDA5RrBcMSPE7AIBkIl8"
183 "UFGgP6Fu4IOawczAZpOZl1lix8Dm45uYmWfNIOSTlViWqJ+TmJeu75+UlZpcYs3ACZLSA4kzMIYx"
184 "MIX5MAhHIykLLinKzEu3ZmDJBSoDOZiPgRlMgv3T2MDygZGRs4OJB8n9MBoWzrAwmQD1Eyy8WZHC"
185 "mg0pvBkVIGpAYc4oABEHhRuTAsRMUDwwQ9WAwoJBAaIGHE5Q9aB4BgBQSwECHgMUAAAACAD9VjdJ"
186 "rPfZSDEBAAAgAgAADAAYAAAAAAAAAAAAoIEAAAAAY2xhc3NlczIuZGV4VVQFAAOtbOVXdXgLAAEE"
187 "5AMBAASIEwAAUEsBAh4DFAAAAAgAAFc3Saz32UgxAQAAIAIAAAwAGAAAAAAAAAAAAKCBdwEAAGNs"
188 "YXNzZXMzLmRleFVUBQADr2zlV3V4CwABBOQDAQAEiBMAAFBLAQIeAxQAAAAIANVRN0ms99lIMQEA"
189 "ACACAAALABgAAAAAAAAAAACgge4CAABjbGFzc2VzLmRleFVUBQADAWPlV3V4CwABBOQDAQAEiBMA"
190 "AFBLBQYAAAAAAwADAPUAAABkBAAAAAA=";
191
Jeff Haoa4cd6772017-04-13 14:36:29 -0700192static const char kRawDexBadMapOffset[] =
193 "ZGV4CjAzNQAZKGSz85r+tXJ1I24FYi+FpQtWbXtelAmoAQAAcAAAAHhWNBIAAAAAAAAAAEAwIBAF"
194 "AAAAcAAAAAMAAACEAAAAAQAAAJAAAAAAAAAAAAAAAAIAAACcAAAAAQAAAKwAAADcAAAAzAAAAOQA"
195 "AADsAAAA9AAAAPkAAAANAQAAAgAAAAMAAAAEAAAABAAAAAIAAAAAAAAAAAAAAAAAAAABAAAAAAAA"
196 "AAAAAAABAAAAAQAAAAAAAAABAAAAAAAAABUBAAAAAAAAAQABAAEAAAAQAQAABAAAAHAQAQAAAA4A"
197 "Bjxpbml0PgAGQS5qYXZhAANMQTsAEkxqYXZhL2xhbmcvT2JqZWN0OwABVgABAAcOAAAAAQAAgYAE"
198 "zAEACwAAAAAAAAABAAAAAAAAAAEAAAAFAAAAcAAAAAIAAAADAAAAhAAAAAMAAAABAAAAkAAAAAUA"
199 "AAACAAAAnAAAAAYAAAABAAAArAAAAAEgAAABAAAAzAAAAAIgAAAFAAAA5AAAAAMgAAABAAAAEAEA"
200 "AAAgAAABAAAAFQEAAAAQAAABAAAAIAEAAA==";
201
Jeff Haoc1225362017-05-01 17:29:35 -0700202static const char kRawDexDebugInfoLocalNullType[] =
203 "ZGV4CjAzNQA+Kwj2g6OZMH88OvK9Ey6ycdIsFCt18ED8AQAAcAAAAHhWNBIAAAAAAAAAAHQBAAAI"
204 "AAAAcAAAAAQAAACQAAAAAgAAAKAAAAAAAAAAAAAAAAMAAAC4AAAAAQAAANAAAAAMAQAA8AAAABwB"
205 "AAAkAQAALAEAAC8BAAA0AQAASAEAAEsBAABOAQAAAgAAAAMAAAAEAAAABQAAAAIAAAAAAAAAAAAA"
206 "AAUAAAADAAAAAAAAAAEAAQAAAAAAAQAAAAYAAAACAAEAAAAAAAEAAAABAAAAAgAAAAAAAAABAAAA"
207 "AAAAAGMBAAAAAAAAAQABAAEAAABUAQAABAAAAHAQAgAAAA4AAgABAAAAAABZAQAAAgAAABIQDwAG"
208 "PGluaXQ+AAZBLmphdmEAAUkAA0xBOwASTGphdmEvbGFuZy9PYmplY3Q7AAFWAAFhAAR0aGlzAAEA"
209 "Bw4AAwAHDh4DAAcAAAAAAQEAgYAE8AEBAIgCAAAACwAAAAAAAAABAAAAAAAAAAEAAAAIAAAAcAAA"
210 "AAIAAAAEAAAAkAAAAAMAAAACAAAAoAAAAAUAAAADAAAAuAAAAAYAAAABAAAA0AAAAAEgAAACAAAA"
211 "8AAAAAIgAAAIAAAAHAEAAAMgAAACAAAAVAEAAAAgAAABAAAAYwEAAAAQAAABAAAAdAEAAA==";
212
Narayan Kamath52e66502016-08-01 14:20:31 +0100213static void DecodeAndWriteDexFile(const char* base64, const char* location) {
Ian Rogers33e95662013-05-20 20:29:14 -0700214 // decode base64
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700215 CHECK(base64 != nullptr);
Alex Light9c20a142016-08-23 15:05:12 -0700216 std::vector<uint8_t> dex_bytes = DecodeBase64Vec(base64);
Orion Hodsona4c2a052016-08-17 10:51:42 +0100217 CHECK_NE(dex_bytes.size(), 0u);
Ian Rogers33e95662013-05-20 20:29:14 -0700218
219 // write to provided file
Ian Rogers700a4022014-05-19 16:49:03 -0700220 std::unique_ptr<File> file(OS::CreateEmptyFile(location));
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700221 CHECK(file.get() != nullptr);
Orion Hodsona4c2a052016-08-17 10:51:42 +0100222 if (!file->WriteFully(dex_bytes.data(), dex_bytes.size())) {
Ian Rogers33e95662013-05-20 20:29:14 -0700223 PLOG(FATAL) << "Failed to write base64 as dex file";
224 }
Andreas Gampe4303ba92014-11-06 01:00:46 -0800225 if (file->FlushCloseOrErase() != 0) {
226 PLOG(FATAL) << "Could not flush and close test file.";
227 }
Narayan Kamath52e66502016-08-01 14:20:31 +0100228}
229
David Sehr9fddd362016-09-22 14:05:37 -0700230static bool OpenDexFilesBase64(const char* base64,
231 const char* location,
232 std::vector<std::unique_ptr<const DexFile>>* dex_files,
233 std::string* error_msg) {
Narayan Kamath52e66502016-08-01 14:20:31 +0100234 DecodeAndWriteDexFile(base64, location);
Ian Rogers33e95662013-05-20 20:29:14 -0700235
David Sehr9fddd362016-09-22 14:05:37 -0700236 // read dex file(s)
Ian Rogers33e95662013-05-20 20:29:14 -0700237 ScopedObjectAccess soa(Thread::Current());
Aart Bik37d6a3b2016-06-21 18:30:10 -0700238 static constexpr bool kVerifyChecksum = true;
Richard Uhlerfbef44d2014-12-23 09:48:51 -0800239 std::vector<std::unique_ptr<const DexFile>> tmp;
Nicolas Geoffray095c6c92017-10-19 13:59:55 +0100240 bool success = DexFileLoader::Open(
241 location, location, /* verify */ true, kVerifyChecksum, error_msg, &tmp);
David Sehr9fddd362016-09-22 14:05:37 -0700242 if (success) {
243 for (std::unique_ptr<const DexFile>& dex_file : tmp) {
244 EXPECT_EQ(PROT_READ, dex_file->GetPermissions());
245 EXPECT_TRUE(dex_file->IsReadOnly());
246 }
247 *dex_files = std::move(tmp);
248 }
249 return success;
250}
251
252static std::unique_ptr<const DexFile> OpenDexFileBase64(const char* base64,
253 const char* location) {
254 // read dex files.
255 std::string error_msg;
256 std::vector<std::unique_ptr<const DexFile>> dex_files;
257 bool success = OpenDexFilesBase64(base64, location, &dex_files, &error_msg);
Andreas Gampe833a4852014-05-21 18:46:59 -0700258 CHECK(success) << error_msg;
David Sehr9fddd362016-09-22 14:05:37 -0700259 EXPECT_EQ(1U, dex_files.size());
260 return std::move(dex_files[0]);
Ian Rogers33e95662013-05-20 20:29:14 -0700261}
262
Orion Hodsona4c2a052016-08-17 10:51:42 +0100263static std::unique_ptr<const DexFile> OpenDexFileInMemoryBase64(const char* base64,
264 const char* location,
Jeff Haoa4cd6772017-04-13 14:36:29 -0700265 uint32_t location_checksum,
266 bool expect_success) {
Orion Hodsona4c2a052016-08-17 10:51:42 +0100267 CHECK(base64 != nullptr);
Alex Light9c20a142016-08-23 15:05:12 -0700268 std::vector<uint8_t> dex_bytes = DecodeBase64Vec(base64);
Orion Hodsona4c2a052016-08-17 10:51:42 +0100269 CHECK_NE(dex_bytes.size(), 0u);
270
271 std::string error_message;
272 std::unique_ptr<MemMap> region(MemMap::MapAnonymous("test-region",
273 nullptr,
274 dex_bytes.size(),
275 PROT_READ | PROT_WRITE,
276 /* low_4gb */ false,
277 /* reuse */ false,
278 &error_message));
279 memcpy(region->Begin(), dex_bytes.data(), dex_bytes.size());
Mathieu Chartier79c87da2017-10-10 11:54:29 -0700280 std::unique_ptr<const DexFile> dex_file(DexFileLoader::Open(location,
281 location_checksum,
282 std::move(region),
283 /* verify */ true,
284 /* verify_checksum */ true,
285 &error_message));
Jeff Haoa4cd6772017-04-13 14:36:29 -0700286 if (expect_success) {
287 CHECK(dex_file != nullptr) << error_message;
288 } else {
289 CHECK(dex_file == nullptr) << "Expected dex file open to fail.";
290 }
Orion Hodsona4c2a052016-08-17 10:51:42 +0100291 return dex_file;
292}
293
Orion Hodsoncffc5292016-09-05 13:43:11 +0100294static void ValidateDexFileHeader(std::unique_ptr<const DexFile> dex_file) {
295 static const uint8_t kExpectedDexFileMagic[8] = {
296 /* d */ 0x64, /* e */ 0x64, /* x */ 0x78, /* \n */ 0x0d,
297 /* 0 */ 0x30, /* 3 */ 0x33, /* 5 */ 0x35, /* \0 */ 0x00
298 };
299 static const uint8_t kExpectedSha1[DexFile::kSha1DigestSize] = {
300 0x7b, 0xb8, 0x0c, 0xd4, 0x1f, 0xd6, 0x1e, 0xc5,
301 0x89, 0xe8, 0xbe, 0xe5, 0x18, 0x02, 0x12, 0x18,
302 0x2e, 0xf2, 0x8c, 0x3d,
303 };
Orion Hodsona4c2a052016-08-17 10:51:42 +0100304
Orion Hodsoncffc5292016-09-05 13:43:11 +0100305 const DexFile::Header& header = dex_file->GetHeader();
306 EXPECT_EQ(*kExpectedDexFileMagic, *header.magic_);
Orion Hodsona4c2a052016-08-17 10:51:42 +0100307 EXPECT_EQ(0x00d87910U, header.checksum_);
Orion Hodsoncffc5292016-09-05 13:43:11 +0100308 EXPECT_EQ(*kExpectedSha1, *header.signature_);
Orion Hodsona4c2a052016-08-17 10:51:42 +0100309 EXPECT_EQ(904U, header.file_size_);
310 EXPECT_EQ(112U, header.header_size_);
311 EXPECT_EQ(0U, header.link_size_);
312 EXPECT_EQ(0U, header.link_off_);
313 EXPECT_EQ(15U, header.string_ids_size_);
314 EXPECT_EQ(112U, header.string_ids_off_);
315 EXPECT_EQ(7U, header.type_ids_size_);
316 EXPECT_EQ(172U, header.type_ids_off_);
317 EXPECT_EQ(2U, header.proto_ids_size_);
318 EXPECT_EQ(200U, header.proto_ids_off_);
319 EXPECT_EQ(1U, header.field_ids_size_);
320 EXPECT_EQ(224U, header.field_ids_off_);
321 EXPECT_EQ(3U, header.method_ids_size_);
322 EXPECT_EQ(232U, header.method_ids_off_);
323 EXPECT_EQ(2U, header.class_defs_size_);
324 EXPECT_EQ(256U, header.class_defs_off_);
325 EXPECT_EQ(584U, header.data_size_);
326 EXPECT_EQ(320U, header.data_off_);
327
Orion Hodsoncffc5292016-09-05 13:43:11 +0100328 EXPECT_EQ(header.checksum_, dex_file->GetLocationChecksum());
329}
330
331TEST_F(DexFileTest, Header) {
332 ScratchFile tmp;
333 std::unique_ptr<const DexFile> raw(OpenDexFileBase64(kRawDex, tmp.GetFilename().c_str()));
334 ValidateDexFileHeader(std::move(raw));
Orion Hodsona4c2a052016-08-17 10:51:42 +0100335}
336
337TEST_F(DexFileTest, HeaderInMemory) {
338 ScratchFile tmp;
339 std::unique_ptr<const DexFile> raw =
Jeff Haoa4cd6772017-04-13 14:36:29 -0700340 OpenDexFileInMemoryBase64(kRawDex, tmp.GetFilename().c_str(), 0x00d87910U, true);
Orion Hodsoncffc5292016-09-05 13:43:11 +0100341 ValidateDexFileHeader(std::move(raw));
Brian Carlstrom5b332c82012-02-01 15:02:31 -0800342}
343
Narayan Kamath52e66502016-08-01 14:20:31 +0100344TEST_F(DexFileTest, Version38Accepted) {
345 ScratchFile tmp;
346 std::unique_ptr<const DexFile> raw(OpenDexFileBase64(kRawDex38, tmp.GetFilename().c_str()));
347 ASSERT_TRUE(raw.get() != nullptr);
348
349 const DexFile::Header& header = raw->GetHeader();
350 EXPECT_EQ(38u, header.GetVersion());
351}
352
Orion Hodson2e599942017-09-22 16:17:41 +0100353TEST_F(DexFileTest, Version39Accepted) {
354 ScratchFile tmp;
355 std::unique_ptr<const DexFile> raw(OpenDexFileBase64(kRawDex39, tmp.GetFilename().c_str()));
356 ASSERT_TRUE(raw.get() != nullptr);
357
358 const DexFile::Header& header = raw->GetHeader();
359 EXPECT_EQ(39u, header.GetVersion());
360}
361
362TEST_F(DexFileTest, Version40Rejected) {
Narayan Kamath52e66502016-08-01 14:20:31 +0100363 ScratchFile tmp;
364 const char* location = tmp.GetFilename().c_str();
Orion Hodson2e599942017-09-22 16:17:41 +0100365 DecodeAndWriteDexFile(kRawDex40, location);
366
367 ScopedObjectAccess soa(Thread::Current());
368 static constexpr bool kVerifyChecksum = true;
369 std::string error_msg;
370 std::vector<std::unique_ptr<const DexFile>> dex_files;
Nicolas Geoffray095c6c92017-10-19 13:59:55 +0100371 ASSERT_FALSE(DexFileLoader::Open(
372 location, location, /* verify */ true, kVerifyChecksum, &error_msg, &dex_files));
Orion Hodson2e599942017-09-22 16:17:41 +0100373}
374
375TEST_F(DexFileTest, Version41Rejected) {
376 ScratchFile tmp;
377 const char* location = tmp.GetFilename().c_str();
378 DecodeAndWriteDexFile(kRawDex41, location);
Narayan Kamath52e66502016-08-01 14:20:31 +0100379
380 ScopedObjectAccess soa(Thread::Current());
381 static constexpr bool kVerifyChecksum = true;
382 std::string error_msg;
383 std::vector<std::unique_ptr<const DexFile>> dex_files;
Nicolas Geoffray095c6c92017-10-19 13:59:55 +0100384 ASSERT_FALSE(DexFileLoader::Open(
385 location, location, /* verify */ true, kVerifyChecksum, &error_msg, &dex_files));
Narayan Kamath52e66502016-08-01 14:20:31 +0100386}
387
ganxiaolincd16d0a2016-07-18 11:21:44 +0800388TEST_F(DexFileTest, ZeroLengthDexRejected) {
389 ScratchFile tmp;
390 const char* location = tmp.GetFilename().c_str();
391 DecodeAndWriteDexFile(kRawDexZeroLength, location);
392
393 ScopedObjectAccess soa(Thread::Current());
394 static constexpr bool kVerifyChecksum = true;
395 std::string error_msg;
396 std::vector<std::unique_ptr<const DexFile>> dex_files;
Nicolas Geoffray095c6c92017-10-19 13:59:55 +0100397 ASSERT_FALSE(DexFileLoader::Open(
398 location, location, /* verify */ true, kVerifyChecksum, &error_msg, &dex_files));
ganxiaolincd16d0a2016-07-18 11:21:44 +0800399}
400
Brian Carlstrom5b332c82012-02-01 15:02:31 -0800401TEST_F(DexFileTest, GetLocationChecksum) {
Ian Rogers33e95662013-05-20 20:29:14 -0700402 ScopedObjectAccess soa(Thread::Current());
Richard Uhlerfbef44d2014-12-23 09:48:51 -0800403 std::unique_ptr<const DexFile> raw(OpenTestDexFile("Main"));
Brian Carlstrom5b332c82012-02-01 15:02:31 -0800404 EXPECT_NE(raw->GetHeader().checksum_, raw->GetLocationChecksum());
405}
406
407TEST_F(DexFileTest, GetChecksum) {
Richard Uhler84f50ae2017-02-06 15:12:45 +0000408 std::vector<uint32_t> checksums;
Ian Rogers33e95662013-05-20 20:29:14 -0700409 ScopedObjectAccess soa(Thread::Current());
Ian Rogers8d31bbd2013-10-13 10:44:14 -0700410 std::string error_msg;
Mathieu Chartier79c87da2017-10-10 11:54:29 -0700411 EXPECT_TRUE(DexFileLoader::GetMultiDexChecksums(GetLibCoreDexFileNames()[0].c_str(),
412 &checksums,
413 &error_msg))
Ian Rogers8d31bbd2013-10-13 10:44:14 -0700414 << error_msg;
Richard Uhler84f50ae2017-02-06 15:12:45 +0000415 ASSERT_EQ(1U, checksums.size());
416 EXPECT_EQ(java_lang_dex_file_->GetLocationChecksum(), checksums[0]);
Brian Carlstrom7e49dca2011-07-22 18:07:34 -0700417}
418
Richard Uhler69bcf2c2017-01-24 10:25:21 +0000419TEST_F(DexFileTest, GetMultiDexChecksums) {
420 std::string error_msg;
421 std::vector<uint32_t> checksums;
422 std::string multidex_file = GetTestDexFileName("MultiDex");
Mathieu Chartier79c87da2017-10-10 11:54:29 -0700423 EXPECT_TRUE(DexFileLoader::GetMultiDexChecksums(multidex_file.c_str(),
424 &checksums,
425 &error_msg)) << error_msg;
Richard Uhler69bcf2c2017-01-24 10:25:21 +0000426
Richard Uhler84f50ae2017-02-06 15:12:45 +0000427 std::vector<std::unique_ptr<const DexFile>> dexes = OpenTestDexFiles("MultiDex");
428 ASSERT_EQ(2U, dexes.size());
429 ASSERT_EQ(2U, checksums.size());
Richard Uhler69bcf2c2017-01-24 10:25:21 +0000430
Mathieu Chartier79c87da2017-10-10 11:54:29 -0700431 EXPECT_EQ(dexes[0]->GetLocation(), DexFileLoader::GetMultiDexLocation(0, multidex_file.c_str()));
Richard Uhler84f50ae2017-02-06 15:12:45 +0000432 EXPECT_EQ(dexes[0]->GetLocationChecksum(), checksums[0]);
Richard Uhler69bcf2c2017-01-24 10:25:21 +0000433
Mathieu Chartier79c87da2017-10-10 11:54:29 -0700434 EXPECT_EQ(dexes[1]->GetLocation(), DexFileLoader::GetMultiDexLocation(1, multidex_file.c_str()));
Richard Uhler84f50ae2017-02-06 15:12:45 +0000435 EXPECT_EQ(dexes[1]->GetLocationChecksum(), checksums[1]);
Richard Uhler69bcf2c2017-01-24 10:25:21 +0000436}
437
Brian Carlstrom9f30b382011-08-28 22:41:38 -0700438TEST_F(DexFileTest, ClassDefs) {
Ian Rogers33e95662013-05-20 20:29:14 -0700439 ScopedObjectAccess soa(Thread::Current());
Richard Uhlerfbef44d2014-12-23 09:48:51 -0800440 std::unique_ptr<const DexFile> raw(OpenTestDexFile("Nested"));
441 ASSERT_TRUE(raw.get() != nullptr);
Andreas Gampeae78c262017-02-01 20:40:44 -0800442 EXPECT_EQ(3U, raw->NumClassDefs());
Brian Carlstrom7e49dca2011-07-22 18:07:34 -0700443
Brian Carlstromf615a612011-07-23 12:50:34 -0700444 const DexFile::ClassDef& c0 = raw->GetClassDef(0);
Andreas Gampeae78c262017-02-01 20:40:44 -0800445 EXPECT_STREQ("LNested$1;", raw->GetClassDescriptor(c0));
Brian Carlstrom7e49dca2011-07-22 18:07:34 -0700446
Brian Carlstromf615a612011-07-23 12:50:34 -0700447 const DexFile::ClassDef& c1 = raw->GetClassDef(1);
Andreas Gampeae78c262017-02-01 20:40:44 -0800448 EXPECT_STREQ("LNested$Inner;", raw->GetClassDescriptor(c1));
449
450 const DexFile::ClassDef& c2 = raw->GetClassDef(2);
451 EXPECT_STREQ("LNested;", raw->GetClassDescriptor(c2));
Carl Shapiro1fb86202011-06-27 17:43:13 -0700452}
453
Ian Rogersd91d6d62013-09-25 20:26:14 -0700454TEST_F(DexFileTest, GetMethodSignature) {
Ian Rogers33e95662013-05-20 20:29:14 -0700455 ScopedObjectAccess soa(Thread::Current());
Richard Uhlerfbef44d2014-12-23 09:48:51 -0800456 std::unique_ptr<const DexFile> raw(OpenTestDexFile("GetMethodSignature"));
457 ASSERT_TRUE(raw.get() != nullptr);
Carl Shapiro419ec7b2011-08-03 14:48:33 -0700458 EXPECT_EQ(1U, raw->NumClassDefs());
459
460 const DexFile::ClassDef& class_def = raw->GetClassDef(0);
Ian Rogersd91d6d62013-09-25 20:26:14 -0700461 ASSERT_STREQ("LGetMethodSignature;", raw->GetClassDescriptor(class_def));
Carl Shapiro419ec7b2011-08-03 14:48:33 -0700462
Ian Rogers13735952014-10-08 12:43:28 -0700463 const uint8_t* class_data = raw->GetClassData(class_def);
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700464 ASSERT_TRUE(class_data != nullptr);
Elliott Hughes4d6850c2012-01-18 15:55:06 -0800465 ClassDataItemIterator it(*raw, class_data);
Carl Shapiro419ec7b2011-08-03 14:48:33 -0700466
Ian Rogers0571d352011-11-03 19:51:38 -0700467 EXPECT_EQ(1u, it.NumDirectMethods());
Carl Shapiro419ec7b2011-08-03 14:48:33 -0700468
Ian Rogers0571d352011-11-03 19:51:38 -0700469 // Check the signature for the static initializer.
Carl Shapiro419ec7b2011-08-03 14:48:33 -0700470 {
Ian Rogers0571d352011-11-03 19:51:38 -0700471 ASSERT_EQ(1U, it.NumDirectMethods());
472 const DexFile::MethodId& method_id = raw->GetMethodId(it.GetMemberIndex());
Ian Rogers0571d352011-11-03 19:51:38 -0700473 const char* name = raw->StringDataByIdx(method_id.name_idx_);
Carl Shapiro419ec7b2011-08-03 14:48:33 -0700474 ASSERT_STREQ("<init>", name);
Ian Rogersd91d6d62013-09-25 20:26:14 -0700475 std::string signature(raw->GetMethodSignature(method_id).ToString());
Ian Rogers0571d352011-11-03 19:51:38 -0700476 ASSERT_EQ("()V", signature);
Carl Shapiro419ec7b2011-08-03 14:48:33 -0700477 }
478
Vladimir Markob8a55f82017-09-21 16:21:43 +0100479 // Check all virtual methods.
480 struct Result {
481 const char* name;
482 const char* signature;
483 const char* pretty_method;
484 };
485 static const Result results[] = {
486 {
487 "m1",
488 "(IDJLjava/lang/Object;)Ljava/lang/Float;",
489 "java.lang.Float GetMethodSignature.m1(int, double, long, java.lang.Object)"
490 },
Igor Murashkin5573c372017-11-16 13:34:30 -0800491 {
Vladimir Markob8a55f82017-09-21 16:21:43 +0100492 "m2",
493 "(ZSC)LGetMethodSignature;",
494 "GetMethodSignature GetMethodSignature.m2(boolean, short, char)"
495 },
Igor Murashkin5573c372017-11-16 13:34:30 -0800496 {
Vladimir Markob8a55f82017-09-21 16:21:43 +0100497 "m3",
498 "()V",
499 "void GetMethodSignature.m3()"
500 },
Igor Murashkin5573c372017-11-16 13:34:30 -0800501 {
Vladimir Markob8a55f82017-09-21 16:21:43 +0100502 "m4",
503 "(I)V",
504 "void GetMethodSignature.m4(int)"
505 },
Igor Murashkin5573c372017-11-16 13:34:30 -0800506 {
Vladimir Markob8a55f82017-09-21 16:21:43 +0100507 "m5",
508 "(II)V",
509 "void GetMethodSignature.m5(int, int)"
510 },
Igor Murashkin5573c372017-11-16 13:34:30 -0800511 {
Vladimir Markob8a55f82017-09-21 16:21:43 +0100512 "m6",
513 "(II[[I)V",
514 "void GetMethodSignature.m6(int, int, int[][])"
515 },
Igor Murashkin5573c372017-11-16 13:34:30 -0800516 {
Vladimir Markob8a55f82017-09-21 16:21:43 +0100517 "m7",
518 "(II[[ILjava/lang/Object;)V",
519 "void GetMethodSignature.m7(int, int, int[][], java.lang.Object)"
520 },
Igor Murashkin5573c372017-11-16 13:34:30 -0800521 {
Vladimir Markob8a55f82017-09-21 16:21:43 +0100522 "m8",
523 "(II[[ILjava/lang/Object;[[Ljava/lang/Object;)V",
524 "void GetMethodSignature.m8(int, int, int[][], java.lang.Object, java.lang.Object[][])"
525 },
Igor Murashkin5573c372017-11-16 13:34:30 -0800526 {
Vladimir Markob8a55f82017-09-21 16:21:43 +0100527 "m9",
528 "()I",
529 "int GetMethodSignature.m9()"
530 },
Igor Murashkin5573c372017-11-16 13:34:30 -0800531 {
Vladimir Markob8a55f82017-09-21 16:21:43 +0100532 "mA",
533 "()[[I",
534 "int[][] GetMethodSignature.mA()"
535 },
Igor Murashkin5573c372017-11-16 13:34:30 -0800536 {
Vladimir Markob8a55f82017-09-21 16:21:43 +0100537 "mB",
538 "()[[Ljava/lang/Object;",
539 "java.lang.Object[][] GetMethodSignature.mB()"
540 },
541 };
542 ASSERT_EQ(arraysize(results), it.NumVirtualMethods());
543 for (const Result& r : results) {
Ian Rogers0571d352011-11-03 19:51:38 -0700544 it.Next();
545 const DexFile::MethodId& method_id = raw->GetMethodId(it.GetMemberIndex());
Carl Shapiro419ec7b2011-08-03 14:48:33 -0700546
Ian Rogers0571d352011-11-03 19:51:38 -0700547 const char* name = raw->StringDataByIdx(method_id.name_idx_);
Vladimir Markob8a55f82017-09-21 16:21:43 +0100548 ASSERT_STREQ(r.name, name);
Carl Shapiro419ec7b2011-08-03 14:48:33 -0700549
Ian Rogersd91d6d62013-09-25 20:26:14 -0700550 std::string signature(raw->GetMethodSignature(method_id).ToString());
Vladimir Markob8a55f82017-09-21 16:21:43 +0100551 ASSERT_EQ(r.signature, signature);
Carl Shapiro419ec7b2011-08-03 14:48:33 -0700552
Vladimir Markob8a55f82017-09-21 16:21:43 +0100553 std::string plain_method = std::string("GetMethodSignature.") + r.name;
554 ASSERT_EQ(plain_method, raw->PrettyMethod(it.GetMemberIndex(), /* with_signature */ false));
555 ASSERT_EQ(r.pretty_method, raw->PrettyMethod(it.GetMemberIndex(), /* with_signature */ true));
Ian Rogers0571d352011-11-03 19:51:38 -0700556 }
557}
558
559TEST_F(DexFileTest, FindStringId) {
Ian Rogers33e95662013-05-20 20:29:14 -0700560 ScopedObjectAccess soa(Thread::Current());
Richard Uhlerfbef44d2014-12-23 09:48:51 -0800561 std::unique_ptr<const DexFile> raw(OpenTestDexFile("GetMethodSignature"));
562 ASSERT_TRUE(raw.get() != nullptr);
Ian Rogers0571d352011-11-03 19:51:38 -0700563 EXPECT_EQ(1U, raw->NumClassDefs());
564
Ian Rogersd91d6d62013-09-25 20:26:14 -0700565 const char* strings[] = { "LGetMethodSignature;", "Ljava/lang/Float;", "Ljava/lang/Object;",
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700566 "D", "I", "J", nullptr };
567 for (size_t i = 0; strings[i] != nullptr; i++) {
Ian Rogers0571d352011-11-03 19:51:38 -0700568 const char* str = strings[i];
569 const DexFile::StringId* str_id = raw->FindStringId(str);
570 const char* dex_str = raw->GetStringData(*str_id);
571 EXPECT_STREQ(dex_str, str);
572 }
573}
574
575TEST_F(DexFileTest, FindTypeId) {
576 for (size_t i = 0; i < java_lang_dex_file_->NumTypeIds(); i++) {
Andreas Gampea5b09a62016-11-17 15:21:22 -0800577 const char* type_str = java_lang_dex_file_->StringByTypeIdx(dex::TypeIndex(i));
Ian Rogers0571d352011-11-03 19:51:38 -0700578 const DexFile::StringId* type_str_id = java_lang_dex_file_->FindStringId(type_str);
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700579 ASSERT_TRUE(type_str_id != nullptr);
Andreas Gampe8a0128a2016-11-28 07:38:35 -0800580 dex::StringIndex type_str_idx = java_lang_dex_file_->GetIndexForStringId(*type_str_id);
Ian Rogers0571d352011-11-03 19:51:38 -0700581 const DexFile::TypeId* type_id = java_lang_dex_file_->FindTypeId(type_str_idx);
Mathieu Chartier9507fa22015-10-29 15:08:57 -0700582 ASSERT_EQ(type_id, java_lang_dex_file_->FindTypeId(type_str));
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700583 ASSERT_TRUE(type_id != nullptr);
Andreas Gampea5b09a62016-11-17 15:21:22 -0800584 EXPECT_EQ(java_lang_dex_file_->GetIndexForTypeId(*type_id).index_, i);
Ian Rogers0571d352011-11-03 19:51:38 -0700585 }
586}
587
588TEST_F(DexFileTest, FindProtoId) {
589 for (size_t i = 0; i < java_lang_dex_file_->NumProtoIds(); i++) {
590 const DexFile::ProtoId& to_find = java_lang_dex_file_->GetProtoId(i);
591 const DexFile::TypeList* to_find_tl = java_lang_dex_file_->GetProtoParameters(to_find);
Andreas Gampea5b09a62016-11-17 15:21:22 -0800592 std::vector<dex::TypeIndex> to_find_types;
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700593 if (to_find_tl != nullptr) {
Ian Rogers0571d352011-11-03 19:51:38 -0700594 for (size_t j = 0; j < to_find_tl->Size(); j++) {
595 to_find_types.push_back(to_find_tl->GetTypeItem(j).type_idx_);
596 }
597 }
598 const DexFile::ProtoId* found =
599 java_lang_dex_file_->FindProtoId(to_find.return_type_idx_, to_find_types);
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700600 ASSERT_TRUE(found != nullptr);
Ian Rogers0571d352011-11-03 19:51:38 -0700601 EXPECT_EQ(java_lang_dex_file_->GetIndexForProtoId(*found), i);
602 }
603}
604
605TEST_F(DexFileTest, FindMethodId) {
606 for (size_t i = 0; i < java_lang_dex_file_->NumMethodIds(); i++) {
607 const DexFile::MethodId& to_find = java_lang_dex_file_->GetMethodId(i);
608 const DexFile::TypeId& klass = java_lang_dex_file_->GetTypeId(to_find.class_idx_);
609 const DexFile::StringId& name = java_lang_dex_file_->GetStringId(to_find.name_idx_);
610 const DexFile::ProtoId& signature = java_lang_dex_file_->GetProtoId(to_find.proto_idx_);
611 const DexFile::MethodId* found = java_lang_dex_file_->FindMethodId(klass, name, signature);
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700612 ASSERT_TRUE(found != nullptr) << "Didn't find method " << i << ": "
Ian Rogers0571d352011-11-03 19:51:38 -0700613 << java_lang_dex_file_->StringByTypeIdx(to_find.class_idx_) << "."
614 << java_lang_dex_file_->GetStringData(name)
Ian Rogersd91d6d62013-09-25 20:26:14 -0700615 << java_lang_dex_file_->GetMethodSignature(to_find);
Ian Rogers0571d352011-11-03 19:51:38 -0700616 EXPECT_EQ(java_lang_dex_file_->GetIndexForMethodId(*found), i);
Carl Shapiro419ec7b2011-08-03 14:48:33 -0700617 }
Carl Shapiro419ec7b2011-08-03 14:48:33 -0700618}
619
Ian Rogers9b1a4f42011-11-14 18:35:10 -0800620TEST_F(DexFileTest, FindFieldId) {
621 for (size_t i = 0; i < java_lang_dex_file_->NumFieldIds(); i++) {
622 const DexFile::FieldId& to_find = java_lang_dex_file_->GetFieldId(i);
623 const DexFile::TypeId& klass = java_lang_dex_file_->GetTypeId(to_find.class_idx_);
624 const DexFile::StringId& name = java_lang_dex_file_->GetStringId(to_find.name_idx_);
625 const DexFile::TypeId& type = java_lang_dex_file_->GetTypeId(to_find.type_idx_);
626 const DexFile::FieldId* found = java_lang_dex_file_->FindFieldId(klass, name, type);
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700627 ASSERT_TRUE(found != nullptr) << "Didn't find field " << i << ": "
Ian Rogers9b1a4f42011-11-14 18:35:10 -0800628 << java_lang_dex_file_->StringByTypeIdx(to_find.type_idx_) << " "
629 << java_lang_dex_file_->StringByTypeIdx(to_find.class_idx_) << "."
630 << java_lang_dex_file_->GetStringData(name);
631 EXPECT_EQ(java_lang_dex_file_->GetIndexForFieldId(*found), i);
632 }
633}
634
Calin Juravle4e1d5792014-07-15 23:56:47 +0100635TEST_F(DexFileTest, GetMultiDexClassesDexName) {
Mathieu Chartier79c87da2017-10-10 11:54:29 -0700636 ASSERT_EQ("classes.dex", DexFileLoader::GetMultiDexClassesDexName(0));
637 ASSERT_EQ("classes2.dex", DexFileLoader::GetMultiDexClassesDexName(1));
638 ASSERT_EQ("classes3.dex", DexFileLoader::GetMultiDexClassesDexName(2));
639 ASSERT_EQ("classes100.dex", DexFileLoader::GetMultiDexClassesDexName(99));
Andreas Gampe90e34042015-04-27 20:01:52 -0700640}
641
642TEST_F(DexFileTest, GetMultiDexLocation) {
Calin Juravle4e1d5792014-07-15 23:56:47 +0100643 std::string dex_location_str = "/system/app/framework.jar";
644 const char* dex_location = dex_location_str.c_str();
Mathieu Chartier79c87da2017-10-10 11:54:29 -0700645 ASSERT_EQ("/system/app/framework.jar", DexFileLoader::GetMultiDexLocation(0, dex_location));
Calin Juravlea308a322017-07-18 16:51:51 -0700646 ASSERT_EQ("/system/app/framework.jar!classes2.dex",
Mathieu Chartier79c87da2017-10-10 11:54:29 -0700647 DexFileLoader::GetMultiDexLocation(1, dex_location));
Calin Juravlea308a322017-07-18 16:51:51 -0700648 ASSERT_EQ("/system/app/framework.jar!classes101.dex",
Mathieu Chartier79c87da2017-10-10 11:54:29 -0700649 DexFileLoader::GetMultiDexLocation(100, dex_location));
Calin Juravle4e1d5792014-07-15 23:56:47 +0100650}
651
652TEST_F(DexFileTest, GetDexCanonicalLocation) {
653 ScratchFile file;
Vladimir Markoaa4497d2014-09-05 14:01:17 +0100654 UniqueCPtr<const char[]> dex_location_real(realpath(file.GetFilename().c_str(), nullptr));
655 std::string dex_location(dex_location_real.get());
Calin Juravle4e1d5792014-07-15 23:56:47 +0100656
Mathieu Chartier79c87da2017-10-10 11:54:29 -0700657 ASSERT_EQ(dex_location, DexFileLoader::GetDexCanonicalLocation(dex_location.c_str()));
658 std::string multidex_location = DexFileLoader::GetMultiDexLocation(1, dex_location.c_str());
659 ASSERT_EQ(multidex_location, DexFileLoader::GetDexCanonicalLocation(multidex_location.c_str()));
Calin Juravle4e1d5792014-07-15 23:56:47 +0100660
661 std::string dex_location_sym = dex_location + "symlink";
662 ASSERT_EQ(0, symlink(dex_location.c_str(), dex_location_sym.c_str()));
663
Mathieu Chartier79c87da2017-10-10 11:54:29 -0700664 ASSERT_EQ(dex_location, DexFileLoader::GetDexCanonicalLocation(dex_location_sym.c_str()));
Calin Juravle4e1d5792014-07-15 23:56:47 +0100665
Mathieu Chartier79c87da2017-10-10 11:54:29 -0700666 std::string multidex_location_sym = DexFileLoader::GetMultiDexLocation(
667 1, dex_location_sym.c_str());
668 ASSERT_EQ(multidex_location,
669 DexFileLoader::GetDexCanonicalLocation(multidex_location_sym.c_str()));
Calin Juravle4e1d5792014-07-15 23:56:47 +0100670
671 ASSERT_EQ(0, unlink(dex_location_sym.c_str()));
672}
673
Richard Uhlere5fed032015-03-18 08:21:11 -0700674TEST(DexFileUtilsTest, GetBaseLocationAndMultiDexSuffix) {
Mathieu Chartier79c87da2017-10-10 11:54:29 -0700675 EXPECT_EQ("/foo/bar/baz.jar", DexFileLoader::GetBaseLocation("/foo/bar/baz.jar"));
676 EXPECT_EQ("/foo/bar/baz.jar", DexFileLoader::GetBaseLocation("/foo/bar/baz.jar!classes2.dex"));
677 EXPECT_EQ("/foo/bar/baz.jar", DexFileLoader::GetBaseLocation("/foo/bar/baz.jar!classes8.dex"));
678 EXPECT_EQ("", DexFileLoader::GetMultiDexSuffix("/foo/bar/baz.jar"));
679 EXPECT_EQ("!classes2.dex", DexFileLoader::GetMultiDexSuffix("/foo/bar/baz.jar!classes2.dex"));
680 EXPECT_EQ("!classes8.dex", DexFileLoader::GetMultiDexSuffix("/foo/bar/baz.jar!classes8.dex"));
Richard Uhlere5fed032015-03-18 08:21:11 -0700681}
682
David Sehr9fddd362016-09-22 14:05:37 -0700683TEST_F(DexFileTest, ZipOpenClassesPresent) {
684 ScratchFile tmp;
685 std::vector<std::unique_ptr<const DexFile>> dex_files;
686 std::string error_msg;
687 ASSERT_TRUE(OpenDexFilesBase64(kRawZipClassesDexPresent, tmp.GetFilename().c_str(), &dex_files,
688 &error_msg));
689 EXPECT_EQ(dex_files.size(), 1u);
690}
691
692TEST_F(DexFileTest, ZipOpenClassesAbsent) {
693 ScratchFile tmp;
694 std::vector<std::unique_ptr<const DexFile>> dex_files;
695 std::string error_msg;
696 ASSERT_FALSE(OpenDexFilesBase64(kRawZipClassesDexAbsent, tmp.GetFilename().c_str(), &dex_files,
697 &error_msg));
698 EXPECT_EQ(dex_files.size(), 0u);
699}
700
701TEST_F(DexFileTest, ZipOpenThreeDexFiles) {
702 ScratchFile tmp;
703 std::vector<std::unique_ptr<const DexFile>> dex_files;
704 std::string error_msg;
705 ASSERT_TRUE(OpenDexFilesBase64(kRawZipThreeDexFiles, tmp.GetFilename().c_str(), &dex_files,
706 &error_msg));
707 EXPECT_EQ(dex_files.size(), 3u);
708}
709
Jeff Haoa4cd6772017-04-13 14:36:29 -0700710TEST_F(DexFileTest, OpenDexBadMapOffset) {
711 ScratchFile tmp;
712 std::unique_ptr<const DexFile> raw =
713 OpenDexFileInMemoryBase64(kRawDexBadMapOffset, tmp.GetFilename().c_str(), 0xb3642819U, false);
714 EXPECT_EQ(raw, nullptr);
715}
716
Jeff Hao120504f2017-04-14 14:33:52 -0700717TEST_F(DexFileTest, GetStringWithNoIndex) {
718 ScratchFile tmp;
719 std::unique_ptr<const DexFile> raw(OpenDexFileBase64(kRawDex, tmp.GetFilename().c_str()));
720 dex::TypeIndex idx;
721 EXPECT_EQ(raw->StringByTypeIdx(idx), nullptr);
722}
723
Jeff Haoc1225362017-05-01 17:29:35 -0700724static void Callback(void* context ATTRIBUTE_UNUSED,
725 const DexFile::LocalInfo& entry ATTRIBUTE_UNUSED) {
726}
727
728TEST_F(DexFileTest, OpenDexDebugInfoLocalNullType) {
729 ScratchFile tmp;
730 std::unique_ptr<const DexFile> raw = OpenDexFileInMemoryBase64(
731 kRawDexDebugInfoLocalNullType, tmp.GetFilename().c_str(), 0xf25f2b38U, true);
732 const DexFile::ClassDef& class_def = raw->GetClassDef(0);
733 const DexFile::CodeItem* code_item = raw->GetCodeItem(raw->FindCodeItemOffset(class_def, 1));
Mathieu Chartier698ebbc2018-01-05 11:00:42 -0800734 CodeItemDebugInfoAccessor accessor(*raw, code_item);
Mathieu Chartier808c7a52017-12-15 11:19:33 -0800735 ASSERT_TRUE(accessor.DecodeDebugLocalInfo(true, 1, Callback, nullptr));
Jeff Haoc1225362017-05-01 17:29:35 -0700736}
737
Carl Shapiro1fb86202011-06-27 17:43:13 -0700738} // namespace art