From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from mail-pl1-x630.google.com (mail-pl1-x630.google.com [IPv6:2607:f8b0:4864:20::630]) by sourceware.org (Postfix) with ESMTPS id 4A7183857349 for ; Tue, 19 Dec 2023 09:36:17 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.2 sourceware.org 4A7183857349 Authentication-Results: sourceware.org; dmarc=pass (p=none dis=none) header.from=gmail.com Authentication-Results: sourceware.org; spf=pass smtp.mailfrom=gmail.com ARC-Filter: OpenARC Filter v1.0.0 sourceware.org 4A7183857349 Authentication-Results: server2.sourceware.org; arc=none smtp.remote-ip=2607:f8b0:4864:20::630 ARC-Seal: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1702978579; cv=none; b=IUViwHU1igeuoiBoUC2T1BGDA5F6SiEgnu8lBLKlAAkTMMsnZSeg1R11FaxxNdJPt0dJOs6d1eM2saS47GvCI2VOXPAaHsWuw2YeD1GFMLYczUwjj5aAqKDi4ZsPk5OPtZxjUUrfQjQAPVlcgxGEdcNuXLEnyJsffUEacLmfd+Q= ARC-Message-Signature: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1702978579; c=relaxed/simple; bh=IdQAsYBfMTa8J6/4sIxSVpzcUBgrJkDgmLiFmk71BHI=; h=DKIM-Signature:From:To:Subject:Date:Message-Id:MIME-Version; b=B4nkrfArfPKQOQWYQlQaMJUzIFY9KPDKVaLdhWCiBmsLdapfjx0lp8fL6uwnSHhE8QU3DP4P65FtBmbJh6/X8OFjulDzGeUrI0tCi5j5m9xOPm9wmtVm68w0gz61RVuQWI4xYEIdGA9+G7//HmVQaHuYWLjLmCjDGdj5CxQMAQU= ARC-Authentication-Results: i=1; server2.sourceware.org Received: by mail-pl1-x630.google.com with SMTP id d9443c01a7336-1d3dc30ae01so4054195ad.0 for ; Tue, 19 Dec 2023 01:36:17 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1702978575; x=1703583375; darn=sourceware.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=e5zhifzpydgR+Am/ya05/tlClHVzVGxTdHRGps+Tbsk=; b=JI/W4jgnXAhSgx46jL07Sd8OTVmznsb0U09h7mOKeqAZptmZtVg64Mz2fdLtrlICMo tqx4bnKSYwfXXitJxYqhYgT5lV0IPUpYsCJSz+2VJttqnpJNeeQyPYI3T7V6QxAHzFQg 2JSx9x92hgYynBGPf/2/dpKGPfw8iG0yQX4FVO6B6lcMI3ypfeNGMP+jj0tQsoD3H/f/ ulDiwGrHKEbbjEOEsb7wKQ37EX2YMvQlEf7DiO4JBDQFAHEG1vjMYyUMX2wJ4f3R9kh2 b3YlOIiBt2+HhrDYo3x7/+9nCp/3ieg9q86mlj0+RSDWZsOQI7Rd3PUQFY7kJ7m4XklS VzlQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1702978575; x=1703583375; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=e5zhifzpydgR+Am/ya05/tlClHVzVGxTdHRGps+Tbsk=; b=q0GOYt6YwWkHy+EnjT88qpe59mE9Kng31CQSUys9KNODNvVJ21+Aso1dgyfNYkn037 ehApNF40im734wyU/BUpcE707EuggndDnk406E8Vro9pETwJct5H5v8i3O6/BMpc5LWv 52ixU3C/GuxKMU5up6dHf6NdeBeP17f506Ct6FDHT/HgQ/0OVCpDfkuhO0YCUCpIwEYG eS6giFMTKv0aotw4WUDPOeKzKE1KcMFqES2k1blcVtcilYSk33PP7OvOvRlIvgKQpl1I AOm1SPNDX66l6SPEIaniJLVlQjJxYDHazQEJYij9ndZaIogNP8IK6qwEInET8gbw7wk+ ejig== X-Gm-Message-State: AOJu0Yy2RlnF9na78gHdwA72sqEI7tfSWtbjIrSbcYd2hb1Ja5waXfut 6LxOLtTQm2hBnwu8plnAzg4oNL+9YZg= X-Google-Smtp-Source: AGHT+IFPMqk4FLscKRJ08JQv6RnuxgsYCgI3Q5sXGyhaU0zQYHGRXtVOSKL6kPRnkj1/I5Th6Fmzew== X-Received: by 2002:a17:902:db01:b0:1d3:44ad:215b with SMTP id m1-20020a170902db0100b001d344ad215bmr13229947plx.92.1702978575437; Tue, 19 Dec 2023 01:36:15 -0800 (PST) Received: from squeak.. ([2406:3400:51d:8cc0:f25f:eeff:1565:a817]) by smtp.gmail.com with ESMTPSA id t8-20020a1709028c8800b001c5b8087fe5sm20607075plo.94.2023.12.19.01.36.13 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 19 Dec 2023 01:36:15 -0800 (PST) From: Alan Modra To: binutils@sourceware.org Cc: "Maciej W . Rozycki" , Chenghua Xu , Alan Modra Subject: coff-mips refhi list Date: Tue, 19 Dec 2023 20:05:46 +1030 Message-Id: <20231219093546.2112095-3-amodra@gmail.com> X-Mailer: git-send-email 2.39.2 In-Reply-To: <20231219093546.2112095-1-amodra@gmail.com> References: <20231219093546.2112095-1-amodra@gmail.com> MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Spam-Status: No, score=-3033.0 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. * 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_bfd_free_cached_info): Clear new hi16 list attached to sections rather than bfd tdata. diff --git a/bfd/coff-alpha.c b/bfd/coff-alpha.c index 3403e13ef1b..0ccc377a950 100644 --- a/bfd/coff-alpha.c +++ b/bfd/coff-alpha.c @@ -1461,11 +1461,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 { @@ -1498,7 +1498,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..1b5cc6ae10c 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, 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,34 @@ 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->data = data; + 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 +483,37 @@ 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; + + /* Apply the REFHI relocation. */ + hi->rel.addend += vallo; + ret = bfd_perform_relocation (abfd, &hi->rel, hi->data, + input_section, output_bfd, + error_message); + if (ret != bfd_reloc_ok) + return ret; + + sdata->u.mips_hi16_list = hi->next; + free (hi); } - - ecoff_data (abfd)->mips_refhi_list = NULL; } /* Now do the REFLO reloc in the usual way. */ diff --git a/bfd/ecoff.c b/bfd/ecoff.c index 844f1a5247d..c8af3032e40 100644 --- a/bfd/ecoff.c +++ b/bfd/ecoff.c @@ -109,6 +109,29 @@ _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_bfd_free_cached_info (bfd *abfd) { @@ -118,13 +141,14 @@ _bfd_ecoff_bfd_free_cached_info (bfd *abfd) || bfd_get_format (abfd) == bfd_core) && (tdata = ecoff_data (abfd)) != NULL) { - while (tdata->mips_refhi_list != NULL) + _bfd_ecoff_free_ecoff_debug_info (&tdata->debug_info); + if (ecoff_backend (abfd)->arch == bfd_arch_mips) { - struct mips_hi *ref = tdata->mips_refhi_list; - tdata->mips_refhi_list = ref->next; - free (ref); + 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); } - _bfd_ecoff_free_ecoff_debug_info (&tdata->debug_info); } return _bfd_generic_bfd_free_cached_info (abfd); } diff --git a/bfd/libecoff.h b/bfd/libecoff.h index 2267c7bc53b..96b8a9a4547 100644 --- a/bfd/libecoff.h +++ b/bfd/libecoff.h @@ -80,11 +80,11 @@ 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; + bfd_byte *data; + arelent rel; }; /* This is the target specific information kept for ECOFF files. */ @@ -151,9 +151,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. */ @@ -192,13 +189,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. */