Home | History | Annotate | Line # | Download | only in bfd
elf32-lm32.c revision 1.1
      1  1.1  christos /* Lattice Mico32-specific support for 32-bit ELF
      2  1.1  christos    Copyright 2008, 2009, 2010  Free Software Foundation, Inc.
      3  1.1  christos    Contributed by Jon Beniston <jon (at) beniston.com>
      4  1.1  christos 
      5  1.1  christos    This file is part of BFD, the Binary File Descriptor library.
      6  1.1  christos 
      7  1.1  christos    This program is free software; you can redistribute it and/or modify
      8  1.1  christos    it under the terms of the GNU General Public License as published by
      9  1.1  christos    the Free Software Foundation; either version 3 of the License, or
     10  1.1  christos    (at your option) any later version.
     11  1.1  christos 
     12  1.1  christos    This program is distributed in the hope that it will be useful,
     13  1.1  christos    but WITHOUT ANY WARRANTY; without even the implied warranty of
     14  1.1  christos    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     15  1.1  christos    GNU General Public License for more details.
     16  1.1  christos 
     17  1.1  christos    You should have received a copy of the GNU General Public License
     18  1.1  christos    along with this program; if not, write to the Free Software
     19  1.1  christos    Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
     20  1.1  christos    MA 02110-1301, USA.  */
     21  1.1  christos 
     22  1.1  christos #include "bfd.h"
     23  1.1  christos #include "sysdep.h"
     24  1.1  christos #include "libbfd.h"
     25  1.1  christos #include "elf-bfd.h"
     26  1.1  christos #include "elf/lm32.h"
     27  1.1  christos 
     28  1.1  christos #define DEFAULT_STACK_SIZE 0x20000
     29  1.1  christos 
     30  1.1  christos #define PLT_ENTRY_SIZE 20
     31  1.1  christos 
     32  1.1  christos #define PLT0_ENTRY_WORD0  0
     33  1.1  christos #define PLT0_ENTRY_WORD1  0
     34  1.1  christos #define PLT0_ENTRY_WORD2  0
     35  1.1  christos #define PLT0_ENTRY_WORD3  0
     36  1.1  christos #define PLT0_ENTRY_WORD4  0
     37  1.1  christos 
     38  1.1  christos #define PLT0_PIC_ENTRY_WORD0  0
     39  1.1  christos #define PLT0_PIC_ENTRY_WORD1  0
     40  1.1  christos #define PLT0_PIC_ENTRY_WORD2  0
     41  1.1  christos #define PLT0_PIC_ENTRY_WORD3  0
     42  1.1  christos #define PLT0_PIC_ENTRY_WORD4  0
     43  1.1  christos 
     44  1.1  christos #define ELF_DYNAMIC_INTERPRETER "/usr/lib/libc.so.1"
     45  1.1  christos 
     46  1.1  christos extern const bfd_target bfd_elf32_lm32fdpic_vec;
     47  1.1  christos 
     48  1.1  christos #define IS_FDPIC(bfd) ((bfd)->xvec == &bfd_elf32_lm32fdpic_vec)
     49  1.1  christos 
     50  1.1  christos static bfd_reloc_status_type lm32_elf_gprel_reloc
     51  1.1  christos   (bfd *, arelent *, asymbol *, void *, asection *, bfd *, char **);
     52  1.1  christos 
     53  1.1  christos /* The linker needs to keep track of the number of relocs that it
     54  1.1  christos    decides to copy as dynamic relocs in check_relocs for each symbol.
     55  1.1  christos    This is so that it can later discard them if they are found to be
     56  1.1  christos    unnecessary.  We store the information in a field extending the
     57  1.1  christos    regular ELF linker hash table.  */
     58  1.1  christos 
     59  1.1  christos struct elf_lm32_dyn_relocs
     60  1.1  christos {
     61  1.1  christos   struct elf_lm32_dyn_relocs *next;
     62  1.1  christos 
     63  1.1  christos   /* The input section of the reloc.  */
     64  1.1  christos   asection *sec;
     65  1.1  christos 
     66  1.1  christos   /* Total number of relocs copied for the input section.  */
     67  1.1  christos   bfd_size_type count;
     68  1.1  christos 
     69  1.1  christos   /* Number of pc-relative relocs copied for the input section.  */
     70  1.1  christos   bfd_size_type pc_count;
     71  1.1  christos };
     72  1.1  christos 
     73  1.1  christos /* lm32 ELF linker hash entry.  */
     74  1.1  christos 
     75  1.1  christos struct elf_lm32_link_hash_entry
     76  1.1  christos {
     77  1.1  christos   struct elf_link_hash_entry root;
     78  1.1  christos 
     79  1.1  christos   /* Track dynamic relocs copied for this symbol.  */
     80  1.1  christos   struct elf_lm32_dyn_relocs *dyn_relocs;
     81  1.1  christos };
     82  1.1  christos 
     83  1.1  christos /* lm32 ELF linker hash table.  */
     84  1.1  christos 
     85  1.1  christos struct elf_lm32_link_hash_table
     86  1.1  christos {
     87  1.1  christos   struct elf_link_hash_table root;
     88  1.1  christos 
     89  1.1  christos   /* Short-cuts to get to dynamic linker sections.  */
     90  1.1  christos   asection *sgot;
     91  1.1  christos   asection *sgotplt;
     92  1.1  christos   asection *srelgot;
     93  1.1  christos   asection *sfixup32;
     94  1.1  christos   asection *splt;
     95  1.1  christos   asection *srelplt;
     96  1.1  christos   asection *sdynbss;
     97  1.1  christos   asection *srelbss;
     98  1.1  christos 
     99  1.1  christos   int relocs32;
    100  1.1  christos };
    101  1.1  christos 
    102  1.1  christos /* Get the lm32 ELF linker hash table from a link_info structure.  */
    103  1.1  christos 
    104  1.1  christos #define lm32_elf_hash_table(p) \
    105  1.1  christos   (elf_hash_table_id ((struct elf_link_hash_table *) ((p)->hash)) \
    106  1.1  christos   == LM32_ELF_DATA ? ((struct elf_lm32_link_hash_table *) ((p)->hash)) : NULL)
    107  1.1  christos 
    108  1.1  christos #define lm32fdpic_got_section(info) \
    109  1.1  christos   (lm32_elf_hash_table (info)->sgot)
    110  1.1  christos #define lm32fdpic_gotrel_section(info) \
    111  1.1  christos   (lm32_elf_hash_table (info)->srelgot)
    112  1.1  christos #define lm32fdpic_fixup32_section(info) \
    113  1.1  christos   (lm32_elf_hash_table (info)->sfixup32)
    114  1.1  christos 
    115  1.1  christos struct weak_symbol_list
    116  1.1  christos {
    117  1.1  christos   const char *name;
    118  1.1  christos   struct weak_symbol_list *next;
    119  1.1  christos };
    120  1.1  christos 
    121  1.1  christos /* Create an entry in an lm32 ELF linker hash table.  */
    122  1.1  christos 
    123  1.1  christos static struct bfd_hash_entry *
    124  1.1  christos lm32_elf_link_hash_newfunc (struct bfd_hash_entry *entry,
    125  1.1  christos 			    struct bfd_hash_table *table,
    126  1.1  christos 			    const char *string)
    127  1.1  christos {
    128  1.1  christos   struct elf_lm32_link_hash_entry *ret =
    129  1.1  christos     (struct elf_lm32_link_hash_entry *) entry;
    130  1.1  christos 
    131  1.1  christos   /* Allocate the structure if it has not already been allocated by a
    132  1.1  christos      subclass.  */
    133  1.1  christos   if (ret == NULL)
    134  1.1  christos     ret = bfd_hash_allocate (table,
    135  1.1  christos 			     sizeof (struct elf_lm32_link_hash_entry));
    136  1.1  christos   if (ret == NULL)
    137  1.1  christos     return NULL;
    138  1.1  christos 
    139  1.1  christos   /* Call the allocation method of the superclass.  */
    140  1.1  christos   ret = ((struct elf_lm32_link_hash_entry *)
    141  1.1  christos          _bfd_elf_link_hash_newfunc ((struct bfd_hash_entry *) ret,
    142  1.1  christos                                      table, string));
    143  1.1  christos   if (ret != NULL)
    144  1.1  christos     {
    145  1.1  christos       struct elf_lm32_link_hash_entry *eh;
    146  1.1  christos 
    147  1.1  christos       eh = (struct elf_lm32_link_hash_entry *) ret;
    148  1.1  christos       eh->dyn_relocs = NULL;
    149  1.1  christos     }
    150  1.1  christos 
    151  1.1  christos   return (struct bfd_hash_entry *) ret;
    152  1.1  christos }
    153  1.1  christos 
    154  1.1  christos /* Create an lm32 ELF linker hash table.  */
    155  1.1  christos 
    156  1.1  christos static struct bfd_link_hash_table *
    157  1.1  christos lm32_elf_link_hash_table_create (bfd *abfd)
    158  1.1  christos {
    159  1.1  christos   struct elf_lm32_link_hash_table *ret;
    160  1.1  christos   bfd_size_type amt = sizeof (struct elf_lm32_link_hash_table);
    161  1.1  christos 
    162  1.1  christos   ret = bfd_malloc (amt);
    163  1.1  christos   if (ret == NULL)
    164  1.1  christos     return NULL;
    165  1.1  christos 
    166  1.1  christos   if (!_bfd_elf_link_hash_table_init (&ret->root, abfd,
    167  1.1  christos 				      lm32_elf_link_hash_newfunc,
    168  1.1  christos 				      sizeof (struct elf_lm32_link_hash_entry),
    169  1.1  christos 				      LM32_ELF_DATA))
    170  1.1  christos     {
    171  1.1  christos       free (ret);
    172  1.1  christos       return NULL;
    173  1.1  christos     }
    174  1.1  christos 
    175  1.1  christos   ret->sgot = NULL;
    176  1.1  christos   ret->sgotplt = NULL;
    177  1.1  christos   ret->srelgot = NULL;
    178  1.1  christos   ret->sfixup32 = NULL;
    179  1.1  christos   ret->splt = NULL;
    180  1.1  christos   ret->srelplt = NULL;
    181  1.1  christos   ret->sdynbss = NULL;
    182  1.1  christos   ret->srelbss = NULL;
    183  1.1  christos   ret->relocs32 = 0;
    184  1.1  christos 
    185  1.1  christos   return &ret->root.root;
    186  1.1  christos }
    187  1.1  christos 
    188  1.1  christos /* Add a fixup to the ROFIXUP section.  */
    189  1.1  christos 
    190  1.1  christos static bfd_vma
    191  1.1  christos _lm32fdpic_add_rofixup (bfd *output_bfd, asection *rofixup, bfd_vma relocation)
    192  1.1  christos {
    193  1.1  christos   bfd_vma fixup_offset;
    194  1.1  christos 
    195  1.1  christos   if (rofixup->flags & SEC_EXCLUDE)
    196  1.1  christos     return -1;
    197  1.1  christos 
    198  1.1  christos   fixup_offset = rofixup->reloc_count * 4;
    199  1.1  christos   if (rofixup->contents)
    200  1.1  christos     {
    201  1.1  christos       BFD_ASSERT (fixup_offset < rofixup->size);
    202  1.1  christos       if (fixup_offset < rofixup->size)
    203  1.1  christos       bfd_put_32 (output_bfd, relocation, rofixup->contents + fixup_offset);
    204  1.1  christos     }
    205  1.1  christos   rofixup->reloc_count++;
    206  1.1  christos 
    207  1.1  christos   return fixup_offset;
    208  1.1  christos }
    209  1.1  christos 
    210  1.1  christos /* Create .got, .gotplt, and .rela.got sections in DYNOBJ, and set up
    211  1.1  christos    shortcuts to them in our hash table.  */
    212  1.1  christos 
    213  1.1  christos static bfd_boolean
    214  1.1  christos create_got_section (bfd *dynobj, struct bfd_link_info *info)
    215  1.1  christos {
    216  1.1  christos   struct elf_lm32_link_hash_table *htab;
    217  1.1  christos   asection *s;
    218  1.1  christos 
    219  1.1  christos   /* This function may be called more than once.  */
    220  1.1  christos   s = bfd_get_section_by_name (dynobj, ".got");
    221  1.1  christos   if (s != NULL && (s->flags & SEC_LINKER_CREATED) != 0)
    222  1.1  christos     return TRUE;
    223  1.1  christos 
    224  1.1  christos   htab = lm32_elf_hash_table (info);
    225  1.1  christos   if (htab == NULL)
    226  1.1  christos     return FALSE;
    227  1.1  christos 
    228  1.1  christos   if (! _bfd_elf_create_got_section (dynobj, info))
    229  1.1  christos     return FALSE;
    230  1.1  christos 
    231  1.1  christos   htab->sgot = bfd_get_section_by_name (dynobj, ".got");
    232  1.1  christos   htab->sgotplt = bfd_get_section_by_name (dynobj, ".got.plt");
    233  1.1  christos   htab->srelgot = bfd_get_section_by_name (dynobj, ".rela.got");
    234  1.1  christos   if (! htab->sgot || ! htab->sgotplt || ! htab->srelgot)
    235  1.1  christos     abort ();
    236  1.1  christos 
    237  1.1  christos   return TRUE;
    238  1.1  christos }
    239  1.1  christos 
    240  1.1  christos /* Create .rofixup sections in DYNOBJ, and set up
    241  1.1  christos    shortcuts to them in our hash table.  */
    242  1.1  christos 
    243  1.1  christos static bfd_boolean
    244  1.1  christos create_rofixup_section (bfd *dynobj, struct bfd_link_info *info)
    245  1.1  christos {
    246  1.1  christos   struct elf_lm32_link_hash_table *htab;
    247  1.1  christos   htab = lm32_elf_hash_table (info);
    248  1.1  christos 
    249  1.1  christos   if (htab == NULL)
    250  1.1  christos     return FALSE;
    251  1.1  christos 
    252  1.1  christos   /* Fixup section for R_LM32_32 relocs.  */
    253  1.1  christos   lm32fdpic_fixup32_section (info) = bfd_make_section_with_flags (dynobj,
    254  1.1  christos                                                                    ".rofixup",
    255  1.1  christos 				                                   (SEC_ALLOC
    256  1.1  christos                                                                    | SEC_LOAD
    257  1.1  christos                                                                    | SEC_HAS_CONTENTS
    258  1.1  christos                                                                    | SEC_IN_MEMORY
    259  1.1  christos 	                                                           | SEC_LINKER_CREATED
    260  1.1  christos                                                                    | SEC_READONLY));
    261  1.1  christos   if (lm32fdpic_fixup32_section (info) == NULL
    262  1.1  christos       || ! bfd_set_section_alignment (dynobj, lm32fdpic_fixup32_section (info), 2))
    263  1.1  christos     return FALSE;
    264  1.1  christos 
    265  1.1  christos   return TRUE;
    266  1.1  christos }
    267  1.1  christos 
    268  1.1  christos static reloc_howto_type lm32_elf_howto_table [] =
    269  1.1  christos {
    270  1.1  christos   /* This reloc does nothing.  */
    271  1.1  christos   HOWTO (R_LM32_NONE,               /* type */
    272  1.1  christos          0,                         /* rightshift */
    273  1.1  christos          2,                         /* size (0 = byte, 1 = short, 2 = long) */
    274  1.1  christos          32,                        /* bitsize */
    275  1.1  christos          FALSE,                     /* pc_relative */
    276  1.1  christos          0,                         /* bitpos */
    277  1.1  christos          complain_overflow_bitfield,/* complain_on_overflow */
    278  1.1  christos          bfd_elf_generic_reloc,     /* special_function */
    279  1.1  christos          "R_LM32_NONE",             /* name */
    280  1.1  christos          FALSE,                     /* partial_inplace */
    281  1.1  christos          0,                         /* src_mask */
    282  1.1  christos          0,                         /* dst_mask */
    283  1.1  christos          FALSE),                    /* pcrel_offset */
    284  1.1  christos 
    285  1.1  christos   /* An 8 bit absolute relocation.  */
    286  1.1  christos   HOWTO (R_LM32_8,                  /* type */
    287  1.1  christos          0,                         /* rightshift */
    288  1.1  christos          0,                         /* size (0 = byte, 1 = short, 2 = long) */
    289  1.1  christos          8,                         /* bitsize */
    290  1.1  christos          FALSE,                     /* pc_relative */
    291  1.1  christos          0,                         /* bitpos */
    292  1.1  christos          complain_overflow_bitfield,/* complain_on_overflow */
    293  1.1  christos          bfd_elf_generic_reloc,     /* special_function */
    294  1.1  christos          "R_LM32_8",                /* name */
    295  1.1  christos          FALSE,                     /* partial_inplace */
    296  1.1  christos          0,                         /* src_mask */
    297  1.1  christos          0xff,                      /* dst_mask */
    298  1.1  christos          FALSE),                    /* pcrel_offset */
    299  1.1  christos 
    300  1.1  christos   /* A 16 bit absolute relocation.  */
    301  1.1  christos   HOWTO (R_LM32_16,                 /* type */
    302  1.1  christos          0,                         /* rightshift */
    303  1.1  christos          1,                         /* size (0 = byte, 1 = short, 2 = long) */
    304  1.1  christos          16,                        /* bitsize */
    305  1.1  christos          FALSE,                     /* pc_relative */
    306  1.1  christos          0,                         /* bitpos */
    307  1.1  christos          complain_overflow_bitfield,/* complain_on_overflow */
    308  1.1  christos          bfd_elf_generic_reloc,     /* special_function */
    309  1.1  christos          "R_LM32_16",               /* name */
    310  1.1  christos          FALSE,                     /* partial_inplace */
    311  1.1  christos          0,                         /* src_mask */
    312  1.1  christos          0xffff,                    /* dst_mask */
    313  1.1  christos          FALSE),                    /* pcrel_offset */
    314  1.1  christos 
    315  1.1  christos   /* A 32 bit absolute relocation.  */
    316  1.1  christos   HOWTO (R_LM32_32,                 /* type */
    317  1.1  christos          0,                         /* rightshift */
    318  1.1  christos          2,                         /* size (0 = byte, 1 = short, 2 = long) */
    319  1.1  christos          32,                        /* bitsize */
    320  1.1  christos          FALSE,                     /* pc_relative */
    321  1.1  christos          0,                         /* bitpos */
    322  1.1  christos          complain_overflow_bitfield,/* complain_on_overflow */
    323  1.1  christos          bfd_elf_generic_reloc,     /* special_function */
    324  1.1  christos          "R_LM32_32",               /* name */
    325  1.1  christos          FALSE,                     /* partial_inplace */
    326  1.1  christos          0,                         /* src_mask */
    327  1.1  christos          0xffffffff,                /* dst_mask */
    328  1.1  christos          FALSE),                    /* pcrel_offset */
    329  1.1  christos 
    330  1.1  christos   HOWTO (R_LM32_HI16,               /* type */
    331  1.1  christos          16,                        /* 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_bitfield,/* complain_on_overflow */
    337  1.1  christos          bfd_elf_generic_reloc,     /* special_function */
    338  1.1  christos          "R_LM32_HI16",             /* name */
    339  1.1  christos          FALSE,                     /* partial_inplace */
    340  1.1  christos          0,                         /* src_mask */
    341  1.1  christos          0xffff,                    /* dst_mask */
    342  1.1  christos          FALSE),                    /* pcrel_offset */
    343  1.1  christos 
    344  1.1  christos   HOWTO (R_LM32_LO16,               /* type */
    345  1.1  christos          0,                         /* rightshift */
    346  1.1  christos          2,                         /* size (0 = byte, 1 = short, 2 = long) */
    347  1.1  christos          16,                        /* bitsize */
    348  1.1  christos          FALSE,                     /* pc_relative */
    349  1.1  christos          0,                         /* bitpos */
    350  1.1  christos          complain_overflow_dont,    /* complain_on_overflow */
    351  1.1  christos          bfd_elf_generic_reloc,     /* special_function */
    352  1.1  christos          "R_LM32_LO16",             /* name */
    353  1.1  christos          FALSE,                     /* partial_inplace */
    354  1.1  christos          0,                         /* src_mask */
    355  1.1  christos          0xffff,                    /* dst_mask */
    356  1.1  christos          FALSE),                    /* pcrel_offset */
    357  1.1  christos 
    358  1.1  christos   HOWTO (R_LM32_GPREL16,            /* type */
    359  1.1  christos          0,                         /* rightshift */
    360  1.1  christos          2,                         /* size (0 = byte, 1 = short, 2 = long) */
    361  1.1  christos          16,                        /* bitsize */
    362  1.1  christos          FALSE,                     /* pc_relative */
    363  1.1  christos          0,                         /* bitpos */
    364  1.1  christos          complain_overflow_dont,    /* complain_on_overflow */
    365  1.1  christos          lm32_elf_gprel_reloc,      /* special_function */
    366  1.1  christos          "R_LM32_GPREL16",          /* name */
    367  1.1  christos          FALSE,                     /* partial_inplace */
    368  1.1  christos          0,                         /* src_mask */
    369  1.1  christos          0xffff,                    /* dst_mask */
    370  1.1  christos          FALSE),                    /* pcrel_offset */
    371  1.1  christos 
    372  1.1  christos   HOWTO (R_LM32_CALL,               /* type */
    373  1.1  christos          2,                         /* rightshift */
    374  1.1  christos          2,                         /* size (0 = byte, 1 = short, 2 = long) */
    375  1.1  christos          26,                        /* bitsize */
    376  1.1  christos          TRUE,                      /* pc_relative */
    377  1.1  christos          0,                         /* bitpos */
    378  1.1  christos          complain_overflow_signed,  /* complain_on_overflow */
    379  1.1  christos          bfd_elf_generic_reloc,     /* special_function */
    380  1.1  christos          "R_LM32_CALL",             /* name */
    381  1.1  christos          FALSE,                     /* partial_inplace */
    382  1.1  christos          0,                         /* src_mask */
    383  1.1  christos          0x3ffffff,                 /* dst_mask */
    384  1.1  christos          TRUE),                     /* pcrel_offset */
    385  1.1  christos 
    386  1.1  christos   HOWTO (R_LM32_BRANCH,             /* type */
    387  1.1  christos          2,                         /* rightshift */
    388  1.1  christos          2,                         /* size (0 = byte, 1 = short, 2 = long) */
    389  1.1  christos          16,                        /* bitsize */
    390  1.1  christos          TRUE,                      /* pc_relative */
    391  1.1  christos          0,                         /* bitpos */
    392  1.1  christos          complain_overflow_signed,  /* complain_on_overflow */
    393  1.1  christos          bfd_elf_generic_reloc,     /* special_function */
    394  1.1  christos          "R_LM32_BRANCH",           /* name */
    395  1.1  christos          FALSE,                     /* partial_inplace */
    396  1.1  christos          0,                         /* src_mask */
    397  1.1  christos          0xffff,                    /* dst_mask */
    398  1.1  christos          TRUE),                     /* pcrel_offset */
    399  1.1  christos 
    400  1.1  christos   /* GNU extension to record C++ vtable hierarchy.  */
    401  1.1  christos   HOWTO (R_LM32_GNU_VTINHERIT,      /* type */
    402  1.1  christos          0,                         /* rightshift */
    403  1.1  christos          2,                         /* size (0 = byte, 1 = short, 2 = long) */
    404  1.1  christos          0,                         /* bitsize */
    405  1.1  christos          FALSE,                     /* pc_relative */
    406  1.1  christos          0,                         /* bitpos */
    407  1.1  christos          complain_overflow_dont,    /* complain_on_overflow */
    408  1.1  christos          NULL,                      /* special_function */
    409  1.1  christos          "R_LM32_GNU_VTINHERIT",    /* name */
    410  1.1  christos          FALSE,                     /* partial_inplace */
    411  1.1  christos          0,                         /* src_mask */
    412  1.1  christos          0,                         /* dst_mask */
    413  1.1  christos          FALSE),                    /* pcrel_offset */
    414  1.1  christos 
    415  1.1  christos   /* GNU extension to record C++ vtable member usage.  */
    416  1.1  christos   HOWTO (R_LM32_GNU_VTENTRY,        /* type */
    417  1.1  christos          0,                         /* rightshift */
    418  1.1  christos          2,                         /* size (0 = byte, 1 = short, 2 = long) */
    419  1.1  christos          0,                         /* bitsize */
    420  1.1  christos          FALSE,                     /* pc_relative */
    421  1.1  christos          0,                         /* bitpos */
    422  1.1  christos          complain_overflow_dont,    /* complain_on_overflow */
    423  1.1  christos          _bfd_elf_rel_vtable_reloc_fn,/* special_function */
    424  1.1  christos          "R_LM32_GNU_VTENTRY",      /* name */
    425  1.1  christos          FALSE,                     /* partial_inplace */
    426  1.1  christos          0,                         /* src_mask */
    427  1.1  christos          0,                         /* dst_mask */
    428  1.1  christos          FALSE),                    /* pcrel_offset */
    429  1.1  christos 
    430  1.1  christos   HOWTO (R_LM32_16_GOT,             /* type */
    431  1.1  christos          0,                         /* rightshift */
    432  1.1  christos          2,                         /* size (0 = byte, 1 = short, 2 = long) */
    433  1.1  christos          16,                        /* bitsize */
    434  1.1  christos          FALSE,                     /* pc_relative */
    435  1.1  christos          0,                         /* bitpos */
    436  1.1  christos          complain_overflow_signed,  /* complain_on_overflow */
    437  1.1  christos          bfd_elf_generic_reloc,     /* special_function */
    438  1.1  christos          "R_LM32_16_GOT",           /* name */
    439  1.1  christos          FALSE,                     /* partial_inplace */
    440  1.1  christos          0,                         /* src_mask */
    441  1.1  christos          0xffff,                    /* dst_mask */
    442  1.1  christos          FALSE),                    /* pcrel_offset */
    443  1.1  christos 
    444  1.1  christos   HOWTO (R_LM32_GOTOFF_HI16,        /* type */
    445  1.1  christos          16,                        /* rightshift */
    446  1.1  christos          2,                         /* size (0 = byte, 1 = short, 2 = long) */
    447  1.1  christos          16,                        /* bitsize */
    448  1.1  christos          FALSE,                     /* pc_relative */
    449  1.1  christos          0,                         /* bitpos */
    450  1.1  christos          complain_overflow_dont,    /* complain_on_overflow */
    451  1.1  christos          bfd_elf_generic_reloc,     /* special_function */
    452  1.1  christos          "R_LM32_GOTOFF_HI16",      /* name */
    453  1.1  christos          FALSE,                     /* partial_inplace */
    454  1.1  christos          0xffff,                    /* src_mask */
    455  1.1  christos          0xffff,                    /* dst_mask */
    456  1.1  christos          FALSE),                    /* pcrel_offset */
    457  1.1  christos 
    458  1.1  christos   HOWTO (R_LM32_GOTOFF_LO16,        /* type */
    459  1.1  christos          0,                         /* rightshift */
    460  1.1  christos          2,                         /* size (0 = byte, 1 = short, 2 = long) */
    461  1.1  christos          16,                        /* bitsize */
    462  1.1  christos          FALSE,                     /* pc_relative */
    463  1.1  christos          0,                         /* bitpos */
    464  1.1  christos          complain_overflow_dont,    /* complain_on_overflow */
    465  1.1  christos          bfd_elf_generic_reloc,     /* special_function */
    466  1.1  christos          "R_LM32_GOTOFF_LO16",      /* name */
    467  1.1  christos          FALSE,                     /* partial_inplace */
    468  1.1  christos          0xffff,                    /* src_mask */
    469  1.1  christos          0xffff,                    /* dst_mask */
    470  1.1  christos          FALSE),                    /* pcrel_offset */
    471  1.1  christos 
    472  1.1  christos   HOWTO (R_LM32_COPY,		/* type */
    473  1.1  christos 	 0,			/* rightshift */
    474  1.1  christos 	 2,			/* size (0 = byte, 1 = short, 2 = long) */
    475  1.1  christos 	 32,			/* bitsize */
    476  1.1  christos 	 FALSE,			/* pc_relative */
    477  1.1  christos 	 0,			/* bitpos */
    478  1.1  christos 	 complain_overflow_bitfield, /* complain_on_overflow */
    479  1.1  christos 	 bfd_elf_generic_reloc, /* special_function */
    480  1.1  christos 	 "R_LM32_COPY",		/* name */
    481  1.1  christos 	 FALSE,			/* partial_inplace */
    482  1.1  christos 	 0xffffffff,		/* src_mask */
    483  1.1  christos 	 0xffffffff,		/* dst_mask */
    484  1.1  christos 	 FALSE),		/* pcrel_offset */
    485  1.1  christos 
    486  1.1  christos   HOWTO (R_LM32_GLOB_DAT,	/* type */
    487  1.1  christos 	 0,			/* rightshift */
    488  1.1  christos 	 2,			/* size (0 = byte, 1 = short, 2 = long) */
    489  1.1  christos 	 32,			/* bitsize */
    490  1.1  christos 	 FALSE,			/* pc_relative */
    491  1.1  christos 	 0,			/* bitpos */
    492  1.1  christos 	 complain_overflow_bitfield, /* complain_on_overflow */
    493  1.1  christos 	 bfd_elf_generic_reloc, /* special_function */
    494  1.1  christos 	 "R_LM32_GLOB_DAT",	/* name */
    495  1.1  christos 	 FALSE,			/* partial_inplace */
    496  1.1  christos 	 0xffffffff,		/* src_mask */
    497  1.1  christos 	 0xffffffff,		/* dst_mask */
    498  1.1  christos 	 FALSE),		/* pcrel_offset */
    499  1.1  christos 
    500  1.1  christos   HOWTO (R_LM32_JMP_SLOT,	/* type */
    501  1.1  christos 	 0,			/* rightshift */
    502  1.1  christos 	 2,			/* size (0 = byte, 1 = short, 2 = long) */
    503  1.1  christos 	 32,			/* bitsize */
    504  1.1  christos 	 FALSE,			/* pc_relative */
    505  1.1  christos 	 0,			/* bitpos */
    506  1.1  christos 	 complain_overflow_bitfield, /* complain_on_overflow */
    507  1.1  christos 	 bfd_elf_generic_reloc, /* special_function */
    508  1.1  christos 	 "R_LM32_JMP_SLOT",	/* name */
    509  1.1  christos 	 FALSE,			/* partial_inplace */
    510  1.1  christos 	 0xffffffff,		/* src_mask */
    511  1.1  christos 	 0xffffffff,		/* dst_mask */
    512  1.1  christos 	 FALSE),		/* pcrel_offset */
    513  1.1  christos 
    514  1.1  christos   HOWTO (R_LM32_RELATIVE,	/* type */
    515  1.1  christos 	 0,			/* rightshift */
    516  1.1  christos 	 2,			/* size (0 = byte, 1 = short, 2 = long) */
    517  1.1  christos 	 32,			/* bitsize */
    518  1.1  christos 	 FALSE,			/* pc_relative */
    519  1.1  christos 	 0,			/* bitpos */
    520  1.1  christos 	 complain_overflow_bitfield, /* complain_on_overflow */
    521  1.1  christos 	 bfd_elf_generic_reloc, /* special_function */
    522  1.1  christos 	 "R_LM32_RELATIVE",	/* name */
    523  1.1  christos 	 FALSE,			/* partial_inplace */
    524  1.1  christos 	 0xffffffff,		/* src_mask */
    525  1.1  christos 	 0xffffffff,		/* dst_mask */
    526  1.1  christos 	 FALSE),		/* pcrel_offset */
    527  1.1  christos 
    528  1.1  christos };
    529  1.1  christos 
    530  1.1  christos /* Map BFD reloc types to lm32 ELF reloc types. */
    531  1.1  christos 
    532  1.1  christos struct lm32_reloc_map
    533  1.1  christos {
    534  1.1  christos     bfd_reloc_code_real_type bfd_reloc_val;
    535  1.1  christos     unsigned char elf_reloc_val;
    536  1.1  christos };
    537  1.1  christos 
    538  1.1  christos static const struct lm32_reloc_map lm32_reloc_map[] =
    539  1.1  christos {
    540  1.1  christos   { BFD_RELOC_NONE,             R_LM32_NONE },
    541  1.1  christos   { BFD_RELOC_8,                R_LM32_8 },
    542  1.1  christos   { BFD_RELOC_16,               R_LM32_16 },
    543  1.1  christos   { BFD_RELOC_32,               R_LM32_32 },
    544  1.1  christos   { BFD_RELOC_HI16,             R_LM32_HI16 },
    545  1.1  christos   { BFD_RELOC_LO16,             R_LM32_LO16 },
    546  1.1  christos   { BFD_RELOC_GPREL16,          R_LM32_GPREL16 },
    547  1.1  christos   { BFD_RELOC_LM32_CALL,        R_LM32_CALL },
    548  1.1  christos   { BFD_RELOC_LM32_BRANCH,      R_LM32_BRANCH },
    549  1.1  christos   { BFD_RELOC_VTABLE_INHERIT,   R_LM32_GNU_VTINHERIT },
    550  1.1  christos   { BFD_RELOC_VTABLE_ENTRY,     R_LM32_GNU_VTENTRY },
    551  1.1  christos   { BFD_RELOC_LM32_16_GOT,      R_LM32_16_GOT },
    552  1.1  christos   { BFD_RELOC_LM32_GOTOFF_HI16, R_LM32_GOTOFF_HI16 },
    553  1.1  christos   { BFD_RELOC_LM32_GOTOFF_LO16, R_LM32_GOTOFF_LO16 },
    554  1.1  christos   { BFD_RELOC_LM32_COPY,        R_LM32_COPY },
    555  1.1  christos   { BFD_RELOC_LM32_GLOB_DAT,    R_LM32_GLOB_DAT },
    556  1.1  christos   { BFD_RELOC_LM32_JMP_SLOT,    R_LM32_JMP_SLOT },
    557  1.1  christos   { BFD_RELOC_LM32_RELATIVE,    R_LM32_RELATIVE },
    558  1.1  christos };
    559  1.1  christos 
    560  1.1  christos static reloc_howto_type *
    561  1.1  christos lm32_reloc_type_lookup (bfd *abfd ATTRIBUTE_UNUSED,
    562  1.1  christos                         bfd_reloc_code_real_type code)
    563  1.1  christos {
    564  1.1  christos   unsigned int i;
    565  1.1  christos 
    566  1.1  christos   for (i = 0; i < sizeof (lm32_reloc_map) / sizeof (lm32_reloc_map[0]); i++)
    567  1.1  christos     if (lm32_reloc_map[i].bfd_reloc_val == code)
    568  1.1  christos       return &lm32_elf_howto_table[lm32_reloc_map[i].elf_reloc_val];
    569  1.1  christos   return NULL;
    570  1.1  christos }
    571  1.1  christos 
    572  1.1  christos static reloc_howto_type *
    573  1.1  christos lm32_reloc_name_lookup (bfd *abfd ATTRIBUTE_UNUSED,
    574  1.1  christos 			const char *r_name)
    575  1.1  christos {
    576  1.1  christos   unsigned int i;
    577  1.1  christos 
    578  1.1  christos   for (i = 0;
    579  1.1  christos        i < sizeof (lm32_elf_howto_table) / sizeof (lm32_elf_howto_table[0]);
    580  1.1  christos        i++)
    581  1.1  christos     if (lm32_elf_howto_table[i].name != NULL
    582  1.1  christos 	&& strcasecmp (lm32_elf_howto_table[i].name, r_name) == 0)
    583  1.1  christos       return &lm32_elf_howto_table[i];
    584  1.1  christos 
    585  1.1  christos   return NULL;
    586  1.1  christos }
    587  1.1  christos 
    588  1.1  christos 
    589  1.1  christos /* Set the howto pointer for an Lattice Mico32 ELF reloc.  */
    590  1.1  christos 
    591  1.1  christos static void
    592  1.1  christos lm32_info_to_howto_rela (bfd *abfd ATTRIBUTE_UNUSED,
    593  1.1  christos                          arelent *cache_ptr,
    594  1.1  christos                          Elf_Internal_Rela *dst)
    595  1.1  christos {
    596  1.1  christos   unsigned int r_type;
    597  1.1  christos 
    598  1.1  christos   r_type = ELF32_R_TYPE (dst->r_info);
    599  1.1  christos   BFD_ASSERT (r_type < (unsigned int) R_LM32_max);
    600  1.1  christos   cache_ptr->howto = &lm32_elf_howto_table[r_type];
    601  1.1  christos }
    602  1.1  christos 
    603  1.1  christos /* Set the right machine number for an Lattice Mico32 ELF file. */
    604  1.1  christos 
    605  1.1  christos static bfd_boolean
    606  1.1  christos lm32_elf_object_p (bfd *abfd)
    607  1.1  christos {
    608  1.1  christos   return bfd_default_set_arch_mach (abfd, bfd_arch_lm32, bfd_mach_lm32);
    609  1.1  christos }
    610  1.1  christos 
    611  1.1  christos /* Set machine type flags just before file is written out. */
    612  1.1  christos 
    613  1.1  christos static void
    614  1.1  christos lm32_elf_final_write_processing (bfd *abfd, bfd_boolean linker ATTRIBUTE_UNUSED)
    615  1.1  christos {
    616  1.1  christos   elf_elfheader (abfd)->e_machine = EM_LATTICEMICO32;
    617  1.1  christos   elf_elfheader (abfd)->e_flags &=~ EF_LM32_MACH;
    618  1.1  christos   switch (bfd_get_mach (abfd))
    619  1.1  christos     {
    620  1.1  christos       case bfd_mach_lm32:
    621  1.1  christos         elf_elfheader (abfd)->e_flags |= E_LM32_MACH;
    622  1.1  christos         break;
    623  1.1  christos       default:
    624  1.1  christos         abort ();
    625  1.1  christos     }
    626  1.1  christos }
    627  1.1  christos 
    628  1.1  christos /* Set the GP value for OUTPUT_BFD.  Returns FALSE if this is a
    629  1.1  christos    dangerous relocation.  */
    630  1.1  christos 
    631  1.1  christos static bfd_boolean
    632  1.1  christos lm32_elf_assign_gp (bfd *output_bfd, bfd_vma *pgp)
    633  1.1  christos {
    634  1.1  christos   unsigned int count;
    635  1.1  christos   asymbol **sym;
    636  1.1  christos   unsigned int i;
    637  1.1  christos 
    638  1.1  christos   /* If we've already figured out what GP will be, just return it. */
    639  1.1  christos   *pgp = _bfd_get_gp_value (output_bfd);
    640  1.1  christos   if (*pgp)
    641  1.1  christos     return TRUE;
    642  1.1  christos 
    643  1.1  christos   count = bfd_get_symcount (output_bfd);
    644  1.1  christos   sym = bfd_get_outsymbols (output_bfd);
    645  1.1  christos 
    646  1.1  christos   /* The linker script will have created a symbol named `_gp' with the
    647  1.1  christos      appropriate value.  */
    648  1.1  christos   if (sym == NULL)
    649  1.1  christos     i = count;
    650  1.1  christos   else
    651  1.1  christos     {
    652  1.1  christos       for (i = 0; i < count; i++, sym++)
    653  1.1  christos 	{
    654  1.1  christos 	  const char *name;
    655  1.1  christos 
    656  1.1  christos 	  name = bfd_asymbol_name (*sym);
    657  1.1  christos 	  if (*name == '_' && strcmp (name, "_gp") == 0)
    658  1.1  christos 	    {
    659  1.1  christos 	      *pgp = bfd_asymbol_value (*sym);
    660  1.1  christos 	      _bfd_set_gp_value (output_bfd, *pgp);
    661  1.1  christos 	      break;
    662  1.1  christos 	    }
    663  1.1  christos 	}
    664  1.1  christos     }
    665  1.1  christos 
    666  1.1  christos   if (i >= count)
    667  1.1  christos     {
    668  1.1  christos       /* Only get the error once.  */
    669  1.1  christos       *pgp = 4;
    670  1.1  christos       _bfd_set_gp_value (output_bfd, *pgp);
    671  1.1  christos       return FALSE;
    672  1.1  christos     }
    673  1.1  christos 
    674  1.1  christos   return TRUE;
    675  1.1  christos }
    676  1.1  christos 
    677  1.1  christos /* We have to figure out the gp value, so that we can adjust the
    678  1.1  christos    symbol value correctly.  We look up the symbol _gp in the output
    679  1.1  christos    BFD.  If we can't find it, we're stuck.  We cache it in the ELF
    680  1.1  christos    target data.  We don't need to adjust the symbol value for an
    681  1.1  christos    external symbol if we are producing relocatable output.  */
    682  1.1  christos 
    683  1.1  christos static bfd_reloc_status_type
    684  1.1  christos lm32_elf_final_gp (bfd *output_bfd, asymbol *symbol, bfd_boolean relocatable,
    685  1.1  christos                     char **error_message, bfd_vma *pgp)
    686  1.1  christos {
    687  1.1  christos   if (bfd_is_und_section (symbol->section) && !relocatable)
    688  1.1  christos     {
    689  1.1  christos       *pgp = 0;
    690  1.1  christos       return bfd_reloc_undefined;
    691  1.1  christos     }
    692  1.1  christos 
    693  1.1  christos   *pgp = _bfd_get_gp_value (output_bfd);
    694  1.1  christos   if (*pgp == 0 && (!relocatable || (symbol->flags & BSF_SECTION_SYM) != 0))
    695  1.1  christos     {
    696  1.1  christos       if (relocatable)
    697  1.1  christos 	{
    698  1.1  christos 	  /* Make up a value.  */
    699  1.1  christos 	  *pgp = symbol->section->output_section->vma + 0x4000;
    700  1.1  christos 	  _bfd_set_gp_value (output_bfd, *pgp);
    701  1.1  christos 	}
    702  1.1  christos       else if (!lm32_elf_assign_gp (output_bfd, pgp))
    703  1.1  christos 	{
    704  1.1  christos 	  *error_message =
    705  1.1  christos 	    (char *)
    706  1.1  christos 	    _("global pointer relative relocation when _gp not defined");
    707  1.1  christos 	  return bfd_reloc_dangerous;
    708  1.1  christos 	}
    709  1.1  christos     }
    710  1.1  christos 
    711  1.1  christos   return bfd_reloc_ok;
    712  1.1  christos }
    713  1.1  christos 
    714  1.1  christos static bfd_reloc_status_type
    715  1.1  christos lm32_elf_do_gprel_relocate (bfd *abfd,
    716  1.1  christos 			    reloc_howto_type *howto,
    717  1.1  christos 			    asection *input_section ATTRIBUTE_UNUSED,
    718  1.1  christos 			    bfd_byte *data,
    719  1.1  christos 			    bfd_vma offset,
    720  1.1  christos 			    bfd_vma symbol_value,
    721  1.1  christos 			    bfd_vma addend)
    722  1.1  christos {
    723  1.1  christos   return _bfd_final_link_relocate (howto, abfd, input_section,
    724  1.1  christos 				   data, offset, symbol_value, addend);
    725  1.1  christos }
    726  1.1  christos 
    727  1.1  christos static bfd_reloc_status_type
    728  1.1  christos lm32_elf_gprel_reloc (bfd *abfd,
    729  1.1  christos 		      arelent *reloc_entry,
    730  1.1  christos 		      asymbol *symbol,
    731  1.1  christos 		      void *data,
    732  1.1  christos 		      asection *input_section,
    733  1.1  christos 		      bfd *output_bfd,
    734  1.1  christos 		      char **msg)
    735  1.1  christos {
    736  1.1  christos   bfd_vma relocation;
    737  1.1  christos   bfd_vma gp;
    738  1.1  christos   bfd_reloc_status_type r;
    739  1.1  christos 
    740  1.1  christos   if (output_bfd != (bfd *) NULL
    741  1.1  christos       && (symbol->flags & BSF_SECTION_SYM) == 0
    742  1.1  christos       && (!reloc_entry->howto->partial_inplace || reloc_entry->addend == 0))
    743  1.1  christos     {
    744  1.1  christos       reloc_entry->address += input_section->output_offset;
    745  1.1  christos       return bfd_reloc_ok;
    746  1.1  christos     }
    747  1.1  christos 
    748  1.1  christos   if (output_bfd != NULL)
    749  1.1  christos     return bfd_reloc_ok;
    750  1.1  christos 
    751  1.1  christos   relocation = symbol->value
    752  1.1  christos     + symbol->section->output_section->vma + symbol->section->output_offset;
    753  1.1  christos 
    754  1.1  christos   if ((r =
    755  1.1  christos        lm32_elf_final_gp (abfd, symbol, FALSE, msg, &gp)) == bfd_reloc_ok)
    756  1.1  christos     {
    757  1.1  christos       relocation = relocation + reloc_entry->addend - gp;
    758  1.1  christos       reloc_entry->addend = 0;
    759  1.1  christos       if ((signed) relocation < -32768 || (signed) relocation > 32767)
    760  1.1  christos 	{
    761  1.1  christos 	  *msg = _("global pointer relative address out of range");
    762  1.1  christos 	  r = bfd_reloc_outofrange;
    763  1.1  christos 	}
    764  1.1  christos       else
    765  1.1  christos 	{
    766  1.1  christos 	  r = lm32_elf_do_gprel_relocate (abfd, reloc_entry->howto,
    767  1.1  christos 					     input_section,
    768  1.1  christos 					     data, reloc_entry->address,
    769  1.1  christos 					     relocation, reloc_entry->addend);
    770  1.1  christos 	}
    771  1.1  christos     }
    772  1.1  christos 
    773  1.1  christos   return r;
    774  1.1  christos }
    775  1.1  christos 
    776  1.1  christos /* Find the segment number in which OSEC, and output section, is
    777  1.1  christos    located.  */
    778  1.1  christos 
    779  1.1  christos static unsigned
    780  1.1  christos _lm32fdpic_osec_to_segment (bfd *output_bfd, asection *osec)
    781  1.1  christos {
    782  1.1  christos   struct elf_segment_map *m;
    783  1.1  christos   Elf_Internal_Phdr *p;
    784  1.1  christos 
    785  1.1  christos   /* Find the segment that contains the output_section.  */
    786  1.1  christos   for (m = elf_tdata (output_bfd)->segment_map,
    787  1.1  christos 	 p = elf_tdata (output_bfd)->phdr;
    788  1.1  christos        m != NULL;
    789  1.1  christos        m = m->next, p++)
    790  1.1  christos     {
    791  1.1  christos       int i;
    792  1.1  christos 
    793  1.1  christos       for (i = m->count - 1; i >= 0; i--)
    794  1.1  christos 	if (m->sections[i] == osec)
    795  1.1  christos 	  break;
    796  1.1  christos 
    797  1.1  christos       if (i >= 0)
    798  1.1  christos 	break;
    799  1.1  christos     }
    800  1.1  christos 
    801  1.1  christos   return p - elf_tdata (output_bfd)->phdr;
    802  1.1  christos }
    803  1.1  christos 
    804  1.1  christos /* Determine if an output section is read-only.  */
    805  1.1  christos 
    806  1.1  christos inline static bfd_boolean
    807  1.1  christos _lm32fdpic_osec_readonly_p (bfd *output_bfd, asection *osec)
    808  1.1  christos {
    809  1.1  christos   unsigned seg = _lm32fdpic_osec_to_segment (output_bfd, osec);
    810  1.1  christos 
    811  1.1  christos   return ! (elf_tdata (output_bfd)->phdr[seg].p_flags & PF_W);
    812  1.1  christos }
    813  1.1  christos 
    814  1.1  christos /* Relocate a section */
    815  1.1  christos 
    816  1.1  christos static bfd_boolean
    817  1.1  christos lm32_elf_relocate_section (bfd *output_bfd,
    818  1.1  christos                            struct bfd_link_info *info,
    819  1.1  christos                            bfd *input_bfd,
    820  1.1  christos                            asection *input_section,
    821  1.1  christos                            bfd_byte *contents,
    822  1.1  christos                            Elf_Internal_Rela *relocs,
    823  1.1  christos                            Elf_Internal_Sym *local_syms,
    824  1.1  christos                            asection **local_sections)
    825  1.1  christos {
    826  1.1  christos   Elf_Internal_Shdr *symtab_hdr = &elf_tdata (input_bfd)->symtab_hdr;
    827  1.1  christos   struct elf_link_hash_entry **sym_hashes = elf_sym_hashes (input_bfd);
    828  1.1  christos   Elf_Internal_Rela *rel, *relend;
    829  1.1  christos   struct elf_lm32_link_hash_table *htab = lm32_elf_hash_table (info);
    830  1.1  christos   bfd *dynobj;
    831  1.1  christos   bfd_vma *local_got_offsets;
    832  1.1  christos   asection *sgot;
    833  1.1  christos 
    834  1.1  christos   if (htab == NULL)
    835  1.1  christos     return FALSE;
    836  1.1  christos 
    837  1.1  christos   dynobj = htab->root.dynobj;
    838  1.1  christos   local_got_offsets = elf_local_got_offsets (input_bfd);
    839  1.1  christos 
    840  1.1  christos   sgot = htab->sgot;
    841  1.1  christos 
    842  1.1  christos   symtab_hdr = &elf_tdata (input_bfd)->symtab_hdr;
    843  1.1  christos   sym_hashes = elf_sym_hashes (input_bfd);
    844  1.1  christos 
    845  1.1  christos   rel = relocs;
    846  1.1  christos   relend = relocs + input_section->reloc_count;
    847  1.1  christos   for (; rel < relend; rel++)
    848  1.1  christos     {
    849  1.1  christos       reloc_howto_type *howto;
    850  1.1  christos       unsigned int r_type;
    851  1.1  christos       unsigned long r_symndx;
    852  1.1  christos       Elf_Internal_Sym *sym;
    853  1.1  christos       asection *sec;
    854  1.1  christos       struct elf_link_hash_entry *h;
    855  1.1  christos       bfd_vma relocation;
    856  1.1  christos       bfd_vma gp;
    857  1.1  christos       bfd_reloc_status_type r;
    858  1.1  christos       const char *name = NULL;
    859  1.1  christos 
    860  1.1  christos       r_symndx = ELF32_R_SYM (rel->r_info);
    861  1.1  christos       r_type = ELF32_R_TYPE (rel->r_info);
    862  1.1  christos 
    863  1.1  christos       if (r_type == R_LM32_GNU_VTENTRY
    864  1.1  christos           || r_type == R_LM32_GNU_VTINHERIT )
    865  1.1  christos         continue;
    866  1.1  christos 
    867  1.1  christos       h = NULL;
    868  1.1  christos       sym = NULL;
    869  1.1  christos       sec = NULL;
    870  1.1  christos 
    871  1.1  christos       howto = lm32_elf_howto_table + r_type;
    872  1.1  christos 
    873  1.1  christos       if (r_symndx < symtab_hdr->sh_info)
    874  1.1  christos         {
    875  1.1  christos           /* It's a local symbol.  */
    876  1.1  christos           sym = local_syms + r_symndx;
    877  1.1  christos           sec = local_sections[r_symndx];
    878  1.1  christos           relocation = _bfd_elf_rela_local_sym (output_bfd, sym, &sec, rel);
    879  1.1  christos           name = bfd_elf_string_from_elf_section
    880  1.1  christos 	    (input_bfd, symtab_hdr->sh_link, sym->st_name);
    881  1.1  christos 	  name = (name == NULL) ? bfd_section_name (input_bfd, sec) : name;
    882  1.1  christos         }
    883  1.1  christos       else
    884  1.1  christos         {
    885  1.1  christos           /* It's a global symbol.  */
    886  1.1  christos           bfd_boolean unresolved_reloc;
    887  1.1  christos 	  bfd_boolean warned;
    888  1.1  christos 
    889  1.1  christos 	  RELOC_FOR_GLOBAL_SYMBOL (info, input_bfd, input_section, rel,
    890  1.1  christos 				   r_symndx, symtab_hdr, sym_hashes,
    891  1.1  christos 				   h, sec, relocation,
    892  1.1  christos 				   unresolved_reloc, warned);
    893  1.1  christos 	  name = h->root.root.string;
    894  1.1  christos         }
    895  1.1  christos 
    896  1.1  christos       if (sec != NULL && elf_discarded_section (sec))
    897  1.1  christos 	RELOC_AGAINST_DISCARDED_SECTION (info, input_bfd, input_section,
    898  1.1  christos 					 rel, relend, howto, contents);
    899  1.1  christos 
    900  1.1  christos       if (info->relocatable)
    901  1.1  christos         {
    902  1.1  christos 	  /* This is a relocatable link.  We don't have to change
    903  1.1  christos 	     anything, unless the reloc is against a section symbol,
    904  1.1  christos 	     in which case we have to adjust according to where the
    905  1.1  christos 	     section symbol winds up in the output section.  */
    906  1.1  christos 	  if (sym == NULL || ELF_ST_TYPE (sym->st_info) != STT_SECTION)
    907  1.1  christos 	    continue;
    908  1.1  christos 
    909  1.1  christos 	  /* If partial_inplace, we need to store any additional addend
    910  1.1  christos 	     back in the section.  */
    911  1.1  christos 	  if (! howto->partial_inplace)
    912  1.1  christos 	    continue;
    913  1.1  christos 
    914  1.1  christos           /* Shouldn't reach here.  */
    915  1.1  christos 	  abort ();
    916  1.1  christos 	  r = bfd_reloc_ok;
    917  1.1  christos         }
    918  1.1  christos       else
    919  1.1  christos         {
    920  1.1  christos           switch (howto->type)
    921  1.1  christos             {
    922  1.1  christos             case R_LM32_GPREL16:
    923  1.1  christos               if (!lm32_elf_assign_gp (output_bfd, &gp))
    924  1.1  christos                 r = bfd_reloc_dangerous;
    925  1.1  christos               else
    926  1.1  christos                 {
    927  1.1  christos                   relocation = relocation + rel->r_addend - gp;
    928  1.1  christos                   rel->r_addend = 0;
    929  1.1  christos                   if ((signed)relocation < -32768 || (signed)relocation > 32767)
    930  1.1  christos                     r = bfd_reloc_outofrange;
    931  1.1  christos                   else
    932  1.1  christos                     {
    933  1.1  christos                       r = _bfd_final_link_relocate (howto, input_bfd,
    934  1.1  christos                 				  input_section, contents,
    935  1.1  christos                				  rel->r_offset, relocation,
    936  1.1  christos                				  rel->r_addend);
    937  1.1  christos                    }
    938  1.1  christos                 }
    939  1.1  christos               break;
    940  1.1  christos             case R_LM32_16_GOT:
    941  1.1  christos               /* Relocation is to the entry for this symbol in the global
    942  1.1  christos                  offset table.  */
    943  1.1  christos               BFD_ASSERT (sgot != NULL);
    944  1.1  christos               if (h != NULL)
    945  1.1  christos                 {
    946  1.1  christos                   bfd_boolean dyn;
    947  1.1  christos                   bfd_vma off;
    948  1.1  christos 
    949  1.1  christos                   off = h->got.offset;
    950  1.1  christos                   BFD_ASSERT (off != (bfd_vma) -1);
    951  1.1  christos 
    952  1.1  christos                   dyn = htab->root.dynamic_sections_created;
    953  1.1  christos                   if (! WILL_CALL_FINISH_DYNAMIC_SYMBOL (dyn, info->shared, h)
    954  1.1  christos                       || (info->shared
    955  1.1  christos                           && (info->symbolic
    956  1.1  christos                               || h->dynindx == -1
    957  1.1  christos                               || h->forced_local)
    958  1.1  christos                           && h->def_regular))
    959  1.1  christos                     {
    960  1.1  christos                       /* This is actually a static link, or it is a
    961  1.1  christos                          -Bsymbolic link and the symbol is defined
    962  1.1  christos                          locally, or the symbol was forced to be local
    963  1.1  christos                          because of a version file.  We must initialize
    964  1.1  christos                          this entry in the global offset table.  Since the
    965  1.1  christos                          offset must always be a multiple of 4, we use the
    966  1.1  christos                          least significant bit to record whether we have
    967  1.1  christos                          initialized it already.
    968  1.1  christos 
    969  1.1  christos                          When doing a dynamic link, we create a .rela.got
    970  1.1  christos                          relocation entry to initialize the value.  This
    971  1.1  christos                          is done in the finish_dynamic_symbol routine.  */
    972  1.1  christos                       if ((off & 1) != 0)
    973  1.1  christos                         off &= ~1;
    974  1.1  christos                       else
    975  1.1  christos                         {
    976  1.1  christos                           /* Write entry in GOT */
    977  1.1  christos                           bfd_put_32 (output_bfd, relocation,
    978  1.1  christos                                       sgot->contents + off);
    979  1.1  christos                           /* Create entry in .rofixup pointing to GOT entry.  */
    980  1.1  christos                            if (IS_FDPIC (output_bfd) && h->root.type != bfd_link_hash_undefweak)
    981  1.1  christos                              {
    982  1.1  christos 	                       _lm32fdpic_add_rofixup (output_bfd,
    983  1.1  christos 			                               lm32fdpic_fixup32_section
    984  1.1  christos 				                        (info),
    985  1.1  christos 				                       sgot->output_section->vma
    986  1.1  christos                                                         + sgot->output_offset
    987  1.1  christos                                                         + off);
    988  1.1  christos                              }
    989  1.1  christos                           /* Mark GOT entry as having been written.  */
    990  1.1  christos                           h->got.offset |= 1;
    991  1.1  christos                         }
    992  1.1  christos                     }
    993  1.1  christos 
    994  1.1  christos                   relocation = sgot->output_offset + off;
    995  1.1  christos                 }
    996  1.1  christos               else
    997  1.1  christos                 {
    998  1.1  christos                   bfd_vma off;
    999  1.1  christos                   bfd_byte *loc;
   1000  1.1  christos 
   1001  1.1  christos                   BFD_ASSERT (local_got_offsets != NULL
   1002  1.1  christos                               && local_got_offsets[r_symndx] != (bfd_vma) -1);
   1003  1.1  christos 
   1004  1.1  christos                   /* Get offset into GOT table.  */
   1005  1.1  christos                   off = local_got_offsets[r_symndx];
   1006  1.1  christos 
   1007  1.1  christos                   /* The offset must always be a multiple of 4.  We use
   1008  1.1  christos                      the least significant bit to record whether we have
   1009  1.1  christos                      already processed this entry.  */
   1010  1.1  christos                   if ((off & 1) != 0)
   1011  1.1  christos                     off &= ~1;
   1012  1.1  christos                   else
   1013  1.1  christos                     {
   1014  1.1  christos                       /* Write entry in GOT.  */
   1015  1.1  christos                       bfd_put_32 (output_bfd, relocation, sgot->contents + off);
   1016  1.1  christos                       /* Create entry in .rofixup pointing to GOT entry.  */
   1017  1.1  christos                       if (IS_FDPIC (output_bfd))
   1018  1.1  christos                         {
   1019  1.1  christos 	                  _lm32fdpic_add_rofixup (output_bfd,
   1020  1.1  christos 				                  lm32fdpic_fixup32_section
   1021  1.1  christos 				                   (info),
   1022  1.1  christos 				                  sgot->output_section->vma
   1023  1.1  christos                                                    + sgot->output_offset
   1024  1.1  christos                                                    + off);
   1025  1.1  christos                         }
   1026  1.1  christos 
   1027  1.1  christos                       if (info->shared)
   1028  1.1  christos                         {
   1029  1.1  christos                           asection *srelgot;
   1030  1.1  christos                           Elf_Internal_Rela outrel;
   1031  1.1  christos 
   1032  1.1  christos                           /* We need to generate a R_LM32_RELATIVE reloc
   1033  1.1  christos                              for the dynamic linker.  */
   1034  1.1  christos                           srelgot = bfd_get_section_by_name (dynobj, ".rela.got");
   1035  1.1  christos                           BFD_ASSERT (srelgot != NULL);
   1036  1.1  christos 
   1037  1.1  christos                           outrel.r_offset = (sgot->output_section->vma
   1038  1.1  christos                                              + sgot->output_offset
   1039  1.1  christos                                              + off);
   1040  1.1  christos                           outrel.r_info = ELF32_R_INFO (0, R_LM32_RELATIVE);
   1041  1.1  christos                           outrel.r_addend = relocation;
   1042  1.1  christos                           loc = srelgot->contents;
   1043  1.1  christos                           loc += srelgot->reloc_count * sizeof (Elf32_External_Rela);
   1044  1.1  christos                           bfd_elf32_swap_reloca_out (output_bfd, &outrel,loc);
   1045  1.1  christos                           ++srelgot->reloc_count;
   1046  1.1  christos                         }
   1047  1.1  christos 
   1048  1.1  christos                       local_got_offsets[r_symndx] |= 1;
   1049  1.1  christos                     }
   1050  1.1  christos 
   1051  1.1  christos 
   1052  1.1  christos                   relocation = sgot->output_offset + off;
   1053  1.1  christos                 }
   1054  1.1  christos 
   1055  1.1  christos               /* Addend should be zero.  */
   1056  1.1  christos               if (rel->r_addend != 0)
   1057  1.1  christos                 (*_bfd_error_handler) (_("internal error: addend should be zero for R_LM32_16_GOT"));
   1058  1.1  christos 
   1059  1.1  christos               r = _bfd_final_link_relocate (howto,
   1060  1.1  christos                                             input_bfd,
   1061  1.1  christos                                             input_section,
   1062  1.1  christos                                             contents,
   1063  1.1  christos                                             rel->r_offset,
   1064  1.1  christos                                             relocation,
   1065  1.1  christos                                             rel->r_addend);
   1066  1.1  christos               break;
   1067  1.1  christos 
   1068  1.1  christos             case R_LM32_GOTOFF_LO16:
   1069  1.1  christos             case R_LM32_GOTOFF_HI16:
   1070  1.1  christos               /* Relocation is offset from GOT.  */
   1071  1.1  christos 	      BFD_ASSERT (sgot != NULL);
   1072  1.1  christos 	      relocation -= sgot->output_section->vma;
   1073  1.1  christos 	      /* Account for sign-extension.  */
   1074  1.1  christos               if ((r_type == R_LM32_GOTOFF_HI16)
   1075  1.1  christos                   && ((relocation + rel->r_addend) & 0x8000))
   1076  1.1  christos                 rel->r_addend += 0x10000;
   1077  1.1  christos               r = _bfd_final_link_relocate (howto,
   1078  1.1  christos                                             input_bfd,
   1079  1.1  christos                                             input_section,
   1080  1.1  christos                                             contents,
   1081  1.1  christos                                             rel->r_offset,
   1082  1.1  christos                                             relocation,
   1083  1.1  christos                                             rel->r_addend);
   1084  1.1  christos               break;
   1085  1.1  christos 
   1086  1.1  christos             case R_LM32_32:
   1087  1.1  christos               if (IS_FDPIC (output_bfd))
   1088  1.1  christos                 {
   1089  1.1  christos                   if ((!h) || (h && h->root.type != bfd_link_hash_undefweak))
   1090  1.1  christos                     {
   1091  1.1  christos                       /* Only create .rofixup entries for relocs in loadable sections.  */
   1092  1.1  christos                       if ((bfd_get_section_flags (output_bfd, input_section->output_section)
   1093  1.1  christos                           & (SEC_ALLOC | SEC_LOAD)) == (SEC_ALLOC | SEC_LOAD))
   1094  1.1  christos 
   1095  1.1  christos                         {
   1096  1.1  christos                           /* Check address to be modified is writable.  */
   1097  1.1  christos                           if (_lm32fdpic_osec_readonly_p (output_bfd,
   1098  1.1  christos                                                           input_section
   1099  1.1  christos                                                            ->output_section))
   1100  1.1  christos                             {
   1101  1.1  christos                               info->callbacks->warning
   1102  1.1  christos                                 (info,
   1103  1.1  christos                                  _("cannot emit dynamic relocations in read-only section"),
   1104  1.1  christos                                  name, input_bfd, input_section, rel->r_offset);
   1105  1.1  christos                                return FALSE;
   1106  1.1  christos                             }
   1107  1.1  christos                           /* Create entry in .rofixup section.  */
   1108  1.1  christos                           _lm32fdpic_add_rofixup (output_bfd,
   1109  1.1  christos                                                   lm32fdpic_fixup32_section (info),
   1110  1.1  christos                                                   input_section->output_section->vma
   1111  1.1  christos                                                    + input_section->output_offset
   1112  1.1  christos                                                    + rel->r_offset);
   1113  1.1  christos                         }
   1114  1.1  christos                     }
   1115  1.1  christos                 }
   1116  1.1  christos               /* Fall through.  */
   1117  1.1  christos 
   1118  1.1  christos             default:
   1119  1.1  christos               r = _bfd_final_link_relocate (howto,
   1120  1.1  christos                                             input_bfd,
   1121  1.1  christos                                             input_section,
   1122  1.1  christos                                             contents,
   1123  1.1  christos                                             rel->r_offset,
   1124  1.1  christos                                             relocation,
   1125  1.1  christos                                             rel->r_addend);
   1126  1.1  christos               break;
   1127  1.1  christos             }
   1128  1.1  christos         }
   1129  1.1  christos 
   1130  1.1  christos       if (r != bfd_reloc_ok)
   1131  1.1  christos         {
   1132  1.1  christos           const char *msg = NULL;
   1133  1.1  christos           arelent bfd_reloc;
   1134  1.1  christos 
   1135  1.1  christos           lm32_info_to_howto_rela (input_bfd, &bfd_reloc, rel);
   1136  1.1  christos           howto = bfd_reloc.howto;
   1137  1.1  christos 
   1138  1.1  christos           if (h != NULL)
   1139  1.1  christos             name = h->root.root.string;
   1140  1.1  christos           else
   1141  1.1  christos             {
   1142  1.1  christos               name = (bfd_elf_string_from_elf_section
   1143  1.1  christos                       (input_bfd, symtab_hdr->sh_link, sym->st_name));
   1144  1.1  christos               if (name == NULL || *name == '\0')
   1145  1.1  christos                 name = bfd_section_name (input_bfd, sec);
   1146  1.1  christos             }
   1147  1.1  christos 
   1148  1.1  christos           switch (r)
   1149  1.1  christos             {
   1150  1.1  christos 	    case bfd_reloc_overflow:
   1151  1.1  christos 	      if ((h != NULL)
   1152  1.1  christos                  && (h->root.type == bfd_link_hash_undefweak))
   1153  1.1  christos 	        break;
   1154  1.1  christos 	      if (! ((*info->callbacks->reloc_overflow)
   1155  1.1  christos 		     (info, (h ? &h->root : NULL), name, howto->name,
   1156  1.1  christos 		      (bfd_vma) 0, input_bfd, input_section, rel->r_offset)))
   1157  1.1  christos 		return FALSE;
   1158  1.1  christos 	      break;
   1159  1.1  christos 
   1160  1.1  christos             case bfd_reloc_undefined:
   1161  1.1  christos               if (! ((*info->callbacks->undefined_symbol)
   1162  1.1  christos                      (info, name, input_bfd, input_section,
   1163  1.1  christos                       rel->r_offset, TRUE)))
   1164  1.1  christos                 return FALSE;
   1165  1.1  christos               break;
   1166  1.1  christos 
   1167  1.1  christos             case bfd_reloc_outofrange:
   1168  1.1  christos               msg = _("internal error: out of range error");
   1169  1.1  christos               goto common_error;
   1170  1.1  christos 
   1171  1.1  christos             case bfd_reloc_notsupported:
   1172  1.1  christos               msg = _("internal error: unsupported relocation error");
   1173  1.1  christos               goto common_error;
   1174  1.1  christos 
   1175  1.1  christos             case bfd_reloc_dangerous:
   1176  1.1  christos               msg = _("internal error: dangerous error");
   1177  1.1  christos               goto common_error;
   1178  1.1  christos 
   1179  1.1  christos             default:
   1180  1.1  christos               msg = _("internal error: unknown error");
   1181  1.1  christos               /* fall through */
   1182  1.1  christos 
   1183  1.1  christos             common_error:
   1184  1.1  christos               if (!((*info->callbacks->warning)
   1185  1.1  christos                     (info, msg, name, input_bfd, input_section,
   1186  1.1  christos                      rel->r_offset)))
   1187  1.1  christos                 return FALSE;
   1188  1.1  christos               break;
   1189  1.1  christos             }
   1190  1.1  christos         }
   1191  1.1  christos     }
   1192  1.1  christos 
   1193  1.1  christos   return TRUE;
   1194  1.1  christos }
   1195  1.1  christos 
   1196  1.1  christos static asection *
   1197  1.1  christos lm32_elf_gc_mark_hook (asection *sec,
   1198  1.1  christos                        struct bfd_link_info *info,
   1199  1.1  christos                        Elf_Internal_Rela *rel,
   1200  1.1  christos                        struct elf_link_hash_entry *h,
   1201  1.1  christos                        Elf_Internal_Sym *sym)
   1202  1.1  christos {
   1203  1.1  christos   if (h != NULL)
   1204  1.1  christos     switch (ELF32_R_TYPE (rel->r_info))
   1205  1.1  christos       {
   1206  1.1  christos       case R_LM32_GNU_VTINHERIT:
   1207  1.1  christos       case R_LM32_GNU_VTENTRY:
   1208  1.1  christos 	return NULL;
   1209  1.1  christos       }
   1210  1.1  christos 
   1211  1.1  christos   return _bfd_elf_gc_mark_hook (sec, info, rel, h, sym);
   1212  1.1  christos }
   1213  1.1  christos 
   1214  1.1  christos static bfd_boolean
   1215  1.1  christos lm32_elf_gc_sweep_hook (bfd *abfd,
   1216  1.1  christos                         struct bfd_link_info *info ATTRIBUTE_UNUSED,
   1217  1.1  christos                         asection *sec,
   1218  1.1  christos                         const Elf_Internal_Rela *relocs ATTRIBUTE_UNUSED)
   1219  1.1  christos {
   1220  1.1  christos   /* Update the got entry reference counts for the section being removed.  */
   1221  1.1  christos   Elf_Internal_Shdr *symtab_hdr;
   1222  1.1  christos   struct elf_link_hash_entry **sym_hashes;
   1223  1.1  christos   bfd_signed_vma *local_got_refcounts;
   1224  1.1  christos   const Elf_Internal_Rela *rel, *relend;
   1225  1.1  christos 
   1226  1.1  christos   elf_section_data (sec)->local_dynrel = NULL;
   1227  1.1  christos 
   1228  1.1  christos   symtab_hdr = &elf_tdata (abfd)->symtab_hdr;
   1229  1.1  christos   sym_hashes = elf_sym_hashes (abfd);
   1230  1.1  christos   local_got_refcounts = elf_local_got_refcounts (abfd);
   1231  1.1  christos 
   1232  1.1  christos   relend = relocs + sec->reloc_count;
   1233  1.1  christos   for (rel = relocs; rel < relend; rel++)
   1234  1.1  christos     {
   1235  1.1  christos       unsigned long r_symndx;
   1236  1.1  christos       struct elf_link_hash_entry *h = NULL;
   1237  1.1  christos 
   1238  1.1  christos       r_symndx = ELF32_R_SYM (rel->r_info);
   1239  1.1  christos       if (r_symndx >= symtab_hdr->sh_info)
   1240  1.1  christos 	{
   1241  1.1  christos 	  h = sym_hashes[r_symndx - symtab_hdr->sh_info];
   1242  1.1  christos 	  while (h->root.type == bfd_link_hash_indirect
   1243  1.1  christos 		 || h->root.type == bfd_link_hash_warning)
   1244  1.1  christos 	    h = (struct elf_link_hash_entry *) h->root.u.i.link;
   1245  1.1  christos 	}
   1246  1.1  christos 
   1247  1.1  christos       switch (ELF32_R_TYPE (rel->r_info))
   1248  1.1  christos 	{
   1249  1.1  christos 	case R_LM32_16_GOT:
   1250  1.1  christos 	  if (h != NULL)
   1251  1.1  christos 	    {
   1252  1.1  christos 	      if (h->got.refcount > 0)
   1253  1.1  christos 		h->got.refcount--;
   1254  1.1  christos 	    }
   1255  1.1  christos 	  else
   1256  1.1  christos 	    {
   1257  1.1  christos 	      if (local_got_refcounts && local_got_refcounts[r_symndx] > 0)
   1258  1.1  christos 		local_got_refcounts[r_symndx]--;
   1259  1.1  christos 	    }
   1260  1.1  christos 	  break;
   1261  1.1  christos 
   1262  1.1  christos 	default:
   1263  1.1  christos 	  break;
   1264  1.1  christos 	}
   1265  1.1  christos     }
   1266  1.1  christos   return TRUE;
   1267  1.1  christos }
   1268  1.1  christos 
   1269  1.1  christos /* Look through the relocs for a section during the first phase.  */
   1270  1.1  christos 
   1271  1.1  christos static bfd_boolean
   1272  1.1  christos lm32_elf_check_relocs (bfd *abfd,
   1273  1.1  christos                        struct bfd_link_info *info,
   1274  1.1  christos                        asection *sec,
   1275  1.1  christos                        const Elf_Internal_Rela *relocs)
   1276  1.1  christos {
   1277  1.1  christos   Elf_Internal_Shdr *symtab_hdr;
   1278  1.1  christos   struct elf_link_hash_entry **sym_hashes, **sym_hashes_end;
   1279  1.1  christos   const Elf_Internal_Rela *rel;
   1280  1.1  christos   const Elf_Internal_Rela *rel_end;
   1281  1.1  christos   struct elf_lm32_link_hash_table *htab;
   1282  1.1  christos   bfd *dynobj;
   1283  1.1  christos 
   1284  1.1  christos   if (info->relocatable)
   1285  1.1  christos     return TRUE;
   1286  1.1  christos 
   1287  1.1  christos   symtab_hdr = &elf_tdata (abfd)->symtab_hdr;
   1288  1.1  christos   sym_hashes = elf_sym_hashes (abfd);
   1289  1.1  christos   sym_hashes_end = sym_hashes + symtab_hdr->sh_size/sizeof (Elf32_External_Sym);
   1290  1.1  christos   if (!elf_bad_symtab (abfd))
   1291  1.1  christos     sym_hashes_end -= symtab_hdr->sh_info;
   1292  1.1  christos 
   1293  1.1  christos   htab = lm32_elf_hash_table (info);
   1294  1.1  christos   if (htab == NULL)
   1295  1.1  christos     return FALSE;
   1296  1.1  christos 
   1297  1.1  christos   dynobj = htab->root.dynobj;
   1298  1.1  christos 
   1299  1.1  christos   rel_end = relocs + sec->reloc_count;
   1300  1.1  christos   for (rel = relocs; rel < rel_end; rel++)
   1301  1.1  christos     {
   1302  1.1  christos       int r_type;
   1303  1.1  christos       struct elf_link_hash_entry *h;
   1304  1.1  christos       unsigned long r_symndx;
   1305  1.1  christos 
   1306  1.1  christos       r_symndx = ELF32_R_SYM (rel->r_info);
   1307  1.1  christos       r_type = ELF32_R_TYPE (rel->r_info);
   1308  1.1  christos       if (r_symndx < symtab_hdr->sh_info)
   1309  1.1  christos         h = NULL;
   1310  1.1  christos       else
   1311  1.1  christos 	{
   1312  1.1  christos 	  h = sym_hashes[r_symndx - symtab_hdr->sh_info];
   1313  1.1  christos 	  while (h->root.type == bfd_link_hash_indirect
   1314  1.1  christos 		 || h->root.type == bfd_link_hash_warning)
   1315  1.1  christos 	    h = (struct elf_link_hash_entry *) h->root.u.i.link;
   1316  1.1  christos 	}
   1317  1.1  christos 
   1318  1.1  christos       /* Some relocs require a global offset table.  */
   1319  1.1  christos       if (htab->sgot == NULL)
   1320  1.1  christos         {
   1321  1.1  christos           switch (r_type)
   1322  1.1  christos             {
   1323  1.1  christos             case R_LM32_16_GOT:
   1324  1.1  christos             case R_LM32_GOTOFF_HI16:
   1325  1.1  christos             case R_LM32_GOTOFF_LO16:
   1326  1.1  christos               if (dynobj == NULL)
   1327  1.1  christos                 htab->root.dynobj = dynobj = abfd;
   1328  1.1  christos               if (! create_got_section (dynobj, info))
   1329  1.1  christos                 return FALSE;
   1330  1.1  christos               break;
   1331  1.1  christos             }
   1332  1.1  christos         }
   1333  1.1  christos 
   1334  1.1  christos       /* Some relocs require a rofixup table. */
   1335  1.1  christos       if (IS_FDPIC (abfd))
   1336  1.1  christos         {
   1337  1.1  christos           switch (r_type)
   1338  1.1  christos             {
   1339  1.1  christos             case R_LM32_32:
   1340  1.1  christos               /* FDPIC requires a GOT if there is a .rofixup section
   1341  1.1  christos                  (Normal ELF doesn't). */
   1342  1.1  christos               if (dynobj == NULL)
   1343  1.1  christos                 htab->root.dynobj = dynobj = abfd;
   1344  1.1  christos               if (! create_got_section (dynobj, info))
   1345  1.1  christos                 return FALSE;
   1346  1.1  christos               /* Create .rofixup section */
   1347  1.1  christos               if (htab->sfixup32 == NULL)
   1348  1.1  christos                 {
   1349  1.1  christos                   if (! create_rofixup_section (abfd, info))
   1350  1.1  christos                     return FALSE;
   1351  1.1  christos                 }
   1352  1.1  christos               break;
   1353  1.1  christos             case R_LM32_16_GOT:
   1354  1.1  christos             case R_LM32_GOTOFF_HI16:
   1355  1.1  christos             case R_LM32_GOTOFF_LO16:
   1356  1.1  christos               /* Create .rofixup section.  */
   1357  1.1  christos               if (htab->sfixup32 == NULL)
   1358  1.1  christos                 {
   1359  1.1  christos                   if (! create_rofixup_section (abfd, info))
   1360  1.1  christos                     return FALSE;
   1361  1.1  christos                 }
   1362  1.1  christos               break;
   1363  1.1  christos             }
   1364  1.1  christos         }
   1365  1.1  christos 
   1366  1.1  christos       switch (r_type)
   1367  1.1  christos 	{
   1368  1.1  christos 	case R_LM32_16_GOT:
   1369  1.1  christos           if (h != NULL)
   1370  1.1  christos             h->got.refcount += 1;
   1371  1.1  christos           else
   1372  1.1  christos             {
   1373  1.1  christos               bfd_signed_vma *local_got_refcounts;
   1374  1.1  christos 
   1375  1.1  christos               /* This is a global offset table entry for a local symbol.  */
   1376  1.1  christos               local_got_refcounts = elf_local_got_refcounts (abfd);
   1377  1.1  christos               if (local_got_refcounts == NULL)
   1378  1.1  christos                 {
   1379  1.1  christos                   bfd_size_type size;
   1380  1.1  christos 
   1381  1.1  christos                   size = symtab_hdr->sh_info;
   1382  1.1  christos                   size *= sizeof (bfd_signed_vma);
   1383  1.1  christos                   local_got_refcounts = bfd_zalloc (abfd, size);
   1384  1.1  christos                   if (local_got_refcounts == NULL)
   1385  1.1  christos                     return FALSE;
   1386  1.1  christos                   elf_local_got_refcounts (abfd) = local_got_refcounts;
   1387  1.1  christos                 }
   1388  1.1  christos               local_got_refcounts[r_symndx] += 1;
   1389  1.1  christos             }
   1390  1.1  christos           break;
   1391  1.1  christos 
   1392  1.1  christos         /* This relocation describes the C++ object vtable hierarchy.
   1393  1.1  christos            Reconstruct it for later use during GC.  */
   1394  1.1  christos         case R_LM32_GNU_VTINHERIT:
   1395  1.1  christos           if (!bfd_elf_gc_record_vtinherit (abfd, sec, h, rel->r_offset))
   1396  1.1  christos             return FALSE;
   1397  1.1  christos           break;
   1398  1.1  christos 
   1399  1.1  christos         /* This relocation describes which C++ vtable entries are actually
   1400  1.1  christos            used.  Record for later use during GC.  */
   1401  1.1  christos         case R_LM32_GNU_VTENTRY:
   1402  1.1  christos           if (!bfd_elf_gc_record_vtentry (abfd, sec, h, rel->r_addend))
   1403  1.1  christos             return FALSE;
   1404  1.1  christos           break;
   1405  1.1  christos 
   1406  1.1  christos         }
   1407  1.1  christos     }
   1408  1.1  christos 
   1409  1.1  christos   return TRUE;
   1410  1.1  christos }
   1411  1.1  christos 
   1412  1.1  christos /* Finish up the dynamic sections.  */
   1413  1.1  christos 
   1414  1.1  christos static bfd_boolean
   1415  1.1  christos lm32_elf_finish_dynamic_sections (bfd *output_bfd,
   1416  1.1  christos 				  struct bfd_link_info *info)
   1417  1.1  christos {
   1418  1.1  christos   struct elf_lm32_link_hash_table *htab;
   1419  1.1  christos   bfd *dynobj;
   1420  1.1  christos   asection *sdyn;
   1421  1.1  christos   asection *sgot;
   1422  1.1  christos 
   1423  1.1  christos   htab = lm32_elf_hash_table (info);
   1424  1.1  christos   if (htab == NULL)
   1425  1.1  christos     return FALSE;
   1426  1.1  christos 
   1427  1.1  christos   dynobj = htab->root.dynobj;
   1428  1.1  christos 
   1429  1.1  christos   sgot = htab->sgotplt;
   1430  1.1  christos   sdyn = bfd_get_section_by_name (dynobj, ".dynamic");
   1431  1.1  christos 
   1432  1.1  christos   if (htab->root.dynamic_sections_created)
   1433  1.1  christos     {
   1434  1.1  christos       asection *splt;
   1435  1.1  christos       Elf32_External_Dyn *dyncon, *dynconend;
   1436  1.1  christos 
   1437  1.1  christos       BFD_ASSERT (sgot != NULL && sdyn != NULL);
   1438  1.1  christos 
   1439  1.1  christos       dyncon = (Elf32_External_Dyn *) sdyn->contents;
   1440  1.1  christos       dynconend = (Elf32_External_Dyn *) (sdyn->contents + sdyn->size);
   1441  1.1  christos 
   1442  1.1  christos       for (; dyncon < dynconend; dyncon++)
   1443  1.1  christos         {
   1444  1.1  christos           Elf_Internal_Dyn dyn;
   1445  1.1  christos           asection *s;
   1446  1.1  christos 
   1447  1.1  christos           bfd_elf32_swap_dyn_in (dynobj, dyncon, &dyn);
   1448  1.1  christos 
   1449  1.1  christos           switch (dyn.d_tag)
   1450  1.1  christos             {
   1451  1.1  christos             default:
   1452  1.1  christos               break;
   1453  1.1  christos 
   1454  1.1  christos             case DT_PLTGOT:
   1455  1.1  christos               s = htab->sgot->output_section;
   1456  1.1  christos               goto get_vma;
   1457  1.1  christos             case DT_JMPREL:
   1458  1.1  christos               s = htab->srelplt->output_section;
   1459  1.1  christos             get_vma:
   1460  1.1  christos               BFD_ASSERT (s != NULL);
   1461  1.1  christos               dyn.d_un.d_ptr = s->vma;
   1462  1.1  christos               bfd_elf32_swap_dyn_out (output_bfd, &dyn, dyncon);
   1463  1.1  christos               break;
   1464  1.1  christos 
   1465  1.1  christos             case DT_PLTRELSZ:
   1466  1.1  christos               s = htab->srelplt->output_section;
   1467  1.1  christos               BFD_ASSERT (s != NULL);
   1468  1.1  christos 	      dyn.d_un.d_val = s->size;
   1469  1.1  christos               bfd_elf32_swap_dyn_out (output_bfd, &dyn, dyncon);
   1470  1.1  christos               break;
   1471  1.1  christos 
   1472  1.1  christos             case DT_RELASZ:
   1473  1.1  christos               /* My reading of the SVR4 ABI indicates that the
   1474  1.1  christos                  procedure linkage table relocs (DT_JMPREL) should be
   1475  1.1  christos                  included in the overall relocs (DT_RELA).  This is
   1476  1.1  christos                  what Solaris does.  However, UnixWare can not handle
   1477  1.1  christos                  that case.  Therefore, we override the DT_RELASZ entry
   1478  1.1  christos                  here to make it not include the JMPREL relocs.  Since
   1479  1.1  christos                  the linker script arranges for .rela.plt to follow all
   1480  1.1  christos                  other relocation sections, we don't have to worry
   1481  1.1  christos                  about changing the DT_RELA entry.  */
   1482  1.1  christos               if (htab->srelplt != NULL)
   1483  1.1  christos                 {
   1484  1.1  christos                   s = htab->srelplt->output_section;
   1485  1.1  christos 		  dyn.d_un.d_val -= s->size;
   1486  1.1  christos                 }
   1487  1.1  christos               bfd_elf32_swap_dyn_out (output_bfd, &dyn, dyncon);
   1488  1.1  christos               break;
   1489  1.1  christos             }
   1490  1.1  christos         }
   1491  1.1  christos 
   1492  1.1  christos       /* Fill in the first entry in the procedure linkage table.  */
   1493  1.1  christos       splt = htab->splt;
   1494  1.1  christos       if (splt && splt->size > 0)
   1495  1.1  christos         {
   1496  1.1  christos           if (info->shared)
   1497  1.1  christos             {
   1498  1.1  christos               bfd_put_32 (output_bfd, PLT0_PIC_ENTRY_WORD0, splt->contents);
   1499  1.1  christos               bfd_put_32 (output_bfd, PLT0_PIC_ENTRY_WORD1, splt->contents + 4);
   1500  1.1  christos               bfd_put_32 (output_bfd, PLT0_PIC_ENTRY_WORD2, splt->contents + 8);
   1501  1.1  christos               bfd_put_32 (output_bfd, PLT0_PIC_ENTRY_WORD3, splt->contents + 12);
   1502  1.1  christos               bfd_put_32 (output_bfd, PLT0_PIC_ENTRY_WORD4, splt->contents + 16);
   1503  1.1  christos             }
   1504  1.1  christos           else
   1505  1.1  christos             {
   1506  1.1  christos               unsigned long addr;
   1507  1.1  christos               /* addr = .got + 4 */
   1508  1.1  christos               addr = sgot->output_section->vma + sgot->output_offset + 4;
   1509  1.1  christos               bfd_put_32 (output_bfd,
   1510  1.1  christos 			  PLT0_ENTRY_WORD0 | ((addr >> 16) & 0xffff),
   1511  1.1  christos 			  splt->contents);
   1512  1.1  christos               bfd_put_32 (output_bfd,
   1513  1.1  christos 			  PLT0_ENTRY_WORD1 | (addr & 0xffff),
   1514  1.1  christos 			  splt->contents + 4);
   1515  1.1  christos               bfd_put_32 (output_bfd, PLT0_ENTRY_WORD2, splt->contents + 8);
   1516  1.1  christos               bfd_put_32 (output_bfd, PLT0_ENTRY_WORD3, splt->contents + 12);
   1517  1.1  christos               bfd_put_32 (output_bfd, PLT0_ENTRY_WORD4, splt->contents + 16);
   1518  1.1  christos             }
   1519  1.1  christos 
   1520  1.1  christos           elf_section_data (splt->output_section)->this_hdr.sh_entsize =
   1521  1.1  christos             PLT_ENTRY_SIZE;
   1522  1.1  christos         }
   1523  1.1  christos     }
   1524  1.1  christos 
   1525  1.1  christos   /* Fill in the first three entries in the global offset table.  */
   1526  1.1  christos   if (sgot && sgot->size > 0)
   1527  1.1  christos     {
   1528  1.1  christos       if (sdyn == NULL)
   1529  1.1  christos         bfd_put_32 (output_bfd, (bfd_vma) 0, sgot->contents);
   1530  1.1  christos       else
   1531  1.1  christos         bfd_put_32 (output_bfd,
   1532  1.1  christos                     sdyn->output_section->vma + sdyn->output_offset,
   1533  1.1  christos                     sgot->contents);
   1534  1.1  christos       bfd_put_32 (output_bfd, (bfd_vma) 0, sgot->contents + 4);
   1535  1.1  christos       bfd_put_32 (output_bfd, (bfd_vma) 0, sgot->contents + 8);
   1536  1.1  christos 
   1537  1.1  christos       /* FIXME:  This can be null if create_dynamic_sections wasn't called. */
   1538  1.1  christos       if (elf_section_data (sgot->output_section) != NULL)
   1539  1.1  christos         elf_section_data (sgot->output_section)->this_hdr.sh_entsize = 4;
   1540  1.1  christos     }
   1541  1.1  christos 
   1542  1.1  christos   if (lm32fdpic_fixup32_section (info))
   1543  1.1  christos     {
   1544  1.1  christos       struct elf_link_hash_entry *hgot = elf_hash_table (info)->hgot;
   1545  1.1  christos       bfd_vma got_value = hgot->root.u.def.value
   1546  1.1  christos             + hgot->root.u.def.section->output_section->vma
   1547  1.1  christos             + hgot->root.u.def.section->output_offset;
   1548  1.1  christos       struct bfd_link_hash_entry *hend;
   1549  1.1  christos 
   1550  1.1  christos       /* Last entry is pointer to GOT.  */
   1551  1.1  christos       _lm32fdpic_add_rofixup (output_bfd, lm32fdpic_fixup32_section (info), got_value);
   1552  1.1  christos 
   1553  1.1  christos       /* Check we wrote enough entries.  */
   1554  1.1  christos       if (lm32fdpic_fixup32_section (info)->size
   1555  1.1  christos               != (lm32fdpic_fixup32_section (info)->reloc_count * 4))
   1556  1.1  christos         {
   1557  1.1  christos           (*_bfd_error_handler)
   1558  1.1  christos             ("LINKER BUG: .rofixup section size mismatch: size/4 %d != relocs %d",
   1559  1.1  christos             lm32fdpic_fixup32_section (info)->size/4,
   1560  1.1  christos             lm32fdpic_fixup32_section (info)->reloc_count);
   1561  1.1  christos           return FALSE;
   1562  1.1  christos         }
   1563  1.1  christos 
   1564  1.1  christos       hend = bfd_link_hash_lookup (info->hash, "__ROFIXUP_END__",
   1565  1.1  christos               FALSE, FALSE, TRUE);
   1566  1.1  christos       if (hend
   1567  1.1  christos           && (hend->type == bfd_link_hash_defined
   1568  1.1  christos               || hend->type == bfd_link_hash_defweak))
   1569  1.1  christos         {
   1570  1.1  christos           bfd_vma value =
   1571  1.1  christos             lm32fdpic_fixup32_section (info)->output_section->vma
   1572  1.1  christos             + lm32fdpic_fixup32_section (info)->output_offset
   1573  1.1  christos             + lm32fdpic_fixup32_section (info)->size
   1574  1.1  christos             - hend->u.def.section->output_section->vma
   1575  1.1  christos             - hend->u.def.section->output_offset;
   1576  1.1  christos           BFD_ASSERT (hend->u.def.value == value);
   1577  1.1  christos           if (hend->u.def.value != value)
   1578  1.1  christos             {
   1579  1.1  christos               (*_bfd_error_handler)
   1580  1.1  christos                 ("LINKER BUG: .rofixup section hend->u.def.value != value: %ld != %ld", hend->u.def.value, value);
   1581  1.1  christos               return FALSE;
   1582  1.1  christos             }
   1583  1.1  christos         }
   1584  1.1  christos     }
   1585  1.1  christos 
   1586  1.1  christos   return TRUE;
   1587  1.1  christos }
   1588  1.1  christos 
   1589  1.1  christos /* Finish up dynamic symbol handling.  We set the contents of various
   1590  1.1  christos    dynamic sections here.  */
   1591  1.1  christos 
   1592  1.1  christos static bfd_boolean
   1593  1.1  christos lm32_elf_finish_dynamic_symbol (bfd *output_bfd,
   1594  1.1  christos 				struct bfd_link_info *info,
   1595  1.1  christos 				struct elf_link_hash_entry *h,
   1596  1.1  christos 				Elf_Internal_Sym *sym)
   1597  1.1  christos {
   1598  1.1  christos   struct elf_lm32_link_hash_table *htab;
   1599  1.1  christos   bfd_byte *loc;
   1600  1.1  christos 
   1601  1.1  christos   htab = lm32_elf_hash_table (info);
   1602  1.1  christos   if (htab == NULL)
   1603  1.1  christos     return FALSE;
   1604  1.1  christos 
   1605  1.1  christos   if (h->plt.offset != (bfd_vma) -1)
   1606  1.1  christos     {
   1607  1.1  christos       asection *splt;
   1608  1.1  christos       asection *sgot;
   1609  1.1  christos       asection *srela;
   1610  1.1  christos 
   1611  1.1  christos       bfd_vma plt_index;
   1612  1.1  christos       bfd_vma got_offset;
   1613  1.1  christos       Elf_Internal_Rela rela;
   1614  1.1  christos 
   1615  1.1  christos       /* This symbol has an entry in the procedure linkage table.  Set
   1616  1.1  christos          it up.  */
   1617  1.1  christos       BFD_ASSERT (h->dynindx != -1);
   1618  1.1  christos 
   1619  1.1  christos       splt = htab->splt;
   1620  1.1  christos       sgot = htab->sgotplt;
   1621  1.1  christos       srela = htab->srelplt;
   1622  1.1  christos       BFD_ASSERT (splt != NULL && sgot != NULL && srela != NULL);
   1623  1.1  christos 
   1624  1.1  christos       /* Get the index in the procedure linkage table which
   1625  1.1  christos          corresponds to this symbol.  This is the index of this symbol
   1626  1.1  christos          in all the symbols for which we are making plt entries.  The
   1627  1.1  christos          first entry in the procedure linkage table is reserved.  */
   1628  1.1  christos       plt_index = h->plt.offset / PLT_ENTRY_SIZE - 1;
   1629  1.1  christos 
   1630  1.1  christos       /* Get the offset into the .got table of the entry that
   1631  1.1  christos         corresponds to this function.  Each .got entry is 4 bytes.
   1632  1.1  christos         The first three are reserved.  */
   1633  1.1  christos       got_offset = (plt_index + 3) * 4;
   1634  1.1  christos 
   1635  1.1  christos       /* Fill in the entry in the procedure linkage table.  */
   1636  1.1  christos       if (! info->shared)
   1637  1.1  christos         {
   1638  1.1  christos           /* TODO */
   1639  1.1  christos         }
   1640  1.1  christos       else
   1641  1.1  christos         {
   1642  1.1  christos           /* TODO */
   1643  1.1  christos         }
   1644  1.1  christos 
   1645  1.1  christos       /* Fill in the entry in the global offset table.  */
   1646  1.1  christos       bfd_put_32 (output_bfd,
   1647  1.1  christos                   (splt->output_section->vma
   1648  1.1  christos                    + splt->output_offset
   1649  1.1  christos                    + h->plt.offset
   1650  1.1  christos                    + 12), /* same offset */
   1651  1.1  christos                   sgot->contents + got_offset);
   1652  1.1  christos 
   1653  1.1  christos       /* Fill in the entry in the .rela.plt section.  */
   1654  1.1  christos       rela.r_offset = (sgot->output_section->vma
   1655  1.1  christos                        + sgot->output_offset
   1656  1.1  christos                        + got_offset);
   1657  1.1  christos       rela.r_info = ELF32_R_INFO (h->dynindx, R_LM32_JMP_SLOT);
   1658  1.1  christos       rela.r_addend = 0;
   1659  1.1  christos       loc = srela->contents;
   1660  1.1  christos       loc += plt_index * sizeof (Elf32_External_Rela);
   1661  1.1  christos       bfd_elf32_swap_reloca_out (output_bfd, &rela, loc);
   1662  1.1  christos 
   1663  1.1  christos       if (!h->def_regular)
   1664  1.1  christos         {
   1665  1.1  christos           /* Mark the symbol as undefined, rather than as defined in
   1666  1.1  christos              the .plt section.  Leave the value alone.  */
   1667  1.1  christos           sym->st_shndx = SHN_UNDEF;
   1668  1.1  christos         }
   1669  1.1  christos 
   1670  1.1  christos     }
   1671  1.1  christos 
   1672  1.1  christos   if (h->got.offset != (bfd_vma) -1)
   1673  1.1  christos     {
   1674  1.1  christos       asection *sgot;
   1675  1.1  christos       asection *srela;
   1676  1.1  christos       Elf_Internal_Rela rela;
   1677  1.1  christos 
   1678  1.1  christos       /* This symbol has an entry in the global offset table.  Set it
   1679  1.1  christos          up.  */
   1680  1.1  christos       sgot = htab->sgot;
   1681  1.1  christos       srela = htab->srelgot;
   1682  1.1  christos       BFD_ASSERT (sgot != NULL && srela != NULL);
   1683  1.1  christos 
   1684  1.1  christos       rela.r_offset = (sgot->output_section->vma
   1685  1.1  christos                        + sgot->output_offset
   1686  1.1  christos                        + (h->got.offset &~ 1));
   1687  1.1  christos 
   1688  1.1  christos       /* If this is a -Bsymbolic link, and the symbol is defined
   1689  1.1  christos          locally, we just want to emit a RELATIVE reloc.  Likewise if
   1690  1.1  christos          the symbol was forced to be local because of a version file.
   1691  1.1  christos          The entry in the global offset table will already have been
   1692  1.1  christos          initialized in the relocate_section function.  */
   1693  1.1  christos       if (info->shared
   1694  1.1  christos           && (info->symbolic
   1695  1.1  christos 	      || h->dynindx == -1
   1696  1.1  christos 	      || h->forced_local)
   1697  1.1  christos           && h->def_regular)
   1698  1.1  christos         {
   1699  1.1  christos           rela.r_info = ELF32_R_INFO (0, R_LM32_RELATIVE);
   1700  1.1  christos           rela.r_addend = (h->root.u.def.value
   1701  1.1  christos                            + h->root.u.def.section->output_section->vma
   1702  1.1  christos                            + h->root.u.def.section->output_offset);
   1703  1.1  christos         }
   1704  1.1  christos       else
   1705  1.1  christos         {
   1706  1.1  christos 	  BFD_ASSERT ((h->got.offset & 1) == 0);
   1707  1.1  christos           bfd_put_32 (output_bfd, (bfd_vma) 0, sgot->contents + h->got.offset);
   1708  1.1  christos           rela.r_info = ELF32_R_INFO (h->dynindx, R_LM32_GLOB_DAT);
   1709  1.1  christos           rela.r_addend = 0;
   1710  1.1  christos         }
   1711  1.1  christos 
   1712  1.1  christos       loc = srela->contents;
   1713  1.1  christos       loc += srela->reloc_count * sizeof (Elf32_External_Rela);
   1714  1.1  christos       bfd_elf32_swap_reloca_out (output_bfd, &rela, loc);
   1715  1.1  christos       ++srela->reloc_count;
   1716  1.1  christos     }
   1717  1.1  christos 
   1718  1.1  christos   if (h->needs_copy)
   1719  1.1  christos     {
   1720  1.1  christos       asection *s;
   1721  1.1  christos       Elf_Internal_Rela rela;
   1722  1.1  christos 
   1723  1.1  christos       /* This symbols needs a copy reloc.  Set it up.  */
   1724  1.1  christos       BFD_ASSERT (h->dynindx != -1
   1725  1.1  christos                   && (h->root.type == bfd_link_hash_defined
   1726  1.1  christos                       || h->root.type == bfd_link_hash_defweak));
   1727  1.1  christos 
   1728  1.1  christos       s = bfd_get_section_by_name (h->root.u.def.section->owner,
   1729  1.1  christos                                    ".rela.bss");
   1730  1.1  christos       BFD_ASSERT (s != NULL);
   1731  1.1  christos 
   1732  1.1  christos       rela.r_offset = (h->root.u.def.value
   1733  1.1  christos                        + h->root.u.def.section->output_section->vma
   1734  1.1  christos                        + h->root.u.def.section->output_offset);
   1735  1.1  christos       rela.r_info = ELF32_R_INFO (h->dynindx, R_LM32_COPY);
   1736  1.1  christos       rela.r_addend = 0;
   1737  1.1  christos       loc = s->contents;
   1738  1.1  christos       loc += s->reloc_count * sizeof (Elf32_External_Rela);
   1739  1.1  christos       bfd_elf32_swap_reloca_out (output_bfd, &rela, loc);
   1740  1.1  christos       ++s->reloc_count;
   1741  1.1  christos     }
   1742  1.1  christos 
   1743  1.1  christos   /* Mark some specially defined symbols as absolute.  */
   1744  1.1  christos   if (strcmp (h->root.root.string, "_DYNAMIC") == 0
   1745  1.1  christos       || h == htab->root.hgot)
   1746  1.1  christos     sym->st_shndx = SHN_ABS;
   1747  1.1  christos 
   1748  1.1  christos   return TRUE;
   1749  1.1  christos }
   1750  1.1  christos 
   1751  1.1  christos static enum elf_reloc_type_class
   1752  1.1  christos lm32_elf_reloc_type_class (const Elf_Internal_Rela *rela)
   1753  1.1  christos {
   1754  1.1  christos   switch ((int) ELF32_R_TYPE (rela->r_info))
   1755  1.1  christos     {
   1756  1.1  christos     case R_LM32_RELATIVE:  return reloc_class_relative;
   1757  1.1  christos     case R_LM32_JMP_SLOT:  return reloc_class_plt;
   1758  1.1  christos     case R_LM32_COPY:      return reloc_class_copy;
   1759  1.1  christos     default:      	   return reloc_class_normal;
   1760  1.1  christos     }
   1761  1.1  christos }
   1762  1.1  christos 
   1763  1.1  christos /* Adjust a symbol defined by a dynamic object and referenced by a
   1764  1.1  christos    regular object.  The current definition is in some section of the
   1765  1.1  christos    dynamic object, but we're not including those sections.  We have to
   1766  1.1  christos    change the definition to something the rest of the link can
   1767  1.1  christos    understand.  */
   1768  1.1  christos 
   1769  1.1  christos static bfd_boolean
   1770  1.1  christos lm32_elf_adjust_dynamic_symbol (struct bfd_link_info *info,
   1771  1.1  christos 				struct elf_link_hash_entry *h)
   1772  1.1  christos {
   1773  1.1  christos   struct elf_lm32_link_hash_table *htab;
   1774  1.1  christos   struct elf_lm32_link_hash_entry *eh;
   1775  1.1  christos   struct elf_lm32_dyn_relocs *p;
   1776  1.1  christos   bfd *dynobj;
   1777  1.1  christos   asection *s;
   1778  1.1  christos 
   1779  1.1  christos   dynobj = elf_hash_table (info)->dynobj;
   1780  1.1  christos 
   1781  1.1  christos   /* Make sure we know what is going on here.  */
   1782  1.1  christos   BFD_ASSERT (dynobj != NULL
   1783  1.1  christos               && (h->needs_plt
   1784  1.1  christos                   || h->u.weakdef != NULL
   1785  1.1  christos                   || (h->def_dynamic
   1786  1.1  christos                       && h->ref_regular
   1787  1.1  christos                       && !h->def_regular)));
   1788  1.1  christos 
   1789  1.1  christos   /* If this is a function, put it in the procedure linkage table.  We
   1790  1.1  christos      will fill in the contents of the procedure linkage table later,
   1791  1.1  christos      when we know the address of the .got section.  */
   1792  1.1  christos   if (h->type == STT_FUNC
   1793  1.1  christos       || h->needs_plt)
   1794  1.1  christos     {
   1795  1.1  christos       if (! info->shared
   1796  1.1  christos           && !h->def_dynamic
   1797  1.1  christos           && !h->ref_dynamic
   1798  1.1  christos 	  && h->root.type != bfd_link_hash_undefweak
   1799  1.1  christos 	  && h->root.type != bfd_link_hash_undefined)
   1800  1.1  christos         {
   1801  1.1  christos           /* This case can occur if we saw a PLT reloc in an input
   1802  1.1  christos              file, but the symbol was never referred to by a dynamic
   1803  1.1  christos              object.  In such a case, we don't actually need to build
   1804  1.1  christos              a procedure linkage table, and we can just do a PCREL
   1805  1.1  christos              reloc instead.  */
   1806  1.1  christos           h->plt.offset = (bfd_vma) -1;
   1807  1.1  christos           h->needs_plt = 0;
   1808  1.1  christos         }
   1809  1.1  christos 
   1810  1.1  christos       return TRUE;
   1811  1.1  christos     }
   1812  1.1  christos   else
   1813  1.1  christos     h->plt.offset = (bfd_vma) -1;
   1814  1.1  christos 
   1815  1.1  christos   /* If this is a weak symbol, and there is a real definition, the
   1816  1.1  christos      processor independent code will have arranged for us to see the
   1817  1.1  christos      real definition first, and we can just use the same value.  */
   1818  1.1  christos   if (h->u.weakdef != NULL)
   1819  1.1  christos     {
   1820  1.1  christos       BFD_ASSERT (h->u.weakdef->root.type == bfd_link_hash_defined
   1821  1.1  christos                   || h->u.weakdef->root.type == bfd_link_hash_defweak);
   1822  1.1  christos       h->root.u.def.section = h->u.weakdef->root.u.def.section;
   1823  1.1  christos       h->root.u.def.value = h->u.weakdef->root.u.def.value;
   1824  1.1  christos       return TRUE;
   1825  1.1  christos     }
   1826  1.1  christos 
   1827  1.1  christos   /* This is a reference to a symbol defined by a dynamic object which
   1828  1.1  christos      is not a function.  */
   1829  1.1  christos 
   1830  1.1  christos   /* If we are creating a shared library, we must presume that the
   1831  1.1  christos      only references to the symbol are via the global offset table.
   1832  1.1  christos      For such cases we need not do anything here; the relocations will
   1833  1.1  christos      be handled correctly by relocate_section.  */
   1834  1.1  christos   if (info->shared)
   1835  1.1  christos     return TRUE;
   1836  1.1  christos 
   1837  1.1  christos   /* If there are no references to this symbol that do not use the
   1838  1.1  christos      GOT, we don't need to generate a copy reloc.  */
   1839  1.1  christos   if (!h->non_got_ref)
   1840  1.1  christos     return TRUE;
   1841  1.1  christos 
   1842  1.1  christos   /* If -z nocopyreloc was given, we won't generate them either.  */
   1843  1.1  christos   if (info->nocopyreloc)
   1844  1.1  christos     {
   1845  1.1  christos       h->non_got_ref = 0;
   1846  1.1  christos       return TRUE;
   1847  1.1  christos     }
   1848  1.1  christos 
   1849  1.1  christos   eh = (struct elf_lm32_link_hash_entry *) h;
   1850  1.1  christos   for (p = eh->dyn_relocs; p != NULL; p = p->next)
   1851  1.1  christos     {
   1852  1.1  christos       s = p->sec->output_section;
   1853  1.1  christos       if (s != NULL && (s->flags & (SEC_READONLY | SEC_HAS_CONTENTS)) != 0)
   1854  1.1  christos         break;
   1855  1.1  christos     }
   1856  1.1  christos 
   1857  1.1  christos   /* If we didn't find any dynamic relocs in sections which needs the
   1858  1.1  christos      copy reloc, then we'll be keeping the dynamic relocs and avoiding
   1859  1.1  christos      the copy reloc.  */
   1860  1.1  christos   if (p == NULL)
   1861  1.1  christos     {
   1862  1.1  christos       h->non_got_ref = 0;
   1863  1.1  christos       return TRUE;
   1864  1.1  christos     }
   1865  1.1  christos 
   1866  1.1  christos   if (h->size == 0)
   1867  1.1  christos     {
   1868  1.1  christos       (*_bfd_error_handler) (_("dynamic variable `%s' is zero size"),
   1869  1.1  christos 			     h->root.root.string);
   1870  1.1  christos       return TRUE;
   1871  1.1  christos     }
   1872  1.1  christos 
   1873  1.1  christos   /* We must allocate the symbol in our .dynbss section, which will
   1874  1.1  christos      become part of the .bss section of the executable.  There will be
   1875  1.1  christos      an entry for this symbol in the .dynsym section.  The dynamic
   1876  1.1  christos      object will contain position independent code, so all references
   1877  1.1  christos      from the dynamic object to this symbol will go through the global
   1878  1.1  christos      offset table.  The dynamic linker will use the .dynsym entry to
   1879  1.1  christos      determine the address it must put in the global offset table, so
   1880  1.1  christos      both the dynamic object and the regular object will refer to the
   1881  1.1  christos      same memory location for the variable.  */
   1882  1.1  christos 
   1883  1.1  christos   htab = lm32_elf_hash_table (info);
   1884  1.1  christos   if (htab == NULL)
   1885  1.1  christos     return FALSE;
   1886  1.1  christos 
   1887  1.1  christos   s = htab->sdynbss;
   1888  1.1  christos   BFD_ASSERT (s != NULL);
   1889  1.1  christos 
   1890  1.1  christos   /* We must generate a R_LM32_COPY reloc to tell the dynamic linker
   1891  1.1  christos      to copy the initial value out of the dynamic object and into the
   1892  1.1  christos      runtime process image.  We need to remember the offset into the
   1893  1.1  christos      .rela.bss section we are going to use.  */
   1894  1.1  christos   if ((h->root.u.def.section->flags & SEC_ALLOC) != 0)
   1895  1.1  christos     {
   1896  1.1  christos       asection *srel;
   1897  1.1  christos 
   1898  1.1  christos       srel = htab->srelbss;
   1899  1.1  christos       BFD_ASSERT (srel != NULL);
   1900  1.1  christos       srel->size += sizeof (Elf32_External_Rela);
   1901  1.1  christos       h->needs_copy = 1;
   1902  1.1  christos     }
   1903  1.1  christos 
   1904  1.1  christos   return _bfd_elf_adjust_dynamic_copy (h, s);
   1905  1.1  christos }
   1906  1.1  christos 
   1907  1.1  christos /* Allocate space in .plt, .got and associated reloc sections for
   1908  1.1  christos    dynamic relocs.  */
   1909  1.1  christos 
   1910  1.1  christos static bfd_boolean
   1911  1.1  christos allocate_dynrelocs (struct elf_link_hash_entry *h, void * inf)
   1912  1.1  christos {
   1913  1.1  christos   struct bfd_link_info *info;
   1914  1.1  christos   struct elf_lm32_link_hash_table *htab;
   1915  1.1  christos   struct elf_lm32_link_hash_entry *eh;
   1916  1.1  christos   struct elf_lm32_dyn_relocs *p;
   1917  1.1  christos 
   1918  1.1  christos   if (h->root.type == bfd_link_hash_indirect)
   1919  1.1  christos     return TRUE;
   1920  1.1  christos 
   1921  1.1  christos   if (h->root.type == bfd_link_hash_warning)
   1922  1.1  christos     /* When warning symbols are created, they **replace** the "real"
   1923  1.1  christos        entry in the hash table, thus we never get to see the real
   1924  1.1  christos        symbol in a hash traversal.  So look at it now.  */
   1925  1.1  christos     h = (struct elf_link_hash_entry *) h->root.u.i.link;
   1926  1.1  christos 
   1927  1.1  christos   info = (struct bfd_link_info *) inf;
   1928  1.1  christos   htab = lm32_elf_hash_table (info);
   1929  1.1  christos   if (htab == NULL)
   1930  1.1  christos     return FALSE;
   1931  1.1  christos 
   1932  1.1  christos   eh = (struct elf_lm32_link_hash_entry *) h;
   1933  1.1  christos 
   1934  1.1  christos   if (htab->root.dynamic_sections_created
   1935  1.1  christos       && h->plt.refcount > 0)
   1936  1.1  christos     {
   1937  1.1  christos       /* Make sure this symbol is output as a dynamic symbol.
   1938  1.1  christos          Undefined weak syms won't yet be marked as dynamic.  */
   1939  1.1  christos       if (h->dynindx == -1
   1940  1.1  christos           && !h->forced_local)
   1941  1.1  christos         {
   1942  1.1  christos           if (! bfd_elf_link_record_dynamic_symbol (info, h))
   1943  1.1  christos             return FALSE;
   1944  1.1  christos         }
   1945  1.1  christos 
   1946  1.1  christos       if (WILL_CALL_FINISH_DYNAMIC_SYMBOL (1, info->shared, h))
   1947  1.1  christos         {
   1948  1.1  christos           asection *s = htab->splt;
   1949  1.1  christos 
   1950  1.1  christos           /* If this is the first .plt entry, make room for the special
   1951  1.1  christos              first entry.  */
   1952  1.1  christos           if (s->size == 0)
   1953  1.1  christos             s->size += PLT_ENTRY_SIZE;
   1954  1.1  christos 
   1955  1.1  christos           h->plt.offset = s->size;
   1956  1.1  christos 
   1957  1.1  christos           /* If this symbol is not defined in a regular file, and we are
   1958  1.1  christos              not generating a shared library, then set the symbol to this
   1959  1.1  christos              location in the .plt.  This is required to make function
   1960  1.1  christos              pointers compare as equal between the normal executable and
   1961  1.1  christos              the shared library.  */
   1962  1.1  christos           if (! info->shared
   1963  1.1  christos               && !h->def_regular)
   1964  1.1  christos             {
   1965  1.1  christos               h->root.u.def.section = s;
   1966  1.1  christos               h->root.u.def.value = h->plt.offset;
   1967  1.1  christos             }
   1968  1.1  christos 
   1969  1.1  christos           /* Make room for this entry.  */
   1970  1.1  christos           s->size += PLT_ENTRY_SIZE;
   1971  1.1  christos 
   1972  1.1  christos           /* We also need to make an entry in the .got.plt section, which
   1973  1.1  christos              will be placed in the .got section by the linker script.  */
   1974  1.1  christos           htab->sgotplt->size += 4;
   1975  1.1  christos 
   1976  1.1  christos           /* We also need to make an entry in the .rel.plt section.  */
   1977  1.1  christos           htab->srelplt->size += sizeof (Elf32_External_Rela);
   1978  1.1  christos         }
   1979  1.1  christos       else
   1980  1.1  christos         {
   1981  1.1  christos           h->plt.offset = (bfd_vma) -1;
   1982  1.1  christos           h->needs_plt = 0;
   1983  1.1  christos         }
   1984  1.1  christos     }
   1985  1.1  christos   else
   1986  1.1  christos     {
   1987  1.1  christos       h->plt.offset = (bfd_vma) -1;
   1988  1.1  christos       h->needs_plt = 0;
   1989  1.1  christos     }
   1990  1.1  christos 
   1991  1.1  christos   if (h->got.refcount > 0)
   1992  1.1  christos     {
   1993  1.1  christos       asection *s;
   1994  1.1  christos       bfd_boolean dyn;
   1995  1.1  christos 
   1996  1.1  christos       /* Make sure this symbol is output as a dynamic symbol.
   1997  1.1  christos          Undefined weak syms won't yet be marked as dynamic.  */
   1998  1.1  christos       if (h->dynindx == -1
   1999  1.1  christos           && !h->forced_local)
   2000  1.1  christos         {
   2001  1.1  christos           if (! bfd_elf_link_record_dynamic_symbol (info, h))
   2002  1.1  christos             return FALSE;
   2003  1.1  christos         }
   2004  1.1  christos 
   2005  1.1  christos       s = htab->sgot;
   2006  1.1  christos 
   2007  1.1  christos       h->got.offset = s->size;
   2008  1.1  christos       s->size += 4;
   2009  1.1  christos       dyn = htab->root.dynamic_sections_created;
   2010  1.1  christos       if (WILL_CALL_FINISH_DYNAMIC_SYMBOL (dyn, info->shared, h))
   2011  1.1  christos         htab->srelgot->size += sizeof (Elf32_External_Rela);
   2012  1.1  christos     }
   2013  1.1  christos   else
   2014  1.1  christos     h->got.offset = (bfd_vma) -1;
   2015  1.1  christos 
   2016  1.1  christos   if (eh->dyn_relocs == NULL)
   2017  1.1  christos     return TRUE;
   2018  1.1  christos 
   2019  1.1  christos   /* In the shared -Bsymbolic case, discard space allocated for
   2020  1.1  christos      dynamic pc-relative relocs against symbols which turn out to be
   2021  1.1  christos      defined in regular objects.  For the normal shared case, discard
   2022  1.1  christos      space for pc-relative relocs that have become local due to symbol
   2023  1.1  christos      visibility changes.  */
   2024  1.1  christos 
   2025  1.1  christos   if (info->shared)
   2026  1.1  christos     {
   2027  1.1  christos       if (h->def_regular
   2028  1.1  christos           && (h->forced_local
   2029  1.1  christos               || info->symbolic))
   2030  1.1  christos         {
   2031  1.1  christos           struct elf_lm32_dyn_relocs **pp;
   2032  1.1  christos 
   2033  1.1  christos           for (pp = &eh->dyn_relocs; (p = *pp) != NULL;)
   2034  1.1  christos             {
   2035  1.1  christos               p->count -= p->pc_count;
   2036  1.1  christos               p->pc_count = 0;
   2037  1.1  christos               if (p->count == 0)
   2038  1.1  christos                 *pp = p->next;
   2039  1.1  christos               else
   2040  1.1  christos                 pp = &p->next;
   2041  1.1  christos             }
   2042  1.1  christos         }
   2043  1.1  christos 
   2044  1.1  christos       /* Also discard relocs on undefined weak syms with non-default
   2045  1.1  christos 	 visibility.  */
   2046  1.1  christos       if (eh->dyn_relocs != NULL
   2047  1.1  christos 	  && h->root.type == bfd_link_hash_undefweak)
   2048  1.1  christos 	{
   2049  1.1  christos 	  if (ELF_ST_VISIBILITY (h->other) != STV_DEFAULT)
   2050  1.1  christos 	    eh->dyn_relocs = NULL;
   2051  1.1  christos 
   2052  1.1  christos 	  /* Make sure undefined weak symbols are output as a dynamic
   2053  1.1  christos 	     symbol in PIEs.  */
   2054  1.1  christos 	  else if (h->dynindx == -1
   2055  1.1  christos 		   && !h->forced_local)
   2056  1.1  christos 	    {
   2057  1.1  christos 	      if (! bfd_elf_link_record_dynamic_symbol (info, h))
   2058  1.1  christos 		return FALSE;
   2059  1.1  christos 	    }
   2060  1.1  christos 	}
   2061  1.1  christos     }
   2062  1.1  christos   else
   2063  1.1  christos     {
   2064  1.1  christos       /* For the non-shared case, discard space for relocs against
   2065  1.1  christos          symbols which turn out to need copy relocs or are not
   2066  1.1  christos          dynamic.  */
   2067  1.1  christos 
   2068  1.1  christos       if (!h->non_got_ref
   2069  1.1  christos           && ((h->def_dynamic
   2070  1.1  christos                && !h->def_regular)
   2071  1.1  christos               || (htab->root.dynamic_sections_created
   2072  1.1  christos                   && (h->root.type == bfd_link_hash_undefweak
   2073  1.1  christos                       || h->root.type == bfd_link_hash_undefined))))
   2074  1.1  christos         {
   2075  1.1  christos           /* Make sure this symbol is output as a dynamic symbol.
   2076  1.1  christos              Undefined weak syms won't yet be marked as dynamic.  */
   2077  1.1  christos           if (h->dynindx == -1
   2078  1.1  christos               && !h->forced_local)
   2079  1.1  christos             {
   2080  1.1  christos               if (! bfd_elf_link_record_dynamic_symbol (info, h))
   2081  1.1  christos                 return FALSE;
   2082  1.1  christos             }
   2083  1.1  christos 
   2084  1.1  christos           /* If that succeeded, we know we'll be keeping all the
   2085  1.1  christos              relocs.  */
   2086  1.1  christos           if (h->dynindx != -1)
   2087  1.1  christos             goto keep;
   2088  1.1  christos         }
   2089  1.1  christos 
   2090  1.1  christos       eh->dyn_relocs = NULL;
   2091  1.1  christos 
   2092  1.1  christos     keep: ;
   2093  1.1  christos     }
   2094  1.1  christos 
   2095  1.1  christos   /* Finally, allocate space.  */
   2096  1.1  christos   for (p = eh->dyn_relocs; p != NULL; p = p->next)
   2097  1.1  christos     {
   2098  1.1  christos       asection *sreloc = elf_section_data (p->sec)->sreloc;
   2099  1.1  christos       sreloc->size += p->count * sizeof (Elf32_External_Rela);
   2100  1.1  christos     }
   2101  1.1  christos 
   2102  1.1  christos   return TRUE;
   2103  1.1  christos }
   2104  1.1  christos 
   2105  1.1  christos /* Find any dynamic relocs that apply to read-only sections.  */
   2106  1.1  christos 
   2107  1.1  christos static bfd_boolean
   2108  1.1  christos readonly_dynrelocs (struct elf_link_hash_entry *h, void * inf)
   2109  1.1  christos {
   2110  1.1  christos   struct elf_lm32_link_hash_entry *eh;
   2111  1.1  christos   struct elf_lm32_dyn_relocs *p;
   2112  1.1  christos 
   2113  1.1  christos   if (h->root.type == bfd_link_hash_warning)
   2114  1.1  christos     h = (struct elf_link_hash_entry *) h->root.u.i.link;
   2115  1.1  christos 
   2116  1.1  christos   eh = (struct elf_lm32_link_hash_entry *) h;
   2117  1.1  christos   for (p = eh->dyn_relocs; p != NULL; p = p->next)
   2118  1.1  christos     {
   2119  1.1  christos       asection *s = p->sec->output_section;
   2120  1.1  christos 
   2121  1.1  christos       if (s != NULL && (s->flags & SEC_READONLY) != 0)
   2122  1.1  christos         {
   2123  1.1  christos           struct bfd_link_info *info = (struct bfd_link_info *) inf;
   2124  1.1  christos 
   2125  1.1  christos           info->flags |= DF_TEXTREL;
   2126  1.1  christos 
   2127  1.1  christos           /* Not an error, just cut short the traversal.  */
   2128  1.1  christos           return FALSE;
   2129  1.1  christos         }
   2130  1.1  christos     }
   2131  1.1  christos   return TRUE;
   2132  1.1  christos }
   2133  1.1  christos 
   2134  1.1  christos /* Set the sizes of the dynamic sections.  */
   2135  1.1  christos 
   2136  1.1  christos static bfd_boolean
   2137  1.1  christos lm32_elf_size_dynamic_sections (bfd *output_bfd,
   2138  1.1  christos                                 struct bfd_link_info *info)
   2139  1.1  christos {
   2140  1.1  christos   struct elf_lm32_link_hash_table *htab;
   2141  1.1  christos   bfd *dynobj;
   2142  1.1  christos   asection *s;
   2143  1.1  christos   bfd_boolean relocs;
   2144  1.1  christos   bfd *ibfd;
   2145  1.1  christos 
   2146  1.1  christos   htab = lm32_elf_hash_table (info);
   2147  1.1  christos   if (htab == NULL)
   2148  1.1  christos     return FALSE;
   2149  1.1  christos 
   2150  1.1  christos   dynobj = htab->root.dynobj;
   2151  1.1  christos   BFD_ASSERT (dynobj != NULL);
   2152  1.1  christos 
   2153  1.1  christos   if (htab->root.dynamic_sections_created)
   2154  1.1  christos     {
   2155  1.1  christos       /* Set the contents of the .interp section to the interpreter.  */
   2156  1.1  christos       if (info->executable)
   2157  1.1  christos 	{
   2158  1.1  christos 	  s = bfd_get_section_by_name (dynobj, ".interp");
   2159  1.1  christos 	  BFD_ASSERT (s != NULL);
   2160  1.1  christos 	  s->size = sizeof ELF_DYNAMIC_INTERPRETER;
   2161  1.1  christos 	  s->contents = (unsigned char *) ELF_DYNAMIC_INTERPRETER;
   2162  1.1  christos 	}
   2163  1.1  christos     }
   2164  1.1  christos 
   2165  1.1  christos   /* Set up .got offsets for local syms, and space for local dynamic
   2166  1.1  christos      relocs.  */
   2167  1.1  christos   for (ibfd = info->input_bfds; ibfd != NULL; ibfd = ibfd->link_next)
   2168  1.1  christos     {
   2169  1.1  christos       bfd_signed_vma *local_got;
   2170  1.1  christos       bfd_signed_vma *end_local_got;
   2171  1.1  christos       bfd_size_type locsymcount;
   2172  1.1  christos       Elf_Internal_Shdr *symtab_hdr;
   2173  1.1  christos       asection *srel;
   2174  1.1  christos 
   2175  1.1  christos       if (bfd_get_flavour (ibfd) != bfd_target_elf_flavour)
   2176  1.1  christos         continue;
   2177  1.1  christos 
   2178  1.1  christos       for (s = ibfd->sections; s != NULL; s = s->next)
   2179  1.1  christos         {
   2180  1.1  christos           struct elf_lm32_dyn_relocs *p;
   2181  1.1  christos 
   2182  1.1  christos           for (p = ((struct elf_lm32_dyn_relocs *)
   2183  1.1  christos                     elf_section_data (s)->local_dynrel);
   2184  1.1  christos                p != NULL;
   2185  1.1  christos                p = p->next)
   2186  1.1  christos             {
   2187  1.1  christos               if (! bfd_is_abs_section (p->sec)
   2188  1.1  christos                   && bfd_is_abs_section (p->sec->output_section))
   2189  1.1  christos                 {
   2190  1.1  christos                   /* Input section has been discarded, either because
   2191  1.1  christos                      it is a copy of a linkonce section or due to
   2192  1.1  christos                      linker script /DISCARD/, so we'll be discarding
   2193  1.1  christos                      the relocs too.  */
   2194  1.1  christos                 }
   2195  1.1  christos               else if (p->count != 0)
   2196  1.1  christos                 {
   2197  1.1  christos                   srel = elf_section_data (p->sec)->sreloc;
   2198  1.1  christos                   srel->size += p->count * sizeof (Elf32_External_Rela);
   2199  1.1  christos                   if ((p->sec->output_section->flags & SEC_READONLY) != 0)
   2200  1.1  christos                     info->flags |= DF_TEXTREL;
   2201  1.1  christos                 }
   2202  1.1  christos             }
   2203  1.1  christos         }
   2204  1.1  christos 
   2205  1.1  christos       local_got = elf_local_got_refcounts (ibfd);
   2206  1.1  christos       if (!local_got)
   2207  1.1  christos         continue;
   2208  1.1  christos 
   2209  1.1  christos       symtab_hdr = &elf_tdata (ibfd)->symtab_hdr;
   2210  1.1  christos       locsymcount = symtab_hdr->sh_info;
   2211  1.1  christos       end_local_got = local_got + locsymcount;
   2212  1.1  christos       s = htab->sgot;
   2213  1.1  christos       srel = htab->srelgot;
   2214  1.1  christos       for (; local_got < end_local_got; ++local_got)
   2215  1.1  christos         {
   2216  1.1  christos           if (*local_got > 0)
   2217  1.1  christos             {
   2218  1.1  christos               *local_got = s->size;
   2219  1.1  christos               s->size += 4;
   2220  1.1  christos               if (info->shared)
   2221  1.1  christos                 srel->size += sizeof (Elf32_External_Rela);
   2222  1.1  christos             }
   2223  1.1  christos           else
   2224  1.1  christos             *local_got = (bfd_vma) -1;
   2225  1.1  christos         }
   2226  1.1  christos     }
   2227  1.1  christos 
   2228  1.1  christos   /* Allocate global sym .plt and .got entries, and space for global
   2229  1.1  christos      sym dynamic relocs.  */
   2230  1.1  christos   elf_link_hash_traverse (&htab->root, allocate_dynrelocs, info);
   2231  1.1  christos 
   2232  1.1  christos   /* We now have determined the sizes of the various dynamic sections.
   2233  1.1  christos      Allocate memory for them.  */
   2234  1.1  christos   relocs = FALSE;
   2235  1.1  christos   for (s = dynobj->sections; s != NULL; s = s->next)
   2236  1.1  christos     {
   2237  1.1  christos       if ((s->flags & SEC_LINKER_CREATED) == 0)
   2238  1.1  christos         continue;
   2239  1.1  christos 
   2240  1.1  christos       if (s == htab->splt
   2241  1.1  christos           || s == htab->sgot
   2242  1.1  christos           || s == htab->sgotplt
   2243  1.1  christos 	  || s == htab->sdynbss)
   2244  1.1  christos         {
   2245  1.1  christos           /* Strip this section if we don't need it; see the
   2246  1.1  christos              comment below.  */
   2247  1.1  christos         }
   2248  1.1  christos       else if (CONST_STRNEQ (bfd_get_section_name (dynobj, s), ".rela"))
   2249  1.1  christos         {
   2250  1.1  christos           if (s->size != 0 && s != htab->srelplt)
   2251  1.1  christos             relocs = TRUE;
   2252  1.1  christos 
   2253  1.1  christos           /* We use the reloc_count field as a counter if we need
   2254  1.1  christos              to copy relocs into the output file.  */
   2255  1.1  christos           s->reloc_count = 0;
   2256  1.1  christos         }
   2257  1.1  christos       else
   2258  1.1  christos 	/* It's not one of our sections, so don't allocate space.  */
   2259  1.1  christos 	continue;
   2260  1.1  christos 
   2261  1.1  christos       if (s->size == 0)
   2262  1.1  christos         {
   2263  1.1  christos           /* If we don't need this section, strip it from the
   2264  1.1  christos              output file.  This is mostly to handle .rela.bss and
   2265  1.1  christos              .rela.plt.  We must create both sections in
   2266  1.1  christos              create_dynamic_sections, because they must be created
   2267  1.1  christos              before the linker maps input sections to output
   2268  1.1  christos              sections.  The linker does that before
   2269  1.1  christos              adjust_dynamic_symbol is called, and it is that
   2270  1.1  christos              function which decides whether anything needs to go
   2271  1.1  christos              into these sections.  */
   2272  1.1  christos           s->flags |= SEC_EXCLUDE;
   2273  1.1  christos           continue;
   2274  1.1  christos         }
   2275  1.1  christos 
   2276  1.1  christos       if ((s->flags & SEC_HAS_CONTENTS) == 0)
   2277  1.1  christos 	continue;
   2278  1.1  christos 
   2279  1.1  christos       /* Allocate memory for the section contents.  We use bfd_zalloc
   2280  1.1  christos          here in case unused entries are not reclaimed before the
   2281  1.1  christos          section's contents are written out.  This should not happen,
   2282  1.1  christos          but this way if it does, we get a R_LM32_NONE reloc instead
   2283  1.1  christos          of garbage.  */
   2284  1.1  christos       s->contents = bfd_zalloc (dynobj, s->size);
   2285  1.1  christos       if (s->contents == NULL)
   2286  1.1  christos         return FALSE;
   2287  1.1  christos     }
   2288  1.1  christos 
   2289  1.1  christos   if (htab->root.dynamic_sections_created)
   2290  1.1  christos     {
   2291  1.1  christos       /* Add some entries to the .dynamic section.  We fill in the
   2292  1.1  christos 	 values later, in lm32_elf_finish_dynamic_sections, but we
   2293  1.1  christos 	 must add the entries now so that we get the correct size for
   2294  1.1  christos 	 the .dynamic section.  The DT_DEBUG entry is filled in by the
   2295  1.1  christos 	 dynamic linker and used by the debugger.  */
   2296  1.1  christos #define add_dynamic_entry(TAG, VAL) \
   2297  1.1  christos   _bfd_elf_add_dynamic_entry (info, TAG, VAL)
   2298  1.1  christos 
   2299  1.1  christos      if (info->executable)
   2300  1.1  christos 	{
   2301  1.1  christos 	  if (! add_dynamic_entry (DT_DEBUG, 0))
   2302  1.1  christos 	    return FALSE;
   2303  1.1  christos 	}
   2304  1.1  christos 
   2305  1.1  christos       if (htab->splt->size != 0)
   2306  1.1  christos         {
   2307  1.1  christos           if (! add_dynamic_entry (DT_PLTGOT, 0)
   2308  1.1  christos               || ! add_dynamic_entry (DT_PLTRELSZ, 0)
   2309  1.1  christos               || ! add_dynamic_entry (DT_PLTREL, DT_RELA)
   2310  1.1  christos               || ! add_dynamic_entry (DT_JMPREL, 0))
   2311  1.1  christos             return FALSE;
   2312  1.1  christos         }
   2313  1.1  christos 
   2314  1.1  christos       if (relocs)
   2315  1.1  christos         {
   2316  1.1  christos           if (! add_dynamic_entry (DT_RELA, 0)
   2317  1.1  christos               || ! add_dynamic_entry (DT_RELASZ, 0)
   2318  1.1  christos               || ! add_dynamic_entry (DT_RELAENT,
   2319  1.1  christos                                       sizeof (Elf32_External_Rela)))
   2320  1.1  christos             return FALSE;
   2321  1.1  christos 
   2322  1.1  christos           /* If any dynamic relocs apply to a read-only section,
   2323  1.1  christos              then we need a DT_TEXTREL entry.  */
   2324  1.1  christos           if ((info->flags & DF_TEXTREL) == 0)
   2325  1.1  christos             elf_link_hash_traverse (&htab->root, readonly_dynrelocs,
   2326  1.1  christos                                     info);
   2327  1.1  christos 
   2328  1.1  christos           if ((info->flags & DF_TEXTREL) != 0)
   2329  1.1  christos             {
   2330  1.1  christos               if (! add_dynamic_entry (DT_TEXTREL, 0))
   2331  1.1  christos                 return FALSE;
   2332  1.1  christos             }
   2333  1.1  christos         }
   2334  1.1  christos     }
   2335  1.1  christos #undef add_dynamic_entry
   2336  1.1  christos 
   2337  1.1  christos   /* Allocate .rofixup section.  */
   2338  1.1  christos   if (IS_FDPIC (output_bfd))
   2339  1.1  christos     {
   2340  1.1  christos       struct weak_symbol_list *list_start = NULL, *list_end = NULL;
   2341  1.1  christos       int rgot_weak_count = 0;
   2342  1.1  christos       int r32_count = 0;
   2343  1.1  christos       int rgot_count = 0;
   2344  1.1  christos       /* Look for deleted sections.  */
   2345  1.1  christos       for (ibfd = info->input_bfds; ibfd != NULL; ibfd = ibfd->link_next)
   2346  1.1  christos         {
   2347  1.1  christos           for (s = ibfd->sections; s != NULL; s = s->next)
   2348  1.1  christos             {
   2349  1.1  christos               if (s->reloc_count)
   2350  1.1  christos                 {
   2351  1.1  christos                   /* Count relocs that need .rofixup entires.  */
   2352  1.1  christos                   Elf_Internal_Rela *internal_relocs, *end;
   2353  1.1  christos                   internal_relocs = elf_section_data (s)->relocs;
   2354  1.1  christos                   if (internal_relocs == NULL)
   2355  1.1  christos                     internal_relocs = (_bfd_elf_link_read_relocs (ibfd, s, NULL, NULL, FALSE));
   2356  1.1  christos                   if (internal_relocs != NULL)
   2357  1.1  christos                     {
   2358  1.1  christos                       end = internal_relocs + s->reloc_count;
   2359  1.1  christos                       while (internal_relocs < end)
   2360  1.1  christos                         {
   2361  1.1  christos                           Elf_Internal_Shdr *symtab_hdr = &elf_tdata (ibfd)->symtab_hdr;
   2362  1.1  christos                           struct elf_link_hash_entry **sym_hashes = elf_sym_hashes (ibfd);
   2363  1.1  christos                           unsigned long r_symndx;
   2364  1.1  christos                           struct elf_link_hash_entry *h;
   2365  1.1  christos 
   2366  1.1  christos                           symtab_hdr = &elf_tdata (ibfd)->symtab_hdr;
   2367  1.1  christos                           sym_hashes = elf_sym_hashes (ibfd);
   2368  1.1  christos                           r_symndx = ELF32_R_SYM (internal_relocs->r_info);
   2369  1.1  christos                           h = NULL;
   2370  1.1  christos                           if (r_symndx < symtab_hdr->sh_info)
   2371  1.1  christos                             {
   2372  1.1  christos                             }
   2373  1.1  christos                           else
   2374  1.1  christos                             {
   2375  1.1  christos                               h = sym_hashes[r_symndx - symtab_hdr->sh_info];
   2376  1.1  christos                               while (h->root.type == bfd_link_hash_indirect
   2377  1.1  christos                                      || h->root.type == bfd_link_hash_warning)
   2378  1.1  christos                                 h = (struct elf_link_hash_entry *) h->root.u.i.link;
   2379  1.1  christos                               }
   2380  1.1  christos 
   2381  1.1  christos                           /* Don't generate entries for weak symbols.  */
   2382  1.1  christos                           if (!h || (h && h->root.type != bfd_link_hash_undefweak))
   2383  1.1  christos                             {
   2384  1.1  christos                               if (!elf_discarded_section (s) && !((bfd_get_section_flags (ibfd, s) & SEC_ALLOC) == 0))
   2385  1.1  christos                                 {
   2386  1.1  christos                                   switch (ELF32_R_TYPE (internal_relocs->r_info))
   2387  1.1  christos                                     {
   2388  1.1  christos                                     case R_LM32_32:
   2389  1.1  christos                                       r32_count++;
   2390  1.1  christos                                       break;
   2391  1.1  christos                                     case R_LM32_16_GOT:
   2392  1.1  christos                                       rgot_count++;
   2393  1.1  christos                                       break;
   2394  1.1  christos                                     }
   2395  1.1  christos                                 }
   2396  1.1  christos                             }
   2397  1.1  christos                           else
   2398  1.1  christos                             {
   2399  1.1  christos                               struct weak_symbol_list *current, *new_entry;
   2400  1.1  christos                               /* Is this symbol already in the list?  */
   2401  1.1  christos                               for (current = list_start; current; current = current->next)
   2402  1.1  christos                                 {
   2403  1.1  christos                                   if (!strcmp (current->name, h->root.root.string))
   2404  1.1  christos                                     break;
   2405  1.1  christos                                 }
   2406  1.1  christos                               if (!current && !elf_discarded_section (s) && (bfd_get_section_flags (ibfd, s) & SEC_ALLOC))
   2407  1.1  christos                                 {
   2408  1.1  christos                                   /* Will this have an entry in the GOT.  */
   2409  1.1  christos                                   if (ELF32_R_TYPE (internal_relocs->r_info) == R_LM32_16_GOT)
   2410  1.1  christos                                     {
   2411  1.1  christos                                       /* Create a new entry.  */
   2412  1.1  christos                                       new_entry = malloc (sizeof (struct weak_symbol_list));
   2413  1.1  christos                                       if (!new_entry)
   2414  1.1  christos                                         return FALSE;
   2415  1.1  christos                                       new_entry->name = h->root.root.string;
   2416  1.1  christos                                       new_entry->next = NULL;
   2417  1.1  christos                                       /* Add to list */
   2418  1.1  christos                                       if (list_start == NULL)
   2419  1.1  christos                                         {
   2420  1.1  christos                                           list_start = new_entry;
   2421  1.1  christos                                           list_end = new_entry;
   2422  1.1  christos                                         }
   2423  1.1  christos                                       else
   2424  1.1  christos                                         {
   2425  1.1  christos                                           list_end->next = new_entry;
   2426  1.1  christos                                           list_end = new_entry;
   2427  1.1  christos                                         }
   2428  1.1  christos                                       /* Increase count of undefined weak symbols in the got.  */
   2429  1.1  christos                                       rgot_weak_count++;
   2430  1.1  christos                                     }
   2431  1.1  christos                                 }
   2432  1.1  christos                             }
   2433  1.1  christos                           internal_relocs++;
   2434  1.1  christos                         }
   2435  1.1  christos                     }
   2436  1.1  christos                   else
   2437  1.1  christos                     return FALSE;
   2438  1.1  christos                 }
   2439  1.1  christos             }
   2440  1.1  christos         }
   2441  1.1  christos       /* Free list.  */
   2442  1.1  christos       while (list_start)
   2443  1.1  christos         {
   2444  1.1  christos           list_end = list_start->next;
   2445  1.1  christos           free (list_start);
   2446  1.1  christos           list_start = list_end;
   2447  1.1  christos         }
   2448  1.1  christos 
   2449  1.1  christos       /* Size sections.  */
   2450  1.1  christos       lm32fdpic_fixup32_section (info)->size = (r32_count + (htab->sgot->size / 4) - rgot_weak_count + 1) * 4;
   2451  1.1  christos       if (lm32fdpic_fixup32_section (info)->size == 0)
   2452  1.1  christos         lm32fdpic_fixup32_section (info)->flags |= SEC_EXCLUDE;
   2453  1.1  christos       else
   2454  1.1  christos         {
   2455  1.1  christos           lm32fdpic_fixup32_section (info)->contents =
   2456  1.1  christos     	     bfd_zalloc (dynobj, lm32fdpic_fixup32_section (info)->size);
   2457  1.1  christos           if (lm32fdpic_fixup32_section (info)->contents == NULL)
   2458  1.1  christos     	    return FALSE;
   2459  1.1  christos         }
   2460  1.1  christos     }
   2461  1.1  christos 
   2462  1.1  christos   return TRUE;
   2463  1.1  christos }
   2464  1.1  christos 
   2465  1.1  christos /* Create dynamic sections when linking against a dynamic object.  */
   2466  1.1  christos 
   2467  1.1  christos static bfd_boolean
   2468  1.1  christos lm32_elf_create_dynamic_sections (bfd *abfd, struct bfd_link_info *info)
   2469  1.1  christos {
   2470  1.1  christos   struct elf_lm32_link_hash_table *htab;
   2471  1.1  christos   flagword flags, pltflags;
   2472  1.1  christos   asection *s;
   2473  1.1  christos   const struct elf_backend_data *bed = get_elf_backend_data (abfd);
   2474  1.1  christos   int ptralign = 2; /* 32bit */
   2475  1.1  christos 
   2476  1.1  christos   htab = lm32_elf_hash_table (info);
   2477  1.1  christos   if (htab == NULL)
   2478  1.1  christos     return FALSE;
   2479  1.1  christos 
   2480  1.1  christos   /* Make sure we have a GOT - For the case where we have a dynamic object
   2481  1.1  christos      but none of the relocs in check_relocs */
   2482  1.1  christos   if (! create_got_section (abfd, info))
   2483  1.1  christos     return FALSE;
   2484  1.1  christos   if (IS_FDPIC (abfd) && (htab->sfixup32 == NULL))
   2485  1.1  christos     {
   2486  1.1  christos       if (! create_rofixup_section (abfd, info))
   2487  1.1  christos         return FALSE;
   2488  1.1  christos     }
   2489  1.1  christos 
   2490  1.1  christos   /* We need to create .plt, .rel[a].plt, .got, .got.plt, .dynbss, and
   2491  1.1  christos      .rel[a].bss sections.  */
   2492  1.1  christos   flags = (SEC_ALLOC | SEC_LOAD | SEC_HAS_CONTENTS | SEC_IN_MEMORY
   2493  1.1  christos            | SEC_LINKER_CREATED);
   2494  1.1  christos 
   2495  1.1  christos   pltflags = flags;
   2496  1.1  christos   pltflags |= SEC_CODE;
   2497  1.1  christos   if (bed->plt_not_loaded)
   2498  1.1  christos     pltflags &= ~ (SEC_LOAD | SEC_HAS_CONTENTS);
   2499  1.1  christos   if (bed->plt_readonly)
   2500  1.1  christos     pltflags |= SEC_READONLY;
   2501  1.1  christos 
   2502  1.1  christos   s = bfd_make_section_with_flags (abfd, ".plt", pltflags);
   2503  1.1  christos   htab->splt = s;
   2504  1.1  christos   if (s == NULL
   2505  1.1  christos       || ! bfd_set_section_alignment (abfd, s, bed->plt_alignment))
   2506  1.1  christos     return FALSE;
   2507  1.1  christos 
   2508  1.1  christos   if (bed->want_plt_sym)
   2509  1.1  christos     {
   2510  1.1  christos       /* Define the symbol _PROCEDURE_LINKAGE_TABLE_ at the start of the
   2511  1.1  christos          .plt section.  */
   2512  1.1  christos       struct bfd_link_hash_entry *bh = NULL;
   2513  1.1  christos       struct elf_link_hash_entry *h;
   2514  1.1  christos 
   2515  1.1  christos       if (! (_bfd_generic_link_add_one_symbol
   2516  1.1  christos              (info, abfd, "_PROCEDURE_LINKAGE_TABLE_", BSF_GLOBAL, s,
   2517  1.1  christos               (bfd_vma) 0, NULL, FALSE,
   2518  1.1  christos               get_elf_backend_data (abfd)->collect, &bh)))
   2519  1.1  christos         return FALSE;
   2520  1.1  christos       h = (struct elf_link_hash_entry *) bh;
   2521  1.1  christos       h->def_regular = 1;
   2522  1.1  christos       h->type = STT_OBJECT;
   2523  1.1  christos       htab->root.hplt = h;
   2524  1.1  christos 
   2525  1.1  christos       if (info->shared
   2526  1.1  christos           && ! bfd_elf_link_record_dynamic_symbol (info, h))
   2527  1.1  christos         return FALSE;
   2528  1.1  christos     }
   2529  1.1  christos 
   2530  1.1  christos   s = bfd_make_section_with_flags (abfd,
   2531  1.1  christos 				   bed->default_use_rela_p ? ".rela.plt" : ".rel.plt",
   2532  1.1  christos 				   flags | SEC_READONLY);
   2533  1.1  christos   htab->srelplt = s;
   2534  1.1  christos   if (s == NULL
   2535  1.1  christos       || ! bfd_set_section_alignment (abfd, s, ptralign))
   2536  1.1  christos     return FALSE;
   2537  1.1  christos 
   2538  1.1  christos   if (htab->sgot == NULL
   2539  1.1  christos       && ! create_got_section (abfd, info))
   2540  1.1  christos     return FALSE;
   2541  1.1  christos 
   2542  1.1  christos   {
   2543  1.1  christos     const char *secname;
   2544  1.1  christos     char *relname;
   2545  1.1  christos     flagword secflags;
   2546  1.1  christos     asection *sec;
   2547  1.1  christos 
   2548  1.1  christos     for (sec = abfd->sections; sec; sec = sec->next)
   2549  1.1  christos       {
   2550  1.1  christos         secflags = bfd_get_section_flags (abfd, sec);
   2551  1.1  christos         if ((secflags & (SEC_DATA | SEC_LINKER_CREATED))
   2552  1.1  christos             || ((secflags & SEC_HAS_CONTENTS) != SEC_HAS_CONTENTS))
   2553  1.1  christos           continue;
   2554  1.1  christos         secname = bfd_get_section_name (abfd, sec);
   2555  1.1  christos         relname = bfd_malloc ((bfd_size_type) strlen (secname) + 6);
   2556  1.1  christos         strcpy (relname, ".rela");
   2557  1.1  christos         strcat (relname, secname);
   2558  1.1  christos         if (bfd_get_section_by_name (abfd, secname))
   2559  1.1  christos           continue;
   2560  1.1  christos         s = bfd_make_section_with_flags (abfd, relname,
   2561  1.1  christos 					 flags | SEC_READONLY);
   2562  1.1  christos         if (s == NULL
   2563  1.1  christos             || ! bfd_set_section_alignment (abfd, s, ptralign))
   2564  1.1  christos           return FALSE;
   2565  1.1  christos       }
   2566  1.1  christos   }
   2567  1.1  christos 
   2568  1.1  christos   if (bed->want_dynbss)
   2569  1.1  christos     {
   2570  1.1  christos       /* The .dynbss section is a place to put symbols which are defined
   2571  1.1  christos          by dynamic objects, are referenced by regular objects, and are
   2572  1.1  christos          not functions.  We must allocate space for them in the process
   2573  1.1  christos          image and use a R_*_COPY reloc to tell the dynamic linker to
   2574  1.1  christos          initialize them at run time.  The linker script puts the .dynbss
   2575  1.1  christos          section into the .bss section of the final image.  */
   2576  1.1  christos       s = bfd_make_section_with_flags (abfd, ".dynbss",
   2577  1.1  christos 				       SEC_ALLOC | SEC_LINKER_CREATED);
   2578  1.1  christos       htab->sdynbss = s;
   2579  1.1  christos       if (s == NULL)
   2580  1.1  christos         return FALSE;
   2581  1.1  christos       /* The .rel[a].bss section holds copy relocs.  This section is not
   2582  1.1  christos          normally needed.  We need to create it here, though, so that the
   2583  1.1  christos          linker will map it to an output section.  We can't just create it
   2584  1.1  christos          only if we need it, because we will not know whether we need it
   2585  1.1  christos          until we have seen all the input files, and the first time the
   2586  1.1  christos          main linker code calls BFD after examining all the input files
   2587  1.1  christos          (size_dynamic_sections) the input sections have already been
   2588  1.1  christos          mapped to the output sections.  If the section turns out not to
   2589  1.1  christos          be needed, we can discard it later.  We will never need this
   2590  1.1  christos          section when generating a shared object, since they do not use
   2591  1.1  christos          copy relocs.  */
   2592  1.1  christos       if (! info->shared)
   2593  1.1  christos         {
   2594  1.1  christos           s = bfd_make_section_with_flags (abfd,
   2595  1.1  christos 					   (bed->default_use_rela_p
   2596  1.1  christos 					    ? ".rela.bss" : ".rel.bss"),
   2597  1.1  christos 					   flags | SEC_READONLY);
   2598  1.1  christos           htab->srelbss = s;
   2599  1.1  christos           if (s == NULL
   2600  1.1  christos               || ! bfd_set_section_alignment (abfd, s, ptralign))
   2601  1.1  christos             return FALSE;
   2602  1.1  christos         }
   2603  1.1  christos     }
   2604  1.1  christos 
   2605  1.1  christos   return TRUE;
   2606  1.1  christos }
   2607  1.1  christos 
   2608  1.1  christos /* Copy the extra info we tack onto an elf_link_hash_entry.  */
   2609  1.1  christos 
   2610  1.1  christos static void
   2611  1.1  christos lm32_elf_copy_indirect_symbol (struct bfd_link_info *info,
   2612  1.1  christos                                struct elf_link_hash_entry *dir,
   2613  1.1  christos                                struct elf_link_hash_entry *ind)
   2614  1.1  christos {
   2615  1.1  christos   struct elf_lm32_link_hash_entry * edir;
   2616  1.1  christos   struct elf_lm32_link_hash_entry * eind;
   2617  1.1  christos 
   2618  1.1  christos   edir = (struct elf_lm32_link_hash_entry *) dir;
   2619  1.1  christos   eind = (struct elf_lm32_link_hash_entry *) ind;
   2620  1.1  christos 
   2621  1.1  christos   if (eind->dyn_relocs != NULL)
   2622  1.1  christos     {
   2623  1.1  christos       if (edir->dyn_relocs != NULL)
   2624  1.1  christos         {
   2625  1.1  christos           struct elf_lm32_dyn_relocs **pp;
   2626  1.1  christos           struct elf_lm32_dyn_relocs *p;
   2627  1.1  christos 
   2628  1.1  christos           /* Add reloc counts against the indirect sym to the direct sym
   2629  1.1  christos              list.  Merge any entries against the same section.  */
   2630  1.1  christos           for (pp = &eind->dyn_relocs; (p = *pp) != NULL;)
   2631  1.1  christos             {
   2632  1.1  christos               struct elf_lm32_dyn_relocs *q;
   2633  1.1  christos 
   2634  1.1  christos               for (q = edir->dyn_relocs; q != NULL; q = q->next)
   2635  1.1  christos                 if (q->sec == p->sec)
   2636  1.1  christos                   {
   2637  1.1  christos                     q->pc_count += p->pc_count;
   2638  1.1  christos                     q->count += p->count;
   2639  1.1  christos                     *pp = p->next;
   2640  1.1  christos                     break;
   2641  1.1  christos                   }
   2642  1.1  christos               if (q == NULL)
   2643  1.1  christos                 pp = &p->next;
   2644  1.1  christos             }
   2645  1.1  christos           *pp = edir->dyn_relocs;
   2646  1.1  christos         }
   2647  1.1  christos 
   2648  1.1  christos       edir->dyn_relocs = eind->dyn_relocs;
   2649  1.1  christos       eind->dyn_relocs = NULL;
   2650  1.1  christos     }
   2651  1.1  christos 
   2652  1.1  christos   _bfd_elf_link_hash_copy_indirect (info, dir, ind);
   2653  1.1  christos }
   2654  1.1  christos 
   2655  1.1  christos static bfd_boolean
   2656  1.1  christos lm32_elf_always_size_sections (bfd *output_bfd,
   2657  1.1  christos 				 struct bfd_link_info *info)
   2658  1.1  christos {
   2659  1.1  christos   if (!info->relocatable)
   2660  1.1  christos     {
   2661  1.1  christos       struct elf_link_hash_entry *h;
   2662  1.1  christos 
   2663  1.1  christos       /* Force a PT_GNU_STACK segment to be created.  */
   2664  1.1  christos       if (! elf_tdata (output_bfd)->stack_flags)
   2665  1.1  christos 	elf_tdata (output_bfd)->stack_flags = PF_R | PF_W | PF_X;
   2666  1.1  christos 
   2667  1.1  christos       /* Define __stacksize if it's not defined yet.  */
   2668  1.1  christos       h = elf_link_hash_lookup (elf_hash_table (info), "__stacksize",
   2669  1.1  christos 				FALSE, FALSE, FALSE);
   2670  1.1  christos       if (! h || h->root.type != bfd_link_hash_defined
   2671  1.1  christos 	  || h->type != STT_OBJECT
   2672  1.1  christos 	  || !h->def_regular)
   2673  1.1  christos 	{
   2674  1.1  christos 	  struct bfd_link_hash_entry *bh = NULL;
   2675  1.1  christos 
   2676  1.1  christos 	  if (!(_bfd_generic_link_add_one_symbol
   2677  1.1  christos 		(info, output_bfd, "__stacksize",
   2678  1.1  christos 		 BSF_GLOBAL, bfd_abs_section_ptr, DEFAULT_STACK_SIZE,
   2679  1.1  christos 		 (const char *) NULL, FALSE,
   2680  1.1  christos 		 get_elf_backend_data (output_bfd)->collect, &bh)))
   2681  1.1  christos 	    return FALSE;
   2682  1.1  christos 
   2683  1.1  christos 	  h = (struct elf_link_hash_entry *) bh;
   2684  1.1  christos 	  h->def_regular = 1;
   2685  1.1  christos 	  h->type = STT_OBJECT;
   2686  1.1  christos 	  /* This one must NOT be hidden.  */
   2687  1.1  christos 	}
   2688  1.1  christos     }
   2689  1.1  christos 
   2690  1.1  christos   return TRUE;
   2691  1.1  christos }
   2692  1.1  christos 
   2693  1.1  christos static bfd_boolean
   2694  1.1  christos lm32_elf_modify_segment_map (bfd *output_bfd,
   2695  1.1  christos 			     struct bfd_link_info *info)
   2696  1.1  christos {
   2697  1.1  christos   struct elf_segment_map *m;
   2698  1.1  christos 
   2699  1.1  christos   /* objcopy and strip preserve what's already there using elf32_lm32fdpic_copy_
   2700  1.1  christos      private_bfd_data ().  */
   2701  1.1  christos   if (! info)
   2702  1.1  christos     return TRUE;
   2703  1.1  christos 
   2704  1.1  christos   for (m = elf_tdata (output_bfd)->segment_map; m != NULL; m = m->next)
   2705  1.1  christos     if (m->p_type == PT_GNU_STACK)
   2706  1.1  christos       break;
   2707  1.1  christos 
   2708  1.1  christos   if (m)
   2709  1.1  christos     {
   2710  1.1  christos       asection *sec = bfd_get_section_by_name (output_bfd, ".stack");
   2711  1.1  christos       struct elf_link_hash_entry *h;
   2712  1.1  christos 
   2713  1.1  christos       if (sec)
   2714  1.1  christos 	{
   2715  1.1  christos 	  /* Obtain the pointer to the __stacksize symbol.  */
   2716  1.1  christos 	  h = elf_link_hash_lookup (elf_hash_table (info), "__stacksize",
   2717  1.1  christos 				    FALSE, FALSE, FALSE);
   2718  1.1  christos 	  while (h->root.type == bfd_link_hash_indirect
   2719  1.1  christos 		 || h->root.type == bfd_link_hash_warning)
   2720  1.1  christos 	    h = (struct elf_link_hash_entry *)h->root.u.i.link;
   2721  1.1  christos 	  BFD_ASSERT (h->root.type == bfd_link_hash_defined);
   2722  1.1  christos 
   2723  1.1  christos 	  /* Set the section size from the symbol value.  We
   2724  1.1  christos 	     intentionally ignore the symbol section.  */
   2725  1.1  christos 	  if (h->root.type == bfd_link_hash_defined)
   2726  1.1  christos 	    sec->size = h->root.u.def.value;
   2727  1.1  christos 	  else
   2728  1.1  christos 	    sec->size = DEFAULT_STACK_SIZE;
   2729  1.1  christos 
   2730  1.1  christos 	  /* Add the stack section to the PT_GNU_STACK segment,
   2731  1.1  christos 	     such that its size and alignment requirements make it
   2732  1.1  christos 	     to the segment.  */
   2733  1.1  christos 	  m->sections[m->count] = sec;
   2734  1.1  christos 	  m->count++;
   2735  1.1  christos 	}
   2736  1.1  christos     }
   2737  1.1  christos 
   2738  1.1  christos   return TRUE;
   2739  1.1  christos }
   2740  1.1  christos 
   2741  1.1  christos static bfd_boolean
   2742  1.1  christos lm32_elf_modify_program_headers (bfd *output_bfd,
   2743  1.1  christos 				       struct bfd_link_info *info)
   2744  1.1  christos {
   2745  1.1  christos   struct elf_obj_tdata *tdata = elf_tdata (output_bfd);
   2746  1.1  christos   struct elf_segment_map *m;
   2747  1.1  christos   Elf_Internal_Phdr *p;
   2748  1.1  christos 
   2749  1.1  christos   if (! info)
   2750  1.1  christos     return TRUE;
   2751  1.1  christos 
   2752  1.1  christos   for (p = tdata->phdr, m = tdata->segment_map; m != NULL; m = m->next, p++)
   2753  1.1  christos     if (m->p_type == PT_GNU_STACK)
   2754  1.1  christos       break;
   2755  1.1  christos 
   2756  1.1  christos   if (m)
   2757  1.1  christos     {
   2758  1.1  christos       struct elf_link_hash_entry *h;
   2759  1.1  christos 
   2760  1.1  christos       /* Obtain the pointer to the __stacksize symbol.  */
   2761  1.1  christos       h = elf_link_hash_lookup (elf_hash_table (info), "__stacksize",
   2762  1.1  christos 				FALSE, FALSE, FALSE);
   2763  1.1  christos       if (h)
   2764  1.1  christos 	{
   2765  1.1  christos 	  while (h->root.type == bfd_link_hash_indirect
   2766  1.1  christos 		 || h->root.type == bfd_link_hash_warning)
   2767  1.1  christos 	    h = (struct elf_link_hash_entry *) h->root.u.i.link;
   2768  1.1  christos 	  BFD_ASSERT (h->root.type == bfd_link_hash_defined);
   2769  1.1  christos 	}
   2770  1.1  christos 
   2771  1.1  christos       /* Set the header p_memsz from the symbol value.  We
   2772  1.1  christos 	 intentionally ignore the symbol section.  */
   2773  1.1  christos       if (h && h->root.type == bfd_link_hash_defined)
   2774  1.1  christos 	p->p_memsz = h->root.u.def.value;
   2775  1.1  christos       else
   2776  1.1  christos 	p->p_memsz = DEFAULT_STACK_SIZE;
   2777  1.1  christos 
   2778  1.1  christos       p->p_align = 8;
   2779  1.1  christos     }
   2780  1.1  christos 
   2781  1.1  christos   return TRUE;
   2782  1.1  christos }
   2783  1.1  christos 
   2784  1.1  christos 
   2785  1.1  christos static bfd_boolean
   2786  1.1  christos lm32_elf_copy_private_bfd_data (bfd *ibfd, bfd *obfd)
   2787  1.1  christos {
   2788  1.1  christos   if (bfd_get_flavour (ibfd) != bfd_target_elf_flavour
   2789  1.1  christos       || bfd_get_flavour (obfd) != bfd_target_elf_flavour)
   2790  1.1  christos     return TRUE;
   2791  1.1  christos 
   2792  1.1  christos   BFD_ASSERT (!elf_flags_init (obfd)
   2793  1.1  christos 	      || elf_elfheader (obfd)->e_flags == elf_elfheader (ibfd)->e_flags);
   2794  1.1  christos 
   2795  1.1  christos   elf_elfheader (obfd)->e_flags = elf_elfheader (ibfd)->e_flags;
   2796  1.1  christos   elf_flags_init (obfd) = TRUE;
   2797  1.1  christos 
   2798  1.1  christos   /* Copy object attributes.  */
   2799  1.1  christos   _bfd_elf_copy_obj_attributes (ibfd, obfd);
   2800  1.1  christos 
   2801  1.1  christos   return TRUE;
   2802  1.1  christos }
   2803  1.1  christos 
   2804  1.1  christos 
   2805  1.1  christos static bfd_boolean
   2806  1.1  christos lm32_elf_fdpic_copy_private_bfd_data (bfd *ibfd, bfd *obfd)
   2807  1.1  christos {
   2808  1.1  christos   unsigned i;
   2809  1.1  christos 
   2810  1.1  christos   if (bfd_get_flavour (ibfd) != bfd_target_elf_flavour
   2811  1.1  christos       || bfd_get_flavour (obfd) != bfd_target_elf_flavour)
   2812  1.1  christos     return TRUE;
   2813  1.1  christos 
   2814  1.1  christos   if (! lm32_elf_copy_private_bfd_data (ibfd, obfd))
   2815  1.1  christos     return FALSE;
   2816  1.1  christos 
   2817  1.1  christos   if (! elf_tdata (ibfd) || ! elf_tdata (ibfd)->phdr
   2818  1.1  christos       || ! elf_tdata (obfd) || ! elf_tdata (obfd)->phdr)
   2819  1.1  christos     return TRUE;
   2820  1.1  christos 
   2821  1.1  christos   /* Copy the stack size.  */
   2822  1.1  christos   for (i = 0; i < elf_elfheader (ibfd)->e_phnum; i++)
   2823  1.1  christos     if (elf_tdata (ibfd)->phdr[i].p_type == PT_GNU_STACK)
   2824  1.1  christos       {
   2825  1.1  christos 	Elf_Internal_Phdr *iphdr = &elf_tdata (ibfd)->phdr[i];
   2826  1.1  christos 
   2827  1.1  christos 	for (i = 0; i < elf_elfheader (obfd)->e_phnum; i++)
   2828  1.1  christos 	  if (elf_tdata (obfd)->phdr[i].p_type == PT_GNU_STACK)
   2829  1.1  christos 	    {
   2830  1.1  christos 	      memcpy (&elf_tdata (obfd)->phdr[i], iphdr, sizeof (*iphdr));
   2831  1.1  christos 
   2832  1.1  christos 	      /* Rewrite the phdrs, since we're only called after they were first written.  */
   2833  1.1  christos 	      if (bfd_seek (obfd, (bfd_signed_vma) get_elf_backend_data (obfd)
   2834  1.1  christos 			    ->s->sizeof_ehdr, SEEK_SET) != 0
   2835  1.1  christos 		  || get_elf_backend_data (obfd)->s->write_out_phdrs (obfd, elf_tdata (obfd)->phdr,
   2836  1.1  christos 				     elf_elfheader (obfd)->e_phnum) != 0)
   2837  1.1  christos 		return FALSE;
   2838  1.1  christos 	      break;
   2839  1.1  christos 	    }
   2840  1.1  christos 
   2841  1.1  christos 	break;
   2842  1.1  christos       }
   2843  1.1  christos 
   2844  1.1  christos   return TRUE;
   2845  1.1  christos }
   2846  1.1  christos 
   2847  1.1  christos 
   2848  1.1  christos #define ELF_ARCH                bfd_arch_lm32
   2849  1.1  christos #define ELF_TARGET_ID		LM32_ELF_DATA
   2850  1.1  christos #define ELF_MACHINE_CODE        EM_LATTICEMICO32
   2851  1.1  christos #define ELF_MAXPAGESIZE         0x1000
   2852  1.1  christos 
   2853  1.1  christos #define TARGET_BIG_SYM          bfd_elf32_lm32_vec
   2854  1.1  christos #define TARGET_BIG_NAME         "elf32-lm32"
   2855  1.1  christos 
   2856  1.1  christos #define bfd_elf32_bfd_reloc_type_lookup         lm32_reloc_type_lookup
   2857  1.1  christos #define bfd_elf32_bfd_reloc_name_lookup         lm32_reloc_name_lookup
   2858  1.1  christos #define elf_info_to_howto                       lm32_info_to_howto_rela
   2859  1.1  christos #define elf_info_to_howto_rel                   0
   2860  1.1  christos #define elf_backend_rela_normal                 1
   2861  1.1  christos #define elf_backend_object_p                    lm32_elf_object_p
   2862  1.1  christos #define elf_backend_final_write_processing      lm32_elf_final_write_processing
   2863  1.1  christos #define elf_backend_can_gc_sections             1
   2864  1.1  christos #define elf_backend_can_refcount                1
   2865  1.1  christos #define elf_backend_gc_mark_hook                lm32_elf_gc_mark_hook
   2866  1.1  christos #define elf_backend_gc_sweep_hook               lm32_elf_gc_sweep_hook
   2867  1.1  christos #define elf_backend_plt_readonly                1
   2868  1.1  christos #define elf_backend_want_got_plt                1
   2869  1.1  christos #define elf_backend_want_plt_sym                0
   2870  1.1  christos #define elf_backend_got_header_size             12
   2871  1.1  christos #define bfd_elf32_bfd_link_hash_table_create    lm32_elf_link_hash_table_create
   2872  1.1  christos #define elf_backend_check_relocs                lm32_elf_check_relocs
   2873  1.1  christos #define elf_backend_reloc_type_class            lm32_elf_reloc_type_class
   2874  1.1  christos #define elf_backend_copy_indirect_symbol        lm32_elf_copy_indirect_symbol
   2875  1.1  christos #define elf_backend_size_dynamic_sections       lm32_elf_size_dynamic_sections
   2876  1.1  christos #define elf_backend_omit_section_dynsym         ((bfd_boolean (*) (bfd *, struct bfd_link_info *, asection *)) bfd_true)
   2877  1.1  christos #define elf_backend_create_dynamic_sections     lm32_elf_create_dynamic_sections
   2878  1.1  christos #define elf_backend_finish_dynamic_sections     lm32_elf_finish_dynamic_sections
   2879  1.1  christos #define elf_backend_adjust_dynamic_symbol       lm32_elf_adjust_dynamic_symbol
   2880  1.1  christos #define elf_backend_finish_dynamic_symbol       lm32_elf_finish_dynamic_symbol
   2881  1.1  christos #define elf_backend_relocate_section            lm32_elf_relocate_section
   2882  1.1  christos 
   2883  1.1  christos #include "elf32-target.h"
   2884  1.1  christos 
   2885  1.1  christos #undef  ELF_MAXPAGESIZE
   2886  1.1  christos #define ELF_MAXPAGESIZE		0x4000
   2887  1.1  christos 
   2888  1.1  christos 
   2889  1.1  christos #undef  TARGET_BIG_SYM
   2890  1.1  christos #define TARGET_BIG_SYM          bfd_elf32_lm32fdpic_vec
   2891  1.1  christos #undef  TARGET_BIG_NAME
   2892  1.1  christos #define TARGET_BIG_NAME		"elf32-lm32fdpic"
   2893  1.1  christos #undef	elf32_bed
   2894  1.1  christos #define	elf32_bed		elf32_lm32fdpic_bed
   2895  1.1  christos 
   2896  1.1  christos #undef  elf_backend_always_size_sections
   2897  1.1  christos #define elf_backend_always_size_sections        lm32_elf_always_size_sections
   2898  1.1  christos #undef  elf_backend_modify_segment_map
   2899  1.1  christos #define elf_backend_modify_segment_map          lm32_elf_modify_segment_map
   2900  1.1  christos #undef  elf_backend_modify_program_headers
   2901  1.1  christos #define elf_backend_modify_program_headers      lm32_elf_modify_program_headers
   2902  1.1  christos #undef  bfd_elf32_bfd_copy_private_bfd_data
   2903  1.1  christos #define bfd_elf32_bfd_copy_private_bfd_data     lm32_elf_fdpic_copy_private_bfd_data
   2904  1.1  christos 
   2905  1.1  christos #include "elf32-target.h"
   2906