+ cannotBeUsedWithBitcode(arg);
+ }
+ else if ( strcmp(arg, "-page_align_data_atoms") == 0 ) {
+ fPageAlignDataAtoms = true;
+ cannotBeUsedWithBitcode(arg);
+ }
+ else if (strcmp(arg, "-debug_snapshot") == 0) {
+ fLinkSnapshot.setSnapshotMode(Snapshot::SNAPSHOT_DEBUG);
+ fSnapshotRequested = true;
+ cannotBeUsedWithBitcode(arg);
+ }
+ else if (strcmp(arg, "-snapshot_dir") == 0) {
+ const char* path = argv[++i];
+ if ( path == NULL )
+ throw "-snapshot_dir missing path";
+ fLinkSnapshot.setSnapshotMode(Snapshot::SNAPSHOT_DEBUG);
+ fLinkSnapshot.setSnapshotPath(path);
+ fSnapshotRequested = true;
+ cannotBeUsedWithBitcode(arg);
+ }
+ else if ( strcmp(arg, "-new_main") == 0 ) {
+ fEntryPointLoadCommandForceOn = true;
+ cannotBeUsedWithBitcode(arg);
+ }
+ else if ( strcmp(arg, "-no_new_main") == 0 ) {
+ fEntryPointLoadCommandForceOff = true;
+ cannotBeUsedWithBitcode(arg);
+ }
+ else if ( strcmp(arg, "-source_version") == 0 ) {
+ const char* vers = argv[++i];
+ if ( vers == NULL )
+ throw "-source_version missing <version>";
+ fSourceVersion = parseVersionNumber64(vers);
+ }
+ else if ( strcmp(arg, "-add_source_version") == 0 ) {
+ fSourceVersionLoadCommandForceOn = true;
+ }
+ else if ( strcmp(arg, "-no_source_version") == 0 ) {
+ fSourceVersionLoadCommandForceOff = true;
+ cannotBeUsedWithBitcode(arg);
+ }
+ else if ( strcmp(arg, "-sdk_version") == 0 ) {
+ const char* vers = argv[++i];
+ if ( vers == NULL )
+ throw "-sdk_version missing <version>";
+ fSDKVersion = parseVersionNumber32(vers);
+ }
+ else if ( strcmp(arg, "-dependent_dr_info") == 0 ) {
+ warnObsolete(arg);
+ }
+ else if ( strcmp(arg, "-no_dependent_dr_info") == 0 ) {
+ warnObsolete(arg);
+ }
+ else if ( strcmp(arg, "-kexts_use_stubs") == 0 ) {
+ fKextsUseStubs = true;
+ cannotBeUsedWithBitcode(arg);
+ }
+ else if ( strcmp(argv[i], "-dependency_info") == 0 ) {
+ snapshotArgCount = 0;
+ ++i;
+ // previously handled by buildSearchPaths()
+ }
+ else if ( strcmp(arg, "-export_dynamic") == 0 ) {
+ fExportDynamic = true;
+ }
+ else if ( strcmp(arg, "-force_symbols_coalesce_list") == 0 ) {
+ snapshotFileArgIndex = 1;
+ loadExportFile(argv[++i], "-force_symbols_coalesce_list", fForceCoalesceSymbols);
+ }
+ else if ( strcmp(arg, "-add_linker_option") == 0 ) {
+ // ex: -add_linker_option '-framework Foundation'
+ const char* optString = argv[++i];
+ if ( optString == NULL )
+ throw "-add_linker_option missing <option>";
+ // break up into list of tokens at whitespace
+ std::vector<const char*> opts;
+ char* buffer = strdup(optString);
+ char* start = buffer;
+ for (char* s = buffer; ; ++s) {
+ if ( isspace(*s) ) {
+ *s = '\0';
+ opts.push_back(start);
+ start = s+1;
+ }
+ else if ( *s == '\0' ) {
+ opts.push_back(start);
+ break;
+ }
+ }
+ fLinkerOptions.push_back(opts);
+ cannotBeUsedWithBitcode(arg);
+ }
+ else if ( strcmp(arg, "-allow_simulator_linking_to_macosx_dylibs") == 0 ) {
+ fAllowSimulatorToLinkWithMacOSX = true;
+ cannotBeUsedWithBitcode(arg);
+ }
+ else if ( strcmp(arg, "-keep_dwarf_unwind") == 0 ) {
+ fKeepDwarfUnwindForcedOn = true;
+ fKeepDwarfUnwindForcedOff = false;
+ cannotBeUsedWithBitcode(arg);
+ }
+ else if ( strcmp(arg, "-no_keep_dwarf_unwind") == 0 ) {
+ fKeepDwarfUnwindForcedOn = false;
+ fKeepDwarfUnwindForcedOff = true;
+ cannotBeUsedWithBitcode(arg);
+ }
+ else if ( strcmp(arg, "-verbose_optimization_hints") == 0 ) {
+ fVerboseOptimizationHints = true;
+ }
+ else if ( strcmp(arg, "-ignore_optimization_hints") == 0 ) {
+ fIgnoreOptimizationHints = true;
+ cannotBeUsedWithBitcode(arg);
+ }
+ else if ( strcmp(arg, "-no_dtrace_dof") == 0 ) {
+ fGenerateDtraceDOF = false;
+ }
+ else if ( strcmp(arg, "-rename_section") == 0 ) {
+ if ( (argv[i+1]==NULL) || (argv[i+2]==NULL) || (argv[i+3]==NULL) || (argv[i+4]==NULL) )
+ throw "-rename_section missing <segment> <section> <segment> <section>";
+ addSectionRename(argv[i+1], argv[i+2], argv[i+3], argv[i+4]);
+ i += 4;
+ cannotBeUsedWithBitcode(arg);
+ }
+ else if ( strcmp(arg, "-rename_segment") == 0 ) {
+ if ( (argv[i+1]==NULL) || (argv[i+2]==NULL) )
+ throw "-rename_segment missing <existing-segment> <new-segment>";
+ addSegmentRename(argv[i+1], argv[i+2]);
+ i += 2;
+ cannotBeUsedWithBitcode(arg);
+ }
+ else if ( strcmp(arg, "-move_to_ro_segment") == 0 ) {
+ if ( (argv[i+1]==NULL) || (argv[i+2]==NULL) )
+ throw "-move_to_ro_segment missing <segment> <symbol-list-file>";
+ addSymbolMove(argv[i+1], argv[i+2], fSymbolsMovesCode, "-move_to_ro_segment");
+ i += 2;
+ cannotBeUsedWithBitcode(arg);
+ }
+ else if ( strcmp(arg, "-move_to_rw_segment") == 0 ) {
+ if ( (argv[i+1]==NULL) || (argv[i+2]==NULL) )
+ throw "-move_to_rw_segment missing <segment> <symbol-list-file>";
+ addSymbolMove(argv[i+1], argv[i+2], fSymbolsMovesData, "-move_to_rw_segment");
+ i += 2;
+ cannotBeUsedWithBitcode(arg);
+ }
+ else if ( strcmp(arg, "-trace_symbol_layout") == 0 ) {
+ fTraceSymbolLayout = true;
+ }
+ else if ( strcmp(arg, "-no_branch_islands") == 0 ) {
+ fAllowBranchIslands = false;
+ cannotBeUsedWithBitcode(arg);
+ }
+ else if ( strcmp(arg, "-segment_order") == 0 ) {
+ // ex: -segment_order __TEXT:__DATA:__JUNK
+ const char* optString = argv[++i];
+ if ( optString == NULL )
+ throw "-segment_order missing colon separated <segment-list>";
+ if ( !fSegmentOrder.empty() )
+ throw "-segment_order used more than once";
+ // break up into list of tokens at colon
+ char* buffer = strdup(optString);
+ char* start = buffer;
+ for (char* s = buffer; ; ++s) {
+ if ( *s == ':' ) {
+ *s = '\0';
+ fSegmentOrder.push_back(start);
+ start = s+1;
+ }
+ else if ( *s == '\0' ) {
+ fSegmentOrder.push_back(start);
+ break;
+ }
+ }
+ cannotBeUsedWithBitcode(arg);
+ }
+ else if ( strcmp(arg, "-section_order") == 0 ) {
+ // ex: -section_order __DATA __data:__const:__nl_pointers
+ if ( (argv[i+1]==NULL) || (argv[i+2]==NULL) )
+ throw "-section_order missing <segment> <section-list>";
+ const char* segName = argv[++i];
+ const char* optString = argv[++i];
+ if ( sectionOrder(segName) != NULL )
+ throwf("-section_order %s ... used more than once", segName);
+ SectionOrderList dummy;
+ fSectionOrder.push_back(dummy);
+ SectionOrderList& entry = fSectionOrder.back();
+ entry.segmentName = segName;
+ // break up into list of tokens at colon
+ char* buffer = strdup(optString);
+ char* start = buffer;
+ for (char* s = buffer; ; ++s) {
+ if ( *s == ':' ) {
+ *s = '\0';
+ entry.sectionOrder.push_back(start);
+ start = s+1;
+ }
+ else if ( *s == '\0' ) {
+ entry.sectionOrder.push_back(start);
+ break;
+ }
+ }
+ cannotBeUsedWithBitcode(arg);
+ }
+ else if ( strcmp(arg, "-application_extension") == 0 ) {
+ fMarkAppExtensionSafe = true;
+ fCheckAppExtensionSafe = true;
+ }
+ else if ( strcmp(arg, "-no_application_extension") == 0 ) {
+ fMarkAppExtensionSafe = false;
+ fCheckAppExtensionSafe = false;
+ }
+ else if ( strcmp(arg, "-add_ast_path") == 0 ) {
+ const char* path = argv[++i];
+ if ( path == NULL )
+ throw "-add_ast_path missing <option>";
+ fASTFilePaths.push_back(path);
+ }
+ else if ( strcmp(arg, "-force_load_swift_libs") == 0 ) {
+ fForceLoadSwiftLibs = true;
+ }
+ else if ( strcmp(arg, "-not_for_dyld_shared_cache") == 0 ) {
+ fSharedRegionEligibleForceOff = true;
+ cannotBeUsedWithBitcode(arg);
+ }
+ else if ( strcmp(arg, "-dirty_data_list") == 0 ) {
+ if ( argv[i+1] == NULL )
+ throw "-dirty_data_list missing <symbol-list-file>";
+ addSymbolMove("__DATA_DIRTY", argv[i+1], fSymbolsMovesData, "-dirty_data_list");
+ ++i;
+ cannotBeUsedWithBitcode(arg);
+ }
+ else if ( strcmp(arg, "-data_const") == 0 ) {
+ fUseDataConstSegmentForceOn = true;
+ cannotBeUsedWithBitcode(arg);
+ }
+ else if ( strcmp(arg, "-no_data_const") == 0 ) {
+ fUseDataConstSegmentForceOff = true;
+ cannotBeUsedWithBitcode(arg);
+ }
+ else if ( strcmp(arg, "-text_exec") == 0 ) {
+ fUseTextExecSegment = true;
+ cannotBeUsedWithBitcode(arg);
+ }
+ else if ( strcmp(arg, "-add_split_seg_info") == 0) {
+ fSharedRegionEligible = true;
+ cannotBeUsedWithBitcode(arg);
+ }
+ else if ( strcmp(arg, "-no_deduplicate") == 0 ) {
+ fDeDupe = false;
+ }
+ else if ( strcmp(arg, "-verbose_deduplicate") == 0 ) {
+ fVerboseDeDupe = true;
+ }
+ else if ( strcmp(arg, "-max_default_common_align") == 0 ) {
+ const char* alignStr = argv[++i];
+ if ( alignStr == NULL )
+ throw "-max_default_common_align missing <align-value>";
+ // argument is a hexadecimal number
+ char* endptr;
+ unsigned long value = strtoul(alignStr, &endptr, 16);
+ if ( *endptr != '\0')
+ throw "argument for -max_default_common_align is not a hexadecimal number";
+ if ( value > 0x8000 )
+ throw "argument for -max_default_common_align must be less than or equal to 0x8000";
+ if ( value == 0 ) {
+ warning("zero is not a valid -max_default_common_align");
+ value = 1;
+ }
+ // alignment is power of 2
+ uint8_t alignment = (uint8_t)__builtin_ctz(value);
+ if ( (unsigned long)(1 << alignment) != value ) {
+ warning("alignment for -max_default_common_align is not a power of two, using 0x%X", 1 << alignment);
+ }
+ fMaxDefaultCommonAlign = alignment;
+ }
+ else if ( strcmp(argv[i], "-no_weak_imports") == 0 ) {
+ fAllowWeakImports = false;
+ }
+ // put this last so that it does not interfer with other options starting with 'i'
+ else if ( strncmp(arg, "-i", 2) == 0 ) {
+ const char* colon = strchr(arg, ':');
+ if ( colon == NULL )
+ throwf("unknown option: %s", arg);
+ Options::AliasPair pair;
+ char* temp = new char[colon-arg];
+ strlcpy(temp, &arg[2], colon-arg-1);
+ pair.realName = &colon[1];
+ pair.alias = temp;
+ fAliases.push_back(pair);