| Index: src/trusted/service_runtime/sel_ldr_standard.c
|
| ===================================================================
|
| --- src/trusted/service_runtime/sel_ldr_standard.c (revision 3633)
|
| +++ src/trusted/service_runtime/sel_ldr_standard.c (working copy)
|
| @@ -44,32 +44,51 @@
|
|
|
| /*
|
| * Fill from static_text_end to end of that page with halt
|
| - * instruction, which is NACL_HALT_LEN in size. Does not touch
|
| - * dynamic text region, which should be pre-filled with HLTs.
|
| + * instruction, which is at least NACL_HALT_LEN in size when no
|
| + * dynamic text is present. Does not touch dynamic text region, which
|
| + * should be pre-filled with HLTs.
|
| + *
|
| + * By adding NACL_HALT_SLED_SIZE, we ensure that the code region ends
|
| + * with HLTs, just in case the CPU has a bug in which it fails to
|
| + * check for running off the end of the x86 code segment.
|
| */
|
| void NaClFillEndOfTextRegion(struct NaClApp *nap) {
|
| size_t page_pad;
|
|
|
| /*
|
| - * By adding NACL_HALT_SLED_SIZE, we ensure that the code region
|
| - * ends with HLTs, just in case the CPU has a bug in which it fails
|
| - * to check for running off the end of the x86 code segment.
|
| + * NOTE: make sure we are not silently overwriting data. It is the
|
| + * toolchain's responsibility to ensure that a NACL_HALT_SLED_SIZE
|
| + * gap exists.
|
| */
|
| - page_pad = (NaClRoundAllocPage(nap->static_text_end + NACL_HALT_SLED_SIZE)
|
| - - nap->static_text_end);
|
| -
|
| - /* NOTE: make sure we are not silently overwriting data */
|
| if (0 != nap->data_start &&
|
| nap->static_text_end + NACL_HALT_SLED_SIZE > nap->data_start) {
|
| - NaClLog(LOG_FATAL, "Missing gap between text and data for halt_sled");
|
| + NaClLog(LOG_FATAL, "Missing gap between text and data for halt_sled\n");
|
| }
|
| if (0 != nap->rodata_start &&
|
| nap->static_text_end + NACL_HALT_SLED_SIZE > nap->rodata_start) {
|
| - NaClLog(LOG_FATAL, "Missing gap between text and rodata for halt_sled");
|
| + NaClLog(LOG_FATAL, "Missing gap between text and rodata for halt_sled\n");
|
| }
|
|
|
| - CHECK(page_pad >= NACL_HALT_SLED_SIZE);
|
| - CHECK(page_pad < NACL_MAP_PAGESIZE + NACL_HALT_SLED_SIZE);
|
| + if (NULL == nap->text_shm) {
|
| + /*
|
| + * No dynamic text exists. Space for NACL_HALT_SLED_SIZE must
|
| + * exist.
|
| + */
|
| + page_pad = (NaClRoundAllocPage(nap->static_text_end + NACL_HALT_SLED_SIZE)
|
| + - nap->static_text_end);
|
| + CHECK(page_pad >= NACL_HALT_SLED_SIZE);
|
| + CHECK(page_pad < NACL_MAP_PAGESIZE + NACL_HALT_SLED_SIZE);
|
| + } else {
|
| + /*
|
| + * Dynamic text exists; the halt sled resides in the dynamic text
|
| + * region, so all we need to do here is to round out the last
|
| + * static text page with HLT instructions. It doesn't matter if
|
| + * the size of this region is smaller than NACL_HALT_SLED_SIZE --
|
| + * this is just to fully initialize the page, rather than (later)
|
| + * decoding/validating zero-filled memory as instructions.
|
| + */
|
| + page_pad = NaClRoundAllocPage(nap->static_text_end) - nap->static_text_end;
|
| + }
|
|
|
| NaClLog(4,
|
| "Filling with halts: %08"NACL_PRIxPTR", %08"NACL_PRIxS" bytes\n",
|
| @@ -138,13 +157,41 @@
|
| goto done;
|
| }
|
|
|
| + if (0 == nap->data_start) {
|
| + if (0 == nap->rodata_start) {
|
| + if (NaClRoundAllocPage(max_vaddr) - max_vaddr < NACL_HALT_SLED_SIZE) {
|
| + /*
|
| + * if no rodata and no data, we make sure that there is space for
|
| + * the halt sled.
|
| + */
|
| + max_vaddr += NACL_MAP_PAGESIZE;
|
| + }
|
| + } else {
|
| + /*
|
| + * no data, but there is rodata. this means max_vaddr is just
|
| + * where rodata ends. this might not be at an allocation
|
| + * boundary, and in this the page would not be writable. round
|
| + * max_vaddr up to the next allocation boundary so that bss will
|
| + * be at the next writable region.
|
| + */
|
| + ;
|
| + }
|
| + max_vaddr = NaClRoundAllocPage(max_vaddr);
|
| + }
|
| + /*
|
| + * max_vaddr -- the break or the boundary between data (initialized
|
| + * and bss) and the address space hole -- does not have to be at a
|
| + * page boundary.
|
| + */
|
| nap->break_addr = max_vaddr;
|
| nap->data_end = max_vaddr;
|
|
|
| - NaClLog(4, "rodata_end = %08"NACL_PRIxPTR"\n", rodata_end);
|
| - NaClLog(4, "data_start = %08"NACL_PRIxPTR"\n", nap->data_start);
|
| - NaClLog(4, "data_end = %08"NACL_PRIxPTR"\n", data_end);
|
| - NaClLog(4, "max_vaddr = %08"NACL_PRIxPTR"\n", max_vaddr);
|
| + NaClLog(4, "Values from NaClElfImageValidateProgramHeaders:\n");
|
| + NaClLog(4, "rodata_start = 0x%08"NACL_PRIxPTR"\n", nap->rodata_start);
|
| + NaClLog(4, "rodata_end = 0x%08"NACL_PRIxPTR"\n", rodata_end);
|
| + NaClLog(4, "data_start = 0x%08"NACL_PRIxPTR"\n", nap->data_start);
|
| + NaClLog(4, "data_end = 0x%08"NACL_PRIxPTR"\n", data_end);
|
| + NaClLog(4, "max_vaddr = 0x%08"NACL_PRIxPTR"\n", max_vaddr);
|
|
|
| #if 0 == NACL_DANGEROUS_DEBUG_MODE_DISABLE_INNER_SANDBOX
|
| nap->bundle_size = NaClElfImageGetBundleSize(image);
|
| @@ -159,15 +206,33 @@
|
| nap->entry_pt = NaClElfImageGetEntryPoint(image);
|
|
|
| NaClLog(2,
|
| - "static_text_end: 0x%016"NACL_PRIxPTR" "
|
| - "break_add: 0x%016"NACL_PRIxPTR" "
|
| - "data_end: 0x%016"NACL_PRIxPTR" "
|
| - "entry_pt: 0x%016"NACL_PRIxPTR" "
|
| - "bundle_size: 0x%x\n",
|
| - nap->static_text_end,
|
| - nap->break_addr,
|
| - nap->data_end,
|
| - nap->entry_pt,
|
| + "NaClApp addr space layout:\n");
|
| + NaClLog(2,
|
| + "nap->static_text_end = 0x%016"NACL_PRIxPTR"\n",
|
| + nap->static_text_end);
|
| + NaClLog(2,
|
| + "nap->dynamic_text_start = 0x%016"NACL_PRIxPTR"\n",
|
| + nap->dynamic_text_start);
|
| + NaClLog(2,
|
| + "nap->dynamic_text_end = 0x%016"NACL_PRIxPTR"\n",
|
| + nap->dynamic_text_end);
|
| + NaClLog(2,
|
| + "nap->rodata_start = 0x%016"NACL_PRIxPTR"\n",
|
| + nap->rodata_start);
|
| + NaClLog(2,
|
| + "nap->data_start = 0x%016"NACL_PRIxPTR"\n",
|
| + nap->data_start);
|
| + NaClLog(2,
|
| + "nap->data_end = 0x%016"NACL_PRIxPTR"\n",
|
| + nap->data_end);
|
| + NaClLog(2,
|
| + "nap->break_addr = 0x%016"NACL_PRIxPTR"\n",
|
| + nap->break_addr);
|
| + NaClLog(2,
|
| + "nap->entry_pt = 0x%016"NACL_PRIxPTR"\n",
|
| + nap->entry_pt);
|
| + NaClLog(2,
|
| + "nap->bundle_size = 0x%x\n",
|
| nap->bundle_size);
|
|
|
| if (!NaClAddrIsValidEntryPt(nap, nap->entry_pt)) {
|
| @@ -185,7 +250,7 @@
|
| goto done;
|
| }
|
| } else if (0 != nap->rodata_start) {
|
| - if (rodata_end != max_vaddr) {
|
| + if (NaClRoundAllocPage(rodata_end) != max_vaddr) {
|
| /*
|
| * This should be unreachable, but we include it just for
|
| * completeness.
|
| @@ -222,6 +287,19 @@
|
| }
|
| }
|
|
|
| + if (0 != nap->rodata_start &&
|
| + NaClRoundAllocPage(nap->rodata_start) != nap->rodata_start) {
|
| + NaClLog(LOG_INFO, "rodata_start not a multiple of allocation size\n");
|
| + ret = LOAD_BAD_RODATA_ALIGNMENT;
|
| + goto done;
|
| + }
|
| + if (0 != nap->data_start &&
|
| + NaClRoundAllocPage(nap->data_start) != nap->data_start) {
|
| + NaClLog(LOG_INFO, "data_start not a multiple of allocation size\n");
|
| + ret = LOAD_BAD_DATA_ALIGNMENT;
|
| + goto done;
|
| + }
|
| +
|
| NaClLog(2, "Allocating address space\n");
|
| subret = NaClAllocAddrSpace(nap);
|
| if (LOAD_OK != subret) {
|
| @@ -314,6 +392,35 @@
|
| ret = subret;
|
| goto done;
|
| }
|
| + NaClLog(2,
|
| + "NaClAppLoadFile done; addr space layout:\n");
|
| + NaClLog(2,
|
| + "nap->static_text_end = 0x%016"NACL_PRIxPTR"\n",
|
| + nap->static_text_end);
|
| + NaClLog(2,
|
| + "nap->dynamic_text_start = 0x%016"NACL_PRIxPTR"\n",
|
| + nap->dynamic_text_start);
|
| + NaClLog(2,
|
| + "nap->dynamic_text_end = 0x%016"NACL_PRIxPTR"\n",
|
| + nap->dynamic_text_end);
|
| + NaClLog(2,
|
| + "nap->rodata_start = 0x%016"NACL_PRIxPTR"\n",
|
| + nap->rodata_start);
|
| + NaClLog(2,
|
| + "nap->data_start = 0x%016"NACL_PRIxPTR"\n",
|
| + nap->data_start);
|
| + NaClLog(2,
|
| + "nap->data_end = 0x%016"NACL_PRIxPTR"\n",
|
| + nap->data_end);
|
| + NaClLog(2,
|
| + "nap->break_addr = 0x%016"NACL_PRIxPTR"\n",
|
| + nap->break_addr);
|
| + NaClLog(2,
|
| + "nap->entry_pt = 0x%016"NACL_PRIxPTR"\n",
|
| + nap->entry_pt);
|
| + NaClLog(2,
|
| + "nap->bundle_size = 0x%x\n",
|
| + nap->bundle_size);
|
|
|
| ret = LOAD_OK;
|
| done:
|
|
|