* [PATCH v3] PR30592 objcopy: allow --set-section-flags to add or remove SHF_X86_64_LARGE
@ 2023-07-07 5:43 Fangrui Song
2023-07-07 8:24 ` Alan Modra
0 siblings, 1 reply; 2+ messages in thread
From: Fangrui Song @ 2023-07-07 5:43 UTC (permalink / raw)
To: binutils, Jan Beulich; +Cc: Fangrui Song
For example, objcopy --set-section-flags .data=alloc,large will add
SHF_X86_64_LARGE to the .data section. Omitting "large" will drop the
SHF_X86_64_LARGE flag.
The bfd_section flag is named generically, SEC_ELF_LARGE, in case other
processors want to follow SHF_X86_64_LARGE. SEC_ELF_LARGE has the same value
as SEC_TIC54X_CLINK and SEC_MEP_VLIW.
bfd/
* section.c: Define SEC_ELF_LARGE.
* bfd-in2.h: Regenerate.
* elf.c (_bfd_elf_make_section_from_shdr): Check SHF_X86_64_LARGE.
(elf_fake_sections): Check SEC_ELF_LARGE.
(_bfd_elf_init_private_section_data): Drop SHF_X86_64_LARGE for
x86-64 so that objcopy --set-section-flags without 'large'
clears the section flag.
binutils/
* NEWS: Mention the new feature for objcopy.
* doc/binutils.texi: Mention "large".
* objcopy.c (parse_flags): Parse "large".
* testsuite/binutils-all/x86-64/large-sections.d: New.
* testsuite/binutils-all/x86-64/large-sections.s: New.
* testsuite/binutils-all/x86-64/large-sections-2.d: New.
* testsuite/binutils-all/x86-64/large-sections-2.s: New.
include/
* elf/common.h: Define SHF_X86_64_LARGE to be used by elf.c.
--
Changes from v1:
* Add an entry to binutils/NEWS
* Adjust doc/binutils.texi wording
* Guard a SEC_ELF_LARGE branch with EM_X86_64 check
Changes from v2:
* Address Jan's comments https://sourceware.org/pipermail/binutils/2023-July/128303.html
---
bfd/bfd-in2.h | 3 +++
bfd/elf.c | 12 +++++++++++-
bfd/section.c | 3 +++
binutils/NEWS | 3 +++
binutils/doc/binutils.texi | 15 ++++++++-------
binutils/objcopy.c | 4 +++-
.../binutils-all/x86-64/large-sections-2.d | 15 +++++++++++++++
.../binutils-all/x86-64/large-sections-2.s | 4 ++++
.../binutils-all/x86-64/large-sections.d | 14 ++++++++++++++
.../binutils-all/x86-64/large-sections.s | 8 ++++++++
include/elf/common.h | 2 ++
11 files changed, 74 insertions(+), 9 deletions(-)
create mode 100644 binutils/testsuite/binutils-all/x86-64/large-sections-2.d
create mode 100644 binutils/testsuite/binutils-all/x86-64/large-sections-2.s
create mode 100644 binutils/testsuite/binutils-all/x86-64/large-sections.d
create mode 100644 binutils/testsuite/binutils-all/x86-64/large-sections.s
diff --git a/bfd/bfd-in2.h b/bfd/bfd-in2.h
index b34c8ef9fc9..03767efb260 100644
--- a/bfd/bfd-in2.h
+++ b/bfd/bfd-in2.h
@@ -633,6 +633,9 @@ typedef struct bfd_section
/* This section contains vliw code. This is for Toshiba MeP only. */
#define SEC_MEP_VLIW 0x20000000
+ /* This section has the SHF_X86_64_LARGE flag. This is ELF x86-64 only. */
+#define SEC_ELF_LARGE 0x20000000
+
/* All symbols, sizes and relocations in this section are octets
instead of bytes. Required for DWARF debug sections as DWARF
information is organized in octets, not bytes. */
diff --git a/bfd/elf.c b/bfd/elf.c
index d38e0afff2e..fe41798e413 100644
--- a/bfd/elf.c
+++ b/bfd/elf.c
@@ -1045,6 +1045,11 @@ _bfd_elf_make_section_from_shdr (bfd *abfd,
if ((hdr->sh_flags & SHF_EXCLUDE) != 0)
flags |= SEC_EXCLUDE;
+ bed = get_elf_backend_data (abfd);
+ if (bed->elf_machine_code == EM_X86_64 &&
+ (hdr->sh_flags & SHF_X86_64_LARGE) != 0)
+ flags |= SEC_ELF_LARGE;
+
switch (elf_elfheader (abfd)->e_ident[EI_OSABI])
{
/* FIXME: We should not recognize SHF_GNU_MBIND for ELFOSABI_NONE,
@@ -1104,7 +1109,6 @@ _bfd_elf_make_section_from_shdr (bfd *abfd,
if (!bfd_set_section_flags (newsect, flags))
return false;
- bed = get_elf_backend_data (abfd);
if (bed->elf_backend_section_flags)
if (!bed->elf_backend_section_flags (hdr))
return false;
@@ -3912,6 +3916,8 @@ elf_fake_sections (bfd *abfd, asection *asect, void *fsarg)
}
if ((asect->flags & (SEC_GROUP | SEC_EXCLUDE)) == SEC_EXCLUDE)
this_hdr->sh_flags |= SHF_EXCLUDE;
+ if (bed->elf_machine_code == EM_X86_64 && (asect->flags & SEC_ELF_LARGE) != 0)
+ this_hdr->sh_flags |= SHF_X86_64_LARGE;
/* If the section has relocs, set up a section header for the
SHT_REL[A] section. If two relocation sections are required for
@@ -8508,6 +8514,10 @@ _bfd_elf_init_private_section_data (bfd *ibfd,
elf_section_flags (osec) = (elf_section_flags (isec)
& (SHF_MASKOS | SHF_MASKPROC));
+ /* objcopy --set-section-flags without "large" drops SHF_X86_64_LARGE. */
+ if (get_elf_backend_data (ibfd)->elf_machine_code == EM_X86_64)
+ elf_section_flags (osec) = (elf_section_flags (isec) & ~SHF_X86_64_LARGE);
+
/* Copy sh_info from input for mbind section. */
if ((elf_tdata (ibfd)->has_gnu_osabi & elf_gnu_osabi_mbind) != 0
&& elf_section_flags (isec) & SHF_GNU_MBIND)
diff --git a/bfd/section.c b/bfd/section.c
index 73770294e56..b7c771b4fb8 100644
--- a/bfd/section.c
+++ b/bfd/section.c
@@ -367,6 +367,9 @@ CODE_FRAGMENT
. {* This section contains vliw code. This is for Toshiba MeP only. *}
.#define SEC_MEP_VLIW 0x20000000
.
+. {* This section has the SHF_X86_64_LARGE flag. This is ELF x86-64 only. *}
+.#define SEC_ELF_LARGE 0x20000000
+.
. {* All symbols, sizes and relocations in this section are octets
. instead of bytes. Required for DWARF debug sections as DWARF
. information is organized in octets, not bytes. *}
diff --git a/binutils/NEWS b/binutils/NEWS
index 563062c6904..cad877b943a 100644
--- a/binutils/NEWS
+++ b/binutils/NEWS
@@ -1,5 +1,8 @@
-*- text -*-
+* objcopy's --set-section-flags now support "large" to set SHF_X86_64_LARGE
+ for ELF x86-64 objects.
+
Changes in 2.41:
* The MIPS port now supports the Sony Interactive Entertainment Allegrex
diff --git a/binutils/doc/binutils.texi b/binutils/doc/binutils.texi
index 8314cb57562..309bedf6110 100644
--- a/binutils/doc/binutils.texi
+++ b/binutils/doc/binutils.texi
@@ -1745,13 +1745,14 @@ Set the flags for any sections matching @var{sectionpattern}. The
@var{flags} argument is a comma separated string of flag names. The
recognized names are @samp{alloc}, @samp{contents}, @samp{load},
@samp{noload}, @samp{readonly}, @samp{code}, @samp{data}, @samp{rom},
-@samp{exclude}, @samp{share}, and @samp{debug}. You can set the
-@samp{contents} flag for a section which does not have contents, but it
-is not meaningful to clear the @samp{contents} flag of a section which
-does have contents--just remove the section instead. Not all flags are
-meaningful for all object file formats. In particular the
-@samp{share} flag is only meaningful for COFF format files and not for
-ELF format files.
+@samp{exclude}, @samp{share}, @samp{debug}, and @samp{large}.
+You can set the @samp{contents} flag for a section which does not have
+contents, but it is not meaningful to clear the @samp{contents} flag of a
+section which does have contents--just remove the section instead. Not all
+flags are meaningful for all object file formats. In particular the
+@samp{share} flag is only meaningful for COFF format files and not for ELF
+format files. The ELF x86-64 specific flag @samp{large} corresponds to
+SHF_X86_64_LARGE.
@item --set-section-alignment @var{sectionpattern}=@var{align}
Set the alignment for any sections matching @var{sectionpattern}.
diff --git a/binutils/objcopy.c b/binutils/objcopy.c
index 3569b890c7d..cb0d44ec0f4 100644
--- a/binutils/objcopy.c
+++ b/binutils/objcopy.c
@@ -803,6 +803,7 @@ parse_flags (const char *s)
PARSE_FLAG ("contents", SEC_HAS_CONTENTS);
PARSE_FLAG ("merge", SEC_MERGE);
PARSE_FLAG ("strings", SEC_STRINGS);
+ PARSE_FLAG ("large", SEC_ELF_LARGE);
#undef PARSE_FLAG
else
{
@@ -813,7 +814,8 @@ parse_flags (const char *s)
copy[len] = '\0';
non_fatal (_("unrecognized section flag `%s'"), copy);
fatal (_("supported flags: %s"),
- "alloc, load, noload, readonly, debug, code, data, rom, exclude, share, contents, merge, strings");
+ "alloc, load, noload, readonly, debug, code, data, rom, exclude, "
+ "share, contents, merge, strings, (ELF x86-64 specific) large");
}
s = snext;
diff --git a/binutils/testsuite/binutils-all/x86-64/large-sections-2.d b/binutils/testsuite/binutils-all/x86-64/large-sections-2.d
new file mode 100644
index 00000000000..29ace42cc9e
--- /dev/null
+++ b/binutils/testsuite/binutils-all/x86-64/large-sections-2.d
@@ -0,0 +1,15 @@
+#source: large-sections.s
+#PROG: objcopy
+#as: --64
+#objcopy: --set-section-flags .ldata=alloc
+#readelf: -S -W
+
+#...
+ \[[ 0-9]+\] \.text.*[ \t]+PROGBITS[ \t0-9a-f]+AX[ \t]+.*
+#...
+ \[[ 0-9]+\] \.data.*[ \t]+PROGBITS[ \t0-9a-f]+WA[ \t]+.*
+#...
+ \[[ 0-9]+\] \.ltext.*[ \t]+PROGBITS[ \t0-9a-f]+AXl[ \t]+.*
+#...
+ \[[ 0-9]+\] \.ldata.*[ \t]+PROGBITS[ \t0-9a-f]+WA[ \t]+.*
+#pass
diff --git a/binutils/testsuite/binutils-all/x86-64/large-sections-2.s b/binutils/testsuite/binutils-all/x86-64/large-sections-2.s
new file mode 100644
index 00000000000..6f31aa93701
--- /dev/null
+++ b/binutils/testsuite/binutils-all/x86-64/large-sections-2.s
@@ -0,0 +1,4 @@
+ .section .text, "axl"
+ nop
+ .section .data, "awl"
+ .byte 1
diff --git a/binutils/testsuite/binutils-all/x86-64/large-sections.d b/binutils/testsuite/binutils-all/x86-64/large-sections.d
new file mode 100644
index 00000000000..5d945e46ba3
--- /dev/null
+++ b/binutils/testsuite/binutils-all/x86-64/large-sections.d
@@ -0,0 +1,14 @@
+#PROG: objcopy
+#as: --64
+#objcopy: --set-section-flags .text=alloc,readonly,code,large --set-section-flags .data=alloc,large
+#readelf: -S -W
+
+#...
+ \[[ 0-9]+\] \.text.*[ \t]+PROGBITS[ \t0-9a-f]+AXl[ \t]+.*
+#...
+ \[[ 0-9]+\] \.data.*[ \t]+PROGBITS[ \t0-9a-f]+WAl[ \t]+.*
+#...
+ \[[ 0-9]+\] \.ltext.*[ \t]+PROGBITS[ \t0-9a-f]+AXl[ \t]+.*
+#...
+ \[[ 0-9]+\] \.ldata.*[ \t]+PROGBITS[ \t0-9a-f]+WAl[ \t]+.*
+#pass
diff --git a/binutils/testsuite/binutils-all/x86-64/large-sections.s b/binutils/testsuite/binutils-all/x86-64/large-sections.s
new file mode 100644
index 00000000000..072e456a1ed
--- /dev/null
+++ b/binutils/testsuite/binutils-all/x86-64/large-sections.s
@@ -0,0 +1,8 @@
+ .section .text, "ax"
+ nop
+ .section .data, "aw"
+ .byte 1
+ .section .ltext, "axl"
+ nop
+ .section .ldata, "awl"
+ .byte 1
diff --git a/include/elf/common.h b/include/elf/common.h
index ffa6b60bd2b..1397d60402e 100644
--- a/include/elf/common.h
+++ b/include/elf/common.h
@@ -588,6 +588,8 @@
#define SHF_GNU_MBIND 0x01000000 /* Mbind section. */
+#define SHF_X86_64_LARGE 0x10000000
+
/* Compression types. */
#define ELFCOMPRESS_ZLIB 1 /* Compressed with zlib. */
#define ELFCOMPRESS_ZSTD 2 /* Compressed with zstd */
--
2.41.0.255.g8b1d071c50-goog
^ permalink raw reply [flat|nested] 2+ messages in thread
* Re: [PATCH v3] PR30592 objcopy: allow --set-section-flags to add or remove SHF_X86_64_LARGE
2023-07-07 5:43 [PATCH v3] PR30592 objcopy: allow --set-section-flags to add or remove SHF_X86_64_LARGE Fangrui Song
@ 2023-07-07 8:24 ` Alan Modra
0 siblings, 0 replies; 2+ messages in thread
From: Alan Modra @ 2023-07-07 8:24 UTC (permalink / raw)
To: Fangrui Song; +Cc: binutils, Jan Beulich
On Thu, Jul 06, 2023 at 10:43:06PM -0700, Fangrui Song via Binutils wrote:
> include/
> * elf/common.h: Define SHF_X86_64_LARGE to be used by elf.c.
Don't do this.
> --- a/bfd/elf.c
> +++ b/bfd/elf.c
> @@ -1045,6 +1045,11 @@ _bfd_elf_make_section_from_shdr (bfd *abfd,
> if ((hdr->sh_flags & SHF_EXCLUDE) != 0)
> flags |= SEC_EXCLUDE;
>
> + bed = get_elf_backend_data (abfd);
> + if (bed->elf_machine_code == EM_X86_64 &&
> + (hdr->sh_flags & SHF_X86_64_LARGE) != 0)
> + flags |= SEC_ELF_LARGE;
Or this. Instead write an elf_backend_section_flags for x86_64.
> @@ -3912,6 +3916,8 @@ elf_fake_sections (bfd *abfd, asection *asect, void *fsarg)
> }
> if ((asect->flags & (SEC_GROUP | SEC_EXCLUDE)) == SEC_EXCLUDE)
> this_hdr->sh_flags |= SHF_EXCLUDE;
> + if (bed->elf_machine_code == EM_X86_64 && (asect->flags & SEC_ELF_LARGE) != 0)
> + this_hdr->sh_flags |= SHF_X86_64_LARGE;
>
Or this. Instead write elf_backend_fake_sections for x86_64.
> /* If the section has relocs, set up a section header for the
> SHT_REL[A] section. If two relocation sections are required for
> @@ -8508,6 +8514,10 @@ _bfd_elf_init_private_section_data (bfd *ibfd,
> elf_section_flags (osec) = (elf_section_flags (isec)
> & (SHF_MASKOS | SHF_MASKPROC));
>
> + /* objcopy --set-section-flags without "large" drops SHF_X86_64_LARGE. */
> + if (get_elf_backend_data (ibfd)->elf_machine_code == EM_X86_64)
> + elf_section_flags (osec) = (elf_section_flags (isec) & ~SHF_X86_64_LARGE);
> +
> /* Copy sh_info from input for mbind section. */
> if ((elf_tdata (ibfd)->has_gnu_osabi & elf_gnu_osabi_mbind) != 0
> && elf_section_flags (isec) & SHF_GNU_MBIND)
And this should be done in a bfd_elf64_bfd_copy_private_symbol_data
for x86_64.
--
Alan Modra
Australia Development Lab, IBM
^ permalink raw reply [flat|nested] 2+ messages in thread
end of thread, other threads:[~2023-07-07 8:24 UTC | newest]
Thread overview: 2+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2023-07-07 5:43 [PATCH v3] PR30592 objcopy: allow --set-section-flags to add or remove SHF_X86_64_LARGE Fangrui Song
2023-07-07 8:24 ` Alan Modra
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).