diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 9113d5d4b9a..de0dd70eb14 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,13 @@
+2007-03-12  Mark Mitchell  <mark@codesourcery.com>
+
+	* cppdefault.c (cpp_EXEC_PREFIX): New variable.
+	* cppdefault.h (cpp_PREFIX): Document.
+	(cpp_PREFIX_len): Likewise.
+	(cpp_EXEC_PREFIX): New variable.
+	* Makefile.in (PREPROCESSOR_DEFINES): Add STANDARD_EXEC_PREFIX.
+	* c-incpath.c (add_standard_paths): Correct logic for relocating
+	paths within prefix.
+
 2007-03-12  Uros Bizjak  <ubizjak@gmail.com>
 
 	* config/i386/i386.md (fixuns_trunc<mode>hi2): Implement from
diff --git a/gcc/Makefile.in b/gcc/Makefile.in
index a8792b80146..6d3fe12e0d7 100644
--- a/gcc/Makefile.in
+++ b/gcc/Makefile.in
@@ -3210,6 +3210,7 @@ PREPROCESSOR_DEFINES = \
   -DCROSS_INCLUDE_DIR=\"$(CROSS_SYSTEM_HEADER_DIR)\" \
   -DTOOL_INCLUDE_DIR=\"$(gcc_tooldir)/include\" \
   -DPREFIX=\"$(prefix)\" \
+  -DSTANDARD_EXEC_PREFIX=\"$(libdir)/gcc\" \
   @TARGET_SYSTEM_ROOT_DEFINE@
 
 cppdefault.o: cppdefault.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) \
diff --git a/gcc/c-incpath.c b/gcc/c-incpath.c
index fe863d52b6e..3a9585bd26d 100644
--- a/gcc/c-incpath.c
+++ b/gcc/c-incpath.c
@@ -167,11 +167,26 @@ add_standard_paths (const char *sysroot, const char *iprefix,
 	  else if (!p->add_sysroot && relocated
 		   && strncmp (p->fname, cpp_PREFIX, cpp_PREFIX_len) == 0)
 	    {
-	      /* If the compiler is relocated, and this is a configured 
-		 prefix relative path, then we use gcc_exec_prefix instead 
-		 of the configured prefix.  */
-	      str = concat (gcc_exec_prefix, p->fname
-			      + cpp_PREFIX_len, NULL);
+ 	      static const char *relocated_prefix;
+	      /* If this path starts with the configure-time prefix, 
+		 but the compiler has been relocated, replace it 
+		 with the run-time prefix.  The run-time exec prefix
+		 is GCC_EXEC_PREFIX.  Compute the path from there back
+		 to the toplevel prefix.  */
+	      if (!relocated_prefix)
+		{
+		  char *dummy;
+		  /* Make relative prefix expects the first argument
+		     to be a program, not a directory.  */
+		  dummy = concat (gcc_exec_prefix, "dummy", NULL);
+		  relocated_prefix 
+		    = make_relative_prefix (dummy,
+					    cpp_EXEC_PREFIX,
+					    cpp_PREFIX);
+		}
+	      str = concat (relocated_prefix,
+			    p->fname + cpp_PREFIX_len, 
+			    NULL);
 	      str = update_path (str, p->component);
 	    }
 	  else
diff --git a/gcc/cppdefault.c b/gcc/cppdefault.c
index 597988ee332..3e60841980f 100644
--- a/gcc/cppdefault.c
+++ b/gcc/cppdefault.c
@@ -112,6 +112,7 @@ const size_t cpp_GCC_INCLUDE_DIR_len = 0;
 /* The configured prefix.  */
 const char cpp_PREFIX[] = PREFIX;
 const size_t cpp_PREFIX_len = sizeof PREFIX - 1;
+const char cpp_EXEC_PREFIX[] = STANDARD_EXEC_PREFIX;
 
 /* This value is set by cpp_relocated at runtime */
 const char *gcc_exec_prefix;
diff --git a/gcc/cppdefault.h b/gcc/cppdefault.h
index 2da6d05f564..398cc857424 100644
--- a/gcc/cppdefault.h
+++ b/gcc/cppdefault.h
@@ -52,8 +52,16 @@ extern const struct default_include cpp_include_defaults[];
 extern const char cpp_GCC_INCLUDE_DIR[];
 extern const size_t cpp_GCC_INCLUDE_DIR_len;
 
+/* The configure-time prefix, i.e., the value supplied as the argument
+   to --prefix=.  */
 extern const char cpp_PREFIX[];
+/* The length of the configure-time prefix.  */
 extern const size_t cpp_PREFIX_len;
+/* The configure-time execution prefix.  This is typically the lib/gcc
+   subdirectory of cpp_PREFIX.  */
+extern const char cpp_EXEC_PREFIX[];
+/* The run-time execution prefix.  This is typically the lib/gcc
+   subdirectory of the actual installation.  */
 extern const char *gcc_exec_prefix;
 
 /* Return true if the toolchain is relocated.  */