Loading...
--- dyld/dyld-1335/cache_builder/BuilderConfig.cpp
+++ /dev/null
@@ -1,252 +0,0 @@
-/* -*- mode: C++; c-basic-offset: 4; indent-tabs-mode: nil -*-
-*
-* Copyright (c) 2017 Apple Inc. All rights reserved.
-*
-* @APPLE_LICENSE_HEADER_START@
-*
-* This file contains Original Code and/or Modifications of Original Code
-* as defined in and that are subject to the Apple Public Source License
-* Version 2.0 (the 'License'). You may not use this file except in
-* compliance with the License. Please obtain a copy of the License at
-* http://www.opensource.apple.com/apsl/ and read it before using this
-* file.
-*
-* The Original Code and all software distributed under the License are
-* distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
-* EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
-* INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
-* FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
-* Please see the License for the specific language governing rights and
-* limitations under the License.
-*
-* @APPLE_LICENSE_HEADER_END@
-*/
-
-#include "BuilderConfig.h"
-#include "BuilderOptions.h"
-#include "CodeSigningTypes.h"
-#include "Architecture.h"
-#include "Platform.h"
-
-#include "dyld_cache_config.h"
-
-#include <assert.h>
-
-using namespace cache_builder;
-
-using mach_o::Architecture;
-using mach_o::Platform;
-
-//
-// MARK: --- cache_builder::Logger methods ---
-//
-
-cache_builder::Logger::Logger(const BuilderOptions& options)
- : logPrefix(options.logPrefix)
-{
- this->printTimers = options.timePasses;
- this->printStats = options.stats;
- this->printDebug = options.debug;
- this->printDebugIMPCaches = options.debugIMPCaches;
- this->printDebugCacheLayout = options.debugCacheLayout;
-}
-
-void cache_builder::Logger::log(const char* format, ...) const
-{
- char* output_string;
- va_list list;
- va_start(list, format);
- vasprintf(&output_string, format, list);
- va_end(list);
-
- fprintf(stderr, "[%s]: %s", this->logPrefix.c_str(), output_string);
-
- free(output_string);
-}
-
-//
-// MARK: --- cache_builder::Layout methods ---
-//
-
-static uint32_t defaultPageSize(Architecture arch)
-{
- if ( arch.sameCpu(Architecture::x86_64) )
- return 4096;
- else
- return 16384;
-}
-
-static bool hasAuthRegion(Architecture arch)
-{
- return arch == Architecture::arm64e;
-}
-
-static uint32_t supportsTPROMapping(Architecture arch)
-{
- return !arch.sameCpu(Architecture::x86_64);
-}
-
-cache_builder::Layout::Layout(const BuilderOptions& options)
-: is64(options.arch.is64())
- , hasAuthRegion(::hasAuthRegion(options.arch))
- , tproIsInData(!::supportsTPROMapping(options.arch))
- , pageSize(defaultPageSize(options.arch))
-{
- if ( options.arch.sameCpu(Architecture::x86_64) ) {
- // x86_64 uses discontiguous mappings
- this->discontiguous.emplace();
-
- this->discontiguous->regionAlignment = 1_GB;
- this->discontiguous->subCacheTextLimit = CacheVMSize(512_MB);
- } else {
- // Everyone else uses contiguous mappings
- this->contiguous.emplace();
- this->contiguous->regionPadding = CacheVMSize(32_MB);
- this->contiguous->subCacheTextDataLimit = CacheVMSize(2_GB);
- this->contiguous->subCacheStubsLimit = CacheVMSize(110_MB);
-
- // Note we have 2 padding regions in total in a given TEXT/DATA/AUTH/... region
- // 1 between TEXT/DATA_CONST and DATA, then another from DATA to LINKEDIT.
- this->contiguous->subCachePadding = this->contiguous->regionPadding + this->contiguous->regionPadding;
- }
-
- struct CacheLayout
- {
- uint64_t baseAddress;
- uint64_t cacheSize;
- };
- CacheLayout layout;
-
- if ( options.arch.sameCpu(Architecture::x86_64) ) {
- layout.baseAddress = X86_64_SHARED_REGION_START;
- layout.cacheSize = X86_64_SHARED_REGION_SIZE;
- } else if ( options.arch.sameCpu(Architecture::arm64) ) {
- layout.baseAddress = ARM64_SHARED_REGION_START;
-
- if ( options.isSimulator() ) {
- // Limit to 4GB to support back deployment to older hosts with 4GB shared regions
- layout.cacheSize = 4_GB;
- } else {
- layout.cacheSize = ARM64_SHARED_REGION_SIZE;
- }
-
- // Limit the max slide for arm64 based caches to 512MB. Combined with large
- // caches putting 1.5GB of TEXT in the first cache region, this will ensure that
- // this 1.5GB of TEXT will stay in the same 2GB region. <rdar://problem/49852839>
- cacheMaxSlide = 512_MB;
- } else if ( options.arch == Architecture::arm64_32 ) {
- layout.baseAddress = ARM64_32_SHARED_REGION_START;
- layout.cacheSize = 2_GB;
-
- // The cache contents can't exceed 2GB, but use the space above it for the slide
- if ( ARM64_32_SHARED_REGION_SIZE >= layout.cacheSize ) {
- this->cacheFixedSlide = ARM64_32_SHARED_REGION_SIZE - layout.cacheSize;
- }
- } else {
- assert("Unknown arch");
- }
-
- this->cacheBaseAddress = CacheVMAddress(layout.baseAddress);
- this->cacheSize = CacheVMSize(layout.cacheSize);
-}
-
-//
-// MARK: --- cache_builder::SlideInfo methods ---
-//
-
-SlideInfo::SlideInfo(const BuilderOptions& options, const Layout& layout)
-{
- // Compute slide info. Note the simulator doesn't slide
- if ( options.isSimulator() )
- return;
-
- if ( options.arch.sameCpu(Architecture::x86_64) || (options.arch == Architecture::arm64) ) {
- this->slideInfoFormat = SlideInfoFormat::v2;
-
- // 1 uint16_t per page
- this->slideInfoBytesPerDataPage = 2;
-
- // x86_64 and arm64 share the same mask, as Swift needs the high byte as if x86_64 had TBI
- this->slideInfoDeltaMask = 0x00FFFF0000000000ULL;
-
- // Only x86_64 needs a value add field on slide info V2
- if ( options.arch.sameCpu(Architecture::x86_64) ) {
- this->slideInfoValueAdd = layout.cacheBaseAddress;
- }
- else {
- this->slideInfoValueAdd = CacheVMAddress(0ULL);
- }
- }
- else if ( options.arch == Architecture::arm64e ) {
- // 1 uint16_t per page
- this->slideInfoBytesPerDataPage = 2;
-
- if ( layout.cacheSize > CacheVMSize(4_GB) ) {
- this->slideInfoFormat = SlideInfoFormat::v5;
-
- // 16k pages so that we can also use page-in linking for this format
- this->slideInfoPageSize = 0x4000;
- } else {
- this->slideInfoFormat = SlideInfoFormat::v3;
- }
- }
- else if ( options.arch == Architecture::arm64_32 ) {
- this->slideInfoFormat = SlideInfoFormat::v1;
-
- // 128 bytes per page. Enough for a bitmap with 1-bit entry per 32-bit location
- // Plus 2-bytes per page for the TOC offset
- this->slideInfoBytesPerDataPage = 130;
- }
- else {
- assert("Unknown arch");
- }
-}
-
-//
-// MARK: --- cache_builder::CodeSign methods ---
-//
-
-static cache_builder::CodeSign::Mode platformCodeSigningDigestMode(Platform platform)
-{
- if ( platform == Platform::watchOS )
- return cache_builder::CodeSign::Mode::agile;
- return cache_builder::CodeSign::Mode::onlySHA256;
-}
-
-static uint32_t codeSigningPageSize(Platform platform, Architecture arch)
-{
- if ( (arch == Architecture::arm64e) || (arch == Architecture::arm64_32) )
- return CS_PAGE_SIZE_16K;
-
- // arm64 on iOS is new enough for 16k pages, as is arm64 on macOS (ie the simulator)
- if ( arch == Architecture::arm64 ) {
- if ( platform.isSimulator() || (platform == Platform::iOS) )
- return CS_PAGE_SIZE_16K;
- return CS_PAGE_SIZE_4K;
- }
-
- if ( arch.sameCpu(Architecture::x86_64) )
- return CS_PAGE_SIZE_4K;
-
- // Unknown arch
- assert(0);
-}
-
-cache_builder::CodeSign::CodeSign(const BuilderOptions& options)
- : mode(platformCodeSigningDigestMode(options.platform))
- , pageSize(codeSigningPageSize(options.platform, options.arch))
-{
-}
-
-//
-// MARK: --- cache_builder::BuilderConfig methods ---
-//
-
-cache_builder::BuilderConfig::BuilderConfig(const BuilderOptions& options)
- : log(options)
- , timer()
- , layout(options)
- , slideInfo(options, layout)
- , codeSign(options)
-{
-}