Home | History | Annotate | Line # | Download | only in bfd
elfnn-ia64.c revision 1.1.1.5.4.1
      1          1.1  christos /* IA-64 support for 64-bit ELF
      2  1.1.1.5.4.1  christos    Copyright (C) 1998-2019 Free Software Foundation, Inc.
      3          1.1  christos    Contributed by David Mosberger-Tang <davidm (at) hpl.hp.com>
      4          1.1  christos 
      5          1.1  christos    This file is part of BFD, the Binary File Descriptor library.
      6          1.1  christos 
      7          1.1  christos    This program is free software; you can redistribute it and/or modify
      8          1.1  christos    it under the terms of the GNU General Public License as published by
      9          1.1  christos    the Free Software Foundation; either version 3 of the License, or
     10          1.1  christos    (at your option) any later version.
     11          1.1  christos 
     12          1.1  christos    This program is distributed in the hope that it will be useful,
     13          1.1  christos    but WITHOUT ANY WARRANTY; without even the implied warranty of
     14          1.1  christos    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     15          1.1  christos    GNU General Public License for more details.
     16          1.1  christos 
     17          1.1  christos    You should have received a copy of the GNU General Public License
     18          1.1  christos    along with this program; if not, write to the Free Software
     19          1.1  christos    Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
     20          1.1  christos    MA 02110-1301, USA.  */
     21          1.1  christos 
     22          1.1  christos #include "sysdep.h"
     23          1.1  christos #include "bfd.h"
     24          1.1  christos #include "libbfd.h"
     25          1.1  christos #include "elf-bfd.h"
     26          1.1  christos #include "opcode/ia64.h"
     27          1.1  christos #include "elf/ia64.h"
     28          1.1  christos #include "objalloc.h"
     29          1.1  christos #include "hashtab.h"
     30          1.1  christos #include "elfxx-ia64.h"
     31          1.1  christos 
     32          1.1  christos #define ARCH_SIZE	NN
     33          1.1  christos 
     34          1.1  christos #if ARCH_SIZE == 64
     35          1.1  christos #define	LOG_SECTION_ALIGN	3
     36          1.1  christos #endif
     37          1.1  christos 
     38          1.1  christos #if ARCH_SIZE == 32
     39          1.1  christos #define	LOG_SECTION_ALIGN	2
     40          1.1  christos #endif
     41          1.1  christos 
     42          1.1  christos typedef struct bfd_hash_entry *(*new_hash_entry_func)
     43          1.1  christos   (struct bfd_hash_entry *, struct bfd_hash_table *, const char *);
     44          1.1  christos 
     45          1.1  christos /* In dynamically (linker-) created sections, we generally need to keep track
     46          1.1  christos    of the place a symbol or expression got allocated to. This is done via hash
     47          1.1  christos    tables that store entries of the following type.  */
     48          1.1  christos 
     49          1.1  christos struct elfNN_ia64_dyn_sym_info
     50          1.1  christos {
     51          1.1  christos   /* The addend for which this entry is relevant.  */
     52          1.1  christos   bfd_vma addend;
     53          1.1  christos 
     54          1.1  christos   bfd_vma got_offset;
     55          1.1  christos   bfd_vma fptr_offset;
     56          1.1  christos   bfd_vma pltoff_offset;
     57          1.1  christos   bfd_vma plt_offset;
     58          1.1  christos   bfd_vma plt2_offset;
     59          1.1  christos   bfd_vma tprel_offset;
     60          1.1  christos   bfd_vma dtpmod_offset;
     61          1.1  christos   bfd_vma dtprel_offset;
     62          1.1  christos 
     63          1.1  christos   /* The symbol table entry, if any, that this was derived from.  */
     64          1.1  christos   struct elf_link_hash_entry *h;
     65          1.1  christos 
     66          1.1  christos   /* Used to count non-got, non-plt relocations for delayed sizing
     67          1.1  christos      of relocation sections.  */
     68          1.1  christos   struct elfNN_ia64_dyn_reloc_entry
     69          1.1  christos   {
     70          1.1  christos     struct elfNN_ia64_dyn_reloc_entry *next;
     71          1.1  christos     asection *srel;
     72          1.1  christos     int type;
     73          1.1  christos     int count;
     74          1.1  christos 
     75          1.1  christos     /* Is this reloc against readonly section? */
     76          1.1  christos     bfd_boolean reltext;
     77          1.1  christos   } *reloc_entries;
     78          1.1  christos 
     79          1.1  christos   /* TRUE when the section contents have been updated.  */
     80          1.1  christos   unsigned got_done : 1;
     81          1.1  christos   unsigned fptr_done : 1;
     82          1.1  christos   unsigned pltoff_done : 1;
     83          1.1  christos   unsigned tprel_done : 1;
     84          1.1  christos   unsigned dtpmod_done : 1;
     85          1.1  christos   unsigned dtprel_done : 1;
     86          1.1  christos 
     87          1.1  christos   /* TRUE for the different kinds of linker data we want created.  */
     88          1.1  christos   unsigned want_got : 1;
     89          1.1  christos   unsigned want_gotx : 1;
     90          1.1  christos   unsigned want_fptr : 1;
     91          1.1  christos   unsigned want_ltoff_fptr : 1;
     92          1.1  christos   unsigned want_plt : 1;
     93          1.1  christos   unsigned want_plt2 : 1;
     94          1.1  christos   unsigned want_pltoff : 1;
     95          1.1  christos   unsigned want_tprel : 1;
     96          1.1  christos   unsigned want_dtpmod : 1;
     97          1.1  christos   unsigned want_dtprel : 1;
     98          1.1  christos };
     99          1.1  christos 
    100          1.1  christos struct elfNN_ia64_local_hash_entry
    101          1.1  christos {
    102          1.1  christos   int id;
    103          1.1  christos   unsigned int r_sym;
    104          1.1  christos   /* The number of elements in elfNN_ia64_dyn_sym_info array.  */
    105          1.1  christos   unsigned int count;
    106          1.1  christos   /* The number of sorted elements in elfNN_ia64_dyn_sym_info array.  */
    107          1.1  christos   unsigned int sorted_count;
    108          1.1  christos   /* The size of elfNN_ia64_dyn_sym_info array.  */
    109          1.1  christos   unsigned int size;
    110          1.1  christos   /* The array of elfNN_ia64_dyn_sym_info.  */
    111          1.1  christos   struct elfNN_ia64_dyn_sym_info *info;
    112          1.1  christos 
    113          1.1  christos   /* TRUE if this hash entry's addends was translated for
    114          1.1  christos      SHF_MERGE optimization.  */
    115          1.1  christos   unsigned sec_merge_done : 1;
    116          1.1  christos };
    117          1.1  christos 
    118          1.1  christos struct elfNN_ia64_link_hash_entry
    119          1.1  christos {
    120          1.1  christos   struct elf_link_hash_entry root;
    121          1.1  christos   /* The number of elements in elfNN_ia64_dyn_sym_info array.  */
    122          1.1  christos   unsigned int count;
    123          1.1  christos   /* The number of sorted elements in elfNN_ia64_dyn_sym_info array.  */
    124          1.1  christos   unsigned int sorted_count;
    125          1.1  christos   /* The size of elfNN_ia64_dyn_sym_info array.  */
    126          1.1  christos   unsigned int size;
    127          1.1  christos   /* The array of elfNN_ia64_dyn_sym_info.  */
    128          1.1  christos   struct elfNN_ia64_dyn_sym_info *info;
    129          1.1  christos };
    130          1.1  christos 
    131          1.1  christos struct elfNN_ia64_link_hash_table
    132          1.1  christos {
    133          1.1  christos   /* The main hash table.  */
    134          1.1  christos   struct elf_link_hash_table root;
    135          1.1  christos 
    136          1.1  christos   asection *fptr_sec;		/* Function descriptor table (or NULL).  */
    137          1.1  christos   asection *rel_fptr_sec;	/* Dynamic relocation section for same.  */
    138          1.1  christos   asection *pltoff_sec;		/* Private descriptors for plt (or NULL).  */
    139          1.1  christos   asection *rel_pltoff_sec;	/* Dynamic relocation section for same.  */
    140          1.1  christos 
    141          1.1  christos   bfd_size_type minplt_entries;	/* Number of minplt entries.  */
    142          1.1  christos   unsigned reltext : 1;		/* Are there relocs against readonly sections?  */
    143          1.1  christos   unsigned self_dtpmod_done : 1;/* Has self DTPMOD entry been finished?  */
    144          1.1  christos   bfd_vma self_dtpmod_offset;	/* .got offset to self DTPMOD entry.  */
    145          1.1  christos   /* There are maybe R_IA64_GPREL22 relocations, including those
    146          1.1  christos      optimized from R_IA64_LTOFF22X, against non-SHF_IA_64_SHORT
    147          1.1  christos      sections.  We need to record those sections so that we can choose
    148          1.1  christos      a proper GP to cover all R_IA64_GPREL22 relocations.  */
    149          1.1  christos   asection *max_short_sec;	/* Maximum short output section.  */
    150          1.1  christos   bfd_vma max_short_offset;	/* Maximum short offset.  */
    151          1.1  christos   asection *min_short_sec;	/* Minimum short output section.  */
    152          1.1  christos   bfd_vma min_short_offset;	/* Minimum short offset.  */
    153          1.1  christos 
    154          1.1  christos   htab_t loc_hash_table;
    155          1.1  christos   void *loc_hash_memory;
    156          1.1  christos };
    157          1.1  christos 
    158          1.1  christos struct elfNN_ia64_allocate_data
    159          1.1  christos {
    160          1.1  christos   struct bfd_link_info *info;
    161          1.1  christos   bfd_size_type ofs;
    162          1.1  christos   bfd_boolean only_got;
    163          1.1  christos };
    164          1.1  christos 
    165          1.1  christos #define elfNN_ia64_hash_table(p) \
    166          1.1  christos   (elf_hash_table_id ((struct elf_link_hash_table *) ((p)->hash)) \
    167          1.1  christos   == IA64_ELF_DATA ? ((struct elfNN_ia64_link_hash_table *) ((p)->hash)) : NULL)
    168          1.1  christos 
    169          1.1  christos static struct elfNN_ia64_dyn_sym_info * get_dyn_sym_info
    170          1.1  christos   (struct elfNN_ia64_link_hash_table *ia64_info,
    171          1.1  christos    struct elf_link_hash_entry *h,
    172          1.1  christos    bfd *abfd, const Elf_Internal_Rela *rel, bfd_boolean create);
    173          1.1  christos static bfd_boolean elfNN_ia64_dynamic_symbol_p
    174          1.1  christos   (struct elf_link_hash_entry *h, struct bfd_link_info *info, int);
    175          1.1  christos static bfd_boolean elfNN_ia64_choose_gp
    176          1.1  christos   (bfd *abfd, struct bfd_link_info *info, bfd_boolean final);
    177          1.1  christos static void elfNN_ia64_dyn_sym_traverse
    178          1.1  christos   (struct elfNN_ia64_link_hash_table *ia64_info,
    179          1.1  christos    bfd_boolean (*func) (struct elfNN_ia64_dyn_sym_info *, void *),
    180          1.1  christos    void * info);
    181          1.1  christos static bfd_boolean allocate_global_data_got
    182          1.1  christos   (struct elfNN_ia64_dyn_sym_info *dyn_i, void * data);
    183          1.1  christos static bfd_boolean allocate_global_fptr_got
    184          1.1  christos   (struct elfNN_ia64_dyn_sym_info *dyn_i, void * data);
    185          1.1  christos static bfd_boolean allocate_local_got
    186          1.1  christos   (struct elfNN_ia64_dyn_sym_info *dyn_i, void * data);
    187          1.1  christos static bfd_boolean elfNN_ia64_hpux_vec
    188          1.1  christos   (const bfd_target *vec);
    189          1.1  christos static bfd_boolean allocate_dynrel_entries
    190          1.1  christos   (struct elfNN_ia64_dyn_sym_info *dyn_i, void * data);
    191          1.1  christos static asection *get_pltoff
    192          1.1  christos   (bfd *abfd, struct bfd_link_info *info,
    193          1.1  christos    struct elfNN_ia64_link_hash_table *ia64_info);
    194          1.1  christos 
    195          1.1  christos /* ia64-specific relocation.  */
    197          1.1  christos 
    198          1.1  christos /* Given a ELF reloc, return the matching HOWTO structure.  */
    199  1.1.1.5.4.1  christos 
    200          1.1  christos static bfd_boolean
    201          1.1  christos elfNN_ia64_info_to_howto (bfd *abfd ATTRIBUTE_UNUSED,
    202          1.1  christos 			  arelent *bfd_reloc,
    203          1.1  christos 			  Elf_Internal_Rela *elf_reloc)
    204  1.1.1.5.4.1  christos {
    205  1.1.1.5.4.1  christos   unsigned int r_type = ELF32_R_TYPE (elf_reloc->r_info);
    206  1.1.1.5.4.1  christos 
    207  1.1.1.5.4.1  christos   bfd_reloc->howto = ia64_elf_lookup_howto (r_type);
    208  1.1.1.5.4.1  christos   if (bfd_reloc->howto == NULL)
    209  1.1.1.5.4.1  christos     {
    210  1.1.1.5.4.1  christos       /* xgettext:c-format */
    211  1.1.1.5.4.1  christos       _bfd_error_handler (_("%pB: unsupported relocation type %#x"),
    212  1.1.1.5.4.1  christos 			  abfd, r_type);
    213  1.1.1.5.4.1  christos       bfd_set_error (bfd_error_bad_value);
    214  1.1.1.5.4.1  christos       return FALSE;
    215  1.1.1.5.4.1  christos     }
    216  1.1.1.5.4.1  christos 
    217          1.1  christos   return TRUE;
    218          1.1  christos }
    219          1.1  christos 
    220          1.1  christos #define PLT_HEADER_SIZE		(3 * 16)
    222          1.1  christos #define PLT_MIN_ENTRY_SIZE	(1 * 16)
    223          1.1  christos #define PLT_FULL_ENTRY_SIZE	(2 * 16)
    224          1.1  christos #define PLT_RESERVED_WORDS	3
    225          1.1  christos 
    226  1.1.1.5.4.1  christos static const bfd_byte plt_header[PLT_HEADER_SIZE] =
    227  1.1.1.5.4.1  christos {
    228  1.1.1.5.4.1  christos   0x0b, 0x10, 0x00, 0x1c, 0x00, 0x21,  /*   [MMI]	mov r2=r14;;	   */
    229  1.1.1.5.4.1  christos   0xe0, 0x00, 0x08, 0x00, 0x48, 0x00,  /*		addl r14=0,r2	   */
    230  1.1.1.5.4.1  christos   0x00, 0x00, 0x04, 0x00,	       /*		nop.i 0x0;;	   */
    231  1.1.1.5.4.1  christos   0x0b, 0x80, 0x20, 0x1c, 0x18, 0x14,  /*   [MMI]	ld8 r16=[r14],8;;  */
    232  1.1.1.5.4.1  christos   0x10, 0x41, 0x38, 0x30, 0x28, 0x00,  /*		ld8 r17=[r14],8	   */
    233  1.1.1.5.4.1  christos   0x00, 0x00, 0x04, 0x00,	       /*		nop.i 0x0;;	   */
    234  1.1.1.5.4.1  christos   0x11, 0x08, 0x00, 0x1c, 0x18, 0x10,  /*   [MIB]	ld8 r1=[r14]	   */
    235          1.1  christos   0x60, 0x88, 0x04, 0x80, 0x03, 0x00,  /*		mov b6=r17	   */
    236          1.1  christos   0x60, 0x00, 0x80, 0x00	       /*		br.few b6;;	   */
    237          1.1  christos };
    238          1.1  christos 
    239  1.1.1.5.4.1  christos static const bfd_byte plt_min_entry[PLT_MIN_ENTRY_SIZE] =
    240  1.1.1.5.4.1  christos {
    241  1.1.1.5.4.1  christos   0x11, 0x78, 0x00, 0x00, 0x00, 0x24,  /*   [MIB]	mov r15=0	   */
    242          1.1  christos   0x00, 0x00, 0x00, 0x02, 0x00, 0x00,  /*		nop.i 0x0	   */
    243          1.1  christos   0x00, 0x00, 0x00, 0x40	       /*		br.few 0 <PLT0>;;  */
    244          1.1  christos };
    245          1.1  christos 
    246  1.1.1.5.4.1  christos static const bfd_byte plt_full_entry[PLT_FULL_ENTRY_SIZE] =
    247  1.1.1.5.4.1  christos {
    248  1.1.1.5.4.1  christos   0x0b, 0x78, 0x00, 0x02, 0x00, 0x24,  /*   [MMI]	addl r15=0,r1;;	   */
    249  1.1.1.5.4.1  christos   0x00, 0x41, 0x3c, 0x70, 0x29, 0xc0,  /*		ld8.acq r16=[r15],8*/
    250  1.1.1.5.4.1  christos   0x01, 0x08, 0x00, 0x84,	       /*		mov r14=r1;;	   */
    251  1.1.1.5.4.1  christos   0x11, 0x08, 0x00, 0x1e, 0x18, 0x10,  /*   [MIB]	ld8 r1=[r15]	   */
    252          1.1  christos   0x60, 0x80, 0x04, 0x80, 0x03, 0x00,  /*		mov b6=r16	   */
    253          1.1  christos   0x60, 0x00, 0x80, 0x00	       /*		br.few b6;;	   */
    254          1.1  christos };
    255          1.1  christos 
    256          1.1  christos #define ELF_DYNAMIC_INTERPRETER "/usr/lib/ld.so.1"
    257          1.1  christos 
    258  1.1.1.5.4.1  christos static const bfd_byte oor_brl[16] =
    259  1.1.1.5.4.1  christos {
    260          1.1  christos   0x05, 0x00, 0x00, 0x00, 0x01, 0x00,  /*  [MLX]	nop.m 0		   */
    261          1.1  christos   0x00, 0x00, 0x00, 0x00, 0x00, 0x00,  /*		brl.sptk.few tgt;; */
    262          1.1  christos   0x00, 0x00, 0x00, 0xc0
    263          1.1  christos };
    264          1.1  christos 
    265  1.1.1.5.4.1  christos static const bfd_byte oor_ip[48] =
    266  1.1.1.5.4.1  christos {
    267          1.1  christos   0x04, 0x00, 0x00, 0x00, 0x01, 0x00,  /*  [MLX]	nop.m 0		   */
    268  1.1.1.5.4.1  christos   0x00, 0x00, 0x00, 0x00, 0x00, 0xe0,  /*		movl r15=0	   */
    269  1.1.1.5.4.1  christos   0x01, 0x00, 0x00, 0x60,
    270  1.1.1.5.4.1  christos   0x03, 0x00, 0x00, 0x00, 0x01, 0x00,  /*  [MII]	nop.m 0		   */
    271  1.1.1.5.4.1  christos   0x00, 0x01, 0x00, 0x60, 0x00, 0x00,  /*		mov r16=ip;;	   */
    272  1.1.1.5.4.1  christos   0xf2, 0x80, 0x00, 0x80,	       /*		add r16=r15,r16;;  */
    273  1.1.1.5.4.1  christos   0x11, 0x00, 0x00, 0x00, 0x01, 0x00,  /*  [MIB]	nop.m 0		   */
    274          1.1  christos   0x60, 0x80, 0x04, 0x80, 0x03, 0x00,  /*		mov b6=r16	   */
    275          1.1  christos   0x60, 0x00, 0x80, 0x00	       /*		br b6;;		   */
    276          1.1  christos };
    277          1.1  christos 
    278          1.1  christos static size_t oor_branch_size = sizeof (oor_brl);
    279          1.1  christos 
    280          1.1  christos void
    281          1.1  christos bfd_elfNN_ia64_after_parse (int itanium)
    282          1.1  christos {
    283          1.1  christos   oor_branch_size = itanium ? sizeof (oor_ip) : sizeof (oor_brl);
    284          1.1  christos }
    285          1.1  christos 
    286          1.1  christos 
    288          1.1  christos /* Rename some of the generic section flags to better document how they
    289          1.1  christos    are used here.  */
    290          1.1  christos #define skip_relax_pass_0 sec_flg0
    291          1.1  christos #define skip_relax_pass_1 sec_flg1
    292          1.1  christos 
    293          1.1  christos /* These functions do relaxation for IA-64 ELF.  */
    294          1.1  christos 
    295          1.1  christos static void
    296          1.1  christos elfNN_ia64_update_short_info (asection *sec, bfd_vma offset,
    297          1.1  christos 			      struct elfNN_ia64_link_hash_table *ia64_info)
    298          1.1  christos {
    299          1.1  christos   /* Skip ABS and SHF_IA_64_SHORT sections.  */
    300          1.1  christos   if (sec == bfd_abs_section_ptr
    301          1.1  christos       || (sec->flags & SEC_SMALL_DATA) != 0)
    302          1.1  christos     return;
    303          1.1  christos 
    304          1.1  christos   if (!ia64_info->min_short_sec)
    305          1.1  christos     {
    306          1.1  christos       ia64_info->max_short_sec = sec;
    307          1.1  christos       ia64_info->max_short_offset = offset;
    308          1.1  christos       ia64_info->min_short_sec = sec;
    309          1.1  christos       ia64_info->min_short_offset = offset;
    310          1.1  christos     }
    311          1.1  christos   else if (sec == ia64_info->max_short_sec
    312          1.1  christos 	   && offset > ia64_info->max_short_offset)
    313          1.1  christos     ia64_info->max_short_offset = offset;
    314          1.1  christos   else if (sec == ia64_info->min_short_sec
    315          1.1  christos 	   && offset < ia64_info->min_short_offset)
    316          1.1  christos     ia64_info->min_short_offset = offset;
    317          1.1  christos   else if (sec->output_section->vma
    318          1.1  christos 	   > ia64_info->max_short_sec->vma)
    319          1.1  christos     {
    320          1.1  christos       ia64_info->max_short_sec = sec;
    321          1.1  christos       ia64_info->max_short_offset = offset;
    322          1.1  christos     }
    323          1.1  christos   else if (sec->output_section->vma
    324          1.1  christos 	   < ia64_info->min_short_sec->vma)
    325          1.1  christos     {
    326          1.1  christos       ia64_info->min_short_sec = sec;
    327          1.1  christos       ia64_info->min_short_offset = offset;
    328          1.1  christos     }
    329          1.1  christos }
    330          1.1  christos 
    331          1.1  christos static bfd_boolean
    332          1.1  christos elfNN_ia64_relax_section (bfd *abfd, asection *sec,
    333          1.1  christos 			  struct bfd_link_info *link_info,
    334          1.1  christos 			  bfd_boolean *again)
    335          1.1  christos {
    336          1.1  christos   struct one_fixup
    337          1.1  christos     {
    338          1.1  christos       struct one_fixup *next;
    339          1.1  christos       asection *tsec;
    340          1.1  christos       bfd_vma toff;
    341          1.1  christos       bfd_vma trampoff;
    342          1.1  christos     };
    343          1.1  christos 
    344          1.1  christos   Elf_Internal_Shdr *symtab_hdr;
    345          1.1  christos   Elf_Internal_Rela *internal_relocs;
    346          1.1  christos   Elf_Internal_Rela *irel, *irelend;
    347          1.1  christos   bfd_byte *contents;
    348          1.1  christos   Elf_Internal_Sym *isymbuf = NULL;
    349          1.1  christos   struct elfNN_ia64_link_hash_table *ia64_info;
    350          1.1  christos   struct one_fixup *fixups = NULL;
    351          1.1  christos   bfd_boolean changed_contents = FALSE;
    352          1.1  christos   bfd_boolean changed_relocs = FALSE;
    353          1.1  christos   bfd_boolean changed_got = FALSE;
    354          1.1  christos   bfd_boolean skip_relax_pass_0 = TRUE;
    355          1.1  christos   bfd_boolean skip_relax_pass_1 = TRUE;
    356          1.1  christos   bfd_vma gp = 0;
    357          1.1  christos 
    358          1.1  christos   /* Assume we're not going to change any sizes, and we'll only need
    359      1.1.1.4  christos      one pass.  */
    360          1.1  christos   *again = FALSE;
    361          1.1  christos 
    362          1.1  christos   if (bfd_link_relocatable (link_info))
    363          1.1  christos     (*link_info->callbacks->einfo)
    364          1.1  christos       (_("%P%F: --relax and -r may not be used together\n"));
    365          1.1  christos 
    366          1.1  christos   /* Don't even try to relax for non-ELF outputs.  */
    367          1.1  christos   if (!is_elf_hash_table (link_info->hash))
    368          1.1  christos     return FALSE;
    369          1.1  christos 
    370          1.1  christos   /* Nothing to do if there are no relocations or there is no need for
    371          1.1  christos      the current pass.  */
    372          1.1  christos   if ((sec->flags & SEC_RELOC) == 0
    373          1.1  christos       || sec->reloc_count == 0
    374          1.1  christos       || (link_info->relax_pass == 0 && sec->skip_relax_pass_0)
    375          1.1  christos       || (link_info->relax_pass == 1 && sec->skip_relax_pass_1))
    376          1.1  christos     return TRUE;
    377          1.1  christos 
    378          1.1  christos   ia64_info = elfNN_ia64_hash_table (link_info);
    379          1.1  christos   if (ia64_info == NULL)
    380          1.1  christos     return FALSE;
    381          1.1  christos 
    382          1.1  christos   symtab_hdr = &elf_tdata (abfd)->symtab_hdr;
    383          1.1  christos 
    384          1.1  christos   /* Load the relocations for this section.  */
    385          1.1  christos   internal_relocs = (_bfd_elf_link_read_relocs
    386          1.1  christos 		     (abfd, sec, NULL, (Elf_Internal_Rela *) NULL,
    387          1.1  christos 		      link_info->keep_memory));
    388          1.1  christos   if (internal_relocs == NULL)
    389          1.1  christos     return FALSE;
    390          1.1  christos 
    391          1.1  christos   irelend = internal_relocs + sec->reloc_count;
    392          1.1  christos 
    393          1.1  christos   /* Get the section contents.  */
    394          1.1  christos   if (elf_section_data (sec)->this_hdr.contents != NULL)
    395          1.1  christos     contents = elf_section_data (sec)->this_hdr.contents;
    396          1.1  christos   else
    397          1.1  christos     {
    398          1.1  christos       if (!bfd_malloc_and_get_section (abfd, sec, &contents))
    399          1.1  christos 	goto error_return;
    400          1.1  christos     }
    401          1.1  christos 
    402          1.1  christos   for (irel = internal_relocs; irel < irelend; irel++)
    403          1.1  christos     {
    404          1.1  christos       unsigned long r_type = ELFNN_R_TYPE (irel->r_info);
    405          1.1  christos       bfd_vma symaddr, reladdr, trampoff, toff, roff;
    406          1.1  christos       asection *tsec;
    407          1.1  christos       struct one_fixup *f;
    408          1.1  christos       bfd_size_type amt;
    409          1.1  christos       bfd_boolean is_branch;
    410          1.1  christos       struct elfNN_ia64_dyn_sym_info *dyn_i;
    411          1.1  christos       char symtype;
    412          1.1  christos 
    413          1.1  christos       switch (r_type)
    414          1.1  christos 	{
    415          1.1  christos 	case R_IA64_PCREL21B:
    416          1.1  christos 	case R_IA64_PCREL21BI:
    417          1.1  christos 	case R_IA64_PCREL21M:
    418          1.1  christos 	case R_IA64_PCREL21F:
    419          1.1  christos 	  /* In pass 1, all br relaxations are done. We can skip it. */
    420          1.1  christos 	  if (link_info->relax_pass == 1)
    421          1.1  christos 	    continue;
    422          1.1  christos 	  skip_relax_pass_0 = FALSE;
    423          1.1  christos 	  is_branch = TRUE;
    424          1.1  christos 	  break;
    425          1.1  christos 
    426          1.1  christos 	case R_IA64_PCREL60B:
    427          1.1  christos 	  /* We can't optimize brl to br in pass 0 since br relaxations
    428          1.1  christos 	     will increase the code size. Defer it to pass 1.  */
    429          1.1  christos 	  if (link_info->relax_pass == 0)
    430          1.1  christos 	    {
    431          1.1  christos 	      skip_relax_pass_1 = FALSE;
    432          1.1  christos 	      continue;
    433          1.1  christos 	    }
    434          1.1  christos 	  is_branch = TRUE;
    435          1.1  christos 	  break;
    436          1.1  christos 
    437          1.1  christos 	case R_IA64_GPREL22:
    438          1.1  christos 	  /* Update max_short_sec/min_short_sec.  */
    439          1.1  christos 
    440          1.1  christos 	case R_IA64_LTOFF22X:
    441          1.1  christos 	case R_IA64_LDXMOV:
    442          1.1  christos 	  /* We can't relax ldx/mov in pass 0 since br relaxations will
    443          1.1  christos 	     increase the code size. Defer it to pass 1.  */
    444          1.1  christos 	  if (link_info->relax_pass == 0)
    445          1.1  christos 	    {
    446          1.1  christos 	      skip_relax_pass_1 = FALSE;
    447          1.1  christos 	      continue;
    448          1.1  christos 	    }
    449          1.1  christos 	  is_branch = FALSE;
    450          1.1  christos 	  break;
    451          1.1  christos 
    452          1.1  christos 	default:
    453          1.1  christos 	  continue;
    454          1.1  christos 	}
    455          1.1  christos 
    456          1.1  christos       /* Get the value of the symbol referred to by the reloc.  */
    457          1.1  christos       if (ELFNN_R_SYM (irel->r_info) < symtab_hdr->sh_info)
    458          1.1  christos 	{
    459          1.1  christos 	  /* A local symbol.  */
    460          1.1  christos 	  Elf_Internal_Sym *isym;
    461          1.1  christos 
    462          1.1  christos 	  /* Read this BFD's local symbols.  */
    463          1.1  christos 	  if (isymbuf == NULL)
    464          1.1  christos 	    {
    465          1.1  christos 	      isymbuf = (Elf_Internal_Sym *) symtab_hdr->contents;
    466          1.1  christos 	      if (isymbuf == NULL)
    467          1.1  christos 		isymbuf = bfd_elf_get_elf_syms (abfd, symtab_hdr,
    468          1.1  christos 						symtab_hdr->sh_info, 0,
    469          1.1  christos 						NULL, NULL, NULL);
    470          1.1  christos 	      if (isymbuf == 0)
    471          1.1  christos 		goto error_return;
    472          1.1  christos 	    }
    473          1.1  christos 
    474          1.1  christos 	  isym = isymbuf + ELFNN_R_SYM (irel->r_info);
    475          1.1  christos 	  if (isym->st_shndx == SHN_UNDEF)
    476          1.1  christos 	    continue;	/* We can't do anything with undefined symbols.  */
    477          1.1  christos 	  else if (isym->st_shndx == SHN_ABS)
    478          1.1  christos 	    tsec = bfd_abs_section_ptr;
    479          1.1  christos 	  else if (isym->st_shndx == SHN_COMMON)
    480          1.1  christos 	    tsec = bfd_com_section_ptr;
    481          1.1  christos 	  else if (isym->st_shndx == SHN_IA_64_ANSI_COMMON)
    482          1.1  christos 	    tsec = bfd_com_section_ptr;
    483          1.1  christos 	  else
    484          1.1  christos 	    tsec = bfd_section_from_elf_index (abfd, isym->st_shndx);
    485          1.1  christos 
    486          1.1  christos 	  toff = isym->st_value;
    487          1.1  christos 	  dyn_i = get_dyn_sym_info (ia64_info, NULL, abfd, irel, FALSE);
    488          1.1  christos 	  symtype = ELF_ST_TYPE (isym->st_info);
    489          1.1  christos 	}
    490          1.1  christos       else
    491          1.1  christos 	{
    492          1.1  christos 	  unsigned long indx;
    493          1.1  christos 	  struct elf_link_hash_entry *h;
    494          1.1  christos 
    495          1.1  christos 	  indx = ELFNN_R_SYM (irel->r_info) - symtab_hdr->sh_info;
    496          1.1  christos 	  h = elf_sym_hashes (abfd)[indx];
    497          1.1  christos 	  BFD_ASSERT (h != NULL);
    498          1.1  christos 
    499          1.1  christos 	  while (h->root.type == bfd_link_hash_indirect
    500          1.1  christos 		 || h->root.type == bfd_link_hash_warning)
    501          1.1  christos 	    h = (struct elf_link_hash_entry *) h->root.u.i.link;
    502          1.1  christos 
    503          1.1  christos 	  dyn_i = get_dyn_sym_info (ia64_info, h, abfd, irel, FALSE);
    504          1.1  christos 
    505          1.1  christos 	  /* For branches to dynamic symbols, we're interested instead
    506          1.1  christos 	     in a branch to the PLT entry.  */
    507          1.1  christos 	  if (is_branch && dyn_i && dyn_i->want_plt2)
    508          1.1  christos 	    {
    509          1.1  christos 	      /* Internal branches shouldn't be sent to the PLT.
    510          1.1  christos 		 Leave this for now and we'll give an error later.  */
    511          1.1  christos 	      if (r_type != R_IA64_PCREL21B)
    512          1.1  christos 		continue;
    513          1.1  christos 
    514          1.1  christos 	      tsec = ia64_info->root.splt;
    515          1.1  christos 	      toff = dyn_i->plt2_offset;
    516          1.1  christos 	      BFD_ASSERT (irel->r_addend == 0);
    517          1.1  christos 	    }
    518          1.1  christos 
    519          1.1  christos 	  /* Can't do anything else with dynamic symbols.  */
    520          1.1  christos 	  else if (elfNN_ia64_dynamic_symbol_p (h, link_info, r_type))
    521          1.1  christos 	    continue;
    522          1.1  christos 
    523          1.1  christos 	  else
    524          1.1  christos 	    {
    525          1.1  christos 	      /* We can't do anything with undefined symbols.  */
    526          1.1  christos 	      if (h->root.type == bfd_link_hash_undefined
    527          1.1  christos 		  || h->root.type == bfd_link_hash_undefweak)
    528          1.1  christos 		continue;
    529          1.1  christos 
    530          1.1  christos 	      tsec = h->root.u.def.section;
    531          1.1  christos 	      toff = h->root.u.def.value;
    532          1.1  christos 	    }
    533          1.1  christos 
    534          1.1  christos 	  symtype = h->type;
    535          1.1  christos 	}
    536          1.1  christos 
    537          1.1  christos       if (tsec->sec_info_type == SEC_INFO_TYPE_MERGE)
    538          1.1  christos 	{
    539          1.1  christos 	  /* At this stage in linking, no SEC_MERGE symbol has been
    540          1.1  christos 	     adjusted, so all references to such symbols need to be
    541          1.1  christos 	     passed through _bfd_merged_section_offset.  (Later, in
    542          1.1  christos 	     relocate_section, all SEC_MERGE symbols *except* for
    543          1.1  christos 	     section symbols have been adjusted.)
    544          1.1  christos 
    545          1.1  christos 	     gas may reduce relocations against symbols in SEC_MERGE
    546          1.1  christos 	     sections to a relocation against the section symbol when
    547          1.1  christos 	     the original addend was zero.  When the reloc is against
    548          1.1  christos 	     a section symbol we should include the addend in the
    549          1.1  christos 	     offset passed to _bfd_merged_section_offset, since the
    550          1.1  christos 	     location of interest is the original symbol.  On the
    551          1.1  christos 	     other hand, an access to "sym+addend" where "sym" is not
    552          1.1  christos 	     a section symbol should not include the addend;  Such an
    553          1.1  christos 	     access is presumed to be an offset from "sym";  The
    554          1.1  christos 	     location of interest is just "sym".  */
    555          1.1  christos 	   if (symtype == STT_SECTION)
    556          1.1  christos 	     toff += irel->r_addend;
    557          1.1  christos 
    558          1.1  christos 	   toff = _bfd_merged_section_offset (abfd, &tsec,
    559          1.1  christos 					      elf_section_data (tsec)->sec_info,
    560          1.1  christos 					      toff);
    561          1.1  christos 
    562          1.1  christos 	   if (symtype != STT_SECTION)
    563          1.1  christos 	     toff += irel->r_addend;
    564          1.1  christos 	}
    565          1.1  christos       else
    566          1.1  christos 	toff += irel->r_addend;
    567          1.1  christos 
    568          1.1  christos       symaddr = tsec->output_section->vma + tsec->output_offset + toff;
    569          1.1  christos 
    570          1.1  christos       roff = irel->r_offset;
    571          1.1  christos 
    572          1.1  christos       if (is_branch)
    573          1.1  christos 	{
    574          1.1  christos 	  bfd_signed_vma offset;
    575          1.1  christos 
    576          1.1  christos 	  reladdr = (sec->output_section->vma
    577          1.1  christos 		     + sec->output_offset
    578          1.1  christos 		     + roff) & (bfd_vma) -4;
    579          1.1  christos 
    580          1.1  christos 	  /* The .plt section is aligned at 32byte and the .text section
    581          1.1  christos 	     is aligned at 64byte. The .text section is right after the
    582          1.1  christos 	     .plt section.  After the first relaxation pass, linker may
    583          1.1  christos 	     increase the gap between the .plt and .text sections up
    584          1.1  christos 	     to 32byte.  We assume linker will always insert 32byte
    585          1.1  christos 	     between the .plt and .text sections after the first
    586          1.1  christos 	     relaxation pass.  */
    587          1.1  christos 	  if (tsec == ia64_info->root.splt)
    588          1.1  christos 	    offset = -0x1000000 + 32;
    589          1.1  christos 	  else
    590          1.1  christos 	    offset = -0x1000000;
    591          1.1  christos 
    592          1.1  christos 	  /* If the branch is in range, no need to do anything.  */
    593          1.1  christos 	  if ((bfd_signed_vma) (symaddr - reladdr) >= offset
    594          1.1  christos 	      && (bfd_signed_vma) (symaddr - reladdr) <= 0x0FFFFF0)
    595          1.1  christos 	    {
    596          1.1  christos 	      /* If the 60-bit branch is in 21-bit range, optimize it. */
    597          1.1  christos 	      if (r_type == R_IA64_PCREL60B)
    598          1.1  christos 		{
    599          1.1  christos 		  ia64_elf_relax_brl (contents, roff);
    600          1.1  christos 
    601          1.1  christos 		  irel->r_info
    602          1.1  christos 		    = ELFNN_R_INFO (ELFNN_R_SYM (irel->r_info),
    603          1.1  christos 				    R_IA64_PCREL21B);
    604          1.1  christos 
    605          1.1  christos 		  /* If the original relocation offset points to slot
    606  1.1.1.5.4.1  christos 		     1, change it to slot 2.  */
    607  1.1.1.5.4.1  christos 		  if ((irel->r_offset & 3) == 1)
    608  1.1.1.5.4.1  christos 		    irel->r_offset += 1;
    609          1.1  christos 
    610          1.1  christos 		  changed_contents = TRUE;
    611          1.1  christos 		  changed_relocs = TRUE;
    612          1.1  christos 		}
    613          1.1  christos 
    614          1.1  christos 	      continue;
    615          1.1  christos 	    }
    616          1.1  christos 	  else if (r_type == R_IA64_PCREL60B)
    617          1.1  christos 	    continue;
    618          1.1  christos 	  else if (ia64_elf_relax_br (contents, roff))
    619          1.1  christos 	    {
    620          1.1  christos 	      irel->r_info
    621          1.1  christos 		= ELFNN_R_INFO (ELFNN_R_SYM (irel->r_info),
    622          1.1  christos 				R_IA64_PCREL60B);
    623  1.1.1.5.4.1  christos 
    624  1.1.1.5.4.1  christos 	      /* Make the relocation offset point to slot 1.  */
    625  1.1.1.5.4.1  christos 	      irel->r_offset = (irel->r_offset & ~((bfd_vma) 0x3)) + 1;
    626          1.1  christos 
    627          1.1  christos 	      changed_contents = TRUE;
    628          1.1  christos 	      changed_relocs = TRUE;
    629          1.1  christos 	      continue;
    630          1.1  christos 	    }
    631          1.1  christos 
    632          1.1  christos 	  /* We can't put a trampoline in a .init/.fini section. Issue
    633          1.1  christos 	     an error.  */
    634      1.1.1.5  christos 	  if (strcmp (sec->output_section->name, ".init") == 0
    635      1.1.1.5  christos 	      || strcmp (sec->output_section->name, ".fini") == 0)
    636  1.1.1.5.4.1  christos 	    {
    637  1.1.1.5.4.1  christos 	      _bfd_error_handler
    638  1.1.1.5.4.1  christos 		/* xgettext:c-format */
    639          1.1  christos 		(_("%pB: can't relax br at %#" PRIx64 " in section `%pA';"
    640          1.1  christos 		   " please use brl or indirect branch"),
    641          1.1  christos 		 sec->owner, (uint64_t) roff, sec);
    642          1.1  christos 	      bfd_set_error (bfd_error_bad_value);
    643          1.1  christos 	      goto error_return;
    644          1.1  christos 	    }
    645          1.1  christos 
    646          1.1  christos 	  /* If the branch and target are in the same section, you've
    647          1.1  christos 	     got one honking big section and we can't help you unless
    648          1.1  christos 	     you are branching backwards.  You'll get an error message
    649          1.1  christos 	     later.  */
    650          1.1  christos 	  if (tsec == sec && toff > roff)
    651          1.1  christos 	    continue;
    652          1.1  christos 
    653          1.1  christos 	  /* Look for an existing fixup to this address.  */
    654          1.1  christos 	  for (f = fixups; f ; f = f->next)
    655          1.1  christos 	    if (f->tsec == tsec && f->toff == toff)
    656          1.1  christos 	      break;
    657          1.1  christos 
    658          1.1  christos 	  if (f == NULL)
    659          1.1  christos 	    {
    660          1.1  christos 	      /* Two alternatives: If it's a branch to a PLT entry, we can
    661          1.1  christos 		 make a copy of the FULL_PLT entry.  Otherwise, we'll have
    662          1.1  christos 		 to use a `brl' insn to get where we're going.  */
    663          1.1  christos 
    664          1.1  christos 	      size_t size;
    665          1.1  christos 
    666          1.1  christos 	      if (tsec == ia64_info->root.splt)
    667          1.1  christos 		size = sizeof (plt_full_entry);
    668          1.1  christos 	      else
    669          1.1  christos 		size = oor_branch_size;
    670          1.1  christos 
    671          1.1  christos 	      /* Resize the current section to make room for the new branch. */
    672          1.1  christos 	      trampoff = (sec->size + 15) & (bfd_vma) -16;
    673          1.1  christos 
    674          1.1  christos 	      /* If trampoline is out of range, there is nothing we
    675          1.1  christos 		 can do.  */
    676          1.1  christos 	      offset = trampoff - (roff & (bfd_vma) -4);
    677          1.1  christos 	      if (offset < -0x1000000 || offset > 0x0FFFFF0)
    678          1.1  christos 		continue;
    679          1.1  christos 
    680          1.1  christos 	      amt = trampoff + size;
    681          1.1  christos 	      contents = (bfd_byte *) bfd_realloc (contents, amt);
    682          1.1  christos 	      if (contents == NULL)
    683          1.1  christos 		goto error_return;
    684          1.1  christos 	      sec->size = amt;
    685          1.1  christos 
    686          1.1  christos 	      if (tsec == ia64_info->root.splt)
    687          1.1  christos 		{
    688          1.1  christos 		  memcpy (contents + trampoff, plt_full_entry, size);
    689          1.1  christos 
    690          1.1  christos 		  /* Hijack the old relocation for use as the PLTOFF reloc.  */
    691          1.1  christos 		  irel->r_info = ELFNN_R_INFO (ELFNN_R_SYM (irel->r_info),
    692          1.1  christos 					       R_IA64_PLTOFF22);
    693          1.1  christos 		  irel->r_offset = trampoff;
    694          1.1  christos 		}
    695          1.1  christos 	      else
    696          1.1  christos 		{
    697          1.1  christos 		  if (size == sizeof (oor_ip))
    698          1.1  christos 		    {
    699          1.1  christos 		      memcpy (contents + trampoff, oor_ip, size);
    700          1.1  christos 		      irel->r_info = ELFNN_R_INFO (ELFNN_R_SYM (irel->r_info),
    701          1.1  christos 						   R_IA64_PCREL64I);
    702          1.1  christos 		      irel->r_addend -= 16;
    703          1.1  christos 		      irel->r_offset = trampoff + 2;
    704          1.1  christos 		    }
    705          1.1  christos 		  else
    706          1.1  christos 		    {
    707          1.1  christos 		      memcpy (contents + trampoff, oor_brl, size);
    708          1.1  christos 		      irel->r_info = ELFNN_R_INFO (ELFNN_R_SYM (irel->r_info),
    709          1.1  christos 						   R_IA64_PCREL60B);
    710          1.1  christos 		      irel->r_offset = trampoff + 2;
    711          1.1  christos 		    }
    712          1.1  christos 
    713          1.1  christos 		}
    714          1.1  christos 
    715          1.1  christos 	      /* Record the fixup so we don't do it again this section.  */
    716          1.1  christos 	      f = (struct one_fixup *)
    717          1.1  christos 		bfd_malloc ((bfd_size_type) sizeof (*f));
    718          1.1  christos 	      f->next = fixups;
    719          1.1  christos 	      f->tsec = tsec;
    720          1.1  christos 	      f->toff = toff;
    721          1.1  christos 	      f->trampoff = trampoff;
    722          1.1  christos 	      fixups = f;
    723          1.1  christos 	    }
    724          1.1  christos 	  else
    725          1.1  christos 	    {
    726          1.1  christos 	      /* If trampoline is out of range, there is nothing we
    727          1.1  christos 		 can do.  */
    728          1.1  christos 	      offset = f->trampoff - (roff & (bfd_vma) -4);
    729          1.1  christos 	      if (offset < -0x1000000 || offset > 0x0FFFFF0)
    730          1.1  christos 		continue;
    731          1.1  christos 
    732          1.1  christos 	      /* Nop out the reloc, since we're finalizing things here.  */
    733          1.1  christos 	      irel->r_info = ELFNN_R_INFO (0, R_IA64_NONE);
    734          1.1  christos 	    }
    735          1.1  christos 
    736          1.1  christos 	  /* Fix up the existing branch to hit the trampoline.  */
    737          1.1  christos 	  if (ia64_elf_install_value (contents + roff, offset, r_type)
    738          1.1  christos 	      != bfd_reloc_ok)
    739          1.1  christos 	    goto error_return;
    740          1.1  christos 
    741          1.1  christos 	  changed_contents = TRUE;
    742          1.1  christos 	  changed_relocs = TRUE;
    743          1.1  christos 	}
    744          1.1  christos       else
    745          1.1  christos 	{
    746          1.1  christos 	  /* Fetch the gp.  */
    747          1.1  christos 	  if (gp == 0)
    748          1.1  christos 	    {
    749          1.1  christos 	      bfd *obfd = sec->output_section->owner;
    750          1.1  christos 	      gp = _bfd_get_gp_value (obfd);
    751          1.1  christos 	      if (gp == 0)
    752          1.1  christos 		{
    753          1.1  christos 		  if (!elfNN_ia64_choose_gp (obfd, link_info, FALSE))
    754          1.1  christos 		    goto error_return;
    755          1.1  christos 		  gp = _bfd_get_gp_value (obfd);
    756          1.1  christos 		}
    757          1.1  christos 	    }
    758          1.1  christos 
    759          1.1  christos 	  /* If the data is out of range, do nothing.  */
    760          1.1  christos 	  if ((bfd_signed_vma) (symaddr - gp) >= 0x200000
    761          1.1  christos 	      ||(bfd_signed_vma) (symaddr - gp) < -0x200000)
    762          1.1  christos 	    continue;
    763          1.1  christos 
    764          1.1  christos 	  if (r_type == R_IA64_GPREL22)
    765          1.1  christos 	    elfNN_ia64_update_short_info (tsec->output_section,
    766          1.1  christos 					  tsec->output_offset + toff,
    767          1.1  christos 					  ia64_info);
    768          1.1  christos 	  else if (r_type == R_IA64_LTOFF22X)
    769          1.1  christos 	    {
    770          1.1  christos 	      irel->r_info = ELFNN_R_INFO (ELFNN_R_SYM (irel->r_info),
    771          1.1  christos 					   R_IA64_GPREL22);
    772          1.1  christos 	      changed_relocs = TRUE;
    773          1.1  christos 	      if (dyn_i->want_gotx)
    774          1.1  christos 		{
    775          1.1  christos 		  dyn_i->want_gotx = 0;
    776          1.1  christos 		  changed_got |= !dyn_i->want_got;
    777          1.1  christos 		}
    778          1.1  christos 
    779          1.1  christos 	      elfNN_ia64_update_short_info (tsec->output_section,
    780          1.1  christos 					    tsec->output_offset + toff,
    781          1.1  christos 					    ia64_info);
    782          1.1  christos 	    }
    783          1.1  christos 	  else
    784          1.1  christos 	    {
    785          1.1  christos 	      ia64_elf_relax_ldxmov (contents, roff);
    786          1.1  christos 	      irel->r_info = ELFNN_R_INFO (0, R_IA64_NONE);
    787          1.1  christos 	      changed_contents = TRUE;
    788          1.1  christos 	      changed_relocs = TRUE;
    789          1.1  christos 	    }
    790          1.1  christos 	}
    791          1.1  christos     }
    792          1.1  christos 
    793          1.1  christos   /* ??? If we created fixups, this may push the code segment large
    794          1.1  christos      enough that the data segment moves, which will change the GP.
    795          1.1  christos      Reset the GP so that we re-calculate next round.  We need to
    796          1.1  christos      do this at the _beginning_ of the next round; now will not do.  */
    797          1.1  christos 
    798          1.1  christos   /* Clean up and go home.  */
    799          1.1  christos   while (fixups)
    800          1.1  christos     {
    801          1.1  christos       struct one_fixup *f = fixups;
    802          1.1  christos       fixups = fixups->next;
    803          1.1  christos       free (f);
    804          1.1  christos     }
    805          1.1  christos 
    806          1.1  christos   if (isymbuf != NULL
    807          1.1  christos       && symtab_hdr->contents != (unsigned char *) isymbuf)
    808          1.1  christos     {
    809          1.1  christos       if (! link_info->keep_memory)
    810          1.1  christos 	free (isymbuf);
    811          1.1  christos       else
    812          1.1  christos 	{
    813          1.1  christos 	  /* Cache the symbols for elf_link_input_bfd.  */
    814          1.1  christos 	  symtab_hdr->contents = (unsigned char *) isymbuf;
    815          1.1  christos 	}
    816          1.1  christos     }
    817          1.1  christos 
    818          1.1  christos   if (contents != NULL
    819          1.1  christos       && elf_section_data (sec)->this_hdr.contents != contents)
    820          1.1  christos     {
    821          1.1  christos       if (!changed_contents && !link_info->keep_memory)
    822          1.1  christos 	free (contents);
    823          1.1  christos       else
    824          1.1  christos 	{
    825          1.1  christos 	  /* Cache the section contents for elf_link_input_bfd.  */
    826          1.1  christos 	  elf_section_data (sec)->this_hdr.contents = contents;
    827          1.1  christos 	}
    828          1.1  christos     }
    829          1.1  christos 
    830          1.1  christos   if (elf_section_data (sec)->relocs != internal_relocs)
    831          1.1  christos     {
    832          1.1  christos       if (!changed_relocs)
    833          1.1  christos 	free (internal_relocs);
    834          1.1  christos       else
    835          1.1  christos 	elf_section_data (sec)->relocs = internal_relocs;
    836          1.1  christos     }
    837          1.1  christos 
    838          1.1  christos   if (changed_got)
    839          1.1  christos     {
    840          1.1  christos       struct elfNN_ia64_allocate_data data;
    841          1.1  christos       data.info = link_info;
    842          1.1  christos       data.ofs = 0;
    843          1.1  christos       ia64_info->self_dtpmod_offset = (bfd_vma) -1;
    844          1.1  christos 
    845          1.1  christos       elfNN_ia64_dyn_sym_traverse (ia64_info, allocate_global_data_got, &data);
    846          1.1  christos       elfNN_ia64_dyn_sym_traverse (ia64_info, allocate_global_fptr_got, &data);
    847          1.1  christos       elfNN_ia64_dyn_sym_traverse (ia64_info, allocate_local_got, &data);
    848          1.1  christos       ia64_info->root.sgot->size = data.ofs;
    849          1.1  christos 
    850          1.1  christos       if (ia64_info->root.dynamic_sections_created
    851          1.1  christos 	  && ia64_info->root.srelgot != NULL)
    852      1.1.1.4  christos 	{
    853          1.1  christos 	  /* Resize .rela.got.  */
    854          1.1  christos 	  ia64_info->root.srelgot->size = 0;
    855          1.1  christos 	  if (bfd_link_pic (link_info)
    856          1.1  christos 	      && ia64_info->self_dtpmod_offset != (bfd_vma) -1)
    857          1.1  christos 	    ia64_info->root.srelgot->size += sizeof (ElfNN_External_Rela);
    858          1.1  christos 	  data.only_got = TRUE;
    859          1.1  christos 	  elfNN_ia64_dyn_sym_traverse (ia64_info, allocate_dynrel_entries,
    860          1.1  christos 				       &data);
    861          1.1  christos 	}
    862          1.1  christos     }
    863          1.1  christos 
    864          1.1  christos   if (link_info->relax_pass == 0)
    865          1.1  christos     {
    866          1.1  christos       /* Pass 0 is only needed to relax br.  */
    867          1.1  christos       sec->skip_relax_pass_0 = skip_relax_pass_0;
    868          1.1  christos       sec->skip_relax_pass_1 = skip_relax_pass_1;
    869          1.1  christos     }
    870          1.1  christos 
    871          1.1  christos   *again = changed_contents || changed_relocs;
    872          1.1  christos   return TRUE;
    873          1.1  christos 
    874          1.1  christos  error_return:
    875          1.1  christos   if (isymbuf != NULL && (unsigned char *) isymbuf != symtab_hdr->contents)
    876          1.1  christos     free (isymbuf);
    877          1.1  christos   if (contents != NULL
    878          1.1  christos       && elf_section_data (sec)->this_hdr.contents != contents)
    879          1.1  christos     free (contents);
    880          1.1  christos   if (internal_relocs != NULL
    881          1.1  christos       && elf_section_data (sec)->relocs != internal_relocs)
    882          1.1  christos     free (internal_relocs);
    883          1.1  christos   return FALSE;
    884          1.1  christos }
    885          1.1  christos #undef skip_relax_pass_0
    886          1.1  christos #undef skip_relax_pass_1
    887          1.1  christos 
    888          1.1  christos /* Return TRUE if NAME is an unwind table section name.  */
    890          1.1  christos 
    891          1.1  christos static inline bfd_boolean
    892          1.1  christos is_unwind_section_name (bfd *abfd, const char *name)
    893          1.1  christos {
    894          1.1  christos   if (elfNN_ia64_hpux_vec (abfd->xvec)
    895          1.1  christos       && !strcmp (name, ELF_STRING_ia64_unwind_hdr))
    896          1.1  christos     return FALSE;
    897          1.1  christos 
    898          1.1  christos   return ((CONST_STRNEQ (name, ELF_STRING_ia64_unwind)
    899          1.1  christos 	   && ! CONST_STRNEQ (name, ELF_STRING_ia64_unwind_info))
    900          1.1  christos 	  || CONST_STRNEQ (name, ELF_STRING_ia64_unwind_once));
    901          1.1  christos }
    902          1.1  christos 
    903          1.1  christos /* Handle an IA-64 specific section when reading an object file.  This
    904          1.1  christos    is called when bfd_section_from_shdr finds a section with an unknown
    905          1.1  christos    type.  */
    906          1.1  christos 
    907          1.1  christos static bfd_boolean
    908          1.1  christos elfNN_ia64_section_from_shdr (bfd *abfd,
    909          1.1  christos 			      Elf_Internal_Shdr *hdr,
    910          1.1  christos 			      const char *name,
    911          1.1  christos 			      int shindex)
    912          1.1  christos {
    913          1.1  christos   /* There ought to be a place to keep ELF backend specific flags, but
    914          1.1  christos      at the moment there isn't one.  We just keep track of the
    915          1.1  christos      sections by their name, instead.  Fortunately, the ABI gives
    916          1.1  christos      suggested names for all the MIPS specific sections, so we will
    917          1.1  christos      probably get away with this.  */
    918          1.1  christos   switch (hdr->sh_type)
    919          1.1  christos     {
    920          1.1  christos     case SHT_IA_64_UNWIND:
    921          1.1  christos     case SHT_IA_64_HP_OPT_ANOT:
    922          1.1  christos       break;
    923          1.1  christos 
    924          1.1  christos     case SHT_IA_64_EXT:
    925          1.1  christos       if (strcmp (name, ELF_STRING_ia64_archext) != 0)
    926          1.1  christos 	return FALSE;
    927          1.1  christos       break;
    928          1.1  christos 
    929          1.1  christos     default:
    930          1.1  christos       return FALSE;
    931          1.1  christos     }
    932          1.1  christos 
    933          1.1  christos   if (! _bfd_elf_make_section_from_shdr (abfd, hdr, name, shindex))
    934          1.1  christos     return FALSE;
    935          1.1  christos 
    936          1.1  christos   return TRUE;
    937          1.1  christos }
    938          1.1  christos 
    939          1.1  christos /* Convert IA-64 specific section flags to bfd internal section flags.  */
    940          1.1  christos 
    941          1.1  christos /* ??? There is no bfd internal flag equivalent to the SHF_IA_64_NORECOV
    942          1.1  christos    flag.  */
    943          1.1  christos 
    944          1.1  christos static bfd_boolean
    945          1.1  christos elfNN_ia64_section_flags (flagword *flags,
    946          1.1  christos 			  const Elf_Internal_Shdr *hdr)
    947          1.1  christos {
    948          1.1  christos   if (hdr->sh_flags & SHF_IA_64_SHORT)
    949          1.1  christos     *flags |= SEC_SMALL_DATA;
    950          1.1  christos 
    951          1.1  christos   return TRUE;
    952          1.1  christos }
    953          1.1  christos 
    954          1.1  christos /* Set the correct type for an IA-64 ELF section.  We do this by the
    955          1.1  christos    section name, which is a hack, but ought to work.  */
    956          1.1  christos 
    957          1.1  christos static bfd_boolean
    958          1.1  christos elfNN_ia64_fake_sections (bfd *abfd, Elf_Internal_Shdr *hdr,
    959          1.1  christos 			  asection *sec)
    960          1.1  christos {
    961          1.1  christos   const char *name;
    962          1.1  christos 
    963          1.1  christos   name = bfd_get_section_name (abfd, sec);
    964          1.1  christos 
    965          1.1  christos   if (is_unwind_section_name (abfd, name))
    966          1.1  christos     {
    967          1.1  christos       /* We don't have the sections numbered at this point, so sh_info
    968          1.1  christos 	 is set later, in elfNN_ia64_final_write_processing.  */
    969          1.1  christos       hdr->sh_type = SHT_IA_64_UNWIND;
    970          1.1  christos       hdr->sh_flags |= SHF_LINK_ORDER;
    971          1.1  christos     }
    972          1.1  christos   else if (strcmp (name, ELF_STRING_ia64_archext) == 0)
    973          1.1  christos     hdr->sh_type = SHT_IA_64_EXT;
    974          1.1  christos   else if (strcmp (name, ".HP.opt_annot") == 0)
    975          1.1  christos     hdr->sh_type = SHT_IA_64_HP_OPT_ANOT;
    976          1.1  christos   else if (strcmp (name, ".reloc") == 0)
    977          1.1  christos     /* This is an ugly, but unfortunately necessary hack that is
    978          1.1  christos        needed when producing EFI binaries on IA-64. It tells
    979          1.1  christos        elf.c:elf_fake_sections() not to consider ".reloc" as a section
    980          1.1  christos        containing ELF relocation info.  We need this hack in order to
    981          1.1  christos        be able to generate ELF binaries that can be translated into
    982          1.1  christos        EFI applications (which are essentially COFF objects).  Those
    983          1.1  christos        files contain a COFF ".reloc" section inside an ELFNN object,
    984          1.1  christos        which would normally cause BFD to segfault because it would
    985          1.1  christos        attempt to interpret this section as containing relocation
    986          1.1  christos        entries for section "oc".  With this hack enabled, ".reloc"
    987          1.1  christos        will be treated as a normal data section, which will avoid the
    988          1.1  christos        segfault.  However, you won't be able to create an ELFNN binary
    989          1.1  christos        with a section named "oc" that needs relocations, but that's
    990          1.1  christos        the kind of ugly side-effects you get when detecting section
    991          1.1  christos        types based on their names...  In practice, this limitation is
    992          1.1  christos        unlikely to bite.  */
    993          1.1  christos     hdr->sh_type = SHT_PROGBITS;
    994          1.1  christos 
    995          1.1  christos   if (sec->flags & SEC_SMALL_DATA)
    996          1.1  christos     hdr->sh_flags |= SHF_IA_64_SHORT;
    997          1.1  christos 
    998          1.1  christos   /* Some HP linkers look for the SHF_IA_64_HP_TLS flag instead of SHF_TLS. */
    999          1.1  christos 
   1000          1.1  christos   if (elfNN_ia64_hpux_vec (abfd->xvec) && (sec->flags & SHF_TLS))
   1001          1.1  christos     hdr->sh_flags |= SHF_IA_64_HP_TLS;
   1002          1.1  christos 
   1003          1.1  christos   return TRUE;
   1004          1.1  christos }
   1005          1.1  christos 
   1006          1.1  christos /* The final processing done just before writing out an IA-64 ELF
   1007          1.1  christos    object file.  */
   1008          1.1  christos 
   1009          1.1  christos static void
   1010          1.1  christos elfNN_ia64_final_write_processing (bfd *abfd,
   1011          1.1  christos 				   bfd_boolean linker ATTRIBUTE_UNUSED)
   1012          1.1  christos {
   1013          1.1  christos   Elf_Internal_Shdr *hdr;
   1014          1.1  christos   asection *s;
   1015          1.1  christos 
   1016          1.1  christos   for (s = abfd->sections; s; s = s->next)
   1017          1.1  christos     {
   1018          1.1  christos       hdr = &elf_section_data (s)->this_hdr;
   1019          1.1  christos       switch (hdr->sh_type)
   1020          1.1  christos 	{
   1021          1.1  christos 	case SHT_IA_64_UNWIND:
   1022          1.1  christos 	  /* The IA-64 processor-specific ABI requires setting sh_link
   1023          1.1  christos 	     to the unwind section, whereas HP-UX requires sh_info to
   1024          1.1  christos 	     do so.  For maximum compatibility, we'll set both for
   1025          1.1  christos 	     now... */
   1026          1.1  christos 	  hdr->sh_info = hdr->sh_link;
   1027          1.1  christos 	  break;
   1028          1.1  christos 	}
   1029          1.1  christos     }
   1030          1.1  christos 
   1031          1.1  christos   if (! elf_flags_init (abfd))
   1032          1.1  christos     {
   1033          1.1  christos       unsigned long flags = 0;
   1034          1.1  christos 
   1035          1.1  christos       if (abfd->xvec->byteorder == BFD_ENDIAN_BIG)
   1036          1.1  christos 	flags |= EF_IA_64_BE;
   1037          1.1  christos       if (bfd_get_mach (abfd) == bfd_mach_ia64_elf64)
   1038          1.1  christos 	flags |= EF_IA_64_ABI64;
   1039          1.1  christos 
   1040          1.1  christos       elf_elfheader(abfd)->e_flags = flags;
   1041          1.1  christos       elf_flags_init (abfd) = TRUE;
   1042          1.1  christos     }
   1043          1.1  christos }
   1044          1.1  christos 
   1045          1.1  christos /* Hook called by the linker routine which adds symbols from an object
   1046          1.1  christos    file.  We use it to put .comm items in .sbss, and not .bss.  */
   1047          1.1  christos 
   1048          1.1  christos static bfd_boolean
   1049          1.1  christos elfNN_ia64_add_symbol_hook (bfd *abfd,
   1050          1.1  christos 			    struct bfd_link_info *info,
   1051          1.1  christos 			    Elf_Internal_Sym *sym,
   1052          1.1  christos 			    const char **namep ATTRIBUTE_UNUSED,
   1053          1.1  christos 			    flagword *flagsp ATTRIBUTE_UNUSED,
   1054      1.1.1.4  christos 			    asection **secp,
   1055          1.1  christos 			    bfd_vma *valp)
   1056          1.1  christos {
   1057          1.1  christos   if (sym->st_shndx == SHN_COMMON
   1058          1.1  christos       && !bfd_link_relocatable (info)
   1059          1.1  christos       && sym->st_size <= elf_gp_size (abfd))
   1060          1.1  christos     {
   1061          1.1  christos       /* Common symbols less than or equal to -G nn bytes are
   1062          1.1  christos 	 automatically put into .sbss.  */
   1063          1.1  christos 
   1064          1.1  christos       asection *scomm = bfd_get_section_by_name (abfd, ".scommon");
   1065          1.1  christos 
   1066          1.1  christos       if (scomm == NULL)
   1067          1.1  christos 	{
   1068          1.1  christos 	  scomm = bfd_make_section_with_flags (abfd, ".scommon",
   1069          1.1  christos 					       (SEC_ALLOC
   1070          1.1  christos 						| SEC_IS_COMMON
   1071          1.1  christos 						| SEC_LINKER_CREATED));
   1072          1.1  christos 	  if (scomm == NULL)
   1073          1.1  christos 	    return FALSE;
   1074          1.1  christos 	}
   1075          1.1  christos 
   1076          1.1  christos       *secp = scomm;
   1077          1.1  christos       *valp = sym->st_size;
   1078          1.1  christos     }
   1079          1.1  christos 
   1080          1.1  christos   return TRUE;
   1081          1.1  christos }
   1082          1.1  christos 
   1083          1.1  christos /* Return the number of additional phdrs we will need.  */
   1084          1.1  christos 
   1085          1.1  christos static int
   1086          1.1  christos elfNN_ia64_additional_program_headers (bfd *abfd,
   1087          1.1  christos 				       struct bfd_link_info *info ATTRIBUTE_UNUSED)
   1088          1.1  christos {
   1089          1.1  christos   asection *s;
   1090          1.1  christos   int ret = 0;
   1091          1.1  christos 
   1092          1.1  christos   /* See if we need a PT_IA_64_ARCHEXT segment.  */
   1093          1.1  christos   s = bfd_get_section_by_name (abfd, ELF_STRING_ia64_archext);
   1094          1.1  christos   if (s && (s->flags & SEC_LOAD))
   1095          1.1  christos     ++ret;
   1096          1.1  christos 
   1097          1.1  christos   /* Count how many PT_IA_64_UNWIND segments we need.  */
   1098          1.1  christos   for (s = abfd->sections; s; s = s->next)
   1099          1.1  christos     if (is_unwind_section_name (abfd, s->name) && (s->flags & SEC_LOAD))
   1100          1.1  christos       ++ret;
   1101          1.1  christos 
   1102          1.1  christos   return ret;
   1103          1.1  christos }
   1104          1.1  christos 
   1105          1.1  christos static bfd_boolean
   1106          1.1  christos elfNN_ia64_modify_segment_map (bfd *abfd,
   1107          1.1  christos 			       struct bfd_link_info *info ATTRIBUTE_UNUSED)
   1108          1.1  christos {
   1109          1.1  christos   struct elf_segment_map *m, **pm;
   1110          1.1  christos   Elf_Internal_Shdr *hdr;
   1111          1.1  christos   asection *s;
   1112          1.1  christos 
   1113          1.1  christos   /* If we need a PT_IA_64_ARCHEXT segment, it must come before
   1114          1.1  christos      all PT_LOAD segments.  */
   1115          1.1  christos   s = bfd_get_section_by_name (abfd, ELF_STRING_ia64_archext);
   1116          1.1  christos   if (s && (s->flags & SEC_LOAD))
   1117          1.1  christos     {
   1118          1.1  christos       for (m = elf_seg_map (abfd); m != NULL; m = m->next)
   1119          1.1  christos 	if (m->p_type == PT_IA_64_ARCHEXT)
   1120          1.1  christos 	  break;
   1121          1.1  christos       if (m == NULL)
   1122          1.1  christos 	{
   1123          1.1  christos 	  m = ((struct elf_segment_map *)
   1124          1.1  christos 	       bfd_zalloc (abfd, (bfd_size_type) sizeof *m));
   1125          1.1  christos 	  if (m == NULL)
   1126          1.1  christos 	    return FALSE;
   1127          1.1  christos 
   1128          1.1  christos 	  m->p_type = PT_IA_64_ARCHEXT;
   1129          1.1  christos 	  m->count = 1;
   1130          1.1  christos 	  m->sections[0] = s;
   1131          1.1  christos 
   1132          1.1  christos 	  /* We want to put it after the PHDR and INTERP segments.  */
   1133          1.1  christos 	  pm = &elf_seg_map (abfd);
   1134          1.1  christos 	  while (*pm != NULL
   1135          1.1  christos 		 && ((*pm)->p_type == PT_PHDR
   1136          1.1  christos 		     || (*pm)->p_type == PT_INTERP))
   1137          1.1  christos 	    pm = &(*pm)->next;
   1138          1.1  christos 
   1139          1.1  christos 	  m->next = *pm;
   1140          1.1  christos 	  *pm = m;
   1141          1.1  christos 	}
   1142          1.1  christos     }
   1143          1.1  christos 
   1144          1.1  christos   /* Install PT_IA_64_UNWIND segments, if needed.  */
   1145          1.1  christos   for (s = abfd->sections; s; s = s->next)
   1146          1.1  christos     {
   1147          1.1  christos       hdr = &elf_section_data (s)->this_hdr;
   1148          1.1  christos       if (hdr->sh_type != SHT_IA_64_UNWIND)
   1149          1.1  christos 	continue;
   1150          1.1  christos 
   1151          1.1  christos       if (s && (s->flags & SEC_LOAD))
   1152          1.1  christos 	{
   1153          1.1  christos 	  for (m = elf_seg_map (abfd); m != NULL; m = m->next)
   1154          1.1  christos 	    if (m->p_type == PT_IA_64_UNWIND)
   1155          1.1  christos 	      {
   1156          1.1  christos 		int i;
   1157          1.1  christos 
   1158          1.1  christos 		/* Look through all sections in the unwind segment
   1159          1.1  christos 		   for a match since there may be multiple sections
   1160          1.1  christos 		   to a segment.  */
   1161          1.1  christos 		for (i = m->count - 1; i >= 0; --i)
   1162          1.1  christos 		  if (m->sections[i] == s)
   1163          1.1  christos 		    break;
   1164          1.1  christos 
   1165          1.1  christos 		if (i >= 0)
   1166          1.1  christos 		  break;
   1167          1.1  christos 	      }
   1168          1.1  christos 
   1169          1.1  christos 	  if (m == NULL)
   1170          1.1  christos 	    {
   1171          1.1  christos 	      m = ((struct elf_segment_map *)
   1172          1.1  christos 		   bfd_zalloc (abfd, (bfd_size_type) sizeof *m));
   1173          1.1  christos 	      if (m == NULL)
   1174          1.1  christos 		return FALSE;
   1175          1.1  christos 
   1176          1.1  christos 	      m->p_type = PT_IA_64_UNWIND;
   1177          1.1  christos 	      m->count = 1;
   1178          1.1  christos 	      m->sections[0] = s;
   1179          1.1  christos 	      m->next = NULL;
   1180          1.1  christos 
   1181          1.1  christos 	      /* We want to put it last.  */
   1182          1.1  christos 	      pm = &elf_seg_map (abfd);
   1183          1.1  christos 	      while (*pm != NULL)
   1184          1.1  christos 		pm = &(*pm)->next;
   1185          1.1  christos 	      *pm = m;
   1186          1.1  christos 	    }
   1187          1.1  christos 	}
   1188          1.1  christos     }
   1189          1.1  christos 
   1190          1.1  christos   return TRUE;
   1191          1.1  christos }
   1192          1.1  christos 
   1193          1.1  christos /* Turn on PF_IA_64_NORECOV if needed.  This involves traversing all of
   1194          1.1  christos    the input sections for each output section in the segment and testing
   1195          1.1  christos    for SHF_IA_64_NORECOV on each.  */
   1196          1.1  christos 
   1197          1.1  christos static bfd_boolean
   1198          1.1  christos elfNN_ia64_modify_program_headers (bfd *abfd,
   1199          1.1  christos 				   struct bfd_link_info *info ATTRIBUTE_UNUSED)
   1200          1.1  christos {
   1201          1.1  christos   struct elf_obj_tdata *tdata = elf_tdata (abfd);
   1202          1.1  christos   struct elf_segment_map *m;
   1203          1.1  christos   Elf_Internal_Phdr *p;
   1204          1.1  christos 
   1205          1.1  christos   for (p = tdata->phdr, m = elf_seg_map (abfd); m != NULL; m = m->next, p++)
   1206          1.1  christos     if (m->p_type == PT_LOAD)
   1207          1.1  christos       {
   1208          1.1  christos 	int i;
   1209          1.1  christos 	for (i = m->count - 1; i >= 0; --i)
   1210          1.1  christos 	  {
   1211          1.1  christos 	    struct bfd_link_order *order = m->sections[i]->map_head.link_order;
   1212          1.1  christos 
   1213          1.1  christos 	    while (order != NULL)
   1214          1.1  christos 	      {
   1215          1.1  christos 		if (order->type == bfd_indirect_link_order)
   1216          1.1  christos 		  {
   1217          1.1  christos 		    asection *is = order->u.indirect.section;
   1218          1.1  christos 		    bfd_vma flags = elf_section_data(is)->this_hdr.sh_flags;
   1219          1.1  christos 		    if (flags & SHF_IA_64_NORECOV)
   1220          1.1  christos 		      {
   1221          1.1  christos 			p->p_flags |= PF_IA_64_NORECOV;
   1222          1.1  christos 			goto found;
   1223          1.1  christos 		      }
   1224          1.1  christos 		  }
   1225          1.1  christos 		order = order->next;
   1226          1.1  christos 	      }
   1227          1.1  christos 	  }
   1228          1.1  christos       found:;
   1229          1.1  christos       }
   1230          1.1  christos 
   1231          1.1  christos   return TRUE;
   1232          1.1  christos }
   1233          1.1  christos 
   1234          1.1  christos /* According to the Tahoe assembler spec, all labels starting with a
   1235          1.1  christos    '.' are local.  */
   1236          1.1  christos 
   1237          1.1  christos static bfd_boolean
   1238          1.1  christos elfNN_ia64_is_local_label_name (bfd *abfd ATTRIBUTE_UNUSED,
   1239          1.1  christos 				const char *name)
   1240          1.1  christos {
   1241          1.1  christos   return name[0] == '.';
   1242          1.1  christos }
   1243          1.1  christos 
   1244          1.1  christos /* Should we do dynamic things to this symbol?  */
   1245          1.1  christos 
   1246          1.1  christos static bfd_boolean
   1247          1.1  christos elfNN_ia64_dynamic_symbol_p (struct elf_link_hash_entry *h,
   1248          1.1  christos 			     struct bfd_link_info *info, int r_type)
   1249          1.1  christos {
   1250          1.1  christos   bfd_boolean ignore_protected
   1251          1.1  christos     = ((r_type & 0xf8) == 0x40		/* FPTR relocs */
   1252          1.1  christos        || (r_type & 0xf8) == 0x50);	/* LTOFF_FPTR relocs */
   1253          1.1  christos 
   1254          1.1  christos   return _bfd_elf_dynamic_symbol_p (h, info, ignore_protected);
   1255          1.1  christos }
   1256          1.1  christos 
   1257          1.1  christos static struct bfd_hash_entry*
   1259          1.1  christos elfNN_ia64_new_elf_hash_entry (struct bfd_hash_entry *entry,
   1260          1.1  christos 			       struct bfd_hash_table *table,
   1261          1.1  christos 			       const char *string)
   1262          1.1  christos {
   1263          1.1  christos   struct elfNN_ia64_link_hash_entry *ret;
   1264          1.1  christos   ret = (struct elfNN_ia64_link_hash_entry *) entry;
   1265          1.1  christos 
   1266          1.1  christos   /* Allocate the structure if it has not already been allocated by a
   1267          1.1  christos      subclass.  */
   1268          1.1  christos   if (!ret)
   1269          1.1  christos     ret = bfd_hash_allocate (table, sizeof (*ret));
   1270          1.1  christos 
   1271          1.1  christos   if (!ret)
   1272          1.1  christos     return 0;
   1273          1.1  christos 
   1274          1.1  christos   /* Call the allocation method of the superclass.  */
   1275          1.1  christos   ret = ((struct elfNN_ia64_link_hash_entry *)
   1276          1.1  christos 	 _bfd_elf_link_hash_newfunc ((struct bfd_hash_entry *) ret,
   1277          1.1  christos 				     table, string));
   1278          1.1  christos 
   1279          1.1  christos   ret->info = NULL;
   1280          1.1  christos   ret->count = 0;
   1281          1.1  christos   ret->sorted_count = 0;
   1282          1.1  christos   ret->size = 0;
   1283          1.1  christos   return (struct bfd_hash_entry *) ret;
   1284          1.1  christos }
   1285          1.1  christos 
   1286          1.1  christos static void
   1287          1.1  christos elfNN_ia64_hash_copy_indirect (struct bfd_link_info *info,
   1288          1.1  christos 			       struct elf_link_hash_entry *xdir,
   1289          1.1  christos 			       struct elf_link_hash_entry *xind)
   1290          1.1  christos {
   1291          1.1  christos   struct elfNN_ia64_link_hash_entry *dir, *ind;
   1292          1.1  christos 
   1293          1.1  christos   dir = (struct elfNN_ia64_link_hash_entry *) xdir;
   1294      1.1.1.5  christos   ind = (struct elfNN_ia64_link_hash_entry *) xind;
   1295      1.1.1.5  christos 
   1296          1.1  christos   /* Copy down any references that we may have already seen to the
   1297          1.1  christos      symbol which just became indirect.  */
   1298          1.1  christos 
   1299          1.1  christos   if (dir->root.versioned != versioned_hidden)
   1300          1.1  christos     dir->root.ref_dynamic |= ind->root.ref_dynamic;
   1301          1.1  christos   dir->root.ref_regular |= ind->root.ref_regular;
   1302          1.1  christos   dir->root.ref_regular_nonweak |= ind->root.ref_regular_nonweak;
   1303          1.1  christos   dir->root.needs_plt |= ind->root.needs_plt;
   1304          1.1  christos 
   1305          1.1  christos   if (ind->root.root.type != bfd_link_hash_indirect)
   1306          1.1  christos     return;
   1307          1.1  christos 
   1308          1.1  christos   /* Copy over the got and plt data.  This would have been done
   1309          1.1  christos      by check_relocs.  */
   1310          1.1  christos 
   1311          1.1  christos   if (ind->info != NULL)
   1312          1.1  christos     {
   1313          1.1  christos       struct elfNN_ia64_dyn_sym_info *dyn_i;
   1314          1.1  christos       unsigned int count;
   1315          1.1  christos 
   1316          1.1  christos       if (dir->info)
   1317          1.1  christos 	free (dir->info);
   1318          1.1  christos 
   1319          1.1  christos       dir->info = ind->info;
   1320          1.1  christos       dir->count = ind->count;
   1321          1.1  christos       dir->sorted_count = ind->sorted_count;
   1322          1.1  christos       dir->size = ind->size;
   1323          1.1  christos 
   1324          1.1  christos       ind->info = NULL;
   1325          1.1  christos       ind->count = 0;
   1326          1.1  christos       ind->sorted_count = 0;
   1327          1.1  christos       ind->size = 0;
   1328          1.1  christos 
   1329          1.1  christos       /* Fix up the dyn_sym_info pointers to the global symbol.  */
   1330          1.1  christos       for (count = dir->count, dyn_i = dir->info;
   1331          1.1  christos 	   count != 0;
   1332          1.1  christos 	   count--, dyn_i++)
   1333          1.1  christos 	dyn_i->h = &dir->root;
   1334          1.1  christos     }
   1335          1.1  christos 
   1336          1.1  christos   /* Copy over the dynindx.  */
   1337          1.1  christos 
   1338          1.1  christos   if (ind->root.dynindx != -1)
   1339          1.1  christos     {
   1340          1.1  christos       if (dir->root.dynindx != -1)
   1341          1.1  christos 	_bfd_elf_strtab_delref (elf_hash_table (info)->dynstr,
   1342          1.1  christos 				dir->root.dynstr_index);
   1343          1.1  christos       dir->root.dynindx = ind->root.dynindx;
   1344          1.1  christos       dir->root.dynstr_index = ind->root.dynstr_index;
   1345          1.1  christos       ind->root.dynindx = -1;
   1346          1.1  christos       ind->root.dynstr_index = 0;
   1347          1.1  christos     }
   1348          1.1  christos }
   1349          1.1  christos 
   1350          1.1  christos static void
   1351          1.1  christos elfNN_ia64_hash_hide_symbol (struct bfd_link_info *info,
   1352          1.1  christos 			     struct elf_link_hash_entry *xh,
   1353          1.1  christos 			     bfd_boolean force_local)
   1354          1.1  christos {
   1355          1.1  christos   struct elfNN_ia64_link_hash_entry *h;
   1356          1.1  christos   struct elfNN_ia64_dyn_sym_info *dyn_i;
   1357          1.1  christos   unsigned int count;
   1358          1.1  christos 
   1359          1.1  christos   h = (struct elfNN_ia64_link_hash_entry *)xh;
   1360          1.1  christos 
   1361          1.1  christos   _bfd_elf_link_hash_hide_symbol (info, &h->root, force_local);
   1362          1.1  christos 
   1363          1.1  christos   for (count = h->count, dyn_i = h->info;
   1364          1.1  christos        count != 0;
   1365          1.1  christos        count--, dyn_i++)
   1366          1.1  christos     {
   1367          1.1  christos       dyn_i->want_plt2 = 0;
   1368          1.1  christos       dyn_i->want_plt = 0;
   1369          1.1  christos     }
   1370          1.1  christos }
   1371          1.1  christos 
   1372          1.1  christos /* Compute a hash of a local hash entry.  */
   1373          1.1  christos 
   1374          1.1  christos static hashval_t
   1375          1.1  christos elfNN_ia64_local_htab_hash (const void *ptr)
   1376          1.1  christos {
   1377          1.1  christos   struct elfNN_ia64_local_hash_entry *entry
   1378          1.1  christos     = (struct elfNN_ia64_local_hash_entry *) ptr;
   1379          1.1  christos 
   1380          1.1  christos   return ELF_LOCAL_SYMBOL_HASH (entry->id, entry->r_sym);
   1381          1.1  christos }
   1382          1.1  christos 
   1383          1.1  christos /* Compare local hash entries.  */
   1384          1.1  christos 
   1385          1.1  christos static int
   1386          1.1  christos elfNN_ia64_local_htab_eq (const void *ptr1, const void *ptr2)
   1387          1.1  christos {
   1388          1.1  christos   struct elfNN_ia64_local_hash_entry *entry1
   1389          1.1  christos     = (struct elfNN_ia64_local_hash_entry *) ptr1;
   1390          1.1  christos   struct elfNN_ia64_local_hash_entry *entry2
   1391          1.1  christos     = (struct elfNN_ia64_local_hash_entry *) ptr2;
   1392          1.1  christos 
   1393          1.1  christos   return entry1->id == entry2->id && entry1->r_sym == entry2->r_sym;
   1394          1.1  christos }
   1395          1.1  christos 
   1396          1.1  christos /* Free the global elfNN_ia64_dyn_sym_info array.  */
   1397          1.1  christos 
   1398          1.1  christos static bfd_boolean
   1399          1.1  christos elfNN_ia64_global_dyn_info_free (void **xentry,
   1400          1.1  christos 				 void * unused ATTRIBUTE_UNUSED)
   1401          1.1  christos {
   1402          1.1  christos   struct elfNN_ia64_link_hash_entry *entry
   1403          1.1  christos     = (struct elfNN_ia64_link_hash_entry *) xentry;
   1404          1.1  christos 
   1405          1.1  christos   if (entry->info)
   1406          1.1  christos     {
   1407          1.1  christos       free (entry->info);
   1408          1.1  christos       entry->info = NULL;
   1409          1.1  christos       entry->count = 0;
   1410          1.1  christos       entry->sorted_count = 0;
   1411          1.1  christos       entry->size = 0;
   1412          1.1  christos     }
   1413          1.1  christos 
   1414          1.1  christos   return TRUE;
   1415          1.1  christos }
   1416          1.1  christos 
   1417          1.1  christos /* Free the local elfNN_ia64_dyn_sym_info array.  */
   1418          1.1  christos 
   1419          1.1  christos static bfd_boolean
   1420          1.1  christos elfNN_ia64_local_dyn_info_free (void **slot,
   1421          1.1  christos 				void * unused ATTRIBUTE_UNUSED)
   1422          1.1  christos {
   1423          1.1  christos   struct elfNN_ia64_local_hash_entry *entry
   1424          1.1  christos     = (struct elfNN_ia64_local_hash_entry *) *slot;
   1425          1.1  christos 
   1426          1.1  christos   if (entry->info)
   1427          1.1  christos     {
   1428          1.1  christos       free (entry->info);
   1429          1.1  christos       entry->info = NULL;
   1430          1.1  christos       entry->count = 0;
   1431          1.1  christos       entry->sorted_count = 0;
   1432          1.1  christos       entry->size = 0;
   1433          1.1  christos     }
   1434          1.1  christos 
   1435          1.1  christos   return TRUE;
   1436      1.1.1.3  christos }
   1437          1.1  christos 
   1438          1.1  christos /* Destroy IA-64 linker hash table.  */
   1439      1.1.1.3  christos 
   1440          1.1  christos static void
   1441          1.1  christos elfNN_ia64_link_hash_table_free (bfd *obfd)
   1442          1.1  christos {
   1443          1.1  christos   struct elfNN_ia64_link_hash_table *ia64_info
   1444          1.1  christos     = (struct elfNN_ia64_link_hash_table *) obfd->link.hash;
   1445          1.1  christos   if (ia64_info->loc_hash_table)
   1446          1.1  christos     {
   1447          1.1  christos       htab_traverse (ia64_info->loc_hash_table,
   1448          1.1  christos 		     elfNN_ia64_local_dyn_info_free, NULL);
   1449          1.1  christos       htab_delete (ia64_info->loc_hash_table);
   1450      1.1.1.3  christos     }
   1451      1.1.1.3  christos   if (ia64_info->loc_hash_memory)
   1452      1.1.1.3  christos     objalloc_free ((struct objalloc *) ia64_info->loc_hash_memory);
   1453      1.1.1.3  christos   elf_link_hash_traverse (&ia64_info->root,
   1454      1.1.1.3  christos 			  elfNN_ia64_global_dyn_info_free, NULL);
   1455      1.1.1.3  christos   _bfd_elf_link_hash_table_free (obfd);
   1456      1.1.1.3  christos }
   1457      1.1.1.3  christos 
   1458      1.1.1.3  christos /* Create the derived linker hash table.  The IA-64 ELF port uses this
   1459      1.1.1.3  christos    derived hash table to keep information specific to the IA-64 ElF
   1460      1.1.1.3  christos    linker (without using static variables).  */
   1461      1.1.1.3  christos 
   1462      1.1.1.3  christos static struct bfd_link_hash_table *
   1463      1.1.1.3  christos elfNN_ia64_hash_table_create (bfd *abfd)
   1464      1.1.1.3  christos {
   1465      1.1.1.3  christos   struct elfNN_ia64_link_hash_table *ret;
   1466      1.1.1.3  christos 
   1467      1.1.1.3  christos   ret = bfd_zmalloc ((bfd_size_type) sizeof (*ret));
   1468      1.1.1.3  christos   if (!ret)
   1469      1.1.1.3  christos     return NULL;
   1470      1.1.1.3  christos 
   1471      1.1.1.3  christos   if (!_bfd_elf_link_hash_table_init (&ret->root, abfd,
   1472      1.1.1.3  christos 				      elfNN_ia64_new_elf_hash_entry,
   1473      1.1.1.3  christos 				      sizeof (struct elfNN_ia64_link_hash_entry),
   1474      1.1.1.3  christos 				      IA64_ELF_DATA))
   1475      1.1.1.3  christos     {
   1476      1.1.1.3  christos       free (ret);
   1477      1.1.1.3  christos       return NULL;
   1478      1.1.1.3  christos     }
   1479      1.1.1.3  christos 
   1480      1.1.1.3  christos   ret->loc_hash_table = htab_try_create (1024, elfNN_ia64_local_htab_hash,
   1481      1.1.1.3  christos 					 elfNN_ia64_local_htab_eq, NULL);
   1482      1.1.1.3  christos   ret->loc_hash_memory = objalloc_create ();
   1483      1.1.1.3  christos   if (!ret->loc_hash_table || !ret->loc_hash_memory)
   1484      1.1.1.3  christos     {
   1485      1.1.1.3  christos       elfNN_ia64_link_hash_table_free (abfd);
   1486          1.1  christos       return NULL;
   1487          1.1  christos     }
   1488          1.1  christos   ret->root.root.hash_table_free = elfNN_ia64_link_hash_table_free;
   1489          1.1  christos 
   1490          1.1  christos   return &ret->root.root;
   1491          1.1  christos }
   1492          1.1  christos 
   1493          1.1  christos /* Traverse both local and global hash tables.  */
   1494          1.1  christos 
   1495          1.1  christos struct elfNN_ia64_dyn_sym_traverse_data
   1496          1.1  christos {
   1497          1.1  christos   bfd_boolean (*func) (struct elfNN_ia64_dyn_sym_info *, void *);
   1498          1.1  christos   void * data;
   1499          1.1  christos };
   1500          1.1  christos 
   1501          1.1  christos static bfd_boolean
   1502          1.1  christos elfNN_ia64_global_dyn_sym_thunk (struct bfd_hash_entry *xentry,
   1503          1.1  christos 				 void * xdata)
   1504          1.1  christos {
   1505          1.1  christos   struct elfNN_ia64_link_hash_entry *entry
   1506          1.1  christos     = (struct elfNN_ia64_link_hash_entry *) xentry;
   1507          1.1  christos   struct elfNN_ia64_dyn_sym_traverse_data *data
   1508          1.1  christos     = (struct elfNN_ia64_dyn_sym_traverse_data *) xdata;
   1509          1.1  christos   struct elfNN_ia64_dyn_sym_info *dyn_i;
   1510          1.1  christos   unsigned int count;
   1511          1.1  christos 
   1512          1.1  christos   for (count = entry->count, dyn_i = entry->info;
   1513          1.1  christos        count != 0;
   1514          1.1  christos        count--, dyn_i++)
   1515          1.1  christos     if (! (*data->func) (dyn_i, data->data))
   1516          1.1  christos       return FALSE;
   1517          1.1  christos   return TRUE;
   1518          1.1  christos }
   1519          1.1  christos 
   1520          1.1  christos static bfd_boolean
   1521          1.1  christos elfNN_ia64_local_dyn_sym_thunk (void **slot, void * xdata)
   1522          1.1  christos {
   1523          1.1  christos   struct elfNN_ia64_local_hash_entry *entry
   1524          1.1  christos     = (struct elfNN_ia64_local_hash_entry *) *slot;
   1525          1.1  christos   struct elfNN_ia64_dyn_sym_traverse_data *data
   1526          1.1  christos     = (struct elfNN_ia64_dyn_sym_traverse_data *) xdata;
   1527          1.1  christos   struct elfNN_ia64_dyn_sym_info *dyn_i;
   1528          1.1  christos   unsigned int count;
   1529          1.1  christos 
   1530          1.1  christos   for (count = entry->count, dyn_i = entry->info;
   1531          1.1  christos        count != 0;
   1532          1.1  christos        count--, dyn_i++)
   1533          1.1  christos     if (! (*data->func) (dyn_i, data->data))
   1534          1.1  christos       return FALSE;
   1535          1.1  christos   return TRUE;
   1536          1.1  christos }
   1537          1.1  christos 
   1538          1.1  christos static void
   1539          1.1  christos elfNN_ia64_dyn_sym_traverse (struct elfNN_ia64_link_hash_table *ia64_info,
   1540          1.1  christos 			     bfd_boolean (*func) (struct elfNN_ia64_dyn_sym_info *, void *),
   1541          1.1  christos 			     void * data)
   1542          1.1  christos {
   1543          1.1  christos   struct elfNN_ia64_dyn_sym_traverse_data xdata;
   1544          1.1  christos 
   1545          1.1  christos   xdata.func = func;
   1546          1.1  christos   xdata.data = data;
   1547          1.1  christos 
   1548          1.1  christos   elf_link_hash_traverse (&ia64_info->root,
   1549          1.1  christos 			  elfNN_ia64_global_dyn_sym_thunk, &xdata);
   1550          1.1  christos   htab_traverse (ia64_info->loc_hash_table,
   1551          1.1  christos 		 elfNN_ia64_local_dyn_sym_thunk, &xdata);
   1552          1.1  christos }
   1553          1.1  christos 
   1554          1.1  christos static bfd_boolean
   1556          1.1  christos elfNN_ia64_create_dynamic_sections (bfd *abfd,
   1557          1.1  christos 				    struct bfd_link_info *info)
   1558          1.1  christos {
   1559          1.1  christos   struct elfNN_ia64_link_hash_table *ia64_info;
   1560          1.1  christos   asection *s;
   1561          1.1  christos 
   1562          1.1  christos   if (! _bfd_elf_create_dynamic_sections (abfd, info))
   1563          1.1  christos     return FALSE;
   1564          1.1  christos 
   1565          1.1  christos   ia64_info = elfNN_ia64_hash_table (info);
   1566          1.1  christos   if (ia64_info == NULL)
   1567          1.1  christos     return FALSE;
   1568      1.1.1.2  christos 
   1569      1.1.1.2  christos   {
   1570          1.1  christos     flagword flags = bfd_get_section_flags (abfd, ia64_info->root.sgot);
   1571          1.1  christos     bfd_set_section_flags (abfd, ia64_info->root.sgot,
   1572          1.1  christos 			   SEC_SMALL_DATA | flags);
   1573          1.1  christos     /* The .got section is always aligned at 8 bytes.  */
   1574          1.1  christos     if (! bfd_set_section_alignment (abfd, ia64_info->root.sgot, 3))
   1575          1.1  christos       return FALSE;
   1576          1.1  christos   }
   1577          1.1  christos 
   1578          1.1  christos   if (!get_pltoff (abfd, info, ia64_info))
   1579          1.1  christos     return FALSE;
   1580          1.1  christos 
   1581          1.1  christos   s = bfd_make_section_anyway_with_flags (abfd, ".rela.IA_64.pltoff",
   1582          1.1  christos 					  (SEC_ALLOC | SEC_LOAD
   1583          1.1  christos 					   | SEC_HAS_CONTENTS
   1584          1.1  christos 					   | SEC_IN_MEMORY
   1585          1.1  christos 					   | SEC_LINKER_CREATED
   1586          1.1  christos 					   | SEC_READONLY));
   1587          1.1  christos   if (s == NULL
   1588          1.1  christos       || !bfd_set_section_alignment (abfd, s, LOG_SECTION_ALIGN))
   1589          1.1  christos     return FALSE;
   1590          1.1  christos   ia64_info->rel_pltoff_sec = s;
   1591          1.1  christos 
   1592          1.1  christos   return TRUE;
   1593          1.1  christos }
   1594          1.1  christos 
   1595          1.1  christos /* Find and/or create a hash entry for local symbol.  */
   1596          1.1  christos static struct elfNN_ia64_local_hash_entry *
   1597          1.1  christos get_local_sym_hash (struct elfNN_ia64_link_hash_table *ia64_info,
   1598          1.1  christos 		    bfd *abfd, const Elf_Internal_Rela *rel,
   1599          1.1  christos 		    bfd_boolean create)
   1600          1.1  christos {
   1601          1.1  christos   struct elfNN_ia64_local_hash_entry e, *ret;
   1602          1.1  christos   asection *sec = abfd->sections;
   1603          1.1  christos   hashval_t h = ELF_LOCAL_SYMBOL_HASH (sec->id,
   1604          1.1  christos 				       ELFNN_R_SYM (rel->r_info));
   1605          1.1  christos   void **slot;
   1606          1.1  christos 
   1607          1.1  christos   e.id = sec->id;
   1608          1.1  christos   e.r_sym = ELFNN_R_SYM (rel->r_info);
   1609          1.1  christos   slot = htab_find_slot_with_hash (ia64_info->loc_hash_table, &e, h,
   1610          1.1  christos 				   create ? INSERT : NO_INSERT);
   1611          1.1  christos 
   1612          1.1  christos   if (!slot)
   1613          1.1  christos     return NULL;
   1614          1.1  christos 
   1615          1.1  christos   if (*slot)
   1616          1.1  christos     return (struct elfNN_ia64_local_hash_entry *) *slot;
   1617          1.1  christos 
   1618          1.1  christos   ret = (struct elfNN_ia64_local_hash_entry *)
   1619          1.1  christos 	objalloc_alloc ((struct objalloc *) ia64_info->loc_hash_memory,
   1620          1.1  christos 			sizeof (struct elfNN_ia64_local_hash_entry));
   1621          1.1  christos   if (ret)
   1622          1.1  christos     {
   1623          1.1  christos       memset (ret, 0, sizeof (*ret));
   1624          1.1  christos       ret->id = sec->id;
   1625          1.1  christos       ret->r_sym = ELFNN_R_SYM (rel->r_info);
   1626          1.1  christos       *slot = ret;
   1627          1.1  christos     }
   1628          1.1  christos   return ret;
   1629          1.1  christos }
   1630          1.1  christos 
   1631          1.1  christos /* Used to sort elfNN_ia64_dyn_sym_info array.  */
   1632          1.1  christos 
   1633          1.1  christos static int
   1634          1.1  christos addend_compare (const void *xp, const void *yp)
   1635          1.1  christos {
   1636          1.1  christos   const struct elfNN_ia64_dyn_sym_info *x
   1637          1.1  christos     = (const struct elfNN_ia64_dyn_sym_info *) xp;
   1638          1.1  christos   const struct elfNN_ia64_dyn_sym_info *y
   1639          1.1  christos     = (const struct elfNN_ia64_dyn_sym_info *) yp;
   1640          1.1  christos 
   1641          1.1  christos   return x->addend < y->addend ? -1 : x->addend > y->addend ? 1 : 0;
   1642          1.1  christos }
   1643          1.1  christos 
   1644          1.1  christos /* Sort elfNN_ia64_dyn_sym_info array and remove duplicates.  */
   1645          1.1  christos 
   1646          1.1  christos static unsigned int
   1647          1.1  christos sort_dyn_sym_info (struct elfNN_ia64_dyn_sym_info *info,
   1648          1.1  christos 		   unsigned int count)
   1649          1.1  christos {
   1650          1.1  christos   bfd_vma curr, prev, got_offset;
   1651          1.1  christos   unsigned int i, kept, dupes, diff, dest, src, len;
   1652          1.1  christos 
   1653          1.1  christos   qsort (info, count, sizeof (*info), addend_compare);
   1654          1.1  christos 
   1655          1.1  christos   /* Find the first duplicate.  */
   1656          1.1  christos   prev = info [0].addend;
   1657          1.1  christos   got_offset = info [0].got_offset;
   1658          1.1  christos   for (i = 1; i < count; i++)
   1659          1.1  christos     {
   1660          1.1  christos       curr = info [i].addend;
   1661          1.1  christos       if (curr == prev)
   1662          1.1  christos 	{
   1663          1.1  christos 	  /* For duplicates, make sure that GOT_OFFSET is valid.  */
   1664          1.1  christos 	  if (got_offset == (bfd_vma) -1)
   1665          1.1  christos 	    got_offset = info [i].got_offset;
   1666          1.1  christos 	  break;
   1667          1.1  christos 	}
   1668          1.1  christos       got_offset = info [i].got_offset;
   1669          1.1  christos       prev = curr;
   1670          1.1  christos     }
   1671          1.1  christos 
   1672          1.1  christos   /* We may move a block of elements to here.  */
   1673          1.1  christos   dest = i++;
   1674          1.1  christos 
   1675          1.1  christos   /* Remove duplicates.  */
   1676          1.1  christos   if (i < count)
   1677          1.1  christos     {
   1678          1.1  christos       while (i < count)
   1679          1.1  christos 	{
   1680          1.1  christos 	  /* For duplicates, make sure that the kept one has a valid
   1681          1.1  christos 	     got_offset.  */
   1682          1.1  christos 	  kept = dest - 1;
   1683          1.1  christos 	  if (got_offset != (bfd_vma) -1)
   1684          1.1  christos 	    info [kept].got_offset = got_offset;
   1685          1.1  christos 
   1686          1.1  christos 	  curr = info [i].addend;
   1687          1.1  christos 	  got_offset = info [i].got_offset;
   1688          1.1  christos 
   1689          1.1  christos 	  /* Move a block of elements whose first one is different from
   1690          1.1  christos 	     the previous.  */
   1691          1.1  christos 	  if (curr == prev)
   1692          1.1  christos 	    {
   1693          1.1  christos 	      for (src = i + 1; src < count; src++)
   1694          1.1  christos 		{
   1695          1.1  christos 		  if (info [src].addend != curr)
   1696          1.1  christos 		    break;
   1697          1.1  christos 		  /* For duplicates, make sure that GOT_OFFSET is
   1698          1.1  christos 		     valid.  */
   1699          1.1  christos 		  if (got_offset == (bfd_vma) -1)
   1700          1.1  christos 		    got_offset = info [src].got_offset;
   1701          1.1  christos 		}
   1702          1.1  christos 
   1703          1.1  christos 	      /* Make sure that the kept one has a valid got_offset.  */
   1704          1.1  christos 	      if (got_offset != (bfd_vma) -1)
   1705          1.1  christos 		info [kept].got_offset = got_offset;
   1706          1.1  christos 	    }
   1707          1.1  christos 	  else
   1708          1.1  christos 	    src = i;
   1709          1.1  christos 
   1710          1.1  christos 	  if (src >= count)
   1711          1.1  christos 	    break;
   1712          1.1  christos 
   1713          1.1  christos 	  /* Find the next duplicate.  SRC will be kept.  */
   1714          1.1  christos 	  prev = info [src].addend;
   1715          1.1  christos 	  got_offset = info [src].got_offset;
   1716          1.1  christos 	  for (dupes = src + 1; dupes < count; dupes ++)
   1717          1.1  christos 	    {
   1718          1.1  christos 	      curr = info [dupes].addend;
   1719          1.1  christos 	      if (curr == prev)
   1720          1.1  christos 		{
   1721          1.1  christos 		  /* Make sure that got_offset is valid.  */
   1722          1.1  christos 		  if (got_offset == (bfd_vma) -1)
   1723          1.1  christos 		    got_offset = info [dupes].got_offset;
   1724          1.1  christos 
   1725          1.1  christos 		  /* For duplicates, make sure that the kept one has
   1726          1.1  christos 		     a valid got_offset.  */
   1727          1.1  christos 		  if (got_offset != (bfd_vma) -1)
   1728          1.1  christos 		    info [dupes - 1].got_offset = got_offset;
   1729          1.1  christos 		  break;
   1730          1.1  christos 		}
   1731          1.1  christos 	      got_offset = info [dupes].got_offset;
   1732          1.1  christos 	      prev = curr;
   1733          1.1  christos 	    }
   1734          1.1  christos 
   1735          1.1  christos 	  /* How much to move.  */
   1736          1.1  christos 	  len = dupes - src;
   1737          1.1  christos 	  i = dupes + 1;
   1738          1.1  christos 
   1739          1.1  christos 	  if (len == 1 && dupes < count)
   1740          1.1  christos 	    {
   1741          1.1  christos 	      /* If we only move 1 element, we combine it with the next
   1742          1.1  christos 		 one.  There must be at least a duplicate.  Find the
   1743          1.1  christos 		 next different one.  */
   1744          1.1  christos 	      for (diff = dupes + 1, src++; diff < count; diff++, src++)
   1745          1.1  christos 		{
   1746          1.1  christos 		  if (info [diff].addend != curr)
   1747          1.1  christos 		    break;
   1748          1.1  christos 		  /* Make sure that got_offset is valid.  */
   1749          1.1  christos 		  if (got_offset == (bfd_vma) -1)
   1750          1.1  christos 		    got_offset = info [diff].got_offset;
   1751          1.1  christos 		}
   1752          1.1  christos 
   1753          1.1  christos 	      /* Makre sure that the last duplicated one has an valid
   1754          1.1  christos 		 offset.  */
   1755          1.1  christos 	      BFD_ASSERT (curr == prev);
   1756          1.1  christos 	      if (got_offset != (bfd_vma) -1)
   1757          1.1  christos 		info [diff - 1].got_offset = got_offset;
   1758          1.1  christos 
   1759          1.1  christos 	      if (diff < count)
   1760          1.1  christos 		{
   1761          1.1  christos 		  /* Find the next duplicate.  Track the current valid
   1762          1.1  christos 		     offset.  */
   1763          1.1  christos 		  prev = info [diff].addend;
   1764          1.1  christos 		  got_offset = info [diff].got_offset;
   1765          1.1  christos 		  for (dupes = diff + 1; dupes < count; dupes ++)
   1766          1.1  christos 		    {
   1767          1.1  christos 		      curr = info [dupes].addend;
   1768          1.1  christos 		      if (curr == prev)
   1769          1.1  christos 			{
   1770          1.1  christos 			  /* For duplicates, make sure that GOT_OFFSET
   1771          1.1  christos 			     is valid.  */
   1772          1.1  christos 			  if (got_offset == (bfd_vma) -1)
   1773          1.1  christos 			    got_offset = info [dupes].got_offset;
   1774          1.1  christos 			  break;
   1775          1.1  christos 			}
   1776          1.1  christos 		      got_offset = info [dupes].got_offset;
   1777          1.1  christos 		      prev = curr;
   1778          1.1  christos 		      diff++;
   1779          1.1  christos 		    }
   1780          1.1  christos 
   1781          1.1  christos 		  len = diff - src + 1;
   1782          1.1  christos 		  i = diff + 1;
   1783          1.1  christos 		}
   1784          1.1  christos 	    }
   1785          1.1  christos 
   1786          1.1  christos 	  memmove (&info [dest], &info [src], len * sizeof (*info));
   1787          1.1  christos 
   1788          1.1  christos 	  dest += len;
   1789          1.1  christos 	}
   1790          1.1  christos 
   1791          1.1  christos       count = dest;
   1792          1.1  christos     }
   1793          1.1  christos   else
   1794          1.1  christos     {
   1795          1.1  christos       /* When we get here, either there is no duplicate at all or
   1796          1.1  christos 	 the only duplicate is the last element.  */
   1797          1.1  christos       if (dest < count)
   1798          1.1  christos 	{
   1799          1.1  christos 	  /* If the last element is a duplicate, make sure that the
   1800          1.1  christos 	     kept one has a valid got_offset.  We also update count.  */
   1801          1.1  christos 	  if (got_offset != (bfd_vma) -1)
   1802          1.1  christos 	    info [dest - 1].got_offset = got_offset;
   1803          1.1  christos 	  count = dest;
   1804          1.1  christos 	}
   1805          1.1  christos     }
   1806          1.1  christos 
   1807          1.1  christos   return count;
   1808          1.1  christos }
   1809          1.1  christos 
   1810          1.1  christos /* Find and/or create a descriptor for dynamic symbol info.  This will
   1811          1.1  christos    vary based on global or local symbol, and the addend to the reloc.
   1812          1.1  christos 
   1813          1.1  christos    We don't sort when inserting.  Also, we sort and eliminate
   1814          1.1  christos    duplicates if there is an unsorted section.  Typically, this will
   1815          1.1  christos    only happen once, because we do all insertions before lookups.  We
   1816          1.1  christos    then use bsearch to do a lookup.  This also allows lookups to be
   1817          1.1  christos    fast.  So we have fast insertion (O(log N) due to duplicate check),
   1818          1.1  christos    fast lookup (O(log N)) and one sort (O(N log N) expected time).
   1819          1.1  christos    Previously, all lookups were O(N) because of the use of the linked
   1820          1.1  christos    list and also all insertions were O(N) because of the check for
   1821          1.1  christos    duplicates.  There are some complications here because the array
   1822          1.1  christos    size grows occasionally, which may add an O(N) factor, but this
   1823          1.1  christos    should be rare.  Also,  we free the excess array allocation, which
   1824          1.1  christos    requires a copy which is O(N), but this only happens once.  */
   1825          1.1  christos 
   1826          1.1  christos static struct elfNN_ia64_dyn_sym_info *
   1827          1.1  christos get_dyn_sym_info (struct elfNN_ia64_link_hash_table *ia64_info,
   1828          1.1  christos 		  struct elf_link_hash_entry *h, bfd *abfd,
   1829          1.1  christos 		  const Elf_Internal_Rela *rel, bfd_boolean create)
   1830          1.1  christos {
   1831          1.1  christos   struct elfNN_ia64_dyn_sym_info **info_p, *info, *dyn_i, key;
   1832          1.1  christos   unsigned int *count_p, *sorted_count_p, *size_p;
   1833          1.1  christos   unsigned int count, sorted_count, size;
   1834          1.1  christos   bfd_vma addend = rel ? rel->r_addend : 0;
   1835          1.1  christos   bfd_size_type amt;
   1836          1.1  christos 
   1837          1.1  christos   if (h)
   1838          1.1  christos     {
   1839          1.1  christos       struct elfNN_ia64_link_hash_entry *global_h;
   1840          1.1  christos 
   1841          1.1  christos       global_h = (struct elfNN_ia64_link_hash_entry *) h;
   1842          1.1  christos       info_p = &global_h->info;
   1843          1.1  christos       count_p = &global_h->count;
   1844          1.1  christos       sorted_count_p = &global_h->sorted_count;
   1845          1.1  christos       size_p = &global_h->size;
   1846          1.1  christos     }
   1847          1.1  christos   else
   1848          1.1  christos     {
   1849          1.1  christos       struct elfNN_ia64_local_hash_entry *loc_h;
   1850          1.1  christos 
   1851          1.1  christos       loc_h = get_local_sym_hash (ia64_info, abfd, rel, create);
   1852          1.1  christos       if (!loc_h)
   1853          1.1  christos 	{
   1854          1.1  christos 	  BFD_ASSERT (!create);
   1855          1.1  christos 	  return NULL;
   1856          1.1  christos 	}
   1857          1.1  christos 
   1858          1.1  christos       info_p = &loc_h->info;
   1859          1.1  christos       count_p = &loc_h->count;
   1860          1.1  christos       sorted_count_p = &loc_h->sorted_count;
   1861          1.1  christos       size_p = &loc_h->size;
   1862          1.1  christos     }
   1863          1.1  christos 
   1864          1.1  christos   count = *count_p;
   1865  1.1.1.5.4.1  christos   sorted_count = *sorted_count_p;
   1866          1.1  christos   size = *size_p;
   1867          1.1  christos   info = *info_p;
   1868          1.1  christos   if (create)
   1869          1.1  christos     {
   1870          1.1  christos       /* When we create the array, we don't check for duplicates,
   1871          1.1  christos 	 except in the previously sorted section if one exists, and
   1872          1.1  christos 	 against the last inserted entry.  This allows insertions to
   1873          1.1  christos 	 be fast.  */
   1874          1.1  christos       if (info)
   1875          1.1  christos 	{
   1876          1.1  christos 	  if (sorted_count)
   1877          1.1  christos 	    {
   1878          1.1  christos 	      /* Try bsearch first on the sorted section.  */
   1879          1.1  christos 	      key.addend = addend;
   1880          1.1  christos 	      dyn_i = bsearch (&key, info, sorted_count,
   1881          1.1  christos 			       sizeof (*info), addend_compare);
   1882          1.1  christos 
   1883          1.1  christos 	      if (dyn_i)
   1884          1.1  christos 		{
   1885          1.1  christos 		  return dyn_i;
   1886          1.1  christos 		}
   1887          1.1  christos 	    }
   1888          1.1  christos 
   1889          1.1  christos 	  /* Do a quick check for the last inserted entry.  */
   1890          1.1  christos 	  dyn_i = info + count - 1;
   1891          1.1  christos 	  if (dyn_i->addend == addend)
   1892          1.1  christos 	    {
   1893          1.1  christos 	      return dyn_i;
   1894          1.1  christos 	    }
   1895          1.1  christos 	}
   1896          1.1  christos 
   1897          1.1  christos       if (size == 0)
   1898          1.1  christos 	{
   1899          1.1  christos 	  /* It is the very first element. We create the array of size
   1900          1.1  christos 	     1.  */
   1901          1.1  christos 	  size = 1;
   1902          1.1  christos 	  amt = size * sizeof (*info);
   1903          1.1  christos 	  info = bfd_malloc (amt);
   1904          1.1  christos 	}
   1905          1.1  christos       else if (size <= count)
   1906          1.1  christos 	{
   1907          1.1  christos 	  /* We double the array size every time when we reach the
   1908          1.1  christos 	     size limit.  */
   1909          1.1  christos 	  size += size;
   1910          1.1  christos 	  amt = size * sizeof (*info);
   1911          1.1  christos 	  info = bfd_realloc (info, amt);
   1912          1.1  christos 	}
   1913          1.1  christos       else
   1914          1.1  christos 	goto has_space;
   1915          1.1  christos 
   1916          1.1  christos       if (info == NULL)
   1917          1.1  christos 	return NULL;
   1918          1.1  christos       *size_p = size;
   1919          1.1  christos       *info_p = info;
   1920          1.1  christos 
   1921          1.1  christos has_space:
   1922          1.1  christos       /* Append the new one to the array.  */
   1923          1.1  christos       dyn_i = info + count;
   1924          1.1  christos       memset (dyn_i, 0, sizeof (*dyn_i));
   1925          1.1  christos       dyn_i->got_offset = (bfd_vma) -1;
   1926          1.1  christos       dyn_i->addend = addend;
   1927          1.1  christos 
   1928          1.1  christos       /* We increment count only since the new ones are unsorted and
   1929          1.1  christos 	 may have duplicate.  */
   1930          1.1  christos       (*count_p)++;
   1931          1.1  christos     }
   1932          1.1  christos   else
   1933          1.1  christos     {
   1934          1.1  christos       /* It is a lookup without insertion.  Sort array if part of the
   1935          1.1  christos 	 array isn't sorted.  */
   1936          1.1  christos       if (count != sorted_count)
   1937          1.1  christos 	{
   1938          1.1  christos 	  count = sort_dyn_sym_info (info, count);
   1939          1.1  christos 	  *count_p = count;
   1940          1.1  christos 	  *sorted_count_p = count;
   1941          1.1  christos 	}
   1942          1.1  christos 
   1943          1.1  christos       /* Free unused memory.  */
   1944          1.1  christos       if (size != count)
   1945          1.1  christos 	{
   1946          1.1  christos 	  amt = count * sizeof (*info);
   1947          1.1  christos 	  info = bfd_malloc (amt);
   1948          1.1  christos 	  if (info != NULL)
   1949          1.1  christos 	    {
   1950          1.1  christos 	      memcpy (info, *info_p, amt);
   1951          1.1  christos 	      free (*info_p);
   1952          1.1  christos 	      *size_p = count;
   1953          1.1  christos 	      *info_p = info;
   1954          1.1  christos 	    }
   1955          1.1  christos 	}
   1956          1.1  christos 
   1957          1.1  christos       key.addend = addend;
   1958          1.1  christos       dyn_i = bsearch (&key, info, count,
   1959          1.1  christos 		       sizeof (*info), addend_compare);
   1960          1.1  christos     }
   1961          1.1  christos 
   1962          1.1  christos   return dyn_i;
   1963          1.1  christos }
   1964          1.1  christos 
   1965          1.1  christos static asection *
   1966          1.1  christos get_got (bfd *abfd, struct bfd_link_info *info,
   1967          1.1  christos 	 struct elfNN_ia64_link_hash_table *ia64_info)
   1968          1.1  christos {
   1969          1.1  christos   asection *got;
   1970          1.1  christos   bfd *dynobj;
   1971          1.1  christos 
   1972          1.1  christos   got = ia64_info->root.sgot;
   1973          1.1  christos   if (!got)
   1974          1.1  christos     {
   1975      1.1.1.2  christos       flagword flags;
   1976          1.1  christos 
   1977          1.1  christos       dynobj = ia64_info->root.dynobj;
   1978          1.1  christos       if (!dynobj)
   1979          1.1  christos 	ia64_info->root.dynobj = dynobj = abfd;
   1980          1.1  christos       if (!_bfd_elf_create_got_section (dynobj, info))
   1981      1.1.1.2  christos 	return NULL;
   1982          1.1  christos 
   1983          1.1  christos       got = ia64_info->root.sgot;
   1984      1.1.1.2  christos 
   1985      1.1.1.2  christos       /* The .got section is always aligned at 8 bytes.  */
   1986          1.1  christos       if (!bfd_set_section_alignment (abfd, got, 3))
   1987          1.1  christos 	return NULL;
   1988          1.1  christos 
   1989          1.1  christos       flags = bfd_get_section_flags (abfd, got);
   1990          1.1  christos       if (! bfd_set_section_flags (abfd, got, SEC_SMALL_DATA | flags))
   1991          1.1  christos 	return NULL;
   1992          1.1  christos     }
   1993          1.1  christos 
   1994          1.1  christos   return got;
   1995          1.1  christos }
   1996          1.1  christos 
   1997          1.1  christos /* Create function descriptor section (.opd).  This section is called .opd
   1998          1.1  christos    because it contains "official procedure descriptors".  The "official"
   1999          1.1  christos    refers to the fact that these descriptors are used when taking the address
   2000          1.1  christos    of a procedure, thus ensuring a unique address for each procedure.  */
   2001          1.1  christos 
   2002          1.1  christos static asection *
   2003          1.1  christos get_fptr (bfd *abfd, struct bfd_link_info *info,
   2004          1.1  christos 	  struct elfNN_ia64_link_hash_table *ia64_info)
   2005          1.1  christos {
   2006          1.1  christos   asection *fptr;
   2007          1.1  christos   bfd *dynobj;
   2008          1.1  christos 
   2009          1.1  christos   fptr = ia64_info->fptr_sec;
   2010          1.1  christos   if (!fptr)
   2011          1.1  christos     {
   2012          1.1  christos       dynobj = ia64_info->root.dynobj;
   2013          1.1  christos       if (!dynobj)
   2014          1.1  christos 	ia64_info->root.dynobj = dynobj = abfd;
   2015      1.1.1.4  christos 
   2016      1.1.1.4  christos       fptr = bfd_make_section_anyway_with_flags (dynobj, ".opd",
   2017          1.1  christos 						 (SEC_ALLOC
   2018          1.1  christos 						  | SEC_LOAD
   2019          1.1  christos 						  | SEC_HAS_CONTENTS
   2020          1.1  christos 						  | SEC_IN_MEMORY
   2021          1.1  christos 						  | (bfd_link_pie (info)
   2022          1.1  christos 						     ? 0 : SEC_READONLY)
   2023          1.1  christos 						  | SEC_LINKER_CREATED));
   2024          1.1  christos       if (!fptr
   2025          1.1  christos 	  || !bfd_set_section_alignment (abfd, fptr, 4))
   2026          1.1  christos 	{
   2027      1.1.1.4  christos 	  BFD_ASSERT (0);
   2028          1.1  christos 	  return NULL;
   2029          1.1  christos 	}
   2030          1.1  christos 
   2031          1.1  christos       ia64_info->fptr_sec = fptr;
   2032          1.1  christos 
   2033          1.1  christos       if (bfd_link_pie (info))
   2034          1.1  christos 	{
   2035          1.1  christos 	  asection *fptr_rel;
   2036          1.1  christos 	  fptr_rel = bfd_make_section_anyway_with_flags (dynobj, ".rela.opd",
   2037          1.1  christos 							 (SEC_ALLOC | SEC_LOAD
   2038          1.1  christos 							  | SEC_HAS_CONTENTS
   2039          1.1  christos 							  | SEC_IN_MEMORY
   2040          1.1  christos 							  | SEC_LINKER_CREATED
   2041          1.1  christos 							  | SEC_READONLY));
   2042          1.1  christos 	  if (fptr_rel == NULL
   2043          1.1  christos 	      || !bfd_set_section_alignment (abfd, fptr_rel,
   2044          1.1  christos 					     LOG_SECTION_ALIGN))
   2045          1.1  christos 	    {
   2046          1.1  christos 	      BFD_ASSERT (0);
   2047          1.1  christos 	      return NULL;
   2048          1.1  christos 	    }
   2049          1.1  christos 
   2050          1.1  christos 	  ia64_info->rel_fptr_sec = fptr_rel;
   2051          1.1  christos 	}
   2052          1.1  christos     }
   2053          1.1  christos 
   2054          1.1  christos   return fptr;
   2055          1.1  christos }
   2056          1.1  christos 
   2057          1.1  christos static asection *
   2058          1.1  christos get_pltoff (bfd *abfd, struct bfd_link_info *info ATTRIBUTE_UNUSED,
   2059          1.1  christos 	    struct elfNN_ia64_link_hash_table *ia64_info)
   2060          1.1  christos {
   2061          1.1  christos   asection *pltoff;
   2062          1.1  christos   bfd *dynobj;
   2063          1.1  christos 
   2064          1.1  christos   pltoff = ia64_info->pltoff_sec;
   2065          1.1  christos   if (!pltoff)
   2066          1.1  christos     {
   2067          1.1  christos       dynobj = ia64_info->root.dynobj;
   2068          1.1  christos       if (!dynobj)
   2069          1.1  christos 	ia64_info->root.dynobj = dynobj = abfd;
   2070          1.1  christos 
   2071          1.1  christos       pltoff = bfd_make_section_anyway_with_flags (dynobj,
   2072          1.1  christos 						   ELF_STRING_ia64_pltoff,
   2073          1.1  christos 						   (SEC_ALLOC
   2074          1.1  christos 						    | SEC_LOAD
   2075          1.1  christos 						    | SEC_HAS_CONTENTS
   2076          1.1  christos 						    | SEC_IN_MEMORY
   2077          1.1  christos 						    | SEC_SMALL_DATA
   2078          1.1  christos 						    | SEC_LINKER_CREATED));
   2079          1.1  christos       if (!pltoff
   2080          1.1  christos 	  || !bfd_set_section_alignment (abfd, pltoff, 4))
   2081          1.1  christos 	{
   2082          1.1  christos 	  BFD_ASSERT (0);
   2083          1.1  christos 	  return NULL;
   2084          1.1  christos 	}
   2085          1.1  christos 
   2086          1.1  christos       ia64_info->pltoff_sec = pltoff;
   2087          1.1  christos     }
   2088          1.1  christos 
   2089          1.1  christos   return pltoff;
   2090          1.1  christos }
   2091          1.1  christos 
   2092          1.1  christos static asection *
   2093          1.1  christos get_reloc_section (bfd *abfd,
   2094          1.1  christos 		   struct elfNN_ia64_link_hash_table *ia64_info,
   2095          1.1  christos 		   asection *sec, bfd_boolean create)
   2096          1.1  christos {
   2097          1.1  christos   const char *srel_name;
   2098          1.1  christos   asection *srel;
   2099          1.1  christos   bfd *dynobj;
   2100          1.1  christos 
   2101          1.1  christos   srel_name = (bfd_elf_string_from_elf_section
   2102          1.1  christos 	       (abfd, elf_elfheader(abfd)->e_shstrndx,
   2103          1.1  christos 		_bfd_elf_single_rel_hdr (sec)->sh_name));
   2104          1.1  christos   if (srel_name == NULL)
   2105          1.1  christos     return NULL;
   2106          1.1  christos 
   2107          1.1  christos   dynobj = ia64_info->root.dynobj;
   2108          1.1  christos   if (!dynobj)
   2109          1.1  christos     ia64_info->root.dynobj = dynobj = abfd;
   2110          1.1  christos 
   2111          1.1  christos   srel = bfd_get_linker_section (dynobj, srel_name);
   2112          1.1  christos   if (srel == NULL && create)
   2113          1.1  christos     {
   2114          1.1  christos       srel = bfd_make_section_anyway_with_flags (dynobj, srel_name,
   2115          1.1  christos 						 (SEC_ALLOC | SEC_LOAD
   2116          1.1  christos 						  | SEC_HAS_CONTENTS
   2117          1.1  christos 						  | SEC_IN_MEMORY
   2118          1.1  christos 						  | SEC_LINKER_CREATED
   2119          1.1  christos 						  | SEC_READONLY));
   2120          1.1  christos       if (srel == NULL
   2121          1.1  christos 	  || !bfd_set_section_alignment (dynobj, srel,
   2122          1.1  christos 					 LOG_SECTION_ALIGN))
   2123          1.1  christos 	return NULL;
   2124          1.1  christos     }
   2125          1.1  christos 
   2126          1.1  christos   return srel;
   2127          1.1  christos }
   2128          1.1  christos 
   2129          1.1  christos static bfd_boolean
   2130          1.1  christos count_dyn_reloc (bfd *abfd, struct elfNN_ia64_dyn_sym_info *dyn_i,
   2131          1.1  christos 		 asection *srel, int type, bfd_boolean reltext)
   2132          1.1  christos {
   2133          1.1  christos   struct elfNN_ia64_dyn_reloc_entry *rent;
   2134          1.1  christos 
   2135          1.1  christos   for (rent = dyn_i->reloc_entries; rent; rent = rent->next)
   2136          1.1  christos     if (rent->srel == srel && rent->type == type)
   2137          1.1  christos       break;
   2138          1.1  christos 
   2139          1.1  christos   if (!rent)
   2140          1.1  christos     {
   2141          1.1  christos       rent = ((struct elfNN_ia64_dyn_reloc_entry *)
   2142          1.1  christos 	      bfd_alloc (abfd, (bfd_size_type) sizeof (*rent)));
   2143          1.1  christos       if (!rent)
   2144          1.1  christos 	return FALSE;
   2145          1.1  christos 
   2146          1.1  christos       rent->next = dyn_i->reloc_entries;
   2147          1.1  christos       rent->srel = srel;
   2148          1.1  christos       rent->type = type;
   2149          1.1  christos       rent->count = 0;
   2150          1.1  christos       dyn_i->reloc_entries = rent;
   2151          1.1  christos     }
   2152          1.1  christos   rent->reltext = reltext;
   2153          1.1  christos   rent->count++;
   2154          1.1  christos 
   2155          1.1  christos   return TRUE;
   2156          1.1  christos }
   2157          1.1  christos 
   2158          1.1  christos static bfd_boolean
   2159          1.1  christos elfNN_ia64_check_relocs (bfd *abfd, struct bfd_link_info *info,
   2160          1.1  christos 			 asection *sec,
   2161          1.1  christos 			 const Elf_Internal_Rela *relocs)
   2162          1.1  christos {
   2163          1.1  christos   struct elfNN_ia64_link_hash_table *ia64_info;
   2164          1.1  christos   const Elf_Internal_Rela *relend;
   2165          1.1  christos   Elf_Internal_Shdr *symtab_hdr;
   2166          1.1  christos   const Elf_Internal_Rela *rel;
   2167          1.1  christos   asection *got, *fptr, *srel, *pltoff;
   2168          1.1  christos   enum {
   2169          1.1  christos     NEED_GOT = 1,
   2170          1.1  christos     NEED_GOTX = 2,
   2171          1.1  christos     NEED_FPTR = 4,
   2172          1.1  christos     NEED_PLTOFF = 8,
   2173          1.1  christos     NEED_MIN_PLT = 16,
   2174          1.1  christos     NEED_FULL_PLT = 32,
   2175          1.1  christos     NEED_DYNREL = 64,
   2176          1.1  christos     NEED_LTOFF_FPTR = 128,
   2177          1.1  christos     NEED_TPREL = 256,
   2178          1.1  christos     NEED_DTPMOD = 512,
   2179          1.1  christos     NEED_DTPREL = 1024
   2180      1.1.1.4  christos   };
   2181          1.1  christos   int need_entry;
   2182          1.1  christos   struct elf_link_hash_entry *h;
   2183          1.1  christos   unsigned long r_symndx;
   2184          1.1  christos   bfd_boolean maybe_dynamic;
   2185          1.1  christos 
   2186          1.1  christos   if (bfd_link_relocatable (info))
   2187          1.1  christos     return TRUE;
   2188          1.1  christos 
   2189          1.1  christos   symtab_hdr = &elf_tdata (abfd)->symtab_hdr;
   2190          1.1  christos   ia64_info = elfNN_ia64_hash_table (info);
   2191          1.1  christos   if (ia64_info == NULL)
   2192          1.1  christos     return FALSE;
   2193          1.1  christos 
   2194          1.1  christos   got = fptr = srel = pltoff = NULL;
   2195          1.1  christos 
   2196          1.1  christos   relend = relocs + sec->reloc_count;
   2197          1.1  christos 
   2198          1.1  christos   /* We scan relocations first to create dynamic relocation arrays.  We
   2199          1.1  christos      modified get_dyn_sym_info to allow fast insertion and support fast
   2200          1.1  christos      lookup in the next loop.  */
   2201          1.1  christos   for (rel = relocs; rel < relend; ++rel)
   2202          1.1  christos     {
   2203          1.1  christos       r_symndx = ELFNN_R_SYM (rel->r_info);
   2204          1.1  christos       if (r_symndx >= symtab_hdr->sh_info)
   2205          1.1  christos 	{
   2206          1.1  christos 	  long indx = r_symndx - symtab_hdr->sh_info;
   2207          1.1  christos 	  h = elf_sym_hashes (abfd)[indx];
   2208          1.1  christos 	  while (h->root.type == bfd_link_hash_indirect
   2209  1.1.1.5.4.1  christos 		 || h->root.type == bfd_link_hash_warning)
   2210  1.1.1.5.4.1  christos 	    h = (struct elf_link_hash_entry *) h->root.u.i.link;
   2211  1.1.1.5.4.1  christos 	}
   2212          1.1  christos       else
   2213          1.1  christos 	h = NULL;
   2214          1.1  christos 
   2215          1.1  christos       if (h && UNDEFWEAK_NO_DYNAMIC_RELOC (info, h))
   2216      1.1.1.4  christos 	continue;
   2217          1.1  christos 
   2218          1.1  christos       /* We can only get preliminary data on whether a symbol is
   2219          1.1  christos 	 locally or externally defined, as not all of the input files
   2220          1.1  christos 	 have yet been processed.  Do something with what we know, as
   2221          1.1  christos 	 this may help reduce memory usage and processing time later.  */
   2222          1.1  christos       maybe_dynamic = (h && ((!bfd_link_executable (info)
   2223          1.1  christos 			      && (!SYMBOLIC_BIND (info, h)
   2224          1.1  christos 				  || info->unresolved_syms_in_shared_libs == RM_IGNORE))
   2225          1.1  christos 			     || !h->def_regular
   2226          1.1  christos 			     || h->root.type == bfd_link_hash_defweak));
   2227      1.1.1.4  christos 
   2228          1.1  christos       need_entry = 0;
   2229          1.1  christos       switch (ELFNN_R_TYPE (rel->r_info))
   2230          1.1  christos 	{
   2231          1.1  christos 	case R_IA64_TPREL64MSB:
   2232          1.1  christos 	case R_IA64_TPREL64LSB:
   2233      1.1.1.4  christos 	  if (bfd_link_pic (info) || maybe_dynamic)
   2234          1.1  christos 	    need_entry = NEED_DYNREL;
   2235          1.1  christos 	  break;
   2236          1.1  christos 
   2237          1.1  christos 	case R_IA64_LTOFF_TPREL22:
   2238          1.1  christos 	  need_entry = NEED_TPREL;
   2239          1.1  christos 	  if (bfd_link_pic (info))
   2240          1.1  christos 	    info->flags |= DF_STATIC_TLS;
   2241      1.1.1.4  christos 	  break;
   2242          1.1  christos 
   2243          1.1  christos 	case R_IA64_DTPREL32MSB:
   2244          1.1  christos 	case R_IA64_DTPREL32LSB:
   2245          1.1  christos 	case R_IA64_DTPREL64MSB:
   2246          1.1  christos 	case R_IA64_DTPREL64LSB:
   2247          1.1  christos 	  if (bfd_link_pic (info) || maybe_dynamic)
   2248          1.1  christos 	    need_entry = NEED_DYNREL;
   2249          1.1  christos 	  break;
   2250          1.1  christos 
   2251      1.1.1.4  christos 	case R_IA64_LTOFF_DTPREL22:
   2252          1.1  christos 	  need_entry = NEED_DTPREL;
   2253          1.1  christos 	  break;
   2254          1.1  christos 
   2255          1.1  christos 	case R_IA64_DTPMOD64MSB:
   2256          1.1  christos 	case R_IA64_DTPMOD64LSB:
   2257          1.1  christos 	  if (bfd_link_pic (info) || maybe_dynamic)
   2258          1.1  christos 	    need_entry = NEED_DYNREL;
   2259          1.1  christos 	  break;
   2260          1.1  christos 
   2261          1.1  christos 	case R_IA64_LTOFF_DTPMOD22:
   2262          1.1  christos 	  need_entry = NEED_DTPMOD;
   2263          1.1  christos 	  break;
   2264          1.1  christos 
   2265          1.1  christos 	case R_IA64_LTOFF_FPTR22:
   2266          1.1  christos 	case R_IA64_LTOFF_FPTR64I:
   2267          1.1  christos 	case R_IA64_LTOFF_FPTR32MSB:
   2268          1.1  christos 	case R_IA64_LTOFF_FPTR32LSB:
   2269          1.1  christos 	case R_IA64_LTOFF_FPTR64MSB:
   2270          1.1  christos 	case R_IA64_LTOFF_FPTR64LSB:
   2271          1.1  christos 	  need_entry = NEED_FPTR | NEED_GOT | NEED_LTOFF_FPTR;
   2272          1.1  christos 	  break;
   2273      1.1.1.4  christos 
   2274          1.1  christos 	case R_IA64_FPTR64I:
   2275          1.1  christos 	case R_IA64_FPTR32MSB:
   2276          1.1  christos 	case R_IA64_FPTR32LSB:
   2277          1.1  christos 	case R_IA64_FPTR64MSB:
   2278          1.1  christos 	case R_IA64_FPTR64LSB:
   2279          1.1  christos 	  if (bfd_link_pic (info) || h)
   2280          1.1  christos 	    need_entry = NEED_FPTR | NEED_DYNREL;
   2281          1.1  christos 	  else
   2282          1.1  christos 	    need_entry = NEED_FPTR;
   2283          1.1  christos 	  break;
   2284          1.1  christos 
   2285          1.1  christos 	case R_IA64_LTOFF22:
   2286          1.1  christos 	case R_IA64_LTOFF64I:
   2287          1.1  christos 	  need_entry = NEED_GOT;
   2288          1.1  christos 	  break;
   2289          1.1  christos 
   2290          1.1  christos 	case R_IA64_LTOFF22X:
   2291          1.1  christos 	  need_entry = NEED_GOTX;
   2292          1.1  christos 	  break;
   2293          1.1  christos 
   2294          1.1  christos 	case R_IA64_PLTOFF22:
   2295          1.1  christos 	case R_IA64_PLTOFF64I:
   2296          1.1  christos 	case R_IA64_PLTOFF64MSB:
   2297          1.1  christos 	case R_IA64_PLTOFF64LSB:
   2298          1.1  christos 	  need_entry = NEED_PLTOFF;
   2299          1.1  christos 	  if (h)
   2300          1.1  christos 	    {
   2301          1.1  christos 	      if (maybe_dynamic)
   2302          1.1  christos 		need_entry |= NEED_MIN_PLT;
   2303          1.1  christos 	    }
   2304          1.1  christos 	  else
   2305          1.1  christos 	    {
   2306          1.1  christos 	      (*info->callbacks->warning)
   2307  1.1.1.5.4.1  christos 		(info, _("@pltoff reloc against local symbol"), 0,
   2308          1.1  christos 		 abfd, 0, (bfd_vma) 0);
   2309          1.1  christos 	    }
   2310          1.1  christos 	  break;
   2311          1.1  christos 
   2312          1.1  christos 	case R_IA64_PCREL21B:
   2313          1.1  christos 	case R_IA64_PCREL60B:
   2314          1.1  christos 	  /* Depending on where this symbol is defined, we may or may not
   2315          1.1  christos 	     need a full plt entry.  Only skip if we know we'll not need
   2316          1.1  christos 	     the entry -- static or symbolic, and the symbol definition
   2317          1.1  christos 	     has already been seen.  */
   2318          1.1  christos 	  if (maybe_dynamic && rel->r_addend == 0)
   2319          1.1  christos 	    need_entry = NEED_FULL_PLT;
   2320          1.1  christos 	  break;
   2321          1.1  christos 
   2322          1.1  christos 	case R_IA64_IMM14:
   2323          1.1  christos 	case R_IA64_IMM22:
   2324      1.1.1.4  christos 	case R_IA64_IMM64:
   2325          1.1  christos 	case R_IA64_DIR32MSB:
   2326          1.1  christos 	case R_IA64_DIR32LSB:
   2327          1.1  christos 	case R_IA64_DIR64MSB:
   2328          1.1  christos 	case R_IA64_DIR64LSB:
   2329          1.1  christos 	  /* Shared objects will always need at least a REL relocation.  */
   2330          1.1  christos 	  if (bfd_link_pic (info) || maybe_dynamic)
   2331      1.1.1.4  christos 	    need_entry = NEED_DYNREL;
   2332          1.1  christos 	  break;
   2333          1.1  christos 
   2334          1.1  christos 	case R_IA64_IPLTMSB:
   2335          1.1  christos 	case R_IA64_IPLTLSB:
   2336          1.1  christos 	  /* Shared objects will always need at least a REL relocation.  */
   2337          1.1  christos 	  if (bfd_link_pic (info) || maybe_dynamic)
   2338          1.1  christos 	    need_entry = NEED_DYNREL;
   2339          1.1  christos 	  break;
   2340          1.1  christos 
   2341          1.1  christos 	case R_IA64_PCREL22:
   2342          1.1  christos 	case R_IA64_PCREL64I:
   2343          1.1  christos 	case R_IA64_PCREL32MSB:
   2344          1.1  christos 	case R_IA64_PCREL32LSB:
   2345          1.1  christos 	case R_IA64_PCREL64MSB:
   2346          1.1  christos 	case R_IA64_PCREL64LSB:
   2347          1.1  christos 	  if (maybe_dynamic)
   2348          1.1  christos 	    need_entry = NEED_DYNREL;
   2349          1.1  christos 	  break;
   2350          1.1  christos 	}
   2351          1.1  christos 
   2352          1.1  christos       if (!need_entry)
   2353          1.1  christos 	continue;
   2354          1.1  christos 
   2355          1.1  christos       if ((need_entry & NEED_FPTR) != 0
   2356          1.1  christos 	  && rel->r_addend)
   2357          1.1  christos 	{
   2358          1.1  christos 	  (*info->callbacks->warning)
   2359          1.1  christos 	    (info, _("non-zero addend in @fptr reloc"), 0,
   2360          1.1  christos 	     abfd, 0, (bfd_vma) 0);
   2361          1.1  christos 	}
   2362          1.1  christos 
   2363          1.1  christos       if (get_dyn_sym_info (ia64_info, h, abfd, rel, TRUE) == NULL)
   2364          1.1  christos 	return FALSE;
   2365          1.1  christos     }
   2366          1.1  christos 
   2367          1.1  christos   /* Now, we only do lookup without insertion, which is very fast
   2368          1.1  christos      with the modified get_dyn_sym_info.  */
   2369          1.1  christos   for (rel = relocs; rel < relend; ++rel)
   2370          1.1  christos     {
   2371          1.1  christos       struct elfNN_ia64_dyn_sym_info *dyn_i;
   2372          1.1  christos       int dynrel_type = R_IA64_NONE;
   2373          1.1  christos 
   2374          1.1  christos       r_symndx = ELFNN_R_SYM (rel->r_info);
   2375          1.1  christos       if (r_symndx >= symtab_hdr->sh_info)
   2376          1.1  christos 	{
   2377          1.1  christos 	  /* We're dealing with a global symbol -- find its hash entry
   2378          1.1  christos 	     and mark it as being referenced.  */
   2379      1.1.1.2  christos 	  long indx = r_symndx - symtab_hdr->sh_info;
   2380      1.1.1.2  christos 	  h = elf_sym_hashes (abfd)[indx];
   2381          1.1  christos 	  while (h->root.type == bfd_link_hash_indirect
   2382          1.1  christos 		 || h->root.type == bfd_link_hash_warning)
   2383          1.1  christos 	    h = (struct elf_link_hash_entry *) h->root.u.i.link;
   2384          1.1  christos 
   2385          1.1  christos 	  /* PR15323, ref flags aren't set for references in the same
   2386  1.1.1.5.4.1  christos 	     object.  */
   2387  1.1.1.5.4.1  christos 	  h->ref_regular = 1;
   2388  1.1.1.5.4.1  christos 	}
   2389          1.1  christos       else
   2390          1.1  christos 	h = NULL;
   2391          1.1  christos 
   2392          1.1  christos       if (h && UNDEFWEAK_NO_DYNAMIC_RELOC (info, h))
   2393      1.1.1.4  christos 	continue;
   2394          1.1  christos 
   2395          1.1  christos       /* We can only get preliminary data on whether a symbol is
   2396          1.1  christos 	 locally or externally defined, as not all of the input files
   2397          1.1  christos 	 have yet been processed.  Do something with what we know, as
   2398          1.1  christos 	 this may help reduce memory usage and processing time later.  */
   2399          1.1  christos       maybe_dynamic = (h && ((!bfd_link_executable (info)
   2400          1.1  christos 			      && (!SYMBOLIC_BIND (info, h)
   2401          1.1  christos 				  || info->unresolved_syms_in_shared_libs == RM_IGNORE))
   2402          1.1  christos 			     || !h->def_regular
   2403          1.1  christos 			     || h->root.type == bfd_link_hash_defweak));
   2404      1.1.1.4  christos 
   2405          1.1  christos       need_entry = 0;
   2406          1.1  christos       switch (ELFNN_R_TYPE (rel->r_info))
   2407      1.1.1.4  christos 	{
   2408          1.1  christos 	case R_IA64_TPREL64MSB:
   2409          1.1  christos 	case R_IA64_TPREL64LSB:
   2410          1.1  christos 	  if (bfd_link_pic (info) || maybe_dynamic)
   2411          1.1  christos 	    need_entry = NEED_DYNREL;
   2412          1.1  christos 	  dynrel_type = R_IA64_TPREL64LSB;
   2413      1.1.1.4  christos 	  if (bfd_link_pic (info))
   2414          1.1  christos 	    info->flags |= DF_STATIC_TLS;
   2415          1.1  christos 	  break;
   2416          1.1  christos 
   2417          1.1  christos 	case R_IA64_LTOFF_TPREL22:
   2418          1.1  christos 	  need_entry = NEED_TPREL;
   2419          1.1  christos 	  if (bfd_link_pic (info))
   2420          1.1  christos 	    info->flags |= DF_STATIC_TLS;
   2421      1.1.1.4  christos 	  break;
   2422          1.1  christos 
   2423          1.1  christos 	case R_IA64_DTPREL32MSB:
   2424          1.1  christos 	case R_IA64_DTPREL32LSB:
   2425          1.1  christos 	case R_IA64_DTPREL64MSB:
   2426          1.1  christos 	case R_IA64_DTPREL64LSB:
   2427          1.1  christos 	  if (bfd_link_pic (info) || maybe_dynamic)
   2428          1.1  christos 	    need_entry = NEED_DYNREL;
   2429          1.1  christos 	  dynrel_type = R_IA64_DTPRELNNLSB;
   2430          1.1  christos 	  break;
   2431          1.1  christos 
   2432      1.1.1.4  christos 	case R_IA64_LTOFF_DTPREL22:
   2433          1.1  christos 	  need_entry = NEED_DTPREL;
   2434          1.1  christos 	  break;
   2435          1.1  christos 
   2436          1.1  christos 	case R_IA64_DTPMOD64MSB:
   2437          1.1  christos 	case R_IA64_DTPMOD64LSB:
   2438          1.1  christos 	  if (bfd_link_pic (info) || maybe_dynamic)
   2439          1.1  christos 	    need_entry = NEED_DYNREL;
   2440          1.1  christos 	  dynrel_type = R_IA64_DTPMOD64LSB;
   2441          1.1  christos 	  break;
   2442          1.1  christos 
   2443          1.1  christos 	case R_IA64_LTOFF_DTPMOD22:
   2444          1.1  christos 	  need_entry = NEED_DTPMOD;
   2445          1.1  christos 	  break;
   2446          1.1  christos 
   2447          1.1  christos 	case R_IA64_LTOFF_FPTR22:
   2448          1.1  christos 	case R_IA64_LTOFF_FPTR64I:
   2449          1.1  christos 	case R_IA64_LTOFF_FPTR32MSB:
   2450          1.1  christos 	case R_IA64_LTOFF_FPTR32LSB:
   2451          1.1  christos 	case R_IA64_LTOFF_FPTR64MSB:
   2452          1.1  christos 	case R_IA64_LTOFF_FPTR64LSB:
   2453          1.1  christos 	  need_entry = NEED_FPTR | NEED_GOT | NEED_LTOFF_FPTR;
   2454          1.1  christos 	  break;
   2455      1.1.1.4  christos 
   2456          1.1  christos 	case R_IA64_FPTR64I:
   2457          1.1  christos 	case R_IA64_FPTR32MSB:
   2458          1.1  christos 	case R_IA64_FPTR32LSB:
   2459          1.1  christos 	case R_IA64_FPTR64MSB:
   2460          1.1  christos 	case R_IA64_FPTR64LSB:
   2461          1.1  christos 	  if (bfd_link_pic (info) || h)
   2462          1.1  christos 	    need_entry = NEED_FPTR | NEED_DYNREL;
   2463          1.1  christos 	  else
   2464          1.1  christos 	    need_entry = NEED_FPTR;
   2465          1.1  christos 	  dynrel_type = R_IA64_FPTRNNLSB;
   2466          1.1  christos 	  break;
   2467          1.1  christos 
   2468          1.1  christos 	case R_IA64_LTOFF22:
   2469          1.1  christos 	case R_IA64_LTOFF64I:
   2470          1.1  christos 	  need_entry = NEED_GOT;
   2471          1.1  christos 	  break;
   2472          1.1  christos 
   2473          1.1  christos 	case R_IA64_LTOFF22X:
   2474          1.1  christos 	  need_entry = NEED_GOTX;
   2475          1.1  christos 	  break;
   2476          1.1  christos 
   2477          1.1  christos 	case R_IA64_PLTOFF22:
   2478          1.1  christos 	case R_IA64_PLTOFF64I:
   2479          1.1  christos 	case R_IA64_PLTOFF64MSB:
   2480          1.1  christos 	case R_IA64_PLTOFF64LSB:
   2481          1.1  christos 	  need_entry = NEED_PLTOFF;
   2482          1.1  christos 	  if (h)
   2483          1.1  christos 	    {
   2484  1.1.1.5.4.1  christos 	      if (maybe_dynamic)
   2485          1.1  christos 		need_entry |= NEED_MIN_PLT;
   2486          1.1  christos 	    }
   2487          1.1  christos 	  break;
   2488          1.1  christos 
   2489          1.1  christos 	case R_IA64_PCREL21B:
   2490          1.1  christos 	case R_IA64_PCREL60B:
   2491          1.1  christos 	  /* Depending on where this symbol is defined, we may or may not
   2492          1.1  christos 	     need a full plt entry.  Only skip if we know we'll not need
   2493          1.1  christos 	     the entry -- static or symbolic, and the symbol definition
   2494          1.1  christos 	     has already been seen.  */
   2495          1.1  christos 	  if (maybe_dynamic && rel->r_addend == 0)
   2496          1.1  christos 	    need_entry = NEED_FULL_PLT;
   2497          1.1  christos 	  break;
   2498          1.1  christos 
   2499          1.1  christos 	case R_IA64_IMM14:
   2500          1.1  christos 	case R_IA64_IMM22:
   2501      1.1.1.4  christos 	case R_IA64_IMM64:
   2502          1.1  christos 	case R_IA64_DIR32MSB:
   2503          1.1  christos 	case R_IA64_DIR32LSB:
   2504          1.1  christos 	case R_IA64_DIR64MSB:
   2505          1.1  christos 	case R_IA64_DIR64LSB:
   2506          1.1  christos 	  /* Shared objects will always need at least a REL relocation.  */
   2507          1.1  christos 	  if (bfd_link_pic (info) || maybe_dynamic)
   2508          1.1  christos 	    need_entry = NEED_DYNREL;
   2509      1.1.1.4  christos 	  dynrel_type = R_IA64_DIRNNLSB;
   2510          1.1  christos 	  break;
   2511          1.1  christos 
   2512          1.1  christos 	case R_IA64_IPLTMSB:
   2513          1.1  christos 	case R_IA64_IPLTLSB:
   2514          1.1  christos 	  /* Shared objects will always need at least a REL relocation.  */
   2515          1.1  christos 	  if (bfd_link_pic (info) || maybe_dynamic)
   2516          1.1  christos 	    need_entry = NEED_DYNREL;
   2517          1.1  christos 	  dynrel_type = R_IA64_IPLTLSB;
   2518          1.1  christos 	  break;
   2519          1.1  christos 
   2520          1.1  christos 	case R_IA64_PCREL22:
   2521          1.1  christos 	case R_IA64_PCREL64I:
   2522          1.1  christos 	case R_IA64_PCREL32MSB:
   2523          1.1  christos 	case R_IA64_PCREL32LSB:
   2524          1.1  christos 	case R_IA64_PCREL64MSB:
   2525          1.1  christos 	case R_IA64_PCREL64LSB:
   2526          1.1  christos 	  if (maybe_dynamic)
   2527          1.1  christos 	    need_entry = NEED_DYNREL;
   2528          1.1  christos 	  dynrel_type = R_IA64_PCRELNNLSB;
   2529          1.1  christos 	  break;
   2530          1.1  christos 	}
   2531          1.1  christos 
   2532          1.1  christos       if (!need_entry)
   2533          1.1  christos 	continue;
   2534          1.1  christos 
   2535          1.1  christos       dyn_i = get_dyn_sym_info (ia64_info, h, abfd, rel, FALSE);
   2536          1.1  christos 
   2537          1.1  christos       /* Record whether or not this is a local symbol.  */
   2538          1.1  christos       dyn_i->h = h;
   2539          1.1  christos 
   2540          1.1  christos       /* Create what's needed.  */
   2541          1.1  christos       if (need_entry & (NEED_GOT | NEED_GOTX | NEED_TPREL
   2542          1.1  christos 			| NEED_DTPMOD | NEED_DTPREL))
   2543          1.1  christos 	{
   2544          1.1  christos 	  if (!got)
   2545          1.1  christos 	    {
   2546          1.1  christos 	      got = get_got (abfd, info, ia64_info);
   2547          1.1  christos 	      if (!got)
   2548          1.1  christos 		return FALSE;
   2549          1.1  christos 	    }
   2550          1.1  christos 	  if (need_entry & NEED_GOT)
   2551          1.1  christos 	    dyn_i->want_got = 1;
   2552          1.1  christos 	  if (need_entry & NEED_GOTX)
   2553          1.1  christos 	    dyn_i->want_gotx = 1;
   2554          1.1  christos 	  if (need_entry & NEED_TPREL)
   2555          1.1  christos 	    dyn_i->want_tprel = 1;
   2556          1.1  christos 	  if (need_entry & NEED_DTPMOD)
   2557          1.1  christos 	    dyn_i->want_dtpmod = 1;
   2558          1.1  christos 	  if (need_entry & NEED_DTPREL)
   2559          1.1  christos 	    dyn_i->want_dtprel = 1;
   2560          1.1  christos 	}
   2561          1.1  christos       if (need_entry & NEED_FPTR)
   2562          1.1  christos 	{
   2563          1.1  christos 	  if (!fptr)
   2564          1.1  christos 	    {
   2565          1.1  christos 	      fptr = get_fptr (abfd, info, ia64_info);
   2566          1.1  christos 	      if (!fptr)
   2567      1.1.1.4  christos 		return FALSE;
   2568          1.1  christos 	    }
   2569          1.1  christos 
   2570          1.1  christos 	  /* FPTRs for shared libraries are allocated by the dynamic
   2571          1.1  christos 	     linker.  Make sure this local symbol will appear in the
   2572          1.1  christos 	     dynamic symbol table.  */
   2573          1.1  christos 	  if (!h && bfd_link_pic (info))
   2574          1.1  christos 	    {
   2575          1.1  christos 	      if (! (bfd_elf_link_record_local_dynamic_symbol
   2576          1.1  christos 		     (info, abfd, (long) r_symndx)))
   2577          1.1  christos 		return FALSE;
   2578          1.1  christos 	    }
   2579          1.1  christos 
   2580  1.1.1.5.4.1  christos 	  dyn_i->want_fptr = 1;
   2581          1.1  christos 	}
   2582          1.1  christos       if (need_entry & NEED_LTOFF_FPTR)
   2583          1.1  christos 	dyn_i->want_ltoff_fptr = 1;
   2584          1.1  christos       if (need_entry & (NEED_MIN_PLT | NEED_FULL_PLT))
   2585          1.1  christos 	{
   2586          1.1  christos 	  if (!ia64_info->root.dynobj)
   2587          1.1  christos 	    ia64_info->root.dynobj = abfd;
   2588          1.1  christos 	  h->needs_plt = 1;
   2589          1.1  christos 	  dyn_i->want_plt = 1;
   2590          1.1  christos 	}
   2591          1.1  christos       if (need_entry & NEED_FULL_PLT)
   2592          1.1  christos 	dyn_i->want_plt2 = 1;
   2593          1.1  christos       if (need_entry & NEED_PLTOFF)
   2594          1.1  christos 	{
   2595          1.1  christos 	  /* This is needed here, in case @pltoff is used in a non-shared
   2596          1.1  christos 	     link.  */
   2597          1.1  christos 	  if (!pltoff)
   2598          1.1  christos 	    {
   2599          1.1  christos 	      pltoff = get_pltoff (abfd, info, ia64_info);
   2600          1.1  christos 	      if (!pltoff)
   2601          1.1  christos 		return FALSE;
   2602          1.1  christos 	    }
   2603          1.1  christos 
   2604          1.1  christos 	  dyn_i->want_pltoff = 1;
   2605          1.1  christos 	}
   2606          1.1  christos       if ((need_entry & NEED_DYNREL) && (sec->flags & SEC_ALLOC))
   2607          1.1  christos 	{
   2608          1.1  christos 	  if (!srel)
   2609          1.1  christos 	    {
   2610          1.1  christos 	      srel = get_reloc_section (abfd, ia64_info, sec, TRUE);
   2611          1.1  christos 	      if (!srel)
   2612          1.1  christos 		return FALSE;
   2613          1.1  christos 	    }
   2614          1.1  christos 	  if (!count_dyn_reloc (abfd, dyn_i, srel, dynrel_type,
   2615          1.1  christos 				(sec->flags & SEC_READONLY) != 0))
   2616          1.1  christos 	    return FALSE;
   2617          1.1  christos 	}
   2618          1.1  christos     }
   2619          1.1  christos 
   2620          1.1  christos   return TRUE;
   2621          1.1  christos }
   2622          1.1  christos 
   2623          1.1  christos /* For cleanliness, and potentially faster dynamic loading, allocate
   2624          1.1  christos    external GOT entries first.  */
   2625          1.1  christos 
   2626          1.1  christos static bfd_boolean
   2627          1.1  christos allocate_global_data_got (struct elfNN_ia64_dyn_sym_info *dyn_i,
   2628          1.1  christos 			  void * data)
   2629          1.1  christos {
   2630          1.1  christos   struct elfNN_ia64_allocate_data *x = (struct elfNN_ia64_allocate_data *)data;
   2631          1.1  christos 
   2632          1.1  christos   if ((dyn_i->want_got || dyn_i->want_gotx)
   2633          1.1  christos       && ! dyn_i->want_fptr
   2634          1.1  christos       && elfNN_ia64_dynamic_symbol_p (dyn_i->h, x->info, 0))
   2635          1.1  christos      {
   2636          1.1  christos        dyn_i->got_offset = x->ofs;
   2637          1.1  christos        x->ofs += 8;
   2638          1.1  christos      }
   2639          1.1  christos   if (dyn_i->want_tprel)
   2640          1.1  christos     {
   2641          1.1  christos       dyn_i->tprel_offset = x->ofs;
   2642          1.1  christos       x->ofs += 8;
   2643          1.1  christos     }
   2644          1.1  christos   if (dyn_i->want_dtpmod)
   2645          1.1  christos     {
   2646          1.1  christos       if (elfNN_ia64_dynamic_symbol_p (dyn_i->h, x->info, 0))
   2647          1.1  christos 	{
   2648          1.1  christos 	  dyn_i->dtpmod_offset = x->ofs;
   2649          1.1  christos 	  x->ofs += 8;
   2650          1.1  christos 	}
   2651          1.1  christos       else
   2652          1.1  christos 	{
   2653          1.1  christos 	  struct elfNN_ia64_link_hash_table *ia64_info;
   2654          1.1  christos 
   2655          1.1  christos 	  ia64_info = elfNN_ia64_hash_table (x->info);
   2656          1.1  christos 	  if (ia64_info == NULL)
   2657          1.1  christos 	    return FALSE;
   2658          1.1  christos 
   2659          1.1  christos 	  if (ia64_info->self_dtpmod_offset == (bfd_vma) -1)
   2660          1.1  christos 	    {
   2661          1.1  christos 	      ia64_info->self_dtpmod_offset = x->ofs;
   2662          1.1  christos 	      x->ofs += 8;
   2663          1.1  christos 	    }
   2664          1.1  christos 	  dyn_i->dtpmod_offset = ia64_info->self_dtpmod_offset;
   2665          1.1  christos 	}
   2666          1.1  christos     }
   2667          1.1  christos   if (dyn_i->want_dtprel)
   2668          1.1  christos     {
   2669          1.1  christos       dyn_i->dtprel_offset = x->ofs;
   2670          1.1  christos       x->ofs += 8;
   2671          1.1  christos     }
   2672          1.1  christos   return TRUE;
   2673          1.1  christos }
   2674          1.1  christos 
   2675          1.1  christos /* Next, allocate all the GOT entries used by LTOFF_FPTR relocs.  */
   2676          1.1  christos 
   2677          1.1  christos static bfd_boolean
   2678          1.1  christos allocate_global_fptr_got (struct elfNN_ia64_dyn_sym_info *dyn_i,
   2679          1.1  christos 			  void * data)
   2680          1.1  christos {
   2681          1.1  christos   struct elfNN_ia64_allocate_data *x = (struct elfNN_ia64_allocate_data *)data;
   2682          1.1  christos 
   2683          1.1  christos   if (dyn_i->want_got
   2684          1.1  christos       && dyn_i->want_fptr
   2685          1.1  christos       && elfNN_ia64_dynamic_symbol_p (dyn_i->h, x->info, R_IA64_FPTRNNLSB))
   2686          1.1  christos     {
   2687          1.1  christos       dyn_i->got_offset = x->ofs;
   2688          1.1  christos       x->ofs += 8;
   2689          1.1  christos     }
   2690          1.1  christos   return TRUE;
   2691          1.1  christos }
   2692          1.1  christos 
   2693          1.1  christos /* Lastly, allocate all the GOT entries for local data.  */
   2694          1.1  christos 
   2695          1.1  christos static bfd_boolean
   2696          1.1  christos allocate_local_got (struct elfNN_ia64_dyn_sym_info *dyn_i,
   2697          1.1  christos 		    void * data)
   2698          1.1  christos {
   2699          1.1  christos   struct elfNN_ia64_allocate_data *x = (struct elfNN_ia64_allocate_data *)data;
   2700          1.1  christos 
   2701          1.1  christos   if ((dyn_i->want_got || dyn_i->want_gotx)
   2702          1.1  christos       && !elfNN_ia64_dynamic_symbol_p (dyn_i->h, x->info, 0))
   2703          1.1  christos     {
   2704          1.1  christos       dyn_i->got_offset = x->ofs;
   2705          1.1  christos       x->ofs += 8;
   2706          1.1  christos     }
   2707          1.1  christos   return TRUE;
   2708          1.1  christos }
   2709          1.1  christos 
   2710          1.1  christos /* Search for the index of a global symbol in it's defining object file.  */
   2711          1.1  christos 
   2712          1.1  christos static long
   2713          1.1  christos global_sym_index (struct elf_link_hash_entry *h)
   2714          1.1  christos {
   2715          1.1  christos   struct elf_link_hash_entry **p;
   2716          1.1  christos   bfd *obj;
   2717          1.1  christos 
   2718          1.1  christos   BFD_ASSERT (h->root.type == bfd_link_hash_defined
   2719          1.1  christos 	      || h->root.type == bfd_link_hash_defweak);
   2720          1.1  christos 
   2721          1.1  christos   obj = h->root.u.def.section->owner;
   2722          1.1  christos   for (p = elf_sym_hashes (obj); *p != h; ++p)
   2723          1.1  christos     continue;
   2724          1.1  christos 
   2725          1.1  christos   return p - elf_sym_hashes (obj) + elf_tdata (obj)->symtab_hdr.sh_info;
   2726          1.1  christos }
   2727          1.1  christos 
   2728          1.1  christos /* Allocate function descriptors.  We can do these for every function
   2729          1.1  christos    in a main executable that is not exported.  */
   2730          1.1  christos 
   2731          1.1  christos static bfd_boolean
   2732          1.1  christos allocate_fptr (struct elfNN_ia64_dyn_sym_info *dyn_i, void * data)
   2733          1.1  christos {
   2734          1.1  christos   struct elfNN_ia64_allocate_data *x = (struct elfNN_ia64_allocate_data *)data;
   2735          1.1  christos 
   2736          1.1  christos   if (dyn_i->want_fptr)
   2737          1.1  christos     {
   2738          1.1  christos       struct elf_link_hash_entry *h = dyn_i->h;
   2739      1.1.1.4  christos 
   2740          1.1  christos       if (h)
   2741  1.1.1.5.4.1  christos 	while (h->root.type == bfd_link_hash_indirect
   2742  1.1.1.5.4.1  christos 	       || h->root.type == bfd_link_hash_warning)
   2743          1.1  christos 	  h = (struct elf_link_hash_entry *) h->root.u.i.link;
   2744          1.1  christos 
   2745          1.1  christos       if (!bfd_link_executable (x->info)
   2746          1.1  christos 	  && (!h
   2747          1.1  christos 	      || (ELF_ST_VISIBILITY (h->other) == STV_DEFAULT
   2748          1.1  christos 		  && !UNDEFWEAK_NO_DYNAMIC_RELOC (x->info, h))
   2749          1.1  christos 	      || (h->root.type != bfd_link_hash_undefweak
   2750          1.1  christos 		  && h->root.type != bfd_link_hash_undefined)))
   2751          1.1  christos 	{
   2752          1.1  christos 	  if (h && h->dynindx == -1)
   2753          1.1  christos 	    {
   2754          1.1  christos 	      BFD_ASSERT ((h->root.type == bfd_link_hash_defined)
   2755          1.1  christos 			  || (h->root.type == bfd_link_hash_defweak));
   2756          1.1  christos 
   2757          1.1  christos 	      if (!bfd_elf_link_record_local_dynamic_symbol
   2758          1.1  christos 		    (x->info, h->root.u.def.section->owner,
   2759          1.1  christos 		     global_sym_index (h)))
   2760          1.1  christos 		return FALSE;
   2761          1.1  christos 	    }
   2762          1.1  christos 
   2763          1.1  christos 	  dyn_i->want_fptr = 0;
   2764          1.1  christos 	}
   2765          1.1  christos       else if (h == NULL || h->dynindx == -1)
   2766          1.1  christos 	{
   2767          1.1  christos 	  dyn_i->fptr_offset = x->ofs;
   2768          1.1  christos 	  x->ofs += 16;
   2769          1.1  christos 	}
   2770          1.1  christos       else
   2771          1.1  christos 	dyn_i->want_fptr = 0;
   2772          1.1  christos     }
   2773          1.1  christos   return TRUE;
   2774          1.1  christos }
   2775          1.1  christos 
   2776          1.1  christos /* Allocate all the minimal PLT entries.  */
   2777          1.1  christos 
   2778          1.1  christos static bfd_boolean
   2779          1.1  christos allocate_plt_entries (struct elfNN_ia64_dyn_sym_info *dyn_i,
   2780          1.1  christos 		      void * data)
   2781          1.1  christos {
   2782          1.1  christos   struct elfNN_ia64_allocate_data *x = (struct elfNN_ia64_allocate_data *)data;
   2783          1.1  christos 
   2784          1.1  christos   if (dyn_i->want_plt)
   2785          1.1  christos     {
   2786          1.1  christos       struct elf_link_hash_entry *h = dyn_i->h;
   2787          1.1  christos 
   2788          1.1  christos       if (h)
   2789          1.1  christos 	while (h->root.type == bfd_link_hash_indirect
   2790          1.1  christos 	       || h->root.type == bfd_link_hash_warning)
   2791          1.1  christos 	  h = (struct elf_link_hash_entry *) h->root.u.i.link;
   2792          1.1  christos 
   2793          1.1  christos       /* ??? Versioned symbols seem to lose NEEDS_PLT.  */
   2794          1.1  christos       if (elfNN_ia64_dynamic_symbol_p (h, x->info, 0))
   2795          1.1  christos 	{
   2796          1.1  christos 	  bfd_size_type offset = x->ofs;
   2797          1.1  christos 	  if (offset == 0)
   2798          1.1  christos 	    offset = PLT_HEADER_SIZE;
   2799          1.1  christos 	  dyn_i->plt_offset = offset;
   2800          1.1  christos 	  x->ofs = offset + PLT_MIN_ENTRY_SIZE;
   2801          1.1  christos 
   2802          1.1  christos 	  dyn_i->want_pltoff = 1;
   2803          1.1  christos 	}
   2804          1.1  christos       else
   2805          1.1  christos 	{
   2806          1.1  christos 	  dyn_i->want_plt = 0;
   2807          1.1  christos 	  dyn_i->want_plt2 = 0;
   2808          1.1  christos 	}
   2809          1.1  christos     }
   2810          1.1  christos   return TRUE;
   2811          1.1  christos }
   2812          1.1  christos 
   2813          1.1  christos /* Allocate all the full PLT entries.  */
   2814          1.1  christos 
   2815          1.1  christos static bfd_boolean
   2816          1.1  christos allocate_plt2_entries (struct elfNN_ia64_dyn_sym_info *dyn_i,
   2817          1.1  christos 		       void * data)
   2818          1.1  christos {
   2819          1.1  christos   struct elfNN_ia64_allocate_data *x = (struct elfNN_ia64_allocate_data *)data;
   2820          1.1  christos 
   2821          1.1  christos   if (dyn_i->want_plt2)
   2822          1.1  christos     {
   2823          1.1  christos       struct elf_link_hash_entry *h = dyn_i->h;
   2824          1.1  christos       bfd_size_type ofs = x->ofs;
   2825          1.1  christos 
   2826          1.1  christos       dyn_i->plt2_offset = ofs;
   2827          1.1  christos       x->ofs = ofs + PLT_FULL_ENTRY_SIZE;
   2828          1.1  christos 
   2829          1.1  christos       while (h->root.type == bfd_link_hash_indirect
   2830          1.1  christos 	     || h->root.type == bfd_link_hash_warning)
   2831          1.1  christos 	h = (struct elf_link_hash_entry *) h->root.u.i.link;
   2832          1.1  christos       dyn_i->h->plt.offset = ofs;
   2833          1.1  christos     }
   2834          1.1  christos   return TRUE;
   2835          1.1  christos }
   2836          1.1  christos 
   2837          1.1  christos /* Allocate all the PLTOFF entries requested by relocations and
   2838          1.1  christos    plt entries.  We can't share space with allocated FPTR entries,
   2839          1.1  christos    because the latter are not necessarily addressable by the GP.
   2840          1.1  christos    ??? Relaxation might be able to determine that they are.  */
   2841          1.1  christos 
   2842          1.1  christos static bfd_boolean
   2843          1.1  christos allocate_pltoff_entries (struct elfNN_ia64_dyn_sym_info *dyn_i,
   2844          1.1  christos 			 void * data)
   2845          1.1  christos {
   2846          1.1  christos   struct elfNN_ia64_allocate_data *x = (struct elfNN_ia64_allocate_data *)data;
   2847          1.1  christos 
   2848          1.1  christos   if (dyn_i->want_pltoff)
   2849          1.1  christos     {
   2850          1.1  christos       dyn_i->pltoff_offset = x->ofs;
   2851          1.1  christos       x->ofs += 16;
   2852          1.1  christos     }
   2853          1.1  christos   return TRUE;
   2854          1.1  christos }
   2855          1.1  christos 
   2856          1.1  christos /* Allocate dynamic relocations for those symbols that turned out
   2857          1.1  christos    to be dynamic.  */
   2858          1.1  christos 
   2859          1.1  christos static bfd_boolean
   2860          1.1  christos allocate_dynrel_entries (struct elfNN_ia64_dyn_sym_info *dyn_i,
   2861          1.1  christos 			 void * data)
   2862          1.1  christos {
   2863          1.1  christos   struct elfNN_ia64_allocate_data *x = (struct elfNN_ia64_allocate_data *)data;
   2864          1.1  christos   struct elfNN_ia64_link_hash_table *ia64_info;
   2865          1.1  christos   struct elfNN_ia64_dyn_reloc_entry *rent;
   2866          1.1  christos   bfd_boolean dynamic_symbol, shared, resolved_zero;
   2867          1.1  christos 
   2868          1.1  christos   ia64_info = elfNN_ia64_hash_table (x->info);
   2869      1.1.1.4  christos   if (ia64_info == NULL)
   2870          1.1  christos     return FALSE;
   2871  1.1.1.5.4.1  christos 
   2872  1.1.1.5.4.1  christos   /* Note that this can't be used in relation to FPTR relocs below.  */
   2873          1.1  christos   dynamic_symbol = elfNN_ia64_dynamic_symbol_p (dyn_i->h, x->info, 0);
   2874          1.1  christos 
   2875          1.1  christos   shared = bfd_link_pic (x->info);
   2876          1.1  christos   resolved_zero = (dyn_i->h
   2877          1.1  christos 		   && UNDEFWEAK_NO_DYNAMIC_RELOC (x->info,
   2878          1.1  christos 						       dyn_i->h));
   2879          1.1  christos 
   2880          1.1  christos   /* Take care of the GOT and PLT relocations.  */
   2881          1.1  christos 
   2882          1.1  christos   if ((!resolved_zero
   2883          1.1  christos        && (dynamic_symbol || shared)
   2884      1.1.1.4  christos        && (dyn_i->want_got || dyn_i->want_gotx))
   2885          1.1  christos       || (dyn_i->want_ltoff_fptr
   2886          1.1  christos 	  && dyn_i->h
   2887          1.1  christos 	  && dyn_i->h->dynindx != -1))
   2888          1.1  christos     {
   2889          1.1  christos       if (!dyn_i->want_ltoff_fptr
   2890          1.1  christos 	  || !bfd_link_pie (x->info)
   2891          1.1  christos 	  || dyn_i->h == NULL
   2892          1.1  christos 	  || dyn_i->h->root.type != bfd_link_hash_undefweak)
   2893          1.1  christos 	ia64_info->root.srelgot->size += sizeof (ElfNN_External_Rela);
   2894          1.1  christos     }
   2895          1.1  christos   if ((dynamic_symbol || shared) && dyn_i->want_tprel)
   2896          1.1  christos     ia64_info->root.srelgot->size += sizeof (ElfNN_External_Rela);
   2897          1.1  christos   if (dynamic_symbol && dyn_i->want_dtpmod)
   2898          1.1  christos     ia64_info->root.srelgot->size += sizeof (ElfNN_External_Rela);
   2899          1.1  christos   if (dynamic_symbol && dyn_i->want_dtprel)
   2900          1.1  christos     ia64_info->root.srelgot->size += sizeof (ElfNN_External_Rela);
   2901          1.1  christos 
   2902          1.1  christos   if (x->only_got)
   2903          1.1  christos     return TRUE;
   2904          1.1  christos 
   2905          1.1  christos   if (ia64_info->rel_fptr_sec && dyn_i->want_fptr)
   2906          1.1  christos     {
   2907          1.1  christos       if (dyn_i->h == NULL || dyn_i->h->root.type != bfd_link_hash_undefweak)
   2908          1.1  christos 	ia64_info->rel_fptr_sec->size += sizeof (ElfNN_External_Rela);
   2909          1.1  christos     }
   2910          1.1  christos 
   2911          1.1  christos   if (!resolved_zero && dyn_i->want_pltoff)
   2912          1.1  christos     {
   2913          1.1  christos       bfd_size_type t = 0;
   2914          1.1  christos 
   2915          1.1  christos       /* Dynamic symbols get one IPLT relocation.  Local symbols in
   2916          1.1  christos 	 shared libraries get two REL relocations.  Local symbols in
   2917          1.1  christos 	 main applications get nothing.  */
   2918          1.1  christos       if (dynamic_symbol)
   2919          1.1  christos 	t = sizeof (ElfNN_External_Rela);
   2920          1.1  christos       else if (shared)
   2921          1.1  christos 	t = 2 * sizeof (ElfNN_External_Rela);
   2922          1.1  christos 
   2923          1.1  christos       ia64_info->rel_pltoff_sec->size += t;
   2924          1.1  christos     }
   2925          1.1  christos 
   2926          1.1  christos   /* Take care of the normal data relocations.  */
   2927          1.1  christos 
   2928          1.1  christos   for (rent = dyn_i->reloc_entries; rent; rent = rent->next)
   2929          1.1  christos     {
   2930          1.1  christos       int count = rent->count;
   2931          1.1  christos 
   2932          1.1  christos       switch (rent->type)
   2933          1.1  christos 	{
   2934      1.1.1.4  christos 	case R_IA64_FPTR32LSB:
   2935          1.1  christos 	case R_IA64_FPTR64LSB:
   2936          1.1  christos 	  /* Allocate one iff !want_fptr and not PIE, which by this point
   2937          1.1  christos 	     will be true only if we're actually allocating one statically
   2938          1.1  christos 	     in the main executable.  Position independent executables
   2939          1.1  christos 	     need a relative reloc.  */
   2940          1.1  christos 	  if (dyn_i->want_fptr && !bfd_link_pie (x->info))
   2941          1.1  christos 	    continue;
   2942          1.1  christos 	  break;
   2943          1.1  christos 	case R_IA64_PCREL32LSB:
   2944          1.1  christos 	case R_IA64_PCREL64LSB:
   2945          1.1  christos 	  if (!dynamic_symbol)
   2946          1.1  christos 	    continue;
   2947          1.1  christos 	  break;
   2948          1.1  christos 	case R_IA64_DIR32LSB:
   2949          1.1  christos 	case R_IA64_DIR64LSB:
   2950          1.1  christos 	  if (!dynamic_symbol && !shared)
   2951          1.1  christos 	    continue;
   2952          1.1  christos 	  break;
   2953          1.1  christos 	case R_IA64_IPLTLSB:
   2954          1.1  christos 	  if (!dynamic_symbol && !shared)
   2955          1.1  christos 	    continue;
   2956          1.1  christos 	  /* Use two REL relocations for IPLT relocations
   2957          1.1  christos 	     against local symbols.  */
   2958          1.1  christos 	  if (!dynamic_symbol)
   2959          1.1  christos 	    count *= 2;
   2960          1.1  christos 	  break;
   2961          1.1  christos 	case R_IA64_DTPREL32LSB:
   2962          1.1  christos 	case R_IA64_TPREL64LSB:
   2963          1.1  christos 	case R_IA64_DTPREL64LSB:
   2964          1.1  christos 	case R_IA64_DTPMOD64LSB:
   2965          1.1  christos 	  break;
   2966          1.1  christos 	default:
   2967          1.1  christos 	  abort ();
   2968          1.1  christos 	}
   2969          1.1  christos       if (rent->reltext)
   2970          1.1  christos 	ia64_info->reltext = 1;
   2971          1.1  christos       rent->srel->size += sizeof (ElfNN_External_Rela) * count;
   2972          1.1  christos     }
   2973          1.1  christos 
   2974          1.1  christos   return TRUE;
   2975          1.1  christos }
   2976          1.1  christos 
   2977          1.1  christos static bfd_boolean
   2978          1.1  christos elfNN_ia64_adjust_dynamic_symbol (struct bfd_link_info *info ATTRIBUTE_UNUSED,
   2979          1.1  christos 				  struct elf_link_hash_entry *h)
   2980          1.1  christos {
   2981  1.1.1.5.4.1  christos   /* ??? Undefined symbols with PLT entries should be re-defined
   2982          1.1  christos      to be the PLT entry.  */
   2983  1.1.1.5.4.1  christos 
   2984  1.1.1.5.4.1  christos   /* If this is a weak symbol, and there is a real definition, the
   2985  1.1.1.5.4.1  christos      processor independent code will have arranged for us to see the
   2986  1.1.1.5.4.1  christos      real definition first, and we can just use the same value.  */
   2987          1.1  christos   if (h->is_weakalias)
   2988          1.1  christos     {
   2989          1.1  christos       struct elf_link_hash_entry *def = weakdef (h);
   2990          1.1  christos       BFD_ASSERT (def->root.type == bfd_link_hash_defined);
   2991          1.1  christos       h->root.u.def.section = def->root.u.def.section;
   2992          1.1  christos       h->root.u.def.value = def->root.u.def.value;
   2993          1.1  christos       return TRUE;
   2994          1.1  christos     }
   2995          1.1  christos 
   2996          1.1  christos   /* If this is a reference to a symbol defined by a dynamic object which
   2997          1.1  christos      is not a function, we might allocate the symbol in our .dynbss section
   2998          1.1  christos      and allocate a COPY dynamic relocation.
   2999          1.1  christos 
   3000          1.1  christos      But IA-64 code is canonically PIC, so as a rule we can avoid this sort
   3001          1.1  christos      of hackery.  */
   3002          1.1  christos 
   3003          1.1  christos   return TRUE;
   3004          1.1  christos }
   3005          1.1  christos 
   3006          1.1  christos static bfd_boolean
   3007          1.1  christos elfNN_ia64_size_dynamic_sections (bfd *output_bfd ATTRIBUTE_UNUSED,
   3008          1.1  christos 				  struct bfd_link_info *info)
   3009          1.1  christos {
   3010          1.1  christos   struct elfNN_ia64_allocate_data data;
   3011          1.1  christos   struct elfNN_ia64_link_hash_table *ia64_info;
   3012          1.1  christos   asection *sec;
   3013      1.1.1.5  christos   bfd *dynobj;
   3014          1.1  christos   bfd_boolean relplt = FALSE;
   3015          1.1  christos 
   3016          1.1  christos   ia64_info = elfNN_ia64_hash_table (info);
   3017          1.1  christos   if (ia64_info == NULL)
   3018          1.1  christos     return FALSE;
   3019          1.1  christos   dynobj = ia64_info->root.dynobj;
   3020      1.1.1.4  christos   ia64_info->self_dtpmod_offset = (bfd_vma) -1;
   3021          1.1  christos   BFD_ASSERT(dynobj != NULL);
   3022          1.1  christos   data.info = info;
   3023          1.1  christos 
   3024          1.1  christos   /* Set the contents of the .interp section to the interpreter.  */
   3025          1.1  christos   if (ia64_info->root.dynamic_sections_created
   3026          1.1  christos       && bfd_link_executable (info) && !info->nointerp)
   3027          1.1  christos     {
   3028          1.1  christos       sec = bfd_get_linker_section (dynobj, ".interp");
   3029          1.1  christos       BFD_ASSERT (sec != NULL);
   3030          1.1  christos       sec->contents = (bfd_byte *) ELF_DYNAMIC_INTERPRETER;
   3031          1.1  christos       sec->size = strlen (ELF_DYNAMIC_INTERPRETER) + 1;
   3032          1.1  christos     }
   3033          1.1  christos 
   3034          1.1  christos   /* Allocate the GOT entries.  */
   3035          1.1  christos 
   3036          1.1  christos   if (ia64_info->root.sgot)
   3037          1.1  christos     {
   3038          1.1  christos       data.ofs = 0;
   3039          1.1  christos       elfNN_ia64_dyn_sym_traverse (ia64_info, allocate_global_data_got, &data);
   3040          1.1  christos       elfNN_ia64_dyn_sym_traverse (ia64_info, allocate_global_fptr_got, &data);
   3041          1.1  christos       elfNN_ia64_dyn_sym_traverse (ia64_info, allocate_local_got, &data);
   3042          1.1  christos       ia64_info->root.sgot->size = data.ofs;
   3043          1.1  christos     }
   3044          1.1  christos 
   3045          1.1  christos   /* Allocate the FPTR entries.  */
   3046          1.1  christos 
   3047          1.1  christos   if (ia64_info->fptr_sec)
   3048          1.1  christos     {
   3049          1.1  christos       data.ofs = 0;
   3050          1.1  christos       elfNN_ia64_dyn_sym_traverse (ia64_info, allocate_fptr, &data);
   3051          1.1  christos       ia64_info->fptr_sec->size = data.ofs;
   3052          1.1  christos     }
   3053          1.1  christos 
   3054          1.1  christos   /* Now that we've seen all of the input files, we can decide which
   3055          1.1  christos      symbols need plt entries.  Allocate the minimal PLT entries first.
   3056          1.1  christos      We do this even though dynamic_sections_created may be FALSE, because
   3057          1.1  christos      this has the side-effect of clearing want_plt and want_plt2.  */
   3058          1.1  christos 
   3059          1.1  christos   data.ofs = 0;
   3060          1.1  christos   elfNN_ia64_dyn_sym_traverse (ia64_info, allocate_plt_entries, &data);
   3061          1.1  christos 
   3062          1.1  christos   ia64_info->minplt_entries = 0;
   3063          1.1  christos   if (data.ofs)
   3064          1.1  christos     {
   3065          1.1  christos       ia64_info->minplt_entries
   3066          1.1  christos 	= (data.ofs - PLT_HEADER_SIZE) / PLT_MIN_ENTRY_SIZE;
   3067          1.1  christos     }
   3068          1.1  christos 
   3069          1.1  christos   /* Align the pointer for the plt2 entries.  */
   3070          1.1  christos   data.ofs = (data.ofs + 31) & (bfd_vma) -32;
   3071          1.1  christos 
   3072          1.1  christos   elfNN_ia64_dyn_sym_traverse (ia64_info, allocate_plt2_entries, &data);
   3073          1.1  christos   if (data.ofs != 0 || ia64_info->root.dynamic_sections_created)
   3074          1.1  christos     {
   3075          1.1  christos       /* FIXME: we always reserve the memory for dynamic linker even if
   3076          1.1  christos 	 there are no PLT entries since dynamic linker may assume the
   3077          1.1  christos 	 reserved memory always exists.  */
   3078          1.1  christos 
   3079      1.1.1.5  christos       BFD_ASSERT (ia64_info->root.dynamic_sections_created);
   3080          1.1  christos 
   3081          1.1  christos       ia64_info->root.splt->size = data.ofs;
   3082          1.1  christos 
   3083          1.1  christos       /* If we've got a .plt, we need some extra memory for the dynamic
   3084          1.1  christos 	 linker.  We stuff these in .got.plt.  */
   3085          1.1  christos       ia64_info->root.sgotplt->size = 8 * PLT_RESERVED_WORDS;
   3086          1.1  christos     }
   3087          1.1  christos 
   3088          1.1  christos   /* Allocate the PLTOFF entries.  */
   3089          1.1  christos 
   3090          1.1  christos   if (ia64_info->pltoff_sec)
   3091          1.1  christos     {
   3092          1.1  christos       data.ofs = 0;
   3093          1.1  christos       elfNN_ia64_dyn_sym_traverse (ia64_info, allocate_pltoff_entries, &data);
   3094          1.1  christos       ia64_info->pltoff_sec->size = data.ofs;
   3095          1.1  christos     }
   3096      1.1.1.4  christos 
   3097          1.1  christos   if (ia64_info->root.dynamic_sections_created)
   3098          1.1  christos     {
   3099          1.1  christos       /* Allocate space for the dynamic relocations that turned out to be
   3100          1.1  christos 	 required.  */
   3101          1.1  christos 
   3102          1.1  christos       if (bfd_link_pic (info) && ia64_info->self_dtpmod_offset != (bfd_vma) -1)
   3103          1.1  christos 	ia64_info->root.srelgot->size += sizeof (ElfNN_External_Rela);
   3104          1.1  christos       data.only_got = FALSE;
   3105          1.1  christos       elfNN_ia64_dyn_sym_traverse (ia64_info, allocate_dynrel_entries, &data);
   3106          1.1  christos     }
   3107          1.1  christos 
   3108          1.1  christos   /* We have now determined the sizes of the various dynamic sections.
   3109          1.1  christos      Allocate memory for them.  */
   3110          1.1  christos   for (sec = dynobj->sections; sec != NULL; sec = sec->next)
   3111          1.1  christos     {
   3112          1.1  christos       bfd_boolean strip;
   3113          1.1  christos 
   3114          1.1  christos       if (!(sec->flags & SEC_LINKER_CREATED))
   3115          1.1  christos 	continue;
   3116          1.1  christos 
   3117          1.1  christos       /* If we don't need this section, strip it from the output file.
   3118          1.1  christos 	 There were several sections primarily related to dynamic
   3119          1.1  christos 	 linking that must be create before the linker maps input
   3120          1.1  christos 	 sections to output sections.  The linker does that before
   3121          1.1  christos 	 bfd_elf_size_dynamic_sections is called, and it is that
   3122          1.1  christos 	 function which decides whether anything needs to go into
   3123          1.1  christos 	 these sections.  */
   3124          1.1  christos 
   3125          1.1  christos       strip = (sec->size == 0);
   3126          1.1  christos 
   3127          1.1  christos       if (sec == ia64_info->root.sgot)
   3128          1.1  christos 	strip = FALSE;
   3129          1.1  christos       else if (sec == ia64_info->root.srelgot)
   3130          1.1  christos 	{
   3131          1.1  christos 	  if (strip)
   3132          1.1  christos 	    ia64_info->root.srelgot = NULL;
   3133          1.1  christos 	  else
   3134          1.1  christos 	    /* We use the reloc_count field as a counter if we need to
   3135          1.1  christos 	       copy relocs into the output file.  */
   3136          1.1  christos 	    sec->reloc_count = 0;
   3137          1.1  christos 	}
   3138          1.1  christos       else if (sec == ia64_info->fptr_sec)
   3139          1.1  christos 	{
   3140          1.1  christos 	  if (strip)
   3141          1.1  christos 	    ia64_info->fptr_sec = NULL;
   3142          1.1  christos 	}
   3143          1.1  christos       else if (sec == ia64_info->rel_fptr_sec)
   3144          1.1  christos 	{
   3145          1.1  christos 	  if (strip)
   3146          1.1  christos 	    ia64_info->rel_fptr_sec = NULL;
   3147          1.1  christos 	  else
   3148          1.1  christos 	    /* We use the reloc_count field as a counter if we need to
   3149          1.1  christos 	       copy relocs into the output file.  */
   3150          1.1  christos 	    sec->reloc_count = 0;
   3151          1.1  christos 	}
   3152          1.1  christos       else if (sec == ia64_info->root.splt)
   3153          1.1  christos 	{
   3154          1.1  christos 	  if (strip)
   3155          1.1  christos 	    ia64_info->root.splt = NULL;
   3156          1.1  christos 	}
   3157          1.1  christos       else if (sec == ia64_info->pltoff_sec)
   3158          1.1  christos 	{
   3159          1.1  christos 	  if (strip)
   3160          1.1  christos 	    ia64_info->pltoff_sec = NULL;
   3161          1.1  christos 	}
   3162          1.1  christos       else if (sec == ia64_info->rel_pltoff_sec)
   3163          1.1  christos 	{
   3164          1.1  christos 	  if (strip)
   3165          1.1  christos 	    ia64_info->rel_pltoff_sec = NULL;
   3166          1.1  christos 	  else
   3167          1.1  christos 	    {
   3168          1.1  christos 	      relplt = TRUE;
   3169          1.1  christos 	      /* We use the reloc_count field as a counter if we need to
   3170          1.1  christos 		 copy relocs into the output file.  */
   3171          1.1  christos 	      sec->reloc_count = 0;
   3172          1.1  christos 	    }
   3173          1.1  christos 	}
   3174          1.1  christos       else
   3175          1.1  christos 	{
   3176          1.1  christos 	  const char *name;
   3177          1.1  christos 
   3178          1.1  christos 	  /* It's OK to base decisions on the section name, because none
   3179          1.1  christos 	     of the dynobj section names depend upon the input files.  */
   3180          1.1  christos 	  name = bfd_get_section_name (dynobj, sec);
   3181          1.1  christos 
   3182          1.1  christos 	  if (strcmp (name, ".got.plt") == 0)
   3183          1.1  christos 	    strip = FALSE;
   3184          1.1  christos 	  else if (CONST_STRNEQ (name, ".rel"))
   3185          1.1  christos 	    {
   3186          1.1  christos 	      if (!strip)
   3187          1.1  christos 		{
   3188          1.1  christos 		  /* We use the reloc_count field as a counter if we need to
   3189          1.1  christos 		     copy relocs into the output file.  */
   3190          1.1  christos 		  sec->reloc_count = 0;
   3191          1.1  christos 		}
   3192          1.1  christos 	    }
   3193          1.1  christos 	  else
   3194          1.1  christos 	    continue;
   3195          1.1  christos 	}
   3196          1.1  christos 
   3197          1.1  christos       if (strip)
   3198          1.1  christos 	sec->flags |= SEC_EXCLUDE;
   3199          1.1  christos       else
   3200          1.1  christos 	{
   3201          1.1  christos 	  /* Allocate memory for the section contents.  */
   3202      1.1.1.5  christos 	  sec->contents = (bfd_byte *) bfd_zalloc (dynobj, sec->size);
   3203          1.1  christos 	  if (sec->contents == NULL && sec->size != 0)
   3204          1.1  christos 	    return FALSE;
   3205          1.1  christos 	}
   3206          1.1  christos     }
   3207          1.1  christos 
   3208      1.1.1.4  christos   if (ia64_info->root.dynamic_sections_created)
   3209          1.1  christos     {
   3210          1.1  christos       /* Add some entries to the .dynamic section.  We fill in the values
   3211          1.1  christos 	 later (in finish_dynamic_sections) but we must add the entries now
   3212          1.1  christos 	 so that we get the correct size for the .dynamic section.  */
   3213          1.1  christos 
   3214          1.1  christos       if (bfd_link_executable (info))
   3215          1.1  christos 	{
   3216          1.1  christos 	  /* The DT_DEBUG entry is filled in by the dynamic linker and used
   3217          1.1  christos 	     by the debugger.  */
   3218          1.1  christos #define add_dynamic_entry(TAG, VAL) \
   3219          1.1  christos   _bfd_elf_add_dynamic_entry (info, TAG, VAL)
   3220          1.1  christos 
   3221          1.1  christos 	  if (!add_dynamic_entry (DT_DEBUG, 0))
   3222          1.1  christos 	    return FALSE;
   3223          1.1  christos 	}
   3224          1.1  christos 
   3225          1.1  christos       if (!add_dynamic_entry (DT_IA_64_PLT_RESERVE, 0))
   3226          1.1  christos 	return FALSE;
   3227          1.1  christos       if (!add_dynamic_entry (DT_PLTGOT, 0))
   3228          1.1  christos 	return FALSE;
   3229          1.1  christos 
   3230          1.1  christos       if (relplt)
   3231          1.1  christos 	{
   3232          1.1  christos 	  if (!add_dynamic_entry (DT_PLTRELSZ, 0)
   3233          1.1  christos 	      || !add_dynamic_entry (DT_PLTREL, DT_RELA)
   3234          1.1  christos 	      || !add_dynamic_entry (DT_JMPREL, 0))
   3235          1.1  christos 	    return FALSE;
   3236          1.1  christos 	}
   3237          1.1  christos 
   3238          1.1  christos       if (!add_dynamic_entry (DT_RELA, 0)
   3239          1.1  christos 	  || !add_dynamic_entry (DT_RELASZ, 0)
   3240          1.1  christos 	  || !add_dynamic_entry (DT_RELAENT, sizeof (ElfNN_External_Rela)))
   3241          1.1  christos 	return FALSE;
   3242          1.1  christos 
   3243          1.1  christos       if (ia64_info->reltext)
   3244          1.1  christos 	{
   3245          1.1  christos 	  if (!add_dynamic_entry (DT_TEXTREL, 0))
   3246          1.1  christos 	    return FALSE;
   3247          1.1  christos 	  info->flags |= DF_TEXTREL;
   3248          1.1  christos 	}
   3249          1.1  christos     }
   3250          1.1  christos 
   3251          1.1  christos   /* ??? Perhaps force __gp local.  */
   3252          1.1  christos 
   3253          1.1  christos   return TRUE;
   3254          1.1  christos }
   3255          1.1  christos 
   3256          1.1  christos static void
   3257          1.1  christos elfNN_ia64_install_dyn_reloc (bfd *abfd, struct bfd_link_info *info,
   3258          1.1  christos 			      asection *sec, asection *srel,
   3259          1.1  christos 			      bfd_vma offset, unsigned int type,
   3260          1.1  christos 			      long dynindx, bfd_vma addend)
   3261          1.1  christos {
   3262          1.1  christos   Elf_Internal_Rela outrel;
   3263          1.1  christos   bfd_byte *loc;
   3264          1.1  christos 
   3265          1.1  christos   BFD_ASSERT (dynindx != -1);
   3266          1.1  christos   outrel.r_info = ELFNN_R_INFO (dynindx, type);
   3267          1.1  christos   outrel.r_addend = addend;
   3268          1.1  christos   outrel.r_offset = _bfd_elf_section_offset (abfd, info, sec, offset);
   3269          1.1  christos   if (outrel.r_offset >= (bfd_vma) -2)
   3270          1.1  christos     {
   3271          1.1  christos       /* Run for the hills.  We shouldn't be outputting a relocation
   3272          1.1  christos 	 for this.  So do what everyone else does and output a no-op.  */
   3273          1.1  christos       outrel.r_info = ELFNN_R_INFO (0, R_IA64_NONE);
   3274          1.1  christos       outrel.r_addend = 0;
   3275          1.1  christos       outrel.r_offset = 0;
   3276          1.1  christos     }
   3277          1.1  christos   else
   3278          1.1  christos     outrel.r_offset += sec->output_section->vma + sec->output_offset;
   3279          1.1  christos 
   3280          1.1  christos   loc = srel->contents;
   3281          1.1  christos   loc += srel->reloc_count++ * sizeof (ElfNN_External_Rela);
   3282          1.1  christos   bfd_elfNN_swap_reloca_out (abfd, &outrel, loc);
   3283          1.1  christos   BFD_ASSERT (sizeof (ElfNN_External_Rela) * srel->reloc_count <= srel->size);
   3284          1.1  christos }
   3285          1.1  christos 
   3286          1.1  christos /* Store an entry for target address TARGET_ADDR in the linkage table
   3287          1.1  christos    and return the gp-relative address of the linkage table entry.  */
   3288          1.1  christos 
   3289          1.1  christos static bfd_vma
   3290          1.1  christos set_got_entry (bfd *abfd, struct bfd_link_info *info,
   3291          1.1  christos 	       struct elfNN_ia64_dyn_sym_info *dyn_i,
   3292          1.1  christos 	       long dynindx, bfd_vma addend, bfd_vma value,
   3293          1.1  christos 	       unsigned int dyn_r_type)
   3294          1.1  christos {
   3295          1.1  christos   struct elfNN_ia64_link_hash_table *ia64_info;
   3296          1.1  christos   asection *got_sec;
   3297          1.1  christos   bfd_boolean done;
   3298          1.1  christos   bfd_vma got_offset;
   3299          1.1  christos 
   3300          1.1  christos   ia64_info = elfNN_ia64_hash_table (info);
   3301          1.1  christos   if (ia64_info == NULL)
   3302          1.1  christos     return 0;
   3303          1.1  christos 
   3304          1.1  christos   got_sec = ia64_info->root.sgot;
   3305          1.1  christos 
   3306          1.1  christos   switch (dyn_r_type)
   3307          1.1  christos     {
   3308          1.1  christos     case R_IA64_TPREL64LSB:
   3309          1.1  christos       done = dyn_i->tprel_done;
   3310          1.1  christos       dyn_i->tprel_done = TRUE;
   3311          1.1  christos       got_offset = dyn_i->tprel_offset;
   3312          1.1  christos       break;
   3313          1.1  christos     case R_IA64_DTPMOD64LSB:
   3314          1.1  christos       if (dyn_i->dtpmod_offset != ia64_info->self_dtpmod_offset)
   3315          1.1  christos 	{
   3316          1.1  christos 	  done = dyn_i->dtpmod_done;
   3317          1.1  christos 	  dyn_i->dtpmod_done = TRUE;
   3318          1.1  christos 	}
   3319          1.1  christos       else
   3320          1.1  christos 	{
   3321          1.1  christos 	  done = ia64_info->self_dtpmod_done;
   3322          1.1  christos 	  ia64_info->self_dtpmod_done = TRUE;
   3323          1.1  christos 	  dynindx = 0;
   3324          1.1  christos 	}
   3325          1.1  christos       got_offset = dyn_i->dtpmod_offset;
   3326          1.1  christos       break;
   3327          1.1  christos     case R_IA64_DTPREL32LSB:
   3328          1.1  christos     case R_IA64_DTPREL64LSB:
   3329          1.1  christos       done = dyn_i->dtprel_done;
   3330          1.1  christos       dyn_i->dtprel_done = TRUE;
   3331          1.1  christos       got_offset = dyn_i->dtprel_offset;
   3332          1.1  christos       break;
   3333          1.1  christos     default:
   3334          1.1  christos       done = dyn_i->got_done;
   3335          1.1  christos       dyn_i->got_done = TRUE;
   3336          1.1  christos       got_offset = dyn_i->got_offset;
   3337          1.1  christos       break;
   3338          1.1  christos     }
   3339          1.1  christos 
   3340          1.1  christos   BFD_ASSERT ((got_offset & 7) == 0);
   3341          1.1  christos 
   3342      1.1.1.4  christos   if (! done)
   3343          1.1  christos     {
   3344  1.1.1.5.4.1  christos       /* Store the target address in the linkage table entry.  */
   3345  1.1.1.5.4.1  christos       bfd_put_64 (abfd, value, got_sec->contents + got_offset);
   3346          1.1  christos 
   3347          1.1  christos       /* Install a dynamic relocation if needed.  */
   3348          1.1  christos       if (((bfd_link_pic (info)
   3349  1.1.1.5.4.1  christos 	    && (!dyn_i->h
   3350          1.1  christos 		|| (ELF_ST_VISIBILITY (dyn_i->h->other) == STV_DEFAULT
   3351          1.1  christos 		    && !UNDEFWEAK_NO_DYNAMIC_RELOC (info, dyn_i->h))
   3352          1.1  christos 		|| dyn_i->h->root.type != bfd_link_hash_undefweak)
   3353          1.1  christos 	    && dyn_r_type != R_IA64_DTPREL32LSB
   3354      1.1.1.4  christos 	    && dyn_r_type != R_IA64_DTPREL64LSB)
   3355          1.1  christos 	   || elfNN_ia64_dynamic_symbol_p (dyn_i->h, info, dyn_r_type)
   3356          1.1  christos 	   || (dynindx != -1
   3357          1.1  christos 	       && (dyn_r_type == R_IA64_FPTR32LSB
   3358          1.1  christos 		   || dyn_r_type == R_IA64_FPTR64LSB)))
   3359          1.1  christos 	  && (!dyn_i->want_ltoff_fptr
   3360          1.1  christos 	      || !bfd_link_pie (info)
   3361          1.1  christos 	      || !dyn_i->h
   3362          1.1  christos 	      || dyn_i->h->root.type != bfd_link_hash_undefweak))
   3363          1.1  christos 	{
   3364          1.1  christos 	  if (dynindx == -1
   3365          1.1  christos 	      && dyn_r_type != R_IA64_TPREL64LSB
   3366          1.1  christos 	      && dyn_r_type != R_IA64_DTPMOD64LSB
   3367          1.1  christos 	      && dyn_r_type != R_IA64_DTPREL32LSB
   3368          1.1  christos 	      && dyn_r_type != R_IA64_DTPREL64LSB)
   3369          1.1  christos 	    {
   3370          1.1  christos 	      dyn_r_type = R_IA64_RELNNLSB;
   3371          1.1  christos 	      dynindx = 0;
   3372          1.1  christos 	      addend = value;
   3373          1.1  christos 	    }
   3374          1.1  christos 
   3375          1.1  christos 	  if (bfd_big_endian (abfd))
   3376          1.1  christos 	    {
   3377          1.1  christos 	      switch (dyn_r_type)
   3378          1.1  christos 		{
   3379          1.1  christos 		case R_IA64_REL32LSB:
   3380          1.1  christos 		  dyn_r_type = R_IA64_REL32MSB;
   3381          1.1  christos 		  break;
   3382          1.1  christos 		case R_IA64_DIR32LSB:
   3383          1.1  christos 		  dyn_r_type = R_IA64_DIR32MSB;
   3384          1.1  christos 		  break;
   3385          1.1  christos 		case R_IA64_FPTR32LSB:
   3386          1.1  christos 		  dyn_r_type = R_IA64_FPTR32MSB;
   3387          1.1  christos 		  break;
   3388          1.1  christos 		case R_IA64_DTPREL32LSB:
   3389          1.1  christos 		  dyn_r_type = R_IA64_DTPREL32MSB;
   3390          1.1  christos 		  break;
   3391          1.1  christos 		case R_IA64_REL64LSB:
   3392          1.1  christos 		  dyn_r_type = R_IA64_REL64MSB;
   3393          1.1  christos 		  break;
   3394          1.1  christos 		case R_IA64_DIR64LSB:
   3395          1.1  christos 		  dyn_r_type = R_IA64_DIR64MSB;
   3396          1.1  christos 		  break;
   3397          1.1  christos 		case R_IA64_FPTR64LSB:
   3398          1.1  christos 		  dyn_r_type = R_IA64_FPTR64MSB;
   3399          1.1  christos 		  break;
   3400          1.1  christos 		case R_IA64_TPREL64LSB:
   3401          1.1  christos 		  dyn_r_type = R_IA64_TPREL64MSB;
   3402          1.1  christos 		  break;
   3403          1.1  christos 		case R_IA64_DTPMOD64LSB:
   3404          1.1  christos 		  dyn_r_type = R_IA64_DTPMOD64MSB;
   3405          1.1  christos 		  break;
   3406          1.1  christos 		case R_IA64_DTPREL64LSB:
   3407          1.1  christos 		  dyn_r_type = R_IA64_DTPREL64MSB;
   3408          1.1  christos 		  break;
   3409          1.1  christos 		default:
   3410          1.1  christos 		  BFD_ASSERT (FALSE);
   3411          1.1  christos 		  break;
   3412          1.1  christos 		}
   3413          1.1  christos 	    }
   3414          1.1  christos 
   3415          1.1  christos 	  elfNN_ia64_install_dyn_reloc (abfd, NULL, got_sec,
   3416          1.1  christos 					ia64_info->root.srelgot,
   3417          1.1  christos 					got_offset, dyn_r_type,
   3418          1.1  christos 					dynindx, addend);
   3419          1.1  christos 	}
   3420          1.1  christos     }
   3421          1.1  christos 
   3422          1.1  christos   /* Return the address of the linkage table entry.  */
   3423          1.1  christos   value = (got_sec->output_section->vma
   3424          1.1  christos 	   + got_sec->output_offset
   3425          1.1  christos 	   + got_offset);
   3426          1.1  christos 
   3427          1.1  christos   return value;
   3428          1.1  christos }
   3429          1.1  christos 
   3430          1.1  christos /* Fill in a function descriptor consisting of the function's code
   3431          1.1  christos    address and its global pointer.  Return the descriptor's address.  */
   3432          1.1  christos 
   3433          1.1  christos static bfd_vma
   3434          1.1  christos set_fptr_entry (bfd *abfd, struct bfd_link_info *info,
   3435          1.1  christos 		struct elfNN_ia64_dyn_sym_info *dyn_i,
   3436          1.1  christos 		bfd_vma value)
   3437          1.1  christos {
   3438          1.1  christos   struct elfNN_ia64_link_hash_table *ia64_info;
   3439          1.1  christos   asection *fptr_sec;
   3440          1.1  christos 
   3441          1.1  christos   ia64_info = elfNN_ia64_hash_table (info);
   3442          1.1  christos   if (ia64_info == NULL)
   3443          1.1  christos     return 0;
   3444          1.1  christos 
   3445          1.1  christos   fptr_sec = ia64_info->fptr_sec;
   3446          1.1  christos 
   3447          1.1  christos   if (!dyn_i->fptr_done)
   3448          1.1  christos     {
   3449          1.1  christos       dyn_i->fptr_done = 1;
   3450          1.1  christos 
   3451          1.1  christos       /* Fill in the function descriptor.  */
   3452          1.1  christos       bfd_put_64 (abfd, value, fptr_sec->contents + dyn_i->fptr_offset);
   3453          1.1  christos       bfd_put_64 (abfd, _bfd_get_gp_value (abfd),
   3454          1.1  christos 		  fptr_sec->contents + dyn_i->fptr_offset + 8);
   3455          1.1  christos       if (ia64_info->rel_fptr_sec)
   3456          1.1  christos 	{
   3457          1.1  christos 	  Elf_Internal_Rela outrel;
   3458          1.1  christos 	  bfd_byte *loc;
   3459          1.1  christos 
   3460          1.1  christos 	  if (bfd_little_endian (abfd))
   3461          1.1  christos 	    outrel.r_info = ELFNN_R_INFO (0, R_IA64_IPLTLSB);
   3462          1.1  christos 	  else
   3463          1.1  christos 	    outrel.r_info = ELFNN_R_INFO (0, R_IA64_IPLTMSB);
   3464          1.1  christos 	  outrel.r_addend = value;
   3465          1.1  christos 	  outrel.r_offset = (fptr_sec->output_section->vma
   3466          1.1  christos 			     + fptr_sec->output_offset
   3467          1.1  christos 			     + dyn_i->fptr_offset);
   3468          1.1  christos 	  loc = ia64_info->rel_fptr_sec->contents;
   3469          1.1  christos 	  loc += ia64_info->rel_fptr_sec->reloc_count++
   3470          1.1  christos 		 * sizeof (ElfNN_External_Rela);
   3471          1.1  christos 	  bfd_elfNN_swap_reloca_out (abfd, &outrel, loc);
   3472          1.1  christos 	}
   3473          1.1  christos     }
   3474          1.1  christos 
   3475          1.1  christos   /* Return the descriptor's address.  */
   3476          1.1  christos   value = (fptr_sec->output_section->vma
   3477          1.1  christos 	   + fptr_sec->output_offset
   3478          1.1  christos 	   + dyn_i->fptr_offset);
   3479          1.1  christos 
   3480          1.1  christos   return value;
   3481          1.1  christos }
   3482          1.1  christos 
   3483          1.1  christos /* Fill in a PLTOFF entry consisting of the function's code address
   3484          1.1  christos    and its global pointer.  Return the descriptor's address.  */
   3485          1.1  christos 
   3486          1.1  christos static bfd_vma
   3487          1.1  christos set_pltoff_entry (bfd *abfd, struct bfd_link_info *info,
   3488          1.1  christos 		  struct elfNN_ia64_dyn_sym_info *dyn_i,
   3489          1.1  christos 		  bfd_vma value, bfd_boolean is_plt)
   3490          1.1  christos {
   3491          1.1  christos   struct elfNN_ia64_link_hash_table *ia64_info;
   3492          1.1  christos   asection *pltoff_sec;
   3493          1.1  christos 
   3494          1.1  christos   ia64_info = elfNN_ia64_hash_table (info);
   3495          1.1  christos   if (ia64_info == NULL)
   3496          1.1  christos     return 0;
   3497          1.1  christos 
   3498          1.1  christos   pltoff_sec = ia64_info->pltoff_sec;
   3499          1.1  christos 
   3500          1.1  christos   /* Don't do anything if this symbol uses a real PLT entry.  In
   3501          1.1  christos      that case, we'll fill this in during finish_dynamic_symbol.  */
   3502          1.1  christos   if ((! dyn_i->want_plt || is_plt)
   3503          1.1  christos       && !dyn_i->pltoff_done)
   3504          1.1  christos     {
   3505          1.1  christos       bfd_vma gp = _bfd_get_gp_value (abfd);
   3506          1.1  christos 
   3507      1.1.1.4  christos       /* Fill in the function descriptor.  */
   3508          1.1  christos       bfd_put_64 (abfd, value, pltoff_sec->contents + dyn_i->pltoff_offset);
   3509  1.1.1.5.4.1  christos       bfd_put_64 (abfd, gp, pltoff_sec->contents + dyn_i->pltoff_offset + 8);
   3510  1.1.1.5.4.1  christos 
   3511          1.1  christos       /* Install dynamic relocations if needed.  */
   3512          1.1  christos       if (!is_plt
   3513          1.1  christos 	  && bfd_link_pic (info)
   3514          1.1  christos 	  && (!dyn_i->h
   3515          1.1  christos 	      || (ELF_ST_VISIBILITY (dyn_i->h->other) == STV_DEFAULT
   3516          1.1  christos 		  && !UNDEFWEAK_NO_DYNAMIC_RELOC (info, dyn_i->h))
   3517          1.1  christos 	      || dyn_i->h->root.type != bfd_link_hash_undefweak))
   3518          1.1  christos 	{
   3519          1.1  christos 	  unsigned int dyn_r_type;
   3520          1.1  christos 
   3521          1.1  christos 	  if (bfd_big_endian (abfd))
   3522          1.1  christos 	    dyn_r_type = R_IA64_RELNNMSB;
   3523          1.1  christos 	  else
   3524          1.1  christos 	    dyn_r_type = R_IA64_RELNNLSB;
   3525          1.1  christos 
   3526          1.1  christos 	  elfNN_ia64_install_dyn_reloc (abfd, NULL, pltoff_sec,
   3527          1.1  christos 					ia64_info->rel_pltoff_sec,
   3528          1.1  christos 					dyn_i->pltoff_offset,
   3529          1.1  christos 					dyn_r_type, 0, value);
   3530          1.1  christos 	  elfNN_ia64_install_dyn_reloc (abfd, NULL, pltoff_sec,
   3531          1.1  christos 					ia64_info->rel_pltoff_sec,
   3532          1.1  christos 					dyn_i->pltoff_offset + ARCH_SIZE / 8,
   3533          1.1  christos 					dyn_r_type, 0, gp);
   3534          1.1  christos 	}
   3535          1.1  christos 
   3536          1.1  christos       dyn_i->pltoff_done = 1;
   3537          1.1  christos     }
   3538          1.1  christos 
   3539          1.1  christos   /* Return the descriptor's address.  */
   3540          1.1  christos   value = (pltoff_sec->output_section->vma
   3541          1.1  christos 	   + pltoff_sec->output_offset
   3542          1.1  christos 	   + dyn_i->pltoff_offset);
   3543          1.1  christos 
   3544          1.1  christos   return value;
   3545          1.1  christos }
   3546          1.1  christos 
   3547          1.1  christos /* Return the base VMA address which should be subtracted from real addresses
   3548          1.1  christos    when resolving @tprel() relocation.
   3549          1.1  christos    Main program TLS (whose template starts at PT_TLS p_vaddr)
   3550          1.1  christos    is assigned offset round(2 * size of pointer, PT_TLS p_align).  */
   3551          1.1  christos 
   3552          1.1  christos static bfd_vma
   3553          1.1  christos elfNN_ia64_tprel_base (struct bfd_link_info *info)
   3554          1.1  christos {
   3555          1.1  christos   asection *tls_sec = elf_hash_table (info)->tls_sec;
   3556          1.1  christos   return tls_sec->vma - align_power ((bfd_vma) ARCH_SIZE / 4,
   3557          1.1  christos 				     tls_sec->alignment_power);
   3558          1.1  christos }
   3559          1.1  christos 
   3560          1.1  christos /* Return the base VMA address which should be subtracted from real addresses
   3561          1.1  christos    when resolving @dtprel() relocation.
   3562          1.1  christos    This is PT_TLS segment p_vaddr.  */
   3563          1.1  christos 
   3564          1.1  christos static bfd_vma
   3565          1.1  christos elfNN_ia64_dtprel_base (struct bfd_link_info *info)
   3566          1.1  christos {
   3567          1.1  christos   return elf_hash_table (info)->tls_sec->vma;
   3568          1.1  christos }
   3569          1.1  christos 
   3570          1.1  christos /* Called through qsort to sort the .IA_64.unwind section during a
   3571          1.1  christos    non-relocatable link.  Set elfNN_ia64_unwind_entry_compare_bfd
   3572          1.1  christos    to the output bfd so we can do proper endianness frobbing.  */
   3573          1.1  christos 
   3574          1.1  christos static bfd *elfNN_ia64_unwind_entry_compare_bfd;
   3575          1.1  christos 
   3576          1.1  christos static int
   3577          1.1  christos elfNN_ia64_unwind_entry_compare (const void * a, const void * b)
   3578          1.1  christos {
   3579          1.1  christos   bfd_vma av, bv;
   3580          1.1  christos 
   3581          1.1  christos   av = bfd_get_64 (elfNN_ia64_unwind_entry_compare_bfd, a);
   3582          1.1  christos   bv = bfd_get_64 (elfNN_ia64_unwind_entry_compare_bfd, b);
   3583          1.1  christos 
   3584          1.1  christos   return (av < bv ? -1 : av > bv ? 1 : 0);
   3585          1.1  christos }
   3586          1.1  christos 
   3587          1.1  christos /* Make sure we've got ourselves a nice fat __gp value.  */
   3588          1.1  christos static bfd_boolean
   3589          1.1  christos elfNN_ia64_choose_gp (bfd *abfd, struct bfd_link_info *info, bfd_boolean final)
   3590          1.1  christos {
   3591          1.1  christos   bfd_vma min_vma = (bfd_vma) -1, max_vma = 0;
   3592          1.1  christos   bfd_vma min_short_vma = min_vma, max_short_vma = 0;
   3593          1.1  christos   struct elf_link_hash_entry *gp;
   3594          1.1  christos   bfd_vma gp_val;
   3595          1.1  christos   asection *os;
   3596          1.1  christos   struct elfNN_ia64_link_hash_table *ia64_info;
   3597          1.1  christos 
   3598          1.1  christos   ia64_info = elfNN_ia64_hash_table (info);
   3599          1.1  christos   if (ia64_info == NULL)
   3600          1.1  christos     return FALSE;
   3601          1.1  christos 
   3602          1.1  christos   /* Find the min and max vma of all sections marked short.  Also collect
   3603          1.1  christos      min and max vma of any type, for use in selecting a nice gp.  */
   3604          1.1  christos   for (os = abfd->sections; os ; os = os->next)
   3605          1.1  christos     {
   3606          1.1  christos       bfd_vma lo, hi;
   3607          1.1  christos 
   3608          1.1  christos       if ((os->flags & SEC_ALLOC) == 0)
   3609          1.1  christos 	continue;
   3610          1.1  christos 
   3611          1.1  christos       lo = os->vma;
   3612          1.1  christos       /* When this function is called from elfNN_ia64_final_link
   3613          1.1  christos 	 the correct value to use is os->size.  When called from
   3614          1.1  christos 	 elfNN_ia64_relax_section we are in the middle of section
   3615          1.1  christos 	 sizing; some sections will already have os->size set, others
   3616          1.1  christos 	 will have os->size zero and os->rawsize the previous size.  */
   3617          1.1  christos       hi = os->vma + (!final && os->rawsize ? os->rawsize : os->size);
   3618          1.1  christos       if (hi < lo)
   3619          1.1  christos 	hi = (bfd_vma) -1;
   3620          1.1  christos 
   3621          1.1  christos       if (min_vma > lo)
   3622          1.1  christos 	min_vma = lo;
   3623          1.1  christos       if (max_vma < hi)
   3624          1.1  christos 	max_vma = hi;
   3625          1.1  christos       if (os->flags & SEC_SMALL_DATA)
   3626          1.1  christos 	{
   3627          1.1  christos 	  if (min_short_vma > lo)
   3628          1.1  christos 	    min_short_vma = lo;
   3629          1.1  christos 	  if (max_short_vma < hi)
   3630          1.1  christos 	    max_short_vma = hi;
   3631          1.1  christos 	}
   3632          1.1  christos     }
   3633          1.1  christos 
   3634          1.1  christos   if (ia64_info->min_short_sec)
   3635          1.1  christos     {
   3636          1.1  christos       if (min_short_vma
   3637          1.1  christos 	  > (ia64_info->min_short_sec->vma
   3638          1.1  christos 	     + ia64_info->min_short_offset))
   3639          1.1  christos 	min_short_vma = (ia64_info->min_short_sec->vma
   3640          1.1  christos 			 + ia64_info->min_short_offset);
   3641          1.1  christos       if (max_short_vma
   3642          1.1  christos 	  < (ia64_info->max_short_sec->vma
   3643          1.1  christos 	     + ia64_info->max_short_offset))
   3644          1.1  christos 	max_short_vma = (ia64_info->max_short_sec->vma
   3645          1.1  christos 			 + ia64_info->max_short_offset);
   3646          1.1  christos     }
   3647          1.1  christos 
   3648          1.1  christos   /* See if the user wants to force a value.  */
   3649          1.1  christos   gp = elf_link_hash_lookup (elf_hash_table (info), "__gp", FALSE,
   3650          1.1  christos 			     FALSE, FALSE);
   3651          1.1  christos 
   3652          1.1  christos   if (gp
   3653          1.1  christos       && (gp->root.type == bfd_link_hash_defined
   3654          1.1  christos 	  || gp->root.type == bfd_link_hash_defweak))
   3655          1.1  christos     {
   3656          1.1  christos       asection *gp_sec = gp->root.u.def.section;
   3657          1.1  christos       gp_val = (gp->root.u.def.value
   3658          1.1  christos 		+ gp_sec->output_section->vma
   3659          1.1  christos 		+ gp_sec->output_offset);
   3660          1.1  christos     }
   3661          1.1  christos   else
   3662          1.1  christos     {
   3663          1.1  christos       /* Pick a sensible value.  */
   3664          1.1  christos 
   3665          1.1  christos       if (ia64_info->min_short_sec)
   3666          1.1  christos 	{
   3667          1.1  christos 	  bfd_vma short_range = max_short_vma - min_short_vma;
   3668          1.1  christos 
   3669          1.1  christos 	  /* If min_short_sec is set, pick one in the middle bewteen
   3670          1.1  christos 	     min_short_vma and max_short_vma.  */
   3671          1.1  christos 	  if (short_range >= 0x400000)
   3672          1.1  christos 	    goto overflow;
   3673          1.1  christos 	  gp_val = min_short_vma + short_range / 2;
   3674          1.1  christos 	}
   3675          1.1  christos       else
   3676          1.1  christos 	{
   3677          1.1  christos 	  asection *got_sec = ia64_info->root.sgot;
   3678          1.1  christos 
   3679          1.1  christos 	  /* Start with just the address of the .got.  */
   3680          1.1  christos 	  if (got_sec)
   3681          1.1  christos 	    gp_val = got_sec->output_section->vma;
   3682          1.1  christos 	  else if (max_short_vma != 0)
   3683          1.1  christos 	    gp_val = min_short_vma;
   3684          1.1  christos 	  else if (max_vma - min_vma < 0x200000)
   3685          1.1  christos 	    gp_val = min_vma;
   3686          1.1  christos 	  else
   3687          1.1  christos 	    gp_val = max_vma - 0x200000 + 8;
   3688          1.1  christos 	}
   3689          1.1  christos 
   3690          1.1  christos       /* If it is possible to address the entire image, but we
   3691          1.1  christos 	 don't with the choice above, adjust.  */
   3692          1.1  christos       if (max_vma - min_vma < 0x400000
   3693          1.1  christos 	  && (max_vma - gp_val >= 0x200000
   3694          1.1  christos 	      || gp_val - min_vma > 0x200000))
   3695          1.1  christos 	gp_val = min_vma + 0x200000;
   3696          1.1  christos       else if (max_short_vma != 0)
   3697          1.1  christos 	{
   3698          1.1  christos 	  /* If we don't cover all the short data, adjust.  */
   3699          1.1  christos 	  if (max_short_vma - gp_val >= 0x200000)
   3700          1.1  christos 	    gp_val = min_short_vma + 0x200000;
   3701          1.1  christos 
   3702          1.1  christos 	  /* If we're addressing stuff past the end, adjust back.  */
   3703          1.1  christos 	  if (gp_val > max_vma)
   3704          1.1  christos 	    gp_val = max_vma - 0x200000 + 8;
   3705          1.1  christos 	}
   3706          1.1  christos     }
   3707          1.1  christos 
   3708          1.1  christos   /* Validate whether all SHF_IA_64_SHORT sections are within
   3709          1.1  christos      range of the chosen GP.  */
   3710      1.1.1.5  christos 
   3711      1.1.1.5  christos   if (max_short_vma != 0)
   3712  1.1.1.5.4.1  christos     {
   3713  1.1.1.5.4.1  christos       if (max_short_vma - min_short_vma >= 0x400000)
   3714          1.1  christos 	{
   3715          1.1  christos overflow:
   3716          1.1  christos 	  _bfd_error_handler
   3717          1.1  christos 	    /* xgettext:c-format */
   3718          1.1  christos 	    (_("%pB: short data segment overflowed (%#" PRIx64 " >= 0x400000)"),
   3719          1.1  christos 	     abfd, (uint64_t) (max_short_vma - min_short_vma));
   3720          1.1  christos 	  return FALSE;
   3721      1.1.1.5  christos 	}
   3722  1.1.1.5.4.1  christos       else if ((gp_val > min_short_vma
   3723          1.1  christos 		&& gp_val - min_short_vma > 0x200000)
   3724          1.1  christos 	       || (gp_val < max_short_vma
   3725          1.1  christos 		   && max_short_vma - gp_val >= 0x200000))
   3726          1.1  christos 	{
   3727          1.1  christos 	  _bfd_error_handler
   3728          1.1  christos 	    (_("%pB: __gp does not cover short data segment"), abfd);
   3729          1.1  christos 	  return FALSE;
   3730          1.1  christos 	}
   3731          1.1  christos     }
   3732          1.1  christos 
   3733          1.1  christos   _bfd_set_gp_value (abfd, gp_val);
   3734          1.1  christos 
   3735          1.1  christos   return TRUE;
   3736          1.1  christos }
   3737          1.1  christos 
   3738          1.1  christos static bfd_boolean
   3739          1.1  christos elfNN_ia64_final_link (bfd *abfd, struct bfd_link_info *info)
   3740          1.1  christos {
   3741          1.1  christos   struct elfNN_ia64_link_hash_table *ia64_info;
   3742          1.1  christos   asection *unwind_output_sec;
   3743      1.1.1.4  christos 
   3744          1.1  christos   ia64_info = elfNN_ia64_hash_table (info);
   3745          1.1  christos   if (ia64_info == NULL)
   3746          1.1  christos     return FALSE;
   3747          1.1  christos 
   3748          1.1  christos   /* Make sure we've got ourselves a nice fat __gp value.  */
   3749          1.1  christos   if (!bfd_link_relocatable (info))
   3750          1.1  christos     {
   3751          1.1  christos       bfd_vma gp_val;
   3752          1.1  christos       struct elf_link_hash_entry *gp;
   3753          1.1  christos 
   3754          1.1  christos       /* We assume after gp is set, section size will only decrease. We
   3755          1.1  christos 	 need to adjust gp for it.  */
   3756  1.1.1.5.4.1  christos       _bfd_set_gp_value (abfd, 0);
   3757          1.1  christos       if (! elfNN_ia64_choose_gp (abfd, info, TRUE))
   3758          1.1  christos 	return FALSE;
   3759          1.1  christos       gp_val = _bfd_get_gp_value (abfd);
   3760          1.1  christos 
   3761          1.1  christos       gp = elf_link_hash_lookup (elf_hash_table (info), "__gp", FALSE,
   3762          1.1  christos 				 FALSE, FALSE);
   3763          1.1  christos       if (gp)
   3764          1.1  christos 	{
   3765          1.1  christos 	  gp->root.type = bfd_link_hash_defined;
   3766          1.1  christos 	  gp->root.u.def.value = gp_val;
   3767          1.1  christos 	  gp->root.u.def.section = bfd_abs_section_ptr;
   3768          1.1  christos 	}
   3769      1.1.1.4  christos     }
   3770          1.1  christos 
   3771          1.1  christos   /* If we're producing a final executable, we need to sort the contents
   3772          1.1  christos      of the .IA_64.unwind section.  Force this section to be relocated
   3773          1.1  christos      into memory rather than written immediately to the output file.  */
   3774          1.1  christos   unwind_output_sec = NULL;
   3775          1.1  christos   if (!bfd_link_relocatable (info))
   3776          1.1  christos     {
   3777          1.1  christos       asection *s = bfd_get_section_by_name (abfd, ELF_STRING_ia64_unwind);
   3778          1.1  christos       if (s)
   3779          1.1  christos 	{
   3780          1.1  christos 	  unwind_output_sec = s->output_section;
   3781          1.1  christos 	  unwind_output_sec->contents
   3782          1.1  christos 	    = bfd_malloc (unwind_output_sec->size);
   3783          1.1  christos 	  if (unwind_output_sec->contents == NULL)
   3784          1.1  christos 	    return FALSE;
   3785          1.1  christos 	}
   3786          1.1  christos     }
   3787          1.1  christos 
   3788          1.1  christos   /* Invoke the regular ELF backend linker to do all the work.  */
   3789          1.1  christos   if (!bfd_elf_final_link (abfd, info))
   3790          1.1  christos     return FALSE;
   3791          1.1  christos 
   3792          1.1  christos   if (unwind_output_sec)
   3793          1.1  christos     {
   3794          1.1  christos       elfNN_ia64_unwind_entry_compare_bfd = abfd;
   3795          1.1  christos       qsort (unwind_output_sec->contents,
   3796          1.1  christos 	     (size_t) (unwind_output_sec->size / 24),
   3797          1.1  christos 	     24,
   3798          1.1  christos 	     elfNN_ia64_unwind_entry_compare);
   3799          1.1  christos 
   3800          1.1  christos       if (! bfd_set_section_contents (abfd, unwind_output_sec,
   3801          1.1  christos 				      unwind_output_sec->contents, (bfd_vma) 0,
   3802          1.1  christos 				      unwind_output_sec->size))
   3803          1.1  christos 	return FALSE;
   3804          1.1  christos     }
   3805          1.1  christos 
   3806          1.1  christos   return TRUE;
   3807          1.1  christos }
   3808          1.1  christos 
   3809          1.1  christos static bfd_boolean
   3810          1.1  christos elfNN_ia64_relocate_section (bfd *output_bfd,
   3811          1.1  christos 			     struct bfd_link_info *info,
   3812          1.1  christos 			     bfd *input_bfd,
   3813          1.1  christos 			     asection *input_section,
   3814          1.1  christos 			     bfd_byte *contents,
   3815          1.1  christos 			     Elf_Internal_Rela *relocs,
   3816          1.1  christos 			     Elf_Internal_Sym *local_syms,
   3817          1.1  christos 			     asection **local_sections)
   3818          1.1  christos {
   3819          1.1  christos   struct elfNN_ia64_link_hash_table *ia64_info;
   3820          1.1  christos   Elf_Internal_Shdr *symtab_hdr;
   3821          1.1  christos   Elf_Internal_Rela *rel;
   3822          1.1  christos   Elf_Internal_Rela *relend;
   3823          1.1  christos   asection *srel;
   3824          1.1  christos   bfd_boolean ret_val = TRUE;	/* for non-fatal errors */
   3825          1.1  christos   bfd_vma gp_val;
   3826          1.1  christos 
   3827      1.1.1.4  christos   symtab_hdr = &elf_tdata (input_bfd)->symtab_hdr;
   3828          1.1  christos   ia64_info = elfNN_ia64_hash_table (info);
   3829          1.1  christos   if (ia64_info == NULL)
   3830          1.1  christos     return FALSE;
   3831          1.1  christos 
   3832          1.1  christos   /* Infect various flags from the input section to the output section.  */
   3833          1.1  christos   if (bfd_link_relocatable (info))
   3834          1.1  christos     {
   3835          1.1  christos       bfd_vma flags;
   3836          1.1  christos 
   3837          1.1  christos       flags = elf_section_data(input_section)->this_hdr.sh_flags;
   3838          1.1  christos       flags &= SHF_IA_64_NORECOV;
   3839          1.1  christos 
   3840          1.1  christos       elf_section_data(input_section->output_section)
   3841          1.1  christos 	->this_hdr.sh_flags |= flags;
   3842          1.1  christos     }
   3843          1.1  christos 
   3844          1.1  christos   gp_val = _bfd_get_gp_value (output_bfd);
   3845          1.1  christos   srel = get_reloc_section (input_bfd, ia64_info, input_section, FALSE);
   3846          1.1  christos 
   3847          1.1  christos   rel = relocs;
   3848          1.1  christos   relend = relocs + input_section->reloc_count;
   3849          1.1  christos   for (; rel < relend; ++rel)
   3850          1.1  christos     {
   3851          1.1  christos       struct elf_link_hash_entry *h;
   3852          1.1  christos       struct elfNN_ia64_dyn_sym_info *dyn_i;
   3853          1.1  christos       bfd_reloc_status_type r;
   3854          1.1  christos       reloc_howto_type *howto;
   3855          1.1  christos       unsigned long r_symndx;
   3856          1.1  christos       Elf_Internal_Sym *sym;
   3857          1.1  christos       unsigned int r_type;
   3858          1.1  christos       bfd_vma value;
   3859          1.1  christos       asection *sym_sec;
   3860          1.1  christos       bfd_byte *hit_addr;
   3861  1.1.1.5.4.1  christos       bfd_boolean dynamic_symbol_p;
   3862  1.1.1.5.4.1  christos       bfd_boolean undef_weak_ref;
   3863  1.1.1.5.4.1  christos 
   3864          1.1  christos       r_type = ELFNN_R_TYPE (rel->r_info);
   3865          1.1  christos       if (r_type > R_IA64_MAX_RELOC_CODE)
   3866          1.1  christos 	{
   3867          1.1  christos 	  /* xgettext:c-format */
   3868          1.1  christos 	  _bfd_error_handler (_("%pB: unsupported relocation type %#x"),
   3869          1.1  christos 			      input_bfd, (int) r_type);
   3870  1.1.1.5.4.1  christos 	  bfd_set_error (bfd_error_bad_value);
   3871  1.1.1.5.4.1  christos 	  ret_val = FALSE;
   3872  1.1.1.5.4.1  christos 	  continue;
   3873  1.1.1.5.4.1  christos 	}
   3874  1.1.1.5.4.1  christos 
   3875  1.1.1.5.4.1  christos       howto = ia64_elf_lookup_howto (r_type);
   3876          1.1  christos       if (howto == NULL)
   3877          1.1  christos 	{
   3878          1.1  christos 	  ret_val = FALSE;
   3879          1.1  christos 	  continue;
   3880          1.1  christos 	}
   3881          1.1  christos 
   3882          1.1  christos       r_symndx = ELFNN_R_SYM (rel->r_info);
   3883          1.1  christos       h = NULL;
   3884          1.1  christos       sym = NULL;
   3885          1.1  christos       sym_sec = NULL;
   3886          1.1  christos       undef_weak_ref = FALSE;
   3887          1.1  christos 
   3888          1.1  christos       if (r_symndx < symtab_hdr->sh_info)
   3889          1.1  christos 	{
   3890      1.1.1.4  christos 	  /* Reloc against local symbol.  */
   3891          1.1  christos 	  asection *msec;
   3892          1.1  christos 	  sym = local_syms + r_symndx;
   3893          1.1  christos 	  sym_sec = local_sections[r_symndx];
   3894          1.1  christos 	  msec = sym_sec;
   3895          1.1  christos 	  value = _bfd_elf_rela_local_sym (output_bfd, sym, &msec, rel);
   3896          1.1  christos 	  if (!bfd_link_relocatable (info)
   3897          1.1  christos 	      && (sym_sec->flags & SEC_MERGE) != 0
   3898          1.1  christos 	      && ELF_ST_TYPE (sym->st_info) == STT_SECTION
   3899          1.1  christos 	      && sym_sec->sec_info_type == SEC_INFO_TYPE_MERGE)
   3900          1.1  christos 	    {
   3901          1.1  christos 	      struct elfNN_ia64_local_hash_entry *loc_h;
   3902          1.1  christos 
   3903          1.1  christos 	      loc_h = get_local_sym_hash (ia64_info, input_bfd, rel, FALSE);
   3904          1.1  christos 	      if (loc_h && ! loc_h->sec_merge_done)
   3905          1.1  christos 		{
   3906          1.1  christos 		  struct elfNN_ia64_dyn_sym_info *dynent;
   3907          1.1  christos 		  unsigned int count;
   3908          1.1  christos 
   3909          1.1  christos 		  for (count = loc_h->count, dynent = loc_h->info;
   3910          1.1  christos 		       count != 0;
   3911          1.1  christos 		       count--, dynent++)
   3912          1.1  christos 		    {
   3913          1.1  christos 		      msec = sym_sec;
   3914          1.1  christos 		      dynent->addend =
   3915          1.1  christos 			_bfd_merged_section_offset (output_bfd, &msec,
   3916          1.1  christos 						    elf_section_data (msec)->
   3917          1.1  christos 						    sec_info,
   3918          1.1  christos 						    sym->st_value
   3919          1.1  christos 						    + dynent->addend);
   3920          1.1  christos 		      dynent->addend -= sym->st_value;
   3921          1.1  christos 		      dynent->addend += msec->output_section->vma
   3922          1.1  christos 					+ msec->output_offset
   3923          1.1  christos 					- sym_sec->output_section->vma
   3924          1.1  christos 					- sym_sec->output_offset;
   3925          1.1  christos 		    }
   3926          1.1  christos 
   3927          1.1  christos 		  /* We may have introduced duplicated entries. We need
   3928          1.1  christos 		     to remove them properly.  */
   3929          1.1  christos 		  count = sort_dyn_sym_info (loc_h->info, loc_h->count);
   3930          1.1  christos 		  if (count != loc_h->count)
   3931          1.1  christos 		    {
   3932          1.1  christos 		      loc_h->count = count;
   3933          1.1  christos 		      loc_h->sorted_count = count;
   3934          1.1  christos 		    }
   3935          1.1  christos 
   3936          1.1  christos 		  loc_h->sec_merge_done = 1;
   3937      1.1.1.2  christos 		}
   3938          1.1  christos 	    }
   3939          1.1  christos 	}
   3940          1.1  christos       else
   3941          1.1  christos 	{
   3942          1.1  christos 	  bfd_boolean unresolved_reloc;
   3943      1.1.1.2  christos 	  bfd_boolean warned, ignored;
   3944          1.1  christos 	  struct elf_link_hash_entry **sym_hashes = elf_sym_hashes (input_bfd);
   3945          1.1  christos 
   3946          1.1  christos 	  RELOC_FOR_GLOBAL_SYMBOL (info, input_bfd, input_section, rel,
   3947      1.1.1.4  christos 				   r_symndx, symtab_hdr, sym_hashes,
   3948          1.1  christos 				   h, sym_sec, value,
   3949          1.1  christos 				   unresolved_reloc, warned, ignored);
   3950          1.1  christos 
   3951          1.1  christos 	  if (h->root.type == bfd_link_hash_undefweak)
   3952          1.1  christos 	    undef_weak_ref = TRUE;
   3953          1.1  christos 	  else if (warned || (ignored && bfd_link_executable (info)))
   3954          1.1  christos 	    continue;
   3955      1.1.1.4  christos 	}
   3956          1.1  christos 
   3957          1.1  christos       if (sym_sec != NULL && discarded_section (sym_sec))
   3958          1.1  christos 	RELOC_AGAINST_DISCARDED_SECTION (info, input_bfd, input_section,
   3959          1.1  christos 					 rel, 1, relend, howto, 0, contents);
   3960          1.1  christos 
   3961          1.1  christos       if (bfd_link_relocatable (info))
   3962          1.1  christos 	continue;
   3963          1.1  christos 
   3964          1.1  christos       hit_addr = contents + rel->r_offset;
   3965          1.1  christos       value += rel->r_addend;
   3966          1.1  christos       dynamic_symbol_p = elfNN_ia64_dynamic_symbol_p (h, info, r_type);
   3967          1.1  christos 
   3968          1.1  christos       switch (r_type)
   3969          1.1  christos 	{
   3970          1.1  christos 	case R_IA64_NONE:
   3971          1.1  christos 	case R_IA64_LDXMOV:
   3972          1.1  christos 	  continue;
   3973          1.1  christos 
   3974          1.1  christos 	case R_IA64_IMM14:
   3975          1.1  christos 	case R_IA64_IMM22:
   3976      1.1.1.4  christos 	case R_IA64_IMM64:
   3977  1.1.1.5.4.1  christos 	case R_IA64_DIR32MSB:
   3978          1.1  christos 	case R_IA64_DIR32LSB:
   3979          1.1  christos 	case R_IA64_DIR64MSB:
   3980          1.1  christos 	case R_IA64_DIR64LSB:
   3981          1.1  christos 	  /* Install a dynamic relocation for this reloc.  */
   3982          1.1  christos 	  if ((dynamic_symbol_p || bfd_link_pic (info))
   3983          1.1  christos 	      && !(h && UNDEFWEAK_NO_DYNAMIC_RELOC (info, h))
   3984          1.1  christos 	      && r_symndx != STN_UNDEF
   3985          1.1  christos 	      && (input_section->flags & SEC_ALLOC) != 0)
   3986          1.1  christos 	    {
   3987          1.1  christos 	      unsigned int dyn_r_type;
   3988          1.1  christos 	      long dynindx;
   3989          1.1  christos 	      bfd_vma addend;
   3990          1.1  christos 
   3991          1.1  christos 	      BFD_ASSERT (srel != NULL);
   3992          1.1  christos 
   3993          1.1  christos 	      switch (r_type)
   3994      1.1.1.5  christos 		{
   3995      1.1.1.5  christos 		case R_IA64_IMM14:
   3996  1.1.1.5.4.1  christos 		case R_IA64_IMM22:
   3997          1.1  christos 		case R_IA64_IMM64:
   3998          1.1  christos 		  /* ??? People shouldn't be doing non-pic code in
   3999          1.1  christos 		     shared libraries nor dynamic executables.  */
   4000          1.1  christos 		  _bfd_error_handler
   4001          1.1  christos 		    /* xgettext:c-format */
   4002          1.1  christos 		    (_("%pB: non-pic code with imm relocation against dynamic symbol `%s'"),
   4003          1.1  christos 		     input_bfd,
   4004          1.1  christos 		     h ? h->root.root.string
   4005          1.1  christos 		       : bfd_elf_sym_name (input_bfd, symtab_hdr, sym,
   4006          1.1  christos 					   sym_sec));
   4007          1.1  christos 		  ret_val = FALSE;
   4008          1.1  christos 		  continue;
   4009          1.1  christos 
   4010          1.1  christos 		default:
   4011          1.1  christos 		  break;
   4012          1.1  christos 		}
   4013          1.1  christos 
   4014          1.1  christos 	      /* If we don't need dynamic symbol lookup, find a
   4015          1.1  christos 		 matching RELATIVE relocation.  */
   4016          1.1  christos 	      dyn_r_type = r_type;
   4017          1.1  christos 	      if (dynamic_symbol_p)
   4018          1.1  christos 		{
   4019          1.1  christos 		  dynindx = h->dynindx;
   4020          1.1  christos 		  addend = rel->r_addend;
   4021          1.1  christos 		  value = 0;
   4022          1.1  christos 		}
   4023          1.1  christos 	      else
   4024          1.1  christos 		{
   4025          1.1  christos 		  switch (r_type)
   4026          1.1  christos 		    {
   4027          1.1  christos 		    case R_IA64_DIR32MSB:
   4028          1.1  christos 		      dyn_r_type = R_IA64_REL32MSB;
   4029          1.1  christos 		      break;
   4030          1.1  christos 		    case R_IA64_DIR32LSB:
   4031          1.1  christos 		      dyn_r_type = R_IA64_REL32LSB;
   4032          1.1  christos 		      break;
   4033          1.1  christos 		    case R_IA64_DIR64MSB:
   4034          1.1  christos 		      dyn_r_type = R_IA64_REL64MSB;
   4035          1.1  christos 		      break;
   4036          1.1  christos 		    case R_IA64_DIR64LSB:
   4037          1.1  christos 		      dyn_r_type = R_IA64_REL64LSB;
   4038          1.1  christos 		      break;
   4039          1.1  christos 
   4040          1.1  christos 		    default:
   4041          1.1  christos 		      break;
   4042          1.1  christos 		    }
   4043          1.1  christos 		  dynindx = 0;
   4044          1.1  christos 		  addend = value;
   4045          1.1  christos 		}
   4046          1.1  christos 
   4047          1.1  christos 	      elfNN_ia64_install_dyn_reloc (output_bfd, info, input_section,
   4048          1.1  christos 					    srel, rel->r_offset, dyn_r_type,
   4049          1.1  christos 					    dynindx, addend);
   4050          1.1  christos 	    }
   4051          1.1  christos 	  /* Fall through.  */
   4052          1.1  christos 
   4053          1.1  christos 	case R_IA64_LTV32MSB:
   4054          1.1  christos 	case R_IA64_LTV32LSB:
   4055          1.1  christos 	case R_IA64_LTV64MSB:
   4056          1.1  christos 	case R_IA64_LTV64LSB:
   4057          1.1  christos 	  r = ia64_elf_install_value (hit_addr, value, r_type);
   4058          1.1  christos 	  break;
   4059          1.1  christos 
   4060          1.1  christos 	case R_IA64_GPREL22:
   4061          1.1  christos 	case R_IA64_GPREL64I:
   4062      1.1.1.5  christos 	case R_IA64_GPREL32MSB:
   4063      1.1.1.5  christos 	case R_IA64_GPREL32LSB:
   4064  1.1.1.5.4.1  christos 	case R_IA64_GPREL64MSB:
   4065          1.1  christos 	case R_IA64_GPREL64LSB:
   4066          1.1  christos 	  if (dynamic_symbol_p)
   4067          1.1  christos 	    {
   4068          1.1  christos 	      _bfd_error_handler
   4069          1.1  christos 		/* xgettext:c-format */
   4070          1.1  christos 		(_("%pB: @gprel relocation against dynamic symbol %s"),
   4071          1.1  christos 		 input_bfd,
   4072          1.1  christos 		 h ? h->root.root.string
   4073          1.1  christos 		   : bfd_elf_sym_name (input_bfd, symtab_hdr, sym,
   4074          1.1  christos 				       sym_sec));
   4075          1.1  christos 	      ret_val = FALSE;
   4076          1.1  christos 	      continue;
   4077          1.1  christos 	    }
   4078          1.1  christos 	  value -= gp_val;
   4079  1.1.1.5.4.1  christos 	  r = ia64_elf_install_value (hit_addr, value, r_type);
   4080          1.1  christos 	  break;
   4081          1.1  christos 
   4082          1.1  christos 	case R_IA64_LTOFF22:
   4083          1.1  christos 	case R_IA64_LTOFF22X:
   4084          1.1  christos 	case R_IA64_LTOFF64I:
   4085          1.1  christos 	  dyn_i = get_dyn_sym_info (ia64_info, h, input_bfd, rel, FALSE);
   4086          1.1  christos 	  value = set_got_entry (input_bfd, info, dyn_i, (h ? h->dynindx : -1),
   4087          1.1  christos 				 rel->r_addend, value, R_IA64_DIRNNLSB);
   4088          1.1  christos 	  value -= gp_val;
   4089          1.1  christos 	  r = ia64_elf_install_value (hit_addr, value, r_type);
   4090  1.1.1.5.4.1  christos 	  break;
   4091          1.1  christos 
   4092          1.1  christos 	case R_IA64_PLTOFF22:
   4093          1.1  christos 	case R_IA64_PLTOFF64I:
   4094          1.1  christos 	case R_IA64_PLTOFF64MSB:
   4095          1.1  christos 	case R_IA64_PLTOFF64LSB:
   4096          1.1  christos 	  dyn_i = get_dyn_sym_info (ia64_info, h, input_bfd, rel, FALSE);
   4097          1.1  christos 	  value = set_pltoff_entry (output_bfd, info, dyn_i, value, FALSE);
   4098          1.1  christos 	  value -= gp_val;
   4099          1.1  christos 	  r = ia64_elf_install_value (hit_addr, value, r_type);
   4100          1.1  christos 	  break;
   4101  1.1.1.5.4.1  christos 
   4102          1.1  christos 	case R_IA64_FPTR64I:
   4103          1.1  christos 	case R_IA64_FPTR32MSB:
   4104          1.1  christos 	case R_IA64_FPTR32LSB:
   4105          1.1  christos 	case R_IA64_FPTR64MSB:
   4106          1.1  christos 	case R_IA64_FPTR64LSB:
   4107      1.1.1.4  christos 	  dyn_i = get_dyn_sym_info (ia64_info, h, input_bfd, rel, FALSE);
   4108          1.1  christos 	  if (dyn_i->want_fptr)
   4109          1.1  christos 	    {
   4110          1.1  christos 	      if (!undef_weak_ref)
   4111          1.1  christos 		value = set_fptr_entry (output_bfd, info, dyn_i, value);
   4112          1.1  christos 	    }
   4113          1.1  christos 	  if (!dyn_i->want_fptr || bfd_link_pie (info))
   4114          1.1  christos 	    {
   4115          1.1  christos 	      long dynindx;
   4116          1.1  christos 	      unsigned int dyn_r_type = r_type;
   4117          1.1  christos 	      bfd_vma addend = rel->r_addend;
   4118          1.1  christos 
   4119          1.1  christos 	      /* Otherwise, we expect the dynamic linker to create
   4120          1.1  christos 		 the entry.  */
   4121          1.1  christos 
   4122          1.1  christos 	      if (dyn_i->want_fptr)
   4123          1.1  christos 		{
   4124          1.1  christos 		  if (r_type == R_IA64_FPTR64I)
   4125          1.1  christos 		    {
   4126      1.1.1.5  christos 		      /* We can't represent this without a dynamic symbol.
   4127  1.1.1.5.4.1  christos 			 Adjust the relocation to be against an output
   4128          1.1  christos 			 section symbol, which are always present in the
   4129          1.1  christos 			 dynamic symbol table.  */
   4130          1.1  christos 		      /* ??? People shouldn't be doing non-pic code in
   4131          1.1  christos 			 shared libraries.  Hork.  */
   4132          1.1  christos 		      _bfd_error_handler
   4133          1.1  christos 			(_("%pB: linking non-pic code in a position independent executable"),
   4134          1.1  christos 			 input_bfd);
   4135          1.1  christos 		      ret_val = FALSE;
   4136          1.1  christos 		      continue;
   4137          1.1  christos 		    }
   4138          1.1  christos 		  dynindx = 0;
   4139          1.1  christos 		  addend = value;
   4140          1.1  christos 		  dyn_r_type = r_type + R_IA64_RELNNLSB - R_IA64_FPTRNNLSB;
   4141          1.1  christos 		}
   4142          1.1  christos 	      else if (h)
   4143          1.1  christos 		{
   4144          1.1  christos 		  if (h->dynindx != -1)
   4145          1.1  christos 		    dynindx = h->dynindx;
   4146          1.1  christos 		  else
   4147          1.1  christos 		    dynindx = (_bfd_elf_link_lookup_local_dynindx
   4148          1.1  christos 			       (info, h->root.u.def.section->owner,
   4149          1.1  christos 				global_sym_index (h)));
   4150          1.1  christos 		  value = 0;
   4151          1.1  christos 		}
   4152          1.1  christos 	      else
   4153          1.1  christos 		{
   4154          1.1  christos 		  dynindx = (_bfd_elf_link_lookup_local_dynindx
   4155          1.1  christos 			     (info, input_bfd, (long) r_symndx));
   4156          1.1  christos 		  value = 0;
   4157          1.1  christos 		}
   4158          1.1  christos 
   4159          1.1  christos 	      elfNN_ia64_install_dyn_reloc (output_bfd, info, input_section,
   4160          1.1  christos 					    srel, rel->r_offset, dyn_r_type,
   4161          1.1  christos 					    dynindx, addend);
   4162          1.1  christos 	    }
   4163          1.1  christos 
   4164          1.1  christos 	  r = ia64_elf_install_value (hit_addr, value, r_type);
   4165          1.1  christos 	  break;
   4166          1.1  christos 
   4167          1.1  christos 	case R_IA64_LTOFF_FPTR22:
   4168          1.1  christos 	case R_IA64_LTOFF_FPTR64I:
   4169          1.1  christos 	case R_IA64_LTOFF_FPTR32MSB:
   4170          1.1  christos 	case R_IA64_LTOFF_FPTR32LSB:
   4171          1.1  christos 	case R_IA64_LTOFF_FPTR64MSB:
   4172          1.1  christos 	case R_IA64_LTOFF_FPTR64LSB:
   4173          1.1  christos 	  {
   4174  1.1.1.5.4.1  christos 	    long dynindx;
   4175  1.1.1.5.4.1  christos 
   4176          1.1  christos 	    dyn_i = get_dyn_sym_info (ia64_info, h, input_bfd, rel, FALSE);
   4177          1.1  christos 	    if (dyn_i->want_fptr)
   4178          1.1  christos 	      {
   4179          1.1  christos 		BFD_ASSERT (h == NULL || h->dynindx == -1);
   4180  1.1.1.5.4.1  christos 		if (!undef_weak_ref)
   4181          1.1  christos 		  value = set_fptr_entry (output_bfd, info, dyn_i, value);
   4182  1.1.1.5.4.1  christos 		dynindx = -1;
   4183          1.1  christos 	      }
   4184          1.1  christos 	    else
   4185          1.1  christos 	      {
   4186          1.1  christos 		/* Otherwise, we expect the dynamic linker to create
   4187          1.1  christos 		   the entry.  */
   4188          1.1  christos 		if (h)
   4189          1.1  christos 		  {
   4190          1.1  christos 		    if (h->dynindx != -1)
   4191          1.1  christos 		      dynindx = h->dynindx;
   4192          1.1  christos 		    else
   4193          1.1  christos 		      dynindx = (_bfd_elf_link_lookup_local_dynindx
   4194          1.1  christos 				 (info, h->root.u.def.section->owner,
   4195          1.1  christos 				  global_sym_index (h)));
   4196          1.1  christos 		  }
   4197          1.1  christos 		else
   4198          1.1  christos 		  dynindx = (_bfd_elf_link_lookup_local_dynindx
   4199          1.1  christos 			     (info, input_bfd, (long) r_symndx));
   4200          1.1  christos 		value = 0;
   4201          1.1  christos 	      }
   4202          1.1  christos 
   4203          1.1  christos 	    value = set_got_entry (output_bfd, info, dyn_i, dynindx,
   4204          1.1  christos 				   rel->r_addend, value, R_IA64_FPTRNNLSB);
   4205          1.1  christos 	    value -= gp_val;
   4206          1.1  christos 	    r = ia64_elf_install_value (hit_addr, value, r_type);
   4207          1.1  christos 	  }
   4208          1.1  christos 	  break;
   4209          1.1  christos 
   4210          1.1  christos 	case R_IA64_PCREL32MSB:
   4211          1.1  christos 	case R_IA64_PCREL32LSB:
   4212          1.1  christos 	case R_IA64_PCREL64MSB:
   4213          1.1  christos 	case R_IA64_PCREL64LSB:
   4214          1.1  christos 	  /* Install a dynamic relocation for this reloc.  */
   4215          1.1  christos 	  if (dynamic_symbol_p && r_symndx != STN_UNDEF)
   4216          1.1  christos 	    {
   4217          1.1  christos 	      BFD_ASSERT (srel != NULL);
   4218          1.1  christos 
   4219          1.1  christos 	      elfNN_ia64_install_dyn_reloc (output_bfd, info, input_section,
   4220          1.1  christos 					    srel, rel->r_offset, r_type,
   4221          1.1  christos 					    h->dynindx, rel->r_addend);
   4222          1.1  christos 	    }
   4223          1.1  christos 	  goto finish_pcrel;
   4224          1.1  christos 
   4225          1.1  christos 	case R_IA64_PCREL21B:
   4226          1.1  christos 	case R_IA64_PCREL60B:
   4227          1.1  christos 	  /* We should have created a PLT entry for any dynamic symbol.  */
   4228          1.1  christos 	  dyn_i = NULL;
   4229          1.1  christos 	  if (h)
   4230          1.1  christos 	    dyn_i = get_dyn_sym_info (ia64_info, h, NULL, NULL, FALSE);
   4231          1.1  christos 
   4232          1.1  christos 	  if (dyn_i && dyn_i->want_plt2)
   4233          1.1  christos 	    {
   4234          1.1  christos 	      /* Should have caught this earlier.  */
   4235          1.1  christos 	      BFD_ASSERT (rel->r_addend == 0);
   4236          1.1  christos 
   4237          1.1  christos 	      value = (ia64_info->root.splt->output_section->vma
   4238          1.1  christos 		       + ia64_info->root.splt->output_offset
   4239          1.1  christos 		       + dyn_i->plt2_offset);
   4240          1.1  christos 	    }
   4241          1.1  christos 	  else
   4242          1.1  christos 	    {
   4243          1.1  christos 	      /* Since there's no PLT entry, Validate that this is
   4244          1.1  christos 		 locally defined.  */
   4245          1.1  christos 	      BFD_ASSERT (undef_weak_ref || sym_sec->output_section != NULL);
   4246          1.1  christos 
   4247          1.1  christos 	      /* If the symbol is undef_weak, we shouldn't be trying
   4248          1.1  christos 		 to call it.  There's every chance that we'd wind up
   4249          1.1  christos 		 with an out-of-range fixup here.  Don't bother setting
   4250          1.1  christos 		 any value at all.  */
   4251          1.1  christos 	      if (undef_weak_ref)
   4252          1.1  christos 		continue;
   4253          1.1  christos 	    }
   4254          1.1  christos 	  goto finish_pcrel;
   4255          1.1  christos 
   4256          1.1  christos 	case R_IA64_PCREL21BI:
   4257          1.1  christos 	case R_IA64_PCREL21F:
   4258          1.1  christos 	case R_IA64_PCREL21M:
   4259          1.1  christos 	case R_IA64_PCREL22:
   4260          1.1  christos 	case R_IA64_PCREL64I:
   4261          1.1  christos 	  /* The PCREL21BI reloc is specifically not intended for use with
   4262          1.1  christos 	     dynamic relocs.  PCREL21F and PCREL21M are used for speculation
   4263          1.1  christos 	     fixup code, and thus probably ought not be dynamic.  The
   4264      1.1.1.5  christos 	     PCREL22 and PCREL64I relocs aren't emitted as dynamic relocs.  */
   4265  1.1.1.5.4.1  christos 	  if (dynamic_symbol_p)
   4266          1.1  christos 	    {
   4267      1.1.1.5  christos 	      const char *msg;
   4268  1.1.1.5.4.1  christos 
   4269          1.1  christos 	      if (r_type == R_IA64_PCREL21BI)
   4270      1.1.1.5  christos 		/* xgettext:c-format */
   4271  1.1.1.5.4.1  christos 		msg = _("%pB: @internal branch to dynamic symbol %s");
   4272      1.1.1.5  christos 	      else if (r_type == R_IA64_PCREL21F || r_type == R_IA64_PCREL21M)
   4273      1.1.1.5  christos 		/* xgettext:c-format */
   4274      1.1.1.5  christos 		msg = _("%pB: speculation fixup to dynamic symbol %s");
   4275      1.1.1.5  christos 	      else
   4276      1.1.1.5  christos 		/* xgettext:c-format */
   4277      1.1.1.5  christos 		msg = _("%pB: @pcrel relocation against dynamic symbol %s");
   4278          1.1  christos 	      _bfd_error_handler (msg, input_bfd,
   4279          1.1  christos 				  h ? h->root.root.string
   4280          1.1  christos 				  : bfd_elf_sym_name (input_bfd,
   4281          1.1  christos 						      symtab_hdr,
   4282          1.1  christos 						      sym,
   4283          1.1  christos 						      sym_sec));
   4284          1.1  christos 	      ret_val = FALSE;
   4285          1.1  christos 	      continue;
   4286          1.1  christos 	    }
   4287          1.1  christos 	  goto finish_pcrel;
   4288          1.1  christos 
   4289          1.1  christos 	finish_pcrel:
   4290          1.1  christos 	  /* Make pc-relative.  */
   4291          1.1  christos 	  value -= (input_section->output_section->vma
   4292          1.1  christos 		    + input_section->output_offset
   4293          1.1  christos 		    + rel->r_offset) & ~ (bfd_vma) 0x3;
   4294          1.1  christos 	  r = ia64_elf_install_value (hit_addr, value, r_type);
   4295          1.1  christos 	  break;
   4296          1.1  christos 
   4297          1.1  christos 	case R_IA64_SEGREL32MSB:
   4298          1.1  christos 	case R_IA64_SEGREL32LSB:
   4299          1.1  christos 	case R_IA64_SEGREL64MSB:
   4300          1.1  christos 	case R_IA64_SEGREL64LSB:
   4301          1.1  christos 	    {
   4302          1.1  christos 	      /* Find the segment that contains the output_section.  */
   4303          1.1  christos 	      Elf_Internal_Phdr *p = _bfd_elf_find_segment_containing_section
   4304          1.1  christos 		(output_bfd, input_section->output_section);
   4305          1.1  christos 
   4306          1.1  christos 	      if (p == NULL)
   4307          1.1  christos 		{
   4308          1.1  christos 		  r = bfd_reloc_notsupported;
   4309          1.1  christos 		}
   4310          1.1  christos 	      else
   4311          1.1  christos 		{
   4312          1.1  christos 		  /* The VMA of the segment is the vaddr of the associated
   4313          1.1  christos 		     program header.  */
   4314          1.1  christos 		  if (value > p->p_vaddr)
   4315          1.1  christos 		    value -= p->p_vaddr;
   4316          1.1  christos 		  else
   4317          1.1  christos 		    value = 0;
   4318          1.1  christos 		  r = ia64_elf_install_value (hit_addr, value, r_type);
   4319          1.1  christos 		}
   4320          1.1  christos 	      break;
   4321          1.1  christos 	    }
   4322          1.1  christos 
   4323          1.1  christos 	case R_IA64_SECREL32MSB:
   4324          1.1  christos 	case R_IA64_SECREL32LSB:
   4325          1.1  christos 	case R_IA64_SECREL64MSB:
   4326          1.1  christos 	case R_IA64_SECREL64LSB:
   4327          1.1  christos 	  /* Make output-section relative to section where the symbol
   4328          1.1  christos 	     is defined. PR 475  */
   4329          1.1  christos 	  if (sym_sec)
   4330          1.1  christos 	    value -= sym_sec->output_section->vma;
   4331      1.1.1.4  christos 	  r = ia64_elf_install_value (hit_addr, value, r_type);
   4332          1.1  christos 	  break;
   4333          1.1  christos 
   4334          1.1  christos 	case R_IA64_IPLTMSB:
   4335          1.1  christos 	case R_IA64_IPLTLSB:
   4336          1.1  christos 	  /* Install a dynamic relocation for this reloc.  */
   4337          1.1  christos 	  if ((dynamic_symbol_p || bfd_link_pic (info))
   4338          1.1  christos 	      && (input_section->flags & SEC_ALLOC) != 0)
   4339          1.1  christos 	    {
   4340          1.1  christos 	      BFD_ASSERT (srel != NULL);
   4341          1.1  christos 
   4342          1.1  christos 	      /* If we don't need dynamic symbol lookup, install two
   4343          1.1  christos 		 RELATIVE relocations.  */
   4344          1.1  christos 	      if (!dynamic_symbol_p)
   4345          1.1  christos 		{
   4346          1.1  christos 		  unsigned int dyn_r_type;
   4347          1.1  christos 
   4348          1.1  christos 		  if (r_type == R_IA64_IPLTMSB)
   4349          1.1  christos 		    dyn_r_type = R_IA64_REL64MSB;
   4350          1.1  christos 		  else
   4351          1.1  christos 		    dyn_r_type = R_IA64_REL64LSB;
   4352          1.1  christos 
   4353          1.1  christos 		  elfNN_ia64_install_dyn_reloc (output_bfd, info,
   4354          1.1  christos 						input_section,
   4355          1.1  christos 						srel, rel->r_offset,
   4356          1.1  christos 						dyn_r_type, 0, value);
   4357          1.1  christos 		  elfNN_ia64_install_dyn_reloc (output_bfd, info,
   4358          1.1  christos 						input_section,
   4359          1.1  christos 						srel, rel->r_offset + 8,
   4360          1.1  christos 						dyn_r_type, 0, gp_val);
   4361          1.1  christos 		}
   4362          1.1  christos 	      else
   4363          1.1  christos 		elfNN_ia64_install_dyn_reloc (output_bfd, info, input_section,
   4364          1.1  christos 					      srel, rel->r_offset, r_type,
   4365          1.1  christos 					      h->dynindx, rel->r_addend);
   4366          1.1  christos 	    }
   4367          1.1  christos 
   4368          1.1  christos 	  if (r_type == R_IA64_IPLTMSB)
   4369          1.1  christos 	    r_type = R_IA64_DIR64MSB;
   4370          1.1  christos 	  else
   4371          1.1  christos 	    r_type = R_IA64_DIR64LSB;
   4372          1.1  christos 	  ia64_elf_install_value (hit_addr, value, r_type);
   4373          1.1  christos 	  r = ia64_elf_install_value (hit_addr + 8, gp_val, r_type);
   4374          1.1  christos 	  break;
   4375          1.1  christos 
   4376          1.1  christos 	case R_IA64_TPREL14:
   4377          1.1  christos 	case R_IA64_TPREL22:
   4378          1.1  christos 	case R_IA64_TPREL64I:
   4379          1.1  christos 	  if (elf_hash_table (info)->tls_sec == NULL)
   4380          1.1  christos 	    goto missing_tls_sec;
   4381          1.1  christos 	  value -= elfNN_ia64_tprel_base (info);
   4382          1.1  christos 	  r = ia64_elf_install_value (hit_addr, value, r_type);
   4383          1.1  christos 	  break;
   4384          1.1  christos 
   4385          1.1  christos 	case R_IA64_DTPREL14:
   4386          1.1  christos 	case R_IA64_DTPREL22:
   4387          1.1  christos 	case R_IA64_DTPREL64I:
   4388          1.1  christos 	case R_IA64_DTPREL32LSB:
   4389          1.1  christos 	case R_IA64_DTPREL32MSB:
   4390          1.1  christos 	case R_IA64_DTPREL64LSB:
   4391          1.1  christos 	case R_IA64_DTPREL64MSB:
   4392          1.1  christos 	  if (elf_hash_table (info)->tls_sec == NULL)
   4393          1.1  christos 	    goto missing_tls_sec;
   4394          1.1  christos 	  value -= elfNN_ia64_dtprel_base (info);
   4395          1.1  christos 	  r = ia64_elf_install_value (hit_addr, value, r_type);
   4396          1.1  christos 	  break;
   4397          1.1  christos 
   4398          1.1  christos 	case R_IA64_LTOFF_TPREL22:
   4399          1.1  christos 	case R_IA64_LTOFF_DTPMOD22:
   4400          1.1  christos 	case R_IA64_LTOFF_DTPREL22:
   4401          1.1  christos 	  {
   4402          1.1  christos 	    int got_r_type;
   4403          1.1  christos 	    long dynindx = h ? h->dynindx : -1;
   4404          1.1  christos 	    bfd_vma r_addend = rel->r_addend;
   4405          1.1  christos 
   4406          1.1  christos 	    switch (r_type)
   4407          1.1  christos 	      {
   4408      1.1.1.4  christos 	      default:
   4409          1.1  christos 	      case R_IA64_LTOFF_TPREL22:
   4410          1.1  christos 		if (!dynamic_symbol_p)
   4411          1.1  christos 		  {
   4412          1.1  christos 		    if (elf_hash_table (info)->tls_sec == NULL)
   4413          1.1  christos 		      goto missing_tls_sec;
   4414          1.1  christos 		    if (!bfd_link_pic (info))
   4415          1.1  christos 		      value -= elfNN_ia64_tprel_base (info);
   4416          1.1  christos 		    else
   4417          1.1  christos 		      {
   4418          1.1  christos 			r_addend += value - elfNN_ia64_dtprel_base (info);
   4419      1.1.1.4  christos 			dynindx = 0;
   4420          1.1  christos 		      }
   4421          1.1  christos 		  }
   4422          1.1  christos 		got_r_type = R_IA64_TPREL64LSB;
   4423          1.1  christos 		break;
   4424          1.1  christos 	      case R_IA64_LTOFF_DTPMOD22:
   4425          1.1  christos 		if (!dynamic_symbol_p && !bfd_link_pic (info))
   4426          1.1  christos 		  value = 1;
   4427          1.1  christos 		got_r_type = R_IA64_DTPMOD64LSB;
   4428          1.1  christos 		break;
   4429          1.1  christos 	      case R_IA64_LTOFF_DTPREL22:
   4430          1.1  christos 		if (!dynamic_symbol_p)
   4431          1.1  christos 		  {
   4432          1.1  christos 		    if (elf_hash_table (info)->tls_sec == NULL)
   4433          1.1  christos 		      goto missing_tls_sec;
   4434          1.1  christos 		    value -= elfNN_ia64_dtprel_base (info);
   4435          1.1  christos 		  }
   4436          1.1  christos 		got_r_type = R_IA64_DTPRELNNLSB;
   4437          1.1  christos 		break;
   4438          1.1  christos 	      }
   4439          1.1  christos 	    dyn_i = get_dyn_sym_info (ia64_info, h, input_bfd, rel, FALSE);
   4440          1.1  christos 	    value = set_got_entry (input_bfd, info, dyn_i, dynindx, r_addend,
   4441          1.1  christos 				   value, got_r_type);
   4442          1.1  christos 	    value -= gp_val;
   4443          1.1  christos 	    r = ia64_elf_install_value (hit_addr, value, r_type);
   4444          1.1  christos 	  }
   4445          1.1  christos 	  break;
   4446          1.1  christos 
   4447          1.1  christos 	default:
   4448          1.1  christos 	  r = bfd_reloc_notsupported;
   4449          1.1  christos 	  break;
   4450          1.1  christos 	}
   4451          1.1  christos 
   4452          1.1  christos       switch (r)
   4453          1.1  christos 	{
   4454          1.1  christos 	case bfd_reloc_ok:
   4455          1.1  christos 	  break;
   4456          1.1  christos 
   4457          1.1  christos 	case bfd_reloc_undefined:
   4458          1.1  christos 	  /* This can happen for global table relative relocs if
   4459          1.1  christos 	     __gp is undefined.  This is a panic situation so we
   4460          1.1  christos 	     don't try to continue.  */
   4461          1.1  christos 	  (*info->callbacks->undefined_symbol)
   4462          1.1  christos 	    (info, "__gp", input_bfd, input_section, rel->r_offset, 1);
   4463          1.1  christos 	  return FALSE;
   4464          1.1  christos 
   4465          1.1  christos 	case bfd_reloc_notsupported:
   4466          1.1  christos 	  {
   4467          1.1  christos 	    const char *name;
   4468      1.1.1.4  christos 
   4469      1.1.1.4  christos 	    if (h)
   4470      1.1.1.4  christos 	      name = h->root.root.string;
   4471          1.1  christos 	    else
   4472          1.1  christos 	      name = bfd_elf_sym_name (input_bfd, symtab_hdr, sym,
   4473          1.1  christos 				       sym_sec);
   4474          1.1  christos 	    (*info->callbacks->warning) (info, _("unsupported reloc"),
   4475          1.1  christos 					 name, input_bfd,
   4476          1.1  christos 					 input_section, rel->r_offset);
   4477          1.1  christos 	    ret_val = FALSE;
   4478          1.1  christos 	  }
   4479          1.1  christos 	  break;
   4480          1.1  christos 
   4481          1.1  christos 	case bfd_reloc_dangerous:
   4482          1.1  christos 	case bfd_reloc_outofrange:
   4483          1.1  christos 	case bfd_reloc_overflow:
   4484          1.1  christos 	default:
   4485          1.1  christos missing_tls_sec:
   4486          1.1  christos 	  {
   4487          1.1  christos 	    const char *name;
   4488          1.1  christos 
   4489          1.1  christos 	    if (h)
   4490          1.1  christos 	      name = h->root.root.string;
   4491          1.1  christos 	    else
   4492          1.1  christos 	      name = bfd_elf_sym_name (input_bfd, symtab_hdr, sym,
   4493          1.1  christos 				       sym_sec);
   4494          1.1  christos 
   4495          1.1  christos 	    switch (r_type)
   4496          1.1  christos 	      {
   4497          1.1  christos 	      case R_IA64_TPREL14:
   4498          1.1  christos 	      case R_IA64_TPREL22:
   4499          1.1  christos 	      case R_IA64_TPREL64I:
   4500          1.1  christos 	      case R_IA64_DTPREL14:
   4501          1.1  christos 	      case R_IA64_DTPREL22:
   4502          1.1  christos 	      case R_IA64_DTPREL64I:
   4503          1.1  christos 	      case R_IA64_DTPREL32LSB:
   4504      1.1.1.5  christos 	      case R_IA64_DTPREL32MSB:
   4505      1.1.1.5  christos 	      case R_IA64_DTPREL64LSB:
   4506  1.1.1.5.4.1  christos 	      case R_IA64_DTPREL64MSB:
   4507  1.1.1.5.4.1  christos 	      case R_IA64_LTOFF_TPREL22:
   4508      1.1.1.5  christos 	      case R_IA64_LTOFF_DTPMOD22:
   4509  1.1.1.5.4.1  christos 	      case R_IA64_LTOFF_DTPREL22:
   4510          1.1  christos 		_bfd_error_handler
   4511          1.1  christos 		  /* xgettext:c-format */
   4512          1.1  christos 		  (_("%pB: missing TLS section for relocation %s against `%s'"
   4513          1.1  christos 		     " at %#" PRIx64 " in section `%pA'."),
   4514          1.1  christos 		   input_bfd, howto->name, name,
   4515          1.1  christos 		   (uint64_t) rel->r_offset, input_section);
   4516          1.1  christos 		break;
   4517          1.1  christos 
   4518          1.1  christos 	      case R_IA64_PCREL21B:
   4519          1.1  christos 	      case R_IA64_PCREL21BI:
   4520          1.1  christos 	      case R_IA64_PCREL21M:
   4521      1.1.1.5  christos 	      case R_IA64_PCREL21F:
   4522      1.1.1.5  christos 		if (is_elf_hash_table (info->hash))
   4523  1.1.1.5.4.1  christos 		  {
   4524  1.1.1.5.4.1  christos 		    /* Relaxtion is always performed for ELF output.
   4525  1.1.1.5.4.1  christos 		       Overflow failures for those relocations mean
   4526  1.1.1.5.4.1  christos 		       that the section is too big to relax.  */
   4527  1.1.1.5.4.1  christos 		    _bfd_error_handler
   4528          1.1  christos 		      /* xgettext:c-format */
   4529          1.1  christos 		      (_("%pB: Can't relax br (%s) to `%s' at %#" PRIx64
   4530      1.1.1.5  christos 			 " in section `%pA' with size %#" PRIx64
   4531          1.1  christos 			 " (> 0x1000000)."),
   4532      1.1.1.4  christos 		       input_bfd, howto->name, name, (uint64_t) rel->r_offset,
   4533      1.1.1.4  christos 		       input_section, (uint64_t) input_section->size);
   4534      1.1.1.4  christos 		    break;
   4535      1.1.1.4  christos 		  }
   4536      1.1.1.4  christos 		/* Fall through.  */
   4537      1.1.1.4  christos 	      default:
   4538      1.1.1.4  christos 		(*info->callbacks->reloc_overflow) (info,
   4539      1.1.1.4  christos 						    &h->root,
   4540          1.1  christos 						    name,
   4541          1.1  christos 						    howto->name,
   4542          1.1  christos 						    (bfd_vma) 0,
   4543          1.1  christos 						    input_bfd,
   4544          1.1  christos 						    input_section,
   4545          1.1  christos 						    rel->r_offset);
   4546          1.1  christos 		break;
   4547          1.1  christos 	      }
   4548          1.1  christos 
   4549          1.1  christos 	    ret_val = FALSE;
   4550          1.1  christos 	  }
   4551          1.1  christos 	  break;
   4552          1.1  christos 	}
   4553          1.1  christos     }
   4554          1.1  christos 
   4555          1.1  christos   return ret_val;
   4556          1.1  christos }
   4557          1.1  christos 
   4558          1.1  christos static bfd_boolean
   4559          1.1  christos elfNN_ia64_finish_dynamic_symbol (bfd *output_bfd,
   4560          1.1  christos 				  struct bfd_link_info *info,
   4561          1.1  christos 				  struct elf_link_hash_entry *h,
   4562          1.1  christos 				  Elf_Internal_Sym *sym)
   4563          1.1  christos {
   4564          1.1  christos   struct elfNN_ia64_link_hash_table *ia64_info;
   4565          1.1  christos   struct elfNN_ia64_dyn_sym_info *dyn_i;
   4566          1.1  christos 
   4567          1.1  christos   ia64_info = elfNN_ia64_hash_table (info);
   4568          1.1  christos   if (ia64_info == NULL)
   4569          1.1  christos     return FALSE;
   4570          1.1  christos 
   4571          1.1  christos   dyn_i = get_dyn_sym_info (ia64_info, h, NULL, NULL, FALSE);
   4572          1.1  christos 
   4573          1.1  christos   /* Fill in the PLT data, if required.  */
   4574          1.1  christos   if (dyn_i && dyn_i->want_plt)
   4575          1.1  christos     {
   4576          1.1  christos       Elf_Internal_Rela outrel;
   4577          1.1  christos       bfd_byte *loc;
   4578          1.1  christos       asection *plt_sec;
   4579          1.1  christos       bfd_vma plt_addr, pltoff_addr, gp_val, plt_index;
   4580          1.1  christos 
   4581          1.1  christos       gp_val = _bfd_get_gp_value (output_bfd);
   4582          1.1  christos 
   4583          1.1  christos       /* Initialize the minimal PLT entry.  */
   4584          1.1  christos 
   4585          1.1  christos       plt_index = (dyn_i->plt_offset - PLT_HEADER_SIZE) / PLT_MIN_ENTRY_SIZE;
   4586          1.1  christos       plt_sec = ia64_info->root.splt;
   4587          1.1  christos       loc = plt_sec->contents + dyn_i->plt_offset;
   4588          1.1  christos 
   4589          1.1  christos       memcpy (loc, plt_min_entry, PLT_MIN_ENTRY_SIZE);
   4590          1.1  christos       ia64_elf_install_value (loc, plt_index, R_IA64_IMM22);
   4591          1.1  christos       ia64_elf_install_value (loc+2, -dyn_i->plt_offset, R_IA64_PCREL21B);
   4592          1.1  christos 
   4593          1.1  christos       plt_addr = (plt_sec->output_section->vma
   4594          1.1  christos 		  + plt_sec->output_offset
   4595          1.1  christos 		  + dyn_i->plt_offset);
   4596          1.1  christos       pltoff_addr = set_pltoff_entry (output_bfd, info, dyn_i, plt_addr, TRUE);
   4597          1.1  christos 
   4598          1.1  christos       /* Initialize the FULL PLT entry, if needed.  */
   4599          1.1  christos       if (dyn_i->want_plt2)
   4600          1.1  christos 	{
   4601          1.1  christos 	  loc = plt_sec->contents + dyn_i->plt2_offset;
   4602          1.1  christos 
   4603          1.1  christos 	  memcpy (loc, plt_full_entry, PLT_FULL_ENTRY_SIZE);
   4604          1.1  christos 	  ia64_elf_install_value (loc, pltoff_addr - gp_val, R_IA64_IMM22);
   4605          1.1  christos 
   4606          1.1  christos 	  /* Mark the symbol as undefined, rather than as defined in the
   4607          1.1  christos 	     plt section.  Leave the value alone.  */
   4608          1.1  christos 	  /* ??? We didn't redefine it in adjust_dynamic_symbol in the
   4609          1.1  christos 	     first place.  But perhaps elflink.c did some for us.  */
   4610          1.1  christos 	  if (!h->def_regular)
   4611          1.1  christos 	    sym->st_shndx = SHN_UNDEF;
   4612          1.1  christos 	}
   4613          1.1  christos 
   4614          1.1  christos       /* Create the dynamic relocation.  */
   4615          1.1  christos       outrel.r_offset = pltoff_addr;
   4616          1.1  christos       if (bfd_little_endian (output_bfd))
   4617          1.1  christos 	outrel.r_info = ELFNN_R_INFO (h->dynindx, R_IA64_IPLTLSB);
   4618          1.1  christos       else
   4619          1.1  christos 	outrel.r_info = ELFNN_R_INFO (h->dynindx, R_IA64_IPLTMSB);
   4620          1.1  christos       outrel.r_addend = 0;
   4621          1.1  christos 
   4622          1.1  christos       /* This is fun.  In the .IA_64.pltoff section, we've got entries
   4623          1.1  christos 	 that correspond both to real PLT entries, and those that
   4624          1.1  christos 	 happened to resolve to local symbols but need to be created
   4625          1.1  christos 	 to satisfy @pltoff relocations.  The .rela.IA_64.pltoff
   4626          1.1  christos 	 relocations for the real PLT should come at the end of the
   4627          1.1  christos 	 section, so that they can be indexed by plt entry at runtime.
   4628          1.1  christos 
   4629          1.1  christos 	 We emitted all of the relocations for the non-PLT @pltoff
   4630          1.1  christos 	 entries during relocate_section.  So we can consider the
   4631          1.1  christos 	 existing sec->reloc_count to be the base of the array of
   4632          1.1  christos 	 PLT relocations.  */
   4633          1.1  christos 
   4634          1.1  christos       loc = ia64_info->rel_pltoff_sec->contents;
   4635          1.1  christos       loc += ((ia64_info->rel_pltoff_sec->reloc_count + plt_index)
   4636          1.1  christos 	      * sizeof (ElfNN_External_Rela));
   4637          1.1  christos       bfd_elfNN_swap_reloca_out (output_bfd, &outrel, loc);
   4638          1.1  christos     }
   4639          1.1  christos 
   4640          1.1  christos   /* Mark some specially defined symbols as absolute.  */
   4641          1.1  christos   if (h == ia64_info->root.hdynamic
   4642          1.1  christos       || h == ia64_info->root.hgot
   4643          1.1  christos       || h == ia64_info->root.hplt)
   4644          1.1  christos     sym->st_shndx = SHN_ABS;
   4645          1.1  christos 
   4646          1.1  christos   return TRUE;
   4647          1.1  christos }
   4648          1.1  christos 
   4649          1.1  christos static bfd_boolean
   4650          1.1  christos elfNN_ia64_finish_dynamic_sections (bfd *abfd,
   4651          1.1  christos 				    struct bfd_link_info *info)
   4652          1.1  christos {
   4653          1.1  christos   struct elfNN_ia64_link_hash_table *ia64_info;
   4654          1.1  christos   bfd *dynobj;
   4655          1.1  christos 
   4656      1.1.1.5  christos   ia64_info = elfNN_ia64_hash_table (info);
   4657          1.1  christos   if (ia64_info == NULL)
   4658          1.1  christos     return FALSE;
   4659          1.1  christos 
   4660          1.1  christos   dynobj = ia64_info->root.dynobj;
   4661          1.1  christos 
   4662          1.1  christos   if (ia64_info->root.dynamic_sections_created)
   4663      1.1.1.5  christos     {
   4664          1.1  christos       ElfNN_External_Dyn *dyncon, *dynconend;
   4665          1.1  christos       asection *sdyn, *sgotplt;
   4666          1.1  christos       bfd_vma gp_val;
   4667          1.1  christos 
   4668          1.1  christos       sdyn = bfd_get_linker_section (dynobj, ".dynamic");
   4669          1.1  christos       sgotplt = ia64_info->root.sgotplt;
   4670          1.1  christos       BFD_ASSERT (sdyn != NULL);
   4671          1.1  christos       dyncon = (ElfNN_External_Dyn *) sdyn->contents;
   4672          1.1  christos       dynconend = (ElfNN_External_Dyn *) (sdyn->contents + sdyn->size);
   4673          1.1  christos 
   4674          1.1  christos       gp_val = _bfd_get_gp_value (abfd);
   4675          1.1  christos 
   4676          1.1  christos       for (; dyncon < dynconend; dyncon++)
   4677          1.1  christos 	{
   4678          1.1  christos 	  Elf_Internal_Dyn dyn;
   4679          1.1  christos 
   4680          1.1  christos 	  bfd_elfNN_swap_dyn_in (dynobj, dyncon, &dyn);
   4681          1.1  christos 
   4682          1.1  christos 	  switch (dyn.d_tag)
   4683          1.1  christos 	    {
   4684          1.1  christos 	    case DT_PLTGOT:
   4685          1.1  christos 	      dyn.d_un.d_ptr = gp_val;
   4686          1.1  christos 	      break;
   4687          1.1  christos 
   4688          1.1  christos 	    case DT_PLTRELSZ:
   4689          1.1  christos 	      dyn.d_un.d_val = (ia64_info->minplt_entries
   4690          1.1  christos 				* sizeof (ElfNN_External_Rela));
   4691          1.1  christos 	      break;
   4692          1.1  christos 
   4693          1.1  christos 	    case DT_JMPREL:
   4694          1.1  christos 	      /* See the comment above in finish_dynamic_symbol.  */
   4695          1.1  christos 	      dyn.d_un.d_ptr = (ia64_info->rel_pltoff_sec->output_section->vma
   4696          1.1  christos 				+ ia64_info->rel_pltoff_sec->output_offset
   4697          1.1  christos 				+ (ia64_info->rel_pltoff_sec->reloc_count
   4698          1.1  christos 				   * sizeof (ElfNN_External_Rela)));
   4699          1.1  christos 	      break;
   4700          1.1  christos 
   4701          1.1  christos 	    case DT_IA_64_PLT_RESERVE:
   4702          1.1  christos 	      dyn.d_un.d_ptr = (sgotplt->output_section->vma
   4703          1.1  christos 				+ sgotplt->output_offset);
   4704          1.1  christos 	      break;
   4705          1.1  christos 	    }
   4706          1.1  christos 
   4707          1.1  christos 	  bfd_elfNN_swap_dyn_out (abfd, &dyn, dyncon);
   4708          1.1  christos 	}
   4709          1.1  christos 
   4710          1.1  christos       /* Initialize the PLT0 entry.  */
   4711          1.1  christos       if (ia64_info->root.splt)
   4712          1.1  christos 	{
   4713          1.1  christos 	  bfd_byte *loc = ia64_info->root.splt->contents;
   4714          1.1  christos 	  bfd_vma pltres;
   4715          1.1  christos 
   4716          1.1  christos 	  memcpy (loc, plt_header, PLT_HEADER_SIZE);
   4717          1.1  christos 
   4718          1.1  christos 	  pltres = (sgotplt->output_section->vma
   4719          1.1  christos 		    + sgotplt->output_offset
   4720          1.1  christos 		    - gp_val);
   4721          1.1  christos 
   4722          1.1  christos 	  ia64_elf_install_value (loc+1, pltres, R_IA64_GPREL22);
   4723          1.1  christos 	}
   4724          1.1  christos     }
   4725          1.1  christos 
   4726          1.1  christos   return TRUE;
   4727          1.1  christos }
   4728          1.1  christos 
   4729          1.1  christos /* ELF file flag handling:  */
   4731          1.1  christos 
   4732          1.1  christos /* Function to keep IA-64 specific file flags.  */
   4733          1.1  christos static bfd_boolean
   4734          1.1  christos elfNN_ia64_set_private_flags (bfd *abfd, flagword flags)
   4735          1.1  christos {
   4736          1.1  christos   BFD_ASSERT (!elf_flags_init (abfd)
   4737          1.1  christos 	      || elf_elfheader (abfd)->e_flags == flags);
   4738          1.1  christos 
   4739          1.1  christos   elf_elfheader (abfd)->e_flags = flags;
   4740      1.1.1.5  christos   elf_flags_init (abfd) = TRUE;
   4741          1.1  christos   return TRUE;
   4742      1.1.1.5  christos }
   4743          1.1  christos 
   4744          1.1  christos /* Merge backend specific data from an object file to the output
   4745          1.1  christos    object file when linking.  */
   4746          1.1  christos static bfd_boolean
   4747          1.1  christos elfNN_ia64_merge_private_bfd_data (bfd *ibfd, struct bfd_link_info *info)
   4748          1.1  christos {
   4749          1.1  christos   bfd *obfd = info->output_bfd;
   4750          1.1  christos   flagword out_flags;
   4751          1.1  christos   flagword in_flags;
   4752          1.1  christos   bfd_boolean ok = TRUE;
   4753          1.1  christos 
   4754          1.1  christos   /* Don't even pretend to support mixed-format linking.  */
   4755          1.1  christos   if (bfd_get_flavour (ibfd) != bfd_target_elf_flavour
   4756          1.1  christos       || bfd_get_flavour (obfd) != bfd_target_elf_flavour)
   4757          1.1  christos     return FALSE;
   4758          1.1  christos 
   4759          1.1  christos   in_flags  = elf_elfheader (ibfd)->e_flags;
   4760          1.1  christos   out_flags = elf_elfheader (obfd)->e_flags;
   4761          1.1  christos 
   4762          1.1  christos   if (! elf_flags_init (obfd))
   4763          1.1  christos     {
   4764          1.1  christos       elf_flags_init (obfd) = TRUE;
   4765          1.1  christos       elf_elfheader (obfd)->e_flags = in_flags;
   4766          1.1  christos 
   4767          1.1  christos       if (bfd_get_arch (obfd) == bfd_get_arch (ibfd)
   4768          1.1  christos 	  && bfd_get_arch_info (obfd)->the_default)
   4769          1.1  christos 	{
   4770          1.1  christos 	  return bfd_set_arch_mach (obfd, bfd_get_arch (ibfd),
   4771          1.1  christos 				    bfd_get_mach (ibfd));
   4772          1.1  christos 	}
   4773          1.1  christos 
   4774          1.1  christos       return TRUE;
   4775          1.1  christos     }
   4776          1.1  christos 
   4777          1.1  christos   /* Check flag compatibility.  */
   4778          1.1  christos   if (in_flags == out_flags)
   4779          1.1  christos     return TRUE;
   4780      1.1.1.5  christos 
   4781  1.1.1.5.4.1  christos   /* Output has EF_IA_64_REDUCEDFP set only if all inputs have it set.  */
   4782          1.1  christos   if (!(in_flags & EF_IA_64_REDUCEDFP) && (out_flags & EF_IA_64_REDUCEDFP))
   4783          1.1  christos     elf_elfheader (obfd)->e_flags &= ~EF_IA_64_REDUCEDFP;
   4784          1.1  christos 
   4785          1.1  christos   if ((in_flags & EF_IA_64_TRAPNIL) != (out_flags & EF_IA_64_TRAPNIL))
   4786          1.1  christos     {
   4787          1.1  christos       _bfd_error_handler
   4788          1.1  christos 	(_("%pB: linking trap-on-NULL-dereference with non-trapping files"),
   4789      1.1.1.5  christos 	 ibfd);
   4790  1.1.1.5.4.1  christos 
   4791          1.1  christos       bfd_set_error (bfd_error_bad_value);
   4792          1.1  christos       ok = FALSE;
   4793          1.1  christos     }
   4794          1.1  christos   if ((in_flags & EF_IA_64_BE) != (out_flags & EF_IA_64_BE))
   4795          1.1  christos     {
   4796          1.1  christos       _bfd_error_handler
   4797          1.1  christos 	(_("%pB: linking big-endian files with little-endian files"),
   4798      1.1.1.5  christos 	 ibfd);
   4799  1.1.1.5.4.1  christos 
   4800          1.1  christos       bfd_set_error (bfd_error_bad_value);
   4801          1.1  christos       ok = FALSE;
   4802          1.1  christos     }
   4803          1.1  christos   if ((in_flags & EF_IA_64_ABI64) != (out_flags & EF_IA_64_ABI64))
   4804          1.1  christos     {
   4805          1.1  christos       _bfd_error_handler
   4806          1.1  christos 	(_("%pB: linking 64-bit files with 32-bit files"),
   4807      1.1.1.5  christos 	 ibfd);
   4808  1.1.1.5.4.1  christos 
   4809          1.1  christos       bfd_set_error (bfd_error_bad_value);
   4810          1.1  christos       ok = FALSE;
   4811          1.1  christos     }
   4812          1.1  christos   if ((in_flags & EF_IA_64_CONS_GP) != (out_flags & EF_IA_64_CONS_GP))
   4813          1.1  christos     {
   4814          1.1  christos       _bfd_error_handler
   4815          1.1  christos 	(_("%pB: linking constant-gp files with non-constant-gp files"),
   4816          1.1  christos 	 ibfd);
   4817      1.1.1.5  christos 
   4818  1.1.1.5.4.1  christos       bfd_set_error (bfd_error_bad_value);
   4819          1.1  christos       ok = FALSE;
   4820          1.1  christos     }
   4821          1.1  christos   if ((in_flags & EF_IA_64_NOFUNCDESC_CONS_GP)
   4822          1.1  christos       != (out_flags & EF_IA_64_NOFUNCDESC_CONS_GP))
   4823          1.1  christos     {
   4824          1.1  christos       _bfd_error_handler
   4825          1.1  christos 	(_("%pB: linking auto-pic files with non-auto-pic files"),
   4826          1.1  christos 	 ibfd);
   4827          1.1  christos 
   4828          1.1  christos       bfd_set_error (bfd_error_bad_value);
   4829          1.1  christos       ok = FALSE;
   4830          1.1  christos     }
   4831          1.1  christos 
   4832          1.1  christos   return ok;
   4833          1.1  christos }
   4834          1.1  christos 
   4835          1.1  christos static bfd_boolean
   4836          1.1  christos elfNN_ia64_print_private_bfd_data (bfd *abfd, void * ptr)
   4837          1.1  christos {
   4838          1.1  christos   FILE *file = (FILE *) ptr;
   4839          1.1  christos   flagword flags = elf_elfheader (abfd)->e_flags;
   4840          1.1  christos 
   4841          1.1  christos   BFD_ASSERT (abfd != NULL && ptr != NULL);
   4842          1.1  christos 
   4843          1.1  christos   fprintf (file, "private flags = %s%s%s%s%s%s%s%s\n",
   4844          1.1  christos 	   (flags & EF_IA_64_TRAPNIL) ? "TRAPNIL, " : "",
   4845          1.1  christos 	   (flags & EF_IA_64_EXT) ? "EXT, " : "",
   4846          1.1  christos 	   (flags & EF_IA_64_BE) ? "BE, " : "LE, ",
   4847          1.1  christos 	   (flags & EF_IA_64_REDUCEDFP) ? "REDUCEDFP, " : "",
   4848          1.1  christos 	   (flags & EF_IA_64_CONS_GP) ? "CONS_GP, " : "",
   4849          1.1  christos 	   (flags & EF_IA_64_NOFUNCDESC_CONS_GP) ? "NOFUNCDESC_CONS_GP, " : "",
   4850          1.1  christos 	   (flags & EF_IA_64_ABSOLUTE) ? "ABSOLUTE, " : "",
   4851      1.1.1.2  christos 	   (flags & EF_IA_64_ABI64) ? "ABI64" : "ABI32");
   4852      1.1.1.2  christos 
   4853      1.1.1.2  christos   _bfd_elf_print_private_bfd_data (abfd, ptr);
   4854          1.1  christos   return TRUE;
   4855          1.1  christos }
   4856          1.1  christos 
   4857          1.1  christos static enum elf_reloc_type_class
   4858          1.1  christos elfNN_ia64_reloc_type_class (const struct bfd_link_info *info ATTRIBUTE_UNUSED,
   4859          1.1  christos 			     const asection *rel_sec ATTRIBUTE_UNUSED,
   4860          1.1  christos 			     const Elf_Internal_Rela *rela)
   4861          1.1  christos {
   4862          1.1  christos   switch ((int) ELFNN_R_TYPE (rela->r_info))
   4863          1.1  christos     {
   4864          1.1  christos     case R_IA64_REL32MSB:
   4865          1.1  christos     case R_IA64_REL32LSB:
   4866          1.1  christos     case R_IA64_REL64MSB:
   4867          1.1  christos     case R_IA64_REL64LSB:
   4868          1.1  christos       return reloc_class_relative;
   4869          1.1  christos     case R_IA64_IPLTMSB:
   4870          1.1  christos     case R_IA64_IPLTLSB:
   4871          1.1  christos       return reloc_class_plt;
   4872          1.1  christos     case R_IA64_COPY:
   4873          1.1  christos       return reloc_class_copy;
   4874  1.1.1.5.4.1  christos     default:
   4875          1.1  christos       return reloc_class_normal;
   4876  1.1.1.5.4.1  christos     }
   4877          1.1  christos }
   4878          1.1  christos 
   4879          1.1  christos static const struct bfd_elf_special_section elfNN_ia64_special_sections[] =
   4880          1.1  christos {
   4881          1.1  christos   { STRING_COMMA_LEN (".sbss"),	 -1, SHT_NOBITS,   SHF_ALLOC + SHF_WRITE + SHF_IA_64_SHORT },
   4882          1.1  christos   { STRING_COMMA_LEN (".sdata"), -1, SHT_PROGBITS, SHF_ALLOC + SHF_WRITE + SHF_IA_64_SHORT },
   4883          1.1  christos   { NULL,		     0,	  0, 0,		   0 }
   4884          1.1  christos };
   4885          1.1  christos 
   4886          1.1  christos static bfd_boolean
   4887          1.1  christos elfNN_ia64_object_p (bfd *abfd)
   4888          1.1  christos {
   4889          1.1  christos   asection *sec;
   4890          1.1  christos   asection *group, *unwi, *unw;
   4891          1.1  christos   flagword flags;
   4892          1.1  christos   const char *name;
   4893          1.1  christos   char *unwi_name, *unw_name;
   4894          1.1  christos   bfd_size_type amt;
   4895          1.1  christos 
   4896          1.1  christos   if (abfd->flags & DYNAMIC)
   4897          1.1  christos     return TRUE;
   4898          1.1  christos 
   4899          1.1  christos   /* Flags for fake group section.  */
   4900          1.1  christos   flags = (SEC_LINKER_CREATED | SEC_GROUP | SEC_LINK_ONCE
   4901          1.1  christos 	   | SEC_EXCLUDE);
   4902          1.1  christos 
   4903          1.1  christos   /* We add a fake section group for each .gnu.linkonce.t.* section,
   4904          1.1  christos      which isn't in a section group, and its unwind sections.  */
   4905          1.1  christos   for (sec = abfd->sections; sec != NULL; sec = sec->next)
   4906          1.1  christos     {
   4907          1.1  christos       if (elf_sec_group (sec) == NULL
   4908          1.1  christos 	  && ((sec->flags & (SEC_LINK_ONCE | SEC_CODE | SEC_GROUP))
   4909          1.1  christos 	      == (SEC_LINK_ONCE | SEC_CODE))
   4910          1.1  christos 	  && CONST_STRNEQ (sec->name, ".gnu.linkonce.t."))
   4911          1.1  christos 	{
   4912          1.1  christos 	  name = sec->name + 16;
   4913          1.1  christos 
   4914          1.1  christos 	  amt = strlen (name) + sizeof (".gnu.linkonce.ia64unwi.");
   4915          1.1  christos 	  unwi_name = bfd_alloc (abfd, amt);
   4916          1.1  christos 	  if (!unwi_name)
   4917          1.1  christos 	    return FALSE;
   4918          1.1  christos 
   4919          1.1  christos 	  strcpy (stpcpy (unwi_name, ".gnu.linkonce.ia64unwi."), name);
   4920          1.1  christos 	  unwi = bfd_get_section_by_name (abfd, unwi_name);
   4921          1.1  christos 
   4922          1.1  christos 	  amt = strlen (name) + sizeof (".gnu.linkonce.ia64unw.");
   4923          1.1  christos 	  unw_name = bfd_alloc (abfd, amt);
   4924          1.1  christos 	  if (!unw_name)
   4925          1.1  christos 	    return FALSE;
   4926          1.1  christos 
   4927          1.1  christos 	  strcpy (stpcpy (unw_name, ".gnu.linkonce.ia64unw."), name);
   4928          1.1  christos 	  unw = bfd_get_section_by_name (abfd, unw_name);
   4929          1.1  christos 
   4930          1.1  christos 	  /* We need to create a fake group section for it and its
   4931          1.1  christos 	     unwind sections.  */
   4932          1.1  christos 	  group = bfd_make_section_anyway_with_flags (abfd, name,
   4933          1.1  christos 						      flags);
   4934          1.1  christos 	  if (group == NULL)
   4935          1.1  christos 	    return FALSE;
   4936          1.1  christos 
   4937          1.1  christos 	  /* Move the fake group section to the beginning.  */
   4938          1.1  christos 	  bfd_section_list_remove (abfd, group);
   4939          1.1  christos 	  bfd_section_list_prepend (abfd, group);
   4940          1.1  christos 
   4941          1.1  christos 	  elf_next_in_group (group) = sec;
   4942          1.1  christos 
   4943          1.1  christos 	  elf_group_name (sec) = name;
   4944          1.1  christos 	  elf_next_in_group (sec) = sec;
   4945          1.1  christos 	  elf_sec_group (sec) = group;
   4946          1.1  christos 
   4947          1.1  christos 	  if (unwi)
   4948          1.1  christos 	    {
   4949          1.1  christos 	      elf_group_name (unwi) = name;
   4950          1.1  christos 	      elf_next_in_group (unwi) = sec;
   4951          1.1  christos 	      elf_next_in_group (sec) = unwi;
   4952          1.1  christos 	      elf_sec_group (unwi) = group;
   4953          1.1  christos 	    }
   4954          1.1  christos 
   4955          1.1  christos 	   if (unw)
   4956          1.1  christos 	     {
   4957          1.1  christos 	       elf_group_name (unw) = name;
   4958          1.1  christos 	       if (unwi)
   4959          1.1  christos 		 {
   4960          1.1  christos 		   elf_next_in_group (unw) = elf_next_in_group (unwi);
   4961          1.1  christos 		   elf_next_in_group (unwi) = unw;
   4962          1.1  christos 		 }
   4963          1.1  christos 	       else
   4964          1.1  christos 		 {
   4965          1.1  christos 		   elf_next_in_group (unw) = sec;
   4966          1.1  christos 		   elf_next_in_group (sec) = unw;
   4967          1.1  christos 		 }
   4968          1.1  christos 	       elf_sec_group (unw) = group;
   4969          1.1  christos 	     }
   4970          1.1  christos 
   4971          1.1  christos 	   /* Fake SHT_GROUP section header.  */
   4972          1.1  christos 	  elf_section_data (group)->this_hdr.bfd_section = group;
   4973          1.1  christos 	  elf_section_data (group)->this_hdr.sh_type = SHT_GROUP;
   4974          1.1  christos 	}
   4975      1.1.1.3  christos     }
   4976      1.1.1.3  christos   return TRUE;
   4977          1.1  christos }
   4978          1.1  christos 
   4979          1.1  christos static bfd_boolean
   4980          1.1  christos elfNN_ia64_hpux_vec (const bfd_target *vec)
   4981          1.1  christos {
   4982          1.1  christos   extern const bfd_target ia64_elfNN_hpux_be_vec;
   4983          1.1  christos   return (vec == &ia64_elfNN_hpux_be_vec);
   4984          1.1  christos }
   4985          1.1  christos 
   4986          1.1  christos static void
   4987          1.1  christos elfNN_hpux_post_process_headers (bfd *abfd,
   4988          1.1  christos 				 struct bfd_link_info *info ATTRIBUTE_UNUSED)
   4989          1.1  christos {
   4990          1.1  christos   Elf_Internal_Ehdr *i_ehdrp = elf_elfheader (abfd);
   4991          1.1  christos 
   4992          1.1  christos   i_ehdrp->e_ident[EI_OSABI] = get_elf_backend_data (abfd)->elf_osabi;
   4993          1.1  christos   i_ehdrp->e_ident[EI_ABIVERSION] = 1;
   4994          1.1  christos }
   4995          1.1  christos 
   4996          1.1  christos static bfd_boolean
   4997          1.1  christos elfNN_hpux_backend_section_from_bfd_section (bfd *abfd ATTRIBUTE_UNUSED,
   4998          1.1  christos 					     asection *sec, int *retval)
   4999          1.1  christos {
   5000          1.1  christos   if (bfd_is_com_section (sec))
   5001          1.1  christos     {
   5002          1.1  christos       *retval = SHN_IA_64_ANSI_COMMON;
   5003          1.1  christos       return TRUE;
   5004          1.1  christos     }
   5005          1.1  christos   return FALSE;
   5006          1.1  christos }
   5007          1.1  christos 
   5008          1.1  christos static void
   5009          1.1  christos elfNN_hpux_backend_symbol_processing (bfd *abfd ATTRIBUTE_UNUSED,
   5010          1.1  christos 				      asymbol *asym)
   5011          1.1  christos {
   5012          1.1  christos   elf_symbol_type *elfsym = (elf_symbol_type *) asym;
   5013          1.1  christos 
   5014          1.1  christos   switch (elfsym->internal_elf_sym.st_shndx)
   5015          1.1  christos     {
   5016          1.1  christos     case SHN_IA_64_ANSI_COMMON:
   5017      1.1.1.3  christos       asym->section = bfd_com_section_ptr;
   5018          1.1  christos       asym->value = elfsym->internal_elf_sym.st_size;
   5019      1.1.1.3  christos       asym->flags &= ~BSF_GLOBAL;
   5020          1.1  christos       break;
   5021          1.1  christos     }
   5022          1.1  christos }
   5023          1.1  christos 
   5024          1.1  christos #define TARGET_LITTLE_SYM		ia64_elfNN_le_vec
   5026          1.1  christos #define TARGET_LITTLE_NAME		"elfNN-ia64-little"
   5027          1.1  christos #define TARGET_BIG_SYM			ia64_elfNN_be_vec
   5028          1.1  christos #define TARGET_BIG_NAME			"elfNN-ia64-big"
   5029          1.1  christos #define ELF_ARCH			bfd_arch_ia64
   5030          1.1  christos #define ELF_TARGET_ID			IA64_ELF_DATA
   5031          1.1  christos #define ELF_MACHINE_CODE		EM_IA_64
   5032          1.1  christos #define ELF_MACHINE_ALT1		1999	/* EAS2.3 */
   5033          1.1  christos #define ELF_MACHINE_ALT2		1998	/* EAS2.2 */
   5034          1.1  christos #define ELF_MAXPAGESIZE			0x10000	/* 64KB */
   5035          1.1  christos #define ELF_COMMONPAGESIZE		0x4000	/* 16KB */
   5036          1.1  christos 
   5037          1.1  christos #define elf_backend_section_from_shdr \
   5038          1.1  christos 	elfNN_ia64_section_from_shdr
   5039          1.1  christos #define elf_backend_section_flags \
   5040          1.1  christos 	elfNN_ia64_section_flags
   5041          1.1  christos #define elf_backend_fake_sections \
   5042          1.1  christos 	elfNN_ia64_fake_sections
   5043          1.1  christos #define elf_backend_final_write_processing \
   5044          1.1  christos 	elfNN_ia64_final_write_processing
   5045          1.1  christos #define elf_backend_add_symbol_hook \
   5046          1.1  christos 	elfNN_ia64_add_symbol_hook
   5047          1.1  christos #define elf_backend_additional_program_headers \
   5048          1.1  christos 	elfNN_ia64_additional_program_headers
   5049          1.1  christos #define elf_backend_modify_segment_map \
   5050          1.1  christos 	elfNN_ia64_modify_segment_map
   5051          1.1  christos #define elf_backend_modify_program_headers \
   5052          1.1  christos 	elfNN_ia64_modify_program_headers
   5053          1.1  christos #define elf_info_to_howto \
   5054          1.1  christos 	elfNN_ia64_info_to_howto
   5055          1.1  christos 
   5056          1.1  christos #define bfd_elfNN_bfd_reloc_type_lookup \
   5057          1.1  christos 	ia64_elf_reloc_type_lookup
   5058          1.1  christos #define bfd_elfNN_bfd_reloc_name_lookup \
   5059          1.1  christos 	ia64_elf_reloc_name_lookup
   5060          1.1  christos #define bfd_elfNN_bfd_is_local_label_name \
   5061          1.1  christos 	elfNN_ia64_is_local_label_name
   5062          1.1  christos #define bfd_elfNN_bfd_relax_section \
   5063          1.1  christos 	elfNN_ia64_relax_section
   5064          1.1  christos 
   5065          1.1  christos #define elf_backend_object_p \
   5066          1.1  christos 	elfNN_ia64_object_p
   5067          1.1  christos 
   5068          1.1  christos /* Stuff for the BFD linker: */
   5069          1.1  christos #define bfd_elfNN_bfd_link_hash_table_create \
   5070          1.1  christos 	elfNN_ia64_hash_table_create
   5071          1.1  christos #define elf_backend_create_dynamic_sections \
   5072  1.1.1.5.4.1  christos 	elfNN_ia64_create_dynamic_sections
   5073          1.1  christos #define elf_backend_check_relocs \
   5074          1.1  christos 	elfNN_ia64_check_relocs
   5075          1.1  christos #define elf_backend_adjust_dynamic_symbol \
   5076          1.1  christos 	elfNN_ia64_adjust_dynamic_symbol
   5077          1.1  christos #define elf_backend_size_dynamic_sections \
   5078          1.1  christos 	elfNN_ia64_size_dynamic_sections
   5079          1.1  christos #define elf_backend_omit_section_dynsym \
   5080          1.1  christos 	_bfd_elf_omit_section_dynsym_all
   5081          1.1  christos #define elf_backend_relocate_section \
   5082          1.1  christos 	elfNN_ia64_relocate_section
   5083          1.1  christos #define elf_backend_finish_dynamic_symbol \
   5084          1.1  christos 	elfNN_ia64_finish_dynamic_symbol
   5085          1.1  christos #define elf_backend_finish_dynamic_sections \
   5086          1.1  christos 	elfNN_ia64_finish_dynamic_sections
   5087          1.1  christos #define bfd_elfNN_bfd_final_link \
   5088          1.1  christos 	elfNN_ia64_final_link
   5089          1.1  christos 
   5090  1.1.1.5.4.1  christos #define bfd_elfNN_bfd_merge_private_bfd_data \
   5091          1.1  christos 	elfNN_ia64_merge_private_bfd_data
   5092          1.1  christos #define bfd_elfNN_bfd_set_private_flags \
   5093          1.1  christos 	elfNN_ia64_set_private_flags
   5094          1.1  christos #define bfd_elfNN_bfd_print_private_bfd_data \
   5095          1.1  christos 	elfNN_ia64_print_private_bfd_data
   5096          1.1  christos 
   5097          1.1  christos #define elf_backend_plt_readonly	1
   5098          1.1  christos #define elf_backend_can_gc_sections	1
   5099          1.1  christos #define elf_backend_want_plt_sym	0
   5100          1.1  christos #define elf_backend_plt_alignment	5
   5101          1.1  christos #define elf_backend_got_header_size	0
   5102          1.1  christos #define elf_backend_want_got_plt	1
   5103          1.1  christos #define elf_backend_may_use_rel_p	1
   5104      1.1.1.5  christos #define elf_backend_may_use_rela_p	1
   5105          1.1  christos #define elf_backend_default_use_rela_p	1
   5106          1.1  christos #define elf_backend_want_dynbss		0
   5107          1.1  christos #define elf_backend_copy_indirect_symbol elfNN_ia64_hash_copy_indirect
   5108          1.1  christos #define elf_backend_hide_symbol		elfNN_ia64_hash_hide_symbol
   5109          1.1  christos #define elf_backend_fixup_symbol	_bfd_elf_link_hash_fixup_symbol
   5110          1.1  christos #define elf_backend_reloc_type_class	elfNN_ia64_reloc_type_class
   5111          1.1  christos #define elf_backend_rela_normal		1
   5112          1.1  christos #define elf_backend_dtrel_excludes_plt	1
   5113          1.1  christos #define elf_backend_special_sections	elfNN_ia64_special_sections
   5114          1.1  christos #define elf_backend_default_execstack	0
   5115          1.1  christos 
   5116          1.1  christos /* FIXME: PR 290: The Intel C compiler generates SHT_IA_64_UNWIND with
   5117          1.1  christos    SHF_LINK_ORDER. But it doesn't set the sh_link or sh_info fields.
   5118          1.1  christos    We don't want to flood users with so many error messages. We turn
   5119          1.1  christos    off the warning for now. It will be turned on later when the Intel
   5120          1.1  christos    compiler is fixed.   */
   5121          1.1  christos #define elf_backend_link_order_error_handler NULL
   5122  1.1.1.5.4.1  christos 
   5123  1.1.1.5.4.1  christos #include "elfNN-target.h"
   5124  1.1.1.5.4.1  christos 
   5125          1.1  christos /* HPUX-specific vectors.  */
   5126          1.1  christos 
   5127          1.1  christos #undef  TARGET_LITTLE_SYM
   5128          1.1  christos #undef  TARGET_LITTLE_NAME
   5129          1.1  christos #undef  TARGET_BIG_SYM
   5130          1.1  christos #define TARGET_BIG_SYM			ia64_elfNN_hpux_be_vec
   5131          1.1  christos #undef	TARGET_BIG_NAME
   5132          1.1  christos #define TARGET_BIG_NAME			"elfNN-ia64-hpux-big"
   5133          1.1  christos 
   5134          1.1  christos /* These are HP-UX specific functions.  */
   5135          1.1  christos 
   5136          1.1  christos #undef  elf_backend_post_process_headers
   5137          1.1  christos #define elf_backend_post_process_headers elfNN_hpux_post_process_headers
   5138          1.1  christos 
   5139          1.1  christos #undef  elf_backend_section_from_bfd_section
   5140          1.1  christos #define elf_backend_section_from_bfd_section elfNN_hpux_backend_section_from_bfd_section
   5141          1.1  christos 
   5142          1.1  christos #undef elf_backend_symbol_processing
   5143          1.1  christos #define elf_backend_symbol_processing elfNN_hpux_backend_symbol_processing
   5144          1.1  christos 
   5145          1.1  christos #undef  elf_backend_want_p_paddr_set_to_zero
   5146          1.1  christos #define elf_backend_want_p_paddr_set_to_zero 1
   5147          1.1  christos 
   5148                        #undef ELF_COMMONPAGESIZE
   5149                        #undef ELF_OSABI
   5150                        #define ELF_OSABI			ELFOSABI_HPUX
   5151                        
   5152                        #undef  elfNN_bed
   5153                        #define elfNN_bed elfNN_ia64_hpux_bed
   5154                        
   5155                        #include "elfNN-target.h"
   5156