home *** CD-ROM | disk | FTP | other *** search
- /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
- /*
- * The contents of this file are subject to the Netscape Public License
- * Version 1.0 (the "NPL"); you may not use this file except in
- * compliance with the NPL. You may obtain a copy of the NPL at
- * http://www.mozilla.org/NPL/
- *
- * Software distributed under the NPL is distributed on an "AS IS" basis,
- * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
- * for the specific language governing rights and limitations under the
- * NPL.
- *
- * The Initial Developer of this code under the NPL is Netscape
- * Communications Corporation. Portions created by Netscape are
- * Copyright (C) 1998 Netscape Communications Corporation. All Rights
- * Reserved.
- */
-
- #include "primpl.h"
-
- void _PR_InitSegs(void)
- {
- _PR_MD_INIT_SEGS();
- }
-
- /*
- ** Allocate a memory segment. The size value is rounded up to the native
- ** system page size and a page aligned portion of memory is returned.
- ** This memory is not part of the malloc heap. If "vaddr" is not NULL
- ** then PR tries to allocate the segment at the desired virtual address.
- */
- PR_IMPLEMENT(PRSegment*) PR_NewSegment(PRUint32 size, void *vaddr)
- {
- PRSegment *seg;
-
- /* calloc the data structure for the segment */
- seg = PR_NEWZAP(PRSegment);
-
- if (seg) {
- size = ((size + _pr_pageSize - 1) >> _pr_pageShift) << _pr_pageShift;
- /*
- ** Now, allocate the actual segment memory (or map under some OS)
- ** The OS specific code decides from where or how to allocate memory.
- */
- if (_PR_MD_ALLOC_SEGMENT(seg, size, vaddr) != PR_SUCCESS) {
- PR_DELETE(seg);
- return NULL;
- }
- }
-
- return seg;
- }
-
- /*
- ** Free a memory segment.
- */
- PR_IMPLEMENT(void) PR_DestroySegment(PRSegment *seg)
- {
- _PR_MD_FREE_SEGMENT(seg);
- PR_DELETE(seg);
- }
-
- /* XXX Fix the following to make machine-independent */
- #ifdef XP_UNIX
- #include <sys/mman.h>
- #endif
-
- #ifndef PROT_NONE
- #define PROT_NONE 0
- #endif
-
- extern PRInt32 _pr_zero_fd;
-
- /*
- ** Attempt to grow/shrink the given segment.
- */
- PR_IMPLEMENT(PRUint32) PR_GrowSegment(PRSegment *seg, PRInt32 delta)
- {
- char *oldend, *newend;
- #if 0
- #ifdef XP_UNIX
- int prot;
- void *rv = (void *) -1;
- #endif
- #endif /* 0 */
-
- if (!(seg->flags & _PR_SEG_VM)) {
- return 0;
- }
-
- oldend = (char*)seg->vaddr + seg->size;
- if (delta > 0) {
- #if 0
-
- /*
- * CANNOT use MAP_FIXED because it will replace any existing mappings
- */
- /* Growing the segment */
- delta = ((delta + _pr_pageSize - 1) >> _pr_pageShift) << _pr_pageShift;
- newend = oldend + delta;
- #ifdef XP_UNIX
- prot = PROT_READ|PROT_WRITE;
- rv = mmap(oldend, delta, prot,
- #ifdef OSF1
- /* XXX need to pick a vaddr to use */
- MAP_PRIVATE|MAP_FIXED,
- #else
- MAP_SHARED|MAP_FIXED,
- #endif
- _pr_zero_fd, 0);
- #endif /* XP_UNIX */
- if (rv == (void*)-1) {
- /* Can't extend the heap */
- return 0;
- }
- seg->size = seg->size + delta;
- #endif /* 0 */
- } else if (delta < 0) {
- /* Shrinking the segment */
- delta = -delta;
- delta = (delta >> _pr_pageShift) << _pr_pageShift; /* trunc */
- if ((PRUint32)delta >= seg->size) {
- /* XXX what to do? */
- return 0;
- }
- newend = oldend - delta;
- if (newend < oldend) {
- #ifdef XP_UNIX
- (void) munmap(oldend, newend - oldend);
- seg->size = seg->size + delta;
- #endif
- }
- }
- return delta;
- }
-
- /*
- ** Change the mapping on a segment.
- ** "how" == PR_SEGMENT_NONE: the segment becomes unmapped
- ** "how" == PR_SEGMENT_RDONLY: the segment becomes mapped and readable
- ** "how" == PR_SEGMENT_RDWR: the segment becomes mapped read/write
- **
- ** If a segment can be read then it is also possible to execute code in
- ** it.
- */
- PR_IMPLEMENT(void) PR_MapSegment(PRSegment *seg, PRSegmentAccess how)
- {
- if (seg->access == how) return;
- seg->access = how;
-
- #ifdef XP_UNIX
- if (seg->flags & _PR_SEG_VM) {
- int prot;
- switch (how) {
- case PR_SEGMENT_NONE:
- prot = PROT_NONE;
- break;
- case PR_SEGMENT_RDONLY:
- prot = PROT_READ;
- break;
- case PR_SEGMENT_RDWR:
- prot = PROT_READ|PROT_WRITE;
- break;
- }
- (void) mprotect(seg->vaddr, seg->size, prot);
- }
- #endif
- }
-
- /*
- ** Return the size of the segment
- */
- PR_IMPLEMENT(size_t) PR_GetSegmentSize(PRSegment *seg)
- {
- return seg->size;
- }
-
- /*
- ** Return the virtual address of the segment
- */
- PR_IMPLEMENT(void*) PR_GetSegmentVaddr(PRSegment *seg)
- {
- return seg->vaddr;
- }
-
- /*
- ** Return a segments current access rights
- */
- PR_IMPLEMENT(PRSegmentAccess) PR_GetSegmentAccess(PRSegment *seg)
- {
- return seg->access;
- }
-