1f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines//===- Assignment.cpp -----------------------------------------------------===// 2f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines// 3f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines// The MCLinker Project 4f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines// 5f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines// This file is distributed under the University of Illinois Open Source 6f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines// License. See LICENSE.TXT for details. 7f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines// 8f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines//===----------------------------------------------------------------------===// 9f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines#include <mcld/Script/Assignment.h> 10f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines#include <mcld/Script/RpnExpr.h> 11f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines#include <mcld/Script/Operand.h> 12f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines#include <mcld/Script/Operator.h> 13f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines#include <mcld/Script/RpnEvaluator.h> 14f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines#include <mcld/Support/raw_ostream.h> 15f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines#include <mcld/LinkerScript.h> 16f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines#include <mcld/LD/LDSection.h> 17f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines#include <mcld/LD/SectionData.h> 18f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines#include <mcld/Module.h> 19f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines#include <llvm/Support/Casting.h> 20f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines#include <cassert> 21f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines 22f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hinesusing namespace mcld; 23f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines 24f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines//===----------------------------------------------------------------------===// 25f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines// Assignment 26f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines//===----------------------------------------------------------------------===// 27f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen HinesAssignment::Assignment(Level pLevel, 28f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines Type pType, 29f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines SymOperand& pSymbol, 30f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines RpnExpr& pRpnExpr) 31f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines : ScriptCommand(ScriptCommand::ASSIGNMENT), 32f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines m_Level(pLevel), 33f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines m_Type(pType), 34f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines m_Symbol(pSymbol), 35f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines m_RpnExpr(pRpnExpr) 36f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines{ 37f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines} 38f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines 39f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen HinesAssignment::~Assignment() 40f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines{ 41f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines} 42f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines 43f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen HinesAssignment& Assignment::operator=(const Assignment& pAssignment) 44f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines{ 45f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines return *this; 46f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines} 47f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines 48f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hinesvoid Assignment::dump() const 49f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines{ 50f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines switch (type()) { 51f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines case DEFAULT: 52f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines break; 53f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines case HIDDEN: 54f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines mcld::outs() << "HIDDEN ( "; 55f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines break; 56f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines case PROVIDE: 57f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines mcld::outs() << "PROVIDE ( "; 58f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines break; 59f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines case PROVIDE_HIDDEN: 60f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines mcld::outs() << "PROVIDE_HIDDEN ( "; 61f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines break; 62f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines default: 63f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines break; 64f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines } 65f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines 66f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines m_Symbol.dump(); 67f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines 68f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines mcld::outs() << " = "; 69f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines 70f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines m_RpnExpr.dump(); 71f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines 72f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines if (type() != DEFAULT) 73f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines mcld::outs() << " )"; 74f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines 75f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines mcld::outs() << ";\n"; 76f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines} 77f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines 78f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hinesvoid Assignment::activate(Module& pModule) 79f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines{ 80f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines bool isLhsDot = m_Symbol.isDot(); 81f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines LinkerScript& script = pModule.getScript(); 82f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines switch (m_Level) { 83f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines case OUTSIDE_SECTIONS: 84f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines assert(!isLhsDot); 85f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines script.assignments().push_back(std::make_pair((LDSymbol*)NULL, *this)); 86f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines break; 87f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines 88f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines case OUTPUT_SECTION: { 89f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines bool hasDotInRhs = m_RpnExpr.hasDot(); 90f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines SectionMap::reference out = script.sectionMap().back(); 91f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines if (hasDotInRhs) { 92f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines if (!isLhsDot && out->dotAssignments().empty()) { 93f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines // . = ADDR ( `prev_output_sect' ) + SIZEOF ( `prev_output_sect' ) 94f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines SectionMap::iterator prev = script.sectionMap().begin() + 95f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines script.sectionMap().size() - 2; 96f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines Assignment assign(OUTPUT_SECTION, 97f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines HIDDEN, 98f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines *SymOperand::create("."), 99f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines *RpnExpr::buildHelperExpr(prev)); 100f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines out->dotAssignments().push_back(assign); 101f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines } 102f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines 103f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines if (!out->dotAssignments().empty()) { 104f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines Assignment& prevDotAssign = out->dotAssignments().back(); 105f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines // If this is the 1st explicit assignment that includes both lhs dot and 106f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines // rhs dot, then because of possible orphan sections, we are unable to 107f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines // substitute the rhs dot now. 108f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines if (!isLhsDot || prevDotAssign.type() == DEFAULT) { 109f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines for (RpnExpr::iterator it = m_RpnExpr.begin(), ie = m_RpnExpr.end(); 110f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines it != ie; ++it) { 111f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines // substitute the rhs dot with the appropriate helper expr 112f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines if ((*it)->kind() == ExprToken::OPERAND && 113f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines llvm::cast<Operand>(*it)->isDot()) 114f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines *it = &(prevDotAssign.symbol()); 115f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines } // for each expression token 116f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines } 117f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines } 118f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines } 119f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines 120f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines if (isLhsDot) { 121f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines out->dotAssignments().push_back(*this); 122f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines } else { 123f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines script.assignments().push_back(std::make_pair((LDSymbol*)NULL, *this)); 124f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines } 125f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines 126f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines break; 127f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines } 128f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines 129f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines case INPUT_SECTION: { 130f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines bool hasDotInRhs = m_RpnExpr.hasDot(); 131f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines SectionMap::Output::reference in = script.sectionMap().back()->back(); 132f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines if (hasDotInRhs) { 133f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines if (in->dotAssignments().empty()) { 134f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines // . = `frag' 135f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines RpnExpr* expr = 136f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines RpnExpr::buildHelperExpr(in->getSection()->getSectionData()->front()); 137f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines Assignment assign(INPUT_SECTION, 138f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines HIDDEN, 139f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines *SymOperand::create("."), 140f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines *expr); 141f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines in->dotAssignments().push_back(std::make_pair((Fragment*)NULL, assign)); 142f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines } 143f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines 144f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines Assignment& prevDotAssign = in->dotAssignments().back().second; 145f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines for (RpnExpr::iterator it = m_RpnExpr.begin(), ie = m_RpnExpr.end(); 146f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines it != ie; ++it) { 147f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines // substitute the rhs dot with the appropriate helper expr 148f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines if ((*it)->kind() == ExprToken::OPERAND && 149f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines llvm::cast<Operand>(*it)->isDot()) 150f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines *it = &(prevDotAssign.symbol()); 151f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines } // end of for 152f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines } 153f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines 154f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines if (isLhsDot) { 155f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines in->dotAssignments().push_back( 156f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines std::make_pair(in->getSection()->getSectionData()->front().getNextNode(), 157f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines *this)); 158f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines } else { 159f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines script.assignments().push_back(std::make_pair((LDSymbol*)NULL, *this)); 160f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines } 161f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines 162f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines break; 163f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines } 164f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines 165f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines } // end of switch 166f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines} 167f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines 168f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hinesbool Assignment::assign(RpnEvaluator& pEvaluator) 169f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines{ 170f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines uint64_t result = 0; 171f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines bool success = pEvaluator.eval(m_RpnExpr, result); 172f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines if (success) 173f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines m_Symbol.setValue(result); 174f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines return success; 175f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines} 176