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.
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"
17 #include "native_client/src/trusted/desc/nacl_desc_io.h"
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"
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;
29 VCHECK((code_bytes & ((1 << NACL_PAGESHIFT) - 1)) == 0,
30 ("code_bytes (0x%08"NACL_PRIxS") is not page aligned\n",
35 "NaClAllocateSegmentForCodeRegion: fewer than one code pages?\n");
38 "NaClLdtAllocatePageSelector(code, 1, 0x%08"
39 NACL_PRIxPTR", 0x%"NACL_PRIxS"\n",
40 code_start, code_pages);
42 return NaClLdtAllocatePageSelector(NACL_LDT_DESCRIPTOR_CODE,
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
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.
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.
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));
69 CHECK(nap->addr_bits > NACL_PAGESHIFT);
73 "NaClAllocateSegmentForDataRegion: address space"
74 " is fewer than one page?\n");
77 "NaClLdtAllocatePageSelector(data, 1, 0x%08"NACL_PRIxPTR", "
79 data_start, data_pages - 1);
81 return NaClLdtAllocatePageSelector(NACL_LDT_DESCRIPTOR_DATA,
89 * Allocate ldt for app, without creating the main thread.
91 NaClErrorCode NaClAppPrepareToLaunch(struct NaClApp *nap) {
95 NaClErrorCode retval = LOAD_INTERNAL;
97 NaClXMutexLock(&nap->mu);
99 cs = NaClAllocateSegmentForCodeRegion(nap);
101 NaClLog(2, "got 0x%x\n", cs);
103 retval = SRT_NO_SEG_SEL;
107 des_seg = NaClAllocateSegmentForDataRegion(nap);
109 NaClLog(2, "got 0x%x\n", des_seg);
111 NaClLdtDeleteSelector(cs);
112 retval = SRT_NO_SEG_SEL;
116 nap->code_seg_sel = cs;
117 nap->data_seg_sel = des_seg;
120 * Note that gs is thread-specific and not global, so that is allocated
121 * elsewhere. See nacl_app_thread.c.
126 NaClXMutexUnlock(&nap->mu);