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] backends: Check type DIE exists before calling dwarf_tag ().


dwarf_attr () or dwarf_form () functions leave typedie NULL when they fail
because of missing attribute or unexpected form. In such cases first check
the DIE exists and return error instead of calling dwarf_tag () and crashing.

This also happens in the testsuite with native tests when elfutils is build
without DWZ support on a distro that uses DWZ DWARF compression on system
libraries. Only the backends used dwarf_tag () directly without checking,
all other uses in elfutils already checked whether the given DIE was NULL.

Signed-off-by: Mark Wielaard <mjw@redhat.com>
---
 backends/ChangeLog       |   17 +++++++++++++++++
 backends/alpha_retval.c  |    7 ++++---
 backends/arm_retval.c    |    7 ++++---
 backends/i386_retval.c   |    7 ++++---
 backends/ia64_retval.c   |   10 ++++++----
 backends/libebl_CPU.h    |   11 +++++++++++
 backends/ppc64_retval.c  |    3 ++-
 backends/ppc_retval.c    |    7 ++++---
 backends/s390_retval.c   |    7 ++++---
 backends/sh_retval.c     |    7 ++++---
 backends/sparc_retval.c  |    7 ++++---
 backends/tilegx_retval.c |    9 +++++----
 backends/x86_64_retval.c |    7 ++++---
 13 files changed, 73 insertions(+), 33 deletions(-)

diff --git a/backends/ChangeLog b/backends/ChangeLog
index ab9cde9..0e51af2 100644
--- a/backends/ChangeLog
+++ b/backends/ChangeLog
@@ -1,3 +1,20 @@
+2013-02-06  Mark Wielaard  <mjw@redhat.com>
+
+	* libebl_CPU.h (CHECK_DWARF_TAG): New macro.
+	* backends/alpha_retval.c (alpha_return_value_location): Use new
+	CHECK_DWARF_TAG macro instead of dwarf_tag ().
+	* backends/arm_retval.c (arm_return_value_location): Likewise.
+	* backends/i386_retval.c (i386_return_value_location): Likewise.
+	* backends/ia64_retval.c (hfa_type): Likewise.
+	(ia64_return_value_location): Likewise.
+	* backends/ppc64_retval.c (ppc64_return_value_location): Likewise.
+	* backends/ppc_retval.c (ppc_return_value_location): Likewise.
+	* backends/s390_retval.c (s390_return_value_location): Likewise.
+	* backends/sh_retval.c (sh_return_value_location): Likewise.
+	* backends/sparc_retval.c (sparc_return_value_location): Likewise.
+	* backends/tilegx_retval.c (tilegx_return_value_location): Likewise.
+	* backends/x86_64_retval.c (x86_64_return_value_location): Likewise.
+
 2013-01-29  Jan Kratochvil  <jan.kratochvil@redhat.com>
 	    Roland McGrath <roland@hack.frob.com>
 
diff --git a/backends/alpha_retval.c b/backends/alpha_retval.c
index 62cbfc7..19a6253 100644
--- a/backends/alpha_retval.c
+++ b/backends/alpha_retval.c
@@ -75,9 +75,10 @@ alpha_return_value_location (Dwarf_Die *functypedie, const Dwarf_Op **locp)
     /* The function has no return value, like a `void' function in C.  */
     return 0;
 
+  int tag;
   Dwarf_Die die_mem;
   Dwarf_Die *typedie = dwarf_formref_die (attr, &die_mem);
-  int tag = dwarf_tag (typedie);
+  CHECK_DWARF_TAG (typedie, tag);
 
   /* Follow typedefs and qualifiers to get to the actual type.  */
   while (tag == DW_TAG_typedef
@@ -86,7 +87,7 @@ alpha_return_value_location (Dwarf_Die *functypedie, const Dwarf_Op **locp)
     {
       attr = dwarf_attr_integrate (typedie, DW_AT_type, &attr_mem);
       typedie = dwarf_formref_die (attr, &die_mem);
-      tag = dwarf_tag (typedie);
+      CHECK_DWARF_TAG (typedie, tag);
     }
 
   switch (tag)
@@ -99,7 +100,7 @@ alpha_return_value_location (Dwarf_Die *functypedie, const Dwarf_Op **locp)
 	{
 	  attr = dwarf_attr_integrate (typedie, DW_AT_type, &attr_mem);
 	  typedie = dwarf_formref_die (attr, &die_mem);
-	  tag = dwarf_tag (typedie);
+	  CHECK_DWARF_TAG (typedie, tag);
 	}
       /* Fall through.  */
 
diff --git a/backends/arm_retval.c b/backends/arm_retval.c
index 0c33c5b..6483bc2 100644
--- a/backends/arm_retval.c
+++ b/backends/arm_retval.c
@@ -71,9 +71,10 @@ arm_return_value_location (Dwarf_Die *functypedie, const Dwarf_Op **locp)
     /* The function has no return value, like a `void' function in C.  */
     return 0;
 
+  int tag;
   Dwarf_Die die_mem;
   Dwarf_Die *typedie = dwarf_formref_die (attr, &die_mem);
-  int tag = dwarf_tag (typedie);
+  CHECK_DWARF_TAG (typedie, tag);
 
   /* Follow typedefs and qualifiers to get to the actual type.  */
   while (tag == DW_TAG_typedef
@@ -82,7 +83,7 @@ arm_return_value_location (Dwarf_Die *functypedie, const Dwarf_Op **locp)
     {
       attr = dwarf_attr_integrate (typedie, DW_AT_type, &attr_mem);
       typedie = dwarf_formref_die (attr, &die_mem);
-      tag = dwarf_tag (typedie);
+      CHECK_DWARF_TAG (typedie, tag);
     }
 
   Dwarf_Word size;
@@ -96,7 +97,7 @@ arm_return_value_location (Dwarf_Die *functypedie, const Dwarf_Op **locp)
 	{
 	  attr = dwarf_attr_integrate (typedie, DW_AT_type, &attr_mem);
 	  typedie = dwarf_formref_die (attr, &die_mem);
-	  tag = dwarf_tag (typedie);
+	  CHECK_DWARF_TAG (typedie, tag);
 	}
       /* Fall through.  */
 
diff --git a/backends/i386_retval.c b/backends/i386_retval.c
index 95f5b92..ce5bb13 100644
--- a/backends/i386_retval.c
+++ b/backends/i386_retval.c
@@ -75,9 +75,10 @@ i386_return_value_location (Dwarf_Die *functypedie, const Dwarf_Op **locp)
     /* The function has no return value, like a `void' function in C.  */
     return 0;
 
+  int tag;
   Dwarf_Die die_mem;
   Dwarf_Die *typedie = dwarf_formref_die (attr, &die_mem);
-  int tag = dwarf_tag (typedie);
+  CHECK_DWARF_TAG (typedie, tag);
 
   /* Follow typedefs and qualifiers to get to the actual type.  */
   while (tag == DW_TAG_typedef
@@ -86,7 +87,7 @@ i386_return_value_location (Dwarf_Die *functypedie, const Dwarf_Op **locp)
     {
       attr = dwarf_attr_integrate (typedie, DW_AT_type, &attr_mem);
       typedie = dwarf_formref_die (attr, &die_mem);
-      tag = dwarf_tag (typedie);
+      CHECK_DWARF_TAG (typedie, tag);
     }
 
   switch (tag)
@@ -99,7 +100,7 @@ i386_return_value_location (Dwarf_Die *functypedie, const Dwarf_Op **locp)
 	{
 	  attr = dwarf_attr_integrate (typedie, DW_AT_type, &attr_mem);
 	  typedie = dwarf_formref_die (attr, &die_mem);
-	  tag = dwarf_tag (typedie);
+	  CHECK_DWARF_TAG (typedie, tag);
 	}
       /* Fall through.  */
 
diff --git a/backends/ia64_retval.c b/backends/ia64_retval.c
index 644359b..26472b5 100644
--- a/backends/ia64_retval.c
+++ b/backends/ia64_retval.c
@@ -109,7 +109,8 @@ hfa_type (Dwarf_Die *typedie, Dwarf_Word size,
       return fpregs_used + nregs;
     }
 
-  int tag = dwarf_tag (typedie);
+  int tag;
+  CHECK_DWARF_TAG (typedie, tag);
   switch (tag)
     {
       Dwarf_Attribute attr_mem;
@@ -246,9 +247,10 @@ ia64_return_value_location (Dwarf_Die *functypedie, const Dwarf_Op **locp)
     /* The function has no return value, like a `void' function in C.  */
     return 0;
 
+  int tag;
   Dwarf_Die die_mem;
   Dwarf_Die *typedie = dwarf_formref_die (attr, &die_mem);
-  int tag = dwarf_tag (typedie);
+  CHECK_DWARF_TAG (typedie, tag);
 
   /* Follow typedefs and qualifiers to get to the actual type.  */
   while (tag == DW_TAG_typedef
@@ -257,7 +259,7 @@ ia64_return_value_location (Dwarf_Die *functypedie, const Dwarf_Op **locp)
     {
       attr = dwarf_attr (typedie, DW_AT_type, &attr_mem);
       typedie = dwarf_formref_die (attr, &die_mem);
-      tag = dwarf_tag (typedie);
+      CHECK_DWARF_TAG (typedie, tag);
     }
 
   Dwarf_Word size;
@@ -271,7 +273,7 @@ ia64_return_value_location (Dwarf_Die *functypedie, const Dwarf_Op **locp)
 	{
 	  attr = dwarf_attr_integrate (typedie, DW_AT_type, &attr_mem);
 	  typedie = dwarf_formref_die (attr, &die_mem);
-	  tag = dwarf_tag (typedie);
+	  CHECK_DWARF_TAG (typedie, tag);
 	}
       /* Fall through.  */
 
diff --git a/backends/libebl_CPU.h b/backends/libebl_CPU.h
index 36b3a4a..2cfa980 100644
--- a/backends/libebl_CPU.h
+++ b/backends/libebl_CPU.h
@@ -45,5 +45,16 @@ extern const char *EBLHOOK(init) (Elf *elf, GElf_Half machine,
 
 extern bool (*generic_debugscn_p) (const char *) attribute_hidden;
 
+/* Helper for retval.  Does tag = dwarf_tag (die), but returns early
+   if there where previous errors that leave die NULL.  */
+#define CHECK_DWARF_TAG(die, tag) \
+  do				  \
+    {				  \
+      if (! die)		  \
+	return -1;		  \
+      tag = dwarf_tag (die);	  \
+    }				  \
+  while (0);
+
 
 #endif	/* libebl_CPU.h */
diff --git a/backends/ppc64_retval.c b/backends/ppc64_retval.c
index b26bb1e..4962b9c 100644
--- a/backends/ppc64_retval.c
+++ b/backends/ppc64_retval.c
@@ -85,9 +85,10 @@ ppc64_return_value_location (Dwarf_Die *functypedie, const Dwarf_Op **locp)
     /* The function has no return value, like a `void' function in C.  */
     return 0;
 
+  int tag;
   Dwarf_Die die_mem;
   Dwarf_Die *typedie = dwarf_formref_die (attr, &die_mem);
-  int tag = dwarf_tag (typedie);
+  CHECK_DWARF_TAG (typedie, tag);
 
   /* Follow typedefs and qualifiers to get to the actual type.  */
   while (tag == DW_TAG_typedef
diff --git a/backends/ppc_retval.c b/backends/ppc_retval.c
index 29f5a23..e55d916 100644
--- a/backends/ppc_retval.c
+++ b/backends/ppc_retval.c
@@ -97,9 +97,10 @@ ppc_return_value_location (Dwarf_Die *functypedie, const Dwarf_Op **locp)
     /* The function has no return value, like a `void' function in C.  */
     return 0;
 
+  int tag;
   Dwarf_Die die_mem;
   Dwarf_Die *typedie = dwarf_formref_die (attr, &die_mem);
-  int tag = dwarf_tag (typedie);
+  CHECK_DWARF_TAG (typedie, tag);
 
   /* Follow typedefs and qualifiers to get to the actual type.  */
   while (tag == DW_TAG_typedef
@@ -108,7 +109,7 @@ ppc_return_value_location (Dwarf_Die *functypedie, const Dwarf_Op **locp)
     {
       attr = dwarf_attr_integrate (typedie, DW_AT_type, &attr_mem);
       typedie = dwarf_formref_die (attr, &die_mem);
-      tag = dwarf_tag (typedie);
+      CHECK_DWARF_TAG (typedie, tag);
     }
 
   Dwarf_Word size;
@@ -122,7 +123,7 @@ ppc_return_value_location (Dwarf_Die *functypedie, const Dwarf_Op **locp)
 	{
 	  attr = dwarf_attr_integrate (typedie, DW_AT_type, &attr_mem);
 	  typedie = dwarf_formref_die (attr, &die_mem);
-	  tag = dwarf_tag (typedie);
+	  CHECK_DWARF_TAG (typedie, tag);
 	}
       /* Fall through.  */
 
diff --git a/backends/s390_retval.c b/backends/s390_retval.c
index 4cebe45..822455e 100644
--- a/backends/s390_retval.c
+++ b/backends/s390_retval.c
@@ -76,9 +76,10 @@ s390_return_value_location (Dwarf_Die *functypedie, const Dwarf_Op **locp)
     /* The function has no return value, like a `void' function in C.  */
     return 0;
 
+  int tag;
   Dwarf_Die die_mem;
   Dwarf_Die *typedie = dwarf_formref_die (attr, &die_mem);
-  int tag = dwarf_tag (typedie);
+  CHECK_DWARF_TAG (typedie, tag);
 
   /* Follow typedefs and qualifiers to get to the actual type.  */
   while (tag == DW_TAG_typedef
@@ -87,7 +88,7 @@ s390_return_value_location (Dwarf_Die *functypedie, const Dwarf_Op **locp)
     {
       attr = dwarf_attr_integrate (typedie, DW_AT_type, &attr_mem);
       typedie = dwarf_formref_die (attr, &die_mem);
-      tag = dwarf_tag (typedie);
+      CHECK_DWARF_TAG (typedie, tag);
     }
 
   Dwarf_Word size;
@@ -101,7 +102,7 @@ s390_return_value_location (Dwarf_Die *functypedie, const Dwarf_Op **locp)
 	{
 	  attr = dwarf_attr (typedie, DW_AT_type, &attr_mem);
 	  typedie = dwarf_formref_die (attr, &die_mem);
-	  tag = dwarf_tag (typedie);
+	  CHECK_DWARF_TAG (typedie, tag);
 	}
       /* Fall through.  */
 
diff --git a/backends/sh_retval.c b/backends/sh_retval.c
index 4692d35..b723916 100644
--- a/backends/sh_retval.c
+++ b/backends/sh_retval.c
@@ -73,9 +73,10 @@ sh_return_value_location (Dwarf_Die *functypedie, const Dwarf_Op **locp)
     /* The function has no return value, like a `void' function in C.  */
     return 0;
 
+  int tag;
   Dwarf_Die die_mem;
   Dwarf_Die *typedie = dwarf_formref_die (attr, &die_mem);
-  int tag = dwarf_tag (typedie);
+  CHECK_DWARF_TAG (typedie, tag);
 
   /* Follow typedefs and qualifiers to get to the actual type.  */
   while (tag == DW_TAG_typedef
@@ -84,7 +85,7 @@ sh_return_value_location (Dwarf_Die *functypedie, const Dwarf_Op **locp)
     {
       attr = dwarf_attr_integrate (typedie, DW_AT_type, &attr_mem);
       typedie = dwarf_formref_die (attr, &die_mem);
-      tag = dwarf_tag (typedie);
+      CHECK_DWARF_TAG (typedie, tag);
     }
 
   Dwarf_Word size;
@@ -98,7 +99,7 @@ sh_return_value_location (Dwarf_Die *functypedie, const Dwarf_Op **locp)
 	{
 	  attr = dwarf_attr_integrate (typedie, DW_AT_type, &attr_mem);
 	  typedie = dwarf_formref_die (attr, &die_mem);
-	  tag = dwarf_tag (typedie);
+	  CHECK_DWARF_TAG (typedie, tag);
 	}
       /* Fall through.  */
 
diff --git a/backends/sparc_retval.c b/backends/sparc_retval.c
index 2c2728c..2dafb99 100644
--- a/backends/sparc_retval.c
+++ b/backends/sparc_retval.c
@@ -80,9 +80,10 @@ sparc_return_value_location (Dwarf_Die *functypedie, const Dwarf_Op **locp)
     /* The function has no return value, like a `void' function in C.  */
     return 0;
 
+  int tag;
   Dwarf_Die die_mem;
   Dwarf_Die *typedie = dwarf_formref_die (attr, &die_mem);
-  int tag = dwarf_tag (typedie);
+  CHECK_DWARF_TAG (typedie, tag);
 
   /* Follow typedefs and qualifiers to get to the actual type.  */
   while (tag == DW_TAG_typedef
@@ -91,7 +92,7 @@ sparc_return_value_location (Dwarf_Die *functypedie, const Dwarf_Op **locp)
     {
       attr = dwarf_attr_integrate (typedie, DW_AT_type, &attr_mem);
       typedie = dwarf_formref_die (attr, &die_mem);
-      tag = dwarf_tag (typedie);
+      CHECK_DWARF_TAG (typedie, tag);
     }
 
   Dwarf_Word size;
@@ -105,7 +106,7 @@ sparc_return_value_location (Dwarf_Die *functypedie, const Dwarf_Op **locp)
 	{
 	  attr = dwarf_attr_integrate (typedie, DW_AT_type, &attr_mem);
 	  typedie = dwarf_formref_die (attr, &die_mem);
-	  tag = dwarf_tag (typedie);
+	  CHECK_DWARF_TAG (typedie, tag);
 	}
       /* Fall through.  */
 
diff --git a/backends/tilegx_retval.c b/backends/tilegx_retval.c
index fd4feef..1ddce37 100644
--- a/backends/tilegx_retval.c
+++ b/backends/tilegx_retval.c
@@ -67,9 +67,10 @@ tilegx_return_value_location (Dwarf_Die *functypedie, const Dwarf_Op **locp)
     /* The function has no return value, like a `void' function in C.  */
     return 0;
 
+  int tag;
   Dwarf_Die die_mem;
   Dwarf_Die *typedie = dwarf_formref_die (attr, &die_mem);
-  int tag = dwarf_tag (typedie);
+  CHECK_DWARF_TAG (typedie, tag);
 
   /* Follow typedefs and qualifiers to get to the actual type.  */
   while (tag == DW_TAG_typedef
@@ -78,7 +79,7 @@ tilegx_return_value_location (Dwarf_Die *functypedie, const Dwarf_Op **locp)
     {
       attr = dwarf_attr_integrate (typedie, DW_AT_type, &attr_mem);
       typedie = dwarf_formref_die (attr, &die_mem);
-      tag = dwarf_tag (typedie);
+      CHECK_DWARF_TAG (typedie, tag);
     }
 
   Dwarf_Word size;
@@ -92,7 +93,7 @@ tilegx_return_value_location (Dwarf_Die *functypedie, const Dwarf_Op **locp)
 	{
 	  attr = dwarf_attr_integrate (typedie, DW_AT_type, &attr_mem);
 	  typedie = dwarf_formref_die (attr, &die_mem);
-	  tag = dwarf_tag (typedie);
+	  CHECK_DWARF_TAG (typedie, tag);
 	}
       /* Fall through.  */
 
@@ -142,7 +143,7 @@ tilegx_return_value_location (Dwarf_Die *functypedie, const Dwarf_Op **locp)
 	      /* Check if it's a character array.  */
 	      attr = dwarf_attr_integrate (typedie, DW_AT_type, &attr_mem);
 	      typedie = dwarf_formref_die (attr, &die_mem);
-	      tag = dwarf_tag (typedie);
+	      CHECK_DWARF_TAG (typedie, tag);
 	      if (tag != DW_TAG_base_type)
 		goto aggregate;
 	      if (dwarf_formudata (dwarf_attr_integrate (typedie,
diff --git a/backends/x86_64_retval.c b/backends/x86_64_retval.c
index d67b05f..15cc258 100644
--- a/backends/x86_64_retval.c
+++ b/backends/x86_64_retval.c
@@ -89,9 +89,10 @@ x86_64_return_value_location (Dwarf_Die *functypedie, const Dwarf_Op **locp)
     /* The function has no return value, like a `void' function in C.  */
     return 0;
 
+  int tag;
   Dwarf_Die die_mem;
   Dwarf_Die *typedie = dwarf_formref_die (attr, &die_mem);
-  int tag = dwarf_tag (typedie);
+  CHECK_DWARF_TAG (typedie, tag);
 
   /* Follow typedefs and qualifiers to get to the actual type.  */
   while (tag == DW_TAG_typedef
@@ -100,7 +101,7 @@ x86_64_return_value_location (Dwarf_Die *functypedie, const Dwarf_Op **locp)
     {
       attr = dwarf_attr_integrate (typedie, DW_AT_type, &attr_mem);
       typedie = dwarf_formref_die (attr, &die_mem);
-      tag = dwarf_tag (typedie);
+      CHECK_DWARF_TAG (typedie, tag);
     }
 
   Dwarf_Word size;
@@ -114,7 +115,7 @@ x86_64_return_value_location (Dwarf_Die *functypedie, const Dwarf_Op **locp)
 	{
 	  attr = dwarf_attr_integrate (typedie, DW_AT_type, &attr_mem);
 	  typedie = dwarf_formref_die (attr, &die_mem);
-	  tag = dwarf_tag (typedie);
+	  CHECK_DWARF_TAG (typedie, tag);
 	}
       /* Fall through.  */
 
-- 
1.7.1


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