Factor out the common handling of DW_AT_abstract_origin and
DW_AT_specification from read_function_entry and read_referenced_name.

2018-12-10  Tom de Vries  <tdevr...@suse.de>

        * dwarf.c (read_referenced_name_1): New function.  Factor out of ...
        (read_referenced_name): ... here, and ...
        (read_function_entry): ... here.
---
 libbacktrace/dwarf.c | 83 +++++++++++++++++++++++++++++++---------------------
 1 file changed, 50 insertions(+), 33 deletions(-)

diff --git a/libbacktrace/dwarf.c b/libbacktrace/dwarf.c
index 2483295beb4..99e5f4c3f51 100644
--- a/libbacktrace/dwarf.c
+++ b/libbacktrace/dwarf.c
@@ -2111,6 +2111,42 @@ read_line_info (struct backtrace_state *state, struct 
dwarf_data *ddata,
   return 0;
 }
 
+static const char *read_referenced_name (struct dwarf_data *, struct unit *,
+                                        uint64_t, backtrace_error_callback,
+                                        void *);
+
+/* Read the name of a function from a DIE referenced by ATTR with VAL.  */
+
+static const char *
+read_referenced_name_1 (struct dwarf_data *ddata, struct unit *u,
+                       struct attr *attr, struct attr_val *val,
+                       backtrace_error_callback error_callback, void *data)
+{
+  switch (attr->name)
+    {
+    case DW_AT_abstract_origin:
+    case DW_AT_specification:
+      break;
+    default:
+      return NULL;
+    }
+
+  if (attr->form == DW_FORM_ref_addr
+      || attr->form == DW_FORM_ref_sig8)
+    {
+      /* This refers to an abstract origin defined in
+        some other compilation unit.  We can handle
+        this case if we must, but it's harder.  */
+      return NULL;
+    }
+
+  if (val->encoding == ATTR_VAL_UINT
+      || val->encoding == ATTR_VAL_REF_UNIT)
+    return read_referenced_name (ddata, u, val->u.uint, error_callback, data);
+
+  return NULL;
+}
+
 /* Read the name of a function from a DIE referenced by a
    DW_AT_abstract_origin or DW_AT_specification tag.  OFFSET is within
    the same compilation unit.  */
@@ -2194,24 +2230,14 @@ read_referenced_name (struct dwarf_data *ddata, struct 
unit *u,
        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)
-           {
-             /* This refers to a specification defined in some other
-                compilation unit.  We can handle this case if we
-                must, but it's harder.  */
-             break;
-           }
-         if (val.encoding == ATTR_VAL_UINT
-             || val.encoding == ATTR_VAL_REF_UNIT)
-           {
-             const char *name;
+         {
+           const char *name;
 
-             name = read_referenced_name (ddata, u, val.u.uint,
+           name = read_referenced_name_1 (ddata, u, &abbrev->attrs[i], &val,
                                           error_callback, data);
-             if (name != NULL)
-               ret = name;
-           }
+           if (name != NULL)
+             ret = name;
+         }
          break;
 
        default:
@@ -2436,24 +2462,15 @@ read_function_entry (struct backtrace_state *state, 
struct dwarf_data *ddata,
                     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)
-                   {
-                     /* This refers to an abstract origin defined in
-                        some other compilation unit.  We can handle
-                        this case if we must, but it's harder.  */
-                     break;
-                   }
-                 if (val.encoding == ATTR_VAL_UINT
-                     || val.encoding == ATTR_VAL_REF_UNIT)
-                   {
-                     const char *name;
+                 {
+                   const char *name;
 
-                     name = read_referenced_name (ddata, u, val.u.uint,
-                                                  error_callback, data);
-                     if (name != NULL)
-                       function->name = name;
-                   }
+                   name
+                     = read_referenced_name_1 (ddata, u, &abbrev->attrs[i],
+                                               &val, error_callback, data);
+                   if (name != NULL)
+                     function->name = name;
+                 }
                  break;
 
                case DW_AT_name:
-- 
2.16.4

Reply via email to