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 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// MCLinker 190//===----------------------------------------------------------------------===// 191MCLinker::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 202MCLinker::~MCLinker() 203{ 204 delete m_pLinker; 205 delete m_pBuilder; 206} 207 208bool 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 223bool 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 234bool MCLinker::runOnMachineFunction(MachineFunction& pF) 235{ 236 // basically, linkers do nothing during function is generated. 237 return false; 238} 239 240void 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