// Copyright 2019 The Fuchsia Authors
//
// Use of this source code is governed by a MIT-style
// license that can be found in the LICENSE file or at
// https://opensource.org/licenses/MIT

#include <align.h>
#include <lib/llvm-profdata/llvm-profdata.h>
#include <lib/version.h>
#include <stdint.h>
#include <string.h>
#include <zircon/assert.h>

#include <ktl/byte.h>
#include <ktl/move.h>
#include <ktl/span.h>
#include <ktl/string_view.h>
#include <vm/vm_object_paged.h>

#include "kernel-mapped-vmo.h"
#include "private.h"

#include <ktl/enforce.h>

namespace {

constexpr ktl::string_view kVmoName = "data/zircon.elf.profraw";

// This holds the pinned mapping of the live-updated counters.
KernelMappedVmo gProfdataCounters;

}  // namespace

InstrumentationDataVmo LlvmProfdataVmo() {
  LlvmProfdata profdata;
  profdata.Init(ElfBuildId());
  if (profdata.size_bytes() == 0) {
    return {};
  }

  // Create a VMO to hold the whole profdata dump.
  fbl::RefPtr<VmObjectPaged> vmo;
  zx_status_t status = VmObjectPaged::Create(PMM_ALLOC_FLAG_ANY, 0, profdata.size_bytes(), &vmo);
  ZX_ASSERT(status == ZX_OK);

  // First fill in just the fixed data, by mapping the whole VMO into the
  // kernel address space.  Then let the mapping and pinning be cleaned up,
  // since we don't need the whole thing mapped into the kernel at runtime.
  {
    KernelMappedVmo mapped_vmo;
    status = mapped_vmo.Init(vmo, 0, profdata.size_bytes(), "llvm-profdata-setup");
    ZX_ASSERT(status == ZX_OK);
    ktl::span<ktl::byte> mapped_data{
        reinterpret_cast<ktl::byte*>(mapped_vmo.base()),
        mapped_vmo.size(),
    };
    profdata.WriteFixedData(mapped_data);
  }

  // Now map in just the pages holding the counters.  This mapping will be kept
  // alive permanently so the live counters can be updated through it.
  const uint64_t map_offset = ROUNDDOWN(profdata.counters_offset(), PAGE_SIZE);
  const size_t map_size =
      ROUNDUP_PAGE_SIZE(profdata.counters_offset() + profdata.counters_size_bytes()) - map_offset;
  status = gProfdataCounters.Init(ktl::move(vmo), map_offset, map_size, "llvm-profdata-counters");
  ZX_ASSERT(status == ZX_OK);
  ktl::span<ktl::byte> counters{
      reinterpret_cast<ktl::byte*>(profdata.counters_offset() - map_offset +
                                   gProfdataCounters.base()),
      profdata.counters_size_bytes(),
  };

  // Counts up to this point have collected in global variable space.
  // Copy those counters into the mapped VMO data.
  profdata.CopyCounters(counters);

  // Switch instrumented code over to updating the mapped VMO data in place.
  // From this point on, the kernel's VMO mapping is used by all instrumented
  // code and must be kept valid and pinned.
  //
  // TODO(mcgrathr): We could theoretically decommit the global data pages
  // after this to recover that RAM.  That part of the kernel's global data
  // area should never be accessed again.
  LlvmProfdata::UseCounters(counters);

  return {
      .announce = LlvmProfdata::kAnnounce,
      .sink_name = LlvmProfdata::kDataSinkName,
      .handle = gProfdataCounters.Publish(kVmoName, profdata.size_bytes()),
  };
}
