// Copyright (c) 2017, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

#include "vm/dwarf.h"

#include "vm/code_comments.h"
#include "vm/code_descriptors.h"
#include "vm/dwarf_so_writer.h"
#include "vm/elf.h"
#include "vm/image_snapshot.h"
#include "vm/object_store.h"
#include "vm/version.h"

namespace dart {

#if defined(DART_PRECOMPILER)

DEFINE_FLAG(bool,
            resolve_dwarf_paths,
            false,
            "Resolve script URIs to absolute or relative file paths in DWARF");

DEFINE_FLAG(charp,
            write_code_comments_as_synthetic_source_to,
            nullptr,
            "Print comments associated with instructions into the given file");

class DwarfPosition {
 public:
  DwarfPosition(int32_t line, int32_t column) : line_(line), column_(column) {
    // Should only have no line information if also no column information.
    ASSERT(line_ > kNoLine || column_ <= kNoColumn);
  }
  // CodeSourceMaps start the line and column registers at -1, not at 0, and
  // the arguments passed to ChangePosition are retrieved from CodeSourceMaps.
  explicit DwarfPosition(int32_t line) : DwarfPosition(line, -1) {}
  constexpr DwarfPosition() : line_(-1), column_(-1) {}

  // The DWARF standard uses 0 to denote missing line or column
  // information.
  static constexpr int32_t kNoLine = 0;
  static constexpr int32_t kNoColumn = 0;

  int32_t line() const { return line_ > kNoLine ? line_ : kNoLine; }
  int32_t column() const { return column_ > kNoColumn ? column_ : kNoColumn; }

  // Adjusts the contents given the arguments to a ChangePosition instruction
  // from CodeSourceMaps.
  void ChangePosition(int32_t line_delta, int32_t new_column) {
    line_ = Utils::AddWithWrapAround(line_, line_delta);
    column_ = new_column;
  }

 private:
  int32_t line_;
  int32_t column_;
};

static constexpr auto kNoDwarfPositionInfo = DwarfPosition();

class InliningNode : public ZoneAllocated {
 public:
  InliningNode(const Function& function,
               const DwarfPosition& position,
               int32_t start_pc_offset)
      : function(function),
        position(position),
        start_pc_offset(start_pc_offset),
        end_pc_offset(-1),
        children_head(nullptr),
        children_tail(nullptr),
        children_next(nullptr) {
    ASSERT(!function.IsNull());
    DEBUG_ASSERT(function.IsNotTemporaryScopedHandle());
  }

  void AppendChild(InliningNode* child) {
    if (children_tail == nullptr) {
      children_head = children_tail = child;
    } else {
      children_tail->children_next = child;
      children_tail = child;
    }
  }

  const Function& function;
  DwarfPosition position;
  int32_t start_pc_offset;
  int32_t end_pc_offset;
  InliningNode* children_head;
  InliningNode* children_tail;
  InliningNode* children_next;
};

static const char* GetRootLibraryName(Zone* zone) {
  const auto& root_library = Library::Handle(
      zone, IsolateGroup::Current()->object_store()->root_library());
  const auto& root_uri = String::Handle(zone, root_library.url());
  return root_uri.ToCString();
}

Dwarf::Dwarf(Zone* zone,
             const Trie<const char>* deobfuscation_trie,
             const char* compilation_unit_name)
    : zone_(zone),
      compilation_unit_name_(compilation_unit_name != nullptr
                                 ? compilation_unit_name
                                 : GetRootLibraryName(zone)),
      deobfuscation_trie_(deobfuscation_trie),
      codes_(zone, 1024),
      code_to_label_(zone),
      functions_(zone, 1024),
      function_to_index_(zone),
      scripts_(zone, 1024),
      script_to_index_(zone) {}

void Dwarf::AddCode(const Code& orig_code, intptr_t label) {
  ASSERT(!orig_code.IsNull());
  ASSERT(label > 0);

  if (auto const old_pair = code_to_label_.Lookup(&orig_code)) {
    // Dwarf objects can be shared, so we may get the same information for a
    // given code object in different calls. In DEBUG mode, make sure the
    // information is the same before returning.
    ASSERT_EQUAL(label, old_pair->value);
    return;
  }

  // Generate an appropriately zoned ZoneHandle for storing.
  const auto& code = Code::ZoneHandle(zone_, orig_code.ptr());
  codes_.Add(&code);
  // Currently assumes the name has the same lifetime as the Zone of the
  // Dwarf object (which is currently true).  Otherwise, need to copy.
  code_to_label_.Insert({&code, label});

  if (code.IsFunctionCode() && !code.IsUnknownDartCode()) {
    const Function& function = Function::Handle(zone_, code.function());
    AddFunction(function);
  }
  const Array& inline_functions =
      Array::Handle(zone_, code.inlined_id_to_function());
  if (!inline_functions.IsNull()) {
    Function& function = Function::Handle(zone_);
    for (intptr_t i = 0; i < inline_functions.Length(); i++) {
      function ^= inline_functions.At(i);
      AddFunction(function);
    }
  }
}

intptr_t Dwarf::AddFunction(const Function& function) {
  RELEASE_ASSERT(!function.IsNull());
  FunctionIndexPair* pair = function_to_index_.Lookup(&function);
  if (pair != nullptr) {
    return pair->index_;
  }
  intptr_t index = functions_.length();
  const Function& zone_func = Function::ZoneHandle(zone_, function.ptr());
  function_to_index_.Insert(FunctionIndexPair(&zone_func, index));
  functions_.Add(&zone_func);
  const Script& script = Script::Handle(zone_, function.script());
  AddScript(script);
  return index;
}

intptr_t Dwarf::AddScript(const Script& script) {
  RELEASE_ASSERT(!script.IsNull());
  ScriptIndexPair* pair = script_to_index_.Lookup(&script);
  if (pair != nullptr) {
    return pair->index_;
  }
  // DWARF file numbers start from 1.
  intptr_t index = scripts_.length() + 1;
  const Script& zone_script = Script::ZoneHandle(zone_, script.ptr());
  script_to_index_.Insert(ScriptIndexPair(&zone_script, index));
  scripts_.Add(&zone_script);
  return index;
}

intptr_t Dwarf::LookupFunction(const Function& function) {
  RELEASE_ASSERT(!function.IsNull());
  FunctionIndexPair* pair = function_to_index_.Lookup(&function);
  if (pair == nullptr) {
    FATAL("Function detected too late during DWARF generation: %s",
          function.ToCString());
  }
  return pair->index_;
}

intptr_t Dwarf::LookupScript(const Script& script) {
  RELEASE_ASSERT(!script.IsNull());
  ScriptIndexPair* pair = script_to_index_.Lookup(&script);
  if (pair == nullptr) {
    FATAL("Script detected too late during DWARF generation: %s",
          script.ToCString());
  }
  return pair->index_;
}

void Dwarf::WriteAbbreviations(DwarfWriteStream* stream) {
  // Dwarf data mostly takes the form of a tree, whose nodes are called
  // DIEs. Each DIE begins with an abbreviation code, and the abbreviation
  // describes the attributes of that DIE and their representation.

  stream->uleb128(kCompilationUnit);     // Abbrev code.
  stream->uleb128(DW_TAG_compile_unit);  // Type.
  stream->u1(DW_CHILDREN_yes);
  stream->uleb128(DW_AT_name);  // Start of attributes.
  stream->uleb128(DW_FORM_string);
  stream->uleb128(DW_AT_producer);
  stream->uleb128(DW_FORM_string);
  stream->uleb128(DW_AT_comp_dir);
  stream->uleb128(DW_FORM_string);
  stream->uleb128(DW_AT_low_pc);
  stream->uleb128(DW_FORM_addr);
  stream->uleb128(DW_AT_high_pc);
  stream->uleb128(DW_FORM_addr);
  stream->uleb128(DW_AT_stmt_list);
  stream->uleb128(DW_FORM_sec_offset);
  stream->uleb128(0);
  stream->uleb128(0);  // End of attributes.

  stream->uleb128(kAbstractFunction);  // Abbrev code.
  stream->uleb128(DW_TAG_subprogram);  // Type.
  stream->u1(DW_CHILDREN_yes);
  stream->uleb128(DW_AT_name);  // Start of attributes.
  stream->uleb128(DW_FORM_string);
  stream->uleb128(DW_AT_decl_file);
  stream->uleb128(DW_FORM_udata);
  stream->uleb128(DW_AT_decl_line);
  stream->uleb128(DW_FORM_udata);
  stream->uleb128(DW_AT_decl_column);
  stream->uleb128(DW_FORM_udata);
  stream->uleb128(DW_AT_inline);
  stream->uleb128(DW_FORM_udata);
  stream->uleb128(0);
  stream->uleb128(0);  // End of attributes.

  stream->uleb128(kConcreteFunction);  // Abbrev code.
  stream->uleb128(DW_TAG_subprogram);  // Type.
  stream->u1(DW_CHILDREN_yes);
  stream->uleb128(DW_AT_abstract_origin);  // Start of attributes.
  stream->uleb128(DW_FORM_ref4);
  stream->uleb128(DW_AT_low_pc);
  stream->uleb128(DW_FORM_addr);
  stream->uleb128(DW_AT_high_pc);
  stream->uleb128(DW_FORM_addr);
  stream->uleb128(DW_AT_artificial);
  stream->uleb128(DW_FORM_flag);
  stream->uleb128(0);
  stream->uleb128(0);  // End of attributes.

  stream->uleb128(kInlinedFunction);           // Abbrev code.
  stream->uleb128(DW_TAG_inlined_subroutine);  // Type.
  stream->u1(DW_CHILDREN_yes);
  stream->uleb128(DW_AT_abstract_origin);  // Start of attributes.
  stream->uleb128(DW_FORM_ref4);
  stream->uleb128(DW_AT_low_pc);
  stream->uleb128(DW_FORM_addr);
  stream->uleb128(DW_AT_high_pc);
  stream->uleb128(DW_FORM_addr);
  stream->uleb128(DW_AT_call_file);
  stream->uleb128(DW_FORM_udata);
  stream->uleb128(DW_AT_call_line);
  stream->uleb128(DW_FORM_udata);
  stream->uleb128(DW_AT_call_column);
  stream->uleb128(DW_FORM_udata);
  stream->uleb128(DW_AT_artificial);
  stream->uleb128(DW_FORM_flag);
  stream->uleb128(0);
  stream->uleb128(0);  // End of attributes.

  stream->uleb128(0);  // End of abbreviations.
}

void Dwarf::WriteDebugInfo(DwarfWriteStream* stream) {
  // 7.5.1.1 Compilation Unit Header

  // Unit length.
  stream->WritePrefixedLength("cu", [&]() {
    stream->u2(2);                            // DWARF version 2
    stream->u4(0);                            // debug_abbrev_offset
    stream->u1(compiler::target::kWordSize);  // address_size

    // Compilation Unit DIE. We describe the entire Dart program as a single
    // compilation unit. Note we write attributes in the same order we declared
    // them in our abbreviation above in WriteAbbreviations.
    stream->uleb128(kCompilationUnit);
    stream->string(compilation_unit_name_);  // DW_AT_name
    const char* producer = zone_->PrintToString("Dart %s\n", Version::String());
    stream->string(producer);  // DW_AT_producer
    stream->string("");        // DW_AT_comp_dir

    // DW_AT_low_pc
    // The lowest instruction address in this object file that is part of our
    // compilation unit. Dwarf consumers use this to quickly decide which
    // compilation unit DIE to consult for a given pc.
    auto const isolate_instructions_label = ImageWriter::SectionLabel(
        ImageWriter::ProgramSection::Text, /*vm=*/false);
    stream->OffsetFromSymbol(isolate_instructions_label, 0);

    // DW_AT_high_pc
    // The highest instruction address in this object file that is part of our
    // compilation unit. Dwarf consumers use this to quickly decide which
    // compilation unit DIE to consult for a given pc.
    if (codes_.is_empty()) {
      // No code objects in this program, so set high_pc to same as low_pc.
      stream->OffsetFromSymbol(isolate_instructions_label, 0);
    } else {
      const Code& last_code = *codes_.Last();
      auto const last_code_label = code_to_label_.LookupValue(&last_code);
      ASSERT(last_code_label > 0);
      stream->OffsetFromSymbol(last_code_label, last_code.Size());
    }

    // DW_AT_stmt_list (offset into .debug_line)
    // Indicates which line number program is associated with this compilation
    // unit. We only emit a single line number program.
    stream->u4(0);

    WriteAbstractFunctions(stream);
    WriteConcreteFunctions(stream);

    stream->uleb128(0);  // End of children.

    stream->uleb128(0);  // End of entries.
  });
}

void Dwarf::WriteAbstractFunctions(DwarfWriteStream* stream) {
  Script& script = Script::Handle(zone_);
  String& name = String::Handle(zone_);
  stream->InitializeAbstractOrigins(functions_.length());
  // By the point we're creating DWARF information, scripts have already lost
  // their token stream and we can't look up their line number or column
  // information, hence the lack of DW_AT_decl_line and DW_AT_decl_column.
  for (intptr_t i = 0; i < functions_.length(); i++) {
    const Function& function = *(functions_[i]);
    name = function.QualifiedUserVisibleName();
    script = function.script();
    const intptr_t file = LookupScript(script);
    intptr_t line = 0;
    intptr_t column = 0;
    script.GetTokenLocation(function.token_pos(), &line, &column);

    auto const name_cstr =
        ImageWriter::Deobfuscate(zone_, deobfuscation_trie_, name.ToCString());

    stream->RegisterAbstractOrigin(i);
    stream->uleb128(kAbstractFunction);
    stream->string(name_cstr);        // DW_AT_name
    stream->uleb128(file);            // DW_AT_decl_file
    stream->uleb128(line);            // DW_AT_decl_line
    stream->uleb128(column);          // DW_AT_decl_column
    stream->uleb128(DW_INL_inlined);  // DW_AT_inline
    stream->uleb128(0);               // End of children.
  }
}

void Dwarf::WriteConcreteFunctions(DwarfWriteStream* stream) {
  Function& function = Function::Handle(zone_);
  Script& script = Script::Handle(zone_);
  for (intptr_t i = 0; i < codes_.length(); i++) {
    const Code& code = *(codes_[i]);
    RELEASE_ASSERT(!code.IsNull());
    if (!code.IsFunctionCode() || code.IsUnknownDartCode()) {
      continue;
    }

    function = code.function();
    intptr_t function_index = LookupFunction(function);
    script = function.script();
    intptr_t label = code_to_label_.LookupValue(&code);
    ASSERT(label > 0);

    stream->uleb128(kConcreteFunction);
    // DW_AT_abstract_origin
    // References a node written above in WriteAbstractFunctions.
    stream->AbstractOrigin(function_index);

    // DW_AT_low_pc
    stream->OffsetFromSymbol(label, 0);
    // DW_AT_high_pc
    stream->OffsetFromSymbol(label, code.Size());
    // DW_AT_artificial
    stream->u1(function.is_visible() ? 0 : 1);

    InliningNode* node = ExpandInliningTree(code);
    if (node != nullptr) {
      for (InliningNode* child = node->children_head; child != nullptr;
           child = child->children_next) {
        WriteInliningNode(stream, child, label, script);
      }
    }

    stream->uleb128(0);  // End of children.
  }
}

// Our state machine encodes position metadata such that we don't know the
// end pc for an inlined function until it is popped, but DWARF DIEs encode
// it where the function is pushed. We expand the state transitions into
// an in-memory tree to do the conversion.
InliningNode* Dwarf::ExpandInliningTree(const Code& code) {
  const CodeSourceMap& map =
      CodeSourceMap::Handle(zone_, code.code_source_map());
  if (map.IsNull()) {
    return nullptr;
  }
  const Array& functions = Array::Handle(zone_, code.inlined_id_to_function());
  const Function& root_function = Function::ZoneHandle(zone_, code.function());
  if (root_function.IsNull()) {
    FATAL("Wherefore art thou functionless code, %s?\n", code.ToCString());
  }

  GrowableArray<InliningNode*> node_stack(zone_, 4);
  GrowableArray<DwarfPosition> token_positions(zone_, 4);

  NoSafepointScope no_safepoint;
  ReadStream stream(map.Data(), map.Length());

  int32_t current_pc_offset = 0;
  token_positions.Add(kNoDwarfPositionInfo);
  InliningNode* root_node =
      new (zone_) InliningNode(root_function, token_positions.Last(), 0);
  root_node->end_pc_offset = code.Size();
  node_stack.Add(root_node);

  while (stream.PendingBytes() > 0) {
    int32_t arg1;
    int32_t arg2 = -1;
    const uint8_t opcode = CodeSourceMapOps::Read(&stream, &arg1, &arg2);
    switch (opcode) {
      case CodeSourceMapOps::kChangePosition: {
        DwarfPosition& pos = token_positions[token_positions.length() - 1];
        pos.ChangePosition(arg1, arg2);
        break;
      }
      case CodeSourceMapOps::kAdvancePC: {
        current_pc_offset += arg1;
        if (arg1 == 0) {
          // This happens at the start of the function where we emit a special
          // kAdvancePC 0 instruction to record information about the function
          // itself. We need to advance current_pc_offset a bit to prevent
          // starting inlining interval directy at the start of the function
          // itself.
          current_pc_offset += 1;
        }
        break;
      }
      case CodeSourceMapOps::kPushFunction: {
        const Function& child_func =
            Function::ZoneHandle(zone_, Function::RawCast(functions.At(arg1)));
        InliningNode* child_node = new (zone_)
            InliningNode(child_func, token_positions.Last(), current_pc_offset);
        node_stack.Last()->AppendChild(child_node);
        node_stack.Add(child_node);
        token_positions.Add(kNoDwarfPositionInfo);
        break;
      }
      case CodeSourceMapOps::kPopFunction: {
        // We never pop the root function.
        ASSERT(node_stack.length() > 1);
        ASSERT(token_positions.length() > 1);
        node_stack.Last()->end_pc_offset = current_pc_offset;
        node_stack.RemoveLast();
        token_positions.RemoveLast();
        break;
      }
      case CodeSourceMapOps::kNullCheck: {
        break;
      }
      default:
        UNREACHABLE();
    }
  }

  while (node_stack.length() > 1) {
    node_stack.Last()->end_pc_offset = current_pc_offset;
    node_stack.RemoveLast();
    token_positions.RemoveLast();
  }
  ASSERT(node_stack[0] == root_node);
  return root_node;
}

void Dwarf::WriteInliningNode(DwarfWriteStream* stream,
                              InliningNode* node,
                              intptr_t root_label,
                              const Script& parent_script) {
  ASSERT(root_label > 0);
  intptr_t file = LookupScript(parent_script);
  intptr_t function_index = LookupFunction(node->function);
  const Script& script = Script::Handle(zone_, node->function.script());

  stream->uleb128(kInlinedFunction);
  // DW_AT_abstract_origin
  // References a node written above in WriteAbstractFunctions.
  stream->AbstractOrigin(function_index);

  // DW_AT_low_pc
  stream->OffsetFromSymbol(root_label, node->start_pc_offset);
  // DW_AT_high_pc
  stream->OffsetFromSymbol(root_label, node->end_pc_offset);
  // DW_AT_call_file
  stream->uleb128(file);

  // DW_AT_call_line
  stream->uleb128(node->position.line());
  // DW_AT_call_column
  stream->uleb128(node->position.column());
  // DW_AT_artificial
  stream->u1(node->function.is_visible() ? 0 : 1);

  for (InliningNode* child = node->children_head; child != nullptr;
       child = child->children_next) {
    WriteInliningNode(stream, child, root_label, script);
  }

  stream->uleb128(0);  // End of children.
}

// Helper class for tracking state of DWARF registers and emitting
// line number program commands to set these registers to the right
// state.
class LineNumberProgramWriter {
 public:
  explicit LineNumberProgramWriter(DwarfWriteStream* stream)
      : stream_(stream) {}

  void EmitRow(intptr_t file,
               intptr_t line,
               intptr_t column,
               intptr_t label,
               intptr_t pc_offset) {
    if (AddRow(file, line, column, label, pc_offset)) {
      // Address register must be updated from 0 before emitting an LNP row
      // (dartbug.com/41756).
      stream_->u1(Dwarf::DW_LNS_copy);
    }
  }

  // Associates the given file, line, and column information for the instruction
  // at the pc_offset into the instructions payload of the Code object with the
  // symbol asm_name. Returns whether any changes were made to the stream.
  DART_WARN_UNUSED_RESULT bool AddRow(intptr_t file,
                                      intptr_t line,
                                      intptr_t column,
                                      intptr_t label,
                                      intptr_t pc_offset) {
    ASSERT_EQUAL(end_sequence_, false);
    bool source_info_changed = false;
    // Note that files are 1-indexed.
    ASSERT(file >= 1);
    if (file != file_) {
      stream_->u1(Dwarf::DW_LNS_set_file);
      stream_->uleb128(file);
      file_ = file;
      source_info_changed = true;
    }
    ASSERT(line >= DwarfPosition::kNoLine);
    if (line != line_) {
      stream_->u1(Dwarf::DW_LNS_advance_line);
      stream_->sleb128(line - line_);
      line_ = line;
      source_info_changed = true;
    }
    ASSERT(column >= DwarfPosition::kNoColumn);
    if (column != column_) {
      stream_->u1(Dwarf::DW_LNS_set_column);
      stream_->uleb128(column);
      column_ = column;
      source_info_changed = true;
    }
    // If the file, line, and column information match that for the previous
    // AddRow call, no change is made to the stream. This is because all
    // addresses between two line number program rows inherit the source
    // information from the first.
    if (source_info_changed) {
      SetCurrentPosition(label, pc_offset);
    }
    return source_info_changed;
  }

  void MarkEnd() {
    ASSERT_EQUAL(end_sequence_, false);
    // End of contiguous machine code.
    stream_->u1(0);  // This is an extended opcode
    stream_->u1(1);  // that is 1 byte long
    stream_->u1(Dwarf::DW_LNE_end_sequence);
    end_sequence_ = true;
  }

  void MarkEnd(intptr_t label, intptr_t pc_offset) {
    ASSERT_EQUAL(end_sequence_, false);
    SetCurrentPosition(label, pc_offset);
    MarkEnd();
  }

 private:
  void SetCurrentPosition(intptr_t label, intptr_t pc_offset) {
    // Each LNP row is either in a different function from the previous row
    // or is at an increasing PC offset into the same function.
    ASSERT(label > 0);
    ASSERT(pc_offset >= 0);
    ASSERT(label_ != label || pc_offset > pc_offset_);
    if (label_ != label) {
      // Set the address register to the given offset into the new code payload.
      auto const instr_size = 1 + compiler::target::kWordSize;
      stream_->u1(0);           // This is an extended opcode
      stream_->u1(instr_size);  // that is 5 or 9 bytes long
      stream_->u1(Dwarf::DW_LNE_set_address);
      stream_->OffsetFromSymbol(label, pc_offset);
    } else {
      // Change the address register by the difference in the two offsets.
      stream_->u1(Dwarf::DW_LNS_advance_pc);
      stream_->uleb128(pc_offset - pc_offset_);
    }
    label_ = label;
    pc_offset_ = pc_offset;
  }

  DwarfWriteStream* const stream_;
  // The initial values for the line number program state machine registers
  // according to the DWARF standard.
  intptr_t pc_offset_ = 0;
  intptr_t file_ = 1;
  intptr_t line_ = 1;
  intptr_t column_ = 0;
  bool end_sequence_ = false;

  // Other info not stored in the state machine registers.
  intptr_t label_ = 0;
};

void Dwarf::WriteSyntheticLineNumberProgram(LineNumberProgramWriter* writer) {
  // We emit it last after all other scripts.
  const intptr_t comments_file_index = scripts_.length() + 1;

  auto file_open = Dart::file_open_callback();
  auto file_write = Dart::file_write_callback();
  auto file_close = Dart::file_close_callback();
  if ((file_open == nullptr) || (file_write == nullptr) ||
      (file_close == nullptr)) {
    OS::PrintErr("warning: Could not access file callbacks.");
    return;
  }

  TextBuffer comments_buffer(128 * KB);

  const char* filename = FLAG_write_code_comments_as_synthetic_source_to;
  void* comments_file = file_open(filename, /*write=*/true);
  if (comments_file == nullptr) {
    OS::PrintErr("warning: Failed to write code comments source: %s\n",
                 filename);
    return;
  }

  // Lines in DWARF are 1-indexed.
  intptr_t current_line = 1;

  for (intptr_t i = 0; i < codes_.length(); i++) {
    const Code& code = *(codes_[i]);
    auto const label = code_to_label_.LookupValue(&code);
    ASSERT(label > 0);

    auto& comments = code.comments();
    for (intptr_t i = 0, len = comments.Length(); i < len;) {
      intptr_t current_pc_offset = comments.PCOffsetAt(i);
      while (i < len && current_pc_offset == comments.PCOffsetAt(i)) {
        comments_buffer.AddString(comments.CommentAt(i));
        comments_buffer.AddChar('\n');
        current_line++;
        i++;
      }
      writer->EmitRow(comments_file_index, current_line - 1,
                      DwarfPosition::kNoColumn, label, current_pc_offset);
    }
  }

  file_write(comments_buffer.buffer(), comments_buffer.length(), comments_file);
  file_close(comments_file);
}

void Dwarf::WriteLineNumberProgramFromCodeSourceMaps(
    LineNumberProgramWriter* writer) {
  Function& root_function = Function::Handle(zone_);
  Script& script = Script::Handle(zone_);
  CodeSourceMap& map = CodeSourceMap::Handle(zone_);
  Array& functions = Array::Handle(zone_);
  GrowableArray<const Function*> function_stack(zone_, 8);
  GrowableArray<DwarfPosition> token_positions(zone_, 8);

  for (intptr_t i = 0; i < codes_.length(); i++) {
    const Code& code = *(codes_[i]);
    auto const label = code_to_label_.LookupValue(&code);
    ASSERT(label > 0);

    map = code.code_source_map();
    if (map.IsNull()) {
      continue;
    }
    root_function = code.function();
    functions = code.inlined_id_to_function();

    NoSafepointScope no_safepoint;
    ReadStream code_map_stream(map.Data(), map.Length());

    function_stack.Clear();
    token_positions.Clear();

    // CodeSourceMap might start in the following way:
    //
    //   ChangePosition function.token_pos()
    //   AdvancePC 0
    //   ChangePosition x
    //   AdvancePC y
    //
    // This entry is emitted to ensure correct symbolization of
    // function listener frames produced by async unwinding.
    // (See EmitFunctionEntrySourcePositionDescriptorIfNeeded).
    // Directly interpreting this sequence would cause us to emit
    // multiple with the same pc into line number table and different
    // position information. To avoid this will make an adjustment for
    // the second record we emit: if position x is a synthetic one we will
    // simply drop the second record, if position x is real then we will
    // emit row with a slightly adjusted PC (by 1 byte). This would not
    // affect symbolization (you can't have a call that is 1 byte long)
    // but will avoid line number table entries with the same PC.
    bool function_entry_position_was_emitted = false;

    int32_t current_pc_offset = 0;
    function_stack.Add(&root_function);
    token_positions.Add(kNoDwarfPositionInfo);

    while (code_map_stream.PendingBytes() > 0) {
      int32_t arg1;
      int32_t arg2 = -1;
      const uint8_t opcode =
          CodeSourceMapOps::Read(&code_map_stream, &arg1, &arg2);
      switch (opcode) {
        case CodeSourceMapOps::kChangePosition: {
          DwarfPosition& pos = token_positions[token_positions.length() - 1];
          pos.ChangePosition(arg1, arg2);
          break;
        }
        case CodeSourceMapOps::kAdvancePC: {
          // Emit a row for the previous PC value if the source location
          // changed since the last row was emitted.
          const Function& function = *(function_stack.Last());
          script = function.script();
          const intptr_t file = LookupScript(script);
          const intptr_t line = token_positions.Last().line();
          const intptr_t column = token_positions.Last().column();
          intptr_t pc_offset_adjustment = 0;
          bool should_emit = true;

          // If we are at the function entry and have already emitted a row
          // then adjust current_pc_offset to avoid duplicated entries.
          // See the comment below which explains why this code is here.
          if (current_pc_offset == 0 && function_entry_position_was_emitted) {
            pc_offset_adjustment = 1;
            // Ignore synthetic positions. Function entry position gives
            // more information anyway.
            should_emit = !(line == 0 && column == 0);
          }

          if (should_emit) {
            writer->EmitRow(file, line, column, label,
                            current_pc_offset + pc_offset_adjustment);
          }

          current_pc_offset += arg1;
          if (arg1 == 0) {  // Special case of AdvancePC 0.
            ASSERT(current_pc_offset == 0);
            ASSERT(!function_entry_position_was_emitted);
            function_entry_position_was_emitted = true;
          }
          break;
        }
        case CodeSourceMapOps::kPushFunction: {
          auto child_func =
              &Function::Handle(zone_, Function::RawCast(functions.At(arg1)));
          function_stack.Add(child_func);
          token_positions.Add(kNoDwarfPositionInfo);
          break;
        }
        case CodeSourceMapOps::kPopFunction: {
          // We never pop the root function.
          ASSERT(function_stack.length() > 1);
          ASSERT(token_positions.length() > 1);
          function_stack.RemoveLast();
          token_positions.RemoveLast();
          break;
        }
        case CodeSourceMapOps::kNullCheck: {
          break;
        }
        default:
          UNREACHABLE();
      }
    }
  }
}

static constexpr char kResolvedFileRoot[] = "file:///";
static constexpr intptr_t kResolvedFileRootLen = sizeof(kResolvedFileRoot) - 1;
static constexpr char kResolvedFlutterRoot[] = "org-dartlang-sdk:///flutter/";
static constexpr intptr_t kResolvedFlutterRootLen =
    sizeof(kResolvedFlutterRoot) - 1;
static constexpr char kResolvedSdkRoot[] = "org-dartlang-sdk:///";
static constexpr intptr_t kResolvedSdkRootLen = sizeof(kResolvedSdkRoot) - 1;
static constexpr char kResolvedGoogle3Root[] = "google3:///";
static constexpr intptr_t kResolvedGoogle3RootLen =
    sizeof(kResolvedGoogle3Root) - 1;

static const char* ConvertResolvedURI(const char* str) {
  const intptr_t len = strlen(str);
  if (len > kResolvedFileRootLen &&
      strncmp(str, kResolvedFileRoot, kResolvedFileRootLen) == 0) {
#if defined(DART_HOST_OS_WINDOWS)
    return str + kResolvedFileRootLen;  // Strip off the entire prefix.
#else
    return str + kResolvedFileRootLen - 1;  // Leave a '/' on the front.
#endif
  }
  // Must do kResolvedFlutterRoot before kResolvedSdkRoot, since the latter is
  // a prefix of the former.
  if (len > kResolvedFlutterRootLen &&
      strncmp(str, kResolvedFlutterRoot, kResolvedFlutterRootLen) == 0) {
    return str + kResolvedFlutterRootLen;  // Strip off the entire prefix.
  }
  if (len > kResolvedSdkRootLen &&
      strncmp(str, kResolvedSdkRoot, kResolvedSdkRootLen) == 0) {
    return str + kResolvedSdkRootLen;  // Strip off the entire prefix.
  }
  if (len > kResolvedGoogle3RootLen &&
      strncmp(str, kResolvedGoogle3Root, kResolvedGoogle3RootLen) == 0) {
    return str + kResolvedGoogle3RootLen;  // Strip off the entire prefix.
  }
  return nullptr;
}

void Dwarf::WriteLineNumberProgram(DwarfWriteStream* stream) {
  // 6.2.4 The Line Number Program Header

  // 1. unit_length. This encoding implies 32-bit DWARF.
  stream->WritePrefixedLength("line", [&]() {
    stream->u2(2);  // 2. DWARF version 2

    // 3. header_length
    stream->WritePrefixedLength("lineheader", [&]() {
      stream->u1(1);   // 4. minimum_instruction_length
      stream->u1(1);   // 5. default_is_stmt (true for dsymutil compatibility).
      stream->u1(0);   // 6. line_base
      stream->u1(1);   // 7. line_range
      stream->u1(13);  // 8. opcode_base (12 standard opcodes in Dwarf 2)

      // 9. standard_opcode_lengths
      stream->u1(0);  // DW_LNS_copy, 0 operands
      stream->u1(1);  // DW_LNS_advance_pc, 1 operands
      stream->u1(1);  // DW_LNS_advance_list, 1 operands
      stream->u1(1);  // DW_LNS_set_file, 1 operands
      stream->u1(1);  // DW_LNS_set_column, 1 operands
      stream->u1(0);  // DW_LNS_negate_stmt, 0 operands
      stream->u1(0);  // DW_LNS_set_basic_block, 0 operands
      stream->u1(0);  // DW_LNS_const_add_pc, 0 operands
      stream->u1(1);  // DW_LNS_fixed_advance_pc, 1 operands
      stream->u1(0);  // DW_LNS_set_prolog_end, 0 operands
      stream->u1(0);  // DW_LNS_set_epilogue_begin, 0 operands
      stream->u1(1);  // DW_LNS_set_isa, 1 operands

      // 10. include_directories (sequence of path names)
      // We don't emit any because we use full paths below.
      stream->u1(0);

      // 11. file_names (sequence of file entries)
      String& uri = String::Handle(zone_);
      for (intptr_t i = 0; i < scripts_.length(); i++) {
        const Script& script = *(scripts_[i]);
        const char* uri_cstr = nullptr;
        if (FLAG_resolve_dwarf_paths) {
          uri = script.resolved_url();
          // Strictly enforce this to catch unresolvable cases.
          if (uri.IsNull()) {
            FATAL("no resolved URI for Script %s available",
                  script.ToCString());
          }
          // resolved_url is never obfuscated, so just convert the prefix.
          auto const orig_cstr = uri.ToCString();
          auto const converted_cstr = ConvertResolvedURI(orig_cstr);
          // Strictly enforce this to catch inconvertible cases.
          if (converted_cstr == nullptr) {
            FATAL("cannot convert resolved URI %s", orig_cstr);
          }
          uri_cstr = converted_cstr;
        } else {
          uri = script.url();
          ASSERT(!uri.IsNull());
          uri_cstr = ImageWriter::Deobfuscate(zone_, deobfuscation_trie_,
                                              uri.ToCString());
        }
        RELEASE_ASSERT(strlen(uri_cstr) != 0);

        stream->string(uri_cstr);  // NOLINT
        stream->uleb128(0);        // Include directory index.
        stream->uleb128(0);        // File modification time.
        stream->uleb128(0);        // File length.
      }
      if (FLAG_write_code_comments_as_synthetic_source_to != nullptr) {
        stream->string(  // NOLINT
            FLAG_write_code_comments_as_synthetic_source_to);
        stream->uleb128(0);  // Include directory index.
        stream->uleb128(0);  // File modification time.
        stream->uleb128(0);  // File length.
      }
      stream->u1(0);  // End of file names.
    });

    // 6.2.5 The Line Number Program
    LineNumberProgramWriter lnp_writer(stream);
    if (FLAG_write_code_comments_as_synthetic_source_to != nullptr) {
      WriteSyntheticLineNumberProgram(&lnp_writer);
    } else {
      WriteLineNumberProgramFromCodeSourceMaps(&lnp_writer);
    }

    // Advance pc to end of the compilation unit if not already there.
    if (codes_.length() != 0) {
      const intptr_t last_code_index = codes_.length() - 1;
      const Code& last_code = *(codes_[last_code_index]);
      const intptr_t last_pc_offset = last_code.Size();
      auto const last_label = code_to_label_.LookupValue(&last_code);
      ASSERT(last_label > 0);
      lnp_writer.MarkEnd(last_label, last_pc_offset);
    } else {
      lnp_writer.MarkEnd();
    }
  });
}

#if !defined(TARGET_ARCH_IA32)
void Dwarf::WriteCallFrameInformationRecords(
    DwarfSharedObjectStream* stream,
    const GrowableArray<FrameDescriptionEntry>& fdes) {
  ASSERT(!fdes.is_empty());

#if defined(TARGET_ARCH_X64)
  // The x86_64 psABI defines the DWARF register numbers, which differ from
  // the registers' usual encoding within instructions.
  const intptr_t DWARF_RA = 16;  // No corresponding register.
  const intptr_t DWARF_FP = 6;   // RBP
#else
  const intptr_t DWARF_RA = ConcreteRegister(LINK_REGISTER);
  const intptr_t DWARF_FP = FP;
#endif

  // Multiplier which will be used to scale operands of DW_CFA_offset and
  // DW_CFA_val_offset.
  const intptr_t kDataAlignment = -compiler::target::kWordSize;

  // Used to calculate offset to CIE in FDEs.
  const intptr_t cie_start = stream->Position();
  stream->WritePrefixedLength([&] {
    stream->u4(0);  // CIE
    stream->u1(1);  // Version (must be 1 or 3)
    // Augmentation String
    stream->string("zR");             // NOLINT
    stream->uleb128(1);               // Code alignment (must be 1).
    stream->sleb128(kDataAlignment);  // Data alignment
    stream->u1(DWARF_RA);             // Return address register
    stream->uleb128(1);               // Augmentation size
    stream->u1(DW_EH_PE_pcrel | DW_EH_PE_sdata4);  // FDE encoding.
    // CFA is caller's SP (FP+kCallerSpSlotFromFp*kWordSize)
    stream->u1(Dwarf::DW_CFA_def_cfa);
    stream->uleb128(DWARF_FP);
    stream->uleb128(kCallerSpSlotFromFp * compiler::target::kWordSize);
  });

  // Emit rule defining that |reg| value is stored at CFA+offset.
  const auto cfa_offset = [&](intptr_t reg, intptr_t offset) {
    const intptr_t scaled_offset = offset / kDataAlignment;
    RELEASE_ASSERT(scaled_offset >= 0);
    stream->u1(Dwarf::DW_CFA_offset | reg);
    stream->uleb128(scaled_offset);
  };

  // Emit an FDE covering each .text section.
  for (const auto& fde : fdes) {
#if defined(DART_TARGET_OS_WINDOWS) && defined(TARGET_ARCH_IS_64_BIT)
    if (fde.label == 0) {
      // Unwinding instructions sections doesn't have label, doesn't dwarf
      continue;
    }
#endif
    ASSERT(fde.label != 0);  // Needed for relocations.
    stream->WritePrefixedLength([&]() {
      // Offset to CIE. Note that unlike pcrel this offset is encoded
      // backwards: it will be subtracted from the current position.
      stream->u4(stream->Position() - cie_start);
      // Start address as a PC relative reference.
      stream->RelativeSymbolOffset(fde.label, kInt32Size);
      stream->u4(fde.size);  // Size.
      stream->u1(0);         // Augmentation Data length.

      // Caller FP at FP+kSavedCallerPcSlotFromFp*kWordSize,
      // where FP is CFA - kCallerSpSlotFromFp*kWordSize.
      COMPILE_ASSERT((kSavedCallerFpSlotFromFp - kCallerSpSlotFromFp) <= 0);
      cfa_offset(DWARF_FP, (kSavedCallerFpSlotFromFp - kCallerSpSlotFromFp) *
                               compiler::target::kWordSize);

      // Caller LR at FP+kSavedCallerPcSlotFromFp*kWordSize,
      // where FP is CFA - kCallerSpSlotFromFp*kWordSize
      COMPILE_ASSERT((kSavedCallerPcSlotFromFp - kCallerSpSlotFromFp) <= 0);
      cfa_offset(DWARF_RA, (kSavedCallerPcSlotFromFp - kCallerSpSlotFromFp) *
                               compiler::target::kWordSize);
    });
  }

  stream->u4(0);  // end of section (FDE with zero length)
}
#endif

#endif  // DART_PRECOMPILER

}  // namespace dart
