1 // expression.cc -- expressions in linker scripts for gold 2 3 // Copyright (C) 2006-2014 Free Software Foundation, Inc. 4 // Written by Ian Lance Taylor <iant (at) google.com>. 5 6 // This file is part of gold. 7 8 // This program is free software; you can redistribute it and/or modify 9 // it under the terms of the GNU General Public License as published by 10 // the Free Software Foundation; either version 3 of the License, or 11 // (at your option) any later version. 12 13 // This program is distributed in the hope that it will be useful, 14 // but WITHOUT ANY WARRANTY; without even the implied warranty of 15 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 // GNU General Public License for more details. 17 18 // You should have received a copy of the GNU General Public License 19 // along with this program; if not, write to the Free Software 20 // Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, 21 // MA 02110-1301, USA. 22 23 #include "gold.h" 24 25 #include <string> 26 27 #include "elfcpp.h" 28 #include "parameters.h" 29 #include "symtab.h" 30 #include "layout.h" 31 #include "output.h" 32 #include "script.h" 33 #include "script-c.h" 34 35 namespace gold 36 { 37 38 // This file holds the code which handles linker expressions. 39 40 // The dot symbol, which linker scripts refer to simply as ".", 41 // requires special treatment. The dot symbol is set several times, 42 // section addresses will refer to it, output sections will change it, 43 // and it can be set based on the value of other symbols. We simplify 44 // the handling by prohibiting setting the dot symbol to the value of 45 // a non-absolute symbol. 46 47 // When evaluating the value of an expression, we pass in a pointer to 48 // this struct, so that the expression evaluation can find the 49 // information it needs. 50 51 struct Expression::Expression_eval_info 52 { 53 // The symbol table. 54 const Symbol_table* symtab; 55 // The layout--we use this to get section information. 56 const Layout* layout; 57 // Whether to check assertions. 58 bool check_assertions; 59 // Whether expressions can refer to the dot symbol. The dot symbol 60 // is only available within a SECTIONS clause. 61 bool is_dot_available; 62 // The current value of the dot symbol. 63 uint64_t dot_value; 64 // The section in which the dot symbol is defined; this is NULL if 65 // it is absolute. 66 Output_section* dot_section; 67 // Points to where the section of the result should be stored. 68 Output_section** result_section_pointer; 69 // Pointer to where the alignment of the result should be stored. 70 uint64_t* result_alignment_pointer; 71 // Pointer to where the type of the symbol on the RHS should be stored. 72 elfcpp::STT* type_pointer; 73 // Pointer to where the visibility of the symbol on the RHS should be stored. 74 elfcpp::STV* vis_pointer; 75 // Pointer to where the rest of the symbol's st_other field should be stored. 76 unsigned char* nonvis_pointer; 77 }; 78 79 // Evaluate an expression. 80 81 uint64_t 82 Expression::eval(const Symbol_table* symtab, const Layout* layout, 83 bool check_assertions) 84 { 85 return this->eval_maybe_dot(symtab, layout, check_assertions, false, 0, 86 NULL, NULL, NULL, NULL, NULL, NULL, false); 87 } 88 89 // Evaluate an expression which may refer to the dot symbol. 90 91 uint64_t 92 Expression::eval_with_dot(const Symbol_table* symtab, const Layout* layout, 93 bool check_assertions, uint64_t dot_value, 94 Output_section* dot_section, 95 Output_section** result_section_pointer, 96 uint64_t* result_alignment_pointer, 97 bool is_section_dot_assignment) 98 { 99 return this->eval_maybe_dot(symtab, layout, check_assertions, true, 100 dot_value, dot_section, result_section_pointer, 101 result_alignment_pointer, NULL, NULL, NULL, 102 is_section_dot_assignment); 103 } 104 105 // Evaluate an expression which may or may not refer to the dot 106 // symbol. 107 108 uint64_t 109 Expression::eval_maybe_dot(const Symbol_table* symtab, const Layout* layout, 110 bool check_assertions, bool is_dot_available, 111 uint64_t dot_value, Output_section* dot_section, 112 Output_section** result_section_pointer, 113 uint64_t* result_alignment_pointer, 114 elfcpp::STT* type_pointer, 115 elfcpp::STV* vis_pointer, 116 unsigned char* nonvis_pointer, 117 bool is_section_dot_assignment) 118 { 119 Expression_eval_info eei; 120 eei.symtab = symtab; 121 eei.layout = layout; 122 eei.check_assertions = check_assertions; 123 eei.is_dot_available = is_dot_available; 124 eei.dot_value = dot_value; 125 eei.dot_section = dot_section; 126 127 // We assume the value is absolute, and only set this to a section 128 // if we find a section-relative reference. 129 if (result_section_pointer != NULL) 130 *result_section_pointer = NULL; 131 eei.result_section_pointer = result_section_pointer; 132 133 // For symbol=symbol assignments, we need to track the type, visibility, 134 // and remaining st_other bits. 135 eei.type_pointer = type_pointer; 136 eei.vis_pointer = vis_pointer; 137 eei.nonvis_pointer = nonvis_pointer; 138 139 eei.result_alignment_pointer = result_alignment_pointer; 140 141 uint64_t val = this->value(&eei); 142 143 // If this is an assignment to dot within a section, and the value 144 // is absolute, treat it as a section-relative offset. 145 if (is_section_dot_assignment && *result_section_pointer == NULL) 146 { 147 gold_assert(dot_section != NULL); 148 val += dot_section->address(); 149 *result_section_pointer = dot_section; 150 } 151 return val; 152 } 153 154 // A number. 155 156 class Integer_expression : public Expression 157 { 158 public: 159 Integer_expression(uint64_t val) 160 : val_(val) 161 { } 162 163 uint64_t 164 value(const Expression_eval_info*) 165 { return this->val_; } 166 167 void 168 print(FILE* f) const 169 { fprintf(f, "0x%llx", static_cast<unsigned long long>(this->val_)); } 170 171 private: 172 uint64_t val_; 173 }; 174 175 extern "C" Expression* 176 script_exp_integer(uint64_t val) 177 { 178 return new Integer_expression(val); 179 } 180 181 // An expression whose value is the value of a symbol. 182 183 class Symbol_expression : public Expression 184 { 185 public: 186 Symbol_expression(const char* name, size_t length) 187 : name_(name, length) 188 { } 189 190 uint64_t 191 value(const Expression_eval_info*); 192 193 void 194 print(FILE* f) const 195 { fprintf(f, "%s", this->name_.c_str()); } 196 197 private: 198 std::string name_; 199 }; 200 201 uint64_t 202 Symbol_expression::value(const Expression_eval_info* eei) 203 { 204 Symbol* sym = eei->symtab->lookup(this->name_.c_str()); 205 if (sym == NULL || !sym->is_defined()) 206 { 207 gold_error(_("undefined symbol '%s' referenced in expression"), 208 this->name_.c_str()); 209 return 0; 210 } 211 212 if (eei->result_section_pointer != NULL) 213 *eei->result_section_pointer = sym->output_section(); 214 if (eei->type_pointer != NULL) 215 *eei->type_pointer = sym->type(); 216 if (eei->vis_pointer != NULL) 217 *eei->vis_pointer = sym->visibility(); 218 if (eei->nonvis_pointer != NULL) 219 *eei->nonvis_pointer = sym->nonvis(); 220 221 if (parameters->target().get_size() == 32) 222 return eei->symtab->get_sized_symbol<32>(sym)->value(); 223 else if (parameters->target().get_size() == 64) 224 return eei->symtab->get_sized_symbol<64>(sym)->value(); 225 else 226 gold_unreachable(); 227 } 228 229 // An expression whose value is the value of the special symbol ".". 230 // This is only valid within a SECTIONS clause. 231 232 class Dot_expression : public Expression 233 { 234 public: 235 Dot_expression() 236 { } 237 238 uint64_t 239 value(const Expression_eval_info*); 240 241 void 242 print(FILE* f) const 243 { fprintf(f, "."); } 244 }; 245 246 uint64_t 247 Dot_expression::value(const Expression_eval_info* eei) 248 { 249 if (!eei->is_dot_available) 250 { 251 gold_error(_("invalid reference to dot symbol outside of " 252 "SECTIONS clause")); 253 return 0; 254 } 255 if (eei->result_section_pointer != NULL) 256 *eei->result_section_pointer = eei->dot_section; 257 return eei->dot_value; 258 } 259 260 // A string. This is either the name of a symbol, or ".". 261 262 extern "C" Expression* 263 script_exp_string(const char* name, size_t length) 264 { 265 if (length == 1 && name[0] == '.') 266 return new Dot_expression(); 267 else 268 return new Symbol_expression(name, length); 269 } 270 271 // A unary expression. 272 273 class Unary_expression : public Expression 274 { 275 public: 276 Unary_expression(Expression* arg) 277 : arg_(arg) 278 { } 279 280 ~Unary_expression() 281 { delete this->arg_; } 282 283 protected: 284 uint64_t 285 arg_value(const Expression_eval_info* eei, 286 Output_section** arg_section_pointer) const 287 { 288 return this->arg_->eval_maybe_dot(eei->symtab, eei->layout, 289 eei->check_assertions, 290 eei->is_dot_available, 291 eei->dot_value, 292 eei->dot_section, 293 arg_section_pointer, 294 eei->result_alignment_pointer, 295 NULL, 296 NULL, 297 NULL, 298 false); 299 } 300 301 void 302 arg_print(FILE* f) const 303 { this->arg_->print(f); } 304 305 private: 306 Expression* arg_; 307 }; 308 309 // Handle unary operators. We use a preprocessor macro as a hack to 310 // capture the C operator. 311 312 #define UNARY_EXPRESSION(NAME, OPERATOR) \ 313 class Unary_ ## NAME : public Unary_expression \ 314 { \ 315 public: \ 316 Unary_ ## NAME(Expression* arg) \ 317 : Unary_expression(arg) \ 318 { } \ 319 \ 320 uint64_t \ 321 value(const Expression_eval_info* eei) \ 322 { \ 323 Output_section* arg_section; \ 324 uint64_t ret = OPERATOR this->arg_value(eei, &arg_section); \ 325 if (arg_section != NULL && parameters->options().relocatable()) \ 326 gold_warning(_("unary " #NAME " applied to section " \ 327 "relative value")); \ 328 return ret; \ 329 } \ 330 \ 331 void \ 332 print(FILE* f) const \ 333 { \ 334 fprintf(f, "(%s ", #OPERATOR); \ 335 this->arg_print(f); \ 336 fprintf(f, ")"); \ 337 } \ 338 }; \ 339 \ 340 extern "C" Expression* \ 341 script_exp_unary_ ## NAME(Expression* arg) \ 342 { \ 343 return new Unary_ ## NAME(arg); \ 344 } 345 346 UNARY_EXPRESSION(minus, -) 347 UNARY_EXPRESSION(logical_not, !) 348 UNARY_EXPRESSION(bitwise_not, ~) 349 350 // A binary expression. 351 352 class Binary_expression : public Expression 353 { 354 public: 355 Binary_expression(Expression* left, Expression* right) 356 : left_(left), right_(right) 357 { } 358 359 ~Binary_expression() 360 { 361 delete this->left_; 362 delete this->right_; 363 } 364 365 protected: 366 uint64_t 367 left_value(const Expression_eval_info* eei, 368 Output_section** section_pointer, 369 uint64_t* alignment_pointer) const 370 { 371 return this->left_->eval_maybe_dot(eei->symtab, eei->layout, 372 eei->check_assertions, 373 eei->is_dot_available, 374 eei->dot_value, 375 eei->dot_section, 376 section_pointer, 377 alignment_pointer, 378 NULL, 379 NULL, 380 NULL, 381 false); 382 } 383 384 uint64_t 385 right_value(const Expression_eval_info* eei, 386 Output_section** section_pointer, 387 uint64_t* alignment_pointer) const 388 { 389 return this->right_->eval_maybe_dot(eei->symtab, eei->layout, 390 eei->check_assertions, 391 eei->is_dot_available, 392 eei->dot_value, 393 eei->dot_section, 394 section_pointer, 395 alignment_pointer, 396 NULL, 397 NULL, 398 NULL, 399 false); 400 } 401 402 void 403 left_print(FILE* f) const 404 { this->left_->print(f); } 405 406 void 407 right_print(FILE* f) const 408 { this->right_->print(f); } 409 410 // This is a call to function FUNCTION_NAME. Print it. This is for 411 // debugging. 412 void 413 print_function(FILE* f, const char* function_name) const 414 { 415 fprintf(f, "%s(", function_name); 416 this->left_print(f); 417 fprintf(f, ", "); 418 this->right_print(f); 419 fprintf(f, ")"); 420 } 421 422 private: 423 Expression* left_; 424 Expression* right_; 425 }; 426 427 // Handle binary operators. We use a preprocessor macro as a hack to 428 // capture the C operator. KEEP_LEFT means that if the left operand 429 // is section relative and the right operand is not, the result uses 430 // the same section as the left operand. KEEP_RIGHT is the same with 431 // left and right swapped. IS_DIV means that we need to give an error 432 // if the right operand is zero. WARN means that we should warn if 433 // used on section relative values in a relocatable link. We always 434 // warn if used on values in different sections in a relocatable link. 435 436 #define BINARY_EXPRESSION(NAME, OPERATOR, KEEP_LEFT, KEEP_RIGHT, IS_DIV, WARN) \ 437 class Binary_ ## NAME : public Binary_expression \ 438 { \ 439 public: \ 440 Binary_ ## NAME(Expression* left, Expression* right) \ 441 : Binary_expression(left, right) \ 442 { } \ 443 \ 444 uint64_t \ 445 value(const Expression_eval_info* eei) \ 446 { \ 447 Output_section* left_section; \ 448 uint64_t left_alignment = 0; \ 449 uint64_t left = this->left_value(eei, &left_section, \ 450 &left_alignment); \ 451 Output_section* right_section; \ 452 uint64_t right_alignment = 0; \ 453 uint64_t right = this->right_value(eei, &right_section, \ 454 &right_alignment); \ 455 if (KEEP_RIGHT && left_section == NULL && right_section != NULL) \ 456 { \ 457 if (eei->result_section_pointer != NULL) \ 458 *eei->result_section_pointer = right_section; \ 459 if (eei->result_alignment_pointer != NULL \ 460 && right_alignment > *eei->result_alignment_pointer) \ 461 *eei->result_alignment_pointer = right_alignment; \ 462 } \ 463 else if (KEEP_LEFT \ 464 && left_section != NULL \ 465 && right_section == NULL) \ 466 { \ 467 if (eei->result_section_pointer != NULL) \ 468 *eei->result_section_pointer = left_section; \ 469 if (eei->result_alignment_pointer != NULL \ 470 && left_alignment > *eei->result_alignment_pointer) \ 471 *eei->result_alignment_pointer = left_alignment; \ 472 } \ 473 else if ((WARN || left_section != right_section) \ 474 && (left_section != NULL || right_section != NULL) \ 475 && parameters->options().relocatable()) \ 476 gold_warning(_("binary " #NAME " applied to section " \ 477 "relative value")); \ 478 if (IS_DIV && right == 0) \ 479 { \ 480 gold_error(_(#NAME " by zero")); \ 481 return 0; \ 482 } \ 483 return left OPERATOR right; \ 484 } \ 485 \ 486 void \ 487 print(FILE* f) const \ 488 { \ 489 fprintf(f, "("); \ 490 this->left_print(f); \ 491 fprintf(f, " %s ", #OPERATOR); \ 492 this->right_print(f); \ 493 fprintf(f, ")"); \ 494 } \ 495 }; \ 496 \ 497 extern "C" Expression* \ 498 script_exp_binary_ ## NAME(Expression* left, Expression* right) \ 499 { \ 500 return new Binary_ ## NAME(left, right); \ 501 } 502 503 BINARY_EXPRESSION(mult, *, false, false, false, true) 504 BINARY_EXPRESSION(div, /, false, false, true, true) 505 BINARY_EXPRESSION(mod, %, false, false, true, true) 506 BINARY_EXPRESSION(add, +, true, true, false, true) 507 BINARY_EXPRESSION(sub, -, true, false, false, false) 508 BINARY_EXPRESSION(lshift, <<, false, false, false, true) 509 BINARY_EXPRESSION(rshift, >>, false, false, false, true) 510 BINARY_EXPRESSION(eq, ==, false, false, false, false) 511 BINARY_EXPRESSION(ne, !=, false, false, false, false) 512 BINARY_EXPRESSION(le, <=, false, false, false, false) 513 BINARY_EXPRESSION(ge, >=, false, false, false, false) 514 BINARY_EXPRESSION(lt, <, false, false, false, false) 515 BINARY_EXPRESSION(gt, >, false, false, false, false) 516 BINARY_EXPRESSION(bitwise_and, &, true, true, false, true) 517 BINARY_EXPRESSION(bitwise_xor, ^, true, true, false, true) 518 BINARY_EXPRESSION(bitwise_or, |, true, true, false, true) 519 BINARY_EXPRESSION(logical_and, &&, false, false, false, true) 520 BINARY_EXPRESSION(logical_or, ||, false, false, false, true) 521 522 // A trinary expression. 523 524 class Trinary_expression : public Expression 525 { 526 public: 527 Trinary_expression(Expression* arg1, Expression* arg2, Expression* arg3) 528 : arg1_(arg1), arg2_(arg2), arg3_(arg3) 529 { } 530 531 ~Trinary_expression() 532 { 533 delete this->arg1_; 534 delete this->arg2_; 535 delete this->arg3_; 536 } 537 538 protected: 539 uint64_t 540 arg1_value(const Expression_eval_info* eei, 541 Output_section** section_pointer) const 542 { 543 return this->arg1_->eval_maybe_dot(eei->symtab, eei->layout, 544 eei->check_assertions, 545 eei->is_dot_available, 546 eei->dot_value, 547 eei->dot_section, 548 section_pointer, 549 NULL, 550 NULL, 551 NULL, 552 NULL, 553 false); 554 } 555 556 uint64_t 557 arg2_value(const Expression_eval_info* eei, 558 Output_section** section_pointer, 559 uint64_t* alignment_pointer) const 560 { 561 return this->arg1_->eval_maybe_dot(eei->symtab, eei->layout, 562 eei->check_assertions, 563 eei->is_dot_available, 564 eei->dot_value, 565 eei->dot_section, 566 section_pointer, 567 alignment_pointer, 568 NULL, 569 NULL, 570 NULL, 571 false); 572 } 573 574 uint64_t 575 arg3_value(const Expression_eval_info* eei, 576 Output_section** section_pointer, 577 uint64_t* alignment_pointer) const 578 { 579 return this->arg1_->eval_maybe_dot(eei->symtab, eei->layout, 580 eei->check_assertions, 581 eei->is_dot_available, 582 eei->dot_value, 583 eei->dot_section, 584 section_pointer, 585 alignment_pointer, 586 NULL, 587 NULL, 588 NULL, 589 false); 590 } 591 592 void 593 arg1_print(FILE* f) const 594 { this->arg1_->print(f); } 595 596 void 597 arg2_print(FILE* f) const 598 { this->arg2_->print(f); } 599 600 void 601 arg3_print(FILE* f) const 602 { this->arg3_->print(f); } 603 604 private: 605 Expression* arg1_; 606 Expression* arg2_; 607 Expression* arg3_; 608 }; 609 610 // The conditional operator. 611 612 class Trinary_cond : public Trinary_expression 613 { 614 public: 615 Trinary_cond(Expression* arg1, Expression* arg2, Expression* arg3) 616 : Trinary_expression(arg1, arg2, arg3) 617 { } 618 619 uint64_t 620 value(const Expression_eval_info* eei) 621 { 622 Output_section* arg1_section; 623 uint64_t arg1 = this->arg1_value(eei, &arg1_section); 624 return (arg1 625 ? this->arg2_value(eei, eei->result_section_pointer, 626 eei->result_alignment_pointer) 627 : this->arg3_value(eei, eei->result_section_pointer, 628 eei->result_alignment_pointer)); 629 } 630 631 void 632 print(FILE* f) const 633 { 634 fprintf(f, "("); 635 this->arg1_print(f); 636 fprintf(f, " ? "); 637 this->arg2_print(f); 638 fprintf(f, " : "); 639 this->arg3_print(f); 640 fprintf(f, ")"); 641 } 642 }; 643 644 extern "C" Expression* 645 script_exp_trinary_cond(Expression* arg1, Expression* arg2, Expression* arg3) 646 { 647 return new Trinary_cond(arg1, arg2, arg3); 648 } 649 650 // Max function. 651 652 class Max_expression : public Binary_expression 653 { 654 public: 655 Max_expression(Expression* left, Expression* right) 656 : Binary_expression(left, right) 657 { } 658 659 uint64_t 660 value(const Expression_eval_info* eei) 661 { 662 Output_section* left_section; 663 uint64_t left_alignment; 664 uint64_t left = this->left_value(eei, &left_section, &left_alignment); 665 Output_section* right_section; 666 uint64_t right_alignment; 667 uint64_t right = this->right_value(eei, &right_section, &right_alignment); 668 if (left_section == right_section) 669 { 670 if (eei->result_section_pointer != NULL) 671 *eei->result_section_pointer = left_section; 672 } 673 else if ((left_section != NULL || right_section != NULL) 674 && parameters->options().relocatable()) 675 gold_warning(_("max applied to section relative value")); 676 if (eei->result_alignment_pointer != NULL) 677 { 678 uint64_t ra = *eei->result_alignment_pointer; 679 if (left > right) 680 ra = std::max(ra, left_alignment); 681 else if (right > left) 682 ra = std::max(ra, right_alignment); 683 else 684 ra = std::max(ra, std::max(left_alignment, right_alignment)); 685 *eei->result_alignment_pointer = ra; 686 } 687 return std::max(left, right); 688 } 689 690 void 691 print(FILE* f) const 692 { this->print_function(f, "MAX"); } 693 }; 694 695 extern "C" Expression* 696 script_exp_function_max(Expression* left, Expression* right) 697 { 698 return new Max_expression(left, right); 699 } 700 701 // Min function. 702 703 class Min_expression : public Binary_expression 704 { 705 public: 706 Min_expression(Expression* left, Expression* right) 707 : Binary_expression(left, right) 708 { } 709 710 uint64_t 711 value(const Expression_eval_info* eei) 712 { 713 Output_section* left_section; 714 uint64_t left_alignment; 715 uint64_t left = this->left_value(eei, &left_section, &left_alignment); 716 Output_section* right_section; 717 uint64_t right_alignment; 718 uint64_t right = this->right_value(eei, &right_section, &right_alignment); 719 if (left_section == right_section) 720 { 721 if (eei->result_section_pointer != NULL) 722 *eei->result_section_pointer = left_section; 723 } 724 else if ((left_section != NULL || right_section != NULL) 725 && parameters->options().relocatable()) 726 gold_warning(_("min applied to section relative value")); 727 if (eei->result_alignment_pointer != NULL) 728 { 729 uint64_t ra = *eei->result_alignment_pointer; 730 if (left < right) 731 ra = std::max(ra, left_alignment); 732 else if (right < left) 733 ra = std::max(ra, right_alignment); 734 else 735 ra = std::max(ra, std::max(left_alignment, right_alignment)); 736 *eei->result_alignment_pointer = ra; 737 } 738 return std::min(left, right); 739 } 740 741 void 742 print(FILE* f) const 743 { this->print_function(f, "MIN"); } 744 }; 745 746 extern "C" Expression* 747 script_exp_function_min(Expression* left, Expression* right) 748 { 749 return new Min_expression(left, right); 750 } 751 752 // Class Section_expression. This is a parent class used for 753 // functions which take the name of an output section. 754 755 class Section_expression : public Expression 756 { 757 public: 758 Section_expression(const char* section_name, size_t section_name_len) 759 : section_name_(section_name, section_name_len) 760 { } 761 762 uint64_t 763 value(const Expression_eval_info*); 764 765 void 766 print(FILE* f) const 767 { fprintf(f, "%s(%s)", this->function_name(), this->section_name_.c_str()); } 768 769 protected: 770 // The child class must implement this. 771 virtual uint64_t 772 value_from_output_section(const Expression_eval_info*, 773 Output_section*) = 0; 774 775 // The child class must implement this. 776 virtual uint64_t 777 value_from_script_output_section(uint64_t address, uint64_t load_address, 778 uint64_t addralign, uint64_t size) = 0; 779 780 // The child class must implement this. 781 virtual const char* 782 function_name() const = 0; 783 784 private: 785 std::string section_name_; 786 }; 787 788 uint64_t 789 Section_expression::value(const Expression_eval_info* eei) 790 { 791 const char* section_name = this->section_name_.c_str(); 792 Output_section* os = eei->layout->find_output_section(section_name); 793 if (os != NULL) 794 return this->value_from_output_section(eei, os); 795 796 uint64_t address; 797 uint64_t load_address; 798 uint64_t addralign; 799 uint64_t size; 800 const Script_options* ss = eei->layout->script_options(); 801 if (ss->saw_sections_clause()) 802 { 803 if (ss->script_sections()->get_output_section_info(section_name, 804 &address, 805 &load_address, 806 &addralign, 807 &size)) 808 return this->value_from_script_output_section(address, load_address, 809 addralign, size); 810 } 811 812 gold_error("%s called on nonexistent output section '%s'", 813 this->function_name(), section_name); 814 return 0; 815 } 816 817 // ABSOLUTE function. 818 819 class Absolute_expression : public Unary_expression 820 { 821 public: 822 Absolute_expression(Expression* arg) 823 : Unary_expression(arg) 824 { } 825 826 uint64_t 827 value(const Expression_eval_info* eei) 828 { 829 uint64_t ret = this->arg_value(eei, NULL); 830 // Force the value to be absolute. 831 if (eei->result_section_pointer != NULL) 832 *eei->result_section_pointer = NULL; 833 return ret; 834 } 835 836 void 837 print(FILE* f) const 838 { 839 fprintf(f, "ABSOLUTE("); 840 this->arg_print(f); 841 fprintf(f, ")"); 842 } 843 }; 844 845 extern "C" Expression* 846 script_exp_function_absolute(Expression* arg) 847 { 848 return new Absolute_expression(arg); 849 } 850 851 // ALIGN function. 852 853 class Align_expression : public Binary_expression 854 { 855 public: 856 Align_expression(Expression* left, Expression* right) 857 : Binary_expression(left, right) 858 { } 859 860 uint64_t 861 value(const Expression_eval_info* eei) 862 { 863 Output_section* align_section; 864 uint64_t align = this->right_value(eei, &align_section, NULL); 865 if (align_section != NULL 866 && parameters->options().relocatable()) 867 gold_warning(_("aligning to section relative value")); 868 869 if (eei->result_alignment_pointer != NULL 870 && align > *eei->result_alignment_pointer) 871 { 872 uint64_t a = align; 873 while ((a & (a - 1)) != 0) 874 a &= a - 1; 875 *eei->result_alignment_pointer = a; 876 } 877 878 uint64_t value = this->left_value(eei, eei->result_section_pointer, NULL); 879 if (align <= 1) 880 return value; 881 return ((value + align - 1) / align) * align; 882 } 883 884 void 885 print(FILE* f) const 886 { this->print_function(f, "ALIGN"); } 887 }; 888 889 extern "C" Expression* 890 script_exp_function_align(Expression* left, Expression* right) 891 { 892 return new Align_expression(left, right); 893 } 894 895 // ASSERT function. 896 897 class Assert_expression : public Unary_expression 898 { 899 public: 900 Assert_expression(Expression* arg, const char* message, size_t length) 901 : Unary_expression(arg), message_(message, length) 902 { } 903 904 uint64_t 905 value(const Expression_eval_info* eei) 906 { 907 uint64_t value = this->arg_value(eei, eei->result_section_pointer); 908 if (!value && eei->check_assertions) 909 gold_error("%s", this->message_.c_str()); 910 return value; 911 } 912 913 void 914 print(FILE* f) const 915 { 916 fprintf(f, "ASSERT("); 917 this->arg_print(f); 918 fprintf(f, ", %s)", this->message_.c_str()); 919 } 920 921 private: 922 std::string message_; 923 }; 924 925 extern "C" Expression* 926 script_exp_function_assert(Expression* expr, const char* message, 927 size_t length) 928 { 929 return new Assert_expression(expr, message, length); 930 } 931 932 // ADDR function. 933 934 class Addr_expression : public Section_expression 935 { 936 public: 937 Addr_expression(const char* section_name, size_t section_name_len) 938 : Section_expression(section_name, section_name_len) 939 { } 940 941 protected: 942 uint64_t 943 value_from_output_section(const Expression_eval_info* eei, 944 Output_section* os) 945 { 946 if (eei->result_section_pointer != NULL) 947 *eei->result_section_pointer = os; 948 return os->address(); 949 } 950 951 uint64_t 952 value_from_script_output_section(uint64_t address, uint64_t, uint64_t, 953 uint64_t) 954 { return address; } 955 956 const char* 957 function_name() const 958 { return "ADDR"; } 959 }; 960 961 extern "C" Expression* 962 script_exp_function_addr(const char* section_name, size_t section_name_len) 963 { 964 return new Addr_expression(section_name, section_name_len); 965 } 966 967 // ALIGNOF. 968 969 class Alignof_expression : public Section_expression 970 { 971 public: 972 Alignof_expression(const char* section_name, size_t section_name_len) 973 : Section_expression(section_name, section_name_len) 974 { } 975 976 protected: 977 uint64_t 978 value_from_output_section(const Expression_eval_info*, 979 Output_section* os) 980 { return os->addralign(); } 981 982 uint64_t 983 value_from_script_output_section(uint64_t, uint64_t, uint64_t addralign, 984 uint64_t) 985 { return addralign; } 986 987 const char* 988 function_name() const 989 { return "ALIGNOF"; } 990 }; 991 992 extern "C" Expression* 993 script_exp_function_alignof(const char* section_name, size_t section_name_len) 994 { 995 return new Alignof_expression(section_name, section_name_len); 996 } 997 998 // CONSTANT. It would be nice if we could simply evaluate this 999 // immediately and return an Integer_expression, but unfortunately we 1000 // don't know the target. 1001 1002 class Constant_expression : public Expression 1003 { 1004 public: 1005 Constant_expression(const char* name, size_t length); 1006 1007 uint64_t 1008 value(const Expression_eval_info*); 1009 1010 void 1011 print(FILE* f) const; 1012 1013 private: 1014 enum Constant_function 1015 { 1016 CONSTANT_MAXPAGESIZE, 1017 CONSTANT_COMMONPAGESIZE 1018 }; 1019 1020 Constant_function function_; 1021 }; 1022 1023 Constant_expression::Constant_expression(const char* name, size_t length) 1024 { 1025 if (length == 11 && strncmp(name, "MAXPAGESIZE", length) == 0) 1026 this->function_ = CONSTANT_MAXPAGESIZE; 1027 else if (length == 14 && strncmp(name, "COMMONPAGESIZE", length) == 0) 1028 this->function_ = CONSTANT_COMMONPAGESIZE; 1029 else 1030 { 1031 std::string s(name, length); 1032 gold_error(_("unknown constant %s"), s.c_str()); 1033 this->function_ = CONSTANT_MAXPAGESIZE; 1034 } 1035 } 1036 1037 uint64_t 1038 Constant_expression::value(const Expression_eval_info*) 1039 { 1040 switch (this->function_) 1041 { 1042 case CONSTANT_MAXPAGESIZE: 1043 return parameters->target().abi_pagesize(); 1044 case CONSTANT_COMMONPAGESIZE: 1045 return parameters->target().common_pagesize(); 1046 default: 1047 gold_unreachable(); 1048 } 1049 } 1050 1051 void 1052 Constant_expression::print(FILE* f) const 1053 { 1054 const char* name; 1055 switch (this->function_) 1056 { 1057 case CONSTANT_MAXPAGESIZE: 1058 name = "MAXPAGESIZE"; 1059 break; 1060 case CONSTANT_COMMONPAGESIZE: 1061 name = "COMMONPAGESIZE"; 1062 break; 1063 default: 1064 gold_unreachable(); 1065 } 1066 fprintf(f, "CONSTANT(%s)", name); 1067 } 1068 1069 extern "C" Expression* 1070 script_exp_function_constant(const char* name, size_t length) 1071 { 1072 return new Constant_expression(name, length); 1073 } 1074 1075 // DATA_SEGMENT_ALIGN. FIXME: we don't implement this; we always fall 1076 // back to the general case. 1077 1078 extern "C" Expression* 1079 script_exp_function_data_segment_align(Expression* left, Expression*) 1080 { 1081 Expression* e1 = script_exp_function_align(script_exp_string(".", 1), left); 1082 Expression* e2 = script_exp_binary_sub(left, script_exp_integer(1)); 1083 Expression* e3 = script_exp_binary_bitwise_and(script_exp_string(".", 1), 1084 e2); 1085 return script_exp_binary_add(e1, e3); 1086 } 1087 1088 // DATA_SEGMENT_RELRO. FIXME: This is not implemented. 1089 1090 extern "C" Expression* 1091 script_exp_function_data_segment_relro_end(Expression*, Expression* right) 1092 { 1093 return right; 1094 } 1095 1096 // DATA_SEGMENT_END. FIXME: This is not implemented. 1097 1098 extern "C" Expression* 1099 script_exp_function_data_segment_end(Expression* val) 1100 { 1101 return val; 1102 } 1103 1104 // DEFINED function. 1105 1106 class Defined_expression : public Expression 1107 { 1108 public: 1109 Defined_expression(const char* symbol_name, size_t symbol_name_len) 1110 : symbol_name_(symbol_name, symbol_name_len) 1111 { } 1112 1113 uint64_t 1114 value(const Expression_eval_info* eei) 1115 { 1116 Symbol* sym = eei->symtab->lookup(this->symbol_name_.c_str()); 1117 return sym != NULL && sym->is_defined(); 1118 } 1119 1120 void 1121 print(FILE* f) const 1122 { fprintf(f, "DEFINED(%s)", this->symbol_name_.c_str()); } 1123 1124 private: 1125 std::string symbol_name_; 1126 }; 1127 1128 extern "C" Expression* 1129 script_exp_function_defined(const char* symbol_name, size_t symbol_name_len) 1130 { 1131 return new Defined_expression(symbol_name, symbol_name_len); 1132 } 1133 1134 // LOADADDR function 1135 1136 class Loadaddr_expression : public Section_expression 1137 { 1138 public: 1139 Loadaddr_expression(const char* section_name, size_t section_name_len) 1140 : Section_expression(section_name, section_name_len) 1141 { } 1142 1143 protected: 1144 uint64_t 1145 value_from_output_section(const Expression_eval_info* eei, 1146 Output_section* os) 1147 { 1148 if (os->has_load_address()) 1149 return os->load_address(); 1150 else 1151 { 1152 if (eei->result_section_pointer != NULL) 1153 *eei->result_section_pointer = os; 1154 return os->address(); 1155 } 1156 } 1157 1158 uint64_t 1159 value_from_script_output_section(uint64_t, uint64_t load_address, uint64_t, 1160 uint64_t) 1161 { return load_address; } 1162 1163 const char* 1164 function_name() const 1165 { return "LOADADDR"; } 1166 }; 1167 1168 extern "C" Expression* 1169 script_exp_function_loadaddr(const char* section_name, size_t section_name_len) 1170 { 1171 return new Loadaddr_expression(section_name, section_name_len); 1172 } 1173 1174 // SIZEOF function 1175 1176 class Sizeof_expression : public Section_expression 1177 { 1178 public: 1179 Sizeof_expression(const char* section_name, size_t section_name_len) 1180 : Section_expression(section_name, section_name_len) 1181 { } 1182 1183 protected: 1184 uint64_t 1185 value_from_output_section(const Expression_eval_info*, 1186 Output_section* os) 1187 { 1188 // We can not use data_size here, as the size of the section may 1189 // not have been finalized. Instead we get whatever the current 1190 // size is. This will work correctly for backward references in 1191 // linker scripts. 1192 return os->current_data_size(); 1193 } 1194 1195 uint64_t 1196 value_from_script_output_section(uint64_t, uint64_t, uint64_t, 1197 uint64_t size) 1198 { return size; } 1199 1200 const char* 1201 function_name() const 1202 { return "SIZEOF"; } 1203 }; 1204 1205 extern "C" Expression* 1206 script_exp_function_sizeof(const char* section_name, size_t section_name_len) 1207 { 1208 return new Sizeof_expression(section_name, section_name_len); 1209 } 1210 1211 // SIZEOF_HEADERS. 1212 1213 class Sizeof_headers_expression : public Expression 1214 { 1215 public: 1216 Sizeof_headers_expression() 1217 { } 1218 1219 uint64_t 1220 value(const Expression_eval_info*); 1221 1222 void 1223 print(FILE* f) const 1224 { fprintf(f, "SIZEOF_HEADERS"); } 1225 }; 1226 1227 uint64_t 1228 Sizeof_headers_expression::value(const Expression_eval_info* eei) 1229 { 1230 unsigned int ehdr_size; 1231 unsigned int phdr_size; 1232 if (parameters->target().get_size() == 32) 1233 { 1234 ehdr_size = elfcpp::Elf_sizes<32>::ehdr_size; 1235 phdr_size = elfcpp::Elf_sizes<32>::phdr_size; 1236 } 1237 else if (parameters->target().get_size() == 64) 1238 { 1239 ehdr_size = elfcpp::Elf_sizes<64>::ehdr_size; 1240 phdr_size = elfcpp::Elf_sizes<64>::phdr_size; 1241 } 1242 else 1243 gold_unreachable(); 1244 1245 return ehdr_size + phdr_size * eei->layout->expected_segment_count(); 1246 } 1247 1248 extern "C" Expression* 1249 script_exp_function_sizeof_headers() 1250 { 1251 return new Sizeof_headers_expression(); 1252 } 1253 1254 // SEGMENT_START. 1255 1256 class Segment_start_expression : public Unary_expression 1257 { 1258 public: 1259 Segment_start_expression(const char* segment_name, size_t segment_name_len, 1260 Expression* default_value) 1261 : Unary_expression(default_value), 1262 segment_name_(segment_name, segment_name_len) 1263 { } 1264 1265 uint64_t 1266 value(const Expression_eval_info*); 1267 1268 void 1269 print(FILE* f) const 1270 { 1271 fprintf(f, "SEGMENT_START(\"%s\", ", this->segment_name_.c_str()); 1272 this->arg_print(f); 1273 fprintf(f, ")"); 1274 } 1275 1276 private: 1277 std::string segment_name_; 1278 }; 1279 1280 uint64_t 1281 Segment_start_expression::value(const Expression_eval_info* eei) 1282 { 1283 // Check for command line overrides. 1284 if (parameters->options().user_set_Ttext() 1285 && this->segment_name_ == ".text") 1286 return parameters->options().Ttext(); 1287 else if (parameters->options().user_set_Tdata() 1288 && this->segment_name_ == ".data") 1289 return parameters->options().Tdata(); 1290 else if (parameters->options().user_set_Tbss() 1291 && this->segment_name_ == ".bss") 1292 return parameters->options().Tbss(); 1293 else 1294 { 1295 uint64_t ret = this->arg_value(eei, NULL); 1296 // Force the value to be absolute. 1297 if (eei->result_section_pointer != NULL) 1298 *eei->result_section_pointer = NULL; 1299 return ret; 1300 } 1301 } 1302 1303 extern "C" Expression* 1304 script_exp_function_segment_start(const char* segment_name, 1305 size_t segment_name_len, 1306 Expression* default_value) 1307 { 1308 return new Segment_start_expression(segment_name, segment_name_len, 1309 default_value); 1310 } 1311 1312 } // End namespace gold. 1313