blob: 6719d0848c54e7716e9a88eea0d75cd557a4f842 [file] [log] [blame]
Jeff Haoc3acfc52016-08-29 14:18:26 -07001/*
2 * Copyright (C) 2016 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 */
16
Andreas Gampe8cf9cb32017-07-19 09:28:38 -070017#include <sstream>
Jeff Haoc3acfc52016-08-29 14:18:26 -070018#include <string>
19#include <vector>
Jeff Haoc3acfc52016-08-29 14:18:26 -070020
21#include <sys/types.h>
22#include <unistd.h>
23
Jeff Hao042e8982016-10-19 11:17:11 -070024#include "base/unix_file/fd_file.h"
David Sehr8f4b0562018-03-02 12:01:51 -080025#include "base/utils.h"
Jeff Haoc3acfc52016-08-29 14:18:26 -070026#include "common_runtime_test.h"
David Sehr013fd802018-01-11 22:55:24 -080027#include "dex/art_dex_file_loader.h"
David Sehre1123402018-02-01 02:46:18 -080028#include "dex/base64_test_util.h"
David Sehr9e734c72018-01-04 17:56:19 -080029#include "dex/code_item_accessors-inl.h"
30#include "dex/dex_file-inl.h"
31#include "dex/dex_file_loader.h"
Mathieu Chartier75175552018-01-25 11:23:01 -080032#include "dexlayout.h"
David Sehr97c381e2017-02-01 15:09:58 -080033#include "exec_utils.h"
Mathieu Chartierd00e02b2017-05-24 12:04:13 -070034#include "jit/profile_compilation_info.h"
Jeff Haoc3acfc52016-08-29 14:18:26 -070035
36namespace art {
37
Jeff Hao042e8982016-10-19 11:17:11 -070038static const char kDexFileLayoutInputDex[] =
39 "ZGV4CjAzNQD1KW3+B8NAB0f2A/ZVIBJ0aHrGIqcpVTAUAgAAcAAAAHhWNBIAAAAAAAAAAIwBAAAH"
40 "AAAAcAAAAAQAAACMAAAAAQAAAJwAAAAAAAAAAAAAAAMAAACoAAAAAgAAAMAAAAAUAQAAAAEAADAB"
41 "AAA4AQAAQAEAAEgBAABNAQAAUgEAAGYBAAADAAAABAAAAAUAAAAGAAAABgAAAAMAAAAAAAAAAAAA"
42 "AAAAAAABAAAAAAAAAAIAAAAAAAAAAAAAAAAAAAACAAAAAAAAAAEAAAAAAAAAdQEAAAAAAAABAAAA"
43 "AAAAAAIAAAAAAAAAAgAAAAAAAAB/AQAAAAAAAAEAAQABAAAAaQEAAAQAAABwEAIAAAAOAAEAAQAB"
44 "AAAAbwEAAAQAAABwEAIAAAAOAAY8aW5pdD4ABkEuamF2YQAGQi5qYXZhAANMQTsAA0xCOwASTGph"
45 "dmEvbGFuZy9PYmplY3Q7AAFWAAQABw48AAQABw48AAAAAQAAgIAEgAIAAAEAAYCABJgCAAAACwAA"
46 "AAAAAAABAAAAAAAAAAEAAAAHAAAAcAAAAAIAAAAEAAAAjAAAAAMAAAABAAAAnAAAAAUAAAADAAAA"
47 "qAAAAAYAAAACAAAAwAAAAAEgAAACAAAAAAEAAAIgAAAHAAAAMAEAAAMgAAACAAAAaQEAAAAgAAAC"
48 "AAAAdQEAAAAQAAABAAAAjAEAAA==";
49
Jeff Haoe17f5892017-02-23 16:14:04 -080050// Dex file with catch handler unreferenced by try blocks.
51// Constructed by building a dex file with try/catch blocks and hex editing.
52static const char kUnreferencedCatchHandlerInputDex[] =
53 "ZGV4CjAzNQD+exd52Y0f9nY5x5GmInXq5nXrO6Kl2RV4AwAAcAAAAHhWNBIAAAAAAAAAANgCAAAS"
54 "AAAAcAAAAAgAAAC4AAAAAwAAANgAAAABAAAA/AAAAAQAAAAEAQAAAQAAACQBAAA0AgAARAEAANYB"
55 "AADeAQAA5gEAAO4BAAAAAgAADwIAACYCAAA9AgAAUQIAAGUCAAB5AgAAfwIAAIUCAACIAgAAjAIA"
56 "AKECAACnAgAArAIAAAQAAAAFAAAABgAAAAcAAAAIAAAACQAAAAwAAAAOAAAADAAAAAYAAAAAAAAA"
57 "DQAAAAYAAADIAQAADQAAAAYAAADQAQAABQABABAAAAAAAAAAAAAAAAAAAgAPAAAAAQABABEAAAAD"
58 "AAAAAAAAAAAAAAABAAAAAwAAAAAAAAADAAAAAAAAAMgCAAAAAAAAAQABAAEAAAC1AgAABAAAAHAQ"
59 "AwAAAA4AAwABAAIAAgC6AgAAIQAAAGIAAAAaAQoAbiACABAAYgAAABoBCwBuIAIAEAAOAA0AYgAA"
60 "ABoBAQBuIAIAEAAo8A0AYgAAABoBAgBuIAIAEAAo7gAAAAAAAAcAAQAHAAAABwABAAIBAg8BAhgA"
61 "AQAAAAQAAAABAAAABwAGPGluaXQ+AAZDYXRjaDEABkNhdGNoMgAQSGFuZGxlclRlc3QuamF2YQAN"
62 "TEhhbmRsZXJUZXN0OwAVTGphdmEvaW8vUHJpbnRTdHJlYW07ABVMamF2YS9sYW5nL0V4Y2VwdGlv"
63 "bjsAEkxqYXZhL2xhbmcvT2JqZWN0OwASTGphdmEvbGFuZy9TdHJpbmc7ABJMamF2YS9sYW5nL1N5"
64 "c3RlbTsABFRyeTEABFRyeTIAAVYAAlZMABNbTGphdmEvbGFuZy9TdHJpbmc7AARtYWluAANvdXQA"
65 "B3ByaW50bG4AAQAHDgAEAQAHDn17AncdHoseAAAAAgAAgYAExAIBCdwCAAANAAAAAAAAAAEAAAAA"
66 "AAAAAQAAABIAAABwAAAAAgAAAAgAAAC4AAAAAwAAAAMAAADYAAAABAAAAAEAAAD8AAAABQAAAAQA"
67 "AAAEAQAABgAAAAEAAAAkAQAAASAAAAIAAABEAQAAARAAAAIAAADIAQAAAiAAABIAAADWAQAAAyAA"
68 "AAIAAAC1AgAAACAAAAEAAADIAgAAABAAAAEAAADYAgAA";
69
Jeff Haoac462712017-03-02 10:59:43 -080070// Dex file with 0-size (catch all only) catch handler unreferenced by try blocks.
71// Constructed by building a dex file with try/catch blocks and hex editing.
72static const char kUnreferenced0SizeCatchHandlerInputDex[] =
73 "ZGV4CjAzNQCEbEEvMstSNpQpjPdfMEfUBS48cis2QRJoAwAAcAAAAHhWNBIAAAAAAAAAAMgCAAAR"
74 "AAAAcAAAAAcAAAC0AAAAAwAAANAAAAABAAAA9AAAAAQAAAD8AAAAAQAAABwBAAAsAgAAPAEAAOoB"
75 "AADyAQAABAIAABMCAAAqAgAAPgIAAFICAABmAgAAaQIAAG0CAACCAgAAhgIAAIoCAACQAgAAlQIA"
76 "AJ4CAACiAgAAAgAAAAMAAAAEAAAABQAAAAYAAAAHAAAACQAAAAcAAAAFAAAAAAAAAAgAAAAFAAAA"
77 "3AEAAAgAAAAFAAAA5AEAAAQAAQANAAAAAAAAAAAAAAAAAAIADAAAAAEAAQAOAAAAAgAAAAAAAAAA"
78 "AAAAAQAAAAIAAAAAAAAAAQAAAAAAAAC5AgAAAAAAAAEAAQABAAAApgIAAAQAAABwEAMAAAAOAAQA"
79 "AQACAAIAqwIAAC8AAABiAAAAGgEPAG4gAgAQAGIAAAAaAQoAbiACABAAYgAAABoBEABuIAIAEABi"
80 "AAAAGgELAG4gAgAQAA4ADQBiAQAAGgIKAG4gAgAhACcADQBiAQAAGgILAG4gAgAhACcAAAAAAAAA"
81 "BwABAA4AAAAHAAEAAgAdACYAAAABAAAAAwAAAAEAAAAGAAY8aW5pdD4AEEhhbmRsZXJUZXN0Lmph"
82 "dmEADUxIYW5kbGVyVGVzdDsAFUxqYXZhL2lvL1ByaW50U3RyZWFtOwASTGphdmEvbGFuZy9PYmpl"
83 "Y3Q7ABJMamF2YS9sYW5nL1N0cmluZzsAEkxqYXZhL2xhbmcvU3lzdGVtOwABVgACVkwAE1tMamF2"
84 "YS9sYW5nL1N0cmluZzsAAmYxAAJmMgAEbWFpbgADb3V0AAdwcmludGxuAAJ0MQACdDIAAQAHDgAE"
85 "AQAHDnl7eXkCeB2bAAAAAgAAgYAEvAIBCdQCAA0AAAAAAAAAAQAAAAAAAAABAAAAEQAAAHAAAAAC"
86 "AAAABwAAALQAAAADAAAAAwAAANAAAAAEAAAAAQAAAPQAAAAFAAAABAAAAPwAAAAGAAAAAQAAABwB"
87 "AAABIAAAAgAAADwBAAABEAAAAgAAANwBAAACIAAAEQAAAOoBAAADIAAAAgAAAKYCAAAAIAAAAQAA"
88 "ALkCAAAAEAAAAQAAAMgCAAA=";
89
Jeff Haoa64a64c2017-03-06 15:05:38 -080090// Dex file with an unreferenced catch handler at end of code item.
91// Constructed by building a dex file with try/catch blocks and hex editing.
92static const char kUnreferencedEndingCatchHandlerInputDex[] =
93 "ZGV4CjAzNQCEflufI6xGTDDRmLpbfYi6ujPrDLIwvYcEBAAAcAAAAHhWNBIAAAAAAAAAAGQDAAAT"
94 "AAAAcAAAAAgAAAC8AAAAAwAAANwAAAABAAAAAAEAAAUAAAAIAQAAAQAAADABAAC0AgAAUAEAAE4C"
95 "AABWAgAAXgIAAGYCAAB4AgAAhwIAAJ4CAAC1AgAAyQIAAN0CAADxAgAA9wIAAP0CAAAAAwAABAMA"
96 "ABkDAAAcAwAAIgMAACcDAAAEAAAABQAAAAYAAAAHAAAACAAAAAkAAAAMAAAADgAAAAwAAAAGAAAA"
97 "AAAAAA0AAAAGAAAAQAIAAA0AAAAGAAAASAIAAAUAAQARAAAAAAAAAAAAAAAAAAAADwAAAAAAAgAQ"
98 "AAAAAQABABIAAAADAAAAAAAAAAAAAAABAAAAAwAAAAAAAAADAAAAAAAAAFADAAAAAAAAAQABAAEA"
99 "AAAwAwAABAAAAHAQBAAAAA4AAgAAAAIAAgA1AwAAIQAAAGIAAAAaAQoAbiADABAAYgAAABoBCwBu"
100 "IAMAEAAOAA0AYgAAABoBAQBuIAMAEAAo8A0AYgAAABoBAgBuIAMAEAAo7gAAAAAAAAcAAQAHAAAA"
101 "BwABAAIBAg8BAhgAAwABAAIAAgBCAwAAIQAAAGIAAAAaAQoAbiADABAAYgAAABoBCwBuIAMAEAAO"
102 "AA0AYgAAABoBAQBuIAMAEAAo8A0AYgAAABoBAgBuIAMAEAAo7gAAAAAAAAcAAQAHAAAABwABAAIB"
103 "Ag8BAhgAAQAAAAQAAAABAAAABwAGPGluaXQ+AAZDYXRjaDEABkNhdGNoMgAQSGFuZGxlclRlc3Qu"
104 "amF2YQANTEhhbmRsZXJUZXN0OwAVTGphdmEvaW8vUHJpbnRTdHJlYW07ABVMamF2YS9sYW5nL0V4"
105 "Y2VwdGlvbjsAEkxqYXZhL2xhbmcvT2JqZWN0OwASTGphdmEvbGFuZy9TdHJpbmc7ABJMamF2YS9s"
106 "YW5nL1N5c3RlbTsABFRyeTEABFRyeTIAAVYAAlZMABNbTGphdmEvbGFuZy9TdHJpbmc7AAFhAARt"
107 "YWluAANvdXQAB3ByaW50bG4AAQAHDgAEAAcOfHsCeB0eih4AEQEABw59ewJ3HR6LHgAAAAMAAIGA"
108 "BNACAQnoAgEJ1AMAAA0AAAAAAAAAAQAAAAAAAAABAAAAEwAAAHAAAAACAAAACAAAALwAAAADAAAA"
109 "AwAAANwAAAAEAAAAAQAAAAABAAAFAAAABQAAAAgBAAAGAAAAAQAAADABAAABIAAAAwAAAFABAAAB"
110 "EAAAAgAAAEACAAACIAAAEwAAAE4CAAADIAAAAwAAADADAAAAIAAAAQAAAFADAAAAEAAAAQAAAGQD"
111 "AAA=";
112
Mathieu Chartier6b0dbef2017-02-21 12:45:30 -0800113// Dex file with multiple code items that have the same debug_info_off_. Constructed by a modified
114// dexlayout on XandY.
115static const char kDexFileDuplicateOffset[] =
116 "ZGV4CjAzNwAQfXfPCB8qCxo7MqdFhmHZQwCv8+udHD8MBAAAcAAAAHhWNBIAAAAAAAAAAFQDAAAT"
117 "AAAAcAAAAAgAAAC8AAAAAQAAANwAAAABAAAA6AAAAAUAAADwAAAAAwAAABgBAACUAgAAeAEAABQC"
118 "AAAeAgAAJgIAACsCAAAyAgAANwIAAFsCAAB7AgAAngIAALICAAC1AgAAvQIAAMUCAADIAgAA1QIA"
119 "AOkCAADvAgAA9QIAAPwCAAACAAAAAwAAAAQAAAAFAAAABgAAAAcAAAAIAAAACQAAAAkAAAAHAAAA"
120 "AAAAAAIAAQASAAAAAAAAAAEAAAABAAAAAQAAAAIAAAAAAAAAAgAAAAEAAAAGAAAAAQAAAAAAAAAA"
121 "AAAABgAAAAAAAAAKAAAAAAAAACsDAAAAAAAAAQAAAAAAAAAGAAAAAAAAAAsAAAD0AQAANQMAAAAA"
122 "AAACAAAAAAAAAAAAAAAAAAAACwAAAAQCAAA/AwAAAAAAAAIAAAAUAwAAGgMAAAEAAAAjAwAAAQAB"
123 "AAEAAAAFAAAABAAAAHAQBAAAAA4AAQABAAEAAAAFAAAABAAAAHAQBAAAAA4AAQAAAAEAAAAFAAAA"
124 "CAAAACIAAQBwEAEAAABpAAAADgABAAEAAQAAAAUAAAAEAAAAcBAAAAAADgB4AQAAAAAAAAAAAAAA"
125 "AAAAhAEAAAAAAAAAAAAAAAAAAAg8Y2xpbml0PgAGPGluaXQ+AANMWDsABUxZJFo7AANMWTsAIkxk"
126 "YWx2aWsvYW5ub3RhdGlvbi9FbmNsb3NpbmdDbGFzczsAHkxkYWx2aWsvYW5ub3RhdGlvbi9Jbm5l"
127 "ckNsYXNzOwAhTGRhbHZpay9hbm5vdGF0aW9uL01lbWJlckNsYXNzZXM7ABJMamF2YS9sYW5nL09i"
128 "amVjdDsAAVYABlguamF2YQAGWS5qYXZhAAFaAAthY2Nlc3NGbGFncwASZW1pdHRlcjogamFjay00"
129 "LjI1AARuYW1lAAR0aGlzAAV2YWx1ZQABegARAAcOABMABw4AEgAHDnYAEQAHDgACAwERGAICBAIN"
130 "BAgPFwwCBQERHAEYAQAAAQAAgIAEjAMAAAEAAYCABKQDAQACAAAIAoiABLwDAYCABNwDAAAADwAA"
131 "AAAAAAABAAAAAAAAAAEAAAATAAAAcAAAAAIAAAAIAAAAvAAAAAMAAAABAAAA3AAAAAQAAAABAAAA"
132 "6AAAAAUAAAAFAAAA8AAAAAYAAAADAAAAGAEAAAMQAAACAAAAeAEAAAEgAAAEAAAAjAEAAAYgAAAC"
133 "AAAA9AEAAAIgAAATAAAAFAIAAAMgAAAEAAAA/wIAAAQgAAADAAAAFAMAAAAgAAADAAAAKwMAAAAQ"
134 "AAABAAAAVAMAAA==";
135
Jeff Haof914f8e2017-02-21 16:14:23 -0800136// Dex file with null value for annotations_off in the annotation_set_ref_list.
137// Constructed by building a dex file with annotations and hex editing.
138static const char kNullSetRefListElementInputDex[] =
139 "ZGV4CjAzNQB1iA+7ZwgkF+7E6ZesYFc2lRAR3qnRAanwAwAAcAAAAHhWNBIAAAAAAAAAACADAAAS"
140 "AAAAcAAAAAgAAAC4AAAAAwAAANgAAAABAAAA/AAAAAQAAAAEAQAAAgAAACQBAACMAgAAZAEAAOgB"
141 "AADwAQAAAAIAAAMCAAAQAgAAIAIAADQCAABIAgAAawIAAI0CAAC1AgAAyAIAANECAADUAgAA2QIA"
142 "ANwCAADjAgAA6QIAAAMAAAAEAAAABQAAAAYAAAAHAAAACAAAAAkAAAAMAAAAAgAAAAMAAAAAAAAA"
143 "DAAAAAcAAAAAAAAADQAAAAcAAADgAQAABgAGAAsAAAAAAAEAAAAAAAAAAgAOAAAAAQAAABAAAAAC"
144 "AAEAAAAAAAAAAAAAAAAAAgAAAAAAAAABAAAAsAEAAAgDAAAAAAAAAQAAAAEmAAACAAAA2AEAAAoA"
145 "AADIAQAAFgMAAAAAAAACAAAAAAAAAHwBAAABAAAA/AIAAAAAAAABAAAAAgMAAAEAAQABAAAA8AIA"
146 "AAQAAABwEAMAAAAOAAIAAgAAAAAA9QIAAAEAAAAOAAAAAAAAAAAAAAAAAAAAAQAAAAEAAABkAQAA"
147 "cAEAAAAAAAAAAAAAAAAAAAEAAAAEAAAAAgAAAAMAAwAGPGluaXQ+AA5Bbm5vQ2xhc3MuamF2YQAB"
148 "TAALTEFubm9DbGFzczsADkxNeUFubm90YXRpb247ABJMamF2YS9sYW5nL09iamVjdDsAEkxqYXZh"
149 "L2xhbmcvU3RyaW5nOwAhTGphdmEvbGFuZy9hbm5vdGF0aW9uL0Fubm90YXRpb247ACBMamF2YS9s"
150 "YW5nL2Fubm90YXRpb24vUmV0ZW50aW9uOwAmTGphdmEvbGFuZy9hbm5vdGF0aW9uL1JldGVudGlv"
151 "blBvbGljeTsAEU15QW5ub3RhdGlvbi5qYXZhAAdSVU5USU1FAAFWAANWTEwAAWEABWFOYW1lAARu"
152 "YW1lAAV2YWx1ZQABAAcOAAICAAAHDgABBQERGwABAQEQFw8AAAIAAICABIQDAQmcAwAAAAECgQgA"
153 "AAARAAAAAAAAAAEAAAAAAAAAAQAAABIAAABwAAAAAgAAAAgAAAC4AAAAAwAAAAMAAADYAAAABAAA"
154 "AAEAAAD8AAAABQAAAAQAAAAEAQAABgAAAAIAAAAkAQAAAhAAAAEAAABkAQAAAxAAAAMAAABwAQAA"
155 "ASAAAAIAAACEAQAABiAAAAIAAACwAQAAARAAAAIAAADYAQAAAiAAABIAAADoAQAAAyAAAAIAAADw"
156 "AgAABCAAAAIAAAD8AgAAACAAAAIAAAAIAwAAABAAAAEAAAAgAwAA";
157
Jeff Haoe17f5892017-02-23 16:14:04 -0800158// Dex file with shared empty class data item for multiple class defs.
159// Constructing by building a dex file with multiple classes and hex editing.
160static const char kMultiClassDataInputDex[] =
161 "ZGV4CjAzNQALJgF9TtnLq748xVe/+wyxETrT9lTEiW6YAQAAcAAAAHhWNBIAAAAAAAAAADQBAAAI"
162 "AAAAcAAAAAQAAACQAAAAAAAAAAAAAAACAAAAoAAAAAAAAAAAAAAAAgAAALAAAACoAAAA8AAAAPAA"
163 "AAD4AAAAAAEAAAMBAAAIAQAADQEAACEBAAAkAQAAAgAAAAMAAAAEAAAABQAAAAEAAAAGAAAAAgAA"
164 "AAcAAAABAAAAAQYAAAMAAAAAAAAAAAAAAAAAAAAnAQAAAAAAAAIAAAABBgAAAwAAAAAAAAABAAAA"
165 "AAAAACcBAAAAAAAABkEuamF2YQAGQi5qYXZhAAFJAANMQTsAA0xCOwASTGphdmEvbGFuZy9PYmpl"
166 "Y3Q7AAFhAAFiAAAAAAABAAAAARkAAAAIAAAAAAAAAAEAAAAAAAAAAQAAAAgAAABwAAAAAgAAAAQA"
167 "AACQAAAABAAAAAIAAACgAAAABgAAAAIAAACwAAAAAiAAAAgAAADwAAAAACAAAAIAAAAnAQAAABAA"
168 "AAEAAAA0AQAA";
169
170// Dex file with code info followed by non 4-byte aligned section.
171// Constructed a dex file with code info followed by string data and hex edited.
172static const char kUnalignedCodeInfoInputDex[] =
173 "ZGV4CjAzNQDXJzXNb4iWn2SLhmLydW/8h1K9moERIw7UAQAAcAAAAHhWNBIAAAAAAAAAAEwBAAAG"
174 "AAAAcAAAAAMAAACIAAAAAQAAAJQAAAAAAAAAAAAAAAMAAACgAAAAAQAAALgAAAD8AAAA2AAAAAIB"
175 "AAAKAQAAEgEAABcBAAArAQAALgEAAAIAAAADAAAABAAAAAQAAAACAAAAAAAAAAAAAAAAAAAAAAAA"
176 "AAUAAAABAAAAAAAAAAAAAAABAAAAAQAAAAAAAAABAAAAAAAAADsBAAAAAAAAAQABAAEAAAAxAQAA"
177 "BAAAAHAQAgAAAA4AAQABAAAAAAA2AQAAAQAAAA4ABjxpbml0PgAGQS5qYXZhAANMQTsAEkxqYXZh"
178 "L2xhbmcvT2JqZWN0OwABVgABYQABAAcOAAMABw4AAAABAQCBgATYAQEB8AEAAAALAAAAAAAAAAEA"
179 "AAAAAAAAAQAAAAYAAABwAAAAAgAAAAMAAACIAAAAAwAAAAEAAACUAAAABQAAAAMAAACgAAAABgAA"
180 "AAEAAAC4AAAAASAAAAIAAADYAAAAAiAAAAYAAAACAQAAAyAAAAIAAAAxAQAAACAAAAEAAAA7AQAA"
181 "ABAAAAEAAABMAQAA";
Jeff Hao44652a32017-02-22 14:20:41 -0800182
Jeff Hao32a60ab2017-03-01 16:44:50 -0800183// Dex file with class data section preceding code items.
184// Constructed by passing dex file through dexmerger tool and hex editing.
185static const char kClassDataBeforeCodeInputDex[] =
186 "ZGV4CjAzNQCZKmCu3XXn4zvxCh5VH0gZNNobEAcsc49EAgAAcAAAAHhWNBIAAAAAAAAAAAQBAAAJ"
187 "AAAAcAAAAAQAAACUAAAAAgAAAKQAAAAAAAAAAAAAAAUAAAC8AAAAAQAAAOQAAABAAQAABAEAAPgB"
188 "AAAAAgAACAIAAAsCAAAQAgAAJAIAACcCAAAqAgAALQIAAAIAAAADAAAABAAAAAUAAAACAAAAAAAA"
189 "AAAAAAAFAAAAAwAAAAAAAAABAAEAAAAAAAEAAAAGAAAAAQAAAAcAAAABAAAACAAAAAIAAQAAAAAA"
190 "AQAAAAEAAAACAAAAAAAAAAEAAAAAAAAAjAEAAAAAAAALAAAAAAAAAAEAAAAAAAAAAQAAAAkAAABw"
191 "AAAAAgAAAAQAAACUAAAAAwAAAAIAAACkAAAABQAAAAUAAAC8AAAABgAAAAEAAADkAAAAABAAAAEA"
192 "AAAEAQAAACAAAAEAAACMAQAAASAAAAQAAACkAQAAAiAAAAkAAAD4AQAAAyAAAAQAAAAwAgAAAAAB"
193 "AwCBgASkAwEBvAMBAdADAQHkAwAAAQABAAEAAAAwAgAABAAAAHAQBAAAAA4AAgABAAAAAAA1AgAA"
194 "AgAAABIQDwACAAEAAAAAADoCAAACAAAAEiAPAAIAAQAAAAAAPwIAAAIAAAASMA8ABjxpbml0PgAG"
195 "QS5qYXZhAAFJAANMQTsAEkxqYXZhL2xhbmcvT2JqZWN0OwABVgABYQABYgABYwABAAcOAAMABw4A"
196 "BgAHDgAJAAcOAA==";
197
Jeff Haod9be7682017-04-05 09:29:43 -0700198// Dex file with local info containing a null type descriptor.
199// Constructed a dex file with debug info sequence containing DBG_RESTART_LOCAL without any
200// DBG_START_LOCAL to give it a declared type.
201static const char kUnknownTypeDebugInfoInputDex[] =
202 "ZGV4CjAzNQBtKqZfzjHLNSNwW2A6Bz9FuCEX0sL+FF38AQAAcAAAAHhWNBIAAAAAAAAAAHQBAAAI"
203 "AAAAcAAAAAQAAACQAAAAAgAAAKAAAAAAAAAAAAAAAAMAAAC4AAAAAQAAANAAAAAMAQAA8AAAABwB"
204 "AAAkAQAALAEAAC8BAAA0AQAASAEAAEsBAABOAQAAAgAAAAMAAAAEAAAABQAAAAIAAAAAAAAAAAAA"
205 "AAUAAAADAAAAAAAAAAEAAQAAAAAAAQAAAAYAAAACAAEAAAAAAAEAAAABAAAAAgAAAAAAAAABAAAA"
206 "AAAAAGMBAAAAAAAAAQABAAEAAABUAQAABAAAAHAQAgAAAA4AAgABAAAAAABZAQAAAgAAABIQDwAG"
207 "PGluaXQ+AAZBLmphdmEAAUkAA0xBOwASTGphdmEvbGFuZy9PYmplY3Q7AAFWAAFhAAR0aGlzAAEA"
208 "Bw4AAwAHDh4GAAYAAAAAAQEAgYAE8AEBAYgCAAAACwAAAAAAAAABAAAAAAAAAAEAAAAIAAAAcAAA"
209 "AAIAAAAEAAAAkAAAAAMAAAACAAAAoAAAAAUAAAADAAAAuAAAAAYAAAABAAAA0AAAAAEgAAACAAAA"
210 "8AAAAAIgAAAIAAAAHAEAAAMgAAACAAAAVAEAAAAgAAABAAAAYwEAAAAQAAABAAAAdAEAAA==";
211
Jeff Haod212d5b2017-04-26 12:09:06 -0700212// Dex file with multiple class data items pointing to the same code item.
213// Constructed by hex editing.
214static const char kDuplicateCodeItemInputDex[] =
215 "ZGV4CjAzNQCwKtVglQOmLWuHwldN5jkBOInC7mTMhJMAAgAAcAAAAHhWNBIAAAAAAAAAAHgBAAAH"
216 "AAAAcAAAAAMAAACMAAAAAQAAAJgAAAAAAAAAAAAAAAQAAACkAAAAAQAAAMQAAAAcAQAA5AAAACQB"
217 "AAAsAQAANAEAADkBAABNAQAAUAEAAFMBAAACAAAAAwAAAAQAAAAEAAAAAgAAAAAAAAAAAAAAAAAA"
218 "AAAAAAAFAAAAAAAAAAYAAAABAAAAAAAAAAAAAAABAAAAAQAAAAAAAAABAAAAAAAAAGUBAAAAAAAA"
219 "AQABAAEAAABWAQAABAAAAHAQAwAAAA4AAQABAAAAAABbAQAAAQAAAA4AAAABAAEAAAAAAGABAAAB"
220 "AAAADgAAAAY8aW5pdD4ABkEuamF2YQADTEE7ABJMamF2YS9sYW5nL09iamVjdDsAAVYAAWEAAWIA"
221 "AQAHDgADAAcOAAUABw4AAAABAgCBgATkAQEA/AEBAPwBAAsAAAAAAAAAAQAAAAAAAAABAAAABwAA"
222 "AHAAAAACAAAAAwAAAIwAAAADAAAAAQAAAJgAAAAFAAAABAAAAKQAAAAGAAAAAQAAAMQAAAABIAAA"
223 "AwAAAOQAAAACIAAABwAAACQBAAADIAAAAwAAAFYBAAAAIAAAAQAAAGUBAAAAEAAAAQAAAHgBAAA=";
224
Mathieu Chartiera27af082018-02-03 16:12:23 -0800225// Returns the default compact dex option for dexlayout based on kDefaultCompactDexLevel.
226static std::vector<std::string> DefaultCompactDexOption() {
227 return (kDefaultCompactDexLevel == CompactDexLevel::kCompactDexLevelFast) ?
228 std::vector<std::string>{"-x", "fast"} : std::vector<std::string>{"-x", "none"};
229}
230
Mathieu Chartier6b0dbef2017-02-21 12:45:30 -0800231static void WriteBase64ToFile(const char* base64, File* file) {
Jeff Hao042e8982016-10-19 11:17:11 -0700232 // Decode base64.
233 CHECK(base64 != nullptr);
234 size_t length;
235 std::unique_ptr<uint8_t[]> bytes(DecodeBase64(base64, &length));
Mathieu Chartier6b0dbef2017-02-21 12:45:30 -0800236 CHECK(bytes != nullptr);
Jeff Hao042e8982016-10-19 11:17:11 -0700237 if (!file->WriteFully(bytes.get(), length)) {
238 PLOG(FATAL) << "Failed to write base64 as file";
239 }
Mathieu Chartier6b0dbef2017-02-21 12:45:30 -0800240}
241
242static void WriteFileBase64(const char* base64, const char* location) {
243 // Write to provided file.
244 std::unique_ptr<File> file(OS::CreateEmptyFile(location));
245 CHECK(file != nullptr);
246 WriteBase64ToFile(base64, file.get());
Jeff Hao042e8982016-10-19 11:17:11 -0700247 if (file->FlushCloseOrErase() != 0) {
248 PLOG(FATAL) << "Could not flush and close test file.";
249 }
250}
251
Jeff Haoc3acfc52016-08-29 14:18:26 -0700252class DexLayoutTest : public CommonRuntimeTest {
253 protected:
Andreas Gampe693bfbf2017-11-10 12:23:31 -0800254 std::string GetDexLayoutPath() {
255 return GetTestAndroidRoot() + "/bin/dexlayoutd";
Jeff Haoc3acfc52016-08-29 14:18:26 -0700256 }
257
Jeff Haoa8621002016-10-04 18:13:44 +0000258 // Runs FullPlainOutput test.
259 bool FullPlainOutputExec(std::string* error_msg) {
Jeff Haoc3acfc52016-08-29 14:18:26 -0700260 // TODO: dexdump2 -> dexdump ?
261 ScratchFile dexdump_output;
Andreas Gampeca620d72016-11-08 08:09:33 -0800262 const std::string& dexdump_filename = dexdump_output.GetFilename();
Jeff Haoc3acfc52016-08-29 14:18:26 -0700263 std::string dexdump = GetTestAndroidRoot() + "/bin/dexdump2";
264 EXPECT_TRUE(OS::FileExists(dexdump.c_str())) << dexdump << " should be a valid file path";
Jeff Haoc3acfc52016-08-29 14:18:26 -0700265
266 ScratchFile dexlayout_output;
Andreas Gampeca620d72016-11-08 08:09:33 -0800267 const std::string& dexlayout_filename = dexlayout_output.GetFilename();
Jeff Haoc3acfc52016-08-29 14:18:26 -0700268
Jeff Haoa8621002016-10-04 18:13:44 +0000269 for (const std::string &dex_file : GetLibCoreDexFileNames()) {
270 std::vector<std::string> dexdump_exec_argv =
271 { dexdump, "-d", "-f", "-h", "-l", "plain", "-o", dexdump_filename, dex_file };
Andreas Gampe693bfbf2017-11-10 12:23:31 -0800272 std::vector<std::string> dexlayout_args =
273 { "-d", "-f", "-h", "-l", "plain", "-o", dexlayout_filename, dex_file };
Jeff Haoa8621002016-10-04 18:13:44 +0000274 if (!::art::Exec(dexdump_exec_argv, error_msg)) {
275 return false;
276 }
Andreas Gampe693bfbf2017-11-10 12:23:31 -0800277 if (!DexLayoutExec(dexlayout_args, error_msg)) {
Jeff Haoa8621002016-10-04 18:13:44 +0000278 return false;
279 }
280 std::vector<std::string> diff_exec_argv =
281 { "/usr/bin/diff", dexdump_filename, dexlayout_filename };
282 if (!::art::Exec(diff_exec_argv, error_msg)) {
283 return false;
284 }
Jeff Haoc3acfc52016-08-29 14:18:26 -0700285 }
286 return true;
287 }
288
Jeff Haoa8621002016-10-04 18:13:44 +0000289 // Runs DexFileOutput test.
290 bool DexFileOutputExec(std::string* error_msg) {
291 ScratchFile tmp_file;
Andreas Gampeca620d72016-11-08 08:09:33 -0800292 const std::string& tmp_name = tmp_file.GetFilename();
293 size_t tmp_last_slash = tmp_name.rfind('/');
Jeff Haoa8621002016-10-04 18:13:44 +0000294 std::string tmp_dir = tmp_name.substr(0, tmp_last_slash + 1);
Jeff Haoa8621002016-10-04 18:13:44 +0000295
296 for (const std::string &dex_file : GetLibCoreDexFileNames()) {
Andreas Gampe693bfbf2017-11-10 12:23:31 -0800297 std::vector<std::string> dexlayout_args =
298 { "-w", tmp_dir, "-o", tmp_name, dex_file };
Mathieu Chartiera27af082018-02-03 16:12:23 -0800299 if (!DexLayoutExec(dexlayout_args, error_msg, /*pass_default_cdex_option*/ false)) {
Jeff Haoa8621002016-10-04 18:13:44 +0000300 return false;
301 }
Andreas Gampe5555dd12017-08-24 13:50:21 -0700302 size_t dex_file_last_slash = dex_file.rfind('/');
Jeff Haoa8621002016-10-04 18:13:44 +0000303 std::string dex_file_name = dex_file.substr(dex_file_last_slash + 1);
304 std::vector<std::string> unzip_exec_argv =
305 { "/usr/bin/unzip", dex_file, "classes.dex", "-d", tmp_dir};
306 if (!::art::Exec(unzip_exec_argv, error_msg)) {
307 return false;
308 }
309 std::vector<std::string> diff_exec_argv =
310 { "/usr/bin/diff", tmp_dir + "classes.dex" , tmp_dir + dex_file_name };
311 if (!::art::Exec(diff_exec_argv, error_msg)) {
312 return false;
313 }
Orion Hodson98273672018-02-06 11:50:27 +0000314 if (!UnlinkFile(tmp_dir + "classes.dex")) {
Jeff Haoa8621002016-10-04 18:13:44 +0000315 return false;
316 }
Orion Hodson98273672018-02-06 11:50:27 +0000317 if (!UnlinkFile(tmp_dir + dex_file_name)) {
Jeff Haoa8621002016-10-04 18:13:44 +0000318 return false;
319 }
320 }
Jeff Hao042e8982016-10-19 11:17:11 -0700321 return true;
322 }
Jeff Haoa8621002016-10-04 18:13:44 +0000323
Mathieu Chartierd00e02b2017-05-24 12:04:13 -0700324 // Create a profile with some subset of methods and classes.
325 void CreateProfile(const std::string& input_dex,
326 const std::string& out_profile,
327 const std::string& dex_location) {
328 std::vector<std::unique_ptr<const DexFile>> dex_files;
329 std::string error_msg;
David Sehr013fd802018-01-11 22:55:24 -0800330 const ArtDexFileLoader dex_file_loader;
331 bool result = dex_file_loader.Open(input_dex.c_str(),
332 input_dex,
333 /*verify*/ true,
334 /*verify_checksum*/ false,
335 &error_msg,
336 &dex_files);
Mathieu Chartierd00e02b2017-05-24 12:04:13 -0700337
338 ASSERT_TRUE(result) << error_msg;
339 ASSERT_GE(dex_files.size(), 1u);
340
341 size_t profile_methods = 0;
342 size_t profile_classes = 0;
343 ProfileCompilationInfo pfi;
Mathieu Chartierd00e02b2017-05-24 12:04:13 -0700344 std::set<DexCacheResolvedClasses> classes;
345 for (const std::unique_ptr<const DexFile>& dex_file : dex_files) {
346 for (uint32_t i = 0; i < dex_file->NumMethodIds(); i += 2) {
Mathieu Chartierbbe3a5e2017-06-13 16:36:17 -0700347 uint8_t flags = 0u;
348
Mathieu Chartierd00e02b2017-05-24 12:04:13 -0700349 if ((i & 3) != 0) {
Mathieu Chartierbbe3a5e2017-06-13 16:36:17 -0700350 flags |= ProfileCompilationInfo::MethodHotness::kFlagHot;
Mathieu Chartierea650f32017-05-24 12:04:13 -0700351 ++profile_methods;
352 } else if ((i & 2) != 0) {
Mathieu Chartierbbe3a5e2017-06-13 16:36:17 -0700353 flags |= ProfileCompilationInfo::MethodHotness::kFlagStartup;
Mathieu Chartierd00e02b2017-05-24 12:04:13 -0700354 ++profile_methods;
355 }
Mathieu Chartierbbe3a5e2017-06-13 16:36:17 -0700356 pfi.AddMethodIndex(static_cast<ProfileCompilationInfo::MethodHotness::Flag>(flags),
357 dex_location,
358 dex_file->GetLocationChecksum(),
359 /*dex_method_idx*/i,
360 dex_file->NumMethodIds());
Mathieu Chartierd00e02b2017-05-24 12:04:13 -0700361 }
362 DexCacheResolvedClasses cur_classes(dex_location,
363 dex_location,
Mathieu Chartierea650f32017-05-24 12:04:13 -0700364 dex_file->GetLocationChecksum(),
365 dex_file->NumMethodIds());
Mathieu Chartierd00e02b2017-05-24 12:04:13 -0700366 // Add every even class too.
367 for (uint32_t i = 0; i < dex_file->NumClassDefs(); i += 1) {
Mathieu Chartierea650f32017-05-24 12:04:13 -0700368 if ((i & 2) == 0) {
369 cur_classes.AddClass(dex_file->GetClassDef(i).class_idx_);
370 ++profile_classes;
371 }
Mathieu Chartierd00e02b2017-05-24 12:04:13 -0700372 }
Mathieu Chartierea650f32017-05-24 12:04:13 -0700373 classes.insert(cur_classes);
Mathieu Chartierd00e02b2017-05-24 12:04:13 -0700374 }
Mathieu Chartierbbe3a5e2017-06-13 16:36:17 -0700375 pfi.AddClasses(classes);
Mathieu Chartierd00e02b2017-05-24 12:04:13 -0700376 // Write to provided file.
377 std::unique_ptr<File> file(OS::CreateEmptyFile(out_profile.c_str()));
378 ASSERT_TRUE(file != nullptr);
379 pfi.Save(file->Fd());
380 if (file->FlushCloseOrErase() != 0) {
381 PLOG(FATAL) << "Could not flush and close test file.";
382 }
383 EXPECT_GE(profile_methods, 0u);
384 EXPECT_GE(profile_classes, 0u);
385 }
386
Jeff Haod9be7682017-04-05 09:29:43 -0700387 // Runs DexFileLayout test.
Jeff Hao042e8982016-10-19 11:17:11 -0700388 bool DexFileLayoutExec(std::string* error_msg) {
389 ScratchFile tmp_file;
Andreas Gampe641a4732017-08-24 13:21:35 -0700390 const std::string& tmp_name = tmp_file.GetFilename();
Andreas Gampe5555dd12017-08-24 13:50:21 -0700391 size_t tmp_last_slash = tmp_name.rfind('/');
Jeff Hao042e8982016-10-19 11:17:11 -0700392 std::string tmp_dir = tmp_name.substr(0, tmp_last_slash + 1);
393
394 // Write inputs and expected outputs.
395 std::string dex_file = tmp_dir + "classes.dex";
396 WriteFileBase64(kDexFileLayoutInputDex, dex_file.c_str());
397 std::string profile_file = tmp_dir + "primary.prof";
Mathieu Chartierd00e02b2017-05-24 12:04:13 -0700398 CreateProfile(dex_file, profile_file, dex_file);
399 // WriteFileBase64(kDexFileLayoutInputProfile, profile_file.c_str());
Jeff Hao042e8982016-10-19 11:17:11 -0700400 std::string output_dex = tmp_dir + "classes.dex.new";
401
Andreas Gampe693bfbf2017-11-10 12:23:31 -0800402 std::vector<std::string> dexlayout_args =
403 { "-v", "-w", tmp_dir, "-o", tmp_name, "-p", profile_file, dex_file };
404 if (!DexLayoutExec(dexlayout_args, error_msg)) {
Jeff Hao042e8982016-10-19 11:17:11 -0700405 return false;
406 }
Mathieu Chartierfa0aa092017-03-27 15:43:54 -0700407
408 // -v makes sure that the layout did not corrupt the dex file.
Orion Hodson98273672018-02-06 11:50:27 +0000409 if (!UnlinkFile(dex_file) || !UnlinkFile(profile_file) || !UnlinkFile(output_dex)) {
Jeff Hao042e8982016-10-19 11:17:11 -0700410 return false;
411 }
Jeff Haoa8621002016-10-04 18:13:44 +0000412 return true;
413 }
Jeff Hao44652a32017-02-22 14:20:41 -0800414
Bharadwaj Kalandhabhatta02ef6402017-05-17 17:13:39 -0700415 // Runs DexFileLayout test twice (second time is run on output of first time)
416 // for behavior consistency.
417 bool DexFileLayoutFixedPointExec(std::string* error_msg) {
418 ScratchFile tmp_file;
Andreas Gampe641a4732017-08-24 13:21:35 -0700419 const std::string& tmp_name = tmp_file.GetFilename();
Andreas Gampe5555dd12017-08-24 13:50:21 -0700420 size_t tmp_last_slash = tmp_name.rfind('/');
Bharadwaj Kalandhabhatta02ef6402017-05-17 17:13:39 -0700421 std::string tmp_dir = tmp_name.substr(0, tmp_last_slash + 1);
422
Mathieu Chartierd00e02b2017-05-24 12:04:13 -0700423 // Unzip the test dex file to the classes.dex destination. It is required to unzip since
424 // opening from jar recalculates the dex location checksum.
Bharadwaj Kalandhabhatta02ef6402017-05-17 17:13:39 -0700425 std::string dex_file = tmp_dir + "classes.dex";
Mathieu Chartierd00e02b2017-05-24 12:04:13 -0700426
427 std::vector<std::string> unzip_args = {
428 "/usr/bin/unzip",
429 GetTestDexFileName("ManyMethods"),
430 "classes.dex",
431 "-d",
432 tmp_dir,
433 };
434 if (!art::Exec(unzip_args, error_msg)) {
435 LOG(ERROR) << "Failed to unzip dex";
436 return false;
437 }
438
Bharadwaj Kalandhabhatta02ef6402017-05-17 17:13:39 -0700439 std::string profile_file = tmp_dir + "primary.prof";
Mathieu Chartierd00e02b2017-05-24 12:04:13 -0700440 CreateProfile(dex_file, profile_file, dex_file);
Bharadwaj Kalandhabhatta02ef6402017-05-17 17:13:39 -0700441 std::string output_dex = tmp_dir + "classes.dex.new";
442 std::string second_output_dex = tmp_dir + "classes.dex.new.new";
443
Bharadwaj Kalandhabhatta02ef6402017-05-17 17:13:39 -0700444 // -v makes sure that the layout did not corrupt the dex file.
Andreas Gampe693bfbf2017-11-10 12:23:31 -0800445 std::vector<std::string> dexlayout_args =
446 { "-i", "-v", "-w", tmp_dir, "-o", tmp_name, "-p", profile_file, dex_file };
Mathieu Chartiera27af082018-02-03 16:12:23 -0800447 if (!DexLayoutExec(dexlayout_args, error_msg, /*pass_default_cdex_option*/ false)) {
Bharadwaj Kalandhabhatta02ef6402017-05-17 17:13:39 -0700448 return false;
449 }
450
Mathieu Chartierd00e02b2017-05-24 12:04:13 -0700451 // Recreate the profile with the new dex location. This is required so that the profile dex
452 // location matches.
453 CreateProfile(dex_file, profile_file, output_dex);
454
Bharadwaj Kalandhabhatta02ef6402017-05-17 17:13:39 -0700455 // -v makes sure that the layout did not corrupt the dex file.
Mathieu Chartierd00e02b2017-05-24 12:04:13 -0700456 // -i since the checksum won't match from the first layout.
Andreas Gampe693bfbf2017-11-10 12:23:31 -0800457 std::vector<std::string> second_dexlayout_args =
458 { "-i", "-v", "-w", tmp_dir, "-o", tmp_name, "-p", profile_file, output_dex };
Mathieu Chartiera27af082018-02-03 16:12:23 -0800459 if (!DexLayoutExec(second_dexlayout_args, error_msg, /*pass_default_cdex_option*/ false)) {
Bharadwaj Kalandhabhatta02ef6402017-05-17 17:13:39 -0700460 return false;
461 }
462
463 bool diff_result = true;
464 std::vector<std::string> diff_exec_argv =
465 { "/usr/bin/diff", output_dex, second_output_dex };
466 if (!::art::Exec(diff_exec_argv, error_msg)) {
467 diff_result = false;
468 }
469
Orion Hodson98273672018-02-06 11:50:27 +0000470 std::vector<std::string> test_files = { dex_file, profile_file, output_dex, second_output_dex };
471 for (auto test_file : test_files) {
472 if (!UnlinkFile(test_file)) {
473 return false;
474 }
Bharadwaj Kalandhabhatta02ef6402017-05-17 17:13:39 -0700475 }
476
477 return diff_result;
478 }
479
Jeff Haoac462712017-03-02 10:59:43 -0800480 // Runs UnreferencedCatchHandlerTest & Unreferenced0SizeCatchHandlerTest.
481 bool UnreferencedCatchHandlerExec(std::string* error_msg, const char* filename) {
Jeff Hao44652a32017-02-22 14:20:41 -0800482 ScratchFile tmp_file;
Andreas Gampe641a4732017-08-24 13:21:35 -0700483 const std::string& tmp_name = tmp_file.GetFilename();
Andreas Gampe5555dd12017-08-24 13:50:21 -0700484 size_t tmp_last_slash = tmp_name.rfind('/');
Jeff Hao44652a32017-02-22 14:20:41 -0800485 std::string tmp_dir = tmp_name.substr(0, tmp_last_slash + 1);
486
487 // Write inputs and expected outputs.
488 std::string input_dex = tmp_dir + "classes.dex";
Jeff Haoac462712017-03-02 10:59:43 -0800489 WriteFileBase64(filename, input_dex.c_str());
Jeff Hao44652a32017-02-22 14:20:41 -0800490 std::string output_dex = tmp_dir + "classes.dex.new";
491
Andreas Gampe693bfbf2017-11-10 12:23:31 -0800492 std::vector<std::string> dexlayout_args = { "-w", tmp_dir, "-o", "/dev/null", input_dex };
Mathieu Chartiera27af082018-02-03 16:12:23 -0800493 if (!DexLayoutExec(dexlayout_args, error_msg, /*pass_default_cdex_option*/ false)) {
Jeff Hao44652a32017-02-22 14:20:41 -0800494 return false;
495 }
496
497 // Diff input and output. They should be the same.
498 std::vector<std::string> diff_exec_argv = { "/usr/bin/diff", input_dex, output_dex };
499 if (!::art::Exec(diff_exec_argv, error_msg)) {
500 return false;
501 }
502
Orion Hodson98273672018-02-06 11:50:27 +0000503 std::vector<std::string> dex_files = { input_dex, output_dex };
504 for (auto dex_file : dex_files) {
505 if (!UnlinkFile(dex_file)) {
506 return false;
507 }
Jeff Hao44652a32017-02-22 14:20:41 -0800508 }
509 return true;
510 }
Jeff Haod9be7682017-04-05 09:29:43 -0700511
512 bool DexLayoutExec(ScratchFile* dex_file,
513 const char* dex_filename,
514 ScratchFile* profile_file,
Andreas Gampe693bfbf2017-11-10 12:23:31 -0800515 const std::vector<std::string>& dexlayout_args) {
Mathieu Chartieraf7c9022017-10-27 09:42:46 -0700516 if (dex_filename != nullptr) {
517 WriteBase64ToFile(dex_filename, dex_file->GetFile());
518 EXPECT_EQ(dex_file->GetFile()->Flush(), 0);
519 }
Jeff Haod9be7682017-04-05 09:29:43 -0700520 if (profile_file != nullptr) {
Mathieu Chartierd00e02b2017-05-24 12:04:13 -0700521 CreateProfile(dex_file->GetFilename(), profile_file->GetFilename(), dex_file->GetFilename());
Jeff Haod9be7682017-04-05 09:29:43 -0700522 }
Andreas Gampe693bfbf2017-11-10 12:23:31 -0800523
Jeff Haod9be7682017-04-05 09:29:43 -0700524 std::string error_msg;
Andreas Gampe693bfbf2017-11-10 12:23:31 -0800525 const bool result = DexLayoutExec(dexlayout_args, &error_msg);
Jeff Haod9be7682017-04-05 09:29:43 -0700526 if (!result) {
527 LOG(ERROR) << "Error: " << error_msg;
528 return false;
529 }
530 return true;
531 }
Andreas Gampe693bfbf2017-11-10 12:23:31 -0800532
Mathieu Chartiera27af082018-02-03 16:12:23 -0800533 bool DexLayoutExec(const std::vector<std::string>& dexlayout_args,
534 std::string* error_msg,
535 bool pass_default_cdex_option = true) {
Andreas Gampe693bfbf2017-11-10 12:23:31 -0800536 std::vector<std::string> argv;
537
538 std::string dexlayout = GetDexLayoutPath();
539 CHECK(OS::FileExists(dexlayout.c_str())) << dexlayout << " should be a valid file path";
540 argv.push_back(dexlayout);
Mathieu Chartiera27af082018-02-03 16:12:23 -0800541 if (pass_default_cdex_option) {
542 std::vector<std::string> cdex_level = DefaultCompactDexOption();
543 argv.insert(argv.end(), cdex_level.begin(), cdex_level.end());
544 }
Andreas Gampe693bfbf2017-11-10 12:23:31 -0800545
546 argv.insert(argv.end(), dexlayout_args.begin(), dexlayout_args.end());
547
548 return ::art::Exec(argv, error_msg);
549 }
Orion Hodson98273672018-02-06 11:50:27 +0000550
551 bool UnlinkFile(const std::string& file_path) {
552 return unix_file::FdFile(file_path, 0, false).Unlink();
553 }
Jeff Haoc3acfc52016-08-29 14:18:26 -0700554};
555
556
557TEST_F(DexLayoutTest, FullPlainOutput) {
Jeff Hao0f7eaeb2016-08-31 17:56:13 -0700558 // Disable test on target.
559 TEST_DISABLED_FOR_TARGET();
Jeff Haoc3acfc52016-08-29 14:18:26 -0700560 std::string error_msg;
Jeff Haoa8621002016-10-04 18:13:44 +0000561 ASSERT_TRUE(FullPlainOutputExec(&error_msg)) << error_msg;
562}
563
564TEST_F(DexLayoutTest, DexFileOutput) {
565 // Disable test on target.
566 TEST_DISABLED_FOR_TARGET();
567 std::string error_msg;
568 ASSERT_TRUE(DexFileOutputExec(&error_msg)) << error_msg;
Jeff Haoc3acfc52016-08-29 14:18:26 -0700569}
570
Jeff Hao042e8982016-10-19 11:17:11 -0700571TEST_F(DexLayoutTest, DexFileLayout) {
572 // Disable test on target.
573 TEST_DISABLED_FOR_TARGET();
574 std::string error_msg;
575 ASSERT_TRUE(DexFileLayoutExec(&error_msg)) << error_msg;
576}
577
Bharadwaj Kalandhabhatta02ef6402017-05-17 17:13:39 -0700578TEST_F(DexLayoutTest, DexFileLayoutFixedPoint) {
579 // Disable test on target.
580 TEST_DISABLED_FOR_TARGET();
581 std::string error_msg;
582 ASSERT_TRUE(DexFileLayoutFixedPointExec(&error_msg)) << error_msg;
583}
584
Jeff Haoe17f5892017-02-23 16:14:04 -0800585TEST_F(DexLayoutTest, UnreferencedCatchHandler) {
586 // Disable test on target.
587 TEST_DISABLED_FOR_TARGET();
588 std::string error_msg;
Jeff Haoac462712017-03-02 10:59:43 -0800589 ASSERT_TRUE(UnreferencedCatchHandlerExec(&error_msg,
590 kUnreferencedCatchHandlerInputDex)) << error_msg;
Jeff Haoe17f5892017-02-23 16:14:04 -0800591}
Jeff Haoac462712017-03-02 10:59:43 -0800592
593TEST_F(DexLayoutTest, Unreferenced0SizeCatchHandler) {
594 // Disable test on target.
595 TEST_DISABLED_FOR_TARGET();
596 std::string error_msg;
597 ASSERT_TRUE(UnreferencedCatchHandlerExec(&error_msg,
598 kUnreferenced0SizeCatchHandlerInputDex)) << error_msg;
599}
600
Jeff Haoa64a64c2017-03-06 15:05:38 -0800601TEST_F(DexLayoutTest, UnreferencedEndingCatchHandler) {
602 // Disable test on target.
603 TEST_DISABLED_FOR_TARGET();
604 std::string error_msg;
605 ASSERT_TRUE(UnreferencedCatchHandlerExec(&error_msg,
606 kUnreferencedEndingCatchHandlerInputDex)) << error_msg;
607}
608
Mathieu Chartier6b0dbef2017-02-21 12:45:30 -0800609TEST_F(DexLayoutTest, DuplicateOffset) {
Jeff Haod9be7682017-04-05 09:29:43 -0700610 ScratchFile temp_dex;
Andreas Gampe693bfbf2017-11-10 12:23:31 -0800611 std::vector<std::string> dexlayout_args =
612 { "-a", "-i", "-o", "/dev/null", temp_dex.GetFilename() };
Jeff Haod9be7682017-04-05 09:29:43 -0700613 ASSERT_TRUE(DexLayoutExec(&temp_dex,
614 kDexFileDuplicateOffset,
615 nullptr /* profile_file */,
Andreas Gampe693bfbf2017-11-10 12:23:31 -0800616 dexlayout_args));
Mathieu Chartier6b0dbef2017-02-21 12:45:30 -0800617}
618
Jeff Haof914f8e2017-02-21 16:14:23 -0800619TEST_F(DexLayoutTest, NullSetRefListElement) {
Jeff Haod9be7682017-04-05 09:29:43 -0700620 ScratchFile temp_dex;
Andreas Gampe693bfbf2017-11-10 12:23:31 -0800621 std::vector<std::string> dexlayout_args = { "-o", "/dev/null", temp_dex.GetFilename() };
Jeff Haod9be7682017-04-05 09:29:43 -0700622 ASSERT_TRUE(DexLayoutExec(&temp_dex,
623 kNullSetRefListElementInputDex,
624 nullptr /* profile_file */,
Andreas Gampe693bfbf2017-11-10 12:23:31 -0800625 dexlayout_args));
Jeff Haof914f8e2017-02-21 16:14:23 -0800626}
627
Jeff Haoe17f5892017-02-23 16:14:04 -0800628TEST_F(DexLayoutTest, MultiClassData) {
Jeff Haod9be7682017-04-05 09:29:43 -0700629 ScratchFile temp_dex;
630 ScratchFile temp_profile;
Andreas Gampe693bfbf2017-11-10 12:23:31 -0800631 std::vector<std::string> dexlayout_args =
632 { "-p", temp_profile.GetFilename(), "-o", "/dev/null", temp_dex.GetFilename() };
Jeff Haod9be7682017-04-05 09:29:43 -0700633 ASSERT_TRUE(DexLayoutExec(&temp_dex,
634 kMultiClassDataInputDex,
635 &temp_profile,
Andreas Gampe693bfbf2017-11-10 12:23:31 -0800636 dexlayout_args));
Jeff Haoe17f5892017-02-23 16:14:04 -0800637}
638
639TEST_F(DexLayoutTest, UnalignedCodeInfo) {
Jeff Haod9be7682017-04-05 09:29:43 -0700640 ScratchFile temp_dex;
641 ScratchFile temp_profile;
Andreas Gampe693bfbf2017-11-10 12:23:31 -0800642 std::vector<std::string> dexlayout_args =
643 { "-p", temp_profile.GetFilename(), "-o", "/dev/null", temp_dex.GetFilename() };
Jeff Haod9be7682017-04-05 09:29:43 -0700644 ASSERT_TRUE(DexLayoutExec(&temp_dex,
645 kUnalignedCodeInfoInputDex,
646 &temp_profile,
Andreas Gampe693bfbf2017-11-10 12:23:31 -0800647 dexlayout_args));
Jeff Hao44652a32017-02-22 14:20:41 -0800648}
649
Jeff Hao32a60ab2017-03-01 16:44:50 -0800650TEST_F(DexLayoutTest, ClassDataBeforeCode) {
Jeff Haod9be7682017-04-05 09:29:43 -0700651 ScratchFile temp_dex;
652 ScratchFile temp_profile;
Andreas Gampe693bfbf2017-11-10 12:23:31 -0800653 std::vector<std::string> dexlayout_args =
654 { "-p", temp_profile.GetFilename(), "-o", "/dev/null", temp_dex.GetFilename() };
Jeff Haod9be7682017-04-05 09:29:43 -0700655 ASSERT_TRUE(DexLayoutExec(&temp_dex,
656 kClassDataBeforeCodeInputDex,
657 &temp_profile,
Andreas Gampe693bfbf2017-11-10 12:23:31 -0800658 dexlayout_args));
Jeff Haod9be7682017-04-05 09:29:43 -0700659}
660
661TEST_F(DexLayoutTest, UnknownTypeDebugInfo) {
662 ScratchFile temp_dex;
Andreas Gampe693bfbf2017-11-10 12:23:31 -0800663 std::vector<std::string> dexlayout_args = { "-o", "/dev/null", temp_dex.GetFilename() };
Jeff Haod9be7682017-04-05 09:29:43 -0700664 ASSERT_TRUE(DexLayoutExec(&temp_dex,
665 kUnknownTypeDebugInfoInputDex,
666 nullptr /* profile_file */,
Andreas Gampe693bfbf2017-11-10 12:23:31 -0800667 dexlayout_args));
Jeff Hao32a60ab2017-03-01 16:44:50 -0800668}
669
Jeff Haod212d5b2017-04-26 12:09:06 -0700670TEST_F(DexLayoutTest, DuplicateCodeItem) {
671 ScratchFile temp_dex;
Andreas Gampe693bfbf2017-11-10 12:23:31 -0800672 std::vector<std::string> dexlayout_args = { "-o", "/dev/null", temp_dex.GetFilename() };
Jeff Haod212d5b2017-04-26 12:09:06 -0700673 ASSERT_TRUE(DexLayoutExec(&temp_dex,
674 kDuplicateCodeItemInputDex,
675 nullptr /* profile_file */,
Andreas Gampe693bfbf2017-11-10 12:23:31 -0800676 dexlayout_args));
Jeff Haod212d5b2017-04-26 12:09:06 -0700677}
678
Mathieu Chartieraf7c9022017-10-27 09:42:46 -0700679// Test that instructions that go past the end of the code items don't cause crashes.
680TEST_F(DexLayoutTest, CodeItemOverrun) {
681 ScratchFile temp_dex;
682 MutateDexFile(temp_dex.GetFile(), GetTestDexFileName("ManyMethods"), [] (DexFile* dex) {
683 bool mutated_successfully = false;
684 // Change the dex instructions to make an opcode that spans past the end of the code item.
685 for (size_t i = 0; i < dex->NumClassDefs(); ++i) {
686 const DexFile::ClassDef& def = dex->GetClassDef(i);
687 const uint8_t* data = dex->GetClassData(def);
688 if (data == nullptr) {
689 continue;
690 }
691 ClassDataItemIterator it(*dex, data);
692 it.SkipAllFields();
Mathieu Chartierb7c273c2017-11-10 18:07:56 -0800693 while (it.HasNextMethod()) {
Mathieu Chartieraf7c9022017-10-27 09:42:46 -0700694 DexFile::CodeItem* item = const_cast<DexFile::CodeItem*>(it.GetMethodCodeItem());
695 if (item != nullptr) {
Mathieu Chartier698ebbc2018-01-05 11:00:42 -0800696 CodeItemInstructionAccessor instructions(*dex, item);
Mathieu Chartieraf7c9022017-10-27 09:42:46 -0700697 if (instructions.begin() != instructions.end()) {
698 DexInstructionIterator last_instruction = instructions.begin();
699 for (auto dex_it = instructions.begin(); dex_it != instructions.end(); ++dex_it) {
700 last_instruction = dex_it;
701 }
702 if (last_instruction->SizeInCodeUnits() == 1) {
703 // Set the opcode to something that will go past the end of the code item.
Mathieu Chartier2b2bef22017-10-26 17:10:19 -0700704 const_cast<Instruction&>(last_instruction.Inst()).SetOpcode(
Mathieu Chartieraf7c9022017-10-27 09:42:46 -0700705 Instruction::CONST_STRING_JUMBO);
706 mutated_successfully = true;
Mathieu Chartier176190c2017-10-31 09:58:07 -0700707 // Test that the safe iterator doesn't go past the end.
708 SafeDexInstructionIterator it2(instructions.begin(), instructions.end());
709 while (!it2.IsErrorState()) {
710 ++it2;
711 }
712 EXPECT_TRUE(it2 == last_instruction);
713 EXPECT_TRUE(it2 < instructions.end());
Mathieu Chartieraf7c9022017-10-27 09:42:46 -0700714 }
715 }
716 }
717 it.Next();
718 }
719 }
720 CHECK(mutated_successfully)
721 << "Failed to find candidate code item with only one code unit in last instruction.";
722 });
Mathieu Chartiera27af082018-02-03 16:12:23 -0800723
724 std::string error_msg;
725
726 ScratchFile tmp_file;
727 const std::string& tmp_name = tmp_file.GetFilename();
728 size_t tmp_last_slash = tmp_name.rfind('/');
729 std::string tmp_dir = tmp_name.substr(0, tmp_last_slash + 1);
730 ScratchFile profile_file;
731
732 std::vector<std::string> dexlayout_args =
733 { "-i",
734 "-v",
735 "-w", tmp_dir,
736 "-o", tmp_name,
737 "-p", profile_file.GetFilename(),
738 temp_dex.GetFilename()
739 };
740 // -v makes sure that the layout did not corrupt the dex file.
Mathieu Chartieraf7c9022017-10-27 09:42:46 -0700741 ASSERT_TRUE(DexLayoutExec(&temp_dex,
742 /*dex_filename*/ nullptr,
Mathieu Chartiera27af082018-02-03 16:12:23 -0800743 &profile_file,
Andreas Gampe693bfbf2017-11-10 12:23:31 -0800744 dexlayout_args));
Orion Hodson98273672018-02-06 11:50:27 +0000745 ASSERT_TRUE(UnlinkFile(temp_dex.GetFilename() + ".new"));
Mathieu Chartieraf7c9022017-10-27 09:42:46 -0700746}
747
Mathieu Chartier2f36d2f2017-11-20 15:45:25 -0800748// Test that link data is written out (or at least the header is updated).
749TEST_F(DexLayoutTest, LinkData) {
Mathieu Chartierfe9185a2017-11-21 19:01:10 -0800750 TEST_DISABLED_FOR_TARGET();
Mathieu Chartier2f36d2f2017-11-20 15:45:25 -0800751 ScratchFile temp_dex;
752 size_t file_size = 0;
753 MutateDexFile(temp_dex.GetFile(), GetTestDexFileName("ManyMethods"), [&] (DexFile* dex) {
754 DexFile::Header& header = const_cast<DexFile::Header&>(dex->GetHeader());
755 header.link_off_ = header.file_size_;
756 header.link_size_ = 16 * KB;
757 header.file_size_ += header.link_size_;
758 file_size = header.file_size_;
759 });
760 TEMP_FAILURE_RETRY(temp_dex.GetFile()->SetLength(file_size));
761
762 std::string error_msg;
763
764 ScratchFile tmp_file;
765 const std::string& tmp_name = tmp_file.GetFilename();
766 size_t tmp_last_slash = tmp_name.rfind('/');
767 std::string tmp_dir = tmp_name.substr(0, tmp_last_slash + 1);
768 ScratchFile profile_file;
769
770 std::vector<std::string> dexlayout_args =
771 { "-i",
772 "-v",
773 "-w", tmp_dir,
774 "-o", tmp_name,
775 "-p", profile_file.GetFilename(),
776 temp_dex.GetFilename()
777 };
778 // -v makes sure that the layout did not corrupt the dex file.
779 ASSERT_TRUE(DexLayoutExec(&temp_dex,
780 /*dex_filename*/ nullptr,
781 &profile_file,
782 dexlayout_args));
Orion Hodson98273672018-02-06 11:50:27 +0000783 ASSERT_TRUE(UnlinkFile(temp_dex.GetFilename() + ".new"));
Mathieu Chartier2f36d2f2017-11-20 15:45:25 -0800784}
785
Mathieu Chartier75175552018-01-25 11:23:01 -0800786TEST_F(DexLayoutTest, ClassFilter) {
787 std::vector<std::unique_ptr<const DexFile>> dex_files;
788 std::string error_msg;
789 const ArtDexFileLoader dex_file_loader;
790 const std::string input_jar = GetTestDexFileName("ManyMethods");
791 CHECK(dex_file_loader.Open(input_jar.c_str(),
792 input_jar.c_str(),
793 /*verify*/ true,
794 /*verify_checksum*/ true,
795 &error_msg,
796 &dex_files)) << error_msg;
797 ASSERT_EQ(dex_files.size(), 1u);
798 for (const std::unique_ptr<const DexFile>& dex_file : dex_files) {
799 EXPECT_GT(dex_file->NumClassDefs(), 1u);
800 for (uint32_t i = 0; i < dex_file->NumClassDefs(); ++i) {
801 const DexFile::ClassDef& class_def = dex_file->GetClassDef(i);
802 LOG(INFO) << dex_file->GetClassDescriptor(class_def);
803 }
804 Options options;
805 // Filter out all the classes other than the one below based on class descriptor.
806 options.class_filter_.insert("LManyMethods$Strings;");
807 DexLayout dexlayout(options,
808 /*info*/ nullptr,
809 /*out_file*/ nullptr,
810 /*header*/ nullptr);
811 std::unique_ptr<DexContainer> out;
Mathieu Chartier05f90d12018-02-07 13:47:17 -0800812 bool result = dexlayout.ProcessDexFile(
813 dex_file->GetLocation().c_str(),
814 dex_file.get(),
815 /*dex_file_index*/ 0,
816 &out,
817 &error_msg);
818 ASSERT_TRUE(result) << "Failed to run dexlayout " << error_msg;
Mathieu Chartier75175552018-01-25 11:23:01 -0800819 std::unique_ptr<const DexFile> output_dex_file(
820 dex_file_loader.OpenWithDataSection(
821 out->GetMainSection()->Begin(),
822 out->GetMainSection()->Size(),
823 out->GetDataSection()->Begin(),
824 out->GetDataSection()->Size(),
825 dex_file->GetLocation().c_str(),
826 /* checksum */ 0,
827 /*oat_dex_file*/ nullptr,
828 /* verify */ true,
829 /*verify_checksum*/ false,
830 &error_msg));
831 ASSERT_TRUE(output_dex_file != nullptr);
832
Mathieu Chartier807b21b2018-01-29 05:18:24 -0800833 ASSERT_EQ(output_dex_file->NumClassDefs(), options.class_filter_.size());
Mathieu Chartier75175552018-01-25 11:23:01 -0800834 for (uint32_t i = 0; i < output_dex_file->NumClassDefs(); ++i) {
Mathieu Chartier807b21b2018-01-29 05:18:24 -0800835 // Check that every class in the output dex file is in the filter.
Mathieu Chartier75175552018-01-25 11:23:01 -0800836 const DexFile::ClassDef& class_def = output_dex_file->GetClassDef(i);
837 ASSERT_TRUE(options.class_filter_.find(output_dex_file->GetClassDescriptor(class_def)) !=
838 options.class_filter_.end());
839 }
840 }
841}
842
Jeff Haoc3acfc52016-08-29 14:18:26 -0700843} // namespace art