#include "passes/compact_unwind.h"
#include "passes/order.h"
#include "passes/branch_island.h"
+#include "passes/thread_starts.h"
#include "passes/branch_shim.h"
#include "passes/objc.h"
#include "passes/dylibs.h"
#include "parsers/lto_file.h"
#include "parsers/opaque_section_file.h"
+const ld::VersionSet ld::File::_platforms;
struct PerformanceStatistics {
uint64_t startTool;
{
public:
FinalSection(const ld::Section& sect, uint32_t sectionsSeen, const Options&);
- static int sectionComparer(const void* l, const void* r);
static const ld::Section& outputSection(const ld::Section& sect, bool mergeZeroFill);
static const ld::Section& objectOutputSection(const ld::Section& sect, const Options&);
private:
return 12;
case ld::Section::typeStubHelper:
return 13;
+ case ld::Section::typeThreadStarts:
+ return INT_MAX-5;
case ld::Section::typeLSDA:
return INT_MAX-4;
case ld::Section::typeUnwindInfo:
return 32;
else if ( strcmp(sect.sectionName(), "__objc_data") == 0 )
return 33;
+ else if ( strcmp(sect.sectionName(), "__objc_const_ax") == 0 )
+ return 34;
else
return sectionsSeen+40;
}
if ( (sectType != ld::Section::typeZeroFill)
&& (sectType != ld::Section::typeUnclassified)
&& (sectType != ld::Section::typeTentativeDefs)
+ && (sectType != ld::Section::typeTLVDefs)
&& (sectType != ld::Section::typeDyldInfo) ) {
if ( !wildCardMatch )
warning("cannot move symbol '%s' from file %s to segment '%s' because symbol is not data (is %d)", atom.name(), path, dstSeg, sectType);
}
}
}
+ else if ( atom.symbolTableInclusion() == ld::Atom::symbolTableNotInFinalLinkedImages ) {
+ const char* symName = atom.name();
+ if ( strncmp(symName, "l_OBJC_$_INSTANCE_METHODS_", 26) == 0 ) {
+ if ( _options.moveAXMethodList(&symName[26]) ) {
+ curSectName = "__objc_const_ax";
+ fs = this->getFinalSection(curSegName, curSectName, sectType);
+ if ( _options.traceSymbolLayout() )
+ printf("symbol '%s', .axsymbol mapped it to %s/%s\n", atom.name(), curSegName, curSectName);
+ }
+ }
+ else if ( strncmp(symName, "l_OBJC_$_CLASS_METHODS_", 23) == 0 ) {
+ if ( _options.moveAXMethodList(&symName[23]) ) {
+ curSectName = "__objc_const_ax";
+ fs = this->getFinalSection(curSegName, curSectName, sectType);
+ if ( _options.traceSymbolLayout() )
+ printf("symbol '%s', .axsymbol mapped it to %s/%s\n", atom.name(), curSegName, curSectName);
+ }
+ }
+ }
+
// support for -rename_section and -rename_segment
for (const Options::SectionRename& rename : _options.sectionRenames()) {
if ( (strcmp(curSectName, rename.fromSection) == 0) && (strcmp(curSegName, rename.fromSegment) == 0) ) {
}
-int InternalState::FinalSection::sectionComparer(const void* l, const void* r)
-{
- const FinalSection* left = *(FinalSection**)l;
- const FinalSection* right = *(FinalSection**)r;
- if ( left->_segmentOrder != right->_segmentOrder )
- return (left->_segmentOrder - right->_segmentOrder);
- return (left->_sectionOrder - right->_sectionOrder);
-}
-
void InternalState::sortSections()
{
//fprintf(stderr, "UNSORTED final sections:\n");
//for (std::vector<ld::Internal::FinalSection*>::iterator it = sections.begin(); it != sections.end(); ++it) {
// fprintf(stderr, "final section %p %s/%s\n", (*it), (*it)->segmentName(), (*it)->sectionName());
//}
- qsort(§ions[0], sections.size(), sizeof(FinalSection*), &InternalState::FinalSection::sectionComparer);
+ std::stable_sort(sections.begin(), sections.end(), [](const ld::Internal::FinalSection* l, const ld::Internal::FinalSection* r) {
+ const FinalSection* left = (FinalSection*)l;
+ const FinalSection* right = (FinalSection*)r;
+ if ( left->_segmentOrder != right->_segmentOrder )
+ return (left->_segmentOrder < right->_segmentOrder);
+ return (left->_sectionOrder < right->_sectionOrder);
+ });
//fprintf(stderr, "SORTED final sections:\n");
//for (std::vector<ld::Internal::FinalSection*>::iterator it = sections.begin(); it != sections.end(); ++it) {
// fprintf(stderr, "final section %p %s/%s\n", (*it), (*it)->segmentName(), (*it)->sectionName());
ld::passes::dtrace::doPass(options, state);
ld::passes::compact_unwind::doPass(options, state); // must be after order pass
ld::passes::bitcode_bundle::doPass(options, state); // must be after dylib
+
+ // Sort again so that we get the segments in order.
+ state.sortSections();
+ ld::passes::thread_starts::doPass(options, state); // must be after dylib
// sort final sections
state.sortSections();