gas/ELF: allow "inheriting" section attributes and type

While --sectname-subst is nice, it isn't enough to e.g. mimic
-f{function,data}-sections in assembly code, when such use is to be
optional (e.g. dependent upon some configuration setting).

Assign meaning to '+' and '-' as section attribute letters, allowing
to inherit the prior section's attributes (and possibly type) along
with adding or removing some. Note that documenting the interaction
with '?' as undefined is a precautionary measure.

While touching the function invocation, stop using |= on the result of
obj_elf_parse_section_letters(): "attr" is firmly zero ahead of the
call.
This commit is contained in:
Jan Beulich 2023-08-25 14:55:12 +02:00
parent 7b793987b5
commit cefaa117f7
5 changed files with 162 additions and 3 deletions

View File

@ -822,10 +822,12 @@ obj_elf_change_section (const char *name,
static bfd_vma
obj_elf_parse_section_letters (char *str, size_t len,
bool *is_clone, bfd_vma *gnu_attr)
bool *is_clone, int *inherit, bfd_vma *gnu_attr)
{
bfd_vma attr = 0;
*is_clone = false;
*inherit = 0;
while (len > 0)
{
@ -923,6 +925,8 @@ obj_elf_parse_section_letters (char *str, size_t len,
len -= (end - str);
str = end;
}
else if (!attr && !*gnu_attr && (*str == '+' || *str == '-'))
*inherit = *str == '+' ? 1 : -1;
else
as_fatal ("%s", bad_msg);
}
@ -1171,6 +1175,7 @@ obj_elf_section (int push)
if (*input_line_pointer == '"')
{
bool is_clone;
int inherit;
beg = demand_copy_C_string (&dummy);
if (beg == NULL)
@ -1178,8 +1183,15 @@ obj_elf_section (int push)
ignore_rest_of_line ();
return;
}
attr |= obj_elf_parse_section_letters (beg, strlen (beg),
&is_clone, &gnu_attr);
attr = obj_elf_parse_section_letters (beg, strlen (beg), &is_clone,
&inherit, &gnu_attr);
if (inherit > 0)
attr |= elf_section_flags (now_seg);
else if (inherit < 0)
attr = elf_section_flags (now_seg) & ~attr;
if (inherit)
type = elf_section_type (now_seg);
SKIP_WHITESPACE ();
if (*input_line_pointer == ',')
@ -1224,6 +1236,9 @@ obj_elf_section (int push)
{
++input_line_pointer;
SKIP_WHITESPACE ();
if (inherit && *input_line_pointer == ','
&& (bfd_section_flags (now_seg) & SEC_MERGE) != 0)
goto fetch_entsize;
entsize = get_absolute_expression ();
SKIP_WHITESPACE ();
if (entsize < 0)
@ -1233,6 +1248,12 @@ obj_elf_section (int push)
entsize = 0;
}
}
else if ((attr & SHF_MERGE) != 0 && inherit
&& (bfd_section_flags (now_seg) & SEC_MERGE) != 0)
{
fetch_entsize:
entsize = now_seg->entsize;
}
else if ((attr & SHF_MERGE) != 0)
{
as_warn (_("entity size for SHF_MERGE not specified"));
@ -1248,6 +1269,9 @@ obj_elf_section (int push)
{
linked_to_section_index = strtoul (input_line_pointer, & input_line_pointer, 0);
}
else if (inherit && *input_line_pointer == ','
&& (elf_section_flags (now_seg) & SHF_LINK_ORDER) != 0)
goto fetch_linked_to;
else
{
char c;
@ -1260,6 +1284,17 @@ obj_elf_section (int push)
match.linked_to_symbol_name = xmemdup0 (beg, length);
}
}
else if ((attr & SHF_LINK_ORDER) != 0 && inherit
&& (elf_section_flags (now_seg) & SHF_LINK_ORDER) != 0)
{
fetch_linked_to:
if (now_seg->map_head.linked_to_symbol_name)
match.linked_to_symbol_name =
now_seg->map_head.linked_to_symbol_name;
else
linked_to_section_index =
elf_section_data (now_seg)->this_hdr.sh_link;
}
if ((attr & SHF_GROUP) != 0 && is_clone)
{
@ -1270,6 +1305,10 @@ obj_elf_section (int push)
if ((attr & SHF_GROUP) != 0 && *input_line_pointer == ',')
{
++input_line_pointer;
SKIP_WHITESPACE ();
if (inherit && *input_line_pointer == ','
&& (elf_section_flags (now_seg) & SHF_GROUP) != 0)
goto fetch_group;
match.group_name = obj_elf_section_name ();
if (match.group_name == NULL)
attr &= ~SHF_GROUP;
@ -1286,6 +1325,14 @@ obj_elf_section (int push)
else if (startswith (name, ".gnu.linkonce"))
linkonce = 1;
}
else if ((attr & SHF_GROUP) != 0 && inherit
&& (elf_section_flags (now_seg) & SHF_GROUP) != 0)
{
fetch_group:
match.group_name = elf_group_name (now_seg);
linkonce =
(bfd_section_flags (now_seg) & SEC_LINK_ONCE) != 0;
}
else if ((attr & SHF_GROUP) != 0)
{
as_warn (_("group name for SHF_GROUP not specified"));

View File

@ -6818,6 +6818,12 @@ section is a member of a section group
section is used for thread-local-storage
@item ?
section is a member of the previously-current section's group, if any
@item +
section inherits attributes and (unless explicitly specified) type from the
previously-current section, adding other attributes as specified
@item -
section inherits attributes and (unless explicitly specified) type from the
previously-current section, removing other attributes as specified
@item R
retained section (apply SHF_GNU_RETAIN to prevent linker garbage
collection, GNU ELF extension)
@ -6839,6 +6845,12 @@ section may have the executable (@code{x}) flag added. Also note that the
@code{.attach_to_group} directive can be used to add a section to a group even
if the section was not originally declared to be part of that group.
Note further that @code{+} and @code{-} need to come first and can only take
the effect described here unless overridden by a target. The attributes
inherited are those in effect at the time the directive is processed.
Attributes added later (see above) will not be inherited. Using either
together with @code{?} is undefined at this point.
The optional @var{type} argument may contain one of the following constants:
@table @code

View File

@ -280,6 +280,11 @@ if { [is_elf_format] } then {
run_dump_test "section27"
run_dump_test "section28"
run_dump_test "section29"
if { ![istarget "rx-*-*"] } then {
run_dump_test "section30"
} else {
run_dump_test "section30" {{as -muse-conventional-section-names}}
}
run_dump_test "sh-link-zero"
run_dump_test "size"
run_dump_test "dwarf2-1" $dump_opts

View File

@ -0,0 +1,28 @@
#as: --sectname-subst
#readelf: -SW
#name: --sectname-subst plus section attr/type inherting
# Targets setting NO_PSEUDO_DOT don't allow macros of certain names.
#notarget: m681*-*-* m68hc1*-*-* s12z-*-* spu-*-* xgate-*-* z80-*-*
#...
\[..\] \.group +GROUP +[0-9a-f]+ [0-9a-f]+ 0+c 04 +[1-9][0-9]* +[1-9][0-9]* +4
\[..\] \.text +PROGBITS +[0-9a-f]+ [0-9a-f]+ 0+0 00 AX 0 0 +[1-9][0-9]*
\[..\] \.data +PROGBITS +[0-9a-f]+ [0-9a-f]+ 0+0 00 WA 0 0 +[1-9][0-9]*
\[..\] \.bss +NOBITS +[0-9a-f]+ [0-9a-f]+ 0+0 00 WA 0 0 +[1-9][0-9]*
#...
\[..\] \.text\.func1 +PROGBITS +[0-9a-f]+ [0-9a-f]+ [0-9a-f]+ 00 AX 0 0 +[1-9][0-9]*
\[..\] \.text\.func2 +PROGBITS +[0-9a-f]+ [0-9a-f]+ [0-9a-f]+ 00 AX 0 0 +[1-9][0-9]*
\[..\] \.data\.data1 +PROGBITS +[0-9a-f]+ [0-9a-f]+ 0+1 00 WA 0 0 1
#...
\[..\] \.bss\.data2 +NOBITS +[0-9a-f]+ [0-9a-f]+ 0+2 00 WA 0 0 1
\[..\] \.rodata +PROGBITS +[0-9a-f]+ [0-9a-f]+ 0+0 00 A 0 0 1
\[..\] \.rodata\.data3 +PROGBITS +[0-9a-f]+ [0-9a-f]+ 0+3 00 A 0 0 1
\[..\] \.rodata\.str1\.1 +PROGBITS +[0-9a-f]+ [0-9a-f]+ 0+0 01 AMS 0 0 1
\[..\] \.rodata\.str1\.1\.str1 +PROGBITS +[0-9a-f]+ [0-9a-f]+ 0+8 01 AMS 0 0 1
\[..\] \.rodata\.2 +PROGBITS +[0-9a-f]+ [0-9a-f]+ 0+0 00 AL [1-9] 0 1
\[..\] \.rodata\.2\.data4 +PROGBITS +[0-9a-f]+ [0-9a-f]+ 0+4 00 AL [1-9] 0 1
\[..\] \.bss\.data5 +NOBITS +[0-9a-f]+ [0-9a-f]+ 0+5 00 WA 0 0 1
\[..\] \.rodata\.3 +PROGBITS +[0-9a-f]+ [0-9a-f]+ 0+0 00 AG 0 0 1
\[..\] \.rodata\.3\.data6 +PROGBITS +[0-9a-f]+ [0-9a-f]+ 0+6 00 AG 0 0 1
\[..\] \.bss\.data7 +NOBITS +[0-9a-f]+ [0-9a-f]+ 0+7 00 WA 0 0 1
#pass

View File

@ -0,0 +1,67 @@
.macro func name:req
.pushsection %S.\name, "+"
.type \name, %function
.global \name
.hidden \name
\name:
.endm
.macro data name:req
.pushsection %S.\name, "+"
.type \name, %object
\name:
.endm
.macro end name:req
.size \name, . - \name
.popsection
.endm
.text
func func1
.nop
end func1
func func2
.nop
.nop
end func2
.data
data data1
.byte 1
end data1
.section .bss
data data2
.skip 2
end data2
.section .rodata, "a", %progbits
data data3
.byte 3, 3, 3
end data3
.section .rodata.str1.1, "aMS", %progbits, 1
data str1
.asciz "string1"
end str1
.section .rodata.2, "ao", %progbits, func1
data data4
.byte 4, 4, 4, 4
end data4
.pushsection .bss.data5, "-o", %nobits
.type data5, %object
data5: .fill 5
end data5
.section .rodata.3, "aG", %progbits, sig1, comdat
data data6
.byte 6, 6, 6, 6, 6, 6
end data6
.pushsection .bss.data7, "-G", %nobits
.type data7, %object
data7: .skip 7
end data7