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