This is the mail archive of the binutils-cvs@sourceware.org mailing list for the binutils project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[binutils-gdb] Discard FDEs for zero-length address ranges.


https://sourceware.org/git/gitweb.cgi?p=binutils-gdb.git;h=fc5a9bd57cbb974b8fc3aeb9a15d644cd9103451

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.

Diff:
---
 gold/ChangeLog  |  8 ++++++++
 gold/ehframe.cc | 39 ++++++++++++++++++++++++++++++++++-----
 gold/ehframe.h  |  5 +++++
 3 files changed, 47 insertions(+), 5 deletions(-)

diff --git a/gold/ChangeLog b/gold/ChangeLog
index 45d02bf..53c1ceb 100644
--- a/gold/ChangeLog
+++ b/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-15  H.J. Lu  <hongjiu.lu@intel.com>
 
 	* testsuite/Makefile.am (x86_64_mov_to_lea5.o): Pass
diff --git a/gold/ehframe.cc b/gold/ehframe.cc
index 71bcc20..57eb031 100644
--- a/gold/ehframe.cc
+++ b/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.
       object->add_merge_mapping(this, shndx, (pfde - 8) - pcontents,
                                 pfdeend - (pfde - 8), -1);
diff --git a/gold/ehframe.h b/gold/ehframe.h
index a32b550..14281b0 100644
--- a/gold/ehframe.h
+++ b/gold/ehframe.h
@@ -323,6 +323,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&);


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]