diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 68fcd05..d58f6ee 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,12 @@
+2016-03-17  Hongxu Jia  <hongxu.jia@windriver.com>
+	PR **/**
+	* c-family/c-opts.c: Include file-map.h
+	(c_common_handle_option): Handle -ffile-prefix-map.
+	* c-family/c.opt(-ffile-prefix-map=): New option.
+	* gimplify.c: Include file-map.h
+	(gimplify_call_expr): Call remap_file_filename
+	* dwarf2out.c (gen_producer_string): Ignore -ffile-prefix-map.
+
 2016-03-16  Carlos O'Donell  <carlos@redhat.com>
 	    Sandra Loosemore  <sandra@codesourcery.com>
 
diff --git a/gcc/c-family/c-opts.c b/gcc/c-family/c-opts.c
index fec58bc..4dab155 100644
--- a/gcc/c-family/c-opts.c
+++ b/gcc/c-family/c-opts.c
@@ -39,6 +39,7 @@ along with GCC; see the file COPYING3.  If not see
 #include "plugin.h"		/* For PLUGIN_INCLUDE_FILE event.  */
 #include "mkdeps.h"
 #include "dumpfile.h"
+#include "file-map.h"
 
 #ifndef DOLLARS_IN_IDENTIFIERS
 # define DOLLARS_IN_IDENTIFIERS true
@@ -503,6 +504,11 @@ c_common_handle_option (size_t scode, const char *arg, int value,
       cpp_opts->narrow_charset = arg;
       break;
 
+    case OPT_ffile_prefix_map_:
+      if (add_file_prefix_map(arg) < 0)
+        error ("invalid argument %qs to -ffile-prefix-map", arg);
+      break;
+
     case OPT_fwide_exec_charset_:
       cpp_opts->wide_charset = arg;
       break;
diff --git a/gcc/c-family/c.opt b/gcc/c-family/c.opt
index 7c5f6c7..2b88874 100644
--- a/gcc/c-family/c.opt
+++ b/gcc/c-family/c.opt
@@ -1204,6 +1204,10 @@ fexec-charset=
 C ObjC C++ ObjC++ Joined RejectNegative
 -fexec-charset=<cset>	Convert all strings and character constants to character set <cset>.
 
+ffile-prefix-map=
+C ObjC C++ ObjC++ Joined RejectNegative
+-ffile-prefix-map=<old=new>	Map one directory name to another in __FILE__, __BASE_FILE__ and __builtin_FILE()
+
 fextended-identifiers
 C ObjC C++ ObjC++
 Permit universal character names (\\u and \\U) in identifiers.
diff --git a/gcc/doc/invoke.texi b/gcc/doc/invoke.texi
index 99ac11b..d45d85f 100644
--- a/gcc/doc/invoke.texi
+++ b/gcc/doc/invoke.texi
@@ -323,6 +323,7 @@ Objective-C and Objective-C++ Dialects}.
 -gstabs  -gstabs+  -gstrict-dwarf  -gno-strict-dwarf @gol
 -gvms  -gxcoff  -gxcoff+ -gz@r{[}=@var{type}@r{]} @gol
 -fdebug-prefix-map=@var{old}=@var{new} -fdebug-types-section @gol
+-ffile-prefix-map=@var{old}=@var{new} @gol
 -feliminate-dwarf2-dups -fno-eliminate-unused-debug-types @gol
 -femit-struct-debug-baseonly -femit-struct-debug-reduced @gol
 -femit-struct-debug-detailed@r{[}=@var{spec-list}@r{]} @gol
@@ -5929,6 +5930,11 @@ link processing time.  Merging is enabled by default.
 When compiling files in directory @file{@var{old}}, record debugging
 information describing them as in @file{@var{new}} instead.
 
+@item -ffile-prefix-map=@var{old}=@var{new}
+@opindex ffile-prefix-map
+When parsing __FILE__, __BASE_FILE__ and __builtin_FILE(), use directory
+@file{@var{new}} to replace @file{@var{old}}.
+
 @item -fvar-tracking
 @opindex fvar-tracking
 Run variable tracking pass.  It computes where variables are stored at each
diff --git a/gcc/dwarf2out.c b/gcc/dwarf2out.c
index 61bf267..d8beeea 100644
--- a/gcc/dwarf2out.c
+++ b/gcc/dwarf2out.c
@@ -21672,6 +21672,7 @@ gen_producer_string (void)
       case OPT_fltrans_output_list_:
       case OPT_fresolution_:
       case OPT_fdebug_prefix_map_:
+      case OPT_ffile_prefix_map_:
 	/* Ignore these.  */
 	continue;
       default:
diff --git a/gcc/gimplify.c b/gcc/gimplify.c
index b331e41..7b88706 100644
--- a/gcc/gimplify.c
+++ b/gcc/gimplify.c
@@ -59,6 +59,7 @@ along with GCC; see the file COPYING3.  If not see
 #include "gimple-walk.h"
 #include "langhooks-def.h"	/* FIXME: for lhd_set_decl_assembler_name */
 #include "builtins.h"
+#include "file-map.h"
 
 enum gimplify_omp_var_data
 {
@@ -2429,6 +2430,7 @@ gimplify_call_expr (tree *expr_p, gimple_seq *pre_p, bool want_value)
       case BUILT_IN_FILE:
 	{
 	  const char *locfile = LOCATION_FILE (EXPR_LOCATION (*expr_p));
+	  locfile = remap_file_filename (locfile);
 	  *expr_p = build_string_literal (strlen (locfile) + 1, locfile);
 	  return GS_OK;
 	}
diff --git a/libcpp/ChangeLog b/libcpp/ChangeLog
index 89b582d..5dba07e 100644
--- a/libcpp/ChangeLog
+++ b/libcpp/ChangeLog
@@ -1,3 +1,15 @@
+2016-03-17  Hongxu Jia  <hongxu.jia@windriver.com>
+	PR **/**
+	* macro.c: Include file-map.h
+	(_cpp_builtin_macro_text): Call remap_file_filename
+	* include/file-map.h (remap_file_filename,
+	add_file_prefix_map): Declare.
+	* file-map.c: Include config.h, system.h, file-map.h.
+	(struct file_prefix_map, file_prefix_maps, add_file_prefix_map,
+	remap_file_filename): New.
+	* Makefile.in (file-map.c, file-map.o,
+	file-map.h): Update dependencies.
+
 2016-03-15  Richard Henderson  <rth@redhat.com>
 
 	* line-map.c (new_linemap): Make alloc_size a size_t.
diff --git a/libcpp/Makefile.in b/libcpp/Makefile.in
index a7d7828..3d29572 100644
--- a/libcpp/Makefile.in
+++ b/libcpp/Makefile.in
@@ -84,12 +84,12 @@ DEPMODE = $(CXXDEPMODE)
 
 
 libcpp_a_OBJS = charset.o directives.o directives-only.o errors.o \
-	expr.o files.o identifiers.o init.o lex.o line-map.o macro.o \
-	mkdeps.o pch.o symtab.o traditional.o
+	expr.o file-map.o files.o identifiers.o init.o lex.o line-map.o \
+	macro.o mkdeps.o pch.o symtab.o traditional.o
 
 libcpp_a_SOURCES = charset.c directives.c directives-only.c errors.c \
-	expr.c files.c identifiers.c init.c lex.c line-map.c macro.c \
-	mkdeps.c pch.c symtab.c traditional.c
+	expr.c file-map.c files.c identifiers.c init.c lex.c line-map.c \
+	macro.c mkdeps.c pch.c symtab.c traditional.c
 
 all: libcpp.a $(USED_CATALOGS)
 
@@ -263,7 +263,7 @@ po/$(PACKAGE).pot: $(libcpp_a_SOURCES)
 
 TAGS_SOURCES = $(libcpp_a_SOURCES) internal.h ucnid.h \
     include/line-map.h include/symtab.h include/cpp-id-data.h \
-    include/cpplib.h include/mkdeps.h system.h
+    include/cpplib.h include/mkdeps.h system.h include/file-map.h
 
 TAGS: $(TAGS_SOURCES)
 	cd $(srcdir) && etags $(TAGS_SOURCES)
diff --git a/libcpp/file-map.c b/libcpp/file-map.c
new file mode 100644
index 0000000..04e851b
--- /dev/null
+++ b/libcpp/file-map.c
@@ -0,0 +1,92 @@
+/* Map one directory name to another in __FILE__, __BASE_FILE__
+   and __builtin_FILE().
+   Copyright (C) 2001-2016 Free Software Foundation, Inc.
+
+This program 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 3, or (at your option) any
+later version.
+
+This program 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 this program; see the file COPYING3.  If not see
+<http://www.gnu.org/licenses/>.
+
+ In other words, you are welcome to use, share and improve this program.
+ You are forbidden to forbid anyone else to use, share and improve
+ what you give them.   Help stamp out software-hoarding!  */
+
+#include "config.h"
+#include "system.h"
+#include "file-map.h"
+
+/* Structure recording the mapping from source file and directory
+   names at compile time to __FILE__ */
+typedef struct file_prefix_map
+{
+  const char *old_prefix;
+  const char *new_prefix;
+  size_t old_len;
+  size_t new_len;
+  struct file_prefix_map *next;
+} file_prefix_map;
+
+/* Linked list of such structures.  */
+static file_prefix_map *file_prefix_maps;
+
+/* Record prefix mapping of __FILE__.  ARG is the argument to
+   -ffile-prefix-map and must be of the form OLD=NEW.  */
+int
+add_file_prefix_map (const char *arg)
+{
+  file_prefix_map *map;
+  const char *p;
+
+  p = strchr (arg, '=');
+  if (!p)
+  {
+      fprintf(stderr, "invalid argument %qs to -ffile-prefix-map", arg);
+      return -1;
+  }
+  map = XNEW (file_prefix_map);
+  map->old_prefix = xstrndup (arg, p - arg);
+  map->old_len = p - arg;
+  p++;
+  map->new_prefix = xstrdup (p);
+  map->new_len = strlen (p);
+  map->next = file_prefix_maps;
+  file_prefix_maps = map;
+
+  return 0;
+}
+
+/* Perform user-specified mapping of __FILE__ prefixes.  Return
+   the new name corresponding to FILENAME.  */
+
+const char *
+remap_file_filename (const char *filename)
+{
+  file_prefix_map *map;
+  char *s;
+  const char *name;
+  size_t name_len;
+
+  for (map = file_prefix_maps; map; map = map->next)
+    if (filename_ncmp (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);
+}
+
+
diff --git a/libcpp/include/file-map.h b/libcpp/include/file-map.h
new file mode 100644
index 0000000..e6f8cbf
--- /dev/null
+++ b/libcpp/include/file-map.h
@@ -0,0 +1,30 @@
+/* Map one directory name to another in __FILE__, __BASE_FILE__
+   and __builtin_FILE().
+   Copyright (C) 2001-2016 Free Software Foundation, Inc.
+
+This program 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 3, or (at your option) any
+later version.
+
+This program 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 this program; see the file COPYING3.  If not see
+<http://www.gnu.org/licenses/>.
+
+ In other words, you are welcome to use, share and improve this program.
+ You are forbidden to forbid anyone else to use, share and improve
+ what you give them.   Help stamp out software-hoarding!  */
+
+#ifndef LIBCPP_FILE_MAP_H
+#define LIBCPP_FILE_MAP_H
+
+const char * remap_file_filename (const char *filename);
+
+int add_file_prefix_map (const char *arg);
+
+#endif /* !LIBCPP_FILE_MAP_H  */
diff --git a/libcpp/macro.c b/libcpp/macro.c
index cfb09ce..3915cea 100644
--- a/libcpp/macro.c
+++ b/libcpp/macro.c
@@ -26,6 +26,7 @@ along with this program; see the file COPYING3.  If not see
 #include "system.h"
 #include "cpplib.h"
 #include "internal.h"
+#include "file-map.h"
 
 typedef struct macro_arg macro_arg;
 /* This structure represents the tokens of a macro argument.  These
@@ -299,6 +300,7 @@ _cpp_builtin_macro_text (cpp_reader *pfile, cpp_hashnode *node)
 	    if (!name)
 	      abort ();
 	  }
+	name = remap_file_filename(name);
 	len = strlen (name);
 	buf = _cpp_unaligned_alloc (pfile, len * 2 + 3);
 	result = buf;
