diff options
Diffstat (limited to 'compiler/dwarf')
| -rw-r--r-- | compiler/dwarf/dwarf_test.cc | 28 | ||||
| -rw-r--r-- | compiler/dwarf/dwarf_test.h | 33 | ||||
| -rw-r--r-- | compiler/dwarf/headers.h | 65 |
3 files changed, 64 insertions, 62 deletions
diff --git a/compiler/dwarf/dwarf_test.cc b/compiler/dwarf/dwarf_test.cc index 3ba380e9db..a412a99d98 100644 --- a/compiler/dwarf/dwarf_test.cc +++ b/compiler/dwarf/dwarf_test.cc @@ -122,12 +122,12 @@ TEST_F(DwarfTest, DebugFrame) { DW_CHECK_NEXT("DW_CFA_restore: r5 (ebp)"); DebugFrameOpCodeWriter<> initial_opcodes; - WriteDebugFrameCIE(is64bit, DW_EH_PE_absptr, Reg(is64bit ? 16 : 8), - initial_opcodes, kCFIFormat, &debug_frame_data_); + WriteCIE(is64bit, Reg(is64bit ? 16 : 8), + initial_opcodes, kCFIFormat, &debug_frame_data_); std::vector<uintptr_t> debug_frame_patches; std::vector<uintptr_t> expected_patches { 28 }; // NOLINT - WriteDebugFrameFDE(is64bit, 0, 0x01000000, 0x01000000, ArrayRef<const uint8_t>(*opcodes.data()), - kCFIFormat, &debug_frame_data_, &debug_frame_patches); + WriteFDE(is64bit, 0, 0, 0x01000000, 0x01000000, ArrayRef<const uint8_t>(*opcodes.data()), + kCFIFormat, 0, &debug_frame_data_, &debug_frame_patches); EXPECT_EQ(expected_patches, debug_frame_patches); CheckObjdumpOutput(is64bit, "-W"); @@ -136,14 +136,14 @@ TEST_F(DwarfTest, DebugFrame) { TEST_F(DwarfTest, DebugFrame64) { constexpr bool is64bit = true; DebugFrameOpCodeWriter<> initial_opcodes; - WriteDebugFrameCIE(is64bit, DW_EH_PE_absptr, Reg(16), - initial_opcodes, kCFIFormat, &debug_frame_data_); + WriteCIE(is64bit, Reg(16), + initial_opcodes, kCFIFormat, &debug_frame_data_); DebugFrameOpCodeWriter<> opcodes; std::vector<uintptr_t> debug_frame_patches; std::vector<uintptr_t> expected_patches { 32 }; // NOLINT - WriteDebugFrameFDE(is64bit, 0, 0x0100000000000000, 0x0200000000000000, - ArrayRef<const uint8_t>(*opcodes.data()), - kCFIFormat, &debug_frame_data_, &debug_frame_patches); + WriteFDE(is64bit, 0, 0, 0x0100000000000000, 0x0200000000000000, + ArrayRef<const uint8_t>(*opcodes.data()), + kCFIFormat, 0, &debug_frame_data_, &debug_frame_patches); DW_CHECK("FDE cie=00000000 pc=100000000000000..300000000000000"); EXPECT_EQ(expected_patches, debug_frame_patches); @@ -176,12 +176,12 @@ TEST_F(DwarfTest, x86_64_RegisterMapping) { DW_CHECK_NEXT("DW_CFA_offset: r14 (r14)"); DW_CHECK_NEXT("DW_CFA_offset: r15 (r15)"); DebugFrameOpCodeWriter<> initial_opcodes; - WriteDebugFrameCIE(is64bit, DW_EH_PE_absptr, Reg(16), - initial_opcodes, kCFIFormat, &debug_frame_data_); + WriteCIE(is64bit, Reg(16), + initial_opcodes, kCFIFormat, &debug_frame_data_); std::vector<uintptr_t> debug_frame_patches; - WriteDebugFrameFDE(is64bit, 0, 0x0100000000000000, 0x0200000000000000, - ArrayRef<const uint8_t>(*opcodes.data()), - kCFIFormat, &debug_frame_data_, &debug_frame_patches); + WriteFDE(is64bit, 0, 0, 0x0100000000000000, 0x0200000000000000, + ArrayRef<const uint8_t>(*opcodes.data()), + kCFIFormat, 0, &debug_frame_data_, &debug_frame_patches); CheckObjdumpOutput(is64bit, "-W"); } diff --git a/compiler/dwarf/dwarf_test.h b/compiler/dwarf/dwarf_test.h index f819c49cee..5464ed9c49 100644 --- a/compiler/dwarf/dwarf_test.h +++ b/compiler/dwarf/dwarf_test.h @@ -59,38 +59,27 @@ class DwarfTest : public CommonRuntimeTest { std::vector<std::string> Objdump(const char* args) { // Write simple elf file with just the DWARF sections. InstructionSet isa = (sizeof(typename ElfTypes::Addr) == 8) ? kX86_64 : kX86; - class NoCode : public CodeOutput { - bool Write(OutputStream*) OVERRIDE { return true; } // NOLINT - } no_code; - ElfBuilder<ElfTypes> builder(isa, 0, &no_code, 0, &no_code, 0); - typedef typename ElfBuilder<ElfTypes>::RawSection RawSection; - RawSection debug_info(".debug_info", SHT_PROGBITS, 0, nullptr, 0, 1, 0); - RawSection debug_abbrev(".debug_abbrev", SHT_PROGBITS, 0, nullptr, 0, 1, 0); - RawSection debug_str(".debug_str", SHT_PROGBITS, 0, nullptr, 0, 1, 0); - RawSection debug_line(".debug_line", SHT_PROGBITS, 0, nullptr, 0, 1, 0); - RawSection debug_frame(".debug_frame", SHT_PROGBITS, 0, nullptr, 0, 8, 0); + ScratchFile file; + FileOutputStream output_stream(file.GetFile()); + ElfBuilder<ElfTypes> builder(isa, &output_stream); + builder.Start(); if (!debug_info_data_.empty()) { - debug_info.SetBuffer(debug_info_data_); - builder.RegisterSection(&debug_info); + builder.WriteSection(".debug_info", &debug_info_data_); } if (!debug_abbrev_data_.empty()) { - debug_abbrev.SetBuffer(debug_abbrev_data_); - builder.RegisterSection(&debug_abbrev); + builder.WriteSection(".debug_abbrev", &debug_abbrev_data_); } if (!debug_str_data_.empty()) { - debug_str.SetBuffer(debug_str_data_); - builder.RegisterSection(&debug_str); + builder.WriteSection(".debug_str", &debug_str_data_); } if (!debug_line_data_.empty()) { - debug_line.SetBuffer(debug_line_data_); - builder.RegisterSection(&debug_line); + builder.WriteSection(".debug_line", &debug_line_data_); } if (!debug_frame_data_.empty()) { - debug_frame.SetBuffer(debug_frame_data_); - builder.RegisterSection(&debug_frame); + builder.WriteSection(".debug_frame", &debug_frame_data_); } - ScratchFile file; - builder.Write(file.GetFile()); + builder.End(); + EXPECT_TRUE(builder.Good()); // Read the elf file back using objdump. std::vector<std::string> lines; diff --git a/compiler/dwarf/headers.h b/compiler/dwarf/headers.h index f3fba4b1fa..883d756885 100644 --- a/compiler/dwarf/headers.h +++ b/compiler/dwarf/headers.h @@ -38,15 +38,14 @@ namespace dwarf { // Write common information entry (CIE) to .debug_frame or .eh_frame section. template<typename Vector> -void WriteDebugFrameCIE(bool is64bit, - ExceptionHeaderValueApplication address_type, - Reg return_address_register, - const DebugFrameOpCodeWriter<Vector>& opcodes, - CFIFormat format, - std::vector<uint8_t>* debug_frame) { +void WriteCIE(bool is64bit, + Reg return_address_register, + const DebugFrameOpCodeWriter<Vector>& opcodes, + CFIFormat format, + std::vector<uint8_t>* buffer) { static_assert(std::is_same<typename Vector::value_type, uint8_t>::value, "Invalid value type"); - Writer<> writer(debug_frame); + Writer<> writer(buffer); size_t cie_header_start_ = writer.data()->size(); writer.PushUint32(0); // Length placeholder. writer.PushUint32((format == DW_EH_FRAME_FORMAT) ? 0 : 0xFFFFFFFF); // CIE id. @@ -57,17 +56,17 @@ void WriteDebugFrameCIE(bool is64bit, writer.PushUleb128(return_address_register.num()); // ubyte in DWARF2. writer.PushUleb128(1); // z: Augmentation data size. if (is64bit) { - if (address_type == DW_EH_PE_pcrel) { + if (format == DW_EH_FRAME_FORMAT) { writer.PushUint8(DW_EH_PE_pcrel | DW_EH_PE_sdata8); // R: Pointer encoding. } else { - DCHECK(address_type == DW_EH_PE_absptr); + DCHECK(format == DW_DEBUG_FRAME_FORMAT); writer.PushUint8(DW_EH_PE_absptr | DW_EH_PE_udata8); // R: Pointer encoding. } } else { - if (address_type == DW_EH_PE_pcrel) { + if (format == DW_EH_FRAME_FORMAT) { writer.PushUint8(DW_EH_PE_pcrel | DW_EH_PE_sdata4); // R: Pointer encoding. } else { - DCHECK(address_type == DW_EH_PE_absptr); + DCHECK(format == DW_DEBUG_FRAME_FORMAT); writer.PushUint8(DW_EH_PE_absptr | DW_EH_PE_udata4); // R: Pointer encoding. } } @@ -78,30 +77,44 @@ void WriteDebugFrameCIE(bool is64bit, // Write frame description entry (FDE) to .debug_frame or .eh_frame section. inline -void WriteDebugFrameFDE(bool is64bit, size_t cie_offset, - uint64_t initial_address, uint64_t address_range, - const ArrayRef<const uint8_t>& opcodes, - CFIFormat format, - std::vector<uint8_t>* debug_frame, - std::vector<uintptr_t>* debug_frame_patches) { - Writer<> writer(debug_frame); +void WriteFDE(bool is64bit, + uint64_t section_address, // Absolute address of the section. + uint64_t cie_address, // Absolute address of last CIE. + uint64_t code_address, + uint64_t code_size, + const ArrayRef<const uint8_t>& opcodes, + CFIFormat format, + uint64_t buffer_address, // Address of buffer in linked application. + std::vector<uint8_t>* buffer, + std::vector<uintptr_t>* patch_locations) { + CHECK_GE(cie_address, section_address); + CHECK_GE(buffer_address, section_address); + + Writer<> writer(buffer); size_t fde_header_start = writer.data()->size(); writer.PushUint32(0); // Length placeholder. if (format == DW_EH_FRAME_FORMAT) { - uint32_t cie_pointer = writer.data()->size() - cie_offset; + uint32_t cie_pointer = (buffer_address + buffer->size()) - cie_address; writer.PushUint32(cie_pointer); } else { - uint32_t cie_pointer = cie_offset; + DCHECK(format == DW_DEBUG_FRAME_FORMAT); + uint32_t cie_pointer = cie_address - section_address; writer.PushUint32(cie_pointer); } - // Relocate initial_address, but not address_range (it is size). - debug_frame_patches->push_back(writer.data()->size()); + if (format == DW_EH_FRAME_FORMAT) { + // .eh_frame encodes the location as relative address. + code_address -= buffer_address + buffer->size(); + } else { + DCHECK(format == DW_DEBUG_FRAME_FORMAT); + // Relocate code_address if it has absolute value. + patch_locations->push_back(buffer_address + buffer->size() - section_address); + } if (is64bit) { - writer.PushUint64(initial_address); - writer.PushUint64(address_range); + writer.PushUint64(code_address); + writer.PushUint64(code_size); } else { - writer.PushUint32(initial_address); - writer.PushUint32(address_range); + writer.PushUint32(code_address); + writer.PushUint32(code_size); } writer.PushUleb128(0); // Augmentation data size. writer.PushData(opcodes); |