From patchwork Tue Mar 31 18:15:27 2026 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "H.J. Lu" X-Patchwork-Id: 132539 Return-Path: X-Original-To: patchwork@sourceware.org Delivered-To: patchwork@sourceware.org Received: from vm01.sourceware.org (localhost [127.0.0.1]) by sourceware.org (Postfix) with ESMTP id E8AB04B7A1F8 for ; Tue, 31 Mar 2026 18:16:13 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org E8AB04B7A1F8 Authentication-Results: sourceware.org; dkim=pass (2048-bit key, unprotected) header.d=gmail.com header.i=@gmail.com header.a=rsa-sha256 header.s=20251104 header.b=NPXDgvnW X-Original-To: binutils@sourceware.org Delivered-To: binutils@sourceware.org Received: from mail-dl1-x122f.google.com (mail-dl1-x122f.google.com [IPv6:2607:f8b0:4864:20::122f]) by sourceware.org (Postfix) with ESMTPS id D86674BA23EA for ; Tue, 31 Mar 2026 18:15:35 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.2 sourceware.org D86674BA23EA Authentication-Results: sourceware.org; dmarc=pass (p=none dis=none) header.from=gmail.com Authentication-Results: sourceware.org; spf=pass smtp.mailfrom=gmail.com ARC-Filter: OpenARC Filter v1.0.0 sourceware.org D86674BA23EA Authentication-Results: server2.sourceware.org; arc=none smtp.remote-ip=2607:f8b0:4864:20::122f ARC-Seal: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1774980936; cv=none; b=cP1wz+nR+JdtS8Pm90sn+G+CQQLwQYTfSYQi59Saxtyvd9RDf/Bt/yD8oyd6FYikuCK0gHpy6Ig6HhgQAu81dCx3Gr97QTHU/+w9Fv23g4eKGZNhHRNeHgSOEoFPFIX73VQdxNWB9+duzvXmpdejVNwkp7LDcNf0IzGhZYxp6Ng= ARC-Message-Signature: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1774980936; c=relaxed/simple; bh=9BobzC3oRF/98J8sEa54JQwvwu3hPfQZN0gWJVIHP2A=; h=DKIM-Signature:From:To:Subject:Date:Message-ID:MIME-Version; b=pfi0j06tjIwafrcQ1dlD+5tTnZiGXZ3+ktcDMgXf0ix6V5zVGcY0t07+SNOhzDb5rTmQSgUQU3Mf7N7z2a3WWFBvMmHzDXLm5DKv9z5u6OxE2ze/jbp7j0NuI+/a8UWZHUUX4SYQJxDfLbCqPjft1pxaJ4xDN4kvUSJDAf9D6mc= ARC-Authentication-Results: i=1; server2.sourceware.org DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org D86674BA23EA Received: by mail-dl1-x122f.google.com with SMTP id a92af1059eb24-12a80c36350so6403956c88.1 for ; Tue, 31 Mar 2026 11:15:35 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20251104; t=1774980935; x=1775585735; darn=sourceware.org; h=content-transfer-encoding:mime-version:message-id:date:subject:cc :to:from:from:to:cc:subject:date:message-id:reply-to; bh=QuLBmfosm49cW5ezb0RMzjjcvFNixwLq9b9mCfep+0E=; b=NPXDgvnWgqY74SbmlRpCp8zfOrEs2EX2ql822Sj5DQTLYNpGCeh1T/FSTt78cvdRzR r5w8ZUZtQeF9AEoXmfxhf03Hm9oQp/R0CoG3WxFTYK6n2OQyi8orjS/JhDUPG3aS+lUE gdSaPcMi3Ly+IbcVwVBwaEeCCzutOVa5wrQnX6gJRrrwEbMxgFSbxPcGWL142kFEDzlR o2iKEAVHQOgmiwE2vNMe+loEV844L7Q+upIagca9Cfq66rnrgRi1rK2qnmCbtGedmEHQ 8FK6TNblzKm5RlqsfYvom3YhMZoEfhdecBSjG2v3MxlfC9qJ7fmYdZxyqcz0KJK+XG3Y fFnA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1774980935; x=1775585735; h=content-transfer-encoding:mime-version:message-id:date:subject:cc :to:from:x-gm-gg:x-gm-message-state:from:to:cc:subject:date :message-id:reply-to; bh=QuLBmfosm49cW5ezb0RMzjjcvFNixwLq9b9mCfep+0E=; b=RHK33o3+6QH0LwiI/ihbXnT0pckCYkmruGMJ8oIQJwVO43s21E9iig6uYiKu13FvRQ V7C9Ur0ZonOxLlMIvKIiagp5I3sj1SBs9cj+xAQwsb8ca46qd0A9M/G94UqUI2LNKFGK sqiihIiQxz2Z8AKsT0PwNZ5d5o295sRIZlLP2C9DJZcWt6Q0Emhu6CraKKRJDAhyjVX6 HzOPN11UaSgzc8r/gdtIcw6APkeN+MaLZZ3qQa+o4MyIcS0h5ugTMA3GZn4sYEqbXjMK 5tyqxi1GnRTMamqIC5c17yyUDL89nsIeF02hATU6gM+OTUYnbagFnJxoCW5J6z7Y5Noj tQgg== X-Gm-Message-State: AOJu0Yzn6CgjKCczcW4g6MxdzSD//UCMEx8TXXEqBvK8QO396Sg8mr5l s0GIpF8WypHWqtzF1FXMvlenVpsrFJdh1CObKxyQEsf6nXzOpX76z4WvFEkrxA== X-Gm-Gg: ATEYQzxQJMM6RszKUI5H23uTmQ4fhLm0TZT5YWx/uoHJD6XsUm+9pD5fq8m4iXD1G5i x3KB/dw1attIt5eCAdHD+j1ZcsHSyOs9GqSxsbTnKUHMmeAwFo74tIo2B6te4C21X2ugMSXt87p v29J4mDPN6PhoUSq7DT3NNRkbRaiqT9XwHMfTcyqtUC1m/R2+JZRv2hcD8twUjXg6FeUWhkchTl x66kgOVoz38d/X2LG0sx3/nVWNmweWghsCAkD1Sn74EehNWiucUuKVFh+q37VGuPgs1j3ERB/Zo OZaySBKK+0fjRaxbbS4a6fTmPX/tz63aggGL/0dVjFgX6kKLMCxjVps4li7oWniSSP3frEw/5dn ZFG8zyG+9JuOdo4ia5R1o+G/AhANNogycQyfS12PZGEHC0hCnBSXrJQp4fjHWIWjD3DIwlMmNlC xndj69xpdKU1w2BGMs8ncM2jnGTFai1sEyxOMEJjg= X-Received: by 2002:a05:7022:398:b0:128:d967:4673 with SMTP id a92af1059eb24-12be6442901mr273218c88.16.1774980934489; Tue, 31 Mar 2026 11:15:34 -0700 (PDT) Received: from gnu-tgl-3.localdomain ([172.59.163.89]) by smtp.gmail.com with ESMTPSA id a92af1059eb24-12abde65313sm10232848c88.14.2026.03.31.11.15.33 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 31 Mar 2026 11:15:33 -0700 (PDT) Received: from gnu-tgl-3.localdomain (localhost [127.0.0.1]) by gnu-tgl-3.localdomain (Postfix) with ESMTP id D60B0C0610; Tue, 31 Mar 2026 11:15:32 -0700 (PDT) From: "H.J. Lu" To: binutils@sourceware.org Cc: nickc@redhat.com, amodra@gmail.com, jbeulich@suse.com Subject: [PATCH] ld: Handle special ELF readonly output sections Date: Tue, 31 Mar 2026 11:15:27 -0700 Message-ID: <20260331181527.884535-1-hjl.tools@gmail.com> X-Mailer: git-send-email 2.53.0 MIME-Version: 1.0 X-Spam-Status: No, score=-3013.6 required=5.0 tests=BAYES_00, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, DKIM_VALID_EF, FREEMAIL_FROM, GIT_PATCH_0, RCVD_IN_DNSWL_BLOCKED, SPF_HELO_NONE, SPF_PASS, TXREP autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on sourceware.org X-BeenThere: binutils@sourceware.org X-Mailman-Version: 2.1.30 Precedence: list List-Id: Binutils mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: binutils-bounces~patchwork=sourceware.org@sourceware.org There are many special ELF sections which should be readonly. But output sections created in linker script won't set the SEC_READONLY if they aren't marked with READONLY. Add bfd_is_special_readonly_section to return true if a section name is a special ELF readonly section and use it when creating output sections. bfd/ PR ld/34024 * bfd-in2.h: Regenerated. * bfd.c (bfd_is_special_readonly_section): New function. * elf-bfd.h (elf_backend_data): Add is_special_readonly_section. (_bfd_elf_is_special_readonly_section): New prototype. * elf.c (elf_get_special_section): New function. (_bfd_elf_get_sec_type_attr): Call elf_get_special_section. (_bfd_elf_is_special_readonly_section): New function. * elfxx-target.h (elf_backend_is_special_readonly_section): New. (elfNN_bed): Add elf_backend_is_special_readonly_section. ld/ PR ld/34024 * ldlang.c (get_os_init_flag): Return SEC_READONLY if the output section is a special readonly section. * testsuite/ld-elf/flags2.d: New file. * testsuite/ld-elf/flags2.ld: Likewise. * testsuite/ld-elf/flags2.s: Likewise. Signed-off-by: H.J. Lu --- bfd/bfd-in2.h | 2 ++ bfd/bfd.c | 24 ++++++++++++++++++++++++ bfd/elf-bfd.h | 7 +++++++ bfd/elf.c | 35 ++++++++++++++++++++++++++--------- bfd/elfxx-target.h | 5 +++++ ld/ldlang.c | 5 ++++- ld/testsuite/ld-elf/flags2.d | 9 +++++++++ ld/testsuite/ld-elf/flags2.ld | 1 + ld/testsuite/ld-elf/flags2.s | 6 ++++++ 9 files changed, 84 insertions(+), 10 deletions(-) create mode 100644 ld/testsuite/ld-elf/flags2.d create mode 100644 ld/testsuite/ld-elf/flags2.ld create mode 100644 ld/testsuite/ld-elf/flags2.s diff --git a/bfd/bfd-in2.h b/bfd/bfd-in2.h index 0b934005f9d..70659dfe824 100644 --- a/bfd/bfd-in2.h +++ b/bfd/bfd-in2.h @@ -2818,6 +2818,8 @@ char *bfd_demangle (bfd *, const char *, int); asymbol *bfd_group_signature (asection *group, asymbol **isympp); +bool bfd_is_special_readonly_section (bfd *abfd, const char *name); + /* Extracted from bfdio.c. */ bfd_size_type bfd_read (void *, bfd_size_type, bfd *) ATTRIBUTE_WARN_UNUSED_RESULT; diff --git a/bfd/bfd.c b/bfd/bfd.c index 31c70890ad9..a198eb8002f 100644 --- a/bfd/bfd.c +++ b/bfd/bfd.c @@ -3133,3 +3133,27 @@ bfd_group_signature (asection *group, asymbol **isympp) } return NULL; } + +/* +FUNCTION + bfd_is_special_readonly_section + +SYNOPSIS + bool bfd_is_special_readonly_section (bfd *abfd, const char *name); + +DESCRIPTION + Return true if the BFD section of NAME is a special readonly + section. +*/ + +bool +bfd_is_special_readonly_section (bfd *abfd, const char *name) +{ + if (bfd_get_flavour (abfd) == bfd_target_elf_flavour) + { + elf_backend_data *bed = get_elf_backend_data (abfd); + return bed->is_special_readonly_section (abfd, name); + } + + return false; +} diff --git a/bfd/elf-bfd.h b/bfd/elf-bfd.h index 3d2fad49aa4..cb4745166de 100644 --- a/bfd/elf-bfd.h +++ b/bfd/elf-bfd.h @@ -1127,6 +1127,11 @@ struct elf_backend_data const struct bfd_elf_special_section * (*get_sec_type_attr) (bfd *, asection *); + /* A function that returns true if the given BFD section of name + is a special readonly section. */ + bool (*is_special_readonly_section) + (bfd *, const char*); + /* A function to handle unusual program segment types when creating BFD sections from ELF program segments. */ bool (*elf_backend_section_from_phdr) @@ -2542,6 +2547,8 @@ extern const struct bfd_elf_special_section *_bfd_elf_get_special_section ATTRIBUTE_HIDDEN; extern const struct bfd_elf_special_section *_bfd_elf_get_sec_type_attr (bfd *, asection *) ATTRIBUTE_HIDDEN; +extern bool _bfd_elf_is_special_readonly_section + (bfd *, const char *) ATTRIBUTE_HIDDEN; extern bool _bfd_elf_link_hide_sym_by_version (struct bfd_link_info *, struct elf_link_hash_entry *) ATTRIBUTE_HIDDEN; diff --git a/bfd/elf.c b/bfd/elf.c index 5f02188b4b5..db7c5620337 100644 --- a/bfd/elf.c +++ b/bfd/elf.c @@ -3275,32 +3275,31 @@ _bfd_elf_get_special_section (const char *name, return NULL; } -const struct bfd_elf_special_section * -_bfd_elf_get_sec_type_attr (bfd *abfd, asection *sec) +static const struct bfd_elf_special_section * +elf_get_special_section (bfd *abfd, const char *name, + unsigned int use_rela_p) { int i; const struct bfd_elf_special_section *spec; elf_backend_data *bed; /* See if this is one of the special sections. */ - if (sec->name == NULL) + if (name == NULL) return NULL; bed = get_elf_backend_data (abfd); spec = bed->special_sections; if (spec) { - spec = _bfd_elf_get_special_section (sec->name, - bed->special_sections, - sec->use_rela_p); + spec = _bfd_elf_get_special_section (name, spec, use_rela_p); if (spec != NULL) return spec; } - if (sec->name[0] != '.') + if (name[0] != '.') return NULL; - i = sec->name[1] - 'b'; + i = name[1] - 'b'; if (i < 0 || i > 'z' - 'b') return NULL; @@ -3309,7 +3308,25 @@ _bfd_elf_get_sec_type_attr (bfd *abfd, asection *sec) if (spec == NULL) return NULL; - return _bfd_elf_get_special_section (sec->name, spec, sec->use_rela_p); + return _bfd_elf_get_special_section (name, spec, use_rela_p); +} + +const struct bfd_elf_special_section * +_bfd_elf_get_sec_type_attr (bfd *abfd, asection *sec) +{ + return elf_get_special_section (abfd, sec->name, sec->use_rela_p); +} + +bool +_bfd_elf_is_special_readonly_section (bfd *abfd, const char *name) +{ + elf_backend_data *bed; + const struct bfd_elf_special_section *spec; + bed = get_elf_backend_data (abfd); + spec = elf_get_special_section (abfd, name, bed->default_use_rela_p); + if (spec == NULL) + return false; + return (spec->attr & SHF_WRITE) == 0; } bool diff --git a/bfd/elfxx-target.h b/bfd/elfxx-target.h index 124be5ed0c4..580276a543b 100644 --- a/bfd/elfxx-target.h +++ b/bfd/elfxx-target.h @@ -443,6 +443,10 @@ #ifndef elf_backend_get_sec_type_attr #define elf_backend_get_sec_type_attr _bfd_elf_get_sec_type_attr #endif +#ifndef elf_backend_is_special_readonly_section +#define elf_backend_is_special_readonly_section \ + _bfd_elf_is_special_readonly_section +#endif #ifndef elf_backend_section_from_phdr #define elf_backend_section_from_phdr _bfd_elf_make_section_from_phdr #endif @@ -872,6 +876,7 @@ static const struct elf_backend_data elfNN_bed = elf_backend_section_from_shdr, elf_backend_section_flags, elf_backend_get_sec_type_attr, + elf_backend_is_special_readonly_section, elf_backend_section_from_phdr, elf_backend_fake_sections, elf_backend_section_from_bfd_section, diff --git a/ld/ldlang.c b/ld/ldlang.c index 656edeb4981..b6d19e95401 100644 --- a/ld/ldlang.c +++ b/ld/ldlang.c @@ -2604,7 +2604,10 @@ get_os_init_flag (lang_output_section_statement_type * os) { case readonly_section: return SEC_READONLY; case noload_section: return SEC_NEVER_LOAD; - default: break; + default: + if (bfd_is_special_readonly_section (link_info.output_bfd, + os->name)) + return SEC_READONLY; } return 0; diff --git a/ld/testsuite/ld-elf/flags2.d b/ld/testsuite/ld-elf/flags2.d new file mode 100644 index 00000000000..5fc8571d9dc --- /dev/null +++ b/ld/testsuite/ld-elf/flags2.d @@ -0,0 +1,9 @@ +#name: .rodata section attributes +#ld: -Tflags2.ld +#readelf: -S --wide + +#... +Section Headers: +#... + \[[ 0-9]+\] \.rodata.*[ \t]+PROGBITS[ \t0-9a-f]+ A .* +#pass diff --git a/ld/testsuite/ld-elf/flags2.ld b/ld/testsuite/ld-elf/flags2.ld new file mode 100644 index 00000000000..90eeca713e7 --- /dev/null +++ b/ld/testsuite/ld-elf/flags2.ld @@ -0,0 +1 @@ +SECTIONS { .rodata : ALIGN(4) { __crc_hello = .; LONG(0x05d25769); } } diff --git a/ld/testsuite/ld-elf/flags2.s b/ld/testsuite/ld-elf/flags2.s new file mode 100644 index 00000000000..c5dbfbf0a2f --- /dev/null +++ b/ld/testsuite/ld-elf/flags2.s @@ -0,0 +1,6 @@ + .text + .globl start + .type start, %function +start: + .byte 0 + .section .note.GNU-stack, "", %progbits