diff -urNp --exclude CVS --exclude BitKeeper --exclude {arch} --exclude .arch-ids x-ref/fs/proc/base.c x/fs/proc/base.c
--- x-ref/fs/proc/base.c	2004-03-11 08:27:41.000000000 +0100
+++ x/fs/proc/base.c	2004-04-06 01:24:58.286949504 +0200
@@ -60,6 +60,7 @@ enum pid_directory_inos {
 	PROC_TGID_MAPS,
 	PROC_TGID_MOUNTS,
 	PROC_TGID_WCHAN,
+	PROC_TGID_MAPBASE,
 #ifdef CONFIG_SECURITY
 	PROC_TGID_ATTR,
 	PROC_TGID_ATTR_CURRENT,
@@ -117,6 +118,9 @@ static struct pid_entry tgid_base_stuff[
 	E(PROC_TGID_ROOT,      "root",    S_IFLNK|S_IRWXUGO),
 	E(PROC_TGID_EXE,       "exe",     S_IFLNK|S_IRWXUGO),
 	E(PROC_TGID_MOUNTS,    "mounts",  S_IFREG|S_IRUGO),
+#ifdef __HAS_ARCH_PROC_MAPPED_BASE
+   	E(PROC_TGID_MAPBASE,	"mapped_base",	S_IFREG|S_IRUSR|S_IWUSR),
+#endif
 #ifdef CONFIG_SECURITY
 	E(PROC_TGID_ATTR,      "attr",    S_IFDIR|S_IRUGO|S_IXUGO),
 #endif
@@ -689,6 +693,55 @@ static struct file_operations proc_mem_o
 	.open		= mem_open,
 };
 
+#ifdef __HAS_ARCH_PROC_MAPPED_BASE
+static ssize_t mapbase_read(struct file * file, char * buf,
+			size_t count, loff_t *ppos)
+{
+	struct task_struct *task = proc_task(file->f_dentry->d_inode);
+	char buffer[64];
+	size_t len;
+
+	len = sprintf(buffer, "%li\n", task->map_base) + 1;
+	if (*ppos >= len)
+		return 0;
+	if (count > len-*ppos)
+		count = len-*ppos;
+	if (copy_to_user(buf, buffer + *ppos, count)) 
+		return -EFAULT;
+	*ppos += count;
+	return count;
+}
+
+static ssize_t mapbase_write(struct file * file, const char * buf,
+			 size_t count, loff_t *ppos)
+{
+	struct task_struct *task = proc_task(file->f_dentry->d_inode);
+	char buffer[64], *end;
+	unsigned long newbase;
+
+	if (!capable(CAP_SYS_ADMIN))
+		return -EPERM;
+	memset(buffer, 0, 64);	
+	if (count > 62)
+		count = 62;
+	if (copy_from_user(buffer, buf, count)) 
+		return -EFAULT;
+	newbase = simple_strtoul(buffer, &end, 0);
+	if (*end == '\n')
+		end++;
+	if (newbase > 0)
+		task->map_base = newbase;
+	if (end - buffer == 0) 
+		return -EIO;
+	return end - buffer;
+}
+
+static struct file_operations proc_mapbase_operations = {
+	read:		mapbase_read,
+	write:		mapbase_write,
+};
+#endif /* __HAS_ARCH_PROC_MAPPED_BASE */
+
 static struct inode_operations proc_mem_inode_operations = {
 	.permission	= proc_permission,
 };
@@ -1353,6 +1406,11 @@ static struct dentry *proc_pident_lookup
 		case PROC_TGID_MAPS:
 			inode->i_fop = &proc_maps_operations;
 			break;
+#ifdef __HAS_ARCH_PROC_MAPPED_BASE
+ 		case PROC_TGID_MAPBASE:
+ 			inode->i_fop = &proc_mapbase_operations;
+ 			break;
+#endif
 		case PROC_TID_MEM:
 		case PROC_TGID_MEM:
 			inode->i_op = &proc_mem_inode_operations;
diff -urNp --exclude CVS --exclude BitKeeper --exclude {arch} --exclude .arch-ids x-ref/include/asm-i386/processor.h x/include/asm-i386/processor.h
--- x-ref/include/asm-i386/processor.h	2004-03-11 08:27:42.000000000 +0100
+++ x/include/asm-i386/processor.h	2004-04-06 01:24:58.284949808 +0200
@@ -299,7 +299,8 @@ extern unsigned int mca_pentium_flag;
 /* This decides where the kernel will search for a free chunk of vm
  * space during mmap's.
  */
-#define TASK_UNMAPPED_BASE	(PAGE_ALIGN(TASK_SIZE / 3))
+#define TASK_UNMAPPED_BASE	(current->map_base)
+#define __TASK_UNMAPPED_BASE PAGE_ALIGN(TASK_SIZE/3)
 
 /*
  * Size of io_bitmap, covering ports 0 to 0x3ff.
diff -urNp --exclude CVS --exclude BitKeeper --exclude {arch} --exclude .arch-ids x-ref/include/asm-s390/processor.h x/include/asm-s390/processor.h
--- x-ref/include/asm-s390/processor.h	2004-04-04 08:09:29.000000000 +0200
+++ x/include/asm-s390/processor.h	2004-04-06 01:24:58.283949960 +0200
@@ -62,7 +62,9 @@ extern struct task_struct *last_task_use
 #ifndef __s390x__
 
 # define TASK_SIZE		(0x80000000UL)
-# define TASK_UNMAPPED_BASE	(TASK_SIZE / 2)
+# define TASK_UNMAPPED_BASE (current->map_base)
+# define __TASK_UNMAPPED_BASE	(TASK_SIZE / 2)
+
 
 #else /* __s390x__ */
 
diff -urNp --exclude CVS --exclude BitKeeper --exclude {arch} --exclude .arch-ids x-ref/include/asm-um/processor-generic.h x/include/asm-um/processor-generic.h
--- x-ref/include/asm-um/processor-generic.h	2004-04-04 08:09:30.000000000 +0200
+++ x/include/asm-um/processor-generic.h	2004-04-06 01:24:58.283949960 +0200
@@ -119,7 +119,8 @@ extern unsigned long task_size;
 /* This decides where the kernel will search for a free chunk of vm
  * space during mmap's.
  */
-#define TASK_UNMAPPED_BASE	(0x40000000)
+#define __TASK_UNMAPPED_BASE	(0x40000000)
+#define TASK_UNMAPPED_BASE	(current->map_base)
 
 extern void start_thread(struct pt_regs *regs, unsigned long entry, 
 			 unsigned long stack);
diff -urNp --exclude CVS --exclude BitKeeper --exclude {arch} --exclude .arch-ids x-ref/include/asm-x86_64/processor.h x/include/asm-x86_64/processor.h
--- x-ref/include/asm-x86_64/processor.h	2004-04-04 08:09:31.000000000 +0200
+++ x/include/asm-x86_64/processor.h	2004-04-06 01:24:58.279950568 +0200
@@ -171,9 +171,14 @@ static inline void clear_in_cr4 (unsigne
 
 /* This decides where the kernel will search for a free chunk of vm
  * space during mmap's.
+ *
+ * /proc/pid/unmap_base is only supported for 32bit processes without
+ * 3GB personality for now.
  */
 #define IA32_PAGE_OFFSET ((current->personality & ADDR_LIMIT_3GB) ? 0xc0000000 : 0xFFFFe000)
-#define TASK_UNMAPPED_32 PAGE_ALIGN(IA32_PAGE_OFFSET/3)
+#define __TASK_UNMAPPED_BASE (PAGE_ALIGN(0xffffe000 / 3))
+#define TASK_UNMAPPED_32 ((current->personality & ADDR_LIMIT_3GB) ? \
+	PAGE_ALIGN(0xc0000000 / 3) : PAGE_ALIGN(current->map_base))
 #define TASK_UNMAPPED_64 PAGE_ALIGN(TASK_SIZE/3) 
 #define TASK_UNMAPPED_BASE	\
 	(test_thread_flag(TIF_IA32) ? TASK_UNMAPPED_32 : TASK_UNMAPPED_64)  
diff -urNp --exclude CVS --exclude BitKeeper --exclude {arch} --exclude .arch-ids x-ref/include/linux/init_task.h x/include/linux/init_task.h
--- x-ref/include/linux/init_task.h	2004-03-11 08:27:46.000000000 +0100
+++ x/include/linux/init_task.h	2004-04-06 01:27:23.683845816 +0200
@@ -112,6 +112,7 @@ extern struct group_info init_groups;
 	.proc_lock	= SPIN_LOCK_UNLOCKED,				\
 	.switch_lock	= SPIN_LOCK_UNLOCKED,				\
 	.journal_info	= NULL,						\
+	.map_base	= __TASK_UNMAPPED_BASE,				\
 }
 
 
diff -urNp --exclude CVS --exclude BitKeeper --exclude {arch} --exclude .arch-ids x-ref/include/linux/sched.h x/include/linux/sched.h
--- x-ref/include/linux/sched.h	2004-04-06 01:24:52.363849952 +0200
+++ x/include/linux/sched.h	2004-04-06 01:27:12.920482096 +0200
@@ -493,6 +493,9 @@ struct task_struct {
 
 	unsigned long ptrace_message;
 	siginfo_t *last_siginfo; /* For ptrace use.  */
+
+/* TASK_UNMAPPED_BASE */
+	unsigned long map_base;
 };
 
 static inline pid_t process_group(struct task_struct *tsk)
@@ -505,6 +508,12 @@ extern void __put_task_struct(struct tas
 #define put_task_struct(tsk) \
 do { if (atomic_dec_and_test(&(tsk)->usage)) __put_task_struct(tsk); } while(0)
 
+#ifndef __TASK_UNMAPPED_BASE
+#define __TASK_UNMAPPED_BASE 0UL
+#else
+#define __HAS_ARCH_PROC_MAPPED_BASE
+#endif
+
 /*
  * Per process flags
  */