Discard FDEs for zero-length address ranges.
2016-02-26 Egor Kochetov <egor.kochetov@intel.com> Cary Coutant <ccoutant@gmail.com> gold/ PR gold/19735 * ehframe.h (Cie::fde_encoding): New method. * ehframe.cc (Eh_frame::read_fde): Discard FDEs for zero-length address ranges.
This commit is contained in:
parent
9fde51ed30
commit
fc5a9bd57c
3 changed files with 47 additions and 5 deletions
|
@ -1,3 +1,11 @@
|
||||||
|
2016-02-26 Egor Kochetov <egor.kochetov@intel.com>
|
||||||
|
Cary Coutant <ccoutant@gmail.com>
|
||||||
|
|
||||||
|
PR gold/19735
|
||||||
|
* ehframe.h (Cie::fde_encoding): New method.
|
||||||
|
* ehframe.cc (Eh_frame::read_fde): Discard FDEs for zero-length
|
||||||
|
address ranges.
|
||||||
|
|
||||||
2016-02-15 H.J. Lu <hongjiu.lu@intel.com>
|
2016-02-15 H.J. Lu <hongjiu.lu@intel.com>
|
||||||
|
|
||||||
* testsuite/Makefile.am (x86_64_mov_to_lea5.o): Pass
|
* testsuite/Makefile.am (x86_64_mov_to_lea5.o): Pass
|
||||||
|
|
|
@ -1010,6 +1010,8 @@ Eh_frame::read_fde(Sized_relobj_file<size, big_endian>* object,
|
||||||
// pointer to a PC relative offset when generating a shared library.
|
// pointer to a PC relative offset when generating a shared library.
|
||||||
relocs->advance(pfdeend - pcontents);
|
relocs->advance(pfdeend - pcontents);
|
||||||
|
|
||||||
|
// Find the section index for code that this FDE describes.
|
||||||
|
// If we have discarded the section, we can also discard the FDE.
|
||||||
unsigned int fde_shndx;
|
unsigned int fde_shndx;
|
||||||
const int sym_size = elfcpp::Elf_sizes<size>::sym_size;
|
const int sym_size = elfcpp::Elf_sizes<size>::sym_size;
|
||||||
if (symndx >= symbols_size / sym_size)
|
if (symndx >= symbols_size / sym_size)
|
||||||
|
@ -1018,13 +1020,40 @@ Eh_frame::read_fde(Sized_relobj_file<size, big_endian>* object,
|
||||||
bool is_ordinary;
|
bool is_ordinary;
|
||||||
fde_shndx = object->adjust_sym_shndx(symndx, sym.get_st_shndx(),
|
fde_shndx = object->adjust_sym_shndx(symndx, sym.get_st_shndx(),
|
||||||
&is_ordinary);
|
&is_ordinary);
|
||||||
|
bool is_discarded = (is_ordinary
|
||||||
|
&& fde_shndx != elfcpp::SHN_UNDEF
|
||||||
|
&& fde_shndx < object->shnum()
|
||||||
|
&& !object->is_section_included(fde_shndx));
|
||||||
|
|
||||||
if (is_ordinary
|
// Fetch the address range field from the FDE. The offset and size
|
||||||
&& fde_shndx != elfcpp::SHN_UNDEF
|
// of the field depends on the PC encoding given in the CIE, but
|
||||||
&& fde_shndx < object->shnum()
|
// it is always an absolute value. If the address range is 0, this
|
||||||
&& !object->is_section_included(fde_shndx))
|
// FDE corresponds to a function that was discarded during optimization
|
||||||
|
// (too late to discard the corresponding FDE).
|
||||||
|
uint64_t address_range = 0;
|
||||||
|
int pc_size = cie->fde_encoding() & 7;
|
||||||
|
if (pc_size == elfcpp::DW_EH_PE_absptr)
|
||||||
|
pc_size = size == 32 ? elfcpp::DW_EH_PE_udata4 : elfcpp::DW_EH_PE_udata8;
|
||||||
|
switch (pc_size)
|
||||||
{
|
{
|
||||||
// This FDE applies to a section which we are discarding. We
|
case elfcpp::DW_EH_PE_udata2:
|
||||||
|
address_range = elfcpp::Swap<16, big_endian>::readval(pfde + 2);
|
||||||
|
break;
|
||||||
|
case elfcpp::DW_EH_PE_udata4:
|
||||||
|
address_range = elfcpp::Swap<32, big_endian>::readval(pfde + 4);
|
||||||
|
break;
|
||||||
|
case elfcpp::DW_EH_PE_udata8:
|
||||||
|
gold_assert(size == 64);
|
||||||
|
address_range = elfcpp::Swap_unaligned<64, big_endian>::readval(pfde + 8);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
// All other cases were rejected in Eh_frame::read_cie.
|
||||||
|
gold_unreachable();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (is_discarded || address_range == 0)
|
||||||
|
{
|
||||||
|
// This FDE applies to a discarded function. We
|
||||||
// can discard this FDE.
|
// can discard this FDE.
|
||||||
object->add_merge_mapping(this, shndx, (pfde - 8) - pcontents,
|
object->add_merge_mapping(this, shndx, (pfde - 8) - pcontents,
|
||||||
pfdeend - (pfde - 8), -1);
|
pfdeend - (pfde - 8), -1);
|
||||||
|
|
|
@ -323,6 +323,11 @@ class Cie
|
||||||
unsigned int addralign, Eh_frame_hdr* eh_frame_hdr,
|
unsigned int addralign, Eh_frame_hdr* eh_frame_hdr,
|
||||||
Post_fdes* post_fdes);
|
Post_fdes* post_fdes);
|
||||||
|
|
||||||
|
// Return the FDE encoding.
|
||||||
|
unsigned char
|
||||||
|
fde_encoding() const
|
||||||
|
{ return this->fde_encoding_; }
|
||||||
|
|
||||||
friend bool operator<(const Cie&, const Cie&);
|
friend bool operator<(const Cie&, const Cie&);
|
||||||
friend bool operator==(const Cie&, const Cie&);
|
friend bool operator==(const Cie&, const Cie&);
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue