mirror of
https://github.com/espressif/binutils-gdb.git
synced 2025-06-27 14:39:09 +08:00
Fix ehframe header handling for shared libraries.
This commit is contained in:
@ -234,8 +234,11 @@ Eh_frame_hdr::do_sized_write(Output_file* of)
|
|||||||
|
|
||||||
template<int size, bool big_endian>
|
template<int size, bool big_endian>
|
||||||
typename elfcpp::Elf_types<size>::Elf_Addr
|
typename elfcpp::Elf_types<size>::Elf_Addr
|
||||||
Eh_frame_hdr::get_fde_pc(const unsigned char* eh_frame_contents,
|
Eh_frame_hdr::get_fde_pc(
|
||||||
off_t fde_offset, unsigned char fde_encoding)
|
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
|
// The FDE starts with a 4 byte length and a 4 byte offset to the
|
||||||
// CIE. The PC follows.
|
// CIE. The PC follows.
|
||||||
@ -274,6 +277,22 @@ Eh_frame_hdr::get_fde_pc(const unsigned char* eh_frame_contents,
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
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();
|
gold_unreachable();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -304,7 +323,8 @@ Eh_frame_hdr::get_fde_addresses(Output_file* of,
|
|||||||
++p)
|
++p)
|
||||||
{
|
{
|
||||||
typename elfcpp::Elf_types<size>::Elf_Addr fde_pc;
|
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);
|
p->first, p->second);
|
||||||
fde_addresses->push_back(fde_pc, eh_frame_address + p->first);
|
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:
|
case elfcpp::DW_EH_PE_udata8:
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
|
// We don't expect to see any other cases here, and
|
||||||
|
// we're not prepared to handle them.
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
++p;
|
++p;
|
||||||
|
@ -131,7 +131,8 @@ class Eh_frame_hdr : public Output_section_data
|
|||||||
// Return the PC to which an FDE refers.
|
// Return the PC to which an FDE refers.
|
||||||
template<int size, bool big_endian>
|
template<int size, bool big_endian>
|
||||||
typename elfcpp::Elf_types<size>::Elf_Addr
|
typename elfcpp::Elf_types<size>::Elf_Addr
|
||||||
get_fde_pc(const unsigned char* eh_frame_contents,
|
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);
|
off_t fde_offset, unsigned char fde_encoding);
|
||||||
|
|
||||||
// Convert Fde_offsets to Fde_addresses.
|
// Convert Fde_offsets to Fde_addresses.
|
||||||
|
@ -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
|
// Find the PT_LOAD segments, and set their addresses and offsets
|
||||||
// and their section's addresses and offsets.
|
// and their section's addresses and offsets.
|
||||||
uint64_t addr;
|
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();
|
addr = options_.text_segment_address();
|
||||||
else
|
else
|
||||||
addr = target->default_text_segment_address();
|
addr = target->default_text_segment_address();
|
||||||
|
Reference in New Issue
Block a user