// Copyright 2018 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "base/trace_event/cfi_backtrace_android.h"

#include "base/files/file_util.h"
#include "testing/gtest/include/gtest/gtest.h"

namespace base {
namespace trace_event {

namespace {

void* GetPC() {
  return __builtin_return_address(0);
}

}  // namespace

TEST(CFIBacktraceAndroidTest, TestUnwinding) {
  auto* unwinder = CFIBacktraceAndroid::GetInitializedInstance();
  EXPECT_TRUE(unwinder->can_unwind_stack_frames());
  EXPECT_GT(unwinder->executable_start_addr(), 0u);
  EXPECT_GT(unwinder->executable_end_addr(), unwinder->executable_start_addr());
  EXPECT_GT(unwinder->cfi_mmap_->length(), 0u);

  const size_t kMaxFrames = 100;
  const void* frames[kMaxFrames];
  size_t unwind_count = unwinder->Unwind(frames, kMaxFrames);
  // Expect at least 2 frames in the result.
  ASSERT_GT(unwind_count, 2u);
  EXPECT_LE(unwind_count, kMaxFrames);

  const size_t kMaxCurrentFuncCodeSize = 50;
  const uintptr_t current_pc = reinterpret_cast<uintptr_t>(GetPC());
  const uintptr_t actual_frame = reinterpret_cast<uintptr_t>(frames[2]);
  EXPECT_NEAR(current_pc, actual_frame, kMaxCurrentFuncCodeSize);

  for (size_t i = 0; i < unwind_count; ++i) {
    EXPECT_GT(reinterpret_cast<uintptr_t>(frames[i]),
              unwinder->executable_start_addr());
    EXPECT_LT(reinterpret_cast<uintptr_t>(frames[i]),
              unwinder->executable_end_addr());
  }
}

// Flaky: https://bugs.chromium.org/p/chromium/issues/detail?id=829555
TEST(CFIBacktraceAndroidTest, DISABLED_TestFindCFIRow) {
  auto* unwinder = CFIBacktraceAndroid::GetInitializedInstance();
  /* Input is generated from the CFI file:
  STACK CFI INIT 1000 500
  STACK CFI 1002 .cfa: sp 272 + .ra: .cfa -4 + ^ r4: .cfa -16 +
  STACK CFI 1008 .cfa: sp 544 + .r1: .cfa -0 + ^ r4: .cfa -16 + ^
  STACK CFI 1040 .cfa: sp 816 + .r1: .cfa -0 + ^ r4: .cfa -16 + ^
  STACK CFI 1050 .cfa: sp 816 + .ra: .cfa -8 + ^ r4: .cfa -16 + ^
  STACK CFI 1080 .cfa: sp 544 + .r1: .cfa -0 + ^ r4: .cfa -16 + ^

  STACK CFI INIT 2000 22
  STACK CFI 2004 .cfa: sp 16 + .ra: .cfa -12 + ^ r4: .cfa -16 + ^
  STACK CFI 2008 .cfa: sp 16 + .ra: .cfa -12 + ^ r4: .cfa -16 + ^

  STACK CFI INIT 2024 100
  STACK CFI 2030 .cfa: sp 48 + .ra: .cfa -12 + ^ r4: .cfa -16 + ^
  STACK CFI 2100 .cfa: sp 64 + .r1: .cfa -0 + ^ r4: .cfa -16 + ^

  STACK CFI INIT 2200 10
  STACK CFI 2204 .cfa: sp 44 + .ra: .cfa -8 + ^ r4: .cfa -16 + ^
  */
  uint16_t input[] = {// UNW_INDEX size
                      0x07, 0x0,

                      // UNW_INDEX address column (4 byte rows).
                      0x1000, 0x0, 0x1502, 0x0, 0x2000, 0x0, 0x2024, 0x0,
                      0x2126, 0x0, 0x2200, 0x0, 0x2212, 0x0,

                      // UNW_INDEX index column (2 byte rows).
                      0x0, 0xffff, 0xb, 0x10, 0xffff, 0x15, 0xffff,

                      // UNW_DATA table.
                      0x5, 0x2, 0x111, 0x8, 0x220, 0x40, 0x330, 0x50, 0x332,
                      0x80, 0x220, 0x2, 0x4, 0x13, 0x8, 0x13, 0x2, 0xc, 0x33,
                      0xdc, 0x40, 0x1, 0x4, 0x2e};
  FilePath temp_path;
  CreateTemporaryFile(&temp_path);
  EXPECT_EQ(
      static_cast<int>(sizeof(input)),
      WriteFile(temp_path, reinterpret_cast<char*>(input), sizeof(input)));

  unwinder->cfi_mmap_.reset(new MemoryMappedFile());
  ASSERT_TRUE(unwinder->cfi_mmap_->Initialize(temp_path));
  unwinder->ParseCFITables();

  CFIBacktraceAndroid::CFIRow cfi_row = {0};
  EXPECT_FALSE(unwinder->FindCFIRowForPC(0x01, &cfi_row));
  EXPECT_FALSE(unwinder->FindCFIRowForPC(0x100, &cfi_row));
  EXPECT_FALSE(unwinder->FindCFIRowForPC(0x1502, &cfi_row));
  EXPECT_FALSE(unwinder->FindCFIRowForPC(0x3000, &cfi_row));
  EXPECT_FALSE(unwinder->FindCFIRowForPC(0x2024, &cfi_row));
  EXPECT_FALSE(unwinder->FindCFIRowForPC(0x2212, &cfi_row));

  const CFIBacktraceAndroid::CFIRow kRow1 = {0x110, 0x4};
  const CFIBacktraceAndroid::CFIRow kRow2 = {0x220, 0x4};
  const CFIBacktraceAndroid::CFIRow kRow3 = {0x220, 0x8};
  const CFIBacktraceAndroid::CFIRow kRow4 = {0x30, 0xc};
  const CFIBacktraceAndroid::CFIRow kRow5 = {0x2c, 0x8};
  EXPECT_TRUE(unwinder->FindCFIRowForPC(0x1002, &cfi_row));
  EXPECT_EQ(kRow1, cfi_row);
  EXPECT_TRUE(unwinder->FindCFIRowForPC(0x1003, &cfi_row));
  EXPECT_EQ(kRow1, cfi_row);
  EXPECT_TRUE(unwinder->FindCFIRowForPC(0x1008, &cfi_row));
  EXPECT_EQ(kRow2, cfi_row);
  EXPECT_TRUE(unwinder->FindCFIRowForPC(0x1009, &cfi_row));
  EXPECT_EQ(kRow2, cfi_row);
  EXPECT_TRUE(unwinder->FindCFIRowForPC(0x1039, &cfi_row));
  EXPECT_EQ(kRow2, cfi_row);
  EXPECT_TRUE(unwinder->FindCFIRowForPC(0x1080, &cfi_row));
  EXPECT_EQ(kRow3, cfi_row);
  EXPECT_TRUE(unwinder->FindCFIRowForPC(0x1100, &cfi_row));
  EXPECT_EQ(kRow3, cfi_row);
  EXPECT_TRUE(unwinder->FindCFIRowForPC(0x2050, &cfi_row));
  EXPECT_EQ(kRow4, cfi_row);
  EXPECT_TRUE(unwinder->FindCFIRowForPC(0x2208, &cfi_row));
  EXPECT_EQ(kRow5, cfi_row);
  EXPECT_TRUE(unwinder->FindCFIRowForPC(0x2210, &cfi_row));
  EXPECT_EQ(kRow5, cfi_row);

  // Test if cache is used on the future calls to Find, all addresses should
  // have different hash. Resetting the memory map to make sure it is never
  // accessed in Find().
  unwinder->cfi_mmap_.reset(new MemoryMappedFile());
  EXPECT_TRUE(unwinder->FindCFIRowForPC(0x1002, &cfi_row));
  EXPECT_EQ(kRow1, cfi_row);
  EXPECT_TRUE(unwinder->FindCFIRowForPC(0x1003, &cfi_row));
  EXPECT_EQ(kRow1, cfi_row);
  EXPECT_TRUE(unwinder->FindCFIRowForPC(0x1008, &cfi_row));
  EXPECT_EQ(kRow2, cfi_row);
  EXPECT_TRUE(unwinder->FindCFIRowForPC(0x1009, &cfi_row));
  EXPECT_EQ(kRow2, cfi_row);
  EXPECT_TRUE(unwinder->FindCFIRowForPC(0x1039, &cfi_row));
  EXPECT_EQ(kRow2, cfi_row);
  EXPECT_TRUE(unwinder->FindCFIRowForPC(0x1080, &cfi_row));
  EXPECT_EQ(kRow3, cfi_row);
  EXPECT_TRUE(unwinder->FindCFIRowForPC(0x1100, &cfi_row));
  EXPECT_EQ(kRow3, cfi_row);
  EXPECT_TRUE(unwinder->FindCFIRowForPC(0x2050, &cfi_row));
  EXPECT_EQ(kRow4, cfi_row);
  EXPECT_TRUE(unwinder->FindCFIRowForPC(0x2208, &cfi_row));
  EXPECT_EQ(kRow5, cfi_row);
  EXPECT_TRUE(unwinder->FindCFIRowForPC(0x2210, &cfi_row));
  EXPECT_EQ(kRow5, cfi_row);
}

TEST(CFIBacktraceAndroidTest, TestCFICache) {
  // Use ASSERT macros in this function since they are in loop and using EXPECT
  // prints too many failures.
  CFIBacktraceAndroid::CFICache cache;
  CFIBacktraceAndroid::CFIRow cfi;

  // Empty cache should not find anything.
  EXPECT_FALSE(cache.Find(1, &cfi));

  // Insert 1 - 2*kLimit
  for (uintptr_t i = 1; i <= 2 * cache.kLimit; ++i) {
    CFIBacktraceAndroid::CFIRow val = {static_cast<uint16_t>(4 * i),
                                       static_cast<uint16_t>(2 * i)};
    cache.Add(i, val);
    ASSERT_TRUE(cache.Find(i, &cfi));
    ASSERT_EQ(cfi, val);

    // Inserting more than kLimit items evicts |i - cache.kLimit| from cache.
    if (i >= cache.kLimit)
      ASSERT_FALSE(cache.Find(i - cache.kLimit, &cfi));
  }
  // Cache contains kLimit+1 - 2*kLimit.

  // Check that 1 - kLimit cannot be found.
  for (uintptr_t i = 1; i <= cache.kLimit; ++i) {
    ASSERT_FALSE(cache.Find(i, &cfi));
  }

  // Check if kLimit+1 - 2*kLimit still exists in cache.
  for (uintptr_t i = cache.kLimit + 1; i <= 2 * cache.kLimit; ++i) {
    CFIBacktraceAndroid::CFIRow val = {static_cast<uint16_t>(4 * i),
                                       static_cast<uint16_t>(2 * i)};
    ASSERT_TRUE(cache.Find(i, &cfi));
    ASSERT_EQ(cfi, val);
  }

  // Insert 2*kLimit+1, will evict kLimit.
  cfi = {1, 1};
  cache.Add(2 * cache.kLimit + 1, cfi);
  EXPECT_TRUE(cache.Find(2 * cache.kLimit + 1, &cfi));
  EXPECT_FALSE(cache.Find(cache.kLimit + 1, &cfi));
  // Cache contains kLimit+1 - 2*kLimit.
}

}  // namespace trace_event
}  // namespace base
