/*
 * 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
    LinearAllocHdr* pHdr = getHeader(classLoader);

    /* make sure we have the right region (and mem != NULL) */
    assert(mem != NULL);
    assert(mem >= (void*) pHdr->mapAddr &&
           mem < (void*) (pHdr->mapAddr + pHdr->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;

    LinearAllocHdr* pHdr = getHeader(classLoader);

    /* make sure we have the right region */
    assert(mem >= (void*) pHdr->mapAddr &&
           mem < (void*) (pHdr->mapAddr + pHdr->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);
}

