DistroBaker 6ff1af
From bab443ab4f756ef80f814af0353143f41e90e6a6 Mon Sep 17 00:00:00 2001
DistroBaker 6ff1af
From: Jan Kratochvil <jan.kratochvil@redhat.com>
DistroBaker 6ff1af
Date: Mon, 17 Aug 2020 21:58:19 +0200
DistroBaker 6ff1af
Subject: [PATCH 4/6] [NFC] debugedit: Move code to separate functions.
DistroBaker 6ff1af
DistroBaker 6ff1af
New functions edit_strp, skip_form and edit_attributes_str_comp_dir
DistroBaker 6ff1af
called by edit_attributes.
DistroBaker 6ff1af
Split part of read_dwarf2_line into a read_dwarf4_line function.
DistroBaker 6ff1af
New function edit_dwarf2_any_str called by edit_dwarf2 at the end of
DistroBaker 6ff1af
phase 0 to rebuild .debug_str.
DistroBaker 6ff1af
---
DistroBaker 6ff1af
 tools/debugedit.c | 367 ++++++++++++++++++++++++++--------------------
DistroBaker 6ff1af
 1 file changed, 212 insertions(+), 155 deletions(-)
DistroBaker 6ff1af
DistroBaker 6ff1af
diff --git a/tools/debugedit.c b/tools/debugedit.c
DistroBaker 6ff1af
index 87c1cd622..7464883c5 100644
DistroBaker 6ff1af
--- a/tools/debugedit.c
DistroBaker 6ff1af
+++ b/tools/debugedit.c
DistroBaker 6ff1af
@@ -1457,37 +1457,128 @@ edit_dwarf2_line (DSO *dso)
DistroBaker 6ff1af
     }
DistroBaker 6ff1af
 }
DistroBaker 6ff1af
 
DistroBaker 6ff1af
-/* Called during phase zero for each debug_line table referenced from
DistroBaker 6ff1af
-   .debug_info.  Outputs all source files seen and records any
DistroBaker 6ff1af
-   adjustments needed in the debug_list data structures. Returns true
DistroBaker 6ff1af
-   if line_table needs to be rewrite either the dir or file paths. */
DistroBaker 6ff1af
+/* Record or adjust (according to phase) DW_FORM_strp.  */
DistroBaker 6ff1af
+static void
DistroBaker 6ff1af
+edit_strp (DSO *dso, unsigned char *ptr, int phase, bool handled_strp)
DistroBaker 6ff1af
+{
DistroBaker 6ff1af
+  unsigned char *ptr_orig = ptr;
DistroBaker 6ff1af
+
DistroBaker 6ff1af
+  /* In the first pass we collect all strings, in the
DistroBaker 6ff1af
+     second we put the new references back (if there are
DistroBaker 6ff1af
+     any changes).  */
DistroBaker 6ff1af
+  if (phase == 0)
DistroBaker 6ff1af
+    {
DistroBaker 6ff1af
+      /* handled_strp is set for attributes referring to
DistroBaker 6ff1af
+	 files. If it is set the string is already
DistroBaker 6ff1af
+	 recorded. */
DistroBaker 6ff1af
+      if (! handled_strp)
DistroBaker 6ff1af
+	{
DistroBaker 6ff1af
+	  size_t idx = do_read_32_relocated (ptr);
DistroBaker 6ff1af
+	  record_existing_string_entry_idx (&dso->strings, idx);
DistroBaker 6ff1af
+	}
DistroBaker 6ff1af
+    }
DistroBaker 6ff1af
+  else if (need_strp_update) /* && phase == 1 */
DistroBaker 6ff1af
+    {
DistroBaker 6ff1af
+      struct stridxentry *entry;
DistroBaker 6ff1af
+      size_t idx, new_idx;
DistroBaker 6ff1af
+      idx = do_read_32_relocated (ptr);
DistroBaker 6ff1af
+      entry = string_find_entry (&dso->strings, idx);
DistroBaker 6ff1af
+      new_idx = strent_offset (entry->entry);
DistroBaker 6ff1af
+      do_write_32_relocated (ptr, new_idx);
DistroBaker 6ff1af
+    }
DistroBaker 6ff1af
+
DistroBaker 6ff1af
+  assert (ptr == ptr_orig);
DistroBaker 6ff1af
+}
DistroBaker 6ff1af
+
DistroBaker 6ff1af
+/* Adjust *PTRP after the current *FORMP, update *FORMP for FORM_INDIRECT.  */
DistroBaker 6ff1af
+static enum { FORM_OK, FORM_ERROR, FORM_INDIRECT }
DistroBaker 6ff1af
+skip_form (DSO *dso, uint32_t *formp, unsigned char **ptrp)
DistroBaker 6ff1af
+{
DistroBaker 6ff1af
+  size_t len = 0;
DistroBaker 6ff1af
+
DistroBaker 6ff1af
+  switch (*formp)
DistroBaker 6ff1af
+    {
DistroBaker 6ff1af
+    case DW_FORM_ref_addr:
DistroBaker 6ff1af
+      if (cu_version == 2)
DistroBaker 6ff1af
+	*ptrp += ptr_size;
DistroBaker 6ff1af
+      else
DistroBaker 6ff1af
+	*ptrp += 4;
DistroBaker 6ff1af
+      break;
DistroBaker 6ff1af
+    case DW_FORM_flag_present:
DistroBaker 6ff1af
+      break;
DistroBaker 6ff1af
+    case DW_FORM_addr:
DistroBaker 6ff1af
+      *ptrp += ptr_size;
DistroBaker 6ff1af
+      break;
DistroBaker 6ff1af
+    case DW_FORM_ref1:
DistroBaker 6ff1af
+    case DW_FORM_flag:
DistroBaker 6ff1af
+    case DW_FORM_data1:
DistroBaker 6ff1af
+      ++*ptrp;
DistroBaker 6ff1af
+      break;
DistroBaker 6ff1af
+    case DW_FORM_ref2:
DistroBaker 6ff1af
+    case DW_FORM_data2:
DistroBaker 6ff1af
+      *ptrp += 2;
DistroBaker 6ff1af
+      break;
DistroBaker 6ff1af
+    case DW_FORM_ref4:
DistroBaker 6ff1af
+    case DW_FORM_data4:
DistroBaker 6ff1af
+    case DW_FORM_sec_offset:
DistroBaker 6ff1af
+      *ptrp += 4;
DistroBaker 6ff1af
+      break;
DistroBaker 6ff1af
+    case DW_FORM_ref8:
DistroBaker 6ff1af
+    case DW_FORM_data8:
DistroBaker 6ff1af
+    case DW_FORM_ref_sig8:
DistroBaker 6ff1af
+      *ptrp += 8;
DistroBaker 6ff1af
+      break;
DistroBaker 6ff1af
+    case DW_FORM_sdata:
DistroBaker 6ff1af
+    case DW_FORM_ref_udata:
DistroBaker 6ff1af
+    case DW_FORM_udata:
DistroBaker 6ff1af
+      read_uleb128 (*ptrp);
DistroBaker 6ff1af
+      break;
DistroBaker 6ff1af
+    case DW_FORM_strp:
DistroBaker 6ff1af
+      *ptrp += 4;
DistroBaker 6ff1af
+      break;
DistroBaker 6ff1af
+    case DW_FORM_string:
DistroBaker 6ff1af
+      *ptrp = (unsigned char *) strchr ((char *)*ptrp, '\0') + 1;
DistroBaker 6ff1af
+      break;
DistroBaker 6ff1af
+    case DW_FORM_indirect:
DistroBaker 6ff1af
+      *formp = read_uleb128 (*ptrp);
DistroBaker 6ff1af
+      return FORM_INDIRECT;
DistroBaker 6ff1af
+    case DW_FORM_block1:
DistroBaker 6ff1af
+      len = *(*ptrp)++;
DistroBaker 6ff1af
+      break;
DistroBaker 6ff1af
+    case DW_FORM_block2:
DistroBaker 6ff1af
+      len = read_16 (*ptrp);
DistroBaker 6ff1af
+      *formp = DW_FORM_block1;
DistroBaker 6ff1af
+      break;
DistroBaker 6ff1af
+    case DW_FORM_block4:
DistroBaker 6ff1af
+      len = read_32 (*ptrp);
DistroBaker 6ff1af
+      *formp = DW_FORM_block1;
DistroBaker 6ff1af
+      break;
DistroBaker 6ff1af
+    case DW_FORM_block:
DistroBaker 6ff1af
+    case DW_FORM_exprloc:
DistroBaker 6ff1af
+      len = read_uleb128 (*ptrp);
DistroBaker 6ff1af
+      *formp = DW_FORM_block1;
DistroBaker 6ff1af
+      assert (len < UINT_MAX);
DistroBaker 6ff1af
+      break;
DistroBaker 6ff1af
+    default:
DistroBaker 6ff1af
+      error (0, 0, "%s: Unknown DWARF DW_FORM_%d", dso->filename, *formp);
DistroBaker 6ff1af
+      return FORM_ERROR;
DistroBaker 6ff1af
+    }
DistroBaker 6ff1af
+
DistroBaker 6ff1af
+  if (*formp == DW_FORM_block1)
DistroBaker 6ff1af
+    *ptrp += len;
DistroBaker 6ff1af
+
DistroBaker 6ff1af
+  return FORM_OK;
DistroBaker 6ff1af
+}
DistroBaker 6ff1af
+
DistroBaker 6ff1af
+/* Part of read_dwarf2_line processing DWARF-4.  */
DistroBaker 6ff1af
 static bool
DistroBaker 6ff1af
-read_dwarf2_line (DSO *dso, uint32_t off, char *comp_dir)
DistroBaker 6ff1af
+read_dwarf4_line (DSO *dso, unsigned char *ptr, char *comp_dir,
DistroBaker 6ff1af
+		  struct line_table *table)
DistroBaker 6ff1af
 {
DistroBaker 6ff1af
-  unsigned char *ptr, *dir;
DistroBaker 6ff1af
   unsigned char **dirt;
DistroBaker 6ff1af
   uint32_t value, dirt_cnt;
DistroBaker 6ff1af
   size_t comp_dir_len = !comp_dir ? 0 : strlen (comp_dir);
DistroBaker 6ff1af
-  struct line_table *table;
DistroBaker 6ff1af
-
DistroBaker 6ff1af
-  if (get_line_table (dso, off, &table) == false
DistroBaker 6ff1af
-      || table == NULL)
DistroBaker 6ff1af
-    return false;
DistroBaker 6ff1af
-
DistroBaker 6ff1af
-  /* Skip to the directory table. The rest of the header has already
DistroBaker 6ff1af
-     been read and checked by get_line_table. */
DistroBaker 6ff1af
-  ptr = debug_sections[DEBUG_LINE].data + off;
DistroBaker 6ff1af
-  ptr += (4 /* unit len */
DistroBaker 6ff1af
-	  + 2 /* version */
DistroBaker 6ff1af
-	  + 4 /* header len */
DistroBaker 6ff1af
-	  + 1 /* min instr len */
DistroBaker 6ff1af
-	  + (table->version >= 4) /* max op per instr, if version >= 4 */
DistroBaker 6ff1af
-	  + 1 /* default is stmt */
DistroBaker 6ff1af
-	  + 1 /* line base */
DistroBaker 6ff1af
-	  + 1 /* line range */
DistroBaker 6ff1af
-	  + 1 /* opcode base */
DistroBaker 6ff1af
-	  + table->opcode_base - 1); /* opcode len table */
DistroBaker 6ff1af
-  dir = ptr;
DistroBaker 6ff1af
+  unsigned char *dir = ptr;
DistroBaker 6ff1af
 
DistroBaker 6ff1af
   /* dir table: */
DistroBaker 6ff1af
   value = 1;
DistroBaker 6ff1af
@@ -1620,6 +1711,40 @@ read_dwarf2_line (DSO *dso, uint32_t off, char *comp_dir)
DistroBaker 6ff1af
       read_uleb128 (ptr);
DistroBaker 6ff1af
     }
DistroBaker 6ff1af
 
DistroBaker 6ff1af
+  return true;
DistroBaker 6ff1af
+}
DistroBaker 6ff1af
+
DistroBaker 6ff1af
+/* Called during phase zero for each debug_line table referenced from
DistroBaker 6ff1af
+   .debug_info.  Outputs all source files seen and records any
DistroBaker 6ff1af
+   adjustments needed in the debug_list data structures. Returns true
DistroBaker 6ff1af
+   if line_table needs to be rewrite either the dir or file paths. */
DistroBaker 6ff1af
+static bool
DistroBaker 6ff1af
+read_dwarf2_line (DSO *dso, uint32_t off, char *comp_dir)
DistroBaker 6ff1af
+{
DistroBaker 6ff1af
+  unsigned char *ptr;
DistroBaker 6ff1af
+  struct line_table *table;
DistroBaker 6ff1af
+
DistroBaker 6ff1af
+  if (get_line_table (dso, off, &table) == false
DistroBaker 6ff1af
+      || table == NULL)
DistroBaker 6ff1af
+    return false;
DistroBaker 6ff1af
+
DistroBaker 6ff1af
+  /* Skip to the directory table. The rest of the header has already
DistroBaker 6ff1af
+     been read and checked by get_line_table. */
DistroBaker 6ff1af
+  ptr = debug_sections[DEBUG_LINE].data + off;
DistroBaker 6ff1af
+  ptr += (4 /* unit len */
DistroBaker 6ff1af
+	  + 2 /* version */
DistroBaker 6ff1af
+	  + 4 /* header len */
DistroBaker 6ff1af
+	  + 1 /* min instr len */
DistroBaker 6ff1af
+	  + (table->version >= 4) /* max op per instr, if version >= 4 */
DistroBaker 6ff1af
+	  + 1 /* default is stmt */
DistroBaker 6ff1af
+	  + 1 /* line base */
DistroBaker 6ff1af
+	  + 1 /* line range */
DistroBaker 6ff1af
+	  + 1 /* opcode base */
DistroBaker 6ff1af
+	  + table->opcode_base - 1); /* opcode len table */
DistroBaker 6ff1af
+
DistroBaker 6ff1af
+  if (! read_dwarf4_line (dso, ptr, comp_dir, table))
DistroBaker 6ff1af
+   return false;
DistroBaker 6ff1af
+
DistroBaker 6ff1af
   dso->lines.debug_lines_len += 4 + table->unit_length + table->size_diff;
DistroBaker 6ff1af
   return table->replace_dirs || table->replace_files;
DistroBaker 6ff1af
 }
DistroBaker 6ff1af
@@ -1637,6 +1762,33 @@ find_new_list_offs (struct debug_lines *lines, size_t idx)
DistroBaker 6ff1af
   return table->new_idx;
DistroBaker 6ff1af
 }
DistroBaker 6ff1af
 
DistroBaker 6ff1af
+/* Read DW_FORM_strp collecting compilation directory.  */
DistroBaker 6ff1af
+static void
DistroBaker 6ff1af
+edit_attributes_str_comp_dir (DSO *dso, unsigned char **ptrp, int phase,
DistroBaker 6ff1af
+			      char **comp_dirp, bool *handled_strpp)
DistroBaker 6ff1af
+{
DistroBaker 6ff1af
+  const char *dir;
DistroBaker 6ff1af
+  size_t idx = do_read_32_relocated (*ptrp);
DistroBaker 6ff1af
+  /* In phase zero we collect the comp_dir.  */
DistroBaker 6ff1af
+  if (phase == 0)
DistroBaker 6ff1af
+    {
DistroBaker 6ff1af
+      if (idx >= debug_sections[DEBUG_STR].size)
DistroBaker 6ff1af
+	error (1, 0, "%s: Bad string pointer index %zd for comp_dir",
DistroBaker 6ff1af
+	       dso->filename, idx);
DistroBaker 6ff1af
+      dir = (char *) debug_sections[DEBUG_STR].data + idx;
DistroBaker 6ff1af
+
DistroBaker 6ff1af
+      free (*comp_dirp);
DistroBaker 6ff1af
+      *comp_dirp = strdup (dir);
DistroBaker 6ff1af
+    }
DistroBaker 6ff1af
+
DistroBaker 6ff1af
+  if (dest_dir != NULL && phase == 0)
DistroBaker 6ff1af
+    {
DistroBaker 6ff1af
+      if (record_file_string_entry_idx (&dso->strings, idx))
DistroBaker 6ff1af
+	need_strp_update = true;
DistroBaker 6ff1af
+      *handled_strpp = true;
DistroBaker 6ff1af
+    }
DistroBaker 6ff1af
+}
DistroBaker 6ff1af
+
DistroBaker 6ff1af
 /* This scans the attributes of one DIE described by the given abbrev_tag.
DistroBaker 6ff1af
    PTR points to the data in the debug_info. It will be advanced till all
DistroBaker 6ff1af
    abbrev data is consumed. In phase zero data is collected, in phase one
DistroBaker 6ff1af
@@ -1655,7 +1807,6 @@ edit_attributes (DSO *dso, unsigned char *ptr, struct abbrev_tag *t, int phase)
DistroBaker 6ff1af
   for (i = 0; i < t->nattr; ++i)
DistroBaker 6ff1af
     {
DistroBaker 6ff1af
       uint32_t form = t->attr[i].form;
DistroBaker 6ff1af
-      size_t len = 0;
DistroBaker 6ff1af
       while (1)
DistroBaker 6ff1af
 	{
DistroBaker 6ff1af
 	  /* Whether we already handled a string as file for this
DistroBaker 6ff1af
@@ -1743,29 +1894,8 @@ edit_attributes (DSO *dso, unsigned char *ptr, struct abbrev_tag *t, int phase)
DistroBaker 6ff1af
 		}
DistroBaker 6ff1af
 	      else if (form == DW_FORM_strp &&
DistroBaker 6ff1af
 		       debug_sections[DEBUG_STR].data)
DistroBaker 6ff1af
-		{
DistroBaker 6ff1af
-		  const char *dir;
DistroBaker 6ff1af
-		  size_t idx = do_read_32_relocated (ptr);
DistroBaker 6ff1af
-		  /* In phase zero we collect the comp_dir.  */
DistroBaker 6ff1af
-		  if (phase == 0)
DistroBaker 6ff1af
-		    {
DistroBaker 6ff1af
-		      if (idx >= debug_sections[DEBUG_STR].size)
DistroBaker 6ff1af
-			error (1, 0,
DistroBaker 6ff1af
-			       "%s: Bad string pointer index %zd for comp_dir",
DistroBaker 6ff1af
-			       dso->filename, idx);
DistroBaker 6ff1af
-		      dir = (char *) debug_sections[DEBUG_STR].data + idx;
DistroBaker 6ff1af
-
DistroBaker 6ff1af
-		      free (comp_dir);
DistroBaker 6ff1af
-		      comp_dir = strdup (dir);
DistroBaker 6ff1af
-		    }
DistroBaker 6ff1af
-
DistroBaker 6ff1af
-		  if (dest_dir != NULL && phase == 0)
DistroBaker 6ff1af
-		    {
DistroBaker 6ff1af
-		      if (record_file_string_entry_idx (&dso->strings, idx))
DistroBaker 6ff1af
-			need_strp_update = true;
DistroBaker 6ff1af
-		      handled_strp = true;
DistroBaker 6ff1af
-		    }
DistroBaker 6ff1af
-		}
DistroBaker 6ff1af
+		edit_attributes_str_comp_dir (dso, &ptr, phase, &comp_dir,
DistroBaker 6ff1af
+					      &handled_strp);
DistroBaker 6ff1af
 	    }
DistroBaker 6ff1af
 	  else if ((t->tag == DW_TAG_compile_unit
DistroBaker 6ff1af
 		    || t->tag == DW_TAG_partial_unit)
DistroBaker 6ff1af
@@ -1815,99 +1945,21 @@ edit_attributes (DSO *dso, unsigned char *ptr, struct abbrev_tag *t, int phase)
DistroBaker 6ff1af
 
DistroBaker 6ff1af
 	  switch (form)
DistroBaker 6ff1af
 	    {
DistroBaker 6ff1af
-	    case DW_FORM_ref_addr:
DistroBaker 6ff1af
-	      if (cu_version == 2)
DistroBaker 6ff1af
-		ptr += ptr_size;
DistroBaker 6ff1af
-	      else
DistroBaker 6ff1af
-		ptr += 4;
DistroBaker 6ff1af
-	      break;
DistroBaker 6ff1af
-	    case DW_FORM_flag_present:
DistroBaker 6ff1af
-	      break;
DistroBaker 6ff1af
-	    case DW_FORM_addr:
DistroBaker 6ff1af
-	      ptr += ptr_size;
DistroBaker 6ff1af
-	      break;
DistroBaker 6ff1af
-	    case DW_FORM_ref1:
DistroBaker 6ff1af
-	    case DW_FORM_flag:
DistroBaker 6ff1af
-	    case DW_FORM_data1:
DistroBaker 6ff1af
-	      ++ptr;
DistroBaker 6ff1af
-	      break;
DistroBaker 6ff1af
-	    case DW_FORM_ref2:
DistroBaker 6ff1af
-	    case DW_FORM_data2:
DistroBaker 6ff1af
-	      ptr += 2;
DistroBaker 6ff1af
-	      break;
DistroBaker 6ff1af
-	    case DW_FORM_ref4:
DistroBaker 6ff1af
-	    case DW_FORM_data4:
DistroBaker 6ff1af
-	    case DW_FORM_sec_offset:
DistroBaker 6ff1af
-	      ptr += 4;
DistroBaker 6ff1af
-	      break;
DistroBaker 6ff1af
-	    case DW_FORM_ref8:
DistroBaker 6ff1af
-	    case DW_FORM_data8:
DistroBaker 6ff1af
-	    case DW_FORM_ref_sig8:
DistroBaker 6ff1af
-	      ptr += 8;
DistroBaker 6ff1af
-	      break;
DistroBaker 6ff1af
-	    case DW_FORM_sdata:
DistroBaker 6ff1af
-	    case DW_FORM_ref_udata:
DistroBaker 6ff1af
-	    case DW_FORM_udata:
DistroBaker 6ff1af
-	      read_uleb128 (ptr);
DistroBaker 6ff1af
-	      break;
DistroBaker 6ff1af
 	    case DW_FORM_strp:
DistroBaker 6ff1af
-	      /* In the first pass we collect all strings, in the
DistroBaker 6ff1af
-		 second we put the new references back (if there are
DistroBaker 6ff1af
-		 any changes).  */
DistroBaker 6ff1af
-	      if (phase == 0)
DistroBaker 6ff1af
-		{
DistroBaker 6ff1af
-		  /* handled_strp is set for attributes referring to
DistroBaker 6ff1af
-		     files. If it is set the string is already
DistroBaker 6ff1af
-		     recorded. */
DistroBaker 6ff1af
-		  if (! handled_strp)
DistroBaker 6ff1af
-		    {
DistroBaker 6ff1af
-		      size_t idx = do_read_32_relocated (ptr);
DistroBaker 6ff1af
-		      record_existing_string_entry_idx (&dso->strings, idx);
DistroBaker 6ff1af
-		    }
DistroBaker 6ff1af
-		}
DistroBaker 6ff1af
-	      else if (need_strp_update) /* && phase == 1 */
DistroBaker 6ff1af
-		{
DistroBaker 6ff1af
-		  struct stridxentry *entry;
DistroBaker 6ff1af
-		  size_t idx, new_idx;
DistroBaker 6ff1af
-		  idx = do_read_32_relocated (ptr);
DistroBaker 6ff1af
-		  entry = string_find_entry (&dso->strings, idx);
DistroBaker 6ff1af
-		  new_idx = strent_offset (entry->entry);
DistroBaker 6ff1af
-		  do_write_32_relocated (ptr, new_idx);
DistroBaker 6ff1af
-		}
DistroBaker 6ff1af
-	      ptr += 4;
DistroBaker 6ff1af
-	      break;
DistroBaker 6ff1af
-	    case DW_FORM_string:
DistroBaker 6ff1af
-	      ptr = (unsigned char *) strchr ((char *)ptr, '\0') + 1;
DistroBaker 6ff1af
-	      break;
DistroBaker 6ff1af
-	    case DW_FORM_indirect:
DistroBaker 6ff1af
-	      form = read_uleb128 (ptr);
DistroBaker 6ff1af
-	      continue;
DistroBaker 6ff1af
-	    case DW_FORM_block1:
DistroBaker 6ff1af
-	      len = *ptr++;
DistroBaker 6ff1af
-	      break;
DistroBaker 6ff1af
-	    case DW_FORM_block2:
DistroBaker 6ff1af
-	      len = read_16 (ptr);
DistroBaker 6ff1af
-	      form = DW_FORM_block1;
DistroBaker 6ff1af
+	      edit_strp (dso, ptr, phase, handled_strp);
DistroBaker 6ff1af
 	      break;
DistroBaker 6ff1af
-	    case DW_FORM_block4:
DistroBaker 6ff1af
-	      len = read_32 (ptr);
DistroBaker 6ff1af
-	      form = DW_FORM_block1;
DistroBaker 6ff1af
-	      break;
DistroBaker 6ff1af
-	    case DW_FORM_block:
DistroBaker 6ff1af
-	    case DW_FORM_exprloc:
DistroBaker 6ff1af
-	      len = read_uleb128 (ptr);
DistroBaker 6ff1af
-	      form = DW_FORM_block1;
DistroBaker 6ff1af
-	      assert (len < UINT_MAX);
DistroBaker 6ff1af
+	    }
DistroBaker 6ff1af
+
DistroBaker 6ff1af
+	  switch (skip_form (dso, &form, &ptr))
DistroBaker 6ff1af
+	    {
DistroBaker 6ff1af
+	    case FORM_OK:
DistroBaker 6ff1af
 	      break;
DistroBaker 6ff1af
-	    default:
DistroBaker 6ff1af
-	      error (0, 0, "%s: Unknown DWARF DW_FORM_%d", dso->filename,
DistroBaker 6ff1af
-		     form);
DistroBaker 6ff1af
+	    case FORM_ERROR:
DistroBaker 6ff1af
 	      return NULL;
DistroBaker 6ff1af
+	    case FORM_INDIRECT:
DistroBaker 6ff1af
+	      continue;
DistroBaker 6ff1af
 	    }
DistroBaker 6ff1af
 
DistroBaker 6ff1af
-	  if (form == DW_FORM_block1)
DistroBaker 6ff1af
-	    ptr += len;
DistroBaker 6ff1af
-
DistroBaker 6ff1af
 	  break;
DistroBaker 6ff1af
 	}
DistroBaker 6ff1af
     }
DistroBaker 6ff1af
@@ -2068,6 +2120,28 @@ edit_info (DSO *dso, int phase, struct debug_section *sec)
DistroBaker 6ff1af
   return 0;
DistroBaker 6ff1af
 }
DistroBaker 6ff1af
 
DistroBaker 6ff1af
+/* Rebuild .debug_str.  */
DistroBaker 6ff1af
+static void
DistroBaker 6ff1af
+edit_dwarf2_any_str (DSO *dso)
DistroBaker 6ff1af
+{
DistroBaker 6ff1af
+  Strtab *strtab = dso->strings.str_tab;
DistroBaker 6ff1af
+  Elf_Data *strdata = debug_sections[DEBUG_STR].elf_data;
DistroBaker 6ff1af
+  int strndx = debug_sections[DEBUG_STR].sec;
DistroBaker 6ff1af
+  Elf_Scn *strscn = dso->scn[strndx];
DistroBaker 6ff1af
+
DistroBaker 6ff1af
+  /* Out with the old. */
DistroBaker 6ff1af
+  strdata->d_size = 0;
DistroBaker 6ff1af
+  /* In with the new. */
DistroBaker 6ff1af
+  strdata = elf_newdata (strscn);
DistroBaker 6ff1af
+
DistroBaker 6ff1af
+  /* We really should check whether we had enough memory,
DistroBaker 6ff1af
+     but the old ebl version will just abort on out of
DistroBaker 6ff1af
+     memory... */
DistroBaker 6ff1af
+  strtab_finalize (strtab, strdata);
DistroBaker 6ff1af
+  debug_sections[DEBUG_STR].size = strdata->d_size;
DistroBaker 6ff1af
+  dso->strings.str_buf = strdata->d_buf;
DistroBaker 6ff1af
+}
DistroBaker 6ff1af
+
DistroBaker 6ff1af
 static int
DistroBaker 6ff1af
 edit_dwarf2 (DSO *dso)
DistroBaker 6ff1af
 {
DistroBaker 6ff1af
@@ -2466,24 +2540,7 @@ edit_dwarf2 (DSO *dso)
DistroBaker 6ff1af
 	 in place for phase 1 updating of debug_info
DistroBaker 6ff1af
 	 references. */
DistroBaker 6ff1af
       if (phase == 0 && need_strp_update)
DistroBaker 6ff1af
-	{
DistroBaker 6ff1af
-	  Strtab *strtab = dso->strings.str_tab;
DistroBaker 6ff1af
-	  Elf_Data *strdata = debug_sections[DEBUG_STR].elf_data;
DistroBaker 6ff1af
-	  int strndx = debug_sections[DEBUG_STR].sec;
DistroBaker 6ff1af
-	  Elf_Scn *strscn = dso->scn[strndx];
DistroBaker 6ff1af
-
DistroBaker 6ff1af
-	  /* Out with the old. */
DistroBaker 6ff1af
-	  strdata->d_size = 0;
DistroBaker 6ff1af
-	  /* In with the new. */
DistroBaker 6ff1af
-	  strdata = elf_newdata (strscn);
DistroBaker 6ff1af
-
DistroBaker 6ff1af
-	  /* We really should check whether we had enough memory,
DistroBaker 6ff1af
-	     but the old ebl version will just abort on out of
DistroBaker 6ff1af
-	     memory... */
DistroBaker 6ff1af
-	  strtab_finalize (strtab, strdata);
DistroBaker 6ff1af
-	  debug_sections[DEBUG_STR].size = strdata->d_size;
DistroBaker 6ff1af
-	  dso->strings.str_buf = strdata->d_buf;
DistroBaker 6ff1af
-	}
DistroBaker 6ff1af
+	edit_dwarf2_any_str (dso);
DistroBaker 6ff1af
 
DistroBaker 6ff1af
     }
DistroBaker 6ff1af
 
DistroBaker 6ff1af
-- 
DistroBaker 6ff1af
2.18.4
DistroBaker 6ff1af