patches/uClibc/0.9.29/100-fix-mmap.patch
author "Yann E. MORIN" <yann.morin.1998@anciens.enib.fr>
Sat Dec 31 18:47:37 2011 +0100 (2011-12-31)
changeset 2829 0c3c95f911ec
parent 291 64c57f736ec3
permissions -rw-r--r--
docs: credit Konrad EISELE for the initial multilib support

Konrad submitted an initial patch adding multlib support:
http://sourceware.org/ml/crossgcc/2011-11/msg00040.html

The patch was full of good ideas, but had a few issues, so
I (Yann E. MORIN) started it all from scatch, re-using part
of the original patch. This got implemented in this series:
hg log -r 446a17b5dd1e:e47d17391ae3

As I forgot to credit Konrad in these changelogs, update the
docs so that the work by Konrad gets credited. Without his
initial effort, we would probably not have had multlib support
so soon. Thank you Konrad!

Signed-off-by: "Yann E. MORIN" <yann.morin.1998@anciens.enib.fr>
     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