summaryrefslogtreecommitdiffstats
path: root/binutils-2.25/gold/arm.cc
diff options
context:
space:
mode:
authorHan Shen <shenhan@google.com>2015-11-17 16:29:47 -0800
committerHan Shen <shenhan@google.com>2015-11-19 17:29:00 -0800
commit8bfb6b2bf11cfbc445239158ec28d0988f8fa947 (patch)
tree64baf9be2b2d76eb0d3d83ec6acf3d5ddd452b64 /binutils-2.25/gold/arm.cc
parent932d71b859239e834651fdee549dc661cda82fe8 (diff)
downloadtoolchain_binutils-8bfb6b2bf11cfbc445239158ec28d0988f8fa947.tar.gz
toolchain_binutils-8bfb6b2bf11cfbc445239158ec28d0988f8fa947.tar.bz2
toolchain_binutils-8bfb6b2bf11cfbc445239158ec28d0988f8fa947.zip
Create an unified binutils source tree for both Android and ChromiumOS.
About source code - The base version of this binutils is newer than that of aosp/binutils-2.25, it is based on the binutils that is used to build google products and ChromiumOS. And it contains *all* local Android patches as well as all patches that are cherry-picked from upstream for aosp/binutils-2.25 tree (up to Nov. 5 - 932d71b85). You may find the detailed development history for this binutils tree here - https://chromium.googlesource.com/chromiumos/third_party/binutils/+log/unification (This CL is a combination of all the CLs in it. After this CL is submitted the tree will be identical to https://chromium.googlesource.com/chromiumos/third_party/binutils/+log/unification at 2865a3615d80bd5f82d14d7e0484e84dc052596a) About testing - We tested this binutils for both ChromiumOS and Android. For android, we tested building N4, N5X, N6, N7, N9 using new binutils, we also did a full-build of toolchain (by build.py) and built a N5X image; for ChromiumOS - it passed ChromiumOS toolchain release tests on all 4 platforms (x86, x86_64, arm32 and arm64). Change-Id: I2bb2cf579f9458d0a8bc9612331dc7d5043e3d82
Diffstat (limited to 'binutils-2.25/gold/arm.cc')
-rw-r--r--binutils-2.25/gold/arm.cc103
1 files changed, 94 insertions, 9 deletions
diff --git a/binutils-2.25/gold/arm.cc b/binutils-2.25/gold/arm.cc
index 2d10357a..86920c4f 100644
--- a/binutils-2.25/gold/arm.cc
+++ b/binutils-2.25/gold/arm.cc
@@ -1,6 +1,6 @@
// arm.cc -- arm target support for gold.
-// Copyright (C) 2009-2015 Free Software Foundation, Inc.
+// Copyright (C) 2009-2014 Free Software Foundation, Inc.
// Written by Doug Kwan <dougkwan@google.com> based on the i386 code
// by Ian Lance Taylor <iant@google.com>.
// This file also contains borrowed and adapted code from
@@ -874,7 +874,7 @@ class Stub_table : public Output_data
Stub_table(Arm_input_section<big_endian>* owner)
: Output_data(), owner_(owner), reloc_stubs_(), reloc_stubs_size_(0),
reloc_stubs_addralign_(1), cortex_a8_stubs_(), arm_v4bx_stubs_(0xf),
- prev_data_size_(0), prev_addralign_(1)
+ prev_data_size_(0), prev_addralign_(1), padding_(0)
{ }
~Stub_table()
@@ -994,14 +994,16 @@ class Stub_table : public Output_data
// Reset address and file offset.
void
do_reset_address_and_file_offset()
- { this->set_current_data_size_for_child(this->prev_data_size_); }
+ {
+ this->set_current_data_size_for_child(
+ this->prev_data_size_ + this->padding_);
+ }
// Set final data size.
void
set_final_data_size()
{ this->set_data_size(this->current_data_size()); }
- private:
// Relocate one stub.
void
relocate_stub(Stub*, const Relocate_info<32, big_endian>*,
@@ -1036,6 +1038,7 @@ class Stub_table : public Output_data
off_t prev_data_size_;
// address alignment of this in the previous pass.
uint64_t prev_addralign_;
+ off_t padding_;
};
// Arm_exidx_cantunwind class. This represents an EXIDX_CANTUNWIND entry
@@ -4560,7 +4563,7 @@ Reloc_stub::stub_type_for_reloc(
Target_arm<false>::default_target();
may_use_blx = little_endian_target->may_use_v5t_interworking();
should_force_pic_veneer |=
- little_endian_target->should_force_pic_veneer();
+ little_endian_target->should_force_pic_veneer();
thumb2 = little_endian_target->using_thumb2();
thumb_only = little_endian_target->using_thumb_only();
}
@@ -5071,6 +5074,15 @@ Stub_table<big_endian>::do_write(Output_file* of)
big_endian);
}
+ if (parameters->options().stub_group_auto_padding())
+ {
+ // Zero-fill padding area.
+ gold_assert((unsigned int)(this->prev_data_size_ + this->padding_) <= oview_size);
+ unsigned char* p_padding_area = oview + this->prev_data_size_;
+ for (unsigned int i = 0; i < this->padding_; ++i)
+ *(p_padding_area + i) = 0;
+ }
+
of->write_output_view(this->offset(), oview_size, oview);
}
@@ -5109,10 +5121,59 @@ Stub_table<big_endian>::update_data_size_and_addralign()
+ stub_template->size());
}
+ unsigned int prev_padding = this->padding_;
+
+ // Smart padding.
+ if (parameters->options().stub_group_auto_padding())
+ {
+ if(size > this->prev_data_size_)
+ {
+ // Stub table has to grow 'delta' bytes.
+ unsigned int delta = size - this->prev_data_size_;
+ // Test to see if this delta grow could be "absorbed" by the
+ // "padding_" we added in previously iteration.
+ if (delta <= this->padding_)
+ {
+ // Yes! Grow into padding area, shrink padding, keep stub table
+ // size unchanged.
+ this->padding_ -= delta;
+ }
+ else
+ {
+ // No! Delta is too much to fit in padding area. Heuristically, we
+ // increase padding. Padding is about 0.5% of huge increment, or
+ // 2% of moderate increment, or 0% for smaller ones..
+ if (delta >= 0x50000)
+ this->padding_ = 0x250;
+ else if (delta >= 0x30000)
+ this->padding_ = 0x150;
+ else if (delta >= 0x10000)
+ this->padding_ = 0x100;
+ else if (delta >= 0x500)
+ {
+ // Set padding to 2% of stub table growth delta or 0x40,
+ // whichever is smaller.
+ this->padding_ = std::min((unsigned int)(delta * 0.02),
+ (unsigned int)0x40);
+ }
+ }
+ }
+ else if (size < this->prev_data_size_)
+ {
+ // Stub table shrinks, this is rare, but not impossible.
+ unsigned int delta = this->prev_data_size_ - size;
+ // So let padding increase to absorb the shrinking. Still we get an
+ // unchanged stub table.
+ this->padding_ += delta;
+ }
+ }
+
// Check if either data size or alignment changed in this pass.
// Update prev_data_size_ and prev_addralign_. These will be used
// as the current data size and address alignment for the next pass.
- bool changed = size != this->prev_data_size_;
+ bool changed = (size + this->padding_) !=
+ this->prev_data_size_ + prev_padding;
+
this->prev_data_size_ = size;
if (addralign != this->prev_addralign_)
@@ -5852,7 +5913,7 @@ Arm_output_section<big_endian>::group_sections(
(state == FINDING_STUB_SECTION
? group_end
: stub_table),
- target, &new_relaxed_sections, task);
+ target, &new_relaxed_sections, task);
}
// Convert input section into relaxed input section in a batch.
@@ -10557,6 +10618,7 @@ Target_arm<big_endian>::do_adjust_elf_header(
}
elfcpp::Ehdr_write<32, big_endian> oehdr(view);
oehdr.put_e_ident(e_ident);
+ oehdr.put_e_flags(this->processor_specific_flags());
}
// do_make_elf_object to override the same function in the base class.
@@ -10753,6 +10815,24 @@ Target_arm<big_endian>::tag_cpu_arch_combine(
T(V7E_M), // V6S_M.
T(V7E_M) // V7E_M.
};
+ static const int v8[] =
+ {
+ T(V8), // PRE_V4.
+ T(V8), // V4.
+ T(V8), // V4T.
+ T(V8), // V5T.
+ T(V8), // V5TE.
+ T(V8), // V5TEJ.
+ T(V8), // V6.
+ T(V8), // V6KZ.
+ T(V8), // V6T2.
+ T(V8), // V6K.
+ T(V8), // V7.
+ T(V8), // V6_M.
+ T(V8), // V6S_M.
+ T(V8), // V7E_M.
+ T(V8) // V8.
+ };
static const int v4t_plus_v6_m[] =
{
-1, // PRE_V4.
@@ -10769,6 +10849,7 @@ Target_arm<big_endian>::tag_cpu_arch_combine(
T(V6_M), // V6_M.
T(V6S_M), // V6S_M.
T(V7E_M), // V7E_M.
+ T(V8), // V8.
T(V4T_PLUS_V6_M) // V4T plus V6_M.
};
static const int* comb[] =
@@ -10779,6 +10860,7 @@ Target_arm<big_endian>::tag_cpu_arch_combine(
v6_m,
v6s_m,
v7e_m,
+ v8,
// Pseudo-architecture.
v4t_plus_v6_m
};
@@ -10876,7 +10958,8 @@ Target_arm<big_endian>::tag_cpu_name_value(unsigned int value)
"ARM v7",
"ARM v6-M",
"ARM v6S-M",
- "ARM v7E-M"
+ "ARM v7E-M",
+ "ARM v8"
};
const size_t name_table_size = sizeof(name_table) / sizeof(name_table[0]);
@@ -12157,7 +12240,9 @@ Target_arm<big_endian>::do_relax(
bool any_stub_table_changed = false;
Unordered_set<const Output_section*> sections_needing_adjustment;
for (Stub_table_iterator sp = this->stub_tables_.begin();
- (sp != this->stub_tables_.end()) && !any_stub_table_changed;
+ (sp != this->stub_tables_.end()
+ && (parameters->options().stub_group_auto_padding()
+ || !any_stub_table_changed));
++sp)
{
if ((*sp)->update_data_size_and_addralign())