From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 76762 invoked by alias); 9 Aug 2016 09:57:36 -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 75490 invoked by uid 89); 9 Aug 2016 09:57:35 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=-2.3 required=5.0 tests=BAYES_00,RP_MATCHES_RCVD,SPF_PASS autolearn=ham version=3.3.2 spammy=elfcpp, GOT, uint32_t, PLT X-HELO: foss.arm.com Received: from foss.arm.com (HELO foss.arm.com) (217.140.101.70) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with ESMTP; Tue, 09 Aug 2016 09:57:21 +0000 Received: from usa-sjc-imap-foss1.foss.arm.com (unknown [10.72.51.249]) by usa-sjc-mx-foss1.foss.arm.com (Postfix) with ESMTP id 02D9E2F; Tue, 9 Aug 2016 02:58:47 -0700 (PDT) Received: from e105689-lin.cambridge.arm.com (e105689-lin.cambridge.arm.com [10.2.207.32]) by usa-sjc-imap-foss1.foss.arm.com (Postfix) with ESMTPSA id 33FE53F459; Tue, 9 Aug 2016 02:57:19 -0700 (PDT) Subject: Re: [Patch][Gold] BE8 for ARM To: "Bharathi Seshadri (bseshadr)" , "binutils@sourceware.org" References: Cc: "ccoutant@gmail.com" From: "Richard Earnshaw (lists)" Message-ID: Date: Tue, 09 Aug 2016 09:57:00 -0000 User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:45.0) Gecko/20100101 Thunderbird/45.2.0 MIME-Version: 1.0 In-Reply-To: Content-Type: text/plain; charset=us-ascii Content-Transfer-Encoding: 7bit X-SW-Source: 2016-08/txt/msg00052.txt.bz2 On 08/07/16 00:25, Bharathi Seshadri (bseshadr) wrote: > Hi, > > This patch implements the BE8 support for ARM in the gold linker. It has been tested on a non-trivial large program (size ~120MB). > Thanks to Cary Coutant for his initial review. > > gold/ChangeLog > 2016-07-07 Bharathi Seshadri > > * options.h (General_options): Add --be8 option. > * arm.cc (Arm_relobj::do_relocate_sections): Add code to swap for be8. > (Output_data_plt_arm_standard::do_fill_first_plt_entry): Likewise. > (Output_data_plt_arm_short::do_fill_plt_entry): Likewise. > (Output_data_plt_arm_long::do_fill_plt_entry): Likewise. > (Target_arm::do_adjust_elf_header): Do EF_ARM_BE8 adjustment. > > Regards, > Bharathi > Why are you only swapping ARM code? Thumb is just the same, but in granules of 2 bytes rather than 4. R. > > be8_arm_patch.txt > > > diff --git a/gold/arm.cc b/gold/arm.cc > index c47b002..4b0f85f 100644 > --- a/gold/arm.cc > +++ b/gold/arm.cc > @@ -6639,6 +6639,60 @@ Arm_relobj::do_relocate_sections( > section_address, > section_size); > } > + > + // BE8 swapping > + if (parameters->options().user_set_be8()) > + { > + section_size_type span_start, span_end; > + elfcpp::Shdr<32, big_endian> > + shdr(pshdrs + i * elfcpp::Elf_sizes<32>::shdr_size); > + Mapping_symbol_position section_start(i, 0); > + typename Mapping_symbols_info::const_iterator p = > + this->mapping_symbols_info_.lower_bound(section_start); > + unsigned char* view = (*pviews)[i].view; > + Arm_address view_address = (*pviews)[i].address; > + section_size_type view_size = (*pviews)[i].view_size; > + while (p != this->mapping_symbols_info_.end() && p->first.first == i) > + { > + typename Mapping_symbols_info::const_iterator next = > + this->mapping_symbols_info_.upper_bound(p->first); > + > + // Only swap arm code. > + if (p->second == 'a') > + { > + Output_section* os = this->output_section(i); > + gold_assert(os != NULL); > + Arm_address section_address = > + this->simple_input_section_output_address(i, os); > + span_start = convert_to_section_size_type(p->first.second); > + if (next != this->mapping_symbols_info_.end() > + && next->first.first == i) > + span_end = convert_to_section_size_type(next->first.second); > + else > + span_end = convert_to_section_size_type(shdr.get_sh_size()); > + unsigned char* section_view = > + view + (section_address - view_address); > + uint64_t section_size = this->section_size(i); > + > + gold_assert(section_address >= view_address > + && ((section_address + section_size) > + <= (view_address + view_size))); > + > + // Set Output view for swapping > + unsigned char *oview = section_view + span_start; > + unsigned int index = 0; > + while (index + 3 < (span_end - span_start)) > + { > + typedef typename elfcpp::Swap<32, big_endian>::Valtype Valtype; > + Valtype* wv = reinterpret_cast(oview+index); > + uint32_t val = elfcpp::Swap<32, false>::readval(wv); > + elfcpp::Swap<32, true>::writeval(wv, val); > + index += 4; > + } > + } > + p = next; > + } > + } > } > } > > @@ -7785,9 +7839,16 @@ Output_data_plt_arm_standard::do_fill_first_plt_entry( > const size_t num_first_plt_words = (sizeof(first_plt_entry) > / 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]); > + if (parameters->options().user_set_be8()) > + elfcpp::Swap<32, false>::writeval(pov + i * 4, first_plt_entry[i]); > + else > + elfcpp::Swap<32, big_endian>::writeval(pov + i * 4, first_plt_entry[i]); > // Last word in first PLT entry is &GOT[0] - . > - elfcpp::Swap<32, big_endian>::writeval(pov + 16, > + if (parameters->options().user_set_be8()) > + elfcpp::Swap<32, false>::writeval(pov + 16, > + got_address - (plt_address + 16)); > + else > + elfcpp::Swap<32, big_endian>::writeval(pov + 16, > got_address - (plt_address + 16)); > } > > @@ -7846,11 +7907,20 @@ Output_data_plt_arm_short::do_fill_plt_entry( > gold_error(_("PLT offset too large, try linking with --long-plt")); > > uint32_t plt_insn0 = plt_entry[0] | ((offset >> 20) & 0xff); > - elfcpp::Swap<32, big_endian>::writeval(pov, plt_insn0); > uint32_t plt_insn1 = plt_entry[1] | ((offset >> 12) & 0xff); > - elfcpp::Swap<32, big_endian>::writeval(pov + 4, plt_insn1); > uint32_t plt_insn2 = plt_entry[2] | (offset & 0xfff); > - elfcpp::Swap<32, big_endian>::writeval(pov + 8, plt_insn2); > + if (parameters->options().user_set_be8()) > + { > + elfcpp::Swap<32, false>::writeval(pov, plt_insn0); > + elfcpp::Swap<32, false>::writeval(pov + 4, plt_insn1); > + elfcpp::Swap<32, false>::writeval(pov + 8, plt_insn2); > + } > + else > + { > + elfcpp::Swap<32, big_endian>::writeval(pov, plt_insn0); > + elfcpp::Swap<32, big_endian>::writeval(pov + 4, plt_insn1); > + elfcpp::Swap<32, big_endian>::writeval(pov + 8, plt_insn2); > + } > } > > // This class generates long (16-byte) entries, for arbitrary displacements. > @@ -7906,13 +7976,23 @@ Output_data_plt_arm_long::do_fill_plt_entry( > - (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); > + if (parameters->options().user_set_be8()) > + { > + elfcpp::Swap<32, false>::writeval(pov, plt_insn0); > + elfcpp::Swap<32, false>::writeval(pov + 4, plt_insn1); > + elfcpp::Swap<32, false>::writeval(pov + 8, plt_insn2); > + elfcpp::Swap<32, false>::writeval(pov + 12, plt_insn3); > + } > + else > + { > + elfcpp::Swap<32, big_endian>::writeval(pov, plt_insn0); > + elfcpp::Swap<32, big_endian>::writeval(pov + 4, plt_insn1); > + elfcpp::Swap<32, big_endian>::writeval(pov + 8, plt_insn2); > + elfcpp::Swap<32, big_endian>::writeval(pov + 12, plt_insn3); > + } > } > > // Write out the PLT. This uses the hand-coded instructions above, > @@ -10683,7 +10763,14 @@ Target_arm::do_adjust_elf_header( > e_ident[elfcpp::EI_OSABI] = 0; > e_ident[elfcpp::EI_ABIVERSION] = 0; > > - // FIXME: Do EF_ARM_BE8 adjustment. > + // Do EF_ARM_BE8 adjustment. > + if (parameters->options().user_set_be8() && !big_endian) > + gold_error("BE8 images only valid in big-endian mode."); > + if (parameters->options().user_set_be8()) > + { > + flags |= elfcpp::EF_ARM_BE8; > + this->set_processor_specific_flags(flags); > + } > > // If we're working in EABI_VER5, set the hard/soft float ABI flags > // as appropriate. > diff --git a/gold/options.h b/gold/options.h > index 23c9658..7260c41 100644 > --- a/gold/options.h > +++ b/gold/options.h > @@ -674,6 +674,9 @@ class General_options > DEFINE_bool_alias(dn, Bdynamic, options::ONE_DASH, '\0', > N_("alias for -Bstatic"), NULL, true); > > + DEFINE_bool(be8,options::TWO_DASHES, '\0', false, > + N_("(ARM only) be8 -byte invariant addressing."), NULL); > + > DEFINE_bool(Bgroup, options::ONE_DASH, '\0', false, > N_("Use group name lookup rules for shared library"), NULL); > >