|
@@ -417,8 +417,8 @@ static int load_flat_file(struct linux_binprm * bprm,
|
|
unsigned long textpos = 0, datapos = 0, result;
|
|
unsigned long textpos = 0, datapos = 0, result;
|
|
unsigned long realdatastart = 0;
|
|
unsigned long realdatastart = 0;
|
|
unsigned long text_len, data_len, bss_len, stack_len, flags;
|
|
unsigned long text_len, data_len, bss_len, stack_len, flags;
|
|
- unsigned long len, reallen, memp = 0;
|
|
|
|
- unsigned long extra, rlim;
|
|
|
|
|
|
+ unsigned long len, memp = 0;
|
|
|
|
+ unsigned long memp_size, extra, rlim;
|
|
unsigned long *reloc = 0, *rp;
|
|
unsigned long *reloc = 0, *rp;
|
|
struct inode *inode;
|
|
struct inode *inode;
|
|
int i, rev, relocs = 0;
|
|
int i, rev, relocs = 0;
|
|
@@ -543,17 +543,10 @@ static int load_flat_file(struct linux_binprm * bprm,
|
|
}
|
|
}
|
|
|
|
|
|
len = data_len + extra + MAX_SHARED_LIBS * sizeof(unsigned long);
|
|
len = data_len + extra + MAX_SHARED_LIBS * sizeof(unsigned long);
|
|
|
|
+ len = PAGE_ALIGN(len);
|
|
down_write(¤t->mm->mmap_sem);
|
|
down_write(¤t->mm->mmap_sem);
|
|
realdatastart = do_mmap(0, 0, len,
|
|
realdatastart = do_mmap(0, 0, len,
|
|
PROT_READ|PROT_WRITE|PROT_EXEC, MAP_PRIVATE, 0);
|
|
PROT_READ|PROT_WRITE|PROT_EXEC, MAP_PRIVATE, 0);
|
|
- /* Remap to use all availabe slack region space */
|
|
|
|
- if (realdatastart && (realdatastart < (unsigned long)-4096)) {
|
|
|
|
- reallen = kobjsize((void *)realdatastart);
|
|
|
|
- if (reallen > len) {
|
|
|
|
- realdatastart = do_mremap(realdatastart, len,
|
|
|
|
- reallen, MREMAP_FIXED, realdatastart);
|
|
|
|
- }
|
|
|
|
- }
|
|
|
|
up_write(¤t->mm->mmap_sem);
|
|
up_write(¤t->mm->mmap_sem);
|
|
|
|
|
|
if (realdatastart == 0 || realdatastart >= (unsigned long)-4096) {
|
|
if (realdatastart == 0 || realdatastart >= (unsigned long)-4096) {
|
|
@@ -591,21 +584,14 @@ static int load_flat_file(struct linux_binprm * bprm,
|
|
|
|
|
|
reloc = (unsigned long *) (datapos+(ntohl(hdr->reloc_start)-text_len));
|
|
reloc = (unsigned long *) (datapos+(ntohl(hdr->reloc_start)-text_len));
|
|
memp = realdatastart;
|
|
memp = realdatastart;
|
|
-
|
|
|
|
|
|
+ memp_size = len;
|
|
} else {
|
|
} else {
|
|
|
|
|
|
len = text_len + data_len + extra + MAX_SHARED_LIBS * sizeof(unsigned long);
|
|
len = text_len + data_len + extra + MAX_SHARED_LIBS * sizeof(unsigned long);
|
|
|
|
+ len = PAGE_ALIGN(len);
|
|
down_write(¤t->mm->mmap_sem);
|
|
down_write(¤t->mm->mmap_sem);
|
|
textpos = do_mmap(0, 0, len,
|
|
textpos = do_mmap(0, 0, len,
|
|
PROT_READ | PROT_EXEC | PROT_WRITE, MAP_PRIVATE, 0);
|
|
PROT_READ | PROT_EXEC | PROT_WRITE, MAP_PRIVATE, 0);
|
|
- /* Remap to use all availabe slack region space */
|
|
|
|
- if (textpos && (textpos < (unsigned long) -4096)) {
|
|
|
|
- reallen = kobjsize((void *)textpos);
|
|
|
|
- if (reallen > len) {
|
|
|
|
- textpos = do_mremap(textpos, len, reallen,
|
|
|
|
- MREMAP_FIXED, textpos);
|
|
|
|
- }
|
|
|
|
- }
|
|
|
|
up_write(¤t->mm->mmap_sem);
|
|
up_write(¤t->mm->mmap_sem);
|
|
|
|
|
|
if (!textpos || textpos >= (unsigned long) -4096) {
|
|
if (!textpos || textpos >= (unsigned long) -4096) {
|
|
@@ -622,7 +608,7 @@ static int load_flat_file(struct linux_binprm * bprm,
|
|
reloc = (unsigned long *) (textpos + ntohl(hdr->reloc_start) +
|
|
reloc = (unsigned long *) (textpos + ntohl(hdr->reloc_start) +
|
|
MAX_SHARED_LIBS * sizeof(unsigned long));
|
|
MAX_SHARED_LIBS * sizeof(unsigned long));
|
|
memp = textpos;
|
|
memp = textpos;
|
|
-
|
|
|
|
|
|
+ memp_size = len;
|
|
#ifdef CONFIG_BINFMT_ZFLAT
|
|
#ifdef CONFIG_BINFMT_ZFLAT
|
|
/*
|
|
/*
|
|
* load it all in and treat it like a RAM load from now on
|
|
* load it all in and treat it like a RAM load from now on
|
|
@@ -680,10 +666,12 @@ static int load_flat_file(struct linux_binprm * bprm,
|
|
* set up the brk stuff, uses any slack left in data/bss/stack
|
|
* set up the brk stuff, uses any slack left in data/bss/stack
|
|
* allocation. We put the brk after the bss (between the bss
|
|
* allocation. We put the brk after the bss (between the bss
|
|
* and stack) like other platforms.
|
|
* and stack) like other platforms.
|
|
|
|
+ * Userspace code relies on the stack pointer starting out at
|
|
|
|
+ * an address right at the end of a page.
|
|
*/
|
|
*/
|
|
current->mm->start_brk = datapos + data_len + bss_len;
|
|
current->mm->start_brk = datapos + data_len + bss_len;
|
|
current->mm->brk = (current->mm->start_brk + 3) & ~3;
|
|
current->mm->brk = (current->mm->start_brk + 3) & ~3;
|
|
- current->mm->context.end_brk = memp + kobjsize((void *) memp) - stack_len;
|
|
|
|
|
|
+ current->mm->context.end_brk = memp + memp_size - stack_len;
|
|
}
|
|
}
|
|
|
|
|
|
if (flags & FLAT_FLAG_KTRACE)
|
|
if (flags & FLAT_FLAG_KTRACE)
|
|
@@ -790,8 +778,8 @@ static int load_flat_file(struct linux_binprm * bprm,
|
|
|
|
|
|
/* zero the BSS, BRK and stack areas */
|
|
/* zero the BSS, BRK and stack areas */
|
|
memset((void*)(datapos + data_len), 0, bss_len +
|
|
memset((void*)(datapos + data_len), 0, bss_len +
|
|
- (memp + kobjsize((void *) memp) - stack_len - /* end brk */
|
|
|
|
- libinfo->lib_list[id].start_brk) + /* start brk */
|
|
|
|
|
|
+ (memp + memp_size - stack_len - /* end brk */
|
|
|
|
+ libinfo->lib_list[id].start_brk) + /* start brk */
|
|
stack_len);
|
|
stack_len);
|
|
|
|
|
|
return 0;
|
|
return 0;
|