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