diff --git a/bin/install.pike b/bin/install.pike
index e0b115f4b98fd24117f090dffa49f577beb9db60..f1fd7955609f1dd6d9f1028a2fab6ab61d535423 100644
--- a/bin/install.pike
+++ b/bin/install.pike
@@ -1008,6 +1008,8 @@ void make_master(string dest, string master, string lib_prefix)
   status("Finalizing",master);
   string master_data=Stdio.read_file(master);
   master_data=replace(master_data,"�lib_prefix�",replace(lib_prefix,"\\","\\\\"));
+  if((vars->PIKE_MODULE_RELOC||"") != "")
+    master_data=replace(master_data,"#undef PIKE_MODULE_RELOC","#define PIKE_MODULE_RELOC 1");
   Stdio.write_file(combine_path(vars->TMP_LIBDIR,"master.pike"),master_data);
   status("Finalizing",master,"done");
 }
diff --git a/lib/master.pike.in b/lib/master.pike.in
index 1c109078c079c4d3e18661fdb415721d22ac1adc..7b8ddea6d59f0491c61b6bfbb2015a3ff9b416b7 100644
--- a/lib/master.pike.in
+++ b/lib/master.pike.in
@@ -1,6 +1,6 @@
 /* -*- Pike -*-
  *	
- * $Id: master.pike.in,v 1.168 2001/08/31 07:18:19 hubbe Exp $
+ * $Id: master.pike.in,v 1.169 2001/09/02 01:36:13 marcus Exp $
  * 
  * Master-file for Pike.
  *
@@ -33,6 +33,8 @@ constant out_of_date_warning = OUT_OF_DATE_WARNING;
 #define PIKE_WARNINGS 0
 #endif /* PIKE_WARNINGS */
 
+#undef PIKE_MODULE_RELOC
+
 /*
  * Functions begin here.
  */
@@ -53,6 +55,41 @@ string fakeroot(string s)
 #define fakeroot(X) X
 #endif
 
+#ifdef PIKE_MODULE_RELOC
+string relocate_module(string s)
+{
+  if(s[..1]=="/$" && (s+"/")[..20] == "/${PIKE_MODULE_PATH}/") {
+    string tmp = s[21..];
+    foreach(pike_module_path, string path) {
+      string s2 = fakeroot(sizeof(tmp)? combine_path(path, tmp) : path);
+      if(master_file_stat(s2))
+	return s2;
+    }
+  }
+  return fakeroot(s);
+}
+
+string unrelocate_module(string s)
+{
+  if(s[..1]=="/$" && (s+"/")[..20] == "/${PIKE_MODULE_PATH}/")
+    return s;
+
+  foreach(pike_module_path, string path)
+    if(s == path)
+      return "/${PIKE_MODULE_PATH}";
+    else {
+      string s2 = combine_path(path, "");
+      if(s[..sizeof(s2)-1] == s2)
+	return "/${PIKE_MODULE_PATH}/"+s[sizeof(s2)..];
+    }
+  return s;
+}
+#ifdef fakeroot
+#undef fakeroot
+#endif
+#define fakeroot relocate_module
+#endif
+
 
 //! @appears is_absolute_path
 //! Check if a path @[p] is fully qualified (ie not relative).
@@ -392,6 +429,10 @@ static program low_findprog(string pname,
   }
 #endif
 
+#ifdef PIKE_MODULE_RELOC
+  fname = unrelocate_module(fname);
+#endif
+
 #ifdef PIKE_AUTORELOAD
   if(!autoreload_on || load_time[fname]>=time())
 #endif
@@ -1683,6 +1724,9 @@ mixed get_inhibit_compile_errors()
 static private function(string:string) _trim_file_name_cb=0;
 string trim_file_name(string s)
 {
+#ifdef PIKE_MODULE_RELOC
+  s = relocate_module(s);
+#endif
   if(getenv("LONG_PIKE_ERRORS")) return s;
   if(getenv("SHORT_PIKE_ERRORS")) return BASENAME(s);
 
diff --git a/lib/modules/Calendar.pmod/Events.pmod b/lib/modules/Calendar.pmod/Events.pmod
index 77dfc741aea70ab969628ec7ae62b5f92030de6a..70b053776b764c8e0a2883ff5af94369e96938bd 100644
--- a/lib/modules/Calendar.pmod/Events.pmod
+++ b/lib/modules/Calendar.pmod/Events.pmod
@@ -12,7 +12,7 @@ constant wd2n=(["Mon":1,"Tue":2,"Wed":3,"Thu":4,"Fri":5,"Sat":6,"Sun":7]);
 
 void read_all_data()
 {
-   all_data=Stdio.read_bytes(
+   all_data=master()->master_read_file(
       combine_path(__FILE__,"../events/regional"));
 }
 
@@ -171,7 +171,7 @@ mapping made_namedays=([]);
 
 string read_all_namedays()
 {
-   return Stdio.read_bytes(
+   return master()->master_read_file(
       combine_path(__FILE__,"../events/namedays"));
 }
 
diff --git a/lib/modules/Calendar.pmod/TZnames.pmod b/lib/modules/Calendar.pmod/TZnames.pmod
index 7b89f936f8921d8eb9e00f3a1125460ed2ebcbd7..b77a3d8bd59e133f4a920239c85e34ef7696e1ad 100644
--- a/lib/modules/Calendar.pmod/TZnames.pmod
+++ b/lib/modules/Calendar.pmod/TZnames.pmod
@@ -31,7 +31,7 @@ static string raw_zone_tab=0;
 string _zone_tab()
 {
    return raw_zone_tab ||
-      (raw_zone_tab = Stdio.read_bytes(
+      (raw_zone_tab = master()->master_read_file(
 	 combine_path(__FILE__,"..","tzdata/zone.tab")));
 }
 
diff --git a/lib/modules/Calendar.pmod/Timezone.pmod b/lib/modules/Calendar.pmod/Timezone.pmod
index 1a66c049c7eec26c139e792b4ceef38fcfd46360..684c29d0fe488213fc247632b92bb9913a54ee81 100644
--- a/lib/modules/Calendar.pmod/Timezone.pmod
+++ b/lib/modules/Calendar.pmod/Timezone.pmod
@@ -1041,7 +1041,7 @@ class Runtime_timezone_compiler
 	 map(files,
 	     lambda(string fn)
 	     {
-		return Stdio.read_bytes(base_path+fn) ||
+		return master()->master_read_file(base_path+fn) ||
 		   (error("Failed to open file %O\n",base_path+fn), "");
 	     })*"\n";
    }
diff --git a/src/Makefile.in b/src/Makefile.in
index 09f5fe80453d79e4b424f2f596d1256feea563e2..08387f8c37eeb83c66b4bd4fa0f5b4a5aa52f590 100644
--- a/src/Makefile.in
+++ b/src/Makefile.in
@@ -1,5 +1,5 @@
 #
-# $Id: Makefile.in,v 1.270 2001/07/20 12:44:50 grubba Exp $
+# $Id: Makefile.in,v 1.271 2001/09/02 01:36:14 marcus Exp $
 #
 
 # This line is needed on some machines.
@@ -99,6 +99,7 @@ RUNPIKE=$(DEFAULT_RUNPIKE)
 USE_TPIKE=$(TMP_BUILDDIR)/precompile.sh
 USE_PIKE=@PIKE@ $(PIKEOPTS)
 RUNTPIKE=$(@RUNTPIKE@)
+PIKE_MODULE_RELOC=@PIKE_MODULE_RELOC@
 
 MAKE_FLAGS=
 
@@ -371,14 +372,14 @@ install: pike hilfe pike-module aclocal
 	TMP_LIBDIR="$(TMP_LIBDIR)" LIBDIR_SRC="$(LIBDIR_SRC)" \
 	SRCDIR="$(SRCDIR)" prefix="$(prefix)" MANDIR_SRC="$(MANDIR_SRC)" \
 	man_prefix="$(man_prefix)" pike_name=$(pike_name) \
-	fakeroot="$(buildroot)"
+	fakeroot="$(buildroot)" PIKE_MODULE_RELOC="$(PIKE_MODULE_RELOC)"
 
 install_interactive: pike hilfe pike-module aclocal
 	@$(RUNPIKE) $(TMP_BINDIR)/install.pike --interactive \
 	exec_prefix="$(exec_prefix)"  prefix=$(prefix) \
 	TMP_LIBDIR="$(TMP_LIBDIR)" LIBDIR_SRC="$(LIBDIR_SRC)" \
 	SRCDIR="$(SRCDIR)" MANDIR_SRC="$(MANDIR_SRC)" \
-	fakeroot="$(buildroot)"
+	fakeroot="$(buildroot)" PIKE_MODULE_RELOC="$(PIKE_MODULE_RELOC)"
 
 # tidy up a bit
 tidy:
@@ -441,10 +442,10 @@ just_verify: module_testsuites testsuite master-stamp
 
 tinstall: aclocal master-stamp aclocal
 	-rm -rf test-install
-	$(RUNPIKE) $(TMP_BINDIR)/install.pike $(INSTALLARGS) pike_name="test-pike" lib_prefix="$(lib_prefix)" TMP_LIBDIR="$(TMP_LIBDIR)" LIBDIR_SRC="$(LIBDIR_SRC)" SRCDIR="$(SRCDIR)" prefix="./test-install" MANDIR_SRC="$(MANDIR_SRC)" man_prefix="$(man_prefix)" fakeroot="$(buildroot)"
+	$(RUNPIKE) $(TMP_BINDIR)/install.pike $(INSTALLARGS) pike_name="test-pike" lib_prefix="$(lib_prefix)" TMP_LIBDIR="$(TMP_LIBDIR)" LIBDIR_SRC="$(LIBDIR_SRC)" SRCDIR="$(SRCDIR)" prefix="./test-install" MANDIR_SRC="$(MANDIR_SRC)" man_prefix="$(man_prefix)" fakeroot="$(buildroot)" PIKE_MODULE_RELOC="$(PIKE_MODULE_RELOC)"
 
 just-tinstall: aclocal master-stamp aclocal
-	$(RUNPIKE) $(TMP_BINDIR)/install.pike $(INSTALLARGS) pike_name="test-pike" lib_prefix="$(lib_prefix)" TMP_LIBDIR="$(TMP_LIBDIR)" LIBDIR_SRC="$(LIBDIR_SRC)" SRCDIR="$(SRCDIR)" prefix="./test-install" MANDIR_SRC="$(MANDIR_SRC)" man_prefix="$(man_prefix)" fakeroot="$(buildroot)"
+	$(RUNPIKE) $(TMP_BINDIR)/install.pike $(INSTALLARGS) pike_name="test-pike" lib_prefix="$(lib_prefix)" TMP_LIBDIR="$(TMP_LIBDIR)" LIBDIR_SRC="$(LIBDIR_SRC)" SRCDIR="$(SRCDIR)" prefix="./test-install" MANDIR_SRC="$(MANDIR_SRC)" man_prefix="$(man_prefix)" fakeroot="$(buildroot)" PIKE_MODULE_RELOC="$(PIKE_MODULE_RELOC)"
 
 
 verify: module_testsuites testsuite tinstall
@@ -500,8 +501,10 @@ lib: Makefile
 
 master.pike: $(LIBDIR_SRC)/master.pike.in Makefile
 	t="$$PIKE_PATH_TRANSLATE"; if test "x$$t" = "x"; then t=s,x,x,; else :; fi; \
+	if test "x$(PIKE_MODULE_RELOC)" = "x"; then u=s,x,x,; else u='s/^#undef PIKE_MODULE_RELOC/#define PIKE_MODULE_RELOC 1/'; fi; \
 	sed -e 's!�lib_prefix�!'"`echo "$(TMP_LIBDIR)" | sed -e "$$t"`"'!' <$(LIBDIR_SRC)/master.pike.in \
-	  | sed -e 's!�share_prefix�!'"`echo "$(LIBDIR_SRC)" | sed -e "$$t"`"'!' >master.pike
+	  | sed -e 's!�share_prefix�!'"`echo "$(LIBDIR_SRC)" | sed -e "$$t"`"'!' \
+	  | sed -e "$$u" >master.pike
 
 # Want master.pike up-to-date, but yet there's no dependency on the
 # that file. Works like the .h_src.h target.
@@ -551,7 +554,7 @@ bin_export: aclocal
 	exec_prefix="$(exec_prefix)" lib_prefix="$(lib_prefix)" \
 	TMP_LIBDIR="$(TMP_LIBDIR)" LIBDIR_SRC="$(LIBDIR_SRC)" \
 	SRCDIR="$(SRCDIR)" prefix="$(prefix)" MANDIR_SRC="$(MANDIR_SRC)" \
-	man_prefix="$(man_prefix)" pike_name=$(pike_name)
+	man_prefix="$(man_prefix)" pike_name=$(pike_name) PIKE_MODULE_RELOC="$(PIKE_MODULE_RELOC)"
 	@case " $(CC)" in \
 	  *\ rnt*) \
 	    $(MAKE) $(MAKE_FLAGS) uncompress_header ;\
diff --git a/src/configure.in b/src/configure.in
index 5fb180587704c63d0d2dec562fb13b638804f51d..81ea40b1d97d8ce55bd9554a53eb49ed93a70161 100644
--- a/src/configure.in
+++ b/src/configure.in
@@ -1,4 +1,4 @@
-AC_REVISION("$Id: configure.in,v 1.544 2001/08/29 16:11:03 mast Exp $")
+AC_REVISION("$Id: configure.in,v 1.545 2001/09/02 01:36:14 marcus Exp $")
 AC_INIT(interpret.c)
 AC_CONFIG_HEADER(machine.h)
 
@@ -884,6 +884,7 @@ AC_ARG_WITH(root,              [  --with-root=path                 specify a cro
     ;;
   esac
 ],[with_root=""])
+AC_ARG_WITH(relocatable_dumped_modules, [  --with-relocatable-dumped-modules     make dumped modules relocatable],[with_relocatable_dumped_modules=yes],[])
 AC_ARG_WITH(dynamic_modules,   [  --without-dynamic-modules        link modules statically],[],[])
 AC_ARG_WITH(static_linking,    [  --with-static-linking            link statically, if possible],[with_static_linking=yes],[])
 AC_ARG_WITH(include-path,[  --with-include-path    A list of paths to search for include files.])
@@ -1052,6 +1053,13 @@ if test "x$with_thread_trace" = "xyes"; then
   AC_DEFINE(THREAD_TRACE)
 else :; fi
 
+if test "x$with_relocatable_dumped_modules" = xyes; then
+  PIKE_MODULE_RELOC=1
+else
+  PIKE_MODULE_RELOC=""
+fi
+AC_SUBST(PIKE_MODULE_RELOC)
+
 
 #
 # Allow --with(out)-debug to toggle both cdebug and rtldebug, but
@@ -5770,6 +5778,7 @@ PAD_FEATURE([debug])$with_debug
 PAD_FEATURE([dmalloc])$with_dmalloc
 PAD_FEATURE([rtldebug])$with_rtldebug
 PAD_FEATURE([mmx])$with_mmx$mmx_reason
+PAD_FEATURE([module reloc])${with_relocatable_dumped_modules:-no}
 EOF
 
 touch confdefs.h 2>/dev/null
diff --git a/src/dumpmodule.pike b/src/dumpmodule.pike
index 28cfaa8e2e70dff8dced721017d441ffcee48409..323bb7d99096e338ef274add9cfee9b10fee7a0f 100755
--- a/src/dumpmodule.pike
+++ b/src/dumpmodule.pike
@@ -18,19 +18,27 @@ Tools.Install.ProgressBar progress_bar;
 
 mapping function_names=([]);
 
-class __Codec
+static string fixup_path(string x)
 {
-  string last_id;
-
-  static string fixup_path(string x)
-  {
+  if(master()->relocate_module) {
     foreach(master()->pike_module_path, string path) {
       path = combine_path(path, "");
       if(x[..sizeof(path)-1] == path)
-	return "mpath:"+x[sizeof(path)..];
+	return "/${PIKE_MODULE_PATH}/"+x[sizeof(path)..];
+    }
+    /* This is necessary to find compat modules... */
+    foreach(master()->pike_module_path, string path) {
+      path = combine_path(path, "..", "");
+      if(x[..sizeof(path)-1] == path)
+	return "/${PIKE_MODULE_PATH}/../"+x[sizeof(path)..];
     }
-    return x;
   }
+  return x;
+}
+
+class __Codec
+{
+  string last_id;
 
   string nameof(mixed x)
   {
@@ -234,6 +242,15 @@ class Handler
     }
 }
 
+program compile_file(string file, object|void handler)
+{
+  if(master()->relocate_module) {
+    string s = master()->master_read_file(file);
+    return master()->compile_string(s,fixup_path(file), handler);
+  } else
+    return master()->compile_file(file, handler);
+}
+
 void dumpit(string file)
 {
   if(logfile)