From: Ian Lance Taylor Date: Fri, 7 Dec 2007 06:44:01 +0000 (+0000) Subject: Fix ehframe header handling for shared libraries. X-Git-Tag: sid-snapshot-20080101~217 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=4117d76827b3768e9da6ef52f52a59c5ae92bed3;p=external%2Fbinutils.git Fix ehframe header handling for shared libraries. --- diff --git a/gold/ehframe.cc b/gold/ehframe.cc index 91a977f..328048b 100644 --- a/gold/ehframe.cc +++ b/gold/ehframe.cc @@ -234,8 +234,11 @@ Eh_frame_hdr::do_sized_write(Output_file* of) template typename elfcpp::Elf_types::Elf_Addr -Eh_frame_hdr::get_fde_pc(const unsigned char* eh_frame_contents, - off_t fde_offset, unsigned char fde_encoding) +Eh_frame_hdr::get_fde_pc( + typename elfcpp::Elf_types::Elf_Addr eh_frame_address, + const unsigned char* eh_frame_contents, + off_t fde_offset, + unsigned char fde_encoding) { // The FDE starts with a 4 byte length and a 4 byte offset to the // CIE. The PC follows. @@ -274,6 +277,22 @@ Eh_frame_hdr::get_fde_pc(const unsigned char* eh_frame_contents, break; default: + // All other cases were rejected in Eh_frame::read_cie. + gold_unreachable(); + } + + switch (fde_encoding & 0xf0) + { + case 0: + break; + + case elfcpp::DW_EH_PE_pcrel: + pc += eh_frame_address + fde_offset + 8; + break; + + default: + // If other cases arise, then we have to handle them, or we have + // to reject them by returning false in Eh_frame::read_cie. gold_unreachable(); } @@ -304,7 +323,8 @@ Eh_frame_hdr::get_fde_addresses(Output_file* of, ++p) { typename elfcpp::Elf_types::Elf_Addr fde_pc; - fde_pc = this->get_fde_pc(eh_frame_contents, + fde_pc = this->get_fde_pc(eh_frame_address, + eh_frame_contents, p->first, p->second); fde_addresses->push_back(fde_pc, eh_frame_address + p->first); } @@ -742,6 +762,8 @@ Eh_frame::read_cie(Sized_relobj* object, case elfcpp::DW_EH_PE_udata8: break; default: + // We don't expect to see any other cases here, and + // we're not prepared to handle them. return false; } ++p; diff --git a/gold/ehframe.h b/gold/ehframe.h index 12c8c16..5a733e7 100644 --- a/gold/ehframe.h +++ b/gold/ehframe.h @@ -131,7 +131,8 @@ class Eh_frame_hdr : public Output_section_data // Return the PC to which an FDE refers. template typename elfcpp::Elf_types::Elf_Addr - get_fde_pc(const unsigned char* eh_frame_contents, + get_fde_pc(typename elfcpp::Elf_types::Elf_Addr eh_frame_address, + const unsigned char* eh_frame_contents, off_t fde_offset, unsigned char fde_encoding); // Convert Fde_offsets to Fde_addresses. diff --git a/gold/layout.cc b/gold/layout.cc index 68ebc6b..f5a1f67 100644 --- a/gold/layout.cc +++ b/gold/layout.cc @@ -992,7 +992,9 @@ Layout::set_segment_offsets(const Target* target, Output_segment* load_seg, // Find the PT_LOAD segments, and set their addresses and offsets // and their section's addresses and offsets. uint64_t addr; - if (options_.user_set_text_segment_address()) + if (parameters->output_is_shared()) + addr = 0; + else if (options_.user_set_text_segment_address()) addr = options_.text_segment_address(); else addr = target->default_text_segment_address();