/*
 * Copyright (C) 2016 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_debug_writer.h"

#include <vector>
#include <unordered_map>

#include "base/array_ref.h"
#include "debug/dwarf/dwarf_constants.h"
#include "debug/elf_compilation_unit.h"
#include "debug/elf_debug_frame_writer.h"
#include "debug/elf_debug_info_writer.h"
#include "debug/elf_debug_line_writer.h"
#include "debug/elf_debug_loc_writer.h"
#include "debug/elf_gnu_debugdata_writer.h"
#include "debug/elf_symtab_writer.h"
#include "debug/method_debug_info.h"
#include "linker/elf_builder.h"
#include "linker/vector_output_stream.h"
#include "oat.h"

namespace art {
namespace debug {

template <typename ElfTypes>
void WriteDebugInfo(linker::ElfBuilder<ElfTypes>* builder,
                    const ArrayRef<const MethodDebugInfo>& method_infos,
                    dwarf::CFIFormat cfi_format,
                    bool write_oat_patches) {
  // Write .strtab and .symtab.
  WriteDebugSymbols(builder, method_infos, true /* with_signature */);

  // Write .debug_frame.
  WriteCFISection(builder, method_infos, cfi_format, write_oat_patches);

  // Group the methods into compilation units based on class.
  std::unordered_map<const DexFile::ClassDef*, ElfCompilationUnit> class_to_compilation_unit;
  for (const MethodDebugInfo& mi : method_infos) {
    if (mi.dex_file != nullptr) {
      auto& dex_class_def = mi.dex_file->GetClassDef(mi.class_def_index);
      ElfCompilationUnit& cu = class_to_compilation_unit[&dex_class_def];
      cu.methods.push_back(&mi);
      // All methods must have the same addressing mode otherwise the min/max below does not work.
      DCHECK_EQ(cu.methods.front()->is_code_address_text_relative, mi.is_code_address_text_relative);
      cu.is_code_address_text_relative = mi.is_code_address_text_relative;
      cu.code_address = std::min(cu.code_address, mi.code_address);
      cu.code_end = std::max(cu.code_end, mi.code_address + mi.code_size);
    }
  }

  // Sort compilation units to make the compiler output deterministic.
  std::vector<ElfCompilationUnit> compilation_units;
  compilation_units.reserve(class_to_compilation_unit.size());
  for (auto& it : class_to_compilation_unit) {
    // The .debug_line section requires the methods to be sorted by code address.
    std::stable_sort(it.second.methods.begin(),
                     it.second.methods.end(),
                     [](const MethodDebugInfo* a, const MethodDebugInfo* b) {
                         return a->code_address < b->code_address;
                     });
    compilation_units.push_back(std::move(it.second));
  }
  std::sort(compilation_units.begin(),
            compilation_units.end(),
            [](ElfCompilationUnit& a, ElfCompilationUnit& b) {
                // Sort by index of the first method within the method_infos array.
                // This assumes that the order of method_infos is deterministic.
                // Code address is not good for sorting due to possible duplicates.
                return a.methods.front() < b.methods.front();
            });

  // Write .debug_line section.
  if (!compilation_units.empty()) {
    ElfDebugLineWriter<ElfTypes> line_writer(builder);
    line_writer.Start();
    for (auto& compilation_unit : compilation_units) {
      line_writer.WriteCompilationUnit(compilation_unit);
    }
    line_writer.End(write_oat_patches);
  }

  // Write .debug_info section.
  if (!compilation_units.empty()) {
    ElfDebugInfoWriter<ElfTypes> info_writer(builder);
    info_writer.Start();
    for (const auto& compilation_unit : compilation_units) {
      ElfCompilationUnitWriter<ElfTypes> cu_writer(&info_writer);
      cu_writer.Write(compilation_unit);
    }
    info_writer.End(write_oat_patches);
  }
}

std::vector<uint8_t> MakeMiniDebugInfo(
    InstructionSet isa,
    const InstructionSetFeatures* features,
    size_t rodata_size,
    size_t text_size,
    const ArrayRef<const MethodDebugInfo>& method_infos) {
  if (Is64BitInstructionSet(isa)) {
    return MakeMiniDebugInfoInternal<ElfTypes64>(isa,
                                                 features,
                                                 rodata_size,
                                                 text_size,
                                                 method_infos);
  } else {
    return MakeMiniDebugInfoInternal<ElfTypes32>(isa,
                                                 features,
                                                 rodata_size,
                                                 text_size,
                                                 method_infos);
  }
}

template <typename ElfTypes>
static std::vector<uint8_t> WriteDebugElfFileForMethodsInternal(
    InstructionSet isa,
    const InstructionSetFeatures* features,
    const ArrayRef<const MethodDebugInfo>& method_infos) {
  std::vector<uint8_t> buffer;
  buffer.reserve(KB);
  linker::VectorOutputStream out("Debug ELF file", &buffer);
  std::unique_ptr<linker::ElfBuilder<ElfTypes>> builder(
      new linker::ElfBuilder<ElfTypes>(isa, features, &out));
  // No program headers since the ELF file is not linked and has no allocated sections.
  builder->Start(false /* write_program_headers */);
  WriteDebugInfo(builder.get(),
                 method_infos,
                 dwarf::DW_DEBUG_FRAME_FORMAT,
                 false /* write_oat_patches */);
  builder->End();
  CHECK(builder->Good());
  return buffer;
}

std::vector<uint8_t> WriteDebugElfFileForMethods(
    InstructionSet isa,
    const InstructionSetFeatures* features,
    const ArrayRef<const MethodDebugInfo>& method_infos) {
  if (Is64BitInstructionSet(isa)) {
    return WriteDebugElfFileForMethodsInternal<ElfTypes64>(isa, features, method_infos);
  } else {
    return WriteDebugElfFileForMethodsInternal<ElfTypes32>(isa, features, method_infos);
  }
}

template <typename ElfTypes>
static std::vector<uint8_t> WriteDebugElfFileForClassesInternal(
    InstructionSet isa,
    const InstructionSetFeatures* features,
    const ArrayRef<mirror::Class*>& types)
    REQUIRES_SHARED(Locks::mutator_lock_) {
  std::vector<uint8_t> buffer;
  buffer.reserve(KB);
  linker::VectorOutputStream out("Debug ELF file", &buffer);
  std::unique_ptr<linker::ElfBuilder<ElfTypes>> builder(
      new linker::ElfBuilder<ElfTypes>(isa, features, &out));
  // No program headers since the ELF file is not linked and has no allocated sections.
  builder->Start(false /* write_program_headers */);
  ElfDebugInfoWriter<ElfTypes> info_writer(builder.get());
  info_writer.Start();
  ElfCompilationUnitWriter<ElfTypes> cu_writer(&info_writer);
  cu_writer.Write(types);
  info_writer.End(false /* write_oat_patches */);

  builder->End();
  CHECK(builder->Good());
  return buffer;
}

std::vector<uint8_t> WriteDebugElfFileForClasses(InstructionSet isa,
                                                 const InstructionSetFeatures* features,
                                                 const ArrayRef<mirror::Class*>& types) {
  if (Is64BitInstructionSet(isa)) {
    return WriteDebugElfFileForClassesInternal<ElfTypes64>(isa, features, types);
  } else {
    return WriteDebugElfFileForClassesInternal<ElfTypes32>(isa, features, types);
  }
}

// Explicit instantiations
template void WriteDebugInfo<ElfTypes32>(
    linker::ElfBuilder<ElfTypes32>* builder,
    const ArrayRef<const MethodDebugInfo>& method_infos,
    dwarf::CFIFormat cfi_format,
    bool write_oat_patches);
template void WriteDebugInfo<ElfTypes64>(
    linker::ElfBuilder<ElfTypes64>* builder,
    const ArrayRef<const MethodDebugInfo>& method_infos,
    dwarf::CFIFormat cfi_format,
    bool write_oat_patches);

}  // namespace debug
}  // namespace art
