summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMark Wielaard <mjw@redhat.com>2015-12-02 17:07:40 +0100
committerMark Wielaard <mjw@redhat.com>2016-01-02 20:37:45 +0100
commit8bbfc552a062e47e307a897e49f2a4a25ba6291e (patch)
treeab1a378ae1ca9444ae4721ec2f008105ff700bd9
parent70cd907e38757283f3696465771f723a342cc3d1 (diff)
downloadelfutils-8bbfc552a062e47e307a897e49f2a4a25ba6291e.tar.gz
elfutils-8bbfc552a062e47e307a897e49f2a4a25ba6291e.tar.xz
libdw: Don't leak duplicate FDEs.
Although it isn't supposed to happen there could be FDEs that cover the same address range. Don't leak such FDEs and use an existing FDE for consistency. Signed-off-by: Mark Wielaard <mjw@redhat.com>
-rw-r--r--libdw/ChangeLog4
-rw-r--r--libdw/fde.c11
2 files changed, 14 insertions, 1 deletions
diff --git a/libdw/ChangeLog b/libdw/ChangeLog
index 738e223..d0e97f3 100644
--- a/libdw/ChangeLog
+++ b/libdw/ChangeLog
@@ -1,3 +1,7 @@
+2015-12-02 Mark Wielaard <mjw@redhat.com>
+
+ * fde.c (intern_fde): Don't leak duplicate FDEs.
+
2015-12-01 Mark Wielaard <mjw@redhat.com>
* fde.c (intern_fde): Don't intern an fde that doesn't cover a
diff --git a/libdw/fde.c b/libdw/fde.c
index 2a59d3e..f5f6fbe 100644
--- a/libdw/fde.c
+++ b/libdw/fde.c
@@ -119,12 +119,21 @@ intern_fde (Dwarf_CFI *cache, const Dwarf_FDE *entry)
fde->instructions += cie->fde_augmentation_data_size;
/* Add the new entry to the search tree. */
- if (tsearch (fde, &cache->fde_tree, &compare_fde) == NULL)
+ struct dwarf_fde **tres = tsearch (fde, &cache->fde_tree, &compare_fde);
+ if (tres == NULL)
{
free (fde);
__libdw_seterrno (DWARF_E_NOMEM);
return NULL;
}
+ else if (*tres != fde)
+ {
+ /* There is already an FDE in the cache that covers the same
+ address range. That is odd. Ignore this FDE. And just use
+ the one in the cache for consistency. */
+ free (fde);
+ return *tres;
+ }
return fde;
}