From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 21544 invoked by alias); 5 Jul 2007 00:48:36 -0000 Received: (qmail 21144 invoked by uid 22791); 5 Jul 2007 00:48:32 -0000 X-Spam-Check-By: sourceware.org Received: from mail.codesourcery.com (HELO mail.codesourcery.com) (65.74.133.4) by sourceware.org (qpsmtpd/0.31) with ESMTP; Thu, 05 Jul 2007 00:48:21 +0000 Received: (qmail 856 invoked from network); 5 Jul 2007 00:48:18 -0000 Received: from unknown (HELO digraph.polyomino.org.uk) (joseph@127.0.0.2) by mail.codesourcery.com with ESMTPA; 5 Jul 2007 00:48:18 -0000 Received: from jsm28 (helo=localhost) by digraph.polyomino.org.uk with local-esmtp (Exim 4.63) (envelope-from ) id 1I6FW4-00033x-TK; Thu, 05 Jul 2007 00:48:16 +0000 Date: Thu, 05 Jul 2007 05:02:00 -0000 From: "Joseph S. Myers" To: gcc-patches@gcc.gnu.org, binutils@gcc.gnu.org Subject: Debug info path remapping Message-ID: MIME-Version: 1.0 Content-Type: TEXT/PLAIN; charset=US-ASCII Mailing-List: contact gcc-patches-help@gcc.gnu.org; run by ezmlm Precedence: bulk List-Id: List-Archive: List-Post: List-Help: Sender: gcc-patches-owner@gcc.gnu.org X-SW-Source: 2007-07/txt/msg00406.txt.bz2 These GCC and GAS patches add compiler and assembler support for remapping paths when generating debug information, as discussed in 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 Joseph Myers * 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 Joseph Myers * mt-gnu (CXXFLAGS_FOR_TARGET): Add $(DEBUG_PREFIX_CFLAGS_FOR_TARGET). gcc: 2007-07-04 Paul Brook Joseph Myers * 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 = ""; + 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=:[,:,...] 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 Paul Brook * 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=. */ ,{"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