+ if (xar_opt_set(x, XAR_OPT_COMPRESSION, XAR_OPT_VAL_NONE) != 0)
+ throwf("could not reset compression type for exports list");
+ } else if ( _options.hasExportRestrictList() ) {
+ // handle unexported list here
+ std::vector<const char*> unexportedSymbols;
+ for ( auto § : _state.sections ) {
+ for ( auto &atom : sect->atoms ) {
+ // The unexported symbols should not include anything that is in TranslationUnit scope (static) or
+ // that cannot be in the SymbolTable
+ if ( atom->scope() != ld::Atom::scopeTranslationUnit &&
+ atom->symbolTableInclusion() == ld::Atom::symbolTableIn &&
+ !_options.shouldExport(atom->name()) )
+ unexportedSymbols.push_back(atom->name());
+ }
+ }
+ linkCmd.push_back("-unexported_symbols_list");
+ linkCmd.push_back("unexports.exp");
+ const char* unexportsPath = "unexports.exp";
+ std::string unexps;
+ for (std::vector<const char*>::iterator it = unexportedSymbols.begin();
+ it != unexportedSymbols.end(); ++ it) {
+ // try obfuscate the name for symbols in unexported symbols list. They are likely to be obfsucated.
+ const char* sym_name = NULL;
+ if ( _options.hideSymbols() )
+ sym_name = obfuscator->lookupHiddenName(*it);
+ if ( sym_name )
+ unexps += sym_name;
+ else
+ unexps += *it;
+ unexps += "\n";
+ }
+ unexps += "\n";
+ if (xar_opt_set(x, XAR_OPT_COMPRESSION, XAR_OPT_VAL_GZIP) != 0)
+ throwf("could not set compression type for exports list");
+ xar_file_t unexportsFile = xar_add_frombuffer(x, NULL, unexportsPath, const_cast<char*>(unexps.data()), unexps.size());
+ if (unexportsFile == NULL)
+ throwf("could not add unexports list to bitcode bundle");
+ if (xar_prop_set(unexportsFile, "file-type", "Exports") != 0)
+ throwf("could not set exports property in bitcode bundle");
+ if (xar_opt_set(x, XAR_OPT_COMPRESSION, XAR_OPT_VAL_NONE) != 0)
+ throwf("could not reset compression type for exports list");
+ }
+
+ // Handle order file. We need to obfuscate all the entries in the order file
+ if ( _options.orderedSymbolsCount() > 0 ) {
+ std::string orderFile;
+ for ( auto entry = _options.orderedSymbolsBegin(); entry != _options.orderedSymbolsEnd(); ++ entry ) {
+ std::stringstream line;
+ if ( entry->objectFileName != NULL ) {
+ unsigned index = 0;
+ for ( auto &f : _state.filesWithBitcode ) {
+ const char* atomFullPath = f->path();
+ const char* lastSlash = strrchr(atomFullPath, '/');
+ if ( (lastSlash != NULL && strcmp(&lastSlash[1], entry->objectFileName) == 0) ||
+ strcmp(atomFullPath, entry->objectFileName) == 0 )
+ break;
+ ++ index;
+ }
+ if ( index >= _state.filesWithBitcode.size() )
+ continue;
+ line << index << ".o:";
+ }
+ const char* sym_name = NULL;
+ if ( _options.hideSymbols() )
+ sym_name = obfuscator->lookupHiddenName(entry->symbolName);
+ if ( sym_name )
+ line << sym_name;
+ else
+ line << entry->symbolName;
+ line << "\n";
+ orderFile += line.str();
+ }
+ if (xar_opt_set(x, XAR_OPT_COMPRESSION, XAR_OPT_VAL_GZIP) != 0)
+ throwf("could not set compression type for order file");
+ xar_file_t ordersFile = xar_add_frombuffer(x, NULL, "file.order", const_cast<char*>(orderFile.data()), orderFile.size());
+ if (ordersFile == NULL)
+ throwf("could not add order file to bitcode bundle");
+ if (xar_prop_set(ordersFile, "file-type", "OrderFile") != 0)
+ throwf("could not set order file property in bitcode bundle");
+ if (xar_opt_set(x, XAR_OPT_COMPRESSION, XAR_OPT_VAL_NONE) != 0)
+ throwf("could not reset compression type for order file");
+ linkCmd.push_back("-order_file");
+ linkCmd.push_back("file.order");