From patchwork Fri Dec 9 11:08:04 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Alan Modra X-Patchwork-Id: 31724 Return-Path: Delivered-To: ouuuleilei@gmail.com Received: by 2002:adf:f944:0:0:0:0:0 with SMTP id q4csp707233wrr; Fri, 9 Dec 2022 03:08:21 -0800 (PST) X-Google-Smtp-Source: AA0mqf4BjL3QV2KJIviF1ESTZ2Ttxy/7CPRQ3jT0qB/7msouMv47hLt2/NqDBqPqT9JEIVqrJo4F X-Received: by 2002:a17:907:2a57:b0:7c1:52a:e903 with SMTP id fe23-20020a1709072a5700b007c1052ae903mr5514480ejc.55.1670584101117; Fri, 09 Dec 2022 03:08:21 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1670584101; cv=none; d=google.com; s=arc-20160816; b=dj79MVJ4dfzuyehw4ytP+noPhPqhAAwvkWU4WuIT/TagAyhqtOyJCxNx2jtOAUJfUm XvJKqM/f1iPyh33vdbnDgUk53voIaLBGoOun9epE07Mq1f2as+ThnOZteE6TOzI7yatd cN0K8hBDHeHAOt1V/bvNvmzZjcsURCjP+nEp1DomLYrJmaH1PssmTYd2yMAskM4yXvBx JmAXT8tK4njxUozLizdcwniEllBI4wcX4l4e/e8aGkbn+3Ub4FVJxIMBc7KGtjj3VrcQ tuf6/ozq5yYxIMCr0YMsVOqJNG2G8Jz7END7ENJBBWwr1Q+JGl8wQo1cunoJdo5w5n9E AJ3w== 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 :content-disposition:mime-version:message-id:subject:to:date :dmarc-filter:delivered-to:dkim-signature:dkim-filter; bh=W2H7I2qxfGxtHI2OI/8CyFoqP/HWwuof2H0+F+R2XSg=; b=kOs2a6J/RA7KNadUYxjj6hEhti1Ujmglwd9rxTflZjf1YGX3uJ6X1U+ifbXJZ8oK8w 1Hod32VUqGqjh9VZBSm8zdHbcObbZJtah3q3M6JamXUMmztEeqL2ndxIaWhi+QFe5XNq JUrjREjCbBtoFNW7ohtjbVifOwW9v4q29W4zjDJDOK2/EnMZ7mWFl2F8h91gA/de89OE 6UzSeKgQkf3rGpNK9xdj98rDLnGdvIwgBGEvxULnXZwAZUumF1xOCvZJUyUmZ1z5qhev hsYEzBppFHrYKPc1Yr5b2NPcLqPeB4nJ+dUjpsAr+ZdjHIM32v43zW8KKXXfdPb829dZ uczA== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@sourceware.org header.s=default header.b=A6b77wNv; 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 (server2.sourceware.org. [8.43.85.97]) by mx.google.com with ESMTPS id hq32-20020a1709073f2000b007c1070653adsi1135852ejc.809.2022.12.09.03.08.20 for (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 09 Dec 2022 03:08:21 -0800 (PST) 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=A6b77wNv; 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 13C1D38717C8 for ; Fri, 9 Dec 2022 11:08:20 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 13C1D38717C8 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=sourceware.org; s=default; t=1670584100; bh=W2H7I2qxfGxtHI2OI/8CyFoqP/HWwuof2H0+F+R2XSg=; h=Date:To:Subject:List-Id:List-Unsubscribe:List-Archive:List-Post: List-Help:List-Subscribe:From:Reply-To:From; b=A6b77wNvwJ5iGj2tbk2OvFNRVPIHnf5dgjxXN+WtabxyzcrgnMrBcu/k0fCTQXqlW 1+6JuOR8kSvkSOl+YolXiMFniCnYmUCqc+wUR1e0jeKuIrRhM/G44IbzPZOO1E9P7e w2t0LWR1u+9ZO8SoC1I8giDwkg6J0GG41CZvUPZA= X-Original-To: binutils@sourceware.org Delivered-To: binutils@sourceware.org Received: from mail-pj1-x102b.google.com (mail-pj1-x102b.google.com [IPv6:2607:f8b0:4864:20::102b]) by sourceware.org (Postfix) with ESMTPS id C42EC385B513 for ; Fri, 9 Dec 2022 11:08:08 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.1 sourceware.org C42EC385B513 Received: by mail-pj1-x102b.google.com with SMTP id n65-20020a17090a2cc700b0021bc5ef7a14so4643325pjd.0 for ; Fri, 09 Dec 2022 03:08:08 -0800 (PST) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=content-disposition:mime-version:message-id:subject:to:from:date :x-gm-message-state:from:to:cc:subject:date:message-id:reply-to; bh=W2H7I2qxfGxtHI2OI/8CyFoqP/HWwuof2H0+F+R2XSg=; b=5tTpK0p9hshMil6M8iJBO/p6bmIG6lr6uKo0TpBxnoHBJT3U2bkD+BtXuecLC0TU0u UDFBRllr4CuJcLdHXAeEpmPnqkiOkZeVt66t18xtagrGp7Kf0sFOqmn+AD5prD30aOtp 0NCwduDAN4aepsyVCj0408xDLwcnnr2abuiTvGwE13dk8RXh+UnCwiyJEC1StDOy7zCi 2Y/avr6HIIV4HQi93H23LLy5zDMZcyJEA8P2F8lsIIDO36jpkmnH6n1RTQ9yZmtSBz8O gyFbSAttfG2Eml3z5IeJdGxVlbRYakI8s5C1zTG0/BkDiLjNsrqxikOyFXJVIfP+DKGR KufQ== X-Gm-Message-State: ANoB5pmkYBInzRX9uQMYCnajkiI3J+ZcA6mPpQ13lRJBQ6fDZSH/OZQX jaCaZRRtaWPe8wBRJx0E8hQV4mbWyrY= X-Received: by 2002:a05:6a20:43a1:b0:9d:efbe:2063 with SMTP id i33-20020a056a2043a100b0009defbe2063mr8565692pzl.25.1670584087356; Fri, 09 Dec 2022 03:08:07 -0800 (PST) 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 m3-20020a62a203000000b00574740c99e9sm1033506pff.129.2022.12.09.03.08.06 for (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 09 Dec 2022 03:08:06 -0800 (PST) Received: by squeak.grove.modra.org (Postfix, from userid 1000) id 09F6A1142F80; Fri, 9 Dec 2022 21:38:04 +1030 (ACDT) Date: Fri, 9 Dec 2022 21:38:04 +1030 To: binutils@sourceware.org Subject: PR28306, segfault in _bfd_mips_elf_reloc_unshuffle Message-ID: MIME-Version: 1.0 Content-Disposition: inline X-Spam-Status: No, score=-3036.0 required=5.0 tests=BAYES_00, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, DKIM_VALID_EF, FILL_THIS_FORM, FREEMAIL_FROM, GIT_PATCH_0, RCVD_IN_DNSWL_NONE, SPF_HELO_NONE, SPF_PASS, TXREP 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?1751734394360455252?= X-GMAIL-MSGID: =?utf-8?q?1751734394360455252?= Access to section data during relocation processing should be bounds checked, as it is in bfd_perform_relocation. bfd_perform_relocation does these checks after any special_function is called. So a reloc special_function needs to do its own bounds checking before accessing section data. This patch adds many such checks to the mips backend. Checking mips relocs is not without some difficulty. See the comment in _bfd_mips_reloc_offset_in_range. In a multitple reloc sequence applied to the same location, relocs that may appear somewhere other than the last one of the sequence need to be treated specially since they apply to the addend for the next relocation rather than the section contents. If the addend is in the section then it needs to be checked but not when the addend is in the reloc. check_inplace handles this situation. _bfd_mips_reloc_offset_in_range with check_shuffle handles the case where contents are shuffled before applying the relocation. PR 28306 * elf32-mips.c (_bfd_mips_elf32_gprel16_reloc): Check reloc address using _bfd_mips_reloc_offset_in_range. (gprel32_with_gp, mips16_gprel_reloc): Likewise. * elf64-mips.c (mips_elf64_gprel32_reloc): Likewise. (mips16_gprel_reloc): Likewise. * elfn32-mips.c (mips16_gprel_reloc): Likewise. (gprel32_with_gp): Check reloc address using bfd_reloc_offset_in_range. * elfxx-mips.h (enum reloc_check): Define. (_bfd_mips_reloc_offset_in_range): Declare. * elfxx-mips.c (needs_shuffle): New function. (_bfd_mips_elf_reloc_unshuffle, _bfd_mips_elf_reloc_shuffle): Use it. (_bfd_mips_reloc_offset_in_range): New function. (_bfd_mips_elf_gprel16_with_gp): Move reloc address checks to partial_inplace handling. Use bfd_reloc_offset_in_range. (_bfd_mips_elf_lo16_reloc): Check reloc address using bfd_reloc_offset_in_range. (_bfd_mips_elf_generic_reloc): Check reloc address using _bfd_mips_reloc_offset_in_range. (mips_elf_calculate_relocation): Check reloc address before calling mips_elf_nullify_got_load. (_bfd_mips_elf_check_relocs): Likewise. (mips_elf_read_rel_addend): Add sec param, check reloc address before reading. Adjust callers. (mips_elf_add_lo16_rel_addend): Add sec param, adjust callers. diff --git a/bfd/elf32-mips.c b/bfd/elf32-mips.c index 3f92df6ee11..be28d1a3b1c 100644 --- a/bfd/elf32-mips.c +++ b/bfd/elf32-mips.c @@ -1790,6 +1790,10 @@ _bfd_mips_elf32_gprel16_reloc (bfd *abfd, arelent *reloc_entry, if (ret != bfd_reloc_ok) return ret; + if (!_bfd_mips_reloc_offset_in_range (abfd, input_section, reloc_entry, + check_shuffle)) + return bfd_reloc_outofrange; + location = (bfd_byte *) data + reloc_entry->address; _bfd_mips_elf_reloc_unshuffle (abfd, reloc_entry->howto->type, false, location); @@ -1857,7 +1861,8 @@ gprel32_with_gp (bfd *abfd, asymbol *symbol, arelent *reloc_entry, relocation += symbol->section->output_section->vma; relocation += symbol->section->output_offset; - if (reloc_entry->address > bfd_get_section_limit (abfd, input_section)) + if (!_bfd_mips_reloc_offset_in_range (abfd, input_section, reloc_entry, + check_inplace)) return bfd_reloc_outofrange; /* Set val to the offset into the section or symbol. */ @@ -1956,6 +1961,10 @@ mips16_gprel_reloc (bfd *abfd, arelent *reloc_entry, asymbol *symbol, if (ret != bfd_reloc_ok) return ret; + if (!_bfd_mips_reloc_offset_in_range (abfd, input_section, reloc_entry, + check_shuffle)) + return bfd_reloc_outofrange; + location = (bfd_byte *) data + reloc_entry->address; _bfd_mips_elf_reloc_unshuffle (abfd, reloc_entry->howto->type, false, location); diff --git a/bfd/elf64-mips.c b/bfd/elf64-mips.c index e3ee0b99d97..419d9bc6dbd 100644 --- a/bfd/elf64-mips.c +++ b/bfd/elf64-mips.c @@ -3580,7 +3580,8 @@ mips_elf64_gprel32_reloc (bfd *abfd, arelent *reloc_entry, asymbol *symbol, relocation += symbol->section->output_section->vma; relocation += symbol->section->output_offset; - if (reloc_entry->address > bfd_get_section_limit (abfd, input_section)) + if (!_bfd_mips_reloc_offset_in_range (abfd, input_section, reloc_entry, + check_inplace)) return bfd_reloc_outofrange; /* Set val to the offset into the section or symbol. */ @@ -3661,6 +3662,10 @@ mips16_gprel_reloc (bfd *abfd, arelent *reloc_entry, asymbol *symbol, if (ret != bfd_reloc_ok) return ret; + if (!_bfd_mips_reloc_offset_in_range (abfd, input_section, reloc_entry, + check_shuffle)) + return bfd_reloc_outofrange; + location = (bfd_byte *) data + reloc_entry->address; _bfd_mips_elf_reloc_unshuffle (abfd, reloc_entry->howto->type, false, location); diff --git a/bfd/elfn32-mips.c b/bfd/elfn32-mips.c index ac604eda5ea..d222d1a5d15 100644 --- a/bfd/elfn32-mips.c +++ b/bfd/elfn32-mips.c @@ -3411,7 +3411,8 @@ gprel32_with_gp (bfd *abfd, asymbol *symbol, arelent *reloc_entry, relocation += symbol->section->output_section->vma; relocation += symbol->section->output_offset; - if (reloc_entry->address > bfd_get_section_limit (abfd, input_section)) + if (!bfd_reloc_offset_in_range (reloc_entry->howto, abfd, input_section, + reloc_entry->address)) return bfd_reloc_outofrange; if (reloc_entry->howto->src_mask == 0) @@ -3491,6 +3492,10 @@ mips16_gprel_reloc (bfd *abfd, arelent *reloc_entry, asymbol *symbol, if (ret != bfd_reloc_ok) return ret; + if (!_bfd_mips_reloc_offset_in_range (abfd, input_section, reloc_entry, + check_shuffle)) + return bfd_reloc_outofrange; + location = (bfd_byte *) data + reloc_entry->address; _bfd_mips_elf_reloc_unshuffle (abfd, reloc_entry->howto->type, false, location); diff --git a/bfd/elfxx-mips.c b/bfd/elfxx-mips.c index 932167c15c6..1bd9622c1f9 100644 --- a/bfd/elfxx-mips.c +++ b/bfd/elfxx-mips.c @@ -2346,13 +2346,19 @@ tls_gottprel_reloc_p (unsigned int r_type) || r_type == R_MICROMIPS_TLS_GOTTPREL); } +static inline bool +needs_shuffle (int r_type) +{ + return mips16_reloc_p (r_type) || micromips_reloc_shuffle_p (r_type); +} + void _bfd_mips_elf_reloc_unshuffle (bfd *abfd, int r_type, bool jal_shuffle, bfd_byte *data) { bfd_vma first, second, val; - if (!mips16_reloc_p (r_type) && !micromips_reloc_shuffle_p (r_type)) + if (!needs_shuffle (r_type)) return; /* Pick up the first and second halfwords of the instruction. */ @@ -2375,7 +2381,7 @@ _bfd_mips_elf_reloc_shuffle (bfd *abfd, int r_type, { bfd_vma first, second, val; - if (!mips16_reloc_p (r_type) && !micromips_reloc_shuffle_p (r_type)) + if (!needs_shuffle (r_type)) return; val = bfd_get_32 (abfd, data); @@ -2399,6 +2405,32 @@ _bfd_mips_elf_reloc_shuffle (bfd *abfd, int r_type, bfd_put_16 (abfd, first, data); } +/* Perform reloc offset checking. + We can only use bfd_reloc_offset_in_range, which takes into account + the size of the field being relocated, when section contents will + be accessed because mips object files may use relocations that seem + to access beyond section limits. + gas/testsuite/gas/mips/dla-reloc.s is an example that puts + R_MIPS_SUB, a 64-bit relocation, on the last instruction in the + section. The R_MIPS_SUB applies to the addend for the next reloc + rather than the section contents. + + CHECK is CHECK_STD for the standard bfd_reloc_offset_in_range check, + CHECK_INPLACE to only check partial_inplace relocs, and + CHECK_SHUFFLE to only check relocs that shuffle/unshuffle. */ + +bool +_bfd_mips_reloc_offset_in_range (bfd *abfd, asection *input_section, + arelent *reloc_entry, enum reloc_check check) +{ + if (check == check_inplace && !reloc_entry->howto->partial_inplace) + return true; + if (check == check_shuffle && !needs_shuffle (reloc_entry->howto->type)) + return true; + return bfd_reloc_offset_in_range (reloc_entry->howto, abfd, + input_section, reloc_entry->address); +} + bfd_reloc_status_type _bfd_mips_elf_gprel16_with_gp (bfd *abfd, asymbol *symbol, arelent *reloc_entry, asection *input_section, @@ -2416,9 +2448,6 @@ _bfd_mips_elf_gprel16_with_gp (bfd *abfd, asymbol *symbol, relocation += symbol->section->output_section->vma; relocation += symbol->section->output_offset; - if (reloc_entry->address > bfd_get_section_limit (abfd, input_section)) - return bfd_reloc_outofrange; - /* Set val to the offset into the section or symbol. */ val = reloc_entry->addend; @@ -2433,6 +2462,10 @@ _bfd_mips_elf_gprel16_with_gp (bfd *abfd, asymbol *symbol, if (reloc_entry->howto->partial_inplace) { + if (!bfd_reloc_offset_in_range (reloc_entry->howto, abfd, input_section, + reloc_entry->address)) + return bfd_reloc_outofrange; + status = _bfd_relocate_contents (reloc_entry->howto, abfd, val, (bfd_byte *) data + reloc_entry->address); @@ -2534,7 +2567,8 @@ _bfd_mips_elf_lo16_reloc (bfd *abfd, arelent *reloc_entry, asymbol *symbol, bfd_vma vallo; bfd_byte *location = (bfd_byte *) data + reloc_entry->address; - if (reloc_entry->address > bfd_get_section_limit (abfd, input_section)) + if (!bfd_reloc_offset_in_range (reloc_entry->howto, abfd, input_section, + reloc_entry->address)) return bfd_reloc_outofrange; _bfd_mips_elf_reloc_unshuffle (abfd, reloc_entry->howto->type, false, @@ -2597,7 +2631,9 @@ _bfd_mips_elf_generic_reloc (bfd *abfd ATTRIBUTE_UNUSED, arelent *reloc_entry, relocatable = (output_bfd != NULL); - if (reloc_entry->address > bfd_get_section_limit (abfd, input_section)) + if (!_bfd_mips_reloc_offset_in_range (abfd, input_section, reloc_entry, + (relocatable + ? check_inplace : check_std))) return bfd_reloc_outofrange; /* Build up the field adjustment in VAL. */ @@ -5819,6 +5855,8 @@ mips_elf_calculate_relocation (bfd *abfd, bfd *input_bfd, case R_MICROMIPS_CALL_LO16: if (resolved_to_zero && !bfd_link_relocatable (info) + && bfd_reloc_offset_in_range (howto, input_bfd, input_section, + relocation->r_offset) && mips_elf_nullify_got_load (input_bfd, contents, relocation, howto, true)) return bfd_reloc_continue; @@ -8142,7 +8180,8 @@ mips_elf_rel_relocation_p (bfd *abfd, asection *sec, of the section that REL is against. */ static bfd_vma -mips_elf_read_rel_addend (bfd *abfd, const Elf_Internal_Rela *rel, +mips_elf_read_rel_addend (bfd *abfd, asection *sec, + const Elf_Internal_Rela *rel, reloc_howto_type *howto, bfd_byte *contents) { bfd_byte *location; @@ -8150,6 +8189,9 @@ mips_elf_read_rel_addend (bfd *abfd, const Elf_Internal_Rela *rel, bfd_vma addend; bfd_vma bytes; + if (!bfd_reloc_offset_in_range (howto, abfd, sec, rel->r_offset)) + return 0; + r_type = ELF_R_TYPE (abfd, rel->r_info); location = contents + rel->r_offset; @@ -8176,6 +8218,7 @@ mips_elf_read_rel_addend (bfd *abfd, const Elf_Internal_Rela *rel, static bool mips_elf_add_lo16_rel_addend (bfd *abfd, + asection *sec, const Elf_Internal_Rela *rel, const Elf_Internal_Rela *relend, bfd_byte *contents, bfd_vma *addend) @@ -8218,7 +8261,8 @@ mips_elf_add_lo16_rel_addend (bfd *abfd, /* Obtain the addend kept there. */ lo16_howto = MIPS_ELF_RTYPE_TO_HOWTO (abfd, lo16_type, false); - l = mips_elf_read_rel_addend (abfd, lo16_relocation, lo16_howto, contents); + l = mips_elf_read_rel_addend (abfd, sec, lo16_relocation, lo16_howto, + contents); l <<= lo16_howto->rightshift; l = _bfd_mips_elf_sign_extend (l, 16); @@ -8685,11 +8729,12 @@ _bfd_mips_elf_check_relocs (bfd *abfd, struct bfd_link_info *info, rel_reloc = mips_elf_rel_relocation_p (abfd, sec, relocs, rel); howto = MIPS_ELF_RTYPE_TO_HOWTO (abfd, r_type, !rel_reloc); - - if (!mips_elf_nullify_got_load (abfd, contents, rel, howto, - false)) - if (!mips_elf_define_absolute_zero (abfd, info, htab, r_type)) - return false; + if (bfd_reloc_offset_in_range (howto, abfd, sec, rel->r_offset)) + if (!mips_elf_nullify_got_load (abfd, contents, rel, howto, + false)) + if (!mips_elf_define_absolute_zero (abfd, info, htab, + r_type)) + return false; } /* Fall through. */ @@ -8903,10 +8948,10 @@ _bfd_mips_elf_check_relocs (bfd *abfd, struct bfd_link_info *info, if (!mips_elf_get_section_contents (abfd, sec, &contents)) return false; howto = MIPS_ELF_RTYPE_TO_HOWTO (abfd, r_type, false); - addend = mips_elf_read_rel_addend (abfd, rel, + addend = mips_elf_read_rel_addend (abfd, sec, rel, howto, contents); if (got16_reloc_p (r_type)) - mips_elf_add_lo16_rel_addend (abfd, rel, rel_end, + mips_elf_add_lo16_rel_addend (abfd, sec, rel, rel_end, contents, &addend); else addend <<= howto->rightshift; @@ -10423,14 +10468,15 @@ _bfd_mips_elf_relocate_section (bfd *output_bfd, struct bfd_link_info *info, relocs, rel)) { rela_relocation_p = false; - addend = mips_elf_read_rel_addend (input_bfd, rel, - howto, contents); + addend = mips_elf_read_rel_addend (input_bfd, input_section, + rel, howto, contents); if (hi16_reloc_p (r_type) || (got16_reloc_p (r_type) && mips_elf_local_relocation_p (input_bfd, rel, local_sections))) { - if (!mips_elf_add_lo16_rel_addend (input_bfd, rel, relend, + if (!mips_elf_add_lo16_rel_addend (input_bfd, input_section, + rel, relend, contents, &addend)) { if (h) diff --git a/bfd/elfxx-mips.h b/bfd/elfxx-mips.h index af6d14c6ce3..6b22fdab3ae 100644 --- a/bfd/elfxx-mips.h +++ b/bfd/elfxx-mips.h @@ -22,6 +22,13 @@ #include "elf/internal.h" #include "elf/mips.h" +enum reloc_check +{ + check_std, + check_inplace, + check_shuffle +}; + extern bool _bfd_mips_elf_mkobject (bfd *); extern bool _bfd_mips_elf_new_section_hook @@ -129,6 +136,8 @@ extern void _bfd_mips_elf_reloc_unshuffle (bfd *, int, bool, bfd_byte *); extern void _bfd_mips_elf_reloc_shuffle (bfd *, int, bool, bfd_byte *); +extern bool _bfd_mips_reloc_offset_in_range + (bfd *, asection *, arelent *, enum reloc_check); extern bfd_reloc_status_type _bfd_mips_elf_gprel16_with_gp (bfd *, asymbol *, arelent *, asection *, bool, void *, bfd_vma); extern bfd_reloc_status_type _bfd_mips_elf32_gprel16_reloc