SysUtil.cpp revision f6c387128427e121477c1b32ad35cdcaa5101ba3
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 */
16f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/*
17f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * System utilities.
18f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */
19f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project#include "DexFile.h"
20f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project#include "SysUtil.h"
21f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
22f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project#include <stdlib.h>
23f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project#include <stdio.h>
24f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project#include <unistd.h>
25f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project#include <string.h>
26f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
27f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project#ifdef HAVE_POSIX_FILEMAP
28f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project#include <sys/mman.h>
29f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project#endif
30f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
31f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project#include <limits.h>
32f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project#include <errno.h>
33f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
34f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/*
35f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Having trouble finding a portable way to get this.  sysconf(_SC_PAGE_SIZE)
36f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * seems appropriate, but we don't have that on the device.  Some systems
37f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * have getpagesize(2), though the linux man page has some odd cautions.
38f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */
39f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project#define DEFAULT_PAGE_SIZE   4096
40f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
41f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
42f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/*
43f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Create an anonymous shared memory segment large enough to hold "length"
44f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * bytes.  The actual segment may be larger because mmap() operates on
45f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * page boundaries (usually 4K).
46f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */
47f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectstatic void* sysCreateAnonShmem(size_t length)
48f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{
49f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project#ifdef HAVE_POSIX_FILEMAP
50f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    void* ptr;
51f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
52f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    ptr = mmap(NULL, length, PROT_READ | PROT_WRITE,
53f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            MAP_SHARED | MAP_ANON, -1, 0);
54f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    if (ptr == MAP_FAILED) {
55f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        LOGW("mmap(%d, RW, SHARED|ANON) failed: %s\n", (int) length,
56f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            strerror(errno));
57f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        return NULL;
58f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
59f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
60f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    return ptr;
61f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project#else
62f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    LOGE("sysCreateAnonShmem not implemented.\n");
63f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    return NULL;
64f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project#endif
65f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project}
66f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
67f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectstatic int getFileStartAndLength(int fd, off_t *start_, size_t *length_)
68f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{
69f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    off_t start, end;
70f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    size_t length;
71f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
72f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    assert(start_ != NULL);
73f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    assert(length_ != NULL);
74f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
75f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    start = lseek(fd, 0L, SEEK_CUR);
76f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    end = lseek(fd, 0L, SEEK_END);
77f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    (void) lseek(fd, start, SEEK_SET);
78f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
79f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    if (start == (off_t) -1 || end == (off_t) -1) {
80f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        LOGE("could not determine length of file\n");
81f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        return -1;
82f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
83f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
84f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    length = end - start;
85f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    if (length == 0) {
86f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        LOGE("file is empty\n");
87f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        return -1;
88f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
89f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
90f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    *start_ = start;
91f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    *length_ = length;
92f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
93f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    return 0;
94f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project}
95f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
96f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/*
97f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Pull the contents of a file into an new shared memory segment.  We grab
98f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * everything from fd's current offset on.
99f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project *
100f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * We need to know the length ahead of time so we can allocate a segment
101f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * of sufficient size.
102f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */
103f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectint sysLoadFileInShmem(int fd, MemMapping* pMap)
104f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{
105f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project#ifdef HAVE_POSIX_FILEMAP
106f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    off_t start;
107f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    size_t length, actual;
108f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    void* memPtr;
109f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
110f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    assert(pMap != NULL);
111f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
112f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    if (getFileStartAndLength(fd, &start, &length) < 0)
113f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        return -1;
114f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
115f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    memPtr = sysCreateAnonShmem(length);
116f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    if (memPtr == NULL)
117f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        return -1;
118f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
119f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    actual = read(fd, memPtr, length);
120f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    if (actual != length) {
121f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        LOGE("only read %d of %d bytes\n", (int) actual, (int) length);
122f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        sysReleaseShmem(pMap);
123f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        return -1;
124f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
125f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
126f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    pMap->baseAddr = pMap->addr = memPtr;
127f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    pMap->baseLength = pMap->length = length;
128f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
129f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    return 0;
130f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project#else
131f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    LOGE("sysLoadFileInShmem not implemented.\n");
132f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    return -1;
133f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project#endif
134f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project}
135f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
136f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/*
137f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Map a file (from fd's current offset) into a shared, read-only memory
138f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * segment.  The file offset must be a multiple of the page size.
139f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project *
140f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * On success, returns 0 and fills out "pMap".  On failure, returns a nonzero
141f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * value and does not disturb "pMap".
142f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */
143f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectint sysMapFileInShmem(int fd, MemMapping* pMap)
144f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{
145f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project#ifdef HAVE_POSIX_FILEMAP
146f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    off_t start;
147f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    size_t length;
148f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    void* memPtr;
149f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
150f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    assert(pMap != NULL);
151f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
152f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    if (getFileStartAndLength(fd, &start, &length) < 0)
153f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        return -1;
154f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
155f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    memPtr = mmap(NULL, length, PROT_READ, MAP_FILE | MAP_SHARED, fd, start);
156f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    if (memPtr == MAP_FAILED) {
157f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        LOGW("mmap(%d, R, FILE|SHARED, %d, %d) failed: %s\n", (int) length,
158f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            fd, (int) start, strerror(errno));
159f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        return -1;
160f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
161f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
162f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    pMap->baseAddr = pMap->addr = memPtr;
163f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    pMap->baseLength = pMap->length = length;
164f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
165f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    return 0;
166f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project#else
167f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    /* No MMAP, just fake it by copying the bits.
168f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project       For Win32 we could use MapViewOfFile if really necessary
169f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project       (see libs/utils/FileMap.cpp).
170f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    */
171f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    off_t start;
172f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    size_t length;
173f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    void* memPtr;
174f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
175f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    assert(pMap != NULL);
176f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
177f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    if (getFileStartAndLength(fd, &start, &length) < 0)
178f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        return -1;
179f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
180f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    memPtr = malloc(length);
181f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    if (read(fd, memPtr, length) < 0) {
182f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        LOGW("read(fd=%d, start=%d, length=%d) failed: %s\n", (int) length,
183f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            fd, (int) start, strerror(errno));
184f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        return -1;
185f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
186f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
187f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    pMap->baseAddr = pMap->addr = memPtr;
188f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    pMap->baseLength = pMap->length = length;
189f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
190f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    return 0;
191f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project#endif
192f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project}
193f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
194f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/*
195f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Map part of a file (from fd's current offset) into a shared, read-only
196f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * memory segment.
197f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project *
198f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * On success, returns 0 and fills out "pMap".  On failure, returns a nonzero
199f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * value and does not disturb "pMap".
200f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */
201f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectint sysMapFileSegmentInShmem(int fd, off_t start, long length,
202f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    MemMapping* pMap)
203f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{
204f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project#ifdef HAVE_POSIX_FILEMAP
205f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    off_t dummy;
206f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    size_t fileLength, actualLength;
207f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    off_t actualStart;
208f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    int adjust;
209f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    void* memPtr;
210f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
211f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    assert(pMap != NULL);
212f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
213f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    if (getFileStartAndLength(fd, &dummy, &fileLength) < 0)
214f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        return -1;
215f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
216f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    if (start + length > (long)fileLength) {
217f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        LOGW("bad segment: st=%d len=%ld flen=%d\n",
218f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            (int) start, length, (int) fileLength);
219f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        return -1;
220f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
221f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
222f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    /* adjust to be page-aligned */
223f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    adjust = start % DEFAULT_PAGE_SIZE;
224f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    actualStart = start - adjust;
225f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    actualLength = length + adjust;
226f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
227f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    memPtr = mmap(NULL, actualLength, PROT_READ, MAP_FILE | MAP_SHARED,
228f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                fd, actualStart);
229f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    if (memPtr == MAP_FAILED) {
230f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        LOGW("mmap(%d, R, FILE|SHARED, %d, %d) failed: %s\n",
231f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            (int) actualLength, fd, (int) actualStart, strerror(errno));
232f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        return -1;
233f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
234f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
235f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    pMap->baseAddr = memPtr;
236f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    pMap->baseLength = actualLength;
237f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    pMap->addr = (char*)memPtr + adjust;
238f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    pMap->length = length;
239f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
240f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    LOGVV("mmap seg (st=%d ln=%d): bp=%p bl=%d ad=%p ln=%d\n",
241f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        (int) start, (int) length,
242f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        pMap->baseAddr, (int) pMap->baseLength,
243f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        pMap->addr, (int) pMap->length);
244f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
245f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    return 0;
246f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project#else
247f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    LOGE("sysMapFileSegmentInShmem not implemented.\n");
248f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    return -1;
249f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project#endif
250f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project}
251f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
252f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/*
253f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Release a memory mapping.
254f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */
255f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectvoid sysReleaseShmem(MemMapping* pMap)
256f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{
257f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project#ifdef HAVE_POSIX_FILEMAP
258f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    if (pMap->baseAddr == NULL && pMap->baseLength == 0)
259f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        return;
260f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
261f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    if (munmap(pMap->baseAddr, pMap->baseLength) < 0) {
262f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        LOGW("munmap(%p, %d) failed: %s\n",
263f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            pMap->baseAddr, (int)pMap->baseLength, strerror(errno));
264f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    } else {
265f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        LOGV("munmap(%p, %d) succeeded\n", pMap->baseAddr, pMap->baseLength);
266f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        pMap->baseAddr = NULL;
267f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        pMap->baseLength = 0;
268f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
269f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project#else
270f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    /* Free the bits allocated by sysMapFileInShmem. */
271f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    if (pMap->baseAddr != NULL) {
272f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project      free(pMap->baseAddr);
273f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project      pMap->baseAddr = NULL;
274f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
275f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    pMap->baseLength = 0;
276f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project#endif
277f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project}
278f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
279f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/*
280f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Make a copy of a MemMapping.
281f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */
282f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectvoid sysCopyMap(MemMapping* dst, const MemMapping* src)
283f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{
284f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    memcpy(dst, src, sizeof(MemMapping));
285f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project}
286f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
287