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