- if ((bfd_signed_vma) gpdisp < -(bfd_signed_vma) 0x80000000
- || (bfd_signed_vma) gpdisp >= (bfd_signed_vma) 0x7fff8000)
- ret = bfd_reloc_overflow;
-
- /* compensate for the sign extension again. */
- i_ldah = ((i_ldah & 0xffff0000)
- | (((gpdisp >> 16) + ((gpdisp >> 15) & 1)) & 0xffff));
- i_lda = (i_lda & 0xffff0000) | (gpdisp & 0xffff);
-
- bfd_put_32 (abfd, (bfd_vma) i_ldah, p_ldah);
- bfd_put_32 (abfd, (bfd_vma) i_lda, p_lda);
-
- return ret;
-}
-
-/* The special function for the GPDISP reloc. */
-
-static bfd_reloc_status_type
-elf64_alpha_reloc_gpdisp (abfd, reloc_entry, sym, data, input_section,
- output_bfd, err_msg)
- bfd *abfd;
- arelent *reloc_entry;
- asymbol *sym ATTRIBUTE_UNUSED;
- PTR data;
- asection *input_section;
- bfd *output_bfd;
- char **err_msg;
-{
- bfd_reloc_status_type ret;
- bfd_vma gp, relocation;
- bfd_vma high_address;
- bfd_byte *p_ldah, *p_lda;
-
- /* Don't do anything if we're not doing a final link. */
- if (output_bfd)
- {
- reloc_entry->address += input_section->output_offset;
- return bfd_reloc_ok;
- }
-
- high_address = bfd_get_section_limit (abfd, input_section);
- if (reloc_entry->address > high_address
- || reloc_entry->address + reloc_entry->addend > high_address)
- return bfd_reloc_outofrange;
-
- /* The gp used in the portion of the output object to which this
- input object belongs is cached on the input bfd. */
- gp = _bfd_get_gp_value (abfd);
-
- relocation = (input_section->output_section->vma
- + input_section->output_offset
- + reloc_entry->address);
-
- p_ldah = (bfd_byte *) data + reloc_entry->address;
- p_lda = p_ldah + reloc_entry->addend;
-
- ret = elf64_alpha_do_reloc_gpdisp (abfd, gp - relocation, p_ldah, p_lda);
-
- /* Complain if the instructions are not correct. */
- if (ret == bfd_reloc_dangerous)
- *err_msg = _("GPDISP relocation did not find ldah and lda instructions");
-
- return ret;
-}
-
-/* A mapping from BFD reloc types to Alpha ELF reloc types. */
-
-struct elf_reloc_map
-{
- bfd_reloc_code_real_type bfd_reloc_val;
- int elf_reloc_val;
-};
-
-static const struct elf_reloc_map elf64_alpha_reloc_map[] =
-{
- {BFD_RELOC_NONE, R_ALPHA_NONE},
- {BFD_RELOC_32, R_ALPHA_REFLONG},
- {BFD_RELOC_64, R_ALPHA_REFQUAD},
- {BFD_RELOC_CTOR, R_ALPHA_REFQUAD},
- {BFD_RELOC_GPREL32, R_ALPHA_GPREL32},
- {BFD_RELOC_ALPHA_ELF_LITERAL, R_ALPHA_LITERAL},
- {BFD_RELOC_ALPHA_LITUSE, R_ALPHA_LITUSE},
- {BFD_RELOC_ALPHA_GPDISP, R_ALPHA_GPDISP},
- {BFD_RELOC_23_PCREL_S2, R_ALPHA_BRADDR},
- {BFD_RELOC_ALPHA_HINT, R_ALPHA_HINT},
- {BFD_RELOC_16_PCREL, R_ALPHA_SREL16},
- {BFD_RELOC_32_PCREL, R_ALPHA_SREL32},
- {BFD_RELOC_64_PCREL, R_ALPHA_SREL64},
- {BFD_RELOC_ALPHA_GPREL_HI16, R_ALPHA_GPRELHIGH},
- {BFD_RELOC_ALPHA_GPREL_LO16, R_ALPHA_GPRELLOW},
- {BFD_RELOC_GPREL16, R_ALPHA_GPREL16},
- {BFD_RELOC_ALPHA_BRSGP, R_ALPHA_BRSGP},
- {BFD_RELOC_ALPHA_TLSGD, R_ALPHA_TLSGD},
- {BFD_RELOC_ALPHA_TLSLDM, R_ALPHA_TLSLDM},
- {BFD_RELOC_ALPHA_DTPMOD64, R_ALPHA_DTPMOD64},
- {BFD_RELOC_ALPHA_GOTDTPREL16, R_ALPHA_GOTDTPREL},
- {BFD_RELOC_ALPHA_DTPREL64, R_ALPHA_DTPREL64},
- {BFD_RELOC_ALPHA_DTPREL_HI16, R_ALPHA_DTPRELHI},
- {BFD_RELOC_ALPHA_DTPREL_LO16, R_ALPHA_DTPRELLO},
- {BFD_RELOC_ALPHA_DTPREL16, R_ALPHA_DTPREL16},
- {BFD_RELOC_ALPHA_GOTTPREL16, R_ALPHA_GOTTPREL},
- {BFD_RELOC_ALPHA_TPREL64, R_ALPHA_TPREL64},
- {BFD_RELOC_ALPHA_TPREL_HI16, R_ALPHA_TPRELHI},
- {BFD_RELOC_ALPHA_TPREL_LO16, R_ALPHA_TPRELLO},
- {BFD_RELOC_ALPHA_TPREL16, R_ALPHA_TPREL16},
-};
-
-/* Given a BFD reloc type, return a HOWTO structure. */
-
-static reloc_howto_type *
-elf64_alpha_bfd_reloc_type_lookup (abfd, code)
- bfd *abfd ATTRIBUTE_UNUSED;
- bfd_reloc_code_real_type code;
-{
- const struct elf_reloc_map *i, *e;
- i = e = elf64_alpha_reloc_map;
- e += sizeof (elf64_alpha_reloc_map) / sizeof (struct elf_reloc_map);
- for (; i != e; ++i)