1 : /*
2 : * Copyright (c) 2012 The Native Client Authors. All rights reserved.
3 : * Use of this source code is governed by a BSD-style license that can be
4 : * found in the LICENSE file.
5 : */
6 :
7 : /* @file
8 : *
9 : * Implementation of service runtime effector subclass used for all
10 : * application threads.
11 : */
12 : #include "native_client/src/shared/platform/nacl_host_desc.h"
13 :
14 : #include "native_client/src/trusted/service_runtime/nacl_desc_effector_ldr.h"
15 :
16 : #include "native_client/src/trusted/service_runtime/include/bits/mman.h"
17 : #include "native_client/src/trusted/service_runtime/nacl_syscall_common.h"
18 :
19 :
20 : static struct NaClDescEffectorVtbl const NaClDescEffectorLdrVtbl; /* fwd */
21 :
22 295 : int NaClDescEffectorLdrCtor(struct NaClDescEffectorLdr *self,
23 295 : struct NaClApp *nap) {
24 295 : self->base.vtbl = &NaClDescEffectorLdrVtbl;
25 295 : self->nap = nap;
26 295 : return 1;
27 : }
28 :
29 : #if NACL_WINDOWS
30 : static void NaClDescEffLdrUnmapMemory(struct NaClDescEffector *vself,
31 : uintptr_t sysaddr,
32 : size_t nbytes) {
33 : struct NaClDescEffectorLdr *self = (struct NaClDescEffectorLdr *) vself;
34 : uintptr_t addr;
35 : uintptr_t endaddr;
36 : uintptr_t usraddr;
37 : struct NaClVmmapEntry const *map_region;
38 :
39 : NaClLog(4,
40 : ("NaClDescEffLdrUnmapMemory(0x%08"NACL_PRIxPTR", 0x%08"NACL_PRIxPTR
41 : ", 0x%"NACL_PRIxS")\n"),
42 : (uintptr_t) vself, (uintptr_t) sysaddr, nbytes);
43 :
44 : for (addr = sysaddr, endaddr = sysaddr + nbytes;
45 : addr < endaddr;
46 : addr += NACL_MAP_PAGESIZE) {
47 : usraddr = NaClSysToUser(self->nap, addr);
48 :
49 : map_region = NaClVmmapFindPage(&self->nap->mem_map,
50 : usraddr >> NACL_PAGESHIFT);
51 : /*
52 : * When mapping beyond the end of file, the mapping will be rounded to
53 : * the 64k page boundary and the remaining space will be marked as
54 : * inaccessible by marking the pages as MEM_RESERVE.
55 : *
56 : * When unmapping the memory region, we use the file size, recorded in
57 : * the VmmapEntry to prevent a race condition when file size changes
58 : * after it was mmapped, together with the page num and offset to check
59 : * whether the page is the one backed by the file, in which case we
60 : * need to unmap it, or whether it's one of the tail pages backed by the
61 : * virtual memory in which case we need to release it.
62 : */
63 : if (NULL != map_region &&
64 : NULL != map_region->desc &&
65 : (map_region->offset + (usraddr -
66 : (map_region->page_num << NACL_PAGESHIFT))
67 : < (uintptr_t) map_region->file_size)) {
68 : if (!UnmapViewOfFile((void *) addr)) {
69 : NaClLog(LOG_FATAL,
70 : ("NaClDescEffLdrUnmapMemory: UnmapViewOfFile failed at"
71 : " user addr 0x%08"NACL_PRIxPTR" (sys 0x%08"NACL_PRIxPTR")"
72 : " error %d\n"),
73 : usraddr, addr, GetLastError());
74 : }
75 : } else {
76 : /*
77 : * No memory in address space, and we have only MEM_RESERVE'd
78 : * the address space; or memory is in address space, but not
79 : * backed by a file.
80 : */
81 : if (!VirtualFree((void *) addr, 0, MEM_RELEASE)) {
82 : NaClLog(LOG_FATAL,
83 : ("NaClDescEffLdrUnmapMemory: VirtualFree at user addr"
84 : " 0x%08"NACL_PRIxPTR" (sys 0x%08"NACL_PRIxPTR") failed:"
85 : " error %d\n"),
86 : usraddr, addr, GetLastError());
87 : }
88 : }
89 : }
90 : }
91 :
92 : #else /* NACL_WINDOWS */
93 :
94 0 : static void NaClDescEffLdrUnmapMemory(struct NaClDescEffector *vself,
95 0 : uintptr_t sysaddr,
96 0 : size_t nbytes) {
97 0 : UNREFERENCED_PARAMETER(vself);
98 0 : UNREFERENCED_PARAMETER(sysaddr);
99 0 : UNREFERENCED_PARAMETER(nbytes);
100 0 : }
101 : #endif /* NACL_WINDOWS */
102 :
103 : static struct NaClDescEffectorVtbl const NaClDescEffectorLdrVtbl = {
104 : NaClDescEffLdrUnmapMemory,
105 : };
|