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