1//===- StaticResolver.h ---------------------------------------------------===//
2//
3//                     The MCLinker Project
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9#ifndef MCLD_LD_STATICRESOLVER_H_
10#define MCLD_LD_STATICRESOLVER_H_
11#include "mcld/LD/ResolveInfo.h"
12#include "mcld/LD/Resolver.h"
13
14#include <string>
15
16namespace mcld {
17
18class NamePool;
19
20/** \class StaticResolver
21 */
22class StaticResolver : public Resolver {
23 public:
24  /** \enum LinkAction
25   *  LinkAction follows BFD:linker.c (binary file descriptor).
26   *  List all actions to take in the state table
27   */
28  enum LinkAction {
29    FAIL,    // abort.
30    NOACT,   // no action.
31    UND,     // override by symbol undefined symbol.
32    WEAK,    // override by symbol weak undefined.
33    DEF,     // override by symbol defined.
34    DEFW,    // override by symbol weak defined.
35    DEFD,    // override by symbol dynamic defined.
36    DEFWD,   // override by symbol dynamic weak defined.
37    MDEFD,   // mark symbol dynamic defined.
38    MDEFWD,  // mark symbol dynamic weak defined.
39    DUND,    // override dynamic defined symbol by undefined one.
40    DUNDW,   // oevrride dynamic defined symbol by weak undefined one.
41    COM,     // override by symbol common.
42    CREF,    // Possibly warn about common reference to defined symbol.
43    CDEF,    // redefine existing common symbol.
44    BIG,     // override by symbol common using largest size.
45    MBIG,    // mark common symbol by larger size.
46    IND,     // override by indirect symbol.
47    CIND,    // mark indirect symbol from existing common symbol.
48    MDEF,    // multiple definition error.
49    MIND,    // multiple indirect symbols.
50    REFC     // Mark indirect symbol referenced and then CYCLE.
51  };
52
53 private:
54  // These are the values generated by the bit codes.
55  /** Encoding:
56   *  D -> define
57   *  U -> undefine
58   *  d -> dynamic
59   *  w -> weak
60   *  C -> common
61   *  I -> indirect
62   */
63  enum {
64    U    = ResolveInfo::global_flag | ResolveInfo::regular_flag | ResolveInfo::undefine_flag,  // NOLINT
65    w_U  = ResolveInfo::weak_flag   | ResolveInfo::regular_flag | ResolveInfo::undefine_flag,  // NOLINT
66    d_U  = ResolveInfo::global_flag | ResolveInfo::dynamic_flag | ResolveInfo::undefine_flag,  // NOLINT
67    wd_U = ResolveInfo::weak_flag   | ResolveInfo::dynamic_flag | ResolveInfo::undefine_flag,  // NOLINT
68    D    = ResolveInfo::global_flag | ResolveInfo::regular_flag | ResolveInfo::define_flag,    // NOLINT
69    w_D  = ResolveInfo::weak_flag   | ResolveInfo::regular_flag | ResolveInfo::define_flag,    // NOLINT
70    d_D  = ResolveInfo::global_flag | ResolveInfo::dynamic_flag | ResolveInfo::define_flag,    // NOLINT
71    wd_D = ResolveInfo::weak_flag   | ResolveInfo::dynamic_flag | ResolveInfo::define_flag,    // NOLINT
72    C    = ResolveInfo::global_flag | ResolveInfo::regular_flag | ResolveInfo::common_flag,    // NOLINT
73    w_C  = ResolveInfo::weak_flag   | ResolveInfo::regular_flag | ResolveInfo::common_flag,    // NOLINT
74    d_C  = ResolveInfo::global_flag | ResolveInfo::dynamic_flag | ResolveInfo::common_flag,    // NOLINT
75    wd_C = ResolveInfo::weak_flag   | ResolveInfo::dynamic_flag | ResolveInfo::common_flag,    // NOLINT
76    I    = ResolveInfo::global_flag | ResolveInfo::regular_flag | ResolveInfo::indirect_flag,  // NOLINT
77    w_I  = ResolveInfo::weak_flag   | ResolveInfo::regular_flag | ResolveInfo::indirect_flag,  // NOLINT
78    d_I  = ResolveInfo::global_flag | ResolveInfo::dynamic_flag | ResolveInfo::indirect_flag,  // NOLINT
79    wd_I = ResolveInfo::weak_flag   | ResolveInfo::dynamic_flag | ResolveInfo::indirect_flag   // NOLINT
80  };
81
82  enum ORDINATE {
83    U_ORD,
84    w_U_ORD,
85    d_U_ORD,
86    wd_U_ORD,
87    D_ORD,
88    w_D_ORD,
89    d_D_ORD,
90    wd_D_ORD,
91    C_ORD,
92    w_C_ORD,
93    Cs_ORD,
94    Is_ORD,
95    LAST_ORD
96  };
97
98 public:
99  virtual ~StaticResolver();
100
101  /// shouldOverride - Can resolver override the symbol pOld by the symbol pNew?
102  /// @return successfully resolved, return true; otherwise, return false.
103  /// @param pOld the symbol which may be overridden.
104  /// @param pNew the symbol which is used to replace pOld
105  virtual bool resolve(ResolveInfo& __restrict__ pOld,
106                       const ResolveInfo& __restrict__ pNew,
107                       bool& pOverride,
108                       LDSymbol::ValueType pValue) const;
109
110 private:
111  inline unsigned int getOrdinate(const ResolveInfo& pInfo) const {
112    if (pInfo.isAbsolute() && pInfo.isDyn())
113      return d_D_ORD;
114    if (pInfo.isAbsolute())
115      return D_ORD;
116    if (pInfo.isCommon() && pInfo.isDyn())
117      return Cs_ORD;
118    if (pInfo.isCommon() && pInfo.isDefine())
119      return C_ORD;
120    if (pInfo.isCommon() && pInfo.isWeak())
121      return w_C_ORD;
122    if (pInfo.isIndirect())
123      return Is_ORD;
124    return pInfo.info();
125  }
126};
127
128}  // namespace mcld
129
130#endif  // MCLD_LD_STATICRESOLVER_H_
131