elf_backend_section_flags and _bfd_elf_init_private_section_data

I was looking at elf_backend_section_flags as a means of setting
SEC_SMALL_DATA for .sdata, .sbss and the like, and condidered adding
an asection* parameter to access the section name easily before
realising that hdr->bfd_section of course makes the section
available.  So no new parameter needed.  In fact the flagword*
parameter isn't needed either, so out it goes.

The patch also tidies some horrible code in _bfd_elf_new_section_hook
that can change whether known ABI sections have sh_type and sh_flags
set up depending on which of the bfd_make_section functions is used.
(Some of those set section flags before _bfd_elf_new_section_hook is
called, others leave the flags zero.)  The function also had some
hacks for .init_array and .fini_array to affect how
_bfd_elf_init_private_section_data behaved for those sections.  It's
cleaner to do that in _bfd_elf_init_private_section_data.  So that all
goes and we now init sh_type and sh_flags for all known ABI sections
in _bfd_elf_new_section_hook.  _bfd_elf_init_private_section_data is
changed to suit, and now doesn't just single out SHT_INIT_ARRAY and
SHT_FINI_ARRAY but rather any of the special section types.

The _bfd_elf_new_section_hook change resulting in
+FAIL: ld-aarch64/erratum835769-843419
exposing some errors in the aarch64 backend.  elfNN_aarch64_size_stubs
should not be looking at linker created sections in the stub bfd.  Nor
should code like "symtab_hdr = &elf_tdata (input_bfd)->symtab_hdr" be
run without first checking that input_bfd is ELF.

	* elf-bfd.h (elf_backend_section_flags): Remove flagword* param.
	* elf.c (_bfd_elf_make_section_from_shdr): Set section flags before
	calling elf_backend_section_flags with adjusted params.  Use
	newsect->flags past that point.
	(_bfd_elf_new_section_hook): Always set sh_type and sh_flags for
	special sections.
	(_bfd_elf_init_private_section_data): Allow normal sh_type sections
	to have their type overridden, and all sh_flags but processor and
	os specific.
	* elf32-arm.c (elf32_arm_section_flags): Adjust for changed params.
	* elf32-mep.c (mep_elf_section_flags): Likewise.
	* elf32-nios2.c (nios2_elf32_section_flags): Likewise.
	* elf64-alpha.c (elf64_alpha_section_flags): Likewise.
	* elf64-ia64-vms.c (elf64_ia64_section_flags): Likewise.
	* elfnn-ia64.c (elfNN_ia64_section_flags): Likewise.
	* elfnn-aarch64.c (elfNN_aarch64_size_stubs): Exclude the linker
	stub BFD and non-aarch64 input files when scanning for stubs.
This commit is contained in:
Alan Modra 2020-03-02 10:16:02 +10:30
parent 7d4b2d2d29
commit 8c803a2dd7
10 changed files with 79 additions and 53 deletions

View File

@ -1,3 +1,23 @@
2020-03-02 Alan Modra <amodra@gmail.com>
* elf-bfd.h (elf_backend_section_flags): Remove flagword* param.
* elf.c (_bfd_elf_make_section_from_shdr): Set section flags before
calling elf_backend_section_flags with adjusted params. Use
newsect->flags past that point.
(_bfd_elf_new_section_hook): Always set sh_type and sh_flags for
special sections.
(_bfd_elf_init_private_section_data): Allow normal sh_type sections
to have their type overridden, and all sh_flags but processor and
os specific.
* elf32-arm.c (elf32_arm_section_flags): Adjust for changed params.
* elf32-mep.c (mep_elf_section_flags): Likewise.
* elf32-nios2.c (nios2_elf32_section_flags): Likewise.
* elf64-alpha.c (elf64_alpha_section_flags): Likewise.
* elf64-ia64-vms.c (elf64_ia64_section_flags): Likewise.
* elfnn-ia64.c (elfNN_ia64_section_flags): Likewise.
* elfnn-aarch64.c (elfNN_aarch64_size_stubs): Exclude the linker
stub BFD and non-aarch64 input files when scanning for stubs.
2020-03-02 Alan Modra <amodra@gmail.com>
* coff-alpha.c (alpha_ecoff_get_elt_at_filepos): Provide an upper

View File

@ -955,7 +955,7 @@ struct elf_backend_data
/* A function to convert machine dependent ELF section header flags to
BFD internal section header flags. */
bfd_boolean (*elf_backend_section_flags)
(flagword *, const Elf_Internal_Shdr *);
(const Elf_Internal_Shdr *);
/* A function that returns a struct containing ELF section flags and
type for the given BFD section. */

View File

@ -1114,12 +1114,12 @@ _bfd_elf_make_section_from_shdr (bfd *abfd,
&& elf_next_in_group (newsect) == NULL)
flags |= SEC_LINK_ONCE | SEC_LINK_DUPLICATES_DISCARD;
bed = get_elf_backend_data (abfd);
if (bed->elf_backend_section_flags)
if (! bed->elf_backend_section_flags (&flags, hdr))
if (!bfd_set_section_flags (newsect, flags))
return FALSE;
if (!bfd_set_section_flags (newsect, flags))
bed = get_elf_backend_data (abfd);
if (bed->elf_backend_section_flags)
if (!bed->elf_backend_section_flags (hdr))
return FALSE;
/* We do not parse the PT_NOTE segments as we are interested even in the
@ -1137,7 +1137,7 @@ _bfd_elf_make_section_from_shdr (bfd *abfd,
free (contents);
}
if ((flags & SEC_ALLOC) != 0)
if ((newsect->flags & SEC_ALLOC) != 0)
{
Elf_Internal_Phdr *phdr;
unsigned int i, nload;
@ -1163,7 +1163,7 @@ _bfd_elf_make_section_from_shdr (bfd *abfd,
|| phdr->p_type == PT_TLS)
&& ELF_SECTION_IN_SEGMENT (hdr, phdr))
{
if ((flags & SEC_LOAD) == 0)
if ((newsect->flags & SEC_LOAD) == 0)
newsect->lma = (phdr->p_paddr
+ hdr->sh_addr - phdr->p_vaddr);
else
@ -1191,7 +1191,7 @@ _bfd_elf_make_section_from_shdr (bfd *abfd,
/* Compress/decompress DWARF debug sections with names: .debug_* and
.zdebug_*, after the section flags is set. */
if ((flags & SEC_DEBUGGING)
if ((newsect->flags & SEC_DEBUGGING)
&& ((name[1] == 'd' && name[6] == '_')
|| (name[1] == 'z' && name[7] == '_')))
{
@ -2900,29 +2900,14 @@ _bfd_elf_new_section_hook (bfd *abfd, asection *sec)
bed = get_elf_backend_data (abfd);
sec->use_rela_p = bed->default_use_rela_p;
/* When we read a file, we don't need to set ELF section type and
flags. They will be overridden in _bfd_elf_make_section_from_shdr
anyway. We will set ELF section type and flags for all linker
created sections. If user specifies BFD section flags, we will
set ELF section type and flags based on BFD section flags in
elf_fake_sections. Special handling for .init_array/.fini_array
output sections since they may contain .ctors/.dtors input
sections. We don't want _bfd_elf_init_private_section_data to
copy ELF section type from .ctors/.dtors input sections. */
if (abfd->direction != read_direction
|| (sec->flags & SEC_LINKER_CREATED) != 0)
{
/* Set up ELF section type and flags for newly created sections, if
there is an ABI mandated section. */
ssect = (*bed->get_sec_type_attr) (abfd, sec);
if (ssect != NULL
&& (!sec->flags
|| (sec->flags & SEC_LINKER_CREATED) != 0
|| ssect->type == SHT_INIT_ARRAY
|| ssect->type == SHT_FINI_ARRAY))
if (ssect != NULL)
{
elf_section_type (sec) = ssect->type;
elf_section_flags (sec) = ssect->attr;
}
}
return _bfd_generic_new_section_hook (abfd, sec);
}
@ -7757,10 +7742,19 @@ _bfd_elf_init_private_section_data (bfd *ibfd,
BFD_ASSERT (elf_section_data (osec) != NULL);
/* For objcopy and relocatable link, don't copy the output ELF
section type from input if the output BFD section flags have been
set to something different. For a final link allow some flags
that the linker clears to differ. */
/* If this is a known ABI section, ELF section type and flags may
have been set up when OSEC was created. For normal sections we
allow the user to override the type and flags other than
SHF_MASKOS and SHF_MASKPROC. */
if (elf_section_type (osec) == SHT_PROGBITS
|| elf_section_type (osec) == SHT_NOTE
|| elf_section_type (osec) == SHT_NOBITS)
elf_section_type (osec) = SHT_NULL;
/* For objcopy and relocatable link, copy the ELF section type from
the input file if the BFD section flags are the same. (If they
are different the user may be doing something like
"objcopy --set-section-flags .text=alloc,data".) For a final
link allow some flags that the linker clears to differ. */
if (elf_section_type (osec) == SHT_NULL
&& (osec->flags == isec->flags
|| (final_link
@ -7769,7 +7763,7 @@ _bfd_elf_init_private_section_data (bfd *ibfd,
elf_section_type (osec) = elf_section_type (isec);
/* FIXME: Is this correct for all OS/PROC specific flags? */
elf_section_flags (osec) |= (elf_section_flags (isec)
elf_section_flags (osec) = (elf_section_flags (isec)
& (SHF_MASKOS | SHF_MASKPROC));
/* Copy sh_info from input for mbind section. */

View File

@ -20230,10 +20230,10 @@ elf32_arm_get_synthetic_symtab (bfd *abfd,
}
static bfd_boolean
elf32_arm_section_flags (flagword *flags, const Elf_Internal_Shdr * hdr)
elf32_arm_section_flags (const Elf_Internal_Shdr *hdr)
{
if (hdr->sh_flags & SHF_ARM_PURECODE)
*flags |= SEC_ELF_PURECODE;
hdr->bfd_section->flags |= SEC_ELF_PURECODE;
return TRUE;
}

View File

@ -717,10 +717,10 @@ mep_elf_object_p (bfd * abfd)
}
static bfd_boolean
mep_elf_section_flags (flagword * flags, const Elf_Internal_Shdr * hdr)
mep_elf_section_flags (const Elf_Internal_Shdr *hdr)
{
if (hdr->sh_flags & SHF_MEP_VLIW)
* flags |= SEC_MEP_VLIW;
hdr->bfd_section->flags |= SEC_MEP_VLIW;
return TRUE;
}

View File

@ -4539,10 +4539,10 @@ nios2_elf32_relocate_section (bfd *output_bfd,
/* Implement elf-backend_section_flags:
Convert NIOS2 specific section flags to bfd internal section flags. */
static bfd_boolean
nios2_elf32_section_flags (flagword *flags, const Elf_Internal_Shdr *hdr)
nios2_elf32_section_flags (const Elf_Internal_Shdr *hdr)
{
if (hdr->sh_flags & SHF_NIOS2_GPREL)
*flags |= SEC_SMALL_DATA;
hdr->bfd_section->flags |= SEC_SMALL_DATA;
return TRUE;
}

View File

@ -1180,10 +1180,10 @@ elf64_alpha_section_from_shdr (bfd *abfd,
/* Convert Alpha specific section flags to bfd internal section flags. */
static bfd_boolean
elf64_alpha_section_flags (flagword *flags, const Elf_Internal_Shdr *hdr)
elf64_alpha_section_flags (const Elf_Internal_Shdr *hdr)
{
if (hdr->sh_flags & SHF_ALPHA_GPREL)
*flags |= SEC_SMALL_DATA;
hdr->bfd_section->flags |= SEC_SMALL_DATA;
return TRUE;
}

View File

@ -822,11 +822,10 @@ is_unwind_section_name (bfd *abfd ATTRIBUTE_UNUSED, const char *name)
flag. */
static bfd_boolean
elf64_ia64_section_flags (flagword *flags,
const Elf_Internal_Shdr *hdr)
elf64_ia64_section_flags (const Elf_Internal_Shdr *hdr)
{
if (hdr->sh_flags & SHF_IA_64_SHORT)
*flags |= SEC_SMALL_DATA;
hdr->bfd_section->flags |= SEC_SMALL_DATA;
return TRUE;
}

View File

@ -4313,9 +4313,15 @@ elfNN_aarch64_size_stubs (bfd *output_bfd,
for (input_bfd = info->input_bfds;
input_bfd != NULL; input_bfd = input_bfd->link.next)
{
if (!is_aarch64_elf (input_bfd)
|| (input_bfd->flags & BFD_LINKER_CREATED) != 0)
continue;
if (!_bfd_aarch64_erratum_835769_scan (input_bfd, info,
&num_erratum_835769_fixes))
return FALSE;
}
_bfd_aarch64_resize_stubs (htab);
(*htab->layout_sections_again) ();
@ -4331,6 +4337,10 @@ elfNN_aarch64_size_stubs (bfd *output_bfd,
{
asection *section;
if (!is_aarch64_elf (input_bfd)
|| (input_bfd->flags & BFD_LINKER_CREATED) != 0)
continue;
for (section = input_bfd->sections;
section != NULL;
section = section->next)
@ -4353,6 +4363,10 @@ elfNN_aarch64_size_stubs (bfd *output_bfd,
asection *section;
Elf_Internal_Sym *local_syms = NULL;
if (!is_aarch64_elf (input_bfd)
|| (input_bfd->flags & BFD_LINKER_CREATED) != 0)
continue;
/* We'll need the symbol table in a second. */
symtab_hdr = &elf_tdata (input_bfd)->symtab_hdr;
if (symtab_hdr->sh_info == 0)

View File

@ -942,11 +942,10 @@ elfNN_ia64_section_from_shdr (bfd *abfd,
flag. */
static bfd_boolean
elfNN_ia64_section_flags (flagword *flags,
const Elf_Internal_Shdr *hdr)
elfNN_ia64_section_flags (const Elf_Internal_Shdr *hdr)
{
if (hdr->sh_flags & SHF_IA_64_SHORT)
*flags |= SEC_SMALL_DATA;
hdr->bfd_section->flags |= SEC_SMALL_DATA;
return TRUE;
}