/*
 * Copyright (C) 2016 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#include <sstream>
#include <string>
#include <vector>

#include <sys/types.h>
#include <unistd.h>

#include "base/common_art_test.h"
#include "base/unix_file/fd_file.h"
#include "base/utils.h"
#include "dex/art_dex_file_loader.h"
#include "dex/base64_test_util.h"
#include "dex/class_accessor-inl.h"
#include "dex/code_item_accessors-inl.h"
#include "dex/dex_file-inl.h"
#include "dex/dex_file_loader.h"
#include "dexlayout.h"
#include "exec_utils.h"
#include "profile/profile_compilation_info.h"

namespace art {

static const char kDexFileLayoutInputDex[] =
    "ZGV4CjAzNQD1KW3+B8NAB0f2A/ZVIBJ0aHrGIqcpVTAUAgAAcAAAAHhWNBIAAAAAAAAAAIwBAAAH"
    "AAAAcAAAAAQAAACMAAAAAQAAAJwAAAAAAAAAAAAAAAMAAACoAAAAAgAAAMAAAAAUAQAAAAEAADAB"
    "AAA4AQAAQAEAAEgBAABNAQAAUgEAAGYBAAADAAAABAAAAAUAAAAGAAAABgAAAAMAAAAAAAAAAAAA"
    "AAAAAAABAAAAAAAAAAIAAAAAAAAAAAAAAAAAAAACAAAAAAAAAAEAAAAAAAAAdQEAAAAAAAABAAAA"
    "AAAAAAIAAAAAAAAAAgAAAAAAAAB/AQAAAAAAAAEAAQABAAAAaQEAAAQAAABwEAIAAAAOAAEAAQAB"
    "AAAAbwEAAAQAAABwEAIAAAAOAAY8aW5pdD4ABkEuamF2YQAGQi5qYXZhAANMQTsAA0xCOwASTGph"
    "dmEvbGFuZy9PYmplY3Q7AAFWAAQABw48AAQABw48AAAAAQAAgIAEgAIAAAEAAYCABJgCAAAACwAA"
    "AAAAAAABAAAAAAAAAAEAAAAHAAAAcAAAAAIAAAAEAAAAjAAAAAMAAAABAAAAnAAAAAUAAAADAAAA"
    "qAAAAAYAAAACAAAAwAAAAAEgAAACAAAAAAEAAAIgAAAHAAAAMAEAAAMgAAACAAAAaQEAAAAgAAAC"
    "AAAAdQEAAAAQAAABAAAAjAEAAA==";

// Dex file with catch handler unreferenced by try blocks.
// Constructed by building a dex file with try/catch blocks and hex editing.
static const char kUnreferencedCatchHandlerInputDex[] =
    "ZGV4CjAzNQD+exd52Y0f9nY5x5GmInXq5nXrO6Kl2RV4AwAAcAAAAHhWNBIAAAAAAAAAANgCAAAS"
    "AAAAcAAAAAgAAAC4AAAAAwAAANgAAAABAAAA/AAAAAQAAAAEAQAAAQAAACQBAAA0AgAARAEAANYB"
    "AADeAQAA5gEAAO4BAAAAAgAADwIAACYCAAA9AgAAUQIAAGUCAAB5AgAAfwIAAIUCAACIAgAAjAIA"
    "AKECAACnAgAArAIAAAQAAAAFAAAABgAAAAcAAAAIAAAACQAAAAwAAAAOAAAADAAAAAYAAAAAAAAA"
    "DQAAAAYAAADIAQAADQAAAAYAAADQAQAABQABABAAAAAAAAAAAAAAAAAAAgAPAAAAAQABABEAAAAD"
    "AAAAAAAAAAAAAAABAAAAAwAAAAAAAAADAAAAAAAAAMgCAAAAAAAAAQABAAEAAAC1AgAABAAAAHAQ"
    "AwAAAA4AAwABAAIAAgC6AgAAIQAAAGIAAAAaAQoAbiACABAAYgAAABoBCwBuIAIAEAAOAA0AYgAA"
    "ABoBAQBuIAIAEAAo8A0AYgAAABoBAgBuIAIAEAAo7gAAAAAAAAcAAQAHAAAABwABAAIBAg8BAhgA"
    "AQAAAAQAAAABAAAABwAGPGluaXQ+AAZDYXRjaDEABkNhdGNoMgAQSGFuZGxlclRlc3QuamF2YQAN"
    "TEhhbmRsZXJUZXN0OwAVTGphdmEvaW8vUHJpbnRTdHJlYW07ABVMamF2YS9sYW5nL0V4Y2VwdGlv"
    "bjsAEkxqYXZhL2xhbmcvT2JqZWN0OwASTGphdmEvbGFuZy9TdHJpbmc7ABJMamF2YS9sYW5nL1N5"
    "c3RlbTsABFRyeTEABFRyeTIAAVYAAlZMABNbTGphdmEvbGFuZy9TdHJpbmc7AARtYWluAANvdXQA"
    "B3ByaW50bG4AAQAHDgAEAQAHDn17AncdHoseAAAAAgAAgYAExAIBCdwCAAANAAAAAAAAAAEAAAAA"
    "AAAAAQAAABIAAABwAAAAAgAAAAgAAAC4AAAAAwAAAAMAAADYAAAABAAAAAEAAAD8AAAABQAAAAQA"
    "AAAEAQAABgAAAAEAAAAkAQAAASAAAAIAAABEAQAAARAAAAIAAADIAQAAAiAAABIAAADWAQAAAyAA"
    "AAIAAAC1AgAAACAAAAEAAADIAgAAABAAAAEAAADYAgAA";

// Dex file with 0-size (catch all only) catch handler unreferenced by try blocks.
// Constructed by building a dex file with try/catch blocks and hex editing.
static const char kUnreferenced0SizeCatchHandlerInputDex[] =
    "ZGV4CjAzNQCEbEEvMstSNpQpjPdfMEfUBS48cis2QRJoAwAAcAAAAHhWNBIAAAAAAAAAAMgCAAAR"
    "AAAAcAAAAAcAAAC0AAAAAwAAANAAAAABAAAA9AAAAAQAAAD8AAAAAQAAABwBAAAsAgAAPAEAAOoB"
    "AADyAQAABAIAABMCAAAqAgAAPgIAAFICAABmAgAAaQIAAG0CAACCAgAAhgIAAIoCAACQAgAAlQIA"
    "AJ4CAACiAgAAAgAAAAMAAAAEAAAABQAAAAYAAAAHAAAACQAAAAcAAAAFAAAAAAAAAAgAAAAFAAAA"
    "3AEAAAgAAAAFAAAA5AEAAAQAAQANAAAAAAAAAAAAAAAAAAIADAAAAAEAAQAOAAAAAgAAAAAAAAAA"
    "AAAAAQAAAAIAAAAAAAAAAQAAAAAAAAC5AgAAAAAAAAEAAQABAAAApgIAAAQAAABwEAMAAAAOAAQA"
    "AQACAAIAqwIAAC8AAABiAAAAGgEPAG4gAgAQAGIAAAAaAQoAbiACABAAYgAAABoBEABuIAIAEABi"
    "AAAAGgELAG4gAgAQAA4ADQBiAQAAGgIKAG4gAgAhACcADQBiAQAAGgILAG4gAgAhACcAAAAAAAAA"
    "BwABAA4AAAAHAAEAAgAdACYAAAABAAAAAwAAAAEAAAAGAAY8aW5pdD4AEEhhbmRsZXJUZXN0Lmph"
    "dmEADUxIYW5kbGVyVGVzdDsAFUxqYXZhL2lvL1ByaW50U3RyZWFtOwASTGphdmEvbGFuZy9PYmpl"
    "Y3Q7ABJMamF2YS9sYW5nL1N0cmluZzsAEkxqYXZhL2xhbmcvU3lzdGVtOwABVgACVkwAE1tMamF2"
    "YS9sYW5nL1N0cmluZzsAAmYxAAJmMgAEbWFpbgADb3V0AAdwcmludGxuAAJ0MQACdDIAAQAHDgAE"
    "AQAHDnl7eXkCeB2bAAAAAgAAgYAEvAIBCdQCAA0AAAAAAAAAAQAAAAAAAAABAAAAEQAAAHAAAAAC"
    "AAAABwAAALQAAAADAAAAAwAAANAAAAAEAAAAAQAAAPQAAAAFAAAABAAAAPwAAAAGAAAAAQAAABwB"
    "AAABIAAAAgAAADwBAAABEAAAAgAAANwBAAACIAAAEQAAAOoBAAADIAAAAgAAAKYCAAAAIAAAAQAA"
    "ALkCAAAAEAAAAQAAAMgCAAA=";

// Dex file with an unreferenced catch handler at end of code item.
// Constructed by building a dex file with try/catch blocks and hex editing.
static const char kUnreferencedEndingCatchHandlerInputDex[] =
    "ZGV4CjAzNQCEflufI6xGTDDRmLpbfYi6ujPrDLIwvYcEBAAAcAAAAHhWNBIAAAAAAAAAAGQDAAAT"
    "AAAAcAAAAAgAAAC8AAAAAwAAANwAAAABAAAAAAEAAAUAAAAIAQAAAQAAADABAAC0AgAAUAEAAE4C"
    "AABWAgAAXgIAAGYCAAB4AgAAhwIAAJ4CAAC1AgAAyQIAAN0CAADxAgAA9wIAAP0CAAAAAwAABAMA"
    "ABkDAAAcAwAAIgMAACcDAAAEAAAABQAAAAYAAAAHAAAACAAAAAkAAAAMAAAADgAAAAwAAAAGAAAA"
    "AAAAAA0AAAAGAAAAQAIAAA0AAAAGAAAASAIAAAUAAQARAAAAAAAAAAAAAAAAAAAADwAAAAAAAgAQ"
    "AAAAAQABABIAAAADAAAAAAAAAAAAAAABAAAAAwAAAAAAAAADAAAAAAAAAFADAAAAAAAAAQABAAEA"
    "AAAwAwAABAAAAHAQBAAAAA4AAgAAAAIAAgA1AwAAIQAAAGIAAAAaAQoAbiADABAAYgAAABoBCwBu"
    "IAMAEAAOAA0AYgAAABoBAQBuIAMAEAAo8A0AYgAAABoBAgBuIAMAEAAo7gAAAAAAAAcAAQAHAAAA"
    "BwABAAIBAg8BAhgAAwABAAIAAgBCAwAAIQAAAGIAAAAaAQoAbiADABAAYgAAABoBCwBuIAMAEAAO"
    "AA0AYgAAABoBAQBuIAMAEAAo8A0AYgAAABoBAgBuIAMAEAAo7gAAAAAAAAcAAQAHAAAABwABAAIB"
    "Ag8BAhgAAQAAAAQAAAABAAAABwAGPGluaXQ+AAZDYXRjaDEABkNhdGNoMgAQSGFuZGxlclRlc3Qu"
    "amF2YQANTEhhbmRsZXJUZXN0OwAVTGphdmEvaW8vUHJpbnRTdHJlYW07ABVMamF2YS9sYW5nL0V4"
    "Y2VwdGlvbjsAEkxqYXZhL2xhbmcvT2JqZWN0OwASTGphdmEvbGFuZy9TdHJpbmc7ABJMamF2YS9s"
    "YW5nL1N5c3RlbTsABFRyeTEABFRyeTIAAVYAAlZMABNbTGphdmEvbGFuZy9TdHJpbmc7AAFhAARt"
    "YWluAANvdXQAB3ByaW50bG4AAQAHDgAEAAcOfHsCeB0eih4AEQEABw59ewJ3HR6LHgAAAAMAAIGA"
    "BNACAQnoAgEJ1AMAAA0AAAAAAAAAAQAAAAAAAAABAAAAEwAAAHAAAAACAAAACAAAALwAAAADAAAA"
    "AwAAANwAAAAEAAAAAQAAAAABAAAFAAAABQAAAAgBAAAGAAAAAQAAADABAAABIAAAAwAAAFABAAAB"
    "EAAAAgAAAEACAAACIAAAEwAAAE4CAAADIAAAAwAAADADAAAAIAAAAQAAAFADAAAAEAAAAQAAAGQD"
    "AAA=";

// Dex file with multiple code items that have the same debug_info_off_. Constructed by a modified
// dexlayout on XandY.
static const char kDexFileDuplicateOffset[] =
    "ZGV4CjAzNwAQfXfPCB8qCxo7MqdFhmHZQwCv8+udHD8MBAAAcAAAAHhWNBIAAAAAAAAAAFQDAAAT"
    "AAAAcAAAAAgAAAC8AAAAAQAAANwAAAABAAAA6AAAAAUAAADwAAAAAwAAABgBAACUAgAAeAEAABQC"
    "AAAeAgAAJgIAACsCAAAyAgAANwIAAFsCAAB7AgAAngIAALICAAC1AgAAvQIAAMUCAADIAgAA1QIA"
    "AOkCAADvAgAA9QIAAPwCAAACAAAAAwAAAAQAAAAFAAAABgAAAAcAAAAIAAAACQAAAAkAAAAHAAAA"
    "AAAAAAIAAQASAAAAAAAAAAEAAAABAAAAAQAAAAIAAAAAAAAAAgAAAAEAAAAGAAAAAQAAAAAAAAAA"
    "AAAABgAAAAAAAAAKAAAAAAAAACsDAAAAAAAAAQAAAAAAAAAGAAAAAAAAAAsAAAD0AQAANQMAAAAA"
    "AAACAAAAAAAAAAAAAAAAAAAACwAAAAQCAAA/AwAAAAAAAAIAAAAUAwAAGgMAAAEAAAAjAwAAAQAB"
    "AAEAAAAFAAAABAAAAHAQBAAAAA4AAQABAAEAAAAFAAAABAAAAHAQBAAAAA4AAQAAAAEAAAAFAAAA"
    "CAAAACIAAQBwEAEAAABpAAAADgABAAEAAQAAAAUAAAAEAAAAcBAAAAAADgB4AQAAAAAAAAAAAAAA"
    "AAAAhAEAAAAAAAAAAAAAAAAAAAg8Y2xpbml0PgAGPGluaXQ+AANMWDsABUxZJFo7AANMWTsAIkxk"
    "YWx2aWsvYW5ub3RhdGlvbi9FbmNsb3NpbmdDbGFzczsAHkxkYWx2aWsvYW5ub3RhdGlvbi9Jbm5l"
    "ckNsYXNzOwAhTGRhbHZpay9hbm5vdGF0aW9uL01lbWJlckNsYXNzZXM7ABJMamF2YS9sYW5nL09i"
    "amVjdDsAAVYABlguamF2YQAGWS5qYXZhAAFaAAthY2Nlc3NGbGFncwASZW1pdHRlcjogamFjay00"
    "LjI1AARuYW1lAAR0aGlzAAV2YWx1ZQABegARAAcOABMABw4AEgAHDnYAEQAHDgACAwERGAICBAIN"
    "BAgPFwwCBQERHAEYAQAAAQAAgIAEjAMAAAEAAYCABKQDAQACAAAIAoiABLwDAYCABNwDAAAADwAA"
    "AAAAAAABAAAAAAAAAAEAAAATAAAAcAAAAAIAAAAIAAAAvAAAAAMAAAABAAAA3AAAAAQAAAABAAAA"
    "6AAAAAUAAAAFAAAA8AAAAAYAAAADAAAAGAEAAAMQAAACAAAAeAEAAAEgAAAEAAAAjAEAAAYgAAAC"
    "AAAA9AEAAAIgAAATAAAAFAIAAAMgAAAEAAAA/wIAAAQgAAADAAAAFAMAAAAgAAADAAAAKwMAAAAQ"
    "AAABAAAAVAMAAA==";

// Dex file with null value for annotations_off in the annotation_set_ref_list.
// Constructed by building a dex file with annotations and hex editing.
static const char kNullSetRefListElementInputDex[] =
    "ZGV4CjAzNQB1iA+7ZwgkF+7E6ZesYFc2lRAR3qnRAanwAwAAcAAAAHhWNBIAAAAAAAAAACADAAAS"
    "AAAAcAAAAAgAAAC4AAAAAwAAANgAAAABAAAA/AAAAAQAAAAEAQAAAgAAACQBAACMAgAAZAEAAOgB"
    "AADwAQAAAAIAAAMCAAAQAgAAIAIAADQCAABIAgAAawIAAI0CAAC1AgAAyAIAANECAADUAgAA2QIA"
    "ANwCAADjAgAA6QIAAAMAAAAEAAAABQAAAAYAAAAHAAAACAAAAAkAAAAMAAAAAgAAAAMAAAAAAAAA"
    "DAAAAAcAAAAAAAAADQAAAAcAAADgAQAABgAGAAsAAAAAAAEAAAAAAAAAAgAOAAAAAQAAABAAAAAC"
    "AAEAAAAAAAAAAAAAAAAAAgAAAAAAAAABAAAAsAEAAAgDAAAAAAAAAQAAAAEmAAACAAAA2AEAAAoA"
    "AADIAQAAFgMAAAAAAAACAAAAAAAAAHwBAAABAAAA/AIAAAAAAAABAAAAAgMAAAEAAQABAAAA8AIA"
    "AAQAAABwEAMAAAAOAAIAAgAAAAAA9QIAAAEAAAAOAAAAAAAAAAAAAAAAAAAAAQAAAAEAAABkAQAA"
    "cAEAAAAAAAAAAAAAAAAAAAEAAAAEAAAAAgAAAAMAAwAGPGluaXQ+AA5Bbm5vQ2xhc3MuamF2YQAB"
    "TAALTEFubm9DbGFzczsADkxNeUFubm90YXRpb247ABJMamF2YS9sYW5nL09iamVjdDsAEkxqYXZh"
    "L2xhbmcvU3RyaW5nOwAhTGphdmEvbGFuZy9hbm5vdGF0aW9uL0Fubm90YXRpb247ACBMamF2YS9s"
    "YW5nL2Fubm90YXRpb24vUmV0ZW50aW9uOwAmTGphdmEvbGFuZy9hbm5vdGF0aW9uL1JldGVudGlv"
    "blBvbGljeTsAEU15QW5ub3RhdGlvbi5qYXZhAAdSVU5USU1FAAFWAANWTEwAAWEABWFOYW1lAARu"
    "YW1lAAV2YWx1ZQABAAcOAAICAAAHDgABBQERGwABAQEQFw8AAAIAAICABIQDAQmcAwAAAAECgQgA"
    "AAARAAAAAAAAAAEAAAAAAAAAAQAAABIAAABwAAAAAgAAAAgAAAC4AAAAAwAAAAMAAADYAAAABAAA"
    "AAEAAAD8AAAABQAAAAQAAAAEAQAABgAAAAIAAAAkAQAAAhAAAAEAAABkAQAAAxAAAAMAAABwAQAA"
    "ASAAAAIAAACEAQAABiAAAAIAAACwAQAAARAAAAIAAADYAQAAAiAAABIAAADoAQAAAyAAAAIAAADw"
    "AgAABCAAAAIAAAD8AgAAACAAAAIAAAAIAwAAABAAAAEAAAAgAwAA";

// Dex file with shared empty class data item for multiple class defs.
// Constructing by building a dex file with multiple classes and hex editing.
static const char kMultiClassDataInputDex[] =
    "ZGV4CjAzNQALJgF9TtnLq748xVe/+wyxETrT9lTEiW6YAQAAcAAAAHhWNBIAAAAAAAAAADQBAAAI"
    "AAAAcAAAAAQAAACQAAAAAAAAAAAAAAACAAAAoAAAAAAAAAAAAAAAAgAAALAAAACoAAAA8AAAAPAA"
    "AAD4AAAAAAEAAAMBAAAIAQAADQEAACEBAAAkAQAAAgAAAAMAAAAEAAAABQAAAAEAAAAGAAAAAgAA"
    "AAcAAAABAAAAAQYAAAMAAAAAAAAAAAAAAAAAAAAnAQAAAAAAAAIAAAABBgAAAwAAAAAAAAABAAAA"
    "AAAAACcBAAAAAAAABkEuamF2YQAGQi5qYXZhAAFJAANMQTsAA0xCOwASTGphdmEvbGFuZy9PYmpl"
    "Y3Q7AAFhAAFiAAAAAAABAAAAARkAAAAIAAAAAAAAAAEAAAAAAAAAAQAAAAgAAABwAAAAAgAAAAQA"
    "AACQAAAABAAAAAIAAACgAAAABgAAAAIAAACwAAAAAiAAAAgAAADwAAAAACAAAAIAAAAnAQAAABAA"
    "AAEAAAA0AQAA";

// Dex file with code info followed by non 4-byte aligned section.
// Constructed a dex file with code info followed by string data and hex edited.
static const char kUnalignedCodeInfoInputDex[] =
    "ZGV4CjAzNQDXJzXNb4iWn2SLhmLydW/8h1K9moERIw7UAQAAcAAAAHhWNBIAAAAAAAAAAEwBAAAG"
    "AAAAcAAAAAMAAACIAAAAAQAAAJQAAAAAAAAAAAAAAAMAAACgAAAAAQAAALgAAAD8AAAA2AAAAAIB"
    "AAAKAQAAEgEAABcBAAArAQAALgEAAAIAAAADAAAABAAAAAQAAAACAAAAAAAAAAAAAAAAAAAAAAAA"
    "AAUAAAABAAAAAAAAAAAAAAABAAAAAQAAAAAAAAABAAAAAAAAADsBAAAAAAAAAQABAAEAAAAxAQAA"
    "BAAAAHAQAgAAAA4AAQABAAAAAAA2AQAAAQAAAA4ABjxpbml0PgAGQS5qYXZhAANMQTsAEkxqYXZh"
    "L2xhbmcvT2JqZWN0OwABVgABYQABAAcOAAMABw4AAAABAQCBgATYAQEB8AEAAAALAAAAAAAAAAEA"
    "AAAAAAAAAQAAAAYAAABwAAAAAgAAAAMAAACIAAAAAwAAAAEAAACUAAAABQAAAAMAAACgAAAABgAA"
    "AAEAAAC4AAAAASAAAAIAAADYAAAAAiAAAAYAAAACAQAAAyAAAAIAAAAxAQAAACAAAAEAAAA7AQAA"
    "ABAAAAEAAABMAQAA";

// Dex file with class data section preceding code items.
// Constructed by passing dex file through dexmerger tool and hex editing.
static const char kClassDataBeforeCodeInputDex[] =
    "ZGV4CjAzNQCZKmCu3XXn4zvxCh5VH0gZNNobEAcsc49EAgAAcAAAAHhWNBIAAAAAAAAAAAQBAAAJ"
    "AAAAcAAAAAQAAACUAAAAAgAAAKQAAAAAAAAAAAAAAAUAAAC8AAAAAQAAAOQAAABAAQAABAEAAPgB"
    "AAAAAgAACAIAAAsCAAAQAgAAJAIAACcCAAAqAgAALQIAAAIAAAADAAAABAAAAAUAAAACAAAAAAAA"
    "AAAAAAAFAAAAAwAAAAAAAAABAAEAAAAAAAEAAAAGAAAAAQAAAAcAAAABAAAACAAAAAIAAQAAAAAA"
    "AQAAAAEAAAACAAAAAAAAAAEAAAAAAAAAjAEAAAAAAAALAAAAAAAAAAEAAAAAAAAAAQAAAAkAAABw"
    "AAAAAgAAAAQAAACUAAAAAwAAAAIAAACkAAAABQAAAAUAAAC8AAAABgAAAAEAAADkAAAAABAAAAEA"
    "AAAEAQAAACAAAAEAAACMAQAAASAAAAQAAACkAQAAAiAAAAkAAAD4AQAAAyAAAAQAAAAwAgAAAAAB"
    "AwCBgASkAwEBvAMBAdADAQHkAwAAAQABAAEAAAAwAgAABAAAAHAQBAAAAA4AAgABAAAAAAA1AgAA"
    "AgAAABIQDwACAAEAAAAAADoCAAACAAAAEiAPAAIAAQAAAAAAPwIAAAIAAAASMA8ABjxpbml0PgAG"
    "QS5qYXZhAAFJAANMQTsAEkxqYXZhL2xhbmcvT2JqZWN0OwABVgABYQABYgABYwABAAcOAAMABw4A"
    "BgAHDgAJAAcOAA==";

// Dex file with local info containing a null type descriptor.
// Constructed a dex file with debug info sequence containing DBG_RESTART_LOCAL without any
// DBG_START_LOCAL to give it a declared type.
static const char kUnknownTypeDebugInfoInputDex[] =
    "ZGV4CjAzNQBtKqZfzjHLNSNwW2A6Bz9FuCEX0sL+FF38AQAAcAAAAHhWNBIAAAAAAAAAAHQBAAAI"
    "AAAAcAAAAAQAAACQAAAAAgAAAKAAAAAAAAAAAAAAAAMAAAC4AAAAAQAAANAAAAAMAQAA8AAAABwB"
    "AAAkAQAALAEAAC8BAAA0AQAASAEAAEsBAABOAQAAAgAAAAMAAAAEAAAABQAAAAIAAAAAAAAAAAAA"
    "AAUAAAADAAAAAAAAAAEAAQAAAAAAAQAAAAYAAAACAAEAAAAAAAEAAAABAAAAAgAAAAAAAAABAAAA"
    "AAAAAGMBAAAAAAAAAQABAAEAAABUAQAABAAAAHAQAgAAAA4AAgABAAAAAABZAQAAAgAAABIQDwAG"
    "PGluaXQ+AAZBLmphdmEAAUkAA0xBOwASTGphdmEvbGFuZy9PYmplY3Q7AAFWAAFhAAR0aGlzAAEA"
    "Bw4AAwAHDh4GAAYAAAAAAQEAgYAE8AEBAYgCAAAACwAAAAAAAAABAAAAAAAAAAEAAAAIAAAAcAAA"
    "AAIAAAAEAAAAkAAAAAMAAAACAAAAoAAAAAUAAAADAAAAuAAAAAYAAAABAAAA0AAAAAEgAAACAAAA"
    "8AAAAAIgAAAIAAAAHAEAAAMgAAACAAAAVAEAAAAgAAABAAAAYwEAAAAQAAABAAAAdAEAAA==";

// Dex file with multiple class data items pointing to the same code item.
// Constructed by hex editing.
static const char kDuplicateCodeItemInputDex[] =
    "ZGV4CjAzNQCwKtVglQOmLWuHwldN5jkBOInC7mTMhJMAAgAAcAAAAHhWNBIAAAAAAAAAAHgBAAAH"
    "AAAAcAAAAAMAAACMAAAAAQAAAJgAAAAAAAAAAAAAAAQAAACkAAAAAQAAAMQAAAAcAQAA5AAAACQB"
    "AAAsAQAANAEAADkBAABNAQAAUAEAAFMBAAACAAAAAwAAAAQAAAAEAAAAAgAAAAAAAAAAAAAAAAAA"
    "AAAAAAAFAAAAAAAAAAYAAAABAAAAAAAAAAAAAAABAAAAAQAAAAAAAAABAAAAAAAAAGUBAAAAAAAA"
    "AQABAAEAAABWAQAABAAAAHAQAwAAAA4AAQABAAAAAABbAQAAAQAAAA4AAAABAAEAAAAAAGABAAAB"
    "AAAADgAAAAY8aW5pdD4ABkEuamF2YQADTEE7ABJMamF2YS9sYW5nL09iamVjdDsAAVYAAWEAAWIA"
    "AQAHDgADAAcOAAUABw4AAAABAgCBgATkAQEA/AEBAPwBAAsAAAAAAAAAAQAAAAAAAAABAAAABwAA"
    "AHAAAAACAAAAAwAAAIwAAAADAAAAAQAAAJgAAAAFAAAABAAAAKQAAAAGAAAAAQAAAMQAAAABIAAA"
    "AwAAAOQAAAACIAAABwAAACQBAAADIAAAAwAAAFYBAAAAIAAAAQAAAGUBAAAAEAAAAQAAAHgBAAA=";

// Returns the default compact dex option for dexlayout based on kDefaultCompactDexLevel.
static std::vector<std::string> DefaultCompactDexOption() {
  return (kDefaultCompactDexLevel == CompactDexLevel::kCompactDexLevelFast) ?
      std::vector<std::string>{"-x", "fast"} : std::vector<std::string>{"-x", "none"};
}

static void WriteBase64ToFile(const char* base64, File* file) {
  // Decode base64.
  CHECK(base64 != nullptr);
  size_t length;
  std::unique_ptr<uint8_t[]> bytes(DecodeBase64(base64, &length));
  CHECK(bytes != nullptr);
  if (!file->WriteFully(bytes.get(), length)) {
    PLOG(FATAL) << "Failed to write base64 as file";
  }
}

static void WriteFileBase64(const char* base64, const char* location) {
  // Write to provided file.
  std::unique_ptr<File> file(OS::CreateEmptyFile(location));
  CHECK(file != nullptr);
  WriteBase64ToFile(base64, file.get());
  if (file->FlushCloseOrErase() != 0) {
    PLOG(FATAL) << "Could not flush and close test file.";
  }
}

class DexLayoutTest : public CommonArtTest {
 protected:
  std::string GetDexLayoutPath() {
    return GetArtBinDir() + "/dexlayoutd";
  }

  // Runs FullPlainOutput test.
  bool FullPlainOutputExec(std::string* error_msg) {
    ScratchFile dexdump_output;
    const std::string& dexdump_filename = dexdump_output.GetFilename();
    std::string dexdump = GetArtBinDir() + "/dexdump";
    EXPECT_TRUE(OS::FileExists(dexdump.c_str())) << dexdump << " should be a valid file path";

    ScratchFile dexlayout_output;
    const std::string& dexlayout_filename = dexlayout_output.GetFilename();

    for (const std::string& dex_file : GetLibCoreDexFileNames()) {
      std::vector<std::string> dexdump_exec_argv =
          { dexdump, "-d", "-f", "-h", "-l", "plain", "-o", dexdump_filename, dex_file };
      std::vector<std::string> dexlayout_args =
          { "-d", "-f", "-h", "-l", "plain", "-o", dexlayout_filename, dex_file };
      if (!::art::Exec(dexdump_exec_argv, error_msg)) {
        return false;
      }
      if (!DexLayoutExec(dexlayout_args, error_msg)) {
        return false;
      }
      std::vector<std::string> diff_exec_argv =
          { "/usr/bin/diff", dexdump_filename, dexlayout_filename };
      if (!::art::Exec(diff_exec_argv, error_msg)) {
        return false;
      }
    }
    return true;
  }

  // Runs DexFileOutput test.
  bool DexFileOutputExec(std::string* error_msg) {
    ScratchFile tmp_file;
    const std::string& tmp_name = tmp_file.GetFilename();
    size_t tmp_last_slash = tmp_name.rfind('/');
    std::string tmp_dir = tmp_name.substr(0, tmp_last_slash + 1);
    std::string unzip_dir = tmp_dir + "unzip/";

    for (const std::string& dex_file : GetLibCoreDexFileNames()) {
      std::vector<std::string> dexlayout_args =
          { "-w", tmp_dir, "-o", tmp_name, dex_file };
      if (!DexLayoutExec(dexlayout_args, error_msg, /*pass_default_cdex_option=*/ false)) {
        return false;
      }
      std::string dex_file_name = "classes.dex";
      std::vector<std::string> unzip_exec_argv =
          { "/usr/bin/unzip", dex_file, "classes.dex", "-d", unzip_dir};
      if (!::art::Exec(unzip_exec_argv, error_msg)) {
        return false;
      }
      std::vector<std::string> diff_exec_argv =
          { "/usr/bin/diff", tmp_dir + "classes.dex" , unzip_dir + dex_file_name };
      if (!::art::Exec(diff_exec_argv, error_msg)) {
        return false;
      }
      if (!UnlinkFile(unzip_dir + "classes.dex")) {
        return false;
      }
      if (!UnlinkFile(tmp_dir + dex_file_name)) {
        return false;
      }
      // Remove the unzip temp directory so that unlinking android_data doesn't fail.
      EXPECT_EQ(rmdir(unzip_dir.c_str()), 0);
    }
    return true;
  }

  // Create a profile with some subset of methods and classes.
  void CreateProfile(const std::string& input_dex,
                     const std::string& out_profile) {
    std::vector<std::unique_ptr<const DexFile>> dex_files;
    std::string error_msg;
    const ArtDexFileLoader dex_file_loader;
    bool result = dex_file_loader.Open(input_dex.c_str(),
                                       input_dex,
                                       /*verify=*/ true,
                                       /*verify_checksum=*/ false,
                                       &error_msg,
                                       &dex_files);

    ASSERT_TRUE(result) << error_msg;
    ASSERT_GE(dex_files.size(), 1u);

    size_t profile_methods = 0;
    size_t profile_classes = 0;
    ProfileCompilationInfo pfi;
    for (const std::unique_ptr<const DexFile>& dex_file : dex_files) {
      for (uint32_t i = 0; i < dex_file->NumMethodIds(); i += 2) {
        uint8_t flags = 0u;

        if ((i & 3) != 0) {
          flags |= ProfileCompilationInfo::MethodHotness::kFlagHot;
          ++profile_methods;
        } else if ((i & 2) != 0) {
          flags |= ProfileCompilationInfo::MethodHotness::kFlagStartup;
          ++profile_methods;
        }
        pfi.AddMethod(ProfileMethodInfo(MethodReference(dex_file.get(), /*index=*/ i)),
                      static_cast<ProfileCompilationInfo::MethodHotness::Flag>(flags));
      }
      // Add every even class too.
      std::set<dex::TypeIndex> classes;
      for (uint32_t i = 0; i < dex_file->NumClassDefs(); i += 1) {
        if ((i & 2) == 0) {
          classes.insert(dex::TypeIndex(dex_file->GetClassDef(i).class_idx_));
          ++profile_classes;
        }
      }
      if (!classes.empty()) {
        pfi.AddClassesForDex(dex_file.get(), classes.begin(), classes.end());
      }
    }
    // Write to provided file.
    std::unique_ptr<File> file(OS::CreateEmptyFile(out_profile.c_str()));
    ASSERT_TRUE(file != nullptr);
    pfi.Save(file->Fd());
    if (file->FlushCloseOrErase() != 0) {
      PLOG(FATAL) << "Could not flush and close test file.";
    }
    EXPECT_GE(profile_methods, 0u);
    EXPECT_GE(profile_classes, 0u);
  }

  // Runs DexFileLayout test.
  bool DexFileLayoutExec(std::string* error_msg) {
    ScratchFile tmp_file;
    const std::string& tmp_name = tmp_file.GetFilename();
    size_t tmp_last_slash = tmp_name.rfind('/');
    std::string tmp_dir = tmp_name.substr(0, tmp_last_slash + 1);

    // Write inputs and expected outputs.
    std::string dex_file = tmp_dir + "classes.dex";
    WriteFileBase64(kDexFileLayoutInputDex, dex_file.c_str());
    std::string profile_file = tmp_dir + "primary.prof";
    CreateProfile(dex_file, profile_file);
    // WriteFileBase64(kDexFileLayoutInputProfile, profile_file.c_str());
    std::string output_dex = tmp_dir + "classes.dex.new";

    std::vector<std::string> dexlayout_args =
        { "-v", "-w", tmp_dir, "-o", tmp_name, "-p", profile_file, dex_file };
    if (!DexLayoutExec(dexlayout_args, error_msg)) {
      return false;
    }

    // -v makes sure that the layout did not corrupt the dex file.
    if (!UnlinkFile(dex_file) || !UnlinkFile(profile_file) || !UnlinkFile(output_dex)) {
      return false;
    }
    return true;
  }

  // Runs DexFileLayout test twice (second time is run on output of first time)
  // for behavior consistency.
  bool DexFileLayoutFixedPointExec(std::string* error_msg) {
    ScratchFile tmp_file;
    const std::string& tmp_name = tmp_file.GetFilename();
    size_t tmp_last_slash = tmp_name.rfind('/');
    std::string tmp_dir = tmp_name.substr(0, tmp_last_slash + 1);

    // Unzip the test dex file to the classes.dex destination. It is required to unzip since
    // opening from jar recalculates the dex location checksum.
    std::string dex_file = tmp_dir + "classes.dex";

    std::vector<std::string> unzip_args = {
        "/usr/bin/unzip",
        GetTestDexFileName("ManyMethods"),
        "classes.dex",
        "-d",
        tmp_dir,
    };
    if (!art::Exec(unzip_args, error_msg)) {
      LOG(ERROR) << "Failed to unzip dex";
      return false;
    }

    std::string profile_file = tmp_dir + "primary.prof";
    CreateProfile(dex_file, profile_file);
    std::string output_dex = tmp_dir + "classes.dex.new";
    std::string second_output_dex = tmp_dir + "classes.dex.new.new";

    // -v makes sure that the layout did not corrupt the dex file.
    std::vector<std::string> dexlayout_args =
        { "-v", "-w", tmp_dir, "-o", tmp_name, "-p", profile_file, dex_file };
    if (!DexLayoutExec(dexlayout_args, error_msg, /*pass_default_cdex_option=*/ false)) {
      return false;
    }

    // Recreate the profile with the new dex location. This is required so that the profile dex
    // location matches.
    CreateProfile(output_dex, profile_file);
    // -v makes sure that the layout did not corrupt the dex file.
    // -i since the checksum won't match from the first layout.
    std::vector<std::string> second_dexlayout_args =
        { "-i", "-v", "-w", tmp_dir, "-o", tmp_name, "-p", profile_file, output_dex };
    if (!DexLayoutExec(second_dexlayout_args, error_msg, /*pass_default_cdex_option=*/ false)) {
      return false;
    }

    bool diff_result = true;
    std::vector<std::string> diff_exec_argv =
        { "/usr/bin/diff", output_dex, second_output_dex };
    if (!::art::Exec(diff_exec_argv, error_msg)) {
      diff_result = false;
    }

    std::vector<std::string> test_files = { dex_file, profile_file, output_dex, second_output_dex };
    for (const std::string& test_file : test_files) {
      if (!UnlinkFile(test_file)) {
        return false;
      }
    }

    return diff_result;
  }

  // Runs UnreferencedCatchHandlerTest & Unreferenced0SizeCatchHandlerTest.
  bool UnreferencedCatchHandlerExec(std::string* error_msg, const char* filename) {
    ScratchFile tmp_file;
    const std::string& tmp_name = tmp_file.GetFilename();
    size_t tmp_last_slash = tmp_name.rfind('/');
    std::string tmp_dir = tmp_name.substr(0, tmp_last_slash + 1);

    // Write inputs and expected outputs.
    std::string input_dex = tmp_dir + "classes.dex";
    WriteFileBase64(filename, input_dex.c_str());
    std::string output_dex = tmp_dir + "classes.dex.new";

    std::vector<std::string> dexlayout_args = { "-w", tmp_dir, "-o", "/dev/null", input_dex };
    if (!DexLayoutExec(dexlayout_args, error_msg, /*pass_default_cdex_option=*/ false)) {
      return false;
    }

    // Diff input and output. They should be the same.
    std::vector<std::string> diff_exec_argv = { "/usr/bin/diff", input_dex, output_dex };
    if (!::art::Exec(diff_exec_argv, error_msg)) {
      return false;
    }

    std::vector<std::string> dex_files = { input_dex, output_dex };
    for (const std::string& dex_file : dex_files) {
      if (!UnlinkFile(dex_file)) {
        return false;
      }
    }
    return true;
  }

  bool DexLayoutExec(ScratchFile* dex_file,
                     const char* dex_filename,
                     ScratchFile* profile_file,
                     const std::vector<std::string>& dexlayout_args) {
    if (dex_filename != nullptr) {
      WriteBase64ToFile(dex_filename, dex_file->GetFile());
      EXPECT_EQ(dex_file->GetFile()->Flush(), 0);
    }
    if (profile_file != nullptr) {
      CreateProfile(dex_file->GetFilename(), profile_file->GetFilename());
    }

    std::string error_msg;
    const bool result = DexLayoutExec(dexlayout_args, &error_msg);
    if (!result) {
      LOG(ERROR) << "Error: " << error_msg;
      return false;
    }
    return true;
  }

  bool DexLayoutExec(const std::vector<std::string>& dexlayout_args,
                     std::string* error_msg,
                     bool pass_default_cdex_option = true) {
    std::vector<std::string> argv;

    std::string dexlayout = GetDexLayoutPath();
    CHECK(OS::FileExists(dexlayout.c_str())) << dexlayout << " should be a valid file path";
    argv.push_back(dexlayout);
    if (pass_default_cdex_option) {
      std::vector<std::string> cdex_level = DefaultCompactDexOption();
      argv.insert(argv.end(), cdex_level.begin(), cdex_level.end());
    }

    argv.insert(argv.end(), dexlayout_args.begin(), dexlayout_args.end());

    return ::art::Exec(argv, error_msg);
  }

  bool UnlinkFile(const std::string& file_path) {
    return unix_file::FdFile(file_path, 0, false).Unlink();
  }
};


TEST_F(DexLayoutTest, FullPlainOutput) {
  // Disable test on target.
  TEST_DISABLED_FOR_TARGET();
  std::string error_msg;
  ASSERT_TRUE(FullPlainOutputExec(&error_msg)) << error_msg;
}

TEST_F(DexLayoutTest, DexFileOutput) {
  // Disable test on target.
  TEST_DISABLED_FOR_TARGET();
  std::string error_msg;
  ASSERT_TRUE(DexFileOutputExec(&error_msg)) << error_msg;
}

TEST_F(DexLayoutTest, DexFileLayout) {
  // Disable test on target.
  TEST_DISABLED_FOR_TARGET();
  std::string error_msg;
  ASSERT_TRUE(DexFileLayoutExec(&error_msg)) << error_msg;
}

TEST_F(DexLayoutTest, DexFileLayoutFixedPoint) {
  // Disable test on target.
  TEST_DISABLED_FOR_TARGET();
  std::string error_msg;
  ASSERT_TRUE(DexFileLayoutFixedPointExec(&error_msg)) << error_msg;
}

TEST_F(DexLayoutTest, UnreferencedCatchHandler) {
  // Disable test on target.
  TEST_DISABLED_FOR_TARGET();
  std::string error_msg;
  ASSERT_TRUE(UnreferencedCatchHandlerExec(&error_msg,
                                           kUnreferencedCatchHandlerInputDex)) << error_msg;
}

TEST_F(DexLayoutTest, Unreferenced0SizeCatchHandler) {
  // Disable test on target.
  TEST_DISABLED_FOR_TARGET();
  std::string error_msg;
  ASSERT_TRUE(UnreferencedCatchHandlerExec(&error_msg,
                                           kUnreferenced0SizeCatchHandlerInputDex)) << error_msg;
}

TEST_F(DexLayoutTest, UnreferencedEndingCatchHandler) {
  // Disable test on target.
  TEST_DISABLED_FOR_TARGET();
  std::string error_msg;
  ASSERT_TRUE(UnreferencedCatchHandlerExec(&error_msg,
                                           kUnreferencedEndingCatchHandlerInputDex)) << error_msg;
}

TEST_F(DexLayoutTest, DuplicateOffset) {
  ScratchFile temp_dex;
  std::vector<std::string> dexlayout_args =
      { "-a", "-i", "-o", "/dev/null", temp_dex.GetFilename() };
  ASSERT_TRUE(DexLayoutExec(&temp_dex,
                            kDexFileDuplicateOffset,
                            /* profile_file= */ nullptr,
                            dexlayout_args));
}

TEST_F(DexLayoutTest, NullSetRefListElement) {
  ScratchFile temp_dex;
  std::vector<std::string> dexlayout_args = { "-o", "/dev/null", temp_dex.GetFilename() };
  ASSERT_TRUE(DexLayoutExec(&temp_dex,
                            kNullSetRefListElementInputDex,
                            /* profile_file= */ nullptr,
                            dexlayout_args));
}

TEST_F(DexLayoutTest, MultiClassData) {
  ScratchFile temp_dex;
  ScratchFile temp_profile;
  std::vector<std::string> dexlayout_args =
      { "-p", temp_profile.GetFilename(), "-o", "/dev/null", temp_dex.GetFilename() };
  ASSERT_TRUE(DexLayoutExec(&temp_dex,
                            kMultiClassDataInputDex,
                            &temp_profile,
                            dexlayout_args));
}

TEST_F(DexLayoutTest, UnalignedCodeInfo) {
  ScratchFile temp_dex;
  ScratchFile temp_profile;
  std::vector<std::string> dexlayout_args =
      { "-p", temp_profile.GetFilename(), "-o", "/dev/null", temp_dex.GetFilename() };
  ASSERT_TRUE(DexLayoutExec(&temp_dex,
                            kUnalignedCodeInfoInputDex,
                            &temp_profile,
                            dexlayout_args));
}

TEST_F(DexLayoutTest, ClassDataBeforeCode) {
  ScratchFile temp_dex;
  ScratchFile temp_profile;
  std::vector<std::string> dexlayout_args =
      { "-p", temp_profile.GetFilename(), "-o", "/dev/null", temp_dex.GetFilename() };
  ASSERT_TRUE(DexLayoutExec(&temp_dex,
                            kClassDataBeforeCodeInputDex,
                            &temp_profile,
                            dexlayout_args));
}

TEST_F(DexLayoutTest, UnknownTypeDebugInfo) {
  ScratchFile temp_dex;
  std::vector<std::string> dexlayout_args = { "-o", "/dev/null", temp_dex.GetFilename() };
  ASSERT_TRUE(DexLayoutExec(&temp_dex,
                            kUnknownTypeDebugInfoInputDex,
                            /* profile_file= */ nullptr,
                            dexlayout_args));
}

TEST_F(DexLayoutTest, DuplicateCodeItem) {
  ScratchFile temp_dex;
  std::vector<std::string> dexlayout_args = { "-o", "/dev/null", temp_dex.GetFilename() };
  ASSERT_TRUE(DexLayoutExec(&temp_dex,
                            kDuplicateCodeItemInputDex,
                            /* profile_file= */ nullptr,
                            dexlayout_args));
}

// Test that instructions that go past the end of the code items don't cause crashes.
TEST_F(DexLayoutTest, CodeItemOverrun) {
  ScratchFile temp_dex;
  MutateDexFile(temp_dex.GetFile(), GetTestDexFileName("ManyMethods"), [] (DexFile* dex) {
    bool mutated_successfully = false;
    // Change the dex instructions to make an opcode that spans past the end of the code item.
    for (ClassAccessor accessor : dex->GetClasses()) {
      for (const ClassAccessor::Method& method : accessor.GetMethods()) {
        dex::CodeItem* item = const_cast<dex::CodeItem*>(method.GetCodeItem());
        if (item != nullptr) {
          CodeItemInstructionAccessor instructions(*dex, item);
          if (instructions.begin() != instructions.end()) {
            DexInstructionIterator last_instruction = instructions.begin();
            for (auto dex_it = instructions.begin(); dex_it != instructions.end(); ++dex_it) {
              last_instruction = dex_it;
            }
            if (last_instruction->SizeInCodeUnits() == 1) {
              // Set the opcode to something that will go past the end of the code item.
              const_cast<Instruction&>(last_instruction.Inst()).SetOpcode(
                  Instruction::CONST_STRING_JUMBO);
              mutated_successfully = true;
              // Test that the safe iterator doesn't go past the end.
              SafeDexInstructionIterator it2(instructions.begin(), instructions.end());
              while (!it2.IsErrorState()) {
                ++it2;
              }
              EXPECT_TRUE(it2 == last_instruction);
              EXPECT_TRUE(it2 < instructions.end());
            }
          }
        }
      }
    }
    CHECK(mutated_successfully)
        << "Failed to find candidate code item with only one code unit in last instruction.";
  });

  std::string error_msg;

  ScratchFile tmp_file;
  const std::string& tmp_name = tmp_file.GetFilename();
  size_t tmp_last_slash = tmp_name.rfind('/');
  std::string tmp_dir = tmp_name.substr(0, tmp_last_slash + 1);
  ScratchFile profile_file;

  std::vector<std::string> dexlayout_args =
      { "-i",
        "-v",
        "-w", tmp_dir,
        "-o", tmp_name,
        "-p", profile_file.GetFilename(),
        temp_dex.GetFilename()
      };
  // -v makes sure that the layout did not corrupt the dex file.
  ASSERT_TRUE(DexLayoutExec(&temp_dex,
                            /*dex_filename=*/ nullptr,
                            &profile_file,
                            dexlayout_args));
  ASSERT_TRUE(UnlinkFile(temp_dex.GetFilename() + ".new"));
}

// Test that link data is written out (or at least the header is updated).
TEST_F(DexLayoutTest, LinkData) {
  TEST_DISABLED_FOR_TARGET();
  ScratchFile temp_dex;
  size_t file_size = 0;
  MutateDexFile(temp_dex.GetFile(), GetTestDexFileName("ManyMethods"), [&] (DexFile* dex) {
    DexFile::Header& header = const_cast<DexFile::Header&>(dex->GetHeader());
    header.link_off_ = header.file_size_;
    header.link_size_ = 16 * KB;
    header.file_size_ += header.link_size_;
    file_size = header.file_size_;
  });
  TEMP_FAILURE_RETRY(temp_dex.GetFile()->SetLength(file_size));

  std::string error_msg;

  ScratchFile tmp_file;
  const std::string& tmp_name = tmp_file.GetFilename();
  size_t tmp_last_slash = tmp_name.rfind('/');
  std::string tmp_dir = tmp_name.substr(0, tmp_last_slash + 1);
  ScratchFile profile_file;

  std::vector<std::string> dexlayout_args =
      { "-i",
        "-v",
        "-w", tmp_dir,
        "-o", tmp_name,
        "-p", profile_file.GetFilename(),
        temp_dex.GetFilename()
      };
  // -v makes sure that the layout did not corrupt the dex file.
  ASSERT_TRUE(DexLayoutExec(&temp_dex,
                            /*dex_filename=*/ nullptr,
                            &profile_file,
                            dexlayout_args));
  ASSERT_TRUE(UnlinkFile(temp_dex.GetFilename() + ".new"));
}

TEST_F(DexLayoutTest, ClassFilter) {
  std::vector<std::unique_ptr<const DexFile>> dex_files;
  std::string error_msg;
  const ArtDexFileLoader dex_file_loader;
  const std::string input_jar = GetTestDexFileName("ManyMethods");
  CHECK(dex_file_loader.Open(input_jar.c_str(),
                             input_jar.c_str(),
                             /*verify=*/ true,
                             /*verify_checksum=*/ true,
                             &error_msg,
                             &dex_files)) << error_msg;
  ASSERT_EQ(dex_files.size(), 1u);
  for (const std::unique_ptr<const DexFile>& dex_file : dex_files) {
    EXPECT_GT(dex_file->NumClassDefs(), 1u);
    for (uint32_t i = 0; i < dex_file->NumClassDefs(); ++i) {
      const dex::ClassDef& class_def = dex_file->GetClassDef(i);
      LOG(INFO) << dex_file->GetClassDescriptor(class_def);
    }
    Options options;
    // Filter out all the classes other than the one below based on class descriptor.
    options.class_filter_.insert("LManyMethods$Strings;");
    DexLayout dexlayout(options,
                        /*info=*/ nullptr,
                        /*out_file=*/ nullptr,
                        /*header=*/ nullptr);
    std::unique_ptr<DexContainer> out;
    bool result = dexlayout.ProcessDexFile(
        dex_file->GetLocation().c_str(),
        dex_file.get(),
        /*dex_file_index=*/ 0,
        &out,
        &error_msg);
    ASSERT_TRUE(result) << "Failed to run dexlayout " << error_msg;
    std::unique_ptr<const DexFile> output_dex_file(
        dex_file_loader.OpenWithDataSection(
            out->GetMainSection()->Begin(),
            out->GetMainSection()->Size(),
            out->GetDataSection()->Begin(),
            out->GetDataSection()->Size(),
            dex_file->GetLocation().c_str(),
            /* location_checksum= */ 0,
            /*oat_dex_file=*/ nullptr,
            /* verify= */ true,
            /*verify_checksum=*/ false,
            &error_msg));
    ASSERT_TRUE(output_dex_file != nullptr);

    ASSERT_EQ(output_dex_file->NumClassDefs(), options.class_filter_.size());
    for (uint32_t i = 0; i < output_dex_file->NumClassDefs(); ++i) {
      // Check that every class in the output dex file is in the filter.
      const dex::ClassDef& class_def = output_dex_file->GetClassDef(i);
      ASSERT_TRUE(options.class_filter_.find(output_dex_file->GetClassDescriptor(class_def)) !=
          options.class_filter_.end());
    }
  }
}

}  // namespace art
