/* * NCValidateInit: Initialize NaCl validator internal state * Parameters: * vbase: base virtual address for code segment * vlimit: size in bytes of code segment * alignment: 16 or 32, specifying alignment * Returns: * an initialized struct NCValidatorState * if everything is okay, * else NULL */ struct NCValidatorState *NCValidateInit(const uint32_t vbase, const uint32_t vlimit, const uint8_t alignment) { struct NCValidatorState *vstate; dprint(("NCValidateInit(%08x, %08x, %08x)\n", vbase, vlimit, alignment)); InitBadPrefixMask(); do { if (vlimit <= vbase) break; if (alignment != 16 && alignment != 32) break; if ((vbase & (alignment - 1)) != 0) break; dprint(("ncv_init(%x, %x)\n", vbase, vlimit)); vstate = (struct NCValidatorState *)calloc(1, sizeof(*vstate)); if (vstate == NULL) break; vstate->num_diagnostics = kMaxDiagnostics; vstate->iadrbase = vbase; vstate->iadrlimit = vlimit; vstate->alignment = alignment; vstate->alignmask = alignment-1; vstate->vttable = (uint8_t *)calloc(IATOffset(vlimit - vbase) + 1, 1); vstate->kttable = (uint8_t *)calloc(IATOffset(vlimit - vbase) + 1, 1); vstate->do_stub_out = 0; if (vstate->vttable == NULL || vstate->kttable == NULL) break; dprint((" allocated tables\n")); Stats_Init(vstate); NCDecodeRegisterCallbacks(ValidateInst, Stats_NewSegment, Stats_SegFault, Stats_InternalError); return vstate; } while (0); /* failure */ return NULL; }
/** * Allocates the heap struct and initializes it */ void Heap_Init(Heap *heap, size_t minHeapSize, size_t maxHeapSize) { size_t memoryLimit = Heap_getMemoryLimit(); if (maxHeapSize < MIN_HEAP_SIZE) { fprintf(stderr, "SCALANATIVE_MAX_HEAP_SIZE too small to initialize heap.\n"); fprintf(stderr, "Minimum required: %zum \n", MIN_HEAP_SIZE / 1024 / 1024); fflush(stderr); exit(1); } if (minHeapSize > memoryLimit) { fprintf(stderr, "SCALANATIVE_MIN_HEAP_SIZE is too large.\n"); fprintf(stderr, "Maximum possible: %zug \n", memoryLimit / 1024 / 1024 / 1024); fflush(stderr); exit(1); } if (maxHeapSize < minHeapSize) { fprintf(stderr, "SCALANATIVE_MAX_HEAP_SIZE should be at least " "SCALANATIVE_MIN_HEAP_SIZE\n"); fflush(stderr); exit(1); } if (minHeapSize < MIN_HEAP_SIZE) { minHeapSize = MIN_HEAP_SIZE; } if (maxHeapSize == UNLIMITED_HEAP_SIZE) { maxHeapSize = memoryLimit; } uint32_t maxNumberOfBlocks = maxHeapSize / SPACE_USED_PER_BLOCK; uint32_t initialBlockCount = minHeapSize / SPACE_USED_PER_BLOCK; heap->maxHeapSize = maxHeapSize; heap->blockCount = initialBlockCount; heap->maxBlockCount = maxNumberOfBlocks; // reserve space for block headers size_t blockMetaSpaceSize = maxNumberOfBlocks * sizeof(BlockMeta); word_t *blockMetaStart = Heap_mapAndAlign(blockMetaSpaceSize, WORD_SIZE); heap->blockMetaStart = blockMetaStart; heap->blockMetaEnd = blockMetaStart + initialBlockCount * sizeof(BlockMeta) / WORD_SIZE; // reserve space for line headers size_t lineMetaSpaceSize = (size_t)maxNumberOfBlocks * LINE_COUNT * LINE_METADATA_SIZE; word_t *lineMetaStart = Heap_mapAndAlign(lineMetaSpaceSize, WORD_SIZE); heap->lineMetaStart = lineMetaStart; assert(LINE_COUNT * LINE_SIZE == BLOCK_TOTAL_SIZE); assert(LINE_COUNT * LINE_METADATA_SIZE % WORD_SIZE == 0); heap->lineMetaEnd = lineMetaStart + initialBlockCount * LINE_COUNT * LINE_METADATA_SIZE / WORD_SIZE; word_t *heapStart = Heap_mapAndAlign(maxHeapSize, BLOCK_TOTAL_SIZE); BlockAllocator_Init(&blockAllocator, blockMetaStart, initialBlockCount); // reserve space for bytemap Bytemap *bytemap = (Bytemap *)Heap_mapAndAlign( maxHeapSize / ALLOCATION_ALIGNMENT + sizeof(Bytemap), ALLOCATION_ALIGNMENT); heap->bytemap = bytemap; // Init heap for small objects heap->heapSize = minHeapSize; heap->heapStart = heapStart; heap->heapEnd = heapStart + minHeapSize / WORD_SIZE; Bytemap_Init(bytemap, heapStart, maxHeapSize); Allocator_Init(&allocator, &blockAllocator, bytemap, blockMetaStart, heapStart); LargeAllocator_Init(&largeAllocator, &blockAllocator, bytemap, blockMetaStart, heapStart); char *statsFile = Settings_StatsFileName(); if (statsFile != NULL) { heap->stats = malloc(sizeof(Stats)); Stats_Init(heap->stats, statsFile); } }