diff options
author | Alan Modra <amodra@gmail.com> | 2016-12-07 14:15:59 +1030 |
---|---|---|
committer | Alan Modra <amodra@gmail.com> | 2016-12-07 14:15:59 +1030 |
commit | 1c3a5fbe155614a0f87079b953df0d7618e0ab50 (patch) | |
tree | 8335a91b8f1a56a9548e2ea37f5c69a6aa192bcb /gold | |
parent | a5018ae555cdf491005907c03f997558ba15fc47 (diff) | |
download | gdb-1c3a5fbe155614a0f87079b953df0d7618e0ab50.zip gdb-1c3a5fbe155614a0f87079b953df0d7618e0ab50.tar.gz gdb-1c3a5fbe155614a0f87079b953df0d7618e0ab50.tar.bz2 |
[GOLD] PowerPC --stub-group-multi
Adds a new option, defaulting to off, that allows a group of stubs to
serve multiple output sections. Prior to this patch powerpc gold
allowed this unconditionally, which is a little unsafe with clever
code that discards/reuses sections at runtime.
* options.h (--stub-group-multi): New PowerPC option.
* powerpc.cc (Stub_control): Add multi_os_ var and param
to constructor. Sort start_ var later. Comment State.
(Stub_control::can_add_to_stub_group): Heed multi_os_.
(Target_powerpc::group_sections): Update.
Diffstat (limited to 'gold')
-rw-r--r-- | gold/ChangeLog | 8 | ||||
-rw-r--r-- | gold/options.h | 4 | ||||
-rw-r--r-- | gold/powerpc.cc | 49 |
3 files changed, 42 insertions, 19 deletions
diff --git a/gold/ChangeLog b/gold/ChangeLog index 367cb02..2fcd80e 100644 --- a/gold/ChangeLog +++ b/gold/ChangeLog @@ -1,5 +1,13 @@ 2016-12-07 Alan Modra <amodra@gmail.com> + * options.h (--stub-group-multi): New PowerPC option. + * powerpc.cc (Stub_control): Add multi_os_ var and param + to constructor. Sort start_ var later. Comment State. + (Stub_control::can_add_to_stub_group): Heed multi_os_. + (Target_powerpc::group_sections): Update. + +2016-12-07 Alan Modra <amodra@gmail.com> + PR gold/20878 * powerpc.cc (Stub_control): Replace stubs_always_before_branch_ with stubs_always_after_branch_, group_end_addr_ with diff --git a/gold/options.h b/gold/options.h index 90ccc80..6722667 100644 --- a/gold/options.h +++ b/gold/options.h @@ -1219,6 +1219,10 @@ class General_options "stubs are always after the group. 1 means use default size"), N_("SIZE")); + DEFINE_bool(stub_group_multi, options::TWO_DASHES, '\0', false, + N_("(PowerpC only) Allow a group of stubs to serve multiple " + "output sections"), NULL); + DEFINE_uint(split_stack_adjust_size, options::TWO_DASHES, '\0', 0x4000, N_("Stack size when -fsplit-stack function calls non-split"), N_("SIZE")); diff --git a/gold/powerpc.cc b/gold/powerpc.cc index f763618..068f5ca 100644 --- a/gold/powerpc.cc +++ b/gold/powerpc.cc @@ -2441,11 +2441,11 @@ class Stub_control // value of the parameter --stub-group-size. If --stub-group-size // is passed a negative value, we restrict stubs to be always after // the stubbed branches. - Stub_control(int32_t size, bool no_size_errors) - : state_(NO_GROUP), stub_group_size_(abs(size)), - stubs_always_after_branch_(size < 0), - suppress_size_errors_(no_size_errors), group_size_(0), - group_start_addr_(0), owner_(NULL), output_section_(NULL) + Stub_control(int32_t size, bool no_size_errors, bool multi_os) + : stub_group_size_(abs(size)), stubs_always_after_branch_(size < 0), + suppress_size_errors_(no_size_errors), multi_os_(multi_os), + state_(NO_GROUP), group_size_(0), group_start_addr_(0), + owner_(NULL), output_section_(NULL) { } @@ -2475,15 +2475,20 @@ class Stub_control private: typedef enum { + // Initial state. NO_GROUP, + // Adding group sections before the stubs. FINDING_STUB_SECTION, + // Adding group sections after the stubs. HAS_STUB_SECTION } State; - State state_; uint32_t stub_group_size_; bool stubs_always_after_branch_; bool suppress_size_errors_; + // True if a stub group can serve multiple output sections. + bool multi_os_; + State state_; // Current max size of group. Starts at stub_group_size_ but is // reduced to stub_group_size_/1024 on seeing a section with // external conditional branches. @@ -2537,7 +2542,19 @@ Stub_control::can_add_to_stub_group(Output_section* o, ? this_size : (long long) end_addr - this->group_start_addr_)); - if (this->state_ == HAS_STUB_SECTION) + if (this->state_ == NO_GROUP) + { + // Only here on very first use of Stub_control + this->owner_ = i; + this->output_section_ = o; + this->state_ = FINDING_STUB_SECTION; + this->group_size_ = group_size; + this->group_start_addr_ = start_addr; + return true; + } + else if (!this->multi_os_ && this->output_section_ != o) + ; + else if (this->state_ == HAS_STUB_SECTION) { // Can we add this section, which is after the stubs, to the // group? @@ -2571,20 +2588,13 @@ Stub_control::can_add_to_stub_group(Output_section* o, return true; } } - else if (this->state_ == NO_GROUP) - { - // Only here on very first use of Stub_control - this->owner_ = i; - this->output_section_ = o; - this->state_ = FINDING_STUB_SECTION; - this->group_size_ = group_size; - this->group_start_addr_ = start_addr; - return true; - } else gold_unreachable(); - gold_debug(DEBUG_TARGET, "nope, didn't fit\n"); + gold_debug(DEBUG_TARGET, + !this->multi_os_ && this->output_section_ != o + ? "nope, new output section\n" + : "nope, didn't fit\n"); // The section fails to fit in the current group. Set up a few // things for the next group. owner_ and output_section_ will be @@ -2604,7 +2614,8 @@ Target_powerpc<size, big_endian>::group_sections(Layout* layout, const Task*, bool no_size_errors) { - Stub_control stub_control(this->stub_group_size_, no_size_errors); + Stub_control stub_control(this->stub_group_size_, no_size_errors, + parameters->options().stub_group_multi()); // Group input sections and insert stub table Stub_table_owner* table_owner = NULL; |