diff --git a/compiler/dwarf/debug_frame_opcode_writer.h b/compiler/dwarf/debug_frame_opcode_writer.h
new file mode 100644
index 0000000..cc4ef8f
--- /dev/null
+++ b/compiler/dwarf/debug_frame_opcode_writer.h
@@ -0,0 +1,282 @@
+/*
+ * Copyright (C) 2015 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.
+ */
+
+#ifndef ART_COMPILER_DWARF_DEBUG_FRAME_OPCODE_WRITER_H_
+#define ART_COMPILER_DWARF_DEBUG_FRAME_OPCODE_WRITER_H_
+
+#include "dwarf.h"
+#include "register.h"
+#include "writer.h"
+
+namespace art {
+namespace dwarf {
+
+// Writer for .debug_frame opcodes (DWARF-3).
+// See the DWARF specification for the precise meaning of the opcodes.
+// The writer is very light-weight, however it will do the following for you:
+//  * Choose the most compact encoding of a given opcode.
+//  * Keep track of current state and convert absolute values to deltas.
+//  * Divide by header-defined factors as appropriate.
+template<typename Allocator = std::allocator<uint8_t> >
+class DebugFrameOpCodeWriter : private Writer<Allocator> {
+ public:
+  // To save space, DWARF divides most offsets by header-defined factors.
+  // They are used in integer divisions, so we make them constants.
+  // We usually subtract from stack base pointer, so making the factor
+  // negative makes the encoded values positive and thus easier to encode.
+  static constexpr int kDataAlignmentFactor = -4;
+  static constexpr int kCodeAlignmentFactor = 1;
+
+  // Explicitely advance the program counter to given location.
+  void AdvancePC(int absolute_pc) {
+    DCHECK_GE(absolute_pc, current_pc_);
+    int delta = FactorCodeOffset(absolute_pc - current_pc_);
+    if (delta != 0) {
+      if (delta <= 0x3F) {
+        this->PushUint8(DW_CFA_advance_loc | delta);
+      } else if (delta <= UINT8_MAX) {
+        this->PushUint8(DW_CFA_advance_loc1);
+        this->PushUint8(delta);
+      } else if (delta <= UINT16_MAX) {
+        this->PushUint8(DW_CFA_advance_loc2);
+        this->PushUint16(delta);
+      } else {
+        this->PushUint8(DW_CFA_advance_loc4);
+        this->PushUint32(delta);
+      }
+    }
+    current_pc_ = absolute_pc;
+  }
+
+  // Override this method to automatically advance the PC before each opcode.
+  virtual void ImplicitlyAdvancePC() { }
+
+  // Common alias in assemblers - spill relative to current stack pointer.
+  void RelOffset(Reg reg, int offset) {
+    Offset(reg, offset - current_cfa_offset_);
+  }
+
+  // Common alias in assemblers - increase stack frame size.
+  void AdjustCFAOffset(int delta) {
+    DefCFAOffset(current_cfa_offset_ + delta);
+  }
+
+  // Custom alias - spill many registers based on bitmask.
+  void RelOffsetForMany(Reg reg_base, int offset, uint32_t reg_mask,
+                        int reg_size) {
+    DCHECK(reg_size == 4 || reg_size == 8);
+    for (int i = 0; reg_mask != 0u; reg_mask >>= 1, i++) {
+      if ((reg_mask & 1) != 0u) {
+        RelOffset(Reg(reg_base.num() + i), offset);
+        offset += reg_size;
+      }
+    }
+  }
+
+  // Custom alias - unspill many registers based on bitmask.
+  void RestoreMany(Reg reg_base, uint32_t reg_mask) {
+    for (int i = 0; reg_mask != 0u; reg_mask >>= 1, i++) {
+      if ((reg_mask & 1) != 0u) {
+        Restore(Reg(reg_base.num() + i));
+      }
+    }
+  }
+
+  void Nop() {
+    this->PushUint8(DW_CFA_nop);
+  }
+
+  void Offset(Reg reg, int offset) {
+    ImplicitlyAdvancePC();
+    int factored_offset = FactorDataOffset(offset);  // May change sign.
+    if (factored_offset >= 0) {
+      if (0 <= reg.num() && reg.num() <= 0x3F) {
+        this->PushUint8(DW_CFA_offset | reg.num());
+        this->PushUleb128(factored_offset);
+      } else {
+        this->PushUint8(DW_CFA_offset_extended);
+        this->PushUleb128(reg.num());
+        this->PushUleb128(factored_offset);
+      }
+    } else {
+      uses_dwarf3_features_ = true;
+      this->PushUint8(DW_CFA_offset_extended_sf);
+      this->PushUleb128(reg.num());
+      this->PushSleb128(factored_offset);
+    }
+  }
+
+  void Restore(Reg reg) {
+    ImplicitlyAdvancePC();
+    if (0 <= reg.num() && reg.num() <= 0x3F) {
+      this->PushUint8(DW_CFA_restore | reg.num());
+    } else {
+      this->PushUint8(DW_CFA_restore_extended);
+      this->PushUleb128(reg.num());
+    }
+  }
+
+  void Undefined(Reg reg) {
+    ImplicitlyAdvancePC();
+    this->PushUint8(DW_CFA_undefined);
+    this->PushUleb128(reg.num());
+  }
+
+  void SameValue(Reg reg) {
+    ImplicitlyAdvancePC();
+    this->PushUint8(DW_CFA_same_value);
+    this->PushUleb128(reg.num());
+  }
+
+  // The previous value of "reg" is stored in register "new_reg".
+  void Register(Reg reg, Reg new_reg) {
+    ImplicitlyAdvancePC();
+    this->PushUint8(DW_CFA_register);
+    this->PushUleb128(reg.num());
+    this->PushUleb128(new_reg.num());
+  }
+
+  void RememberState() {
+    // Note that we do not need to advance the PC.
+    this->PushUint8(DW_CFA_remember_state);
+  }
+
+  void RestoreState() {
+    ImplicitlyAdvancePC();
+    this->PushUint8(DW_CFA_restore_state);
+  }
+
+  void DefCFA(Reg reg, int offset) {
+    ImplicitlyAdvancePC();
+    if (offset >= 0) {
+      this->PushUint8(DW_CFA_def_cfa);
+      this->PushUleb128(reg.num());
+      this->PushUleb128(offset);  // Non-factored.
+    } else {
+      uses_dwarf3_features_ = true;
+      this->PushUint8(DW_CFA_def_cfa_sf);
+      this->PushUleb128(reg.num());
+      this->PushSleb128(FactorDataOffset(offset));
+    }
+    current_cfa_offset_ = offset;
+  }
+
+  void DefCFARegister(Reg reg) {
+    ImplicitlyAdvancePC();
+    this->PushUint8(DW_CFA_def_cfa_register);
+    this->PushUleb128(reg.num());
+  }
+
+  void DefCFAOffset(int offset) {
+    if (current_cfa_offset_ != offset) {
+      ImplicitlyAdvancePC();
+      if (offset >= 0) {
+        this->PushUint8(DW_CFA_def_cfa_offset);
+        this->PushUleb128(offset);  // Non-factored.
+      } else {
+        uses_dwarf3_features_ = true;
+        this->PushUint8(DW_CFA_def_cfa_offset_sf);
+        this->PushSleb128(FactorDataOffset(offset));
+      }
+      current_cfa_offset_ = offset;
+    }
+  }
+
+  void ValOffset(Reg reg, int offset) {
+    ImplicitlyAdvancePC();
+    uses_dwarf3_features_ = true;
+    int factored_offset = FactorDataOffset(offset);  // May change sign.
+    if (factored_offset >= 0) {
+      this->PushUint8(DW_CFA_val_offset);
+      this->PushUleb128(reg.num());
+      this->PushUleb128(factored_offset);
+    } else {
+      this->PushUint8(DW_CFA_val_offset_sf);
+      this->PushUleb128(reg.num());
+      this->PushSleb128(factored_offset);
+    }
+  }
+
+  void DefCFAExpression(void* expr, int expr_size) {
+    ImplicitlyAdvancePC();
+    uses_dwarf3_features_ = true;
+    this->PushUint8(DW_CFA_def_cfa_expression);
+    this->PushUleb128(expr_size);
+    this->PushData(expr, expr_size);
+  }
+
+  void Expression(Reg reg, void* expr, int expr_size) {
+    ImplicitlyAdvancePC();
+    uses_dwarf3_features_ = true;
+    this->PushUint8(DW_CFA_expression);
+    this->PushUleb128(reg.num());
+    this->PushUleb128(expr_size);
+    this->PushData(expr, expr_size);
+  }
+
+  void ValExpression(Reg reg, void* expr, int expr_size) {
+    ImplicitlyAdvancePC();
+    uses_dwarf3_features_ = true;
+    this->PushUint8(DW_CFA_val_expression);
+    this->PushUleb128(reg.num());
+    this->PushUleb128(expr_size);
+    this->PushData(expr, expr_size);
+  }
+
+  int GetCurrentCFAOffset() const {
+    return current_cfa_offset_;
+  }
+
+  void SetCurrentCFAOffset(int offset) {
+    current_cfa_offset_ = offset;
+  }
+
+  using Writer<Allocator>::data;
+
+  DebugFrameOpCodeWriter(const Allocator& alloc = Allocator())
+      : Writer<Allocator>(&opcodes_),
+        opcodes_(alloc),
+        current_cfa_offset_(0),
+        current_pc_(0),
+        uses_dwarf3_features_(false) {
+  }
+
+  virtual ~DebugFrameOpCodeWriter() { }
+
+ protected:
+  int FactorDataOffset(int offset) const {
+    DCHECK_EQ(offset % kDataAlignmentFactor, 0);
+    return offset / kDataAlignmentFactor;
+  }
+
+  int FactorCodeOffset(int offset) const {
+    DCHECK_EQ(offset % kCodeAlignmentFactor, 0);
+    return offset / kCodeAlignmentFactor;
+  }
+
+  std::vector<uint8_t, Allocator> opcodes_;
+  int current_cfa_offset_;
+  int current_pc_;
+  bool uses_dwarf3_features_;
+
+ private:
+  DISALLOW_COPY_AND_ASSIGN(DebugFrameOpCodeWriter);
+};
+
+}  // namespace dwarf
+}  // namespace art
+
+#endif  // ART_COMPILER_DWARF_DEBUG_FRAME_OPCODE_WRITER_H_
diff --git a/compiler/dwarf/debug_frame_writer.h b/compiler/dwarf/debug_frame_writer.h
new file mode 100644
index 0000000..6de45f5
--- /dev/null
+++ b/compiler/dwarf/debug_frame_writer.h
@@ -0,0 +1,96 @@
+/*
+ * Copyright (C) 2015 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.
+ */
+
+#ifndef ART_COMPILER_DWARF_DEBUG_FRAME_WRITER_H_
+#define ART_COMPILER_DWARF_DEBUG_FRAME_WRITER_H_
+
+#include "debug_frame_opcode_writer.h"
+#include "dwarf.h"
+#include "writer.h"
+
+namespace art {
+namespace dwarf {
+
+// Writer for the .eh_frame section (which extends .debug_frame specification).
+template<typename Allocator = std::allocator<uint8_t>>
+class DebugFrameWriter FINAL : private Writer<Allocator> {
+ public:
+  void WriteCIE(Reg return_address_register,
+                const uint8_t* initial_opcodes,
+                int initial_opcodes_size) {
+    DCHECK(cie_header_start_ == ~0u);
+    cie_header_start_ = this->data()->size();
+    this->PushUint32(0);  // Length placeholder.
+    this->PushUint32(0);  // CIE id.
+    this->PushUint8(1);   // Version.
+    this->PushString("zR");
+    this->PushUleb128(DebugFrameOpCodeWriter<Allocator>::kCodeAlignmentFactor);
+    this->PushSleb128(DebugFrameOpCodeWriter<Allocator>::kDataAlignmentFactor);
+    this->PushUleb128(return_address_register.num());  // ubyte in DWARF2.
+    this->PushUleb128(1);  // z: Augmentation data size.
+    if (use_64bit_address_) {
+      this->PushUint8(0x04);  // R: ((DW_EH_PE_absptr << 4) | DW_EH_PE_udata8).
+    } else {
+      this->PushUint8(0x03);  // R: ((DW_EH_PE_absptr << 4) | DW_EH_PE_udata4).
+    }
+    this->PushData(initial_opcodes, initial_opcodes_size);
+    this->Pad(use_64bit_address_ ? 8 : 4);
+    this->UpdateUint32(cie_header_start_, this->data()->size() - cie_header_start_ - 4);
+  }
+
+  void WriteCIE(Reg return_address_register,
+                const DebugFrameOpCodeWriter<Allocator>& opcodes) {
+    WriteCIE(return_address_register, opcodes.data()->data(), opcodes.data()->size());
+  }
+
+  void WriteFDE(uint64_t initial_address,
+                uint64_t address_range,
+                const uint8_t* unwind_opcodes,
+                int unwind_opcodes_size) {
+    DCHECK(cie_header_start_ != ~0u);
+    size_t fde_header_start = this->data()->size();
+    this->PushUint32(0);  // Length placeholder.
+    this->PushUint32(this->data()->size() - cie_header_start_);  // 'CIE_pointer'
+    if (use_64bit_address_) {
+      this->PushUint64(initial_address);
+      this->PushUint64(address_range);
+    } else {
+      this->PushUint32(initial_address);
+      this->PushUint32(address_range);
+    }
+    this->PushUleb128(0);  // Augmentation data size.
+    this->PushData(unwind_opcodes, unwind_opcodes_size);
+    this->Pad(use_64bit_address_ ? 8 : 4);
+    this->UpdateUint32(fde_header_start, this->data()->size() - fde_header_start - 4);
+  }
+
+  DebugFrameWriter(std::vector<uint8_t, Allocator>* buffer, bool use_64bit_address)
+      : Writer<Allocator>(buffer),
+        use_64bit_address_(use_64bit_address),
+        cie_header_start_(~0u) {
+  }
+
+ private:
+  bool use_64bit_address_;
+  size_t cie_header_start_;
+
+  DISALLOW_COPY_AND_ASSIGN(DebugFrameWriter);
+};
+
+}  // namespace dwarf
+}  // namespace art
+
+#endif  // ART_COMPILER_DWARF_DEBUG_FRAME_WRITER_H_
diff --git a/compiler/dwarf/debug_line_opcode_writer.h b/compiler/dwarf/debug_line_opcode_writer.h
new file mode 100644
index 0000000..f34acee
--- /dev/null
+++ b/compiler/dwarf/debug_line_opcode_writer.h
@@ -0,0 +1,243 @@
+/*
+ * Copyright (C) 2015 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.
+ */
+
+#ifndef ART_COMPILER_DWARF_DEBUG_LINE_OPCODE_WRITER_H_
+#define ART_COMPILER_DWARF_DEBUG_LINE_OPCODE_WRITER_H_
+
+#include "dwarf.h"
+#include "writer.h"
+
+namespace art {
+namespace dwarf {
+
+// Writer for the .debug_line opcodes (DWARF-3).
+// The writer is very light-weight, however it will do the following for you:
+//  * Choose the most compact encoding of a given opcode.
+//  * Keep track of current state and convert absolute values to deltas.
+//  * Divide by header-defined factors as appropriate.
+template<typename Allocator = std::allocator<uint8_t>>
+class DebugLineOpCodeWriter FINAL : private Writer<Allocator> {
+ public:
+  static constexpr int kOpcodeBase = 13;
+  static constexpr bool kDefaultIsStmt = true;
+  static constexpr int kLineBase = -5;
+  static constexpr int kLineRange = 14;
+
+  void AddRow() {
+    this->PushUint8(DW_LNS_copy);
+  }
+
+  void AdvancePC(uint64_t absolute_address) {
+    DCHECK_NE(current_address_, 0u);  // Use SetAddress for the first advance.
+    DCHECK_GE(absolute_address, current_address_);
+    if (absolute_address != current_address_) {
+      uint64_t delta = FactorCodeOffset(absolute_address - current_address_);
+      if (delta <= INT32_MAX) {
+        this->PushUint8(DW_LNS_advance_pc);
+        this->PushUleb128(static_cast<int>(delta));
+        current_address_ = absolute_address;
+      } else {
+        SetAddress(absolute_address);
+      }
+    }
+  }
+
+  void AdvanceLine(int absolute_line) {
+    int delta = absolute_line - current_line_;
+    if (delta != 0) {
+      this->PushUint8(DW_LNS_advance_line);
+      this->PushSleb128(delta);
+      current_line_ = absolute_line;
+    }
+  }
+
+  void SetFile(int file) {
+    if (current_file_ != file) {
+      this->PushUint8(DW_LNS_set_file);
+      this->PushUleb128(file);
+      current_file_ = file;
+    }
+  }
+
+  void SetColumn(int column) {
+    this->PushUint8(DW_LNS_set_column);
+    this->PushUleb128(column);
+  }
+
+  void NegateStmt() {
+    this->PushUint8(DW_LNS_negate_stmt);
+  }
+
+  void SetBasicBlock() {
+    this->PushUint8(DW_LNS_set_basic_block);
+  }
+
+  void SetPrologueEnd() {
+    uses_dwarf3_features_ = true;
+    this->PushUint8(DW_LNS_set_prologue_end);
+  }
+
+  void SetEpilogueBegin() {
+    uses_dwarf3_features_ = true;
+    this->PushUint8(DW_LNS_set_epilogue_begin);
+  }
+
+  void SetISA(int isa) {
+    uses_dwarf3_features_ = true;
+    this->PushUint8(DW_LNS_set_isa);
+    this->PushUleb128(isa);
+  }
+
+  void EndSequence() {
+    this->PushUint8(0);
+    this->PushUleb128(1);
+    this->PushUint8(DW_LNE_end_sequence);
+    current_address_ = 0;
+    current_file_ = 1;
+    current_line_ = 1;
+  }
+
+  // Uncoditionally set address using the long encoding.
+  // This gives the linker opportunity to relocate the address.
+  void SetAddress(uint64_t absolute_address) {
+    DCHECK_GE(absolute_address, current_address_);
+    FactorCodeOffset(absolute_address);  // Check if it is factorable.
+    this->PushUint8(0);
+    if (use_64bit_address_) {
+      this->PushUleb128(1 + 8);
+      this->PushUint8(DW_LNE_set_address);
+      this->PushUint64(absolute_address);
+    } else {
+      this->PushUleb128(1 + 4);
+      this->PushUint8(DW_LNE_set_address);
+      this->PushUint32(absolute_address);
+    }
+    current_address_ = absolute_address;
+  }
+
+  void DefineFile(const char* filename,
+                  int directory_index,
+                  int modification_time,
+                  int file_size) {
+    int size = 1 +
+               strlen(filename) + 1 +
+               UnsignedLeb128Size(directory_index) +
+               UnsignedLeb128Size(modification_time) +
+               UnsignedLeb128Size(file_size);
+    this->PushUint8(0);
+    this->PushUleb128(size);
+    size_t start = data()->size();
+    this->PushUint8(DW_LNE_define_file);
+    this->PushString(filename);
+    this->PushUleb128(directory_index);
+    this->PushUleb128(modification_time);
+    this->PushUleb128(file_size);
+    DCHECK_EQ(start + size, data()->size());
+  }
+
+  // Compact address and line opcode.
+  void AddRow(uint64_t absolute_address, int absolute_line) {
+    DCHECK_GE(absolute_address, current_address_);
+
+    // If the address is definitely too far, use the long encoding.
+    uint64_t delta_address = FactorCodeOffset(absolute_address - current_address_);
+    if (delta_address > UINT8_MAX) {
+      AdvancePC(absolute_address);
+      delta_address = 0;
+    }
+
+    // If the line is definitely too far, use the long encoding.
+    int delta_line = absolute_line - current_line_;
+    if (!(kLineBase <= delta_line && delta_line < kLineBase + kLineRange)) {
+      AdvanceLine(absolute_line);
+      delta_line = 0;
+    }
+
+    // Both address and line should be reasonable now.  Use the short encoding.
+    int opcode = kOpcodeBase + (delta_line - kLineBase) +
+                 (static_cast<int>(delta_address) * kLineRange);
+    if (opcode > UINT8_MAX) {
+      // If the address is still too far, try to increment it by const amount.
+      int const_advance = (0xFF - kOpcodeBase) / kLineRange;
+      opcode -= (kLineRange * const_advance);
+      if (opcode <= UINT8_MAX) {
+        this->PushUint8(DW_LNS_const_add_pc);
+      } else {
+        // Give up and use long encoding for address.
+        AdvancePC(absolute_address);
+        // Still use the opcode to do line advance and copy.
+        opcode = kOpcodeBase + (delta_line - kLineBase);
+      }
+    }
+    DCHECK(kOpcodeBase <= opcode && opcode <= 0xFF);
+    this->PushUint8(opcode);  // Special opcode.
+    current_line_ = absolute_line;
+    current_address_ = absolute_address;
+  }
+
+  int GetCodeFactorBits() const {
+    return code_factor_bits_;
+  }
+
+  uint64_t CurrentAddress() const {
+    return current_address_;
+  }
+
+  int CurrentFile() const {
+    return current_file_;
+  }
+
+  int CurrentLine() const {
+    return current_line_;
+  }
+
+  using Writer<Allocator>::data;
+
+  DebugLineOpCodeWriter(bool use64bitAddress,
+                        int codeFactorBits,
+                        const Allocator& alloc = Allocator())
+      : Writer<Allocator>(&opcodes_),
+        opcodes_(alloc),
+        uses_dwarf3_features_(false),
+        use_64bit_address_(use64bitAddress),
+        code_factor_bits_(codeFactorBits),
+        current_address_(0),
+        current_file_(1),
+        current_line_(1) {
+  }
+
+ private:
+  uint64_t FactorCodeOffset(uint64_t offset) const {
+    DCHECK_GE(code_factor_bits_, 0);
+    DCHECK_EQ((offset >> code_factor_bits_) << code_factor_bits_, offset);
+    return offset >> code_factor_bits_;
+  }
+
+  std::vector<uint8_t, Allocator> opcodes_;
+  bool uses_dwarf3_features_;
+  bool use_64bit_address_;
+  int code_factor_bits_;
+  uint64_t current_address_;
+  int current_file_;
+  int current_line_;
+
+  DISALLOW_COPY_AND_ASSIGN(DebugLineOpCodeWriter);
+};
+
+}  // namespace dwarf
+}  // namespace art
+
+#endif  // ART_COMPILER_DWARF_DEBUG_LINE_OPCODE_WRITER_H_
diff --git a/compiler/dwarf/debug_line_writer.h b/compiler/dwarf/debug_line_writer.h
new file mode 100644
index 0000000..4b7d8d9
--- /dev/null
+++ b/compiler/dwarf/debug_line_writer.h
@@ -0,0 +1,87 @@
+/*
+ * Copyright (C) 2015 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.
+ */
+
+#ifndef ART_COMPILER_DWARF_DEBUG_LINE_WRITER_H_
+#define ART_COMPILER_DWARF_DEBUG_LINE_WRITER_H_
+
+#include "debug_line_opcode_writer.h"
+#include "dwarf.h"
+#include "writer.h"
+#include <string>
+
+namespace art {
+namespace dwarf {
+
+// Writer for the .debug_line section (DWARF-3).
+template<typename Allocator = std::allocator<uint8_t>>
+class DebugLineWriter FINAL : private Writer<Allocator> {
+ public:
+  struct FileEntry {
+    std::string file_name;
+    int directory_index;
+    int modification_time;
+    int file_size;
+  };
+
+  void WriteTable(const std::vector<std::string>& include_directories,
+                  const std::vector<FileEntry>& files,
+                  const DebugLineOpCodeWriter<Allocator>& opcodes) {
+    size_t header_start = this->data()->size();
+    this->PushUint32(0);  // Section-length placeholder.
+    // Claim DWARF-2 version even though we use some DWARF-3 features.
+    // DWARF-2 consumers will ignore the unknown opcodes.
+    // This is what clang currently does.
+    this->PushUint16(2);  // .debug_line version.
+    size_t header_length_pos = this->data()->size();
+    this->PushUint32(0);  // Header-length placeholder.
+    this->PushUint8(1 << opcodes.GetCodeFactorBits());
+    this->PushUint8(DebugLineOpCodeWriter<Allocator>::kDefaultIsStmt ? 1 : 0);
+    this->PushInt8(DebugLineOpCodeWriter<Allocator>::kLineBase);
+    this->PushUint8(DebugLineOpCodeWriter<Allocator>::kLineRange);
+    this->PushUint8(DebugLineOpCodeWriter<Allocator>::kOpcodeBase);
+    static const int opcode_lengths[DebugLineOpCodeWriter<Allocator>::kOpcodeBase] = {
+        0, 0, 1, 1, 1, 1, 0, 0, 0, 1, 0, 0, 1 };
+    for (int i = 1; i < DebugLineOpCodeWriter<Allocator>::kOpcodeBase; i++) {
+      this->PushUint8(opcode_lengths[i]);
+    }
+    for (const std::string& directory : include_directories) {
+      this->PushData(directory.data(), directory.size() + 1);
+    }
+    this->PushUint8(0);  // Terminate include_directories list.
+    for (const FileEntry& file : files) {
+      this->PushData(file.file_name.data(), file.file_name.size() + 1);
+      this->PushUleb128(file.directory_index);
+      this->PushUleb128(file.modification_time);
+      this->PushUleb128(file.file_size);
+    }
+    this->PushUint8(0);  // Terminate file list.
+    this->UpdateUint32(header_length_pos, this->data()->size() - header_length_pos - 4);
+    this->PushData(opcodes.data()->data(), opcodes.data()->size());
+    this->UpdateUint32(header_start, this->data()->size() - header_start - 4);
+  }
+
+  explicit DebugLineWriter(std::vector<uint8_t, Allocator>* buffer)
+    : Writer<Allocator>(buffer) {
+  }
+
+ private:
+  DISALLOW_COPY_AND_ASSIGN(DebugLineWriter);
+};
+
+}  // namespace dwarf
+}  // namespace art
+
+#endif  // ART_COMPILER_DWARF_DEBUG_LINE_WRITER_H_
diff --git a/compiler/dwarf/dwarf_test.cc b/compiler/dwarf/dwarf_test.cc
new file mode 100644
index 0000000..f3553bc
--- /dev/null
+++ b/compiler/dwarf/dwarf_test.cc
@@ -0,0 +1,235 @@
+/*
+ * Copyright (C) 2015 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 "dwarf_test.h"
+
+#include "dwarf/debug_frame_opcode_writer.h"
+#include "dwarf/debug_frame_writer.h"
+#include "dwarf/debug_line_opcode_writer.h"
+#include "dwarf/debug_line_writer.h"
+#include "gtest/gtest.h"
+
+namespace art {
+namespace dwarf {
+
+// Run the tests only on host since we need objdump.
+#ifndef HAVE_ANDROID_OS
+
+TEST_F(DwarfTest, DebugFrame) {
+  const bool is64bit = false;
+
+  // Pick offset value which would catch Uleb vs Sleb errors.
+  const int offset = 40000;
+  ASSERT_EQ(UnsignedLeb128Size(offset / 4), 2u);
+  ASSERT_EQ(SignedLeb128Size(offset / 4), 3u);
+  DW_CHECK("Data alignment factor: -4");
+  const Reg reg(6);
+
+  // Test the opcodes in the order mentioned in the spec.
+  // There are usually several encoding variations of each opcode.
+  DebugFrameOpCodeWriter<> opcodes;
+  DW_CHECK("FDE");
+  int pc = 0;
+  for (int i : {0, 1, 0x3F, 0x40, 0xFF, 0x100, 0xFFFF, 0x10000}) {
+    pc += i;
+    opcodes.AdvancePC(pc);
+  }
+  DW_CHECK_NEXT("DW_CFA_advance_loc: 1 to 01000001");
+  DW_CHECK_NEXT("DW_CFA_advance_loc: 63 to 01000040");
+  DW_CHECK_NEXT("DW_CFA_advance_loc1: 64 to 01000080");
+  DW_CHECK_NEXT("DW_CFA_advance_loc1: 255 to 0100017f");
+  DW_CHECK_NEXT("DW_CFA_advance_loc2: 256 to 0100027f");
+  DW_CHECK_NEXT("DW_CFA_advance_loc2: 65535 to 0101027e");
+  DW_CHECK_NEXT("DW_CFA_advance_loc4: 65536 to 0102027e");
+  opcodes.DefCFA(reg, offset);
+  DW_CHECK_NEXT("DW_CFA_def_cfa: r6 (esi) ofs 40000");
+  opcodes.DefCFA(reg, -offset);
+  DW_CHECK_NEXT("DW_CFA_def_cfa_sf: r6 (esi) ofs -40000");
+  opcodes.DefCFARegister(reg);
+  DW_CHECK_NEXT("DW_CFA_def_cfa_register: r6 (esi)");
+  opcodes.DefCFAOffset(offset);
+  DW_CHECK_NEXT("DW_CFA_def_cfa_offset: 40000");
+  opcodes.DefCFAOffset(-offset);
+  DW_CHECK_NEXT("DW_CFA_def_cfa_offset_sf: -40000");
+  uint8_t expr[] = { 0 };
+  opcodes.DefCFAExpression(expr, arraysize(expr));
+  DW_CHECK_NEXT("DW_CFA_def_cfa_expression");
+  opcodes.Undefined(reg);
+  DW_CHECK_NEXT("DW_CFA_undefined: r6 (esi)");
+  opcodes.SameValue(reg);
+  DW_CHECK_NEXT("DW_CFA_same_value: r6 (esi)");
+  opcodes.Offset(Reg(0x3F), -offset);
+  // Bad register likely means that it does not exist on x86,
+  // but we want to test high register numbers anyway.
+  DW_CHECK_NEXT("DW_CFA_offset: bad register: r63 at cfa-40000");
+  opcodes.Offset(Reg(0x40), -offset);
+  DW_CHECK_NEXT("DW_CFA_offset_extended: bad register: r64 at cfa-40000");
+  opcodes.Offset(Reg(0x40), offset);
+  DW_CHECK_NEXT("DW_CFA_offset_extended_sf: bad register: r64 at cfa+40000");
+  opcodes.ValOffset(reg, -offset);
+  DW_CHECK_NEXT("DW_CFA_val_offset: r6 (esi) at cfa-40000");
+  opcodes.ValOffset(reg, offset);
+  DW_CHECK_NEXT("DW_CFA_val_offset_sf: r6 (esi) at cfa+40000");
+  opcodes.Register(reg, Reg(1));
+  DW_CHECK_NEXT("DW_CFA_register: r6 (esi) in r1 (ecx)");
+  opcodes.Expression(reg, expr, arraysize(expr));
+  DW_CHECK_NEXT("DW_CFA_expression: r6 (esi)");
+  opcodes.ValExpression(reg, expr, arraysize(expr));
+  DW_CHECK_NEXT("DW_CFA_val_expression: r6 (esi)");
+  opcodes.Restore(Reg(0x3F));
+  DW_CHECK_NEXT("DW_CFA_restore: bad register: r63");
+  opcodes.Restore(Reg(0x40));
+  DW_CHECK_NEXT("DW_CFA_restore_extended: bad register: r64");
+  opcodes.Restore(reg);
+  DW_CHECK_NEXT("DW_CFA_restore: r6 (esi)");
+  opcodes.RememberState();
+  DW_CHECK_NEXT("DW_CFA_remember_state");
+  opcodes.RestoreState();
+  DW_CHECK_NEXT("DW_CFA_restore_state");
+  opcodes.Nop();
+  DW_CHECK_NEXT("DW_CFA_nop");
+
+  // Also test helpers.
+  opcodes.DefCFA(Reg(4), 100);  // ESP
+  DW_CHECK_NEXT("DW_CFA_def_cfa: r4 (esp) ofs 100");
+  opcodes.AdjustCFAOffset(8);
+  DW_CHECK_NEXT("DW_CFA_def_cfa_offset: 108");
+  opcodes.RelOffset(Reg(0), 0);  // push R0
+  DW_CHECK_NEXT("DW_CFA_offset: r0 (eax) at cfa-108");
+  opcodes.RelOffset(Reg(1), 4);  // push R1
+  DW_CHECK_NEXT("DW_CFA_offset: r1 (ecx) at cfa-104");
+  opcodes.RelOffsetForMany(Reg(2), 8, 1 | (1 << 3), 4);  // push R2 and R5
+  DW_CHECK_NEXT("DW_CFA_offset: r2 (edx) at cfa-100");
+  DW_CHECK_NEXT("DW_CFA_offset: r5 (ebp) at cfa-96");
+  opcodes.RestoreMany(Reg(2), 1 | (1 << 3));  // pop R2 and R5
+  DW_CHECK_NEXT("DW_CFA_restore: r2 (edx)");
+  DW_CHECK_NEXT("DW_CFA_restore: r5 (ebp)");
+
+  DebugFrameWriter<> eh_frame(&eh_frame_data_, is64bit);
+  DebugFrameOpCodeWriter<> initial_opcodes;
+  eh_frame.WriteCIE(Reg(is64bit ? 16 : 8),  // Return address register.
+                    initial_opcodes);  // Initial opcodes.
+  eh_frame.WriteFDE(0x01000000, 0x01000000,
+                    opcodes.data()->data(), opcodes.data()->size());
+  CheckObjdumpOutput(is64bit, "-W");
+}
+
+TEST_F(DwarfTest, DebugFrame64) {
+  const bool is64bit = true;
+  DebugFrameWriter<> eh_frame(&eh_frame_data_, is64bit);
+  DebugFrameOpCodeWriter<> no_opcodes;
+  eh_frame.WriteCIE(Reg(16), no_opcodes);
+  eh_frame.WriteFDE(0x0100000000000000, 0x0200000000000000,
+                    no_opcodes.data()->data(), no_opcodes.data()->size());
+  DW_CHECK("FDE cie=00000000 pc=100000000000000..300000000000000");
+  CheckObjdumpOutput(is64bit, "-W");
+}
+
+TEST_F(DwarfTest, DebugLine) {
+  const bool is64bit = false;
+  const int code_factor_bits = 1;
+  DebugLineOpCodeWriter<> opcodes(is64bit, code_factor_bits);
+
+  std::vector<std::string> include_directories;
+  include_directories.push_back("/path/to/source");
+  DW_CHECK("/path/to/source");
+
+  std::vector<DebugLineWriter<>::FileEntry> files {
+    { "file0.c", 0, 1000, 2000 },
+    { "file1.c", 1, 1000, 2000 },
+    { "file2.c", 1, 1000, 2000 },
+  };
+  DW_CHECK("1\t0\t1000\t2000\tfile0.c");
+  DW_CHECK_NEXT("2\t1\t1000\t2000\tfile1.c");
+  DW_CHECK_NEXT("3\t1\t1000\t2000\tfile2.c");
+
+  DW_CHECK("Line Number Statements");
+  opcodes.SetAddress(0x01000000);
+  DW_CHECK_NEXT("Extended opcode 2: set Address to 0x1000000");
+  opcodes.AddRow();
+  DW_CHECK_NEXT("Copy");
+  opcodes.AdvancePC(0x01000100);
+  DW_CHECK_NEXT("Advance PC by 256 to 0x1000100");
+  opcodes.SetFile(2);
+  DW_CHECK_NEXT("Set File Name to entry 2 in the File Name Table");
+  opcodes.AdvanceLine(3);
+  DW_CHECK_NEXT("Advance Line by 2 to 3");
+  opcodes.SetColumn(4);
+  DW_CHECK_NEXT("Set column to 4");
+  opcodes.NegateStmt();
+  DW_CHECK_NEXT("Set is_stmt to 0");
+  opcodes.SetBasicBlock();
+  DW_CHECK_NEXT("Set basic block");
+  opcodes.SetPrologueEnd();
+  DW_CHECK_NEXT("Set prologue_end to true");
+  opcodes.SetEpilogueBegin();
+  DW_CHECK_NEXT("Set epilogue_begin to true");
+  opcodes.SetISA(5);
+  DW_CHECK_NEXT("Set ISA to 5");
+  opcodes.EndSequence();
+  DW_CHECK_NEXT("Extended opcode 1: End of Sequence");
+  opcodes.DefineFile("file.c", 0, 1000, 2000);
+  DW_CHECK_NEXT("Extended opcode 3: define new File Table entry");
+  DW_CHECK_NEXT("Entry\tDir\tTime\tSize\tName");
+  DW_CHECK_NEXT("1\t0\t1000\t2000\tfile.c");
+
+  DebugLineWriter<> debug_line(&debug_line_data_);
+  debug_line.WriteTable(include_directories, files, opcodes);
+  CheckObjdumpOutput(is64bit, "-W");
+}
+
+// DWARF has special one byte codes which advance PC and line at the same time.
+TEST_F(DwarfTest, DebugLineSpecialOpcodes) {
+  const bool is64bit = false;
+  const int code_factor_bits = 1;
+  uint32_t pc = 0x01000000;
+  int line = 1;
+  DebugLineOpCodeWriter<> opcodes(is64bit, code_factor_bits);
+  opcodes.SetAddress(pc);
+  size_t num_rows = 0;
+  DW_CHECK("Line Number Statements:");
+  DW_CHECK("Special opcode");
+  DW_CHECK("Advance PC by constant");
+  DW_CHECK("Decoded dump of debug contents of section .debug_line:");
+  DW_CHECK("Line number    Starting address");
+  for (int addr_delta = 0; addr_delta < 80; addr_delta += 2) {
+    for (int line_delta = 16; line_delta >= -16; --line_delta) {
+      pc += addr_delta;
+      line += line_delta;
+      opcodes.AddRow(pc, line);
+      num_rows++;
+      ASSERT_EQ(opcodes.CurrentAddress(), pc);
+      ASSERT_EQ(opcodes.CurrentLine(), line);
+      char expected[1024];
+      sprintf(expected, "%i           0x%x", line, pc);
+      DW_CHECK_NEXT(expected);
+    }
+  }
+  EXPECT_LT(opcodes.data()->size(), num_rows * 3);
+
+  std::vector<std::string> directories;
+  std::vector<DebugLineWriter<>::FileEntry> files {
+    { "file.c", 0, 1000, 2000 },
+  };
+  DebugLineWriter<> debug_line(&debug_line_data_);
+  debug_line.WriteTable(directories, files, opcodes);
+  CheckObjdumpOutput(is64bit, "-W -WL");
+}
+
+#endif  // HAVE_ANDROID_OS
+
+}  // namespace dwarf
+}  // namespace art
diff --git a/compiler/dwarf/dwarf_test.h b/compiler/dwarf/dwarf_test.h
new file mode 100644
index 0000000..dd5e0c2
--- /dev/null
+++ b/compiler/dwarf/dwarf_test.h
@@ -0,0 +1,220 @@
+/*
+ * Copyright (C) 2015 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.
+ */
+
+#ifndef ART_COMPILER_DWARF_DWARF_TEST_H_
+#define ART_COMPILER_DWARF_DWARF_TEST_H_
+
+#include <cstring>
+#include <dirent.h>
+#include <memory>
+#include <set>
+#include <stdio.h>
+#include <string>
+#include <sys/types.h>
+
+#include "utils.h"
+#include "base/unix_file/fd_file.h"
+#include "common_runtime_test.h"
+#include "elf_builder.h"
+#include "gtest/gtest.h"
+#include "os.h"
+
+namespace art {
+namespace dwarf {
+
+#define DW_CHECK(substring) Check(substring, false, __FILE__, __LINE__)
+#define DW_CHECK_NEXT(substring) Check(substring, true, __FILE__, __LINE__)
+
+class DwarfTest : public CommonRuntimeTest {
+ public:
+  static constexpr bool kPrintObjdumpOutput = false;  // debugging.
+
+  struct ExpectedLine {
+    std::string substring;
+    bool next;
+    const char* at_file;
+    int at_line;
+  };
+
+  // Check that the objdump output contains given output.
+  // If next is true, it must be the next line.  Otherwise lines are skipped.
+  void Check(const char* substr, bool next, const char* at_file, int at_line) {
+    expected_lines_.push_back(ExpectedLine {substr, next, at_file, at_line});
+  }
+
+  static std::string GetObjdumpPath() {
+    const char* android_build_top = getenv("ANDROID_BUILD_TOP");
+    if (android_build_top != nullptr) {
+      std::string host_prebuilts = std::string(android_build_top) +
+                                   "/prebuilts/gcc/linux-x86/host/";
+      // Read the content of the directory.
+      std::set<std::string> entries;
+      DIR* dir = opendir(host_prebuilts.c_str());
+      if (dir != nullptr) {
+        struct dirent* entry;
+        while ((entry = readdir(dir)) != nullptr) {
+          if (strstr(entry->d_name, "linux-glibc")) {
+            entries.insert(host_prebuilts + entry->d_name);
+          }
+        }
+        closedir(dir);
+      }
+      // Strings are sorted so the last one should be the most recent version.
+      if (!entries.empty()) {
+        std::string path = *entries.rbegin() + "/x86_64-linux/bin/objdump";
+        struct stat st;
+        if (stat(path.c_str(), &st) == 0) {
+          return path;  // File exists.
+        }
+      }
+    }
+    ADD_FAILURE() << "Can not find prebuild objdump.";
+    return "objdump";  // Use the system objdump as fallback.
+  }
+
+  // Pretty-print the generated DWARF data using objdump.
+  template<typename Elf_Word, typename Elf_Sword, typename Elf_Addr, typename Elf_Dyn,
+           typename Elf_Sym, typename Elf_Ehdr, typename Elf_Phdr, typename Elf_Shdr>
+  std::vector<std::string> Objdump(bool is64bit, const char* args) {
+    // Write simple elf file with just the DWARF sections.
+    class NoCode : public CodeOutput {
+      virtual void SetCodeOffset(size_t) { }
+      virtual bool Write(OutputStream*) { return true; }
+    } code;
+    ScratchFile file;
+    InstructionSet isa = is64bit ? kX86_64 : kX86;
+    ElfBuilder<Elf_Word, Elf_Sword, Elf_Addr, Elf_Dyn,
+               Elf_Sym, Elf_Ehdr, Elf_Phdr, Elf_Shdr> builder(
+        &code, file.GetFile(), isa, 0, 0, 0, 0, 0, 0, false, false);
+    typedef ElfRawSectionBuilder<Elf_Word, Elf_Sword, Elf_Shdr> Section;
+    if (!debug_info_data_.empty()) {
+      Section debug_info(".debug_info", SHT_PROGBITS, 0, nullptr, 0, 1, 0);
+      debug_info.SetBuffer(debug_info_data_);
+      builder.RegisterRawSection(debug_info);
+    }
+    if (!debug_abbrev_data_.empty()) {
+      Section debug_abbrev(".debug_abbrev", SHT_PROGBITS, 0, nullptr, 0, 1, 0);
+      debug_abbrev.SetBuffer(debug_abbrev_data_);
+      builder.RegisterRawSection(debug_abbrev);
+    }
+    if (!debug_str_data_.empty()) {
+      Section debug_str(".debug_str", SHT_PROGBITS, 0, nullptr, 0, 1, 0);
+      debug_str.SetBuffer(debug_str_data_);
+      builder.RegisterRawSection(debug_str);
+    }
+    if (!debug_line_data_.empty()) {
+      Section debug_line(".debug_line", SHT_PROGBITS, 0, nullptr, 0, 1, 0);
+      debug_line.SetBuffer(debug_line_data_);
+      builder.RegisterRawSection(debug_line);
+    }
+    if (!eh_frame_data_.empty()) {
+      Section eh_frame(".eh_frame", SHT_PROGBITS, SHF_ALLOC, nullptr, 0, 4, 0);
+      eh_frame.SetBuffer(eh_frame_data_);
+      builder.RegisterRawSection(eh_frame);
+    }
+    builder.Init();
+    builder.Write();
+
+    // Read the elf file back using objdump.
+    std::vector<std::string> lines;
+    std::string cmd = GetObjdumpPath();
+    cmd = cmd + " " + args + " " + file.GetFilename() + " 2>&1";
+    FILE* output = popen(cmd.data(), "r");
+    char buffer[1024];
+    const char* line;
+    while ((line = fgets(buffer, sizeof(buffer), output)) != nullptr) {
+      if (kPrintObjdumpOutput) {
+        printf("%s", line);
+      }
+      if (line[0] != '\0' && line[0] != '\n') {
+        EXPECT_TRUE(strstr(line, "objdump: Error:") == nullptr) << line;
+        EXPECT_TRUE(strstr(line, "objdump: Warning:") == nullptr) << line;
+        std::string str(line);
+        if (str.back() == '\n') {
+          str.pop_back();
+        }
+        lines.push_back(str);
+      }
+    }
+    pclose(output);
+    return lines;
+  }
+
+  std::vector<std::string> Objdump(bool is64bit, const char* args) {
+    if (is64bit) {
+      return Objdump<Elf64_Word, Elf64_Sword, Elf64_Addr, Elf64_Dyn,
+          Elf64_Sym, Elf64_Ehdr, Elf64_Phdr, Elf64_Shdr>(is64bit, args);
+    } else {
+      return Objdump<Elf32_Word, Elf32_Sword, Elf32_Addr, Elf32_Dyn,
+          Elf32_Sym, Elf32_Ehdr, Elf32_Phdr, Elf32_Shdr>(is64bit, args);
+    }
+  }
+
+  // Compare objdump output to the recorded checks.
+  void CheckObjdumpOutput(bool is64bit, const char* args) {
+    std::vector<std::string> actual_lines = Objdump(is64bit, args);
+    auto actual_line = actual_lines.begin();
+    for (const ExpectedLine& expected_line : expected_lines_) {
+      const std::string& substring = expected_line.substring;
+      if (actual_line == actual_lines.end()) {
+        ADD_FAILURE_AT(expected_line.at_file, expected_line.at_line) <<
+            "Expected '" << substring << "'.\n" <<
+            "Seen end of output.";
+      } else if (expected_line.next) {
+        if (actual_line->find(substring) == std::string::npos) {
+          ADD_FAILURE_AT(expected_line.at_file, expected_line.at_line) <<
+            "Expected '" << substring << "'.\n" <<
+            "Seen '" << actual_line->data() << "'.";
+        } else {
+          // printf("Found '%s' in '%s'.\n", substring.data(), actual_line->data());
+        }
+        actual_line++;
+      } else {
+        bool found = false;
+        for (auto it = actual_line; it < actual_lines.end(); it++) {
+          if (it->find(substring) != std::string::npos) {
+            actual_line = it;
+            found = true;
+            break;
+          }
+        }
+        if (!found) {
+          ADD_FAILURE_AT(expected_line.at_file, expected_line.at_line) <<
+            "Expected '" << substring << "'.\n" <<
+            "Not found anywhere in the rest of the output.";
+        } else {
+          // printf("Found '%s' in '%s'.\n", substring.data(), actual_line->data());
+          actual_line++;
+        }
+      }
+    }
+  }
+
+  // Buffers which are going to assembled into ELF file and passed to objdump.
+  std::vector<uint8_t> eh_frame_data_;
+  std::vector<uint8_t> debug_info_data_;
+  std::vector<uint8_t> debug_abbrev_data_;
+  std::vector<uint8_t> debug_str_data_;
+  std::vector<uint8_t> debug_line_data_;
+
+  // The expected output of objdump.
+  std::vector<ExpectedLine> expected_lines_;
+};
+
+}  // namespace dwarf
+}  // namespace art
+
+#endif  // ART_COMPILER_DWARF_DWARF_TEST_H_
diff --git a/compiler/dwarf/register.h b/compiler/dwarf/register.h
new file mode 100644
index 0000000..fa666df
--- /dev/null
+++ b/compiler/dwarf/register.h
@@ -0,0 +1,58 @@
+/*
+ * Copyright (C) 2015 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.
+ */
+
+#ifndef ART_COMPILER_DWARF_REGISTER_H_
+#define ART_COMPILER_DWARF_REGISTER_H_
+
+namespace art {
+namespace dwarf {
+
+// Represents DWARF register.
+class Reg {
+ public:
+  explicit Reg(int reg_num) : num_(reg_num) { }
+  int num() const { return num_; }
+
+  // TODO: Arm S0–S31 register mapping is obsolescent.
+  //   We should use VFP-v3/Neon D0-D31 mapping instead.
+  //   However, D0 is aliased to pair of S0 and S1, so using that
+  //   mapping we can not easily say S0 is spilled and S1 is not.
+  //   There are ways around this in DWARF but they are complex.
+  //   It would be much simpler to always spill whole D registers.
+  //   Arm64 mapping is correct since we already do this there.
+
+  static Reg ArmCore(int num) { return Reg(num); }
+  static Reg ArmFp(int num) { return Reg(64 + num); }  // S0–S31.
+  static Reg Arm64Core(int num) { return Reg(num); }
+  static Reg Arm64Fp(int num) { return Reg(64 + num); }  // V0-V31.
+  static Reg MipsCore(int num) { return Reg(num); }
+  static Reg Mips64Core(int num) { return Reg(num); }
+  static Reg X86Core(int num) { return Reg(num); }
+  static Reg X86Fp(int num) { return Reg(21 + num); }
+  static Reg X86_64Core(int num) {
+    static const int map[8] = {0, 2, 1, 3, 7, 6, 4, 5};
+    return Reg(num < 8 ? map[num] : num);
+  }
+  static Reg X86_64Fp(int num) { return Reg(17 + num); }
+
+ private:
+  int num_;
+};
+
+}  // namespace dwarf
+}  // namespace art
+
+#endif  // ART_COMPILER_DWARF_REGISTER_H_
diff --git a/compiler/dwarf/writer.h b/compiler/dwarf/writer.h
new file mode 100644
index 0000000..d8e29f0
--- /dev/null
+++ b/compiler/dwarf/writer.h
@@ -0,0 +1,159 @@
+/*
+ * Copyright (C) 2015 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.
+ */
+
+#ifndef ART_COMPILER_DWARF_WRITER_H_
+#define ART_COMPILER_DWARF_WRITER_H_
+
+#include <vector>
+#include "leb128.h"
+#include "base/logging.h"
+#include "utils.h"
+
+namespace art {
+namespace dwarf {
+
+// The base class for all DWARF writers.
+template<typename Allocator = std::allocator<uint8_t>>
+class Writer {
+ public:
+  void PushUint8(int value) {
+    DCHECK_GE(value, 0);
+    DCHECK_LE(value, UINT8_MAX);
+    data_->push_back(value & 0xff);
+  }
+
+  void PushUint16(int value) {
+    DCHECK_GE(value, 0);
+    DCHECK_LE(value, UINT16_MAX);
+    data_->push_back((value >> 0) & 0xff);
+    data_->push_back((value >> 8) & 0xff);
+  }
+
+  void PushUint32(uint32_t value) {
+    data_->push_back((value >> 0) & 0xff);
+    data_->push_back((value >> 8) & 0xff);
+    data_->push_back((value >> 16) & 0xff);
+    data_->push_back((value >> 24) & 0xff);
+  }
+
+  void PushUint32(int value) {
+    DCHECK_GE(value, 0);
+    PushUint32(static_cast<uint32_t>(value));
+  }
+
+  void PushUint32(uint64_t value) {
+    DCHECK_LE(value, UINT32_MAX);
+    PushUint32(static_cast<uint32_t>(value));
+  }
+
+  void PushUint64(uint64_t value) {
+    data_->push_back((value >> 0) & 0xff);
+    data_->push_back((value >> 8) & 0xff);
+    data_->push_back((value >> 16) & 0xff);
+    data_->push_back((value >> 24) & 0xff);
+    data_->push_back((value >> 32) & 0xff);
+    data_->push_back((value >> 40) & 0xff);
+    data_->push_back((value >> 48) & 0xff);
+    data_->push_back((value >> 56) & 0xff);
+  }
+
+  void PushInt8(int value) {
+    DCHECK_GE(value, INT8_MIN);
+    DCHECK_LE(value, INT8_MAX);
+    PushUint8(static_cast<uint8_t>(value));
+  }
+
+  void PushInt16(int value) {
+    DCHECK_GE(value, INT16_MIN);
+    DCHECK_LE(value, INT16_MAX);
+    PushUint16(static_cast<uint16_t>(value));
+  }
+
+  void PushInt32(int value) {
+    PushUint32(static_cast<uint32_t>(value));
+  }
+
+  void PushInt64(int64_t value) {
+    PushUint64(static_cast<uint64_t>(value));
+  }
+
+  // Variable-length encoders.
+
+  void PushUleb128(uint32_t value) {
+    EncodeUnsignedLeb128(data_, value);
+  }
+
+  void PushUleb128(int value) {
+    DCHECK_GE(value, 0);
+    EncodeUnsignedLeb128(data_, value);
+  }
+
+  void PushSleb128(int value) {
+    EncodeSignedLeb128(data_, value);
+  }
+
+  // Miscellaneous functions.
+
+  void PushString(const char* value) {
+    data_->insert(data_->end(), value, value + strlen(value) + 1);
+  }
+
+  void PushData(const void* ptr, size_t size) {
+    const char* p = reinterpret_cast<const char*>(ptr);
+    data_->insert(data_->end(), p, p + size);
+  }
+
+  void UpdateUint32(size_t offset, uint32_t value) {
+    DCHECK_LT(offset + 3, data_->size());
+    (*data_)[offset + 0] = (value >> 0) & 0xFF;
+    (*data_)[offset + 1] = (value >> 8) & 0xFF;
+    (*data_)[offset + 2] = (value >> 16) & 0xFF;
+    (*data_)[offset + 3] = (value >> 24) & 0xFF;
+  }
+
+  void UpdateUint64(size_t offset, uint64_t value) {
+    DCHECK_LT(offset + 7, data_->size());
+    (*data_)[offset + 0] = (value >> 0) & 0xFF;
+    (*data_)[offset + 1] = (value >> 8) & 0xFF;
+    (*data_)[offset + 2] = (value >> 16) & 0xFF;
+    (*data_)[offset + 3] = (value >> 24) & 0xFF;
+    (*data_)[offset + 4] = (value >> 32) & 0xFF;
+    (*data_)[offset + 5] = (value >> 40) & 0xFF;
+    (*data_)[offset + 6] = (value >> 48) & 0xFF;
+    (*data_)[offset + 7] = (value >> 56) & 0xFF;
+  }
+
+  void Pad(int alignment) {
+    DCHECK_NE(alignment, 0);
+    data_->resize(RoundUp(data_->size(), alignment), 0);
+  }
+
+  const std::vector<uint8_t, Allocator>* data() const {
+    return data_;
+  }
+
+  explicit Writer(std::vector<uint8_t, Allocator>* buffer) : data_(buffer) { }
+
+ private:
+  std::vector<uint8_t, Allocator>* data_;
+
+  DISALLOW_COPY_AND_ASSIGN(Writer);
+};
+
+}  // namespace dwarf
+}  // namespace art
+
+#endif  // ART_COMPILER_DWARF_WRITER_H_
