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