- {
- 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)
- && !(info->executable && !info->pie))
- {
- 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 (info->executable && !info->pie
- && (!h || BFINFDPIC_FUNCDESC_LOCAL (info, h)))
- {
- bfd_vma offset;
-
- addend += bfinfdpic_got_section (info)->output_section->vma;
- if ((bfd_get_section_flags (output_bfd,
- 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;
- }