1 /* 2 * File: ElftosbAST.cpp 3 * 4 * Copyright (c) Freescale Semiconductor, Inc. All rights reserved. 5 * See included license file for license details. 6 */ 7 8 #include "ElftosbAST.h" 9 #include <stdexcept> 10 #include <math.h> 11 #include <assert.h> 12 #include "ElftosbErrors.h" 13 #include "format_string.h" 14 15 using namespace elftosb; 16 17 #pragma mark = ASTNode = 18 19 void ASTNode::printTree(int indent) const 20 { 21 printIndent(indent); 22 printf("%s\n", nodeName().c_str()); 23 } 24 25 void ASTNode::printIndent(int indent) const 26 { 27 int i; 28 for (i=0; i<indent; ++i) 29 { 30 printf(" "); 31 } 32 } 33 34 void ASTNode::setLocation(token_loc_t & first, token_loc_t & last) 35 { 36 m_location.m_firstLine = first.m_firstLine; 37 m_location.m_lastLine = last.m_lastLine; 38 } 39 40 void ASTNode::setLocation(ASTNode * first, ASTNode * last) 41 { 42 m_location.m_firstLine = first->getLocation().m_firstLine; 43 m_location.m_lastLine = last->getLocation().m_lastLine; 44 } 45 46 #pragma mark = ListASTNode = 47 48 ListASTNode::ListASTNode(const ListASTNode & other) 49 : ASTNode(other), m_list() 50 { 51 // deep copy each item of the original's list 52 const_iterator it = other.begin(); 53 for (; it != other.end(); ++it) 54 { 55 m_list.push_back((*it)->clone()); 56 } 57 } 58 59 //! Deletes child node in the list. 60 //! 61 ListASTNode::~ListASTNode() 62 { 63 iterator it = begin(); 64 for (; it != end(); it++) 65 { 66 delete *it; 67 } 68 } 69 70 //! If \a node is NULL then the list is left unmodified. 71 //! 72 //! The list node's location is automatically updated after the node is added by a call 73 //! to updateLocation(). 74 void ListASTNode::appendNode(ASTNode * node) 75 { 76 if (node) 77 { 78 m_list.push_back(node); 79 updateLocation(); 80 } 81 } 82 83 void ListASTNode::printTree(int indent) const 84 { 85 ASTNode::printTree(indent); 86 87 int n = 0; 88 const_iterator it = begin(); 89 for (; it != end(); it++, n++) 90 { 91 printIndent(indent + 1); 92 printf("%d:\n", n); 93 (*it)->printTree(indent + 2); 94 } 95 } 96 97 void ListASTNode::updateLocation() 98 { 99 token_loc_t current = { 0 }; 100 const_iterator it = begin(); 101 for (; it != end(); it++) 102 { 103 const ASTNode * node = *it; 104 const token_loc_t & loc = node->getLocation(); 105 106 // handle first node 107 if (current.m_firstLine == 0) 108 { 109 current = loc; 110 continue; 111 } 112 113 if (loc.m_firstLine < current.m_firstLine) 114 { 115 current.m_firstLine = loc.m_firstLine; 116 } 117 118 if (loc.m_lastLine > current.m_lastLine) 119 { 120 current.m_lastLine = loc.m_lastLine; 121 } 122 } 123 124 setLocation(current); 125 } 126 127 #pragma mark = CommandFileASTNode = 128 129 CommandFileASTNode::CommandFileASTNode() 130 : ASTNode(), m_options(), m_constants(), m_sources(), m_sections() 131 { 132 } 133 134 CommandFileASTNode::CommandFileASTNode(const CommandFileASTNode & other) 135 : ASTNode(other), m_options(), m_constants(), m_sources(), m_sections() 136 { 137 m_options = dynamic_cast<ListASTNode*>(other.m_options->clone()); 138 m_constants = dynamic_cast<ListASTNode*>(other.m_constants->clone()); 139 m_sources = dynamic_cast<ListASTNode*>(other.m_sources->clone()); 140 m_sections = dynamic_cast<ListASTNode*>(other.m_sections->clone()); 141 } 142 143 void CommandFileASTNode::printTree(int indent) const 144 { 145 ASTNode::printTree(indent); 146 147 printIndent(indent + 1); 148 printf("options:\n"); 149 if (m_options) m_options->printTree(indent + 2); 150 151 printIndent(indent + 1); 152 printf("constants:\n"); 153 if (m_constants) m_constants->printTree(indent + 2); 154 155 printIndent(indent + 1); 156 printf("sources:\n"); 157 if (m_sources) m_sources->printTree(indent + 2); 158 159 printIndent(indent + 1); 160 printf("sections:\n"); 161 if (m_sections) m_sections->printTree(indent + 2); 162 } 163 164 #pragma mark = ExprASTNode = 165 166 int_size_t ExprASTNode::resultIntSize(int_size_t a, int_size_t b) 167 { 168 int_size_t result; 169 switch (a) 170 { 171 case kWordSize: 172 result = kWordSize; 173 break; 174 case kHalfWordSize: 175 if (b == kWordSize) 176 { 177 result = kWordSize; 178 } 179 else 180 { 181 result = kHalfWordSize; 182 } 183 break; 184 case kByteSize: 185 if (b == kWordSize) 186 { 187 result = kWordSize; 188 } 189 else if (b == kHalfWordSize) 190 { 191 result = kHalfWordSize; 192 } 193 else 194 { 195 result = kByteSize; 196 } 197 break; 198 } 199 200 return result; 201 } 202 203 #pragma mark = IntConstExprASTNode = 204 205 IntConstExprASTNode::IntConstExprASTNode(const IntConstExprASTNode & other) 206 : ExprASTNode(other), m_value(other.m_value), m_size(other.m_size) 207 { 208 } 209 210 void IntConstExprASTNode::printTree(int indent) const 211 { 212 printIndent(indent); 213 char sizeChar='?'; 214 switch (m_size) 215 { 216 case kWordSize: 217 sizeChar = 'w'; 218 break; 219 case kHalfWordSize: 220 sizeChar = 'h'; 221 break; 222 case kByteSize: 223 sizeChar = 'b'; 224 break; 225 } 226 printf("%s(%d:%c)\n", nodeName().c_str(), m_value, sizeChar); 227 } 228 229 #pragma mark = VariableExprASTNode = 230 231 VariableExprASTNode::VariableExprASTNode(const VariableExprASTNode & other) 232 : ExprASTNode(other), m_variable() 233 { 234 m_variable = new std::string(*other.m_variable); 235 } 236 237 void VariableExprASTNode::printTree(int indent) const 238 { 239 printIndent(indent); 240 printf("%s(%s)\n", nodeName().c_str(), m_variable->c_str()); 241 } 242 243 ExprASTNode * VariableExprASTNode::reduce(EvalContext & context) 244 { 245 if (!context.isVariableDefined(*m_variable)) 246 { 247 throw std::runtime_error(format_string("line %d: undefined variable '%s'", getFirstLine(), m_variable->c_str())); 248 } 249 250 uint32_t value = context.getVariableValue(*m_variable); 251 int_size_t size = context.getVariableSize(*m_variable); 252 return new IntConstExprASTNode(value, size); 253 } 254 255 #pragma mark = SymbolRefExprASTNode = 256 257 SymbolRefExprASTNode::SymbolRefExprASTNode(const SymbolRefExprASTNode & other) 258 : ExprASTNode(other), m_symbol(NULL) 259 { 260 if (other.m_symbol) 261 { 262 m_symbol = dynamic_cast<SymbolASTNode*>(other.m_symbol->clone()); 263 } 264 } 265 266 void SymbolRefExprASTNode::printTree(int indent) const 267 { 268 } 269 270 ExprASTNode * SymbolRefExprASTNode::reduce(EvalContext & context) 271 { 272 EvalContext::SourceFileManager * manager = context.getSourceFileManager(); 273 if (!manager) 274 { 275 throw std::runtime_error("no source manager available"); 276 } 277 278 if (!m_symbol) 279 { 280 throw semantic_error("no symbol provided"); 281 } 282 283 // Get the name of the symbol 284 std::string * symbolName = m_symbol->getSymbolName(); 285 // if (!symbolName) 286 // { 287 // throw semantic_error(format_string("line %d: no symbol name provided", getFirstLine())); 288 // } 289 290 // Get the source file. 291 std::string * sourceName = m_symbol->getSource(); 292 SourceFile * sourceFile; 293 294 if (sourceName) 295 { 296 sourceFile = manager->getSourceFile(*sourceName); 297 if (!sourceFile) 298 { 299 throw semantic_error(format_string("line %d: no source file named %s", getFirstLine(), sourceName->c_str())); 300 } 301 } 302 else 303 { 304 sourceFile = manager->getDefaultSourceFile(); 305 if (!sourceFile) 306 { 307 throw semantic_error(format_string("line %d: no default source file is set", getFirstLine())); 308 } 309 } 310 311 // open the file if it hasn't already been 312 if (!sourceFile->isOpen()) 313 { 314 sourceFile->open(); 315 } 316 317 // Make sure the source file supports symbols before going any further 318 if (symbolName && !sourceFile->supportsNamedSymbols()) 319 { 320 throw semantic_error(format_string("line %d: source file %s does not support symbols", getFirstLine(), sourceFile->getPath().c_str())); 321 } 322 323 if (!symbolName && !sourceFile->hasEntryPoint()) 324 { 325 throw semantic_error(format_string("line %d: source file %s does not have an entry point", getFirstLine(), sourceFile->getPath().c_str())); 326 } 327 328 // Returns a const expr node with the symbol's value. 329 uint32_t value; 330 if (symbolName) 331 { 332 value = sourceFile->getSymbolValue(*symbolName); 333 } 334 else 335 { 336 value = sourceFile->getEntryPointAddress(); 337 } 338 return new IntConstExprASTNode(value); 339 } 340 341 #pragma mark = NegativeExprASTNode = 342 343 NegativeExprASTNode::NegativeExprASTNode(const NegativeExprASTNode & other) 344 : ExprASTNode(other), m_expr() 345 { 346 m_expr = dynamic_cast<ExprASTNode*>(other.m_expr->clone()); 347 } 348 349 void NegativeExprASTNode::printTree(int indent) const 350 { 351 ExprASTNode::printTree(indent); 352 if (m_expr) m_expr->printTree(indent + 1); 353 } 354 355 ExprASTNode * NegativeExprASTNode::reduce(EvalContext & context) 356 { 357 if (!m_expr) 358 { 359 return this; 360 } 361 362 m_expr = m_expr->reduce(context); 363 IntConstExprASTNode * intConst = dynamic_cast<IntConstExprASTNode*>(m_expr.get()); 364 if (intConst) 365 { 366 int32_t value = -(int32_t)intConst->getValue(); 367 return new IntConstExprASTNode((uint32_t)value, intConst->getSize()); 368 } 369 else 370 { 371 return this; 372 } 373 } 374 375 #pragma mark = BooleanNotExprASTNode = 376 377 BooleanNotExprASTNode::BooleanNotExprASTNode(const BooleanNotExprASTNode & other) 378 : ExprASTNode(other), m_expr() 379 { 380 m_expr = dynamic_cast<ExprASTNode*>(other.m_expr->clone()); 381 } 382 383 void BooleanNotExprASTNode::printTree(int indent) const 384 { 385 ExprASTNode::printTree(indent); 386 if (m_expr) m_expr->printTree(indent + 1); 387 } 388 389 ExprASTNode * BooleanNotExprASTNode::reduce(EvalContext & context) 390 { 391 if (!m_expr) 392 { 393 return this; 394 } 395 396 m_expr = m_expr->reduce(context); 397 IntConstExprASTNode * intConst = dynamic_cast<IntConstExprASTNode*>(m_expr.get()); 398 if (intConst) 399 { 400 int32_t value = !((int32_t)intConst->getValue()); 401 return new IntConstExprASTNode((uint32_t)value, intConst->getSize()); 402 } 403 else 404 { 405 throw semantic_error(format_string("line %d: expression did not evaluate to an integer", m_expr->getFirstLine())); 406 } 407 } 408 409 #pragma mark = SourceFileFunctionASTNode = 410 411 SourceFileFunctionASTNode::SourceFileFunctionASTNode(const SourceFileFunctionASTNode & other) 412 : ExprASTNode(other), m_functionName(), m_sourceFile() 413 { 414 m_functionName = new std::string(*other.m_functionName); 415 m_sourceFile = new std::string(*other.m_sourceFile); 416 } 417 418 void SourceFileFunctionASTNode::printTree(int indent) const 419 { 420 ExprASTNode::printTree(indent); 421 printIndent(indent+1); 422 423 // for some stupid reason the msft C++ compiler barfs on the following line if the ".get()" parts are remove, 424 // even though the first line of reduce() below has the same expression, just in parentheses. stupid compiler. 425 if (m_functionName.get() && m_sourceFile.get()) 426 { 427 printf("%s ( %s )\n", m_functionName->c_str(), m_sourceFile->c_str()); 428 } 429 } 430 431 ExprASTNode * SourceFileFunctionASTNode::reduce(EvalContext & context) 432 { 433 if (!(m_functionName && m_sourceFile)) 434 { 435 throw std::runtime_error("unset function name or source file"); 436 } 437 438 // Get source file manager from evaluation context. This will be the 439 // conversion controller itself. 440 EvalContext::SourceFileManager * mgr = context.getSourceFileManager(); 441 if (!mgr) 442 { 443 throw std::runtime_error("source file manager is not set"); 444 } 445 446 // Perform function 447 uint32_t functionResult = 0; 448 if (*m_functionName == "exists") 449 { 450 functionResult = static_cast<uint32_t>(mgr->hasSourceFile(*m_sourceFile)); 451 } 452 453 // Return function result as an expression node 454 return new IntConstExprASTNode(functionResult); 455 } 456 457 #pragma mark = DefinedOperatorASTNode = 458 459 DefinedOperatorASTNode::DefinedOperatorASTNode(const DefinedOperatorASTNode & other) 460 : ExprASTNode(other), m_constantName() 461 { 462 m_constantName = new std::string(*other.m_constantName); 463 } 464 465 void DefinedOperatorASTNode::printTree(int indent) const 466 { 467 ExprASTNode::printTree(indent); 468 printIndent(indent+1); 469 470 if (m_constantName) 471 { 472 printf("defined ( %s )\n", m_constantName->c_str()); 473 } 474 } 475 476 ExprASTNode * DefinedOperatorASTNode::reduce(EvalContext & context) 477 { 478 assert(m_constantName); 479 480 // Return function result as an expression node 481 return new IntConstExprASTNode(context.isVariableDefined(m_constantName) ? 1 : 0); 482 } 483 484 #pragma mark = SizeofOperatorASTNode = 485 486 SizeofOperatorASTNode::SizeofOperatorASTNode(const SizeofOperatorASTNode & other) 487 : ExprASTNode(other), m_constantName(), m_symbol() 488 { 489 m_constantName = new std::string(*other.m_constantName); 490 m_symbol = dynamic_cast<SymbolASTNode*>(other.m_symbol->clone()); 491 } 492 493 void SizeofOperatorASTNode::printTree(int indent) const 494 { 495 ExprASTNode::printTree(indent); 496 497 printIndent(indent+1); 498 499 if (m_constantName) 500 { 501 printf("sizeof: %s\n", m_constantName->c_str()); 502 } 503 else if (m_symbol) 504 { 505 printf("sizeof:\n"); 506 m_symbol->printTree(indent + 2); 507 } 508 } 509 510 ExprASTNode * SizeofOperatorASTNode::reduce(EvalContext & context) 511 { 512 // One or the other must be defined. 513 assert(m_constantName || m_symbol); 514 515 EvalContext::SourceFileManager * manager = context.getSourceFileManager(); 516 assert(manager); 517 518 unsigned sizeInBytes = 0; 519 SourceFile * sourceFile; 520 521 if (m_symbol) 522 { 523 // Get the symbol name. 524 std::string * symbolName = m_symbol->getSymbolName(); 525 assert(symbolName); 526 527 // Get the source file, using the default if one is not specified. 528 std::string * sourceName = m_symbol->getSource(); 529 if (sourceName) 530 { 531 sourceFile = manager->getSourceFile(*sourceName); 532 if (!sourceFile) 533 { 534 throw semantic_error(format_string("line %d: invalid source file: %s", getFirstLine(), sourceName->c_str())); 535 } 536 } 537 else 538 { 539 sourceFile = manager->getDefaultSourceFile(); 540 if (!sourceFile) 541 { 542 throw semantic_error(format_string("line %d: no default source file is set", getFirstLine())); 543 } 544 } 545 546 // Get the size of the symbol. 547 if (sourceFile->hasSymbol(*symbolName)) 548 { 549 sizeInBytes = sourceFile->getSymbolSize(*symbolName); 550 } 551 } 552 else if (m_constantName) 553 { 554 // See if the "constant" is really a constant or if it's a source name. 555 if (manager->hasSourceFile(m_constantName)) 556 { 557 sourceFile = manager->getSourceFile(m_constantName); 558 if (sourceFile) 559 { 560 sizeInBytes = sourceFile->getSize(); 561 } 562 } 563 else 564 { 565 // Regular constant. 566 if (!context.isVariableDefined(*m_constantName)) 567 { 568 throw semantic_error(format_string("line %d: cannot get size of undefined constant %s", getFirstLine(), m_constantName->c_str())); 569 } 570 571 int_size_t intSize = context.getVariableSize(*m_constantName); 572 switch (intSize) 573 { 574 case kWordSize: 575 sizeInBytes = sizeof(uint32_t); 576 break; 577 case kHalfWordSize: 578 sizeInBytes = sizeof(uint16_t); 579 break; 580 case kByteSize: 581 sizeInBytes = sizeof(uint8_t); 582 break; 583 } 584 } 585 } 586 587 // Return function result as an expression node 588 return new IntConstExprASTNode(sizeInBytes); 589 } 590 591 #pragma mark = BinaryOpExprASTNode = 592 593 BinaryOpExprASTNode::BinaryOpExprASTNode(const BinaryOpExprASTNode & other) 594 : ExprASTNode(other), m_left(), m_op(other.m_op), m_right() 595 { 596 m_left = dynamic_cast<ExprASTNode*>(other.m_left->clone()); 597 m_right = dynamic_cast<ExprASTNode*>(other.m_right->clone()); 598 } 599 600 void BinaryOpExprASTNode::printTree(int indent) const 601 { 602 ExprASTNode::printTree(indent); 603 604 printIndent(indent + 1); 605 printf("left:\n"); 606 if (m_left) m_left->printTree(indent + 2); 607 608 printIndent(indent + 1); 609 printf("op: %s\n", getOperatorName().c_str()); 610 611 printIndent(indent + 1); 612 printf("right:\n"); 613 if (m_right) m_right->printTree(indent + 2); 614 } 615 616 std::string BinaryOpExprASTNode::getOperatorName() const 617 { 618 switch (m_op) 619 { 620 case kAdd: 621 return "+"; 622 case kSubtract: 623 return "-"; 624 case kMultiply: 625 return "*"; 626 case kDivide: 627 return "/"; 628 case kModulus: 629 return "%"; 630 case kPower: 631 return "**"; 632 case kBitwiseAnd: 633 return "&"; 634 case kBitwiseOr: 635 return "|"; 636 case kBitwiseXor: 637 return "^"; 638 case kShiftLeft: 639 return "<<"; 640 case kShiftRight: 641 return ">>"; 642 case kLessThan: 643 return "<"; 644 case kGreaterThan: 645 return ">"; 646 case kLessThanEqual: 647 return "<="; 648 case kGreaterThanEqual: 649 return ">"; 650 case kEqual: 651 return "=="; 652 case kNotEqual: 653 return "!="; 654 case kBooleanAnd: 655 return "&&"; 656 case kBooleanOr: 657 return "||"; 658 } 659 660 return "???"; 661 } 662 663 //! \todo Fix power operator under windows!!! 664 //! 665 ExprASTNode * BinaryOpExprASTNode::reduce(EvalContext & context) 666 { 667 if (!m_left || !m_right) 668 { 669 return this; 670 } 671 672 IntConstExprASTNode * leftIntConst = NULL; 673 IntConstExprASTNode * rightIntConst = NULL; 674 uint32_t leftValue; 675 uint32_t rightValue; 676 uint32_t result = 0; 677 678 // Always reduce the left hand side. 679 m_left = m_left->reduce(context); 680 leftIntConst = dynamic_cast<IntConstExprASTNode*>(m_left.get()); 681 if (!leftIntConst) 682 { 683 throw semantic_error(format_string("left hand side of %s operator failed to evaluate to an integer", getOperatorName().c_str())); 684 } 685 leftValue = leftIntConst->getValue(); 686 687 // Boolean && and || operators are handled separately so that we can perform 688 // short-circuit evaluation. 689 if (m_op == kBooleanAnd || m_op == kBooleanOr) 690 { 691 // Reduce right hand side only if required to evaluate the boolean operator. 692 if ((m_op == kBooleanAnd && leftValue != 0) || (m_op == kBooleanOr && leftValue == 0)) 693 { 694 m_right = m_right->reduce(context); 695 rightIntConst = dynamic_cast<IntConstExprASTNode*>(m_right.get()); 696 if (!rightIntConst) 697 { 698 throw semantic_error(format_string("right hand side of %s operator failed to evaluate to an integer", getOperatorName().c_str())); 699 } 700 rightValue = rightIntConst->getValue(); 701 702 // Perform the boolean operation. 703 switch (m_op) 704 { 705 case kBooleanAnd: 706 result = leftValue && rightValue; 707 break; 708 709 case kBooleanOr: 710 result = leftValue && rightValue; 711 break; 712 } 713 } 714 else if (m_op == kBooleanAnd) 715 { 716 // The left hand side is false, so the && operator's result must be false 717 // without regard to the right hand side. 718 result = 0; 719 } 720 else if (m_op == kBooleanOr) 721 { 722 // The left hand value is true so the || result is automatically true. 723 result = 1; 724 } 725 } 726 else 727 { 728 // Reduce right hand side always for most operators. 729 m_right = m_right->reduce(context); 730 rightIntConst = dynamic_cast<IntConstExprASTNode*>(m_right.get()); 731 if (!rightIntConst) 732 { 733 throw semantic_error(format_string("right hand side of %s operator failed to evaluate to an integer", getOperatorName().c_str())); 734 } 735 rightValue = rightIntConst->getValue(); 736 737 switch (m_op) 738 { 739 case kAdd: 740 result = leftValue + rightValue; 741 break; 742 case kSubtract: 743 result = leftValue - rightValue; 744 break; 745 case kMultiply: 746 result = leftValue * rightValue; 747 break; 748 case kDivide: 749 result = leftValue / rightValue; 750 break; 751 case kModulus: 752 result = leftValue % rightValue; 753 break; 754 case kPower: 755 #ifdef WIN32 756 result = 0; 757 #else 758 result = lroundf(powf(float(leftValue), float(rightValue))); 759 #endif 760 break; 761 case kBitwiseAnd: 762 result = leftValue & rightValue; 763 break; 764 case kBitwiseOr: 765 result = leftValue | rightValue; 766 break; 767 case kBitwiseXor: 768 result = leftValue ^ rightValue; 769 break; 770 case kShiftLeft: 771 result = leftValue << rightValue; 772 break; 773 case kShiftRight: 774 result = leftValue >> rightValue; 775 break; 776 case kLessThan: 777 result = leftValue < rightValue; 778 break; 779 case kGreaterThan: 780 result = leftValue > rightValue; 781 break; 782 case kLessThanEqual: 783 result = leftValue <= rightValue; 784 break; 785 case kGreaterThanEqual: 786 result = leftValue >= rightValue; 787 break; 788 case kEqual: 789 result = leftValue == rightValue; 790 break; 791 case kNotEqual: 792 result = leftValue != rightValue; 793 break; 794 } 795 } 796 797 // Create the result value. 798 int_size_t resultSize; 799 if (leftIntConst && rightIntConst) 800 { 801 resultSize = resultIntSize(leftIntConst->getSize(), rightIntConst->getSize()); 802 } 803 else if (leftIntConst) 804 { 805 resultSize = leftIntConst->getSize(); 806 } 807 else 808 { 809 // This shouldn't really be possible, but just in case. 810 resultSize = kWordSize; 811 } 812 return new IntConstExprASTNode(result, resultSize); 813 } 814 815 #pragma mark = IntSizeExprASTNode = 816 817 IntSizeExprASTNode::IntSizeExprASTNode(const IntSizeExprASTNode & other) 818 : ExprASTNode(other), m_expr(), m_size(other.m_size) 819 { 820 m_expr = dynamic_cast<ExprASTNode*>(other.m_expr->clone()); 821 } 822 823 void IntSizeExprASTNode::printTree(int indent) const 824 { 825 ExprASTNode::printTree(indent); 826 827 char sizeChar='?'; 828 switch (m_size) 829 { 830 case kWordSize: 831 sizeChar = 'w'; 832 break; 833 case kHalfWordSize: 834 sizeChar = 'h'; 835 break; 836 case kByteSize: 837 sizeChar = 'b'; 838 break; 839 } 840 printIndent(indent + 1); 841 printf("size: %c\n", sizeChar); 842 843 printIndent(indent + 1); 844 printf("expr:\n"); 845 if (m_expr) m_expr->printTree(indent + 2); 846 } 847 848 ExprASTNode * IntSizeExprASTNode::reduce(EvalContext & context) 849 { 850 if (!m_expr) 851 { 852 return this; 853 } 854 855 m_expr = m_expr->reduce(context); 856 IntConstExprASTNode * intConst = dynamic_cast<IntConstExprASTNode*>(m_expr.get()); 857 if (!intConst) 858 { 859 return this; 860 } 861 862 return new IntConstExprASTNode(intConst->getValue(), m_size); 863 } 864 865 #pragma mark = ExprConstASTNode = 866 867 ExprConstASTNode::ExprConstASTNode(const ExprConstASTNode & other) 868 : ConstASTNode(other), m_expr() 869 { 870 m_expr = dynamic_cast<ExprASTNode*>(other.m_expr->clone()); 871 } 872 873 void ExprConstASTNode::printTree(int indent) const 874 { 875 ConstASTNode::printTree(indent); 876 if (m_expr) m_expr->printTree(indent + 1); 877 } 878 879 #pragma mark = StringConstASTNode = 880 881 StringConstASTNode::StringConstASTNode(const StringConstASTNode & other) 882 : ConstASTNode(other), m_value() 883 { 884 m_value = new std::string(other.m_value); 885 } 886 887 void StringConstASTNode::printTree(int indent) const 888 { 889 printIndent(indent); 890 printf("%s(%s)\n", nodeName().c_str(), m_value->c_str()); 891 } 892 893 #pragma mark = BlobConstASTNode = 894 895 BlobConstASTNode::BlobConstASTNode(const BlobConstASTNode & other) 896 : ConstASTNode(other), m_blob() 897 { 898 m_blob = new Blob(*other.m_blob); 899 } 900 901 void BlobConstASTNode::printTree(int indent) const 902 { 903 printIndent(indent); 904 905 const uint8_t * dataPtr = m_blob->getData(); 906 unsigned dataLen = m_blob->getLength(); 907 printf("%s(%p:%d)\n", nodeName().c_str(), dataPtr, dataLen); 908 } 909 910 #pragma mark = IVTConstASTNode = 911 912 IVTConstASTNode::IVTConstASTNode(const IVTConstASTNode & other) 913 : ConstASTNode(other), m_fields() 914 { 915 m_fields = dynamic_cast<ListASTNode*>(other.m_fields->clone()); 916 } 917 918 void IVTConstASTNode::printTree(int indent) const 919 { 920 printIndent(indent); 921 printf("%s:\n", nodeName().c_str()); 922 if (m_fields) 923 { 924 m_fields->printTree(indent + 1); 925 } 926 } 927 928 #pragma mark = AssignmentASTNode = 929 930 AssignmentASTNode::AssignmentASTNode(const AssignmentASTNode & other) 931 : ASTNode(other), m_ident(), m_value() 932 { 933 m_ident = new std::string(*other.m_ident); 934 m_value = dynamic_cast<ConstASTNode*>(other.m_value->clone()); 935 } 936 937 void AssignmentASTNode::printTree(int indent) const 938 { 939 printIndent(indent); 940 printf("%s(%s)\n", nodeName().c_str(), m_ident->c_str()); 941 942 if (m_value) m_value->printTree(indent + 1); 943 } 944 945 #pragma mark = SourceDefASTNode = 946 947 SourceDefASTNode::SourceDefASTNode(const SourceDefASTNode & other) 948 : ASTNode(other), m_name() 949 { 950 m_name = new std::string(*other.m_name); 951 } 952 953 #pragma mark = PathSourceDefASTNode = 954 955 PathSourceDefASTNode::PathSourceDefASTNode(const PathSourceDefASTNode & other) 956 : SourceDefASTNode(other), m_path() 957 { 958 m_path = new std::string(*other.m_path); 959 } 960 961 void PathSourceDefASTNode::printTree(int indent) const 962 { 963 SourceDefASTNode::printTree(indent); 964 965 printIndent(indent+1); 966 printf("path: %s\n", m_path->c_str()); 967 968 printIndent(indent+1); 969 printf("attributes:\n"); 970 if (m_attributes) 971 { 972 m_attributes->printTree(indent+2); 973 } 974 } 975 976 #pragma mark = ExternSourceDefASTNode = 977 978 ExternSourceDefASTNode::ExternSourceDefASTNode(const ExternSourceDefASTNode & other) 979 : SourceDefASTNode(other), m_expr() 980 { 981 m_expr = dynamic_cast<ExprASTNode*>(other.m_expr->clone()); 982 } 983 984 void ExternSourceDefASTNode::printTree(int indent) const 985 { 986 SourceDefASTNode::printTree(indent); 987 988 printIndent(indent+1); 989 printf("expr:\n"); 990 if (m_expr) m_expr->printTree(indent + 2); 991 992 printIndent(indent+1); 993 printf("attributes:\n"); 994 if (m_attributes) 995 { 996 m_attributes->printTree(indent+2); 997 } 998 } 999 1000 #pragma mark = SectionContentsASTNode = 1001 1002 SectionContentsASTNode::SectionContentsASTNode(const SectionContentsASTNode & other) 1003 : ASTNode(other), m_sectionExpr() 1004 { 1005 m_sectionExpr = dynamic_cast<ExprASTNode*>(other.m_sectionExpr->clone()); 1006 } 1007 1008 void SectionContentsASTNode::printTree(int indent) const 1009 { 1010 ASTNode::printTree(indent); 1011 1012 printIndent(indent + 1); 1013 printf("section#:\n"); 1014 if (m_sectionExpr) m_sectionExpr->printTree(indent + 2); 1015 } 1016 1017 #pragma mark = DataSectionContentsASTNode = 1018 1019 DataSectionContentsASTNode::DataSectionContentsASTNode(const DataSectionContentsASTNode & other) 1020 : SectionContentsASTNode(other), m_contents() 1021 { 1022 m_contents = dynamic_cast<ASTNode*>(other.m_contents->clone()); 1023 } 1024 1025 void DataSectionContentsASTNode::printTree(int indent) const 1026 { 1027 SectionContentsASTNode::printTree(indent); 1028 1029 if (m_contents) 1030 { 1031 m_contents->printTree(indent + 1); 1032 } 1033 } 1034 1035 #pragma mark = BootableSectionContentsASTNode = 1036 1037 BootableSectionContentsASTNode::BootableSectionContentsASTNode(const BootableSectionContentsASTNode & other) 1038 : SectionContentsASTNode(other), m_statements() 1039 { 1040 m_statements = dynamic_cast<ListASTNode*>(other.m_statements->clone()); 1041 } 1042 1043 void BootableSectionContentsASTNode::printTree(int indent) const 1044 { 1045 SectionContentsASTNode::printTree(indent); 1046 1047 printIndent(indent + 1); 1048 printf("statements:\n"); 1049 if (m_statements) m_statements->printTree(indent + 2); 1050 } 1051 1052 #pragma mark = IfStatementASTNode = 1053 1054 //! \warning Be careful; this method could enter an infinite loop if m_nextIf feeds 1055 //! back onto itself. m_nextIf must be NULL at some point down the next if list. 1056 IfStatementASTNode::IfStatementASTNode(const IfStatementASTNode & other) 1057 : StatementASTNode(), 1058 m_conditionExpr(), 1059 m_ifStatements(), 1060 m_nextIf(), 1061 m_elseStatements() 1062 { 1063 m_conditionExpr = dynamic_cast<ExprASTNode*>(other.m_conditionExpr->clone()); 1064 m_ifStatements = dynamic_cast<ListASTNode*>(other.m_ifStatements->clone()); 1065 m_nextIf = dynamic_cast<IfStatementASTNode*>(other.m_nextIf->clone()); 1066 m_elseStatements = dynamic_cast<ListASTNode*>(other.m_elseStatements->clone()); 1067 } 1068 1069 #pragma mark = ModeStatementASTNode = 1070 1071 ModeStatementASTNode::ModeStatementASTNode(const ModeStatementASTNode & other) 1072 : StatementASTNode(other), m_modeExpr() 1073 { 1074 m_modeExpr = dynamic_cast<ExprASTNode*>(other.m_modeExpr->clone()); 1075 } 1076 1077 void ModeStatementASTNode::printTree(int indent) const 1078 { 1079 StatementASTNode::printTree(indent); 1080 printIndent(indent + 1); 1081 printf("mode:\n"); 1082 if (m_modeExpr) m_modeExpr->printTree(indent + 2); 1083 } 1084 1085 #pragma mark = MessageStatementASTNode = 1086 1087 MessageStatementASTNode::MessageStatementASTNode(const MessageStatementASTNode & other) 1088 : StatementASTNode(other), m_type(other.m_type), m_message() 1089 { 1090 m_message = new std::string(*other.m_message); 1091 } 1092 1093 void MessageStatementASTNode::printTree(int indent) const 1094 { 1095 StatementASTNode::printTree(indent); 1096 printIndent(indent + 1); 1097 printf("%s: %s\n", getTypeName(), m_message->c_str()); 1098 } 1099 1100 const char * MessageStatementASTNode::getTypeName() const 1101 { 1102 switch (m_type) 1103 { 1104 case kInfo: 1105 return "info"; 1106 1107 case kWarning: 1108 return "warning"; 1109 1110 case kError: 1111 return "error"; 1112 } 1113 1114 return "unknown"; 1115 } 1116 1117 #pragma mark = LoadStatementASTNode = 1118 1119 LoadStatementASTNode::LoadStatementASTNode(const LoadStatementASTNode & other) 1120 : StatementASTNode(other), m_data(), m_target(), m_isDCDLoad(other.m_isDCDLoad) 1121 { 1122 m_data = other.m_data->clone(); 1123 m_target = other.m_target->clone(); 1124 } 1125 1126 void LoadStatementASTNode::printTree(int indent) const 1127 { 1128 StatementASTNode::printTree(indent); 1129 1130 printIndent(indent + 1); 1131 printf("data:\n"); 1132 if (m_data) m_data->printTree(indent + 2); 1133 1134 printIndent(indent + 1); 1135 printf("target:\n"); 1136 if (m_target) m_target->printTree(indent + 2); 1137 } 1138 1139 #pragma mark = CallStatementASTNode = 1140 1141 CallStatementASTNode::CallStatementASTNode(const CallStatementASTNode & other) 1142 : StatementASTNode(other), m_type(other.m_type), m_target(), m_arg() 1143 { 1144 m_target = other.m_target->clone(); 1145 m_arg = other.m_arg->clone(); 1146 } 1147 1148 void CallStatementASTNode::printTree(int indent) const 1149 { 1150 printIndent(indent); 1151 printf("%s(%s)%s\n", nodeName().c_str(), (m_type == kCallType ? "call" : "jump"), (m_isHAB ? "/HAB" : "")); 1152 1153 printIndent(indent + 1); 1154 printf("target:\n"); 1155 if (m_target) m_target->printTree(indent + 2); 1156 1157 printIndent(indent + 1); 1158 printf("arg:\n"); 1159 if (m_arg) m_arg->printTree(indent + 2); 1160 } 1161 1162 #pragma mark = SourceASTNode = 1163 1164 SourceASTNode::SourceASTNode(const SourceASTNode & other) 1165 : ASTNode(other), m_name() 1166 { 1167 m_name = new std::string(*other.m_name); 1168 } 1169 1170 void SourceASTNode::printTree(int indent) const 1171 { 1172 printIndent(indent); 1173 printf("%s(%s)\n", nodeName().c_str(), m_name->c_str()); 1174 } 1175 1176 #pragma mark = SectionMatchListASTNode = 1177 1178 SectionMatchListASTNode::SectionMatchListASTNode(const SectionMatchListASTNode & other) 1179 : ASTNode(other), m_sections(), m_source() 1180 { 1181 if (other.m_sections) 1182 { 1183 m_sections = dynamic_cast<ListASTNode *>(other.m_sections->clone()); 1184 } 1185 1186 if (other.m_source) 1187 { 1188 m_source = new std::string(*other.m_source); 1189 } 1190 } 1191 1192 void SectionMatchListASTNode::printTree(int indent) const 1193 { 1194 ASTNode::printTree(indent); 1195 1196 printIndent(indent+1); 1197 printf("sections:\n"); 1198 if (m_sections) 1199 { 1200 m_sections->printTree(indent+2); 1201 } 1202 1203 printIndent(indent+1); 1204 printf("source: "); 1205 if (m_source) 1206 { 1207 printf("%s\n", m_source->c_str()); 1208 } 1209 else 1210 { 1211 printf("\n"); 1212 } 1213 } 1214 1215 #pragma mark = SectionASTNode = 1216 1217 SectionASTNode::SectionASTNode(const SectionASTNode & other) 1218 : ASTNode(other), m_name(), m_source() 1219 { 1220 m_action = other.m_action; 1221 1222 if (other.m_name) 1223 { 1224 m_name = new std::string(*other.m_name); 1225 } 1226 1227 if (other.m_source) 1228 { 1229 m_source = new std::string(*other.m_source); 1230 } 1231 } 1232 1233 void SectionASTNode::printTree(int indent) const 1234 { 1235 printIndent(indent); 1236 1237 const char * actionName; 1238 switch (m_action) 1239 { 1240 case kInclude: 1241 actionName = "include"; 1242 break; 1243 case kExclude: 1244 actionName = "exclude"; 1245 break; 1246 } 1247 1248 if (m_source) 1249 { 1250 printf("%s(%s:%s:%s)\n", nodeName().c_str(), actionName, m_name->c_str(), m_source->c_str()); 1251 } 1252 else 1253 { 1254 printf("%s(%s:%s)\n", nodeName().c_str(), actionName, m_name->c_str()); 1255 } 1256 } 1257 1258 #pragma mark = SymbolASTNode = 1259 1260 SymbolASTNode::SymbolASTNode(const SymbolASTNode & other) 1261 : ASTNode(other), m_symbol(), m_source() 1262 { 1263 m_symbol = new std::string(*other.m_symbol); 1264 m_source = new std::string(*other.m_source); 1265 } 1266 1267 void SymbolASTNode::printTree(int indent) const 1268 { 1269 printIndent(indent); 1270 1271 const char * symbol = NULL; 1272 if (m_symbol) 1273 { 1274 symbol = m_symbol->c_str(); 1275 } 1276 1277 const char * source = NULL; 1278 if (m_source) 1279 { 1280 source = m_source->c_str(); 1281 } 1282 1283 printf("%s(", nodeName().c_str()); 1284 if (source) 1285 { 1286 printf("%s", source); 1287 } 1288 else 1289 { 1290 printf("."); 1291 } 1292 printf(":"); 1293 if (symbol) 1294 { 1295 printf("%s", symbol); 1296 } 1297 else 1298 { 1299 printf("."); 1300 } 1301 printf(")\n"); 1302 } 1303 1304 #pragma mark = AddressRangeASTNode = 1305 1306 AddressRangeASTNode::AddressRangeASTNode(const AddressRangeASTNode & other) 1307 : ASTNode(other), m_begin(), m_end() 1308 { 1309 m_begin = other.m_begin->clone(); 1310 m_end = other.m_end->clone(); 1311 } 1312 1313 void AddressRangeASTNode::printTree(int indent) const 1314 { 1315 ASTNode::printTree(indent); 1316 1317 printIndent(indent + 1); 1318 printf("begin:\n"); 1319 if (m_begin) m_begin->printTree(indent + 2); 1320 1321 printIndent(indent + 1); 1322 printf("end:\n"); 1323 if (m_end) m_end->printTree(indent + 2); 1324 } 1325 1326 #pragma mark = FromStatementASTNode = 1327 1328 FromStatementASTNode::FromStatementASTNode(std::string * source, ListASTNode * statements) 1329 : StatementASTNode(), m_source(source), m_statements(statements) 1330 { 1331 } 1332 1333 FromStatementASTNode::FromStatementASTNode(const FromStatementASTNode & other) 1334 : StatementASTNode(), m_source(), m_statements() 1335 { 1336 m_source = new std::string(*other.m_source); 1337 m_statements = dynamic_cast<ListASTNode*>(other.m_statements->clone()); 1338 } 1339 1340 void FromStatementASTNode::printTree(int indent) const 1341 { 1342 ASTNode::printTree(indent); 1343 1344 printIndent(indent + 1); 1345 printf("source: "); 1346 if (m_source) printf("%s\n", m_source->c_str()); 1347 1348 printIndent(indent + 1); 1349 printf("statements:\n"); 1350 if (m_statements) m_statements->printTree(indent + 2); 1351 } 1352 1353