Loading...
--- dyld/dyld-353.2.1/launch-cache/dsc_extractor.cpp
+++ dyld/dyld-421.1/launch-cache/dsc_extractor.cpp
@@ -83,16 +83,25 @@
public:
NotReExportSymbol(const std::set<int> &rd) :_reexportDeps(rd) {}
bool operator()(const mach_o::trie::Entry &entry) const {
+ bool result = isSymbolReExport(entry);
+ if (result) {
+ // <rdar://problem/17671438> Xcode 6 leaks in dyld_shared_cache_extract_dylibs
+ ::free((void*)entry.name);
+ const_cast<mach_o::trie::Entry*>(&entry)->name = NULL;
+ }
+ return result;
+ }
+private:
+ bool isSymbolReExport(const mach_o::trie::Entry &entry) const {
if ( (entry.flags & EXPORT_SYMBOL_FLAGS_KIND_MASK) != EXPORT_SYMBOL_FLAGS_KIND_REGULAR )
return true;
if ( (entry.flags & EXPORT_SYMBOL_FLAGS_REEXPORT) == 0 )
return true;
// If the symbol comes from a dylib that is re-exported, this is not an individual symbol re-export
- if ( _reexportDeps.count(entry.other) != 0 )
+ if ( _reexportDeps.count((int)entry.other) != 0 )
return true;
return false;
}
-private:
const std::set<int> &_reexportDeps;
};
@@ -109,8 +118,11 @@
// update load commands
uint64_t cumulativeFileSize = 0;
+ const unsigned origLoadCommandsSize = mh->sizeofcmds();
+ unsigned bytesRemaining = origLoadCommandsSize;
+ unsigned removedCount = 0;
const macho_load_command<P>* const cmds = (macho_load_command<P>*)((uint8_t*)mh + sizeof(macho_header<P>));
- const uint32_t cmd_count = mh->ncmds();
+ const uint32_t cmdCount = mh->ncmds();
const macho_load_command<P>* cmd = cmds;
macho_segment_command<P>* linkEditSegCmd = NULL;
macho_symtab_command<P>* symtab = NULL;
@@ -121,7 +133,8 @@
uint32_t exportsTrieSize = 0;
std::set<int> reexportDeps;
int depIndex = 0;
- for (uint32_t i = 0; i < cmd_count; ++i) {
+ for (uint32_t i = 0; i < cmdCount; ++i) {
+ bool remove = false;
switch ( cmd->cmd() ) {
case macho_segment_command<P>::CMD:
{
@@ -179,10 +192,28 @@
reexportDeps.insert(depIndex);
}
break;
- }
- cmd = (const macho_load_command<P>*)(((uint8_t*)cmd)+cmd->cmdsize());
- }
-
+ case LC_SEGMENT_SPLIT_INFO:
+ // <rdar://problem/23212513> dylibs iOS 9 dyld caches have bogus LC_SEGMENT_SPLIT_INFO
+ remove = true;
+ break;
+ }
+ uint32_t cmdSize = cmd->cmdsize();
+ macho_load_command<P>* nextCmd = (macho_load_command<P>*)(((uint8_t*)cmd)+cmdSize);
+ if ( remove ) {
+ ::memmove((void*)cmd, (void*)nextCmd, bytesRemaining);
+ ++removedCount;
+ }
+ else {
+ bytesRemaining -= cmdSize;
+ cmd = nextCmd;
+ }
+ }
+ // zero out stuff removed
+ ::bzero((void*)cmd, bytesRemaining);
+ // update header
+ mh->set_ncmds(cmdCount - removedCount);
+ mh->set_sizeofcmds(origLoadCommandsSize - bytesRemaining);
+
// rebuild symbol table
if ( linkEditSegCmd == NULL ) {
fprintf(stderr, "__LINKEDIT not found\n");
@@ -357,6 +388,12 @@
// return new size
*newSize = (symtab->stroff()+symtab->strsize()+4095) & (-4096);
+ // <rdar://problem/17671438> Xcode 6 leaks in dyld_shared_cache_extract_dylibs
+ for (std::vector<mach_o::trie::Entry>::iterator it = exports.begin(); it != exports.end(); ++it) {
+ ::free((void*)(it->name));
+ }
+
+
return 0;
}