Home | History | Annotate | Line # | Download | only in bfd
elf32-microblaze.c revision 1.1.1.10
      1 /* Xilinx MicroBlaze-specific support for 32-bit ELF
      2 
      3    Copyright (C) 2009-2022 Free Software Foundation, Inc.
      4 
      5    This file is part of BFD, the Binary File Descriptor library.
      6 
      7    This program is free software; you can redistribute it and/or modify
      8    it under the terms of the GNU General Public License as published by
      9    the Free Software Foundation; either version 3 of the License, or
     10    (at your option) any later version.
     11 
     12    This program is distributed in the hope that it will be useful,
     13    but WITHOUT ANY WARRANTY; without even the implied warranty of
     14    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     15    GNU General Public License for more details.
     16 
     17    You should have received a copy of the GNU General Public License
     18    along with this program; if not, write to the
     19    Free Software Foundation, Inc., 51 Franklin Street - Fifth Floor,
     20    Boston, MA 02110-1301, USA.  */
     21 
     22 
     23 #include "sysdep.h"
     24 #include "bfd.h"
     25 #include "bfdlink.h"
     26 #include "libbfd.h"
     27 #include "elf-bfd.h"
     28 #include "elf/microblaze.h"
     29 #include <assert.h>
     30 
     31 #define	USE_RELA	/* Only USE_REL is actually significant, but this is
     32 			   here are a reminder...  */
     33 #define INST_WORD_SIZE 4
     34 
     35 static int ro_small_data_pointer = 0;
     36 static int rw_small_data_pointer = 0;
     37 
     38 static reloc_howto_type * microblaze_elf_howto_table [(int) R_MICROBLAZE_max];
     39 
     40 static reloc_howto_type microblaze_elf_howto_raw[] =
     41 {
     42    /* This reloc does nothing.  */
     43    HOWTO (R_MICROBLAZE_NONE,	/* Type.  */
     44 	  0,			/* Rightshift.  */
     45 	  0,			/* Size.  */
     46 	  0,			/* Bitsize.  */
     47 	  false,		/* PC_relative.  */
     48 	  0,			/* Bitpos.  */
     49 	  complain_overflow_dont,  /* Complain on overflow.  */
     50 	  NULL,			 /* Special Function.  */
     51 	  "R_MICROBLAZE_NONE",	/* Name.  */
     52 	  false,		/* Partial Inplace.  */
     53 	  0,			/* Source Mask.  */
     54 	  0,			/* Dest Mask.  */
     55 	  false),		/* PC relative offset?  */
     56 
     57    /* A standard 32 bit relocation.  */
     58    HOWTO (R_MICROBLAZE_32,	/* Type.  */
     59 	  0,			/* Rightshift.  */
     60 	  4,			/* Size.  */
     61 	  32,			/* Bitsize.  */
     62 	  false,		/* PC_relative.  */
     63 	  0,			/* Bitpos.  */
     64 	  complain_overflow_bitfield, /* Complain on overflow.  */
     65 	  bfd_elf_generic_reloc,/* Special Function.  */
     66 	  "R_MICROBLAZE_32",	/* Name.  */
     67 	  false,		/* Partial Inplace.  */
     68 	  0,			/* Source Mask.  */
     69 	  0xffffffff,		/* Dest Mask.  */
     70 	  false),		/* PC relative offset?  */
     71 
     72    /* A standard PCREL 32 bit relocation.  */
     73    HOWTO (R_MICROBLAZE_32_PCREL,/* Type.  */
     74 	  0,			/* Rightshift.  */
     75 	  4,			/* Size.  */
     76 	  32,			/* Bitsize.  */
     77 	  true,			/* PC_relative.  */
     78 	  0,			/* Bitpos.  */
     79 	  complain_overflow_bitfield, /* Complain on overflow.  */
     80 	  bfd_elf_generic_reloc,/* Special Function.  */
     81 	  "R_MICROBLAZE_32_PCREL",	/* Name.  */
     82 	  true,			/* Partial Inplace.  */
     83 	  0,			/* Source Mask.  */
     84 	  0xffffffff,		/* Dest Mask.  */
     85 	  true),		/* PC relative offset?  */
     86 
     87    /* A 64 bit PCREL relocation.  Table-entry not really used.  */
     88    HOWTO (R_MICROBLAZE_64_PCREL,/* Type.  */
     89 	  0,			/* Rightshift.  */
     90 	  4,			/* Size.  */
     91 	  16,			/* Bitsize.  */
     92 	  true,			/* PC_relative.  */
     93 	  0,			/* Bitpos.  */
     94 	  complain_overflow_dont, /* Complain on overflow.  */
     95 	  bfd_elf_generic_reloc,/* Special Function.  */
     96 	  "R_MICROBLAZE_64_PCREL",	/* Name.  */
     97 	  false,		/* Partial Inplace.  */
     98 	  0,			/* Source Mask.  */
     99 	  0x0000ffff,		/* Dest Mask.  */
    100 	  true),		/* PC relative offset?  */
    101 
    102    /* The low half of a PCREL 32 bit relocation.  */
    103    HOWTO (R_MICROBLAZE_32_PCREL_LO,	/* Type.  */
    104 	  0,			/* Rightshift.  */
    105 	  4,			/* Size.  */
    106 	  16,			/* Bitsize.  */
    107 	  true,			/* PC_relative.  */
    108 	  0,			/* Bitpos.  */
    109 	  complain_overflow_signed, /* Complain on overflow.  */
    110 	  bfd_elf_generic_reloc,	/* Special Function.  */
    111 	  "R_MICROBLAZE_32_PCREL_LO",	/* Name.  */
    112 	  false,		/* Partial Inplace.  */
    113 	  0,			/* Source Mask.  */
    114 	  0x0000ffff,		/* Dest Mask.  */
    115 	  true),		/* PC relative offset?  */
    116 
    117    /* A 64 bit relocation.  Table entry not really used.  */
    118    HOWTO (R_MICROBLAZE_64,	/* Type.  */
    119 	  0,			/* Rightshift.  */
    120 	  4,			/* Size.  */
    121 	  16,			/* Bitsize.  */
    122 	  false,		/* PC_relative.  */
    123 	  0,			/* Bitpos.  */
    124 	  complain_overflow_dont, /* Complain on overflow.  */
    125 	  bfd_elf_generic_reloc,/* Special Function.  */
    126 	  "R_MICROBLAZE_64",	/* Name.  */
    127 	  false,		/* Partial Inplace.  */
    128 	  0,			/* Source Mask.  */
    129 	  0x0000ffff,		/* Dest Mask.  */
    130 	  false),		/* PC relative offset?  */
    131 
    132    /* The low half of a 32 bit relocation.  */
    133    HOWTO (R_MICROBLAZE_32_LO,	/* Type.  */
    134 	  0,			/* Rightshift.  */
    135 	  4,			/* Size.  */
    136 	  16,			/* Bitsize.  */
    137 	  false,		/* PC_relative.  */
    138 	  0,			/* Bitpos.  */
    139 	  complain_overflow_signed, /* Complain on overflow.  */
    140 	  bfd_elf_generic_reloc,/* Special Function.  */
    141 	  "R_MICROBLAZE_32_LO", /* Name.  */
    142 	  false,		/* Partial Inplace.  */
    143 	  0,			/* Source Mask.  */
    144 	  0x0000ffff,		/* Dest Mask.  */
    145 	  false),		/* PC relative offset?  */
    146 
    147    /* Read-only small data section relocation.  */
    148    HOWTO (R_MICROBLAZE_SRO32,	/* Type.  */
    149 	  0,			/* Rightshift.  */
    150 	  4,			/* Size.  */
    151 	  16,			/* Bitsize.  */
    152 	  false,		/* PC_relative.  */
    153 	  0,			/* Bitpos.  */
    154 	  complain_overflow_bitfield, /* Complain on overflow.  */
    155 	  bfd_elf_generic_reloc,/* Special Function.  */
    156 	  "R_MICROBLAZE_SRO32", /* Name.  */
    157 	  false,		/* Partial Inplace.  */
    158 	  0,			/* Source Mask.  */
    159 	  0x0000ffff,		/* Dest Mask.  */
    160 	  false),		/* PC relative offset?  */
    161 
    162    /* Read-write small data area relocation.  */
    163    HOWTO (R_MICROBLAZE_SRW32,	/* Type.  */
    164 	  0,			/* Rightshift.  */
    165 	  4,			/* Size.  */
    166 	  16,			/* Bitsize.  */
    167 	  false,		/* PC_relative.  */
    168 	  0,			/* Bitpos.  */
    169 	  complain_overflow_bitfield, /* Complain on overflow.  */
    170 	  bfd_elf_generic_reloc,/* Special Function.  */
    171 	  "R_MICROBLAZE_SRW32", /* Name.  */
    172 	  false,		/* Partial Inplace.  */
    173 	  0,			/* Source Mask.  */
    174 	  0x0000ffff,		/* Dest Mask.  */
    175 	  false),		/* PC relative offset?  */
    176 
    177    /* This reloc does nothing.	Used for relaxation.  */
    178    HOWTO (R_MICROBLAZE_64_NONE,	/* Type.  */
    179 	  0,			/* Rightshift.  */
    180 	  0,			/* Size.  */
    181 	  0,			/* Bitsize.  */
    182 	  true,			/* PC_relative.  */
    183 	  0,			/* Bitpos.  */
    184 	  complain_overflow_dont, /* Complain on overflow.  */
    185 	  NULL,			 /* Special Function.  */
    186 	  "R_MICROBLAZE_64_NONE",/* Name.  */
    187 	  false,		/* Partial Inplace.  */
    188 	  0,			/* Source Mask.  */
    189 	  0,			/* Dest Mask.  */
    190 	  false),		/* PC relative offset?  */
    191 
    192    /* Symbol Op Symbol relocation.  */
    193    HOWTO (R_MICROBLAZE_32_SYM_OP_SYM,		/* Type.  */
    194 	  0,			/* Rightshift.  */
    195 	  4,			/* Size.  */
    196 	  32,			/* Bitsize.  */
    197 	  false,		/* PC_relative.  */
    198 	  0,			/* Bitpos.  */
    199 	  complain_overflow_bitfield, /* Complain on overflow.  */
    200 	  bfd_elf_generic_reloc,/* Special Function.  */
    201 	  "R_MICROBLAZE_32_SYM_OP_SYM",		/* Name.  */
    202 	  false,		/* Partial Inplace.  */
    203 	  0,			/* Source Mask.  */
    204 	  0xffffffff,		/* Dest Mask.  */
    205 	  false),		/* PC relative offset?  */
    206 
    207    /* GNU extension to record C++ vtable hierarchy.  */
    208    HOWTO (R_MICROBLAZE_GNU_VTINHERIT, /* Type.  */
    209 	  0,			 /* Rightshift.  */
    210 	  4,			 /* Size.  */
    211 	  0,			 /* Bitsize.  */
    212 	  false,		 /* PC_relative.  */
    213 	  0,			 /* Bitpos.  */
    214 	  complain_overflow_dont,/* Complain on overflow.  */
    215 	  NULL,			 /* Special Function.  */
    216 	  "R_MICROBLAZE_GNU_VTINHERIT", /* Name.  */
    217 	  false,		 /* Partial Inplace.  */
    218 	  0,			 /* Source Mask.  */
    219 	  0,			 /* Dest Mask.  */
    220 	  false),		 /* PC relative offset?  */
    221 
    222    /* GNU extension to record C++ vtable member usage.  */
    223    HOWTO (R_MICROBLAZE_GNU_VTENTRY,   /* Type.  */
    224 	  0,			 /* Rightshift.  */
    225 	  4,			 /* Size.  */
    226 	  0,			 /* Bitsize.  */
    227 	  false,		 /* PC_relative.  */
    228 	  0,			 /* Bitpos.  */
    229 	  complain_overflow_dont,/* Complain on overflow.  */
    230 	  _bfd_elf_rel_vtable_reloc_fn,	 /* Special Function.  */
    231 	  "R_MICROBLAZE_GNU_VTENTRY", /* Name.  */
    232 	  false,		 /* Partial Inplace.  */
    233 	  0,			 /* Source Mask.  */
    234 	  0,			 /* Dest Mask.  */
    235 	  false),		 /* PC relative offset?  */
    236 
    237    /* A 64 bit GOTPC relocation.  Table-entry not really used.  */
    238    HOWTO (R_MICROBLAZE_GOTPC_64,	/* Type.  */
    239 	  0,			/* Rightshift.  */
    240 	  4,			/* Size.  */
    241 	  16,			/* Bitsize.  */
    242 	  true,			/* PC_relative.  */
    243 	  0,			/* Bitpos.  */
    244 	  complain_overflow_dont, /* Complain on overflow.  */
    245 	  bfd_elf_generic_reloc,	/* Special Function.  */
    246 	  "R_MICROBLAZE_GOTPC_64",	/* Name.  */
    247 	  false,		/* Partial Inplace.  */
    248 	  0,			/* Source Mask.  */
    249 	  0x0000ffff,		/* Dest Mask.  */
    250 	  true),		/* PC relative offset?  */
    251 
    252      /* A 64 bit TEXTPCREL relocation.  Table-entry not really used.  */
    253    HOWTO (R_MICROBLAZE_TEXTPCREL_64,	/* Type.  */
    254 	  0,			/* Rightshift.  */
    255 	  4,			/* Size.  */
    256 	  16,			/* Bitsize.  */
    257 	  true,			/* PC_relative.  */
    258 	  0,			/* Bitpos.  */
    259 	  complain_overflow_dont, /* Complain on overflow.  */
    260 	  bfd_elf_generic_reloc,	/* Special Function.  */
    261 	  "R_MICROBLAZE_TEXTPCREL_64",	/* Name.  */
    262 	  false,		/* Partial Inplace.  */
    263 	  0,			/* Source Mask.  */
    264 	  0x0000ffff,		/* Dest Mask.  */
    265 	  true),		/* PC relative offset?  */
    266 
    267    /* A 64 bit GOT relocation.  Table-entry not really used.  */
    268    HOWTO (R_MICROBLAZE_GOT_64,  /* Type.  */
    269 	  0,			/* Rightshift.  */
    270 	  4,			/* Size.  */
    271 	  16,			/* Bitsize.  */
    272 	  false,		/* PC_relative.  */
    273 	  0,			/* Bitpos.  */
    274 	  complain_overflow_dont, /* Complain on overflow.  */
    275 	  bfd_elf_generic_reloc,/* Special Function.  */
    276 	  "R_MICROBLAZE_GOT_64",/* Name.  */
    277 	  false,		/* Partial Inplace.  */
    278 	  0,			/* Source Mask.  */
    279 	  0x0000ffff,		/* Dest Mask.  */
    280 	  false),		/* PC relative offset?  */
    281 
    282     /* A 64 bit TEXTREL relocation.  Table-entry not really used.  */
    283    HOWTO (R_MICROBLAZE_TEXTREL_64,  /* Type.  */
    284 	  0,			/* Rightshift.  */
    285 	  4,			/* Size.  */
    286 	  16,			/* Bitsize.  */
    287 	  false,		/* PC_relative.  */
    288 	  0,			/* Bitpos.  */
    289 	  complain_overflow_dont, /* Complain on overflow.  */
    290 	  bfd_elf_generic_reloc,/* Special Function.  */
    291 	  "R_MICROBLAZE_TEXTREL_64",/* Name.  */
    292 	  false,		/* Partial Inplace.  */
    293 	  0,			/* Source Mask.  */
    294 	  0x0000ffff,		/* Dest Mask.  */
    295 	  false),		/* PC relative offset?  */
    296 
    297    /* A 64 bit PLT relocation.  Table-entry not really used.  */
    298    HOWTO (R_MICROBLAZE_PLT_64,  /* Type.  */
    299 	  0,			/* Rightshift.  */
    300 	  4,			/* Size.  */
    301 	  16,			/* Bitsize.  */
    302 	  true,			/* PC_relative.  */
    303 	  0,			/* Bitpos.  */
    304 	  complain_overflow_dont, /* Complain on overflow.  */
    305 	  bfd_elf_generic_reloc,/* Special Function.  */
    306 	  "R_MICROBLAZE_PLT_64",/* Name.  */
    307 	  false,		/* Partial Inplace.  */
    308 	  0,			/* Source Mask.  */
    309 	  0x0000ffff,		/* Dest Mask.  */
    310 	  true),		/* PC relative offset?  */
    311 
    312    /*  Table-entry not really used.  */
    313    HOWTO (R_MICROBLAZE_REL,	/* Type.  */
    314 	  0,			/* Rightshift.  */
    315 	  4,			/* Size.  */
    316 	  16,			/* Bitsize.  */
    317 	  true,			/* PC_relative.  */
    318 	  0,			/* Bitpos.  */
    319 	  complain_overflow_dont, /* Complain on overflow.  */
    320 	  bfd_elf_generic_reloc,/* Special Function.  */
    321 	  "R_MICROBLAZE_REL",	/* Name.  */
    322 	  false,		/* Partial Inplace.  */
    323 	  0,			/* Source Mask.  */
    324 	  0x0000ffff,		/* Dest Mask.  */
    325 	  true),		/* PC relative offset?  */
    326 
    327    /*  Table-entry not really used.  */
    328    HOWTO (R_MICROBLAZE_JUMP_SLOT,/* Type.  */
    329 	  0,			/* Rightshift.  */
    330 	  4,			/* Size.  */
    331 	  16,			/* Bitsize.  */
    332 	  true,			/* PC_relative.  */
    333 	  0,			/* Bitpos.  */
    334 	  complain_overflow_dont, /* Complain on overflow.  */
    335 	  bfd_elf_generic_reloc,/* Special Function.  */
    336 	  "R_MICROBLAZE_JUMP_SLOT",	/* Name.  */
    337 	  false,		/* Partial Inplace.  */
    338 	  0,			/* Source Mask.  */
    339 	  0x0000ffff,		/* Dest Mask.  */
    340 	  true),		/* PC relative offset?  */
    341 
    342    /*  Table-entry not really used.  */
    343    HOWTO (R_MICROBLAZE_GLOB_DAT,/* Type.  */
    344 	  0,			/* Rightshift.  */
    345 	  4,			/* Size.  */
    346 	  16,			/* Bitsize.  */
    347 	  true,			/* PC_relative.  */
    348 	  0,			/* Bitpos.  */
    349 	  complain_overflow_dont, /* Complain on overflow.  */
    350 	  bfd_elf_generic_reloc,/* Special Function.  */
    351 	  "R_MICROBLAZE_GLOB_DAT",	/* Name.  */
    352 	  false,		/* Partial Inplace.  */
    353 	  0,			/* Source Mask.  */
    354 	  0x0000ffff,		/* Dest Mask.  */
    355 	  true),		/* PC relative offset?  */
    356 
    357    /* A 64 bit GOT relative relocation.  Table-entry not really used.  */
    358    HOWTO (R_MICROBLAZE_GOTOFF_64,	/* Type.  */
    359 	  0,			/* Rightshift.  */
    360 	  4,			/* Size.  */
    361 	  16,			/* Bitsize.  */
    362 	  false,		/* PC_relative.  */
    363 	  0,			/* Bitpos.  */
    364 	  complain_overflow_dont, /* Complain on overflow.  */
    365 	  bfd_elf_generic_reloc,/* Special Function.  */
    366 	  "R_MICROBLAZE_GOTOFF_64",	/* Name.  */
    367 	  false,		/* Partial Inplace.  */
    368 	  0,			/* Source Mask.  */
    369 	  0x0000ffff,		/* Dest Mask.  */
    370 	  false),		/* PC relative offset?  */
    371 
    372    /* A 32 bit GOT relative relocation.  Table-entry not really used.  */
    373    HOWTO (R_MICROBLAZE_GOTOFF_32,	/* Type.  */
    374 	  0,			/* Rightshift.  */
    375 	  4,			/* Size.  */
    376 	  16,			/* Bitsize.  */
    377 	  false,		/* PC_relative.  */
    378 	  0,			/* Bitpos.  */
    379 	  complain_overflow_dont, /* Complain on overflow.  */
    380 	  bfd_elf_generic_reloc,	/* Special Function.  */
    381 	  "R_MICROBLAZE_GOTOFF_32",	/* Name.  */
    382 	  false,		/* Partial Inplace.  */
    383 	  0,			/* Source Mask.  */
    384 	  0x0000ffff,		/* Dest Mask.  */
    385 	  false),		/* PC relative offset?  */
    386 
    387    /* COPY relocation.  Table-entry not really used.  */
    388    HOWTO (R_MICROBLAZE_COPY,	/* Type.  */
    389 	  0,			/* Rightshift.  */
    390 	  4,			/* Size.  */
    391 	  16,			/* Bitsize.  */
    392 	  false,		/* PC_relative.  */
    393 	  0,			/* Bitpos.  */
    394 	  complain_overflow_dont, /* Complain on overflow.  */
    395 	  bfd_elf_generic_reloc,/* Special Function.  */
    396 	  "R_MICROBLAZE_COPY",	/* Name.  */
    397 	  false,		/* Partial Inplace.  */
    398 	  0,			/* Source Mask.  */
    399 	  0x0000ffff,		/* Dest Mask.  */
    400 	  false),		/* PC relative offset?  */
    401 
    402    /* Marker relocs for TLS.  */
    403    HOWTO (R_MICROBLAZE_TLS,
    404 	 0,			/* rightshift */
    405 	 4,			/* size */
    406 	 32,			/* bitsize */
    407 	 false,			/* pc_relative */
    408 	 0,			/* bitpos */
    409 	 complain_overflow_dont, /* complain_on_overflow */
    410 	 bfd_elf_generic_reloc,	/* special_function */
    411 	 "R_MICROBLAZE_TLS",		/* name */
    412 	 false,			/* partial_inplace */
    413 	 0,			/* src_mask */
    414 	 0x0000ffff,			/* dst_mask */
    415 	 false),		/* pcrel_offset */
    416 
    417    HOWTO (R_MICROBLAZE_TLSGD,
    418 	 0,			/* rightshift */
    419 	 4,			/* size */
    420 	 32,			/* bitsize */
    421 	 false,			/* pc_relative */
    422 	 0,			/* bitpos */
    423 	 complain_overflow_dont, /* complain_on_overflow */
    424 	 bfd_elf_generic_reloc, /* special_function */
    425 	 "R_MICROBLAZE_TLSGD",		/* name */
    426 	 false,			/* partial_inplace */
    427 	 0,			/* src_mask */
    428 	 0x0000ffff,			/* dst_mask */
    429 	 false),		/* pcrel_offset */
    430 
    431    HOWTO (R_MICROBLAZE_TLSLD,
    432 	 0,			/* rightshift */
    433 	 4,			/* size */
    434 	 32,			/* bitsize */
    435 	 false,			/* pc_relative */
    436 	 0,			/* bitpos */
    437 	 complain_overflow_dont, /* complain_on_overflow */
    438 	 bfd_elf_generic_reloc, /* special_function */
    439 	 "R_MICROBLAZE_TLSLD",		/* name */
    440 	 false,			/* partial_inplace */
    441 	 0,			/* src_mask */
    442 	 0x0000ffff,		/* dst_mask */
    443 	 false),		/* pcrel_offset */
    444 
    445    /* Computes the load module index of the load module that contains the
    446       definition of its TLS sym.  */
    447    HOWTO (R_MICROBLAZE_TLSDTPMOD32,
    448 	 0,			/* rightshift */
    449 	 4,			/* size */
    450 	 32,			/* bitsize */
    451 	 false,			/* pc_relative */
    452 	 0,			/* bitpos */
    453 	 complain_overflow_dont, /* complain_on_overflow */
    454 	 bfd_elf_generic_reloc, /* special_function */
    455 	 "R_MICROBLAZE_TLSDTPMOD32",	/* name */
    456 	 false,			/* partial_inplace */
    457 	 0,			/* src_mask */
    458 	 0x0000ffff,		/* dst_mask */
    459 	 false),		/* pcrel_offset */
    460 
    461    /* Computes a dtv-relative displacement, the difference between the value
    462       of sym+add and the base address of the thread-local storage block that
    463       contains the definition of sym, minus 0x8000.  Used for initializing GOT */
    464    HOWTO (R_MICROBLAZE_TLSDTPREL32,
    465 	 0,			/* rightshift */
    466 	 4,			/* size */
    467 	 32,			/* bitsize */
    468 	 false,			/* pc_relative */
    469 	 0,			/* bitpos */
    470 	 complain_overflow_dont, /* complain_on_overflow */
    471 	 bfd_elf_generic_reloc, /* special_function */
    472 	 "R_MICROBLAZE_TLSDTPREL32",	/* name */
    473 	 false,			/* partial_inplace */
    474 	 0,			/* src_mask */
    475 	 0x0000ffff,		/* dst_mask */
    476 	 false),		/* pcrel_offset */
    477 
    478    /* Computes a dtv-relative displacement, the difference between the value
    479       of sym+add and the base address of the thread-local storage block that
    480       contains the definition of sym, minus 0x8000.  */
    481    HOWTO (R_MICROBLAZE_TLSDTPREL64,
    482 	 0,			/* rightshift */
    483 	 4,			/* size */
    484 	 32,			/* bitsize */
    485 	 false,			/* pc_relative */
    486 	 0,			/* bitpos */
    487 	 complain_overflow_dont, /* complain_on_overflow */
    488 	 bfd_elf_generic_reloc, /* special_function */
    489 	 "R_MICROBLAZE_TLSDTPREL64",	/* name */
    490 	 false,			/* partial_inplace */
    491 	 0,			/* src_mask */
    492 	 0x0000ffff,		/* dst_mask */
    493 	 false),		/* pcrel_offset */
    494 
    495    /* Computes a tp-relative displacement, the difference between the value of
    496       sym+add and the value of the thread pointer (r13).  */
    497    HOWTO (R_MICROBLAZE_TLSGOTTPREL32,
    498 	 0,			/* rightshift */
    499 	 4,			/* size */
    500 	 32,			/* bitsize */
    501 	 false,			/* pc_relative */
    502 	 0,			/* bitpos */
    503 	 complain_overflow_dont, /* complain_on_overflow */
    504 	 bfd_elf_generic_reloc, /* special_function */
    505 	 "R_MICROBLAZE_TLSGOTTPREL32",	/* name */
    506 	 false,			/* partial_inplace */
    507 	 0,			/* src_mask */
    508 	 0x0000ffff,		/* dst_mask */
    509 	 false),		/* pcrel_offset */
    510 
    511    /* Computes a tp-relative displacement, the difference between the value of
    512       sym+add and the value of the thread pointer (r13).  */
    513    HOWTO (R_MICROBLAZE_TLSTPREL32,
    514 	 0,			/* rightshift */
    515 	 4,			/* size */
    516 	 32,			/* bitsize */
    517 	 false,			/* pc_relative */
    518 	 0,			/* bitpos */
    519 	 complain_overflow_dont, /* complain_on_overflow */
    520 	 bfd_elf_generic_reloc, /* special_function */
    521 	 "R_MICROBLAZE_TLSTPREL32",	/* name */
    522 	 false,			/* partial_inplace */
    523 	 0,			/* src_mask */
    524 	 0x0000ffff,		/* dst_mask */
    525 	 false),		/* pcrel_offset */
    526 
    527 };
    528 
    529 #ifndef NUM_ELEM
    530 #define NUM_ELEM(a) (sizeof (a) / sizeof (a)[0])
    531 #endif
    532 
    533 /* Initialize the microblaze_elf_howto_table, so that linear accesses can be done.  */
    535 
    536 static void
    537 microblaze_elf_howto_init (void)
    538 {
    539   unsigned int i;
    540 
    541   for (i = NUM_ELEM (microblaze_elf_howto_raw); i--;)
    542     {
    543       unsigned int type;
    544 
    545       type = microblaze_elf_howto_raw[i].type;
    546 
    547       BFD_ASSERT (type < NUM_ELEM (microblaze_elf_howto_table));
    548 
    549       microblaze_elf_howto_table [type] = & microblaze_elf_howto_raw [i];
    550     }
    551 }
    552 
    553 static reloc_howto_type *
    555 microblaze_elf_reloc_type_lookup (bfd * abfd ATTRIBUTE_UNUSED,
    556 				  bfd_reloc_code_real_type code)
    557 {
    558   enum elf_microblaze_reloc_type microblaze_reloc = R_MICROBLAZE_NONE;
    559 
    560   switch (code)
    561     {
    562     case BFD_RELOC_NONE:
    563       microblaze_reloc = R_MICROBLAZE_NONE;
    564       break;
    565     case BFD_RELOC_MICROBLAZE_64_NONE:
    566       microblaze_reloc = R_MICROBLAZE_64_NONE;
    567       break;
    568     case BFD_RELOC_32:
    569       microblaze_reloc = R_MICROBLAZE_32;
    570       break;
    571       /* RVA is treated the same as 32 */
    572     case BFD_RELOC_RVA:
    573       microblaze_reloc = R_MICROBLAZE_32;
    574       break;
    575     case BFD_RELOC_32_PCREL:
    576       microblaze_reloc = R_MICROBLAZE_32_PCREL;
    577       break;
    578     case BFD_RELOC_64_PCREL:
    579       microblaze_reloc = R_MICROBLAZE_64_PCREL;
    580       break;
    581     case BFD_RELOC_MICROBLAZE_32_LO_PCREL:
    582       microblaze_reloc = R_MICROBLAZE_32_PCREL_LO;
    583       break;
    584     case BFD_RELOC_64:
    585       microblaze_reloc = R_MICROBLAZE_64;
    586       break;
    587     case BFD_RELOC_MICROBLAZE_32_LO:
    588       microblaze_reloc = R_MICROBLAZE_32_LO;
    589       break;
    590     case BFD_RELOC_MICROBLAZE_32_ROSDA:
    591       microblaze_reloc = R_MICROBLAZE_SRO32;
    592       break;
    593     case BFD_RELOC_MICROBLAZE_32_RWSDA:
    594       microblaze_reloc = R_MICROBLAZE_SRW32;
    595       break;
    596     case BFD_RELOC_MICROBLAZE_32_SYM_OP_SYM:
    597       microblaze_reloc = R_MICROBLAZE_32_SYM_OP_SYM;
    598       break;
    599     case BFD_RELOC_VTABLE_INHERIT:
    600       microblaze_reloc = R_MICROBLAZE_GNU_VTINHERIT;
    601       break;
    602     case BFD_RELOC_VTABLE_ENTRY:
    603       microblaze_reloc = R_MICROBLAZE_GNU_VTENTRY;
    604       break;
    605     case BFD_RELOC_MICROBLAZE_64_GOTPC:
    606       microblaze_reloc = R_MICROBLAZE_GOTPC_64;
    607       break;
    608     case BFD_RELOC_MICROBLAZE_64_GOT:
    609       microblaze_reloc = R_MICROBLAZE_GOT_64;
    610       break;
    611     case BFD_RELOC_MICROBLAZE_64_TEXTPCREL:
    612       microblaze_reloc = R_MICROBLAZE_TEXTPCREL_64;
    613       break;
    614     case BFD_RELOC_MICROBLAZE_64_TEXTREL:
    615       microblaze_reloc = R_MICROBLAZE_TEXTREL_64;
    616       break;
    617     case BFD_RELOC_MICROBLAZE_64_PLT:
    618       microblaze_reloc = R_MICROBLAZE_PLT_64;
    619       break;
    620     case BFD_RELOC_MICROBLAZE_64_GOTOFF:
    621       microblaze_reloc = R_MICROBLAZE_GOTOFF_64;
    622       break;
    623     case BFD_RELOC_MICROBLAZE_32_GOTOFF:
    624       microblaze_reloc = R_MICROBLAZE_GOTOFF_32;
    625       break;
    626     case BFD_RELOC_MICROBLAZE_64_TLSGD:
    627       microblaze_reloc = R_MICROBLAZE_TLSGD;
    628       break;
    629     case BFD_RELOC_MICROBLAZE_64_TLSLD:
    630       microblaze_reloc = R_MICROBLAZE_TLSLD;
    631       break;
    632     case BFD_RELOC_MICROBLAZE_32_TLSDTPREL:
    633       microblaze_reloc = R_MICROBLAZE_TLSDTPREL32;
    634       break;
    635     case BFD_RELOC_MICROBLAZE_64_TLSDTPREL:
    636       microblaze_reloc = R_MICROBLAZE_TLSDTPREL64;
    637       break;
    638     case BFD_RELOC_MICROBLAZE_32_TLSDTPMOD:
    639       microblaze_reloc = R_MICROBLAZE_TLSDTPMOD32;
    640       break;
    641     case BFD_RELOC_MICROBLAZE_64_TLSGOTTPREL:
    642       microblaze_reloc = R_MICROBLAZE_TLSGOTTPREL32;
    643       break;
    644     case BFD_RELOC_MICROBLAZE_64_TLSTPREL:
    645       microblaze_reloc = R_MICROBLAZE_TLSTPREL32;
    646       break;
    647     case BFD_RELOC_MICROBLAZE_COPY:
    648       microblaze_reloc = R_MICROBLAZE_COPY;
    649       break;
    650     default:
    651       return (reloc_howto_type *) NULL;
    652     }
    653 
    654   if (!microblaze_elf_howto_table [R_MICROBLAZE_32])
    655     /* Initialize howto table if needed.  */
    656     microblaze_elf_howto_init ();
    657 
    658   return microblaze_elf_howto_table [(int) microblaze_reloc];
    659 };
    660 
    661 static reloc_howto_type *
    662 microblaze_elf_reloc_name_lookup (bfd *abfd ATTRIBUTE_UNUSED,
    663 				  const char *r_name)
    664 {
    665   unsigned int i;
    666 
    667   for (i = 0; i < NUM_ELEM (microblaze_elf_howto_raw); i++)
    668     if (microblaze_elf_howto_raw[i].name != NULL
    669 	&& strcasecmp (microblaze_elf_howto_raw[i].name, r_name) == 0)
    670       return &microblaze_elf_howto_raw[i];
    671 
    672   return NULL;
    673 }
    674 
    675 /* Set the howto pointer for a RCE ELF reloc.  */
    676 
    677 static bool
    678 microblaze_elf_info_to_howto (bfd * abfd,
    679 			      arelent * cache_ptr,
    680 			      Elf_Internal_Rela * dst)
    681 {
    682   unsigned int r_type;
    683 
    684   if (!microblaze_elf_howto_table [R_MICROBLAZE_32])
    685     /* Initialize howto table if needed.  */
    686     microblaze_elf_howto_init ();
    687 
    688   r_type = ELF32_R_TYPE (dst->r_info);
    689   if (r_type >= R_MICROBLAZE_max)
    690     {
    691       /* xgettext:c-format */
    692       _bfd_error_handler (_("%pB: unsupported relocation type %#x"),
    693 			  abfd, r_type);
    694       bfd_set_error (bfd_error_bad_value);
    695       return false;
    696     }
    697 
    698   cache_ptr->howto = microblaze_elf_howto_table [r_type];
    699   return true;
    700 }
    701 
    702 /* Relax table contains information about instructions which can
    703    be removed by relaxation -- replacing a long address with a
    704    short address.  */
    705 struct relax_table
    706 {
    707   /* Address where bytes may be deleted.  */
    708   bfd_vma addr;
    709 
    710   /* Number of bytes to be deleted.  */
    711   size_t size;
    712 };
    713 
    714 struct _microblaze_elf_section_data
    715 {
    716   struct bfd_elf_section_data elf;
    717   /* Count of used relaxation table entries.  */
    718   size_t relax_count;
    719   /* Relaxation table.  */
    720   struct relax_table *relax;
    721 };
    722 
    723 #define microblaze_elf_section_data(sec) \
    724   ((struct _microblaze_elf_section_data *) elf_section_data (sec))
    725 
    726 static bool
    727 microblaze_elf_new_section_hook (bfd *abfd, asection *sec)
    728 {
    729   if (!sec->used_by_bfd)
    730     {
    731       struct _microblaze_elf_section_data *sdata;
    732       size_t amt = sizeof (*sdata);
    733 
    734       sdata = bfd_zalloc (abfd, amt);
    735       if (sdata == NULL)
    736 	return false;
    737       sec->used_by_bfd = sdata;
    738     }
    739 
    740   return _bfd_elf_new_section_hook (abfd, sec);
    741 }
    742 
    743 /* Microblaze ELF local labels start with 'L.' or '$L', not '.L'.  */
    744 
    745 static bool
    746 microblaze_elf_is_local_label_name (bfd *abfd, const char *name)
    747 {
    748   if (name[0] == 'L' && name[1] == '.')
    749     return true;
    750 
    751   if (name[0] == '$' && name[1] == 'L')
    752     return true;
    753 
    754   /* With gcc, the labels go back to starting with '.', so we accept
    755      the generic ELF local label syntax as well.  */
    756   return _bfd_elf_is_local_label_name (abfd, name);
    757 }
    758 
    759 /* ELF linker hash entry.  */
    760 
    761 struct elf32_mb_link_hash_entry
    762 {
    763   struct elf_link_hash_entry elf;
    764 
    765   /* TLS Reference Types for the symbol; Updated by check_relocs */
    766 #define TLS_GD     1  /* GD reloc. */
    767 #define TLS_LD     2  /* LD reloc. */
    768 #define TLS_TPREL  4  /* TPREL reloc, => IE. */
    769 #define TLS_DTPREL 8  /* DTPREL reloc, => LD. */
    770 #define TLS_TLS    16 /* Any TLS reloc.  */
    771   unsigned char tls_mask;
    772 
    773 };
    774 
    775 #define IS_TLS_GD(x)     (x == (TLS_TLS | TLS_GD))
    776 #define IS_TLS_LD(x)     (x == (TLS_TLS | TLS_LD))
    777 #define IS_TLS_DTPREL(x) (x == (TLS_TLS | TLS_DTPREL))
    778 #define IS_TLS_NONE(x)   (x == 0)
    779 
    780 #define elf32_mb_hash_entry(ent) ((struct elf32_mb_link_hash_entry *)(ent))
    781 
    782 /* ELF linker hash table.  */
    783 
    784 struct elf32_mb_link_hash_table
    785 {
    786   struct elf_link_hash_table elf;
    787 
    788   /* TLS Local Dynamic GOT Entry */
    789   union {
    790     bfd_signed_vma refcount;
    791     bfd_vma offset;
    792   } tlsld_got;
    793 };
    794 
    795 /* Nonzero if this section has TLS related relocations.  */
    796 #define has_tls_reloc sec_flg0
    797 
    798 /* Get the ELF linker hash table from a link_info structure.  */
    799 
    800 #define elf32_mb_hash_table(p) \
    801   ((is_elf_hash_table ((p)->hash)					\
    802     && elf_hash_table_id (elf_hash_table (p)) == MICROBLAZE_ELF_DATA)	\
    803    ? (struct elf32_mb_link_hash_table *) (p)->hash : NULL)
    804 
    805 /* Create an entry in a microblaze ELF linker hash table.  */
    806 
    807 static struct bfd_hash_entry *
    808 link_hash_newfunc (struct bfd_hash_entry *entry,
    809 		   struct bfd_hash_table *table,
    810 		   const char *string)
    811 {
    812   /* Allocate the structure if it has not already been allocated by a
    813      subclass.  */
    814   if (entry == NULL)
    815     {
    816       entry = bfd_hash_allocate (table,
    817 				 sizeof (struct elf32_mb_link_hash_entry));
    818       if (entry == NULL)
    819 	return entry;
    820     }
    821 
    822   /* Call the allocation method of the superclass.  */
    823   entry = _bfd_elf_link_hash_newfunc (entry, table, string);
    824   if (entry != NULL)
    825     {
    826       struct elf32_mb_link_hash_entry *eh;
    827 
    828       eh = (struct elf32_mb_link_hash_entry *) entry;
    829       eh->tls_mask = 0;
    830     }
    831 
    832   return entry;
    833 }
    834 
    835 /* Create a mb ELF linker hash table.  */
    836 
    837 static struct bfd_link_hash_table *
    838 microblaze_elf_link_hash_table_create (bfd *abfd)
    839 {
    840   struct elf32_mb_link_hash_table *ret;
    841   size_t amt = sizeof (struct elf32_mb_link_hash_table);
    842 
    843   ret = (struct elf32_mb_link_hash_table *) bfd_zmalloc (amt);
    844   if (ret == NULL)
    845     return NULL;
    846 
    847   if (!_bfd_elf_link_hash_table_init (&ret->elf, abfd, link_hash_newfunc,
    848 				      sizeof (struct elf32_mb_link_hash_entry),
    849 				      MICROBLAZE_ELF_DATA))
    850     {
    851       free (ret);
    852       return NULL;
    853     }
    854 
    855   return &ret->elf.root;
    856 }
    857 
    858 /* Set the values of the small data pointers.  */
    860 
    861 static void
    862 microblaze_elf_final_sdp (struct bfd_link_info *info)
    863 {
    864   struct bfd_link_hash_entry *h;
    865 
    866   h = bfd_link_hash_lookup (info->hash, RO_SDA_ANCHOR_NAME, false, false, true);
    867   if (h != (struct bfd_link_hash_entry *) NULL
    868       && h->type == bfd_link_hash_defined)
    869     ro_small_data_pointer = (h->u.def.value
    870 			     + h->u.def.section->output_section->vma
    871 			     + h->u.def.section->output_offset);
    872 
    873   h = bfd_link_hash_lookup (info->hash, RW_SDA_ANCHOR_NAME, false, false, true);
    874   if (h != (struct bfd_link_hash_entry *) NULL
    875       && h->type == bfd_link_hash_defined)
    876     rw_small_data_pointer = (h->u.def.value
    877 			     + h->u.def.section->output_section->vma
    878 			     + h->u.def.section->output_offset);
    879 }
    880 
    881 static bfd_vma
    882 dtprel_base (struct bfd_link_info *info)
    883 {
    884   /* If tls_sec is NULL, we should have signalled an error already.  */
    885   if (elf_hash_table (info)->tls_sec == NULL)
    886     return 0;
    887   return elf_hash_table (info)->tls_sec->vma;
    888 }
    889 
    890 /* The size of the thread control block.  */
    891 #define TCB_SIZE	8
    892 
    893 /* Output a simple dynamic relocation into SRELOC.  */
    894 
    895 static void
    896 microblaze_elf_output_dynamic_relocation (bfd *output_bfd,
    897 					  asection *sreloc,
    898 					  unsigned long reloc_index,
    899 					  unsigned long indx,
    900 					  int r_type,
    901 					  bfd_vma offset,
    902 					  bfd_vma addend)
    903 {
    904 
    905   Elf_Internal_Rela rel;
    906 
    907   rel.r_info = ELF32_R_INFO (indx, r_type);
    908   rel.r_offset = offset;
    909   rel.r_addend = addend;
    910 
    911   bfd_elf32_swap_reloca_out (output_bfd, &rel,
    912 	      (sreloc->contents + reloc_index * sizeof (Elf32_External_Rela)));
    913 }
    914 
    915 /* This code is taken from elf32-m32r.c
    916    There is some attempt to make this function usable for many architectures,
    917    both USE_REL and USE_RELA ['twould be nice if such a critter existed],
    918    if only to serve as a learning tool.
    919 
    920    The RELOCATE_SECTION function is called by the new ELF backend linker
    921    to handle the relocations for a section.
    922 
    923    The relocs are always passed as Rela structures; if the section
    924    actually uses Rel structures, the r_addend field will always be
    925    zero.
    926 
    927    This function is responsible for adjust the section contents as
    928    necessary, and (if using Rela relocs and generating a
    929    relocatable output file) adjusting the reloc addend as
    930    necessary.
    931 
    932    This function does not have to worry about setting the reloc
    933    address or the reloc symbol index.
    934 
    935    LOCAL_SYMS is a pointer to the swapped in local symbols.
    936 
    937    LOCAL_SECTIONS is an array giving the section in the input file
    938    corresponding to the st_shndx field of each local symbol.
    939 
    940    The global hash table entry for the global symbols can be found
    941    via elf_sym_hashes (input_bfd).
    942 
    943    When generating relocatable output, this function must handle
    944    STB_LOCAL/STT_SECTION symbols specially.  The output symbol is
    945    going to be the section symbol corresponding to the output
    946    section, which means that the addend must be adjusted
    947    accordingly.  */
    948 
    949 static int
    950 microblaze_elf_relocate_section (bfd *output_bfd,
    951 				 struct bfd_link_info *info,
    952 				 bfd *input_bfd,
    953 				 asection *input_section,
    954 				 bfd_byte *contents,
    955 				 Elf_Internal_Rela *relocs,
    956 				 Elf_Internal_Sym *local_syms,
    957 				 asection **local_sections)
    958 {
    959   struct elf32_mb_link_hash_table *htab;
    960   Elf_Internal_Shdr *symtab_hdr = &elf_tdata (input_bfd)->symtab_hdr;
    961   struct elf_link_hash_entry **sym_hashes = elf_sym_hashes (input_bfd);
    962   Elf_Internal_Rela *rel, *relend;
    963   int endian = (bfd_little_endian (output_bfd)) ? 0 : 2;
    964   /* Assume success.  */
    965   bool ret = true;
    966   asection *sreloc;
    967   bfd_vma *local_got_offsets;
    968   unsigned int tls_type;
    969 
    970   if (!microblaze_elf_howto_table[R_MICROBLAZE_max-1])
    971     microblaze_elf_howto_init ();
    972 
    973   htab = elf32_mb_hash_table (info);
    974   if (htab == NULL)
    975     return false;
    976 
    977   local_got_offsets = elf_local_got_offsets (input_bfd);
    978 
    979   sreloc = elf_section_data (input_section)->sreloc;
    980 
    981   rel = relocs;
    982   relend = relocs + input_section->reloc_count;
    983   for (; rel < relend; rel++)
    984     {
    985       int r_type;
    986       reloc_howto_type *howto;
    987       unsigned long r_symndx;
    988       bfd_vma addend = rel->r_addend;
    989       bfd_vma offset = rel->r_offset;
    990       struct elf_link_hash_entry *h;
    991       Elf_Internal_Sym *sym;
    992       asection *sec;
    993       const char *sym_name;
    994       bfd_reloc_status_type r = bfd_reloc_ok;
    995       const char *errmsg = NULL;
    996       bool unresolved_reloc = false;
    997 
    998       h = NULL;
    999       r_type = ELF32_R_TYPE (rel->r_info);
   1000       tls_type = 0;
   1001 
   1002       if (r_type < 0 || r_type >= (int) R_MICROBLAZE_max)
   1003 	{
   1004 	  /* xgettext:c-format */
   1005 	  _bfd_error_handler (_("%pB: unsupported relocation type %#x"),
   1006 			      input_bfd, (int) r_type);
   1007 	  bfd_set_error (bfd_error_bad_value);
   1008 	  ret = false;
   1009 	  continue;
   1010 	}
   1011 
   1012       howto = microblaze_elf_howto_table[r_type];
   1013       r_symndx = ELF32_R_SYM (rel->r_info);
   1014 
   1015       if (bfd_link_relocatable (info))
   1016 	{
   1017 	  /* This is a relocatable link.  We don't have to change
   1018 	     anything, unless the reloc is against a section symbol,
   1019 	     in which case we have to adjust according to where the
   1020 	     section symbol winds up in the output section.  */
   1021 	  sec = NULL;
   1022 	  if (r_symndx >= symtab_hdr->sh_info)
   1023 	    /* External symbol.  */
   1024 	    continue;
   1025 
   1026 	  /* Local symbol.  */
   1027 	  sym = local_syms + r_symndx;
   1028 	  sym_name = "<local symbol>";
   1029 	  /* STT_SECTION: symbol is associated with a section.  */
   1030 	  if (ELF_ST_TYPE (sym->st_info) != STT_SECTION)
   1031 	    /* Symbol isn't associated with a section.  Nothing to do.  */
   1032 	    continue;
   1033 
   1034 	  sec = local_sections[r_symndx];
   1035 	  addend += sec->output_offset + sym->st_value;
   1036 #ifndef USE_REL
   1037 	  /* This can't be done for USE_REL because it doesn't mean anything
   1038 	     and elf_link_input_bfd asserts this stays zero.  */
   1039 	  /* rel->r_addend = addend; */
   1040 #endif
   1041 
   1042 #ifndef USE_REL
   1043 	  /* Addends are stored with relocs.  We're done.  */
   1044 	  continue;
   1045 #else /* USE_REL */
   1046 	  /* If partial_inplace, we need to store any additional addend
   1047 	     back in the section.  */
   1048 	  if (!howto->partial_inplace)
   1049 	    continue;
   1050 	  /* ??? Here is a nice place to call a special_function like handler.  */
   1051 	  r = _bfd_relocate_contents (howto, input_bfd, addend,
   1052 				      contents + offset);
   1053 #endif /* USE_REL */
   1054 	}
   1055       else
   1056 	{
   1057 	  bfd_vma relocation;
   1058 	  bool resolved_to_zero;
   1059 
   1060 	  /* This is a final link.  */
   1061 	  sym = NULL;
   1062 	  sec = NULL;
   1063 	  unresolved_reloc = false;
   1064 
   1065 	  if (r_symndx < symtab_hdr->sh_info)
   1066 	    {
   1067 	      /* Local symbol.  */
   1068 	      sym = local_syms + r_symndx;
   1069 	      sec = local_sections[r_symndx];
   1070 	      if (sec == 0)
   1071 		continue;
   1072 	      sym_name = "<local symbol>";
   1073 	      relocation = _bfd_elf_rela_local_sym (output_bfd, sym, &sec, rel);
   1074 	      /* r_addend may have changed if the reference section was
   1075 		 a merge section.  */
   1076 	      addend = rel->r_addend;
   1077 	    }
   1078 	  else
   1079 	    {
   1080 	      /* External symbol.  */
   1081 	      bool warned ATTRIBUTE_UNUSED;
   1082 	      bool ignored ATTRIBUTE_UNUSED;
   1083 
   1084 	      RELOC_FOR_GLOBAL_SYMBOL (info, input_bfd, input_section, rel,
   1085 				       r_symndx, symtab_hdr, sym_hashes,
   1086 				       h, sec, relocation,
   1087 				       unresolved_reloc, warned, ignored);
   1088 	      sym_name = h->root.root.string;
   1089 	    }
   1090 
   1091 	  /* Sanity check the address.  */
   1092 	  if (offset > bfd_get_section_limit (input_bfd, input_section))
   1093 	    {
   1094 	      r = bfd_reloc_outofrange;
   1095 	      goto check_reloc;
   1096 	    }
   1097 
   1098 	  resolved_to_zero = (h != NULL
   1099 			      && UNDEFWEAK_NO_DYNAMIC_RELOC (info, h));
   1100 
   1101 	  switch ((int) r_type)
   1102 	    {
   1103 	    case (int) R_MICROBLAZE_SRO32 :
   1104 	      {
   1105 		const char *name;
   1106 
   1107 		/* Only relocate if the symbol is defined.  */
   1108 		if (sec)
   1109 		  {
   1110 		    name = bfd_section_name (sec);
   1111 
   1112 		    if (strcmp (name, ".sdata2") == 0
   1113 			|| strcmp (name, ".sbss2") == 0)
   1114 		      {
   1115 			if (ro_small_data_pointer == 0)
   1116 			  microblaze_elf_final_sdp (info);
   1117 			if (ro_small_data_pointer == 0)
   1118 			  {
   1119 			    ret = false;
   1120 			    r = bfd_reloc_undefined;
   1121 			    goto check_reloc;
   1122 			  }
   1123 
   1124 			/* At this point `relocation' contains the object's
   1125 			   address.  */
   1126 			relocation -= ro_small_data_pointer;
   1127 			/* Now it contains the offset from _SDA2_BASE_.  */
   1128 			r = _bfd_final_link_relocate (howto, input_bfd,
   1129 						      input_section,
   1130 						      contents, offset,
   1131 						      relocation, addend);
   1132 		      }
   1133 		    else
   1134 		      {
   1135 			_bfd_error_handler
   1136 			  /* xgettext:c-format */
   1137 			  (_("%pB: the target (%s) of an %s relocation"
   1138 			     " is in the wrong section (%pA)"),
   1139 			   input_bfd,
   1140 			   sym_name,
   1141 			   microblaze_elf_howto_table[(int) r_type]->name,
   1142 			   sec);
   1143 			/*bfd_set_error (bfd_error_bad_value); ??? why? */
   1144 			ret = false;
   1145 			continue;
   1146 		      }
   1147 		  }
   1148 	      }
   1149 	      break;
   1150 
   1151 	    case (int) R_MICROBLAZE_SRW32 :
   1152 	      {
   1153 		const char *name;
   1154 
   1155 		/* Only relocate if the symbol is defined.  */
   1156 		if (sec)
   1157 		  {
   1158 		    name = bfd_section_name (sec);
   1159 
   1160 		    if (strcmp (name, ".sdata") == 0
   1161 			|| strcmp (name, ".sbss") == 0)
   1162 		      {
   1163 			if (rw_small_data_pointer == 0)
   1164 			  microblaze_elf_final_sdp (info);
   1165 			if (rw_small_data_pointer == 0)
   1166 			  {
   1167 			    ret = false;
   1168 			    r = bfd_reloc_undefined;
   1169 			    goto check_reloc;
   1170 			  }
   1171 
   1172 			/* At this point `relocation' contains the object's
   1173 			   address.  */
   1174 			relocation -= rw_small_data_pointer;
   1175 			/* Now it contains the offset from _SDA_BASE_.  */
   1176 			r = _bfd_final_link_relocate (howto, input_bfd,
   1177 						      input_section,
   1178 						      contents, offset,
   1179 						      relocation, addend);
   1180 		      }
   1181 		    else
   1182 		      {
   1183 			_bfd_error_handler
   1184 			  /* xgettext:c-format */
   1185 			  (_("%pB: the target (%s) of an %s relocation"
   1186 			     " is in the wrong section (%pA)"),
   1187 			   input_bfd,
   1188 			   sym_name,
   1189 			   microblaze_elf_howto_table[(int) r_type]->name,
   1190 			   sec);
   1191 			/*bfd_set_error (bfd_error_bad_value); ??? why? */
   1192 			ret = false;
   1193 			continue;
   1194 		      }
   1195 		  }
   1196 	      }
   1197 	      break;
   1198 
   1199 	    case (int) R_MICROBLAZE_32_SYM_OP_SYM:
   1200 	      break; /* Do nothing.  */
   1201 
   1202 	    case (int) R_MICROBLAZE_GOTPC_64:
   1203 	      relocation = (htab->elf.sgotplt->output_section->vma
   1204 			    + htab->elf.sgotplt->output_offset);
   1205 	      relocation -= (input_section->output_section->vma
   1206 			     + input_section->output_offset
   1207 			     + offset + INST_WORD_SIZE);
   1208 	      relocation += addend;
   1209 	      bfd_put_16 (input_bfd, (relocation >> 16) & 0xffff,
   1210 			  contents + offset + endian);
   1211 	      bfd_put_16 (input_bfd, relocation & 0xffff,
   1212 			  contents + offset + endian + INST_WORD_SIZE);
   1213 	      break;
   1214 
   1215 	    case (int) R_MICROBLAZE_TEXTPCREL_64:
   1216 	      relocation = input_section->output_section->vma;
   1217 	      relocation -= (input_section->output_section->vma
   1218 			     + input_section->output_offset
   1219 			     + offset + INST_WORD_SIZE);
   1220 	      relocation += addend;
   1221 	      bfd_put_16 (input_bfd, (relocation >> 16) & 0xffff,
   1222 			  contents + offset + endian);
   1223 	      bfd_put_16 (input_bfd, relocation & 0xffff,
   1224 			  contents + offset + endian + INST_WORD_SIZE);
   1225 	      break;
   1226 
   1227 	    case (int) R_MICROBLAZE_PLT_64:
   1228 	      {
   1229 		bfd_vma immediate;
   1230 		if (htab->elf.splt != NULL && h != NULL
   1231 		    && h->plt.offset != (bfd_vma) -1)
   1232 		  {
   1233 		    relocation = (htab->elf.splt->output_section->vma
   1234 				  + htab->elf.splt->output_offset
   1235 				  + h->plt.offset);
   1236 		    unresolved_reloc = false;
   1237 		    immediate = relocation - (input_section->output_section->vma
   1238 					      + input_section->output_offset
   1239 					      + offset + INST_WORD_SIZE);
   1240 		    bfd_put_16 (input_bfd, (immediate >> 16) & 0xffff,
   1241 				contents + offset + endian);
   1242 		    bfd_put_16 (input_bfd, immediate & 0xffff,
   1243 				contents + offset + endian + INST_WORD_SIZE);
   1244 		  }
   1245 		else
   1246 		  {
   1247 		    relocation -= (input_section->output_section->vma
   1248 				   + input_section->output_offset
   1249 				   + offset + INST_WORD_SIZE);
   1250 		    immediate = relocation;
   1251 		    bfd_put_16 (input_bfd, (immediate >> 16) & 0xffff,
   1252 				contents + offset + endian);
   1253 		    bfd_put_16 (input_bfd, immediate & 0xffff,
   1254 				contents + offset + endian + INST_WORD_SIZE);
   1255 		  }
   1256 		break;
   1257 	      }
   1258 
   1259 	    case (int) R_MICROBLAZE_TLSGD:
   1260 	      tls_type = (TLS_TLS | TLS_GD);
   1261 	      goto dogot;
   1262 	    case (int) R_MICROBLAZE_TLSLD:
   1263 	      tls_type = (TLS_TLS | TLS_LD);
   1264 	      /* Fall through.  */
   1265 	    dogot:
   1266 	    case (int) R_MICROBLAZE_GOT_64:
   1267 	      {
   1268 		bfd_vma *offp;
   1269 		bfd_vma off, off2;
   1270 		unsigned long indx;
   1271 		bfd_vma static_value;
   1272 
   1273 		bool need_relocs = false;
   1274 		if (htab->elf.sgot == NULL)
   1275 		  abort ();
   1276 
   1277 		indx = 0;
   1278 		offp = NULL;
   1279 
   1280 		/* 1. Identify GOT Offset;
   1281 		   2. Compute Static Values
   1282 		   3. Process Module Id, Process Offset
   1283 		   4. Fixup Relocation with GOT offset value. */
   1284 
   1285 		/* 1. Determine GOT Offset to use : TLS_LD, global, local */
   1286 		if (IS_TLS_LD (tls_type))
   1287 		  offp = &htab->tlsld_got.offset;
   1288 		else if (h != NULL)
   1289 		  {
   1290 		    if (htab->elf.sgotplt != NULL
   1291 			&& h->got.offset != (bfd_vma) -1)
   1292 		      offp = &h->got.offset;
   1293 		    else
   1294 		      abort ();
   1295 		  }
   1296 		else
   1297 		  {
   1298 		    if (local_got_offsets == NULL)
   1299 		      abort ();
   1300 		    offp = &local_got_offsets[r_symndx];
   1301 		  }
   1302 
   1303 		if (!offp)
   1304 		  abort ();
   1305 
   1306 		off = (*offp) & ~1;
   1307 		off2 = off;
   1308 
   1309 		if (IS_TLS_LD(tls_type) || IS_TLS_GD(tls_type))
   1310 		  off2 = off + 4;
   1311 
   1312 		/* Symbol index to use for relocs */
   1313 		if (h != NULL)
   1314 		  {
   1315 		    bool dyn =
   1316 			elf_hash_table (info)->dynamic_sections_created;
   1317 
   1318 		    if (WILL_CALL_FINISH_DYNAMIC_SYMBOL (dyn,
   1319 							 bfd_link_pic (info),
   1320 							 h)
   1321 			&& (!bfd_link_pic (info)
   1322 			    || !SYMBOL_REFERENCES_LOCAL (info, h)))
   1323 		      indx = h->dynindx;
   1324 		  }
   1325 
   1326 		/* Need to generate relocs ? */
   1327 		if ((bfd_link_pic (info) || indx != 0)
   1328 		    && (h == NULL
   1329 		    || (ELF_ST_VISIBILITY (h->other) == STV_DEFAULT
   1330 			&& !resolved_to_zero)
   1331 		    || h->root.type != bfd_link_hash_undefweak))
   1332 		  need_relocs = true;
   1333 
   1334 		/* 2. Compute/Emit Static value of r-expression */
   1335 		static_value = relocation + addend;
   1336 
   1337 		/* 3. Process module-id and offset */
   1338 		if (! ((*offp) & 1) )
   1339 		  {
   1340 		    bfd_vma got_offset;
   1341 
   1342 		    got_offset = (htab->elf.sgot->output_section->vma
   1343 				  + htab->elf.sgot->output_offset
   1344 				  + off);
   1345 
   1346 		    /* Process module-id */
   1347 		    if (IS_TLS_LD(tls_type))
   1348 		      {
   1349 			if (! bfd_link_pic (info))
   1350 			  bfd_put_32 (output_bfd, 1,
   1351 				      htab->elf.sgot->contents + off);
   1352 			else
   1353 			  microblaze_elf_output_dynamic_relocation
   1354 			    (output_bfd,
   1355 			     htab->elf.srelgot,
   1356 			     htab->elf.srelgot->reloc_count++,
   1357 			     /* symindex= */ 0, R_MICROBLAZE_TLSDTPMOD32,
   1358 			     got_offset, 0);
   1359 		      }
   1360 		    else if (IS_TLS_GD(tls_type))
   1361 		      {
   1362 			if (! need_relocs)
   1363 			  bfd_put_32 (output_bfd, 1,
   1364 				      htab->elf.sgot->contents + off);
   1365 			else
   1366 			  microblaze_elf_output_dynamic_relocation
   1367 			    (output_bfd,
   1368 			     htab->elf.srelgot,
   1369 			     htab->elf.srelgot->reloc_count++,
   1370 			     /* symindex= */ indx, R_MICROBLAZE_TLSDTPMOD32,
   1371 			     got_offset, indx ? 0 : static_value);
   1372 		      }
   1373 
   1374 		    /* Process Offset */
   1375 		    if (htab->elf.srelgot == NULL)
   1376 		      abort ();
   1377 
   1378 		    got_offset = (htab->elf.sgot->output_section->vma
   1379 				  + htab->elf.sgot->output_offset
   1380 				  + off2);
   1381 		    if (IS_TLS_LD(tls_type))
   1382 		      {
   1383 			/* For LD, offset should be 0 */
   1384 			*offp |= 1;
   1385 			bfd_put_32 (output_bfd, 0,
   1386 				    htab->elf.sgot->contents + off2);
   1387 		      }
   1388 		    else if (IS_TLS_GD(tls_type))
   1389 		      {
   1390 			*offp |= 1;
   1391 			static_value -= dtprel_base(info);
   1392 			if (need_relocs)
   1393 			  microblaze_elf_output_dynamic_relocation
   1394 			    (output_bfd,
   1395 			     htab->elf.srelgot,
   1396 			     htab->elf.srelgot->reloc_count++,
   1397 			     /* symindex= */ indx, R_MICROBLAZE_TLSDTPREL32,
   1398 			     got_offset, indx ? 0 : static_value);
   1399 			else
   1400 			  bfd_put_32 (output_bfd, static_value,
   1401 				      htab->elf.sgot->contents + off2);
   1402 		      }
   1403 		    else
   1404 		      {
   1405 			bfd_put_32 (output_bfd, static_value,
   1406 				    htab->elf.sgot->contents + off2);
   1407 
   1408 			/* Relocs for dyn symbols generated by
   1409 			   finish_dynamic_symbols */
   1410 			if (bfd_link_pic (info) && h == NULL)
   1411 			  {
   1412 			    *offp |= 1;
   1413 			    microblaze_elf_output_dynamic_relocation
   1414 			      (output_bfd,
   1415 			       htab->elf.srelgot,
   1416 			       htab->elf.srelgot->reloc_count++,
   1417 			       /* symindex= */ indx, R_MICROBLAZE_REL,
   1418 			       got_offset, static_value);
   1419 			  }
   1420 		      }
   1421 		  }
   1422 
   1423 		/* 4. Fixup Relocation with GOT offset value
   1424 		      Compute relative address of GOT entry for applying
   1425 		      the current relocation */
   1426 		relocation = htab->elf.sgot->output_section->vma
   1427 			     + htab->elf.sgot->output_offset
   1428 			     + off
   1429 			     - htab->elf.sgotplt->output_section->vma
   1430 			     - htab->elf.sgotplt->output_offset;
   1431 
   1432 		/* Apply Current Relocation */
   1433 		bfd_put_16 (input_bfd, (relocation >> 16) & 0xffff,
   1434 			    contents + offset + endian);
   1435 		bfd_put_16 (input_bfd, relocation & 0xffff,
   1436 			    contents + offset + endian + INST_WORD_SIZE);
   1437 
   1438 		unresolved_reloc = false;
   1439 		break;
   1440 	      }
   1441 
   1442 	    case (int) R_MICROBLAZE_GOTOFF_64:
   1443 	      {
   1444 		bfd_vma immediate;
   1445 		unsigned short lo, high;
   1446 		relocation += addend;
   1447 		relocation -= (htab->elf.sgotplt->output_section->vma
   1448 			       + htab->elf.sgotplt->output_offset);
   1449 		/* Write this value into correct location.  */
   1450 		immediate = relocation;
   1451 		lo = immediate & 0x0000ffff;
   1452 		high = (immediate >> 16) & 0x0000ffff;
   1453 		bfd_put_16 (input_bfd, high, contents + offset + endian);
   1454 		bfd_put_16 (input_bfd, lo,
   1455 			    contents + offset + INST_WORD_SIZE + endian);
   1456 		break;
   1457 	      }
   1458 
   1459 	    case (int) R_MICROBLAZE_GOTOFF_32:
   1460 	      {
   1461 		relocation += addend;
   1462 		relocation -= (htab->elf.sgotplt->output_section->vma
   1463 			       + htab->elf.sgotplt->output_offset);
   1464 		/* Write this value into correct location.  */
   1465 		bfd_put_32 (input_bfd, relocation, contents + offset);
   1466 		break;
   1467 	      }
   1468 
   1469 	    case (int) R_MICROBLAZE_TLSDTPREL64:
   1470 	      relocation += addend;
   1471 	      relocation -= dtprel_base(info);
   1472 	      bfd_put_16 (input_bfd, (relocation >> 16) & 0xffff,
   1473 			  contents + offset + 2);
   1474 	      bfd_put_16 (input_bfd, relocation & 0xffff,
   1475 			  contents + offset + 2 + INST_WORD_SIZE);
   1476 	      break;
   1477 	    case (int) R_MICROBLAZE_TEXTREL_64:
   1478 	    case (int) R_MICROBLAZE_TEXTREL_32_LO:
   1479 	    case (int) R_MICROBLAZE_64_PCREL :
   1480 	    case (int) R_MICROBLAZE_64:
   1481 	    case (int) R_MICROBLAZE_32:
   1482 	      {
   1483 		/* r_symndx will be STN_UNDEF (zero) only for relocs against symbols
   1484 		   from removed linkonce sections, or sections discarded by
   1485 		   a linker script.  */
   1486 		if (r_symndx == STN_UNDEF || (input_section->flags & SEC_ALLOC) == 0)
   1487 		  {
   1488 		    relocation += addend;
   1489 		    if (r_type == R_MICROBLAZE_32)
   1490 		      bfd_put_32 (input_bfd, relocation, contents + offset);
   1491 		    else
   1492 		      {
   1493 			if (r_type == R_MICROBLAZE_64_PCREL)
   1494 			  relocation -= (input_section->output_section->vma
   1495 					 + input_section->output_offset
   1496 					 + offset + INST_WORD_SIZE);
   1497 			else if (r_type == R_MICROBLAZE_TEXTREL_64
   1498 				 || r_type == R_MICROBLAZE_TEXTREL_32_LO)
   1499 			  relocation -= input_section->output_section->vma;
   1500 
   1501 			if (r_type == R_MICROBLAZE_TEXTREL_32_LO)
   1502 			  bfd_put_16 (input_bfd, relocation & 0xffff,
   1503 				      contents + offset + endian);
   1504 
   1505 			else
   1506 			  {
   1507 			    bfd_put_16 (input_bfd, (relocation >> 16) & 0xffff,
   1508 				    contents + offset + endian);
   1509 			    bfd_put_16 (input_bfd, relocation & 0xffff,
   1510 				    contents + offset + endian + INST_WORD_SIZE);
   1511 		      }
   1512 		    }
   1513 		    break;
   1514 		  }
   1515 
   1516 		if ((bfd_link_pic (info)
   1517 		     && (h == NULL
   1518 			 || (ELF_ST_VISIBILITY (h->other) == STV_DEFAULT
   1519 			     && !resolved_to_zero)
   1520 			 || h->root.type != bfd_link_hash_undefweak)
   1521 		     && (!howto->pc_relative
   1522 			 || (h != NULL
   1523 			     && h->dynindx != -1
   1524 			     && (!info->symbolic
   1525 				 || !h->def_regular))))
   1526 		    || (!bfd_link_pic (info)
   1527 			&& h != NULL
   1528 			&& h->dynindx != -1
   1529 			&& !h->non_got_ref
   1530 			&& ((h->def_dynamic
   1531 			     && !h->def_regular)
   1532 			    || h->root.type == bfd_link_hash_undefweak
   1533 			    || h->root.type == bfd_link_hash_undefined)))
   1534 		  {
   1535 		    Elf_Internal_Rela outrel;
   1536 		    bfd_byte *loc;
   1537 		    bool skip;
   1538 
   1539 		    /* When generating a shared object, these relocations
   1540 		       are copied into the output file to be resolved at run
   1541 		       time.  */
   1542 
   1543 		    BFD_ASSERT (sreloc != NULL);
   1544 
   1545 		    skip = false;
   1546 
   1547 		    outrel.r_offset =
   1548 		      _bfd_elf_section_offset (output_bfd, info, input_section,
   1549 					       rel->r_offset);
   1550 		    if (outrel.r_offset == (bfd_vma) -1)
   1551 		      skip = true;
   1552 		    else if (outrel.r_offset == (bfd_vma) -2)
   1553 		      skip = true;
   1554 		    outrel.r_offset += (input_section->output_section->vma
   1555 					+ input_section->output_offset);
   1556 
   1557 		    if (skip)
   1558 		      memset (&outrel, 0, sizeof outrel);
   1559 		    /* h->dynindx may be -1 if the symbol was marked to
   1560 		       become local.  */
   1561 		    else if (h != NULL
   1562 			     && ((! info->symbolic && h->dynindx != -1)
   1563 				 || !h->def_regular))
   1564 		      {
   1565 			BFD_ASSERT (h->dynindx != -1);
   1566 			outrel.r_info = ELF32_R_INFO (h->dynindx, r_type);
   1567 			outrel.r_addend = addend;
   1568 		      }
   1569 		    else
   1570 		      {
   1571 			if (r_type == R_MICROBLAZE_32)
   1572 			  {
   1573 			    outrel.r_info = ELF32_R_INFO (0, R_MICROBLAZE_REL);
   1574 			    outrel.r_addend = relocation + addend;
   1575 			  }
   1576 			else
   1577 			  {
   1578 			    BFD_FAIL ();
   1579 			    _bfd_error_handler
   1580 			      (_("%pB: probably compiled without -fPIC?"),
   1581 			       input_bfd);
   1582 			    bfd_set_error (bfd_error_bad_value);
   1583 			    return false;
   1584 			  }
   1585 		      }
   1586 
   1587 		    loc = sreloc->contents;
   1588 		    loc += sreloc->reloc_count++ * sizeof (Elf32_External_Rela);
   1589 		    bfd_elf32_swap_reloca_out (output_bfd, &outrel, loc);
   1590 		    break;
   1591 		  }
   1592 		else
   1593 		  {
   1594 		    relocation += addend;
   1595 		    if (r_type == R_MICROBLAZE_32)
   1596 		      bfd_put_32 (input_bfd, relocation, contents + offset);
   1597 		    else
   1598 		      {
   1599 			if (r_type == R_MICROBLAZE_64_PCREL)
   1600 			  relocation -= (input_section->output_section->vma
   1601 					 + input_section->output_offset
   1602 					 + offset + INST_WORD_SIZE);
   1603 			else if (r_type == R_MICROBLAZE_TEXTREL_64
   1604 				 || r_type == R_MICROBLAZE_TEXTREL_32_LO)
   1605 			  relocation -= input_section->output_section->vma;
   1606 
   1607 			if (r_type == R_MICROBLAZE_TEXTREL_32_LO)
   1608 			  {
   1609 			     bfd_put_16 (input_bfd, relocation & 0xffff,
   1610 					 contents + offset + endian);
   1611 			  }
   1612 			else
   1613 			  {
   1614 			    bfd_put_16 (input_bfd, (relocation >> 16) & 0xffff,
   1615 				        contents + offset + endian);
   1616 			    bfd_put_16 (input_bfd, relocation & 0xffff,
   1617 					contents + offset + endian
   1618 					+ INST_WORD_SIZE);
   1619 			  }
   1620 		    }
   1621 		    break;
   1622 		  }
   1623 	      }
   1624 
   1625 	    default :
   1626 	      r = _bfd_final_link_relocate (howto, input_bfd, input_section,
   1627 					    contents, offset,
   1628 					    relocation, addend);
   1629 	      break;
   1630 	    }
   1631 	}
   1632 
   1633     check_reloc:
   1634 
   1635       if (r != bfd_reloc_ok)
   1636 	{
   1637 	  /* FIXME: This should be generic enough to go in a utility.  */
   1638 	  const char *name;
   1639 
   1640 	  if (h != NULL)
   1641 	    name = h->root.root.string;
   1642 	  else
   1643 	    {
   1644 	      name = (bfd_elf_string_from_elf_section
   1645 		      (input_bfd, symtab_hdr->sh_link, sym->st_name));
   1646 	      if (name == NULL || *name == '\0')
   1647 		name = bfd_section_name (sec);
   1648 	    }
   1649 
   1650 	  if (errmsg != NULL)
   1651 	    goto common_error;
   1652 
   1653 	  switch (r)
   1654 	    {
   1655 	    case bfd_reloc_overflow:
   1656 	      (*info->callbacks->reloc_overflow)
   1657 		(info, (h ? &h->root : NULL), name, howto->name,
   1658 		 (bfd_vma) 0, input_bfd, input_section, offset);
   1659 	      break;
   1660 
   1661 	    case bfd_reloc_undefined:
   1662 	      (*info->callbacks->undefined_symbol)
   1663 		(info, name, input_bfd, input_section, offset, true);
   1664 	      break;
   1665 
   1666 	    case bfd_reloc_outofrange:
   1667 	      errmsg = _("internal error: out of range error");
   1668 	      goto common_error;
   1669 
   1670 	    case bfd_reloc_notsupported:
   1671 	      errmsg = _("internal error: unsupported relocation error");
   1672 	      goto common_error;
   1673 
   1674 	    case bfd_reloc_dangerous:
   1675 	      errmsg = _("internal error: dangerous error");
   1676 	      goto common_error;
   1677 
   1678 	    default:
   1679 	      errmsg = _("internal error: unknown error");
   1680 	      /* Fall through.  */
   1681 	    common_error:
   1682 	      (*info->callbacks->warning) (info, errmsg, name, input_bfd,
   1683 					   input_section, offset);
   1684 	      break;
   1685 	    }
   1686 	}
   1687     }
   1688 
   1689   return ret;
   1690 }
   1691 
   1692 /* Calculate fixup value for reference.  */
   1694 
   1695 static size_t
   1696 calc_fixup (bfd_vma start, bfd_vma size, asection *sec)
   1697 {
   1698   bfd_vma end = start + size;
   1699   size_t i, fixup = 0;
   1700   struct _microblaze_elf_section_data *sdata;
   1701 
   1702   if (sec == NULL || (sdata = microblaze_elf_section_data (sec)) == NULL)
   1703     return 0;
   1704 
   1705   /* Look for addr in relax table, total fixup value.  */
   1706   for (i = 0; i < sdata->relax_count; i++)
   1707     {
   1708       if (end <= sdata->relax[i].addr)
   1709 	break;
   1710       if (end != start && start > sdata->relax[i].addr)
   1711 	continue;
   1712       fixup += sdata->relax[i].size;
   1713     }
   1714   return fixup;
   1715 }
   1716 
   1717 /* Read-modify-write into the bfd, an immediate value into appropriate fields of
   1718    a 32-bit instruction.  */
   1719 static void
   1720 microblaze_bfd_write_imm_value_32 (bfd *abfd, bfd_byte *bfd_addr, bfd_vma val)
   1721 {
   1722     unsigned long instr = bfd_get_32 (abfd, bfd_addr);
   1723     instr &= ~0x0000ffff;
   1724     instr |= (val & 0x0000ffff);
   1725     bfd_put_32 (abfd, instr, bfd_addr);
   1726 }
   1727 
   1728 /* Read-modify-write into the bfd, an immediate value into appropriate fields of
   1729    two consecutive 32-bit instructions.  */
   1730 static void
   1731 microblaze_bfd_write_imm_value_64 (bfd *abfd, bfd_byte *bfd_addr, bfd_vma val)
   1732 {
   1733     unsigned long instr_hi;
   1734     unsigned long instr_lo;
   1735 
   1736     instr_hi = bfd_get_32 (abfd, bfd_addr);
   1737     instr_hi &= ~0x0000ffff;
   1738     instr_hi |= ((val >> 16) & 0x0000ffff);
   1739     bfd_put_32 (abfd, instr_hi, bfd_addr);
   1740 
   1741     instr_lo = bfd_get_32 (abfd, bfd_addr + INST_WORD_SIZE);
   1742     instr_lo &= ~0x0000ffff;
   1743     instr_lo |= (val & 0x0000ffff);
   1744     bfd_put_32 (abfd, instr_lo, bfd_addr + INST_WORD_SIZE);
   1745 }
   1746 
   1747 static bool
   1748 microblaze_elf_relax_section (bfd *abfd,
   1749 			      asection *sec,
   1750 			      struct bfd_link_info *link_info,
   1751 			      bool *again)
   1752 {
   1753   Elf_Internal_Shdr *symtab_hdr;
   1754   Elf_Internal_Rela *internal_relocs;
   1755   Elf_Internal_Rela *free_relocs = NULL;
   1756   Elf_Internal_Rela *irel, *irelend;
   1757   bfd_byte *contents = NULL;
   1758   bfd_byte *free_contents = NULL;
   1759   int rel_count;
   1760   unsigned int shndx;
   1761   size_t i, sym_index;
   1762   asection *o;
   1763   struct elf_link_hash_entry *sym_hash;
   1764   Elf_Internal_Sym *isymbuf, *isymend;
   1765   Elf_Internal_Sym *isym;
   1766   size_t symcount;
   1767   size_t offset;
   1768   bfd_vma src, dest;
   1769   struct _microblaze_elf_section_data *sdata;
   1770 
   1771   /* We only do this once per section.  We may be able to delete some code
   1772      by running multiple passes, but it is not worth it.  */
   1773   *again = false;
   1774 
   1775   /* Only do this for a text section.  */
   1776   if (bfd_link_relocatable (link_info)
   1777       || (sec->flags & SEC_RELOC) == 0
   1778       || (sec->flags & SEC_CODE) == 0
   1779       || sec->reloc_count == 0
   1780       || (sdata = microblaze_elf_section_data (sec)) == NULL)
   1781     return true;
   1782 
   1783   BFD_ASSERT ((sec->size > 0) || (sec->rawsize > 0));
   1784 
   1785   /* If this is the first time we have been called for this section,
   1786      initialize the cooked size.  */
   1787   if (sec->size == 0)
   1788     sec->size = sec->rawsize;
   1789 
   1790   /* Get symbols for this section.  */
   1791   symtab_hdr = &elf_tdata (abfd)->symtab_hdr;
   1792   isymbuf = (Elf_Internal_Sym *) symtab_hdr->contents;
   1793   symcount =  symtab_hdr->sh_size / sizeof (Elf32_External_Sym);
   1794   if (isymbuf == NULL)
   1795     isymbuf = bfd_elf_get_elf_syms (abfd, symtab_hdr, symcount,
   1796 				    0, NULL, NULL, NULL);
   1797   BFD_ASSERT (isymbuf != NULL);
   1798 
   1799   internal_relocs = _bfd_elf_link_read_relocs (abfd, sec, NULL, NULL, link_info->keep_memory);
   1800   if (internal_relocs == NULL)
   1801     goto error_return;
   1802   if (! link_info->keep_memory)
   1803     free_relocs = internal_relocs;
   1804 
   1805   sdata->relax_count = 0;
   1806   sdata->relax = (struct relax_table *) bfd_malloc ((sec->reloc_count + 1)
   1807 						    * sizeof (*sdata->relax));
   1808   if (sdata->relax == NULL)
   1809     goto error_return;
   1810 
   1811   irelend = internal_relocs + sec->reloc_count;
   1812   rel_count = 0;
   1813   for (irel = internal_relocs; irel < irelend; irel++, rel_count++)
   1814     {
   1815       bfd_vma symval;
   1816       if ((ELF32_R_TYPE (irel->r_info) != (int) R_MICROBLAZE_64_PCREL)
   1817 	  && (ELF32_R_TYPE (irel->r_info) != (int) R_MICROBLAZE_64)
   1818 	  && (ELF32_R_TYPE (irel->r_info) != (int) R_MICROBLAZE_TEXTREL_64))
   1819 	continue; /* Can't delete this reloc.  */
   1820 
   1821       /* Get the section contents.  */
   1822       if (contents == NULL)
   1823 	{
   1824 	  if (elf_section_data (sec)->this_hdr.contents != NULL)
   1825 	    contents = elf_section_data (sec)->this_hdr.contents;
   1826 	  else
   1827 	    {
   1828 	      contents = (bfd_byte *) bfd_malloc (sec->size);
   1829 	      if (contents == NULL)
   1830 		goto error_return;
   1831 	      free_contents = contents;
   1832 
   1833 	      if (!bfd_get_section_contents (abfd, sec, contents,
   1834 					     (file_ptr) 0, sec->size))
   1835 		goto error_return;
   1836 	      elf_section_data (sec)->this_hdr.contents = contents;
   1837 	    }
   1838 	}
   1839 
   1840       /* Get the value of the symbol referred to by the reloc.  */
   1841       if (ELF32_R_SYM (irel->r_info) < symtab_hdr->sh_info)
   1842 	{
   1843 	  /* A local symbol.  */
   1844 	  asection *sym_sec;
   1845 
   1846 	  isym = isymbuf + ELF32_R_SYM (irel->r_info);
   1847 	  if (isym->st_shndx == SHN_UNDEF)
   1848 	    sym_sec = bfd_und_section_ptr;
   1849 	  else if (isym->st_shndx == SHN_ABS)
   1850 	    sym_sec = bfd_abs_section_ptr;
   1851 	  else if (isym->st_shndx == SHN_COMMON)
   1852 	    sym_sec = bfd_com_section_ptr;
   1853 	  else
   1854 	    sym_sec = bfd_section_from_elf_index (abfd, isym->st_shndx);
   1855 
   1856 	  symval = _bfd_elf_rela_local_sym (abfd, isym, &sym_sec, irel);
   1857 	}
   1858       else
   1859 	{
   1860 	  unsigned long indx;
   1861 	  struct elf_link_hash_entry *h;
   1862 
   1863 	  indx = ELF32_R_SYM (irel->r_info) - symtab_hdr->sh_info;
   1864 	  h = elf_sym_hashes (abfd)[indx];
   1865 	  BFD_ASSERT (h != NULL);
   1866 
   1867 	  if (h->root.type != bfd_link_hash_defined
   1868 	      && h->root.type != bfd_link_hash_defweak)
   1869 	    /* This appears to be a reference to an undefined
   1870 	       symbol.  Just ignore it--it will be caught by the
   1871 	       regular reloc processing.  */
   1872 	    continue;
   1873 
   1874 	  symval = (h->root.u.def.value
   1875 		    + h->root.u.def.section->output_section->vma
   1876 		    + h->root.u.def.section->output_offset);
   1877 	}
   1878 
   1879       /* If this is a PC-relative reloc, subtract the instr offset from
   1880 	 the symbol value.  */
   1881       if (ELF32_R_TYPE (irel->r_info) == (int) R_MICROBLAZE_64_PCREL)
   1882 	{
   1883 	  symval = symval + irel->r_addend
   1884 	    - (irel->r_offset
   1885 	       + sec->output_section->vma
   1886 	       + sec->output_offset);
   1887 	}
   1888       else if (ELF32_R_TYPE (irel->r_info) == (int) R_MICROBLAZE_TEXTREL_64)
   1889 	{
   1890 	  symval = symval + irel->r_addend - (sec->output_section->vma);
   1891 	}
   1892       else
   1893 	symval += irel->r_addend;
   1894 
   1895       if ((symval & 0xffff8000) == 0
   1896 	  || (symval & 0xffff8000) == 0xffff8000)
   1897 	{
   1898 	  /* We can delete this instruction.  */
   1899 	  sdata->relax[sdata->relax_count].addr = irel->r_offset;
   1900 	  sdata->relax[sdata->relax_count].size = INST_WORD_SIZE;
   1901 	  sdata->relax_count++;
   1902 
   1903 	  /* Rewrite relocation type.  */
   1904 	  switch ((enum elf_microblaze_reloc_type) ELF32_R_TYPE (irel->r_info))
   1905 	    {
   1906 	    case R_MICROBLAZE_64_PCREL:
   1907 	      irel->r_info = ELF32_R_INFO (ELF32_R_SYM (irel->r_info),
   1908 					   (int) R_MICROBLAZE_32_PCREL_LO);
   1909 	      break;
   1910 	    case R_MICROBLAZE_64:
   1911 	      irel->r_info = ELF32_R_INFO (ELF32_R_SYM (irel->r_info),
   1912 					   (int) R_MICROBLAZE_32_LO);
   1913 	      break;
   1914 	    case R_MICROBLAZE_TEXTREL_64:
   1915 	      irel->r_info = ELF32_R_INFO (ELF32_R_SYM (irel->r_info),
   1916 					   (int) R_MICROBLAZE_TEXTREL_32_LO);
   1917 	      break;
   1918 	    default:
   1919 	      /* Cannot happen.  */
   1920 	      BFD_ASSERT (false);
   1921 	    }
   1922 	}
   1923     } /* Loop through all relocations.  */
   1924 
   1925   /* Loop through the relocs again, and see if anything needs to change.  */
   1926   if (sdata->relax_count > 0)
   1927     {
   1928       shndx = _bfd_elf_section_from_bfd_section (abfd, sec);
   1929       rel_count = 0;
   1930       sdata->relax[sdata->relax_count].addr = sec->size;
   1931 
   1932       for (irel = internal_relocs; irel < irelend; irel++, rel_count++)
   1933 	{
   1934 	  bfd_vma nraddr;
   1935 
   1936 	  /* Get the new reloc address.  */
   1937 	  nraddr = irel->r_offset - calc_fixup (irel->r_offset, 0, sec);
   1938 	  switch ((enum elf_microblaze_reloc_type) ELF32_R_TYPE (irel->r_info))
   1939 	    {
   1940 	    default:
   1941 	      break;
   1942 	    case R_MICROBLAZE_64_PCREL:
   1943 	      break;
   1944 	    case R_MICROBLAZE_TEXTREL_64:
   1945 	    case R_MICROBLAZE_TEXTREL_32_LO:
   1946 	    case R_MICROBLAZE_64:
   1947 	    case R_MICROBLAZE_32_LO:
   1948 	      /* If this reloc is against a symbol defined in this
   1949 		 section, we must check the addend to see it will put the value in
   1950 		 range to be adjusted, and hence must be changed.  */
   1951 	      if (ELF32_R_SYM (irel->r_info) < symtab_hdr->sh_info)
   1952 		{
   1953 		  isym = isymbuf + ELF32_R_SYM (irel->r_info);
   1954 		  /* Only handle relocs against .text.  */
   1955 		  if (isym->st_shndx == shndx
   1956 		      && ELF32_ST_TYPE (isym->st_info) == STT_SECTION)
   1957 		    irel->r_addend -= calc_fixup (irel->r_addend, 0, sec);
   1958 		}
   1959 	      break;
   1960 	    case R_MICROBLAZE_NONE:
   1961 	      {
   1962 		/* This was a PC-relative instruction that was
   1963 		   completely resolved.  */
   1964 		size_t sfix, efix;
   1965 		bfd_vma target_address;
   1966 		target_address = irel->r_addend + irel->r_offset;
   1967 		sfix = calc_fixup (irel->r_offset, 0, sec);
   1968 		efix = calc_fixup (target_address, 0, sec);
   1969 		irel->r_addend -= (efix - sfix);
   1970 		/* Should use HOWTO.  */
   1971 		microblaze_bfd_write_imm_value_32 (abfd, contents + irel->r_offset,
   1972 						   irel->r_addend);
   1973 	      }
   1974 	      break;
   1975 	    case R_MICROBLAZE_64_NONE:
   1976 	      {
   1977 		/* This was a PC-relative 64-bit instruction that was
   1978 		   completely resolved.  */
   1979 		size_t sfix, efix;
   1980 		bfd_vma target_address;
   1981 		target_address = irel->r_addend + irel->r_offset + INST_WORD_SIZE;
   1982 		sfix = calc_fixup (irel->r_offset + INST_WORD_SIZE, 0, sec);
   1983 		efix = calc_fixup (target_address, 0, sec);
   1984 		irel->r_addend -= (efix - sfix);
   1985     microblaze_bfd_write_imm_value_32 (abfd, contents + irel->r_offset
   1986 				       + INST_WORD_SIZE, irel->r_addend);
   1987 	      }
   1988 	      break;
   1989 	    }
   1990 	  irel->r_offset = nraddr;
   1991 	} /* Change all relocs in this section.  */
   1992 
   1993       /* Look through all other sections.  */
   1994       for (o = abfd->sections; o != NULL; o = o->next)
   1995 	{
   1996 	  Elf_Internal_Rela *irelocs;
   1997 	  Elf_Internal_Rela *irelscan, *irelscanend;
   1998 	  bfd_byte *ocontents;
   1999 
   2000 	  if (o == sec
   2001 	      || (o->flags & SEC_RELOC) == 0
   2002 	      || o->reloc_count == 0)
   2003 	    continue;
   2004 
   2005 	  /* We always cache the relocs.  Perhaps, if info->keep_memory is
   2006 	     FALSE, we should free them, if we are permitted to.  */
   2007 
   2008 	  irelocs = _bfd_elf_link_read_relocs (abfd, o, NULL, NULL, true);
   2009 	  if (irelocs == NULL)
   2010 	    goto error_return;
   2011 
   2012 	  ocontents = NULL;
   2013 	  irelscanend = irelocs + o->reloc_count;
   2014 	  for (irelscan = irelocs; irelscan < irelscanend; irelscan++)
   2015 	    {
   2016 	      if (ELF32_R_TYPE (irelscan->r_info) == (int) R_MICROBLAZE_32)
   2017 		{
   2018 		  isym = isymbuf + ELF32_R_SYM (irelscan->r_info);
   2019 
   2020 		  /* Look at the reloc only if the value has been resolved.  */
   2021 		  if (isym->st_shndx == shndx
   2022 		      && (ELF32_ST_TYPE (isym->st_info) == STT_SECTION))
   2023 		    {
   2024 		      if (ocontents == NULL)
   2025 			{
   2026 			  if (elf_section_data (o)->this_hdr.contents != NULL)
   2027 			    ocontents = elf_section_data (o)->this_hdr.contents;
   2028 			  else
   2029 			    {
   2030 			      /* We always cache the section contents.
   2031 				 Perhaps, if info->keep_memory is FALSE, we
   2032 				 should free them, if we are permitted to.  */
   2033 			      if (o->rawsize == 0)
   2034 				o->rawsize = o->size;
   2035 			      ocontents = (bfd_byte *) bfd_malloc (o->rawsize);
   2036 			      if (ocontents == NULL)
   2037 				goto error_return;
   2038 			      if (!bfd_get_section_contents (abfd, o, ocontents,
   2039 							     (file_ptr) 0,
   2040 							     o->rawsize))
   2041 				goto error_return;
   2042 			      elf_section_data (o)->this_hdr.contents = ocontents;
   2043 			    }
   2044 
   2045 			}
   2046 		      irelscan->r_addend -= calc_fixup (irelscan->r_addend, 0, sec);
   2047 		    }
   2048 		  else if (ELF32_R_TYPE (irelscan->r_info) == (int) R_MICROBLAZE_32_SYM_OP_SYM)
   2049 		    {
   2050 		      isym = isymbuf + ELF32_R_SYM (irelscan->r_info);
   2051 
   2052 		      /* Look at the reloc only if the value has been resolved.  */
   2053 		      if (ocontents == NULL)
   2054 			{
   2055 			  if (elf_section_data (o)->this_hdr.contents != NULL)
   2056 			    ocontents = elf_section_data (o)->this_hdr.contents;
   2057 			  else
   2058 			    {
   2059 			      /* We always cache the section contents.
   2060 				 Perhaps, if info->keep_memory is FALSE, we
   2061 				 should free them, if we are permitted to.  */
   2062 
   2063 			      if (o->rawsize == 0)
   2064 				o->rawsize = o->size;
   2065 			      ocontents = (bfd_byte *) bfd_malloc (o->rawsize);
   2066 			      if (ocontents == NULL)
   2067 				goto error_return;
   2068 			      if (!bfd_get_section_contents (abfd, o, ocontents,
   2069 							     (file_ptr) 0,
   2070 							     o->rawsize))
   2071 				goto error_return;
   2072 			      elf_section_data (o)->this_hdr.contents = ocontents;
   2073 			    }
   2074 			}
   2075 		      irelscan->r_addend -= calc_fixup (irel->r_addend
   2076 							+ isym->st_value,
   2077 							0,
   2078 							sec);
   2079 		    }
   2080 		}
   2081 	      else if ((ELF32_R_TYPE (irelscan->r_info) == (int) R_MICROBLAZE_32_PCREL_LO)
   2082 		       || (ELF32_R_TYPE (irelscan->r_info)
   2083 				   == (int) R_MICROBLAZE_32_LO)
   2084 		       || (ELF32_R_TYPE (irelscan->r_info)
   2085 				   == (int) R_MICROBLAZE_TEXTREL_32_LO))
   2086 		{
   2087 		  isym = isymbuf + ELF32_R_SYM (irelscan->r_info);
   2088 
   2089 		  /* Look at the reloc only if the value has been resolved.  */
   2090 		  if (isym->st_shndx == shndx
   2091 		      && (ELF32_ST_TYPE (isym->st_info) == STT_SECTION))
   2092 		    {
   2093 		      bfd_vma immediate;
   2094 		      bfd_vma target_address;
   2095 
   2096 		      if (ocontents == NULL)
   2097 			{
   2098 			  if (elf_section_data (o)->this_hdr.contents != NULL)
   2099 			    ocontents = elf_section_data (o)->this_hdr.contents;
   2100 			  else
   2101 			    {
   2102 			      /* We always cache the section contents.
   2103 				 Perhaps, if info->keep_memory is FALSE, we
   2104 				 should free them, if we are permitted to.  */
   2105 			      if (o->rawsize == 0)
   2106 				o->rawsize = o->size;
   2107 			      ocontents = (bfd_byte *) bfd_malloc (o->rawsize);
   2108 			      if (ocontents == NULL)
   2109 				goto error_return;
   2110 			      if (!bfd_get_section_contents (abfd, o, ocontents,
   2111 							     (file_ptr) 0,
   2112 							     o->rawsize))
   2113 				goto error_return;
   2114 			      elf_section_data (o)->this_hdr.contents = ocontents;
   2115 			    }
   2116 			}
   2117 
   2118 		      unsigned long instr = bfd_get_32 (abfd, ocontents + irelscan->r_offset);
   2119 		      immediate = instr & 0x0000ffff;
   2120 		      target_address = immediate;
   2121 		      offset = calc_fixup (target_address, 0, sec);
   2122 		      immediate -= offset;
   2123 		      irelscan->r_addend -= offset;
   2124 	  microblaze_bfd_write_imm_value_32 (abfd, ocontents + irelscan->r_offset,
   2125 					     irelscan->r_addend);
   2126 		    }
   2127 		}
   2128 
   2129 	      if (ELF32_R_TYPE (irelscan->r_info) == (int) R_MICROBLAZE_64
   2130 		  || (ELF32_R_TYPE (irelscan->r_info)
   2131 			      == (int) R_MICROBLAZE_TEXTREL_64))
   2132 		{
   2133 		  isym = isymbuf + ELF32_R_SYM (irelscan->r_info);
   2134 
   2135 		  /* Look at the reloc only if the value has been resolved.  */
   2136 		  if (isym->st_shndx == shndx
   2137 		      && (ELF32_ST_TYPE (isym->st_info) == STT_SECTION))
   2138 		    {
   2139 		      if (ocontents == NULL)
   2140 			{
   2141 			  if (elf_section_data (o)->this_hdr.contents != NULL)
   2142 			    ocontents = elf_section_data (o)->this_hdr.contents;
   2143 			  else
   2144 			    {
   2145 			      /* We always cache the section contents.
   2146 				 Perhaps, if info->keep_memory is FALSE, we
   2147 				 should free them, if we are permitted to.  */
   2148 
   2149 			      if (o->rawsize == 0)
   2150 				o->rawsize = o->size;
   2151 			      ocontents = (bfd_byte *) bfd_malloc (o->rawsize);
   2152 			      if (ocontents == NULL)
   2153 				goto error_return;
   2154 			      if (!bfd_get_section_contents (abfd, o, ocontents,
   2155 							     (file_ptr) 0,
   2156 							     o->rawsize))
   2157 				goto error_return;
   2158 			      elf_section_data (o)->this_hdr.contents = ocontents;
   2159 			    }
   2160 			}
   2161 		      offset = calc_fixup (irelscan->r_addend, 0, sec);
   2162 		      irelscan->r_addend -= offset;
   2163 		    }
   2164 		}
   2165 	      else if (ELF32_R_TYPE (irelscan->r_info) == (int) R_MICROBLAZE_64_PCREL)
   2166 		{
   2167 		  isym = isymbuf + ELF32_R_SYM (irelscan->r_info);
   2168 
   2169 		  /* Look at the reloc only if the value has been resolved.  */
   2170 		  if (isym->st_shndx == shndx
   2171 		      && (ELF32_ST_TYPE (isym->st_info) == STT_SECTION))
   2172 		    {
   2173 		      bfd_vma immediate;
   2174 		      bfd_vma target_address;
   2175 
   2176 		      if (ocontents == NULL)
   2177 			{
   2178 			  if (elf_section_data (o)->this_hdr.contents != NULL)
   2179 			    ocontents = elf_section_data (o)->this_hdr.contents;
   2180 			  else
   2181 			    {
   2182 			      /* We always cache the section contents.
   2183 				 Perhaps, if info->keep_memory is FALSE, we
   2184 				 should free them, if we are permitted to.  */
   2185 			      if (o->rawsize == 0)
   2186 				o->rawsize = o->size;
   2187 			      ocontents = (bfd_byte *) bfd_malloc (o->rawsize);
   2188 			      if (ocontents == NULL)
   2189 				goto error_return;
   2190 			      if (!bfd_get_section_contents (abfd, o, ocontents,
   2191 							     (file_ptr) 0,
   2192 							     o->rawsize))
   2193 				goto error_return;
   2194 			      elf_section_data (o)->this_hdr.contents = ocontents;
   2195 			    }
   2196 			}
   2197 	  unsigned long instr_hi =  bfd_get_32 (abfd, ocontents
   2198 						+ irelscan->r_offset);
   2199 	  unsigned long instr_lo =  bfd_get_32 (abfd, ocontents
   2200 						+ irelscan->r_offset
   2201 						+ INST_WORD_SIZE);
   2202 	  immediate = (instr_hi & 0x0000ffff) << 16;
   2203 	  immediate |= (instr_lo & 0x0000ffff);
   2204 		      target_address = immediate;
   2205 		      offset = calc_fixup (target_address, 0, sec);
   2206 		      immediate -= offset;
   2207 		      irelscan->r_addend -= offset;
   2208 	  microblaze_bfd_write_imm_value_64 (abfd, ocontents
   2209 					     + irelscan->r_offset, immediate);
   2210 		    }
   2211 		}
   2212 	    }
   2213 	}
   2214 
   2215       /* Adjust the local symbols defined in this section.  */
   2216       isymend = isymbuf + symtab_hdr->sh_info;
   2217       for (isym = isymbuf; isym < isymend; isym++)
   2218 	{
   2219 	  if (isym->st_shndx == shndx)
   2220 	    {
   2221 	      isym->st_value -= calc_fixup (isym->st_value, 0, sec);
   2222 	      if (isym->st_size)
   2223 		isym->st_size -= calc_fixup (isym->st_value, isym->st_size, sec);
   2224 	    }
   2225 	}
   2226 
   2227       /* Now adjust the global symbols defined in this section.  */
   2228       isym = isymbuf + symtab_hdr->sh_info;
   2229       symcount =  (symtab_hdr->sh_size / sizeof (Elf32_External_Sym)) - symtab_hdr->sh_info;
   2230       for (sym_index = 0; sym_index < symcount; sym_index++)
   2231 	{
   2232 	  sym_hash = elf_sym_hashes (abfd)[sym_index];
   2233 	  if ((sym_hash->root.type == bfd_link_hash_defined
   2234 		  || sym_hash->root.type == bfd_link_hash_defweak)
   2235 	      && sym_hash->root.u.def.section == sec)
   2236 	    {
   2237 	      sym_hash->root.u.def.value -= calc_fixup (sym_hash->root.u.def.value,
   2238 							0, sec);
   2239 	      if (sym_hash->size)
   2240 		sym_hash->size -= calc_fixup (sym_hash->root.u.def.value,
   2241 					      sym_hash->size, sec);
   2242 	    }
   2243 	}
   2244 
   2245       /* Physically move the code and change the cooked size.  */
   2246       dest = sdata->relax[0].addr;
   2247       for (i = 0; i < sdata->relax_count; i++)
   2248 	{
   2249 	  size_t len;
   2250 	  src = sdata->relax[i].addr + sdata->relax[i].size;
   2251 	  len = (sdata->relax[i+1].addr - sdata->relax[i].addr
   2252 		 - sdata->relax[i].size);
   2253 
   2254 	  memmove (contents + dest, contents + src, len);
   2255 	  sec->size -= sdata->relax[i].size;
   2256 	  dest += len;
   2257 	}
   2258 
   2259       elf_section_data (sec)->relocs = internal_relocs;
   2260       free_relocs = NULL;
   2261 
   2262       elf_section_data (sec)->this_hdr.contents = contents;
   2263       free_contents = NULL;
   2264 
   2265       symtab_hdr->contents = (bfd_byte *) isymbuf;
   2266     }
   2267 
   2268   free (free_relocs);
   2269   free_relocs = NULL;
   2270 
   2271   if (free_contents != NULL)
   2272     {
   2273       if (!link_info->keep_memory)
   2274 	free (free_contents);
   2275       else
   2276 	/* Cache the section contents for elf_link_input_bfd.  */
   2277 	elf_section_data (sec)->this_hdr.contents = contents;
   2278       free_contents = NULL;
   2279     }
   2280 
   2281   if (sdata->relax_count == 0)
   2282     {
   2283       *again = false;
   2284       free (sdata->relax);
   2285       sdata->relax = NULL;
   2286     }
   2287   else
   2288     *again = true;
   2289   return true;
   2290 
   2291  error_return:
   2292   free (free_relocs);
   2293   free (free_contents);
   2294   free (sdata->relax);
   2295   sdata->relax = NULL;
   2296   sdata->relax_count = 0;
   2297   return false;
   2298 }
   2299 
   2300 /* Return the section that should be marked against GC for a given
   2301    relocation.  */
   2302 
   2303 static asection *
   2304 microblaze_elf_gc_mark_hook (asection *sec,
   2305 			     struct bfd_link_info * info,
   2306 			     Elf_Internal_Rela * rel,
   2307 			     struct elf_link_hash_entry * h,
   2308 			     Elf_Internal_Sym * sym)
   2309 {
   2310   if (h != NULL)
   2311     switch (ELF32_R_TYPE (rel->r_info))
   2312       {
   2313       case R_MICROBLAZE_GNU_VTINHERIT:
   2314       case R_MICROBLAZE_GNU_VTENTRY:
   2315 	return NULL;
   2316       }
   2317 
   2318   return _bfd_elf_gc_mark_hook (sec, info, rel, h, sym);
   2319 }
   2320 
   2321 /* PIC support.  */
   2322 
   2323 #define PLT_ENTRY_SIZE 16
   2324 
   2325 #define PLT_ENTRY_WORD_0  0xb0000000	      /* "imm 0".  */
   2326 #define PLT_ENTRY_WORD_1  0xe9940000	      /* "lwi r12,r20,0" - relocated to lwi r12,r20,func@GOT.  */
   2327 #define PLT_ENTRY_WORD_1_NOPIC	0xe9800000    /* "lwi r12,r0,0" - non-PIC object.  */
   2328 #define PLT_ENTRY_WORD_2  0x98186000	      /* "brad r12".  */
   2329 #define PLT_ENTRY_WORD_3  0x80000000	      /* "nop".  */
   2330 
   2331 static bool
   2332 update_local_sym_info (bfd *abfd,
   2333 		       Elf_Internal_Shdr *symtab_hdr,
   2334 		       unsigned long r_symndx,
   2335 		       unsigned int tls_type)
   2336 {
   2337   bfd_signed_vma *local_got_refcounts = elf_local_got_refcounts (abfd);
   2338   unsigned char *local_got_tls_masks;
   2339 
   2340   if (local_got_refcounts == NULL)
   2341     {
   2342       bfd_size_type size = symtab_hdr->sh_info;
   2343 
   2344       size *= (sizeof (*local_got_refcounts) + sizeof (*local_got_tls_masks));
   2345       local_got_refcounts = bfd_zalloc (abfd, size);
   2346       if (local_got_refcounts == NULL)
   2347 	return false;
   2348       elf_local_got_refcounts (abfd) = local_got_refcounts;
   2349     }
   2350 
   2351   local_got_tls_masks =
   2352 	 (unsigned char *) (local_got_refcounts + symtab_hdr->sh_info);
   2353   local_got_tls_masks[r_symndx] |= tls_type;
   2354   local_got_refcounts[r_symndx] += 1;
   2355 
   2356   return true;
   2357 }
   2358 /* Look through the relocs for a section during the first phase.  */
   2359 
   2360 static bool
   2361 microblaze_elf_check_relocs (bfd * abfd,
   2362 			     struct bfd_link_info * info,
   2363 			     asection * sec,
   2364 			     const Elf_Internal_Rela * relocs)
   2365 {
   2366   Elf_Internal_Shdr *		symtab_hdr;
   2367   struct elf_link_hash_entry ** sym_hashes;
   2368   const Elf_Internal_Rela *	rel;
   2369   const Elf_Internal_Rela *	rel_end;
   2370   struct elf32_mb_link_hash_table *htab;
   2371   asection *sreloc = NULL;
   2372 
   2373   if (bfd_link_relocatable (info))
   2374     return true;
   2375 
   2376   htab = elf32_mb_hash_table (info);
   2377   if (htab == NULL)
   2378     return false;
   2379 
   2380   symtab_hdr = & elf_tdata (abfd)->symtab_hdr;
   2381   sym_hashes = elf_sym_hashes (abfd);
   2382 
   2383   rel_end = relocs + sec->reloc_count;
   2384 
   2385   for (rel = relocs; rel < rel_end; rel++)
   2386     {
   2387       unsigned int r_type;
   2388       struct elf_link_hash_entry * h;
   2389       unsigned long r_symndx;
   2390       unsigned char tls_type = 0;
   2391 
   2392       r_symndx = ELF32_R_SYM (rel->r_info);
   2393       r_type = ELF32_R_TYPE (rel->r_info);
   2394 
   2395       if (r_symndx < symtab_hdr->sh_info)
   2396 	h = NULL;
   2397       else
   2398 	{
   2399 	  h = sym_hashes [r_symndx - symtab_hdr->sh_info];
   2400 	  while (h->root.type == bfd_link_hash_indirect
   2401 		 || h->root.type == bfd_link_hash_warning)
   2402 	    h = (struct elf_link_hash_entry *) h->root.u.i.link;
   2403 	}
   2404 
   2405       switch (r_type)
   2406 	{
   2407 	  /* This relocation describes the C++ object vtable hierarchy.
   2408 	     Reconstruct it for later use during GC.  */
   2409 	case R_MICROBLAZE_GNU_VTINHERIT:
   2410 	  if (!bfd_elf_gc_record_vtinherit (abfd, sec, h, rel->r_offset))
   2411 	    return false;
   2412 	  break;
   2413 
   2414 	  /* This relocation describes which C++ vtable entries are actually
   2415 	     used.  Record for later use during GC.  */
   2416 	case R_MICROBLAZE_GNU_VTENTRY:
   2417 	  if (!bfd_elf_gc_record_vtentry (abfd, sec, h, rel->r_addend))
   2418 	    return false;
   2419 	  break;
   2420 
   2421 	  /* This relocation requires .plt entry.  */
   2422 	case R_MICROBLAZE_PLT_64:
   2423 	  if (h != NULL)
   2424 	    {
   2425 	      h->needs_plt = 1;
   2426 	      h->plt.refcount += 1;
   2427 	    }
   2428 	  break;
   2429 
   2430 	  /* This relocation requires .got entry.  */
   2431 	case R_MICROBLAZE_TLSGD:
   2432 	  tls_type |= (TLS_TLS | TLS_GD);
   2433 	  goto dogottls;
   2434 	case R_MICROBLAZE_TLSLD:
   2435 	  tls_type |= (TLS_TLS | TLS_LD);
   2436 	  /* Fall through.  */
   2437 	dogottls:
   2438 	  sec->has_tls_reloc = 1;
   2439 	  /* Fall through.  */
   2440 	case R_MICROBLAZE_GOT_64:
   2441 	  if (htab->elf.sgot == NULL)
   2442 	    {
   2443 	      if (htab->elf.dynobj == NULL)
   2444 		htab->elf.dynobj = abfd;
   2445 	      if (!_bfd_elf_create_got_section (htab->elf.dynobj, info))
   2446 		return false;
   2447 	    }
   2448 	  if (h != NULL)
   2449 	    {
   2450 	      h->got.refcount += 1;
   2451 	      elf32_mb_hash_entry (h)->tls_mask |= tls_type;
   2452 	    }
   2453 	  else
   2454 	    {
   2455 	      if (! update_local_sym_info(abfd, symtab_hdr, r_symndx, tls_type) )
   2456 		return false;
   2457 	    }
   2458 	  break;
   2459 
   2460 	case R_MICROBLAZE_GOTOFF_64:
   2461 	case R_MICROBLAZE_GOTOFF_32:
   2462 	  if (htab->elf.sgot == NULL)
   2463 	    {
   2464 	      if (htab->elf.dynobj == NULL)
   2465 		htab->elf.dynobj = abfd;
   2466 	      if (!_bfd_elf_create_got_section (htab->elf.dynobj, info))
   2467 		return false;
   2468 	    }
   2469 	  break;
   2470 
   2471 	case R_MICROBLAZE_64:
   2472 	case R_MICROBLAZE_64_PCREL:
   2473 	case R_MICROBLAZE_32:
   2474 	  {
   2475 	    if (h != NULL && !bfd_link_pic (info))
   2476 	      {
   2477 		/* we may need a copy reloc.  */
   2478 		h->non_got_ref = 1;
   2479 
   2480 		/* we may also need a .plt entry.  */
   2481 		h->plt.refcount += 1;
   2482 		if (ELF32_R_TYPE (rel->r_info) != R_MICROBLAZE_64_PCREL)
   2483 		  h->pointer_equality_needed = 1;
   2484 	      }
   2485 
   2486 
   2487 	    /* If we are creating a shared library, and this is a reloc
   2488 	       against a global symbol, or a non PC relative reloc
   2489 	       against a local symbol, then we need to copy the reloc
   2490 	       into the shared library.  However, if we are linking with
   2491 	       -Bsymbolic, we do not need to copy a reloc against a
   2492 	       global symbol which is defined in an object we are
   2493 	       including in the link (i.e., DEF_REGULAR is set).  At
   2494 	       this point we have not seen all the input files, so it is
   2495 	       possible that DEF_REGULAR is not set now but will be set
   2496 	       later (it is never cleared).  In case of a weak definition,
   2497 	       DEF_REGULAR may be cleared later by a strong definition in
   2498 	       a shared library.  We account for that possibility below by
   2499 	       storing information in the relocs_copied field of the hash
   2500 	       table entry.  A similar situation occurs when creating
   2501 	       shared libraries and symbol visibility changes render the
   2502 	       symbol local.
   2503 
   2504 	       If on the other hand, we are creating an executable, we
   2505 	       may need to keep relocations for symbols satisfied by a
   2506 	       dynamic library if we manage to avoid copy relocs for the
   2507 	       symbol.  */
   2508 
   2509 	    if ((bfd_link_pic (info)
   2510 		 && (sec->flags & SEC_ALLOC) != 0
   2511 		 && (r_type != R_MICROBLAZE_64_PCREL
   2512 		     || (h != NULL
   2513 			 && (! info->symbolic
   2514 			     || h->root.type == bfd_link_hash_defweak
   2515 			     || !h->def_regular))))
   2516 		|| (!bfd_link_pic (info)
   2517 		    && (sec->flags & SEC_ALLOC) != 0
   2518 		    && h != NULL
   2519 		    && (h->root.type == bfd_link_hash_defweak
   2520 			|| !h->def_regular)))
   2521 	      {
   2522 		struct elf_dyn_relocs *p;
   2523 		struct elf_dyn_relocs **head;
   2524 
   2525 		/* When creating a shared object, we must copy these
   2526 		   relocs into the output file.  We create a reloc
   2527 		   section in dynobj and make room for the reloc.  */
   2528 
   2529 		if (sreloc == NULL)
   2530 		  {
   2531 		    bfd *dynobj;
   2532 
   2533 		    if (htab->elf.dynobj == NULL)
   2534 		      htab->elf.dynobj = abfd;
   2535 		    dynobj = htab->elf.dynobj;
   2536 
   2537 		    sreloc = _bfd_elf_make_dynamic_reloc_section (sec, dynobj,
   2538 								  2, abfd, 1);
   2539 		    if (sreloc == NULL)
   2540 		      return false;
   2541 		  }
   2542 
   2543 		/* If this is a global symbol, we count the number of
   2544 		   relocations we need for this symbol.  */
   2545 		if (h != NULL)
   2546 		  head = &h->dyn_relocs;
   2547 		else
   2548 		  {
   2549 		    /* Track dynamic relocs needed for local syms too.
   2550 		       We really need local syms available to do this
   2551 		       easily.  Oh well.  */
   2552 
   2553 		    asection *s;
   2554 		    Elf_Internal_Sym *isym;
   2555 		    void *vpp;
   2556 
   2557 		    isym = bfd_sym_from_r_symndx (&htab->elf.sym_cache,
   2558 						  abfd, r_symndx);
   2559 		    if (isym == NULL)
   2560 		      return false;
   2561 
   2562 		    s = bfd_section_from_elf_index (abfd, isym->st_shndx);
   2563 		    if (s == NULL)
   2564 		      return false;
   2565 
   2566 		    vpp = &elf_section_data (s)->local_dynrel;
   2567 		    head = (struct elf_dyn_relocs **) vpp;
   2568 		  }
   2569 
   2570 		p = *head;
   2571 		if (p == NULL || p->sec != sec)
   2572 		  {
   2573 		    size_t amt = sizeof *p;
   2574 		    p = ((struct elf_dyn_relocs *)
   2575 			 bfd_alloc (htab->elf.dynobj, amt));
   2576 		    if (p == NULL)
   2577 		      return false;
   2578 		    p->next = *head;
   2579 		    *head = p;
   2580 		    p->sec = sec;
   2581 		    p->count = 0;
   2582 		    p->pc_count = 0;
   2583 		  }
   2584 
   2585 		p->count += 1;
   2586 		if (r_type == R_MICROBLAZE_64_PCREL)
   2587 		  p->pc_count += 1;
   2588 	      }
   2589 	  }
   2590 	  break;
   2591 	}
   2592     }
   2593 
   2594   return true;
   2595 }
   2596 
   2597 /* Copy the extra info we tack onto an elf_link_hash_entry.  */
   2598 
   2599 static void
   2600 microblaze_elf_copy_indirect_symbol (struct bfd_link_info *info,
   2601 				     struct elf_link_hash_entry *dir,
   2602 				     struct elf_link_hash_entry *ind)
   2603 {
   2604   struct elf32_mb_link_hash_entry *edir, *eind;
   2605 
   2606   edir = (struct elf32_mb_link_hash_entry *) dir;
   2607   eind = (struct elf32_mb_link_hash_entry *) ind;
   2608 
   2609   edir->tls_mask |= eind->tls_mask;
   2610 
   2611   _bfd_elf_link_hash_copy_indirect (info, dir, ind);
   2612 }
   2613 
   2614 static bool
   2615 microblaze_elf_adjust_dynamic_symbol (struct bfd_link_info *info,
   2616 				      struct elf_link_hash_entry *h)
   2617 {
   2618   struct elf32_mb_link_hash_table *htab;
   2619   asection *s, *srel;
   2620   unsigned int power_of_two;
   2621 
   2622   htab = elf32_mb_hash_table (info);
   2623   if (htab == NULL)
   2624     return false;
   2625 
   2626   /* If this is a function, put it in the procedure linkage table.  We
   2627      will fill in the contents of the procedure linkage table later,
   2628      when we know the address of the .got section.  */
   2629   if (h->type == STT_FUNC
   2630       || h->needs_plt)
   2631     {
   2632       if (h->plt.refcount <= 0
   2633 	  || SYMBOL_CALLS_LOCAL (info, h)
   2634 	  || (ELF_ST_VISIBILITY (h->other) != STV_DEFAULT
   2635 	      && h->root.type == bfd_link_hash_undefweak))
   2636 	{
   2637 	  /* This case can occur if we saw a PLT reloc in an input
   2638 	     file, but the symbol was never referred to by a dynamic
   2639 	     object, or if all references were garbage collected.  In
   2640 	     such a case, we don't actually need to build a procedure
   2641 	     linkage table, and we can just do a PC32 reloc instead.  */
   2642 	  h->plt.offset = (bfd_vma) -1;
   2643 	  h->needs_plt = 0;
   2644 	}
   2645 
   2646       return true;
   2647     }
   2648   else
   2649     /* It's possible that we incorrectly decided a .plt reloc was
   2650        needed for an R_MICROBLAZE_64_PCREL reloc to a non-function sym in
   2651        check_relocs.  We can't decide accurately between function and
   2652        non-function syms in check-relocs;  Objects loaded later in
   2653        the link may change h->type.  So fix it now.  */
   2654     h->plt.offset = (bfd_vma) -1;
   2655 
   2656   /* If this is a weak symbol, and there is a real definition, the
   2657      processor independent code will have arranged for us to see the
   2658      real definition first, and we can just use the same value.  */
   2659   if (h->is_weakalias)
   2660     {
   2661       struct elf_link_hash_entry *def = weakdef (h);
   2662       BFD_ASSERT (def->root.type == bfd_link_hash_defined);
   2663       h->root.u.def.section = def->root.u.def.section;
   2664       h->root.u.def.value = def->root.u.def.value;
   2665       return true;
   2666     }
   2667 
   2668   /* This is a reference to a symbol defined by a dynamic object which
   2669      is not a function.  */
   2670 
   2671   /* If we are creating a shared library, we must presume that the
   2672      only references to the symbol are via the global offset table.
   2673      For such cases we need not do anything here; the relocations will
   2674      be handled correctly by relocate_section.  */
   2675   if (bfd_link_pic (info))
   2676     return true;
   2677 
   2678   /* If there are no references to this symbol that do not use the
   2679      GOT, we don't need to generate a copy reloc.  */
   2680   if (!h->non_got_ref)
   2681     return true;
   2682 
   2683   /* If -z nocopyreloc was given, we won't generate them either.  */
   2684   if (info->nocopyreloc)
   2685     {
   2686       h->non_got_ref = 0;
   2687       return true;
   2688     }
   2689 
   2690   /* If we don't find any dynamic relocs in read-only sections, then
   2691      we'll be keeping the dynamic relocs and avoiding the copy reloc.  */
   2692   if (!_bfd_elf_readonly_dynrelocs (h))
   2693     {
   2694       h->non_got_ref = 0;
   2695       return true;
   2696     }
   2697 
   2698   /* We must allocate the symbol in our .dynbss section, which will
   2699      become part of the .bss section of the executable.  There will be
   2700      an entry for this symbol in the .dynsym section.  The dynamic
   2701      object will contain position independent code, so all references
   2702      from the dynamic object to this symbol will go through the global
   2703      offset table.  The dynamic linker will use the .dynsym entry to
   2704      determine the address it must put in the global offset table, so
   2705      both the dynamic object and the regular object will refer to the
   2706      same memory location for the variable.  */
   2707 
   2708   /* We must generate a R_MICROBLAZE_COPY reloc to tell the dynamic linker
   2709      to copy the initial value out of the dynamic object and into the
   2710      runtime process image.  */
   2711   if ((h->root.u.def.section->flags & SEC_READONLY) != 0)
   2712     {
   2713       s = htab->elf.sdynrelro;
   2714       srel = htab->elf.sreldynrelro;
   2715     }
   2716   else
   2717     {
   2718       s = htab->elf.sdynbss;
   2719       srel = htab->elf.srelbss;
   2720     }
   2721   if ((h->root.u.def.section->flags & SEC_ALLOC) != 0)
   2722     {
   2723       srel->size += sizeof (Elf32_External_Rela);
   2724       h->needs_copy = 1;
   2725     }
   2726 
   2727   /* We need to figure out the alignment required for this symbol.  I
   2728      have no idea how ELF linkers handle this.  */
   2729   power_of_two = bfd_log2 (h->size);
   2730   if (power_of_two > 3)
   2731     power_of_two = 3;
   2732 
   2733   /* Apply the required alignment.  */
   2734   s->size = BFD_ALIGN (s->size, (bfd_size_type) (1 << power_of_two));
   2735   if (power_of_two > s->alignment_power)
   2736     {
   2737       if (!bfd_set_section_alignment (s, power_of_two))
   2738 	return false;
   2739     }
   2740 
   2741   /* Define the symbol as being at this point in the section.  */
   2742   h->root.u.def.section = s;
   2743   h->root.u.def.value = s->size;
   2744 
   2745   /* Increment the section size to make room for the symbol.  */
   2746   s->size += h->size;
   2747   return true;
   2748 }
   2749 
   2750 /* Allocate space in .plt, .got and associated reloc sections for
   2751    dynamic relocs.  */
   2752 
   2753 static bool
   2754 allocate_dynrelocs (struct elf_link_hash_entry *h, void * dat)
   2755 {
   2756   struct bfd_link_info *info;
   2757   struct elf32_mb_link_hash_table *htab;
   2758   struct elf32_mb_link_hash_entry *eh;
   2759   struct elf_dyn_relocs *p;
   2760 
   2761   if (h->root.type == bfd_link_hash_indirect)
   2762     return true;
   2763 
   2764   info = (struct bfd_link_info *) dat;
   2765   htab = elf32_mb_hash_table (info);
   2766   if (htab == NULL)
   2767     return false;
   2768 
   2769   if (htab->elf.dynamic_sections_created
   2770       && h->plt.refcount > 0)
   2771     {
   2772       /* Make sure this symbol is output as a dynamic symbol.
   2773 	 Undefined weak syms won't yet be marked as dynamic.  */
   2774       if (h->dynindx == -1
   2775 	  && !h->forced_local)
   2776 	{
   2777 	  if (! bfd_elf_link_record_dynamic_symbol (info, h))
   2778 	    return false;
   2779 	}
   2780 
   2781       if (WILL_CALL_FINISH_DYNAMIC_SYMBOL (1, bfd_link_pic (info), h))
   2782 	{
   2783 	  asection *s = htab->elf.splt;
   2784 
   2785 	  /* The first entry in .plt is reserved.  */
   2786 	  if (s->size == 0)
   2787 	    s->size = PLT_ENTRY_SIZE;
   2788 
   2789 	  h->plt.offset = s->size;
   2790 
   2791 	  /* If this symbol is not defined in a regular file, and we are
   2792 	     not generating a shared library, then set the symbol to this
   2793 	     location in the .plt.  This is required to make function
   2794 	     pointers compare as equal between the normal executable and
   2795 	     the shared library.  */
   2796 	  if (! bfd_link_pic (info)
   2797 	      && !h->def_regular)
   2798 	    {
   2799 	      h->root.u.def.section = s;
   2800 	      h->root.u.def.value = h->plt.offset;
   2801 	    }
   2802 
   2803 	  /* Make room for this entry.  */
   2804 	  s->size += PLT_ENTRY_SIZE;
   2805 
   2806 	  /* We also need to make an entry in the .got.plt section, which
   2807 	     will be placed in the .got section by the linker script.  */
   2808 	  htab->elf.sgotplt->size += 4;
   2809 
   2810 	  /* We also need to make an entry in the .rel.plt section.  */
   2811 	  htab->elf.srelplt->size += sizeof (Elf32_External_Rela);
   2812 	}
   2813       else
   2814 	{
   2815 	  h->plt.offset = (bfd_vma) -1;
   2816 	  h->needs_plt = 0;
   2817 	}
   2818     }
   2819   else
   2820     {
   2821       h->plt.offset = (bfd_vma) -1;
   2822       h->needs_plt = 0;
   2823     }
   2824 
   2825   eh = (struct elf32_mb_link_hash_entry *) h;
   2826   if (h->got.refcount > 0)
   2827     {
   2828       unsigned int need;
   2829       asection *s;
   2830 
   2831       /* Make sure this symbol is output as a dynamic symbol.
   2832 	 Undefined weak syms won't yet be marked as dynamic.  */
   2833       if (h->dynindx == -1
   2834 	  && !h->forced_local)
   2835 	{
   2836 	  if (! bfd_elf_link_record_dynamic_symbol (info, h))
   2837 	    return false;
   2838 	}
   2839 
   2840       need = 0;
   2841       if ((eh->tls_mask & TLS_TLS) != 0)
   2842 	{
   2843 	  /* Handle TLS Symbol */
   2844 	  if ((eh->tls_mask & TLS_LD) != 0)
   2845 	    {
   2846 	      if (!eh->elf.def_dynamic)
   2847 		/* We'll just use htab->tlsld_got.offset.  This should
   2848 		   always be the case.  It's a little odd if we have
   2849 		   a local dynamic reloc against a non-local symbol.  */
   2850 		htab->tlsld_got.refcount += 1;
   2851 	      else
   2852 		need += 8;
   2853 	    }
   2854 	  if ((eh->tls_mask & TLS_GD) != 0)
   2855 	    need += 8;
   2856 	}
   2857       else
   2858 	{
   2859 	  /* Regular (non-TLS) symbol */
   2860 	  need += 4;
   2861 	}
   2862       if (need == 0)
   2863 	{
   2864 	  h->got.offset = (bfd_vma) -1;
   2865 	}
   2866       else
   2867 	{
   2868 	  s = htab->elf.sgot;
   2869 	  h->got.offset = s->size;
   2870 	  s->size += need;
   2871 	  htab->elf.srelgot->size += need * (sizeof (Elf32_External_Rela) / 4);
   2872 	}
   2873     }
   2874   else
   2875     h->got.offset = (bfd_vma) -1;
   2876 
   2877   if (h->dyn_relocs == NULL)
   2878     return true;
   2879 
   2880   /* In the shared -Bsymbolic case, discard space allocated for
   2881      dynamic pc-relative relocs against symbols which turn out to be
   2882      defined in regular objects.  For the normal shared case, discard
   2883      space for pc-relative relocs that have become local due to symbol
   2884      visibility changes.  */
   2885 
   2886   if (bfd_link_pic (info))
   2887     {
   2888       if (h->def_regular
   2889 	  && (h->forced_local
   2890 	      || info->symbolic))
   2891 	{
   2892 	  struct elf_dyn_relocs **pp;
   2893 
   2894 	  for (pp = &h->dyn_relocs; (p = *pp) != NULL; )
   2895 	    {
   2896 	      p->count -= p->pc_count;
   2897 	      p->pc_count = 0;
   2898 	      if (p->count == 0)
   2899 		*pp = p->next;
   2900 	      else
   2901 		pp = &p->next;
   2902 	    }
   2903 	}
   2904       else if (UNDEFWEAK_NO_DYNAMIC_RELOC (info, h))
   2905 	h->dyn_relocs = NULL;
   2906     }
   2907   else
   2908     {
   2909       /* For the non-shared case, discard space for relocs against
   2910 	 symbols which turn out to need copy relocs or are not
   2911 	 dynamic.  */
   2912 
   2913       if (!h->non_got_ref
   2914 	  && ((h->def_dynamic
   2915 	       && !h->def_regular)
   2916 	      || (htab->elf.dynamic_sections_created
   2917 		  && (h->root.type == bfd_link_hash_undefweak
   2918 		      || h->root.type == bfd_link_hash_undefined))))
   2919 	{
   2920 	  /* Make sure this symbol is output as a dynamic symbol.
   2921 	     Undefined weak syms won't yet be marked as dynamic.  */
   2922 	  if (h->dynindx == -1
   2923 	      && !h->forced_local)
   2924 	    {
   2925 	      if (! bfd_elf_link_record_dynamic_symbol (info, h))
   2926 		return false;
   2927 	    }
   2928 
   2929 	  /* If that succeeded, we know we'll be keeping all the
   2930 	     relocs.  */
   2931 	  if (h->dynindx != -1)
   2932 	    goto keep;
   2933 	}
   2934 
   2935       h->dyn_relocs = NULL;
   2936 
   2937     keep: ;
   2938     }
   2939 
   2940   /* Finally, allocate space.  */
   2941   for (p = h->dyn_relocs; p != NULL; p = p->next)
   2942     {
   2943       asection *sreloc = elf_section_data (p->sec)->sreloc;
   2944       sreloc->size += p->count * sizeof (Elf32_External_Rela);
   2945     }
   2946 
   2947   return true;
   2948 }
   2949 
   2950 /* Set the sizes of the dynamic sections.  */
   2951 
   2952 static bool
   2953 microblaze_elf_size_dynamic_sections (bfd *output_bfd ATTRIBUTE_UNUSED,
   2954 				      struct bfd_link_info *info)
   2955 {
   2956   struct elf32_mb_link_hash_table *htab;
   2957   bfd *dynobj;
   2958   asection *s;
   2959   bfd *ibfd;
   2960 
   2961   htab = elf32_mb_hash_table (info);
   2962   if (htab == NULL)
   2963     return false;
   2964 
   2965   dynobj = htab->elf.dynobj;
   2966   BFD_ASSERT (dynobj != NULL);
   2967 
   2968   /* Set up .got offsets for local syms, and space for local dynamic
   2969      relocs.  */
   2970   for (ibfd = info->input_bfds; ibfd != NULL; ibfd = ibfd->link.next)
   2971     {
   2972       bfd_signed_vma *local_got;
   2973       bfd_signed_vma *end_local_got;
   2974       bfd_size_type locsymcount;
   2975       Elf_Internal_Shdr *symtab_hdr;
   2976       unsigned char *lgot_masks;
   2977       asection *srel;
   2978 
   2979       if (bfd_get_flavour (ibfd) != bfd_target_elf_flavour)
   2980 	continue;
   2981 
   2982       for (s = ibfd->sections; s != NULL; s = s->next)
   2983 	{
   2984 	  struct elf_dyn_relocs *p;
   2985 
   2986 	  for (p = ((struct elf_dyn_relocs *)
   2987 		    elf_section_data (s)->local_dynrel);
   2988 	       p != NULL;
   2989 	       p = p->next)
   2990 	    {
   2991 	      if (!bfd_is_abs_section (p->sec)
   2992 		  && bfd_is_abs_section (p->sec->output_section))
   2993 		{
   2994 		  /* Input section has been discarded, either because
   2995 		     it is a copy of a linkonce section or due to
   2996 		     linker script /DISCARD/, so we'll be discarding
   2997 		     the relocs too.  */
   2998 		}
   2999 	      else if (p->count != 0)
   3000 		{
   3001 		  srel = elf_section_data (p->sec)->sreloc;
   3002 		  srel->size += p->count * sizeof (Elf32_External_Rela);
   3003 		  if ((p->sec->output_section->flags & SEC_READONLY) != 0)
   3004 		    info->flags |= DF_TEXTREL;
   3005 		}
   3006 	    }
   3007 	}
   3008 
   3009       local_got = elf_local_got_refcounts (ibfd);
   3010       if (!local_got)
   3011 	continue;
   3012 
   3013       symtab_hdr = &elf_tdata (ibfd)->symtab_hdr;
   3014       locsymcount = symtab_hdr->sh_info;
   3015       end_local_got = local_got + locsymcount;
   3016       lgot_masks = (unsigned char *) end_local_got;
   3017       s = htab->elf.sgot;
   3018       srel = htab->elf.srelgot;
   3019 
   3020       for (; local_got < end_local_got; ++local_got, ++lgot_masks)
   3021 	{
   3022 	  if (*local_got > 0)
   3023 	    {
   3024 	      unsigned int need = 0;
   3025 	      if ((*lgot_masks & TLS_TLS) != 0)
   3026 		{
   3027 		  if ((*lgot_masks & TLS_GD) != 0)
   3028 		    need += 8;
   3029 		  if ((*lgot_masks & TLS_LD) != 0)
   3030 		    htab->tlsld_got.refcount += 1;
   3031 		}
   3032 	      else
   3033 		need += 4;
   3034 
   3035 	      if (need == 0)
   3036 		{
   3037 		  *local_got = (bfd_vma) -1;
   3038 		}
   3039 	      else
   3040 		{
   3041 		  *local_got = s->size;
   3042 		  s->size += need;
   3043 		  if (bfd_link_pic (info))
   3044 		    srel->size += need * (sizeof (Elf32_External_Rela) / 4);
   3045 		}
   3046 	    }
   3047 	  else
   3048 	    *local_got = (bfd_vma) -1;
   3049 	}
   3050     }
   3051 
   3052   /* Allocate global sym .plt and .got entries, and space for global
   3053      sym dynamic relocs.  */
   3054   elf_link_hash_traverse (elf_hash_table (info), allocate_dynrelocs, info);
   3055 
   3056   if (htab->tlsld_got.refcount > 0)
   3057     {
   3058       htab->tlsld_got.offset = htab->elf.sgot->size;
   3059       htab->elf.sgot->size += 8;
   3060       if (bfd_link_pic (info))
   3061 	htab->elf.srelgot->size += sizeof (Elf32_External_Rela);
   3062     }
   3063   else
   3064     htab->tlsld_got.offset = (bfd_vma) -1;
   3065 
   3066   if (elf_hash_table (info)->dynamic_sections_created)
   3067     {
   3068       /* Make space for the trailing nop in .plt.  */
   3069       if (htab->elf.splt->size > 0)
   3070 	htab->elf.splt->size += 4;
   3071     }
   3072 
   3073   /* The check_relocs and adjust_dynamic_symbol entry points have
   3074      determined the sizes of the various dynamic sections.  Allocate
   3075      memory for them.  */
   3076   for (s = dynobj->sections; s != NULL; s = s->next)
   3077     {
   3078       const char *name;
   3079       bool strip = false;
   3080 
   3081       if ((s->flags & SEC_LINKER_CREATED) == 0)
   3082 	continue;
   3083 
   3084       /* It's OK to base decisions on the section name, because none
   3085 	 of the dynobj section names depend upon the input files.  */
   3086       name = bfd_section_name (s);
   3087 
   3088       if (startswith (name, ".rela"))
   3089 	{
   3090 	  if (s->size == 0)
   3091 	    {
   3092 	      /* If we don't need this section, strip it from the
   3093 		 output file.  This is to handle .rela.bss and
   3094 		 .rela.plt.  We must create it in
   3095 		 create_dynamic_sections, because it must be created
   3096 		 before the linker maps input sections to output
   3097 		 sections.  The linker does that before
   3098 		 adjust_dynamic_symbol is called, and it is that
   3099 		 function which decides whether anything needs to go
   3100 		 into these sections.  */
   3101 	      strip = true;
   3102 	    }
   3103 	  else
   3104 	    {
   3105 	      /* We use the reloc_count field as a counter if we need
   3106 		 to copy relocs into the output file.  */
   3107 	      s->reloc_count = 0;
   3108 	    }
   3109 	}
   3110       else if (s != htab->elf.splt
   3111 	       && s != htab->elf.sgot
   3112 	       && s != htab->elf.sgotplt
   3113 	       && s != htab->elf.sdynbss
   3114 	       && s != htab->elf.sdynrelro)
   3115 	{
   3116 	  /* It's not one of our sections, so don't allocate space.  */
   3117 	  continue;
   3118 	}
   3119 
   3120       if (strip)
   3121 	{
   3122 	  s->flags |= SEC_EXCLUDE;
   3123 	  continue;
   3124 	}
   3125 
   3126       /* Allocate memory for the section contents.  */
   3127       /* FIXME: This should be a call to bfd_alloc not bfd_zalloc.
   3128 	 Unused entries should be reclaimed before the section's contents
   3129 	 are written out, but at the moment this does not happen.  Thus in
   3130 	 order to prevent writing out garbage, we initialise the section's
   3131 	 contents to zero.  */
   3132       s->contents = (bfd_byte *) bfd_zalloc (dynobj, s->size);
   3133       if (s->contents == NULL && s->size != 0)
   3134 	return false;
   3135     }
   3136 
   3137   /* ??? Force DF_BIND_NOW?  */
   3138   info->flags |= DF_BIND_NOW;
   3139   return _bfd_elf_add_dynamic_tags (output_bfd, info, true);
   3140 }
   3141 
   3142 /* Finish up dynamic symbol handling.  We set the contents of various
   3143    dynamic sections here.  */
   3144 
   3145 static bool
   3146 microblaze_elf_finish_dynamic_symbol (bfd *output_bfd,
   3147 				      struct bfd_link_info *info,
   3148 				      struct elf_link_hash_entry *h,
   3149 				      Elf_Internal_Sym *sym)
   3150 {
   3151   struct elf32_mb_link_hash_table *htab;
   3152   struct elf32_mb_link_hash_entry *eh = elf32_mb_hash_entry(h);
   3153 
   3154   htab = elf32_mb_hash_table (info);
   3155   if (htab == NULL)
   3156     return false;
   3157 
   3158   if (h->plt.offset != (bfd_vma) -1)
   3159     {
   3160       asection *splt;
   3161       asection *srela;
   3162       asection *sgotplt;
   3163       Elf_Internal_Rela rela;
   3164       bfd_byte *loc;
   3165       bfd_vma plt_index;
   3166       bfd_vma got_offset;
   3167       bfd_vma got_addr;
   3168 
   3169       /* This symbol has an entry in the procedure linkage table.  Set
   3170 	 it up.  */
   3171       BFD_ASSERT (h->dynindx != -1);
   3172 
   3173       splt = htab->elf.splt;
   3174       srela = htab->elf.srelplt;
   3175       sgotplt = htab->elf.sgotplt;
   3176       BFD_ASSERT (splt != NULL && srela != NULL && sgotplt != NULL);
   3177 
   3178       plt_index = h->plt.offset / PLT_ENTRY_SIZE - 1; /* first entry reserved.  */
   3179       got_offset = (plt_index + 3) * 4; /* 3 reserved ???  */
   3180       got_addr = got_offset;
   3181 
   3182       /* For non-PIC objects we need absolute address of the GOT entry.  */
   3183       if (!bfd_link_pic (info))
   3184 	got_addr += sgotplt->output_section->vma + sgotplt->output_offset;
   3185 
   3186       /* Fill in the entry in the procedure linkage table.  */
   3187       bfd_put_32 (output_bfd, PLT_ENTRY_WORD_0 + ((got_addr >> 16) & 0xffff),
   3188 		  splt->contents + h->plt.offset);
   3189       if (bfd_link_pic (info))
   3190 	bfd_put_32 (output_bfd, PLT_ENTRY_WORD_1 + (got_addr & 0xffff),
   3191 		    splt->contents + h->plt.offset + 4);
   3192       else
   3193 	bfd_put_32 (output_bfd, PLT_ENTRY_WORD_1_NOPIC + (got_addr & 0xffff),
   3194 		    splt->contents + h->plt.offset + 4);
   3195       bfd_put_32 (output_bfd, (bfd_vma) PLT_ENTRY_WORD_2,
   3196 		  splt->contents + h->plt.offset + 8);
   3197       bfd_put_32 (output_bfd, (bfd_vma) PLT_ENTRY_WORD_3,
   3198 		  splt->contents + h->plt.offset + 12);
   3199 
   3200       /* Any additions to the .got section??? */
   3201       /*      bfd_put_32 (output_bfd,
   3202 	      splt->output_section->vma + splt->output_offset + h->plt.offset + 4,
   3203 	      sgotplt->contents + got_offset); */
   3204 
   3205       /* Fill in the entry in the .rela.plt section.  */
   3206       rela.r_offset = (sgotplt->output_section->vma
   3207 		       + sgotplt->output_offset
   3208 		       + got_offset);
   3209       rela.r_info = ELF32_R_INFO (h->dynindx, R_MICROBLAZE_JUMP_SLOT);
   3210       rela.r_addend = 0;
   3211       loc = srela->contents;
   3212       loc += plt_index * sizeof (Elf32_External_Rela);
   3213       bfd_elf32_swap_reloca_out (output_bfd, &rela, loc);
   3214 
   3215       if (!h->def_regular)
   3216 	{
   3217 	  /* Mark the symbol as undefined, rather than as defined in
   3218 	     the .plt section.  Zero the value.  */
   3219 	  sym->st_shndx = SHN_UNDEF;
   3220 	  sym->st_value = 0;
   3221 	}
   3222     }
   3223 
   3224   /* h->got.refcount to be checked ? */
   3225   if (h->got.offset != (bfd_vma) -1 &&
   3226       ! ((h->got.offset & 1) ||
   3227 	  IS_TLS_LD(eh->tls_mask) || IS_TLS_GD(eh->tls_mask)))
   3228     {
   3229       asection *sgot;
   3230       asection *srela;
   3231       bfd_vma offset;
   3232 
   3233       /* This symbol has an entry in the global offset table.  Set it
   3234 	 up.  */
   3235 
   3236       sgot = htab->elf.sgot;
   3237       srela = htab->elf.srelgot;
   3238       BFD_ASSERT (sgot != NULL && srela != NULL);
   3239 
   3240       offset = (sgot->output_section->vma + sgot->output_offset
   3241 		+ (h->got.offset &~ (bfd_vma) 1));
   3242 
   3243       /* If this is a -Bsymbolic link, and the symbol is defined
   3244 	 locally, we just want to emit a RELATIVE reloc.  Likewise if
   3245 	 the symbol was forced to be local because of a version file.
   3246 	 The entry in the global offset table will already have been
   3247 	 initialized in the relocate_section function.  */
   3248       if (bfd_link_pic (info)
   3249 	  && ((info->symbolic && h->def_regular)
   3250 	      || h->dynindx == -1))
   3251 	{
   3252 	  asection *sec = h->root.u.def.section;
   3253 	  bfd_vma value;
   3254 
   3255 	  value = h->root.u.def.value;
   3256 	  if (sec->output_section != NULL)
   3257 	    /* PR 21180: If the output section is NULL, then the symbol is no
   3258 	       longer needed, and in theory the GOT entry is redundant.  But
   3259 	       it is too late to change our minds now...  */
   3260 	    value += sec->output_section->vma + sec->output_offset;
   3261 
   3262 	  microblaze_elf_output_dynamic_relocation (output_bfd,
   3263 						    srela, srela->reloc_count++,
   3264 						    /* symindex= */ 0,
   3265 						    R_MICROBLAZE_REL, offset,
   3266 						    value);
   3267 	}
   3268       else
   3269 	{
   3270 	  microblaze_elf_output_dynamic_relocation (output_bfd,
   3271 						    srela, srela->reloc_count++,
   3272 						    h->dynindx,
   3273 						    R_MICROBLAZE_GLOB_DAT,
   3274 						    offset, 0);
   3275 	}
   3276 
   3277       bfd_put_32 (output_bfd, (bfd_vma) 0,
   3278 		  sgot->contents + (h->got.offset &~ (bfd_vma) 1));
   3279     }
   3280 
   3281   if (h->needs_copy)
   3282     {
   3283       asection *s;
   3284       Elf_Internal_Rela rela;
   3285       bfd_byte *loc;
   3286 
   3287       /* This symbols needs a copy reloc.  Set it up.  */
   3288 
   3289       BFD_ASSERT (h->dynindx != -1);
   3290 
   3291       rela.r_offset = (h->root.u.def.value
   3292 		       + h->root.u.def.section->output_section->vma
   3293 		       + h->root.u.def.section->output_offset);
   3294       rela.r_info = ELF32_R_INFO (h->dynindx, R_MICROBLAZE_COPY);
   3295       rela.r_addend = 0;
   3296       if (h->root.u.def.section == htab->elf.sdynrelro)
   3297 	s = htab->elf.sreldynrelro;
   3298       else
   3299 	s = htab->elf.srelbss;
   3300       loc = s->contents + s->reloc_count++ * sizeof (Elf32_External_Rela);
   3301       bfd_elf32_swap_reloca_out (output_bfd, &rela, loc);
   3302     }
   3303 
   3304   /* Mark some specially defined symbols as absolute.  */
   3305   if (h == htab->elf.hdynamic
   3306       || h == htab->elf.hgot
   3307       || h == htab->elf.hplt)
   3308     sym->st_shndx = SHN_ABS;
   3309 
   3310   return true;
   3311 }
   3312 
   3313 
   3314 /* Finish up the dynamic sections.  */
   3315 
   3316 static bool
   3317 microblaze_elf_finish_dynamic_sections (bfd *output_bfd,
   3318 					struct bfd_link_info *info)
   3319 {
   3320   bfd *dynobj;
   3321   asection *sdyn, *sgot;
   3322   struct elf32_mb_link_hash_table *htab;
   3323 
   3324   htab = elf32_mb_hash_table (info);
   3325   if (htab == NULL)
   3326     return false;
   3327 
   3328   dynobj = htab->elf.dynobj;
   3329 
   3330   sdyn = bfd_get_linker_section (dynobj, ".dynamic");
   3331 
   3332   if (htab->elf.dynamic_sections_created)
   3333     {
   3334       asection *splt;
   3335       Elf32_External_Dyn *dyncon, *dynconend;
   3336 
   3337       dyncon = (Elf32_External_Dyn *) sdyn->contents;
   3338       dynconend = (Elf32_External_Dyn *) (sdyn->contents + sdyn->size);
   3339       for (; dyncon < dynconend; dyncon++)
   3340 	{
   3341 	  Elf_Internal_Dyn dyn;
   3342 	  asection *s;
   3343 	  bool size;
   3344 
   3345 	  bfd_elf32_swap_dyn_in (dynobj, dyncon, &dyn);
   3346 
   3347 	  switch (dyn.d_tag)
   3348 	    {
   3349 	    case DT_PLTGOT:
   3350 	      s = htab->elf.sgotplt;
   3351 	      size = false;
   3352 	      break;
   3353 
   3354 	    case DT_PLTRELSZ:
   3355 	      s = htab->elf.srelplt;
   3356 	      size = true;
   3357 	      break;
   3358 
   3359 	    case DT_JMPREL:
   3360 	      s = htab->elf.srelplt;
   3361 	      size = false;
   3362 	      break;
   3363 
   3364 	    default:
   3365 	      continue;
   3366 	    }
   3367 
   3368 	  if (s == NULL)
   3369 	    dyn.d_un.d_val = 0;
   3370 	  else
   3371 	    {
   3372 	      if (!size)
   3373 		dyn.d_un.d_ptr = s->output_section->vma + s->output_offset;
   3374 	      else
   3375 		dyn.d_un.d_val = s->size;
   3376 	    }
   3377 	  bfd_elf32_swap_dyn_out (output_bfd, &dyn, dyncon);
   3378 	}
   3379 
   3380       splt = htab->elf.splt;
   3381       BFD_ASSERT (splt != NULL && sdyn != NULL);
   3382 
   3383       /* Clear the first entry in the procedure linkage table,
   3384 	 and put a nop in the last four bytes.  */
   3385       if (splt->size > 0)
   3386 	{
   3387 	  memset (splt->contents, 0, PLT_ENTRY_SIZE);
   3388 	  bfd_put_32 (output_bfd, (bfd_vma) 0x80000000 /* nop.  */,
   3389 		      splt->contents + splt->size - 4);
   3390 
   3391 	  if (splt->output_section != bfd_abs_section_ptr)
   3392 	    elf_section_data (splt->output_section)->this_hdr.sh_entsize = 4;
   3393 	}
   3394     }
   3395 
   3396   /* Set the first entry in the global offset table to the address of
   3397      the dynamic section.  */
   3398   sgot = htab->elf.sgotplt;
   3399   if (sgot && sgot->size > 0)
   3400     {
   3401       if (sdyn == NULL)
   3402 	bfd_put_32 (output_bfd, (bfd_vma) 0, sgot->contents);
   3403       else
   3404 	bfd_put_32 (output_bfd,
   3405 		    sdyn->output_section->vma + sdyn->output_offset,
   3406 		    sgot->contents);
   3407       elf_section_data (sgot->output_section)->this_hdr.sh_entsize = 4;
   3408     }
   3409 
   3410   if (htab->elf.sgot && htab->elf.sgot->size > 0)
   3411     elf_section_data (htab->elf.sgot->output_section)->this_hdr.sh_entsize = 4;
   3412 
   3413   return true;
   3414 }
   3415 
   3416 /* Hook called by the linker routine which adds symbols from an object
   3417    file.  We use it to put .comm items in .sbss, and not .bss.  */
   3418 
   3419 static bool
   3420 microblaze_elf_add_symbol_hook (bfd *abfd,
   3421 				struct bfd_link_info *info,
   3422 				Elf_Internal_Sym *sym,
   3423 				const char **namep ATTRIBUTE_UNUSED,
   3424 				flagword *flagsp ATTRIBUTE_UNUSED,
   3425 				asection **secp,
   3426 				bfd_vma *valp)
   3427 {
   3428   if (sym->st_shndx == SHN_COMMON
   3429       && !bfd_link_relocatable (info)
   3430       && sym->st_size <= elf_gp_size (abfd))
   3431     {
   3432       /* Common symbols less than or equal to -G nn bytes are automatically
   3433 	 put into .sbss.  */
   3434       *secp = bfd_make_section_old_way (abfd, ".sbss");
   3435       if (*secp == NULL
   3436 	  || !bfd_set_section_flags (*secp, SEC_IS_COMMON | SEC_SMALL_DATA))
   3437 	return false;
   3438 
   3439       *valp = sym->st_size;
   3440     }
   3441 
   3442   return true;
   3443 }
   3444 
   3445 #define TARGET_LITTLE_SYM      microblaze_elf32_le_vec
   3446 #define TARGET_LITTLE_NAME     "elf32-microblazeel"
   3447 
   3448 #define TARGET_BIG_SYM		microblaze_elf32_vec
   3449 #define TARGET_BIG_NAME		"elf32-microblaze"
   3450 
   3451 #define ELF_ARCH		bfd_arch_microblaze
   3452 #define ELF_TARGET_ID		MICROBLAZE_ELF_DATA
   3453 #define ELF_MACHINE_CODE	EM_MICROBLAZE
   3454 #define ELF_MACHINE_ALT1	EM_MICROBLAZE_OLD
   3455 #define ELF_MAXPAGESIZE		0x1000
   3456 #define elf_info_to_howto	microblaze_elf_info_to_howto
   3457 #define elf_info_to_howto_rel	NULL
   3458 
   3459 #define bfd_elf32_bfd_reloc_type_lookup		microblaze_elf_reloc_type_lookup
   3460 #define bfd_elf32_bfd_is_local_label_name	microblaze_elf_is_local_label_name
   3461 #define bfd_elf32_new_section_hook		microblaze_elf_new_section_hook
   3462 #define elf_backend_relocate_section		microblaze_elf_relocate_section
   3463 #define bfd_elf32_bfd_relax_section		microblaze_elf_relax_section
   3464 #define bfd_elf32_bfd_merge_private_bfd_data	_bfd_generic_verify_endian_match
   3465 #define bfd_elf32_bfd_reloc_name_lookup		microblaze_elf_reloc_name_lookup
   3466 
   3467 #define elf_backend_gc_mark_hook		microblaze_elf_gc_mark_hook
   3468 #define elf_backend_check_relocs		microblaze_elf_check_relocs
   3469 #define elf_backend_copy_indirect_symbol	microblaze_elf_copy_indirect_symbol
   3470 #define bfd_elf32_bfd_link_hash_table_create	microblaze_elf_link_hash_table_create
   3471 #define elf_backend_can_gc_sections		1
   3472 #define elf_backend_can_refcount		1
   3473 #define elf_backend_want_got_plt		1
   3474 #define elf_backend_plt_readonly		1
   3475 #define elf_backend_got_header_size		12
   3476 #define elf_backend_want_dynrelro		1
   3477 #define elf_backend_rela_normal			1
   3478 #define elf_backend_dtrel_excludes_plt		1
   3479 
   3480 #define elf_backend_adjust_dynamic_symbol	microblaze_elf_adjust_dynamic_symbol
   3481 #define elf_backend_create_dynamic_sections	_bfd_elf_create_dynamic_sections
   3482 #define elf_backend_finish_dynamic_sections	microblaze_elf_finish_dynamic_sections
   3483 #define elf_backend_finish_dynamic_symbol	microblaze_elf_finish_dynamic_symbol
   3484 #define elf_backend_size_dynamic_sections	microblaze_elf_size_dynamic_sections
   3485 #define elf_backend_add_symbol_hook		microblaze_elf_add_symbol_hook
   3486 
   3487 #include "elf32-target.h"
   3488