Debug info path remapping

Joseph S. Myers joseph@codesourcery.com
Thu Jul 5 01:03:00 GMT 2007


These GCC and GAS patches add compiler and assembler support for
remapping paths when generating debug information, as discussed in
<http://gcc.gnu.org/ml/gcc-patches/2006-10/msg00064.html> and thread.
This allows you to generate objects whose debug information references
a canonical location for source files, without the limitations of
postprocessing the objects (on lengths of paths involved etc.).

A GCC option -fdebug-prefix-map=OLD=NEW, a GAS option
--debug-prefix-map OLD=NEW, and a configure option
--with-debug-prefix-map="OLD1=NEW1 OLD2=NEW2 ..." are added.  The
configure option causes the -fdebug-prefix-map options to be passed
when building GCC's runtime libraries; when applied to src, it has the
same effect for building newlib.  GCC passes --debug-prefix-map to the
assembler if support was available at configure time.

The change to dwarf2out.c:file_table_relative_p deals with the case
where you compile a source file from an absolute path but with a
relative -I option; at the point dwarf2out_finish checks whether
DW_AT_comp_dir is needed, d->emitted_number is 0 and it only becomes 1
later.  This is needed to have correct debug information from which
the relocated paths to all source files can be found.

Tested with no regressions on i686-pc-linux-gnu.  OK to commit?

(For the GAS patch, see below the GCC one.)

2007-07-04  Paul Brook  <paul@codesourcery.com>
            Joseph Myers  <joseph@codesourcery.com>

	* Makefile.tpl (DEBUG_PREFIX_CFLAGS_FOR_TARGET): New.
	(CFLAGS_FOR_TARGET, CXXFLAGS_FOR_TARGET): Include it.
	* Makefile.in: Regenerate.
	* configure.ac (--with-debug-prefix-map): New.
	* configure: Regenerate.

config:
2007-07-04  Paul Brook  <paul@codesourcery.com>
            Joseph Myers  <joseph@codesourcery.com>

	* mt-gnu (CXXFLAGS_FOR_TARGET): Add
	$(DEBUG_PREFIX_CFLAGS_FOR_TARGET).

gcc:
2007-07-04  Paul Brook  <paul@codesourcery.com>
            Joseph Myers  <joseph@codesourcery.com>

	* common.opt (-fdebug-prefix-map=): New option.
	* opts.c: Include debug.h.
	(common_handle_option): Handle -fdebug-prefix-map.
	* final.c: Include ggc.h.
	(struct debug_prefix_map, debug_prefix_maps, add_debug_prefix_map,
	remap_debug_filename): New.
	* Makefile.in (final.o, opts.o): Update dependencies.
	* debug.h (remap_debug_filename, add_debug_prefix_map): Declare.
	* configure.ac: Check for assembler --debug-prefix-map support.
	* configure, config.in: Regenerate.
	* gcc.c (ASM_MAP): Define conditional on HAVE_AS_DEBUG_PREFIX_MAP.
	(ASM_DEBUG_SPEC): Include ASM_MAP.
	* doc/install.texi (--with-debug-prefix-map): Document.
	* doc/invoke.texi (-fdebug-prefix-map): Document.
	* dbxout.c (dbxout_init, dbxout_start_source_file,
	dbxout_source_file): Call remap_debug_filename.
	* dwarf2out.c (add_comp_dir_attribute, maybe_emit_file,
	dwarf2out_start_source_file, dwarf2out_finish): Call
	remap_debug_filename.
	(file_table_relative_p): Do not check d->emitted_number.
	* toplev.c (output_file_directive): Call remap_debug_filename.
	* vmsdbgout.c (write_srccorr): Call remap_debug_filename.
	* xcoffout.c (xcoffout_source_file): Call remap_debug_filename.

Index: gcc/doc/invoke.texi
===================================================================
--- gcc/doc/invoke.texi	(revision 126328)
+++ gcc/doc/invoke.texi	(working copy)
@@ -303,6 +303,7 @@
 -ftest-coverage  -ftime-report -fvar-tracking @gol
 -g  -g@var{level}  -gcoff -gdwarf-2 @gol
 -ggdb  -gstabs  -gstabs+  -gvms  -gxcoff  -gxcoff+ @gol
+-fdebug-prefix-map=@var{old}=@var{new} @gol
 -femit-struct-debug-baseonly -femit-struct-debug-reduced @gol
 -femit-struct-debug-detailed@r{[}=@var{spec-list}@r{]} @gol
 -p  -pg  -print-file-name=@var{library}  -print-libgcc-file-name @gol
@@ -4133,6 +4134,11 @@
 
 This option works only with DWARF 2.
 
+@item -fdebug-prefix-map=@var{old}=@var{new}
+@opindex fdebug-prefix-map
+When compiling files in directory @file{@var{old}}, record debugging
+information describing them as in @file{@var{new}} instead.
+
 @cindex @command{prof}
 @item -p
 @opindex p
Index: gcc/doc/install.texi
===================================================================
--- gcc/doc/install.texi	(revision 126328)
+++ gcc/doc/install.texi	(working copy)
@@ -1345,6 +1345,11 @@
 shorthand assumptions are not correct, you can use the explicit
 include and lib options directly.
 
+@item --with-debug-prefix-map=@var{map}
+Convert source directory names using @option{-fdebug-prefix-map} when
+building runtime libraries.  @samp{@var{map}} is a space-separated
+list of maps of the form @samp{@var{old}=@var{new}}.
+
 @end table
 
 @subheading Cross-Compiler-Specific Options
Index: gcc/final.c
===================================================================
--- gcc/final.c	(revision 126328)
+++ gcc/final.c	(working copy)
@@ -78,6 +78,7 @@
 #include "coverage.h"
 #include "df.h"
 #include "vecprim.h"
+#include "ggc.h"
 
 #ifdef XCOFF_DEBUGGING_INFO
 #include "xcoffout.h"		/* Needed for external data
@@ -1351,6 +1352,72 @@
 }
 #endif
 
+/* ??? This is probably the wrong place for these.  */
+/* Structure recording the mapping from source file and directory
+   names at compile time to those to be embedded in debug
+   information.  */
+typedef struct debug_prefix_map
+{
+  const char *old_prefix;
+  const char *new_prefix;
+  size_t old_len;
+  size_t new_len;
+  struct debug_prefix_map *next;
+} debug_prefix_map;
+
+/* Linked list of such structures.  */
+debug_prefix_map *debug_prefix_maps;
+
+
+/* Record a debug file prefix mapping.  ARG is the argument to
+   -fdebug-prefix-map and must be of the form OLD=NEW.  */
+
+void
+add_debug_prefix_map (const char *arg)
+{
+  debug_prefix_map *map;
+  const char *p;
+
+  p = strchr (arg, '=');
+  if (!p)
+    {
+      error ("invalid argument %qs to -fdebug-prefix-map", arg);
+      return;
+    }
+  map = XNEW (debug_prefix_map);
+  map->old_prefix = ggc_alloc_string (arg, p - arg);
+  map->old_len = p - arg;
+  p++;
+  map->new_prefix = ggc_strdup (p);
+  map->new_len = strlen (p);
+  map->next = debug_prefix_maps;
+  debug_prefix_maps = map;
+}
+
+/* Perform user-specified mapping of debug filename prefixes.  Return
+   the new name corresponding to FILENAME.  */
+
+const char *
+remap_debug_filename (const char *filename)
+{
+  debug_prefix_map *map;
+  char *s;
+  const char *name;
+  size_t name_len;
+
+  for (map = debug_prefix_maps; map; map = map->next)
+    if (strncmp (filename, map->old_prefix, map->old_len) == 0)
+      break;
+  if (!map)
+    return filename;
+  name = filename + map->old_len;
+  name_len = strlen (name) + 1;
+  s = (char *) alloca (name_len + map->new_len);
+  memcpy (s, map->new_prefix, map->new_len);
+  memcpy (s + map->new_len, name, name_len);
+  return ggc_strdup (s);
+}
+
 /* Output assembler code for the start of a function,
    and initialize some of the variables in this file
    for the new function.  The label for the function and associated
Index: gcc/gcc.c
===================================================================
--- gcc/gcc.c	(revision 126328)
+++ gcc/gcc.c	(working copy)
@@ -656,21 +656,27 @@
 #define LINKER_NAME "collect2"
 #endif
 
+#ifdef HAVE_AS_DEBUG_PREFIX_MAP
+#define ASM_MAP " %{fdebug-prefix-map=*:--debug-prefix-map %*}"
+#else
+#define ASM_MAP ""
+#endif
+
 /* Define ASM_DEBUG_SPEC to be a spec suitable for translating '-g'
    to the assembler.  */
 #ifndef ASM_DEBUG_SPEC
 # if defined(DBX_DEBUGGING_INFO) && defined(DWARF2_DEBUGGING_INFO) \
      && defined(HAVE_AS_GDWARF2_DEBUG_FLAG) && defined(HAVE_AS_GSTABS_DEBUG_FLAG)
-#  define ASM_DEBUG_SPEC					\
-      (PREFERRED_DEBUGGING_TYPE == DBX_DEBUG			\
-       ? "%{gdwarf-2*:--gdwarf2}%{!gdwarf-2*:%{g*:--gstabs}}"	\
-       : "%{gstabs*:--gstabs}%{!gstabs*:%{g*:--gdwarf2}}")
+#  define ASM_DEBUG_SPEC						\
+      (PREFERRED_DEBUGGING_TYPE == DBX_DEBUG				\
+       ? "%{gdwarf-2*:--gdwarf2}%{!gdwarf-2*:%{g*:--gstabs}}" ASM_MAP	\
+       : "%{gstabs*:--gstabs}%{!gstabs*:%{g*:--gdwarf2}}" ASM_MAP)
 # else
 #  if defined(DBX_DEBUGGING_INFO) && defined(HAVE_AS_GSTABS_DEBUG_FLAG)
-#   define ASM_DEBUG_SPEC "%{g*:--gstabs}"
+#   define ASM_DEBUG_SPEC "%{g*:--gstabs}" ASM_MAP
 #  endif
 #  if defined(DWARF2_DEBUGGING_INFO) && defined(HAVE_AS_GDWARF2_DEBUG_FLAG)
-#   define ASM_DEBUG_SPEC "%{g*:--gdwarf2}"
+#   define ASM_DEBUG_SPEC "%{g*:--gdwarf2}" ASM_MAP
 #  endif
 # endif
 #endif
Index: gcc/toplev.c
===================================================================
--- gcc/toplev.c	(revision 126328)
+++ gcc/toplev.c	(working copy)
@@ -702,6 +702,8 @@
 
   if (input_name == NULL)
     input_name = "<stdin>";
+  else
+    input_name = remap_debug_filename (input_name);
 
   len = strlen (input_name);
   na = input_name + len;
Index: gcc/vmsdbgout.c
===================================================================
--- gcc/vmsdbgout.c	(revision 126328)
+++ gcc/vmsdbgout.c	(working copy)
@@ -1150,7 +1150,8 @@
     (src_command.dst_a_src_cmd_fields.dst_a_src_decl_src.dst_b_src_df_filename,
      "source_corr (filename length)", dosizeonly);
 
-  totsize += write_debug_string (file_info_entry.file_name,
+  totsize += write_debug_string (remap_debug_filename (
+				    file_info_entry.file_name),
 				 "source file name", dosizeonly);
   totsize += write_debug_data1 (src_cmdtrlr.dst_b_src_df_libmodname,
 				"source_corr (libmodname)", dosizeonly);
Index: gcc/debug.h
===================================================================
--- gcc/debug.h	(revision 126328)
+++ gcc/debug.h	(working copy)
@@ -167,4 +167,7 @@
 extern int debug_nesting;
 extern int symbol_queue_index;
 
+const char *remap_debug_filename (const char *);
+void add_debug_prefix_map (const char *);
+
 #endif /* !GCC_DEBUG_H  */
Index: gcc/dbxout.c
===================================================================
--- gcc/dbxout.c	(revision 126328)
+++ gcc/dbxout.c	(working copy)
@@ -984,6 +984,7 @@
   char ltext_label_name[100];
   bool used_ltext_label_name = false;
   tree syms = lang_hooks.decls.getdecls ();
+  const char *mapped_name;
 
   typevec_len = 100;
   typevec = ggc_calloc (typevec_len, sizeof typevec[0]);
@@ -1009,6 +1010,7 @@
 	    cwd = "/";
 	  else if (!IS_DIR_SEPARATOR (cwd[strlen (cwd) - 1]))
 	    cwd = concat (cwd, "/", NULL);
+	  cwd = remap_debug_filename (cwd);
 	}
 #ifdef DBX_OUTPUT_MAIN_SOURCE_DIRECTORY
       DBX_OUTPUT_MAIN_SOURCE_DIRECTORY (asm_out_file, cwd);
@@ -1019,10 +1021,11 @@
 #endif /* no DBX_OUTPUT_MAIN_SOURCE_DIRECTORY */
     }
 
+  mapped_name = remap_debug_filename (input_file_name);
 #ifdef DBX_OUTPUT_MAIN_SOURCE_FILENAME
-  DBX_OUTPUT_MAIN_SOURCE_FILENAME (asm_out_file, input_file_name);
+  DBX_OUTPUT_MAIN_SOURCE_FILENAME (asm_out_file, mapped_name);
 #else
-  dbxout_begin_simple_stabs_desc (input_file_name, N_SO, get_lang_number ());
+  dbxout_begin_simple_stabs_desc (mapped_name, N_SO, get_lang_number ());
   dbxout_stab_value_label (ltext_label_name);
   used_ltext_label_name = true;
 #endif
@@ -1164,7 +1167,7 @@
   n->prev = NULL;
   current_file->prev = n;
   n->bincl_status = BINCL_PENDING;
-  n->pending_bincl_name = filename;
+  n->pending_bincl_name = remap_debug_filename (filename);
   pending_bincls = 1;
   current_file = n;
 #endif
@@ -1230,7 +1233,7 @@
       if (current_function_decl == NULL_TREE)
 	switch_to_section (text_section);
 
-      dbxout_begin_simple_stabs (filename, N_SOL);
+      dbxout_begin_simple_stabs (remap_debug_filename (filename), N_SOL);
       dbxout_stab_value_internal_label ("Ltext", &source_label_number);
       lastfile = filename;
     }
Index: gcc/xcoffout.c
===================================================================
--- gcc/xcoffout.c	(revision 126328)
+++ gcc/xcoffout.c	(working copy)
@@ -301,7 +301,8 @@
       if (xcoff_current_include_file)
 	{
 	  fprintf (file, "\t.ei\t");
-	  output_quoted_string (file, xcoff_current_include_file);
+	  output_quoted_string (file,
+	      remap_debug_filename (xcoff_current_include_file));
 	  fprintf (file, "\n");
 	  xcoff_current_include_file = NULL;
 	}
@@ -309,7 +310,7 @@
       if (strcmp (main_input_filename, filename) || inline_p)
 	{
 	  fprintf (file, "\t.bi\t");
-	  output_quoted_string (file, filename);
+	  output_quoted_string (file, remap_debug_filename (filename));
 	  fprintf (file, "\n");
 	  xcoff_current_include_file = filename;
 	}
Index: gcc/dwarf2out.c
===================================================================
--- gcc/dwarf2out.c	(revision 126328)
+++ gcc/dwarf2out.c	(working copy)
@@ -10734,7 +10734,7 @@
 {
   const char *wd = get_src_pwd ();
   if (wd != NULL)
-    add_AT_string (die, DW_AT_comp_dir, wd);
+    add_AT_string (die, DW_AT_comp_dir, remap_debug_filename (wd));
 }
 
 /* Given a tree node describing an array bound (either lower or upper) output
@@ -13827,7 +13827,8 @@
       if (DWARF2_ASM_LINE_DEBUG_INFO)
 	{
 	  fprintf (asm_out_file, "\t.file %u ", fd->emitted_number);
-	  output_quoted_string (asm_out_file, fd->filename);
+	  output_quoted_string (asm_out_file,
+				remap_debug_filename (fd->filename));
 	  fputc ('\n', asm_out_file);
 	}
     }
@@ -13994,7 +13995,7 @@
       dw_die_ref bincl_die;
 
       bincl_die = new_die (DW_TAG_GNU_BINCL, comp_unit_die, NULL);
-      add_AT_string (bincl_die, DW_AT_name, filename);
+      add_AT_string (bincl_die, DW_AT_name, remap_debug_filename (filename));
     }
 
   if (debug_info_level >= DINFO_LEVEL_VERBOSE)
@@ -14453,7 +14454,7 @@
 {
   bool *p = param;
   struct dwarf_file_data *d = *slot;
-  if (d->emitted_number && !IS_ABSOLUTE_PATH (d->filename))
+  if (!IS_ABSOLUTE_PATH (d->filename))
     {
       *p = true;
       return 0;
@@ -14472,7 +14473,7 @@
 
   /* Add the name for the main input file now.  We delayed this from
      dwarf2out_init to avoid complications with PCH.  */
-  add_name_attribute (comp_unit_die, filename);
+  add_name_attribute (comp_unit_die, remap_debug_filename (filename));
   if (!IS_ABSOLUTE_PATH (filename))
     add_comp_dir_attribute (comp_unit_die);
   else if (get_AT (comp_unit_die, DW_AT_comp_dir) == NULL)
Index: gcc/opts.c
===================================================================
--- gcc/opts.c	(revision 126328)
+++ gcc/opts.c	(working copy)
@@ -41,6 +41,7 @@
 #include "target.h"
 #include "tree-pass.h"
 #include "dbgcnt.h"
+#include "debug.h"
 
 /* Value of the -G xx switch, and whether it was passed or not.  */
 unsigned HOST_WIDE_INT g_switch_value;
@@ -1442,6 +1443,10 @@
       dbg_cnt_list_all_counters ();
       break;
 
+    case OPT_fdebug_prefix_map_:
+      add_debug_prefix_map (arg);
+      break;
+
     case OPT_fdiagnostics_show_location_:
       if (!strcmp (arg, "once"))
 	diagnostic_prefixing_rule (global_dc) = DIAGNOSTICS_SHOW_PREFIX_ONCE;
Index: gcc/configure.ac
===================================================================
--- gcc/configure.ac	(revision 126328)
+++ gcc/configure.ac	(working copy)
@@ -3050,6 +3050,12 @@
    fi],
   [AC_DEFINE(HAVE_AS_GSTABS_DEBUG_FLAG, 1,
 [Define if your assembler supports the --gstabs option.])])
+
+ gcc_GAS_CHECK_FEATURE([--debug-prefix-map option],
+  gcc_cv_as_debug_prefix_map_flag,
+  [2,18,0], [--debug-prefix-map /a=/b], [$insn],,
+  [AC_DEFINE(HAVE_AS_DEBUG_PREFIX_MAP, 1,
+[Define if your assembler supports the --debug-prefix-map option.])])
 fi
 
 AC_CACHE_CHECK([assembler for tolerance to line number 0],
Index: gcc/common.opt
===================================================================
--- gcc/common.opt	(revision 126328)
+++ gcc/common.opt	(working copy)
@@ -400,6 +400,10 @@
 Common RejectNegative Joined
 -fdbg-cnt=<counter>:<limit>[,<counter>:<limit>,...]    Set the debug counter limit.   
 
+fdebug-prefix-map=
+Common Joined RejectNegative
+Map one directory name to another in debug information
+
 ; Nonzero for -fdefer-pop: don't pop args after each function call
 ; instead save them up to pop many calls' args with one insns.
 fdefer-pop
Index: gcc/Makefile.in
===================================================================
--- gcc/Makefile.in	(revision 126328)
+++ gcc/Makefile.in	(working copy)
@@ -2276,7 +2276,7 @@
 opts.o : opts.c opts.h options.h toplev.h $(CONFIG_H) $(SYSTEM_H) \
    coretypes.h $(TREE_H) $(TM_H) langhooks.h $(GGC_H) $(RTL_H) \
    output.h $(DIAGNOSTIC_H) $(TM_P_H) $(INSN_ATTR_H) intl.h $(TARGET_H) \
-   $(FLAGS_H) $(PARAMS_H) tree-pass.h $(DBGCNT_H)
+   $(FLAGS_H) $(PARAMS_H) tree-pass.h $(DBGCNT_H) debug.h
 opts-common.o : opts-common.c opts.h $(CONFIG_H) $(SYSTEM_H) \
    coretypes.h intl.h
 targhooks.o : targhooks.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TREE_H) \
@@ -2762,7 +2762,7 @@
    insn-config.h $(INSN_ATTR_H) $(FUNCTION_H) output.h hard-reg-set.h \
    except.h debug.h xcoffout.h toplev.h reload.h dwarf2out.h tree-pass.h \
    $(BASIC_BLOCK_H) $(TM_P_H) $(TARGET_H) $(EXPR_H) $(CFGLAYOUT_H) dbxout.h \
-   $(TIMEVAR_H) $(CGRAPH_H) $(COVERAGE_H) $(REAL_H) $(DF_H) vecprim.h
+   $(TIMEVAR_H) $(CGRAPH_H) $(COVERAGE_H) $(REAL_H) $(DF_H) vecprim.h $(GGC_H)
 recog.o : recog.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(RTL_H) \
    $(FUNCTION_H) $(BASIC_BLOCK_H) $(REGS_H) $(RECOG_H) $(EXPR_H) \
    $(FLAGS_H) insn-config.h $(INSN_ATTR_H) toplev.h output.h reload.h \
Index: configure.ac
===================================================================
--- configure.ac	(revision 126328)
+++ configure.ac	(working copy)
@@ -1590,6 +1590,18 @@
   [SYSROOT_CFLAGS_FOR_TARGET=])
 AC_SUBST(SYSROOT_CFLAGS_FOR_TARGET)
 
+AC_ARG_WITH([debug-prefix-map],
+  [  --with-debug-prefix-map='A=B C=D ...'
+                             map A to B, C to D ... in debug information],
+  [if test x"$withval" != x; then
+     DEBUG_PREFIX_CFLAGS_FOR_TARGET=
+     for debug_map in $withval; do
+       DEBUG_PREFIX_CFLAGS_FOR_TARGET="$DEBUG_PREFIX_CFLAGS_FOR_TARGET -fdebug-prefix-map=$debug_map"
+     done
+   fi],
+  [DEBUG_PREFIX_CFLAGS_FOR_TARGET=])
+AC_SUBST(DEBUG_PREFIX_CFLAGS_FOR_TARGET)
+
 # Handle --with-headers=XXX.  If the value is not "yes", the contents of
 # the named directory are copied to $(tooldir)/sys-include.
 if test x"${with_headers}" != x && test x"${with_headers}" != xno ; then
Index: Makefile.tpl
===================================================================
--- Makefile.tpl	(revision 126328)
+++ Makefile.tpl	(working copy)
@@ -361,9 +361,12 @@
 # CFLAGS will be just -g.  We want to ensure that TARGET libraries
 # (which we know are built with gcc) are built with optimizations so
 # prepend -O2 when setting CFLAGS_FOR_TARGET.
-CFLAGS_FOR_TARGET = -O2 $(CFLAGS) $(SYSROOT_CFLAGS_FOR_TARGET)
+CFLAGS_FOR_TARGET = -O2 $(CFLAGS) $(SYSROOT_CFLAGS_FOR_TARGET) \
+	$(DEBUG_PREFIX_CFLAGS_FOR_TARGET)
 SYSROOT_CFLAGS_FOR_TARGET = @SYSROOT_CFLAGS_FOR_TARGET@
-CXXFLAGS_FOR_TARGET = $(CXXFLAGS) $(SYSROOT_CFLAGS_FOR_TARGET)
+DEBUG_PREFIX_CFLAGS_FOR_TARGET = @DEBUG_PREFIX_CFLAGS_FOR_TARGET@
+CXXFLAGS_FOR_TARGET = $(CXXFLAGS) $(SYSROOT_CFLAGS_FOR_TARGET) \
+	$(DEBUG_PREFIX_CFLAGS_FOR_TARGET)
 LIBCFLAGS_FOR_TARGET = $(CFLAGS_FOR_TARGET)
 LIBCXXFLAGS_FOR_TARGET = $(CXXFLAGS_FOR_TARGET) -fno-implicit-templates
 LDFLAGS_FOR_TARGET = 
Index: config/mt-gnu
===================================================================
--- config/mt-gnu	(revision 126328)
+++ config/mt-gnu	(working copy)
@@ -1 +1,2 @@
-CXXFLAGS_FOR_TARGET = $(CXXFLAGS) $(SYSROOT_CFLAGS_FOR_TARGET) -D_GNU_SOURCE
+CXXFLAGS_FOR_TARGET = $(CXXFLAGS) $(SYSROOT_CFLAGS_FOR_TARGET) \
+	$(DEBUG_PREFIX_CFLAGS_FOR_TARGET) -D_GNU_SOURCE






2007-07-04  Joseph Myers  <joseph@codesourcery.com>
            Paul Brook  <paul@codesourcery.com>

	* remap.c: New.
	* as.h (remap_debug_filename, add_debug_prefix_map): Declare.
	* as.c (show_usage): Document --debug-prefix-map option.
	(parse_args): Handle --debug-prefix-map.
	* dwarf2dbg.c (out_file_list, out_debug_info): Remap debug paths.
	* stabs.c (stabs_generate_asm_file): Remap debug paths.
	* Makefile.am (GAS_CFILES): Add remap.c
	(GENERIC_OBJS): Add remap.o.
	Regenerate dependencies.
	* Makefile.in: Regenerate.
	* doc/as.texinfo (--debug-prefix-map): Document.

Index: gas/Makefile.am
===================================================================
RCS file: /cvs/src/src/gas/Makefile.am,v
retrieving revision 1.151
diff -u -r1.151 Makefile.am
--- gas/Makefile.am	2 Jul 2007 07:12:50 -0000	1.151
+++ gas/Makefile.am	4 Jul 2007 21:25:51 -0000
@@ -195,6 +195,7 @@
 	messages.c \
 	output-file.c \
 	read.c \
+	remap.c \
 	sb.c \
 	stabs.c \
 	subsegs.c \
@@ -439,6 +440,7 @@
 	messages.o \
 	output-file.o \
 	read.o \
+	remap.o \
 	subsegs.o \
 	symbols.o \
 	write.o \
@@ -1490,6 +1492,11 @@
   $(INCDIR)/bfdlink.h $(srcdir)/config/tc-bfin.h dwarf2dbg.h \
   $(INCDIR)/safe-ctype.h subsegs.h $(INCDIR)/obstack.h \
   $(INCDIR)/obstack.h struc-symbol.h dwarf2dbg.h $(INCDIR)/aout/aout64.h
+DEPOBJ_cr16_elf = $(srcdir)/config/obj-elf.h $(BFDDIR)/elf-bfd.h \
+  $(INCDIR)/elf/common.h $(INCDIR)/elf/internal.h $(INCDIR)/elf/external.h \
+  $(INCDIR)/bfdlink.h $(srcdir)/config/tc-cr16.h dwarf2dbg.h \
+  $(INCDIR)/safe-ctype.h subsegs.h $(INCDIR)/obstack.h \
+  $(INCDIR)/obstack.h struc-symbol.h dwarf2dbg.h $(INCDIR)/aout/aout64.h
 DEPOBJ_cris_aout = $(srcdir)/config/obj-aout.h $(srcdir)/config/tc-cris.h \
   $(BFDDIR)/libaout.h $(INCDIR)/bfdlink.h $(INCDIR)/aout/aout64.h \
   $(INCDIR)/obstack.h
@@ -2158,6 +2165,7 @@
 output-file.o: output-file.c output-file.h
 read.o: read.c $(INCDIR)/safe-ctype.h subsegs.h $(INCDIR)/obstack.h \
   sb.h macro.h ecoff.h dw2gencfi.h $(INCDIR)/elf/dwarf2.h
+remap.o: remap.c
 sb.o: sb.c sb.h
 stabs.o: stabs.c $(INCDIR)/obstack.h subsegs.h ecoff.h \
   $(INCDIR)/aout/stab_gnu.h $(INCDIR)/aout/stab.def
Index: gas/as.c
===================================================================
RCS file: /cvs/src/src/gas/as.c,v
retrieving revision 1.75
diff -u -r1.75 as.c
--- gas/as.c	3 Jul 2007 11:01:02 -0000	1.75
+++ gas/as.c	4 Jul 2007 21:25:52 -0000
@@ -244,6 +244,8 @@
   fprintf (stream, _("\
   -D                      produce assembler debugging messages\n"));
   fprintf (stream, _("\
+  --debug-prefix-map OLD=NEW  Map OLD to NEW in debug information\n"));
+  fprintf (stream, _("\
   --defsym SYM=VAL        define symbol SYM to given value\n"));
 #ifdef USE_EMULATIONS
   {
@@ -407,6 +409,7 @@
       OPTION_DUMPCONFIG,
       OPTION_VERBOSE,
       OPTION_EMULATION,
+      OPTION_DEBUG_PREFIX_MAP,
       OPTION_DEFSYM,
       OPTION_INSTTBL,
       OPTION_LISTING_LHS_WIDTH,
@@ -445,6 +448,7 @@
     ,{"a", optional_argument, NULL, 'a'}
     /* Handle -al=<FILE>.  */
     ,{"al", optional_argument, NULL, OPTION_AL}
+    ,{"debug-prefix-map", required_argument, NULL, OPTION_DEBUG_PREFIX_MAP}
     ,{"defsym", required_argument, NULL, OPTION_DEFSYM}
     ,{"dump-config", no_argument, NULL, OPTION_DUMPCONFIG}
     ,{"emulation", required_argument, NULL, OPTION_EMULATION}
@@ -620,6 +624,10 @@
 #endif
 	  exit (EXIT_SUCCESS);
 
+	case OPTION_DEBUG_PREFIX_MAP:
+	  add_debug_prefix_map (optarg);
+	  break;
+
 	case OPTION_DEFSYM:
 	  {
 	    char *s;
Index: gas/as.h
===================================================================
RCS file: /cvs/src/src/gas/as.h,v
retrieving revision 1.57
diff -u -r1.57 as.h
--- gas/as.h	3 Jul 2007 11:01:02 -0000	1.57
+++ gas/as.h	4 Jul 2007 21:25:52 -0000
@@ -567,6 +567,9 @@
 void   print_dependencies (void);
 segT   subseg_get (const char *, int);
 
+const char *remap_debug_filename (const char *);
+void add_debug_prefix_map (const char *);
+
 struct expressionS;
 struct fix;
 typedef struct symbol symbolS;
Index: gas/dwarf2dbg.c
===================================================================
RCS file: /cvs/src/src/gas/dwarf2dbg.c,v
retrieving revision 1.89
diff -u -r1.89 dwarf2dbg.c
--- gas/dwarf2dbg.c	3 Jul 2007 11:01:02 -0000	1.89
+++ gas/dwarf2dbg.c	4 Jul 2007 21:25:52 -0000
@@ -1224,15 +1224,17 @@
 out_file_list (void)
 {
   size_t size;
+  const char *dir;
   char *cp;
   unsigned int i;
 
   /* Emit directory list.  */
   for (i = 1; i < dirs_in_use; ++i)
     {
-      size = strlen (dirs[i]) + 1;
+      dir = remap_debug_filename (dirs[i]);
+      size = strlen (dir) + 1;
       cp = frag_more (size);
-      memcpy (cp, dirs[i], size);
+      memcpy (cp, dir, size);
     }
   /* Terminate it.  */
   out_byte ('\0');
@@ -1514,7 +1516,8 @@
 out_debug_info (segT info_seg, segT abbrev_seg, segT line_seg, segT ranges_seg)
 {
   char producer[128];
-  char *comp_dir;
+  const char *comp_dir;
+  const char *dirname;
   expressionS expr;
   symbolS *info_start;
   symbolS *info_end;
@@ -1604,9 +1607,10 @@
     abort ();
   if (files[1].dir)
     {
-      len = strlen (dirs[files[1].dir]);
+      dirname = remap_debug_filename (dirs[files[1].dir]);
+      len = strlen (dirname);
       p = frag_more (len + 1);
-      memcpy (p, dirs[files[1].dir], len);
+      memcpy (p, dirname, len);
       INSERT_DIR_SEPARATOR (p, len);
     }
   len = strlen (files[1].filename) + 1;
@@ -1614,7 +1618,7 @@
   memcpy (p, files[1].filename, len);
 
   /* DW_AT_comp_dir */
-  comp_dir = getpwd ();
+  comp_dir = remap_debug_filename (getpwd ());
   len = strlen (comp_dir) + 1;
   p = frag_more (len);
   memcpy (p, comp_dir, len);
Index: gas/remap.c
===================================================================
RCS file: gas/remap.c
diff -N gas/remap.c
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ gas/remap.c	4 Jul 2007 21:25:52 -0000
@@ -0,0 +1,89 @@
+/* Remap file names for debug info for GNU assembler.
+   Copyright 2007 Free Software Foundation, Inc.
+
+   This file is part of GAS, the GNU Assembler.
+
+   GAS is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2, or (at your option)
+   any later version.
+
+   GAS is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with GAS; see the file COPYING.  If not, write to the Free
+   Software Foundation, 51 Franklin Street - Fifth Floor, Boston, MA
+   02110-1301, USA.  */
+
+#include "as.h"
+
+/* Structure recording the mapping from source file and directory
+   names at compile time to those to be embedded in debug
+   information.  */
+typedef struct debug_prefix_map
+{
+  const char *old_prefix;
+  const char *new_prefix;
+  size_t old_len;
+  size_t new_len;
+  struct debug_prefix_map *next;
+} debug_prefix_map;
+
+/* Linked list of such structures.  */
+debug_prefix_map *debug_prefix_maps;
+
+
+/* Record a debug file prefix mapping.  ARG is the argument to
+   -fdebug-prefix-map and must be of the form OLD=NEW.  */
+
+void
+add_debug_prefix_map (const char *arg)
+{
+  debug_prefix_map *map;
+  const char *p;
+  char *o;
+
+  p = strchr (arg, '=');
+  if (!p)
+    {
+      as_fatal (_("invalid argument '%s' to -fdebug-prefix-map"), arg);
+      return;
+    }
+  map = xmalloc (sizeof (debug_prefix_map));
+  o = xstrdup (arg);
+  map->old_prefix = o;
+  map->old_len = p - arg;
+  o[map->old_len] = 0;
+  p++;
+  map->new_prefix = xstrdup (p);
+  map->new_len = strlen (p);
+  map->next = debug_prefix_maps;
+  debug_prefix_maps = map;
+}
+
+/* Perform user-specified mapping of debug filename prefixes.  Return
+   the new name corresponding to FILENAME.  */
+
+const char *
+remap_debug_filename (const char *filename)
+{
+  debug_prefix_map *map;
+  char *s;
+  const char *name;
+  size_t name_len;
+
+  for (map = debug_prefix_maps; map; map = map->next)
+    if (strncmp (filename, map->old_prefix, map->old_len) == 0)
+      break;
+  if (!map)
+    return filename;
+  name = filename + map->old_len;
+  name_len = strlen (name) + 1;
+  s = (char *) alloca (name_len + map->new_len);
+  memcpy (s, map->new_prefix, map->new_len);
+  memcpy (s + map->new_len, name, name_len);
+  return xstrdup (s);
+}
Index: gas/stabs.c
===================================================================
RCS file: /cvs/src/src/gas/stabs.c,v
retrieving revision 1.28
diff -u -r1.28 stabs.c
--- gas/stabs.c	3 Jul 2007 11:01:03 -0000	1.28
+++ gas/stabs.c	4 Jul 2007 21:25:52 -0000
@@ -492,9 +492,10 @@
   as_where (&file, &lineno);
   if (use_gnu_debug_info_extensions)
     {
-      char *dir, *dir2;
+      const char *dir;
+      char *dir2;
 
-      dir = getpwd ();
+      dir = remap_debug_filename (getpwd ());
       dir2 = alloca (strlen (dir) + 2);
       sprintf (dir2, "%s%s", dir, "/");
       generate_asm_file (N_SO, dir2);
Index: gas/doc/Makefile.in
===================================================================
RCS file: /cvs/src/src/gas/doc/Makefile.in,v
retrieving revision 1.92
diff -u -r1.92 Makefile.in
--- gas/doc/Makefile.in	2 Jul 2007 07:12:50 -0000	1.92
+++ gas/doc/Makefile.in	4 Jul 2007 21:25:52 -0000
@@ -295,9 +295,9 @@
 	      exit 1;; \
 	  esac; \
 	done; \
-	echo ' cd $(top_srcdir) && $(AUTOMAKE) --cygnus  doc/Makefile'; \
+	echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign  doc/Makefile'; \
 	cd $(top_srcdir) && \
-	  $(AUTOMAKE) --cygnus  doc/Makefile
+	  $(AUTOMAKE) --foreign  doc/Makefile
 .PRECIOUS: Makefile
 Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
 	@case '$?' in \
Index: gas/doc/as.texinfo
===================================================================
RCS file: /cvs/src/src/gas/doc/as.texinfo,v
retrieving revision 1.166
diff -u -r1.166 as.texinfo
--- gas/doc/as.texinfo	29 Jun 2007 14:09:30 -0000	1.166
+++ gas/doc/as.texinfo	4 Jul 2007 21:25:54 -0000
@@ -226,6 +226,7 @@
 @smallexample
 @c man begin SYNOPSIS
 @value{AS} [@b{-a}[@b{cdhlns}][=@var{file}]] [@b{--alternate}] [@b{-D}]
+ [@b{--debug-prefix-map} @var{old}=@var{new}]
  [@b{--defsym} @var{sym}=@var{val}] [@b{-f}] [@b{-g}] [@b{--gstabs}]
  [@b{--gstabs+}] [@b{--gdwarf-2}] [@b{--help}] [@b{-I} @var{dir}] [@b{-J}]
  [@b{-K}] [@b{-L}] [@b{--listing-lhs-width}=@var{NUM}]
@@ -501,6 +502,10 @@
 Ignored.  This option is accepted for script compatibility with calls to
 other assemblers.
 
+@item --debug-prefix-map @var{old}=@var{new}
+When assembling files in directory @file{@var{old}}, record debugging
+information describing them as in @file{@var{new}} instead.
+
 @item --defsym @var{sym}=@var{value}
 Define the symbol @var{sym} to be @var{value} before assembling the input file.
 @var{value} must be an integer constant.  As in C, a leading @samp{0x}

-- 
Joseph S. Myers
joseph@codesourcery.com



More information about the Binutils mailing list