[5/9,libbacktrace] Unify function name preference handling

Message ID 20181211101411.7067-6-tdevries@suse.de
State New
Headers show
Series
  • Handle .gnu_debugaltlink
Related show

Commit Message

Tom de Vries Dec. 11, 2018, 10:14 a.m.
Both read_function_entry and read_referenced_name implement a priority scheme
for names.  The priorities are:
- 1st: DW_AT_linkage_name
- 2nd: Name from DW_AT_abstract_origin or DW_AT_specification
- 3rd: DW_AT_name.

Ensure both functions fully adhere to it.

2018-11-21  Tom de Vries  <tdevries@suse.de>

	* dwarf.c (read_referenced_name): Don't allow DW_AT_name to override any
	name.
	(read_function_entry): Same.  Don't allow name found via
	DW_AT_abstract_origin or case DW_AT_specification to override linkage
	name.
---
 libbacktrace/dwarf.c | 33 +++++++++++++++++++++++----------
 1 file changed, 23 insertions(+), 10 deletions(-)

-- 
2.16.4

Comments

Richard Biener via Gcc-patches Jan. 16, 2019, 1:10 a.m. | #1
On Tue, Dec 11, 2018 at 2:15 AM Tom de Vries <tdevries@suse.de> wrote:
>

> Both read_function_entry and read_referenced_name implement a priority scheme

> for names.  The priorities are:

> - 1st: DW_AT_linkage_name

> - 2nd: Name from DW_AT_abstract_origin or DW_AT_specification

> - 3rd: DW_AT_name.

>

> Ensure both functions fully adhere to it.

>

> 2018-11-21  Tom de Vries  <tdevries@suse.de>

>

>         * dwarf.c (read_referenced_name): Don't allow DW_AT_name to override any

>         name.

>         (read_function_entry): Same.  Don't allow name found via

>         DW_AT_abstract_origin or case DW_AT_specification to override linkage

>         name.


This is OK.

Thanks.

Ian

Patch

diff --git a/libbacktrace/dwarf.c b/libbacktrace/dwarf.c
index 341b84605c0..2483295beb4 100644
--- a/libbacktrace/dwarf.c
+++ b/libbacktrace/dwarf.c
@@ -2175,18 +2175,25 @@  read_referenced_name (struct dwarf_data *ddata, struct unit *u,
       switch (abbrev->attrs[i].name)
 	{
 	case DW_AT_name:
-	  /* We prefer the linkage name if get one.  */
+	  /* Third name preference: don't override.  A name we found in some
+	     other way, will normally be more useful -- e.g., this name is
+	     normally not mangled.  */
+	  if (ret != NULL)
+	    break;
 	  if (val.encoding == ATTR_VAL_STRING)
 	    ret = val.u.string;
 	  break;
 
 	case DW_AT_linkage_name:
 	case DW_AT_MIPS_linkage_name:
+	  /* First name preference: override all.  */
 	  if (val.encoding == ATTR_VAL_STRING)
 	    return val.u.string;
 	  break;
 
 	case DW_AT_specification:
+	  /* Second name preference: override DW_AT_name, don't override
+	     DW_AT_linkage_name.  */
 	  if (abbrev->attrs[i].form == DW_FORM_ref_addr
 	      || abbrev->attrs[i].form == DW_FORM_ref_sig8)
 	    {
@@ -2339,6 +2346,7 @@  read_function_entry (struct backtrace_state *state, struct dwarf_data *ddata,
       int highpc_is_relative;
       uint64_t ranges;
       int have_ranges;
+      int have_linkage_name;
 
       code = read_uleb128 (unit_buf);
       if (code == 0)
@@ -2375,6 +2383,7 @@  read_function_entry (struct backtrace_state *state, struct dwarf_data *ddata,
       highpc_is_relative = 0;
       ranges = 0;
       have_ranges = 0;
+      have_linkage_name = 0;
       for (i = 0; i < abbrev->num_attrs; ++i)
 	{
 	  struct attr_val val;
@@ -2423,6 +2432,10 @@  read_function_entry (struct backtrace_state *state, struct dwarf_data *ddata,
 
 		case DW_AT_abstract_origin:
 		case DW_AT_specification:
+		  /* Second name preference: override DW_AT_name, don't override
+		     DW_AT_linkage_name.  */
+		  if (have_linkage_name)
+		    break;
 		  if (abbrev->attrs[i].form == DW_FORM_ref_addr
 		      || abbrev->attrs[i].form == DW_FORM_ref_sig8)
 		    {
@@ -2444,21 +2457,21 @@  read_function_entry (struct backtrace_state *state, struct dwarf_data *ddata,
 		  break;
 
 		case DW_AT_name:
+		  /* Third name preference: don't override.  */
+		  if (function->name != NULL)
+		    break;
 		  if (val.encoding == ATTR_VAL_STRING)
-		    {
-		      /* Don't override a name we found in some other
-			 way, as it will normally be more
-			 useful--e.g., this name is normally not
-			 mangled.  */
-		      if (function->name == NULL)
-			function->name = val.u.string;
-		    }
+		    function->name = val.u.string;
 		  break;
 
 		case DW_AT_linkage_name:
 		case DW_AT_MIPS_linkage_name:
+		  /* First name preference: override all.  */
 		  if (val.encoding == ATTR_VAL_STRING)
-		    function->name = val.u.string;
+		    {
+		      function->name = val.u.string;
+		      have_linkage_name = 1;
+		    }
 		  break;
 
 		case DW_AT_low_pc: