MCLinker.cpp revision f33f6de54db174aa679a4b6d1e040d37e95541c0
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/LinkerScript.h> 18#include <mcld/InputTree.h> 19#include <mcld/Linker.h> 20#include <mcld/IRBuilder.h> 21#include <mcld/MC/InputBuilder.h> 22#include <mcld/MC/FileAction.h> 23#include <mcld/MC/CommandAction.h> 24#include <mcld/Object/ObjectLinker.h> 25#include <mcld/Support/CommandLine.h> 26#include <mcld/Support/FileSystem.h> 27#include <mcld/Support/MsgHandling.h> 28#include <mcld/Support/FileHandle.h> 29#include <mcld/Support/raw_ostream.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 38using namespace mcld; 39using namespace llvm; 40 41char MCLinker::m_ID = 0; 42 43//===----------------------------------------------------------------------===// 44// Help Functions 45//===----------------------------------------------------------------------===// 46static 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//===----------------------------------------------------------------------===// 67static cl::list<mcld::sys::fs::Path> 68ArgInputObjectFiles(cl::Positional, 69 cl::desc("[input object files]"), 70 cl::ZeroOrMore); 71 72//===----------------------------------------------------------------------===// 73// Namespecs 74//===----------------------------------------------------------------------===// 75static cl::list<std::string> 76ArgNameSpecList("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 83static cl::alias 84ArgNameSpecListAlias("library", 85 cl::desc("alias for -l"), 86 cl::aliasopt(ArgNameSpecList)); 87 88//===----------------------------------------------------------------------===// 89// Attributes 90//===----------------------------------------------------------------------===// 91static cl::list<bool> 92ArgWholeArchiveList("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 98static cl::list<bool> 99ArgNoWholeArchiveList("no-whole-archive", 100 cl::ValueDisallowed, 101 cl::desc("Turn off the effect of the --whole-archive option for " 102 "subsequent archive files.")); 103 104static cl::list<bool> 105ArgAsNeededList("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 111static cl::list<bool> 112ArgNoAsNeededList("no-as-needed", 113 cl::ValueDisallowed, 114 cl::desc("Turn off the effect of the --as-needed option for " 115 "subsequent dynamic libraries")); 116 117static cl::list<bool> 118ArgAddNeededList("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 124static cl::list<bool> 125ArgNoAddNeededList("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 130static cl::list<bool> 131ArgBDynamicList("Bdynamic", 132 cl::ValueDisallowed, 133 cl::desc("Link against dynamic library")); 134 135static cl::alias 136ArgBDynamicListAlias1("dy", 137 cl::desc("alias for --Bdynamic"), 138 cl::aliasopt(ArgBDynamicList)); 139 140static cl::alias 141ArgBDynamicListAlias2("call_shared", 142 cl::desc("alias for --Bdynamic"), 143 cl::aliasopt(ArgBDynamicList)); 144 145static cl::list<bool> 146ArgBStaticList("Bstatic", 147 cl::ValueDisallowed, 148 cl::desc("Link against static library")); 149 150static cl::alias 151ArgBStaticListAlias1("dn", 152 cl::desc("alias for --Bstatic"), 153 cl::aliasopt(ArgBStaticList)); 154 155static cl::alias 156ArgBStaticListAlias2("static", 157 cl::desc("alias for --Bstatic"), 158 cl::aliasopt(ArgBStaticList)); 159 160static cl::alias 161ArgBStaticListAlias3("non_shared", 162 cl::desc("alias for --Bstatic"), 163 cl::aliasopt(ArgBStaticList)); 164 165//===----------------------------------------------------------------------===// 166// Groups 167//===----------------------------------------------------------------------===// 168static cl::list<bool> 169ArgStartGroupList("start-group", 170 cl::ValueDisallowed, 171 cl::desc("start to record a group of archives")); 172 173static cl::alias 174ArgStartGroupListAlias("(", 175 cl::desc("alias for --start-group"), 176 cl::aliasopt(ArgStartGroupList)); 177 178static cl::list<bool> 179ArgEndGroupList("end-group", 180 cl::ValueDisallowed, 181 cl::desc("stop recording a group of archives")); 182 183static cl::alias 184ArgEndGroupListAlias(")", 185 cl::desc("alias for --end-group"), 186 cl::aliasopt(ArgEndGroupList)); 187 188//===----------------------------------------------------------------------===// 189// --defsym 190//===----------------------------------------------------------------------===// 191static cl::list<std::string> 192ArgDefSymList("defsym", 193 cl::ZeroOrMore, 194 cl::desc("Define a symbol"), 195 cl::value_desc("symbol=expression")); 196 197//===----------------------------------------------------------------------===// 198// MCLinker 199//===----------------------------------------------------------------------===// 200MCLinker::MCLinker(LinkerConfig& pConfig, 201 mcld::Module& pModule, 202 FileHandle& pFileHandle) 203 : MachineFunctionPass(m_ID), 204 m_Config(pConfig), 205 m_Module(pModule), 206 m_FileHandle(pFileHandle), 207 m_pBuilder(NULL), 208 m_pLinker(NULL) { 209} 210 211MCLinker::~MCLinker() 212{ 213 delete m_pLinker; 214 delete m_pBuilder; 215} 216 217bool MCLinker::doInitialization(llvm::Module &pM) 218{ 219 // Now, all input arguments are prepared well, send it into ObjectLinker 220 m_pLinker = new Linker(); 221 222 if (!m_pLinker->emulate(m_Module.getScript(), m_Config)) 223 return false; 224 225 m_pBuilder = new IRBuilder(m_Module, m_Config); 226 227 initializeInputTree(*m_pBuilder); 228 229 return true; 230} 231 232bool MCLinker::doFinalization(llvm::Module &pM) 233{ 234 if (!m_pLinker->link(m_Module, *m_pBuilder)) 235 return true; 236 237 if (!m_pLinker->emit(m_Module, m_FileHandle.handler())) 238 return true; 239 240 return false; 241} 242 243bool MCLinker::runOnMachineFunction(MachineFunction& pF) 244{ 245 // basically, linkers do nothing during function is generated. 246 return false; 247} 248 249void MCLinker::initializeInputTree(IRBuilder& pBuilder) 250{ 251 if (0 == ArgInputObjectFiles.size() && 252 0 == ArgNameSpecList.size() && 253 !m_Config.bitcode().hasDefined()) { 254 fatal(diag::err_no_inputs); 255 return; 256 } 257 258 size_t num_actions = ArgInputObjectFiles.size() + 259 ArgNameSpecList.size() + 260 ArgWholeArchiveList.size() + 261 ArgNoWholeArchiveList.size() + 262 ArgAsNeededList.size() + 263 ArgNoAsNeededList.size() + 264 ArgAddNeededList.size() + 265 ArgNoAddNeededList.size() + 266 ArgBDynamicList.size() + 267 ArgBStaticList.size() + 268 ArgStartGroupList.size() + 269 ArgEndGroupList.size() + 270 ArgDefSymList.size() + 271 1; // bitcode 272 std::vector<InputAction*> actions; 273 actions.reserve(num_actions); 274 275 // ----- scripts ----- // 276 /// -T 277 if (!m_Config.options().getScriptList().empty()) { 278 GeneralOptions::const_script_iterator ii, ie = m_Config.options().script_end(); 279 for (ii = m_Config.options().script_begin(); ii != ie; ++ii) { 280 actions.push_back(new ScriptAction(0x0, 281 *ii, 282 ScriptFile::LDScript, 283 m_Module.getScript().directories())); 284 actions.push_back(new ContextAction(0x0)); 285 actions.push_back(new MemoryAreaAction(0x0, FileHandle::ReadOnly)); 286 } 287 } 288 289 /// --defsym 290 cl::list<std::string>::iterator defsym, dsBegin, dsEnd; 291 dsBegin = ArgDefSymList.begin(); 292 dsEnd = ArgDefSymList.end(); 293 for (defsym = dsBegin; defsym != dsEnd; ++defsym) { 294 unsigned int pos = ArgDefSymList.getPosition(defsym - dsBegin); 295 actions.push_back(new DefSymAction(pos, *defsym)); 296 } 297 298 // ----- inputs ----- // 299 cl::list<mcld::sys::fs::Path>::iterator input, inBegin, inEnd; 300 inBegin = ArgInputObjectFiles.begin(); 301 inEnd = ArgInputObjectFiles.end(); 302 for (input = inBegin; input != inEnd; ++input) { 303 unsigned int pos = ArgInputObjectFiles.getPosition(input - inBegin); 304 actions.push_back(new InputFileAction(pos, *input)); 305 actions.push_back(new ContextAction(pos)); 306 actions.push_back(new MemoryAreaAction(pos, FileHandle::ReadOnly)); 307 } 308 309 // ----- namespecs ----- // 310 cl::list<std::string>::iterator namespec, nsBegin, nsEnd; 311 nsBegin = ArgNameSpecList.begin(); 312 nsEnd = ArgNameSpecList.end(); 313 for (namespec = nsBegin; namespec != nsEnd; ++namespec) { 314 unsigned int pos = ArgNameSpecList.getPosition(namespec - nsBegin); 315 actions.push_back(new NamespecAction(pos, *namespec, 316 m_Module.getScript().directories())); 317 actions.push_back(new ContextAction(pos)); 318 actions.push_back(new MemoryAreaAction(pos, FileHandle::ReadOnly)); 319 } 320 321 // ----- attributes ----- // 322 /// --whole-archive 323 cl::list<bool>::iterator attr, attrBegin, attrEnd; 324 attrBegin = ArgWholeArchiveList.begin(); 325 attrEnd = ArgWholeArchiveList.end(); 326 for (attr = attrBegin; attr != attrEnd; ++attr) { 327 unsigned int pos = ArgWholeArchiveList.getPosition(attr - attrBegin); 328 actions.push_back(new WholeArchiveAction(pos)); 329 } 330 331 /// --no-whole-archive 332 attrBegin = ArgNoWholeArchiveList.begin(); 333 attrEnd = ArgNoWholeArchiveList.end(); 334 for (attr = attrBegin; attr != attrEnd; ++attr) { 335 unsigned int pos = ArgNoWholeArchiveList.getPosition(attr - attrBegin); 336 actions.push_back(new NoWholeArchiveAction(pos)); 337 } 338 339 /// --as-needed 340 attrBegin = ArgAsNeededList.begin(); 341 attrEnd = ArgAsNeededList.end(); 342 for (attr = attrBegin; attr != attrEnd; ++attr) { 343 unsigned int pos = ArgAsNeededList.getPosition(attr - attrBegin); 344 actions.push_back(new AsNeededAction(pos)); 345 } 346 347 /// --no-as-needed 348 attrBegin = ArgNoAsNeededList.begin(); 349 attrEnd = ArgNoAsNeededList.end(); 350 for (attr = attrBegin; attr != attrEnd; ++attr) { 351 unsigned int pos = ArgNoAsNeededList.getPosition(attr - attrBegin); 352 actions.push_back(new NoAsNeededAction(pos)); 353 } 354 355 /// --add--needed 356 attrBegin = ArgAddNeededList.begin(); 357 attrEnd = ArgAddNeededList.end(); 358 for (attr = attrBegin; attr != attrEnd; ++attr) { 359 unsigned int pos = ArgAddNeededList.getPosition(attr - attrBegin); 360 actions.push_back(new AddNeededAction(pos)); 361 } 362 363 /// --no-add--needed 364 attrBegin = ArgNoAddNeededList.begin(); 365 attrEnd = ArgNoAddNeededList.end(); 366 for (attr = attrBegin; attr != attrEnd; ++attr) { 367 unsigned int pos = ArgNoAddNeededList.getPosition(attr - attrBegin); 368 actions.push_back(new NoAddNeededAction(pos)); 369 } 370 371 /// --Bdynamic 372 attrBegin = ArgBDynamicList.begin(); 373 attrEnd = ArgBDynamicList.end(); 374 for (attr = attrBegin; attr != attrEnd; ++attr) { 375 unsigned int pos = ArgBDynamicList.getPosition(attr - attrBegin); 376 actions.push_back(new BDynamicAction(pos)); 377 } 378 379 /// --Bstatic 380 attrBegin = ArgBStaticList.begin(); 381 attrEnd = ArgBStaticList.end(); 382 for (attr = attrBegin; attr != attrEnd; ++attr) { 383 unsigned int pos = ArgBStaticList.getPosition(attr - attrBegin); 384 actions.push_back(new BStaticAction(pos)); 385 } 386 387 // ----- groups ----- // 388 /// --start-group 389 cl::list<bool>::iterator group, gsBegin, gsEnd; 390 gsBegin = ArgStartGroupList.begin(); 391 gsEnd = ArgStartGroupList.end(); 392 for (group = gsBegin; group != gsEnd; ++group) { 393 unsigned int pos = ArgStartGroupList.getPosition(group - gsBegin); 394 actions.push_back(new StartGroupAction(pos)); 395 } 396 397 /// --end-group 398 gsBegin = ArgEndGroupList.begin(); 399 gsEnd = ArgEndGroupList.end(); 400 for (group = gsBegin; group != gsEnd; ++group) { 401 unsigned int pos = ArgEndGroupList.getPosition(group - gsBegin); 402 actions.push_back(new EndGroupAction(pos)); 403 } 404 405 // ----- bitcode ----- // 406 if (m_Config.bitcode().hasDefined()) { 407 actions.push_back(new BitcodeAction(m_Config.bitcode().getPosition(), 408 m_Config.bitcode().getPath())); 409 } 410 411 // stable sort 412 std::stable_sort(actions.begin(), actions.end(), CompareAction); 413 414 // build up input tree 415 std::vector<InputAction*>::iterator action, actionEnd = actions.end(); 416 for (action = actions.begin(); action != actionEnd; ++action) { 417 (*action)->activate(pBuilder.getInputBuilder()); 418 delete *action; 419 } 420 421 if (pBuilder.getInputBuilder().isInGroup()) 422 report_fatal_error("no matched --start-group and --end-group"); 423} 424 425