// 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/elf/elf_image_reader.h"

#include <dlfcn.h>
#include <link.h>
#include <unistd.h>

#include "build/build_config.h"
#include "gtest/gtest.h"
#include "test/multiprocess_exec.h"
#include "test/process_type.h"
#include "test/scoped_module_handle.h"
#include "test/test_paths.h"
#include "util/file/file_io.h"
#include "util/misc/address_types.h"
#include "util/misc/elf_note_types.h"
#include "util/misc/from_pointer_cast.h"
#include "util/process/process_memory_native.h"

#if defined(OS_FUCHSIA)
#include <lib/zx/process.h>

#include "base/fuchsia/fuchsia_logging.h"

#elif defined(OS_LINUX) || defined(OS_CHROMEOS) || defined(OS_ANDROID)

#include "test/linux/fake_ptrace_connection.h"
#include "util/linux/auxiliary_vector.h"
#include "util/linux/memory_map.h"

#else

#error Port.

#endif  // OS_FUCHSIA

extern "C" {
__attribute__((visibility("default"))) void ElfImageReaderTestExportedSymbol() {
}
}  // extern "C"

namespace crashpad {
namespace test {
namespace {


#if defined(OS_FUCHSIA)

void LocateExecutable(const ProcessType& process,
                      ProcessMemory* memory,
                      VMAddress* elf_address) {
  uintptr_t debug_address;
  zx_status_t status = process->get_property(
      ZX_PROP_PROCESS_DEBUG_ADDR, &debug_address, sizeof(debug_address));
  ASSERT_EQ(status, ZX_OK)
      << "zx_object_get_property: ZX_PROP_PROCESS_DEBUG_ADDR";
  // Can be 0 if requested before the loader has loaded anything.
  EXPECT_NE(debug_address, 0u);

  constexpr auto k_r_debug_map_offset = offsetof(r_debug, r_map);
  uintptr_t map;
  ASSERT_TRUE(
      memory->Read(debug_address + k_r_debug_map_offset, sizeof(map), &map))
      << "read link_map";

  constexpr auto k_link_map_addr_offset = offsetof(link_map, l_addr);
  uintptr_t base;
  ASSERT_TRUE(memory->Read(map + k_link_map_addr_offset, sizeof(base), &base))
      << "read base";

  *elf_address = base;
}

#elif defined(OS_LINUX) || defined(OS_CHROMEOS) || defined(OS_ANDROID)

void LocateExecutable(PtraceConnection* connection,
                      ProcessMemory* memory,
                      VMAddress* elf_address) {
  AuxiliaryVector aux;
  ASSERT_TRUE(aux.Initialize(connection));

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

  MemoryMap memory_map;
  ASSERT_TRUE(memory_map.Initialize(connection));
  const MemoryMap::Mapping* phdr_mapping = memory_map.FindMapping(phdrs);
  ASSERT_TRUE(phdr_mapping);
  auto possible_mappings = memory_map.FindFilePossibleMmapStarts(*phdr_mapping);
  ASSERT_EQ(possible_mappings->Count(), 1u);
  *elf_address = possible_mappings->Next()->range.Base();
}

#endif  // OS_FUCHSIA

void ExpectSymbol(ElfImageReader* reader,
                  const std::string& symbol_name,
                  VMAddress expected_symbol_address) {
  VMAddress symbol_address;
  VMSize symbol_size;
  ASSERT_TRUE(
      reader->GetDynamicSymbol(symbol_name, &symbol_address, &symbol_size));
  EXPECT_EQ(symbol_address, expected_symbol_address);

  EXPECT_FALSE(
      reader->GetDynamicSymbol("notasymbol", &symbol_address, &symbol_size));
}

void ReadThisExecutableInTarget(ProcessType process,
                                VMAddress exported_symbol_address) {
#if defined(ARCH_CPU_64_BITS)
  constexpr bool am_64_bit = true;
#else
  constexpr bool am_64_bit = false;
#endif  // ARCH_CPU_64_BITS

  VMAddress elf_address;
#if defined(OS_LINUX) || defined(OS_CHROMEOS) || defined(OS_ANDROID)
  FakePtraceConnection connection;
  ASSERT_TRUE(connection.Initialize(process));
  ProcessMemoryLinux memory(&connection);
  LocateExecutable(&connection, &memory, &elf_address);
#elif defined(OS_FUCHSIA)
  ProcessMemoryFuchsia memory;
  ASSERT_TRUE(memory.Initialize(process));
  LocateExecutable(process, &memory, &elf_address);
#endif
  ASSERT_NO_FATAL_FAILURE();

  ProcessMemoryRange range;
  ASSERT_TRUE(range.Initialize(&memory, am_64_bit));

  ElfImageReader reader;
  ASSERT_TRUE(reader.Initialize(range, elf_address));

  ExpectSymbol(
      &reader, "ElfImageReaderTestExportedSymbol", exported_symbol_address);

  ElfImageReader::NoteReader::Result result;
  std::string note_name;
  std::string note_desc;
  ElfImageReader::NoteReader::NoteType note_type;
  VMAddress desc_addr;

  std::unique_ptr<ElfImageReader::NoteReader> notes = reader.Notes(10000);
  while ((result = notes->NextNote(
              &note_name, &note_type, &note_desc, &desc_addr)) ==
         ElfImageReader::NoteReader::Result::kSuccess) {
  }
  EXPECT_EQ(result, ElfImageReader::NoteReader::Result::kNoMoreNotes);

  notes = reader.Notes(0);
  EXPECT_EQ(notes->NextNote(&note_name, &note_type, &note_desc, &desc_addr),
            ElfImageReader::NoteReader::Result::kNoMoreNotes);

  // Find the note defined in elf_image_reader_test_note.S.
  constexpr uint32_t kCrashpadNoteDesc = 42;
  notes = reader.NotesWithNameAndType(
      CRASHPAD_ELF_NOTE_NAME, CRASHPAD_ELF_NOTE_TYPE_SNAPSHOT_TEST, 10000);
  ASSERT_EQ(notes->NextNote(&note_name, &note_type, &note_desc, &desc_addr),
            ElfImageReader::NoteReader::Result::kSuccess);
  EXPECT_EQ(note_name, CRASHPAD_ELF_NOTE_NAME);
  EXPECT_EQ(note_type,
            implicit_cast<unsigned int>(CRASHPAD_ELF_NOTE_TYPE_SNAPSHOT_TEST));
  EXPECT_EQ(note_desc.size(), sizeof(kCrashpadNoteDesc));
  EXPECT_EQ(*reinterpret_cast<decltype(kCrashpadNoteDesc)*>(&note_desc[0]),
            kCrashpadNoteDesc);

  EXPECT_EQ(notes->NextNote(&note_name, &note_type, &note_desc, &desc_addr),
            ElfImageReader::NoteReader::Result::kNoMoreNotes);
}

void ReadLibcInTarget(ProcessType process,
                      VMAddress elf_address,
                      VMAddress getpid_address) {
#if defined(ARCH_CPU_64_BITS)
  constexpr bool am_64_bit = true;
#else
  constexpr bool am_64_bit = false;
#endif  // ARCH_CPU_64_BITS

#if defined(OS_ANDROID) || defined(OS_LINUX) || defined(OS_CHROMEOS)
  FakePtraceConnection connection;
  ASSERT_TRUE(connection.Initialize(process));
  ProcessMemoryLinux memory(&connection);
#else
  ProcessMemoryNative memory;
  ASSERT_TRUE(memory.Initialize(process));
#endif

  ProcessMemoryRange range;
  ASSERT_TRUE(range.Initialize(&memory, am_64_bit));

  ElfImageReader reader;
  ASSERT_TRUE(reader.Initialize(range, elf_address));

  ExpectSymbol(&reader, "getpid", getpid_address);
}

TEST(ElfImageReader, MainExecutableSelf) {
  ReadThisExecutableInTarget(
      GetSelfProcess(),
      FromPointerCast<VMAddress>(ElfImageReaderTestExportedSymbol));
}

CRASHPAD_CHILD_TEST_MAIN(ReadExecutableChild) {
  VMAddress exported_symbol_address =
      FromPointerCast<VMAddress>(ElfImageReaderTestExportedSymbol);
  CheckedWriteFile(StdioFileHandle(StdioStream::kStandardOutput),
                   &exported_symbol_address,
                   sizeof(exported_symbol_address));
  CheckedReadFileAtEOF(StdioFileHandle(StdioStream::kStandardInput));
  return 0;
}

class ReadExecutableChildTest : public MultiprocessExec {
 public:
  ReadExecutableChildTest() : MultiprocessExec() {}

 private:
  void MultiprocessParent() {
    // This read serves two purposes -- on Fuchsia, the loader may have not
    // filled in debug address as soon as the child process handle is valid, so
    // this causes a wait at least until the main() of the child, at which point
    // it will always be valid. Secondarily, the address of the symbol to be
    // looked up needs to be communicated.
    VMAddress exported_symbol_address;
    CheckedReadFileExactly(ReadPipeHandle(),
                           &exported_symbol_address,
                           sizeof(exported_symbol_address));
    ReadThisExecutableInTarget(ChildProcess(), exported_symbol_address);
  }
};

TEST(ElfImageReader, MainExecutableChild) {
  ReadExecutableChildTest test;
  test.SetChildTestMainFunction("ReadExecutableChild");
  test.Run();
}

TEST(ElfImageReader, OneModuleSelf) {
  Dl_info info;
  ASSERT_TRUE(dladdr(reinterpret_cast<void*>(getpid), &info)) << "dladdr:"
                                                              << dlerror();
  VMAddress elf_address = FromPointerCast<VMAddress>(info.dli_fbase);
  ReadLibcInTarget(
      GetSelfProcess(), elf_address, FromPointerCast<VMAddress>(getpid));
}

CRASHPAD_CHILD_TEST_MAIN(ReadLibcChild) {
  // Get the address of libc (by using getpid() as a representative member),
  // and also the address of getpid() itself, and write them to the parent, so
  // it can validate reading this information back out.
  Dl_info info;
  EXPECT_TRUE(dladdr(reinterpret_cast<void*>(getpid), &info))
      << "dladdr:" << dlerror();
  VMAddress elf_address = FromPointerCast<VMAddress>(info.dli_fbase);
  VMAddress getpid_address = FromPointerCast<VMAddress>(getpid);

  CheckedWriteFile(StdioFileHandle(StdioStream::kStandardOutput),
                   &elf_address,
                   sizeof(elf_address));
  CheckedWriteFile(StdioFileHandle(StdioStream::kStandardOutput),
                   &getpid_address,
                   sizeof(getpid_address));
  CheckedReadFileAtEOF(StdioFileHandle(StdioStream::kStandardInput));
  return 0;
}

class ReadLibcChildTest : public MultiprocessExec {
 public:
  ReadLibcChildTest() : MultiprocessExec() {}
  ~ReadLibcChildTest() {}

 private:
  void MultiprocessParent() {
    VMAddress elf_address, getpid_address;
    CheckedReadFileExactly(ReadPipeHandle(), &elf_address, sizeof(elf_address));
    CheckedReadFileExactly(
        ReadPipeHandle(), &getpid_address, sizeof(getpid_address));
    ReadLibcInTarget(ChildProcess(), elf_address, getpid_address);
  }
};

TEST(ElfImageReader, OneModuleChild) {
  ReadLibcChildTest test;
  test.SetChildTestMainFunction("ReadLibcChild");
  test.Run();
}

#if defined(OS_FUCHSIA)

// crashpad_snapshot_test_both_dt_hash_styles is specially built and forced to
// include both .hash and .gnu.hash sections. Linux, Android, and Fuchsia have
// different defaults for which of these sections should be included; this test
// confirms that we get the same count from both sections.
//
// TODO(scottmg): Investigation in https://crrev.com/c/876879 resulted in
// realizing that ld.bfd does not emit a .gnu.hash that is very useful for this
// purpose when there's 0 exported entries in the module. This is not likely to
// be too important, as there's little need to look up non-exported symbols.
// However, it makes this test not work on Linux, where the default build uses
// ld.bfd. On Fuchsia, the only linker in use is lld, and it generates the
// expected .gnu.hash. So, for now, this test is only run on Fuchsia, not Linux.
//
// TODO(scottmg): Separately, the location of the ELF on Android needs some
// work, and then the test could also be enabled there.
TEST(ElfImageReader, DtHashAndDtGnuHashMatch) {
  base::FilePath module_path =
      TestPaths::BuildArtifact(FILE_PATH_LITERAL("snapshot"),
                               FILE_PATH_LITERAL("both_dt_hash_styles"),
                               TestPaths::FileType::kLoadableModule);
  // TODO(scottmg): Remove this when upstream Fuchsia bug ZX-1619 is resolved.
  // See also explanation in build/run_tests.py for Fuchsia .so files.
  module_path = module_path.BaseName();
  ScopedModuleHandle module(
      dlopen(module_path.value().c_str(), RTLD_LAZY | RTLD_LOCAL));
  ASSERT_TRUE(module.valid()) << "dlopen " << module_path.value() << ": "
                              << dlerror();

#if defined(ARCH_CPU_64_BITS)
  constexpr bool am_64_bit = true;
#else
  constexpr bool am_64_bit = false;
#endif  // ARCH_CPU_64_BITS

  ProcessMemoryNative memory;
  ASSERT_TRUE(memory.Initialize(GetSelfProcess()));
  ProcessMemoryRange range;
  ASSERT_TRUE(range.Initialize(&memory, am_64_bit));

  struct link_map* lm = reinterpret_cast<struct link_map*>(module.get());

  ElfImageReader reader;
  ASSERT_TRUE(reader.Initialize(range, lm->l_addr));

  VMSize from_dt_hash;
  ASSERT_TRUE(reader.GetNumberOfSymbolEntriesFromDtHash(&from_dt_hash));

  VMSize from_dt_gnu_hash;
  ASSERT_TRUE(reader.GetNumberOfSymbolEntriesFromDtGnuHash(&from_dt_gnu_hash));

  EXPECT_EQ(from_dt_hash, from_dt_gnu_hash);
}

#endif  // OS_FUCHSIA

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