1 // expression.cc -- expressions in linker scripts for gold
3 // Copyright 2006, 2007, 2008 Free Software Foundation, Inc.
4 // Written by Ian Lance Taylor <iant@google.com>.
6 // This file is part of gold.
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.
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.
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.
28 #include "parameters.h"
38 // This file holds the code which handles linker expressions.
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.
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.
51 struct Expression::Expression_eval_info
54 const Symbol_table
* symtab
;
55 // The layout--we use this to get section information.
57 // Whether expressions can refer to the dot symbol. The dot symbol
58 // is only available within a SECTIONS clause.
59 bool is_dot_available
;
60 // Whether the dot symbol currently has a value.
62 // The current value of the dot symbol.
64 // Points to the IS_ABSOLUTE variable, which is set to false if the
65 // expression uses a value which is not absolute.
69 // Evaluate an expression.
72 Expression::eval(const Symbol_table
* symtab
, const Layout
* layout
)
75 return this->eval_maybe_dot(symtab
, layout
, false, false, 0, &dummy
);
78 // Evaluate an expression which may refer to the dot symbol.
81 Expression::eval_with_dot(const Symbol_table
* symtab
, const Layout
* layout
,
82 bool dot_has_value
, uint64_t dot_value
,
85 return this->eval_maybe_dot(symtab
, layout
, true, dot_has_value
, dot_value
,
89 // Evaluate an expression which may or may not refer to the dot
93 Expression::eval_maybe_dot(const Symbol_table
* symtab
, const Layout
* layout
,
94 bool is_dot_available
, bool dot_has_value
,
95 uint64_t dot_value
, bool* is_absolute
)
97 Expression_eval_info eei
;
100 eei
.is_dot_available
= is_dot_available
;
101 eei
.dot_has_value
= dot_has_value
;
102 eei
.dot_value
= dot_value
;
104 // We assume the value is absolute, and only set this to false if we
105 // find a section relative reference.
107 eei
.is_absolute
= is_absolute
;
109 return this->value(&eei
);
114 class Integer_expression
: public Expression
117 Integer_expression(uint64_t val
)
122 value(const Expression_eval_info
*)
123 { return this->val_
; }
127 { fprintf(f
, "0x%llx", static_cast<unsigned long long>(this->val_
)); }
133 extern "C" Expression
*
134 script_exp_integer(uint64_t val
)
136 return new Integer_expression(val
);
139 // An expression whose value is the value of a symbol.
141 class Symbol_expression
: public Expression
144 Symbol_expression(const char* name
, size_t length
)
145 : name_(name
, length
)
149 value(const Expression_eval_info
*);
153 { fprintf(f
, "%s", this->name_
.c_str()); }
160 Symbol_expression::value(const Expression_eval_info
* eei
)
162 Symbol
* sym
= eei
->symtab
->lookup(this->name_
.c_str());
163 if (sym
== NULL
|| !sym
->is_defined())
165 gold_error(_("undefined symbol '%s' referenced in expression"),
166 this->name_
.c_str());
170 // If this symbol does not have an absolute value, then the whole
171 // expression does not have an absolute value. This is not strictly
172 // accurate: the subtraction of two symbols in the same section is
173 // absolute. This is unlikely to matter in practice, as this value
174 // is only used for error checking.
175 if (!sym
->value_is_absolute())
176 *eei
->is_absolute
= false;
178 if (parameters
->get_size() == 32)
179 return eei
->symtab
->get_sized_symbol
<32>(sym
)->value();
180 else if (parameters
->get_size() == 64)
181 return eei
->symtab
->get_sized_symbol
<64>(sym
)->value();
186 // An expression whose value is the value of the special symbol ".".
187 // This is only valid within a SECTIONS clause.
189 class Dot_expression
: public Expression
196 value(const Expression_eval_info
*);
204 Dot_expression::value(const Expression_eval_info
* eei
)
206 if (!eei
->is_dot_available
)
208 gold_error(_("invalid reference to dot symbol outside of "
212 else if (!eei
->dot_has_value
)
214 gold_error(_("invalid reference to dot symbol before "
215 "it has been given a value"));
218 return eei
->dot_value
;
221 // A string. This is either the name of a symbol, or ".".
223 extern "C" Expression
*
224 script_exp_string(const char* name
, size_t length
)
226 if (length
== 1 && name
[0] == '.')
227 return new Dot_expression();
229 return new Symbol_expression(name
, length
);
232 // A unary expression.
234 class Unary_expression
: public Expression
237 Unary_expression(Expression
* arg
)
242 { delete this->arg_
; }
246 arg_value(const Expression_eval_info
* eei
) const
247 { return this->arg_
->value(eei
); }
250 arg_print(FILE* f
) const
251 { this->arg_
->print(f
); }
257 // Handle unary operators. We use a preprocessor macro as a hack to
258 // capture the C operator.
260 #define UNARY_EXPRESSION(NAME, OPERATOR) \
261 class Unary_ ## NAME : public Unary_expression \
264 Unary_ ## NAME(Expression* arg) \
265 : Unary_expression(arg) \
269 value(const Expression_eval_info* eei) \
270 { return OPERATOR this->arg_value(eei); } \
273 print(FILE* f) const \
275 fprintf(f, "(%s ", #OPERATOR); \
276 this->arg_print(f); \
281 extern "C" Expression* \
282 script_exp_unary_ ## NAME(Expression* arg) \
284 return new Unary_ ## NAME(arg); \
287 UNARY_EXPRESSION(minus
, -)
288 UNARY_EXPRESSION(logical_not
, !)
289 UNARY_EXPRESSION(bitwise_not
, ~)
291 // A binary expression.
293 class Binary_expression
: public Expression
296 Binary_expression(Expression
* left
, Expression
* right
)
297 : left_(left
), right_(right
)
308 left_value(const Expression_eval_info
* eei
) const
309 { return this->left_
->value(eei
); }
312 right_value(const Expression_eval_info
* eei
) const
313 { return this->right_
->value(eei
); }
316 left_print(FILE* f
) const
317 { this->left_
->print(f
); }
320 right_print(FILE* f
) const
321 { this->right_
->print(f
); }
323 // This is a call to function FUNCTION_NAME. Print it. This is for
326 print_function(FILE* f
, const char *function_name
) const
328 fprintf(f
, "%s(", function_name
);
331 this->right_print(f
);
340 // Handle binary operators. We use a preprocessor macro as a hack to
341 // capture the C operator.
343 #define BINARY_EXPRESSION(NAME, OPERATOR) \
344 class Binary_ ## NAME : public Binary_expression \
347 Binary_ ## NAME(Expression* left, Expression* right) \
348 : Binary_expression(left, right) \
352 value(const Expression_eval_info* eei) \
354 return (this->left_value(eei) \
355 OPERATOR this->right_value(eei)); \
359 print(FILE* f) const \
362 this->left_print(f); \
363 fprintf(f, " %s ", #OPERATOR); \
364 this->right_print(f); \
369 extern "C" Expression* \
370 script_exp_binary_ ## NAME(Expression* left, Expression* right) \
372 return new Binary_ ## NAME(left, right); \
375 BINARY_EXPRESSION(mult
, *)
376 BINARY_EXPRESSION(div
, /)
377 BINARY_EXPRESSION(mod
, %)
378 BINARY_EXPRESSION(add
, +)
379 BINARY_EXPRESSION(sub
, -)
380 BINARY_EXPRESSION(lshift
, <<)
381 BINARY_EXPRESSION(rshift
, >>)
382 BINARY_EXPRESSION(eq
, ==)
383 BINARY_EXPRESSION(ne
, !=)
384 BINARY_EXPRESSION(le
, <=)
385 BINARY_EXPRESSION(ge
, >=)
386 BINARY_EXPRESSION(lt
, <)
387 BINARY_EXPRESSION(gt
, >)
388 BINARY_EXPRESSION(bitwise_and
, &)
389 BINARY_EXPRESSION(bitwise_xor
, ^)
390 BINARY_EXPRESSION(bitwise_or
, |)
391 BINARY_EXPRESSION(logical_and
, &&)
392 BINARY_EXPRESSION(logical_or
, ||)
394 // A trinary expression.
396 class Trinary_expression
: public Expression
399 Trinary_expression(Expression
* arg1
, Expression
* arg2
, Expression
* arg3
)
400 : arg1_(arg1
), arg2_(arg2
), arg3_(arg3
)
403 ~Trinary_expression()
412 arg1_value(const Expression_eval_info
* eei
) const
413 { return this->arg1_
->value(eei
); }
416 arg2_value(const Expression_eval_info
* eei
) const
417 { return this->arg2_
->value(eei
); }
420 arg3_value(const Expression_eval_info
* eei
) const
421 { return this->arg3_
->value(eei
); }
424 arg1_print(FILE* f
) const
425 { this->arg1_
->print(f
); }
428 arg2_print(FILE* f
) const
429 { this->arg2_
->print(f
); }
432 arg3_print(FILE* f
) const
433 { this->arg3_
->print(f
); }
441 // The conditional operator.
443 class Trinary_cond
: public Trinary_expression
446 Trinary_cond(Expression
* arg1
, Expression
* arg2
, Expression
* arg3
)
447 : Trinary_expression(arg1
, arg2
, arg3
)
451 value(const Expression_eval_info
* eei
)
453 return (this->arg1_value(eei
)
454 ? this->arg2_value(eei
)
455 : this->arg3_value(eei
));
471 extern "C" Expression
*
472 script_exp_trinary_cond(Expression
* arg1
, Expression
* arg2
, Expression
* arg3
)
474 return new Trinary_cond(arg1
, arg2
, arg3
);
479 class Max_expression
: public Binary_expression
482 Max_expression(Expression
* left
, Expression
* right
)
483 : Binary_expression(left
, right
)
487 value(const Expression_eval_info
* eei
)
488 { return std::max(this->left_value(eei
), this->right_value(eei
)); }
492 { this->print_function(f
, "MAX"); }
495 extern "C" Expression
*
496 script_exp_function_max(Expression
* left
, Expression
* right
)
498 return new Max_expression(left
, right
);
503 class Min_expression
: public Binary_expression
506 Min_expression(Expression
* left
, Expression
* right
)
507 : Binary_expression(left
, right
)
511 value(const Expression_eval_info
* eei
)
512 { return std::min(this->left_value(eei
), this->right_value(eei
)); }
516 { this->print_function(f
, "MIN"); }
519 extern "C" Expression
*
520 script_exp_function_min(Expression
* left
, Expression
* right
)
522 return new Min_expression(left
, right
);
527 class Align_expression
: public Binary_expression
530 Align_expression(Expression
* left
, Expression
* right
)
531 : Binary_expression(left
, right
)
535 value(const Expression_eval_info
* eei
)
537 uint64_t align
= this->right_value(eei
);
538 uint64_t value
= this->left_value(eei
);
541 return ((value
+ align
- 1) / align
) * align
;
546 { this->print_function(f
, "ALIGN"); }
549 extern "C" Expression
*
550 script_exp_function_align(Expression
* left
, Expression
* right
)
552 return new Align_expression(left
, right
);
557 class Assert_expression
: public Unary_expression
560 Assert_expression(Expression
* arg
, const char* message
, size_t length
)
561 : Unary_expression(arg
), message_(message
, length
)
565 value(const Expression_eval_info
* eei
)
567 uint64_t value
= this->arg_value(eei
);
569 gold_error("%s", this->message_
.c_str());
576 fprintf(f
, "ASSERT(");
578 fprintf(f
, ", %s)", this->message_
.c_str());
582 std::string message_
;
585 extern "C" Expression
*
586 script_exp_function_assert(Expression
* expr
, const char* message
,
589 return new Assert_expression(expr
, message
, length
);
594 class Addr_expression
: public Expression
597 Addr_expression(const char* section_name
, size_t section_name_len
)
598 : section_name_(section_name
, section_name_len
)
602 value(const Expression_eval_info
*);
606 { fprintf(f
, "ADDR(%s)", this->section_name_
.c_str()); }
609 std::string section_name_
;
613 Addr_expression::value(const Expression_eval_info
* eei
)
615 const char* section_name
= this->section_name_
.c_str();
616 Output_section
* os
= eei
->layout
->find_output_section(section_name
);
619 gold_error("ADDR called on nonexistent output section '%s'",
624 // Note that the address of a section is an absolute address, and we
625 // should not clear *EEI->IS_ABSOLUTE here.
627 return os
->address();
630 extern "C" Expression
*
631 script_exp_function_addr(const char* section_name
, size_t section_name_len
)
633 return new Addr_expression(section_name
, section_name_len
);
636 // CONSTANT. It would be nice if we could simply evaluate this
637 // immediately and return an Integer_expression, but unfortunately we
638 // don't know the target.
640 class Constant_expression
: public Expression
643 Constant_expression(const char* name
, size_t length
);
646 value(const Expression_eval_info
*);
649 print(FILE* f
) const;
652 enum Constant_function
654 CONSTANT_MAXPAGESIZE
,
655 CONSTANT_COMMONPAGESIZE
658 Constant_function function_
;
661 Constant_expression::Constant_expression(const char* name
, size_t length
)
663 if (length
== 11 && strncmp(name
, "MAXPAGESIZE", length
) == 0)
664 this->function_
= CONSTANT_MAXPAGESIZE
;
665 else if (length
== 14 && strncmp(name
, "COMMONPAGESIZE", length
) == 0)
666 this->function_
= CONSTANT_COMMONPAGESIZE
;
669 std::string
s(name
, length
);
670 gold_error(_("unknown constant %s"), s
.c_str());
671 this->function_
= CONSTANT_MAXPAGESIZE
;
676 Constant_expression::value(const Expression_eval_info
*)
678 switch (this->function_
)
680 case CONSTANT_MAXPAGESIZE
:
681 return parameters
->target()->abi_pagesize();
682 case CONSTANT_COMMONPAGESIZE
:
683 return parameters
->target()->common_pagesize();
690 Constant_expression::print(FILE* f
) const
693 switch (this->function_
)
695 case CONSTANT_MAXPAGESIZE
:
696 name
= "MAXPAGESIZE";
698 case CONSTANT_COMMONPAGESIZE
:
699 name
= "COMMONPAGESIZE";
704 fprintf(f
, "CONSTANT(%s)", name
);
707 extern "C" Expression
*
708 script_exp_function_constant(const char* name
, size_t length
)
710 return new Constant_expression(name
, length
);
713 // DATA_SEGMENT_ALIGN. FIXME: we don't implement this; we always fall
714 // back to the general case.
716 extern "C" Expression
*
717 script_exp_function_data_segment_align(Expression
* left
, Expression
*)
719 Expression
* e1
= script_exp_function_align(script_exp_string(".", 1), left
);
720 Expression
* e2
= script_exp_binary_sub(left
, script_exp_integer(1));
721 Expression
* e3
= script_exp_binary_bitwise_and(script_exp_string(".", 1),
723 return script_exp_binary_add(e1
, e3
);
726 // DATA_SEGMENT_RELRO. FIXME: This is not implemented.
728 extern "C" Expression
*
729 script_exp_function_data_segment_relro_end(Expression
*, Expression
* right
)
734 // DATA_SEGMENT_END. FIXME: This is not implemented.
736 extern "C" Expression
*
737 script_exp_function_data_segment_end(Expression
* val
)
744 class Sizeof_headers_expression
: public Expression
747 Sizeof_headers_expression()
751 value(const Expression_eval_info
*);
755 { fprintf(f
, "SIZEOF_HEADERS"); }
759 Sizeof_headers_expression::value(const Expression_eval_info
* eei
)
761 unsigned int ehdr_size
;
762 unsigned int phdr_size
;
763 if (parameters
->get_size() == 32)
765 ehdr_size
= elfcpp::Elf_sizes
<32>::ehdr_size
;
766 phdr_size
= elfcpp::Elf_sizes
<32>::phdr_size
;
768 else if (parameters
->get_size() == 64)
770 ehdr_size
= elfcpp::Elf_sizes
<64>::ehdr_size
;
771 phdr_size
= elfcpp::Elf_sizes
<64>::phdr_size
;
776 return ehdr_size
+ phdr_size
* eei
->layout
->expected_segment_count();
779 extern "C" Expression
*
780 script_exp_function_sizeof_headers()
782 return new Sizeof_headers_expression();
787 extern "C" Expression
*
788 script_exp_function_defined(const char*, size_t)
790 gold_fatal(_("DEFINED not implemented"));
793 extern "C" Expression
*
794 script_exp_function_alignof(const char*, size_t)
796 gold_fatal(_("ALIGNOF not implemented"));
799 extern "C" Expression
*
800 script_exp_function_sizeof(const char*, size_t)
802 gold_fatal(_("SIZEOF not implemented"));
805 extern "C" Expression
*
806 script_exp_function_loadaddr(const char*, size_t)
808 gold_fatal(_("LOADADDR not implemented"));
811 extern "C" Expression
*
812 script_exp_function_origin(const char*, size_t)
814 gold_fatal(_("ORIGIN not implemented"));
817 extern "C" Expression
*
818 script_exp_function_length(const char*, size_t)
820 gold_fatal(_("LENGTH not implemented"));
823 extern "C" Expression
*
824 script_exp_function_absolute(Expression
*)
826 gold_fatal(_("ABSOLUTE not implemented"));
829 extern "C" Expression
*
830 script_exp_function_segment_start(const char*, size_t, Expression
*)
832 gold_fatal(_("SEGMENT_START not implemented"));
835 } // End namespace gold.