From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 39331 invoked by alias); 2 Dec 2015 18:17:57 -0000 Mailing-List: contact binutils-help@sourceware.org; run by ezmlm Precedence: bulk List-Id: List-Subscribe: List-Archive: List-Post: List-Help: , Sender: binutils-owner@sourceware.org Received: (qmail 39319 invoked by uid 89); 2 Dec 2015 18:17:56 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=-2.5 required=5.0 tests=AWL,BAYES_00,RCVD_IN_DNSWL_LOW,SPF_PASS,T_RP_MATCHES_RCVD autolearn=ham version=3.3.2 X-HELO: mail-yk0-f177.google.com Received: from mail-yk0-f177.google.com (HELO mail-yk0-f177.google.com) (209.85.160.177) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with (AES128-GCM-SHA256 encrypted) ESMTPS; Wed, 02 Dec 2015 18:17:55 +0000 Received: by ykdr82 with SMTP id r82so56561264ykd.3 for ; Wed, 02 Dec 2015 10:17:53 -0800 (PST) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20130820; h=x-gm-message-state:mime-version:in-reply-to:references:date :message-id:subject:from:to:cc:content-type; bh=NqSVOJbZLXz2SNvB/Tc9KvPWo6Rg9GdGErR4DxqvHpg=; b=AOC94ZPKBirzPc7qvgRZ/Wk4wZgBj5+L9ZjPe9tfuF+Dd7C947AFdefAuy0d6GY5Ir y05YEMCbpUzR0kdq/9cRPewBF7XiVeRiGz2xo4uyD42ced7dTQh8bNUytHSs8ZMqTU0u 0nnEEiBBnLxUIxBGhShD4GIcDdInCqLGOTqhpaupmQ6zRkop5eQ4XNcRzz++RTEgZ+AQ EmCCVeO/v+ej1XyX5de5qNykv8qWxXVPvouaDLo3wgCC6iZiblNUI/etKpPZI8Mrt9+w ostnoQMDOcThPH/w1dG64GZ85TeT5UiN+Ts4SowwuOGEH0tLBs0YnHQQ+sqA+soWaDLZ wYsA== X-Gm-Message-State: ALoCoQm1qVzXfQxN/IapwBQTmZa98sKqaC8OPT8/lXDRCPaCkYs1FYS863IBBItrGwaxN8SItZ2m MIME-Version: 1.0 X-Received: by 10.13.194.193 with SMTP id e184mr3140215ywd.203.1449080273068; Wed, 02 Dec 2015 10:17:53 -0800 (PST) Received: by 10.37.214.214 with HTTP; Wed, 2 Dec 2015 10:17:52 -0800 (PST) In-Reply-To: <1448063109-18860-1-git-send-email-pcc@google.com> References: <1448063109-18860-1-git-send-email-pcc@google.com> Date: Wed, 02 Dec 2015 18:17:00 -0000 Message-ID: Subject: Re: [PATCH] gold: Implement --long-plt flag. From: Peter Collingbourne To: binutils@sourceware.org Cc: ccoutant@gmail.com Content-Type: text/plain; charset=UTF-8 X-IsSubscribed: yes X-SW-Source: 2015-12/txt/msg00026.txt.bz2 Ping. On Fri, Nov 20, 2015 at 3:45 PM, Peter Collingbourne wrote: > gold/ > PR gold/18780 > * arm.cc (Target_arm::do_make_data_plt): Choose PLT generator based > on value of --long-plt flag. > (Output_data_plt_arm_standard::do_get_plt_entry_size): Moved to > Output_data_plt_arm_short. > (Output_data_plt_arm_standard::do_fill_plt_entry): Likewise. > (Output_data_plt_arm_standard::plt_entry): Likewise. > (Output_data_plt_arm_standard::do_fill_first_plt_entry): Fix > variable reference. > (Output_data_plt_arm_short): New class. > (Output_data_plt_arm_long): New class. > * options.h (General_options): Define --long-plt flag. > --- > gold/arm.cc | 124 +++++++++++++++++++++++++++++++++++++++++++++++---------- > gold/options.h | 4 ++ > 2 files changed, 108 insertions(+), 20 deletions(-) > > diff --git a/gold/arm.cc b/gold/arm.cc > index 4a6d414..2381442 100644 > --- a/gold/arm.cc > +++ b/gold/arm.cc > @@ -62,7 +62,10 @@ template > class Output_data_plt_arm; > > template > -class Output_data_plt_arm_standard; > +class Output_data_plt_arm_short; > + > +template > +class Output_data_plt_arm_long; > > template > class Stub_table; > @@ -2555,7 +2558,11 @@ class Target_arm : public Sized_target<32, big_endian> > Output_data_space* got_irelative) > { > gold_assert(got_plt != NULL && got_irelative != NULL); > - return new Output_data_plt_arm_standard( > + if (parameters->options().long_plt()) > + return new Output_data_plt_arm_long( > + layout, got, got_plt, got_irelative); > + else > + return new Output_data_plt_arm_short( > layout, got, got_plt, got_irelative); > } > > @@ -7719,29 +7726,14 @@ class Output_data_plt_arm_standard : public Output_data_plt_arm > do_first_plt_entry_offset() const > { return sizeof(first_plt_entry); } > > - // Return the size of a PLT entry. > - virtual unsigned int > - do_get_plt_entry_size() const > - { return sizeof(plt_entry); } > - > virtual void > do_fill_first_plt_entry(unsigned char* pov, > Arm_address got_address, > Arm_address plt_address); > > - virtual void > - do_fill_plt_entry(unsigned char* pov, > - Arm_address got_address, > - Arm_address plt_address, > - unsigned int got_offset, > - unsigned int plt_offset); > - > private: > // Template for the first PLT entry. > static const uint32_t first_plt_entry[5]; > - > - // Template for subsequent PLT entries. > - static const uint32_t plt_entry[3]; > }; > > // ARM PLTs. > @@ -7769,7 +7761,7 @@ Output_data_plt_arm_standard::do_fill_first_plt_entry( > { > // Write first PLT entry. All but the last word are constants. > const size_t num_first_plt_words = (sizeof(first_plt_entry) > - / sizeof(plt_entry[0])); > + / sizeof(first_plt_entry[0])); > for (size_t i = 0; i < num_first_plt_words - 1; i++) > elfcpp::Swap<32, big_endian>::writeval(pov + i * 4, first_plt_entry[i]); > // Last word in first PLT entry is &GOT[0] - . > @@ -7778,9 +7770,39 @@ Output_data_plt_arm_standard::do_fill_first_plt_entry( > } > > // Subsequent entries in the PLT. > +// This class generates short (12-byte) entries, for displacements up to 2^28. > > template > -const uint32_t Output_data_plt_arm_standard::plt_entry[3] = > +class Output_data_plt_arm_short : public Output_data_plt_arm_standard > +{ > + public: > + Output_data_plt_arm_short(Layout* layout, > + Arm_output_data_got* got, > + Output_data_space* got_plt, > + Output_data_space* got_irelative) > + : Output_data_plt_arm_standard(layout, got, got_plt, got_irelative) > + { } > + > + protected: > + // Return the size of a PLT entry. > + virtual unsigned int > + do_get_plt_entry_size() const > + { return sizeof(plt_entry); } > + > + virtual void > + do_fill_plt_entry(unsigned char* pov, > + Arm_address got_address, > + Arm_address plt_address, > + unsigned int got_offset, > + unsigned int plt_offset); > + > + private: > + // Template for subsequent PLT entries. > + static const uint32_t plt_entry[3]; > +}; > + > +template > +const uint32_t Output_data_plt_arm_short::plt_entry[3] = > { > 0xe28fc600, // add ip, pc, #0xNN00000 > 0xe28cca00, // add ip, ip, #0xNN000 > @@ -7789,7 +7811,7 @@ const uint32_t Output_data_plt_arm_standard::plt_entry[3] = > > template > void > -Output_data_plt_arm_standard::do_fill_plt_entry( > +Output_data_plt_arm_short::do_fill_plt_entry( > unsigned char* pov, > Arm_address got_address, > Arm_address plt_address, > @@ -7808,6 +7830,68 @@ Output_data_plt_arm_standard::do_fill_plt_entry( > elfcpp::Swap<32, big_endian>::writeval(pov + 8, plt_insn2); > } > > +// This class generates long (16-byte) entries, for arbitrary displacements. > + > +template > +class Output_data_plt_arm_long : public Output_data_plt_arm_standard > +{ > + public: > + Output_data_plt_arm_long(Layout* layout, > + Arm_output_data_got* got, > + Output_data_space* got_plt, > + Output_data_space* got_irelative) > + : Output_data_plt_arm_standard(layout, got, got_plt, got_irelative) > + { } > + > + protected: > + // Return the size of a PLT entry. > + virtual unsigned int > + do_get_plt_entry_size() const > + { return sizeof(plt_entry); } > + > + virtual void > + do_fill_plt_entry(unsigned char* pov, > + Arm_address got_address, > + Arm_address plt_address, > + unsigned int got_offset, > + unsigned int plt_offset); > + > + private: > + // Template for subsequent PLT entries. > + static const uint32_t plt_entry[4]; > +}; > + > +template > +const uint32_t Output_data_plt_arm_long::plt_entry[4] = > +{ > + 0xe28fc200, // add ip, pc, #0xN0000000 > + 0xe28cc600, // add ip, ip, #0xNN00000 > + 0xe28cca00, // add ip, ip, #0xNN000 > + 0xe5bcf000, // ldr pc, [ip, #0xNNN]! > +}; > + > +template > +void > +Output_data_plt_arm_long::do_fill_plt_entry( > + unsigned char* pov, > + Arm_address got_address, > + Arm_address plt_address, > + unsigned int got_offset, > + unsigned int plt_offset) > +{ > + int32_t offset = ((got_address + got_offset) > + - (plt_address + plt_offset + 8)); > + > + uint32_t plt_insn0 = plt_entry[0] | (offset >> 28); > + elfcpp::Swap<32, big_endian>::writeval(pov, plt_insn0); > + uint32_t plt_insn1 = plt_entry[1] | ((offset >> 20) & 0xff); > + elfcpp::Swap<32, big_endian>::writeval(pov + 4, plt_insn1); > + uint32_t plt_insn2 = plt_entry[2] | ((offset >> 12) & 0xff); > + elfcpp::Swap<32, big_endian>::writeval(pov + 8, plt_insn2); > + uint32_t plt_insn3 = plt_entry[3] | (offset & 0xfff); > + elfcpp::Swap<32, big_endian>::writeval(pov + 12, plt_insn3); > +} > + > // Write out the PLT. This uses the hand-coded instructions above, > // and adjusts them as needed. This is all specified by the arm ELF > // Processor Supplement. > diff --git a/gold/options.h b/gold/options.h > index ffc44e6..d83ea54 100644 > --- a/gold/options.h > +++ b/gold/options.h > @@ -834,6 +834,10 @@ class General_options > "veneer"), > NULL); > > + DEFINE_bool(long_plt, options::TWO_DASHES, '\0', false, > + N_("(ARM only) Generate long PLT entries."), > + N_("(ARM only) Do not generate long PLT entries.")); > + > DEFINE_bool(g, options::EXACTLY_ONE_DASH, '\0', false, > N_("Ignored"), NULL); > > -- > 2.6.0.rc2.230.g3dd15c0 >