Add infrastructure for threading support.
[external/binutils.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)