summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorHan Shen <shenhan@google.com>2016-03-10 16:58:00 -0800
committerHan Shen <shenhan@google.com>2016-03-10 17:00:27 -0800
commit066607388945f542727bd5035fb8d84bfd798034 (patch)
treeeeb9926a127554d0c1ac52a87811d84c9414cbea
parent48ba8648ee02f246c4fb286d7918f750c2b4ea4f (diff)
downloadtoolchain_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/ChangeLog8
-rw-r--r--binutils-2.25/gold/ehframe.cc39
-rw-r--r--binutils-2.25/gold/ehframe.h5
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&);