//===- 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