// 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/memory.h"
#include "starboard/string.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";

  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() {
  dynamic_section_->CallDestructors();
}
}  // namespace elf_loader
}  // namespace starboard
