#include <windows.h> // This include needs to be here due to the coding conventions. Unfortunately // it drags in the definition of the ERROR macro. Similarly to base/utils.cc, // undefine the macro here. See also, the comment at android-base/logging.h. #ifdef ERROR #undef ERROR #endif
void* MemMap::TargetMMap(void* start, size_t len, int prot, int flags, int fd, off_t fd_off) {
UNUSED(start);
size_t padding = fd_off % allocation_granularity;
off_t file_offset = fd_off - padding;
off_t map_length = len + padding;
// Only read and write permissions are supported. if ((prot != PROT_READ) && (prot != (PROT_READ | PROT_WRITE))) {
PLOG(ERROR) << "Protection or flag error was not supported.";
errno = EINVAL; return MAP_FAILED;
} // Fixed is not currently supported either. // TODO(sehr): add MAP_FIXED support. if ((flags & MAP_FIXED) != 0) {
PLOG(ERROR) << "MAP_FIXED not supported.";
errno = EINVAL; return MAP_FAILED;
}
// Compute the Windows access flags for the two APIs from the PROTs and MAPs.
DWORD map_access = 0;
DWORD view_access = 0; if ((prot & PROT_WRITE) != 0) {
map_access = PAGE_READWRITE; if (((flags & MAP_SHARED) != 0) && ((flags & MAP_PRIVATE) == 0)) {
view_access = FILE_MAP_ALL_ACCESS;
} elseif (((flags & MAP_SHARED) == 0) && ((flags & MAP_PRIVATE) != 0)) {
view_access = FILE_MAP_COPY | FILE_MAP_READ;
} else {
PLOG(ERROR) << "MAP_PRIVATE and MAP_SHARED inconsistently set.";
errno = EINVAL; return MAP_FAILED;
}
} else {
map_access = PAGE_READONLY;
view_access = FILE_MAP_READ;
}
// MapViewOfFile does not like to see a size greater than the file size of the // underlying file object, unless the underlying file object is writable. If // the mapped region would go beyond the end of the underlying file, use zero, // as this indicates the physical size.
HANDLE file_handle = reinterpret_cast<HANDLE>(_get_osfhandle(fd));
LARGE_INTEGER file_length; if (!::GetFileSizeEx(file_handle, &file_length)) {
PLOG(ERROR) << "Couldn't get file size.";
errno = EINVAL; return MAP_FAILED;
} if (((map_access & PAGE_READONLY) != 0) &&
file_offset + map_length > file_length.QuadPart) {
map_length = 0;
}
// Create a file mapping object that will be used to access the file.
HANDLE handle = ::CreateFileMapping(reinterpret_cast<HANDLE>(_get_osfhandle(fd)),
nullptr,
map_access, 0, 0,
nullptr); if (handle == nullptr) {
DWORD error = ::GetLastError();
PLOG(ERROR) << StringPrintf("Couldn't create file mapping %lx.", error);
errno = EINVAL; return MAP_FAILED;
}
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.