From 591be3e4a841ac56bb3ee094447b708d58a6d4b8 Mon Sep 17 00:00:00 2001 From: Cary Coutant Date: Tue, 13 Dec 2016 13:01:13 -0800 Subject: [PATCH] Add --orphan-handling option. gold/ PR gold/20749 * options.h (--orphan-handling): New option. (General_options::Orphan_handling): New enum. (General_options::orphan_handling_enum): New method. (General_options::set_orphan_handling_enum): New method. (General_options::orphan_handling_enum_): New data member. * options.cc (General_options::General_options): Initialize new member. (General_options::finalize): Convert --orphan-handling argument to enum. * script-sections.cc (Script_sections::output_section_name): Check it. --- gold/ChangeLog | 12 ++++++++++++ gold/options.cc | 16 +++++++++++++++- gold/options.h | 26 ++++++++++++++++++++++++++ gold/script-sections.cc | 30 +++++++++++++++++++++++++++--- 4 files changed, 80 insertions(+), 4 deletions(-) diff --git a/gold/ChangeLog b/gold/ChangeLog index ac5fce8..b40f7b8 100644 --- a/gold/ChangeLog +++ b/gold/ChangeLog @@ -1,5 +1,17 @@ 2016-12-13 Cary Coutant + PR gold/20749 + * options.h (--orphan-handling): New option. + (General_options::Orphan_handling): New enum. + (General_options::orphan_handling_enum): New method. + (General_options::set_orphan_handling_enum): New method. + (General_options::orphan_handling_enum_): New data member. + * options.cc (General_options::General_options): Initialize new member. + (General_options::finalize): Convert --orphan-handling argument to enum. + * script-sections.cc (Script_sections::output_section_name): Check it. + +2016-12-13 Cary Coutant + PR gold/20522 * layout.cc (Layout::choose_output_section): Add is_reloc parameter. Adjust all callers. Do not use linker script for is_reloc sections. diff --git a/gold/options.cc b/gold/options.cc index 276be39..1650910 100644 --- a/gold/options.cc +++ b/gold/options.cc @@ -998,7 +998,8 @@ General_options::General_options() section_starts_(), fix_v4bx_(FIX_V4BX_NONE), endianness_(ENDIANNESS_NOT_SET), - discard_locals_(DISCARD_SEC_MERGE) + discard_locals_(DISCARD_SEC_MERGE), + orphan_handling_enum_(ORPHAN_PLACE) { // Turn off option registration once construction is complete. gold::options::ready_to_register = false; @@ -1157,6 +1158,19 @@ General_options::finalize() this->set_do_demangle(getenv("COLLECT_NO_DEMANGLE") == NULL); } + // Parse the --orphan-handling argument. + if (this->user_set_orphan_handling()) + { + if (strcmp(this->orphan_handling(), "place") == 0) + this->set_orphan_handling_enum(ORPHAN_PLACE); + else if (strcmp(this->orphan_handling(), "discard") == 0) + this->set_orphan_handling_enum(ORPHAN_DISCARD); + else if (strcmp(this->orphan_handling(), "warn") == 0) + this->set_orphan_handling_enum(ORPHAN_WARN); + else if (strcmp(this->orphan_handling(), "error") == 0) + this->set_orphan_handling_enum(ORPHAN_ERROR); + } + // -M is equivalent to "-Map -". if (this->print_map() && !this->user_set_Map()) { diff --git a/gold/options.h b/gold/options.h index 75b2f09..ebe08df 100644 --- a/gold/options.h +++ b/gold/options.h @@ -1072,6 +1072,10 @@ class General_options DEFINE_uint(optimize, options::EXACTLY_ONE_DASH, 'O', 0, N_("Optimize output file size"), N_("LEVEL")); + DEFINE_enum(orphan_handling, options::TWO_DASHES, '\0', "place", + N_("Orphan section handling"), N_("[place,discard,warn,error]"), + {"place", "discard", "warn", "error"}); + // p DEFINE_bool(p, options::ONE_DASH, 'p', false, @@ -1684,6 +1688,22 @@ class General_options discard_sec_merge() const { return this->discard_locals_ == DISCARD_SEC_MERGE; } + enum Orphan_handling + { + // Place orphan sections normally (default). + ORPHAN_PLACE, + // Discard all orphan sections. + ORPHAN_DISCARD, + // Warn when placing orphan sections. + ORPHAN_WARN, + // Issue error for orphan sections. + ORPHAN_ERROR + }; + + Orphan_handling + orphan_handling_enum() const + { return this->orphan_handling_enum_; } + private: // Don't copy this structure. General_options(const General_options&); @@ -1739,6 +1759,10 @@ class General_options set_static(bool value) { static_ = value; } + void + set_orphan_handling_enum(Orphan_handling value) + { this->orphan_handling_enum_ = value; } + // These are called by finalize() to set up the search-path correctly. void add_to_library_path_with_sysroot(const std::string& arg) @@ -1804,6 +1828,8 @@ class General_options Discard_locals discard_locals_; // Stack of saved options for --push-state/--pop-state. std::vector options_stack_; + // Orphan handling option, decoded to an enum value. + Orphan_handling orphan_handling_enum_; }; // The position-dependent options. We use this to store the state of diff --git a/gold/script-sections.cc b/gold/script-sections.cc index 90ec8d4..ffd4666 100644 --- a/gold/script-sections.cc +++ b/gold/script-sections.cc @@ -3592,13 +3592,37 @@ Script_sections::output_section_name( } } - // If we couldn't find a mapping for the name, the output section - // gets the name of the input section. - + // We have an orphan section. *output_section_slot = NULL; *psection_type = Script_sections::ST_NONE; *keep = false; + General_options::Orphan_handling orphan_handling = + parameters->options().orphan_handling_enum(); + if (orphan_handling == General_options::ORPHAN_DISCARD) + return NULL; + if (orphan_handling == General_options::ORPHAN_ERROR) + { + if (file_name == NULL) + gold_error(_("unplaced orphan section '%s'"), section_name); + else + gold_error(_("unplaced orphan section '%s' from '%s'"), + section_name, file_name); + return NULL; + } + if (orphan_handling == General_options::ORPHAN_WARN) + { + if (file_name == NULL) + gold_warning(_("orphan section '%s' is being placed in section '%s'"), + section_name, section_name); + else + gold_warning(_("orphan section '%s' from '%s' is being placed " + "in section '%s'"), + section_name, file_name, section_name); + } + + // If we couldn't find a mapping for the name, the output section + // gets the name of the input section. return section_name; } -- 2.7.4