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 */