1 //===- MCLinker.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 // 10 // This file implements the MCLinker class. 11 // 12 //===----------------------------------------------------------------------===// 13 #include <mcld/CodeGen/MCLinker.h> 14 15 #include <mcld/Module.h> 16 #include <mcld/LinkerConfig.h> 17 #include <mcld/InputTree.h> 18 #include <mcld/Linker.h> 19 #include <mcld/IRBuilder.h> 20 #include <mcld/MC/InputBuilder.h> 21 #include <mcld/MC/FileAction.h> 22 #include <mcld/MC/CommandAction.h> 23 #include <mcld/Object/ObjectLinker.h> 24 #include <mcld/Support/CommandLine.h> 25 #include <mcld/Support/FileSystem.h> 26 #include <mcld/Support/MsgHandling.h> 27 #include <mcld/Support/FileHandle.h> 28 #include <mcld/Support/raw_ostream.h> 29 #include <mcld/Support/MemoryArea.h> 30 31 #include <llvm/IR/Module.h> 32 #include <llvm/Support/CommandLine.h> 33 34 #include <algorithm> 35 #include <vector> 36 #include <string> 37 38 using namespace mcld; 39 using namespace llvm; 40 41 char MCLinker::m_ID = 0; 42 43 //===----------------------------------------------------------------------===// 44 // Help Functions 45 //===----------------------------------------------------------------------===// 46 static inline bool CompareAction(const InputAction* X, const InputAction* Y) 47 { 48 return (X->position() < Y->position()); 49 } 50 51 //===----------------------------------------------------------------------===// 52 // Positional Options 53 // There are four kinds of positional options: 54 // 1. Inputs, object files, such as /tmp/XXXX.o 55 // 2. Namespecs, short names of libraries. A namespec may refer to an archive 56 // or a shared library. For example, -lm. 57 // 3. Attributes of inputs. Attributes describe inputs appears after them. 58 // For example, --as-needed and --whole-archive. 59 // 4. Groups. A Group is a set of archives. Linkers repeatedly read archives 60 // in groups until there is no new undefined symbols. 61 // 5. Bitcode. Bitcode is a kind of object files. MCLinker compiles it to 62 // object file first, then link it as a object file. (Bitcode is recorded 63 // in BitcodeOption, not be read by LLVM Command Line library.) 64 //===----------------------------------------------------------------------===// 65 // Inputs 66 //===----------------------------------------------------------------------===// 67 static cl::list<mcld::sys::fs::Path> 68 ArgInputObjectFiles(cl::Positional, 69 cl::desc("[input object files]"), 70 cl::ZeroOrMore); 71 72 //===----------------------------------------------------------------------===// 73 // Namespecs 74 //===----------------------------------------------------------------------===// 75 static cl::list<std::string> 76 ArgNameSpecList("l", 77 cl::ZeroOrMore, 78 cl::desc("Add the archive or object file specified by namespec to " 79 "the list of files to link."), 80 cl::value_desc("namespec"), 81 cl::Prefix); 82 83 static cl::alias 84 ArgNameSpecListAlias("library", 85 cl::desc("alias for -l"), 86 cl::aliasopt(ArgNameSpecList)); 87 88 //===----------------------------------------------------------------------===// 89 // Attributes 90 //===----------------------------------------------------------------------===// 91 static cl::list<bool> 92 ArgWholeArchiveList("whole-archive", 93 cl::ValueDisallowed, 94 cl::desc("For each archive mentioned on the command line after " 95 "the --whole-archive option, include all object files " 96 "in the archive.")); 97 98 static cl::list<bool> 99 ArgNoWholeArchiveList("no-whole-archive", 100 cl::ValueDisallowed, 101 cl::desc("Turn off the effect of the --whole-archive option for " 102 "subsequent archive files.")); 103 104 static cl::list<bool> 105 ArgAsNeededList("as-needed", 106 cl::ValueDisallowed, 107 cl::desc("This option affects ELF DT_NEEDED tags for dynamic " 108 "libraries mentioned on the command line after the " 109 "--as-needed option.")); 110 111 static cl::list<bool> 112 ArgNoAsNeededList("no-as-needed", 113 cl::ValueDisallowed, 114 cl::desc("Turn off the effect of the --as-needed option for " 115 "subsequent dynamic libraries")); 116 117 static cl::list<bool> 118 ArgAddNeededList("add-needed", 119 cl::ValueDisallowed, 120 cl::desc("--add-needed causes DT_NEEDED tags are always " 121 "emitted for those libraries from DT_NEEDED tags. " 122 "This is the default behavior.")); 123 124 static cl::list<bool> 125 ArgNoAddNeededList("no-add-needed", 126 cl::ValueDisallowed, 127 cl::desc("--no-add-needed causes DT_NEEDED tags will never be " 128 "emitted for those libraries from DT_NEEDED tags")); 129 130 static cl::list<bool> 131 ArgBDynamicList("Bdynamic", 132 cl::ValueDisallowed, 133 cl::desc("Link against dynamic library")); 134 135 static cl::alias 136 ArgBDynamicListAlias1("dy", 137 cl::desc("alias for --Bdynamic"), 138 cl::aliasopt(ArgBDynamicList)); 139 140 static cl::alias 141 ArgBDynamicListAlias2("call_shared", 142 cl::desc("alias for --Bdynamic"), 143 cl::aliasopt(ArgBDynamicList)); 144 145 static cl::list<bool> 146 ArgBStaticList("Bstatic", 147 cl::ValueDisallowed, 148 cl::desc("Link against static library")); 149 150 static cl::alias 151 ArgBStaticListAlias1("dn", 152 cl::desc("alias for --Bstatic"), 153 cl::aliasopt(ArgBStaticList)); 154 155 static cl::alias 156 ArgBStaticListAlias2("static", 157 cl::desc("alias for --Bstatic"), 158 cl::aliasopt(ArgBStaticList)); 159 160 static cl::alias 161 ArgBStaticListAlias3("non_shared", 162 cl::desc("alias for --Bstatic"), 163 cl::aliasopt(ArgBStaticList)); 164 165 //===----------------------------------------------------------------------===// 166 // Groups 167 //===----------------------------------------------------------------------===// 168 static cl::list<bool> 169 ArgStartGroupList("start-group", 170 cl::ValueDisallowed, 171 cl::desc("start to record a group of archives")); 172 173 static cl::alias 174 ArgStartGroupListAlias("(", 175 cl::desc("alias for --start-group"), 176 cl::aliasopt(ArgStartGroupList)); 177 178 static cl::list<bool> 179 ArgEndGroupList("end-group", 180 cl::ValueDisallowed, 181 cl::desc("stop recording a group of archives")); 182 183 static cl::alias 184 ArgEndGroupListAlias(")", 185 cl::desc("alias for --end-group"), 186 cl::aliasopt(ArgEndGroupList)); 187 188 //===----------------------------------------------------------------------===// 189 // MCLinker 190 //===----------------------------------------------------------------------===// 191 MCLinker::MCLinker(LinkerConfig& pConfig, 192 mcld::Module& pModule, 193 MemoryArea& pOutput) 194 : MachineFunctionPass(m_ID), 195 m_Config(pConfig), 196 m_Module(pModule), 197 m_Output(pOutput), 198 m_pBuilder(NULL), 199 m_pLinker(NULL) { 200 } 201 202 MCLinker::~MCLinker() 203 { 204 delete m_pLinker; 205 delete m_pBuilder; 206 } 207 208 bool MCLinker::doInitialization(llvm::Module &pM) 209 { 210 // Now, all input arguments are prepared well, send it into ObjectLinker 211 m_pLinker = new Linker(); 212 213 if (!m_pLinker->emulate(m_Module.getScript(), m_Config)) 214 return false; 215 216 m_pBuilder = new IRBuilder(m_Module, m_Config); 217 218 initializeInputTree(*m_pBuilder); 219 220 return true; 221 } 222 223 bool MCLinker::doFinalization(llvm::Module &pM) 224 { 225 if (!m_pLinker->link(m_Module, *m_pBuilder)) 226 return true; 227 228 if (!m_pLinker->emit(m_Output)) 229 return true; 230 231 return false; 232 } 233 234 bool MCLinker::runOnMachineFunction(MachineFunction& pF) 235 { 236 // basically, linkers do nothing during function is generated. 237 return false; 238 } 239 240 void MCLinker::initializeInputTree(IRBuilder& pBuilder) 241 { 242 if (0 == ArgInputObjectFiles.size() && 243 0 == ArgNameSpecList.size() && 244 !m_Config.bitcode().hasDefined()) { 245 fatal(diag::err_no_inputs); 246 return; 247 } 248 249 size_t num_actions = ArgInputObjectFiles.size() + 250 ArgNameSpecList.size() + 251 ArgWholeArchiveList.size() + 252 ArgNoWholeArchiveList.size() + 253 ArgAsNeededList.size() + 254 ArgNoAsNeededList.size() + 255 ArgAddNeededList.size() + 256 ArgNoAddNeededList.size() + 257 ArgBDynamicList.size() + 258 ArgBStaticList.size() + 259 ArgStartGroupList.size() + 260 ArgEndGroupList.size() + 261 1; // bitcode 262 std::vector<InputAction*> actions; 263 actions.reserve(num_actions); 264 265 // ----- inputs ----- // 266 cl::list<mcld::sys::fs::Path>::iterator input, inBegin, inEnd; 267 inBegin = ArgInputObjectFiles.begin(); 268 inEnd = ArgInputObjectFiles.end(); 269 for (input = inBegin; input != inEnd; ++input) { 270 unsigned int pos = ArgInputObjectFiles.getPosition(input - inBegin); 271 actions.push_back(new InputFileAction(pos, *input)); 272 actions.push_back(new ContextAction(pos)); 273 actions.push_back(new MemoryAreaAction(pos, FileHandle::ReadOnly)); 274 } 275 276 // ----- namespecs ----- // 277 cl::list<std::string>::iterator namespec, nsBegin, nsEnd; 278 nsBegin = ArgNameSpecList.begin(); 279 nsEnd = ArgNameSpecList.end(); 280 mcld::Module& module = pBuilder.getModule(); 281 for (namespec = nsBegin; namespec != nsEnd; ++namespec) { 282 unsigned int pos = ArgNameSpecList.getPosition(namespec - nsBegin); 283 actions.push_back(new NamespecAction(pos, *namespec, 284 module.getScript().directories())); 285 actions.push_back(new ContextAction(pos)); 286 actions.push_back(new MemoryAreaAction(pos, FileHandle::ReadOnly)); 287 } 288 289 // ----- attributes ----- // 290 /// --whole-archive 291 cl::list<bool>::iterator attr, attrBegin, attrEnd; 292 attrBegin = ArgWholeArchiveList.begin(); 293 attrEnd = ArgWholeArchiveList.end(); 294 for (attr = attrBegin; attr != attrEnd; ++attr) { 295 unsigned int pos = ArgWholeArchiveList.getPosition(attr - attrBegin); 296 actions.push_back(new WholeArchiveAction(pos)); 297 } 298 299 /// --no-whole-archive 300 attrBegin = ArgNoWholeArchiveList.begin(); 301 attrEnd = ArgNoWholeArchiveList.end(); 302 for (attr = attrBegin; attr != attrEnd; ++attr) { 303 unsigned int pos = ArgNoWholeArchiveList.getPosition(attr - attrBegin); 304 actions.push_back(new NoWholeArchiveAction(pos)); 305 } 306 307 /// --as-needed 308 attrBegin = ArgAsNeededList.begin(); 309 attrEnd = ArgAsNeededList.end(); 310 for (attr = attrBegin; attr != attrEnd; ++attr) { 311 unsigned int pos = ArgAsNeededList.getPosition(attr - attrBegin); 312 actions.push_back(new AsNeededAction(pos)); 313 } 314 315 /// --no-as-needed 316 attrBegin = ArgNoAsNeededList.begin(); 317 attrEnd = ArgNoAsNeededList.end(); 318 for (attr = attrBegin; attr != attrEnd; ++attr) { 319 unsigned int pos = ArgNoAsNeededList.getPosition(attr - attrBegin); 320 actions.push_back(new NoAsNeededAction(pos)); 321 } 322 323 /// --add--needed 324 attrBegin = ArgAddNeededList.begin(); 325 attrEnd = ArgAddNeededList.end(); 326 for (attr = attrBegin; attr != attrEnd; ++attr) { 327 unsigned int pos = ArgAddNeededList.getPosition(attr - attrBegin); 328 actions.push_back(new AddNeededAction(pos)); 329 } 330 331 /// --no-add--needed 332 attrBegin = ArgNoAddNeededList.begin(); 333 attrEnd = ArgNoAddNeededList.end(); 334 for (attr = attrBegin; attr != attrEnd; ++attr) { 335 unsigned int pos = ArgNoAddNeededList.getPosition(attr - attrBegin); 336 actions.push_back(new NoAddNeededAction(pos)); 337 } 338 339 /// --Bdynamic 340 attrBegin = ArgBDynamicList.begin(); 341 attrEnd = ArgBDynamicList.end(); 342 for (attr = attrBegin; attr != attrEnd; ++attr) { 343 unsigned int pos = ArgBDynamicList.getPosition(attr - attrBegin); 344 actions.push_back(new BDynamicAction(pos)); 345 } 346 347 /// --Bstatic 348 attrBegin = ArgBStaticList.begin(); 349 attrEnd = ArgBStaticList.end(); 350 for (attr = attrBegin; attr != attrEnd; ++attr) { 351 unsigned int pos = ArgBStaticList.getPosition(attr - attrBegin); 352 actions.push_back(new BStaticAction(pos)); 353 } 354 355 // ----- groups ----- // 356 /// --start-group 357 cl::list<bool>::iterator group, gsBegin, gsEnd; 358 gsBegin = ArgStartGroupList.begin(); 359 gsEnd = ArgStartGroupList.end(); 360 for (group = gsBegin; group != gsEnd; ++group) { 361 unsigned int pos = ArgStartGroupList.getPosition(group - gsBegin); 362 actions.push_back(new StartGroupAction(pos)); 363 } 364 365 /// --end-group 366 gsBegin = ArgEndGroupList.begin(); 367 gsEnd = ArgEndGroupList.end(); 368 for (group = gsBegin; group != gsEnd; ++group) { 369 unsigned int pos = ArgEndGroupList.getPosition(group - gsBegin); 370 actions.push_back(new EndGroupAction(pos)); 371 } 372 373 // ----- bitcode ----- // 374 if (m_Config.bitcode().hasDefined()) { 375 actions.push_back(new BitcodeAction(m_Config.bitcode().getPosition(), 376 m_Config.bitcode().getPath())); 377 } 378 379 // stable sort 380 std::stable_sort(actions.begin(), actions.end(), CompareAction); 381 382 // build up input tree 383 std::vector<InputAction*>::iterator action, actionEnd = actions.end(); 384 for (action = actions.begin(); action != actionEnd; ++action) { 385 (*action)->activate(pBuilder.getInputBuilder()); 386 delete *action; 387 } 388 389 if (pBuilder.getInputBuilder().isInGroup()) 390 report_fatal_error("no matched --start-group and --end-group"); 391 } 392 393