Merge "Windows LTO: bfd: Search plugin dir for dependencies"
diff --git a/binutils-2.27/gold/output.cc b/binutils-2.27/gold/output.cc
index 95b6eab..b905503 100644
--- a/binutils-2.27/gold/output.cc
+++ b/binutils-2.27/gold/output.cc
@@ -1231,29 +1231,17 @@
Output_reloc<elfcpp::SHT_RELR, dynamic, size, big_endian>::write(
unsigned char* pov) const
{
- typedef Output_data_reloc_base<elfcpp::SHT_RELR, dynamic, size,
- big_endian> Base;
elfcpp::Relr_write<size, big_endian> orel(pov);
-
- if (this->jump_ == 0)
+ if (this->bits_ == 0)
{
- // Delta from previous offset is either too big,
- // or is not a multiple of word_size. Encode as
- // two words: relocations bitmap and the offset.
- orel.put_r_data(this->bits_);
- pov += Base::reloc_size;
- elfcpp::Relr_write<size, big_endian> orel(pov);
+ // This is not a continuation entry. Output full address.
orel.put_r_data(this->rel_.get_address());
- return;
}
-
- // Encode jump:bits in a relr relocation entry.
- // High order 8-bits always encode the jump.
- // The remaining bits encode the bitmap.
- Relr_Data data;
- data = this->jump_ << (size - 8);
- data = data | this->bits_;
- orel.put_r_data(data);
+ else
+ {
+ // This is a continuation entry. Output the bitmap.
+ orel.put_r_data((this->bits_<<1)|1);
+ }
}
// Output_data_reloc_base methods.
diff --git a/binutils-2.27/gold/output.h b/binutils-2.27/gold/output.h
index a28d189..78fd426 100644
--- a/binutils-2.27/gold/output.h
+++ b/binutils-2.27/gold/output.h
@@ -1520,13 +1520,13 @@
Output_reloc(Symbol* gsym, Output_data* od, Address address)
: rel_(gsym, 0, od, address, true, true, false),
- jump_(0), bits_(0)
+ bits_(0)
{ }
Output_reloc(Symbol* gsym, Sized_relobj<size, big_endian>* relobj,
unsigned int shndx, Address address)
: rel_(gsym, 0, relobj, shndx, address, true, true, false),
- jump_(0), bits_(0)
+ bits_(0)
{ }
// A reloc against a local symbol.
@@ -1536,7 +1536,7 @@
bool is_section_symbol)
: rel_(relobj, local_sym_index, 0, od, address, true,
true, is_section_symbol, false),
- jump_(0), bits_(0)
+ bits_(0)
{ }
Output_reloc(Sized_relobj<size, big_endian>* relobj,
@@ -1544,31 +1544,31 @@
Address address, bool is_section_symbol)
: rel_(relobj, local_sym_index, 0, shndx, address, true,
true, is_section_symbol, false),
- jump_(0), bits_(0)
+ bits_(0)
{ }
// A reloc against the STT_SECTION symbol of an output section.
Output_reloc(Output_section* os, Output_data* od, Address address)
: rel_(os, 0, od, address, true),
- jump_(0), bits_(0) { }
+ bits_(0) { }
Output_reloc(Output_section* os, Sized_relobj<size, big_endian>* relobj,
unsigned int shndx, Address address)
: rel_(os, 0, relobj, shndx, address, true),
- jump_(0), bits_(0) { }
+ bits_(0) { }
// A relative relocation with no symbol.
Output_reloc(Output_data* od, Address address)
: rel_(0, od, address, true),
- jump_(0), bits_(0)
+ bits_(0)
{ }
Output_reloc(Sized_relobj<size, big_endian>* relobj,
unsigned int shndx, Address address)
: rel_(0, relobj, shndx, address, true),
- jump_(0), bits_(0)
+ bits_(0)
{ }
// Return whether this is a RELATIVE relocation.
@@ -1603,11 +1603,9 @@
// The basic reloc.
Output_reloc<elfcpp::SHT_REL, dynamic, size, big_endian> rel_;
- // Number of words to jump since last offset, maximum 0xff.
- Relr_Data jump_;
-
- // Relocations bitmap for addresses starting at the offset,
- // 24-bits/56-bits.
+ // Relocation bitmap for encoding offsets continuing from previous entry.
+ // https://groups.google.com/d/msg/generic-abi/bX460iggiKg/Pi9aSwwABgAJ
+ // 31-bits/63-bits.
Relr_Data bits_;
};
@@ -2493,8 +2491,6 @@
{
Output_reloc_writer::write(p, pov);
pov += Base::reloc_size;
- if (p->jump_ == 0)
- pov += Base::reloc_size;
}
gold_assert(pov - oview == oview_size);
@@ -2512,58 +2508,60 @@
shrink_relocs.clear();
// Always sort the relocs_ vector for RELR relocs.
- std::sort(this->relocs_.begin(), this->relocs_.end(), Sort_relocs_comparison());
+ std::sort(this->relocs_.begin(), this->relocs_.end(),
+ Sort_relocs_comparison());
- // Word size in number of bytes, used for computing jump/bits.
+ // Word size in number of bytes, used for computing the offsets bitmap.
unsigned int word_size = size / 8;
- // Number of bits to use for the relocations bitmap
- // (jump field is always 8-bit wide).
- unsigned int n_bits = size - 8;
+ // Number of bits to use for the relocation offsets bitmap.
+ // These many relative relocations can be encoded in a single entry.
+ unsigned int n_bits = size - 1;
- Address prev = 0;
- off_t addnl_relocs_size = 0;
+ Address base = 0;
typename Relocs::iterator curr = this->relocs_.begin();
while (curr != this->relocs_.end())
{
- Address delta = curr->rel_.get_address() - prev;
- Relr_Data jump = delta / word_size;
- bool aligned = (delta % word_size) == 0;
+ Address current = curr->rel_.get_address();
+ // Odd addresses are not supported in SHT_RELR.
+ gold_assert(current%2 == 0);
- // Compute bitmap for next relocations that can be folded into curr.
Relr_Data bits = 0;
typename Relocs::iterator next = curr;
- while (next != this->relocs_.end())
+ if ((base > 0) && (base <= current))
{
- Address diff = next->rel_.get_address() - curr->rel_.get_address();
- // If next is too far out, it cannot be folded into curr.
- if (diff >= (n_bits * word_size))
- break;
- // If next is not a multiple of word_size away, it cannot
- // be folded into curr.
- if ((diff % word_size) != 0)
- break;
- // next can be folded into curr, update the bitmap to include it.
- bits |= 1ULL << (diff / word_size);
- ++next;
+ while (next != this->relocs_.end())
+ {
+ Address delta = next->rel_.get_address() - base;
+ // If next is too far out, it cannot be folded into curr.
+ if (delta >= (n_bits * word_size))
+ break;
+ // If next is not a multiple of word_size away, it cannot
+ // be folded into curr.
+ if ((delta % word_size) != 0)
+ break;
+ // next can be folded into curr, add it to the bitmap.
+ bits |= 1ULL << (delta / word_size);
+ ++next;
+ }
}
- // If jump is too big, or if the delta between curr and prev is not a
- // multiple of word_size, we need to fallback to using two entries in
- // the output: the relocations bitmap, followed by the full offset.
- // This is signaled by setting jump to 0.
- if (jump > 0xff || !aligned)
- {
- jump = 0;
- addnl_relocs_size += Base::reloc_size;
- }
-
- curr->jump_ = jump;
curr->bits_ = bits;
shrink_relocs.push_back(*curr);
-
- prev = curr->rel_.get_address();
- curr = next;
+ if (bits == 0)
+ {
+ // This is not a continuation entry, only one offset was
+ // consumed. Set base offset for subsequent bitmap entries.
+ base = current + word_size;
+ ++curr;
+ }
+ else
+ {
+ // This is a continuation entry encoding multiple offsets
+ // in a bitmap. Advance base offset by n_bits words.
+ base += n_bits * word_size;
+ curr = next;
+ }
}
// Copy shrink_relocs vector to relocs_
@@ -2574,8 +2572,7 @@
{
this->relocs_.push_back(*p);
}
- this->set_current_data_size(addnl_relocs_size
- + (this->relocs_.size() * Base::reloc_size));
+ this->set_current_data_size(this->relocs_.size() * Base::reloc_size);
}
void
diff --git a/build.py b/build.py
index 6a99aca..840ba56 100755
--- a/build.py
+++ b/build.py
@@ -162,7 +162,7 @@
else:
compress_arg = '-j'
- package_path = os.path.join(dist_dir, package_name + 'tar.bz2')
+ package_path = os.path.join(dist_dir, package_name + '.tar.bz2')
cmd = [
'tar', compress_arg, '-cf', package_path, '-C', base_dir, package_name,
]