示例#1
0
/*
 * Map a file (from fd's current offset) into a shared, read-only memory
 * segment.  The file offset must be a multiple of the page size.
 *
 * On success, returns 0 and fills out "pMap".  On failure, returns a nonzero
 * value and does not disturb "pMap".
 */
int sysMapFileInShmem(int fd, MemMapping* pMap)
{
#ifdef HAVE_POSIX_FILEMAP
    off_t start;
    size_t length;
    void* memPtr;

    assert(pMap != NULL);

    if (getFileStartAndLength(fd, &start, &length) < 0)
        return -1;

    memPtr = mmap(NULL, length, PROT_READ, MAP_FILE | MAP_SHARED, fd, start);
    if (memPtr == MAP_FAILED) {
        LOGW("mmap(%d, R, FILE|SHARED, %d, %d) failed: %s\n", (int) length,
            fd, (int) start, strerror(errno));
        return -1;
    }

    pMap->baseAddr = pMap->addr = memPtr;
    pMap->baseLength = pMap->length = length;

    return 0;
#else
    /* No MMAP, just fake it by copying the bits.
       For Win32 we could use MapViewOfFile if really necessary
       (see libs/utils/FileMap.cpp).
    */
    off_t start;
    size_t length;
    void* memPtr;

    assert(pMap != NULL);

    if (getFileStartAndLength(fd, &start, &length) < 0)
        return -1;

    memPtr = malloc(length);
    if (read(fd, memPtr, length) < 0) {
        LOGW("read(fd=%d, start=%d, length=%d) failed: %s\n", (int) length,
            fd, (int) start, strerror(errno));
        return -1;
    }

    pMap->baseAddr = pMap->addr = memPtr;
    pMap->baseLength = pMap->length = length;

    return 0;
#endif
}
示例#2
0
/*
 * Map a file (from fd's current offset) into a private, read-only memory
 * segment.  The file offset must be a multiple of the page size.
 *
 * On success, returns 0 and fills out "pMap".  On failure, returns a nonzero
 * value and does not disturb "pMap".
 */
static int sysMapFD(int fd, MemMapping* pMap)
{
    off_t start;
    size_t length;
    void* memPtr;

    assert(pMap != NULL);

    if (getFileStartAndLength(fd, &start, &length) < 0)
        return -1;

    memPtr = mmap(NULL, length, PROT_READ, MAP_PRIVATE, fd, start);
    if (memPtr == MAP_FAILED) {
        LOGW("mmap(%d, R, PRIVATE, %d, %d) failed: %s\n", (int) length,
            fd, (int) start, strerror(errno));
        return -1;
    }

    pMap->addr = memPtr;
    pMap->length = length;
    pMap->range_count = 1;
    pMap->ranges = malloc(sizeof(MappedRange));
    pMap->ranges[0].addr = memPtr;
    pMap->ranges[0].length = length;

    return 0;
}
示例#3
0
/*
 * Pull the contents of a file into an new shared memory segment.  We grab
 * everything from fd's current offset on.
 *
 * We need to know the length ahead of time so we can allocate a segment
 * of sufficient size.
 */
int sysLoadFileInShmem(int fd, MemMapping* pMap)
{
    loff_t start;
    size_t length, actual;
    void* memPtr;

    assert(pMap != NULL);

    if (getFileStartAndLength(fd, &start, &length) < 0)
        return -1;

    memPtr = sysCreateAnonShmem(length);
    if (memPtr == NULL)
        return -1;

    actual = read(fd, memPtr, length);
    if (actual != length) {
        LOGE("only read %d of %d bytes\n", (int) actual, (int) length);
        sysReleaseShmem(pMap);
        return -1;
    }

    pMap->baseAddr = pMap->addr = memPtr;
    pMap->baseLength = pMap->length = length;

    return 0;
}
示例#4
0
/*
 * Map a file (from fd's current offset) into a shared, read-only memory
 * segment.  The file offset must be a multiple of the page size.
 *
 * On success, returns 0 and fills out "pMap".  On failure, returns a nonzero
 * value and does not disturb "pMap".
 */
int
sysMapFileInShmem (int fd, MemMapping * pMap)
{
  off_t start;
  size_t length;
  void *memPtr;

  assert (pMap != NULL);

  if (getFileStartAndLength (fd, &start, &length) < 0)
    return -1;

  memPtr = mmap (NULL, length, PROT_READ, MAP_FILE | MAP_SHARED, fd, start);
  if (memPtr == MAP_FAILED)
	  {
	    LOGW ("mmap(%d, R, FILE|SHARED, %d, %d) failed: %s\n",
		  (int) length, fd, (int) start, strerror (errno));
	    return -1;
	  }

  pMap->baseAddr = pMap->addr = memPtr;
  pMap->baseLength = pMap->length = length;

  return 0;
}
示例#5
0
/*
 * Map a file (from fd's current offset) into a private, read-write memory
 * segment that will be marked read-only (a/k/a "writable read-only").  The
 * file offset must be a multiple of the system page size.
 *
 * In some cases the mapping will be fully writable (e.g. for files on
 * FAT filesystems).
 *
 * On success, returns 0 and fills out "pMap".  On failure, returns a nonzero
 * value and does not disturb "pMap".
 */
int sysMapFileInShmemWritableReadOnly(int fd, MemMapping* pMap)
{
#ifdef HAVE_POSIX_FILEMAP
    off_t start;
    size_t length;
    void* memPtr;

    assert(pMap != NULL);

    if (getFileStartAndLength(fd, &start, &length) < 0)
        return -1;

    memPtr = mmap(NULL, length, PROT_READ | PROT_WRITE, MAP_FILE | MAP_PRIVATE,
            fd, start);
    if (memPtr == MAP_FAILED) {
        ALOGW("mmap(%d, R/W, FILE|PRIVATE, %d, %d) failed: %s", (int) length,
            fd, (int) start, strerror(errno));
        return -1;
    }
    if (mprotect(memPtr, length, PROT_READ) < 0) {
        /* this fails with EACCESS on FAT filesystems, e.g. /sdcard */
        int err = errno;
        ALOGV("mprotect(%p, %d, PROT_READ) failed: %s",
            memPtr, length, strerror(err));
        ALOGD("mprotect(RO) failed (%d), file will remain read-write", err);
    }

    pMap->baseAddr = pMap->addr = memPtr;
    pMap->baseLength = pMap->length = length;

    return 0;
#else
    return sysFakeMapFile(fd, pMap);
#endif
}
示例#6
0
int sysFakeMapFile(int fd, MemMapping* pMap)
{
    /* No MMAP, just fake it by copying the bits.
       For Win32 we could use MapViewOfFile if really necessary
       (see libs/utils/FileMap.cpp).
    */
    off_t start;
    size_t length;
    void* memPtr;

    assert(pMap != NULL);

    if (getFileStartAndLength(fd, &start, &length) < 0)
        return -1;

    memPtr = malloc(length);
    if (read(fd, memPtr, length) < 0) {
        ALOGW("read(fd=%d, start=%d, length=%d) failed: %s", (int) length,
            fd, (int) start, strerror(errno));
        return -1;
    }

    pMap->baseAddr = pMap->addr = memPtr;
    pMap->baseLength = pMap->length = length;

    return 0;
}
示例#7
0
/*
 * Map a file (from fd's current offset) into a shared, read-only memory
 * segment.  The file offset must be a multiple of the system page size.
 *
 * On success, returns 0 and fills out "pMap".  On failure, returns a nonzero
 * value and does not disturb "pMap".
 */
int sysMapFileInShmemReadOnly(int fd, MemMapping* pMap)
{
#ifdef HAVE_POSIX_FILEMAP
    off_t start;
    size_t length;
    void* memPtr;

    assert(pMap != NULL);

    if (getFileStartAndLength(fd, &start, &length) < 0)
        return -1;

    memPtr = mmap(NULL, length, PROT_READ, MAP_FILE | MAP_SHARED, fd, start);
    if (memPtr == MAP_FAILED) {
        ALOGW("mmap(%d, RO, FILE|SHARED, %d, %d) failed: %s", (int) length,
            fd, (int) start, strerror(errno));
        return -1;
    }

    pMap->baseAddr = pMap->addr = memPtr;
    pMap->baseLength = pMap->length = length;

    return 0;
#else
    return sysFakeMapFile(fd, pMap);
#endif
}
示例#8
0
/*
 * Pull the contents of a file into an new shared memory segment.  We grab
 * everything from fd's current offset on.
 *
 * We need to know the length ahead of time so we can allocate a segment
 * of sufficient size.
 */
int sysLoadFileInShmem(int fd, MemMapping* pMap)
{
#ifdef HAVE_POSIX_FILEMAP
    off_t start;
    size_t length, actual;
    void* memPtr;

    assert(pMap != NULL);

    if (getFileStartAndLength(fd, &start, &length) < 0)
        return -1;

    memPtr = sysCreateAnonShmem(length);
    if (memPtr == NULL)
        return -1;

    actual = read(fd, memPtr, length);
    if (actual != length) {
        ALOGE("only read %d of %d bytes", (int) actual, (int) length);
        sysReleaseShmem(pMap);
        return -1;
    }

    pMap->baseAddr = pMap->addr = memPtr;
    pMap->baseLength = pMap->length = length;

    return 0;
#else
    ALOGE("sysLoadFileInShmem not implemented.");
    return -1;
#endif
}
示例#9
0
/*
 * Map part of a file (from fd's current offset) into a shared, read-only
 * memory segment.
 *
 * On success, returns 0 and fills out "pMap".  On failure, returns a nonzero
 * value and does not disturb "pMap".
 */
int sysMapFileSegmentInShmem(int fd, off_t start, long length,
    MemMapping* pMap)
{
#ifdef HAVE_POSIX_FILEMAP
    off_t dummy;
    size_t fileLength, actualLength;
    off_t actualStart;
    int adjust;
    void* memPtr;

    assert(pMap != NULL);

    if (getFileStartAndLength(fd, &dummy, &fileLength) < 0)
        return -1;

    if (start + length > (long)fileLength) {
        LOGW("bad segment: st=%d len=%ld flen=%d\n",
            (int) start, length, (int) fileLength);
        return -1;
    }

    /* adjust to be page-aligned */
    adjust = start % DEFAULT_PAGE_SIZE;
    actualStart = start - adjust;
    actualLength = length + adjust;

    memPtr = mmap(NULL, actualLength, PROT_READ, MAP_FILE | MAP_SHARED,
                fd, actualStart);
    if (memPtr == MAP_FAILED) {
        LOGW("mmap(%d, R, FILE|SHARED, %d, %d) failed: %s\n",
            (int) actualLength, fd, (int) actualStart, strerror(errno));
        return -1;
    }

    pMap->baseAddr = memPtr;
    pMap->baseLength = actualLength;
    pMap->addr = (char*)memPtr + adjust;
    pMap->length = length;

    LOGVV("mmap seg (st=%d ln=%d): bp=%p bl=%d ad=%p ln=%d\n",
        (int) start, (int) length,
        pMap->baseAddr, (int) pMap->baseLength,
        pMap->addr, (int) pMap->length);

    return 0;
#else
    LOGE("sysMapFileSegmentInShmem not implemented.\n");
    return -1;
#endif
}