This is the mail archive of the elfutils-devel@sourceware.org mailing list for the elfutils 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]

[patch] Fix error code from __libdw_find_fde


Hi,

__libdw_find_fde may errorneously return DWARF_E_INVALID_DWARF instead of
correct DWARF_E_NO_MATCH.

This is because .eh_frame_hdr contains only starts of ranges covered by FDEs,
not their ends (lengths).  Therefore if .eh_frame_hdr returned us some FDE but
that FDE ends before the searched PC that .eh_frame_hdr is not broken.
.eh_frame_hdr is just acceleration, not authoritative information, only
.eh_frame is authoritative what it does and what it does not cover.

Testcase for this patch is the whole testsuite of:
	[API RFC] unwinder
	https://lists.fedorahosted.org/pipermail/elfutils-devel/2012-October/002618.html

where without -> with this fix on x86_64:

$ cd tests; ./backtrace; echo $?
# 3 0x7f8ce6f56959 - 1	_start
No DWARF information found
1
->
[...]
# 3 0x7f18eae6c959 - 1	_start
0

("No DWARF information found" is not the real error code from .eh_frame_hdr,
it got translated into a different code from the DWARF unwinder.)


Thanks,
Jan


libdw/
2012-10-08  Jan Kratochvil  <jan.kratochvil@redhat.com>

	* fde.c (__libdw_find_fde): Return DWARF_E_NO_MATCH if .eh_frame_hdr
	points to FDE which is too short for searched PC.

diff --git a/libdw/fde.c b/libdw/fde.c
index bde0c99..f619912 100644
--- a/libdw/fde.c
+++ b/libdw/fde.c
@@ -231,11 +231,15 @@ __libdw_find_fde (Dwarf_CFI *cache, Dwarf_Addr address)
       struct dwarf_fde *fde = __libdw_fde_by_offset (cache, offset);
       if (unlikely (fde != NULL)
 	  /* Sanity check the address range.  */
-	  && unlikely (address < fde->start || address >= fde->end))
+	  && unlikely (address < fde->start))
 	{
 	  __libdw_seterrno (DWARF_E_INVALID_DWARF);
 	  return NULL;
 	}
+      if (unlikely (fde != NULL)
+	  /* .eh_frame_hdr does not indicate length covered by FDE.  */
+	  && unlikely (address >= fde->end))
+	goto no_match;
       return fde;
     }
 

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