From patchwork Sat May 20 11:44:46 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Alan Modra X-Patchwork-Id: 96762 Return-Path: Delivered-To: ouuuleilei@gmail.com Received: by 2002:a59:b0ea:0:b0:3b6:4342:cba0 with SMTP id b10csp307690vqo; Sat, 20 May 2023 04:45:01 -0700 (PDT) X-Google-Smtp-Source: ACHHUZ6nEVQOqgpt/cei7yM98d7gl7HubQADtbk/VVmfiAbveylPzRzJC5u6ReKXLPqsozq3ssvd X-Received: by 2002:a17:907:a089:b0:966:350f:f42d with SMTP id hu9-20020a170907a08900b00966350ff42dmr4310894ejc.23.1684583100984; Sat, 20 May 2023 04:45:00 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1684583100; cv=none; d=google.com; s=arc-20160816; b=gWEkspUgfDB2xYu5LAxvThF9geyLKrrwxWq0VX2RX4PO0Pocgj29v5/vHYf/wCG9zU xfn8qAqpasUtEGIWZ9WgQeB+Hh2UleHw3xf2nCbFdkcAkiUfaq99LFeYdQCUmFZ+JZ7I ZPwtlS2OoEPwzP3FzuJQnC1DplW9h8lbLiqr9sC3S7LYYnHocSyXFK0gQh56BJ0hN++M yIItEajBB8Eis/rO1ivdCdWPrN/5N6jFyWC1UnOccGL0ticOpcOB9K8w0+Vsz9l7wAnb 4GG4QonRwfyXzcpbT9k0KNb+Euv5XQDZ9e7FS64xCFTe1jbeZS96eM7ZESdIN4qZFjzC DgMg== 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:cc :to:date:dmarc-filter:delivered-to:dkim-signature:dkim-filter; bh=GN0tsQKd2Q+vmpIkAl0OUg//LbnupaKRYnknreHRAco=; b=dNTG6Ewza9CJCoupMribm5HKrtzDkqKy4scm2iBH0uFBhj031fVSJ6vGvcGCEWpRXf c/hUzpE4s0AKUOgHZEf37M0e4Q+6udV0cIVtAuJU4MEyKdkg5gYLxsdujt9DEmnOqzk+ dDZl9g9zZu1khA9spe8C/93JXW5ra6Clnv1elsyFDqyU0IX3NLxGrd+MXNQmc6ZzmY2F jTmDQXDI5LDu+HQjfxxuIanLg3k/6ejKzLOi/9d19EN8R/PxoFaovtzJ372bdLaaUEeF 3uSC/8+Q6yV8y3selqSPpT9f7nyqTj3N3PeUxevkqgBbUM1Yp+Ba+uk/QGgf8brB70fL kn7g== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@sourceware.org header.s=default header.b=EF0Nhdu1; 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 b9-20020a1709062b4900b00965cf59bf1bsi1247516ejg.31.2023.05.20.04.45.00 for (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sat, 20 May 2023 04:45:00 -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=EF0Nhdu1; 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 C53CC3858401 for ; Sat, 20 May 2023 11:44:59 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org C53CC3858401 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=sourceware.org; s=default; t=1684583099; bh=GN0tsQKd2Q+vmpIkAl0OUg//LbnupaKRYnknreHRAco=; h=Date:To:Cc:Subject:References:In-Reply-To:List-Id: List-Unsubscribe:List-Archive:List-Post:List-Help:List-Subscribe: From:Reply-To:From; b=EF0Nhdu1q6Ts3BusjIQKDwouocM9l4hBPu5FAdsOTFxTClhnR/QEddNmChN4aHbb+ 7QZ2FEHXKR4e8pEUGWgHpwgV3KZgG5QQeG68VOYO1FlAsgEfcqVS0dZIse9XA3i14i LIYOXlSSv6/l80lmZxksuRdm8zGo/nKGahNVL/zc= X-Original-To: binutils@sourceware.org Delivered-To: binutils@sourceware.org Received: from mail-pl1-x62a.google.com (mail-pl1-x62a.google.com [IPv6:2607:f8b0:4864:20::62a]) by sourceware.org (Postfix) with ESMTPS id 0F28F3858C52 for ; Sat, 20 May 2023 11:44:51 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.2 sourceware.org 0F28F3858C52 Received: by mail-pl1-x62a.google.com with SMTP id d9443c01a7336-1ae40dcdc18so30738495ad.2 for ; Sat, 20 May 2023 04:44:51 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20221208; t=1684583090; x=1687175090; h=in-reply-to:content-disposition:mime-version:references:message-id :subject:cc:to:from:date:x-gm-message-state:from:to:cc:subject:date :message-id:reply-to; bh=GN0tsQKd2Q+vmpIkAl0OUg//LbnupaKRYnknreHRAco=; b=fKgwzf3hhK8a0NbN5983IJi4AnJzZWnVMhZMbfVD2j/UTAAl8oyCTkT7+CQF/YSHZG 5adHPiTk9/MdaDwjlcQFqlpDJmArl6G6dd0iHaV7vw6ADCNVHAPI2RWkMSX6i0n8BS84 xsvska1miyfkwXdv+xZtsprFWle2lkE/Fdx4YstqL/Cd4MneANFINYa7IuUQtJhMb7qN QsN8z6PZfkhFS3isDPLUjm8FnYg7wC8zVSw6HMZ0CoIVuVxaNkO1PVIb8FI6wuTAgWu0 OtD65e6I7IxMFQQpviLZM2wR8v/1VKbtH4qof+XrB7ynGZ0Rm3v2uhdVexIHu0JH2aJA 9PXg== X-Gm-Message-State: AC+VfDxtvr36gmCYkuQdPssXhxmZYbdSCODURR4/4gc3SsaG2PutQ8P5 DdjEXLjKZ/AY+TBkuU2C2EM= X-Received: by 2002:a17:902:e5ce:b0:1a6:4127:857 with SMTP id u14-20020a170902e5ce00b001a641270857mr7051896plf.5.1684583089786; Sat, 20 May 2023 04:44:49 -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 q31-20020a17090a1b2200b002508f0ac3edsm3089745pjq.53.2023.05.20.04.44.48 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sat, 20 May 2023 04:44:49 -0700 (PDT) Received: by squeak.grove.modra.org (Postfix, from userid 1000) id B1B4B11403ED; Sat, 20 May 2023 21:14:46 +0930 (ACST) Date: Sat, 20 May 2023 21:14:46 +0930 To: binutils@sourceware.org Cc: "Maciej W. Rozycki" , Chenghua Xu Subject: coff-mips refhi list Message-ID: References: MIME-Version: 1.0 Content-Disposition: inline In-Reply-To: X-Spam-Status: No, score=-3034.8 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?1766413410046631810?= X-GMAIL-MSGID: =?utf-8?q?1766413410046631810?= Like "Move mips_hi16_list to mips_elf_section_data" but for coff. Also makes mips_refhi_reloc and mips_reflo_reloc a little more elegant in that they now make use of the generic reloc machinery in order to apply the relocations. OK? * libecoff.h (struct mips_hi): Delete (struct mips_h16): New. (struct ecoff_tdata): Delete mips_refhi_list. (struct ecoff_section_tdata): Put existing gp into a union. Add mips_hi16_list. * coff-alpha.c (alpha_relocate_section): Adjust section data access. * coff-mips.c (mips_refhi_reloc): Delete dead code. Stash hi reloc on ecoff_section_tdata. (mips_reflo_reloc): Use new hi16 list. Apply hi reloc using bfd_perform_relocation. * ecoff.c (free_mips_hi16_list): New function. (_bfd_ecoff_close_and_cleanup): Clear new hi16 list attached to sections rather than bfd tdata. diff --git a/bfd/coff-alpha.c b/bfd/coff-alpha.c index 45b3f760f55..79bae7a24d4 100644 --- a/bfd/coff-alpha.c +++ b/bfd/coff-alpha.c @@ -1422,11 +1422,11 @@ alpha_relocate_section (bfd *output_bfd, lita_sec->used_by_bfd = lita_sec_data; } - if (lita_sec_data->gp != 0) + if (lita_sec_data->u.gp != 0) { /* If we already assigned a gp to this section, we better stick with that value. */ - gp = lita_sec_data->gp; + gp = lita_sec_data->u.gp; } else { @@ -1459,7 +1459,7 @@ alpha_relocate_section (bfd *output_bfd, } - lita_sec_data->gp = gp; + lita_sec_data->u.gp = gp; } _bfd_set_gp_value (output_bfd, gp); diff --git a/bfd/coff-mips.c b/bfd/coff-mips.c index fdc0771979d..11b6a064248 100644 --- a/bfd/coff-mips.c +++ b/bfd/coff-mips.c @@ -427,17 +427,11 @@ static bfd_reloc_status_type mips_refhi_reloc (bfd *abfd, arelent *reloc_entry, asymbol *symbol, - void * data, + void *data ATTRIBUTE_UNUSED, asection *input_section, bfd *output_bfd, char **error_message ATTRIBUTE_UNUSED) { - bfd_reloc_status_type ret; - bfd_vma relocation; - struct mips_hi *n; - - /* If we're relocating, and this an external symbol, we don't want - to change anything. */ if (output_bfd != (bfd *) NULL && (symbol->flags & BSF_SECTION_SYM) == 0 && reloc_entry->addend == 0) @@ -446,36 +440,33 @@ mips_refhi_reloc (bfd *abfd, return bfd_reloc_ok; } - ret = bfd_reloc_ok; - if (bfd_is_und_section (symbol->section) - && output_bfd == (bfd *) NULL) - ret = bfd_reloc_undefined; - - if (bfd_is_com_section (symbol->section)) - relocation = 0; - else - relocation = symbol->value; - - relocation += symbol->section->output_section->vma; - relocation += symbol->section->output_offset; - relocation += reloc_entry->addend; - - if (reloc_entry->address > bfd_get_section_limit (abfd, input_section)) - return bfd_reloc_outofrange; + /* Is this the call via bfd_perform_relocation in mips_reflo_reloc? + If so, continue and apply the reloc. */ + struct ecoff_section_tdata *sdata = input_section->used_by_bfd; + if (sdata != NULL + && sdata->u.mips_hi16_list != NULL + && reloc_entry == &sdata->u.mips_hi16_list->rel) + return bfd_reloc_continue; + if (sdata == NULL) + { + sdata = bfd_zalloc (abfd, sizeof (*sdata)); + input_section->used_by_bfd = sdata; + if (sdata == NULL) + return bfd_reloc_outofrange; + } /* Save the information, and let REFLO do the actual relocation. */ - n = (struct mips_hi *) bfd_malloc ((bfd_size_type) sizeof *n); + struct mips_hi16 *n = bfd_malloc (sizeof (*n)); if (n == NULL) return bfd_reloc_outofrange; - n->addr = (bfd_byte *) data + reloc_entry->address; - n->addend = relocation; - n->next = ecoff_data (abfd)->mips_refhi_list; - ecoff_data (abfd)->mips_refhi_list = n; + n->rel = *reloc_entry; + n->next = sdata->u.mips_hi16_list; + sdata->u.mips_hi16_list = n; if (output_bfd != (bfd *) NULL) reloc_entry->address += input_section->output_offset; - return ret; + return bfd_reloc_ok; } /* Do a REFLO relocation. This is a straightforward 16 bit inplace @@ -491,54 +482,36 @@ mips_reflo_reloc (bfd *abfd, bfd *output_bfd, char **error_message) { - if (ecoff_data (abfd)->mips_refhi_list != NULL) + bfd_size_type octets = (reloc_entry->address + * OCTETS_PER_BYTE (abfd, input_section)); + + if (!bfd_reloc_offset_in_range (reloc_entry->howto, abfd, + input_section, octets)) + return bfd_reloc_outofrange; + + struct ecoff_section_tdata* sdata = input_section->used_by_bfd; + if (sdata != NULL && sdata->u.mips_hi16_list != NULL) { - struct mips_hi *l; + struct mips_hi16 *hi; + bfd_byte *loc = (bfd_byte *) data + octets; + /* Adjustment for the high part addend. See longer explanation + in elfxx-mips.c _bfd_mips_elf_lo16_reloc. */ + bfd_vma vallo = (bfd_get_32 (abfd, loc) & 0x8000) ^ 0x8000; - l = ecoff_data (abfd)->mips_refhi_list; - while (l != NULL) + while ((hi = sdata->u.mips_hi16_list) != NULL) { - unsigned long insn; - unsigned long val; - unsigned long vallo; - struct mips_hi *next; - bfd_size_type octets = (reloc_entry->address - * OCTETS_PER_BYTE (abfd, input_section)); - bfd_byte *loc = (bfd_byte *) data + octets; - - if (!bfd_reloc_offset_in_range (reloc_entry->howto, abfd, - input_section, octets)) - return bfd_reloc_outofrange; - - /* Do the REFHI relocation. Note that we actually don't - need to know anything about the REFLO itself, except - where to find the low 16 bits of the addend needed by the - REFHI. */ - insn = bfd_get_32 (abfd, l->addr); - vallo = bfd_get_32 (abfd, loc) & 0xffff; - val = ((insn & 0xffff) << 16) + vallo; - val += l->addend; - - /* The low order 16 bits are always treated as a signed - value. Therefore, a negative value in the low order bits - requires an adjustment in the high order bits. We need - to make this adjustment in two ways: once for the bits we - took from the data, and once for the bits we are putting - back in to the data. */ - if ((vallo & 0x8000) != 0) - val -= 0x10000; - if ((val & 0x8000) != 0) - val += 0x10000; - - insn = (insn &~ (unsigned) 0xffff) | ((val >> 16) & 0xffff); - bfd_put_32 (abfd, (bfd_vma) insn, l->addr); - - next = l->next; - free (l); - l = next; - } + bfd_reloc_status_type ret; - ecoff_data (abfd)->mips_refhi_list = NULL; + /* Apply the REFHI relocation. */ + hi->rel.addend += vallo; + ret = bfd_perform_relocation (abfd, &hi->rel, data, input_section, + output_bfd, error_message); + if (ret != bfd_reloc_ok) + return ret; + + sdata->u.mips_hi16_list = hi->next; + free (hi); + } } /* Now do the REFLO reloc in the usual way. */ diff --git a/bfd/ecoff.c b/bfd/ecoff.c index 676b8d84017..8e3b4585555 100644 --- a/bfd/ecoff.c +++ b/bfd/ecoff.c @@ -109,18 +109,40 @@ _bfd_ecoff_mkobject_hook (bfd *abfd, void * filehdr, void * aouthdr) return (void *) ecoff; } +/* Free the mips_hi16_list attached to S. Return true if there were + unmatched hi16 relocs. */ + +static bool +free_mips_hi16_list (asection *s) +{ + struct ecoff_section_tdata* sdata = s->used_by_bfd; + if (sdata != NULL) + { + struct mips_hi16 *hi; + struct mips_hi16 **hip = &sdata->u.mips_hi16_list; + bool ret = *hip != NULL; + + while ((hi = *hip) != NULL) + { + *hip = hi->next; + free (hi); + } + return ret; + } + return false; +} + bool _bfd_ecoff_close_and_cleanup (bfd *abfd) { - struct ecoff_tdata *tdata = ecoff_data (abfd); - - if (tdata != NULL && bfd_get_format (abfd) == bfd_object) - while (tdata->mips_refhi_list != NULL) - { - struct mips_hi *ref = tdata->mips_refhi_list; - tdata->mips_refhi_list = ref->next; - free (ref); - } + if (bfd_get_format (abfd) == bfd_object + && ecoff_backend (abfd)->arch == bfd_arch_mips) + { + for (asection *s = abfd->sections; s; s = s->next) + if (free_mips_hi16_list (s)) + _bfd_error_handler + (_("%pB(%pA): unmatched hi16 reloc"), abfd, s); + } return _bfd_generic_close_and_cleanup (abfd); } diff --git a/bfd/libecoff.h b/bfd/libecoff.h index 12664b890c4..96649c39e3d 100644 --- a/bfd/libecoff.h +++ b/bfd/libecoff.h @@ -80,11 +80,10 @@ struct ecoff_backend_data members of the embedded bfd_coff_backend_data struct. */ #define ECOFF_NO_LONG_SECTION_NAMES (false), _bfd_ecoff_no_long_sections -struct mips_hi +struct mips_hi16 { - struct mips_hi *next; - bfd_byte *addr; - bfd_vma addend; + struct mips_hi16 *next; + arelent rel; }; /* This is the target specific information kept for ECOFF files. */ @@ -154,9 +153,6 @@ typedef struct ecoff_tdata particular ECOFF file. This is not valid until ecoff_compute_section_file_positions is called. */ bool rdata_in_text; - - /* Used by coff-mips.c to track REFHI relocs for pairing with REFLO. */ - struct mips_hi *mips_refhi_list; } ecoff_data_type; /* Each canonical asymbol really looks like this. */ @@ -195,13 +191,18 @@ typedef struct ecoff_symbol_struct struct ecoff_section_tdata { - /* When producing an executable (i.e., final, non-relocatable link) - on the Alpha, we may need to use multiple global pointer values - to span the entire .lita section. In essence, we allow each - input .lita section to have its own gp value. To support this, - we need to keep track of the gp values that we picked for each - input .lita section . */ - bfd_vma gp; + union + { + /* When producing an executable (i.e., final, non-relocatable link) + on the Alpha, we may need to use multiple global pointer values + to span the entire .lita section. In essence, we allow each + input .lita section to have its own gp value. To support this, + we need to keep track of the gp values that we picked for each + input .lita section . */ + bfd_vma gp; + /* Used by coff-mips.c to track hi16 relocs. */ + struct mips_hi16 *mips_hi16_list; + } u; }; /* An accessor macro for the ecoff_section_tdata structure. */