Upstream version 9.38.198.0
[platform/framework/web/crosswalk.git] / src / native_client / src / trusted / service_runtime / arch / x86_32 / nacl_app_32.c
1 /*
2  * Copyright 2008 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 /*
8  * NaCl run time.
9  */
10
11 #include <fcntl.h>
12
13 #include "native_client/src/shared/platform/nacl_check.h"
14 #include "native_client/src/shared/platform/nacl_host_desc.h"
15 #include "native_client/src/shared/platform/nacl_sync_checked.h"
16
17 #include "native_client/src/trusted/desc/nacl_desc_io.h"
18
19 #include "native_client/src/trusted/service_runtime/arch/x86/nacl_ldt_x86.h"
20 #include "native_client/src/trusted/service_runtime/nacl_app.h"
21 #include "native_client/src/trusted/service_runtime/sel_ldr.h"
22
23
24 static uint16_t NaClAllocateSegmentForCodeRegion(struct NaClApp *nap) {
25   uintptr_t code_start = nap->mem_start;
26   size_t    code_bytes = nap->dynamic_text_end;
27   size_t    code_pages = code_bytes >> NACL_PAGESHIFT;
28
29   VCHECK((code_bytes & ((1 << NACL_PAGESHIFT) - 1)) == 0,
30         ("code_bytes (0x%08"NACL_PRIxS") is not page aligned\n",
31          code_bytes));
32
33   if (code_pages < 1) {
34     NaClLog(LOG_FATAL,
35             "NaClAllocateSegmentForCodeRegion: fewer than one code pages?\n");
36   }
37   NaClLog(2,
38           "NaClLdtAllocatePageSelector(code, 1, 0x%08"
39           NACL_PRIxPTR", 0x%"NACL_PRIxS"\n",
40           code_start, code_pages);
41
42   return NaClLdtAllocatePageSelector(NACL_LDT_DESCRIPTOR_CODE,
43                                      1,
44                                      (void *) code_start,
45                                      code_pages);
46 }
47
48
49 /*
50  * NB: in our memory model, we roughly follow standard 7th edition unix but with
51  * a >16-bit address space: data and code overlap, and the start of the data
52  * segment is the same as the start of the code region; and the data segment
53  * actually includes the memory hole between the break and the top of the stack,
54  * as well as the stack and environment variables and other things in memory
55  * above the stack.
56  *
57  * The code pages, which is marked read-only via the page protection mechanism,
58  * could be viewed as read-only data.  Nothing prevents a NaCl application from
59  * looking at its own code.
60  *
61  * The same segment selector is used for ds, es, and ss, and thus "des_seg".
62  * Nuthin' to do with the old Data Encryption Standard.
63  */
64 static uint16_t NaClAllocateSegmentForDataRegion(struct NaClApp *nap) {
65   uintptr_t           data_start = nap->mem_start;
66   size_t              data_pages = ((size_t) 1U <<
67                                     (nap->addr_bits - NACL_PAGESHIFT));
68
69   CHECK(nap->addr_bits > NACL_PAGESHIFT);
70
71   if (data_pages < 1) {
72     NaClLog(LOG_FATAL,
73             "NaClAllocateSegmentForDataRegion: address space"
74             " is fewer than one page?\n");
75   }
76   NaClLog(2,
77           "NaClLdtAllocatePageSelector(data, 1, 0x%08"NACL_PRIxPTR", "
78           "0x%"NACL_PRIxS"\n",
79           data_start, data_pages - 1);
80
81   return NaClLdtAllocatePageSelector(NACL_LDT_DESCRIPTOR_DATA,
82                                      0,
83                                      (void *) data_start,
84                                      data_pages);
85 }
86
87
88 /*
89  * Allocate ldt for app, without creating the main thread.
90  */
91 NaClErrorCode NaClAppPrepareToLaunch(struct NaClApp     *nap) {
92   uint16_t            cs;
93   uint16_t            des_seg;
94
95   NaClErrorCode       retval = LOAD_INTERNAL;
96
97   NaClXMutexLock(&nap->mu);
98
99   cs = NaClAllocateSegmentForCodeRegion(nap);
100
101   NaClLog(2, "got 0x%x\n", cs);
102   if (0 == cs) {
103     retval = SRT_NO_SEG_SEL;
104     goto done;
105   }
106
107   des_seg = NaClAllocateSegmentForDataRegion(nap);
108
109   NaClLog(2, "got 0x%x\n", des_seg);
110   if (0 == des_seg) {
111     NaClLdtDeleteSelector(cs);
112     retval = SRT_NO_SEG_SEL;
113     goto done;
114   }
115
116   nap->code_seg_sel = cs;
117   nap->data_seg_sel = des_seg;
118
119   /*
120    * Note that gs is thread-specific and not global, so that is allocated
121    * elsewhere.  See nacl_app_thread.c.
122    */
123
124   retval = LOAD_OK;
125 done:
126   NaClXMutexUnlock(&nap->mu);
127   return retval;
128 }