From patchwork Fri Jan 7 19:06:22 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "H.J. Lu" X-Patchwork-Id: 49731 Return-Path: X-Original-To: patchwork@sourceware.org Delivered-To: patchwork@sourceware.org Received: from server2.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id AA9133857C71 for ; Fri, 7 Jan 2022 19:21:44 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org AA9133857C71 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=sourceware.org; s=default; t=1641583304; bh=XhbWPcBttQHl4CkZfBYcZC9ADoFlVNcCayfddUIl8oI=; h=To:Subject:Date:In-Reply-To:References:List-Id:List-Unsubscribe: List-Archive:List-Post:List-Help:List-Subscribe:From:Reply-To:Cc: From; b=DL3D5J4hMNLu3Z2XJSquS8jUnAahsdJANRNJ+we0ZvYU33++giNjJ4HR5zZWYEGqW sJSep33zSh40ITazsla1iu5+/2kG1kwhG9NdBHRcu/WypQQy3lQXTmtnapeap4XXeK iN1gsiS3FdEvwXNMeBYkO/sdx0w6Wwwqp2nig1lk= X-Original-To: libc-alpha@sourceware.org Delivered-To: libc-alpha@sourceware.org Received: from mail-pf1-x435.google.com (mail-pf1-x435.google.com [IPv6:2607:f8b0:4864:20::435]) by sourceware.org (Postfix) with ESMTPS id D9B673858C39; Fri, 7 Jan 2022 19:06:35 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.1 sourceware.org D9B673858C39 Received: by mail-pf1-x435.google.com with SMTP id t123so5862084pfc.13; Fri, 07 Jan 2022 11:06:35 -0800 (PST) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=XhbWPcBttQHl4CkZfBYcZC9ADoFlVNcCayfddUIl8oI=; b=nuKN3QYdTeuxQwXs2zrxbLidYncStt9oQhnmok65UWJ2csn/k+tqBMrZlFInv0WIai UO3BhMGv/r1NwdWF1n9l3Zvn0dpORVEX3VQVWYfk5tU0LjNYuiukxYl7ZRvueVEQZ5N9 3vK77k0tDS7/hbHZzl5umqAE5nGQJxzZubnTFQ3dItc3Y/dWw0xcOK0POeaLUmrIiVxP TKa6YEeam/TBLIVlhBgg6u+sLpuLaP4QFVo5MBWG4WgbT3P9kmgdlTulB3TkB/liPUtl va2n0u7GsTyED/1vpUuOZRCsSoIBx7mvQb6n/7KilsL0V3zhiEECZH2jeux40vxR3R7V NVcg== X-Gm-Message-State: AOAM5326k50pZFpLz13MDFKeRsPwFMc5WZDfLSBq7qGFDUfFf/b8UG8n W4Dq7QTRenzOufaqCx5YjJI= X-Google-Smtp-Source: ABdhPJyzEDUQl8/abc517Jv78beOBpSHb/In1JFAmutdlpeF2C7f+dZVBkTWg2ag1dJW6HdOYi52EQ== X-Received: by 2002:a05:6a00:230d:b0:49f:b8ad:ae23 with SMTP id h13-20020a056a00230d00b0049fb8adae23mr64986322pfh.80.1641582394761; Fri, 07 Jan 2022 11:06:34 -0800 (PST) Received: from gnu-tgl-3.localdomain ([172.58.35.133]) by smtp.gmail.com with ESMTPSA id 193sm6299093pfz.43.2022.01.07.11.06.33 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 07 Jan 2022 11:06:33 -0800 (PST) Received: from gnu-tgl-3.. (localhost [IPv6:::1]) by gnu-tgl-3.localdomain (Postfix) with ESMTP id E08C1C07B0; Fri, 7 Jan 2022 11:06:31 -0800 (PST) To: binutils@sourceware.org Subject: [PATCH 01/10] ld: Extract _bfd_elf_link_iterate_on_relocs Date: Fri, 7 Jan 2022 11:06:22 -0800 Message-Id: <20220107190631.309790-2-hjl.tools@gmail.com> X-Mailer: git-send-email 2.33.1 In-Reply-To: <20220107190631.309790-1-hjl.tools@gmail.com> References: <20220107190631.309790-1-hjl.tools@gmail.com> MIME-Version: 1.0 X-Spam-Status: No, score=-3028.9 required=5.0 tests=BAYES_00, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, DKIM_VALID_EF, FREEMAIL_FROM, GIT_PATCH_0, RCVD_IN_BARRACUDACENTRAL, RCVD_IN_DNSWL_NONE, SPF_HELO_NONE, SPF_PASS, TXREP autolearn=ham autolearn_force=no version=3.4.4 X-Spam-Checker-Version: SpamAssassin 3.4.4 (2020-01-24) on server2.sourceware.org X-BeenThere: libc-alpha@sourceware.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Libc-alpha mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-Patchwork-Original-From: "H.J. Lu via Libc-alpha" From: "H.J. Lu" Reply-To: "H.J. Lu" Cc: libc-alpha@sourceware.org, Nick Clifton , Alan Modra Errors-To: libc-alpha-bounces+patchwork=sourceware.org@sourceware.org Sender: "Libc-alpha" DT_RELR encodes consecutive R_*_RELATIVE relocations in GOT (the global offset table) and data sections in a compact format: https://groups.google.com/g/generic-abi/c/bX460iggiKg On some targets, R_*_RELATIVE relocations are counted and the GOT offsets are allocated when setting the dynamic section sizes after seeing all relocations. R_*_RELATIVE relocations are generated while relocating sections after section layout has been finalized. To prepare for DT_RELR implementation on these targets, extract _bfd_elf_link_iterate_on_relocs from _bfd_elf_link_check_relocs so that a backend can scan relocations in elf_backend_always_size_sections For x86 targets, the old check_relocs is renamed to scan_relocs and a new check_relocs is added to chek input sections and create dynamic relocation sections so that they will be mapped to output sections. scan_relocs is now called from elf_backend_always_size_sections. Since relocations are scanned after __start, __stop, .startof. and .sizeof. symbols have been finalized on x86, __[start|stop]_SECNAME for --gc-sections -z start-stop-gc are now zero when all SECNAME sections been garbage collected. This is no need for elf_x86_start_stop_gc_p. bfd/ * elf-bfd.h (_bfd_elf_link_iterate_on_relocs): New. * elf32-i386.c (elf_i386_convert_load_reloc): Don't call elf_x86_start_stop_gc_p. (elf_i386_check_relocs): Renamed to ... (elf_i386_scan_relocs): This. Don't call _bfd_elf_make_dynamic_reloc_section. (elf_i386_always_size_sections): New. (elf_backend_check_relocs): Removed. (elf_backend_always_size_sections): New. * elf64-x86-64.c (elf_x86_64_convert_load_reloc): Don't call elf_x86_start_stop_gc_p. (elf_x86_64_check_relocs): Renamed to ... (elf_x86_64_scan_relocs): This. Don't call _bfd_elf_make_dynamic_reloc_section. (elf_x86_64_always_size_sections): New. (elf_backend_check_relocs): Removed. (elf_backend_always_size_sections): New. * elflink.c (elf_link_check_or_scan_relocs): New. Extracted from _bfd_elf_link_check_relocs. (_bfd_elf_link_check_relocs): Call elf_link_check_or_scan_relocs. * elfxx-x86.c (_bfd_x86_elf_check_relocs): New. * elfxx-x86.h (X86_64_NEED_DYNAMIC_RELOC_TYPE_P): New. (I386_NEED_DYNAMIC_RELOC_TYPE_P): Likewise. (X86_NEED_DYNAMIC_RELOC_TYPE_P): Likewise. (_bfd_x86_elf_check_relocs): Likewise. (elf_backend_check_relocs): Likewise. (elf_backend_always_size_sections): Removed. (elf_x86_start_stop_gc_p): Likewise. ld/ * testsuite/ld-i386/pr27491-1a.d: Updated. * testsuite/ld-x86-64/pr27491-1a.d: Likewise. --- bfd/elf-bfd.h | 4 ++ bfd/elf32-i386.c | 58 ++++++++++---------- bfd/elf64-x86-64.c | 55 +++++++++---------- bfd/elflink.c | 23 ++++++-- bfd/elfxx-x86.c | 85 +++++++++++++++++++++++++++++ bfd/elfxx-x86.h | 60 +++++++++----------- ld/testsuite/ld-i386/pr27491-1a.d | 4 +- ld/testsuite/ld-x86-64/pr27491-1a.d | 4 +- 8 files changed, 191 insertions(+), 102 deletions(-) diff --git a/bfd/elf-bfd.h b/bfd/elf-bfd.h index 896aa08fd76..81f8fd47db7 100644 --- a/bfd/elf-bfd.h +++ b/bfd/elf-bfd.h @@ -2632,6 +2632,10 @@ extern int bfd_elf_add_dt_needed_tag (bfd *, struct bfd_link_info *); extern bool _bfd_elf_link_check_relocs (bfd *, struct bfd_link_info *); +extern bool _bfd_elf_link_iterate_on_relocs + (bfd *, struct bfd_link_info *, + bool (*) (bfd *, struct bfd_link_info *, asection *, + const Elf_Internal_Rela *)); extern bool bfd_elf_link_record_dynamic_symbol (struct bfd_link_info *, struct elf_link_hash_entry *); diff --git a/bfd/elf32-i386.c b/bfd/elf32-i386.c index 97962072ff0..d1f61be5044 100644 --- a/bfd/elf32-i386.c +++ b/bfd/elf32-i386.c @@ -522,7 +522,7 @@ elf_i386_grok_psinfo (bfd *abfd, Elf_Internal_Note *note) Functions named elf_i386_* are called by external routines, other functions are only called locally. elf_i386_* functions appear in this file more or less in the order in which they are called - from external routines. eg. elf_i386_check_relocs is called + from external routines. eg. elf_i386_scan_relocs is called early in the link process, elf_i386_finish_dynamic_sections is one of the last functions. */ @@ -1106,7 +1106,7 @@ elf_i386_tls_transition (struct bfd_link_info *info, bfd *abfd, } /* We checked the transition before when we were called from - elf_i386_check_relocs. We only want to check the new + elf_i386_scan_relocs. We only want to check the new transition which hasn't been checked before. */ check = new_to_type != to_type && from_type == to_type; to_type = new_to_type; @@ -1387,11 +1387,6 @@ elf_i386_convert_load_reloc (bfd *abfd, Elf_Internal_Shdr *symtab_hdr, || h->root.type == bfd_link_hash_defweak) && local_ref)) { - /* Skip __start_SECNAME/__stop_SECNAME when --gc-sections - -z start-stop-gc are used. */ - if (elf_x86_start_stop_gc_p (link_info, h)) - return true; - convert_load: if (opcode == 0x8b) { @@ -1452,21 +1447,20 @@ elf_i386_convert_load_reloc (bfd *abfd, Elf_Internal_Shdr *symtab_hdr, } /* Look through the relocs for a section during the first phase, and - calculate needed space in the global offset table, procedure linkage - table, and dynamic reloc sections. */ + calculate needed space in the global offset table, and procedure + linkage table. */ static bool -elf_i386_check_relocs (bfd *abfd, - struct bfd_link_info *info, - asection *sec, - const Elf_Internal_Rela *relocs) +elf_i386_scan_relocs (bfd *abfd, + struct bfd_link_info *info, + asection *sec, + const Elf_Internal_Rela *relocs) { struct elf_x86_link_hash_table *htab; Elf_Internal_Shdr *symtab_hdr; struct elf_link_hash_entry **sym_hashes; const Elf_Internal_Rela *rel; const Elf_Internal_Rela *rel_end; - asection *sreloc; bfd_byte *contents; bool converted; @@ -1496,8 +1490,6 @@ elf_i386_check_relocs (bfd *abfd, converted = false; - sreloc = NULL; - rel_end = relocs + sec->reloc_count; for (rel = relocs; rel < rel_end; rel++) { @@ -1818,18 +1810,6 @@ elf_i386_check_relocs (bfd *abfd, struct elf_dyn_relocs *p; struct elf_dyn_relocs **head; - /* We must copy these reloc types into the output file. - Create a reloc section in dynobj and make room for - this reloc. */ - if (sreloc == NULL) - { - sreloc = _bfd_elf_make_dynamic_reloc_section - (sec, htab->elf.dynobj, 2, abfd, /*rela?*/ false); - - if (sreloc == NULL) - goto error_return; - } - /* If this is a global symbol, we count the number of relocations we need for this symbol. */ if (h != NULL) @@ -1924,6 +1904,24 @@ elf_i386_check_relocs (bfd *abfd, return false; } +static bool +elf_i386_always_size_sections (bfd *output_bfd, + struct bfd_link_info *info) +{ + bfd *abfd; + + /* Scan relocations after rel_from_abs has been set on __ehdr_start. */ + for (abfd = info->input_bfds; + abfd != (bfd *) NULL; + abfd = abfd->link.next) + if (bfd_get_flavour (abfd) == bfd_target_elf_flavour + && !_bfd_elf_link_iterate_on_relocs (abfd, info, + elf_i386_scan_relocs)) + return false; + + return _bfd_x86_elf_always_size_sections (output_bfd, info); +} + /* Set the correct type for an x86 ELF section. We do this by the section name, which is a hack, but ought to work. */ @@ -2000,7 +1998,7 @@ elf_i386_relocate_section (bfd *output_bfd, bool is_vxworks_tls; unsigned plt_entry_size; - /* Skip if check_relocs failed. */ + /* Skip if check_relocs or scan_relocs failed. */ if (input_section->check_relocs_failed) return false; @@ -4390,7 +4388,7 @@ elf_i386_link_setup_gnu_properties (struct bfd_link_info *info) #define bfd_elf32_get_synthetic_symtab elf_i386_get_synthetic_symtab #define elf_backend_relocs_compatible _bfd_elf_relocs_compatible -#define elf_backend_check_relocs elf_i386_check_relocs +#define elf_backend_always_size_sections elf_i386_always_size_sections #define elf_backend_create_dynamic_sections _bfd_elf_create_dynamic_sections #define elf_backend_fake_sections elf_i386_fake_sections #define elf_backend_finish_dynamic_sections elf_i386_finish_dynamic_sections diff --git a/bfd/elf64-x86-64.c b/bfd/elf64-x86-64.c index 22aa3ee3b68..ad885f89e11 100644 --- a/bfd/elf64-x86-64.c +++ b/bfd/elf64-x86-64.c @@ -1309,7 +1309,7 @@ elf_x86_64_tls_transition (struct bfd_link_info *info, bfd *abfd, } /* We checked the transition before when we were called from - elf_x86_64_check_relocs. We only want to check the new + elf_x86_64_scan_relocs. We only want to check the new transition which hasn't been checked before. */ check = new_to_type != to_type && from_type == to_type; to_type = new_to_type; @@ -1628,11 +1628,6 @@ elf_x86_64_convert_load_reloc (bfd *abfd, || h->root.type == bfd_link_hash_defweak) && h->root.u.def.section == bfd_und_section_ptr)))) { - /* Skip __start_SECNAME/__stop_SECNAME when --gc-sections - -z start-stop-gc are used. */ - if (elf_x86_start_stop_gc_p (link_info, h)) - return true; - /* Skip since R_X86_64_32/R_X86_64_32S may overflow. */ if (no_overflow) return true; @@ -1823,20 +1818,19 @@ elf_x86_64_convert_load_reloc (bfd *abfd, } /* Look through the relocs for a section during the first phase, and - calculate needed space in the global offset table, procedure - linkage table, and dynamic reloc sections. */ + calculate needed space in the global offset table, and procedure + linkage table. */ static bool -elf_x86_64_check_relocs (bfd *abfd, struct bfd_link_info *info, - asection *sec, - const Elf_Internal_Rela *relocs) +elf_x86_64_scan_relocs (bfd *abfd, struct bfd_link_info *info, + asection *sec, + const Elf_Internal_Rela *relocs) { struct elf_x86_link_hash_table *htab; Elf_Internal_Shdr *symtab_hdr; struct elf_link_hash_entry **sym_hashes; const Elf_Internal_Rela *rel; const Elf_Internal_Rela *rel_end; - asection *sreloc; bfd_byte *contents; bool converted; @@ -1866,8 +1860,6 @@ elf_x86_64_check_relocs (bfd *abfd, struct bfd_link_info *info, converted = false; - sreloc = NULL; - rel_end = relocs + sec->reloc_count; for (rel = relocs; rel < rel_end; rel++) { @@ -2263,19 +2255,6 @@ elf_x86_64_check_relocs (bfd *abfd, struct bfd_link_info *info, struct elf_dyn_relocs *p; struct elf_dyn_relocs **head; - /* We must copy these reloc types into the output file. - Create a reloc section in dynobj and make room for - this reloc. */ - if (sreloc == NULL) - { - sreloc = _bfd_elf_make_dynamic_reloc_section - (sec, htab->elf.dynobj, ABI_64_P (abfd) ? 3 : 2, - abfd, /*rela?*/ true); - - if (sreloc == NULL) - goto error_return; - } - /* If this is a global symbol, we count the number of relocations we need for this symbol. */ if (h != NULL) @@ -2371,6 +2350,24 @@ elf_x86_64_check_relocs (bfd *abfd, struct bfd_link_info *info, return false; } +static bool +elf_x86_64_always_size_sections (bfd *output_bfd, + struct bfd_link_info *info) +{ + bfd *abfd; + + /* Scan relocations after rel_from_abs has been set on __ehdr_start. */ + for (abfd = info->input_bfds; + abfd != (bfd *) NULL; + abfd = abfd->link.next) + if (bfd_get_flavour (abfd) == bfd_target_elf_flavour + && !_bfd_elf_link_iterate_on_relocs (abfd, info, + elf_x86_64_scan_relocs)) + return false; + + return _bfd_x86_elf_always_size_sections (output_bfd, info); +} + /* Return the relocation value for @tpoff relocation if STT_TLS virtual address is ADDRESS. */ @@ -2413,7 +2410,7 @@ elf_x86_64_relocate_section (bfd *output_bfd, unsigned int plt_entry_size; bool status; - /* Skip if check_relocs failed. */ + /* Skip if check_relocs or scan_relocs failed. */ if (input_section->check_relocs_failed) return false; @@ -5238,7 +5235,7 @@ elf_x86_64_special_sections[]= elf_x86_64_reloc_name_lookup #define elf_backend_relocs_compatible elf_x86_64_relocs_compatible -#define elf_backend_check_relocs elf_x86_64_check_relocs +#define elf_backend_always_size_sections elf_x86_64_always_size_sections #define elf_backend_create_dynamic_sections _bfd_elf_create_dynamic_sections #define elf_backend_finish_dynamic_sections elf_x86_64_finish_dynamic_sections #define elf_backend_finish_dynamic_symbol elf_x86_64_finish_dynamic_symbol diff --git a/bfd/elflink.c b/bfd/elflink.c index 08c161713cc..059461b5725 100644 --- a/bfd/elflink.c +++ b/bfd/elflink.c @@ -4008,10 +4008,13 @@ _bfd_elf_notice_as_needed (bfd *ibfd, return (*info->callbacks->notice) (info, NULL, NULL, ibfd, NULL, act, 0); } -/* Check relocations an ELF object file. */ +/* Call ACTION on each relocation in an ELF object file. */ bool -_bfd_elf_link_check_relocs (bfd *abfd, struct bfd_link_info *info) +_bfd_elf_link_iterate_on_relocs + (bfd *abfd, struct bfd_link_info *info, + bool (*action) (bfd *, struct bfd_link_info *, asection *, + const Elf_Internal_Rela *)) { const struct elf_backend_data *bed = get_elf_backend_data (abfd); struct elf_link_hash_table *htab = elf_hash_table (info); @@ -4035,7 +4038,6 @@ _bfd_elf_link_check_relocs (bfd *abfd, struct bfd_link_info *info) different format. It probably can't be done. */ if ((abfd->flags & DYNAMIC) == 0 && is_elf_hash_table (&htab->root) - && bed->check_relocs != NULL && elf_object_id (abfd) == elf_hash_table_id (htab) && (*bed->relocs_compatible) (abfd->xvec, info->output_bfd->xvec)) { @@ -4070,7 +4072,7 @@ _bfd_elf_link_check_relocs (bfd *abfd, struct bfd_link_info *info) if (internal_relocs == NULL) return false; - ok = (*bed->check_relocs) (abfd, info, o, internal_relocs); + ok = action (abfd, info, o, internal_relocs); if (elf_section_data (o)->relocs != internal_relocs) free (internal_relocs); @@ -4083,6 +4085,19 @@ _bfd_elf_link_check_relocs (bfd *abfd, struct bfd_link_info *info) return true; } +/* Check relocations in an ELF object file. This is called after + all input files have been opened. */ + +bool +_bfd_elf_link_check_relocs (bfd *abfd, struct bfd_link_info *info) +{ + const struct elf_backend_data *bed = get_elf_backend_data (abfd); + if (bed->check_relocs != NULL) + return _bfd_elf_link_iterate_on_relocs (abfd, info, + bed->check_relocs); + return true; +} + /* Add symbols from an ELF object file to the linker hash table. */ static bool diff --git a/bfd/elfxx-x86.c b/bfd/elfxx-x86.c index ca4b90e22cc..25f7717ea88 100644 --- a/bfd/elfxx-x86.c +++ b/bfd/elfxx-x86.c @@ -892,6 +892,91 @@ _bfd_x86_elf_link_check_relocs (bfd *abfd, struct bfd_link_info *info) return _bfd_elf_link_check_relocs (abfd, info); } +/* Look through the relocs for a section before allocation to make the + dynamic reloc section. */ + +bool +_bfd_x86_elf_check_relocs (bfd *abfd, + struct bfd_link_info *info, + asection *sec, + const Elf_Internal_Rela *relocs) +{ + struct elf_x86_link_hash_table *htab; + Elf_Internal_Shdr *symtab_hdr; + struct elf_link_hash_entry **sym_hashes; + const Elf_Internal_Rela *rel; + const Elf_Internal_Rela *rel_end; + asection *sreloc; + const struct elf_backend_data *bed; + bool is_x86_64; + + if (bfd_link_relocatable (info)) + return true; + + bed = get_elf_backend_data (abfd); + htab = elf_x86_hash_table (info, bed->target_id); + if (htab == NULL) + { + sec->check_relocs_failed = 1; + return false; + } + + is_x86_64 = bed->target_id == X86_64_ELF_DATA; + + symtab_hdr = &elf_symtab_hdr (abfd); + sym_hashes = elf_sym_hashes (abfd); + + rel_end = relocs + sec->reloc_count; + for (rel = relocs; rel < rel_end; rel++) + { + unsigned int r_type; + unsigned int r_symndx; + struct elf_link_hash_entry *h; + + r_symndx = htab->r_sym (rel->r_info); + r_type = ELF32_R_TYPE (rel->r_info); + + if (r_symndx >= NUM_SHDR_ENTRIES (symtab_hdr)) + { + /* xgettext:c-format */ + _bfd_error_handler (_("%pB: bad symbol index: %d"), + abfd, r_symndx); + goto error_return; + } + + if (r_symndx < symtab_hdr->sh_info) + h = NULL; + else + { + h = sym_hashes[r_symndx - symtab_hdr->sh_info]; + while (h->root.type == bfd_link_hash_indirect + || h->root.type == bfd_link_hash_warning) + h = (struct elf_link_hash_entry *) h->root.u.i.link; + } + + if (X86_NEED_DYNAMIC_RELOC_TYPE_P (is_x86_64, r_type) + && NEED_DYNAMIC_RELOCATION_P (is_x86_64, info, true, h, sec, + r_type, htab->pointer_r_type)) + { + /* We may copy these reloc types into the output file. + Create a reloc section in dynobj and make room for + this reloc. */ + sreloc = _bfd_elf_make_dynamic_reloc_section + (sec, htab->elf.dynobj, ABI_64_P (abfd) ? 3 : 2, + abfd, sec->use_rela_p); + + if (sreloc != NULL) + return true; + + error_return: + sec->check_relocs_failed = 1; + return false; + } + } + + return true; +} + bool _bfd_elf_x86_valid_reloc_p (asection *input_section, struct bfd_link_info *info, diff --git a/bfd/elfxx-x86.h b/bfd/elfxx-x86.h index 16565a5638b..1bb80280918 100644 --- a/bfd/elfxx-x86.h +++ b/bfd/elfxx-x86.h @@ -47,6 +47,25 @@ #define X86_SIZE_TYPE_P(IS_X86_64, TYPE) \ ((IS_X86_64) ? X86_64_SIZE_TYPE_P(TYPE) : I386_SIZE_TYPE_P (TYPE)) +#define X86_64_NEED_DYNAMIC_RELOC_TYPE_P(TYPE) \ + (X86_64_SIZE_TYPE_P (TYPE) \ + || X86_64_PCREL_TYPE_P (TYPE) \ + || (TYPE) == R_X86_64_8 \ + || (TYPE) == R_X86_64_16 \ + || (TYPE) == R_X86_64_32 \ + || (TYPE) == R_X86_64_32S \ + || (TYPE) == R_X86_64_64) +#define I386_NEED_DYNAMIC_RELOC_TYPE_P(TYPE) \ + (I386_SIZE_TYPE_P (TYPE) \ + || I386_PCREL_TYPE_P (TYPE) \ + || (TYPE) == R_386_32 \ + || (TYPE) == R_386_TLS_LE \ + || (TYPE) == R_386_TLS_LE_32) +#define X86_NEED_DYNAMIC_RELOC_TYPE_P(IS_X86_64, TYPE) \ + ((IS_X86_64) \ + ? X86_64_NEED_DYNAMIC_RELOC_TYPE_P (TYPE) \ + : I386_NEED_DYNAMIC_RELOC_TYPE_P (TYPE)) + #define PLT_CIE_LENGTH 20 #define PLT_FDE_LENGTH 36 #define PLT_FDE_START_OFFSET 4 + PLT_CIE_LENGTH + 8 @@ -653,6 +672,10 @@ extern int _bfd_x86_elf_compare_relocs extern bool _bfd_x86_elf_link_check_relocs (bfd *, struct bfd_link_info *); +extern bool _bfd_x86_elf_check_relocs + (bfd *, struct bfd_link_info *, asection *, + const Elf_Internal_Rela *); + extern bool _bfd_elf_x86_valid_reloc_p (asection *, struct bfd_link_info *, struct elf_x86_link_hash_table *, const Elf_Internal_Rela *, struct elf_link_hash_entry *, @@ -730,10 +753,10 @@ extern void _bfd_x86_elf_link_report_relative_reloc #define bfd_elf32_bfd_link_check_relocs \ _bfd_x86_elf_link_check_relocs +#define elf_backend_check_relocs \ + _bfd_x86_elf_check_relocs #define elf_backend_size_dynamic_sections \ _bfd_x86_elf_size_dynamic_sections -#define elf_backend_always_size_sections \ - _bfd_x86_elf_always_size_sections #define elf_backend_merge_symbol_attribute \ _bfd_x86_elf_merge_symbol_attribute #define elf_backend_copy_indirect_symbol \ @@ -757,39 +780,6 @@ extern void _bfd_x86_elf_link_report_relative_reloc #define ELF_P_ALIGN ELF_MINPAGESIZE -/* Return true if H is a __start_SECNAME/__stop_SECNAME symbol for the - SECNAME section which has been garbage collected by --gc-sections - -z start-stop-gc. */ - -static inline bool -elf_x86_start_stop_gc_p (struct bfd_link_info *link_info, - struct elf_link_hash_entry *h) -{ - if (h->start_stop - && link_info->gc_sections - && link_info->start_stop_gc) - { - asection *s = h->root.u.def.section; - - do - { - /* Return false if any SECNAME section is kept. */ - if (s->gc_mark) - return false; - s = bfd_get_next_section_by_name (s->owner, s); - } - while (s != NULL); - - /* Return true only if all SECNAME sections have been garbage - collected. */ - return true; - } - - /* Return false if H isn't a __start_SECNAME/__stop_SECNAME symbol or - --gc-sections or -z start-stop-gc isn't used. */ - return false; -} - /* Allocate x86 GOT info for local symbols. */ static inline bool diff --git a/ld/testsuite/ld-i386/pr27491-1a.d b/ld/testsuite/ld-i386/pr27491-1a.d index 006c17695c1..39b25f6507f 100644 --- a/ld/testsuite/ld-i386/pr27491-1a.d +++ b/ld/testsuite/ld-i386/pr27491-1a.d @@ -9,6 +9,6 @@ Disassembly of section .text: [a-f0-9]+ : - +[a-f0-9]+: 8b 83 ([0-9a-f]{2} ){4}[ \t]+mov +-0x[a-f0-9]+\(%ebx\),%eax - +[a-f0-9]+: 8b 83 ([0-9a-f]{2} ){4}[ \t]+mov +-0x[a-f0-9]+\(%ebx\),%eax + +[a-f0-9]+: c7 c0 00 00 00 00 mov \$0x0,%eax + +[a-f0-9]+: c7 c0 00 00 00 00 mov \$0x0,%eax #pass diff --git a/ld/testsuite/ld-x86-64/pr27491-1a.d b/ld/testsuite/ld-x86-64/pr27491-1a.d index ade5c6fa4f9..215124c6401 100644 --- a/ld/testsuite/ld-x86-64/pr27491-1a.d +++ b/ld/testsuite/ld-x86-64/pr27491-1a.d @@ -9,6 +9,6 @@ Disassembly of section .text: [a-f0-9]+ : - +[a-f0-9]+: 48 8b 05 ([0-9a-f]{2} ){4}[ \t]+mov +0x[a-f0-9]+\(%rip\),%rax[ \t]+# [a-f0-9]+ <_DYNAMIC\+0x[a-f0-9]+> - +[a-f0-9]+: 48 8b 05 ([0-9a-f]{2} ){4}[ \t]+mov +0x[a-f0-9]+\(%rip\),%rax[ \t]+# [a-f0-9]+ <_DYNAMIC\+0x[a-f0-9]+> + +[a-f0-9]+: 48 c7 c0 00 00 00 00 mov \$0x0,%rax + +[a-f0-9]+: 48 c7 c0 00 00 00 00 mov \$0x0,%rax #pass From patchwork Fri Jan 7 19:06:23 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "H.J. Lu" X-Patchwork-Id: 49723 Return-Path: X-Original-To: patchwork@sourceware.org Delivered-To: patchwork@sourceware.org Received: from server2.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id 881263857C4D for ; Fri, 7 Jan 2022 19:07:56 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 881263857C4D DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=sourceware.org; s=default; t=1641582476; bh=Do+Y3VLR0PJRAHhibGhFMEAZcC1lR9uXPD/wEOiv52c=; h=To:Subject:Date:In-Reply-To:References:List-Id:List-Unsubscribe: List-Archive:List-Post:List-Help:List-Subscribe:From:Reply-To:Cc: From; b=lUGpr1qKNLrOrlZOR/TRLCI/RhQPRs3smc1XjXCgwb9bIPhA1VkTB3KpkZvMHtbe2 m8RSvI8pYvZHzxzEJrlyB9SkVgytYuDnr4uq4P1W2eaH0cHuvx5HAb0u0nse6PYvAC CtoeIKoXMim1e0S9AnfQyBasmBK/5/T9KRrcxOQg= X-Original-To: libc-alpha@sourceware.org Delivered-To: libc-alpha@sourceware.org Received: from mail-pl1-x636.google.com (mail-pl1-x636.google.com [IPv6:2607:f8b0:4864:20::636]) by sourceware.org (Postfix) with ESMTPS id 5BD9F3858C39; Fri, 7 Jan 2022 19:06:34 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.1 sourceware.org 5BD9F3858C39 Received: by mail-pl1-x636.google.com with SMTP id s15so5521506plg.12; Fri, 07 Jan 2022 11:06:34 -0800 (PST) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=Do+Y3VLR0PJRAHhibGhFMEAZcC1lR9uXPD/wEOiv52c=; b=lzIkSdbei7YDYYh4/xeFhpk3FPWNbNuyaMhpNqT1dCsLltEbpTVbWcRyo6StzVx82I ko0c5BWEXChkomz+amIUtJcDB3KZvzkPKXiaxkg9bQwvi71wcMw3khvqm1y8oUXu/8+V xAdnvKtwfyHU0TVAVFFxG28DJNz8sx64KZ7CcQjqSrUtHu7susiFrXIcezMGvIF8f91N mSAAMQQkfI9qdyuMf9dbk3dqax9ey+WvRQd3HARtEeMhGQscPsEd43rhHWRno2DgOCi8 6rqNqQa7TSbymJU5nFk01W/zHzQub0oabyOsT/QfurI3CR1Nu8g6uj1wg08T+gzTonNS vbtw== X-Gm-Message-State: AOAM532O/RFVzra720UeW9btMf4rwDXGqq0wL+Bf6CCtR9zzPETdyOHK fHYeMFThCy+lCEnkVIVvObiUI5fgAZU= X-Google-Smtp-Source: ABdhPJys4YntMmJSgPEo9h3ezoUnDrIDI2BqjPgOwGQi5OaN+MsoBZ4A0yDivnEOp5TWkpJ8CZclqw== X-Received: by 2002:a17:902:d510:b0:149:3b5d:2b89 with SMTP id b16-20020a170902d51000b001493b5d2b89mr63486754plg.97.1641582393429; Fri, 07 Jan 2022 11:06:33 -0800 (PST) Received: from gnu-tgl-3.localdomain ([172.58.35.133]) by smtp.gmail.com with ESMTPSA id p2sm2470581pga.24.2022.01.07.11.06.32 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 07 Jan 2022 11:06:33 -0800 (PST) Received: from gnu-tgl-3.. (localhost [IPv6:::1]) by gnu-tgl-3.localdomain (Postfix) with ESMTP id EF331C0920; Fri, 7 Jan 2022 11:06:31 -0800 (PST) To: binutils@sourceware.org Subject: [PATCH 02/10] elf: Add .relr.dyn to special_sections_r Date: Fri, 7 Jan 2022 11:06:23 -0800 Message-Id: <20220107190631.309790-3-hjl.tools@gmail.com> X-Mailer: git-send-email 2.33.1 In-Reply-To: <20220107190631.309790-1-hjl.tools@gmail.com> References: <20220107190631.309790-1-hjl.tools@gmail.com> MIME-Version: 1.0 X-Spam-Status: No, score=-3028.9 required=5.0 tests=BAYES_00, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, DKIM_VALID_EF, FREEMAIL_FROM, GIT_PATCH_0, RCVD_IN_BARRACUDACENTRAL, RCVD_IN_DNSWL_NONE, SPF_HELO_NONE, SPF_PASS, TXREP autolearn=ham autolearn_force=no version=3.4.4 X-Spam-Checker-Version: SpamAssassin 3.4.4 (2020-01-24) on server2.sourceware.org X-BeenThere: libc-alpha@sourceware.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Libc-alpha mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-Patchwork-Original-From: "H.J. Lu via Libc-alpha" From: "H.J. Lu" Reply-To: "H.J. Lu" Cc: libc-alpha@sourceware.org, Nick Clifton , Alan Modra Errors-To: libc-alpha-bounces+patchwork=sourceware.org@sourceware.org Sender: "Libc-alpha" * elf.c (special_sections_r): Add .relr.dyn. --- bfd/elf.c | 1 + 1 file changed, 1 insertion(+) diff --git a/bfd/elf.c b/bfd/elf.c index 1003bd2cdbe..ef0d18105ba 100644 --- a/bfd/elf.c +++ b/bfd/elf.c @@ -2714,6 +2714,7 @@ static const struct bfd_elf_special_section special_sections_r[] = { { STRING_COMMA_LEN (".rodata"), -2, SHT_PROGBITS, SHF_ALLOC }, { STRING_COMMA_LEN (".rodata1"), 0, SHT_PROGBITS, SHF_ALLOC }, + { STRING_COMMA_LEN (".relr.dyn"), 0, SHT_RELR, SHF_ALLOC }, { STRING_COMMA_LEN (".rela"), -1, SHT_RELA, 0 }, { STRING_COMMA_LEN (".rel"), -1, SHT_REL, 0 }, { NULL, 0, 0, 0, 0 } From patchwork Fri Jan 7 19:06:24 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "H.J. Lu" X-Patchwork-Id: 49725 Return-Path: X-Original-To: patchwork@sourceware.org Delivered-To: patchwork@sourceware.org Received: from server2.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id 5C2103857C4A for ; Fri, 7 Jan 2022 19:10:21 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 5C2103857C4A DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=sourceware.org; s=default; t=1641582621; bh=AvRq8T+Y/X4lnD507eZM92Z+2OnMCJ7ez31YhAm4aiY=; h=To:Subject:Date:In-Reply-To:References:List-Id:List-Unsubscribe: List-Archive:List-Post:List-Help:List-Subscribe:From:Reply-To:Cc: From; b=HzQhGRvPQA7JXAKUgTRQA74/FGOcjJbGdbhnq7PPIjahXtdHFqP+P7PFYBt+qv+wn QjFvYq+mg66JRzTsfq32XQD27Q+LD/Ve53r9WaV2JAyuQSs4FJ2+QthEwBch+icZ0W ndWrLjijasSYcUZI31SNy8b0C2QGnV/6sSCEO5Fw= X-Original-To: libc-alpha@sourceware.org Delivered-To: libc-alpha@sourceware.org Received: from mail-pj1-x1029.google.com (mail-pj1-x1029.google.com [IPv6:2607:f8b0:4864:20::1029]) by sourceware.org (Postfix) with ESMTPS id C0E893858412; Fri, 7 Jan 2022 19:06:34 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.1 sourceware.org C0E893858412 Received: by mail-pj1-x1029.google.com with SMTP id 59-20020a17090a09c100b001b34a13745eso5573149pjo.5; Fri, 07 Jan 2022 11:06:34 -0800 (PST) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=AvRq8T+Y/X4lnD507eZM92Z+2OnMCJ7ez31YhAm4aiY=; b=G3vcL2gqAswif74tNyW4uXPR9R9eLKzam1AAj0EXMh43EaOVtTdtmN7RqiCZHAewBw CZwXzh2SoaV/PcrKwhUyuNbgUQuX/I+hRJkgUGsQoutoUu4D+oF204Mwxs+HX70Y1yUj gd5v3F0M7MnU4PFFA8+FUQ4d/K0BXa0Z33f0J6mSXKahmvnfTNKAazH0VLQDEuuhvHJ0 D7TNarmzPPzRdM6ef7VBKE/JN5O3YnDp1Ph2e6JmWVVO/L/PbDYa8PYL2slNlYVCj1zt 7kpxNtnKmgmfUY4WCcjNKYzspg+qFsJ68Ms0fCIaUM3RE+Db5YZijDfVeua8DbkVUnJN CBmg== X-Gm-Message-State: AOAM533K8fFV0a4i6D9AJkUg97cRS9tsV9hMORGpy7Xz/jBJHhaerF4L AXtGyzBlmTs5zRXI7qxYmpA= X-Google-Smtp-Source: ABdhPJx/8WvaxLQ2PbrItKKEmbyHFDKgG3+sbaBwQfzQw2LvFCwi5HFYSUWk4x5nEP1/TiFIlls9CQ== X-Received: by 2002:a17:902:dac4:b0:148:fde0:692a with SMTP id q4-20020a170902dac400b00148fde0692amr64672945plx.47.1641582393760; Fri, 07 Jan 2022 11:06:33 -0800 (PST) Received: from gnu-tgl-3.localdomain ([172.58.35.133]) by smtp.gmail.com with ESMTPSA id z3sm5476330pgc.45.2022.01.07.11.06.32 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 07 Jan 2022 11:06:33 -0800 (PST) Received: from gnu-tgl-3.. (localhost [IPv6:::1]) by gnu-tgl-3.localdomain (Postfix) with ESMTP id F0336C0D75; Fri, 7 Jan 2022 11:06:31 -0800 (PST) To: binutils@sourceware.org Subject: [PATCH 03/10] elf: Extract _bfd_elf_process_reverse_copy Date: Fri, 7 Jan 2022 11:06:24 -0800 Message-Id: <20220107190631.309790-4-hjl.tools@gmail.com> X-Mailer: git-send-email 2.33.1 In-Reply-To: <20220107190631.309790-1-hjl.tools@gmail.com> References: <20220107190631.309790-1-hjl.tools@gmail.com> MIME-Version: 1.0 X-Spam-Status: No, score=-3028.9 required=5.0 tests=BAYES_00, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, DKIM_VALID_EF, FREEMAIL_FROM, GIT_PATCH_0, RCVD_IN_BARRACUDACENTRAL, RCVD_IN_DNSWL_NONE, SPF_HELO_NONE, SPF_PASS, TXREP autolearn=ham autolearn_force=no version=3.4.4 X-Spam-Checker-Version: SpamAssassin 3.4.4 (2020-01-24) on server2.sourceware.org X-BeenThere: libc-alpha@sourceware.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Libc-alpha mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-Patchwork-Original-From: "H.J. Lu via Libc-alpha" From: "H.J. Lu" Reply-To: "H.J. Lu" Cc: libc-alpha@sourceware.org, Nick Clifton , Alan Modra Errors-To: libc-alpha-bounces+patchwork=sourceware.org@sourceware.org Sender: "Libc-alpha" Extract _bfd_elf_process_reverse_copy from elf_link_input_bfd so that it can be called in check_relocs to set SEC_ELF_REVERSE_COPY before elf_link_input_bfd is called. * elf-bfd.h (_bfd_elf_process_reverse_copy): New prototype. * elflink.c (_bfd_elf_process_reverse_copy): New. Extracted from elf_link_input_bfd. (elf_link_input_bfd): Call _bfd_elf_process_reverse_copy. --- bfd/elf-bfd.h | 2 ++ bfd/elflink.c | 60 ++++++++++++++++++++++++++++++++------------------- 2 files changed, 40 insertions(+), 22 deletions(-) diff --git a/bfd/elf-bfd.h b/bfd/elf-bfd.h index 81f8fd47db7..2441b3c0cd7 100644 --- a/bfd/elf-bfd.h +++ b/bfd/elf-bfd.h @@ -2331,6 +2331,8 @@ extern const struct bfd_elf_special_section *_bfd_elf_get_special_section (const char *, const struct bfd_elf_special_section *, unsigned int); extern const struct bfd_elf_special_section *_bfd_elf_get_sec_type_attr (bfd *, asection *); +extern bool _bfd_elf_process_reverse_copy (asection *, unsigned int, + unsigned int); extern bool _bfd_elf_link_hide_sym_by_version (struct bfd_link_info *, struct elf_link_hash_entry *); diff --git a/bfd/elflink.c b/bfd/elflink.c index 059461b5725..29ef9ddf8b9 100644 --- a/bfd/elflink.c +++ b/bfd/elflink.c @@ -10851,6 +10851,41 @@ _bfd_elf_check_kept_section (asection *sec, struct bfd_link_info *info) return kept; } +/* Set SEC_ELF_REVERSE_COPY on section S when we need to reverse-copy + input .ctors/.dtors sections if they are placed in .init_array or + .finit_array for output. ADDRESS_SIZE is address in bytes. + INT_RELS_PER_EXT_REL is the number of internal relocations to + allocate per external relocation entry. */ + +bool +_bfd_elf_process_reverse_copy (asection *s, unsigned int address_size, + unsigned int int_rels_per_ext_rel) +{ + if (s->size <= address_size + || (s->flags & SEC_ELF_REVERSE_COPY) != 0) + return true; + + if (((startswith (s->name, ".ctors") + && strcmp (s->output_section->name, ".init_array") == 0) + || (startswith (s->name, ".dtors") + && strcmp (s->output_section->name, ".fini_array") == 0)) + && (s->name[6] == 0 || s->name[6] == '.')) + { + if (s->size * int_rels_per_ext_rel + != s->reloc_count * address_size) + { + _bfd_error_handler + /* xgettext:c-format */ + (_("error: %pB: size of section %pA is not multiple of " + "address size"), s->owner, s); + bfd_set_error (bfd_error_bad_value); + return false; + } + s->flags |= SEC_ELF_REVERSE_COPY; + } + return true; +} + /* Link an input file into the linker output file. This function handles all the sections and relocations of the input file at once. This is so that we only have to read the local symbols once, and @@ -11249,28 +11284,9 @@ elf_link_input_bfd (struct elf_final_link_info *flinfo, bfd *input_bfd) /* We need to reverse-copy input .ctors/.dtors sections if they are placed in .init_array/.finit_array for output. */ - if (o->size > address_size - && ((startswith (o->name, ".ctors") - && strcmp (o->output_section->name, - ".init_array") == 0) - || (startswith (o->name, ".dtors") - && strcmp (o->output_section->name, - ".fini_array") == 0)) - && (o->name[6] == 0 || o->name[6] == '.')) - { - if (o->size * bed->s->int_rels_per_ext_rel - != o->reloc_count * address_size) - { - _bfd_error_handler - /* xgettext:c-format */ - (_("error: %pB: size of section %pA is not " - "multiple of address size"), - input_bfd, o); - bfd_set_error (bfd_error_bad_value); - return false; - } - o->flags |= SEC_ELF_REVERSE_COPY; - } + if (!_bfd_elf_process_reverse_copy (o, address_size, + bed->s->int_rels_per_ext_rel)) + return false; action_discarded = -1; if (!elf_section_ignore_discarded_relocs (o)) From patchwork Fri Jan 7 19:06:25 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "H.J. Lu" X-Patchwork-Id: 49724 Return-Path: X-Original-To: patchwork@sourceware.org Delivered-To: patchwork@sourceware.org Received: from server2.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id CC1933858017 for ; Fri, 7 Jan 2022 19:09:38 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org CC1933858017 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=sourceware.org; s=default; t=1641582578; bh=Shha5XO9Qq5yWLD6GKRmXLdQ7jhGbuheO+D1g8Sl3dM=; h=To:Subject:Date:In-Reply-To:References:List-Id:List-Unsubscribe: List-Archive:List-Post:List-Help:List-Subscribe:From:Reply-To:Cc: From; b=ObiYEnEjZ7aM7NKVtifzN2X9hxnUH8CeB702FYJVlULwGP3eLH5WD6kngayuMIibq DnAHouq9mM0ywmIZ8ixQeYdXvVzkn57h4tQC2Xy/cfd2eS140hF+8JKwXu/DOT23kp asFVRVC4HQAbkqVWRAtBd1tOuJtYszU0jLlx/G9c= X-Original-To: libc-alpha@sourceware.org Delivered-To: libc-alpha@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 840943858408; Fri, 7 Jan 2022 19:06:34 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.1 sourceware.org 840943858408 Received: by mail-pl1-x633.google.com with SMTP id h1so5536283pls.11; Fri, 07 Jan 2022 11:06:34 -0800 (PST) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=Shha5XO9Qq5yWLD6GKRmXLdQ7jhGbuheO+D1g8Sl3dM=; b=7wZ4H4lTLU+LId0azYZNbJqa2eBMhKhzHKOvEFmfp32p11El12pXVE9XesKm3BZEOA u129eNOKTZwqReMEr9xLjIllCAHborn74APykwCQ008dgja0RKThqiNT8t7fSccNmgxf LXsyWr1y2GXg5xh0ZXonfASr5BySHcaK/TdIjFBi45o3+3HIxj0ofTJ3FnIeoxe9frvL yM8qFmLx9QEWs+t1MPNar6jwlkPX71Kq3xnBKlpiLXFinv7hx9xS/2vqfTxZMbyDVX19 JDBGTzpGkDWl+u+f0xM1VB052xr5v3v0kK2ICy5wKF/S98A0dFl6Pgm7rvQUqG+sFwUd c6lw== X-Gm-Message-State: AOAM5301KmDhb+1tZ5q7c595hTPBppU7swqd+xxJcPOdWCOwZjRegO/f WCQgzOfyAuP6gioDp5WjmfIgY7+ggYA= X-Google-Smtp-Source: ABdhPJx9Sclct/ETFW2ghD2fDgNS3bAVNEA3Scv2SVj8byfKqMtzTBoH7PfXtuB8w8iY2+qHwlaDLg== X-Received: by 2002:a17:90b:3607:: with SMTP id ml7mr17224102pjb.56.1641582393598; Fri, 07 Jan 2022 11:06:33 -0800 (PST) Received: from gnu-tgl-3.localdomain ([172.58.35.133]) by smtp.gmail.com with ESMTPSA id e5sm1031121pjr.25.2022.01.07.11.06.32 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 07 Jan 2022 11:06:33 -0800 (PST) Received: from gnu-tgl-3.. (localhost [IPv6:::1]) by gnu-tgl-3.localdomain (Postfix) with ESMTP id 0BE54C0DB6; Fri, 7 Jan 2022 11:06:32 -0800 (PST) To: binutils@sourceware.org Subject: [PATCH 04/10] elf: Pass need_layout to _bfd_elf_map_sections_to_segments Date: Fri, 7 Jan 2022 11:06:25 -0800 Message-Id: <20220107190631.309790-5-hjl.tools@gmail.com> X-Mailer: git-send-email 2.33.1 In-Reply-To: <20220107190631.309790-1-hjl.tools@gmail.com> References: <20220107190631.309790-1-hjl.tools@gmail.com> MIME-Version: 1.0 X-Spam-Status: No, score=-3028.9 required=5.0 tests=BAYES_00, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, DKIM_VALID_EF, FREEMAIL_FROM, GIT_PATCH_0, RCVD_IN_BARRACUDACENTRAL, RCVD_IN_DNSWL_NONE, SPF_HELO_NONE, SPF_PASS, TXREP autolearn=ham autolearn_force=no version=3.4.4 X-Spam-Checker-Version: SpamAssassin 3.4.4 (2020-01-24) on server2.sourceware.org X-BeenThere: libc-alpha@sourceware.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Libc-alpha mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-Patchwork-Original-From: "H.J. Lu via Libc-alpha" From: "H.J. Lu" Reply-To: "H.J. Lu" Cc: libc-alpha@sourceware.org, Nick Clifton , Alan Modra Errors-To: libc-alpha-bounces+patchwork=sourceware.org@sourceware.org Sender: "Libc-alpha" On some targets, the DT_RELR section size can be computed only after all symbols addresses can be determined. Update ldelf_map_segments to pass need_layout to _bfd_elf_map_sections_to_segments which will size DT_RELR section and set need_layout to true if the DT_RELR section size is changed. bfd/ * elf-bfd.h (_bfd_elf_map_sections_to_segments): Add a bool pointer argument. * elf.c (_bfd_elf_map_sections_to_segments): Add a bool pointer argument to indicate if section layout needs update. (assign_file_positions_for_load_sections): Pass NULL to _bfd_elf_map_sections_to_segments. * elflink.c (_bfd_elf_strip_zero_sized_dynamic_sections): Pass NULL to _bfd_elf_map_sections_to_segments. ld/ * ldelfgen.c (ldelf_map_segments): Pass &need_layout to _bfd_elf_map_sections_to_segments. --- bfd/elf-bfd.h | 2 +- bfd/elf.c | 9 ++++++--- bfd/elflink.c | 3 ++- ld/ldelfgen.c | 3 ++- 4 files changed, 11 insertions(+), 6 deletions(-) diff --git a/bfd/elf-bfd.h b/bfd/elf-bfd.h index 2441b3c0cd7..c4d2ef00d6b 100644 --- a/bfd/elf-bfd.h +++ b/bfd/elf-bfd.h @@ -2718,7 +2718,7 @@ extern struct elf_segment_map * _bfd_elf_make_dynamic_segment (bfd *, asection *); extern bool _bfd_elf_map_sections_to_segments - (bfd *, struct bfd_link_info *); + (bfd *, struct bfd_link_info *, bool *); extern bool _bfd_elf_is_function_type (unsigned int); diff --git a/bfd/elf.c b/bfd/elf.c index ef0d18105ba..8b866b63e18 100644 --- a/bfd/elf.c +++ b/bfd/elf.c @@ -4609,10 +4609,13 @@ elf_modify_segment_map (bfd *abfd, #define IS_TBSS(s) \ ((s->flags & (SEC_THREAD_LOCAL | SEC_LOAD)) == SEC_THREAD_LOCAL) -/* Set up a mapping from BFD sections to program segments. */ +/* Set up a mapping from BFD sections to program segments. Update + NEED_LAYOUT if the section layout is changed. */ bool -_bfd_elf_map_sections_to_segments (bfd *abfd, struct bfd_link_info *info) +_bfd_elf_map_sections_to_segments (bfd *abfd, + struct bfd_link_info *info, + bool *need_layout ATTRIBUTE_UNUSED) { unsigned int count; struct elf_segment_map *m; @@ -5416,7 +5419,7 @@ assign_file_positions_for_load_sections (bfd *abfd, unsigned int opb = bfd_octets_per_byte (abfd, NULL); if (link_info == NULL - && !_bfd_elf_map_sections_to_segments (abfd, link_info)) + && !_bfd_elf_map_sections_to_segments (abfd, link_info, NULL)) return false; alloc = 0; diff --git a/bfd/elflink.c b/bfd/elflink.c index 29ef9ddf8b9..bea413ec24e 100644 --- a/bfd/elflink.c +++ b/bfd/elflink.c @@ -3676,7 +3676,8 @@ _bfd_elf_strip_zero_sized_dynamic_sections (struct bfd_link_info *info) { /* Regenerate program headers. */ elf_seg_map (info->output_bfd) = NULL; - return _bfd_elf_map_sections_to_segments (info->output_bfd, info); + return _bfd_elf_map_sections_to_segments (info->output_bfd, info, + NULL); } return true; diff --git a/ld/ldelfgen.c b/ld/ldelfgen.c index 5c033bbfbe0..58b37c65bc9 100644 --- a/ld/ldelfgen.c +++ b/ld/ldelfgen.c @@ -304,7 +304,8 @@ ldelf_map_segments (bool need_layout) if (lang_phdr_list == NULL) elf_seg_map (link_info.output_bfd) = NULL; if (!_bfd_elf_map_sections_to_segments (link_info.output_bfd, - &link_info)) + &link_info, + &need_layout)) einfo (_("%F%P: map sections to segments failed: %E\n")); if (phdr_size != elf_program_header_size (link_info.output_bfd)) From patchwork Fri Jan 7 19:06:26 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "H.J. Lu" X-Patchwork-Id: 49729 Return-Path: X-Original-To: patchwork@sourceware.org Delivered-To: patchwork@sourceware.org Received: from server2.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id 5FBC63857C6D for ; Fri, 7 Jan 2022 19:18:18 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 5FBC63857C6D DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=sourceware.org; s=default; t=1641583098; bh=eW9vAratfr/tZZZnxwbtSN9t/HNH9WLYavOR6nb+kg8=; h=To:Subject:Date:In-Reply-To:References:List-Id:List-Unsubscribe: List-Archive:List-Post:List-Help:List-Subscribe:From:Reply-To:Cc: From; b=jRZwuEknLxsR7GzYH/Z+q3d3MrvsUcWsRz8D+WdOG9F5BfZ9XbuXBDAitEZ/LDuJP Cb7/KLwsPdCGoMKXFfYryklJgpy4i4dB8QlCR3WMk3M3t57/M/hTHQfoIjaIS7ZdF5 Mwd1DiJMy5XX9uJ3S3A7gfea2/AuezHiYbJerxA8= X-Original-To: libc-alpha@sourceware.org Delivered-To: libc-alpha@sourceware.org Received: from mail-pg1-x531.google.com (mail-pg1-x531.google.com [IPv6:2607:f8b0:4864:20::531]) by sourceware.org (Postfix) with ESMTPS id 2F68D3858408; Fri, 7 Jan 2022 19:06:36 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.1 sourceware.org 2F68D3858408 Received: by mail-pg1-x531.google.com with SMTP id f8so6198839pgf.8; Fri, 07 Jan 2022 11:06:36 -0800 (PST) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=eW9vAratfr/tZZZnxwbtSN9t/HNH9WLYavOR6nb+kg8=; b=nJL8xx5pfwkOrPidSjaETHQQ0NqT7ituTNgVCtCJIHM9RiBUDElAUZskeAE4FuYqUl Ithx7OBl09JNIHQY5oqgOlBYezl4TgRSS7nBfnOalKXtOvtjjQ8fFA0JuI8OJp1GMQP6 IMLd+wYUhP5bjwPS2uciaAub2Mx6DzXyxM7hWnF6JXlAxQ8Sa4lbEEpPz6bIO8JVrqik mdEKsolVbEoVEzb/hqHBWd/+AnTAURB2kIAncZPpmcg2HjHbG4fgvNb9Vf8NTf2zLVgh lQiTIHDRkBXdKp5fM/UoCpSuBr9whMRgASGfVHkxAtE4twlyfrlbBR+mbXN/KjOldY7+ 3FDQ== X-Gm-Message-State: AOAM531fwaJUg9wy8md2knHla8ygJ6Zy1JgIogTS38EHIG+NqTRScoCz dQ4AWVwopGLvlUDWulJecVU= X-Google-Smtp-Source: ABdhPJxYA43KpFdRP2Fg/FByptYKmKK+QkgnrOm1LXonf4Un0cpFlCImqtnqTNchEHTcqkKMOlBfNQ== X-Received: by 2002:a63:8c5a:: with SMTP id q26mr3330380pgn.283.1641582395129; Fri, 07 Jan 2022 11:06:35 -0800 (PST) Received: from gnu-tgl-3.localdomain ([172.58.35.133]) by smtp.gmail.com with ESMTPSA id e15sm6624256pfv.23.2022.01.07.11.06.34 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 07 Jan 2022 11:06:34 -0800 (PST) Received: from gnu-tgl-3.. (localhost [IPv6:::1]) by gnu-tgl-3.localdomain (Postfix) with ESMTP id 1AF97C0EDD; Fri, 7 Jan 2022 11:06:32 -0800 (PST) To: binutils@sourceware.org Subject: [PATCH 05/10] ld: Initial DT_RELR support Date: Fri, 7 Jan 2022 11:06:26 -0800 Message-Id: <20220107190631.309790-6-hjl.tools@gmail.com> X-Mailer: git-send-email 2.33.1 In-Reply-To: <20220107190631.309790-1-hjl.tools@gmail.com> References: <20220107190631.309790-1-hjl.tools@gmail.com> MIME-Version: 1.0 X-Spam-Status: No, score=-3028.9 required=5.0 tests=BAYES_00, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, DKIM_VALID_EF, FREEMAIL_FROM, GIT_PATCH_0, RCVD_IN_BARRACUDACENTRAL, RCVD_IN_DNSWL_NONE, SPF_HELO_NONE, SPF_PASS, TXREP autolearn=ham autolearn_force=no version=3.4.4 X-Spam-Checker-Version: SpamAssassin 3.4.4 (2020-01-24) on server2.sourceware.org X-BeenThere: libc-alpha@sourceware.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Libc-alpha mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-Patchwork-Original-From: "H.J. Lu via Libc-alpha" From: "H.J. Lu" Reply-To: "H.J. Lu" Cc: libc-alpha@sourceware.org, Nick Clifton , Alan Modra Errors-To: libc-alpha-bounces+patchwork=sourceware.org@sourceware.org Sender: "Libc-alpha" Add a -z pack-relative-relocs option to enable DT_RELR and create a relr.dyn section for DT_RELR. -z pack-relative-relocs implies -z combreloc and --relax. --no-relax and -z nocombreloc imply -z nopack-relative-relocs. -z pack-relative-relocs is chosen over the similar option in lld, --pack-dyn-relocs=relr, to implement a glibc binary lockout mechanism with a special glibc version symbol, to avoid random crashes of DT_RELR binaries with the existing glibc binaries. bfd/ * elf-bfd.h (elf_link_hash_table): Add srelrdyn. * elflink.c (_bfd_elf_link_create_dynamic_sections): Create a .relr.dyn section for DT_RELR. include/ * bfdlink.h (bfd_link_info): Add enable_dt_relr. ld/ * News: Mention -z pack-relative-relocs and -z nopack-relative-relocs. * ld.texi: Document -z pack-relative-relocs and -z nopack-relative-relocs. * ldelf.c (ldelf_after_parse): Disable DT_RELR if not building PIE nor shared library. Add 3 spare dynamic tags for DT_RELR, DT_RELRSZ and DT_RELRENT. * lexsup.c (parse_args): Disable DT_RELR for --no-relax. * emulparams/elf32_x86_64.sh: Source dt-relr.sh. * emulparams/elf_i386.sh: Likewise. * emulparams/elf_x86_64.sh: Likewise. * emulparams/dt-relr.sh: New file. * emultempl/elf.em (gld${EMULATION_NAME}_handle_option): Disable DT_RELR for -z nocombreloc. * scripttempl/elf.sc: Support .relr.dyn. --- bfd/elf-bfd.h | 1 + bfd/elflink.c | 11 +++++++++++ include/bfdlink.h | 4 ++++ ld/NEWS | 3 +++ ld/emulparams/dt-relr.sh | 21 +++++++++++++++++++++ ld/emulparams/elf32_x86_64.sh | 1 + ld/emulparams/elf_i386.sh | 1 + ld/emulparams/elf_x86_64.sh | 1 + ld/emultempl/elf.em | 5 ++++- ld/ld.texi | 14 +++++++++++++- ld/ldelf.c | 13 +++++++++++++ ld/lexsup.c | 1 + ld/scripttempl/elf.sc | 4 ++++ 13 files changed, 78 insertions(+), 2 deletions(-) create mode 100644 ld/emulparams/dt-relr.sh diff --git a/bfd/elf-bfd.h b/bfd/elf-bfd.h index c4d2ef00d6b..4e73d79ee77 100644 --- a/bfd/elf-bfd.h +++ b/bfd/elf-bfd.h @@ -707,6 +707,7 @@ struct elf_link_hash_table asection *irelplt; asection *irelifunc; asection *dynsym; + asection *srelrdyn; }; /* Returns TRUE if the hash table is a struct elf_link_hash_table. */ diff --git a/bfd/elflink.c b/bfd/elflink.c index bea413ec24e..d51b00b6c10 100644 --- a/bfd/elflink.c +++ b/bfd/elflink.c @@ -359,6 +359,17 @@ _bfd_elf_link_create_dynamic_sections (bfd *abfd, struct bfd_link_info *info) elf_section_data (s)->this_hdr.sh_entsize = 4; } + if (info->enable_dt_relr) + { + s = bfd_make_section_anyway_with_flags (abfd, ".relr.dyn", + (bed->dynamic_sec_flags + | SEC_READONLY)); + if (s == NULL + || !bfd_set_section_alignment (s, bed->s->log_file_align)) + return false; + elf_hash_table (info)->srelrdyn = s; + } + /* Let the backend create the rest of the sections. This lets the backend set the right flags. The backend will normally create the .got and .plt sections. */ diff --git a/include/bfdlink.h b/include/bfdlink.h index 01f57c22edf..92e3e32360b 100644 --- a/include/bfdlink.h +++ b/include/bfdlink.h @@ -413,6 +413,10 @@ struct bfd_link_info /* TRUE if PT_GNU_RELRO segment should be created. */ unsigned int relro: 1; + /* TRUE if DT_RELR should be enabled for compact relative + relocations. */ + unsigned int enable_dt_relr: 1; + /* TRUE if separate code segment should be created. */ unsigned int separate_code: 1; diff --git a/ld/NEWS b/ld/NEWS index 5d3d80dbbba..77c716b577d 100644 --- a/ld/NEWS +++ b/ld/NEWS @@ -1,5 +1,8 @@ -*- text -*- +* Add -z pack-relative-relocs/-z no pack-relative-relocs to x86 ELF + linker to pack relative relocations in the DT_RELR section. + * Add support for the LoongArch architecture. * Add -z indirect-extern-access/-z noindirect-extern-access to x86 ELF diff --git a/ld/emulparams/dt-relr.sh b/ld/emulparams/dt-relr.sh new file mode 100644 index 00000000000..ed93ee2b5c2 --- /dev/null +++ b/ld/emulparams/dt-relr.sh @@ -0,0 +1,21 @@ +HAVE_DT_RELR=yes +PARSE_AND_LIST_OPTIONS_PACK_RELATIVE_RELOCS=' + fprintf (file, _("\ + -z pack-relative-relocs Pack relative relocations\n")); + fprintf (file, _("\ + -z nopack-relative-relocs Do not pack relative relocations (default)\n")); +' + +PARSE_AND_LIST_ARGS_CASE_Z_PACK_RELATIVE_RELOCS=' + else if (strcmp (optarg, "pack-relative-relocs") == 0) + { + link_info.enable_dt_relr = true; + link_info.combreloc = true; + } + else if (strcmp (optarg, "nopack-relative-relocs") == 0) + link_info.enable_dt_relr = false; +' + + +PARSE_AND_LIST_OPTIONS="$PARSE_AND_LIST_OPTIONS $PARSE_AND_LIST_OPTIONS_PACK_RELATIVE_RELOCS" +PARSE_AND_LIST_ARGS_CASE_Z="$PARSE_AND_LIST_ARGS_CASE_Z $PARSE_AND_LIST_ARGS_CASE_Z_PACK_RELATIVE_RELOCS" diff --git a/ld/emulparams/elf32_x86_64.sh b/ld/emulparams/elf32_x86_64.sh index ac0a7aa6dcf..4bff41287c1 100644 --- a/ld/emulparams/elf32_x86_64.sh +++ b/ld/emulparams/elf32_x86_64.sh @@ -7,6 +7,7 @@ source_sh ${srcdir}/emulparams/cet.sh source_sh ${srcdir}/emulparams/x86-report-relative.sh source_sh ${srcdir}/emulparams/x86-64-level.sh source_sh ${srcdir}/emulparams/static.sh +source_sh ${srcdir}/emulparams/dt-relr.sh SCRIPT_NAME=elf ELFSIZE=32 OUTPUT_FORMAT="elf32-x86-64" diff --git a/ld/emulparams/elf_i386.sh b/ld/emulparams/elf_i386.sh index 98532e5edbc..ae17bb4b3f7 100644 --- a/ld/emulparams/elf_i386.sh +++ b/ld/emulparams/elf_i386.sh @@ -6,6 +6,7 @@ source_sh ${srcdir}/emulparams/cet.sh source_sh ${srcdir}/emulparams/x86-report-relative.sh source_sh ${srcdir}/emulparams/x86-64-level.sh source_sh ${srcdir}/emulparams/static.sh +source_sh ${srcdir}/emulparams/dt-relr.sh SCRIPT_NAME=elf OUTPUT_FORMAT="elf32-i386" NO_RELA_RELOCS=yes diff --git a/ld/emulparams/elf_x86_64.sh b/ld/emulparams/elf_x86_64.sh index 48d0974711b..5f2743ed409 100644 --- a/ld/emulparams/elf_x86_64.sh +++ b/ld/emulparams/elf_x86_64.sh @@ -8,6 +8,7 @@ source_sh ${srcdir}/emulparams/x86-report-relative.sh source_sh ${srcdir}/emulparams/x86-64-level.sh source_sh ${srcdir}/emulparams/x86-64-lam.sh source_sh ${srcdir}/emulparams/static.sh +source_sh ${srcdir}/emulparams/dt-relr.sh SCRIPT_NAME=elf ELFSIZE=64 OUTPUT_FORMAT="elf64-x86-64" diff --git a/ld/emultempl/elf.em b/ld/emultempl/elf.em index 59775260b06..7a32a4cc4d4 100644 --- a/ld/emultempl/elf.em +++ b/ld/emultempl/elf.em @@ -822,7 +822,10 @@ fragment < link_info.maxpagesize) einfo (_("%F%P: common page size (0x%v) > maximum page size (0x%v)\n"), diff --git a/ld/lexsup.c b/ld/lexsup.c index 5acc47ed5a0..3942716963a 100644 --- a/ld/lexsup.c +++ b/ld/lexsup.c @@ -1229,6 +1229,7 @@ parse_args (unsigned argc, char **argv) break; case OPTION_NO_RELAX: DISABLE_RELAXATION; + link_info.enable_dt_relr = false; break; case OPTION_RELAX: ENABLE_RELAXATION; diff --git a/ld/scripttempl/elf.sc b/ld/scripttempl/elf.sc index a9a39ad402c..f3552a4a554 100644 --- a/ld/scripttempl/elf.sc +++ b/ld/scripttempl/elf.sc @@ -10,6 +10,7 @@ # empty. # HAVE_NOINIT - Include a .noinit output section in the script. # HAVE_PERSISTENT - Include a .persistent output section in the script. +# HAVE_DT_RELR - Include a .relr.dyn output section in the script. # SMALL_DATA_CTOR - .ctors contains small data. # SMALL_DATA_DTOR - .dtors contains small data. # DATA_ADDR - if end-of-text-plus-one-page isn't right for data start @@ -520,6 +521,9 @@ emit_dyn() fi fi rm -f ldscripts/dyntmp.$$ + if test -n "${COMBRELOC}" && test -n "${HAVE_DT_RELR}"; then + echo " .relr.dyn : { *(.relr.dyn) }" + fi } test -n "${NON_ALLOC_DYN}${SEPARATE_CODE}" || emit_dyn From patchwork Fri Jan 7 19:06:27 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "H.J. Lu" X-Patchwork-Id: 49727 Return-Path: X-Original-To: patchwork@sourceware.org Delivered-To: patchwork@sourceware.org Received: from server2.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id A4F7E3857C59 for ; Fri, 7 Jan 2022 19:13:51 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org A4F7E3857C59 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=sourceware.org; s=default; t=1641582831; bh=/vZ6gCMPu8UV8jYvh4DQxd1Ke9f1uLbhrhjIl8JsiIg=; h=To:Subject:Date:In-Reply-To:References:List-Id:List-Unsubscribe: List-Archive:List-Post:List-Help:List-Subscribe:From:Reply-To:Cc: From; b=l9c3ZH/FZGGrLtsKXIScxrk0lqddqZ5WjtEGW4rqcHD5Z3roJ73zuyogQBiZkpdpj agEpZHPqAiOcUSqhQltrWEDEqZaoJ8LXYtn3G/e7h8vG5NOXUHWk5x8iRYM1WuT66Z PlupUKBlNnjrv8Eots21Xc2R8GF5/gH3/tAqDCtc= X-Original-To: libc-alpha@sourceware.org Delivered-To: libc-alpha@sourceware.org Received: from mail-pj1-x1034.google.com (mail-pj1-x1034.google.com [IPv6:2607:f8b0:4864:20::1034]) by sourceware.org (Postfix) with ESMTPS id 5792C3858430; Fri, 7 Jan 2022 19:06:36 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.1 sourceware.org 5792C3858430 Received: by mail-pj1-x1034.google.com with SMTP id l10-20020a17090a384a00b001b22190e075so12874249pjf.3; Fri, 07 Jan 2022 11:06:36 -0800 (PST) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=/vZ6gCMPu8UV8jYvh4DQxd1Ke9f1uLbhrhjIl8JsiIg=; b=lepnC3goWTptZHxC6NtsjxjqU9Tif9XcmsFiKsfNzdfns0NWZLDtpXhlbC5NxxklHc 851/YH2KneR5RiE/e3/rHJ0O+qnvbjGX7yRTW2fnQO/IQcuNwdeD4muPJTLLqS4De+In OZWt5x03dyt5b0clsy/aPmSdYWKPS1d9hm6ItutDENXY4nXK0SgNOquBntIHwmTW7y3Z wzj9ULxXvb8htm8cXbTqyMD9+s5yZhI3n0Z2wDbZBCd7OJBNBGW68dfJAyWC+GbN+NTx NJ4ZbIfcBay890DohYcXuylC7wNlws+mbrf2qOMdQq8DhGFKvmSSMFh+q7R4LuZiV1A4 f8FQ== X-Gm-Message-State: AOAM531l0Ja530CzMS5CK90IxLPX8Msp+Wz6zmWpl9oXJI+A6oPmURuV xcj4+O05dK7uSCqjD6yHiBSeY62puIg= X-Google-Smtp-Source: ABdhPJxBat5kifiDE8yjv7HkkuJ/CkGF6B6br3L87uhuGw5kzVYxqJ39sqOUusUhOed/yGHAkxuE0w== X-Received: by 2002:a17:902:d4c1:b0:149:e781:df84 with SMTP id o1-20020a170902d4c100b00149e781df84mr11020335plg.152.1641582395446; Fri, 07 Jan 2022 11:06:35 -0800 (PST) Received: from gnu-tgl-3.localdomain ([172.58.35.133]) by smtp.gmail.com with ESMTPSA id k13sm7083830pfc.60.2022.01.07.11.06.34 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 07 Jan 2022 11:06:34 -0800 (PST) Received: from gnu-tgl-3.. (localhost [IPv6:::1]) by gnu-tgl-3.localdomain (Postfix) with ESMTP id 299AAC0EDF; Fri, 7 Jan 2022 11:06:32 -0800 (PST) To: binutils@sourceware.org Subject: [PATCH 06/10] elf: Add size_relative_relocs and finish_relative_relocs Date: Fri, 7 Jan 2022 11:06:27 -0800 Message-Id: <20220107190631.309790-7-hjl.tools@gmail.com> X-Mailer: git-send-email 2.33.1 In-Reply-To: <20220107190631.309790-1-hjl.tools@gmail.com> References: <20220107190631.309790-1-hjl.tools@gmail.com> MIME-Version: 1.0 X-Spam-Status: No, score=-3028.9 required=5.0 tests=BAYES_00, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, DKIM_VALID_EF, FREEMAIL_FROM, GIT_PATCH_0, RCVD_IN_BARRACUDACENTRAL, RCVD_IN_DNSWL_NONE, SPF_HELO_NONE, SPF_PASS, TXREP autolearn=ham autolearn_force=no version=3.4.4 X-Spam-Checker-Version: SpamAssassin 3.4.4 (2020-01-24) on server2.sourceware.org X-BeenThere: libc-alpha@sourceware.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Libc-alpha mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-Patchwork-Original-From: "H.J. Lu via Libc-alpha" From: "H.J. Lu" Reply-To: "H.J. Lu" Cc: libc-alpha@sourceware.org, Nick Clifton , Alan Modra Errors-To: libc-alpha-bounces+patchwork=sourceware.org@sourceware.org Sender: "Libc-alpha" On some targets, the DT_RELR section size can be computed only after all symbols addresses can be determined. Set the preliminary DT_RELR section size before mapping sections to segments and set the final DT_RELR section size after regular symbol processing is done. * elf-bfd.h (elf_backend_data): Add size_relative_relocs and finish_relative_relocs. * elf.c (_bfd_elf_map_sections_to_segments): Call size_relative_relocs if DT_RELR is enabled. * elflink.c (bfd_elf_final_link): Call finish_relative_relocs after regular symbol processing is finished if DT_RELR is enabled. * elfxx-target.h (elf_backend_size_relative_relocs): New. (elf_backend_finish_relative_relocs): Likewise. (elfNN_bed): Add elf_backend_size_relative_relocs and elf_backend_finish_relative_relocs. --- bfd/elf-bfd.h | 10 ++++++++++ bfd/elf.c | 14 ++++++++++++-- bfd/elflink.c | 8 ++++++++ bfd/elfxx-target.h | 8 ++++++++ 4 files changed, 38 insertions(+), 2 deletions(-) diff --git a/bfd/elf-bfd.h b/bfd/elf-bfd.h index 4e73d79ee77..c006008ab7e 100644 --- a/bfd/elf-bfd.h +++ b/bfd/elf-bfd.h @@ -1105,6 +1105,16 @@ struct elf_backend_data (bfd *abfd, struct bfd_link_info *info, asection *o, const Elf_Internal_Rela *relocs); + /* The SIZE_RELATIVE_RELOCS function is called to size relative + relocations when mappig sections to segments. */ + bool (*size_relative_relocs) + (struct bfd_link_info *info, bool *need_layout); + + /* The FINISH_RELATIVE_RELOCS function is called to finish relative + relocations in bfd_elf_final_link. */ + bool (*finish_relative_relocs) + (struct bfd_link_info *info); + /* The CHECK_DIRECTIVES function is called once per input file by the add_symbols phase of the ELF backend linker. The function must inspect the bfd and create any additional symbols according diff --git a/bfd/elf.c b/bfd/elf.c index 8b866b63e18..14c2c7ba734 100644 --- a/bfd/elf.c +++ b/bfd/elf.c @@ -4615,7 +4615,7 @@ elf_modify_segment_map (bfd *abfd, bool _bfd_elf_map_sections_to_segments (bfd *abfd, struct bfd_link_info *info, - bool *need_layout ATTRIBUTE_UNUSED) + bool *need_layout) { unsigned int count; struct elf_segment_map *m; @@ -4626,7 +4626,17 @@ _bfd_elf_map_sections_to_segments (bfd *abfd, no_user_phdrs = elf_seg_map (abfd) == NULL; if (info != NULL) - info->user_phdrs = !no_user_phdrs; + { + info->user_phdrs = !no_user_phdrs; + + /* Size the relative relocations if DT_RELR is enabled. */ + if (info->enable_dt_relr + && need_layout != NULL + && bed->size_relative_relocs + && !bed->size_relative_relocs (info, need_layout)) + info->callbacks->einfo + (_("%F%P: failed to size relative relocations\n")); + } if (no_user_phdrs && bfd_count_sections (abfd) != 0) { diff --git a/bfd/elflink.c b/bfd/elflink.c index d51b00b6c10..31b13f5df7a 100644 --- a/bfd/elflink.c +++ b/bfd/elflink.c @@ -12625,6 +12625,14 @@ bfd_elf_final_link (bfd *abfd, struct bfd_link_info *info) if (!_bfd_elf_fixup_eh_frame_hdr (info)) return false; + /* Finish relative relocations here after regular symbol processing + is finished if DT_RELR is enabled. */ + if (info->enable_dt_relr + && bed->finish_relative_relocs + && !bed->finish_relative_relocs (info)) + info->callbacks->einfo + (_("%F%P: %pB: failed to finish relative relocations\n"), abfd); + /* Since ELF permits relocations to be against local symbols, we must have the local symbols available when we do the relocations. Since we would rather only read the local symbols once, and we diff --git a/bfd/elfxx-target.h b/bfd/elfxx-target.h index 360b056ff58..e31985ef777 100644 --- a/bfd/elfxx-target.h +++ b/bfd/elfxx-target.h @@ -478,6 +478,12 @@ #ifndef elf_backend_check_relocs #define elf_backend_check_relocs 0 #endif +#ifndef elf_backend_size_relative_relocs +#define elf_backend_size_relative_relocs 0 +#endif +#ifndef elf_backend_finish_relative_relocs +#define elf_backend_finish_relative_relocs 0 +#endif #ifndef elf_backend_check_directives #define elf_backend_check_directives 0 #endif @@ -842,6 +848,8 @@ static const struct elf_backend_data elfNN_bed = elf_backend_omit_section_dynsym, elf_backend_relocs_compatible, elf_backend_check_relocs, + elf_backend_size_relative_relocs, + elf_backend_finish_relative_relocs, elf_backend_check_directives, elf_backend_notice_as_needed, elf_backend_adjust_dynamic_symbol, From patchwork Fri Jan 7 19:06:28 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "H.J. Lu" X-Patchwork-Id: 49732 Return-Path: X-Original-To: patchwork@sourceware.org Delivered-To: patchwork@sourceware.org Received: from server2.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id 032343857803 for ; Fri, 7 Jan 2022 19:23:43 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 032343857803 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=sourceware.org; s=default; t=1641583423; bh=N3mwbqti83tyUpt1/KfPy+rGSv6/agKd/LHzW4RCJQ8=; h=To:Subject:Date:In-Reply-To:References:List-Id:List-Unsubscribe: List-Archive:List-Post:List-Help:List-Subscribe:From:Reply-To:Cc: From; b=guEDJfKZFAnHz47+E1gIqXkD1CFux9wtZn+LrBGCFRbmNWgbPKyeUNMbf9wm5BFLc aFJG7ur7gUZ/AtH30GdKgvqqiDvIKpC0GqotTUY9GJt+NzkAYWuT7GBEzRe1linH8J LwdbtZ+Xoka6H7BeSbNwarrTAxIssWQzUfLWTv24= X-Original-To: libc-alpha@sourceware.org Delivered-To: libc-alpha@sourceware.org Received: from mail-pl1-x62e.google.com (mail-pl1-x62e.google.com [IPv6:2607:f8b0:4864:20::62e]) by sourceware.org (Postfix) with ESMTPS id 7E17B3858037; Fri, 7 Jan 2022 19:06:37 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.1 sourceware.org 7E17B3858037 Received: by mail-pl1-x62e.google.com with SMTP id x15so5566506plg.1; Fri, 07 Jan 2022 11:06:37 -0800 (PST) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=N3mwbqti83tyUpt1/KfPy+rGSv6/agKd/LHzW4RCJQ8=; b=QwemhWnNz3DzFr1CFUJt57J/SIKb82XUmqM3VVl+jzNcOKIB0BdIlxuF/Kgj6+RjPN NQCe5QD2N7jb33fEJh/LvbBBHfMIWk2V6yowg4vIia7BQb2Z5Nunvq1LIAHepA/CleQw TTMGMFC5lRxS5B1U5iV6USxksmSqEENAkr6iXOSC+HAirWW+w5Hjq0EMguEjfwxX3W38 W8pkdbjzzntCdZPY5cjlrhnvGYOlaY5hRfrs8M3z8IdJYPmddd/49RbJssJOOcBDGS/8 ms+W/daTX9Lo1d3wQnwnMBCS5nU3lhnCL9FHOl3G3WMam2kdBUJg/VRZ9IJUC/CrrhPy 60Vg== X-Gm-Message-State: AOAM533iAy1bjEBZoZYozqHj36+d3LXhlvyfNMwd0CVQiRYRX+oQZPyb hhlLnRtyCGWGpiMB6DDUUFycM9ze35Y= X-Google-Smtp-Source: ABdhPJyifAZS5Z8ch/MNoVsw06xuOvIfieXXpkB7GndTAm5nT/5Ir7uPTEO6AG6txyKKv68bvAxKuw== X-Received: by 2002:a17:90a:6fc2:: with SMTP id e60mr7022847pjk.102.1641582396283; Fri, 07 Jan 2022 11:06:36 -0800 (PST) Received: from gnu-tgl-3.localdomain ([172.58.35.133]) by smtp.gmail.com with ESMTPSA id c19sm4171273pfl.118.2022.01.07.11.06.34 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 07 Jan 2022 11:06:34 -0800 (PST) Received: from gnu-tgl-3.. (localhost [IPv6:::1]) by gnu-tgl-3.localdomain (Postfix) with ESMTP id 35942C0EE0; Fri, 7 Jan 2022 11:06:32 -0800 (PST) To: binutils@sourceware.org Subject: [PATCH 07/10] elf: Support DT_RELR in linker tests Date: Fri, 7 Jan 2022 11:06:28 -0800 Message-Id: <20220107190631.309790-8-hjl.tools@gmail.com> X-Mailer: git-send-email 2.33.1 In-Reply-To: <20220107190631.309790-1-hjl.tools@gmail.com> References: <20220107190631.309790-1-hjl.tools@gmail.com> MIME-Version: 1.0 X-Spam-Status: No, score=-3028.9 required=5.0 tests=BAYES_00, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, DKIM_VALID_EF, FREEMAIL_FROM, GIT_PATCH_0, RCVD_IN_BARRACUDACENTRAL, RCVD_IN_DNSWL_NONE, SPF_HELO_NONE, SPF_PASS, TXREP autolearn=ham autolearn_force=no version=3.4.4 X-Spam-Checker-Version: SpamAssassin 3.4.4 (2020-01-24) on server2.sourceware.org X-BeenThere: libc-alpha@sourceware.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Libc-alpha mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-Patchwork-Original-From: "H.J. Lu via Libc-alpha" From: "H.J. Lu" Reply-To: "H.J. Lu" Cc: libc-alpha@sourceware.org, Nick Clifton , Alan Modra Errors-To: libc-alpha-bounces+patchwork=sourceware.org@sourceware.org Sender: "Libc-alpha" Allow eabling and disabling DT_RELR in linker tests. Disable DT_RELR in linker tests which don't expect DT_RELR in linker outputs. binutils/ * testsuite/lib/binutils-common.exp (run_dump_test): Make DT_RELR_LDFLAGS and NO_DT_RELR_LDFLAGS global. ld/ * testsuite/config/default.exp (DT_RELR_LDFLAGS): New. (DT_RELR_CC_LDFLAGS): Likewise. (NO_DT_RELR_LDFLAGS): Likewise. (NO_DT_RELR_CC_LDFLAGS): Likewise. * testsuite/ld-elf/shared.exp: Pass $NO_DT_RELR_LDFLAGS to linker for some tests. * testsuite/ld-i386/export-class.exp: Likewise. * testsuite/ld-i386/i386.exp: Likewise. * testsuite/ld-i386/ibt-plt-2a.d: Pass $NO_DT_RELR_LDFLAGS to linker. * testsuite/ld-i386/ibt-plt-3a.d: Likewise. * testsuite/ld-i386/ibt-plt-3c.d: Likewise. * testsuite/ld-i386/report-reloc-1.d: Likewise. * testsuite/ld-ifunc/ifunc-2-i386-now.d: Likewise. * testsuite/ld-ifunc/ifunc-2-local-i386-now.d: Likewise. * testsuite/ld-ifunc/ifunc-2-local-x86-64-now.d: Likewise. * testsuite/ld-ifunc/ifunc-2-x86-64-now.d: Likewise. * testsuite/ld-ifunc/pr17154-x86-64.d: Likewise. * testsuite/ld-x86-64/bnd-branch-1-now.d: Likewise. * testsuite/ld-x86-64/bnd-ifunc-1-now.d: Likewise. * testsuite/ld-x86-64/bnd-ifunc-2-now.d: Likewise. * testsuite/ld-x86-64/bnd-ifunc-2.d: Likewise. * testsuite/ld-x86-64/bnd-plt-1-now.d: Likewise. * testsuite/ld-x86-64/bnd-plt-1.d: Likewise. * testsuite/ld-x86-64/ibt-plt-2a-x32.d: Likewise. * testsuite/ld-x86-64/ibt-plt-2a.d: Likewise. * testsuite/ld-x86-64/ibt-plt-3a-x32.d: Likewise. * testsuite/ld-x86-64/ibt-plt-3a.d: Likewise. * testsuite/ld-x86-64/ilp32-4.d: Likewise. * testsuite/ld-x86-64/load1c.d: Likewise. * testsuite/ld-x86-64/load1d.d: Likewise. * testsuite/ld-x86-64/pr13082-2b.d: Likewise. * testsuite/ld-x86-64/pr14207.d: Likewise. * testsuite/ld-x86-64/pr18176.d: Likewise. * testsuite/ld-x86-64/pr19162.d: Likewise. * testsuite/ld-x86-64/pr19636-2d.d: Likewise. * testsuite/ld-x86-64/pr19636-2l.d: Likewise. * testsuite/ld-x86-64/pr20253-1d.d: Likewise. * testsuite/ld-x86-64/pr20253-1f.d: Likewise. * testsuite/ld-x86-64/pr20253-1j.d: Likewise. * testsuite/ld-x86-64/pr20253-1l.d: Likewise. * testsuite/ld-x86-64/report-reloc-1-x32.d: Likewise. * testsuite/ld-x86-64/report-reloc-1.d: Likewise. * testsuite/ld-x86-64/export-class.exp (x86_64_export_class_test): Pass $NO_DT_RELR_LDFLAGS to linker. * testsuite/ld-x86-64/x86-64.exp: Pass $NO_DT_RELR_LDFLAGS to linker for some tests. --- binutils/testsuite/lib/binutils-common.exp | 1 + ld/testsuite/config/default.exp | 16 +++++ ld/testsuite/ld-elf/shared.exp | 3 +- ld/testsuite/ld-i386/export-class.exp | 2 +- ld/testsuite/ld-i386/i386.exp | 20 ++++-- ld/testsuite/ld-i386/ibt-plt-2a.d | 2 +- ld/testsuite/ld-i386/ibt-plt-3a.d | 2 +- ld/testsuite/ld-i386/ibt-plt-3c.d | 2 +- ld/testsuite/ld-i386/report-reloc-1.d | 2 +- ld/testsuite/ld-ifunc/ifunc-2-i386-now.d | 2 +- .../ld-ifunc/ifunc-2-local-i386-now.d | 2 +- .../ld-ifunc/ifunc-2-local-x86-64-now.d | 2 +- ld/testsuite/ld-ifunc/ifunc-2-x86-64-now.d | 2 +- ld/testsuite/ld-ifunc/pr17154-x86-64-now.d | 2 +- ld/testsuite/ld-ifunc/pr17154-x86-64.d | 2 +- ld/testsuite/ld-x86-64/bnd-branch-1-now.d | 2 +- ld/testsuite/ld-x86-64/bnd-ifunc-1-now.d | 2 +- ld/testsuite/ld-x86-64/bnd-ifunc-2-now.d | 2 +- ld/testsuite/ld-x86-64/bnd-ifunc-2.d | 2 +- ld/testsuite/ld-x86-64/bnd-plt-1-now.d | 2 +- ld/testsuite/ld-x86-64/bnd-plt-1.d | 2 +- ld/testsuite/ld-x86-64/export-class.exp | 3 +- ld/testsuite/ld-x86-64/ibt-plt-2a-x32.d | 2 +- ld/testsuite/ld-x86-64/ibt-plt-2a.d | 2 +- ld/testsuite/ld-x86-64/ibt-plt-3a-x32.d | 2 +- ld/testsuite/ld-x86-64/ibt-plt-3a.d | 2 +- ld/testsuite/ld-x86-64/ilp32-4.d | 2 +- ld/testsuite/ld-x86-64/load1c.d | 2 +- ld/testsuite/ld-x86-64/load1d.d | 2 +- ld/testsuite/ld-x86-64/pr13082-2b.d | 2 +- ld/testsuite/ld-x86-64/pr14207.d | 2 +- ld/testsuite/ld-x86-64/pr18176.d | 2 +- ld/testsuite/ld-x86-64/pr19162.d | 2 +- ld/testsuite/ld-x86-64/pr19636-2d.d | 2 +- ld/testsuite/ld-x86-64/pr19636-2l.d | 2 +- ld/testsuite/ld-x86-64/pr20253-1d.d | 2 +- ld/testsuite/ld-x86-64/pr20253-1f.d | 2 +- ld/testsuite/ld-x86-64/pr20253-1j.d | 2 +- ld/testsuite/ld-x86-64/pr20253-1l.d | 2 +- ld/testsuite/ld-x86-64/report-reloc-1-x32.d | 2 +- ld/testsuite/ld-x86-64/report-reloc-1.d | 2 +- ld/testsuite/ld-x86-64/x86-64.exp | 65 ++++++++++++------- 42 files changed, 114 insertions(+), 66 deletions(-) diff --git a/binutils/testsuite/lib/binutils-common.exp b/binutils/testsuite/lib/binutils-common.exp index 0e0ba8e5aee..88fdc1a71c7 100644 --- a/binutils/testsuite/lib/binutils-common.exp +++ b/binutils/testsuite/lib/binutils-common.exp @@ -855,6 +855,7 @@ proc run_dump_test { name {extra_options {}} } { global ELFEDIT ELFEDITFLAGS LD LDFLAGS NM NMFLAGS OBJCOPY OBJCOPYFLAGS global OBJDUMP OBJDUMPFLAGS READELF READELFFLAGS STRIP STRIPFLAGS global copyfile env runtests srcdir subdir verbose + global DT_RELR_LDFLAGS NO_DT_RELR_LDFLAGS if [string match "*/*" $name] { set file $name diff --git a/ld/testsuite/config/default.exp b/ld/testsuite/config/default.exp index c988d5d2924..52e75048ede 100644 --- a/ld/testsuite/config/default.exp +++ b/ld/testsuite/config/default.exp @@ -313,6 +313,22 @@ if ![info exists LDFLAGS] then { set LDFLAGS {} } +if { ![info exists DT_RELR_LDFLAGS] } then { + set DT_RELR_LDFLAGS "-z pack-relative-relocs" +} + +if { ![info exists DT_RELR_CC_LDFLAGS] } then { + set DT_RELR_CC_LDFLAGS "-Wl,-z,pack-relative-relocs" +} + +if { ![info exists NO_DT_RELR_LDFLAGS] } then { + set NO_DT_RELR_LDFLAGS "-z nopack-relative-relocs" +} + +if { ![info exists NO_DT_RELR_CC_LDFLAGS] } then { + set NO_DT_RELR_CC_LDFLAGS "-Wl,-z,nopack-relative-relocs" +} + # Set LD_CLASS to "64bit" for a 64-bit *host* linker. if { ![info exists LD_CLASS] } then { set REAL_LD [findfile $base_dir/.libs/ld-new .libs/ld-new $LD [transform ld]] diff --git a/ld/testsuite/ld-elf/shared.exp b/ld/testsuite/ld-elf/shared.exp index cb3b8c15cfc..1381544e6f8 100644 --- a/ld/testsuite/ld-elf/shared.exp +++ b/ld/testsuite/ld-elf/shared.exp @@ -452,7 +452,8 @@ setup_xfail mips*-*-* bfin-*-* clear_xfail bfin-*-linux* run_ld_link_tests [list \ [list "-Bsymbolic-functions" \ - "-shared -Bsymbolic-functions" "" "$AFLAGS_PIC" \ + "-shared -Bsymbolic-functions $NO_DT_RELR_LDFLAGS" \ + "" "$AFLAGS_PIC" \ {symbolic-func.s} {{readelf {-r --wide} symbolic-func.r}} \ "symbolic-func.so"] \ ] diff --git a/ld/testsuite/ld-i386/export-class.exp b/ld/testsuite/ld-i386/export-class.exp index 47b2c0f0056..04bc6a0d836 100644 --- a/ld/testsuite/ld-i386/export-class.exp +++ b/ld/testsuite/ld-i386/export-class.exp @@ -74,7 +74,7 @@ run_ld_link_tests [list \ run_ld_link_tests [list \ [list \ "$testname (final shared object)" \ - "-shared -Tdata=0x12340000 tmpdir/i386-export-class-ref-r.o tmpdir/i386-export-class-lib.so" "" \ + "-shared $NO_DT_RELR_LDFLAGS -Tdata=0x12340000 tmpdir/i386-export-class-ref-r.o tmpdir/i386-export-class-lib.so" "" \ "" \ { ../ld-elf/export-class-dep.s ../ld-elf/export-class-def.s } \ { \ diff --git a/ld/testsuite/ld-i386/i386.exp b/ld/testsuite/ld-i386/i386.exp index 3ed6e42e78f..c2d8d8268c3 100644 --- a/ld/testsuite/ld-i386/i386.exp +++ b/ld/testsuite/ld-i386/i386.exp @@ -177,12 +177,6 @@ set i386tests { {{readelf -Ssrl tlsbindesc.rd} {objdump -drj.text tlsbindesc.dd} {objdump -sj.got tlsbindesc.sd} {objdump -sj.tdata tlsbindesc.td}} "tlsbindesc"} - {"TLS -fno-pic -shared" - "-shared -melf_i386 --no-ld-generated-unwind-info -z notext \ - -z noseparate-code --hash-style=sysv" "" - "--32" {tlsnopic1.s tlsnopic2.s} - {{readelf -Ssrl tlsnopic.rd} {objdump -drj.text tlsnopic.dd} - {objdump -sj.got tlsnopic.sd}} "libtlsnopic.so"} {"TLS with global dynamic and descriptors" "-shared -melf_i386 --no-ld-generated-unwind-info \ -z noseparate-code --hash-style=sysv" "" @@ -293,6 +287,20 @@ iamcu_tests run_ld_link_tests $i386tests +run_ld_link_tests [list \ + [list \ + "TLS -fno-pic -shared" \ + "-shared -melf_i386 --no-ld-generated-unwind-info -z notext \ + -z noseparate-code --hash-style=sysv $NO_DT_RELR_LDFLAGS" \ + "" "--32" \ + {tlsnopic1.s tlsnopic2.s} \ + {{readelf -Ssrl tlsnopic.rd} \ + {objdump -drj.text tlsnopic.dd} \ + {objdump -sj.got tlsnopic.sd}} \ + "libtlsnopic.so" \ + ] \ +] + run_dump_test "abs" run_dump_test "pcrel8" run_dump_test "pcrel16" diff --git a/ld/testsuite/ld-i386/ibt-plt-2a.d b/ld/testsuite/ld-i386/ibt-plt-2a.d index 42aa2ce7410..98b6fb9a5aa 100644 --- a/ld/testsuite/ld-i386/ibt-plt-2a.d +++ b/ld/testsuite/ld-i386/ibt-plt-2a.d @@ -1,6 +1,6 @@ #source: ibt-plt-2.s #as: --32 -#ld: -shared -m elf_i386 -z ibtplt --hash-style=sysv -z noseparate-code +#ld: -shared -m elf_i386 -z ibtplt --hash-style=sysv -z noseparate-code $NO_DT_RELR_LDFLAGS #objdump: -dw .*: +file format .* diff --git a/ld/testsuite/ld-i386/ibt-plt-3a.d b/ld/testsuite/ld-i386/ibt-plt-3a.d index b357a74a33b..91f2023db35 100644 --- a/ld/testsuite/ld-i386/ibt-plt-3a.d +++ b/ld/testsuite/ld-i386/ibt-plt-3a.d @@ -1,6 +1,6 @@ #source: ibt-plt-3.s #as: --32 -#ld: -shared -m elf_i386 -z ibtplt --hash-style=sysv -z noseparate-code +#ld: -shared -m elf_i386 -z ibtplt --hash-style=sysv -z noseparate-code $NO_DT_RELR_LDFLAGS #objdump: -dw .*: +file format .* diff --git a/ld/testsuite/ld-i386/ibt-plt-3c.d b/ld/testsuite/ld-i386/ibt-plt-3c.d index b357a74a33b..91f2023db35 100644 --- a/ld/testsuite/ld-i386/ibt-plt-3c.d +++ b/ld/testsuite/ld-i386/ibt-plt-3c.d @@ -1,6 +1,6 @@ #source: ibt-plt-3.s #as: --32 -#ld: -shared -m elf_i386 -z ibtplt --hash-style=sysv -z noseparate-code +#ld: -shared -m elf_i386 -z ibtplt --hash-style=sysv -z noseparate-code $NO_DT_RELR_LDFLAGS #objdump: -dw .*: +file format .* diff --git a/ld/testsuite/ld-i386/report-reloc-1.d b/ld/testsuite/ld-i386/report-reloc-1.d index 51fbbd8d105..162161592a1 100644 --- a/ld/testsuite/ld-i386/report-reloc-1.d +++ b/ld/testsuite/ld-i386/report-reloc-1.d @@ -1,6 +1,6 @@ #source: report-reloc-1.s #as: --32 -#ld: -pie -melf_i386 -z report-relative-reloc +#ld: -pie -melf_i386 -z report-relative-reloc $NO_DT_RELR_LDFLAGS #warning_output: report-reloc-1.l #readelf: -r --wide diff --git a/ld/testsuite/ld-ifunc/ifunc-2-i386-now.d b/ld/testsuite/ld-ifunc/ifunc-2-i386-now.d index 0d3f7b80d06..aae24b2809d 100644 --- a/ld/testsuite/ld-ifunc/ifunc-2-i386-now.d +++ b/ld/testsuite/ld-ifunc/ifunc-2-i386-now.d @@ -1,5 +1,5 @@ #source: ifunc-2-i386.s -#ld: -z now -m elf_i386 -shared --hash-style=sysv -z noseparate-code +#ld: -z now -m elf_i386 -shared --hash-style=sysv -z noseparate-code $NO_DT_RELR_LDFLAGS #as: --32 #objdump: -dw #target: x86_64-*-* i?86-*-* diff --git a/ld/testsuite/ld-ifunc/ifunc-2-local-i386-now.d b/ld/testsuite/ld-ifunc/ifunc-2-local-i386-now.d index 48d2084d38f..86083c12a08 100644 --- a/ld/testsuite/ld-ifunc/ifunc-2-local-i386-now.d +++ b/ld/testsuite/ld-ifunc/ifunc-2-local-i386-now.d @@ -1,5 +1,5 @@ #source: ifunc-2-local-i386.s -#ld: -z now -m elf_i386 -shared --hash-style=sysv -z noseparate-code +#ld: -z now -m elf_i386 -shared --hash-style=sysv -z noseparate-code $NO_DT_RELR_LDFLAGS #as: --32 #objdump: -dw #target: x86_64-*-* i?86-*-* diff --git a/ld/testsuite/ld-ifunc/ifunc-2-local-x86-64-now.d b/ld/testsuite/ld-ifunc/ifunc-2-local-x86-64-now.d index 14866a8f6cc..be3da08e12b 100644 --- a/ld/testsuite/ld-ifunc/ifunc-2-local-x86-64-now.d +++ b/ld/testsuite/ld-ifunc/ifunc-2-local-x86-64-now.d @@ -1,6 +1,6 @@ #source: ifunc-2-local-x86-64.s #as: --64 -#ld: -z now -shared -melf_x86_64 --hash-style=sysv -z max-page-size=0x200000 -z noseparate-code +#ld: -z now -shared -melf_x86_64 --hash-style=sysv -z max-page-size=0x200000 -z noseparate-code $NO_DT_RELR_LDFLAGS #objdump: -dw #target: x86_64-*-* diff --git a/ld/testsuite/ld-ifunc/ifunc-2-x86-64-now.d b/ld/testsuite/ld-ifunc/ifunc-2-x86-64-now.d index 1cd60941ac0..b504f9adedd 100644 --- a/ld/testsuite/ld-ifunc/ifunc-2-x86-64-now.d +++ b/ld/testsuite/ld-ifunc/ifunc-2-x86-64-now.d @@ -1,6 +1,6 @@ #source: ifunc-2-x86-64.s #as: --64 -#ld: -z now -shared -melf_x86_64 --hash-style=sysv -z max-page-size=0x200000 -z noseparate-code +#ld: -z now -shared -melf_x86_64 --hash-style=sysv -z max-page-size=0x200000 -z noseparate-code $NO_DT_RELR_LDFLAGS #objdump: -dw #target: x86_64-*-* diff --git a/ld/testsuite/ld-ifunc/pr17154-x86-64-now.d b/ld/testsuite/ld-ifunc/pr17154-x86-64-now.d index 4cc1dc206d5..f6920272b63 100644 --- a/ld/testsuite/ld-ifunc/pr17154-x86-64-now.d +++ b/ld/testsuite/ld-ifunc/pr17154-x86-64-now.d @@ -1,6 +1,6 @@ #source: pr17154-x86.s #as: --64 -#ld: -z now -shared -melf_x86_64 --hash-style=sysv -z max-page-size=0x200000 -z noseparate-code +#ld: -z now -shared -melf_x86_64 --hash-style=sysv -z max-page-size=0x200000 -z noseparate-code $NO_DT_RELR_LDFLAGS #objdump: -dw #target: x86_64-*-* diff --git a/ld/testsuite/ld-ifunc/pr17154-x86-64.d b/ld/testsuite/ld-ifunc/pr17154-x86-64.d index 9fb23d410e3..90918426ee5 100644 --- a/ld/testsuite/ld-ifunc/pr17154-x86-64.d +++ b/ld/testsuite/ld-ifunc/pr17154-x86-64.d @@ -1,6 +1,6 @@ #source: pr17154-x86.s #as: --64 -#ld: -shared -melf_x86_64 --hash-style=sysv -z max-page-size=0x200000 -z noseparate-code +#ld: -shared -melf_x86_64 --hash-style=sysv -z max-page-size=0x200000 -z noseparate-code $NO_DT_RELR_LDFLAGS #objdump: -dw #target: x86_64-*-* diff --git a/ld/testsuite/ld-x86-64/bnd-branch-1-now.d b/ld/testsuite/ld-x86-64/bnd-branch-1-now.d index b7bc4e526cc..b1bcea3cf4c 100644 --- a/ld/testsuite/ld-x86-64/bnd-branch-1-now.d +++ b/ld/testsuite/ld-x86-64/bnd-branch-1-now.d @@ -1,6 +1,6 @@ #source: bnd-branch-1.s -mx86-used-note=no #as: --64 -#ld: -z now -shared -melf_x86_64 --hash-style=sysv -z max-page-size=0x200000 -z noseparate-code +#ld: -z now -shared -melf_x86_64 --hash-style=sysv -z max-page-size=0x200000 -z noseparate-code $NO_DT_RELR_LDFLAGS #objdump: -dw .*: +file format .* diff --git a/ld/testsuite/ld-x86-64/bnd-ifunc-1-now.d b/ld/testsuite/ld-x86-64/bnd-ifunc-1-now.d index 15ecfe1cc50..86ba30a46d5 100644 --- a/ld/testsuite/ld-x86-64/bnd-ifunc-1-now.d +++ b/ld/testsuite/ld-x86-64/bnd-ifunc-1-now.d @@ -1,6 +1,6 @@ #source: bnd-ifunc-1.s #as: --64 -madd-bnd-prefix -mx86-used-note=no -#ld: -z now -shared -melf_x86_64 -z bndplt --hash-style=sysv -z max-page-size=0x200000 -z noseparate-code +#ld: -z now -shared -melf_x86_64 -z bndplt --hash-style=sysv -z max-page-size=0x200000 -z noseparate-code $NO_DT_RELR_LDFLAGS #objdump: -dw .*: +file format .* diff --git a/ld/testsuite/ld-x86-64/bnd-ifunc-2-now.d b/ld/testsuite/ld-x86-64/bnd-ifunc-2-now.d index 211d72d2335..fa7ec07aaf0 100644 --- a/ld/testsuite/ld-x86-64/bnd-ifunc-2-now.d +++ b/ld/testsuite/ld-x86-64/bnd-ifunc-2-now.d @@ -1,6 +1,6 @@ #source: bnd-ifunc-2.s #as: --64 -madd-bnd-prefix -mx86-used-note=no -#ld: -z now -shared -melf_x86_64 -z bndplt --hash-style=sysv -z max-page-size=0x200000 -z noseparate-code +#ld: -z now -shared -melf_x86_64 -z bndplt --hash-style=sysv -z max-page-size=0x200000 -z noseparate-code $NO_DT_RELR_LDFLAGS #objdump: -dw .*: +file format .* diff --git a/ld/testsuite/ld-x86-64/bnd-ifunc-2.d b/ld/testsuite/ld-x86-64/bnd-ifunc-2.d index f80ba15aa35..36534b14feb 100644 --- a/ld/testsuite/ld-x86-64/bnd-ifunc-2.d +++ b/ld/testsuite/ld-x86-64/bnd-ifunc-2.d @@ -1,5 +1,5 @@ #as: --64 -madd-bnd-prefix -mx86-used-note=no -#ld: -shared -melf_x86_64 -z bndplt --hash-style=sysv -z max-page-size=0x200000 -z noseparate-code +#ld: -shared -melf_x86_64 -z bndplt --hash-style=sysv -z max-page-size=0x200000 -z noseparate-code $NO_DT_RELR_LDFLAGS #objdump: -dw #... diff --git a/ld/testsuite/ld-x86-64/bnd-plt-1-now.d b/ld/testsuite/ld-x86-64/bnd-plt-1-now.d index 24e28210a0a..47289a04f43 100644 --- a/ld/testsuite/ld-x86-64/bnd-plt-1-now.d +++ b/ld/testsuite/ld-x86-64/bnd-plt-1-now.d @@ -1,6 +1,6 @@ #source: bnd-branch-1.s #as: --64 -mx86-used-note=no -#ld: -z now -shared -melf_x86_64 -z bndplt --hash-style=sysv -z max-page-size=0x200000 -z noseparate-code +#ld: -z now -shared -melf_x86_64 -z bndplt --hash-style=sysv -z max-page-size=0x200000 -z noseparate-code $NO_DT_RELR_LDFLAGS #objdump: -dw .*: +file format .* diff --git a/ld/testsuite/ld-x86-64/bnd-plt-1.d b/ld/testsuite/ld-x86-64/bnd-plt-1.d index 0df32555c18..f047da897ce 100644 --- a/ld/testsuite/ld-x86-64/bnd-plt-1.d +++ b/ld/testsuite/ld-x86-64/bnd-plt-1.d @@ -1,6 +1,6 @@ #source: bnd-branch-1.s #as: --64 -mx86-used-note=no -#ld: -shared -melf_x86_64 -z bndplt --hash-style=sysv -z max-page-size=0x200000 -z noseparate-code +#ld: -shared -melf_x86_64 -z bndplt --hash-style=sysv -z max-page-size=0x200000 -z noseparate-code $NO_DT_RELR_LDFLAGS #objdump: -dw .*: +file format .* diff --git a/ld/testsuite/ld-x86-64/export-class.exp b/ld/testsuite/ld-x86-64/export-class.exp index 26896d1ca87..14c2d240fac 100644 --- a/ld/testsuite/ld-x86-64/export-class.exp +++ b/ld/testsuite/ld-x86-64/export-class.exp @@ -31,6 +31,7 @@ if { ![istarget x86_64*-*-linux*] } { } proc x86_64_export_class_test { abi flag emul } { + global NO_DT_RELR_LDFLAGS set testname "x86-64 $abi symbol export class test" @@ -75,7 +76,7 @@ proc x86_64_export_class_test { abi flag emul } { run_ld_link_tests [list \ [list \ "$testname (final shared object)" \ - "$LDFLAGS -shared -Tdata=0x12340000 tmpdir/x86-64-$abi-export-class-ref-r.o tmpdir/x86-64-$abi-export-class-lib.so" "" \ + "$LDFLAGS $NO_DT_RELR_LDFLAGS -shared -Tdata=0x12340000 tmpdir/x86-64-$abi-export-class-ref-r.o tmpdir/x86-64-$abi-export-class-lib.so" "" \ "$AFLAGS" \ { ../ld-elf/export-class-dep.s ../ld-elf/export-class-def.s } \ [list \ diff --git a/ld/testsuite/ld-x86-64/ibt-plt-2a-x32.d b/ld/testsuite/ld-x86-64/ibt-plt-2a-x32.d index a19cece98e8..23e31e62f55 100644 --- a/ld/testsuite/ld-x86-64/ibt-plt-2a-x32.d +++ b/ld/testsuite/ld-x86-64/ibt-plt-2a-x32.d @@ -1,6 +1,6 @@ #source: ibt-plt-2.s #as: --x32 -#ld: -shared -m elf32_x86_64 -z ibtplt --hash-style=sysv -z max-page-size=0x200000 -z noseparate-code +#ld: -shared -m elf32_x86_64 -z ibtplt --hash-style=sysv -z max-page-size=0x200000 -z noseparate-code $NO_DT_RELR_LDFLAGS #objdump: -dw .*: +file format .* diff --git a/ld/testsuite/ld-x86-64/ibt-plt-2a.d b/ld/testsuite/ld-x86-64/ibt-plt-2a.d index 92785929092..adbbf62e84d 100644 --- a/ld/testsuite/ld-x86-64/ibt-plt-2a.d +++ b/ld/testsuite/ld-x86-64/ibt-plt-2a.d @@ -1,6 +1,6 @@ #source: ibt-plt-2.s #as: --64 -defsym __64_bit__=1 -#ld: -shared -m elf_x86_64 -z ibtplt --hash-style=sysv -z max-page-size=0x200000 -z noseparate-code +#ld: -shared -m elf_x86_64 -z ibtplt --hash-style=sysv -z max-page-size=0x200000 -z noseparate-code $NO_DT_RELR_LDFLAGS #objdump: -dw .*: +file format .* diff --git a/ld/testsuite/ld-x86-64/ibt-plt-3a-x32.d b/ld/testsuite/ld-x86-64/ibt-plt-3a-x32.d index d6f8bb3afbe..f52b1cc796f 100644 --- a/ld/testsuite/ld-x86-64/ibt-plt-3a-x32.d +++ b/ld/testsuite/ld-x86-64/ibt-plt-3a-x32.d @@ -1,6 +1,6 @@ #source: ibt-plt-3.s #as: --x32 -#ld: -shared -m elf32_x86_64 -z ibtplt --hash-style=sysv -z max-page-size=0x200000 -z noseparate-code +#ld: -shared -m elf32_x86_64 -z ibtplt --hash-style=sysv -z max-page-size=0x200000 -z noseparate-code $NO_DT_RELR_LDFLAGS #objdump: -dw .*: +file format .* diff --git a/ld/testsuite/ld-x86-64/ibt-plt-3a.d b/ld/testsuite/ld-x86-64/ibt-plt-3a.d index 9c15ed4f928..8bd8851ea73 100644 --- a/ld/testsuite/ld-x86-64/ibt-plt-3a.d +++ b/ld/testsuite/ld-x86-64/ibt-plt-3a.d @@ -1,6 +1,6 @@ #source: ibt-plt-3.s #as: --64 -defsym __64_bit__=1 -#ld: -shared -m elf_x86_64 -z ibtplt --hash-style=sysv -z max-page-size=0x200000 -z noseparate-code +#ld: -shared -m elf_x86_64 -z ibtplt --hash-style=sysv -z max-page-size=0x200000 -z noseparate-code $NO_DT_RELR_LDFLAGS #objdump: -dw .*: +file format .* diff --git a/ld/testsuite/ld-x86-64/ilp32-4.d b/ld/testsuite/ld-x86-64/ilp32-4.d index 34be012056e..ad5c9cdf858 100644 --- a/ld/testsuite/ld-x86-64/ilp32-4.d +++ b/ld/testsuite/ld-x86-64/ilp32-4.d @@ -1,5 +1,5 @@ #as: --x32 -#ld: -m elf32_x86_64 -shared --no-ld-generated-unwind-info --hash-style=sysv +#ld: -m elf32_x86_64 -shared --no-ld-generated-unwind-info --hash-style=sysv $NO_DT_RELR_LDFLAGS #readelf: -d -S --wide #target: x86_64-*-linux* diff --git a/ld/testsuite/ld-x86-64/load1c.d b/ld/testsuite/ld-x86-64/load1c.d index db9c69fadbf..7404c7093b4 100644 --- a/ld/testsuite/ld-x86-64/load1c.d +++ b/ld/testsuite/ld-x86-64/load1c.d @@ -1,6 +1,6 @@ #source: load1.s #as: --64 -#ld: -shared -melf_x86_64 --hash-style=sysv -z max-page-size=0x200000 -z noseparate-code +#ld: -shared -melf_x86_64 --hash-style=sysv -z max-page-size=0x200000 -z noseparate-code $NO_DT_RELR_LDFLAGS #objdump: -dw .*: +file format .* diff --git a/ld/testsuite/ld-x86-64/load1d.d b/ld/testsuite/ld-x86-64/load1d.d index 7ccae532f27..1b474a375c7 100644 --- a/ld/testsuite/ld-x86-64/load1d.d +++ b/ld/testsuite/ld-x86-64/load1d.d @@ -1,6 +1,6 @@ #source: load1.s #as: --x32 -#ld: -shared -melf32_x86_64 --hash-style=sysv -z max-page-size=0x200000 -z noseparate-code +#ld: -shared -melf32_x86_64 --hash-style=sysv -z max-page-size=0x200000 -z noseparate-code $NO_DT_RELR_LDFLAGS #objdump: -dw .*: +file format .* diff --git a/ld/testsuite/ld-x86-64/pr13082-2b.d b/ld/testsuite/ld-x86-64/pr13082-2b.d index c218eafe34c..71c44fc0ee5 100644 --- a/ld/testsuite/ld-x86-64/pr13082-2b.d +++ b/ld/testsuite/ld-x86-64/pr13082-2b.d @@ -1,7 +1,7 @@ #source: pr13082-2.s #name: PR ld/13082-2 (b) #as: --x32 -#ld: -pie -melf32_x86_64 +#ld: -pie -melf32_x86_64 $NO_DT_RELR_LDFLAGS #readelf: -r --wide Relocation section '.rela.dyn' at offset 0x[0-9a-f]+ contains 1 entry: diff --git a/ld/testsuite/ld-x86-64/pr14207.d b/ld/testsuite/ld-x86-64/pr14207.d index f330600b916..e3af36146c6 100644 --- a/ld/testsuite/ld-x86-64/pr14207.d +++ b/ld/testsuite/ld-x86-64/pr14207.d @@ -1,6 +1,6 @@ #name: PR ld/14207 #as: --64 -#ld: -melf_x86_64 -shared -z relro -z now --hash-style=sysv -z max-page-size=0x200000 -z noseparate-code +#ld: -melf_x86_64 -shared -z relro -z now --hash-style=sysv -z max-page-size=0x200000 -z noseparate-code $NO_DT_RELR_LDFLAGS #readelf: -l --wide #target: x86_64-*-linux* diff --git a/ld/testsuite/ld-x86-64/pr18176.d b/ld/testsuite/ld-x86-64/pr18176.d index 4e3ad9ff08d..a99ff15ac6b 100644 --- a/ld/testsuite/ld-x86-64/pr18176.d +++ b/ld/testsuite/ld-x86-64/pr18176.d @@ -1,6 +1,6 @@ #name: PR ld/18176 #as: --64 -#ld: -melf_x86_64 -shared -z relro -T pr18176.t -z max-page-size=0x200000 -z common-page-size=0x1000 +#ld: -melf_x86_64 -shared -z relro -T pr18176.t -z max-page-size=0x200000 -z common-page-size=0x1000 $NO_DT_RELR_LDFLAGS #readelf: -l --wide #target: x86_64-*-linux* diff --git a/ld/testsuite/ld-x86-64/pr19162.d b/ld/testsuite/ld-x86-64/pr19162.d index 2d51dabe729..f458853d8e5 100644 --- a/ld/testsuite/ld-x86-64/pr19162.d +++ b/ld/testsuite/ld-x86-64/pr19162.d @@ -1,7 +1,7 @@ #source: pr19162a.s #source: pr19162b.s #as: --64 -#ld: -melf_x86_64 -shared -z noseparate-code -z max-page-size=0x200000 -z common-page-size=0x1000 --hash-style=sysv +#ld: -melf_x86_64 -shared -z noseparate-code -z max-page-size=0x200000 -z common-page-size=0x1000 --hash-style=sysv $NO_DT_RELR_LDFLAGS #readelf: -l --wide #target: x86_64-*-linux* diff --git a/ld/testsuite/ld-x86-64/pr19636-2d.d b/ld/testsuite/ld-x86-64/pr19636-2d.d index 3bd33a9a915..092992be9d4 100644 --- a/ld/testsuite/ld-x86-64/pr19636-2d.d +++ b/ld/testsuite/ld-x86-64/pr19636-2d.d @@ -1,6 +1,6 @@ #source: pr19636-2.s #as: --64 -mrelax-relocations=no -#ld: -pie -m elf_x86_64 --no-dynamic-linker --hash-style=sysv -z max-page-size=0x200000 -z noseparate-code +#ld: -pie -m elf_x86_64 --no-dynamic-linker --hash-style=sysv -z max-page-size=0x200000 -z noseparate-code $NO_DT_RELR_LDFLAGS #objdump: -dw .*: +file format .* diff --git a/ld/testsuite/ld-x86-64/pr19636-2l.d b/ld/testsuite/ld-x86-64/pr19636-2l.d index 1b894b3e97c..8c23c0b7411 100644 --- a/ld/testsuite/ld-x86-64/pr19636-2l.d +++ b/ld/testsuite/ld-x86-64/pr19636-2l.d @@ -1,6 +1,6 @@ #source: pr19636-2.s #as: --64 -mrelax-relocations=no -#ld: -pie -m elf_x86_64 --no-dynamic-linker --hash-style=sysv -z dynamic-undefined-weak -z max-page-size=0x200000 -z noseparate-code +#ld: -pie -m elf_x86_64 --no-dynamic-linker --hash-style=sysv -z dynamic-undefined-weak -z max-page-size=0x200000 -z noseparate-code $NO_DT_RELR_LDFLAGS #objdump: -dw #warning: -z dynamic-undefined-weak ignored diff --git a/ld/testsuite/ld-x86-64/pr20253-1d.d b/ld/testsuite/ld-x86-64/pr20253-1d.d index f9f03ba8403..057577bdc57 100644 --- a/ld/testsuite/ld-x86-64/pr20253-1d.d +++ b/ld/testsuite/ld-x86-64/pr20253-1d.d @@ -1,6 +1,6 @@ #source: pr20253-1.s #as: --64 -#ld: -pie -melf_x86_64 --hash-style=sysv -z max-page-size=0x200000 -z noseparate-code +#ld: -pie -melf_x86_64 --hash-style=sysv -z max-page-size=0x200000 -z noseparate-code $NO_DT_RELR_LDFLAGS #objdump: -dw .*: +file format .* diff --git a/ld/testsuite/ld-x86-64/pr20253-1f.d b/ld/testsuite/ld-x86-64/pr20253-1f.d index 6666bcaf147..479db8202e8 100644 --- a/ld/testsuite/ld-x86-64/pr20253-1f.d +++ b/ld/testsuite/ld-x86-64/pr20253-1f.d @@ -1,6 +1,6 @@ #source: pr20253-1.s #as: --64 -#ld: -shared -melf_x86_64 --hash-style=sysv -z max-page-size=0x200000 -z noseparate-code +#ld: -shared -melf_x86_64 --hash-style=sysv -z max-page-size=0x200000 -z noseparate-code $NO_DT_RELR_LDFLAGS #objdump: -dw .*: +file format .* diff --git a/ld/testsuite/ld-x86-64/pr20253-1j.d b/ld/testsuite/ld-x86-64/pr20253-1j.d index 88c9715ad75..20176a2d357 100644 --- a/ld/testsuite/ld-x86-64/pr20253-1j.d +++ b/ld/testsuite/ld-x86-64/pr20253-1j.d @@ -1,6 +1,6 @@ #source: pr20253-1.s #as: --x32 -#ld: -pie -melf32_x86_64 --hash-style=sysv -z max-page-size=0x200000 -z noseparate-code +#ld: -pie -melf32_x86_64 --hash-style=sysv -z max-page-size=0x200000 -z noseparate-code $NO_DT_RELR_LDFLAGS #objdump: -dw .*: +file format .* diff --git a/ld/testsuite/ld-x86-64/pr20253-1l.d b/ld/testsuite/ld-x86-64/pr20253-1l.d index 7428a721b16..4b179077dec 100644 --- a/ld/testsuite/ld-x86-64/pr20253-1l.d +++ b/ld/testsuite/ld-x86-64/pr20253-1l.d @@ -1,6 +1,6 @@ #source: pr20253-1.s #as: --x32 -#ld: -shared -melf32_x86_64 --hash-style=sysv -z max-page-size=0x200000 -z noseparate-code +#ld: -shared -melf32_x86_64 --hash-style=sysv -z max-page-size=0x200000 -z noseparate-code $NO_DT_RELR_LDFLAGS #objdump: -dw .*: +file format .* diff --git a/ld/testsuite/ld-x86-64/report-reloc-1-x32.d b/ld/testsuite/ld-x86-64/report-reloc-1-x32.d index c66f956c473..63fe7b1bb8a 100644 --- a/ld/testsuite/ld-x86-64/report-reloc-1-x32.d +++ b/ld/testsuite/ld-x86-64/report-reloc-1-x32.d @@ -1,6 +1,6 @@ #source: report-reloc-1.s #as: --x32 -#ld: -pie -melf32_x86_64 -z report-relative-reloc +#ld: -pie -melf32_x86_64 -z report-relative-reloc $NO_DT_RELR_LDFLAGS #warning_output: report-reloc-1.l #readelf: -r --wide diff --git a/ld/testsuite/ld-x86-64/report-reloc-1.d b/ld/testsuite/ld-x86-64/report-reloc-1.d index 1b5f91fdd3f..69f164c9434 100644 --- a/ld/testsuite/ld-x86-64/report-reloc-1.d +++ b/ld/testsuite/ld-x86-64/report-reloc-1.d @@ -1,6 +1,6 @@ #source: report-reloc-1.s #as: --64 -#ld: -pie -melf_x86_64 -z report-relative-reloc +#ld: -pie -melf_x86_64 -z report-relative-reloc $NO_DT_RELR_LDFLAGS #warning_output: report-reloc-1.l #readelf: -r --wide diff --git a/ld/testsuite/ld-x86-64/x86-64.exp b/ld/testsuite/ld-x86-64/x86-64.exp index c100879397e..b4048128057 100644 --- a/ld/testsuite/ld-x86-64/x86-64.exp +++ b/ld/testsuite/ld-x86-64/x86-64.exp @@ -45,28 +45,6 @@ set x86_64tests { {"basic PLT generation" "-melf_x86_64 tmpdir/libpltlib.so" "" "--64" {plt.s} {{objdump -drj.plt plt.pd}} "plt"} - {"TLS -fpic -shared transitions" - "-shared -melf_x86_64 --no-ld-generated-unwind-info \ - -z noseparate-code -z max-page-size=0x200000 --hash-style=sysv" "" - "--64" {tlspic1.s tlspic2.s} - {{readelf -WSsrl tlspic.rd} {objdump -drj.text\ -Mintel64 tlspic.dd} - {objdump -sj.got tlspic.sd} {objdump -sj.tdata tlspic.td}} - "libtlspic.so"} - {"TLS -fpic -shared transitions with r15 as GOT base" - "-shared -melf_x86_64 --no-ld-generated-unwind-info \ - -z noseparate-code -z max-page-size=0x200000 --hash-style=sysv" "" - "--64 -mrelax-relocations=yes" - {tlspic3.s tlspic2.s} - {{readelf -WSsrl tlspic2.rd} {objdump -drj.text\ -Mintel64 tlspic2.dd} - {objdump -sj.got tlspic2.sd} {objdump -sj.tdata tlspic2.td}} - "libtlspic2.so"} - {"TLS descriptor -fpic -shared transitions" - "-shared -melf_x86_64 --no-ld-generated-unwind-info \ - -z noseparate-code -z max-page-size=0x200000 --hash-style=sysv" "" - "--64" {tlsdesc.s tlspic2.s} - {{readelf -WSsrld tlsdesc.rd} {objdump -drj.text tlsdesc.dd} - {objdump "-s -j.got -j.got.plt" tlsdesc.sd} {objdump -sj.tdata tlsdesc.td} - {objdump -drj.plt tlsdesc.pd}} "libtlsdesc.so"} {"Helper shared library" "-shared -melf_x86_64" "" "--64" {tlslib.s} {} "libtlslib.so"} {"TLS -fpic and -fno-pic exec transitions" @@ -240,6 +218,49 @@ set x86_64tests { run_ld_link_tests $x86_64tests +run_ld_link_tests [list \ + [list \ + "TLS -fpic -shared transitions" \ + "-shared -melf_x86_64 --no-ld-generated-unwind-info \ + -z noseparate-code -z max-page-size=0x200000 --hash-style=sysv \ + $NO_DT_RELR_LDFLAGS" \ + "" "--64" \ + {tlspic1.s tlspic2.s} \ + {{readelf -WSsrl tlspic.rd} \ + {objdump {-drj.text -Mintel64} tlspic.dd} \ + {objdump -sj.got tlspic.sd} \ + {objdump -sj.tdata tlspic.td}} \ + "libtlspic.so" \ + ] \ + [list \ + "TLS -fpic -shared transitions with r15 as GOT base" \ + "-shared -melf_x86_64 --no-ld-generated-unwind-info \ + -z noseparate-code -z max-page-size=0x200000 --hash-style=sysv \ + $NO_DT_RELR_LDFLAGS" \ + "" "--64 -mrelax-relocations=yes" \ + {tlspic3.s tlspic2.s} \ + {{readelf -WSsrl tlspic2.rd} \ + {objdump {-drj.text -Mintel64} tlspic2.dd} \ + {objdump -sj.got tlspic2.sd} \ + {objdump -sj.tdata tlspic2.td}} \ + "libtlspic2.so" \ + ] \ + [list \ + "TLS descriptor -fpic -shared transitions" \ + "-shared -melf_x86_64 --no-ld-generated-unwind-info \ + -z noseparate-code -z max-page-size=0x200000 --hash-style=sysv \ + $NO_DT_RELR_LDFLAGS" \ + "" "--64" \ + {tlsdesc.s tlspic2.s} \ + {{readelf -WSsrld tlsdesc.rd} \ + {objdump -drj.text tlsdesc.dd} \ + {objdump {-s -j.got -j.got.plt} tlsdesc.sd} \ + {objdump -sj.tdata tlsdesc.td} \ + {objdump -drj.plt tlsdesc.pd}} \ + "libtlsdesc.so" \ + ] \ +] + set test_name "Mixed x86_64 and i386 input test 1" set test mixed1 if { ![ld_link $ld tmpdir/$test "-m$emul tmpdir/${test}a.o tmpdir/${test}b.o"] } { From patchwork Fri Jan 7 19:06:29 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "H.J. Lu" X-Patchwork-Id: 49733 Return-Path: X-Original-To: patchwork@sourceware.org Delivered-To: patchwork@sourceware.org Received: from server2.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id 70F0A3857C65 for ; Fri, 7 Jan 2022 19:24:55 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 70F0A3857C65 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=sourceware.org; s=default; t=1641583495; bh=cD6GEHMA/Xg4/UbDhoy6ZaJQxYjMNDM4iynTNnQoBnk=; h=To:Subject:Date:In-Reply-To:References:List-Id:List-Unsubscribe: List-Archive:List-Post:List-Help:List-Subscribe:From:Reply-To:Cc: From; b=n0cy52VQW9heHHR4ENcz8oAywAfSaDrLwBVllaVu37EYiFVPBjKjIRcwh5v1o6vxq EGhrcPGxe+VQBK3561/wefUJdlCpP3hM4Co2aoaKtUemz+YNiScxhxZI0jx+N3qhv8 rboinOnpqS/dG2Jah+3h5F01iEA9iSbZw9wFO/Jc= X-Original-To: libc-alpha@sourceware.org Delivered-To: libc-alpha@sourceware.org Received: from mail-pf1-x42c.google.com (mail-pf1-x42c.google.com [IPv6:2607:f8b0:4864:20::42c]) by sourceware.org (Postfix) with ESMTPS id 3A95C3857C4D; Fri, 7 Jan 2022 19:06:38 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.1 sourceware.org 3A95C3857C4D Received: by mail-pf1-x42c.google.com with SMTP id q3so5898291pfs.7; Fri, 07 Jan 2022 11:06:38 -0800 (PST) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=cD6GEHMA/Xg4/UbDhoy6ZaJQxYjMNDM4iynTNnQoBnk=; b=HIsxP/faaZrGIXeFdm2in1mH5U2xud2JzPXKRp37VRlusqsZbcycKJUKsSI3sEIhS3 iLPVPVlRhObELfcuLVsMYx6iPrgiHuMOA4H7qiQZZbkt9id/QAhWPj//wNt29pfNTkf2 lrKj+E/kmcF+F5dNT6YrWHO3jIkMhbXeBCRAuPbo4YmPIzgkieO9/gNixbDQ7v6f59wU zQp+sCtv7KNk0yQjOHw7g9JVGFwooumx1htoyFC4QVBy+Qxomip7FK5xidtyoLu6HtqM zWgT2mofQgpCrBsmtrJHNLDiw7d4s+eSVGgoFxNVQ7xl1p076a7UQ7dVSxp4vDZgAyUQ 6xbg== X-Gm-Message-State: AOAM530LcHhvJhHdJxy41isO2QZZAhgGylbXK95ZpMZPmDp2AiWLdsNw NoB2VBE8stKK4idhUzdaggU= X-Google-Smtp-Source: ABdhPJzdQ9emp+ZqSF67M/gfaJXZXXot/IEyFnwSj09G5MhSoSNIhehwDCUP9nm7YptXhSEX1cucsQ== X-Received: by 2002:a63:575c:: with SMTP id h28mr56819897pgm.171.1641582396593; Fri, 07 Jan 2022 11:06:36 -0800 (PST) Received: from gnu-tgl-3.localdomain ([172.58.35.133]) by smtp.gmail.com with ESMTPSA id y18sm5871368pfn.202.2022.01.07.11.06.34 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 07 Jan 2022 11:06:35 -0800 (PST) Received: from gnu-tgl-3.. (localhost [IPv6:::1]) by gnu-tgl-3.localdomain (Postfix) with ESMTP id 42362C0EE1; Fri, 7 Jan 2022 11:06:32 -0800 (PST) To: binutils@sourceware.org Subject: [PATCH 08/10] x86: Add DT_RELR support Date: Fri, 7 Jan 2022 11:06:29 -0800 Message-Id: <20220107190631.309790-9-hjl.tools@gmail.com> X-Mailer: git-send-email 2.33.1 In-Reply-To: <20220107190631.309790-1-hjl.tools@gmail.com> References: <20220107190631.309790-1-hjl.tools@gmail.com> MIME-Version: 1.0 X-Spam-Status: No, score=-3028.1 required=5.0 tests=BAYES_00, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, DKIM_VALID_EF, FREEMAIL_FROM, GIT_PATCH_0, KAM_STOCKGEN, RCVD_IN_BARRACUDACENTRAL, RCVD_IN_DNSWL_NONE, SPF_HELO_NONE, SPF_PASS, TXREP autolearn=ham autolearn_force=no version=3.4.4 X-Spam-Checker-Version: SpamAssassin 3.4.4 (2020-01-24) on server2.sourceware.org X-BeenThere: libc-alpha@sourceware.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Libc-alpha mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-Patchwork-Original-From: "H.J. Lu via Libc-alpha" From: "H.J. Lu" Reply-To: "H.J. Lu" Cc: libc-alpha@sourceware.org, Nick Clifton , Alan Modra Errors-To: libc-alpha-bounces+patchwork=sourceware.org@sourceware.org Sender: "Libc-alpha" DT_RELR is implemented with linker relaxation: 1. During linker relaxation, we scan input relocations with the same logic in relocate_section to determine if a relative relocation should be generated and save the relative relocation candidate information for sizing the DT_RELR section later after all symbols addresses can be determined. For these relative relocations which can't be placed in the DT_RELR section, they will be placed in the rela.dyn/rel.dyn section. 2. When DT_RELR is enabled, _bfd_elf_map_sections_to_segments calls a backend function to size the DT_RELR section which will compute the DT_RELR section size and tell ldelf_map_segments to layout sections again when the DT_RELR section size has been increased. 3. After regular symbol processing is finished, bfd_elf_final_link calls a backend function to finish the DT_RELR section. * elf32-i386.c (elf_i386_scan_relocs): Set SEC_ELF_REVERSE_COPY on input section for DT_RELR. (elf_i386_relocate_section): Don't generate relative relocation when DT_RELR is enabled. * elf64-x86-64.c (elf_x86_64_scan_relocs): Set SEC_ELF_REVERSE_COPY on input section for DT_RELR. (elf_x86_64_relocate_section): Don't generate relative relocation when DT_RELR is enabled. * elfxx-x86.c (_bfd_x86_elf_link_hash_table_create): Initialize relative_r_type, relative_r_name, elf_append_reloc, elf_write_addend and elf_write_addend_in_got. (elf_x86_relative_reloc_record_add): New function. (_bfd_x86_elf_link_relax_section): Likewise. (elf64_dt_relr_bitmap_add): Likewise. (elf32_dt_relr_bitmap_add): Likewise. (_bfd_elf32_write_addend): Likewise. (_bfd_elf64_write_addend): Likewise. (elf_x86_size_or_finish_relative_reloc): Likewise. (elf_x86_compute_dl_relr_bitmap): Likewise. (elf_x86_write_dl_relr_bitmap): Likewise. (elf_x86_relative_reloc_compare ): Likewise. (_bfd_elf_x86_size_relative_relocs): Likewise. (_bfd_elf_x86_finish_relative_relocs): Likewise. (_bfd_x86_elf_size_dynamic_sections): Skip the .relr.dyn section. (_bfd_x86_elf_finish_dynamic_sections): Convert 3 spare dynamic tags to DT_RELR, DT_RELRSZ and for compact relative relocation. * elfxx-x86.h (X86_64_GOT_TYPE_P): New. (I386_GOT_TYPE_P): Likewise. (X86_GOT_TYPE_P): Likewise. (X86_64_RELATIVE_RELOC_TYPE_P): Likewise. (I386_RELATIVE_RELOC_TYPE_P): Likewise. (X86_RELATIVE_RELOC_TYPE_P): Likewise. (X86_LOCAL_GOT_RELATIVE_RELOC_P): Likewise. (I386_PCREL_TYPE_P): Likewise. (X86_64_PCREL_TYPE_P): Likewise. (X86_64_NEED_DYNAMIC_RELOC_TYPE_P): Rewrite. (I386_NEED_DYNAMIC_RELOC_TYPE_P): Likewise. (GENERATE_DYNAMIC_RELOCATION_P): Also check rel_from_abs. (elf_x86_link_hash_entry): Add got_relative_reloc_done. (elf_x86_relative_reloc_record): New. (elf_x86_relative_reloc_data): Likewise. (elf_dt_relr_bitmap): Likewise. (elf_x86_link_hash_table): Add dt_relr_bitmap, relative_reloc, unaligned_relative_reloc, relative_r_type, relative_r_name, elf_append_reloc, elf_write_addend, elf_write_addend_in_got and relative_reloc_done. (elf_x86_relative_reloc_done): New. (relative_reloc_packed): Likewise. (_bfd_x86_elf_link_relax_section): Likewise. (_bfd_elf_x86_size_relative_relocs): Likewise. (_bfd_elf_x86_finish_relative_relocs): Likewise. (_bfd_elf32_write_addend): Likewise. (_bfd_elf64_write_addend): Likewise. (bfd_elf32_bfd_relax_section): Likewise. (bfd_elf64_bfd_relax_section): Likewise. (elf_backend_size_relative_relocs): Likewise. (elf_backend_finish_relative_relocs): Likewise. (elf_x86_allocate_local_got_info): Also allocate relative_reloc_done. --- bfd/elf32-i386.c | 54 ++- bfd/elf64-x86-64.c | 63 ++- bfd/elfxx-x86.c | 937 +++++++++++++++++++++++++++++++++++++++++++++ bfd/elfxx-x86.h | 147 ++++++- 4 files changed, 1161 insertions(+), 40 deletions(-) diff --git a/bfd/elf32-i386.c b/bfd/elf32-i386.c index d1f61be5044..8e34bf0bcb4 100644 --- a/bfd/elf32-i386.c +++ b/bfd/elf32-i386.c @@ -1456,6 +1456,7 @@ elf_i386_scan_relocs (bfd *abfd, asection *sec, const Elf_Internal_Rela *relocs) { + const struct elf_backend_data *bed; struct elf_x86_link_hash_table *htab; Elf_Internal_Shdr *symtab_hdr; struct elf_link_hash_entry **sym_hashes; @@ -1485,6 +1486,14 @@ elf_i386_scan_relocs (bfd *abfd, return false; } + bed = get_elf_backend_data (abfd); + + /* Set SEC_ELF_REVERSE_COPY here so that the correct section offset + will be used for DT_RELR. */ + if (!_bfd_elf_process_reverse_copy (sec, 4, + bed->s->int_rels_per_ext_rel)) + return false; + symtab_hdr = &elf_symtab_hdr (abfd); sym_hashes = elf_sym_hashes (abfd); @@ -2473,8 +2482,10 @@ elf_i386_relocate_section (bfd *output_bfd, bfd_put_32 (output_bfd, relocation, htab->elf.sgot->contents + off); h->got.offset |= 1; - - if (GENERATE_RELATIVE_RELOC_P (info, h)) + /* NB: Don't generate relative relocation here if + it has been generated by DT_RELR. */ + if (!info->enable_dt_relr + && GENERATE_RELATIVE_RELOC_P (info, h)) { /* PR ld/21402: If this symbol isn't dynamic in PIC, generate R_386_RELATIVE here. */ @@ -2504,7 +2515,9 @@ elf_i386_relocate_section (bfd *output_bfd, htab->elf.sgot->contents + off); local_got_offsets[r_symndx] |= 1; - if (bfd_link_pic (info)) + /* NB: Don't generate relative relocation here if it + has been generated by DT_RELR. */ + if (!info->enable_dt_relr && bfd_link_pic (info)) relative_reloc = true; } } @@ -2707,6 +2720,7 @@ elf_i386_relocate_section (bfd *output_bfd, { Elf_Internal_Rela outrel; bool skip, relocate; + bool generate_dynamic_reloc = true; asection *sreloc; /* When generating a shared object, these relocations @@ -2734,23 +2748,33 @@ elf_i386_relocate_section (bfd *output_bfd, { /* This symbol is local, or marked to become local. */ relocate = true; - outrel.r_info = ELF32_R_INFO (0, R_386_RELATIVE); + /* NB: Don't generate relative relocation here if it + has been generated by DT_RELR. */ + if (info->enable_dt_relr) + generate_dynamic_reloc = false; + else + { + outrel.r_info = ELF32_R_INFO (0, R_386_RELATIVE); - if (htab->params->report_relative_reloc) - _bfd_x86_elf_link_report_relative_reloc - (info, input_section, h, sym, "R_386_RELATIVE", - &outrel); + if (htab->params->report_relative_reloc) + _bfd_x86_elf_link_report_relative_reloc + (info, input_section, h, sym, "R_386_RELATIVE", + &outrel); + } } - sreloc = elf_section_data (input_section)->sreloc; - - if (sreloc == NULL || sreloc->contents == NULL) + if (generate_dynamic_reloc) { - r = bfd_reloc_notsupported; - goto check_relocation_error; - } + sreloc = elf_section_data (input_section)->sreloc; - elf_append_rel (output_bfd, sreloc, &outrel); + if (sreloc == NULL || sreloc->contents == NULL) + { + r = bfd_reloc_notsupported; + goto check_relocation_error; + } + + elf_append_rel (output_bfd, sreloc, &outrel); + } /* If this reloc is against an external symbol, we do not want to fiddle with the addend. Otherwise, we diff --git a/bfd/elf64-x86-64.c b/bfd/elf64-x86-64.c index ad885f89e11..0842df33c75 100644 --- a/bfd/elf64-x86-64.c +++ b/bfd/elf64-x86-64.c @@ -1826,6 +1826,7 @@ elf_x86_64_scan_relocs (bfd *abfd, struct bfd_link_info *info, asection *sec, const Elf_Internal_Rela *relocs) { + const struct elf_backend_data *bed; struct elf_x86_link_hash_table *htab; Elf_Internal_Shdr *symtab_hdr; struct elf_link_hash_entry **sym_hashes; @@ -1855,6 +1856,14 @@ elf_x86_64_scan_relocs (bfd *abfd, struct bfd_link_info *info, return false; } + bed = get_elf_backend_data (abfd); + + /* Set SEC_ELF_REVERSE_COPY here so that the correct section offset + will be used for DT_RELR. */ + if (!_bfd_elf_process_reverse_copy (sec, ABI_64_P (abfd) ? 8 : 4, + bed->s->int_rels_per_ext_rel)) + return false; + symtab_hdr = &elf_symtab_hdr (abfd); sym_hashes = elf_sym_hashes (abfd); @@ -2867,7 +2876,10 @@ elf_x86_64_relocate_section (bfd *output_bfd, as -1 | 1 still is -1. */ h->got.offset |= 1; - if (GENERATE_RELATIVE_RELOC_P (info, h)) + /* NB: Don't generate relative relocation here if + it has been generated by DT_RELR. */ + if (!info->enable_dt_relr + && GENERATE_RELATIVE_RELOC_P (info, h)) { /* If this symbol isn't dynamic in PIC, generate R_X86_64_RELATIVE here. */ @@ -2899,8 +2911,11 @@ elf_x86_64_relocate_section (bfd *output_bfd, /* NB: GOTPCREL relocations against local absolute symbol store relocation value in the GOT slot - without relative relocation. */ - if (bfd_link_pic (info) + without relative relocation. Don't generate + relative relocation here if it has been generated + by DT_RELR. */ + if (!info->enable_dt_relr + && bfd_link_pic (info) && !(sym->st_shndx == SHN_ABS && (r_type == R_X86_64_GOTPCREL || r_type == R_X86_64_GOTPCRELX @@ -3215,6 +3230,7 @@ elf_x86_64_relocate_section (bfd *output_bfd, { Elf_Internal_Rela outrel; bool skip, relocate; + bool generate_dynamic_reloc = true; asection *sreloc; const char *relative_reloc_name = NULL; @@ -3253,9 +3269,17 @@ elf_x86_64_relocate_section (bfd *output_bfd, && htab->params->no_reloc_overflow_check)) { relocate = true; - outrel.r_info = htab->r_info (0, R_X86_64_RELATIVE); - outrel.r_addend = relocation + rel->r_addend; - relative_reloc_name = "R_X86_64_RELATIVE"; + /* NB: Don't generate relative relocation here if + it has been generated by DT_RELR. */ + if (info->enable_dt_relr) + generate_dynamic_reloc = false; + else + { + outrel.r_info = + htab->r_info (0, R_X86_64_RELATIVE); + outrel.r_addend = relocation + rel->r_addend; + relative_reloc_name = "R_X86_64_RELATIVE"; + } } else if (r_type == R_X86_64_64 && !ABI_64_P (output_bfd)) @@ -3323,21 +3347,24 @@ elf_x86_64_relocate_section (bfd *output_bfd, } } - sreloc = elf_section_data (input_section)->sreloc; - - if (sreloc == NULL || sreloc->contents == NULL) + if (generate_dynamic_reloc) { - r = bfd_reloc_notsupported; - goto check_relocation_error; - } + sreloc = elf_section_data (input_section)->sreloc; - if (relative_reloc_name - && htab->params->report_relative_reloc) - _bfd_x86_elf_link_report_relative_reloc - (info, input_section, h, sym, relative_reloc_name, - &outrel); + if (sreloc == NULL || sreloc->contents == NULL) + { + r = bfd_reloc_notsupported; + goto check_relocation_error; + } - elf_append_rela (output_bfd, sreloc, &outrel); + if (relative_reloc_name + && htab->params->report_relative_reloc) + _bfd_x86_elf_link_report_relative_reloc + (info, input_section, h, sym, + relative_reloc_name, &outrel); + + elf_append_rela (output_bfd, sreloc, &outrel); + } /* If this reloc is against an external symbol, we do not want to fiddle with the addend. Otherwise, we diff --git a/bfd/elfxx-x86.c b/bfd/elfxx-x86.c index 25f7717ea88..0f4e6542ef0 100644 --- a/bfd/elfxx-x86.c +++ b/bfd/elfxx-x86.c @@ -726,6 +726,10 @@ _bfd_x86_elf_link_hash_table_create (bfd *abfd) ret->got_entry_size = 8; ret->pcrel_plt = true; ret->tls_get_addr = "__tls_get_addr"; + ret->relative_r_type = R_X86_64_RELATIVE; + ret->relative_r_name = "R_X86_64_RELATIVE"; + ret->elf_append_reloc = elf_append_rela; + ret->elf_write_addend_in_got = _bfd_elf64_write_addend; } if (ABI_64_P (abfd)) { @@ -733,6 +737,7 @@ _bfd_x86_elf_link_hash_table_create (bfd *abfd) ret->pointer_r_type = R_X86_64_64; ret->dynamic_interpreter = ELF64_DYNAMIC_INTERPRETER; ret->dynamic_interpreter_size = sizeof ELF64_DYNAMIC_INTERPRETER; + ret->elf_write_addend = _bfd_elf64_write_addend; } else { @@ -743,6 +748,7 @@ _bfd_x86_elf_link_hash_table_create (bfd *abfd) ret->dynamic_interpreter = ELFX32_DYNAMIC_INTERPRETER; ret->dynamic_interpreter_size = sizeof ELFX32_DYNAMIC_INTERPRETER; + ret->elf_write_addend = _bfd_elf32_write_addend; } else { @@ -751,6 +757,11 @@ _bfd_x86_elf_link_hash_table_create (bfd *abfd) ret->got_entry_size = 4; ret->pcrel_plt = false; ret->pointer_r_type = R_386_32; + ret->relative_r_type = R_386_RELATIVE; + ret->relative_r_name = "R_386_RELATIVE"; + ret->elf_append_reloc = elf_append_rel; + ret->elf_write_addend = _bfd_elf32_write_addend; + ret->elf_write_addend_in_got = _bfd_elf32_write_addend; ret->dynamic_interpreter = ELF32_DYNAMIC_INTERPRETER; ret->dynamic_interpreter_size = sizeof ELF32_DYNAMIC_INTERPRETER; @@ -977,6 +988,902 @@ _bfd_x86_elf_check_relocs (bfd *abfd, return true; } +/* Add an entry to the relative reloc record. */ + +static bool +elf_x86_relative_reloc_record_add + (struct bfd_link_info *info, + struct elf_x86_relative_reloc_data *relative_reloc, + Elf_Internal_Rela *rel, asection *sec, + asection *sym_sec, struct elf_link_hash_entry *h, + Elf_Internal_Sym *sym, bfd_vma offset) +{ + bfd_size_type newidx; + + if (relative_reloc->data == NULL) + { + relative_reloc->data = bfd_malloc + (sizeof (struct elf_x86_relative_reloc_record)); + relative_reloc->count = 0; + relative_reloc->size = 1; + } + + newidx = relative_reloc->count++; + + if (relative_reloc->count > relative_reloc->size) + { + relative_reloc->size <<= 1; + relative_reloc->data = bfd_realloc + (relative_reloc->data, + (relative_reloc->size + * sizeof (struct elf_x86_relative_reloc_record))); + } + + if (relative_reloc->data == NULL) + { + info->callbacks->einfo + /* xgettext:c-format */ + (_("%F%P: %pB: failed to allocate relative reloc record\n"), + info->output_bfd); + return false; + } + + relative_reloc->data[newidx].rel = *rel; + relative_reloc->data[newidx].sec = sec; + if (h != NULL) + { + /* Set SYM to NULL to indicate a global symbol. */ + relative_reloc->data[newidx].sym = NULL; + relative_reloc->data[newidx].u.h = h; + } + else + { + relative_reloc->data[newidx].sym = sym; + relative_reloc->data[newidx].u.sym_sec = sym_sec; + } + relative_reloc->data[newidx].offset = offset; + relative_reloc->data[newidx].address = 0; + return true; +} + +/* After input sections have been mapped to output sections and + addresses of output sections are set initiallly, scan input + relocations with the same logic in relocate_section to determine + if a relative relocation should be generated. Save the relative + relocation candidate information for sizing the DT_RELR section + later after all symbols addresses can be determined. */ + +bool +_bfd_x86_elf_link_relax_section (bfd *abfd ATTRIBUTE_UNUSED, + asection *input_section, + struct bfd_link_info *info, + bool *again) +{ + Elf_Internal_Shdr *symtab_hdr; + Elf_Internal_Rela *internal_relocs; + Elf_Internal_Rela *irel, *irelend; + Elf_Internal_Sym *isymbuf = NULL; + struct elf_link_hash_entry **sym_hashes; + const struct elf_backend_data *bed; + struct elf_x86_link_hash_table *htab; + bfd_vma *local_got_offsets; + bool is_x86_64; + bool unaligned_section; + + if (bfd_link_relocatable (info)) + return true; + + /* Assume we're not going to change any sizes, and we'll only need + one pass. */ + *again = false; + + bed = get_elf_backend_data (abfd); + htab = elf_x86_hash_table (info, bed->target_id); + if (htab == NULL) + return true; + + /* Nothing to do if there are no relocations or relative relocations + have been packed. */ + if (input_section == htab->elf.srelrdyn + || input_section->relative_reloc_packed + || ((input_section->flags & (SEC_RELOC | SEC_ALLOC)) + != (SEC_RELOC | SEC_ALLOC)) + || (input_section->flags & SEC_DEBUGGING) != 0 + || input_section->reloc_count == 0) + return true; + + /* Skip if the section isn't aligned. */ + unaligned_section = input_section->alignment_power == 0; + + is_x86_64 = bed->target_id == X86_64_ELF_DATA; + + symtab_hdr = &elf_tdata (abfd)->symtab_hdr; + sym_hashes = elf_sym_hashes (abfd); + local_got_offsets = elf_local_got_offsets (abfd); + + /* Load the relocations for this section. */ + internal_relocs = + _bfd_elf_link_read_relocs (abfd, input_section, NULL, + (Elf_Internal_Rela *) NULL, + info->keep_memory); + if (internal_relocs == NULL) + return false; + + irelend = internal_relocs + input_section->reloc_count; + for (irel = internal_relocs; irel < irelend; irel++) + { + unsigned int r_type; + unsigned int r_symndx; + Elf_Internal_Sym *isym; + struct elf_link_hash_entry *h; + struct elf_x86_link_hash_entry *eh; + bfd_vma offset; + bool resolved_to_zero; + bool need_copy_reloc_in_pie; + bool pc32_reloc; + asection *sec; + /* Offset must be a multiple of 2. */ + bool unaligned_offset = (irel->r_offset & 1) != 0; + + /* Get the value of the symbol referred to by the reloc. */ + r_symndx = htab->r_sym (irel->r_info); + + r_type = ELF32_R_TYPE (irel->r_info); + /* Clear the R_X86_64_converted_reloc_bit bit. */ + r_type &= ~R_X86_64_converted_reloc_bit; + + sec = NULL; + h = NULL; + + if (r_symndx < symtab_hdr->sh_info) + { + /* Read this BFD's local symbols. */ + if (isymbuf == NULL) + { + isymbuf = (Elf_Internal_Sym *) symtab_hdr->contents; + if (isymbuf == NULL) + isymbuf = bfd_elf_get_elf_syms (abfd, symtab_hdr, + symtab_hdr->sh_info, 0, + NULL, NULL, NULL); + if (isymbuf == NULL) + goto error_return; + } + + isym = isymbuf + r_symndx; + switch (isym->st_shndx) + { + case SHN_ABS: + sec = bfd_abs_section_ptr; + break; + case SHN_COMMON: + sec = bfd_com_section_ptr; + break; + case SHN_X86_64_LCOMMON: + if (!is_x86_64) + abort (); + sec = &_bfd_elf_large_com_section; + break; + default: + sec = bfd_section_from_elf_index (abfd, isym->st_shndx); + break; + } + + /* Check relocation against local STT_GNU_IFUNC symbol. */ + if (ELF32_ST_TYPE (isym->st_info) == STT_GNU_IFUNC) + { + h = _bfd_elf_x86_get_local_sym_hash (htab, abfd, irel, + true); + if (h == NULL) + goto error_return; + } + + resolved_to_zero = false; + } + else + { + /* Get H and SEC for GENERATE_DYNAMIC_RELOCATION_P below. */ + h = sym_hashes[r_symndx - symtab_hdr->sh_info]; + while (h->root.type == bfd_link_hash_indirect + || h->root.type == bfd_link_hash_warning) + h = (struct elf_link_hash_entry *) h->root.u.i.link; + + if (h->root.type == bfd_link_hash_defined + || h->root.type == bfd_link_hash_defweak) + sec = h->root.u.def.section; + + isym = NULL; + } + + eh = (struct elf_x86_link_hash_entry *) h; + resolved_to_zero = (eh != NULL + && UNDEFINED_WEAK_RESOLVED_TO_ZERO (info, eh)); + + if (X86_GOT_TYPE_P (is_x86_64, r_type)) + { + /* Pack GOT relative relocations. There should be only a + single R_*_RELATIVE relocation in GOT. */ + if (eh != NULL) + { + if (eh->got_relative_reloc_done) + continue; + + if (!(h->type != STT_GNU_IFUNC + && RESOLVED_LOCALLY_P (info, h, htab) + && GENERATE_RELATIVE_RELOC_P (info, h))) + continue; + + eh->no_finish_dynamic_symbol = 1; + eh->got_relative_reloc_done = 1; + offset = h->got.offset; + } + else + { + if (elf_x86_relative_reloc_done (abfd)[r_symndx]) + continue; + + if (!X86_LOCAL_GOT_RELATIVE_RELOC_P (is_x86_64, info, + isym)) + continue; + + elf_x86_relative_reloc_done (abfd)[r_symndx] = 1; + offset = local_got_offsets[r_symndx]; + } + + if (!elf_x86_relative_reloc_record_add (info, + &htab->relative_reloc, + irel, htab->elf.sgot, + sec, h, isym, offset)) + goto error_return; + + continue; + } + + if (is_x86_64 + && irel->r_addend == 0 + && !ABI_64_P (info->output_bfd)) + { + /* For x32, if addend is zero, treat R_X86_64_64 like + R_X86_64_32 and R_X86_64_SIZE64 like R_X86_64_SIZE32. */ + if (r_type == R_X86_64_64) + r_type = R_X86_64_32; + else if (r_type == R_X86_64_SIZE64) + r_type = R_X86_64_SIZE32; + } + + if (!X86_RELATIVE_RELOC_TYPE_P (is_x86_64, r_type) + || (h != NULL && h->type == STT_GNU_IFUNC)) + continue; + + /* Pack non-GOT relative relocations. */ + if (is_x86_64) + { + need_copy_reloc_in_pie = + (bfd_link_pie (info) + && h != NULL + && (h->needs_copy + || eh->needs_copy + || (h->root.type == bfd_link_hash_undefined)) + && (X86_PCREL_TYPE_P (true, r_type) + || X86_SIZE_TYPE_P (true, r_type))); + pc32_reloc = false; + } + else + { + need_copy_reloc_in_pie = false; + pc32_reloc = r_type == R_386_PC32; + } + + if (GENERATE_DYNAMIC_RELOCATION_P (is_x86_64, info, eh, r_type, + sec, need_copy_reloc_in_pie, + resolved_to_zero, pc32_reloc)) + { + /* When generating a shared object, these relocations + are copied into the output file to be resolved at run + time. */ + offset = _bfd_elf_section_offset (info->output_bfd, info, + input_section, + irel->r_offset); + if (offset == (bfd_vma) -1 + || offset == (bfd_vma) -2 + || COPY_INPUT_RELOC_P (is_x86_64, info, h, r_type)) + continue; + + /* This symbol is local, or marked to become local. When + relocation overflow check is disabled, we convert + R_X86_64_32 to dynamic R_X86_64_RELATIVE. */ + if (is_x86_64 + && !(r_type == htab->pointer_r_type + || (r_type == R_X86_64_32 + && htab->params->no_reloc_overflow_check))) + continue; + + if (!elf_x86_relative_reloc_record_add + (info, + ((unaligned_section || unaligned_offset) + ? &htab->unaligned_relative_reloc + : &htab->relative_reloc), + irel, input_section, sec, h, isym, offset)) + goto error_return; + } + } + + input_section->relative_reloc_packed = 1; + + return true; + +error_return: + if ((unsigned char *) isymbuf != symtab_hdr->contents) + free (isymbuf); + if (elf_section_data (input_section)->relocs != internal_relocs) + free (internal_relocs); + return false; +} + +/* Add an entry to the 64-bit DT_RELR bitmap. */ + +static void +elf64_dt_relr_bitmap_add + (struct bfd_link_info *info, struct elf_dt_relr_bitmap *bitmap, + uint64_t entry) +{ + bfd_size_type newidx; + + if (bitmap->u.elf64 == NULL) + { + bitmap->u.elf64 = bfd_malloc (sizeof (uint64_t)); + bitmap->count = 0; + bitmap->size = 1; + } + + newidx = bitmap->count++; + + if (bitmap->count > bitmap->size) + { + bitmap->size <<= 1; + bitmap->u.elf64 = bfd_realloc (bitmap->u.elf64, + (bitmap->size * sizeof (uint64_t))); + } + + if (bitmap->u.elf64 == NULL) + { + info->callbacks->einfo + /* xgettext:c-format */ + (_("%F%P: %pB: failed to allocate 64-bit DT_RELR bitmap\n"), + info->output_bfd); + } + + bitmap->u.elf64[newidx] = entry; +} + +/* Add an entry to the 32-bit DT_RELR bitmap. */ + +static void +elf32_dt_relr_bitmap_add + (struct bfd_link_info *info, struct elf_dt_relr_bitmap *bitmap, + uint32_t entry) +{ + bfd_size_type newidx; + + if (bitmap->u.elf32 == NULL) + { + bitmap->u.elf32 = bfd_malloc (sizeof (uint32_t)); + bitmap->count = 0; + bitmap->size = 1; + } + + newidx = bitmap->count++; + + if (bitmap->count > bitmap->size) + { + bitmap->size <<= 1; + bitmap->u.elf32 = bfd_realloc (bitmap->u.elf32, + (bitmap->size * sizeof (uint32_t))); + } + + if (bitmap->u.elf32 == NULL) + { + info->callbacks->einfo + /* xgettext:c-format */ + (_("%F%P: %pB: failed to allocate 32-bit DT_RELR bitmap\n"), + info->output_bfd); + } + + bitmap->u.elf32[newidx] = entry; +} + +void +_bfd_elf32_write_addend (bfd *abfd, uint64_t value, void *addr) +{ + bfd_put_32 (abfd, value, addr); +} + +void +_bfd_elf64_write_addend (bfd *abfd, uint64_t value, void *addr) +{ + bfd_put_64 (abfd, value, addr); +} + +/* Size or finish relative relocations to determine the run-time + addresses for DT_RELR bitmap computation later. OUTREL is set + to NULL in the sizing phase and non-NULL in the finising phase + where the regular relative relocations will be written out. */ + +static void +elf_x86_size_or_finish_relative_reloc + (bool is_x86_64, struct bfd_link_info *info, + struct elf_x86_link_hash_table *htab, bool unaligned, + Elf_Internal_Rela *outrel) +{ + unsigned int align_mask; + bfd_size_type i, count; + asection *sec, *srel; + struct elf_link_hash_entry *h; + bfd_vma offset; + Elf_Internal_Sym *sym; + asection *sym_sec; + asection *sgot = htab->elf.sgot; + asection *srelgot = htab->elf.srelgot; + struct elf_x86_relative_reloc_data *relative_reloc; + + if (unaligned) + { + align_mask = 0; + relative_reloc = &htab->unaligned_relative_reloc; + } + else + { + align_mask = 1; + relative_reloc = &htab->relative_reloc; + } + + count = relative_reloc->count; + for (i = 0; i < count; i++) + { + sec = relative_reloc->data[i].sec; + sym = relative_reloc->data[i].sym; + + /* If SYM is NULL, it must be a global symbol. */ + if (sym == NULL) + h = relative_reloc->data[i].u.h; + else + h = NULL; + + if (is_x86_64) + { + bfd_vma relocation; + /* This function may be called more than once and REL may be + updated by _bfd_elf_rela_local_sym below. */ + Elf_Internal_Rela rel = relative_reloc->data[i].rel; + + if (h != NULL) + { + if (h->root.type == bfd_link_hash_defined + || h->root.type == bfd_link_hash_defweak) + { + sym_sec = h->root.u.def.section; + relocation = (h->root.u.def.value + + sym_sec->output_section->vma + + sym_sec->output_offset); + } + else + { + /* Allow undefined symbol only at the sizing phase. */ + if (outrel == NULL) + relocation = 0; + else + abort (); + } + } + else + { + sym_sec = relative_reloc->data[i].u.sym_sec; + relocation = _bfd_elf_rela_local_sym + (info->output_bfd, sym, &sym_sec, &rel); + } + + if (outrel != NULL) + { + outrel->r_addend = relocation; + if (sec == sgot) + { + if (h != NULL && h->needs_plt) + abort (); + } + else + outrel->r_addend += rel.r_addend; + + /* Write the implicit addend if ALIGN_MASK isn't 0. */ + if (align_mask) + { + if (sec == sgot) + { + if (relative_reloc->data[i].offset >= sec->size) + abort (); + htab->elf_write_addend_in_got + (info->output_bfd, outrel->r_addend, + sec->contents + relative_reloc->data[i].offset); + } + else + { + if (rel.r_offset >= sec->size) + abort (); + htab->elf_write_addend + (info->output_bfd, outrel->r_addend, + (elf_section_data (sec)->this_hdr.contents + + rel.r_offset)); + } + } + } + } + + if (sec == sgot) + srel = srelgot; + else + srel = elf_section_data (sec)->sreloc; + offset = (sec->output_section->vma + sec->output_offset + + relative_reloc->data[i].offset); + relative_reloc->data[i].address = offset; + if (outrel != NULL) + { + outrel->r_offset = offset; + + if ((outrel->r_offset & align_mask) != 0) + abort (); + + if (htab->params->report_relative_reloc) + _bfd_x86_elf_link_report_relative_reloc + (info, sec, h, sym, htab->relative_r_name, outrel); + + /* Generate regular relative relocation if ALIGN_MASK is 0. */ + if (align_mask == 0) + htab->elf_append_reloc (info->output_bfd, srel, outrel); + } + } +} + +/* Compute the DT_RELR section size. Set NEED_PLAYOUT to true if + the DT_RELR section size has been increased. */ + +static void +elf_x86_compute_dl_relr_bitmap + (struct bfd_link_info *info, struct elf_x86_link_hash_table *htab, + bool *need_layout) +{ + bfd_vma base; + bfd_size_type i, count, new_count; + struct elf_x86_relative_reloc_data *relative_reloc = + &htab->relative_reloc; + /* Save the old DT_RELR bitmap count. Don't shrink the DT_RELR bitmap + if the new DT_RELR bitmap count is smaller than the old one. Pad + with trailing 1s which won't be decoded to more relocations. */ + bfd_size_type dt_relr_bitmap_count = htab->dt_relr_bitmap.count; + + /* Clear the DT_RELR bitmap count. */ + htab->dt_relr_bitmap.count = 0; + + count = relative_reloc->count; + + if (ABI_64_P (info->output_bfd)) + { + /* Compute the 64-bit DT_RELR bitmap. */ + i = 0; + while (i < count) + { + if ((relative_reloc->data[i].address % 1) != 0) + abort (); + + elf64_dt_relr_bitmap_add (info, &htab->dt_relr_bitmap, + relative_reloc->data[i].address); + + base = relative_reloc->data[i].address + 8; + i++; + + while (i < count) + { + uint64_t bitmap = 0; + for (; i < count; i++) + { + bfd_vma delta = (relative_reloc->data[i].address + - base); + /* Stop if it is too far from base. */ + if (delta >= 63 * 8) + break; + /* Stop if it isn't a multiple of 8. */ + if ((delta % 8) != 0) + break; + bitmap |= 1ULL << (delta / 8); + } + + if (bitmap == 0) + break; + + elf64_dt_relr_bitmap_add (info, &htab->dt_relr_bitmap, + (bitmap << 1) | 1); + + base += 63 * 8; + } + } + + new_count = htab->dt_relr_bitmap.count; + if (dt_relr_bitmap_count > new_count) + { + /* Don't shrink the DT_RELR section size to avoid section + layout oscillation. Instead, pad the DT_RELR bitmap with + 1s which do not decode to more relocations. */ + + htab->dt_relr_bitmap.count = dt_relr_bitmap_count; + count = dt_relr_bitmap_count - new_count; + for (i = 0; i < count; i++) + htab->dt_relr_bitmap.u.elf64[new_count + i] = 1; + } + } + else + { + /* Compute the 32-bit DT_RELR bitmap. */ + i = 0; + while (i < count) + { + if ((relative_reloc->data[i].address % 1) != 0) + abort (); + + elf32_dt_relr_bitmap_add (info, &htab->dt_relr_bitmap, + relative_reloc->data[i].address); + + base = relative_reloc->data[i].address + 4; + i++; + + while (i < count) + { + uint32_t bitmap = 0; + for (; i < count; i++) + { + bfd_vma delta = (relative_reloc->data[i].address + - base); + /* Stop if it is too far from base. */ + if (delta >= 31 * 4) + break; + /* Stop if it isn't a multiple of 4. */ + if ((delta % 4) != 0) + break; + bitmap |= 1ULL << (delta / 4); + } + + if (bitmap == 0) + break; + + elf32_dt_relr_bitmap_add (info, &htab->dt_relr_bitmap, + (bitmap << 1) | 1); + + base += 31 * 4; + } + } + + new_count = htab->dt_relr_bitmap.count; + if (dt_relr_bitmap_count > new_count) + { + /* Don't shrink the DT_RELR section size to avoid section + layout oscillation. Instead, pad the DT_RELR bitmap with + 1s which do not decode to more relocations. */ + + htab->dt_relr_bitmap.count = dt_relr_bitmap_count; + count = dt_relr_bitmap_count - new_count; + for (i = 0; i < count; i++) + htab->dt_relr_bitmap.u.elf32[new_count + i] = 1; + } + } + + if (htab->dt_relr_bitmap.count != dt_relr_bitmap_count) + { + if (need_layout) + { + /* The .relr.dyn section size is changed. Update the section + size and tell linker to layout sections again. */ + htab->elf.srelrdyn->size = + (htab->dt_relr_bitmap.count + * (ABI_64_P (info->output_bfd) ? 8 : 4)); + + *need_layout = true; + } + else + info->callbacks->einfo + /* xgettext:c-format */ + (_("%F%P: %pB: size of compact relative reloc section is " + "changed: new (%lu) != old (%lu)\n"), + info->output_bfd, htab->dt_relr_bitmap.count, + dt_relr_bitmap_count); + } +} + +/* Write out the DT_RELR section. */ + +static void +elf_x86_write_dl_relr_bitmap (struct bfd_link_info *info, + struct elf_x86_link_hash_table *htab) +{ + asection *sec = htab->elf.srelrdyn; + bfd_size_type size = sec->size; + bfd_size_type i; + unsigned char *contents; + + contents = (unsigned char *) bfd_alloc (sec->owner, size); + if (contents == NULL) + info->callbacks->einfo + /* xgettext:c-format */ + (_("%F%P: %pB: failed to allocate compact relative reloc section\n"), + info->output_bfd); + + /* Cache the section contents for elf_link_input_bfd. */ + sec->contents = contents; + + if (ABI_64_P (info->output_bfd)) + for (i = 0; i < htab->dt_relr_bitmap.count; i++, contents += 8) + bfd_put_64 (info->output_bfd, htab->dt_relr_bitmap.u.elf64[i], + contents); + else + for (i = 0; i < htab->dt_relr_bitmap.count; i++, contents += 4) + bfd_put_32 (info->output_bfd, htab->dt_relr_bitmap.u.elf32[i], + contents); +} + +/* Sort relative relocations by address. */ + +static int +elf_x86_relative_reloc_compare (const void *pa, const void *pb) +{ + struct elf_x86_relative_reloc_record *a = + (struct elf_x86_relative_reloc_record *) pa; + struct elf_x86_relative_reloc_record *b = + (struct elf_x86_relative_reloc_record *) pb; + if (a->address < b->address) + return -1; + if (a->address > b->address) + return 1; + return 0; +} + +bool +_bfd_elf_x86_size_relative_relocs (struct bfd_link_info *info, + bool *need_layout) +{ + struct elf_x86_link_hash_table *htab; + const struct elf_backend_data *bed; + bool is_x86_64; + bfd_size_type i, count, unaligned_count; + asection *sec, *srel; + + /* Do nothing for ld -r. */ + if (bfd_link_relocatable (info)) + return true; + + bed = get_elf_backend_data (info->output_bfd); + htab = elf_x86_hash_table (info, bed->target_id); + if (htab == NULL) + return false; + + count = htab->relative_reloc.count; + unaligned_count = htab->unaligned_relative_reloc.count; + if (count == 0) + { + if (htab->generate_relative_reloc_pass == 0 + && htab->elf.srelrdyn != NULL) + { + /* Remove the empty .relr.dyn sections now. */ + if (!bfd_is_abs_section (htab->elf.srelrdyn->output_section)) + { + bfd_section_list_remove + (info->output_bfd, htab->elf.srelrdyn->output_section); + info->output_bfd->section_count--; + } + bfd_section_list_remove (htab->elf.srelrdyn->owner, + htab->elf.srelrdyn); + htab->elf.srelrdyn->owner->section_count--; + } + if (unaligned_count == 0) + { + htab->generate_relative_reloc_pass++; + return true; + } + } + + is_x86_64 = bed->target_id == X86_64_ELF_DATA; + + /* Size relative relocations. */ + if (htab->generate_relative_reloc_pass) + { + /* Reset the regular relative relocation count. */ + for (i = 0; i < unaligned_count; i++) + { + sec = htab->unaligned_relative_reloc.data[i].sec; + srel = elf_section_data (sec)->sreloc; + srel->reloc_count = 0; + } + } + else + { + /* Remove the reserved space for compact relative relocations. */ + if (count) + { + asection *sgot = htab->elf.sgot; + asection *srelgot = htab->elf.srelgot; + + for (i = 0; i < count; i++) + { + sec = htab->relative_reloc.data[i].sec; + if (sec == sgot) + srel = srelgot; + else + srel = elf_section_data (sec)->sreloc; + srel->size -= htab->sizeof_reloc; + } + } + } + + /* Size unaligned relative relocations. */ + if (unaligned_count) + elf_x86_size_or_finish_relative_reloc (is_x86_64, info, htab, + true, NULL); + + if (count) + { + elf_x86_size_or_finish_relative_reloc (is_x86_64, info, htab, + false, NULL); + + /* Sort relative relocations by addresses. We only need to + sort them in the first pass since the relative positions + won't change. */ + if (htab->generate_relative_reloc_pass == 0) + qsort (htab->relative_reloc.data, count, + sizeof (struct elf_x86_relative_reloc_record), + elf_x86_relative_reloc_compare); + + elf_x86_compute_dl_relr_bitmap (info, htab, need_layout); + } + + htab->generate_relative_reloc_pass++; + + return true; +} + +bool +_bfd_elf_x86_finish_relative_relocs (struct bfd_link_info *info) +{ + struct elf_x86_link_hash_table *htab; + const struct elf_backend_data *bed; + Elf_Internal_Rela outrel; + bool is_x86_64; + bfd_size_type count; + + /* Do nothing for ld -r. */ + if (bfd_link_relocatable (info)) + return true; + + bed = get_elf_backend_data (info->output_bfd); + htab = elf_x86_hash_table (info, bed->target_id); + if (htab == NULL) + return false; + + is_x86_64 = bed->target_id == X86_64_ELF_DATA; + + outrel.r_info = htab->r_info (0, htab->relative_r_type); + + if (htab->unaligned_relative_reloc.count) + elf_x86_size_or_finish_relative_reloc (is_x86_64, info, htab, + true, &outrel); + + count = htab->relative_reloc.count; + if (count) + { + elf_x86_size_or_finish_relative_reloc (is_x86_64, info, htab, + false, &outrel); + + elf_x86_compute_dl_relr_bitmap (info, htab, NULL); + + elf_x86_write_dl_relr_bitmap (info, htab); + } + + return true; +} + bool _bfd_elf_x86_valid_reloc_p (asection *input_section, struct bfd_link_info *info, @@ -1332,6 +2239,11 @@ _bfd_x86_elf_size_dynamic_sections (bfd *output_bfd, if ((s->flags & SEC_LINKER_CREATED) == 0) continue; + /* The .relr.dyn section for compact relative relocation will + be filled later. */ + if (s == htab->elf.srelrdyn) + continue; + if (s == htab->elf.splt || s == htab->elf.sgot) { @@ -1459,6 +2371,7 @@ _bfd_x86_elf_finish_dynamic_sections (bfd *output_bfd, asection *sdyn; bfd_byte *dyncon, *dynconend; bfd_size_type sizeof_dyn; + bfd_size_type dt_relr_bitmap_count; bed = get_elf_backend_data (output_bfd); htab = elf_x86_hash_table (info, bed->target_id); @@ -1517,6 +2430,8 @@ _bfd_x86_elf_finish_dynamic_sections (bfd *output_bfd, if (sdyn == NULL || htab->elf.sgot == NULL) abort (); + dt_relr_bitmap_count = htab->dt_relr_bitmap.count; + sizeof_dyn = bed->s->sizeof_dyn; dyncon = sdyn->contents; dynconend = sdyn->contents + sdyn->size; @@ -1535,6 +2450,28 @@ _bfd_x86_elf_finish_dynamic_sections (bfd *output_bfd, break; continue; + case DT_NULL: + if (dt_relr_bitmap_count != 0) + { + /* Convert 3 spare dynamic tags to DT_RELR, DT_RELRSZ and + DT_RELRENT for compact relative relocation. */ + s = htab->elf.srelrdyn; + dyn.d_tag = DT_RELR; + dyn.d_un.d_ptr = s->output_section->vma + s->output_offset; + (*bed->s->swap_dyn_out) (output_bfd, &dyn, dyncon); + dyncon += sizeof_dyn; + dyn.d_tag = DT_RELRSZ; + dyn.d_un.d_val = s->size; + (*bed->s->swap_dyn_out) (output_bfd, &dyn, dyncon); + dyncon += sizeof_dyn; + dyn.d_tag = DT_RELRENT; + dyn.d_un.d_val = ABI_64_P (output_bfd) ? 8 : 4; + elf_section_data (s->output_section)->this_hdr.sh_entsize + = dyn.d_un.d_val; + dt_relr_bitmap_count = 0; + } + break; + case DT_PLTGOT: s = htab->elf.sgotplt; dyn.d_un.d_ptr = s->output_section->vma + s->output_offset; diff --git a/bfd/elfxx-x86.h b/bfd/elfxx-x86.h index 1bb80280918..4b5784ca08a 100644 --- a/bfd/elfxx-x86.h +++ b/bfd/elfxx-x86.h @@ -47,18 +47,35 @@ #define X86_SIZE_TYPE_P(IS_X86_64, TYPE) \ ((IS_X86_64) ? X86_64_SIZE_TYPE_P(TYPE) : I386_SIZE_TYPE_P (TYPE)) -#define X86_64_NEED_DYNAMIC_RELOC_TYPE_P(TYPE) \ - (X86_64_SIZE_TYPE_P (TYPE) \ - || X86_64_PCREL_TYPE_P (TYPE) \ +#define X86_64_GOT_TYPE_P(TYPE) \ + ((TYPE) == R_X86_64_GOTPCREL \ + || (TYPE) == R_X86_64_GOTPCRELX \ + || (TYPE) == R_X86_64_REX_GOTPCRELX) +#define I386_GOT_TYPE_P(TYPE) \ + ((TYPE) == R_386_GOT32 || (TYPE) == R_386_GOT32X) +#define X86_GOT_TYPE_P(IS_X86_64, TYPE) \ + ((IS_X86_64) ? X86_64_GOT_TYPE_P (TYPE) : I386_GOT_TYPE_P (TYPE)) + +#define X86_64_RELATIVE_RELOC_TYPE_P(TYPE) \ + (X86_64_PCREL_TYPE_P (TYPE) \ || (TYPE) == R_X86_64_8 \ || (TYPE) == R_X86_64_16 \ || (TYPE) == R_X86_64_32 \ || (TYPE) == R_X86_64_32S \ || (TYPE) == R_X86_64_64) +#define I386_RELATIVE_RELOC_TYPE_P(TYPE) \ + ((TYPE) == R_386_32 || (TYPE) == R_386_PC32) +#define X86_RELATIVE_RELOC_TYPE_P(IS_X86_64, TYPE) \ + ((IS_X86_64) \ + ? X86_64_RELATIVE_RELOC_TYPE_P (TYPE) \ + : I386_RELATIVE_RELOC_TYPE_P(TYPE)) + +#define X86_64_NEED_DYNAMIC_RELOC_TYPE_P(TYPE) \ + (X86_64_SIZE_TYPE_P (TYPE) \ + || X86_64_RELATIVE_RELOC_TYPE_P (TYPE)) #define I386_NEED_DYNAMIC_RELOC_TYPE_P(TYPE) \ (I386_SIZE_TYPE_P (TYPE) \ - || I386_PCREL_TYPE_P (TYPE) \ - || (TYPE) == R_386_32 \ + || I386_RELATIVE_RELOC_TYPE_P (TYPE) \ || (TYPE) == R_386_TLS_LE \ || (TYPE) == R_386_TLS_LE_32) #define X86_NEED_DYNAMIC_RELOC_TYPE_P(IS_X86_64, TYPE) \ @@ -66,11 +83,23 @@ ? X86_64_NEED_DYNAMIC_RELOC_TYPE_P (TYPE) \ : I386_NEED_DYNAMIC_RELOC_TYPE_P (TYPE)) +#define X86_LOCAL_GOT_RELATIVE_RELOC_P(IS_X86_64, INFO, SYM) \ + (bfd_link_pic (INFO) \ + && (!(IS_X86_64) || ((SYM) != NULL && (SYM)->st_shndx != SHN_ABS))) + #define PLT_CIE_LENGTH 20 #define PLT_FDE_LENGTH 36 #define PLT_FDE_START_OFFSET 4 + PLT_CIE_LENGTH + 8 #define PLT_FDE_LEN_OFFSET 4 + PLT_CIE_LENGTH + 12 +#define I386_PCREL_TYPE_P(TYPE) ((TYPE) == R_386_PC32) +#define X86_64_PCREL_TYPE_P(TYPE) \ + ((TYPE) == R_X86_64_PC8 \ + || (TYPE) == R_X86_64_PC16 \ + || (TYPE) == R_X86_64_PC32 \ + || (TYPE) == R_X86_64_PC32_BND \ + || (TYPE) == R_X86_64_PC64) + #define ABI_64_P(abfd) \ (get_elf_backend_data (abfd)->s->elfclass == ELFCLASS64) @@ -160,12 +189,18 @@ relocations against resolved undefined weak symbols in PIE, except when PC32_RELOC is TRUE. Undefined weak symbol is bound locally when PIC is false. Don't generate dynamic relocations against - non-preemptible absolute symbol. */ + non-preemptible absolute symbol. NB: rel_from_abs is set on symbols + defined by linker scripts from "dot" (also SEGMENT_START or ORIGIN) + outside of an output section statement, which will be converted from + absolute to section-relative in set_sym_sections called from + ldexp_finalize_syms after ldemul_finish. */ #define GENERATE_DYNAMIC_RELOCATION_P(IS_X86_64, INFO, EH, R_TYPE, \ SEC, NEED_COPY_RELOC_IN_PIE, \ RESOLVED_TO_ZERO, PC32_RELOC) \ ((bfd_link_pic (INFO) \ && !(bfd_is_abs_section (SEC) \ + && ((EH) == NULL \ + || (EH)->elf.root.rel_from_abs == 0) \ && ((EH) == NULL \ || SYMBOL_REFERENCES_LOCAL (INFO, &(EH)->elf))) \ && !(NEED_COPY_RELOC_IN_PIE) \ @@ -302,6 +337,10 @@ struct elf_x86_link_hash_entry /* Don't call finish_dynamic_symbol on this symbol. */ unsigned int no_finish_dynamic_symbol : 1; + /* R_*_RELATIVE relocation in GOT for this symbol has been + processed. */ + unsigned int got_relative_reloc_done : 1; + /* TRUE if symbol is __tls_get_addr. */ unsigned int tls_get_addr : 1; @@ -481,6 +520,52 @@ struct elf_x86_plt_layout #define elf_x86_hash_entry(ent) \ ((struct elf_x86_link_hash_entry *)(ent)) +/* Information of an input relocation used to compute its contribution + to the DT_RELR section size. */ + +struct elf_x86_relative_reloc_record +{ + /* The original relocation info. */ + Elf_Internal_Rela rel; + /* The input or the GOT section where the relocation is applied. */ + asection *sec; + /* Local symbol info. NULL for global symbol. */ + Elf_Internal_Sym *sym; + union + { + /* Section where the local symbol is defined. */ + asection *sym_sec; + /* Global symbol hash. */ + struct elf_link_hash_entry *h; + } u; + /* The offset into the output section where the relative relocation + will be applied at run-time. */ + bfd_vma offset; + /* The run-time address. */ + bfd_vma address; +}; + +struct elf_x86_relative_reloc_data +{ + bfd_size_type count; + bfd_size_type size; + struct elf_x86_relative_reloc_record *data; +}; + +/* DT_RELR bitmap. */ +struct elf_dt_relr_bitmap +{ + bfd_size_type count; + bfd_size_type size; + union + { + /* 32-bit bitmap. */ + uint32_t *elf32; + /* 64-bit bitmap. */ + uint64_t *elf64; + } u; +}; + /* x86 ELF linker hash table. */ struct elf_x86_link_hash_table @@ -533,6 +618,18 @@ struct elf_x86_link_hash_table is only used for i386. */ bfd_vma next_tls_desc_index; + /* DT_RELR bitmap. */ + struct elf_dt_relr_bitmap dt_relr_bitmap; + + /* Relative relocation data. */ + struct elf_x86_relative_reloc_data relative_reloc; + + /* Unaligned relative relocation data. */ + struct elf_x86_relative_reloc_data unaligned_relative_reloc; + + /* Number of relative reloc generation pass. */ + unsigned int generate_relative_reloc_pass; + /* Value used to fill the unused bytes of the first PLT entry. This is only used for i386. */ bfd_byte plt0_pad_byte; @@ -554,9 +651,14 @@ struct elf_x86_link_hash_table unsigned int sizeof_reloc; unsigned int got_entry_size; unsigned int pointer_r_type; + unsigned int relative_r_type; int dynamic_interpreter_size; const char *dynamic_interpreter; const char *tls_get_addr; + const char *relative_r_name; + void (*elf_append_reloc) (bfd *, asection *, Elf_Internal_Rela *); + void (*elf_write_addend) (bfd *, uint64_t, void *); + void (*elf_write_addend_in_got) (bfd *, uint64_t, void *); /* Options passed from the linker. */ struct elf_linker_x86_params *params; @@ -591,6 +693,10 @@ struct elf_x86_obj_tdata /* GOTPLT entries for TLS descriptors. */ bfd_vma *local_tlsdesc_gotent; + + /* R_*_RELATIVE relocation in GOT for this local symbol has been + processed. */ + char *relative_reloc_done; }; enum elf_x86_plt_type @@ -626,6 +732,9 @@ struct elf_x86_plt #define elf_x86_local_tlsdesc_gotent(abfd) \ (elf_x86_tdata (abfd)->local_tlsdesc_gotent) +#define elf_x86_relative_reloc_done(abfd) \ + (elf_x86_tdata (abfd)->relative_reloc_done) + #define elf_x86_compute_jump_table_size(htab) \ ((htab)->elf.srelplt->reloc_count * (htab)->got_entry_size) @@ -637,6 +746,7 @@ struct elf_x86_plt /* Rename some of the generic section flags to better document how they are used here. */ #define check_relocs_failed sec_flg0 +#define relative_reloc_packed sec_flg1 extern bool _bfd_x86_elf_mkobject (bfd *); @@ -676,6 +786,18 @@ extern bool _bfd_x86_elf_check_relocs (bfd *, struct bfd_link_info *, asection *, const Elf_Internal_Rela *); +extern bool _bfd_x86_elf_link_relax_section + (bfd *, asection *, struct bfd_link_info *, bool *); + +extern bool _bfd_elf_x86_size_relative_relocs + (struct bfd_link_info *, bool *); + +extern bool _bfd_elf_x86_finish_relative_relocs + (struct bfd_link_info *); + +extern void _bfd_elf32_write_addend (bfd *, uint64_t, void *); +extern void _bfd_elf64_write_addend (bfd *, uint64_t, void *); + extern bool _bfd_elf_x86_valid_reloc_p (asection *, struct bfd_link_info *, struct elf_x86_link_hash_table *, const Elf_Internal_Rela *, struct elf_link_hash_entry *, @@ -752,6 +874,10 @@ extern void _bfd_x86_elf_link_report_relative_reloc _bfd_x86_elf_link_check_relocs #define bfd_elf32_bfd_link_check_relocs \ _bfd_x86_elf_link_check_relocs +#define bfd_elf32_bfd_relax_section \ + _bfd_x86_elf_link_relax_section +#define bfd_elf64_bfd_relax_section \ + _bfd_x86_elf_link_relax_section #define elf_backend_check_relocs \ _bfd_x86_elf_check_relocs @@ -777,6 +903,10 @@ extern void _bfd_x86_elf_link_report_relative_reloc _bfd_x86_elf_merge_gnu_properties #define elf_backend_fixup_gnu_properties \ _bfd_x86_elf_link_fixup_gnu_properties +#define elf_backend_size_relative_relocs \ + _bfd_elf_x86_size_relative_relocs +#define elf_backend_finish_relative_relocs \ + _bfd_elf_x86_finish_relative_relocs #define ELF_P_ALIGN ELF_MINPAGESIZE @@ -789,7 +919,8 @@ elf_x86_allocate_local_got_info (bfd *abfd, bfd_size_type count) if (local_got_refcounts == NULL) { bfd_size_type size = count * (sizeof (bfd_signed_vma) - + sizeof (bfd_vma) + sizeof(char)); + + sizeof (bfd_vma) + + 2 * sizeof(char)); local_got_refcounts = (bfd_signed_vma *) bfd_zalloc (abfd, size); if (local_got_refcounts == NULL) return false; @@ -798,6 +929,8 @@ elf_x86_allocate_local_got_info (bfd *abfd, bfd_size_type count) (bfd_vma *) (local_got_refcounts + count); elf_x86_local_got_tls_type (abfd) = (char *) (local_got_refcounts + 2 * count); + elf_x86_relative_reloc_done (abfd) = + ((char *) (local_got_refcounts + 2 * count)) + count; } return true; } From patchwork Fri Jan 7 19:06:30 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "H.J. Lu" X-Patchwork-Id: 49728 Return-Path: X-Original-To: patchwork@sourceware.org Delivered-To: patchwork@sourceware.org Received: from server2.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id AF5E53857C6D for ; Fri, 7 Jan 2022 19:15:34 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org AF5E53857C6D DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=sourceware.org; s=default; t=1641582934; bh=AXjjkasH7faV5aH60uMlhgSb57580VT8sl60JwcF/h4=; h=To:Subject:Date:In-Reply-To:References:List-Id:List-Unsubscribe: List-Archive:List-Post:List-Help:List-Subscribe:From:Reply-To:Cc: From; b=L9J1PKxa5ZJQwOLIMKIEBRzPF7R9j18CxNJsfM41gLixe2kjj9U3xuTicLsO2rVQr u6rCuIU+1CRXUcEwI8bXbDyGQP9XwXjxe3SiSTGe5GVM9OR2nwshoFz1J/rjlmy6Ge z7NK7K5FXXHUx0s22j5oblB/uKx5CApGJFOg4YAQ= X-Original-To: libc-alpha@sourceware.org Delivered-To: libc-alpha@sourceware.org Received: from mail-pj1-x1035.google.com (mail-pj1-x1035.google.com [IPv6:2607:f8b0:4864:20::1035]) by sourceware.org (Postfix) with ESMTPS id 518243858412; Fri, 7 Jan 2022 19:06:36 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.1 sourceware.org 518243858412 Received: by mail-pj1-x1035.google.com with SMTP id lr15-20020a17090b4b8f00b001b19671cbebso7260310pjb.1; Fri, 07 Jan 2022 11:06:36 -0800 (PST) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=AXjjkasH7faV5aH60uMlhgSb57580VT8sl60JwcF/h4=; b=ijHPBHDVbk/t9HcdUhQWH85poJcOsdk++XWLdZjhzZzqmCKe2g+Gdenf6q5awFdzA3 ezEz/fgs7e75A9Eoy0k63nUIYCnJsMbH2HQryupIhl4KDgJDsLaeZRwGeYy7JumcmceT zv6qWb/XCbHCaF07rDE9rZ/8kUQ2K9W3C1hOdBrxmJfr0R2hs9rAfvr/MKgS25+nuC+o HFdXOcNQPqKQ3kofO8OJXxXW10B2ICYyMXs9v67ADXysuoqtA1B49/m/AC0zi9cSb3Ov QIqemWyoduWH3xF462NuCGndzsW8hLRKbOmWIOzMDqrWG4KGvQHs2UBaKh+MUHYHbkg7 Yd3g== X-Gm-Message-State: AOAM5327oM+62R1M98L0nEGHZPyuwFmSncC8JPVv5lrcMKeY8OjnpNHP ly9QWTFYZ5yhdmwb0ueYt9U= X-Google-Smtp-Source: ABdhPJxBD7t2ojKhPxOz74izPqqLhlEIIU1WF0TgyEk8qzxYYAUp/DDrTHxxUgEEuQqcd/EE7EpQ2g== X-Received: by 2002:a17:902:e549:b0:149:22b4:530c with SMTP id n9-20020a170902e54900b0014922b4530cmr62658560plf.17.1641582395291; Fri, 07 Jan 2022 11:06:35 -0800 (PST) Received: from gnu-tgl-3.localdomain ([172.58.35.133]) by smtp.gmail.com with ESMTPSA id s25sm6312754pfg.208.2022.01.07.11.06.34 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 07 Jan 2022 11:06:34 -0800 (PST) Received: from gnu-tgl-3.. (localhost [IPv6:::1]) by gnu-tgl-3.localdomain (Postfix) with ESMTP id 55BC9C0EE2; Fri, 7 Jan 2022 11:06:32 -0800 (PST) To: binutils@sourceware.org Subject: [PATCH 09/10] ld: Add simple DT_RELR tests Date: Fri, 7 Jan 2022 11:06:30 -0800 Message-Id: <20220107190631.309790-10-hjl.tools@gmail.com> X-Mailer: git-send-email 2.33.1 In-Reply-To: <20220107190631.309790-1-hjl.tools@gmail.com> References: <20220107190631.309790-1-hjl.tools@gmail.com> MIME-Version: 1.0 X-Spam-Status: No, score=-3028.9 required=5.0 tests=BAYES_00, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, DKIM_VALID_EF, FREEMAIL_FROM, GIT_PATCH_0, RCVD_IN_BARRACUDACENTRAL, RCVD_IN_DNSWL_NONE, SPF_HELO_NONE, SPF_PASS, TXREP autolearn=ham autolearn_force=no version=3.4.4 X-Spam-Checker-Version: SpamAssassin 3.4.4 (2020-01-24) on server2.sourceware.org X-BeenThere: libc-alpha@sourceware.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Libc-alpha mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-Patchwork-Original-From: "H.J. Lu via Libc-alpha" From: "H.J. Lu" Reply-To: "H.J. Lu" Cc: libc-alpha@sourceware.org, Nick Clifton , Alan Modra Errors-To: libc-alpha-bounces+patchwork=sourceware.org@sourceware.org Sender: "Libc-alpha" * testsuite/ld-elf/dt-relr-1.s: New file. * testsuite/ld-elf/dt-relr-1a.d: Likewise. * testsuite/ld-elf/dt-relr-1b.d: Likewise. * testsuite/ld-elf/dt-relr-1c.d: Likewise. * testsuite/ld-elf/dt-relr-2.s: Likewise. * testsuite/ld-elf/dt-relr-2a.d: Likewise. * testsuite/ld-elf/dt-relr-2b.d: Likewise. * testsuite/ld-elf/dt-relr-2c.d: Likewise. * testsuite/ld-elf/dt-relr-2d.d: Likewise. * testsuite/ld-elf/dt-relr-2e.d: Likewise. * testsuite/ld-elf/dt-relr-2f.d: Likewise. * testsuite/ld-elf/dt-relr-2g.d: Likewise. * testsuite/ld-elf/dt-relr-2h.d: Likewise. --- ld/testsuite/ld-elf/dt-relr-1.s | 13 +++++++++++++ ld/testsuite/ld-elf/dt-relr-1a.d | 10 ++++++++++ ld/testsuite/ld-elf/dt-relr-1b.d | 9 +++++++++ ld/testsuite/ld-elf/dt-relr-1c.d | 9 +++++++++ ld/testsuite/ld-elf/dt-relr-2.s | 20 ++++++++++++++++++++ ld/testsuite/ld-elf/dt-relr-2a.d | 10 ++++++++++ ld/testsuite/ld-elf/dt-relr-2b.d | 17 +++++++++++++++++ ld/testsuite/ld-elf/dt-relr-2c.d | 17 +++++++++++++++++ ld/testsuite/ld-elf/dt-relr-2d.d | 9 +++++++++ ld/testsuite/ld-elf/dt-relr-2e.d | 9 +++++++++ ld/testsuite/ld-elf/dt-relr-2f.d | 8 ++++++++ ld/testsuite/ld-elf/dt-relr-2g.d | 9 +++++++++ ld/testsuite/ld-elf/dt-relr-2h.d | 9 +++++++++ 13 files changed, 149 insertions(+) create mode 100644 ld/testsuite/ld-elf/dt-relr-1.s create mode 100644 ld/testsuite/ld-elf/dt-relr-1a.d create mode 100644 ld/testsuite/ld-elf/dt-relr-1b.d create mode 100644 ld/testsuite/ld-elf/dt-relr-1c.d create mode 100644 ld/testsuite/ld-elf/dt-relr-2.s create mode 100644 ld/testsuite/ld-elf/dt-relr-2a.d create mode 100644 ld/testsuite/ld-elf/dt-relr-2b.d create mode 100644 ld/testsuite/ld-elf/dt-relr-2c.d create mode 100644 ld/testsuite/ld-elf/dt-relr-2d.d create mode 100644 ld/testsuite/ld-elf/dt-relr-2e.d create mode 100644 ld/testsuite/ld-elf/dt-relr-2f.d create mode 100644 ld/testsuite/ld-elf/dt-relr-2g.d create mode 100644 ld/testsuite/ld-elf/dt-relr-2h.d diff --git a/ld/testsuite/ld-elf/dt-relr-1.s b/ld/testsuite/ld-elf/dt-relr-1.s new file mode 100644 index 00000000000..18486d3acb2 --- /dev/null +++ b/ld/testsuite/ld-elf/dt-relr-1.s @@ -0,0 +1,13 @@ + .text + .p2align 3 + .globl _start +_start: + .byte 0 + + .data + .p2align 3 + .globl data +data: + .byte 0 + // Offset is not a multiple of 2. Don't use DT_RELR. + .dc.a __ehdr_start + 10 diff --git a/ld/testsuite/ld-elf/dt-relr-1a.d b/ld/testsuite/ld-elf/dt-relr-1a.d new file mode 100644 index 00000000000..55c93cefb59 --- /dev/null +++ b/ld/testsuite/ld-elf/dt-relr-1a.d @@ -0,0 +1,10 @@ +#source: dt-relr-1.s +#ld: -e _start $DT_RELR_LDFLAGS +#readelf: -rW -d +#target: x86_64-*-linux* i?86-*-linux-gnu i?86-*-gnu* + +#... +There is no dynamic section in this file. +#... +There are no relocations in this file. +#pass diff --git a/ld/testsuite/ld-elf/dt-relr-1b.d b/ld/testsuite/ld-elf/dt-relr-1b.d new file mode 100644 index 00000000000..2b78f75d378 --- /dev/null +++ b/ld/testsuite/ld-elf/dt-relr-1b.d @@ -0,0 +1,9 @@ +#source: dt-relr-1.s +#ld: -e _start -pie $DT_RELR_LDFLAGS +#readelf: -rW -d +#target: x86_64-*-linux* i?86-*-linux-gnu i?86-*-gnu* + +#failif +#... +Relocation section '\.relr\.dyn' at offset .* +#pass diff --git a/ld/testsuite/ld-elf/dt-relr-1c.d b/ld/testsuite/ld-elf/dt-relr-1c.d new file mode 100644 index 00000000000..14f6cda6832 --- /dev/null +++ b/ld/testsuite/ld-elf/dt-relr-1c.d @@ -0,0 +1,9 @@ +#source: dt-relr-1.s +#ld: -shared $DT_RELR_LDFLAGS +#readelf: -rW -d +#target: x86_64-*-linux* i?86-*-linux-gnu i?86-*-gnu* + +#failif +#... +Relocation section '\.relr\.dyn' at offset .* +#pass diff --git a/ld/testsuite/ld-elf/dt-relr-2.s b/ld/testsuite/ld-elf/dt-relr-2.s new file mode 100644 index 00000000000..c3917ee8c3a --- /dev/null +++ b/ld/testsuite/ld-elf/dt-relr-2.s @@ -0,0 +1,20 @@ + .text + .p2align 3 + .globl _start +_start: + .byte 0 + + .data + .p2align 3 + .globl data +data: + + .dc.a .data + .dc.a 0 + .dc.a data + 2 + .dc.a __ehdr_start + 4 + .dc.a __ehdr_start + 9 + + .byte 0 + // Offset is not a multiple of 2. Don't use DT_RELR. + .dc.a __ehdr_start + 10 diff --git a/ld/testsuite/ld-elf/dt-relr-2a.d b/ld/testsuite/ld-elf/dt-relr-2a.d new file mode 100644 index 00000000000..31ef9e8e80e --- /dev/null +++ b/ld/testsuite/ld-elf/dt-relr-2a.d @@ -0,0 +1,10 @@ +#source: dt-relr-2.s +#ld: -e _start $DT_RELR_LDFLAGS +#readelf: -rW -d +#target: x86_64-*-linux* i?86-*-linux-gnu i?86-*-gnu* + +#... +There is no dynamic section in this file. +#... +There are no relocations in this file. +#pass diff --git a/ld/testsuite/ld-elf/dt-relr-2b.d b/ld/testsuite/ld-elf/dt-relr-2b.d new file mode 100644 index 00000000000..7c401732a56 --- /dev/null +++ b/ld/testsuite/ld-elf/dt-relr-2b.d @@ -0,0 +1,17 @@ +#source: dt-relr-2.s +#ld: -e _start -pie $DT_RELR_LDFLAGS +#readelf: -rW -d +#target: x86_64-*-linux* i?86-*-linux-gnu i?86-*-gnu* + +#... + 0x[0-9a-f]+ \(RELR\) +0x[0-9a-f]+ + 0x[0-9a-f]+ \(RELRSZ\) +(8|16) \(bytes\) + 0x[0-9a-f]+ \(RELRENT\) +(4|8) \(bytes\) +#... +Relocation section '\.rel(a|)\.dyn' at offset 0x[0-9a-f]+ contains 1 entry: +#... +[0-9a-f]+ +[0-9a-f]+ +R_.*_RELATIVE .* +#... +Relocation section '\.relr\.dyn' at offset 0x[0-9a-f]+ contains 2 entries: + 4 offsets +#pass diff --git a/ld/testsuite/ld-elf/dt-relr-2c.d b/ld/testsuite/ld-elf/dt-relr-2c.d new file mode 100644 index 00000000000..63877b2f90f --- /dev/null +++ b/ld/testsuite/ld-elf/dt-relr-2c.d @@ -0,0 +1,17 @@ +#source: dt-relr-2.s +#ld: -shared $DT_RELR_LDFLAGS +#readelf: -rW -d +#target: x86_64-*-linux* i?86-*-linux-gnu i?86-*-gnu* + +#... + 0x[0-9a-f]+ \(RELR\) +0x[0-9a-f]+ + 0x[0-9a-f]+ \(RELRSZ\) +(8|16) \(bytes\) + 0x[0-9a-f]+ \(RELRENT\) +(4|8) \(bytes\) +#... +Relocation section '\.rel(a|)\.dyn' at offset 0x[0-9a-f]+ contains 2 entries: +#... +[0-9a-f]+ +[0-9a-f]+ +R_.*_RELATIVE .* +#... +Relocation section '\.relr\.dyn' at offset 0x[0-9a-f]+ contains 2 entries: + 3 offsets +#pass diff --git a/ld/testsuite/ld-elf/dt-relr-2d.d b/ld/testsuite/ld-elf/dt-relr-2d.d new file mode 100644 index 00000000000..270a901f1a6 --- /dev/null +++ b/ld/testsuite/ld-elf/dt-relr-2d.d @@ -0,0 +1,9 @@ +#source: dt-relr-2.s +#ld: -e _start -pie $DT_RELR_LDFLAGS --no-relax +#readelf: -rW -d +#target: x86_64-*-linux* i?86-*-linux-gnu i?86-*-gnu* + +#failif +#... +Relocation section '\.relr\.dyn' at offset .* +#pass diff --git a/ld/testsuite/ld-elf/dt-relr-2e.d b/ld/testsuite/ld-elf/dt-relr-2e.d new file mode 100644 index 00000000000..79ea62b096a --- /dev/null +++ b/ld/testsuite/ld-elf/dt-relr-2e.d @@ -0,0 +1,9 @@ +#source: dt-relr-2.s +#ld: -e _start -pie $DT_RELR_LDFLAGS -z nocombreloc +#readelf: -rW -d +#target: x86_64-*-linux* i?86-*-linux-gnu i?86-*-gnu* + +#failif +#... +Relocation section '\.relr\.dyn' at offset .* +#pass diff --git a/ld/testsuite/ld-elf/dt-relr-2f.d b/ld/testsuite/ld-elf/dt-relr-2f.d new file mode 100644 index 00000000000..4ad592f71fb --- /dev/null +++ b/ld/testsuite/ld-elf/dt-relr-2f.d @@ -0,0 +1,8 @@ +#source: dt-relr-2.s +#ld: -r $DT_RELR_LDFLAGS +#readelf: -rW +#target: x86_64-*-linux* i?86-*-linux-gnu i?86-*-gnu* + +#... +Relocation section '\.rel(a|)\.data' at offset 0x[0-9a-f]+ contains 5 entries: +#pass diff --git a/ld/testsuite/ld-elf/dt-relr-2g.d b/ld/testsuite/ld-elf/dt-relr-2g.d new file mode 100644 index 00000000000..78e370068af --- /dev/null +++ b/ld/testsuite/ld-elf/dt-relr-2g.d @@ -0,0 +1,9 @@ +#source: dt-relr-2.s +#ld: -e _start -pie $NO_DT_RELR_LDFLAGS +#readelf: -rW -d +#target: x86_64-*-linux* i?86-*-linux-gnu i?86-*-gnu* + +#failif +#... +Relocation section '\.relr\.dyn' at offset .* +#pass diff --git a/ld/testsuite/ld-elf/dt-relr-2h.d b/ld/testsuite/ld-elf/dt-relr-2h.d new file mode 100644 index 00000000000..312373fb179 --- /dev/null +++ b/ld/testsuite/ld-elf/dt-relr-2h.d @@ -0,0 +1,9 @@ +#source: dt-relr-2.s +#ld: -e _start -shared $NO_DT_RELR_LDFLAGS +#readelf: -rW -d +#target: x86_64-*-linux* i?86-*-linux-gnu i?86-*-gnu* + +#failif +#... +Relocation section '\.relr\.dyn' at offset .* +#pass From patchwork Fri Jan 7 19:06:31 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "H.J. Lu" X-Patchwork-Id: 49730 Return-Path: X-Original-To: patchwork@sourceware.org Delivered-To: patchwork@sourceware.org Received: from server2.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id 9F3833858408 for ; Fri, 7 Jan 2022 19:19:00 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 9F3833858408 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=sourceware.org; s=default; t=1641583140; bh=9LfXvAwZ2hsxDofw8tP3fb/eCRwMyjwy0wDOYu1Ff2k=; h=To:Subject:Date:In-Reply-To:References:List-Id:List-Unsubscribe: List-Archive:List-Post:List-Help:List-Subscribe:From:Reply-To:Cc: From; b=dysyNF++TW7/5wlknsx/hUwX/VIAOUyDV0OGUrWEmvtVy0SMTy86KJR8k8WXTKJG5 vgqkIYNOvOkQcrrMwlEpo/0BwL94yrdUUFOQ8/MVCYbwgcUlHb5LuiKV9M6tTKUlQ2 JhHZRBqVnuabCuZOwNdizDEv+BYZZOASQMy4b1/g= X-Original-To: libc-alpha@sourceware.org Delivered-To: libc-alpha@sourceware.org Received: from mail-pg1-x52f.google.com (mail-pg1-x52f.google.com [IPv6:2607:f8b0:4864:20::52f]) by sourceware.org (Postfix) with ESMTPS id BB2DB385800C; Fri, 7 Jan 2022 19:06:36 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.1 sourceware.org BB2DB385800C Received: by mail-pg1-x52f.google.com with SMTP id s1so6204609pga.5; Fri, 07 Jan 2022 11:06:36 -0800 (PST) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=9LfXvAwZ2hsxDofw8tP3fb/eCRwMyjwy0wDOYu1Ff2k=; b=x/47tK1PiY8M8nXov7ir56VHcaAM8Re+QItyBUTFelDwK+AthOtf+DyVBM59RzdxSE IeI6i3+xjqENIhmyEqpm/bKN28CT8afHOswe09MsFgTFSLwKglxBeIXThV65KwuToWr8 7xZTTLWWvcKPwN7pbsM6Gx01juq1LefyTnV+FAzRHCvrAf7haxiUfDZiBPuSS72E4+sc 6Wg13O6lN1XpRxmYRgRbaAudZFBVGCnlUHVdTcusc8ZXSV2x9jrdbbCLmJmJZEdRjn5X XJiFT9jrJKJfEv4LXU6TFu/tcSQpE/WLrunYlNcmPISA/ToavLr/qAIVxFWzXavzXaUl +C5Q== X-Gm-Message-State: AOAM5334fcskl++3Gb9NdjIVX1eIUE9RHhA/FvGCGDeYt3EpKeoZ752+ LlsSB4DzGd+xknkl/NTASEg= X-Google-Smtp-Source: ABdhPJxOb60qQtn1cc6cBhO5u3VG8EllVhDzwrqEmJUsmf7J0Z5dA2r9WcVIoIPq5IcURIlAtXq5qg== X-Received: by 2002:a05:6a00:1582:b0:4ba:e636:391 with SMTP id u2-20020a056a00158200b004bae6360391mr66431879pfk.55.1641582395767; Fri, 07 Jan 2022 11:06:35 -0800 (PST) Received: from gnu-tgl-3.localdomain ([172.58.35.133]) by smtp.gmail.com with ESMTPSA id hk13sm7010658pjb.35.2022.01.07.11.06.34 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 07 Jan 2022 11:06:34 -0800 (PST) Received: from gnu-tgl-3.. (localhost [IPv6:::1]) by gnu-tgl-3.localdomain (Postfix) with ESMTP id 612A7C0EE3; Fri, 7 Jan 2022 11:06:32 -0800 (PST) To: binutils@sourceware.org Subject: [PATCH 10/10] ld: Add glibc dependency for DT_RELR Date: Fri, 7 Jan 2022 11:06:31 -0800 Message-Id: <20220107190631.309790-11-hjl.tools@gmail.com> X-Mailer: git-send-email 2.33.1 In-Reply-To: <20220107190631.309790-1-hjl.tools@gmail.com> References: <20220107190631.309790-1-hjl.tools@gmail.com> MIME-Version: 1.0 X-Spam-Status: No, score=-3028.2 required=5.0 tests=BAYES_00, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, DKIM_VALID_EF, FREEMAIL_FROM, GIT_PATCH_0, RCVD_IN_BARRACUDACENTRAL, RCVD_IN_DNSWL_NONE, SPF_HELO_NONE, SPF_PASS, TXREP, URIBL_BLACK autolearn=ham autolearn_force=no version=3.4.4 X-Spam-Checker-Version: SpamAssassin 3.4.4 (2020-01-24) on server2.sourceware.org X-BeenThere: libc-alpha@sourceware.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Libc-alpha mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-Patchwork-Original-From: "H.J. Lu via Libc-alpha" From: "H.J. Lu" Reply-To: "H.J. Lu" Cc: libc-alpha@sourceware.org, Nick Clifton , Alan Modra Errors-To: libc-alpha-bounces+patchwork=sourceware.org@sourceware.org Sender: "Libc-alpha" When DT_RELR is enabled, to avoid random run-time crash with older glibc binaries without DT_RELR support, add a GLIBC_ABI_DT_RELR symbol version, which is provided by glibc with DT_RELR support, dependency on the shared C library if it provides a GLIBC_2.XX symbol version. bfd/ * elflink.c (elf_link_add_dt_relr_dependency): New function. (bfd_elf_size_dynamic_sections): Call elf_link_add_dt_relr_dependency if DT_RELR is enabled. ld/ * ld.texi: Mention GLIBC_ABI_DT_RELR in -z pack-relative-relocs entry. * testsuite/ld-elf/dt-relr-glibc-1.c: New file. * testsuite/ld-elf/dt-relr-glibc-1a.rd: Likewise. * testsuite/ld-elf/dt-relr-glibc-1b.rd: Likewise. * testsuite/ld-elf/dt-relr.exp: Likewise. --- bfd/elflink.c | 86 +++++++++++++++++++++++++ ld/ld.texi | 4 +- ld/testsuite/ld-elf/dt-relr-glibc-1.c | 11 ++++ ld/testsuite/ld-elf/dt-relr-glibc-1a.rd | 4 ++ ld/testsuite/ld-elf/dt-relr-glibc-1b.rd | 7 ++ ld/testsuite/ld-elf/dt-relr.exp | 44 +++++++++++++ 6 files changed, 155 insertions(+), 1 deletion(-) create mode 100644 ld/testsuite/ld-elf/dt-relr-glibc-1.c create mode 100644 ld/testsuite/ld-elf/dt-relr-glibc-1a.rd create mode 100644 ld/testsuite/ld-elf/dt-relr-glibc-1b.rd create mode 100644 ld/testsuite/ld-elf/dt-relr.exp diff --git a/bfd/elflink.c b/bfd/elflink.c index 31b13f5df7a..05ac1cb7a63 100644 --- a/bfd/elflink.c +++ b/bfd/elflink.c @@ -2213,6 +2213,85 @@ _bfd_elf_export_symbol (struct elf_link_hash_entry *h, void *data) return true; } +/* Return true if GLIBC_ABI_DT_RELR is added to the list of version + dependencies successfully. GLIBC_ABI_DT_RELR will be put into the + .gnu.version_r section. */ + +static bool +elf_link_add_dt_relr_dependency (struct elf_find_verdep_info *rinfo) +{ + bfd *glibc_bfd = NULL; + Elf_Internal_Verneed *t; + Elf_Internal_Vernaux *a; + size_t amt; + const char *relr = "GLIBC_ABI_DT_RELR"; + + /* See if we already know about GLIBC_PRIVATE_DT_RELR. */ + for (t = elf_tdata (rinfo->info->output_bfd)->verref; + t != NULL; + t = t->vn_nextref) + { + const char *soname = bfd_elf_get_dt_soname (t->vn_bfd); + /* Skip the shared library if it isn't libc.so. */ + if (!soname || !startswith (soname, "libc.so.")) + continue; + + for (a = t->vn_auxptr; a != NULL; a = a->vna_nextptr) + { + /* Return if GLIBC_PRIVATE_DT_RELR dependency has been + added. */ + if (a->vna_nodename == relr + || strcmp (a->vna_nodename, relr) == 0) + return true; + + /* Check if libc.so provides GLIBC_2.XX version. */ + if (!glibc_bfd && startswith (a->vna_nodename, "GLIBC_2.")) + glibc_bfd = t->vn_bfd; + } + + break; + } + + /* Skip if it isn't linked against glibc. */ + if (glibc_bfd == NULL) + return true; + + /* This is a new version. Add it to tree we are building. */ + if (t == NULL) + { + amt = sizeof *t; + t = (Elf_Internal_Verneed *) bfd_zalloc (rinfo->info->output_bfd, + amt); + if (t == NULL) + { + rinfo->failed = true; + return false; + } + + t->vn_bfd = glibc_bfd; + t->vn_nextref = elf_tdata (rinfo->info->output_bfd)->verref; + elf_tdata (rinfo->info->output_bfd)->verref = t; + } + + amt = sizeof *a; + a = (Elf_Internal_Vernaux *) bfd_zalloc (rinfo->info->output_bfd, amt); + if (a == NULL) + { + rinfo->failed = true; + return false; + } + + a->vna_nodename = relr; + a->vna_flags = 0; + a->vna_nextptr = t->vn_auxptr; + a->vna_other = rinfo->vers + 1; + ++rinfo->vers; + + t->vn_auxptr = a; + + return true; +} + /* Look through the symbols which are defined in other shared libraries and referenced here. Update the list of version dependencies. This will be put into the .gnu.version_r section. @@ -6940,6 +7019,13 @@ bfd_elf_size_dynamic_sections (bfd *output_bfd, if (sinfo.failed) return false; + if (info->enable_dt_relr) + { + elf_link_add_dt_relr_dependency (&sinfo); + if (sinfo.failed) + return false; + } + if (elf_tdata (output_bfd)->verref == NULL) s->flags |= SEC_EXCLUDE; else diff --git a/ld/ld.texi b/ld/ld.texi index 457089ec06a..a16657ddb45 100644 --- a/ld/ld.texi +++ b/ld/ld.texi @@ -1439,7 +1439,9 @@ and shared library. It adds @code{DT_RELR}, @code{DT_RELRSZ} and building position-dependent executable and relocatable output. This option also implies @option{combreloc} and @option{--relax}. @option{nopack-relative-relocs} is the default, which disables -compact relative relocation. Supported for i386 and x86-64. +compact relative relocation. When linked against the GNU C Library, +a GLIBC_ABI_DT_RELR symbol version dependency on the shared C Library +is added to the output. Supported for i386 and x86-64. @item relro @itemx norelro diff --git a/ld/testsuite/ld-elf/dt-relr-glibc-1.c b/ld/testsuite/ld-elf/dt-relr-glibc-1.c new file mode 100644 index 00000000000..beacffe29e7 --- /dev/null +++ b/ld/testsuite/ld-elf/dt-relr-glibc-1.c @@ -0,0 +1,11 @@ +#define REL(n) \ + static int data##n; \ + void *p##n = &data##n; + +REL(1) +REL(2) +REL(3) +REL(4) +REL(5) +REL(6) +REL(7) diff --git a/ld/testsuite/ld-elf/dt-relr-glibc-1a.rd b/ld/testsuite/ld-elf/dt-relr-glibc-1a.rd new file mode 100644 index 00000000000..51bda5d70a1 --- /dev/null +++ b/ld/testsuite/ld-elf/dt-relr-glibc-1a.rd @@ -0,0 +1,4 @@ +#failif +#... + 0x[a-f0-9]+: Name: GLIBC_ABI_DT_RELR Flags: none Version: [0-9]+ +#... diff --git a/ld/testsuite/ld-elf/dt-relr-glibc-1b.rd b/ld/testsuite/ld-elf/dt-relr-glibc-1b.rd new file mode 100644 index 00000000000..6556a6d939e --- /dev/null +++ b/ld/testsuite/ld-elf/dt-relr-glibc-1b.rd @@ -0,0 +1,7 @@ +#... +Version needs section '.gnu.version_r' contains 1 entry: + Addr: 0x[0-9a-f]+ +Offset: 0x[0-9a-f]+ +Link: +[0-9]+ +\(.dynstr\) + +0+: Version: 1 +File: libc\.so\.6(|\.1) +Cnt: +[0-9]+ +#... + 0x[a-f0-9]+: Name: GLIBC_ABI_DT_RELR Flags: none Version: [0-9]+ +#pass diff --git a/ld/testsuite/ld-elf/dt-relr.exp b/ld/testsuite/ld-elf/dt-relr.exp new file mode 100644 index 00000000000..51d21e400ab --- /dev/null +++ b/ld/testsuite/ld-elf/dt-relr.exp @@ -0,0 +1,44 @@ +# Expect script for DT_RELR. +# Copyright (C) 2022 Free Software Foundation, Inc. +# +# This file is part of the GNU Binutils. +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, +# MA 02110-1301, USA. +# + +# Linux tests. +if { ![istarget "*-*-linux*"] } { + return +} + +run_cc_link_tests [list \ + [list \ + "Build dt-relr-glibc-1a.so" \ + "-shared $NO_DT_RELR_CC_LDFLAGS" \ + "-fPIC" \ + { dt-relr-glibc-1.c } \ + {{readelf {--version-info} dt-relr-glibc-1a.rd}} \ + "glibc-relr-1a.so" \ + ] \ + [list \ + "Build dt-relr-glibc-1b.so" \ + "-shared $DT_RELR_CC_LDFLAGS" \ + "-fPIC" \ + { dt-relr-glibc-1.c } \ + {{readelf {-W --version-info} dt-relr-glibc-1b.rd}} \ + "dt-relr-glibc-1b.so" \ + ] \ +]