diff options
author | Han Shen <shenhan@google.com> | 2015-11-17 16:29:47 -0800 |
---|---|---|
committer | Han Shen <shenhan@google.com> | 2015-11-19 17:29:00 -0800 |
commit | 8bfb6b2bf11cfbc445239158ec28d0988f8fa947 (patch) | |
tree | 64baf9be2b2d76eb0d3d83ec6acf3d5ddd452b64 /binutils-2.25/gold/arm.cc | |
parent | 932d71b859239e834651fdee549dc661cda82fe8 (diff) | |
download | toolchain_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.cc | 103 |
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()) |