1 //===- CommandLine.cpp ----------------------------------------------------===// 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 #include <mcld/Support/CommandLine.h> 10 11 #include <llvm/ADT/StringRef.h> 12 #include <llvm/ADT/Twine.h> 13 #include <llvm/ADT/StringSwitch.h> 14 #include <llvm/Support/ErrorHandling.h> 15 16 using namespace llvm; 17 using namespace llvm::cl; 18 19 using namespace mcld; 20 21 static const size_t MaxOptWidth = 8; // arbitrary spacing for printOptionDiff 22 23 //===----------------------------------------------------------------------===// 24 // SearchDirParser 25 //===----------------------------------------------------------------------===// 26 // parse - Return true on error. 27 bool SearchDirParser::parse(Option &pOption, 28 StringRef pArgName, 29 StringRef pArg, 30 std::string &pValue) 31 { 32 char separator = *(pArgName.data() + 1); 33 if ('=' == separator) 34 pValue = '='; 35 pValue += pArg.str(); 36 return false; 37 } 38 39 void SearchDirParser::printOptionDiff(const Option &pOption, 40 StringRef pValue, 41 OptVal pDefault, 42 size_t pGlobalWidth) const 43 { 44 printOptionName(pOption, pGlobalWidth); 45 outs() << "= " << pValue; 46 size_t NumSpaces = MaxOptWidth > pValue.size()?MaxOptWidth - pValue.size():0; 47 outs().indent(NumSpaces) << " (default: "; 48 if (pDefault.hasValue()) 49 outs() << pDefault.getValue(); 50 else 51 outs() << "*no default*"; 52 outs() << ")\n"; 53 } 54 55 void SearchDirParser::anchor() 56 { 57 // do nothing 58 } 59 60 //===----------------------------------------------------------------------===// 61 // parser<mcld::sys::fs::Path> 62 //===----------------------------------------------------------------------===// 63 bool parser<mcld::sys::fs::Path>::parse(llvm::cl::Option &O, 64 llvm::StringRef ArgName, 65 llvm::StringRef Arg, 66 mcld::sys::fs::Path &Val) 67 { 68 Val.assign<llvm::StringRef::const_iterator>(Arg.begin(), Arg.end()); 69 return false; 70 } 71 72 void parser<mcld::sys::fs::Path>::printOptionDiff(const llvm::cl::Option &O, 73 const mcld::sys::fs::Path &V, 74 parser<mcld::sys::fs::Path>::OptVal Default, 75 size_t GlobalWidth) const 76 { 77 printOptionName(O, GlobalWidth); 78 outs() << "= " << V; 79 size_t VSize = V.native().size(); 80 size_t NumSpaces = MaxOptWidth > VSize ? MaxOptWidth - VSize : 0; 81 outs().indent(NumSpaces) << " (default: "; 82 if (Default.hasValue()) 83 outs() << Default.getValue().c_str(); 84 else 85 outs() << "*no default*"; 86 outs() << ")\n"; 87 } 88 89 void parser<mcld::sys::fs::Path>::anchor() 90 { 91 // do nothing 92 } 93 94 //===----------------------------------------------------------------------===// 95 // parser<mcld::ZOption> 96 //===----------------------------------------------------------------------===// 97 bool parser<mcld::ZOption>::parse(llvm::cl::Option &O, 98 llvm::StringRef ArgName, 99 llvm::StringRef Arg, 100 mcld::ZOption &Val) 101 { 102 if (0 == Arg.compare("combreloc")) 103 Val.setKind(ZOption::CombReloc); 104 else if (0 == Arg.compare("nocombreloc")) 105 Val.setKind(ZOption::NoCombReloc); 106 else if (0 == Arg.compare("defs")) 107 Val.setKind(ZOption::Defs); 108 else if (0 == Arg.compare("execstack")) 109 Val.setKind(ZOption::ExecStack); 110 else if (0 == Arg.compare("noexecstack")) 111 Val.setKind(ZOption::NoExecStack); 112 else if (0 == Arg.compare("initfirst")) 113 Val.setKind(ZOption::InitFirst); 114 else if (0 == Arg.compare("interpose")) 115 Val.setKind(ZOption::InterPose); 116 else if (0 == Arg.compare("loadfltr")) 117 Val.setKind(ZOption::LoadFltr); 118 else if (0 == Arg.compare("muldefs")) 119 Val.setKind(ZOption::MulDefs); 120 else if (0 == Arg.compare("nocopyreloc")) 121 Val.setKind(ZOption::NoCopyReloc); 122 else if (0 == Arg.compare("nodefaultlib")) 123 Val.setKind(ZOption::NoDefaultLib); 124 else if (0 == Arg.compare("nodelete")) 125 Val.setKind(ZOption::NoDelete); 126 else if (0 == Arg.compare("nodlopen")) 127 Val.setKind(ZOption::NoDLOpen); 128 else if (0 == Arg.compare("nodump")) 129 Val.setKind(ZOption::NoDump); 130 else if (0 == Arg.compare("relro")) 131 Val.setKind(ZOption::Relro); 132 else if (0 == Arg.compare("norelro")) 133 Val.setKind(ZOption::NoRelro); 134 else if (0 == Arg.compare("lazy")) 135 Val.setKind(ZOption::Lazy); 136 else if (0 == Arg.compare("now")) 137 Val.setKind(ZOption::Now); 138 else if (0 == Arg.compare("origin")) 139 Val.setKind(ZOption::Origin); 140 else if (Arg.startswith("common-page-size=")) { 141 Val.setKind(ZOption::CommPageSize); 142 long long unsigned size = 0; 143 Arg.drop_front(17).getAsInteger(0, size); 144 Val.setPageSize(static_cast<uint64_t>(size)); 145 } 146 else if (Arg.startswith("max-page-size=")) { 147 Val.setKind(ZOption::MaxPageSize); 148 long long unsigned size = 0; 149 Arg.drop_front(14).getAsInteger(0, size); 150 Val.setPageSize(static_cast<uint64_t>(size)); 151 } 152 153 if (ZOption::Unknown == Val.kind()) 154 llvm::report_fatal_error(llvm::Twine("unknown -z option: `") + 155 Arg + 156 llvm::Twine("'\n")); 157 return false; 158 } 159 160 void parser<mcld::ZOption>::printOptionDiff(const llvm::cl::Option &O, 161 const mcld::ZOption &V, 162 parser<mcld::ZOption>::OptVal Default, 163 size_t GlobalWidth) const 164 { 165 // TODO 166 } 167 168 void parser<mcld::ZOption>::anchor() 169 { 170 // do nothing 171 } 172 173