patch-2.4.0-test5 linux/arch/ia64/ia32/binfmt_elf32.c
Next file: linux/arch/ia64/ia32/ia32_entry.S
Previous file: linux/arch/ia64/ia32/Makefile
Back to the patch index
Back to the overall index
- Lines: 90
- Date:
Fri Jul 14 16:08:11 2000
- Orig file:
v2.4.0-test4/linux/arch/ia64/ia32/binfmt_elf32.c
- Orig date:
Fri Jun 23 21:55:07 2000
diff -u --recursive --new-file v2.4.0-test4/linux/arch/ia64/ia32/binfmt_elf32.c linux/arch/ia64/ia32/binfmt_elf32.c
@@ -6,7 +6,8 @@
* 06/16/00 A. Mallick initialize csd/ssd/tssd/cflg for ia32_load_state
*/
#include <linux/config.h>
-#include <linux/posix_types.h>
+
+#include <linux/types.h>
#include <asm/signal.h>
#include <asm/ia32.h>
@@ -16,7 +17,9 @@
/* Override some function names */
#undef start_thread
#define start_thread ia32_start_thread
+#define elf_format elf32_format
#define init_elf_binfmt init_elf32_binfmt
+#define exit_elf_binfmt exit_elf32_binfmt
#undef CONFIG_BINFMT_ELF
#ifdef CONFIG_BINFMT_ELF32
@@ -28,10 +31,12 @@
# define CONFIG_BINFMT_ELF_MODULE CONFIG_BINFMT_ELF32_MODULE
#endif
-void ia64_elf32_init(struct pt_regs *regs);
-#define ELF_PLAT_INIT(_r) ia64_elf32_init(_r)
+extern void ia64_elf32_init(struct pt_regs *regs);
+extern void put_dirty_page(struct task_struct * tsk, struct page *page, unsigned long address);
+#define ELF_PLAT_INIT(_r) ia64_elf32_init(_r)
#define setup_arg_pages(bprm) ia32_setup_arg_pages(bprm)
+#define elf_map elf_map32
/* Ugly but avoids duplication */
#include "../../../fs/binfmt_elf.c"
@@ -200,4 +205,54 @@
}
return 0;
+}
+
+static unsigned long
+ia32_mm_addr(unsigned long addr)
+{
+ struct vm_area_struct *vma;
+
+ if ((vma = find_vma(current->mm, addr)) == NULL)
+ return(ELF_PAGESTART(addr));
+ if (vma->vm_start > addr)
+ return(ELF_PAGESTART(addr));
+ return(ELF_PAGEALIGN(addr));
+}
+
+/*
+ * Normally we would do an `mmap' to map in the process's text section.
+ * This doesn't work with IA32 processes as the ELF file might specify
+ * a non page size aligned address. Instead we will just allocate
+ * memory and read the data in from the file. Slightly less efficient
+ * but it works.
+ */
+extern long ia32_do_mmap (struct file *filep, unsigned int len, unsigned int prot,
+ unsigned int flags, unsigned int fd, unsigned int offset);
+
+static unsigned long
+elf_map32 (struct file *filep, unsigned long addr, struct elf_phdr *eppnt, int prot, int type)
+{
+ unsigned long retval;
+
+ if (eppnt->p_memsz >= (1UL<<32) || addr > (1UL<<32) - eppnt->p_memsz)
+ return -EINVAL;
+
+#if 1
+ set_brk(ia32_mm_addr(addr), addr + eppnt->p_memsz);
+ memset((char *) addr + eppnt->p_filesz, 0, eppnt->p_memsz - eppnt->p_filesz);
+ kernel_read(filep, eppnt->p_offset, (char *) addr, eppnt->p_filesz);
+ retval = (unsigned long) addr;
+#else
+ /* doesn't work yet... */
+# define IA32_PAGESTART(_v) ((_v) & ~(unsigned long)(ELF_EXEC_PAGESIZE-1))
+# define IA32_PAGEOFFSET(_v) ((_v) & (ELF_EXEC_PAGESIZE-1))
+# define IA32_PAGEALIGN(_v) (((_v) + ELF_EXEC_PAGESIZE - 1) & ~(ELF_EXEC_PAGESIZE - 1))
+
+ down(¤t->mm->mmap_sem);
+ retval = ia32_do_mmap(filep, IA32_PAGESTART(addr),
+ eppnt->p_filesz + IA32_PAGEOFFSET(eppnt->p_vaddr), prot, type,
+ eppnt->p_offset - IA32_PAGEOFFSET(eppnt->p_vaddr));
+ up(¤t->mm->mmap_sem);
+#endif
+ return retval;
}
FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen (who was at: slshen@lbl.gov)