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
printTree(int indent) const19 void ASTNode::printTree(int indent) const
20 {
21 printIndent(indent);
22 printf("%s\n", nodeName().c_str());
23 }
24
printIndent(int indent) const25 void ASTNode::printIndent(int indent) const
26 {
27 int i;
28 for (i=0; i<indent; ++i)
29 {
30 printf(" ");
31 }
32 }
33
setLocation(token_loc_t & first,token_loc_t & last)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
setLocation(ASTNode * first,ASTNode * last)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
ListASTNode(const ListASTNode & other)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 //!
~ListASTNode()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().
appendNode(ASTNode * node)74 void ListASTNode::appendNode(ASTNode * node)
75 {
76 if (node)
77 {
78 m_list.push_back(node);
79 updateLocation();
80 }
81 }
82
printTree(int indent) const83 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
updateLocation()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
CommandFileASTNode()129 CommandFileASTNode::CommandFileASTNode()
130 : ASTNode(), m_options(), m_constants(), m_sources(), m_sections()
131 {
132 }
133
CommandFileASTNode(const CommandFileASTNode & other)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
printTree(int indent) const143 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
resultIntSize(int_size_t a,int_size_t b)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
IntConstExprASTNode(const IntConstExprASTNode & other)205 IntConstExprASTNode::IntConstExprASTNode(const IntConstExprASTNode & other)
206 : ExprASTNode(other), m_value(other.m_value), m_size(other.m_size)
207 {
208 }
209
printTree(int indent) const210 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
VariableExprASTNode(const VariableExprASTNode & other)231 VariableExprASTNode::VariableExprASTNode(const VariableExprASTNode & other)
232 : ExprASTNode(other), m_variable()
233 {
234 m_variable = new std::string(*other.m_variable);
235 }
236
printTree(int indent) const237 void VariableExprASTNode::printTree(int indent) const
238 {
239 printIndent(indent);
240 printf("%s(%s)\n", nodeName().c_str(), m_variable->c_str());
241 }
242
reduce(EvalContext & context)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
SymbolRefExprASTNode(const SymbolRefExprASTNode & other)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
printTree(int indent) const266 void SymbolRefExprASTNode::printTree(int indent) const
267 {
268 }
269
reduce(EvalContext & context)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
NegativeExprASTNode(const NegativeExprASTNode & other)343 NegativeExprASTNode::NegativeExprASTNode(const NegativeExprASTNode & other)
344 : ExprASTNode(other), m_expr()
345 {
346 m_expr = dynamic_cast<ExprASTNode*>(other.m_expr->clone());
347 }
348
printTree(int indent) const349 void NegativeExprASTNode::printTree(int indent) const
350 {
351 ExprASTNode::printTree(indent);
352 if (m_expr) m_expr->printTree(indent + 1);
353 }
354
reduce(EvalContext & context)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
BooleanNotExprASTNode(const BooleanNotExprASTNode & other)377 BooleanNotExprASTNode::BooleanNotExprASTNode(const BooleanNotExprASTNode & other)
378 : ExprASTNode(other), m_expr()
379 {
380 m_expr = dynamic_cast<ExprASTNode*>(other.m_expr->clone());
381 }
382
printTree(int indent) const383 void BooleanNotExprASTNode::printTree(int indent) const
384 {
385 ExprASTNode::printTree(indent);
386 if (m_expr) m_expr->printTree(indent + 1);
387 }
388
reduce(EvalContext & context)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
SourceFileFunctionASTNode(const SourceFileFunctionASTNode & other)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
printTree(int indent) const418 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
reduce(EvalContext & context)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
DefinedOperatorASTNode(const DefinedOperatorASTNode & other)459 DefinedOperatorASTNode::DefinedOperatorASTNode(const DefinedOperatorASTNode & other)
460 : ExprASTNode(other), m_constantName()
461 {
462 m_constantName = new std::string(*other.m_constantName);
463 }
464
printTree(int indent) const465 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
reduce(EvalContext & context)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
SizeofOperatorASTNode(const SizeofOperatorASTNode & other)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
printTree(int indent) const493 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
reduce(EvalContext & context)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
BinaryOpExprASTNode(const BinaryOpExprASTNode & other)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
printTree(int indent) const600 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
getOperatorName() const616 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 //!
reduce(EvalContext & context)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
IntSizeExprASTNode(const IntSizeExprASTNode & other)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
printTree(int indent) const823 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
reduce(EvalContext & context)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
ExprConstASTNode(const ExprConstASTNode & other)867 ExprConstASTNode::ExprConstASTNode(const ExprConstASTNode & other)
868 : ConstASTNode(other), m_expr()
869 {
870 m_expr = dynamic_cast<ExprASTNode*>(other.m_expr->clone());
871 }
872
printTree(int indent) const873 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
StringConstASTNode(const StringConstASTNode & other)881 StringConstASTNode::StringConstASTNode(const StringConstASTNode & other)
882 : ConstASTNode(other), m_value()
883 {
884 m_value = new std::string(other.m_value);
885 }
886
printTree(int indent) const887 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
BlobConstASTNode(const BlobConstASTNode & other)895 BlobConstASTNode::BlobConstASTNode(const BlobConstASTNode & other)
896 : ConstASTNode(other), m_blob()
897 {
898 m_blob = new Blob(*other.m_blob);
899 }
900
printTree(int indent) const901 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
IVTConstASTNode(const IVTConstASTNode & other)912 IVTConstASTNode::IVTConstASTNode(const IVTConstASTNode & other)
913 : ConstASTNode(other), m_fields()
914 {
915 m_fields = dynamic_cast<ListASTNode*>(other.m_fields->clone());
916 }
917
printTree(int indent) const918 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
AssignmentASTNode(const AssignmentASTNode & other)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
printTree(int indent) const937 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
SourceDefASTNode(const SourceDefASTNode & other)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
PathSourceDefASTNode(const PathSourceDefASTNode & other)955 PathSourceDefASTNode::PathSourceDefASTNode(const PathSourceDefASTNode & other)
956 : SourceDefASTNode(other), m_path()
957 {
958 m_path = new std::string(*other.m_path);
959 }
960
printTree(int indent) const961 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
ExternSourceDefASTNode(const ExternSourceDefASTNode & other)978 ExternSourceDefASTNode::ExternSourceDefASTNode(const ExternSourceDefASTNode & other)
979 : SourceDefASTNode(other), m_expr()
980 {
981 m_expr = dynamic_cast<ExprASTNode*>(other.m_expr->clone());
982 }
983
printTree(int indent) const984 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
SectionContentsASTNode(const SectionContentsASTNode & other)1002 SectionContentsASTNode::SectionContentsASTNode(const SectionContentsASTNode & other)
1003 : ASTNode(other), m_sectionExpr()
1004 {
1005 m_sectionExpr = dynamic_cast<ExprASTNode*>(other.m_sectionExpr->clone());
1006 }
1007
printTree(int indent) const1008 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
DataSectionContentsASTNode(const DataSectionContentsASTNode & other)1019 DataSectionContentsASTNode::DataSectionContentsASTNode(const DataSectionContentsASTNode & other)
1020 : SectionContentsASTNode(other), m_contents()
1021 {
1022 m_contents = dynamic_cast<ASTNode*>(other.m_contents->clone());
1023 }
1024
printTree(int indent) const1025 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
BootableSectionContentsASTNode(const BootableSectionContentsASTNode & other)1037 BootableSectionContentsASTNode::BootableSectionContentsASTNode(const BootableSectionContentsASTNode & other)
1038 : SectionContentsASTNode(other), m_statements()
1039 {
1040 m_statements = dynamic_cast<ListASTNode*>(other.m_statements->clone());
1041 }
1042
printTree(int indent) const1043 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.
IfStatementASTNode(const IfStatementASTNode & other)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
ModeStatementASTNode(const ModeStatementASTNode & other)1071 ModeStatementASTNode::ModeStatementASTNode(const ModeStatementASTNode & other)
1072 : StatementASTNode(other), m_modeExpr()
1073 {
1074 m_modeExpr = dynamic_cast<ExprASTNode*>(other.m_modeExpr->clone());
1075 }
1076
printTree(int indent) const1077 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
MessageStatementASTNode(const MessageStatementASTNode & other)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
printTree(int indent) const1093 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
getTypeName() const1100 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
LoadStatementASTNode(const LoadStatementASTNode & other)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
printTree(int indent) const1126 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
CallStatementASTNode(const CallStatementASTNode & other)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
printTree(int indent) const1148 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
SourceASTNode(const SourceASTNode & other)1164 SourceASTNode::SourceASTNode(const SourceASTNode & other)
1165 : ASTNode(other), m_name()
1166 {
1167 m_name = new std::string(*other.m_name);
1168 }
1169
printTree(int indent) const1170 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
SectionMatchListASTNode(const SectionMatchListASTNode & other)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
printTree(int indent) const1192 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
SectionASTNode(const SectionASTNode & other)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
printTree(int indent) const1233 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
SymbolASTNode(const SymbolASTNode & other)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
printTree(int indent) const1267 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
AddressRangeASTNode(const AddressRangeASTNode & other)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
printTree(int indent) const1313 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
FromStatementASTNode(std::string * source,ListASTNode * statements)1328 FromStatementASTNode::FromStatementASTNode(std::string * source, ListASTNode * statements)
1329 : StatementASTNode(), m_source(source), m_statements(statements)
1330 {
1331 }
1332
FromStatementASTNode(const FromStatementASTNode & other)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
printTree(int indent) const1340 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