blob: 3a7f9eeda6a084d8fa6733cfe21aaa053e1d73c0 [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"
Jeff Haoc3acfc52016-08-29 14:18:26 -070025#include "common_runtime_test.h"
David Sehr013fd802018-01-11 22:55:24 -080026#include "dex/art_dex_file_loader.h"
David Sehr9e734c72018-01-04 17:56:19 -080027#include "dex/code_item_accessors-inl.h"
28#include "dex/dex_file-inl.h"
29#include "dex/dex_file_loader.h"
David Sehr97c381e2017-02-01 15:09:58 -080030#include "exec_utils.h"
Mathieu Chartierd00e02b2017-05-24 12:04:13 -070031#include "jit/profile_compilation_info.h"
Jeff Haoc3acfc52016-08-29 14:18:26 -070032#include "utils.h"
33
34namespace art {
35
Jeff Hao042e8982016-10-19 11:17:11 -070036static const char kDexFileLayoutInputDex[] =
37 "ZGV4CjAzNQD1KW3+B8NAB0f2A/ZVIBJ0aHrGIqcpVTAUAgAAcAAAAHhWNBIAAAAAAAAAAIwBAAAH"
38 "AAAAcAAAAAQAAACMAAAAAQAAAJwAAAAAAAAAAAAAAAMAAACoAAAAAgAAAMAAAAAUAQAAAAEAADAB"
39 "AAA4AQAAQAEAAEgBAABNAQAAUgEAAGYBAAADAAAABAAAAAUAAAAGAAAABgAAAAMAAAAAAAAAAAAA"
40 "AAAAAAABAAAAAAAAAAIAAAAAAAAAAAAAAAAAAAACAAAAAAAAAAEAAAAAAAAAdQEAAAAAAAABAAAA"
41 "AAAAAAIAAAAAAAAAAgAAAAAAAAB/AQAAAAAAAAEAAQABAAAAaQEAAAQAAABwEAIAAAAOAAEAAQAB"
42 "AAAAbwEAAAQAAABwEAIAAAAOAAY8aW5pdD4ABkEuamF2YQAGQi5qYXZhAANMQTsAA0xCOwASTGph"
43 "dmEvbGFuZy9PYmplY3Q7AAFWAAQABw48AAQABw48AAAAAQAAgIAEgAIAAAEAAYCABJgCAAAACwAA"
44 "AAAAAAABAAAAAAAAAAEAAAAHAAAAcAAAAAIAAAAEAAAAjAAAAAMAAAABAAAAnAAAAAUAAAADAAAA"
45 "qAAAAAYAAAACAAAAwAAAAAEgAAACAAAAAAEAAAIgAAAHAAAAMAEAAAMgAAACAAAAaQEAAAAgAAAC"
46 "AAAAdQEAAAAQAAABAAAAjAEAAA==";
47
Jeff Haoe17f5892017-02-23 16:14:04 -080048// Dex file with catch handler unreferenced by try blocks.
49// Constructed by building a dex file with try/catch blocks and hex editing.
50static const char kUnreferencedCatchHandlerInputDex[] =
51 "ZGV4CjAzNQD+exd52Y0f9nY5x5GmInXq5nXrO6Kl2RV4AwAAcAAAAHhWNBIAAAAAAAAAANgCAAAS"
52 "AAAAcAAAAAgAAAC4AAAAAwAAANgAAAABAAAA/AAAAAQAAAAEAQAAAQAAACQBAAA0AgAARAEAANYB"
53 "AADeAQAA5gEAAO4BAAAAAgAADwIAACYCAAA9AgAAUQIAAGUCAAB5AgAAfwIAAIUCAACIAgAAjAIA"
54 "AKECAACnAgAArAIAAAQAAAAFAAAABgAAAAcAAAAIAAAACQAAAAwAAAAOAAAADAAAAAYAAAAAAAAA"
55 "DQAAAAYAAADIAQAADQAAAAYAAADQAQAABQABABAAAAAAAAAAAAAAAAAAAgAPAAAAAQABABEAAAAD"
56 "AAAAAAAAAAAAAAABAAAAAwAAAAAAAAADAAAAAAAAAMgCAAAAAAAAAQABAAEAAAC1AgAABAAAAHAQ"
57 "AwAAAA4AAwABAAIAAgC6AgAAIQAAAGIAAAAaAQoAbiACABAAYgAAABoBCwBuIAIAEAAOAA0AYgAA"
58 "ABoBAQBuIAIAEAAo8A0AYgAAABoBAgBuIAIAEAAo7gAAAAAAAAcAAQAHAAAABwABAAIBAg8BAhgA"
59 "AQAAAAQAAAABAAAABwAGPGluaXQ+AAZDYXRjaDEABkNhdGNoMgAQSGFuZGxlclRlc3QuamF2YQAN"
60 "TEhhbmRsZXJUZXN0OwAVTGphdmEvaW8vUHJpbnRTdHJlYW07ABVMamF2YS9sYW5nL0V4Y2VwdGlv"
61 "bjsAEkxqYXZhL2xhbmcvT2JqZWN0OwASTGphdmEvbGFuZy9TdHJpbmc7ABJMamF2YS9sYW5nL1N5"
62 "c3RlbTsABFRyeTEABFRyeTIAAVYAAlZMABNbTGphdmEvbGFuZy9TdHJpbmc7AARtYWluAANvdXQA"
63 "B3ByaW50bG4AAQAHDgAEAQAHDn17AncdHoseAAAAAgAAgYAExAIBCdwCAAANAAAAAAAAAAEAAAAA"
64 "AAAAAQAAABIAAABwAAAAAgAAAAgAAAC4AAAAAwAAAAMAAADYAAAABAAAAAEAAAD8AAAABQAAAAQA"
65 "AAAEAQAABgAAAAEAAAAkAQAAASAAAAIAAABEAQAAARAAAAIAAADIAQAAAiAAABIAAADWAQAAAyAA"
66 "AAIAAAC1AgAAACAAAAEAAADIAgAAABAAAAEAAADYAgAA";
67
Jeff Haoac462712017-03-02 10:59:43 -080068// Dex file with 0-size (catch all only) catch handler unreferenced by try blocks.
69// Constructed by building a dex file with try/catch blocks and hex editing.
70static const char kUnreferenced0SizeCatchHandlerInputDex[] =
71 "ZGV4CjAzNQCEbEEvMstSNpQpjPdfMEfUBS48cis2QRJoAwAAcAAAAHhWNBIAAAAAAAAAAMgCAAAR"
72 "AAAAcAAAAAcAAAC0AAAAAwAAANAAAAABAAAA9AAAAAQAAAD8AAAAAQAAABwBAAAsAgAAPAEAAOoB"
73 "AADyAQAABAIAABMCAAAqAgAAPgIAAFICAABmAgAAaQIAAG0CAACCAgAAhgIAAIoCAACQAgAAlQIA"
74 "AJ4CAACiAgAAAgAAAAMAAAAEAAAABQAAAAYAAAAHAAAACQAAAAcAAAAFAAAAAAAAAAgAAAAFAAAA"
75 "3AEAAAgAAAAFAAAA5AEAAAQAAQANAAAAAAAAAAAAAAAAAAIADAAAAAEAAQAOAAAAAgAAAAAAAAAA"
76 "AAAAAQAAAAIAAAAAAAAAAQAAAAAAAAC5AgAAAAAAAAEAAQABAAAApgIAAAQAAABwEAMAAAAOAAQA"
77 "AQACAAIAqwIAAC8AAABiAAAAGgEPAG4gAgAQAGIAAAAaAQoAbiACABAAYgAAABoBEABuIAIAEABi"
78 "AAAAGgELAG4gAgAQAA4ADQBiAQAAGgIKAG4gAgAhACcADQBiAQAAGgILAG4gAgAhACcAAAAAAAAA"
79 "BwABAA4AAAAHAAEAAgAdACYAAAABAAAAAwAAAAEAAAAGAAY8aW5pdD4AEEhhbmRsZXJUZXN0Lmph"
80 "dmEADUxIYW5kbGVyVGVzdDsAFUxqYXZhL2lvL1ByaW50U3RyZWFtOwASTGphdmEvbGFuZy9PYmpl"
81 "Y3Q7ABJMamF2YS9sYW5nL1N0cmluZzsAEkxqYXZhL2xhbmcvU3lzdGVtOwABVgACVkwAE1tMamF2"
82 "YS9sYW5nL1N0cmluZzsAAmYxAAJmMgAEbWFpbgADb3V0AAdwcmludGxuAAJ0MQACdDIAAQAHDgAE"
83 "AQAHDnl7eXkCeB2bAAAAAgAAgYAEvAIBCdQCAA0AAAAAAAAAAQAAAAAAAAABAAAAEQAAAHAAAAAC"
84 "AAAABwAAALQAAAADAAAAAwAAANAAAAAEAAAAAQAAAPQAAAAFAAAABAAAAPwAAAAGAAAAAQAAABwB"
85 "AAABIAAAAgAAADwBAAABEAAAAgAAANwBAAACIAAAEQAAAOoBAAADIAAAAgAAAKYCAAAAIAAAAQAA"
86 "ALkCAAAAEAAAAQAAAMgCAAA=";
87
Jeff Haoa64a64c2017-03-06 15:05:38 -080088// Dex file with an unreferenced catch handler at end of code item.
89// Constructed by building a dex file with try/catch blocks and hex editing.
90static const char kUnreferencedEndingCatchHandlerInputDex[] =
91 "ZGV4CjAzNQCEflufI6xGTDDRmLpbfYi6ujPrDLIwvYcEBAAAcAAAAHhWNBIAAAAAAAAAAGQDAAAT"
92 "AAAAcAAAAAgAAAC8AAAAAwAAANwAAAABAAAAAAEAAAUAAAAIAQAAAQAAADABAAC0AgAAUAEAAE4C"
93 "AABWAgAAXgIAAGYCAAB4AgAAhwIAAJ4CAAC1AgAAyQIAAN0CAADxAgAA9wIAAP0CAAAAAwAABAMA"
94 "ABkDAAAcAwAAIgMAACcDAAAEAAAABQAAAAYAAAAHAAAACAAAAAkAAAAMAAAADgAAAAwAAAAGAAAA"
95 "AAAAAA0AAAAGAAAAQAIAAA0AAAAGAAAASAIAAAUAAQARAAAAAAAAAAAAAAAAAAAADwAAAAAAAgAQ"
96 "AAAAAQABABIAAAADAAAAAAAAAAAAAAABAAAAAwAAAAAAAAADAAAAAAAAAFADAAAAAAAAAQABAAEA"
97 "AAAwAwAABAAAAHAQBAAAAA4AAgAAAAIAAgA1AwAAIQAAAGIAAAAaAQoAbiADABAAYgAAABoBCwBu"
98 "IAMAEAAOAA0AYgAAABoBAQBuIAMAEAAo8A0AYgAAABoBAgBuIAMAEAAo7gAAAAAAAAcAAQAHAAAA"
99 "BwABAAIBAg8BAhgAAwABAAIAAgBCAwAAIQAAAGIAAAAaAQoAbiADABAAYgAAABoBCwBuIAMAEAAO"
100 "AA0AYgAAABoBAQBuIAMAEAAo8A0AYgAAABoBAgBuIAMAEAAo7gAAAAAAAAcAAQAHAAAABwABAAIB"
101 "Ag8BAhgAAQAAAAQAAAABAAAABwAGPGluaXQ+AAZDYXRjaDEABkNhdGNoMgAQSGFuZGxlclRlc3Qu"
102 "amF2YQANTEhhbmRsZXJUZXN0OwAVTGphdmEvaW8vUHJpbnRTdHJlYW07ABVMamF2YS9sYW5nL0V4"
103 "Y2VwdGlvbjsAEkxqYXZhL2xhbmcvT2JqZWN0OwASTGphdmEvbGFuZy9TdHJpbmc7ABJMamF2YS9s"
104 "YW5nL1N5c3RlbTsABFRyeTEABFRyeTIAAVYAAlZMABNbTGphdmEvbGFuZy9TdHJpbmc7AAFhAARt"
105 "YWluAANvdXQAB3ByaW50bG4AAQAHDgAEAAcOfHsCeB0eih4AEQEABw59ewJ3HR6LHgAAAAMAAIGA"
106 "BNACAQnoAgEJ1AMAAA0AAAAAAAAAAQAAAAAAAAABAAAAEwAAAHAAAAACAAAACAAAALwAAAADAAAA"
107 "AwAAANwAAAAEAAAAAQAAAAABAAAFAAAABQAAAAgBAAAGAAAAAQAAADABAAABIAAAAwAAAFABAAAB"
108 "EAAAAgAAAEACAAACIAAAEwAAAE4CAAADIAAAAwAAADADAAAAIAAAAQAAAFADAAAAEAAAAQAAAGQD"
109 "AAA=";
110
Mathieu Chartier6b0dbef2017-02-21 12:45:30 -0800111// Dex file with multiple code items that have the same debug_info_off_. Constructed by a modified
112// dexlayout on XandY.
113static const char kDexFileDuplicateOffset[] =
114 "ZGV4CjAzNwAQfXfPCB8qCxo7MqdFhmHZQwCv8+udHD8MBAAAcAAAAHhWNBIAAAAAAAAAAFQDAAAT"
115 "AAAAcAAAAAgAAAC8AAAAAQAAANwAAAABAAAA6AAAAAUAAADwAAAAAwAAABgBAACUAgAAeAEAABQC"
116 "AAAeAgAAJgIAACsCAAAyAgAANwIAAFsCAAB7AgAAngIAALICAAC1AgAAvQIAAMUCAADIAgAA1QIA"
117 "AOkCAADvAgAA9QIAAPwCAAACAAAAAwAAAAQAAAAFAAAABgAAAAcAAAAIAAAACQAAAAkAAAAHAAAA"
118 "AAAAAAIAAQASAAAAAAAAAAEAAAABAAAAAQAAAAIAAAAAAAAAAgAAAAEAAAAGAAAAAQAAAAAAAAAA"
119 "AAAABgAAAAAAAAAKAAAAAAAAACsDAAAAAAAAAQAAAAAAAAAGAAAAAAAAAAsAAAD0AQAANQMAAAAA"
120 "AAACAAAAAAAAAAAAAAAAAAAACwAAAAQCAAA/AwAAAAAAAAIAAAAUAwAAGgMAAAEAAAAjAwAAAQAB"
121 "AAEAAAAFAAAABAAAAHAQBAAAAA4AAQABAAEAAAAFAAAABAAAAHAQBAAAAA4AAQAAAAEAAAAFAAAA"
122 "CAAAACIAAQBwEAEAAABpAAAADgABAAEAAQAAAAUAAAAEAAAAcBAAAAAADgB4AQAAAAAAAAAAAAAA"
123 "AAAAhAEAAAAAAAAAAAAAAAAAAAg8Y2xpbml0PgAGPGluaXQ+AANMWDsABUxZJFo7AANMWTsAIkxk"
124 "YWx2aWsvYW5ub3RhdGlvbi9FbmNsb3NpbmdDbGFzczsAHkxkYWx2aWsvYW5ub3RhdGlvbi9Jbm5l"
125 "ckNsYXNzOwAhTGRhbHZpay9hbm5vdGF0aW9uL01lbWJlckNsYXNzZXM7ABJMamF2YS9sYW5nL09i"
126 "amVjdDsAAVYABlguamF2YQAGWS5qYXZhAAFaAAthY2Nlc3NGbGFncwASZW1pdHRlcjogamFjay00"
127 "LjI1AARuYW1lAAR0aGlzAAV2YWx1ZQABegARAAcOABMABw4AEgAHDnYAEQAHDgACAwERGAICBAIN"
128 "BAgPFwwCBQERHAEYAQAAAQAAgIAEjAMAAAEAAYCABKQDAQACAAAIAoiABLwDAYCABNwDAAAADwAA"
129 "AAAAAAABAAAAAAAAAAEAAAATAAAAcAAAAAIAAAAIAAAAvAAAAAMAAAABAAAA3AAAAAQAAAABAAAA"
130 "6AAAAAUAAAAFAAAA8AAAAAYAAAADAAAAGAEAAAMQAAACAAAAeAEAAAEgAAAEAAAAjAEAAAYgAAAC"
131 "AAAA9AEAAAIgAAATAAAAFAIAAAMgAAAEAAAA/wIAAAQgAAADAAAAFAMAAAAgAAADAAAAKwMAAAAQ"
132 "AAABAAAAVAMAAA==";
133
Jeff Haof914f8e2017-02-21 16:14:23 -0800134// Dex file with null value for annotations_off in the annotation_set_ref_list.
135// Constructed by building a dex file with annotations and hex editing.
136static const char kNullSetRefListElementInputDex[] =
137 "ZGV4CjAzNQB1iA+7ZwgkF+7E6ZesYFc2lRAR3qnRAanwAwAAcAAAAHhWNBIAAAAAAAAAACADAAAS"
138 "AAAAcAAAAAgAAAC4AAAAAwAAANgAAAABAAAA/AAAAAQAAAAEAQAAAgAAACQBAACMAgAAZAEAAOgB"
139 "AADwAQAAAAIAAAMCAAAQAgAAIAIAADQCAABIAgAAawIAAI0CAAC1AgAAyAIAANECAADUAgAA2QIA"
140 "ANwCAADjAgAA6QIAAAMAAAAEAAAABQAAAAYAAAAHAAAACAAAAAkAAAAMAAAAAgAAAAMAAAAAAAAA"
141 "DAAAAAcAAAAAAAAADQAAAAcAAADgAQAABgAGAAsAAAAAAAEAAAAAAAAAAgAOAAAAAQAAABAAAAAC"
142 "AAEAAAAAAAAAAAAAAAAAAgAAAAAAAAABAAAAsAEAAAgDAAAAAAAAAQAAAAEmAAACAAAA2AEAAAoA"
143 "AADIAQAAFgMAAAAAAAACAAAAAAAAAHwBAAABAAAA/AIAAAAAAAABAAAAAgMAAAEAAQABAAAA8AIA"
144 "AAQAAABwEAMAAAAOAAIAAgAAAAAA9QIAAAEAAAAOAAAAAAAAAAAAAAAAAAAAAQAAAAEAAABkAQAA"
145 "cAEAAAAAAAAAAAAAAAAAAAEAAAAEAAAAAgAAAAMAAwAGPGluaXQ+AA5Bbm5vQ2xhc3MuamF2YQAB"
146 "TAALTEFubm9DbGFzczsADkxNeUFubm90YXRpb247ABJMamF2YS9sYW5nL09iamVjdDsAEkxqYXZh"
147 "L2xhbmcvU3RyaW5nOwAhTGphdmEvbGFuZy9hbm5vdGF0aW9uL0Fubm90YXRpb247ACBMamF2YS9s"
148 "YW5nL2Fubm90YXRpb24vUmV0ZW50aW9uOwAmTGphdmEvbGFuZy9hbm5vdGF0aW9uL1JldGVudGlv"
149 "blBvbGljeTsAEU15QW5ub3RhdGlvbi5qYXZhAAdSVU5USU1FAAFWAANWTEwAAWEABWFOYW1lAARu"
150 "YW1lAAV2YWx1ZQABAAcOAAICAAAHDgABBQERGwABAQEQFw8AAAIAAICABIQDAQmcAwAAAAECgQgA"
151 "AAARAAAAAAAAAAEAAAAAAAAAAQAAABIAAABwAAAAAgAAAAgAAAC4AAAAAwAAAAMAAADYAAAABAAA"
152 "AAEAAAD8AAAABQAAAAQAAAAEAQAABgAAAAIAAAAkAQAAAhAAAAEAAABkAQAAAxAAAAMAAABwAQAA"
153 "ASAAAAIAAACEAQAABiAAAAIAAACwAQAAARAAAAIAAADYAQAAAiAAABIAAADoAQAAAyAAAAIAAADw"
154 "AgAABCAAAAIAAAD8AgAAACAAAAIAAAAIAwAAABAAAAEAAAAgAwAA";
155
Jeff Haoe17f5892017-02-23 16:14:04 -0800156// Dex file with shared empty class data item for multiple class defs.
157// Constructing by building a dex file with multiple classes and hex editing.
158static const char kMultiClassDataInputDex[] =
159 "ZGV4CjAzNQALJgF9TtnLq748xVe/+wyxETrT9lTEiW6YAQAAcAAAAHhWNBIAAAAAAAAAADQBAAAI"
160 "AAAAcAAAAAQAAACQAAAAAAAAAAAAAAACAAAAoAAAAAAAAAAAAAAAAgAAALAAAACoAAAA8AAAAPAA"
161 "AAD4AAAAAAEAAAMBAAAIAQAADQEAACEBAAAkAQAAAgAAAAMAAAAEAAAABQAAAAEAAAAGAAAAAgAA"
162 "AAcAAAABAAAAAQYAAAMAAAAAAAAAAAAAAAAAAAAnAQAAAAAAAAIAAAABBgAAAwAAAAAAAAABAAAA"
163 "AAAAACcBAAAAAAAABkEuamF2YQAGQi5qYXZhAAFJAANMQTsAA0xCOwASTGphdmEvbGFuZy9PYmpl"
164 "Y3Q7AAFhAAFiAAAAAAABAAAAARkAAAAIAAAAAAAAAAEAAAAAAAAAAQAAAAgAAABwAAAAAgAAAAQA"
165 "AACQAAAABAAAAAIAAACgAAAABgAAAAIAAACwAAAAAiAAAAgAAADwAAAAACAAAAIAAAAnAQAAABAA"
166 "AAEAAAA0AQAA";
167
168// Dex file with code info followed by non 4-byte aligned section.
169// Constructed a dex file with code info followed by string data and hex edited.
170static const char kUnalignedCodeInfoInputDex[] =
171 "ZGV4CjAzNQDXJzXNb4iWn2SLhmLydW/8h1K9moERIw7UAQAAcAAAAHhWNBIAAAAAAAAAAEwBAAAG"
172 "AAAAcAAAAAMAAACIAAAAAQAAAJQAAAAAAAAAAAAAAAMAAACgAAAAAQAAALgAAAD8AAAA2AAAAAIB"
173 "AAAKAQAAEgEAABcBAAArAQAALgEAAAIAAAADAAAABAAAAAQAAAACAAAAAAAAAAAAAAAAAAAAAAAA"
174 "AAUAAAABAAAAAAAAAAAAAAABAAAAAQAAAAAAAAABAAAAAAAAADsBAAAAAAAAAQABAAEAAAAxAQAA"
175 "BAAAAHAQAgAAAA4AAQABAAAAAAA2AQAAAQAAAA4ABjxpbml0PgAGQS5qYXZhAANMQTsAEkxqYXZh"
176 "L2xhbmcvT2JqZWN0OwABVgABYQABAAcOAAMABw4AAAABAQCBgATYAQEB8AEAAAALAAAAAAAAAAEA"
177 "AAAAAAAAAQAAAAYAAABwAAAAAgAAAAMAAACIAAAAAwAAAAEAAACUAAAABQAAAAMAAACgAAAABgAA"
178 "AAEAAAC4AAAAASAAAAIAAADYAAAAAiAAAAYAAAACAQAAAyAAAAIAAAAxAQAAACAAAAEAAAA7AQAA"
179 "ABAAAAEAAABMAQAA";
Jeff Hao44652a32017-02-22 14:20:41 -0800180
Jeff Hao32a60ab2017-03-01 16:44:50 -0800181// Dex file with class data section preceding code items.
182// Constructed by passing dex file through dexmerger tool and hex editing.
183static const char kClassDataBeforeCodeInputDex[] =
184 "ZGV4CjAzNQCZKmCu3XXn4zvxCh5VH0gZNNobEAcsc49EAgAAcAAAAHhWNBIAAAAAAAAAAAQBAAAJ"
185 "AAAAcAAAAAQAAACUAAAAAgAAAKQAAAAAAAAAAAAAAAUAAAC8AAAAAQAAAOQAAABAAQAABAEAAPgB"
186 "AAAAAgAACAIAAAsCAAAQAgAAJAIAACcCAAAqAgAALQIAAAIAAAADAAAABAAAAAUAAAACAAAAAAAA"
187 "AAAAAAAFAAAAAwAAAAAAAAABAAEAAAAAAAEAAAAGAAAAAQAAAAcAAAABAAAACAAAAAIAAQAAAAAA"
188 "AQAAAAEAAAACAAAAAAAAAAEAAAAAAAAAjAEAAAAAAAALAAAAAAAAAAEAAAAAAAAAAQAAAAkAAABw"
189 "AAAAAgAAAAQAAACUAAAAAwAAAAIAAACkAAAABQAAAAUAAAC8AAAABgAAAAEAAADkAAAAABAAAAEA"
190 "AAAEAQAAACAAAAEAAACMAQAAASAAAAQAAACkAQAAAiAAAAkAAAD4AQAAAyAAAAQAAAAwAgAAAAAB"
191 "AwCBgASkAwEBvAMBAdADAQHkAwAAAQABAAEAAAAwAgAABAAAAHAQBAAAAA4AAgABAAAAAAA1AgAA"
192 "AgAAABIQDwACAAEAAAAAADoCAAACAAAAEiAPAAIAAQAAAAAAPwIAAAIAAAASMA8ABjxpbml0PgAG"
193 "QS5qYXZhAAFJAANMQTsAEkxqYXZhL2xhbmcvT2JqZWN0OwABVgABYQABYgABYwABAAcOAAMABw4A"
194 "BgAHDgAJAAcOAA==";
195
Jeff Haod9be7682017-04-05 09:29:43 -0700196// Dex file with local info containing a null type descriptor.
197// Constructed a dex file with debug info sequence containing DBG_RESTART_LOCAL without any
198// DBG_START_LOCAL to give it a declared type.
199static const char kUnknownTypeDebugInfoInputDex[] =
200 "ZGV4CjAzNQBtKqZfzjHLNSNwW2A6Bz9FuCEX0sL+FF38AQAAcAAAAHhWNBIAAAAAAAAAAHQBAAAI"
201 "AAAAcAAAAAQAAACQAAAAAgAAAKAAAAAAAAAAAAAAAAMAAAC4AAAAAQAAANAAAAAMAQAA8AAAABwB"
202 "AAAkAQAALAEAAC8BAAA0AQAASAEAAEsBAABOAQAAAgAAAAMAAAAEAAAABQAAAAIAAAAAAAAAAAAA"
203 "AAUAAAADAAAAAAAAAAEAAQAAAAAAAQAAAAYAAAACAAEAAAAAAAEAAAABAAAAAgAAAAAAAAABAAAA"
204 "AAAAAGMBAAAAAAAAAQABAAEAAABUAQAABAAAAHAQAgAAAA4AAgABAAAAAABZAQAAAgAAABIQDwAG"
205 "PGluaXQ+AAZBLmphdmEAAUkAA0xBOwASTGphdmEvbGFuZy9PYmplY3Q7AAFWAAFhAAR0aGlzAAEA"
206 "Bw4AAwAHDh4GAAYAAAAAAQEAgYAE8AEBAYgCAAAACwAAAAAAAAABAAAAAAAAAAEAAAAIAAAAcAAA"
207 "AAIAAAAEAAAAkAAAAAMAAAACAAAAoAAAAAUAAAADAAAAuAAAAAYAAAABAAAA0AAAAAEgAAACAAAA"
208 "8AAAAAIgAAAIAAAAHAEAAAMgAAACAAAAVAEAAAAgAAABAAAAYwEAAAAQAAABAAAAdAEAAA==";
209
Jeff Haod212d5b2017-04-26 12:09:06 -0700210// Dex file with multiple class data items pointing to the same code item.
211// Constructed by hex editing.
212static const char kDuplicateCodeItemInputDex[] =
213 "ZGV4CjAzNQCwKtVglQOmLWuHwldN5jkBOInC7mTMhJMAAgAAcAAAAHhWNBIAAAAAAAAAAHgBAAAH"
214 "AAAAcAAAAAMAAACMAAAAAQAAAJgAAAAAAAAAAAAAAAQAAACkAAAAAQAAAMQAAAAcAQAA5AAAACQB"
215 "AAAsAQAANAEAADkBAABNAQAAUAEAAFMBAAACAAAAAwAAAAQAAAAEAAAAAgAAAAAAAAAAAAAAAAAA"
216 "AAAAAAAFAAAAAAAAAAYAAAABAAAAAAAAAAAAAAABAAAAAQAAAAAAAAABAAAAAAAAAGUBAAAAAAAA"
217 "AQABAAEAAABWAQAABAAAAHAQAwAAAA4AAQABAAAAAABbAQAAAQAAAA4AAAABAAEAAAAAAGABAAAB"
218 "AAAADgAAAAY8aW5pdD4ABkEuamF2YQADTEE7ABJMamF2YS9sYW5nL09iamVjdDsAAVYAAWEAAWIA"
219 "AQAHDgADAAcOAAUABw4AAAABAgCBgATkAQEA/AEBAPwBAAsAAAAAAAAAAQAAAAAAAAABAAAABwAA"
220 "AHAAAAACAAAAAwAAAIwAAAADAAAAAQAAAJgAAAAFAAAABAAAAKQAAAAGAAAAAQAAAMQAAAABIAAA"
221 "AwAAAOQAAAACIAAABwAAACQBAAADIAAAAwAAAFYBAAAAIAAAAQAAAGUBAAAAEAAAAQAAAHgBAAA=";
222
Mathieu Chartier6b0dbef2017-02-21 12:45:30 -0800223static void WriteBase64ToFile(const char* base64, File* file) {
Jeff Hao042e8982016-10-19 11:17:11 -0700224 // Decode base64.
225 CHECK(base64 != nullptr);
226 size_t length;
227 std::unique_ptr<uint8_t[]> bytes(DecodeBase64(base64, &length));
Mathieu Chartier6b0dbef2017-02-21 12:45:30 -0800228 CHECK(bytes != nullptr);
Jeff Hao042e8982016-10-19 11:17:11 -0700229 if (!file->WriteFully(bytes.get(), length)) {
230 PLOG(FATAL) << "Failed to write base64 as file";
231 }
Mathieu Chartier6b0dbef2017-02-21 12:45:30 -0800232}
233
234static void WriteFileBase64(const char* base64, const char* location) {
235 // Write to provided file.
236 std::unique_ptr<File> file(OS::CreateEmptyFile(location));
237 CHECK(file != nullptr);
238 WriteBase64ToFile(base64, file.get());
Jeff Hao042e8982016-10-19 11:17:11 -0700239 if (file->FlushCloseOrErase() != 0) {
240 PLOG(FATAL) << "Could not flush and close test file.";
241 }
242}
243
Jeff Haoc3acfc52016-08-29 14:18:26 -0700244class DexLayoutTest : public CommonRuntimeTest {
245 protected:
Andreas Gampe693bfbf2017-11-10 12:23:31 -0800246 std::string GetDexLayoutPath() {
247 return GetTestAndroidRoot() + "/bin/dexlayoutd";
Jeff Haoc3acfc52016-08-29 14:18:26 -0700248 }
249
Jeff Haoa8621002016-10-04 18:13:44 +0000250 // Runs FullPlainOutput test.
251 bool FullPlainOutputExec(std::string* error_msg) {
Jeff Haoc3acfc52016-08-29 14:18:26 -0700252 // TODO: dexdump2 -> dexdump ?
253 ScratchFile dexdump_output;
Andreas Gampeca620d72016-11-08 08:09:33 -0800254 const std::string& dexdump_filename = dexdump_output.GetFilename();
Jeff Haoc3acfc52016-08-29 14:18:26 -0700255 std::string dexdump = GetTestAndroidRoot() + "/bin/dexdump2";
256 EXPECT_TRUE(OS::FileExists(dexdump.c_str())) << dexdump << " should be a valid file path";
Jeff Haoc3acfc52016-08-29 14:18:26 -0700257
258 ScratchFile dexlayout_output;
Andreas Gampeca620d72016-11-08 08:09:33 -0800259 const std::string& dexlayout_filename = dexlayout_output.GetFilename();
Jeff Haoc3acfc52016-08-29 14:18:26 -0700260
Jeff Haoa8621002016-10-04 18:13:44 +0000261 for (const std::string &dex_file : GetLibCoreDexFileNames()) {
262 std::vector<std::string> dexdump_exec_argv =
263 { dexdump, "-d", "-f", "-h", "-l", "plain", "-o", dexdump_filename, dex_file };
Andreas Gampe693bfbf2017-11-10 12:23:31 -0800264 std::vector<std::string> dexlayout_args =
265 { "-d", "-f", "-h", "-l", "plain", "-o", dexlayout_filename, dex_file };
Jeff Haoa8621002016-10-04 18:13:44 +0000266 if (!::art::Exec(dexdump_exec_argv, error_msg)) {
267 return false;
268 }
Andreas Gampe693bfbf2017-11-10 12:23:31 -0800269 if (!DexLayoutExec(dexlayout_args, error_msg)) {
Jeff Haoa8621002016-10-04 18:13:44 +0000270 return false;
271 }
272 std::vector<std::string> diff_exec_argv =
273 { "/usr/bin/diff", dexdump_filename, dexlayout_filename };
274 if (!::art::Exec(diff_exec_argv, error_msg)) {
275 return false;
276 }
Jeff Haoc3acfc52016-08-29 14:18:26 -0700277 }
278 return true;
279 }
280
Jeff Haoa8621002016-10-04 18:13:44 +0000281 // Runs DexFileOutput test.
282 bool DexFileOutputExec(std::string* error_msg) {
283 ScratchFile tmp_file;
Andreas Gampeca620d72016-11-08 08:09:33 -0800284 const std::string& tmp_name = tmp_file.GetFilename();
285 size_t tmp_last_slash = tmp_name.rfind('/');
Jeff Haoa8621002016-10-04 18:13:44 +0000286 std::string tmp_dir = tmp_name.substr(0, tmp_last_slash + 1);
Jeff Haoa8621002016-10-04 18:13:44 +0000287
288 for (const std::string &dex_file : GetLibCoreDexFileNames()) {
Andreas Gampe693bfbf2017-11-10 12:23:31 -0800289 std::vector<std::string> dexlayout_args =
290 { "-w", tmp_dir, "-o", tmp_name, dex_file };
291 if (!DexLayoutExec(dexlayout_args, error_msg)) {
Jeff Haoa8621002016-10-04 18:13:44 +0000292 return false;
293 }
Andreas Gampe5555dd12017-08-24 13:50:21 -0700294 size_t dex_file_last_slash = dex_file.rfind('/');
Jeff Haoa8621002016-10-04 18:13:44 +0000295 std::string dex_file_name = dex_file.substr(dex_file_last_slash + 1);
296 std::vector<std::string> unzip_exec_argv =
297 { "/usr/bin/unzip", dex_file, "classes.dex", "-d", tmp_dir};
298 if (!::art::Exec(unzip_exec_argv, error_msg)) {
299 return false;
300 }
301 std::vector<std::string> diff_exec_argv =
302 { "/usr/bin/diff", tmp_dir + "classes.dex" , tmp_dir + dex_file_name };
303 if (!::art::Exec(diff_exec_argv, error_msg)) {
304 return false;
305 }
306 std::vector<std::string> rm_zip_exec_argv = { "/bin/rm", tmp_dir + "classes.dex" };
307 if (!::art::Exec(rm_zip_exec_argv, error_msg)) {
308 return false;
309 }
310 std::vector<std::string> rm_out_exec_argv = { "/bin/rm", tmp_dir + dex_file_name };
311 if (!::art::Exec(rm_out_exec_argv, error_msg)) {
312 return false;
313 }
314 }
Jeff Hao042e8982016-10-19 11:17:11 -0700315 return true;
316 }
Jeff Haoa8621002016-10-04 18:13:44 +0000317
Mathieu Chartieraf7c9022017-10-27 09:42:46 -0700318 template <typename Mutator>
319 bool MutateDexFile(File* output_dex, const std::string& input_jar, const Mutator& mutator) {
320 std::vector<std::unique_ptr<const DexFile>> dex_files;
321 std::string error_msg;
David Sehr013fd802018-01-11 22:55:24 -0800322 const ArtDexFileLoader dex_file_loader;
323 CHECK(dex_file_loader.Open(input_jar.c_str(),
324 input_jar.c_str(),
325 /*verify*/ true,
326 /*verify_checksum*/ true,
327 &error_msg,
328 &dex_files)) << error_msg;
Mathieu Chartieraf7c9022017-10-27 09:42:46 -0700329 EXPECT_EQ(dex_files.size(), 1u) << "Only one input dex is supported";
330 for (const std::unique_ptr<const DexFile>& dex : dex_files) {
331 CHECK(dex->EnableWrite()) << "Failed to enable write";
332 mutator(const_cast<DexFile*>(dex.get()));
333 if (!output_dex->WriteFully(dex->Begin(), dex->Size())) {
334 return false;
335 }
336 }
337 if (output_dex->Flush() != 0) {
338 PLOG(FATAL) << "Could not flush the output file.";
339 }
340 return true;
341 }
342
Mathieu Chartierd00e02b2017-05-24 12:04:13 -0700343 // Create a profile with some subset of methods and classes.
344 void CreateProfile(const std::string& input_dex,
345 const std::string& out_profile,
346 const std::string& dex_location) {
347 std::vector<std::unique_ptr<const DexFile>> dex_files;
348 std::string error_msg;
David Sehr013fd802018-01-11 22:55:24 -0800349 const ArtDexFileLoader dex_file_loader;
350 bool result = dex_file_loader.Open(input_dex.c_str(),
351 input_dex,
352 /*verify*/ true,
353 /*verify_checksum*/ false,
354 &error_msg,
355 &dex_files);
Mathieu Chartierd00e02b2017-05-24 12:04:13 -0700356
357 ASSERT_TRUE(result) << error_msg;
358 ASSERT_GE(dex_files.size(), 1u);
359
360 size_t profile_methods = 0;
361 size_t profile_classes = 0;
362 ProfileCompilationInfo pfi;
Mathieu Chartierd00e02b2017-05-24 12:04:13 -0700363 std::set<DexCacheResolvedClasses> classes;
364 for (const std::unique_ptr<const DexFile>& dex_file : dex_files) {
365 for (uint32_t i = 0; i < dex_file->NumMethodIds(); i += 2) {
Mathieu Chartierbbe3a5e2017-06-13 16:36:17 -0700366 uint8_t flags = 0u;
367
Mathieu Chartierd00e02b2017-05-24 12:04:13 -0700368 if ((i & 3) != 0) {
Mathieu Chartierbbe3a5e2017-06-13 16:36:17 -0700369 flags |= ProfileCompilationInfo::MethodHotness::kFlagHot;
Mathieu Chartierea650f32017-05-24 12:04:13 -0700370 ++profile_methods;
371 } else if ((i & 2) != 0) {
Mathieu Chartierbbe3a5e2017-06-13 16:36:17 -0700372 flags |= ProfileCompilationInfo::MethodHotness::kFlagStartup;
Mathieu Chartierd00e02b2017-05-24 12:04:13 -0700373 ++profile_methods;
374 }
Mathieu Chartierbbe3a5e2017-06-13 16:36:17 -0700375 pfi.AddMethodIndex(static_cast<ProfileCompilationInfo::MethodHotness::Flag>(flags),
376 dex_location,
377 dex_file->GetLocationChecksum(),
378 /*dex_method_idx*/i,
379 dex_file->NumMethodIds());
Mathieu Chartierd00e02b2017-05-24 12:04:13 -0700380 }
381 DexCacheResolvedClasses cur_classes(dex_location,
382 dex_location,
Mathieu Chartierea650f32017-05-24 12:04:13 -0700383 dex_file->GetLocationChecksum(),
384 dex_file->NumMethodIds());
Mathieu Chartierd00e02b2017-05-24 12:04:13 -0700385 // Add every even class too.
386 for (uint32_t i = 0; i < dex_file->NumClassDefs(); i += 1) {
Mathieu Chartierea650f32017-05-24 12:04:13 -0700387 if ((i & 2) == 0) {
388 cur_classes.AddClass(dex_file->GetClassDef(i).class_idx_);
389 ++profile_classes;
390 }
Mathieu Chartierd00e02b2017-05-24 12:04:13 -0700391 }
Mathieu Chartierea650f32017-05-24 12:04:13 -0700392 classes.insert(cur_classes);
Mathieu Chartierd00e02b2017-05-24 12:04:13 -0700393 }
Mathieu Chartierbbe3a5e2017-06-13 16:36:17 -0700394 pfi.AddClasses(classes);
Mathieu Chartierd00e02b2017-05-24 12:04:13 -0700395 // Write to provided file.
396 std::unique_ptr<File> file(OS::CreateEmptyFile(out_profile.c_str()));
397 ASSERT_TRUE(file != nullptr);
398 pfi.Save(file->Fd());
399 if (file->FlushCloseOrErase() != 0) {
400 PLOG(FATAL) << "Could not flush and close test file.";
401 }
402 EXPECT_GE(profile_methods, 0u);
403 EXPECT_GE(profile_classes, 0u);
404 }
405
Jeff Haod9be7682017-04-05 09:29:43 -0700406 // Runs DexFileLayout test.
Jeff Hao042e8982016-10-19 11:17:11 -0700407 bool DexFileLayoutExec(std::string* error_msg) {
408 ScratchFile tmp_file;
Andreas Gampe641a4732017-08-24 13:21:35 -0700409 const std::string& tmp_name = tmp_file.GetFilename();
Andreas Gampe5555dd12017-08-24 13:50:21 -0700410 size_t tmp_last_slash = tmp_name.rfind('/');
Jeff Hao042e8982016-10-19 11:17:11 -0700411 std::string tmp_dir = tmp_name.substr(0, tmp_last_slash + 1);
412
413 // Write inputs and expected outputs.
414 std::string dex_file = tmp_dir + "classes.dex";
415 WriteFileBase64(kDexFileLayoutInputDex, dex_file.c_str());
416 std::string profile_file = tmp_dir + "primary.prof";
Mathieu Chartierd00e02b2017-05-24 12:04:13 -0700417 CreateProfile(dex_file, profile_file, dex_file);
418 // WriteFileBase64(kDexFileLayoutInputProfile, profile_file.c_str());
Jeff Hao042e8982016-10-19 11:17:11 -0700419 std::string output_dex = tmp_dir + "classes.dex.new";
420
Andreas Gampe693bfbf2017-11-10 12:23:31 -0800421 std::vector<std::string> dexlayout_args =
422 { "-v", "-w", tmp_dir, "-o", tmp_name, "-p", profile_file, dex_file };
423 if (!DexLayoutExec(dexlayout_args, error_msg)) {
Jeff Hao042e8982016-10-19 11:17:11 -0700424 return false;
425 }
Mathieu Chartierfa0aa092017-03-27 15:43:54 -0700426
427 // -v makes sure that the layout did not corrupt the dex file.
Jeff Hao042e8982016-10-19 11:17:11 -0700428
429 std::vector<std::string> rm_exec_argv =
Mathieu Chartierfa0aa092017-03-27 15:43:54 -0700430 { "/bin/rm", dex_file, profile_file, output_dex };
Jeff Hao042e8982016-10-19 11:17:11 -0700431 if (!::art::Exec(rm_exec_argv, error_msg)) {
432 return false;
433 }
Jeff Haoa8621002016-10-04 18:13:44 +0000434 return true;
435 }
Jeff Hao44652a32017-02-22 14:20:41 -0800436
Bharadwaj Kalandhabhatta02ef6402017-05-17 17:13:39 -0700437 // Runs DexFileLayout test twice (second time is run on output of first time)
438 // for behavior consistency.
439 bool DexFileLayoutFixedPointExec(std::string* error_msg) {
440 ScratchFile tmp_file;
Andreas Gampe641a4732017-08-24 13:21:35 -0700441 const std::string& tmp_name = tmp_file.GetFilename();
Andreas Gampe5555dd12017-08-24 13:50:21 -0700442 size_t tmp_last_slash = tmp_name.rfind('/');
Bharadwaj Kalandhabhatta02ef6402017-05-17 17:13:39 -0700443 std::string tmp_dir = tmp_name.substr(0, tmp_last_slash + 1);
444
Mathieu Chartierd00e02b2017-05-24 12:04:13 -0700445 // Unzip the test dex file to the classes.dex destination. It is required to unzip since
446 // opening from jar recalculates the dex location checksum.
Bharadwaj Kalandhabhatta02ef6402017-05-17 17:13:39 -0700447 std::string dex_file = tmp_dir + "classes.dex";
Mathieu Chartierd00e02b2017-05-24 12:04:13 -0700448
449 std::vector<std::string> unzip_args = {
450 "/usr/bin/unzip",
451 GetTestDexFileName("ManyMethods"),
452 "classes.dex",
453 "-d",
454 tmp_dir,
455 };
456 if (!art::Exec(unzip_args, error_msg)) {
457 LOG(ERROR) << "Failed to unzip dex";
458 return false;
459 }
460
Bharadwaj Kalandhabhatta02ef6402017-05-17 17:13:39 -0700461 std::string profile_file = tmp_dir + "primary.prof";
Mathieu Chartierd00e02b2017-05-24 12:04:13 -0700462 CreateProfile(dex_file, profile_file, dex_file);
Bharadwaj Kalandhabhatta02ef6402017-05-17 17:13:39 -0700463 std::string output_dex = tmp_dir + "classes.dex.new";
464 std::string second_output_dex = tmp_dir + "classes.dex.new.new";
465
Bharadwaj Kalandhabhatta02ef6402017-05-17 17:13:39 -0700466 // -v makes sure that the layout did not corrupt the dex file.
Andreas Gampe693bfbf2017-11-10 12:23:31 -0800467 std::vector<std::string> dexlayout_args =
468 { "-i", "-v", "-w", tmp_dir, "-o", tmp_name, "-p", profile_file, dex_file };
469 if (!DexLayoutExec(dexlayout_args, error_msg)) {
Bharadwaj Kalandhabhatta02ef6402017-05-17 17:13:39 -0700470 return false;
471 }
472
Mathieu Chartierd00e02b2017-05-24 12:04:13 -0700473 // Recreate the profile with the new dex location. This is required so that the profile dex
474 // location matches.
475 CreateProfile(dex_file, profile_file, output_dex);
476
Bharadwaj Kalandhabhatta02ef6402017-05-17 17:13:39 -0700477 // -v makes sure that the layout did not corrupt the dex file.
Mathieu Chartierd00e02b2017-05-24 12:04:13 -0700478 // -i since the checksum won't match from the first layout.
Andreas Gampe693bfbf2017-11-10 12:23:31 -0800479 std::vector<std::string> second_dexlayout_args =
480 { "-i", "-v", "-w", tmp_dir, "-o", tmp_name, "-p", profile_file, output_dex };
481 if (!DexLayoutExec(second_dexlayout_args, error_msg)) {
Bharadwaj Kalandhabhatta02ef6402017-05-17 17:13:39 -0700482 return false;
483 }
484
485 bool diff_result = true;
486 std::vector<std::string> diff_exec_argv =
487 { "/usr/bin/diff", output_dex, second_output_dex };
488 if (!::art::Exec(diff_exec_argv, error_msg)) {
489 diff_result = false;
490 }
491
492 std::vector<std::string> rm_exec_argv =
493 { "/bin/rm", dex_file, profile_file, output_dex, second_output_dex };
494 if (!::art::Exec(rm_exec_argv, error_msg)) {
495 return false;
496 }
497
498 return diff_result;
499 }
500
Jeff Haoac462712017-03-02 10:59:43 -0800501 // Runs UnreferencedCatchHandlerTest & Unreferenced0SizeCatchHandlerTest.
502 bool UnreferencedCatchHandlerExec(std::string* error_msg, const char* filename) {
Jeff Hao44652a32017-02-22 14:20:41 -0800503 ScratchFile tmp_file;
Andreas Gampe641a4732017-08-24 13:21:35 -0700504 const std::string& tmp_name = tmp_file.GetFilename();
Andreas Gampe5555dd12017-08-24 13:50:21 -0700505 size_t tmp_last_slash = tmp_name.rfind('/');
Jeff Hao44652a32017-02-22 14:20:41 -0800506 std::string tmp_dir = tmp_name.substr(0, tmp_last_slash + 1);
507
508 // Write inputs and expected outputs.
509 std::string input_dex = tmp_dir + "classes.dex";
Jeff Haoac462712017-03-02 10:59:43 -0800510 WriteFileBase64(filename, input_dex.c_str());
Jeff Hao44652a32017-02-22 14:20:41 -0800511 std::string output_dex = tmp_dir + "classes.dex.new";
512
Andreas Gampe693bfbf2017-11-10 12:23:31 -0800513 std::vector<std::string> dexlayout_args = { "-w", tmp_dir, "-o", "/dev/null", input_dex };
514 if (!DexLayoutExec(dexlayout_args, error_msg)) {
Jeff Hao44652a32017-02-22 14:20:41 -0800515 return false;
516 }
517
518 // Diff input and output. They should be the same.
519 std::vector<std::string> diff_exec_argv = { "/usr/bin/diff", input_dex, output_dex };
520 if (!::art::Exec(diff_exec_argv, error_msg)) {
521 return false;
522 }
523
524 std::vector<std::string> rm_exec_argv = { "/bin/rm", input_dex, output_dex };
525 if (!::art::Exec(rm_exec_argv, error_msg)) {
526 return false;
527 }
528 return true;
529 }
Jeff Haod9be7682017-04-05 09:29:43 -0700530
531 bool DexLayoutExec(ScratchFile* dex_file,
532 const char* dex_filename,
533 ScratchFile* profile_file,
Andreas Gampe693bfbf2017-11-10 12:23:31 -0800534 const std::vector<std::string>& dexlayout_args) {
Mathieu Chartieraf7c9022017-10-27 09:42:46 -0700535 if (dex_filename != nullptr) {
536 WriteBase64ToFile(dex_filename, dex_file->GetFile());
537 EXPECT_EQ(dex_file->GetFile()->Flush(), 0);
538 }
Jeff Haod9be7682017-04-05 09:29:43 -0700539 if (profile_file != nullptr) {
Mathieu Chartierd00e02b2017-05-24 12:04:13 -0700540 CreateProfile(dex_file->GetFilename(), profile_file->GetFilename(), dex_file->GetFilename());
Jeff Haod9be7682017-04-05 09:29:43 -0700541 }
Andreas Gampe693bfbf2017-11-10 12:23:31 -0800542
Jeff Haod9be7682017-04-05 09:29:43 -0700543 std::string error_msg;
Andreas Gampe693bfbf2017-11-10 12:23:31 -0800544 const bool result = DexLayoutExec(dexlayout_args, &error_msg);
Jeff Haod9be7682017-04-05 09:29:43 -0700545 if (!result) {
546 LOG(ERROR) << "Error: " << error_msg;
547 return false;
548 }
549 return true;
550 }
Andreas Gampe693bfbf2017-11-10 12:23:31 -0800551
552 bool DexLayoutExec(const std::vector<std::string>& dexlayout_args, std::string* error_msg) {
553 std::vector<std::string> argv;
554
555 std::string dexlayout = GetDexLayoutPath();
556 CHECK(OS::FileExists(dexlayout.c_str())) << dexlayout << " should be a valid file path";
557 argv.push_back(dexlayout);
558
559 argv.insert(argv.end(), dexlayout_args.begin(), dexlayout_args.end());
560
561 return ::art::Exec(argv, error_msg);
562 }
Jeff Haoc3acfc52016-08-29 14:18:26 -0700563};
564
565
566TEST_F(DexLayoutTest, FullPlainOutput) {
Jeff Hao0f7eaeb2016-08-31 17:56:13 -0700567 // Disable test on target.
568 TEST_DISABLED_FOR_TARGET();
Jeff Haoc3acfc52016-08-29 14:18:26 -0700569 std::string error_msg;
Jeff Haoa8621002016-10-04 18:13:44 +0000570 ASSERT_TRUE(FullPlainOutputExec(&error_msg)) << error_msg;
571}
572
573TEST_F(DexLayoutTest, DexFileOutput) {
574 // Disable test on target.
575 TEST_DISABLED_FOR_TARGET();
576 std::string error_msg;
577 ASSERT_TRUE(DexFileOutputExec(&error_msg)) << error_msg;
Jeff Haoc3acfc52016-08-29 14:18:26 -0700578}
579
Jeff Hao042e8982016-10-19 11:17:11 -0700580TEST_F(DexLayoutTest, DexFileLayout) {
581 // Disable test on target.
582 TEST_DISABLED_FOR_TARGET();
583 std::string error_msg;
584 ASSERT_TRUE(DexFileLayoutExec(&error_msg)) << error_msg;
585}
586
Bharadwaj Kalandhabhatta02ef6402017-05-17 17:13:39 -0700587TEST_F(DexLayoutTest, DexFileLayoutFixedPoint) {
588 // Disable test on target.
589 TEST_DISABLED_FOR_TARGET();
590 std::string error_msg;
591 ASSERT_TRUE(DexFileLayoutFixedPointExec(&error_msg)) << error_msg;
592}
593
Jeff Haoe17f5892017-02-23 16:14:04 -0800594TEST_F(DexLayoutTest, UnreferencedCatchHandler) {
595 // Disable test on target.
596 TEST_DISABLED_FOR_TARGET();
597 std::string error_msg;
Jeff Haoac462712017-03-02 10:59:43 -0800598 ASSERT_TRUE(UnreferencedCatchHandlerExec(&error_msg,
599 kUnreferencedCatchHandlerInputDex)) << error_msg;
Jeff Haoe17f5892017-02-23 16:14:04 -0800600}
Jeff Haoac462712017-03-02 10:59:43 -0800601
602TEST_F(DexLayoutTest, Unreferenced0SizeCatchHandler) {
603 // Disable test on target.
604 TEST_DISABLED_FOR_TARGET();
605 std::string error_msg;
606 ASSERT_TRUE(UnreferencedCatchHandlerExec(&error_msg,
607 kUnreferenced0SizeCatchHandlerInputDex)) << error_msg;
608}
609
Jeff Haoa64a64c2017-03-06 15:05:38 -0800610TEST_F(DexLayoutTest, UnreferencedEndingCatchHandler) {
611 // Disable test on target.
612 TEST_DISABLED_FOR_TARGET();
613 std::string error_msg;
614 ASSERT_TRUE(UnreferencedCatchHandlerExec(&error_msg,
615 kUnreferencedEndingCatchHandlerInputDex)) << error_msg;
616}
617
Mathieu Chartier6b0dbef2017-02-21 12:45:30 -0800618TEST_F(DexLayoutTest, DuplicateOffset) {
Jeff Haod9be7682017-04-05 09:29:43 -0700619 ScratchFile temp_dex;
Andreas Gampe693bfbf2017-11-10 12:23:31 -0800620 std::vector<std::string> dexlayout_args =
621 { "-a", "-i", "-o", "/dev/null", temp_dex.GetFilename() };
Jeff Haod9be7682017-04-05 09:29:43 -0700622 ASSERT_TRUE(DexLayoutExec(&temp_dex,
623 kDexFileDuplicateOffset,
624 nullptr /* profile_file */,
Andreas Gampe693bfbf2017-11-10 12:23:31 -0800625 dexlayout_args));
Mathieu Chartier6b0dbef2017-02-21 12:45:30 -0800626}
627
Jeff Haof914f8e2017-02-21 16:14:23 -0800628TEST_F(DexLayoutTest, NullSetRefListElement) {
Jeff Haod9be7682017-04-05 09:29:43 -0700629 ScratchFile temp_dex;
Andreas Gampe693bfbf2017-11-10 12:23:31 -0800630 std::vector<std::string> dexlayout_args = { "-o", "/dev/null", temp_dex.GetFilename() };
Jeff Haod9be7682017-04-05 09:29:43 -0700631 ASSERT_TRUE(DexLayoutExec(&temp_dex,
632 kNullSetRefListElementInputDex,
633 nullptr /* profile_file */,
Andreas Gampe693bfbf2017-11-10 12:23:31 -0800634 dexlayout_args));
Jeff Haof914f8e2017-02-21 16:14:23 -0800635}
636
Jeff Haoe17f5892017-02-23 16:14:04 -0800637TEST_F(DexLayoutTest, MultiClassData) {
Jeff Haod9be7682017-04-05 09:29:43 -0700638 ScratchFile temp_dex;
639 ScratchFile temp_profile;
Andreas Gampe693bfbf2017-11-10 12:23:31 -0800640 std::vector<std::string> dexlayout_args =
641 { "-p", temp_profile.GetFilename(), "-o", "/dev/null", temp_dex.GetFilename() };
Jeff Haod9be7682017-04-05 09:29:43 -0700642 ASSERT_TRUE(DexLayoutExec(&temp_dex,
643 kMultiClassDataInputDex,
644 &temp_profile,
Andreas Gampe693bfbf2017-11-10 12:23:31 -0800645 dexlayout_args));
Jeff Haoe17f5892017-02-23 16:14:04 -0800646}
647
648TEST_F(DexLayoutTest, UnalignedCodeInfo) {
Jeff Haod9be7682017-04-05 09:29:43 -0700649 ScratchFile temp_dex;
650 ScratchFile temp_profile;
Andreas Gampe693bfbf2017-11-10 12:23:31 -0800651 std::vector<std::string> dexlayout_args =
652 { "-p", temp_profile.GetFilename(), "-o", "/dev/null", temp_dex.GetFilename() };
Jeff Haod9be7682017-04-05 09:29:43 -0700653 ASSERT_TRUE(DexLayoutExec(&temp_dex,
654 kUnalignedCodeInfoInputDex,
655 &temp_profile,
Andreas Gampe693bfbf2017-11-10 12:23:31 -0800656 dexlayout_args));
Jeff Hao44652a32017-02-22 14:20:41 -0800657}
658
Jeff Hao32a60ab2017-03-01 16:44:50 -0800659TEST_F(DexLayoutTest, ClassDataBeforeCode) {
Jeff Haod9be7682017-04-05 09:29:43 -0700660 ScratchFile temp_dex;
661 ScratchFile temp_profile;
Andreas Gampe693bfbf2017-11-10 12:23:31 -0800662 std::vector<std::string> dexlayout_args =
663 { "-p", temp_profile.GetFilename(), "-o", "/dev/null", temp_dex.GetFilename() };
Jeff Haod9be7682017-04-05 09:29:43 -0700664 ASSERT_TRUE(DexLayoutExec(&temp_dex,
665 kClassDataBeforeCodeInputDex,
666 &temp_profile,
Andreas Gampe693bfbf2017-11-10 12:23:31 -0800667 dexlayout_args));
Jeff Haod9be7682017-04-05 09:29:43 -0700668}
669
670TEST_F(DexLayoutTest, UnknownTypeDebugInfo) {
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 Haod9be7682017-04-05 09:29:43 -0700673 ASSERT_TRUE(DexLayoutExec(&temp_dex,
674 kUnknownTypeDebugInfoInputDex,
675 nullptr /* profile_file */,
Andreas Gampe693bfbf2017-11-10 12:23:31 -0800676 dexlayout_args));
Jeff Hao32a60ab2017-03-01 16:44:50 -0800677}
678
Jeff Haod212d5b2017-04-26 12:09:06 -0700679TEST_F(DexLayoutTest, DuplicateCodeItem) {
680 ScratchFile temp_dex;
Andreas Gampe693bfbf2017-11-10 12:23:31 -0800681 std::vector<std::string> dexlayout_args = { "-o", "/dev/null", temp_dex.GetFilename() };
Jeff Haod212d5b2017-04-26 12:09:06 -0700682 ASSERT_TRUE(DexLayoutExec(&temp_dex,
683 kDuplicateCodeItemInputDex,
684 nullptr /* profile_file */,
Andreas Gampe693bfbf2017-11-10 12:23:31 -0800685 dexlayout_args));
Jeff Haod212d5b2017-04-26 12:09:06 -0700686}
687
Mathieu Chartieraf7c9022017-10-27 09:42:46 -0700688// Test that instructions that go past the end of the code items don't cause crashes.
689TEST_F(DexLayoutTest, CodeItemOverrun) {
690 ScratchFile temp_dex;
691 MutateDexFile(temp_dex.GetFile(), GetTestDexFileName("ManyMethods"), [] (DexFile* dex) {
692 bool mutated_successfully = false;
693 // Change the dex instructions to make an opcode that spans past the end of the code item.
694 for (size_t i = 0; i < dex->NumClassDefs(); ++i) {
695 const DexFile::ClassDef& def = dex->GetClassDef(i);
696 const uint8_t* data = dex->GetClassData(def);
697 if (data == nullptr) {
698 continue;
699 }
700 ClassDataItemIterator it(*dex, data);
701 it.SkipAllFields();
Mathieu Chartierb7c273c2017-11-10 18:07:56 -0800702 while (it.HasNextMethod()) {
Mathieu Chartieraf7c9022017-10-27 09:42:46 -0700703 DexFile::CodeItem* item = const_cast<DexFile::CodeItem*>(it.GetMethodCodeItem());
704 if (item != nullptr) {
Mathieu Chartier698ebbc2018-01-05 11:00:42 -0800705 CodeItemInstructionAccessor instructions(*dex, item);
Mathieu Chartieraf7c9022017-10-27 09:42:46 -0700706 if (instructions.begin() != instructions.end()) {
707 DexInstructionIterator last_instruction = instructions.begin();
708 for (auto dex_it = instructions.begin(); dex_it != instructions.end(); ++dex_it) {
709 last_instruction = dex_it;
710 }
711 if (last_instruction->SizeInCodeUnits() == 1) {
712 // Set the opcode to something that will go past the end of the code item.
Mathieu Chartier2b2bef22017-10-26 17:10:19 -0700713 const_cast<Instruction&>(last_instruction.Inst()).SetOpcode(
Mathieu Chartieraf7c9022017-10-27 09:42:46 -0700714 Instruction::CONST_STRING_JUMBO);
715 mutated_successfully = true;
Mathieu Chartier176190c2017-10-31 09:58:07 -0700716 // Test that the safe iterator doesn't go past the end.
717 SafeDexInstructionIterator it2(instructions.begin(), instructions.end());
718 while (!it2.IsErrorState()) {
719 ++it2;
720 }
721 EXPECT_TRUE(it2 == last_instruction);
722 EXPECT_TRUE(it2 < instructions.end());
Mathieu Chartieraf7c9022017-10-27 09:42:46 -0700723 }
724 }
725 }
726 it.Next();
727 }
728 }
729 CHECK(mutated_successfully)
730 << "Failed to find candidate code item with only one code unit in last instruction.";
731 });
Andreas Gampe693bfbf2017-11-10 12:23:31 -0800732 std::vector<std::string> dexlayout_args = { "-i", "-o", "/dev/null", temp_dex.GetFilename() };
Mathieu Chartieraf7c9022017-10-27 09:42:46 -0700733 ASSERT_TRUE(DexLayoutExec(&temp_dex,
734 /*dex_filename*/ nullptr,
735 nullptr /* profile_file */,
Andreas Gampe693bfbf2017-11-10 12:23:31 -0800736 dexlayout_args));
Mathieu Chartieraf7c9022017-10-27 09:42:46 -0700737}
738
Mathieu Chartier2f36d2f2017-11-20 15:45:25 -0800739// Test that link data is written out (or at least the header is updated).
740TEST_F(DexLayoutTest, LinkData) {
Mathieu Chartierfe9185a2017-11-21 19:01:10 -0800741 TEST_DISABLED_FOR_TARGET();
Mathieu Chartier2f36d2f2017-11-20 15:45:25 -0800742 ScratchFile temp_dex;
743 size_t file_size = 0;
744 MutateDexFile(temp_dex.GetFile(), GetTestDexFileName("ManyMethods"), [&] (DexFile* dex) {
745 DexFile::Header& header = const_cast<DexFile::Header&>(dex->GetHeader());
746 header.link_off_ = header.file_size_;
747 header.link_size_ = 16 * KB;
748 header.file_size_ += header.link_size_;
749 file_size = header.file_size_;
750 });
751 TEMP_FAILURE_RETRY(temp_dex.GetFile()->SetLength(file_size));
752
753 std::string error_msg;
754
755 ScratchFile tmp_file;
756 const std::string& tmp_name = tmp_file.GetFilename();
757 size_t tmp_last_slash = tmp_name.rfind('/');
758 std::string tmp_dir = tmp_name.substr(0, tmp_last_slash + 1);
759 ScratchFile profile_file;
760
761 std::vector<std::string> dexlayout_args =
762 { "-i",
763 "-v",
764 "-w", tmp_dir,
765 "-o", tmp_name,
766 "-p", profile_file.GetFilename(),
767 temp_dex.GetFilename()
768 };
769 // -v makes sure that the layout did not corrupt the dex file.
770 ASSERT_TRUE(DexLayoutExec(&temp_dex,
771 /*dex_filename*/ nullptr,
772 &profile_file,
773 dexlayout_args));
774
775 std::string output_dex = temp_dex.GetFilename() + ".new";
776 std::vector<std::string> rm_exec_argv =
777 { "/bin/rm", output_dex };
778 ASSERT_TRUE(::art::Exec(rm_exec_argv, &error_msg));
779}
780
Jeff Haoc3acfc52016-08-29 14:18:26 -0700781} // namespace art