15ed68d29a140e14c8d46980fa844548eb33b1e87Mike Lockwood//===- ScriptFile.cpp -----------------------------------------------------===// 25ed68d29a140e14c8d46980fa844548eb33b1e87Mike Lockwood// 35ed68d29a140e14c8d46980fa844548eb33b1e87Mike Lockwood// The MCLinker Project 45ed68d29a140e14c8d46980fa844548eb33b1e87Mike Lockwood// 55ed68d29a140e14c8d46980fa844548eb33b1e87Mike Lockwood// This file is distributed under the University of Illinois Open Source 65ed68d29a140e14c8d46980fa844548eb33b1e87Mike Lockwood// License. See LICENSE.TXT for details. 75ed68d29a140e14c8d46980fa844548eb33b1e87Mike Lockwood// 85ed68d29a140e14c8d46980fa844548eb33b1e87Mike Lockwood//===----------------------------------------------------------------------===// 95ed68d29a140e14c8d46980fa844548eb33b1e87Mike Lockwood#include "mcld/Script/ScriptFile.h" 105ed68d29a140e14c8d46980fa844548eb33b1e87Mike Lockwood 115ed68d29a140e14c8d46980fa844548eb33b1e87Mike Lockwood#include "mcld/ADT/HashEntry.h" 125ed68d29a140e14c8d46980fa844548eb33b1e87Mike Lockwood#include "mcld/ADT/HashTable.h" 135ed68d29a140e14c8d46980fa844548eb33b1e87Mike Lockwood#include "mcld/ADT/StringHash.h" 145ed68d29a140e14c8d46980fa844548eb33b1e87Mike Lockwood#include "mcld/Script/AssertCmd.h" 155ed68d29a140e14c8d46980fa844548eb33b1e87Mike Lockwood#include "mcld/Script/EntryCmd.h" 165ed68d29a140e14c8d46980fa844548eb33b1e87Mike Lockwood#include "mcld/Script/GroupCmd.h" 175ed68d29a140e14c8d46980fa844548eb33b1e87Mike Lockwood#include "mcld/Script/InputCmd.h" 185ed68d29a140e14c8d46980fa844548eb33b1e87Mike Lockwood#include "mcld/Script/Operand.h" 195ed68d29a140e14c8d46980fa844548eb33b1e87Mike Lockwood#include "mcld/Script/OutputArchCmd.h" 208a7ffae09a019de7109b30c505561c453910bde1Daichi Hirono#include "mcld/Script/OutputCmd.h" 215ed68d29a140e14c8d46980fa844548eb33b1e87Mike Lockwood#include "mcld/Script/OutputFormatCmd.h" 228a7ffae09a019de7109b30c505561c453910bde1Daichi Hirono#include "mcld/Script/RpnExpr.h" 235ed68d29a140e14c8d46980fa844548eb33b1e87Mike Lockwood#include "mcld/Script/ScriptCommand.h" 245ed68d29a140e14c8d46980fa844548eb33b1e87Mike Lockwood#include "mcld/Script/SearchDirCmd.h" 255ed68d29a140e14c8d46980fa844548eb33b1e87Mike Lockwood#include "mcld/Script/SectionsCmd.h" 260cf89f2e622aa53f31fa5762ca4bc805bb509ed3Mike Lockwood#include "mcld/Script/StringList.h" 270cf89f2e622aa53f31fa5762ca4bc805bb509ed3Mike Lockwood#include "mcld/Script/StrToken.h" 28b14e588bec4d5e39e61b020b5b575f2ce555d316Mike Lockwood#include "mcld/MC/Input.h" 2942d0b79a787814d42e4c6f9dfe14f13cc0f6a758Mike Lockwood#include "mcld/MC/InputBuilder.h" 3042d0b79a787814d42e4c6f9dfe14f13cc0f6a758Mike Lockwood#include "mcld/Support/MemoryArea.h" 31b14e588bec4d5e39e61b020b5b575f2ce555d316Mike Lockwood#include "mcld/InputTree.h" 325ed68d29a140e14c8d46980fa844548eb33b1e87Mike Lockwood 335ed68d29a140e14c8d46980fa844548eb33b1e87Mike Lockwood#include <llvm/Support/Casting.h> 345ed68d29a140e14c8d46980fa844548eb33b1e87Mike Lockwood#include <llvm/Support/ManagedStatic.h> 358a7ffae09a019de7109b30c505561c453910bde1Daichi Hirono 365ed68d29a140e14c8d46980fa844548eb33b1e87Mike Lockwood#include <cassert> 375ed68d29a140e14c8d46980fa844548eb33b1e87Mike Lockwood 385ed68d29a140e14c8d46980fa844548eb33b1e87Mike Lockwoodnamespace mcld { 395ed68d29a140e14c8d46980fa844548eb33b1e87Mike Lockwood 405ed68d29a140e14c8d46980fa844548eb33b1e87Mike Lockwoodtypedef HashEntry<std::string, void*, hash::StringCompare<std::string> > 415ed68d29a140e14c8d46980fa844548eb33b1e87Mike Lockwood ParserStrEntry; 425ed68d29a140e14c8d46980fa844548eb33b1e87Mike Lockwoodtypedef HashTable<ParserStrEntry, 4342d0b79a787814d42e4c6f9dfe14f13cc0f6a758Mike Lockwood hash::StringHash<hash::DJB>, 4442d0b79a787814d42e4c6f9dfe14f13cc0f6a758Mike Lockwood EntryFactory<ParserStrEntry> > ParserStrPool; 4542d0b79a787814d42e4c6f9dfe14f13cc0f6a758Mike Lockwoodstatic llvm::ManagedStatic<ParserStrPool> g_ParserStrPool; 4642d0b79a787814d42e4c6f9dfe14f13cc0f6a758Mike Lockwood 475ed68d29a140e14c8d46980fa844548eb33b1e87Mike Lockwood//===----------------------------------------------------------------------===// 48a6c490b8b2d96ebaab632286029463f932ae3b6bMike Lockwood// ScriptFile 495ed68d29a140e14c8d46980fa844548eb33b1e87Mike Lockwood//===----------------------------------------------------------------------===// 505ed68d29a140e14c8d46980fa844548eb33b1e87Mike LockwoodScriptFile::ScriptFile(Kind pKind, Input& pInput, InputBuilder& pBuilder) 515ed68d29a140e14c8d46980fa844548eb33b1e87Mike Lockwood : m_Kind(pKind), 525ed68d29a140e14c8d46980fa844548eb33b1e87Mike Lockwood m_Input(pInput), 535ed68d29a140e14c8d46980fa844548eb33b1e87Mike Lockwood m_Name(pInput.path().native()), 545ed68d29a140e14c8d46980fa844548eb33b1e87Mike Lockwood m_pInputTree(NULL), 555ed68d29a140e14c8d46980fa844548eb33b1e87Mike Lockwood m_Builder(pBuilder), 565ed68d29a140e14c8d46980fa844548eb33b1e87Mike Lockwood m_bHasSectionsCmd(false), 575ed68d29a140e14c8d46980fa844548eb33b1e87Mike Lockwood m_bInSectionsCmd(false), 588a7ffae09a019de7109b30c505561c453910bde1Daichi Hirono m_bInOutputSectDesc(false), 598a7ffae09a019de7109b30c505561c453910bde1Daichi Hirono m_pRpnExpr(NULL), 60f7454622eaac287d20ab43013d7015fe42b894f8Mike Lockwood m_pStringList(NULL), 61f7454622eaac287d20ab43013d7015fe42b894f8Mike Lockwood m_bAsNeeded(false) { 628a7ffae09a019de7109b30c505561c453910bde1Daichi Hirono // FIXME: move creation of input tree out of ScriptFile. 638a7ffae09a019de7109b30c505561c453910bde1Daichi Hirono m_pInputTree = new InputTree(); 645ed68d29a140e14c8d46980fa844548eb33b1e87Mike Lockwood} 658d20945c08dfdd85c252c8ba92d197bf1bd2b208Daichi Hirono 668d20945c08dfdd85c252c8ba92d197bf1bd2b208Daichi HironoScriptFile::~ScriptFile() { 678d20945c08dfdd85c252c8ba92d197bf1bd2b208Daichi Hirono for (iterator it = begin(), ie = end(); it != ie; ++it) { 688d20945c08dfdd85c252c8ba92d197bf1bd2b208Daichi Hirono if (*it != NULL) 690cf89f2e622aa53f31fa5762ca4bc805bb509ed3Mike Lockwood delete *it; 700cf89f2e622aa53f31fa5762ca4bc805bb509ed3Mike Lockwood } 718a7ffae09a019de7109b30c505561c453910bde1Daichi Hirono if (m_pInputTree != NULL) 728a7ffae09a019de7109b30c505561c453910bde1Daichi Hirono delete m_pInputTree; 730cf89f2e622aa53f31fa5762ca4bc805bb509ed3Mike Lockwood} 74d4b4296b401162a7a42f757c96e3652b82255b13Daichi Hirono 75d4b4296b401162a7a42f757c96e3652b82255b13Daichi Hironovoid ScriptFile::dump() const { 76d4b4296b401162a7a42f757c96e3652b82255b13Daichi Hirono for (const_iterator it = begin(), ie = end(); it != ie; ++it) 775ed68d29a140e14c8d46980fa844548eb33b1e87Mike Lockwood (*it)->dump(); 784a7cea889d81bbf8f555df006fe384a405b3ba53Daichi Hirono} 794a7cea889d81bbf8f555df006fe384a405b3ba53Daichi Hirono 804a7cea889d81bbf8f555df006fe384a405b3ba53Daichi Hironovoid ScriptFile::activate(Module& pModule) { 814a7cea889d81bbf8f555df006fe384a405b3ba53Daichi Hirono for (const_iterator it = begin(), ie = end(); it != ie; ++it) 824a7cea889d81bbf8f555df006fe384a405b3ba53Daichi Hirono (*it)->activate(pModule); 834a7cea889d81bbf8f555df006fe384a405b3ba53Daichi Hirono} 844a7cea889d81bbf8f555df006fe384a405b3ba53Daichi Hirono 854a7cea889d81bbf8f555df006fe384a405b3ba53Daichi Hironovoid ScriptFile::addEntryPoint(const std::string& pSymbol) { 865ed68d29a140e14c8d46980fa844548eb33b1e87Mike Lockwood EntryCmd* entry = new EntryCmd(pSymbol); 8723f1b33c5f88f07510ca5dc01b3afd7af6843d6cMike Lockwood 8823f1b33c5f88f07510ca5dc01b3afd7af6843d6cMike Lockwood if (m_bInSectionsCmd) { 8923f1b33c5f88f07510ca5dc01b3afd7af6843d6cMike Lockwood assert(!m_CommandQueue.empty()); 905ed68d29a140e14c8d46980fa844548eb33b1e87Mike Lockwood SectionsCmd* sections = llvm::cast<SectionsCmd>(back()); 915ed68d29a140e14c8d46980fa844548eb33b1e87Mike Lockwood sections->push_back(entry); 925ed68d29a140e14c8d46980fa844548eb33b1e87Mike Lockwood } else { 930c7c7c76a96a82ec728a2d5c091941c4057ffb25Mike Lockwood m_CommandQueue.push_back(entry); 945ed68d29a140e14c8d46980fa844548eb33b1e87Mike Lockwood } 955ed68d29a140e14c8d46980fa844548eb33b1e87Mike Lockwood} 965ed68d29a140e14c8d46980fa844548eb33b1e87Mike Lockwood 975ed68d29a140e14c8d46980fa844548eb33b1e87Mike Lockwoodvoid ScriptFile::addOutputFormatCmd(const std::string& pName) { 985ed68d29a140e14c8d46980fa844548eb33b1e87Mike Lockwood m_CommandQueue.push_back(new OutputFormatCmd(pName)); 995ed68d29a140e14c8d46980fa844548eb33b1e87Mike Lockwood} 1005ed68d29a140e14c8d46980fa844548eb33b1e87Mike Lockwood 1015ed68d29a140e14c8d46980fa844548eb33b1e87Mike Lockwoodvoid ScriptFile::addOutputFormatCmd(const std::string& pDefault, 10227afe3a1cc9c07ac4884a7720087a597aea3c76fMike Lockwood const std::string& pBig, 10327afe3a1cc9c07ac4884a7720087a597aea3c76fMike Lockwood const std::string& pLittle) { 1045ed68d29a140e14c8d46980fa844548eb33b1e87Mike Lockwood m_CommandQueue.push_back(new OutputFormatCmd(pDefault, pBig, pLittle)); 1053e072b354d1e1e3ee62d58492f0739139df8aff1Mike Lockwood} 1060cf89f2e622aa53f31fa5762ca4bc805bb509ed3Mike Lockwood 107532b4f23c7e08fdae9fff189c4b565f6216ffd2aTomasz Mikolajewskivoid ScriptFile::addInputCmd(StringList& pStringList, 1086afc41d095ccb159f6c4705bed903b6c048b922aMike Lockwood ObjectReader& pObjectReader, 1096afc41d095ccb159f6c4705bed903b6c048b922aMike Lockwood ArchiveReader& pArchiveReader, 110d7221079292b17a81ec003adef06d58019d9236dDaichi Hirono DynObjReader& pDynObjReader, 1115ed68d29a140e14c8d46980fa844548eb33b1e87Mike Lockwood const LinkerConfig& pConfig) { 11298693f674125484de8873d969c209276a6dd604bMike Lockwood m_CommandQueue.push_back(new InputCmd(pStringList, 11398693f674125484de8873d969c209276a6dd604bMike Lockwood *m_pInputTree, 114a6c490b8b2d96ebaab632286029463f932ae3b6bMike Lockwood m_Builder, 11599e393a39a31bfbdeb435462939519e2d0279433Mike Lockwood pObjectReader, 116a6c490b8b2d96ebaab632286029463f932ae3b6bMike Lockwood pArchiveReader, 11766a9abef47f7c8bd438bb1897617ebad3858c736Daichi Hirono pDynObjReader, 11866a9abef47f7c8bd438bb1897617ebad3858c736Daichi Hirono pConfig)); 11966a9abef47f7c8bd438bb1897617ebad3858c736Daichi Hirono} 1204fd9a8b9865addfedbcd84d5c9efea0f647086a0Daichi Hirono 1214a7cea889d81bbf8f555df006fe384a405b3ba53Daichi Hironovoid ScriptFile::addGroupCmd(StringList& pStringList, 12223f1b33c5f88f07510ca5dc01b3afd7af6843d6cMike Lockwood GroupReader& pGroupReader, 12327afe3a1cc9c07ac4884a7720087a597aea3c76fMike Lockwood const LinkerConfig& pConfig) { 124025ffd9c17a7b30d862436954aa0db8d08bfaa9fTomasz Mikolajewski m_CommandQueue.push_back(new GroupCmd( 1254a7cea889d81bbf8f555df006fe384a405b3ba53Daichi Hirono pStringList, *m_pInputTree, m_Builder, pGroupReader, pConfig)); 1264a7cea889d81bbf8f555df006fe384a405b3ba53Daichi Hirono} 1274a7cea889d81bbf8f555df006fe384a405b3ba53Daichi Hirono 1284a7cea889d81bbf8f555df006fe384a405b3ba53Daichi Hironovoid ScriptFile::addOutputCmd(const std::string& pFileName) { 1294a7cea889d81bbf8f555df006fe384a405b3ba53Daichi Hirono m_CommandQueue.push_back(new OutputCmd(pFileName)); 1304a7cea889d81bbf8f555df006fe384a405b3ba53Daichi Hirono} 131326edd98bbc52d41de6e0943ca8a343228ed87a5Daichi Hirono 132326edd98bbc52d41de6e0943ca8a343228ed87a5Daichi Hironovoid ScriptFile::addSearchDirCmd(const std::string& pPath) { 133326edd98bbc52d41de6e0943ca8a343228ed87a5Daichi Hirono m_CommandQueue.push_back(new SearchDirCmd(pPath)); 134326edd98bbc52d41de6e0943ca8a343228ed87a5Daichi Hirono} 135326edd98bbc52d41de6e0943ca8a343228ed87a5Daichi Hirono 136326edd98bbc52d41de6e0943ca8a343228ed87a5Daichi Hironovoid ScriptFile::addOutputArchCmd(const std::string& pArch) { 1378a7ffae09a019de7109b30c505561c453910bde1Daichi Hirono m_CommandQueue.push_back(new OutputArchCmd(pArch)); 1388a7ffae09a019de7109b30c505561c453910bde1Daichi Hirono} 1398a7ffae09a019de7109b30c505561c453910bde1Daichi Hirono 1408a7ffae09a019de7109b30c505561c453910bde1Daichi Hironovoid ScriptFile::addAssertCmd(RpnExpr& pRpnExpr, const std::string& pMessage) { 1418a7ffae09a019de7109b30c505561c453910bde1Daichi Hirono m_CommandQueue.push_back(new AssertCmd(pRpnExpr, pMessage)); 1428a7ffae09a019de7109b30c505561c453910bde1Daichi Hirono} 14359a90609cc340d2933c119aa47045a5c95530b48Daichi Hirono 14459a90609cc340d2933c119aa47045a5c95530b48Daichi Hironovoid ScriptFile::addAssignment(const std::string& pSymbolName, 14559a90609cc340d2933c119aa47045a5c95530b48Daichi Hirono RpnExpr& pRpnExpr, 1468a7ffae09a019de7109b30c505561c453910bde1Daichi Hirono Assignment::Type pType) { 1478a7ffae09a019de7109b30c505561c453910bde1Daichi Hirono if (m_bInSectionsCmd) { 1488a7ffae09a019de7109b30c505561c453910bde1Daichi Hirono assert(!m_CommandQueue.empty()); 1498a7ffae09a019de7109b30c505561c453910bde1Daichi Hirono SectionsCmd* sections = llvm::cast<SectionsCmd>(back()); 1500cf89f2e622aa53f31fa5762ca4bc805bb509ed3Mike Lockwood if (m_bInOutputSectDesc) { 1515ed68d29a140e14c8d46980fa844548eb33b1e87Mike Lockwood assert(!sections->empty()); 1524fd9a8b9865addfedbcd84d5c9efea0f647086a0Daichi Hirono OutputSectDesc* output_desc = 1534a7cea889d81bbf8f555df006fe384a405b3ba53Daichi Hirono llvm::cast<OutputSectDesc>(sections->back()); 1544a7cea889d81bbf8f555df006fe384a405b3ba53Daichi Hirono output_desc->push_back(new Assignment(Assignment::INPUT_SECTION, 1554a7cea889d81bbf8f555df006fe384a405b3ba53Daichi Hirono pType, 1564a7cea889d81bbf8f555df006fe384a405b3ba53Daichi Hirono *(SymOperand::create(pSymbolName)), 1574a7cea889d81bbf8f555df006fe384a405b3ba53Daichi Hirono pRpnExpr)); 1584a7cea889d81bbf8f555df006fe384a405b3ba53Daichi Hirono } else { 1594a7cea889d81bbf8f555df006fe384a405b3ba53Daichi Hirono sections->push_back(new Assignment(Assignment::OUTPUT_SECTION, 1604a7cea889d81bbf8f555df006fe384a405b3ba53Daichi Hirono pType, 1614a7cea889d81bbf8f555df006fe384a405b3ba53Daichi Hirono *(SymOperand::create(pSymbolName)), 1625ed68d29a140e14c8d46980fa844548eb33b1e87Mike Lockwood pRpnExpr)); 1630cf89f2e622aa53f31fa5762ca4bc805bb509ed3Mike Lockwood } 1645ed68d29a140e14c8d46980fa844548eb33b1e87Mike Lockwood } else { 1650cf89f2e622aa53f31fa5762ca4bc805bb509ed3Mike Lockwood m_CommandQueue.push_back(new Assignment(Assignment::OUTSIDE_SECTIONS, 1665ed68d29a140e14c8d46980fa844548eb33b1e87Mike Lockwood pType, 1675ed68d29a140e14c8d46980fa844548eb33b1e87Mike Lockwood *(SymOperand::create(pSymbolName)), 1685ed68d29a140e14c8d46980fa844548eb33b1e87Mike Lockwood pRpnExpr)); 1695ed68d29a140e14c8d46980fa844548eb33b1e87Mike Lockwood } 1705ed68d29a140e14c8d46980fa844548eb33b1e87Mike Lockwood} 1715ed68d29a140e14c8d46980fa844548eb33b1e87Mike Lockwood 172bool ScriptFile::hasSectionsCmd() const { 173 return m_bHasSectionsCmd; 174} 175 176void ScriptFile::enterSectionsCmd() { 177 m_bHasSectionsCmd = true; 178 m_bInSectionsCmd = true; 179 m_CommandQueue.push_back(new SectionsCmd()); 180} 181 182void ScriptFile::leaveSectionsCmd() { 183 m_bInSectionsCmd = false; 184} 185 186void ScriptFile::enterOutputSectDesc(const std::string& pName, 187 const OutputSectDesc::Prolog& pProlog) { 188 assert(!m_CommandQueue.empty()); 189 assert(m_bInSectionsCmd); 190 SectionsCmd* sections = llvm::cast<SectionsCmd>(back()); 191 sections->push_back(new OutputSectDesc(pName, pProlog)); 192 193 m_bInOutputSectDesc = true; 194} 195 196void ScriptFile::leaveOutputSectDesc(const OutputSectDesc::Epilog& pEpilog) { 197 assert(!m_CommandQueue.empty()); 198 assert(m_bInSectionsCmd); 199 SectionsCmd* sections = llvm::cast<SectionsCmd>(back()); 200 201 assert(!sections->empty() && m_bInOutputSectDesc); 202 OutputSectDesc* output_desc = llvm::cast<OutputSectDesc>(sections->back()); 203 output_desc->setEpilog(pEpilog); 204 205 m_bInOutputSectDesc = false; 206} 207 208void ScriptFile::addInputSectDesc(InputSectDesc::KeepPolicy pPolicy, 209 const InputSectDesc::Spec& pSpec) { 210 assert(!m_CommandQueue.empty()); 211 assert(m_bInSectionsCmd); 212 SectionsCmd* sections = llvm::cast<SectionsCmd>(back()); 213 214 assert(!sections->empty() && m_bInOutputSectDesc); 215 OutputSectDesc* output_sect = llvm::cast<OutputSectDesc>(sections->back()); 216 217 output_sect->push_back(new InputSectDesc(pPolicy, pSpec, *output_sect)); 218} 219 220RpnExpr* ScriptFile::createRpnExpr() { 221 m_pRpnExpr = RpnExpr::create(); 222 return m_pRpnExpr; 223} 224 225StringList* ScriptFile::createStringList() { 226 m_pStringList = StringList::create(); 227 return m_pStringList; 228} 229 230void ScriptFile::setAsNeeded(bool pEnable) { 231 m_bAsNeeded = pEnable; 232} 233 234const std::string& ScriptFile::createParserStr(const char* pText, 235 size_t pLength) { 236 bool exist = false; 237 ParserStrEntry* entry = 238 g_ParserStrPool->insert(std::string(pText, pLength), exist); 239 return entry->key(); 240} 241 242void ScriptFile::clearParserStrPool() { 243 g_ParserStrPool->clear(); 244} 245 246} // namespace mcld 247