// 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 "util/linux/auxiliary_vector.h"

#include <linux/auxvec.h>
#include <sys/utsname.h>
#include <unistd.h>

#include <limits>

#include "base/bit_cast.h"
#include "base/macros.h"
#include "build/build_config.h"
#include "gtest/gtest.h"
#include "test/errors.h"
#include "test/linux/fake_ptrace_connection.h"
#include "test/main_arguments.h"
#include "test/multiprocess.h"
#include "util/linux/address_types.h"
#include "util/linux/memory_map.h"
#include "util/misc/from_pointer_cast.h"
#include "util/numeric/int128.h"
#include "util/process/process_memory_linux.h"

#if !defined(OS_ANDROID)
// TODO(jperaza): This symbol isn't defined when building in chromium for
// Android. There may be another symbol to use.
extern "C" {
#if defined(ARCH_CPU_MIPS_FAMILY)
#define START_SYMBOL __start
#else
#define START_SYMBOL _start
#endif
extern void START_SYMBOL();
}  // extern "C"
#endif

namespace crashpad {
namespace test {
namespace {

void TestAgainstCloneOrSelf(pid_t pid) {
  FakePtraceConnection connection;
  ASSERT_TRUE(connection.Initialize(pid));

  AuxiliaryVector aux;
  ASSERT_TRUE(aux.Initialize(&connection));

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

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

  int pagesize;
  ASSERT_TRUE(aux.GetValue(AT_PAGESZ, &pagesize));
  EXPECT_EQ(pagesize, getpagesize());

  LinuxVMAddress interp_base;
  ASSERT_TRUE(aux.GetValue(AT_BASE, &interp_base));
  EXPECT_TRUE(mappings.FindMapping(interp_base));

#if !defined(OS_ANDROID)
  LinuxVMAddress entry_addr;
  ASSERT_TRUE(aux.GetValue(AT_ENTRY, &entry_addr));
  EXPECT_EQ(entry_addr, FromPointerCast<LinuxVMAddress>(START_SYMBOL));
#endif

  uid_t uid;
  ASSERT_TRUE(aux.GetValue(AT_UID, &uid));
  EXPECT_EQ(uid, getuid());

  uid_t euid;
  ASSERT_TRUE(aux.GetValue(AT_EUID, &euid));
  EXPECT_EQ(euid, geteuid());

  gid_t gid;
  ASSERT_TRUE(aux.GetValue(AT_GID, &gid));
  EXPECT_EQ(gid, getgid());

  gid_t egid;
  ASSERT_TRUE(aux.GetValue(AT_EGID, &egid));
  EXPECT_EQ(egid, getegid());

  ProcessMemoryLinux memory(&connection);

  LinuxVMAddress platform_addr;
  ASSERT_TRUE(aux.GetValue(AT_PLATFORM, &platform_addr));
  std::string platform;
  ASSERT_TRUE(memory.ReadCStringSizeLimited(platform_addr, 10, &platform));
#if defined(ARCH_CPU_X86)
  EXPECT_STREQ(platform.c_str(), "i686");
#elif defined(ARCH_CPU_X86_64)
  EXPECT_STREQ(platform.c_str(), "x86_64");
#elif defined(ARCH_CPU_ARMEL)
  // Machine name and platform are set in Linux:/arch/arm/kernel/setup.c
  // Machine typically looks like "armv7l".
  // Platform typically looks like "v7l".
  utsname sys_names;
  ASSERT_EQ(uname(&sys_names), 0);
  std::string machine_name(sys_names.machine);
  EXPECT_NE(machine_name.find(platform), std::string::npos);
#elif defined(ARCH_CPU_ARM64)
  EXPECT_STREQ(platform.c_str(), "aarch64");
#endif  // ARCH_CPU_X86

#if defined(AT_SYSINFO_EHDR)
  LinuxVMAddress vdso_addr;
  if (aux.GetValue(AT_SYSINFO_EHDR, &vdso_addr)) {
    EXPECT_TRUE(mappings.FindMapping(vdso_addr));
  }
#endif  // AT_SYSINFO_EHDR

#if defined(AT_EXECFN)
  LinuxVMAddress filename_addr;
  ASSERT_TRUE(aux.GetValue(AT_EXECFN, &filename_addr));
  std::string filename;
  ASSERT_TRUE(memory.ReadCStringSizeLimited(filename_addr, 4096, &filename));
  EXPECT_TRUE(filename.find(GetMainArguments()[0]) != std::string::npos);
#endif  // AT_EXECFN

  int ignore;
  EXPECT_FALSE(aux.GetValue(AT_NULL, &ignore));

  char too_small;
  EXPECT_FALSE(aux.GetValue(AT_PAGESZ, &too_small));

  uint128_struct big_dest;
  memset(&big_dest, 0xf, sizeof(big_dest));
  ASSERT_TRUE(aux.GetValue(AT_PHDR, &big_dest));
  EXPECT_EQ(big_dest.lo, phdrs);
}

TEST(AuxiliaryVector, ReadSelf) {
  TestAgainstCloneOrSelf(getpid());
}

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

 private:
  void MultiprocessParent() override { TestAgainstCloneOrSelf(ChildPID()); }

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

  DISALLOW_COPY_AND_ASSIGN(ReadChildTest);
};

TEST(AuxiliaryVector, ReadChild) {
  ReadChildTest test;
  test.Run();
}

class AuxVecTester : public AuxiliaryVector {
 public:
  AuxVecTester() : AuxiliaryVector() {}
  void Insert(uint64_t type, uint64_t value) { values_[type] = value; }
};

TEST(AuxiliaryVector, SignedBit) {
  FakePtraceConnection connection;
  ASSERT_TRUE(connection.Initialize(getpid()));

  AuxVecTester aux;
  ASSERT_TRUE(&connection);
  constexpr uint64_t type = 0x0000000012345678;

  constexpr int32_t neg1_32 = -1;
  aux.Insert(type, bit_cast<uint32_t>(neg1_32));
  int32_t outval32s;
  ASSERT_TRUE(aux.GetValue(type, &outval32s));
  EXPECT_EQ(outval32s, neg1_32);

  constexpr int32_t int32_max = std::numeric_limits<int32_t>::max();
  aux.Insert(type, bit_cast<uint32_t>(int32_max));
  ASSERT_TRUE(aux.GetValue(type, &outval32s));
  EXPECT_EQ(outval32s, int32_max);

  constexpr uint32_t uint32_max = std::numeric_limits<uint32_t>::max();
  aux.Insert(type, uint32_max);
  uint32_t outval32u;
  ASSERT_TRUE(aux.GetValue(type, &outval32u));
  EXPECT_EQ(outval32u, uint32_max);

  constexpr int64_t neg1_64 = -1;
  aux.Insert(type, bit_cast<uint64_t>(neg1_64));
  int64_t outval64s;
  ASSERT_TRUE(aux.GetValue(type, &outval64s));
  EXPECT_EQ(outval64s, neg1_64);

  constexpr int64_t int64_max = std::numeric_limits<int64_t>::max();
  aux.Insert(type, bit_cast<uint64_t>(int64_max));
  ASSERT_TRUE(aux.GetValue(type, &outval64s));
  EXPECT_EQ(outval64s, int64_max);

  constexpr uint64_t uint64_max = std::numeric_limits<uint64_t>::max();
  aux.Insert(type, uint64_max);
  uint64_t outval64u;
  ASSERT_TRUE(aux.GetValue(type, &outval64u));
  EXPECT_EQ(outval64u, uint64_max);
}

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