/*
 * Copyright (C) 2017 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 <openssl/sha.h>
#include <dirent.h>
#include <sys/types.h>

#include <string>
#include <vector>

#include "android-base/stringprintf.h"
#include "android-base/strings.h"

#include "dexopt_test.h"
#include "leb128.h"
#include "runtime.h"

#include <gtest/gtest.h>

namespace art {

using android::base::StringPrintf;

class PatchoatTest : public DexoptTest {
 public:
  static bool ListDirFilesEndingWith(
      const std::string& dir,
      const std::string& suffix,
      std::vector<std::string>* filenames,
      std::string* error_msg) {
    DIR* d = opendir(dir.c_str());
    if (d == nullptr) {
      *error_msg = "Failed to open directory";
      return false;
    }
    dirent* e;
    struct stat s;
    size_t suffix_len = suffix.size();
    while ((e = readdir(d)) != nullptr) {
      if ((strcmp(e->d_name, ".") == 0) || (strcmp(e->d_name, "..") == 0)) {
        continue;
      }
      size_t name_len = strlen(e->d_name);
      if ((name_len < suffix_len) || (strcmp(&e->d_name[name_len - suffix_len], suffix.c_str()))) {
        continue;
      }
      std::string basename(e->d_name);
      std::string filename = dir + "/" + basename;
      int stat_result = lstat(filename.c_str(), &s);
      if (stat_result != 0) {
        *error_msg =
            StringPrintf("Failed to stat %s: stat returned %d", filename.c_str(), stat_result);
        return false;
      }
      if (S_ISDIR(s.st_mode)) {
        continue;
      }
      filenames->push_back(basename);
    }
    closedir(d);
    return true;
  }

  static void AddRuntimeArg(std::vector<std::string>& args, const std::string& arg) {
    args.push_back("--runtime-arg");
    args.push_back(arg);
  }

  bool CompileBootImage(const std::vector<std::string>& extra_args,
                        const std::string& image_file_name_prefix,
                        uint32_t base_addr,
                        std::string* error_msg) {
    Runtime* const runtime = Runtime::Current();
    std::vector<std::string> argv;
    argv.push_back(runtime->GetCompilerExecutable());
    AddRuntimeArg(argv, "-Xms64m");
    AddRuntimeArg(argv, "-Xmx64m");
    std::vector<std::string> dex_files = GetLibCoreDexFileNames();
    for (const std::string& dex_file : dex_files) {
      argv.push_back("--dex-file=" + dex_file);
      argv.push_back("--dex-location=" + dex_file);
    }
    if (runtime->IsJavaDebuggable()) {
      argv.push_back("--debuggable");
    }
    runtime->AddCurrentRuntimeFeaturesAsDex2OatArguments(&argv);

    AddRuntimeArg(argv, "-Xverify:softfail");

    if (!kIsTargetBuild) {
      argv.push_back("--host");
    }

    argv.push_back("--image=" + image_file_name_prefix + ".art");
    argv.push_back("--oat-file=" + image_file_name_prefix + ".oat");
    argv.push_back("--oat-location=" + image_file_name_prefix + ".oat");
    argv.push_back(StringPrintf("--base=0x%" PRIx32, base_addr));
    argv.push_back("--compile-pic");
    argv.push_back("--multi-image");
    argv.push_back("--no-generate-debug-info");

    std::vector<std::string> compiler_options = runtime->GetCompilerOptions();
    argv.insert(argv.end(), compiler_options.begin(), compiler_options.end());

    // We must set --android-root.
    const char* android_root = getenv("ANDROID_ROOT");
    CHECK(android_root != nullptr);
    argv.push_back("--android-root=" + std::string(android_root));
    argv.insert(argv.end(), extra_args.begin(), extra_args.end());

    return RunDex2OatOrPatchoat(argv, error_msg);
  }

  static std::vector<std::string> BasePatchoatCommand(const std::string& input_image_location,
                                                      off_t base_offset_delta) {
    Runtime* const runtime = Runtime::Current();
    std::vector<std::string> argv;
    argv.push_back(runtime->GetPatchoatExecutable());
    argv.push_back("--input-image-location=" + input_image_location);
    argv.push_back(StringPrintf("--base-offset-delta=0x%jx", (intmax_t) base_offset_delta));
    argv.push_back(StringPrintf("--instruction-set=%s", GetInstructionSetString(kRuntimeISA)));

    return argv;
  }

  bool RelocateBootImage(const std::string& input_image_location,
                         const std::string& output_image_filename,
                         off_t base_offset_delta,
                         std::string* error_msg) {
    std::vector<std::string> argv = BasePatchoatCommand(input_image_location, base_offset_delta);
    argv.push_back("--output-image-file=" + output_image_filename);

    return RunDex2OatOrPatchoat(argv, error_msg);
  }

  bool VerifyBootImage(const std::string& input_image_location,
                       const std::string& output_image_filename,
                       off_t base_offset_delta,
                       std::string* error_msg) {
    std::vector<std::string> argv = BasePatchoatCommand(input_image_location, base_offset_delta);
    argv.push_back("--output-image-file=" + output_image_filename);
    argv.push_back("--verify");

    return RunDex2OatOrPatchoat(argv, error_msg);
  }

  bool GenerateBootImageRelFile(const std::string& input_image_location,
                                const std::string& output_rel_filename,
                                off_t base_offset_delta,
                                std::string* error_msg) {
    std::vector<std::string> argv = BasePatchoatCommand(input_image_location, base_offset_delta);
    argv.push_back("--output-image-relocation-file=" + output_rel_filename);

    return RunDex2OatOrPatchoat(argv, error_msg);
  }

  bool RunDex2OatOrPatchoat(const std::vector<std::string>& args, std::string* error_msg) {
    int link[2];

    if (pipe(link) == -1) {
      return false;
    }

    pid_t pid = fork();
    if (pid == -1) {
      return false;
    }

    if (pid == 0) {
      // We need dex2oat to actually log things.
      setenv("ANDROID_LOG_TAGS", "*:e", 1);
      dup2(link[1], STDERR_FILENO);
      close(link[0]);
      close(link[1]);
      std::vector<const char*> c_args;
      for (const std::string& str : args) {
        c_args.push_back(str.c_str());
      }
      c_args.push_back(nullptr);
      execv(c_args[0], const_cast<char* const*>(c_args.data()));
      exit(1);
      UNREACHABLE();
    } else {
      close(link[1]);
      char buffer[128];
      memset(buffer, 0, 128);
      ssize_t bytes_read = 0;

      while (TEMP_FAILURE_RETRY(bytes_read = read(link[0], buffer, 128)) > 0) {
        *error_msg += std::string(buffer, bytes_read);
      }
      close(link[0]);
      int status = -1;
      if (waitpid(pid, &status, 0) != -1) {
        return (status == 0);
      }
      return false;
    }
  }

  bool CompileBootImageToDir(
      const std::string& output_dir,
      const std::vector<std::string>& dex2oat_extra_args,
      uint32_t base_addr,
      std::string* error_msg) {
    return CompileBootImage(dex2oat_extra_args, output_dir + "/boot", base_addr, error_msg);
  }

  bool CopyImageChecksumAndSetPatchDelta(
      const std::string& src_image_filename,
      const std::string& dest_image_filename,
      off_t dest_patch_delta,
      std::string* error_msg) {
    std::unique_ptr<File> src_file(OS::OpenFileForReading(src_image_filename.c_str()));
    if (src_file.get() == nullptr) {
      *error_msg = StringPrintf("Failed to open source image file %s", src_image_filename.c_str());
      return false;
    }
    ImageHeader src_header;
    if (!src_file->ReadFully(&src_header, sizeof(src_header))) {
      *error_msg = StringPrintf("Failed to read source image file %s", src_image_filename.c_str());
      return false;
    }

    std::unique_ptr<File> dest_file(OS::OpenFileReadWrite(dest_image_filename.c_str()));
    if (dest_file.get() == nullptr) {
      *error_msg =
          StringPrintf("Failed to open destination image file %s", dest_image_filename.c_str());
      return false;
    }
    ImageHeader dest_header;
    if (!dest_file->ReadFully(&dest_header, sizeof(dest_header))) {
      *error_msg =
          StringPrintf("Failed to read destination image file %s", dest_image_filename.c_str());
      return false;
    }
    dest_header.SetOatChecksum(src_header.GetOatChecksum());
    dest_header.SetPatchDelta(dest_patch_delta);
    if (!dest_file->ResetOffset()) {
      *error_msg =
          StringPrintf(
              "Failed to seek to start of destination image file %s", dest_image_filename.c_str());
      return false;
    }
    if (!dest_file->WriteFully(&dest_header, sizeof(dest_header))) {
      *error_msg =
          StringPrintf("Failed to write to destination image file %s", dest_image_filename.c_str());
      dest_file->Erase();
      return false;
    }
    if (dest_file->FlushCloseOrErase() != 0) {
      *error_msg =
          StringPrintf(
              "Failed to flush/close destination image file %s", dest_image_filename.c_str());
      return false;
    }

    return true;
  }

  bool ReadFully(
      const std::string& filename, std::vector<uint8_t>* contents, std::string* error_msg) {
    std::unique_ptr<File> file(OS::OpenFileForReading(filename.c_str()));
    if (file.get() == nullptr) {
      *error_msg = "Failed to open";
      return false;
    }
    int64_t size = file->GetLength();
    if (size < 0) {
      *error_msg = "Failed to get size";
      return false;
    }
    contents->resize(size);
    if (!file->ReadFully(&(*contents)[0], size)) {
      *error_msg = "Failed to read";
      contents->clear();
      return false;
    }
    return true;
  }

  bool BinaryDiff(
      const std::string& filename1, const std::string& filename2, std::string* error_msg) {
    std::string read_error_msg;
    std::vector<uint8_t> image1;
    if (!ReadFully(filename1, &image1, &read_error_msg)) {
      *error_msg = StringPrintf("Failed to read %s: %s", filename1.c_str(), read_error_msg.c_str());
      return true;
    }
    std::vector<uint8_t> image2;
    if (!ReadFully(filename2, &image2, &read_error_msg)) {
      *error_msg = StringPrintf("Failed to read %s: %s", filename2.c_str(), read_error_msg.c_str());
      return true;
    }
    if (image1.size() != image1.size()) {
      *error_msg =
          StringPrintf(
              "%s and %s are of different size: %zu vs %zu",
              filename1.c_str(),
              filename2.c_str(),
              image1.size(),
              image2.size());
      return true;
    }
    size_t size = image1.size();
    for (size_t i = 0; i < size; i++) {
      if (image1[i] != image2[i]) {
        *error_msg =
            StringPrintf("%s and %s differ at offset %zu", filename1.c_str(), filename2.c_str(), i);
        return true;
      }
    }

    return false;
  }
};

TEST_F(PatchoatTest, PatchoatRelocationSameAsDex2oatRelocation) {
#if defined(ART_USE_READ_BARRIER)
  // This test checks that relocating a boot image using patchoat produces the same result as
  // producing the boot image for that relocated base address using dex2oat. To be precise, these
  // two files will have two small differences: the OAT checksum and base address. However, this
  // test takes this into account.

  // Compile boot image into a random directory using dex2oat
  ScratchFile dex2oat_orig_scratch;
  dex2oat_orig_scratch.Unlink();
  std::string dex2oat_orig_dir = dex2oat_orig_scratch.GetFilename();
  ASSERT_EQ(0, mkdir(dex2oat_orig_dir.c_str(), 0700));
  const uint32_t orig_base_addr = 0x60000000;
  // Force deterministic output. We want the boot images created by this dex2oat run and the run
  // below to differ only in their base address.
  std::vector<std::string> dex2oat_extra_args;
  dex2oat_extra_args.push_back("--force-determinism");
  dex2oat_extra_args.push_back("-j1");  // Might not be needed. Causes a 3-5x slowdown.
  std::string error_msg;
  if (!CompileBootImageToDir(dex2oat_orig_dir, dex2oat_extra_args, orig_base_addr, &error_msg)) {
    FAIL() << "CompileBootImage1 failed: " << error_msg;
  }

  // Compile a "relocated" boot image into a random directory using dex2oat. This image is relocated
  // in the sense that it uses a different base address.
  ScratchFile dex2oat_reloc_scratch;
  dex2oat_reloc_scratch.Unlink();
  std::string dex2oat_reloc_dir = dex2oat_reloc_scratch.GetFilename();
  ASSERT_EQ(0, mkdir(dex2oat_reloc_dir.c_str(), 0700));
  const uint32_t reloc_base_addr = 0x70000000;
  if (!CompileBootImageToDir(dex2oat_reloc_dir, dex2oat_extra_args, reloc_base_addr, &error_msg)) {
    FAIL() << "CompileBootImage2 failed: " << error_msg;
  }
  const off_t base_addr_delta = reloc_base_addr - orig_base_addr;

  // Relocate the original boot image using patchoat. The image is relocated by the same amount
  // as the second/relocated image produced by dex2oat.
  ScratchFile patchoat_scratch;
  patchoat_scratch.Unlink();
  std::string patchoat_dir = patchoat_scratch.GetFilename();
  ASSERT_EQ(0, mkdir(patchoat_dir.c_str(), 0700));
  std::string dex2oat_orig_with_arch_dir =
      dex2oat_orig_dir + "/" + GetInstructionSetString(kRuntimeISA);
  // The arch-including symlink is needed by patchoat
  ASSERT_EQ(0, symlink(dex2oat_orig_dir.c_str(), dex2oat_orig_with_arch_dir.c_str()));
  if (!RelocateBootImage(
      dex2oat_orig_dir + "/boot.art",
      patchoat_dir + "/boot.art",
      base_addr_delta,
      &error_msg)) {
    FAIL() << "RelocateBootImage failed: " << error_msg;
  }

  // Assert that patchoat created the same set of .art files as dex2oat
  std::vector<std::string> dex2oat_image_basenames;
  std::vector<std::string> patchoat_image_basenames;
  if (!ListDirFilesEndingWith(dex2oat_reloc_dir, ".art", &dex2oat_image_basenames, &error_msg)) {
    FAIL() << "Failed to list *.art files in " << dex2oat_reloc_dir << ": " << error_msg;
  }
  if (!ListDirFilesEndingWith(patchoat_dir, ".art", &patchoat_image_basenames, &error_msg)) {
    FAIL() << "Failed to list *.art files in " << patchoat_dir << ": " << error_msg;
  }
  std::sort(dex2oat_image_basenames.begin(), dex2oat_image_basenames.end());
  std::sort(patchoat_image_basenames.begin(), patchoat_image_basenames.end());
  // .art file names output by patchoat look like tmp@art-data-<random>-<random>@boot*.art. To
  // compare these with .art file names output by dex2oat we retain only the part of the file name
  // after the last @.
  std::vector<std::string> patchoat_image_shortened_basenames(patchoat_image_basenames.size());
  for (size_t i = 0; i < patchoat_image_basenames.size(); i++) {
    patchoat_image_shortened_basenames[i] =
        patchoat_image_basenames[i].substr(patchoat_image_basenames[i].find_last_of("@") + 1);
  }
  ASSERT_EQ(dex2oat_image_basenames, patchoat_image_shortened_basenames);

  // Patch up the dex2oat-relocated image files so that it looks as though they were relocated by
  // patchoat. patchoat preserves the OAT checksum header field and sets patch delta header field.
  for (const std::string& image_basename : dex2oat_image_basenames) {
    if (!CopyImageChecksumAndSetPatchDelta(
        dex2oat_orig_dir + "/" + image_basename,
        dex2oat_reloc_dir + "/" + image_basename,
        base_addr_delta,
        &error_msg)) {
      FAIL() << "Unable to patch up " << image_basename << ": " << error_msg;
    }
  }

  // Assert that the patchoat-relocated images are identical to the dex2oat-relocated images
  for (size_t i = 0; i < dex2oat_image_basenames.size(); i++) {
    const std::string& dex2oat_image_basename = dex2oat_image_basenames[i];
    const std::string& dex2oat_image_filename = dex2oat_reloc_dir + "/" + dex2oat_image_basename;
    const std::string& patchoat_image_filename = patchoat_dir + "/" + patchoat_image_basenames[i];
    if (BinaryDiff(dex2oat_image_filename, patchoat_image_filename, &error_msg)) {
      FAIL() << "patchoat- and dex2oat-relocated variants of " << dex2oat_image_basename
          << " differ: " << error_msg;
    }
  }

  ClearDirectory(dex2oat_orig_dir.c_str(), /*recursive*/ true);
  ClearDirectory(dex2oat_reloc_dir.c_str(), /*recursive*/ true);
  ClearDirectory(patchoat_dir.c_str(), /*recursive*/ true);
  rmdir(dex2oat_orig_dir.c_str());
  rmdir(dex2oat_reloc_dir.c_str());
  rmdir(patchoat_dir.c_str());
#else
  LOG(INFO) << "Skipping PatchoatRelocationSameAsDex2oatRelocation";
  // Force-print to std::cout so it's also outside the logcat.
  std::cout << "Skipping PatchoatRelocationSameAsDex2oatRelocation" << std::endl;
#endif
}

TEST_F(PatchoatTest, RelFileVerification) {
  // This test checks that a boot image relocated using patchoat can be unrelocated using the .rel
  // file created by patchoat.

  // This test doesn't work when heap poisoning is enabled because some of the
  // references are negated. b/72117833 is tracking the effort to have patchoat
  // and its tests support heap poisoning.
  TEST_DISABLED_FOR_HEAP_POISONING();

  // Compile boot image into a random directory using dex2oat
  ScratchFile dex2oat_orig_scratch;
  dex2oat_orig_scratch.Unlink();
  std::string dex2oat_orig_dir = dex2oat_orig_scratch.GetFilename();
  ASSERT_EQ(0, mkdir(dex2oat_orig_dir.c_str(), 0700));
  const uint32_t orig_base_addr = 0x60000000;
  std::vector<std::string> dex2oat_extra_args;
  std::string error_msg;
  if (!CompileBootImageToDir(dex2oat_orig_dir, dex2oat_extra_args, orig_base_addr, &error_msg)) {
    FAIL() << "CompileBootImage1 failed: " << error_msg;
  }

  // Generate image relocation file for the original boot image
  std::string dex2oat_orig_with_arch_dir =
      dex2oat_orig_dir + "/" + GetInstructionSetString(kRuntimeISA);
  // The arch-including symlink is needed by patchoat
  ASSERT_EQ(0, symlink(dex2oat_orig_dir.c_str(), dex2oat_orig_with_arch_dir.c_str()));
  off_t base_addr_delta = 0x100000;
  if (!GenerateBootImageRelFile(
      dex2oat_orig_dir + "/boot.art",
      dex2oat_orig_dir + "/boot.art.rel",
      base_addr_delta,
      &error_msg)) {
    FAIL() << "RelocateBootImage failed: " << error_msg;
  }

  // Relocate the original boot image using patchoat
  ScratchFile relocated_scratch;
  relocated_scratch.Unlink();
  std::string relocated_dir = relocated_scratch.GetFilename();
  ASSERT_EQ(0, mkdir(relocated_dir.c_str(), 0700));
  // Use a different relocation delta from the one used when generating .rel files above. This is
  // to make sure .rel files are not specific to a particular relocation delta.
  base_addr_delta -= 0x10000;
  if (!RelocateBootImage(
      dex2oat_orig_dir + "/boot.art",
      relocated_dir + "/boot.art",
      base_addr_delta,
      &error_msg)) {
    FAIL() << "RelocateBootImage failed: " << error_msg;
  }

  // Assert that patchoat created the same set of .art and .art.rel files
  std::vector<std::string> rel_basenames;
  std::vector<std::string> relocated_image_basenames;
  if (!ListDirFilesEndingWith(dex2oat_orig_dir, ".rel", &rel_basenames, &error_msg)) {
    FAIL() << "Failed to list *.art.rel files in " << dex2oat_orig_dir << ": " << error_msg;
  }
  if (!ListDirFilesEndingWith(relocated_dir, ".art", &relocated_image_basenames, &error_msg)) {
    FAIL() << "Failed to list *.art files in " << relocated_dir << ": " << error_msg;
  }
  std::sort(rel_basenames.begin(), rel_basenames.end());
  std::sort(relocated_image_basenames.begin(), relocated_image_basenames.end());

  // .art and .art.rel file names output by patchoat look like
  // tmp@art-data-<random>-<random>@boot*.art, encoding the name of the directory in their name.
  // To compare these with each other, we retain only the part of the file name after the last @,
  // and we also drop the extension.
  std::vector<std::string> rel_shortened_basenames(rel_basenames.size());
  std::vector<std::string> relocated_image_shortened_basenames(relocated_image_basenames.size());
  for (size_t i = 0; i < rel_basenames.size(); i++) {
    rel_shortened_basenames[i] = rel_basenames[i].substr(rel_basenames[i].find_last_of("@") + 1);
    rel_shortened_basenames[i] =
        rel_shortened_basenames[i].substr(0, rel_shortened_basenames[i].find("."));
  }
  for (size_t i = 0; i < relocated_image_basenames.size(); i++) {
    relocated_image_shortened_basenames[i] =
        relocated_image_basenames[i].substr(relocated_image_basenames[i].find_last_of("@") + 1);
    relocated_image_shortened_basenames[i] =
        relocated_image_shortened_basenames[i].substr(
            0, relocated_image_shortened_basenames[i].find("."));
  }
  ASSERT_EQ(rel_shortened_basenames, relocated_image_shortened_basenames);

  // Assert that verification works with the .rel files.
  if (!VerifyBootImage(
      dex2oat_orig_dir + "/boot.art",
      relocated_dir + "/boot.art",
      base_addr_delta,
      &error_msg)) {
    FAIL() << "VerifyBootImage failed: " << error_msg;
  }

  ClearDirectory(dex2oat_orig_dir.c_str(), /*recursive*/ true);
  ClearDirectory(relocated_dir.c_str(), /*recursive*/ true);

  rmdir(dex2oat_orig_dir.c_str());
  rmdir(relocated_dir.c_str());
}

}  // namespace art
