* elf32-spu.c (spu_elf_relocate_section): Correct return type.
[deliverable/binutils-gdb.git] / gold / script-sections.cc
CommitLineData
494e05f4
ILT
1// script-sections.cc -- linker script SECTIONS for gold
2
3// Copyright 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#include <vector>
27
28#include "script-c.h"
29#include "script.h"
30#include "script-sections.h"
31
32// Support for the SECTIONS clause in linker scripts.
33
34namespace gold
35{
36
37// An element in a SECTIONS clause.
38
39class Sections_element
40{
41 public:
42 Sections_element()
43 { }
44
45 virtual ~Sections_element()
46 { }
47
48 virtual void
49 print(FILE* f) const = 0;
50};
51
52// An assignment in a SECTIONS clause outside of an output section.
53
54class Sections_element_assignment : public Sections_element
55{
56 public:
57 Sections_element_assignment(const char* name, size_t namelen,
58 Expression* val, bool provide, bool hidden)
59 : assignment_(name, namelen, val, provide, hidden)
60 { }
61
62 void
63 print(FILE* f) const
64 {
65 fprintf(f, " ");
66 this->assignment_.print(f);
67 }
68
69 private:
70 Symbol_assignment assignment_;
71};
72
73// An assertion in a SECTIONS clause outside of an output section.
74
75class Sections_element_assertion : public Sections_element
76{
77 public:
78 Sections_element_assertion(Expression* check, const char* message,
79 size_t messagelen)
80 : assertion_(check, message, messagelen)
81 { }
82
83 void
84 print(FILE* f) const
85 {
86 fprintf(f, " ");
87 this->assertion_.print(f);
88 }
89
90 private:
91 Script_assertion assertion_;
92};
93
94// An element in an output section in a SECTIONS clause.
95
96class Output_section_element
97{
98 public:
99 Output_section_element()
100 { }
101
102 virtual ~Output_section_element()
103 { }
104
105 virtual void
106 print(FILE* f) const = 0;
107};
108
109// A symbol assignment in an output section.
110
111class Output_section_element_assignment : public Output_section_element
112{
113 public:
114 Output_section_element_assignment(const char* name, size_t namelen,
115 Expression* val, bool provide,
116 bool hidden)
117 : assignment_(name, namelen, val, provide, hidden)
118 { }
119
120 void
121 print(FILE* f) const
122 {
123 fprintf(f, " ");
124 this->assignment_.print(f);
125 }
126
127 private:
128 Symbol_assignment assignment_;
129};
130
131// An assertion in an output section.
132
133class Output_section_element_assertion : public Output_section_element
134{
135 public:
136 Output_section_element_assertion(Expression* check, const char* message,
137 size_t messagelen)
138 : assertion_(check, message, messagelen)
139 { }
140
141 void
142 print(FILE* f) const
143 {
144 fprintf(f, " ");
145 this->assertion_.print(f);
146 }
147
148 private:
149 Script_assertion assertion_;
150};
151
152// A data item in an output section.
153
154class Output_section_element_data : public Output_section_element
155{
156 public:
157 Output_section_element_data(int size, bool is_signed, Expression* val)
158 : size_(size), is_signed_(is_signed), val_(val)
159 { }
160
161 void
162 print(FILE*) const;
163
164 private:
165 // The size in bytes.
166 int size_;
167 // Whether the value is signed.
168 bool is_signed_;
169 // The value.
170 Expression* val_;
171};
172
173// Print for debugging.
174
175void
176Output_section_element_data::print(FILE* f) const
177{
178 const char* s;
179 switch (this->size_)
180 {
181 case 1:
182 s = "BYTE";
183 break;
184 case 2:
185 s = "SHORT";
186 break;
187 case 4:
188 s = "LONG";
189 break;
190 case 8:
191 if (this->is_signed_)
192 s = "SQUAD";
193 else
194 s = "QUAD";
195 break;
196 default:
197 gold_unreachable();
198 }
199 fprintf(f, " %s(", s);
200 this->val_->print(f);
201 fprintf(f, ")\n");
202}
203
204// A fill value setting in an output section.
205
206class Output_section_element_fill : public Output_section_element
207{
208 public:
209 Output_section_element_fill(Expression* val)
210 : val_(val)
211 { }
212
213 void
214 print(FILE* f) const
215 {
216 fprintf(f, " FILL(");
217 this->val_->print(f);
218 fprintf(f, ")\n");
219 }
220
221 private:
222 // The new fill value.
223 Expression* val_;
224};
225
226// An input section specification in an output section
227
228class Output_section_element_input : public Output_section_element
229{
230 public:
231 // Note that an Input_section_spec holds some pointers to vectors.
232 // This constructor takes ownership of them. The parser is
233 // implemented such that this works.
234 Output_section_element_input(const Input_section_spec* spec, bool keep);
235
236 void
237 print(FILE* f) const;
238
239 private:
240 // An input section pattern.
241 struct Input_section_pattern
242 {
243 std::string pattern;
244 Sort_wildcard sort;
245
246 Input_section_pattern(const char* patterna, size_t patternlena,
247 Sort_wildcard sorta)
248 : pattern(patterna, patternlena), sort(sorta)
249 { }
250 };
251
252 typedef std::vector<Input_section_pattern> Input_section_patterns;
253
254 typedef std::vector<std::string> Filename_exclusions;
255
256 // The file name pattern.
257 std::string filename_pattern_;
258 // How the file names should be sorted. This may only be
259 // SORT_WILDCARD_NONE or SORT_WILDCARD_BY_NAME.
260 Sort_wildcard filename_sort_;
261 // The list of file names to exclude.
262 Filename_exclusions filename_exclusions_;
263 // The list of input section patterns.
264 Input_section_patterns input_section_patterns_;
265 // Whether to keep this section when garbage collecting.
266 bool keep_;
267};
268
269// Construct Output_section_element_input. The parser records strings
270// as pointers into a copy of the script file, which will go away when
271// parsing is complete. We make sure they are in std::string objects.
272
273Output_section_element_input::Output_section_element_input(
274 const Input_section_spec* spec,
275 bool keep)
276 : filename_pattern_(spec->file.name.value, spec->file.name.length),
277 filename_sort_(spec->file.sort),
278 filename_exclusions_(),
279 input_section_patterns_(),
280 keep_(keep)
281{
282 if (spec->input_sections.exclude != NULL)
283 {
284 for (String_list::const_iterator p =
285 spec->input_sections.exclude->begin();
286 p != spec->input_sections.exclude->end();
287 ++p)
288 this->filename_exclusions_.push_back(*p);
289 }
290
291 if (spec->input_sections.sections != NULL)
292 {
293 Input_section_patterns& isp(this->input_section_patterns_);
294 for (String_sort_list::const_iterator p =
295 spec->input_sections.sections->begin();
296 p != spec->input_sections.sections->end();
297 ++p)
298 isp.push_back(Input_section_pattern(p->name.value, p->name.length,
299 p->sort));
300 }
301}
302
303// Print for debugging.
304
305void
306Output_section_element_input::print(FILE* f) const
307{
308 fprintf(f, " ");
309
310 if (this->keep_)
311 fprintf(f, "KEEP(");
312
313 if (!this->filename_pattern_.empty())
314 {
315 bool need_close_paren = false;
316 switch (this->filename_sort_)
317 {
318 case SORT_WILDCARD_NONE:
319 break;
320 case SORT_WILDCARD_BY_NAME:
321 fprintf(f, "SORT_BY_NAME(");
322 need_close_paren = true;
323 break;
324 default:
325 gold_unreachable();
326 }
327
328 fprintf(f, "%s", this->filename_pattern_.c_str());
329
330 if (need_close_paren)
331 fprintf(f, ")");
332 }
333
334 if (!this->input_section_patterns_.empty()
335 || !this->filename_exclusions_.empty())
336 {
337 fprintf(f, "(");
338
339 bool need_space = false;
340 if (!this->filename_exclusions_.empty())
341 {
342 fprintf(f, "EXCLUDE_FILE(");
343 bool need_comma = false;
344 for (Filename_exclusions::const_iterator p =
345 this->filename_exclusions_.begin();
346 p != this->filename_exclusions_.end();
347 ++p)
348 {
349 if (need_comma)
350 fprintf(f, ", ");
351 fprintf(f, "%s", p->c_str());
352 need_comma = true;
353 }
354 fprintf(f, ")");
355 need_space = true;
356 }
357
358 for (Input_section_patterns::const_iterator p =
359 this->input_section_patterns_.begin();
360 p != this->input_section_patterns_.end();
361 ++p)
362 {
363 if (need_space)
364 fprintf(f, " ");
365
366 int close_parens = 0;
367 switch (p->sort)
368 {
369 case SORT_WILDCARD_NONE:
370 break;
371 case SORT_WILDCARD_BY_NAME:
372 fprintf(f, "SORT_BY_NAME(");
373 close_parens = 1;
374 break;
375 case SORT_WILDCARD_BY_ALIGNMENT:
376 fprintf(f, "SORT_BY_ALIGNMENT(");
377 close_parens = 1;
378 break;
379 case SORT_WILDCARD_BY_NAME_BY_ALIGNMENT:
380 fprintf(f, "SORT_BY_NAME(SORT_BY_ALIGNMENT(");
381 close_parens = 2;
382 break;
383 case SORT_WILDCARD_BY_ALIGNMENT_BY_NAME:
384 fprintf(f, "SORT_BY_ALIGNMENT(SORT_BY_NAME(");
385 close_parens = 2;
386 break;
387 default:
388 gold_unreachable();
389 }
390
391 fprintf(f, "%s", p->pattern.c_str());
392
393 for (int i = 0; i < close_parens; ++i)
394 fprintf(f, ")");
395
396 need_space = true;
397 }
398
399 fprintf(f, ")");
400 }
401
402 if (this->keep_)
403 fprintf(f, ")");
404
405 fprintf(f, "\n");
406}
407
408// An output section.
409
410class Output_section_definition : public Sections_element
411{
412 public:
413 Output_section_definition(const char* name, size_t namelen,
414 const Parser_output_section_header* header);
415
416 // Finish the output section with the information in the trailer.
417 void
418 finish(const Parser_output_section_trailer* trailer);
419
420 // Add a symbol to be defined.
421 void
422 add_symbol_assignment(const char* name, size_t length, Expression* value,
423 bool provide, bool hidden);
424 // Add an assertion.
425 void
426 add_assertion(Expression* check, const char* message, size_t messagelen);
427
428 // Add a data item to the current output section.
429 void
430 add_data(int size, bool is_signed, Expression* val);
431
432 // Add a setting for the fill value.
433 void
434 add_fill(Expression* val);
435
436 // Add an input section specification.
437 void
438 add_input_section(const Input_section_spec* spec, bool keep);
439
440 // Print the contents to the FILE. This is for debugging.
441 void
442 print(FILE*) const;
443
444 private:
445 typedef std::vector<Output_section_element*> Output_section_elements;
446
447 // The output section name.
448 std::string name_;
449 // The address. This may be NULL.
450 Expression* address_;
451 // The load address. This may be NULL.
452 Expression* load_address_;
453 // The alignment. This may be NULL.
454 Expression* align_;
455 // The input section alignment. This may be NULL.
456 Expression* subalign_;
457 // The fill value. This may be NULL.
458 Expression* fill_;
459 // The list of elements defining the section.
460 Output_section_elements elements_;
461};
462
463// Constructor.
464
465Output_section_definition::Output_section_definition(
466 const char* name,
467 size_t namelen,
468 const Parser_output_section_header* header)
469 : name_(name, namelen),
470 address_(header->address),
471 load_address_(header->load_address),
472 align_(header->align),
473 subalign_(header->subalign),
474 fill_(NULL),
475 elements_()
476{
477}
478
479// Finish an output section.
480
481void
482Output_section_definition::finish(const Parser_output_section_trailer* trailer)
483{
484 this->fill_ = trailer->fill;
485}
486
487// Add a symbol to be defined.
488
489void
490Output_section_definition::add_symbol_assignment(const char* name,
491 size_t length,
492 Expression* value,
493 bool provide,
494 bool hidden)
495{
496 Output_section_element* p = new Output_section_element_assignment(name,
497 length,
498 value,
499 provide,
500 hidden);
501 this->elements_.push_back(p);
502}
503
504// Add an assertion.
505
506void
507Output_section_definition::add_assertion(Expression* check,
508 const char* message,
509 size_t messagelen)
510{
511 Output_section_element* p = new Output_section_element_assertion(check,
512 message,
513 messagelen);
514 this->elements_.push_back(p);
515}
516
517// Add a data item to the current output section.
518
519void
520Output_section_definition::add_data(int size, bool is_signed, Expression* val)
521{
522 Output_section_element* p = new Output_section_element_data(size, is_signed,
523 val);
524 this->elements_.push_back(p);
525}
526
527// Add a setting for the fill value.
528
529void
530Output_section_definition::add_fill(Expression* val)
531{
532 Output_section_element* p = new Output_section_element_fill(val);
533 this->elements_.push_back(p);
534}
535
536// Add an input section specification.
537
538void
539Output_section_definition::add_input_section(const Input_section_spec* spec,
540 bool keep)
541{
542 Output_section_element* p = new Output_section_element_input(spec, keep);
543 this->elements_.push_back(p);
544}
545
546// Print for debugging.
547
548void
549Output_section_definition::print(FILE* f) const
550{
551 fprintf(f, " %s ", this->name_.c_str());
552
553 if (this->address_ != NULL)
554 {
555 this->address_->print(f);
556 fprintf(f, " ");
557 }
558
559 fprintf(f, ": ");
560
561 if (this->load_address_ != NULL)
562 {
563 fprintf(f, "AT(");
564 this->load_address_->print(f);
565 fprintf(f, ") ");
566 }
567
568 if (this->align_ != NULL)
569 {
570 fprintf(f, "ALIGN(");
571 this->align_->print(f);
572 fprintf(f, ") ");
573 }
574
575 if (this->subalign_ != NULL)
576 {
577 fprintf(f, "SUBALIGN(");
578 this->subalign_->print(f);
579 fprintf(f, ") ");
580 }
581
582 fprintf(f, "{\n");
583
584 for (Output_section_elements::const_iterator p = this->elements_.begin();
585 p != this->elements_.end();
586 ++p)
587 (*p)->print(f);
588
589 fprintf(f, " }");
590
591 if (this->fill_ != NULL)
592 {
593 fprintf(f, " = ");
594 this->fill_->print(f);
595 }
596
597 fprintf(f, "\n");
598}
599
600// Class Script_sections.
601
602Script_sections::Script_sections()
603 : saw_sections_clause_(false),
604 in_sections_clause_(false),
605 sections_elements_(NULL),
606 output_section_(NULL)
607{
608}
609
610// Start a SECTIONS clause.
611
612void
613Script_sections::start_sections()
614{
615 gold_assert(!this->in_sections_clause_ && this->output_section_ == NULL);
616 this->saw_sections_clause_ = true;
617 this->in_sections_clause_ = true;
618 if (this->sections_elements_ == NULL)
619 this->sections_elements_ = new Sections_elements;
620}
621
622// Finish a SECTIONS clause.
623
624void
625Script_sections::finish_sections()
626{
627 gold_assert(this->in_sections_clause_ && this->output_section_ == NULL);
628 this->in_sections_clause_ = false;
629}
630
631// Add a symbol to be defined.
632
633void
634Script_sections::add_symbol_assignment(const char* name, size_t length,
635 Expression* val, bool provide,
636 bool hidden)
637{
638 if (this->output_section_ != NULL)
639 this->output_section_->add_symbol_assignment(name, length, val,
640 provide, hidden);
641 else
642 {
643 Sections_element* p = new Sections_element_assignment(name, length,
644 val, provide,
645 hidden);
646 this->sections_elements_->push_back(p);
647 }
648}
649
650// Add an assertion.
651
652void
653Script_sections::add_assertion(Expression* check, const char* message,
654 size_t messagelen)
655{
656 if (this->output_section_ != NULL)
657 this->output_section_->add_assertion(check, message, messagelen);
658 else
659 {
660 Sections_element* p = new Sections_element_assertion(check, message,
661 messagelen);
662 this->sections_elements_->push_back(p);
663 }
664}
665
666// Start processing entries for an output section.
667
668void
669Script_sections::start_output_section(
670 const char* name,
671 size_t namelen,
672 const Parser_output_section_header *header)
673{
674 Output_section_definition* posd = new Output_section_definition(name,
675 namelen,
676 header);
677 this->sections_elements_->push_back(posd);
678 gold_assert(this->output_section_ == NULL);
679 this->output_section_ = posd;
680}
681
682// Stop processing entries for an output section.
683
684void
685Script_sections::finish_output_section(
686 const Parser_output_section_trailer* trailer)
687{
688 gold_assert(this->output_section_ != NULL);
689 this->output_section_->finish(trailer);
690 this->output_section_ = NULL;
691}
692
693// Add a data item to the current output section.
694
695void
696Script_sections::add_data(int size, bool is_signed, Expression* val)
697{
698 gold_assert(this->output_section_ != NULL);
699 this->output_section_->add_data(size, is_signed, val);
700}
701
702// Add a fill value setting to the current output section.
703
704void
705Script_sections::add_fill(Expression* val)
706{
707 gold_assert(this->output_section_ != NULL);
708 this->output_section_->add_fill(val);
709}
710
711// Add an input section specification to the current output section.
712
713void
714Script_sections::add_input_section(const Input_section_spec* spec, bool keep)
715{
716 gold_assert(this->output_section_ != NULL);
717 this->output_section_->add_input_section(spec, keep);
718}
719
720// Print the SECTIONS clause to F for debugging.
721
722void
723Script_sections::print(FILE* f) const
724{
725 if (!this->saw_sections_clause_)
726 return;
727
728 fprintf(f, "SECTIONS {\n");
729
730 for (Sections_elements::const_iterator p = this->sections_elements_->begin();
731 p != this->sections_elements_->end();
732 ++p)
733 (*p)->print(f);
734
735 fprintf(f, "}\n");
736}
737
738} // End namespace gold.
This page took 0.050703 seconds and 4 git commands to generate.