From owner-p4-projects Thu May 2 6: 2:24 2002 Delivered-To: p4-projects@freebsd.org Received: by hub.freebsd.org (Postfix, from userid 32767) id 8F93837B41A; Thu, 2 May 2002 06:00:28 -0700 (PDT) Delivered-To: perforce@freebsd.org Received: from freefall.freebsd.org (freefall.FreeBSD.org [216.136.204.21]) by hub.freebsd.org (Postfix) with ESMTP id 9B7F237B41B for ; Thu, 2 May 2002 06:00:26 -0700 (PDT) Received: (from perforce@localhost) by freefall.freebsd.org (8.11.6/8.11.6) id g42D0QN84013 for perforce@freebsd.org; Thu, 2 May 2002 06:00:26 -0700 (PDT) (envelope-from dfr@freebsd.org) Date: Thu, 2 May 2002 06:00:26 -0700 (PDT) Message-Id: <200205021300.g42D0QN84013@freefall.freebsd.org> X-Authentication-Warning: freefall.freebsd.org: perforce set sender to dfr@freebsd.org using -f From: Doug Rabson Subject: PERFORCE change 10680 for review To: Perforce Change Reviews Sender: owner-p4-projects@FreeBSD.ORG Precedence: bulk List-ID: List-Archive: (Web Archive) List-Help: (List Instructions) List-Subscribe: List-Unsubscribe: X-Loop: FreeBSD.ORG http://people.freebsd.org/~peter/p4db/chv.cgi?CH=10680 Change 10680 by dfr@dfr_home on 2002/05/02 05:59:55 * Use suword32 instead of suhword. * Rename to avoid conflicts with elf32. * Fix another page-size wrinkle in section mapping code. Affected files ... ... //depot/projects/ia64/sys/ia64/ia32/imgact_ia32.c#2 edit Differences ... ==== //depot/projects/ia64/sys/ia64/ia32/imgact_ia32.c#2 (text+ko) ==== @@ -61,6 +61,7 @@ #include #include +#include #include #include #include @@ -72,28 +73,25 @@ __ElfType(Brandinfo); __ElfType(Auxargs); -#define IA32_USRSTACK (3L*1024*1024*1024) -#define IA32_PS_STRINGS (IA32_USRSTACK - sizeof(struct ia32_ps_strings)) +extern int suword32(void *p, u_int32_t v); -extern int suhword(void *p, u_int32_t v); - -static int elf32_check_header(const Elf32_Ehdr *hdr); -static int elf32_freebsd_fixup(register_t **stack_base, +static int ia32_check_header(const Elf32_Ehdr *hdr); +static int ia32_freebsd_fixup(register_t **stack_base, struct image_params *imgp); -static int elf32_load_file(struct proc *p, const char *file, u_long *addr, +static int ia32_load_file(struct proc *p, const char *file, u_long *addr, u_long *entry); -static int elf32_load_section(struct proc *p, +static int ia32_load_section(struct proc *p, struct vmspace *vmspace, struct vnode *vp, vm_offset_t offset, caddr_t vmaddr, size_t memsz, size_t filsz, vm_prot_t prot); -static int exec_elf32_imgact(struct image_params *imgp); -static int elf32_coredump(struct thread *td, struct vnode *vp, off_t limit); -static register_t *elf32_copyout_strings(struct image_params *imgp); -static void elf32_setregs(struct thread *td, u_long entry, u_long stack, +static int exec_ia32_imgact(struct image_params *imgp); +static int ia32_coredump(struct thread *td, struct vnode *vp, off_t limit); +static register_t *ia32_copyout_strings(struct image_params *imgp); +static void ia32_setregs(struct thread *td, u_long entry, u_long stack, u_long ps_strings); -static int elf32_trace = 0; -SYSCTL_INT(_debug, OID_AUTO, elf32_trace, CTLFLAG_RW, &elf32_trace, 0, ""); +static int ia32_trace = 0; +SYSCTL_INT(_debug, OID_AUTO, ia32_trace, CTLFLAG_RW, &ia32_trace, 0, ""); extern struct sysent ia32_sysent[]; @@ -112,7 +110,7 @@ }; static int ia32_szsigcode = sizeof(ia32_sigcode) & ~3; -struct sysentvec elf32_freebsd_sysvec = { +struct sysentvec ia32_freebsd_sysvec = { SYS_MAXSYSCALL, ia32_sysent, 0, @@ -121,27 +119,27 @@ 0, 0, 0, - elf32_freebsd_fixup, + ia32_freebsd_fixup, sendsig, ia32_sigcode, &ia32_szsigcode, 0, "FreeBSD ELF", - elf32_coredump, + ia32_coredump, NULL, MINSIGSTKSZ, - elf32_copyout_strings, - elf32_setregs + ia32_copyout_strings, + ia32_setregs }; static Elf32_Brandinfo freebsd_brand_info = { ELFOSABI_FREEBSD, "FreeBSD", - "", + "/compat/ia32", "/usr/libexec/ld-elf.so.1", - &elf32_freebsd_sysvec + &ia32_freebsd_sysvec }; -static Elf32_Brandinfo *elf32_brand_list[MAX_BRANDS] = { +static Elf32_Brandinfo *ia32_brand_list[MAX_BRANDS] = { &freebsd_brand_info, NULL, NULL, NULL, NULL, NULL, NULL, NULL @@ -150,7 +148,7 @@ #if 0 int -elf32_insert_brand_entry(Elf32_Brandinfo *entry) +ia32_insert_brand_entry(Elf32_Brandinfo *entry) { int i; @@ -202,7 +200,7 @@ #endif static int -elf32_check_header(const Elf32_Ehdr *hdr) +ia32_check_header(const Elf32_Ehdr *hdr) { if (!IS_ELF(*hdr) || hdr->e_ident[EI_CLASS] != ELF_TARG_CLASS || @@ -225,7 +223,7 @@ #define trunc_page4k(x) ((x) & ~(PAGE4K_MASK)) static int -elf32_map_partial(vm_map_t map, vm_object_t object, vm_ooffset_t offset, +ia32_map_partial(vm_map_t map, vm_object_t object, vm_ooffset_t offset, vm_offset_t start, vm_offset_t end, vm_prot_t prot, vm_prot_t max) { @@ -272,32 +270,79 @@ } static int -elf32_map_insert(vm_map_t map, vm_object_t object, vm_ooffset_t offset, +ia32_map_insert(vm_map_t map, vm_object_t object, vm_ooffset_t offset, vm_offset_t start, vm_offset_t end, vm_prot_t prot, vm_prot_t max, int cow) { int rv; if (start != trunc_page(start)) { - rv = elf32_map_partial(map, object, offset, + rv = ia32_map_partial(map, object, offset, start, round_page(start), prot, max); if (rv) return rv; + offset += round_page(start) - start; start = round_page(start); - offset = round_page(offset); } if (end != round_page(end)) { - rv = elf32_map_partial(map, object, offset, + rv = ia32_map_partial(map, object, + offset + trunc_page(end) - start, trunc_page(end), end, prot, max); if (rv) return rv; end = trunc_page(end); } if (end > start) { - vm_map_lock(map); - rv = vm_map_insert(map, object, offset, start, end, - prot, max, cow); - vm_map_unlock(map); + if (offset & PAGE_MASK) { + vm_offset_t data_buf, off; + vm_size_t sz; + int error; + + /* + * The mapping is not page aligned. This means we have + * to copy the data. Sigh. + */ + rv = vm_map_find(map, 0, 0, + &start, end - start, + FALSE, prot, max, 0); + if (rv) + return rv; + while (start < end) { + vm_object_reference(object); + rv = vm_map_find(exec_map, + object, + trunc_page(offset), + &data_buf, + 2*PAGE_SIZE, + TRUE, + VM_PROT_READ, + VM_PROT_ALL, + (MAP_COPY_ON_WRITE + | MAP_PREFAULT_PARTIAL)); + if (rv != KERN_SUCCESS) { + vm_object_deallocate(object); + return rv; + } + off = offset - trunc_page(offset); + sz = end - start; + if (sz > PAGE_SIZE) + sz = PAGE_SIZE; + error = copyout((caddr_t)data_buf+off, + (caddr_t)start, sz); + vm_map_remove(exec_map, data_buf, + data_buf + 2*PAGE_SIZE); + if (error) { + return KERN_FAILURE; + } + start += sz; + } + rv = KERN_SUCCESS; + } else { + vm_map_lock(map); + rv = vm_map_insert(map, object, offset, start, end, + prot, max, cow); + vm_map_unlock(map); + } return rv; } else { return KERN_SUCCESS; @@ -305,7 +350,7 @@ } static int -elf32_load_section(struct proc *p, struct vmspace *vmspace, struct vnode *vp, vm_offset_t offset, caddr_t vmaddr, size_t memsz, size_t filsz, vm_prot_t prot) +ia32_load_section(struct proc *p, struct vmspace *vmspace, struct vnode *vp, vm_offset_t offset, caddr_t vmaddr, size_t memsz, size_t filsz, vm_prot_t prot) { size_t map_len; vm_offset_t map_addr; @@ -331,7 +376,7 @@ */ if ((off_t)filsz + offset > object->un_pager.vnp.vnp_size || filsz > memsz) { - uprintf("elf32_load_section: truncated ELF file\n"); + uprintf("ia32_load_section: truncated ELF file\n"); return (ENOEXEC); } @@ -351,7 +396,7 @@ if (map_len != 0) { vm_object_reference(object); - rv = elf32_map_insert(&vmspace->vm_map, + rv = ia32_map_insert(&vmspace->vm_map, object, file_addr, /* file offset */ map_addr, /* virtual start */ @@ -383,7 +428,7 @@ /* This had damn well better be true! */ if (map_len != 0) { - rv = elf32_map_insert(&vmspace->vm_map, NULL, 0, + rv = ia32_map_insert(&vmspace->vm_map, NULL, 0, map_addr, map_addr + map_len, VM_PROT_ALL, VM_PROT_ALL, 0); if (rv != KERN_SUCCESS) { @@ -420,8 +465,8 @@ /* * set it to the specified protection */ - vm_map_protect(&vmspace->vm_map, map_addr, map_addr + map_len, prot, - FALSE); + vm_map_protect(&vmspace->vm_map, trunc_page(map_addr), + round_page(map_addr + map_len), prot, FALSE); return error; } @@ -439,7 +484,7 @@ * the entry point for the loaded file. */ static int -elf32_load_file(struct proc *p, const char *file, u_long *addr, u_long *entry) +ia32_load_file(struct proc *p, const char *file, u_long *addr, u_long *entry) { struct { struct nameidata nd; @@ -458,7 +503,7 @@ int error, i, numsegs; if (curthread->td_proc != p) - panic("elf32_load_file - thread"); /* XXXKSE DIAGNOSTIC */ + panic("ia32_load_file - thread"); /* XXXKSE DIAGNOSTIC */ tempdata = malloc(sizeof(*tempdata), M_TEMP, M_WAITOK); nd = &tempdata->nd; @@ -511,7 +556,7 @@ goto fail; hdr = (const Elf32_Ehdr *)imgp->image_header; - if ((error = elf32_check_header(hdr)) != 0) + if ((error = ia32_check_header(hdr)) != 0) goto fail; if (hdr->e_type == ET_DYN) rbase = *addr; @@ -541,7 +586,7 @@ if (phdr[i].p_flags & PF_R) prot |= VM_PROT_READ; - if ((error = elf32_load_section(p, vmspace, nd->ni_vp, + if ((error = ia32_load_section(p, vmspace, nd->ni_vp, phdr[i].p_offset, (caddr_t)(uintptr_t)phdr[i].p_vaddr + rbase, @@ -578,16 +623,16 @@ * non static, as it can be overridden by start_init() */ #ifdef __ia64__ -int fallback_elf32_brand = ELFOSABI_FREEBSD; +int fallback_ia32_brand = ELFOSABI_FREEBSD; #else -int fallback_elf32_brand = -1; +int fallback_ia32_brand = -1; #endif -SYSCTL_INT(_kern, OID_AUTO, fallback_elf32_brand, CTLFLAG_RW, - &fallback_elf32_brand, -1, +SYSCTL_INT(_kern, OID_AUTO, fallback_ia32_brand, CTLFLAG_RW, + &fallback_ia32_brand, -1, "ELF brand of last resort"); static int -exec_elf32_imgact(struct image_params *imgp) +exec_ia32_imgact(struct image_params *imgp) { const Elf32_Ehdr *hdr = (const Elf32_Ehdr *) imgp->image_header; const Elf32_Phdr *phdr; @@ -607,7 +652,7 @@ /* * Do we have a valid ELF header ? */ - if (elf32_check_header(hdr) != 0 || hdr->e_type != ET_EXEC) + if (ia32_check_header(hdr) != 0 || hdr->e_type != ET_EXEC) return -1; /* @@ -639,7 +684,7 @@ if ((error = exec_extract_strings(imgp)) != 0) goto fail; - exec_new_vmspace(imgp, IA32_USRSTACK); + exec_new_vmspace(imgp, VM_MIN_ADDRESS, IA32_USRSTACK, IA32_USRSTACK); vmspace = imgp->proc->p_vmspace; @@ -655,7 +700,7 @@ if (phdr[i].p_flags & PF_R) prot |= VM_PROT_READ; - if ((error = elf32_load_section(imgp->proc, + if ((error = ia32_load_section(imgp->proc, vmspace, imgp->vp, phdr[i].p_offset, (caddr_t)(uintptr_t)phdr[i].p_vaddr, @@ -719,7 +764,7 @@ /* If the executable has a brand, search for it in the brand list. */ if (brand_info == NULL) { for (i = 0; i < MAX_BRANDS; i++) { - Elf32_Brandinfo *bi = elf32_brand_list[i]; + Elf32_Brandinfo *bi = ia32_brand_list[i]; if (bi != NULL && (hdr->e_ident[EI_OSABI] == bi->brand @@ -735,7 +780,7 @@ /* Lacking a known brand, search for a recognized interpreter. */ if (brand_info == NULL && interp != NULL) { for (i = 0; i < MAX_BRANDS; i++) { - Elf32_Brandinfo *bi = elf32_brand_list[i]; + Elf32_Brandinfo *bi = ia32_brand_list[i]; if (bi != NULL && strcmp(interp, bi->interp_path) == 0) { @@ -748,9 +793,9 @@ /* Lacking a recognized interpreter, try the default brand */ if (brand_info == NULL) { for (i = 0; i < MAX_BRANDS; i++) { - Elf32_Brandinfo *bi = elf32_brand_list[i]; + Elf32_Brandinfo *bi = ia32_brand_list[i]; - if (bi != NULL && fallback_elf32_brand == bi->brand) { + if (bi != NULL && fallback_ia32_brand == bi->brand) { brand_info = bi; break; } @@ -769,9 +814,9 @@ path = malloc(MAXPATHLEN, M_TEMP, M_WAITOK); snprintf(path, MAXPATHLEN, "%s%s", brand_info->emul_path, interp); - if ((error = elf32_load_file(imgp->proc, path, &addr, + if ((error = ia32_load_file(imgp->proc, path, &addr, &imgp->entry_addr)) != 0) { - if ((error = elf32_load_file(imgp->proc, interp, &addr, + if ((error = ia32_load_file(imgp->proc, interp, &addr, &imgp->entry_addr)) != 0) { uprintf("ELF interpreter %s not found\n", path); free(path, M_TEMP); @@ -793,7 +838,7 @@ elf32_auxargs->base = addr; elf32_auxargs->flags = 0; elf32_auxargs->entry = entry; - elf32_auxargs->trace = elf32_trace; + elf32_auxargs->trace = ia32_trace; imgp->auxargs = elf32_auxargs; imgp->interpreted = 0; @@ -802,10 +847,10 @@ return error; } -#define AUXARGS32_ENTRY(pos, id, val) {suhword(pos++, id); suhword(pos++, val);} +#define AUXARGS32_ENTRY(pos, id, val) {suword32(pos++, id); suword32(pos++, val);} static int -elf32_freebsd_fixup(register_t **stack_base, struct image_params *imgp) +ia32_freebsd_fixup(register_t **stack_base, struct image_params *imgp) { Elf32_Auxargs *args = (Elf32_Auxargs *)imgp->auxargs; u_int32_t *pos; @@ -831,7 +876,7 @@ imgp->auxargs = NULL; (*(u_int32_t **)stack_base)--; - suhword(*stack_base, (long) imgp->argc); + suword32(*stack_base, (long) imgp->argc); return 0; } @@ -856,17 +901,17 @@ static void cb_put_phdr(vm_map_entry_t, void *); static void cb_size_segment(vm_map_entry_t, void *); static void each_writable_segment(struct proc *, segment_callback, void *); -static int elf32_corehdr(struct thread *, struct vnode *, struct ucred *, +static int ia32_corehdr(struct thread *, struct vnode *, struct ucred *, int, void *, size_t); -static void elf32_puthdr(struct proc *, void *, size_t *, +static void ia32_puthdr(struct proc *, void *, size_t *, const prstatus_t *, const prfpregset_t *, const prpsinfo_t *, int); -static void elf32_putnote(void *, size_t *, const char *, int, +static void ia32_putnote(void *, size_t *, const char *, int, const void *, size_t); extern int osreldate; static int -elf32_coredump(td, vp, limit) +ia32_coredump(td, vp, limit) struct thread *td; register struct vnode *vp; off_t limit; @@ -889,7 +934,7 @@ * size is calculated. */ hdrsize = 0; - elf32_puthdr((struct proc *)NULL, (void *)NULL, &hdrsize, + ia32_puthdr((struct proc *)NULL, (void *)NULL, &hdrsize, (const prstatus_t *)NULL, (const prfpregset_t *)NULL, (const prpsinfo_t *)NULL, seginfo.count); @@ -904,7 +949,7 @@ if (hdr == NULL) { return EINVAL; } - error = elf32_corehdr(td, vp, cred, seginfo.count, hdr, hdrsize); + error = ia32_corehdr(td, vp, cred, seginfo.count, hdr, hdrsize); /* Write the contents of all of the writable segments. */ if (error == 0) { @@ -1030,7 +1075,7 @@ * the page boundary. */ static int -elf32_corehdr(td, vp, cred, numsegs, hdr, hdrsize) +ia32_corehdr(td, vp, cred, numsegs, hdr, hdrsize) struct thread *td; struct vnode *vp; struct ucred *cred; @@ -1076,7 +1121,7 @@ /* Fill in the header. */ bzero(hdr, hdrsize); off = 0; - elf32_puthdr(p, hdr, &off, status, fpregset, psinfo, numsegs); + ia32_puthdr(p, hdr, &off, status, fpregset, psinfo, numsegs); free(tempdata, M_TEMP); @@ -1086,7 +1131,7 @@ } static void -elf32_puthdr(struct proc *p, void *dst, size_t *off, const prstatus_t *status, +ia32_puthdr(struct proc *p, void *dst, size_t *off, const prstatus_t *status, const prfpregset_t *fpregset, const prpsinfo_t *psinfo, int numsegs) { size_t ehoff; @@ -1101,11 +1146,11 @@ *off += (numsegs + 1) * sizeof(Elf32_Phdr); noteoff = *off; - elf32_putnote(dst, off, "FreeBSD", NT_PRSTATUS, status, + ia32_putnote(dst, off, "FreeBSD", NT_PRSTATUS, status, sizeof *status); - elf32_putnote(dst, off, "FreeBSD", NT_FPREGSET, fpregset, + ia32_putnote(dst, off, "FreeBSD", NT_FPREGSET, fpregset, sizeof *fpregset); - elf32_putnote(dst, off, "FreeBSD", NT_PRPSINFO, psinfo, + ia32_putnote(dst, off, "FreeBSD", NT_PRPSINFO, psinfo, sizeof *psinfo); notesz = *off - noteoff; @@ -1168,7 +1213,7 @@ } static void -elf32_putnote(void *dst, size_t *off, const char *name, int type, +ia32_putnote(void *dst, size_t *off, const char *name, int type, const void *desc, size_t descsz) { Elf_Note note; @@ -1187,15 +1232,8 @@ *off += roundup2(note.n_descsz, sizeof(Elf32_Size)); } -struct ia32_ps_strings { - u_int32_t ps_argvstr; /* first of 0 or more argument strings */ - int ps_nargvstr; /* the number of argument strings */ - u_int32_t ps_envstr; /* first of 0 or more environment strings */ - int ps_nenvstr; /* the number of environment strings */ -}; - static register_t * -elf32_copyout_strings(struct image_params *imgp) +ia32_copyout_strings(struct image_params *imgp) { int argc, envc; u_int32_t *vectp; @@ -1264,44 +1302,43 @@ /* * Fill in "ps_strings" struct for ps, w, etc. */ - suhword(&arginfo->ps_argvstr, (u_int32_t)(intptr_t)vectp); - suhword(&arginfo->ps_nargvstr, argc); + suword32(&arginfo->ps_argvstr, (u_int32_t)(intptr_t)vectp); + suword32(&arginfo->ps_nargvstr, argc); /* * Fill in argument portion of vector table. */ for (; argc > 0; --argc) { - suhword(vectp++, (u_int32_t)(intptr_t)destp); + suword32(vectp++, (u_int32_t)(intptr_t)destp); while (*stringp++ != 0) destp++; destp++; } /* a null vector table pointer separates the argp's from the envp's */ - suhword(vectp++, 0); + suword32(vectp++, 0); - suhword(&arginfo->ps_envstr, (u_int32_t)(intptr_t)vectp); - suhword(&arginfo->ps_nenvstr, envc); + suword32(&arginfo->ps_envstr, (u_int32_t)(intptr_t)vectp); + suword32(&arginfo->ps_nenvstr, envc); /* * Fill in environment portion of vector table. */ for (; envc > 0; --envc) { - suhword(vectp++, (u_int32_t)(intptr_t)destp); + suword32(vectp++, (u_int32_t)(intptr_t)destp); while (*stringp++ != 0) destp++; destp++; } /* end of vector table is a null pointer */ - suhword(vectp, 0); + suword32(vectp, 0); return ((register_t *)stack_base); } static void -elf32_setregs(struct thread *td, u_long entry, u_long stack, - u_long ps_strings) +ia32_setregs(struct thread *td, u_long entry, u_long stack, u_long ps_strings) { struct trapframe *frame = td->td_frame; vm_offset_t gdt, ldt; @@ -1325,6 +1362,7 @@ | IA64_PSR_IT | IA64_PSR_DT | IA64_PSR_RT + | IA64_PSR_DFH | IA64_PSR_IS | IA64_PSR_BN | IA64_PSR_CPL_USER); @@ -1425,12 +1463,6 @@ frame->tf_r[FRAME_R11] = ps_strings; /* - * Set ia32 control registers. - */ - ia64_set_cflg((CR0_PE | CR0_PG) - | ((long)(CR4_XMM | CR4_FXSR) << 32)); - - /* * XXX - Linux emulator * Make sure sure edx is 0x0 on entry. Linux binaries depend * on it. @@ -1441,5 +1473,5 @@ /* * Tell kern_execve.c about it, with a little help from the linker. */ -static struct execsw elf32_execsw = {exec_elf32_imgact, "ELF32"}; -EXEC_SET(elf32, elf32_execsw); +static struct execsw ia32_execsw = {exec_ia32_imgact, "IA32"}; +EXEC_SET(ia32, ia32_execsw); To Unsubscribe: send mail to majordomo@FreeBSD.org with "unsubscribe p4-projects" in the body of the message