/*
 * Copyright (C) 2008 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

/*
 * Linear memory allocation, tied to class loaders.
 */
#include "Dalvik.h"

#include <sys/mman.h>
#include <limits.h>
#include <errno.h>

//#define DISABLE_LINEAR_ALLOC

// Use ashmem to name the LinearAlloc section
#define USE_ASHMEM 1

#ifdef USE_ASHMEM
#include <cutils/ashmem.h>
#endif /* USE_ASHMEM */

/*
Overview

This is intended to be a simple, fast allocator for "write-once" storage.
The expectation is that this will hold small allocations that don't change,
such as parts of classes (vtables, fields, methods, interfaces).  Because
the lifetime of these items is tied to classes, which in turn are tied
to class loaders, we associate the storage with a ClassLoader object.

[ We don't yet support class unloading, and our ClassLoader implementation
is in flux, so for now we just have a single global region and the
"classLoader" argument is ignored. ]

By storing the data here, rather than on the system heap, we reduce heap
clutter, speed class loading, reduce the memory footprint (reduced heap
structure overhead), and most importantly we increase the number of pages
that remain shared between processes launched in "Zygote mode".

The 4 bytes preceding each block contain the block length.  This allows us
to support "free" and "realloc" calls in a limited way.  We don't free
storage once it has been allocated, but in some circumstances it could be
useful to erase storage to garbage values after a "free" or "realloc".
(Bad idea if we're trying to share pages.)  We need to align to 8-byte
boundaries for some architectures, so we have a 50-50 chance of getting
this for free in a given block.

A NULL value for the "classLoader" argument refers to the bootstrap class
loader, which is never unloaded (until the VM shuts down).

Because the memory is not expected to be updated, we can use mprotect to
guard the pages on debug builds.  Handy when tracking down corruption.
*/

/* alignment for allocations; must be power of 2, and currently >= hdr_xtra */
#define BLOCK_ALIGN         8

/* default length of memory segment (worst case is probably "dexopt") */
#define DEFAULT_MAX_LENGTH  (5*1024*1024)

/* leave enough space for a length word */
#define HEADER_EXTRA        4

/* overload the length word */
#define LENGTHFLAG_FREE    0x80000000
#define LENGTHFLAG_RW      0x40000000
#define LENGTHFLAG_MASK    (~(LENGTHFLAG_FREE|LENGTHFLAG_RW))


/* fwd */
static void checkAllFree(Object* classLoader);


/*
 * Someday, retrieve the linear alloc struct associated with a particular
 * class loader.  For now, always use the boostrap loader's instance.
 */
static inline LinearAllocHdr* getHeader(Object* classLoader)
{
    return gDvm.pBootLoaderAlloc;
}

/*
 * Convert a pointer to memory to a pointer to the block header (which is
 * currently just a length word).
 */
static inline u4* getBlockHeader(void* mem)
{
    return ((u4*) mem) -1;
}

/*
 * Create a new linear allocation block.
 */
LinearAllocHdr* dvmLinearAllocCreate(Object* classLoader)
{
#ifdef DISABLE_LINEAR_ALLOC
    return (LinearAllocHdr*) 0x12345;
#endif
    LinearAllocHdr* pHdr;

    pHdr = (LinearAllocHdr*) malloc(sizeof(*pHdr));


    /*
     * "curOffset" points to the location of the next pre-block header,
     * which means we have to advance to the next BLOCK_ALIGN address and
     * back up.
     *
     * Note we leave the first page empty (see below), and start the
     * first entry on the second page at an offset that ensures the next
     * chunk of data will be properly aligned.
     */
    assert(BLOCK_ALIGN >= HEADER_EXTRA);
    pHdr->curOffset = pHdr->firstOffset =
        (BLOCK_ALIGN-HEADER_EXTRA) + SYSTEM_PAGE_SIZE;
    pHdr->mapLength = DEFAULT_MAX_LENGTH;

#ifdef USE_ASHMEM
    int fd;

    fd = ashmem_create_region("dalvik-LinearAlloc", DEFAULT_MAX_LENGTH);
    if (fd < 0) {
        LOGE("ashmem LinearAlloc failed %s", strerror(errno));
        free(pHdr);
        return NULL;
    }

    pHdr->mapAddr = mmap(NULL, pHdr->mapLength, PROT_READ | PROT_WRITE,
        MAP_PRIVATE, fd, 0);
    if (pHdr->mapAddr == MAP_FAILED) {
        LOGE("LinearAlloc mmap(%d) failed: %s\n", pHdr->mapLength,
            strerror(errno));
        free(pHdr);
        close(fd);
        return NULL;
    }

    close(fd);
#else /*USE_ASHMEM*/
    // MAP_ANON is listed as "deprecated" on Linux,
    // but MAP_ANONYMOUS is not defined under Mac OS X.
    pHdr->mapAddr = mmap(NULL, pHdr->mapLength, PROT_READ | PROT_WRITE,
        MAP_PRIVATE | MAP_ANON, -1, 0);
    if (pHdr->mapAddr == MAP_FAILED) {
        LOGE("LinearAlloc mmap(%d) failed: %s\n", pHdr->mapLength,
            strerror(errno));
        free(pHdr);
        return NULL;
    }
#endif /*USE_ASHMEM*/

    /* region expected to begin on a page boundary */
    assert(((int) pHdr->mapAddr & (SYSTEM_PAGE_SIZE-1)) == 0);

    /* the system should initialize newly-mapped memory to zero */
    assert(*(u4*) (pHdr->mapAddr + pHdr->curOffset) == 0);

    /*
     * Disable access to all except starting page.  We will enable pages
     * as we use them.  This helps prevent bad pointers from working.  The
     * pages start out PROT_NONE, become read/write while we access them,
     * then go to read-only after we finish our changes.
     *
     * We have to make the first page readable because we have 4 pad bytes,
     * followed by 4 length bytes, giving an initial offset of 8.  The
     * generic code below assumes that there could have been a previous
     * allocation that wrote into those 4 pad bytes, therefore the page
     * must have been marked readable by the previous allocation.
     *
     * We insert an extra page in here to force a break in the memory map
     * so we can see ourselves more easily in "showmap".  Otherwise this
     * stuff blends into the neighboring pages.  [TODO: do we still need
     * the extra page now that we have ashmem?]
     */
    if (mprotect(pHdr->mapAddr, pHdr->mapLength, PROT_NONE) != 0) {
        LOGW("LinearAlloc init mprotect failed: %s\n", strerror(errno));
        free(pHdr);
        return NULL;
    }
    if (mprotect(pHdr->mapAddr + SYSTEM_PAGE_SIZE, SYSTEM_PAGE_SIZE,
            ENFORCE_READ_ONLY ? PROT_READ : PROT_READ|PROT_WRITE) != 0)
    {
        LOGW("LinearAlloc init mprotect #2 failed: %s\n", strerror(errno));
        free(pHdr);
        return NULL;
    }

    if (ENFORCE_READ_ONLY) {
        /* allocate the per-page ref count */
        int numPages = (pHdr->mapLength+SYSTEM_PAGE_SIZE-1) / SYSTEM_PAGE_SIZE;
        pHdr->writeRefCount = calloc(numPages, sizeof(short));
        if (pHdr->writeRefCount == NULL) {
            free(pHdr);
            return NULL;
        }
    }

    dvmInitMutex(&pHdr->lock);

    LOGV("LinearAlloc: created region at %p-%p\n",
        pHdr->mapAddr, pHdr->mapAddr + pHdr->mapLength-1);

    return pHdr;
}

/*
 * Destroy a linear allocation area.
 *
 * We do a trivial "has everything been freed?" check before unmapping the
 * memory and freeing the LinearAllocHdr.
 */
void dvmLinearAllocDestroy(Object* classLoader)
{
#ifdef DISABLE_LINEAR_ALLOC
    return;
#endif
    LinearAllocHdr* pHdr = getHeader(classLoader);
    if (pHdr == NULL)
        return;

    checkAllFree(classLoader);

    //dvmLinearAllocDump(classLoader);

    if (gDvm.verboseShutdown) {
        LOGV("Unmapping linear allocator base=%p\n", pHdr->mapAddr);
        LOGD("LinearAlloc %p used %d of %d (%d%%)\n",
            classLoader, pHdr->curOffset, pHdr->mapLength,
            (pHdr->curOffset * 100) / pHdr->mapLength);
    }

    if (munmap(pHdr->mapAddr, pHdr->mapLength) != 0) {
        LOGW("LinearAlloc munmap(%p, %d) failed: %s\n",
            pHdr->mapAddr, pHdr->mapLength, strerror(errno));
    }
    free(pHdr);
}

/*
 * Allocate "size" bytes of storage, associated with a particular class
 * loader.
 *
 * It's okay for size to be zero.
 *
 * We always leave "curOffset" pointing at the next place where we will
 * store the header that precedes the returned storage.
 *
 * This aborts the VM on failure, so it's not necessary to check for a
 * NULL return value.
 */
void* dvmLinearAlloc(Object* classLoader, size_t size)
{
    LinearAllocHdr* pHdr = getHeader(classLoader);
    int startOffset, nextOffset;
    int lastGoodOff, firstWriteOff, lastWriteOff;

#ifdef DISABLE_LINEAR_ALLOC
    return calloc(1, size);
#endif

    LOGVV("--- LinearAlloc(%p, %d)\n", classLoader, size);

    /*
     * What we'd like to do is just determine the new end-of-alloc size
     * and atomic-swap the updated value in.  The trouble is that, the
     * first time we reach a new page, we need to call mprotect() to
     * make the page available, and we don't want to call mprotect() on
     * every allocation.  The troubled situation is:
     *  - thread A allocs across a page boundary, but gets preempted
     *    before mprotect() completes
     *  - thread B allocs within the new page, and doesn't call mprotect()
     */
    dvmLockMutex(&pHdr->lock);

    startOffset = pHdr->curOffset;
    assert(((startOffset + HEADER_EXTRA) & (BLOCK_ALIGN-1)) == 0);

    /*
     * Compute the new offset.  The old offset points at the address where
     * we will store the hidden block header, so we advance past that,
     * add the size of data they want, add another header's worth so we
     * know we have room for that, and round up to BLOCK_ALIGN.  That's
     * the next location where we'll put user data.  We then subtract the
     * chunk header size off so we're back to the header pointer.
     *
     * Examples:
     *   old=12 size=3 new=((12+(4*2)+3+7) & ~7)-4 = 24-4 --> 20
     *   old=12 size=5 new=((12+(4*2)+5+7) & ~7)-4 = 32-4 --> 28
     */
    nextOffset = ((startOffset + HEADER_EXTRA*2 + size + (BLOCK_ALIGN-1))
                    & ~(BLOCK_ALIGN-1)) - HEADER_EXTRA;
    LOGVV("--- old=%d size=%d new=%d\n", startOffset, size, nextOffset);

    if (nextOffset > pHdr->mapLength) {
        /*
         * We don't have to abort here.  We could fall back on the system
         * malloc(), and have our "free" call figure out what to do.  Only
         * works if the users of these functions actually free everything
         * they allocate.
         */
        LOGE("LinearAlloc exceeded capacity (%d), last=%d\n",
            pHdr->mapLength, (int) size);
        dvmAbort();
    }

    /*
     * Round up "size" to encompass the entire region, including the 0-7
     * pad bytes before the next chunk header.  This way we get maximum
     * utility out of "realloc", and when we're doing ENFORCE_READ_ONLY
     * stuff we always treat the full extent.
     */
    size = nextOffset - (startOffset + HEADER_EXTRA);
    LOGVV("--- (size now %d)\n", size);

    /*
     * See if we are starting on or have crossed into a new page.  If so,
     * call mprotect on the page(s) we're about to write to.  We have to
     * page-align the start address, but don't have to make the length a
     * SYSTEM_PAGE_SIZE multiple (but we do it anyway).
     *
     * Note that "startOffset" is not the last *allocated* byte, but rather
     * the offset of the first *unallocated* byte (which we are about to
     * write the chunk header to).  "nextOffset" is similar.
     *
     * If ENFORCE_READ_ONLY is enabled, we have to call mprotect even if
     * we've written to this page before, because it might be read-only.
     */
    lastGoodOff = (startOffset-1) & ~(SYSTEM_PAGE_SIZE-1);
    firstWriteOff = startOffset & ~(SYSTEM_PAGE_SIZE-1);
    lastWriteOff = (nextOffset-1) & ~(SYSTEM_PAGE_SIZE-1);
    LOGVV("---  lastGood=0x%04x firstWrite=0x%04x lastWrite=0x%04x\n",
        lastGoodOff, firstWriteOff, lastWriteOff);
    if (lastGoodOff != lastWriteOff || ENFORCE_READ_ONLY) {
        int cc, start, len;

        start = firstWriteOff;
        assert(start <= nextOffset);
        len = (lastWriteOff - firstWriteOff) + SYSTEM_PAGE_SIZE;

        LOGVV("---    calling mprotect(start=%d len=%d RW)\n", start, len);
        cc = mprotect(pHdr->mapAddr + start, len, PROT_READ | PROT_WRITE);
        if (cc != 0) {
            LOGE("LinearAlloc mprotect (+%d %d) failed: %s\n",
                start, len, strerror(errno));
            /* we're going to fail soon, might as do it now */
            dvmAbort();
        }
    }

    /* update the ref counts on the now-writable pages */
    if (ENFORCE_READ_ONLY) {
        int i, start, end;

        start = firstWriteOff / SYSTEM_PAGE_SIZE;
        end = lastWriteOff / SYSTEM_PAGE_SIZE;

        LOGVV("---  marking pages %d-%d RW (alloc %d at %p)\n",
            start, end, size, pHdr->mapAddr + startOffset + HEADER_EXTRA);
        for (i = start; i <= end; i++)
            pHdr->writeRefCount[i]++;
    }

    /* stow the size in the header */
    if (ENFORCE_READ_ONLY)
        *(u4*)(pHdr->mapAddr + startOffset) = size | LENGTHFLAG_RW;
    else
        *(u4*)(pHdr->mapAddr + startOffset) = size;

    /*
     * Update data structure.
     */
    pHdr->curOffset = nextOffset;

    dvmUnlockMutex(&pHdr->lock);
    return pHdr->mapAddr + startOffset + HEADER_EXTRA;
}

/*
 * Helper function, replaces strdup().
 */
char* dvmLinearStrdup(Object* classLoader, const char* str)
{
#ifdef DISABLE_LINEAR_ALLOC
    return strdup(str);
#endif
    int len = strlen(str);
    void* mem = dvmLinearAlloc(classLoader, len+1);
    memcpy(mem, str, len+1);
    if (ENFORCE_READ_ONLY)
        dvmLinearSetReadOnly(classLoader, mem);
    return (char*) mem;
}

/*
 * "Reallocate" a piece of memory.
 *
 * If the new size is <= the old size, we return the original pointer
 * without doing anything.
 *
 * If the new size is > the old size, we allocate new storage, copy the
 * old stuff over, and mark the new stuff as free.
 */
void* dvmLinearRealloc(Object* classLoader, void* mem, size_t newSize)
{
#ifdef DISABLE_LINEAR_ALLOC
    return realloc(mem, newSize);
#endif
    /* make sure we have the right region (and mem != NULL) */
    assert(mem != NULL);
    assert(mem >= (void*) getHeader(classLoader)->mapAddr &&
           mem < (void*) (getHeader(classLoader)->mapAddr +
                          getHeader(classLoader)->curOffset));

    const u4* pLen = getBlockHeader(mem);
    LOGV("--- LinearRealloc(%d) old=%d\n", newSize, *pLen);

    /* handle size reduction case */
    if (*pLen >= newSize) {
        if (ENFORCE_READ_ONLY)
            dvmLinearSetReadWrite(classLoader, mem);
        return mem;
    }

    void* newMem;

    newMem = dvmLinearAlloc(classLoader, newSize);
    assert(newMem != NULL);
    memcpy(newMem, mem, *pLen);
    dvmLinearFree(classLoader, mem);

    return newMem;
}


/*
 * Update the read/write status of one or more pages.
 */
static void updatePages(Object* classLoader, void* mem, int direction)
{
    LinearAllocHdr* pHdr = getHeader(classLoader);
    dvmLockMutex(&pHdr->lock);

    /* make sure we have the right region */
    assert(mem >= (void*) pHdr->mapAddr &&
           mem < (void*) (pHdr->mapAddr + pHdr->curOffset));

    u4* pLen = getBlockHeader(mem);
    u4 len = *pLen & LENGTHFLAG_MASK;
    int firstPage, lastPage;

    firstPage = ((u1*)pLen - (u1*)pHdr->mapAddr) / SYSTEM_PAGE_SIZE;
    lastPage = ((u1*)mem - (u1*)pHdr->mapAddr + (len-1)) / SYSTEM_PAGE_SIZE;
    LOGVV("--- updating pages %d-%d (%d)\n", firstPage, lastPage, direction);

    int i, cc;

    /*
     * Update individual pages.  We could do some sort of "lazy update" to
     * combine mprotect calls, but that's almost certainly more trouble
     * than it's worth.
     */
    for (i = firstPage; i <= lastPage; i++) {
        if (direction < 0) {
            /*
             * Trying to mark read-only.
             */
            if (i == firstPage) {
                if ((*pLen & LENGTHFLAG_RW) == 0) {
                    LOGW("Double RO on %p\n", mem);
                    dvmAbort();
                } else
                    *pLen &= ~LENGTHFLAG_RW;
            }

            if (pHdr->writeRefCount[i] == 0) {
                LOGE("Can't make page %d any less writable\n", i);
                dvmAbort();
            }
            pHdr->writeRefCount[i]--;
            if (pHdr->writeRefCount[i] == 0) {
                LOGVV("---  prot page %d RO\n", i);
                cc = mprotect(pHdr->mapAddr + SYSTEM_PAGE_SIZE * i,
                        SYSTEM_PAGE_SIZE, PROT_READ);
                assert(cc == 0);
            }
        } else {
            /*
             * Trying to mark writable.
             */
            if (pHdr->writeRefCount[i] >= 32767) {
                LOGE("Can't make page %d any more writable\n", i);
                dvmAbort();
            }
            if (pHdr->writeRefCount[i] == 0) {
                LOGVV("---  prot page %d RW\n", i);
                cc = mprotect(pHdr->mapAddr + SYSTEM_PAGE_SIZE * i,
                        SYSTEM_PAGE_SIZE, PROT_READ | PROT_WRITE);
                assert(cc == 0);
            }
            pHdr->writeRefCount[i]++;

            if (i == firstPage) {
                if ((*pLen & LENGTHFLAG_RW) != 0) {
                    LOGW("Double RW on %p\n", mem);
                    dvmAbort();
                } else
                    *pLen |= LENGTHFLAG_RW;
            }
        }
    }

    dvmUnlockMutex(&pHdr->lock);
}

/*
 * Try to mark the pages in which a chunk of memory lives as read-only.
 * Whether or not the pages actually change state depends on how many
 * others are trying to access the same pages.
 *
 * Only call here if ENFORCE_READ_ONLY is true.
 */
void dvmLinearSetReadOnly(Object* classLoader, void* mem)
{
#ifdef DISABLE_LINEAR_ALLOC
    return;
#endif
    updatePages(classLoader, mem, -1);
}

/*
 * Make the pages on which "mem" sits read-write.
 *
 * This covers the header as well as the data itself.  (We could add a
 * "header-only" mode for dvmLinearFree.)
 *
 * Only call here if ENFORCE_READ_ONLY is true.
 */
void dvmLinearSetReadWrite(Object* classLoader, void* mem)
{
#ifdef DISABLE_LINEAR_ALLOC
    return;
#endif
    updatePages(classLoader, mem, 1);
}

/*
 * Mark an allocation as free.
 */
void dvmLinearFree(Object* classLoader, void* mem)
{
#ifdef DISABLE_LINEAR_ALLOC
    free(mem);
    return;
#endif
    if (mem == NULL)
        return;

    /* make sure we have the right region */
    assert(mem >= (void*) getHeader(classLoader)->mapAddr &&
           mem < (void*) (getHeader(classLoader)->mapAddr +
                          getHeader(classLoader)->curOffset));

    if (ENFORCE_READ_ONLY)
        dvmLinearSetReadWrite(classLoader, mem);

    u4* pLen = getBlockHeader(mem);
    *pLen |= LENGTHFLAG_FREE;

    if (ENFORCE_READ_ONLY)
        dvmLinearSetReadOnly(classLoader, mem);
}

/*
 * For debugging, dump the contents of a linear alloc area.
 *
 * We grab the lock so that the header contents and list output are
 * consistent.
 */
void dvmLinearAllocDump(Object* classLoader)
{
#ifdef DISABLE_LINEAR_ALLOC
    return;
#endif
    LinearAllocHdr* pHdr = getHeader(classLoader);

    dvmLockMutex(&pHdr->lock);

    LOGI("LinearAlloc classLoader=%p\n", classLoader);
    LOGI("  mapAddr=%p mapLength=%d firstOffset=%d\n",
        pHdr->mapAddr, pHdr->mapLength, pHdr->firstOffset);
    LOGI("  curOffset=%d\n", pHdr->curOffset);

    int off = pHdr->firstOffset;
    u4 rawLen, fullLen;

    while (off < pHdr->curOffset) {
        rawLen = *(u4*) (pHdr->mapAddr + off);
        fullLen = ((HEADER_EXTRA*2 + (rawLen & LENGTHFLAG_MASK))
                    & ~(BLOCK_ALIGN-1));

        LOGI("  %p (%3d): %clen=%d%s\n", pHdr->mapAddr + off + HEADER_EXTRA,
            (int) ((off + HEADER_EXTRA) / SYSTEM_PAGE_SIZE),
            (rawLen & LENGTHFLAG_FREE) != 0 ? '*' : ' ',
            rawLen & LENGTHFLAG_MASK,
            (rawLen & LENGTHFLAG_RW) != 0 ? " [RW]" : "");

        off += fullLen;
    }

    if (ENFORCE_READ_ONLY) {
        LOGI("writeRefCount map:\n");

        int numPages = (pHdr->mapLength+SYSTEM_PAGE_SIZE-1) / SYSTEM_PAGE_SIZE;
        int zstart = 0;
        int i;

        for (i = 0; i < numPages; i++) {
            int count = pHdr->writeRefCount[i];

            if (count != 0) {
                if (zstart < i-1)
                    printf(" %d-%d: zero\n", zstart, i-1);
                else if (zstart == i-1)
                    printf(" %d: zero\n", zstart);
                zstart = i+1;
                printf(" %d: %d\n", i, count);
            }
        }
        if (zstart < i)
            printf(" %d-%d: zero\n", zstart, i-1);
    }

    LOGD("LinearAlloc %p using %d of %d (%d%%)\n",
        classLoader, pHdr->curOffset, pHdr->mapLength,
        (pHdr->curOffset * 100) / pHdr->mapLength);

    dvmUnlockMutex(&pHdr->lock);
}

/*
 * Verify that all blocks are freed.
 *
 * This should only be done as we're shutting down, but there could be a
 * daemon thread that's still trying to do something, so we grab the locks.
 */
static void checkAllFree(Object* classLoader)
{
#ifdef DISABLE_LINEAR_ALLOC
    return;
#endif
    LinearAllocHdr* pHdr = getHeader(classLoader);

    dvmLockMutex(&pHdr->lock);

    int off = pHdr->firstOffset;
    u4 rawLen, fullLen;

    while (off < pHdr->curOffset) {
        rawLen = *(u4*) (pHdr->mapAddr + off);
        fullLen = ((HEADER_EXTRA*2 + (rawLen & LENGTHFLAG_MASK))
                    & ~(BLOCK_ALIGN-1));

        if ((rawLen & LENGTHFLAG_FREE) == 0) {
            LOGW("LinearAlloc %p not freed: %p len=%d\n", classLoader,
                pHdr->mapAddr + off + HEADER_EXTRA, rawLen & LENGTHFLAG_MASK);
        }

        off += fullLen;
    }

    dvmUnlockMutex(&pHdr->lock);
}

/*
 * Determine if [start, start+length) is contained in the in-use area of
 * a single LinearAlloc.  The full set of linear allocators is scanned.
 *
 * [ Since we currently only have one region, this is pretty simple.  In
 * the future we'll need to traverse a table of class loaders. ]
 */
bool dvmLinearAllocContains(const void* start, size_t length)
{
    LinearAllocHdr* pHdr = getHeader(NULL);

    if (pHdr == NULL)
        return false;

    return (char*) start >= pHdr->mapAddr &&
           ((char*)start + length) <= (pHdr->mapAddr + pHdr->curOffset);
}
