Home | History | Annotate | Line # | Download | only in bfd
elfnn-riscv.c revision 1.4.2.2
      1      1.1      matt /* RISC-V-specific support for NN-bit ELF.
      2  1.4.2.2    martin    Copyright (C) 2011-2020 Free Software Foundation, Inc.
      3      1.1      matt 
      4      1.4  christos    Contributed by Andrew Waterman (andrew (at) sifive.com).
      5      1.1      matt    Based on TILE-Gx and MIPS targets.
      6      1.1      matt 
      7      1.1      matt    This file is part of BFD, the Binary File Descriptor library.
      8      1.1      matt 
      9      1.1      matt    This program is free software; you can redistribute it and/or modify
     10      1.1      matt    it under the terms of the GNU General Public License as published by
     11      1.1      matt    the Free Software Foundation; either version 3 of the License, or
     12      1.1      matt    (at your option) any later version.
     13      1.1      matt 
     14      1.1      matt    This program is distributed in the hope that it will be useful,
     15      1.1      matt    but WITHOUT ANY WARRANTY; without even the implied warranty of
     16      1.1      matt    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     17      1.1      matt    GNU General Public License for more details.
     18      1.1      matt 
     19      1.1      matt    You should have received a copy of the GNU General Public License
     20      1.4  christos    along with this program; see the file COPYING3. If not,
     21      1.4  christos    see <http://www.gnu.org/licenses/>.  */
     22      1.1      matt 
     23      1.1      matt /* This file handles RISC-V ELF targets.  */
     24      1.1      matt 
     25      1.1      matt #include "sysdep.h"
     26      1.1      matt #include "bfd.h"
     27      1.1      matt #include "libbfd.h"
     28      1.1      matt #include "bfdlink.h"
     29  1.4.2.1  christos #include "genlink.h"
     30  1.4.2.1  christos #include "elf-bfd.h"
     31      1.1      matt #include "elfxx-riscv.h"
     32      1.1      matt #include "elf/riscv.h"
     33      1.1      matt #include "opcode/riscv.h"
     34      1.1      matt 
     35      1.4  christos /* Internal relocations used exclusively by the relaxation pass.  */
     36      1.4  christos #define R_RISCV_DELETE (R_RISCV_max + 1)
     37      1.4  christos 
     38      1.1      matt #define ARCH_SIZE NN
     39      1.1      matt 
     40      1.1      matt #define MINUS_ONE ((bfd_vma)0 - 1)
     41      1.1      matt 
     42      1.1      matt #define RISCV_ELF_LOG_WORD_BYTES (ARCH_SIZE == 32 ? 2 : 3)
     43      1.1      matt 
     44      1.1      matt #define RISCV_ELF_WORD_BYTES (1 << RISCV_ELF_LOG_WORD_BYTES)
     45      1.1      matt 
     46      1.1      matt /* The name of the dynamic interpreter.  This is put in the .interp
     47      1.1      matt    section.  */
     48      1.1      matt 
     49      1.1      matt #define ELF64_DYNAMIC_INTERPRETER "/lib/ld.so.1"
     50      1.1      matt #define ELF32_DYNAMIC_INTERPRETER "/lib32/ld.so.1"
     51      1.1      matt 
     52      1.4  christos #define ELF_ARCH			bfd_arch_riscv
     53      1.4  christos #define ELF_TARGET_ID			RISCV_ELF_DATA
     54      1.4  christos #define ELF_MACHINE_CODE		EM_RISCV
     55      1.4  christos #define ELF_MAXPAGESIZE			0x1000
     56      1.4  christos #define ELF_COMMONPAGESIZE		0x1000
     57      1.1      matt 
     58      1.1      matt /* RISC-V ELF linker hash entry.  */
     59      1.1      matt 
     60      1.1      matt struct riscv_elf_link_hash_entry
     61      1.1      matt {
     62      1.1      matt   struct elf_link_hash_entry elf;
     63      1.1      matt 
     64      1.1      matt   /* Track dynamic relocs copied for this symbol.  */
     65      1.4  christos   struct elf_dyn_relocs *dyn_relocs;
     66      1.1      matt 
     67      1.1      matt #define GOT_UNKNOWN     0
     68      1.1      matt #define GOT_NORMAL      1
     69      1.1      matt #define GOT_TLS_GD      2
     70      1.1      matt #define GOT_TLS_IE      4
     71      1.1      matt #define GOT_TLS_LE      8
     72      1.1      matt   char tls_type;
     73      1.1      matt };
     74      1.1      matt 
     75      1.1      matt #define riscv_elf_hash_entry(ent) \
     76      1.1      matt   ((struct riscv_elf_link_hash_entry *)(ent))
     77      1.1      matt 
     78      1.1      matt struct _bfd_riscv_elf_obj_tdata
     79      1.1      matt {
     80      1.1      matt   struct elf_obj_tdata root;
     81      1.1      matt 
     82      1.1      matt   /* tls_type for each local got entry.  */
     83      1.1      matt   char *local_got_tls_type;
     84      1.1      matt };
     85      1.1      matt 
     86      1.1      matt #define _bfd_riscv_elf_tdata(abfd) \
     87      1.1      matt   ((struct _bfd_riscv_elf_obj_tdata *) (abfd)->tdata.any)
     88      1.1      matt 
     89      1.1      matt #define _bfd_riscv_elf_local_got_tls_type(abfd) \
     90      1.1      matt   (_bfd_riscv_elf_tdata (abfd)->local_got_tls_type)
     91      1.1      matt 
     92      1.1      matt #define _bfd_riscv_elf_tls_type(abfd, h, symndx)		\
     93      1.4  christos   (*((h) != NULL ? &riscv_elf_hash_entry (h)->tls_type		\
     94      1.1      matt      : &_bfd_riscv_elf_local_got_tls_type (abfd) [symndx]))
     95      1.1      matt 
     96      1.1      matt #define is_riscv_elf(bfd)				\
     97      1.1      matt   (bfd_get_flavour (bfd) == bfd_target_elf_flavour	\
     98      1.1      matt    && elf_tdata (bfd) != NULL				\
     99      1.1      matt    && elf_object_id (bfd) == RISCV_ELF_DATA)
    100      1.1      matt 
    101      1.1      matt #include "elf/common.h"
    102      1.1      matt #include "elf/internal.h"
    103      1.1      matt 
    104      1.1      matt struct riscv_elf_link_hash_table
    105      1.1      matt {
    106      1.1      matt   struct elf_link_hash_table elf;
    107      1.1      matt 
    108      1.1      matt   /* Short-cuts to get to dynamic linker sections.  */
    109      1.1      matt   asection *sdyntdata;
    110      1.1      matt 
    111      1.1      matt   /* Small local sym to section mapping cache.  */
    112      1.1      matt   struct sym_cache sym_cache;
    113      1.4  christos 
    114      1.4  christos   /* The max alignment of output sections.  */
    115      1.4  christos   bfd_vma max_alignment;
    116      1.1      matt };
    117      1.1      matt 
    118      1.1      matt 
    119      1.1      matt /* Get the RISC-V ELF linker hash table from a link_info structure.  */
    120      1.1      matt #define riscv_elf_hash_table(p) \
    121      1.1      matt   (elf_hash_table_id ((struct elf_link_hash_table *) ((p)->hash)) \
    122      1.1      matt   == RISCV_ELF_DATA ? ((struct riscv_elf_link_hash_table *) ((p)->hash)) : NULL)
    123      1.1      matt 
    124  1.4.2.1  christos static bfd_boolean
    125  1.4.2.1  christos riscv_info_to_howto_rela (bfd *abfd,
    126      1.1      matt 			  arelent *cache_ptr,
    127      1.1      matt 			  Elf_Internal_Rela *dst)
    128      1.1      matt {
    129  1.4.2.1  christos   cache_ptr->howto = riscv_elf_rtype_to_howto (abfd, ELFNN_R_TYPE (dst->r_info));
    130  1.4.2.1  christos   return cache_ptr->howto != NULL;
    131      1.1      matt }
    132      1.1      matt 
    133      1.1      matt static void
    134      1.1      matt riscv_elf_append_rela (bfd *abfd, asection *s, Elf_Internal_Rela *rel)
    135      1.1      matt {
    136      1.1      matt   const struct elf_backend_data *bed;
    137      1.1      matt   bfd_byte *loc;
    138      1.1      matt 
    139      1.1      matt   bed = get_elf_backend_data (abfd);
    140      1.1      matt   loc = s->contents + (s->reloc_count++ * bed->s->sizeof_rela);
    141      1.1      matt   bed->s->swap_reloca_out (abfd, rel, loc);
    142      1.1      matt }
    143      1.1      matt 
    144      1.4  christos /* PLT/GOT stuff.  */
    145      1.1      matt 
    146      1.1      matt #define PLT_HEADER_INSNS 8
    147      1.1      matt #define PLT_ENTRY_INSNS 4
    148      1.1      matt #define PLT_HEADER_SIZE (PLT_HEADER_INSNS * 4)
    149      1.1      matt #define PLT_ENTRY_SIZE (PLT_ENTRY_INSNS * 4)
    150      1.1      matt 
    151      1.1      matt #define GOT_ENTRY_SIZE RISCV_ELF_WORD_BYTES
    152      1.1      matt 
    153      1.1      matt #define GOTPLT_HEADER_SIZE (2 * GOT_ENTRY_SIZE)
    154      1.1      matt 
    155      1.1      matt #define sec_addr(sec) ((sec)->output_section->vma + (sec)->output_offset)
    156      1.1      matt 
    157      1.1      matt static bfd_vma
    158      1.1      matt riscv_elf_got_plt_val (bfd_vma plt_index, struct bfd_link_info *info)
    159      1.1      matt {
    160      1.1      matt   return sec_addr (riscv_elf_hash_table (info)->elf.sgotplt)
    161      1.1      matt 	 + GOTPLT_HEADER_SIZE + (plt_index * GOT_ENTRY_SIZE);
    162      1.1      matt }
    163      1.1      matt 
    164      1.1      matt #if ARCH_SIZE == 32
    165      1.1      matt # define MATCH_LREG MATCH_LW
    166      1.1      matt #else
    167      1.1      matt # define MATCH_LREG MATCH_LD
    168      1.1      matt #endif
    169      1.1      matt 
    170      1.4  christos /* Generate a PLT header.  */
    171      1.1      matt 
    172  1.4.2.2    martin static bfd_boolean
    173  1.4.2.2    martin riscv_make_plt_header (bfd *output_bfd, bfd_vma gotplt_addr, bfd_vma addr,
    174  1.4.2.2    martin 		       uint32_t *entry)
    175      1.1      matt {
    176      1.4  christos   bfd_vma gotplt_offset_high = RISCV_PCREL_HIGH_PART (gotplt_addr, addr);
    177      1.4  christos   bfd_vma gotplt_offset_low = RISCV_PCREL_LOW_PART (gotplt_addr, addr);
    178      1.4  christos 
    179  1.4.2.2    martin   /* RVE has no t3 register, so this won't work, and is not supported.  */
    180  1.4.2.2    martin   if (elf_elfheader (output_bfd)->e_flags & EF_RISCV_RVE)
    181  1.4.2.2    martin     {
    182  1.4.2.2    martin       _bfd_error_handler (_("%pB: warning: RVE PLT generation not supported"),
    183  1.4.2.2    martin 			  output_bfd);
    184  1.4.2.2    martin       return FALSE;
    185  1.4.2.2    martin     }
    186  1.4.2.2    martin 
    187      1.1      matt   /* auipc  t2, %hi(.got.plt)
    188      1.4  christos      sub    t1, t1, t3		     # shifted .got.plt offset + hdr size + 12
    189      1.1      matt      l[w|d] t3, %lo(.got.plt)(t2)    # _dl_runtime_resolve
    190      1.1      matt      addi   t1, t1, -(hdr size + 12) # shifted .got.plt offset
    191      1.1      matt      addi   t0, t2, %lo(.got.plt)    # &.got.plt
    192      1.1      matt      srli   t1, t1, log2(16/PTRSIZE) # .got.plt offset
    193      1.4  christos      l[w|d] t0, PTRSIZE(t0)	     # link map
    194      1.4  christos      jr	    t3 */
    195      1.1      matt 
    196      1.4  christos   entry[0] = RISCV_UTYPE (AUIPC, X_T2, gotplt_offset_high);
    197      1.4  christos   entry[1] = RISCV_RTYPE (SUB, X_T1, X_T1, X_T3);
    198      1.4  christos   entry[2] = RISCV_ITYPE (LREG, X_T3, X_T2, gotplt_offset_low);
    199      1.1      matt   entry[3] = RISCV_ITYPE (ADDI, X_T1, X_T1, -(PLT_HEADER_SIZE + 12));
    200      1.4  christos   entry[4] = RISCV_ITYPE (ADDI, X_T0, X_T2, gotplt_offset_low);
    201      1.1      matt   entry[5] = RISCV_ITYPE (SRLI, X_T1, X_T1, 4 - RISCV_ELF_LOG_WORD_BYTES);
    202      1.1      matt   entry[6] = RISCV_ITYPE (LREG, X_T0, X_T0, RISCV_ELF_WORD_BYTES);
    203      1.1      matt   entry[7] = RISCV_ITYPE (JALR, 0, X_T3, 0);
    204  1.4.2.2    martin 
    205  1.4.2.2    martin   return TRUE;
    206      1.1      matt }
    207      1.1      matt 
    208      1.4  christos /* Generate a PLT entry.  */
    209      1.1      matt 
    210  1.4.2.2    martin static bfd_boolean
    211  1.4.2.2    martin riscv_make_plt_entry (bfd *output_bfd, bfd_vma got, bfd_vma addr,
    212  1.4.2.2    martin 		      uint32_t *entry)
    213      1.1      matt {
    214  1.4.2.2    martin   /* RVE has no t3 register, so this won't work, and is not supported.  */
    215  1.4.2.2    martin   if (elf_elfheader (output_bfd)->e_flags & EF_RISCV_RVE)
    216  1.4.2.2    martin     {
    217  1.4.2.2    martin       _bfd_error_handler (_("%pB: warning: RVE PLT generation not supported"),
    218  1.4.2.2    martin 			  output_bfd);
    219  1.4.2.2    martin       return FALSE;
    220  1.4.2.2    martin     }
    221  1.4.2.2    martin 
    222      1.4  christos   /* auipc  t3, %hi(.got.plt entry)
    223      1.4  christos      l[w|d] t3, %lo(.got.plt entry)(t3)
    224      1.4  christos      jalr   t1, t3
    225      1.1      matt      nop */
    226      1.1      matt 
    227      1.4  christos   entry[0] = RISCV_UTYPE (AUIPC, X_T3, RISCV_PCREL_HIGH_PART (got, addr));
    228      1.4  christos   entry[1] = RISCV_ITYPE (LREG,  X_T3, X_T3, RISCV_PCREL_LOW_PART (got, addr));
    229      1.4  christos   entry[2] = RISCV_ITYPE (JALR, X_T1, X_T3, 0);
    230      1.1      matt   entry[3] = RISCV_NOP;
    231  1.4.2.2    martin 
    232  1.4.2.2    martin   return TRUE;
    233      1.1      matt }
    234      1.1      matt 
    235      1.1      matt /* Create an entry in an RISC-V ELF linker hash table.  */
    236      1.1      matt 
    237      1.1      matt static struct bfd_hash_entry *
    238      1.1      matt link_hash_newfunc (struct bfd_hash_entry *entry,
    239      1.1      matt 		   struct bfd_hash_table *table, const char *string)
    240      1.1      matt {
    241      1.1      matt   /* Allocate the structure if it has not already been allocated by a
    242      1.1      matt      subclass.  */
    243      1.1      matt   if (entry == NULL)
    244      1.1      matt     {
    245      1.1      matt       entry =
    246      1.1      matt 	bfd_hash_allocate (table,
    247      1.1      matt 			   sizeof (struct riscv_elf_link_hash_entry));
    248      1.1      matt       if (entry == NULL)
    249      1.1      matt 	return entry;
    250      1.1      matt     }
    251      1.1      matt 
    252      1.1      matt   /* Call the allocation method of the superclass.  */
    253      1.1      matt   entry = _bfd_elf_link_hash_newfunc (entry, table, string);
    254      1.1      matt   if (entry != NULL)
    255      1.1      matt     {
    256      1.1      matt       struct riscv_elf_link_hash_entry *eh;
    257      1.1      matt 
    258      1.1      matt       eh = (struct riscv_elf_link_hash_entry *) entry;
    259      1.1      matt       eh->dyn_relocs = NULL;
    260      1.1      matt       eh->tls_type = GOT_UNKNOWN;
    261      1.1      matt     }
    262      1.1      matt 
    263      1.1      matt   return entry;
    264      1.1      matt }
    265      1.1      matt 
    266      1.1      matt /* Create a RISC-V ELF linker hash table.  */
    267      1.1      matt 
    268      1.1      matt static struct bfd_link_hash_table *
    269      1.1      matt riscv_elf_link_hash_table_create (bfd *abfd)
    270      1.1      matt {
    271      1.1      matt   struct riscv_elf_link_hash_table *ret;
    272      1.1      matt   bfd_size_type amt = sizeof (struct riscv_elf_link_hash_table);
    273      1.1      matt 
    274      1.1      matt   ret = (struct riscv_elf_link_hash_table *) bfd_zmalloc (amt);
    275      1.1      matt   if (ret == NULL)
    276      1.1      matt     return NULL;
    277      1.1      matt 
    278      1.1      matt   if (!_bfd_elf_link_hash_table_init (&ret->elf, abfd, link_hash_newfunc,
    279      1.1      matt 				      sizeof (struct riscv_elf_link_hash_entry),
    280      1.1      matt 				      RISCV_ELF_DATA))
    281      1.1      matt     {
    282      1.1      matt       free (ret);
    283      1.1      matt       return NULL;
    284      1.1      matt     }
    285      1.1      matt 
    286      1.4  christos   ret->max_alignment = (bfd_vma) -1;
    287      1.1      matt   return &ret->elf.root;
    288      1.1      matt }
    289      1.1      matt 
    290      1.1      matt /* Create the .got section.  */
    291      1.1      matt 
    292      1.1      matt static bfd_boolean
    293      1.1      matt riscv_elf_create_got_section (bfd *abfd, struct bfd_link_info *info)
    294      1.1      matt {
    295      1.1      matt   flagword flags;
    296      1.1      matt   asection *s, *s_got;
    297      1.1      matt   struct elf_link_hash_entry *h;
    298      1.1      matt   const struct elf_backend_data *bed = get_elf_backend_data (abfd);
    299      1.1      matt   struct elf_link_hash_table *htab = elf_hash_table (info);
    300      1.1      matt 
    301      1.1      matt   /* This function may be called more than once.  */
    302      1.4  christos   if (htab->sgot != NULL)
    303      1.1      matt     return TRUE;
    304      1.1      matt 
    305      1.1      matt   flags = bed->dynamic_sec_flags;
    306      1.1      matt 
    307      1.1      matt   s = bfd_make_section_anyway_with_flags (abfd,
    308      1.1      matt 					  (bed->rela_plts_and_copies_p
    309      1.1      matt 					   ? ".rela.got" : ".rel.got"),
    310      1.1      matt 					  (bed->dynamic_sec_flags
    311      1.1      matt 					   | SEC_READONLY));
    312      1.1      matt   if (s == NULL
    313  1.4.2.2    martin       || !bfd_set_section_alignment (s, bed->s->log_file_align))
    314      1.1      matt     return FALSE;
    315      1.1      matt   htab->srelgot = s;
    316      1.1      matt 
    317      1.1      matt   s = s_got = bfd_make_section_anyway_with_flags (abfd, ".got", flags);
    318      1.1      matt   if (s == NULL
    319  1.4.2.2    martin       || !bfd_set_section_alignment (s, bed->s->log_file_align))
    320      1.1      matt     return FALSE;
    321      1.1      matt   htab->sgot = s;
    322      1.1      matt 
    323      1.1      matt   /* The first bit of the global offset table is the header.  */
    324      1.1      matt   s->size += bed->got_header_size;
    325      1.1      matt 
    326      1.1      matt   if (bed->want_got_plt)
    327      1.1      matt     {
    328      1.1      matt       s = bfd_make_section_anyway_with_flags (abfd, ".got.plt", flags);
    329      1.1      matt       if (s == NULL
    330  1.4.2.2    martin 	  || !bfd_set_section_alignment (s, bed->s->log_file_align))
    331      1.1      matt 	return FALSE;
    332      1.1      matt       htab->sgotplt = s;
    333      1.1      matt 
    334      1.1      matt       /* Reserve room for the header.  */
    335      1.1      matt       s->size += GOTPLT_HEADER_SIZE;
    336      1.1      matt     }
    337      1.1      matt 
    338      1.1      matt   if (bed->want_got_sym)
    339      1.1      matt     {
    340      1.1      matt       /* Define the symbol _GLOBAL_OFFSET_TABLE_ at the start of the .got
    341      1.1      matt 	 section.  We don't do this in the linker script because we don't want
    342      1.1      matt 	 to define the symbol if we are not creating a global offset
    343      1.1      matt 	 table.  */
    344      1.1      matt       h = _bfd_elf_define_linkage_sym (abfd, info, s_got,
    345      1.1      matt 				       "_GLOBAL_OFFSET_TABLE_");
    346      1.1      matt       elf_hash_table (info)->hgot = h;
    347      1.1      matt       if (h == NULL)
    348      1.1      matt 	return FALSE;
    349      1.1      matt     }
    350      1.1      matt 
    351      1.1      matt   return TRUE;
    352      1.1      matt }
    353      1.1      matt 
    354      1.1      matt /* Create .plt, .rela.plt, .got, .got.plt, .rela.got, .dynbss, and
    355      1.1      matt    .rela.bss sections in DYNOBJ, and set up shortcuts to them in our
    356      1.1      matt    hash table.  */
    357      1.1      matt 
    358      1.1      matt static bfd_boolean
    359      1.1      matt riscv_elf_create_dynamic_sections (bfd *dynobj,
    360      1.1      matt 				   struct bfd_link_info *info)
    361      1.1      matt {
    362      1.1      matt   struct riscv_elf_link_hash_table *htab;
    363      1.1      matt 
    364      1.1      matt   htab = riscv_elf_hash_table (info);
    365      1.1      matt   BFD_ASSERT (htab != NULL);
    366      1.1      matt 
    367      1.1      matt   if (!riscv_elf_create_got_section (dynobj, info))
    368      1.1      matt     return FALSE;
    369      1.1      matt 
    370      1.1      matt   if (!_bfd_elf_create_dynamic_sections (dynobj, info))
    371      1.1      matt     return FALSE;
    372      1.1      matt 
    373      1.3  christos   if (!bfd_link_pic (info))
    374      1.1      matt     {
    375  1.4.2.2    martin       /* Technically, this section doesn't have contents.  It is used as the
    376  1.4.2.2    martin 	 target of TLS copy relocs, to copy TLS data from shared libraries into
    377  1.4.2.2    martin 	 the executable.  However, if we don't mark it as loadable, then it
    378  1.4.2.2    martin 	 matches the IS_TBSS test in ldlang.c, and there is no run-time address
    379  1.4.2.2    martin 	 space allocated for it even though it has SEC_ALLOC.  That test is
    380  1.4.2.2    martin 	 correct for .tbss, but not correct for this section.  There is also
    381  1.4.2.2    martin 	 a second problem that having a section with no contents can only work
    382  1.4.2.2    martin 	 if it comes after all sections with contents in the same segment,
    383  1.4.2.2    martin 	 but the linker script does not guarantee that.  This is just mixed in
    384  1.4.2.2    martin 	 with other .tdata.* sections.  We can fix both problems by lying and
    385  1.4.2.2    martin 	 saying that there are contents.  This section is expected to be small
    386  1.4.2.2    martin 	 so this should not cause a significant extra program startup cost.  */
    387      1.1      matt       htab->sdyntdata =
    388      1.1      matt 	bfd_make_section_anyway_with_flags (dynobj, ".tdata.dyn",
    389  1.4.2.2    martin 					    (SEC_ALLOC | SEC_THREAD_LOCAL
    390  1.4.2.2    martin 					     | SEC_LOAD | SEC_DATA
    391  1.4.2.2    martin 					     | SEC_HAS_CONTENTS
    392  1.4.2.2    martin 					     | SEC_LINKER_CREATED));
    393      1.1      matt     }
    394      1.1      matt 
    395      1.4  christos   if (!htab->elf.splt || !htab->elf.srelplt || !htab->elf.sdynbss
    396      1.4  christos       || (!bfd_link_pic (info) && (!htab->elf.srelbss || !htab->sdyntdata)))
    397      1.1      matt     abort ();
    398      1.1      matt 
    399      1.1      matt   return TRUE;
    400      1.1      matt }
    401      1.1      matt 
    402      1.1      matt /* Copy the extra info we tack onto an elf_link_hash_entry.  */
    403      1.1      matt 
    404      1.1      matt static void
    405      1.1      matt riscv_elf_copy_indirect_symbol (struct bfd_link_info *info,
    406      1.1      matt 				struct elf_link_hash_entry *dir,
    407      1.1      matt 				struct elf_link_hash_entry *ind)
    408      1.1      matt {
    409      1.1      matt   struct riscv_elf_link_hash_entry *edir, *eind;
    410      1.1      matt 
    411      1.1      matt   edir = (struct riscv_elf_link_hash_entry *) dir;
    412      1.1      matt   eind = (struct riscv_elf_link_hash_entry *) ind;
    413      1.1      matt 
    414      1.1      matt   if (eind->dyn_relocs != NULL)
    415      1.1      matt     {
    416      1.1      matt       if (edir->dyn_relocs != NULL)
    417      1.1      matt 	{
    418      1.4  christos 	  struct elf_dyn_relocs **pp;
    419      1.4  christos 	  struct elf_dyn_relocs *p;
    420      1.1      matt 
    421      1.1      matt 	  /* Add reloc counts against the indirect sym to the direct sym
    422      1.1      matt 	     list.  Merge any entries against the same section.  */
    423      1.1      matt 	  for (pp = &eind->dyn_relocs; (p = *pp) != NULL; )
    424      1.1      matt 	    {
    425      1.4  christos 	      struct elf_dyn_relocs *q;
    426      1.1      matt 
    427      1.1      matt 	      for (q = edir->dyn_relocs; q != NULL; q = q->next)
    428      1.1      matt 		if (q->sec == p->sec)
    429      1.1      matt 		  {
    430      1.1      matt 		    q->pc_count += p->pc_count;
    431      1.1      matt 		    q->count += p->count;
    432      1.1      matt 		    *pp = p->next;
    433      1.1      matt 		    break;
    434      1.1      matt 		  }
    435      1.1      matt 	      if (q == NULL)
    436      1.1      matt 		pp = &p->next;
    437      1.1      matt 	    }
    438      1.1      matt 	  *pp = edir->dyn_relocs;
    439      1.1      matt 	}
    440      1.1      matt 
    441      1.1      matt       edir->dyn_relocs = eind->dyn_relocs;
    442      1.1      matt       eind->dyn_relocs = NULL;
    443      1.1      matt     }
    444      1.1      matt 
    445      1.1      matt   if (ind->root.type == bfd_link_hash_indirect
    446      1.1      matt       && dir->got.refcount <= 0)
    447      1.1      matt     {
    448      1.1      matt       edir->tls_type = eind->tls_type;
    449      1.1      matt       eind->tls_type = GOT_UNKNOWN;
    450      1.1      matt     }
    451      1.1      matt   _bfd_elf_link_hash_copy_indirect (info, dir, ind);
    452      1.1      matt }
    453      1.1      matt 
    454      1.1      matt static bfd_boolean
    455      1.1      matt riscv_elf_record_tls_type (bfd *abfd, struct elf_link_hash_entry *h,
    456      1.1      matt 			   unsigned long symndx, char tls_type)
    457      1.1      matt {
    458      1.1      matt   char *new_tls_type = &_bfd_riscv_elf_tls_type (abfd, h, symndx);
    459      1.4  christos 
    460      1.1      matt   *new_tls_type |= tls_type;
    461      1.1      matt   if ((*new_tls_type & GOT_NORMAL) && (*new_tls_type & ~GOT_NORMAL))
    462      1.1      matt     {
    463      1.1      matt       (*_bfd_error_handler)
    464  1.4.2.1  christos 	(_("%pB: `%s' accessed both as normal and thread local symbol"),
    465      1.1      matt 	 abfd, h ? h->root.root.string : "<local>");
    466      1.1      matt       return FALSE;
    467      1.1      matt     }
    468      1.1      matt   return TRUE;
    469      1.1      matt }
    470      1.1      matt 
    471      1.1      matt static bfd_boolean
    472      1.1      matt riscv_elf_record_got_reference (bfd *abfd, struct bfd_link_info *info,
    473      1.1      matt 				struct elf_link_hash_entry *h, long symndx)
    474      1.1      matt {
    475      1.1      matt   struct riscv_elf_link_hash_table *htab = riscv_elf_hash_table (info);
    476      1.1      matt   Elf_Internal_Shdr *symtab_hdr = &elf_tdata (abfd)->symtab_hdr;
    477      1.1      matt 
    478      1.1      matt   if (htab->elf.sgot == NULL)
    479      1.1      matt     {
    480      1.1      matt       if (!riscv_elf_create_got_section (htab->elf.dynobj, info))
    481      1.4  christos 	return FALSE;
    482      1.1      matt     }
    483      1.1      matt 
    484      1.1      matt   if (h != NULL)
    485      1.1      matt     {
    486      1.1      matt       h->got.refcount += 1;
    487      1.1      matt       return TRUE;
    488      1.1      matt     }
    489      1.1      matt 
    490      1.1      matt   /* This is a global offset table entry for a local symbol.  */
    491      1.1      matt   if (elf_local_got_refcounts (abfd) == NULL)
    492      1.1      matt     {
    493      1.1      matt       bfd_size_type size = symtab_hdr->sh_info * (sizeof (bfd_vma) + 1);
    494      1.1      matt       if (!(elf_local_got_refcounts (abfd) = bfd_zalloc (abfd, size)))
    495      1.1      matt 	return FALSE;
    496      1.1      matt       _bfd_riscv_elf_local_got_tls_type (abfd)
    497      1.1      matt 	= (char *) (elf_local_got_refcounts (abfd) + symtab_hdr->sh_info);
    498      1.1      matt     }
    499      1.1      matt   elf_local_got_refcounts (abfd) [symndx] += 1;
    500      1.1      matt 
    501      1.1      matt   return TRUE;
    502      1.1      matt }
    503      1.1      matt 
    504      1.1      matt static bfd_boolean
    505      1.1      matt bad_static_reloc (bfd *abfd, unsigned r_type, struct elf_link_hash_entry *h)
    506      1.1      matt {
    507  1.4.2.1  christos   reloc_howto_type * r = riscv_elf_rtype_to_howto (abfd, r_type);
    508  1.4.2.1  christos 
    509      1.1      matt   (*_bfd_error_handler)
    510  1.4.2.1  christos     (_("%pB: relocation %s against `%s' can not be used when making a shared "
    511      1.4  christos        "object; recompile with -fPIC"),
    512  1.4.2.1  christos      abfd, r ? r->name : _("<unknown>"),
    513  1.4.2.1  christos      h != NULL ? h->root.root.string : "a local symbol");
    514      1.1      matt   bfd_set_error (bfd_error_bad_value);
    515      1.1      matt   return FALSE;
    516      1.1      matt }
    517      1.1      matt /* Look through the relocs for a section during the first phase, and
    518      1.1      matt    allocate space in the global offset table or procedure linkage
    519      1.1      matt    table.  */
    520      1.1      matt 
    521      1.1      matt static bfd_boolean
    522      1.1      matt riscv_elf_check_relocs (bfd *abfd, struct bfd_link_info *info,
    523      1.1      matt 			asection *sec, const Elf_Internal_Rela *relocs)
    524      1.1      matt {
    525      1.1      matt   struct riscv_elf_link_hash_table *htab;
    526      1.1      matt   Elf_Internal_Shdr *symtab_hdr;
    527      1.1      matt   struct elf_link_hash_entry **sym_hashes;
    528      1.1      matt   const Elf_Internal_Rela *rel;
    529      1.1      matt   asection *sreloc = NULL;
    530      1.1      matt 
    531      1.3  christos   if (bfd_link_relocatable (info))
    532      1.1      matt     return TRUE;
    533      1.1      matt 
    534      1.1      matt   htab = riscv_elf_hash_table (info);
    535      1.1      matt   symtab_hdr = &elf_tdata (abfd)->symtab_hdr;
    536      1.1      matt   sym_hashes = elf_sym_hashes (abfd);
    537      1.1      matt 
    538      1.1      matt   if (htab->elf.dynobj == NULL)
    539      1.1      matt     htab->elf.dynobj = abfd;
    540      1.1      matt 
    541      1.1      matt   for (rel = relocs; rel < relocs + sec->reloc_count; rel++)
    542      1.1      matt     {
    543      1.1      matt       unsigned int r_type;
    544      1.4  christos       unsigned int r_symndx;
    545      1.1      matt       struct elf_link_hash_entry *h;
    546      1.1      matt 
    547      1.1      matt       r_symndx = ELFNN_R_SYM (rel->r_info);
    548      1.1      matt       r_type = ELFNN_R_TYPE (rel->r_info);
    549      1.1      matt 
    550      1.1      matt       if (r_symndx >= NUM_SHDR_ENTRIES (symtab_hdr))
    551      1.1      matt 	{
    552  1.4.2.1  christos 	  (*_bfd_error_handler) (_("%pB: bad symbol index: %d"),
    553      1.1      matt 				 abfd, r_symndx);
    554      1.1      matt 	  return FALSE;
    555      1.1      matt 	}
    556      1.1      matt 
    557      1.1      matt       if (r_symndx < symtab_hdr->sh_info)
    558      1.1      matt 	h = NULL;
    559      1.1      matt       else
    560      1.1      matt 	{
    561      1.1      matt 	  h = sym_hashes[r_symndx - symtab_hdr->sh_info];
    562      1.1      matt 	  while (h->root.type == bfd_link_hash_indirect
    563      1.1      matt 		 || h->root.type == bfd_link_hash_warning)
    564      1.1      matt 	    h = (struct elf_link_hash_entry *) h->root.u.i.link;
    565      1.1      matt 	}
    566      1.1      matt 
    567      1.1      matt       switch (r_type)
    568      1.1      matt 	{
    569      1.1      matt 	case R_RISCV_TLS_GD_HI20:
    570      1.1      matt 	  if (!riscv_elf_record_got_reference (abfd, info, h, r_symndx)
    571      1.1      matt 	      || !riscv_elf_record_tls_type (abfd, h, r_symndx, GOT_TLS_GD))
    572      1.1      matt 	    return FALSE;
    573      1.1      matt 	  break;
    574      1.1      matt 
    575      1.1      matt 	case R_RISCV_TLS_GOT_HI20:
    576      1.3  christos 	  if (bfd_link_pic (info))
    577      1.1      matt 	    info->flags |= DF_STATIC_TLS;
    578      1.1      matt 	  if (!riscv_elf_record_got_reference (abfd, info, h, r_symndx)
    579      1.1      matt 	      || !riscv_elf_record_tls_type (abfd, h, r_symndx, GOT_TLS_IE))
    580      1.1      matt 	    return FALSE;
    581      1.1      matt 	  break;
    582      1.1      matt 
    583      1.1      matt 	case R_RISCV_GOT_HI20:
    584      1.1      matt 	  if (!riscv_elf_record_got_reference (abfd, info, h, r_symndx)
    585      1.1      matt 	      || !riscv_elf_record_tls_type (abfd, h, r_symndx, GOT_NORMAL))
    586      1.1      matt 	    return FALSE;
    587      1.1      matt 	  break;
    588      1.1      matt 
    589      1.1      matt 	case R_RISCV_CALL_PLT:
    590      1.1      matt 	  /* This symbol requires a procedure linkage table entry.  We
    591      1.1      matt 	     actually build the entry in adjust_dynamic_symbol,
    592      1.1      matt 	     because this might be a case of linking PIC code without
    593      1.1      matt 	     linking in any dynamic objects, in which case we don't
    594      1.1      matt 	     need to generate a procedure linkage table after all.  */
    595      1.1      matt 
    596      1.1      matt 	  if (h != NULL)
    597      1.1      matt 	    {
    598      1.1      matt 	      h->needs_plt = 1;
    599      1.1      matt 	      h->plt.refcount += 1;
    600      1.1      matt 	    }
    601      1.1      matt 	  break;
    602      1.1      matt 
    603      1.1      matt 	case R_RISCV_CALL:
    604      1.1      matt 	case R_RISCV_JAL:
    605      1.1      matt 	case R_RISCV_BRANCH:
    606      1.4  christos 	case R_RISCV_RVC_BRANCH:
    607      1.4  christos 	case R_RISCV_RVC_JUMP:
    608      1.1      matt 	case R_RISCV_PCREL_HI20:
    609      1.4  christos 	  /* In shared libraries, these relocs are known to bind locally.  */
    610      1.3  christos 	  if (bfd_link_pic (info))
    611      1.1      matt 	    break;
    612      1.1      matt 	  goto static_reloc;
    613      1.1      matt 
    614      1.1      matt 	case R_RISCV_TPREL_HI20:
    615      1.3  christos 	  if (!bfd_link_executable (info))
    616      1.1      matt 	    return bad_static_reloc (abfd, r_type, h);
    617      1.1      matt 	  if (h != NULL)
    618      1.1      matt 	    riscv_elf_record_tls_type (abfd, h, r_symndx, GOT_TLS_LE);
    619      1.1      matt 	  goto static_reloc;
    620      1.1      matt 
    621      1.1      matt 	case R_RISCV_HI20:
    622      1.3  christos 	  if (bfd_link_pic (info))
    623      1.1      matt 	    return bad_static_reloc (abfd, r_type, h);
    624      1.1      matt 	  /* Fall through.  */
    625      1.1      matt 
    626      1.1      matt 	case R_RISCV_COPY:
    627      1.1      matt 	case R_RISCV_JUMP_SLOT:
    628      1.1      matt 	case R_RISCV_RELATIVE:
    629      1.1      matt 	case R_RISCV_64:
    630      1.1      matt 	case R_RISCV_32:
    631      1.1      matt 	  /* Fall through.  */
    632      1.1      matt 
    633      1.1      matt 	static_reloc:
    634      1.4  christos 	  /* This reloc might not bind locally.  */
    635      1.1      matt 	  if (h != NULL)
    636      1.1      matt 	    h->non_got_ref = 1;
    637      1.1      matt 
    638      1.3  christos 	  if (h != NULL && !bfd_link_pic (info))
    639      1.1      matt 	    {
    640      1.1      matt 	      /* We may need a .plt entry if the function this reloc
    641      1.1      matt 		 refers to is in a shared lib.  */
    642      1.1      matt 	      h->plt.refcount += 1;
    643      1.1      matt 	    }
    644      1.1      matt 
    645      1.1      matt 	  /* If we are creating a shared library, and this is a reloc
    646      1.1      matt 	     against a global symbol, or a non PC relative reloc
    647      1.1      matt 	     against a local symbol, then we need to copy the reloc
    648      1.1      matt 	     into the shared library.  However, if we are linking with
    649      1.1      matt 	     -Bsymbolic, we do not need to copy a reloc against a
    650      1.1      matt 	     global symbol which is defined in an object we are
    651      1.1      matt 	     including in the link (i.e., DEF_REGULAR is set).  At
    652      1.1      matt 	     this point we have not seen all the input files, so it is
    653      1.1      matt 	     possible that DEF_REGULAR is not set now but will be set
    654      1.1      matt 	     later (it is never cleared).  In case of a weak definition,
    655      1.1      matt 	     DEF_REGULAR may be cleared later by a strong definition in
    656      1.1      matt 	     a shared library.  We account for that possibility below by
    657      1.1      matt 	     storing information in the relocs_copied field of the hash
    658      1.1      matt 	     table entry.  A similar situation occurs when creating
    659      1.1      matt 	     shared libraries and symbol visibility changes render the
    660      1.1      matt 	     symbol local.
    661      1.1      matt 
    662      1.1      matt 	     If on the other hand, we are creating an executable, we
    663      1.1      matt 	     may need to keep relocations for symbols satisfied by a
    664      1.1      matt 	     dynamic library if we manage to avoid copy relocs for the
    665      1.1      matt 	     symbol.  */
    666  1.4.2.1  christos 	  reloc_howto_type * r = riscv_elf_rtype_to_howto (abfd, r_type);
    667  1.4.2.1  christos 
    668      1.3  christos 	  if ((bfd_link_pic (info)
    669      1.1      matt 	       && (sec->flags & SEC_ALLOC) != 0
    670  1.4.2.1  christos 	       && ((r != NULL && ! r->pc_relative)
    671      1.1      matt 		   || (h != NULL
    672      1.1      matt 		       && (! info->symbolic
    673      1.1      matt 			   || h->root.type == bfd_link_hash_defweak
    674      1.1      matt 			   || !h->def_regular))))
    675      1.3  christos 	      || (!bfd_link_pic (info)
    676      1.1      matt 		  && (sec->flags & SEC_ALLOC) != 0
    677      1.1      matt 		  && h != NULL
    678      1.1      matt 		  && (h->root.type == bfd_link_hash_defweak
    679      1.1      matt 		      || !h->def_regular)))
    680      1.1      matt 	    {
    681      1.4  christos 	      struct elf_dyn_relocs *p;
    682      1.4  christos 	      struct elf_dyn_relocs **head;
    683      1.1      matt 
    684      1.1      matt 	      /* When creating a shared object, we must copy these
    685      1.1      matt 		 relocs into the output file.  We create a reloc
    686      1.1      matt 		 section in dynobj and make room for the reloc.  */
    687      1.1      matt 	      if (sreloc == NULL)
    688      1.1      matt 		{
    689      1.1      matt 		  sreloc = _bfd_elf_make_dynamic_reloc_section
    690      1.1      matt 		    (sec, htab->elf.dynobj, RISCV_ELF_LOG_WORD_BYTES,
    691      1.1      matt 		    abfd, /*rela?*/ TRUE);
    692      1.1      matt 
    693      1.1      matt 		  if (sreloc == NULL)
    694      1.1      matt 		    return FALSE;
    695      1.1      matt 		}
    696      1.1      matt 
    697      1.1      matt 	      /* If this is a global symbol, we count the number of
    698      1.1      matt 		 relocations we need for this symbol.  */
    699      1.1      matt 	      if (h != NULL)
    700      1.1      matt 		head = &((struct riscv_elf_link_hash_entry *) h)->dyn_relocs;
    701      1.1      matt 	      else
    702      1.1      matt 		{
    703      1.1      matt 		  /* Track dynamic relocs needed for local syms too.
    704      1.1      matt 		     We really need local syms available to do this
    705      1.1      matt 		     easily.  Oh well.  */
    706      1.1      matt 
    707      1.1      matt 		  asection *s;
    708      1.1      matt 		  void *vpp;
    709      1.1      matt 		  Elf_Internal_Sym *isym;
    710      1.1      matt 
    711      1.1      matt 		  isym = bfd_sym_from_r_symndx (&htab->sym_cache,
    712      1.1      matt 						abfd, r_symndx);
    713      1.1      matt 		  if (isym == NULL)
    714      1.1      matt 		    return FALSE;
    715      1.1      matt 
    716      1.1      matt 		  s = bfd_section_from_elf_index (abfd, isym->st_shndx);
    717      1.1      matt 		  if (s == NULL)
    718      1.1      matt 		    s = sec;
    719      1.1      matt 
    720      1.1      matt 		  vpp = &elf_section_data (s)->local_dynrel;
    721      1.4  christos 		  head = (struct elf_dyn_relocs **) vpp;
    722      1.1      matt 		}
    723      1.1      matt 
    724      1.1      matt 	      p = *head;
    725      1.1      matt 	      if (p == NULL || p->sec != sec)
    726      1.1      matt 		{
    727      1.1      matt 		  bfd_size_type amt = sizeof *p;
    728      1.4  christos 		  p = ((struct elf_dyn_relocs *)
    729      1.1      matt 		       bfd_alloc (htab->elf.dynobj, amt));
    730      1.1      matt 		  if (p == NULL)
    731      1.1      matt 		    return FALSE;
    732      1.1      matt 		  p->next = *head;
    733      1.1      matt 		  *head = p;
    734      1.1      matt 		  p->sec = sec;
    735      1.1      matt 		  p->count = 0;
    736      1.1      matt 		  p->pc_count = 0;
    737      1.1      matt 		}
    738      1.1      matt 
    739      1.1      matt 	      p->count += 1;
    740  1.4.2.1  christos 	      p->pc_count += r == NULL ? 0 : r->pc_relative;
    741      1.1      matt 	    }
    742      1.1      matt 
    743      1.1      matt 	  break;
    744      1.1      matt 
    745      1.1      matt 	case R_RISCV_GNU_VTINHERIT:
    746      1.1      matt 	  if (!bfd_elf_gc_record_vtinherit (abfd, sec, h, rel->r_offset))
    747      1.1      matt 	    return FALSE;
    748      1.1      matt 	  break;
    749      1.1      matt 
    750      1.1      matt 	case R_RISCV_GNU_VTENTRY:
    751      1.1      matt 	  if (!bfd_elf_gc_record_vtentry (abfd, sec, h, rel->r_addend))
    752      1.1      matt 	    return FALSE;
    753      1.1      matt 	  break;
    754      1.1      matt 
    755      1.1      matt 	default:
    756      1.1      matt 	  break;
    757      1.1      matt 	}
    758      1.1      matt     }
    759      1.1      matt 
    760      1.1      matt   return TRUE;
    761      1.1      matt }
    762      1.1      matt 
    763      1.1      matt static asection *
    764      1.1      matt riscv_elf_gc_mark_hook (asection *sec,
    765      1.1      matt 			struct bfd_link_info *info,
    766      1.1      matt 			Elf_Internal_Rela *rel,
    767      1.1      matt 			struct elf_link_hash_entry *h,
    768      1.1      matt 			Elf_Internal_Sym *sym)
    769      1.1      matt {
    770      1.1      matt   if (h != NULL)
    771      1.1      matt     switch (ELFNN_R_TYPE (rel->r_info))
    772      1.1      matt       {
    773      1.1      matt       case R_RISCV_GNU_VTINHERIT:
    774      1.1      matt       case R_RISCV_GNU_VTENTRY:
    775      1.1      matt 	return NULL;
    776      1.1      matt       }
    777      1.1      matt 
    778      1.1      matt   return _bfd_elf_gc_mark_hook (sec, info, rel, h, sym);
    779      1.1      matt }
    780      1.1      matt 
    781      1.4  christos /* Find dynamic relocs for H that apply to read-only sections.  */
    782      1.4  christos 
    783      1.4  christos static asection *
    784      1.4  christos readonly_dynrelocs (struct elf_link_hash_entry *h)
    785      1.1      matt {
    786      1.4  christos   struct elf_dyn_relocs *p;
    787      1.1      matt 
    788      1.4  christos   for (p = riscv_elf_hash_entry (h)->dyn_relocs; p != NULL; p = p->next)
    789      1.1      matt     {
    790      1.4  christos       asection *s = p->sec->output_section;
    791      1.1      matt 
    792      1.4  christos       if (s != NULL && (s->flags & SEC_READONLY) != 0)
    793      1.4  christos 	return p->sec;
    794      1.1      matt     }
    795      1.4  christos   return NULL;
    796      1.1      matt }
    797      1.1      matt 
    798      1.1      matt /* Adjust a symbol defined by a dynamic object and referenced by a
    799      1.1      matt    regular object.  The current definition is in some section of the
    800      1.1      matt    dynamic object, but we're not including those sections.  We have to
    801      1.1      matt    change the definition to something the rest of the link can
    802      1.1      matt    understand.  */
    803      1.1      matt 
    804      1.1      matt static bfd_boolean
    805      1.1      matt riscv_elf_adjust_dynamic_symbol (struct bfd_link_info *info,
    806      1.1      matt 				 struct elf_link_hash_entry *h)
    807      1.1      matt {
    808      1.1      matt   struct riscv_elf_link_hash_table *htab;
    809      1.1      matt   struct riscv_elf_link_hash_entry * eh;
    810      1.1      matt   bfd *dynobj;
    811      1.4  christos   asection *s, *srel;
    812      1.1      matt 
    813      1.1      matt   htab = riscv_elf_hash_table (info);
    814      1.1      matt   BFD_ASSERT (htab != NULL);
    815      1.1      matt 
    816      1.1      matt   dynobj = htab->elf.dynobj;
    817      1.1      matt 
    818      1.1      matt   /* Make sure we know what is going on here.  */
    819      1.1      matt   BFD_ASSERT (dynobj != NULL
    820      1.1      matt 	      && (h->needs_plt
    821      1.2      matt 		  || h->type == STT_GNU_IFUNC
    822      1.4  christos 		  || h->is_weakalias
    823      1.1      matt 		  || (h->def_dynamic
    824      1.1      matt 		      && h->ref_regular
    825      1.1      matt 		      && !h->def_regular)));
    826      1.1      matt 
    827      1.1      matt   /* If this is a function, put it in the procedure linkage table.  We
    828      1.1      matt      will fill in the contents of the procedure linkage table later
    829      1.1      matt      (although we could actually do it here).  */
    830      1.2      matt   if (h->type == STT_FUNC || h->type == STT_GNU_IFUNC || h->needs_plt)
    831      1.1      matt     {
    832      1.1      matt       if (h->plt.refcount <= 0
    833      1.1      matt 	  || SYMBOL_CALLS_LOCAL (info, h)
    834      1.1      matt 	  || (ELF_ST_VISIBILITY (h->other) != STV_DEFAULT
    835      1.1      matt 	      && h->root.type == bfd_link_hash_undefweak))
    836      1.1      matt 	{
    837      1.1      matt 	  /* This case can occur if we saw a R_RISCV_CALL_PLT reloc in an
    838      1.1      matt 	     input file, but the symbol was never referred to by a dynamic
    839      1.1      matt 	     object, or if all references were garbage collected.  In such
    840      1.1      matt 	     a case, we don't actually need to build a PLT entry.  */
    841      1.1      matt 	  h->plt.offset = (bfd_vma) -1;
    842      1.1      matt 	  h->needs_plt = 0;
    843      1.1      matt 	}
    844      1.1      matt 
    845      1.1      matt       return TRUE;
    846      1.1      matt     }
    847      1.1      matt   else
    848      1.1      matt     h->plt.offset = (bfd_vma) -1;
    849      1.1      matt 
    850      1.1      matt   /* If this is a weak symbol, and there is a real definition, the
    851      1.1      matt      processor independent code will have arranged for us to see the
    852      1.1      matt      real definition first, and we can just use the same value.  */
    853      1.4  christos   if (h->is_weakalias)
    854      1.1      matt     {
    855      1.4  christos       struct elf_link_hash_entry *def = weakdef (h);
    856      1.4  christos       BFD_ASSERT (def->root.type == bfd_link_hash_defined);
    857      1.4  christos       h->root.u.def.section = def->root.u.def.section;
    858      1.4  christos       h->root.u.def.value = def->root.u.def.value;
    859      1.1      matt       return TRUE;
    860      1.1      matt     }
    861      1.1      matt 
    862      1.1      matt   /* This is a reference to a symbol defined by a dynamic object which
    863      1.1      matt      is not a function.  */
    864      1.1      matt 
    865      1.1      matt   /* If we are creating a shared library, we must presume that the
    866      1.1      matt      only references to the symbol are via the global offset table.
    867      1.1      matt      For such cases we need not do anything here; the relocations will
    868      1.1      matt      be handled correctly by relocate_section.  */
    869      1.3  christos   if (bfd_link_pic (info))
    870      1.1      matt     return TRUE;
    871      1.1      matt 
    872      1.1      matt   /* If there are no references to this symbol that do not use the
    873      1.1      matt      GOT, we don't need to generate a copy reloc.  */
    874      1.1      matt   if (!h->non_got_ref)
    875      1.1      matt     return TRUE;
    876      1.1      matt 
    877      1.1      matt   /* If -z nocopyreloc was given, we won't generate them either.  */
    878      1.1      matt   if (info->nocopyreloc)
    879      1.1      matt     {
    880      1.1      matt       h->non_got_ref = 0;
    881      1.1      matt       return TRUE;
    882      1.1      matt     }
    883      1.1      matt 
    884      1.4  christos   /* If we don't find any dynamic relocs in read-only sections, then
    885      1.1      matt      we'll be keeping the dynamic relocs and avoiding the copy reloc.  */
    886      1.4  christos   if (!readonly_dynrelocs (h))
    887      1.1      matt     {
    888      1.1      matt       h->non_got_ref = 0;
    889      1.1      matt       return TRUE;
    890      1.1      matt     }
    891      1.1      matt 
    892      1.1      matt   /* We must allocate the symbol in our .dynbss section, which will
    893      1.1      matt      become part of the .bss section of the executable.  There will be
    894      1.1      matt      an entry for this symbol in the .dynsym section.  The dynamic
    895      1.1      matt      object will contain position independent code, so all references
    896      1.1      matt      from the dynamic object to this symbol will go through the global
    897      1.1      matt      offset table.  The dynamic linker will use the .dynsym entry to
    898      1.1      matt      determine the address it must put in the global offset table, so
    899      1.1      matt      both the dynamic object and the regular object will refer to the
    900      1.1      matt      same memory location for the variable.  */
    901      1.1      matt 
    902      1.1      matt   /* We must generate a R_RISCV_COPY reloc to tell the dynamic linker
    903      1.1      matt      to copy the initial value out of the dynamic object and into the
    904      1.1      matt      runtime process image.  We need to remember the offset into the
    905      1.1      matt      .rel.bss section we are going to use.  */
    906      1.4  christos   eh = (struct riscv_elf_link_hash_entry *) h;
    907      1.4  christos   if (eh->tls_type & ~GOT_NORMAL)
    908      1.4  christos     {
    909      1.4  christos       s = htab->sdyntdata;
    910      1.4  christos       srel = htab->elf.srelbss;
    911      1.4  christos     }
    912      1.4  christos   else if ((h->root.u.def.section->flags & SEC_READONLY) != 0)
    913      1.4  christos     {
    914      1.4  christos       s = htab->elf.sdynrelro;
    915      1.4  christos       srel = htab->elf.sreldynrelro;
    916      1.4  christos     }
    917      1.4  christos   else
    918      1.4  christos     {
    919      1.4  christos       s = htab->elf.sdynbss;
    920      1.4  christos       srel = htab->elf.srelbss;
    921      1.4  christos     }
    922      1.1      matt   if ((h->root.u.def.section->flags & SEC_ALLOC) != 0 && h->size != 0)
    923      1.1      matt     {
    924      1.4  christos       srel->size += sizeof (ElfNN_External_Rela);
    925      1.1      matt       h->needs_copy = 1;
    926      1.1      matt     }
    927      1.1      matt 
    928      1.4  christos   return _bfd_elf_adjust_dynamic_copy (info, h, s);
    929      1.1      matt }
    930      1.1      matt 
    931      1.1      matt /* Allocate space in .plt, .got and associated reloc sections for
    932      1.1      matt    dynamic relocs.  */
    933      1.1      matt 
    934      1.1      matt static bfd_boolean
    935      1.1      matt allocate_dynrelocs (struct elf_link_hash_entry *h, void *inf)
    936      1.1      matt {
    937      1.1      matt   struct bfd_link_info *info;
    938      1.1      matt   struct riscv_elf_link_hash_table *htab;
    939      1.1      matt   struct riscv_elf_link_hash_entry *eh;
    940      1.4  christos   struct elf_dyn_relocs *p;
    941      1.1      matt 
    942      1.1      matt   if (h->root.type == bfd_link_hash_indirect)
    943      1.1      matt     return TRUE;
    944      1.1      matt 
    945      1.1      matt   info = (struct bfd_link_info *) inf;
    946      1.1      matt   htab = riscv_elf_hash_table (info);
    947      1.1      matt   BFD_ASSERT (htab != NULL);
    948      1.1      matt 
    949      1.1      matt   if (htab->elf.dynamic_sections_created
    950      1.1      matt       && h->plt.refcount > 0)
    951      1.1      matt     {
    952      1.1      matt       /* Make sure this symbol is output as a dynamic symbol.
    953      1.1      matt 	 Undefined weak syms won't yet be marked as dynamic.  */
    954      1.1      matt       if (h->dynindx == -1
    955      1.1      matt 	  && !h->forced_local)
    956      1.1      matt 	{
    957      1.1      matt 	  if (! bfd_elf_link_record_dynamic_symbol (info, h))
    958      1.1      matt 	    return FALSE;
    959      1.1      matt 	}
    960      1.1      matt 
    961      1.3  christos       if (WILL_CALL_FINISH_DYNAMIC_SYMBOL (1, bfd_link_pic (info), h))
    962      1.1      matt 	{
    963      1.1      matt 	  asection *s = htab->elf.splt;
    964      1.1      matt 
    965      1.1      matt 	  if (s->size == 0)
    966      1.1      matt 	    s->size = PLT_HEADER_SIZE;
    967      1.1      matt 
    968      1.1      matt 	  h->plt.offset = s->size;
    969      1.1      matt 
    970      1.1      matt 	  /* Make room for this entry.  */
    971      1.1      matt 	  s->size += PLT_ENTRY_SIZE;
    972      1.1      matt 
    973      1.1      matt 	  /* We also need to make an entry in the .got.plt section.  */
    974      1.1      matt 	  htab->elf.sgotplt->size += GOT_ENTRY_SIZE;
    975      1.1      matt 
    976      1.1      matt 	  /* We also need to make an entry in the .rela.plt section.  */
    977      1.1      matt 	  htab->elf.srelplt->size += sizeof (ElfNN_External_Rela);
    978      1.1      matt 
    979      1.1      matt 	  /* If this symbol is not defined in a regular file, and we are
    980      1.1      matt 	     not generating a shared library, then set the symbol to this
    981      1.1      matt 	     location in the .plt.  This is required to make function
    982      1.1      matt 	     pointers compare as equal between the normal executable and
    983      1.1      matt 	     the shared library.  */
    984      1.3  christos 	  if (! bfd_link_pic (info)
    985      1.1      matt 	      && !h->def_regular)
    986      1.1      matt 	    {
    987      1.1      matt 	      h->root.u.def.section = s;
    988      1.1      matt 	      h->root.u.def.value = h->plt.offset;
    989      1.1      matt 	    }
    990      1.1      matt 	}
    991      1.1      matt       else
    992      1.1      matt 	{
    993      1.1      matt 	  h->plt.offset = (bfd_vma) -1;
    994      1.1      matt 	  h->needs_plt = 0;
    995      1.1      matt 	}
    996      1.1      matt     }
    997      1.1      matt   else
    998      1.1      matt     {
    999      1.1      matt       h->plt.offset = (bfd_vma) -1;
   1000      1.1      matt       h->needs_plt = 0;
   1001      1.1      matt     }
   1002      1.1      matt 
   1003      1.1      matt   if (h->got.refcount > 0)
   1004      1.1      matt     {
   1005      1.1      matt       asection *s;
   1006      1.1      matt       bfd_boolean dyn;
   1007      1.4  christos       int tls_type = riscv_elf_hash_entry (h)->tls_type;
   1008      1.1      matt 
   1009      1.1      matt       /* Make sure this symbol is output as a dynamic symbol.
   1010      1.1      matt 	 Undefined weak syms won't yet be marked as dynamic.  */
   1011      1.1      matt       if (h->dynindx == -1
   1012      1.1      matt 	  && !h->forced_local)
   1013      1.1      matt 	{
   1014      1.1      matt 	  if (! bfd_elf_link_record_dynamic_symbol (info, h))
   1015      1.1      matt 	    return FALSE;
   1016      1.1      matt 	}
   1017      1.1      matt 
   1018      1.1      matt       s = htab->elf.sgot;
   1019      1.1      matt       h->got.offset = s->size;
   1020      1.1      matt       dyn = htab->elf.dynamic_sections_created;
   1021      1.1      matt       if (tls_type & (GOT_TLS_GD | GOT_TLS_IE))
   1022      1.1      matt 	{
   1023      1.1      matt 	  /* TLS_GD needs two dynamic relocs and two GOT slots.  */
   1024      1.1      matt 	  if (tls_type & GOT_TLS_GD)
   1025      1.1      matt 	    {
   1026      1.1      matt 	      s->size += 2 * RISCV_ELF_WORD_BYTES;
   1027      1.1      matt 	      htab->elf.srelgot->size += 2 * sizeof (ElfNN_External_Rela);
   1028      1.1      matt 	    }
   1029      1.1      matt 
   1030      1.1      matt 	  /* TLS_IE needs one dynamic reloc and one GOT slot.  */
   1031      1.1      matt 	  if (tls_type & GOT_TLS_IE)
   1032      1.1      matt 	    {
   1033      1.1      matt 	      s->size += RISCV_ELF_WORD_BYTES;
   1034      1.1      matt 	      htab->elf.srelgot->size += sizeof (ElfNN_External_Rela);
   1035      1.1      matt 	    }
   1036      1.1      matt 	}
   1037      1.1      matt       else
   1038      1.1      matt 	{
   1039      1.1      matt 	  s->size += RISCV_ELF_WORD_BYTES;
   1040  1.4.2.1  christos 	  if (WILL_CALL_FINISH_DYNAMIC_SYMBOL (dyn, bfd_link_pic (info), h)
   1041  1.4.2.1  christos 	      && ! UNDEFWEAK_NO_DYNAMIC_RELOC (info, h))
   1042      1.1      matt 	    htab->elf.srelgot->size += sizeof (ElfNN_External_Rela);
   1043      1.1      matt 	}
   1044      1.1      matt     }
   1045      1.1      matt   else
   1046      1.1      matt     h->got.offset = (bfd_vma) -1;
   1047      1.1      matt 
   1048      1.1      matt   eh = (struct riscv_elf_link_hash_entry *) h;
   1049      1.1      matt   if (eh->dyn_relocs == NULL)
   1050      1.1      matt     return TRUE;
   1051      1.1      matt 
   1052      1.1      matt   /* In the shared -Bsymbolic case, discard space allocated for
   1053      1.1      matt      dynamic pc-relative relocs against symbols which turn out to be
   1054      1.1      matt      defined in regular objects.  For the normal shared case, discard
   1055      1.1      matt      space for pc-relative relocs that have become local due to symbol
   1056      1.1      matt      visibility changes.  */
   1057      1.1      matt 
   1058      1.3  christos   if (bfd_link_pic (info))
   1059      1.1      matt     {
   1060      1.1      matt       if (SYMBOL_CALLS_LOCAL (info, h))
   1061      1.1      matt 	{
   1062      1.4  christos 	  struct elf_dyn_relocs **pp;
   1063      1.1      matt 
   1064      1.1      matt 	  for (pp = &eh->dyn_relocs; (p = *pp) != NULL; )
   1065      1.1      matt 	    {
   1066      1.1      matt 	      p->count -= p->pc_count;
   1067      1.1      matt 	      p->pc_count = 0;
   1068      1.1      matt 	      if (p->count == 0)
   1069      1.1      matt 		*pp = p->next;
   1070      1.1      matt 	      else
   1071      1.1      matt 		pp = &p->next;
   1072      1.1      matt 	    }
   1073      1.1      matt 	}
   1074      1.1      matt 
   1075      1.1      matt       /* Also discard relocs on undefined weak syms with non-default
   1076      1.1      matt 	 visibility.  */
   1077      1.1      matt       if (eh->dyn_relocs != NULL
   1078      1.1      matt 	  && h->root.type == bfd_link_hash_undefweak)
   1079      1.1      matt 	{
   1080  1.4.2.1  christos 	  if (ELF_ST_VISIBILITY (h->other) != STV_DEFAULT
   1081  1.4.2.1  christos 	      || UNDEFWEAK_NO_DYNAMIC_RELOC (info, h))
   1082      1.1      matt 	    eh->dyn_relocs = NULL;
   1083      1.1      matt 
   1084      1.1      matt 	  /* Make sure undefined weak symbols are output as a dynamic
   1085      1.1      matt 	     symbol in PIEs.  */
   1086      1.1      matt 	  else if (h->dynindx == -1
   1087      1.1      matt 		   && !h->forced_local)
   1088      1.1      matt 	    {
   1089      1.1      matt 	      if (! bfd_elf_link_record_dynamic_symbol (info, h))
   1090      1.1      matt 		return FALSE;
   1091      1.1      matt 	    }
   1092      1.1      matt 	}
   1093      1.1      matt     }
   1094      1.1      matt   else
   1095      1.1      matt     {
   1096      1.1      matt       /* For the non-shared case, discard space for relocs against
   1097      1.1      matt 	 symbols which turn out to need copy relocs or are not
   1098      1.1      matt 	 dynamic.  */
   1099      1.1      matt 
   1100      1.1      matt       if (!h->non_got_ref
   1101      1.1      matt 	  && ((h->def_dynamic
   1102      1.1      matt 	       && !h->def_regular)
   1103      1.1      matt 	      || (htab->elf.dynamic_sections_created
   1104      1.1      matt 		  && (h->root.type == bfd_link_hash_undefweak
   1105      1.1      matt 		      || h->root.type == bfd_link_hash_undefined))))
   1106      1.1      matt 	{
   1107      1.1      matt 	  /* Make sure this symbol is output as a dynamic symbol.
   1108      1.1      matt 	     Undefined weak syms won't yet be marked as dynamic.  */
   1109      1.1      matt 	  if (h->dynindx == -1
   1110      1.1      matt 	      && !h->forced_local)
   1111      1.1      matt 	    {
   1112      1.1      matt 	      if (! bfd_elf_link_record_dynamic_symbol (info, h))
   1113      1.1      matt 		return FALSE;
   1114      1.1      matt 	    }
   1115      1.1      matt 
   1116      1.1      matt 	  /* If that succeeded, we know we'll be keeping all the
   1117      1.1      matt 	     relocs.  */
   1118      1.1      matt 	  if (h->dynindx != -1)
   1119      1.1      matt 	    goto keep;
   1120      1.1      matt 	}
   1121      1.1      matt 
   1122      1.1      matt       eh->dyn_relocs = NULL;
   1123      1.1      matt 
   1124      1.1      matt     keep: ;
   1125      1.1      matt     }
   1126      1.1      matt 
   1127      1.1      matt   /* Finally, allocate space.  */
   1128      1.1      matt   for (p = eh->dyn_relocs; p != NULL; p = p->next)
   1129      1.1      matt     {
   1130      1.1      matt       asection *sreloc = elf_section_data (p->sec)->sreloc;
   1131      1.1      matt       sreloc->size += p->count * sizeof (ElfNN_External_Rela);
   1132      1.1      matt     }
   1133      1.1      matt 
   1134      1.1      matt   return TRUE;
   1135      1.1      matt }
   1136      1.1      matt 
   1137      1.4  christos /* Set DF_TEXTREL if we find any dynamic relocs that apply to
   1138      1.4  christos    read-only sections.  */
   1139      1.1      matt 
   1140      1.1      matt static bfd_boolean
   1141      1.4  christos maybe_set_textrel (struct elf_link_hash_entry *h, void *info_p)
   1142      1.1      matt {
   1143      1.4  christos   asection *sec;
   1144      1.4  christos 
   1145      1.4  christos   if (h->root.type == bfd_link_hash_indirect)
   1146      1.4  christos     return TRUE;
   1147      1.1      matt 
   1148      1.4  christos   sec = readonly_dynrelocs (h);
   1149      1.4  christos   if (sec != NULL)
   1150      1.1      matt     {
   1151      1.4  christos       struct bfd_link_info *info = (struct bfd_link_info *) info_p;
   1152      1.1      matt 
   1153      1.4  christos       info->flags |= DF_TEXTREL;
   1154      1.4  christos       info->callbacks->minfo
   1155  1.4.2.1  christos 	(_("%pB: dynamic relocation against `%pT' in read-only section `%pA'\n"),
   1156      1.4  christos 	 sec->owner, h->root.root.string, sec);
   1157      1.1      matt 
   1158      1.4  christos       /* Not an error, just cut short the traversal.  */
   1159      1.4  christos       return FALSE;
   1160      1.1      matt     }
   1161      1.1      matt   return TRUE;
   1162      1.1      matt }
   1163      1.1      matt 
   1164      1.1      matt static bfd_boolean
   1165      1.1      matt riscv_elf_size_dynamic_sections (bfd *output_bfd, struct bfd_link_info *info)
   1166      1.1      matt {
   1167      1.1      matt   struct riscv_elf_link_hash_table *htab;
   1168      1.1      matt   bfd *dynobj;
   1169      1.1      matt   asection *s;
   1170      1.1      matt   bfd *ibfd;
   1171      1.1      matt 
   1172      1.1      matt   htab = riscv_elf_hash_table (info);
   1173      1.1      matt   BFD_ASSERT (htab != NULL);
   1174      1.1      matt   dynobj = htab->elf.dynobj;
   1175      1.1      matt   BFD_ASSERT (dynobj != NULL);
   1176      1.1      matt 
   1177      1.1      matt   if (elf_hash_table (info)->dynamic_sections_created)
   1178      1.1      matt     {
   1179      1.1      matt       /* Set the contents of the .interp section to the interpreter.  */
   1180      1.4  christos       if (bfd_link_executable (info) && !info->nointerp)
   1181      1.1      matt 	{
   1182      1.1      matt 	  s = bfd_get_linker_section (dynobj, ".interp");
   1183      1.1      matt 	  BFD_ASSERT (s != NULL);
   1184      1.1      matt 	  s->size = strlen (ELFNN_DYNAMIC_INTERPRETER) + 1;
   1185      1.1      matt 	  s->contents = (unsigned char *) ELFNN_DYNAMIC_INTERPRETER;
   1186      1.1      matt 	}
   1187      1.1      matt     }
   1188      1.1      matt 
   1189      1.1      matt   /* Set up .got offsets for local syms, and space for local dynamic
   1190      1.1      matt      relocs.  */
   1191      1.3  christos   for (ibfd = info->input_bfds; ibfd != NULL; ibfd = ibfd->link.next)
   1192      1.1      matt     {
   1193      1.1      matt       bfd_signed_vma *local_got;
   1194      1.1      matt       bfd_signed_vma *end_local_got;
   1195      1.1      matt       char *local_tls_type;
   1196      1.1      matt       bfd_size_type locsymcount;
   1197      1.1      matt       Elf_Internal_Shdr *symtab_hdr;
   1198      1.1      matt       asection *srel;
   1199      1.1      matt 
   1200      1.1      matt       if (! is_riscv_elf (ibfd))
   1201      1.1      matt 	continue;
   1202      1.1      matt 
   1203      1.1      matt       for (s = ibfd->sections; s != NULL; s = s->next)
   1204      1.1      matt 	{
   1205      1.4  christos 	  struct elf_dyn_relocs *p;
   1206      1.1      matt 
   1207      1.1      matt 	  for (p = elf_section_data (s)->local_dynrel; p != NULL; p = p->next)
   1208      1.1      matt 	    {
   1209      1.1      matt 	      if (!bfd_is_abs_section (p->sec)
   1210      1.1      matt 		  && bfd_is_abs_section (p->sec->output_section))
   1211      1.1      matt 		{
   1212      1.1      matt 		  /* Input section has been discarded, either because
   1213      1.1      matt 		     it is a copy of a linkonce section or due to
   1214      1.1      matt 		     linker script /DISCARD/, so we'll be discarding
   1215      1.1      matt 		     the relocs too.  */
   1216      1.1      matt 		}
   1217      1.1      matt 	      else if (p->count != 0)
   1218      1.1      matt 		{
   1219      1.1      matt 		  srel = elf_section_data (p->sec)->sreloc;
   1220      1.1      matt 		  srel->size += p->count * sizeof (ElfNN_External_Rela);
   1221      1.1      matt 		  if ((p->sec->output_section->flags & SEC_READONLY) != 0)
   1222      1.1      matt 		    info->flags |= DF_TEXTREL;
   1223      1.1      matt 		}
   1224      1.1      matt 	    }
   1225      1.1      matt 	}
   1226      1.1      matt 
   1227      1.1      matt       local_got = elf_local_got_refcounts (ibfd);
   1228      1.1      matt       if (!local_got)
   1229      1.1      matt 	continue;
   1230      1.1      matt 
   1231      1.1      matt       symtab_hdr = &elf_symtab_hdr (ibfd);
   1232      1.1      matt       locsymcount = symtab_hdr->sh_info;
   1233      1.1      matt       end_local_got = local_got + locsymcount;
   1234      1.1      matt       local_tls_type = _bfd_riscv_elf_local_got_tls_type (ibfd);
   1235      1.1      matt       s = htab->elf.sgot;
   1236      1.1      matt       srel = htab->elf.srelgot;
   1237      1.1      matt       for (; local_got < end_local_got; ++local_got, ++local_tls_type)
   1238      1.1      matt 	{
   1239      1.1      matt 	  if (*local_got > 0)
   1240      1.1      matt 	    {
   1241      1.1      matt 	      *local_got = s->size;
   1242      1.1      matt 	      s->size += RISCV_ELF_WORD_BYTES;
   1243      1.1      matt 	      if (*local_tls_type & GOT_TLS_GD)
   1244      1.1      matt 		s->size += RISCV_ELF_WORD_BYTES;
   1245      1.3  christos 	      if (bfd_link_pic (info)
   1246      1.1      matt 		  || (*local_tls_type & (GOT_TLS_GD | GOT_TLS_IE)))
   1247      1.1      matt 		srel->size += sizeof (ElfNN_External_Rela);
   1248      1.1      matt 	    }
   1249      1.1      matt 	  else
   1250      1.1      matt 	    *local_got = (bfd_vma) -1;
   1251      1.1      matt 	}
   1252      1.1      matt     }
   1253      1.1      matt 
   1254      1.1      matt   /* Allocate global sym .plt and .got entries, and space for global
   1255      1.1      matt      sym dynamic relocs.  */
   1256      1.1      matt   elf_link_hash_traverse (&htab->elf, allocate_dynrelocs, info);
   1257      1.1      matt 
   1258      1.1      matt   if (htab->elf.sgotplt)
   1259      1.1      matt     {
   1260      1.1      matt       struct elf_link_hash_entry *got;
   1261      1.1      matt       got = elf_link_hash_lookup (elf_hash_table (info),
   1262      1.1      matt 				  "_GLOBAL_OFFSET_TABLE_",
   1263      1.1      matt 				  FALSE, FALSE, FALSE);
   1264      1.1      matt 
   1265      1.1      matt       /* Don't allocate .got.plt section if there are no GOT nor PLT
   1266      1.1      matt 	 entries and there is no refeence to _GLOBAL_OFFSET_TABLE_.  */
   1267      1.1      matt       if ((got == NULL
   1268      1.1      matt 	   || !got->ref_regular_nonweak)
   1269      1.1      matt 	  && (htab->elf.sgotplt->size == GOTPLT_HEADER_SIZE)
   1270      1.1      matt 	  && (htab->elf.splt == NULL
   1271      1.1      matt 	      || htab->elf.splt->size == 0)
   1272      1.1      matt 	  && (htab->elf.sgot == NULL
   1273      1.1      matt 	      || (htab->elf.sgot->size
   1274      1.1      matt 		  == get_elf_backend_data (output_bfd)->got_header_size)))
   1275      1.1      matt 	htab->elf.sgotplt->size = 0;
   1276      1.1      matt     }
   1277      1.1      matt 
   1278      1.1      matt   /* The check_relocs and adjust_dynamic_symbol entry points have
   1279      1.1      matt      determined the sizes of the various dynamic sections.  Allocate
   1280      1.1      matt      memory for them.  */
   1281      1.1      matt   for (s = dynobj->sections; s != NULL; s = s->next)
   1282      1.1      matt     {
   1283      1.1      matt       if ((s->flags & SEC_LINKER_CREATED) == 0)
   1284      1.1      matt 	continue;
   1285      1.1      matt 
   1286      1.1      matt       if (s == htab->elf.splt
   1287      1.1      matt 	  || s == htab->elf.sgot
   1288      1.1      matt 	  || s == htab->elf.sgotplt
   1289      1.4  christos 	  || s == htab->elf.sdynbss
   1290  1.4.2.2    martin 	  || s == htab->elf.sdynrelro
   1291  1.4.2.2    martin 	  || s == htab->sdyntdata)
   1292      1.1      matt 	{
   1293      1.1      matt 	  /* Strip this section if we don't need it; see the
   1294      1.1      matt 	     comment below.  */
   1295      1.1      matt 	}
   1296      1.1      matt       else if (strncmp (s->name, ".rela", 5) == 0)
   1297      1.1      matt 	{
   1298      1.1      matt 	  if (s->size != 0)
   1299      1.1      matt 	    {
   1300      1.1      matt 	      /* We use the reloc_count field as a counter if we need
   1301      1.1      matt 		 to copy relocs into the output file.  */
   1302      1.1      matt 	      s->reloc_count = 0;
   1303      1.1      matt 	    }
   1304      1.1      matt 	}
   1305      1.1      matt       else
   1306      1.1      matt 	{
   1307      1.1      matt 	  /* It's not one of our sections.  */
   1308      1.1      matt 	  continue;
   1309      1.1      matt 	}
   1310      1.1      matt 
   1311      1.1      matt       if (s->size == 0)
   1312      1.1      matt 	{
   1313      1.1      matt 	  /* If we don't need this section, strip it from the
   1314      1.1      matt 	     output file.  This is mostly to handle .rela.bss and
   1315      1.1      matt 	     .rela.plt.  We must create both sections in
   1316      1.1      matt 	     create_dynamic_sections, because they must be created
   1317      1.1      matt 	     before the linker maps input sections to output
   1318      1.1      matt 	     sections.  The linker does that before
   1319      1.1      matt 	     adjust_dynamic_symbol is called, and it is that
   1320      1.1      matt 	     function which decides whether anything needs to go
   1321      1.1      matt 	     into these sections.  */
   1322      1.1      matt 	  s->flags |= SEC_EXCLUDE;
   1323      1.1      matt 	  continue;
   1324      1.1      matt 	}
   1325      1.1      matt 
   1326      1.1      matt       if ((s->flags & SEC_HAS_CONTENTS) == 0)
   1327      1.1      matt 	continue;
   1328      1.1      matt 
   1329      1.1      matt       /* Allocate memory for the section contents.  Zero the memory
   1330      1.1      matt 	 for the benefit of .rela.plt, which has 4 unused entries
   1331      1.1      matt 	 at the beginning, and we don't want garbage.  */
   1332      1.1      matt       s->contents = (bfd_byte *) bfd_zalloc (dynobj, s->size);
   1333      1.1      matt       if (s->contents == NULL)
   1334      1.1      matt 	return FALSE;
   1335      1.1      matt     }
   1336      1.1      matt 
   1337      1.1      matt   if (elf_hash_table (info)->dynamic_sections_created)
   1338      1.1      matt     {
   1339      1.1      matt       /* Add some entries to the .dynamic section.  We fill in the
   1340      1.1      matt 	 values later, in riscv_elf_finish_dynamic_sections, but we
   1341      1.1      matt 	 must add the entries now so that we get the correct size for
   1342      1.1      matt 	 the .dynamic section.  The DT_DEBUG entry is filled in by the
   1343      1.1      matt 	 dynamic linker and used by the debugger.  */
   1344      1.1      matt #define add_dynamic_entry(TAG, VAL) \
   1345      1.1      matt   _bfd_elf_add_dynamic_entry (info, TAG, VAL)
   1346      1.1      matt 
   1347      1.3  christos       if (bfd_link_executable (info))
   1348      1.1      matt 	{
   1349      1.1      matt 	  if (!add_dynamic_entry (DT_DEBUG, 0))
   1350      1.1      matt 	    return FALSE;
   1351      1.1      matt 	}
   1352      1.1      matt 
   1353      1.1      matt       if (htab->elf.srelplt->size != 0)
   1354      1.1      matt 	{
   1355      1.1      matt 	  if (!add_dynamic_entry (DT_PLTGOT, 0)
   1356      1.1      matt 	      || !add_dynamic_entry (DT_PLTRELSZ, 0)
   1357      1.1      matt 	      || !add_dynamic_entry (DT_PLTREL, DT_RELA)
   1358      1.1      matt 	      || !add_dynamic_entry (DT_JMPREL, 0))
   1359      1.1      matt 	    return FALSE;
   1360      1.1      matt 	}
   1361      1.1      matt 
   1362      1.1      matt       if (!add_dynamic_entry (DT_RELA, 0)
   1363      1.1      matt 	  || !add_dynamic_entry (DT_RELASZ, 0)
   1364      1.1      matt 	  || !add_dynamic_entry (DT_RELAENT, sizeof (ElfNN_External_Rela)))
   1365      1.1      matt 	return FALSE;
   1366      1.1      matt 
   1367      1.1      matt       /* If any dynamic relocs apply to a read-only section,
   1368      1.1      matt 	 then we need a DT_TEXTREL entry.  */
   1369      1.1      matt       if ((info->flags & DF_TEXTREL) == 0)
   1370      1.4  christos 	elf_link_hash_traverse (&htab->elf, maybe_set_textrel, info);
   1371      1.1      matt 
   1372      1.1      matt       if (info->flags & DF_TEXTREL)
   1373      1.1      matt 	{
   1374      1.1      matt 	  if (!add_dynamic_entry (DT_TEXTREL, 0))
   1375      1.1      matt 	    return FALSE;
   1376      1.1      matt 	}
   1377      1.1      matt     }
   1378      1.1      matt #undef add_dynamic_entry
   1379      1.1      matt 
   1380      1.1      matt   return TRUE;
   1381      1.1      matt }
   1382      1.1      matt 
   1383      1.1      matt #define TP_OFFSET 0
   1384      1.1      matt #define DTP_OFFSET 0x800
   1385      1.1      matt 
   1386      1.1      matt /* Return the relocation value for a TLS dtp-relative reloc.  */
   1387      1.1      matt 
   1388      1.1      matt static bfd_vma
   1389      1.1      matt dtpoff (struct bfd_link_info *info, bfd_vma address)
   1390      1.1      matt {
   1391      1.1      matt   /* If tls_sec is NULL, we should have signalled an error already.  */
   1392      1.1      matt   if (elf_hash_table (info)->tls_sec == NULL)
   1393      1.1      matt     return 0;
   1394      1.1      matt   return address - elf_hash_table (info)->tls_sec->vma - DTP_OFFSET;
   1395      1.1      matt }
   1396      1.1      matt 
   1397      1.1      matt /* Return the relocation value for a static TLS tp-relative relocation.  */
   1398      1.1      matt 
   1399      1.1      matt static bfd_vma
   1400      1.1      matt tpoff (struct bfd_link_info *info, bfd_vma address)
   1401      1.1      matt {
   1402      1.1      matt   /* If tls_sec is NULL, we should have signalled an error already.  */
   1403      1.1      matt   if (elf_hash_table (info)->tls_sec == NULL)
   1404      1.1      matt     return 0;
   1405      1.1      matt   return address - elf_hash_table (info)->tls_sec->vma - TP_OFFSET;
   1406      1.1      matt }
   1407      1.1      matt 
   1408      1.1      matt /* Return the global pointer's value, or 0 if it is not in use.  */
   1409      1.1      matt 
   1410      1.1      matt static bfd_vma
   1411      1.1      matt riscv_global_pointer_value (struct bfd_link_info *info)
   1412      1.1      matt {
   1413      1.1      matt   struct bfd_link_hash_entry *h;
   1414      1.1      matt 
   1415      1.4  christos   h = bfd_link_hash_lookup (info->hash, RISCV_GP_SYMBOL, FALSE, FALSE, TRUE);
   1416      1.1      matt   if (h == NULL || h->type != bfd_link_hash_defined)
   1417      1.1      matt     return 0;
   1418      1.1      matt 
   1419      1.1      matt   return h->u.def.value + sec_addr (h->u.def.section);
   1420      1.1      matt }
   1421      1.1      matt 
   1422      1.1      matt /* Emplace a static relocation.  */
   1423      1.1      matt 
   1424      1.1      matt static bfd_reloc_status_type
   1425      1.1      matt perform_relocation (const reloc_howto_type *howto,
   1426      1.1      matt 		    const Elf_Internal_Rela *rel,
   1427      1.1      matt 		    bfd_vma value,
   1428      1.1      matt 		    asection *input_section,
   1429      1.1      matt 		    bfd *input_bfd,
   1430      1.1      matt 		    bfd_byte *contents)
   1431      1.1      matt {
   1432      1.1      matt   if (howto->pc_relative)
   1433      1.1      matt     value -= sec_addr (input_section) + rel->r_offset;
   1434      1.1      matt   value += rel->r_addend;
   1435      1.1      matt 
   1436      1.1      matt   switch (ELFNN_R_TYPE (rel->r_info))
   1437      1.1      matt     {
   1438      1.1      matt     case R_RISCV_HI20:
   1439      1.1      matt     case R_RISCV_TPREL_HI20:
   1440      1.1      matt     case R_RISCV_PCREL_HI20:
   1441      1.1      matt     case R_RISCV_GOT_HI20:
   1442      1.1      matt     case R_RISCV_TLS_GOT_HI20:
   1443      1.1      matt     case R_RISCV_TLS_GD_HI20:
   1444      1.4  christos       if (ARCH_SIZE > 32 && !VALID_UTYPE_IMM (RISCV_CONST_HIGH_PART (value)))
   1445      1.4  christos 	return bfd_reloc_overflow;
   1446      1.1      matt       value = ENCODE_UTYPE_IMM (RISCV_CONST_HIGH_PART (value));
   1447      1.1      matt       break;
   1448      1.1      matt 
   1449      1.1      matt     case R_RISCV_LO12_I:
   1450      1.4  christos     case R_RISCV_GPREL_I:
   1451      1.1      matt     case R_RISCV_TPREL_LO12_I:
   1452      1.4  christos     case R_RISCV_TPREL_I:
   1453      1.1      matt     case R_RISCV_PCREL_LO12_I:
   1454      1.1      matt       value = ENCODE_ITYPE_IMM (value);
   1455      1.1      matt       break;
   1456      1.1      matt 
   1457      1.1      matt     case R_RISCV_LO12_S:
   1458      1.4  christos     case R_RISCV_GPREL_S:
   1459      1.1      matt     case R_RISCV_TPREL_LO12_S:
   1460      1.4  christos     case R_RISCV_TPREL_S:
   1461      1.1      matt     case R_RISCV_PCREL_LO12_S:
   1462      1.1      matt       value = ENCODE_STYPE_IMM (value);
   1463      1.1      matt       break;
   1464      1.1      matt 
   1465      1.1      matt     case R_RISCV_CALL:
   1466      1.1      matt     case R_RISCV_CALL_PLT:
   1467      1.4  christos       if (ARCH_SIZE > 32 && !VALID_UTYPE_IMM (RISCV_CONST_HIGH_PART (value)))
   1468      1.1      matt 	return bfd_reloc_overflow;
   1469      1.1      matt       value = ENCODE_UTYPE_IMM (RISCV_CONST_HIGH_PART (value))
   1470      1.1      matt 	      | (ENCODE_ITYPE_IMM (value) << 32);
   1471      1.1      matt       break;
   1472      1.1      matt 
   1473      1.1      matt     case R_RISCV_JAL:
   1474      1.1      matt       if (!VALID_UJTYPE_IMM (value))
   1475      1.1      matt 	return bfd_reloc_overflow;
   1476      1.1      matt       value = ENCODE_UJTYPE_IMM (value);
   1477      1.1      matt       break;
   1478      1.1      matt 
   1479      1.1      matt     case R_RISCV_BRANCH:
   1480      1.1      matt       if (!VALID_SBTYPE_IMM (value))
   1481      1.1      matt 	return bfd_reloc_overflow;
   1482      1.1      matt       value = ENCODE_SBTYPE_IMM (value);
   1483      1.1      matt       break;
   1484      1.1      matt 
   1485      1.4  christos     case R_RISCV_RVC_BRANCH:
   1486      1.4  christos       if (!VALID_RVC_B_IMM (value))
   1487      1.4  christos 	return bfd_reloc_overflow;
   1488      1.4  christos       value = ENCODE_RVC_B_IMM (value);
   1489      1.4  christos       break;
   1490      1.4  christos 
   1491      1.4  christos     case R_RISCV_RVC_JUMP:
   1492      1.4  christos       if (!VALID_RVC_J_IMM (value))
   1493      1.4  christos 	return bfd_reloc_overflow;
   1494      1.4  christos       value = ENCODE_RVC_J_IMM (value);
   1495      1.4  christos       break;
   1496      1.4  christos 
   1497      1.4  christos     case R_RISCV_RVC_LUI:
   1498  1.4.2.2    martin       if (RISCV_CONST_HIGH_PART (value) == 0)
   1499  1.4.2.2    martin 	{
   1500  1.4.2.2    martin 	  /* Linker relaxation can convert an address equal to or greater than
   1501  1.4.2.2    martin 	     0x800 to slightly below 0x800.  C.LUI does not accept zero as a
   1502  1.4.2.2    martin 	     valid immediate.  We can fix this by converting it to a C.LI.  */
   1503  1.4.2.2    martin 	  bfd_vma insn = bfd_get (howto->bitsize, input_bfd,
   1504  1.4.2.2    martin 				  contents + rel->r_offset);
   1505  1.4.2.2    martin 	  insn = (insn & ~MATCH_C_LUI) | MATCH_C_LI;
   1506  1.4.2.2    martin 	  bfd_put (howto->bitsize, input_bfd, insn, contents + rel->r_offset);
   1507  1.4.2.2    martin 	  value = ENCODE_RVC_IMM (0);
   1508  1.4.2.2    martin 	}
   1509  1.4.2.2    martin       else if (!VALID_RVC_LUI_IMM (RISCV_CONST_HIGH_PART (value)))
   1510      1.4  christos 	return bfd_reloc_overflow;
   1511  1.4.2.2    martin       else
   1512  1.4.2.2    martin 	value = ENCODE_RVC_LUI_IMM (RISCV_CONST_HIGH_PART (value));
   1513      1.4  christos       break;
   1514      1.4  christos 
   1515      1.1      matt     case R_RISCV_32:
   1516      1.1      matt     case R_RISCV_64:
   1517      1.1      matt     case R_RISCV_ADD8:
   1518      1.1      matt     case R_RISCV_ADD16:
   1519      1.1      matt     case R_RISCV_ADD32:
   1520      1.1      matt     case R_RISCV_ADD64:
   1521      1.4  christos     case R_RISCV_SUB6:
   1522      1.1      matt     case R_RISCV_SUB8:
   1523      1.1      matt     case R_RISCV_SUB16:
   1524      1.1      matt     case R_RISCV_SUB32:
   1525      1.1      matt     case R_RISCV_SUB64:
   1526      1.4  christos     case R_RISCV_SET6:
   1527      1.4  christos     case R_RISCV_SET8:
   1528      1.4  christos     case R_RISCV_SET16:
   1529      1.4  christos     case R_RISCV_SET32:
   1530      1.4  christos     case R_RISCV_32_PCREL:
   1531      1.1      matt     case R_RISCV_TLS_DTPREL32:
   1532      1.1      matt     case R_RISCV_TLS_DTPREL64:
   1533      1.1      matt       break;
   1534      1.1      matt 
   1535      1.4  christos     case R_RISCV_DELETE:
   1536      1.4  christos       return bfd_reloc_ok;
   1537      1.4  christos 
   1538      1.1      matt     default:
   1539      1.1      matt       return bfd_reloc_notsupported;
   1540      1.1      matt     }
   1541      1.1      matt 
   1542      1.1      matt   bfd_vma word = bfd_get (howto->bitsize, input_bfd, contents + rel->r_offset);
   1543      1.1      matt   word = (word & ~howto->dst_mask) | (value & howto->dst_mask);
   1544      1.1      matt   bfd_put (howto->bitsize, input_bfd, word, contents + rel->r_offset);
   1545      1.1      matt 
   1546      1.1      matt   return bfd_reloc_ok;
   1547      1.1      matt }
   1548      1.1      matt 
   1549      1.1      matt /* Remember all PC-relative high-part relocs we've encountered to help us
   1550      1.1      matt    later resolve the corresponding low-part relocs.  */
   1551      1.1      matt 
   1552      1.4  christos typedef struct
   1553      1.4  christos {
   1554      1.1      matt   bfd_vma address;
   1555      1.1      matt   bfd_vma value;
   1556      1.1      matt } riscv_pcrel_hi_reloc;
   1557      1.1      matt 
   1558      1.4  christos typedef struct riscv_pcrel_lo_reloc
   1559      1.4  christos {
   1560      1.4  christos   asection *			 input_section;
   1561      1.4  christos   struct bfd_link_info *	 info;
   1562      1.4  christos   reloc_howto_type *		 howto;
   1563      1.4  christos   const Elf_Internal_Rela *	 reloc;
   1564      1.4  christos   bfd_vma			 addr;
   1565      1.4  christos   const char *			 name;
   1566      1.4  christos   bfd_byte *			 contents;
   1567      1.4  christos   struct riscv_pcrel_lo_reloc *	 next;
   1568      1.1      matt } riscv_pcrel_lo_reloc;
   1569      1.1      matt 
   1570      1.4  christos typedef struct
   1571      1.4  christos {
   1572      1.1      matt   htab_t hi_relocs;
   1573      1.1      matt   riscv_pcrel_lo_reloc *lo_relocs;
   1574      1.1      matt } riscv_pcrel_relocs;
   1575      1.1      matt 
   1576      1.1      matt static hashval_t
   1577      1.1      matt riscv_pcrel_reloc_hash (const void *entry)
   1578      1.1      matt {
   1579      1.1      matt   const riscv_pcrel_hi_reloc *e = entry;
   1580      1.1      matt   return (hashval_t)(e->address >> 2);
   1581      1.1      matt }
   1582      1.1      matt 
   1583      1.1      matt static bfd_boolean
   1584      1.1      matt riscv_pcrel_reloc_eq (const void *entry1, const void *entry2)
   1585      1.1      matt {
   1586      1.1      matt   const riscv_pcrel_hi_reloc *e1 = entry1, *e2 = entry2;
   1587      1.1      matt   return e1->address == e2->address;
   1588      1.1      matt }
   1589      1.1      matt 
   1590      1.1      matt static bfd_boolean
   1591      1.1      matt riscv_init_pcrel_relocs (riscv_pcrel_relocs *p)
   1592      1.1      matt {
   1593      1.1      matt 
   1594      1.1      matt   p->lo_relocs = NULL;
   1595      1.1      matt   p->hi_relocs = htab_create (1024, riscv_pcrel_reloc_hash,
   1596      1.1      matt 			      riscv_pcrel_reloc_eq, free);
   1597      1.1      matt   return p->hi_relocs != NULL;
   1598      1.1      matt }
   1599      1.1      matt 
   1600      1.1      matt static void
   1601      1.1      matt riscv_free_pcrel_relocs (riscv_pcrel_relocs *p)
   1602      1.1      matt {
   1603      1.1      matt   riscv_pcrel_lo_reloc *cur = p->lo_relocs;
   1604      1.4  christos 
   1605      1.1      matt   while (cur != NULL)
   1606      1.1      matt     {
   1607      1.1      matt       riscv_pcrel_lo_reloc *next = cur->next;
   1608      1.1      matt       free (cur);
   1609      1.1      matt       cur = next;
   1610      1.1      matt     }
   1611      1.1      matt 
   1612      1.1      matt   htab_delete (p->hi_relocs);
   1613      1.1      matt }
   1614      1.1      matt 
   1615      1.1      matt static bfd_boolean
   1616      1.4  christos riscv_zero_pcrel_hi_reloc (Elf_Internal_Rela *rel,
   1617      1.4  christos 			   struct bfd_link_info *info,
   1618      1.4  christos 			   bfd_vma pc,
   1619      1.4  christos 			   bfd_vma addr,
   1620      1.4  christos 			   bfd_byte *contents,
   1621      1.4  christos 			   const reloc_howto_type *howto,
   1622      1.4  christos 			   bfd *input_bfd)
   1623      1.4  christos {
   1624      1.4  christos   /* We may need to reference low addreses in PC-relative modes even when the
   1625      1.4  christos    * PC is far away from these addresses.  For example, undefweak references
   1626      1.4  christos    * need to produce the address 0 when linked.  As 0 is far from the arbitrary
   1627      1.4  christos    * addresses that we can link PC-relative programs at, the linker can't
   1628      1.4  christos    * actually relocate references to those symbols.  In order to allow these
   1629      1.4  christos    * programs to work we simply convert the PC-relative auipc sequences to
   1630      1.4  christos    * 0-relative lui sequences.  */
   1631      1.4  christos   if (bfd_link_pic (info))
   1632      1.4  christos     return FALSE;
   1633      1.4  christos 
   1634      1.4  christos   /* If it's possible to reference the symbol using auipc we do so, as that's
   1635      1.4  christos    * more in the spirit of the PC-relative relocations we're processing.  */
   1636      1.4  christos   bfd_vma offset = addr - pc;
   1637      1.4  christos   if (ARCH_SIZE == 32 || VALID_UTYPE_IMM (RISCV_CONST_HIGH_PART (offset)))
   1638      1.4  christos     return FALSE;
   1639      1.4  christos 
   1640      1.4  christos   /* If it's impossible to reference this with a LUI-based offset then don't
   1641      1.4  christos    * bother to convert it at all so users still see the PC-relative relocation
   1642      1.4  christos    * in the truncation message.  */
   1643      1.4  christos   if (ARCH_SIZE > 32 && !VALID_UTYPE_IMM (RISCV_CONST_HIGH_PART (addr)))
   1644      1.4  christos     return FALSE;
   1645      1.4  christos 
   1646      1.4  christos   rel->r_info = ELFNN_R_INFO(addr, R_RISCV_HI20);
   1647      1.4  christos 
   1648      1.4  christos   bfd_vma insn = bfd_get(howto->bitsize, input_bfd, contents + rel->r_offset);
   1649      1.4  christos   insn = (insn & ~MASK_AUIPC) | MATCH_LUI;
   1650      1.4  christos   bfd_put(howto->bitsize, input_bfd, insn, contents + rel->r_offset);
   1651      1.4  christos   return TRUE;
   1652      1.4  christos }
   1653      1.4  christos 
   1654      1.4  christos static bfd_boolean
   1655      1.4  christos riscv_record_pcrel_hi_reloc (riscv_pcrel_relocs *p, bfd_vma addr,
   1656      1.4  christos 			     bfd_vma value, bfd_boolean absolute)
   1657      1.1      matt {
   1658      1.4  christos   bfd_vma offset = absolute ? value : value - addr;
   1659      1.4  christos   riscv_pcrel_hi_reloc entry = {addr, offset};
   1660      1.1      matt   riscv_pcrel_hi_reloc **slot =
   1661      1.1      matt     (riscv_pcrel_hi_reloc **) htab_find_slot (p->hi_relocs, &entry, INSERT);
   1662      1.4  christos 
   1663      1.1      matt   BFD_ASSERT (*slot == NULL);
   1664      1.1      matt   *slot = (riscv_pcrel_hi_reloc *) bfd_malloc (sizeof (riscv_pcrel_hi_reloc));
   1665      1.1      matt   if (*slot == NULL)
   1666      1.1      matt     return FALSE;
   1667      1.1      matt   **slot = entry;
   1668      1.1      matt   return TRUE;
   1669      1.1      matt }
   1670      1.1      matt 
   1671      1.1      matt static bfd_boolean
   1672      1.1      matt riscv_record_pcrel_lo_reloc (riscv_pcrel_relocs *p,
   1673      1.1      matt 			     asection *input_section,
   1674      1.1      matt 			     struct bfd_link_info *info,
   1675      1.1      matt 			     reloc_howto_type *howto,
   1676      1.1      matt 			     const Elf_Internal_Rela *reloc,
   1677      1.1      matt 			     bfd_vma addr,
   1678      1.1      matt 			     const char *name,
   1679      1.1      matt 			     bfd_byte *contents)
   1680      1.1      matt {
   1681      1.1      matt   riscv_pcrel_lo_reloc *entry;
   1682      1.1      matt   entry = (riscv_pcrel_lo_reloc *) bfd_malloc (sizeof (riscv_pcrel_lo_reloc));
   1683      1.1      matt   if (entry == NULL)
   1684      1.1      matt     return FALSE;
   1685      1.1      matt   *entry = (riscv_pcrel_lo_reloc) {input_section, info, howto, reloc, addr,
   1686      1.1      matt 				   name, contents, p->lo_relocs};
   1687      1.1      matt   p->lo_relocs = entry;
   1688      1.1      matt   return TRUE;
   1689      1.1      matt }
   1690      1.1      matt 
   1691      1.1      matt static bfd_boolean
   1692      1.1      matt riscv_resolve_pcrel_lo_relocs (riscv_pcrel_relocs *p)
   1693      1.1      matt {
   1694      1.1      matt   riscv_pcrel_lo_reloc *r;
   1695      1.4  christos 
   1696      1.1      matt   for (r = p->lo_relocs; r != NULL; r = r->next)
   1697      1.1      matt     {
   1698      1.1      matt       bfd *input_bfd = r->input_section->owner;
   1699      1.4  christos 
   1700      1.1      matt       riscv_pcrel_hi_reloc search = {r->addr, 0};
   1701      1.1      matt       riscv_pcrel_hi_reloc *entry = htab_find (p->hi_relocs, &search);
   1702  1.4.2.2    martin       if (entry == NULL
   1703  1.4.2.2    martin 	  /* Check for overflow into bit 11 when adding reloc addend.  */
   1704  1.4.2.2    martin 	  || (! (entry->value & 0x800)
   1705  1.4.2.2    martin 	      && ((entry->value + r->reloc->r_addend) & 0x800)))
   1706  1.4.2.2    martin 	{
   1707  1.4.2.2    martin 	  char *string = (entry == NULL
   1708  1.4.2.2    martin 			  ? "%pcrel_lo missing matching %pcrel_hi"
   1709  1.4.2.2    martin 			  : "%pcrel_lo overflow with an addend");
   1710  1.4.2.2    martin 	  (*r->info->callbacks->reloc_dangerous)
   1711  1.4.2.2    martin 	    (r->info, string, input_bfd, r->input_section, r->reloc->r_offset);
   1712      1.4  christos 	  return TRUE;
   1713      1.4  christos 	}
   1714      1.1      matt 
   1715      1.1      matt       perform_relocation (r->howto, r->reloc, entry->value, r->input_section,
   1716      1.1      matt 			  input_bfd, r->contents);
   1717      1.1      matt     }
   1718      1.1      matt 
   1719      1.1      matt   return TRUE;
   1720      1.1      matt }
   1721      1.1      matt 
   1722      1.1      matt /* Relocate a RISC-V ELF section.
   1723      1.1      matt 
   1724      1.1      matt    The RELOCATE_SECTION function is called by the new ELF backend linker
   1725      1.1      matt    to handle the relocations for a section.
   1726      1.1      matt 
   1727      1.1      matt    The relocs are always passed as Rela structures.
   1728      1.1      matt 
   1729      1.1      matt    This function is responsible for adjusting the section contents as
   1730      1.1      matt    necessary, and (if generating a relocatable output file) adjusting
   1731      1.1      matt    the reloc addend as necessary.
   1732      1.1      matt 
   1733      1.1      matt    This function does not have to worry about setting the reloc
   1734      1.1      matt    address or the reloc symbol index.
   1735      1.1      matt 
   1736      1.1      matt    LOCAL_SYMS is a pointer to the swapped in local symbols.
   1737      1.1      matt 
   1738      1.1      matt    LOCAL_SECTIONS is an array giving the section in the input file
   1739      1.1      matt    corresponding to the st_shndx field of each local symbol.
   1740      1.1      matt 
   1741      1.1      matt    The global hash table entry for the global symbols can be found
   1742      1.1      matt    via elf_sym_hashes (input_bfd).
   1743      1.1      matt 
   1744      1.1      matt    When generating relocatable output, this function must handle
   1745      1.1      matt    STB_LOCAL/STT_SECTION symbols specially.  The output symbol is
   1746      1.1      matt    going to be the section symbol corresponding to the output
   1747      1.1      matt    section, which means that the addend must be adjusted
   1748      1.1      matt    accordingly.  */
   1749      1.1      matt 
   1750      1.1      matt static bfd_boolean
   1751      1.4  christos riscv_elf_relocate_section (bfd *output_bfd,
   1752      1.4  christos 			    struct bfd_link_info *info,
   1753      1.4  christos 			    bfd *input_bfd,
   1754      1.4  christos 			    asection *input_section,
   1755      1.4  christos 			    bfd_byte *contents,
   1756      1.4  christos 			    Elf_Internal_Rela *relocs,
   1757      1.1      matt 			    Elf_Internal_Sym *local_syms,
   1758      1.1      matt 			    asection **local_sections)
   1759      1.1      matt {
   1760      1.1      matt   Elf_Internal_Rela *rel;
   1761      1.1      matt   Elf_Internal_Rela *relend;
   1762      1.1      matt   riscv_pcrel_relocs pcrel_relocs;
   1763      1.1      matt   bfd_boolean ret = FALSE;
   1764      1.1      matt   asection *sreloc = elf_section_data (input_section)->sreloc;
   1765      1.1      matt   struct riscv_elf_link_hash_table *htab = riscv_elf_hash_table (info);
   1766      1.1      matt   Elf_Internal_Shdr *symtab_hdr = &elf_symtab_hdr (input_bfd);
   1767      1.1      matt   struct elf_link_hash_entry **sym_hashes = elf_sym_hashes (input_bfd);
   1768      1.1      matt   bfd_vma *local_got_offsets = elf_local_got_offsets (input_bfd);
   1769      1.4  christos   bfd_boolean absolute;
   1770      1.1      matt 
   1771      1.1      matt   if (!riscv_init_pcrel_relocs (&pcrel_relocs))
   1772      1.1      matt     return FALSE;
   1773      1.1      matt 
   1774      1.1      matt   relend = relocs + input_section->reloc_count;
   1775      1.1      matt   for (rel = relocs; rel < relend; rel++)
   1776      1.1      matt     {
   1777      1.1      matt       unsigned long r_symndx;
   1778      1.1      matt       struct elf_link_hash_entry *h;
   1779      1.1      matt       Elf_Internal_Sym *sym;
   1780      1.1      matt       asection *sec;
   1781      1.1      matt       bfd_vma relocation;
   1782      1.1      matt       bfd_reloc_status_type r = bfd_reloc_ok;
   1783      1.1      matt       const char *name;
   1784      1.1      matt       bfd_vma off, ie_off;
   1785      1.1      matt       bfd_boolean unresolved_reloc, is_ie = FALSE;
   1786      1.1      matt       bfd_vma pc = sec_addr (input_section) + rel->r_offset;
   1787      1.1      matt       int r_type = ELFNN_R_TYPE (rel->r_info), tls_type;
   1788  1.4.2.1  christos       reloc_howto_type *howto = riscv_elf_rtype_to_howto (input_bfd, r_type);
   1789      1.1      matt       const char *msg = NULL;
   1790  1.4.2.2    martin       char *msg_buf = NULL;
   1791  1.4.2.1  christos       bfd_boolean resolved_to_zero;
   1792      1.1      matt 
   1793  1.4.2.1  christos       if (howto == NULL
   1794  1.4.2.1  christos 	  || r_type == R_RISCV_GNU_VTINHERIT || r_type == R_RISCV_GNU_VTENTRY)
   1795      1.1      matt 	continue;
   1796      1.1      matt 
   1797      1.1      matt       /* This is a final link.  */
   1798      1.1      matt       r_symndx = ELFNN_R_SYM (rel->r_info);
   1799      1.1      matt       h = NULL;
   1800      1.1      matt       sym = NULL;
   1801      1.1      matt       sec = NULL;
   1802      1.1      matt       unresolved_reloc = FALSE;
   1803      1.1      matt       if (r_symndx < symtab_hdr->sh_info)
   1804      1.1      matt 	{
   1805      1.1      matt 	  sym = local_syms + r_symndx;
   1806      1.1      matt 	  sec = local_sections[r_symndx];
   1807      1.1      matt 	  relocation = _bfd_elf_rela_local_sym (output_bfd, sym, &sec, rel);
   1808      1.1      matt 	}
   1809      1.1      matt       else
   1810      1.1      matt 	{
   1811      1.3  christos 	  bfd_boolean warned, ignored;
   1812      1.1      matt 
   1813      1.1      matt 	  RELOC_FOR_GLOBAL_SYMBOL (info, input_bfd, input_section, rel,
   1814      1.1      matt 				   r_symndx, symtab_hdr, sym_hashes,
   1815      1.1      matt 				   h, sec, relocation,
   1816      1.3  christos 				   unresolved_reloc, warned, ignored);
   1817      1.1      matt 	  if (warned)
   1818      1.1      matt 	    {
   1819      1.1      matt 	      /* To avoid generating warning messages about truncated
   1820      1.1      matt 		 relocations, set the relocation's address to be the same as
   1821      1.1      matt 		 the start of this section.  */
   1822      1.1      matt 	      if (input_section->output_section != NULL)
   1823      1.1      matt 		relocation = input_section->output_section->vma;
   1824      1.1      matt 	      else
   1825      1.1      matt 		relocation = 0;
   1826      1.1      matt 	    }
   1827      1.1      matt 	}
   1828      1.1      matt 
   1829      1.1      matt       if (sec != NULL && discarded_section (sec))
   1830      1.1      matt 	RELOC_AGAINST_DISCARDED_SECTION (info, input_bfd, input_section,
   1831      1.1      matt 					 rel, 1, relend, howto, 0, contents);
   1832      1.1      matt 
   1833      1.3  christos       if (bfd_link_relocatable (info))
   1834      1.1      matt 	continue;
   1835      1.1      matt 
   1836      1.1      matt       if (h != NULL)
   1837      1.1      matt 	name = h->root.root.string;
   1838      1.1      matt       else
   1839      1.1      matt 	{
   1840      1.1      matt 	  name = (bfd_elf_string_from_elf_section
   1841      1.1      matt 		  (input_bfd, symtab_hdr->sh_link, sym->st_name));
   1842      1.1      matt 	  if (name == NULL || *name == '\0')
   1843  1.4.2.2    martin 	    name = bfd_section_name (sec);
   1844      1.1      matt 	}
   1845      1.1      matt 
   1846  1.4.2.1  christos       resolved_to_zero = (h != NULL
   1847  1.4.2.1  christos 			  && UNDEFWEAK_NO_DYNAMIC_RELOC (info, h));
   1848  1.4.2.1  christos 
   1849      1.1      matt       switch (r_type)
   1850      1.1      matt 	{
   1851      1.1      matt 	case R_RISCV_NONE:
   1852      1.4  christos 	case R_RISCV_RELAX:
   1853      1.1      matt 	case R_RISCV_TPREL_ADD:
   1854      1.1      matt 	case R_RISCV_COPY:
   1855      1.1      matt 	case R_RISCV_JUMP_SLOT:
   1856      1.1      matt 	case R_RISCV_RELATIVE:
   1857      1.1      matt 	  /* These require nothing of us at all.  */
   1858      1.1      matt 	  continue;
   1859      1.1      matt 
   1860      1.4  christos 	case R_RISCV_HI20:
   1861      1.1      matt 	case R_RISCV_BRANCH:
   1862      1.4  christos 	case R_RISCV_RVC_BRANCH:
   1863      1.4  christos 	case R_RISCV_RVC_LUI:
   1864      1.4  christos 	case R_RISCV_LO12_I:
   1865      1.4  christos 	case R_RISCV_LO12_S:
   1866      1.4  christos 	case R_RISCV_SET6:
   1867      1.4  christos 	case R_RISCV_SET8:
   1868      1.4  christos 	case R_RISCV_SET16:
   1869      1.4  christos 	case R_RISCV_SET32:
   1870      1.4  christos 	case R_RISCV_32_PCREL:
   1871      1.4  christos 	case R_RISCV_DELETE:
   1872      1.1      matt 	  /* These require no special handling beyond perform_relocation.  */
   1873      1.1      matt 	  break;
   1874      1.1      matt 
   1875      1.1      matt 	case R_RISCV_GOT_HI20:
   1876      1.1      matt 	  if (h != NULL)
   1877      1.1      matt 	    {
   1878      1.4  christos 	      bfd_boolean dyn, pic;
   1879      1.1      matt 
   1880      1.1      matt 	      off = h->got.offset;
   1881      1.1      matt 	      BFD_ASSERT (off != (bfd_vma) -1);
   1882      1.1      matt 	      dyn = elf_hash_table (info)->dynamic_sections_created;
   1883      1.4  christos 	      pic = bfd_link_pic (info);
   1884      1.1      matt 
   1885      1.4  christos 	      if (! WILL_CALL_FINISH_DYNAMIC_SYMBOL (dyn, pic, h)
   1886      1.4  christos 		  || (pic && SYMBOL_REFERENCES_LOCAL (info, h)))
   1887      1.1      matt 		{
   1888      1.1      matt 		  /* This is actually a static link, or it is a
   1889      1.1      matt 		     -Bsymbolic link and the symbol is defined
   1890      1.1      matt 		     locally, or the symbol was forced to be local
   1891      1.1      matt 		     because of a version file.  We must initialize
   1892      1.1      matt 		     this entry in the global offset table.  Since the
   1893      1.1      matt 		     offset must always be a multiple of the word size,
   1894      1.1      matt 		     we use the least significant bit to record whether
   1895      1.1      matt 		     we have initialized it already.
   1896      1.1      matt 
   1897      1.1      matt 		     When doing a dynamic link, we create a .rela.got
   1898      1.1      matt 		     relocation entry to initialize the value.  This
   1899      1.1      matt 		     is done in the finish_dynamic_symbol routine.  */
   1900      1.1      matt 		  if ((off & 1) != 0)
   1901      1.1      matt 		    off &= ~1;
   1902      1.1      matt 		  else
   1903      1.1      matt 		    {
   1904      1.1      matt 		      bfd_put_NN (output_bfd, relocation,
   1905      1.1      matt 				  htab->elf.sgot->contents + off);
   1906      1.1      matt 		      h->got.offset |= 1;
   1907      1.1      matt 		    }
   1908      1.1      matt 		}
   1909      1.1      matt 	      else
   1910      1.1      matt 		unresolved_reloc = FALSE;
   1911      1.1      matt 	    }
   1912      1.1      matt 	  else
   1913      1.1      matt 	    {
   1914      1.1      matt 	      BFD_ASSERT (local_got_offsets != NULL
   1915      1.1      matt 			  && local_got_offsets[r_symndx] != (bfd_vma) -1);
   1916      1.1      matt 
   1917      1.1      matt 	      off = local_got_offsets[r_symndx];
   1918      1.1      matt 
   1919      1.4  christos 	      /* The offset must always be a multiple of the word size.
   1920      1.4  christos 		 So, we can use the least significant bit to record
   1921      1.1      matt 		 whether we have already processed this entry.  */
   1922      1.1      matt 	      if ((off & 1) != 0)
   1923      1.1      matt 		off &= ~1;
   1924      1.1      matt 	      else
   1925      1.1      matt 		{
   1926      1.3  christos 		  if (bfd_link_pic (info))
   1927      1.1      matt 		    {
   1928      1.1      matt 		      asection *s;
   1929      1.1      matt 		      Elf_Internal_Rela outrel;
   1930      1.1      matt 
   1931      1.1      matt 		      /* We need to generate a R_RISCV_RELATIVE reloc
   1932      1.1      matt 			 for the dynamic linker.  */
   1933      1.1      matt 		      s = htab->elf.srelgot;
   1934      1.1      matt 		      BFD_ASSERT (s != NULL);
   1935      1.1      matt 
   1936      1.1      matt 		      outrel.r_offset = sec_addr (htab->elf.sgot) + off;
   1937      1.1      matt 		      outrel.r_info =
   1938      1.1      matt 			ELFNN_R_INFO (0, R_RISCV_RELATIVE);
   1939      1.1      matt 		      outrel.r_addend = relocation;
   1940      1.1      matt 		      relocation = 0;
   1941      1.1      matt 		      riscv_elf_append_rela (output_bfd, s, &outrel);
   1942      1.1      matt 		    }
   1943      1.1      matt 
   1944      1.1      matt 		  bfd_put_NN (output_bfd, relocation,
   1945      1.1      matt 			      htab->elf.sgot->contents + off);
   1946      1.1      matt 		  local_got_offsets[r_symndx] |= 1;
   1947      1.1      matt 		}
   1948      1.1      matt 	    }
   1949      1.1      matt 	  relocation = sec_addr (htab->elf.sgot) + off;
   1950      1.4  christos 	  absolute = riscv_zero_pcrel_hi_reloc (rel,
   1951      1.4  christos 						info,
   1952      1.4  christos 						pc,
   1953      1.4  christos 						relocation,
   1954      1.4  christos 						contents,
   1955      1.4  christos 						howto,
   1956      1.4  christos 						input_bfd);
   1957      1.4  christos 	  r_type = ELFNN_R_TYPE (rel->r_info);
   1958  1.4.2.1  christos 	  howto = riscv_elf_rtype_to_howto (input_bfd, r_type);
   1959  1.4.2.1  christos 	  if (howto == NULL)
   1960  1.4.2.1  christos 	    r = bfd_reloc_notsupported;
   1961  1.4.2.1  christos 	  else if (!riscv_record_pcrel_hi_reloc (&pcrel_relocs, pc,
   1962  1.4.2.1  christos 						 relocation, absolute))
   1963      1.1      matt 	    r = bfd_reloc_overflow;
   1964      1.1      matt 	  break;
   1965      1.1      matt 
   1966      1.1      matt 	case R_RISCV_ADD8:
   1967      1.1      matt 	case R_RISCV_ADD16:
   1968      1.1      matt 	case R_RISCV_ADD32:
   1969      1.1      matt 	case R_RISCV_ADD64:
   1970      1.1      matt 	  {
   1971      1.1      matt 	    bfd_vma old_value = bfd_get (howto->bitsize, input_bfd,
   1972      1.1      matt 					 contents + rel->r_offset);
   1973      1.1      matt 	    relocation = old_value + relocation;
   1974      1.1      matt 	  }
   1975      1.1      matt 	  break;
   1976      1.1      matt 
   1977      1.4  christos 	case R_RISCV_SUB6:
   1978      1.1      matt 	case R_RISCV_SUB8:
   1979      1.1      matt 	case R_RISCV_SUB16:
   1980      1.1      matt 	case R_RISCV_SUB32:
   1981      1.1      matt 	case R_RISCV_SUB64:
   1982      1.1      matt 	  {
   1983      1.1      matt 	    bfd_vma old_value = bfd_get (howto->bitsize, input_bfd,
   1984      1.1      matt 					 contents + rel->r_offset);
   1985      1.1      matt 	    relocation = old_value - relocation;
   1986      1.1      matt 	  }
   1987      1.1      matt 	  break;
   1988      1.1      matt 
   1989      1.1      matt 	case R_RISCV_CALL:
   1990  1.4.2.2    martin 	case R_RISCV_CALL_PLT:
   1991  1.4.2.1  christos 	  /* Handle a call to an undefined weak function.  This won't be
   1992  1.4.2.1  christos 	     relaxed, so we have to handle it here.  */
   1993  1.4.2.1  christos 	  if (h != NULL && h->root.type == bfd_link_hash_undefweak
   1994  1.4.2.2    martin 	      && (!bfd_link_pic (info) || h->plt.offset == MINUS_ONE))
   1995  1.4.2.1  christos 	    {
   1996  1.4.2.1  christos 	      /* We can use x0 as the base register.  */
   1997  1.4.2.1  christos 	      bfd_vma insn = bfd_get_32 (input_bfd,
   1998  1.4.2.1  christos 					 contents + rel->r_offset + 4);
   1999  1.4.2.1  christos 	      insn &= ~(OP_MASK_RS1 << OP_SH_RS1);
   2000  1.4.2.1  christos 	      bfd_put_32 (input_bfd, insn, contents + rel->r_offset + 4);
   2001  1.4.2.1  christos 	      /* Set the relocation value so that we get 0 after the pc
   2002  1.4.2.1  christos 		 relative adjustment.  */
   2003  1.4.2.1  christos 	      relocation = sec_addr (input_section) + rel->r_offset;
   2004  1.4.2.1  christos 	    }
   2005  1.4.2.1  christos 	  /* Fall through.  */
   2006  1.4.2.1  christos 
   2007      1.1      matt 	case R_RISCV_JAL:
   2008      1.4  christos 	case R_RISCV_RVC_JUMP:
   2009  1.4.2.2    martin 	  /* This line has to match the check in _bfd_riscv_relax_section.  */
   2010      1.3  christos 	  if (bfd_link_pic (info) && h != NULL && h->plt.offset != MINUS_ONE)
   2011      1.1      matt 	    {
   2012      1.1      matt 	      /* Refer to the PLT entry.  */
   2013      1.1      matt 	      relocation = sec_addr (htab->elf.splt) + h->plt.offset;
   2014      1.1      matt 	      unresolved_reloc = FALSE;
   2015      1.1      matt 	    }
   2016      1.1      matt 	  break;
   2017      1.1      matt 
   2018      1.1      matt 	case R_RISCV_TPREL_HI20:
   2019      1.1      matt 	  relocation = tpoff (info, relocation);
   2020      1.1      matt 	  break;
   2021      1.1      matt 
   2022      1.1      matt 	case R_RISCV_TPREL_LO12_I:
   2023      1.1      matt 	case R_RISCV_TPREL_LO12_S:
   2024      1.1      matt 	  relocation = tpoff (info, relocation);
   2025      1.4  christos 	  break;
   2026      1.4  christos 
   2027      1.4  christos 	case R_RISCV_TPREL_I:
   2028      1.4  christos 	case R_RISCV_TPREL_S:
   2029      1.4  christos 	  relocation = tpoff (info, relocation);
   2030      1.1      matt 	  if (VALID_ITYPE_IMM (relocation + rel->r_addend))
   2031      1.1      matt 	    {
   2032      1.1      matt 	      /* We can use tp as the base register.  */
   2033      1.1      matt 	      bfd_vma insn = bfd_get_32 (input_bfd, contents + rel->r_offset);
   2034      1.1      matt 	      insn &= ~(OP_MASK_RS1 << OP_SH_RS1);
   2035      1.1      matt 	      insn |= X_TP << OP_SH_RS1;
   2036      1.1      matt 	      bfd_put_32 (input_bfd, insn, contents + rel->r_offset);
   2037      1.1      matt 	    }
   2038      1.4  christos 	  else
   2039      1.4  christos 	    r = bfd_reloc_overflow;
   2040      1.1      matt 	  break;
   2041      1.1      matt 
   2042      1.4  christos 	case R_RISCV_GPREL_I:
   2043      1.4  christos 	case R_RISCV_GPREL_S:
   2044      1.1      matt 	  {
   2045      1.1      matt 	    bfd_vma gp = riscv_global_pointer_value (info);
   2046      1.1      matt 	    bfd_boolean x0_base = VALID_ITYPE_IMM (relocation + rel->r_addend);
   2047      1.1      matt 	    if (x0_base || VALID_ITYPE_IMM (relocation + rel->r_addend - gp))
   2048      1.1      matt 	      {
   2049      1.1      matt 		/* We can use x0 or gp as the base register.  */
   2050      1.1      matt 		bfd_vma insn = bfd_get_32 (input_bfd, contents + rel->r_offset);
   2051      1.1      matt 		insn &= ~(OP_MASK_RS1 << OP_SH_RS1);
   2052      1.1      matt 		if (!x0_base)
   2053      1.1      matt 		  {
   2054      1.1      matt 		    rel->r_addend -= gp;
   2055      1.1      matt 		    insn |= X_GP << OP_SH_RS1;
   2056      1.1      matt 		  }
   2057      1.1      matt 		bfd_put_32 (input_bfd, insn, contents + rel->r_offset);
   2058      1.1      matt 	      }
   2059      1.4  christos 	    else
   2060      1.4  christos 	      r = bfd_reloc_overflow;
   2061      1.1      matt 	    break;
   2062      1.1      matt 	  }
   2063      1.1      matt 
   2064      1.1      matt 	case R_RISCV_PCREL_HI20:
   2065      1.4  christos 	  absolute = riscv_zero_pcrel_hi_reloc (rel,
   2066      1.4  christos 						info,
   2067      1.4  christos 						pc,
   2068      1.4  christos 						relocation,
   2069      1.4  christos 						contents,
   2070      1.4  christos 						howto,
   2071      1.4  christos 						input_bfd);
   2072      1.4  christos 	  r_type = ELFNN_R_TYPE (rel->r_info);
   2073  1.4.2.1  christos 	  howto = riscv_elf_rtype_to_howto (input_bfd, r_type);
   2074  1.4.2.1  christos 	  if (howto == NULL)
   2075  1.4.2.1  christos 	    r = bfd_reloc_notsupported;
   2076  1.4.2.1  christos 	  else if (!riscv_record_pcrel_hi_reloc (&pcrel_relocs, pc,
   2077  1.4.2.1  christos 						 relocation + rel->r_addend,
   2078  1.4.2.1  christos 						 absolute))
   2079      1.1      matt 	    r = bfd_reloc_overflow;
   2080      1.1      matt 	  break;
   2081      1.1      matt 
   2082      1.1      matt 	case R_RISCV_PCREL_LO12_I:
   2083      1.1      matt 	case R_RISCV_PCREL_LO12_S:
   2084  1.4.2.2    martin 	  /* We don't allow section symbols plus addends as the auipc address,
   2085  1.4.2.2    martin 	     because then riscv_relax_delete_bytes would have to search through
   2086  1.4.2.2    martin 	     all relocs to update these addends.  This is also ambiguous, as
   2087  1.4.2.2    martin 	     we do allow offsets to be added to the target address, which are
   2088  1.4.2.2    martin 	     not to be used to find the auipc address.  */
   2089  1.4.2.2    martin 	  if (((sym != NULL && (ELF_ST_TYPE (sym->st_info) == STT_SECTION))
   2090  1.4.2.2    martin 	       || (h != NULL && h->type == STT_SECTION))
   2091  1.4.2.2    martin 	      && rel->r_addend)
   2092  1.4.2.1  christos 	    {
   2093  1.4.2.2    martin 	      msg = _("%pcrel_lo section symbol with an addend");
   2094  1.4.2.1  christos 	      r = bfd_reloc_dangerous;
   2095  1.4.2.1  christos 	      break;
   2096  1.4.2.1  christos 	    }
   2097  1.4.2.1  christos 
   2098      1.1      matt 	  if (riscv_record_pcrel_lo_reloc (&pcrel_relocs, input_section, info,
   2099      1.1      matt 					   howto, rel, relocation, name,
   2100      1.1      matt 					   contents))
   2101      1.1      matt 	    continue;
   2102      1.1      matt 	  r = bfd_reloc_overflow;
   2103      1.1      matt 	  break;
   2104      1.1      matt 
   2105      1.1      matt 	case R_RISCV_TLS_DTPREL32:
   2106      1.1      matt 	case R_RISCV_TLS_DTPREL64:
   2107      1.1      matt 	  relocation = dtpoff (info, relocation);
   2108      1.1      matt 	  break;
   2109      1.1      matt 
   2110      1.1      matt 	case R_RISCV_32:
   2111      1.1      matt 	case R_RISCV_64:
   2112      1.1      matt 	  if ((input_section->flags & SEC_ALLOC) == 0)
   2113      1.1      matt 	    break;
   2114      1.1      matt 
   2115      1.3  christos 	  if ((bfd_link_pic (info)
   2116      1.1      matt 	       && (h == NULL
   2117  1.4.2.1  christos 		   || (ELF_ST_VISIBILITY (h->other) == STV_DEFAULT
   2118  1.4.2.1  christos 		       && !resolved_to_zero)
   2119      1.1      matt 		   || h->root.type != bfd_link_hash_undefweak)
   2120      1.1      matt 	       && (! howto->pc_relative
   2121      1.1      matt 		   || !SYMBOL_CALLS_LOCAL (info, h)))
   2122      1.3  christos 	      || (!bfd_link_pic (info)
   2123      1.1      matt 		  && h != NULL
   2124      1.1      matt 		  && h->dynindx != -1
   2125      1.1      matt 		  && !h->non_got_ref
   2126      1.1      matt 		  && ((h->def_dynamic
   2127      1.1      matt 		       && !h->def_regular)
   2128      1.1      matt 		      || h->root.type == bfd_link_hash_undefweak
   2129      1.1      matt 		      || h->root.type == bfd_link_hash_undefined)))
   2130      1.1      matt 	    {
   2131      1.1      matt 	      Elf_Internal_Rela outrel;
   2132      1.1      matt 	      bfd_boolean skip_static_relocation, skip_dynamic_relocation;
   2133      1.1      matt 
   2134      1.1      matt 	      /* When generating a shared object, these relocations
   2135      1.1      matt 		 are copied into the output file to be resolved at run
   2136      1.1      matt 		 time.  */
   2137      1.1      matt 
   2138      1.1      matt 	      outrel.r_offset =
   2139      1.1      matt 		_bfd_elf_section_offset (output_bfd, info, input_section,
   2140      1.1      matt 					 rel->r_offset);
   2141      1.1      matt 	      skip_static_relocation = outrel.r_offset != (bfd_vma) -2;
   2142      1.1      matt 	      skip_dynamic_relocation = outrel.r_offset >= (bfd_vma) -2;
   2143      1.1      matt 	      outrel.r_offset += sec_addr (input_section);
   2144      1.1      matt 
   2145      1.1      matt 	      if (skip_dynamic_relocation)
   2146      1.1      matt 		memset (&outrel, 0, sizeof outrel);
   2147      1.1      matt 	      else if (h != NULL && h->dynindx != -1
   2148      1.3  christos 		       && !(bfd_link_pic (info)
   2149      1.1      matt 			    && SYMBOLIC_BIND (info, h)
   2150      1.1      matt 			    && h->def_regular))
   2151      1.1      matt 		{
   2152      1.1      matt 		  outrel.r_info = ELFNN_R_INFO (h->dynindx, r_type);
   2153      1.1      matt 		  outrel.r_addend = rel->r_addend;
   2154      1.1      matt 		}
   2155      1.1      matt 	      else
   2156      1.1      matt 		{
   2157      1.1      matt 		  outrel.r_info = ELFNN_R_INFO (0, R_RISCV_RELATIVE);
   2158      1.1      matt 		  outrel.r_addend = relocation + rel->r_addend;
   2159      1.1      matt 		}
   2160      1.1      matt 
   2161      1.1      matt 	      riscv_elf_append_rela (output_bfd, sreloc, &outrel);
   2162      1.1      matt 	      if (skip_static_relocation)
   2163      1.1      matt 		continue;
   2164      1.1      matt 	    }
   2165      1.1      matt 	  break;
   2166      1.1      matt 
   2167      1.1      matt 	case R_RISCV_TLS_GOT_HI20:
   2168      1.1      matt 	  is_ie = TRUE;
   2169      1.1      matt 	  /* Fall through.  */
   2170      1.1      matt 
   2171      1.1      matt 	case R_RISCV_TLS_GD_HI20:
   2172      1.1      matt 	  if (h != NULL)
   2173      1.1      matt 	    {
   2174      1.1      matt 	      off = h->got.offset;
   2175      1.1      matt 	      h->got.offset |= 1;
   2176      1.1      matt 	    }
   2177      1.1      matt 	  else
   2178      1.1      matt 	    {
   2179      1.1      matt 	      off = local_got_offsets[r_symndx];
   2180      1.1      matt 	      local_got_offsets[r_symndx] |= 1;
   2181      1.1      matt 	    }
   2182      1.1      matt 
   2183      1.1      matt 	  tls_type = _bfd_riscv_elf_tls_type (input_bfd, h, r_symndx);
   2184      1.1      matt 	  BFD_ASSERT (tls_type & (GOT_TLS_IE | GOT_TLS_GD));
   2185      1.1      matt 	  /* If this symbol is referenced by both GD and IE TLS, the IE
   2186      1.1      matt 	     reference's GOT slot follows the GD reference's slots.  */
   2187      1.1      matt 	  ie_off = 0;
   2188      1.1      matt 	  if ((tls_type & GOT_TLS_GD) && (tls_type & GOT_TLS_IE))
   2189      1.1      matt 	    ie_off = 2 * GOT_ENTRY_SIZE;
   2190      1.1      matt 
   2191      1.1      matt 	  if ((off & 1) != 0)
   2192      1.1      matt 	    off &= ~1;
   2193      1.1      matt 	  else
   2194      1.1      matt 	    {
   2195      1.1      matt 	      Elf_Internal_Rela outrel;
   2196      1.1      matt 	      int indx = 0;
   2197      1.1      matt 	      bfd_boolean need_relocs = FALSE;
   2198      1.1      matt 
   2199      1.1      matt 	      if (htab->elf.srelgot == NULL)
   2200      1.1      matt 		abort ();
   2201      1.1      matt 
   2202      1.1      matt 	      if (h != NULL)
   2203      1.4  christos 		{
   2204      1.4  christos 		  bfd_boolean dyn, pic;
   2205      1.4  christos 		  dyn = htab->elf.dynamic_sections_created;
   2206      1.4  christos 		  pic = bfd_link_pic (info);
   2207      1.1      matt 
   2208      1.4  christos 		  if (WILL_CALL_FINISH_DYNAMIC_SYMBOL (dyn, pic, h)
   2209      1.4  christos 		      && (!pic || !SYMBOL_REFERENCES_LOCAL (info, h)))
   2210      1.1      matt 		    indx = h->dynindx;
   2211      1.4  christos 		}
   2212      1.1      matt 
   2213      1.1      matt 	      /* The GOT entries have not been initialized yet.  Do it
   2214      1.4  christos 		 now, and emit any relocations.  */
   2215      1.3  christos 	      if ((bfd_link_pic (info) || indx != 0)
   2216      1.1      matt 		  && (h == NULL
   2217      1.1      matt 		      || ELF_ST_VISIBILITY (h->other) == STV_DEFAULT
   2218      1.1      matt 		      || h->root.type != bfd_link_hash_undefweak))
   2219      1.1      matt 		    need_relocs = TRUE;
   2220      1.1      matt 
   2221      1.1      matt 	      if (tls_type & GOT_TLS_GD)
   2222      1.1      matt 		{
   2223      1.1      matt 		  if (need_relocs)
   2224      1.1      matt 		    {
   2225      1.1      matt 		      outrel.r_offset = sec_addr (htab->elf.sgot) + off;
   2226      1.1      matt 		      outrel.r_addend = 0;
   2227      1.1      matt 		      outrel.r_info = ELFNN_R_INFO (indx, R_RISCV_TLS_DTPMODNN);
   2228      1.1      matt 		      bfd_put_NN (output_bfd, 0,
   2229      1.1      matt 				  htab->elf.sgot->contents + off);
   2230      1.1      matt 		      riscv_elf_append_rela (output_bfd, htab->elf.srelgot, &outrel);
   2231      1.1      matt 		      if (indx == 0)
   2232      1.4  christos 			{
   2233      1.1      matt 			  BFD_ASSERT (! unresolved_reloc);
   2234      1.1      matt 			  bfd_put_NN (output_bfd,
   2235      1.1      matt 				      dtpoff (info, relocation),
   2236      1.1      matt 				      (htab->elf.sgot->contents + off +
   2237      1.1      matt 				       RISCV_ELF_WORD_BYTES));
   2238      1.4  christos 			}
   2239      1.1      matt 		      else
   2240      1.4  christos 			{
   2241      1.1      matt 			  bfd_put_NN (output_bfd, 0,
   2242      1.1      matt 				      (htab->elf.sgot->contents + off +
   2243      1.1      matt 				       RISCV_ELF_WORD_BYTES));
   2244      1.4  christos 			  outrel.r_info = ELFNN_R_INFO (indx, R_RISCV_TLS_DTPRELNN);
   2245      1.4  christos 			  outrel.r_offset += RISCV_ELF_WORD_BYTES;
   2246      1.4  christos 			  riscv_elf_append_rela (output_bfd, htab->elf.srelgot, &outrel);
   2247      1.4  christos 			}
   2248      1.1      matt 		    }
   2249      1.1      matt 		  else
   2250      1.1      matt 		    {
   2251      1.1      matt 		      /* If we are not emitting relocations for a
   2252      1.4  christos 			 general dynamic reference, then we must be in a
   2253      1.4  christos 			 static link or an executable link with the
   2254      1.4  christos 			 symbol binding locally.  Mark it as belonging
   2255      1.4  christos 			 to module 1, the executable.  */
   2256      1.1      matt 		      bfd_put_NN (output_bfd, 1,
   2257      1.1      matt 				  htab->elf.sgot->contents + off);
   2258      1.1      matt 		      bfd_put_NN (output_bfd,
   2259      1.1      matt 				  dtpoff (info, relocation),
   2260      1.1      matt 				  (htab->elf.sgot->contents + off +
   2261      1.1      matt 				   RISCV_ELF_WORD_BYTES));
   2262      1.1      matt 		   }
   2263      1.1      matt 		}
   2264      1.1      matt 
   2265      1.1      matt 	      if (tls_type & GOT_TLS_IE)
   2266      1.1      matt 		{
   2267      1.1      matt 		  if (need_relocs)
   2268      1.1      matt 		    {
   2269      1.1      matt 		      bfd_put_NN (output_bfd, 0,
   2270      1.1      matt 				  htab->elf.sgot->contents + off + ie_off);
   2271      1.1      matt 		      outrel.r_offset = sec_addr (htab->elf.sgot)
   2272      1.1      matt 				       + off + ie_off;
   2273      1.1      matt 		      outrel.r_addend = 0;
   2274      1.1      matt 		      if (indx == 0)
   2275      1.4  christos 			outrel.r_addend = tpoff (info, relocation);
   2276      1.1      matt 		      outrel.r_info = ELFNN_R_INFO (indx, R_RISCV_TLS_TPRELNN);
   2277      1.1      matt 		      riscv_elf_append_rela (output_bfd, htab->elf.srelgot, &outrel);
   2278      1.1      matt 		    }
   2279      1.1      matt 		  else
   2280      1.1      matt 		    {
   2281      1.1      matt 		      bfd_put_NN (output_bfd, tpoff (info, relocation),
   2282      1.1      matt 				  htab->elf.sgot->contents + off + ie_off);
   2283      1.1      matt 		    }
   2284      1.1      matt 		}
   2285      1.1      matt 	    }
   2286      1.1      matt 
   2287      1.1      matt 	  BFD_ASSERT (off < (bfd_vma) -2);
   2288      1.1      matt 	  relocation = sec_addr (htab->elf.sgot) + off + (is_ie ? ie_off : 0);
   2289      1.4  christos 	  if (!riscv_record_pcrel_hi_reloc (&pcrel_relocs, pc,
   2290      1.4  christos 					    relocation, FALSE))
   2291      1.1      matt 	    r = bfd_reloc_overflow;
   2292      1.1      matt 	  unresolved_reloc = FALSE;
   2293      1.1      matt 	  break;
   2294      1.1      matt 
   2295      1.1      matt 	default:
   2296      1.1      matt 	  r = bfd_reloc_notsupported;
   2297      1.1      matt 	}
   2298      1.1      matt 
   2299      1.1      matt       /* Dynamic relocs are not propagated for SEC_DEBUGGING sections
   2300      1.1      matt 	 because such sections are not SEC_ALLOC and thus ld.so will
   2301      1.1      matt 	 not process them.  */
   2302      1.1      matt       if (unresolved_reloc
   2303      1.1      matt 	  && !((input_section->flags & SEC_DEBUGGING) != 0
   2304      1.1      matt 	       && h->def_dynamic)
   2305      1.1      matt 	  && _bfd_elf_section_offset (output_bfd, info, input_section,
   2306      1.1      matt 				      rel->r_offset) != (bfd_vma) -1)
   2307      1.1      matt 	{
   2308  1.4.2.2    martin 	  switch (r_type)
   2309  1.4.2.2    martin 	    {
   2310  1.4.2.2    martin 	    case R_RISCV_CALL:
   2311  1.4.2.2    martin 	    case R_RISCV_JAL:
   2312  1.4.2.2    martin 	    case R_RISCV_RVC_JUMP:
   2313  1.4.2.2    martin 	      if (asprintf (&msg_buf,
   2314  1.4.2.2    martin 			    _("%%X%%P: relocation %s against `%s' can "
   2315  1.4.2.2    martin 			      "not be used when making a shared object; "
   2316  1.4.2.2    martin 			      "recompile with -fPIC\n"),
   2317  1.4.2.2    martin 			    howto->name,
   2318  1.4.2.2    martin 			    h->root.root.string) == -1)
   2319  1.4.2.2    martin 		msg_buf = NULL;
   2320  1.4.2.2    martin 	      break;
   2321  1.4.2.2    martin 
   2322  1.4.2.2    martin 	    default:
   2323  1.4.2.2    martin 	      if (asprintf (&msg_buf,
   2324  1.4.2.2    martin 			    _("%%X%%P: unresolvable %s relocation against "
   2325  1.4.2.2    martin 			      "symbol `%s'\n"),
   2326  1.4.2.2    martin 			    howto->name,
   2327  1.4.2.2    martin 			    h->root.root.string) == -1)
   2328  1.4.2.2    martin 		msg_buf = NULL;
   2329  1.4.2.2    martin 	      break;
   2330  1.4.2.2    martin 	    }
   2331  1.4.2.2    martin 
   2332  1.4.2.2    martin 	  msg = msg_buf;
   2333  1.4.2.2    martin 	  r = bfd_reloc_notsupported;
   2334      1.1      matt 	}
   2335      1.1      matt 
   2336      1.1      matt       if (r == bfd_reloc_ok)
   2337      1.1      matt 	r = perform_relocation (howto, rel, relocation, input_section,
   2338      1.1      matt 				input_bfd, contents);
   2339      1.1      matt 
   2340  1.4.2.2    martin       /* We should have already detected the error and set message before.
   2341  1.4.2.2    martin 	 If the error message isn't set since the linker runs out of memory
   2342  1.4.2.2    martin 	 or we don't set it before, then we should set the default message
   2343  1.4.2.2    martin 	 with the "internal error" string here.  */
   2344      1.1      matt       switch (r)
   2345      1.1      matt 	{
   2346      1.1      matt 	case bfd_reloc_ok:
   2347      1.1      matt 	  continue;
   2348      1.4  christos 
   2349      1.1      matt 	case bfd_reloc_overflow:
   2350      1.4  christos 	  info->callbacks->reloc_overflow
   2351      1.1      matt 	    (info, (h ? &h->root : NULL), name, howto->name,
   2352      1.1      matt 	     (bfd_vma) 0, input_bfd, input_section, rel->r_offset);
   2353      1.1      matt 	  break;
   2354      1.4  christos 
   2355      1.1      matt 	case bfd_reloc_undefined:
   2356      1.4  christos 	  info->callbacks->undefined_symbol
   2357      1.1      matt 	    (info, name, input_bfd, input_section, rel->r_offset,
   2358      1.1      matt 	     TRUE);
   2359      1.1      matt 	  break;
   2360      1.4  christos 
   2361      1.1      matt 	case bfd_reloc_outofrange:
   2362  1.4.2.2    martin 	  if (msg == NULL)
   2363  1.4.2.2    martin 	    msg = _("%X%P: internal error: out of range error\n");
   2364      1.1      matt 	  break;
   2365      1.4  christos 
   2366      1.1      matt 	case bfd_reloc_notsupported:
   2367  1.4.2.2    martin 	  if (msg == NULL)
   2368  1.4.2.2    martin 	    msg = _("%X%P: internal error: unsupported relocation error\n");
   2369      1.1      matt 	  break;
   2370      1.4  christos 
   2371      1.1      matt 	case bfd_reloc_dangerous:
   2372  1.4.2.2    martin 	  /* The error message should already be set.  */
   2373  1.4.2.2    martin 	  if (msg == NULL)
   2374  1.4.2.2    martin 	    msg = _("dangerous relocation error");
   2375  1.4.2.1  christos 	  info->callbacks->reloc_dangerous
   2376  1.4.2.2    martin 	    (info, msg, input_bfd, input_section, rel->r_offset);
   2377      1.1      matt 	  break;
   2378      1.4  christos 
   2379      1.1      matt 	default:
   2380  1.4.2.1  christos 	  msg = _("%X%P: internal error: unknown error\n");
   2381      1.1      matt 	  break;
   2382      1.1      matt 	}
   2383      1.4  christos 
   2384  1.4.2.2    martin       /* Do not report error message for the dangerous relocation again.  */
   2385  1.4.2.2    martin       if (msg && r != bfd_reloc_dangerous)
   2386  1.4.2.1  christos 	info->callbacks->einfo (msg);
   2387  1.4.2.1  christos 
   2388  1.4.2.2    martin       /* Free the unused `msg_buf` if needed.  */
   2389  1.4.2.2    martin       if (msg_buf)
   2390  1.4.2.2    martin 	free (msg_buf);
   2391  1.4.2.2    martin 
   2392  1.4.2.1  christos       /* We already reported the error via a callback, so don't try to report
   2393  1.4.2.1  christos 	 it again by returning false.  That leads to spurious errors.  */
   2394  1.4.2.1  christos       ret = TRUE;
   2395      1.1      matt       goto out;
   2396      1.1      matt     }
   2397      1.1      matt 
   2398      1.1      matt   ret = riscv_resolve_pcrel_lo_relocs (&pcrel_relocs);
   2399      1.1      matt out:
   2400      1.1      matt   riscv_free_pcrel_relocs (&pcrel_relocs);
   2401      1.1      matt   return ret;
   2402      1.1      matt }
   2403      1.1      matt 
   2404      1.1      matt /* Finish up dynamic symbol handling.  We set the contents of various
   2405      1.1      matt    dynamic sections here.  */
   2406      1.1      matt 
   2407      1.1      matt static bfd_boolean
   2408      1.1      matt riscv_elf_finish_dynamic_symbol (bfd *output_bfd,
   2409      1.1      matt 				 struct bfd_link_info *info,
   2410      1.1      matt 				 struct elf_link_hash_entry *h,
   2411      1.1      matt 				 Elf_Internal_Sym *sym)
   2412      1.1      matt {
   2413      1.1      matt   struct riscv_elf_link_hash_table *htab = riscv_elf_hash_table (info);
   2414      1.1      matt   const struct elf_backend_data *bed = get_elf_backend_data (output_bfd);
   2415      1.1      matt 
   2416      1.1      matt   if (h->plt.offset != (bfd_vma) -1)
   2417      1.1      matt     {
   2418      1.1      matt       /* We've decided to create a PLT entry for this symbol.  */
   2419      1.1      matt       bfd_byte *loc;
   2420      1.1      matt       bfd_vma i, header_address, plt_idx, got_address;
   2421      1.1      matt       uint32_t plt_entry[PLT_ENTRY_INSNS];
   2422      1.1      matt       Elf_Internal_Rela rela;
   2423      1.1      matt 
   2424      1.1      matt       BFD_ASSERT (h->dynindx != -1);
   2425      1.1      matt 
   2426      1.1      matt       /* Calculate the address of the PLT header.  */
   2427      1.1      matt       header_address = sec_addr (htab->elf.splt);
   2428      1.1      matt 
   2429      1.1      matt       /* Calculate the index of the entry.  */
   2430      1.1      matt       plt_idx = (h->plt.offset - PLT_HEADER_SIZE) / PLT_ENTRY_SIZE;
   2431      1.1      matt 
   2432      1.1      matt       /* Calculate the address of the .got.plt entry.  */
   2433      1.1      matt       got_address = riscv_elf_got_plt_val (plt_idx, info);
   2434      1.1      matt 
   2435      1.1      matt       /* Find out where the .plt entry should go.  */
   2436      1.1      matt       loc = htab->elf.splt->contents + h->plt.offset;
   2437      1.1      matt 
   2438      1.1      matt       /* Fill in the PLT entry itself.  */
   2439  1.4.2.2    martin       if (! riscv_make_plt_entry (output_bfd, got_address,
   2440  1.4.2.2    martin 				  header_address + h->plt.offset,
   2441  1.4.2.2    martin 				  plt_entry))
   2442  1.4.2.2    martin 	return FALSE;
   2443  1.4.2.2    martin 
   2444      1.1      matt       for (i = 0; i < PLT_ENTRY_INSNS; i++)
   2445      1.1      matt 	bfd_put_32 (output_bfd, plt_entry[i], loc + 4*i);
   2446      1.1      matt 
   2447      1.1      matt       /* Fill in the initial value of the .got.plt entry.  */
   2448      1.1      matt       loc = htab->elf.sgotplt->contents
   2449      1.1      matt 	    + (got_address - sec_addr (htab->elf.sgotplt));
   2450      1.1      matt       bfd_put_NN (output_bfd, sec_addr (htab->elf.splt), loc);
   2451      1.1      matt 
   2452      1.1      matt       /* Fill in the entry in the .rela.plt section.  */
   2453      1.1      matt       rela.r_offset = got_address;
   2454      1.1      matt       rela.r_addend = 0;
   2455      1.1      matt       rela.r_info = ELFNN_R_INFO (h->dynindx, R_RISCV_JUMP_SLOT);
   2456      1.1      matt 
   2457      1.1      matt       loc = htab->elf.srelplt->contents + plt_idx * sizeof (ElfNN_External_Rela);
   2458      1.1      matt       bed->s->swap_reloca_out (output_bfd, &rela, loc);
   2459      1.1      matt 
   2460      1.1      matt       if (!h->def_regular)
   2461      1.1      matt 	{
   2462      1.1      matt 	  /* Mark the symbol as undefined, rather than as defined in
   2463      1.1      matt 	     the .plt section.  Leave the value alone.  */
   2464      1.1      matt 	  sym->st_shndx = SHN_UNDEF;
   2465      1.1      matt 	  /* If the symbol is weak, we do need to clear the value.
   2466      1.1      matt 	     Otherwise, the PLT entry would provide a definition for
   2467      1.1      matt 	     the symbol even if the symbol wasn't defined anywhere,
   2468      1.1      matt 	     and so the symbol would never be NULL.  */
   2469      1.1      matt 	  if (!h->ref_regular_nonweak)
   2470      1.1      matt 	    sym->st_value = 0;
   2471      1.1      matt 	}
   2472      1.1      matt     }
   2473      1.1      matt 
   2474      1.1      matt   if (h->got.offset != (bfd_vma) -1
   2475  1.4.2.1  christos       && !(riscv_elf_hash_entry (h)->tls_type & (GOT_TLS_GD | GOT_TLS_IE))
   2476  1.4.2.1  christos       && !UNDEFWEAK_NO_DYNAMIC_RELOC (info, h))
   2477      1.1      matt     {
   2478      1.1      matt       asection *sgot;
   2479      1.1      matt       asection *srela;
   2480      1.1      matt       Elf_Internal_Rela rela;
   2481      1.1      matt 
   2482      1.1      matt       /* This symbol has an entry in the GOT.  Set it up.  */
   2483      1.1      matt 
   2484      1.1      matt       sgot = htab->elf.sgot;
   2485      1.1      matt       srela = htab->elf.srelgot;
   2486      1.1      matt       BFD_ASSERT (sgot != NULL && srela != NULL);
   2487      1.1      matt 
   2488      1.1      matt       rela.r_offset = sec_addr (sgot) + (h->got.offset &~ (bfd_vma) 1);
   2489      1.1      matt 
   2490  1.4.2.1  christos       /* If this is a local symbol reference, we just want to emit a RELATIVE
   2491  1.4.2.1  christos 	 reloc.  This can happen if it is a -Bsymbolic link, or a pie link, or
   2492      1.1      matt 	 the symbol was forced to be local because of a version file.
   2493      1.1      matt 	 The entry in the global offset table will already have been
   2494      1.1      matt 	 initialized in the relocate_section function.  */
   2495      1.3  christos       if (bfd_link_pic (info)
   2496  1.4.2.1  christos 	  && SYMBOL_REFERENCES_LOCAL (info, h))
   2497      1.1      matt 	{
   2498  1.4.2.1  christos 	  BFD_ASSERT((h->got.offset & 1) != 0);
   2499      1.1      matt 	  asection *sec = h->root.u.def.section;
   2500      1.1      matt 	  rela.r_info = ELFNN_R_INFO (0, R_RISCV_RELATIVE);
   2501      1.1      matt 	  rela.r_addend = (h->root.u.def.value
   2502      1.1      matt 			   + sec->output_section->vma
   2503      1.1      matt 			   + sec->output_offset);
   2504      1.1      matt 	}
   2505      1.1      matt       else
   2506      1.1      matt 	{
   2507  1.4.2.1  christos 	  BFD_ASSERT((h->got.offset & 1) == 0);
   2508      1.1      matt 	  BFD_ASSERT (h->dynindx != -1);
   2509      1.1      matt 	  rela.r_info = ELFNN_R_INFO (h->dynindx, R_RISCV_NN);
   2510      1.1      matt 	  rela.r_addend = 0;
   2511      1.1      matt 	}
   2512      1.1      matt 
   2513      1.1      matt       bfd_put_NN (output_bfd, 0,
   2514      1.1      matt 		  sgot->contents + (h->got.offset & ~(bfd_vma) 1));
   2515      1.1      matt       riscv_elf_append_rela (output_bfd, srela, &rela);
   2516      1.1      matt     }
   2517      1.1      matt 
   2518      1.1      matt   if (h->needs_copy)
   2519      1.1      matt     {
   2520      1.1      matt       Elf_Internal_Rela rela;
   2521      1.4  christos       asection *s;
   2522      1.1      matt 
   2523      1.1      matt       /* This symbols needs a copy reloc.  Set it up.  */
   2524      1.1      matt       BFD_ASSERT (h->dynindx != -1);
   2525      1.1      matt 
   2526      1.1      matt       rela.r_offset = sec_addr (h->root.u.def.section) + h->root.u.def.value;
   2527      1.1      matt       rela.r_info = ELFNN_R_INFO (h->dynindx, R_RISCV_COPY);
   2528      1.1      matt       rela.r_addend = 0;
   2529      1.4  christos       if (h->root.u.def.section == htab->elf.sdynrelro)
   2530      1.4  christos 	s = htab->elf.sreldynrelro;
   2531      1.4  christos       else
   2532      1.4  christos 	s = htab->elf.srelbss;
   2533      1.4  christos       riscv_elf_append_rela (output_bfd, s, &rela);
   2534      1.1      matt     }
   2535      1.1      matt 
   2536      1.1      matt   /* Mark some specially defined symbols as absolute.  */
   2537      1.4  christos   if (h == htab->elf.hdynamic
   2538      1.1      matt       || (h == htab->elf.hgot || h == htab->elf.hplt))
   2539      1.1      matt     sym->st_shndx = SHN_ABS;
   2540      1.1      matt 
   2541      1.1      matt   return TRUE;
   2542      1.1      matt }
   2543      1.1      matt 
   2544      1.1      matt /* Finish up the dynamic sections.  */
   2545      1.1      matt 
   2546      1.1      matt static bfd_boolean
   2547      1.1      matt riscv_finish_dyn (bfd *output_bfd, struct bfd_link_info *info,
   2548      1.1      matt 		  bfd *dynobj, asection *sdyn)
   2549      1.1      matt {
   2550      1.1      matt   struct riscv_elf_link_hash_table *htab = riscv_elf_hash_table (info);
   2551      1.1      matt   const struct elf_backend_data *bed = get_elf_backend_data (output_bfd);
   2552      1.1      matt   size_t dynsize = bed->s->sizeof_dyn;
   2553      1.1      matt   bfd_byte *dyncon, *dynconend;
   2554      1.1      matt 
   2555      1.1      matt   dynconend = sdyn->contents + sdyn->size;
   2556      1.1      matt   for (dyncon = sdyn->contents; dyncon < dynconend; dyncon += dynsize)
   2557      1.1      matt     {
   2558      1.1      matt       Elf_Internal_Dyn dyn;
   2559      1.1      matt       asection *s;
   2560      1.1      matt 
   2561      1.1      matt       bed->s->swap_dyn_in (dynobj, dyncon, &dyn);
   2562      1.1      matt 
   2563      1.1      matt       switch (dyn.d_tag)
   2564      1.1      matt 	{
   2565      1.1      matt 	case DT_PLTGOT:
   2566      1.1      matt 	  s = htab->elf.sgotplt;
   2567      1.1      matt 	  dyn.d_un.d_ptr = s->output_section->vma + s->output_offset;
   2568      1.1      matt 	  break;
   2569      1.1      matt 	case DT_JMPREL:
   2570      1.1      matt 	  s = htab->elf.srelplt;
   2571      1.1      matt 	  dyn.d_un.d_ptr = s->output_section->vma + s->output_offset;
   2572      1.1      matt 	  break;
   2573      1.1      matt 	case DT_PLTRELSZ:
   2574      1.1      matt 	  s = htab->elf.srelplt;
   2575      1.1      matt 	  dyn.d_un.d_val = s->size;
   2576      1.1      matt 	  break;
   2577      1.1      matt 	default:
   2578      1.1      matt 	  continue;
   2579      1.1      matt 	}
   2580      1.1      matt 
   2581      1.1      matt       bed->s->swap_dyn_out (output_bfd, &dyn, dyncon);
   2582      1.1      matt     }
   2583      1.1      matt   return TRUE;
   2584      1.1      matt }
   2585      1.1      matt 
   2586      1.1      matt static bfd_boolean
   2587      1.1      matt riscv_elf_finish_dynamic_sections (bfd *output_bfd,
   2588      1.1      matt 				   struct bfd_link_info *info)
   2589      1.1      matt {
   2590      1.1      matt   bfd *dynobj;
   2591      1.1      matt   asection *sdyn;
   2592      1.1      matt   struct riscv_elf_link_hash_table *htab;
   2593      1.1      matt 
   2594      1.1      matt   htab = riscv_elf_hash_table (info);
   2595      1.1      matt   BFD_ASSERT (htab != NULL);
   2596      1.1      matt   dynobj = htab->elf.dynobj;
   2597      1.1      matt 
   2598      1.1      matt   sdyn = bfd_get_linker_section (dynobj, ".dynamic");
   2599      1.1      matt 
   2600      1.1      matt   if (elf_hash_table (info)->dynamic_sections_created)
   2601      1.1      matt     {
   2602      1.1      matt       asection *splt;
   2603      1.1      matt       bfd_boolean ret;
   2604      1.1      matt 
   2605      1.1      matt       splt = htab->elf.splt;
   2606      1.1      matt       BFD_ASSERT (splt != NULL && sdyn != NULL);
   2607      1.1      matt 
   2608      1.1      matt       ret = riscv_finish_dyn (output_bfd, info, dynobj, sdyn);
   2609      1.1      matt 
   2610      1.4  christos       if (!ret)
   2611      1.1      matt 	return ret;
   2612      1.1      matt 
   2613      1.1      matt       /* Fill in the head and tail entries in the procedure linkage table.  */
   2614      1.1      matt       if (splt->size > 0)
   2615      1.1      matt 	{
   2616      1.1      matt 	  int i;
   2617      1.1      matt 	  uint32_t plt_header[PLT_HEADER_INSNS];
   2618  1.4.2.2    martin 	  ret = riscv_make_plt_header (output_bfd,
   2619  1.4.2.2    martin 				       sec_addr (htab->elf.sgotplt),
   2620  1.4.2.2    martin 				       sec_addr (splt), plt_header);
   2621  1.4.2.2    martin 	  if (!ret)
   2622  1.4.2.2    martin 	    return ret;
   2623      1.1      matt 
   2624      1.1      matt 	  for (i = 0; i < PLT_HEADER_INSNS; i++)
   2625      1.1      matt 	    bfd_put_32 (output_bfd, plt_header[i], splt->contents + 4*i);
   2626      1.4  christos 
   2627      1.4  christos 	  elf_section_data (splt->output_section)->this_hdr.sh_entsize
   2628      1.4  christos 	    = PLT_ENTRY_SIZE;
   2629      1.1      matt 	}
   2630      1.1      matt     }
   2631      1.1      matt 
   2632      1.1      matt   if (htab->elf.sgotplt)
   2633      1.1      matt     {
   2634      1.4  christos       asection *output_section = htab->elf.sgotplt->output_section;
   2635      1.4  christos 
   2636      1.4  christos       if (bfd_is_abs_section (output_section))
   2637      1.1      matt 	{
   2638      1.1      matt 	  (*_bfd_error_handler)
   2639  1.4.2.1  christos 	    (_("discarded output section: `%pA'"), htab->elf.sgotplt);
   2640      1.1      matt 	  return FALSE;
   2641      1.1      matt 	}
   2642      1.1      matt 
   2643      1.1      matt       if (htab->elf.sgotplt->size > 0)
   2644      1.1      matt 	{
   2645      1.1      matt 	  /* Write the first two entries in .got.plt, needed for the dynamic
   2646      1.1      matt 	     linker.  */
   2647      1.1      matt 	  bfd_put_NN (output_bfd, (bfd_vma) -1, htab->elf.sgotplt->contents);
   2648      1.1      matt 	  bfd_put_NN (output_bfd, (bfd_vma) 0,
   2649      1.1      matt 		      htab->elf.sgotplt->contents + GOT_ENTRY_SIZE);
   2650      1.1      matt 	}
   2651      1.1      matt 
   2652      1.4  christos       elf_section_data (output_section)->this_hdr.sh_entsize = GOT_ENTRY_SIZE;
   2653      1.1      matt     }
   2654      1.1      matt 
   2655      1.1      matt   if (htab->elf.sgot)
   2656      1.1      matt     {
   2657      1.4  christos       asection *output_section = htab->elf.sgot->output_section;
   2658      1.4  christos 
   2659      1.1      matt       if (htab->elf.sgot->size > 0)
   2660      1.1      matt 	{
   2661      1.1      matt 	  /* Set the first entry in the global offset table to the address of
   2662      1.1      matt 	     the dynamic section.  */
   2663      1.1      matt 	  bfd_vma val = sdyn ? sec_addr (sdyn) : 0;
   2664      1.1      matt 	  bfd_put_NN (output_bfd, val, htab->elf.sgot->contents);
   2665      1.1      matt 	}
   2666      1.1      matt 
   2667      1.4  christos       elf_section_data (output_section)->this_hdr.sh_entsize = GOT_ENTRY_SIZE;
   2668      1.1      matt     }
   2669      1.1      matt 
   2670      1.1      matt   return TRUE;
   2671      1.1      matt }
   2672      1.1      matt 
   2673      1.1      matt /* Return address for Ith PLT stub in section PLT, for relocation REL
   2674      1.1      matt    or (bfd_vma) -1 if it should not be included.  */
   2675      1.1      matt 
   2676      1.1      matt static bfd_vma
   2677      1.1      matt riscv_elf_plt_sym_val (bfd_vma i, const asection *plt,
   2678      1.1      matt 		       const arelent *rel ATTRIBUTE_UNUSED)
   2679      1.1      matt {
   2680      1.1      matt   return plt->vma + PLT_HEADER_SIZE + i * PLT_ENTRY_SIZE;
   2681      1.1      matt }
   2682      1.1      matt 
   2683      1.1      matt static enum elf_reloc_type_class
   2684      1.4  christos riscv_reloc_type_class (const struct bfd_link_info *info ATTRIBUTE_UNUSED,
   2685      1.4  christos 			const asection *rel_sec ATTRIBUTE_UNUSED,
   2686      1.1      matt 			const Elf_Internal_Rela *rela)
   2687      1.1      matt {
   2688      1.1      matt   switch (ELFNN_R_TYPE (rela->r_info))
   2689      1.1      matt     {
   2690      1.1      matt     case R_RISCV_RELATIVE:
   2691      1.1      matt       return reloc_class_relative;
   2692      1.1      matt     case R_RISCV_JUMP_SLOT:
   2693      1.1      matt       return reloc_class_plt;
   2694      1.1      matt     case R_RISCV_COPY:
   2695      1.1      matt       return reloc_class_copy;
   2696      1.1      matt     default:
   2697      1.1      matt       return reloc_class_normal;
   2698      1.1      matt     }
   2699      1.1      matt }
   2700      1.1      matt 
   2701  1.4.2.2    martin /* Given the ELF header flags in FLAGS, it returns a string that describes the
   2702  1.4.2.2    martin    float ABI.  */
   2703  1.4.2.2    martin 
   2704  1.4.2.2    martin static const char *
   2705  1.4.2.2    martin riscv_float_abi_string (flagword flags)
   2706  1.4.2.2    martin {
   2707  1.4.2.2    martin   switch (flags & EF_RISCV_FLOAT_ABI)
   2708  1.4.2.2    martin     {
   2709  1.4.2.2    martin     case EF_RISCV_FLOAT_ABI_SOFT:
   2710  1.4.2.2    martin       return "soft-float";
   2711  1.4.2.2    martin       break;
   2712  1.4.2.2    martin     case EF_RISCV_FLOAT_ABI_SINGLE:
   2713  1.4.2.2    martin       return "single-float";
   2714  1.4.2.2    martin       break;
   2715  1.4.2.2    martin     case EF_RISCV_FLOAT_ABI_DOUBLE:
   2716  1.4.2.2    martin       return "double-float";
   2717  1.4.2.2    martin       break;
   2718  1.4.2.2    martin     case EF_RISCV_FLOAT_ABI_QUAD:
   2719  1.4.2.2    martin       return "quad-float";
   2720  1.4.2.2    martin       break;
   2721  1.4.2.2    martin     default:
   2722  1.4.2.2    martin       abort ();
   2723  1.4.2.2    martin     }
   2724  1.4.2.2    martin }
   2725  1.4.2.2    martin 
   2726  1.4.2.2    martin /* The information of architecture attribute.  */
   2727  1.4.2.2    martin static riscv_subset_list_t in_subsets;
   2728  1.4.2.2    martin static riscv_subset_list_t out_subsets;
   2729  1.4.2.2    martin static riscv_subset_list_t merged_subsets;
   2730  1.4.2.2    martin 
   2731  1.4.2.2    martin /* Predicator for standard extension.  */
   2732  1.4.2.2    martin 
   2733  1.4.2.2    martin static bfd_boolean
   2734  1.4.2.2    martin riscv_std_ext_p (const char *name)
   2735  1.4.2.2    martin {
   2736  1.4.2.2    martin   return (strlen (name) == 1) && (name[0] != 'x') && (name[0] != 's');
   2737  1.4.2.2    martin }
   2738  1.4.2.2    martin 
   2739  1.4.2.2    martin /* Predicator for non-standard extension.  */
   2740  1.4.2.2    martin 
   2741  1.4.2.2    martin static bfd_boolean
   2742  1.4.2.2    martin riscv_non_std_ext_p (const char *name)
   2743  1.4.2.2    martin {
   2744  1.4.2.2    martin   return (strlen (name) >= 2) && (name[0] == 'x');
   2745  1.4.2.2    martin }
   2746  1.4.2.2    martin 
   2747  1.4.2.2    martin /* Predicator for standard supervisor extension.  */
   2748  1.4.2.2    martin 
   2749  1.4.2.2    martin static bfd_boolean
   2750  1.4.2.2    martin riscv_std_sv_ext_p (const char *name)
   2751  1.4.2.2    martin {
   2752  1.4.2.2    martin   return (strlen (name) >= 2) && (name[0] == 's') && (name[1] != 'x');
   2753  1.4.2.2    martin }
   2754  1.4.2.2    martin 
   2755  1.4.2.2    martin /* Predicator for non-standard supervisor extension.  */
   2756  1.4.2.2    martin 
   2757  1.4.2.2    martin static bfd_boolean
   2758  1.4.2.2    martin riscv_non_std_sv_ext_p (const char *name)
   2759  1.4.2.2    martin {
   2760  1.4.2.2    martin   return (strlen (name) >= 3) && (name[0] == 's') && (name[1] == 'x');
   2761  1.4.2.2    martin }
   2762  1.4.2.2    martin 
   2763  1.4.2.2    martin /* Error handler when version mis-match.  */
   2764  1.4.2.2    martin 
   2765  1.4.2.2    martin static void
   2766  1.4.2.2    martin riscv_version_mismatch (bfd *ibfd,
   2767  1.4.2.2    martin 			struct riscv_subset_t *in,
   2768  1.4.2.2    martin 			struct riscv_subset_t *out)
   2769  1.4.2.2    martin {
   2770  1.4.2.2    martin   _bfd_error_handler
   2771  1.4.2.2    martin     (_("error: %pB: Mis-matched ISA version for '%s' extension. "
   2772  1.4.2.2    martin        "%d.%d vs %d.%d"),
   2773  1.4.2.2    martin        ibfd, in->name,
   2774  1.4.2.2    martin        in->major_version, in->minor_version,
   2775  1.4.2.2    martin        out->major_version, out->minor_version);
   2776  1.4.2.2    martin }
   2777  1.4.2.2    martin 
   2778  1.4.2.2    martin /* Return true if subset is 'i' or 'e'.  */
   2779  1.4.2.2    martin 
   2780  1.4.2.2    martin static bfd_boolean
   2781  1.4.2.2    martin riscv_i_or_e_p (bfd *ibfd,
   2782  1.4.2.2    martin 		const char *arch,
   2783  1.4.2.2    martin 		struct riscv_subset_t *subset)
   2784  1.4.2.2    martin {
   2785  1.4.2.2    martin   if ((strcasecmp (subset->name, "e") != 0)
   2786  1.4.2.2    martin       && (strcasecmp (subset->name, "i") != 0))
   2787  1.4.2.2    martin     {
   2788  1.4.2.2    martin       _bfd_error_handler
   2789  1.4.2.2    martin 	(_("error: %pB: corrupted ISA string '%s'. "
   2790  1.4.2.2    martin 	   "First letter should be 'i' or 'e' but got '%s'."),
   2791  1.4.2.2    martin 	   ibfd, arch, subset->name);
   2792  1.4.2.2    martin       return FALSE;
   2793  1.4.2.2    martin     }
   2794  1.4.2.2    martin   return TRUE;
   2795  1.4.2.2    martin }
   2796  1.4.2.2    martin 
   2797  1.4.2.2    martin /* Merge standard extensions.
   2798  1.4.2.2    martin 
   2799  1.4.2.2    martin    Return Value:
   2800  1.4.2.2    martin      Return FALSE if failed to merge.
   2801  1.4.2.2    martin 
   2802  1.4.2.2    martin    Arguments:
   2803  1.4.2.2    martin      `bfd`: bfd handler.
   2804  1.4.2.2    martin      `in_arch`: Raw arch string for input object.
   2805  1.4.2.2    martin      `out_arch`: Raw arch string for output object.
   2806  1.4.2.2    martin      `pin`: subset list for input object, and it'll skip all merged subset after
   2807  1.4.2.2    martin             merge.
   2808  1.4.2.2    martin      `pout`: Like `pin`, but for output object.  */
   2809  1.4.2.2    martin 
   2810  1.4.2.2    martin static bfd_boolean
   2811  1.4.2.2    martin riscv_merge_std_ext (bfd *ibfd,
   2812  1.4.2.2    martin 		     const char *in_arch,
   2813  1.4.2.2    martin 		     const char *out_arch,
   2814  1.4.2.2    martin 		     struct riscv_subset_t **pin,
   2815  1.4.2.2    martin 		     struct riscv_subset_t **pout)
   2816  1.4.2.2    martin {
   2817  1.4.2.2    martin   const char *standard_exts = riscv_supported_std_ext ();
   2818  1.4.2.2    martin   const char *p;
   2819  1.4.2.2    martin   struct riscv_subset_t *in = *pin;
   2820  1.4.2.2    martin   struct riscv_subset_t *out = *pout;
   2821  1.4.2.2    martin 
   2822  1.4.2.2    martin   /* First letter should be 'i' or 'e'.  */
   2823  1.4.2.2    martin   if (!riscv_i_or_e_p (ibfd, in_arch, in))
   2824  1.4.2.2    martin     return FALSE;
   2825  1.4.2.2    martin 
   2826  1.4.2.2    martin   if (!riscv_i_or_e_p (ibfd, out_arch, out))
   2827  1.4.2.2    martin     return FALSE;
   2828  1.4.2.2    martin 
   2829  1.4.2.2    martin   if (in->name[0] != out->name[0])
   2830  1.4.2.2    martin     {
   2831  1.4.2.2    martin       /* TODO: We might allow merge 'i' with 'e'.  */
   2832  1.4.2.2    martin       _bfd_error_handler
   2833  1.4.2.2    martin 	(_("error: %pB: Mis-matched ISA string to merge '%s' and '%s'."),
   2834  1.4.2.2    martin 	 ibfd, in->name, out->name);
   2835  1.4.2.2    martin       return FALSE;
   2836  1.4.2.2    martin     }
   2837  1.4.2.2    martin   else if ((in->major_version != out->major_version) ||
   2838  1.4.2.2    martin 	   (in->minor_version != out->minor_version))
   2839  1.4.2.2    martin     {
   2840  1.4.2.2    martin       /* TODO: Allow different merge policy.  */
   2841  1.4.2.2    martin       riscv_version_mismatch (ibfd, in, out);
   2842  1.4.2.2    martin       return FALSE;
   2843  1.4.2.2    martin     }
   2844  1.4.2.2    martin   else
   2845  1.4.2.2    martin     riscv_add_subset (&merged_subsets,
   2846  1.4.2.2    martin 		      in->name, in->major_version, in->minor_version);
   2847  1.4.2.2    martin 
   2848  1.4.2.2    martin   in = in->next;
   2849  1.4.2.2    martin   out = out->next;
   2850  1.4.2.2    martin 
   2851  1.4.2.2    martin   /* Handle standard extension first.  */
   2852  1.4.2.2    martin   for (p = standard_exts; *p; ++p)
   2853  1.4.2.2    martin     {
   2854  1.4.2.2    martin       char find_ext[2] = {*p, '\0'};
   2855  1.4.2.2    martin       struct riscv_subset_t *find_in =
   2856  1.4.2.2    martin 	riscv_lookup_subset (&in_subsets, find_ext);
   2857  1.4.2.2    martin       struct riscv_subset_t *find_out =
   2858  1.4.2.2    martin 	riscv_lookup_subset (&out_subsets, find_ext);
   2859  1.4.2.2    martin 
   2860  1.4.2.2    martin       if (find_in == NULL && find_out == NULL)
   2861  1.4.2.2    martin 	continue;
   2862  1.4.2.2    martin 
   2863  1.4.2.2    martin       /* Check version is same or not.  */
   2864  1.4.2.2    martin       /* TODO: Allow different merge policy.  */
   2865  1.4.2.2    martin       if ((find_in != NULL && find_out != NULL)
   2866  1.4.2.2    martin 	  && ((find_in->major_version != find_out->major_version)
   2867  1.4.2.2    martin 	      || (find_in->minor_version != find_out->minor_version)))
   2868  1.4.2.2    martin 	{
   2869  1.4.2.2    martin 	  riscv_version_mismatch (ibfd, in, out);
   2870  1.4.2.2    martin 	  return FALSE;
   2871  1.4.2.2    martin 	}
   2872  1.4.2.2    martin 
   2873  1.4.2.2    martin       struct riscv_subset_t *merged = find_in ? find_in : find_out;
   2874  1.4.2.2    martin       riscv_add_subset (&merged_subsets, merged->name,
   2875  1.4.2.2    martin 			merged->major_version, merged->minor_version);
   2876  1.4.2.2    martin     }
   2877  1.4.2.2    martin 
   2878  1.4.2.2    martin   /* Skip all standard extensions.  */
   2879  1.4.2.2    martin   while ((in != NULL) && riscv_std_ext_p (in->name)) in = in->next;
   2880  1.4.2.2    martin   while ((out != NULL) && riscv_std_ext_p (out->name)) out = out->next;
   2881  1.4.2.2    martin 
   2882  1.4.2.2    martin   *pin = in;
   2883  1.4.2.2    martin   *pout = out;
   2884  1.4.2.2    martin 
   2885  1.4.2.2    martin   return TRUE;
   2886  1.4.2.2    martin }
   2887  1.4.2.2    martin 
   2888  1.4.2.2    martin /* Merge non-standard and supervisor extensions.
   2889  1.4.2.2    martin    Return Value:
   2890  1.4.2.2    martin      Return FALSE if failed to merge.
   2891  1.4.2.2    martin 
   2892  1.4.2.2    martin    Arguments:
   2893  1.4.2.2    martin      `bfd`: bfd handler.
   2894  1.4.2.2    martin      `in_arch`: Raw arch string for input object.
   2895  1.4.2.2    martin      `out_arch`: Raw arch string for output object.
   2896  1.4.2.2    martin      `pin`: subset list for input object, and it'll skip all merged subset after
   2897  1.4.2.2    martin             merge.
   2898  1.4.2.2    martin      `pout`: Like `pin`, but for output object. */
   2899  1.4.2.2    martin 
   2900  1.4.2.2    martin static bfd_boolean
   2901  1.4.2.2    martin riscv_merge_non_std_and_sv_ext (bfd *ibfd,
   2902  1.4.2.2    martin 				riscv_subset_t **pin,
   2903  1.4.2.2    martin 				riscv_subset_t **pout,
   2904  1.4.2.2    martin 				bfd_boolean (*predicate_func) (const char *))
   2905  1.4.2.2    martin {
   2906  1.4.2.2    martin   riscv_subset_t *in = *pin;
   2907  1.4.2.2    martin   riscv_subset_t *out = *pout;
   2908  1.4.2.2    martin 
   2909  1.4.2.2    martin   for (in = *pin; in != NULL && predicate_func (in->name); in = in->next)
   2910  1.4.2.2    martin     riscv_add_subset (&merged_subsets, in->name, in->major_version,
   2911  1.4.2.2    martin 		      in->minor_version);
   2912  1.4.2.2    martin 
   2913  1.4.2.2    martin   for (out = *pout; out != NULL && predicate_func (out->name); out = out->next)
   2914  1.4.2.2    martin     {
   2915  1.4.2.2    martin       riscv_subset_t *find_ext =
   2916  1.4.2.2    martin 	riscv_lookup_subset (&merged_subsets, out->name);
   2917  1.4.2.2    martin       if (find_ext != NULL)
   2918  1.4.2.2    martin 	{
   2919  1.4.2.2    martin 	  /* Check version is same or not. */
   2920  1.4.2.2    martin 	  /* TODO: Allow different merge policy.  */
   2921  1.4.2.2    martin 	  if ((find_ext->major_version != out->major_version)
   2922  1.4.2.2    martin 	      || (find_ext->minor_version != out->minor_version))
   2923  1.4.2.2    martin 	    {
   2924  1.4.2.2    martin 	      riscv_version_mismatch (ibfd, find_ext, out);
   2925  1.4.2.2    martin 	      return FALSE;
   2926  1.4.2.2    martin 	    }
   2927  1.4.2.2    martin 	}
   2928  1.4.2.2    martin       else
   2929  1.4.2.2    martin 	riscv_add_subset (&merged_subsets, out->name,
   2930  1.4.2.2    martin 			  out->major_version, out->minor_version);
   2931  1.4.2.2    martin     }
   2932  1.4.2.2    martin 
   2933  1.4.2.2    martin   *pin = in;
   2934  1.4.2.2    martin   *pout = out;
   2935  1.4.2.2    martin   return TRUE;
   2936  1.4.2.2    martin }
   2937  1.4.2.2    martin 
   2938  1.4.2.2    martin /* Merge Tag_RISCV_arch attribute.  */
   2939  1.4.2.2    martin 
   2940  1.4.2.2    martin static char *
   2941  1.4.2.2    martin riscv_merge_arch_attr_info (bfd *ibfd, char *in_arch, char *out_arch)
   2942  1.4.2.2    martin {
   2943  1.4.2.2    martin   riscv_subset_t *in, *out;
   2944  1.4.2.2    martin   char *merged_arch_str;
   2945  1.4.2.2    martin 
   2946  1.4.2.2    martin   unsigned xlen_in, xlen_out;
   2947  1.4.2.2    martin   merged_subsets.head = NULL;
   2948  1.4.2.2    martin   merged_subsets.tail = NULL;
   2949  1.4.2.2    martin 
   2950  1.4.2.2    martin   riscv_parse_subset_t rpe_in;
   2951  1.4.2.2    martin   riscv_parse_subset_t rpe_out;
   2952  1.4.2.2    martin 
   2953  1.4.2.2    martin   rpe_in.subset_list = &in_subsets;
   2954  1.4.2.2    martin   rpe_in.error_handler = _bfd_error_handler;
   2955  1.4.2.2    martin   rpe_in.xlen = &xlen_in;
   2956  1.4.2.2    martin 
   2957  1.4.2.2    martin   rpe_out.subset_list = &out_subsets;
   2958  1.4.2.2    martin   rpe_out.error_handler = _bfd_error_handler;
   2959  1.4.2.2    martin   rpe_out.xlen = &xlen_out;
   2960  1.4.2.2    martin 
   2961  1.4.2.2    martin   if (in_arch == NULL && out_arch == NULL)
   2962  1.4.2.2    martin     return NULL;
   2963  1.4.2.2    martin 
   2964  1.4.2.2    martin   if (in_arch == NULL && out_arch != NULL)
   2965  1.4.2.2    martin     return out_arch;
   2966  1.4.2.2    martin 
   2967  1.4.2.2    martin   if (in_arch != NULL && out_arch == NULL)
   2968  1.4.2.2    martin     return in_arch;
   2969  1.4.2.2    martin 
   2970  1.4.2.2    martin   /* Parse subset from arch string.  */
   2971  1.4.2.2    martin   if (!riscv_parse_subset (&rpe_in, in_arch))
   2972  1.4.2.2    martin     return NULL;
   2973  1.4.2.2    martin 
   2974  1.4.2.2    martin   if (!riscv_parse_subset (&rpe_out, out_arch))
   2975  1.4.2.2    martin     return NULL;
   2976  1.4.2.2    martin 
   2977  1.4.2.2    martin   /* Checking XLEN.  */
   2978  1.4.2.2    martin   if (xlen_out != xlen_in)
   2979  1.4.2.2    martin     {
   2980  1.4.2.2    martin       _bfd_error_handler
   2981  1.4.2.2    martin 	(_("error: %pB: ISA string of input (%s) doesn't match "
   2982  1.4.2.2    martin 	   "output (%s)."), ibfd, in_arch, out_arch);
   2983  1.4.2.2    martin       return NULL;
   2984  1.4.2.2    martin     }
   2985  1.4.2.2    martin 
   2986  1.4.2.2    martin   /* Merge subset list.  */
   2987  1.4.2.2    martin   in = in_subsets.head;
   2988  1.4.2.2    martin   out = out_subsets.head;
   2989  1.4.2.2    martin 
   2990  1.4.2.2    martin   /* Merge standard extension.  */
   2991  1.4.2.2    martin   if (!riscv_merge_std_ext (ibfd, in_arch, out_arch, &in, &out))
   2992  1.4.2.2    martin     return NULL;
   2993  1.4.2.2    martin   /* Merge non-standard extension.  */
   2994  1.4.2.2    martin   if (!riscv_merge_non_std_and_sv_ext (ibfd, &in, &out, riscv_non_std_ext_p))
   2995  1.4.2.2    martin     return NULL;
   2996  1.4.2.2    martin   /* Merge standard supervisor extension.  */
   2997  1.4.2.2    martin   if (!riscv_merge_non_std_and_sv_ext (ibfd, &in, &out, riscv_std_sv_ext_p))
   2998  1.4.2.2    martin     return NULL;
   2999  1.4.2.2    martin   /* Merge non-standard supervisor extension.  */
   3000  1.4.2.2    martin   if (!riscv_merge_non_std_and_sv_ext (ibfd, &in, &out, riscv_non_std_sv_ext_p))
   3001  1.4.2.2    martin     return NULL;
   3002  1.4.2.2    martin 
   3003  1.4.2.2    martin   if (xlen_in != xlen_out)
   3004  1.4.2.2    martin     {
   3005  1.4.2.2    martin       _bfd_error_handler
   3006  1.4.2.2    martin 	(_("error: %pB: XLEN of input (%u) doesn't match "
   3007  1.4.2.2    martin 	   "output (%u)."), ibfd, xlen_in, xlen_out);
   3008  1.4.2.2    martin       return NULL;
   3009  1.4.2.2    martin     }
   3010  1.4.2.2    martin 
   3011  1.4.2.2    martin   if (xlen_in != ARCH_SIZE)
   3012  1.4.2.2    martin     {
   3013  1.4.2.2    martin       _bfd_error_handler
   3014  1.4.2.2    martin 	(_("error: %pB: Unsupported XLEN (%u), you might be "
   3015  1.4.2.2    martin 	   "using wrong emulation."), ibfd, xlen_in);
   3016  1.4.2.2    martin       return NULL;
   3017  1.4.2.2    martin     }
   3018  1.4.2.2    martin 
   3019  1.4.2.2    martin   merged_arch_str = riscv_arch_str (ARCH_SIZE, &merged_subsets);
   3020  1.4.2.2    martin 
   3021  1.4.2.2    martin   /* Release the subset lists.  */
   3022  1.4.2.2    martin   riscv_release_subset_list (&in_subsets);
   3023  1.4.2.2    martin   riscv_release_subset_list (&out_subsets);
   3024  1.4.2.2    martin   riscv_release_subset_list (&merged_subsets);
   3025  1.4.2.2    martin 
   3026  1.4.2.2    martin   return merged_arch_str;
   3027  1.4.2.2    martin }
   3028  1.4.2.2    martin 
   3029  1.4.2.2    martin /* Merge object attributes from IBFD into output_bfd of INFO.
   3030  1.4.2.2    martin    Raise an error if there are conflicting attributes.  */
   3031  1.4.2.2    martin 
   3032  1.4.2.2    martin static bfd_boolean
   3033  1.4.2.2    martin riscv_merge_attributes (bfd *ibfd, struct bfd_link_info *info)
   3034  1.4.2.2    martin {
   3035  1.4.2.2    martin   bfd *obfd = info->output_bfd;
   3036  1.4.2.2    martin   obj_attribute *in_attr;
   3037  1.4.2.2    martin   obj_attribute *out_attr;
   3038  1.4.2.2    martin   bfd_boolean result = TRUE;
   3039  1.4.2.2    martin   const char *sec_name = get_elf_backend_data (ibfd)->obj_attrs_section;
   3040  1.4.2.2    martin   unsigned int i;
   3041  1.4.2.2    martin 
   3042  1.4.2.2    martin   /* Skip linker created files.  */
   3043  1.4.2.2    martin   if (ibfd->flags & BFD_LINKER_CREATED)
   3044  1.4.2.2    martin     return TRUE;
   3045  1.4.2.2    martin 
   3046  1.4.2.2    martin   /* Skip any input that doesn't have an attribute section.
   3047  1.4.2.2    martin      This enables to link object files without attribute section with
   3048  1.4.2.2    martin      any others.  */
   3049  1.4.2.2    martin   if (bfd_get_section_by_name (ibfd, sec_name) == NULL)
   3050  1.4.2.2    martin     return TRUE;
   3051  1.4.2.2    martin 
   3052  1.4.2.2    martin   if (!elf_known_obj_attributes_proc (obfd)[0].i)
   3053  1.4.2.2    martin     {
   3054  1.4.2.2    martin       /* This is the first object.  Copy the attributes.  */
   3055  1.4.2.2    martin       _bfd_elf_copy_obj_attributes (ibfd, obfd);
   3056  1.4.2.2    martin 
   3057  1.4.2.2    martin       out_attr = elf_known_obj_attributes_proc (obfd);
   3058  1.4.2.2    martin 
   3059  1.4.2.2    martin       /* Use the Tag_null value to indicate the attributes have been
   3060  1.4.2.2    martin 	 initialized.  */
   3061  1.4.2.2    martin       out_attr[0].i = 1;
   3062  1.4.2.2    martin 
   3063  1.4.2.2    martin       return TRUE;
   3064  1.4.2.2    martin     }
   3065  1.4.2.2    martin 
   3066  1.4.2.2    martin   in_attr = elf_known_obj_attributes_proc (ibfd);
   3067  1.4.2.2    martin   out_attr = elf_known_obj_attributes_proc (obfd);
   3068  1.4.2.2    martin 
   3069  1.4.2.2    martin   for (i = LEAST_KNOWN_OBJ_ATTRIBUTE; i < NUM_KNOWN_OBJ_ATTRIBUTES; i++)
   3070  1.4.2.2    martin     {
   3071  1.4.2.2    martin     switch (i)
   3072  1.4.2.2    martin       {
   3073  1.4.2.2    martin       case Tag_RISCV_arch:
   3074  1.4.2.2    martin 	if (!out_attr[Tag_RISCV_arch].s)
   3075  1.4.2.2    martin 	  out_attr[Tag_RISCV_arch].s = in_attr[Tag_RISCV_arch].s;
   3076  1.4.2.2    martin 	else if (in_attr[Tag_RISCV_arch].s
   3077  1.4.2.2    martin 		 && out_attr[Tag_RISCV_arch].s)
   3078  1.4.2.2    martin 	  {
   3079  1.4.2.2    martin 	    /* Check arch compatible.  */
   3080  1.4.2.2    martin 	    char *merged_arch =
   3081  1.4.2.2    martin 		riscv_merge_arch_attr_info (ibfd,
   3082  1.4.2.2    martin 					    in_attr[Tag_RISCV_arch].s,
   3083  1.4.2.2    martin 					    out_attr[Tag_RISCV_arch].s);
   3084  1.4.2.2    martin 	    if (merged_arch == NULL)
   3085  1.4.2.2    martin 	      {
   3086  1.4.2.2    martin 		result = FALSE;
   3087  1.4.2.2    martin 		out_attr[Tag_RISCV_arch].s = "";
   3088  1.4.2.2    martin 	      }
   3089  1.4.2.2    martin 	    else
   3090  1.4.2.2    martin 	      out_attr[Tag_RISCV_arch].s = merged_arch;
   3091  1.4.2.2    martin 	  }
   3092  1.4.2.2    martin 	break;
   3093  1.4.2.2    martin       case Tag_RISCV_priv_spec:
   3094  1.4.2.2    martin       case Tag_RISCV_priv_spec_minor:
   3095  1.4.2.2    martin       case Tag_RISCV_priv_spec_revision:
   3096  1.4.2.2    martin 	if (out_attr[i].i != in_attr[i].i)
   3097  1.4.2.2    martin 	  {
   3098  1.4.2.2    martin 	    _bfd_error_handler
   3099  1.4.2.2    martin 	      (_("error: %pB: conflicting priv spec version "
   3100  1.4.2.2    martin 		 "(major/minor/revision)."), ibfd);
   3101  1.4.2.2    martin 	    result = FALSE;
   3102  1.4.2.2    martin 	  }
   3103  1.4.2.2    martin 	break;
   3104  1.4.2.2    martin       case Tag_RISCV_unaligned_access:
   3105  1.4.2.2    martin 	out_attr[i].i |= in_attr[i].i;
   3106  1.4.2.2    martin 	break;
   3107  1.4.2.2    martin       case Tag_RISCV_stack_align:
   3108  1.4.2.2    martin 	if (out_attr[i].i == 0)
   3109  1.4.2.2    martin 	  out_attr[i].i = in_attr[i].i;
   3110  1.4.2.2    martin 	else if (in_attr[i].i != 0
   3111  1.4.2.2    martin 		 && out_attr[i].i != 0
   3112  1.4.2.2    martin 		 && out_attr[i].i != in_attr[i].i)
   3113  1.4.2.2    martin 	  {
   3114  1.4.2.2    martin 	    _bfd_error_handler
   3115  1.4.2.2    martin 	      (_("error: %pB use %u-byte stack aligned but the output "
   3116  1.4.2.2    martin 		 "use %u-byte stack aligned."),
   3117  1.4.2.2    martin 	       ibfd, in_attr[i].i, out_attr[i].i);
   3118  1.4.2.2    martin 	    result = FALSE;
   3119  1.4.2.2    martin 	  }
   3120  1.4.2.2    martin 	break;
   3121  1.4.2.2    martin       default:
   3122  1.4.2.2    martin 	result &= _bfd_elf_merge_unknown_attribute_low (ibfd, obfd, i);
   3123  1.4.2.2    martin       }
   3124  1.4.2.2    martin 
   3125  1.4.2.2    martin       /* If out_attr was copied from in_attr then it won't have a type yet.  */
   3126  1.4.2.2    martin       if (in_attr[i].type && !out_attr[i].type)
   3127  1.4.2.2    martin 	out_attr[i].type = in_attr[i].type;
   3128  1.4.2.2    martin     }
   3129  1.4.2.2    martin 
   3130  1.4.2.2    martin   /* Merge Tag_compatibility attributes and any common GNU ones.  */
   3131  1.4.2.2    martin   if (!_bfd_elf_merge_object_attributes (ibfd, info))
   3132  1.4.2.2    martin     return FALSE;
   3133  1.4.2.2    martin 
   3134  1.4.2.2    martin   /* Check for any attributes not known on RISC-V.  */
   3135  1.4.2.2    martin   result &= _bfd_elf_merge_unknown_attribute_list (ibfd, obfd);
   3136  1.4.2.2    martin 
   3137  1.4.2.2    martin   return result;
   3138  1.4.2.2    martin }
   3139  1.4.2.2    martin 
   3140      1.1      matt /* Merge backend specific data from an object file to the output
   3141      1.1      matt    object file when linking.  */
   3142      1.1      matt 
   3143      1.1      matt static bfd_boolean
   3144      1.4  christos _bfd_riscv_elf_merge_private_bfd_data (bfd *ibfd, struct bfd_link_info *info)
   3145      1.1      matt {
   3146      1.4  christos   bfd *obfd = info->output_bfd;
   3147  1.4.2.2    martin   flagword new_flags, old_flags;
   3148      1.1      matt 
   3149      1.1      matt   if (!is_riscv_elf (ibfd) || !is_riscv_elf (obfd))
   3150      1.1      matt     return TRUE;
   3151      1.1      matt 
   3152      1.1      matt   if (strcmp (bfd_get_target (ibfd), bfd_get_target (obfd)) != 0)
   3153      1.1      matt     {
   3154      1.1      matt       (*_bfd_error_handler)
   3155  1.4.2.1  christos 	(_("%pB: ABI is incompatible with that of the selected emulation:\n"
   3156      1.4  christos 	   "  target emulation `%s' does not match `%s'"),
   3157      1.4  christos 	 ibfd, bfd_get_target (ibfd), bfd_get_target (obfd));
   3158      1.1      matt       return FALSE;
   3159      1.1      matt     }
   3160      1.1      matt 
   3161      1.4  christos   if (!_bfd_elf_merge_object_attributes (ibfd, info))
   3162      1.1      matt     return FALSE;
   3163      1.1      matt 
   3164  1.4.2.2    martin   if (!riscv_merge_attributes (ibfd, info))
   3165  1.4.2.2    martin     return FALSE;
   3166  1.4.2.2    martin 
   3167  1.4.2.2    martin   new_flags = elf_elfheader (ibfd)->e_flags;
   3168  1.4.2.2    martin   old_flags = elf_elfheader (obfd)->e_flags;
   3169  1.4.2.2    martin 
   3170      1.1      matt   if (! elf_flags_init (obfd))
   3171      1.1      matt     {
   3172      1.1      matt       elf_flags_init (obfd) = TRUE;
   3173      1.1      matt       elf_elfheader (obfd)->e_flags = new_flags;
   3174      1.1      matt       return TRUE;
   3175      1.1      matt     }
   3176      1.1      matt 
   3177  1.4.2.2    martin   /* Check to see if the input BFD actually contains any sections.  If not,
   3178  1.4.2.2    martin      its flags may not have been initialized either, but it cannot actually
   3179  1.4.2.2    martin      cause any incompatibility.  Do not short-circuit dynamic objects; their
   3180  1.4.2.2    martin      section list may be emptied by elf_link_add_object_symbols.
   3181  1.4.2.2    martin 
   3182  1.4.2.2    martin      Also check to see if there are no code sections in the input.  In this
   3183  1.4.2.2    martin      case, there is no need to check for code specific flags.  */
   3184  1.4.2.2    martin   if (!(ibfd->flags & DYNAMIC))
   3185  1.4.2.2    martin     {
   3186  1.4.2.2    martin       bfd_boolean null_input_bfd = TRUE;
   3187  1.4.2.2    martin       bfd_boolean only_data_sections = TRUE;
   3188  1.4.2.2    martin       asection *sec;
   3189  1.4.2.2    martin 
   3190  1.4.2.2    martin       for (sec = ibfd->sections; sec != NULL; sec = sec->next)
   3191  1.4.2.2    martin 	{
   3192  1.4.2.2    martin 	  if ((bfd_section_flags (sec)
   3193  1.4.2.2    martin 	       & (SEC_LOAD | SEC_CODE | SEC_HAS_CONTENTS))
   3194  1.4.2.2    martin 	      == (SEC_LOAD | SEC_CODE | SEC_HAS_CONTENTS))
   3195  1.4.2.2    martin 	    only_data_sections = FALSE;
   3196  1.4.2.2    martin 
   3197  1.4.2.2    martin 	  null_input_bfd = FALSE;
   3198  1.4.2.2    martin 	  break;
   3199  1.4.2.2    martin 	}
   3200  1.4.2.2    martin 
   3201  1.4.2.2    martin       if (null_input_bfd || only_data_sections)
   3202  1.4.2.2    martin 	return TRUE;
   3203  1.4.2.2    martin     }
   3204  1.4.2.2    martin 
   3205      1.4  christos   /* Disallow linking different float ABIs.  */
   3206      1.4  christos   if ((old_flags ^ new_flags) & EF_RISCV_FLOAT_ABI)
   3207      1.1      matt     {
   3208      1.1      matt       (*_bfd_error_handler)
   3209  1.4.2.2    martin 	(_("%pB: can't link %s modules with %s modules"), ibfd,
   3210  1.4.2.2    martin 	 riscv_float_abi_string (new_flags),
   3211  1.4.2.2    martin 	 riscv_float_abi_string (old_flags));
   3212  1.4.2.1  christos       goto fail;
   3213  1.4.2.1  christos     }
   3214  1.4.2.1  christos 
   3215  1.4.2.1  christos   /* Disallow linking RVE and non-RVE.  */
   3216  1.4.2.1  christos   if ((old_flags ^ new_flags) & EF_RISCV_RVE)
   3217  1.4.2.1  christos     {
   3218  1.4.2.1  christos       (*_bfd_error_handler)
   3219  1.4.2.1  christos        (_("%pB: can't link RVE with other target"), ibfd);
   3220      1.1      matt       goto fail;
   3221      1.1      matt     }
   3222      1.1      matt 
   3223      1.4  christos   /* Allow linking RVC and non-RVC, and keep the RVC flag.  */
   3224      1.4  christos   elf_elfheader (obfd)->e_flags |= new_flags & EF_RISCV_RVC;
   3225      1.1      matt 
   3226      1.1      matt   return TRUE;
   3227      1.1      matt 
   3228      1.1      matt fail:
   3229      1.1      matt   bfd_set_error (bfd_error_bad_value);
   3230      1.1      matt   return FALSE;
   3231      1.1      matt }
   3232      1.1      matt 
   3233      1.1      matt /* Delete some bytes from a section while relaxing.  */
   3234      1.1      matt 
   3235      1.1      matt static bfd_boolean
   3236  1.4.2.1  christos riscv_relax_delete_bytes (bfd *abfd, asection *sec, bfd_vma addr, size_t count,
   3237  1.4.2.1  christos 			  struct bfd_link_info *link_info)
   3238      1.1      matt {
   3239      1.1      matt   unsigned int i, symcount;
   3240      1.1      matt   bfd_vma toaddr = sec->size;
   3241      1.1      matt   struct elf_link_hash_entry **sym_hashes = elf_sym_hashes (abfd);
   3242      1.1      matt   Elf_Internal_Shdr *symtab_hdr = &elf_tdata (abfd)->symtab_hdr;
   3243      1.1      matt   unsigned int sec_shndx = _bfd_elf_section_from_bfd_section (abfd, sec);
   3244      1.1      matt   struct bfd_elf_section_data *data = elf_section_data (sec);
   3245      1.1      matt   bfd_byte *contents = data->this_hdr.contents;
   3246      1.1      matt 
   3247      1.1      matt   /* Actually delete the bytes.  */
   3248      1.1      matt   sec->size -= count;
   3249      1.1      matt   memmove (contents + addr, contents + addr + count, toaddr - addr - count);
   3250      1.1      matt 
   3251      1.1      matt   /* Adjust the location of all of the relocs.  Note that we need not
   3252      1.1      matt      adjust the addends, since all PC-relative references must be against
   3253      1.1      matt      symbols, which we will adjust below.  */
   3254      1.1      matt   for (i = 0; i < sec->reloc_count; i++)
   3255      1.1      matt     if (data->relocs[i].r_offset > addr && data->relocs[i].r_offset < toaddr)
   3256      1.1      matt       data->relocs[i].r_offset -= count;
   3257      1.1      matt 
   3258      1.1      matt   /* Adjust the local symbols defined in this section.  */
   3259      1.1      matt   for (i = 0; i < symtab_hdr->sh_info; i++)
   3260      1.1      matt     {
   3261      1.1      matt       Elf_Internal_Sym *sym = (Elf_Internal_Sym *) symtab_hdr->contents + i;
   3262      1.1      matt       if (sym->st_shndx == sec_shndx)
   3263      1.1      matt 	{
   3264      1.1      matt 	  /* If the symbol is in the range of memory we just moved, we
   3265      1.1      matt 	     have to adjust its value.  */
   3266      1.1      matt 	  if (sym->st_value > addr && sym->st_value <= toaddr)
   3267      1.1      matt 	    sym->st_value -= count;
   3268      1.1      matt 
   3269      1.1      matt 	  /* If the symbol *spans* the bytes we just deleted (i.e. its
   3270      1.1      matt 	     *end* is in the moved bytes but its *start* isn't), then we
   3271  1.4.2.1  christos 	     must adjust its size.
   3272  1.4.2.1  christos 
   3273  1.4.2.1  christos 	     This test needs to use the original value of st_value, otherwise
   3274  1.4.2.1  christos 	     we might accidentally decrease size when deleting bytes right
   3275  1.4.2.1  christos 	     before the symbol.  But since deleted relocs can't span across
   3276  1.4.2.1  christos 	     symbols, we can't have both a st_value and a st_size decrease,
   3277  1.4.2.1  christos 	     so it is simpler to just use an else.  */
   3278  1.4.2.1  christos 	  else if (sym->st_value <= addr
   3279  1.4.2.1  christos 		   && sym->st_value + sym->st_size > addr
   3280  1.4.2.1  christos 		   && sym->st_value + sym->st_size <= toaddr)
   3281      1.1      matt 	    sym->st_size -= count;
   3282      1.1      matt 	}
   3283      1.1      matt     }
   3284      1.1      matt 
   3285      1.1      matt   /* Now adjust the global symbols defined in this section.  */
   3286      1.4  christos   symcount = ((symtab_hdr->sh_size / sizeof (ElfNN_External_Sym))
   3287      1.1      matt 	      - symtab_hdr->sh_info);
   3288      1.1      matt 
   3289      1.1      matt   for (i = 0; i < symcount; i++)
   3290      1.1      matt     {
   3291      1.1      matt       struct elf_link_hash_entry *sym_hash = sym_hashes[i];
   3292      1.1      matt 
   3293  1.4.2.1  christos       /* The '--wrap SYMBOL' option is causing a pain when the object file,
   3294  1.4.2.1  christos 	 containing the definition of __wrap_SYMBOL, includes a direct
   3295  1.4.2.1  christos 	 call to SYMBOL as well. Since both __wrap_SYMBOL and SYMBOL reference
   3296  1.4.2.1  christos 	 the same symbol (which is __wrap_SYMBOL), but still exist as two
   3297  1.4.2.1  christos 	 different symbols in 'sym_hashes', we don't want to adjust
   3298  1.4.2.1  christos 	 the global symbol __wrap_SYMBOL twice.  */
   3299  1.4.2.1  christos       /* The same problem occurs with symbols that are versioned_hidden, as
   3300  1.4.2.1  christos 	 foo becomes an alias for foo@BAR, and hence they need the same
   3301  1.4.2.1  christos 	 treatment.  */
   3302  1.4.2.1  christos       if (link_info->wrap_hash != NULL
   3303  1.4.2.1  christos 	  || sym_hash->versioned == versioned_hidden)
   3304  1.4.2.1  christos 	{
   3305  1.4.2.1  christos 	  struct elf_link_hash_entry **cur_sym_hashes;
   3306  1.4.2.1  christos 
   3307  1.4.2.1  christos 	  /* Loop only over the symbols which have already been checked.  */
   3308  1.4.2.1  christos 	  for (cur_sym_hashes = sym_hashes; cur_sym_hashes < &sym_hashes[i];
   3309  1.4.2.1  christos 	       cur_sym_hashes++)
   3310  1.4.2.1  christos 	    {
   3311  1.4.2.1  christos 	      /* If the current symbol is identical to 'sym_hash', that means
   3312  1.4.2.1  christos 		 the symbol was already adjusted (or at least checked).  */
   3313  1.4.2.1  christos 	      if (*cur_sym_hashes == sym_hash)
   3314  1.4.2.1  christos 		break;
   3315  1.4.2.1  christos 	    }
   3316  1.4.2.1  christos 	  /* Don't adjust the symbol again.  */
   3317  1.4.2.1  christos 	  if (cur_sym_hashes < &sym_hashes[i])
   3318  1.4.2.1  christos 	    continue;
   3319  1.4.2.1  christos 	}
   3320  1.4.2.1  christos 
   3321      1.1      matt       if ((sym_hash->root.type == bfd_link_hash_defined
   3322      1.1      matt 	   || sym_hash->root.type == bfd_link_hash_defweak)
   3323      1.1      matt 	  && sym_hash->root.u.def.section == sec)
   3324      1.1      matt 	{
   3325      1.1      matt 	  /* As above, adjust the value if needed.  */
   3326      1.1      matt 	  if (sym_hash->root.u.def.value > addr
   3327      1.1      matt 	      && sym_hash->root.u.def.value <= toaddr)
   3328      1.1      matt 	    sym_hash->root.u.def.value -= count;
   3329      1.1      matt 
   3330      1.1      matt 	  /* As above, adjust the size if needed.  */
   3331  1.4.2.1  christos 	  else if (sym_hash->root.u.def.value <= addr
   3332  1.4.2.1  christos 		   && sym_hash->root.u.def.value + sym_hash->size > addr
   3333  1.4.2.1  christos 		   && sym_hash->root.u.def.value + sym_hash->size <= toaddr)
   3334      1.1      matt 	    sym_hash->size -= count;
   3335      1.1      matt 	}
   3336      1.1      matt     }
   3337      1.1      matt 
   3338      1.1      matt   return TRUE;
   3339      1.1      matt }
   3340      1.1      matt 
   3341      1.4  christos /* A second format for recording PC-relative hi relocations.  This stores the
   3342      1.4  christos    information required to relax them to GP-relative addresses.  */
   3343      1.4  christos 
   3344      1.4  christos typedef struct riscv_pcgp_hi_reloc riscv_pcgp_hi_reloc;
   3345      1.4  christos struct riscv_pcgp_hi_reloc
   3346      1.4  christos {
   3347      1.4  christos   bfd_vma hi_sec_off;
   3348      1.4  christos   bfd_vma hi_addend;
   3349      1.4  christos   bfd_vma hi_addr;
   3350      1.4  christos   unsigned hi_sym;
   3351      1.4  christos   asection *sym_sec;
   3352  1.4.2.2    martin   bfd_boolean undefined_weak;
   3353      1.4  christos   riscv_pcgp_hi_reloc *next;
   3354      1.4  christos };
   3355      1.4  christos 
   3356      1.4  christos typedef struct riscv_pcgp_lo_reloc riscv_pcgp_lo_reloc;
   3357      1.4  christos struct riscv_pcgp_lo_reloc
   3358      1.4  christos {
   3359      1.4  christos   bfd_vma hi_sec_off;
   3360      1.4  christos   riscv_pcgp_lo_reloc *next;
   3361      1.4  christos };
   3362      1.4  christos 
   3363      1.4  christos typedef struct
   3364      1.4  christos {
   3365      1.4  christos   riscv_pcgp_hi_reloc *hi;
   3366      1.4  christos   riscv_pcgp_lo_reloc *lo;
   3367      1.4  christos } riscv_pcgp_relocs;
   3368      1.4  christos 
   3369  1.4.2.2    martin /* Initialize the pcgp reloc info in P.  */
   3370  1.4.2.2    martin 
   3371      1.4  christos static bfd_boolean
   3372      1.4  christos riscv_init_pcgp_relocs (riscv_pcgp_relocs *p)
   3373      1.4  christos {
   3374      1.4  christos   p->hi = NULL;
   3375      1.4  christos   p->lo = NULL;
   3376      1.4  christos   return TRUE;
   3377      1.4  christos }
   3378      1.4  christos 
   3379  1.4.2.2    martin /* Free the pcgp reloc info in P.  */
   3380  1.4.2.2    martin 
   3381      1.4  christos static void
   3382      1.4  christos riscv_free_pcgp_relocs (riscv_pcgp_relocs *p,
   3383      1.4  christos 			bfd *abfd ATTRIBUTE_UNUSED,
   3384      1.4  christos 			asection *sec ATTRIBUTE_UNUSED)
   3385      1.4  christos {
   3386      1.4  christos   riscv_pcgp_hi_reloc *c;
   3387      1.4  christos   riscv_pcgp_lo_reloc *l;
   3388      1.4  christos 
   3389      1.4  christos   for (c = p->hi; c != NULL;)
   3390      1.4  christos     {
   3391      1.4  christos       riscv_pcgp_hi_reloc *next = c->next;
   3392      1.4  christos       free (c);
   3393      1.4  christos       c = next;
   3394      1.4  christos     }
   3395      1.4  christos 
   3396      1.4  christos   for (l = p->lo; l != NULL;)
   3397      1.4  christos     {
   3398      1.4  christos       riscv_pcgp_lo_reloc *next = l->next;
   3399      1.4  christos       free (l);
   3400      1.4  christos       l = next;
   3401      1.4  christos     }
   3402      1.4  christos }
   3403      1.4  christos 
   3404  1.4.2.2    martin /* Record pcgp hi part reloc info in P, using HI_SEC_OFF as the lookup index.
   3405  1.4.2.2    martin    The HI_ADDEND, HI_ADDR, HI_SYM, and SYM_SEC args contain info required to
   3406  1.4.2.2    martin    relax the corresponding lo part reloc.  */
   3407  1.4.2.2    martin 
   3408      1.4  christos static bfd_boolean
   3409      1.4  christos riscv_record_pcgp_hi_reloc (riscv_pcgp_relocs *p, bfd_vma hi_sec_off,
   3410      1.4  christos 			    bfd_vma hi_addend, bfd_vma hi_addr,
   3411  1.4.2.2    martin 			    unsigned hi_sym, asection *sym_sec,
   3412  1.4.2.2    martin 			    bfd_boolean undefined_weak)
   3413      1.4  christos {
   3414      1.4  christos   riscv_pcgp_hi_reloc *new = bfd_malloc (sizeof(*new));
   3415      1.4  christos   if (!new)
   3416      1.4  christos     return FALSE;
   3417      1.4  christos   new->hi_sec_off = hi_sec_off;
   3418      1.4  christos   new->hi_addend = hi_addend;
   3419      1.4  christos   new->hi_addr = hi_addr;
   3420      1.4  christos   new->hi_sym = hi_sym;
   3421      1.4  christos   new->sym_sec = sym_sec;
   3422  1.4.2.2    martin   new->undefined_weak = undefined_weak;
   3423      1.4  christos   new->next = p->hi;
   3424      1.4  christos   p->hi = new;
   3425      1.4  christos   return TRUE;
   3426      1.4  christos }
   3427      1.4  christos 
   3428  1.4.2.2    martin /* Look up hi part pcgp reloc info in P, using HI_SEC_OFF as the lookup index.
   3429  1.4.2.2    martin    This is used by a lo part reloc to find the corresponding hi part reloc.  */
   3430  1.4.2.2    martin 
   3431      1.4  christos static riscv_pcgp_hi_reloc *
   3432      1.4  christos riscv_find_pcgp_hi_reloc(riscv_pcgp_relocs *p, bfd_vma hi_sec_off)
   3433      1.4  christos {
   3434      1.4  christos   riscv_pcgp_hi_reloc *c;
   3435      1.4  christos 
   3436      1.4  christos   for (c = p->hi; c != NULL; c = c->next)
   3437      1.4  christos     if (c->hi_sec_off == hi_sec_off)
   3438      1.4  christos       return c;
   3439      1.4  christos   return NULL;
   3440      1.4  christos }
   3441      1.4  christos 
   3442  1.4.2.2    martin /* Record pcgp lo part reloc info in P, using HI_SEC_OFF as the lookup info.
   3443  1.4.2.2    martin    This is used to record relocs that can't be relaxed.  */
   3444      1.4  christos 
   3445      1.4  christos static bfd_boolean
   3446      1.4  christos riscv_record_pcgp_lo_reloc (riscv_pcgp_relocs *p, bfd_vma hi_sec_off)
   3447      1.4  christos {
   3448      1.4  christos   riscv_pcgp_lo_reloc *new = bfd_malloc (sizeof(*new));
   3449      1.4  christos   if (!new)
   3450      1.4  christos     return FALSE;
   3451      1.4  christos   new->hi_sec_off = hi_sec_off;
   3452      1.4  christos   new->next = p->lo;
   3453      1.4  christos   p->lo = new;
   3454      1.4  christos   return TRUE;
   3455      1.4  christos }
   3456      1.4  christos 
   3457  1.4.2.2    martin /* Look up lo part pcgp reloc info in P, using HI_SEC_OFF as the lookup index.
   3458  1.4.2.2    martin    This is used by a hi part reloc to find the corresponding lo part reloc.  */
   3459  1.4.2.2    martin 
   3460      1.4  christos static bfd_boolean
   3461      1.4  christos riscv_find_pcgp_lo_reloc (riscv_pcgp_relocs *p, bfd_vma hi_sec_off)
   3462      1.4  christos {
   3463      1.4  christos   riscv_pcgp_lo_reloc *c;
   3464      1.4  christos 
   3465      1.4  christos   for (c = p->lo; c != NULL; c = c->next)
   3466      1.4  christos     if (c->hi_sec_off == hi_sec_off)
   3467      1.4  christos       return TRUE;
   3468      1.4  christos   return FALSE;
   3469      1.4  christos }
   3470      1.4  christos 
   3471      1.4  christos typedef bfd_boolean (*relax_func_t) (bfd *, asection *, asection *,
   3472      1.4  christos 				     struct bfd_link_info *,
   3473      1.4  christos 				     Elf_Internal_Rela *,
   3474      1.4  christos 				     bfd_vma, bfd_vma, bfd_vma, bfd_boolean *,
   3475  1.4.2.2    martin 				     riscv_pcgp_relocs *,
   3476  1.4.2.2    martin 				     bfd_boolean undefined_weak);
   3477      1.4  christos 
   3478      1.1      matt /* Relax AUIPC + JALR into JAL.  */
   3479      1.1      matt 
   3480      1.1      matt static bfd_boolean
   3481      1.4  christos _bfd_riscv_relax_call (bfd *abfd, asection *sec, asection *sym_sec,
   3482      1.1      matt 		       struct bfd_link_info *link_info,
   3483      1.1      matt 		       Elf_Internal_Rela *rel,
   3484      1.1      matt 		       bfd_vma symval,
   3485      1.4  christos 		       bfd_vma max_alignment,
   3486      1.4  christos 		       bfd_vma reserve_size ATTRIBUTE_UNUSED,
   3487      1.4  christos 		       bfd_boolean *again,
   3488  1.4.2.2    martin 		       riscv_pcgp_relocs *pcgp_relocs ATTRIBUTE_UNUSED,
   3489  1.4.2.2    martin 		       bfd_boolean undefined_weak ATTRIBUTE_UNUSED)
   3490      1.1      matt {
   3491      1.1      matt   bfd_byte *contents = elf_section_data (sec)->this_hdr.contents;
   3492      1.1      matt   bfd_signed_vma foff = symval - (sec_addr (sec) + rel->r_offset);
   3493      1.1      matt   bfd_boolean near_zero = (symval + RISCV_IMM_REACH/2) < RISCV_IMM_REACH;
   3494      1.1      matt   bfd_vma auipc, jalr;
   3495      1.4  christos   int rd, r_type, len = 4, rvc = elf_elfheader (abfd)->e_flags & EF_RISCV_RVC;
   3496      1.4  christos 
   3497      1.4  christos   /* If the call crosses section boundaries, an alignment directive could
   3498  1.4.2.2    martin      cause the PC-relative offset to later increase, so we need to add in the
   3499  1.4.2.2    martin      max alignment of any section inclusive from the call to the target.
   3500  1.4.2.2    martin      Otherwise, we only need to use the alignment of the current section.  */
   3501  1.4.2.2    martin   if (VALID_UJTYPE_IMM (foff))
   3502  1.4.2.2    martin     {
   3503  1.4.2.2    martin       if (sym_sec->output_section == sec->output_section
   3504  1.4.2.2    martin 	  && sym_sec->output_section != bfd_abs_section_ptr)
   3505  1.4.2.2    martin 	max_alignment = (bfd_vma) 1 << sym_sec->output_section->alignment_power;
   3506  1.4.2.2    martin       foff += (foff < 0 ? -max_alignment : max_alignment);
   3507  1.4.2.2    martin     }
   3508      1.1      matt 
   3509      1.1      matt   /* See if this function call can be shortened.  */
   3510      1.3  christos   if (!VALID_UJTYPE_IMM (foff) && !(!bfd_link_pic (link_info) && near_zero))
   3511      1.1      matt     return TRUE;
   3512      1.1      matt 
   3513      1.1      matt   /* Shorten the function call.  */
   3514      1.1      matt   BFD_ASSERT (rel->r_offset + 8 <= sec->size);
   3515      1.1      matt 
   3516      1.1      matt   auipc = bfd_get_32 (abfd, contents + rel->r_offset);
   3517      1.1      matt   jalr = bfd_get_32 (abfd, contents + rel->r_offset + 4);
   3518      1.4  christos   rd = (jalr >> OP_SH_RD) & OP_MASK_RD;
   3519  1.4.2.2    martin   rvc = rvc && VALID_RVC_J_IMM (foff);
   3520  1.4.2.2    martin 
   3521  1.4.2.2    martin   /* C.J exists on RV32 and RV64, but C.JAL is RV32-only.  */
   3522  1.4.2.2    martin   rvc = rvc && (rd == 0 || (rd == X_RA && ARCH_SIZE == 32));
   3523      1.1      matt 
   3524  1.4.2.2    martin   if (rvc)
   3525      1.4  christos     {
   3526      1.4  christos       /* Relax to C.J[AL] rd, addr.  */
   3527      1.4  christos       r_type = R_RISCV_RVC_JUMP;
   3528      1.4  christos       auipc = rd == 0 ? MATCH_C_J : MATCH_C_JAL;
   3529      1.4  christos       len = 2;
   3530      1.4  christos     }
   3531      1.4  christos   else if (VALID_UJTYPE_IMM (foff))
   3532      1.1      matt     {
   3533      1.1      matt       /* Relax to JAL rd, addr.  */
   3534      1.1      matt       r_type = R_RISCV_JAL;
   3535      1.4  christos       auipc = MATCH_JAL | (rd << OP_SH_RD);
   3536      1.1      matt     }
   3537      1.1      matt   else /* near_zero */
   3538      1.1      matt     {
   3539      1.1      matt       /* Relax to JALR rd, x0, addr.  */
   3540      1.1      matt       r_type = R_RISCV_LO12_I;
   3541      1.4  christos       auipc = MATCH_JALR | (rd << OP_SH_RD);
   3542      1.1      matt     }
   3543      1.1      matt 
   3544      1.1      matt   /* Replace the R_RISCV_CALL reloc.  */
   3545      1.1      matt   rel->r_info = ELFNN_R_INFO (ELFNN_R_SYM (rel->r_info), r_type);
   3546      1.1      matt   /* Replace the AUIPC.  */
   3547      1.4  christos   bfd_put (8 * len, abfd, auipc, contents + rel->r_offset);
   3548      1.1      matt 
   3549      1.1      matt   /* Delete unnecessary JALR.  */
   3550      1.1      matt   *again = TRUE;
   3551  1.4.2.1  christos   return riscv_relax_delete_bytes (abfd, sec, rel->r_offset + len, 8 - len,
   3552  1.4.2.1  christos 				   link_info);
   3553      1.4  christos }
   3554      1.4  christos 
   3555      1.4  christos /* Traverse all output sections and return the max alignment.  */
   3556      1.4  christos 
   3557      1.4  christos static bfd_vma
   3558      1.4  christos _bfd_riscv_get_max_alignment (asection *sec)
   3559      1.4  christos {
   3560      1.4  christos   unsigned int max_alignment_power = 0;
   3561      1.4  christos   asection *o;
   3562      1.4  christos 
   3563      1.4  christos   for (o = sec->output_section->owner->sections; o != NULL; o = o->next)
   3564      1.4  christos     {
   3565      1.4  christos       if (o->alignment_power > max_alignment_power)
   3566      1.4  christos 	max_alignment_power = o->alignment_power;
   3567      1.4  christos     }
   3568      1.4  christos 
   3569      1.4  christos   return (bfd_vma) 1 << max_alignment_power;
   3570      1.1      matt }
   3571      1.1      matt 
   3572      1.1      matt /* Relax non-PIC global variable references.  */
   3573      1.1      matt 
   3574      1.1      matt static bfd_boolean
   3575      1.4  christos _bfd_riscv_relax_lui (bfd *abfd,
   3576      1.4  christos 		      asection *sec,
   3577      1.4  christos 		      asection *sym_sec,
   3578      1.1      matt 		      struct bfd_link_info *link_info,
   3579      1.1      matt 		      Elf_Internal_Rela *rel,
   3580      1.1      matt 		      bfd_vma symval,
   3581      1.4  christos 		      bfd_vma max_alignment,
   3582      1.4  christos 		      bfd_vma reserve_size,
   3583      1.4  christos 		      bfd_boolean *again,
   3584  1.4.2.2    martin 		      riscv_pcgp_relocs *pcgp_relocs ATTRIBUTE_UNUSED,
   3585  1.4.2.2    martin 		      bfd_boolean undefined_weak)
   3586      1.1      matt {
   3587      1.4  christos   bfd_byte *contents = elf_section_data (sec)->this_hdr.contents;
   3588      1.1      matt   bfd_vma gp = riscv_global_pointer_value (link_info);
   3589      1.4  christos   int use_rvc = elf_elfheader (abfd)->e_flags & EF_RISCV_RVC;
   3590      1.1      matt 
   3591      1.1      matt   BFD_ASSERT (rel->r_offset + 4 <= sec->size);
   3592      1.1      matt 
   3593      1.4  christos   if (gp)
   3594      1.4  christos     {
   3595  1.4.2.2    martin       /* If gp and the symbol are in the same output section, which is not the
   3596  1.4.2.2    martin 	 abs section, then consider only that output section's alignment.  */
   3597      1.4  christos       struct bfd_link_hash_entry *h =
   3598      1.4  christos 	bfd_link_hash_lookup (link_info->hash, RISCV_GP_SYMBOL, FALSE, FALSE,
   3599      1.4  christos 			      TRUE);
   3600  1.4.2.2    martin       if (h->u.def.section->output_section == sym_sec->output_section
   3601  1.4.2.2    martin 	  && sym_sec->output_section != bfd_abs_section_ptr)
   3602      1.4  christos 	max_alignment = (bfd_vma) 1 << sym_sec->output_section->alignment_power;
   3603      1.4  christos     }
   3604      1.4  christos 
   3605      1.4  christos   /* Is the reference in range of x0 or gp?
   3606      1.4  christos      Valid gp range conservatively because of alignment issue.  */
   3607  1.4.2.2    martin   if (undefined_weak
   3608  1.4.2.2    martin       || (VALID_ITYPE_IMM (symval)
   3609  1.4.2.2    martin 	  || (symval >= gp
   3610  1.4.2.2    martin 	      && VALID_ITYPE_IMM (symval - gp + max_alignment + reserve_size))
   3611  1.4.2.2    martin 	  || (symval < gp
   3612  1.4.2.2    martin 	      && VALID_ITYPE_IMM (symval - gp - max_alignment - reserve_size))))
   3613      1.4  christos     {
   3614      1.4  christos       unsigned sym = ELFNN_R_SYM (rel->r_info);
   3615      1.4  christos       switch (ELFNN_R_TYPE (rel->r_info))
   3616      1.4  christos 	{
   3617      1.4  christos 	case R_RISCV_LO12_I:
   3618  1.4.2.2    martin 	  if (undefined_weak)
   3619  1.4.2.2    martin 	    {
   3620  1.4.2.2    martin 	      /* Change the RS1 to zero.  */
   3621  1.4.2.2    martin 	      bfd_vma insn = bfd_get_32 (abfd, contents + rel->r_offset);
   3622  1.4.2.2    martin 	      insn &= ~(OP_MASK_RS1 << OP_SH_RS1);
   3623  1.4.2.2    martin 	      bfd_put_32 (abfd, insn, contents + rel->r_offset);
   3624  1.4.2.2    martin 	    }
   3625  1.4.2.2    martin 	  else
   3626  1.4.2.2    martin 	    rel->r_info = ELFNN_R_INFO (sym, R_RISCV_GPREL_I);
   3627      1.4  christos 	  return TRUE;
   3628      1.4  christos 
   3629      1.4  christos 	case R_RISCV_LO12_S:
   3630  1.4.2.2    martin 	  if (undefined_weak)
   3631  1.4.2.2    martin 	    {
   3632  1.4.2.2    martin 	      /* Change the RS1 to zero.  */
   3633  1.4.2.2    martin 	      bfd_vma insn = bfd_get_32 (abfd, contents + rel->r_offset);
   3634  1.4.2.2    martin 	      insn &= ~(OP_MASK_RS1 << OP_SH_RS1);
   3635  1.4.2.2    martin 	      bfd_put_32 (abfd, insn, contents + rel->r_offset);
   3636  1.4.2.2    martin 	    }
   3637  1.4.2.2    martin 	  else
   3638  1.4.2.2    martin 	    rel->r_info = ELFNN_R_INFO (sym, R_RISCV_GPREL_S);
   3639      1.4  christos 	  return TRUE;
   3640      1.4  christos 
   3641      1.4  christos 	case R_RISCV_HI20:
   3642      1.4  christos 	  /* We can delete the unnecessary LUI and reloc.  */
   3643      1.4  christos 	  rel->r_info = ELFNN_R_INFO (0, R_RISCV_NONE);
   3644      1.4  christos 	  *again = TRUE;
   3645  1.4.2.1  christos 	  return riscv_relax_delete_bytes (abfd, sec, rel->r_offset, 4,
   3646  1.4.2.1  christos 					   link_info);
   3647      1.4  christos 
   3648      1.4  christos 	default:
   3649      1.4  christos 	  abort ();
   3650      1.4  christos 	}
   3651      1.4  christos     }
   3652      1.4  christos 
   3653      1.4  christos   /* Can we relax LUI to C.LUI?  Alignment might move the section forward;
   3654  1.4.2.2    martin      account for this assuming page alignment at worst. In the presence of
   3655  1.4.2.2    martin      RELRO segment the linker aligns it by one page size, therefore sections
   3656  1.4.2.2    martin      after the segment can be moved more than one page. */
   3657  1.4.2.2    martin 
   3658      1.4  christos   if (use_rvc
   3659      1.4  christos       && ELFNN_R_TYPE (rel->r_info) == R_RISCV_HI20
   3660      1.4  christos       && VALID_RVC_LUI_IMM (RISCV_CONST_HIGH_PART (symval))
   3661  1.4.2.2    martin       && VALID_RVC_LUI_IMM (RISCV_CONST_HIGH_PART (symval)
   3662  1.4.2.2    martin 			    + (link_info->relro ? 2 * ELF_MAXPAGESIZE
   3663  1.4.2.2    martin 			       : ELF_MAXPAGESIZE)))
   3664      1.4  christos     {
   3665      1.4  christos       /* Replace LUI with C.LUI if legal (i.e., rd != x0 and rd != x2/sp).  */
   3666      1.4  christos       bfd_vma lui = bfd_get_32 (abfd, contents + rel->r_offset);
   3667      1.4  christos       unsigned rd = ((unsigned)lui >> OP_SH_RD) & OP_MASK_RD;
   3668      1.4  christos       if (rd == 0 || rd == X_SP)
   3669      1.4  christos 	return TRUE;
   3670      1.4  christos 
   3671      1.4  christos       lui = (lui & (OP_MASK_RD << OP_SH_RD)) | MATCH_C_LUI;
   3672      1.4  christos       bfd_put_32 (abfd, lui, contents + rel->r_offset);
   3673      1.4  christos 
   3674      1.4  christos       /* Replace the R_RISCV_HI20 reloc.  */
   3675      1.4  christos       rel->r_info = ELFNN_R_INFO (ELFNN_R_SYM (rel->r_info), R_RISCV_RVC_LUI);
   3676      1.4  christos 
   3677      1.4  christos       *again = TRUE;
   3678  1.4.2.1  christos       return riscv_relax_delete_bytes (abfd, sec, rel->r_offset + 2, 2,
   3679  1.4.2.1  christos 				       link_info);
   3680      1.4  christos     }
   3681      1.4  christos 
   3682      1.4  christos   return TRUE;
   3683      1.1      matt }
   3684      1.1      matt 
   3685      1.1      matt /* Relax non-PIC TLS references.  */
   3686      1.1      matt 
   3687      1.1      matt static bfd_boolean
   3688      1.4  christos _bfd_riscv_relax_tls_le (bfd *abfd,
   3689      1.4  christos 			 asection *sec,
   3690      1.4  christos 			 asection *sym_sec ATTRIBUTE_UNUSED,
   3691      1.1      matt 			 struct bfd_link_info *link_info,
   3692      1.1      matt 			 Elf_Internal_Rela *rel,
   3693      1.1      matt 			 bfd_vma symval,
   3694      1.4  christos 			 bfd_vma max_alignment ATTRIBUTE_UNUSED,
   3695      1.4  christos 			 bfd_vma reserve_size ATTRIBUTE_UNUSED,
   3696      1.4  christos 			 bfd_boolean *again,
   3697  1.4.2.2    martin 			 riscv_pcgp_relocs *prcel_relocs ATTRIBUTE_UNUSED,
   3698  1.4.2.2    martin 			 bfd_boolean undefined_weak ATTRIBUTE_UNUSED)
   3699      1.1      matt {
   3700      1.1      matt   /* See if this symbol is in range of tp.  */
   3701      1.1      matt   if (RISCV_CONST_HIGH_PART (tpoff (link_info, symval)) != 0)
   3702      1.1      matt     return TRUE;
   3703      1.1      matt 
   3704      1.1      matt   BFD_ASSERT (rel->r_offset + 4 <= sec->size);
   3705      1.4  christos   switch (ELFNN_R_TYPE (rel->r_info))
   3706      1.4  christos     {
   3707      1.4  christos     case R_RISCV_TPREL_LO12_I:
   3708      1.4  christos       rel->r_info = ELFNN_R_INFO (ELFNN_R_SYM (rel->r_info), R_RISCV_TPREL_I);
   3709      1.4  christos       return TRUE;
   3710      1.4  christos 
   3711      1.4  christos     case R_RISCV_TPREL_LO12_S:
   3712      1.4  christos       rel->r_info = ELFNN_R_INFO (ELFNN_R_SYM (rel->r_info), R_RISCV_TPREL_S);
   3713      1.4  christos       return TRUE;
   3714      1.4  christos 
   3715      1.4  christos     case R_RISCV_TPREL_HI20:
   3716      1.4  christos     case R_RISCV_TPREL_ADD:
   3717      1.4  christos       /* We can delete the unnecessary instruction and reloc.  */
   3718      1.4  christos       rel->r_info = ELFNN_R_INFO (0, R_RISCV_NONE);
   3719      1.4  christos       *again = TRUE;
   3720  1.4.2.1  christos       return riscv_relax_delete_bytes (abfd, sec, rel->r_offset, 4, link_info);
   3721      1.1      matt 
   3722      1.4  christos     default:
   3723      1.4  christos       abort ();
   3724      1.4  christos     }
   3725      1.1      matt }
   3726      1.1      matt 
   3727      1.1      matt /* Implement R_RISCV_ALIGN by deleting excess alignment NOPs.  */
   3728      1.1      matt 
   3729      1.1      matt static bfd_boolean
   3730      1.1      matt _bfd_riscv_relax_align (bfd *abfd, asection *sec,
   3731      1.4  christos 			asection *sym_sec,
   3732  1.4.2.1  christos 			struct bfd_link_info *link_info,
   3733      1.1      matt 			Elf_Internal_Rela *rel,
   3734      1.1      matt 			bfd_vma symval,
   3735      1.4  christos 			bfd_vma max_alignment ATTRIBUTE_UNUSED,
   3736      1.4  christos 			bfd_vma reserve_size ATTRIBUTE_UNUSED,
   3737      1.4  christos 			bfd_boolean *again ATTRIBUTE_UNUSED,
   3738  1.4.2.2    martin 			riscv_pcgp_relocs *pcrel_relocs ATTRIBUTE_UNUSED,
   3739  1.4.2.2    martin 			bfd_boolean undefined_weak ATTRIBUTE_UNUSED)
   3740      1.1      matt {
   3741      1.4  christos   bfd_byte *contents = elf_section_data (sec)->this_hdr.contents;
   3742      1.4  christos   bfd_vma alignment = 1, pos;
   3743      1.1      matt   while (alignment <= rel->r_addend)
   3744      1.1      matt     alignment *= 2;
   3745      1.1      matt 
   3746      1.1      matt   symval -= rel->r_addend;
   3747      1.1      matt   bfd_vma aligned_addr = ((symval - 1) & ~(alignment - 1)) + alignment;
   3748      1.4  christos   bfd_vma nop_bytes = aligned_addr - symval;
   3749      1.4  christos 
   3750      1.4  christos   /* Once we've handled an R_RISCV_ALIGN, we can't relax anything else.  */
   3751      1.4  christos   sec->sec_flg0 = TRUE;
   3752      1.1      matt 
   3753      1.1      matt   /* Make sure there are enough NOPs to actually achieve the alignment.  */
   3754      1.4  christos   if (rel->r_addend < nop_bytes)
   3755      1.4  christos     {
   3756  1.4.2.1  christos       _bfd_error_handler
   3757  1.4.2.1  christos 	(_("%pB(%pA+%#" PRIx64 "): %" PRId64 " bytes required for alignment "
   3758  1.4.2.1  christos 	   "to %" PRId64 "-byte boundary, but only %" PRId64 " present"),
   3759  1.4.2.1  christos 	 abfd, sym_sec, (uint64_t) rel->r_offset,
   3760  1.4.2.1  christos 	 (int64_t) nop_bytes, (int64_t) alignment, (int64_t) rel->r_addend);
   3761      1.4  christos       bfd_set_error (bfd_error_bad_value);
   3762      1.4  christos       return FALSE;
   3763      1.4  christos     }
   3764      1.1      matt 
   3765      1.1      matt   /* Delete the reloc.  */
   3766      1.1      matt   rel->r_info = ELFNN_R_INFO (0, R_RISCV_NONE);
   3767      1.1      matt 
   3768      1.1      matt   /* If the number of NOPs is already correct, there's nothing to do.  */
   3769      1.4  christos   if (nop_bytes == rel->r_addend)
   3770      1.1      matt     return TRUE;
   3771      1.1      matt 
   3772      1.4  christos   /* Write as many RISC-V NOPs as we need.  */
   3773      1.4  christos   for (pos = 0; pos < (nop_bytes & -4); pos += 4)
   3774      1.4  christos     bfd_put_32 (abfd, RISCV_NOP, contents + rel->r_offset + pos);
   3775      1.4  christos 
   3776      1.4  christos   /* Write a final RVC NOP if need be.  */
   3777      1.4  christos   if (nop_bytes % 4 != 0)
   3778      1.4  christos     bfd_put_16 (abfd, RVC_NOP, contents + rel->r_offset + pos);
   3779      1.4  christos 
   3780      1.4  christos   /* Delete the excess bytes.  */
   3781      1.4  christos   return riscv_relax_delete_bytes (abfd, sec, rel->r_offset + nop_bytes,
   3782  1.4.2.1  christos 				   rel->r_addend - nop_bytes, link_info);
   3783      1.1      matt }
   3784      1.1      matt 
   3785      1.4  christos /* Relax PC-relative references to GP-relative references.  */
   3786      1.4  christos 
   3787      1.4  christos static bfd_boolean
   3788  1.4.2.2    martin _bfd_riscv_relax_pc  (bfd *abfd ATTRIBUTE_UNUSED,
   3789      1.4  christos 		      asection *sec,
   3790      1.4  christos 		      asection *sym_sec,
   3791      1.4  christos 		      struct bfd_link_info *link_info,
   3792      1.4  christos 		      Elf_Internal_Rela *rel,
   3793      1.4  christos 		      bfd_vma symval,
   3794      1.4  christos 		      bfd_vma max_alignment,
   3795      1.4  christos 		      bfd_vma reserve_size,
   3796      1.4  christos 		      bfd_boolean *again ATTRIBUTE_UNUSED,
   3797  1.4.2.2    martin 		      riscv_pcgp_relocs *pcgp_relocs,
   3798  1.4.2.2    martin 		      bfd_boolean undefined_weak)
   3799      1.4  christos {
   3800  1.4.2.2    martin   bfd_byte *contents = elf_section_data (sec)->this_hdr.contents;
   3801      1.4  christos   bfd_vma gp = riscv_global_pointer_value (link_info);
   3802      1.4  christos 
   3803      1.4  christos   BFD_ASSERT (rel->r_offset + 4 <= sec->size);
   3804      1.4  christos 
   3805      1.4  christos   /* Chain the _LO relocs to their cooresponding _HI reloc to compute the
   3806      1.4  christos    * actual target address.  */
   3807  1.4.2.1  christos   riscv_pcgp_hi_reloc hi_reloc;
   3808  1.4.2.1  christos   memset (&hi_reloc, 0, sizeof (hi_reloc));
   3809      1.4  christos   switch (ELFNN_R_TYPE (rel->r_info))
   3810      1.4  christos     {
   3811      1.4  christos     case R_RISCV_PCREL_LO12_I:
   3812      1.4  christos     case R_RISCV_PCREL_LO12_S:
   3813      1.4  christos       {
   3814  1.4.2.2    martin 	/* If the %lo has an addend, it isn't for the label pointing at the
   3815  1.4.2.2    martin 	   hi part instruction, but rather for the symbol pointed at by the
   3816  1.4.2.2    martin 	   hi part instruction.  So we must subtract it here for the lookup.
   3817  1.4.2.2    martin 	   It is still used below in the final symbol address.  */
   3818  1.4.2.2    martin 	bfd_vma hi_sec_off = symval - sec_addr (sym_sec) - rel->r_addend;
   3819      1.4  christos 	riscv_pcgp_hi_reloc *hi = riscv_find_pcgp_hi_reloc (pcgp_relocs,
   3820  1.4.2.2    martin 							    hi_sec_off);
   3821      1.4  christos 	if (hi == NULL)
   3822      1.4  christos 	  {
   3823  1.4.2.2    martin 	    riscv_record_pcgp_lo_reloc (pcgp_relocs, hi_sec_off);
   3824      1.4  christos 	    return TRUE;
   3825      1.4  christos 	  }
   3826      1.4  christos 
   3827      1.4  christos 	hi_reloc = *hi;
   3828      1.4  christos 	symval = hi_reloc.hi_addr;
   3829      1.4  christos 	sym_sec = hi_reloc.sym_sec;
   3830  1.4.2.2    martin 
   3831  1.4.2.2    martin 	/* We can not know whether the undefined weak symbol is referenced
   3832  1.4.2.2    martin 	   according to the information of R_RISCV_PCREL_LO12_I/S.  Therefore,
   3833  1.4.2.2    martin 	   we have to record the 'undefined_weak' flag when handling the
   3834  1.4.2.2    martin 	   corresponding R_RISCV_HI20 reloc in riscv_record_pcgp_hi_reloc.  */
   3835  1.4.2.2    martin 	undefined_weak = hi_reloc.undefined_weak;
   3836      1.4  christos       }
   3837      1.4  christos       break;
   3838      1.4  christos 
   3839      1.4  christos     case R_RISCV_PCREL_HI20:
   3840      1.4  christos       /* Mergeable symbols and code might later move out of range.  */
   3841  1.4.2.2    martin       if (! undefined_weak
   3842  1.4.2.2    martin 	  && sym_sec->flags & (SEC_MERGE | SEC_CODE))
   3843      1.4  christos 	return TRUE;
   3844      1.4  christos 
   3845      1.4  christos       /* If the cooresponding lo relocation has already been seen then it's not
   3846      1.4  christos        * safe to relax this relocation.  */
   3847      1.4  christos       if (riscv_find_pcgp_lo_reloc (pcgp_relocs, rel->r_offset))
   3848      1.4  christos 	return TRUE;
   3849      1.4  christos 
   3850      1.4  christos       break;
   3851      1.4  christos 
   3852      1.4  christos     default:
   3853      1.4  christos       abort ();
   3854      1.4  christos     }
   3855      1.4  christos 
   3856      1.4  christos   if (gp)
   3857      1.4  christos     {
   3858  1.4.2.2    martin       /* If gp and the symbol are in the same output section, which is not the
   3859  1.4.2.2    martin 	 abs section, then consider only that output section's alignment.  */
   3860      1.4  christos       struct bfd_link_hash_entry *h =
   3861  1.4.2.2    martin 	bfd_link_hash_lookup (link_info->hash, RISCV_GP_SYMBOL, FALSE, FALSE,
   3862  1.4.2.2    martin 			      TRUE);
   3863  1.4.2.2    martin       if (h->u.def.section->output_section == sym_sec->output_section
   3864  1.4.2.2    martin 	  && sym_sec->output_section != bfd_abs_section_ptr)
   3865      1.4  christos 	max_alignment = (bfd_vma) 1 << sym_sec->output_section->alignment_power;
   3866      1.4  christos     }
   3867      1.4  christos 
   3868      1.4  christos   /* Is the reference in range of x0 or gp?
   3869      1.4  christos      Valid gp range conservatively because of alignment issue.  */
   3870  1.4.2.2    martin   if (undefined_weak
   3871  1.4.2.2    martin       || (VALID_ITYPE_IMM (symval)
   3872  1.4.2.2    martin 	  || (symval >= gp
   3873  1.4.2.2    martin 	      && VALID_ITYPE_IMM (symval - gp + max_alignment + reserve_size))
   3874  1.4.2.2    martin 	  || (symval < gp
   3875  1.4.2.2    martin 	      && VALID_ITYPE_IMM (symval - gp - max_alignment - reserve_size))))
   3876      1.4  christos     {
   3877      1.4  christos       unsigned sym = hi_reloc.hi_sym;
   3878      1.4  christos       switch (ELFNN_R_TYPE (rel->r_info))
   3879      1.4  christos 	{
   3880      1.4  christos 	case R_RISCV_PCREL_LO12_I:
   3881  1.4.2.2    martin 	  if (undefined_weak)
   3882  1.4.2.2    martin 	    {
   3883  1.4.2.2    martin 	      /* Change the RS1 to zero, and then modify the relocation
   3884  1.4.2.2    martin 		 type to R_RISCV_LO12_I.  */
   3885  1.4.2.2    martin 	      bfd_vma insn = bfd_get_32 (abfd, contents + rel->r_offset);
   3886  1.4.2.2    martin 	      insn &= ~(OP_MASK_RS1 << OP_SH_RS1);
   3887  1.4.2.2    martin 	      bfd_put_32 (abfd, insn, contents + rel->r_offset);
   3888  1.4.2.2    martin 	      rel->r_info = ELFNN_R_INFO (sym, R_RISCV_LO12_I);
   3889  1.4.2.2    martin 	      rel->r_addend = hi_reloc.hi_addend;
   3890  1.4.2.2    martin 	    }
   3891  1.4.2.2    martin 	  else
   3892  1.4.2.2    martin 	    {
   3893  1.4.2.2    martin 	      rel->r_info = ELFNN_R_INFO (sym, R_RISCV_GPREL_I);
   3894  1.4.2.2    martin 	      rel->r_addend += hi_reloc.hi_addend;
   3895  1.4.2.2    martin 	    }
   3896  1.4.2.2    martin 	  return TRUE;
   3897      1.4  christos 
   3898      1.4  christos 	case R_RISCV_PCREL_LO12_S:
   3899  1.4.2.2    martin 	  if (undefined_weak)
   3900  1.4.2.2    martin 	    {
   3901  1.4.2.2    martin 	      /* Change the RS1 to zero, and then modify the relocation
   3902  1.4.2.2    martin 		 type to R_RISCV_LO12_S.  */
   3903  1.4.2.2    martin 	      bfd_vma insn = bfd_get_32 (abfd, contents + rel->r_offset);
   3904  1.4.2.2    martin 	      insn &= ~(OP_MASK_RS1 << OP_SH_RS1);
   3905  1.4.2.2    martin 	      bfd_put_32 (abfd, insn, contents + rel->r_offset);
   3906  1.4.2.2    martin 	      rel->r_info = ELFNN_R_INFO (sym, R_RISCV_LO12_S);
   3907  1.4.2.2    martin 	      rel->r_addend = hi_reloc.hi_addend;
   3908  1.4.2.2    martin 	    }
   3909  1.4.2.2    martin 	  else
   3910  1.4.2.2    martin 	    {
   3911  1.4.2.2    martin 	      rel->r_info = ELFNN_R_INFO (sym, R_RISCV_GPREL_S);
   3912  1.4.2.2    martin 	      rel->r_addend += hi_reloc.hi_addend;
   3913  1.4.2.2    martin 	    }
   3914  1.4.2.2    martin 	  return TRUE;
   3915      1.4  christos 
   3916      1.4  christos 	case R_RISCV_PCREL_HI20:
   3917      1.4  christos 	  riscv_record_pcgp_hi_reloc (pcgp_relocs,
   3918      1.4  christos 				      rel->r_offset,
   3919      1.4  christos 				      rel->r_addend,
   3920      1.4  christos 				      symval,
   3921      1.4  christos 				      ELFNN_R_SYM(rel->r_info),
   3922  1.4.2.2    martin 				      sym_sec,
   3923  1.4.2.2    martin 				      undefined_weak);
   3924      1.4  christos 	  /* We can delete the unnecessary AUIPC and reloc.  */
   3925      1.4  christos 	  rel->r_info = ELFNN_R_INFO (0, R_RISCV_DELETE);
   3926      1.4  christos 	  rel->r_addend = 4;
   3927  1.4.2.2    martin 	  return TRUE;
   3928      1.4  christos 
   3929      1.4  christos 	default:
   3930      1.4  christos 	  abort ();
   3931      1.4  christos 	}
   3932      1.4  christos     }
   3933      1.4  christos 
   3934      1.4  christos   return TRUE;
   3935      1.4  christos }
   3936      1.4  christos 
   3937      1.4  christos /* Relax PC-relative references to GP-relative references.  */
   3938      1.4  christos 
   3939      1.4  christos static bfd_boolean
   3940      1.4  christos _bfd_riscv_relax_delete (bfd *abfd,
   3941      1.4  christos 			 asection *sec,
   3942      1.4  christos 			 asection *sym_sec ATTRIBUTE_UNUSED,
   3943  1.4.2.1  christos 			 struct bfd_link_info *link_info,
   3944      1.4  christos 			 Elf_Internal_Rela *rel,
   3945      1.4  christos 			 bfd_vma symval ATTRIBUTE_UNUSED,
   3946      1.4  christos 			 bfd_vma max_alignment ATTRIBUTE_UNUSED,
   3947      1.4  christos 			 bfd_vma reserve_size ATTRIBUTE_UNUSED,
   3948      1.4  christos 			 bfd_boolean *again ATTRIBUTE_UNUSED,
   3949  1.4.2.2    martin 			 riscv_pcgp_relocs *pcgp_relocs ATTRIBUTE_UNUSED,
   3950  1.4.2.2    martin 			 bfd_boolean undefined_weak ATTRIBUTE_UNUSED)
   3951      1.4  christos {
   3952  1.4.2.1  christos   if (!riscv_relax_delete_bytes(abfd, sec, rel->r_offset, rel->r_addend,
   3953  1.4.2.1  christos 				link_info))
   3954      1.4  christos     return FALSE;
   3955      1.4  christos   rel->r_info = ELFNN_R_INFO(0, R_RISCV_NONE);
   3956      1.4  christos   return TRUE;
   3957      1.4  christos }
   3958      1.4  christos 
   3959      1.4  christos /* Relax a section.  Pass 0 shortens code sequences unless disabled.  Pass 1
   3960      1.4  christos    deletes the bytes that pass 0 made obselete.  Pass 2, which cannot be
   3961      1.4  christos    disabled, handles code alignment directives.  */
   3962      1.1      matt 
   3963      1.1      matt static bfd_boolean
   3964      1.1      matt _bfd_riscv_relax_section (bfd *abfd, asection *sec,
   3965      1.4  christos 			  struct bfd_link_info *info,
   3966      1.4  christos 			  bfd_boolean *again)
   3967      1.1      matt {
   3968      1.1      matt   Elf_Internal_Shdr *symtab_hdr = &elf_symtab_hdr (abfd);
   3969      1.1      matt   struct riscv_elf_link_hash_table *htab = riscv_elf_hash_table (info);
   3970      1.1      matt   struct bfd_elf_section_data *data = elf_section_data (sec);
   3971      1.1      matt   Elf_Internal_Rela *relocs;
   3972      1.1      matt   bfd_boolean ret = FALSE;
   3973      1.1      matt   unsigned int i;
   3974      1.4  christos   bfd_vma max_alignment, reserve_size = 0;
   3975      1.4  christos   riscv_pcgp_relocs pcgp_relocs;
   3976      1.1      matt 
   3977      1.1      matt   *again = FALSE;
   3978      1.1      matt 
   3979      1.3  christos   if (bfd_link_relocatable (info)
   3980      1.4  christos       || sec->sec_flg0
   3981      1.1      matt       || (sec->flags & SEC_RELOC) == 0
   3982      1.1      matt       || sec->reloc_count == 0
   3983      1.4  christos       || (info->disable_target_specific_optimizations
   3984      1.1      matt 	  && info->relax_pass == 0))
   3985      1.1      matt     return TRUE;
   3986      1.1      matt 
   3987      1.4  christos   riscv_init_pcgp_relocs (&pcgp_relocs);
   3988      1.4  christos 
   3989      1.1      matt   /* Read this BFD's relocs if we haven't done so already.  */
   3990      1.1      matt   if (data->relocs)
   3991      1.1      matt     relocs = data->relocs;
   3992      1.1      matt   else if (!(relocs = _bfd_elf_link_read_relocs (abfd, sec, NULL, NULL,
   3993      1.1      matt 						 info->keep_memory)))
   3994      1.1      matt     goto fail;
   3995      1.1      matt 
   3996      1.4  christos   if (htab)
   3997      1.4  christos     {
   3998      1.4  christos       max_alignment = htab->max_alignment;
   3999      1.4  christos       if (max_alignment == (bfd_vma) -1)
   4000      1.4  christos 	{
   4001      1.4  christos 	  max_alignment = _bfd_riscv_get_max_alignment (sec);
   4002      1.4  christos 	  htab->max_alignment = max_alignment;
   4003      1.4  christos 	}
   4004      1.4  christos     }
   4005      1.4  christos   else
   4006      1.4  christos     max_alignment = _bfd_riscv_get_max_alignment (sec);
   4007      1.4  christos 
   4008      1.1      matt   /* Examine and consider relaxing each reloc.  */
   4009      1.1      matt   for (i = 0; i < sec->reloc_count; i++)
   4010      1.1      matt     {
   4011      1.4  christos       asection *sym_sec;
   4012      1.4  christos       Elf_Internal_Rela *rel = relocs + i;
   4013      1.4  christos       relax_func_t relax_func;
   4014      1.1      matt       int type = ELFNN_R_TYPE (rel->r_info);
   4015      1.1      matt       bfd_vma symval;
   4016  1.4.2.2    martin       char symtype;
   4017  1.4.2.2    martin       bfd_boolean undefined_weak = FALSE;
   4018      1.1      matt 
   4019      1.4  christos       relax_func = NULL;
   4020      1.1      matt       if (info->relax_pass == 0)
   4021      1.1      matt 	{
   4022      1.1      matt 	  if (type == R_RISCV_CALL || type == R_RISCV_CALL_PLT)
   4023      1.1      matt 	    relax_func = _bfd_riscv_relax_call;
   4024      1.4  christos 	  else if (type == R_RISCV_HI20
   4025      1.4  christos 		   || type == R_RISCV_LO12_I
   4026      1.4  christos 		   || type == R_RISCV_LO12_S)
   4027      1.1      matt 	    relax_func = _bfd_riscv_relax_lui;
   4028      1.4  christos 	  else if (!bfd_link_pic(info)
   4029      1.4  christos 		   && (type == R_RISCV_PCREL_HI20
   4030      1.4  christos 		   || type == R_RISCV_PCREL_LO12_I
   4031      1.4  christos 		   || type == R_RISCV_PCREL_LO12_S))
   4032      1.4  christos 	    relax_func = _bfd_riscv_relax_pc;
   4033      1.4  christos 	  else if (type == R_RISCV_TPREL_HI20
   4034      1.4  christos 		   || type == R_RISCV_TPREL_ADD
   4035      1.4  christos 		   || type == R_RISCV_TPREL_LO12_I
   4036      1.4  christos 		   || type == R_RISCV_TPREL_LO12_S)
   4037      1.1      matt 	    relax_func = _bfd_riscv_relax_tls_le;
   4038      1.4  christos 	  else
   4039      1.4  christos 	    continue;
   4040      1.4  christos 
   4041      1.4  christos 	  /* Only relax this reloc if it is paired with R_RISCV_RELAX.  */
   4042      1.4  christos 	  if (i == sec->reloc_count - 1
   4043      1.4  christos 	      || ELFNN_R_TYPE ((rel + 1)->r_info) != R_RISCV_RELAX
   4044      1.4  christos 	      || rel->r_offset != (rel + 1)->r_offset)
   4045      1.4  christos 	    continue;
   4046      1.4  christos 
   4047      1.4  christos 	  /* Skip over the R_RISCV_RELAX.  */
   4048      1.4  christos 	  i++;
   4049      1.1      matt 	}
   4050      1.4  christos       else if (info->relax_pass == 1 && type == R_RISCV_DELETE)
   4051      1.4  christos 	relax_func = _bfd_riscv_relax_delete;
   4052      1.4  christos       else if (info->relax_pass == 2 && type == R_RISCV_ALIGN)
   4053      1.1      matt 	relax_func = _bfd_riscv_relax_align;
   4054      1.4  christos       else
   4055      1.1      matt 	continue;
   4056      1.1      matt 
   4057      1.1      matt       data->relocs = relocs;
   4058      1.1      matt 
   4059      1.1      matt       /* Read this BFD's contents if we haven't done so already.  */
   4060      1.1      matt       if (!data->this_hdr.contents
   4061      1.1      matt 	  && !bfd_malloc_and_get_section (abfd, sec, &data->this_hdr.contents))
   4062      1.1      matt 	goto fail;
   4063      1.1      matt 
   4064      1.1      matt       /* Read this BFD's symbols if we haven't done so already.  */
   4065      1.1      matt       if (symtab_hdr->sh_info != 0
   4066      1.1      matt 	  && !symtab_hdr->contents
   4067      1.1      matt 	  && !(symtab_hdr->contents =
   4068      1.1      matt 	       (unsigned char *) bfd_elf_get_elf_syms (abfd, symtab_hdr,
   4069      1.1      matt 						       symtab_hdr->sh_info,
   4070      1.1      matt 						       0, NULL, NULL, NULL)))
   4071      1.1      matt 	goto fail;
   4072      1.1      matt 
   4073      1.1      matt       /* Get the value of the symbol referred to by the reloc.  */
   4074      1.1      matt       if (ELFNN_R_SYM (rel->r_info) < symtab_hdr->sh_info)
   4075      1.1      matt 	{
   4076      1.1      matt 	  /* A local symbol.  */
   4077      1.1      matt 	  Elf_Internal_Sym *isym = ((Elf_Internal_Sym *) symtab_hdr->contents
   4078      1.1      matt 				    + ELFNN_R_SYM (rel->r_info));
   4079      1.4  christos 	  reserve_size = (isym->st_size - rel->r_addend) > isym->st_size
   4080      1.4  christos 	    ? 0 : isym->st_size - rel->r_addend;
   4081      1.1      matt 
   4082      1.1      matt 	  if (isym->st_shndx == SHN_UNDEF)
   4083  1.4.2.2    martin 	    sym_sec = sec, symval = rel->r_offset;
   4084      1.1      matt 	  else
   4085      1.1      matt 	    {
   4086      1.1      matt 	      BFD_ASSERT (isym->st_shndx < elf_numsections (abfd));
   4087      1.4  christos 	      sym_sec = elf_elfsections (abfd)[isym->st_shndx]->bfd_section;
   4088  1.4.2.1  christos #if 0
   4089  1.4.2.1  christos 	      /* The purpose of this code is unknown.  It breaks linker scripts
   4090  1.4.2.1  christos 		 for embedded development that place sections at address zero.
   4091  1.4.2.1  christos 		 This code is believed to be unnecessary.  Disabling it but not
   4092  1.4.2.1  christos 		 yet removing it, in case something breaks.  */
   4093      1.4  christos 	      if (sec_addr (sym_sec) == 0)
   4094      1.1      matt 		continue;
   4095  1.4.2.1  christos #endif
   4096  1.4.2.2    martin 	      symval = isym->st_value;
   4097      1.1      matt 	    }
   4098  1.4.2.2    martin 	  symtype = ELF_ST_TYPE (isym->st_info);
   4099      1.1      matt 	}
   4100      1.1      matt       else
   4101      1.1      matt 	{
   4102      1.1      matt 	  unsigned long indx;
   4103      1.1      matt 	  struct elf_link_hash_entry *h;
   4104      1.1      matt 
   4105      1.1      matt 	  indx = ELFNN_R_SYM (rel->r_info) - symtab_hdr->sh_info;
   4106      1.1      matt 	  h = elf_sym_hashes (abfd)[indx];
   4107      1.1      matt 
   4108      1.1      matt 	  while (h->root.type == bfd_link_hash_indirect
   4109      1.1      matt 		 || h->root.type == bfd_link_hash_warning)
   4110      1.1      matt 	    h = (struct elf_link_hash_entry *) h->root.u.i.link;
   4111      1.1      matt 
   4112  1.4.2.2    martin 	  if (h->root.type == bfd_link_hash_undefweak
   4113  1.4.2.2    martin 	      && (relax_func == _bfd_riscv_relax_lui
   4114  1.4.2.2    martin 		  || relax_func == _bfd_riscv_relax_pc))
   4115  1.4.2.2    martin 	    {
   4116  1.4.2.2    martin 	      /* For the lui and auipc relaxations, since the symbol
   4117  1.4.2.2    martin 		 value of an undefined weak symbol is always be zero,
   4118  1.4.2.2    martin 		 we can optimize the patterns into a single LI/MV/ADDI
   4119  1.4.2.2    martin 		 instruction.
   4120  1.4.2.2    martin 
   4121  1.4.2.2    martin 		 Note that, creating shared libraries and pie output may
   4122  1.4.2.2    martin 		 break the rule above.  Fortunately, since we do not relax
   4123  1.4.2.2    martin 		 pc relocs when creating shared libraries and pie output,
   4124  1.4.2.2    martin 		 and the absolute address access for R_RISCV_HI20 isn't
   4125  1.4.2.2    martin 		 allowed when "-fPIC" is set, the problem of creating shared
   4126  1.4.2.2    martin 		 libraries can not happen currently.  Once we support the
   4127  1.4.2.2    martin 		 auipc relaxations when creating shared libraries, then we will
   4128  1.4.2.2    martin 		 need the more rigorous checking for this optimization.  */
   4129  1.4.2.2    martin 	      undefined_weak = TRUE;
   4130  1.4.2.2    martin 	    }
   4131  1.4.2.2    martin 
   4132  1.4.2.2    martin 	  /* This line has to match the check in riscv_elf_relocate_section
   4133  1.4.2.2    martin 	     in the R_RISCV_CALL[_PLT] case.  */
   4134  1.4.2.2    martin 	  if (bfd_link_pic (info) && h->plt.offset != MINUS_ONE)
   4135  1.4.2.2    martin 	    {
   4136  1.4.2.2    martin 	      sym_sec = htab->elf.splt;
   4137  1.4.2.2    martin 	      symval = h->plt.offset;
   4138  1.4.2.2    martin 	    }
   4139  1.4.2.2    martin 	  else if (undefined_weak)
   4140  1.4.2.2    martin 	    {
   4141  1.4.2.2    martin 	      symval = 0;
   4142  1.4.2.2    martin 	      sym_sec = bfd_und_section_ptr;
   4143  1.4.2.2    martin 	    }
   4144      1.1      matt 	  else if (h->root.u.def.section->output_section == NULL
   4145      1.1      matt 		   || (h->root.type != bfd_link_hash_defined
   4146      1.1      matt 		       && h->root.type != bfd_link_hash_defweak))
   4147      1.1      matt 	    continue;
   4148      1.1      matt 	  else
   4149  1.4.2.2    martin 	    {
   4150  1.4.2.2    martin 	      symval = h->root.u.def.value;
   4151  1.4.2.2    martin 	      sym_sec = h->root.u.def.section;
   4152  1.4.2.2    martin 	    }
   4153      1.4  christos 
   4154      1.4  christos 	  if (h->type != STT_FUNC)
   4155      1.4  christos 	    reserve_size =
   4156      1.4  christos 	      (h->size - rel->r_addend) > h->size ? 0 : h->size - rel->r_addend;
   4157  1.4.2.2    martin 	  symtype = h->type;
   4158      1.1      matt 	}
   4159      1.1      matt 
   4160  1.4.2.2    martin       if (sym_sec->sec_info_type == SEC_INFO_TYPE_MERGE
   4161  1.4.2.2    martin           && (sym_sec->flags & SEC_MERGE))
   4162  1.4.2.2    martin 	{
   4163  1.4.2.2    martin 	  /* At this stage in linking, no SEC_MERGE symbol has been
   4164  1.4.2.2    martin 	     adjusted, so all references to such symbols need to be
   4165  1.4.2.2    martin 	     passed through _bfd_merged_section_offset.  (Later, in
   4166  1.4.2.2    martin 	     relocate_section, all SEC_MERGE symbols *except* for
   4167  1.4.2.2    martin 	     section symbols have been adjusted.)
   4168  1.4.2.2    martin 
   4169  1.4.2.2    martin 	     gas may reduce relocations against symbols in SEC_MERGE
   4170  1.4.2.2    martin 	     sections to a relocation against the section symbol when
   4171  1.4.2.2    martin 	     the original addend was zero.  When the reloc is against
   4172  1.4.2.2    martin 	     a section symbol we should include the addend in the
   4173  1.4.2.2    martin 	     offset passed to _bfd_merged_section_offset, since the
   4174  1.4.2.2    martin 	     location of interest is the original symbol.  On the
   4175  1.4.2.2    martin 	     other hand, an access to "sym+addend" where "sym" is not
   4176  1.4.2.2    martin 	     a section symbol should not include the addend;  Such an
   4177  1.4.2.2    martin 	     access is presumed to be an offset from "sym";  The
   4178  1.4.2.2    martin 	     location of interest is just "sym".  */
   4179  1.4.2.2    martin 	   if (symtype == STT_SECTION)
   4180  1.4.2.2    martin 	     symval += rel->r_addend;
   4181  1.4.2.2    martin 
   4182  1.4.2.2    martin 	   symval = _bfd_merged_section_offset (abfd, &sym_sec,
   4183  1.4.2.2    martin 						elf_section_data (sym_sec)->sec_info,
   4184  1.4.2.2    martin 						symval);
   4185  1.4.2.2    martin 
   4186  1.4.2.2    martin 	   if (symtype != STT_SECTION)
   4187  1.4.2.2    martin 	     symval += rel->r_addend;
   4188  1.4.2.2    martin 	}
   4189  1.4.2.2    martin       else
   4190  1.4.2.2    martin 	symval += rel->r_addend;
   4191  1.4.2.2    martin 
   4192  1.4.2.2    martin       symval += sec_addr (sym_sec);
   4193      1.1      matt 
   4194      1.4  christos       if (!relax_func (abfd, sec, sym_sec, info, rel, symval,
   4195      1.4  christos 		       max_alignment, reserve_size, again,
   4196  1.4.2.2    martin 		       &pcgp_relocs, undefined_weak))
   4197      1.1      matt 	goto fail;
   4198      1.1      matt     }
   4199      1.1      matt 
   4200      1.1      matt   ret = TRUE;
   4201      1.1      matt 
   4202      1.1      matt fail:
   4203      1.1      matt   if (relocs != data->relocs)
   4204      1.1      matt     free (relocs);
   4205      1.4  christos   riscv_free_pcgp_relocs(&pcgp_relocs, abfd, sec);
   4206      1.1      matt 
   4207      1.1      matt   return ret;
   4208      1.1      matt }
   4209      1.1      matt 
   4210      1.4  christos #if ARCH_SIZE == 32
   4211  1.4.2.2    martin # define PRSTATUS_SIZE			204
   4212      1.4  christos # define PRSTATUS_OFFSET_PR_CURSIG	12
   4213      1.4  christos # define PRSTATUS_OFFSET_PR_PID		24
   4214      1.4  christos # define PRSTATUS_OFFSET_PR_REG		72
   4215      1.4  christos # define ELF_GREGSET_T_SIZE		128
   4216      1.4  christos # define PRPSINFO_SIZE			128
   4217      1.4  christos # define PRPSINFO_OFFSET_PR_PID		16
   4218      1.4  christos # define PRPSINFO_OFFSET_PR_FNAME	32
   4219      1.4  christos # define PRPSINFO_OFFSET_PR_PSARGS	48
   4220      1.4  christos #else
   4221      1.4  christos # define PRSTATUS_SIZE			376
   4222      1.4  christos # define PRSTATUS_OFFSET_PR_CURSIG	12
   4223      1.4  christos # define PRSTATUS_OFFSET_PR_PID		32
   4224      1.4  christos # define PRSTATUS_OFFSET_PR_REG		112
   4225      1.4  christos # define ELF_GREGSET_T_SIZE		256
   4226      1.4  christos # define PRPSINFO_SIZE			136
   4227      1.4  christos # define PRPSINFO_OFFSET_PR_PID		24
   4228      1.4  christos # define PRPSINFO_OFFSET_PR_FNAME	40
   4229      1.4  christos # define PRPSINFO_OFFSET_PR_PSARGS	56
   4230      1.4  christos #endif
   4231      1.4  christos 
   4232      1.4  christos /* Support for core dump NOTE sections.  */
   4233      1.4  christos 
   4234      1.4  christos static bfd_boolean
   4235      1.4  christos riscv_elf_grok_prstatus (bfd *abfd, Elf_Internal_Note *note)
   4236      1.4  christos {
   4237      1.4  christos   switch (note->descsz)
   4238      1.4  christos     {
   4239      1.4  christos       default:
   4240      1.4  christos 	return FALSE;
   4241      1.4  christos 
   4242      1.4  christos       case PRSTATUS_SIZE:  /* sizeof(struct elf_prstatus) on Linux/RISC-V.  */
   4243      1.4  christos 	/* pr_cursig */
   4244      1.4  christos 	elf_tdata (abfd)->core->signal
   4245      1.4  christos 	  = bfd_get_16 (abfd, note->descdata + PRSTATUS_OFFSET_PR_CURSIG);
   4246      1.4  christos 
   4247      1.4  christos 	/* pr_pid */
   4248      1.4  christos 	elf_tdata (abfd)->core->lwpid
   4249      1.4  christos 	  = bfd_get_32 (abfd, note->descdata + PRSTATUS_OFFSET_PR_PID);
   4250      1.4  christos 	break;
   4251      1.4  christos     }
   4252      1.4  christos 
   4253      1.4  christos   /* Make a ".reg/999" section.  */
   4254      1.4  christos   return _bfd_elfcore_make_pseudosection (abfd, ".reg", ELF_GREGSET_T_SIZE,
   4255      1.4  christos 					  note->descpos + PRSTATUS_OFFSET_PR_REG);
   4256      1.4  christos }
   4257      1.4  christos 
   4258      1.4  christos static bfd_boolean
   4259      1.4  christos riscv_elf_grok_psinfo (bfd *abfd, Elf_Internal_Note *note)
   4260      1.4  christos {
   4261      1.4  christos   switch (note->descsz)
   4262      1.4  christos     {
   4263      1.4  christos       default:
   4264      1.4  christos 	return FALSE;
   4265      1.4  christos 
   4266      1.4  christos       case PRPSINFO_SIZE: /* sizeof(struct elf_prpsinfo) on Linux/RISC-V.  */
   4267      1.4  christos 	/* pr_pid */
   4268      1.4  christos 	elf_tdata (abfd)->core->pid
   4269      1.4  christos 	  = bfd_get_32 (abfd, note->descdata + PRPSINFO_OFFSET_PR_PID);
   4270      1.4  christos 
   4271      1.4  christos 	/* pr_fname */
   4272      1.4  christos 	elf_tdata (abfd)->core->program = _bfd_elfcore_strndup
   4273      1.4  christos 	  (abfd, note->descdata + PRPSINFO_OFFSET_PR_FNAME, 16);
   4274      1.4  christos 
   4275      1.4  christos 	/* pr_psargs */
   4276      1.4  christos 	elf_tdata (abfd)->core->command = _bfd_elfcore_strndup
   4277      1.4  christos 	  (abfd, note->descdata + PRPSINFO_OFFSET_PR_PSARGS, 80);
   4278      1.4  christos 	break;
   4279      1.4  christos     }
   4280      1.4  christos 
   4281      1.4  christos   /* Note that for some reason, a spurious space is tacked
   4282      1.4  christos      onto the end of the args in some (at least one anyway)
   4283      1.4  christos      implementations, so strip it off if it exists.  */
   4284      1.4  christos 
   4285      1.4  christos   {
   4286      1.4  christos     char *command = elf_tdata (abfd)->core->command;
   4287      1.4  christos     int n = strlen (command);
   4288      1.4  christos 
   4289      1.4  christos     if (0 < n && command[n - 1] == ' ')
   4290      1.4  christos       command[n - 1] = '\0';
   4291      1.4  christos   }
   4292      1.4  christos 
   4293      1.4  christos   return TRUE;
   4294      1.4  christos }
   4295      1.4  christos 
   4296      1.4  christos /* Set the right mach type.  */
   4297      1.4  christos static bfd_boolean
   4298      1.4  christos riscv_elf_object_p (bfd *abfd)
   4299      1.4  christos {
   4300      1.4  christos   /* There are only two mach types in RISCV currently.  */
   4301      1.4  christos   if (strcmp (abfd->xvec->name, "elf32-littleriscv") == 0)
   4302      1.4  christos     bfd_default_set_arch_mach (abfd, bfd_arch_riscv, bfd_mach_riscv32);
   4303      1.4  christos   else
   4304      1.4  christos     bfd_default_set_arch_mach (abfd, bfd_arch_riscv, bfd_mach_riscv64);
   4305      1.4  christos 
   4306      1.4  christos   return TRUE;
   4307      1.4  christos }
   4308      1.4  christos 
   4309  1.4.2.2    martin /* Determine whether an object attribute tag takes an integer, a
   4310  1.4.2.2    martin    string or both.  */
   4311  1.4.2.2    martin 
   4312  1.4.2.2    martin static int
   4313  1.4.2.2    martin riscv_elf_obj_attrs_arg_type (int tag)
   4314  1.4.2.2    martin {
   4315  1.4.2.2    martin   return (tag & 1) != 0 ? ATTR_TYPE_FLAG_STR_VAL : ATTR_TYPE_FLAG_INT_VAL;
   4316  1.4.2.2    martin }
   4317      1.1      matt 
   4318      1.3  christos #define TARGET_LITTLE_SYM		riscv_elfNN_vec
   4319      1.1      matt #define TARGET_LITTLE_NAME		"elfNN-littleriscv"
   4320      1.1      matt 
   4321      1.1      matt #define elf_backend_reloc_type_class	     riscv_reloc_type_class
   4322      1.1      matt 
   4323      1.4  christos #define bfd_elfNN_bfd_reloc_name_lookup	     riscv_reloc_name_lookup
   4324      1.1      matt #define bfd_elfNN_bfd_link_hash_table_create riscv_elf_link_hash_table_create
   4325      1.1      matt #define bfd_elfNN_bfd_reloc_type_lookup	     riscv_reloc_type_lookup
   4326      1.1      matt #define bfd_elfNN_bfd_merge_private_bfd_data \
   4327      1.1      matt   _bfd_riscv_elf_merge_private_bfd_data
   4328      1.1      matt 
   4329      1.1      matt #define elf_backend_copy_indirect_symbol     riscv_elf_copy_indirect_symbol
   4330      1.1      matt #define elf_backend_create_dynamic_sections  riscv_elf_create_dynamic_sections
   4331      1.1      matt #define elf_backend_check_relocs	     riscv_elf_check_relocs
   4332      1.1      matt #define elf_backend_adjust_dynamic_symbol    riscv_elf_adjust_dynamic_symbol
   4333      1.1      matt #define elf_backend_size_dynamic_sections    riscv_elf_size_dynamic_sections
   4334      1.1      matt #define elf_backend_relocate_section	     riscv_elf_relocate_section
   4335      1.1      matt #define elf_backend_finish_dynamic_symbol    riscv_elf_finish_dynamic_symbol
   4336      1.1      matt #define elf_backend_finish_dynamic_sections  riscv_elf_finish_dynamic_sections
   4337      1.1      matt #define elf_backend_gc_mark_hook	     riscv_elf_gc_mark_hook
   4338      1.1      matt #define elf_backend_plt_sym_val		     riscv_elf_plt_sym_val
   4339      1.4  christos #define elf_backend_grok_prstatus	     riscv_elf_grok_prstatus
   4340      1.4  christos #define elf_backend_grok_psinfo		     riscv_elf_grok_psinfo
   4341      1.4  christos #define elf_backend_object_p		     riscv_elf_object_p
   4342      1.4  christos #define elf_info_to_howto_rel		     NULL
   4343      1.4  christos #define elf_info_to_howto		     riscv_info_to_howto_rela
   4344      1.4  christos #define bfd_elfNN_bfd_relax_section	     _bfd_riscv_relax_section
   4345      1.4  christos 
   4346      1.4  christos #define elf_backend_init_index_section	     _bfd_elf_init_1_index_section
   4347      1.4  christos 
   4348      1.4  christos #define elf_backend_can_gc_sections	1
   4349      1.4  christos #define elf_backend_can_refcount	1
   4350      1.4  christos #define elf_backend_want_got_plt	1
   4351      1.4  christos #define elf_backend_plt_readonly	1
   4352      1.4  christos #define elf_backend_plt_alignment	4
   4353      1.4  christos #define elf_backend_want_plt_sym	1
   4354      1.4  christos #define elf_backend_got_header_size	(ARCH_SIZE / 8)
   4355      1.4  christos #define elf_backend_want_dynrelro	1
   4356      1.4  christos #define elf_backend_rela_normal		1
   4357      1.4  christos #define elf_backend_default_execstack	0
   4358      1.1      matt 
   4359  1.4.2.2    martin #undef  elf_backend_obj_attrs_vendor
   4360  1.4.2.2    martin #define elf_backend_obj_attrs_vendor            "riscv"
   4361  1.4.2.2    martin #undef  elf_backend_obj_attrs_arg_type
   4362  1.4.2.2    martin #define elf_backend_obj_attrs_arg_type          riscv_elf_obj_attrs_arg_type
   4363  1.4.2.2    martin #undef  elf_backend_obj_attrs_section_type
   4364  1.4.2.2    martin #define elf_backend_obj_attrs_section_type      SHT_RISCV_ATTRIBUTES
   4365  1.4.2.2    martin #undef  elf_backend_obj_attrs_section
   4366  1.4.2.2    martin #define elf_backend_obj_attrs_section           ".riscv.attributes"
   4367  1.4.2.2    martin 
   4368      1.1      matt #include "elfNN-target.h"
   4369