elf_backend_section_flags and _bfd_elf_init_private_section_data
Szabolcs Nagy
szabolcs.nagy@arm.com
Wed Aug 12 16:38:45 GMT 2020
The 03/02/2020 11:33, Alan Modra wrote:
> 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.
i'm looking at a 2.35 ld regression that affects
the aarch64 linux kernel and this commit might
have caused it.
opened
https://sourceware.org/bugzilla/show_bug.cgi?id=26378
>
> * 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.
>
> diff --git a/bfd/elf-bfd.h b/bfd/elf-bfd.h
> index b930761363..61e733f068 100644
> --- a/bfd/elf-bfd.h
> +++ b/bfd/elf-bfd.h
> @@ -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. */
> diff --git a/bfd/elf.c b/bfd/elf.c
> index 265fc87ad5..fcd84d2d17 100644
> --- a/bfd/elf.c
> +++ b/bfd/elf.c
> @@ -1114,14 +1114,14 @@ _bfd_elf_make_section_from_shdr (bfd *abfd,
> && elf_next_in_group (newsect) == NULL)
> flags |= SEC_LINK_ONCE | SEC_LINK_DUPLICATES_DISCARD;
>
> + 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 (&flags, hdr))
> + if (!bed->elf_backend_section_flags (hdr))
> return FALSE;
>
> - if (!bfd_set_section_flags (newsect, flags))
> - return FALSE;
> -
> /* We do not parse the PT_NOTE segments as we are interested even in the
> separate debug info files which may have the segments offsets corrupted.
> PT_NOTEs from the core files are currently not parsed using BFD. */
> @@ -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,28 +2900,13 @@ _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)
> {
> - 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))
> - {
> - elf_section_type (sec) = ssect->type;
> - elf_section_flags (sec) = ssect->attr;
> - }
> + 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,8 +7763,8 @@ _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)
> - & (SHF_MASKOS | SHF_MASKPROC));
> + elf_section_flags (osec) = (elf_section_flags (isec)
> + & (SHF_MASKOS | SHF_MASKPROC));
>
> /* Copy sh_info from input for mbind section. */
> if ((elf_tdata (ibfd)->has_gnu_osabi & elf_gnu_osabi_mbind) != 0
> diff --git a/bfd/elf32-arm.c b/bfd/elf32-arm.c
> index e9d93cc3b8..c899aeb8f6 100644
> --- a/bfd/elf32-arm.c
> +++ b/bfd/elf32-arm.c
> @@ -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;
> }
>
> diff --git a/bfd/elf32-mep.c b/bfd/elf32-mep.c
> index 14a6d22621..c5775de649 100644
> --- a/bfd/elf32-mep.c
> +++ b/bfd/elf32-mep.c
> @@ -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;
> }
>
> diff --git a/bfd/elf32-nios2.c b/bfd/elf32-nios2.c
> index 17e97bca5a..2fcfe6fd6c 100644
> --- a/bfd/elf32-nios2.c
> +++ b/bfd/elf32-nios2.c
> @@ -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;
> }
> diff --git a/bfd/elf64-alpha.c b/bfd/elf64-alpha.c
> index ed18202b71..9d2d7f1d4d 100644
> --- a/bfd/elf64-alpha.c
> +++ b/bfd/elf64-alpha.c
> @@ -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;
> }
> diff --git a/bfd/elf64-ia64-vms.c b/bfd/elf64-ia64-vms.c
> index 636d7897ee..d40fa4277a 100644
> --- a/bfd/elf64-ia64-vms.c
> +++ b/bfd/elf64-ia64-vms.c
> @@ -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;
> }
> diff --git a/bfd/elfnn-aarch64.c b/bfd/elfnn-aarch64.c
> index 35dd8ab167..ba3ad45468 100644
> --- a/bfd/elfnn-aarch64.c
> +++ b/bfd/elfnn-aarch64.c
> @@ -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 (!_bfd_aarch64_erratum_835769_scan (input_bfd, info,
> - &num_erratum_835769_fixes))
> - return FALSE;
> + {
> + 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)
> diff --git a/bfd/elfnn-ia64.c b/bfd/elfnn-ia64.c
> index 1df2aa842c..208b85df90 100644
> --- a/bfd/elfnn-ia64.c
> +++ b/bfd/elfnn-ia64.c
> @@ -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;
> }
>
> --
> Alan Modra
> Australia Development Lab, IBM
--
More information about the Binutils
mailing list