Re: MultiWindowed Adventure Game



Frank Kotler wrote:

Okay, that helps... The memory I'm trying to access is around 0x40100000 - that's what mmap returns. It seems as if, if I map it as "MAP_PRIVATE" instead of "MAP_SHARED", the problem goes away...

I'm doing my experimentation in Nasm - HLA syntax is just
*too* unintuitive to me :(

Have you tried it in C? That way you can distinguish between a bug in Linux and a bug in your assembly code.


Here's what I've got...

global _start

section .data
    filename db 'mmaptest.dat', 0

section .text
_start:
    nop

    mov eax, 5  ; __NR_open
    mov ebx, filename
    mov ecx, 2 | 100q | 1000q ; O_DRWR, O_CREAT, O_TRUNC
    mov edx, 666q

I think this might be a problem: the 666 should be octal, not hex (which I assume q implies). You can get a SIGBUS if you try to write but don't have write permission, I think.


    int 80h
    or eax, eax
    js exit

    push byte 0
    push eax
;    push byte 2 ; MAP_PRIVATE   this works
    push byte 1 ; MAP_SHARED     bus error
    push byte 7 ; PROT_READ | PROT_WRITE | PROT_EXEC
    push 1000h  ; size
    push byte 0

I don't know NASM, but those 'push byte's look suspicious. I would think you would want to push 32-bit values. I also don't know Linux, but aren't the arguments to syscalls supposed to go in registers?


    mov ebx, esp
    mov eax, 90 ; __NR_mmap
    int 80h
;    call showeax  ; for debugging... 0x40000000
    mov byte [eax], 'A'

exit:
    mov ebx, eax
    mov eax, 1
    int 80h

When I say this "works" with "MAP_PRIVATE"... it doesn't get
the bus error - I don't actually see the 'A' in my file.
That's expected, I guess, without "MAP_SHARED" (?)...

Yes.

Here's my HLA "version"...

I didn't look. I understand HLA even less than I do NASM.

I am not all that familiar with the nuances of mmap(2), and I have not read the standard, but playing with the test program below it appears that you will get a SIGBUS if the original size fo the file is 0, regardless of the size of the mapping. If the original size of the file is not zero, you will get a SIGBUS if you write beyond what has been mapped (which may be greater than what you requested, depending on the page size). The standard ought to spell out all this, but I'm too lazy to check (and it's more fun to experiment).

Here is the little test program in C:

------------ mmap.c ----------------
#include <stdio.h>
#include <stdlib.h>

#include <sys/mman.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>

int main(int argc, char *argv[])
{
    int fd = 0;
    const char *fn = "mmap.out";
    int error = 0;
    char *map = 0;
    struct stat sb;
    int ch;
    int open_flags = O_RDWR | O_CREAT;
    int write_pos = 0;
    char write_char = 'A';

    /* Set to zero so user-supplied size can be stored there. */
    sb.st_size = 0;

    while ((ch = getopt(argc, argv, "f:s:tw:")) != -1) {
        switch ( ch ) {
            case 'f':
                fn = optarg;
                break;
            case 's':
                sb.st_size = strtoul(optarg, 0, 10);
                break;
            case 't':
                open_flags |= O_TRUNC;
                break;
            case 'w':
                write_pos = strtol(optarg, 0, 10);
                break;
            case '?':
            default:
                ;
        }
    }

    if ( (fd = open(fn, open_flags, 0666)) < 0 ) {
        perror(fn);
        error = 1;
    }
    else if ( sb.st_size == 0 && stat(fn, &sb) != 0 ) {
        perror(fn);
        error = 1;
    }
    else if ( (map = mmap(0, sb.st_size,
                          PROT_READ | PROT_WRITE ,
                          MAP_SHARED, fd, 0))
              == MAP_FAILED ) {
        perror(fn);
        error = 1;
    }

    if ( !error ) {
        printf("mapped %s with size %lu\n", fn, sb.st_size);
        printf("writing '%c' at position %lu\n", write_char,
                                                 write_pos);
        map[write_pos] = write_char;
        munmap(map, sb.st_size);
    }

    close(fd);
    return 0;
}

------------ mmap.c ----------------


-- Thomas M. Sommers -- tms@xxxxxx -- AB2SB

.


Quantcast