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:
parent
7d4b2d2d29
commit
8c803a2dd7
10 changed files with 79 additions and 53 deletions
|
@ -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>
|
2020-03-02 Alan Modra <amodra@gmail.com>
|
||||||
|
|
||||||
* coff-alpha.c (alpha_ecoff_get_elt_at_filepos): Provide an upper
|
* coff-alpha.c (alpha_ecoff_get_elt_at_filepos): Provide an upper
|
||||||
|
|
|
@ -955,7 +955,7 @@ struct elf_backend_data
|
||||||
/* A function to convert machine dependent ELF section header flags to
|
/* A function to convert machine dependent ELF section header flags to
|
||||||
BFD internal section header flags. */
|
BFD internal section header flags. */
|
||||||
bfd_boolean (*elf_backend_section_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
|
/* A function that returns a struct containing ELF section flags and
|
||||||
type for the given BFD section. */
|
type for the given BFD section. */
|
||||||
|
|
54
bfd/elf.c
54
bfd/elf.c
|
@ -1114,12 +1114,12 @@ _bfd_elf_make_section_from_shdr (bfd *abfd,
|
||||||
&& elf_next_in_group (newsect) == NULL)
|
&& elf_next_in_group (newsect) == NULL)
|
||||||
flags |= SEC_LINK_ONCE | SEC_LINK_DUPLICATES_DISCARD;
|
flags |= SEC_LINK_ONCE | SEC_LINK_DUPLICATES_DISCARD;
|
||||||
|
|
||||||
bed = get_elf_backend_data (abfd);
|
if (!bfd_set_section_flags (newsect, flags))
|
||||||
if (bed->elf_backend_section_flags)
|
|
||||||
if (! bed->elf_backend_section_flags (&flags, hdr))
|
|
||||||
return FALSE;
|
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;
|
return FALSE;
|
||||||
|
|
||||||
/* We do not parse the PT_NOTE segments as we are interested even in the
|
/* 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);
|
free (contents);
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((flags & SEC_ALLOC) != 0)
|
if ((newsect->flags & SEC_ALLOC) != 0)
|
||||||
{
|
{
|
||||||
Elf_Internal_Phdr *phdr;
|
Elf_Internal_Phdr *phdr;
|
||||||
unsigned int i, nload;
|
unsigned int i, nload;
|
||||||
|
@ -1163,7 +1163,7 @@ _bfd_elf_make_section_from_shdr (bfd *abfd,
|
||||||
|| phdr->p_type == PT_TLS)
|
|| phdr->p_type == PT_TLS)
|
||||||
&& ELF_SECTION_IN_SEGMENT (hdr, phdr))
|
&& ELF_SECTION_IN_SEGMENT (hdr, phdr))
|
||||||
{
|
{
|
||||||
if ((flags & SEC_LOAD) == 0)
|
if ((newsect->flags & SEC_LOAD) == 0)
|
||||||
newsect->lma = (phdr->p_paddr
|
newsect->lma = (phdr->p_paddr
|
||||||
+ hdr->sh_addr - phdr->p_vaddr);
|
+ hdr->sh_addr - phdr->p_vaddr);
|
||||||
else
|
else
|
||||||
|
@ -1191,7 +1191,7 @@ _bfd_elf_make_section_from_shdr (bfd *abfd,
|
||||||
|
|
||||||
/* Compress/decompress DWARF debug sections with names: .debug_* and
|
/* Compress/decompress DWARF debug sections with names: .debug_* and
|
||||||
.zdebug_*, after the section flags is set. */
|
.zdebug_*, after the section flags is set. */
|
||||||
if ((flags & SEC_DEBUGGING)
|
if ((newsect->flags & SEC_DEBUGGING)
|
||||||
&& ((name[1] == 'd' && name[6] == '_')
|
&& ((name[1] == 'd' && name[6] == '_')
|
||||||
|| (name[1] == 'z' && name[7] == '_')))
|
|| (name[1] == 'z' && name[7] == '_')))
|
||||||
{
|
{
|
||||||
|
@ -2900,29 +2900,14 @@ _bfd_elf_new_section_hook (bfd *abfd, asection *sec)
|
||||||
bed = get_elf_backend_data (abfd);
|
bed = get_elf_backend_data (abfd);
|
||||||
sec->use_rela_p = bed->default_use_rela_p;
|
sec->use_rela_p = bed->default_use_rela_p;
|
||||||
|
|
||||||
/* When we read a file, we don't need to set ELF section type and
|
/* Set up ELF section type and flags for newly created sections, if
|
||||||
flags. They will be overridden in _bfd_elf_make_section_from_shdr
|
there is an ABI mandated section. */
|
||||||
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)
|
|
||||||
{
|
|
||||||
ssect = (*bed->get_sec_type_attr) (abfd, sec);
|
ssect = (*bed->get_sec_type_attr) (abfd, sec);
|
||||||
if (ssect != NULL
|
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_type (sec) = ssect->type;
|
||||||
elf_section_flags (sec) = ssect->attr;
|
elf_section_flags (sec) = ssect->attr;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
return _bfd_generic_new_section_hook (abfd, sec);
|
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);
|
BFD_ASSERT (elf_section_data (osec) != NULL);
|
||||||
|
|
||||||
/* For objcopy and relocatable link, don't copy the output ELF
|
/* If this is a known ABI section, ELF section type and flags may
|
||||||
section type from input if the output BFD section flags have been
|
have been set up when OSEC was created. For normal sections we
|
||||||
set to something different. For a final link allow some flags
|
allow the user to override the type and flags other than
|
||||||
that the linker clears to differ. */
|
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
|
if (elf_section_type (osec) == SHT_NULL
|
||||||
&& (osec->flags == isec->flags
|
&& (osec->flags == isec->flags
|
||||||
|| (final_link
|
|| (final_link
|
||||||
|
@ -7769,7 +7763,7 @@ _bfd_elf_init_private_section_data (bfd *ibfd,
|
||||||
elf_section_type (osec) = elf_section_type (isec);
|
elf_section_type (osec) = elf_section_type (isec);
|
||||||
|
|
||||||
/* FIXME: Is this correct for all OS/PROC specific flags? */
|
/* 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));
|
& (SHF_MASKOS | SHF_MASKPROC));
|
||||||
|
|
||||||
/* Copy sh_info from input for mbind section. */
|
/* Copy sh_info from input for mbind section. */
|
||||||
|
|
|
@ -20230,10 +20230,10 @@ elf32_arm_get_synthetic_symtab (bfd *abfd,
|
||||||
}
|
}
|
||||||
|
|
||||||
static bfd_boolean
|
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)
|
if (hdr->sh_flags & SHF_ARM_PURECODE)
|
||||||
*flags |= SEC_ELF_PURECODE;
|
hdr->bfd_section->flags |= SEC_ELF_PURECODE;
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -717,10 +717,10 @@ mep_elf_object_p (bfd * abfd)
|
||||||
}
|
}
|
||||||
|
|
||||||
static bfd_boolean
|
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)
|
if (hdr->sh_flags & SHF_MEP_VLIW)
|
||||||
* flags |= SEC_MEP_VLIW;
|
hdr->bfd_section->flags |= SEC_MEP_VLIW;
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -4539,10 +4539,10 @@ nios2_elf32_relocate_section (bfd *output_bfd,
|
||||||
/* Implement elf-backend_section_flags:
|
/* Implement elf-backend_section_flags:
|
||||||
Convert NIOS2 specific section flags to bfd internal section flags. */
|
Convert NIOS2 specific section flags to bfd internal section flags. */
|
||||||
static bfd_boolean
|
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)
|
if (hdr->sh_flags & SHF_NIOS2_GPREL)
|
||||||
*flags |= SEC_SMALL_DATA;
|
hdr->bfd_section->flags |= SEC_SMALL_DATA;
|
||||||
|
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1180,10 +1180,10 @@ elf64_alpha_section_from_shdr (bfd *abfd,
|
||||||
/* Convert Alpha specific section flags to bfd internal section flags. */
|
/* Convert Alpha specific section flags to bfd internal section flags. */
|
||||||
|
|
||||||
static bfd_boolean
|
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)
|
if (hdr->sh_flags & SHF_ALPHA_GPREL)
|
||||||
*flags |= SEC_SMALL_DATA;
|
hdr->bfd_section->flags |= SEC_SMALL_DATA;
|
||||||
|
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
|
@ -822,11 +822,10 @@ is_unwind_section_name (bfd *abfd ATTRIBUTE_UNUSED, const char *name)
|
||||||
flag. */
|
flag. */
|
||||||
|
|
||||||
static bfd_boolean
|
static bfd_boolean
|
||||||
elf64_ia64_section_flags (flagword *flags,
|
elf64_ia64_section_flags (const Elf_Internal_Shdr *hdr)
|
||||||
const Elf_Internal_Shdr *hdr)
|
|
||||||
{
|
{
|
||||||
if (hdr->sh_flags & SHF_IA_64_SHORT)
|
if (hdr->sh_flags & SHF_IA_64_SHORT)
|
||||||
*flags |= SEC_SMALL_DATA;
|
hdr->bfd_section->flags |= SEC_SMALL_DATA;
|
||||||
|
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
|
@ -4313,9 +4313,15 @@ elfNN_aarch64_size_stubs (bfd *output_bfd,
|
||||||
|
|
||||||
for (input_bfd = info->input_bfds;
|
for (input_bfd = info->input_bfds;
|
||||||
input_bfd != NULL; input_bfd = input_bfd->link.next)
|
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,
|
if (!_bfd_aarch64_erratum_835769_scan (input_bfd, info,
|
||||||
&num_erratum_835769_fixes))
|
&num_erratum_835769_fixes))
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
_bfd_aarch64_resize_stubs (htab);
|
_bfd_aarch64_resize_stubs (htab);
|
||||||
(*htab->layout_sections_again) ();
|
(*htab->layout_sections_again) ();
|
||||||
|
@ -4331,6 +4337,10 @@ elfNN_aarch64_size_stubs (bfd *output_bfd,
|
||||||
{
|
{
|
||||||
asection *section;
|
asection *section;
|
||||||
|
|
||||||
|
if (!is_aarch64_elf (input_bfd)
|
||||||
|
|| (input_bfd->flags & BFD_LINKER_CREATED) != 0)
|
||||||
|
continue;
|
||||||
|
|
||||||
for (section = input_bfd->sections;
|
for (section = input_bfd->sections;
|
||||||
section != NULL;
|
section != NULL;
|
||||||
section = section->next)
|
section = section->next)
|
||||||
|
@ -4353,6 +4363,10 @@ elfNN_aarch64_size_stubs (bfd *output_bfd,
|
||||||
asection *section;
|
asection *section;
|
||||||
Elf_Internal_Sym *local_syms = NULL;
|
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. */
|
/* We'll need the symbol table in a second. */
|
||||||
symtab_hdr = &elf_tdata (input_bfd)->symtab_hdr;
|
symtab_hdr = &elf_tdata (input_bfd)->symtab_hdr;
|
||||||
if (symtab_hdr->sh_info == 0)
|
if (symtab_hdr->sh_info == 0)
|
||||||
|
|
|
@ -942,11 +942,10 @@ elfNN_ia64_section_from_shdr (bfd *abfd,
|
||||||
flag. */
|
flag. */
|
||||||
|
|
||||||
static bfd_boolean
|
static bfd_boolean
|
||||||
elfNN_ia64_section_flags (flagword *flags,
|
elfNN_ia64_section_flags (const Elf_Internal_Shdr *hdr)
|
||||||
const Elf_Internal_Shdr *hdr)
|
|
||||||
{
|
{
|
||||||
if (hdr->sh_flags & SHF_IA_64_SHORT)
|
if (hdr->sh_flags & SHF_IA_64_SHORT)
|
||||||
*flags |= SEC_SMALL_DATA;
|
hdr->bfd_section->flags |= SEC_SMALL_DATA;
|
||||||
|
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue