//===- StaticResolver.h ---------------------------------------------------===// // // The MCLinker Project // // This file is distributed under the University of Illinois Open Source // License. See LICENSE.TXT for details. // //===----------------------------------------------------------------------===// #ifndef MCLD_STATIC_SYMBOL_RESOLVER_H #define MCLD_STATIC_SYMBOL_RESOLVER_H #ifdef ENABLE_UNITTEST #include <gtest.h> #endif #include <string> #include <mcld/LD/Resolver.h> #include <mcld/LD/ResolveInfo.h> 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, w_U = ResolveInfo::weak_flag | ResolveInfo::regular_flag | ResolveInfo::undefine_flag, d_U = ResolveInfo::global_flag | ResolveInfo::dynamic_flag | ResolveInfo::undefine_flag, wd_U = ResolveInfo::weak_flag | ResolveInfo::dynamic_flag | ResolveInfo::undefine_flag, D = ResolveInfo::global_flag | ResolveInfo::regular_flag | ResolveInfo::define_flag, w_D = ResolveInfo::weak_flag | ResolveInfo::regular_flag | ResolveInfo::define_flag, d_D = ResolveInfo::global_flag | ResolveInfo::dynamic_flag | ResolveInfo::define_flag, wd_D = ResolveInfo::weak_flag | ResolveInfo::dynamic_flag | ResolveInfo::define_flag, C = ResolveInfo::global_flag | ResolveInfo::regular_flag | ResolveInfo::common_flag, w_C = ResolveInfo::weak_flag | ResolveInfo::regular_flag | ResolveInfo::common_flag, d_C = ResolveInfo::global_flag | ResolveInfo::dynamic_flag | ResolveInfo::common_flag, wd_C = ResolveInfo::weak_flag | ResolveInfo::dynamic_flag | ResolveInfo::common_flag, I = ResolveInfo::global_flag | ResolveInfo::regular_flag | ResolveInfo::indirect_flag, w_I = ResolveInfo::weak_flag | ResolveInfo::regular_flag | ResolveInfo::indirect_flag, d_I = ResolveInfo::global_flag | ResolveInfo::dynamic_flag | ResolveInfo::indirect_flag, wd_I = ResolveInfo::weak_flag | ResolveInfo::dynamic_flag | ResolveInfo::indirect_flag }; 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) 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 of mcld #endif