From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: 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 Authentication-Results: sourceware.org; dmarc=pass (p=none dis=none) header.from=gmail.com Authentication-Results: sourceware.org; spf=pass smtp.mailfrom=gmail.com Received: by mail-pl1-x62a.google.com with SMTP id d9443c01a7336-1ae40dcdc18so30738495ad.2 for ; Sat, 20 May 2023 04:44:51 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20221208; t=1684583090; x=1687175090; h=in-reply-to:content-disposition:mime-version:references:message-id :subject:cc:to:from:date:from:to:cc:subject:date:message-id:reply-to; bh=GN0tsQKd2Q+vmpIkAl0OUg//LbnupaKRYnknreHRAco=; b=hHp/z7yFU8+Exyo8U2oFZvSVIZxPzbF7lyjI6YUujN55WiQJPWX8trt37xvSJrTkU2 3hsSjElLn0oB4W9DCMwIq9ERKNW5gjovmywS50vmWwpOYVfPQVvi5Q6pK1nfE7P3UHIE mrauj7rwd6w6uJoPWSC47RLnQmBYY4D96LlHpv8CxwtWBKaFK/Dn6yfr2rbcyH1pjoob LVm2c9siuG4Wgqgeotwb6ci+LGL96JCYycUi96mb5ix/TOV7sz36rn3TT2YHL4AanhNp mdXT6EgiqIrjRWTqVVAG1f018a/z4CCnK4dgKT8Nw2OdFM5uBDDtxL2y7Iu5vypEzmKa nxdQ== 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-Google-Smtp-Source: ACHHUZ49/V9wAlLNhCMOBg6cFapqA0trO7HxGnhreWScwoo6nBoc5ZsHQvNdilVw4oqt+svlsEvX3g== 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 From: Alan Modra To: binutils@sourceware.org Cc: "Maciej W. Rozycki" , Chenghua Xu Subject: coff-mips refhi list Message-ID: References: MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii 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 List-Id: 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. */ -- Alan Modra Australia Development Lab, IBM