From 8ca9c7eb6773dd3cc9c536787b3489d36356ccf7 Mon Sep 17 00:00:00 2001 From: "H.J. Lu" Date: Thu, 14 Jan 2021 05:23:58 -0800 Subject: [PATCH] bfin: Skip non SEC_ALLOC section for R_BFIN_FUNCDESC Linker should never generate dynamic relocations for relocations in non-SEC_ALLOC section which has no impact on run-time behavior. Such relocations should be resolved to 0. PR ld/26688 * elf32-bfin.c (bfinfdpic_relocate_section): Skip non SEC_ALLOC section for R_BFIN_FUNCDESC. --- bfd/ChangeLog | 6 ++ bfd/elf32-bfin.c | 235 ++++++++++++++++++++++++----------------------- 2 files changed, 124 insertions(+), 117 deletions(-) diff --git a/bfd/ChangeLog b/bfd/ChangeLog index 7f1b720b94f..db49d6fdcd3 100644 --- a/bfd/ChangeLog +++ b/bfd/ChangeLog @@ -1,3 +1,9 @@ +2021-01-14 H.J. Lu + + PR ld/26688 + * elf32-bfin.c (bfinfdpic_relocate_section): Skip non SEC_ALLOC + section for R_BFIN_FUNCDESC. + 2021-01-14 Nick Clifton * elf.c (elfcore_grok_win32pstatus): Check for a note type of 0. diff --git a/bfd/elf32-bfin.c b/bfd/elf32-bfin.c index 7c926b8a96e..401683c5367 100644 --- a/bfd/elf32-bfin.c +++ b/bfd/elf32-bfin.c @@ -2727,129 +2727,130 @@ bfinfdpic_relocate_section (bfd * output_bfd, break; case R_BFIN_FUNCDESC: - { - int dynindx; - bfd_vma addend = rel->r_addend; - - if (! (h && h->root.type == bfd_link_hash_undefweak - && BFINFDPIC_SYM_LOCAL (info, h))) - { - /* If the symbol is dynamic and there may be dynamic - symbol resolution because we are or are linked with a - shared library, emit a FUNCDESC relocation such that - the dynamic linker will allocate the function - descriptor. If the symbol needs a non-local function - descriptor but binds locally (e.g., its visibility is - protected, emit a dynamic relocation decayed to - section+offset. */ - if (h && ! BFINFDPIC_FUNCDESC_LOCAL (info, h) - && BFINFDPIC_SYM_LOCAL (info, h) - && !bfd_link_pde (info)) - { - dynindx = elf_section_data (h->root.u.def.section - ->output_section)->dynindx; - addend += h->root.u.def.section->output_offset - + h->root.u.def.value; - } - else if (h && ! BFINFDPIC_FUNCDESC_LOCAL (info, h)) - { - if (addend) - { - info->callbacks->warning - (info, _("R_BFIN_FUNCDESC references dynamic symbol with nonzero addend"), - name, input_bfd, input_section, rel->r_offset); - return FALSE; - } - dynindx = h->dynindx; - } - else - { - /* Otherwise, we know we have a private function - descriptor, so reference it directly. */ - BFD_ASSERT (picrel->privfd); - r_type = R_BFIN_BYTE4_DATA; - dynindx = elf_section_data (bfinfdpic_got_section (info) - ->output_section)->dynindx; - addend = bfinfdpic_got_section (info)->output_offset - + bfinfdpic_got_initial_offset (info) - + picrel->fd_entry; - } - - /* If there is room for dynamic symbol resolution, emit - the dynamic relocation. However, if we're linking an - executable at a fixed location, we won't have emitted a - dynamic symbol entry for the got section, so idx will - be zero, which means we can and should compute the - address of the private descriptor ourselves. */ - if (bfd_link_pde (info) - && (!h || BFINFDPIC_FUNCDESC_LOCAL (info, h))) - { - bfd_vma offset; - - addend += bfinfdpic_got_section (info)->output_section->vma; - if ((bfd_section_flags (input_section->output_section) - & (SEC_ALLOC | SEC_LOAD)) == (SEC_ALLOC | SEC_LOAD)) - { - if (_bfinfdpic_osec_readonly_p (output_bfd, - input_section - ->output_section)) - { - info->callbacks->warning - (info, - _("cannot emit fixups in read-only section"), - name, input_bfd, input_section, rel->r_offset); - return FALSE; - } + if ((input_section->flags & SEC_ALLOC) != 0) + { + int dynindx; + bfd_vma addend = rel->r_addend; - offset = _bfd_elf_section_offset - (output_bfd, info, - input_section, rel->r_offset); + if (! (h && h->root.type == bfd_link_hash_undefweak + && BFINFDPIC_SYM_LOCAL (info, h))) + { + /* If the symbol is dynamic and there may be dynamic + symbol resolution because we are or are linked with a + shared library, emit a FUNCDESC relocation such that + the dynamic linker will allocate the function + descriptor. If the symbol needs a non-local function + descriptor but binds locally (e.g., its visibility is + protected, emit a dynamic relocation decayed to + section+offset. */ + if (h && ! BFINFDPIC_FUNCDESC_LOCAL (info, h) + && BFINFDPIC_SYM_LOCAL (info, h) + && !bfd_link_pde (info)) + { + dynindx = elf_section_data (h->root.u.def.section + ->output_section)->dynindx; + addend += h->root.u.def.section->output_offset + + h->root.u.def.value; + } + else if (h && ! BFINFDPIC_FUNCDESC_LOCAL (info, h)) + { + if (addend) + { + info->callbacks->warning + (info, _("R_BFIN_FUNCDESC references dynamic symbol with nonzero addend"), + name, input_bfd, input_section, rel->r_offset); + return FALSE; + } + dynindx = h->dynindx; + } + else + { + /* Otherwise, we know we have a private function + descriptor, so reference it directly. */ + BFD_ASSERT (picrel->privfd); + r_type = R_BFIN_BYTE4_DATA; + dynindx = elf_section_data (bfinfdpic_got_section (info) + ->output_section)->dynindx; + addend = bfinfdpic_got_section (info)->output_offset + + bfinfdpic_got_initial_offset (info) + + picrel->fd_entry; + } - if (offset != (bfd_vma)-1) - _bfinfdpic_add_rofixup (output_bfd, - bfinfdpic_gotfixup_section - (info), + /* If there is room for dynamic symbol resolution, emit + the dynamic relocation. However, if we're linking an + executable at a fixed location, we won't have emitted a + dynamic symbol entry for the got section, so idx will + be zero, which means we can and should compute the + address of the private descriptor ourselves. */ + if (bfd_link_pde (info) + && (!h || BFINFDPIC_FUNCDESC_LOCAL (info, h))) + { + bfd_vma offset; + + addend += bfinfdpic_got_section (info)->output_section->vma; + if ((bfd_section_flags (input_section->output_section) + & (SEC_ALLOC | SEC_LOAD)) == (SEC_ALLOC | SEC_LOAD)) + { + if (_bfinfdpic_osec_readonly_p (output_bfd, + input_section + ->output_section)) + { + info->callbacks->warning + (info, + _("cannot emit fixups in read-only section"), + name, input_bfd, input_section, rel->r_offset); + return FALSE; + } + + offset = _bfd_elf_section_offset + (output_bfd, info, + input_section, rel->r_offset); + + if (offset != (bfd_vma)-1) + _bfinfdpic_add_rofixup (output_bfd, + bfinfdpic_gotfixup_section + (info), + offset + input_section + ->output_section->vma + + input_section->output_offset, + picrel); + } + } + else if ((bfd_section_flags (input_section->output_section) + & (SEC_ALLOC | SEC_LOAD)) == (SEC_ALLOC | SEC_LOAD)) + { + bfd_vma offset; + + if (_bfinfdpic_osec_readonly_p (output_bfd, + input_section + ->output_section)) + { + info->callbacks->warning + (info, + _("cannot emit dynamic relocations in read-only section"), + name, input_bfd, input_section, rel->r_offset); + return FALSE; + } + offset = _bfd_elf_section_offset (output_bfd, info, + input_section, rel->r_offset); + + if (offset != (bfd_vma)-1) + _bfinfdpic_add_dyn_reloc (output_bfd, + bfinfdpic_gotrel_section (info), offset + input_section ->output_section->vma + input_section->output_offset, - picrel); - } - } - else if ((bfd_section_flags (input_section->output_section) - & (SEC_ALLOC | SEC_LOAD)) == (SEC_ALLOC | SEC_LOAD)) - { - bfd_vma offset; - - if (_bfinfdpic_osec_readonly_p (output_bfd, - input_section - ->output_section)) - { - info->callbacks->warning - (info, - _("cannot emit dynamic relocations in read-only section"), - name, input_bfd, input_section, rel->r_offset); - return FALSE; - } - offset = _bfd_elf_section_offset (output_bfd, info, - input_section, rel->r_offset); - - if (offset != (bfd_vma)-1) - _bfinfdpic_add_dyn_reloc (output_bfd, - bfinfdpic_gotrel_section (info), - offset + input_section - ->output_section->vma - + input_section->output_offset, - r_type, - dynindx, addend, picrel); - } - else - addend += bfinfdpic_got_section (info)->output_section->vma; - } + r_type, + dynindx, addend, picrel); + } + else + addend += bfinfdpic_got_section (info)->output_section->vma; + } - /* We want the addend in-place because dynamic - relocations are REL. Setting relocation to it should - arrange for it to be installed. */ - relocation = addend - rel->r_addend; + /* We want the addend in-place because dynamic + relocations are REL. Setting relocation to it should + arrange for it to be installed. */ + relocation = addend - rel->r_addend; } check_segment[0] = check_segment[1] = got_segment; break; -- 2.30.2