Date: Sun, 11 Aug 2002 14:43:34 +0300 (EEST) From: "Jukka A. Ukkonen" <jau@cs132140.pp.htv.fi> To: FreeBSD-gnats-submit@FreeBSD.org Subject: kern/41543: Easier wine/w23 support Message-ID: <200208111143.OAA41137@cs78135006.pp.htv.fi>
next in thread | raw e-mail | index | archive | help
>Number: 41543 >Category: kern >Synopsis: Easier wine/w23 support >Confidential: no >Severity: non-critical >Priority: medium >Responsible: freebsd-bugs >State: open >Quarter: >Keywords: >Date-Required: >Class: change-request >Submitter-Id: current-users >Arrival-Date: Sun Aug 11 04:50:02 PDT 2002 >Closed-Date: >Last-Modified: >Originator: Jukka A. Ukkonen >Release: Irrelevant >Organization: Private person >Environment: Any FreeBSD running on hardware which is also supported by ms-windows >Description: It seemed like a good idea to allow FreeBSD to recognize ms-windows binaries on the fly and start wine as an interpreter for such binaries, if it is installed on the system. All it takes is adding one more very simple imgact function exec_wine_imgact() to the kernel. This is very much in analogy to how the kernel handles "#!" at the beginning of scripts. The actual benefit is lowering very much the threshold for windows users to start using FreeBSD instead. >How-To-Repeat: No bug or problem, just an extension. >Fix: The following shar bundle contains my initial version of exec_wine_imgact() and an include file describing the header parts of a windows binary. To make it obvious that this is just an extension I put the header to <compat/windos.h>. You are welcome to choose otherwise. Due to my systems have always had a tendency to quickly become somewhat modified I have no idea how well this will fit in any vanilla FreeBSD system, but the need for changes should be relatively minor. And in any case, it is the idea that counts. # This is a shell archive. Save it in a file, remove anything before # this line, and then unpack it by entering "sh file". Note, it may # create directories; files and directories will be owned by you and # have default permissions. # # This archive contains: # # windos.h # imgact_wine.c # echo x - windos.h sed 's/^X//' >windos.h << 'END-of-windos.h' X X#ifndef _COMPAT_WINDOS_H X#define _COMPAT_WINDOS_H X X/* X * This file was originally taken from the Willows twin package X * and modified to better suit being used inside a UNIX kernel. X * X * This file does nothing more than describes the format of X * a ms-windows binary file header. X */ X X#ifndef WINDOS_WORD Xtypedef unsigned short WORD; X# define WINDOS_WORD WORD X#endif X X#ifndef WINDOS_DWORD Xtypedef unsigned long DWORD; X# define WINDOS_DWORD DWORD X#endif X X/* X * Old MZ header for DOS programs. X * We check only the magic and the e_lfanew offset to X * the new executable header. X * X * The new format executables should start with PE\0\0. X * The next two bytes after the "PE\0\0" tag specify X * the hardware architecture for which the binary has X * been compiled. X */ X Xtypedef struct X{ X WORD e_magic; /* MZ Header signature */ X WORD e_cblp; /* Bytes on last page of file */ X WORD e_cp; /* Pages in file */ X WORD e_crlc; /* Relocations */ X WORD e_cparhdr; /* Size of header in paragraphs */ X WORD e_minalloc; /* Minimum extra paragraphs needed */ X WORD e_maxalloc; /* Maximum extra paragraphs needed */ X WORD e_ss; /* Initial (relative) SS value */ X WORD e_sp; /* Initial SP value */ X WORD e_csum; /* Checksum */ X WORD e_ip; /* Initial IP value */ X WORD e_cs; /* Initial (relative) CS value */ X WORD e_lfarlc; /* File address of relocation table */ X WORD e_ovno; /* Overlay number */ X WORD e_res[4]; /* Reserved words */ X WORD e_oemid; /* OEM identifier (for e_oeminfo) */ X WORD e_oeminfo; /* OEM information; e_oemid specific */ X WORD e_res2[10]; /* Reserved words */ X WORD e_lfanew; /* Offset to extended header */ X} IMAGE_DOS_HEADER,*PIMAGE_DOS_HEADER; X X#define IMAGE_DOS_SIGNATURE 0x5A4D /* MZ */ X#define IMAGE_OS2_SIGNATURE 0x454E /* NE */ X#define IMAGE_OS2_SIGNATURE_LE 0x454C /* LE */ X#define IMAGE_VXD_SIGNATURE 0x454C /* LE */ X#define IMAGE_NT_SIGNATURE 0x00004550 /* PE00 */ X X#endif END-of-windos.h echo x - imgact_wine.c sed 's/^X//' >imgact_wine.c << 'END-of-imgact_wine.c' X/* X * Copyright (c) 2002, Jukka A. Ukkonen <jau(a)drop-this-part.iki.fi> X * All rights reserved. X * X * Redistribution and use in source and binary forms, with or without X * modification, are permitted provided that the following conditions X * are met: X * 1. Redistributions of source code must retain the above copyright X * notice, this list of conditions and the following disclaimer. X * 2. Redistributions in binary form must reproduce the above copyright X * notice, this list of conditions and the following disclaimer in the X * documentation and/or other materials provided with the distribution. X * X * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND X * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE X * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE X * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE X * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL X * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS X * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) X * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT X * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY X * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF X * SUCH DAMAGE. X * X * $Id: imgact_wine.c,v 1.1 2002/07/20 18:25:47 jau Exp $ X */ X X/* X * Set the editor tab-width to 4 X * to view/edit this file. X * Otherwise this might look a bit funny. X */ X X#include <sys/param.h> X#include <sys/systm.h> X#include <sys/sysproto.h> X#include <sys/exec.h> X#include <sys/imgact.h> X#include <sys/kernel.h> X X#include <vm/vm_param.h> X#include <compat/windos.h> X X#if defined(USER_LDT) && defined(SYSVSHM) \ X && defined(SYSVSEM) && defined(SYSVMSG) X# define IMGACT_WINE_OK X#else X# undef IMGACT_WINE_OK X#endif X X/* X * We do not really have to test for this limit, X * because "/usr/local/bin/wine" is static and X * obviously also much shoter than 64 bytes. X */ X X#define MAXWINECMDLEN 64 X Xstatic int exec_wine_imgact __P((struct image_params *imgp)); X X/* X * Shell interpreter image activator. A interpreter name beginning X * at imgp->stringbase is the minimal successful exit requirement. X */ X Xstatic int Xexec_wine_imgact (imgp) X struct image_params *imgp; X{ X const char *image_header = imgp->image_header; X const char *ihp, *line_endp; X char *interp; X IMAGE_DOS_HEADER *mshdr; X u_int16_t extoffs; X X#ifndef IMGACT_WINE_OK X return (-1); X#else X X# if !defined(i386) && !defined(alpha) && !defined(ppc) X return (-1); X# else X X /* a wine/ms-win executable? */ X X if ((image_header[0] != 'M') || (image_header[1] != 'Z')) X return (-1); X X X mshdr = (IMAGE_DOS_HEADER *) image_header; X X extoffs = mshdr.e_lfanew; X X# if BYTE_ORDER == BIG_ENDIAN X extoffs = (extoffs >> 8) | (extoffs << 8); X# endif X X X if (extoffs > PAGE_SIZE) X return (-1); X X /* X * If it happens to be a PE\0\0 format object, X * we can test also whether it has been intended X * for our present HW architecture. X */ X X if ((image_header[extoffs] == 0x50) /* 'P' */ X && (image_header[extoffs + 1] == 0x45) /* 'E' */ X && (image_header[extoffs + 2] == 0) X && (image_header[extoffs + 3] == 0)) { X X /* X * We *must not* return ENOEXEC here. X * The exec() code will do it unless no other X * imgact activator takes the job. X */ X X# if defined(i386) X if ((image_header[extoffs + 4] != 0x4c) X || (image_header[extoffs + 4] != 0x01)) X return (-1); X# endif X X# if defined(alpha) X if ((image_header[extoffs + 4] != 0x84) X || (image_header[extoffs + 4] != 0x01)) X return (-1); X# endif X X# if defined(ppc) X if ((image_header[extoffs + 4] != 0xf0) X || (image_header[extoffs + 4] != 0x01)) X return (-1); X# endif X X } X# if !defined(i386) X else { X /* X * Not a new format PE binary is assumed to be X * invariably a i386 binary. X * Because we are not running on a i386 host, X * there is pretty little we can do. X */ X return (-1); X } X# endif X X imgp->interpreted = 1; X X interp = imgp->interpreter_name; X ihp = "/usr/local/bin/wine"; X X while (*interp++ = *ihp++); X X imgp->argv0 = imgp->uap->fname; X X return (0); X X# endif X#endif X} X X/* X * Tell kern_execve.c about it, with a little help from the linker. X * Since `const' objects end up in the text segment, TEXT_SET is the X * correct directive to use. X */ X Xstatic const struct execsw wine_execsw = { exec_wine_imgact, "Wine" }; X XEXEC_SET(wine, wine_execsw); END-of-imgact_wine.c exit >Release-Note: >Audit-Trail: >Unformatted: To Unsubscribe: send mail to majordomo@FreeBSD.org with "unsubscribe freebsd-bugs" in the body of the message
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200208111143.OAA41137>