1 /* 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 17 #include <string> 18 #include <vector> 19 #include <sstream> 20 21 #include <sys/types.h> 22 #include <unistd.h> 23 24 #include "base/unix_file/fd_file.h" 25 #include "common_runtime_test.h" 26 #include "dex_file-inl.h" 27 #include "exec_utils.h" 28 #include "jit/profile_compilation_info.h" 29 #include "utils.h" 30 31 namespace art { 32 33 static const char kDexFileLayoutInputDex[] = 34 "ZGV4CjAzNQD1KW3+B8NAB0f2A/ZVIBJ0aHrGIqcpVTAUAgAAcAAAAHhWNBIAAAAAAAAAAIwBAAAH" 35 "AAAAcAAAAAQAAACMAAAAAQAAAJwAAAAAAAAAAAAAAAMAAACoAAAAAgAAAMAAAAAUAQAAAAEAADAB" 36 "AAA4AQAAQAEAAEgBAABNAQAAUgEAAGYBAAADAAAABAAAAAUAAAAGAAAABgAAAAMAAAAAAAAAAAAA" 37 "AAAAAAABAAAAAAAAAAIAAAAAAAAAAAAAAAAAAAACAAAAAAAAAAEAAAAAAAAAdQEAAAAAAAABAAAA" 38 "AAAAAAIAAAAAAAAAAgAAAAAAAAB/AQAAAAAAAAEAAQABAAAAaQEAAAQAAABwEAIAAAAOAAEAAQAB" 39 "AAAAbwEAAAQAAABwEAIAAAAOAAY8aW5pdD4ABkEuamF2YQAGQi5qYXZhAANMQTsAA0xCOwASTGph" 40 "dmEvbGFuZy9PYmplY3Q7AAFWAAQABw48AAQABw48AAAAAQAAgIAEgAIAAAEAAYCABJgCAAAACwAA" 41 "AAAAAAABAAAAAAAAAAEAAAAHAAAAcAAAAAIAAAAEAAAAjAAAAAMAAAABAAAAnAAAAAUAAAADAAAA" 42 "qAAAAAYAAAACAAAAwAAAAAEgAAACAAAAAAEAAAIgAAAHAAAAMAEAAAMgAAACAAAAaQEAAAAgAAAC" 43 "AAAAdQEAAAAQAAABAAAAjAEAAA=="; 44 45 // Dex file with catch handler unreferenced by try blocks. 46 // Constructed by building a dex file with try/catch blocks and hex editing. 47 static const char kUnreferencedCatchHandlerInputDex[] = 48 "ZGV4CjAzNQD+exd52Y0f9nY5x5GmInXq5nXrO6Kl2RV4AwAAcAAAAHhWNBIAAAAAAAAAANgCAAAS" 49 "AAAAcAAAAAgAAAC4AAAAAwAAANgAAAABAAAA/AAAAAQAAAAEAQAAAQAAACQBAAA0AgAARAEAANYB" 50 "AADeAQAA5gEAAO4BAAAAAgAADwIAACYCAAA9AgAAUQIAAGUCAAB5AgAAfwIAAIUCAACIAgAAjAIA" 51 "AKECAACnAgAArAIAAAQAAAAFAAAABgAAAAcAAAAIAAAACQAAAAwAAAAOAAAADAAAAAYAAAAAAAAA" 52 "DQAAAAYAAADIAQAADQAAAAYAAADQAQAABQABABAAAAAAAAAAAAAAAAAAAgAPAAAAAQABABEAAAAD" 53 "AAAAAAAAAAAAAAABAAAAAwAAAAAAAAADAAAAAAAAAMgCAAAAAAAAAQABAAEAAAC1AgAABAAAAHAQ" 54 "AwAAAA4AAwABAAIAAgC6AgAAIQAAAGIAAAAaAQoAbiACABAAYgAAABoBCwBuIAIAEAAOAA0AYgAA" 55 "ABoBAQBuIAIAEAAo8A0AYgAAABoBAgBuIAIAEAAo7gAAAAAAAAcAAQAHAAAABwABAAIBAg8BAhgA" 56 "AQAAAAQAAAABAAAABwAGPGluaXQ+AAZDYXRjaDEABkNhdGNoMgAQSGFuZGxlclRlc3QuamF2YQAN" 57 "TEhhbmRsZXJUZXN0OwAVTGphdmEvaW8vUHJpbnRTdHJlYW07ABVMamF2YS9sYW5nL0V4Y2VwdGlv" 58 "bjsAEkxqYXZhL2xhbmcvT2JqZWN0OwASTGphdmEvbGFuZy9TdHJpbmc7ABJMamF2YS9sYW5nL1N5" 59 "c3RlbTsABFRyeTEABFRyeTIAAVYAAlZMABNbTGphdmEvbGFuZy9TdHJpbmc7AARtYWluAANvdXQA" 60 "B3ByaW50bG4AAQAHDgAEAQAHDn17AncdHoseAAAAAgAAgYAExAIBCdwCAAANAAAAAAAAAAEAAAAA" 61 "AAAAAQAAABIAAABwAAAAAgAAAAgAAAC4AAAAAwAAAAMAAADYAAAABAAAAAEAAAD8AAAABQAAAAQA" 62 "AAAEAQAABgAAAAEAAAAkAQAAASAAAAIAAABEAQAAARAAAAIAAADIAQAAAiAAABIAAADWAQAAAyAA" 63 "AAIAAAC1AgAAACAAAAEAAADIAgAAABAAAAEAAADYAgAA"; 64 65 // Dex file with 0-size (catch all only) catch handler unreferenced by try blocks. 66 // Constructed by building a dex file with try/catch blocks and hex editing. 67 static const char kUnreferenced0SizeCatchHandlerInputDex[] = 68 "ZGV4CjAzNQCEbEEvMstSNpQpjPdfMEfUBS48cis2QRJoAwAAcAAAAHhWNBIAAAAAAAAAAMgCAAAR" 69 "AAAAcAAAAAcAAAC0AAAAAwAAANAAAAABAAAA9AAAAAQAAAD8AAAAAQAAABwBAAAsAgAAPAEAAOoB" 70 "AADyAQAABAIAABMCAAAqAgAAPgIAAFICAABmAgAAaQIAAG0CAACCAgAAhgIAAIoCAACQAgAAlQIA" 71 "AJ4CAACiAgAAAgAAAAMAAAAEAAAABQAAAAYAAAAHAAAACQAAAAcAAAAFAAAAAAAAAAgAAAAFAAAA" 72 "3AEAAAgAAAAFAAAA5AEAAAQAAQANAAAAAAAAAAAAAAAAAAIADAAAAAEAAQAOAAAAAgAAAAAAAAAA" 73 "AAAAAQAAAAIAAAAAAAAAAQAAAAAAAAC5AgAAAAAAAAEAAQABAAAApgIAAAQAAABwEAMAAAAOAAQA" 74 "AQACAAIAqwIAAC8AAABiAAAAGgEPAG4gAgAQAGIAAAAaAQoAbiACABAAYgAAABoBEABuIAIAEABi" 75 "AAAAGgELAG4gAgAQAA4ADQBiAQAAGgIKAG4gAgAhACcADQBiAQAAGgILAG4gAgAhACcAAAAAAAAA" 76 "BwABAA4AAAAHAAEAAgAdACYAAAABAAAAAwAAAAEAAAAGAAY8aW5pdD4AEEhhbmRsZXJUZXN0Lmph" 77 "dmEADUxIYW5kbGVyVGVzdDsAFUxqYXZhL2lvL1ByaW50U3RyZWFtOwASTGphdmEvbGFuZy9PYmpl" 78 "Y3Q7ABJMamF2YS9sYW5nL1N0cmluZzsAEkxqYXZhL2xhbmcvU3lzdGVtOwABVgACVkwAE1tMamF2" 79 "YS9sYW5nL1N0cmluZzsAAmYxAAJmMgAEbWFpbgADb3V0AAdwcmludGxuAAJ0MQACdDIAAQAHDgAE" 80 "AQAHDnl7eXkCeB2bAAAAAgAAgYAEvAIBCdQCAA0AAAAAAAAAAQAAAAAAAAABAAAAEQAAAHAAAAAC" 81 "AAAABwAAALQAAAADAAAAAwAAANAAAAAEAAAAAQAAAPQAAAAFAAAABAAAAPwAAAAGAAAAAQAAABwB" 82 "AAABIAAAAgAAADwBAAABEAAAAgAAANwBAAACIAAAEQAAAOoBAAADIAAAAgAAAKYCAAAAIAAAAQAA" 83 "ALkCAAAAEAAAAQAAAMgCAAA="; 84 85 // Dex file with an unreferenced catch handler at end of code item. 86 // Constructed by building a dex file with try/catch blocks and hex editing. 87 static const char kUnreferencedEndingCatchHandlerInputDex[] = 88 "ZGV4CjAzNQCEflufI6xGTDDRmLpbfYi6ujPrDLIwvYcEBAAAcAAAAHhWNBIAAAAAAAAAAGQDAAAT" 89 "AAAAcAAAAAgAAAC8AAAAAwAAANwAAAABAAAAAAEAAAUAAAAIAQAAAQAAADABAAC0AgAAUAEAAE4C" 90 "AABWAgAAXgIAAGYCAAB4AgAAhwIAAJ4CAAC1AgAAyQIAAN0CAADxAgAA9wIAAP0CAAAAAwAABAMA" 91 "ABkDAAAcAwAAIgMAACcDAAAEAAAABQAAAAYAAAAHAAAACAAAAAkAAAAMAAAADgAAAAwAAAAGAAAA" 92 "AAAAAA0AAAAGAAAAQAIAAA0AAAAGAAAASAIAAAUAAQARAAAAAAAAAAAAAAAAAAAADwAAAAAAAgAQ" 93 "AAAAAQABABIAAAADAAAAAAAAAAAAAAABAAAAAwAAAAAAAAADAAAAAAAAAFADAAAAAAAAAQABAAEA" 94 "AAAwAwAABAAAAHAQBAAAAA4AAgAAAAIAAgA1AwAAIQAAAGIAAAAaAQoAbiADABAAYgAAABoBCwBu" 95 "IAMAEAAOAA0AYgAAABoBAQBuIAMAEAAo8A0AYgAAABoBAgBuIAMAEAAo7gAAAAAAAAcAAQAHAAAA" 96 "BwABAAIBAg8BAhgAAwABAAIAAgBCAwAAIQAAAGIAAAAaAQoAbiADABAAYgAAABoBCwBuIAMAEAAO" 97 "AA0AYgAAABoBAQBuIAMAEAAo8A0AYgAAABoBAgBuIAMAEAAo7gAAAAAAAAcAAQAHAAAABwABAAIB" 98 "Ag8BAhgAAQAAAAQAAAABAAAABwAGPGluaXQ+AAZDYXRjaDEABkNhdGNoMgAQSGFuZGxlclRlc3Qu" 99 "amF2YQANTEhhbmRsZXJUZXN0OwAVTGphdmEvaW8vUHJpbnRTdHJlYW07ABVMamF2YS9sYW5nL0V4" 100 "Y2VwdGlvbjsAEkxqYXZhL2xhbmcvT2JqZWN0OwASTGphdmEvbGFuZy9TdHJpbmc7ABJMamF2YS9s" 101 "YW5nL1N5c3RlbTsABFRyeTEABFRyeTIAAVYAAlZMABNbTGphdmEvbGFuZy9TdHJpbmc7AAFhAARt" 102 "YWluAANvdXQAB3ByaW50bG4AAQAHDgAEAAcOfHsCeB0eih4AEQEABw59ewJ3HR6LHgAAAAMAAIGA" 103 "BNACAQnoAgEJ1AMAAA0AAAAAAAAAAQAAAAAAAAABAAAAEwAAAHAAAAACAAAACAAAALwAAAADAAAA" 104 "AwAAANwAAAAEAAAAAQAAAAABAAAFAAAABQAAAAgBAAAGAAAAAQAAADABAAABIAAAAwAAAFABAAAB" 105 "EAAAAgAAAEACAAACIAAAEwAAAE4CAAADIAAAAwAAADADAAAAIAAAAQAAAFADAAAAEAAAAQAAAGQD" 106 "AAA="; 107 108 // Dex file with multiple code items that have the same debug_info_off_. Constructed by a modified 109 // dexlayout on XandY. 110 static const char kDexFileDuplicateOffset[] = 111 "ZGV4CjAzNwAQfXfPCB8qCxo7MqdFhmHZQwCv8+udHD8MBAAAcAAAAHhWNBIAAAAAAAAAAFQDAAAT" 112 "AAAAcAAAAAgAAAC8AAAAAQAAANwAAAABAAAA6AAAAAUAAADwAAAAAwAAABgBAACUAgAAeAEAABQC" 113 "AAAeAgAAJgIAACsCAAAyAgAANwIAAFsCAAB7AgAAngIAALICAAC1AgAAvQIAAMUCAADIAgAA1QIA" 114 "AOkCAADvAgAA9QIAAPwCAAACAAAAAwAAAAQAAAAFAAAABgAAAAcAAAAIAAAACQAAAAkAAAAHAAAA" 115 "AAAAAAIAAQASAAAAAAAAAAEAAAABAAAAAQAAAAIAAAAAAAAAAgAAAAEAAAAGAAAAAQAAAAAAAAAA" 116 "AAAABgAAAAAAAAAKAAAAAAAAACsDAAAAAAAAAQAAAAAAAAAGAAAAAAAAAAsAAAD0AQAANQMAAAAA" 117 "AAACAAAAAAAAAAAAAAAAAAAACwAAAAQCAAA/AwAAAAAAAAIAAAAUAwAAGgMAAAEAAAAjAwAAAQAB" 118 "AAEAAAAFAAAABAAAAHAQBAAAAA4AAQABAAEAAAAFAAAABAAAAHAQBAAAAA4AAQAAAAEAAAAFAAAA" 119 "CAAAACIAAQBwEAEAAABpAAAADgABAAEAAQAAAAUAAAAEAAAAcBAAAAAADgB4AQAAAAAAAAAAAAAA" 120 "AAAAhAEAAAAAAAAAAAAAAAAAAAg8Y2xpbml0PgAGPGluaXQ+AANMWDsABUxZJFo7AANMWTsAIkxk" 121 "YWx2aWsvYW5ub3RhdGlvbi9FbmNsb3NpbmdDbGFzczsAHkxkYWx2aWsvYW5ub3RhdGlvbi9Jbm5l" 122 "ckNsYXNzOwAhTGRhbHZpay9hbm5vdGF0aW9uL01lbWJlckNsYXNzZXM7ABJMamF2YS9sYW5nL09i" 123 "amVjdDsAAVYABlguamF2YQAGWS5qYXZhAAFaAAthY2Nlc3NGbGFncwASZW1pdHRlcjogamFjay00" 124 "LjI1AARuYW1lAAR0aGlzAAV2YWx1ZQABegARAAcOABMABw4AEgAHDnYAEQAHDgACAwERGAICBAIN" 125 "BAgPFwwCBQERHAEYAQAAAQAAgIAEjAMAAAEAAYCABKQDAQACAAAIAoiABLwDAYCABNwDAAAADwAA" 126 "AAAAAAABAAAAAAAAAAEAAAATAAAAcAAAAAIAAAAIAAAAvAAAAAMAAAABAAAA3AAAAAQAAAABAAAA" 127 "6AAAAAUAAAAFAAAA8AAAAAYAAAADAAAAGAEAAAMQAAACAAAAeAEAAAEgAAAEAAAAjAEAAAYgAAAC" 128 "AAAA9AEAAAIgAAATAAAAFAIAAAMgAAAEAAAA/wIAAAQgAAADAAAAFAMAAAAgAAADAAAAKwMAAAAQ" 129 "AAABAAAAVAMAAA=="; 130 131 // Dex file with null value for annotations_off in the annotation_set_ref_list. 132 // Constructed by building a dex file with annotations and hex editing. 133 static const char kNullSetRefListElementInputDex[] = 134 "ZGV4CjAzNQB1iA+7ZwgkF+7E6ZesYFc2lRAR3qnRAanwAwAAcAAAAHhWNBIAAAAAAAAAACADAAAS" 135 "AAAAcAAAAAgAAAC4AAAAAwAAANgAAAABAAAA/AAAAAQAAAAEAQAAAgAAACQBAACMAgAAZAEAAOgB" 136 "AADwAQAAAAIAAAMCAAAQAgAAIAIAADQCAABIAgAAawIAAI0CAAC1AgAAyAIAANECAADUAgAA2QIA" 137 "ANwCAADjAgAA6QIAAAMAAAAEAAAABQAAAAYAAAAHAAAACAAAAAkAAAAMAAAAAgAAAAMAAAAAAAAA" 138 "DAAAAAcAAAAAAAAADQAAAAcAAADgAQAABgAGAAsAAAAAAAEAAAAAAAAAAgAOAAAAAQAAABAAAAAC" 139 "AAEAAAAAAAAAAAAAAAAAAgAAAAAAAAABAAAAsAEAAAgDAAAAAAAAAQAAAAEmAAACAAAA2AEAAAoA" 140 "AADIAQAAFgMAAAAAAAACAAAAAAAAAHwBAAABAAAA/AIAAAAAAAABAAAAAgMAAAEAAQABAAAA8AIA" 141 "AAQAAABwEAMAAAAOAAIAAgAAAAAA9QIAAAEAAAAOAAAAAAAAAAAAAAAAAAAAAQAAAAEAAABkAQAA" 142 "cAEAAAAAAAAAAAAAAAAAAAEAAAAEAAAAAgAAAAMAAwAGPGluaXQ+AA5Bbm5vQ2xhc3MuamF2YQAB" 143 "TAALTEFubm9DbGFzczsADkxNeUFubm90YXRpb247ABJMamF2YS9sYW5nL09iamVjdDsAEkxqYXZh" 144 "L2xhbmcvU3RyaW5nOwAhTGphdmEvbGFuZy9hbm5vdGF0aW9uL0Fubm90YXRpb247ACBMamF2YS9s" 145 "YW5nL2Fubm90YXRpb24vUmV0ZW50aW9uOwAmTGphdmEvbGFuZy9hbm5vdGF0aW9uL1JldGVudGlv" 146 "blBvbGljeTsAEU15QW5ub3RhdGlvbi5qYXZhAAdSVU5USU1FAAFWAANWTEwAAWEABWFOYW1lAARu" 147 "YW1lAAV2YWx1ZQABAAcOAAICAAAHDgABBQERGwABAQEQFw8AAAIAAICABIQDAQmcAwAAAAECgQgA" 148 "AAARAAAAAAAAAAEAAAAAAAAAAQAAABIAAABwAAAAAgAAAAgAAAC4AAAAAwAAAAMAAADYAAAABAAA" 149 "AAEAAAD8AAAABQAAAAQAAAAEAQAABgAAAAIAAAAkAQAAAhAAAAEAAABkAQAAAxAAAAMAAABwAQAA" 150 "ASAAAAIAAACEAQAABiAAAAIAAACwAQAAARAAAAIAAADYAQAAAiAAABIAAADoAQAAAyAAAAIAAADw" 151 "AgAABCAAAAIAAAD8AgAAACAAAAIAAAAIAwAAABAAAAEAAAAgAwAA"; 152 153 // Dex file with shared empty class data item for multiple class defs. 154 // Constructing by building a dex file with multiple classes and hex editing. 155 static const char kMultiClassDataInputDex[] = 156 "ZGV4CjAzNQALJgF9TtnLq748xVe/+wyxETrT9lTEiW6YAQAAcAAAAHhWNBIAAAAAAAAAADQBAAAI" 157 "AAAAcAAAAAQAAACQAAAAAAAAAAAAAAACAAAAoAAAAAAAAAAAAAAAAgAAALAAAACoAAAA8AAAAPAA" 158 "AAD4AAAAAAEAAAMBAAAIAQAADQEAACEBAAAkAQAAAgAAAAMAAAAEAAAABQAAAAEAAAAGAAAAAgAA" 159 "AAcAAAABAAAAAQYAAAMAAAAAAAAAAAAAAAAAAAAnAQAAAAAAAAIAAAABBgAAAwAAAAAAAAABAAAA" 160 "AAAAACcBAAAAAAAABkEuamF2YQAGQi5qYXZhAAFJAANMQTsAA0xCOwASTGphdmEvbGFuZy9PYmpl" 161 "Y3Q7AAFhAAFiAAAAAAABAAAAARkAAAAIAAAAAAAAAAEAAAAAAAAAAQAAAAgAAABwAAAAAgAAAAQA" 162 "AACQAAAABAAAAAIAAACgAAAABgAAAAIAAACwAAAAAiAAAAgAAADwAAAAACAAAAIAAAAnAQAAABAA" 163 "AAEAAAA0AQAA"; 164 165 // Dex file with code info followed by non 4-byte aligned section. 166 // Constructed a dex file with code info followed by string data and hex edited. 167 static const char kUnalignedCodeInfoInputDex[] = 168 "ZGV4CjAzNQDXJzXNb4iWn2SLhmLydW/8h1K9moERIw7UAQAAcAAAAHhWNBIAAAAAAAAAAEwBAAAG" 169 "AAAAcAAAAAMAAACIAAAAAQAAAJQAAAAAAAAAAAAAAAMAAACgAAAAAQAAALgAAAD8AAAA2AAAAAIB" 170 "AAAKAQAAEgEAABcBAAArAQAALgEAAAIAAAADAAAABAAAAAQAAAACAAAAAAAAAAAAAAAAAAAAAAAA" 171 "AAUAAAABAAAAAAAAAAAAAAABAAAAAQAAAAAAAAABAAAAAAAAADsBAAAAAAAAAQABAAEAAAAxAQAA" 172 "BAAAAHAQAgAAAA4AAQABAAAAAAA2AQAAAQAAAA4ABjxpbml0PgAGQS5qYXZhAANMQTsAEkxqYXZh" 173 "L2xhbmcvT2JqZWN0OwABVgABYQABAAcOAAMABw4AAAABAQCBgATYAQEB8AEAAAALAAAAAAAAAAEA" 174 "AAAAAAAAAQAAAAYAAABwAAAAAgAAAAMAAACIAAAAAwAAAAEAAACUAAAABQAAAAMAAACgAAAABgAA" 175 "AAEAAAC4AAAAASAAAAIAAADYAAAAAiAAAAYAAAACAQAAAyAAAAIAAAAxAQAAACAAAAEAAAA7AQAA" 176 "ABAAAAEAAABMAQAA"; 177 178 // Dex file with class data section preceding code items. 179 // Constructed by passing dex file through dexmerger tool and hex editing. 180 static const char kClassDataBeforeCodeInputDex[] = 181 "ZGV4CjAzNQCZKmCu3XXn4zvxCh5VH0gZNNobEAcsc49EAgAAcAAAAHhWNBIAAAAAAAAAAAQBAAAJ" 182 "AAAAcAAAAAQAAACUAAAAAgAAAKQAAAAAAAAAAAAAAAUAAAC8AAAAAQAAAOQAAABAAQAABAEAAPgB" 183 "AAAAAgAACAIAAAsCAAAQAgAAJAIAACcCAAAqAgAALQIAAAIAAAADAAAABAAAAAUAAAACAAAAAAAA" 184 "AAAAAAAFAAAAAwAAAAAAAAABAAEAAAAAAAEAAAAGAAAAAQAAAAcAAAABAAAACAAAAAIAAQAAAAAA" 185 "AQAAAAEAAAACAAAAAAAAAAEAAAAAAAAAjAEAAAAAAAALAAAAAAAAAAEAAAAAAAAAAQAAAAkAAABw" 186 "AAAAAgAAAAQAAACUAAAAAwAAAAIAAACkAAAABQAAAAUAAAC8AAAABgAAAAEAAADkAAAAABAAAAEA" 187 "AAAEAQAAACAAAAEAAACMAQAAASAAAAQAAACkAQAAAiAAAAkAAAD4AQAAAyAAAAQAAAAwAgAAAAAB" 188 "AwCBgASkAwEBvAMBAdADAQHkAwAAAQABAAEAAAAwAgAABAAAAHAQBAAAAA4AAgABAAAAAAA1AgAA" 189 "AgAAABIQDwACAAEAAAAAADoCAAACAAAAEiAPAAIAAQAAAAAAPwIAAAIAAAASMA8ABjxpbml0PgAG" 190 "QS5qYXZhAAFJAANMQTsAEkxqYXZhL2xhbmcvT2JqZWN0OwABVgABYQABYgABYwABAAcOAAMABw4A" 191 "BgAHDgAJAAcOAA=="; 192 193 // Dex file with local info containing a null type descriptor. 194 // Constructed a dex file with debug info sequence containing DBG_RESTART_LOCAL without any 195 // DBG_START_LOCAL to give it a declared type. 196 static const char kUnknownTypeDebugInfoInputDex[] = 197 "ZGV4CjAzNQBtKqZfzjHLNSNwW2A6Bz9FuCEX0sL+FF38AQAAcAAAAHhWNBIAAAAAAAAAAHQBAAAI" 198 "AAAAcAAAAAQAAACQAAAAAgAAAKAAAAAAAAAAAAAAAAMAAAC4AAAAAQAAANAAAAAMAQAA8AAAABwB" 199 "AAAkAQAALAEAAC8BAAA0AQAASAEAAEsBAABOAQAAAgAAAAMAAAAEAAAABQAAAAIAAAAAAAAAAAAA" 200 "AAUAAAADAAAAAAAAAAEAAQAAAAAAAQAAAAYAAAACAAEAAAAAAAEAAAABAAAAAgAAAAAAAAABAAAA" 201 "AAAAAGMBAAAAAAAAAQABAAEAAABUAQAABAAAAHAQAgAAAA4AAgABAAAAAABZAQAAAgAAABIQDwAG" 202 "PGluaXQ+AAZBLmphdmEAAUkAA0xBOwASTGphdmEvbGFuZy9PYmplY3Q7AAFWAAFhAAR0aGlzAAEA" 203 "Bw4AAwAHDh4GAAYAAAAAAQEAgYAE8AEBAYgCAAAACwAAAAAAAAABAAAAAAAAAAEAAAAIAAAAcAAA" 204 "AAIAAAAEAAAAkAAAAAMAAAACAAAAoAAAAAUAAAADAAAAuAAAAAYAAAABAAAA0AAAAAEgAAACAAAA" 205 "8AAAAAIgAAAIAAAAHAEAAAMgAAACAAAAVAEAAAAgAAABAAAAYwEAAAAQAAABAAAAdAEAAA=="; 206 207 // Dex file with multiple class data items pointing to the same code item. 208 // Constructed by hex editing. 209 static const char kDuplicateCodeItemInputDex[] = 210 "ZGV4CjAzNQCwKtVglQOmLWuHwldN5jkBOInC7mTMhJMAAgAAcAAAAHhWNBIAAAAAAAAAAHgBAAAH" 211 "AAAAcAAAAAMAAACMAAAAAQAAAJgAAAAAAAAAAAAAAAQAAACkAAAAAQAAAMQAAAAcAQAA5AAAACQB" 212 "AAAsAQAANAEAADkBAABNAQAAUAEAAFMBAAACAAAAAwAAAAQAAAAEAAAAAgAAAAAAAAAAAAAAAAAA" 213 "AAAAAAAFAAAAAAAAAAYAAAABAAAAAAAAAAAAAAABAAAAAQAAAAAAAAABAAAAAAAAAGUBAAAAAAAA" 214 "AQABAAEAAABWAQAABAAAAHAQAwAAAA4AAQABAAAAAABbAQAAAQAAAA4AAAABAAEAAAAAAGABAAAB" 215 "AAAADgAAAAY8aW5pdD4ABkEuamF2YQADTEE7ABJMamF2YS9sYW5nL09iamVjdDsAAVYAAWEAAWIA" 216 "AQAHDgADAAcOAAUABw4AAAABAgCBgATkAQEA/AEBAPwBAAsAAAAAAAAAAQAAAAAAAAABAAAABwAA" 217 "AHAAAAACAAAAAwAAAIwAAAADAAAAAQAAAJgAAAAFAAAABAAAAKQAAAAGAAAAAQAAAMQAAAABIAAA" 218 "AwAAAOQAAAACIAAABwAAACQBAAADIAAAAwAAAFYBAAAAIAAAAQAAAGUBAAAAEAAAAQAAAHgBAAA="; 219 220 static void WriteBase64ToFile(const char* base64, File* file) { 221 // Decode base64. 222 CHECK(base64 != nullptr); 223 size_t length; 224 std::unique_ptr<uint8_t[]> bytes(DecodeBase64(base64, &length)); 225 CHECK(bytes != nullptr); 226 if (!file->WriteFully(bytes.get(), length)) { 227 PLOG(FATAL) << "Failed to write base64 as file"; 228 } 229 } 230 231 static void WriteFileBase64(const char* base64, const char* location) { 232 // Write to provided file. 233 std::unique_ptr<File> file(OS::CreateEmptyFile(location)); 234 CHECK(file != nullptr); 235 WriteBase64ToFile(base64, file.get()); 236 if (file->FlushCloseOrErase() != 0) { 237 PLOG(FATAL) << "Could not flush and close test file."; 238 } 239 } 240 241 class DexLayoutTest : public CommonRuntimeTest { 242 protected: 243 virtual void SetUp() { 244 CommonRuntimeTest::SetUp(); 245 } 246 247 // Runs FullPlainOutput test. 248 bool FullPlainOutputExec(std::string* error_msg) { 249 // TODO: dexdump2 -> dexdump ? 250 ScratchFile dexdump_output; 251 const std::string& dexdump_filename = dexdump_output.GetFilename(); 252 std::string dexdump = GetTestAndroidRoot() + "/bin/dexdump2"; 253 EXPECT_TRUE(OS::FileExists(dexdump.c_str())) << dexdump << " should be a valid file path"; 254 255 ScratchFile dexlayout_output; 256 const std::string& dexlayout_filename = dexlayout_output.GetFilename(); 257 std::string dexlayout = GetTestAndroidRoot() + "/bin/dexlayout"; 258 EXPECT_TRUE(OS::FileExists(dexlayout.c_str())) << dexlayout << " should be a valid file path"; 259 260 for (const std::string &dex_file : GetLibCoreDexFileNames()) { 261 std::vector<std::string> dexdump_exec_argv = 262 { dexdump, "-d", "-f", "-h", "-l", "plain", "-o", dexdump_filename, dex_file }; 263 std::vector<std::string> dexlayout_exec_argv = 264 { dexlayout, "-d", "-f", "-h", "-l", "plain", "-o", dexlayout_filename, dex_file }; 265 if (!::art::Exec(dexdump_exec_argv, error_msg)) { 266 return false; 267 } 268 if (!::art::Exec(dexlayout_exec_argv, error_msg)) { 269 return false; 270 } 271 std::vector<std::string> diff_exec_argv = 272 { "/usr/bin/diff", dexdump_filename, dexlayout_filename }; 273 if (!::art::Exec(diff_exec_argv, error_msg)) { 274 return false; 275 } 276 } 277 return true; 278 } 279 280 // Runs DexFileOutput test. 281 bool DexFileOutputExec(std::string* error_msg) { 282 ScratchFile tmp_file; 283 const std::string& tmp_name = tmp_file.GetFilename(); 284 size_t tmp_last_slash = tmp_name.rfind('/'); 285 std::string tmp_dir = tmp_name.substr(0, tmp_last_slash + 1); 286 std::string dexlayout = GetTestAndroidRoot() + "/bin/dexlayout"; 287 EXPECT_TRUE(OS::FileExists(dexlayout.c_str())) << dexlayout << " should be a valid file path"; 288 289 for (const std::string &dex_file : GetLibCoreDexFileNames()) { 290 std::vector<std::string> dexlayout_exec_argv = 291 { dexlayout, "-w", tmp_dir, "-o", tmp_name, dex_file }; 292 if (!::art::Exec(dexlayout_exec_argv, error_msg)) { 293 return false; 294 } 295 size_t dex_file_last_slash = dex_file.rfind("/"); 296 std::string dex_file_name = dex_file.substr(dex_file_last_slash + 1); 297 std::vector<std::string> unzip_exec_argv = 298 { "/usr/bin/unzip", dex_file, "classes.dex", "-d", tmp_dir}; 299 if (!::art::Exec(unzip_exec_argv, error_msg)) { 300 return false; 301 } 302 std::vector<std::string> diff_exec_argv = 303 { "/usr/bin/diff", tmp_dir + "classes.dex" , tmp_dir + dex_file_name }; 304 if (!::art::Exec(diff_exec_argv, error_msg)) { 305 return false; 306 } 307 std::vector<std::string> rm_zip_exec_argv = { "/bin/rm", tmp_dir + "classes.dex" }; 308 if (!::art::Exec(rm_zip_exec_argv, error_msg)) { 309 return false; 310 } 311 std::vector<std::string> rm_out_exec_argv = { "/bin/rm", tmp_dir + dex_file_name }; 312 if (!::art::Exec(rm_out_exec_argv, error_msg)) { 313 return false; 314 } 315 } 316 return true; 317 } 318 319 // Create a profile with some subset of methods and classes. 320 void CreateProfile(const std::string& input_dex, 321 const std::string& out_profile, 322 const std::string& dex_location) { 323 std::vector<std::unique_ptr<const DexFile>> dex_files; 324 std::string error_msg; 325 bool result = DexFile::Open(input_dex.c_str(), 326 input_dex, 327 false, 328 &error_msg, 329 &dex_files); 330 331 ASSERT_TRUE(result) << error_msg; 332 ASSERT_GE(dex_files.size(), 1u); 333 334 size_t profile_methods = 0; 335 size_t profile_classes = 0; 336 ProfileCompilationInfo pfi; 337 std::set<DexCacheResolvedClasses> classes; 338 for (const std::unique_ptr<const DexFile>& dex_file : dex_files) { 339 for (uint32_t i = 0; i < dex_file->NumMethodIds(); i += 2) { 340 uint8_t flags = 0u; 341 342 if ((i & 3) != 0) { 343 flags |= ProfileCompilationInfo::MethodHotness::kFlagHot; 344 ++profile_methods; 345 } else if ((i & 2) != 0) { 346 flags |= ProfileCompilationInfo::MethodHotness::kFlagStartup; 347 ++profile_methods; 348 } 349 pfi.AddMethodIndex(static_cast<ProfileCompilationInfo::MethodHotness::Flag>(flags), 350 dex_location, 351 dex_file->GetLocationChecksum(), 352 /*dex_method_idx*/i, 353 dex_file->NumMethodIds()); 354 } 355 DexCacheResolvedClasses cur_classes(dex_location, 356 dex_location, 357 dex_file->GetLocationChecksum(), 358 dex_file->NumMethodIds()); 359 // Add every even class too. 360 for (uint32_t i = 0; i < dex_file->NumClassDefs(); i += 1) { 361 if ((i & 2) == 0) { 362 cur_classes.AddClass(dex_file->GetClassDef(i).class_idx_); 363 ++profile_classes; 364 } 365 } 366 classes.insert(cur_classes); 367 } 368 pfi.AddClasses(classes); 369 // Write to provided file. 370 std::unique_ptr<File> file(OS::CreateEmptyFile(out_profile.c_str())); 371 ASSERT_TRUE(file != nullptr); 372 pfi.Save(file->Fd()); 373 if (file->FlushCloseOrErase() != 0) { 374 PLOG(FATAL) << "Could not flush and close test file."; 375 } 376 EXPECT_GE(profile_methods, 0u); 377 EXPECT_GE(profile_classes, 0u); 378 } 379 380 // Runs DexFileLayout test. 381 bool DexFileLayoutExec(std::string* error_msg) { 382 ScratchFile tmp_file; 383 std::string tmp_name = tmp_file.GetFilename(); 384 size_t tmp_last_slash = tmp_name.rfind("/"); 385 std::string tmp_dir = tmp_name.substr(0, tmp_last_slash + 1); 386 387 // Write inputs and expected outputs. 388 std::string dex_file = tmp_dir + "classes.dex"; 389 WriteFileBase64(kDexFileLayoutInputDex, dex_file.c_str()); 390 std::string profile_file = tmp_dir + "primary.prof"; 391 CreateProfile(dex_file, profile_file, dex_file); 392 // WriteFileBase64(kDexFileLayoutInputProfile, profile_file.c_str()); 393 std::string output_dex = tmp_dir + "classes.dex.new"; 394 395 std::string dexlayout = GetTestAndroidRoot() + "/bin/dexlayout"; 396 EXPECT_TRUE(OS::FileExists(dexlayout.c_str())) << dexlayout << " should be a valid file path"; 397 398 std::vector<std::string> dexlayout_exec_argv = 399 { dexlayout, "-v", "-w", tmp_dir, "-o", tmp_name, "-p", profile_file, dex_file }; 400 if (!::art::Exec(dexlayout_exec_argv, error_msg)) { 401 return false; 402 } 403 404 // -v makes sure that the layout did not corrupt the dex file. 405 406 std::vector<std::string> rm_exec_argv = 407 { "/bin/rm", dex_file, profile_file, output_dex }; 408 if (!::art::Exec(rm_exec_argv, error_msg)) { 409 return false; 410 } 411 return true; 412 } 413 414 // Runs DexFileLayout test twice (second time is run on output of first time) 415 // for behavior consistency. 416 bool DexFileLayoutFixedPointExec(std::string* error_msg) { 417 ScratchFile tmp_file; 418 std::string tmp_name = tmp_file.GetFilename(); 419 size_t tmp_last_slash = tmp_name.rfind("/"); 420 std::string tmp_dir = tmp_name.substr(0, tmp_last_slash + 1); 421 422 // Unzip the test dex file to the classes.dex destination. It is required to unzip since 423 // opening from jar recalculates the dex location checksum. 424 std::string dex_file = tmp_dir + "classes.dex"; 425 426 std::vector<std::string> unzip_args = { 427 "/usr/bin/unzip", 428 GetTestDexFileName("ManyMethods"), 429 "classes.dex", 430 "-d", 431 tmp_dir, 432 }; 433 if (!art::Exec(unzip_args, error_msg)) { 434 LOG(ERROR) << "Failed to unzip dex"; 435 return false; 436 } 437 438 std::string profile_file = tmp_dir + "primary.prof"; 439 CreateProfile(dex_file, profile_file, dex_file); 440 std::string output_dex = tmp_dir + "classes.dex.new"; 441 std::string second_output_dex = tmp_dir + "classes.dex.new.new"; 442 443 std::string dexlayout = GetTestAndroidRoot() + "/bin/dexlayout"; 444 EXPECT_TRUE(OS::FileExists(dexlayout.c_str())) << dexlayout << " should be a valid file path"; 445 446 // -v makes sure that the layout did not corrupt the dex file. 447 std::vector<std::string> dexlayout_exec_argv = 448 { dexlayout, "-i", "-v", "-w", tmp_dir, "-o", tmp_name, "-p", profile_file, dex_file }; 449 if (!::art::Exec(dexlayout_exec_argv, error_msg)) { 450 return false; 451 } 452 453 // Recreate the profile with the new dex location. This is required so that the profile dex 454 // location matches. 455 CreateProfile(dex_file, profile_file, output_dex); 456 457 // -v makes sure that the layout did not corrupt the dex file. 458 // -i since the checksum won't match from the first layout. 459 std::vector<std::string> second_dexlayout_exec_argv = 460 { dexlayout, "-i", "-v", "-w", tmp_dir, "-o", tmp_name, "-p", profile_file, output_dex }; 461 if (!::art::Exec(second_dexlayout_exec_argv, error_msg)) { 462 return false; 463 } 464 465 bool diff_result = true; 466 std::vector<std::string> diff_exec_argv = 467 { "/usr/bin/diff", output_dex, second_output_dex }; 468 if (!::art::Exec(diff_exec_argv, error_msg)) { 469 diff_result = false; 470 } 471 472 std::vector<std::string> rm_exec_argv = 473 { "/bin/rm", dex_file, profile_file, output_dex, second_output_dex }; 474 if (!::art::Exec(rm_exec_argv, error_msg)) { 475 return false; 476 } 477 478 return diff_result; 479 } 480 481 // Runs UnreferencedCatchHandlerTest & Unreferenced0SizeCatchHandlerTest. 482 bool UnreferencedCatchHandlerExec(std::string* error_msg, const char* filename) { 483 ScratchFile tmp_file; 484 std::string tmp_name = tmp_file.GetFilename(); 485 size_t tmp_last_slash = tmp_name.rfind("/"); 486 std::string tmp_dir = tmp_name.substr(0, tmp_last_slash + 1); 487 488 // Write inputs and expected outputs. 489 std::string input_dex = tmp_dir + "classes.dex"; 490 WriteFileBase64(filename, input_dex.c_str()); 491 std::string output_dex = tmp_dir + "classes.dex.new"; 492 493 std::string dexlayout = GetTestAndroidRoot() + "/bin/dexlayout"; 494 EXPECT_TRUE(OS::FileExists(dexlayout.c_str())) << dexlayout << " should be a valid file path"; 495 496 std::vector<std::string> dexlayout_exec_argv = 497 { dexlayout, "-w", tmp_dir, "-o", "/dev/null", input_dex }; 498 if (!::art::Exec(dexlayout_exec_argv, error_msg)) { 499 return false; 500 } 501 502 // Diff input and output. They should be the same. 503 std::vector<std::string> diff_exec_argv = { "/usr/bin/diff", input_dex, output_dex }; 504 if (!::art::Exec(diff_exec_argv, error_msg)) { 505 return false; 506 } 507 508 std::vector<std::string> rm_exec_argv = { "/bin/rm", input_dex, output_dex }; 509 if (!::art::Exec(rm_exec_argv, error_msg)) { 510 return false; 511 } 512 return true; 513 } 514 515 bool DexLayoutExec(ScratchFile* dex_file, 516 const char* dex_filename, 517 ScratchFile* profile_file, 518 std::vector<std::string>& dexlayout_exec_argv) { 519 WriteBase64ToFile(dex_filename, dex_file->GetFile()); 520 EXPECT_EQ(dex_file->GetFile()->Flush(), 0); 521 if (profile_file != nullptr) { 522 CreateProfile(dex_file->GetFilename(), profile_file->GetFilename(), dex_file->GetFilename()); 523 } 524 std::string error_msg; 525 const bool result = ::art::Exec(dexlayout_exec_argv, &error_msg); 526 if (!result) { 527 LOG(ERROR) << "Error: " << error_msg; 528 return false; 529 } 530 return true; 531 } 532 }; 533 534 535 TEST_F(DexLayoutTest, FullPlainOutput) { 536 // Disable test on target. 537 TEST_DISABLED_FOR_TARGET(); 538 std::string error_msg; 539 ASSERT_TRUE(FullPlainOutputExec(&error_msg)) << error_msg; 540 } 541 542 TEST_F(DexLayoutTest, DexFileOutput) { 543 // Disable test on target. 544 TEST_DISABLED_FOR_TARGET(); 545 std::string error_msg; 546 ASSERT_TRUE(DexFileOutputExec(&error_msg)) << error_msg; 547 } 548 549 TEST_F(DexLayoutTest, DexFileLayout) { 550 // Disable test on target. 551 TEST_DISABLED_FOR_TARGET(); 552 std::string error_msg; 553 ASSERT_TRUE(DexFileLayoutExec(&error_msg)) << error_msg; 554 } 555 556 TEST_F(DexLayoutTest, DexFileLayoutFixedPoint) { 557 // Disable test on target. 558 TEST_DISABLED_FOR_TARGET(); 559 std::string error_msg; 560 ASSERT_TRUE(DexFileLayoutFixedPointExec(&error_msg)) << error_msg; 561 } 562 563 TEST_F(DexLayoutTest, UnreferencedCatchHandler) { 564 // Disable test on target. 565 TEST_DISABLED_FOR_TARGET(); 566 std::string error_msg; 567 ASSERT_TRUE(UnreferencedCatchHandlerExec(&error_msg, 568 kUnreferencedCatchHandlerInputDex)) << error_msg; 569 } 570 571 TEST_F(DexLayoutTest, Unreferenced0SizeCatchHandler) { 572 // Disable test on target. 573 TEST_DISABLED_FOR_TARGET(); 574 std::string error_msg; 575 ASSERT_TRUE(UnreferencedCatchHandlerExec(&error_msg, 576 kUnreferenced0SizeCatchHandlerInputDex)) << error_msg; 577 } 578 579 TEST_F(DexLayoutTest, UnreferencedEndingCatchHandler) { 580 // Disable test on target. 581 TEST_DISABLED_FOR_TARGET(); 582 std::string error_msg; 583 ASSERT_TRUE(UnreferencedCatchHandlerExec(&error_msg, 584 kUnreferencedEndingCatchHandlerInputDex)) << error_msg; 585 } 586 587 TEST_F(DexLayoutTest, DuplicateOffset) { 588 ScratchFile temp_dex; 589 std::string dexlayout = GetTestAndroidRoot() + "/bin/dexlayout"; 590 EXPECT_TRUE(OS::FileExists(dexlayout.c_str())) << dexlayout << " should be a valid file path"; 591 std::vector<std::string> dexlayout_exec_argv = 592 { dexlayout, "-a", "-i", "-o", "/dev/null", temp_dex.GetFilename() }; 593 ASSERT_TRUE(DexLayoutExec(&temp_dex, 594 kDexFileDuplicateOffset, 595 nullptr /* profile_file */, 596 dexlayout_exec_argv)); 597 } 598 599 TEST_F(DexLayoutTest, NullSetRefListElement) { 600 ScratchFile temp_dex; 601 std::string dexlayout = GetTestAndroidRoot() + "/bin/dexlayout"; 602 EXPECT_TRUE(OS::FileExists(dexlayout.c_str())) << dexlayout << " should be a valid file path"; 603 std::vector<std::string> dexlayout_exec_argv = 604 { dexlayout, "-o", "/dev/null", temp_dex.GetFilename() }; 605 ASSERT_TRUE(DexLayoutExec(&temp_dex, 606 kNullSetRefListElementInputDex, 607 nullptr /* profile_file */, 608 dexlayout_exec_argv)); 609 } 610 611 TEST_F(DexLayoutTest, MultiClassData) { 612 ScratchFile temp_dex; 613 ScratchFile temp_profile; 614 std::string dexlayout = GetTestAndroidRoot() + "/bin/dexlayout"; 615 EXPECT_TRUE(OS::FileExists(dexlayout.c_str())) << dexlayout << " should be a valid file path"; 616 std::vector<std::string> dexlayout_exec_argv = 617 { dexlayout, "-p", temp_profile.GetFilename(), "-o", "/dev/null", temp_dex.GetFilename() }; 618 ASSERT_TRUE(DexLayoutExec(&temp_dex, 619 kMultiClassDataInputDex, 620 &temp_profile, 621 dexlayout_exec_argv)); 622 } 623 624 TEST_F(DexLayoutTest, UnalignedCodeInfo) { 625 ScratchFile temp_dex; 626 ScratchFile temp_profile; 627 std::string dexlayout = GetTestAndroidRoot() + "/bin/dexlayout"; 628 EXPECT_TRUE(OS::FileExists(dexlayout.c_str())) << dexlayout << " should be a valid file path"; 629 std::vector<std::string> dexlayout_exec_argv = 630 { dexlayout, "-p", temp_profile.GetFilename(), "-o", "/dev/null", temp_dex.GetFilename() }; 631 ASSERT_TRUE(DexLayoutExec(&temp_dex, 632 kUnalignedCodeInfoInputDex, 633 &temp_profile, 634 dexlayout_exec_argv)); 635 } 636 637 TEST_F(DexLayoutTest, ClassDataBeforeCode) { 638 ScratchFile temp_dex; 639 ScratchFile temp_profile; 640 std::string dexlayout = GetTestAndroidRoot() + "/bin/dexlayout"; 641 EXPECT_TRUE(OS::FileExists(dexlayout.c_str())) << dexlayout << " should be a valid file path"; 642 std::vector<std::string> dexlayout_exec_argv = 643 { dexlayout, "-p", temp_profile.GetFilename(), "-o", "/dev/null", temp_dex.GetFilename() }; 644 ASSERT_TRUE(DexLayoutExec(&temp_dex, 645 kClassDataBeforeCodeInputDex, 646 &temp_profile, 647 dexlayout_exec_argv)); 648 } 649 650 TEST_F(DexLayoutTest, UnknownTypeDebugInfo) { 651 ScratchFile temp_dex; 652 std::string dexlayout = GetTestAndroidRoot() + "/bin/dexlayout"; 653 EXPECT_TRUE(OS::FileExists(dexlayout.c_str())) << dexlayout << " should be a valid file path"; 654 std::vector<std::string> dexlayout_exec_argv = 655 { dexlayout, "-o", "/dev/null", temp_dex.GetFilename() }; 656 ASSERT_TRUE(DexLayoutExec(&temp_dex, 657 kUnknownTypeDebugInfoInputDex, 658 nullptr /* profile_file */, 659 dexlayout_exec_argv)); 660 } 661 662 TEST_F(DexLayoutTest, DuplicateCodeItem) { 663 ScratchFile temp_dex; 664 std::string dexlayout = GetTestAndroidRoot() + "/bin/dexlayout"; 665 EXPECT_TRUE(OS::FileExists(dexlayout.c_str())) << dexlayout << " should be a valid file path"; 666 std::vector<std::string> dexlayout_exec_argv = 667 { dexlayout, "-o", "/dev/null", temp_dex.GetFilename() }; 668 ASSERT_TRUE(DexLayoutExec(&temp_dex, 669 kDuplicateCodeItemInputDex, 670 nullptr /* profile_file */, 671 dexlayout_exec_argv)); 672 } 673 674 } // namespace art 675