/*
 * 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_ = std::make_unique<ThreadPool>("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
