diff options
author | 2019-02-08 15:51:31 +0000 | |
---|---|---|
committer | 2019-02-12 13:51:16 +0000 | |
commit | 91b290038cbd00a48028922a5e76c0c39d6ebcb6 (patch) | |
tree | 0b05e3a20da9ae131b9299554b4c7efa7e156f7d | |
parent | 794350fd0e21aa9e259b6c45394494871e7fdb13 (diff) |
Remove support for generating .eh_frame ELF section.
The eh_frame support was originally added because the
old libunwind library didn't support debug_frame.
The new libunwind supports debug_frame well, and since
we have switched to it, we can remove the legacy code.
The main advantage of debug_frame is that it can be
compressed as part of mini-debug-info.
I am somewhat preserving the .eh_frame_hdr binary
search table (renamed as .debug_frame_hdr.android).
Bug: 123621350
Test: Generated framework oat files are identical.
Change-Id: I35b18895482f2176e02df07b086af7a1d40f90d5
-rw-r--r-- | compiler/cfi_test.h | 5 | ||||
-rw-r--r-- | compiler/debug/dwarf/dwarf_constants.h | 8 | ||||
-rw-r--r-- | compiler/debug/dwarf/dwarf_test.cc | 42 | ||||
-rw-r--r-- | compiler/debug/dwarf/headers.h | 40 | ||||
-rw-r--r-- | compiler/debug/elf_debug_frame_writer.h | 80 | ||||
-rw-r--r-- | compiler/debug/elf_debug_writer.cc | 41 | ||||
-rw-r--r-- | compiler/debug/elf_debug_writer.h | 1 | ||||
-rw-r--r-- | compiler/linker/elf_builder.h | 16 | ||||
-rw-r--r-- | dex2oat/linker/elf_writer_quick.cc | 11 | ||||
-rw-r--r-- | oatdump/oatdump.cc | 5 |
10 files changed, 90 insertions, 159 deletions
diff --git a/compiler/cfi_test.h b/compiler/cfi_test.h index 658bdb35ae..bc816da3dc 100644 --- a/compiler/cfi_test.h +++ b/compiler/cfi_test.h @@ -32,8 +32,6 @@ namespace art { -constexpr dwarf::CFIFormat kCFIFormat = dwarf::DW_DEBUG_FRAME_FORMAT; - class CFITest : public dwarf::DwarfTest { public: void GenerateExpected(FILE* f, InstructionSet isa, const char* isa_str, @@ -50,7 +48,7 @@ class CFITest : public dwarf::DwarfTest { // Pretty-print CFI opcodes. constexpr bool is64bit = false; dwarf::DebugFrameOpCodeWriter<> initial_opcodes; - dwarf::WriteCIE(is64bit, dwarf::Reg(8), initial_opcodes, kCFIFormat, &debug_frame_data_); + dwarf::WriteCIE(is64bit, dwarf::Reg(8), initial_opcodes, &debug_frame_data_); std::vector<uintptr_t> debug_frame_patches; dwarf::WriteFDE(is64bit, /* section_address= */ 0, @@ -58,7 +56,6 @@ class CFITest : public dwarf::DwarfTest { /* code_address= */ 0, actual_asm.size(), actual_cfi, - kCFIFormat, /* buffer_address= */ 0, &debug_frame_data_, &debug_frame_patches); diff --git a/compiler/debug/dwarf/dwarf_constants.h b/compiler/debug/dwarf/dwarf_constants.h index 96f805e85f..7beb1fa7da 100644 --- a/compiler/debug/dwarf/dwarf_constants.h +++ b/compiler/debug/dwarf/dwarf_constants.h @@ -680,14 +680,6 @@ enum ExceptionHeaderValueApplication : uint8_t { DW_EH_PE_aligned = 0x50, }; -enum CFIFormat : uint8_t { - // This is the original format as defined by the specification. - // It is used for the .debug_frame section. - DW_DEBUG_FRAME_FORMAT, - // Slightly modified format used for the .eh_frame section. - DW_EH_FRAME_FORMAT -}; - } // namespace dwarf } // namespace art diff --git a/compiler/debug/dwarf/dwarf_test.cc b/compiler/debug/dwarf/dwarf_test.cc index 6512314ae8..52717c352d 100644 --- a/compiler/debug/dwarf/dwarf_test.cc +++ b/compiler/debug/dwarf/dwarf_test.cc @@ -29,8 +29,6 @@ namespace dwarf { // Run the tests only on host since we need objdump. #ifndef ART_TARGET_ANDROID -constexpr CFIFormat kCFIFormat = DW_DEBUG_FRAME_FORMAT; - TEST_F(DwarfTest, DebugFrame) { const bool is64bit = false; @@ -122,12 +120,18 @@ TEST_F(DwarfTest, DebugFrame) { DW_CHECK_NEXT("DW_CFA_restore: r5 (ebp)"); DebugFrameOpCodeWriter<> initial_opcodes; - WriteCIE(is64bit, Reg(is64bit ? 16 : 8), - initial_opcodes, kCFIFormat, &debug_frame_data_); + 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, 0x01000000, 0x01000000, ArrayRef<const uint8_t>(*opcodes.data()), - kCFIFormat, 0, &debug_frame_data_, &debug_frame_patches); + WriteFDE(is64bit, + 0, + 0, + 0x01000000, + 0x01000000, + ArrayRef<const uint8_t>(*opcodes.data()), + 0, + &debug_frame_data_, + &debug_frame_patches); EXPECT_EQ(expected_patches, debug_frame_patches); CheckObjdumpOutput(is64bit, "-W"); @@ -136,14 +140,19 @@ TEST_F(DwarfTest, DebugFrame) { TEST_F(DwarfTest, DebugFrame64) { constexpr bool is64bit = true; DebugFrameOpCodeWriter<> initial_opcodes; - WriteCIE(is64bit, Reg(16), - initial_opcodes, kCFIFormat, &debug_frame_data_); + 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, 0x0100000000000000, 0x0200000000000000, + WriteFDE(is64bit, + 0, + 0, + 0x0100000000000000, + 0x0200000000000000, ArrayRef<const uint8_t>(*opcodes.data()), - kCFIFormat, 0, &debug_frame_data_, &debug_frame_patches); + 0, + &debug_frame_data_, + &debug_frame_patches); DW_CHECK("FDE cie=00000000 pc=100000000000000..300000000000000"); EXPECT_EQ(expected_patches, debug_frame_patches); @@ -176,12 +185,17 @@ 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; - WriteCIE(is64bit, Reg(16), - initial_opcodes, kCFIFormat, &debug_frame_data_); + WriteCIE(is64bit, Reg(16), initial_opcodes, &debug_frame_data_); std::vector<uintptr_t> debug_frame_patches; - WriteFDE(is64bit, 0, 0, 0x0100000000000000, 0x0200000000000000, + WriteFDE(is64bit, + 0, + 0, + 0x0100000000000000, + 0x0200000000000000, ArrayRef<const uint8_t>(*opcodes.data()), - kCFIFormat, 0, &debug_frame_data_, &debug_frame_patches); + 0, + &debug_frame_data_, + &debug_frame_patches); CheckObjdumpOutput(is64bit, "-W"); } diff --git a/compiler/debug/dwarf/headers.h b/compiler/debug/dwarf/headers.h index 4a27178146..119bfe98a5 100644 --- a/compiler/debug/dwarf/headers.h +++ b/compiler/debug/dwarf/headers.h @@ -41,14 +41,13 @@ template<typename Vector> 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(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. + writer.PushUint32(0xFFFFFFFF); // CIE id. writer.PushUint8(1); // Version. writer.PushString("zR"); writer.PushUleb128(DebugFrameOpCodeWriter<Vector>::kCodeAlignmentFactor); @@ -56,19 +55,9 @@ void WriteCIE(bool is64bit, writer.PushUleb128(return_address_register.num()); // ubyte in DWARF2. writer.PushUleb128(1); // z: Augmentation data size. if (is64bit) { - if (format == DW_EH_FRAME_FORMAT) { - writer.PushUint8(DW_EH_PE_pcrel | DW_EH_PE_sdata8); // R: Pointer encoding. - } else { - DCHECK(format == DW_DEBUG_FRAME_FORMAT); - writer.PushUint8(DW_EH_PE_absptr | DW_EH_PE_udata8); // R: Pointer encoding. - } + writer.PushUint8(DW_EH_PE_absptr | DW_EH_PE_udata8); // R: Pointer encoding. } else { - if (format == DW_EH_FRAME_FORMAT) { - writer.PushUint8(DW_EH_PE_pcrel | DW_EH_PE_sdata4); // R: Pointer encoding. - } else { - DCHECK(format == DW_DEBUG_FRAME_FORMAT); - writer.PushUint8(DW_EH_PE_absptr | DW_EH_PE_udata4); // R: Pointer encoding. - } + writer.PushUint8(DW_EH_PE_absptr | DW_EH_PE_udata4); // R: Pointer encoding. } writer.PushData(opcodes.data()); writer.Pad(is64bit ? 8 : 4); @@ -83,7 +72,6 @@ void WriteFDE(bool is64bit, 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) { @@ -93,23 +81,11 @@ void WriteFDE(bool is64bit, 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 = (buffer_address + buffer->size()) - cie_address; - writer.PushUint32(cie_pointer); - } else { - DCHECK(format == DW_DEBUG_FRAME_FORMAT); - uint32_t cie_pointer = cie_address - section_address; - writer.PushUint32(cie_pointer); - } - 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. - if (patch_locations != nullptr) { - patch_locations->push_back(buffer_address + buffer->size() - section_address); - } + 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); diff --git a/compiler/debug/elf_debug_frame_writer.h b/compiler/debug/elf_debug_frame_writer.h index 27b70c8caa..a6bbea4b60 100644 --- a/compiler/debug/elf_debug_frame_writer.h +++ b/compiler/debug/elf_debug_frame_writer.h @@ -29,9 +29,9 @@ namespace art { namespace debug { -static void WriteCIE(InstructionSet isa, - dwarf::CFIFormat format, - std::vector<uint8_t>* buffer) { +static constexpr bool kWriteDebugFrameHdr = false; + +static void WriteCIE(InstructionSet isa, /*inout*/ std::vector<uint8_t>* buffer) { using Reg = dwarf::Reg; // Scratch registers should be marked as undefined. This tells the // debugger that its value in the previous frame is not recoverable. @@ -58,7 +58,7 @@ static void WriteCIE(InstructionSet isa, } } auto return_reg = Reg::ArmCore(14); // R14(LR). - WriteCIE(is64bit, return_reg, opcodes, format, buffer); + WriteCIE(is64bit, return_reg, opcodes, buffer); return; } case InstructionSet::kArm64: { @@ -81,7 +81,7 @@ static void WriteCIE(InstructionSet isa, } } auto return_reg = Reg::Arm64Core(30); // R30(LR). - WriteCIE(is64bit, return_reg, opcodes, format, buffer); + WriteCIE(is64bit, return_reg, opcodes, buffer); return; } case InstructionSet::kMips: @@ -105,7 +105,7 @@ static void WriteCIE(InstructionSet isa, } } auto return_reg = Reg::MipsCore(31); // R31(RA). - WriteCIE(is64bit, return_reg, opcodes, format, buffer); + WriteCIE(is64bit, return_reg, opcodes, buffer); return; } case InstructionSet::kX86: { @@ -131,7 +131,7 @@ static void WriteCIE(InstructionSet isa, } } auto return_reg = Reg::X86Core(8); // R8(EIP). - WriteCIE(is64bit, return_reg, opcodes, format, buffer); + WriteCIE(is64bit, return_reg, opcodes, buffer); return; } case InstructionSet::kX86_64: { @@ -157,7 +157,7 @@ static void WriteCIE(InstructionSet isa, } } auto return_reg = Reg::X86_64Core(16); // R16(RIP). - WriteCIE(is64bit, return_reg, opcodes, format, buffer); + WriteCIE(is64bit, return_reg, opcodes, buffer); return; } case InstructionSet::kNone: @@ -170,9 +170,7 @@ static void WriteCIE(InstructionSet isa, template<typename ElfTypes> void WriteCFISection(linker::ElfBuilder<ElfTypes>* builder, const ArrayRef<const MethodDebugInfo>& method_infos, - dwarf::CFIFormat format, bool write_oat_patches) { - CHECK(format == dwarf::DW_DEBUG_FRAME_FORMAT || format == dwarf::DW_EH_FRAME_FORMAT); typedef typename ElfTypes::Addr Elf_Addr; // The methods can be written in any order. @@ -200,23 +198,20 @@ void WriteCFISection(linker::ElfBuilder<ElfTypes>* builder, std::vector<uint32_t> binary_search_table; std::vector<uintptr_t> patch_locations; - if (format == dwarf::DW_EH_FRAME_FORMAT) { + if (kWriteDebugFrameHdr) { binary_search_table.reserve(2 * sorted_method_infos.size()); } else { patch_locations.reserve(sorted_method_infos.size()); } - // Write .eh_frame/.debug_frame section. - const bool is_debug_frame = format == dwarf::DW_DEBUG_FRAME_FORMAT; - auto* cfi_section = (is_debug_frame ? builder->GetDebugFrame() : builder->GetEhFrame()); + // Write .debug_frame section. + auto* cfi_section = builder->GetDebugFrame(); { cfi_section->Start(); const bool is64bit = Is64BitInstructionSet(builder->GetIsa()); - const Elf_Addr cfi_address = (is_debug_frame ? 0 : cfi_section->GetAddress()); - const Elf_Addr cie_address = cfi_address; - Elf_Addr buffer_address = cfi_address; + Elf_Addr buffer_address = 0; std::vector<uint8_t> buffer; // Small temporary buffer. - WriteCIE(builder->GetIsa(), format, &buffer); + WriteCIE(builder->GetIsa(), &buffer); cfi_section->WriteFully(buffer.data(), buffer.size()); buffer_address += buffer.size(); buffer.clear(); @@ -225,14 +220,19 @@ void WriteCFISection(linker::ElfBuilder<ElfTypes>* builder, DCHECK(!mi->cfi.empty()); const Elf_Addr code_address = mi->code_address + (mi->is_code_address_text_relative ? builder->GetText()->GetAddress() : 0); - if (format == dwarf::DW_EH_FRAME_FORMAT) { + 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)); } - WriteFDE(is64bit, cfi_address, cie_address, - code_address, mi->code_size, - mi->cfi, format, buffer_address, &buffer, - &patch_locations); + dwarf::WriteFDE(is64bit, + 0, + 0, + code_address, + mi->code_size, + mi->cfi, + buffer_address, + &buffer, + &patch_locations); cfi_section->WriteFully(buffer.data(), buffer.size()); buffer_address += buffer.size(); buffer.clear(); @@ -240,32 +240,18 @@ void WriteCFISection(linker::ElfBuilder<ElfTypes>* builder, cfi_section->End(); } - if (format == dwarf::DW_EH_FRAME_FORMAT) { - auto* header_section = builder->GetEhFrameHdr(); - header_section->Start(); - uint32_t header_address = dchecked_integral_cast<int32_t>(header_section->GetAddress()); - // Write .eh_frame_hdr section. - std::vector<uint8_t> buffer; - dwarf::Writer<> header(&buffer); + if (kWriteDebugFrameHdr) { + std::vector<uint8_t> header_buffer; + dwarf::Writer<> header(&header_buffer); header.PushUint8(1); // Version. - // Encoding of .eh_frame pointer - libunwind does not honor datarel here, - // so we have to use pcrel which means relative to the pointer's location. - header.PushUint8(dwarf::DW_EH_PE_pcrel | dwarf::DW_EH_PE_sdata4); - // Encoding of binary search table size. - header.PushUint8(dwarf::DW_EH_PE_udata4); - // Encoding of binary search table addresses - libunwind supports only this - // specific combination, which means relative to the start of .eh_frame_hdr. - header.PushUint8(dwarf::DW_EH_PE_datarel | dwarf::DW_EH_PE_sdata4); - // .eh_frame pointer - header.PushInt32(cfi_section->GetAddress() - (header_address + 4u)); - // Binary search table size (number of entries). + header.PushUint8(dwarf::DW_EH_PE_omit); // Encoding of .eh_frame pointer - none. + header.PushUint8(dwarf::DW_EH_PE_udata4); // Encoding of binary search table size. + header.PushUint8(dwarf::DW_EH_PE_udata4); // Encoding of binary search table data. header.PushUint32(dchecked_integral_cast<uint32_t>(binary_search_table.size()/2)); - header_section->WriteFully(buffer.data(), buffer.size()); - // Binary search table. - for (size_t i = 0; i < binary_search_table.size(); i++) { - // Make addresses section-relative since we know the header address now. - binary_search_table[i] -= header_address; - } + + auto* header_section = builder->GetDebugFrameHdr(); + header_section->Start(); + header_section->WriteFully(header_buffer.data(), header_buffer.size()); header_section->WriteFully(binary_search_table.data(), binary_search_table.size()); header_section->End(); } else { diff --git a/compiler/debug/elf_debug_writer.cc b/compiler/debug/elf_debug_writer.cc index e5c09aa379..68c4e1530d 100644 --- a/compiler/debug/elf_debug_writer.cc +++ b/compiler/debug/elf_debug_writer.cc @@ -45,13 +45,12 @@ using ElfRuntimeTypes = std::conditional<sizeof(void*) == 4, ElfTypes32, ElfType template <typename ElfTypes> void WriteDebugInfo(linker::ElfBuilder<ElfTypes>* builder, const DebugInfo& debug_info, - dwarf::CFIFormat cfi_format, bool write_oat_patches) { // Write .strtab and .symtab. WriteDebugSymbols(builder, /* mini-debug-info= */ false, debug_info); // Write .debug_frame. - WriteCFISection(builder, debug_info.compiled_methods, cfi_format, write_oat_patches); + WriteCFISection(builder, debug_info.compiled_methods, write_oat_patches); // Group the methods into compilation units based on class. std::unordered_map<const dex::ClassDef*, ElfCompilationUnit> class_to_compilation_unit; @@ -137,10 +136,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, - dwarf::DW_DEBUG_FRAME_FORMAT, - /* write_oat_patches= */ false); + WriteCFISection(builder.get(), debug_info.compiled_methods, /* write_oat_patches= */ false); } builder->End(); CHECK(builder->Good()); @@ -199,15 +195,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, - dwarf::DW_DEBUG_FRAME_FORMAT, - /* write_oat_patches= */ false); + WriteCFISection(builder.get(), debug_info.compiled_methods, /* write_oat_patches= */ false); } else { - WriteDebugInfo(builder.get(), - debug_info, - dwarf::DW_DEBUG_FRAME_FORMAT, - /* write_oat_patches= */ false); + WriteDebugInfo(builder.get(), debug_info, /* write_oat_patches= */ false); } builder->End(); CHECK(builder->Good()); @@ -272,7 +262,7 @@ std::vector<uint8_t> PackElfFileForJIT( auto* debug_frame = builder->GetDebugFrame(); std::deque<Elf_Sym> symbols; std::vector<uint8_t> debug_frame_buffer; - WriteCIE(isa, dwarf::DW_DEBUG_FRAME_FORMAT, &debug_frame_buffer); + WriteCIE(isa, &debug_frame_buffer); // Write symbols names. All other data is buffered. strtab->Start(); @@ -293,16 +283,15 @@ std::vector<uint8_t> PackElfFileForJIT( if (is_removed_symbol(addr)) { return; } - WriteFDE(is64bit, - /*section_address=*/ 0, - /*cie_address=*/ 0, - addr, - size, - opcodes, - dwarf::DW_DEBUG_FRAME_FORMAT, - debug_frame_buffer.size(), - &debug_frame_buffer, - /*patch_locations=*/ nullptr); + dwarf::WriteFDE(is64bit, + /*section_address=*/ 0, + /*cie_address=*/ 0, + addr, + size, + opcodes, + debug_frame_buffer.size(), + &debug_frame_buffer, + /*patch_locations=*/ nullptr); }); } strtab->End(); @@ -382,12 +371,10 @@ std::vector<uint8_t> WriteDebugElfFileForClasses( template void WriteDebugInfo<ElfTypes32>( linker::ElfBuilder<ElfTypes32>* builder, const DebugInfo& debug_info, - dwarf::CFIFormat cfi_format, bool write_oat_patches); template void WriteDebugInfo<ElfTypes64>( linker::ElfBuilder<ElfTypes64>* builder, const DebugInfo& debug_info, - dwarf::CFIFormat cfi_format, bool write_oat_patches); } // namespace debug diff --git a/compiler/debug/elf_debug_writer.h b/compiler/debug/elf_debug_writer.h index 85ab356b0c..d5aa9cd257 100644 --- a/compiler/debug/elf_debug_writer.h +++ b/compiler/debug/elf_debug_writer.h @@ -38,7 +38,6 @@ template <typename ElfTypes> void WriteDebugInfo( linker::ElfBuilder<ElfTypes>* builder, const DebugInfo& debug_info, - dwarf::CFIFormat cfi_format, bool write_oat_patches); std::vector<uint8_t> MakeMiniDebugInfo( diff --git a/compiler/linker/elf_builder.h b/compiler/linker/elf_builder.h index 6acce10fdf..54e07fcd46 100644 --- a/compiler/linker/elf_builder.h +++ b/compiler/linker/elf_builder.h @@ -50,8 +50,6 @@ namespace linker { // .dynamic - Tags which let the linker locate .dynsym. // .strtab - Names for .symtab. // .symtab - Debug symbols. -// .eh_frame - Unwind information (CFI). -// .eh_frame_hdr - Index of .eh_frame. // .debug_frame - Unwind information (CFI). // .debug_frame.oat_patches - Addresses for relocation. // .debug_info - Debug information. @@ -535,11 +533,11 @@ class ElfBuilder final { dynsym_(this, ".dynsym", SHT_DYNSYM, SHF_ALLOC, &dynstr_), hash_(this, ".hash", SHT_HASH, SHF_ALLOC, &dynsym_, 0, sizeof(Elf_Word), sizeof(Elf_Word)), dynamic_(this, ".dynamic", SHT_DYNAMIC, SHF_ALLOC, &dynstr_, 0, kPageSize, sizeof(Elf_Dyn)), - eh_frame_(this, ".eh_frame", SHT_PROGBITS, SHF_ALLOC, nullptr, 0, kPageSize, 0), - eh_frame_hdr_(this, ".eh_frame_hdr", SHT_PROGBITS, SHF_ALLOC, nullptr, 0, 4, 0), strtab_(this, ".strtab", 0, 1), symtab_(this, ".symtab", SHT_SYMTAB, 0, &strtab_), debug_frame_(this, ".debug_frame", SHT_PROGBITS, 0, nullptr, 0, sizeof(Elf_Addr), 0), + debug_frame_hdr_( + this, ".debug_frame_hdr.android", SHT_PROGBITS, 0, nullptr, 0, sizeof(Elf_Addr), 0), debug_info_(this, ".debug_info", SHT_PROGBITS, 0, nullptr, 0, 1, 0), debug_line_(this, ".debug_line", SHT_PROGBITS, 0, nullptr, 0, 1, 0), shstrtab_(this, ".shstrtab", 0, 1), @@ -558,7 +556,6 @@ class ElfBuilder final { dex_.phdr_flags_ = PF_R; dynamic_.phdr_flags_ = PF_R | PF_W; dynamic_.phdr_type_ = PT_DYNAMIC; - eh_frame_hdr_.phdr_type_ = PT_GNU_EH_FRAME; abiflags_.phdr_type_ = PT_MIPS_ABIFLAGS; build_id_.phdr_type_ = PT_NOTE; } @@ -573,9 +570,8 @@ class ElfBuilder final { Section* GetDex() { return &dex_; } StringSection* GetStrTab() { return &strtab_; } SymbolSection* GetSymTab() { return &symtab_; } - Section* GetEhFrame() { return &eh_frame_; } - Section* GetEhFrameHdr() { return &eh_frame_hdr_; } Section* GetDebugFrame() { return &debug_frame_; } + Section* GetDebugFrameHdr() { return &debug_frame_hdr_; } Section* GetDebugInfo() { return &debug_info_; } Section* GetDebugLine() { return &debug_line_; } @@ -633,9 +629,6 @@ class ElfBuilder final { // Note: loaded_size_ == 0 for tests that don't write .rodata, .text, .bss, // .dynstr, dynsym, .hash and .dynamic. These tests should not read loaded_size_. - // TODO: Either refactor the .eh_frame creation so that it counts towards loaded_size_, - // or remove all support for .eh_frame. (The currently unused .eh_frame counts towards - // the virtual_address_ but we don't consider it for loaded_size_.) CHECK(loaded_size_ == 0 || loaded_size_ == RoundUp(virtual_address_, kPageSize)) << loaded_size_ << " " << virtual_address_; @@ -1079,11 +1072,10 @@ class ElfBuilder final { SymbolSection dynsym_; CachedSection hash_; CachedSection dynamic_; - Section eh_frame_; - Section eh_frame_hdr_; StringSection strtab_; SymbolSection symtab_; Section debug_frame_; + Section debug_frame_hdr_; Section debug_info_; Section debug_line_; StringSection shstrtab_; diff --git a/dex2oat/linker/elf_writer_quick.cc b/dex2oat/linker/elf_writer_quick.cc index b3e8290b01..521bc78c76 100644 --- a/dex2oat/linker/elf_writer_quick.cc +++ b/dex2oat/linker/elf_writer_quick.cc @@ -42,15 +42,6 @@ namespace art { namespace linker { -// .eh_frame and .debug_frame are almost identical. -// Except for some minor formatting differences, the main difference -// is that .eh_frame is allocated within the running program because -// it is used by C++ exception handling (which we do not use so we -// can choose either). C++ compilers generally tend to use .eh_frame -// because if they need it sometimes, they might as well always use it. -// Let's use .debug_frame because it is easier to strip or compress. -constexpr dwarf::CFIFormat kCFIFormat = dwarf::DW_DEBUG_FRAME_FORMAT; - class DebugInfoTask : public Task { public: DebugInfoTask(InstructionSet isa, @@ -290,7 +281,7 @@ void ElfWriterQuick<ElfTypes>::WriteDebugInfo(const debug::DebugInfo& debug_info // The Strip method expects debug info to be last (mini-debug-info is not stripped). if (!debug_info.Empty() && compiler_options_.GetGenerateDebugInfo()) { // Generate all the debug information we can. - debug::WriteDebugInfo(builder_.get(), debug_info, kCFIFormat, true /* write_oat_patches */); + debug::WriteDebugInfo(builder_.get(), debug_info, true /* write_oat_patches */); } } diff --git a/oatdump/oatdump.cc b/oatdump/oatdump.cc index 655c2c9213..b1be646c54 100644 --- a/oatdump/oatdump.cc +++ b/oatdump/oatdump.cc @@ -221,10 +221,7 @@ class OatSymbolizer final { debug::DebugInfo debug_info{}; debug_info.compiled_methods = ArrayRef<const debug::MethodDebugInfo>(method_debug_infos_); - debug::WriteDebugInfo(builder_.get(), - debug_info, - dwarf::DW_DEBUG_FRAME_FORMAT, - /* write_oat_patches= */ true); + debug::WriteDebugInfo(builder_.get(), debug_info, /* write_oat_patches= */ true); builder_->End(); |