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 
16 namespace mcld {
17 
18 class NamePool;
19 
20 /** \class StaticResolver
21  */
22 class 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:
getOrdinate(const ResolveInfo & pInfo)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