// the stubbed branches.
Stub_control(int32_t size, bool no_size_errors)
: state_(NO_GROUP), stub_group_size_(abs(size)),
- stub14_group_size_(abs(size) >> 10),
stubs_always_before_branch_(size < 0),
- suppress_size_errors_(no_size_errors), has14_(false),
+ suppress_size_errors_(no_size_errors), group_size_(0),
group_end_addr_(0), owner_(NULL), output_section_(NULL)
{
}
State state_;
uint32_t stub_group_size_;
- uint32_t stub14_group_size_;
bool stubs_always_before_branch_;
bool suppress_size_errors_;
- bool has14_;
+ // 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.
+ uint32_t group_size_;
uint64_t group_end_addr_;
// owner_ and output_section_ specify the section to which stubs are
// attached. The stubs are placed at the end of this section.
this_size = i->data_size();
}
- uint32_t group_size
- = has14 ? this->stub14_group_size_ : this->stub_group_size_;
- uint64_t end_addr = start_addr + this_size;
+ uint32_t group_size = this->stub_group_size_;
+ if (has14)
+ this->group_size_ = group_size = group_size >> 10;
if (this_size > group_size && !this->suppress_size_errors_)
gold_warning(_("%s:%s exceeds group size"),
i->relobj()->name().c_str(),
i->relobj()->section_name(i->shndx()).c_str());
- this->has14_ = this->has14_ || has14;
- group_size = this->has14_ ? this->stub14_group_size_ : this->stub_group_size_;
+ gold_debug(DEBUG_TARGET, "maybe add%s %s:%s size=%#llx total=%#llx",
+ has14 ? " 14bit" : "",
+ i->relobj()->name().c_str(),
+ i->relobj()->section_name(i->shndx()).c_str(),
+ (long long) this_size,
+ (long long) this->group_end_addr_ - start_addr);
+ uint64_t end_addr = start_addr + this_size;
if (this->state_ == HAS_STUB_SECTION)
{
// Can we add this section, which is before the stubs, to the
// group?
- if (this->group_end_addr_ - start_addr <= group_size)
+ if (this->group_end_addr_ - start_addr <= this->group_size_)
return true;
}
else
if (this->state_ == FINDING_STUB_SECTION)
{
- if (this->group_end_addr_ - start_addr <= group_size)
+ if (this->group_end_addr_ - start_addr <= this->group_size_)
return true;
// The group after the stubs has reached maximum size.
// Now see about adding sections before the stubs to the
// group. If the current section has a 14-bit branch and
- // the group after the stubs exceeds stub14_group_size_
- // (because they didn't have 14-bit branches), don't add
- // sections before the stubs: The size of stubs for such a
- // large group may exceed the reach of a 14-bit branch.
+ // the group after the stubs exceeds group_size_ (because
+ // they didn't have 14-bit branches), don't add sections
+ // before the stubs: The size of stubs for such a large
+ // group may exceed the reach of a 14-bit branch.
if (!this->stubs_always_before_branch_
- && this_size <= group_size
- && this->group_end_addr_ - end_addr <= group_size)
+ && this_size <= this->group_size_
+ && this->group_end_addr_ - end_addr <= this->group_size_)
{
+ gold_debug(DEBUG_TARGET, "adding before stubs");
this->state_ = HAS_STUB_SECTION;
this->group_end_addr_ = end_addr;
return true;
{
// Only here on very first use of Stub_control
this->state_ = FINDING_STUB_SECTION;
+ this->group_size_ = group_size;
this->group_end_addr_ = end_addr;
return true;
}
gold_unreachable();
}
+ gold_debug(DEBUG_TARGET, "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
// set later after we've retrieved those values for the current
// group.
this->state_ = FINDING_STUB_SECTION;
- this->has14_ = has14;
+ this->group_size_ = group_size;
this->group_end_addr_ = end_addr;
return false;
}
ppc_object->set_opd_discard(reloc.get_r_offset());
break;
}
- // Fall thru
+ // Fall through.
case elfcpp::R_PPC64_UADDR64:
case elfcpp::R_POWERPC_ADDR32:
case elfcpp::R_POWERPC_UADDR32:
|| gsym->is_preemptible())))
target->make_plt_entry(symtab, layout, gsym);
}
- // Fall thru
+ // Fall through.
case elfcpp::R_PPC64_REL64:
case elfcpp::R_POWERPC_REL32:
if (size != 64)
// R_PPC_TLSGD, R_PPC_TLSLD, R_PPC_EMB_RELST_LO, R_PPC_EMB_RELST_HI
break;
+ // Fall through.
case elfcpp::R_POWERPC_TPREL16:
case elfcpp::R_POWERPC_TPREL16_LO:
case elfcpp::R_POWERPC_TPREL16_HI:
// R_PPC_EMB_NADDR32, R_PPC_EMB_NADDR16, R_PPC_EMB_NADDR16_LO
// R_PPC_EMB_NADDR16_HI, R_PPC_EMB_NADDR16_HA, R_PPC_EMB_SDAI16
break;
+ // Fall through.
case elfcpp::R_POWERPC_DTPREL16:
case elfcpp::R_POWERPC_DTPREL16_LO:
case elfcpp::R_POWERPC_DTPREL16_HI:
case elfcpp::R_POWERPC_ADDR14_BRTAKEN:
case elfcpp::R_POWERPC_REL14_BRTAKEN:
branch_bit = 1 << 21;
+ // Fall through.
case elfcpp::R_POWERPC_ADDR14_BRNTAKEN:
case elfcpp::R_POWERPC_REL14_BRNTAKEN:
{
maybe_dq_reloc = true;
break;
}
+ // Fall through.
case elfcpp::R_POWERPC_ADDR16:
case elfcpp::R_POWERPC_REL16:
case elfcpp::R_PPC64_TOC16:
if (size == 32)
// R_PPC_EMB_MRKREF, R_PPC_EMB_RELST_LO, R_PPC_EMB_RELST_HA
goto unsupp;
+ // Fall through.
case elfcpp::R_POWERPC_ADDR16_HI:
case elfcpp::R_POWERPC_REL16_HI:
case elfcpp::R_PPC64_TOC16_HI:
if (size == 32)
// R_PPC_EMB_RELSEC16, R_PPC_EMB_RELST_HI, R_PPC_EMB_BIT_FLD
goto unsupp;
+ // Fall through.
case elfcpp::R_POWERPC_ADDR16_HA:
case elfcpp::R_POWERPC_REL16_HA:
case elfcpp::R_PPC64_TOC16_HA:
if (size == 32)
// R_PPC_EMB_NADDR16_LO
goto unsupp;
+ // Fall through.
case elfcpp::R_PPC64_ADDR16_HIGHER:
case elfcpp::R_PPC64_TPREL16_HIGHER:
Reloc::addr16_hi2(view, value);
if (size == 32)
// R_PPC_EMB_NADDR16_HI
goto unsupp;
+ // Fall through.
case elfcpp::R_PPC64_ADDR16_HIGHERA:
case elfcpp::R_PPC64_TPREL16_HIGHERA:
Reloc::addr16_ha2(view, value);
if (size == 32)
// R_PPC_EMB_NADDR16_HA
goto unsupp;
+ // Fall through.
case elfcpp::R_PPC64_ADDR16_HIGHEST:
case elfcpp::R_PPC64_TPREL16_HIGHEST:
Reloc::addr16_hi3(view, value);
if (size == 32)
// R_PPC_EMB_SDAI16
goto unsupp;
+ // Fall through.
case elfcpp::R_PPC64_ADDR16_HIGHESTA:
case elfcpp::R_PPC64_TPREL16_HIGHESTA:
Reloc::addr16_ha3(view, value);
if (size == 32)
// R_PPC_EMB_NADDR32, R_PPC_EMB_NADDR16
goto unsupp;
+ // Fall through.
case elfcpp::R_PPC64_TPREL16_DS:
case elfcpp::R_PPC64_TPREL16_LO_DS:
if (size == 32)
// R_PPC_TLSGD, R_PPC_TLSLD
break;
+ // Fall through.
case elfcpp::R_PPC64_ADDR16_DS:
case elfcpp::R_PPC64_ADDR16_LO_DS:
case elfcpp::R_PPC64_TOC16_DS: