patches/uClibc/0.9.29/100-fix-mmap.patch
author "Yann E. MORIN" <yann.morin.1998@anciens.enib.fr>
Mon Jul 28 21:32:33 2008 +0000 (2008-07-28)
changeset 747 d3e603e7c17c
parent 291 patches/uClibc/0.9.29/000-fix-mmap.patch@64c57f736ec3
permissions -rw-r--r--
Fourth step at renaming patches: renumber all patches with a 10-step.
     1 --- uClibc-0.9.29.oorig/test/mmap/mmap2.c	(revision 0)
     2 +++ uClibc-0.9.29/test/mmap/mmap2.c	(revision 18616)
     3 @@ -0,0 +1,41 @@
     4 +/* When trying to map /dev/mem with offset 0xFFFFF000 on the ARM platform, mmap
     5 + * returns -EOVERFLOW.
     6 + *
     7 + * Since off_t is defined as a long int and the sign bit is set in the address,
     8 + * the shift operation shifts in ones instead of zeroes
     9 + * from the left. This results the offset sent to the kernel function becomes
    10 + * 0xFFFFFFFF instead of 0x000FFFFF with MMAP2_PAGE_SHIFT set to 12.
    11 + */
    12 +
    13 +#include <unistd.h>
    14 +#include <stdio.h>
    15 +#include <stdlib.h>
    16 +#include <string.h>
    17 +#include <errno.h>
    18 +#include <fcntl.h>
    19 +#include <sys/mman.h>
    20 +
    21 +#define FATAL do { fprintf(stderr, "Error at line %d, file %s (%d) [%s]\n", \
    22 +  __LINE__, __FILE__, errno, strerror(errno)); exit(1); } while(0)
    23 +
    24 +#define MAP_SIZE 4096UL
    25 +#define MAP_MASK (MAP_SIZE - 1)
    26 +
    27 +int main(int argc, char **argv) {
    28 +    void* map_base = 0;
    29 +    int fd;
    30 +    off_t target = 0xfffff000;
    31 +    if((fd = open("/dev/mem", O_RDWR | O_SYNC)) == -1) FATAL;
    32 +    printf("/dev/mem opened.\n");
    33 +    fflush(stdout);
    34 +
    35 +   /* Map one page */
    36 +    map_base = mmap(0, MAP_SIZE, PROT_READ | PROT_WRITE, MAP_SHARED,
    37 +                        fd, target & ~MAP_MASK);
    38 +    if(map_base == (void *) -1) FATAL;
    39 +    printf("Memory mapped at address %p.\n", map_base);
    40 +    fflush(stdout);
    41 +    if(munmap(map_base, MAP_SIZE) == -1) FATAL;
    42 +    close(fd);
    43 +    return 0;
    44 +}
    45 --- uClibc-0.9.29.oorig/libc/sysdeps/linux/arm/mmap.c	(revision 18615)
    46 +++ uClibc-0.9.29/libc/sysdeps/linux/arm/mmap.c	(revision 18616)
    47 @@ -27,7 +27,6 @@ __ptr_t mmap(__ptr_t addr, size_t len, i
    48  
    49  #elif defined  (__NR_mmap2)
    50  #define __NR__mmap __NR_mmap2
    51 -
    52  #ifndef MMAP2_PAGE_SHIFT
    53  # define MMAP2_PAGE_SHIFT 12
    54  #endif
    55 @@ -39,9 +38,17 @@ __ptr_t mmap(__ptr_t addr, size_t len, i
    56  {
    57    /* check if offset is page aligned */
    58      if (offset & ((1 << MMAP2_PAGE_SHIFT) - 1))
    59 +    {
    60 +        __set_errno(EINVAL);
    61          return MAP_FAILED;
    62 +    }
    63 +#ifdef __USE_FILE_OFFSET64
    64 +  return (__ptr_t) _mmap (addr, len, prot, flags,
    65 +						  fd,((__u_quad_t) offset >> MMAP2_PAGE_SHIFT));
    66 +#else
    67    return (__ptr_t) _mmap (addr, len, prot, flags,
    68 -						  fd,(off_t) (offset >> MMAP2_PAGE_SHIFT));
    69 +                          fd,((__u_long) offset >> MMAP2_PAGE_SHIFT));
    70 +#endif
    71  }
    72  #elif defined (__NR_mmap)
    73  # define __NR__mmap __NR_mmap
    74 --- uClibc-0.9.29.oorig/libc/sysdeps/linux/common/mmap64.c	(revision 18615)
    75 +++ uClibc-0.9.29/libc/sysdeps/linux/common/mmap64.c	(revision 18616)
    76 @@ -58,8 +58,13 @@ __ptr_t mmap64(__ptr_t addr, size_t len,
    77  		__set_errno(EINVAL);
    78  		return MAP_FAILED;
    79  	}
    80 -
    81 -	return __syscall_mmap2(addr, len, prot, flags, fd, (off_t) (offset >> MMAP2_PAGE_SHIFT));
    82 +#ifdef __USE_FILE_OFFSET64
    83 +  return __syscall_mmap2(addr, len, prot, flags,
    84 +                         fd,((__u_quad_t)offset >> MMAP2_PAGE_SHIFT));
    85 +#else
    86 +   return __syscall_mmap2(addr, len, prot, flags,
    87 +                          fd,((__u_long)offset >> MMAP2_PAGE_SHIFT));
    88 +#endif
    89  }
    90  
    91  # endif