patch-2.0.11 linux/fs/binfmt_elf.c
Next file: linux/fs/fat/inode.c
Previous file: linux/drivers/sound/sequencer.c
Back to the patch index
Back to the overall index
- Lines: 750
- Date:
Sun Aug 4 14:18:59 1996
- Orig file:
v2.0.10/linux/fs/binfmt_elf.c
- Orig date:
Sun Apr 14 11:14:43 1996
diff -u --recursive --new-file v2.0.10/linux/fs/binfmt_elf.c linux/fs/binfmt_elf.c
@@ -39,8 +39,21 @@
static int load_elf_binary(struct linux_binprm * bprm, struct pt_regs * regs);
static int load_elf_library(int fd);
+extern int dump_fpu (struct pt_regs *, elf_fpregset_t *);
+extern void dump_thread(struct pt_regs *, struct user *);
+
+/*
+ * If we don't support core dumping, then supply a NULL so we
+ * don't even try.
+ */
+#ifdef USE_ELF_CORE_DUMP
static int elf_core_dump(long signr, struct pt_regs * regs);
-extern int dump_fpu (elf_fpregset_t *);
+#else
+#define elf_core_dump NULL
+#endif
+
+#define ELF_PAGESTART(_v) ((_v) & ~(unsigned long)(ELF_EXEC_PAGESIZE-1))
+#define ELF_PAGEOFFSET(_v) ((_v) & (ELF_EXEC_PAGESIZE-1))
static struct linux_binfmt elf_format = {
#ifndef MODULE
@@ -90,12 +103,18 @@
}
}
-unsigned long * create_elf_tables(char * p,int argc,int envc,struct elfhdr * exec, unsigned int load_addr, unsigned int interp_load_addr, int ibcs)
+unsigned long * create_elf_tables(char *p, int argc, int envc,
+ struct elfhdr * exec,
+ unsigned long load_addr,
+ unsigned long interp_load_addr, int ibcs)
{
- unsigned long *argv,*envp, *dlinfo;
- unsigned long * sp;
+ unsigned long *argv, *envp, *dlinfo;
+ unsigned long *sp;
- sp = (unsigned long *) (0xfffffffc & (unsigned long) p);
+ /*
+ * Force 16 byte alignment here for generality.
+ */
+ sp = (unsigned long *) (~15UL & (unsigned long) p);
sp -= exec ? DLINFO_ITEMS*2 : 2;
dlinfo = sp;
sp -= envc+1;
@@ -110,7 +129,8 @@
#define NEW_AUX_ENT(id, val) \
put_user ((id), dlinfo++); \
put_user ((val), dlinfo++)
- if(exec) { /* Put this here for an ELF program interpreter */
+
+ if (exec) { /* Put this here for an ELF program interpreter */
struct elf_phdr * eppnt;
eppnt = (struct elf_phdr *) exec->e_phoff;
@@ -128,7 +148,6 @@
}
NEW_AUX_ENT (AT_NULL, 0);
#undef NEW_AUX_ENT
-
put_user((unsigned long)argc,--sp);
current->mm->arg_start = (unsigned long) p;
while (argc-->0) {
@@ -152,72 +171,79 @@
is only provided so that we can read a.out libraries that have
an ELF header */
-static unsigned int load_elf_interp(struct elfhdr * interp_elf_ex,
- struct inode * interpreter_inode, unsigned int *interp_load_addr)
+static unsigned long load_elf_interp(struct elfhdr * interp_elf_ex,
+ struct inode * interpreter_inode,
+ unsigned long *interp_load_addr)
{
struct file * file;
struct elf_phdr *elf_phdata = NULL;
struct elf_phdr *eppnt;
- unsigned int len;
- unsigned int load_addr;
+ unsigned long load_addr;
int elf_exec_fileno;
- int elf_bss;
int retval;
- unsigned int last_bss;
- int error;
+ unsigned long last_bss, elf_bss;
+ unsigned long error;
int i;
- unsigned int k;
elf_bss = 0;
last_bss = 0;
error = load_addr = 0;
/* First of all, some simple consistency checks */
- if((interp_elf_ex->e_type != ET_EXEC &&
+ if ((interp_elf_ex->e_type != ET_EXEC &&
interp_elf_ex->e_type != ET_DYN) ||
- (interp_elf_ex->e_machine != EM_386 && interp_elf_ex->e_machine != EM_486) ||
+ !elf_check_arch(interp_elf_ex->e_machine) ||
(!interpreter_inode->i_op ||
!interpreter_inode->i_op->default_file_ops->mmap)){
- return 0xffffffff;
+ return ~0UL;
}
/* Now read in all of the header information */
- if(sizeof(struct elf_phdr) * interp_elf_ex->e_phnum > PAGE_SIZE)
- return 0xffffffff;
+ if (sizeof(struct elf_phdr) * interp_elf_ex->e_phnum > PAGE_SIZE)
+ return ~0UL;
elf_phdata = (struct elf_phdr *)
- kmalloc(sizeof(struct elf_phdr) * interp_elf_ex->e_phnum, GFP_KERNEL);
- if(!elf_phdata)
- return 0xffffffff;
+ kmalloc(sizeof(struct elf_phdr) * interp_elf_ex->e_phnum,
+ GFP_KERNEL);
+ if (!elf_phdata)
+ return ~0UL;
/*
* If the size of this structure has changed, then punt, since
* we will be doing the wrong thing.
*/
- if( interp_elf_ex->e_phentsize != 32 )
+ if (interp_elf_ex->e_phentsize != sizeof(struct elf_phdr))
{
kfree(elf_phdata);
- return 0xffffffff;
+ return ~0UL;
}
- retval = read_exec(interpreter_inode, interp_elf_ex->e_phoff, (char *) elf_phdata,
+ retval = read_exec(interpreter_inode, interp_elf_ex->e_phoff,
+ (char *) elf_phdata,
sizeof(struct elf_phdr) * interp_elf_ex->e_phnum, 1);
+ if (retval < 0) {
+ kfree (elf_phdata);
+ return retval;
+ }
+
elf_exec_fileno = open_inode(interpreter_inode, O_RDONLY);
if (elf_exec_fileno < 0) {
kfree(elf_phdata);
- return 0xffffffff;
+ return ~0UL;
}
file = current->files->fd[elf_exec_fileno];
eppnt = elf_phdata;
for(i=0; i<interp_elf_ex->e_phnum; i++, eppnt++)
- if(eppnt->p_type == PT_LOAD) {
+ if (eppnt->p_type == PT_LOAD) {
int elf_type = MAP_PRIVATE | MAP_DENYWRITE;
int elf_prot = 0;
unsigned long vaddr = 0;
+ unsigned long k;
+
if (eppnt->p_flags & PF_R) elf_prot = PROT_READ;
if (eppnt->p_flags & PF_W) elf_prot |= PROT_WRITE;
if (eppnt->p_flags & PF_X) elf_prot |= PROT_EXEC;
@@ -227,15 +253,20 @@
}
error = do_mmap(file,
- load_addr + (vaddr & 0xfffff000),
- eppnt->p_filesz + (eppnt->p_vaddr & 0xfff),
+ load_addr + ELF_PAGESTART(vaddr),
+ eppnt->p_filesz + ELF_PAGEOFFSET(eppnt->p_vaddr),
elf_prot,
elf_type,
- eppnt->p_offset & 0xfffff000);
+ ELF_PAGESTART(eppnt->p_offset));
- if(error < 0 && error > -1024) break; /* Real error */
+ if (error > -1024UL) {
+ /* Real error */
+ sys_close(elf_exec_fileno);
+ kfree(elf_phdata);
+ return ~0UL;
+ }
- if(!load_addr && interp_elf_ex->e_type == ET_DYN)
+ if (!load_addr && interp_elf_ex->e_type == ET_DYN)
load_addr = error;
/*
@@ -243,23 +274,19 @@
* track of the largest address we see for this.
*/
k = load_addr + eppnt->p_vaddr + eppnt->p_filesz;
- if(k > elf_bss) elf_bss = k;
+ if (k > elf_bss) elf_bss = k;
/*
* Do the same thing for the memory mapping - between
* elf_bss and last_bss is the bss section.
*/
k = load_addr + eppnt->p_memsz + eppnt->p_vaddr;
- if(k > last_bss) last_bss = k;
+ if (k > last_bss) last_bss = k;
}
/* Now use mmap to map the library into memory. */
sys_close(elf_exec_fileno);
- if(error < 0 && error > -1024) {
- kfree(elf_phdata);
- return 0xffffffff;
- }
/*
* Now fill out the bss section. First pad the last page up
@@ -268,24 +295,24 @@
* bss page.
*/
padzero(elf_bss);
- len = (elf_bss + 0xfff) & 0xfffff000; /* What we have mapped so far */
+ elf_bss = ELF_PAGESTART(elf_bss + ELF_EXEC_PAGESIZE - 1); /* What we have mapped so far */
/* Map the last of the bss segment */
- if (last_bss > len)
- do_mmap(NULL, len, last_bss-len,
+ if (last_bss > elf_bss)
+ do_mmap(NULL, elf_bss, last_bss-elf_bss,
PROT_READ|PROT_WRITE|PROT_EXEC,
MAP_FIXED|MAP_PRIVATE, 0);
kfree(elf_phdata);
*interp_load_addr = load_addr;
- return ((unsigned int) interp_elf_ex->e_entry) + load_addr;
+ return ((unsigned long) interp_elf_ex->e_entry) + load_addr;
}
-static unsigned int load_aout_interp(struct exec * interp_ex,
+static unsigned long load_aout_interp(struct exec * interp_ex,
struct inode * interpreter_inode)
{
int retval;
- unsigned int elf_entry;
+ unsigned long elf_entry;
current->mm->brk = interp_ex->a_bss +
(current->mm->end_data = interp_ex->a_data +
@@ -310,12 +337,12 @@
} else
retval = -1;
- if(retval >= 0)
- do_mmap(NULL, (interp_ex->a_text + interp_ex->a_data + 0xfff) &
- 0xfffff000, interp_ex->a_bss,
+ if (retval >= 0)
+ do_mmap(NULL, ELF_PAGESTART(interp_ex->a_text + interp_ex->a_data + ELF_EXEC_PAGESIZE - 1),
+ interp_ex->a_bss,
PROT_READ|PROT_WRITE|PROT_EXEC,
MAP_FIXED|MAP_PRIVATE, 0);
- if(retval < 0) return 0xffffffff;
+ if (retval < 0) return ~0UL;
return elf_entry;
}
@@ -337,7 +364,7 @@
struct file * file;
struct exec interp_ex;
struct inode *interpreter_inode;
- unsigned int load_addr;
+ unsigned long load_addr;
unsigned int interpreter_type = INTERPRETER_NONE;
unsigned char ibcs2_interpreter;
int i;
@@ -345,13 +372,13 @@
int error;
struct elf_phdr * elf_ppnt, *elf_phdata;
int elf_exec_fileno;
- unsigned int elf_bss, k, elf_brk;
+ unsigned long elf_bss, k, elf_brk;
int retval;
char * elf_interpreter;
- unsigned int elf_entry, interp_load_addr = 0;
+ unsigned long elf_entry, interp_load_addr = 0;
int status;
- unsigned int start_code, end_code, end_data;
- unsigned int elf_stack;
+ unsigned long start_code, end_code, end_data;
+ unsigned long elf_stack;
char passed_fileno[6];
ibcs2_interpreter = 0;
@@ -366,9 +393,9 @@
/* First of all, some simple consistency checks */
- if((elf_ex.e_type != ET_EXEC &&
+ if ((elf_ex.e_type != ET_EXEC &&
elf_ex.e_type != ET_DYN) ||
- (elf_ex.e_machine != EM_386 && elf_ex.e_machine != EM_486) ||
+ (! elf_check_arch(elf_ex.e_machine)) ||
(!bprm->inode->i_op || !bprm->inode->i_op->default_file_ops ||
!bprm->inode->i_op->default_file_ops->mmap)){
return -ENOEXEC;
@@ -403,15 +430,15 @@
file = current->files->fd[elf_exec_fileno];
- elf_stack = 0xffffffff;
+ elf_stack = ~0UL;
elf_interpreter = NULL;
- start_code = 0xffffffff;
+ start_code = ~0UL;
end_code = 0;
end_data = 0;
for(i=0;i < elf_ex.e_phnum; i++){
- if(elf_ppnt->p_type == PT_INTERP) {
- if( elf_interpreter != NULL )
+ if (elf_ppnt->p_type == PT_INTERP) {
+ if ( elf_interpreter != NULL )
{
kfree (elf_phdata);
kfree(elf_interpreter);
@@ -432,7 +459,8 @@
return -ENOMEM;
}
- retval = read_exec(bprm->inode,elf_ppnt->p_offset,elf_interpreter,
+ retval = read_exec(bprm->inode,elf_ppnt->p_offset,
+ elf_interpreter,
elf_ppnt->p_filesz, 1);
/* If the program interpreter is one of these two,
then assume an iBCS2 image. Otherwise assume
@@ -443,22 +471,23 @@
#if 0
printk("Using ELF interpreter %s\n", elf_interpreter);
#endif
- if(retval >= 0) {
+ if (retval >= 0) {
old_fs = get_fs(); /* This could probably be optimized */
set_fs(get_ds());
- retval = namei(elf_interpreter, &interpreter_inode);
+ retval = open_namei(elf_interpreter, 0, 0,
+ &interpreter_inode, NULL);
set_fs(old_fs);
}
- if(retval >= 0)
+ if (retval >= 0)
retval = read_exec(interpreter_inode,0,bprm->buf,128, 1);
- if(retval >= 0) {
+ if (retval >= 0) {
interp_ex = *((struct exec *) bprm->buf); /* exec-header */
interp_elf_ex = *((struct elfhdr *) bprm->buf); /* exec-header */
}
- if(retval < 0) {
+ if (retval < 0) {
kfree (elf_phdata);
kfree(elf_interpreter);
sys_close(elf_exec_fileno);
@@ -467,22 +496,22 @@
}
elf_ppnt++;
}
-
+
/* Some simple consistency checks for the interpreter */
- if(elf_interpreter){
+ if (elf_interpreter){
interpreter_type = INTERPRETER_ELF | INTERPRETER_AOUT;
/* Now figure out which format our binary is */
- if((N_MAGIC(interp_ex) != OMAGIC) &&
- (N_MAGIC(interp_ex) != ZMAGIC) &&
- (N_MAGIC(interp_ex) != QMAGIC))
+ if ((N_MAGIC(interp_ex) != OMAGIC) &&
+ (N_MAGIC(interp_ex) != ZMAGIC) &&
+ (N_MAGIC(interp_ex) != QMAGIC))
interpreter_type = INTERPRETER_ELF;
if (interp_elf_ex.e_ident[0] != 0x7f ||
strncmp(&interp_elf_ex.e_ident[1], "ELF",3) != 0)
interpreter_type &= ~INTERPRETER_ELF;
- if(!interpreter_type)
+ if (!interpreter_type)
{
kfree(elf_interpreter);
kfree(elf_phdata);
@@ -497,17 +526,17 @@
if (!bprm->sh_bang) {
char * passed_p;
- if(interpreter_type == INTERPRETER_AOUT) {
+ if (interpreter_type == INTERPRETER_AOUT) {
sprintf(passed_fileno, "%d", elf_exec_fileno);
passed_p = passed_fileno;
- if(elf_interpreter) {
+ if (elf_interpreter) {
bprm->p = copy_strings(1,&passed_p,bprm->page,bprm->p,2);
bprm->argc++;
}
}
if (!bprm->p) {
- if(elf_interpreter) {
+ if (elf_interpreter) {
kfree(elf_interpreter);
}
kfree (elf_phdata);
@@ -523,7 +552,7 @@
current->mm->end_code = 0;
current->mm->start_mmap = ELF_START_MMAP;
current->mm->mmap = NULL;
- elf_entry = (unsigned int) elf_ex.e_entry;
+ elf_entry = (unsigned long) elf_ex.e_entry;
/* Do this so that we can load the interpreter, if need be. We will
change some of these later */
@@ -538,76 +567,69 @@
old_fs = get_fs();
set_fs(get_ds());
-
- elf_ppnt = elf_phdata;
- for(i=0;i < elf_ex.e_phnum; i++){
-
- if(elf_ppnt->p_type == PT_INTERP) {
- /* Set these up so that we are able to load the interpreter */
- /* Now load the interpreter into user address space */
- set_fs(old_fs);
-
- if(interpreter_type & 1) elf_entry =
- load_aout_interp(&interp_ex, interpreter_inode);
-
- if(interpreter_type & 2) elf_entry =
- load_elf_interp(&interp_elf_ex, interpreter_inode, &interp_load_addr);
-
- old_fs = get_fs();
- set_fs(get_ds());
-
- iput(interpreter_inode);
- kfree(elf_interpreter);
-
- if(elf_entry == 0xffffffff) {
- set_fs(old_fs);
- printk("Unable to load interpreter\n");
- kfree(elf_phdata);
- send_sig(SIGSEGV, current, 0);
- return 0;
- }
- }
-
-
- if(elf_ppnt->p_type == PT_LOAD) {
- int elf_prot = (elf_ppnt->p_flags & PF_R) ? PROT_READ : 0;
+ for(i = 0, elf_ppnt = elf_phdata; i < elf_ex.e_phnum; i++, elf_ppnt++) {
+ if (elf_ppnt->p_type == PT_LOAD) {
+ int elf_prot = 0;
+ if (elf_ppnt->p_flags & PF_R) elf_prot |= PROT_READ;
if (elf_ppnt->p_flags & PF_W) elf_prot |= PROT_WRITE;
if (elf_ppnt->p_flags & PF_X) elf_prot |= PROT_EXEC;
+
error = do_mmap(file,
- elf_ppnt->p_vaddr & 0xfffff000,
- elf_ppnt->p_filesz + (elf_ppnt->p_vaddr & 0xfff),
+ ELF_PAGESTART(elf_ppnt->p_vaddr),
+ (elf_ppnt->p_filesz +
+ ELF_PAGEOFFSET(elf_ppnt->p_vaddr)),
elf_prot,
- MAP_FIXED | MAP_PRIVATE | MAP_DENYWRITE | MAP_EXECUTABLE,
- elf_ppnt->p_offset & 0xfffff000);
+ (MAP_FIXED | MAP_PRIVATE |
+ MAP_DENYWRITE | MAP_EXECUTABLE),
+ ELF_PAGESTART(elf_ppnt->p_offset));
#ifdef LOW_ELF_STACK
- if((elf_ppnt->p_vaddr & 0xfffff000) < elf_stack)
- elf_stack = elf_ppnt->p_vaddr & 0xfffff000;
+ if (ELF_PAGESTART(elf_ppnt->p_vaddr) < elf_stack)
+ elf_stack = ELF_PAGESTART(elf_ppnt->p_vaddr);
#endif
- if(!load_addr)
+ if (!load_addr)
load_addr = elf_ppnt->p_vaddr - elf_ppnt->p_offset;
k = elf_ppnt->p_vaddr;
- if(k < start_code) start_code = k;
+ if (k < start_code) start_code = k;
k = elf_ppnt->p_vaddr + elf_ppnt->p_filesz;
- if(k > elf_bss) elf_bss = k;
+ if (k > elf_bss) elf_bss = k;
#if 1
- if((elf_ppnt->p_flags & PF_X) && end_code < k)
+ if ((elf_ppnt->p_flags & PF_X) && end_code < k)
#else
- if( !(elf_ppnt->p_flags & PF_W) && end_code < k)
+ if ( !(elf_ppnt->p_flags & PF_W) && end_code < k)
#endif
end_code = k;
- if(end_data < k) end_data = k;
+ if (end_data < k) end_data = k;
k = elf_ppnt->p_vaddr + elf_ppnt->p_memsz;
- if(k > elf_brk) elf_brk = k;
- }
- elf_ppnt++;
+ if (k > elf_brk) elf_brk = k;
+ }
}
set_fs(old_fs);
-
+
+ if (elf_interpreter) {
+ if (interpreter_type & 1)
+ elf_entry = load_aout_interp(&interp_ex,
+ interpreter_inode);
+ else if (interpreter_type & 2)
+ elf_entry = load_elf_interp(&interp_elf_ex,
+ interpreter_inode,
+ &interp_load_addr);
+
+ iput(interpreter_inode);
+ kfree(elf_interpreter);
+
+ if (elf_entry == ~0UL) {
+ printk("Unable to load interpreter\n");
+ kfree(elf_phdata);
+ send_sig(SIGSEGV, current, 0);
+ return 0;
+ }
+ }
+
kfree(elf_phdata);
- if(interpreter_type != INTERPRETER_AOUT) sys_close(elf_exec_fileno);
+ if (interpreter_type != INTERPRETER_AOUT) sys_close(elf_exec_fileno);
current->personality = (ibcs2_interpreter ? PER_SVR4 : PER_LINUX);
if (current->exec_domain && current->exec_domain->use_count)
@@ -639,7 +661,7 @@
load_addr,
interp_load_addr,
(interpreter_type == INTERPRETER_AOUT ? 0 : 1));
- if(interpreter_type == INTERPRETER_AOUT)
+ if (interpreter_type == INTERPRETER_AOUT)
current->mm->arg_start += strlen(passed_fileno) + 1;
current->mm->start_brk = current->mm->brk = elf_brk;
current->mm->end_code = end_code;
@@ -662,7 +684,7 @@
printk("(brk) %x\n" , current->mm->brk);
#endif
- if( current->personality == PER_SVR4 )
+ if ( current->personality == PER_SVR4 )
{
/* Why this, you ask??? Well SVr4 maps page 0 as read-only,
and some applications "depend" upon this behavior.
@@ -672,14 +694,16 @@
MAP_FIXED | MAP_PRIVATE, 0);
}
- /* SVR4/i386 ABI (pages 3-31, 3-32) says that when the program
- starts %edx contains a pointer to a function which might be
- registered using `atexit'. This provides a mean for the
- dynamic linker to call DT_FINI functions for shared libraries
- that have been loaded before the code runs.
+#ifdef ELF_PLAT_INIT
+ /*
+ * The ABI may specify that certain registers be set up in special
+ * ways (on i386 %edx is the address of a DT_FINI function, for
+ * example. This macro performs whatever initialization to
+ * the regs structure is required.
+ */
+ ELF_PLAT_INIT(regs);
+#endif
- A value of 0 tells we have no such handler. */
- regs->edx = 0;
start_thread(regs, elf_entry, bprm->p);
if (current->flags & PF_PTRACED)
@@ -707,10 +731,10 @@
struct elfhdr elf_ex;
struct elf_phdr *elf_phdata = NULL;
struct inode * inode;
- unsigned int len;
+ unsigned long len;
int elf_bss;
int retval;
- unsigned int bss;
+ unsigned long bss;
int error;
int i,j, k;
@@ -740,14 +764,14 @@
return -ENOEXEC;
/* First of all, some simple consistency checks */
- if(elf_ex.e_type != ET_EXEC || elf_ex.e_phnum > 2 ||
+ if (elf_ex.e_type != ET_EXEC || elf_ex.e_phnum > 2 ||
(elf_ex.e_machine != EM_386 && elf_ex.e_machine != EM_486) ||
(!inode->i_op || !inode->i_op->default_file_ops->mmap))
return -ENOEXEC;
/* Now read in all of the header information */
- if(sizeof(struct elf_phdr) * elf_ex.e_phnum > PAGE_SIZE)
+ if (sizeof(struct elf_phdr) * elf_ex.e_phnum > PAGE_SIZE)
return -ENOEXEC;
elf_phdata = (struct elf_phdr *)
@@ -760,9 +784,9 @@
j = 0;
for(i=0; i<elf_ex.e_phnum; i++)
- if((elf_phdata + i)->p_type == PT_LOAD) j++;
+ if ((elf_phdata + i)->p_type == PT_LOAD) j++;
- if(j != 1) {
+ if (j != 1) {
kfree(elf_phdata);
return -ENOEXEC;
}
@@ -771,23 +795,23 @@
/* Now use mmap to map the library into memory. */
error = do_mmap(file,
- elf_phdata->p_vaddr & 0xfffff000,
- elf_phdata->p_filesz + (elf_phdata->p_vaddr & 0xfff),
+ ELF_PAGESTART(elf_phdata->p_vaddr),
+ elf_phdata->p_filesz + ELF_PAGEOFFSET(elf_phdata->p_vaddr),
PROT_READ | PROT_WRITE | PROT_EXEC,
MAP_FIXED | MAP_PRIVATE | MAP_DENYWRITE,
- elf_phdata->p_offset & 0xfffff000);
+ ELF_PAGESTART(elf_phdata->p_offset));
k = elf_phdata->p_vaddr + elf_phdata->p_filesz;
- if(k > elf_bss) elf_bss = k;
+ if (k > elf_bss) elf_bss = k;
- if (error != (elf_phdata->p_vaddr & 0xfffff000)) {
+ if (error != ELF_PAGESTART(elf_phdata->p_vaddr)) {
kfree(elf_phdata);
return error;
}
padzero(elf_bss);
- len = (elf_phdata->p_filesz + elf_phdata->p_vaddr+ 0xfff) & 0xfffff000;
+ len = ELF_PAGESTART(elf_phdata->p_filesz + elf_phdata->p_vaddr+ ELF_EXEC_PAGESIZE - 1);
bss = elf_phdata->p_memsz + elf_phdata->p_vaddr;
if (bss > len)
do_mmap(NULL, len, bss-len,
@@ -806,7 +830,13 @@
MOD_DEC_USE_COUNT;
return retval;
}
-
+
+/*
+ * Note that some platforms still use traditional core dumps and not
+ * the ELF core dump. Each platform can select it as appropriate.
+ */
+#ifdef USE_ELF_CORE_DUMP
+
/*
* ELF core dumper
*
@@ -982,13 +1012,13 @@
/* Set up header */
memcpy(elf.e_ident, ELFMAG, SELFMAG);
- elf.e_ident[EI_CLASS] = ELFCLASS32;
- elf.e_ident[EI_DATA] = ELFDATA2LSB;
+ elf.e_ident[EI_CLASS] = ELF_CLASS;
+ elf.e_ident[EI_DATA] = ELF_DATA;
elf.e_ident[EI_VERSION] = EV_CURRENT;
memset(elf.e_ident+EI_PAD, 0, EI_NIDENT-EI_PAD);
elf.e_type = ET_CORE;
- elf.e_machine = EM_386;
+ elf.e_machine = ELF_ARCH;
elf.e_version = EV_CURRENT;
elf.e_entry = 0;
elf.e_phoff = sizeof(elf);
@@ -1062,6 +1092,14 @@
prstatus.pr_cutime.tv_usec = CT_TO_USECS(current->cutime);
prstatus.pr_cstime.tv_sec = CT_TO_SECS(current->cstime);
prstatus.pr_cstime.tv_usec = CT_TO_USECS(current->cstime);
+
+ /*
+ * This transfers the registers from regs into the standard
+ * coredump arrangement, whatever that is.
+ */
+#ifdef ELF_CORE_COPY_REGS
+ ELF_CORE_COPY_REGS(prstatus.pr_reg, regs)
+#else
if (sizeof(elf_gregset_t) != sizeof(struct pt_regs))
{
printk("sizeof(elf_gregset_t) (%d) != sizeof(struct pt_regs) (%d)\n",
@@ -1069,6 +1107,7 @@
}
else
*(struct pt_regs *)&prstatus.pr_reg = *regs;
+#endif
#ifdef DEBUG
dump_regs("Passed in regs", (elf_greg_t *)regs);
@@ -1110,7 +1149,7 @@
notes[2].data = current;
/* Try to dump the fpu. */
- prstatus.pr_fpvalid = dump_fpu (&fpu);
+ prstatus.pr_fpvalid = dump_fpu (regs, &fpu);
if (!prstatus.pr_fpvalid)
{
numnote--;
@@ -1213,14 +1252,17 @@
#endif
return has_dumped;
}
+#endif /* USE_ELF_CORE_DUMP */
-int init_elf_binfmt(void) {
+int init_elf_binfmt(void)
+{
return register_binfmt(&elf_format);
}
#ifdef MODULE
-int init_module(void) {
+int init_module(void)
+{
/* Install the COFF, ELF and XOUT loaders.
* N.B. We *rely* on the table being the right size with the
* right number of free slots...
@@ -1229,7 +1271,8 @@
}
-void cleanup_module( void) {
+void cleanup_module( void)
+{
/* Remove the COFF and ELF loaders. */
unregister_binfmt(&elf_format);
}
FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen, slshen@lbl.gov