SysUtil.cpp revision 99409883d9c4c0ffb49b070ce307bb33a9dfe9f1
1f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/* 2f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Copyright (C) 2008 The Android Open Source Project 3f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 4f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Licensed under the Apache License, Version 2.0 (the "License"); 5f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * you may not use this file except in compliance with the License. 6f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * You may obtain a copy of the License at 7f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 8f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * http://www.apache.org/licenses/LICENSE-2.0 9f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 10f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Unless required by applicable law or agreed to in writing, software 11f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * distributed under the License is distributed on an "AS IS" BASIS, 12f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * See the License for the specific language governing permissions and 14f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * limitations under the License. 15f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 1699409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project 17f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/* 18f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * System utilities. 19f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 20f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project#include "DexFile.h" 21f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project#include "SysUtil.h" 22f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 23f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project#include <stdlib.h> 24f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project#include <stdio.h> 25f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project#include <unistd.h> 26f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project#include <string.h> 27f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 28f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project#ifdef HAVE_POSIX_FILEMAP 29f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project#include <sys/mman.h> 30f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project#endif 31f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 32f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project#include <limits.h> 33f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project#include <errno.h> 34f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 35f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/* 36f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Having trouble finding a portable way to get this. sysconf(_SC_PAGE_SIZE) 37f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * seems appropriate, but we don't have that on the device. Some systems 38f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * have getpagesize(2), though the linux man page has some odd cautions. 39f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 40f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project#define DEFAULT_PAGE_SIZE 4096 41f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 42f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 43f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/* 44f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Create an anonymous shared memory segment large enough to hold "length" 45f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * bytes. The actual segment may be larger because mmap() operates on 46f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * page boundaries (usually 4K). 47f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 48f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectstatic void* sysCreateAnonShmem(size_t length) 49f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{ 50f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project#ifdef HAVE_POSIX_FILEMAP 51f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project void* ptr; 52f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 53f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project ptr = mmap(NULL, length, PROT_READ | PROT_WRITE, 54f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project MAP_SHARED | MAP_ANON, -1, 0); 55f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (ptr == MAP_FAILED) { 56f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project LOGW("mmap(%d, RW, SHARED|ANON) failed: %s\n", (int) length, 57f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project strerror(errno)); 58f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return NULL; 59f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 60f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 61f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return ptr; 62f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project#else 63f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project LOGE("sysCreateAnonShmem not implemented.\n"); 64f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return NULL; 65f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project#endif 66f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project} 67f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 6899409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project/* 6999409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project * Create a private anonymous storage area. 7099409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project */ 7199409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Projectint sysCreatePrivateMap(size_t length, MemMapping* pMap) 7299409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project{ 7399409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project void* memPtr; 7499409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project 7599409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project memPtr = sysCreateAnonShmem(length); 7699409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project if (memPtr == NULL) 7799409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project return -1; 7899409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project 7999409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project pMap->addr = pMap->baseAddr = memPtr; 8099409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project pMap->length = pMap->baseLength = length; 8199409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project return 0; 8299409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project} 8399409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project 8499409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project/* 8599409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project * Determine the current offset and remaining length of the open file. 8699409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project */ 87f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectstatic int getFileStartAndLength(int fd, off_t *start_, size_t *length_) 88f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{ 89f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project off_t start, end; 90f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project size_t length; 91f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 92f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project assert(start_ != NULL); 93f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project assert(length_ != NULL); 94f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 95f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project start = lseek(fd, 0L, SEEK_CUR); 96f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project end = lseek(fd, 0L, SEEK_END); 97f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project (void) lseek(fd, start, SEEK_SET); 98f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 99f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (start == (off_t) -1 || end == (off_t) -1) { 100f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project LOGE("could not determine length of file\n"); 101f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return -1; 102f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 103f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 104f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project length = end - start; 105f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (length == 0) { 106f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project LOGE("file is empty\n"); 107f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return -1; 108f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 109f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 110f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project *start_ = start; 111f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project *length_ = length; 112f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 113f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return 0; 114f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project} 115f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 116f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/* 117f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Pull the contents of a file into an new shared memory segment. We grab 118f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * everything from fd's current offset on. 119f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 120f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * We need to know the length ahead of time so we can allocate a segment 121f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * of sufficient size. 122f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 123f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectint sysLoadFileInShmem(int fd, MemMapping* pMap) 124f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{ 125f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project#ifdef HAVE_POSIX_FILEMAP 126f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project off_t start; 127f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project size_t length, actual; 128f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project void* memPtr; 129f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 130f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project assert(pMap != NULL); 131f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 132f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (getFileStartAndLength(fd, &start, &length) < 0) 133f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return -1; 134f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 135f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project memPtr = sysCreateAnonShmem(length); 136f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (memPtr == NULL) 137f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return -1; 138f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 139f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project actual = read(fd, memPtr, length); 140f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (actual != length) { 141f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project LOGE("only read %d of %d bytes\n", (int) actual, (int) length); 142f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project sysReleaseShmem(pMap); 143f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return -1; 144f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 145f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 146f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project pMap->baseAddr = pMap->addr = memPtr; 147f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project pMap->baseLength = pMap->length = length; 148f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 149f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return 0; 150f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project#else 151f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project LOGE("sysLoadFileInShmem not implemented.\n"); 152f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return -1; 153f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project#endif 154f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project} 155f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 156f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/* 157f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Map a file (from fd's current offset) into a shared, read-only memory 158f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * segment. The file offset must be a multiple of the page size. 159f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 160f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * On success, returns 0 and fills out "pMap". On failure, returns a nonzero 161f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * value and does not disturb "pMap". 162f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 163f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectint sysMapFileInShmem(int fd, MemMapping* pMap) 164f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{ 165f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project#ifdef HAVE_POSIX_FILEMAP 166f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project off_t start; 167f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project size_t length; 168f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project void* memPtr; 169f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 170f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project assert(pMap != NULL); 171f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 172f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (getFileStartAndLength(fd, &start, &length) < 0) 173f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return -1; 174f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 175f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project memPtr = mmap(NULL, length, PROT_READ, MAP_FILE | MAP_SHARED, fd, start); 176f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (memPtr == MAP_FAILED) { 177f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project LOGW("mmap(%d, R, FILE|SHARED, %d, %d) failed: %s\n", (int) length, 178f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project fd, (int) start, strerror(errno)); 179f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return -1; 180f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 181f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 182f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project pMap->baseAddr = pMap->addr = memPtr; 183f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project pMap->baseLength = pMap->length = length; 184f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 185f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return 0; 186f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project#else 187f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* No MMAP, just fake it by copying the bits. 188f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project For Win32 we could use MapViewOfFile if really necessary 189f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project (see libs/utils/FileMap.cpp). 190f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 191f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project off_t start; 192f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project size_t length; 193f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project void* memPtr; 194f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 195f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project assert(pMap != NULL); 196f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 197f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (getFileStartAndLength(fd, &start, &length) < 0) 198f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return -1; 199f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 200f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project memPtr = malloc(length); 201f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (read(fd, memPtr, length) < 0) { 202f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project LOGW("read(fd=%d, start=%d, length=%d) failed: %s\n", (int) length, 203f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project fd, (int) start, strerror(errno)); 204f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return -1; 205f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 206f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 207f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project pMap->baseAddr = pMap->addr = memPtr; 208f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project pMap->baseLength = pMap->length = length; 209f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 210f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return 0; 211f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project#endif 212f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project} 213f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 214f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/* 215f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Map part of a file (from fd's current offset) into a shared, read-only 216f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * memory segment. 217f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 218f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * On success, returns 0 and fills out "pMap". On failure, returns a nonzero 219f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * value and does not disturb "pMap". 220f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 221f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectint sysMapFileSegmentInShmem(int fd, off_t start, long length, 222f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project MemMapping* pMap) 223f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{ 224f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project#ifdef HAVE_POSIX_FILEMAP 225f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project off_t dummy; 226f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project size_t fileLength, actualLength; 227f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project off_t actualStart; 228f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project int adjust; 229f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project void* memPtr; 230f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 231f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project assert(pMap != NULL); 232f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 233f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (getFileStartAndLength(fd, &dummy, &fileLength) < 0) 234f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return -1; 235f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 236f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (start + length > (long)fileLength) { 237f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project LOGW("bad segment: st=%d len=%ld flen=%d\n", 238f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project (int) start, length, (int) fileLength); 239f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return -1; 240f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 241f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 242f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* adjust to be page-aligned */ 243f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project adjust = start % DEFAULT_PAGE_SIZE; 244f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project actualStart = start - adjust; 245f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project actualLength = length + adjust; 246f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 247f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project memPtr = mmap(NULL, actualLength, PROT_READ, MAP_FILE | MAP_SHARED, 248f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project fd, actualStart); 249f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (memPtr == MAP_FAILED) { 250f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project LOGW("mmap(%d, R, FILE|SHARED, %d, %d) failed: %s\n", 251f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project (int) actualLength, fd, (int) actualStart, strerror(errno)); 252f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return -1; 253f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 254f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 255f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project pMap->baseAddr = memPtr; 256f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project pMap->baseLength = actualLength; 257f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project pMap->addr = (char*)memPtr + adjust; 258f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project pMap->length = length; 259f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 260f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project LOGVV("mmap seg (st=%d ln=%d): bp=%p bl=%d ad=%p ln=%d\n", 261f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project (int) start, (int) length, 262f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project pMap->baseAddr, (int) pMap->baseLength, 263f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project pMap->addr, (int) pMap->length); 264f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 265f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return 0; 266f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project#else 267f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project LOGE("sysMapFileSegmentInShmem not implemented.\n"); 268f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return -1; 269f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project#endif 270f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project} 271f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 272f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/* 273f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Release a memory mapping. 274f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 275f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectvoid sysReleaseShmem(MemMapping* pMap) 276f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{ 277f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project#ifdef HAVE_POSIX_FILEMAP 278f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (pMap->baseAddr == NULL && pMap->baseLength == 0) 279f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return; 280f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 281f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (munmap(pMap->baseAddr, pMap->baseLength) < 0) { 282f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project LOGW("munmap(%p, %d) failed: %s\n", 283f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project pMap->baseAddr, (int)pMap->baseLength, strerror(errno)); 284f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } else { 285f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project LOGV("munmap(%p, %d) succeeded\n", pMap->baseAddr, pMap->baseLength); 286f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project pMap->baseAddr = NULL; 287f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project pMap->baseLength = 0; 288f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 289f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project#else 290f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* Free the bits allocated by sysMapFileInShmem. */ 291f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (pMap->baseAddr != NULL) { 292f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project free(pMap->baseAddr); 293f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project pMap->baseAddr = NULL; 294f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 295f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project pMap->baseLength = 0; 296f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project#endif 297f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project} 298f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 299f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/* 300f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Make a copy of a MemMapping. 301f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 302f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectvoid sysCopyMap(MemMapping* dst, const MemMapping* src) 303f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{ 304f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project memcpy(dst, src, sizeof(MemMapping)); 305f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project} 306f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 307