/*
 * 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 "dexlayout.h"

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

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

#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 "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.
static std::vector<std::string> DefaultCompactDexOption() { return {"-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;
    ArtDexFileLoader dex_file_loader(input_dex);
    bool result = dex_file_loader.Open(/*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) {
  // TODO(b/256664509): Clean this up.
  GTEST_SKIP() << "Compact dex is disabled";
#if 0
  // Disable test on target.
  TEST_DISABLED_FOR_TARGET();
  std::string error_msg;
  ASSERT_TRUE(FullPlainOutputExec(&error_msg)) << error_msg;
#endif
}

TEST_F(DexLayoutTest, DexFileOutput) {
  // TODO(b/256664509): Clean this up.
  GTEST_SKIP() << "Compact dex is disabled";
#if 0
  // Disable test on target.
  TEST_DISABLED_FOR_TARGET();
  std::string error_msg;
  ASSERT_TRUE(DexFileOutputExec(&error_msg)) << error_msg;
#endif
}

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 std::string input_jar = GetTestDexFileName("ManyMethods");
  {
    ArtDexFileLoader dex_file_loader(input_jar);
    CHECK(dex_file_loader.Open(/*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;
    auto container = std::make_unique<DexLoaderContainer>(out->GetMainSection()->Begin(),
                                                          out->GetMainSection()->End(),
                                                          out->GetDataSection()->Begin(),
                                                          out->GetDataSection()->End());
    ArtDexFileLoader dex_file_loader(std::move(container), dex_file->GetLocation());
    std::unique_ptr<const DexFile> output_dex_file(dex_file_loader.Open(/* 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
