2 * Copyright 2008, Google Inc.
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are
9 * * Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
11 * * Redistributions in binary form must reproduce the above
12 * copyright notice, this list of conditions and the following disclaimer
13 * in the documentation and/or other materials provided with the
15 * * Neither the name of Google Inc. nor the names of its
16 * contributors may be used to endorse or promote products derived from
17 * this software without specific prior written permission.
19 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
20 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
21 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
22 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
23 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
24 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
25 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
26 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
27 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
28 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
29 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
38 #include "native_client/service_runtime/nacl_config.h"
39 #include "native_client/service_runtime/nacl_check.h"
40 #include "native_client/service_runtime/dyn_array.h"
41 #include "native_client/service_runtime/sel_ldr.h"
42 #include "native_client/service_runtime/sel_rt.h"
43 #include "native_client/service_runtime/nacl_app_thread.h"
44 #include "native_client/service_runtime/nacl_ldt.h"
45 #include "native_client/service_runtime/nacl_log.h"
46 #include "native_client/service_runtime/nacl_desc_base.h"
49 * Allocate ldt for app, without creating the main thread.
51 NaClErrorCode
NaClAppPrepareToLaunch(struct NaClApp
*nap
)
64 struct NaClHostDesc
*nhdp
;
66 data_start
= nap
->data_mem_start
;
67 CHECK(nap
->addr_bits
> NACL_PAGESHIFT
);
68 data_pages
= 1 << (nap
->addr_bits
- NACL_PAGESHIFT
);
71 * Determine what region of memory can be accessed as code.
73 code_start
= nap
->code_mem_start
;
74 if (nap
->data_mem_start
== nap
->code_mem_start
)
76 code_bytes
= nap
->text_region_end
;
77 VCHECK((code_bytes
& ((1 << NACL_PAGESHIFT
)-1)) == 0,
78 ("code_bytes (0x%08x) is not page aligned\n",
80 code_pages
= code_bytes
>> NACL_PAGESHIFT
;
83 code_pages
= data_pages
;
86 NaClLog(LOG_FATAL
, "NaClAppPrepareToLaunch: fewer than one code pages?\n");
88 NaClLog(2, "NaClLdtAllocatePageSelector(code, 1, 0x%08x, 0x%x\n",
89 code_start
, code_pages
);
90 cs
= NaClLdtAllocatePageSelector(NACL_LDT_DESCRIPTOR_CODE
,
94 NaClLog(2, "got 0x%x\n", cs
);
96 return SRT_NO_SEG_SEL
;
100 * Determine what region of memory can be accessed as data.
102 * NB: in our memory model, we roughly follow standard 7th edition
103 * unix but with a >16-bit address space: data and code overlap, and
104 * the start of the data segment is the same as the start of the
105 * code region; and the data segment actually includes the memory
106 * hole between the break and the top of the stack, as well as the
107 * stack and environment variables and other things in memory above
110 * The code pages, which is marked read-only via the page protection
111 * mechanism, could be viewed as read-only data. Nothing prevents a
112 * NaCl application from looking at its own code.
114 * The same segment selector is used for ds, es, and ss, and thus
115 * "des_seg". Nuthin' to do with the old Data Encryption Standard.
118 if (data_pages
< 1) {
120 "NaClAppPrepareToLaunch: address space is fewer than one page?\n");
122 NaClLog(2, "NaClLdtAllocatePageSelector(data, 1, 0x%08x, 0x%x\n",
123 data_start
, data_pages
- 1);
124 des_seg
= NaClLdtAllocatePageSelector(NACL_LDT_DESCRIPTOR_DATA
,
129 NaClLog(2, "got 0x%x\n", des_seg
);
131 NaClLdtDeleteSelector(cs
);
132 return SRT_NO_SEG_SEL
;
134 nap
->code_seg_sel
= cs
;
135 nap
->data_seg_sel
= des_seg
;
137 * Note that gs is thread-specific and not global, so that is allocated
138 * elsewhere. See nacl_app_thread.c.
142 * We dup the stdin, stdout, and stderr descriptors and wrap them in
143 * NaClHostDesc objects. Those in turn are wrapped by the
144 * NaClDescIoDesc subclass of NaClDesc, and then put into the
145 * open-file table. NaCl app I/O operations will use these shared
146 * descriptors, and if they close one of these descriptors it will
147 * only be a duplicated descriptor. NB: some fcntl/ioctl flags
148 * apply to the descriptor (e.g., O_CLOEXEC) and some apply to the
149 * underlying open file entry (e.g., O_NONBLOCK), so changes by the
150 * NaCl app could affect the service runtime.
152 for (i
= 0; i
< 3; ++i
) {
153 nhdp
= malloc(sizeof *nhdp
);
156 "NaClAppPrepareToLaunch: no memory for abstract descriptor %d\n",
159 NaClHostDescPosixDup(nhdp
, i
, (0 == i
) ? O_RDONLY
: O_WRONLY
);
160 NaClSetDesc(nap
, i
, (struct NaClDesc
*) NaClDescIoDescMake(nhdp
));