Back to index

cell-binutils  2.17cvs20070401
elf32-frv.c
Go to the documentation of this file.
00001 /* FRV-specific support for 32-bit ELF.
00002    Copyright 2002, 2003, 2004, 2005, 2006, 2007
00003    Free Software Foundation, Inc.
00004 
00005 This file is part of BFD, the Binary File Descriptor library.
00006 
00007 This program is free software; you can redistribute it and/or modify
00008 it under the terms of the GNU General Public License as published by
00009 the Free Software Foundation; either version 2 of the License, or
00010 (at your option) any later version.
00011 
00012 This program is distributed in the hope that it will be useful,
00013 but WITHOUT ANY WARRANTY; without even the implied warranty of
00014 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00015 GNU General Public License for more details.
00016 
00017 You should have received a copy of the GNU General Public License
00018 along with this program; if not, write to the Free Software
00019 Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA.  */
00020 
00021 #include "bfd.h"
00022 #include "sysdep.h"
00023 #include "libbfd.h"
00024 #include "elf-bfd.h"
00025 #include "elf/frv.h"
00026 #include "elf/dwarf2.h"
00027 #include "hashtab.h"
00028 
00029 /* Forward declarations.  */
00030 static bfd_reloc_status_type elf32_frv_relocate_lo16
00031   PARAMS ((bfd *,  Elf_Internal_Rela *, bfd_byte *, bfd_vma));
00032 static bfd_reloc_status_type elf32_frv_relocate_hi16
00033   PARAMS ((bfd *,  Elf_Internal_Rela *, bfd_byte *, bfd_vma));
00034 static bfd_reloc_status_type elf32_frv_relocate_label24
00035   PARAMS ((bfd *, asection *, Elf_Internal_Rela *, bfd_byte *, bfd_vma));
00036 static bfd_reloc_status_type elf32_frv_relocate_gprel12
00037   PARAMS ((struct bfd_link_info *, bfd *, asection *, Elf_Internal_Rela *,
00038           bfd_byte *, bfd_vma));
00039 static bfd_reloc_status_type elf32_frv_relocate_gprelu12
00040   PARAMS ((struct bfd_link_info *, bfd *, asection *, Elf_Internal_Rela *,
00041           bfd_byte *, bfd_vma));
00042 static bfd_reloc_status_type elf32_frv_relocate_gprello
00043   PARAMS ((struct bfd_link_info *, bfd *, asection *, Elf_Internal_Rela *,
00044           bfd_byte *, bfd_vma));
00045 static bfd_reloc_status_type elf32_frv_relocate_gprelhi
00046   PARAMS ((struct bfd_link_info *, bfd *, asection *, Elf_Internal_Rela *,
00047           bfd_byte *, bfd_vma));
00048 static reloc_howto_type *frv_reloc_type_lookup
00049   PARAMS ((bfd *, bfd_reloc_code_real_type));
00050 static void frv_info_to_howto_rela
00051   PARAMS ((bfd *, arelent *, Elf_Internal_Rela *));
00052 static bfd_boolean elf32_frv_relocate_section
00053   PARAMS ((bfd *, struct bfd_link_info *, bfd *, asection *, bfd_byte *,
00054           Elf_Internal_Rela *, Elf_Internal_Sym *, asection **));
00055 static bfd_boolean elf32_frv_add_symbol_hook
00056   PARAMS (( bfd *, struct bfd_link_info *, Elf_Internal_Sym *,
00057            const char **, flagword *, asection **, bfd_vma *));
00058 static bfd_reloc_status_type frv_final_link_relocate
00059   PARAMS ((reloc_howto_type *, bfd *, asection *, bfd_byte *,
00060           Elf_Internal_Rela *, bfd_vma));
00061 static bfd_boolean elf32_frv_check_relocs
00062   PARAMS ((bfd *, struct bfd_link_info *, asection *,
00063           const Elf_Internal_Rela *));
00064 static int elf32_frv_machine
00065   PARAMS ((bfd *));
00066 static bfd_boolean elf32_frv_object_p
00067   PARAMS ((bfd *));
00068 static bfd_boolean frv_elf_set_private_flags
00069   PARAMS ((bfd *, flagword));
00070 static bfd_boolean frv_elf_copy_private_bfd_data
00071   PARAMS ((bfd *, bfd *));
00072 static bfd_boolean frv_elf_merge_private_bfd_data
00073   PARAMS ((bfd *, bfd *));
00074 static bfd_boolean frv_elf_print_private_bfd_data
00075   PARAMS ((bfd *, PTR));
00076 static bfd_boolean elf32_frv_grok_prstatus (bfd * abfd,
00077                                        Elf_Internal_Note * note);
00078 static bfd_boolean elf32_frv_grok_psinfo (bfd * abfd,
00079                                      Elf_Internal_Note * note);
00080 
00081 static reloc_howto_type elf32_frv_howto_table [] =
00082 {
00083   /* This reloc does nothing.  */
00084   HOWTO (R_FRV_NONE,        /* type */
00085         0,                  /* rightshift */
00086         2,                  /* size (0 = byte, 1 = short, 2 = long) */
00087         32,                 /* bitsize */
00088         FALSE,                     /* pc_relative */
00089         0,                  /* bitpos */
00090         complain_overflow_bitfield, /* complain_on_overflow */
00091         bfd_elf_generic_reloc,     /* special_function */
00092         "R_FRV_NONE",              /* name */
00093         FALSE,                     /* partial_inplace */
00094         0,                  /* src_mask */
00095         0,                  /* dst_mask */
00096         FALSE),             /* pcrel_offset */
00097 
00098   /* A 32 bit absolute relocation.  */
00099   HOWTO (R_FRV_32,          /* type */
00100         0,                  /* rightshift */
00101         2,                  /* size (0 = byte, 1 = short, 2 = long) */
00102         32,                 /* bitsize */
00103         FALSE,                     /* pc_relative */
00104         0,                  /* bitpos */
00105         complain_overflow_bitfield, /* complain_on_overflow */
00106         bfd_elf_generic_reloc,     /* special_function */
00107         "R_FRV_32",         /* name */
00108         FALSE,                     /* partial_inplace */
00109         0xffffffff,         /* src_mask */
00110         0xffffffff,         /* dst_mask */
00111         FALSE),             /* pcrel_offset */
00112 
00113   /* A 16 bit pc-relative relocation.  */
00114   HOWTO (R_FRV_LABEL16,            /* type */
00115         2,                  /* rightshift */
00116         2,                  /* size (0 = byte, 1 = short, 2 = long) */
00117         16,                 /* bitsize */
00118         TRUE,               /* pc_relative */
00119         0,                  /* bitpos */
00120         complain_overflow_signed, /* complain_on_overflow */
00121         bfd_elf_generic_reloc,     /* special_function */
00122         "R_FRV_LABEL16",    /* name */
00123         FALSE,                     /* partial_inplace */
00124         0xffff,             /* src_mask */
00125         0xffff,             /* dst_mask */
00126         TRUE),                     /* pcrel_offset */
00127 
00128   /* A 24-bit pc-relative relocation.  */
00129   HOWTO (R_FRV_LABEL24,            /* type */
00130         2,                  /* rightshift */
00131         2,                  /* size (0 = byte, 1 = short, 2 = long) */
00132         26,                 /* bitsize */
00133         TRUE,               /* pc_relative */
00134         0,                  /* bitpos */
00135         complain_overflow_bitfield, /* complain_on_overflow */
00136         bfd_elf_generic_reloc,     /* special_function */
00137         "R_FRV_LABEL24",    /* name */
00138         FALSE,                     /* partial_inplace */
00139         0x7e03ffff,         /* src_mask */
00140         0x7e03ffff,         /* dst_mask */
00141         TRUE),                     /* pcrel_offset */
00142 
00143   HOWTO (R_FRV_LO16,        /* type */
00144         0,                  /* rightshift */
00145         2,                  /* size (0 = byte, 1 = short, 2 = long) */
00146         16,                 /* bitsize */
00147         FALSE,                     /* pc_relative */
00148         0,                  /* bitpos */
00149         complain_overflow_dont, /* complain_on_overflow */
00150         bfd_elf_generic_reloc,     /* special_function */
00151         "R_FRV_LO16",              /* name */
00152         FALSE,                     /* partial_inplace */
00153         0xffff,             /* src_mask */
00154         0xffff,             /* dst_mask */
00155         FALSE),             /* pcrel_offset */
00156 
00157   HOWTO (R_FRV_HI16,        /* type */
00158         0,                  /* rightshift */
00159         2,                  /* size (0 = byte, 1 = short, 2 = long) */
00160         16,                 /* bitsize */
00161         FALSE,                     /* pc_relative */
00162         0,                  /* bitpos */
00163         complain_overflow_dont, /* complain_on_overflow */
00164         bfd_elf_generic_reloc,     /* special_function */
00165         "R_FRV_HI16",              /* name */
00166         FALSE,                     /* partial_inplace */
00167         0xffff,             /* src_mask */
00168         0xffff,             /* dst_mask */
00169         FALSE),             /* pcrel_offset */
00170 
00171   HOWTO (R_FRV_GPREL12,            /* type */
00172         0,                  /* rightshift */
00173         2,                  /* size (0 = byte, 1 = short, 2 = long) */
00174         12,                 /* bitsize */
00175         FALSE,                     /* pc_relative */
00176         0,                  /* bitpos */
00177         complain_overflow_dont, /* complain_on_overflow */
00178         bfd_elf_generic_reloc,     /* special_function */
00179         "R_FRV_GPREL12",    /* name */
00180         FALSE,                     /* partial_inplace */
00181         0xfff,                     /* src_mask */
00182         0xfff,                     /* dst_mask */
00183         FALSE),             /* pcrel_offset */
00184 
00185   HOWTO (R_FRV_GPRELU12,    /* type */
00186         0,                  /* rightshift */
00187         2,                  /* size (0 = byte, 1 = short, 2 = long) */
00188         12,                 /* bitsize */
00189         FALSE,                     /* pc_relative */
00190         0,                  /* bitpos */
00191         complain_overflow_dont, /* complain_on_overflow */
00192         bfd_elf_generic_reloc,     /* special_function */
00193         "R_FRV_GPRELU12",   /* name */
00194         FALSE,                     /* partial_inplace */
00195         0xfff,                     /* src_mask */
00196         0x3f03f,            /* dst_mask */
00197         FALSE),             /* pcrel_offset */
00198 
00199   HOWTO (R_FRV_GPREL32,            /* type */
00200         0,                  /* rightshift */
00201         2,                  /* size (0 = byte, 1 = short, 2 = long) */
00202         32,                 /* bitsize */
00203         FALSE,                     /* pc_relative */
00204         0,                  /* bitpos */
00205         complain_overflow_dont, /* complain_on_overflow */
00206         bfd_elf_generic_reloc,     /* special_function */
00207         "R_FRV_GPREL32",    /* name */
00208         FALSE,                     /* partial_inplace */
00209         0xffffffff,         /* src_mask */
00210         0xffffffff,         /* dst_mask */
00211         FALSE),             /* pcrel_offset */
00212 
00213   HOWTO (R_FRV_GPRELHI,            /* type */
00214         0,                  /* rightshift */
00215         2,                  /* size (0 = byte, 1 = short, 2 = long) */
00216         16,                 /* bitsize */
00217         FALSE,                     /* pc_relative */
00218         0,                  /* bitpos */
00219         complain_overflow_dont, /* complain_on_overflow */
00220         bfd_elf_generic_reloc,     /* special_function */
00221         "R_FRV_GPRELHI",    /* name */
00222         FALSE,                     /* partial_inplace */
00223         0xffff,             /* src_mask */
00224         0xffff,             /* dst_mask */
00225         FALSE),             /* pcrel_offset */
00226 
00227   HOWTO (R_FRV_GPRELLO,            /* type */
00228         0,                  /* rightshift */
00229         2,                  /* size (0 = byte, 1 = short, 2 = long) */
00230         16,                 /* bitsize */
00231         FALSE,                     /* pc_relative */
00232         0,                  /* bitpos */
00233         complain_overflow_dont, /* complain_on_overflow */
00234         bfd_elf_generic_reloc,     /* special_function */
00235         "R_FRV_GPRELLO",    /* name */
00236         FALSE,                     /* partial_inplace */
00237         0xffff,             /* src_mask */
00238         0xffff,             /* dst_mask */
00239         FALSE),             /* pcrel_offset */
00240 
00241   /* A 12-bit signed operand with the GOT offset for the address of
00242      the symbol.  */
00243   HOWTO (R_FRV_GOT12,              /* type */
00244         0,                  /* rightshift */
00245         2,                  /* size (0 = byte, 1 = short, 2 = long) */
00246         12,                 /* bitsize */
00247         FALSE,                     /* pc_relative */
00248         0,                  /* bitpos */
00249         complain_overflow_signed, /* complain_on_overflow */
00250         bfd_elf_generic_reloc,     /* special_function */
00251         "R_FRV_GOT12",             /* name */
00252         FALSE,                     /* partial_inplace */
00253         0xfff,                     /* src_mask */
00254         0xfff,                     /* dst_mask */
00255         FALSE),             /* pcrel_offset */
00256 
00257   /* The upper 16 bits of the GOT offset for the address of the
00258      symbol.  */
00259   HOWTO (R_FRV_GOTHI,              /* type */
00260         0,                  /* rightshift */
00261         2,                  /* size (0 = byte, 1 = short, 2 = long) */
00262         16,                 /* bitsize */
00263         FALSE,                     /* pc_relative */
00264         0,                  /* bitpos */
00265         complain_overflow_dont, /* complain_on_overflow */
00266         bfd_elf_generic_reloc,     /* special_function */
00267         "R_FRV_GOTHI",             /* name */
00268         FALSE,                     /* partial_inplace */
00269         0xffff,             /* src_mask */
00270         0xffff,             /* dst_mask */
00271         FALSE),             /* pcrel_offset */
00272 
00273   /* The lower 16 bits of the GOT offset for the address of the
00274      symbol.  */
00275   HOWTO (R_FRV_GOTLO,              /* type */
00276         0,                  /* rightshift */
00277         2,                  /* size (0 = byte, 1 = short, 2 = long) */
00278         16,                 /* bitsize */
00279         FALSE,                     /* pc_relative */
00280         0,                  /* bitpos */
00281         complain_overflow_dont, /* complain_on_overflow */
00282         bfd_elf_generic_reloc,     /* special_function */
00283         "R_FRV_GOTLO",             /* name */
00284         FALSE,                     /* partial_inplace */
00285         0xffff,             /* src_mask */
00286         0xffff,             /* dst_mask */
00287         FALSE),             /* pcrel_offset */
00288 
00289   /* The 32-bit address of the canonical descriptor of a function.  */
00290   HOWTO (R_FRV_FUNCDESC,    /* type */
00291         0,                  /* rightshift */
00292         2,                  /* size (0 = byte, 1 = short, 2 = long) */
00293         32,                 /* bitsize */
00294         FALSE,                     /* pc_relative */
00295         0,                  /* bitpos */
00296         complain_overflow_bitfield, /* complain_on_overflow */
00297         bfd_elf_generic_reloc,     /* special_function */
00298         "R_FRV_FUNCDESC",   /* name */
00299         FALSE,                     /* partial_inplace */
00300         0xffffffff,         /* src_mask */
00301         0xffffffff,         /* dst_mask */
00302         FALSE),             /* pcrel_offset */
00303 
00304   /* A 12-bit signed operand with the GOT offset for the address of
00305      canonical descriptor of a function.  */
00306   HOWTO (R_FRV_FUNCDESC_GOT12,     /* type */
00307         0,                  /* rightshift */
00308         2,                  /* size (0 = byte, 1 = short, 2 = long) */
00309         12,                 /* bitsize */
00310         FALSE,                     /* pc_relative */
00311         0,                  /* bitpos */
00312         complain_overflow_signed, /* complain_on_overflow */
00313         bfd_elf_generic_reloc,     /* special_function */
00314         "R_FRV_FUNCDESC_GOT12", /* name */
00315         FALSE,                     /* partial_inplace */
00316         0xfff,                     /* src_mask */
00317         0xfff,                     /* dst_mask */
00318         FALSE),             /* pcrel_offset */
00319 
00320   /* The upper 16 bits of the GOT offset for the address of the
00321      canonical descriptor of a function.  */
00322   HOWTO (R_FRV_FUNCDESC_GOTHI,     /* type */
00323         0,                  /* rightshift */
00324         2,                  /* size (0 = byte, 1 = short, 2 = long) */
00325         16,                 /* bitsize */
00326         FALSE,                     /* pc_relative */
00327         0,                  /* bitpos */
00328         complain_overflow_dont, /* complain_on_overflow */
00329         bfd_elf_generic_reloc,     /* special_function */
00330         "R_FRV_FUNCDESC_GOTHI", /* name */
00331         FALSE,                     /* partial_inplace */
00332         0xffff,             /* src_mask */
00333         0xffff,             /* dst_mask */
00334         FALSE),             /* pcrel_offset */
00335 
00336   /* The lower 16 bits of the GOT offset for the address of the
00337      canonical descriptor of a function.  */
00338   HOWTO (R_FRV_FUNCDESC_GOTLO,     /* type */
00339         0,                  /* rightshift */
00340         2,                  /* size (0 = byte, 1 = short, 2 = long) */
00341         16,                 /* bitsize */
00342         FALSE,                     /* pc_relative */
00343         0,                  /* bitpos */
00344         complain_overflow_dont, /* complain_on_overflow */
00345         bfd_elf_generic_reloc,     /* special_function */
00346         "R_FRV_FUNCDESC_GOTLO", /* name */
00347         FALSE,                     /* partial_inplace */
00348         0xffff,             /* src_mask */
00349         0xffff,             /* dst_mask */
00350         FALSE),             /* pcrel_offset */
00351 
00352   /* The 64-bit descriptor of a function.  */
00353   HOWTO (R_FRV_FUNCDESC_VALUE,     /* type */
00354         0,                  /* rightshift */
00355         2,                  /* size (0 = byte, 1 = short, 2 = long) */
00356         64,                 /* bitsize */
00357         FALSE,                     /* pc_relative */
00358         0,                  /* bitpos */
00359         complain_overflow_bitfield, /* complain_on_overflow */
00360         bfd_elf_generic_reloc,     /* special_function */
00361         "R_FRV_FUNCDESC_VALUE", /* name */
00362         FALSE,                     /* partial_inplace */
00363         0xffffffff,         /* src_mask */
00364         0xffffffff,         /* dst_mask */
00365         FALSE),             /* pcrel_offset */
00366 
00367   /* A 12-bit signed operand with the GOT offset for the address of
00368      canonical descriptor of a function.  */
00369   HOWTO (R_FRV_FUNCDESC_GOTOFF12, /* type */
00370         0,                  /* rightshift */
00371         2,                  /* size (0 = byte, 1 = short, 2 = long) */
00372         12,                 /* bitsize */
00373         FALSE,                     /* pc_relative */
00374         0,                  /* bitpos */
00375         complain_overflow_signed, /* complain_on_overflow */
00376         bfd_elf_generic_reloc,     /* special_function */
00377         "R_FRV_FUNCDESC_GOTOFF12", /* name */
00378         FALSE,                     /* partial_inplace */
00379         0xfff,                     /* src_mask */
00380         0xfff,                     /* dst_mask */
00381         FALSE),             /* pcrel_offset */
00382 
00383   /* The upper 16 bits of the GOT offset for the address of the
00384      canonical descriptor of a function.  */
00385   HOWTO (R_FRV_FUNCDESC_GOTOFFHI, /* type */
00386         0,                  /* rightshift */
00387         2,                  /* size (0 = byte, 1 = short, 2 = long) */
00388         16,                 /* bitsize */
00389         FALSE,                     /* pc_relative */
00390         0,                  /* bitpos */
00391         complain_overflow_dont, /* complain_on_overflow */
00392         bfd_elf_generic_reloc,     /* special_function */
00393         "R_FRV_FUNCDESC_GOTOFFHI", /* name */
00394         FALSE,                     /* partial_inplace */
00395         0xffff,             /* src_mask */
00396         0xffff,             /* dst_mask */
00397         FALSE),             /* pcrel_offset */
00398 
00399   /* The lower 16 bits of the GOT offset for the address of the
00400      canonical descriptor of a function.  */
00401   HOWTO (R_FRV_FUNCDESC_GOTOFFLO, /* type */
00402         0,                  /* rightshift */
00403         2,                  /* size (0 = byte, 1 = short, 2 = long) */
00404         16,                 /* bitsize */
00405         FALSE,                     /* pc_relative */
00406         0,                  /* bitpos */
00407         complain_overflow_dont, /* complain_on_overflow */
00408         bfd_elf_generic_reloc,     /* special_function */
00409         "R_FRV_FUNCDESC_GOTOFFLO", /* name */
00410         FALSE,                     /* partial_inplace */
00411         0xffff,             /* src_mask */
00412         0xffff,             /* dst_mask */
00413         FALSE),             /* pcrel_offset */
00414 
00415   /* A 12-bit signed operand with the GOT offset for the address of
00416      the symbol.  */
00417   HOWTO (R_FRV_GOTOFF12,    /* type */
00418         0,                  /* rightshift */
00419         2,                  /* size (0 = byte, 1 = short, 2 = long) */
00420         12,                 /* bitsize */
00421         FALSE,                     /* pc_relative */
00422         0,                  /* bitpos */
00423         complain_overflow_signed, /* complain_on_overflow */
00424         bfd_elf_generic_reloc,     /* special_function */
00425         "R_FRV_GOTOFF12",   /* name */
00426         FALSE,                     /* partial_inplace */
00427         0xfff,                     /* src_mask */
00428         0xfff,                     /* dst_mask */
00429         FALSE),             /* pcrel_offset */
00430 
00431   /* The upper 16 bits of the GOT offset for the address of the
00432      symbol.  */
00433   HOWTO (R_FRV_GOTOFFHI,    /* type */
00434         0,                  /* rightshift */
00435         2,                  /* size (0 = byte, 1 = short, 2 = long) */
00436         16,                 /* bitsize */
00437         FALSE,                     /* pc_relative */
00438         0,                  /* bitpos */
00439         complain_overflow_dont, /* complain_on_overflow */
00440         bfd_elf_generic_reloc,     /* special_function */
00441         "R_FRV_GOTOFFHI",   /* name */
00442         FALSE,                     /* partial_inplace */
00443         0xffff,             /* src_mask */
00444         0xffff,             /* dst_mask */
00445         FALSE),             /* pcrel_offset */
00446 
00447   /* The lower 16 bits of the GOT offset for the address of the
00448      symbol.  */
00449   HOWTO (R_FRV_GOTOFFLO,    /* type */
00450         0,                  /* rightshift */
00451         2,                  /* size (0 = byte, 1 = short, 2 = long) */
00452         16,                 /* bitsize */
00453         FALSE,                     /* pc_relative */
00454         0,                  /* bitpos */
00455         complain_overflow_dont, /* complain_on_overflow */
00456         bfd_elf_generic_reloc,     /* special_function */
00457         "R_FRV_GOTOFFLO",   /* name */
00458         FALSE,                     /* partial_inplace */
00459         0xffff,             /* src_mask */
00460         0xffff,             /* dst_mask */
00461         FALSE),             /* pcrel_offset */
00462 
00463   /* A 24-bit pc-relative relocation referencing the TLS PLT entry for
00464      a thread-local symbol.  If the symbol number is 0, it refers to
00465      the module.  */
00466   HOWTO (R_FRV_GETTLSOFF,   /* type */
00467         2,                  /* rightshift */
00468         2,                  /* size (0 = byte, 1 = short, 2 = long) */
00469         26,                 /* bitsize */
00470         TRUE,               /* pc_relative */
00471         0,                  /* bitpos */
00472         complain_overflow_bitfield, /* complain_on_overflow */
00473         bfd_elf_generic_reloc,     /* special_function */
00474         "R_FRV_GETTLSOFF",  /* name */
00475         FALSE,                     /* partial_inplace */
00476         0x7e03ffff,         /* src_mask */
00477         0x7e03ffff,         /* dst_mask */
00478         TRUE),                     /* pcrel_offset */
00479 
00480   /* A 64-bit TLS descriptor for a symbol.  This relocation is only
00481      valid as a REL, dynamic relocation.  */
00482   HOWTO (R_FRV_TLSDESC_VALUE,      /* type */
00483         0,                  /* rightshift */
00484         2,                  /* size (0 = byte, 1 = short, 2 = long) */
00485         64,                 /* bitsize */
00486         FALSE,                     /* pc_relative */
00487         0,                  /* bitpos */
00488         complain_overflow_bitfield, /* complain_on_overflow */
00489         bfd_elf_generic_reloc,     /* special_function */
00490         "R_FRV_TLSDESC_VALUE", /* name */
00491         FALSE,                     /* partial_inplace */
00492         0xffffffff,         /* src_mask */
00493         0xffffffff,         /* dst_mask */
00494         FALSE),             /* pcrel_offset */
00495 
00496   /* A 12-bit signed operand with the GOT offset for the TLS
00497      descriptor of the symbol.  */
00498   HOWTO (R_FRV_GOTTLSDESC12,       /* type */
00499         0,                  /* rightshift */
00500         2,                  /* size (0 = byte, 1 = short, 2 = long) */
00501         12,                 /* bitsize */
00502         FALSE,                     /* pc_relative */
00503         0,                  /* bitpos */
00504         complain_overflow_signed, /* complain_on_overflow */
00505         bfd_elf_generic_reloc,     /* special_function */
00506         "R_FRV_GOTTLSDESC12",      /* name */
00507         FALSE,                     /* partial_inplace */
00508         0xfff,                     /* src_mask */
00509         0xfff,                     /* dst_mask */
00510         FALSE),             /* pcrel_offset */
00511 
00512   /* The upper 16 bits of the GOT offset for the TLS descriptor of the
00513      symbol.  */
00514   HOWTO (R_FRV_GOTTLSDESCHI,       /* type */
00515         0,                  /* rightshift */
00516         2,                  /* size (0 = byte, 1 = short, 2 = long) */
00517         16,                 /* bitsize */
00518         FALSE,                     /* pc_relative */
00519         0,                  /* bitpos */
00520         complain_overflow_dont, /* complain_on_overflow */
00521         bfd_elf_generic_reloc,     /* special_function */
00522         "R_FRV_GOTTLSDESCHI",      /* name */
00523         FALSE,                     /* partial_inplace */
00524         0xffff,             /* src_mask */
00525         0xffff,             /* dst_mask */
00526         FALSE),             /* pcrel_offset */
00527 
00528   /* The lower 16 bits of the GOT offset for the TLS descriptor of the
00529      symbol.  */
00530   HOWTO (R_FRV_GOTTLSDESCLO,       /* type */
00531         0,                  /* rightshift */
00532         2,                  /* size (0 = byte, 1 = short, 2 = long) */
00533         16,                 /* bitsize */
00534         FALSE,                     /* pc_relative */
00535         0,                  /* bitpos */
00536         complain_overflow_dont, /* complain_on_overflow */
00537         bfd_elf_generic_reloc,     /* special_function */
00538         "R_FRV_GOTTLSDESCLO",      /* name */
00539         FALSE,                     /* partial_inplace */
00540         0xffff,             /* src_mask */
00541         0xffff,             /* dst_mask */
00542         FALSE),             /* pcrel_offset */
00543 
00544   /* A 12-bit signed operand with the offset from the module base
00545      address to the thread-local symbol address.  */
00546   HOWTO (R_FRV_TLSMOFF12,    /* type */
00547         0,                  /* rightshift */
00548         2,                  /* size (0 = byte, 1 = short, 2 = long) */
00549         12,                 /* bitsize */
00550         FALSE,                     /* pc_relative */
00551         0,                  /* bitpos */
00552         complain_overflow_signed, /* complain_on_overflow */
00553         bfd_elf_generic_reloc,     /* special_function */
00554         "R_FRV_TLSMOFF12",  /* name */
00555         FALSE,                     /* partial_inplace */
00556         0xfff,                     /* src_mask */
00557         0xfff,                     /* dst_mask */
00558         FALSE),             /* pcrel_offset */
00559 
00560   /* The upper 16 bits of the offset from the module base address to
00561      the thread-local symbol address.  */
00562   HOWTO (R_FRV_TLSMOFFHI,   /* type */
00563         0,                  /* rightshift */
00564         2,                  /* size (0 = byte, 1 = short, 2 = long) */
00565         16,                 /* bitsize */
00566         FALSE,                     /* pc_relative */
00567         0,                  /* bitpos */
00568         complain_overflow_dont, /* complain_on_overflow */
00569         bfd_elf_generic_reloc,     /* special_function */
00570         "R_FRV_TLSMOFFHI",  /* name */
00571         FALSE,                     /* partial_inplace */
00572         0xffff,             /* src_mask */
00573         0xffff,             /* dst_mask */
00574         FALSE),             /* pcrel_offset */
00575 
00576   /* The lower 16 bits of the offset from the module base address to
00577      the thread-local symbol address.  */
00578   HOWTO (R_FRV_TLSMOFFLO,   /* type */
00579         0,                  /* rightshift */
00580         2,                  /* size (0 = byte, 1 = short, 2 = long) */
00581         16,                 /* bitsize */
00582         FALSE,                     /* pc_relative */
00583         0,                  /* bitpos */
00584         complain_overflow_dont, /* complain_on_overflow */
00585         bfd_elf_generic_reloc,     /* special_function */
00586         "R_FRV_TLSMOFFLO",  /* name */
00587         FALSE,                     /* partial_inplace */
00588         0xffff,             /* src_mask */
00589         0xffff,             /* dst_mask */
00590         FALSE),             /* pcrel_offset */
00591 
00592   /* A 12-bit signed operand with the GOT offset for the TLSOFF entry
00593      for a symbol.  */
00594   HOWTO (R_FRV_GOTTLSOFF12, /* type */
00595         0,                  /* rightshift */
00596         2,                  /* size (0 = byte, 1 = short, 2 = long) */
00597         12,                 /* bitsize */
00598         FALSE,                     /* pc_relative */
00599         0,                  /* bitpos */
00600         complain_overflow_signed, /* complain_on_overflow */
00601         bfd_elf_generic_reloc,     /* special_function */
00602         "R_FRV_GOTTLSOFF12",       /* name */
00603         FALSE,                     /* partial_inplace */
00604         0xfff,                     /* src_mask */
00605         0xfff,                     /* dst_mask */
00606         FALSE),             /* pcrel_offset */
00607 
00608   /* The upper 16 bits of the GOT offset for the TLSOFF entry for a
00609      symbol.  */
00610   HOWTO (R_FRV_GOTTLSOFFHI, /* type */
00611         0,                  /* rightshift */
00612         2,                  /* size (0 = byte, 1 = short, 2 = long) */
00613         16,                 /* bitsize */
00614         FALSE,                     /* pc_relative */
00615         0,                  /* bitpos */
00616         complain_overflow_dont, /* complain_on_overflow */
00617         bfd_elf_generic_reloc,     /* special_function */
00618         "R_FRV_GOTTLSOFFHI",       /* name */
00619         FALSE,                     /* partial_inplace */
00620         0xffff,             /* src_mask */
00621         0xffff,             /* dst_mask */
00622         FALSE),             /* pcrel_offset */
00623 
00624   /* The lower 16 bits of the GOT offset for the TLSOFF entry for a
00625      symbol.  */
00626   HOWTO (R_FRV_GOTTLSOFFLO, /* type */
00627         0,                  /* rightshift */
00628         2,                  /* size (0 = byte, 1 = short, 2 = long) */
00629         16,                 /* bitsize */
00630         FALSE,                     /* pc_relative */
00631         0,                  /* bitpos */
00632         complain_overflow_dont, /* complain_on_overflow */
00633         bfd_elf_generic_reloc,     /* special_function */
00634         "R_FRV_GOTTLSOFFLO",       /* name */
00635         FALSE,                     /* partial_inplace */
00636         0xffff,             /* src_mask */
00637         0xffff,             /* dst_mask */
00638         FALSE),             /* pcrel_offset */
00639 
00640   /* The 32-bit offset from the thread pointer (not the module base
00641      address) to a thread-local symbol.  */
00642   HOWTO (R_FRV_TLSOFF,             /* type */
00643         0,                  /* rightshift */
00644         2,                  /* size (0 = byte, 1 = short, 2 = long) */
00645         32,                 /* bitsize */
00646         FALSE,                     /* pc_relative */
00647         0,                  /* bitpos */
00648         complain_overflow_dont, /* complain_on_overflow */
00649         bfd_elf_generic_reloc,     /* special_function */
00650         "R_FRV_TLSOFF",     /* name */
00651         FALSE,                     /* partial_inplace */
00652         0xffffffff,         /* src_mask */
00653         0xffffffff,         /* dst_mask */
00654         FALSE),             /* pcrel_offset */
00655 
00656   /* An annotation for linker relaxation, that denotes the
00657      symbol+addend whose TLS descriptor is referenced by the sum of
00658      the two input registers of an ldd instruction.  */
00659   HOWTO (R_FRV_TLSDESC_RELAX,      /* type */
00660         0,                  /* rightshift */
00661         2,                  /* size (0 = byte, 1 = short, 2 = long) */
00662         0,                  /* bitsize */
00663         FALSE,                     /* pc_relative */
00664         0,                  /* bitpos */
00665         complain_overflow_dont, /* complain_on_overflow */
00666         bfd_elf_generic_reloc,     /* special_function */
00667         "R_FRV_TLSDESC_RELAX",     /* name */
00668         FALSE,                     /* partial_inplace */
00669         0,                  /* src_mask */
00670         0,                  /* dst_mask */
00671         FALSE),             /* pcrel_offset */
00672 
00673   /* An annotation for linker relaxation, that denotes the
00674      symbol+addend whose TLS resolver entry point is given by the sum
00675      of the two register operands of an calll instruction.  */
00676   HOWTO (R_FRV_GETTLSOFF_RELAX,    /* type */
00677         0,                  /* rightshift */
00678         2,                  /* size (0 = byte, 1 = short, 2 = long) */
00679         0,                  /* bitsize */
00680         FALSE,                     /* pc_relative */
00681         0,                  /* bitpos */
00682         complain_overflow_dont, /* complain_on_overflow */
00683         bfd_elf_generic_reloc,     /* special_function */
00684         "R_FRV_GETTLSOFF_RELAX", /* name */
00685         FALSE,                     /* partial_inplace */
00686         0,                  /* src_mask */
00687         0,                  /* dst_mask */
00688         FALSE),             /* pcrel_offset */
00689 
00690   /* An annotation for linker relaxation, that denotes the
00691      symbol+addend whose TLS offset GOT entry is given by the sum of
00692      the two input registers of an ld instruction.  */
00693   HOWTO (R_FRV_TLSOFF_RELAX,       /* type */
00694         0,                  /* rightshift */
00695         2,                  /* size (0 = byte, 1 = short, 2 = long) */
00696         0,                  /* bitsize */
00697         FALSE,                     /* pc_relative */
00698         0,                  /* bitpos */
00699         complain_overflow_bitfield, /* complain_on_overflow */
00700         bfd_elf_generic_reloc,     /* special_function */
00701         "R_FRV_TLSOFF_RELAX",      /* name */
00702         FALSE,                     /* partial_inplace */
00703         0,                  /* src_mask */
00704         0,                  /* dst_mask */
00705         FALSE),             /* pcrel_offset */
00706 
00707   /* A 32-bit offset from the module base address to
00708      the thread-local symbol address.  */
00709   HOWTO (R_FRV_TLSMOFF,            /* type */
00710         0,                  /* rightshift */
00711         2,                  /* size (0 = byte, 1 = short, 2 = long) */
00712         32,                 /* bitsize */
00713         FALSE,                     /* pc_relative */
00714         0,                  /* bitpos */
00715         complain_overflow_dont, /* complain_on_overflow */
00716         bfd_elf_generic_reloc,     /* special_function */
00717         "R_FRV_TLSMOFF",    /* name */
00718         FALSE,                     /* partial_inplace */
00719         0xffffffff,         /* src_mask */
00720         0xffffffff,         /* dst_mask */
00721         FALSE),             /* pcrel_offset */
00722 };
00723 
00724 /* GNU extension to record C++ vtable hierarchy.  */
00725 static reloc_howto_type elf32_frv_vtinherit_howto =
00726   HOWTO (R_FRV_GNU_VTINHERIT,      /* type */
00727         0,                  /* rightshift */
00728         2,                  /* size (0 = byte, 1 = short, 2 = long) */
00729         0,                  /* bitsize */
00730         FALSE,                     /* pc_relative */
00731         0,                  /* bitpos */
00732         complain_overflow_dont, /* complain_on_overflow */
00733         NULL,               /* special_function */
00734         "R_FRV_GNU_VTINHERIT", /* name */
00735         FALSE,                     /* partial_inplace */
00736         0,                  /* src_mask */
00737         0,                  /* dst_mask */
00738         FALSE);             /* pcrel_offset */
00739 
00740   /* GNU extension to record C++ vtable member usage.  */
00741 static reloc_howto_type elf32_frv_vtentry_howto =
00742   HOWTO (R_FRV_GNU_VTENTRY, /* type */
00743         0,                  /* rightshift */
00744         2,                  /* size (0 = byte, 1 = short, 2 = long) */
00745         0,                  /* bitsize */
00746         FALSE,                     /* pc_relative */
00747         0,                  /* bitpos */
00748         complain_overflow_dont, /* complain_on_overflow */
00749         _bfd_elf_rel_vtable_reloc_fn, /* special_function */
00750         "R_FRV_GNU_VTENTRY",       /* name */
00751         FALSE,                     /* partial_inplace */
00752         0,                  /* src_mask */
00753         0,                  /* dst_mask */
00754         FALSE);             /* pcrel_offset */
00755 
00756 /* The following 3 relocations are REL.  The only difference to the
00757    entries in the table above are that partial_inplace is TRUE.  */
00758 static reloc_howto_type elf32_frv_rel_32_howto =
00759   HOWTO (R_FRV_32,          /* type */
00760         0,                  /* rightshift */
00761         2,                  /* size (0 = byte, 1 = short, 2 = long) */
00762         32,                 /* bitsize */
00763         FALSE,                     /* pc_relative */
00764         0,                  /* bitpos */
00765         complain_overflow_bitfield, /* complain_on_overflow */
00766         bfd_elf_generic_reloc,     /* special_function */
00767         "R_FRV_32",         /* name */
00768         TRUE,               /* partial_inplace */
00769         0xffffffff,         /* src_mask */
00770         0xffffffff,         /* dst_mask */
00771         FALSE);             /* pcrel_offset */
00772 
00773 static reloc_howto_type elf32_frv_rel_funcdesc_howto =
00774   HOWTO (R_FRV_FUNCDESC,    /* type */
00775         0,                  /* rightshift */
00776         2,                  /* size (0 = byte, 1 = short, 2 = long) */
00777         32,                 /* bitsize */
00778         FALSE,                     /* pc_relative */
00779         0,                  /* bitpos */
00780         complain_overflow_bitfield, /* complain_on_overflow */
00781         bfd_elf_generic_reloc,     /* special_function */
00782         "R_FRV_FUNCDESC",   /* name */
00783         TRUE,               /* partial_inplace */
00784         0xffffffff,         /* src_mask */
00785         0xffffffff,         /* dst_mask */
00786         FALSE);             /* pcrel_offset */
00787 
00788 static reloc_howto_type elf32_frv_rel_funcdesc_value_howto =
00789   HOWTO (R_FRV_FUNCDESC_VALUE,     /* type */
00790         0,                  /* rightshift */
00791         2,                  /* size (0 = byte, 1 = short, 2 = long) */
00792         64,                 /* bitsize */
00793         FALSE,                     /* pc_relative */
00794         0,                  /* bitpos */
00795         complain_overflow_bitfield, /* complain_on_overflow */
00796         bfd_elf_generic_reloc,     /* special_function */
00797         "R_FRV_FUNCDESC_VALUE", /* name */
00798         TRUE,               /* partial_inplace */
00799         0xffffffff,         /* src_mask */
00800         0xffffffff,         /* dst_mask */
00801         FALSE);             /* pcrel_offset */
00802 
00803 static reloc_howto_type elf32_frv_rel_tlsdesc_value_howto =
00804   /* A 64-bit TLS descriptor for a symbol.  The first word resolves to
00805      an entry point, and the second resolves to a special argument.
00806      If the symbol turns out to be in static TLS, the entry point is a
00807      return instruction, and the special argument is the TLS offset
00808      for the symbol.  If it's in dynamic TLS, the entry point is a TLS
00809      offset resolver, and the special argument is a pointer to a data
00810      structure allocated by the dynamic loader, containing the GOT
00811      address for the offset resolver, the module id, the offset within
00812      the module, and anything else the TLS offset resolver might need
00813      to determine the TLS offset for the symbol in the running
00814      thread.  */
00815   HOWTO (R_FRV_TLSDESC_VALUE,      /* type */
00816         0,                  /* rightshift */
00817         2,                  /* size (0 = byte, 1 = short, 2 = long) */
00818         64,                 /* bitsize */
00819         FALSE,                     /* pc_relative */
00820         0,                  /* bitpos */
00821         complain_overflow_bitfield, /* complain_on_overflow */
00822         bfd_elf_generic_reloc,     /* special_function */
00823         "R_FRV_TLSDESC_VALUE", /* name */
00824         TRUE,               /* partial_inplace */
00825         0xffffffff,         /* src_mask */
00826         0xffffffff,         /* dst_mask */
00827         FALSE);             /* pcrel_offset */
00828 
00829 static reloc_howto_type elf32_frv_rel_tlsoff_howto =
00830   /* The 32-bit offset from the thread pointer (not the module base
00831      address) to a thread-local symbol.  */
00832   HOWTO (R_FRV_TLSOFF,             /* type */
00833         0,                  /* rightshift */
00834         2,                  /* size (0 = byte, 1 = short, 2 = long) */
00835         32,                 /* bitsize */
00836         FALSE,                     /* pc_relative */
00837         0,                  /* bitpos */
00838         complain_overflow_bitfield, /* complain_on_overflow */
00839         bfd_elf_generic_reloc,     /* special_function */
00840         "R_FRV_TLSOFF",     /* name */
00841         TRUE,               /* partial_inplace */
00842         0xffffffff,         /* src_mask */
00843         0xffffffff,         /* dst_mask */
00844         FALSE);             /* pcrel_offset */
00845 
00846 
00847 
00848 extern const bfd_target bfd_elf32_frvfdpic_vec;
00849 #define IS_FDPIC(bfd) ((bfd)->xvec == &bfd_elf32_frvfdpic_vec)
00850 
00851 /* An extension of the elf hash table data structure, containing some
00852    additional FRV-specific data.  */
00853 struct frvfdpic_elf_link_hash_table
00854 {
00855   struct elf_link_hash_table elf;
00856 
00857   /* A pointer to the .got section.  */
00858   asection *sgot;
00859   /* A pointer to the .rel.got section.  */
00860   asection *sgotrel;
00861   /* A pointer to the .rofixup section.  */
00862   asection *sgotfixup;
00863   /* A pointer to the .plt section.  */
00864   asection *splt;
00865   /* A pointer to the .rel.plt section.  */
00866   asection *spltrel;
00867   /* GOT base offset.  */
00868   bfd_vma got0;
00869   /* Location of the first non-lazy PLT entry, i.e., the number of
00870      bytes taken by lazy PLT entries.  If locally-bound TLS
00871      descriptors require a ret instruction, it will be placed at this
00872      offset.  */
00873   bfd_vma plt0;
00874   /* A hash table holding information about which symbols were
00875      referenced with which PIC-related relocations.  */
00876   struct htab *relocs_info;
00877   /* Summary reloc information collected by
00878      _frvfdpic_count_got_plt_entries.  */
00879   struct _frvfdpic_dynamic_got_info *g;
00880 };
00881 
00882 /* Get the FRV ELF linker hash table from a link_info structure.  */
00883 
00884 #define frvfdpic_hash_table(info) \
00885   ((struct frvfdpic_elf_link_hash_table *) ((info)->hash))
00886 
00887 #define frvfdpic_got_section(info) \
00888   (frvfdpic_hash_table (info)->sgot)
00889 #define frvfdpic_gotrel_section(info) \
00890   (frvfdpic_hash_table (info)->sgotrel)
00891 #define frvfdpic_gotfixup_section(info) \
00892   (frvfdpic_hash_table (info)->sgotfixup)
00893 #define frvfdpic_plt_section(info) \
00894   (frvfdpic_hash_table (info)->splt)
00895 #define frvfdpic_pltrel_section(info) \
00896   (frvfdpic_hash_table (info)->spltrel)
00897 #define frvfdpic_relocs_info(info) \
00898   (frvfdpic_hash_table (info)->relocs_info)
00899 #define frvfdpic_got_initial_offset(info) \
00900   (frvfdpic_hash_table (info)->got0)
00901 #define frvfdpic_plt_initial_offset(info) \
00902   (frvfdpic_hash_table (info)->plt0)
00903 #define frvfdpic_dynamic_got_plt_info(info) \
00904   (frvfdpic_hash_table (info)->g)
00905 
00906 /* Currently it's the same, but if some day we have a reason to change
00907    it, we'd better be using a different macro.
00908 
00909    FIXME: if there's any TLS PLT entry that uses local-exec or
00910    initial-exec models, we could use the ret at the end of any of them
00911    instead of adding one more.  */
00912 #define frvfdpic_plt_tls_ret_offset(info) \
00913   (frvfdpic_plt_initial_offset (info))
00914 
00915 /* The name of the dynamic interpreter.  This is put in the .interp
00916    section.  */
00917 
00918 #define ELF_DYNAMIC_INTERPRETER "/lib/ld.so.1"
00919 
00920 #define DEFAULT_STACK_SIZE 0x20000
00921 
00922 /* This structure is used to collect the number of entries present in
00923    each addressable range of the got.  */
00924 struct _frvfdpic_dynamic_got_info
00925 {
00926   /* Several bits of information about the current link.  */
00927   struct bfd_link_info *info;
00928   /* Total GOT size needed for GOT entries within the 12-, 16- or 32-bit
00929      ranges.  */
00930   bfd_vma got12, gotlos, gothilo;
00931   /* Total GOT size needed for function descriptor entries within the 12-,
00932      16- or 32-bit ranges.  */
00933   bfd_vma fd12, fdlos, fdhilo;
00934   /* Total GOT size needed by function descriptor entries referenced
00935      in PLT entries, that would be profitable to place in offsets
00936      close to the PIC register.  */
00937   bfd_vma fdplt;
00938   /* Total PLT size needed by lazy PLT entries.  */
00939   bfd_vma lzplt;
00940   /* Total GOT size needed for TLS descriptor entries within the 12-,
00941      16- or 32-bit ranges.  */
00942   bfd_vma tlsd12, tlsdlos, tlsdhilo;
00943   /* Total GOT size needed by TLS descriptors referenced in PLT
00944      entries, that would be profitable to place in offers close to the
00945      PIC register.  */
00946   bfd_vma tlsdplt;
00947   /* Total PLT size needed by TLS lazy PLT entries.  */
00948   bfd_vma tlslzplt;
00949   /* Number of relocations carried over from input object files.  */
00950   unsigned long relocs;
00951   /* Number of fixups introduced by relocations in input object files.  */
00952   unsigned long fixups;
00953   /* The number of fixups that reference the ret instruction added to
00954      the PLT for locally-resolved TLS descriptors.  */
00955   unsigned long tls_ret_refs;
00956 };
00957 
00958 /* This structure is used to assign offsets to got entries, function
00959    descriptors, plt entries and lazy plt entries.  */
00960 
00961 struct _frvfdpic_dynamic_got_plt_info
00962 {
00963   /* Summary information collected with _frvfdpic_count_got_plt_entries.  */
00964   struct _frvfdpic_dynamic_got_info g;
00965 
00966   /* For each addressable range, we record a MAX (positive) and MIN
00967      (negative) value.  CUR is used to assign got entries, and it's
00968      incremented from an initial positive value to MAX, then from MIN
00969      to FDCUR (unless FDCUR wraps around first).  FDCUR is used to
00970      assign function descriptors, and it's decreased from an initial
00971      non-positive value to MIN, then from MAX down to CUR (unless CUR
00972      wraps around first).  All of MIN, MAX, CUR and FDCUR always point
00973      to even words.  ODD, if non-zero, indicates an odd word to be
00974      used for the next got entry, otherwise CUR is used and
00975      incremented by a pair of words, wrapping around when it reaches
00976      MAX.  FDCUR is decremented (and wrapped) before the next function
00977      descriptor is chosen.  FDPLT indicates the number of remaining
00978      slots that can be used for function descriptors used only by PLT
00979      entries.
00980 
00981      TMAX, TMIN and TCUR are used to assign TLS descriptors.  TCUR
00982      starts as MAX, and grows up to TMAX, then wraps around to TMIN
00983      and grows up to MIN.  TLSDPLT indicates the number of remaining
00984      slots that can be used for TLS descriptors used only by TLS PLT
00985      entries.  */
00986   struct _frvfdpic_dynamic_got_alloc_data
00987   {
00988     bfd_signed_vma max, cur, odd, fdcur, min;
00989     bfd_signed_vma tmax, tcur, tmin;
00990     bfd_vma fdplt, tlsdplt;
00991   } got12, gotlos, gothilo;
00992 };
00993 
00994 /* Create an FRV ELF linker hash table.  */
00995 
00996 static struct bfd_link_hash_table *
00997 frvfdpic_elf_link_hash_table_create (bfd *abfd)
00998 {
00999   struct frvfdpic_elf_link_hash_table *ret;
01000   bfd_size_type amt = sizeof (struct frvfdpic_elf_link_hash_table);
01001 
01002   ret = bfd_zalloc (abfd, amt);
01003   if (ret == NULL)
01004     return NULL;
01005 
01006   if (!_bfd_elf_link_hash_table_init (&ret->elf, abfd,
01007                                   _bfd_elf_link_hash_newfunc,
01008                                   sizeof (struct elf_link_hash_entry)))
01009     {
01010       free (ret);
01011       return NULL;
01012     }
01013 
01014   return &ret->elf.root;
01015 }
01016 
01017 /* Decide whether a reference to a symbol can be resolved locally or
01018    not.  If the symbol is protected, we want the local address, but
01019    its function descriptor must be assigned by the dynamic linker.  */
01020 #define FRVFDPIC_SYM_LOCAL(INFO, H) \
01021   (_bfd_elf_symbol_refs_local_p ((H), (INFO), 1) \
01022    || ! elf_hash_table (INFO)->dynamic_sections_created)
01023 #define FRVFDPIC_FUNCDESC_LOCAL(INFO, H) \
01024   ((H)->dynindx == -1 || ! elf_hash_table (INFO)->dynamic_sections_created)
01025 
01026 /* This structure collects information on what kind of GOT, PLT or
01027    function descriptors are required by relocations that reference a
01028    certain symbol.  */
01029 struct frvfdpic_relocs_info
01030 {
01031   /* The index of the symbol, as stored in the relocation r_info, if
01032      we have a local symbol; -1 otherwise.  */
01033   long symndx;
01034   union
01035   {
01036     /* The input bfd in which the symbol is defined, if it's a local
01037        symbol.  */
01038     bfd *abfd;
01039     /* If symndx == -1, the hash table entry corresponding to a global
01040        symbol (even if it turns out to bind locally, in which case it
01041        should ideally be replaced with section's symndx + addend).  */
01042     struct elf_link_hash_entry *h;
01043   } d;
01044   /* The addend of the relocation that references the symbol.  */
01045   bfd_vma addend;
01046 
01047   /* The fields above are used to identify an entry.  The fields below
01048      contain information on how an entry is used and, later on, which
01049      locations it was assigned.  */
01050   /* The following 3 fields record whether the symbol+addend above was
01051      ever referenced with a GOT relocation.  The 12 suffix indicates a
01052      GOT12 relocation; los is used for GOTLO relocations that are not
01053      matched by a GOTHI relocation; hilo is used for GOTLO/GOTHI
01054      pairs.  */
01055   unsigned got12:1;
01056   unsigned gotlos:1;
01057   unsigned gothilo:1;
01058   /* Whether a FUNCDESC relocation references symbol+addend.  */
01059   unsigned fd:1;
01060   /* Whether a FUNCDESC_GOT relocation references symbol+addend.  */
01061   unsigned fdgot12:1;
01062   unsigned fdgotlos:1;
01063   unsigned fdgothilo:1;
01064   /* Whether a FUNCDESC_GOTOFF relocation references symbol+addend.  */
01065   unsigned fdgoff12:1;
01066   unsigned fdgofflos:1;
01067   unsigned fdgoffhilo:1;
01068   /* Whether a GETTLSOFF relocation references symbol+addend.  */
01069   unsigned tlsplt:1;
01070   /* FIXME: we should probably add tlspltdesc, tlspltoff and
01071      tlspltimm, to tell what kind of TLS PLT entry we're generating.
01072      We might instead just pre-compute flags telling whether the
01073      object is suitable for local exec, initial exec or general
01074      dynamic addressing, and use that all over the place.  We could
01075      also try to do a better job of merging TLSOFF and TLSDESC entries
01076      in main executables, but perhaps we can get rid of TLSDESC
01077      entirely in them instead.  */
01078   /* Whether a GOTTLSDESC relocation references symbol+addend.  */
01079   unsigned tlsdesc12:1;
01080   unsigned tlsdesclos:1;
01081   unsigned tlsdeschilo:1;
01082   /* Whether a GOTTLSOFF relocation references symbol+addend.  */
01083   unsigned tlsoff12:1;
01084   unsigned tlsofflos:1;
01085   unsigned tlsoffhilo:1;
01086   /* Whether symbol+addend is referenced with GOTOFF12, GOTOFFLO or
01087      GOTOFFHI relocations.  The addend doesn't really matter, since we
01088      envision that this will only be used to check whether the symbol
01089      is mapped to the same segment as the got.  */
01090   unsigned gotoff:1;
01091   /* Whether symbol+addend is referenced by a LABEL24 relocation.  */
01092   unsigned call:1;
01093   /* Whether symbol+addend is referenced by a 32 or FUNCDESC_VALUE
01094      relocation.  */
01095   unsigned sym:1;
01096   /* Whether we need a PLT entry for a symbol.  Should be implied by
01097      something like:
01098      (call && symndx == -1 && ! FRVFDPIC_SYM_LOCAL (info, d.h))  */
01099   unsigned plt:1;
01100   /* Whether a function descriptor should be created in this link unit
01101      for symbol+addend.  Should be implied by something like:
01102      (plt || fdgotoff12 || fdgotofflos || fdgotofflohi
01103       || ((fd || fdgot12 || fdgotlos || fdgothilo)
01104           && (symndx != -1 || FRVFDPIC_FUNCDESC_LOCAL (info, d.h))))  */
01105   unsigned privfd:1;
01106   /* Whether a lazy PLT entry is needed for this symbol+addend.
01107      Should be implied by something like:
01108      (privfd && symndx == -1 && ! FRVFDPIC_SYM_LOCAL (info, d.h)
01109       && ! (info->flags & DF_BIND_NOW))  */
01110   unsigned lazyplt:1;
01111   /* Whether we've already emitted GOT relocations and PLT entries as
01112      needed for this symbol.  */
01113   unsigned done:1;
01114 
01115   /* The number of R_FRV_32, R_FRV_FUNCDESC, R_FRV_FUNCDESC_VALUE and
01116      R_FRV_TLSDESC_VALUE, R_FRV_TLSOFF relocations referencing
01117      symbol+addend.  */
01118   unsigned relocs32, relocsfd, relocsfdv, relocstlsd, relocstlsoff;
01119 
01120   /* The number of .rofixups entries and dynamic relocations allocated
01121      for this symbol, minus any that might have already been used.  */
01122   unsigned fixups, dynrelocs;
01123 
01124   /* The offsets of the GOT entries assigned to symbol+addend, to the
01125      function descriptor's address, and to a function descriptor,
01126      respectively.  Should be zero if unassigned.  The offsets are
01127      counted from the value that will be assigned to the PIC register,
01128      not from the beginning of the .got section.  */
01129   bfd_signed_vma got_entry, fdgot_entry, fd_entry;
01130   /* The offsets of the PLT entries assigned to symbol+addend,
01131      non-lazy and lazy, respectively.  If unassigned, should be
01132      (bfd_vma)-1.  */
01133   bfd_vma plt_entry, lzplt_entry;
01134   /* The offsets of the GOT entries for TLS offset and TLS descriptor.  */
01135   bfd_signed_vma tlsoff_entry, tlsdesc_entry;
01136   /* The offset of the TLS offset PLT entry.  */
01137   bfd_vma tlsplt_entry;
01138 };
01139 
01140 /* Compute a hash with the key fields of an frvfdpic_relocs_info entry.  */
01141 static hashval_t
01142 frvfdpic_relocs_info_hash (const void *entry_)
01143 {
01144   const struct frvfdpic_relocs_info *entry = entry_;
01145 
01146   return (entry->symndx == -1
01147          ? (long) entry->d.h->root.root.hash
01148          : entry->symndx + (long) entry->d.abfd->id * 257) + entry->addend;
01149 }
01150 
01151 /* Test whether the key fields of two frvfdpic_relocs_info entries are
01152    identical.  */
01153 static int
01154 frvfdpic_relocs_info_eq (const void *entry1, const void *entry2)
01155 {
01156   const struct frvfdpic_relocs_info *e1 = entry1;
01157   const struct frvfdpic_relocs_info *e2 = entry2;
01158 
01159   return e1->symndx == e2->symndx && e1->addend == e2->addend
01160     && (e1->symndx == -1 ? e1->d.h == e2->d.h : e1->d.abfd == e2->d.abfd);
01161 }
01162 
01163 /* Find or create an entry in a hash table HT that matches the key
01164    fields of the given ENTRY.  If it's not found, memory for a new
01165    entry is allocated in ABFD's obstack.  */
01166 static struct frvfdpic_relocs_info *
01167 frvfdpic_relocs_info_find (struct htab *ht,
01168                         bfd *abfd,
01169                         const struct frvfdpic_relocs_info *entry,
01170                         enum insert_option insert)
01171 {
01172   struct frvfdpic_relocs_info **loc =
01173     (struct frvfdpic_relocs_info **) htab_find_slot (ht, entry, insert);
01174 
01175   if (! loc)
01176     return NULL;
01177 
01178   if (*loc)
01179     return *loc;
01180 
01181   *loc = bfd_zalloc (abfd, sizeof (**loc));
01182 
01183   if (! *loc)
01184     return *loc;
01185 
01186   (*loc)->symndx = entry->symndx;
01187   (*loc)->d = entry->d;
01188   (*loc)->addend = entry->addend;
01189   (*loc)->plt_entry = (bfd_vma)-1;
01190   (*loc)->lzplt_entry = (bfd_vma)-1;
01191   (*loc)->tlsplt_entry = (bfd_vma)-1;
01192 
01193   return *loc;
01194 }
01195 
01196 /* Obtain the address of the entry in HT associated with H's symbol +
01197    addend, creating a new entry if none existed.  ABFD is only used
01198    for memory allocation purposes.  */
01199 inline static struct frvfdpic_relocs_info *
01200 frvfdpic_relocs_info_for_global (struct htab *ht,
01201                              bfd *abfd,
01202                              struct elf_link_hash_entry *h,
01203                              bfd_vma addend,
01204                              enum insert_option insert)
01205 {
01206   struct frvfdpic_relocs_info entry;
01207 
01208   entry.symndx = -1;
01209   entry.d.h = h;
01210   entry.addend = addend;
01211 
01212   return frvfdpic_relocs_info_find (ht, abfd, &entry, insert);
01213 }
01214 
01215 /* Obtain the address of the entry in HT associated with the SYMNDXth
01216    local symbol of the input bfd ABFD, plus the addend, creating a new
01217    entry if none existed.  */
01218 inline static struct frvfdpic_relocs_info *
01219 frvfdpic_relocs_info_for_local (struct htab *ht,
01220                             bfd *abfd,
01221                             long symndx,
01222                             bfd_vma addend,
01223                             enum insert_option insert)
01224 {
01225   struct frvfdpic_relocs_info entry;
01226 
01227   entry.symndx = symndx;
01228   entry.d.abfd = abfd;
01229   entry.addend = addend;
01230 
01231   return frvfdpic_relocs_info_find (ht, abfd, &entry, insert);
01232 }
01233 
01234 /* Merge fields set by check_relocs() of two entries that end up being
01235    mapped to the same (presumably global) symbol.  */
01236 
01237 inline static void
01238 frvfdpic_pic_merge_early_relocs_info (struct frvfdpic_relocs_info *e2,
01239                                   struct frvfdpic_relocs_info const *e1)
01240 {
01241   e2->got12 |= e1->got12;
01242   e2->gotlos |= e1->gotlos;
01243   e2->gothilo |= e1->gothilo;
01244   e2->fd |= e1->fd;
01245   e2->fdgot12 |= e1->fdgot12;
01246   e2->fdgotlos |= e1->fdgotlos;
01247   e2->fdgothilo |= e1->fdgothilo;
01248   e2->fdgoff12 |= e1->fdgoff12;
01249   e2->fdgofflos |= e1->fdgofflos;
01250   e2->fdgoffhilo |= e1->fdgoffhilo;
01251   e2->tlsplt |= e1->tlsplt;
01252   e2->tlsdesc12 |= e1->tlsdesc12;
01253   e2->tlsdesclos |= e1->tlsdesclos;
01254   e2->tlsdeschilo |= e1->tlsdeschilo;
01255   e2->tlsoff12 |= e1->tlsoff12;
01256   e2->tlsofflos |= e1->tlsofflos;
01257   e2->tlsoffhilo |= e1->tlsoffhilo;
01258   e2->gotoff |= e1->gotoff;
01259   e2->call |= e1->call;
01260   e2->sym |= e1->sym;
01261 }
01262 
01263 /* Every block of 65535 lazy PLT entries shares a single call to the
01264    resolver, inserted in the 32768th lazy PLT entry (i.e., entry #
01265    32767, counting from 0).  All other lazy PLT entries branch to it
01266    in a single instruction.  */
01267 
01268 #define FRVFDPIC_LZPLT_BLOCK_SIZE ((bfd_vma) 8 * 65535 + 4)
01269 #define FRVFDPIC_LZPLT_RESOLV_LOC (8 * 32767)
01270 
01271 /* Add a dynamic relocation to the SRELOC section.  */
01272 
01273 inline static bfd_vma
01274 _frvfdpic_add_dyn_reloc (bfd *output_bfd, asection *sreloc, bfd_vma offset,
01275                       int reloc_type, long dynindx, bfd_vma addend,
01276                       struct frvfdpic_relocs_info *entry)
01277 {
01278   Elf_Internal_Rela outrel;
01279   bfd_vma reloc_offset;
01280 
01281   outrel.r_offset = offset;
01282   outrel.r_info = ELF32_R_INFO (dynindx, reloc_type);
01283   outrel.r_addend = addend;
01284 
01285   reloc_offset = sreloc->reloc_count * sizeof (Elf32_External_Rel);
01286   BFD_ASSERT (reloc_offset < sreloc->size);
01287   bfd_elf32_swap_reloc_out (output_bfd, &outrel,
01288                          sreloc->contents + reloc_offset);
01289   sreloc->reloc_count++;
01290 
01291   /* If the entry's index is zero, this relocation was probably to a
01292      linkonce section that got discarded.  We reserved a dynamic
01293      relocation, but it was for another entry than the one we got at
01294      the time of emitting the relocation.  Unfortunately there's no
01295      simple way for us to catch this situation, since the relocation
01296      is cleared right before calling relocate_section, at which point
01297      we no longer know what the relocation used to point to.  */
01298   if (entry->symndx)
01299     {
01300       BFD_ASSERT (entry->dynrelocs > 0);
01301       entry->dynrelocs--;
01302     }
01303 
01304   return reloc_offset;
01305 }
01306 
01307 /* Add a fixup to the ROFIXUP section.  */
01308 
01309 static bfd_vma
01310 _frvfdpic_add_rofixup (bfd *output_bfd, asection *rofixup, bfd_vma offset,
01311                      struct frvfdpic_relocs_info *entry)
01312 {
01313   bfd_vma fixup_offset;
01314 
01315   if (rofixup->flags & SEC_EXCLUDE)
01316     return -1;
01317 
01318   fixup_offset = rofixup->reloc_count * 4;
01319   if (rofixup->contents)
01320     {
01321       BFD_ASSERT (fixup_offset < rofixup->size);
01322       bfd_put_32 (output_bfd, offset, rofixup->contents + fixup_offset);
01323     }
01324   rofixup->reloc_count++;
01325 
01326   if (entry && entry->symndx)
01327     {
01328       /* See discussion about symndx == 0 in _frvfdpic_add_dyn_reloc
01329         above.  */
01330       BFD_ASSERT (entry->fixups > 0);
01331       entry->fixups--;
01332     }
01333 
01334   return fixup_offset;
01335 }
01336 
01337 /* Find the segment number in which OSEC, and output section, is
01338    located.  */
01339 
01340 static unsigned
01341 _frvfdpic_osec_to_segment (bfd *output_bfd, asection *osec)
01342 {
01343   struct elf_segment_map *m;
01344   Elf_Internal_Phdr *p;
01345 
01346   /* Find the segment that contains the output_section.  */
01347   for (m = elf_tdata (output_bfd)->segment_map,
01348         p = elf_tdata (output_bfd)->phdr;
01349        m != NULL;
01350        m = m->next, p++)
01351     {
01352       int i;
01353 
01354       for (i = m->count - 1; i >= 0; i--)
01355        if (m->sections[i] == osec)
01356          break;
01357 
01358       if (i >= 0)
01359        break;
01360     }
01361 
01362   return p - elf_tdata (output_bfd)->phdr;
01363 }
01364 
01365 inline static bfd_boolean
01366 _frvfdpic_osec_readonly_p (bfd *output_bfd, asection *osec)
01367 {
01368   unsigned seg = _frvfdpic_osec_to_segment (output_bfd, osec);
01369 
01370   return ! (elf_tdata (output_bfd)->phdr[seg].p_flags & PF_W);
01371 }
01372 
01373 #define FRVFDPIC_TLS_BIAS (2048 - 16)
01374 
01375 /* Return the base VMA address which should be subtracted from real addresses
01376    when resolving TLSMOFF relocation.
01377    This is PT_TLS segment p_vaddr, plus the 2048-16 bias.  */
01378 
01379 static bfd_vma
01380 tls_biased_base (struct bfd_link_info *info)
01381 {
01382   /* If tls_sec is NULL, we should have signalled an error already.  */
01383   if (elf_hash_table (info)->tls_sec == NULL)
01384     return FRVFDPIC_TLS_BIAS;
01385   return elf_hash_table (info)->tls_sec->vma + FRVFDPIC_TLS_BIAS;
01386 }
01387 
01388 /* Generate relocations for GOT entries, function descriptors, and
01389    code for PLT and lazy PLT entries.  */
01390 
01391 inline static bfd_boolean
01392 _frvfdpic_emit_got_relocs_plt_entries (struct frvfdpic_relocs_info *entry,
01393                                    bfd *output_bfd,
01394                                    struct bfd_link_info *info,
01395                                    asection *sec,
01396                                    Elf_Internal_Sym *sym,
01397                                    bfd_vma addend)
01398 
01399 {
01400   bfd_vma fd_lazy_rel_offset = (bfd_vma)-1;
01401   int dynindx = -1;
01402 
01403   if (entry->done)
01404     return TRUE;
01405   entry->done = 1;
01406 
01407   if (entry->got_entry || entry->fdgot_entry || entry->fd_entry
01408       || entry->tlsoff_entry || entry->tlsdesc_entry)
01409     {
01410       /* If the symbol is dynamic, consider it for dynamic
01411         relocations, otherwise decay to section + offset.  */
01412       if (entry->symndx == -1 && entry->d.h->dynindx != -1)
01413        dynindx = entry->d.h->dynindx;
01414       else
01415        {
01416          if (sec->output_section
01417              && ! bfd_is_abs_section (sec->output_section)
01418              && ! bfd_is_und_section (sec->output_section))
01419            dynindx = elf_section_data (sec->output_section)->dynindx;
01420          else
01421            dynindx = 0;
01422        }
01423     }
01424 
01425   /* Generate relocation for GOT entry pointing to the symbol.  */
01426   if (entry->got_entry)
01427     {
01428       int idx = dynindx;
01429       bfd_vma ad = addend;
01430 
01431       /* If the symbol is dynamic but binds locally, use
01432         section+offset.  */
01433       if (sec && (entry->symndx != -1
01434                 || FRVFDPIC_SYM_LOCAL (info, entry->d.h)))
01435        {
01436          if (entry->symndx == -1)
01437            ad += entry->d.h->root.u.def.value;
01438          else
01439            ad += sym->st_value;
01440          ad += sec->output_offset;
01441          if (sec->output_section && elf_section_data (sec->output_section))
01442            idx = elf_section_data (sec->output_section)->dynindx;
01443          else
01444            idx = 0;
01445        }
01446 
01447       /* If we're linking an executable at a fixed address, we can
01448         omit the dynamic relocation as long as the symbol is local to
01449         this module.  */
01450       if (info->executable && !info->pie
01451          && (entry->symndx != -1
01452              || FRVFDPIC_SYM_LOCAL (info, entry->d.h)))
01453        {
01454          if (sec)
01455            ad += sec->output_section->vma;
01456          if (entry->symndx != -1
01457              || entry->d.h->root.type != bfd_link_hash_undefweak)
01458            _frvfdpic_add_rofixup (output_bfd,
01459                                frvfdpic_gotfixup_section (info),
01460                                frvfdpic_got_section (info)->output_section
01461                                ->vma
01462                                + frvfdpic_got_section (info)->output_offset
01463                                + frvfdpic_got_initial_offset (info)
01464                                + entry->got_entry, entry);
01465        }
01466       else
01467        _frvfdpic_add_dyn_reloc (output_bfd, frvfdpic_gotrel_section (info),
01468                              _bfd_elf_section_offset
01469                              (output_bfd, info,
01470                               frvfdpic_got_section (info),
01471                               frvfdpic_got_initial_offset (info)
01472                               + entry->got_entry)
01473                              + frvfdpic_got_section (info)
01474                              ->output_section->vma
01475                              + frvfdpic_got_section (info)->output_offset,
01476                              R_FRV_32, idx, ad, entry);
01477 
01478       bfd_put_32 (output_bfd, ad,
01479                 frvfdpic_got_section (info)->contents
01480                 + frvfdpic_got_initial_offset (info)
01481                 + entry->got_entry);
01482     }
01483 
01484   /* Generate relocation for GOT entry pointing to a canonical
01485      function descriptor.  */
01486   if (entry->fdgot_entry)
01487     {
01488       int reloc, idx;
01489       bfd_vma ad = 0;
01490 
01491       if (! (entry->symndx == -1
01492             && entry->d.h->root.type == bfd_link_hash_undefweak
01493             && FRVFDPIC_SYM_LOCAL (info, entry->d.h)))
01494        {
01495          /* If the symbol is dynamic and there may be dynamic symbol
01496             resolution because we are, or are linked with, a shared
01497             library, emit a FUNCDESC relocation such that the dynamic
01498             linker will allocate the function descriptor.  If the
01499             symbol needs a non-local function descriptor but binds
01500             locally (e.g., its visibility is protected, emit a
01501             dynamic relocation decayed to section+offset.  */
01502          if (entry->symndx == -1
01503              && ! FRVFDPIC_FUNCDESC_LOCAL (info, entry->d.h)
01504              && FRVFDPIC_SYM_LOCAL (info, entry->d.h)
01505              && !(info->executable && !info->pie))
01506            {
01507              reloc = R_FRV_FUNCDESC;
01508              idx = elf_section_data (entry->d.h->root.u.def.section
01509                                   ->output_section)->dynindx;
01510              ad = entry->d.h->root.u.def.section->output_offset
01511               + entry->d.h->root.u.def.value;
01512            }
01513          else if (entry->symndx == -1
01514                  && ! FRVFDPIC_FUNCDESC_LOCAL (info, entry->d.h))
01515            {
01516              reloc = R_FRV_FUNCDESC;
01517              idx = dynindx;
01518              ad = addend;
01519              if (ad)
01520               {
01521                 (*info->callbacks->reloc_dangerous)
01522                   (info, _("relocation requires zero addend"),
01523                    elf_hash_table (info)->dynobj,
01524                    frvfdpic_got_section (info),
01525                    entry->fdgot_entry);
01526                 return FALSE;
01527               }
01528            }
01529          else
01530            {
01531              /* Otherwise, we know we have a private function descriptor,
01532                so reference it directly.  */
01533              if (elf_hash_table (info)->dynamic_sections_created)
01534               BFD_ASSERT (entry->privfd);
01535              reloc = R_FRV_32;
01536              idx = elf_section_data (frvfdpic_got_section (info)
01537                                   ->output_section)->dynindx;
01538              ad = frvfdpic_got_section (info)->output_offset
01539               + frvfdpic_got_initial_offset (info) + entry->fd_entry;
01540            }
01541 
01542          /* If there is room for dynamic symbol resolution, emit the
01543             dynamic relocation.  However, if we're linking an
01544             executable at a fixed location, we won't have emitted a
01545             dynamic symbol entry for the got section, so idx will be
01546             zero, which means we can and should compute the address
01547             of the private descriptor ourselves.  */
01548          if (info->executable && !info->pie
01549              && (entry->symndx != -1
01550                 || FRVFDPIC_FUNCDESC_LOCAL (info, entry->d.h)))
01551            {
01552              ad += frvfdpic_got_section (info)->output_section->vma;
01553              _frvfdpic_add_rofixup (output_bfd,
01554                                  frvfdpic_gotfixup_section (info),
01555                                  frvfdpic_got_section (info)
01556                                  ->output_section->vma
01557                                  + frvfdpic_got_section (info)
01558                                  ->output_offset
01559                                  + frvfdpic_got_initial_offset (info)
01560                                  + entry->fdgot_entry, entry);
01561            }
01562          else
01563            _frvfdpic_add_dyn_reloc (output_bfd,
01564                                  frvfdpic_gotrel_section (info),
01565                                  _bfd_elf_section_offset
01566                                  (output_bfd, info,
01567                                   frvfdpic_got_section (info),
01568                                   frvfdpic_got_initial_offset (info)
01569                                   + entry->fdgot_entry)
01570                                  + frvfdpic_got_section (info)
01571                                  ->output_section->vma
01572                                  + frvfdpic_got_section (info)
01573                                  ->output_offset,
01574                                  reloc, idx, ad, entry);
01575        }
01576 
01577       bfd_put_32 (output_bfd, ad,
01578                 frvfdpic_got_section (info)->contents
01579                 + frvfdpic_got_initial_offset (info)
01580                 + entry->fdgot_entry);
01581     }
01582 
01583   /* Generate relocation to fill in a private function descriptor in
01584      the GOT.  */
01585   if (entry->fd_entry)
01586     {
01587       int idx = dynindx;
01588       bfd_vma ad = addend;
01589       bfd_vma ofst;
01590       long lowword, highword;
01591 
01592       /* If the symbol is dynamic but binds locally, use
01593         section+offset.  */
01594       if (sec && (entry->symndx != -1
01595                 || FRVFDPIC_SYM_LOCAL (info, entry->d.h)))
01596        {
01597          if (entry->symndx == -1)
01598            ad += entry->d.h->root.u.def.value;
01599          else
01600            ad += sym->st_value;
01601          ad += sec->output_offset;
01602          if (sec->output_section && elf_section_data (sec->output_section))
01603            idx = elf_section_data (sec->output_section)->dynindx;
01604          else
01605            idx = 0;
01606        }
01607 
01608       /* If we're linking an executable at a fixed address, we can
01609         omit the dynamic relocation as long as the symbol is local to
01610         this module.  */
01611       if (info->executable && !info->pie
01612          && (entry->symndx != -1 || FRVFDPIC_SYM_LOCAL (info, entry->d.h)))
01613        {
01614          if (sec)
01615            ad += sec->output_section->vma;
01616          ofst = 0;
01617          if (entry->symndx != -1
01618              || entry->d.h->root.type != bfd_link_hash_undefweak)
01619            {
01620              _frvfdpic_add_rofixup (output_bfd,
01621                                  frvfdpic_gotfixup_section (info),
01622                                  frvfdpic_got_section (info)
01623                                  ->output_section->vma
01624                                  + frvfdpic_got_section (info)
01625                                  ->output_offset
01626                                  + frvfdpic_got_initial_offset (info)
01627                                  + entry->fd_entry, entry);
01628              _frvfdpic_add_rofixup (output_bfd,
01629                                  frvfdpic_gotfixup_section (info),
01630                                  frvfdpic_got_section (info)
01631                                  ->output_section->vma
01632                                  + frvfdpic_got_section (info)
01633                                  ->output_offset
01634                                  + frvfdpic_got_initial_offset (info)
01635                                  + entry->fd_entry + 4, entry);
01636            }
01637        }
01638       else
01639        {
01640          ofst =
01641            _frvfdpic_add_dyn_reloc (output_bfd,
01642                                  entry->lazyplt
01643                                  ? frvfdpic_pltrel_section (info)
01644                                  : frvfdpic_gotrel_section (info),
01645                                  _bfd_elf_section_offset
01646                                  (output_bfd, info,
01647                                   frvfdpic_got_section (info),
01648                                   frvfdpic_got_initial_offset (info)
01649                                   + entry->fd_entry)
01650                                  + frvfdpic_got_section (info)
01651                                  ->output_section->vma
01652                                  + frvfdpic_got_section (info)
01653                                  ->output_offset,
01654                                  R_FRV_FUNCDESC_VALUE, idx, ad, entry);
01655        }
01656 
01657       /* If we've omitted the dynamic relocation, just emit the fixed
01658         addresses of the symbol and of the local GOT base offset.  */
01659       if (info->executable && !info->pie && sec && sec->output_section)
01660        {
01661          lowword = ad;
01662          highword = frvfdpic_got_section (info)->output_section->vma
01663            + frvfdpic_got_section (info)->output_offset
01664            + frvfdpic_got_initial_offset (info);
01665        }
01666       else if (entry->lazyplt)
01667        {
01668          if (ad)
01669            {
01670              (*info->callbacks->reloc_dangerous)
01671               (info, _("relocation requires zero addend"),
01672                elf_hash_table (info)->dynobj,
01673                frvfdpic_got_section (info),
01674                entry->fd_entry);
01675              return FALSE;
01676            }
01677 
01678          fd_lazy_rel_offset = ofst;
01679 
01680          /* A function descriptor used for lazy or local resolving is
01681             initialized such that its high word contains the output
01682             section index in which the PLT entries are located, and
01683             the low word contains the address of the lazy PLT entry
01684             entry point, that must be within the memory region
01685             assigned to that section.  */
01686          lowword = entry->lzplt_entry + 4
01687            + frvfdpic_plt_section (info)->output_offset
01688            + frvfdpic_plt_section (info)->output_section->vma;
01689          highword = _frvfdpic_osec_to_segment
01690            (output_bfd, frvfdpic_plt_section (info)->output_section);
01691        }
01692       else
01693        {
01694          /* A function descriptor for a local function gets the index
01695             of the section.  For a non-local function, it's
01696             disregarded.  */
01697          lowword = ad;
01698          if (entry->symndx == -1 && entry->d.h->dynindx != -1
01699              && entry->d.h->dynindx == idx)
01700            highword = 0;
01701          else
01702            highword = _frvfdpic_osec_to_segment
01703              (output_bfd, sec->output_section);
01704        }
01705 
01706       bfd_put_32 (output_bfd, lowword,
01707                 frvfdpic_got_section (info)->contents
01708                 + frvfdpic_got_initial_offset (info)
01709                 + entry->fd_entry);
01710       bfd_put_32 (output_bfd, highword,
01711                 frvfdpic_got_section (info)->contents
01712                 + frvfdpic_got_initial_offset (info)
01713                 + entry->fd_entry + 4);
01714     }
01715 
01716   /* Generate code for the PLT entry.  */
01717   if (entry->plt_entry != (bfd_vma) -1)
01718     {
01719       bfd_byte *plt_code = frvfdpic_plt_section (info)->contents
01720        + entry->plt_entry;
01721 
01722       BFD_ASSERT (entry->fd_entry);
01723 
01724       /* Figure out what kind of PLT entry we need, depending on the
01725         location of the function descriptor within the GOT.  */
01726       if (entry->fd_entry >= -(1 << (12 - 1))
01727          && entry->fd_entry < (1 << (12 - 1)))
01728        {
01729          /* lddi @(gr15, fd_entry), gr14 */
01730          bfd_put_32 (output_bfd,
01731                     0x9cccf000 | (entry->fd_entry & ((1 << 12) - 1)),
01732                     plt_code);
01733          plt_code += 4;
01734        }
01735       else
01736        {
01737          if (entry->fd_entry >= -(1 << (16 - 1))
01738              && entry->fd_entry < (1 << (16 - 1)))
01739            {
01740              /* setlos lo(fd_entry), gr14 */
01741              bfd_put_32 (output_bfd,
01742                        0x9cfc0000
01743                        | (entry->fd_entry & (((bfd_vma)1 << 16) - 1)),
01744                        plt_code);
01745              plt_code += 4;
01746            }
01747          else
01748            {
01749              /* sethi.p hi(fd_entry), gr14
01750                setlo lo(fd_entry), gr14 */
01751              bfd_put_32 (output_bfd,
01752                        0x1cf80000
01753                        | ((entry->fd_entry >> 16)
01754                           & (((bfd_vma)1 << 16) - 1)),
01755                        plt_code);
01756              plt_code += 4;
01757              bfd_put_32 (output_bfd,
01758                        0x9cf40000
01759                        | (entry->fd_entry & (((bfd_vma)1 << 16) - 1)),
01760                        plt_code);
01761              plt_code += 4;
01762            }
01763          /* ldd @(gr14,gr15),gr14 */
01764          bfd_put_32 (output_bfd, 0x9c08e14f, plt_code);
01765          plt_code += 4;
01766        }
01767       /* jmpl @(gr14,gr0) */
01768       bfd_put_32 (output_bfd, 0x8030e000, plt_code);
01769     }
01770 
01771   /* Generate code for the lazy PLT entry.  */
01772   if (entry->lzplt_entry != (bfd_vma) -1)
01773     {
01774       bfd_byte *lzplt_code = frvfdpic_plt_section (info)->contents
01775        + entry->lzplt_entry;
01776       bfd_vma resolverStub_addr;
01777 
01778       bfd_put_32 (output_bfd, fd_lazy_rel_offset, lzplt_code);
01779       lzplt_code += 4;
01780 
01781       resolverStub_addr = entry->lzplt_entry / FRVFDPIC_LZPLT_BLOCK_SIZE
01782        * FRVFDPIC_LZPLT_BLOCK_SIZE + FRVFDPIC_LZPLT_RESOLV_LOC;
01783       if (resolverStub_addr >= frvfdpic_plt_initial_offset (info))
01784        resolverStub_addr = frvfdpic_plt_initial_offset (info) - 12;
01785 
01786       if (entry->lzplt_entry == resolverStub_addr)
01787        {
01788          /* This is a lazy PLT entry that includes a resolver call.  */
01789          /* ldd @(gr15,gr0), gr4
01790             jmpl @(gr4,gr0)  */
01791          bfd_put_32 (output_bfd, 0x8808f140, lzplt_code);
01792          bfd_put_32 (output_bfd, 0x80304000, lzplt_code + 4);
01793        }
01794       else
01795        {
01796          /* bra  resolverStub */
01797          bfd_put_32 (output_bfd,
01798                     0xc01a0000
01799                     | (((resolverStub_addr - entry->lzplt_entry)
01800                        / 4) & (((bfd_vma)1 << 16) - 1)),
01801                     lzplt_code);
01802        }
01803     }
01804 
01805   /* Generate relocation for GOT entry holding the TLS offset.  */
01806   if (entry->tlsoff_entry)
01807     {
01808       int idx = dynindx;
01809       bfd_vma ad = addend;
01810 
01811       if (entry->symndx != -1
01812          || FRVFDPIC_SYM_LOCAL (info, entry->d.h))
01813        {
01814          /* If the symbol is dynamic but binds locally, use
01815             section+offset.  */
01816          if (sec)
01817            {
01818              if (entry->symndx == -1)
01819               ad += entry->d.h->root.u.def.value;
01820              else
01821               ad += sym->st_value;
01822              ad += sec->output_offset;
01823              if (sec->output_section
01824                 && elf_section_data (sec->output_section))
01825               idx = elf_section_data (sec->output_section)->dynindx;
01826              else
01827               idx = 0;
01828            }
01829        }
01830 
01831       /* *ABS*+addend is special for TLS relocations, use only the
01832         addend.  */
01833       if (info->executable
01834          && idx == 0
01835          && (bfd_is_abs_section (sec)
01836              || bfd_is_und_section (sec)))
01837        ;
01838       /* If we're linking an executable, we can entirely omit the
01839         dynamic relocation if the symbol is local to this module.  */
01840       else if (info->executable
01841               && (entry->symndx != -1
01842                  || FRVFDPIC_SYM_LOCAL (info, entry->d.h)))
01843        {
01844          if (sec)
01845            ad += sec->output_section->vma - tls_biased_base (info);
01846        }
01847       else
01848        {
01849          if (idx == 0
01850              && (bfd_is_abs_section (sec)
01851                 || bfd_is_und_section (sec)))
01852            {
01853              if (! elf_hash_table (info)->tls_sec)
01854               {
01855                 (*info->callbacks->undefined_symbol)
01856                   (info, "TLS section", elf_hash_table (info)->dynobj,
01857                    frvfdpic_got_section (info), entry->tlsoff_entry, TRUE);
01858                 return FALSE;
01859               }
01860              idx = elf_section_data (elf_hash_table (info)->tls_sec)->dynindx;
01861              ad += FRVFDPIC_TLS_BIAS;
01862            }
01863          _frvfdpic_add_dyn_reloc (output_bfd, frvfdpic_gotrel_section (info),
01864                                _bfd_elf_section_offset
01865                                (output_bfd, info,
01866                                 frvfdpic_got_section (info),
01867                                 frvfdpic_got_initial_offset (info)
01868                                 + entry->tlsoff_entry)
01869                                + frvfdpic_got_section (info)
01870                                ->output_section->vma
01871                                + frvfdpic_got_section (info)
01872                                ->output_offset,
01873                                R_FRV_TLSOFF, idx, ad, entry);
01874        }
01875 
01876       bfd_put_32 (output_bfd, ad,
01877                 frvfdpic_got_section (info)->contents
01878                 + frvfdpic_got_initial_offset (info)
01879                 + entry->tlsoff_entry);
01880     }
01881 
01882   if (entry->tlsdesc_entry)
01883     {
01884       int idx = dynindx;
01885       bfd_vma ad = addend;
01886 
01887       /* If the symbol is dynamic but binds locally, use
01888         section+offset.  */
01889       if (sec && (entry->symndx != -1
01890                 || FRVFDPIC_SYM_LOCAL (info, entry->d.h)))
01891        {
01892          if (entry->symndx == -1)
01893            ad += entry->d.h->root.u.def.value;
01894          else
01895            ad += sym->st_value;
01896          ad += sec->output_offset;
01897          if (sec->output_section && elf_section_data (sec->output_section))
01898            idx = elf_section_data (sec->output_section)->dynindx;
01899          else
01900            idx = 0;
01901        }
01902 
01903       /* If we didn't set up a TLS offset entry, but we're linking an
01904         executable and the symbol binds locally, we can use the
01905         module offset in the TLS descriptor in relaxations.  */
01906       if (info->executable && ! entry->tlsoff_entry)
01907        entry->tlsoff_entry = entry->tlsdesc_entry + 4;
01908 
01909       if (info->executable && !info->pie
01910          && ((idx == 0
01911               && (bfd_is_abs_section (sec)
01912                  || bfd_is_und_section (sec)))
01913              || entry->symndx != -1
01914              || FRVFDPIC_SYM_LOCAL (info, entry->d.h)))
01915        {
01916          /* *ABS*+addend is special for TLS relocations, use only the
01917             addend for the TLS offset, and take the module id as
01918             0.  */
01919          if (idx == 0
01920              && (bfd_is_abs_section (sec)
01921                 || bfd_is_und_section (sec)))
01922            ;
01923          /* For other TLS symbols that bind locally, add the section
01924             TLS offset to the addend.  */
01925          else if (sec)
01926            ad += sec->output_section->vma - tls_biased_base (info);
01927 
01928          bfd_put_32 (output_bfd,
01929                     frvfdpic_plt_section (info)->output_section->vma
01930                     + frvfdpic_plt_section (info)->output_offset
01931                     + frvfdpic_plt_tls_ret_offset (info),
01932                     frvfdpic_got_section (info)->contents
01933                     + frvfdpic_got_initial_offset (info)
01934                     + entry->tlsdesc_entry);
01935 
01936          _frvfdpic_add_rofixup (output_bfd,
01937                              frvfdpic_gotfixup_section (info),
01938                              frvfdpic_got_section (info)
01939                              ->output_section->vma
01940                              + frvfdpic_got_section (info)
01941                              ->output_offset
01942                              + frvfdpic_got_initial_offset (info)
01943                              + entry->tlsdesc_entry, entry);
01944 
01945          BFD_ASSERT (frvfdpic_dynamic_got_plt_info (info)->tls_ret_refs);
01946 
01947          /* We've used one of the reserved fixups, so discount it so
01948             that we can check at the end that we've used them
01949             all.  */
01950          frvfdpic_dynamic_got_plt_info (info)->tls_ret_refs--;
01951 
01952          /* While at that, make sure the ret instruction makes to the
01953             right location in the PLT.  We could do it only when we
01954             got to 0, but since the check at the end will only print
01955             a warning, make sure we have the ret in place in case the
01956             warning is missed.  */
01957          bfd_put_32 (output_bfd, 0xc03a4000,
01958                     frvfdpic_plt_section (info)->contents
01959                     + frvfdpic_plt_tls_ret_offset (info));
01960        }
01961       else
01962        {
01963          if (idx == 0
01964              && (bfd_is_abs_section (sec)
01965                 || bfd_is_und_section (sec)))
01966            {
01967              if (! elf_hash_table (info)->tls_sec)
01968               {
01969                 (*info->callbacks->undefined_symbol)
01970                   (info, "TLS section", elf_hash_table (info)->dynobj,
01971                    frvfdpic_got_section (info), entry->tlsdesc_entry, TRUE);
01972                 return FALSE;
01973               }
01974              idx = elf_section_data (elf_hash_table (info)->tls_sec)->dynindx;
01975              ad += FRVFDPIC_TLS_BIAS;
01976            }
01977 
01978          _frvfdpic_add_dyn_reloc (output_bfd, frvfdpic_gotrel_section (info),
01979                                _bfd_elf_section_offset
01980                                (output_bfd, info,
01981                                 frvfdpic_got_section (info),
01982                                 frvfdpic_got_initial_offset (info)
01983                                 + entry->tlsdesc_entry)
01984                                + frvfdpic_got_section (info)
01985                                ->output_section->vma
01986                                + frvfdpic_got_section (info)
01987                                ->output_offset,
01988                                R_FRV_TLSDESC_VALUE, idx, ad, entry);
01989 
01990          bfd_put_32 (output_bfd, 0,
01991                     frvfdpic_got_section (info)->contents
01992                     + frvfdpic_got_initial_offset (info)
01993                     + entry->tlsdesc_entry);
01994        }
01995 
01996       bfd_put_32 (output_bfd, ad,
01997                 frvfdpic_got_section (info)->contents
01998                 + frvfdpic_got_initial_offset (info)
01999                 + entry->tlsdesc_entry + 4);
02000     }
02001 
02002   /* Generate code for the get-TLS-offset PLT entry.  */
02003   if (entry->tlsplt_entry != (bfd_vma) -1)
02004     {
02005       bfd_byte *plt_code = frvfdpic_plt_section (info)->contents
02006        + entry->tlsplt_entry;
02007 
02008       if (info->executable
02009          && (entry->symndx != -1
02010              || FRVFDPIC_SYM_LOCAL (info, entry->d.h)))
02011        {
02012          int idx = dynindx;
02013          bfd_vma ad = addend;
02014 
02015          /* sec may be NULL when referencing an undefweak symbol
02016             while linking a static executable.  */
02017          if (!sec)
02018            {
02019              BFD_ASSERT (entry->symndx == -1
02020                        && entry->d.h->root.type == bfd_link_hash_undefweak);
02021            }
02022          else
02023            {
02024              if (entry->symndx == -1)
02025               ad += entry->d.h->root.u.def.value;
02026              else
02027               ad += sym->st_value;
02028              ad += sec->output_offset;
02029              if (sec->output_section
02030                 && elf_section_data (sec->output_section))
02031               idx = elf_section_data (sec->output_section)->dynindx;
02032              else
02033               idx = 0;
02034            }
02035 
02036          /* *ABS*+addend is special for TLS relocations, use only the
02037             addend for the TLS offset, and take the module id as
02038             0.  */
02039          if (idx == 0
02040              && (bfd_is_abs_section (sec)
02041                 || bfd_is_und_section (sec)))
02042            ;
02043          /* For other TLS symbols that bind locally, add the section
02044             TLS offset to the addend.  */
02045          else if (sec)
02046            ad += sec->output_section->vma - tls_biased_base (info);
02047 
02048          if ((bfd_signed_vma)ad >= -(1 << (16 - 1))
02049              && (bfd_signed_vma)ad < (1 << (16 - 1)))
02050            {
02051              /* setlos lo(ad), gr9 */
02052              bfd_put_32 (output_bfd,
02053                        0x92fc0000
02054                        | (ad
02055                           & (((bfd_vma)1 << 16) - 1)),
02056                        plt_code);
02057              plt_code += 4;
02058            }
02059          else
02060            {
02061              /* sethi.p hi(ad), gr9
02062                setlo lo(ad), gr9 */
02063              bfd_put_32 (output_bfd,
02064                        0x12f80000
02065                        | ((ad >> 16)
02066                           & (((bfd_vma)1 << 16) - 1)),
02067                        plt_code);
02068              plt_code += 4;
02069              bfd_put_32 (output_bfd,
02070                        0x92f40000
02071                        | (ad
02072                           & (((bfd_vma)1 << 16) - 1)),
02073                        plt_code);
02074              plt_code += 4;
02075            }
02076          /* ret */
02077          bfd_put_32 (output_bfd, 0xc03a4000, plt_code);
02078        }
02079       else if (entry->tlsoff_entry)
02080        {
02081          /* Figure out what kind of PLT entry we need, depending on the
02082             location of the TLS descriptor within the GOT.  */
02083          if (entry->tlsoff_entry >= -(1 << (12 - 1))
02084              && entry->tlsoff_entry < (1 << (12 - 1)))
02085            {
02086              /* ldi @(gr15, tlsoff_entry), gr9 */
02087              bfd_put_32 (output_bfd,
02088                        0x92c8f000 | (entry->tlsoff_entry
02089                                    & ((1 << 12) - 1)),
02090                        plt_code);
02091              plt_code += 4;
02092            }
02093          else
02094            {
02095              if (entry->tlsoff_entry >= -(1 << (16 - 1))
02096                 && entry->tlsoff_entry < (1 << (16 - 1)))
02097               {
02098                 /* setlos lo(tlsoff_entry), gr8 */
02099                 bfd_put_32 (output_bfd,
02100                            0x90fc0000
02101                            | (entry->tlsoff_entry
02102                              & (((bfd_vma)1 << 16) - 1)),
02103                            plt_code);
02104                 plt_code += 4;
02105               }
02106              else
02107               {
02108                 /* sethi.p hi(tlsoff_entry), gr8
02109                    setlo lo(tlsoff_entry), gr8 */
02110                 bfd_put_32 (output_bfd,
02111                            0x10f80000
02112                            | ((entry->tlsoff_entry >> 16)
02113                              & (((bfd_vma)1 << 16) - 1)),
02114                            plt_code);
02115                 plt_code += 4;
02116                 bfd_put_32 (output_bfd,
02117                            0x90f40000
02118                            | (entry->tlsoff_entry
02119                              & (((bfd_vma)1 << 16) - 1)),
02120                            plt_code);
02121                 plt_code += 4;
02122               }
02123              /* ld @(gr15,gr8),gr9 */
02124              bfd_put_32 (output_bfd, 0x9008f108, plt_code);
02125              plt_code += 4;
02126            }
02127          /* ret */
02128          bfd_put_32 (output_bfd, 0xc03a4000, plt_code);
02129        }
02130       else
02131        {
02132          BFD_ASSERT (entry->tlsdesc_entry);
02133 
02134          /* Figure out what kind of PLT entry we need, depending on the
02135             location of the TLS descriptor within the GOT.  */
02136          if (entry->tlsdesc_entry >= -(1 << (12 - 1))
02137              && entry->tlsdesc_entry < (1 << (12 - 1)))
02138            {
02139              /* lddi @(gr15, tlsdesc_entry), gr8 */
02140              bfd_put_32 (output_bfd,
02141                        0x90ccf000 | (entry->tlsdesc_entry
02142                                    & ((1 << 12) - 1)),
02143                        plt_code);
02144              plt_code += 4;
02145            }
02146          else
02147            {
02148              if (entry->tlsdesc_entry >= -(1 << (16 - 1))
02149                 && entry->tlsdesc_entry < (1 << (16 - 1)))
02150               {
02151                 /* setlos lo(tlsdesc_entry), gr8 */
02152                 bfd_put_32 (output_bfd,
02153                            0x90fc0000
02154                            | (entry->tlsdesc_entry
02155                              & (((bfd_vma)1 << 16) - 1)),
02156                            plt_code);
02157                 plt_code += 4;
02158               }
02159              else
02160               {
02161                 /* sethi.p hi(tlsdesc_entry), gr8
02162                    setlo lo(tlsdesc_entry), gr8 */
02163                 bfd_put_32 (output_bfd,
02164                            0x10f80000
02165                            | ((entry->tlsdesc_entry >> 16)
02166                              & (((bfd_vma)1 << 16) - 1)),
02167                            plt_code);
02168                 plt_code += 4;
02169                 bfd_put_32 (output_bfd,
02170                            0x90f40000
02171                            | (entry->tlsdesc_entry
02172                              & (((bfd_vma)1 << 16) - 1)),
02173                            plt_code);
02174                 plt_code += 4;
02175               }
02176              /* ldd @(gr15,gr8),gr8 */
02177              bfd_put_32 (output_bfd, 0x9008f148, plt_code);
02178              plt_code += 4;
02179            }
02180          /* jmpl @(gr8,gr0) */
02181          bfd_put_32 (output_bfd, 0x80308000, plt_code);
02182        }
02183     }
02184 
02185   return TRUE;
02186 }
02187 
02188 /* Handle an FRV small data reloc.  */
02189 
02190 static bfd_reloc_status_type
02191 elf32_frv_relocate_gprel12 (info, input_bfd, input_section, relocation,
02192                          contents, value)
02193      struct bfd_link_info *info;
02194      bfd *input_bfd;
02195      asection *input_section;
02196      Elf_Internal_Rela *relocation;
02197      bfd_byte *contents;
02198      bfd_vma value;
02199 {
02200   bfd_vma insn;
02201   bfd_vma gp;
02202   struct bfd_link_hash_entry *h;
02203 
02204   h = bfd_link_hash_lookup (info->hash, "_gp", FALSE, FALSE, TRUE);
02205 
02206   gp = (h->u.def.value
02207        + h->u.def.section->output_section->vma
02208        + h->u.def.section->output_offset);
02209 
02210   value -= input_section->output_section->vma;
02211   value -= (gp - input_section->output_section->vma);
02212 
02213   insn = bfd_get_32 (input_bfd, contents + relocation->r_offset);
02214 
02215   value += relocation->r_addend;
02216 
02217   if ((long) value > 0x7ff || (long) value < -0x800)
02218     return bfd_reloc_overflow;
02219 
02220   bfd_put_32 (input_bfd,
02221              (insn & 0xfffff000) | (value & 0xfff),
02222              contents + relocation->r_offset);
02223 
02224   return bfd_reloc_ok;
02225 }
02226 
02227 /* Handle an FRV small data reloc. for the u12 field.  */
02228 
02229 static bfd_reloc_status_type
02230 elf32_frv_relocate_gprelu12 (info, input_bfd, input_section, relocation,
02231                           contents, value)
02232      struct bfd_link_info *info;
02233      bfd *input_bfd;
02234      asection *input_section;
02235      Elf_Internal_Rela *relocation;
02236      bfd_byte *contents;
02237      bfd_vma value;
02238 {
02239   bfd_vma insn;
02240   bfd_vma gp;
02241   struct bfd_link_hash_entry *h;
02242   bfd_vma mask;
02243 
02244   h = bfd_link_hash_lookup (info->hash, "_gp", FALSE, FALSE, TRUE);
02245 
02246   gp = (h->u.def.value
02247        + h->u.def.section->output_section->vma
02248        + h->u.def.section->output_offset);
02249 
02250   value -= input_section->output_section->vma;
02251   value -= (gp - input_section->output_section->vma);
02252 
02253   insn = bfd_get_32 (input_bfd, contents + relocation->r_offset);
02254 
02255   value += relocation->r_addend;
02256 
02257   if ((long) value > 0x7ff || (long) value < -0x800)
02258     return bfd_reloc_overflow;
02259 
02260   /* The high 6 bits go into bits 17-12. The low 6 bits go into bits 5-0.  */
02261   mask = 0x3f03f;
02262   insn = (insn & ~mask) | ((value & 0xfc0) << 12) | (value & 0x3f);
02263 
02264   bfd_put_32 (input_bfd, insn, contents + relocation->r_offset);
02265 
02266   return bfd_reloc_ok;
02267 }
02268 
02269 /* Handle an FRV ELF HI16 reloc.  */
02270 
02271 static bfd_reloc_status_type
02272 elf32_frv_relocate_hi16 (input_bfd, relhi, contents, value)
02273      bfd *input_bfd;
02274      Elf_Internal_Rela *relhi;
02275      bfd_byte *contents;
02276      bfd_vma value;
02277 {
02278   bfd_vma insn;
02279 
02280   insn = bfd_get_32 (input_bfd, contents + relhi->r_offset);
02281 
02282   value += relhi->r_addend;
02283   value = ((value >> 16) & 0xffff);
02284 
02285   insn = (insn & 0xffff0000) | value;
02286 
02287   if ((long) value > 0xffff || (long) value < -0x10000)
02288     return bfd_reloc_overflow;
02289 
02290   bfd_put_32 (input_bfd, insn, contents + relhi->r_offset);
02291   return bfd_reloc_ok;
02292 
02293 }
02294 static bfd_reloc_status_type
02295 elf32_frv_relocate_lo16 (input_bfd, rello, contents, value)
02296      bfd *input_bfd;
02297      Elf_Internal_Rela *rello;
02298      bfd_byte *contents;
02299      bfd_vma value;
02300 {
02301   bfd_vma insn;
02302 
02303   insn = bfd_get_32 (input_bfd, contents + rello->r_offset);
02304 
02305   value += rello->r_addend;
02306   value = value & 0xffff;
02307 
02308   insn = (insn & 0xffff0000) | value;
02309 
02310   if ((long) value > 0xffff || (long) value < -0x10000)
02311     return bfd_reloc_overflow;
02312 
02313   bfd_put_32 (input_bfd, insn, contents + rello->r_offset);
02314   return bfd_reloc_ok;
02315 }
02316 
02317 /* Perform the relocation for the CALL label24 instruction.  */
02318 
02319 static bfd_reloc_status_type
02320 elf32_frv_relocate_label24 (input_bfd, input_section, rello, contents, value)
02321      bfd *input_bfd;
02322      asection *input_section;
02323      Elf_Internal_Rela *rello;
02324      bfd_byte *contents;
02325      bfd_vma value;
02326 {
02327   bfd_vma insn;
02328   bfd_vma label6;
02329   bfd_vma label18;
02330 
02331   /* The format for the call instruction is:
02332 
02333     0 000000 0001111 000000000000000000
02334       label6 opcode  label18
02335 
02336     The branch calculation is: pc + (4*label24)
02337     where label24 is the concatenation of label6 and label18.  */
02338 
02339   /* Grab the instruction.  */
02340   insn = bfd_get_32 (input_bfd, contents + rello->r_offset);
02341 
02342   value -= input_section->output_section->vma + input_section->output_offset;
02343   value -= rello->r_offset;
02344   value += rello->r_addend;
02345 
02346   value = value >> 2;
02347 
02348   label6  = value & 0xfc0000;
02349   label6  = label6 << 7;
02350 
02351   label18 = value & 0x3ffff;
02352 
02353   insn = insn & 0x803c0000;
02354   insn = insn | label6;
02355   insn = insn | label18;
02356 
02357   bfd_put_32 (input_bfd, insn, contents + rello->r_offset);
02358 
02359   return bfd_reloc_ok;
02360 }
02361 
02362 static bfd_reloc_status_type
02363 elf32_frv_relocate_gprelhi (info, input_bfd, input_section, relocation,
02364                          contents, value)
02365      struct bfd_link_info *info;
02366      bfd *input_bfd;
02367      asection *input_section;
02368      Elf_Internal_Rela *relocation;
02369      bfd_byte *contents;
02370      bfd_vma value;
02371 {
02372   bfd_vma insn;
02373   bfd_vma gp;
02374   struct bfd_link_hash_entry *h;
02375 
02376   h = bfd_link_hash_lookup (info->hash, "_gp", FALSE, FALSE, TRUE);
02377 
02378   gp = (h->u.def.value
02379         + h->u.def.section->output_section->vma
02380         + h->u.def.section->output_offset);
02381 
02382   value -= input_section->output_section->vma;
02383   value -= (gp - input_section->output_section->vma);
02384   value += relocation->r_addend;
02385   value = ((value >> 16) & 0xffff);
02386 
02387   if ((long) value > 0xffff || (long) value < -0x10000)
02388     return bfd_reloc_overflow;
02389 
02390   insn = bfd_get_32 (input_bfd, contents + relocation->r_offset);
02391   insn = (insn & 0xffff0000) | value;
02392 
02393   bfd_put_32 (input_bfd, insn, contents + relocation->r_offset);
02394   return bfd_reloc_ok;
02395 }
02396 
02397 static bfd_reloc_status_type
02398 elf32_frv_relocate_gprello (info, input_bfd, input_section, relocation,
02399                          contents, value)
02400      struct bfd_link_info *info;
02401      bfd *input_bfd;
02402      asection *input_section;
02403      Elf_Internal_Rela *relocation;
02404      bfd_byte *contents;
02405      bfd_vma value;
02406 {
02407   bfd_vma insn;
02408   bfd_vma gp;
02409   struct bfd_link_hash_entry *h;
02410 
02411   h = bfd_link_hash_lookup (info->hash, "_gp", FALSE, FALSE, TRUE);
02412 
02413   gp = (h->u.def.value
02414         + h->u.def.section->output_section->vma
02415         + h->u.def.section->output_offset);
02416 
02417   value -= input_section->output_section->vma;
02418   value -= (gp - input_section->output_section->vma);
02419   value += relocation->r_addend;
02420   value = value & 0xffff;
02421 
02422   if ((long) value > 0xffff || (long) value < -0x10000)
02423     return bfd_reloc_overflow;
02424 
02425   insn = bfd_get_32 (input_bfd, contents + relocation->r_offset);
02426   insn = (insn & 0xffff0000) | value;
02427 
02428   bfd_put_32 (input_bfd, insn, contents + relocation->r_offset);
02429 
02430  return bfd_reloc_ok;
02431 }
02432 
02433 static reloc_howto_type *
02434 frv_reloc_type_lookup (abfd, code)
02435      bfd *abfd ATTRIBUTE_UNUSED;
02436      bfd_reloc_code_real_type code;
02437 {
02438   switch (code)
02439     {
02440     default:
02441       break;
02442 
02443     case BFD_RELOC_NONE:
02444       return &elf32_frv_howto_table[ (int) R_FRV_NONE];
02445 
02446     case BFD_RELOC_32:
02447       if (elf_elfheader (abfd)->e_type == ET_EXEC
02448          || elf_elfheader (abfd)->e_type == ET_DYN)
02449        return &elf32_frv_rel_32_howto;
02450       /* Fall through.  */
02451     case BFD_RELOC_CTOR:
02452       return &elf32_frv_howto_table[ (int) R_FRV_32];
02453 
02454     case BFD_RELOC_FRV_LABEL16:
02455       return &elf32_frv_howto_table[ (int) R_FRV_LABEL16];
02456 
02457     case BFD_RELOC_FRV_LABEL24:
02458       return &elf32_frv_howto_table[ (int) R_FRV_LABEL24];
02459 
02460     case BFD_RELOC_FRV_LO16:
02461       return &elf32_frv_howto_table[ (int) R_FRV_LO16];
02462 
02463     case BFD_RELOC_FRV_HI16:
02464       return &elf32_frv_howto_table[ (int) R_FRV_HI16];
02465 
02466     case BFD_RELOC_FRV_GPREL12:
02467       return &elf32_frv_howto_table[ (int) R_FRV_GPREL12];
02468 
02469     case BFD_RELOC_FRV_GPRELU12:
02470       return &elf32_frv_howto_table[ (int) R_FRV_GPRELU12];
02471 
02472     case BFD_RELOC_FRV_GPREL32:
02473       return &elf32_frv_howto_table[ (int) R_FRV_GPREL32];
02474 
02475     case BFD_RELOC_FRV_GPRELHI:
02476       return &elf32_frv_howto_table[ (int) R_FRV_GPRELHI];
02477 
02478     case BFD_RELOC_FRV_GPRELLO:
02479       return &elf32_frv_howto_table[ (int) R_FRV_GPRELLO];
02480 
02481     case BFD_RELOC_FRV_GOT12:
02482       return &elf32_frv_howto_table[ (int) R_FRV_GOT12];
02483 
02484     case BFD_RELOC_FRV_GOTHI:
02485       return &elf32_frv_howto_table[ (int) R_FRV_GOTHI];
02486 
02487     case BFD_RELOC_FRV_GOTLO:
02488       return &elf32_frv_howto_table[ (int) R_FRV_GOTLO];
02489 
02490     case BFD_RELOC_FRV_FUNCDESC:
02491       if (elf_elfheader (abfd)->e_type == ET_EXEC
02492          || elf_elfheader (abfd)->e_type == ET_DYN)
02493        return &elf32_frv_rel_funcdesc_howto;
02494       return &elf32_frv_howto_table[ (int) R_FRV_FUNCDESC];
02495 
02496     case BFD_RELOC_FRV_FUNCDESC_GOT12:
02497       return &elf32_frv_howto_table[ (int) R_FRV_FUNCDESC_GOT12];
02498 
02499     case BFD_RELOC_FRV_FUNCDESC_GOTHI:
02500       return &elf32_frv_howto_table[ (int) R_FRV_FUNCDESC_GOTHI];
02501 
02502     case BFD_RELOC_FRV_FUNCDESC_GOTLO:
02503       return &elf32_frv_howto_table[ (int) R_FRV_FUNCDESC_GOTLO];
02504 
02505     case BFD_RELOC_FRV_FUNCDESC_VALUE:
02506       if (elf_elfheader (abfd)->e_type == ET_EXEC
02507          || elf_elfheader (abfd)->e_type == ET_DYN)
02508        return &elf32_frv_rel_funcdesc_value_howto;
02509       return &elf32_frv_howto_table[ (int) R_FRV_FUNCDESC_VALUE];
02510 
02511     case BFD_RELOC_FRV_FUNCDESC_GOTOFF12:
02512       return &elf32_frv_howto_table[ (int) R_FRV_FUNCDESC_GOTOFF12];
02513 
02514     case BFD_RELOC_FRV_FUNCDESC_GOTOFFHI:
02515       return &elf32_frv_howto_table[ (int) R_FRV_FUNCDESC_GOTOFFHI];
02516 
02517     case BFD_RELOC_FRV_FUNCDESC_GOTOFFLO:
02518       return &elf32_frv_howto_table[ (int) R_FRV_FUNCDESC_GOTOFFLO];
02519 
02520     case BFD_RELOC_FRV_GOTOFF12:
02521       return &elf32_frv_howto_table[ (int) R_FRV_GOTOFF12];
02522 
02523     case BFD_RELOC_FRV_GOTOFFHI:
02524       return &elf32_frv_howto_table[ (int) R_FRV_GOTOFFHI];
02525 
02526     case BFD_RELOC_FRV_GOTOFFLO:
02527       return &elf32_frv_howto_table[ (int) R_FRV_GOTOFFLO];
02528 
02529     case BFD_RELOC_FRV_GETTLSOFF:
02530       return &elf32_frv_howto_table[ (int) R_FRV_GETTLSOFF];
02531 
02532     case BFD_RELOC_FRV_TLSDESC_VALUE:
02533       if (elf_elfheader (abfd)->e_type == ET_EXEC
02534          || elf_elfheader (abfd)->e_type == ET_DYN)
02535        return &elf32_frv_rel_tlsdesc_value_howto;
02536       return &elf32_frv_howto_table[ (int) R_FRV_TLSDESC_VALUE];
02537 
02538     case BFD_RELOC_FRV_GOTTLSDESC12:
02539       return &elf32_frv_howto_table[ (int) R_FRV_GOTTLSDESC12];
02540 
02541     case BFD_RELOC_FRV_GOTTLSDESCHI:
02542       return &elf32_frv_howto_table[ (int) R_FRV_GOTTLSDESCHI];
02543 
02544     case BFD_RELOC_FRV_GOTTLSDESCLO:
02545       return &elf32_frv_howto_table[ (int) R_FRV_GOTTLSDESCLO];
02546 
02547     case BFD_RELOC_FRV_TLSMOFF12:
02548       return &elf32_frv_howto_table[ (int) R_FRV_TLSMOFF12];
02549 
02550     case BFD_RELOC_FRV_TLSMOFFHI:
02551       return &elf32_frv_howto_table[ (int) R_FRV_TLSMOFFHI];
02552 
02553     case BFD_RELOC_FRV_TLSMOFFLO:
02554       return &elf32_frv_howto_table[ (int) R_FRV_TLSMOFFLO];
02555 
02556     case BFD_RELOC_FRV_GOTTLSOFF12:
02557       return &elf32_frv_howto_table[ (int) R_FRV_GOTTLSOFF12];
02558 
02559     case BFD_RELOC_FRV_GOTTLSOFFHI:
02560       return &elf32_frv_howto_table[ (int) R_FRV_GOTTLSOFFHI];
02561 
02562     case BFD_RELOC_FRV_GOTTLSOFFLO:
02563       return &elf32_frv_howto_table[ (int) R_FRV_GOTTLSOFFLO];
02564 
02565     case BFD_RELOC_FRV_TLSOFF:
02566       if (elf_elfheader (abfd)->e_type == ET_EXEC
02567          || elf_elfheader (abfd)->e_type == ET_DYN)
02568        return &elf32_frv_rel_tlsoff_howto;
02569       return &elf32_frv_howto_table[ (int) R_FRV_TLSOFF];
02570 
02571     case BFD_RELOC_FRV_TLSDESC_RELAX:
02572       return &elf32_frv_howto_table[ (int) R_FRV_TLSDESC_RELAX];
02573 
02574     case BFD_RELOC_FRV_GETTLSOFF_RELAX:
02575       return &elf32_frv_howto_table[ (int) R_FRV_GETTLSOFF_RELAX];
02576 
02577     case BFD_RELOC_FRV_TLSOFF_RELAX:
02578       return &elf32_frv_howto_table[ (int) R_FRV_TLSOFF_RELAX];
02579 
02580     case BFD_RELOC_FRV_TLSMOFF:
02581       return &elf32_frv_howto_table[ (int) R_FRV_TLSMOFF];
02582 
02583     case BFD_RELOC_VTABLE_INHERIT:
02584       return &elf32_frv_vtinherit_howto;
02585 
02586     case BFD_RELOC_VTABLE_ENTRY:
02587       return &elf32_frv_vtentry_howto;
02588     }
02589 
02590   return NULL;
02591 }
02592 
02593 static reloc_howto_type *
02594 frv_reloc_name_lookup (bfd *abfd ATTRIBUTE_UNUSED, const char *r_name)
02595 {
02596   unsigned int i;
02597 
02598   for (i = 0;
02599        i < sizeof (elf32_frv_howto_table) / sizeof (elf32_frv_howto_table[0]);
02600        i++)
02601     if (elf32_frv_howto_table[i].name != NULL
02602        && strcasecmp (elf32_frv_howto_table[i].name, r_name) == 0)
02603       return &elf32_frv_howto_table[i];
02604 
02605   if (strcasecmp (elf32_frv_vtinherit_howto.name, r_name) == 0)
02606     return &elf32_frv_vtinherit_howto;
02607   if (strcasecmp (elf32_frv_vtentry_howto.name, r_name) == 0)
02608     return &elf32_frv_vtentry_howto;
02609 
02610   return NULL;
02611 }
02612 
02613 /* Set the howto pointer for an FRV ELF reloc.  */
02614 
02615 static void
02616 frv_info_to_howto_rela (abfd, cache_ptr, dst)
02617      bfd *abfd ATTRIBUTE_UNUSED;
02618      arelent *cache_ptr;
02619      Elf_Internal_Rela *dst;
02620 {
02621   unsigned int r_type;
02622 
02623   r_type = ELF32_R_TYPE (dst->r_info);
02624   switch (r_type)
02625     {
02626     case R_FRV_GNU_VTINHERIT:
02627       cache_ptr->howto = &elf32_frv_vtinherit_howto;
02628       break;
02629 
02630     case R_FRV_GNU_VTENTRY:
02631       cache_ptr->howto = &elf32_frv_vtentry_howto;
02632       break;
02633 
02634     default:
02635       cache_ptr->howto = & elf32_frv_howto_table [r_type];
02636       break;
02637     }
02638 }
02639 
02640 /* Set the howto pointer for an FRV ELF REL reloc.  */
02641 static void
02642 frvfdpic_info_to_howto_rel (bfd *abfd ATTRIBUTE_UNUSED,
02643                          arelent *cache_ptr, Elf_Internal_Rela *dst)
02644 {
02645   unsigned int r_type;
02646 
02647   r_type = ELF32_R_TYPE (dst->r_info);
02648   switch (r_type)
02649     {
02650     case R_FRV_32:
02651       cache_ptr->howto = &elf32_frv_rel_32_howto;
02652       break;
02653 
02654     case R_FRV_FUNCDESC:
02655       cache_ptr->howto = &elf32_frv_rel_funcdesc_howto;
02656       break;
02657 
02658     case R_FRV_FUNCDESC_VALUE:
02659       cache_ptr->howto = &elf32_frv_rel_funcdesc_value_howto;
02660       break;
02661 
02662     case R_FRV_TLSDESC_VALUE:
02663       cache_ptr->howto = &elf32_frv_rel_tlsdesc_value_howto;
02664       break;
02665 
02666     case R_FRV_TLSOFF:
02667       cache_ptr->howto = &elf32_frv_rel_tlsoff_howto;
02668       break;
02669 
02670     default:
02671       cache_ptr->howto = NULL;
02672       break;
02673     }
02674 }
02675 
02676 /* Perform a single relocation.  By default we use the standard BFD
02677    routines, but a few relocs, we have to do them ourselves.  */
02678 
02679 static bfd_reloc_status_type
02680 frv_final_link_relocate (howto, input_bfd, input_section, contents, rel,
02681                       relocation)
02682      reloc_howto_type *howto;
02683      bfd *input_bfd;
02684      asection *input_section;
02685      bfd_byte *contents;
02686      Elf_Internal_Rela *rel;
02687      bfd_vma relocation;
02688 {
02689   return _bfd_final_link_relocate (howto, input_bfd, input_section,
02690                                contents, rel->r_offset, relocation,
02691                                rel->r_addend);
02692 }
02693 
02694 
02695 /* Relocate an FRV ELF section.
02696 
02697    The RELOCATE_SECTION function is called by the new ELF backend linker
02698    to handle the relocations for a section.
02699 
02700    The relocs are always passed as Rela structures; if the section
02701    actually uses Rel structures, the r_addend field will always be
02702    zero.
02703 
02704    This function is responsible for adjusting the section contents as
02705    necessary, and (if using Rela relocs and generating a relocatable
02706    output file) adjusting the reloc addend as necessary.
02707 
02708    This function does not have to worry about setting the reloc
02709    address or the reloc symbol index.
02710 
02711    LOCAL_SYMS is a pointer to the swapped in local symbols.
02712 
02713    LOCAL_SECTIONS is an array giving the section in the input file
02714    corresponding to the st_shndx field of each local symbol.
02715 
02716    The global hash table entry for the global symbols can be found
02717    via elf_sym_hashes (input_bfd).
02718 
02719    When generating relocatable output, this function must handle
02720    STB_LOCAL/STT_SECTION symbols specially.  The output symbol is
02721    going to be the section symbol corresponding to the output
02722    section, which means that the addend must be adjusted
02723    accordingly.  */
02724 
02725 static bfd_boolean
02726 elf32_frv_relocate_section (output_bfd, info, input_bfd, input_section,
02727                          contents, relocs, local_syms, local_sections)
02728      bfd *output_bfd ATTRIBUTE_UNUSED;
02729      struct bfd_link_info *info;
02730      bfd *input_bfd;
02731      asection *input_section;
02732      bfd_byte *contents;
02733      Elf_Internal_Rela *relocs;
02734      Elf_Internal_Sym *local_syms;
02735      asection **local_sections;
02736 {
02737   Elf_Internal_Shdr *symtab_hdr;
02738   struct elf_link_hash_entry **sym_hashes;
02739   Elf_Internal_Rela *rel;
02740   Elf_Internal_Rela *relend;
02741   unsigned isec_segment, got_segment, plt_segment, gprel_segment, tls_segment,
02742     check_segment[2];
02743   int silence_segment_error = !(info->shared || info->pie);
02744   unsigned long insn;
02745 
02746   symtab_hdr = & elf_tdata (input_bfd)->symtab_hdr;
02747   sym_hashes = elf_sym_hashes (input_bfd);
02748   relend     = relocs + input_section->reloc_count;
02749 
02750   isec_segment = _frvfdpic_osec_to_segment (output_bfd,
02751                                        input_section->output_section);
02752   if (IS_FDPIC (output_bfd) && frvfdpic_got_section (info))
02753     got_segment = _frvfdpic_osec_to_segment (output_bfd,
02754                                         frvfdpic_got_section (info)
02755                                         ->output_section);
02756   else
02757     got_segment = -1;
02758   if (IS_FDPIC (output_bfd) && frvfdpic_gotfixup_section (info))
02759     gprel_segment = _frvfdpic_osec_to_segment (output_bfd,
02760                                           frvfdpic_gotfixup_section (info)
02761                                           ->output_section);
02762   else
02763     gprel_segment = -1;
02764   if (IS_FDPIC (output_bfd) && frvfdpic_plt_section (info))
02765     plt_segment = _frvfdpic_osec_to_segment (output_bfd,
02766                                         frvfdpic_plt_section (info)
02767                                         ->output_section);
02768   else
02769     plt_segment = -1;
02770   if (elf_hash_table (info)->tls_sec)
02771     tls_segment = _frvfdpic_osec_to_segment (output_bfd,
02772                                         elf_hash_table (info)->tls_sec);
02773   else
02774     tls_segment = -1;
02775 
02776   for (rel = relocs; rel < relend; rel ++)
02777     {
02778       reloc_howto_type *howto;
02779       unsigned long r_symndx;
02780       Elf_Internal_Sym *sym;
02781       asection *sec;
02782       struct elf_link_hash_entry *h;
02783       bfd_vma relocation;
02784       bfd_reloc_status_type r;
02785       const char * name = NULL;
02786       int r_type;
02787       asection *osec;
02788       struct frvfdpic_relocs_info *picrel;
02789       bfd_vma orig_addend = rel->r_addend;
02790 
02791       r_type = ELF32_R_TYPE (rel->r_info);
02792 
02793       if (   r_type == R_FRV_GNU_VTINHERIT
02794          || r_type == R_FRV_GNU_VTENTRY)
02795        continue;
02796 
02797       r_symndx = ELF32_R_SYM (rel->r_info);
02798       howto  = elf32_frv_howto_table + ELF32_R_TYPE (rel->r_info);
02799       h      = NULL;
02800       sym    = NULL;
02801       sec    = NULL;
02802 
02803       if (r_symndx < symtab_hdr->sh_info)
02804        {
02805          sym = local_syms + r_symndx;
02806          osec = sec = local_sections [r_symndx];
02807          relocation = _bfd_elf_rela_local_sym (output_bfd, sym, &sec, rel);
02808 
02809          name = bfd_elf_string_from_elf_section
02810            (input_bfd, symtab_hdr->sh_link, sym->st_name);
02811          name = (name == NULL) ? bfd_section_name (input_bfd, sec) : name;
02812        }
02813       else
02814        {
02815          bfd_boolean warned;
02816          bfd_boolean unresolved_reloc;
02817 
02818          RELOC_FOR_GLOBAL_SYMBOL (info, input_bfd, input_section, rel,
02819                                r_symndx, symtab_hdr, sym_hashes,
02820                                h, sec, relocation,
02821                                unresolved_reloc, warned);
02822          osec = sec;
02823        }
02824 
02825       if (sec != NULL && elf_discarded_section (sec))
02826        {
02827          /* For relocs against symbols from removed linkonce sections,
02828             or sections discarded by a linker script, we just want the
02829             section contents zeroed.  Avoid any special processing.  */
02830          _bfd_clear_contents (howto, input_bfd, contents + rel->r_offset);
02831          rel->r_info = 0;
02832          rel->r_addend = 0;
02833          continue;
02834        }
02835 
02836       if (info->relocatable)
02837        continue;
02838 
02839       if (r_type != R_FRV_TLSMOFF
02840          && h != NULL
02841          && (h->root.type == bfd_link_hash_defined
02842              || h->root.type == bfd_link_hash_defweak)
02843          && !FRVFDPIC_SYM_LOCAL (info, h))
02844        {
02845          osec = sec = NULL;
02846          relocation = 0;
02847        }
02848 
02849       switch (r_type)
02850        {
02851        case R_FRV_LABEL24:
02852        case R_FRV_32:
02853          if (! IS_FDPIC (output_bfd))
02854            goto non_fdpic;
02855 
02856        case R_FRV_GOT12:
02857        case R_FRV_GOTHI:
02858        case R_FRV_GOTLO:
02859        case R_FRV_FUNCDESC_GOT12:
02860        case R_FRV_FUNCDESC_GOTHI:
02861        case R_FRV_FUNCDESC_GOTLO:
02862        case R_FRV_GOTOFF12:
02863        case R_FRV_GOTOFFHI:
02864        case R_FRV_GOTOFFLO:
02865        case R_FRV_FUNCDESC_GOTOFF12:
02866        case R_FRV_FUNCDESC_GOTOFFHI:
02867        case R_FRV_FUNCDESC_GOTOFFLO:
02868        case R_FRV_FUNCDESC:
02869        case R_FRV_FUNCDESC_VALUE:
02870        case R_FRV_GETTLSOFF:
02871        case R_FRV_TLSDESC_VALUE:
02872        case R_FRV_GOTTLSDESC12:
02873        case R_FRV_GOTTLSDESCHI:
02874        case R_FRV_GOTTLSDESCLO:
02875        case R_FRV_TLSMOFF12:
02876        case R_FRV_TLSMOFFHI:
02877        case R_FRV_TLSMOFFLO:
02878        case R_FRV_GOTTLSOFF12:
02879        case R_FRV_GOTTLSOFFHI:
02880        case R_FRV_GOTTLSOFFLO:
02881        case R_FRV_TLSOFF:
02882        case R_FRV_TLSDESC_RELAX:
02883        case R_FRV_GETTLSOFF_RELAX:
02884        case R_FRV_TLSOFF_RELAX:
02885        case R_FRV_TLSMOFF:
02886          if (h != NULL)
02887            picrel = frvfdpic_relocs_info_for_global (frvfdpic_relocs_info
02888                                                 (info), input_bfd, h,
02889                                                 orig_addend, INSERT);
02890          else
02891            /* In order to find the entry we created before, we must
02892               use the original addend, not the one that may have been
02893               modified by _bfd_elf_rela_local_sym().  */
02894            picrel = frvfdpic_relocs_info_for_local (frvfdpic_relocs_info
02895                                                (info), input_bfd, r_symndx,
02896                                                orig_addend, INSERT);
02897          if (! picrel)
02898            return FALSE;
02899 
02900          if (!_frvfdpic_emit_got_relocs_plt_entries (picrel, output_bfd, info,
02901                                                 osec, sym,
02902                                                 rel->r_addend))
02903            {
02904              (*_bfd_error_handler)
02905               (_("%B(%A+0x%x): relocation to `%s+%x' may have caused the error above"),
02906                input_bfd, input_section, rel->r_offset, name, rel->r_addend);
02907              return FALSE;
02908            }
02909 
02910          break;
02911 
02912        default:
02913        non_fdpic:
02914          picrel = NULL;
02915          if (h && ! FRVFDPIC_SYM_LOCAL (info, h))
02916            {
02917              info->callbacks->warning
02918               (info, _("relocation references symbol not defined in the module"),
02919                name, input_bfd, input_section, rel->r_offset);
02920              return FALSE;
02921            }
02922          break;
02923        }
02924 
02925       switch (r_type)
02926        {
02927        case R_FRV_GETTLSOFF:
02928        case R_FRV_TLSDESC_VALUE:
02929        case R_FRV_GOTTLSDESC12:
02930        case R_FRV_GOTTLSDESCHI:
02931        case R_FRV_GOTTLSDESCLO:
02932        case R_FRV_TLSMOFF12:
02933        case R_FRV_TLSMOFFHI:
02934        case R_FRV_TLSMOFFLO:
02935        case R_FRV_GOTTLSOFF12:
02936        case R_FRV_GOTTLSOFFHI:
02937        case R_FRV_GOTTLSOFFLO:
02938        case R_FRV_TLSOFF:
02939        case R_FRV_TLSDESC_RELAX:
02940        case R_FRV_GETTLSOFF_RELAX:
02941        case R_FRV_TLSOFF_RELAX:
02942        case R_FRV_TLSMOFF:
02943          if (sec && (bfd_is_abs_section (sec) || bfd_is_und_section (sec)))
02944            relocation += tls_biased_base (info);
02945          break;
02946 
02947        default:
02948          break;
02949        }
02950 
02951       /* Try to apply TLS relaxations.  */
02952       if (1)
02953        switch (r_type)
02954          {
02955 
02956 #define LOCAL_EXEC_P(info, picrel) \
02957   ((info)->executable \
02958    && (picrel->symndx != -1 || FRVFDPIC_SYM_LOCAL ((info), (picrel)->d.h)))
02959 #define INITIAL_EXEC_P(info, picrel) \
02960   (((info)->executable || (info)->flags & DF_STATIC_TLS) \
02961    && (picrel)->tlsoff_entry)
02962 
02963 #define IN_RANGE_FOR_OFST12_P(value) \
02964   ((bfd_vma)((value) + 2048) < (bfd_vma)4096)
02965 #define IN_RANGE_FOR_SETLOS_P(value) \
02966   ((bfd_vma)((value) + 32768) < (bfd_vma)65536)
02967 #define TLSMOFF_IN_RANGE_FOR_SETLOS_P(value, info) \
02968   (IN_RANGE_FOR_SETLOS_P ((value) - tls_biased_base (info)))
02969 
02970 #define RELAX_GETTLSOFF_LOCAL_EXEC_P(info, picrel, value) \
02971   (LOCAL_EXEC_P ((info), (picrel)) \
02972    && TLSMOFF_IN_RANGE_FOR_SETLOS_P((value), (info)))
02973 #define RELAX_GETTLSOFF_INITIAL_EXEC_P(info, picrel) \
02974   (INITIAL_EXEC_P ((info), (picrel)) \
02975    && IN_RANGE_FOR_OFST12_P ((picrel)->tlsoff_entry))
02976 
02977 #define RELAX_TLSDESC_LOCAL_EXEC_P(info, picrel, value) \
02978   (LOCAL_EXEC_P ((info), (picrel)))
02979 #define RELAX_TLSDESC_INITIAL_EXEC_P(info, picrel) \
02980   (INITIAL_EXEC_P ((info), (picrel)))
02981 
02982 #define RELAX_GOTTLSOFF_LOCAL_EXEC_P(info, picrel, value) \
02983   (LOCAL_EXEC_P ((info), (picrel)) \
02984    && TLSMOFF_IN_RANGE_FOR_SETLOS_P((value), (info)))
02985 
02986          case R_FRV_GETTLSOFF:
02987            insn = bfd_get_32 (input_bfd, contents + rel->r_offset);
02988 
02989            /* Is this a call instruction?  */
02990            if ((insn & (unsigned long)0x01fc0000) != 0x003c0000)
02991              {
02992               r = info->callbacks->warning
02993                 (info,
02994                  _("R_FRV_GETTLSOFF not applied to a call instruction"),
02995                  name, input_bfd, input_section, rel->r_offset);
02996               return FALSE;
02997              }
02998 
02999            if (RELAX_GETTLSOFF_LOCAL_EXEC_P (info, picrel,
03000                                          relocation + rel->r_addend))
03001              {
03002               /* Replace the call instruction (except the packing bit)
03003                  with setlos #tlsmofflo(symbol+offset), gr9.  */
03004               insn &= (unsigned long)0x80000000;
03005               insn |= (unsigned long)0x12fc0000;
03006               bfd_put_32 (input_bfd, insn, contents + rel->r_offset);
03007 
03008               r_type = R_FRV_TLSMOFFLO;
03009               howto  = elf32_frv_howto_table + r_type;
03010               rel->r_info = ELF32_R_INFO (r_symndx, r_type);
03011              }
03012 
03013            else if (RELAX_GETTLSOFF_INITIAL_EXEC_P (info, picrel))
03014              {
03015               /* Replace the call instruction (except the packing bit)
03016                  with ldi @(gr15, #gottlsoff12(symbol+addend)), gr9.  */
03017               insn &= (unsigned long)0x80000000;
03018               insn |= (unsigned long)0x12c8f000;
03019               bfd_put_32 (input_bfd, insn, contents + rel->r_offset);
03020 
03021               r_type = R_FRV_GOTTLSOFF12;
03022               howto  = elf32_frv_howto_table + r_type;
03023               rel->r_info = ELF32_R_INFO (r_symndx, r_type);
03024              }
03025 
03026            break;
03027 
03028          case R_FRV_GOTTLSDESC12:
03029            insn = bfd_get_32 (input_bfd, contents + rel->r_offset);
03030 
03031            /* Is this an lddi instruction?  */
03032            if ((insn & (unsigned long)0x01fc0000) != 0x00cc0000)
03033              {
03034               r = info->callbacks->warning
03035                 (info,
03036                  _("R_FRV_GOTTLSDESC12 not applied to an lddi instruction"),
03037                  name, input_bfd, input_section, rel->r_offset);
03038               return FALSE;
03039              }
03040 
03041            if (RELAX_TLSDESC_LOCAL_EXEC_P (info, picrel,
03042                                        relocation + rel->r_addend)
03043               && TLSMOFF_IN_RANGE_FOR_SETLOS_P (relocation + rel->r_addend,
03044                                             info))
03045              {
03046               /* Replace lddi @(grB, #gottlsdesc12(symbol+offset), grC
03047                  with setlos #tlsmofflo(symbol+offset), gr<C+1>.
03048                  Preserve the packing bit.  */
03049               insn = (insn & (unsigned long)0x80000000)
03050                 | ((insn + (unsigned long)0x02000000)
03051                    & (unsigned long)0x7e000000);
03052               insn |= (unsigned long)0x00fc0000;
03053               bfd_put_32 (input_bfd, insn, contents + rel->r_offset);
03054 
03055               r_type = R_FRV_TLSMOFFLO;
03056               howto  = elf32_frv_howto_table + r_type;
03057               rel->r_info = ELF32_R_INFO (r_symndx, r_type);
03058              }
03059 
03060            else if (RELAX_TLSDESC_LOCAL_EXEC_P (info, picrel,
03061                                            relocation + rel->r_addend))
03062              {
03063               /* Replace lddi @(grB, #gottlsdesc12(symbol+offset), grC
03064                  with sethi #tlsmoffhi(symbol+offset), gr<C+1>.
03065                  Preserve the packing bit.  */
03066               insn = (insn & (unsigned long)0x80000000)
03067                 | ((insn + (unsigned long)0x02000000)
03068                    & (unsigned long)0x7e000000);
03069               insn |= (unsigned long)0x00f80000;
03070               bfd_put_32 (input_bfd, insn, contents + rel->r_offset);
03071 
03072               r_type = R_FRV_TLSMOFFHI;
03073               howto  = elf32_frv_howto_table + r_type;
03074               rel->r_info = ELF32_R_INFO (r_symndx, r_type);
03075              }
03076 
03077            else if (RELAX_TLSDESC_INITIAL_EXEC_P (info, picrel))
03078              {
03079               /* Replace lddi @(grB, #gottlsdesc12(symbol+offset), grC
03080                  with ldi @(grB, #gottlsoff12(symbol+offset),
03081                  gr<C+1>.  Preserve the packing bit.  If gottlsoff12
03082                  overflows, we'll error out, but that's sort-of ok,
03083                  since we'd started with gottlsdesc12, that's actually
03084                  more demanding.  Compiling with -fPIE instead of
03085                  -fpie would fix it; linking with --relax should fix
03086                  it as well.  */
03087               insn = (insn & (unsigned long)0x80cbf000)
03088                 | ((insn + (unsigned long)0x02000000)
03089                    & (unsigned long)0x7e000000);
03090               bfd_put_32 (input_bfd, insn, contents + rel->r_offset);
03091 
03092               r_type = R_FRV_GOTTLSOFF12;
03093               howto  = elf32_frv_howto_table + r_type;
03094               rel->r_info = ELF32_R_INFO (r_symndx, r_type);
03095              }
03096 
03097            break;
03098 
03099          case R_FRV_GOTTLSDESCHI:
03100            insn = bfd_get_32 (input_bfd, contents + rel->r_offset);
03101 
03102            /* Is this a sethi instruction?  */
03103            if ((insn & (unsigned long)0x01ff0000) != 0x00f80000)
03104              {
03105               r = info->callbacks->warning
03106                 (info,
03107                  _("R_FRV_GOTTLSDESCHI not applied to a sethi instruction"),
03108                  name, input_bfd, input_section, rel->r_offset);
03109               return FALSE;
03110              }
03111 
03112            if (RELAX_TLSDESC_LOCAL_EXEC_P (info, picrel,
03113                                        relocation + rel->r_addend)
03114               || (RELAX_TLSDESC_INITIAL_EXEC_P (info, picrel)
03115                   && IN_RANGE_FOR_SETLOS_P (picrel->tlsoff_entry)))
03116              {
03117               /* Replace sethi with a nop.  Preserve the packing bit.  */
03118               insn &= (unsigned long)0x80000000;
03119               insn |= (unsigned long)0x00880000;
03120               bfd_put_32 (input_bfd, insn, contents + rel->r_offset);
03121 
03122               /* Nothing to relocate.  */
03123               continue;
03124              }
03125 
03126            else if (RELAX_TLSDESC_INITIAL_EXEC_P (info, picrel))
03127              {
03128               /* Simply decay GOTTLSDESC to GOTTLSOFF.  */
03129               r_type = R_FRV_GOTTLSOFFHI;
03130               howto  = elf32_frv_howto_table + r_type;
03131               rel->r_info = ELF32_R_INFO (r_symndx, r_type);
03132              }
03133 
03134            break;
03135 
03136          case R_FRV_GOTTLSDESCLO:
03137            insn = bfd_get_32 (input_bfd, contents + rel->r_offset);
03138 
03139            /* Is this a setlo or setlos instruction?  */
03140            if ((insn & (unsigned long)0x01f70000) != 0x00f40000)
03141              {
03142               r = info->callbacks->warning
03143                 (info,
03144                  _("R_FRV_GOTTLSDESCLO"
03145                    " not applied to a setlo or setlos instruction"),
03146                  name, input_bfd, input_section, rel->r_offset);
03147               return FALSE;
03148              }
03149 
03150            if (RELAX_TLSDESC_LOCAL_EXEC_P (info, picrel,
03151                                        relocation + rel->r_addend)
03152               || (RELAX_TLSDESC_INITIAL_EXEC_P (info, picrel)
03153                   && IN_RANGE_FOR_OFST12_P (picrel->tlsoff_entry)))
03154              {
03155               /* Replace setlo/setlos with a nop.  Preserve the
03156                  packing bit.  */
03157               insn &= (unsigned long)0x80000000;
03158               insn |= (unsigned long)0x00880000;
03159               bfd_put_32 (input_bfd, insn, contents + rel->r_offset);
03160 
03161               /* Nothing to relocate.  */
03162               continue;
03163              }
03164 
03165            else if (RELAX_TLSDESC_INITIAL_EXEC_P (info, picrel))
03166              {
03167               /* If the corresponding sethi (if it exists) decayed
03168                  to a nop, make sure this becomes (or already is) a
03169                  setlos, not setlo.  */
03170               if (IN_RANGE_FOR_SETLOS_P (picrel->tlsoff_entry))
03171                 {
03172                   insn |= (unsigned long)0x00080000;
03173                   bfd_put_32 (input_bfd, insn, contents + rel->r_offset);
03174                 }
03175 
03176               /* Simply decay GOTTLSDESC to GOTTLSOFF.  */
03177               r_type = R_FRV_GOTTLSOFFLO;
03178               howto  = elf32_frv_howto_table + r_type;
03179               rel->r_info = ELF32_R_INFO (r_symndx, r_type);
03180              }
03181 
03182            break;
03183 
03184          case R_FRV_TLSDESC_RELAX:
03185            insn = bfd_get_32 (input_bfd, contents + rel->r_offset);
03186 
03187            /* Is this an ldd instruction?  */
03188            if ((insn & (unsigned long)0x01fc0fc0) != 0x00080140)
03189              {
03190               r = info->callbacks->warning
03191                 (info,
03192                  _("R_FRV_TLSDESC_RELAX not applied to an ldd instruction"),
03193                  name, input_bfd, input_section, rel->r_offset);
03194               return FALSE;
03195              }
03196 
03197            if (RELAX_TLSDESC_LOCAL_EXEC_P (info, picrel,
03198                                        relocation + rel->r_addend)
03199               && TLSMOFF_IN_RANGE_FOR_SETLOS_P (relocation + rel->r_addend,
03200                                             info))
03201              {
03202               /* Replace ldd #tlsdesc(symbol+offset)@(grB, grA), grC
03203                  with setlos #tlsmofflo(symbol+offset), gr<C+1>.
03204                  Preserve the packing bit.  */
03205               insn = (insn & (unsigned long)0x80000000)
03206                 | ((insn + (unsigned long)0x02000000)
03207                    & (unsigned long)0x7e000000);
03208               insn |= (unsigned long)0x00fc0000;
03209               bfd_put_32 (input_bfd, insn, contents + rel->r_offset);
03210 
03211               r_type = R_FRV_TLSMOFFLO;
03212               howto  = elf32_frv_howto_table + r_type;
03213               rel->r_info = ELF32_R_INFO (r_symndx, r_type);
03214              }
03215 
03216            else if (RELAX_TLSDESC_LOCAL_EXEC_P (info, picrel,
03217                                            relocation + rel->r_addend))
03218              {
03219               /* Replace ldd #tlsdesc(symbol+offset)@(grB, grA), grC
03220                  with sethi #tlsmoffhi(symbol+offset), gr<C+1>.
03221                  Preserve the packing bit.  */
03222               insn = (insn & (unsigned long)0x80000000)
03223                 | ((insn + (unsigned long)0x02000000)
03224                    & (unsigned long)0x7e000000);
03225               insn |= (unsigned long)0x00f80000;
03226               bfd_put_32 (input_bfd, insn, contents + rel->r_offset);
03227 
03228               r_type = R_FRV_TLSMOFFHI;
03229               howto  = elf32_frv_howto_table + r_type;
03230               rel->r_info = ELF32_R_INFO (r_symndx, r_type);
03231              }
03232 
03233            else if (RELAX_TLSDESC_INITIAL_EXEC_P (info, picrel)
03234                    && IN_RANGE_FOR_OFST12_P (picrel->tlsoff_entry))
03235              {
03236               /* Replace ldd #tlsdesc(symbol+offset)@(grB, grA), grC
03237                  with ldi @(grB, #gottlsoff12(symbol+offset), gr<C+1>.
03238                  Preserve the packing bit.  */
03239               insn = (insn & (unsigned long)0x8003f000)
03240                 | (unsigned long)0x00c80000
03241                 | ((insn + (unsigned long)0x02000000)
03242                    & (unsigned long)0x7e000000);
03243               bfd_put_32 (input_bfd, insn, contents + rel->r_offset);
03244 
03245               r_type = R_FRV_GOTTLSOFF12;
03246               howto  = elf32_frv_howto_table + r_type;
03247               rel->r_info = ELF32_R_INFO (r_symndx, r_type);
03248              }
03249 
03250            else if (RELAX_TLSDESC_INITIAL_EXEC_P (info, picrel))
03251              {
03252               /* Replace ldd #tlsdesc(symbol+offset)@(grB, grA), grC
03253                  with ld #tlsoff(symbol+offset)@(grB, grA), gr<C+1>.
03254                  Preserve the packing bit.  */
03255               insn = (insn & (unsigned long)0x81ffffbf)
03256                 | ((insn + (unsigned long)0x02000000)
03257                    & (unsigned long)0x7e000000);
03258               bfd_put_32 (input_bfd, insn, contents + rel->r_offset);
03259 
03260               /* #tlsoff(symbol+offset) is just a relaxation
03261                     annotation, so there's nothing left to
03262                     relocate.  */
03263               continue;
03264              }
03265 
03266            break;
03267 
03268          case R_FRV_GETTLSOFF_RELAX:
03269            insn = bfd_get_32 (input_bfd, contents + rel->r_offset);
03270 
03271            /* Is this a calll or callil instruction?  */
03272            if ((insn & (unsigned long)0x7ff80fc0) != 0x02300000)
03273              {
03274               r = info->callbacks->warning
03275                 (info,
03276                  _("R_FRV_GETTLSOFF_RELAX"
03277                    " not applied to a calll instruction"),
03278                  name, input_bfd, input_section, rel->r_offset);
03279               return FALSE;
03280              }
03281 
03282            if (RELAX_TLSDESC_LOCAL_EXEC_P (info, picrel,
03283                                        relocation + rel->r_addend)
03284               && TLSMOFF_IN_RANGE_FOR_SETLOS_P (relocation + rel->r_addend,
03285                                             info))
03286              {
03287               /* Replace calll with a nop.  Preserve the packing bit.  */
03288               insn &= (unsigned long)0x80000000;
03289               insn |= (unsigned long)0x00880000;
03290               bfd_put_32 (input_bfd, insn, contents + rel->r_offset);
03291 
03292               /* Nothing to relocate.  */
03293               continue;
03294              }
03295 
03296            else if (RELAX_TLSDESC_LOCAL_EXEC_P (info, picrel,
03297                                            relocation + rel->r_addend))
03298              {
03299               /* Replace calll with setlo #tlsmofflo(symbol+offset), gr9.
03300                  Preserve the packing bit.  */
03301               insn &= (unsigned long)0x80000000;
03302               insn |= (unsigned long)0x12f40000;
03303               bfd_put_32 (input_bfd, insn, contents + rel->r_offset);
03304 
03305               r_type = R_FRV_TLSMOFFLO;
03306               howto  = elf32_frv_howto_table + r_type;
03307               rel->r_info = ELF32_R_INFO (r_symndx, r_type);
03308              }
03309 
03310            else if (RELAX_TLSDESC_INITIAL_EXEC_P (info, picrel))
03311              {
03312               /* Replace calll with a nop.  Preserve the packing bit.  */
03313               insn &= (unsigned long)0x80000000;
03314               insn |= (unsigned long)0x00880000;
03315               bfd_put_32 (input_bfd, insn, contents + rel->r_offset);
03316 
03317               /* Nothing to relocate.  */
03318               continue;
03319              }
03320 
03321            break;
03322 
03323          case R_FRV_GOTTLSOFF12:
03324            insn = bfd_get_32 (input_bfd, contents + rel->r_offset);
03325 
03326            /* Is this an ldi instruction?  */
03327            if ((insn & (unsigned long)0x01fc0000) != 0x00c80000)
03328              {
03329               r = info->callbacks->warning
03330                 (info,
03331                  _("R_FRV_GOTTLSOFF12 not applied to an ldi instruction"),
03332                  name, input_bfd, input_section, rel->r_offset);
03333               return FALSE;
03334              }
03335 
03336            if (RELAX_GOTTLSOFF_LOCAL_EXEC_P (info, picrel,
03337                                          relocation + rel->r_addend))
03338              {
03339               /* Replace ldi @(grB, #gottlsoff12(symbol+offset), grC
03340                  with setlos #tlsmofflo(symbol+offset), grC.
03341                  Preserve the packing bit.  */
03342               insn &= (unsigned long)0xfe000000;
03343               insn |= (unsigned long)0x00fc0000;
03344               bfd_put_32 (input_bfd, insn, contents + rel->r_offset);
03345 
03346               r_type = R_FRV_TLSMOFFLO;
03347               howto  = elf32_frv_howto_table + r_type;
03348               rel->r_info = ELF32_R_INFO (r_symndx, r_type);
03349              }
03350 
03351            break;
03352 
03353          case R_FRV_GOTTLSOFFHI:
03354            insn = bfd_get_32 (input_bfd, contents + rel->r_offset);
03355 
03356            /* Is this a sethi instruction?  */
03357            if ((insn & (unsigned long)0x01ff0000) != 0x00f80000)
03358              {
03359               r = info->callbacks->warning
03360                 (info,
03361                  _("R_FRV_GOTTLSOFFHI not applied to a sethi instruction"),
03362                  name, input_bfd, input_section, rel->r_offset);
03363               return FALSE;
03364              }
03365 
03366            if (RELAX_GOTTLSOFF_LOCAL_EXEC_P (info, picrel,
03367                                          relocation + rel->r_addend)
03368               || (RELAX_TLSDESC_INITIAL_EXEC_P (info, picrel)
03369                   && IN_RANGE_FOR_OFST12_P (picrel->tlsoff_entry)))
03370              {
03371               /* Replace sethi with a nop.  Preserve the packing bit.  */
03372               insn &= (unsigned long)0x80000000;
03373               insn |= (unsigned long)0x00880000;
03374               bfd_put_32 (input_bfd, insn, contents + rel->r_offset);
03375 
03376               /* Nothing to relocate.  */
03377               continue;
03378              }
03379 
03380            break;
03381 
03382          case R_FRV_GOTTLSOFFLO:
03383            insn = bfd_get_32 (input_bfd, contents + rel->r_offset);
03384 
03385            /* Is this a setlo or setlos instruction?  */
03386            if ((insn & (unsigned long)0x01f70000) != 0x00f40000)
03387              {
03388               r = info->callbacks->warning
03389                 (info,
03390                  _("R_FRV_GOTTLSOFFLO"
03391                    " not applied to a setlo or setlos instruction"),
03392                  name, input_bfd, input_section, rel->r_offset);
03393               return FALSE;
03394              }
03395 
03396            if (RELAX_GOTTLSOFF_LOCAL_EXEC_P (info, picrel,
03397                                          relocation + rel->r_addend)
03398               || (RELAX_TLSDESC_INITIAL_EXEC_P (info, picrel)
03399                   && IN_RANGE_FOR_OFST12_P (picrel->tlsoff_entry)))
03400              {
03401               /* Replace setlo/setlos with a nop.  Preserve the
03402                  packing bit.  */
03403               insn &= (unsigned long)0x80000000;
03404               insn |= (unsigned long)0x00880000;
03405               bfd_put_32 (input_bfd, insn, contents + rel->r_offset);
03406 
03407               /* Nothing to relocate.  */
03408               continue;
03409              }
03410 
03411            break;
03412 
03413          case R_FRV_TLSOFF_RELAX:
03414            insn = bfd_get_32 (input_bfd, contents + rel->r_offset);
03415 
03416            /* Is this an ld instruction?  */
03417            if ((insn & (unsigned long)0x01fc0fc0) != 0x00080100)
03418              {
03419               r = info->callbacks->warning
03420                 (info,
03421                  _("R_FRV_TLSOFF_RELAX not applied to an ld instruction"),
03422                  name, input_bfd, input_section, rel->r_offset);
03423               return FALSE;
03424              }
03425 
03426            if (RELAX_GOTTLSOFF_LOCAL_EXEC_P (info, picrel,
03427                                          relocation + rel->r_addend))
03428              {
03429               /* Replace ld #gottlsoff(symbol+offset)@(grB, grA), grC
03430                  with setlos #tlsmofflo(symbol+offset), grC.
03431                  Preserve the packing bit.  */
03432               insn &= (unsigned long)0xfe000000;
03433               insn |= (unsigned long)0x00fc0000;
03434               bfd_put_32 (input_bfd, insn, contents + rel->r_offset);
03435 
03436               r_type = R_FRV_TLSMOFFLO;
03437               howto  = elf32_frv_howto_table + r_type;
03438               rel->r_info = ELF32_R_INFO (r_symndx, r_type);
03439              }
03440 
03441            else if (RELAX_TLSDESC_INITIAL_EXEC_P (info, picrel)
03442                    && IN_RANGE_FOR_OFST12_P (picrel->tlsoff_entry))
03443              {
03444               /* Replace ld #tlsoff(symbol+offset)@(grB, grA), grC
03445                  with ldi @(grB, #gottlsoff12(symbol+offset), grC.
03446                  Preserve the packing bit.  */
03447               insn = (insn & (unsigned long)0xfe03f000)
03448                 | (unsigned long)0x00c80000;;
03449               bfd_put_32 (input_bfd, insn, contents + rel->r_offset);
03450 
03451               r_type = R_FRV_GOTTLSOFF12;
03452               howto  = elf32_frv_howto_table + r_type;
03453               rel->r_info = ELF32_R_INFO (r_symndx, r_type);
03454              }
03455 
03456            break;
03457 
03458          case R_FRV_TLSMOFFHI:
03459            insn = bfd_get_32 (input_bfd, contents + rel->r_offset);
03460 
03461            /* Is this a sethi instruction?  */
03462            if ((insn & (unsigned long)0x01ff0000) != 0x00f80000)
03463              {
03464               r = info->callbacks->warning
03465                 (info,
03466                  _("R_FRV_TLSMOFFHI not applied to a sethi instruction"),
03467                  name, input_bfd, input_section, rel->r_offset);
03468               return FALSE;
03469              }
03470 
03471            if (TLSMOFF_IN_RANGE_FOR_SETLOS_P (relocation + rel->r_addend,
03472                                           info))
03473              {
03474               /* Replace sethi with a nop.  Preserve the packing bit.  */
03475               insn &= (unsigned long)0x80000000;
03476               insn |= (unsigned long)0x00880000;
03477               bfd_put_32 (input_bfd, insn, contents + rel->r_offset);
03478 
03479               /* Nothing to relocate.  */
03480               continue;
03481              }
03482 
03483            break;
03484 
03485          case R_FRV_TLSMOFFLO:
03486            insn = bfd_get_32 (input_bfd, contents + rel->r_offset);
03487 
03488            /* Is this a setlo or setlos instruction?  */
03489            if ((insn & (unsigned long)0x01f70000) != 0x00f40000)
03490              {
03491               r = info->callbacks->warning
03492                 (info,
03493                  _("R_FRV_TLSMOFFLO"
03494                    " not applied to a setlo or setlos instruction"),
03495                  name, input_bfd, input_section, rel->r_offset);
03496               return FALSE;
03497              }
03498 
03499            if (TLSMOFF_IN_RANGE_FOR_SETLOS_P (relocation + rel->r_addend,
03500                                           info))
03501              /* If the corresponding sethi (if it exists) decayed
03502                to a nop, make sure this becomes (or already is) a
03503                setlos, not setlo.  */
03504              {
03505               insn |= (unsigned long)0x00080000;
03506               bfd_put_32 (input_bfd, insn, contents + rel->r_offset);
03507              }
03508 
03509            break;
03510 
03511            /*
03512              There's nothing to relax in these:
03513               R_FRV_TLSDESC_VALUE
03514               R_FRV_TLSOFF
03515               R_FRV_TLSMOFF12
03516               R_FRV_TLSMOFFHI
03517               R_FRV_TLSMOFFLO
03518               R_FRV_TLSMOFF
03519            */
03520 
03521          default:
03522            break;
03523          }
03524 
03525       switch (r_type)
03526        {
03527        case R_FRV_LABEL24:
03528          check_segment[0] = isec_segment;
03529          if (! IS_FDPIC (output_bfd))
03530            check_segment[1] = isec_segment;
03531          else if (picrel->plt)
03532            {
03533              relocation = frvfdpic_plt_section (info)->output_section->vma
03534               + frvfdpic_plt_section (info)->output_offset
03535               + picrel->plt_entry;
03536              check_segment[1] = plt_segment;
03537            }
03538          /* We don't want to warn on calls to undefined weak symbols,
03539             as calls to them must be protected by non-NULL tests
03540             anyway, and unprotected calls would invoke undefined
03541             behavior.  */
03542          else if (picrel->symndx == -1
03543                  && picrel->d.h->root.type == bfd_link_hash_undefweak)
03544            check_segment[1] = check_segment[0];
03545          else
03546            check_segment[1] = sec
03547              ? _frvfdpic_osec_to_segment (output_bfd, sec->output_section)
03548              : (unsigned)-1;
03549          break;
03550 
03551        case R_FRV_GOT12:
03552        case R_FRV_GOTHI:
03553        case R_FRV_GOTLO:
03554          relocation = picrel->got_entry;
03555          check_segment[0] = check_segment[1] = got_segment;
03556          break;
03557 
03558        case R_FRV_FUNCDESC_GOT12:
03559        case R_FRV_FUNCDESC_GOTHI:
03560        case R_FRV_FUNCDESC_GOTLO:
03561          relocation = picrel->fdgot_entry;
03562          check_segment[0] = check_segment[1] = got_segment;
03563          break;
03564 
03565        case R_FRV_GOTOFFHI:
03566        case R_FRV_GOTOFF12:
03567        case R_FRV_GOTOFFLO:
03568          relocation -= frvfdpic_got_section (info)->output_section->vma
03569            + frvfdpic_got_section (info)->output_offset
03570            + frvfdpic_got_initial_offset (info);
03571          check_segment[0] = got_segment;
03572          check_segment[1] = sec
03573            ? _frvfdpic_osec_to_segment (output_bfd, sec->output_section)
03574            : (unsigned)-1;
03575          break;
03576 
03577        case R_FRV_FUNCDESC_GOTOFF12:
03578        case R_FRV_FUNCDESC_GOTOFFHI:
03579        case R_FRV_FUNCDESC_GOTOFFLO:
03580          relocation = picrel->fd_entry;
03581          check_segment[0] = check_segment[1] = got_segment;
03582          break;
03583 
03584        case R_FRV_FUNCDESC:
03585          {
03586            int dynindx;
03587            bfd_vma addend = rel->r_addend;
03588 
03589            if (! (h && h->root.type == bfd_link_hash_undefweak
03590                  && FRVFDPIC_SYM_LOCAL (info, h)))
03591              {
03592               /* If the symbol is dynamic and there may be dynamic
03593                  symbol resolution because we are or are linked with a
03594                  shared library, emit a FUNCDESC relocation such that
03595                  the dynamic linker will allocate the function
03596                  descriptor.  If the symbol needs a non-local function
03597                  descriptor but binds locally (e.g., its visibility is
03598                  protected, emit a dynamic relocation decayed to
03599                  section+offset.  */
03600               if (h && ! FRVFDPIC_FUNCDESC_LOCAL (info, h)
03601                   && FRVFDPIC_SYM_LOCAL (info, h)
03602                   && !(info->executable && !info->pie))
03603                 {
03604                   dynindx = elf_section_data (h->root.u.def.section
03605                                           ->output_section)->dynindx;
03606                   addend += h->root.u.def.section->output_offset
03607                     + h->root.u.def.value;
03608                 }
03609               else if (h && ! FRVFDPIC_FUNCDESC_LOCAL (info, h))
03610                 {
03611                   if (addend)
03612                     {
03613                      info->callbacks->warning
03614                        (info, _("R_FRV_FUNCDESC references dynamic symbol with nonzero addend"),
03615                         name, input_bfd, input_section, rel->r_offset);
03616                      return FALSE;
03617                     }
03618                   dynindx = h->dynindx;
03619                 }
03620               else
03621                 {
03622                   /* Otherwise, we know we have a private function
03623                      descriptor, so reference it directly.  */
03624                   BFD_ASSERT (picrel->privfd);
03625                   r_type = R_FRV_32;
03626                   dynindx = elf_section_data (frvfdpic_got_section (info)
03627                                           ->output_section)->dynindx;
03628                   addend = frvfdpic_got_section (info)->output_offset
03629                     + frvfdpic_got_initial_offset (info)
03630                     + picrel->fd_entry;
03631                 }
03632 
03633               /* If there is room for dynamic symbol resolution, emit
03634                  the dynamic relocation.  However, if we're linking an
03635                  executable at a fixed location, we won't have emitted a
03636                  dynamic symbol entry for the got section, so idx will
03637                  be zero, which means we can and should compute the
03638                  address of the private descriptor ourselves.  */
03639               if (info->executable && !info->pie
03640                   && (!h || FRVFDPIC_FUNCDESC_LOCAL (info, h)))
03641                 {
03642                   addend += frvfdpic_got_section (info)->output_section->vma;
03643                   if ((bfd_get_section_flags (output_bfd,
03644                                           input_section->output_section)
03645                       & (SEC_ALLOC | SEC_LOAD)) == (SEC_ALLOC | SEC_LOAD))
03646                     {
03647                      if (_frvfdpic_osec_readonly_p (output_bfd,
03648                                                  input_section
03649                                                  ->output_section))
03650                        {
03651                          info->callbacks->warning
03652                            (info,
03653                             _("cannot emit fixups in read-only section"),
03654                             name, input_bfd, input_section, rel->r_offset);
03655                          return FALSE;
03656                        }
03657                      _frvfdpic_add_rofixup (output_bfd,
03658                                           frvfdpic_gotfixup_section
03659                                           (info),
03660                                           _bfd_elf_section_offset
03661                                           (output_bfd, info,
03662                                           input_section, rel->r_offset)
03663                                           + input_section
03664                                           ->output_section->vma
03665                                           + input_section->output_offset,
03666                                           picrel);
03667                     }
03668                 }
03669               else if ((bfd_get_section_flags (output_bfd,
03670                                            input_section->output_section)
03671                        & (SEC_ALLOC | SEC_LOAD)) == (SEC_ALLOC | SEC_LOAD))
03672                 {
03673                   if (_frvfdpic_osec_readonly_p (output_bfd,
03674                                              input_section
03675                                              ->output_section))
03676                     {
03677                      info->callbacks->warning
03678                        (info,
03679                         _("cannot emit dynamic relocations in read-only section"),
03680                         name, input_bfd, input_section, rel->r_offset);
03681                      return FALSE;
03682                     }
03683                   _frvfdpic_add_dyn_reloc (output_bfd,
03684                                         frvfdpic_gotrel_section (info),
03685                                         _bfd_elf_section_offset
03686                                         (output_bfd, info,
03687                                          input_section, rel->r_offset)
03688                                         + input_section
03689                                         ->output_section->vma
03690                                         + input_section->output_offset,
03691                                         r_type, dynindx, addend, picrel);
03692                 }
03693               else
03694                 addend += frvfdpic_got_section (info)->output_section->vma;
03695              }
03696 
03697            /* We want the addend in-place because dynamic
03698               relocations are REL.  Setting relocation to it should
03699               arrange for it to be installed.  */
03700            relocation = addend - rel->r_addend;
03701          }
03702          check_segment[0] = check_segment[1] = got_segment;
03703          break;
03704 
03705        case R_FRV_32:
03706          if (! IS_FDPIC (output_bfd))
03707            {
03708              check_segment[0] = check_segment[1] = -1;
03709              break;
03710            }
03711          /* Fall through.  */
03712        case R_FRV_FUNCDESC_VALUE:
03713          {
03714            int dynindx;
03715            bfd_vma addend = rel->r_addend;
03716 
03717            /* If the symbol is dynamic but binds locally, use
03718               section+offset.  */
03719            if (h && ! FRVFDPIC_SYM_LOCAL (info, h))
03720              {
03721               if (addend && r_type == R_FRV_FUNCDESC_VALUE)
03722                 {
03723                   info->callbacks->warning
03724                     (info, _("R_FRV_FUNCDESC_VALUE references dynamic symbol with nonzero addend"),
03725                      name, input_bfd, input_section, rel->r_offset);
03726                   return FALSE;
03727                 }
03728               dynindx = h->dynindx;
03729              }
03730            else
03731              {
03732               if (h)
03733                 addend += h->root.u.def.value;
03734               else
03735                 addend += sym->st_value;
03736               if (osec)
03737                 addend += osec->output_offset;
03738               if (osec && osec->output_section
03739                   && ! bfd_is_abs_section (osec->output_section)
03740                   && ! bfd_is_und_section (osec->output_section))
03741                 dynindx = elf_section_data (osec->output_section)->dynindx;
03742               else
03743                 dynindx = 0;
03744              }
03745 
03746            /* If we're linking an executable at a fixed address, we
03747               can omit the dynamic relocation as long as the symbol
03748               is defined in the current link unit (which is implied
03749               by its output section not being NULL).  */
03750            if (info->executable && !info->pie
03751               && (!h || FRVFDPIC_SYM_LOCAL (info, h)))
03752              {
03753               if (osec)
03754                 addend += osec->output_section->vma;
03755               if (IS_FDPIC (input_bfd)
03756                   && (bfd_get_section_flags (output_bfd,
03757                                           input_section->output_section)
03758                      & (SEC_ALLOC | SEC_LOAD)) == (SEC_ALLOC | SEC_LOAD))
03759                 {
03760                   if (_frvfdpic_osec_readonly_p (output_bfd,
03761                                              input_section
03762                                              ->output_section))
03763                     {
03764                      info->callbacks->warning
03765                        (info,
03766                         _("cannot emit fixups in read-only section"),
03767                         name, input_bfd, input_section, rel->r_offset);
03768                      return FALSE;
03769                     }
03770                   if (!h || h->root.type != bfd_link_hash_undefweak)
03771                     {
03772                      _frvfdpic_add_rofixup (output_bfd,
03773                                           frvfdpic_gotfixup_section
03774                                           (info),
03775                                           _bfd_elf_section_offset
03776                                           (output_bfd, info,
03777                                           input_section, rel->r_offset)
03778                                           + input_section
03779                                           ->output_section->vma
03780                                           + input_section->output_offset,
03781                                           picrel);
03782                      if (r_type == R_FRV_FUNCDESC_VALUE)
03783                        _frvfdpic_add_rofixup
03784                          (output_bfd,
03785                           frvfdpic_gotfixup_section (info),
03786                           _bfd_elf_section_offset
03787                           (output_bfd, info,
03788                            input_section, rel->r_offset)
03789                           + input_section->output_section->vma
03790                           + input_section->output_offset + 4, picrel);
03791                     }
03792                 }
03793              }
03794            else
03795              {
03796               if ((bfd_get_section_flags (output_bfd,
03797                                        input_section->output_section)
03798                    & (SEC_ALLOC | SEC_LOAD)) == (SEC_ALLOC | SEC_LOAD))
03799                 {
03800                   if (_frvfdpic_osec_readonly_p (output_bfd,
03801                                              input_section
03802                                              ->output_section))
03803                     {
03804                      info->callbacks->warning
03805                        (info,
03806                         _("cannot emit dynamic relocations in read-only section"),
03807                         name, input_bfd, input_section, rel->r_offset);
03808                      return FALSE;
03809                     }
03810                   _frvfdpic_add_dyn_reloc (output_bfd,
03811                                         frvfdpic_gotrel_section (info),
03812                                         _bfd_elf_section_offset
03813                                         (output_bfd, info,
03814                                          input_section, rel->r_offset)
03815                                         + input_section
03816                                         ->output_section->vma
03817                                         + input_section->output_offset,
03818                                         r_type, dynindx, addend, picrel);
03819                 }
03820               else if (osec)
03821                 addend += osec->output_section->vma;
03822               /* We want the addend in-place because dynamic
03823                  relocations are REL.  Setting relocation to it
03824                  should arrange for it to be installed.  */
03825               relocation = addend - rel->r_addend;
03826              }
03827 
03828            if (r_type == R_FRV_FUNCDESC_VALUE)
03829              {
03830               /* If we've omitted the dynamic relocation, just emit
03831                  the fixed addresses of the symbol and of the local
03832                  GOT base offset.  */
03833               if (info->executable && !info->pie
03834                   && (!h || FRVFDPIC_SYM_LOCAL (info, h)))
03835                 bfd_put_32 (output_bfd,
03836                            frvfdpic_got_section (info)->output_section->vma
03837                            + frvfdpic_got_section (info)->output_offset
03838                            + frvfdpic_got_initial_offset (info),
03839                            contents + rel->r_offset + 4);
03840               else
03841                 /* A function descriptor used for lazy or local
03842                    resolving is initialized such that its high word
03843                    contains the output section index in which the
03844                    PLT entries are located, and the low word
03845                    contains the offset of the lazy PLT entry entry
03846                    point into that section.  */
03847                 bfd_put_32 (output_bfd,
03848                            h && ! FRVFDPIC_SYM_LOCAL (info, h)
03849                            ? 0
03850                            : _frvfdpic_osec_to_segment (output_bfd,
03851                                                     sec
03852                                                     ->output_section),
03853                            contents + rel->r_offset + 4);
03854              }
03855          }
03856          check_segment[0] = check_segment[1] = got_segment;
03857          break;
03858 
03859        case R_FRV_GPREL12:
03860        case R_FRV_GPRELU12:
03861        case R_FRV_GPREL32:
03862        case R_FRV_GPRELHI:
03863        case R_FRV_GPRELLO:
03864          check_segment[0] = gprel_segment;
03865          check_segment[1] = sec
03866            ? _frvfdpic_osec_to_segment (output_bfd, sec->output_section)
03867            : (unsigned)-1;
03868          break;
03869 
03870        case R_FRV_GETTLSOFF:
03871          relocation = frvfdpic_plt_section (info)->output_section->vma
03872            + frvfdpic_plt_section (info)->output_offset
03873            + picrel->tlsplt_entry;
03874          BFD_ASSERT (picrel->tlsplt_entry != (bfd_vma)-1
03875                     && picrel->tlsdesc_entry);
03876          check_segment[0] = isec_segment;
03877          check_segment[1] = plt_segment;
03878          break;
03879 
03880        case R_FRV_GOTTLSDESC12:
03881        case R_FRV_GOTTLSDESCHI:
03882        case R_FRV_GOTTLSDESCLO:
03883          BFD_ASSERT (picrel->tlsdesc_entry);
03884          relocation = picrel->tlsdesc_entry;
03885          check_segment[0] = tls_segment;
03886          check_segment[1] = sec
03887            && ! bfd_is_abs_section (sec)
03888            && ! bfd_is_und_section (sec)
03889            ? _frvfdpic_osec_to_segment (output_bfd, sec->output_section)
03890            : tls_segment;
03891          break;
03892 
03893        case R_FRV_TLSMOFF12:
03894        case R_FRV_TLSMOFFHI:
03895        case R_FRV_TLSMOFFLO:
03896        case R_FRV_TLSMOFF:
03897          check_segment[0] = tls_segment;
03898          if (! sec)
03899            check_segment[1] = -1;
03900          else if (bfd_is_abs_section (sec)
03901                  || bfd_is_und_section (sec))
03902            {
03903              relocation = 0;
03904              check_segment[1] = tls_segment;
03905            }
03906          else if (sec->output_section)
03907            {
03908              relocation -= tls_biased_base (info);
03909              check_segment[1] =
03910               _frvfdpic_osec_to_segment (output_bfd, sec->output_section);
03911            }
03912          else
03913            check_segment[1] = -1;
03914          break;
03915 
03916        case R_FRV_GOTTLSOFF12:
03917        case R_FRV_GOTTLSOFFHI:
03918        case R_FRV_GOTTLSOFFLO:
03919          BFD_ASSERT (picrel->tlsoff_entry);
03920          relocation = picrel->tlsoff_entry;
03921          check_segment[0] = tls_segment;
03922          check_segment[1] = sec
03923            && ! bfd_is_abs_section (sec)
03924            && ! bfd_is_und_section (sec)
03925            ? _frvfdpic_osec_to_segment (output_bfd, sec->output_section)
03926            : tls_segment;
03927          break;
03928 
03929        case R_FRV_TLSDESC_VALUE:
03930        case R_FRV_TLSOFF:
03931          /* These shouldn't be present in input object files.  */
03932          check_segment[0] = check_segment[1] = isec_segment;
03933          break;
03934 
03935        case R_FRV_TLSDESC_RELAX:
03936        case R_FRV_GETTLSOFF_RELAX:
03937        case R_FRV_TLSOFF_RELAX:
03938          /* These are just annotations for relaxation, nothing to do
03939             here.  */
03940          continue;
03941 
03942        default:
03943          check_segment[0] = isec_segment;
03944          check_segment[1] = sec
03945            ? _frvfdpic_osec_to_segment (output_bfd, sec->output_section)
03946            : (unsigned)-1;
03947          break;
03948        }
03949 
03950       if (check_segment[0] != check_segment[1] && IS_FDPIC (output_bfd))
03951        {
03952          /* If you take this out, remove the #error from fdpic-static-6.d
03953             in the ld testsuite.  */
03954          /* This helps catch problems in GCC while we can't do more
03955             than static linking.  The idea is to test whether the
03956             input file basename is crt0.o only once.  */
03957          if (silence_segment_error == 1)
03958            silence_segment_error =
03959              (strlen (input_bfd->filename) == 6
03960               && strcmp (input_bfd->filename, "crt0.o") == 0)
03961              || (strlen (input_bfd->filename) > 6
03962                 && strcmp (input_bfd->filename
03963                           + strlen (input_bfd->filename) - 7,
03964                           "/crt0.o") == 0)
03965              ? -1 : 0;
03966          if (!silence_segment_error
03967              /* We don't want duplicate errors for undefined
03968                symbols.  */
03969              && !(picrel && picrel->symndx == -1
03970                  && picrel->d.h->root.type == bfd_link_hash_undefined))
03971            {
03972              if (info->shared || info->pie)
03973               (*_bfd_error_handler)
03974                 (_("%B(%A+0x%lx): reloc against `%s': %s"),
03975                  input_bfd, input_section, (long)rel->r_offset, name,
03976                  _("relocation references a different segment"));
03977              else
03978               info->callbacks->warning
03979                 (info,
03980                  _("relocation references a different segment"),
03981                  name, input_bfd, input_section, rel->r_offset);
03982            }
03983          if (!silence_segment_error && (info->shared || info->pie))
03984            return FALSE;
03985          elf_elfheader (output_bfd)->e_flags |= EF_FRV_PIC;
03986        }
03987 
03988       switch (r_type)
03989        {
03990        case R_FRV_GOTOFFHI:
03991        case R_FRV_TLSMOFFHI:
03992          /* We need the addend to be applied before we shift the
03993             value right.  */
03994          relocation += rel->r_addend;
03995          /* Fall through.  */
03996        case R_FRV_GOTHI:
03997        case R_FRV_FUNCDESC_GOTHI:
03998        case R_FRV_FUNCDESC_GOTOFFHI:
03999        case R_FRV_GOTTLSOFFHI:
04000        case R_FRV_GOTTLSDESCHI:
04001          relocation >>= 16;
04002          /* Fall through.  */
04003 
04004        case R_FRV_GOTLO:
04005        case R_FRV_FUNCDESC_GOTLO:
04006        case R_FRV_GOTOFFLO:
04007        case R_FRV_FUNCDESC_GOTOFFLO:
04008        case R_FRV_GOTTLSOFFLO:
04009        case R_FRV_GOTTLSDESCLO:
04010        case R_FRV_TLSMOFFLO:
04011          relocation &= 0xffff;
04012          break;
04013 
04014        default:
04015          break;
04016        }
04017 
04018       switch (r_type)
04019        {
04020        case R_FRV_LABEL24:
04021          if (! IS_FDPIC (output_bfd) || ! picrel->plt)
04022            break;
04023          /* Fall through.  */
04024 
04025          /* When referencing a GOT entry, a function descriptor or a
04026             PLT, we don't want the addend to apply to the reference,
04027             but rather to the referenced symbol.  The actual entry
04028             will have already been created taking the addend into
04029             account, so cancel it out here.  */
04030        case R_FRV_GOT12:
04031        case R_FRV_GOTHI:
04032        case R_FRV_GOTLO:
04033        case R_FRV_FUNCDESC_GOT12:
04034        case R_FRV_FUNCDESC_GOTHI:
04035        case R_FRV_FUNCDESC_GOTLO:
04036        case R_FRV_FUNCDESC_GOTOFF12:
04037        case R_FRV_FUNCDESC_GOTOFFHI:
04038        case R_FRV_FUNCDESC_GOTOFFLO:
04039        case R_FRV_GETTLSOFF:
04040        case R_FRV_GOTTLSDESC12:
04041        case R_FRV_GOTTLSDESCHI:
04042        case R_FRV_GOTTLSDESCLO:
04043        case R_FRV_GOTTLSOFF12:
04044        case R_FRV_GOTTLSOFFHI:
04045        case R_FRV_GOTTLSOFFLO:
04046          /* Note that we only want GOTOFFHI, not GOTOFFLO or GOTOFF12
04047             here, since we do want to apply the addend to the others.
04048             Note that we've applied the addend to GOTOFFHI before we
04049             shifted it right.  */
04050        case R_FRV_GOTOFFHI:
04051        case R_FRV_TLSMOFFHI:
04052          relocation -= rel->r_addend;
04053          break;
04054 
04055        default:
04056          break;
04057        }
04058 
04059      if (r_type == R_FRV_HI16)
04060        r = elf32_frv_relocate_hi16 (input_bfd, rel, contents, relocation);
04061 
04062      else if (r_type == R_FRV_LO16)
04063        r = elf32_frv_relocate_lo16 (input_bfd, rel, contents, relocation);
04064 
04065      else if (r_type == R_FRV_LABEL24 || r_type == R_FRV_GETTLSOFF)
04066        r = elf32_frv_relocate_label24 (input_bfd, input_section, rel,
04067                                    contents, relocation);
04068 
04069      else if (r_type == R_FRV_GPREL12)
04070        r = elf32_frv_relocate_gprel12 (info, input_bfd, input_section, rel,
04071                                    contents, relocation);
04072 
04073      else if (r_type == R_FRV_GPRELU12)
04074        r = elf32_frv_relocate_gprelu12 (info, input_bfd, input_section, rel,
04075                                    contents, relocation);
04076 
04077      else if (r_type == R_FRV_GPRELLO)
04078        r = elf32_frv_relocate_gprello (info, input_bfd, input_section, rel,
04079                                    contents, relocation);
04080 
04081      else if (r_type == R_FRV_GPRELHI)
04082        r = elf32_frv_relocate_gprelhi (info, input_bfd, input_section, rel,
04083                                    contents, relocation);
04084 
04085      else if (r_type == R_FRV_TLSOFF
04086              || r_type == R_FRV_TLSDESC_VALUE)
04087        r = bfd_reloc_notsupported;
04088 
04089      else
04090        r = frv_final_link_relocate (howto, input_bfd, input_section, contents,
04091                                 rel, relocation);
04092 
04093       if (r != bfd_reloc_ok)
04094        {
04095          const char * msg = (const char *) NULL;
04096 
04097          switch (r)
04098            {
04099            case bfd_reloc_overflow:
04100              r = info->callbacks->reloc_overflow
04101               (info, (h ? &h->root : NULL), name, howto->name,
04102                (bfd_vma) 0, input_bfd, input_section, rel->r_offset);
04103              break;
04104 
04105            case bfd_reloc_undefined:
04106              r = info->callbacks->undefined_symbol
04107               (info, name, input_bfd, input_section, rel->r_offset, TRUE);
04108              break;
04109 
04110            case bfd_reloc_outofrange:
04111              msg = _("internal error: out of range error");
04112              break;
04113 
04114            case bfd_reloc_notsupported:
04115              msg = _("internal error: unsupported relocation error");
04116              break;
04117 
04118            case bfd_reloc_dangerous:
04119              msg = _("internal error: dangerous relocation");
04120              break;
04121 
04122            default:
04123              msg = _("internal error: unknown error");
04124              break;
04125            }
04126 
04127          if (msg)
04128            {
04129              (*_bfd_error_handler)
04130               (_("%B(%A+0x%lx): reloc against `%s': %s"),
04131                input_bfd, input_section, (long)rel->r_offset, name, msg);
04132              return FALSE;
04133            }
04134 
04135          if (! r)
04136            return FALSE;
04137        }
04138     }
04139 
04140   return TRUE;
04141 }
04142 
04143 /* Return the section that should be marked against GC for a given
04144    relocation.  */
04145 
04146 static asection *
04147 elf32_frv_gc_mark_hook (asection *sec,
04148                      struct bfd_link_info *info,
04149                      Elf_Internal_Rela *rel,
04150                      struct elf_link_hash_entry *h,
04151                      Elf_Internal_Sym *sym)
04152 {
04153   if (h != NULL)
04154     switch (ELF32_R_TYPE (rel->r_info))
04155       {
04156       case R_FRV_GNU_VTINHERIT:
04157       case R_FRV_GNU_VTENTRY:
04158        return NULL;
04159       }
04160 
04161   return _bfd_elf_gc_mark_hook (sec, info, rel, h, sym);
04162 }
04163 
04164 /* Hook called by the linker routine which adds symbols from an object
04165    file.  We use it to put .comm items in .scomm, and not .comm.  */
04166 
04167 static bfd_boolean
04168 elf32_frv_add_symbol_hook (abfd, info, sym, namep, flagsp, secp, valp)
04169      bfd *abfd;
04170      struct bfd_link_info *info;
04171      Elf_Internal_Sym *sym;
04172      const char **namep ATTRIBUTE_UNUSED;
04173      flagword *flagsp ATTRIBUTE_UNUSED;
04174      asection **secp;
04175      bfd_vma *valp;
04176 {
04177   if (sym->st_shndx == SHN_COMMON
04178       && !info->relocatable
04179       && (int)sym->st_size <= (int)bfd_get_gp_size (abfd))
04180     {
04181       /* Common symbols less than or equal to -G nn bytes are
04182         automatically put into .sbss.  */
04183 
04184       asection *scomm = bfd_get_section_by_name (abfd, ".scommon");
04185 
04186       if (scomm == NULL)
04187        {
04188          scomm = bfd_make_section_with_flags (abfd, ".scommon",
04189                                           (SEC_ALLOC
04190                                           | SEC_IS_COMMON
04191                                           | SEC_LINKER_CREATED));
04192          if (scomm == NULL)
04193            return FALSE;
04194        }
04195 
04196       *secp = scomm;
04197       *valp = sym->st_size;
04198     }
04199 
04200   return TRUE;
04201 }
04202 
04203 /* We need dynamic symbols for every section, since segments can
04204    relocate independently.  */
04205 static bfd_boolean
04206 _frvfdpic_link_omit_section_dynsym (bfd *output_bfd ATTRIBUTE_UNUSED,
04207                                 struct bfd_link_info *info
04208                                 ATTRIBUTE_UNUSED,
04209                                 asection *p ATTRIBUTE_UNUSED)
04210 {
04211   switch (elf_section_data (p)->this_hdr.sh_type)
04212     {
04213     case SHT_PROGBITS:
04214     case SHT_NOBITS:
04215       /* If sh_type is yet undecided, assume it could be
04216         SHT_PROGBITS/SHT_NOBITS.  */
04217     case SHT_NULL:
04218       return FALSE;
04219 
04220       /* There shouldn't be section relative relocations
04221         against any other section.  */
04222     default:
04223       return TRUE;
04224     }
04225 }
04226 
04227 /* Create  a .got section, as well as its additional info field.  This
04228    is almost entirely copied from
04229    elflink.c:_bfd_elf_create_got_section().  */
04230 
04231 static bfd_boolean
04232 _frv_create_got_section (bfd *abfd, struct bfd_link_info *info)
04233 {
04234   flagword flags, pltflags;
04235   asection *s;
04236   struct elf_link_hash_entry *h;
04237   struct bfd_link_hash_entry *bh;
04238   const struct elf_backend_data *bed = get_elf_backend_data (abfd);
04239   int ptralign;
04240   int offset;
04241 
04242   /* This function may be called more than once.  */
04243   s = bfd_get_section_by_name (abfd, ".got");
04244   if (s != NULL && (s->flags & SEC_LINKER_CREATED) != 0)
04245     return TRUE;
04246 
04247   /* Machine specific: although pointers are 32-bits wide, we want the
04248      GOT to be aligned to a 64-bit boundary, such that function
04249      descriptors in it can be accessed with 64-bit loads and
04250      stores.  */
04251   ptralign = 3;
04252 
04253   flags = (SEC_ALLOC | SEC_LOAD | SEC_HAS_CONTENTS | SEC_IN_MEMORY
04254           | SEC_LINKER_CREATED);
04255   pltflags = flags;
04256 
04257   s = bfd_make_section_with_flags (abfd, ".got", flags);
04258   if (s == NULL
04259       || !bfd_set_section_alignment (abfd, s, ptralign))
04260     return FALSE;
04261 
04262   if (bed->want_got_plt)
04263     {
04264       s = bfd_make_section_with_flags (abfd, ".got.plt", flags);
04265       if (s == NULL
04266          || !bfd_set_section_alignment (abfd, s, ptralign))
04267        return FALSE;
04268     }
04269 
04270   if (bed->want_got_sym)
04271     {
04272       /* Define the symbol _GLOBAL_OFFSET_TABLE_ at the start of the .got
04273         (or .got.plt) section.  We don't do this in the linker script
04274         because we don't want to define the symbol if we are not creating
04275         a global offset table.  */
04276       h = _bfd_elf_define_linkage_sym (abfd, info, s, "_GLOBAL_OFFSET_TABLE_");
04277       elf_hash_table (info)->hgot = h;
04278       if (h == NULL)
04279        return FALSE;
04280 
04281       /* Machine-specific: we want the symbol for executables as
04282         well.  */
04283       if (! bfd_elf_link_record_dynamic_symbol (info, h))
04284        return FALSE;
04285     }
04286 
04287   /* The first bit of the global offset table is the header.  */
04288   s->size += bed->got_header_size;
04289 
04290   /* This is the machine-specific part.  Create and initialize section
04291      data for the got.  */
04292   if (IS_FDPIC (abfd))
04293     {
04294       frvfdpic_got_section (info) = s;
04295       frvfdpic_relocs_info (info) = htab_try_create (1,
04296                                                frvfdpic_relocs_info_hash,
04297                                                frvfdpic_relocs_info_eq,
04298                                                (htab_del) NULL);
04299       if (! frvfdpic_relocs_info (info))
04300        return FALSE;
04301 
04302       s = bfd_make_section_with_flags (abfd, ".rel.got",
04303                                    (flags | SEC_READONLY));
04304       if (s == NULL
04305          || ! bfd_set_section_alignment (abfd, s, 2))
04306        return FALSE;
04307 
04308       frvfdpic_gotrel_section (info) = s;
04309 
04310       /* Machine-specific.  */
04311       s = bfd_make_section_with_flags (abfd, ".rofixup",
04312                                    (flags | SEC_READONLY));
04313       if (s == NULL
04314          || ! bfd_set_section_alignment (abfd, s, 2))
04315        return FALSE;
04316 
04317       frvfdpic_gotfixup_section (info) = s;
04318       offset = -2048;
04319       flags = BSF_GLOBAL;
04320     }
04321   else
04322     {
04323       offset = 2048;
04324       flags = BSF_GLOBAL | BSF_WEAK;
04325     }
04326 
04327   /* Define _gp in .rofixup, for FDPIC, or .got otherwise.  If it
04328      turns out that we're linking with a different linker script, the
04329      linker script will override it.  */
04330   bh = NULL;
04331   if (!(_bfd_generic_link_add_one_symbol
04332        (info, abfd, "_gp", flags, s, offset, (const char *) NULL, FALSE,
04333         bed->collect, &bh)))
04334     return FALSE;
04335   h = (struct elf_link_hash_entry *) bh;
04336   h->def_regular = 1;
04337   h->type = STT_OBJECT;
04338   /* h->other = STV_HIDDEN; */ /* Should we?  */
04339 
04340   /* Machine-specific: we want the symbol for executables as well.  */
04341   if (IS_FDPIC (abfd) && ! bfd_elf_link_record_dynamic_symbol (info, h))
04342     return FALSE;
04343 
04344   if (!IS_FDPIC (abfd))
04345     return TRUE;
04346 
04347   /* FDPIC supports Thread Local Storage, and this may require a
04348      procedure linkage table for TLS PLT entries.  */
04349 
04350   /* This is mostly copied from
04351      elflink.c:_bfd_elf_create_dynamic_sections().  */
04352 
04353   flags = pltflags;
04354   pltflags |= SEC_CODE;
04355   if (bed->plt_not_loaded)
04356     pltflags &= ~ (SEC_CODE | SEC_LOAD | SEC_HAS_CONTENTS);
04357   if (bed->plt_readonly)
04358     pltflags |= SEC_READONLY;
04359 
04360   s = bfd_make_section_with_flags (abfd, ".plt", pltflags);
04361   if (s == NULL
04362       || ! bfd_set_section_alignment (abfd, s, bed->plt_alignment))
04363     return FALSE;
04364   /* FRV-specific: remember it.  */
04365   frvfdpic_plt_section (info) = s;
04366 
04367   /* Define the symbol _PROCEDURE_LINKAGE_TABLE_ at the start of the
04368      .plt section.  */
04369   if (bed->want_plt_sym)
04370     {
04371       h = _bfd_elf_define_linkage_sym (abfd, info, s,
04372                                    "_PROCEDURE_LINKAGE_TABLE_");
04373       elf_hash_table (info)->hplt = h;
04374       if (h == NULL)
04375        return FALSE;
04376     }
04377 
04378   /* FRV-specific: we want rel relocations for the plt.  */
04379   s = bfd_make_section_with_flags (abfd, ".rel.plt",
04380                                flags | SEC_READONLY);
04381   if (s == NULL
04382       || ! bfd_set_section_alignment (abfd, s, bed->s->log_file_align))
04383     return FALSE;
04384   /* FRV-specific: remember it.  */
04385   frvfdpic_pltrel_section (info) = s;
04386 
04387   return TRUE;
04388 }
04389 
04390 /* Make sure the got and plt sections exist, and that our pointers in
04391    the link hash table point to them.  */
04392 
04393 static bfd_boolean
04394 elf32_frvfdpic_create_dynamic_sections (bfd *abfd, struct bfd_link_info *info)
04395 {
04396   /* This is mostly copied from
04397      elflink.c:_bfd_elf_create_dynamic_sections().  */
04398   flagword flags;
04399   asection *s;
04400   const struct elf_backend_data *bed = get_elf_backend_data (abfd);
04401 
04402   flags = (SEC_ALLOC | SEC_LOAD | SEC_HAS_CONTENTS | SEC_IN_MEMORY
04403           | SEC_LINKER_CREATED);
04404 
04405   /* We need to create .plt, .rel[a].plt, .got, .got.plt, .dynbss, and
04406      .rel[a].bss sections.  */
04407 
04408   /* FRV-specific: we want to create the GOT and the PLT in the FRV
04409      way.  */
04410   if (! _frv_create_got_section (abfd, info))
04411     return FALSE;
04412 
04413   /* FRV-specific: make sure we created everything we wanted.  */
04414   BFD_ASSERT (frvfdpic_got_section (info) && frvfdpic_gotrel_section (info)
04415              && frvfdpic_gotfixup_section (info)
04416              && frvfdpic_plt_section (info)
04417              && frvfdpic_pltrel_section (info));
04418 
04419   if (bed->want_dynbss)
04420     {
04421       /* The .dynbss section is a place to put symbols which are defined
04422         by dynamic objects, are referenced by regular objects, and are
04423         not functions.  We must allocate space for them in the process
04424         image and use a R_*_COPY reloc to tell the dynamic linker to
04425         initialize them at run time.  The linker script puts the .dynbss
04426         section into the .bss section of the final image.  */
04427       s = bfd_make_section_with_flags (abfd, ".dynbss",
04428                                    SEC_ALLOC | SEC_LINKER_CREATED);
04429       if (s == NULL)
04430        return FALSE;
04431 
04432       /* The .rel[a].bss section holds copy relocs.  This section is not
04433      normally needed.  We need to create it here, though, so that the
04434      linker will map it to an output section.  We can't just create it
04435      only if we need it, because we will not know whether we need it
04436      until we have seen all the input files, and the first time the
04437      main linker code calls BFD after examining all the input files
04438      (size_dynamic_sections) the input sections have already been
04439      mapped to the output sections.  If the section turns out not to
04440      be needed, we can discard it later.  We will never need this
04441      section when generating a shared object, since they do not use
04442      copy relocs.  */
04443       if (! info->shared)
04444        {
04445          s = bfd_make_section_with_flags (abfd,
04446                                       (bed->default_use_rela_p
04447                                        ? ".rela.bss" : ".rel.bss"),
04448                                       flags | SEC_READONLY);
04449          if (s == NULL
04450              || ! bfd_set_section_alignment (abfd, s, bed->s->log_file_align))
04451            return FALSE;
04452        }
04453     }
04454 
04455   return TRUE;
04456 }
04457 
04458 /* Compute the total GOT and PLT size required by each symbol in each
04459    range.  Symbols may require up to 4 words in the GOT: an entry
04460    pointing to the symbol, an entry pointing to its function
04461    descriptor, and a private function descriptors taking two
04462    words.  */
04463 
04464 static void
04465 _frvfdpic_count_nontls_entries (struct frvfdpic_relocs_info *entry,
04466                             struct _frvfdpic_dynamic_got_info *dinfo)
04467 {
04468   /* Allocate space for a GOT entry pointing to the symbol.  */
04469   if (entry->got12)
04470     dinfo->got12 += 4;
04471   else if (entry->gotlos)
04472     dinfo->gotlos += 4;
04473   else if (entry->gothilo)
04474     dinfo->gothilo += 4;
04475   else
04476     entry->relocs32--;
04477   entry->relocs32++;
04478 
04479   /* Allocate space for a GOT entry pointing to the function
04480      descriptor.  */
04481   if (entry->fdgot12)
04482     dinfo->got12 += 4;
04483   else if (entry->fdgotlos)
04484     dinfo->gotlos += 4;
04485   else if (entry->fdgothilo)
04486     dinfo->gothilo += 4;
04487   else
04488     entry->relocsfd--;
04489   entry->relocsfd++;
04490 
04491   /* Decide whether we need a PLT entry, a function descriptor in the
04492      GOT, and a lazy PLT entry for this symbol.  */
04493   entry->plt = entry->call
04494     && entry->symndx == -1 && ! FRVFDPIC_SYM_LOCAL (dinfo->info, entry->d.h)
04495     && elf_hash_table (dinfo->info)->dynamic_sections_created;
04496   entry->privfd = entry->plt
04497     || entry->fdgoff12 || entry->fdgofflos || entry->fdgoffhilo
04498     || ((entry->fd || entry->fdgot12 || entry->fdgotlos || entry->fdgothilo)
04499        && (entry->symndx != -1
04500            || FRVFDPIC_FUNCDESC_LOCAL (dinfo->info, entry->d.h)));
04501   entry->lazyplt = entry->privfd
04502     && entry->symndx == -1 && ! FRVFDPIC_SYM_LOCAL (dinfo->info, entry->d.h)
04503     && ! (dinfo->info->flags & DF_BIND_NOW)
04504     && elf_hash_table (dinfo->info)->dynamic_sections_created;
04505 
04506   /* Allocate space for a function descriptor.  */
04507   if (entry->fdgoff12)
04508     dinfo->fd12 += 8;
04509   else if (entry->fdgofflos)
04510     dinfo->fdlos += 8;
04511   else if (entry->privfd && entry->plt)
04512     dinfo->fdplt += 8;
04513   else if (entry->privfd)
04514     dinfo->fdhilo += 8;
04515   else
04516     entry->relocsfdv--;
04517   entry->relocsfdv++;
04518 
04519   if (entry->lazyplt)
04520     dinfo->lzplt += 8;
04521 }
04522 
04523 /* Compute the total GOT size required by each TLS symbol in each
04524    range.  Symbols may require up to 5 words in the GOT: an entry
04525    holding the TLS offset for the symbol, and an entry with a full TLS
04526    descriptor taking 4 words.  */
04527 
04528 static void
04529 _frvfdpic_count_tls_entries (struct frvfdpic_relocs_info *entry,
04530                           struct _frvfdpic_dynamic_got_info *dinfo,
04531                           bfd_boolean subtract)
04532 {
04533   const int l = subtract ? -1 : 1;
04534 
04535   /* Allocate space for a GOT entry with the TLS offset of the
04536      symbol.  */
04537   if (entry->tlsoff12)
04538     dinfo->got12 += 4 * l;
04539   else if (entry->tlsofflos)
04540     dinfo->gotlos += 4 * l;
04541   else if (entry->tlsoffhilo)
04542     dinfo->gothilo += 4 * l;
04543   else
04544     entry->relocstlsoff -= l;
04545   entry->relocstlsoff += l;
04546 
04547   /* If there's any TLSOFF relocation, mark the output file as not
04548      suitable for dlopening.  This mark will remain even if we relax
04549      all such relocations, but this is not a problem, since we'll only
04550      do so for executables, and we definitely don't want anyone
04551      dlopening executables.  */
04552   if (entry->relocstlsoff)
04553     dinfo->info->flags |= DF_STATIC_TLS;
04554 
04555   /* Allocate space for a TLS descriptor.  */
04556   if (entry->tlsdesc12)
04557     dinfo->tlsd12 += 8 * l;
04558   else if (entry->tlsdesclos)
04559     dinfo->tlsdlos += 8 * l;
04560   else if (entry->tlsplt)
04561     dinfo->tlsdplt += 8 * l;
04562   else if (entry->tlsdeschilo)
04563     dinfo->tlsdhilo += 8 * l;
04564   else
04565     entry->relocstlsd -= l;
04566   entry->relocstlsd += l;
04567 }
04568 
04569 /* Compute the number of dynamic relocations and fixups that a symbol
04570    requires, and add (or subtract) from the grand and per-symbol
04571    totals.  */
04572 
04573 static void
04574 _frvfdpic_count_relocs_fixups (struct frvfdpic_relocs_info *entry,
04575                             struct _frvfdpic_dynamic_got_info *dinfo,
04576                             bfd_boolean subtract)
04577 {
04578   bfd_vma relocs = 0, fixups = 0, tlsrets = 0;
04579 
04580   if (!dinfo->info->executable || dinfo->info->pie)
04581     {
04582       relocs = entry->relocs32 + entry->relocsfd + entry->relocsfdv
04583        + entry->relocstlsd;
04584 
04585       /* In the executable, TLS relocations to symbols that bind
04586         locally (including those that resolve to global TLS offsets)
04587         are resolved immediately, without any need for fixups or
04588         dynamic relocations.  In shared libraries, however, we must
04589         emit dynamic relocations even for local symbols, because we
04590         don't know the module id the library is going to get at
04591         run-time, nor its TLS base offset.  */
04592       if (!dinfo->info->executable
04593          || (entry->symndx == -1
04594              && ! FRVFDPIC_SYM_LOCAL (dinfo->info, entry->d.h)))
04595        relocs += entry->relocstlsoff;
04596     }
04597   else
04598     {
04599       if (entry->symndx != -1 || FRVFDPIC_SYM_LOCAL (dinfo->info, entry->d.h))
04600        {
04601          if (entry->symndx != -1
04602              || entry->d.h->root.type != bfd_link_hash_undefweak)
04603            fixups += entry->relocs32 + 2 * entry->relocsfdv;
04604          fixups += entry->relocstlsd;
04605          tlsrets += entry->relocstlsd;
04606        }
04607       else
04608        {
04609          relocs += entry->relocs32 + entry->relocsfdv
04610            + entry->relocstlsoff + entry->relocstlsd;
04611        }
04612 
04613       if (entry->symndx != -1
04614          || FRVFDPIC_FUNCDESC_LOCAL (dinfo->info, entry->d.h))
04615        {
04616          if (entry->symndx != -1
04617              || entry->d.h->root.type != bfd_link_hash_undefweak)
04618            fixups += entry->relocsfd;
04619        }
04620       else
04621        relocs += entry->relocsfd;
04622     }
04623 
04624   if (subtract)
04625     {
04626       relocs = - relocs;
04627       fixups = - fixups;
04628       tlsrets = - tlsrets;
04629     }
04630 
04631   entry->dynrelocs += relocs;
04632   entry->fixups += fixups;
04633   dinfo->relocs += relocs;
04634   dinfo->fixups += fixups;
04635   dinfo->tls_ret_refs += tlsrets;
04636 }
04637 
04638 /* Look for opportunities to relax TLS relocations.  We can assume
04639    we're linking the main executable or a static-tls library, since
04640    otherwise we wouldn't have got here.  When relaxing, we have to
04641    first undo any previous accounting of TLS uses of fixups, dynamic
04642    relocations, GOT and PLT entries.  */
04643 
04644 static void
04645 _frvfdpic_relax_tls_entries (struct frvfdpic_relocs_info *entry,
04646                           struct _frvfdpic_dynamic_got_info *dinfo,
04647                           bfd_boolean relaxing)
04648 {
04649   bfd_boolean changed = ! relaxing;
04650 
04651   BFD_ASSERT (dinfo->info->executable
04652              || (dinfo->info->flags & DF_STATIC_TLS));
04653 
04654   if (entry->tlsdesc12 || entry->tlsdesclos || entry->tlsdeschilo)
04655     {
04656       if (! changed)
04657        {
04658          _frvfdpic_count_relocs_fixups (entry, dinfo, TRUE);
04659          _frvfdpic_count_tls_entries (entry, dinfo, TRUE);
04660          changed = TRUE;
04661        }
04662 
04663       /* When linking an executable, we can always decay GOTTLSDESC to
04664         TLSMOFF, if the symbol is local, or GOTTLSOFF, otherwise.
04665         When linking a static-tls shared library, using TLSMOFF is
04666         not an option, but we can still use GOTTLSOFF.  When decaying
04667         to GOTTLSOFF, we must keep the GOT entry in range.  We know
04668         it has to fit because we'll be trading the 4 words of hte TLS
04669         descriptor for a single word in the same range.  */
04670       if (! dinfo->info->executable
04671          || (entry->symndx == -1
04672              && ! FRVFDPIC_SYM_LOCAL (dinfo->info, entry->d.h)))
04673        {
04674          entry->tlsoff12 |= entry->tlsdesc12;
04675          entry->tlsofflos |= entry->tlsdesclos;
04676          entry->tlsoffhilo |= entry->tlsdeschilo;
04677        }
04678 
04679       entry->tlsdesc12 = entry->tlsdesclos = entry->tlsdeschilo = 0;
04680     }
04681 
04682   /* We can only decay TLSOFFs or call #gettlsoff to TLSMOFF in the
04683      main executable.  We have to check whether the symbol's TLSOFF is
04684      in range for a setlos.  For symbols with a hash entry, we can
04685      determine exactly what to do; for others locals, we don't have
04686      addresses handy, so we use the size of the TLS section as an
04687      approximation.  If we get it wrong, we'll retain a GOT entry
04688      holding the TLS offset (without dynamic relocations or fixups),
04689      but we'll still optimize away the loads from it.  Since TLS sizes
04690      are generally very small, it's probably not worth attempting to
04691      do better than this.  */
04692   if ((entry->tlsplt
04693        || entry->tlsoff12 || entry->tlsofflos || entry->tlsoffhilo)
04694       && dinfo->info->executable && relaxing
04695       && ((entry->symndx == -1
04696           && FRVFDPIC_SYM_LOCAL (dinfo->info, entry->d.h)
04697           /* The above may hold for an undefweak TLS symbol, so make
04698              sure we don't have this case before accessing def.value
04699              and def.section.  */
04700           && (entry->d.h->root.type == bfd_link_hash_undefweak
04701               || (bfd_vma)(entry->d.h->root.u.def.value
04702                          + (entry->d.h->root.u.def.section
04703                             ->output_section->vma)
04704                          + entry->d.h->root.u.def.section->output_offset
04705                          + entry->addend
04706                          - tls_biased_base (dinfo->info)
04707                          + 32768) < (bfd_vma)65536))
04708          || (entry->symndx != -1
04709              && (elf_hash_table (dinfo->info)->tls_sec->size
04710                 + abs (entry->addend) < 32768 + FRVFDPIC_TLS_BIAS))))
04711     {
04712       if (! changed)
04713        {
04714          _frvfdpic_count_relocs_fixups (entry, dinfo, TRUE);
04715          _frvfdpic_count_tls_entries (entry, dinfo, TRUE);
04716          changed = TRUE;
04717        }
04718 
04719       entry->tlsplt =
04720        entry->tlsoff12 = entry->tlsofflos = entry->tlsoffhilo = 0;
04721     }
04722 
04723   /* We can decay `call #gettlsoff' to a ldi #tlsoff if we already
04724      have a #gottlsoff12 relocation for this entry, or if we can fit
04725      one more in the 12-bit (and 16-bit) ranges.  */
04726   if (entry->tlsplt
04727       && (entry->tlsoff12
04728          || (relaxing
04729              && dinfo->got12 + dinfo->fd12 + dinfo->tlsd12 <= 4096 - 12 - 4
04730              && (dinfo->got12 + dinfo->fd12 + dinfo->tlsd12
04731                 + dinfo->gotlos + dinfo->fdlos + dinfo->tlsdlos
04732                 <= 65536 - 12 - 4))))
04733     {
04734       if (! changed)
04735        {
04736          _frvfdpic_count_relocs_fixups (entry, dinfo, TRUE);
04737          _frvfdpic_count_tls_entries (entry, dinfo, TRUE);
04738          changed = TRUE;
04739        }
04740 
04741       entry->tlsoff12 = 1;
04742       entry->tlsplt = 0;
04743     }
04744 
04745   if (changed)
04746     {
04747       _frvfdpic_count_tls_entries (entry, dinfo, FALSE);
04748       _frvfdpic_count_relocs_fixups (entry, dinfo, FALSE);
04749     }
04750 
04751   return;
04752 }
04753 
04754 /* Compute the total GOT and PLT size required by each symbol in each range. *
04755    Symbols may require up to 4 words in the GOT: an entry pointing to
04756    the symbol, an entry pointing to its function descriptor, and a
04757    private function descriptors taking two words.  */
04758 
04759 static int
04760 _frvfdpic_count_got_plt_entries (void **entryp, void *dinfo_)
04761 {
04762   struct frvfdpic_relocs_info *entry = *entryp;
04763   struct _frvfdpic_dynamic_got_info *dinfo = dinfo_;
04764 
04765   _frvfdpic_count_nontls_entries (entry, dinfo);
04766 
04767   if (dinfo->info->executable || (dinfo->info->flags & DF_STATIC_TLS))
04768     _frvfdpic_relax_tls_entries (entry, dinfo, FALSE);
04769   else
04770     {
04771       _frvfdpic_count_tls_entries (entry, dinfo, FALSE);
04772       _frvfdpic_count_relocs_fixups (entry, dinfo, FALSE);
04773     }
04774 
04775   return 1;
04776 }
04777 
04778 /* Determine the positive and negative ranges to be used by each
04779    offset range in the GOT.  FDCUR and CUR, that must be aligned to a
04780    double-word boundary, are the minimum (negative) and maximum
04781    (positive) GOT offsets already used by previous ranges, except for
04782    an ODD entry that may have been left behind.  GOT and FD indicate
04783    the size of GOT entries and function descriptors that must be
04784    placed within the range from -WRAP to WRAP.  If there's room left,
04785    up to FDPLT bytes should be reserved for additional function
04786    descriptors.  */
04787 
04788 inline static bfd_signed_vma
04789 _frvfdpic_compute_got_alloc_data (struct _frvfdpic_dynamic_got_alloc_data *gad,
04790                               bfd_signed_vma fdcur,
04791                               bfd_signed_vma odd,
04792                               bfd_signed_vma cur,
04793                               bfd_vma got,
04794                               bfd_vma fd,
04795                               bfd_vma fdplt,
04796                               bfd_vma tlsd,
04797                               bfd_vma tlsdplt,
04798                               bfd_vma wrap)
04799 {
04800   bfd_signed_vma wrapmin = -wrap;
04801   const bfd_vma tdescsz = 8;
04802 
04803   /* Start at the given initial points.  */
04804   gad->fdcur = fdcur;
04805   gad->cur = cur;
04806 
04807   /* If we had an incoming odd word and we have any got entries that
04808      are going to use it, consume it, otherwise leave gad->odd at
04809      zero.  We might force gad->odd to zero and return the incoming
04810      odd such that it is used by the next range, but then GOT entries
04811      might appear to be out of order and we wouldn't be able to
04812      shorten the GOT by one word if it turns out to end with an
04813      unpaired GOT entry.  */
04814   if (odd && got)
04815     {
04816       gad->odd = odd;
04817       got -= 4;
04818       odd = 0;
04819     }
04820   else
04821     gad->odd = 0;
04822 
04823   /* If we're left with an unpaired GOT entry, compute its location
04824      such that we can return it.  Otherwise, if got doesn't require an
04825      odd number of words here, either odd was already zero in the
04826      block above, or it was set to zero because got was non-zero, or
04827      got was already zero.  In the latter case, we want the value of
04828      odd to carry over to the return statement, so we don't want to
04829      reset odd unless the condition below is true.  */
04830   if (got & 4)
04831     {
04832       odd = cur + got;
04833       got += 4;
04834     }
04835 
04836   /* Compute the tentative boundaries of this range.  */
04837   gad->max = cur + got;
04838   gad->min = fdcur - fd;
04839   gad->fdplt = 0;
04840 
04841   /* If function descriptors took too much space, wrap some of them
04842      around.  */
04843   if (gad->min < wrapmin)
04844     {
04845       gad->max += wrapmin - gad->min;
04846       gad->tmin = gad->min = wrapmin;
04847     }
04848 
04849   /* If GOT entries took too much space, wrap some of them around.
04850      This may well cause gad->min to become lower than wrapmin.  This
04851      will cause a relocation overflow later on, so we don't have to
04852      report it here . */
04853   if ((bfd_vma) gad->max > wrap)
04854     {
04855       gad->min -= gad->max - wrap;
04856       gad->max = wrap;
04857     }
04858 
04859   /* Add TLS descriptors.  */
04860   gad->tmax = gad->max + tlsd;
04861   gad->tmin = gad->min;
04862   gad->tlsdplt = 0;
04863 
04864   /* If TLS descriptors took too much space, wrap an integral number
04865      of them around.  */
04866   if ((bfd_vma) gad->tmax > wrap)
04867     {
04868       bfd_vma wrapsize = gad->tmax - wrap;
04869 
04870       wrapsize += tdescsz / 2;
04871       wrapsize &= ~ tdescsz / 2;
04872 
04873       gad->tmin -= wrapsize;
04874       gad->tmax -= wrapsize;
04875     }
04876 
04877   /* If there is space left and we have function descriptors
04878      referenced in PLT entries that could take advantage of shorter
04879      offsets, place them now.  */
04880   if (fdplt && gad->tmin > wrapmin)
04881     {
04882       bfd_vma fds;
04883 
04884       if ((bfd_vma) (gad->tmin - wrapmin) < fdplt)
04885        fds = gad->tmin - wrapmin;
04886       else
04887        fds = fdplt;
04888 
04889       fdplt -= fds;
04890       gad->min -= fds;
04891       gad->tmin -= fds;
04892       gad->fdplt += fds;
04893     }
04894 
04895   /* If there is more space left, try to place some more function
04896      descriptors for PLT entries.  */
04897   if (fdplt && (bfd_vma) gad->tmax < wrap)
04898     {
04899       bfd_vma fds;
04900 
04901       if ((bfd_vma) (wrap - gad->tmax) < fdplt)
04902        fds = wrap - gad->tmax;
04903       else
04904        fds = fdplt;
04905 
04906       fdplt -= fds;
04907       gad->max += fds;
04908       gad->tmax += fds;
04909       gad->fdplt += fds;
04910     }
04911 
04912   /* If there is space left and we have TLS descriptors referenced in
04913      PLT entries that could take advantage of shorter offsets, place
04914      them now.  */
04915   if (tlsdplt && gad->tmin > wrapmin)
04916     {
04917       bfd_vma tlsds;
04918 
04919       if ((bfd_vma) (gad->tmin - wrapmin) < tlsdplt)
04920        tlsds = (gad->tmin - wrapmin) & ~ (tdescsz / 2);
04921       else
04922        tlsds = tlsdplt;
04923 
04924       tlsdplt -= tlsds;
04925       gad->tmin -= tlsds;
04926       gad->tlsdplt += tlsds;
04927     }
04928 
04929   /* If there is more space left, try to place some more TLS
04930      descriptors for PLT entries.  Although we could try to fit an
04931      additional TLS descriptor with half of it just before before the
04932      wrap point and another right past the wrap point, this might
04933      cause us to run out of space for the next region, so don't do
04934      it.  */
04935   if (tlsdplt && (bfd_vma) gad->tmax < wrap - tdescsz / 2)
04936     {
04937       bfd_vma tlsds;
04938 
04939       if ((bfd_vma) (wrap - gad->tmax) < tlsdplt)
04940        tlsds = (wrap - gad->tmax) & ~ (tdescsz / 2);
04941       else
04942        tlsds = tlsdplt;
04943 
04944       tlsdplt -= tlsds;
04945       gad->tmax += tlsds;
04946       gad->tlsdplt += tlsds;
04947     }
04948 
04949   /* If odd was initially computed as an offset past the wrap point,
04950      wrap it around.  */
04951   if (odd > gad->max)
04952     odd = gad->min + odd - gad->max;
04953 
04954   /* _frvfdpic_get_got_entry() below will always wrap gad->cur if needed
04955      before returning, so do it here too.  This guarantees that,
04956      should cur and fdcur meet at the wrap point, they'll both be
04957      equal to min.  */
04958   if (gad->cur == gad->max)
04959     gad->cur = gad->min;
04960 
04961   /* Ditto for _frvfdpic_get_tlsdesc_entry().  */
04962   gad->tcur = gad->max;
04963   if (gad->tcur == gad->tmax)
04964     gad->tcur = gad->tmin;
04965 
04966   return odd;
04967 }
04968 
04969 /* Compute the location of the next GOT entry, given the allocation
04970    data for a range.  */
04971 
04972 inline static bfd_signed_vma
04973 _frvfdpic_get_got_entry (struct _frvfdpic_dynamic_got_alloc_data *gad)
04974 {
04975   bfd_signed_vma ret;
04976 
04977   if (gad->odd)
04978     {
04979       /* If there was an odd word left behind, use it.  */
04980       ret = gad->odd;
04981       gad->odd = 0;
04982     }
04983   else
04984     {
04985       /* Otherwise, use the word pointed to by cur, reserve the next
04986         as an odd word, and skip to the next pair of words, possibly
04987         wrapping around.  */
04988       ret = gad->cur;
04989       gad->odd = gad->cur + 4;
04990       gad->cur += 8;
04991       if (gad->cur == gad->max)
04992        gad->cur = gad->min;
04993     }
04994 
04995   return ret;
04996 }
04997 
04998 /* Compute the location of the next function descriptor entry in the
04999    GOT, given the allocation data for a range.  */
05000 
05001 inline static bfd_signed_vma
05002 _frvfdpic_get_fd_entry (struct _frvfdpic_dynamic_got_alloc_data *gad)
05003 {
05004   /* If we're at the bottom, wrap around, and only then allocate the
05005      next pair of words.  */
05006   if (gad->fdcur == gad->min)
05007     gad->fdcur = gad->max;
05008   return gad->fdcur -= 8;
05009 }
05010 
05011 /* Compute the location of the next TLS descriptor entry in the GOT,
05012    given the allocation data for a range.  */
05013 inline static bfd_signed_vma
05014 _frvfdpic_get_tlsdesc_entry (struct _frvfdpic_dynamic_got_alloc_data *gad)
05015 {
05016   bfd_signed_vma ret;
05017 
05018   ret = gad->tcur;
05019 
05020   gad->tcur += 8;
05021 
05022   /* If we're at the top of the region, wrap around to the bottom.  */
05023   if (gad->tcur == gad->tmax)
05024     gad->tcur = gad->tmin;
05025 
05026   return ret;
05027 }
05028 
05029 /* Assign GOT offsets for every GOT entry and function descriptor.
05030    Doing everything in a single pass is tricky.  */
05031 
05032 static int
05033 _frvfdpic_assign_got_entries (void **entryp, void *info_)
05034 {
05035   struct frvfdpic_relocs_info *entry = *entryp;
05036   struct _frvfdpic_dynamic_got_plt_info *dinfo = info_;
05037 
05038   if (entry->got12)
05039     entry->got_entry = _frvfdpic_get_got_entry (&dinfo->got12);
05040   else if (entry->gotlos)
05041     entry->got_entry = _frvfdpic_get_got_entry (&dinfo->gotlos);
05042   else if (entry->gothilo)
05043     entry->got_entry = _frvfdpic_get_got_entry (&dinfo->gothilo);
05044 
05045   if (entry->fdgot12)
05046     entry->fdgot_entry = _frvfdpic_get_got_entry (&dinfo->got12);
05047   else if (entry->fdgotlos)
05048     entry->fdgot_entry = _frvfdpic_get_got_entry (&dinfo->gotlos);
05049   else if (entry->fdgothilo)
05050     entry->fdgot_entry = _frvfdpic_get_got_entry (&dinfo->gothilo);
05051 
05052   if (entry->fdgoff12)
05053     entry->fd_entry = _frvfdpic_get_fd_entry (&dinfo->got12);
05054   else if (entry->plt && dinfo->got12.fdplt)
05055     {
05056       dinfo->got12.fdplt -= 8;
05057       entry->fd_entry = _frvfdpic_get_fd_entry (&dinfo->got12);
05058     }
05059   else if (entry->fdgofflos)
05060     entry->fd_entry = _frvfdpic_get_fd_entry (&dinfo->gotlos);
05061   else if (entry->plt && dinfo->gotlos.fdplt)
05062     {
05063       dinfo->gotlos.fdplt -= 8;
05064       entry->fd_entry = _frvfdpic_get_fd_entry (&dinfo->gotlos);
05065     }
05066   else if (entry->plt)
05067     {
05068       dinfo->gothilo.fdplt -= 8;
05069       entry->fd_entry = _frvfdpic_get_fd_entry (&dinfo->gothilo);
05070     }
05071   else if (entry->privfd)
05072     entry->fd_entry = _frvfdpic_get_fd_entry (&dinfo->gothilo);
05073 
05074   if (entry->tlsoff12)
05075     entry->tlsoff_entry = _frvfdpic_get_got_entry (&dinfo->got12);
05076   else if (entry->tlsofflos)
05077     entry->tlsoff_entry = _frvfdpic_get_got_entry (&dinfo->gotlos);
05078   else if (entry->tlsoffhilo)
05079     entry->tlsoff_entry = _frvfdpic_get_got_entry (&dinfo->gothilo);
05080 
05081   if (entry->tlsdesc12)
05082     entry->tlsdesc_entry = _frvfdpic_get_tlsdesc_entry (&dinfo->got12);
05083   else if (entry->tlsplt && dinfo->got12.tlsdplt)
05084     {
05085       dinfo->got12.tlsdplt -= 8;
05086       entry->tlsdesc_entry = _frvfdpic_get_tlsdesc_entry (&dinfo->got12);
05087     }
05088   else if (entry->tlsdesclos)
05089     entry->tlsdesc_entry = _frvfdpic_get_tlsdesc_entry (&dinfo->gotlos);
05090   else if (entry->tlsplt && dinfo->gotlos.tlsdplt)
05091     {
05092       dinfo->gotlos.tlsdplt -= 8;
05093       entry->tlsdesc_entry = _frvfdpic_get_tlsdesc_entry (&dinfo->gotlos);
05094     }
05095   else if (entry->tlsplt)
05096     {
05097       dinfo->gothilo.tlsdplt -= 8;
05098       entry->tlsdesc_entry = _frvfdpic_get_tlsdesc_entry (&dinfo->gothilo);
05099     }
05100   else if (entry->tlsdeschilo)
05101     entry->tlsdesc_entry = _frvfdpic_get_tlsdesc_entry (&dinfo->gothilo);
05102 
05103   return 1;
05104 }
05105 
05106 /* Assign GOT offsets to private function descriptors used by PLT
05107    entries (or referenced by 32-bit offsets), as well as PLT entries
05108    and lazy PLT entries.  */
05109 
05110 static int
05111 _frvfdpic_assign_plt_entries (void **entryp, void *info_)
05112 {
05113   struct frvfdpic_relocs_info *entry = *entryp;
05114   struct _frvfdpic_dynamic_got_plt_info *dinfo = info_;
05115 
05116   if (entry->privfd)
05117     BFD_ASSERT (entry->fd_entry);
05118 
05119   if (entry->plt)
05120     {
05121       int size;
05122 
05123       /* We use the section's raw size to mark the location of the
05124         next PLT entry.  */
05125       entry->plt_entry = frvfdpic_plt_section (dinfo->g.info)->size;
05126 
05127       /* Figure out the length of this PLT entry based on the
05128         addressing mode we need to reach the function descriptor.  */
05129       BFD_ASSERT (entry->fd_entry);
05130       if (entry->fd_entry >= -(1 << (12 - 1))
05131          && entry->fd_entry < (1 << (12 - 1)))
05132        size = 8;
05133       else if (entry->fd_entry >= -(1 << (16 - 1))
05134               && entry->fd_entry < (1 << (16 - 1)))
05135        size = 12;
05136       else
05137        size = 16;
05138 
05139       frvfdpic_plt_section (dinfo->g.info)->size += size;
05140     }
05141 
05142   if (entry->lazyplt)
05143     {
05144       entry->lzplt_entry = dinfo->g.lzplt;
05145       dinfo->g.lzplt += 8;
05146       /* If this entry is the one that gets the resolver stub, account
05147         for the additional instruction.  */
05148       if (entry->lzplt_entry % FRVFDPIC_LZPLT_BLOCK_SIZE
05149          == FRVFDPIC_LZPLT_RESOLV_LOC)
05150        dinfo->g.lzplt += 4;
05151     }
05152 
05153   if (entry->tlsplt)
05154     {
05155       int size;
05156 
05157       entry->tlsplt_entry
05158        = frvfdpic_plt_section (dinfo->g.info)->size;
05159 
05160       if (dinfo->g.info->executable
05161          && (entry->symndx != -1
05162              || FRVFDPIC_SYM_LOCAL (dinfo->g.info, entry->d.h)))
05163        {
05164          if ((bfd_signed_vma)entry->addend >= -(1 << (16 - 1))
05165              /* FIXME: here we use the size of the TLS section
05166                as an upper bound for the value of the TLS
05167                symbol, because we may not know the exact value
05168                yet.  If we get it wrong, we'll just waste a
05169                word in the PLT, and we should never get even
05170                close to 32 KiB of TLS anyway.  */
05171              && elf_hash_table (dinfo->g.info)->tls_sec
05172              && (elf_hash_table (dinfo->g.info)->tls_sec->size
05173                 + (bfd_signed_vma)(entry->addend) <= (1 << (16 - 1))))
05174            size = 8;
05175          else
05176            size = 12;
05177        }
05178       else if (entry->tlsoff_entry)
05179        {
05180          if (entry->tlsoff_entry >= -(1 << (12 - 1))
05181              && entry->tlsoff_entry < (1 << (12 - 1)))
05182            size = 8;
05183          else if (entry->tlsoff_entry >= -(1 << (16 - 1))
05184                  && entry->tlsoff_entry < (1 << (16 - 1)))
05185            size = 12;
05186          else
05187            size = 16;
05188        }
05189       else
05190        {
05191          BFD_ASSERT (entry->tlsdesc_entry);
05192 
05193          if (entry->tlsdesc_entry >= -(1 << (12 - 1))
05194              && entry->tlsdesc_entry < (1 << (12 - 1)))
05195            size = 8;
05196          else if (entry->tlsdesc_entry >= -(1 << (16 - 1))
05197                  && entry->tlsdesc_entry < (1 << (16 - 1)))
05198            size = 12;
05199          else
05200            size = 16;
05201        }
05202 
05203       frvfdpic_plt_section (dinfo->g.info)->size += size;
05204     }
05205 
05206   return 1;
05207 }
05208 
05209 /* Cancel out any effects of calling _frvfdpic_assign_got_entries and
05210    _frvfdpic_assign_plt_entries.  */
05211 
05212 static int
05213 _frvfdpic_reset_got_plt_entries (void **entryp, void *ignore ATTRIBUTE_UNUSED)
05214 {
05215   struct frvfdpic_relocs_info *entry = *entryp;
05216 
05217   entry->got_entry = 0;
05218   entry->fdgot_entry = 0;
05219   entry->fd_entry = 0;
05220   entry->plt_entry = (bfd_vma)-1;
05221   entry->lzplt_entry = (bfd_vma)-1;
05222   entry->tlsoff_entry = 0;
05223   entry->tlsdesc_entry = 0;
05224   entry->tlsplt_entry = (bfd_vma)-1;
05225 
05226   return 1;
05227 }
05228 
05229 /* Follow indirect and warning hash entries so that each got entry
05230    points to the final symbol definition.  P must point to a pointer
05231    to the hash table we're traversing.  Since this traversal may
05232    modify the hash table, we set this pointer to NULL to indicate
05233    we've made a potentially-destructive change to the hash table, so
05234    the traversal must be restarted.  */
05235 static int
05236 _frvfdpic_resolve_final_relocs_info (void **entryp, void *p)
05237 {
05238   struct frvfdpic_relocs_info *entry = *entryp;
05239   htab_t *htab = p;
05240 
05241   if (entry->symndx == -1)
05242     {
05243       struct elf_link_hash_entry *h = entry->d.h;
05244       struct frvfdpic_relocs_info *oentry;
05245 
05246       while (h->root.type == bfd_link_hash_indirect
05247             || h->root.type == bfd_link_hash_warning)
05248        h = (struct elf_link_hash_entry *)h->root.u.i.link;
05249 
05250       if (entry->d.h == h)
05251        return 1;
05252 
05253       oentry = frvfdpic_relocs_info_for_global (*htab, 0, h, entry->addend,
05254                                           NO_INSERT);
05255 
05256       if (oentry)
05257        {
05258          /* Merge the two entries.  */
05259          frvfdpic_pic_merge_early_relocs_info (oentry, entry);
05260          htab_clear_slot (*htab, entryp);
05261          return 1;
05262        }
05263 
05264       entry->d.h = h;
05265 
05266       /* If we can't find this entry with the new bfd hash, re-insert
05267         it, and get the traversal restarted.  */
05268       if (! htab_find (*htab, entry))
05269        {
05270          htab_clear_slot (*htab, entryp);
05271          entryp = htab_find_slot (*htab, entry, INSERT);
05272          if (! *entryp)
05273            *entryp = entry;
05274          /* Abort the traversal, since the whole table may have
05275             moved, and leave it up to the parent to restart the
05276             process.  */
05277          *(htab_t *)p = NULL;
05278          return 0;
05279        }
05280     }
05281 
05282   return 1;
05283 }
05284 
05285 /* Compute the total size of the GOT, the PLT, the dynamic relocations
05286    section and the rofixup section.  Assign locations for GOT and PLT
05287    entries.  */
05288 
05289 static bfd_boolean
05290 _frvfdpic_size_got_plt (bfd *output_bfd,
05291                      struct _frvfdpic_dynamic_got_plt_info *gpinfop)
05292 {
05293   bfd_signed_vma odd;
05294   bfd_vma limit, tlslimit;
05295   struct bfd_link_info *info = gpinfop->g.info;
05296   bfd *dynobj = elf_hash_table (info)->dynobj;
05297 
05298   memcpy (frvfdpic_dynamic_got_plt_info (info), &gpinfop->g,
05299          sizeof (gpinfop->g));
05300 
05301   odd = 12;
05302   /* Compute the total size taken by entries in the 12-bit and 16-bit
05303      ranges, to tell how many PLT function descriptors we can bring
05304      into the 12-bit range without causing the 16-bit range to
05305      overflow.  */
05306   limit = odd + gpinfop->g.got12 + gpinfop->g.gotlos
05307     + gpinfop->g.fd12 + gpinfop->g.fdlos
05308     + gpinfop->g.tlsd12 + gpinfop->g.tlsdlos;
05309   if (limit < (bfd_vma)1 << 16)
05310     limit = ((bfd_vma)1 << 16) - limit;
05311   else
05312     limit = 0;
05313   if (gpinfop->g.fdplt < limit)
05314     {
05315       tlslimit = (limit - gpinfop->g.fdplt) & ~ (bfd_vma) 8;
05316       limit = gpinfop->g.fdplt;
05317     }
05318   else
05319     tlslimit = 0;
05320   if (gpinfop->g.tlsdplt < tlslimit)
05321     tlslimit = gpinfop->g.tlsdplt;
05322 
05323   /* Determine the ranges of GOT offsets that we can use for each
05324      range of addressing modes.  */
05325   odd = _frvfdpic_compute_got_alloc_data (&gpinfop->got12,
05326                                      0,
05327                                      odd,
05328                                      16,
05329                                      gpinfop->g.got12,
05330                                      gpinfop->g.fd12,
05331                                      limit,
05332                                      gpinfop->g.tlsd12,
05333                                      tlslimit,
05334                                      (bfd_vma)1 << (12-1));
05335   odd = _frvfdpic_compute_got_alloc_data (&gpinfop->gotlos,
05336                                      gpinfop->got12.tmin,
05337                                      odd,
05338                                      gpinfop->got12.tmax,
05339                                      gpinfop->g.gotlos,
05340                                      gpinfop->g.fdlos,
05341                                      gpinfop->g.fdplt
05342                                      - gpinfop->got12.fdplt,
05343                                      gpinfop->g.tlsdlos,
05344                                      gpinfop->g.tlsdplt
05345                                      - gpinfop->got12.tlsdplt,
05346                                      (bfd_vma)1 << (16-1));
05347   odd = _frvfdpic_compute_got_alloc_data (&gpinfop->gothilo,
05348                                      gpinfop->gotlos.tmin,
05349                                      odd,
05350                                      gpinfop->gotlos.tmax,
05351                                      gpinfop->g.gothilo,
05352                                      gpinfop->g.fdhilo,
05353                                      gpinfop->g.fdplt
05354                                      - gpinfop->got12.fdplt
05355                                      - gpinfop->gotlos.fdplt,
05356                                      gpinfop->g.tlsdhilo,
05357                                      gpinfop->g.tlsdplt
05358                                      - gpinfop->got12.tlsdplt
05359                                      - gpinfop->gotlos.tlsdplt,
05360                                      (bfd_vma)1 << (32-1));
05361 
05362   /* Now assign (most) GOT offsets.  */
05363   htab_traverse (frvfdpic_relocs_info (info), _frvfdpic_assign_got_entries,
05364                gpinfop);
05365 
05366   frvfdpic_got_section (info)->size = gpinfop->gothilo.tmax
05367     - gpinfop->gothilo.tmin
05368     /* If an odd word is the last word of the GOT, we don't need this
05369        word to be part of the GOT.  */
05370     - (odd + 4 == gpinfop->gothilo.tmax ? 4 : 0);
05371   if (frvfdpic_got_section (info)->size == 0)
05372     frvfdpic_got_section (info)->flags |= SEC_EXCLUDE;
05373   else if (frvfdpic_got_section (info)->size == 12
05374           && ! elf_hash_table (info)->dynamic_sections_created)
05375     {
05376       frvfdpic_got_section (info)->flags |= SEC_EXCLUDE;
05377       frvfdpic_got_section (info)->size = 0;
05378     }
05379   /* This will be non-NULL during relaxation.  The assumption is that
05380      the size of one of these sections will never grow, only shrink,
05381      so we can use the larger buffer we allocated before.  */
05382   else if (frvfdpic_got_section (info)->contents == NULL)
05383     {
05384       frvfdpic_got_section (info)->contents =
05385        (bfd_byte *) bfd_zalloc (dynobj,
05386                              frvfdpic_got_section (info)->size);
05387       if (frvfdpic_got_section (info)->contents == NULL)
05388        return FALSE;
05389     }
05390 
05391   if (frvfdpic_gotrel_section (info))
05392     /* Subtract the number of lzplt entries, since those will generate
05393        relocations in the pltrel section.  */
05394     frvfdpic_gotrel_section (info)->size =
05395       (gpinfop->g.relocs - gpinfop->g.lzplt / 8)
05396       * get_elf_backend_data (output_bfd)->s->sizeof_rel;
05397   else
05398     BFD_ASSERT (gpinfop->g.relocs == 0);
05399   if (frvfdpic_gotrel_section (info)->size == 0)
05400     frvfdpic_gotrel_section (info)->flags |= SEC_EXCLUDE;
05401   else if (frvfdpic_gotrel_section (info)->contents == NULL)
05402     {
05403       frvfdpic_gotrel_section (info)->contents =
05404        (bfd_byte *) bfd_zalloc (dynobj,
05405                              frvfdpic_gotrel_section (info)->size);
05406       if (frvfdpic_gotrel_section (info)->contents == NULL)
05407        return FALSE;
05408     }
05409 
05410   frvfdpic_gotfixup_section (info)->size = (gpinfop->g.fixups + 1) * 4;
05411   if (frvfdpic_gotfixup_section (info)->size == 0)
05412     frvfdpic_gotfixup_section (info)->flags |= SEC_EXCLUDE;
05413   else if (frvfdpic_gotfixup_section (info)->contents == NULL)
05414     {
05415       frvfdpic_gotfixup_section (info)->contents =
05416        (bfd_byte *) bfd_zalloc (dynobj,
05417                              frvfdpic_gotfixup_section (info)->size);
05418       if (frvfdpic_gotfixup_section (info)->contents == NULL)
05419        return FALSE;
05420     }
05421 
05422   if (frvfdpic_pltrel_section (info))
05423     {
05424       frvfdpic_pltrel_section (info)->size =
05425        gpinfop->g.lzplt / 8
05426        * get_elf_backend_data (output_bfd)->s->sizeof_rel;
05427       if (frvfdpic_pltrel_section (info)->size == 0)
05428        frvfdpic_pltrel_section (info)->flags |= SEC_EXCLUDE;
05429       else if (frvfdpic_pltrel_section (info)->contents == NULL)
05430        {
05431          frvfdpic_pltrel_section (info)->contents =
05432            (bfd_byte *) bfd_zalloc (dynobj,
05433                                  frvfdpic_pltrel_section (info)->size);
05434          if (frvfdpic_pltrel_section (info)->contents == NULL)
05435            return FALSE;
05436        }
05437     }
05438 
05439   /* Add 4 bytes for every block of at most 65535 lazy PLT entries,
05440      such that there's room for the additional instruction needed to
05441      call the resolver.  Since _frvfdpic_assign_got_entries didn't
05442      account for them, our block size is 4 bytes smaller than the real
05443      block size.  */
05444   if (frvfdpic_plt_section (info))
05445     {
05446       frvfdpic_plt_section (info)->size = gpinfop->g.lzplt
05447        + ((gpinfop->g.lzplt + (FRVFDPIC_LZPLT_BLOCK_SIZE - 4) - 8)
05448           / (FRVFDPIC_LZPLT_BLOCK_SIZE - 4) * 4);
05449     }
05450 
05451   /* Reset it, such that _frvfdpic_assign_plt_entries() can use it to
05452      actually assign lazy PLT entries addresses.  */
05453   gpinfop->g.lzplt = 0;
05454 
05455   /* Save information that we're going to need to generate GOT and PLT
05456      entries.  */
05457   frvfdpic_got_initial_offset (info) = -gpinfop->gothilo.tmin;
05458 
05459   if (get_elf_backend_data (output_bfd)->want_got_sym)
05460     elf_hash_table (info)->hgot->root.u.def.value
05461       = frvfdpic_got_initial_offset (info);
05462 
05463   if (frvfdpic_plt_section (info))
05464     frvfdpic_plt_initial_offset (info) =
05465       frvfdpic_plt_section (info)->size;
05466 
05467   /* Allocate a ret statement at plt_initial_offset, to be used by
05468      locally-resolved TLS descriptors.  */
05469   if (gpinfop->g.tls_ret_refs)
05470     frvfdpic_plt_section (info)->size += 4;
05471 
05472   htab_traverse (frvfdpic_relocs_info (info), _frvfdpic_assign_plt_entries,
05473                gpinfop);
05474 
05475   /* Allocate the PLT section contents only after
05476      _frvfdpic_assign_plt_entries has a chance to add the size of the
05477      non-lazy PLT entries.  */
05478   if (frvfdpic_plt_section (info))
05479     {
05480       if (frvfdpic_plt_section (info)->size == 0)
05481        frvfdpic_plt_section (info)->flags |= SEC_EXCLUDE;
05482       else if (frvfdpic_plt_section (info)->contents == NULL)
05483        {
05484          frvfdpic_plt_section (info)->contents =
05485            (bfd_byte *) bfd_zalloc (dynobj,
05486                                  frvfdpic_plt_section (info)->size);
05487          if (frvfdpic_plt_section (info)->contents == NULL)
05488            return FALSE;
05489        }
05490     }
05491 
05492   return TRUE;
05493 }
05494 
05495 /* Set the sizes of the dynamic sections.  */
05496 
05497 static bfd_boolean
05498 elf32_frvfdpic_size_dynamic_sections (bfd *output_bfd,
05499                                   struct bfd_link_info *info)
05500 {
05501   bfd *dynobj;
05502   asection *s;
05503   struct _frvfdpic_dynamic_got_plt_info gpinfo;
05504 
05505   dynobj = elf_hash_table (info)->dynobj;
05506   BFD_ASSERT (dynobj != NULL);
05507 
05508   if (elf_hash_table (info)->dynamic_sections_created)
05509     {
05510       /* Set the contents of the .interp section to the interpreter.  */
05511       if (info->executable)
05512        {
05513          s = bfd_get_section_by_name (dynobj, ".interp");
05514          BFD_ASSERT (s != NULL);
05515          s->size = sizeof ELF_DYNAMIC_INTERPRETER;
05516          s->contents = (bfd_byte *) ELF_DYNAMIC_INTERPRETER;
05517        }
05518     }
05519 
05520   memset (&gpinfo, 0, sizeof (gpinfo));
05521   gpinfo.g.info = info;
05522 
05523   for (;;)
05524     {
05525       htab_t relocs = frvfdpic_relocs_info (info);
05526 
05527       htab_traverse (relocs, _frvfdpic_resolve_final_relocs_info, &relocs);
05528 
05529       if (relocs == frvfdpic_relocs_info (info))
05530        break;
05531     }
05532 
05533   htab_traverse (frvfdpic_relocs_info (info), _frvfdpic_count_got_plt_entries,
05534                &gpinfo.g);
05535 
05536   /* Allocate space to save the summary information, we're going to
05537      use it if we're doing relaxations.  */
05538   frvfdpic_dynamic_got_plt_info (info) = bfd_alloc (dynobj, sizeof (gpinfo.g));
05539 
05540   if (!_frvfdpic_size_got_plt (output_bfd, &gpinfo))
05541     return FALSE;
05542 
05543   if (elf_hash_table (info)->dynamic_sections_created)
05544     {
05545       if (frvfdpic_got_section (info)->size)
05546        if (!_bfd_elf_add_dynamic_entry (info, DT_PLTGOT, 0))
05547          return FALSE;
05548 
05549       if (frvfdpic_pltrel_section (info)->size)
05550        if (!_bfd_elf_add_dynamic_entry (info, DT_PLTRELSZ, 0)
05551            || !_bfd_elf_add_dynamic_entry (info, DT_PLTREL, DT_REL)
05552            || !_bfd_elf_add_dynamic_entry (info, DT_JMPREL, 0))
05553          return FALSE;
05554 
05555       if (frvfdpic_gotrel_section (info)->size)
05556        if (!_bfd_elf_add_dynamic_entry (info, DT_REL, 0)
05557            || !_bfd_elf_add_dynamic_entry (info, DT_RELSZ, 0)
05558            || !_bfd_elf_add_dynamic_entry (info, DT_RELENT,
05559                                        sizeof (Elf32_External_Rel)))
05560          return FALSE;
05561     }
05562 
05563   return TRUE;
05564 }
05565 
05566 static bfd_boolean
05567 elf32_frvfdpic_always_size_sections (bfd *output_bfd,
05568                                  struct bfd_link_info *info)
05569 {
05570   if (!info->relocatable)
05571     {
05572       struct elf_link_hash_entry *h;
05573 
05574       /* Force a PT_GNU_STACK segment to be created.  */
05575       if (! elf_tdata (output_bfd)->stack_flags)
05576        elf_tdata (output_bfd)->stack_flags = PF_R | PF_W | PF_X;
05577 
05578       /* Define __stacksize if it's not defined yet.  */
05579       h = elf_link_hash_lookup (elf_hash_table (info), "__stacksize",
05580                             FALSE, FALSE, FALSE);
05581       if (! h || h->root.type != bfd_link_hash_defined
05582          || h->type != STT_OBJECT
05583          || !h->def_regular)
05584        {
05585          struct bfd_link_hash_entry *bh = NULL;
05586 
05587          if (!(_bfd_generic_link_add_one_symbol
05588               (info, output_bfd, "__stacksize",
05589                BSF_GLOBAL, bfd_abs_section_ptr, DEFAULT_STACK_SIZE,
05590                (const char *) NULL, FALSE,
05591                get_elf_backend_data (output_bfd)->collect, &bh)))
05592            return FALSE;
05593 
05594          h = (struct elf_link_hash_entry *) bh;
05595          h->def_regular = 1;
05596          h->type = STT_OBJECT;
05597          /* This one must NOT be hidden.  */
05598        }
05599     }
05600 
05601   return TRUE;
05602 }
05603 
05604 /* Look for opportunities to relax TLS relocations.  We can assume
05605    we're linking the main executable or a static-tls library, since
05606    otherwise we wouldn't have got here.  */
05607 
05608 static int
05609 _frvfdpic_relax_got_plt_entries (void **entryp, void *dinfo_)
05610 {
05611   struct frvfdpic_relocs_info *entry = *entryp;
05612   struct _frvfdpic_dynamic_got_info *dinfo = dinfo_;
05613 
05614   _frvfdpic_relax_tls_entries (entry, dinfo, TRUE);
05615 
05616   return 1;
05617 }
05618 
05619 static bfd_boolean
05620 elf32_frvfdpic_relax_section (bfd *abfd ATTRIBUTE_UNUSED, asection *sec,
05621                            struct bfd_link_info *info, bfd_boolean *again)
05622 {
05623   struct _frvfdpic_dynamic_got_plt_info gpinfo;
05624 
05625   /* If we return early, we didn't change anything.  */
05626   *again = FALSE;
05627 
05628   /* We'll do our thing when requested to relax the GOT section.  */
05629   if (sec != frvfdpic_got_section (info))
05630     return TRUE;
05631 
05632   /* We can only relax when linking the main executable or a library
05633      that can't be dlopened.  */
05634   if (! info->executable && ! (info->flags & DF_STATIC_TLS))
05635     return TRUE;
05636 
05637   /* If there isn't a TLS section for this binary, we can't do
05638      anything about its TLS relocations (it probably doesn't have
05639      any.  */
05640   if (elf_hash_table (info)->tls_sec == NULL)
05641     return TRUE;
05642 
05643   memset (&gpinfo, 0, sizeof (gpinfo));
05644   memcpy (&gpinfo.g, frvfdpic_dynamic_got_plt_info (info), sizeof (gpinfo.g));
05645 
05646   /* Now look for opportunities to relax, adjusting the GOT usage
05647      as needed.  */
05648   htab_traverse (frvfdpic_relocs_info (info),
05649                _frvfdpic_relax_got_plt_entries,
05650                &gpinfo.g);
05651 
05652   /* If we changed anything, reset and re-assign GOT and PLT entries.  */
05653   if (memcmp (frvfdpic_dynamic_got_plt_info (info),
05654              &gpinfo.g, sizeof (gpinfo.g)) != 0)
05655     {
05656       /* Clear GOT and PLT assignments.  */
05657       htab_traverse (frvfdpic_relocs_info (info),
05658                    _frvfdpic_reset_got_plt_entries,
05659                    NULL);
05660 
05661       /* The owner of the TLS section is the output bfd.  There should
05662         be a better way to get to it.  */
05663       if (!_frvfdpic_size_got_plt (elf_hash_table (info)->tls_sec->owner,
05664                                &gpinfo))
05665        return FALSE;
05666 
05667       /* Repeat until we don't make any further changes.  We could fail to
05668         introduce changes in a round if, for example, the 12-bit range is
05669         full, but we later release some space by getting rid of TLS
05670         descriptors in it.  We have to repeat the whole process because
05671         we might have changed the size of a section processed before this
05672         one.  */
05673       *again = TRUE;
05674     }
05675 
05676   return TRUE;
05677 }
05678 
05679 static bfd_boolean
05680 elf32_frvfdpic_modify_program_headers (bfd *output_bfd,
05681                                    struct bfd_link_info *info)
05682 {
05683   struct elf_obj_tdata *tdata = elf_tdata (output_bfd);
05684   struct elf_segment_map *m;
05685   Elf_Internal_Phdr *p;
05686 
05687   /* objcopy and strip preserve what's already there using
05688      elf32_frvfdpic_copy_private_bfd_data ().  */
05689   if (! info)
05690     return TRUE;
05691 
05692   for (p = tdata->phdr, m = tdata->segment_map; m != NULL; m = m->next, p++)
05693     if (m->p_type == PT_GNU_STACK)
05694       break;
05695 
05696   if (m)
05697     {
05698       struct elf_link_hash_entry *h;
05699 
05700       /* Obtain the pointer to the __stacksize symbol.  */
05701       h = elf_link_hash_lookup (elf_hash_table (info), "__stacksize",
05702                             FALSE, FALSE, FALSE);
05703       if (h)
05704        {
05705          while (h->root.type == bfd_link_hash_indirect
05706                || h->root.type == bfd_link_hash_warning)
05707            h = (struct elf_link_hash_entry *) h->root.u.i.link;
05708          BFD_ASSERT (h->root.type == bfd_link_hash_defined);
05709        }
05710 
05711       /* Set the header p_memsz from the symbol value.  We
05712         intentionally ignore the symbol section.  */
05713       if (h && h->root.type == bfd_link_hash_defined)
05714        p->p_memsz = h->root.u.def.value;
05715       else
05716        p->p_memsz = DEFAULT_STACK_SIZE;
05717 
05718       p->p_align = 8;
05719     }
05720 
05721   return TRUE;
05722 }
05723 
05724 /* Fill in code and data in dynamic sections.  */
05725 
05726 static bfd_boolean
05727 elf32_frv_finish_dynamic_sections (bfd *output_bfd ATTRIBUTE_UNUSED,
05728                                struct bfd_link_info *info ATTRIBUTE_UNUSED)
05729 {
05730   /* Nothing to be done for non-FDPIC.  */
05731   return TRUE;
05732 }
05733 
05734 static bfd_boolean
05735 elf32_frvfdpic_finish_dynamic_sections (bfd *output_bfd,
05736                                    struct bfd_link_info *info)
05737 {
05738   bfd *dynobj;
05739   asection *sdyn;
05740 
05741   dynobj = elf_hash_table (info)->dynobj;
05742 
05743   if (frvfdpic_dynamic_got_plt_info (info))
05744     {
05745       BFD_ASSERT (frvfdpic_dynamic_got_plt_info (info)->tls_ret_refs == 0);
05746     }
05747   if (frvfdpic_got_section (info))
05748     {
05749       BFD_ASSERT (frvfdpic_gotrel_section (info)->size
05750                 == (frvfdpic_gotrel_section (info)->reloc_count
05751                     * sizeof (Elf32_External_Rel)));
05752 
05753       if (frvfdpic_gotfixup_section (info))
05754        {
05755          struct elf_link_hash_entry *hgot = elf_hash_table (info)->hgot;
05756          bfd_vma got_value = hgot->root.u.def.value
05757            + hgot->root.u.def.section->output_section->vma
05758            + hgot->root.u.def.section->output_offset;
05759          struct bfd_link_hash_entry *hend;
05760 
05761          _frvfdpic_add_rofixup (output_bfd, frvfdpic_gotfixup_section (info),
05762                              got_value, 0);
05763 
05764          if (frvfdpic_gotfixup_section (info)->size
05765              != (frvfdpic_gotfixup_section (info)->reloc_count * 4))
05766            {
05767            error:
05768              (*_bfd_error_handler)
05769               ("LINKER BUG: .rofixup section size mismatch");
05770              return FALSE;
05771            }
05772 
05773          hend = bfd_link_hash_lookup (info->hash, "__ROFIXUP_END__",
05774                                    FALSE, FALSE, TRUE);
05775          if (hend
05776              && (hend->type == bfd_link_hash_defined
05777                 || hend->type == bfd_link_hash_defweak))
05778            {
05779              bfd_vma value =
05780               frvfdpic_gotfixup_section (info)->output_section->vma
05781               + frvfdpic_gotfixup_section (info)->output_offset
05782               + frvfdpic_gotfixup_section (info)->size
05783               - hend->u.def.section->output_section->vma
05784               - hend->u.def.section->output_offset;
05785              BFD_ASSERT (hend->u.def.value == value);
05786              if (hend->u.def.value != value)
05787               goto error;
05788            }
05789        }
05790     }
05791   if (frvfdpic_pltrel_section (info))
05792     {
05793       BFD_ASSERT (frvfdpic_pltrel_section (info)->size
05794                 == (frvfdpic_pltrel_section (info)->reloc_count
05795                     * sizeof (Elf32_External_Rel)));
05796     }
05797 
05798 
05799   if (elf_hash_table (info)->dynamic_sections_created)
05800     {
05801       Elf32_External_Dyn * dyncon;
05802       Elf32_External_Dyn * dynconend;
05803 
05804       sdyn = bfd_get_section_by_name (dynobj, ".dynamic");
05805 
05806       BFD_ASSERT (sdyn != NULL);
05807 
05808       dyncon = (Elf32_External_Dyn *) sdyn->contents;
05809       dynconend = (Elf32_External_Dyn *) (sdyn->contents + sdyn->size);
05810 
05811       for (; dyncon < dynconend; dyncon++)
05812        {
05813          Elf_Internal_Dyn dyn;
05814 
05815          bfd_elf32_swap_dyn_in (dynobj, dyncon, &dyn);
05816 
05817          switch (dyn.d_tag)
05818            {
05819            default:
05820              break;
05821 
05822            case DT_PLTGOT:
05823              dyn.d_un.d_ptr = frvfdpic_got_section (info)->output_section->vma
05824               + frvfdpic_got_section (info)->output_offset
05825               + frvfdpic_got_initial_offset (info);
05826              bfd_elf32_swap_dyn_out (output_bfd, &dyn, dyncon);
05827              break;
05828 
05829            case DT_JMPREL:
05830              dyn.d_un.d_ptr = frvfdpic_pltrel_section (info)
05831               ->output_section->vma
05832               + frvfdpic_pltrel_section (info)->output_offset;
05833              bfd_elf32_swap_dyn_out (output_bfd, &dyn, dyncon);
05834              break;
05835 
05836            case DT_PLTRELSZ:
05837              dyn.d_un.d_val = frvfdpic_pltrel_section (info)->size;
05838              bfd_elf32_swap_dyn_out (output_bfd, &dyn, dyncon);
05839              break;
05840            }
05841        }
05842     }
05843 
05844   return TRUE;
05845 }
05846 
05847 /* Adjust a symbol defined by a dynamic object and referenced by a
05848    regular object.  */
05849 
05850 static bfd_boolean
05851 elf32_frvfdpic_adjust_dynamic_symbol
05852 (struct bfd_link_info *info ATTRIBUTE_UNUSED,
05853  struct elf_link_hash_entry *h ATTRIBUTE_UNUSED)
05854 {
05855   bfd * dynobj;
05856 
05857   dynobj = elf_hash_table (info)->dynobj;
05858 
05859   /* Make sure we know what is going on here.  */
05860   BFD_ASSERT (dynobj != NULL
05861              && (h->u.weakdef != NULL
05862                 || (h->def_dynamic
05863                     && h->ref_regular
05864                     && !h->def_regular)));
05865 
05866   /* If this is a weak symbol, and there is a real definition, the
05867      processor independent code will have arranged for us to see the
05868      real definition first, and we can just use the same value.  */
05869   if (h->u.weakdef != NULL)
05870     {
05871       BFD_ASSERT (h->u.weakdef->root.type == bfd_link_hash_defined
05872                 || h->u.weakdef->root.type == bfd_link_hash_defweak);
05873       h->root.u.def.section = h->u.weakdef->root.u.def.section;
05874       h->root.u.def.value = h->u.weakdef->root.u.def.value;
05875     }
05876 
05877   return TRUE;
05878 }
05879 
05880 /* Perform any actions needed for dynamic symbols.  */
05881 
05882 static bfd_boolean
05883 elf32_frvfdpic_finish_dynamic_symbol
05884 (bfd *output_bfd ATTRIBUTE_UNUSED,
05885  struct bfd_link_info *info ATTRIBUTE_UNUSED,
05886  struct elf_link_hash_entry *h ATTRIBUTE_UNUSED,
05887  Elf_Internal_Sym *sym ATTRIBUTE_UNUSED)
05888 {
05889   return TRUE;
05890 }
05891 
05892 /* Decide whether to attempt to turn absptr or lsda encodings in
05893    shared libraries into pcrel within the given input section.  */
05894 
05895 static bfd_boolean
05896 frvfdpic_elf_use_relative_eh_frame
05897 (bfd *input_bfd ATTRIBUTE_UNUSED,
05898  struct bfd_link_info *info ATTRIBUTE_UNUSED,
05899  asection *eh_frame_section ATTRIBUTE_UNUSED)
05900 {
05901   /* We can't use PC-relative encodings in FDPIC binaries, in general.  */
05902   return FALSE;
05903 }
05904 
05905 /* Adjust the contents of an eh_frame_hdr section before they're output.  */
05906 
05907 static bfd_byte
05908 frvfdpic_elf_encode_eh_address (bfd *abfd,
05909                             struct bfd_link_info *info,
05910                             asection *osec, bfd_vma offset,
05911                             asection *loc_sec, bfd_vma loc_offset,
05912                             bfd_vma *encoded)
05913 {
05914   struct elf_link_hash_entry *h;
05915 
05916   h = elf_hash_table (info)->hgot;
05917   BFD_ASSERT (h && h->root.type == bfd_link_hash_defined);
05918 
05919   if (! h || (_frvfdpic_osec_to_segment (abfd, osec)
05920              == _frvfdpic_osec_to_segment (abfd, loc_sec->output_section)))
05921     return _bfd_elf_encode_eh_address (abfd, info, osec, offset,
05922                                    loc_sec, loc_offset, encoded);
05923 
05924   BFD_ASSERT (_frvfdpic_osec_to_segment (abfd, osec)
05925              == (_frvfdpic_osec_to_segment
05926                 (abfd, h->root.u.def.section->output_section)));
05927 
05928   *encoded = osec->vma + offset
05929     - (h->root.u.def.value
05930        + h->root.u.def.section->output_section->vma
05931        + h->root.u.def.section->output_offset);
05932 
05933   return DW_EH_PE_datarel | DW_EH_PE_sdata4;
05934 }
05935 
05936 /* Look through the relocs for a section during the first phase.
05937 
05938    Besides handling virtual table relocs for gc, we have to deal with
05939    all sorts of PIC-related relocations.  We describe below the
05940    general plan on how to handle such relocations, even though we only
05941    collect information at this point, storing them in hash tables for
05942    perusal of later passes.
05943 
05944    32 relocations are propagated to the linker output when creating
05945    position-independent output.  LO16 and HI16 relocations are not
05946    supposed to be encountered in this case.
05947 
05948    LABEL16 should always be resolvable by the linker, since it's only
05949    used by branches.
05950 
05951    LABEL24, on the other hand, is used by calls.  If it turns out that
05952    the target of a call is a dynamic symbol, a PLT entry must be
05953    created for it, which triggers the creation of a private function
05954    descriptor and, unless lazy binding is disabled, a lazy PLT entry.
05955 
05956    GPREL relocations require the referenced symbol to be in the same
05957    segment as _gp, but this can only be checked later.
05958 
05959    All GOT, GOTOFF and FUNCDESC relocations require a .got section to
05960    exist.  LABEL24 might as well, since it may require a PLT entry,
05961    that will require a got.
05962 
05963    Non-FUNCDESC GOT relocations require a GOT entry to be created
05964    regardless of whether the symbol is dynamic.  However, since a
05965    global symbol that turns out to not be exported may have the same
05966    address of a non-dynamic symbol, we don't assign GOT entries at
05967    this point, such that we can share them in this case.  A relocation
05968    for the GOT entry always has to be created, be it to offset a
05969    private symbol by the section load address, be it to get the symbol
05970    resolved dynamically.
05971 
05972    FUNCDESC GOT relocations require a GOT entry to be created, and
05973    handled as if a FUNCDESC relocation was applied to the GOT entry in
05974    an object file.
05975 
05976    FUNCDESC relocations referencing a symbol that turns out to NOT be
05977    dynamic cause a private function descriptor to be created.  The
05978    FUNCDESC relocation then decays to a 32 relocation that points at
05979    the private descriptor.  If the symbol is dynamic, the FUNCDESC
05980    relocation is propagated to the linker output, such that the
05981    dynamic linker creates the canonical descriptor, pointing to the
05982    dynamically-resolved definition of the function.
05983 
05984    Non-FUNCDESC GOTOFF relocations must always refer to non-dynamic
05985    symbols that are assigned to the same segment as the GOT, but we
05986    can only check this later, after we know the complete set of
05987    symbols defined and/or exported.
05988 
05989    FUNCDESC GOTOFF relocations require a function descriptor to be
05990    created and, unless lazy binding is disabled or the symbol is not
05991    dynamic, a lazy PLT entry.  Since we can't tell at this point
05992    whether a symbol is going to be dynamic, we have to decide later
05993    whether to create a lazy PLT entry or bind the descriptor directly
05994    to the private function.
05995 
05996    FUNCDESC_VALUE relocations are not supposed to be present in object
05997    files, but they may very well be simply propagated to the linker
05998    output, since they have no side effect.
05999 
06000 
06001    A function descriptor always requires a FUNCDESC_VALUE relocation.
06002    Whether it's in .plt.rel or not depends on whether lazy binding is
06003    enabled and on whether the referenced symbol is dynamic.
06004 
06005    The existence of a lazy PLT requires the resolverStub lazy PLT
06006    entry to be present.
06007 
06008 
06009    As for assignment of GOT, PLT and lazy PLT entries, and private
06010    descriptors, we might do them all sequentially, but we can do
06011    better than that.  For example, we can place GOT entries and
06012    private function descriptors referenced using 12-bit operands
06013    closer to the PIC register value, such that these relocations don't
06014    overflow.  Those that are only referenced with LO16 relocations
06015    could come next, but we may as well place PLT-required function
06016    descriptors in the 12-bit range to make them shorter.  Symbols
06017    referenced with LO16/HI16 may come next, but we may place
06018    additional function descriptors in the 16-bit range if we can
06019    reliably tell that we've already placed entries that are ever
06020    referenced with only LO16.  PLT entries are therefore generated as
06021    small as possible, while not introducing relocation overflows in
06022    GOT or FUNCDESC_GOTOFF relocations.  Lazy PLT entries could be
06023    generated before or after PLT entries, but not intermingled with
06024    them, such that we can have more lazy PLT entries in range for a
06025    branch to the resolverStub.  The resolverStub should be emitted at
06026    the most distant location from the first lazy PLT entry such that
06027    it's still in range for a branch, or closer, if there isn't a need
06028    for so many lazy PLT entries.  Additional lazy PLT entries may be
06029    emitted after the resolverStub, as long as branches are still in
06030    range.  If the branch goes out of range, longer lazy PLT entries
06031    are emitted.
06032 
06033    We could further optimize PLT and lazy PLT entries by giving them
06034    priority in assignment to closer-to-gr17 locations depending on the
06035    number of occurrences of references to them (assuming a function
06036    that's called more often is more important for performance, so its
06037    PLT entry should be faster), or taking hints from the compiler.
06038    Given infinite time and money... :-)  */
06039 
06040 static bfd_boolean
06041 elf32_frv_check_relocs (abfd, info, sec, relocs)
06042      bfd *abfd;
06043      struct bfd_link_info *info;
06044      asection *sec;
06045      const Elf_Internal_Rela *relocs;
06046 {
06047   Elf_Internal_Shdr *symtab_hdr;
06048   struct elf_link_hash_entry **sym_hashes, **sym_hashes_end;
06049   const Elf_Internal_Rela *rel;
06050   const Elf_Internal_Rela *rel_end;
06051   bfd *dynobj;
06052   struct frvfdpic_relocs_info *picrel;
06053 
06054   if (info->relocatable)
06055     return TRUE;
06056 
06057   symtab_hdr = &elf_tdata (abfd)->symtab_hdr;
06058   sym_hashes = elf_sym_hashes (abfd);
06059   sym_hashes_end = sym_hashes + symtab_hdr->sh_size/sizeof(Elf32_External_Sym);
06060   if (!elf_bad_symtab (abfd))
06061     sym_hashes_end -= symtab_hdr->sh_info;
06062 
06063   dynobj = elf_hash_table (info)->dynobj;
06064   rel_end = relocs + sec->reloc_count;
06065   for (rel = relocs; rel < rel_end; rel++)
06066     {
06067       struct elf_link_hash_entry *h;
06068       unsigned long r_symndx;
06069 
06070       r_symndx = ELF32_R_SYM (rel->r_info);
06071       if (r_symndx < symtab_hdr->sh_info)
06072         h = NULL;
06073       else
06074        {
06075          h = sym_hashes[r_symndx - symtab_hdr->sh_info];
06076          while (h->root.type == bfd_link_hash_indirect
06077                || h->root.type == bfd_link_hash_warning)
06078            h = (struct elf_link_hash_entry *) h->root.u.i.link;
06079        }
06080 
06081       switch (ELF32_R_TYPE (rel->r_info))
06082        {
06083        case R_FRV_GETTLSOFF:
06084        case R_FRV_TLSDESC_VALUE:
06085        case R_FRV_GOTTLSDESC12:
06086        case R_FRV_GOTTLSDESCHI:
06087        case R_FRV_GOTTLSDESCLO:
06088        case R_FRV_GOTTLSOFF12:
06089        case R_FRV_GOTTLSOFFHI:
06090        case R_FRV_GOTTLSOFFLO:
06091        case R_FRV_TLSOFF:
06092        case R_FRV_GOT12:
06093        case R_FRV_GOTHI:
06094        case R_FRV_GOTLO:
06095        case R_FRV_FUNCDESC_GOT12:
06096        case R_FRV_FUNCDESC_GOTHI:
06097        case R_FRV_FUNCDESC_GOTLO:
06098        case R_FRV_GOTOFF12:
06099        case R_FRV_GOTOFFHI:
06100        case R_FRV_GOTOFFLO:
06101        case R_FRV_FUNCDESC_GOTOFF12:
06102        case R_FRV_FUNCDESC_GOTOFFHI:
06103        case R_FRV_FUNCDESC_GOTOFFLO:
06104        case R_FRV_FUNCDESC:
06105        case R_FRV_FUNCDESC_VALUE:
06106        case R_FRV_TLSMOFF12:
06107        case R_FRV_TLSMOFFHI:
06108        case R_FRV_TLSMOFFLO:
06109        case R_FRV_TLSMOFF:
06110          if (! IS_FDPIC (abfd))
06111            goto bad_reloc;
06112          /* Fall through.  */
06113        case R_FRV_GPREL12:
06114        case R_FRV_GPRELU12:
06115        case R_FRV_GPRELHI:
06116        case R_FRV_GPRELLO:
06117        case R_FRV_LABEL24:
06118        case R_FRV_32:
06119          if (! dynobj)
06120            {
06121              elf_hash_table (info)->dynobj = dynobj = abfd;
06122              if (! _frv_create_got_section (abfd, info))
06123               return FALSE;
06124            }
06125          if (! IS_FDPIC (abfd))
06126            {
06127              picrel = NULL;
06128              break;
06129            }
06130          if (h != NULL)
06131            {
06132              if (h->dynindx == -1)
06133               switch (ELF_ST_VISIBILITY (h->other))
06134                 {
06135                 case STV_INTERNAL:
06136                 case STV_HIDDEN:
06137                   break;
06138                 default:
06139                   bfd_elf_link_record_dynamic_symbol (info, h);
06140                   break;
06141                 }
06142              picrel
06143               = frvfdpic_relocs_info_for_global (frvfdpic_relocs_info (info),
06144                                              abfd, h,
06145                                              rel->r_addend, INSERT);
06146            }
06147          else
06148            picrel = frvfdpic_relocs_info_for_local (frvfdpic_relocs_info
06149                                                (info), abfd, r_symndx,
06150                                                rel->r_addend, INSERT);
06151          if (! picrel)
06152            return FALSE;
06153          break;
06154 
06155        default:
06156          picrel = NULL;
06157          break;
06158        }
06159 
06160       switch (ELF32_R_TYPE (rel->r_info))
06161         {
06162        case R_FRV_LABEL24:
06163          if (IS_FDPIC (abfd))
06164            picrel->call = 1;
06165          break;
06166 
06167        case R_FRV_FUNCDESC_VALUE:
06168          picrel->relocsfdv++;
06169          if (bfd_get_section_flags (abfd, sec) & SEC_ALLOC)
06170            picrel->relocs32--;
06171          /* Fall through.  */
06172 
06173        case R_FRV_32:
06174          if (! IS_FDPIC (abfd))
06175            break;
06176 
06177          picrel->sym = 1;
06178          if (bfd_get_section_flags (abfd, sec) & SEC_ALLOC)
06179            picrel->relocs32++;
06180          break;
06181 
06182        case R_FRV_GOT12:
06183          picrel->got12 = 1;
06184          break;
06185 
06186        case R_FRV_GOTHI:
06187        case R_FRV_GOTLO:
06188          picrel->gothilo = 1;
06189          break;
06190 
06191        case R_FRV_FUNCDESC_GOT12:
06192          picrel->fdgot12 = 1;
06193          break;
06194 
06195        case R_FRV_FUNCDESC_GOTHI:
06196        case R_FRV_FUNCDESC_GOTLO:
06197          picrel->fdgothilo = 1;
06198          break;
06199 
06200        case R_FRV_GOTOFF12:
06201        case R_FRV_GOTOFFHI:
06202        case R_FRV_GOTOFFLO:
06203          picrel->gotoff = 1;
06204          break;
06205 
06206        case R_FRV_FUNCDESC_GOTOFF12:
06207          picrel->fdgoff12 = 1;
06208          break;
06209 
06210        case R_FRV_FUNCDESC_GOTOFFHI:
06211        case R_FRV_FUNCDESC_GOTOFFLO:
06212          picrel->fdgoffhilo = 1;
06213          break;
06214 
06215        case R_FRV_FUNCDESC:
06216          picrel->fd = 1;
06217          picrel->relocsfd++;
06218          break;
06219 
06220        case R_FRV_GETTLSOFF:
06221          picrel->tlsplt = 1;
06222          break;
06223 
06224        case R_FRV_TLSDESC_VALUE:
06225          picrel->relocstlsd++;
06226          goto bad_reloc;
06227 
06228        case R_FRV_GOTTLSDESC12:
06229          picrel->tlsdesc12 = 1;
06230          break;
06231 
06232        case R_FRV_GOTTLSDESCHI:
06233        case R_FRV_GOTTLSDESCLO:
06234          picrel->tlsdeschilo = 1;
06235          break;
06236 
06237        case R_FRV_TLSMOFF12:
06238        case R_FRV_TLSMOFFHI:
06239        case R_FRV_TLSMOFFLO:
06240        case R_FRV_TLSMOFF:
06241          break;
06242 
06243        case R_FRV_GOTTLSOFF12:
06244          picrel->tlsoff12 = 1;
06245          info->flags |= DF_STATIC_TLS;
06246          break;
06247 
06248        case R_FRV_GOTTLSOFFHI:
06249        case R_FRV_GOTTLSOFFLO:
06250          picrel->tlsoffhilo = 1;
06251          info->flags |= DF_STATIC_TLS;
06252          break;
06253 
06254        case R_FRV_TLSOFF:
06255          picrel->relocstlsoff++;
06256          info->flags |= DF_STATIC_TLS;
06257          goto bad_reloc;
06258 
06259         /* This relocation describes the C++ object vtable hierarchy.
06260            Reconstruct it for later use during GC.  */
06261         case R_FRV_GNU_VTINHERIT:
06262           if (!bfd_elf_gc_record_vtinherit (abfd, sec, h, rel->r_offset))
06263             return FALSE;
06264           break;
06265 
06266         /* This relocation describes which C++ vtable entries are actually
06267            used.  Record for later use during GC.  */
06268         case R_FRV_GNU_VTENTRY:
06269           if (!bfd_elf_gc_record_vtentry (abfd, sec, h, rel->r_addend))
06270             return FALSE;
06271           break;
06272 
06273        case R_FRV_LABEL16:
06274        case R_FRV_LO16:
06275        case R_FRV_HI16:
06276        case R_FRV_GPREL12:
06277        case R_FRV_GPRELU12:
06278        case R_FRV_GPREL32:
06279        case R_FRV_GPRELHI:
06280        case R_FRV_GPRELLO:
06281        case R_FRV_TLSDESC_RELAX:
06282        case R_FRV_GETTLSOFF_RELAX:
06283        case R_FRV_TLSOFF_RELAX:
06284          break;
06285 
06286        default:
06287        bad_reloc:
06288          (*_bfd_error_handler)
06289            (_("%B: unsupported relocation type %i"),
06290             abfd, ELF32_R_TYPE (rel->r_info));
06291          return FALSE;
06292         }
06293     }
06294 
06295   return TRUE;
06296 }
06297 
06298 
06299 /* Return the machine subcode from the ELF e_flags header.  */
06300 
06301 static int
06302 elf32_frv_machine (abfd)
06303      bfd *abfd;
06304 {
06305   switch (elf_elfheader (abfd)->e_flags & EF_FRV_CPU_MASK)
06306     {
06307     default:             break;
06308     case EF_FRV_CPU_FR550:  return bfd_mach_fr550;
06309     case EF_FRV_CPU_FR500:  return bfd_mach_fr500;
06310     case EF_FRV_CPU_FR450:  return bfd_mach_fr450;
06311     case EF_FRV_CPU_FR405:  return bfd_mach_fr400;
06312     case EF_FRV_CPU_FR400:  return bfd_mach_fr400;
06313     case EF_FRV_CPU_FR300:  return bfd_mach_fr300;
06314     case EF_FRV_CPU_SIMPLE: return bfd_mach_frvsimple;
06315     case EF_FRV_CPU_TOMCAT: return bfd_mach_frvtomcat;
06316     }
06317 
06318   return bfd_mach_frv;
06319 }
06320 
06321 /* Set the right machine number for a FRV ELF file.  */
06322 
06323 static bfd_boolean
06324 elf32_frv_object_p (abfd)
06325      bfd *abfd;
06326 {
06327   bfd_default_set_arch_mach (abfd, bfd_arch_frv, elf32_frv_machine (abfd));
06328   return (((elf_elfheader (abfd)->e_flags & EF_FRV_FDPIC) != 0)
06329          == (IS_FDPIC (abfd)));
06330 }
06331 
06332 /* Function to set the ELF flag bits.  */
06333 
06334 static bfd_boolean
06335 frv_elf_set_private_flags (abfd, flags)
06336      bfd *abfd;
06337      flagword flags;
06338 {
06339   elf_elfheader (abfd)->e_flags = flags;
06340   elf_flags_init (abfd) = TRUE;
06341   return TRUE;
06342 }
06343 
06344 /* Copy backend specific data from one object module to another.  */
06345 
06346 static bfd_boolean
06347 frv_elf_copy_private_bfd_data (ibfd, obfd)
06348      bfd *ibfd;
06349      bfd *obfd;
06350 {
06351   if (bfd_get_flavour (ibfd) != bfd_target_elf_flavour
06352       || bfd_get_flavour (obfd) != bfd_target_elf_flavour)
06353     return TRUE;
06354 
06355   BFD_ASSERT (!elf_flags_init (obfd)
06356              || elf_elfheader (obfd)->e_flags == elf_elfheader (ibfd)->e_flags);
06357 
06358   elf_elfheader (obfd)->e_flags = elf_elfheader (ibfd)->e_flags;
06359   elf_flags_init (obfd) = TRUE;
06360   return TRUE;
06361 }
06362 
06363 /* Return true if the architecture described by elf header flag
06364    EXTENSION is an extension of the architecture described by BASE.  */
06365 
06366 static bfd_boolean
06367 frv_elf_arch_extension_p (flagword base, flagword extension)
06368 {
06369   if (base == extension)
06370     return TRUE;
06371 
06372   /* CPU_GENERIC code can be merged with code for a specific
06373      architecture, in which case the result is marked as being
06374      for the specific architecture.  Everything is therefore
06375      an extension of CPU_GENERIC.  */
06376   if (base == EF_FRV_CPU_GENERIC)
06377     return TRUE;
06378 
06379   if (extension == EF_FRV_CPU_FR450)
06380     if (base == EF_FRV_CPU_FR400 || base == EF_FRV_CPU_FR405)
06381       return TRUE;
06382 
06383   if (extension == EF_FRV_CPU_FR405)
06384     if (base == EF_FRV_CPU_FR400)
06385       return TRUE;
06386 
06387   return FALSE;
06388 }
06389 
06390 static bfd_boolean
06391 elf32_frvfdpic_copy_private_bfd_data (bfd *ibfd, bfd *obfd)
06392 {
06393   unsigned i;
06394 
06395   if (bfd_get_flavour (ibfd) != bfd_target_elf_flavour
06396       || bfd_get_flavour (obfd) != bfd_target_elf_flavour)
06397     return TRUE;
06398 
06399   if (! frv_elf_copy_private_bfd_data (ibfd, obfd))
06400     return FALSE;
06401 
06402   if (! elf_tdata (ibfd) || ! elf_tdata (ibfd)->phdr
06403       || ! elf_tdata (obfd) || ! elf_tdata (obfd)->phdr)
06404     return TRUE;
06405 
06406   /* Copy the stack size.  */
06407   for (i = 0; i < elf_elfheader (ibfd)->e_phnum; i++)
06408     if (elf_tdata (ibfd)->phdr[i].p_type == PT_GNU_STACK)
06409       {
06410        Elf_Internal_Phdr *iphdr = &elf_tdata (ibfd)->phdr[i];
06411 
06412        for (i = 0; i < elf_elfheader (obfd)->e_phnum; i++)
06413          if (elf_tdata (obfd)->phdr[i].p_type == PT_GNU_STACK)
06414            {
06415              memcpy (&elf_tdata (obfd)->phdr[i], iphdr, sizeof (*iphdr));
06416 
06417              /* Rewrite the phdrs, since we're only called after they
06418                were first written.  */
06419              if (bfd_seek (obfd, (bfd_signed_vma) get_elf_backend_data (obfd)
06420                          ->s->sizeof_ehdr, SEEK_SET) != 0
06421                 || get_elf_backend_data (obfd)->s
06422                 ->write_out_phdrs (obfd, elf_tdata (obfd)->phdr,
06423                                  elf_elfheader (obfd)->e_phnum) != 0)
06424               return FALSE;
06425              break;
06426            }
06427 
06428        break;
06429       }
06430 
06431   return TRUE;
06432 }
06433 
06434 /* Merge backend specific data from an object file to the output
06435    object file when linking.  */
06436 
06437 static bfd_boolean
06438 frv_elf_merge_private_bfd_data (ibfd, obfd)
06439      bfd *ibfd;
06440      bfd *obfd;
06441 {
06442   flagword old_flags, old_partial;
06443   flagword new_flags, new_partial;
06444   bfd_boolean error = FALSE;
06445   char new_opt[80];
06446   char old_opt[80];
06447 
06448   new_opt[0] = old_opt[0] = '\0';
06449   new_flags = elf_elfheader (ibfd)->e_flags;
06450   old_flags = elf_elfheader (obfd)->e_flags;
06451 
06452   if (new_flags & EF_FRV_FDPIC)
06453     new_flags &= ~EF_FRV_PIC;
06454 
06455 #ifdef DEBUG
06456   (*_bfd_error_handler) ("old_flags = 0x%.8lx, new_flags = 0x%.8lx, init = %s, filename = %s",
06457                       old_flags, new_flags, elf_flags_init (obfd) ? "yes" : "no",
06458                       bfd_get_filename (ibfd));
06459 #endif
06460 
06461   if (!elf_flags_init (obfd))                    /* First call, no flags set.  */
06462     {
06463       elf_flags_init (obfd) = TRUE;
06464       old_flags = new_flags;
06465     }
06466 
06467   else if (new_flags == old_flags)        /* Compatible flags are ok.  */
06468     ;
06469 
06470   else                                    /* Possibly incompatible flags.  */
06471     {
06472       /* Warn if different # of gprs are used.  Note, 0 means nothing is
06473          said about the size of gprs.  */
06474       new_partial = (new_flags & EF_FRV_GPR_MASK);
06475       old_partial = (old_flags & EF_FRV_GPR_MASK);
06476       if (new_partial == old_partial)
06477        ;
06478 
06479       else if (new_partial == 0)
06480        ;
06481 
06482       else if (old_partial == 0)
06483        old_flags |= new_partial;
06484 
06485       else
06486        {
06487          switch (new_partial)
06488            {
06489            default:         strcat (new_opt, " -mgpr-??"); break;
06490            case EF_FRV_GPR_32: strcat (new_opt, " -mgpr-32"); break;
06491            case EF_FRV_GPR_64: strcat (new_opt, " -mgpr-64"); break;
06492            }
06493 
06494          switch (old_partial)
06495            {
06496            default:         strcat (old_opt, " -mgpr-??"); break;
06497            case EF_FRV_GPR_32: strcat (old_opt, " -mgpr-32"); break;
06498            case EF_FRV_GPR_64: strcat (old_opt, " -mgpr-64"); break;
06499            }
06500        }
06501 
06502       /* Warn if different # of fprs are used.  Note, 0 means nothing is
06503          said about the size of fprs.  */
06504       new_partial = (new_flags & EF_FRV_FPR_MASK);
06505       old_partial = (old_flags & EF_FRV_FPR_MASK);
06506       if (new_partial == old_partial)
06507        ;
06508 
06509       else if (new_partial == 0)
06510        ;
06511 
06512       else if (old_partial == 0)
06513        old_flags |= new_partial;
06514 
06515       else
06516        {
06517          switch (new_partial)
06518            {
06519            default:           strcat (new_opt, " -mfpr-?");      break;
06520            case EF_FRV_FPR_32:   strcat (new_opt, " -mfpr-32");     break;
06521            case EF_FRV_FPR_64:   strcat (new_opt, " -mfpr-64");     break;
06522            case EF_FRV_FPR_NONE: strcat (new_opt, " -msoft-float"); break;
06523            }
06524 
06525          switch (old_partial)
06526            {
06527            default:           strcat (old_opt, " -mfpr-?");      break;
06528            case EF_FRV_FPR_32:   strcat (old_opt, " -mfpr-32");     break;
06529            case EF_FRV_FPR_64:   strcat (old_opt, " -mfpr-64");     break;
06530            case EF_FRV_FPR_NONE: strcat (old_opt, " -msoft-float"); break;
06531            }
06532        }
06533 
06534       /* Warn if different dword support was used.  Note, 0 means nothing is
06535          said about the dword support.  */
06536       new_partial = (new_flags & EF_FRV_DWORD_MASK);
06537       old_partial = (old_flags & EF_FRV_DWORD_MASK);
06538       if (new_partial == old_partial)
06539        ;
06540 
06541       else if (new_partial == 0)
06542        ;
06543 
06544       else if (old_partial == 0)
06545        old_flags |= new_partial;
06546 
06547       else
06548        {
06549          switch (new_partial)
06550            {
06551            default:            strcat (new_opt, " -mdword-?");  break;
06552            case EF_FRV_DWORD_YES: strcat (new_opt, " -mdword");    break;
06553            case EF_FRV_DWORD_NO:  strcat (new_opt, " -mno-dword"); break;
06554            }
06555 
06556          switch (old_partial)
06557            {
06558            default:            strcat (old_opt, " -mdword-?");  break;
06559            case EF_FRV_DWORD_YES: strcat (old_opt, " -mdword");    break;
06560            case EF_FRV_DWORD_NO:  strcat (old_opt, " -mno-dword"); break;
06561            }
06562        }
06563 
06564       /* Or in flags that accumulate (ie, if one module uses it, mark that the
06565         feature is used.  */
06566       old_flags |= new_flags & (EF_FRV_DOUBLE
06567                             | EF_FRV_MEDIA
06568                             | EF_FRV_MULADD
06569                             | EF_FRV_NON_PIC_RELOCS);
06570 
06571       /* If any module was compiled without -G0, clear the G0 bit.  */
06572       old_flags = ((old_flags & ~ EF_FRV_G0)
06573                  | (old_flags & new_flags & EF_FRV_G0));
06574 
06575       /* If any module was compiled without -mnopack, clear the mnopack bit.  */
06576       old_flags = ((old_flags & ~ EF_FRV_NOPACK)
06577                  | (old_flags & new_flags & EF_FRV_NOPACK));
06578 
06579       /* We don't have to do anything if the pic flags are the same, or the new
06580          module(s) were compiled with -mlibrary-pic.  */
06581       new_partial = (new_flags & EF_FRV_PIC_FLAGS);
06582       old_partial = (old_flags & EF_FRV_PIC_FLAGS);
06583       if ((new_partial == old_partial) || ((new_partial & EF_FRV_LIBPIC) != 0))
06584        ;
06585 
06586       /* If the old module(s) were compiled with -mlibrary-pic, copy in the pic
06587          flags if any from the new module.  */
06588       else if ((old_partial & EF_FRV_LIBPIC) != 0)
06589        old_flags = (old_flags & ~ EF_FRV_PIC_FLAGS) | new_partial;
06590 
06591       /* If we have mixtures of -fpic and -fPIC, or in both bits.  */
06592       else if (new_partial != 0 && old_partial != 0)
06593        old_flags |= new_partial;
06594 
06595       /* One module was compiled for pic and the other was not, see if we have
06596          had any relocations that are not pic-safe.  */
06597       else
06598        {
06599          if ((old_flags & EF_FRV_NON_PIC_RELOCS) == 0)
06600            old_flags |= new_partial;
06601          else
06602            {
06603              old_flags &= ~ EF_FRV_PIC_FLAGS;
06604 #ifndef FRV_NO_PIC_ERROR
06605              error = TRUE;
06606              (*_bfd_error_handler)
06607               (_("%s: compiled with %s and linked with modules that use non-pic relocations"),
06608                bfd_get_filename (ibfd),
06609                (new_flags & EF_FRV_BIGPIC) ? "-fPIC" : "-fpic");
06610 #endif
06611            }
06612        }
06613 
06614       /* Warn if different cpu is used (allow a specific cpu to override
06615         the generic cpu).  */
06616       new_partial = (new_flags & EF_FRV_CPU_MASK);
06617       old_partial = (old_flags & EF_FRV_CPU_MASK);
06618       if (frv_elf_arch_extension_p (new_partial, old_partial))
06619        ;
06620 
06621       else if (frv_elf_arch_extension_p (old_partial, new_partial))
06622        old_flags = (old_flags & ~EF_FRV_CPU_MASK) | new_partial;
06623 
06624       else
06625        {
06626          switch (new_partial)
06627            {
06628            default:              strcat (new_opt, " -mcpu=?");      break;
06629            case EF_FRV_CPU_GENERIC: strcat (new_opt, " -mcpu=frv");    break;
06630            case EF_FRV_CPU_SIMPLE:  strcat (new_opt, " -mcpu=simple"); break;
06631            case EF_FRV_CPU_FR550:   strcat (new_opt, " -mcpu=fr550");  break;
06632            case EF_FRV_CPU_FR500:   strcat (new_opt, " -mcpu=fr500");  break;
06633            case EF_FRV_CPU_FR450:   strcat (new_opt, " -mcpu=fr450");  break;
06634            case EF_FRV_CPU_FR405:   strcat (new_opt, " -mcpu=fr405");  break;
06635            case EF_FRV_CPU_FR400:   strcat (new_opt, " -mcpu=fr400");  break;
06636            case EF_FRV_CPU_FR300:   strcat (new_opt, " -mcpu=fr300");  break;
06637            case EF_FRV_CPU_TOMCAT:  strcat (new_opt, " -mcpu=tomcat"); break;
06638            }
06639 
06640          switch (old_partial)
06641            {
06642            default:              strcat (old_opt, " -mcpu=?");      break;
06643            case EF_FRV_CPU_GENERIC: strcat (old_opt, " -mcpu=frv");    break;
06644            case EF_FRV_CPU_SIMPLE:  strcat (old_opt, " -mcpu=simple"); break;
06645            case EF_FRV_CPU_FR550:   strcat (old_opt, " -mcpu=fr550");  break;
06646            case EF_FRV_CPU_FR500:   strcat (old_opt, " -mcpu=fr500");  break;
06647            case EF_FRV_CPU_FR450:   strcat (old_opt, " -mcpu=fr450");  break;
06648            case EF_FRV_CPU_FR405:   strcat (old_opt, " -mcpu=fr405");  break;
06649            case EF_FRV_CPU_FR400:   strcat (old_opt, " -mcpu=fr400");  break;
06650            case EF_FRV_CPU_FR300:   strcat (old_opt, " -mcpu=fr300");  break;
06651            case EF_FRV_CPU_TOMCAT:  strcat (old_opt, " -mcpu=tomcat"); break;
06652            }
06653        }
06654 
06655       /* Print out any mismatches from above.  */
06656       if (new_opt[0])
06657        {
06658          error = TRUE;
06659          (*_bfd_error_handler)
06660            (_("%s: compiled with %s and linked with modules compiled with %s"),
06661             bfd_get_filename (ibfd), new_opt, old_opt);
06662        }
06663 
06664       /* Warn about any other mismatches */
06665       new_partial = (new_flags & ~ EF_FRV_ALL_FLAGS);
06666       old_partial = (old_flags & ~ EF_FRV_ALL_FLAGS);
06667       if (new_partial != old_partial)
06668        {
06669          old_flags |= new_partial;
06670          error = TRUE;
06671          (*_bfd_error_handler)
06672            (_("%s: uses different unknown e_flags (0x%lx) fields than previous modules (0x%lx)"),
06673             bfd_get_filename (ibfd), (long)new_partial, (long)old_partial);
06674        }
06675     }
06676 
06677   /* If the cpu is -mcpu=simple, then set the -mnopack bit.  */
06678   if ((old_flags & EF_FRV_CPU_MASK) == EF_FRV_CPU_SIMPLE)
06679     old_flags |= EF_FRV_NOPACK;
06680 
06681   /* Update the old flags now with changes made above.  */
06682   old_partial = elf_elfheader (obfd)->e_flags & EF_FRV_CPU_MASK;
06683   elf_elfheader (obfd)->e_flags = old_flags;
06684   if (old_partial != (old_flags & EF_FRV_CPU_MASK))
06685     bfd_default_set_arch_mach (obfd, bfd_arch_frv, elf32_frv_machine (obfd));
06686 
06687   if (((new_flags & EF_FRV_FDPIC) == 0)
06688       != (! IS_FDPIC (ibfd)))
06689     {
06690       error = TRUE;
06691       if (IS_FDPIC (obfd))
06692        (*_bfd_error_handler)
06693          (_("%s: cannot link non-fdpic object file into fdpic executable"),
06694           bfd_get_filename (ibfd));
06695       else
06696        (*_bfd_error_handler)
06697          (_("%s: cannot link fdpic object file into non-fdpic executable"),
06698           bfd_get_filename (ibfd));
06699     }
06700 
06701   if (error)
06702     bfd_set_error (bfd_error_bad_value);
06703 
06704   return !error;
06705 }
06706 
06707 
06708 bfd_boolean
06709 frv_elf_print_private_bfd_data (abfd, ptr)
06710      bfd *abfd;
06711      PTR ptr;
06712 {
06713   FILE *file = (FILE *) ptr;
06714   flagword flags;
06715 
06716   BFD_ASSERT (abfd != NULL && ptr != NULL);
06717 
06718   /* Print normal ELF private data.  */
06719   _bfd_elf_print_private_bfd_data (abfd, ptr);
06720 
06721   flags = elf_elfheader (abfd)->e_flags;
06722   fprintf (file, _("private flags = 0x%lx:"), (long)flags);
06723 
06724   switch (flags & EF_FRV_CPU_MASK)
06725     {
06726     default:                                            break;
06727     case EF_FRV_CPU_SIMPLE: fprintf (file, " -mcpu=simple");   break;
06728     case EF_FRV_CPU_FR550:  fprintf (file, " -mcpu=fr550");    break;
06729     case EF_FRV_CPU_FR500:  fprintf (file, " -mcpu=fr500");    break;
06730     case EF_FRV_CPU_FR450:  fprintf (file, " -mcpu=fr450");    break;
06731     case EF_FRV_CPU_FR405:  fprintf (file, " -mcpu=fr405");    break;
06732     case EF_FRV_CPU_FR400:  fprintf (file, " -mcpu=fr400");    break;
06733     case EF_FRV_CPU_FR300:  fprintf (file, " -mcpu=fr300");    break;
06734     case EF_FRV_CPU_TOMCAT: fprintf (file, " -mcpu=tomcat");   break;
06735     }
06736 
06737   switch (flags & EF_FRV_GPR_MASK)
06738     {
06739     default:                                            break;
06740     case EF_FRV_GPR_32: fprintf (file, " -mgpr-32");           break;
06741     case EF_FRV_GPR_64: fprintf (file, " -mgpr-64");           break;
06742     }
06743 
06744   switch (flags & EF_FRV_FPR_MASK)
06745     {
06746     default:                                            break;
06747     case EF_FRV_FPR_32:   fprintf (file, " -mfpr-32");         break;
06748     case EF_FRV_FPR_64:   fprintf (file, " -mfpr-64");         break;
06749     case EF_FRV_FPR_NONE: fprintf (file, " -msoft-float");     break;
06750     }
06751 
06752   switch (flags & EF_FRV_DWORD_MASK)
06753     {
06754     default:                                            break;
06755     case EF_FRV_DWORD_YES: fprintf (file, " -mdword");         break;
06756     case EF_FRV_DWORD_NO:  fprintf (file, " -mno-dword");      break;
06757     }
06758 
06759   if (flags & EF_FRV_DOUBLE)
06760     fprintf (file, " -mdouble");
06761 
06762   if (flags & EF_FRV_MEDIA)
06763     fprintf (file, " -mmedia");
06764 
06765   if (flags & EF_FRV_MULADD)
06766     fprintf (file, " -mmuladd");
06767 
06768   if (flags & EF_FRV_PIC)
06769     fprintf (file, " -fpic");
06770 
06771   if (flags & EF_FRV_BIGPIC)
06772     fprintf (file, " -fPIC");
06773 
06774   if (flags & EF_FRV_LIBPIC)
06775     fprintf (file, " -mlibrary-pic");
06776 
06777   if (flags & EF_FRV_FDPIC)
06778     fprintf (file, " -mfdpic");
06779 
06780   if (flags & EF_FRV_NON_PIC_RELOCS)
06781     fprintf (file, " non-pic relocations");
06782 
06783   if (flags & EF_FRV_G0)
06784     fprintf (file, " -G0");
06785 
06786   fputc ('\n', file);
06787   return TRUE;
06788 }
06789 
06790 
06791 /* Support for core dump NOTE sections.  */
06792 
06793 static bfd_boolean
06794 elf32_frv_grok_prstatus (bfd *abfd, Elf_Internal_Note *note)
06795 {
06796   int offset;
06797   unsigned int raw_size;
06798 
06799   switch (note->descsz)
06800     {
06801       default:
06802        return FALSE;
06803 
06804       /* The Linux/FRV elf_prstatus struct is 268 bytes long.  The other
06805          hardcoded offsets and sizes listed below (and contained within
06806         this lexical block) refer to fields in the target's elf_prstatus
06807         struct.  */
06808       case 268:      
06809        /* `pr_cursig' is at offset 12.  */
06810        elf_tdata (abfd)->core_signal = bfd_get_16 (abfd, note->descdata + 12);
06811 
06812        /* `pr_pid' is at offset 24.  */
06813        elf_tdata (abfd)->core_pid = bfd_get_32 (abfd, note->descdata + 24);
06814 
06815        /* `pr_reg' is at offset 72.  */
06816        offset = 72;
06817 
06818        /* Most grok_prstatus implementations set `raw_size' to the size
06819           of the pr_reg field.  For Linux/FRV, we set `raw_size' to be
06820           the size of `pr_reg' plus the size of `pr_exec_fdpic_loadmap'
06821           and `pr_interp_fdpic_loadmap', both of which (by design)
06822           immediately follow `pr_reg'.  This will allow these fields to
06823           be viewed by GDB as registers.
06824           
06825           `pr_reg' is 184 bytes long.  `pr_exec_fdpic_loadmap' and
06826           `pr_interp_fdpic_loadmap' are 4 bytes each.  */
06827        raw_size = 184 + 4 + 4;
06828 
06829        break;
06830     }
06831 
06832   /* Make a ".reg/999" section.  */
06833   return _bfd_elfcore_make_pseudosection (abfd, ".reg", raw_size,
06834                                      note->descpos + offset);
06835 }
06836 
06837 static bfd_boolean
06838 elf32_frv_grok_psinfo (bfd *abfd, Elf_Internal_Note *note)
06839 {
06840   switch (note->descsz)
06841     {
06842       default:
06843        return FALSE;
06844 
06845       /* The Linux/FRV elf_prpsinfo struct is 124 bytes long.  */
06846       case 124:
06847 
06848        /* `pr_fname' is found at offset 28 and is 16 bytes long.  */
06849        elf_tdata (abfd)->core_program
06850          = _bfd_elfcore_strndup (abfd, note->descdata + 28, 16);
06851 
06852        /* `pr_psargs' is found at offset 44 and is 80 bytes long.  */
06853        elf_tdata (abfd)->core_command
06854          = _bfd_elfcore_strndup (abfd, note->descdata + 44, 80);
06855     }
06856 
06857   /* Note that for some reason, a spurious space is tacked
06858      onto the end of the args in some (at least one anyway)
06859      implementations, so strip it off if it exists.  */
06860 
06861   {
06862     char *command = elf_tdata (abfd)->core_command;
06863     int n = strlen (command);
06864 
06865     if (0 < n && command[n - 1] == ' ')
06866       command[n - 1] = '\0';
06867   }
06868 
06869   return TRUE;
06870 }
06871 #define ELF_ARCH            bfd_arch_frv
06872 #define ELF_MACHINE_CODE    EM_CYGNUS_FRV
06873 #define ELF_MAXPAGESIZE            0x1000
06874 
06875 #define TARGET_BIG_SYM          bfd_elf32_frv_vec
06876 #define TARGET_BIG_NAME            "elf32-frv"
06877 
06878 #define elf_info_to_howto                 frv_info_to_howto_rela
06879 #define elf_backend_relocate_section             elf32_frv_relocate_section
06880 #define elf_backend_gc_mark_hook          elf32_frv_gc_mark_hook
06881 #define elf_backend_check_relocs                elf32_frv_check_relocs
06882 #define elf_backend_object_p                     elf32_frv_object_p
06883 #define elf_backend_add_symbol_hook             elf32_frv_add_symbol_hook
06884 
06885 #define elf_backend_can_gc_sections              1
06886 #define elf_backend_rela_normal                  1
06887 
06888 #define bfd_elf32_bfd_reloc_type_lookup          frv_reloc_type_lookup
06889 #define bfd_elf32_bfd_reloc_name_lookup   frv_reloc_name_lookup
06890 #define bfd_elf32_bfd_set_private_flags          frv_elf_set_private_flags
06891 #define bfd_elf32_bfd_copy_private_bfd_data      frv_elf_copy_private_bfd_data
06892 #define bfd_elf32_bfd_merge_private_bfd_data     frv_elf_merge_private_bfd_data
06893 #define bfd_elf32_bfd_print_private_bfd_data     frv_elf_print_private_bfd_data
06894 
06895 #define elf_backend_want_got_sym   1
06896 #define elf_backend_got_header_size       0
06897 #define elf_backend_want_got_plt   0
06898 #define elf_backend_plt_readonly   1
06899 #define elf_backend_want_plt_sym   0
06900 #define elf_backend_plt_header_size       0
06901 
06902 #define elf_backend_finish_dynamic_sections \
06903               elf32_frv_finish_dynamic_sections
06904 
06905 #define elf_backend_grok_prstatus  elf32_frv_grok_prstatus
06906 #define elf_backend_grok_psinfo           elf32_frv_grok_psinfo
06907 
06908 #include "elf32-target.h"
06909 
06910 #undef ELF_MAXPAGESIZE
06911 #define ELF_MAXPAGESIZE            0x4000
06912 
06913 #undef TARGET_BIG_SYM
06914 #define TARGET_BIG_SYM          bfd_elf32_frvfdpic_vec
06915 #undef TARGET_BIG_NAME
06916 #define TARGET_BIG_NAME            "elf32-frvfdpic"
06917 #undef elf32_bed
06918 #define       elf32_bed            elf32_frvfdpic_bed
06919 
06920 #undef elf_info_to_howto_rel
06921 #define elf_info_to_howto_rel      frvfdpic_info_to_howto_rel
06922 
06923 #undef bfd_elf32_bfd_link_hash_table_create
06924 #define bfd_elf32_bfd_link_hash_table_create \
06925               frvfdpic_elf_link_hash_table_create
06926 #undef elf_backend_always_size_sections
06927 #define elf_backend_always_size_sections \
06928               elf32_frvfdpic_always_size_sections
06929 #undef elf_backend_modify_program_headers
06930 #define elf_backend_modify_program_headers \
06931               elf32_frvfdpic_modify_program_headers
06932 #undef bfd_elf32_bfd_copy_private_bfd_data
06933 #define bfd_elf32_bfd_copy_private_bfd_data \
06934               elf32_frvfdpic_copy_private_bfd_data
06935 
06936 #undef elf_backend_create_dynamic_sections
06937 #define elf_backend_create_dynamic_sections \
06938               elf32_frvfdpic_create_dynamic_sections
06939 #undef elf_backend_adjust_dynamic_symbol
06940 #define elf_backend_adjust_dynamic_symbol \
06941               elf32_frvfdpic_adjust_dynamic_symbol
06942 #undef elf_backend_size_dynamic_sections
06943 #define elf_backend_size_dynamic_sections \
06944               elf32_frvfdpic_size_dynamic_sections
06945 #undef bfd_elf32_bfd_relax_section
06946 #define bfd_elf32_bfd_relax_section \
06947   elf32_frvfdpic_relax_section
06948 #undef elf_backend_finish_dynamic_symbol
06949 #define elf_backend_finish_dynamic_symbol \
06950               elf32_frvfdpic_finish_dynamic_symbol
06951 #undef elf_backend_finish_dynamic_sections
06952 #define elf_backend_finish_dynamic_sections \
06953               elf32_frvfdpic_finish_dynamic_sections
06954 
06955 #undef elf_backend_can_make_relative_eh_frame
06956 #define elf_backend_can_make_relative_eh_frame \
06957               frvfdpic_elf_use_relative_eh_frame
06958 #undef elf_backend_can_make_lsda_relative_eh_frame
06959 #define elf_backend_can_make_lsda_relative_eh_frame \
06960               frvfdpic_elf_use_relative_eh_frame
06961 #undef elf_backend_encode_eh_address
06962 #define elf_backend_encode_eh_address \
06963               frvfdpic_elf_encode_eh_address
06964 
06965 #undef elf_backend_may_use_rel_p
06966 #define elf_backend_may_use_rel_p       1
06967 #undef elf_backend_may_use_rela_p
06968 #define elf_backend_may_use_rela_p      1
06969 /* We use REL for dynamic relocations only.  */
06970 #undef elf_backend_default_use_rela_p
06971 #define elf_backend_default_use_rela_p  1
06972 
06973 #undef elf_backend_omit_section_dynsym
06974 #define elf_backend_omit_section_dynsym _frvfdpic_link_omit_section_dynsym
06975 
06976 #include "elf32-target.h"