Parse a SECTIONS clause in a linker script.
[external/binutils.git] / gold / expression.cc
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 "parameters.h"
28 #include "symtab.h"
29 #include "layout.h"
30 #include "output.h"
31 #include "script.h"
32 #include "script-c.h"
33
34 namespace gold
35 {
36
37 // This file holds the code which handles linker expressions.
38
39 // When evaluating the value of an expression, we pass in a pointer to
40 // this struct, so that the expression evaluation can find the
41 // information it needs.
42
43 struct Expression::Expression_eval_info
44 {
45   const Symbol_table* symtab;
46   const Layout* layout;
47 };
48
49 // Evaluate an expression.
50
51 uint64_t
52 Expression::eval(const Symbol_table* symtab, const Layout* layout)
53 {
54   Expression_eval_info eei;
55   eei.symtab = symtab;
56   eei.layout = layout;
57   return this->value(&eei);
58 }
59
60 // A number.
61
62 class Integer_expression : public Expression
63 {
64  public:
65   Integer_expression(uint64_t val)
66     : val_(val)
67   { }
68
69   uint64_t
70   value(const Expression_eval_info*)
71   { return this->val_; }
72
73   void
74   print(FILE* f) const
75   { fprintf(f, "0x%llx", static_cast<unsigned long long>(this->val_)); }
76
77  private:
78   uint64_t val_;
79 };
80
81 extern "C" Expression*
82 script_exp_integer(uint64_t val)
83 {
84   return new Integer_expression(val);
85 }
86
87 // An expression whose value is the value of a symbol.
88
89 class Symbol_expression : public Expression
90 {
91  public:
92   Symbol_expression(const char* name, size_t length)
93     : name_(name, length)
94   { }
95
96   uint64_t
97   value(const Expression_eval_info*);
98
99   void
100   print(FILE* f) const
101   { fprintf(f, "%s", this->name_.c_str()); }
102
103  private:
104   std::string name_;
105 };
106
107 uint64_t
108 Symbol_expression::value(const Expression_eval_info* eei)
109 {
110   Symbol* sym = eei->symtab->lookup(this->name_.c_str());
111   if (sym == NULL || !sym->is_defined())
112     {
113       gold_error(_("undefined symbol '%s' referenced in expression"),
114                  this->name_.c_str());
115       return 0;
116     }
117
118   if (parameters->get_size() == 32)
119     return eei->symtab->get_sized_symbol<32>(sym)->value();
120   else if (parameters->get_size() == 64)
121     return eei->symtab->get_sized_symbol<64>(sym)->value();
122   else
123     gold_unreachable();
124 }
125
126 // An expression whose value is the value of the special symbol ".".
127 // This is only valid within a SECTIONS clause.
128
129 class Dot_expression : public Expression
130 {
131  public:
132   Dot_expression()
133   { }
134
135   uint64_t
136   value(const Expression_eval_info*);
137
138   void
139   print(FILE* f) const
140   { fprintf(f, "."); }
141 };
142
143 uint64_t
144 Dot_expression::value(const Expression_eval_info*)
145 {
146   gold_error("dot symbol unimplemented");
147   return 0;
148 }
149
150 // A string.  This is either the name of a symbol, or ".".
151
152 extern "C" Expression*
153 script_exp_string(const char* name, size_t length)
154 {
155   if (length == 1 && name[0] == '.')
156     return new Dot_expression();
157   else
158     return new Symbol_expression(name, length);
159 }
160
161 // A unary expression.
162
163 class Unary_expression : public Expression
164 {
165  public:
166   Unary_expression(Expression* arg)
167     : arg_(arg)
168   { }
169
170   ~Unary_expression()
171   { delete this->arg_; }
172
173  protected:
174   uint64_t
175   arg_value(const Expression_eval_info* eei) const
176   { return this->arg_->value(eei); }
177
178   void
179   arg_print(FILE* f) const
180   { this->arg_->print(f); }
181
182  private:
183   Expression* arg_;
184 };
185
186 // Handle unary operators.  We use a preprocessor macro as a hack to
187 // capture the C operator.
188
189 #define UNARY_EXPRESSION(NAME, OPERATOR)                        \
190   class Unary_ ## NAME : public Unary_expression                \
191   {                                                             \
192    public:                                                      \
193     Unary_ ## NAME(Expression* arg)                             \
194       : Unary_expression(arg)                                   \
195     { }                                                         \
196                                                                 \
197     uint64_t                                                    \
198     value(const Expression_eval_info* eei)                      \
199     { return OPERATOR this->arg_value(eei); }                   \
200                                                                 \
201     void                                                        \
202     print(FILE* f) const                                        \
203     {                                                           \
204       fprintf(f, "(%s ", #OPERATOR);                            \
205       this->arg_print(f);                                       \
206       fprintf(f, ")");                                          \
207     }                                                           \
208   };                                                            \
209                                                                 \
210   extern "C" Expression*                                        \
211   script_exp_unary_ ## NAME(Expression* arg)                    \
212   {                                                             \
213     return new Unary_ ## NAME(arg);                             \
214   }
215
216 UNARY_EXPRESSION(minus, -)
217 UNARY_EXPRESSION(logical_not, !)
218 UNARY_EXPRESSION(bitwise_not, ~)
219
220 // A binary expression.
221
222 class Binary_expression : public Expression
223 {
224  public:
225   Binary_expression(Expression* left, Expression* right)
226     : left_(left), right_(right)
227   { }
228
229   ~Binary_expression()
230   {
231     delete this->left_;
232     delete this->right_;
233   }
234
235  protected:
236   uint64_t
237   left_value(const Expression_eval_info* eei) const
238   { return this->left_->value(eei); }
239
240   uint64_t
241   right_value(const Expression_eval_info* eei) const
242   { return this->right_->value(eei); }
243
244   void
245   left_print(FILE* f) const
246   { this->left_->print(f); }
247
248   void
249   right_print(FILE* f) const
250   { this->right_->print(f); }
251
252   // This is a call to function FUNCTION_NAME.  Print it.  This is for
253   // debugging.
254   void
255   print_function(FILE* f, const char *function_name) const
256   {
257     fprintf(f, "%s(", function_name);
258     this->left_print(f);
259     fprintf(f, ", ");
260     this->right_print(f);
261     fprintf(f, ")");
262   }
263
264  private:
265   Expression* left_;
266   Expression* right_;
267 };
268
269 // Handle binary operators.  We use a preprocessor macro as a hack to
270 // capture the C operator.
271
272 #define BINARY_EXPRESSION(NAME, OPERATOR)                               \
273   class Binary_ ## NAME : public Binary_expression                      \
274   {                                                                     \
275   public:                                                               \
276     Binary_ ## NAME(Expression* left, Expression* right)                \
277       : Binary_expression(left, right)                                  \
278     { }                                                                 \
279                                                                         \
280     uint64_t                                                            \
281     value(const Expression_eval_info* eei)                              \
282     {                                                                   \
283       return (this->left_value(eei)                                     \
284               OPERATOR this->right_value(eei));                         \
285     }                                                                   \
286                                                                         \
287     void                                                                \
288     print(FILE* f) const                                                \
289     {                                                                   \
290       fprintf(f, "(");                                                  \
291       this->left_print(f);                                              \
292       fprintf(f, " %s ", #OPERATOR);                                    \
293       this->right_print(f);                                             \
294       fprintf(f, ")");                                                  \
295     }                                                                   \
296   };                                                                    \
297                                                                         \
298   extern "C" Expression*                                                \
299   script_exp_binary_ ## NAME(Expression* left, Expression* right)       \
300   {                                                                     \
301     return new Binary_ ## NAME(left, right);                            \
302   }
303
304 BINARY_EXPRESSION(mult, *)
305 BINARY_EXPRESSION(div, /)
306 BINARY_EXPRESSION(mod, %)
307 BINARY_EXPRESSION(add, +)
308 BINARY_EXPRESSION(sub, -)
309 BINARY_EXPRESSION(lshift, <<)
310 BINARY_EXPRESSION(rshift, >>)
311 BINARY_EXPRESSION(eq, ==)
312 BINARY_EXPRESSION(ne, !=)
313 BINARY_EXPRESSION(le, <=)
314 BINARY_EXPRESSION(ge, >=)
315 BINARY_EXPRESSION(lt, <)
316 BINARY_EXPRESSION(gt, >)
317 BINARY_EXPRESSION(bitwise_and, &)
318 BINARY_EXPRESSION(bitwise_xor, ^)
319 BINARY_EXPRESSION(bitwise_or, |)
320 BINARY_EXPRESSION(logical_and, &&)
321 BINARY_EXPRESSION(logical_or, ||)
322
323 // A trinary expression.
324
325 class Trinary_expression : public Expression
326 {
327  public:
328   Trinary_expression(Expression* arg1, Expression* arg2, Expression* arg3)
329     : arg1_(arg1), arg2_(arg2), arg3_(arg3)
330   { }
331
332   ~Trinary_expression()
333   {
334     delete this->arg1_;
335     delete this->arg2_;
336     delete this->arg3_;
337   }
338
339  protected:
340   uint64_t
341   arg1_value(const Expression_eval_info* eei) const
342   { return this->arg1_->value(eei); }
343
344   uint64_t
345   arg2_value(const Expression_eval_info* eei) const
346   { return this->arg2_->value(eei); }
347
348   uint64_t
349   arg3_value(const Expression_eval_info* eei) const
350   { return this->arg3_->value(eei); }
351
352   void
353   arg1_print(FILE* f) const
354   { this->arg1_->print(f); }
355
356   void
357   arg2_print(FILE* f) const
358   { this->arg2_->print(f); }
359
360   void
361   arg3_print(FILE* f) const
362   { this->arg3_->print(f); }
363
364  private:
365   Expression* arg1_;
366   Expression* arg2_;
367   Expression* arg3_;
368 };
369
370 // The conditional operator.
371
372 class Trinary_cond : public Trinary_expression
373 {
374  public:
375   Trinary_cond(Expression* arg1, Expression* arg2, Expression* arg3)
376     : Trinary_expression(arg1, arg2, arg3)
377   { }
378
379   uint64_t
380   value(const Expression_eval_info* eei)
381   {
382     return (this->arg1_value(eei)
383             ? this->arg2_value(eei)
384             : this->arg3_value(eei));
385   }
386
387   void
388   print(FILE* f) const
389   {
390     fprintf(f, "(");
391     this->arg1_print(f);
392     fprintf(f, " ? ");
393     this->arg2_print(f);
394     fprintf(f, " : ");
395     this->arg3_print(f);
396     fprintf(f, ")");
397   }
398 };
399
400 extern "C" Expression*
401 script_exp_trinary_cond(Expression* arg1, Expression* arg2, Expression* arg3)
402 {
403   return new Trinary_cond(arg1, arg2, arg3);
404 }
405
406 // Max function.
407
408 class Max_expression : public Binary_expression
409 {
410  public:
411   Max_expression(Expression* left, Expression* right)
412     : Binary_expression(left, right)
413   { }
414
415   uint64_t
416   value(const Expression_eval_info* eei)
417   { return std::max(this->left_value(eei), this->right_value(eei)); }
418
419   void
420   print(FILE* f) const
421   { this->print_function(f, "MAX"); }
422 };
423
424 extern "C" Expression*
425 script_exp_function_max(Expression* left, Expression* right)
426 {
427   return new Max_expression(left, right);
428 }
429
430 // Min function.
431
432 class Min_expression : public Binary_expression
433 {
434  public:
435   Min_expression(Expression* left, Expression* right)
436     : Binary_expression(left, right)
437   { }
438
439   uint64_t
440   value(const Expression_eval_info* eei)
441   { return std::min(this->left_value(eei), this->right_value(eei)); }
442
443   void
444   print(FILE* f) const
445   { this->print_function(f, "MIN"); }
446 };
447
448 extern "C" Expression*
449 script_exp_function_min(Expression* left, Expression* right)
450 {
451   return new Min_expression(left, right);
452 }
453
454 // Align function.
455
456 class Align_expression : public Binary_expression
457 {
458  public:
459   Align_expression(Expression* left, Expression* right)
460     : Binary_expression(left, right)
461   { }
462
463   uint64_t
464   value(const Expression_eval_info* eei)
465   {
466     uint64_t align = this->right_value(eei);
467     uint64_t value = this->left_value(eei);
468     if (align <= 1)
469       return value;
470     return ((value + align - 1) / align) * align;
471   }
472
473   void
474   print(FILE* f) const
475   { this->print_function(f, "ALIGN"); }
476 };
477
478 extern "C" Expression*
479 script_exp_function_align(Expression* left, Expression* right)
480 {
481   return new Align_expression(left, right);
482 }
483
484 // Assert function.
485
486 class Assert_expression : public Unary_expression
487 {
488  public:
489   Assert_expression(Expression* arg, const char* message, size_t length)
490     : Unary_expression(arg), message_(message, length)
491   { }
492
493   uint64_t
494   value(const Expression_eval_info* eei)
495   {
496     uint64_t value = this->arg_value(eei);
497     if (!value)
498       gold_error("%s", this->message_.c_str());
499     return value;
500   }
501
502   void
503   print(FILE* f) const
504   {
505     fprintf(f, "ASSERT(");
506     this->arg_print(f);
507     fprintf(f, ", %s)", this->message_.c_str());
508   }
509
510  private:
511   std::string message_;
512 };
513
514 extern "C" Expression*
515 script_exp_function_assert(Expression* expr, const char* message,
516                            size_t length)
517 {
518   return new Assert_expression(expr, message, length);
519 }
520
521 // Addr function.
522
523 class Addr_expression : public Expression
524 {
525  public:
526   Addr_expression(const char* section_name, size_t section_name_len)
527     : section_name_(section_name, section_name_len)
528   { }
529
530   uint64_t
531   value(const Expression_eval_info*);
532
533   void
534   print(FILE* f) const
535   { fprintf(f, "ADDR(%s)", this->section_name_.c_str()); }
536
537  private:
538   std::string section_name_;
539 };
540
541 uint64_t
542 Addr_expression::value(const Expression_eval_info* eei)
543 {
544   const char* section_name = this->section_name_.c_str();
545   Output_section* os = eei->layout->find_output_section(section_name);
546   if (os == NULL)
547     {
548       gold_error("ADDR called on nonexistent output section '%s'",
549                  section_name);
550       return 0;
551     }
552   return os->address();
553 }
554
555 extern "C" Expression*
556 script_exp_function_addr(const char* section_name, size_t section_name_len)
557 {
558   return new Addr_expression(section_name, section_name_len);
559 }
560
561 // Functions.
562
563 extern "C" Expression*
564 script_exp_function_defined(const char*, size_t)
565 {
566   gold_fatal(_("DEFINED not implemented"));
567 }
568
569 extern "C" Expression*
570 script_exp_function_sizeof_headers()
571 {
572   gold_fatal(_("SIZEOF_HEADERS not implemented"));
573 }
574
575 extern "C" Expression*
576 script_exp_function_alignof(const char*, size_t)
577 {
578   gold_fatal(_("ALIGNOF not implemented"));
579 }
580
581 extern "C" Expression*
582 script_exp_function_sizeof(const char*, size_t)
583 {
584   gold_fatal(_("SIZEOF not implemented"));
585 }
586
587 extern "C" Expression*
588 script_exp_function_loadaddr(const char*, size_t)
589 {
590   gold_fatal(_("LOADADDR not implemented"));
591 }
592
593 extern "C" Expression*
594 script_exp_function_origin(const char*, size_t)
595 {
596   gold_fatal(_("ORIGIN not implemented"));
597 }
598
599 extern "C" Expression*
600 script_exp_function_length(const char*, size_t)
601 {
602   gold_fatal(_("LENGTH not implemented"));
603 }
604
605 extern "C" Expression*
606 script_exp_function_constant(const char*, size_t)
607 {
608   gold_fatal(_("CONSTANT not implemented"));
609 }
610
611 extern "C" Expression*
612 script_exp_function_absolute(Expression*)
613 {
614   gold_fatal(_("ABSOLUTE not implemented"));
615 }
616
617 extern "C" Expression*
618 script_exp_function_data_segment_align(Expression*, Expression*)
619 {
620   gold_fatal(_("DATA_SEGMENT_ALIGN not implemented"));
621 }
622
623 extern "C" Expression*
624 script_exp_function_data_segment_relro_end(Expression*, Expression*)
625 {
626   gold_fatal(_("DATA_SEGMENT_RELRO_END not implemented"));
627 }
628
629 extern "C" Expression*
630 script_exp_function_data_segment_end(Expression*)
631 {
632   gold_fatal(_("DATA_SEGMENT_END not implemented"));
633 }
634
635 extern "C" Expression*
636 script_exp_function_segment_start(const char*, size_t, Expression*)
637 {
638   gold_fatal(_("SEGMENT_START not implemented"));
639 }
640
641 } // End namespace gold.