//===- StaticResolver.h ---------------------------------------------------===// // // The MCLinker Project // // This file is distributed under the University of Illinois Open Source // License. See LICENSE.TXT for details. // //===----------------------------------------------------------------------===// #ifndef MCLD_LD_STATICRESOLVER_H_ #define MCLD_LD_STATICRESOLVER_H_ #include "mcld/LD/ResolveInfo.h" #include "mcld/LD/Resolver.h" #include namespace mcld { class NamePool; /** \class StaticResolver */ class StaticResolver : public Resolver { public: /** \enum LinkAction * LinkAction follows BFD:linker.c (binary file descriptor). * List all actions to take in the state table */ enum LinkAction { FAIL, // abort. NOACT, // no action. UND, // override by symbol undefined symbol. WEAK, // override by symbol weak undefined. DEF, // override by symbol defined. DEFW, // override by symbol weak defined. DEFD, // override by symbol dynamic defined. DEFWD, // override by symbol dynamic weak defined. MDEFD, // mark symbol dynamic defined. MDEFWD, // mark symbol dynamic weak defined. DUND, // override dynamic defined symbol by undefined one. DUNDW, // oevrride dynamic defined symbol by weak undefined one. COM, // override by symbol common. CREF, // Possibly warn about common reference to defined symbol. CDEF, // redefine existing common symbol. BIG, // override by symbol common using largest size. MBIG, // mark common symbol by larger size. IND, // override by indirect symbol. CIND, // mark indirect symbol from existing common symbol. MDEF, // multiple definition error. MIND, // multiple indirect symbols. REFC // Mark indirect symbol referenced and then CYCLE. }; private: // These are the values generated by the bit codes. /** Encoding: * D -> define * U -> undefine * d -> dynamic * w -> weak * C -> common * I -> indirect */ enum { U = ResolveInfo::global_flag | ResolveInfo::regular_flag | ResolveInfo::undefine_flag, // NOLINT w_U = ResolveInfo::weak_flag | ResolveInfo::regular_flag | ResolveInfo::undefine_flag, // NOLINT d_U = ResolveInfo::global_flag | ResolveInfo::dynamic_flag | ResolveInfo::undefine_flag, // NOLINT wd_U = ResolveInfo::weak_flag | ResolveInfo::dynamic_flag | ResolveInfo::undefine_flag, // NOLINT D = ResolveInfo::global_flag | ResolveInfo::regular_flag | ResolveInfo::define_flag, // NOLINT w_D = ResolveInfo::weak_flag | ResolveInfo::regular_flag | ResolveInfo::define_flag, // NOLINT d_D = ResolveInfo::global_flag | ResolveInfo::dynamic_flag | ResolveInfo::define_flag, // NOLINT wd_D = ResolveInfo::weak_flag | ResolveInfo::dynamic_flag | ResolveInfo::define_flag, // NOLINT C = ResolveInfo::global_flag | ResolveInfo::regular_flag | ResolveInfo::common_flag, // NOLINT w_C = ResolveInfo::weak_flag | ResolveInfo::regular_flag | ResolveInfo::common_flag, // NOLINT d_C = ResolveInfo::global_flag | ResolveInfo::dynamic_flag | ResolveInfo::common_flag, // NOLINT wd_C = ResolveInfo::weak_flag | ResolveInfo::dynamic_flag | ResolveInfo::common_flag, // NOLINT I = ResolveInfo::global_flag | ResolveInfo::regular_flag | ResolveInfo::indirect_flag, // NOLINT w_I = ResolveInfo::weak_flag | ResolveInfo::regular_flag | ResolveInfo::indirect_flag, // NOLINT d_I = ResolveInfo::global_flag | ResolveInfo::dynamic_flag | ResolveInfo::indirect_flag, // NOLINT wd_I = ResolveInfo::weak_flag | ResolveInfo::dynamic_flag | ResolveInfo::indirect_flag // NOLINT }; enum ORDINATE { U_ORD, w_U_ORD, d_U_ORD, wd_U_ORD, D_ORD, w_D_ORD, d_D_ORD, wd_D_ORD, C_ORD, w_C_ORD, Cs_ORD, Is_ORD, LAST_ORD }; public: virtual ~StaticResolver(); /// shouldOverride - Can resolver override the symbol pOld by the symbol pNew? /// @return successfully resolved, return true; otherwise, return false. /// @param pOld the symbol which may be overridden. /// @param pNew the symbol which is used to replace pOld virtual bool resolve(ResolveInfo& __restrict__ pOld, const ResolveInfo& __restrict__ pNew, bool& pOverride, LDSymbol::ValueType pValue) const; private: inline unsigned int getOrdinate(const ResolveInfo& pInfo) const { if (pInfo.isAbsolute() && pInfo.isDyn()) return d_D_ORD; if (pInfo.isAbsolute()) return D_ORD; if (pInfo.isCommon() && pInfo.isDyn()) return Cs_ORD; if (pInfo.isCommon() && pInfo.isDefine()) return C_ORD; if (pInfo.isCommon() && pInfo.isWeak()) return w_C_ORD; if (pInfo.isIndirect()) return Is_ORD; return pInfo.info(); } }; } // namespace mcld #endif // MCLD_LD_STATICRESOLVER_H_