#include <stdint.h>
#include <math.h>
#include <unistd.h>
#include <dlfcn.h>
#include <mach/machine.h>
#include <vector>
#include "ld.hpp"
#include "dylibs.h"
namespace ld {
namespace passes {
namespace dylibs {
class WillBeUsed
{
public:
bool operator()(ld::dylib::File* dylib) const {
return dylib->willRemoved();
}
};
void doPass(const Options& opts, ld::Internal& state)
{
if ( opts.outputKind() == Options::kObjectFile )
return;
for (std::vector<ld::dylib::File*>::iterator it = state.dylibs.begin(); it != state.dylibs.end(); ++it) {
ld::dylib::File* aDylib = *it;
aDylib->setWillBeRemoved(false);
}
for (std::vector<ld::dylib::File*>::iterator it = state.dylibs.begin(); it != state.dylibs.end(); ++it) {
ld::dylib::File* aDylib = *it;
if ( aDylib->implicitlyLinked() && !aDylib->explicitlyLinked() && !aDylib->providedExportAtom() )
aDylib->setWillBeRemoved(true);
if ( aDylib->explicitlyLinked() && aDylib->deadStrippable() && !aDylib->providedExportAtom() )
aDylib->setWillBeRemoved(true);
if ( opts.deadStripDylibs() && !aDylib->providedExportAtom() )
aDylib->setWillBeRemoved(true);
}
state.dylibs.erase(std::remove_if(state.dylibs.begin(), state.dylibs.end(), WillBeUsed()), state.dylibs.end());
for (std::vector<ld::Internal::FinalSection*>::iterator sit=state.sections.begin(); sit != state.sections.end(); ++sit) {
ld::Internal::FinalSection* sect = *sit;
for (std::vector<const ld::Atom*>::iterator ait=sect->atoms.begin(); ait != sect->atoms.end(); ++ait) {
const ld::Atom* atom = *ait;
const ld::Atom* target = NULL;
bool targetIsWeakImport = false;
for (ld::Fixup::iterator fit = atom->fixupsBegin(), end=atom->fixupsEnd(); fit != end; ++fit) {
if ( fit->firstInCluster() )
target = NULL;
switch ( fit->binding ) {
case ld::Fixup::bindingsIndirectlyBound:
target = state.indirectBindingTable[fit->u.bindingIndex];
targetIsWeakImport = fit->weakImport;
break;
case ld::Fixup::bindingDirectlyBound:
target = fit->u.target;
targetIsWeakImport = fit->weakImport;
break;
default:
break;
}
if ( (target != NULL) && (target->definition() == ld::Atom::definitionProxy) ) {
ld::Atom::WeakImportState curWI = target->weakImportState();
if ( curWI == ld::Atom::weakImportUnset ) {
(const_cast<ld::Atom*>(target))->setWeakImportState(targetIsWeakImport);
}
else {
bool curIsWeakImport = (curWI == ld::Atom::weakImportTrue);
if ( curIsWeakImport != targetIsWeakImport ) {
switch ( opts.weakReferenceMismatchTreatment() ) {
case Options::kWeakReferenceMismatchError:
throwf("mismatching weak references for symbol: %s", target->name());
case Options::kWeakReferenceMismatchWeak:
(const_cast<ld::Atom*>(target))->setWeakImportState(true);
break;
case Options::kWeakReferenceMismatchNonWeak:
(const_cast<ld::Atom*>(target))->setWeakImportState(false);
break;
}
}
}
}
}
}
}
}
} } }