Blob Blame History Raw
--- ./tools/debugedit.c.orig	2017-12-15 12:17:02.564975374 +0000
+++ ./tools/debugedit.c	2017-12-15 12:17:29.058901941 +0000
@@ -71,6 +71,14 @@
 #define DW_FORM_ref_udata	0x15
 #define DW_FORM_indirect	0x16
 
+#define DW_MACRO_GNU_define	1
+#define DW_MACRO_GNU_undef	2
+#define DW_MACRO_GNU_start_file	3
+#define DW_MACRO_GNU_end_file	4
+#define DW_MACRO_GNU_define_indirect 5
+#define DW_MACRO_GNU_undef_indirect 6
+#define DW_MACRO_GNU_transparent_include 7
+
 /* Unfortunately strtab manipulation functions were only officially added
    to elfutils libdw in 0.167.  Before that there were internal unsupported
    ebl variants.  While libebl.h isn't supported we'll try to use it anyway
@@ -2209,6 +2217,67 @@ edit_dwarf2 (DSO *dso)
 		}
 	    }
 
+	  /* the macro section also contains offsets into the str section,
+	   * so we need to update those as well if we update the strings
+	   */
+	  if (need_strp_update && debug_sections[DEBUG_MACRO].data)
+	    {
+	      ptr = debug_sections[DEBUG_MACRO].data;
+	      endsec = ptr + debug_sections[DEBUG_MACRO].size;
+	      int op = 0, macro_version, macro_flags;
+	      
+	      while (ptr < endsec)
+		{
+		  if (!op)
+		    {
+		      macro_version = read_16 (ptr);
+		      macro_flags = read_8 (ptr);
+		      if (macro_version != 4 || (macro_flags & ~2) != 0)
+			error (1, 0, "unhandled .debug_macro version/flags");
+		      if ((macro_flags & 2) != 0)
+			ptr += 4;
+		    }
+		  op = read_8 (ptr);
+		  if (!op)
+		    continue;
+		  switch(op)
+		    {
+		    case DW_MACRO_GNU_define:
+		    case DW_MACRO_GNU_undef:
+		      read_uleb128 (ptr);
+		      ptr = (unsigned char *) strchr ((char *) ptr, '\0') + 1;
+		      break;
+		    case DW_MACRO_GNU_start_file:
+		      read_uleb128 (ptr);
+		      read_uleb128 (ptr);
+		      break;
+		    case DW_MACRO_GNU_define_indirect:
+		    case DW_MACRO_GNU_undef_indirect:
+		      read_uleb128 (ptr);
+		      if (phase == 0)
+			{
+			  size_t idx = read_32 (ptr);
+			  record_existing_string_entry_idx (&dso->strings, idx);
+			}
+		      else
+			{
+			  struct stridxentry *entry;
+			  size_t idx, new_idx;
+			  idx = do_read_32 (ptr);
+			  entry = string_find_entry (&dso->strings, idx);
+			  new_idx = strent_offset (entry->entry);
+			  write_32 (ptr, new_idx);
+			}
+		      break;
+		    case DW_MACRO_GNU_transparent_include:
+		      ptr += 4;
+		      break;
+		    default:
+		      break;
+		    }
+		}
+	    }
+
 	  /* Same for the debug_str section. Make sure everything is
 	     in place for phase 1 updating of debug_info
 	     references. */
@@ -2238,6 +2307,8 @@ edit_dwarf2 (DSO *dso)
 	 new strp, strings and/or linep offsets.  */
       if (need_strp_update || need_string_replacement || need_stmt_update)
 	dirty_section (DEBUG_INFO);
+      if (need_strp_update)
+	dirty_section (DEBUG_MACRO);
 
       /* Update any debug_info relocations addends we might have touched. */
       if (relbuf != NULL && reltype == SHT_RELA)