Add infrastructure for threading support.
[deliverable/binutils-gdb.git] / gold / options.h
1 // options.h -- handle command line options for gold -*- C++ -*-
2
3 // Copyright 2006, 2007 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 // Command_line
24 // Holds everything we get from the command line.
25 // General_options (from Command_line::options())
26 // Options which are not position dependent.
27 // Input_argument (from Command_line::inputs())
28 // The list of input files, including -l options.
29 // Position_dependent_options (from Input_argument::options())
30 // Position dependent options which apply to this argument.
31
32 #ifndef GOLD_OPTIONS_H
33 #define GOLD_OPTIONS_H
34
35 #include <cstdlib>
36 #include <list>
37 #include <string>
38 #include <vector>
39
40 namespace gold
41 {
42
43 class Command_line;
44 class Input_file_group;
45
46 namespace options {
47
48 class Command_line_options;
49 struct One_option;
50
51 } // End namespace gold::options.
52
53 // A directory to search. For each directory we record whether it is
54 // in the sysroot. We need to know this so that, if a linker script
55 // is found within the sysroot, we will apply the sysroot to any files
56 // named by that script.
57
58 class Search_directory
59 {
60 public:
61 // We need a default constructor because we put this in a
62 // std::vector.
63 Search_directory()
64 : name_(NULL), put_in_sysroot_(false), is_in_sysroot_(false)
65 { }
66
67 // This is the usual constructor.
68 Search_directory(const char* name, bool put_in_sysroot)
69 : name_(name), put_in_sysroot_(put_in_sysroot), is_in_sysroot_(false)
70 { gold_assert(!this->name_.empty()); }
71
72 // This is called if we have a sysroot. The sysroot is prefixed to
73 // any entries for which put_in_sysroot_ is true. is_in_sysroot_ is
74 // set to true for any enries which are in the sysroot (this will
75 // naturally include any entries for which put_in_sysroot_ is true).
76 // SYSROOT is the sysroot, CANONICAL_SYSROOT is the result of
77 // passing SYSROOT to lrealpath.
78 void
79 add_sysroot(const char* sysroot, const char* canonical_sysroot);
80
81 // Get the directory name.
82 const std::string&
83 name() const
84 { return this->name_; }
85
86 // Return whether this directory is in the sysroot.
87 bool
88 is_in_sysroot() const
89 { return this->is_in_sysroot_; }
90
91 private:
92 std::string name_;
93 bool put_in_sysroot_;
94 bool is_in_sysroot_;
95 };
96
97 // The position independent options which apply to the whole link.
98 // There are a lot of them.
99
100 class General_options
101 {
102 public:
103 General_options();
104
105 // -E: export dynamic symbols.
106 bool
107 export_dynamic() const
108 { return this->export_dynamic_; }
109
110 // -I: dynamic linker name.
111 const char*
112 dynamic_linker() const
113 { return this->dynamic_linker_; }
114
115 // -L: Library search path.
116 typedef std::vector<Search_directory> Dir_list;
117
118 const Dir_list&
119 search_path() const
120 { return this->search_path_; }
121
122 // -O: optimization level (0: don't try to optimize output size).
123 int
124 optimization_level() const
125 { return this->optimization_level_; }
126
127 // -o: Output file name.
128 const char*
129 output_file_name() const
130 { return this->output_file_name_; }
131
132 // -r: Whether we are doing a relocatable link.
133 bool
134 is_relocatable() const
135 { return this->is_relocatable_; }
136
137 // -s: Strip all symbols.
138 bool
139 strip_all() const
140 { return this->strip_ == STRIP_ALL; }
141
142 // -S: Strip debugging information.
143 bool
144 strip_debug() const
145 { return this->strip_ == STRIP_ALL || this->strip_ == STRIP_DEBUG; }
146
147 // --eh-frame-hdr: Whether to generate an exception frame header.
148 bool
149 create_eh_frame_hdr() const
150 { return this->create_eh_frame_hdr_; }
151
152 // --rpath: The runtime search path.
153 const Dir_list&
154 rpath() const
155 { return this->rpath_; }
156
157 // --rpath-link: The link time search patch for shared libraries.
158 const Dir_list&
159 rpath_link() const
160 { return this->rpath_link_; }
161
162 // --shared: Whether generating a shared object.
163 bool
164 is_shared() const
165 { return this->is_shared_; }
166
167 // --static: Whether doing a static link.
168 bool
169 is_static() const
170 { return this->is_static_; }
171
172 // --stats: Print resource usage statistics.
173 bool
174 print_stats() const
175 { return this->print_stats_; }
176
177 // --sysroot: The system root of a cross-linker.
178 const std::string&
179 sysroot() const
180 { return this->sysroot_; }
181
182 // -Ttext: The address of the .text section
183 uint64_t
184 text_segment_address() const
185 { return this->text_segment_address_; }
186
187 // Whether -Ttext was used.
188 bool
189 user_set_text_segment_address() const
190 { return this->text_segment_address_ != -1U; }
191
192 // --threads: Whether to use threads.
193 bool
194 threads() const
195 { return this->threads_; }
196
197 // --thread-count-initial: Threads to use in initial pass.
198 int
199 thread_count_initial() const
200 { return this->thread_count_initial_; }
201
202 // --thread-count-middle: Threads to use in middle pass.
203 int
204 thread_count_middle() const
205 { return this->thread_count_middle_; }
206
207 // --thread-count-final: Threads to use in final pass.
208 int
209 thread_count_final() const
210 { return this->thread_count_final_; }
211
212 private:
213 // Don't copy this structure.
214 General_options(const General_options&);
215 General_options& operator=(const General_options&);
216
217 friend class Command_line;
218 friend class options::Command_line_options;
219
220 // Which symbols to strip.
221 enum Strip
222 {
223 // Don't strip any symbols.
224 STRIP_NONE,
225 // Strip all symbols.
226 STRIP_ALL,
227 // Strip debugging information.
228 STRIP_DEBUG
229 };
230
231 void
232 set_export_dynamic()
233 { this->export_dynamic_ = true; }
234
235 void
236 set_dynamic_linker(const char* arg)
237 { this->dynamic_linker_ = arg; }
238
239 void
240 add_to_search_path(const char* arg)
241 { this->search_path_.push_back(Search_directory(arg, false)); }
242
243 void
244 add_to_search_path_with_sysroot(const char* arg)
245 { this->search_path_.push_back(Search_directory(arg, true)); }
246
247 void
248 set_optimization_level(const char* arg)
249 { this->optimization_level_ = atoi(arg); }
250
251 void
252 set_output_file_name(const char* arg)
253 { this->output_file_name_ = arg; }
254
255 void
256 set_relocatable()
257 { this->is_relocatable_ = true; }
258
259 void
260 set_strip_all()
261 { this->strip_ = STRIP_ALL; }
262
263 // Note: normalize_options() depends on the fact that this turns off
264 // STRIP_ALL if it were already set.
265 void
266 set_strip_debug()
267 { this->strip_ = STRIP_DEBUG; }
268
269 void
270 set_create_eh_frame_hdr()
271 { this->create_eh_frame_hdr_ = true; }
272
273 void
274 add_to_rpath(const char* arg)
275 { this->rpath_.push_back(Search_directory(arg, false)); }
276
277 void
278 add_to_rpath_link(const char* arg)
279 { this->rpath_link_.push_back(Search_directory(arg, false)); }
280
281 void
282 set_shared()
283 { this->is_shared_ = true; }
284
285 void
286 set_static()
287 { this->is_static_ = true; }
288
289 void
290 set_stats()
291 { this->print_stats_ = true; }
292
293 void
294 set_sysroot(const char* arg)
295 { this->sysroot_ = arg; }
296
297 void
298 set_text_segment_address(const char* arg)
299 {
300 char* endptr;
301 this->text_segment_address_ = strtoull(arg, &endptr, 0);
302 if (*endptr != '\0'
303 || this->text_segment_address_ == -1U)
304 {
305 fprintf(stderr, _("%s: invalid argument to -Ttext: %s\n"),
306 program_name, arg);
307 ::exit(1);
308 }
309 }
310
311 int
312 parse_thread_count(const char* arg)
313 {
314 char* endptr;
315 int count = strtol(arg, &endptr, 0);
316 if (*endptr != '\0' || count < 0)
317 {
318 fprintf(stderr, _("%s: invalid thread count: %s\n"),
319 program_name, arg);
320 ::exit(1);
321 }
322 return count;
323 }
324
325 void
326 set_threads()
327 { this->threads_ = true; }
328
329 void
330 clear_threads()
331 { this->threads_ = false; }
332
333 void
334 set_thread_count(const char* arg)
335 {
336 int count = this->parse_thread_count(arg);
337 this->thread_count_initial_ = count;
338 this->thread_count_middle_ = count;
339 this->thread_count_final_ = count;
340 }
341
342 void
343 set_thread_count_initial(const char* arg)
344 { this->thread_count_initial_ = this->parse_thread_count(arg); }
345
346 void
347 set_thread_count_middle(const char* arg)
348 { this->thread_count_initial_ = this->parse_thread_count(arg); }
349
350 void
351 set_thread_count_final(const char* arg)
352 { this->thread_count_initial_ = this->parse_thread_count(arg); }
353
354 void
355 ignore(const char*)
356 { }
357
358 // Apply any sysroot to the directory lists.
359 void
360 add_sysroot();
361
362 bool export_dynamic_;
363 const char* dynamic_linker_;
364 Dir_list search_path_;
365 int optimization_level_;
366 const char* output_file_name_;
367 bool is_relocatable_;
368 Strip strip_;
369 bool create_eh_frame_hdr_;
370 Dir_list rpath_;
371 Dir_list rpath_link_;
372 bool is_shared_;
373 bool is_static_;
374 bool print_stats_;
375 std::string sysroot_;
376 uint64_t text_segment_address_;
377 bool threads_;
378 int thread_count_initial_;
379 int thread_count_middle_;
380 int thread_count_final_;
381 };
382
383 // The current state of the position dependent options.
384
385 class Position_dependent_options
386 {
387 public:
388 Position_dependent_options();
389
390 // -Bstatic: Whether we are searching for a static archive rather
391 // than a shared object.
392 bool
393 do_static_search() const
394 { return this->do_static_search_; }
395
396 // --as-needed: Whether to add a DT_NEEDED argument only if the
397 // dynamic object is used.
398 bool
399 as_needed() const
400 { return this->as_needed_; }
401
402 // --whole-archive: Whether to include the entire contents of an
403 // --archive.
404 bool
405 include_whole_archive() const
406 { return this->include_whole_archive_; }
407
408 void
409 set_static_search()
410 { this->do_static_search_ = true; }
411
412 void
413 set_dynamic_search()
414 { this->do_static_search_ = false; }
415
416 void
417 set_as_needed()
418 { this->as_needed_ = true; }
419
420 void
421 clear_as_needed()
422 { this->as_needed_ = false; }
423
424 void
425 set_whole_archive()
426 { this->include_whole_archive_ = true; }
427
428 void
429 clear_whole_archive()
430 { this->include_whole_archive_ = false; }
431
432 private:
433 bool do_static_search_;
434 bool as_needed_;
435 bool include_whole_archive_;
436 };
437
438 // A single file or library argument from the command line.
439
440 class Input_file_argument
441 {
442 public:
443 // name: file name or library name
444 // is_lib: true if name is a library name: that is, emits the leading
445 // "lib" and trailing ".so"/".a" from the name
446 // extra_search_path: an extra directory to look for the file, prior
447 // to checking the normal library search path. If this is "",
448 // then no extra directory is added.
449 // options: The position dependent options at this point in the
450 // command line, such as --whole-archive.
451 Input_file_argument()
452 : name_(), is_lib_(false), extra_search_path_(""), options_()
453 { }
454
455 Input_file_argument(const char* name, bool is_lib,
456 const char* extra_search_path,
457 const Position_dependent_options& options)
458 : name_(name), is_lib_(is_lib), extra_search_path_(extra_search_path),
459 options_(options)
460 { }
461
462 const char*
463 name() const
464 { return this->name_.c_str(); }
465
466 const Position_dependent_options&
467 options() const
468 { return this->options_; }
469
470 bool
471 is_lib() const
472 { return this->is_lib_; }
473
474 const char*
475 extra_search_path() const
476 {
477 return (this->extra_search_path_.empty()
478 ? NULL
479 : this->extra_search_path_.c_str());
480 }
481
482 // Return whether this file may require a search using the -L
483 // options.
484 bool
485 may_need_search() const
486 { return this->is_lib_ || !this->extra_search_path_.empty(); }
487
488 private:
489 // We use std::string, not const char*, here for convenience when
490 // using script files, so that we do not have to preserve the string
491 // in that case.
492 std::string name_;
493 bool is_lib_;
494 std::string extra_search_path_;
495 Position_dependent_options options_;
496 };
497
498 // A file or library, or a group, from the command line.
499
500 class Input_argument
501 {
502 public:
503 // Create a file or library argument.
504 explicit Input_argument(Input_file_argument file)
505 : is_file_(true), file_(file), group_(NULL)
506 { }
507
508 // Create a group argument.
509 explicit Input_argument(Input_file_group* group)
510 : is_file_(false), group_(group)
511 { }
512
513 // Return whether this is a file.
514 bool
515 is_file() const
516 { return this->is_file_; }
517
518 // Return whether this is a group.
519 bool
520 is_group() const
521 { return !this->is_file_; }
522
523 // Return the information about the file.
524 const Input_file_argument&
525 file() const
526 {
527 gold_assert(this->is_file_);
528 return this->file_;
529 }
530
531 // Return the information about the group.
532 const Input_file_group*
533 group() const
534 {
535 gold_assert(!this->is_file_);
536 return this->group_;
537 }
538
539 Input_file_group*
540 group()
541 {
542 gold_assert(!this->is_file_);
543 return this->group_;
544 }
545
546 private:
547 bool is_file_;
548 Input_file_argument file_;
549 Input_file_group* group_;
550 };
551
552 // A group from the command line. This is a set of arguments within
553 // --start-group ... --end-group.
554
555 class Input_file_group
556 {
557 public:
558 typedef std::vector<Input_argument> Files;
559 typedef Files::const_iterator const_iterator;
560
561 Input_file_group()
562 : files_()
563 { }
564
565 // Add a file to the end of the group.
566 void
567 add_file(const Input_file_argument& arg)
568 { this->files_.push_back(Input_argument(arg)); }
569
570 // Iterators to iterate over the group contents.
571
572 const_iterator
573 begin() const
574 { return this->files_.begin(); }
575
576 const_iterator
577 end() const
578 { return this->files_.end(); }
579
580 private:
581 Files files_;
582 };
583
584 // A list of files from the command line or a script.
585
586 class Input_arguments
587 {
588 public:
589 typedef std::vector<Input_argument> Input_argument_list;
590 typedef Input_argument_list::const_iterator const_iterator;
591
592 Input_arguments()
593 : input_argument_list_(), in_group_(false)
594 { }
595
596 // Add a file.
597 void
598 add_file(const Input_file_argument& arg);
599
600 // Start a group (the --start-group option).
601 void
602 start_group();
603
604 // End a group (the --end-group option).
605 void
606 end_group();
607
608 // Return whether we are currently in a group.
609 bool
610 in_group() const
611 { return this->in_group_; }
612
613 // The number of entries in the list.
614 int
615 size() const
616 { return this->input_argument_list_.size(); }
617
618 // Iterators to iterate over the list of input files.
619
620 const_iterator
621 begin() const
622 { return this->input_argument_list_.begin(); }
623
624 const_iterator
625 end() const
626 { return this->input_argument_list_.end(); }
627
628 // Return whether the list is empty.
629 bool
630 empty() const
631 { return this->input_argument_list_.empty(); }
632
633 private:
634 Input_argument_list input_argument_list_;
635 bool in_group_;
636 };
637
638 // All the information read from the command line.
639
640 class Command_line
641 {
642 public:
643 typedef Input_arguments::const_iterator const_iterator;
644
645 Command_line();
646
647 // Process the command line options. This will exit with an
648 // appropriate error message if an unrecognized option is seen.
649 void
650 process(int argc, char** argv);
651
652 // Handle a -l option.
653 int
654 process_l_option(int, char**, char*);
655
656 // Handle a --start-group option.
657 void
658 start_group(const char* arg);
659
660 // Handle a --end-group option.
661 void
662 end_group(const char* arg);
663
664 // Get the general options.
665 const General_options&
666 options() const
667 { return this->options_; }
668
669 // The number of input files.
670 int
671 number_of_input_files() const
672 { return this->inputs_.size(); }
673
674 // Iterators to iterate over the list of input files.
675
676 const_iterator
677 begin() const
678 { return this->inputs_.begin(); }
679
680 const_iterator
681 end() const
682 { return this->inputs_.end(); }
683
684 private:
685 Command_line(const Command_line&);
686 Command_line& operator=(const Command_line&);
687
688 // Report usage error.
689 void
690 usage() ATTRIBUTE_NORETURN;
691 void
692 usage(const char* msg, const char* opt) ATTRIBUTE_NORETURN;
693 void
694 usage(const char* msg, char opt) ATTRIBUTE_NORETURN;
695
696 // Apply a command line option.
697 void
698 apply_option(const gold::options::One_option&, const char*);
699
700 // Add a file.
701 void
702 add_file(const char* name, bool is_lib);
703
704 // Examine the result of processing the command-line, and verify
705 // the flags do not contradict each other or are otherwise illegal.
706 void
707 normalize_options();
708
709 General_options options_;
710 Position_dependent_options position_options_;
711 Input_arguments inputs_;
712 };
713
714 } // End namespace gold.
715
716 #endif // !defined(GOLD_OPTIONS_H)
This page took 0.050549 seconds and 5 git commands to generate.