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