1 //===- GeneralOptions.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_GENERALOPTIONS_H_
10 #define MCLD_GENERALOPTIONS_H_
11 #include "mcld/Config/Config.h"
12 #include "mcld/Support/RealPath.h"
13 #include "mcld/Support/FileSystem.h"
14 #include <string>
15 #include <vector>
16 #include <set>
17 
18 namespace mcld {
19 
20 class Input;
21 class ZOption;
22 
23 /** \class GeneralOptions
24  *  \brief GeneralOptions collects the options that not be one of the
25  *     - input files
26  *     - attribute of input files
27  */
28 class GeneralOptions {
29  public:
30   enum class StripSymbolMode {
31     KeepAllSymbols,
32     StripTemporaries,
33     StripLocals,
34     StripAllSymbols
35   };
36 
37   enum class HashStyle : uint8_t {
38     Unknown = 0x0,
39     SystemV = 0x1,
40     GNU = 0x2,
41     Both = 0x3
42   };
43 
44   enum class ICF {
45     Unknown,
46     None,
47     All,
48     Safe
49   };
50 
51   typedef std::vector<std::string> RpathList;
52   typedef RpathList::iterator rpath_iterator;
53   typedef RpathList::const_iterator const_rpath_iterator;
54 
55   typedef std::vector<std::string> ScriptList;
56   typedef ScriptList::iterator script_iterator;
57   typedef ScriptList::const_iterator const_script_iterator;
58 
59   typedef std::vector<std::string> AuxiliaryList;
60   typedef AuxiliaryList::iterator aux_iterator;
61   typedef AuxiliaryList::const_iterator const_aux_iterator;
62 
63   typedef std::vector<std::string> UndefSymList;
64   typedef UndefSymList::iterator undef_sym_iterator;
65   typedef UndefSymList::const_iterator const_undef_sym_iterator;
66 
67   typedef std::set<std::string> ExcludeLIBS;
68 
69  public:
70   GeneralOptions();
71   ~GeneralOptions();
72 
73   /// trace
74   void setTrace(bool pEnableTrace = true) { m_bTrace = pEnableTrace; }
75 
trace()76   bool trace() const { return m_bTrace; }
77 
78   void setBsymbolic(bool pBsymbolic = true) { m_Bsymbolic = pBsymbolic; }
79 
Bsymbolic()80   bool Bsymbolic() const { return m_Bsymbolic; }
81 
82   void setPIE(bool pPIE = true) { m_bPIE = pPIE; }
83 
isPIE()84   bool isPIE() const { return m_bPIE; }
85 
86   void setBgroup(bool pBgroup = true) { m_Bgroup = pBgroup; }
87 
Bgroup()88   bool Bgroup() const { return m_Bgroup; }
89 
setDyld(const std::string & pDyld)90   void setDyld(const std::string& pDyld) { m_Dyld = pDyld; }
91 
dyld()92   const std::string& dyld() const { return m_Dyld; }
93 
hasDyld()94   bool hasDyld() const { return !m_Dyld.empty(); }
95 
96   void setSOName(const std::string& pName);
97 
soname()98   const std::string& soname() const { return m_SOName; }
99 
100   void setVerbose(int8_t pVerbose = -1) { m_Verbose = pVerbose; }
101 
verbose()102   int8_t verbose() const { return m_Verbose; }
103 
setMaxErrorNum(int16_t pNum)104   void setMaxErrorNum(int16_t pNum) { m_MaxErrorNum = pNum; }
105 
maxErrorNum()106   int16_t maxErrorNum() const { return m_MaxErrorNum; }
107 
setMaxWarnNum(int16_t pNum)108   void setMaxWarnNum(int16_t pNum) { m_MaxWarnNum = pNum; }
109 
maxWarnNum()110   int16_t maxWarnNum() const { return m_MaxWarnNum; }
111 
112   void setColor(bool pEnabled = true) { m_bColor = pEnabled; }
113 
color()114   bool color() const { return m_bColor; }
115 
116   void setNoUndefined(bool pEnable = true) {
117     m_NoUndefined = (pEnable ? YES : NO);
118   }
119 
setNumSpareDTags(uint32_t pNum)120   void setNumSpareDTags(uint32_t pNum) {
121     m_NumSpareDTags = pNum;
122   }
123 
getNumSpareDTags()124   unsigned getNumSpareDTags() const { return m_NumSpareDTags; }
125 
126   void setMulDefs(bool pEnable = true) { m_MulDefs = (pEnable ? YES : NO); }
127 
128   void setEhFrameHdr(bool pEnable = true) { m_bCreateEhFrameHdr = pEnable; }
129 
130   ///  -----  the -z options  -----  ///
131   void addZOption(const mcld::ZOption& pOption);
132 
hasCombReloc()133   bool hasCombReloc() const { return m_bCombReloc; }
134 
hasNoUndefined()135   bool hasNoUndefined() const { return (Unknown != m_NoUndefined); }
136 
isNoUndefined()137   bool isNoUndefined() const { return (YES == m_NoUndefined); }
138 
hasStackSet()139   bool hasStackSet() const { return (Unknown != m_ExecStack); }
140 
hasExecStack()141   bool hasExecStack() const { return (YES == m_ExecStack); }
142 
hasInitFirst()143   bool hasInitFirst() const { return m_bInitFirst; }
144 
hasInterPose()145   bool hasInterPose() const { return m_bInterPose; }
146 
hasLoadFltr()147   bool hasLoadFltr() const { return m_bLoadFltr; }
148 
hasMulDefs()149   bool hasMulDefs() const { return (Unknown != m_MulDefs); }
150 
isMulDefs()151   bool isMulDefs() const { return (YES == m_MulDefs); }
152 
hasNoCopyReloc()153   bool hasNoCopyReloc() const { return m_bNoCopyReloc; }
154 
hasNoDefaultLib()155   bool hasNoDefaultLib() const { return m_bNoDefaultLib; }
156 
hasNoDelete()157   bool hasNoDelete() const { return m_bNoDelete; }
158 
hasNoDLOpen()159   bool hasNoDLOpen() const { return m_bNoDLOpen; }
160 
hasNoDump()161   bool hasNoDump() const { return m_bNoDump; }
162 
hasRelro()163   bool hasRelro() const { return m_bRelro; }
164 
hasNow()165   bool hasNow() const { return m_bNow; }
166 
hasOrigin()167   bool hasOrigin() const { return m_bOrigin; }
168 
commPageSize()169   uint64_t commPageSize() const { return m_CommPageSize; }
170 
maxPageSize()171   uint64_t maxPageSize() const { return m_MaxPageSize; }
172 
hasEhFrameHdr()173   bool hasEhFrameHdr() const { return m_bCreateEhFrameHdr; }
174 
175   // -n, --nmagic
176   void setNMagic(bool pMagic = true) { m_bNMagic = pMagic; }
177 
nmagic()178   bool nmagic() const { return m_bNMagic; }
179 
180   // -N, --omagic
181   void setOMagic(bool pMagic = true) { m_bOMagic = pMagic; }
182 
omagic()183   bool omagic() const { return m_bOMagic; }
184 
185   // -S, --strip-debug
186   void setStripDebug(bool pStripDebug = true) { m_bStripDebug = pStripDebug; }
187 
stripDebug()188   bool stripDebug() const { return m_bStripDebug; }
189 
190   // -E, --export-dynamic
191   void setExportDynamic(bool pExportDynamic = true) {
192     m_bExportDynamic = pExportDynamic;
193   }
194 
exportDynamic()195   bool exportDynamic() const { return m_bExportDynamic; }
196 
197   // --warn-shared-textrel
198   void setWarnSharedTextrel(bool pWarnSharedTextrel = true) {
199     m_bWarnSharedTextrel = pWarnSharedTextrel;
200   }
201 
warnSharedTextrel()202   bool warnSharedTextrel() const { return m_bWarnSharedTextrel; }
203 
204   void setBinaryInput(bool pBinaryInput = true) {
205     m_bBinaryInput = pBinaryInput;
206   }
207 
isBinaryInput()208   bool isBinaryInput() const { return m_bBinaryInput; }
209 
210   void setDefineCommon(bool pEnable = true) { m_bDefineCommon = pEnable; }
211 
isDefineCommon()212   bool isDefineCommon() const { return m_bDefineCommon; }
213 
214   void setFatalWarnings(bool pEnable = true) { m_bFatalWarnings = pEnable; }
215 
isFatalWarnings()216   bool isFatalWarnings() const { return m_bFatalWarnings; }
217 
getStripSymbolMode()218   StripSymbolMode getStripSymbolMode() const { return m_StripSymbols; }
219 
setStripSymbols(StripSymbolMode pMode)220   void setStripSymbols(StripSymbolMode pMode) { m_StripSymbols = pMode; }
221 
222   void setNewDTags(bool pEnable = true) { m_bNewDTags = pEnable; }
223 
hasNewDTags()224   bool hasNewDTags() const { return m_bNewDTags; }
225 
226   void setNoStdlib(bool pEnable = true) { m_bNoStdlib = pEnable; }
227 
nostdlib()228   bool nostdlib() const { return m_bNoStdlib; }
229 
230   // -M, --print-map
231   void setPrintMap(bool pEnable = true) { m_bPrintMap = pEnable; }
232 
printMap()233   bool printMap() const { return m_bPrintMap; }
234 
235   void setWarnMismatch(bool pEnable = true) { m_bWarnMismatch = pEnable; }
236 
warnMismatch()237   bool warnMismatch() const { return m_bWarnMismatch; }
238 
239   // --gc-sections
240   void setGCSections(bool pEnable = true) { m_bGCSections = pEnable; }
241 
GCSections()242   bool GCSections() const { return m_bGCSections; }
243 
244   // --print-gc-sections
245   void setPrintGCSections(bool pEnable = true) { m_bPrintGCSections = pEnable; }
246 
getPrintGCSections()247   bool getPrintGCSections() const { return m_bPrintGCSections; }
248 
249   // --ld-generated-unwind-info
250   void setGenUnwindInfo(bool pEnable = true) { m_bGenUnwindInfo = pEnable; }
251 
genUnwindInfo()252   bool genUnwindInfo() const { return m_bGenUnwindInfo; }
253 
254   // -G, max GP size option
setGPSize(int gpsize)255   void setGPSize(int gpsize) { m_GPSize = gpsize; }
256 
getGPSize()257   int getGPSize() const { return m_GPSize; }
258 
getHashStyle()259   HashStyle getHashStyle() const { return m_HashStyle; }
260 
hasGNUHash()261   bool hasGNUHash() const {
262     return m_HashStyle == HashStyle::GNU || m_HashStyle == HashStyle::Both;
263   }
264 
hasSysVHash()265   bool hasSysVHash() const {
266     return m_HashStyle == HashStyle::SystemV || m_HashStyle == HashStyle::Both;
267   }
268 
setHashStyle(HashStyle pStyle)269   void setHashStyle(HashStyle pStyle) { m_HashStyle = pStyle; }
270 
getICFMode()271   ICF getICFMode() const { return m_ICF; }
272 
setICFMode(ICF pMode)273   void setICFMode(ICF pMode) { m_ICF = pMode; }
274 
getICFIterations()275   size_t getICFIterations() const { return m_ICFIterations; }
276 
setICFIterations(size_t pNum)277   void setICFIterations(size_t pNum) { m_ICFIterations = pNum; }
278 
printICFSections()279   bool printICFSections() const { return m_bPrintICFSections; }
280 
281   void setPrintICFSections(bool pPrintICFSections = true) {
282     m_bPrintICFSections = pPrintICFSections;
283   }
284 
285   // -----  link-in rpath  ----- //
getRpathList()286   const RpathList& getRpathList() const { return m_RpathList; }
getRpathList()287   RpathList& getRpathList() { return m_RpathList; }
288 
rpath_begin()289   const_rpath_iterator rpath_begin() const { return m_RpathList.begin(); }
rpath_begin()290   rpath_iterator rpath_begin() { return m_RpathList.begin(); }
rpath_end()291   const_rpath_iterator rpath_end() const { return m_RpathList.end(); }
rpath_end()292   rpath_iterator rpath_end() { return m_RpathList.end(); }
293 
294   // -----  link-in script  ----- //
getScriptList()295   const ScriptList& getScriptList() const { return m_ScriptList; }
getScriptList()296   ScriptList& getScriptList() { return m_ScriptList; }
297 
script_begin()298   const_script_iterator script_begin() const { return m_ScriptList.begin(); }
script_begin()299   script_iterator script_begin() { return m_ScriptList.begin(); }
script_end()300   const_script_iterator script_end() const { return m_ScriptList.end(); }
script_end()301   script_iterator script_end() { return m_ScriptList.end(); }
302 
303   // -----  -u/--undefined, undefined symbols ----- //
getUndefSymList()304   const UndefSymList& getUndefSymList() const { return m_UndefSymList; }
getUndefSymList()305   UndefSymList& getUndefSymList() { return m_UndefSymList; }
306 
undef_sym_begin()307   const_undef_sym_iterator undef_sym_begin() const {
308     return m_UndefSymList.begin();
309   }
undef_sym_begin()310   undef_sym_iterator undef_sym_begin() { return m_UndefSymList.begin(); }
311 
undef_sym_end()312   const_undef_sym_iterator undef_sym_end() const {
313     return m_UndefSymList.end();
314   }
undef_sym_end()315   undef_sym_iterator undef_sym_end() { return m_UndefSymList.end(); }
316 
317   // -----  filter and auxiliary filter  ----- //
setFilter(const std::string & pFilter)318   void setFilter(const std::string& pFilter) { m_Filter = pFilter; }
319 
filter()320   const std::string& filter() const { return m_Filter; }
321 
hasFilter()322   bool hasFilter() const { return !m_Filter.empty(); }
323 
getAuxiliaryList()324   const AuxiliaryList& getAuxiliaryList() const { return m_AuxiliaryList; }
getAuxiliaryList()325   AuxiliaryList& getAuxiliaryList() { return m_AuxiliaryList; }
326 
aux_begin()327   const_aux_iterator aux_begin() const { return m_AuxiliaryList.begin(); }
aux_begin()328   aux_iterator aux_begin() { return m_AuxiliaryList.begin(); }
aux_end()329   const_aux_iterator aux_end() const { return m_AuxiliaryList.end(); }
aux_end()330   aux_iterator aux_end() { return m_AuxiliaryList.end(); }
331 
332   // -----  exclude libs  ----- //
excludeLIBS()333   ExcludeLIBS& excludeLIBS() { return m_ExcludeLIBS; }
334 
335   bool isInExcludeLIBS(const Input& pInput) const;
336 
getVersionString()337   const char* getVersionString() const { return PACKAGE_NAME " " MCLD_VERSION; }
338 
339  private:
340   enum status { YES, NO, Unknown };
341 
342  private:
343   std::string m_DefaultLDScript;
344   std::string m_Dyld;
345   std::string m_SOName;
346   int8_t m_Verbose;          // --verbose[=0,1,2]
347   uint16_t m_MaxErrorNum;    // --error-limit=N
348   uint16_t m_MaxWarnNum;     // --warning-limit=N
349   unsigned m_NumSpareDTags;  // --spare-dynamic-tags
350   status m_ExecStack;        // execstack, noexecstack
351   status m_NoUndefined;      // defs, --no-undefined
352   status m_MulDefs;          // muldefs, --allow-multiple-definition
353   uint64_t m_CommPageSize;   // common-page-size=value
354   uint64_t m_MaxPageSize;    // max-page-size=value
355   bool m_bCombReloc : 1;     // combreloc, nocombreloc
356   bool m_bInitFirst : 1;     // initfirst
357   bool m_bInterPose : 1;     // interpose
358   bool m_bLoadFltr : 1;      // loadfltr
359   bool m_bNoCopyReloc : 1;   // nocopyreloc
360   bool m_bNoDefaultLib : 1;  // nodefaultlib
361   bool m_bNoDelete : 1;      // nodelete
362   bool m_bNoDLOpen : 1;      // nodlopen
363   bool m_bNoDump : 1;        // nodump
364   bool m_bRelro : 1;         // relro, norelro
365   bool m_bNow : 1;           // lazy, now
366   bool m_bOrigin : 1;        // origin
367   bool m_bTrace : 1;         // --trace
368   bool m_Bsymbolic : 1;      // --Bsymbolic
369   bool m_Bgroup : 1;
370   bool m_bPIE : 1;
371   bool m_bColor : 1;              // --color[=true,false,auto]
372   bool m_bCreateEhFrameHdr : 1;   // --eh-frame-hdr
373   bool m_bNMagic : 1;             // -n, --nmagic
374   bool m_bOMagic : 1;             // -N, --omagic
375   bool m_bStripDebug : 1;         // -S, --strip-debug
376   bool m_bExportDynamic : 1;      // -E, --export-dynamic
377   bool m_bWarnSharedTextrel : 1;  // --warn-shared-textrel
378   bool m_bBinaryInput : 1;        // -b [input-format], --format=[input-format]
379   bool m_bDefineCommon : 1;       // -d, -dc, -dp
380   bool m_bFatalWarnings : 1;      // --fatal-warnings
381   bool m_bNewDTags : 1;           // --enable-new-dtags
382   bool m_bNoStdlib : 1;           // -nostdlib
383   bool m_bPrintMap : 1;           // --print-map
384   bool m_bWarnMismatch : 1;       // --no-warn-mismatch
385   bool m_bGCSections : 1;         // --gc-sections
386   bool m_bPrintGCSections : 1;    // --print-gc-sections
387   bool m_bGenUnwindInfo : 1;      // --ld-generated-unwind-info
388   bool m_bPrintICFSections : 1;   // --print-icf-sections
389   ICF m_ICF;
390   size_t m_ICFIterations;
391   uint32_t m_GPSize;  // -G, --gpsize
392   StripSymbolMode m_StripSymbols;
393   RpathList m_RpathList;
394   ScriptList m_ScriptList;
395   UndefSymList m_UndefSymList;  // -u [symbol], --undefined [symbol]
396   HashStyle m_HashStyle;
397   std::string m_Filter;
398   AuxiliaryList m_AuxiliaryList;
399   ExcludeLIBS m_ExcludeLIBS;
400 };
401 
402 }  // namespace mcld
403 
404 #endif  // MCLD_GENERALOPTIONS_H_
405