X-Git-Url: http://git.efficios.com/?a=blobdiff_plain;f=gold%2Foptions.h;h=1e328a8dbecf94041c858073c0414d4d7699af18;hb=3def43e060c89f10b775951cfec9ba963e5db481;hp=eeade6fe28be9c883390ae10999a8aaf9037d731;hpb=ef15dade898122c47e0f7dc0f48c1399c444afdd;p=deliverable%2Fbinutils-gdb.git diff --git a/gold/options.h b/gold/options.h index eeade6fe28..1e328a8dbe 100644 --- a/gold/options.h +++ b/gold/options.h @@ -1,6 +1,6 @@ // options.h -- handle command line options for gold -*- C++ -*- -// Copyright 2006, 2007, 2008, 2009 Free Software Foundation, Inc. +// Copyright 2006, 2007, 2008, 2009, 2010 Free Software Foundation, Inc. // Written by Ian Lance Taylor . // This file is part of gold. @@ -39,6 +39,7 @@ #include #include #include +#include #include #include @@ -52,6 +53,7 @@ class Command_line; class General_options; class Search_directory; class Input_file_group; +class Input_file_lib; class Position_dependent_options; class Target; class Plugin_manager; @@ -82,6 +84,9 @@ typedef Unordered_set String_set; extern void parse_bool(const char* option_name, const char* arg, bool* retval); +extern void +parse_int(const char* option_name, const char* arg, int* retval); + extern void parse_uint(const char* option_name, const char* arg, int* retval); @@ -240,12 +245,18 @@ struct Struct_special : public Struct_var // var() and set_var() as General_options methods. Arguments as are // for the constructor for One_option. param_type__ is the same as // type__ for built-in types, and "const type__ &" otherwise. +// +// When we define the linker command option "assert", the macro argument +// varname__ of DEFINE_var below will be replaced by "assert". On Mac OSX +// assert.h is included implicitly by one of the library headers we use. To +// avoid unintended macro substitution of "assert()", we need to enclose +// varname__ with parenthese. #define DEFINE_var(varname__, dashes__, shortname__, default_value__, \ default_value_as_string__, helpstring__, helparg__, \ optional_arg__, type__, param_type__, parse_fn__) \ public: \ param_type__ \ - varname__() const \ + (varname__)() const \ { return this->varname__##_.value; } \ \ bool \ @@ -305,7 +316,10 @@ struct Struct_special : public Struct_var void \ parse_to_value(const char*, const char*, \ Command_line*, General_options* options) \ - { options->set_##varname__(false); } \ + { \ + options->set_##varname__(false); \ + options->set_user_set_##varname__(); \ + } \ \ options::One_option option; \ }; \ @@ -333,6 +347,12 @@ struct Struct_special : public Struct_var }; \ Struct_disable_##varname__ disable_##varname__##_initializer_ +#define DEFINE_int(varname__, dashes__, shortname__, default_value__, \ + helpstring__, helparg__) \ + DEFINE_var(varname__, dashes__, shortname__, default_value__, \ + #default_value__, helpstring__, helparg__, false, \ + int, int, options::parse_int) + #define DEFINE_uint(varname__, dashes__, shortname__, default_value__, \ helpstring__, helparg__) \ DEFINE_var(varname__, dashes__, shortname__, default_value__, \ @@ -571,13 +591,25 @@ class General_options // alphabetical order). For both, lowercase sorts before uppercase. // The -z options come last. + DEFINE_bool(add_needed, options::TWO_DASHES, '\0', false, + N_("Not supported"), + N_("Do not copy DT_NEEDED tags from shared libraries")); + + DEFINE_bool_alias(allow_multiple_definition, muldefs, options::TWO_DASHES, + '\0', N_("Allow multiple definitions of symbols"), + N_("Do not allow multiple definitions"), false); + DEFINE_bool(allow_shlib_undefined, options::TWO_DASHES, '\0', false, N_("Allow unresolved references in shared libraries"), N_("Do not allow unresolved references in shared libraries")); DEFINE_bool(as_needed, options::TWO_DASHES, '\0', false, - N_("Only set DT_NEEDED for dynamic libs if used"), - N_("Always DT_NEEDED for dynamic libs")); + N_("Only set DT_NEEDED for shared libraries if used"), + N_("Always DT_NEEDED for shared libraries")); + + DEFINE_enum(assert, options::ONE_DASH, '\0', NULL, + N_("Ignored"), N_("[ignored]"), + {"definitions", "nodefinitions", "nosymbolic", "pure-text"}); // This should really be an "enum", but it's too easy for folks to // forget to update the list as they add new targets. So we just @@ -618,6 +650,14 @@ class General_options {"none"}); #endif + DEFINE_bool(copy_dt_needed_entries, options::TWO_DASHES, '\0', false, + N_("Not supported"), + N_("Do not copy DT_NEEDED tags from shared libraries")); + + DEFINE_bool(cref, options::TWO_DASHES, '\0', false, + N_("Output cross reference table"), + N_("Do not output cross reference table")); + DEFINE_bool(define_common, options::TWO_DASHES, 'd', false, N_("Define common symbols"), N_("Do not define common symbols")); @@ -645,6 +685,8 @@ class General_options N_("Try to detect violations of the One Definition Rule"), NULL); + DEFINE_bool(discard_all, options::TWO_DASHES, 'x', false, + N_("Delete all local symbols"), NULL); DEFINE_bool(discard_locals, options::TWO_DASHES, 'X', false, N_("Delete all temporary local symbols"), NULL); @@ -671,16 +713,48 @@ class General_options N_("Export all dynamic symbols"), N_("Do not export all dynamic symbols (default)")); + DEFINE_special(EB, options::ONE_DASH, '\0', + N_("Link big-endian objects."), NULL); + DEFINE_bool(eh_frame_hdr, options::TWO_DASHES, '\0', false, N_("Create exception frame header"), NULL); + DEFINE_special(EL, options::ONE_DASH, '\0', + N_("Link little-endian objects."), NULL); + DEFINE_bool(fatal_warnings, options::TWO_DASHES, '\0', false, N_("Treat warnings as errors"), N_("Do not treat warnings as errors")); + DEFINE_string(fini, options::ONE_DASH, '\0', "_fini", + N_("Call SYMBOL at unload-time"), N_("SYMBOL")); + + DEFINE_bool(fix_cortex_a8, options::TWO_DASHES, '\0', false, + N_("(ARM only) Fix binaries for Cortex-A8 erratum."), + N_("(ARM only) Do not fix binaries for Cortex-A8 erratum.")); + + DEFINE_bool(merge_exidx_entries, options::TWO_DASHES, '\0', true, + N_("(ARM only) Merge exidx entries in debuginfo."), + N_("(ARM only) Do not merge exidx entries in debuginfo.")); + + DEFINE_special(fix_v4bx, options::TWO_DASHES, '\0', + N_("(ARM only) Rewrite BX rn as MOV pc, rn for ARMv4"), + NULL); + + DEFINE_special(fix_v4bx_interworking, options::TWO_DASHES, '\0', + N_("(ARM only) Rewrite BX rn branch to ARMv4 interworking " + "veneer"), + NULL); + + DEFINE_bool(g, options::EXACTLY_ONE_DASH, '\0', false, + N_("Ignored"), NULL); + DEFINE_string(soname, options::ONE_DASH, 'h', NULL, N_("Set shared library name"), N_("FILENAME")); + DEFINE_bool(i, options::EXACTLY_ONE_DASH, '\0', false, + N_("Ignored"), NULL); + DEFINE_double(hash_bucket_empty_fraction, options::TWO_DASHES, '\0', 0.0, N_("Min fraction of empty buckets in dynamic hash"), N_("FRACTION")); @@ -705,15 +779,31 @@ class General_options DEFINE_special(incremental_unknown, options::TWO_DASHES, '\0', N_("Use timestamps to check files (default)"), NULL); + DEFINE_string(init, options::ONE_DASH, '\0', "_init", + N_("Call SYMBOL at load-time"), N_("SYMBOL")); + DEFINE_special(just_symbols, options::TWO_DASHES, '\0', N_("Read only symbol values from FILE"), N_("FILE")); + DEFINE_bool(map_whole_files, options::TWO_DASHES, '\0', + sizeof(void*) >= 8, + N_("Map whole files to memory (default on 64-bit hosts)"), + N_("Map relevant file parts to memory (default on 32-bit " + "hosts)")); + DEFINE_bool(keep_files_mapped, options::TWO_DASHES, '\0', true, + N_("Keep files mapped across passes (default)"), + N_("Release mapped files after each pass")); + DEFINE_special(library, options::TWO_DASHES, 'l', N_("Search for library LIBNAME"), N_("LIBNAME")); DEFINE_dirlist(library_path, options::TWO_DASHES, 'L', N_("Add directory to search path"), N_("DIR")); + DEFINE_bool(nostdlib, options::ONE_DASH, '\0', false, + N_(" Only search directories specified on the command line."), + NULL); + DEFINE_string(m, options::EXACTLY_ONE_DASH, 'm', "", N_("Ignored for compatibility"), N_("EMULATION")); @@ -748,6 +838,18 @@ class General_options DEFINE_string(oformat, options::EXACTLY_TWO_DASHES, '\0', "elf", N_("Set output format"), N_("[binary]")); + DEFINE_bool(p, options::ONE_DASH, '\0', false, + N_("(ARM only) Ignore for backward compatibility"), NULL); + + DEFINE_bool(pie, options::ONE_DASH, '\0', false, + N_("Create a position independent executable"), NULL); + DEFINE_bool_alias(pic_executable, pie, options::TWO_DASHES, '\0', + N_("Create a position independent executable"), NULL, + false); + + DEFINE_bool(pipeline_knowledge, options::ONE_DASH, '\0', false, + NULL, N_("(ARM only) Ignore for backward compatibility")); + #ifdef ENABLE_PLUGINS DEFINE_special(plugin, options::TWO_DASHES, '\0', N_("Load a plugin library"), N_("PLUGIN")); @@ -774,6 +876,9 @@ class General_options DEFINE_bool(relax, options::TWO_DASHES, '\0', false, N_("Relax branches on certain targets"), NULL); + DEFINE_string(retain_symbols_file, options::TWO_DASHES, '\0', NULL, + N_("keep only symbols listed in this file"), N_("FILE")); + // -R really means -rpath, but can mean --just-symbols for // compatibility with GNU ld. -rpath is always -rpath, so we list // it separately. @@ -787,6 +892,17 @@ class General_options N_("Add DIR to link time shared library search path"), N_("DIR")); + DEFINE_special(section_start, options::TWO_DASHES, '\0', + N_("Set address of section"), N_("SECTION=ADDRESS")); + + DEFINE_optional_string(sort_common, options::TWO_DASHES, '\0', NULL, + N_("Sort common symbols by alignment"), + N_("[={ascending,descending}]")); + + DEFINE_uint(spare_dynamic_tags, options::TWO_DASHES, '\0', 5, + N_("Dynamic tag slots to reserve (default 5)"), + N_("COUNT")); + DEFINE_bool(strip_all, options::TWO_DASHES, 's', false, N_("Strip all symbols"), NULL); DEFINE_bool(strip_debug, options::TWO_DASHES, 'S', false, @@ -799,23 +915,37 @@ class General_options DEFINE_bool(strip_lto_sections, options::TWO_DASHES, '\0', true, N_("Strip LTO intermediate code sections"), NULL); - DEFINE_bool(no_keep_memory, options::TWO_DASHES, 's', false, - N_("Use less memory and more disk I/O (included only for compatibility with GNU ld)"), NULL); + DEFINE_int(stub_group_size, options::TWO_DASHES , '\0', 1, + N_("(ARM only) The maximum distance from instructions in a group " + "of sections to their stubs. Negative values mean stubs " + "are always after the group. 1 means using default size.\n"), + N_("SIZE")); + + DEFINE_bool(no_keep_memory, options::TWO_DASHES, '\0', false, + N_("Use less memory and more disk I/O " + "(included only for compatibility with GNU ld)"), NULL); - DEFINE_bool(shared, options::ONE_DASH, '\0', false, + DEFINE_bool(shared, options::ONE_DASH, 'G', false, N_("Generate shared library"), NULL); DEFINE_bool(Bshareable, options::ONE_DASH, '\0', false, N_("Generate shared library"), NULL); + DEFINE_uint(split_stack_adjust_size, options::TWO_DASHES, '\0', 0x4000, + N_("Stack size when -fsplit-stack function calls non-split"), + N_("SIZE")); + // This is not actually special in any way, but I need to give it // a non-standard accessor-function name because 'static' is a keyword. DEFINE_special(static, options::ONE_DASH, '\0', N_("Do not link against shared libraries"), NULL); - DEFINE_bool(icf, options::TWO_DASHES, '\0', false, - N_("Fold identical functions"), - N_("Don't fold identical functions (default)")); + DEFINE_enum(icf, options::TWO_DASHES, '\0', "none", + N_("Identical Code Folding. " + "\'--icf=safe\' Folds ctors, dtors and functions whose" + " pointers are definitely not taken."), + ("[none,all,safe]"), + {"none", "all", "safe"}); DEFINE_uint(icf_iterations, options::TWO_DASHES , '\0', 0, N_("Number of iterations of ICF (default 2)"), N_("COUNT")); @@ -824,6 +954,9 @@ class General_options N_("List folded identical sections on stderr"), N_("Do not list folded identical sections")); + DEFINE_set(keep_unique, options::TWO_DASHES, '\0', + N_("Do not fold this symbol during ICF"), N_("SYMBOL")); + DEFINE_bool(gc_sections, options::TWO_DASHES, '\0', false, N_("Remove unused sections"), N_("Don't remove unused sections (default)")); @@ -872,10 +1005,35 @@ class General_options DEFINE_special(version_script, options::TWO_DASHES, '\0', N_("Read version script"), N_("FILE")); + DEFINE_bool(warn_common, options::TWO_DASHES, '\0', false, + N_("Warn about duplicate common symbols"), + N_("Do not warn about duplicate common symbols (default)")); + + DEFINE_bool(warn_constructors, options::TWO_DASHES, '\0', false, + N_("Ignored"), N_("Ignored")); + + DEFINE_bool(warn_mismatch, options::TWO_DASHES, '\0', true, + NULL, N_("Don't warn about mismatched input files")); + + DEFINE_bool(warn_multiple_gp, options::TWO_DASHES, '\0', false, + N_("Ignored"), NULL); + DEFINE_bool(warn_search_mismatch, options::TWO_DASHES, '\0', true, N_("Warn when skipping an incompatible library"), N_("Don't warn when skipping an incompatible library")); + DEFINE_bool(warn_shared_textrel, options::TWO_DASHES, '\0', false, + N_("Warn if text segment is not shareable"), + N_("Do not warn if text segment is not shareable (default)")); + + DEFINE_bool(warn_unresolved_symbols, options::TWO_DASHES, '\0', false, + N_("Report unresolved symbols as warnings"), + NULL); + DEFINE_bool_alias(error_unresolved_symbols, warn_unresolved_symbols, + options::TWO_DASHES, '\0', + N_("Report unresolved symbols as errors"), + NULL, true); + DEFINE_bool(whole_archive, options::TWO_DASHES, '\0', false, N_("Include all archive contents"), N_("Include only needed archive contents")); @@ -886,6 +1044,10 @@ class General_options DEFINE_set(trace_symbol, options::TWO_DASHES, 'y', N_("Trace references to symbol"), N_("SYMBOL")); + DEFINE_bool(undefined_version, options::TWO_DASHES, '\0', true, + N_("Allow unused version in script (default)"), + N_("Do not allow unused version in script")); + DEFINE_string(Y, options::EXACTLY_ONE_DASH, 'Y', "", N_("Default search path for Solaris compatibility"), N_("PATH")); @@ -895,6 +1057,12 @@ class General_options DEFINE_special(end_group, options::TWO_DASHES, ')', N_("End a library search group"), NULL); + + DEFINE_special(start_lib, options::TWO_DASHES, '\0', + N_("Start a library"), NULL); + DEFINE_special(end_lib, options::TWO_DASHES, '\0', + N_("End a library "), NULL); + // The -z options. DEFINE_bool(combreloc, options::DASH_Z, '\0', true, @@ -921,6 +1089,14 @@ class General_options NULL); DEFINE_uint64(max_page_size, options::DASH_Z, '\0', 0, N_("Set maximum page size to SIZE"), N_("SIZE")); + DEFINE_bool(muldefs, options::DASH_Z, '\0', false, + N_("Allow multiple definitions of symbols"), + NULL); + // copyreloc is here in the list because there is only -z + // nocopyreloc, not -z copyreloc. + DEFINE_bool(copyreloc, options::DASH_Z, '\0', true, + NULL, + N_("Do not create copy relocs")); DEFINE_bool(nodefaultlib, options::DASH_Z, '\0', false, N_("Mark object not to use default search paths"), NULL); @@ -944,6 +1120,12 @@ class General_options DEFINE_bool(relro, options::DASH_Z, '\0', false, N_("Where possible mark variables read-only after relocation"), N_("Don't mark variables read-only after relocation")); + DEFINE_bool(text, options::DASH_Z, '\0', false, + N_("Do not permit relocations in read-only segments"), + NULL); + DEFINE_bool_alias(textoff, text, options::DASH_Z, '\0', + N_("Permit relocations in read-only segments (default)"), + NULL, true); public: typedef options::Dir_list Dir_list; @@ -972,7 +1154,7 @@ class General_options // the output is position-independent or not. bool output_is_position_independent() const - { return this->shared(); } + { return this->shared() || this->pie(); } // Return true if the output is something that can be exec()ed, such // as a static executable, or a position-dependent or @@ -980,13 +1162,7 @@ class General_options // object file. bool output_is_executable() const - { return !this->shared() || this->output_is_pie(); } - - // Return true if the output is a position-independent executable. - // This is currently not supported. - bool - output_is_pie() const - { return false; } + { return !this->shared() && !this->relocatable(); } // This would normally be static(), and defined automatically, but // since static is a keyword, we need to come up with our own name. @@ -1017,6 +1193,15 @@ class General_options bool is_in_system_directory(const std::string& name) const; + // RETURN whether SYMBOL_NAME should be kept, according to symbols_to_retain_. + bool + should_retain_symbol(const char* symbol_name) const + { + if (symbols_to_retain_.empty()) // means flag wasn't specified + return true; + return symbols_to_retain_.find(symbol_name) != symbols_to_retain_.end(); + } + // These are the best way to get access to the execstack state, // not execstack() and noexecstack() which are hard to use properly. bool @@ -1027,6 +1212,14 @@ class General_options is_stack_executable() const { return this->execstack_status_ == EXECSTACK_YES; } + bool + icf_enabled() const + { return this->icf_status_ != ICF_NONE; } + + bool + icf_safe_folding() const + { return this->icf_status_ == ICF_SAFE; } + // The --demangle option takes an optional string, and there is also // a --no-demangle option. This is the best way to decide whether // to demangle or not. @@ -1049,6 +1242,11 @@ class General_options in_dynamic_list(const char* symbol) const { return this->dynamic_list_.version_script_info()->symbol_is_local(symbol); } + // Finalize the dynamic list. + void + finalize_dynamic_list() + { this->dynamic_list_.version_script_info()->finalize(); } + // The disposition given by the --incremental-changed, // --incremental-unchanged or --incremental-unknown option. The // value may change as we proceed parsing the command line flags. @@ -1061,6 +1259,37 @@ class General_options bool check_excluded_libs (const std::string &s) const; + // If an explicit start address was given for section SECNAME with + // the --section-start option, return true and set *PADDR to the + // address. Otherwise return false. + bool + section_start(const char* secname, uint64_t* paddr) const; + + enum Fix_v4bx + { + // Leave original instruction. + FIX_V4BX_NONE, + // Replace instruction. + FIX_V4BX_REPLACE, + // Generate an interworking veneer. + FIX_V4BX_INTERWORKING + }; + + Fix_v4bx + fix_v4bx() const + { return (this->fix_v4bx_); } + + enum Endianness + { + ENDIANNESS_NOT_SET, + ENDIANNESS_BIG, + ENDIANNESS_LITTLE + }; + + Endianness + endianness() const + { return this->endianness_; } + private: // Don't copy this structure. General_options(const General_options&); @@ -1077,6 +1306,20 @@ class General_options EXECSTACK_NO }; + enum Icf_status + { + // Do not fold any functions (Default or --icf=none). + ICF_NONE, + // All functions are candidates for folding. (--icf=all). + ICF_ALL, + // Only ctors and dtors are candidates for folding. (--icf=safe). + ICF_SAFE + }; + + void + set_icf_status(Icf_status value) + { this->icf_status_ = value; } + void set_execstack_status(Execstack value) { this->execstack_status_ = value; } @@ -1110,6 +1353,8 @@ class General_options bool printed_version_; // Whether to mark the stack as executable. Execstack execstack_status_; + // Whether to do code folding. + Icf_status icf_status_; // Whether to do a static link. bool static_; // Whether to do demangling. @@ -1128,8 +1373,16 @@ class General_options // build (--incremental-changed, --incremental-unchanged or // --incremental-unknown) bool implicit_incremental_; - // Libraries excluded from automatic export via --exclude-libs + // Libraries excluded from automatic export, via --exclude-libs. Unordered_set excluded_libs_; + // List of symbol-names to keep, via -retain-symbol-info. + Unordered_set symbols_to_retain_; + // Map from section name to address from --section-start. + std::map section_starts_; + // Whether to process armv4 bx instruction relocation. + Fix_v4bx fix_v4bx_; + // Endianness. + Endianness endianness_; }; // The position-dependent options. We use this to store the state of @@ -1188,9 +1441,20 @@ class Position_dependent_options class Input_file_argument { public: + enum Input_file_type + { + // A regular file, name used as-is, not searched. + INPUT_FILE_TYPE_FILE, + // A library name. When used, "lib" will be prepended and ".so" or + // ".a" appended to make a filename, and that filename will be searched + // for using the -L paths. + INPUT_FILE_TYPE_LIBRARY, + // A regular file, name used as-is, but searched using the -L paths. + INPUT_FILE_TYPE_SEARCHED_FILE + }; + // name: file name or library name - // is_lib: true if name is a library name: that is, emits the leading - // "lib" and trailing ".so"/".a" from the name + // type: the type of this input file. // extra_search_path: an extra directory to look for the file, prior // to checking the normal library search path. If this is "", // then no extra directory is added. @@ -1198,15 +1462,15 @@ class Input_file_argument // options: The position dependent options at this point in the // command line, such as --whole-archive. Input_file_argument() - : name_(), is_lib_(false), extra_search_path_(""), just_symbols_(false), - options_() + : name_(), type_(INPUT_FILE_TYPE_FILE), extra_search_path_(""), + just_symbols_(false), options_() { } - Input_file_argument(const char* name, bool is_lib, + Input_file_argument(const char* name, Input_file_type type, const char* extra_search_path, bool just_symbols, const Position_dependent_options& options) - : name_(name), is_lib_(is_lib), extra_search_path_(extra_search_path), + : name_(name), type_(type), extra_search_path_(extra_search_path), just_symbols_(just_symbols), options_(options) { } @@ -1214,11 +1478,11 @@ class Input_file_argument // Position_dependent_options. In that case, we extract the // position-independent vars from the General_options and only store // those. - Input_file_argument(const char* name, bool is_lib, + Input_file_argument(const char* name, Input_file_type type, const char* extra_search_path, bool just_symbols, const General_options& options) - : name_(name), is_lib_(is_lib), extra_search_path_(extra_search_path), + : name_(name), type_(type), extra_search_path_(extra_search_path), just_symbols_(just_symbols), options_(options) { } @@ -1232,7 +1496,11 @@ class Input_file_argument bool is_lib() const - { return this->is_lib_; } + { return type_ == INPUT_FILE_TYPE_LIBRARY; } + + bool + is_searched_file() const + { return type_ == INPUT_FILE_TYPE_SEARCHED_FILE; } const char* extra_search_path() const @@ -1251,14 +1519,18 @@ class Input_file_argument // options. bool may_need_search() const - { return this->is_lib_ || !this->extra_search_path_.empty(); } + { + return (this->is_lib() + || this->is_searched_file() + || !this->extra_search_path_.empty()); + } private: // We use std::string, not const char*, here for convenience when // using script files, so that we do not have to preserve the string // in that case. std::string name_; - bool is_lib_; + Input_file_type type_; std::string extra_search_path_; bool just_symbols_; Position_dependent_options options_; @@ -1271,12 +1543,17 @@ class Input_argument public: // Create a file or library argument. explicit Input_argument(Input_file_argument file) - : is_file_(true), file_(file), group_(NULL) + : is_file_(true), file_(file), group_(NULL), lib_(NULL) { } // Create a group argument. explicit Input_argument(Input_file_group* group) - : is_file_(false), group_(group) + : is_file_(false), group_(group), lib_(NULL) + { } + + // Create a lib argument. + explicit Input_argument(Input_file_lib* lib) + : is_file_(false), group_(NULL), lib_(lib) { } // Return whether this is a file. @@ -1287,7 +1564,12 @@ class Input_argument // Return whether this is a group. bool is_group() const - { return !this->is_file_; } + { return !this->is_file_ && this->lib_ == NULL; } + + // Return whether this is a lib. + bool + is_lib() const + { return this->lib_ != NULL; } // Return the information about the file. const Input_file_argument& @@ -1312,10 +1594,28 @@ class Input_argument return this->group_; } + // Return the information about the lib. + const Input_file_lib* + lib() const + { + gold_assert(!this->is_file_); + gold_assert(this->lib_); + return this->lib_; + } + + Input_file_lib* + lib() + { + gold_assert(!this->is_file_); + gold_assert(this->lib_); + return this->lib_; + } + private: bool is_file_; Input_file_argument file_; Input_file_group* group_; + Input_file_lib* lib_; }; typedef std::vector Input_argument_list; @@ -1351,6 +1651,46 @@ class Input_file_group Input_argument_list files_; }; +// A lib from the command line. This is a set of arguments within +// --start-lib ... --end-lib. + +class Input_file_lib +{ + public: + typedef Input_argument_list::const_iterator const_iterator; + + Input_file_lib(const Position_dependent_options& options) + : files_(), options_(options) + { } + + // Add a file to the end of the lib. + void + add_file(const Input_file_argument& arg) + { this->files_.push_back(Input_argument(arg)); } + + const Position_dependent_options& + options() const + { return this->options_; } + + // Iterators to iterate over the lib contents. + + const_iterator + begin() const + { return this->files_.begin(); } + + const_iterator + end() const + { return this->files_.end(); } + + size_t + size() const + { return this->files_.size(); } + + private: + Input_argument_list files_; + Position_dependent_options options_; +}; + // A list of files from the command line or a script. class Input_arguments @@ -1359,7 +1699,7 @@ class Input_arguments typedef Input_argument_list::const_iterator const_iterator; Input_arguments() - : input_argument_list_(), in_group_(false) + : input_argument_list_(), in_group_(false), in_lib_(false) { } // Add a file. @@ -1374,11 +1714,24 @@ class Input_arguments void end_group(); + // Start a lib (the --start-lib option). + void + start_lib(const Position_dependent_options&); + + // End a lib (the --end-lib option). + void + end_lib(); + // Return whether we are currently in a group. bool in_group() const { return this->in_group_; } + // Return whether we are currently in a lib. + bool + in_lib() const + { return this->in_lib_; } + // The number of entries in the list. int size() const @@ -1402,6 +1755,7 @@ class Input_arguments private: Input_argument_list input_argument_list_; bool in_group_; + bool in_lib_; }; @@ -1446,10 +1800,9 @@ class Command_line script_options() { return this->script_options_; } - // Get the version-script options: a convenience routine. + // Finalize the version-script options and return them. const Version_script_info& - version_script() const - { return *this->script_options_.version_script_info(); } + version_script(); // Get the input files. Input_arguments& @@ -1475,6 +1828,16 @@ class Command_line Command_line(const Command_line&); Command_line& operator=(const Command_line&); + // This is a dummy class to provide a constructor that runs before + // the constructor for the General_options. The Pre_options constructor + // is used as a hook to set the flag enabling the options to register + // themselves. + struct Pre_options { + Pre_options(); + }; + + // This must come before options_! + Pre_options pre_options_; General_options options_; Position_dependent_options position_options_; Script_options script_options_;