diff options
author | Ian Lance Taylor <iant@google.com> | 2007-12-07 06:44:01 +0000 |
---|---|---|
committer | Ian Lance Taylor <iant@google.com> | 2007-12-07 06:44:01 +0000 |
commit | 4117d76827b3768e9da6ef52f52a59c5ae92bed3 (patch) | |
tree | 0e922a8a56fb517fce40ab926e9d1bb98039818a /gold/ehframe.cc | |
parent | a20d5e98e51d91b66dfccc205d4d27e8850238b2 (diff) | |
download | gdb-4117d76827b3768e9da6ef52f52a59c5ae92bed3.zip gdb-4117d76827b3768e9da6ef52f52a59c5ae92bed3.tar.gz gdb-4117d76827b3768e9da6ef52f52a59c5ae92bed3.tar.bz2 |
Fix ehframe header handling for shared libraries.
Diffstat (limited to 'gold/ehframe.cc')
-rw-r--r-- | gold/ehframe.cc | 28 |
1 files changed, 25 insertions, 3 deletions
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<int size, bool big_endian> typename elfcpp::Elf_types<size>::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<size>::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<size>::Elf_Addr fde_pc; - fde_pc = this->get_fde_pc<size, big_endian>(eh_frame_contents, + fde_pc = this->get_fde_pc<size, big_endian>(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<size, big_endian>* 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; |