Home | History | Annotate | Download | only in bfd
      1 /* IA-64 support for 64-bit ELF
      2    Copyright (C) 1998-2014 Free Software Foundation, Inc.
      3    Contributed by David Mosberger-Tang <davidm (at) hpl.hp.com>
      4 
      5    This file is part of BFD, the Binary File Descriptor library.
      6 
      7    This program is free software; you can redistribute it and/or modify
      8    it under the terms of the GNU General Public License as published by
      9    the Free Software Foundation; either version 3 of the License, or
     10    (at your option) any later version.
     11 
     12    This program is distributed in the hope that it will be useful,
     13    but WITHOUT ANY WARRANTY; without even the implied warranty of
     14    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     15    GNU General Public License for more details.
     16 
     17    You should have received a copy of the GNU General Public License
     18    along with this program; if not, write to the Free Software
     19    Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
     20    MA 02110-1301, USA.  */
     21 
     22 #include "sysdep.h"
     23 #include "bfd.h"
     24 #include "libbfd.h"
     25 #include "elf-bfd.h"
     26 #include "opcode/ia64.h"
     27 #include "elf/ia64.h"
     28 #include "objalloc.h"
     29 #include "hashtab.h"
     30 #include "bfd_stdint.h"
     31 #include "elfxx-ia64.h"
     32 
     33 /* THE RULES for all the stuff the linker creates --
     34 
     35   GOT		Entries created in response to LTOFF or LTOFF_FPTR
     36  		relocations.  Dynamic relocs created for dynamic
     37  		symbols in an application; REL relocs for locals
     38  		in a shared library.
     39 
     40   FPTR		The canonical function descriptor.  Created for local
     41  		symbols in applications.  Descriptors for dynamic symbols
     42  		and local symbols in shared libraries are created by
     43  		ld.so.  Thus there are no dynamic relocs against these
     44  		objects.  The FPTR relocs for such _are_ passed through
     45  		to the dynamic relocation tables.
     46 
     47   FULL_PLT	Created for a PCREL21B relocation against a dynamic symbol.
     48  		Requires the creation of a PLTOFF entry.  This does not
     49  		require any dynamic relocations.
     50 
     51   PLTOFF	Created by PLTOFF relocations.  For local symbols, this
     52  		is an alternate function descriptor, and in shared libraries
     53  		requires two REL relocations.  Note that this cannot be
     54  		transformed into an FPTR relocation, since it must be in
     55  		range of the GP.  For dynamic symbols, this is a function
     56  		descriptor for a MIN_PLT entry, and requires one IPLT reloc.
     57 
     58   MIN_PLT	Created by PLTOFF entries against dynamic symbols.  This
     59  		does not require dynamic relocations.  */
     60 
     61 /* ia64-specific relocation.  */
     62 
     63 #define NELEMS(a)	((int) (sizeof (a) / sizeof ((a)[0])))
     64 
     65 /* Perform a relocation.  Not much to do here as all the hard work is
     66    done in elfNN_ia64_final_link_relocate.  */
     67 static bfd_reloc_status_type
     68 ia64_elf_reloc (bfd *abfd ATTRIBUTE_UNUSED, arelent *reloc,
     69                 asymbol *sym ATTRIBUTE_UNUSED,
     70                 PTR data ATTRIBUTE_UNUSED, asection *input_section,
     71                 bfd *output_bfd, char **error_message)
     72 {
     73   if (output_bfd)
     74     {
     75       reloc->address += input_section->output_offset;
     76       return bfd_reloc_ok;
     77     }
     78 
     79   if (input_section->flags & SEC_DEBUGGING)
     80     return bfd_reloc_continue;
     81 
     82   *error_message = "Unsupported call to ia64_elf_reloc";
     83   return bfd_reloc_notsupported;
     84 }
     85 
     86 #define IA64_HOWTO(TYPE, NAME, SIZE, PCREL, IN)			\
     87   HOWTO (TYPE, 0, SIZE, 0, PCREL, 0, complain_overflow_signed,	\
     88 	 ia64_elf_reloc, NAME, FALSE, 0, -1, IN)
     89 
     90 /* This table has to be sorted according to increasing number of the
     91    TYPE field.  */
     92 static reloc_howto_type ia64_howto_table[] =
     93   {
     94     IA64_HOWTO (R_IA64_NONE,	    "NONE",	   0, FALSE, TRUE),
     95 
     96     IA64_HOWTO (R_IA64_IMM14,	    "IMM14",	   0, FALSE, TRUE),
     97     IA64_HOWTO (R_IA64_IMM22,	    "IMM22",	   0, FALSE, TRUE),
     98     IA64_HOWTO (R_IA64_IMM64,	    "IMM64",	   0, FALSE, TRUE),
     99     IA64_HOWTO (R_IA64_DIR32MSB,    "DIR32MSB",	   2, FALSE, TRUE),
    100     IA64_HOWTO (R_IA64_DIR32LSB,    "DIR32LSB",	   2, FALSE, TRUE),
    101     IA64_HOWTO (R_IA64_DIR64MSB,    "DIR64MSB",	   4, FALSE, TRUE),
    102     IA64_HOWTO (R_IA64_DIR64LSB,    "DIR64LSB",	   4, FALSE, TRUE),
    103 
    104     IA64_HOWTO (R_IA64_GPREL22,	    "GPREL22",	   0, FALSE, TRUE),
    105     IA64_HOWTO (R_IA64_GPREL64I,    "GPREL64I",	   0, FALSE, TRUE),
    106     IA64_HOWTO (R_IA64_GPREL32MSB,  "GPREL32MSB",  2, FALSE, TRUE),
    107     IA64_HOWTO (R_IA64_GPREL32LSB,  "GPREL32LSB",  2, FALSE, TRUE),
    108     IA64_HOWTO (R_IA64_GPREL64MSB,  "GPREL64MSB",  4, FALSE, TRUE),
    109     IA64_HOWTO (R_IA64_GPREL64LSB,  "GPREL64LSB",  4, FALSE, TRUE),
    110 
    111     IA64_HOWTO (R_IA64_LTOFF22,	    "LTOFF22",	   0, FALSE, TRUE),
    112     IA64_HOWTO (R_IA64_LTOFF64I,    "LTOFF64I",	   0, FALSE, TRUE),
    113 
    114     IA64_HOWTO (R_IA64_PLTOFF22,    "PLTOFF22",	   0, FALSE, TRUE),
    115     IA64_HOWTO (R_IA64_PLTOFF64I,   "PLTOFF64I",   0, FALSE, TRUE),
    116     IA64_HOWTO (R_IA64_PLTOFF64MSB, "PLTOFF64MSB", 4, FALSE, TRUE),
    117     IA64_HOWTO (R_IA64_PLTOFF64LSB, "PLTOFF64LSB", 4, FALSE, TRUE),
    118 
    119     IA64_HOWTO (R_IA64_FPTR64I,	    "FPTR64I",	   0, FALSE, TRUE),
    120     IA64_HOWTO (R_IA64_FPTR32MSB,   "FPTR32MSB",   2, FALSE, TRUE),
    121     IA64_HOWTO (R_IA64_FPTR32LSB,   "FPTR32LSB",   2, FALSE, TRUE),
    122     IA64_HOWTO (R_IA64_FPTR64MSB,   "FPTR64MSB",   4, FALSE, TRUE),
    123     IA64_HOWTO (R_IA64_FPTR64LSB,   "FPTR64LSB",   4, FALSE, TRUE),
    124 
    125     IA64_HOWTO (R_IA64_PCREL60B,    "PCREL60B",	   0, TRUE, TRUE),
    126     IA64_HOWTO (R_IA64_PCREL21B,    "PCREL21B",	   0, TRUE, TRUE),
    127     IA64_HOWTO (R_IA64_PCREL21M,    "PCREL21M",	   0, TRUE, TRUE),
    128     IA64_HOWTO (R_IA64_PCREL21F,    "PCREL21F",	   0, TRUE, TRUE),
    129     IA64_HOWTO (R_IA64_PCREL32MSB,  "PCREL32MSB",  2, TRUE, TRUE),
    130     IA64_HOWTO (R_IA64_PCREL32LSB,  "PCREL32LSB",  2, TRUE, TRUE),
    131     IA64_HOWTO (R_IA64_PCREL64MSB,  "PCREL64MSB",  4, TRUE, TRUE),
    132     IA64_HOWTO (R_IA64_PCREL64LSB,  "PCREL64LSB",  4, TRUE, TRUE),
    133 
    134     IA64_HOWTO (R_IA64_LTOFF_FPTR22, "LTOFF_FPTR22", 0, FALSE, TRUE),
    135     IA64_HOWTO (R_IA64_LTOFF_FPTR64I, "LTOFF_FPTR64I", 0, FALSE, TRUE),
    136     IA64_HOWTO (R_IA64_LTOFF_FPTR32MSB, "LTOFF_FPTR32MSB", 2, FALSE, TRUE),
    137     IA64_HOWTO (R_IA64_LTOFF_FPTR32LSB, "LTOFF_FPTR32LSB", 2, FALSE, TRUE),
    138     IA64_HOWTO (R_IA64_LTOFF_FPTR64MSB, "LTOFF_FPTR64MSB", 4, FALSE, TRUE),
    139     IA64_HOWTO (R_IA64_LTOFF_FPTR64LSB, "LTOFF_FPTR64LSB", 4, FALSE, TRUE),
    140 
    141     IA64_HOWTO (R_IA64_SEGREL32MSB, "SEGREL32MSB", 2, FALSE, TRUE),
    142     IA64_HOWTO (R_IA64_SEGREL32LSB, "SEGREL32LSB", 2, FALSE, TRUE),
    143     IA64_HOWTO (R_IA64_SEGREL64MSB, "SEGREL64MSB", 4, FALSE, TRUE),
    144     IA64_HOWTO (R_IA64_SEGREL64LSB, "SEGREL64LSB", 4, FALSE, TRUE),
    145 
    146     IA64_HOWTO (R_IA64_SECREL32MSB, "SECREL32MSB", 2, FALSE, TRUE),
    147     IA64_HOWTO (R_IA64_SECREL32LSB, "SECREL32LSB", 2, FALSE, TRUE),
    148     IA64_HOWTO (R_IA64_SECREL64MSB, "SECREL64MSB", 4, FALSE, TRUE),
    149     IA64_HOWTO (R_IA64_SECREL64LSB, "SECREL64LSB", 4, FALSE, TRUE),
    150 
    151     IA64_HOWTO (R_IA64_REL32MSB,    "REL32MSB",	   2, FALSE, TRUE),
    152     IA64_HOWTO (R_IA64_REL32LSB,    "REL32LSB",	   2, FALSE, TRUE),
    153     IA64_HOWTO (R_IA64_REL64MSB,    "REL64MSB",	   4, FALSE, TRUE),
    154     IA64_HOWTO (R_IA64_REL64LSB,    "REL64LSB",	   4, FALSE, TRUE),
    155 
    156     IA64_HOWTO (R_IA64_LTV32MSB,    "LTV32MSB",	   2, FALSE, TRUE),
    157     IA64_HOWTO (R_IA64_LTV32LSB,    "LTV32LSB",	   2, FALSE, TRUE),
    158     IA64_HOWTO (R_IA64_LTV64MSB,    "LTV64MSB",	   4, FALSE, TRUE),
    159     IA64_HOWTO (R_IA64_LTV64LSB,    "LTV64LSB",	   4, FALSE, TRUE),
    160 
    161     IA64_HOWTO (R_IA64_PCREL21BI,   "PCREL21BI",   0, TRUE, TRUE),
    162     IA64_HOWTO (R_IA64_PCREL22,     "PCREL22",     0, TRUE, TRUE),
    163     IA64_HOWTO (R_IA64_PCREL64I,    "PCREL64I",    0, TRUE, TRUE),
    164 
    165     IA64_HOWTO (R_IA64_IPLTMSB,	    "IPLTMSB",	   4, FALSE, TRUE),
    166     IA64_HOWTO (R_IA64_IPLTLSB,	    "IPLTLSB",	   4, FALSE, TRUE),
    167     IA64_HOWTO (R_IA64_COPY,	    "COPY",	   4, FALSE, TRUE),
    168     IA64_HOWTO (R_IA64_LTOFF22X,    "LTOFF22X",	   0, FALSE, TRUE),
    169     IA64_HOWTO (R_IA64_LDXMOV,	    "LDXMOV",	   0, FALSE, TRUE),
    170 
    171     IA64_HOWTO (R_IA64_TPREL14,	    "TPREL14",	   0, FALSE, FALSE),
    172     IA64_HOWTO (R_IA64_TPREL22,	    "TPREL22",	   0, FALSE, FALSE),
    173     IA64_HOWTO (R_IA64_TPREL64I,    "TPREL64I",	   0, FALSE, FALSE),
    174     IA64_HOWTO (R_IA64_TPREL64MSB,  "TPREL64MSB",  4, FALSE, FALSE),
    175     IA64_HOWTO (R_IA64_TPREL64LSB,  "TPREL64LSB",  4, FALSE, FALSE),
    176     IA64_HOWTO (R_IA64_LTOFF_TPREL22, "LTOFF_TPREL22",  0, FALSE, FALSE),
    177 
    178     IA64_HOWTO (R_IA64_DTPMOD64MSB, "DTPMOD64MSB",  4, FALSE, FALSE),
    179     IA64_HOWTO (R_IA64_DTPMOD64LSB, "DTPMOD64LSB",  4, FALSE, FALSE),
    180     IA64_HOWTO (R_IA64_LTOFF_DTPMOD22, "LTOFF_DTPMOD22", 0, FALSE, FALSE),
    181 
    182     IA64_HOWTO (R_IA64_DTPREL14,    "DTPREL14",	   0, FALSE, FALSE),
    183     IA64_HOWTO (R_IA64_DTPREL22,    "DTPREL22",	   0, FALSE, FALSE),
    184     IA64_HOWTO (R_IA64_DTPREL64I,   "DTPREL64I",   0, FALSE, FALSE),
    185     IA64_HOWTO (R_IA64_DTPREL32MSB, "DTPREL32MSB", 2, FALSE, FALSE),
    186     IA64_HOWTO (R_IA64_DTPREL32LSB, "DTPREL32LSB", 2, FALSE, FALSE),
    187     IA64_HOWTO (R_IA64_DTPREL64MSB, "DTPREL64MSB", 4, FALSE, FALSE),
    188     IA64_HOWTO (R_IA64_DTPREL64LSB, "DTPREL64LSB", 4, FALSE, FALSE),
    189     IA64_HOWTO (R_IA64_LTOFF_DTPREL22, "LTOFF_DTPREL22", 0, FALSE, FALSE),
    190   };
    191 
    192 static unsigned char elf_code_to_howto_index[R_IA64_MAX_RELOC_CODE + 1];
    193 
    194 /* Given a BFD reloc type, return the matching HOWTO structure.  */
    195 
    196 reloc_howto_type *
    197 ia64_elf_lookup_howto (unsigned int rtype)
    198 {
    199   static int inited = 0;
    200   int i;
    201 
    202   if (!inited)
    203     {
    204       inited = 1;
    205 
    206       memset (elf_code_to_howto_index, 0xff, sizeof (elf_code_to_howto_index));
    207       for (i = 0; i < NELEMS (ia64_howto_table); ++i)
    208 	elf_code_to_howto_index[ia64_howto_table[i].type] = i;
    209     }
    210 
    211   if (rtype > R_IA64_MAX_RELOC_CODE)
    212     return 0;
    213   i = elf_code_to_howto_index[rtype];
    214   if (i >= NELEMS (ia64_howto_table))
    215     return 0;
    216   return ia64_howto_table + i;
    217 }
    218 
    219 reloc_howto_type*
    220 ia64_elf_reloc_type_lookup (bfd *abfd ATTRIBUTE_UNUSED,
    221                             bfd_reloc_code_real_type bfd_code)
    222 {
    223   unsigned int rtype;
    224 
    225   switch (bfd_code)
    226     {
    227     case BFD_RELOC_NONE:		rtype = R_IA64_NONE; break;
    228 
    229     case BFD_RELOC_IA64_IMM14:		rtype = R_IA64_IMM14; break;
    230     case BFD_RELOC_IA64_IMM22:		rtype = R_IA64_IMM22; break;
    231     case BFD_RELOC_IA64_IMM64:		rtype = R_IA64_IMM64; break;
    232 
    233     case BFD_RELOC_IA64_DIR32MSB:	rtype = R_IA64_DIR32MSB; break;
    234     case BFD_RELOC_IA64_DIR32LSB:	rtype = R_IA64_DIR32LSB; break;
    235     case BFD_RELOC_IA64_DIR64MSB:	rtype = R_IA64_DIR64MSB; break;
    236     case BFD_RELOC_IA64_DIR64LSB:	rtype = R_IA64_DIR64LSB; break;
    237 
    238     case BFD_RELOC_IA64_GPREL22:	rtype = R_IA64_GPREL22; break;
    239     case BFD_RELOC_IA64_GPREL64I:	rtype = R_IA64_GPREL64I; break;
    240     case BFD_RELOC_IA64_GPREL32MSB:	rtype = R_IA64_GPREL32MSB; break;
    241     case BFD_RELOC_IA64_GPREL32LSB:	rtype = R_IA64_GPREL32LSB; break;
    242     case BFD_RELOC_IA64_GPREL64MSB:	rtype = R_IA64_GPREL64MSB; break;
    243     case BFD_RELOC_IA64_GPREL64LSB:	rtype = R_IA64_GPREL64LSB; break;
    244 
    245     case BFD_RELOC_IA64_LTOFF22:	rtype = R_IA64_LTOFF22; break;
    246     case BFD_RELOC_IA64_LTOFF64I:	rtype = R_IA64_LTOFF64I; break;
    247 
    248     case BFD_RELOC_IA64_PLTOFF22:	rtype = R_IA64_PLTOFF22; break;
    249     case BFD_RELOC_IA64_PLTOFF64I:	rtype = R_IA64_PLTOFF64I; break;
    250     case BFD_RELOC_IA64_PLTOFF64MSB:	rtype = R_IA64_PLTOFF64MSB; break;
    251     case BFD_RELOC_IA64_PLTOFF64LSB:	rtype = R_IA64_PLTOFF64LSB; break;
    252     case BFD_RELOC_IA64_FPTR64I:	rtype = R_IA64_FPTR64I; break;
    253     case BFD_RELOC_IA64_FPTR32MSB:	rtype = R_IA64_FPTR32MSB; break;
    254     case BFD_RELOC_IA64_FPTR32LSB:	rtype = R_IA64_FPTR32LSB; break;
    255     case BFD_RELOC_IA64_FPTR64MSB:	rtype = R_IA64_FPTR64MSB; break;
    256     case BFD_RELOC_IA64_FPTR64LSB:	rtype = R_IA64_FPTR64LSB; break;
    257 
    258     case BFD_RELOC_IA64_PCREL21B:	rtype = R_IA64_PCREL21B; break;
    259     case BFD_RELOC_IA64_PCREL21BI:	rtype = R_IA64_PCREL21BI; break;
    260     case BFD_RELOC_IA64_PCREL21M:	rtype = R_IA64_PCREL21M; break;
    261     case BFD_RELOC_IA64_PCREL21F:	rtype = R_IA64_PCREL21F; break;
    262     case BFD_RELOC_IA64_PCREL22:	rtype = R_IA64_PCREL22; break;
    263     case BFD_RELOC_IA64_PCREL60B:	rtype = R_IA64_PCREL60B; break;
    264     case BFD_RELOC_IA64_PCREL64I:	rtype = R_IA64_PCREL64I; break;
    265     case BFD_RELOC_IA64_PCREL32MSB:	rtype = R_IA64_PCREL32MSB; break;
    266     case BFD_RELOC_IA64_PCREL32LSB:	rtype = R_IA64_PCREL32LSB; break;
    267     case BFD_RELOC_IA64_PCREL64MSB:	rtype = R_IA64_PCREL64MSB; break;
    268     case BFD_RELOC_IA64_PCREL64LSB:	rtype = R_IA64_PCREL64LSB; break;
    269 
    270     case BFD_RELOC_IA64_LTOFF_FPTR22:	rtype = R_IA64_LTOFF_FPTR22; break;
    271     case BFD_RELOC_IA64_LTOFF_FPTR64I:	rtype = R_IA64_LTOFF_FPTR64I; break;
    272     case BFD_RELOC_IA64_LTOFF_FPTR32MSB: rtype = R_IA64_LTOFF_FPTR32MSB; break;
    273     case BFD_RELOC_IA64_LTOFF_FPTR32LSB: rtype = R_IA64_LTOFF_FPTR32LSB; break;
    274     case BFD_RELOC_IA64_LTOFF_FPTR64MSB: rtype = R_IA64_LTOFF_FPTR64MSB; break;
    275     case BFD_RELOC_IA64_LTOFF_FPTR64LSB: rtype = R_IA64_LTOFF_FPTR64LSB; break;
    276 
    277     case BFD_RELOC_IA64_SEGREL32MSB:	rtype = R_IA64_SEGREL32MSB; break;
    278     case BFD_RELOC_IA64_SEGREL32LSB:	rtype = R_IA64_SEGREL32LSB; break;
    279     case BFD_RELOC_IA64_SEGREL64MSB:	rtype = R_IA64_SEGREL64MSB; break;
    280     case BFD_RELOC_IA64_SEGREL64LSB:	rtype = R_IA64_SEGREL64LSB; break;
    281 
    282     case BFD_RELOC_IA64_SECREL32MSB:	rtype = R_IA64_SECREL32MSB; break;
    283     case BFD_RELOC_IA64_SECREL32LSB:	rtype = R_IA64_SECREL32LSB; break;
    284     case BFD_RELOC_IA64_SECREL64MSB:	rtype = R_IA64_SECREL64MSB; break;
    285     case BFD_RELOC_IA64_SECREL64LSB:	rtype = R_IA64_SECREL64LSB; break;
    286 
    287     case BFD_RELOC_IA64_REL32MSB:	rtype = R_IA64_REL32MSB; break;
    288     case BFD_RELOC_IA64_REL32LSB:	rtype = R_IA64_REL32LSB; break;
    289     case BFD_RELOC_IA64_REL64MSB:	rtype = R_IA64_REL64MSB; break;
    290     case BFD_RELOC_IA64_REL64LSB:	rtype = R_IA64_REL64LSB; break;
    291 
    292     case BFD_RELOC_IA64_LTV32MSB:	rtype = R_IA64_LTV32MSB; break;
    293     case BFD_RELOC_IA64_LTV32LSB:	rtype = R_IA64_LTV32LSB; break;
    294     case BFD_RELOC_IA64_LTV64MSB:	rtype = R_IA64_LTV64MSB; break;
    295     case BFD_RELOC_IA64_LTV64LSB:	rtype = R_IA64_LTV64LSB; break;
    296 
    297     case BFD_RELOC_IA64_IPLTMSB:	rtype = R_IA64_IPLTMSB; break;
    298     case BFD_RELOC_IA64_IPLTLSB:	rtype = R_IA64_IPLTLSB; break;
    299     case BFD_RELOC_IA64_COPY:		rtype = R_IA64_COPY; break;
    300     case BFD_RELOC_IA64_LTOFF22X:	rtype = R_IA64_LTOFF22X; break;
    301     case BFD_RELOC_IA64_LDXMOV:		rtype = R_IA64_LDXMOV; break;
    302 
    303     case BFD_RELOC_IA64_TPREL14:	rtype = R_IA64_TPREL14; break;
    304     case BFD_RELOC_IA64_TPREL22:	rtype = R_IA64_TPREL22; break;
    305     case BFD_RELOC_IA64_TPREL64I:	rtype = R_IA64_TPREL64I; break;
    306     case BFD_RELOC_IA64_TPREL64MSB:	rtype = R_IA64_TPREL64MSB; break;
    307     case BFD_RELOC_IA64_TPREL64LSB:	rtype = R_IA64_TPREL64LSB; break;
    308     case BFD_RELOC_IA64_LTOFF_TPREL22:	rtype = R_IA64_LTOFF_TPREL22; break;
    309 
    310     case BFD_RELOC_IA64_DTPMOD64MSB:	rtype = R_IA64_DTPMOD64MSB; break;
    311     case BFD_RELOC_IA64_DTPMOD64LSB:	rtype = R_IA64_DTPMOD64LSB; break;
    312     case BFD_RELOC_IA64_LTOFF_DTPMOD22:	rtype = R_IA64_LTOFF_DTPMOD22; break;
    313 
    314     case BFD_RELOC_IA64_DTPREL14:	rtype = R_IA64_DTPREL14; break;
    315     case BFD_RELOC_IA64_DTPREL22:	rtype = R_IA64_DTPREL22; break;
    316     case BFD_RELOC_IA64_DTPREL64I:	rtype = R_IA64_DTPREL64I; break;
    317     case BFD_RELOC_IA64_DTPREL32MSB:	rtype = R_IA64_DTPREL32MSB; break;
    318     case BFD_RELOC_IA64_DTPREL32LSB:	rtype = R_IA64_DTPREL32LSB; break;
    319     case BFD_RELOC_IA64_DTPREL64MSB:	rtype = R_IA64_DTPREL64MSB; break;
    320     case BFD_RELOC_IA64_DTPREL64LSB:	rtype = R_IA64_DTPREL64LSB; break;
    321     case BFD_RELOC_IA64_LTOFF_DTPREL22:	rtype = R_IA64_LTOFF_DTPREL22; break;
    322 
    323     default: return 0;
    324     }
    325   return ia64_elf_lookup_howto (rtype);
    326 }
    327 
    328 reloc_howto_type *
    329 ia64_elf_reloc_name_lookup (bfd *abfd ATTRIBUTE_UNUSED,
    330                             const char *r_name)
    331 {
    332   unsigned int i;
    333 
    334   for (i = 0;
    335        i < sizeof (ia64_howto_table) / sizeof (ia64_howto_table[0]);
    336        i++)
    337     if (ia64_howto_table[i].name != NULL
    338 	&& strcasecmp (ia64_howto_table[i].name, r_name) == 0)
    339       return &ia64_howto_table[i];
    340 
    341   return NULL;
    342 }
    343 
    344 #define BTYPE_SHIFT	6
    345 #define Y_SHIFT		26
    346 #define X6_SHIFT	27
    347 #define X4_SHIFT	27
    348 #define X3_SHIFT	33
    349 #define X2_SHIFT	31
    350 #define X_SHIFT		33
    351 #define OPCODE_SHIFT	37
    352 
    353 #define OPCODE_BITS	(0xfLL << OPCODE_SHIFT)
    354 #define X6_BITS		(0x3fLL << X6_SHIFT)
    355 #define X4_BITS		(0xfLL << X4_SHIFT)
    356 #define X3_BITS		(0x7LL << X3_SHIFT)
    357 #define X2_BITS		(0x3LL << X2_SHIFT)
    358 #define X_BITS		(0x1LL << X_SHIFT)
    359 #define Y_BITS		(0x1LL << Y_SHIFT)
    360 #define BTYPE_BITS	(0x7LL << BTYPE_SHIFT)
    361 #define PREDICATE_BITS	(0x3fLL)
    362 
    363 #define IS_NOP_B(i) \
    364   (((i) & (OPCODE_BITS | X6_BITS)) == (2LL << OPCODE_SHIFT))
    365 #define IS_NOP_F(i) \
    366   (((i) & (OPCODE_BITS | X_BITS | X6_BITS | Y_BITS)) \
    367    == (0x1LL << X6_SHIFT))
    368 #define IS_NOP_I(i) \
    369   (((i) & (OPCODE_BITS | X3_BITS | X6_BITS | Y_BITS)) \
    370    == (0x1LL << X6_SHIFT))
    371 #define IS_NOP_M(i) \
    372   (((i) & (OPCODE_BITS | X3_BITS | X2_BITS | X4_BITS | Y_BITS)) \
    373    == (0x1LL << X4_SHIFT))
    374 #define IS_BR_COND(i) \
    375   (((i) & (OPCODE_BITS | BTYPE_BITS)) == (0x4LL << OPCODE_SHIFT))
    376 #define IS_BR_CALL(i) \
    377   (((i) & OPCODE_BITS) == (0x5LL << OPCODE_SHIFT))
    378 
    379 bfd_boolean
    380 ia64_elf_relax_br (bfd_byte *contents, bfd_vma off)
    381 {
    382   unsigned int template_val, mlx;
    383   bfd_vma t0, t1, s0, s1, s2, br_code;
    384   long br_slot;
    385   bfd_byte *hit_addr;
    386 
    387   hit_addr = (bfd_byte *) (contents + off);
    388   br_slot = (intptr_t) hit_addr & 0x3;
    389   hit_addr -= br_slot;
    390   t0 = bfd_getl64 (hit_addr + 0);
    391   t1 = bfd_getl64 (hit_addr + 8);
    392 
    393   /* Check if we can turn br into brl.  A label is always at the start
    394      of the bundle.  Even if there are predicates on NOPs, we still
    395      perform this optimization.  */
    396   template_val = t0 & 0x1e;
    397   s0 = (t0 >> 5) & 0x1ffffffffffLL;
    398   s1 = ((t0 >> 46) | (t1 << 18)) & 0x1ffffffffffLL;
    399   s2 = (t1 >> 23) & 0x1ffffffffffLL;
    400   switch (br_slot)
    401     {
    402     case 0:
    403       /* Check if slot 1 and slot 2 are NOPs. Possible template is
    404          BBB.  We only need to check nop.b.  */
    405       if (!(IS_NOP_B (s1) && IS_NOP_B (s2)))
    406 	return FALSE;
    407       br_code = s0;
    408       break;
    409     case 1:
    410       /* Check if slot 2 is NOP. Possible templates are MBB and BBB.
    411 	 For BBB, slot 0 also has to be nop.b.  */
    412       if (!((template_val == 0x12				/* MBB */
    413 	     && IS_NOP_B (s2))
    414 	    || (template_val == 0x16			/* BBB */
    415 		&& IS_NOP_B (s0)
    416 		&& IS_NOP_B (s2))))
    417 	return FALSE;
    418       br_code = s1;
    419       break;
    420     case 2:
    421       /* Check if slot 1 is NOP. Possible templates are MIB, MBB, BBB,
    422 	 MMB and MFB. For BBB, slot 0 also has to be nop.b.  */
    423       if (!((template_val == 0x10				/* MIB */
    424 	     && IS_NOP_I (s1))
    425 	    || (template_val == 0x12			/* MBB */
    426 		&& IS_NOP_B (s1))
    427 	    || (template_val == 0x16			/* BBB */
    428 		&& IS_NOP_B (s0)
    429 		&& IS_NOP_B (s1))
    430 	    || (template_val == 0x18			/* MMB */
    431 		&& IS_NOP_M (s1))
    432 	    || (template_val == 0x1c			/* MFB */
    433 		&& IS_NOP_F (s1))))
    434 	return FALSE;
    435       br_code = s2;
    436       break;
    437     default:
    438       /* It should never happen.  */
    439       abort ();
    440     }
    441 
    442   /* We can turn br.cond/br.call into brl.cond/brl.call.  */
    443   if (!(IS_BR_COND (br_code) || IS_BR_CALL (br_code)))
    444     return FALSE;
    445 
    446   /* Turn br into brl by setting bit 40.  */
    447   br_code |= 0x1LL << 40;
    448 
    449   /* Turn the old bundle into a MLX bundle with the same stop-bit
    450      variety.  */
    451   if (t0 & 0x1)
    452     mlx = 0x5;
    453   else
    454     mlx = 0x4;
    455 
    456   if (template_val == 0x16)
    457     {
    458       /* For BBB, we need to put nop.m in slot 0.  We keep the original
    459 	 predicate only if slot 0 isn't br.  */
    460       if (br_slot == 0)
    461 	t0 = 0LL;
    462       else
    463 	t0 &= PREDICATE_BITS << 5;
    464       t0 |= 0x1LL << (X4_SHIFT + 5);
    465     }
    466   else
    467     {
    468       /* Keep the original instruction in slot 0.  */
    469       t0 &= 0x1ffffffffffLL << 5;
    470     }
    471 
    472   t0 |= mlx;
    473 
    474   /* Put brl in slot 1.  */
    475   t1 = br_code << 23;
    476 
    477   bfd_putl64 (t0, hit_addr);
    478   bfd_putl64 (t1, hit_addr + 8);
    479   return TRUE;
    480 }
    481 
    482 void
    483 ia64_elf_relax_brl (bfd_byte *contents, bfd_vma off)
    484 {
    485   int template_val;
    486   bfd_byte *hit_addr;
    487   bfd_vma t0, t1, i0, i1, i2;
    488 
    489   hit_addr = (bfd_byte *) (contents + off);
    490   hit_addr -= (intptr_t) hit_addr & 0x3;
    491   t0 = bfd_getl64 (hit_addr);
    492   t1 = bfd_getl64 (hit_addr + 8);
    493 
    494   /* Keep the instruction in slot 0. */
    495   i0 = (t0 >> 5) & 0x1ffffffffffLL;
    496   /* Use nop.b for slot 1. */
    497   i1 = 0x4000000000LL;
    498   /* For slot 2, turn brl into br by masking out bit 40.  */
    499   i2 = (t1 >> 23) & 0x0ffffffffffLL;
    500 
    501   /* Turn a MLX bundle into a MBB bundle with the same stop-bit
    502      variety.  */
    503   if (t0 & 0x1)
    504     template_val = 0x13;
    505   else
    506     template_val = 0x12;
    507   t0 = (i1 << 46) | (i0 << 5) | template_val;
    508   t1 = (i2 << 23) | (i1 >> 18);
    509 
    510   bfd_putl64 (t0, hit_addr);
    511   bfd_putl64 (t1, hit_addr + 8);
    512 }
    513 
    514 void
    515 ia64_elf_relax_ldxmov (bfd_byte *contents, bfd_vma off)
    516 {
    517   int shift, r1, r3;
    518   bfd_vma dword, insn;
    519 
    520   switch ((int)off & 0x3)
    521     {
    522     case 0: shift =  5; break;
    523     case 1: shift = 14; off += 3; break;
    524     case 2: shift = 23; off += 6; break;
    525     default:
    526       abort ();
    527     }
    528 
    529   dword = bfd_getl64 (contents + off);
    530   insn = (dword >> shift) & 0x1ffffffffffLL;
    531 
    532   r1 = (insn >> 6) & 127;
    533   r3 = (insn >> 20) & 127;
    534   if (r1 == r3)
    535     insn = 0x8000000;				   /* nop */
    536   else
    537     insn = (insn & 0x7f01fff) | 0x10800000000LL;   /* (qp) mov r1 = r3 */
    538 
    539   dword &= ~(0x1ffffffffffLL << shift);
    540   dword |= (insn << shift);
    541   bfd_putl64 (dword, contents + off);
    542 }
    543 
    544 bfd_reloc_status_type
    546 ia64_elf_install_value (bfd_byte *hit_addr, bfd_vma v, unsigned int r_type)
    547 {
    548   const struct ia64_operand *op;
    549   int bigendian = 0, shift = 0;
    550   bfd_vma t0, t1, dword;
    551   ia64_insn insn;
    552   enum ia64_opnd opnd;
    553   const char *err;
    554   size_t size = 8;
    555 #ifdef BFD_HOST_U_64_BIT
    556   BFD_HOST_U_64_BIT val = (BFD_HOST_U_64_BIT) v;
    557 #else
    558   bfd_vma val = v;
    559 #endif
    560 
    561   opnd = IA64_OPND_NIL;
    562   switch (r_type)
    563     {
    564     case R_IA64_NONE:
    565     case R_IA64_LDXMOV:
    566       return bfd_reloc_ok;
    567 
    568       /* Instruction relocations.  */
    569 
    570     case R_IA64_IMM14:
    571     case R_IA64_TPREL14:
    572     case R_IA64_DTPREL14:
    573       opnd = IA64_OPND_IMM14;
    574       break;
    575 
    576     case R_IA64_PCREL21F:	opnd = IA64_OPND_TGT25; break;
    577     case R_IA64_PCREL21M:	opnd = IA64_OPND_TGT25b; break;
    578     case R_IA64_PCREL60B:	opnd = IA64_OPND_TGT64; break;
    579     case R_IA64_PCREL21B:
    580     case R_IA64_PCREL21BI:
    581       opnd = IA64_OPND_TGT25c;
    582       break;
    583 
    584     case R_IA64_IMM22:
    585     case R_IA64_GPREL22:
    586     case R_IA64_LTOFF22:
    587     case R_IA64_LTOFF22X:
    588     case R_IA64_PLTOFF22:
    589     case R_IA64_PCREL22:
    590     case R_IA64_LTOFF_FPTR22:
    591     case R_IA64_TPREL22:
    592     case R_IA64_DTPREL22:
    593     case R_IA64_LTOFF_TPREL22:
    594     case R_IA64_LTOFF_DTPMOD22:
    595     case R_IA64_LTOFF_DTPREL22:
    596       opnd = IA64_OPND_IMM22;
    597       break;
    598 
    599     case R_IA64_IMM64:
    600     case R_IA64_GPREL64I:
    601     case R_IA64_LTOFF64I:
    602     case R_IA64_PLTOFF64I:
    603     case R_IA64_PCREL64I:
    604     case R_IA64_FPTR64I:
    605     case R_IA64_LTOFF_FPTR64I:
    606     case R_IA64_TPREL64I:
    607     case R_IA64_DTPREL64I:
    608       opnd = IA64_OPND_IMMU64;
    609       break;
    610 
    611       /* Data relocations.  */
    612 
    613     case R_IA64_DIR32MSB:
    614     case R_IA64_GPREL32MSB:
    615     case R_IA64_FPTR32MSB:
    616     case R_IA64_PCREL32MSB:
    617     case R_IA64_LTOFF_FPTR32MSB:
    618     case R_IA64_SEGREL32MSB:
    619     case R_IA64_SECREL32MSB:
    620     case R_IA64_LTV32MSB:
    621     case R_IA64_DTPREL32MSB:
    622       size = 4; bigendian = 1;
    623       break;
    624 
    625     case R_IA64_DIR32LSB:
    626     case R_IA64_GPREL32LSB:
    627     case R_IA64_FPTR32LSB:
    628     case R_IA64_PCREL32LSB:
    629     case R_IA64_LTOFF_FPTR32LSB:
    630     case R_IA64_SEGREL32LSB:
    631     case R_IA64_SECREL32LSB:
    632     case R_IA64_LTV32LSB:
    633     case R_IA64_DTPREL32LSB:
    634       size = 4; bigendian = 0;
    635       break;
    636 
    637     case R_IA64_DIR64MSB:
    638     case R_IA64_GPREL64MSB:
    639     case R_IA64_PLTOFF64MSB:
    640     case R_IA64_FPTR64MSB:
    641     case R_IA64_PCREL64MSB:
    642     case R_IA64_LTOFF_FPTR64MSB:
    643     case R_IA64_SEGREL64MSB:
    644     case R_IA64_SECREL64MSB:
    645     case R_IA64_LTV64MSB:
    646     case R_IA64_TPREL64MSB:
    647     case R_IA64_DTPMOD64MSB:
    648     case R_IA64_DTPREL64MSB:
    649       size = 8; bigendian = 1;
    650       break;
    651 
    652     case R_IA64_DIR64LSB:
    653     case R_IA64_GPREL64LSB:
    654     case R_IA64_PLTOFF64LSB:
    655     case R_IA64_FPTR64LSB:
    656     case R_IA64_PCREL64LSB:
    657     case R_IA64_LTOFF_FPTR64LSB:
    658     case R_IA64_SEGREL64LSB:
    659     case R_IA64_SECREL64LSB:
    660     case R_IA64_LTV64LSB:
    661     case R_IA64_TPREL64LSB:
    662     case R_IA64_DTPMOD64LSB:
    663     case R_IA64_DTPREL64LSB:
    664       size = 8; bigendian = 0;
    665       break;
    666 
    667       /* Unsupported / Dynamic relocations.  */
    668     default:
    669       return bfd_reloc_notsupported;
    670     }
    671 
    672   switch (opnd)
    673     {
    674     case IA64_OPND_IMMU64:
    675       hit_addr -= (intptr_t) hit_addr & 0x3;
    676       t0 = bfd_getl64 (hit_addr);
    677       t1 = bfd_getl64 (hit_addr + 8);
    678 
    679       /* tmpl/s: bits  0.. 5 in t0
    680 	 slot 0: bits  5..45 in t0
    681 	 slot 1: bits 46..63 in t0, bits 0..22 in t1
    682 	 slot 2: bits 23..63 in t1 */
    683 
    684       /* First, clear the bits that form the 64 bit constant.  */
    685       t0 &= ~(0x3ffffLL << 46);
    686       t1 &= ~(0x7fffffLL
    687 	      | ((  (0x07fLL << 13) | (0x1ffLL << 27)
    688 		    | (0x01fLL << 22) | (0x001LL << 21)
    689 		    | (0x001LL << 36)) << 23));
    690 
    691       t0 |= ((val >> 22) & 0x03ffffLL) << 46;		/* 18 lsbs of imm41 */
    692       t1 |= ((val >> 40) & 0x7fffffLL) <<  0;		/* 23 msbs of imm41 */
    693       t1 |= (  (((val >>  0) & 0x07f) << 13)		/* imm7b */
    694 	       | (((val >>  7) & 0x1ff) << 27)		/* imm9d */
    695 	       | (((val >> 16) & 0x01f) << 22)		/* imm5c */
    696 	       | (((val >> 21) & 0x001) << 21)		/* ic */
    697 	       | (((val >> 63) & 0x001) << 36)) << 23;	/* i */
    698 
    699       bfd_putl64 (t0, hit_addr);
    700       bfd_putl64 (t1, hit_addr + 8);
    701       break;
    702 
    703     case IA64_OPND_TGT64:
    704       hit_addr -= (intptr_t) hit_addr & 0x3;
    705       t0 = bfd_getl64 (hit_addr);
    706       t1 = bfd_getl64 (hit_addr + 8);
    707 
    708       /* tmpl/s: bits  0.. 5 in t0
    709 	 slot 0: bits  5..45 in t0
    710 	 slot 1: bits 46..63 in t0, bits 0..22 in t1
    711 	 slot 2: bits 23..63 in t1 */
    712 
    713       /* First, clear the bits that form the 64 bit constant.  */
    714       t0 &= ~(0x3ffffLL << 46);
    715       t1 &= ~(0x7fffffLL
    716 	      | ((1LL << 36 | 0xfffffLL << 13) << 23));
    717 
    718       val >>= 4;
    719       t0 |= ((val >> 20) & 0xffffLL) << 2 << 46;	/* 16 lsbs of imm39 */
    720       t1 |= ((val >> 36) & 0x7fffffLL) << 0;		/* 23 msbs of imm39 */
    721       t1 |= ((((val >> 0) & 0xfffffLL) << 13)		/* imm20b */
    722 	      | (((val >> 59) & 0x1LL) << 36)) << 23;	/* i */
    723 
    724       bfd_putl64 (t0, hit_addr);
    725       bfd_putl64 (t1, hit_addr + 8);
    726       break;
    727 
    728     default:
    729       switch ((intptr_t) hit_addr & 0x3)
    730 	{
    731 	case 0: shift =  5; break;
    732 	case 1: shift = 14; hit_addr += 3; break;
    733 	case 2: shift = 23; hit_addr += 6; break;
    734 	case 3: return bfd_reloc_notsupported; /* shouldn't happen...  */
    735 	}
    736       dword = bfd_getl64 (hit_addr);
    737       insn = (dword >> shift) & 0x1ffffffffffLL;
    738 
    739       op = elf64_ia64_operands + opnd;
    740       err = (*op->insert) (op, val, &insn);
    741       if (err)
    742 	return bfd_reloc_overflow;
    743 
    744       dword &= ~(0x1ffffffffffLL << shift);
    745       dword |= (insn << shift);
    746       bfd_putl64 (dword, hit_addr);
    747       break;
    748 
    749     case IA64_OPND_NIL:
    750       /* A data relocation.  */
    751       if (bigendian)
    752 	if (size == 4)
    753 	  bfd_putb32 (val, hit_addr);
    754 	else
    755 	  bfd_putb64 (val, hit_addr);
    756       else
    757 	if (size == 4)
    758 	  bfd_putl32 (val, hit_addr);
    759 	else
    760 	  bfd_putl64 (val, hit_addr);
    761       break;
    762     }
    763 
    764   return bfd_reloc_ok;
    765 }
    766