diff options
author | Han Shen <shenhan@google.com> | 2016-03-10 16:58:00 -0800 |
---|---|---|
committer | Han Shen <shenhan@google.com> | 2016-03-10 17:00:27 -0800 |
commit | 066607388945f542727bd5035fb8d84bfd798034 (patch) | |
tree | eeb9926a127554d0c1ac52a87811d84c9414cbea | |
parent | 48ba8648ee02f246c4fb286d7918f750c2b4ea4f (diff) | |
download | toolchain_binutils-066607388945f542727bd5035fb8d84bfd798034.zip toolchain_binutils-066607388945f542727bd5035fb8d84bfd798034.tar.gz toolchain_binutils-066607388945f542727bd5035fb8d84bfd798034.tar.bz2 |
Backport upstream CL to fix x86_64 clang test-stlport segfaults.
Upstream patch being backported:
commit fc5a9bd57cbb974b8fc3aeb9a15d644cd9103451
Author: Cary Coutant <ccoutant@gmail.com>
Date: Fri Feb 26 07:50:15 2016 -0800
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.
TESTED=only tested building with 'build.py'
BUG=26085687
Change-Id: I52e90fba86b113a557dd4d29d36ecb4c512f3f7a
-rw-r--r-- | binutils-2.25/gold/ChangeLog | 8 | ||||
-rw-r--r-- | binutils-2.25/gold/ehframe.cc | 39 | ||||
-rw-r--r-- | binutils-2.25/gold/ehframe.h | 5 |
3 files changed, 47 insertions, 5 deletions
diff --git a/binutils-2.25/gold/ChangeLog b/binutils-2.25/gold/ChangeLog index d734a15..fc4250e 100644 --- a/binutils-2.25/gold/ChangeLog +++ b/binutils-2.25/gold/ChangeLog @@ -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-11 Rahul Chaudhry <rahulchaudhry@google.com> * aarch64.cc (Target_aarch64::scan_erratum_843419_span): Remove diff --git a/binutils-2.25/gold/ehframe.cc b/binutils-2.25/gold/ehframe.cc index 4f92618..fc45e87 100644 --- a/binutils-2.25/gold/ehframe.cc +++ b/binutils-2.25/gold/ehframe.cc @@ -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. 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; const int sym_size = elfcpp::Elf_sizes<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; fde_shndx = object->adjust_sym_shndx(symndx, sym.get_st_shndx(), &is_ordinary); + bool is_discarded = (is_ordinary + && fde_shndx != elfcpp::SHN_UNDEF + && fde_shndx < object->shnum() + && !object->is_section_included(fde_shndx)); + + // Fetch the address range field from the FDE. The offset and size + // of the field depends on the PC encoding given in the CIE, but + // it is always an absolute value. If the address range is 0, this + // 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) + { + 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_ordinary - && fde_shndx != elfcpp::SHN_UNDEF - && fde_shndx < object->shnum() - && !object->is_section_included(fde_shndx)) + if (is_discarded || address_range == 0) { - // This FDE applies to a section which we are discarding. We + // This FDE applies to a discarded function. We // can discard this FDE. this->merge_map_.add_mapping(object, shndx, (pfde - 8) - pcontents, pfdeend - (pfde - 8), -1); diff --git a/binutils-2.25/gold/ehframe.h b/binutils-2.25/gold/ehframe.h index e9c9da8..8c0df99 100644 --- a/binutils-2.25/gold/ehframe.h +++ b/binutils-2.25/gold/ehframe.h @@ -322,6 +322,11 @@ class Cie unsigned int addralign, Eh_frame_hdr* eh_frame_hdr, 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&); |