From patchwork Fri Jun 23 11:40:38 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Alan Modra X-Patchwork-Id: 112094 Return-Path: Delivered-To: ouuuleilei@gmail.com Received: by 2002:a59:994d:0:b0:3d9:f83d:47d9 with SMTP id k13csp5705326vqr; Fri, 23 Jun 2023 04:40:53 -0700 (PDT) X-Google-Smtp-Source: ACHHUZ7+nw5I465JtcKCzEvZPwW/0rGaRu+/uc/5m33jvgyMOHDviT5gW5/fNeuYUJ74dg4TQOci X-Received: by 2002:aa7:cd45:0:b0:514:994c:2982 with SMTP id v5-20020aa7cd45000000b00514994c2982mr13900864edw.40.1687520452900; Fri, 23 Jun 2023 04:40:52 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1687520452; cv=none; d=google.com; s=arc-20160816; b=u6ya5vRQrDBqETi+eOt8EqdKO0JVeHhyO2dt596EOmSiA8zKIEOhMOK0Kw6znQKa91 gqAXEM1hEyEWXPof319qTdvEgxBG+nfW9LL/+IXSquGYz0cnEa3yHFEU5f1YwO1+v1JI d4NMNpIkBIHPxOD3n6OGJRAcMC1p8M6Iw88E7OktHxHc4o+P07J0+SUbHw3t+G0F/1k9 bD3rV7AbcpGz2VSMwCHgqQoa5HpYkfPH20ImHzeEie0P2Pxm0neTxXuxtJwPAq0DtJpB CuO5LQ3x+38DyBSYsTSCjBzHS01PcUN1wo8kAjHQWUiT+ii0jzX3V7l7gq3LMtlHUaJj fFxA== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=sender:errors-to:reply-to:from:list-subscribe:list-help:list-post :list-archive:list-unsubscribe:list-id:precedence:in-reply-to :content-disposition:mime-version:references:message-id:subject:to :date:dmarc-filter:delivered-to:dkim-signature:dkim-filter; bh=JG0GEEvJplXz6zTJmzvPC9/UouSHgN20JHm0ckl3204=; b=zhXOrpHrh6LYZdMgS3mKhNRYyhiD254Fq9uPVASS0WWyyxw/IJFtGGII2Y/YfIle7h kzus7EdHJrV8R/UER8SYtaJhDABCA8oocb+i/nFn+hD9j1DEf7Ne87v2XcKhYfIlL4Zg /tIFCSv8U/uAxYdrVE/wEPSKoTUh/at6rxft/jrRrA8mTbffuAKxswl0nEctrEnLGKWf pKbZ3byzPGh1Kj6jCkBIpTg4mMaKPxEYhZBtNydqQO3Oi+OUuhluCiBufo/iu5K8Nx4y ZfAURX+n1SRfOQ5CfKJNNi6EqWwuI4EHA/9COV/OM4ZF3rXqCgROteh4D90FBzm+8Qu0 a5Lw== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@sourceware.org header.s=default header.b=muwa7Jf5; spf=pass (google.com: domain of binutils-bounces+ouuuleilei=gmail.com@sourceware.org designates 8.43.85.97 as permitted sender) smtp.mailfrom="binutils-bounces+ouuuleilei=gmail.com@sourceware.org"; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=sourceware.org Received: from sourceware.org (ip-8-43-85-97.sourceware.org. [8.43.85.97]) by mx.google.com with ESMTPS id j19-20020aa7ca53000000b0051a2cd86dc4si2041307edt.524.2023.06.23.04.40.52 for (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 23 Jun 2023 04:40:52 -0700 (PDT) Received-SPF: pass (google.com: domain of binutils-bounces+ouuuleilei=gmail.com@sourceware.org designates 8.43.85.97 as permitted sender) client-ip=8.43.85.97; Authentication-Results: mx.google.com; dkim=pass header.i=@sourceware.org header.s=default header.b=muwa7Jf5; spf=pass (google.com: domain of binutils-bounces+ouuuleilei=gmail.com@sourceware.org designates 8.43.85.97 as permitted sender) smtp.mailfrom="binutils-bounces+ouuuleilei=gmail.com@sourceware.org"; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=sourceware.org Received: from server2.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id BAD733858404 for ; Fri, 23 Jun 2023 11:40:51 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org BAD733858404 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=sourceware.org; s=default; t=1687520451; bh=JG0GEEvJplXz6zTJmzvPC9/UouSHgN20JHm0ckl3204=; h=Date:To:Subject:References:In-Reply-To:List-Id:List-Unsubscribe: List-Archive:List-Post:List-Help:List-Subscribe:From:Reply-To: From; b=muwa7Jf55tNypiyypg5dGBJsMtchrC7aM9FU4oWCpt4+fsZF0U6Q26j3yrX0OzyMD gXun1YXLRcuVxsByGBlZ3PE2Ksnk6fKqX7uOL79kV8YX0aIokpDM2WOSAJqlXjirYq Y2n2Nnq4SzVRf7IfTGRYWSl+bANzP3ddbNsqepaE= X-Original-To: binutils@sourceware.org Delivered-To: binutils@sourceware.org Received: from mail-pl1-x633.google.com (mail-pl1-x633.google.com [IPv6:2607:f8b0:4864:20::633]) by sourceware.org (Postfix) with ESMTPS id 393303858CD1 for ; Fri, 23 Jun 2023 11:40:43 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.2 sourceware.org 393303858CD1 Received: by mail-pl1-x633.google.com with SMTP id d9443c01a7336-1b5452b77b4so3929675ad.3 for ; Fri, 23 Jun 2023 04:40:43 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20221208; t=1687520442; x=1690112442; h=in-reply-to:content-disposition:mime-version:references:message-id :subject:to:from:date:x-gm-message-state:from:to:cc:subject:date :message-id:reply-to; bh=JG0GEEvJplXz6zTJmzvPC9/UouSHgN20JHm0ckl3204=; b=T84Oe9geOrH129QIAO9hS7K4aTRNM1DB7lpTTioNr/CUV7UJmbtS52jYDpyThhYpiI anc9AP71XhZtFWY8khaSziK6OUcu3Qwfce7wZUpa2hHTotZOQ1Z7WXmEENbNWxh0KsiQ 2bXWiiQpK3Wh1IKv76RuHM2wbLpkhAI80mEnVTp8nciAVoniWLsB9uhedx8ojVkmcKr8 uflhqafTEmeYd8qUU1c5gwhkwfsnHqDcOLv1PWeX+6A/GoQHNkHlgvX8IBptRQjFL/Jg 6dtMFDBjlKZN8n06RMs3TY7NdvH9DYfnWNI87pRnAleKqCOVMu2eJ9VQ1BdMPaOnhYKl 4GdA== X-Gm-Message-State: AC+VfDw/47lQQSojNO2iEgk4CydVmaFUdO6bZyaJlwaP4uefe3k7i9lX 8SSBjeyHJZXjB6MLzDyy0Xk/8xa63dg= X-Received: by 2002:a17:903:2284:b0:1b6:66f1:358f with SMTP id b4-20020a170903228400b001b666f1358fmr15223308plh.24.1687520441669; Fri, 23 Jun 2023 04:40:41 -0700 (PDT) Received: from squeak.grove.modra.org (158.106.96.58.static.exetel.com.au. [58.96.106.158]) by smtp.gmail.com with ESMTPSA id q15-20020a170902bd8f00b001a5fccab02dsm6994837pls.177.2023.06.23.04.40.40 for (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 23 Jun 2023 04:40:41 -0700 (PDT) Received: by squeak.grove.modra.org (Postfix, from userid 1000) id C51EB1142EC8; Fri, 23 Jun 2023 21:10:38 +0930 (ACST) Date: Fri, 23 Jun 2023 21:10:38 +0930 To: binutils@sourceware.org Subject: [GOLD] PowerPC64 huge branch dynamic relocs Message-ID: References: MIME-Version: 1.0 Content-Disposition: inline In-Reply-To: X-Spam-Status: No, score=-3034.6 required=5.0 tests=BAYES_00, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, DKIM_VALID_EF, FREEMAIL_FROM, GIT_PATCH_0, RCVD_IN_DNSWL_NONE, SPF_HELO_NONE, SPF_PASS, TXREP, T_SCC_BODY_TEXT_LINE autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on server2.sourceware.org X-BeenThere: binutils@sourceware.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Binutils mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-Patchwork-Original-From: Alan Modra via Binutils From: Alan Modra Reply-To: Alan Modra Errors-To: binutils-bounces+ouuuleilei=gmail.com@sourceware.org Sender: "Binutils" X-getmail-retrieved-from-mailbox: =?utf-8?q?INBOX?= X-GMAIL-THRID: =?utf-8?q?1769493446192128677?= X-GMAIL-MSGID: =?utf-8?q?1769493446192128677?= PowerPC64 gold and ld.bfd implement an indirect branch trampoline, used when the destination of a branch exceeds a bounce through another "b" instruction. When generating PIEs or shared libraries, the addresses need dynamic relocations. This was implemented in gold using a dedicated relocation section, but this means the relative relocations for these addresses are not sorted properly with other dynamic relative relocations: gold doesn't support merging relocation sections, then sorting. Instead we need to use a single .rela.dyn section. This is done by increasing the size of rela_dyn_ during do_relax to account for needed dynamic relocations, delaying adding the actual relocations until the end of relaxation once the layout has stabilised. * powerpc.cc (Target_powerpc): Add rela_dyn_size_; (update_current_size): New function. (Target_powerpc::do_relax): Capture the size of rela_dyn_ at the start of relaxation. Artifically increase its size during relaxation to account for needed indirect branches, and add those relocations at the end. (Output_data_brlt_powerpc::rel_, reset_brlt_sizes), (finalize_brlt_sizes, add_reloc, set_current_size): Delete. (Target_powerpc::make_brlt_section): Don't make reloc section. diff --git a/gold/powerpc.cc b/gold/powerpc.cc index 5838b49e341..96fef7b8dde 100644 --- a/gold/powerpc.cc +++ b/gold/powerpc.cc @@ -1763,6 +1763,8 @@ class Target_powerpc : public Sized_target Branches branch_info_; Tocsave_loc tocsave_loc_; + off_t rela_dyn_size_; + bool power10_relocs_; bool plt_thread_safe_; bool plt_localentry0_; @@ -3687,6 +3689,18 @@ Target_powerpc::Branch_info::make_stub( return ok; } +// Helper for do_relax, avoiding checks that size, address and offset +// are not set more than once. + +static inline void +update_current_size(Output_section_data_build* od, off_t cur_size) +{ + od->reset_address_and_file_offset(); + od->set_current_data_size(cur_size); + od->finalize_data_size(); + od->output_section()->set_section_offsets_need_adjustment(); +} + // Relaxation hook. This is where we do stub generation. template @@ -3752,10 +3766,11 @@ Target_powerpc::do_relax(int pass, } } this->plt_thread_safe_ = thread_safe; - } - if (pass == 1) - { + if (parameters->options().output_is_position_independent()) + this->rela_dyn_size_ + = this->rela_dyn_section(layout)->current_data_size(); + this->stub_group_size_ = parameters->options().stub_group_size(); bool no_size_errors = true; if (this->stub_group_size_ == 1) @@ -3868,7 +3883,15 @@ Target_powerpc::do_relax(int pass, if (size == 64 && num_huge_branches != 0) this->make_brlt_section(layout); if (size == 64 && again) - this->brlt_section_->set_current_size(num_huge_branches); + { + update_current_size(this->brlt_section_, num_huge_branches * 16); + if (parameters->options().output_is_position_independent()) + { + const unsigned int reloc_size = elfcpp::Elf_sizes::rela_size; + off_t cur = this->rela_dyn_size_ + num_huge_branches * reloc_size; + update_current_size(this->rela_dyn_, cur); + } + } for (typename Stub_tables::reverse_iterator p = this->stub_tables_.rbegin(); p != this->stub_tables_.rend(); @@ -3937,15 +3960,21 @@ Target_powerpc::do_relax(int pass, && parameters->options().output_is_position_independent()) { // Fill in the BRLT relocs. - this->brlt_section_->reset_brlt_sizes(); + this->rela_dyn_->reset_data_size(); + this->rela_dyn_->set_current_data_size(this->rela_dyn_size_); for (typename Branch_lookup_table::const_iterator p = this->branch_lookup_table_.begin(); p != this->branch_lookup_table_.end(); ++p) { - this->brlt_section_->add_reloc(p->first, p->second); + this->rela_dyn_->add_relative(elfcpp::R_POWERPC_RELATIVE, + this->brlt_section_, p->second, + p->first); } - this->brlt_section_->finalize_brlt_sizes(); + this->rela_dyn_->finalize_data_size(); + const unsigned int reloc_size = elfcpp::Elf_sizes::rela_size; + gold_assert(this->rela_dyn_->data_size() + == this->rela_dyn_size_ + num_huge_branches * reloc_size); } if (!again @@ -4554,52 +4583,11 @@ class Output_data_brlt_powerpc : public Output_section_data_build typedef Output_data_reloc Reloc_section; - Output_data_brlt_powerpc(Target_powerpc* targ, - Reloc_section* brlt_rel) + Output_data_brlt_powerpc(Target_powerpc* targ) : Output_section_data_build(size == 32 ? 4 : 8), - rel_(brlt_rel), targ_(targ) { } - void - reset_brlt_sizes() - { - this->reset_data_size(); - this->rel_->reset_data_size(); - } - - void - finalize_brlt_sizes() - { - this->finalize_data_size(); - this->rel_->finalize_data_size(); - } - - // Add a reloc for an entry in the BRLT. - void - add_reloc(Address to, unsigned int off) - { this->rel_->add_relative(elfcpp::R_POWERPC_RELATIVE, this, off, to); } - - // Update section and reloc section size. - void - set_current_size(unsigned int num_branches) - { - this->reset_address_and_file_offset(); - this->set_current_data_size(num_branches * 16); - this->finalize_data_size(); - Output_section* os = this->output_section(); - os->set_section_offsets_need_adjustment(); - if (this->rel_ != NULL) - { - const unsigned int reloc_size = elfcpp::Elf_sizes::rela_size; - this->rel_->reset_address_and_file_offset(); - this->rel_->set_current_data_size(num_branches * reloc_size); - this->rel_->finalize_data_size(); - Output_section* os = this->rel_->output_section(); - os->set_section_offsets_need_adjustment(); - } - } - protected: void do_adjust_output_section(Output_section* os) @@ -4617,8 +4605,6 @@ class Output_data_brlt_powerpc : public Output_section_data_build void do_write(Output_file*); - // The reloc section. - Reloc_section* rel_; Target_powerpc* targ_; }; @@ -4630,24 +4616,15 @@ Target_powerpc::make_brlt_section(Layout* layout) { if (size == 64 && this->brlt_section_ == NULL) { - Reloc_section* brlt_rel = NULL; bool is_pic = parameters->options().output_is_position_independent(); if (is_pic) { // When PIC we can't fill in .branch_lt but must initialise at // runtime via dynamic relocations. this->rela_dyn_section(layout); - // FIXME: This reloc section won't have its relative relocs - // sorted properly among the other relative relocs in rela_dyn_ - // but it must be a separate section due to needing to call - // reset_data_size(). - brlt_rel = new Reloc_section(false); - if (this->rela_dyn_->output_section()) - this->rela_dyn_->output_section() - ->add_output_section_data(brlt_rel); } this->brlt_section_ - = new Output_data_brlt_powerpc(this, brlt_rel); + = new Output_data_brlt_powerpc(this); if (this->plt_ && is_pic && this->plt_->output_section()) this->plt_->output_section() ->add_output_section_data(this->brlt_section_);