mirror of
https://github.com/bminor/binutils-gdb.git
synced 2025-12-06 15:43:09 +00:00
gas/ELF: allow specifying entity size for arbitrary sections
The spec doesn't tie entity size to just SHF_MERGE and SHF_STRINGS sections. Introduce a new "section letter" 'E' to allow recording (and checking) of entity size even without 'M' or 'S'.
This commit is contained in:
15
bfd/elf.c
15
bfd/elf.c
@@ -869,20 +869,16 @@ _bfd_elf_make_section_from_shdr (bfd *abfd,
|
||||
else if ((flags & SEC_LOAD) != 0)
|
||||
flags |= SEC_DATA;
|
||||
if ((hdr->sh_flags & SHF_MERGE) != 0)
|
||||
{
|
||||
flags |= SEC_MERGE;
|
||||
newsect->entsize = hdr->sh_entsize;
|
||||
}
|
||||
flags |= SEC_MERGE;
|
||||
if ((hdr->sh_flags & SHF_STRINGS) != 0)
|
||||
{
|
||||
flags |= SEC_STRINGS;
|
||||
newsect->entsize = hdr->sh_entsize;
|
||||
}
|
||||
flags |= SEC_STRINGS;
|
||||
if ((hdr->sh_flags & SHF_TLS) != 0)
|
||||
flags |= SEC_THREAD_LOCAL;
|
||||
if ((hdr->sh_flags & SHF_EXCLUDE) != 0)
|
||||
flags |= SEC_EXCLUDE;
|
||||
|
||||
newsect->entsize = hdr->sh_entsize;
|
||||
|
||||
switch (elf_elfheader (abfd)->e_ident[EI_OSABI])
|
||||
{
|
||||
/* FIXME: We should not recognize SHF_GNU_MBIND for ELFOSABI_NONE,
|
||||
@@ -3770,6 +3766,9 @@ 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 (this_hdr->sh_entsize == 0)
|
||||
this_hdr->sh_entsize = asect->entsize;
|
||||
|
||||
/* If the section has relocs, set up a section header for the
|
||||
SHT_REL[A] section. If two relocation sections are required for
|
||||
this section, it is up to the processor-specific back-end to
|
||||
|
||||
3
gas/NEWS
3
gas/NEWS
@@ -1,5 +1,8 @@
|
||||
-*- text -*-
|
||||
|
||||
* ELF targets can now have section entity size specified for arbitrary
|
||||
sections, using the new attribute letter 'E'.
|
||||
|
||||
* NaCl target support is removed.
|
||||
|
||||
Changes in 2.45:
|
||||
|
||||
@@ -792,7 +792,7 @@ change_section (const char *name,
|
||||
= match_p->linked_to_symbol_name;
|
||||
|
||||
bfd_set_section_flags (sec, flags);
|
||||
if (flags & (SEC_MERGE | SEC_STRINGS))
|
||||
if (entsize != 0)
|
||||
sec->entsize = entsize;
|
||||
elf_group_name (sec) = match_p->group_name;
|
||||
|
||||
@@ -847,7 +847,7 @@ change_section (const char *name,
|
||||
processor or application specific attribute as suspicious? */
|
||||
elf_section_flags (sec) = attr;
|
||||
|
||||
if ((flags & (SEC_MERGE | SEC_STRINGS))
|
||||
if (entsize != 0
|
||||
&& old_sec->entsize != (unsigned) entsize)
|
||||
as_bad (_("changed section entity size for %s"), name);
|
||||
}
|
||||
@@ -871,7 +871,8 @@ obj_elf_change_section (const char *name,
|
||||
|
||||
static bfd_vma
|
||||
obj_elf_parse_section_letters (char *str, size_t len, bool push,
|
||||
bool *is_clone, int *inherit, bfd_vma *gnu_attr)
|
||||
bool *is_clone, int *inherit, bfd_vma *gnu_attr,
|
||||
bool *has_entsize)
|
||||
{
|
||||
bfd_vma attr = 0;
|
||||
|
||||
@@ -913,6 +914,9 @@ obj_elf_parse_section_letters (char *str, size_t len, bool push,
|
||||
case 'x':
|
||||
attr |= SHF_EXECINSTR;
|
||||
break;
|
||||
case 'E':
|
||||
*has_entsize = true;
|
||||
break;
|
||||
case 'G':
|
||||
attr |= SHF_GROUP;
|
||||
break;
|
||||
@@ -978,8 +982,8 @@ obj_elf_parse_section_letters (char *str, size_t len, bool push,
|
||||
{
|
||||
as_bad (_("unrecognized .%ssection attribute: want %s%s%s,? or number"),
|
||||
push ? "push" : "",
|
||||
gnu_attr != NULL ? "a,d,e,o,w,x,G,M,R,S,T"
|
||||
: "a,e,o,w,x,G,M,S,T",
|
||||
gnu_attr != NULL ? "a,d,e,o,w,x,E,G,M,R,S,T"
|
||||
: "a,e,o,w,x,E,G,M,S,T",
|
||||
md_extra != NULL ? "," : "", md_extra);
|
||||
return attr;
|
||||
}
|
||||
@@ -1187,7 +1191,7 @@ obj_elf_section (int push)
|
||||
bfd_vma attr;
|
||||
bfd_vma gnu_attr;
|
||||
int entsize;
|
||||
bool linkonce;
|
||||
bool linkonce, has_entsize;
|
||||
subsegT new_subsection = 0;
|
||||
struct elf_section_match match;
|
||||
unsigned long linked_to_section_index = -1UL;
|
||||
@@ -1232,6 +1236,7 @@ obj_elf_section (int push)
|
||||
attr = 0;
|
||||
gnu_attr = 0;
|
||||
entsize = 0;
|
||||
has_entsize = false;
|
||||
linkonce = 0;
|
||||
|
||||
if (*input_line_pointer == ',')
|
||||
@@ -1276,7 +1281,8 @@ obj_elf_section (int push)
|
||||
== ELFOSABI_GNU)
|
||||
|| (bed->elf_osabi
|
||||
== ELFOSABI_FREEBSD)
|
||||
? &gnu_attr : NULL);
|
||||
? &gnu_attr : NULL,
|
||||
&has_entsize);
|
||||
|
||||
if (inherit > 0)
|
||||
attr |= elf_section_flags (now_seg);
|
||||
@@ -1285,6 +1291,9 @@ obj_elf_section (int push)
|
||||
if (inherit)
|
||||
type = elf_section_type (now_seg);
|
||||
|
||||
if ((attr & (SHF_MERGE | SHF_STRINGS)) != 0)
|
||||
has_entsize = true;
|
||||
|
||||
SKIP_WHITESPACE ();
|
||||
if (*input_line_pointer == ',')
|
||||
{
|
||||
@@ -1324,16 +1333,18 @@ obj_elf_section (int push)
|
||||
}
|
||||
|
||||
SKIP_WHITESPACE ();
|
||||
if ((attr & (SHF_MERGE | SHF_STRINGS)) != 0
|
||||
&& *input_line_pointer == ',')
|
||||
if (has_entsize && *input_line_pointer == ',')
|
||||
{
|
||||
++input_line_pointer;
|
||||
SKIP_WHITESPACE ();
|
||||
if (inherit && *input_line_pointer == ','
|
||||
&& ((bfd_section_flags (now_seg)
|
||||
& (SEC_MERGE | SEC_STRINGS)) != 0
|
||||
|| now_seg->entsize))
|
||||
goto fetch_entsize;
|
||||
if (is_end_of_stmt (*input_line_pointer)
|
||||
&& (bfd_section_flags (now_seg)
|
||||
& (SEC_MERGE | SEC_STRINGS)) != 0)
|
||||
goto fetch_entsize;
|
||||
if (is_end_of_stmt (*input_line_pointer))
|
||||
{
|
||||
/* ??? This is here for older versions of gcc that
|
||||
test for gas string merge support with
|
||||
@@ -1341,7 +1352,7 @@ obj_elf_section (int push)
|
||||
Unfortunately '@' begins a comment on arm.
|
||||
This isn't as_warn because gcc tests with
|
||||
--fatal-warnings. */
|
||||
as_tsktsk (_("missing merge / string entity size, 1 assumed"));
|
||||
as_tsktsk (_("missing section entity size, 1 assumed"));
|
||||
entsize = 1;
|
||||
}
|
||||
else
|
||||
@@ -1350,15 +1361,17 @@ obj_elf_section (int push)
|
||||
SKIP_WHITESPACE ();
|
||||
if (entsize <= 0)
|
||||
{
|
||||
as_warn (_("invalid merge / string entity size"));
|
||||
as_warn (_("invalid section entity size"));
|
||||
attr &= ~(SHF_MERGE | SHF_STRINGS);
|
||||
has_entsize = false;
|
||||
entsize = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
else if ((attr & (SHF_MERGE | SHF_STRINGS)) != 0 && inherit
|
||||
&& (bfd_section_flags (now_seg)
|
||||
& (SEC_MERGE | SEC_STRINGS)) != 0)
|
||||
else if (has_entsize && inherit
|
||||
&& ((bfd_section_flags (now_seg)
|
||||
& (SEC_MERGE | SEC_STRINGS)) != 0
|
||||
|| now_seg->entsize))
|
||||
{
|
||||
fetch_entsize:
|
||||
entsize = now_seg->entsize;
|
||||
@@ -1369,6 +1382,7 @@ obj_elf_section (int push)
|
||||
entsize must be specified if SHF_MERGE is set. */
|
||||
as_warn (_("entity size for SHF_MERGE not specified"));
|
||||
attr &= ~(SHF_MERGE | SHF_STRINGS);
|
||||
has_entsize = false;
|
||||
}
|
||||
else if ((attr & SHF_STRINGS) != 0)
|
||||
{
|
||||
@@ -1378,6 +1392,11 @@ obj_elf_section (int push)
|
||||
compatibility. */
|
||||
entsize = 1;
|
||||
}
|
||||
else if (has_entsize)
|
||||
{
|
||||
as_warn (_("entity size not specified"));
|
||||
has_entsize = false;
|
||||
}
|
||||
|
||||
if ((attr & (SHF_MERGE | SHF_STRINGS)) != 0 && type == SHT_NOBITS)
|
||||
as_warn (_("bogus SHF_MERGE / SHF_STRINGS for SHT_NOBITS section"));
|
||||
|
||||
@@ -7004,12 +7004,14 @@ section) in the same file.
|
||||
section is writable
|
||||
@item x
|
||||
section is executable
|
||||
@item E
|
||||
section has a (non-zero) element/entry size
|
||||
@item G
|
||||
section is a member of a section group
|
||||
@item M
|
||||
section is mergeable
|
||||
@item S
|
||||
section contains zero terminated strings
|
||||
@item G
|
||||
section is a member of a section group
|
||||
@item T
|
||||
section is used for thread-local-storage
|
||||
@item ?
|
||||
@@ -7118,8 +7120,8 @@ is not generally a good idea as section indices are rarely known at assembly
|
||||
time, but the facility is provided for testing purposes. An index of zero is
|
||||
allowed. It indicates that the linked-to section has already been discarded.
|
||||
|
||||
Note: If both one of @var{M} or @var{S} and @var{o} flags are present, then the
|
||||
fields for the Merge/String flag should come first, like this:
|
||||
Note: If both one of @var{M}, @var{S}, or @var{E} and @var{o} flags are present,
|
||||
then the type and entry size fields should come first, like this:
|
||||
|
||||
@smallexample
|
||||
.section @var{name},"@var{flags}"Mo,@@@var{type},@var{entsize},@var{SymbolName}
|
||||
@@ -7142,8 +7144,8 @@ indicates that only one copy of this section should be retained
|
||||
an alias for comdat
|
||||
@end table
|
||||
|
||||
Note: Uf both one of @var{M} or @var{S} and @var{G} flags are present then the
|
||||
fields for the Merge/String flag should come first, like this:
|
||||
Note: If both one of @var{M}, @var{S}, or @var{E} and @var{G} flags are present
|
||||
then the type and entry size fields should come first, like this:
|
||||
|
||||
@smallexample
|
||||
.section @var{name} , "@var{flags}"MG, @@@var{type}, @var{entsize}, @var{GroupName}[, @var{linkage}]
|
||||
|
||||
@@ -293,6 +293,7 @@ if { [is_elf_format] } then {
|
||||
run_dump_test "sh-link-zero"
|
||||
run_dump_test "string"
|
||||
run_dump_test "size"
|
||||
run_dump_test "entsize"
|
||||
run_dump_test "dwarf2-1" $dump_opts
|
||||
run_dump_test "dwarf2-2" $dump_opts
|
||||
run_dump_test "dwarf2-3" $dump_opts
|
||||
|
||||
9
gas/testsuite/gas/elf/entsize.d
Normal file
9
gas/testsuite/gas/elf/entsize.d
Normal file
@@ -0,0 +1,9 @@
|
||||
#readelf: -SW
|
||||
#name: sections with entity size
|
||||
|
||||
#...
|
||||
[ ]*\[.*\][ ]+\.merge[ ]+PROGBITS[ ]+0+[ ]+[0-9a-f]+[ ]+0+18[ ]+0c[ ]+AM[ ].*
|
||||
[ ]*\[.*\][ ]+\.string[ ]+PROGBITS[ ]+0+[ ]+[0-9a-f]+[ ]+0+6[ ]+02[ ]+AS[ ].*
|
||||
[ ]*\[.*\][ ]+\.custom[ ]+PROGBITS[ ]+0+[ ]+[0-9a-f]+[ ]+0+c[ ]+06[ ]+A[ ].*
|
||||
[ ]*\[.*\][ ]+\.bss\.custom[ ]+NOBITS[ ]+0+[ ]+[0-9a-f]+[ ]+0+1e[ ]+06[ ]+WA[ ].*
|
||||
#pass
|
||||
8
gas/testsuite/gas/elf/entsize.s
Normal file
8
gas/testsuite/gas/elf/entsize.s
Normal file
@@ -0,0 +1,8 @@
|
||||
.section .merge, "aM", 12
|
||||
.dc.l 1, 2, 3, 4, 5, 6
|
||||
.section .string, "aS", %progbits, 2
|
||||
.dc.w 0x0020, 0x0021, 0x0022
|
||||
.section .custom, "aE", 6
|
||||
.dc.w 5, 6, 7, 8, 9, 0
|
||||
.section .bss.custom, "awE", %nobits, 6
|
||||
.skip 30
|
||||
Reference in New Issue
Block a user