blob: c4f7accc8c5a041ce70db3b1f43e5ae0ac4e7e2d [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"
Mathieu Chartierd00e02b2017-05-24 12:04:13 -070026#include "dex_file-inl.h"
Mathieu Chartier79c87da2017-10-10 11:54:29 -070027#include "dex_file_loader.h"
David Sehr97c381e2017-02-01 15:09:58 -080028#include "exec_utils.h"
Mathieu Chartierd00e02b2017-05-24 12:04:13 -070029#include "jit/profile_compilation_info.h"
Jeff Haoc3acfc52016-08-29 14:18:26 -070030#include "utils.h"
31
32namespace art {
33
Jeff Hao042e8982016-10-19 11:17:11 -070034static const char kDexFileLayoutInputDex[] =
35 "ZGV4CjAzNQD1KW3+B8NAB0f2A/ZVIBJ0aHrGIqcpVTAUAgAAcAAAAHhWNBIAAAAAAAAAAIwBAAAH"
36 "AAAAcAAAAAQAAACMAAAAAQAAAJwAAAAAAAAAAAAAAAMAAACoAAAAAgAAAMAAAAAUAQAAAAEAADAB"
37 "AAA4AQAAQAEAAEgBAABNAQAAUgEAAGYBAAADAAAABAAAAAUAAAAGAAAABgAAAAMAAAAAAAAAAAAA"
38 "AAAAAAABAAAAAAAAAAIAAAAAAAAAAAAAAAAAAAACAAAAAAAAAAEAAAAAAAAAdQEAAAAAAAABAAAA"
39 "AAAAAAIAAAAAAAAAAgAAAAAAAAB/AQAAAAAAAAEAAQABAAAAaQEAAAQAAABwEAIAAAAOAAEAAQAB"
40 "AAAAbwEAAAQAAABwEAIAAAAOAAY8aW5pdD4ABkEuamF2YQAGQi5qYXZhAANMQTsAA0xCOwASTGph"
41 "dmEvbGFuZy9PYmplY3Q7AAFWAAQABw48AAQABw48AAAAAQAAgIAEgAIAAAEAAYCABJgCAAAACwAA"
42 "AAAAAAABAAAAAAAAAAEAAAAHAAAAcAAAAAIAAAAEAAAAjAAAAAMAAAABAAAAnAAAAAUAAAADAAAA"
43 "qAAAAAYAAAACAAAAwAAAAAEgAAACAAAAAAEAAAIgAAAHAAAAMAEAAAMgAAACAAAAaQEAAAAgAAAC"
44 "AAAAdQEAAAAQAAABAAAAjAEAAA==";
45
Jeff Haoe17f5892017-02-23 16:14:04 -080046// Dex file with catch handler unreferenced by try blocks.
47// Constructed by building a dex file with try/catch blocks and hex editing.
48static const char kUnreferencedCatchHandlerInputDex[] =
49 "ZGV4CjAzNQD+exd52Y0f9nY5x5GmInXq5nXrO6Kl2RV4AwAAcAAAAHhWNBIAAAAAAAAAANgCAAAS"
50 "AAAAcAAAAAgAAAC4AAAAAwAAANgAAAABAAAA/AAAAAQAAAAEAQAAAQAAACQBAAA0AgAARAEAANYB"
51 "AADeAQAA5gEAAO4BAAAAAgAADwIAACYCAAA9AgAAUQIAAGUCAAB5AgAAfwIAAIUCAACIAgAAjAIA"
52 "AKECAACnAgAArAIAAAQAAAAFAAAABgAAAAcAAAAIAAAACQAAAAwAAAAOAAAADAAAAAYAAAAAAAAA"
53 "DQAAAAYAAADIAQAADQAAAAYAAADQAQAABQABABAAAAAAAAAAAAAAAAAAAgAPAAAAAQABABEAAAAD"
54 "AAAAAAAAAAAAAAABAAAAAwAAAAAAAAADAAAAAAAAAMgCAAAAAAAAAQABAAEAAAC1AgAABAAAAHAQ"
55 "AwAAAA4AAwABAAIAAgC6AgAAIQAAAGIAAAAaAQoAbiACABAAYgAAABoBCwBuIAIAEAAOAA0AYgAA"
56 "ABoBAQBuIAIAEAAo8A0AYgAAABoBAgBuIAIAEAAo7gAAAAAAAAcAAQAHAAAABwABAAIBAg8BAhgA"
57 "AQAAAAQAAAABAAAABwAGPGluaXQ+AAZDYXRjaDEABkNhdGNoMgAQSGFuZGxlclRlc3QuamF2YQAN"
58 "TEhhbmRsZXJUZXN0OwAVTGphdmEvaW8vUHJpbnRTdHJlYW07ABVMamF2YS9sYW5nL0V4Y2VwdGlv"
59 "bjsAEkxqYXZhL2xhbmcvT2JqZWN0OwASTGphdmEvbGFuZy9TdHJpbmc7ABJMamF2YS9sYW5nL1N5"
60 "c3RlbTsABFRyeTEABFRyeTIAAVYAAlZMABNbTGphdmEvbGFuZy9TdHJpbmc7AARtYWluAANvdXQA"
61 "B3ByaW50bG4AAQAHDgAEAQAHDn17AncdHoseAAAAAgAAgYAExAIBCdwCAAANAAAAAAAAAAEAAAAA"
62 "AAAAAQAAABIAAABwAAAAAgAAAAgAAAC4AAAAAwAAAAMAAADYAAAABAAAAAEAAAD8AAAABQAAAAQA"
63 "AAAEAQAABgAAAAEAAAAkAQAAASAAAAIAAABEAQAAARAAAAIAAADIAQAAAiAAABIAAADWAQAAAyAA"
64 "AAIAAAC1AgAAACAAAAEAAADIAgAAABAAAAEAAADYAgAA";
65
Jeff Haoac462712017-03-02 10:59:43 -080066// Dex file with 0-size (catch all only) catch handler unreferenced by try blocks.
67// Constructed by building a dex file with try/catch blocks and hex editing.
68static const char kUnreferenced0SizeCatchHandlerInputDex[] =
69 "ZGV4CjAzNQCEbEEvMstSNpQpjPdfMEfUBS48cis2QRJoAwAAcAAAAHhWNBIAAAAAAAAAAMgCAAAR"
70 "AAAAcAAAAAcAAAC0AAAAAwAAANAAAAABAAAA9AAAAAQAAAD8AAAAAQAAABwBAAAsAgAAPAEAAOoB"
71 "AADyAQAABAIAABMCAAAqAgAAPgIAAFICAABmAgAAaQIAAG0CAACCAgAAhgIAAIoCAACQAgAAlQIA"
72 "AJ4CAACiAgAAAgAAAAMAAAAEAAAABQAAAAYAAAAHAAAACQAAAAcAAAAFAAAAAAAAAAgAAAAFAAAA"
73 "3AEAAAgAAAAFAAAA5AEAAAQAAQANAAAAAAAAAAAAAAAAAAIADAAAAAEAAQAOAAAAAgAAAAAAAAAA"
74 "AAAAAQAAAAIAAAAAAAAAAQAAAAAAAAC5AgAAAAAAAAEAAQABAAAApgIAAAQAAABwEAMAAAAOAAQA"
75 "AQACAAIAqwIAAC8AAABiAAAAGgEPAG4gAgAQAGIAAAAaAQoAbiACABAAYgAAABoBEABuIAIAEABi"
76 "AAAAGgELAG4gAgAQAA4ADQBiAQAAGgIKAG4gAgAhACcADQBiAQAAGgILAG4gAgAhACcAAAAAAAAA"
77 "BwABAA4AAAAHAAEAAgAdACYAAAABAAAAAwAAAAEAAAAGAAY8aW5pdD4AEEhhbmRsZXJUZXN0Lmph"
78 "dmEADUxIYW5kbGVyVGVzdDsAFUxqYXZhL2lvL1ByaW50U3RyZWFtOwASTGphdmEvbGFuZy9PYmpl"
79 "Y3Q7ABJMamF2YS9sYW5nL1N0cmluZzsAEkxqYXZhL2xhbmcvU3lzdGVtOwABVgACVkwAE1tMamF2"
80 "YS9sYW5nL1N0cmluZzsAAmYxAAJmMgAEbWFpbgADb3V0AAdwcmludGxuAAJ0MQACdDIAAQAHDgAE"
81 "AQAHDnl7eXkCeB2bAAAAAgAAgYAEvAIBCdQCAA0AAAAAAAAAAQAAAAAAAAABAAAAEQAAAHAAAAAC"
82 "AAAABwAAALQAAAADAAAAAwAAANAAAAAEAAAAAQAAAPQAAAAFAAAABAAAAPwAAAAGAAAAAQAAABwB"
83 "AAABIAAAAgAAADwBAAABEAAAAgAAANwBAAACIAAAEQAAAOoBAAADIAAAAgAAAKYCAAAAIAAAAQAA"
84 "ALkCAAAAEAAAAQAAAMgCAAA=";
85
Jeff Haoa64a64c2017-03-06 15:05:38 -080086// Dex file with an unreferenced catch handler at end of code item.
87// Constructed by building a dex file with try/catch blocks and hex editing.
88static const char kUnreferencedEndingCatchHandlerInputDex[] =
89 "ZGV4CjAzNQCEflufI6xGTDDRmLpbfYi6ujPrDLIwvYcEBAAAcAAAAHhWNBIAAAAAAAAAAGQDAAAT"
90 "AAAAcAAAAAgAAAC8AAAAAwAAANwAAAABAAAAAAEAAAUAAAAIAQAAAQAAADABAAC0AgAAUAEAAE4C"
91 "AABWAgAAXgIAAGYCAAB4AgAAhwIAAJ4CAAC1AgAAyQIAAN0CAADxAgAA9wIAAP0CAAAAAwAABAMA"
92 "ABkDAAAcAwAAIgMAACcDAAAEAAAABQAAAAYAAAAHAAAACAAAAAkAAAAMAAAADgAAAAwAAAAGAAAA"
93 "AAAAAA0AAAAGAAAAQAIAAA0AAAAGAAAASAIAAAUAAQARAAAAAAAAAAAAAAAAAAAADwAAAAAAAgAQ"
94 "AAAAAQABABIAAAADAAAAAAAAAAAAAAABAAAAAwAAAAAAAAADAAAAAAAAAFADAAAAAAAAAQABAAEA"
95 "AAAwAwAABAAAAHAQBAAAAA4AAgAAAAIAAgA1AwAAIQAAAGIAAAAaAQoAbiADABAAYgAAABoBCwBu"
96 "IAMAEAAOAA0AYgAAABoBAQBuIAMAEAAo8A0AYgAAABoBAgBuIAMAEAAo7gAAAAAAAAcAAQAHAAAA"
97 "BwABAAIBAg8BAhgAAwABAAIAAgBCAwAAIQAAAGIAAAAaAQoAbiADABAAYgAAABoBCwBuIAMAEAAO"
98 "AA0AYgAAABoBAQBuIAMAEAAo8A0AYgAAABoBAgBuIAMAEAAo7gAAAAAAAAcAAQAHAAAABwABAAIB"
99 "Ag8BAhgAAQAAAAQAAAABAAAABwAGPGluaXQ+AAZDYXRjaDEABkNhdGNoMgAQSGFuZGxlclRlc3Qu"
100 "amF2YQANTEhhbmRsZXJUZXN0OwAVTGphdmEvaW8vUHJpbnRTdHJlYW07ABVMamF2YS9sYW5nL0V4"
101 "Y2VwdGlvbjsAEkxqYXZhL2xhbmcvT2JqZWN0OwASTGphdmEvbGFuZy9TdHJpbmc7ABJMamF2YS9s"
102 "YW5nL1N5c3RlbTsABFRyeTEABFRyeTIAAVYAAlZMABNbTGphdmEvbGFuZy9TdHJpbmc7AAFhAARt"
103 "YWluAANvdXQAB3ByaW50bG4AAQAHDgAEAAcOfHsCeB0eih4AEQEABw59ewJ3HR6LHgAAAAMAAIGA"
104 "BNACAQnoAgEJ1AMAAA0AAAAAAAAAAQAAAAAAAAABAAAAEwAAAHAAAAACAAAACAAAALwAAAADAAAA"
105 "AwAAANwAAAAEAAAAAQAAAAABAAAFAAAABQAAAAgBAAAGAAAAAQAAADABAAABIAAAAwAAAFABAAAB"
106 "EAAAAgAAAEACAAACIAAAEwAAAE4CAAADIAAAAwAAADADAAAAIAAAAQAAAFADAAAAEAAAAQAAAGQD"
107 "AAA=";
108
Mathieu Chartier6b0dbef2017-02-21 12:45:30 -0800109// Dex file with multiple code items that have the same debug_info_off_. Constructed by a modified
110// dexlayout on XandY.
111static const char kDexFileDuplicateOffset[] =
112 "ZGV4CjAzNwAQfXfPCB8qCxo7MqdFhmHZQwCv8+udHD8MBAAAcAAAAHhWNBIAAAAAAAAAAFQDAAAT"
113 "AAAAcAAAAAgAAAC8AAAAAQAAANwAAAABAAAA6AAAAAUAAADwAAAAAwAAABgBAACUAgAAeAEAABQC"
114 "AAAeAgAAJgIAACsCAAAyAgAANwIAAFsCAAB7AgAAngIAALICAAC1AgAAvQIAAMUCAADIAgAA1QIA"
115 "AOkCAADvAgAA9QIAAPwCAAACAAAAAwAAAAQAAAAFAAAABgAAAAcAAAAIAAAACQAAAAkAAAAHAAAA"
116 "AAAAAAIAAQASAAAAAAAAAAEAAAABAAAAAQAAAAIAAAAAAAAAAgAAAAEAAAAGAAAAAQAAAAAAAAAA"
117 "AAAABgAAAAAAAAAKAAAAAAAAACsDAAAAAAAAAQAAAAAAAAAGAAAAAAAAAAsAAAD0AQAANQMAAAAA"
118 "AAACAAAAAAAAAAAAAAAAAAAACwAAAAQCAAA/AwAAAAAAAAIAAAAUAwAAGgMAAAEAAAAjAwAAAQAB"
119 "AAEAAAAFAAAABAAAAHAQBAAAAA4AAQABAAEAAAAFAAAABAAAAHAQBAAAAA4AAQAAAAEAAAAFAAAA"
120 "CAAAACIAAQBwEAEAAABpAAAADgABAAEAAQAAAAUAAAAEAAAAcBAAAAAADgB4AQAAAAAAAAAAAAAA"
121 "AAAAhAEAAAAAAAAAAAAAAAAAAAg8Y2xpbml0PgAGPGluaXQ+AANMWDsABUxZJFo7AANMWTsAIkxk"
122 "YWx2aWsvYW5ub3RhdGlvbi9FbmNsb3NpbmdDbGFzczsAHkxkYWx2aWsvYW5ub3RhdGlvbi9Jbm5l"
123 "ckNsYXNzOwAhTGRhbHZpay9hbm5vdGF0aW9uL01lbWJlckNsYXNzZXM7ABJMamF2YS9sYW5nL09i"
124 "amVjdDsAAVYABlguamF2YQAGWS5qYXZhAAFaAAthY2Nlc3NGbGFncwASZW1pdHRlcjogamFjay00"
125 "LjI1AARuYW1lAAR0aGlzAAV2YWx1ZQABegARAAcOABMABw4AEgAHDnYAEQAHDgACAwERGAICBAIN"
126 "BAgPFwwCBQERHAEYAQAAAQAAgIAEjAMAAAEAAYCABKQDAQACAAAIAoiABLwDAYCABNwDAAAADwAA"
127 "AAAAAAABAAAAAAAAAAEAAAATAAAAcAAAAAIAAAAIAAAAvAAAAAMAAAABAAAA3AAAAAQAAAABAAAA"
128 "6AAAAAUAAAAFAAAA8AAAAAYAAAADAAAAGAEAAAMQAAACAAAAeAEAAAEgAAAEAAAAjAEAAAYgAAAC"
129 "AAAA9AEAAAIgAAATAAAAFAIAAAMgAAAEAAAA/wIAAAQgAAADAAAAFAMAAAAgAAADAAAAKwMAAAAQ"
130 "AAABAAAAVAMAAA==";
131
Jeff Haof914f8e2017-02-21 16:14:23 -0800132// Dex file with null value for annotations_off in the annotation_set_ref_list.
133// Constructed by building a dex file with annotations and hex editing.
134static const char kNullSetRefListElementInputDex[] =
135 "ZGV4CjAzNQB1iA+7ZwgkF+7E6ZesYFc2lRAR3qnRAanwAwAAcAAAAHhWNBIAAAAAAAAAACADAAAS"
136 "AAAAcAAAAAgAAAC4AAAAAwAAANgAAAABAAAA/AAAAAQAAAAEAQAAAgAAACQBAACMAgAAZAEAAOgB"
137 "AADwAQAAAAIAAAMCAAAQAgAAIAIAADQCAABIAgAAawIAAI0CAAC1AgAAyAIAANECAADUAgAA2QIA"
138 "ANwCAADjAgAA6QIAAAMAAAAEAAAABQAAAAYAAAAHAAAACAAAAAkAAAAMAAAAAgAAAAMAAAAAAAAA"
139 "DAAAAAcAAAAAAAAADQAAAAcAAADgAQAABgAGAAsAAAAAAAEAAAAAAAAAAgAOAAAAAQAAABAAAAAC"
140 "AAEAAAAAAAAAAAAAAAAAAgAAAAAAAAABAAAAsAEAAAgDAAAAAAAAAQAAAAEmAAACAAAA2AEAAAoA"
141 "AADIAQAAFgMAAAAAAAACAAAAAAAAAHwBAAABAAAA/AIAAAAAAAABAAAAAgMAAAEAAQABAAAA8AIA"
142 "AAQAAABwEAMAAAAOAAIAAgAAAAAA9QIAAAEAAAAOAAAAAAAAAAAAAAAAAAAAAQAAAAEAAABkAQAA"
143 "cAEAAAAAAAAAAAAAAAAAAAEAAAAEAAAAAgAAAAMAAwAGPGluaXQ+AA5Bbm5vQ2xhc3MuamF2YQAB"
144 "TAALTEFubm9DbGFzczsADkxNeUFubm90YXRpb247ABJMamF2YS9sYW5nL09iamVjdDsAEkxqYXZh"
145 "L2xhbmcvU3RyaW5nOwAhTGphdmEvbGFuZy9hbm5vdGF0aW9uL0Fubm90YXRpb247ACBMamF2YS9s"
146 "YW5nL2Fubm90YXRpb24vUmV0ZW50aW9uOwAmTGphdmEvbGFuZy9hbm5vdGF0aW9uL1JldGVudGlv"
147 "blBvbGljeTsAEU15QW5ub3RhdGlvbi5qYXZhAAdSVU5USU1FAAFWAANWTEwAAWEABWFOYW1lAARu"
148 "YW1lAAV2YWx1ZQABAAcOAAICAAAHDgABBQERGwABAQEQFw8AAAIAAICABIQDAQmcAwAAAAECgQgA"
149 "AAARAAAAAAAAAAEAAAAAAAAAAQAAABIAAABwAAAAAgAAAAgAAAC4AAAAAwAAAAMAAADYAAAABAAA"
150 "AAEAAAD8AAAABQAAAAQAAAAEAQAABgAAAAIAAAAkAQAAAhAAAAEAAABkAQAAAxAAAAMAAABwAQAA"
151 "ASAAAAIAAACEAQAABiAAAAIAAACwAQAAARAAAAIAAADYAQAAAiAAABIAAADoAQAAAyAAAAIAAADw"
152 "AgAABCAAAAIAAAD8AgAAACAAAAIAAAAIAwAAABAAAAEAAAAgAwAA";
153
Jeff Haoe17f5892017-02-23 16:14:04 -0800154// Dex file with shared empty class data item for multiple class defs.
155// Constructing by building a dex file with multiple classes and hex editing.
156static const char kMultiClassDataInputDex[] =
157 "ZGV4CjAzNQALJgF9TtnLq748xVe/+wyxETrT9lTEiW6YAQAAcAAAAHhWNBIAAAAAAAAAADQBAAAI"
158 "AAAAcAAAAAQAAACQAAAAAAAAAAAAAAACAAAAoAAAAAAAAAAAAAAAAgAAALAAAACoAAAA8AAAAPAA"
159 "AAD4AAAAAAEAAAMBAAAIAQAADQEAACEBAAAkAQAAAgAAAAMAAAAEAAAABQAAAAEAAAAGAAAAAgAA"
160 "AAcAAAABAAAAAQYAAAMAAAAAAAAAAAAAAAAAAAAnAQAAAAAAAAIAAAABBgAAAwAAAAAAAAABAAAA"
161 "AAAAACcBAAAAAAAABkEuamF2YQAGQi5qYXZhAAFJAANMQTsAA0xCOwASTGphdmEvbGFuZy9PYmpl"
162 "Y3Q7AAFhAAFiAAAAAAABAAAAARkAAAAIAAAAAAAAAAEAAAAAAAAAAQAAAAgAAABwAAAAAgAAAAQA"
163 "AACQAAAABAAAAAIAAACgAAAABgAAAAIAAACwAAAAAiAAAAgAAADwAAAAACAAAAIAAAAnAQAAABAA"
164 "AAEAAAA0AQAA";
165
166// Dex file with code info followed by non 4-byte aligned section.
167// Constructed a dex file with code info followed by string data and hex edited.
168static const char kUnalignedCodeInfoInputDex[] =
169 "ZGV4CjAzNQDXJzXNb4iWn2SLhmLydW/8h1K9moERIw7UAQAAcAAAAHhWNBIAAAAAAAAAAEwBAAAG"
170 "AAAAcAAAAAMAAACIAAAAAQAAAJQAAAAAAAAAAAAAAAMAAACgAAAAAQAAALgAAAD8AAAA2AAAAAIB"
171 "AAAKAQAAEgEAABcBAAArAQAALgEAAAIAAAADAAAABAAAAAQAAAACAAAAAAAAAAAAAAAAAAAAAAAA"
172 "AAUAAAABAAAAAAAAAAAAAAABAAAAAQAAAAAAAAABAAAAAAAAADsBAAAAAAAAAQABAAEAAAAxAQAA"
173 "BAAAAHAQAgAAAA4AAQABAAAAAAA2AQAAAQAAAA4ABjxpbml0PgAGQS5qYXZhAANMQTsAEkxqYXZh"
174 "L2xhbmcvT2JqZWN0OwABVgABYQABAAcOAAMABw4AAAABAQCBgATYAQEB8AEAAAALAAAAAAAAAAEA"
175 "AAAAAAAAAQAAAAYAAABwAAAAAgAAAAMAAACIAAAAAwAAAAEAAACUAAAABQAAAAMAAACgAAAABgAA"
176 "AAEAAAC4AAAAASAAAAIAAADYAAAAAiAAAAYAAAACAQAAAyAAAAIAAAAxAQAAACAAAAEAAAA7AQAA"
177 "ABAAAAEAAABMAQAA";
Jeff Hao44652a32017-02-22 14:20:41 -0800178
Jeff Hao32a60ab2017-03-01 16:44:50 -0800179// Dex file with class data section preceding code items.
180// Constructed by passing dex file through dexmerger tool and hex editing.
181static const char kClassDataBeforeCodeInputDex[] =
182 "ZGV4CjAzNQCZKmCu3XXn4zvxCh5VH0gZNNobEAcsc49EAgAAcAAAAHhWNBIAAAAAAAAAAAQBAAAJ"
183 "AAAAcAAAAAQAAACUAAAAAgAAAKQAAAAAAAAAAAAAAAUAAAC8AAAAAQAAAOQAAABAAQAABAEAAPgB"
184 "AAAAAgAACAIAAAsCAAAQAgAAJAIAACcCAAAqAgAALQIAAAIAAAADAAAABAAAAAUAAAACAAAAAAAA"
185 "AAAAAAAFAAAAAwAAAAAAAAABAAEAAAAAAAEAAAAGAAAAAQAAAAcAAAABAAAACAAAAAIAAQAAAAAA"
186 "AQAAAAEAAAACAAAAAAAAAAEAAAAAAAAAjAEAAAAAAAALAAAAAAAAAAEAAAAAAAAAAQAAAAkAAABw"
187 "AAAAAgAAAAQAAACUAAAAAwAAAAIAAACkAAAABQAAAAUAAAC8AAAABgAAAAEAAADkAAAAABAAAAEA"
188 "AAAEAQAAACAAAAEAAACMAQAAASAAAAQAAACkAQAAAiAAAAkAAAD4AQAAAyAAAAQAAAAwAgAAAAAB"
189 "AwCBgASkAwEBvAMBAdADAQHkAwAAAQABAAEAAAAwAgAABAAAAHAQBAAAAA4AAgABAAAAAAA1AgAA"
190 "AgAAABIQDwACAAEAAAAAADoCAAACAAAAEiAPAAIAAQAAAAAAPwIAAAIAAAASMA8ABjxpbml0PgAG"
191 "QS5qYXZhAAFJAANMQTsAEkxqYXZhL2xhbmcvT2JqZWN0OwABVgABYQABYgABYwABAAcOAAMABw4A"
192 "BgAHDgAJAAcOAA==";
193
Jeff Haod9be7682017-04-05 09:29:43 -0700194// Dex file with local info containing a null type descriptor.
195// Constructed a dex file with debug info sequence containing DBG_RESTART_LOCAL without any
196// DBG_START_LOCAL to give it a declared type.
197static const char kUnknownTypeDebugInfoInputDex[] =
198 "ZGV4CjAzNQBtKqZfzjHLNSNwW2A6Bz9FuCEX0sL+FF38AQAAcAAAAHhWNBIAAAAAAAAAAHQBAAAI"
199 "AAAAcAAAAAQAAACQAAAAAgAAAKAAAAAAAAAAAAAAAAMAAAC4AAAAAQAAANAAAAAMAQAA8AAAABwB"
200 "AAAkAQAALAEAAC8BAAA0AQAASAEAAEsBAABOAQAAAgAAAAMAAAAEAAAABQAAAAIAAAAAAAAAAAAA"
201 "AAUAAAADAAAAAAAAAAEAAQAAAAAAAQAAAAYAAAACAAEAAAAAAAEAAAABAAAAAgAAAAAAAAABAAAA"
202 "AAAAAGMBAAAAAAAAAQABAAEAAABUAQAABAAAAHAQAgAAAA4AAgABAAAAAABZAQAAAgAAABIQDwAG"
203 "PGluaXQ+AAZBLmphdmEAAUkAA0xBOwASTGphdmEvbGFuZy9PYmplY3Q7AAFWAAFhAAR0aGlzAAEA"
204 "Bw4AAwAHDh4GAAYAAAAAAQEAgYAE8AEBAYgCAAAACwAAAAAAAAABAAAAAAAAAAEAAAAIAAAAcAAA"
205 "AAIAAAAEAAAAkAAAAAMAAAACAAAAoAAAAAUAAAADAAAAuAAAAAYAAAABAAAA0AAAAAEgAAACAAAA"
206 "8AAAAAIgAAAIAAAAHAEAAAMgAAACAAAAVAEAAAAgAAABAAAAYwEAAAAQAAABAAAAdAEAAA==";
207
Jeff Haod212d5b2017-04-26 12:09:06 -0700208// Dex file with multiple class data items pointing to the same code item.
209// Constructed by hex editing.
210static const char kDuplicateCodeItemInputDex[] =
211 "ZGV4CjAzNQCwKtVglQOmLWuHwldN5jkBOInC7mTMhJMAAgAAcAAAAHhWNBIAAAAAAAAAAHgBAAAH"
212 "AAAAcAAAAAMAAACMAAAAAQAAAJgAAAAAAAAAAAAAAAQAAACkAAAAAQAAAMQAAAAcAQAA5AAAACQB"
213 "AAAsAQAANAEAADkBAABNAQAAUAEAAFMBAAACAAAAAwAAAAQAAAAEAAAAAgAAAAAAAAAAAAAAAAAA"
214 "AAAAAAAFAAAAAAAAAAYAAAABAAAAAAAAAAAAAAABAAAAAQAAAAAAAAABAAAAAAAAAGUBAAAAAAAA"
215 "AQABAAEAAABWAQAABAAAAHAQAwAAAA4AAQABAAAAAABbAQAAAQAAAA4AAAABAAEAAAAAAGABAAAB"
216 "AAAADgAAAAY8aW5pdD4ABkEuamF2YQADTEE7ABJMamF2YS9sYW5nL09iamVjdDsAAVYAAWEAAWIA"
217 "AQAHDgADAAcOAAUABw4AAAABAgCBgATkAQEA/AEBAPwBAAsAAAAAAAAAAQAAAAAAAAABAAAABwAA"
218 "AHAAAAACAAAAAwAAAIwAAAADAAAAAQAAAJgAAAAFAAAABAAAAKQAAAAGAAAAAQAAAMQAAAABIAAA"
219 "AwAAAOQAAAACIAAABwAAACQBAAADIAAAAwAAAFYBAAAAIAAAAQAAAGUBAAAAEAAAAQAAAHgBAAA=";
220
Mathieu Chartier6b0dbef2017-02-21 12:45:30 -0800221static void WriteBase64ToFile(const char* base64, File* file) {
Jeff Hao042e8982016-10-19 11:17:11 -0700222 // Decode base64.
223 CHECK(base64 != nullptr);
224 size_t length;
225 std::unique_ptr<uint8_t[]> bytes(DecodeBase64(base64, &length));
Mathieu Chartier6b0dbef2017-02-21 12:45:30 -0800226 CHECK(bytes != nullptr);
Jeff Hao042e8982016-10-19 11:17:11 -0700227 if (!file->WriteFully(bytes.get(), length)) {
228 PLOG(FATAL) << "Failed to write base64 as file";
229 }
Mathieu Chartier6b0dbef2017-02-21 12:45:30 -0800230}
231
232static void WriteFileBase64(const char* base64, const char* location) {
233 // Write to provided file.
234 std::unique_ptr<File> file(OS::CreateEmptyFile(location));
235 CHECK(file != nullptr);
236 WriteBase64ToFile(base64, file.get());
Jeff Hao042e8982016-10-19 11:17:11 -0700237 if (file->FlushCloseOrErase() != 0) {
238 PLOG(FATAL) << "Could not flush and close test file.";
239 }
240}
241
Jeff Haoc3acfc52016-08-29 14:18:26 -0700242class DexLayoutTest : public CommonRuntimeTest {
243 protected:
Andreas Gampe693bfbf2017-11-10 12:23:31 -0800244 std::string GetDexLayoutPath() {
245 return GetTestAndroidRoot() + "/bin/dexlayoutd";
Jeff Haoc3acfc52016-08-29 14:18:26 -0700246 }
247
Jeff Haoa8621002016-10-04 18:13:44 +0000248 // Runs FullPlainOutput test.
249 bool FullPlainOutputExec(std::string* error_msg) {
Jeff Haoc3acfc52016-08-29 14:18:26 -0700250 // TODO: dexdump2 -> dexdump ?
251 ScratchFile dexdump_output;
Andreas Gampeca620d72016-11-08 08:09:33 -0800252 const std::string& dexdump_filename = dexdump_output.GetFilename();
Jeff Haoc3acfc52016-08-29 14:18:26 -0700253 std::string dexdump = GetTestAndroidRoot() + "/bin/dexdump2";
254 EXPECT_TRUE(OS::FileExists(dexdump.c_str())) << dexdump << " should be a valid file path";
Jeff Haoc3acfc52016-08-29 14:18:26 -0700255
256 ScratchFile dexlayout_output;
Andreas Gampeca620d72016-11-08 08:09:33 -0800257 const std::string& dexlayout_filename = dexlayout_output.GetFilename();
Jeff Haoc3acfc52016-08-29 14:18:26 -0700258
Jeff Haoa8621002016-10-04 18:13:44 +0000259 for (const std::string &dex_file : GetLibCoreDexFileNames()) {
260 std::vector<std::string> dexdump_exec_argv =
261 { dexdump, "-d", "-f", "-h", "-l", "plain", "-o", dexdump_filename, dex_file };
Andreas Gampe693bfbf2017-11-10 12:23:31 -0800262 std::vector<std::string> dexlayout_args =
263 { "-d", "-f", "-h", "-l", "plain", "-o", dexlayout_filename, dex_file };
Jeff Haoa8621002016-10-04 18:13:44 +0000264 if (!::art::Exec(dexdump_exec_argv, error_msg)) {
265 return false;
266 }
Andreas Gampe693bfbf2017-11-10 12:23:31 -0800267 if (!DexLayoutExec(dexlayout_args, error_msg)) {
Jeff Haoa8621002016-10-04 18:13:44 +0000268 return false;
269 }
270 std::vector<std::string> diff_exec_argv =
271 { "/usr/bin/diff", dexdump_filename, dexlayout_filename };
272 if (!::art::Exec(diff_exec_argv, error_msg)) {
273 return false;
274 }
Jeff Haoc3acfc52016-08-29 14:18:26 -0700275 }
276 return true;
277 }
278
Jeff Haoa8621002016-10-04 18:13:44 +0000279 // Runs DexFileOutput test.
280 bool DexFileOutputExec(std::string* error_msg) {
281 ScratchFile tmp_file;
Andreas Gampeca620d72016-11-08 08:09:33 -0800282 const std::string& tmp_name = tmp_file.GetFilename();
283 size_t tmp_last_slash = tmp_name.rfind('/');
Jeff Haoa8621002016-10-04 18:13:44 +0000284 std::string tmp_dir = tmp_name.substr(0, tmp_last_slash + 1);
Jeff Haoa8621002016-10-04 18:13:44 +0000285
286 for (const std::string &dex_file : GetLibCoreDexFileNames()) {
Andreas Gampe693bfbf2017-11-10 12:23:31 -0800287 std::vector<std::string> dexlayout_args =
288 { "-w", tmp_dir, "-o", tmp_name, dex_file };
289 if (!DexLayoutExec(dexlayout_args, error_msg)) {
Jeff Haoa8621002016-10-04 18:13:44 +0000290 return false;
291 }
Andreas Gampe5555dd12017-08-24 13:50:21 -0700292 size_t dex_file_last_slash = dex_file.rfind('/');
Jeff Haoa8621002016-10-04 18:13:44 +0000293 std::string dex_file_name = dex_file.substr(dex_file_last_slash + 1);
294 std::vector<std::string> unzip_exec_argv =
295 { "/usr/bin/unzip", dex_file, "classes.dex", "-d", tmp_dir};
296 if (!::art::Exec(unzip_exec_argv, error_msg)) {
297 return false;
298 }
299 std::vector<std::string> diff_exec_argv =
300 { "/usr/bin/diff", tmp_dir + "classes.dex" , tmp_dir + dex_file_name };
301 if (!::art::Exec(diff_exec_argv, error_msg)) {
302 return false;
303 }
304 std::vector<std::string> rm_zip_exec_argv = { "/bin/rm", tmp_dir + "classes.dex" };
305 if (!::art::Exec(rm_zip_exec_argv, error_msg)) {
306 return false;
307 }
308 std::vector<std::string> rm_out_exec_argv = { "/bin/rm", tmp_dir + dex_file_name };
309 if (!::art::Exec(rm_out_exec_argv, error_msg)) {
310 return false;
311 }
312 }
Jeff Hao042e8982016-10-19 11:17:11 -0700313 return true;
314 }
Jeff Haoa8621002016-10-04 18:13:44 +0000315
Mathieu Chartieraf7c9022017-10-27 09:42:46 -0700316 template <typename Mutator>
317 bool MutateDexFile(File* output_dex, const std::string& input_jar, const Mutator& mutator) {
318 std::vector<std::unique_ptr<const DexFile>> dex_files;
319 std::string error_msg;
320 CHECK(DexFileLoader::Open(input_jar.c_str(),
321 input_jar.c_str(),
322 /*verify*/ true,
323 /*verify_checksum*/ true,
324 &error_msg,
325 &dex_files)) << error_msg;
326 EXPECT_EQ(dex_files.size(), 1u) << "Only one input dex is supported";
327 for (const std::unique_ptr<const DexFile>& dex : dex_files) {
328 CHECK(dex->EnableWrite()) << "Failed to enable write";
329 mutator(const_cast<DexFile*>(dex.get()));
330 if (!output_dex->WriteFully(dex->Begin(), dex->Size())) {
331 return false;
332 }
333 }
334 if (output_dex->Flush() != 0) {
335 PLOG(FATAL) << "Could not flush the output file.";
336 }
337 return true;
338 }
339
Mathieu Chartierd00e02b2017-05-24 12:04:13 -0700340 // Create a profile with some subset of methods and classes.
341 void CreateProfile(const std::string& input_dex,
342 const std::string& out_profile,
343 const std::string& dex_location) {
344 std::vector<std::unique_ptr<const DexFile>> dex_files;
345 std::string error_msg;
Mathieu Chartier79c87da2017-10-10 11:54:29 -0700346 bool result = DexFileLoader::Open(input_dex.c_str(),
347 input_dex,
Nicolas Geoffray095c6c92017-10-19 13:59:55 +0100348 /*verify*/ true,
349 /*verify_checksum*/ false,
Mathieu Chartier79c87da2017-10-10 11:54:29 -0700350 &error_msg,
351 &dex_files);
Mathieu Chartierd00e02b2017-05-24 12:04:13 -0700352
353 ASSERT_TRUE(result) << error_msg;
354 ASSERT_GE(dex_files.size(), 1u);
355
356 size_t profile_methods = 0;
357 size_t profile_classes = 0;
358 ProfileCompilationInfo pfi;
Mathieu Chartierd00e02b2017-05-24 12:04:13 -0700359 std::set<DexCacheResolvedClasses> classes;
360 for (const std::unique_ptr<const DexFile>& dex_file : dex_files) {
361 for (uint32_t i = 0; i < dex_file->NumMethodIds(); i += 2) {
Mathieu Chartierbbe3a5e2017-06-13 16:36:17 -0700362 uint8_t flags = 0u;
363
Mathieu Chartierd00e02b2017-05-24 12:04:13 -0700364 if ((i & 3) != 0) {
Mathieu Chartierbbe3a5e2017-06-13 16:36:17 -0700365 flags |= ProfileCompilationInfo::MethodHotness::kFlagHot;
Mathieu Chartierea650f32017-05-24 12:04:13 -0700366 ++profile_methods;
367 } else if ((i & 2) != 0) {
Mathieu Chartierbbe3a5e2017-06-13 16:36:17 -0700368 flags |= ProfileCompilationInfo::MethodHotness::kFlagStartup;
Mathieu Chartierd00e02b2017-05-24 12:04:13 -0700369 ++profile_methods;
370 }
Mathieu Chartierbbe3a5e2017-06-13 16:36:17 -0700371 pfi.AddMethodIndex(static_cast<ProfileCompilationInfo::MethodHotness::Flag>(flags),
372 dex_location,
373 dex_file->GetLocationChecksum(),
374 /*dex_method_idx*/i,
375 dex_file->NumMethodIds());
Mathieu Chartierd00e02b2017-05-24 12:04:13 -0700376 }
377 DexCacheResolvedClasses cur_classes(dex_location,
378 dex_location,
Mathieu Chartierea650f32017-05-24 12:04:13 -0700379 dex_file->GetLocationChecksum(),
380 dex_file->NumMethodIds());
Mathieu Chartierd00e02b2017-05-24 12:04:13 -0700381 // Add every even class too.
382 for (uint32_t i = 0; i < dex_file->NumClassDefs(); i += 1) {
Mathieu Chartierea650f32017-05-24 12:04:13 -0700383 if ((i & 2) == 0) {
384 cur_classes.AddClass(dex_file->GetClassDef(i).class_idx_);
385 ++profile_classes;
386 }
Mathieu Chartierd00e02b2017-05-24 12:04:13 -0700387 }
Mathieu Chartierea650f32017-05-24 12:04:13 -0700388 classes.insert(cur_classes);
Mathieu Chartierd00e02b2017-05-24 12:04:13 -0700389 }
Mathieu Chartierbbe3a5e2017-06-13 16:36:17 -0700390 pfi.AddClasses(classes);
Mathieu Chartierd00e02b2017-05-24 12:04:13 -0700391 // Write to provided file.
392 std::unique_ptr<File> file(OS::CreateEmptyFile(out_profile.c_str()));
393 ASSERT_TRUE(file != nullptr);
394 pfi.Save(file->Fd());
395 if (file->FlushCloseOrErase() != 0) {
396 PLOG(FATAL) << "Could not flush and close test file.";
397 }
398 EXPECT_GE(profile_methods, 0u);
399 EXPECT_GE(profile_classes, 0u);
400 }
401
Jeff Haod9be7682017-04-05 09:29:43 -0700402 // Runs DexFileLayout test.
Jeff Hao042e8982016-10-19 11:17:11 -0700403 bool DexFileLayoutExec(std::string* error_msg) {
404 ScratchFile tmp_file;
Andreas Gampe641a4732017-08-24 13:21:35 -0700405 const std::string& tmp_name = tmp_file.GetFilename();
Andreas Gampe5555dd12017-08-24 13:50:21 -0700406 size_t tmp_last_slash = tmp_name.rfind('/');
Jeff Hao042e8982016-10-19 11:17:11 -0700407 std::string tmp_dir = tmp_name.substr(0, tmp_last_slash + 1);
408
409 // Write inputs and expected outputs.
410 std::string dex_file = tmp_dir + "classes.dex";
411 WriteFileBase64(kDexFileLayoutInputDex, dex_file.c_str());
412 std::string profile_file = tmp_dir + "primary.prof";
Mathieu Chartierd00e02b2017-05-24 12:04:13 -0700413 CreateProfile(dex_file, profile_file, dex_file);
414 // WriteFileBase64(kDexFileLayoutInputProfile, profile_file.c_str());
Jeff Hao042e8982016-10-19 11:17:11 -0700415 std::string output_dex = tmp_dir + "classes.dex.new";
416
Andreas Gampe693bfbf2017-11-10 12:23:31 -0800417 std::vector<std::string> dexlayout_args =
418 { "-v", "-w", tmp_dir, "-o", tmp_name, "-p", profile_file, dex_file };
419 if (!DexLayoutExec(dexlayout_args, error_msg)) {
Jeff Hao042e8982016-10-19 11:17:11 -0700420 return false;
421 }
Mathieu Chartierfa0aa092017-03-27 15:43:54 -0700422
423 // -v makes sure that the layout did not corrupt the dex file.
Jeff Hao042e8982016-10-19 11:17:11 -0700424
425 std::vector<std::string> rm_exec_argv =
Mathieu Chartierfa0aa092017-03-27 15:43:54 -0700426 { "/bin/rm", dex_file, profile_file, output_dex };
Jeff Hao042e8982016-10-19 11:17:11 -0700427 if (!::art::Exec(rm_exec_argv, error_msg)) {
428 return false;
429 }
Jeff Haoa8621002016-10-04 18:13:44 +0000430 return true;
431 }
Jeff Hao44652a32017-02-22 14:20:41 -0800432
Bharadwaj Kalandhabhatta02ef6402017-05-17 17:13:39 -0700433 // Runs DexFileLayout test twice (second time is run on output of first time)
434 // for behavior consistency.
435 bool DexFileLayoutFixedPointExec(std::string* error_msg) {
436 ScratchFile tmp_file;
Andreas Gampe641a4732017-08-24 13:21:35 -0700437 const std::string& tmp_name = tmp_file.GetFilename();
Andreas Gampe5555dd12017-08-24 13:50:21 -0700438 size_t tmp_last_slash = tmp_name.rfind('/');
Bharadwaj Kalandhabhatta02ef6402017-05-17 17:13:39 -0700439 std::string tmp_dir = tmp_name.substr(0, tmp_last_slash + 1);
440
Mathieu Chartierd00e02b2017-05-24 12:04:13 -0700441 // Unzip the test dex file to the classes.dex destination. It is required to unzip since
442 // opening from jar recalculates the dex location checksum.
Bharadwaj Kalandhabhatta02ef6402017-05-17 17:13:39 -0700443 std::string dex_file = tmp_dir + "classes.dex";
Mathieu Chartierd00e02b2017-05-24 12:04:13 -0700444
445 std::vector<std::string> unzip_args = {
446 "/usr/bin/unzip",
447 GetTestDexFileName("ManyMethods"),
448 "classes.dex",
449 "-d",
450 tmp_dir,
451 };
452 if (!art::Exec(unzip_args, error_msg)) {
453 LOG(ERROR) << "Failed to unzip dex";
454 return false;
455 }
456
Bharadwaj Kalandhabhatta02ef6402017-05-17 17:13:39 -0700457 std::string profile_file = tmp_dir + "primary.prof";
Mathieu Chartierd00e02b2017-05-24 12:04:13 -0700458 CreateProfile(dex_file, profile_file, dex_file);
Bharadwaj Kalandhabhatta02ef6402017-05-17 17:13:39 -0700459 std::string output_dex = tmp_dir + "classes.dex.new";
460 std::string second_output_dex = tmp_dir + "classes.dex.new.new";
461
Bharadwaj Kalandhabhatta02ef6402017-05-17 17:13:39 -0700462 // -v makes sure that the layout did not corrupt the dex file.
Andreas Gampe693bfbf2017-11-10 12:23:31 -0800463 std::vector<std::string> dexlayout_args =
464 { "-i", "-v", "-w", tmp_dir, "-o", tmp_name, "-p", profile_file, dex_file };
465 if (!DexLayoutExec(dexlayout_args, error_msg)) {
Bharadwaj Kalandhabhatta02ef6402017-05-17 17:13:39 -0700466 return false;
467 }
468
Mathieu Chartierd00e02b2017-05-24 12:04:13 -0700469 // Recreate the profile with the new dex location. This is required so that the profile dex
470 // location matches.
471 CreateProfile(dex_file, profile_file, output_dex);
472
Bharadwaj Kalandhabhatta02ef6402017-05-17 17:13:39 -0700473 // -v makes sure that the layout did not corrupt the dex file.
Mathieu Chartierd00e02b2017-05-24 12:04:13 -0700474 // -i since the checksum won't match from the first layout.
Andreas Gampe693bfbf2017-11-10 12:23:31 -0800475 std::vector<std::string> second_dexlayout_args =
476 { "-i", "-v", "-w", tmp_dir, "-o", tmp_name, "-p", profile_file, output_dex };
477 if (!DexLayoutExec(second_dexlayout_args, error_msg)) {
Bharadwaj Kalandhabhatta02ef6402017-05-17 17:13:39 -0700478 return false;
479 }
480
481 bool diff_result = true;
482 std::vector<std::string> diff_exec_argv =
483 { "/usr/bin/diff", output_dex, second_output_dex };
484 if (!::art::Exec(diff_exec_argv, error_msg)) {
485 diff_result = false;
486 }
487
488 std::vector<std::string> rm_exec_argv =
489 { "/bin/rm", dex_file, profile_file, output_dex, second_output_dex };
490 if (!::art::Exec(rm_exec_argv, error_msg)) {
491 return false;
492 }
493
494 return diff_result;
495 }
496
Jeff Haoac462712017-03-02 10:59:43 -0800497 // Runs UnreferencedCatchHandlerTest & Unreferenced0SizeCatchHandlerTest.
498 bool UnreferencedCatchHandlerExec(std::string* error_msg, const char* filename) {
Jeff Hao44652a32017-02-22 14:20:41 -0800499 ScratchFile tmp_file;
Andreas Gampe641a4732017-08-24 13:21:35 -0700500 const std::string& tmp_name = tmp_file.GetFilename();
Andreas Gampe5555dd12017-08-24 13:50:21 -0700501 size_t tmp_last_slash = tmp_name.rfind('/');
Jeff Hao44652a32017-02-22 14:20:41 -0800502 std::string tmp_dir = tmp_name.substr(0, tmp_last_slash + 1);
503
504 // Write inputs and expected outputs.
505 std::string input_dex = tmp_dir + "classes.dex";
Jeff Haoac462712017-03-02 10:59:43 -0800506 WriteFileBase64(filename, input_dex.c_str());
Jeff Hao44652a32017-02-22 14:20:41 -0800507 std::string output_dex = tmp_dir + "classes.dex.new";
508
Andreas Gampe693bfbf2017-11-10 12:23:31 -0800509 std::vector<std::string> dexlayout_args = { "-w", tmp_dir, "-o", "/dev/null", input_dex };
510 if (!DexLayoutExec(dexlayout_args, error_msg)) {
Jeff Hao44652a32017-02-22 14:20:41 -0800511 return false;
512 }
513
514 // Diff input and output. They should be the same.
515 std::vector<std::string> diff_exec_argv = { "/usr/bin/diff", input_dex, output_dex };
516 if (!::art::Exec(diff_exec_argv, error_msg)) {
517 return false;
518 }
519
520 std::vector<std::string> rm_exec_argv = { "/bin/rm", input_dex, output_dex };
521 if (!::art::Exec(rm_exec_argv, error_msg)) {
522 return false;
523 }
524 return true;
525 }
Jeff Haod9be7682017-04-05 09:29:43 -0700526
527 bool DexLayoutExec(ScratchFile* dex_file,
528 const char* dex_filename,
529 ScratchFile* profile_file,
Andreas Gampe693bfbf2017-11-10 12:23:31 -0800530 const std::vector<std::string>& dexlayout_args) {
Mathieu Chartieraf7c9022017-10-27 09:42:46 -0700531 if (dex_filename != nullptr) {
532 WriteBase64ToFile(dex_filename, dex_file->GetFile());
533 EXPECT_EQ(dex_file->GetFile()->Flush(), 0);
534 }
Jeff Haod9be7682017-04-05 09:29:43 -0700535 if (profile_file != nullptr) {
Mathieu Chartierd00e02b2017-05-24 12:04:13 -0700536 CreateProfile(dex_file->GetFilename(), profile_file->GetFilename(), dex_file->GetFilename());
Jeff Haod9be7682017-04-05 09:29:43 -0700537 }
Andreas Gampe693bfbf2017-11-10 12:23:31 -0800538
Jeff Haod9be7682017-04-05 09:29:43 -0700539 std::string error_msg;
Andreas Gampe693bfbf2017-11-10 12:23:31 -0800540 const bool result = DexLayoutExec(dexlayout_args, &error_msg);
Jeff Haod9be7682017-04-05 09:29:43 -0700541 if (!result) {
542 LOG(ERROR) << "Error: " << error_msg;
543 return false;
544 }
545 return true;
546 }
Andreas Gampe693bfbf2017-11-10 12:23:31 -0800547
548 bool DexLayoutExec(const std::vector<std::string>& dexlayout_args, std::string* error_msg) {
549 std::vector<std::string> argv;
550
551 std::string dexlayout = GetDexLayoutPath();
552 CHECK(OS::FileExists(dexlayout.c_str())) << dexlayout << " should be a valid file path";
553 argv.push_back(dexlayout);
554
555 argv.insert(argv.end(), dexlayout_args.begin(), dexlayout_args.end());
556
557 return ::art::Exec(argv, error_msg);
558 }
Jeff Haoc3acfc52016-08-29 14:18:26 -0700559};
560
561
562TEST_F(DexLayoutTest, FullPlainOutput) {
Jeff Hao0f7eaeb2016-08-31 17:56:13 -0700563 // Disable test on target.
564 TEST_DISABLED_FOR_TARGET();
Jeff Haoc3acfc52016-08-29 14:18:26 -0700565 std::string error_msg;
Jeff Haoa8621002016-10-04 18:13:44 +0000566 ASSERT_TRUE(FullPlainOutputExec(&error_msg)) << error_msg;
567}
568
569TEST_F(DexLayoutTest, DexFileOutput) {
570 // Disable test on target.
571 TEST_DISABLED_FOR_TARGET();
572 std::string error_msg;
573 ASSERT_TRUE(DexFileOutputExec(&error_msg)) << error_msg;
Jeff Haoc3acfc52016-08-29 14:18:26 -0700574}
575
Jeff Hao042e8982016-10-19 11:17:11 -0700576TEST_F(DexLayoutTest, DexFileLayout) {
577 // Disable test on target.
578 TEST_DISABLED_FOR_TARGET();
579 std::string error_msg;
580 ASSERT_TRUE(DexFileLayoutExec(&error_msg)) << error_msg;
581}
582
Bharadwaj Kalandhabhatta02ef6402017-05-17 17:13:39 -0700583TEST_F(DexLayoutTest, DexFileLayoutFixedPoint) {
584 // Disable test on target.
585 TEST_DISABLED_FOR_TARGET();
586 std::string error_msg;
587 ASSERT_TRUE(DexFileLayoutFixedPointExec(&error_msg)) << error_msg;
588}
589
Jeff Haoe17f5892017-02-23 16:14:04 -0800590TEST_F(DexLayoutTest, UnreferencedCatchHandler) {
591 // Disable test on target.
592 TEST_DISABLED_FOR_TARGET();
593 std::string error_msg;
Jeff Haoac462712017-03-02 10:59:43 -0800594 ASSERT_TRUE(UnreferencedCatchHandlerExec(&error_msg,
595 kUnreferencedCatchHandlerInputDex)) << error_msg;
Jeff Haoe17f5892017-02-23 16:14:04 -0800596}
Jeff Haoac462712017-03-02 10:59:43 -0800597
598TEST_F(DexLayoutTest, Unreferenced0SizeCatchHandler) {
599 // Disable test on target.
600 TEST_DISABLED_FOR_TARGET();
601 std::string error_msg;
602 ASSERT_TRUE(UnreferencedCatchHandlerExec(&error_msg,
603 kUnreferenced0SizeCatchHandlerInputDex)) << error_msg;
604}
605
Jeff Haoa64a64c2017-03-06 15:05:38 -0800606TEST_F(DexLayoutTest, UnreferencedEndingCatchHandler) {
607 // Disable test on target.
608 TEST_DISABLED_FOR_TARGET();
609 std::string error_msg;
610 ASSERT_TRUE(UnreferencedCatchHandlerExec(&error_msg,
611 kUnreferencedEndingCatchHandlerInputDex)) << error_msg;
612}
613
Mathieu Chartier6b0dbef2017-02-21 12:45:30 -0800614TEST_F(DexLayoutTest, DuplicateOffset) {
Jeff Haod9be7682017-04-05 09:29:43 -0700615 ScratchFile temp_dex;
Andreas Gampe693bfbf2017-11-10 12:23:31 -0800616 std::vector<std::string> dexlayout_args =
617 { "-a", "-i", "-o", "/dev/null", temp_dex.GetFilename() };
Jeff Haod9be7682017-04-05 09:29:43 -0700618 ASSERT_TRUE(DexLayoutExec(&temp_dex,
619 kDexFileDuplicateOffset,
620 nullptr /* profile_file */,
Andreas Gampe693bfbf2017-11-10 12:23:31 -0800621 dexlayout_args));
Mathieu Chartier6b0dbef2017-02-21 12:45:30 -0800622}
623
Jeff Haof914f8e2017-02-21 16:14:23 -0800624TEST_F(DexLayoutTest, NullSetRefListElement) {
Jeff Haod9be7682017-04-05 09:29:43 -0700625 ScratchFile temp_dex;
Andreas Gampe693bfbf2017-11-10 12:23:31 -0800626 std::vector<std::string> dexlayout_args = { "-o", "/dev/null", temp_dex.GetFilename() };
Jeff Haod9be7682017-04-05 09:29:43 -0700627 ASSERT_TRUE(DexLayoutExec(&temp_dex,
628 kNullSetRefListElementInputDex,
629 nullptr /* profile_file */,
Andreas Gampe693bfbf2017-11-10 12:23:31 -0800630 dexlayout_args));
Jeff Haof914f8e2017-02-21 16:14:23 -0800631}
632
Jeff Haoe17f5892017-02-23 16:14:04 -0800633TEST_F(DexLayoutTest, MultiClassData) {
Jeff Haod9be7682017-04-05 09:29:43 -0700634 ScratchFile temp_dex;
635 ScratchFile temp_profile;
Andreas Gampe693bfbf2017-11-10 12:23:31 -0800636 std::vector<std::string> dexlayout_args =
637 { "-p", temp_profile.GetFilename(), "-o", "/dev/null", temp_dex.GetFilename() };
Jeff Haod9be7682017-04-05 09:29:43 -0700638 ASSERT_TRUE(DexLayoutExec(&temp_dex,
639 kMultiClassDataInputDex,
640 &temp_profile,
Andreas Gampe693bfbf2017-11-10 12:23:31 -0800641 dexlayout_args));
Jeff Haoe17f5892017-02-23 16:14:04 -0800642}
643
644TEST_F(DexLayoutTest, UnalignedCodeInfo) {
Jeff Haod9be7682017-04-05 09:29:43 -0700645 ScratchFile temp_dex;
646 ScratchFile temp_profile;
Andreas Gampe693bfbf2017-11-10 12:23:31 -0800647 std::vector<std::string> dexlayout_args =
648 { "-p", temp_profile.GetFilename(), "-o", "/dev/null", temp_dex.GetFilename() };
Jeff Haod9be7682017-04-05 09:29:43 -0700649 ASSERT_TRUE(DexLayoutExec(&temp_dex,
650 kUnalignedCodeInfoInputDex,
651 &temp_profile,
Andreas Gampe693bfbf2017-11-10 12:23:31 -0800652 dexlayout_args));
Jeff Hao44652a32017-02-22 14:20:41 -0800653}
654
Jeff Hao32a60ab2017-03-01 16:44:50 -0800655TEST_F(DexLayoutTest, ClassDataBeforeCode) {
Jeff Haod9be7682017-04-05 09:29:43 -0700656 ScratchFile temp_dex;
657 ScratchFile temp_profile;
Andreas Gampe693bfbf2017-11-10 12:23:31 -0800658 std::vector<std::string> dexlayout_args =
659 { "-p", temp_profile.GetFilename(), "-o", "/dev/null", temp_dex.GetFilename() };
Jeff Haod9be7682017-04-05 09:29:43 -0700660 ASSERT_TRUE(DexLayoutExec(&temp_dex,
661 kClassDataBeforeCodeInputDex,
662 &temp_profile,
Andreas Gampe693bfbf2017-11-10 12:23:31 -0800663 dexlayout_args));
Jeff Haod9be7682017-04-05 09:29:43 -0700664}
665
666TEST_F(DexLayoutTest, UnknownTypeDebugInfo) {
667 ScratchFile temp_dex;
Andreas Gampe693bfbf2017-11-10 12:23:31 -0800668 std::vector<std::string> dexlayout_args = { "-o", "/dev/null", temp_dex.GetFilename() };
Jeff Haod9be7682017-04-05 09:29:43 -0700669 ASSERT_TRUE(DexLayoutExec(&temp_dex,
670 kUnknownTypeDebugInfoInputDex,
671 nullptr /* profile_file */,
Andreas Gampe693bfbf2017-11-10 12:23:31 -0800672 dexlayout_args));
Jeff Hao32a60ab2017-03-01 16:44:50 -0800673}
674
Jeff Haod212d5b2017-04-26 12:09:06 -0700675TEST_F(DexLayoutTest, DuplicateCodeItem) {
676 ScratchFile temp_dex;
Andreas Gampe693bfbf2017-11-10 12:23:31 -0800677 std::vector<std::string> dexlayout_args = { "-o", "/dev/null", temp_dex.GetFilename() };
Jeff Haod212d5b2017-04-26 12:09:06 -0700678 ASSERT_TRUE(DexLayoutExec(&temp_dex,
679 kDuplicateCodeItemInputDex,
680 nullptr /* profile_file */,
Andreas Gampe693bfbf2017-11-10 12:23:31 -0800681 dexlayout_args));
Jeff Haod212d5b2017-04-26 12:09:06 -0700682}
683
Mathieu Chartieraf7c9022017-10-27 09:42:46 -0700684// Test that instructions that go past the end of the code items don't cause crashes.
685TEST_F(DexLayoutTest, CodeItemOverrun) {
686 ScratchFile temp_dex;
687 MutateDexFile(temp_dex.GetFile(), GetTestDexFileName("ManyMethods"), [] (DexFile* dex) {
688 bool mutated_successfully = false;
689 // Change the dex instructions to make an opcode that spans past the end of the code item.
690 for (size_t i = 0; i < dex->NumClassDefs(); ++i) {
691 const DexFile::ClassDef& def = dex->GetClassDef(i);
692 const uint8_t* data = dex->GetClassData(def);
693 if (data == nullptr) {
694 continue;
695 }
696 ClassDataItemIterator it(*dex, data);
697 it.SkipAllFields();
Mathieu Chartierb7c273c2017-11-10 18:07:56 -0800698 while (it.HasNextMethod()) {
Mathieu Chartieraf7c9022017-10-27 09:42:46 -0700699 DexFile::CodeItem* item = const_cast<DexFile::CodeItem*>(it.GetMethodCodeItem());
700 if (item != nullptr) {
701 IterationRange<DexInstructionIterator> instructions = item->Instructions();
702 if (instructions.begin() != instructions.end()) {
703 DexInstructionIterator last_instruction = instructions.begin();
704 for (auto dex_it = instructions.begin(); dex_it != instructions.end(); ++dex_it) {
705 last_instruction = dex_it;
706 }
707 if (last_instruction->SizeInCodeUnits() == 1) {
708 // Set the opcode to something that will go past the end of the code item.
Mathieu Chartier2b2bef22017-10-26 17:10:19 -0700709 const_cast<Instruction&>(last_instruction.Inst()).SetOpcode(
Mathieu Chartieraf7c9022017-10-27 09:42:46 -0700710 Instruction::CONST_STRING_JUMBO);
711 mutated_successfully = true;
Mathieu Chartier176190c2017-10-31 09:58:07 -0700712 // Test that the safe iterator doesn't go past the end.
713 SafeDexInstructionIterator it2(instructions.begin(), instructions.end());
714 while (!it2.IsErrorState()) {
715 ++it2;
716 }
717 EXPECT_TRUE(it2 == last_instruction);
718 EXPECT_TRUE(it2 < instructions.end());
Mathieu Chartieraf7c9022017-10-27 09:42:46 -0700719 }
720 }
721 }
722 it.Next();
723 }
724 }
725 CHECK(mutated_successfully)
726 << "Failed to find candidate code item with only one code unit in last instruction.";
727 });
Andreas Gampe693bfbf2017-11-10 12:23:31 -0800728 std::vector<std::string> dexlayout_args = { "-i", "-o", "/dev/null", temp_dex.GetFilename() };
Mathieu Chartieraf7c9022017-10-27 09:42:46 -0700729 ASSERT_TRUE(DexLayoutExec(&temp_dex,
730 /*dex_filename*/ nullptr,
731 nullptr /* profile_file */,
Andreas Gampe693bfbf2017-11-10 12:23:31 -0800732 dexlayout_args));
Mathieu Chartieraf7c9022017-10-27 09:42:46 -0700733}
734
Jeff Haoc3acfc52016-08-29 14:18:26 -0700735} // namespace art