summaryrefslogtreecommitdiff
path: root/compiler/debug
diff options
context:
space:
mode:
author David Srbecky <dsrbecky@google.com> 2019-02-12 16:35:48 +0000
committer David Srbecky <dsrbecky@google.com> 2019-03-20 15:20:54 +0000
commit2faab0064bccdf06a454ba5fc37f2cfeceab78bc (patch)
treebc51a211068019d77e7739164adf5be5c6333b7b /compiler/debug
parent5f1465ff689eccbb1b6d15160d1a3700793956da (diff)
Create libelffile library for ELF file manipulation.
Move some of our tooling to library to make it reusable. Remove MIPS support from the ELF builder. This is slightly easier than making it independent of the runtime. Bug: 110133331 Test: test.py -b --host Change-Id: I93343808d0e27ee8e1117e713a2503e8179fc245
Diffstat (limited to 'compiler/debug')
-rw-r--r--compiler/debug/dwarf/debug_abbrev_writer.h98
-rw-r--r--compiler/debug/dwarf/debug_frame_opcode_writer.h341
-rw-r--r--compiler/debug/dwarf/debug_info_entry_writer.h228
-rw-r--r--compiler/debug/dwarf/debug_line_opcode_writer.h261
-rw-r--r--compiler/debug/dwarf/dwarf_constants.h686
-rw-r--r--compiler/debug/dwarf/dwarf_test.cc10
-rw-r--r--compiler/debug/dwarf/dwarf_test.h8
-rw-r--r--compiler/debug/dwarf/expression.h121
-rw-r--r--compiler/debug/dwarf/headers.h162
-rw-r--r--compiler/debug/dwarf/register.h62
-rw-r--r--compiler/debug/dwarf/writer.h184
-rw-r--r--compiler/debug/elf_debug_frame_writer.h10
-rw-r--r--compiler/debug/elf_debug_info_writer.h10
-rw-r--r--compiler/debug/elf_debug_line_writer.h10
-rw-r--r--compiler/debug/elf_debug_loc_writer.h4
-rw-r--r--compiler/debug/elf_debug_reader.h173
-rw-r--r--compiler/debug/elf_debug_writer.cc51
-rw-r--r--compiler/debug/elf_debug_writer.h7
-rw-r--r--compiler/debug/elf_symtab_writer.h4
-rw-r--r--compiler/debug/xz_utils.cc134
-rw-r--r--compiler/debug/xz_utils.h33
21 files changed, 55 insertions, 2542 deletions
diff --git a/compiler/debug/dwarf/debug_abbrev_writer.h b/compiler/debug/dwarf/debug_abbrev_writer.h
deleted file mode 100644
index 63a049b2cc..0000000000
--- a/compiler/debug/dwarf/debug_abbrev_writer.h
+++ /dev/null
@@ -1,98 +0,0 @@
-/*
- * 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.
- */
-
-#ifndef ART_COMPILER_DEBUG_DWARF_DEBUG_ABBREV_WRITER_H_
-#define ART_COMPILER_DEBUG_DWARF_DEBUG_ABBREV_WRITER_H_
-
-#include <cstdint>
-#include <type_traits>
-#include <unordered_map>
-
-#include "base/casts.h"
-#include "base/leb128.h"
-#include "base/stl_util.h"
-#include "debug/dwarf/dwarf_constants.h"
-#include "debug/dwarf/writer.h"
-
-namespace art {
-namespace dwarf {
-
-// Writer for the .debug_abbrev.
-//
-// Abbreviations specify the format of entries in .debug_info.
-// Each entry specifies abbreviation code, which in turns
-// determines all the attributes and their format.
-// It is possible to think of them as type definitions.
-template <typename Vector = std::vector<uint8_t>>
-class DebugAbbrevWriter final : private Writer<Vector> {
- static_assert(std::is_same<typename Vector::value_type, uint8_t>::value, "Invalid value type");
-
- public:
- explicit DebugAbbrevWriter(Vector* buffer)
- : Writer<Vector>(buffer),
- current_abbrev_(buffer->get_allocator()) {
- this->PushUint8(0); // Add abbrev table terminator.
- }
-
- // Start abbreviation declaration.
- void StartAbbrev(Tag tag) {
- DCHECK(current_abbrev_.empty());
- EncodeUnsignedLeb128(&current_abbrev_, tag);
- has_children_offset_ = current_abbrev_.size();
- current_abbrev_.push_back(0); // Place-holder for DW_CHILDREN.
- }
-
- // Add attribute specification.
- void AddAbbrevAttribute(Attribute name, Form type) {
- EncodeUnsignedLeb128(&current_abbrev_, name);
- EncodeUnsignedLeb128(&current_abbrev_, type);
- }
-
- // End abbreviation declaration and return its code.
- // This will deduplicate abbreviations.
- uint32_t EndAbbrev(Children has_children) {
- DCHECK(!current_abbrev_.empty());
- current_abbrev_[has_children_offset_] = has_children;
- auto it = abbrev_codes_.insert(std::make_pair(std::move(current_abbrev_), NextAbbrevCode()));
- uint32_t abbrev_code = it.first->second;
- if (UNLIKELY(it.second)) { // Inserted new entry.
- const Vector& abbrev = it.first->first;
- this->Pop(); // Remove abbrev table terminator.
- this->PushUleb128(abbrev_code);
- this->PushData(abbrev.data(), abbrev.size());
- this->PushUint8(0); // Attribute list end.
- this->PushUint8(0); // Attribute list end.
- this->PushUint8(0); // Add abbrev table terminator.
- }
- current_abbrev_.clear();
- return abbrev_code;
- }
-
- // Get the next free abbrev code.
- uint32_t NextAbbrevCode() {
- return dchecked_integral_cast<uint32_t>(1 + abbrev_codes_.size());
- }
-
- private:
- Vector current_abbrev_;
- size_t has_children_offset_ = 0;
- std::unordered_map<Vector, uint32_t, FNVHash<Vector> > abbrev_codes_;
-};
-
-} // namespace dwarf
-} // namespace art
-
-#endif // ART_COMPILER_DEBUG_DWARF_DEBUG_ABBREV_WRITER_H_
diff --git a/compiler/debug/dwarf/debug_frame_opcode_writer.h b/compiler/debug/dwarf/debug_frame_opcode_writer.h
deleted file mode 100644
index 7c75c9bf37..0000000000
--- a/compiler/debug/dwarf/debug_frame_opcode_writer.h
+++ /dev/null
@@ -1,341 +0,0 @@
-/*
- * 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_DEBUG_DWARF_DEBUG_FRAME_OPCODE_WRITER_H_
-#define ART_COMPILER_DEBUG_DWARF_DEBUG_FRAME_OPCODE_WRITER_H_
-
-#include "base/bit_utils.h"
-#include "debug/dwarf/dwarf_constants.h"
-#include "debug/dwarf/register.h"
-#include "debug/dwarf/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 Vector = std::vector<uint8_t> >
-class DebugFrameOpCodeWriter : private Writer<Vector> {
- static_assert(std::is_same<typename Vector::value_type, uint8_t>::value, "Invalid value type");
-
- 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 ALWAYS_INLINE AdvancePC(int absolute_pc) {
- DCHECK_GE(absolute_pc, current_pc_);
- if (UNLIKELY(enabled_)) {
- 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 ALWAYS_INLINE RelOffset(Reg reg, int offset) {
- Offset(reg, offset - current_cfa_offset_);
- }
-
- // Common alias in assemblers - increase stack frame size.
- void ALWAYS_INLINE AdjustCFAOffset(int delta) {
- DefCFAOffset(current_cfa_offset_ + delta);
- }
-
- // Custom alias - spill many registers based on bitmask.
- void ALWAYS_INLINE RelOffsetForMany(Reg reg_base, int offset,
- uint32_t reg_mask, int reg_size) {
- DCHECK(reg_size == 4 || reg_size == 8);
- if (UNLIKELY(enabled_)) {
- for (int i = 0; reg_mask != 0u; reg_mask >>= 1, i++) {
- // Skip zero bits and go to the set bit.
- int num_zeros = CTZ(reg_mask);
- i += num_zeros;
- reg_mask >>= num_zeros;
- RelOffset(Reg(reg_base.num() + i), offset);
- offset += reg_size;
- }
- }
- }
-
- // Custom alias - unspill many registers based on bitmask.
- void ALWAYS_INLINE RestoreMany(Reg reg_base, uint32_t reg_mask) {
- if (UNLIKELY(enabled_)) {
- for (int i = 0; reg_mask != 0u; reg_mask >>= 1, i++) {
- // Skip zero bits and go to the set bit.
- int num_zeros = CTZ(reg_mask);
- i += num_zeros;
- reg_mask >>= num_zeros;
- Restore(Reg(reg_base.num() + i));
- }
- }
- }
-
- void ALWAYS_INLINE Nop() {
- if (UNLIKELY(enabled_)) {
- this->PushUint8(DW_CFA_nop);
- }
- }
-
- void ALWAYS_INLINE Offset(Reg reg, int offset) {
- if (UNLIKELY(enabled_)) {
- 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 ALWAYS_INLINE Restore(Reg reg) {
- if (UNLIKELY(enabled_)) {
- 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 ALWAYS_INLINE Undefined(Reg reg) {
- if (UNLIKELY(enabled_)) {
- ImplicitlyAdvancePC();
- this->PushUint8(DW_CFA_undefined);
- this->PushUleb128(reg.num());
- }
- }
-
- void ALWAYS_INLINE SameValue(Reg reg) {
- if (UNLIKELY(enabled_)) {
- ImplicitlyAdvancePC();
- this->PushUint8(DW_CFA_same_value);
- this->PushUleb128(reg.num());
- }
- }
-
- // The previous value of "reg" is stored in register "new_reg".
- void ALWAYS_INLINE Register(Reg reg, Reg new_reg) {
- if (UNLIKELY(enabled_)) {
- ImplicitlyAdvancePC();
- this->PushUint8(DW_CFA_register);
- this->PushUleb128(reg.num());
- this->PushUleb128(new_reg.num());
- }
- }
-
- void ALWAYS_INLINE RememberState() {
- if (UNLIKELY(enabled_)) {
- ImplicitlyAdvancePC();
- this->PushUint8(DW_CFA_remember_state);
- }
- }
-
- void ALWAYS_INLINE RestoreState() {
- if (UNLIKELY(enabled_)) {
- ImplicitlyAdvancePC();
- this->PushUint8(DW_CFA_restore_state);
- }
- }
-
- void ALWAYS_INLINE DefCFA(Reg reg, int offset) {
- if (UNLIKELY(enabled_)) {
- 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 ALWAYS_INLINE DefCFARegister(Reg reg) {
- if (UNLIKELY(enabled_)) {
- ImplicitlyAdvancePC();
- this->PushUint8(DW_CFA_def_cfa_register);
- this->PushUleb128(reg.num());
- }
- }
-
- void ALWAYS_INLINE DefCFAOffset(int offset) {
- if (UNLIKELY(enabled_)) {
- 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));
- }
- }
- }
- // Uncoditional so that the user can still get and check the value.
- current_cfa_offset_ = offset;
- }
-
- void ALWAYS_INLINE ValOffset(Reg reg, int offset) {
- if (UNLIKELY(enabled_)) {
- 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 ALWAYS_INLINE DefCFAExpression(uint8_t* expr, int expr_size) {
- if (UNLIKELY(enabled_)) {
- ImplicitlyAdvancePC();
- uses_dwarf3_features_ = true;
- this->PushUint8(DW_CFA_def_cfa_expression);
- this->PushUleb128(expr_size);
- this->PushData(expr, expr_size);
- }
- }
-
- void ALWAYS_INLINE Expression(Reg reg, uint8_t* expr, int expr_size) {
- if (UNLIKELY(enabled_)) {
- ImplicitlyAdvancePC();
- uses_dwarf3_features_ = true;
- this->PushUint8(DW_CFA_expression);
- this->PushUleb128(reg.num());
- this->PushUleb128(expr_size);
- this->PushData(expr, expr_size);
- }
- }
-
- void ALWAYS_INLINE ValExpression(Reg reg, uint8_t* expr, int expr_size) {
- if (UNLIKELY(enabled_)) {
- ImplicitlyAdvancePC();
- uses_dwarf3_features_ = true;
- this->PushUint8(DW_CFA_val_expression);
- this->PushUleb128(reg.num());
- this->PushUleb128(expr_size);
- this->PushData(expr, expr_size);
- }
- }
-
- bool IsEnabled() const { return enabled_; }
-
- void SetEnabled(bool value) {
- enabled_ = value;
- if (enabled_ && opcodes_.capacity() == 0u) {
- opcodes_.reserve(kDefaultCapacity);
- }
- }
-
- int GetCurrentPC() const { return current_pc_; }
-
- int GetCurrentCFAOffset() const { return current_cfa_offset_; }
-
- void SetCurrentCFAOffset(int offset) { current_cfa_offset_ = offset; }
-
- using Writer<Vector>::data;
-
- explicit DebugFrameOpCodeWriter(bool enabled = true,
- const typename Vector::allocator_type& alloc =
- typename Vector::allocator_type())
- : Writer<Vector>(&opcodes_),
- enabled_(false),
- opcodes_(alloc),
- current_cfa_offset_(0),
- current_pc_(0),
- uses_dwarf3_features_(false) {
- SetEnabled(enabled);
- }
-
- virtual ~DebugFrameOpCodeWriter() { }
-
- protected:
- // Best guess based on couple of observed outputs.
- static constexpr size_t kDefaultCapacity = 32u;
-
- 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;
- }
-
- bool enabled_; // If disabled all writes are no-ops.
- Vector 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_DEBUG_DWARF_DEBUG_FRAME_OPCODE_WRITER_H_
diff --git a/compiler/debug/dwarf/debug_info_entry_writer.h b/compiler/debug/dwarf/debug_info_entry_writer.h
deleted file mode 100644
index b198178d5d..0000000000
--- a/compiler/debug/dwarf/debug_info_entry_writer.h
+++ /dev/null
@@ -1,228 +0,0 @@
-/*
- * Copyright (C) 2014 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_DEBUG_DWARF_DEBUG_INFO_ENTRY_WRITER_H_
-#define ART_COMPILER_DEBUG_DWARF_DEBUG_INFO_ENTRY_WRITER_H_
-
-#include <cstdint>
-#include <unordered_map>
-
-#include "base/casts.h"
-#include "base/leb128.h"
-#include "debug/dwarf/debug_abbrev_writer.h"
-#include "debug/dwarf/dwarf_constants.h"
-#include "debug/dwarf/expression.h"
-#include "debug/dwarf/writer.h"
-
-namespace art {
-namespace dwarf {
-
-/*
- * Writer for debug information entries (DIE).
- *
- * Usage:
- * StartTag(DW_TAG_compile_unit);
- * WriteStrp(DW_AT_producer, "Compiler name", debug_str);
- * StartTag(DW_TAG_subprogram);
- * WriteStrp(DW_AT_name, "Foo", debug_str);
- * EndTag();
- * EndTag();
- */
-template <typename Vector = std::vector<uint8_t>>
-class DebugInfoEntryWriter final : private Writer<Vector> {
- static_assert(std::is_same<typename Vector::value_type, uint8_t>::value, "Invalid value type");
-
- public:
- static constexpr size_t kCompilationUnitHeaderSize = 11;
-
- // Start debugging information entry.
- // Returns offset of the entry in compilation unit.
- size_t StartTag(Tag tag) {
- if (inside_entry_) {
- // Write abbrev code for the previous entry.
- // Parent entry is finalized before any children are written.
- this->UpdateUleb128(abbrev_code_offset_, debug_abbrev_->EndAbbrev(DW_CHILDREN_yes));
- inside_entry_ = false;
- }
- debug_abbrev_->StartAbbrev(tag);
- // Abbrev code placeholder of sufficient size.
- abbrev_code_offset_ = this->data()->size();
- this->PushUleb128(debug_abbrev_->NextAbbrevCode());
- depth_++;
- inside_entry_ = true;
- return abbrev_code_offset_ + kCompilationUnitHeaderSize;
- }
-
- // End debugging information entry.
- void EndTag() {
- DCHECK_GT(depth_, 0);
- if (inside_entry_) {
- // Write abbrev code for this entry.
- this->UpdateUleb128(abbrev_code_offset_, debug_abbrev_->EndAbbrev(DW_CHILDREN_no));
- inside_entry_ = false;
- // This entry has no children and so there is no terminator.
- } else {
- // The entry has been already finalized so it must be parent entry
- // and we need to write the terminator required by DW_CHILDREN_yes.
- this->PushUint8(0);
- }
- depth_--;
- }
-
- void WriteAddr(Attribute attrib, uint64_t value) {
- debug_abbrev_->AddAbbrevAttribute(attrib, DW_FORM_addr);
- patch_locations_.push_back(this->data()->size());
- if (is64bit_) {
- this->PushUint64(value);
- } else {
- this->PushUint32(value);
- }
- }
-
- void WriteBlock(Attribute attrib, const uint8_t* ptr, size_t num_bytes) {
- debug_abbrev_->AddAbbrevAttribute(attrib, DW_FORM_block);
- this->PushUleb128(num_bytes);
- this->PushData(ptr, num_bytes);
- }
-
- void WriteExprLoc(Attribute attrib, const Expression& expr) {
- debug_abbrev_->AddAbbrevAttribute(attrib, DW_FORM_exprloc);
- this->PushUleb128(dchecked_integral_cast<uint32_t>(expr.size()));
- this->PushData(expr.data());
- }
-
- void WriteData1(Attribute attrib, uint8_t value) {
- debug_abbrev_->AddAbbrevAttribute(attrib, DW_FORM_data1);
- this->PushUint8(value);
- }
-
- void WriteData2(Attribute attrib, uint16_t value) {
- debug_abbrev_->AddAbbrevAttribute(attrib, DW_FORM_data2);
- this->PushUint16(value);
- }
-
- void WriteData4(Attribute attrib, uint32_t value) {
- debug_abbrev_->AddAbbrevAttribute(attrib, DW_FORM_data4);
- this->PushUint32(value);
- }
-
- void WriteData8(Attribute attrib, uint64_t value) {
- debug_abbrev_->AddAbbrevAttribute(attrib, DW_FORM_data8);
- this->PushUint64(value);
- }
-
- void WriteSecOffset(Attribute attrib, uint32_t offset) {
- debug_abbrev_->AddAbbrevAttribute(attrib, DW_FORM_sec_offset);
- this->PushUint32(offset);
- }
-
- void WriteSdata(Attribute attrib, int value) {
- debug_abbrev_->AddAbbrevAttribute(attrib, DW_FORM_sdata);
- this->PushSleb128(value);
- }
-
- void WriteUdata(Attribute attrib, int value) {
- debug_abbrev_->AddAbbrevAttribute(attrib, DW_FORM_udata);
- this->PushUleb128(value);
- }
-
- void WriteUdata(Attribute attrib, uint32_t value) {
- debug_abbrev_->AddAbbrevAttribute(attrib, DW_FORM_udata);
- this->PushUleb128(value);
- }
-
- void WriteFlag(Attribute attrib, bool value) {
- debug_abbrev_->AddAbbrevAttribute(attrib, DW_FORM_flag);
- this->PushUint8(value ? 1 : 0);
- }
-
- void WriteFlagPresent(Attribute attrib) {
- debug_abbrev_->AddAbbrevAttribute(attrib, DW_FORM_flag_present);
- }
-
- void WriteRef4(Attribute attrib, uint32_t cu_offset) {
- debug_abbrev_->AddAbbrevAttribute(attrib, DW_FORM_ref4);
- this->PushUint32(cu_offset);
- }
-
- void WriteRef(Attribute attrib, uint32_t cu_offset) {
- debug_abbrev_->AddAbbrevAttribute(attrib, DW_FORM_ref_udata);
- this->PushUleb128(cu_offset);
- }
-
- void WriteString(Attribute attrib, const char* value) {
- debug_abbrev_->AddAbbrevAttribute(attrib, DW_FORM_string);
- this->PushString(value);
- }
-
- void WriteStrp(Attribute attrib, size_t debug_str_offset) {
- debug_abbrev_->AddAbbrevAttribute(attrib, DW_FORM_strp);
- this->PushUint32(dchecked_integral_cast<uint32_t>(debug_str_offset));
- }
-
- void WriteStrp(Attribute attrib, const char* str, size_t len,
- std::vector<uint8_t>* debug_str) {
- debug_abbrev_->AddAbbrevAttribute(attrib, DW_FORM_strp);
- this->PushUint32(debug_str->size());
- debug_str->insert(debug_str->end(), str, str + len);
- debug_str->push_back(0);
- }
-
- void WriteStrp(Attribute attrib, const char* str, std::vector<uint8_t>* debug_str) {
- WriteStrp(attrib, str, strlen(str), debug_str);
- }
-
- bool Is64bit() const { return is64bit_; }
-
- const std::vector<uintptr_t>& GetPatchLocations() const {
- return patch_locations_;
- }
-
- int Depth() const { return depth_; }
-
- using Writer<Vector>::data;
- using Writer<Vector>::size;
- using Writer<Vector>::UpdateUint32;
-
- DebugInfoEntryWriter(bool is64bitArch,
- DebugAbbrevWriter<Vector>* debug_abbrev,
- const typename Vector::allocator_type& alloc =
- typename Vector::allocator_type())
- : Writer<Vector>(&entries_),
- debug_abbrev_(debug_abbrev),
- entries_(alloc),
- is64bit_(is64bitArch) {
- }
-
- ~DebugInfoEntryWriter() {
- DCHECK(!inside_entry_);
- DCHECK_EQ(depth_, 0);
- }
-
- private:
- DebugAbbrevWriter<Vector>* debug_abbrev_;
- Vector entries_;
- bool is64bit_;
- int depth_ = 0;
- size_t abbrev_code_offset_ = 0; // Location to patch once we know the code.
- bool inside_entry_ = false; // Entry ends at first child (if any).
- std::vector<uintptr_t> patch_locations_;
-};
-
-} // namespace dwarf
-} // namespace art
-
-#endif // ART_COMPILER_DEBUG_DWARF_DEBUG_INFO_ENTRY_WRITER_H_
diff --git a/compiler/debug/dwarf/debug_line_opcode_writer.h b/compiler/debug/dwarf/debug_line_opcode_writer.h
deleted file mode 100644
index bb4e87ff7e..0000000000
--- a/compiler/debug/dwarf/debug_line_opcode_writer.h
+++ /dev/null
@@ -1,261 +0,0 @@
-/*
- * 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_DEBUG_DWARF_DEBUG_LINE_OPCODE_WRITER_H_
-#define ART_COMPILER_DEBUG_DWARF_DEBUG_LINE_OPCODE_WRITER_H_
-
-#include <cstdint>
-
-#include "debug/dwarf/dwarf_constants.h"
-#include "debug/dwarf/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 Vector = std::vector<uint8_t>>
-class DebugLineOpCodeWriter final : private Writer<Vector> {
- static_assert(std::is_same<typename Vector::value_type, uint8_t>::value, "Invalid value type");
-
- public:
- static constexpr int kOpcodeBase = 13;
- static constexpr bool kDefaultIsStmt = false;
- 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 SetIsStmt(bool is_stmt) {
- if (is_stmt_ != is_stmt) {
- this->PushUint8(DW_LNS_negate_stmt);
- is_stmt_ = is_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;
- is_stmt_ = kDefaultIsStmt;
- }
-
- // 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);
- patch_locations_.push_back(this->data()->size());
- this->PushUint64(absolute_address);
- } else {
- this->PushUleb128(1 + 4);
- this->PushUint8(DW_LNE_set_address);
- patch_locations_.push_back(this->data()->size());
- 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_;
- }
-
- const std::vector<uintptr_t>& GetPatchLocations() const {
- return patch_locations_;
- }
-
- using Writer<Vector>::data;
-
- DebugLineOpCodeWriter(bool use64bitAddress,
- int codeFactorBits,
- const typename Vector::allocator_type& alloc =
- typename Vector::allocator_type())
- : Writer<Vector>(&opcodes_),
- opcodes_(alloc),
- uses_dwarf3_features_(false),
- use_64bit_address_(use64bitAddress),
- code_factor_bits_(codeFactorBits),
- current_address_(0),
- current_file_(1),
- current_line_(1),
- is_stmt_(kDefaultIsStmt) {
- }
-
- 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_;
- }
-
- Vector opcodes_;
- bool uses_dwarf3_features_;
- bool use_64bit_address_;
- int code_factor_bits_;
- uint64_t current_address_;
- int current_file_;
- int current_line_;
- bool is_stmt_;
- std::vector<uintptr_t> patch_locations_;
-
- DISALLOW_COPY_AND_ASSIGN(DebugLineOpCodeWriter);
-};
-
-} // namespace dwarf
-} // namespace art
-
-#endif // ART_COMPILER_DEBUG_DWARF_DEBUG_LINE_OPCODE_WRITER_H_
diff --git a/compiler/debug/dwarf/dwarf_constants.h b/compiler/debug/dwarf/dwarf_constants.h
deleted file mode 100644
index 7beb1fa7da..0000000000
--- a/compiler/debug/dwarf/dwarf_constants.h
+++ /dev/null
@@ -1,686 +0,0 @@
-/*
- * Copyright (C) 2014 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_DEBUG_DWARF_DWARF_CONSTANTS_H_
-#define ART_COMPILER_DEBUG_DWARF_DWARF_CONSTANTS_H_
-
-namespace art {
-namespace dwarf {
-
-// Based on the Dwarf 4 specification at dwarfstd.com and issues marked
-// for inclusion in Dwarf 5 on same. Values not specified in the Dwarf 4
-// standard might change or be removed in the future and may be different
-// than the values used currently by other implementations for the same trait,
-// use at your own risk.
-
-enum Tag {
- DW_TAG_array_type = 0x01,
- DW_TAG_class_type = 0x02,
- DW_TAG_entry_point = 0x03,
- DW_TAG_enumeration_type = 0x04,
- DW_TAG_formal_parameter = 0x05,
- DW_TAG_imported_declaration = 0x08,
- DW_TAG_label = 0x0a,
- DW_TAG_lexical_block = 0x0b,
- DW_TAG_member = 0x0d,
- DW_TAG_pointer_type = 0x0f,
- DW_TAG_reference_type = 0x10,
- DW_TAG_compile_unit = 0x11,
- DW_TAG_string_type = 0x12,
- DW_TAG_structure_type = 0x13,
- DW_TAG_subroutine_type = 0x15,
- DW_TAG_typedef = 0x16,
- DW_TAG_union_type = 0x17,
- DW_TAG_unspecified_parameters = 0x18,
- DW_TAG_variant = 0x19,
- DW_TAG_common_block = 0x1a,
- DW_TAG_common_inclusion = 0x1b,
- DW_TAG_inheritance = 0x1c,
- DW_TAG_inlined_subroutine = 0x1d,
- DW_TAG_module = 0x1e,
- DW_TAG_ptr_to_member_type = 0x1f,
- DW_TAG_set_type = 0x20,
- DW_TAG_subrange_type = 0x21,
- DW_TAG_with_stmt = 0x22,
- DW_TAG_access_declaration = 0x23,
- DW_TAG_base_type = 0x24,
- DW_TAG_catch_block = 0x25,
- DW_TAG_const_type = 0x26,
- DW_TAG_constant = 0x27,
- DW_TAG_enumerator = 0x28,
- DW_TAG_file_type = 0x29,
- DW_TAG_friend = 0x2a,
- DW_TAG_namelist = 0x2b,
- DW_TAG_namelist_item = 0x2c,
- DW_TAG_packed_type = 0x2d,
- DW_TAG_subprogram = 0x2e,
- DW_TAG_template_type_parameter = 0x2f,
- DW_TAG_template_value_parameter = 0x30,
- DW_TAG_thrown_type = 0x31,
- DW_TAG_try_block = 0x32,
- DW_TAG_variant_part = 0x33,
- DW_TAG_variable = 0x34,
- DW_TAG_volatile_type = 0x35,
- DW_TAG_dwarf_procedure = 0x36,
- DW_TAG_restrict_type = 0x37,
- DW_TAG_interface_type = 0x38,
- DW_TAG_namespace = 0x39,
- DW_TAG_imported_module = 0x3a,
- DW_TAG_unspecified_type = 0x3b,
- DW_TAG_partial_unit = 0x3c,
- DW_TAG_imported_unit = 0x3d,
- DW_TAG_condition = 0x3f,
- DW_TAG_shared_type = 0x40,
- DW_TAG_type_unit = 0x41,
- DW_TAG_rvalue_reference_type = 0x42,
- DW_TAG_template_alias = 0x43,
-#ifdef INCLUDE_DWARF5_VALUES
- // Values to be added in Dwarf 5. Final value not yet specified. Values listed
- // may be different than other implementations. Use with caution.
- // TODO Update these values when Dwarf 5 is released.
- DW_TAG_coarray_type = 0x44,
- DW_TAG_call_site = 0x45,
- DW_TAG_call_site_parameter = 0x46,
- DW_TAG_generic_subrange = 0x47,
- DW_TAG_atomic_type = 0x48,
- DW_TAG_dynamic_type = 0x49,
- DW_TAG_aligned_type = 0x50,
-#endif
- DW_TAG_lo_user = 0x4080,
- DW_TAG_hi_user = 0xffff
-};
-
-enum Children : uint8_t {
- DW_CHILDREN_no = 0x00,
- DW_CHILDREN_yes = 0x01
-};
-
-enum Attribute {
- DW_AT_sibling = 0x01,
- DW_AT_location = 0x02,
- DW_AT_name = 0x03,
- DW_AT_ordering = 0x09,
- DW_AT_byte_size = 0x0b,
- DW_AT_bit_offset = 0x0c,
- DW_AT_bit_size = 0x0d,
- DW_AT_stmt_list = 0x10,
- DW_AT_low_pc = 0x11,
- DW_AT_high_pc = 0x12,
- DW_AT_language = 0x13,
- DW_AT_discr = 0x15,
- DW_AT_discr_value = 0x16,
- DW_AT_visibility = 0x17,
- DW_AT_import = 0x18,
- DW_AT_string_length = 0x19,
- DW_AT_common_reference = 0x1a,
- DW_AT_comp_dir = 0x1b,
- DW_AT_const_value = 0x1c,
- DW_AT_containing_type = 0x1d,
- DW_AT_default_value = 0x1e,
- DW_AT_inline = 0x20,
- DW_AT_is_optional = 0x21,
- DW_AT_lower_bound = 0x22,
- DW_AT_producer = 0x25,
- DW_AT_prototyped = 0x27,
- DW_AT_return_addr = 0x2a,
- DW_AT_start_scope = 0x2c,
- DW_AT_bit_stride = 0x2e,
- DW_AT_upper_bound = 0x2f,
- DW_AT_abstract_origin = 0x31,
- DW_AT_accessibility = 0x32,
- DW_AT_address_class = 0x33,
- DW_AT_artificial = 0x34,
- DW_AT_base_types = 0x35,
- DW_AT_calling_convention = 0x36,
- DW_AT_count = 0x37,
- DW_AT_data_member_location = 0x38,
- DW_AT_decl_column = 0x39,
- DW_AT_decl_file = 0x3a,
- DW_AT_decl_line = 0x3b,
- DW_AT_declaration = 0x3c,
- DW_AT_discr_list = 0x3d,
- DW_AT_encoding = 0x3e,
- DW_AT_external = 0x3f,
- DW_AT_frame_base = 0x40,
- DW_AT_friend = 0x41,
- DW_AT_identifier_case = 0x42,
- DW_AT_macro_info = 0x43,
- DW_AT_namelist_item = 0x44,
- DW_AT_priority = 0x45,
- DW_AT_segment = 0x46,
- DW_AT_specification = 0x47,
- DW_AT_static_link = 0x48,
- DW_AT_type = 0x49,
- DW_AT_use_location = 0x4a,
- DW_AT_variable_parameter = 0x4b,
- DW_AT_virtuality = 0x4c,
- DW_AT_vtable_elem_location = 0x4d,
- DW_AT_allocated = 0x4e,
- DW_AT_associated = 0x4f,
- DW_AT_data_location = 0x50,
- DW_AT_byte_stride = 0x51,
- DW_AT_entry_pc = 0x52,
- DW_AT_use_UTF8 = 0x53,
- DW_AT_extension = 0x54,
- DW_AT_ranges = 0x55,
- DW_AT_trampoline = 0x56,
- DW_AT_call_column = 0x57,
- DW_AT_call_file = 0x58,
- DW_AT_call_line = 0x59,
- DW_AT_description = 0x5a,
- DW_AT_binary_scale = 0x5b,
- DW_AT_decimal_scale = 0x5c,
- DW_AT_small = 0x5d,
- DW_AT_decimal_sign = 0x5e,
- DW_AT_digit_count = 0x5f,
- DW_AT_picture_string = 0x60,
- DW_AT_mutable = 0x61,
- DW_AT_threads_scaled = 0x62,
- DW_AT_explicit = 0x63,
- DW_AT_object_pointer = 0x64,
- DW_AT_endianity = 0x65,
- DW_AT_elemental = 0x66,
- DW_AT_pure = 0x67,
- DW_AT_recursive = 0x68,
- DW_AT_signature = 0x69,
- DW_AT_main_subprogram = 0x6a,
- DW_AT_data_bit_offset = 0x6b,
- DW_AT_const_expr = 0x6c,
- DW_AT_enum_class = 0x6d,
- DW_AT_linkage_name = 0x6e,
-#ifdef INCLUDE_DWARF5_VALUES
- // Values to be added in Dwarf 5. Final value not yet specified. Values listed
- // may be different than other implementations. Use with caution.
- // TODO Update these values when Dwarf 5 is released.
- DW_AT_call_site_value = 0x6f,
- DW_AT_call_site_data_value = 0x70,
- DW_AT_call_site_target = 0x71,
- DW_AT_call_site_target_clobbered = 0x72,
- DW_AT_tail_call = 0x73,
- DW_AT_all_tail_call_sites = 0x74,
- DW_AT_all_call_sites = 0x75,
- DW_AT_all_source_call_sites = 0x76,
- DW_AT_call_site_parameter = 0x77,
- DW_AT_tail_call = 0x78,
- DW_AT_all_tail_call_sites = 0x79,
- DW_AT_all_call_sites = 0x7a,
- DW_AT_all_source_call_sites = 0x7b,
- DW_AT_rank = 0x7c,
- DW_AT_string_bitsize = 0x7d,
- DW_AT_string_byte_size = 0x7e,
- DW_AT_reference = 0x7f,
- DW_AT_rvalue_reference = 0x80,
- DW_AT_noreturn = 0x81,
- DW_AT_alignment = 0x82,
-#endif
- DW_AT_lo_user = 0x2000,
- DW_AT_hi_user = 0xffff
-};
-
-enum Form : uint8_t {
- DW_FORM_addr = 0x01,
- DW_FORM_block2 = 0x03,
- DW_FORM_block4 = 0x04,
- DW_FORM_data2 = 0x05,
- DW_FORM_data4 = 0x06,
- DW_FORM_data8 = 0x07,
- DW_FORM_string = 0x08,
- DW_FORM_block = 0x09,
- DW_FORM_block1 = 0x0a,
- DW_FORM_data1 = 0x0b,
- DW_FORM_flag = 0x0c,
- DW_FORM_sdata = 0x0d,
- DW_FORM_strp = 0x0e,
- DW_FORM_udata = 0x0f,
- DW_FORM_ref_addr = 0x10,
- DW_FORM_ref1 = 0x11,
- DW_FORM_ref2 = 0x12,
- DW_FORM_ref4 = 0x13,
- DW_FORM_ref8 = 0x14,
- DW_FORM_ref_udata = 0x15,
- DW_FORM_indirect = 0x16,
- DW_FORM_sec_offset = 0x17,
- DW_FORM_exprloc = 0x18,
- DW_FORM_flag_present = 0x19,
- DW_FORM_ref_sig8 = 0x20
-};
-
-enum Operation : uint16_t {
- DW_OP_addr = 0x03,
- DW_OP_deref = 0x06,
- DW_OP_const1u = 0x08,
- DW_OP_const1s = 0x09,
- DW_OP_const2u = 0x0a,
- DW_OP_const2s = 0x0b,
- DW_OP_const4u = 0x0c,
- DW_OP_const4s = 0x0d,
- DW_OP_const8u = 0x0e,
- DW_OP_const8s = 0x0f,
- DW_OP_constu = 0x10,
- DW_OP_consts = 0x11,
- DW_OP_dup = 0x12,
- DW_OP_drop = 0x13,
- DW_OP_over = 0x14,
- DW_OP_pick = 0x15,
- DW_OP_swap = 0x16,
- DW_OP_rot = 0x17,
- DW_OP_xderef = 0x18,
- DW_OP_abs = 0x19,
- DW_OP_and = 0x1a,
- DW_OP_div = 0x1b,
- DW_OP_minus = 0x1c,
- DW_OP_mod = 0x1d,
- DW_OP_mul = 0x1e,
- DW_OP_neg = 0x1f,
- DW_OP_not = 0x20,
- DW_OP_or = 0x21,
- DW_OP_plus = 0x22,
- DW_OP_plus_uconst = 0x23,
- DW_OP_shl = 0x24,
- DW_OP_shr = 0x25,
- DW_OP_shra = 0x26,
- DW_OP_xor = 0x27,
- DW_OP_skip = 0x2f,
- DW_OP_bra = 0x28,
- DW_OP_eq = 0x29,
- DW_OP_ge = 0x2a,
- DW_OP_gt = 0x2b,
- DW_OP_le = 0x2c,
- DW_OP_lt = 0x2d,
- DW_OP_ne = 0x2e,
- DW_OP_lit0 = 0x30,
- DW_OP_lit1 = 0x31,
- DW_OP_lit2 = 0x32,
- DW_OP_lit3 = 0x33,
- DW_OP_lit4 = 0x34,
- DW_OP_lit5 = 0x35,
- DW_OP_lit6 = 0x36,
- DW_OP_lit7 = 0x37,
- DW_OP_lit8 = 0x38,
- DW_OP_lit9 = 0x39,
- DW_OP_lit10 = 0x3a,
- DW_OP_lit11 = 0x3b,
- DW_OP_lit12 = 0x3c,
- DW_OP_lit13 = 0x3d,
- DW_OP_lit14 = 0x3e,
- DW_OP_lit15 = 0x3f,
- DW_OP_lit16 = 0x40,
- DW_OP_lit17 = 0x41,
- DW_OP_lit18 = 0x42,
- DW_OP_lit19 = 0x43,
- DW_OP_lit20 = 0x44,
- DW_OP_lit21 = 0x45,
- DW_OP_lit22 = 0x46,
- DW_OP_lit23 = 0x47,
- DW_OP_lit24 = 0x48,
- DW_OP_lit25 = 0x49,
- DW_OP_lit26 = 0x4a,
- DW_OP_lit27 = 0x4b,
- DW_OP_lit28 = 0x4c,
- DW_OP_lit29 = 0x4d,
- DW_OP_lit30 = 0x4e,
- DW_OP_lit31 = 0x4f,
- DW_OP_reg0 = 0x50,
- DW_OP_reg1 = 0x51,
- DW_OP_reg2 = 0x52,
- DW_OP_reg3 = 0x53,
- DW_OP_reg4 = 0x54,
- DW_OP_reg5 = 0x55,
- DW_OP_reg6 = 0x56,
- DW_OP_reg7 = 0x57,
- DW_OP_reg8 = 0x58,
- DW_OP_reg9 = 0x59,
- DW_OP_reg10 = 0x5a,
- DW_OP_reg11 = 0x5b,
- DW_OP_reg12 = 0x5c,
- DW_OP_reg13 = 0x5d,
- DW_OP_reg14 = 0x5e,
- DW_OP_reg15 = 0x5f,
- DW_OP_reg16 = 0x60,
- DW_OP_reg17 = 0x61,
- DW_OP_reg18 = 0x62,
- DW_OP_reg19 = 0x63,
- DW_OP_reg20 = 0x64,
- DW_OP_reg21 = 0x65,
- DW_OP_reg22 = 0x66,
- DW_OP_reg23 = 0x67,
- DW_OP_reg24 = 0x68,
- DW_OP_reg25 = 0x69,
- DW_OP_reg26 = 0x6a,
- DW_OP_reg27 = 0x6b,
- DW_OP_reg28 = 0x6c,
- DW_OP_reg29 = 0x6d,
- DW_OP_reg30 = 0x6e,
- DW_OP_reg31 = 0x6f,
- DW_OP_breg0 = 0x70,
- DW_OP_breg1 = 0x71,
- DW_OP_breg2 = 0x72,
- DW_OP_breg3 = 0x73,
- DW_OP_breg4 = 0x74,
- DW_OP_breg5 = 0x75,
- DW_OP_breg6 = 0x76,
- DW_OP_breg7 = 0x77,
- DW_OP_breg8 = 0x78,
- DW_OP_breg9 = 0x79,
- DW_OP_breg10 = 0x7a,
- DW_OP_breg11 = 0x7b,
- DW_OP_breg12 = 0x7c,
- DW_OP_breg13 = 0x7d,
- DW_OP_breg14 = 0x7e,
- DW_OP_breg15 = 0x7f,
- DW_OP_breg16 = 0x80,
- DW_OP_breg17 = 0x81,
- DW_OP_breg18 = 0x82,
- DW_OP_breg19 = 0x83,
- DW_OP_breg20 = 0x84,
- DW_OP_breg21 = 0x85,
- DW_OP_breg22 = 0x86,
- DW_OP_breg23 = 0x87,
- DW_OP_breg24 = 0x88,
- DW_OP_breg25 = 0x89,
- DW_OP_breg26 = 0x8a,
- DW_OP_breg27 = 0x8b,
- DW_OP_breg28 = 0x8c,
- DW_OP_breg29 = 0x8d,
- DW_OP_breg30 = 0x8e,
- DW_OP_breg31 = 0x8f,
- DW_OP_regx = 0x90,
- DW_OP_fbreg = 0x91,
- DW_OP_bregx = 0x92,
- DW_OP_piece = 0x93,
- DW_OP_deref_size = 0x94,
- DW_OP_xderef_size = 0x95,
- DW_OP_nop = 0x96,
- DW_OP_push_object_address = 0x97,
- DW_OP_call2 = 0x98,
- DW_OP_call4 = 0x99,
- DW_OP_call_ref = 0x9a,
- DW_OP_form_tls_address = 0x9b,
- DW_OP_call_frame_cfa = 0x9c,
- DW_OP_bit_piece = 0x9d,
- DW_OP_implicit_value = 0x9e,
- DW_OP_stack_value = 0x9f,
-#ifdef INCLUDE_DWARF5_VALUES
- // Values to be added in Dwarf 5. Final value not yet specified. Values listed
- // may be different than other implementations. Use with caution.
- // TODO Update these values when Dwarf 5 is released.
- DW_OP_entry_value = 0xa0,
- DW_OP_const_type = 0xa1,
- DW_OP_regval_type = 0xa2,
- DW_OP_deref_type = 0xa3,
- DW_OP_xderef_type = 0xa4,
- DW_OP_convert = 0xa5,
- DW_OP_reinterpret = 0xa6,
-#endif
- DW_OP_lo_user = 0xe0,
- DW_OP_hi_user = 0xff
-};
-
-enum BaseTypeEncoding : uint8_t {
- DW_ATE_address = 0x01,
- DW_ATE_boolean = 0x02,
- DW_ATE_complex_float = 0x03,
- DW_ATE_float = 0x04,
- DW_ATE_signed = 0x05,
- DW_ATE_signed_char = 0x06,
- DW_ATE_unsigned = 0x07,
- DW_ATE_unsigned_char = 0x08,
- DW_ATE_imaginary_float = 0x09,
- DW_ATE_packed_decimal = 0x0a,
- DW_ATE_numeric_string = 0x0b,
- DW_ATE_edited = 0x0c,
- DW_ATE_signed_fixed = 0x0d,
- DW_ATE_unsigned_fixed = 0x0e,
- DW_ATE_decimal_float = 0x0f,
- DW_ATE_UTF = 0x10,
- DW_ATE_lo_user = 0x80,
- DW_ATE_hi_user = 0xff
-};
-
-enum DecimalSign : uint8_t {
- DW_DS_unsigned = 0x01,
- DW_DS_leading_overpunch = 0x02,
- DW_DS_trailing_overpunch = 0x03,
- DW_DS_leading_separate = 0x04,
- DW_DS_trailing_separate = 0x05
-};
-
-enum Endianity : uint8_t {
- DW_END_default = 0x00,
- DW_END_big = 0x01,
- DW_END_little = 0x02,
- DW_END_lo_user = 0x40,
- DW_END_hi_user = 0xff
-};
-
-enum Accessibility : uint8_t {
- DW_ACCESS_public = 0x01,
- DW_ACCESS_protected = 0x02,
- DW_ACCESS_private = 0x03
-};
-
-enum Visibility : uint8_t {
- DW_VIS_local = 0x01,
- DW_VIS_exported = 0x02,
- DW_VIS_qualified = 0x03
-};
-
-enum Virtuality : uint8_t {
- DW_VIRTUALITY_none = 0x00,
- DW_VIRTUALITY_virtual = 0x01,
- DW_VIRTUALITY_pure_virtual = 0x02
-};
-
-enum Language {
- DW_LANG_C89 = 0x01,
- DW_LANG_C = 0x02,
- DW_LANG_Ada83 = 0x03,
- DW_LANG_C_plus_plus = 0x04,
- DW_LANG_Cobol74 = 0x05,
- DW_LANG_Cobol85 = 0x06,
- DW_LANG_Fortran77 = 0x07,
- DW_LANG_Fortran90 = 0x08,
- DW_LANG_Pascal83 = 0x09,
- DW_LANG_Modula2 = 0x0a,
- DW_LANG_Java = 0x0b,
- DW_LANG_C99 = 0x0c,
- DW_LANG_Ada95 = 0x0d,
- DW_LANG_Fortran95 = 0x0e,
- DW_LANG_PLI = 0x0f,
- DW_LANG_ObjC = 0x10,
- DW_LANG_ObjC_plus_plus = 0x11,
- DW_LANG_UPC = 0x12,
- DW_LANG_D = 0x13,
- DW_LANG_Python = 0x14,
-#ifdef INCLUDE_DWARF5_VALUES
- // Values to be added in Dwarf 5. Final value not yet specified. Values listed
- // may be different than other implementations. Use with caution.
- // TODO Update these values when Dwarf 5 is released.
- DW_LANG_OpenCL = 0x15,
- DW_LANG_Go = 0x16,
- DW_LANG_Modula3 = 0x17,
- DW_LANG_Haskell = 0x18,
- DW_LANG_C_plus_plus_03 = 0x19,
- DW_LANG_C_plus_plus_11 = 0x1a,
- DW_LANG_OCaml = 0x1b,
- DW_LANG_Rust = 0x1c,
- DW_LANG_C11 = 0x1d,
- DW_LANG_Swift = 0x1e,
- DW_LANG_Julia = 0x1f,
-#endif
- DW_LANG_lo_user = 0x8000,
- DW_LANG_hi_user = 0xffff
-};
-
-enum Identifier : uint8_t {
- DW_ID_case_sensitive = 0x00,
- DW_ID_up_case = 0x01,
- DW_ID_down_case = 0x02,
- DW_ID_case_insensitive = 0x03
-};
-
-enum CallingConvention : uint8_t {
- DW_CC_normal = 0x01,
- DW_CC_program = 0x02,
- DW_CC_nocall = 0x03,
- DW_CC_lo_user = 0x40,
- DW_CC_hi_user = 0xff
-};
-
-enum Inline : uint8_t {
- DW_INL_not_inlined = 0x00,
- DW_INL_inlined = 0x01,
- DW_INL_declared_not_inlined = 0x02,
- DW_INL_declared_inlined = 0x03
-};
-
-enum ArrayOrdering : uint8_t {
- DW_ORD_row_major = 0x00,
- DW_ORD_col_major = 0x01
-};
-
-enum DiscriminantList : uint8_t {
- DW_DSC_label = 0x00,
- DW_DSC_range = 0x01
-};
-
-enum LineNumberOpcode : uint8_t {
- DW_LNS_copy = 0x01,
- DW_LNS_advance_pc = 0x02,
- DW_LNS_advance_line = 0x03,
- DW_LNS_set_file = 0x04,
- DW_LNS_set_column = 0x05,
- DW_LNS_negate_stmt = 0x06,
- DW_LNS_set_basic_block = 0x07,
- DW_LNS_const_add_pc = 0x08,
- DW_LNS_fixed_advance_pc = 0x09,
- DW_LNS_set_prologue_end = 0x0a,
- DW_LNS_set_epilogue_begin = 0x0b,
- DW_LNS_set_isa = 0x0c
-};
-
-enum LineNumberExtendedOpcode : uint8_t {
- DW_LNE_end_sequence = 0x01,
- DW_LNE_set_address = 0x02,
- DW_LNE_define_file = 0x03,
- DW_LNE_set_discriminator = 0x04,
- DW_LNE_lo_user = 0x80,
- DW_LNE_hi_user = 0xff
-};
-
-#ifdef INCLUDE_DWARF5_VALUES
-enum LineNumberFormat : uint8_t {
- // Values to be added in Dwarf 5. Final value not yet specified. Values listed
- // may be different than other implementations. Use with caution.
- // TODO Update these values when Dwarf 5 is released.
- //
- DW_LNF_path = 0x1,
- DW_LNF_include_index = 0x2,
- DW_LNF_timestamp = 0x3,
- DW_LNF_size = 0x4,
- DW_LNF_MD5 = 0x5,
- DW_LNF_lo_user = 0x2000,
- DW_LNF_hi_user = 0x3fff
-};
-#endif
-
-enum MacroInfo : uint8_t {
- DW_MACINFO_define = 0x01,
- DW_MACINFO_undef = 0x02,
- DW_MACINFO_start_file = 0x03,
- DW_MACINFO_end_file = 0x04,
- DW_MACINFO_vendor_ext = 0xff
-};
-
-#ifdef INCLUDE_DWARF5_VALUES
-enum Macro : uint8_t {
- // Values to be added in Dwarf 5. Final value not yet specified. Values listed
- // may be different than other implementations. Use with caution.
- // TODO Update these values when Dwarf 5 is released.
- DW_MACRO_define = 0x01,
- DW_MACRO_undef = 0x02,
- DW_MACRO_start_file = 0x03,
- DW_MACRO_end_file = 0x04,
- DW_MACRO_define_indirect = 0x05,
- DW_MACRO_undef_indirect = 0x06,
- DW_MACRO_transparent_include = 0x07,
- DW_MACRO_define_indirectx = 0x0b,
- DW_MACRO_undef_indirectx = 0x0c,
- DW_MACRO_lo_user = 0xe0,
- DW_MACRO_hi_user = 0xff
-};
-#endif
-
-const uint32_t CIE_ID_32 = 0xffffffff;
-const uint64_t CIE_ID_64 = 0xffffffffffffffff;
-
-enum CallFrameInstruction : uint8_t {
- DW_CFA_advance_loc = 0x40,
- DW_CFA_offset = 0x80,
- DW_CFA_restore = 0xc0,
- DW_CFA_nop = 0x00,
- DW_CFA_set_loc = 0x01,
- DW_CFA_advance_loc1 = 0x02,
- DW_CFA_advance_loc2 = 0x03,
- DW_CFA_advance_loc4 = 0x04,
- DW_CFA_offset_extended = 0x05,
- DW_CFA_restore_extended = 0x06,
- DW_CFA_undefined = 0x07,
- DW_CFA_same_value = 0x08,
- DW_CFA_register = 0x09,
- DW_CFA_remember_state = 0x0a,
- DW_CFA_restore_state = 0x0b,
- DW_CFA_def_cfa = 0x0c,
- DW_CFA_def_cfa_register = 0x0d,
- DW_CFA_def_cfa_offset = 0x0e,
- DW_CFA_def_cfa_expression = 0x0f,
- DW_CFA_expression = 0x10,
- DW_CFA_offset_extended_sf = 0x11,
- DW_CFA_def_cfa_sf = 0x12,
- DW_CFA_def_cfa_offset_sf = 0x13,
- DW_CFA_val_offset = 0x14,
- DW_CFA_val_offset_sf = 0x15,
- DW_CFA_val_expression = 0x16,
- DW_CFA_lo_user = 0x1c,
- DW_CFA_hi_user = 0x3f
-};
-
-enum ExceptionHeaderValueFormat : uint8_t {
- DW_EH_PE_native = 0x00,
- DW_EH_PE_uleb128 = 0x01,
- DW_EH_PE_udata2 = 0x02,
- DW_EH_PE_udata4 = 0x03,
- DW_EH_PE_udata8 = 0x04,
- DW_EH_PE_sleb128 = 0x09,
- DW_EH_PE_sdata2 = 0x0A,
- DW_EH_PE_sdata4 = 0x0B,
- DW_EH_PE_sdata8 = 0x0C,
- DW_EH_PE_omit = 0xFF,
-};
-
-enum ExceptionHeaderValueApplication : uint8_t {
- DW_EH_PE_absptr = 0x00,
- DW_EH_PE_pcrel = 0x10,
- DW_EH_PE_textrel = 0x20,
- DW_EH_PE_datarel = 0x30,
- DW_EH_PE_funcrel = 0x40,
- DW_EH_PE_aligned = 0x50,
-};
-
-} // namespace dwarf
-} // namespace art
-
-#endif // ART_COMPILER_DEBUG_DWARF_DWARF_CONSTANTS_H_
diff --git a/compiler/debug/dwarf/dwarf_test.cc b/compiler/debug/dwarf/dwarf_test.cc
index 5491596dd8..5946af8d55 100644
--- a/compiler/debug/dwarf/dwarf_test.cc
+++ b/compiler/debug/dwarf/dwarf_test.cc
@@ -16,11 +16,11 @@
#include "dwarf_test.h"
-#include "debug/dwarf/debug_frame_opcode_writer.h"
-#include "debug/dwarf/debug_info_entry_writer.h"
-#include "debug/dwarf/debug_line_opcode_writer.h"
-#include "debug/dwarf/dwarf_constants.h"
-#include "debug/dwarf/headers.h"
+#include "dwarf/debug_frame_opcode_writer.h"
+#include "dwarf/debug_info_entry_writer.h"
+#include "dwarf/debug_line_opcode_writer.h"
+#include "dwarf/dwarf_constants.h"
+#include "dwarf/headers.h"
#include "gtest/gtest.h"
namespace art {
diff --git a/compiler/debug/dwarf/dwarf_test.h b/compiler/debug/dwarf/dwarf_test.h
index 6b039a7b5f..e51f807dd4 100644
--- a/compiler/debug/dwarf/dwarf_test.h
+++ b/compiler/debug/dwarf/dwarf_test.h
@@ -29,9 +29,9 @@
#include "base/os.h"
#include "base/unix_file/fd_file.h"
#include "common_compiler_test.h"
+#include "elf/elf_builder.h"
#include "gtest/gtest.h"
-#include "linker/elf_builder.h"
-#include "linker/file_output_stream.h"
+#include "stream/file_output_stream.h"
namespace art {
namespace dwarf {
@@ -63,8 +63,8 @@ class DwarfTest : public CommonCompilerTest {
InstructionSet isa =
(sizeof(typename ElfTypes::Addr) == 8) ? InstructionSet::kX86_64 : InstructionSet::kX86;
ScratchFile file;
- linker::FileOutputStream output_stream(file.GetFile());
- linker::ElfBuilder<ElfTypes> builder(isa, nullptr, &output_stream);
+ FileOutputStream output_stream(file.GetFile());
+ ElfBuilder<ElfTypes> builder(isa, &output_stream);
builder.Start();
if (!debug_info_data_.empty()) {
builder.WriteSection(".debug_info", &debug_info_data_);
diff --git a/compiler/debug/dwarf/expression.h b/compiler/debug/dwarf/expression.h
deleted file mode 100644
index fafc0462d6..0000000000
--- a/compiler/debug/dwarf/expression.h
+++ /dev/null
@@ -1,121 +0,0 @@
-/*
- * 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.
- */
-
-#ifndef ART_COMPILER_DEBUG_DWARF_EXPRESSION_H_
-#define ART_COMPILER_DEBUG_DWARF_EXPRESSION_H_
-
-#include <cstddef>
-#include <cstdint>
-
-#include "debug/dwarf/dwarf_constants.h"
-#include "debug/dwarf/writer.h"
-
-namespace art {
-namespace dwarf {
-
-// Writer for DWARF expressions which are used in .debug_info and .debug_loc sections.
-// See the DWARF specification for the precise meaning of the opcodes.
-// If multiple equivalent encodings are possible, it will choose the most compact one.
-// The writer is not exhaustive - it only implements opcodes we have needed so far.
-class Expression : private Writer<> {
- public:
- using Writer<>::data;
- using Writer<>::size;
-
- // Push signed integer on the stack.
- void WriteOpConsts(int32_t value) {
- if (0 <= value && value < 32) {
- PushUint8(DW_OP_lit0 + value);
- } else {
- PushUint8(DW_OP_consts);
- PushSleb128(value);
- }
- }
-
- // Push unsigned integer on the stack.
- void WriteOpConstu(uint32_t value) {
- if (value < 32) {
- PushUint8(DW_OP_lit0 + value);
- } else {
- PushUint8(DW_OP_constu);
- PushUleb128(value);
- }
- }
-
- // Variable is stored in given register.
- void WriteOpReg(uint32_t dwarf_reg_num) {
- if (dwarf_reg_num < 32) {
- PushUint8(DW_OP_reg0 + dwarf_reg_num);
- } else {
- PushUint8(DW_OP_regx);
- PushUleb128(dwarf_reg_num);
- }
- }
-
- // Variable is stored on stack. Also see DW_AT_frame_base.
- void WriteOpFbreg(int32_t stack_offset) {
- PushUint8(DW_OP_fbreg);
- PushSleb128(stack_offset);
- }
-
- // The variable is stored in multiple locations (pieces).
- void WriteOpPiece(uint32_t num_bytes) {
- PushUint8(DW_OP_piece);
- PushUleb128(num_bytes);
- }
-
- // Loads 32-bit or 64-bit value depending on architecture.
- void WriteOpDeref() { PushUint8(DW_OP_deref); }
-
- // Loads value of given byte size.
- void WriteOpDerefSize(uint8_t num_bytes) {
- PushUint8(DW_OP_deref_size);
- PushUint8(num_bytes);
- }
-
- // Pop two values and push their sum.
- void WriteOpPlus() { PushUint8(DW_OP_plus); }
-
- // Add constant value to value on top of stack.
- void WriteOpPlusUconst(uint32_t offset) {
- PushUint8(DW_OP_plus_uconst);
- PushUleb128(offset);
- }
-
- // Negate top of stack.
- void WriteOpNeg() { PushUint8(DW_OP_neg); }
-
- // Pop two values and push their bitwise-AND.
- void WriteOpAnd() { PushUint8(DW_OP_and); }
-
- // Push stack base pointer as determined from .debug_frame.
- void WriteOpCallFrameCfa() { PushUint8(DW_OP_call_frame_cfa); }
-
- // Push address of the variable we are working with.
- void WriteOpPushObjectAddress() { PushUint8(DW_OP_push_object_address); }
-
- // Return the top stack as the value of the variable.
- // Otherwise, the top of stack is the variable's location.
- void WriteOpStackValue() { PushUint8(DW_OP_stack_value); }
-
- explicit Expression(std::vector<uint8_t>* buffer) : Writer<>(buffer) {
- buffer->clear();
- }
-};
-} // namespace dwarf
-} // namespace art
-
-#endif // ART_COMPILER_DEBUG_DWARF_EXPRESSION_H_
diff --git a/compiler/debug/dwarf/headers.h b/compiler/debug/dwarf/headers.h
deleted file mode 100644
index 3cc8ad8290..0000000000
--- a/compiler/debug/dwarf/headers.h
+++ /dev/null
@@ -1,162 +0,0 @@
-/*
- * 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_DEBUG_DWARF_HEADERS_H_
-#define ART_COMPILER_DEBUG_DWARF_HEADERS_H_
-
-#include <cstdint>
-
-#include "base/array_ref.h"
-#include "debug/dwarf/debug_frame_opcode_writer.h"
-#include "debug/dwarf/debug_info_entry_writer.h"
-#include "debug/dwarf/debug_line_opcode_writer.h"
-#include "debug/dwarf/dwarf_constants.h"
-#include "debug/dwarf/register.h"
-#include "debug/dwarf/writer.h"
-
-namespace art {
-namespace dwarf {
-
-// Note that all headers start with 32-bit length.
-// DWARF also supports 64-bit lengths, but we never use that.
-// It is intended to support very large debug sections (>4GB),
-// and compilers are expected *not* to use it by default.
-// In particular, it is not related to machine architecture.
-
-// Write common information entry (CIE) to .debug_frame or .eh_frame section.
-template<typename Vector>
-void WriteCIE(bool is64bit,
- Reg return_address_register,
- const DebugFrameOpCodeWriter<Vector>& opcodes,
- std::vector<uint8_t>* buffer) {
- static_assert(std::is_same<typename Vector::value_type, uint8_t>::value, "Invalid value type");
-
- Writer<> writer(buffer);
- size_t cie_header_start_ = writer.data()->size();
- writer.PushUint32(0); // Length placeholder.
- writer.PushUint32(0xFFFFFFFF); // CIE id.
- writer.PushUint8(1); // Version.
- writer.PushString("zR");
- writer.PushUleb128(DebugFrameOpCodeWriter<Vector>::kCodeAlignmentFactor);
- writer.PushSleb128(DebugFrameOpCodeWriter<Vector>::kDataAlignmentFactor);
- writer.PushUleb128(return_address_register.num()); // ubyte in DWARF2.
- writer.PushUleb128(1); // z: Augmentation data size.
- if (is64bit) {
- writer.PushUint8(DW_EH_PE_absptr | DW_EH_PE_udata8); // R: Pointer encoding.
- } else {
- writer.PushUint8(DW_EH_PE_absptr | DW_EH_PE_udata4); // R: Pointer encoding.
- }
- writer.PushData(opcodes.data());
- writer.Pad(is64bit ? 8 : 4);
- writer.UpdateUint32(cie_header_start_, writer.data()->size() - cie_header_start_ - 4);
-}
-
-// Write frame description entry (FDE) to .debug_frame or .eh_frame section.
-inline
-void WriteFDE(bool is64bit,
- uint64_t cie_pointer, // Offset of relevant CIE in debug_frame setcion.
- uint64_t code_address,
- uint64_t code_size,
- const ArrayRef<const uint8_t>& opcodes,
- /*inout*/ std::vector<uint8_t>* buffer) {
- Writer<> writer(buffer);
- size_t fde_header_start = writer.data()->size();
- writer.PushUint32(0); // Length placeholder.
- writer.PushUint32(cie_pointer);
- // Relocate code_address if it has absolute value.
- if (is64bit) {
- writer.PushUint64(code_address);
- writer.PushUint64(code_size);
- } else {
- writer.PushUint32(code_address);
- writer.PushUint32(code_size);
- }
- writer.PushUleb128(0); // Augmentation data size.
- writer.PushData(opcodes.data(), opcodes.size());
- writer.Pad(is64bit ? 8 : 4);
- writer.UpdateUint32(fde_header_start, writer.data()->size() - fde_header_start - 4);
-}
-
-// Write compilation unit (CU) to .debug_info section.
-template<typename Vector>
-void WriteDebugInfoCU(uint32_t debug_abbrev_offset,
- const DebugInfoEntryWriter<Vector>& entries,
- std::vector<uint8_t>* debug_info) {
- static_assert(std::is_same<typename Vector::value_type, uint8_t>::value, "Invalid value type");
-
- Writer<> writer(debug_info);
- size_t start = writer.data()->size();
- writer.PushUint32(0); // Length placeholder.
- writer.PushUint16(4); // Version.
- writer.PushUint32(debug_abbrev_offset);
- writer.PushUint8(entries.Is64bit() ? 8 : 4);
- size_t entries_offset = writer.data()->size();
- DCHECK_EQ(entries_offset, DebugInfoEntryWriter<Vector>::kCompilationUnitHeaderSize);
- writer.PushData(entries.data());
- writer.UpdateUint32(start, writer.data()->size() - start - 4);
-}
-
-struct FileEntry {
- std::string file_name;
- int directory_index;
- int modification_time;
- int file_size;
-};
-
-// Write line table to .debug_line section.
-template<typename Vector>
-void WriteDebugLineTable(const std::vector<std::string>& include_directories,
- const std::vector<FileEntry>& files,
- const DebugLineOpCodeWriter<Vector>& opcodes,
- std::vector<uint8_t>* debug_line) {
- static_assert(std::is_same<typename Vector::value_type, uint8_t>::value, "Invalid value type");
-
- Writer<> writer(debug_line);
- size_t header_start = writer.data()->size();
- writer.PushUint32(0); // Section-length placeholder.
- writer.PushUint16(3); // .debug_line version.
- size_t header_length_pos = writer.data()->size();
- writer.PushUint32(0); // Header-length placeholder.
- writer.PushUint8(1 << opcodes.GetCodeFactorBits());
- writer.PushUint8(DebugLineOpCodeWriter<Vector>::kDefaultIsStmt ? 1 : 0);
- writer.PushInt8(DebugLineOpCodeWriter<Vector>::kLineBase);
- writer.PushUint8(DebugLineOpCodeWriter<Vector>::kLineRange);
- writer.PushUint8(DebugLineOpCodeWriter<Vector>::kOpcodeBase);
- static const int opcode_lengths[DebugLineOpCodeWriter<Vector>::kOpcodeBase] = {
- 0, 0, 1, 1, 1, 1, 0, 0, 0, 1, 0, 0, 1 };
- for (int i = 1; i < DebugLineOpCodeWriter<Vector>::kOpcodeBase; i++) {
- writer.PushUint8(opcode_lengths[i]);
- }
- for (const std::string& directory : include_directories) {
- writer.PushData(directory.data(), directory.size() + 1);
- }
- writer.PushUint8(0); // Terminate include_directories list.
- for (const FileEntry& file : files) {
- writer.PushData(file.file_name.data(), file.file_name.size() + 1);
- writer.PushUleb128(file.directory_index);
- writer.PushUleb128(file.modification_time);
- writer.PushUleb128(file.file_size);
- }
- writer.PushUint8(0); // Terminate file list.
- writer.UpdateUint32(header_length_pos, writer.data()->size() - header_length_pos - 4);
- writer.PushData(opcodes.data());
- writer.UpdateUint32(header_start, writer.data()->size() - header_start - 4);
-}
-
-} // namespace dwarf
-} // namespace art
-
-#endif // ART_COMPILER_DEBUG_DWARF_HEADERS_H_
diff --git a/compiler/debug/dwarf/register.h b/compiler/debug/dwarf/register.h
deleted file mode 100644
index 24bacac292..0000000000
--- a/compiler/debug/dwarf/register.h
+++ /dev/null
@@ -1,62 +0,0 @@
-/*
- * 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_DEBUG_DWARF_REGISTER_H_
-#define ART_COMPILER_DEBUG_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 cannot 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.
- // libunwind might struggle with the new mapping as well.
-
- static Reg ArmCore(int num) { return Reg(num); } // R0-R15.
- static Reg ArmFp(int num) { return Reg(64 + num); } // S0–S31.
- static Reg ArmDp(int num) { return Reg(256 + num); } // D0–D31.
- static Reg Arm64Core(int num) { return Reg(num); } // X0-X31.
- 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 MipsFp(int num) { return Reg(32 + num); }
- static Reg Mips64Fp(int num) { return Reg(32 + 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_DEBUG_DWARF_REGISTER_H_
diff --git a/compiler/debug/dwarf/writer.h b/compiler/debug/dwarf/writer.h
deleted file mode 100644
index c09d97aa79..0000000000
--- a/compiler/debug/dwarf/writer.h
+++ /dev/null
@@ -1,184 +0,0 @@
-/*
- * 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_DEBUG_DWARF_WRITER_H_
-#define ART_COMPILER_DEBUG_DWARF_WRITER_H_
-
-#include <type_traits>
-#include <vector>
-
-#include <android-base/logging.h>
-
-#include "base/bit_utils.h"
-#include "base/leb128.h"
-
-namespace art {
-namespace dwarf {
-
-// The base class for all DWARF writers.
-template <typename Vector = std::vector<uint8_t>>
-class Writer {
- static_assert(std::is_same<typename Vector::value_type, uint8_t>::value, "Invalid value type");
-
- 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 uint8_t* ptr, size_t num_bytes) {
- data_->insert(data_->end(), ptr, ptr + num_bytes);
- }
-
- void PushData(const char* ptr, size_t num_bytes) {
- data_->insert(data_->end(), ptr, ptr + num_bytes);
- }
-
- void PushData(const Vector* buffer) {
- data_->insert(data_->end(), buffer->begin(), buffer->end());
- }
-
- 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 UpdateUleb128(size_t offset, uint32_t value) {
- DCHECK_LE(offset + UnsignedLeb128Size(value), data_->size());
- UpdateUnsignedLeb128(data_->data() + offset, value);
- }
-
- void Pop() {
- return data_->pop_back();
- }
-
- void Pad(int alignment) {
- DCHECK_NE(alignment, 0);
- data_->resize(RoundUp(data_->size(), alignment), 0);
- }
-
- const Vector* data() const {
- return data_;
- }
-
- size_t size() const {
- return data_->size();
- }
-
- explicit Writer(Vector* buffer) : data_(buffer) { }
-
- private:
- Vector* const data_;
-
- DISALLOW_COPY_AND_ASSIGN(Writer);
-};
-
-} // namespace dwarf
-} // namespace art
-
-#endif // ART_COMPILER_DEBUG_DWARF_WRITER_H_
diff --git a/compiler/debug/elf_debug_frame_writer.h b/compiler/debug/elf_debug_frame_writer.h
index 1f827eaefc..44b70ff930 100644
--- a/compiler/debug/elf_debug_frame_writer.h
+++ b/compiler/debug/elf_debug_frame_writer.h
@@ -20,11 +20,11 @@
#include <vector>
#include "arch/instruction_set.h"
-#include "debug/dwarf/debug_frame_opcode_writer.h"
-#include "debug/dwarf/dwarf_constants.h"
-#include "debug/dwarf/headers.h"
#include "debug/method_debug_info.h"
-#include "linker/elf_builder.h"
+#include "dwarf/debug_frame_opcode_writer.h"
+#include "dwarf/dwarf_constants.h"
+#include "dwarf/headers.h"
+#include "elf/elf_builder.h"
namespace art {
namespace debug {
@@ -166,7 +166,7 @@ static void WriteCIE(InstructionSet isa, /*inout*/ std::vector<uint8_t>* buffer)
}
template<typename ElfTypes>
-void WriteCFISection(linker::ElfBuilder<ElfTypes>* builder,
+void WriteCFISection(ElfBuilder<ElfTypes>* builder,
const ArrayRef<const MethodDebugInfo>& method_infos) {
typedef typename ElfTypes::Addr Elf_Addr;
diff --git a/compiler/debug/elf_debug_info_writer.h b/compiler/debug/elf_debug_info_writer.h
index 05a4a3e32b..8eead4ecef 100644
--- a/compiler/debug/elf_debug_info_writer.h
+++ b/compiler/debug/elf_debug_info_writer.h
@@ -22,17 +22,17 @@
#include <vector>
#include "art_field-inl.h"
-#include "debug/dwarf/debug_abbrev_writer.h"
-#include "debug/dwarf/debug_info_entry_writer.h"
#include "debug/elf_compilation_unit.h"
#include "debug/elf_debug_loc_writer.h"
#include "debug/method_debug_info.h"
#include "dex/code_item_accessors-inl.h"
#include "dex/dex_file-inl.h"
#include "dex/dex_file.h"
+#include "dwarf/debug_abbrev_writer.h"
+#include "dwarf/debug_info_entry_writer.h"
+#include "elf/elf_builder.h"
#include "heap_poisoning.h"
#include "linear_alloc.h"
-#include "linker/elf_builder.h"
#include "mirror/array.h"
#include "mirror/class-inl.h"
#include "mirror/class.h"
@@ -59,7 +59,7 @@ class ElfDebugInfoWriter {
using Elf_Addr = typename ElfTypes::Addr;
public:
- explicit ElfDebugInfoWriter(linker::ElfBuilder<ElfTypes>* builder)
+ explicit ElfDebugInfoWriter(ElfBuilder<ElfTypes>* builder)
: builder_(builder),
debug_abbrev_(&debug_abbrev_buffer_) {
}
@@ -80,7 +80,7 @@ class ElfDebugInfoWriter {
}
private:
- linker::ElfBuilder<ElfTypes>* builder_;
+ ElfBuilder<ElfTypes>* builder_;
std::vector<uint8_t> debug_abbrev_buffer_;
dwarf::DebugAbbrevWriter<> debug_abbrev_;
std::vector<uint8_t> debug_loc_;
diff --git a/compiler/debug/elf_debug_line_writer.h b/compiler/debug/elf_debug_line_writer.h
index f95912a2d1..479725be99 100644
--- a/compiler/debug/elf_debug_line_writer.h
+++ b/compiler/debug/elf_debug_line_writer.h
@@ -20,12 +20,12 @@
#include <unordered_set>
#include <vector>
-#include "debug/dwarf/debug_line_opcode_writer.h"
-#include "debug/dwarf/headers.h"
#include "debug/elf_compilation_unit.h"
#include "debug/src_map_elem.h"
#include "dex/dex_file-inl.h"
-#include "linker/elf_builder.h"
+#include "dwarf/debug_line_opcode_writer.h"
+#include "dwarf/headers.h"
+#include "elf/elf_builder.h"
#include "oat_file.h"
#include "stack_map.h"
@@ -39,7 +39,7 @@ class ElfDebugLineWriter {
using Elf_Addr = typename ElfTypes::Addr;
public:
- explicit ElfDebugLineWriter(linker::ElfBuilder<ElfTypes>* builder) : builder_(builder) {
+ explicit ElfDebugLineWriter(ElfBuilder<ElfTypes>* builder) : builder_(builder) {
}
void Start() {
@@ -273,7 +273,7 @@ class ElfDebugLineWriter {
}
private:
- linker::ElfBuilder<ElfTypes>* builder_;
+ ElfBuilder<ElfTypes>* builder_;
};
} // namespace debug
diff --git a/compiler/debug/elf_debug_loc_writer.h b/compiler/debug/elf_debug_loc_writer.h
index b663291b4d..a5a84bbb10 100644
--- a/compiler/debug/elf_debug_loc_writer.h
+++ b/compiler/debug/elf_debug_loc_writer.h
@@ -22,9 +22,9 @@
#include "arch/instruction_set.h"
#include "compiled_method.h"
-#include "debug/dwarf/debug_info_entry_writer.h"
-#include "debug/dwarf/register.h"
#include "debug/method_debug_info.h"
+#include "dwarf/debug_info_entry_writer.h"
+#include "dwarf/register.h"
#include "stack_map.h"
namespace art {
diff --git a/compiler/debug/elf_debug_reader.h b/compiler/debug/elf_debug_reader.h
deleted file mode 100644
index 1820e7cdc7..0000000000
--- a/compiler/debug/elf_debug_reader.h
+++ /dev/null
@@ -1,173 +0,0 @@
-/*
- * Copyright (C) 2018 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_DEBUG_ELF_DEBUG_READER_H_
-#define ART_COMPILER_DEBUG_ELF_DEBUG_READER_H_
-
-#include "base/array_ref.h"
-#include "debug/dwarf/headers.h"
-#include "elf.h"
-#include "xz_utils.h"
-
-#include <map>
-#include <string_view>
-
-namespace art {
-namespace debug {
-
-// Trivial ELF file reader.
-//
-// It is the bare minimum needed to read mini-debug-info symbols for unwinding.
-// We use it to merge JIT mini-debug-infos together or to prune them after GC.
-template <typename ElfTypes>
-class ElfDebugReader {
- public:
- // Note that the input buffer might be misaligned.
- typedef typename ElfTypes::Ehdr ALIGNED(1) Elf_Ehdr;
- typedef typename ElfTypes::Shdr ALIGNED(1) Elf_Shdr;
- typedef typename ElfTypes::Sym ALIGNED(1) Elf_Sym;
- typedef typename ElfTypes::Addr ALIGNED(1) Elf_Addr;
-
- // Call Frame Information.
- struct CFI {
- uint32_t length; // Length excluding the size of this field.
- int32_t cie_pointer; // Offset in the section or -1 for CIE.
-
- const uint8_t* data() const { return reinterpret_cast<const uint8_t*>(this); }
- size_t size() const { return sizeof(uint32_t) + length; }
- } PACKED(1);
-
- // Common Information Entry.
- struct CIE : public CFI {
- } PACKED(1);
-
- // Frame Description Entry.
- struct FDE : public CFI {
- Elf_Addr sym_addr;
- Elf_Addr sym_size;
- } PACKED(1);
-
- explicit ElfDebugReader(ArrayRef<const uint8_t> file) : file_(file) {
- header_ = Read<Elf_Ehdr>(/*offset=*/ 0);
- CHECK(header_->checkMagic());
- CHECK_EQ(header_->e_ehsize, sizeof(Elf_Ehdr));
- CHECK_EQ(header_->e_shentsize, sizeof(Elf_Shdr));
-
- // Find all ELF sections.
- sections_ = Read<Elf_Shdr>(header_->e_shoff, header_->e_shnum);
- for (const Elf_Shdr& section : sections_) {
- const char* name = Read<char>(sections_[header_->e_shstrndx].sh_offset + section.sh_name);
- section_map_[std::string_view(name)] = &section;
- }
-
- // Decompressed embedded debug symbols, if any.
- const Elf_Shdr* gnu_debugdata = section_map_[".gnu_debugdata"];
- if (gnu_debugdata != nullptr) {
- auto compressed = Read<uint8_t>(gnu_debugdata->sh_offset, gnu_debugdata->sh_size);
- XzDecompress(compressed, &decompressed_gnu_debugdata_);
- gnu_debugdata_reader_.reset(new ElfDebugReader(decompressed_gnu_debugdata_));
- }
- }
-
- explicit ElfDebugReader(std::vector<uint8_t>& file)
- : ElfDebugReader(ArrayRef<const uint8_t>(file)) {
- }
-
- const Elf_Ehdr* GetHeader() { return header_; }
-
- ArrayRef<Elf_Shdr> GetSections() { return sections_; }
-
- const Elf_Shdr* GetSection(const char* name) { return section_map_[name]; }
-
- template <typename VisitSym>
- void VisitFunctionSymbols(VisitSym visit_sym) {
- const Elf_Shdr* symtab = GetSection(".symtab");
- const Elf_Shdr* strtab = GetSection(".strtab");
- const Elf_Shdr* text = GetSection(".text");
- if (symtab != nullptr && strtab != nullptr) {
- CHECK_EQ(symtab->sh_entsize, sizeof(Elf_Sym));
- size_t count = symtab->sh_size / sizeof(Elf_Sym);
- for (const Elf_Sym& symbol : Read<Elf_Sym>(symtab->sh_offset, count)) {
- if (symbol.getType() == STT_FUNC && &sections_[symbol.st_shndx] == text) {
- visit_sym(symbol, Read<char>(strtab->sh_offset + symbol.st_name));
- }
- }
- }
- if (gnu_debugdata_reader_ != nullptr) {
- gnu_debugdata_reader_->VisitFunctionSymbols(visit_sym);
- }
- }
-
- template <typename VisitSym>
- void VisitDynamicSymbols(VisitSym visit_sym) {
- const Elf_Shdr* dynsym = GetSection(".dynsym");
- const Elf_Shdr* dynstr = GetSection(".dynstr");
- if (dynsym != nullptr && dynstr != nullptr) {
- CHECK_EQ(dynsym->sh_entsize, sizeof(Elf_Sym));
- size_t count = dynsym->sh_size / sizeof(Elf_Sym);
- for (const Elf_Sym& symbol : Read<Elf_Sym>(dynsym->sh_offset, count)) {
- visit_sym(symbol, Read<char>(dynstr->sh_offset + symbol.st_name));
- }
- }
- }
-
- template <typename VisitCIE, typename VisitFDE>
- void VisitDebugFrame(VisitCIE visit_cie, VisitFDE visit_fde) {
- const Elf_Shdr* debug_frame = GetSection(".debug_frame");
- if (debug_frame != nullptr) {
- for (size_t offset = 0; offset < debug_frame->sh_size;) {
- const CFI* entry = Read<CFI>(debug_frame->sh_offset + offset);
- DCHECK_LE(entry->size(), debug_frame->sh_size - offset);
- if (entry->cie_pointer == -1) {
- visit_cie(Read<CIE>(debug_frame->sh_offset + offset));
- } else {
- const FDE* fde = Read<FDE>(debug_frame->sh_offset + offset);
- visit_fde(fde, Read<CIE>(debug_frame->sh_offset + fde->cie_pointer));
- }
- offset += entry->size();
- }
- }
- if (gnu_debugdata_reader_ != nullptr) {
- gnu_debugdata_reader_->VisitDebugFrame(visit_cie, visit_fde);
- }
- }
-
- private:
- template<typename T>
- const T* Read(size_t offset) {
- DCHECK_LE(offset + sizeof(T), file_.size());
- return reinterpret_cast<const T*>(file_.data() + offset);
- }
-
- template<typename T>
- ArrayRef<const T> Read(size_t offset, size_t count) {
- DCHECK_LE(offset + count * sizeof(T), file_.size());
- return ArrayRef<const T>(Read<T>(offset), count);
- }
-
- ArrayRef<const uint8_t> const file_;
- const Elf_Ehdr* header_;
- ArrayRef<const Elf_Shdr> sections_;
- std::unordered_map<std::string_view, const Elf_Shdr*> section_map_;
- std::vector<uint8_t> decompressed_gnu_debugdata_;
- std::unique_ptr<ElfDebugReader> gnu_debugdata_reader_;
-
- DISALLOW_COPY_AND_ASSIGN(ElfDebugReader);
-};
-
-} // namespace debug
-} // namespace art
-#endif // ART_COMPILER_DEBUG_ELF_DEBUG_READER_H_
diff --git a/compiler/debug/elf_debug_writer.cc b/compiler/debug/elf_debug_writer.cc
index 3b7363be6a..cc74717edb 100644
--- a/compiler/debug/elf_debug_writer.cc
+++ b/compiler/debug/elf_debug_writer.cc
@@ -22,20 +22,20 @@
#include "base/array_ref.h"
#include "base/stl_util.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_debug_reader.h"
#include "debug/elf_symtab_writer.h"
#include "debug/method_debug_info.h"
-#include "debug/xz_utils.h"
-#include "elf.h"
-#include "linker/elf_builder.h"
-#include "linker/vector_output_stream.h"
+#include "dwarf/dwarf_constants.h"
+#include "elf/elf.h"
+#include "elf/elf_builder.h"
+#include "elf/elf_debug_reader.h"
+#include "elf/xz_utils.h"
#include "oat.h"
+#include "stream/vector_output_stream.h"
namespace art {
namespace debug {
@@ -43,7 +43,7 @@ namespace debug {
using ElfRuntimeTypes = std::conditional<sizeof(void*) == 4, ElfTypes32, ElfTypes64>::type;
template <typename ElfTypes>
-void WriteDebugInfo(linker::ElfBuilder<ElfTypes>* builder,
+void WriteDebugInfo(ElfBuilder<ElfTypes>* builder,
const DebugInfo& debug_info) {
// Write .strtab and .symtab.
WriteDebugSymbols(builder, /* mini-debug-info= */ false, debug_info);
@@ -112,7 +112,7 @@ void WriteDebugInfo(linker::ElfBuilder<ElfTypes>* builder,
template <typename ElfTypes>
static std::vector<uint8_t> MakeMiniDebugInfoInternal(
InstructionSet isa,
- const InstructionSetFeatures* features,
+ const InstructionSetFeatures* features ATTRIBUTE_UNUSED,
typename ElfTypes::Addr text_section_address,
size_t text_section_size,
typename ElfTypes::Addr dex_section_address,
@@ -120,9 +120,8 @@ static std::vector<uint8_t> MakeMiniDebugInfoInternal(
const DebugInfo& debug_info) {
std::vector<uint8_t> buffer;
buffer.reserve(KB);
- linker::VectorOutputStream out("Mini-debug-info ELF file", &buffer);
- std::unique_ptr<linker::ElfBuilder<ElfTypes>> builder(
- new linker::ElfBuilder<ElfTypes>(isa, features, &out));
+ VectorOutputStream out("Mini-debug-info ELF file", &buffer);
+ std::unique_ptr<ElfBuilder<ElfTypes>> builder(new ElfBuilder<ElfTypes>(isa, &out));
builder->Start(/* write_program_headers= */ false);
// Mirror ELF sections as NOBITS since the added symbols will reference them.
if (text_section_size != 0) {
@@ -174,7 +173,7 @@ std::vector<uint8_t> MakeMiniDebugInfo(
std::vector<uint8_t> MakeElfFileForJIT(
InstructionSet isa,
- const InstructionSetFeatures* features,
+ const InstructionSetFeatures* features ATTRIBUTE_UNUSED,
bool mini_debug_info,
const MethodDebugInfo& method_info) {
using ElfTypes = ElfRuntimeTypes;
@@ -184,9 +183,8 @@ std::vector<uint8_t> MakeElfFileForJIT(
debug_info.compiled_methods = ArrayRef<const MethodDebugInfo>(&method_info, 1);
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));
+ VectorOutputStream out("Debug ELF file", &buffer);
+ std::unique_ptr<ElfBuilder<ElfTypes>> builder(new ElfBuilder<ElfTypes>(isa, &out));
// No program headers since the ELF file is not linked and has no allocated sections.
builder->Start(/* write_program_headers= */ false);
builder->GetText()->AllocateVirtualMemory(method_info.code_address, method_info.code_size);
@@ -230,7 +228,7 @@ std::vector<uint8_t> MakeElfFileForJIT(
// Combine several mini-debug-info ELF files into one, while filtering some symbols.
std::vector<uint8_t> PackElfFileForJIT(
InstructionSet isa,
- const InstructionSetFeatures* features,
+ const InstructionSetFeatures* features ATTRIBUTE_UNUSED,
std::vector<ArrayRef<const uint8_t>>& added_elf_files,
std::vector<const void*>& removed_symbols,
/*out*/ size_t* num_symbols) {
@@ -250,9 +248,8 @@ std::vector<uint8_t> PackElfFileForJIT(
std::vector<uint8_t> inner_elf_file;
{
inner_elf_file.reserve(1 * KB); // Approximate size of ELF file with a single symbol.
- linker::VectorOutputStream out("Mini-debug-info ELF file for JIT", &inner_elf_file);
- std::unique_ptr<linker::ElfBuilder<ElfTypes>> builder(
- new linker::ElfBuilder<ElfTypes>(isa, features, &out));
+ VectorOutputStream out("Mini-debug-info ELF file for JIT", &inner_elf_file);
+ std::unique_ptr<ElfBuilder<ElfTypes>> builder(new ElfBuilder<ElfTypes>(isa, &out));
builder->Start(/*write_program_headers=*/ false);
auto* text = builder->GetText();
auto* strtab = builder->GetStrTab();
@@ -328,9 +325,8 @@ std::vector<uint8_t> PackElfFileForJIT(
XzCompress(ArrayRef<const uint8_t>(inner_elf_file), &gnu_debugdata);
outer_elf_file.reserve(KB + gnu_debugdata.size());
- linker::VectorOutputStream out("Mini-debug-info ELF file for JIT", &outer_elf_file);
- std::unique_ptr<linker::ElfBuilder<ElfTypes>> builder(
- new linker::ElfBuilder<ElfTypes>(isa, features, &out));
+ VectorOutputStream out("Mini-debug-info ELF file for JIT", &outer_elf_file);
+ std::unique_ptr<ElfBuilder<ElfTypes>> builder(new ElfBuilder<ElfTypes>(isa, &out));
builder->Start(/*write_program_headers=*/ false);
if (max_address > min_address) {
builder->GetText()->AllocateVirtualMemory(min_address, max_address - min_address);
@@ -345,16 +341,15 @@ std::vector<uint8_t> PackElfFileForJIT(
std::vector<uint8_t> WriteDebugElfFileForClasses(
InstructionSet isa,
- const InstructionSetFeatures* features,
+ const InstructionSetFeatures* features ATTRIBUTE_UNUSED,
const ArrayRef<mirror::Class*>& types)
REQUIRES_SHARED(Locks::mutator_lock_) {
using ElfTypes = ElfRuntimeTypes;
CHECK_EQ(sizeof(ElfTypes::Addr), static_cast<size_t>(GetInstructionSetPointerSize(isa)));
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));
+ VectorOutputStream out("Debug ELF file", &buffer);
+ std::unique_ptr<ElfBuilder<ElfTypes>> builder(new ElfBuilder<ElfTypes>(isa, &out));
// No program headers since the ELF file is not linked and has no allocated sections.
builder->Start(/* write_program_headers= */ false);
ElfDebugInfoWriter<ElfTypes> info_writer(builder.get());
@@ -370,10 +365,10 @@ std::vector<uint8_t> WriteDebugElfFileForClasses(
// Explicit instantiations
template void WriteDebugInfo<ElfTypes32>(
- linker::ElfBuilder<ElfTypes32>* builder,
+ ElfBuilder<ElfTypes32>* builder,
const DebugInfo& debug_info);
template void WriteDebugInfo<ElfTypes64>(
- linker::ElfBuilder<ElfTypes64>* builder,
+ ElfBuilder<ElfTypes64>* builder,
const DebugInfo& debug_info);
} // namespace debug
diff --git a/compiler/debug/elf_debug_writer.h b/compiler/debug/elf_debug_writer.h
index 90580b4676..14a5edbace 100644
--- a/compiler/debug/elf_debug_writer.h
+++ b/compiler/debug/elf_debug_writer.h
@@ -19,12 +19,13 @@
#include <vector>
+#include "arch/instruction_set_features.h"
#include "base/array_ref.h"
#include "base/macros.h"
#include "base/mutex.h"
-#include "debug/dwarf/dwarf_constants.h"
#include "debug/debug_info.h"
-#include "linker/elf_builder.h"
+#include "dwarf/dwarf_constants.h"
+#include "elf/elf_builder.h"
namespace art {
class OatHeader;
@@ -36,7 +37,7 @@ struct MethodDebugInfo;
template <typename ElfTypes>
void WriteDebugInfo(
- linker::ElfBuilder<ElfTypes>* builder,
+ ElfBuilder<ElfTypes>* builder,
const DebugInfo& debug_info);
std::vector<uint8_t> MakeMiniDebugInfo(
diff --git a/compiler/debug/elf_symtab_writer.h b/compiler/debug/elf_symtab_writer.h
index 7a8e29191a..2ed3a4b1a4 100644
--- a/compiler/debug/elf_symtab_writer.h
+++ b/compiler/debug/elf_symtab_writer.h
@@ -25,7 +25,7 @@
#include "debug/method_debug_info.h"
#include "dex/dex_file-inl.h"
#include "dex/code_item_accessors.h"
-#include "linker/elf_builder.h"
+#include "elf/elf_builder.h"
namespace art {
namespace debug {
@@ -45,7 +45,7 @@ constexpr bool kGenerateArmMappingSymbol = true;
constexpr const char* kDexFileSymbolName = "$dexfile";
template <typename ElfTypes>
-static void WriteDebugSymbols(linker::ElfBuilder<ElfTypes>* builder,
+static void WriteDebugSymbols(ElfBuilder<ElfTypes>* builder,
bool mini_debug_info,
const DebugInfo& debug_info) {
uint64_t mapping_symbol_address = std::numeric_limits<uint64_t>::max();
diff --git a/compiler/debug/xz_utils.cc b/compiler/debug/xz_utils.cc
deleted file mode 100644
index 5b36209d2f..0000000000
--- a/compiler/debug/xz_utils.cc
+++ /dev/null
@@ -1,134 +0,0 @@
-/*
- * Copyright (C) 2018 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 "xz_utils.h"
-
-#include <vector>
-#include <mutex>
-
-#include "base/array_ref.h"
-#include "base/bit_utils.h"
-#include "base/leb128.h"
-#include "dwarf/writer.h"
-
-// liblzma.
-#include "7zCrc.h"
-#include "Xz.h"
-#include "XzCrc64.h"
-#include "XzEnc.h"
-
-namespace art {
-namespace debug {
-
-constexpr size_t kChunkSize = kPageSize;
-
-static void XzInitCrc() {
- static std::once_flag crc_initialized;
- std::call_once(crc_initialized, []() {
- CrcGenerateTable();
- Crc64GenerateTable();
- });
-}
-
-void XzCompress(ArrayRef<const uint8_t> src, std::vector<uint8_t>* dst) {
- // Configure the compression library.
- XzInitCrc();
- CLzma2EncProps lzma2Props;
- Lzma2EncProps_Init(&lzma2Props);
- lzma2Props.lzmaProps.level = 1; // Fast compression.
- lzma2Props.lzmaProps.reduceSize = src.size(); // Size of data that will be compressed.
- lzma2Props.blockSize = kChunkSize;
- Lzma2EncProps_Normalize(&lzma2Props);
- CXzProps props;
- XzProps_Init(&props);
- props.lzma2Props = lzma2Props;
- // Implement the required interface for communication (written in C so no virtual methods).
- struct XzCallbacks : public ISeqInStream, public ISeqOutStream, public ICompressProgress {
- static SRes ReadImpl(const ISeqInStream* p, void* buf, size_t* size) {
- auto* ctx = static_cast<XzCallbacks*>(const_cast<ISeqInStream*>(p));
- *size = std::min(*size, ctx->src_.size() - ctx->src_pos_);
- memcpy(buf, ctx->src_.data() + ctx->src_pos_, *size);
- ctx->src_pos_ += *size;
- return SZ_OK;
- }
- static size_t WriteImpl(const ISeqOutStream* p, const void* buf, size_t size) {
- auto* ctx = static_cast<const XzCallbacks*>(p);
- const uint8_t* buffer = reinterpret_cast<const uint8_t*>(buf);
- ctx->dst_->insert(ctx->dst_->end(), buffer, buffer + size);
- return size;
- }
- static SRes ProgressImpl(const ICompressProgress* , UInt64, UInt64) {
- return SZ_OK;
- }
- size_t src_pos_;
- ArrayRef<const uint8_t> src_;
- std::vector<uint8_t>* dst_;
- };
- XzCallbacks callbacks;
- callbacks.Read = XzCallbacks::ReadImpl;
- callbacks.Write = XzCallbacks::WriteImpl;
- callbacks.Progress = XzCallbacks::ProgressImpl;
- callbacks.src_pos_ = 0;
- callbacks.src_ = src;
- callbacks.dst_ = dst;
- // Compress.
- SRes res = Xz_Encode(&callbacks, &callbacks, &props, &callbacks);
- CHECK_EQ(res, SZ_OK);
-
- // Decompress the data back and check that we get the original.
- if (kIsDebugBuild) {
- std::vector<uint8_t> decompressed;
- XzDecompress(ArrayRef<const uint8_t>(*dst), &decompressed);
- DCHECK_EQ(decompressed.size(), src.size());
- DCHECK_EQ(memcmp(decompressed.data(), src.data(), src.size()), 0);
- }
-}
-
-void XzDecompress(ArrayRef<const uint8_t> src, std::vector<uint8_t>* dst) {
- XzInitCrc();
- std::unique_ptr<CXzUnpacker> state(new CXzUnpacker());
- ISzAlloc alloc;
- alloc.Alloc = [](ISzAllocPtr, size_t size) { return malloc(size); };
- alloc.Free = [](ISzAllocPtr, void* ptr) { return free(ptr); };
- XzUnpacker_Construct(state.get(), &alloc);
-
- size_t src_offset = 0;
- size_t dst_offset = 0;
- ECoderStatus status;
- do {
- dst->resize(RoundUp(dst_offset + kPageSize / 4, kPageSize));
- size_t src_remaining = src.size() - src_offset;
- size_t dst_remaining = dst->size() - dst_offset;
- int return_val = XzUnpacker_Code(state.get(),
- dst->data() + dst_offset,
- &dst_remaining,
- src.data() + src_offset,
- &src_remaining,
- true,
- CODER_FINISH_ANY,
- &status);
- CHECK_EQ(return_val, SZ_OK);
- src_offset += src_remaining;
- dst_offset += dst_remaining;
- } while (status == CODER_STATUS_NOT_FINISHED);
- CHECK_EQ(src_offset, src.size());
- CHECK(XzUnpacker_IsStreamWasFinished(state.get()));
- XzUnpacker_Free(state.get());
- dst->resize(dst_offset);
-}
-
-} // namespace debug
-} // namespace art
diff --git a/compiler/debug/xz_utils.h b/compiler/debug/xz_utils.h
deleted file mode 100644
index 731b03c7e1..0000000000
--- a/compiler/debug/xz_utils.h
+++ /dev/null
@@ -1,33 +0,0 @@
-/*
- * Copyright (C) 2018 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_DEBUG_XZ_UTILS_H_
-#define ART_COMPILER_DEBUG_XZ_UTILS_H_
-
-#include <vector>
-
-#include "base/array_ref.h"
-
-namespace art {
-namespace debug {
-
-void XzCompress(ArrayRef<const uint8_t> src, std::vector<uint8_t>* dst);
-void XzDecompress(ArrayRef<const uint8_t> src, std::vector<uint8_t>* dst);
-
-} // namespace debug
-} // namespace art
-
-#endif // ART_COMPILER_DEBUG_XZ_UTILS_H_