mirror of
https://github.com/bminor/binutils-gdb.git
synced 2025-12-09 17:12:54 +00:00
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:
@@ -822,10 +822,12 @@ obj_elf_change_section (const char *name,
|
|||||||
|
|
||||||
static bfd_vma
|
static bfd_vma
|
||||||
obj_elf_parse_section_letters (char *str, size_t len,
|
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;
|
bfd_vma attr = 0;
|
||||||
|
|
||||||
*is_clone = false;
|
*is_clone = false;
|
||||||
|
*inherit = 0;
|
||||||
|
|
||||||
while (len > 0)
|
while (len > 0)
|
||||||
{
|
{
|
||||||
@@ -923,6 +925,8 @@ obj_elf_parse_section_letters (char *str, size_t len,
|
|||||||
len -= (end - str);
|
len -= (end - str);
|
||||||
str = end;
|
str = end;
|
||||||
}
|
}
|
||||||
|
else if (!attr && !*gnu_attr && (*str == '+' || *str == '-'))
|
||||||
|
*inherit = *str == '+' ? 1 : -1;
|
||||||
else
|
else
|
||||||
as_fatal ("%s", bad_msg);
|
as_fatal ("%s", bad_msg);
|
||||||
}
|
}
|
||||||
@@ -1171,6 +1175,7 @@ obj_elf_section (int push)
|
|||||||
if (*input_line_pointer == '"')
|
if (*input_line_pointer == '"')
|
||||||
{
|
{
|
||||||
bool is_clone;
|
bool is_clone;
|
||||||
|
int inherit;
|
||||||
|
|
||||||
beg = demand_copy_C_string (&dummy);
|
beg = demand_copy_C_string (&dummy);
|
||||||
if (beg == NULL)
|
if (beg == NULL)
|
||||||
@@ -1178,8 +1183,15 @@ obj_elf_section (int push)
|
|||||||
ignore_rest_of_line ();
|
ignore_rest_of_line ();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
attr |= obj_elf_parse_section_letters (beg, strlen (beg),
|
attr = obj_elf_parse_section_letters (beg, strlen (beg), &is_clone,
|
||||||
&is_clone, &gnu_attr);
|
&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 ();
|
SKIP_WHITESPACE ();
|
||||||
if (*input_line_pointer == ',')
|
if (*input_line_pointer == ',')
|
||||||
@@ -1224,6 +1236,9 @@ obj_elf_section (int push)
|
|||||||
{
|
{
|
||||||
++input_line_pointer;
|
++input_line_pointer;
|
||||||
SKIP_WHITESPACE ();
|
SKIP_WHITESPACE ();
|
||||||
|
if (inherit && *input_line_pointer == ','
|
||||||
|
&& (bfd_section_flags (now_seg) & SEC_MERGE) != 0)
|
||||||
|
goto fetch_entsize;
|
||||||
entsize = get_absolute_expression ();
|
entsize = get_absolute_expression ();
|
||||||
SKIP_WHITESPACE ();
|
SKIP_WHITESPACE ();
|
||||||
if (entsize < 0)
|
if (entsize < 0)
|
||||||
@@ -1233,6 +1248,12 @@ obj_elf_section (int push)
|
|||||||
entsize = 0;
|
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)
|
else if ((attr & SHF_MERGE) != 0)
|
||||||
{
|
{
|
||||||
as_warn (_("entity size for SHF_MERGE not specified"));
|
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);
|
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
|
else
|
||||||
{
|
{
|
||||||
char c;
|
char c;
|
||||||
@@ -1260,6 +1284,17 @@ obj_elf_section (int push)
|
|||||||
match.linked_to_symbol_name = xmemdup0 (beg, length);
|
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)
|
if ((attr & SHF_GROUP) != 0 && is_clone)
|
||||||
{
|
{
|
||||||
@@ -1270,6 +1305,10 @@ obj_elf_section (int push)
|
|||||||
if ((attr & SHF_GROUP) != 0 && *input_line_pointer == ',')
|
if ((attr & SHF_GROUP) != 0 && *input_line_pointer == ',')
|
||||||
{
|
{
|
||||||
++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 ();
|
match.group_name = obj_elf_section_name ();
|
||||||
if (match.group_name == NULL)
|
if (match.group_name == NULL)
|
||||||
attr &= ~SHF_GROUP;
|
attr &= ~SHF_GROUP;
|
||||||
@@ -1286,6 +1325,14 @@ obj_elf_section (int push)
|
|||||||
else if (startswith (name, ".gnu.linkonce"))
|
else if (startswith (name, ".gnu.linkonce"))
|
||||||
linkonce = 1;
|
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)
|
else if ((attr & SHF_GROUP) != 0)
|
||||||
{
|
{
|
||||||
as_warn (_("group name for SHF_GROUP not specified"));
|
as_warn (_("group name for SHF_GROUP not specified"));
|
||||||
|
|||||||
@@ -6818,6 +6818,12 @@ section is a member of a section group
|
|||||||
section is used for thread-local-storage
|
section is used for thread-local-storage
|
||||||
@item ?
|
@item ?
|
||||||
section is a member of the previously-current section's group, if any
|
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
|
@item R
|
||||||
retained section (apply SHF_GNU_RETAIN to prevent linker garbage
|
retained section (apply SHF_GNU_RETAIN to prevent linker garbage
|
||||||
collection, GNU ELF extension)
|
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
|
@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.
|
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:
|
The optional @var{type} argument may contain one of the following constants:
|
||||||
|
|
||||||
@table @code
|
@table @code
|
||||||
|
|||||||
@@ -280,6 +280,11 @@ if { [is_elf_format] } then {
|
|||||||
run_dump_test "section27"
|
run_dump_test "section27"
|
||||||
run_dump_test "section28"
|
run_dump_test "section28"
|
||||||
run_dump_test "section29"
|
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 "sh-link-zero"
|
||||||
run_dump_test "size"
|
run_dump_test "size"
|
||||||
run_dump_test "dwarf2-1" $dump_opts
|
run_dump_test "dwarf2-1" $dump_opts
|
||||||
|
|||||||
28
gas/testsuite/gas/elf/section30.d
Normal file
28
gas/testsuite/gas/elf/section30.d
Normal 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
|
||||||
67
gas/testsuite/gas/elf/section30.s
Normal file
67
gas/testsuite/gas/elf/section30.s
Normal 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
|
||||||
Reference in New Issue
Block a user