forked from OSchip/llvm-project
parent
51e318737a
commit
b495562b5d
|
|
@ -18,21 +18,15 @@ namespace lld {
|
||||||
/// It exists to represent content at fixed addresses in memory.
|
/// It exists to represent content at fixed addresses in memory.
|
||||||
class AbsoluteAtom : public Atom {
|
class AbsoluteAtom : public Atom {
|
||||||
public:
|
public:
|
||||||
virtual Definition definition() const {
|
|
||||||
return Atom::definitionAbsolute;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// like dynamic_cast, if atom is definitionAbsolute
|
|
||||||
/// returns atom cast to AbsoluteAtom*, else returns nullptr
|
|
||||||
virtual const AbsoluteAtom* absoluteAtom() const {
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
virtual uint64_t value() const = 0;
|
virtual uint64_t value() const = 0;
|
||||||
|
|
||||||
|
static inline bool classof(const Atom *a) {
|
||||||
|
return a->definition() == definitionAbsolute;
|
||||||
|
}
|
||||||
|
static inline bool classof(const AbsoluteAtom *) { return true; }
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
AbsoluteAtom() {}
|
AbsoluteAtom() : Atom(definitionAbsolute) {}
|
||||||
virtual ~AbsoluteAtom() {}
|
virtual ~AbsoluteAtom() {}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -21,10 +21,6 @@ namespace llvm {
|
||||||
namespace lld {
|
namespace lld {
|
||||||
|
|
||||||
class File;
|
class File;
|
||||||
class DefinedAtom;
|
|
||||||
class UndefinedAtom;
|
|
||||||
class SharedLibraryAtom;
|
|
||||||
class AbsoluteAtom;
|
|
||||||
|
|
||||||
///
|
///
|
||||||
/// The linker has a Graph Theory model of linking. An object file is seen
|
/// The linker has a Graph Theory model of linking. An object file is seen
|
||||||
|
|
@ -52,33 +48,22 @@ public:
|
||||||
|
|
||||||
/// definition - Whether this atom is a definition or represents an undefined
|
/// definition - Whether this atom is a definition or represents an undefined
|
||||||
/// symbol.
|
/// symbol.
|
||||||
virtual Definition definition() const = 0;
|
Definition definition() const { return _definition; };
|
||||||
|
|
||||||
/// definedAtom - like dynamic_cast, if atom is definitionRegular
|
|
||||||
/// returns atom cast to DefinedAtom*, else returns nullptr;
|
|
||||||
virtual const DefinedAtom* definedAtom() const { return nullptr; }
|
|
||||||
|
|
||||||
/// undefinedAtom - like dynamic_cast, if atom is definitionUndefined
|
static inline bool classof(const Atom *a) { return true; }
|
||||||
/// returns atom cast to UndefinedAtom*, else returns nullptr;
|
|
||||||
virtual const UndefinedAtom* undefinedAtom() const { return nullptr; }
|
|
||||||
|
|
||||||
/// sharedLibraryAtom - like dynamic_cast, if atom is definitionSharedLibrary
|
|
||||||
/// returns atom cast to SharedLibraryAtom*, else returns nullptr;
|
|
||||||
virtual const SharedLibraryAtom* sharedLibraryAtom() const { return nullptr; }
|
|
||||||
|
|
||||||
/// absoluteAtom - like dynamic_cast, if atom is definitionAbsolute
|
|
||||||
/// returns atom cast to AbsoluteAtom*, else returns nullptr;
|
|
||||||
virtual const AbsoluteAtom* absoluteAtom() const { return nullptr; }
|
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
/// Atom is an abstract base class. Only subclasses can access constructor.
|
/// Atom is an abstract base class. Only subclasses can access constructor.
|
||||||
Atom() {}
|
Atom(Definition def) : _definition(def) {}
|
||||||
|
|
||||||
/// The memory for Atom objects is always managed by the owning File
|
/// The memory for Atom objects is always managed by the owning File
|
||||||
/// object. Therefore, no one but the owning File object should call
|
/// object. Therefore, no one but the owning File object should call
|
||||||
/// delete on an Atom. In fact, some File objects may bulk allocate
|
/// delete on an Atom. In fact, some File objects may bulk allocate
|
||||||
/// an array of Atoms, so they cannot be individually deleted by anyone.
|
/// an array of Atoms, so they cannot be individually deleted by anyone.
|
||||||
virtual ~Atom() {}
|
virtual ~Atom() {}
|
||||||
|
|
||||||
|
private:
|
||||||
|
Definition _definition;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace lld
|
} // namespace lld
|
||||||
|
|
|
||||||
|
|
@ -88,15 +88,6 @@ class File;
|
||||||
///
|
///
|
||||||
class DefinedAtom : public Atom {
|
class DefinedAtom : public Atom {
|
||||||
public:
|
public:
|
||||||
/// Whether this atom is defined or a proxy for an undefined symbol
|
|
||||||
virtual Definition definition() const {
|
|
||||||
return Atom::definitionRegular;
|
|
||||||
}
|
|
||||||
|
|
||||||
virtual const DefinedAtom* definedAtom() const {
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// The scope in which this atom is acessible to other atoms.
|
/// The scope in which this atom is acessible to other atoms.
|
||||||
enum Scope {
|
enum Scope {
|
||||||
scopeTranslationUnit, ///< Accessible only to atoms in the same translation
|
scopeTranslationUnit, ///< Accessible only to atoms in the same translation
|
||||||
|
|
@ -293,11 +284,15 @@ public:
|
||||||
/// Returns an iterator to the end of this Atom's References
|
/// Returns an iterator to the end of this Atom's References
|
||||||
virtual reference_iterator referencesEnd() const = 0;
|
virtual reference_iterator referencesEnd() const = 0;
|
||||||
|
|
||||||
|
static inline bool classof(const Atom *a) {
|
||||||
|
return a->definition() == definitionRegular;
|
||||||
|
}
|
||||||
|
static inline bool classof(const DefinedAtom *) { return true; }
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
/// DefinedAtom is an abstract base class.
|
/// DefinedAtom is an abstract base class.
|
||||||
/// Only subclasses can access constructor.
|
/// Only subclasses can access constructor.
|
||||||
DefinedAtom() { }
|
DefinedAtom() : Atom(definitionRegular) { }
|
||||||
|
|
||||||
/// The memory for DefinedAtom objects is always managed by the owning File
|
/// The memory for DefinedAtom objects is always managed by the owning File
|
||||||
/// object. Therefore, no one but the owning File object should call
|
/// object. Therefore, no one but the owning File object should call
|
||||||
|
|
|
||||||
|
|
@ -22,16 +22,6 @@ namespace lld {
|
||||||
/// It exists to represent a symbol which will be bound at runtime.
|
/// It exists to represent a symbol which will be bound at runtime.
|
||||||
class SharedLibraryAtom : public Atom {
|
class SharedLibraryAtom : public Atom {
|
||||||
public:
|
public:
|
||||||
virtual Definition definition() const {
|
|
||||||
return Atom::definitionSharedLibrary;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// like dynamic_cast, if atom is definitionSharedLibrary
|
|
||||||
/// returns atom cast to SharedLibraryAtom*, else returns nullptr
|
|
||||||
virtual const SharedLibraryAtom* sharedLibraryAtom() const {
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Returns shared library name used to load it at runtime.
|
/// Returns shared library name used to load it at runtime.
|
||||||
/// On linux that is the DT_NEEDED name.
|
/// On linux that is the DT_NEEDED name.
|
||||||
/// On Darwin it is the LC_DYLIB_LOAD dylib name.
|
/// On Darwin it is the LC_DYLIB_LOAD dylib name.
|
||||||
|
|
@ -40,9 +30,14 @@ public:
|
||||||
/// Returns if shared library symbol can be missing at runtime and if
|
/// Returns if shared library symbol can be missing at runtime and if
|
||||||
/// so the loader should silently resolve address of symbol to be nullptr.
|
/// so the loader should silently resolve address of symbol to be nullptr.
|
||||||
virtual bool canBeNullAtRuntime() const = 0;
|
virtual bool canBeNullAtRuntime() const = 0;
|
||||||
|
|
||||||
|
static inline bool classof(const Atom *a) {
|
||||||
|
return a->definition() == definitionSharedLibrary;
|
||||||
|
}
|
||||||
|
static inline bool classof(const SharedLibraryAtom *) { return true; }
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
SharedLibraryAtom() {}
|
SharedLibraryAtom() : Atom(definitionSharedLibrary) {}
|
||||||
virtual ~SharedLibraryAtom() {}
|
virtual ~SharedLibraryAtom() {}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -18,16 +18,6 @@ namespace lld {
|
||||||
/// It exists as a place holder for a future atom.
|
/// It exists as a place holder for a future atom.
|
||||||
class UndefinedAtom : public Atom {
|
class UndefinedAtom : public Atom {
|
||||||
public:
|
public:
|
||||||
virtual Definition definition() const {
|
|
||||||
return Atom::definitionUndefined;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// like dynamic_cast, if atom is definitionUndefined
|
|
||||||
/// returns atom cast to UndefinedAtom*, else returns nullptr
|
|
||||||
virtual const UndefinedAtom* undefinedAtom() const {
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Whether this undefined symbol needs to be resolved,
|
/// Whether this undefined symbol needs to be resolved,
|
||||||
/// or whether it can just evaluate to nullptr.
|
/// or whether it can just evaluate to nullptr.
|
||||||
/// This concept is often called "weak", but that term
|
/// This concept is often called "weak", but that term
|
||||||
|
|
@ -61,9 +51,13 @@ public:
|
||||||
|
|
||||||
virtual CanBeNull canBeNull() const = 0;
|
virtual CanBeNull canBeNull() const = 0;
|
||||||
|
|
||||||
|
static inline bool classof(const Atom *a) {
|
||||||
|
return a->definition() == definitionUndefined;
|
||||||
|
}
|
||||||
|
static inline bool classof(const UndefinedAtom *) { return true; }
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
UndefinedAtom() {}
|
UndefinedAtom() : Atom(definitionUndefined) {}
|
||||||
virtual ~UndefinedAtom() {}
|
virtual ~UndefinedAtom() {}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -15,6 +15,7 @@
|
||||||
#include "lld/Core/SymbolTable.h"
|
#include "lld/Core/SymbolTable.h"
|
||||||
#include "lld/Core/UndefinedAtom.h"
|
#include "lld/Core/UndefinedAtom.h"
|
||||||
|
|
||||||
|
#include "llvm/Support/Casting.h"
|
||||||
#include "llvm/Support/raw_ostream.h"
|
#include "llvm/Support/raw_ostream.h"
|
||||||
|
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
|
|
@ -33,7 +34,7 @@ public:
|
||||||
if ( _liveAtoms.count(atom) )
|
if ( _liveAtoms.count(atom) )
|
||||||
return false;
|
return false;
|
||||||
// don't remove if marked never-dead-strip
|
// don't remove if marked never-dead-strip
|
||||||
if ( const DefinedAtom* defAtom = atom->definedAtom() ) {
|
if (const DefinedAtom* defAtom = llvm::dyn_cast<DefinedAtom>(atom)) {
|
||||||
if ( defAtom->deadStrip() == DefinedAtom::deadStripNever )
|
if ( defAtom->deadStrip() == DefinedAtom::deadStripNever )
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
@ -194,7 +195,7 @@ void Resolver::resolveUndefines() {
|
||||||
std::vector<const Atom *> tents;
|
std::vector<const Atom *> tents;
|
||||||
for (std::vector<const Atom *>::iterator ait = _atoms.begin();
|
for (std::vector<const Atom *>::iterator ait = _atoms.begin();
|
||||||
ait != _atoms.end(); ++ait) {
|
ait != _atoms.end(); ++ait) {
|
||||||
if ( const DefinedAtom* defAtom = (*ait)->definedAtom() ) {
|
if (const DefinedAtom* defAtom = llvm::dyn_cast<DefinedAtom>(*ait)) {
|
||||||
if ( defAtom->merge() == DefinedAtom::mergeAsTentative )
|
if ( defAtom->merge() == DefinedAtom::mergeAsTentative )
|
||||||
tents.push_back(defAtom);
|
tents.push_back(defAtom);
|
||||||
}
|
}
|
||||||
|
|
@ -206,7 +207,8 @@ void Resolver::resolveUndefines() {
|
||||||
llvm::StringRef tentName = (*dit)->name();
|
llvm::StringRef tentName = (*dit)->name();
|
||||||
const Atom *curAtom = _symbolTable.findByName(tentName);
|
const Atom *curAtom = _symbolTable.findByName(tentName);
|
||||||
assert(curAtom != nullptr);
|
assert(curAtom != nullptr);
|
||||||
if ( const DefinedAtom* curDefAtom = curAtom->definedAtom() ) {
|
if (const DefinedAtom* curDefAtom =
|
||||||
|
llvm::dyn_cast<DefinedAtom>(curAtom)) {
|
||||||
if (curDefAtom->merge() == DefinedAtom::mergeAsTentative )
|
if (curDefAtom->merge() == DefinedAtom::mergeAsTentative )
|
||||||
_inputFiles.searchLibraries(tentName, searchDylibs,
|
_inputFiles.searchLibraries(tentName, searchDylibs,
|
||||||
true, true, *this);
|
true, true, *this);
|
||||||
|
|
@ -221,7 +223,7 @@ void Resolver::resolveUndefines() {
|
||||||
// to the new defined atom
|
// to the new defined atom
|
||||||
void Resolver::updateReferences() {
|
void Resolver::updateReferences() {
|
||||||
for (auto ait = _atoms.begin(); ait != _atoms.end(); ++ait) {
|
for (auto ait = _atoms.begin(); ait != _atoms.end(); ++ait) {
|
||||||
if ( const DefinedAtom* defAtom = (*ait)->definedAtom() ) {
|
if (const DefinedAtom* defAtom = llvm::dyn_cast<DefinedAtom>(*ait)) {
|
||||||
for (auto rit=defAtom->referencesBegin(), end=defAtom->referencesEnd();
|
for (auto rit=defAtom->referencesBegin(), end=defAtom->referencesEnd();
|
||||||
rit != end; ++rit) {
|
rit != end; ++rit) {
|
||||||
const Reference* ref = *rit;
|
const Reference* ref = *rit;
|
||||||
|
|
@ -259,7 +261,7 @@ void Resolver::markLive(const Atom &atom, WhyLiveBackChain *previous) {
|
||||||
WhyLiveBackChain thisChain;
|
WhyLiveBackChain thisChain;
|
||||||
thisChain.previous = previous;
|
thisChain.previous = previous;
|
||||||
thisChain.referer = &atom;
|
thisChain.referer = &atom;
|
||||||
if ( const DefinedAtom* defAtom = atom.definedAtom() ) {
|
if ( const DefinedAtom* defAtom = llvm::dyn_cast<DefinedAtom>(&atom)) {
|
||||||
for (auto rit=defAtom->referencesBegin(), end=defAtom->referencesEnd();
|
for (auto rit=defAtom->referencesBegin(), end=defAtom->referencesEnd();
|
||||||
rit != end; ++rit) {
|
rit != end; ++rit) {
|
||||||
const Reference* ref = *rit;
|
const Reference* ref = *rit;
|
||||||
|
|
@ -342,7 +344,7 @@ void Resolver::removeCoalescedAwayAtoms() {
|
||||||
void Resolver::checkDylibSymbolCollisions() {
|
void Resolver::checkDylibSymbolCollisions() {
|
||||||
for (std::vector<const Atom *>::const_iterator it = _atoms.begin();
|
for (std::vector<const Atom *>::const_iterator it = _atoms.begin();
|
||||||
it != _atoms.end(); ++it) {
|
it != _atoms.end(); ++it) {
|
||||||
const DefinedAtom* defAtom = (*it)->definedAtom();
|
const DefinedAtom* defAtom = llvm::dyn_cast<DefinedAtom>(*it);
|
||||||
if (defAtom == nullptr)
|
if (defAtom == nullptr)
|
||||||
continue;
|
continue;
|
||||||
if ( defAtom->merge() != DefinedAtom::mergeAsTentative )
|
if ( defAtom->merge() != DefinedAtom::mergeAsTentative )
|
||||||
|
|
@ -389,25 +391,23 @@ void Resolver::resolve() {
|
||||||
}
|
}
|
||||||
|
|
||||||
void Resolver::MergedFile::addAtom(const Atom& atom) {
|
void Resolver::MergedFile::addAtom(const Atom& atom) {
|
||||||
if ( const DefinedAtom* defAtom = atom.definedAtom() ) {
|
if (const DefinedAtom* defAtom = llvm::dyn_cast<DefinedAtom>(&atom)) {
|
||||||
_definedAtoms._atoms.push_back(defAtom);
|
_definedAtoms._atoms.push_back(defAtom);
|
||||||
}
|
} else if (const UndefinedAtom* undefAtom =
|
||||||
else if ( const UndefinedAtom* undefAtom = atom.undefinedAtom() ) {
|
llvm::dyn_cast<UndefinedAtom>(&atom)) {
|
||||||
_undefinedAtoms._atoms.push_back(undefAtom);
|
_undefinedAtoms._atoms.push_back(undefAtom);
|
||||||
}
|
} else if (const SharedLibraryAtom* slAtom =
|
||||||
else if ( const SharedLibraryAtom* slAtom = atom.sharedLibraryAtom() ) {
|
llvm::dyn_cast<SharedLibraryAtom>(&atom)) {
|
||||||
_sharedLibraryAtoms._atoms.push_back(slAtom);
|
_sharedLibraryAtoms._atoms.push_back(slAtom);
|
||||||
}
|
} else if (const AbsoluteAtom* abAtom = llvm::dyn_cast<AbsoluteAtom>(&atom)) {
|
||||||
else if ( const AbsoluteAtom* abAtom = atom.absoluteAtom() ) {
|
|
||||||
_absoluteAtoms._atoms.push_back(abAtom);
|
_absoluteAtoms._atoms.push_back(abAtom);
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
assert(0 && "atom has unknown definition kind");
|
assert(0 && "atom has unknown definition kind");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Resolver::MergedFile::addAtoms(std::vector<const Atom*>& all) {
|
void Resolver::MergedFile::addAtoms(std::vector<const Atom*>& all) {
|
||||||
for(std::vector<const Atom*>::iterator it=all.begin(); it != all.end(); ++it) {
|
for(std::vector<const Atom*>::iterator it=all.begin(); it != all.end(); ++it){
|
||||||
this->addAtom(**it);
|
this->addAtom(**it);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -20,6 +20,7 @@
|
||||||
|
|
||||||
#include "llvm/ADT/ArrayRef.h"
|
#include "llvm/ADT/ArrayRef.h"
|
||||||
#include "llvm/ADT/DenseMapInfo.h"
|
#include "llvm/ADT/DenseMapInfo.h"
|
||||||
|
#include "llvm/Support/Casting.h"
|
||||||
#include "llvm/Support/ErrorHandling.h"
|
#include "llvm/Support/ErrorHandling.h"
|
||||||
|
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
|
|
@ -160,8 +161,10 @@ void SymbolTable::addByName(const Atom & newAtom) {
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case NCR_DupUndef: {
|
case NCR_DupUndef: {
|
||||||
const UndefinedAtom* existingUndef = existing->undefinedAtom();
|
const UndefinedAtom* existingUndef =
|
||||||
const UndefinedAtom* newUndef = newAtom.undefinedAtom();
|
llvm::dyn_cast<UndefinedAtom>(existing);
|
||||||
|
const UndefinedAtom* newUndef =
|
||||||
|
llvm::dyn_cast<UndefinedAtom>(&newAtom);
|
||||||
assert(existingUndef != nullptr);
|
assert(existingUndef != nullptr);
|
||||||
assert(newUndef != nullptr);
|
assert(newUndef != nullptr);
|
||||||
if ( existingUndef->canBeNull() == newUndef->canBeNull() ) {
|
if ( existingUndef->canBeNull() == newUndef->canBeNull() ) {
|
||||||
|
|
@ -176,8 +179,10 @@ void SymbolTable::addByName(const Atom & newAtom) {
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case NCR_DupShLib: {
|
case NCR_DupShLib: {
|
||||||
const SharedLibraryAtom* existingShLib = existing->sharedLibraryAtom();
|
const SharedLibraryAtom* existingShLib =
|
||||||
const SharedLibraryAtom* newShLib = newAtom.sharedLibraryAtom();
|
llvm::dyn_cast<SharedLibraryAtom>(existing);
|
||||||
|
const SharedLibraryAtom* newShLib =
|
||||||
|
llvm::dyn_cast<SharedLibraryAtom>(&newAtom);
|
||||||
assert(existingShLib != nullptr);
|
assert(existingShLib != nullptr);
|
||||||
assert(newShLib != nullptr);
|
assert(newShLib != nullptr);
|
||||||
if ( (existingShLib->canBeNullAtRuntime()
|
if ( (existingShLib->canBeNullAtRuntime()
|
||||||
|
|
|
||||||
|
|
@ -38,6 +38,7 @@
|
||||||
#include "lld/Core/Reference.h"
|
#include "lld/Core/Reference.h"
|
||||||
|
|
||||||
#include "llvm/ADT/DenseMap.h"
|
#include "llvm/ADT/DenseMap.h"
|
||||||
|
#include "llvm/Support/Casting.h"
|
||||||
|
|
||||||
namespace lld {
|
namespace lld {
|
||||||
|
|
||||||
|
|
@ -57,7 +58,7 @@ void GOTPass::perform() {
|
||||||
if ( _platform.isGOTAccess(ref->kind(), canBypassGOT) ) {
|
if ( _platform.isGOTAccess(ref->kind(), canBypassGOT) ) {
|
||||||
const Atom* target = ref->target();
|
const Atom* target = ref->target();
|
||||||
assert(target != nullptr);
|
assert(target != nullptr);
|
||||||
const DefinedAtom* defTarget = target->definedAtom();
|
const DefinedAtom* defTarget = llvm::dyn_cast<DefinedAtom>(target);
|
||||||
bool replaceTargetWithGOTAtom = false;
|
bool replaceTargetWithGOTAtom = false;
|
||||||
if ( target->definition() == Atom::definitionSharedLibrary ) {
|
if ( target->definition() == Atom::definitionSharedLibrary ) {
|
||||||
// Accesses to shared library symbols must go through GOT.
|
// Accesses to shared library symbols must go through GOT.
|
||||||
|
|
|
||||||
|
|
@ -21,6 +21,7 @@
|
||||||
#include "lld/Core/Reference.h"
|
#include "lld/Core/Reference.h"
|
||||||
|
|
||||||
#include "llvm/ADT/DenseMap.h"
|
#include "llvm/ADT/DenseMap.h"
|
||||||
|
#include "llvm/Support/Casting.h"
|
||||||
|
|
||||||
namespace lld {
|
namespace lld {
|
||||||
|
|
||||||
|
|
@ -47,8 +48,8 @@ void StubsPass::perform() {
|
||||||
if ( target->definition() == Atom::definitionSharedLibrary ) {
|
if ( target->definition() == Atom::definitionSharedLibrary ) {
|
||||||
// Calls to shared libraries go through stubs.
|
// Calls to shared libraries go through stubs.
|
||||||
replaceCalleeWithStub = true;
|
replaceCalleeWithStub = true;
|
||||||
}
|
} else if (const DefinedAtom* defTarget =
|
||||||
else if ( const DefinedAtom* defTarget = target->definedAtom() ) {
|
llvm::dyn_cast<DefinedAtom>(target)) {
|
||||||
if ( defTarget->interposable() != DefinedAtom::interposeNo ) {
|
if ( defTarget->interposable() != DefinedAtom::interposeNo ) {
|
||||||
// Calls to interposable functions in same linkage unit
|
// Calls to interposable functions in same linkage unit
|
||||||
// must also go through a stub.
|
// must also go through a stub.
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue