// Copyright 2017 The Crashpad Authors. All rights reserved.
//
// 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 "snapshot/linux/debug_rendezvous.h"

#include <linux/auxvec.h>
#include <string.h>
#include <unistd.h>

#include <limits>

#include "base/format_macros.h"
#include "base/strings/string_number_conversions.h"
#include "base/strings/string_piece.h"
#include "base/strings/stringprintf.h"
#include "build/build_config.h"
#include "gtest/gtest.h"
#include "snapshot/elf/elf_image_reader.h"
#include "test/linux/fake_ptrace_connection.h"
#include "test/multiprocess.h"
#include "util/linux/address_types.h"
#include "util/linux/auxiliary_vector.h"
#include "util/linux/direct_ptrace_connection.h"
#include "util/linux/memory_map.h"
#include "util/process/process_memory_linux.h"
#include "util/process/process_memory_range.h"

#if defined(OS_ANDROID)
#include <android/api-level.h>
#endif

namespace crashpad {
namespace test {
namespace {

void TestAgainstTarget(PtraceConnection* connection) {
  // Use ElfImageReader on the main executable which can tell us the debug
  // address. glibc declares the symbol _r_debug in link.h which we can use to
  // get the address, but Android does not.
  AuxiliaryVector aux;
  ASSERT_TRUE(aux.Initialize(connection));

  LinuxVMAddress phdrs;
  ASSERT_TRUE(aux.GetValue(AT_PHDR, &phdrs));

  MemoryMap mappings;
  ASSERT_TRUE(mappings.Initialize(connection));

  const MemoryMap::Mapping* phdr_mapping = mappings.FindMapping(phdrs);
  ASSERT_TRUE(phdr_mapping);

  auto exe_mappings = mappings.FindFilePossibleMmapStarts(*phdr_mapping);
  ASSERT_EQ(exe_mappings->Count(), 1u);
  LinuxVMAddress elf_address = exe_mappings->Next()->range.Base();

  ProcessMemoryLinux memory;
  ASSERT_TRUE(memory.Initialize(connection->GetProcessID()));
  ProcessMemoryRange range;
  ASSERT_TRUE(range.Initialize(&memory, connection->Is64Bit()));

  ElfImageReader exe_reader;
  ASSERT_TRUE(exe_reader.Initialize(range, elf_address));
  LinuxVMAddress debug_address;
  ASSERT_TRUE(exe_reader.GetDebugAddress(&debug_address));

  // start the actual tests
  DebugRendezvous debug;
  ASSERT_TRUE(debug.Initialize(range, debug_address));

#if defined(OS_ANDROID)
  const int android_runtime_api = android_get_device_api_level();
  ASSERT_GE(android_runtime_api, 1);

  EXPECT_NE(debug.Executable()->name.find("crashpad_snapshot_test"),
            std::string::npos);

  // Android's loader never sets the dynamic array for the executable.
  EXPECT_EQ(debug.Executable()->dynamic_array, 0u);
#else
  // glibc's loader implements most of the tested features that Android's was
  // missing but has since gained.
  const int android_runtime_api = std::numeric_limits<int>::max();

  // glibc's loader does not set the name for the executable.
  EXPECT_TRUE(debug.Executable()->name.empty());
  CheckedLinuxAddressRange exe_range(
      connection->Is64Bit(), exe_reader.Address(), exe_reader.Size());
  EXPECT_TRUE(exe_range.ContainsValue(debug.Executable()->dynamic_array));
#endif  // OS_ANDROID

  // Android's loader doesn't set the load bias until Android 4.3 (API 18).
  if (android_runtime_api >= 18) {
    EXPECT_EQ(debug.Executable()->load_bias, exe_reader.GetLoadBias());
  } else {
    EXPECT_EQ(debug.Executable()->load_bias, 0);
  }

  for (const DebugRendezvous::LinkEntry& module : debug.Modules()) {
    SCOPED_TRACE(base::StringPrintf("name %s, load_bias 0x%" PRIx64
                                    ", dynamic_array 0x%" PRIx64,
                                    module.name.c_str(),
                                    module.load_bias,
                                    module.dynamic_array));
    const bool is_android_loader = (module.name == "/system/bin/linker" ||
                                    module.name == "/system/bin/linker64");

    // Android's loader doesn't set its own dynamic array until Android 4.2
    // (API 17).
    if (is_android_loader && android_runtime_api < 17) {
      EXPECT_EQ(module.dynamic_array, 0u);
      EXPECT_EQ(module.load_bias, 0);
      continue;
    }

    ASSERT_TRUE(module.dynamic_array);
    const MemoryMap::Mapping* dyn_mapping =
        mappings.FindMapping(module.dynamic_array);
    ASSERT_TRUE(dyn_mapping);

    auto possible_mappings = mappings.FindFilePossibleMmapStarts(*dyn_mapping);
    ASSERT_GE(possible_mappings->Count(), 1u);

    std::unique_ptr<ElfImageReader> module_reader;
    const MemoryMap::Mapping* module_mapping = nullptr;
    const MemoryMap::Mapping* mapping = nullptr;
    while ((mapping = possible_mappings->Next())) {
      auto parsed_module = std::make_unique<ElfImageReader>();
      VMAddress dynamic_address;
      if (parsed_module->Initialize(range, mapping->range.Base()) &&
          parsed_module->GetDynamicArrayAddress(&dynamic_address) &&
          dynamic_address == module.dynamic_array) {
        module_reader = std::move(parsed_module);
        module_mapping = mapping;
        break;
      }
    }
    ASSERT_TRUE(module_reader.get());

#if defined(OS_ANDROID)
    EXPECT_FALSE(module.name.empty());
#else
    // glibc's loader doesn't always set the name in the link map for the vdso.
    EXPECT_PRED4(
        [](const std::string mapping_name,
           int device,
           int inode,
           const std::string& module_name) {
          const bool is_vdso_mapping =
              device == 0 && inode == 0 && mapping_name == "[vdso]";
          static constexpr char kPrefix[] = "linux-vdso.so.";
          return is_vdso_mapping ==
                 (module_name.empty() ||
                  module_name.compare(0, strlen(kPrefix), kPrefix) == 0);
        },
        module_mapping->name,
        module_mapping->device,
        module_mapping->inode,
        module.name);
#endif  // OS_ANDROID

    // Android's loader stops setting its own load bias after Android 4.4.4
    // (API 20) until Android 6.0 (API 23).
    if (is_android_loader && android_runtime_api > 20 &&
        android_runtime_api < 23) {
      EXPECT_EQ(module.load_bias, 0);
    } else {
      EXPECT_EQ(module.load_bias, module_reader->GetLoadBias());
    }

    CheckedLinuxAddressRange module_range(
        connection->Is64Bit(), module_reader->Address(), module_reader->Size());
    EXPECT_TRUE(module_range.ContainsValue(module.dynamic_array));
  }
}

TEST(DebugRendezvous, Self) {
  FakePtraceConnection connection;
  ASSERT_TRUE(connection.Initialize(getpid()));

  TestAgainstTarget(&connection);
}

class ChildTest : public Multiprocess {
 public:
  ChildTest() {}
  ~ChildTest() {}

 private:
  void MultiprocessParent() {
    DirectPtraceConnection connection;
    ASSERT_TRUE(connection.Initialize(ChildPID()));

    TestAgainstTarget(&connection);
  }

  void MultiprocessChild() { CheckedReadFileAtEOF(ReadPipeHandle()); }

  DISALLOW_COPY_AND_ASSIGN(ChildTest);
};

TEST(DebugRendezvous, Child) {
  ChildTest test;
  test.Run();
}

}  // namespace
}  // namespace test
}  // namespace crashpad
