Solaris X86 Wine

Robert Lunnon bob at yarrabee.net.au
Thu Aug 9 03:08:00 CDT 2001


I am determined to see wine work again on Solaris. A while back there
was some discussion on a modification of mmap to  allow dos mode to
work. The thread of wine-develop faded out after a while with no
resolution. Can someone outline this problem and how it affects wine,
and give me some reason why the finally proposed solution from last year
should not be applied

This was the last reference I found


This is a multi-part message in MIME format.
--------------46C2B1B89C526C87F92A8F9D
Content-Type: text/plain; charset=us-ascii
Content-Transfer-Encoding: 7bit

(I hope this doesn't get me into trouble with the wine-devel mailing
list...  My Netscape doesn't seem to understand it.)

To whomever is interested,

A couple of minutes hacking at my Solaris 8 (Sparc) machine during the
lunch break yields the attached code that seems to emulate Linux'
behaviour.  Do whatever you feel is best.

My $0.02,

Erik Boasson.

--

[Unclassified]
--------------46C2B1B89C526C87F92A8F9D
Content-Type: text/plain; charset=us-ascii;
 name="safe_mmap.c"
Content-Transfer-Encoding: 7bit
Content-Disposition: inline;
 filename="safe_mmap.c"

#include <sys/types.h>
#include <sys/wait.h>
#include <sys/stat.h>
#include <sys/mman.h>
#include <errno.h>
#include <unistd.h>
#include <fcntl.h>
#include <assert.h>
#include <alloca.h>
#include <stdio.h>
#include <string.h>
#include <signal.h>
#include <procfs.h>


static int is_mapped_test (uintptr_t vaddr, size_t size,
                           const prmap_t *asmap, int n)
{
  int i = 0, j = n;

  while (i < j)
  {
    int m = (i + j) / 2;
    const prmap_t *o = &asmap[m];

    if ((uintptr_t) o->pr_vaddr >= vaddr + size)
      j = m;
    else if ((uintptr_t) o->pr_vaddr + o->pr_size <= vaddr)
      i = m + 1;
    else
      return 1;
  }

  return 0;
}


static void *safe_mmap (void *addr, size_t len, int prot, int flags,
                        int fildes, off_t off)
{
  if (flags & MAP_FIXED)
    return mmap (addr, len, prot, flags, fildes, off);
  else
  {
    int stat = 0;
    pid_t pid;
    int fd;
    struct stat sb;
    prmap_t *asmap;
    void *actual_addr;

    assert ((fd = open ("/proc/self/rmap", O_RDONLY)) != -1);
    if ((pid = vfork ()) == -1)
    {
      perror ("is_mapped: vfork");
      abort ();
    }
    else if (pid == 0)
    {
      fstat (fd, &sb);
      asmap = alloca (sb.st_size);
      read (fd, asmap, sb.st_size);
      if (is_mapped_test ((uintptr_t) addr, len, asmap,
                          sb.st_size / sizeof (prmap_t)))
        _exit (EADDRINUSE);
      else if ((actual_addr = mmap (addr, len, prot, flags | MAP_FIXED,
                                    fildes, off)) == (void *) -1)
        _exit (errno);
      else if (actual_addr != addr)
      {
        munmap (actual_addr, len);
        kill (getpid (), SIGKILL);
      }
      else
      {
        _exit (0);
      }
    }
    else if (waitpid (pid,  &stat, WNOHANG) != pid)
    {
      perror ("is_mapped: waitpid");
      abort ();
    }
    close (fd);
    if (!WIFEXITED (stat))
      return mmap (addr, len, prot, flags, fildes, off);
    else if (WEXITSTATUS (stat) == 0)
      return addr;
    else if (WEXITSTATUS (stat) == EADDRINUSE)
      return mmap (addr, len, prot, flags, fildes, off);
    else
    {
      errno = WEXITSTATUS (stat);
      return (void *) -1;
    }
  }
}


/*****************************************************************************/



#include <time.h>
#include <stdio.h>
#include <stdlib.h>


void try (uintptr_t vaddr, size_t size)
{
  void *a;
  a = safe_mmap ((void *) vaddr, size, PROT_READ | PROT_WRITE,
                 MAP_PRIVATE | MAP_ANON, -1, 0);
  printf ("%8x .. %8x  %8p %s\n", vaddr, vaddr + size, a, strerror
(errno));
  if (a != (void *) -1) munmap (a, size);
}


int main (int argc, char **argv)
{
  char buf[128];
  int i;

  sprintf (buf, "/usr/proc/bin/pmap %d", (int) getpid ());
  system (buf);

  srandom (time (0));

  for (i = 1; i < argc; i++)
  {
    uintptr_t vaddr;
    size_t size;

    if (sscanf (argv[i], "%x+%x", &vaddr, &size) == 2)
    {
      try (vaddr, size);
    }
    else
    {
      int n = atoi (argv[i]);
      while (n-- > 0)
      {
        do {
          vaddr = random () & -8192;
          size = (random () % 1048576) & -8192;
        } while (vaddr + size < vaddr);

        try (vaddr, size);
      }
    }
  }

  return 0;
}

--------------46C2B1B89C526C87F92A8F9D--

***************************************************************************




2. When starting Winedbg I get an xterm started with Title Wine Console
with the messages WineDbg Starting.... that sits that way forever. Then
I have to kill -9 wineserver to stop it. CAn someone give me an idea of
the control flow of winedbg so I have a starting point.

<link.h> is sys/link.h in stabs.c and the configure test needs to
include /usr/include/sys looking for link.h to get HAVE_LINK_H right on
Solaris

also bsearch compare function segfaults in get_list_load_order.() when
called with a zero element list of dll overrides. I put a test for a
zero element list in this function and returned FALSE in this case to
work around the problem.

I would appreciate if someone with CVS update access could fix these
things for me







More information about the wine-users mailing list