/*
 * Copyright (C) 2012 The Android Open Source Project
 *
 * 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 "elf_writer_quick.h"

#include <memory>
#include <openssl/sha.h>

#include <android-base/logging.h>

#include "base/casts.h"
#include "base/globals.h"
#include "base/leb128.h"
#include "base/utils.h"
#include "debug/elf_debug_writer.h"
#include "debug/method_debug_info.h"
#include "driver/compiler_options.h"
#include "elf/elf_builder.h"
#include "elf/elf_utils.h"
#include "stream/buffered_output_stream.h"
#include "stream/file_output_stream.h"
#include "thread-current-inl.h"
#include "thread_pool.h"

namespace art {
namespace linker {

class DebugInfoTask : public Task {
 public:
  DebugInfoTask(InstructionSet isa,
                const InstructionSetFeatures* features,
                uint64_t text_section_address,
                size_t text_section_size,
                uint64_t dex_section_address,
                size_t dex_section_size,
                const debug::DebugInfo& debug_info)
      : isa_(isa),
        instruction_set_features_(features),
        text_section_address_(text_section_address),
        text_section_size_(text_section_size),
        dex_section_address_(dex_section_address),
        dex_section_size_(dex_section_size),
        debug_info_(debug_info) {
  }

  void Run(Thread*) override {
    result_ = debug::MakeMiniDebugInfo(isa_,
                                       instruction_set_features_,
                                       text_section_address_,
                                       text_section_size_,
                                       dex_section_address_,
                                       dex_section_size_,
                                       debug_info_);
  }

  std::vector<uint8_t>* GetResult() {
    return &result_;
  }

 private:
  InstructionSet isa_;
  const InstructionSetFeatures* instruction_set_features_;
  uint64_t text_section_address_;
  size_t text_section_size_;
  uint64_t dex_section_address_;
  size_t dex_section_size_;
  const debug::DebugInfo& debug_info_;
  std::vector<uint8_t> result_;
};

template <typename ElfTypes>
class ElfWriterQuick final : public ElfWriter {
 public:
  ElfWriterQuick(const CompilerOptions& compiler_options,
                 File* elf_file);
  ~ElfWriterQuick();

  void Start() override;
  void PrepareDynamicSection(size_t rodata_size,
                             size_t text_size,
                             size_t data_bimg_rel_ro_size,
                             size_t bss_size,
                             size_t bss_methods_offset,
                             size_t bss_roots_offset,
                             size_t dex_section_size) override;
  void PrepareDebugInfo(const debug::DebugInfo& debug_info) override;
  OutputStream* StartRoData() override;
  void EndRoData(OutputStream* rodata) override;
  OutputStream* StartText() override;
  void EndText(OutputStream* text) override;
  OutputStream* StartDataBimgRelRo() override;
  void EndDataBimgRelRo(OutputStream* data_bimg_rel_ro) override;
  void WriteDynamicSection() override;
  void WriteDebugInfo(const debug::DebugInfo& debug_info) override;
  bool StripDebugInfo() override;
  bool End() override;

  OutputStream* GetStream() override;

  size_t GetLoadedSize() override;

  static void EncodeOatPatches(const std::vector<uintptr_t>& locations,
                               std::vector<uint8_t>* buffer);

 private:
  const CompilerOptions& compiler_options_;
  File* const elf_file_;
  size_t rodata_size_;
  size_t text_size_;
  size_t data_bimg_rel_ro_size_;
  size_t bss_size_;
  size_t dex_section_size_;
  std::unique_ptr<BufferedOutputStream> output_stream_;
  std::unique_ptr<ElfBuilder<ElfTypes>> builder_;
  std::unique_ptr<DebugInfoTask> debug_info_task_;
  std::unique_ptr<ThreadPool> debug_info_thread_pool_;

  void ComputeFileBuildId(uint8_t (*build_id)[ElfBuilder<ElfTypes>::kBuildIdLen]);

  DISALLOW_IMPLICIT_CONSTRUCTORS(ElfWriterQuick);
};

std::unique_ptr<ElfWriter> CreateElfWriterQuick(const CompilerOptions& compiler_options,
                                                File* elf_file) {
  if (Is64BitInstructionSet(compiler_options.GetInstructionSet())) {
    return std::make_unique<ElfWriterQuick<ElfTypes64>>(compiler_options, elf_file);
  } else {
    return std::make_unique<ElfWriterQuick<ElfTypes32>>(compiler_options, elf_file);
  }
}

template <typename ElfTypes>
ElfWriterQuick<ElfTypes>::ElfWriterQuick(const CompilerOptions& compiler_options, File* elf_file)
    : ElfWriter(),
      compiler_options_(compiler_options),
      elf_file_(elf_file),
      rodata_size_(0u),
      text_size_(0u),
      data_bimg_rel_ro_size_(0u),
      bss_size_(0u),
      dex_section_size_(0u),
      output_stream_(
          std::make_unique<BufferedOutputStream>(std::make_unique<FileOutputStream>(elf_file))),
      builder_(new ElfBuilder<ElfTypes>(compiler_options_.GetInstructionSet(),
                                        output_stream_.get())) {}

template <typename ElfTypes>
ElfWriterQuick<ElfTypes>::~ElfWriterQuick() {}

template <typename ElfTypes>
void ElfWriterQuick<ElfTypes>::Start() {
  builder_->Start();
  if (compiler_options_.GetGenerateBuildId()) {
    builder_->GetBuildId()->AllocateVirtualMemory(builder_->GetBuildId()->GetSize());
    builder_->WriteBuildIdSection();
  }
}

template <typename ElfTypes>
void ElfWriterQuick<ElfTypes>::PrepareDynamicSection(size_t rodata_size,
                                                     size_t text_size,
                                                     size_t data_bimg_rel_ro_size,
                                                     size_t bss_size,
                                                     size_t bss_methods_offset,
                                                     size_t bss_roots_offset,
                                                     size_t dex_section_size) {
  DCHECK_EQ(rodata_size_, 0u);
  rodata_size_ = rodata_size;
  DCHECK_EQ(text_size_, 0u);
  text_size_ = text_size;
  DCHECK_EQ(data_bimg_rel_ro_size_, 0u);
  data_bimg_rel_ro_size_ = data_bimg_rel_ro_size;
  DCHECK_EQ(bss_size_, 0u);
  bss_size_ = bss_size;
  DCHECK_EQ(dex_section_size_, 0u);
  dex_section_size_ = dex_section_size;
  builder_->PrepareDynamicSection(elf_file_->GetPath(),
                                  rodata_size_,
                                  text_size_,
                                  data_bimg_rel_ro_size_,
                                  bss_size_,
                                  bss_methods_offset,
                                  bss_roots_offset,
                                  dex_section_size);
}

template <typename ElfTypes>
OutputStream* ElfWriterQuick<ElfTypes>::StartRoData() {
  auto* rodata = builder_->GetRoData();
  rodata->Start();
  return rodata;
}

template <typename ElfTypes>
void ElfWriterQuick<ElfTypes>::EndRoData(OutputStream* rodata) {
  CHECK_EQ(builder_->GetRoData(), rodata);
  builder_->GetRoData()->End();
}

template <typename ElfTypes>
OutputStream* ElfWriterQuick<ElfTypes>::StartText() {
  auto* text = builder_->GetText();
  text->Start();
  return text;
}

template <typename ElfTypes>
void ElfWriterQuick<ElfTypes>::EndText(OutputStream* text) {
  CHECK_EQ(builder_->GetText(), text);
  builder_->GetText()->End();
}

template <typename ElfTypes>
OutputStream* ElfWriterQuick<ElfTypes>::StartDataBimgRelRo() {
  auto* data_bimg_rel_ro = builder_->GetDataBimgRelRo();
  data_bimg_rel_ro->Start();
  return data_bimg_rel_ro;
}

template <typename ElfTypes>
void ElfWriterQuick<ElfTypes>::EndDataBimgRelRo(OutputStream* data_bimg_rel_ro) {
  CHECK_EQ(builder_->GetDataBimgRelRo(), data_bimg_rel_ro);
  builder_->GetDataBimgRelRo()->End();
}

template <typename ElfTypes>
void ElfWriterQuick<ElfTypes>::WriteDynamicSection() {
  builder_->WriteDynamicSection();
}

template <typename ElfTypes>
void ElfWriterQuick<ElfTypes>::PrepareDebugInfo(const debug::DebugInfo& debug_info) {
  if (compiler_options_.GetGenerateMiniDebugInfo()) {
    // Prepare the mini-debug-info in background while we do other I/O.
    Thread* self = Thread::Current();
    debug_info_task_ = std::make_unique<DebugInfoTask>(
        builder_->GetIsa(),
        compiler_options_.GetInstructionSetFeatures(),
        builder_->GetText()->GetAddress(),
        text_size_,
        builder_->GetDex()->Exists() ? builder_->GetDex()->GetAddress() : 0,
        dex_section_size_,
        debug_info);
    debug_info_thread_pool_.reset(ThreadPool::Create("Mini-debug-info writer", 1));
    debug_info_thread_pool_->AddTask(self, debug_info_task_.get());
    debug_info_thread_pool_->StartWorkers(self);
  }
}

template <typename ElfTypes>
void ElfWriterQuick<ElfTypes>::WriteDebugInfo(const debug::DebugInfo& debug_info) {
  if (compiler_options_.GetGenerateMiniDebugInfo()) {
    // If mini-debug-info wasn't explicitly created so far, create it now (happens in tests).
    if (debug_info_task_ == nullptr) {
      PrepareDebugInfo(debug_info);
    }
    // Wait for the mini-debug-info generation to finish and write it to disk.
    Thread* self = Thread::Current();
    DCHECK(debug_info_thread_pool_ != nullptr);
    debug_info_thread_pool_->Wait(self, true, false);
    builder_->WriteSection(".gnu_debugdata", debug_info_task_->GetResult());
  }
  // The Strip method expects debug info to be last (mini-debug-info is not stripped).
  if (!debug_info.Empty() && compiler_options_.GetGenerateDebugInfo()) {
    // Generate all the debug information we can.
    debug::WriteDebugInfo(builder_.get(), debug_info);
  }
}

template <typename ElfTypes>
bool ElfWriterQuick<ElfTypes>::StripDebugInfo() {
  off_t file_size = builder_->Strip();
  return elf_file_->SetLength(file_size) == 0;
}

template <typename ElfTypes>
bool ElfWriterQuick<ElfTypes>::End() {
  builder_->End();
  if (compiler_options_.GetGenerateBuildId()) {
    uint8_t build_id[ElfBuilder<ElfTypes>::kBuildIdLen];
    ComputeFileBuildId(&build_id);
    builder_->WriteBuildId(build_id);
  }
  return builder_->Good();
}

template <typename ElfTypes>
void ElfWriterQuick<ElfTypes>::ComputeFileBuildId(
    uint8_t (*build_id)[ElfBuilder<ElfTypes>::kBuildIdLen]) {
  constexpr int kBufSize = 8192;
  std::vector<char> buffer(kBufSize);
  int64_t offset = 0;
  SHA_CTX ctx;
  SHA1_Init(&ctx);
  while (true) {
    int64_t bytes_read = elf_file_->Read(buffer.data(), kBufSize, offset);
    CHECK_GE(bytes_read, 0);
    if (bytes_read == 0) {
      // End of file.
      break;
    }
    SHA1_Update(&ctx, buffer.data(), bytes_read);
    offset += bytes_read;
  }
  SHA1_Final(*build_id, &ctx);
}

template <typename ElfTypes>
OutputStream* ElfWriterQuick<ElfTypes>::GetStream() {
  return builder_->GetStream();
}

template <typename ElfTypes>
size_t ElfWriterQuick<ElfTypes>::GetLoadedSize() {
  return builder_->GetLoadedSize();
}

// Explicit instantiations
template class ElfWriterQuick<ElfTypes32>;
template class ElfWriterQuick<ElfTypes64>;

}  // namespace linker
}  // namespace art
