1 // Copyright 2014 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
8 #include "base/logging.h"
9 #include "components/nacl/loader/nonsfi/irt_interfaces.h"
10 #include "components/nacl/loader/nonsfi/irt_util.h"
11 #include "native_client/src/trusted/service_runtime/include/machine/_types.h"
12 #include "native_client/src/trusted/service_runtime/include/sys/mman.h"
18 int NaClProtToProt(int nacl_prot
) {
20 if ((nacl_prot
& NACL_ABI_PROT_MASK
) == NACL_ABI_PROT_NONE
)
23 if (nacl_prot
& NACL_ABI_PROT_READ
)
25 if (nacl_prot
& NACL_ABI_PROT_WRITE
)
27 if (nacl_prot
& NACL_ABI_PROT_EXEC
)
32 int NaClFlagsToFlags(int nacl_flags
) {
35 if (nacl_flags
& NACL_ABI_MAP_SHARED
)
37 if (nacl_flags
& NACL_ABI_MAP_PRIVATE
)
39 if (nacl_flags
& NACL_ABI_MAP_FIXED
)
42 // Note: NACL_ABI_MAP_ANON is an alias of NACL_ABI_MAP_ANONYMOUS.
43 if (nacl_flags
& NACL_ABI_MAP_ANONYMOUS
)
44 flags
|= MAP_ANONYMOUS
;
48 int IrtMMap(void** addr
, size_t len
, int prot
, int flags
,
49 int fd
, nacl_abi_off_t off
) {
50 const int host_prot
= NaClProtToProt(prot
);
51 // On Chrome OS, mmap can fail if PROT_EXEC is set in |host_prot|,
52 // but mprotect will allow changing the permissions later.
53 // This is because Chrome OS mounts writable filesystems with "noexec".
55 *addr
, len
, host_prot
& ~PROT_EXEC
, NaClFlagsToFlags(flags
), fd
, off
);
56 if (result
== MAP_FAILED
)
58 if (host_prot
& PROT_EXEC
) {
59 if (mprotect(result
, len
, host_prot
) != 0) {
60 // This aborts here because it cannot easily undo the mmap() call.
61 PLOG(FATAL
) << "IrtMMap: mprotect to turn on PROT_EXEC failed.";
69 int IrtMUnmap(void* addr
, size_t len
) {
70 return CheckError(munmap(addr
, len
));
73 int IrtMProtect(void* addr
, size_t len
, int prot
) {
74 return CheckError(mprotect(addr
, len
, NaClProtToProt(prot
)));
79 // For mmap, the argument types should be nacl_abi_off_t rather than off_t.
80 // However, the definition of nacl_irt_memory uses the host type off_t, so here
81 // we need to cast it.
82 const nacl_irt_memory kIrtMemory
= {
83 reinterpret_cast<int(*)(void**, size_t, int, int, int, off_t
)>(IrtMMap
),