diff options
Diffstat (limited to 'compiler')
-rw-r--r-- | compiler/cfi_test.h | 7 | ||||
-rw-r--r-- | compiler/debug/dwarf/dwarf_test.cc | 44 | ||||
-rw-r--r-- | compiler/debug/dwarf/headers.h | 31 | ||||
-rw-r--r-- | compiler/debug/elf_debug_frame_writer.h | 23 | ||||
-rw-r--r-- | compiler/debug/elf_debug_info_writer.h | 13 | ||||
-rw-r--r-- | compiler/debug/elf_debug_line_writer.h | 10 | ||||
-rw-r--r-- | compiler/debug/elf_debug_writer.cc | 30 | ||||
-rw-r--r-- | compiler/debug/elf_debug_writer.h | 3 | ||||
-rw-r--r-- | compiler/linker/elf_builder.h | 27 |
9 files changed, 37 insertions, 151 deletions
diff --git a/compiler/cfi_test.h b/compiler/cfi_test.h index bc816da3dc..2fc81c958a 100644 --- a/compiler/cfi_test.h +++ b/compiler/cfi_test.h @@ -51,14 +51,11 @@ class CFITest : public dwarf::DwarfTest { dwarf::WriteCIE(is64bit, dwarf::Reg(8), initial_opcodes, &debug_frame_data_); std::vector<uintptr_t> debug_frame_patches; dwarf::WriteFDE(is64bit, - /* section_address= */ 0, - /* cie_address= */ 0, + /* cie_pointer= */ 0, /* code_address= */ 0, actual_asm.size(), actual_cfi, - /* buffer_address= */ 0, - &debug_frame_data_, - &debug_frame_patches); + &debug_frame_data_); ReformatCfi(Objdump(false, "-W"), &lines); // Pretty-print assembly. const uint8_t* asm_base = actual_asm.data(); diff --git a/compiler/debug/dwarf/dwarf_test.cc b/compiler/debug/dwarf/dwarf_test.cc index 52717c352d..212fd63efa 100644 --- a/compiler/debug/dwarf/dwarf_test.cc +++ b/compiler/debug/dwarf/dwarf_test.cc @@ -121,19 +121,13 @@ TEST_F(DwarfTest, DebugFrame) { DebugFrameOpCodeWriter<> initial_opcodes; WriteCIE(is64bit, Reg(is64bit ? 16 : 8), initial_opcodes, &debug_frame_data_); - std::vector<uintptr_t> debug_frame_patches; - std::vector<uintptr_t> expected_patches = { 28 }; WriteFDE(is64bit, - 0, - 0, + /* cie_pointer= */ 0, 0x01000000, 0x01000000, ArrayRef<const uint8_t>(*opcodes.data()), - 0, - &debug_frame_data_, - &debug_frame_patches); + &debug_frame_data_); - EXPECT_EQ(expected_patches, debug_frame_patches); CheckObjdumpOutput(is64bit, "-W"); } @@ -142,20 +136,14 @@ TEST_F(DwarfTest, DebugFrame64) { DebugFrameOpCodeWriter<> initial_opcodes; WriteCIE(is64bit, Reg(16), initial_opcodes, &debug_frame_data_); DebugFrameOpCodeWriter<> opcodes; - std::vector<uintptr_t> debug_frame_patches; - std::vector<uintptr_t> expected_patches = { 32 }; WriteFDE(is64bit, - 0, - 0, + /* cie_pointer= */ 0, 0x0100000000000000, 0x0200000000000000, ArrayRef<const uint8_t>(*opcodes.data()), - 0, - &debug_frame_data_, - &debug_frame_patches); + &debug_frame_data_); DW_CHECK("FDE cie=00000000 pc=100000000000000..300000000000000"); - EXPECT_EQ(expected_patches, debug_frame_patches); CheckObjdumpOutput(is64bit, "-W"); } @@ -186,16 +174,12 @@ TEST_F(DwarfTest, x86_64_RegisterMapping) { DW_CHECK_NEXT("DW_CFA_offset: r15 (r15)"); DebugFrameOpCodeWriter<> initial_opcodes; WriteCIE(is64bit, Reg(16), initial_opcodes, &debug_frame_data_); - std::vector<uintptr_t> debug_frame_patches; WriteFDE(is64bit, - 0, - 0, + /* cie_pointer= */ 0, 0x0100000000000000, 0x0200000000000000, ArrayRef<const uint8_t>(*opcodes.data()), - 0, - &debug_frame_data_, - &debug_frame_patches); + &debug_frame_data_); CheckObjdumpOutput(is64bit, "-W"); } @@ -250,12 +234,8 @@ TEST_F(DwarfTest, DebugLine) { DW_CHECK_NEXT("Entry\tDir\tTime\tSize\tName"); DW_CHECK_NEXT("1\t0\t1000\t2000\tfile.c"); - std::vector<uintptr_t> debug_line_patches; - std::vector<uintptr_t> expected_patches = { 87 }; - WriteDebugLineTable(include_directories, files, opcodes, - 0, &debug_line_data_, &debug_line_patches); + WriteDebugLineTable(include_directories, files, opcodes, &debug_line_data_); - EXPECT_EQ(expected_patches, debug_line_patches); CheckObjdumpOutput(is64bit, "-W"); } @@ -290,9 +270,7 @@ TEST_F(DwarfTest, DebugLineSpecialOpcodes) { std::vector<std::string> directories; std::vector<FileEntry> files = { { "file.c", 0, 1000, 2000 } }; - std::vector<uintptr_t> debug_line_patches; - WriteDebugLineTable(directories, files, opcodes, - 0, &debug_line_data_, &debug_line_patches); + WriteDebugLineTable(directories, files, opcodes, &debug_line_data_); CheckObjdumpOutput(is64bit, "-W -WL"); } @@ -346,12 +324,8 @@ TEST_F(DwarfTest, DebugInfo) { DW_CHECK_NEXT("DW_AT_high_pc DW_FORM_addr"); DW_CHECK("3 DW_TAG_compile_unit [no children]"); - std::vector<uintptr_t> debug_info_patches; - std::vector<uintptr_t> expected_patches = { 16, 20, 29, 33, 42, 46 }; - dwarf::WriteDebugInfoCU(/* debug_abbrev_offset= */ 0, info, - 0, &debug_info_data_, &debug_info_patches); + dwarf::WriteDebugInfoCU(/* debug_abbrev_offset= */ 0, info, &debug_info_data_); - EXPECT_EQ(expected_patches, debug_info_patches); CheckObjdumpOutput(is64bit, "-W"); } diff --git a/compiler/debug/dwarf/headers.h b/compiler/debug/dwarf/headers.h index 119bfe98a5..869a2c256e 100644 --- a/compiler/debug/dwarf/headers.h +++ b/compiler/debug/dwarf/headers.h @@ -67,26 +67,16 @@ void WriteCIE(bool is64bit, // Write frame description entry (FDE) to .debug_frame or .eh_frame section. inline void WriteFDE(bool is64bit, - uint64_t section_address, // Absolute address of the section. - uint64_t cie_address, // Absolute address of last CIE. + 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, - 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); - + /*inout*/ std::vector<uint8_t>* buffer) { Writer<> writer(buffer); size_t fde_header_start = writer.data()->size(); writer.PushUint32(0); // Length placeholder. - uint32_t cie_pointer = cie_address - section_address; writer.PushUint32(cie_pointer); // Relocate code_address if it has absolute value. - if (patch_locations != nullptr) { - patch_locations->push_back(buffer_address + buffer->size() - section_address); - } if (is64bit) { writer.PushUint64(code_address); writer.PushUint64(code_size); @@ -128,9 +118,7 @@ bool ReadFDE(const uint8_t** data, Addr* addr, Addr* size, ArrayRef<const uint8_ template<typename Vector> void WriteDebugInfoCU(uint32_t debug_abbrev_offset, const DebugInfoEntryWriter<Vector>& entries, - size_t debug_info_offset, // offset from start of .debug_info. - std::vector<uint8_t>* debug_info, - std::vector<uintptr_t>* debug_info_patches) { + 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); @@ -143,10 +131,6 @@ void WriteDebugInfoCU(uint32_t debug_abbrev_offset, DCHECK_EQ(entries_offset, DebugInfoEntryWriter<Vector>::kCompilationUnitHeaderSize); writer.PushData(entries.data()); writer.UpdateUint32(start, writer.data()->size() - start - 4); - // Copy patch locations and make them relative to .debug_info section. - for (uintptr_t patch_location : entries.GetPatchLocations()) { - debug_info_patches->push_back(debug_info_offset + entries_offset + patch_location); - } } struct FileEntry { @@ -161,9 +145,7 @@ template<typename Vector> void WriteDebugLineTable(const std::vector<std::string>& include_directories, const std::vector<FileEntry>& files, const DebugLineOpCodeWriter<Vector>& opcodes, - size_t debug_line_offset, // offset from start of .debug_line. - std::vector<uint8_t>* debug_line, - std::vector<uintptr_t>* debug_line_patches) { + 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); @@ -194,13 +176,8 @@ void WriteDebugLineTable(const std::vector<std::string>& include_directories, } writer.PushUint8(0); // Terminate file list. writer.UpdateUint32(header_length_pos, writer.data()->size() - header_length_pos - 4); - size_t opcodes_offset = writer.data()->size(); writer.PushData(opcodes.data()); writer.UpdateUint32(header_start, writer.data()->size() - header_start - 4); - // Copy patch locations and make them relative to .debug_line section. - for (uintptr_t patch_location : opcodes.GetPatchLocations()) { - debug_line_patches->push_back(debug_line_offset + opcodes_offset + patch_location); - } } } // namespace dwarf diff --git a/compiler/debug/elf_debug_frame_writer.h b/compiler/debug/elf_debug_frame_writer.h index a6bbea4b60..c5fa64794d 100644 --- a/compiler/debug/elf_debug_frame_writer.h +++ b/compiler/debug/elf_debug_frame_writer.h @@ -169,8 +169,7 @@ static void WriteCIE(InstructionSet isa, /*inout*/ std::vector<uint8_t>* buffer) template<typename ElfTypes> void WriteCFISection(linker::ElfBuilder<ElfTypes>* builder, - const ArrayRef<const MethodDebugInfo>& method_infos, - bool write_oat_patches) { + const ArrayRef<const MethodDebugInfo>& method_infos) { typedef typename ElfTypes::Addr Elf_Addr; // The methods can be written in any order. @@ -197,11 +196,8 @@ void WriteCFISection(linker::ElfBuilder<ElfTypes>* builder, }); std::vector<uint32_t> binary_search_table; - std::vector<uintptr_t> patch_locations; if (kWriteDebugFrameHdr) { binary_search_table.reserve(2 * sorted_method_infos.size()); - } else { - patch_locations.reserve(sorted_method_infos.size()); } // Write .debug_frame section. @@ -209,11 +205,9 @@ void WriteCFISection(linker::ElfBuilder<ElfTypes>* builder, { cfi_section->Start(); const bool is64bit = Is64BitInstructionSet(builder->GetIsa()); - Elf_Addr buffer_address = 0; std::vector<uint8_t> buffer; // Small temporary buffer. WriteCIE(builder->GetIsa(), &buffer); cfi_section->WriteFully(buffer.data(), buffer.size()); - buffer_address += buffer.size(); buffer.clear(); for (const MethodDebugInfo* mi : sorted_method_infos) { DCHECK(!mi->deduped); @@ -222,19 +216,15 @@ void WriteCFISection(linker::ElfBuilder<ElfTypes>* builder, (mi->is_code_address_text_relative ? builder->GetText()->GetAddress() : 0); if (kWriteDebugFrameHdr) { binary_search_table.push_back(dchecked_integral_cast<uint32_t>(code_address)); - binary_search_table.push_back(dchecked_integral_cast<uint32_t>(buffer_address)); + binary_search_table.push_back(cfi_section->GetPosition()); } dwarf::WriteFDE(is64bit, - 0, - 0, + /* cie_pointer= */ 0, code_address, mi->code_size, mi->cfi, - buffer_address, - &buffer, - &patch_locations); + &buffer); cfi_section->WriteFully(buffer.data(), buffer.size()); - buffer_address += buffer.size(); buffer.clear(); } cfi_section->End(); @@ -254,11 +244,6 @@ void WriteCFISection(linker::ElfBuilder<ElfTypes>* builder, header_section->WriteFully(header_buffer.data(), header_buffer.size()); header_section->WriteFully(binary_search_table.data(), binary_search_table.size()); header_section->End(); - } else { - if (write_oat_patches) { - builder->WritePatches(".debug_frame.oat_patches", - ArrayRef<const uintptr_t>(patch_locations)); - } } } diff --git a/compiler/debug/elf_debug_info_writer.h b/compiler/debug/elf_debug_info_writer.h index a63f241f53..05a4a3e32b 100644 --- a/compiler/debug/elf_debug_info_writer.h +++ b/compiler/debug/elf_debug_info_writer.h @@ -68,12 +68,8 @@ class ElfDebugInfoWriter { builder_->GetDebugInfo()->Start(); } - void End(bool write_oat_patches) { + void End() { builder_->GetDebugInfo()->End(); - if (write_oat_patches) { - builder_->WritePatches(".debug_info.oat_patches", - ArrayRef<const uintptr_t>(debug_info_patches_)); - } builder_->WriteSection(".debug_abbrev", &debug_abbrev_buffer_); if (!debug_loc_.empty()) { builder_->WriteSection(".debug_loc", &debug_loc_); @@ -85,7 +81,6 @@ class ElfDebugInfoWriter { private: linker::ElfBuilder<ElfTypes>* builder_; - std::vector<uintptr_t> debug_info_patches_; std::vector<uint8_t> debug_abbrev_buffer_; dwarf::DebugAbbrevWriter<> debug_abbrev_; std::vector<uint8_t> debug_loc_; @@ -281,10 +276,9 @@ class ElfCompilationUnitWriter { CHECK_EQ(info_.Depth(), 0); std::vector<uint8_t> buffer; buffer.reserve(info_.data()->size() + KB); - const size_t offset = owner_->builder_->GetDebugInfo()->GetPosition(); // All compilation units share single table which is at the start of .debug_abbrev. const size_t debug_abbrev_offset = 0; - WriteDebugInfoCU(debug_abbrev_offset, info_, offset, &buffer, &owner_->debug_info_patches_); + WriteDebugInfoCU(debug_abbrev_offset, info_, &buffer); owner_->builder_->GetDebugInfo()->WriteFully(buffer.data(), buffer.size()); } @@ -446,10 +440,9 @@ class ElfCompilationUnitWriter { CHECK_EQ(info_.Depth(), 0); std::vector<uint8_t> buffer; buffer.reserve(info_.data()->size() + KB); - const size_t offset = owner_->builder_->GetDebugInfo()->GetPosition(); // All compilation units share single table which is at the start of .debug_abbrev. const size_t debug_abbrev_offset = 0; - WriteDebugInfoCU(debug_abbrev_offset, info_, offset, &buffer, &owner_->debug_info_patches_); + WriteDebugInfoCU(debug_abbrev_offset, info_, &buffer); owner_->builder_->GetDebugInfo()->WriteFully(buffer.data(), buffer.size()); } diff --git a/compiler/debug/elf_debug_line_writer.h b/compiler/debug/elf_debug_line_writer.h index 0a13a92d07..f95912a2d1 100644 --- a/compiler/debug/elf_debug_line_writer.h +++ b/compiler/debug/elf_debug_line_writer.h @@ -263,23 +263,17 @@ class ElfDebugLineWriter { } std::vector<uint8_t> buffer; buffer.reserve(opcodes.data()->size() + KB); - size_t offset = builder_->GetDebugLine()->GetPosition(); - WriteDebugLineTable(directories, files, opcodes, offset, &buffer, &debug_line_patches_); + WriteDebugLineTable(directories, files, opcodes, &buffer); builder_->GetDebugLine()->WriteFully(buffer.data(), buffer.size()); return buffer.size(); } - void End(bool write_oat_patches) { + void End() { builder_->GetDebugLine()->End(); - if (write_oat_patches) { - builder_->WritePatches(".debug_line.oat_patches", - ArrayRef<const uintptr_t>(debug_line_patches_)); - } } private: linker::ElfBuilder<ElfTypes>* builder_; - std::vector<uintptr_t> debug_line_patches_; }; } // namespace debug diff --git a/compiler/debug/elf_debug_writer.cc b/compiler/debug/elf_debug_writer.cc index 68c4e1530d..78c02b64f0 100644 --- a/compiler/debug/elf_debug_writer.cc +++ b/compiler/debug/elf_debug_writer.cc @@ -44,13 +44,12 @@ using ElfRuntimeTypes = std::conditional<sizeof(void*) == 4, ElfTypes32, ElfType template <typename ElfTypes> void WriteDebugInfo(linker::ElfBuilder<ElfTypes>* builder, - const DebugInfo& debug_info, - bool write_oat_patches) { + const DebugInfo& debug_info) { // Write .strtab and .symtab. WriteDebugSymbols(builder, /* mini-debug-info= */ false, debug_info); // Write .debug_frame. - WriteCFISection(builder, debug_info.compiled_methods, write_oat_patches); + WriteCFISection(builder, debug_info.compiled_methods); // Group the methods into compilation units based on class. std::unordered_map<const dex::ClassDef*, ElfCompilationUnit> class_to_compilation_unit; @@ -95,7 +94,7 @@ void WriteDebugInfo(linker::ElfBuilder<ElfTypes>* builder, for (auto& compilation_unit : compilation_units) { line_writer.WriteCompilationUnit(compilation_unit); } - line_writer.End(write_oat_patches); + line_writer.End(); } // Write .debug_info section. @@ -106,7 +105,7 @@ void WriteDebugInfo(linker::ElfBuilder<ElfTypes>* builder, ElfCompilationUnitWriter<ElfTypes> cu_writer(&info_writer); cu_writer.Write(compilation_unit); } - info_writer.End(write_oat_patches); + info_writer.End(); } } @@ -136,7 +135,7 @@ static std::vector<uint8_t> MakeMiniDebugInfoInternal( WriteDebugSymbols(builder.get(), /* mini-debug-info= */ true, debug_info); } if (!debug_info.compiled_methods.empty()) { - WriteCFISection(builder.get(), debug_info.compiled_methods, /* write_oat_patches= */ false); + WriteCFISection(builder.get(), debug_info.compiled_methods); } builder->End(); CHECK(builder->Good()); @@ -195,9 +194,9 @@ std::vector<uint8_t> MakeElfFileForJIT( // The compression is great help for multiple methods but it is not worth it for a // single method due to the overheads so skip the compression here for performance. WriteDebugSymbols(builder.get(), /* mini-debug-info= */ true, debug_info); - WriteCFISection(builder.get(), debug_info.compiled_methods, /* write_oat_patches= */ false); + WriteCFISection(builder.get(), debug_info.compiled_methods); } else { - WriteDebugInfo(builder.get(), debug_info, /* write_oat_patches= */ false); + WriteDebugInfo(builder.get(), debug_info); } builder->End(); CHECK(builder->Good()); @@ -284,14 +283,11 @@ std::vector<uint8_t> PackElfFileForJIT( return; } dwarf::WriteFDE(is64bit, - /*section_address=*/ 0, - /*cie_address=*/ 0, + /* cie_pointer= */ 0, addr, size, opcodes, - debug_frame_buffer.size(), - &debug_frame_buffer, - /*patch_locations=*/ nullptr); + &debug_frame_buffer); }); } strtab->End(); @@ -360,7 +356,7 @@ std::vector<uint8_t> WriteDebugElfFileForClasses( info_writer.Start(); ElfCompilationUnitWriter<ElfTypes> cu_writer(&info_writer); cu_writer.Write(types); - info_writer.End(/* write_oat_patches= */ false); + info_writer.End(); builder->End(); CHECK(builder->Good()); @@ -370,12 +366,10 @@ std::vector<uint8_t> WriteDebugElfFileForClasses( // Explicit instantiations template void WriteDebugInfo<ElfTypes32>( linker::ElfBuilder<ElfTypes32>* builder, - const DebugInfo& debug_info, - bool write_oat_patches); + const DebugInfo& debug_info); template void WriteDebugInfo<ElfTypes64>( linker::ElfBuilder<ElfTypes64>* builder, - const DebugInfo& debug_info, - bool write_oat_patches); + const DebugInfo& debug_info); } // namespace debug } // namespace art diff --git a/compiler/debug/elf_debug_writer.h b/compiler/debug/elf_debug_writer.h index d5aa9cd257..3cc38a2757 100644 --- a/compiler/debug/elf_debug_writer.h +++ b/compiler/debug/elf_debug_writer.h @@ -37,8 +37,7 @@ struct MethodDebugInfo; template <typename ElfTypes> void WriteDebugInfo( linker::ElfBuilder<ElfTypes>* builder, - const DebugInfo& debug_info, - bool write_oat_patches); + const DebugInfo& debug_info); std::vector<uint8_t> MakeMiniDebugInfo( InstructionSet isa, diff --git a/compiler/linker/elf_builder.h b/compiler/linker/elf_builder.h index 54e07fcd46..33e1866c50 100644 --- a/compiler/linker/elf_builder.h +++ b/compiler/linker/elf_builder.h @@ -51,14 +51,10 @@ namespace linker { // .strtab - Names for .symtab. // .symtab - Debug symbols. // .debug_frame - Unwind information (CFI). -// .debug_frame.oat_patches - Addresses for relocation. // .debug_info - Debug information. -// .debug_info.oat_patches - Addresses for relocation. // .debug_abbrev - Decoding information for .debug_info. // .debug_str - Strings for .debug_info. // .debug_line - Line number tables. -// .debug_line.oat_patches - Addresses for relocation. -// .text.oat_patches - Addresses for relocation. // .shstrtab - Names of ELF sections. // Elf_Shdr[] - Section headers. // @@ -575,29 +571,6 @@ class ElfBuilder final { Section* GetDebugInfo() { return &debug_info_; } Section* GetDebugLine() { return &debug_line_; } - // Encode patch locations as LEB128 list of deltas between consecutive addresses. - // (exposed publicly for tests) - static void EncodeOatPatches(const ArrayRef<const uintptr_t>& locations, - std::vector<uint8_t>* buffer) { - buffer->reserve(buffer->size() + locations.size() * 2); // guess 2 bytes per ULEB128. - uintptr_t address = 0; // relative to start of section. - for (uintptr_t location : locations) { - DCHECK_GE(location, address) << "Patch locations are not in sorted order"; - EncodeUnsignedLeb128(buffer, dchecked_integral_cast<uint32_t>(location - address)); - address = location; - } - } - - void WritePatches(const char* name, const ArrayRef<const uintptr_t>& patch_locations) { - std::vector<uint8_t> buffer; - EncodeOatPatches(patch_locations, &buffer); - std::unique_ptr<Section> s(new Section(this, name, SHT_OAT_PATCH, 0, nullptr, 0, 1, 0)); - s->Start(); - s->WriteFully(buffer.data(), buffer.size()); - s->End(); - other_sections_.push_back(std::move(s)); - } - void WriteSection(const char* name, const std::vector<uint8_t>* buffer) { std::unique_ptr<Section> s(new Section(this, name, SHT_PROGBITS, 0, nullptr, 0, 1, 0)); s->Start(); |