// Copyright 2019 The Cobalt 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 "starboard/elf_loader/elf_loader_impl.h"

#include <string>

#include "starboard/common/log.h"
#include "starboard/common/scoped_ptr.h"
#include "starboard/elf_loader/elf.h"
#include "starboard/elf_loader/elf_loader_constants.h"
#include "starboard/elf_loader/file.h"
#include "starboard/elf_loader/file_impl.h"
#include "starboard/elf_loader/log.h"
#include "starboard/elf_loader/lz4_file_impl.h"
#include "starboard/extension/loader_app_metrics.h"
#include "starboard/memory.h"
#include "starboard/string.h"
#include "starboard/system.h"

namespace starboard {
namespace elf_loader {

namespace {

bool EndsWith(const std::string& s, const std::string& suffix) {
  if (s.size() < suffix.size()) {
    return false;
  }
  return strcmp(s.c_str() + (s.size() - suffix.size()), suffix.c_str()) == 0;
}

}  // namespace

ElfLoaderImpl::ElfLoaderImpl() {
#if !SB_CAN(MAP_EXECUTABLE_MEMORY)
  SB_CHECK(false) << "The elf_loader requires "
                     "executable memory map support!";
#endif
}

bool ElfLoaderImpl::Load(const char* name,
                         bool use_compression,
                         bool use_memory_mapped_files) {
  if (use_compression && use_memory_mapped_files) {
    SB_LOG(ERROR) << "Loading " << name
                  << " Compression is not supported with memory mapped files.";
    return false;
  }

  scoped_ptr<File> elf_file;
  if (use_compression && EndsWith(name, kCompressionSuffix)) {
    elf_file.reset(new LZ4FileImpl());
    SB_LOG(INFO) << "Loading " << name << " using compression";
  } else {
    SB_LOG(INFO) << "Loading " << name;
    elf_file.reset(new FileImpl());
  }
  elf_file->Open(name);

  elf_header_loader_.reset(new ElfHeader());
  if (!elf_header_loader_->LoadElfHeader(elf_file.get())) {
    SB_LOG(ERROR) << "Failed to load ELF header";
    return false;
  }

  SB_DLOG(INFO) << "Loaded ELF header";

  if (use_memory_mapped_files) {
    const auto* memory_mapped_file_extension =
        reinterpret_cast<const CobaltExtensionMemoryMappedFileApi*>(
            SbSystemGetExtension(kCobaltExtensionMemoryMappedFileName));

    if (!memory_mapped_file_extension ||
        strcmp(memory_mapped_file_extension->name,
               kCobaltExtensionMemoryMappedFileName) != 0 ||
        memory_mapped_file_extension->version < 1) {
      SB_LOG(ERROR) << "CobaltExtensionMemoryMappedFileApi not implemented";
      return false;
    }
    program_table_.reset(new ProgramTable(memory_mapped_file_extension));
  } else {
    program_table_.reset(new ProgramTable(nullptr));
  }

  program_table_->LoadProgramHeader(elf_header_loader_->GetHeader(),
                                    elf_file.get());

  SB_DLOG(INFO) << "Loaded Program header";

  if (!program_table_->ReserveLoadMemory()) {
    SB_LOG(ERROR) << "Failed to reserve memory space";
    return false;
  }

  SB_DLOG(INFO) << "Reserved address space";

  if (!program_table_->LoadSegments(elf_file.get())) {
    SB_LOG(ERROR) << "Failed to load segments";
    return false;
  }
  SB_DLOG(INFO) << "Loaded segments";

  Dyn* dynamic = NULL;
  size_t dynamic_count = 0;
  Word dynamic_flags = 0;
  program_table_->GetDynamicSection(&dynamic, &dynamic_count, &dynamic_flags);
  if (!dynamic) {
    SB_LOG(ERROR) << "No PT_DYNAMIC section!";
    return false;
  }
  dynamic_section_.reset(
      new DynamicSection(program_table_->GetBaseMemoryAddress(), dynamic,
                         dynamic_count, dynamic_flags));
  if (!dynamic_section_->InitDynamicSection()) {
    SB_LOG(ERROR) << "Failed to initialize dynamic section";
    return false;
  }
  SB_DLOG(INFO) << "Initialized dynamic section";

  exported_symbols_.reset(new ExportedSymbols());
  relocations_.reset(new Relocations(program_table_->GetBaseMemoryAddress(),
                                     dynamic_section_.get(),
                                     exported_symbols_.get()));
  if (!relocations_->InitRelocations()) {
    SB_LOG(ERROR) << "Failed to initialize relocations";
    return false;
  }
  if (relocations_->HasTextRelocations()) {
    SB_DLOG(INFO) << "HasTextRelocations";
    // Adjust the memory protection to its to allow modifications.
    if (program_table_->AdjustMemoryProtectionOfReadOnlySegments(
            kSbMemoryMapProtectWrite) < 0) {
      SB_LOG(ERROR) << "Unable to make segments writable";
      return false;
    }
  }
  SB_DLOG(INFO) << "Loaded relocations";
  if (!relocations_->ApplyAllRelocations()) {
    SB_LOG(ERROR) << "Failed to apply relocations";
    return false;
  }

  if (relocations_->HasTextRelocations()) {
    // Restores the memory protection to its original state.
    if (program_table_->AdjustMemoryProtectionOfReadOnlySegments(
            kSbMemoryMapProtectReserved) < 0) {
      SB_LOG(ERROR) << "Unable to restore segment protection";
      return false;
    }
  }

  SB_DLOG(INFO) << "Applied relocations";

  auto metrics_extension =
      static_cast<const StarboardExtensionLoaderAppMetricsApi*>(
          SbSystemGetExtension(kStarboardExtensionLoaderAppMetricsName));
  if (metrics_extension &&
      strcmp(metrics_extension->name,
             kStarboardExtensionLoaderAppMetricsName) == 0 &&
      metrics_extension->version >= 2) {
    // CPU memory use is likely the highest at this point of the ELF loading
    // process, and observations support this. This value is therefore recorded
    // here in an attempt to efficiently approximate the maximum CPU memory used
    // at any point during loading of the ELF dynamic shared library.
    metrics_extension->RecordUsedCpuBytesDuringElfLoad(
        SbSystemGetUsedCPUMemory());
  }

  program_table_->PublishEvergreenInfo(name);
  SB_DLOG(INFO) << "Published Evergreen Info";

  SB_DLOG(INFO) << "Call constructors";
  dynamic_section_->CallConstructors();

  SB_DLOG(INFO) << "Finished loading";

  return true;
}
void* ElfLoaderImpl::LookupSymbol(const char* symbol) {
  const Sym* sym = dynamic_section_->LookupByName(symbol);
  void* address = NULL;
  if (sym) {
    address = reinterpret_cast<void*>(program_table_->GetBaseMemoryAddress() +
                                      sym->st_value);
  }
  return address;
}

ElfLoaderImpl::~ElfLoaderImpl() {
  if (dynamic_section_) {
    dynamic_section_->CallDestructors();
  }
}
}  // namespace elf_loader
}  // namespace starboard
