Home | History | Annotate | Line # | Download | only in bfd
      1   1.1  christos /* Xtensa-specific support for 32-bit ELF.
      2  1.10  christos    Copyright (C) 2003-2025 Free Software Foundation, Inc.
      3   1.1  christos 
      4   1.1  christos    This file is part of BFD, the Binary File Descriptor library.
      5   1.1  christos 
      6   1.1  christos    This program is free software; you can redistribute it and/or
      7   1.1  christos    modify it under the terms of the GNU General Public License as
      8   1.1  christos    published by the Free Software Foundation; either version 3 of the
      9   1.1  christos    License, or (at your option) any later version.
     10   1.1  christos 
     11   1.1  christos    This program is distributed in the hope that it will be useful, but
     12   1.1  christos    WITHOUT ANY WARRANTY; without even the implied warranty of
     13   1.1  christos    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
     14   1.1  christos    General Public License for more details.
     15   1.1  christos 
     16   1.1  christos    You should have received a copy of the GNU General Public License
     17   1.1  christos    along with this program; if not, write to the Free Software
     18   1.1  christos    Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA
     19   1.1  christos    02110-1301, USA.  */
     20   1.1  christos 
     21   1.1  christos #include "sysdep.h"
     22   1.1  christos #include "bfd.h"
     23   1.1  christos 
     24   1.1  christos #include <stdarg.h>
     25   1.1  christos #include <strings.h>
     26   1.1  christos 
     27   1.1  christos #include "bfdlink.h"
     28   1.1  christos #include "libbfd.h"
     29   1.1  christos #include "elf-bfd.h"
     30   1.1  christos #include "elf/xtensa.h"
     31   1.3  christos #include "splay-tree.h"
     32   1.1  christos #include "xtensa-isa.h"
     33   1.9  christos #include "xtensa-dynconfig.h"
     34   1.1  christos 
     35   1.7  christos /* All users of this file have bfd_octets_per_byte (abfd, sec) == 1.  */
     36   1.7  christos #define OCTETS_PER_BYTE(ABFD, SEC) 1
     37   1.7  christos 
     38   1.1  christos #define XTENSA_NO_NOP_REMOVAL 0
     39   1.1  christos 
     40   1.8  christos #ifndef XTHAL_ABI_UNDEFINED
     41   1.8  christos #define XTHAL_ABI_UNDEFINED -1
     42   1.8  christos #endif
     43   1.8  christos 
     44   1.1  christos /* Local helper functions.  */
     45   1.1  christos 
     46   1.8  christos static bool add_extra_plt_sections (struct bfd_link_info *, int);
     47   1.1  christos static char *vsprint_msg (const char *, const char *, int, ...) ATTRIBUTE_PRINTF(2,4);
     48   1.1  christos static bfd_reloc_status_type bfd_elf_xtensa_reloc
     49   1.1  christos   (bfd *, arelent *, asymbol *, void *, asection *, bfd *, char **);
     50   1.8  christos static bool do_fix_for_relocatable_link
     51   1.1  christos   (Elf_Internal_Rela *, bfd *, asection *, bfd_byte *);
     52   1.1  christos static void do_fix_for_final_link
     53   1.1  christos   (Elf_Internal_Rela *, bfd *, asection *, bfd_byte *, bfd_vma *);
     54   1.1  christos 
     55   1.1  christos /* Local functions to handle Xtensa configurability.  */
     56   1.1  christos 
     57   1.8  christos static bool is_indirect_call_opcode (xtensa_opcode);
     58   1.8  christos static bool is_direct_call_opcode (xtensa_opcode);
     59   1.8  christos static bool is_windowed_call_opcode (xtensa_opcode);
     60   1.1  christos static xtensa_opcode get_const16_opcode (void);
     61   1.1  christos static xtensa_opcode get_l32r_opcode (void);
     62   1.1  christos static bfd_vma l32r_offset (bfd_vma, bfd_vma);
     63   1.1  christos static int get_relocation_opnd (xtensa_opcode, int);
     64   1.1  christos static int get_relocation_slot (int);
     65   1.1  christos static xtensa_opcode get_relocation_opcode
     66   1.1  christos   (bfd *, asection *, bfd_byte *, Elf_Internal_Rela *);
     67   1.8  christos static bool is_l32r_relocation
     68   1.1  christos   (bfd *, asection *, bfd_byte *, Elf_Internal_Rela *);
     69   1.8  christos static bool is_alt_relocation (int);
     70   1.8  christos static bool is_operand_relocation (int);
     71   1.1  christos static bfd_size_type insn_decode_len
     72   1.1  christos   (bfd_byte *, bfd_size_type, bfd_size_type);
     73   1.7  christos static int insn_num_slots
     74   1.7  christos   (bfd_byte *, bfd_size_type, bfd_size_type);
     75   1.1  christos static xtensa_opcode insn_decode_opcode
     76   1.1  christos   (bfd_byte *, bfd_size_type, bfd_size_type, int);
     77   1.8  christos static bool check_branch_target_aligned
     78   1.1  christos   (bfd_byte *, bfd_size_type, bfd_vma, bfd_vma);
     79   1.8  christos static bool check_loop_aligned
     80   1.1  christos   (bfd_byte *, bfd_size_type, bfd_vma, bfd_vma);
     81   1.8  christos static bool check_branch_target_aligned_address (bfd_vma, int);
     82   1.1  christos static bfd_size_type get_asm_simplify_size
     83   1.1  christos   (bfd_byte *, bfd_size_type, bfd_size_type);
     84   1.1  christos 
     85   1.1  christos /* Functions for link-time code simplifications.  */
     86   1.1  christos 
     87   1.1  christos static bfd_reloc_status_type elf_xtensa_do_asm_simplify
     88   1.1  christos   (bfd_byte *, bfd_vma, bfd_vma, char **);
     89   1.1  christos static bfd_reloc_status_type contract_asm_expansion
     90   1.1  christos   (bfd_byte *, bfd_vma, Elf_Internal_Rela *, char **);
     91   1.1  christos static xtensa_opcode swap_callx_for_call_opcode (xtensa_opcode);
     92   1.8  christos static xtensa_opcode get_expanded_call_opcode (bfd_byte *, int, bool *);
     93   1.1  christos 
     94   1.1  christos /* Access to internal relocations, section contents and symbols.  */
     95   1.1  christos 
     96   1.1  christos static Elf_Internal_Rela *retrieve_internal_relocs
     97   1.8  christos   (bfd *, asection *, bool);
     98   1.1  christos static void pin_internal_relocs (asection *, Elf_Internal_Rela *);
     99   1.1  christos static void release_internal_relocs (asection *, Elf_Internal_Rela *);
    100   1.8  christos static bfd_byte *retrieve_contents (bfd *, asection *, bool);
    101   1.1  christos static void pin_contents (asection *, bfd_byte *);
    102   1.1  christos static void release_contents (asection *, bfd_byte *);
    103   1.1  christos static Elf_Internal_Sym *retrieve_local_syms (bfd *);
    104   1.1  christos 
    105   1.1  christos /* Miscellaneous utility functions.  */
    106   1.1  christos 
    107   1.1  christos static asection *elf_xtensa_get_plt_section (struct bfd_link_info *, int);
    108   1.1  christos static asection *elf_xtensa_get_gotplt_section (struct bfd_link_info *, int);
    109   1.1  christos static asection *get_elf_r_symndx_section (bfd *, unsigned long);
    110   1.1  christos static struct elf_link_hash_entry *get_elf_r_symndx_hash_entry
    111   1.1  christos   (bfd *, unsigned long);
    112   1.1  christos static bfd_vma get_elf_r_symndx_offset (bfd *, unsigned long);
    113   1.8  christos static bool is_reloc_sym_weak (bfd *, Elf_Internal_Rela *);
    114   1.8  christos static bool pcrel_reloc_fits (xtensa_opcode, int, bfd_vma, bfd_vma);
    115   1.8  christos static bool xtensa_is_property_section (asection *);
    116   1.8  christos static bool xtensa_is_insntable_section (asection *);
    117   1.8  christos static bool xtensa_is_littable_section (asection *);
    118   1.8  christos static bool xtensa_is_proptable_section (asection *);
    119   1.1  christos static int internal_reloc_compare (const void *, const void *);
    120   1.1  christos static int internal_reloc_matches (const void *, const void *);
    121   1.1  christos static asection *xtensa_get_property_section (asection *, const char *);
    122   1.1  christos static flagword xtensa_get_property_predef_flags (asection *);
    123   1.1  christos 
    124   1.1  christos /* Other functions called directly by the linker.  */
    125   1.1  christos 
    126   1.1  christos typedef void (*deps_callback_t)
    127   1.1  christos   (asection *, bfd_vma, asection *, bfd_vma, void *);
    128   1.8  christos extern bool xtensa_callback_required_dependence
    129   1.1  christos   (bfd *, asection *, struct bfd_link_info *, deps_callback_t, void *);
    130   1.1  christos 
    131   1.1  christos 
    132   1.1  christos /* Globally visible flag for choosing size optimization of NOP removal
    133   1.1  christos    instead of branch-target-aware minimization for NOP removal.
    134   1.1  christos    When nonzero, narrow all instructions and remove all NOPs possible
    135   1.1  christos    around longcall expansions.  */
    136   1.1  christos 
    137   1.1  christos int elf32xtensa_size_opt;
    138   1.1  christos 
    139   1.1  christos 
    140   1.1  christos /* The "new_section_hook" is used to set up a per-section
    141   1.1  christos    "xtensa_relax_info" data structure with additional information used
    142   1.1  christos    during relaxation.  */
    143   1.1  christos 
    144   1.1  christos typedef struct xtensa_relax_info_struct xtensa_relax_info;
    145   1.1  christos 
    146   1.1  christos 
    147   1.1  christos /* The GNU tools do not easily allow extending interfaces to pass around
    148   1.1  christos    the pointer to the Xtensa ISA information, so instead we add a global
    149   1.1  christos    variable here (in BFD) that can be used by any of the tools that need
    150   1.1  christos    this information. */
    151   1.1  christos 
    152   1.1  christos xtensa_isa xtensa_default_isa;
    153   1.1  christos 
    154   1.1  christos 
    155   1.1  christos /* When this is true, relocations may have been modified to refer to
    156   1.1  christos    symbols from other input files.  The per-section list of "fix"
    157   1.1  christos    records needs to be checked when resolving relocations.  */
    158   1.1  christos 
    159   1.8  christos static bool relaxing_section = false;
    160   1.1  christos 
    161   1.1  christos /* When this is true, during final links, literals that cannot be
    162   1.1  christos    coalesced and their relocations may be moved to other sections.  */
    163   1.1  christos 
    164   1.1  christos int elf32xtensa_no_literal_movement = 1;
    165   1.1  christos 
    166   1.6  christos /* Place property records for a section into individual property section
    167   1.6  christos    with xt.prop. prefix.  */
    168   1.6  christos 
    169   1.8  christos bool elf32xtensa_separate_props = false;
    170   1.8  christos 
    171   1.8  christos /* Xtensa ABI.  It affects PLT entry code.  */
    172   1.8  christos 
    173   1.8  christos int elf32xtensa_abi = XTHAL_ABI_UNDEFINED;
    174   1.6  christos 
    175   1.1  christos /* Rename one of the generic section flags to better document how it
    176   1.1  christos    is used here.  */
    177   1.1  christos /* Whether relocations have been processed.  */
    178   1.1  christos #define reloc_done sec_flg0
    179   1.1  christos 
    180   1.1  christos static reloc_howto_type elf_howto_table[] =
    182   1.8  christos {
    183   1.1  christos   HOWTO (R_XTENSA_NONE, 0, 0, 0, false, 0, complain_overflow_dont,
    184   1.8  christos 	 bfd_elf_xtensa_reloc, "R_XTENSA_NONE",
    185   1.8  christos 	 false, 0, 0, false),
    186   1.1  christos   HOWTO (R_XTENSA_32, 0, 4, 32, false, 0, complain_overflow_bitfield,
    187   1.8  christos 	 bfd_elf_xtensa_reloc, "R_XTENSA_32",
    188   1.1  christos 	 true, 0xffffffff, 0xffffffff, false),
    189   1.1  christos 
    190   1.1  christos   /* Replace a 32-bit value with a value from the runtime linker (only
    191   1.1  christos      used by linker-generated stub functions).  The r_addend value is
    192   1.1  christos      special: 1 means to substitute a pointer to the runtime linker's
    193   1.1  christos      dynamic resolver function; 2 means to substitute the link map for
    194   1.8  christos      the shared object.  */
    195   1.8  christos   HOWTO (R_XTENSA_RTLD, 0, 4, 32, false, 0, complain_overflow_dont,
    196   1.1  christos 	 NULL, "R_XTENSA_RTLD", false, 0, 0, false),
    197   1.8  christos 
    198   1.1  christos   HOWTO (R_XTENSA_GLOB_DAT, 0, 4, 32, false, 0, complain_overflow_bitfield,
    199   1.8  christos 	 bfd_elf_generic_reloc, "R_XTENSA_GLOB_DAT",
    200   1.8  christos 	 false, 0, 0xffffffff, false),
    201   1.1  christos   HOWTO (R_XTENSA_JMP_SLOT, 0, 4, 32, false, 0, complain_overflow_bitfield,
    202   1.8  christos 	 bfd_elf_generic_reloc, "R_XTENSA_JMP_SLOT",
    203   1.8  christos 	 false, 0, 0xffffffff, false),
    204   1.1  christos   HOWTO (R_XTENSA_RELATIVE, 0, 4, 32, false, 0, complain_overflow_bitfield,
    205   1.8  christos 	 bfd_elf_generic_reloc, "R_XTENSA_RELATIVE",
    206   1.8  christos 	 false, 0, 0xffffffff, false),
    207   1.1  christos   HOWTO (R_XTENSA_PLT, 0, 4, 32, false, 0, complain_overflow_bitfield,
    208   1.8  christos 	 bfd_elf_xtensa_reloc, "R_XTENSA_PLT",
    209   1.1  christos 	 false, 0, 0xffffffff, false),
    210   1.1  christos 
    211   1.1  christos   EMPTY_HOWTO (7),
    212   1.1  christos 
    213   1.8  christos   /* Old relocations for backward compatibility.  */
    214   1.8  christos   HOWTO (R_XTENSA_OP0, 0, 0, 0, true, 0, complain_overflow_dont,
    215   1.8  christos 	 bfd_elf_xtensa_reloc, "R_XTENSA_OP0", false, 0, 0, true),
    216   1.8  christos   HOWTO (R_XTENSA_OP1, 0, 0, 0, true, 0, complain_overflow_dont,
    217   1.8  christos 	 bfd_elf_xtensa_reloc, "R_XTENSA_OP1", false, 0, 0, true),
    218   1.8  christos   HOWTO (R_XTENSA_OP2, 0, 0, 0, true, 0, complain_overflow_dont,
    219   1.1  christos 	 bfd_elf_xtensa_reloc, "R_XTENSA_OP2", false, 0, 0, true),
    220   1.1  christos 
    221   1.8  christos   /* Assembly auto-expansion.  */
    222   1.8  christos   HOWTO (R_XTENSA_ASM_EXPAND, 0, 0, 0, true, 0, complain_overflow_dont,
    223   1.1  christos 	 bfd_elf_xtensa_reloc, "R_XTENSA_ASM_EXPAND", false, 0, 0, true),
    224   1.8  christos   /* Relax assembly auto-expansion.  */
    225   1.8  christos   HOWTO (R_XTENSA_ASM_SIMPLIFY, 0, 0, 0, true, 0, complain_overflow_dont,
    226   1.1  christos 	 bfd_elf_xtensa_reloc, "R_XTENSA_ASM_SIMPLIFY", false, 0, 0, true),
    227   1.1  christos 
    228   1.1  christos   EMPTY_HOWTO (13),
    229   1.8  christos 
    230   1.1  christos   HOWTO (R_XTENSA_32_PCREL, 0, 4, 32, true, 0, complain_overflow_bitfield,
    231   1.8  christos 	 bfd_elf_xtensa_reloc, "R_XTENSA_32_PCREL",
    232   1.1  christos 	 false, 0, 0xffffffff, true),
    233   1.1  christos 
    234   1.8  christos   /* GNU extension to record C++ vtable hierarchy.  */
    235   1.6  christos   HOWTO (R_XTENSA_GNU_VTINHERIT, 0, 4, 0, false, 0, complain_overflow_dont,
    236   1.8  christos 	 NULL, "R_XTENSA_GNU_VTINHERIT",
    237   1.1  christos 	 false, 0, 0, false),
    238   1.8  christos   /* GNU extension to record C++ vtable member usage.  */
    239   1.6  christos   HOWTO (R_XTENSA_GNU_VTENTRY, 0, 4, 0, false, 0, complain_overflow_dont,
    240   1.8  christos 	 _bfd_elf_rel_vtable_reloc_fn, "R_XTENSA_GNU_VTENTRY",
    241   1.1  christos 	 false, 0, 0, false),
    242   1.1  christos 
    243   1.8  christos   /* Relocations for supporting difference of symbols.  */
    244   1.8  christos   HOWTO (R_XTENSA_DIFF8, 0, 1, 8, false, 0, complain_overflow_signed,
    245   1.8  christos 	 bfd_elf_xtensa_reloc, "R_XTENSA_DIFF8", false, 0, 0xff, false),
    246   1.8  christos   HOWTO (R_XTENSA_DIFF16, 0, 2, 16, false, 0, complain_overflow_signed,
    247   1.8  christos 	 bfd_elf_xtensa_reloc, "R_XTENSA_DIFF16", false, 0, 0xffff, false),
    248   1.8  christos   HOWTO (R_XTENSA_DIFF32, 0, 4, 32, false, 0, complain_overflow_signed,
    249   1.1  christos 	 bfd_elf_xtensa_reloc, "R_XTENSA_DIFF32", false, 0, 0xffffffff, false),
    250   1.1  christos 
    251   1.8  christos   /* General immediate operand relocations.  */
    252   1.8  christos   HOWTO (R_XTENSA_SLOT0_OP, 0, 0, 0, true, 0, complain_overflow_dont,
    253   1.8  christos 	 bfd_elf_xtensa_reloc, "R_XTENSA_SLOT0_OP", false, 0, 0, true),
    254   1.8  christos   HOWTO (R_XTENSA_SLOT1_OP, 0, 0, 0, true, 0, complain_overflow_dont,
    255   1.8  christos 	 bfd_elf_xtensa_reloc, "R_XTENSA_SLOT1_OP", false, 0, 0, true),
    256   1.8  christos   HOWTO (R_XTENSA_SLOT2_OP, 0, 0, 0, true, 0, complain_overflow_dont,
    257   1.8  christos 	 bfd_elf_xtensa_reloc, "R_XTENSA_SLOT2_OP", false, 0, 0, true),
    258   1.8  christos   HOWTO (R_XTENSA_SLOT3_OP, 0, 0, 0, true, 0, complain_overflow_dont,
    259   1.8  christos 	 bfd_elf_xtensa_reloc, "R_XTENSA_SLOT3_OP", false, 0, 0, true),
    260   1.8  christos   HOWTO (R_XTENSA_SLOT4_OP, 0, 0, 0, true, 0, complain_overflow_dont,
    261   1.8  christos 	 bfd_elf_xtensa_reloc, "R_XTENSA_SLOT4_OP", false, 0, 0, true),
    262   1.8  christos   HOWTO (R_XTENSA_SLOT5_OP, 0, 0, 0, true, 0, complain_overflow_dont,
    263   1.8  christos 	 bfd_elf_xtensa_reloc, "R_XTENSA_SLOT5_OP", false, 0, 0, true),
    264   1.8  christos   HOWTO (R_XTENSA_SLOT6_OP, 0, 0, 0, true, 0, complain_overflow_dont,
    265   1.8  christos 	 bfd_elf_xtensa_reloc, "R_XTENSA_SLOT6_OP", false, 0, 0, true),
    266   1.8  christos   HOWTO (R_XTENSA_SLOT7_OP, 0, 0, 0, true, 0, complain_overflow_dont,
    267   1.8  christos 	 bfd_elf_xtensa_reloc, "R_XTENSA_SLOT7_OP", false, 0, 0, true),
    268   1.8  christos   HOWTO (R_XTENSA_SLOT8_OP, 0, 0, 0, true, 0, complain_overflow_dont,
    269   1.8  christos 	 bfd_elf_xtensa_reloc, "R_XTENSA_SLOT8_OP", false, 0, 0, true),
    270   1.8  christos   HOWTO (R_XTENSA_SLOT9_OP, 0, 0, 0, true, 0, complain_overflow_dont,
    271   1.8  christos 	 bfd_elf_xtensa_reloc, "R_XTENSA_SLOT9_OP", false, 0, 0, true),
    272   1.8  christos   HOWTO (R_XTENSA_SLOT10_OP, 0, 0, 0, true, 0, complain_overflow_dont,
    273   1.8  christos 	 bfd_elf_xtensa_reloc, "R_XTENSA_SLOT10_OP", false, 0, 0, true),
    274   1.8  christos   HOWTO (R_XTENSA_SLOT11_OP, 0, 0, 0, true, 0, complain_overflow_dont,
    275   1.8  christos 	 bfd_elf_xtensa_reloc, "R_XTENSA_SLOT11_OP", false, 0, 0, true),
    276   1.8  christos   HOWTO (R_XTENSA_SLOT12_OP, 0, 0, 0, true, 0, complain_overflow_dont,
    277   1.8  christos 	 bfd_elf_xtensa_reloc, "R_XTENSA_SLOT12_OP", false, 0, 0, true),
    278   1.8  christos   HOWTO (R_XTENSA_SLOT13_OP, 0, 0, 0, true, 0, complain_overflow_dont,
    279   1.8  christos 	 bfd_elf_xtensa_reloc, "R_XTENSA_SLOT13_OP", false, 0, 0, true),
    280   1.8  christos   HOWTO (R_XTENSA_SLOT14_OP, 0, 0, 0, true, 0, complain_overflow_dont,
    281   1.1  christos 	 bfd_elf_xtensa_reloc, "R_XTENSA_SLOT14_OP", false, 0, 0, true),
    282   1.1  christos 
    283   1.8  christos   /* "Alternate" relocations.  The meaning of these is opcode-specific.  */
    284   1.8  christos   HOWTO (R_XTENSA_SLOT0_ALT, 0, 0, 0, true, 0, complain_overflow_dont,
    285   1.8  christos 	 bfd_elf_xtensa_reloc, "R_XTENSA_SLOT0_ALT", false, 0, 0, true),
    286   1.8  christos   HOWTO (R_XTENSA_SLOT1_ALT, 0, 0, 0, true, 0, complain_overflow_dont,
    287   1.8  christos 	 bfd_elf_xtensa_reloc, "R_XTENSA_SLOT1_ALT", false, 0, 0, true),
    288   1.8  christos   HOWTO (R_XTENSA_SLOT2_ALT, 0, 0, 0, true, 0, complain_overflow_dont,
    289   1.8  christos 	 bfd_elf_xtensa_reloc, "R_XTENSA_SLOT2_ALT", false, 0, 0, true),
    290   1.8  christos   HOWTO (R_XTENSA_SLOT3_ALT, 0, 0, 0, true, 0, complain_overflow_dont,
    291   1.8  christos 	 bfd_elf_xtensa_reloc, "R_XTENSA_SLOT3_ALT", false, 0, 0, true),
    292   1.8  christos   HOWTO (R_XTENSA_SLOT4_ALT, 0, 0, 0, true, 0, complain_overflow_dont,
    293   1.8  christos 	 bfd_elf_xtensa_reloc, "R_XTENSA_SLOT4_ALT", false, 0, 0, true),
    294   1.8  christos   HOWTO (R_XTENSA_SLOT5_ALT, 0, 0, 0, true, 0, complain_overflow_dont,
    295   1.8  christos 	 bfd_elf_xtensa_reloc, "R_XTENSA_SLOT5_ALT", false, 0, 0, true),
    296   1.8  christos   HOWTO (R_XTENSA_SLOT6_ALT, 0, 0, 0, true, 0, complain_overflow_dont,
    297   1.8  christos 	 bfd_elf_xtensa_reloc, "R_XTENSA_SLOT6_ALT", false, 0, 0, true),
    298   1.8  christos   HOWTO (R_XTENSA_SLOT7_ALT, 0, 0, 0, true, 0, complain_overflow_dont,
    299   1.8  christos 	 bfd_elf_xtensa_reloc, "R_XTENSA_SLOT7_ALT", false, 0, 0, true),
    300   1.8  christos   HOWTO (R_XTENSA_SLOT8_ALT, 0, 0, 0, true, 0, complain_overflow_dont,
    301   1.8  christos 	 bfd_elf_xtensa_reloc, "R_XTENSA_SLOT8_ALT", false, 0, 0, true),
    302   1.8  christos   HOWTO (R_XTENSA_SLOT9_ALT, 0, 0, 0, true, 0, complain_overflow_dont,
    303   1.8  christos 	 bfd_elf_xtensa_reloc, "R_XTENSA_SLOT9_ALT", false, 0, 0, true),
    304   1.8  christos   HOWTO (R_XTENSA_SLOT10_ALT, 0, 0, 0, true, 0, complain_overflow_dont,
    305   1.8  christos 	 bfd_elf_xtensa_reloc, "R_XTENSA_SLOT10_ALT", false, 0, 0, true),
    306   1.8  christos   HOWTO (R_XTENSA_SLOT11_ALT, 0, 0, 0, true, 0, complain_overflow_dont,
    307   1.8  christos 	 bfd_elf_xtensa_reloc, "R_XTENSA_SLOT11_ALT", false, 0, 0, true),
    308   1.8  christos   HOWTO (R_XTENSA_SLOT12_ALT, 0, 0, 0, true, 0, complain_overflow_dont,
    309   1.8  christos 	 bfd_elf_xtensa_reloc, "R_XTENSA_SLOT12_ALT", false, 0, 0, true),
    310   1.8  christos   HOWTO (R_XTENSA_SLOT13_ALT, 0, 0, 0, true, 0, complain_overflow_dont,
    311   1.8  christos 	 bfd_elf_xtensa_reloc, "R_XTENSA_SLOT13_ALT", false, 0, 0, true),
    312   1.8  christos   HOWTO (R_XTENSA_SLOT14_ALT, 0, 0, 0, true, 0, complain_overflow_dont,
    313   1.1  christos 	 bfd_elf_xtensa_reloc, "R_XTENSA_SLOT14_ALT", false, 0, 0, true),
    314   1.1  christos 
    315   1.8  christos   /* TLS relocations.  */
    316   1.1  christos   HOWTO (R_XTENSA_TLSDESC_FN, 0, 4, 32, false, 0, complain_overflow_dont,
    317   1.8  christos 	 bfd_elf_xtensa_reloc, "R_XTENSA_TLSDESC_FN",
    318   1.8  christos 	 false, 0, 0xffffffff, false),
    319   1.1  christos   HOWTO (R_XTENSA_TLSDESC_ARG, 0, 4, 32, false, 0, complain_overflow_dont,
    320   1.8  christos 	 bfd_elf_xtensa_reloc, "R_XTENSA_TLSDESC_ARG",
    321   1.8  christos 	 false, 0, 0xffffffff, false),
    322   1.1  christos   HOWTO (R_XTENSA_TLS_DTPOFF, 0, 4, 32, false, 0, complain_overflow_dont,
    323   1.8  christos 	 bfd_elf_xtensa_reloc, "R_XTENSA_TLS_DTPOFF",
    324   1.8  christos 	 false, 0, 0xffffffff, false),
    325   1.1  christos   HOWTO (R_XTENSA_TLS_TPOFF, 0, 4, 32, false, 0, complain_overflow_dont,
    326   1.8  christos 	 bfd_elf_xtensa_reloc, "R_XTENSA_TLS_TPOFF",
    327   1.8  christos 	 false, 0, 0xffffffff, false),
    328   1.1  christos   HOWTO (R_XTENSA_TLS_FUNC, 0, 0, 0, false, 0, complain_overflow_dont,
    329   1.8  christos 	 bfd_elf_xtensa_reloc, "R_XTENSA_TLS_FUNC",
    330   1.8  christos 	 false, 0, 0, false),
    331   1.1  christos   HOWTO (R_XTENSA_TLS_ARG, 0, 0, 0, false, 0, complain_overflow_dont,
    332   1.8  christos 	 bfd_elf_xtensa_reloc, "R_XTENSA_TLS_ARG",
    333   1.8  christos 	 false, 0, 0, false),
    334   1.1  christos   HOWTO (R_XTENSA_TLS_CALL, 0, 0, 0, false, 0, complain_overflow_dont,
    335   1.8  christos 	 bfd_elf_xtensa_reloc, "R_XTENSA_TLS_CALL",
    336   1.8  christos 	 false, 0, 0, false),
    337   1.8  christos 
    338   1.8  christos   HOWTO (R_XTENSA_PDIFF8, 0, 1, 8, false, 0, complain_overflow_bitfield,
    339   1.8  christos 	 bfd_elf_xtensa_reloc, "R_XTENSA_PDIFF8", false, 0, 0xff, false),
    340   1.8  christos   HOWTO (R_XTENSA_PDIFF16, 0, 2, 16, false, 0, complain_overflow_bitfield,
    341   1.8  christos 	 bfd_elf_xtensa_reloc, "R_XTENSA_PDIFF16", false, 0, 0xffff, false),
    342   1.8  christos   HOWTO (R_XTENSA_PDIFF32, 0, 4, 32, false, 0, complain_overflow_bitfield,
    343   1.8  christos 	 bfd_elf_xtensa_reloc, "R_XTENSA_PDIFF32", false, 0, 0xffffffff, false),
    344   1.8  christos 
    345   1.8  christos   HOWTO (R_XTENSA_NDIFF8, 0, 1, 8, false, 0, complain_overflow_bitfield,
    346   1.8  christos 	 bfd_elf_xtensa_reloc, "R_XTENSA_NDIFF8", false, 0, 0xff, false),
    347   1.8  christos   HOWTO (R_XTENSA_NDIFF16, 0, 2, 16, false, 0, complain_overflow_bitfield,
    348   1.8  christos 	 bfd_elf_xtensa_reloc, "R_XTENSA_NDIFF16", false, 0, 0xffff, false),
    349   1.8  christos   HOWTO (R_XTENSA_NDIFF32, 0, 4, 32, false, 0, complain_overflow_bitfield,
    350   1.1  christos 	 bfd_elf_xtensa_reloc, "R_XTENSA_NDIFF32", false, 0, 0xffffffff, false),
    351   1.1  christos };
    352   1.1  christos 
    353   1.1  christos #if DEBUG_GEN_RELOC
    354   1.1  christos #define TRACE(str) \
    355   1.1  christos   fprintf (stderr, "Xtensa bfd reloc lookup %d (%s)\n", code, str)
    356   1.1  christos #else
    357   1.1  christos #define TRACE(str)
    358   1.1  christos #endif
    359   1.1  christos 
    360   1.1  christos static reloc_howto_type *
    361   1.1  christos elf_xtensa_reloc_type_lookup (bfd *abfd ATTRIBUTE_UNUSED,
    362   1.1  christos 			      bfd_reloc_code_real_type code)
    363   1.1  christos {
    364   1.1  christos   switch (code)
    365   1.1  christos     {
    366   1.1  christos     case BFD_RELOC_NONE:
    367   1.1  christos       TRACE ("BFD_RELOC_NONE");
    368   1.1  christos       return &elf_howto_table[(unsigned) R_XTENSA_NONE ];
    369   1.1  christos 
    370   1.1  christos     case BFD_RELOC_32:
    371   1.1  christos       TRACE ("BFD_RELOC_32");
    372   1.1  christos       return &elf_howto_table[(unsigned) R_XTENSA_32 ];
    373   1.1  christos 
    374   1.1  christos     case BFD_RELOC_32_PCREL:
    375   1.1  christos       TRACE ("BFD_RELOC_32_PCREL");
    376   1.1  christos       return &elf_howto_table[(unsigned) R_XTENSA_32_PCREL ];
    377   1.1  christos 
    378   1.1  christos     case BFD_RELOC_XTENSA_DIFF8:
    379   1.1  christos       TRACE ("BFD_RELOC_XTENSA_DIFF8");
    380   1.1  christos       return &elf_howto_table[(unsigned) R_XTENSA_DIFF8 ];
    381   1.1  christos 
    382   1.1  christos     case BFD_RELOC_XTENSA_DIFF16:
    383   1.1  christos       TRACE ("BFD_RELOC_XTENSA_DIFF16");
    384   1.1  christos       return &elf_howto_table[(unsigned) R_XTENSA_DIFF16 ];
    385   1.1  christos 
    386   1.1  christos     case BFD_RELOC_XTENSA_DIFF32:
    387   1.1  christos       TRACE ("BFD_RELOC_XTENSA_DIFF32");
    388   1.1  christos       return &elf_howto_table[(unsigned) R_XTENSA_DIFF32 ];
    389   1.8  christos 
    390   1.8  christos     case BFD_RELOC_XTENSA_PDIFF8:
    391   1.8  christos       TRACE ("BFD_RELOC_XTENSA_PDIFF8");
    392   1.8  christos       return &elf_howto_table[(unsigned) R_XTENSA_PDIFF8 ];
    393   1.8  christos 
    394   1.8  christos     case BFD_RELOC_XTENSA_PDIFF16:
    395   1.8  christos       TRACE ("BFD_RELOC_XTENSA_PDIFF16");
    396   1.8  christos       return &elf_howto_table[(unsigned) R_XTENSA_PDIFF16 ];
    397   1.8  christos 
    398   1.8  christos     case BFD_RELOC_XTENSA_PDIFF32:
    399   1.8  christos       TRACE ("BFD_RELOC_XTENSA_PDIFF32");
    400   1.8  christos       return &elf_howto_table[(unsigned) R_XTENSA_PDIFF32 ];
    401   1.8  christos 
    402   1.8  christos     case BFD_RELOC_XTENSA_NDIFF8:
    403   1.8  christos       TRACE ("BFD_RELOC_XTENSA_NDIFF8");
    404   1.8  christos       return &elf_howto_table[(unsigned) R_XTENSA_NDIFF8 ];
    405   1.8  christos 
    406   1.8  christos     case BFD_RELOC_XTENSA_NDIFF16:
    407   1.8  christos       TRACE ("BFD_RELOC_XTENSA_NDIFF16");
    408   1.8  christos       return &elf_howto_table[(unsigned) R_XTENSA_NDIFF16 ];
    409   1.8  christos 
    410   1.8  christos     case BFD_RELOC_XTENSA_NDIFF32:
    411   1.8  christos       TRACE ("BFD_RELOC_XTENSA_NDIFF32");
    412   1.8  christos       return &elf_howto_table[(unsigned) R_XTENSA_NDIFF32 ];
    413   1.1  christos 
    414   1.1  christos     case BFD_RELOC_XTENSA_RTLD:
    415   1.1  christos       TRACE ("BFD_RELOC_XTENSA_RTLD");
    416   1.1  christos       return &elf_howto_table[(unsigned) R_XTENSA_RTLD ];
    417   1.1  christos 
    418   1.1  christos     case BFD_RELOC_XTENSA_GLOB_DAT:
    419   1.1  christos       TRACE ("BFD_RELOC_XTENSA_GLOB_DAT");
    420   1.1  christos       return &elf_howto_table[(unsigned) R_XTENSA_GLOB_DAT ];
    421   1.1  christos 
    422   1.1  christos     case BFD_RELOC_XTENSA_JMP_SLOT:
    423   1.1  christos       TRACE ("BFD_RELOC_XTENSA_JMP_SLOT");
    424   1.1  christos       return &elf_howto_table[(unsigned) R_XTENSA_JMP_SLOT ];
    425   1.1  christos 
    426   1.1  christos     case BFD_RELOC_XTENSA_RELATIVE:
    427   1.1  christos       TRACE ("BFD_RELOC_XTENSA_RELATIVE");
    428   1.1  christos       return &elf_howto_table[(unsigned) R_XTENSA_RELATIVE ];
    429   1.1  christos 
    430   1.1  christos     case BFD_RELOC_XTENSA_PLT:
    431   1.1  christos       TRACE ("BFD_RELOC_XTENSA_PLT");
    432   1.1  christos       return &elf_howto_table[(unsigned) R_XTENSA_PLT ];
    433   1.1  christos 
    434   1.1  christos     case BFD_RELOC_XTENSA_OP0:
    435   1.1  christos       TRACE ("BFD_RELOC_XTENSA_OP0");
    436   1.1  christos       return &elf_howto_table[(unsigned) R_XTENSA_OP0 ];
    437   1.1  christos 
    438   1.1  christos     case BFD_RELOC_XTENSA_OP1:
    439   1.1  christos       TRACE ("BFD_RELOC_XTENSA_OP1");
    440   1.1  christos       return &elf_howto_table[(unsigned) R_XTENSA_OP1 ];
    441   1.1  christos 
    442   1.1  christos     case BFD_RELOC_XTENSA_OP2:
    443   1.1  christos       TRACE ("BFD_RELOC_XTENSA_OP2");
    444   1.1  christos       return &elf_howto_table[(unsigned) R_XTENSA_OP2 ];
    445   1.1  christos 
    446   1.1  christos     case BFD_RELOC_XTENSA_ASM_EXPAND:
    447   1.1  christos       TRACE ("BFD_RELOC_XTENSA_ASM_EXPAND");
    448   1.1  christos       return &elf_howto_table[(unsigned) R_XTENSA_ASM_EXPAND ];
    449   1.1  christos 
    450   1.1  christos     case BFD_RELOC_XTENSA_ASM_SIMPLIFY:
    451   1.1  christos       TRACE ("BFD_RELOC_XTENSA_ASM_SIMPLIFY");
    452   1.1  christos       return &elf_howto_table[(unsigned) R_XTENSA_ASM_SIMPLIFY ];
    453   1.1  christos 
    454   1.1  christos     case BFD_RELOC_VTABLE_INHERIT:
    455   1.1  christos       TRACE ("BFD_RELOC_VTABLE_INHERIT");
    456   1.1  christos       return &elf_howto_table[(unsigned) R_XTENSA_GNU_VTINHERIT ];
    457   1.1  christos 
    458   1.1  christos     case BFD_RELOC_VTABLE_ENTRY:
    459   1.1  christos       TRACE ("BFD_RELOC_VTABLE_ENTRY");
    460   1.1  christos       return &elf_howto_table[(unsigned) R_XTENSA_GNU_VTENTRY ];
    461   1.1  christos 
    462   1.1  christos     case BFD_RELOC_XTENSA_TLSDESC_FN:
    463   1.1  christos       TRACE ("BFD_RELOC_XTENSA_TLSDESC_FN");
    464   1.1  christos       return &elf_howto_table[(unsigned) R_XTENSA_TLSDESC_FN ];
    465   1.1  christos 
    466   1.1  christos     case BFD_RELOC_XTENSA_TLSDESC_ARG:
    467   1.1  christos       TRACE ("BFD_RELOC_XTENSA_TLSDESC_ARG");
    468   1.1  christos       return &elf_howto_table[(unsigned) R_XTENSA_TLSDESC_ARG ];
    469   1.1  christos 
    470   1.1  christos     case BFD_RELOC_XTENSA_TLS_DTPOFF:
    471   1.1  christos       TRACE ("BFD_RELOC_XTENSA_TLS_DTPOFF");
    472   1.1  christos       return &elf_howto_table[(unsigned) R_XTENSA_TLS_DTPOFF ];
    473   1.1  christos 
    474   1.1  christos     case BFD_RELOC_XTENSA_TLS_TPOFF:
    475   1.1  christos       TRACE ("BFD_RELOC_XTENSA_TLS_TPOFF");
    476   1.1  christos       return &elf_howto_table[(unsigned) R_XTENSA_TLS_TPOFF ];
    477   1.1  christos 
    478   1.1  christos     case BFD_RELOC_XTENSA_TLS_FUNC:
    479   1.1  christos       TRACE ("BFD_RELOC_XTENSA_TLS_FUNC");
    480   1.1  christos       return &elf_howto_table[(unsigned) R_XTENSA_TLS_FUNC ];
    481   1.1  christos 
    482   1.1  christos     case BFD_RELOC_XTENSA_TLS_ARG:
    483   1.1  christos       TRACE ("BFD_RELOC_XTENSA_TLS_ARG");
    484   1.1  christos       return &elf_howto_table[(unsigned) R_XTENSA_TLS_ARG ];
    485   1.1  christos 
    486   1.1  christos     case BFD_RELOC_XTENSA_TLS_CALL:
    487   1.1  christos       TRACE ("BFD_RELOC_XTENSA_TLS_CALL");
    488   1.1  christos       return &elf_howto_table[(unsigned) R_XTENSA_TLS_CALL ];
    489   1.1  christos 
    490   1.1  christos     default:
    491   1.1  christos       if (code >= BFD_RELOC_XTENSA_SLOT0_OP
    492   1.1  christos 	  && code <= BFD_RELOC_XTENSA_SLOT14_OP)
    493   1.1  christos 	{
    494   1.1  christos 	  unsigned n = (R_XTENSA_SLOT0_OP +
    495   1.1  christos 			(code - BFD_RELOC_XTENSA_SLOT0_OP));
    496   1.1  christos 	  return &elf_howto_table[n];
    497   1.1  christos 	}
    498   1.1  christos 
    499   1.1  christos       if (code >= BFD_RELOC_XTENSA_SLOT0_ALT
    500   1.1  christos 	  && code <= BFD_RELOC_XTENSA_SLOT14_ALT)
    501   1.1  christos 	{
    502   1.1  christos 	  unsigned n = (R_XTENSA_SLOT0_ALT +
    503   1.1  christos 			(code - BFD_RELOC_XTENSA_SLOT0_ALT));
    504   1.1  christos 	  return &elf_howto_table[n];
    505   1.1  christos 	}
    506   1.1  christos 
    507   1.1  christos       break;
    508   1.1  christos     }
    509   1.6  christos 
    510   1.6  christos   /* xgettext:c-format */
    511   1.6  christos   _bfd_error_handler (_("%pB: unsupported relocation type %#x"), abfd, (int) code);
    512   1.1  christos   bfd_set_error (bfd_error_bad_value);
    513   1.1  christos   TRACE ("Unknown");
    514   1.1  christos   return NULL;
    515   1.1  christos }
    516   1.1  christos 
    517   1.1  christos static reloc_howto_type *
    518   1.1  christos elf_xtensa_reloc_name_lookup (bfd *abfd ATTRIBUTE_UNUSED,
    519   1.1  christos 			      const char *r_name)
    520   1.1  christos {
    521   1.1  christos   unsigned int i;
    522   1.1  christos 
    523   1.1  christos   for (i = 0; i < sizeof (elf_howto_table) / sizeof (elf_howto_table[0]); i++)
    524   1.1  christos     if (elf_howto_table[i].name != NULL
    525   1.1  christos 	&& strcasecmp (elf_howto_table[i].name, r_name) == 0)
    526   1.1  christos       return &elf_howto_table[i];
    527   1.1  christos 
    528   1.1  christos   return NULL;
    529   1.1  christos }
    530   1.1  christos 
    531   1.1  christos 
    532   1.1  christos /* Given an ELF "rela" relocation, find the corresponding howto and record
    533   1.1  christos    it in the BFD internal arelent representation of the relocation.  */
    534   1.8  christos 
    535   1.6  christos static bool
    536   1.1  christos elf_xtensa_info_to_howto_rela (bfd *abfd,
    537   1.1  christos 			       arelent *cache_ptr,
    538   1.1  christos 			       Elf_Internal_Rela *dst)
    539   1.1  christos {
    540   1.1  christos   unsigned int r_type = ELF32_R_TYPE (dst->r_info);
    541   1.3  christos 
    542   1.3  christos   if (r_type >= (unsigned int) R_XTENSA_max)
    543   1.6  christos     {
    544   1.6  christos       /* xgettext:c-format */
    545   1.6  christos       _bfd_error_handler (_("%pB: unsupported relocation type %#x"),
    546   1.6  christos 			  abfd, r_type);
    547   1.8  christos       bfd_set_error (bfd_error_bad_value);
    548   1.3  christos       return false;
    549   1.1  christos     }
    550   1.8  christos   cache_ptr->howto = &elf_howto_table[r_type];
    551   1.1  christos   return true;
    552   1.1  christos }
    553   1.1  christos 
    554   1.1  christos 
    555   1.1  christos /* Functions for the Xtensa ELF linker.  */
    557   1.1  christos 
    558   1.1  christos /* The name of the dynamic interpreter.  This is put in the .interp
    559   1.1  christos    section.  */
    560   1.1  christos 
    561   1.1  christos #define ELF_DYNAMIC_INTERPRETER "/lib/ld.so"
    562   1.1  christos 
    563   1.1  christos /* The size in bytes of an entry in the procedure linkage table.
    564   1.1  christos    (This does _not_ include the space for the literals associated with
    565   1.1  christos    the PLT entry.) */
    566   1.1  christos 
    567   1.1  christos #define PLT_ENTRY_SIZE 16
    568   1.1  christos 
    569   1.1  christos /* For _really_ large PLTs, we may need to alternate between literals
    570   1.1  christos    and code to keep the literals within the 256K range of the L32R
    571   1.1  christos    instructions in the code.  It's unlikely that anyone would ever need
    572   1.1  christos    such a big PLT, but an arbitrary limit on the PLT size would be bad.
    573   1.1  christos    Thus, we split the PLT into chunks.  Since there's very little
    574   1.1  christos    overhead (2 extra literals) for each chunk, the chunk size is kept
    575   1.1  christos    small so that the code for handling multiple chunks get used and
    576   1.1  christos    tested regularly.  With 254 entries, there are 1K of literals for
    577   1.1  christos    each chunk, and that seems like a nice round number.  */
    578   1.1  christos 
    579   1.1  christos #define PLT_ENTRIES_PER_CHUNK 254
    580   1.1  christos 
    581   1.1  christos /* PLT entries are actually used as stub functions for lazy symbol
    582   1.1  christos    resolution.  Once the symbol is resolved, the stub function is never
    583   1.1  christos    invoked.  Note: the 32-byte frame size used here cannot be changed
    584   1.6  christos    without a corresponding change in the runtime linker.  */
    585   1.1  christos 
    586   1.6  christos static const bfd_byte elf_xtensa_be_plt_entry[][PLT_ENTRY_SIZE] =
    587   1.6  christos {
    588   1.6  christos     {
    589   1.6  christos       0x6c, 0x10, 0x04,	/* entry sp, 32 */
    590   1.6  christos       0x18, 0x00, 0x00,	/* l32r  a8, [got entry for rtld's resolver] */
    591   1.6  christos       0x1a, 0x00, 0x00,	/* l32r  a10, [got entry for rtld's link map] */
    592   1.6  christos       0x1b, 0x00, 0x00,	/* l32r  a11, [literal for reloc index] */
    593   1.6  christos       0x0a, 0x80, 0x00,	/* jx    a8 */
    594   1.6  christos       0			/* unused */
    595   1.6  christos     },
    596   1.6  christos     {
    597   1.6  christos       0x18, 0x00, 0x00,	/* l32r  a8, [got entry for rtld's resolver] */
    598   1.6  christos       0x1a, 0x00, 0x00,	/* l32r  a10, [got entry for rtld's link map] */
    599   1.6  christos       0x1b, 0x00, 0x00,	/* l32r  a11, [literal for reloc index] */
    600   1.6  christos       0x0a, 0x80, 0x00,	/* jx    a8 */
    601   1.1  christos       0			/* unused */
    602   1.1  christos     }
    603   1.6  christos };
    604   1.1  christos 
    605   1.6  christos static const bfd_byte elf_xtensa_le_plt_entry[][PLT_ENTRY_SIZE] =
    606   1.6  christos {
    607   1.6  christos     {
    608   1.6  christos       0x36, 0x41, 0x00,	/* entry sp, 32 */
    609   1.6  christos       0x81, 0x00, 0x00,	/* l32r  a8, [got entry for rtld's resolver] */
    610   1.6  christos       0xa1, 0x00, 0x00,	/* l32r  a10, [got entry for rtld's link map] */
    611   1.6  christos       0xb1, 0x00, 0x00,	/* l32r  a11, [literal for reloc index] */
    612   1.6  christos       0xa0, 0x08, 0x00,	/* jx    a8 */
    613   1.6  christos       0			/* unused */
    614   1.6  christos     },
    615   1.6  christos     {
    616   1.6  christos       0x81, 0x00, 0x00,	/* l32r  a8, [got entry for rtld's resolver] */
    617   1.6  christos       0xa1, 0x00, 0x00,	/* l32r  a10, [got entry for rtld's link map] */
    618   1.6  christos       0xb1, 0x00, 0x00,	/* l32r  a11, [literal for reloc index] */
    619   1.6  christos       0xa0, 0x08, 0x00,	/* jx    a8 */
    620   1.1  christos       0			/* unused */
    621   1.1  christos     }
    622   1.1  christos };
    623   1.1  christos 
    624   1.1  christos /* The size of the thread control block.  */
    625   1.1  christos #define TCB_SIZE	8
    626   1.1  christos 
    627   1.1  christos struct elf_xtensa_link_hash_entry
    628   1.1  christos {
    629   1.1  christos   struct elf_link_hash_entry elf;
    630   1.1  christos 
    631   1.1  christos   bfd_signed_vma tlsfunc_refcount;
    632   1.1  christos 
    633   1.1  christos #define GOT_UNKNOWN	0
    634   1.1  christos #define GOT_NORMAL	1
    635   1.1  christos #define GOT_TLS_GD	2	/* global or local dynamic */
    636   1.1  christos #define GOT_TLS_IE	4	/* initial or local exec */
    637   1.1  christos #define GOT_TLS_ANY	(GOT_TLS_GD | GOT_TLS_IE)
    638   1.1  christos   unsigned char tls_type;
    639   1.1  christos };
    640   1.1  christos 
    641   1.1  christos #define elf_xtensa_hash_entry(ent) ((struct elf_xtensa_link_hash_entry *)(ent))
    642   1.1  christos 
    643   1.1  christos struct elf_xtensa_obj_tdata
    644   1.1  christos {
    645   1.1  christos   struct elf_obj_tdata root;
    646   1.1  christos 
    647   1.1  christos   /* tls_type for each local got entry.  */
    648   1.1  christos   char *local_got_tls_type;
    649   1.1  christos 
    650   1.1  christos   bfd_signed_vma *local_tlsfunc_refcounts;
    651   1.1  christos };
    652   1.1  christos 
    653   1.1  christos #define elf_xtensa_tdata(abfd) \
    654   1.1  christos   ((struct elf_xtensa_obj_tdata *) (abfd)->tdata.any)
    655   1.1  christos 
    656   1.1  christos #define elf_xtensa_local_got_tls_type(abfd) \
    657   1.1  christos   (elf_xtensa_tdata (abfd)->local_got_tls_type)
    658   1.1  christos 
    659   1.1  christos #define elf_xtensa_local_tlsfunc_refcounts(abfd) \
    660   1.1  christos   (elf_xtensa_tdata (abfd)->local_tlsfunc_refcounts)
    661   1.1  christos 
    662   1.1  christos #define is_xtensa_elf(bfd) \
    663   1.1  christos   (bfd_get_flavour (bfd) == bfd_target_elf_flavour \
    664   1.1  christos    && elf_tdata (bfd) != NULL \
    665   1.8  christos    && elf_object_id (bfd) == XTENSA_ELF_DATA)
    666   1.1  christos 
    667   1.1  christos static bool
    668  1.10  christos elf_xtensa_mkobject (bfd *abfd)
    669   1.1  christos {
    670   1.1  christos   return bfd_elf_allocate_object (abfd, sizeof (struct elf_xtensa_obj_tdata));
    671   1.1  christos }
    672   1.1  christos 
    673   1.1  christos /* Xtensa ELF linker hash table.  */
    674   1.1  christos 
    675   1.1  christos struct elf_xtensa_link_hash_table
    676   1.1  christos {
    677   1.1  christos   struct elf_link_hash_table elf;
    678   1.1  christos 
    679   1.1  christos   /* Short-cuts to get to dynamic linker sections.  */
    680   1.1  christos   asection *sgotloc;
    681   1.1  christos   asection *spltlittbl;
    682   1.1  christos 
    683   1.1  christos   /* Total count of PLT relocations seen during check_relocs.
    684   1.1  christos      The actual PLT code must be split into multiple sections and all
    685   1.1  christos      the sections have to be created before size_dynamic_sections,
    686   1.1  christos      where we figure out the exact number of PLT entries that will be
    687   1.1  christos      needed.  It is OK if this count is an overestimate, e.g., some
    688   1.1  christos      relocations may be removed by GC.  */
    689   1.1  christos   int plt_reloc_count;
    690   1.1  christos 
    691   1.1  christos   struct elf_xtensa_link_hash_entry *tlsbase;
    692   1.1  christos };
    693   1.1  christos 
    694   1.1  christos /* Get the Xtensa ELF linker hash table from a link_info structure.  */
    695   1.8  christos 
    696   1.8  christos #define elf_xtensa_hash_table(p) \
    697   1.8  christos   ((is_elf_hash_table ((p)->hash)					\
    698   1.1  christos     && elf_hash_table_id (elf_hash_table (p)) == XTENSA_ELF_DATA)	\
    699   1.1  christos    ? (struct elf_xtensa_link_hash_table *) (p)->hash : NULL)
    700   1.1  christos 
    701   1.1  christos /* Create an entry in an Xtensa ELF linker hash table.  */
    702   1.1  christos 
    703   1.1  christos static struct bfd_hash_entry *
    704   1.1  christos elf_xtensa_link_hash_newfunc (struct bfd_hash_entry *entry,
    705   1.1  christos 			      struct bfd_hash_table *table,
    706   1.1  christos 			      const char *string)
    707   1.1  christos {
    708   1.1  christos   /* Allocate the structure if it has not already been allocated by a
    709   1.1  christos      subclass.  */
    710   1.1  christos   if (entry == NULL)
    711   1.1  christos     {
    712   1.1  christos       entry = bfd_hash_allocate (table,
    713   1.1  christos 				 sizeof (struct elf_xtensa_link_hash_entry));
    714   1.1  christos       if (entry == NULL)
    715   1.1  christos 	return entry;
    716   1.1  christos     }
    717   1.1  christos 
    718   1.1  christos   /* Call the allocation method of the superclass.  */
    719   1.1  christos   entry = _bfd_elf_link_hash_newfunc (entry, table, string);
    720   1.1  christos   if (entry != NULL)
    721   1.1  christos     {
    722   1.1  christos       struct elf_xtensa_link_hash_entry *eh = elf_xtensa_hash_entry (entry);
    723   1.1  christos       eh->tlsfunc_refcount = 0;
    724   1.1  christos       eh->tls_type = GOT_UNKNOWN;
    725   1.1  christos     }
    726   1.1  christos 
    727   1.1  christos   return entry;
    728   1.1  christos }
    729   1.1  christos 
    730   1.1  christos /* Create an Xtensa ELF linker hash table.  */
    731   1.1  christos 
    732   1.1  christos static struct bfd_link_hash_table *
    733   1.1  christos elf_xtensa_link_hash_table_create (bfd *abfd)
    734   1.1  christos {
    735   1.8  christos   struct elf_link_hash_entry *tlsbase;
    736   1.1  christos   struct elf_xtensa_link_hash_table *ret;
    737   1.3  christos   size_t amt = sizeof (struct elf_xtensa_link_hash_table);
    738   1.1  christos 
    739   1.1  christos   ret = bfd_zmalloc (amt);
    740   1.1  christos   if (ret == NULL)
    741   1.1  christos     return NULL;
    742   1.1  christos 
    743  1.10  christos   if (!_bfd_elf_link_hash_table_init (&ret->elf, abfd,
    744   1.1  christos 				      elf_xtensa_link_hash_newfunc,
    745   1.1  christos 				      sizeof (struct elf_xtensa_link_hash_entry)))
    746   1.1  christos     {
    747   1.1  christos       free (ret);
    748   1.1  christos       return NULL;
    749   1.1  christos     }
    750   1.1  christos 
    751   1.1  christos   /* Create a hash entry for "_TLS_MODULE_BASE_" to speed up checking
    752   1.8  christos      for it later.  */
    753   1.1  christos   tlsbase = elf_link_hash_lookup (&ret->elf, "_TLS_MODULE_BASE_",
    754   1.1  christos 				  true, false, false);
    755   1.1  christos   tlsbase->root.type = bfd_link_hash_new;
    756   1.8  christos   tlsbase->root.u.undef.abfd = NULL;
    757   1.1  christos   tlsbase->non_elf = 0;
    758   1.1  christos   ret->elf.dt_pltgot_required = true;
    759   1.1  christos   ret->tlsbase = elf_xtensa_hash_entry (tlsbase);
    760   1.1  christos   ret->tlsbase->tls_type = GOT_UNKNOWN;
    761   1.1  christos 
    762   1.1  christos   return &ret->elf.root;
    763   1.1  christos }
    764   1.1  christos 
    765   1.1  christos /* Copy the extra info we tack onto an elf_link_hash_entry.  */
    766   1.1  christos 
    767   1.1  christos static void
    768   1.1  christos elf_xtensa_copy_indirect_symbol (struct bfd_link_info *info,
    769   1.1  christos 				 struct elf_link_hash_entry *dir,
    770   1.1  christos 				 struct elf_link_hash_entry *ind)
    771   1.1  christos {
    772   1.1  christos   struct elf_xtensa_link_hash_entry *edir, *eind;
    773   1.1  christos 
    774   1.1  christos   edir = elf_xtensa_hash_entry (dir);
    775   1.1  christos   eind = elf_xtensa_hash_entry (ind);
    776   1.1  christos 
    777   1.1  christos   if (ind->root.type == bfd_link_hash_indirect)
    778   1.1  christos     {
    779   1.1  christos       edir->tlsfunc_refcount += eind->tlsfunc_refcount;
    780   1.1  christos       eind->tlsfunc_refcount = 0;
    781   1.1  christos 
    782   1.1  christos       if (dir->got.refcount <= 0)
    783   1.1  christos 	{
    784   1.1  christos 	  edir->tls_type = eind->tls_type;
    785   1.1  christos 	  eind->tls_type = GOT_UNKNOWN;
    786   1.1  christos 	}
    787   1.1  christos     }
    788   1.1  christos 
    789   1.1  christos   _bfd_elf_link_hash_copy_indirect (info, dir, ind);
    790   1.8  christos }
    791   1.1  christos 
    792   1.1  christos static inline bool
    793   1.1  christos elf_xtensa_dynamic_symbol_p (struct elf_link_hash_entry *h,
    794   1.1  christos 			     struct bfd_link_info *info)
    795   1.1  christos {
    796   1.1  christos   /* Check if we should do dynamic things to this symbol.  The
    797   1.1  christos      "ignore_protected" argument need not be set, because Xtensa code
    798   1.1  christos      does not require special handling of STV_PROTECTED to make function
    799   1.1  christos      pointer comparisons work properly.  The PLT addresses are never
    800   1.1  christos      used for function pointers.  */
    801   1.1  christos 
    802   1.1  christos   return _bfd_elf_dynamic_symbol_p (h, info, 0);
    803   1.1  christos }
    804   1.1  christos 
    805   1.1  christos 
    806   1.1  christos static int
    808   1.1  christos property_table_compare (const void *ap, const void *bp)
    809   1.1  christos {
    810   1.1  christos   const property_table_entry *a = (const property_table_entry *) ap;
    811   1.1  christos   const property_table_entry *b = (const property_table_entry *) bp;
    812   1.1  christos 
    813   1.1  christos   if (a->address == b->address)
    814   1.1  christos     {
    815   1.1  christos       if (a->size != b->size)
    816   1.1  christos 	return (a->size - b->size);
    817   1.1  christos 
    818   1.1  christos       if ((a->flags & XTENSA_PROP_ALIGN) != (b->flags & XTENSA_PROP_ALIGN))
    819   1.1  christos 	return ((b->flags & XTENSA_PROP_ALIGN)
    820   1.1  christos 		- (a->flags & XTENSA_PROP_ALIGN));
    821   1.1  christos 
    822   1.1  christos       if ((a->flags & XTENSA_PROP_ALIGN)
    823   1.1  christos 	  && (GET_XTENSA_PROP_ALIGNMENT (a->flags)
    824   1.3  christos 	      != GET_XTENSA_PROP_ALIGNMENT (b->flags)))
    825   1.1  christos 	return (GET_XTENSA_PROP_ALIGNMENT (a->flags)
    826   1.1  christos 		- GET_XTENSA_PROP_ALIGNMENT (b->flags));
    827   1.1  christos 
    828   1.1  christos       if ((a->flags & XTENSA_PROP_UNREACHABLE)
    829   1.1  christos 	  != (b->flags & XTENSA_PROP_UNREACHABLE))
    830   1.1  christos 	return ((b->flags & XTENSA_PROP_UNREACHABLE)
    831   1.1  christos 		- (a->flags & XTENSA_PROP_UNREACHABLE));
    832   1.1  christos 
    833   1.1  christos       return (a->flags - b->flags);
    834   1.1  christos     }
    835   1.1  christos 
    836   1.1  christos   return (a->address - b->address);
    837   1.1  christos }
    838   1.1  christos 
    839   1.1  christos 
    840   1.1  christos static int
    841   1.1  christos property_table_matches (const void *ap, const void *bp)
    842   1.1  christos {
    843   1.1  christos   const property_table_entry *a = (const property_table_entry *) ap;
    844   1.1  christos   const property_table_entry *b = (const property_table_entry *) bp;
    845   1.1  christos 
    846   1.1  christos   /* Check if one entry overlaps with the other.  */
    847   1.1  christos   if ((b->address >= a->address && b->address < (a->address + a->size))
    848   1.1  christos       || (a->address >= b->address && a->address < (b->address + b->size)))
    849   1.1  christos     return 0;
    850   1.1  christos 
    851   1.1  christos   return (a->address - b->address);
    852   1.1  christos }
    853   1.1  christos 
    854   1.1  christos 
    855   1.1  christos /* Get the literal table or property table entries for the given
    856   1.6  christos    section.  Sets TABLE_P and returns the number of entries.  On
    857   1.1  christos    error, returns a negative value.  */
    858   1.1  christos 
    859   1.1  christos int
    860   1.1  christos xtensa_read_table_entries (bfd *abfd,
    861   1.8  christos 			   asection *section,
    862   1.1  christos 			   property_table_entry **table_p,
    863   1.1  christos 			   const char *sec_name,
    864   1.1  christos 			   bool output_addr)
    865   1.1  christos {
    866   1.1  christos   asection *table_section;
    867   1.1  christos   bfd_size_type table_size = 0;
    868   1.1  christos   bfd_byte *table_data;
    869   1.1  christos   property_table_entry *blocks;
    870   1.1  christos   int blk, block_count;
    871   1.1  christos   bfd_size_type num_records;
    872   1.1  christos   Elf_Internal_Rela *internal_relocs, *irel, *rel_end;
    873   1.1  christos   bfd_vma section_addr, off;
    874   1.8  christos   flagword predef_flags;
    875   1.8  christos   bfd_size_type table_entry_size, section_limit;
    876   1.1  christos 
    877   1.1  christos   if (bfd_get_flavour (abfd) != bfd_target_elf_flavour
    878   1.1  christos       || !section
    879   1.1  christos       || !(section->flags & SEC_ALLOC)
    880   1.1  christos       || (section->flags & SEC_DEBUGGING))
    881   1.1  christos     {
    882   1.1  christos       *table_p = NULL;
    883   1.1  christos       return 0;
    884   1.1  christos     }
    885   1.1  christos 
    886   1.1  christos   table_section = xtensa_get_property_section (section, sec_name);
    887   1.3  christos   if (table_section)
    888   1.1  christos     table_size = table_section->size;
    889   1.1  christos 
    890   1.1  christos   if (table_size == 0)
    891   1.1  christos     {
    892   1.1  christos       *table_p = NULL;
    893   1.1  christos       return 0;
    894   1.1  christos     }
    895   1.1  christos 
    896   1.1  christos   predef_flags = xtensa_get_property_predef_flags (table_section);
    897   1.1  christos   table_entry_size = 12;
    898   1.1  christos   if (predef_flags)
    899   1.8  christos     table_entry_size -= 4;
    900   1.8  christos 
    901   1.8  christos   num_records = table_size / table_entry_size;
    902   1.8  christos 
    903   1.8  christos   table_data = retrieve_contents (abfd, table_section, true);
    904   1.8  christos   if (table_data == NULL)
    905   1.8  christos     {
    906   1.8  christos       *table_p = NULL;
    907   1.1  christos       return 0;
    908   1.1  christos     }
    909   1.1  christos 
    910   1.1  christos   blocks = (property_table_entry *)
    911   1.1  christos     bfd_malloc (num_records * sizeof (property_table_entry));
    912   1.1  christos   block_count = 0;
    913   1.1  christos 
    914   1.1  christos   if (output_addr)
    915   1.1  christos     section_addr = section->output_section->vma + section->output_offset;
    916   1.8  christos   else
    917   1.1  christos     section_addr = section->vma;
    918   1.1  christos 
    919   1.1  christos   internal_relocs = retrieve_internal_relocs (abfd, table_section, true);
    920   1.1  christos   if (internal_relocs && !table_section->reloc_done)
    921   1.1  christos     {
    922   1.1  christos       qsort (internal_relocs, table_section->reloc_count,
    923   1.1  christos 	     sizeof (Elf_Internal_Rela), internal_reloc_compare);
    924   1.1  christos       irel = internal_relocs;
    925   1.1  christos     }
    926   1.1  christos   else
    927   1.1  christos     irel = NULL;
    928   1.1  christos 
    929   1.3  christos   section_limit = bfd_get_section_limit (abfd, section);
    930   1.1  christos   rel_end = internal_relocs + table_section->reloc_count;
    931   1.1  christos 
    932   1.1  christos   for (off = 0; off < table_size; off += table_entry_size)
    933   1.1  christos     {
    934   1.1  christos       bfd_vma address = bfd_get_32 (abfd, table_data + off);
    935   1.1  christos 
    936   1.1  christos       /* Skip any relocations before the current offset.  This should help
    937   1.1  christos 	 avoid confusion caused by unexpected relocations for the preceding
    938   1.1  christos 	 table entry.  */
    939   1.1  christos       while (irel &&
    940   1.1  christos 	     (irel->r_offset < off
    941   1.1  christos 	      || (irel->r_offset == off
    942   1.1  christos 		  && ELF32_R_TYPE (irel->r_info) == R_XTENSA_NONE)))
    943   1.1  christos 	{
    944   1.1  christos 	  irel += 1;
    945   1.1  christos 	  if (irel >= rel_end)
    946   1.1  christos 	    irel = 0;
    947   1.1  christos 	}
    948   1.1  christos 
    949   1.1  christos       if (irel && irel->r_offset == off)
    950   1.1  christos 	{
    951   1.1  christos 	  bfd_vma sym_off;
    952   1.1  christos 	  unsigned long r_symndx = ELF32_R_SYM (irel->r_info);
    953   1.1  christos 	  BFD_ASSERT (ELF32_R_TYPE (irel->r_info) == R_XTENSA_32);
    954   1.1  christos 
    955   1.1  christos 	  if (get_elf_r_symndx_section (abfd, r_symndx) != section)
    956   1.1  christos 	    continue;
    957   1.1  christos 
    958   1.1  christos 	  sym_off = get_elf_r_symndx_offset (abfd, r_symndx);
    959   1.1  christos 	  BFD_ASSERT (sym_off == 0);
    960   1.1  christos 	  address += (section_addr + sym_off + irel->r_addend);
    961   1.1  christos 	}
    962   1.1  christos       else
    963   1.1  christos 	{
    964   1.1  christos 	  if (address < section_addr
    965   1.1  christos 	      || address >= section_addr + section_limit)
    966   1.1  christos 	    continue;
    967   1.1  christos 	}
    968   1.1  christos 
    969   1.1  christos       blocks[block_count].address = address;
    970   1.1  christos       blocks[block_count].size = bfd_get_32 (abfd, table_data + off + 4);
    971   1.1  christos       if (predef_flags)
    972   1.1  christos 	blocks[block_count].flags = predef_flags;
    973   1.1  christos       else
    974   1.1  christos 	blocks[block_count].flags = bfd_get_32 (abfd, table_data + off + 8);
    975   1.1  christos       block_count++;
    976   1.1  christos     }
    977   1.1  christos 
    978   1.1  christos   release_contents (table_section, table_data);
    979   1.1  christos   release_internal_relocs (table_section, internal_relocs);
    980   1.1  christos 
    981   1.1  christos   if (block_count > 0)
    982   1.1  christos     {
    983   1.1  christos       /* Now sort them into address order for easy reference.  */
    984   1.1  christos       qsort (blocks, block_count, sizeof (property_table_entry),
    985   1.6  christos 	     property_table_compare);
    986   1.1  christos 
    987   1.1  christos       /* Check that the table contents are valid.  Problems may occur,
    988   1.1  christos 	 for example, if an unrelocated object file is stripped.  */
    989   1.1  christos       for (blk = 1; blk < block_count; blk++)
    990   1.1  christos 	{
    991   1.1  christos 	  /* The only circumstance where two entries may legitimately
    992   1.1  christos 	     have the same address is when one of them is a zero-size
    993   1.1  christos 	     placeholder to mark a place where fill can be inserted.
    994   1.1  christos 	     The zero-size entry should come first.  */
    995   1.6  christos 	  if (blocks[blk - 1].address == blocks[blk].address &&
    996   1.6  christos 	      blocks[blk - 1].size != 0)
    997   1.6  christos 	    {
    998   1.1  christos 	      /* xgettext:c-format */
    999   1.1  christos 	      _bfd_error_handler (_("%pB(%pA): invalid property table"),
   1000   1.1  christos 				  abfd, section);
   1001   1.1  christos 	      bfd_set_error (bfd_error_bad_value);
   1002   1.1  christos 	      free (blocks);
   1003   1.1  christos 	      return -1;
   1004   1.1  christos 	    }
   1005   1.1  christos 	}
   1006   1.1  christos     }
   1007   1.1  christos 
   1008   1.1  christos   *table_p = blocks;
   1009   1.1  christos   return block_count;
   1010   1.1  christos }
   1011   1.1  christos 
   1012   1.1  christos 
   1013   1.1  christos static property_table_entry *
   1014   1.1  christos elf_xtensa_find_property_entry (property_table_entry *property_table,
   1015   1.1  christos 				int property_table_size,
   1016   1.1  christos 				bfd_vma addr)
   1017   1.1  christos {
   1018   1.1  christos   property_table_entry entry;
   1019   1.1  christos   property_table_entry *rv;
   1020   1.1  christos 
   1021   1.1  christos   if (property_table_size == 0)
   1022   1.1  christos     return NULL;
   1023   1.1  christos 
   1024   1.1  christos   entry.address = addr;
   1025   1.1  christos   entry.size = 1;
   1026   1.1  christos   entry.flags = 0;
   1027   1.1  christos 
   1028   1.1  christos   rv = bsearch (&entry, property_table, property_table_size,
   1029   1.1  christos 		sizeof (property_table_entry), property_table_matches);
   1030   1.1  christos   return rv;
   1031   1.8  christos }
   1032   1.1  christos 
   1033   1.1  christos 
   1034   1.1  christos static bool
   1035   1.1  christos elf_xtensa_in_literal_pool (property_table_entry *lit_table,
   1036   1.1  christos 			    int lit_table_size,
   1037   1.8  christos 			    bfd_vma addr)
   1038   1.1  christos {
   1039   1.8  christos   if (elf_xtensa_find_property_entry (lit_table, lit_table_size, addr))
   1040   1.1  christos     return true;
   1041   1.1  christos 
   1042   1.1  christos   return false;
   1043   1.1  christos }
   1044   1.1  christos 
   1045   1.1  christos 
   1046   1.8  christos /* Look through the relocs for a section during the first phase, and
   1048   1.1  christos    calculate needed space in the dynamic reloc sections.  */
   1049   1.1  christos 
   1050   1.1  christos static bool
   1051   1.1  christos elf_xtensa_check_relocs (bfd *abfd,
   1052   1.1  christos 			 struct bfd_link_info *info,
   1053   1.1  christos 			 asection *sec,
   1054   1.1  christos 			 const Elf_Internal_Rela *relocs)
   1055   1.1  christos {
   1056   1.1  christos   struct elf_xtensa_link_hash_table *htab;
   1057   1.1  christos   Elf_Internal_Shdr *symtab_hdr;
   1058   1.8  christos   struct elf_link_hash_entry **sym_hashes;
   1059   1.8  christos   const Elf_Internal_Rela *rel;
   1060   1.1  christos   const Elf_Internal_Rela *rel_end;
   1061   1.1  christos 
   1062   1.1  christos   if (bfd_link_relocatable (info))
   1063   1.1  christos     return true;
   1064   1.1  christos 
   1065   1.8  christos   BFD_ASSERT (is_xtensa_elf (abfd));
   1066   1.1  christos 
   1067   1.1  christos   htab = elf_xtensa_hash_table (info);
   1068   1.1  christos   if (htab == NULL)
   1069   1.1  christos     return false;
   1070   1.1  christos 
   1071   1.1  christos   symtab_hdr = &elf_tdata (abfd)->symtab_hdr;
   1072   1.1  christos   sym_hashes = elf_sym_hashes (abfd);
   1073   1.1  christos 
   1074   1.6  christos   rel_end = relocs + sec->reloc_count;
   1075   1.1  christos   for (rel = relocs; rel < rel_end; rel++)
   1076   1.1  christos     {
   1077   1.1  christos       unsigned int r_type;
   1078   1.8  christos       unsigned r_symndx;
   1079   1.8  christos       struct elf_link_hash_entry *h = NULL;
   1080   1.8  christos       struct elf_xtensa_link_hash_entry *eh;
   1081   1.1  christos       int tls_type, old_tls_type;
   1082   1.1  christos       bool is_got = false;
   1083   1.1  christos       bool is_plt = false;
   1084   1.1  christos       bool is_tlsfunc = false;
   1085   1.1  christos 
   1086   1.1  christos       r_symndx = ELF32_R_SYM (rel->r_info);
   1087   1.6  christos       r_type = ELF32_R_TYPE (rel->r_info);
   1088   1.6  christos 
   1089   1.6  christos       if (r_symndx >= NUM_SHDR_ENTRIES (symtab_hdr))
   1090   1.8  christos 	{
   1091   1.1  christos 	  /* xgettext:c-format */
   1092   1.1  christos 	  _bfd_error_handler (_("%pB: bad symbol index: %d"),
   1093   1.1  christos 			      abfd, r_symndx);
   1094   1.1  christos 	  return false;
   1095   1.1  christos 	}
   1096   1.1  christos 
   1097   1.1  christos       if (r_symndx >= symtab_hdr->sh_info)
   1098   1.1  christos 	{
   1099   1.1  christos 	  h = sym_hashes[r_symndx - symtab_hdr->sh_info];
   1100   1.1  christos 	  while (h->root.type == bfd_link_hash_indirect
   1101   1.1  christos 		 || h->root.type == bfd_link_hash_warning)
   1102   1.1  christos 	    h = (struct elf_link_hash_entry *) h->root.u.i.link;
   1103   1.1  christos 	}
   1104   1.1  christos       eh = elf_xtensa_hash_entry (h);
   1105   1.9  christos 
   1106   1.1  christos       switch (r_type)
   1107   1.1  christos 	{
   1108   1.8  christos 	case R_XTENSA_TLSDESC_FN:
   1109   1.8  christos 	  if (bfd_link_dll (info))
   1110   1.1  christos 	    {
   1111   1.1  christos 	      tls_type = GOT_TLS_GD;
   1112   1.1  christos 	      is_got = true;
   1113   1.1  christos 	      is_tlsfunc = true;
   1114   1.1  christos 	    }
   1115   1.1  christos 	  else
   1116   1.9  christos 	    tls_type = GOT_TLS_IE;
   1117   1.1  christos 	  break;
   1118   1.1  christos 
   1119   1.8  christos 	case R_XTENSA_TLSDESC_ARG:
   1120   1.1  christos 	  if (bfd_link_dll (info))
   1121   1.1  christos 	    {
   1122   1.1  christos 	      tls_type = GOT_TLS_GD;
   1123   1.1  christos 	      is_got = true;
   1124   1.9  christos 	    }
   1125   1.9  christos 	  else
   1126   1.8  christos 	    {
   1127   1.1  christos 	      tls_type = GOT_TLS_IE;
   1128   1.1  christos 	      if (h && elf_xtensa_hash_entry (h) != htab->tlsbase
   1129   1.1  christos 		  && elf_xtensa_dynamic_symbol_p (h, info))
   1130   1.1  christos 		is_got = true;
   1131   1.9  christos 	    }
   1132   1.1  christos 	  break;
   1133   1.1  christos 
   1134   1.1  christos 	case R_XTENSA_TLS_DTPOFF:
   1135   1.1  christos 	  if (bfd_link_dll (info))
   1136   1.1  christos 	    tls_type = GOT_TLS_GD;
   1137   1.1  christos 	  else
   1138   1.1  christos 	    tls_type = GOT_TLS_IE;
   1139   1.3  christos 	  break;
   1140   1.1  christos 
   1141   1.9  christos 	case R_XTENSA_TLS_TPOFF:
   1142   1.8  christos 	  tls_type = GOT_TLS_IE;
   1143   1.1  christos 	  if (bfd_link_pic (info))
   1144   1.1  christos 	    info->flags |= DF_STATIC_TLS;
   1145   1.1  christos 	  if (bfd_link_dll (info) || elf_xtensa_dynamic_symbol_p (h, info))
   1146   1.1  christos 	    is_got = true;
   1147   1.8  christos 	  break;
   1148   1.1  christos 
   1149   1.1  christos 	case R_XTENSA_32:
   1150   1.1  christos 	  tls_type = GOT_NORMAL;
   1151   1.1  christos 	  is_got = true;
   1152   1.8  christos 	  break;
   1153   1.1  christos 
   1154   1.1  christos 	case R_XTENSA_PLT:
   1155   1.1  christos 	  tls_type = GOT_NORMAL;
   1156   1.1  christos 	  is_plt = true;
   1157   1.1  christos 	  break;
   1158   1.1  christos 
   1159   1.8  christos 	case R_XTENSA_GNU_VTINHERIT:
   1160   1.1  christos 	  /* This relocation describes the C++ object vtable hierarchy.
   1161   1.1  christos 	     Reconstruct it for later use during GC.  */
   1162   1.1  christos 	  if (!bfd_elf_gc_record_vtinherit (abfd, sec, h, rel->r_offset))
   1163   1.1  christos 	    return false;
   1164   1.1  christos 	  continue;
   1165   1.7  christos 
   1166   1.8  christos 	case R_XTENSA_GNU_VTENTRY:
   1167   1.1  christos 	  /* This relocation describes which C++ vtable entries are actually
   1168   1.1  christos 	     used.  Record for later use during GC.  */
   1169   1.1  christos 	  if (!bfd_elf_gc_record_vtentry (abfd, sec, h, rel->r_addend))
   1170   1.1  christos 	    return false;
   1171   1.1  christos 	  continue;
   1172   1.1  christos 
   1173   1.1  christos 	default:
   1174   1.1  christos 	  /* Nothing to do for any other relocations.  */
   1175   1.1  christos 	  continue;
   1176   1.1  christos 	}
   1177   1.1  christos 
   1178   1.1  christos       if (h)
   1179   1.1  christos 	{
   1180   1.1  christos 	  if (is_plt)
   1181   1.1  christos 	    {
   1182   1.1  christos 	      if (h->plt.refcount <= 0)
   1183   1.1  christos 		{
   1184   1.1  christos 		  h->needs_plt = 1;
   1185   1.1  christos 		  h->plt.refcount = 1;
   1186   1.1  christos 		}
   1187   1.1  christos 	      else
   1188   1.1  christos 		h->plt.refcount += 1;
   1189   1.1  christos 
   1190   1.1  christos 	      /* Keep track of the total PLT relocation count even if we
   1191   1.1  christos 		 don't yet know whether the dynamic sections will be
   1192   1.1  christos 		 created.  */
   1193   1.1  christos 	      htab->plt_reloc_count += 1;
   1194   1.8  christos 
   1195   1.1  christos 	      if (elf_hash_table (info)->dynamic_sections_created)
   1196   1.1  christos 		{
   1197   1.1  christos 		  if (! add_extra_plt_sections (info, htab->plt_reloc_count))
   1198   1.1  christos 		    return false;
   1199   1.1  christos 		}
   1200   1.1  christos 	    }
   1201   1.1  christos 	  else if (is_got)
   1202   1.1  christos 	    {
   1203   1.1  christos 	      if (h->got.refcount <= 0)
   1204   1.1  christos 		h->got.refcount = 1;
   1205   1.1  christos 	      else
   1206   1.1  christos 		h->got.refcount += 1;
   1207   1.1  christos 	    }
   1208   1.1  christos 
   1209   1.1  christos 	  if (is_tlsfunc)
   1210   1.1  christos 	    eh->tlsfunc_refcount += 1;
   1211   1.1  christos 
   1212   1.1  christos 	  old_tls_type = eh->tls_type;
   1213   1.1  christos 	}
   1214   1.1  christos       else
   1215   1.1  christos 	{
   1216   1.1  christos 	  /* Allocate storage the first time.  */
   1217   1.1  christos 	  if (elf_local_got_refcounts (abfd) == NULL)
   1218   1.1  christos 	    {
   1219   1.1  christos 	      bfd_size_type size = symtab_hdr->sh_info;
   1220   1.8  christos 	      void *mem;
   1221   1.1  christos 
   1222   1.1  christos 	      mem = bfd_zalloc (abfd, size * sizeof (bfd_signed_vma));
   1223   1.1  christos 	      if (mem == NULL)
   1224   1.1  christos 		return false;
   1225   1.8  christos 	      elf_local_got_refcounts (abfd) = (bfd_signed_vma *) mem;
   1226   1.1  christos 
   1227   1.1  christos 	      mem = bfd_zalloc (abfd, size);
   1228   1.1  christos 	      if (mem == NULL)
   1229   1.1  christos 		return false;
   1230   1.8  christos 	      elf_xtensa_local_got_tls_type (abfd) = (char *) mem;
   1231   1.1  christos 
   1232   1.1  christos 	      mem = bfd_zalloc (abfd, size * sizeof (bfd_signed_vma));
   1233   1.1  christos 	      if (mem == NULL)
   1234   1.1  christos 		return false;
   1235   1.1  christos 	      elf_xtensa_local_tlsfunc_refcounts (abfd)
   1236   1.1  christos 		= (bfd_signed_vma *) mem;
   1237   1.1  christos 	    }
   1238   1.1  christos 
   1239   1.1  christos 	  /* This is a global offset table entry for a local symbol.  */
   1240   1.1  christos 	  if (is_got || is_plt)
   1241   1.1  christos 	    elf_local_got_refcounts (abfd) [r_symndx] += 1;
   1242   1.1  christos 
   1243   1.1  christos 	  if (is_tlsfunc)
   1244   1.1  christos 	    elf_xtensa_local_tlsfunc_refcounts (abfd) [r_symndx] += 1;
   1245   1.1  christos 
   1246   1.1  christos 	  old_tls_type = elf_xtensa_local_got_tls_type (abfd) [r_symndx];
   1247   1.1  christos 	}
   1248   1.1  christos 
   1249   1.1  christos       if ((old_tls_type & GOT_TLS_IE) && (tls_type & GOT_TLS_IE))
   1250   1.1  christos 	tls_type |= old_tls_type;
   1251   1.1  christos       /* If a TLS symbol is accessed using IE at least once,
   1252   1.1  christos 	 there is no point to use a dynamic model for it.  */
   1253   1.1  christos       else if (old_tls_type != tls_type && old_tls_type != GOT_UNKNOWN
   1254   1.1  christos 	       && ((old_tls_type & GOT_TLS_GD) == 0
   1255   1.1  christos 		   || (tls_type & GOT_TLS_IE) == 0))
   1256   1.1  christos 	{
   1257   1.1  christos 	  if ((old_tls_type & GOT_TLS_IE) && (tls_type & GOT_TLS_GD))
   1258   1.1  christos 	    tls_type = old_tls_type;
   1259   1.6  christos 	  else if ((old_tls_type & GOT_TLS_GD) && (tls_type & GOT_TLS_GD))
   1260   1.6  christos 	    tls_type |= old_tls_type;
   1261   1.6  christos 	  else
   1262   1.1  christos 	    {
   1263   1.1  christos 	      _bfd_error_handler
   1264   1.8  christos 		/* xgettext:c-format */
   1265   1.1  christos 		(_("%pB: `%s' accessed both as normal and thread local symbol"),
   1266   1.1  christos 		 abfd,
   1267   1.1  christos 		 h ? h->root.root.string : "<local>");
   1268   1.1  christos 	      return false;
   1269   1.1  christos 	    }
   1270   1.1  christos 	}
   1271   1.1  christos 
   1272   1.1  christos       if (old_tls_type != tls_type)
   1273   1.1  christos 	{
   1274   1.1  christos 	  if (eh)
   1275   1.1  christos 	    eh->tls_type = tls_type;
   1276   1.1  christos 	  else
   1277   1.8  christos 	    elf_xtensa_local_got_tls_type (abfd) [r_symndx] = tls_type;
   1278   1.1  christos 	}
   1279   1.1  christos     }
   1280   1.1  christos 
   1281   1.1  christos   return true;
   1282   1.1  christos }
   1283   1.6  christos 
   1284   1.1  christos 
   1285   1.3  christos static void
   1286   1.1  christos elf_xtensa_make_sym_local (struct bfd_link_info *info,
   1287   1.1  christos 			   struct elf_link_hash_entry *h)
   1288   1.6  christos {
   1289   1.1  christos   if (bfd_link_pic (info))
   1290   1.1  christos     {
   1291   1.6  christos       if (h->plt.refcount > 0)
   1292   1.6  christos 	{
   1293   1.6  christos 	  /* For shared objects, there's no need for PLT entries for local
   1294   1.6  christos 	     symbols (use RELATIVE relocs instead of JMP_SLOT relocs).  */
   1295   1.6  christos 	  if (h->got.refcount < 0)
   1296   1.1  christos 	    h->got.refcount = 0;
   1297   1.1  christos 	  h->got.refcount += h->plt.refcount;
   1298   1.1  christos 	  h->plt.refcount = 0;
   1299   1.1  christos 	}
   1300   1.1  christos     }
   1301   1.1  christos   else
   1302   1.1  christos     {
   1303   1.1  christos       /* Don't need any dynamic relocations at all.  */
   1304   1.1  christos       h->plt.refcount = 0;
   1305   1.1  christos       h->got.refcount = 0;
   1306   1.1  christos     }
   1307   1.1  christos }
   1308   1.6  christos 
   1309   1.8  christos 
   1310   1.1  christos static void
   1311   1.1  christos elf_xtensa_hide_symbol (struct bfd_link_info *info,
   1312   1.1  christos 			struct elf_link_hash_entry *h,
   1313   1.1  christos 			bool force_local)
   1314   1.1  christos {
   1315   1.1  christos   /* For a shared link, move the plt refcount to the got refcount to leave
   1316   1.1  christos      space for RELATIVE relocs.  */
   1317   1.1  christos   elf_xtensa_make_sym_local (info, h);
   1318   1.1  christos 
   1319   1.1  christos   _bfd_elf_link_hash_hide_symbol (info, h, force_local);
   1320   1.1  christos }
   1321   1.1  christos 
   1322   1.1  christos 
   1323   1.1  christos /* Return the section that should be marked against GC for a given
   1324   1.1  christos    relocation.  */
   1325   1.1  christos 
   1326   1.1  christos static asection *
   1327   1.1  christos elf_xtensa_gc_mark_hook (asection *sec,
   1328   1.1  christos 			 struct bfd_link_info *info,
   1329   1.1  christos 			 Elf_Internal_Rela *rel,
   1330   1.1  christos 			 struct elf_link_hash_entry *h,
   1331   1.1  christos 			 Elf_Internal_Sym *sym)
   1332   1.1  christos {
   1333   1.1  christos   /* Property sections are marked "KEEP" in the linker scripts, but they
   1334   1.1  christos      should not cause other sections to be marked.  (This approach relies
   1335   1.1  christos      on elf_xtensa_discard_info to remove property table entries that
   1336   1.1  christos      describe discarded sections.  Alternatively, it might be more
   1337   1.1  christos      efficient to avoid using "KEEP" in the linker scripts and instead use
   1338   1.1  christos      the gc_mark_extra_sections hook to mark only the property sections
   1339   1.1  christos      that describe marked sections.  That alternative does not work well
   1340   1.1  christos      with the current property table sections, which do not correspond
   1341   1.1  christos      one-to-one with the sections they describe, but that should be fixed
   1342   1.1  christos      someday.) */
   1343   1.1  christos   if (xtensa_is_property_section (sec))
   1344   1.1  christos     return NULL;
   1345   1.1  christos 
   1346   1.1  christos   if (h != NULL)
   1347   1.1  christos     switch (ELF32_R_TYPE (rel->r_info))
   1348   1.1  christos       {
   1349   1.1  christos       case R_XTENSA_GNU_VTINHERIT:
   1350   1.1  christos       case R_XTENSA_GNU_VTENTRY:
   1351   1.1  christos 	return NULL;
   1352   1.1  christos       }
   1353   1.1  christos 
   1354   1.1  christos   return _bfd_elf_gc_mark_hook (sec, info, rel, h, sym);
   1355   1.1  christos }
   1356   1.8  christos 
   1357   1.1  christos 
   1358   1.1  christos /* Create all the dynamic sections.  */
   1359   1.1  christos 
   1360   1.1  christos static bool
   1361   1.1  christos elf_xtensa_create_dynamic_sections (bfd *dynobj, struct bfd_link_info *info)
   1362   1.1  christos {
   1363   1.1  christos   struct elf_xtensa_link_hash_table *htab;
   1364   1.8  christos   flagword flags, noalloc_flags;
   1365   1.1  christos 
   1366   1.1  christos   htab = elf_xtensa_hash_table (info);
   1367   1.1  christos   if (htab == NULL)
   1368   1.8  christos     return false;
   1369   1.1  christos 
   1370   1.1  christos   /* First do all the standard stuff.  */
   1371   1.1  christos   if (! _bfd_elf_create_dynamic_sections (dynobj, info))
   1372   1.1  christos     return false;
   1373   1.8  christos 
   1374   1.1  christos   /* Create any extra PLT sections in case check_relocs has already
   1375   1.1  christos      been called on all the non-dynamic input files.  */
   1376   1.1  christos   if (! add_extra_plt_sections (info, htab->plt_reloc_count))
   1377   1.1  christos     return false;
   1378   1.1  christos 
   1379   1.1  christos   noalloc_flags = (SEC_HAS_CONTENTS | SEC_IN_MEMORY
   1380   1.6  christos 		   | SEC_LINKER_CREATED | SEC_READONLY);
   1381   1.7  christos   flags = noalloc_flags | SEC_ALLOC | SEC_LOAD;
   1382   1.8  christos 
   1383   1.1  christos   /* Mark the ".got.plt" section READONLY.  */
   1384   1.1  christos   if (htab->elf.sgotplt == NULL
   1385   1.1  christos       || !bfd_set_section_flags (htab->elf.sgotplt, flags))
   1386   1.1  christos     return false;
   1387   1.1  christos 
   1388   1.7  christos   /* Create ".got.loc" (literal tables for use by dynamic linker).  */
   1389   1.8  christos   htab->sgotloc = bfd_make_section_anyway_with_flags (dynobj, ".got.loc",
   1390   1.1  christos 						      flags);
   1391   1.1  christos   if (htab->sgotloc == NULL
   1392   1.1  christos       || !bfd_set_section_alignment (htab->sgotloc, 2))
   1393   1.1  christos     return false;
   1394   1.1  christos 
   1395   1.7  christos   /* Create ".xt.lit.plt" (literal table for ".got.plt*").  */
   1396   1.8  christos   htab->spltlittbl = bfd_make_section_anyway_with_flags (dynobj, ".xt.lit.plt",
   1397   1.1  christos 							 noalloc_flags);
   1398   1.8  christos   if (htab->spltlittbl == NULL
   1399   1.1  christos       || !bfd_set_section_alignment (htab->spltlittbl, 2))
   1400   1.1  christos     return false;
   1401   1.1  christos 
   1402   1.8  christos   return true;
   1403   1.1  christos }
   1404   1.1  christos 
   1405   1.1  christos 
   1406   1.1  christos static bool
   1407   1.1  christos add_extra_plt_sections (struct bfd_link_info *info, int count)
   1408   1.1  christos {
   1409   1.1  christos   bfd *dynobj = elf_hash_table (info)->dynobj;
   1410   1.1  christos   int chunk;
   1411   1.1  christos 
   1412   1.1  christos   /* Iterate over all chunks except 0 which uses the standard ".plt" and
   1413   1.1  christos      ".got.plt" sections.  */
   1414   1.1  christos   for (chunk = count / PLT_ENTRIES_PER_CHUNK; chunk > 0; chunk--)
   1415   1.1  christos     {
   1416   1.1  christos       char *sname;
   1417   1.1  christos       flagword flags;
   1418   1.1  christos       asection *s;
   1419   1.1  christos 
   1420   1.1  christos       /* Stop when we find a section has already been created.  */
   1421   1.1  christos       if (elf_xtensa_get_plt_section (info, chunk))
   1422   1.1  christos 	break;
   1423   1.1  christos 
   1424   1.1  christos       flags = (SEC_ALLOC | SEC_LOAD | SEC_HAS_CONTENTS | SEC_IN_MEMORY
   1425   1.1  christos 	       | SEC_LINKER_CREATED | SEC_READONLY);
   1426   1.1  christos 
   1427   1.7  christos       sname = (char *) bfd_malloc (10);
   1428   1.8  christos       sprintf (sname, ".plt.%u", chunk);
   1429   1.1  christos       s = bfd_make_section_anyway_with_flags (dynobj, sname, flags | SEC_CODE);
   1430   1.1  christos       if (s == NULL
   1431   1.1  christos 	  || !bfd_set_section_alignment (s, 2))
   1432   1.1  christos 	return false;
   1433   1.1  christos 
   1434   1.7  christos       sname = (char *) bfd_malloc (14);
   1435   1.8  christos       sprintf (sname, ".got.plt.%u", chunk);
   1436   1.1  christos       s = bfd_make_section_anyway_with_flags (dynobj, sname, flags);
   1437   1.1  christos       if (s == NULL
   1438   1.8  christos 	  || !bfd_set_section_alignment (s, 2))
   1439   1.1  christos 	return false;
   1440   1.1  christos     }
   1441   1.1  christos 
   1442   1.1  christos   return true;
   1443   1.1  christos }
   1444   1.1  christos 
   1445   1.1  christos 
   1446   1.1  christos /* Adjust a symbol defined by a dynamic object and referenced by a
   1447   1.1  christos    regular object.  The current definition is in some section of the
   1448   1.8  christos    dynamic object, but we're not including those sections.  We have to
   1449   1.1  christos    change the definition to something the rest of the link can
   1450   1.1  christos    understand.  */
   1451   1.1  christos 
   1452   1.1  christos static bool
   1453   1.1  christos elf_xtensa_adjust_dynamic_symbol (struct bfd_link_info *info ATTRIBUTE_UNUSED,
   1454   1.1  christos 				  struct elf_link_hash_entry *h)
   1455   1.6  christos {
   1456   1.1  christos   /* If this is a weak symbol, and there is a real definition, the
   1457   1.6  christos      processor independent code will have arranged for us to see the
   1458   1.6  christos      real definition first, and we can just use the same value.  */
   1459   1.6  christos   if (h->is_weakalias)
   1460   1.6  christos     {
   1461   1.8  christos       struct elf_link_hash_entry *def = weakdef (h);
   1462   1.1  christos       BFD_ASSERT (def->root.type == bfd_link_hash_defined);
   1463   1.1  christos       h->root.u.def.section = def->root.u.def.section;
   1464   1.1  christos       h->root.u.def.value = def->root.u.def.value;
   1465   1.1  christos       return true;
   1466   1.1  christos     }
   1467   1.1  christos 
   1468   1.8  christos   /* This is a reference to a symbol defined by a dynamic object.  The
   1469   1.1  christos      reference must go through the GOT, so there's no need for COPY relocs,
   1470   1.1  christos      .dynbss, etc.  */
   1471   1.1  christos 
   1472   1.8  christos   return true;
   1473   1.1  christos }
   1474   1.1  christos 
   1475   1.1  christos 
   1476   1.1  christos static bool
   1477   1.1  christos elf_xtensa_allocate_dynrelocs (struct elf_link_hash_entry *h, void *arg)
   1478   1.1  christos {
   1479   1.1  christos   struct bfd_link_info *info;
   1480   1.8  christos   struct elf_xtensa_link_hash_table *htab;
   1481   1.1  christos   struct elf_xtensa_link_hash_entry *eh = elf_xtensa_hash_entry (h);
   1482   1.1  christos 
   1483   1.1  christos   if (h->root.type == bfd_link_hash_indirect)
   1484   1.1  christos     return true;
   1485   1.8  christos 
   1486   1.1  christos   info = (struct bfd_link_info *) arg;
   1487   1.1  christos   htab = elf_xtensa_hash_table (info);
   1488   1.1  christos   if (htab == NULL)
   1489   1.1  christos     return false;
   1490   1.1  christos 
   1491   1.1  christos   /* If we saw any use of an IE model for this symbol, we can then optimize
   1492   1.1  christos      away GOT entries for any TLSDESC_FN relocs.  */
   1493   1.1  christos   if ((eh->tls_type & GOT_TLS_IE) != 0)
   1494   1.1  christos     {
   1495   1.1  christos       BFD_ASSERT (h->got.refcount >= eh->tlsfunc_refcount);
   1496   1.1  christos       h->got.refcount -= eh->tlsfunc_refcount;
   1497   1.1  christos     }
   1498   1.6  christos 
   1499   1.6  christos   if (! elf_xtensa_dynamic_symbol_p (h, info))
   1500   1.8  christos     elf_xtensa_make_sym_local (info, h);
   1501   1.6  christos 
   1502   1.1  christos   if (! elf_xtensa_dynamic_symbol_p (h, info)
   1503   1.6  christos       && h->root.type == bfd_link_hash_undefweak)
   1504   1.1  christos     return true;
   1505   1.1  christos 
   1506   1.6  christos   if (h->plt.refcount > 0)
   1507   1.1  christos     htab->elf.srelplt->size += (h->plt.refcount * sizeof (Elf32_External_Rela));
   1508   1.8  christos 
   1509   1.1  christos   if (h->got.refcount > 0)
   1510   1.1  christos     htab->elf.srelgot->size += (h->got.refcount * sizeof (Elf32_External_Rela));
   1511   1.1  christos 
   1512   1.1  christos   return true;
   1513   1.1  christos }
   1514   1.1  christos 
   1515   1.1  christos 
   1516   1.1  christos static void
   1517   1.1  christos elf_xtensa_allocate_local_got_size (struct bfd_link_info *info)
   1518   1.1  christos {
   1519   1.1  christos   struct elf_xtensa_link_hash_table *htab;
   1520   1.1  christos   bfd *i;
   1521   1.1  christos 
   1522   1.3  christos   htab = elf_xtensa_hash_table (info);
   1523   1.1  christos   if (htab == NULL)
   1524   1.1  christos     return;
   1525   1.1  christos 
   1526   1.1  christos   for (i = info->input_bfds; i; i = i->link.next)
   1527   1.1  christos     {
   1528   1.1  christos       bfd_signed_vma *local_got_refcounts;
   1529   1.1  christos       bfd_size_type j, cnt;
   1530   1.1  christos       Elf_Internal_Shdr *symtab_hdr;
   1531   1.1  christos 
   1532   1.1  christos       local_got_refcounts = elf_local_got_refcounts (i);
   1533   1.1  christos       if (!local_got_refcounts)
   1534   1.1  christos 	continue;
   1535   1.1  christos 
   1536   1.1  christos       symtab_hdr = &elf_tdata (i)->symtab_hdr;
   1537   1.1  christos       cnt = symtab_hdr->sh_info;
   1538   1.1  christos 
   1539   1.1  christos       for (j = 0; j < cnt; ++j)
   1540   1.1  christos 	{
   1541   1.1  christos 	  /* If we saw any use of an IE model for this symbol, we can
   1542   1.1  christos 	     then optimize away GOT entries for any TLSDESC_FN relocs.  */
   1543   1.1  christos 	  if ((elf_xtensa_local_got_tls_type (i) [j] & GOT_TLS_IE) != 0)
   1544   1.1  christos 	    {
   1545   1.1  christos 	      bfd_signed_vma *tlsfunc_refcount
   1546   1.1  christos 		= &elf_xtensa_local_tlsfunc_refcounts (i) [j];
   1547   1.1  christos 	      BFD_ASSERT (local_got_refcounts[j] >= *tlsfunc_refcount);
   1548   1.6  christos 	      local_got_refcounts[j] -= *tlsfunc_refcount;
   1549   1.6  christos 	    }
   1550   1.1  christos 
   1551   1.1  christos 	  if (local_got_refcounts[j] > 0)
   1552   1.1  christos 	    htab->elf.srelgot->size += (local_got_refcounts[j]
   1553   1.1  christos 					* sizeof (Elf32_External_Rela));
   1554   1.1  christos 	}
   1555   1.1  christos     }
   1556   1.1  christos }
   1557   1.8  christos 
   1558  1.10  christos 
   1559  1.10  christos /* Set the sizes of the dynamic sections.  */
   1560   1.1  christos 
   1561   1.1  christos static bool
   1562   1.1  christos elf_xtensa_late_size_sections (bfd *output_bfd ATTRIBUTE_UNUSED,
   1563   1.1  christos 			       struct bfd_link_info *info)
   1564   1.8  christos {
   1565   1.1  christos   struct elf_xtensa_link_hash_table *htab;
   1566   1.1  christos   bfd *dynobj, *abfd;
   1567   1.1  christos   asection *s, *srelplt, *splt, *sgotplt, *srelgot, *spltlittbl, *sgotloc;
   1568   1.1  christos   bool relplt, relgot;
   1569   1.1  christos   int plt_entries, plt_chunks, chunk;
   1570   1.1  christos 
   1571   1.1  christos   plt_entries = 0;
   1572   1.8  christos   plt_chunks = 0;
   1573   1.1  christos 
   1574   1.1  christos   htab = elf_xtensa_hash_table (info);
   1575   1.1  christos   if (htab == NULL)
   1576  1.10  christos     return false;
   1577   1.6  christos 
   1578   1.6  christos   dynobj = elf_hash_table (info)->dynobj;
   1579   1.1  christos   if (dynobj == NULL)
   1580   1.1  christos     return true;
   1581   1.1  christos   srelgot = htab->elf.srelgot;
   1582   1.6  christos   srelplt = htab->elf.srelplt;
   1583   1.6  christos 
   1584   1.6  christos   if (elf_hash_table (info)->dynamic_sections_created)
   1585   1.1  christos     {
   1586   1.1  christos       BFD_ASSERT (htab->elf.srelgot != NULL
   1587   1.1  christos 		  && htab->elf.srelplt != NULL
   1588   1.1  christos 		  && htab->elf.sgot != NULL
   1589   1.3  christos 		  && htab->spltlittbl != NULL
   1590   1.1  christos 		  && htab->sgotloc != NULL);
   1591   1.1  christos 
   1592   1.1  christos       /* Set the contents of the .interp section to the interpreter.  */
   1593   1.1  christos       if (bfd_link_executable (info) && !info->nointerp)
   1594   1.1  christos 	{
   1595   1.1  christos 	  s = bfd_get_linker_section (dynobj, ".interp");
   1596  1.10  christos 	  if (s == NULL)
   1597   1.1  christos 	    abort ();
   1598   1.1  christos 	  s->size = sizeof ELF_DYNAMIC_INTERPRETER;
   1599   1.1  christos 	  s->contents = (unsigned char *) ELF_DYNAMIC_INTERPRETER;
   1600   1.6  christos 	  s->alloced = 1;
   1601   1.1  christos 	}
   1602   1.1  christos 
   1603   1.1  christos       /* Allocate room for one word in ".got".  */
   1604   1.1  christos       htab->elf.sgot->size = 4;
   1605   1.1  christos 
   1606   1.1  christos       /* Allocate space in ".rela.got" for literals that reference global
   1607   1.1  christos 	 symbols and space in ".rela.plt" for literals that have PLT
   1608   1.1  christos 	 entries.  */
   1609   1.1  christos       elf_link_hash_traverse (elf_hash_table (info),
   1610   1.1  christos 			      elf_xtensa_allocate_dynrelocs,
   1611   1.1  christos 			      (void *) info);
   1612   1.3  christos 
   1613   1.1  christos       /* If we are generating a shared object, we also need space in
   1614   1.1  christos 	 ".rela.got" for R_XTENSA_RELATIVE relocs for literals that
   1615   1.1  christos 	 reference local symbols.  */
   1616   1.1  christos       if (bfd_link_pic (info))
   1617   1.1  christos 	elf_xtensa_allocate_local_got_size (info);
   1618   1.1  christos 
   1619   1.1  christos       /* Allocate space in ".plt" to match the size of ".rela.plt".  For
   1620   1.1  christos 	 each PLT entry, we need the PLT code plus a 4-byte literal.
   1621   1.1  christos 	 For each chunk of ".plt", we also need two more 4-byte
   1622   1.1  christos 	 literals, two corresponding entries in ".rela.got", and an
   1623   1.1  christos 	 8-byte entry in ".xt.lit.plt".  */
   1624   1.1  christos       spltlittbl = htab->spltlittbl;
   1625   1.1  christos       plt_entries = srelplt->size / sizeof (Elf32_External_Rela);
   1626   1.1  christos       plt_chunks =
   1627   1.1  christos 	(plt_entries + PLT_ENTRIES_PER_CHUNK - 1) / PLT_ENTRIES_PER_CHUNK;
   1628   1.1  christos 
   1629   1.1  christos       /* Iterate over all the PLT chunks, including any extra sections
   1630   1.1  christos 	 created earlier because the initial count of PLT relocations
   1631   1.1  christos 	 was an overestimate.  */
   1632   1.1  christos       for (chunk = 0;
   1633   1.1  christos 	   (splt = elf_xtensa_get_plt_section (info, chunk)) != NULL;
   1634   1.1  christos 	   chunk++)
   1635   1.1  christos 	{
   1636   1.1  christos 	  int chunk_entries;
   1637   1.1  christos 
   1638   1.1  christos 	  sgotplt = elf_xtensa_get_gotplt_section (info, chunk);
   1639   1.1  christos 	  BFD_ASSERT (sgotplt != NULL);
   1640   1.1  christos 
   1641   1.1  christos 	  if (chunk < plt_chunks - 1)
   1642   1.1  christos 	    chunk_entries = PLT_ENTRIES_PER_CHUNK;
   1643   1.1  christos 	  else if (chunk == plt_chunks - 1)
   1644   1.1  christos 	    chunk_entries = plt_entries - (chunk * PLT_ENTRIES_PER_CHUNK);
   1645   1.1  christos 	  else
   1646   1.1  christos 	    chunk_entries = 0;
   1647   1.1  christos 
   1648   1.1  christos 	  if (chunk_entries != 0)
   1649   1.1  christos 	    {
   1650   1.1  christos 	      sgotplt->size = 4 * (chunk_entries + 2);
   1651   1.1  christos 	      splt->size = PLT_ENTRY_SIZE * chunk_entries;
   1652   1.1  christos 	      srelgot->size += 2 * sizeof (Elf32_External_Rela);
   1653   1.1  christos 	      spltlittbl->size += 8;
   1654   1.1  christos 	    }
   1655   1.1  christos 	  else
   1656   1.1  christos 	    {
   1657   1.1  christos 	      sgotplt->size = 0;
   1658   1.1  christos 	      splt->size = 0;
   1659   1.1  christos 	    }
   1660   1.1  christos 	}
   1661   1.1  christos 
   1662   1.3  christos       /* Allocate space in ".got.loc" to match the total size of all the
   1663   1.1  christos 	 literal tables.  */
   1664   1.1  christos       sgotloc = htab->sgotloc;
   1665   1.1  christos       sgotloc->size = spltlittbl->size;
   1666   1.1  christos       for (abfd = info->input_bfds; abfd != NULL; abfd = abfd->link.next)
   1667   1.1  christos 	{
   1668   1.1  christos 	  if (abfd->flags & DYNAMIC)
   1669   1.1  christos 	    continue;
   1670   1.1  christos 	  for (s = abfd->sections; s != NULL; s = s->next)
   1671   1.1  christos 	    {
   1672   1.1  christos 	      if (! discarded_section (s)
   1673   1.1  christos 		  && xtensa_is_littable_section (s)
   1674   1.1  christos 		  && s != spltlittbl)
   1675   1.1  christos 		sgotloc->size += s->size;
   1676   1.1  christos 	    }
   1677   1.8  christos 	}
   1678   1.8  christos     }
   1679   1.1  christos 
   1680   1.1  christos   /* Allocate memory for dynamic sections.  */
   1681   1.1  christos   relplt = false;
   1682   1.1  christos   relgot = false;
   1683   1.1  christos   for (s = dynobj->sections; s != NULL; s = s->next)
   1684   1.1  christos     {
   1685   1.1  christos       const char *name;
   1686   1.1  christos 
   1687   1.1  christos       if ((s->flags & SEC_LINKER_CREATED) == 0)
   1688   1.7  christos 	continue;
   1689   1.1  christos 
   1690   1.8  christos       /* It's OK to base decisions on the section name, because none
   1691   1.1  christos 	 of the dynobj section names depend upon the input files.  */
   1692   1.1  christos       name = bfd_section_name (s);
   1693   1.1  christos 
   1694   1.1  christos       if (startswith (name, ".rela"))
   1695   1.8  christos 	{
   1696   1.1  christos 	  if (s->size != 0)
   1697   1.8  christos 	    {
   1698   1.1  christos 	      if (strcmp (name, ".rela.plt") == 0)
   1699   1.1  christos 		relplt = true;
   1700   1.1  christos 	      else if (strcmp (name, ".rela.got") == 0)
   1701   1.1  christos 		relgot = true;
   1702   1.1  christos 
   1703   1.1  christos 	      /* We use the reloc_count field as a counter if we need
   1704   1.8  christos 		 to copy relocs into the output file.  */
   1705   1.8  christos 	      s->reloc_count = 0;
   1706   1.1  christos 	    }
   1707   1.1  christos 	}
   1708   1.1  christos       else if (! startswith (name, ".plt.")
   1709   1.1  christos 	       && ! startswith (name, ".got.plt.")
   1710   1.1  christos 	       && strcmp (name, ".got") != 0
   1711   1.1  christos 	       && strcmp (name, ".plt") != 0
   1712   1.1  christos 	       && strcmp (name, ".got.plt") != 0
   1713   1.1  christos 	       && strcmp (name, ".xt.lit.plt") != 0
   1714   1.1  christos 	       && strcmp (name, ".got.loc") != 0)
   1715   1.1  christos 	{
   1716   1.1  christos 	  /* It's not one of our sections, so don't allocate space.  */
   1717   1.1  christos 	  continue;
   1718   1.1  christos 	}
   1719   1.1  christos 
   1720   1.1  christos       if (s->size == 0)
   1721   1.1  christos 	{
   1722   1.1  christos 	  /* If we don't need this section, strip it from the output
   1723   1.1  christos 	     file.  We must create the ".plt*" and ".got.plt*"
   1724   1.1  christos 	     sections in create_dynamic_sections and/or check_relocs
   1725   1.1  christos 	     based on a conservative estimate of the PLT relocation
   1726   1.1  christos 	     count, because the sections must be created before the
   1727   1.1  christos 	     linker maps input sections to output sections.  The
   1728   1.1  christos 	     linker does that before size_dynamic_sections, where we
   1729   1.1  christos 	     compute the exact size of the PLT, so there may be more
   1730   1.1  christos 	     of these sections than are actually needed.  */
   1731   1.1  christos 	  s->flags |= SEC_EXCLUDE;
   1732   1.1  christos 	}
   1733   1.1  christos       else if ((s->flags & SEC_HAS_CONTENTS) != 0)
   1734   1.8  christos 	{
   1735  1.10  christos 	  /* Allocate memory for the section contents.  */
   1736   1.1  christos 	  s->contents = (bfd_byte *) bfd_zalloc (dynobj, s->size);
   1737   1.1  christos 	  if (s->contents == NULL)
   1738   1.1  christos 	    return false;
   1739   1.1  christos 	  s->alloced = 1;
   1740   1.1  christos 	}
   1741   1.1  christos     }
   1742   1.1  christos 
   1743   1.1  christos   if (elf_hash_table (info)->dynamic_sections_created)
   1744   1.1  christos     {
   1745   1.1  christos       /* Add the special XTENSA_RTLD relocations now.  The offsets won't be
   1746   1.1  christos 	 known until finish_dynamic_sections, but we need to get the relocs
   1747   1.1  christos 	 in place before they are sorted.  */
   1748   1.1  christos       for (chunk = 0; chunk < plt_chunks; chunk++)
   1749   1.1  christos 	{
   1750   1.1  christos 	  Elf_Internal_Rela irela;
   1751   1.1  christos 	  bfd_byte *loc;
   1752   1.1  christos 
   1753   1.1  christos 	  irela.r_offset = 0;
   1754   1.1  christos 	  irela.r_info = ELF32_R_INFO (0, R_XTENSA_RTLD);
   1755   1.1  christos 	  irela.r_addend = 0;
   1756   1.1  christos 
   1757   1.1  christos 	  loc = (srelgot->contents
   1758   1.1  christos 		 + srelgot->reloc_count * sizeof (Elf32_External_Rela));
   1759   1.1  christos 	  bfd_elf32_swap_reloca_out (output_bfd, &irela, loc);
   1760   1.1  christos 	  bfd_elf32_swap_reloca_out (output_bfd, &irela,
   1761   1.1  christos 				     loc + sizeof (Elf32_External_Rela));
   1762   1.1  christos 	  srelgot->reloc_count += 2;
   1763   1.1  christos 	}
   1764   1.1  christos 
   1765   1.1  christos       /* Add some entries to the .dynamic section.  We fill in the
   1766   1.1  christos 	 values later, in elf_xtensa_finish_dynamic_sections, but we
   1767   1.1  christos 	 must add the entries now so that we get the correct size for
   1768   1.1  christos 	 the .dynamic section.  The DT_DEBUG entry is filled in by the
   1769   1.8  christos 	 dynamic linker and used by the debugger.  */
   1770   1.8  christos #define add_dynamic_entry(TAG, VAL) \
   1771   1.8  christos   _bfd_elf_add_dynamic_entry (info, TAG, VAL)
   1772   1.1  christos 
   1773   1.8  christos       if (!_bfd_elf_add_dynamic_tags (output_bfd, info,
   1774   1.1  christos 				      relplt || relgot))
   1775   1.8  christos 	return false;
   1776   1.1  christos 
   1777   1.1  christos       if (!add_dynamic_entry (DT_XTENSA_GOT_LOC_OFF, 0)
   1778   1.1  christos 	  || !add_dynamic_entry (DT_XTENSA_GOT_LOC_SZ, 0))
   1779   1.8  christos 	return false;
   1780   1.1  christos     }
   1781   1.1  christos #undef add_dynamic_entry
   1782   1.8  christos 
   1783  1.10  christos   return true;
   1784   1.1  christos }
   1785   1.1  christos 
   1786   1.1  christos static bool
   1787   1.1  christos elf_xtensa_early_size_sections (bfd *output_bfd, struct bfd_link_info *info)
   1788   1.1  christos {
   1789   1.1  christos   struct elf_xtensa_link_hash_table *htab;
   1790   1.8  christos   asection *tls_sec;
   1791   1.1  christos 
   1792   1.1  christos   htab = elf_xtensa_hash_table (info);
   1793   1.1  christos   if (htab == NULL)
   1794   1.1  christos     return false;
   1795   1.1  christos 
   1796   1.1  christos   tls_sec = htab->elf.tls_sec;
   1797   1.1  christos 
   1798   1.1  christos   if (tls_sec && (htab->tlsbase->tls_type & GOT_TLS_ANY) != 0)
   1799   1.1  christos     {
   1800   1.1  christos       struct elf_link_hash_entry *tlsbase = &htab->tlsbase->elf;
   1801   1.1  christos       struct bfd_link_hash_entry *bh = &tlsbase->root;
   1802   1.1  christos       const struct elf_backend_data *bed = get_elf_backend_data (output_bfd);
   1803   1.8  christos 
   1804   1.1  christos       tlsbase->type = STT_TLS;
   1805   1.8  christos       if (!(_bfd_generic_link_add_one_symbol
   1806   1.1  christos 	    (info, output_bfd, "_TLS_MODULE_BASE_", BSF_LOCAL,
   1807   1.1  christos 	     tls_sec, 0, NULL, false,
   1808   1.8  christos 	     bed->collect, &bh)))
   1809   1.1  christos 	return false;
   1810   1.1  christos       tlsbase->def_regular = 1;
   1811   1.8  christos       tlsbase->other = STV_HIDDEN;
   1812   1.1  christos       (*bed->elf_backend_hide_symbol) (info, tlsbase, true);
   1813   1.1  christos     }
   1814   1.1  christos 
   1815   1.1  christos   return true;
   1816   1.1  christos }
   1817   1.1  christos 
   1818   1.1  christos 
   1819   1.1  christos /* Return the base VMA address which should be subtracted from real addresses
   1821   1.1  christos    when resolving @dtpoff relocation.
   1822   1.1  christos    This is PT_TLS segment p_vaddr.  */
   1823   1.1  christos 
   1824   1.1  christos static bfd_vma
   1825   1.1  christos dtpoff_base (struct bfd_link_info *info)
   1826   1.1  christos {
   1827   1.1  christos   /* If tls_sec is NULL, we should have signalled an error already.  */
   1828   1.1  christos   if (elf_hash_table (info)->tls_sec == NULL)
   1829   1.1  christos     return 0;
   1830   1.1  christos   return elf_hash_table (info)->tls_sec->vma;
   1831   1.1  christos }
   1832   1.1  christos 
   1833   1.1  christos /* Return the relocation value for @tpoff relocation
   1834   1.1  christos    if STT_TLS virtual address is ADDRESS.  */
   1835   1.1  christos 
   1836   1.1  christos static bfd_vma
   1837   1.1  christos tpoff (struct bfd_link_info *info, bfd_vma address)
   1838   1.1  christos {
   1839   1.1  christos   struct elf_link_hash_table *htab = elf_hash_table (info);
   1840   1.1  christos   bfd_vma base;
   1841   1.1  christos 
   1842   1.1  christos   /* If tls_sec is NULL, we should have signalled an error already.  */
   1843   1.1  christos   if (htab->tls_sec == NULL)
   1844   1.1  christos     return 0;
   1845   1.1  christos   base = align_power ((bfd_vma) TCB_SIZE, htab->tls_sec->alignment_power);
   1846   1.1  christos   return address - htab->tls_sec->vma + base;
   1847   1.1  christos }
   1848   1.1  christos 
   1849   1.1  christos /* Perform the specified relocation.  The instruction at (contents + address)
   1850   1.1  christos    is modified to set one operand to represent the value in "relocation".  The
   1851   1.1  christos    operand position is determined by the relocation type recorded in the
   1852   1.1  christos    howto.  */
   1853   1.1  christos 
   1854   1.1  christos #define CALL_SEGMENT_BITS (30)
   1855   1.1  christos #define CALL_SEGMENT_SIZE (1 << CALL_SEGMENT_BITS)
   1856   1.1  christos 
   1857   1.1  christos static bfd_reloc_status_type
   1858   1.1  christos elf_xtensa_do_reloc (reloc_howto_type *howto,
   1859   1.8  christos 		     bfd *abfd,
   1860   1.1  christos 		     asection *input_section,
   1861   1.1  christos 		     bfd_vma relocation,
   1862   1.1  christos 		     bfd_byte *contents,
   1863   1.1  christos 		     bfd_vma address,
   1864   1.1  christos 		     bool is_weak_undef,
   1865   1.1  christos 		     char **error_message)
   1866   1.1  christos {
   1867   1.1  christos   xtensa_format fmt;
   1868   1.1  christos   xtensa_opcode opcode;
   1869   1.1  christos   xtensa_isa isa = xtensa_default_isa;
   1870   1.1  christos   static xtensa_insnbuf ibuff = NULL;
   1871   1.1  christos   static xtensa_insnbuf sbuff = NULL;
   1872   1.1  christos   bfd_vma self_address;
   1873   1.1  christos   bfd_size_type input_size;
   1874   1.1  christos   int opnd, slot;
   1875   1.1  christos   uint32 newval;
   1876   1.1  christos 
   1877   1.1  christos   if (!ibuff)
   1878   1.1  christos     {
   1879   1.1  christos       ibuff = xtensa_insnbuf_alloc (isa);
   1880   1.1  christos       sbuff = xtensa_insnbuf_alloc (isa);
   1881   1.1  christos     }
   1882   1.1  christos 
   1883   1.1  christos   input_size = bfd_get_section_limit (abfd, input_section);
   1884   1.1  christos 
   1885   1.1  christos   /* Calculate the PC address for this instruction.  */
   1886   1.1  christos   self_address = (input_section->output_section->vma
   1887   1.1  christos 		  + input_section->output_offset
   1888   1.1  christos 		  + address);
   1889   1.1  christos 
   1890   1.1  christos   switch (howto->type)
   1891   1.8  christos     {
   1892   1.8  christos     case R_XTENSA_NONE:
   1893   1.8  christos     case R_XTENSA_DIFF8:
   1894   1.8  christos     case R_XTENSA_DIFF16:
   1895   1.8  christos     case R_XTENSA_DIFF32:
   1896   1.8  christos     case R_XTENSA_PDIFF8:
   1897   1.1  christos     case R_XTENSA_PDIFF16:
   1898   1.1  christos     case R_XTENSA_PDIFF32:
   1899   1.1  christos     case R_XTENSA_NDIFF8:
   1900   1.1  christos     case R_XTENSA_NDIFF16:
   1901   1.1  christos     case R_XTENSA_NDIFF32:
   1902   1.1  christos     case R_XTENSA_TLS_FUNC:
   1903   1.1  christos     case R_XTENSA_TLS_ARG:
   1904   1.1  christos     case R_XTENSA_TLS_CALL:
   1905   1.1  christos       return bfd_reloc_ok;
   1906   1.1  christos 
   1907   1.1  christos     case R_XTENSA_ASM_EXPAND:
   1908   1.1  christos       if (!is_weak_undef)
   1909   1.1  christos 	{
   1910   1.1  christos 	  /* Check for windowed CALL across a 1GB boundary.  */
   1911   1.3  christos 	  opcode = get_expanded_call_opcode (contents + address,
   1912   1.1  christos 					     input_size - address, 0);
   1913   1.1  christos 	  if (is_windowed_call_opcode (opcode))
   1914   1.1  christos 	    {
   1915   1.1  christos 	      if ((self_address >> CALL_SEGMENT_BITS)
   1916   1.1  christos 		  != (relocation >> CALL_SEGMENT_BITS))
   1917   1.1  christos 		{
   1918   1.1  christos 		  *error_message = "windowed longcall crosses 1GB boundary; "
   1919   1.1  christos 		    "return may fail";
   1920   1.1  christos 		  return bfd_reloc_dangerous;
   1921   1.1  christos 		}
   1922   1.1  christos 	    }
   1923   1.6  christos 	}
   1924   1.1  christos       return bfd_reloc_ok;
   1925   1.1  christos 
   1926   1.1  christos     case R_XTENSA_ASM_SIMPLIFY:
   1927   1.1  christos       {
   1928   1.1  christos 	/* Convert the L32R/CALLX to CALL.  */
   1929   1.1  christos 	bfd_reloc_status_type retval =
   1930   1.1  christos 	  elf_xtensa_do_asm_simplify (contents, address, input_size,
   1931   1.1  christos 				      error_message);
   1932   1.1  christos 	if (retval != bfd_reloc_ok)
   1933   1.1  christos 	  return bfd_reloc_dangerous;
   1934   1.1  christos 
   1935   1.1  christos 	/* The CALL needs to be relocated.  Continue below for that part.  */
   1936   1.1  christos 	address += 3;
   1937   1.1  christos 	self_address += 3;
   1938   1.1  christos 	howto = &elf_howto_table[(unsigned) R_XTENSA_SLOT0_OP ];
   1939   1.1  christos       }
   1940   1.1  christos       break;
   1941   1.1  christos 
   1942   1.1  christos     case R_XTENSA_32:
   1943   1.1  christos       {
   1944   1.1  christos 	bfd_vma x;
   1945   1.1  christos 	x = bfd_get_32 (abfd, contents + address);
   1946   1.1  christos 	x = x + relocation;
   1947   1.1  christos 	bfd_put_32 (abfd, x, contents + address);
   1948   1.1  christos       }
   1949   1.1  christos       return bfd_reloc_ok;
   1950   1.1  christos 
   1951   1.1  christos     case R_XTENSA_32_PCREL:
   1952   1.1  christos       bfd_put_32 (abfd, relocation - self_address, contents + address);
   1953   1.1  christos       return bfd_reloc_ok;
   1954   1.1  christos 
   1955   1.1  christos     case R_XTENSA_PLT:
   1956   1.1  christos     case R_XTENSA_TLSDESC_FN:
   1957   1.1  christos     case R_XTENSA_TLSDESC_ARG:
   1958   1.1  christos     case R_XTENSA_TLS_DTPOFF:
   1959   1.1  christos     case R_XTENSA_TLS_TPOFF:
   1960   1.1  christos       bfd_put_32 (abfd, relocation, contents + address);
   1961   1.1  christos       return bfd_reloc_ok;
   1962   1.1  christos     }
   1963   1.1  christos 
   1964   1.1  christos   /* Only instruction slot-specific relocations handled below.... */
   1965   1.1  christos   slot = get_relocation_slot (howto->type);
   1966   1.1  christos   if (slot == XTENSA_UNDEFINED)
   1967   1.8  christos     {
   1968   1.8  christos       *error_message = "unexpected relocation";
   1969   1.1  christos       return bfd_reloc_dangerous;
   1970   1.1  christos     }
   1971   1.1  christos 
   1972   1.1  christos   if (input_size <= address)
   1973   1.1  christos     return bfd_reloc_outofrange;
   1974   1.1  christos   /* Read the instruction into a buffer and decode the opcode.  */
   1975   1.1  christos   xtensa_insnbuf_from_chars (isa, ibuff, contents + address,
   1976   1.1  christos 			     input_size - address);
   1977   1.1  christos   fmt = xtensa_format_decode (isa, ibuff);
   1978   1.1  christos   if (fmt == XTENSA_UNDEFINED)
   1979   1.1  christos     {
   1980   1.1  christos       *error_message = "cannot decode instruction format";
   1981   1.1  christos       return bfd_reloc_dangerous;
   1982   1.1  christos     }
   1983   1.1  christos 
   1984   1.1  christos   xtensa_format_get_slot (isa, fmt, slot, ibuff, sbuff);
   1985   1.1  christos 
   1986   1.1  christos   opcode = xtensa_opcode_decode (isa, fmt, slot, sbuff);
   1987   1.1  christos   if (opcode == XTENSA_UNDEFINED)
   1988   1.1  christos     {
   1989   1.1  christos       *error_message = "cannot decode instruction opcode";
   1990   1.1  christos       return bfd_reloc_dangerous;
   1991   1.1  christos     }
   1992   1.1  christos 
   1993   1.1  christos   /* Check for opcode-specific "alternate" relocations.  */
   1994   1.1  christos   if (is_alt_relocation (howto->type))
   1995   1.1  christos     {
   1996   1.1  christos       if (opcode == get_l32r_opcode ())
   1997   1.1  christos 	{
   1998   1.1  christos 	  /* Handle the special-case of non-PC-relative L32R instructions.  */
   1999   1.1  christos 	  bfd *output_bfd = input_section->output_section->owner;
   2000   1.1  christos 	  asection *lit4_sec = bfd_get_section_by_name (output_bfd, ".lit4");
   2001   1.1  christos 	  if (!lit4_sec)
   2002   1.1  christos 	    {
   2003   1.1  christos 	      *error_message = "relocation references missing .lit4 section";
   2004   1.1  christos 	      return bfd_reloc_dangerous;
   2005   1.1  christos 	    }
   2006   1.1  christos 	  self_address = ((lit4_sec->vma & ~0xfff)
   2007   1.1  christos 			  + 0x40000 - 3); /* -3 to compensate for do_reloc */
   2008   1.7  christos 	  newval = relocation;
   2009   1.7  christos 	  opnd = 1;
   2010   1.7  christos 	}
   2011   1.1  christos       else if (opcode == get_const16_opcode ())
   2012   1.1  christos 	{
   2013   1.1  christos 	  /* ALT used for high 16 bits.
   2014   1.1  christos 	     Ignore 32-bit overflow.  */
   2015   1.1  christos 	  newval = (relocation >> 16) & 0xffff;
   2016   1.1  christos 	  opnd = 1;
   2017   1.1  christos 	}
   2018   1.1  christos       else
   2019   1.1  christos 	{
   2020   1.1  christos 	  /* No other "alternate" relocations currently defined.  */
   2021   1.1  christos 	  *error_message = "unexpected relocation";
   2022   1.1  christos 	  return bfd_reloc_dangerous;
   2023   1.1  christos 	}
   2024   1.1  christos     }
   2025   1.1  christos   else /* Not an "alternate" relocation.... */
   2026   1.1  christos     {
   2027   1.1  christos       if (opcode == get_const16_opcode ())
   2028   1.1  christos 	{
   2029   1.1  christos 	  newval = relocation & 0xffff;
   2030   1.1  christos 	  opnd = 1;
   2031   1.1  christos 	}
   2032   1.1  christos       else
   2033   1.1  christos 	{
   2034   1.1  christos 	  /* ...normal PC-relative relocation.... */
   2035   1.1  christos 
   2036   1.1  christos 	  /* Determine which operand is being relocated.  */
   2037   1.1  christos 	  opnd = get_relocation_opnd (opcode, howto->type);
   2038   1.1  christos 	  if (opnd == XTENSA_UNDEFINED)
   2039   1.1  christos 	    {
   2040   1.1  christos 	      *error_message = "unexpected relocation";
   2041   1.1  christos 	      return bfd_reloc_dangerous;
   2042   1.1  christos 	    }
   2043   1.1  christos 
   2044   1.1  christos 	  if (!howto->pc_relative)
   2045   1.1  christos 	    {
   2046   1.1  christos 	      *error_message = "expected PC-relative relocation";
   2047   1.1  christos 	      return bfd_reloc_dangerous;
   2048   1.1  christos 	    }
   2049   1.1  christos 
   2050   1.1  christos 	  newval = relocation;
   2051   1.1  christos 	}
   2052   1.1  christos     }
   2053   1.1  christos 
   2054   1.1  christos   /* Apply the relocation.  */
   2055   1.1  christos   if (xtensa_operand_do_reloc (isa, opcode, opnd, &newval, self_address)
   2056   1.1  christos       || xtensa_operand_encode (isa, opcode, opnd, &newval)
   2057   1.1  christos       || xtensa_operand_set_field (isa, opcode, opnd, fmt, slot,
   2058   1.1  christos 				   sbuff, newval))
   2059   1.1  christos     {
   2060   1.1  christos       const char *opname = xtensa_opcode_name (isa, opcode);
   2061   1.1  christos       const char *msg;
   2062   1.1  christos 
   2063   1.1  christos       msg = "cannot encode";
   2064   1.1  christos       if (is_direct_call_opcode (opcode))
   2065   1.1  christos 	{
   2066   1.1  christos 	  if ((relocation & 0x3) != 0)
   2067   1.1  christos 	    msg = "misaligned call target";
   2068   1.1  christos 	  else
   2069   1.1  christos 	    msg = "call target out of range";
   2070   1.1  christos 	}
   2071   1.1  christos       else if (opcode == get_l32r_opcode ())
   2072   1.1  christos 	{
   2073   1.1  christos 	  if ((relocation & 0x3) != 0)
   2074   1.1  christos 	    msg = "misaligned literal target";
   2075   1.1  christos 	  else if (is_alt_relocation (howto->type))
   2076   1.1  christos 	    msg = "literal target out of range (too many literals)";
   2077   1.1  christos 	  else if (self_address > relocation)
   2078   1.1  christos 	    msg = "literal target out of range (try using text-section-literals)";
   2079   1.1  christos 	  else
   2080   1.1  christos 	    msg = "literal placed after use";
   2081   1.1  christos 	}
   2082   1.1  christos 
   2083   1.1  christos       *error_message = vsprint_msg (opname, ": %s", strlen (msg) + 2, msg);
   2084   1.1  christos       return bfd_reloc_dangerous;
   2085   1.1  christos     }
   2086   1.1  christos 
   2087   1.3  christos   /* Check for calls across 1GB boundaries.  */
   2088   1.1  christos   if (is_direct_call_opcode (opcode)
   2089   1.1  christos       && is_windowed_call_opcode (opcode))
   2090   1.1  christos     {
   2091   1.1  christos       if ((self_address >> CALL_SEGMENT_BITS)
   2092   1.1  christos 	  != (relocation >> CALL_SEGMENT_BITS))
   2093   1.1  christos 	{
   2094   1.1  christos 	  *error_message =
   2095   1.1  christos 	    "windowed call crosses 1GB boundary; return may fail";
   2096   1.1  christos 	  return bfd_reloc_dangerous;
   2097   1.1  christos 	}
   2098   1.1  christos     }
   2099   1.1  christos 
   2100   1.1  christos   /* Write the modified instruction back out of the buffer.  */
   2101   1.1  christos   xtensa_format_set_slot (isa, fmt, slot, ibuff, sbuff);
   2102   1.1  christos   xtensa_insnbuf_to_chars (isa, ibuff, contents + address,
   2103   1.1  christos 			   input_size - address);
   2104   1.1  christos   return bfd_reloc_ok;
   2105   1.1  christos }
   2106   1.1  christos 
   2107   1.1  christos 
   2108   1.1  christos static char *
   2109   1.1  christos vsprint_msg (const char *origmsg, const char *fmt, int arglen, ...)
   2110   1.1  christos {
   2111   1.8  christos   /* To reduce the size of the memory leak,
   2112   1.3  christos      we only use a single message buffer.  */
   2113   1.3  christos   static bfd_size_type alloc_size = 0;
   2114   1.3  christos   static char *message = NULL;
   2115   1.1  christos   bfd_size_type orig_len, len = 0;
   2116   1.3  christos   bool is_append;
   2117   1.1  christos   va_list ap;
   2118   1.1  christos 
   2119   1.1  christos   va_start (ap, arglen);
   2120   1.1  christos 
   2121   1.1  christos   is_append = (origmsg == message);
   2122   1.1  christos 
   2123   1.1  christos   orig_len = strlen (origmsg);
   2124   1.1  christos   len = orig_len + strlen (fmt) + arglen + 20;
   2125   1.1  christos   if (len > alloc_size)
   2126   1.1  christos     {
   2127   1.1  christos       message = (char *) bfd_realloc_or_free (message, len);
   2128   1.1  christos       alloc_size = len;
   2129   1.1  christos     }
   2130   1.1  christos   if (message != NULL)
   2131   1.3  christos     {
   2132   1.1  christos       if (!is_append)
   2133   1.1  christos 	memcpy (message, origmsg, orig_len);
   2134   1.1  christos       vsprintf (message + orig_len, fmt, ap);
   2135   1.1  christos     }
   2136   1.1  christos   va_end (ap);
   2137   1.1  christos   return message;
   2138   1.1  christos }
   2139   1.1  christos 
   2140   1.1  christos 
   2141   1.1  christos /* This function is registered as the "special_function" in the
   2142   1.1  christos    Xtensa howto for handling simplify operations.
   2143   1.1  christos    bfd_perform_relocation / bfd_install_relocation use it to
   2144   1.1  christos    perform (install) the specified relocation.  Since this replaces the code
   2145   1.1  christos    in bfd_perform_relocation, it is basically an Xtensa-specific,
   2146   1.1  christos    stripped-down version of bfd_perform_relocation.  */
   2147   1.1  christos 
   2148   1.1  christos static bfd_reloc_status_type
   2149   1.1  christos bfd_elf_xtensa_reloc (bfd *abfd,
   2150   1.1  christos 		      arelent *reloc_entry,
   2151   1.1  christos 		      asymbol *symbol,
   2152   1.1  christos 		      void *data,
   2153   1.1  christos 		      asection *input_section,
   2154   1.7  christos 		      bfd *output_bfd,
   2155   1.7  christos 		      char **error_message)
   2156   1.1  christos {
   2157   1.1  christos   bfd_vma relocation;
   2158   1.1  christos   bfd_reloc_status_type flag;
   2159   1.8  christos   bfd_size_type octets = (reloc_entry->address
   2160   1.1  christos 			  * OCTETS_PER_BYTE (abfd, input_section));
   2161   1.1  christos   bfd_vma output_base = 0;
   2162   1.1  christos   reloc_howto_type *howto = reloc_entry->howto;
   2163   1.1  christos   asection *reloc_target_output_section;
   2164   1.1  christos   bool is_weak_undef;
   2165   1.1  christos 
   2166   1.1  christos   if (!xtensa_default_isa)
   2167   1.1  christos     xtensa_default_isa = xtensa_isa_init (0, 0);
   2168   1.1  christos 
   2169   1.1  christos   /* ELF relocs are against symbols.  If we are producing relocatable
   2170   1.1  christos      output, and the reloc is against an external symbol, the resulting
   2171   1.1  christos      reloc will also be against the same symbol.  In such a case, we
   2172   1.1  christos      don't want to change anything about the way the reloc is handled,
   2173   1.1  christos      since it will all be done at final link time.  This test is similar
   2174   1.1  christos      to what bfd_elf_generic_reloc does except that it lets relocs with
   2175   1.1  christos      howto->partial_inplace go through even if the addend is non-zero.
   2176   1.1  christos      (The real problem is that partial_inplace is set for XTENSA_32
   2177   1.1  christos      relocs to begin with, but that's a long story and there's little we
   2178   1.1  christos      can do about it now....)  */
   2179   1.1  christos 
   2180   1.1  christos   if (output_bfd && (symbol->flags & BSF_SECTION_SYM) == 0)
   2181   1.1  christos     {
   2182   1.1  christos       reloc_entry->address += input_section->output_offset;
   2183   1.1  christos       return bfd_reloc_ok;
   2184   1.1  christos     }
   2185   1.1  christos 
   2186   1.1  christos   /* Is the address of the relocation really within the section?  */
   2187   1.1  christos   if (reloc_entry->address > bfd_get_section_limit (abfd, input_section))
   2188   1.1  christos     return bfd_reloc_outofrange;
   2189   1.1  christos 
   2190   1.1  christos   /* Work out which section the relocation is targeted at and the
   2191   1.1  christos      initial relocation command value.  */
   2192   1.1  christos 
   2193   1.1  christos   /* Get symbol value.  (Common symbols are special.)  */
   2194   1.1  christos   if (bfd_is_com_section (symbol->section))
   2195   1.1  christos     relocation = 0;
   2196   1.1  christos   else
   2197   1.1  christos     relocation = symbol->value;
   2198   1.1  christos 
   2199   1.1  christos   reloc_target_output_section = symbol->section->output_section;
   2200   1.1  christos 
   2201   1.1  christos   /* Convert input-section-relative symbol value to absolute.  */
   2202   1.1  christos   if ((output_bfd && !howto->partial_inplace)
   2203   1.1  christos       || reloc_target_output_section == NULL)
   2204   1.1  christos     output_base = 0;
   2205   1.1  christos   else
   2206   1.1  christos     output_base = reloc_target_output_section->vma;
   2207   1.1  christos 
   2208   1.1  christos   relocation += output_base + symbol->section->output_offset;
   2209   1.1  christos 
   2210   1.1  christos   /* Add in supplied addend.  */
   2211   1.1  christos   relocation += reloc_entry->addend;
   2212   1.1  christos 
   2213   1.1  christos   /* Here the variable relocation holds the final address of the
   2214   1.1  christos      symbol we are relocating against, plus any addend.  */
   2215   1.1  christos   if (output_bfd)
   2216   1.1  christos     {
   2217   1.1  christos       if (!howto->partial_inplace)
   2218   1.1  christos 	{
   2219   1.1  christos 	  /* This is a partial relocation, and we want to apply the relocation
   2220   1.1  christos 	     to the reloc entry rather than the raw data.  Everything except
   2221   1.1  christos 	     relocations against section symbols has already been handled
   2222   1.1  christos 	     above.  */
   2223   1.1  christos 
   2224   1.1  christos 	  BFD_ASSERT (symbol->flags & BSF_SECTION_SYM);
   2225   1.1  christos 	  reloc_entry->addend = relocation;
   2226   1.1  christos 	  reloc_entry->address += input_section->output_offset;
   2227   1.1  christos 	  return bfd_reloc_ok;
   2228   1.1  christos 	}
   2229   1.1  christos       else
   2230   1.1  christos 	{
   2231   1.1  christos 	  reloc_entry->address += input_section->output_offset;
   2232   1.1  christos 	  reloc_entry->addend = 0;
   2233   1.1  christos 	}
   2234   1.1  christos     }
   2235   1.1  christos 
   2236   1.1  christos   is_weak_undef = (bfd_is_und_section (symbol->section)
   2237   1.1  christos 		   && (symbol->flags & BSF_WEAK) != 0);
   2238   1.1  christos   flag = elf_xtensa_do_reloc (howto, abfd, input_section, relocation,
   2239   1.1  christos 			      (bfd_byte *) data, (bfd_vma) octets,
   2240   1.1  christos 			      is_weak_undef, error_message);
   2241   1.1  christos 
   2242   1.1  christos   if (flag == bfd_reloc_dangerous)
   2243   1.1  christos     {
   2244   1.1  christos       /* Add the symbol name to the error message.  */
   2245   1.1  christos       if (! *error_message)
   2246   1.1  christos 	*error_message = "";
   2247   1.1  christos       *error_message = vsprint_msg (*error_message, ": (%s + 0x%lx)",
   2248   1.1  christos 				    strlen (symbol->name) + 17,
   2249   1.1  christos 				    symbol->name,
   2250   1.1  christos 				    (unsigned long) reloc_entry->addend);
   2251   1.8  christos     }
   2252   1.8  christos 
   2253   1.8  christos   return flag;
   2254   1.8  christos }
   2255   1.8  christos 
   2256   1.8  christos int xtensa_abi_choice (void)
   2257   1.8  christos {
   2258   1.1  christos   if (elf32xtensa_abi == XTHAL_ABI_UNDEFINED)
   2259   1.1  christos     return XSHAL_ABI;
   2260   1.1  christos   else
   2261   1.1  christos     return elf32xtensa_abi;
   2262   1.1  christos }
   2263   1.1  christos 
   2264   1.1  christos /* Set up an entry in the procedure linkage table.  */
   2265   1.1  christos 
   2266   1.1  christos static bfd_vma
   2267   1.1  christos elf_xtensa_create_plt_entry (struct bfd_link_info *info,
   2268   1.3  christos 			     bfd *output_bfd,
   2269   1.1  christos 			     unsigned reloc_index)
   2270   1.8  christos {
   2271   1.1  christos   asection *splt, *sgotplt;
   2272   1.1  christos   bfd_vma plt_base, got_base;
   2273   1.1  christos   bfd_vma code_offset, lit_offset, abi_offset;
   2274   1.1  christos   int chunk;
   2275   1.1  christos   int abi = xtensa_abi_choice ();
   2276   1.1  christos 
   2277   1.1  christos   chunk = reloc_index / PLT_ENTRIES_PER_CHUNK;
   2278   1.1  christos   splt = elf_xtensa_get_plt_section (info, chunk);
   2279   1.1  christos   sgotplt = elf_xtensa_get_gotplt_section (info, chunk);
   2280   1.1  christos   BFD_ASSERT (splt != NULL && sgotplt != NULL);
   2281   1.1  christos 
   2282   1.1  christos   plt_base = splt->output_section->vma + splt->output_offset;
   2283   1.1  christos   got_base = sgotplt->output_section->vma + sgotplt->output_offset;
   2284   1.1  christos 
   2285   1.1  christos   lit_offset = 8 + (reloc_index % PLT_ENTRIES_PER_CHUNK) * 4;
   2286   1.1  christos   code_offset = (reloc_index % PLT_ENTRIES_PER_CHUNK) * PLT_ENTRY_SIZE;
   2287   1.1  christos 
   2288   1.1  christos   /* Fill in the literal entry.  This is the offset of the dynamic
   2289   1.1  christos      relocation entry.  */
   2290   1.1  christos   bfd_put_32 (output_bfd, reloc_index * sizeof (Elf32_External_Rela),
   2291   1.8  christos 	      sgotplt->contents + lit_offset);
   2292   1.8  christos 
   2293   1.1  christos   /* Fill in the entry in the procedure linkage table.  */
   2294   1.8  christos   memcpy (splt->contents + code_offset,
   2295   1.1  christos 	  (bfd_big_endian (output_bfd)
   2296   1.3  christos 	   ? elf_xtensa_be_plt_entry[abi != XTHAL_ABI_WINDOWED]
   2297   1.3  christos 	   : elf_xtensa_le_plt_entry[abi != XTHAL_ABI_WINDOWED]),
   2298   1.1  christos 	  PLT_ENTRY_SIZE);
   2299   1.3  christos   abi_offset = abi == XTHAL_ABI_WINDOWED ? 3 : 0;
   2300   1.3  christos   bfd_put_16 (output_bfd, l32r_offset (got_base + 0,
   2301   1.1  christos 				       plt_base + code_offset + abi_offset),
   2302   1.3  christos 	      splt->contents + code_offset + abi_offset + 1);
   2303   1.3  christos   bfd_put_16 (output_bfd, l32r_offset (got_base + 4,
   2304   1.1  christos 				       plt_base + code_offset + abi_offset + 3),
   2305   1.1  christos 	      splt->contents + code_offset + abi_offset + 4);
   2306   1.1  christos   bfd_put_16 (output_bfd, l32r_offset (got_base + lit_offset,
   2307   1.1  christos 				       plt_base + code_offset + abi_offset + 6),
   2308   1.1  christos 	      splt->contents + code_offset + abi_offset + 7);
   2309   1.8  christos 
   2310   1.1  christos   return plt_base + code_offset;
   2311   1.8  christos }
   2312   1.1  christos 
   2313   1.1  christos 
   2314   1.1  christos static bool get_indirect_call_dest_reg (xtensa_opcode, unsigned *);
   2315   1.1  christos 
   2316   1.8  christos static bool
   2317   1.1  christos replace_tls_insn (Elf_Internal_Rela *rel,
   2318   1.1  christos 		  bfd *abfd,
   2319   1.1  christos 		  asection *input_section,
   2320   1.1  christos 		  bfd_byte *contents,
   2321   1.1  christos 		  bool is_ld_model,
   2322   1.1  christos 		  char **error_message)
   2323   1.1  christos {
   2324   1.1  christos   static xtensa_insnbuf ibuff = NULL;
   2325   1.1  christos   static xtensa_insnbuf sbuff = NULL;
   2326   1.1  christos   xtensa_isa isa = xtensa_default_isa;
   2327   1.1  christos   xtensa_format fmt;
   2328   1.1  christos   xtensa_opcode old_op, new_op;
   2329   1.1  christos   bfd_size_type input_size;
   2330   1.1  christos   int r_type;
   2331   1.1  christos   unsigned dest_reg, src_reg;
   2332   1.1  christos 
   2333   1.1  christos   if (ibuff == NULL)
   2334   1.1  christos     {
   2335   1.1  christos       ibuff = xtensa_insnbuf_alloc (isa);
   2336   1.1  christos       sbuff = xtensa_insnbuf_alloc (isa);
   2337   1.1  christos     }
   2338   1.1  christos 
   2339   1.1  christos   input_size = bfd_get_section_limit (abfd, input_section);
   2340   1.1  christos 
   2341   1.1  christos   /* Read the instruction into a buffer and decode the opcode.  */
   2342   1.1  christos   xtensa_insnbuf_from_chars (isa, ibuff, contents + rel->r_offset,
   2343   1.8  christos 			     input_size - rel->r_offset);
   2344   1.1  christos   fmt = xtensa_format_decode (isa, ibuff);
   2345   1.1  christos   if (fmt == XTENSA_UNDEFINED)
   2346   1.1  christos     {
   2347   1.1  christos       *error_message = "cannot decode instruction format";
   2348   1.1  christos       return false;
   2349   1.1  christos     }
   2350   1.1  christos 
   2351   1.1  christos   BFD_ASSERT (xtensa_format_num_slots (isa, fmt) == 1);
   2352   1.1  christos   xtensa_format_get_slot (isa, fmt, 0, ibuff, sbuff);
   2353   1.8  christos 
   2354   1.1  christos   old_op = xtensa_opcode_decode (isa, fmt, 0, sbuff);
   2355   1.1  christos   if (old_op == XTENSA_UNDEFINED)
   2356   1.1  christos     {
   2357   1.1  christos       *error_message = "cannot decode instruction opcode";
   2358   1.1  christos       return false;
   2359   1.1  christos     }
   2360   1.1  christos 
   2361   1.1  christos   r_type = ELF32_R_TYPE (rel->r_info);
   2362   1.1  christos   switch (r_type)
   2363   1.1  christos     {
   2364   1.1  christos     case R_XTENSA_TLS_FUNC:
   2365   1.1  christos     case R_XTENSA_TLS_ARG:
   2366   1.8  christos       if (old_op != get_l32r_opcode ()
   2367   1.1  christos 	  || xtensa_operand_get_field (isa, old_op, 0, fmt, 0,
   2368   1.1  christos 				       sbuff, &dest_reg) != 0)
   2369   1.1  christos 	{
   2370   1.1  christos 	  *error_message = "cannot extract L32R destination for TLS access";
   2371   1.1  christos 	  return false;
   2372   1.1  christos 	}
   2373   1.1  christos       break;
   2374   1.1  christos 
   2375   1.1  christos     case R_XTENSA_TLS_CALL:
   2376   1.8  christos       if (! get_indirect_call_dest_reg (old_op, &dest_reg)
   2377   1.1  christos 	  || xtensa_operand_get_field (isa, old_op, 0, fmt, 0,
   2378   1.1  christos 				       sbuff, &src_reg) != 0)
   2379   1.1  christos 	{
   2380   1.1  christos 	  *error_message = "cannot extract CALLXn operands for TLS access";
   2381   1.1  christos 	  return false;
   2382   1.1  christos 	}
   2383   1.1  christos       break;
   2384   1.1  christos 
   2385   1.1  christos     default:
   2386   1.1  christos       abort ();
   2387   1.1  christos     }
   2388   1.1  christos 
   2389   1.1  christos   if (is_ld_model)
   2390   1.1  christos     {
   2391   1.1  christos       switch (r_type)
   2392   1.1  christos 	{
   2393   1.1  christos 	case R_XTENSA_TLS_FUNC:
   2394   1.1  christos 	case R_XTENSA_TLS_ARG:
   2395   1.1  christos 	  /* Change the instruction to a NOP (or "OR a1, a1, a1" for older
   2396   1.1  christos 	     versions of Xtensa).  */
   2397   1.1  christos 	  new_op = xtensa_opcode_lookup (isa, "nop");
   2398   1.1  christos 	  if (new_op == XTENSA_UNDEFINED)
   2399   1.1  christos 	    {
   2400   1.1  christos 	      new_op = xtensa_opcode_lookup (isa, "or");
   2401   1.1  christos 	      if (new_op == XTENSA_UNDEFINED
   2402   1.1  christos 		  || xtensa_opcode_encode (isa, fmt, 0, sbuff, new_op) != 0
   2403   1.1  christos 		  || xtensa_operand_set_field (isa, new_op, 0, fmt, 0,
   2404   1.1  christos 					       sbuff, 1) != 0
   2405   1.1  christos 		  || xtensa_operand_set_field (isa, new_op, 1, fmt, 0,
   2406   1.8  christos 					       sbuff, 1) != 0
   2407   1.1  christos 		  || xtensa_operand_set_field (isa, new_op, 2, fmt, 0,
   2408   1.1  christos 					       sbuff, 1) != 0)
   2409   1.1  christos 		{
   2410   1.1  christos 		  *error_message = "cannot encode OR for TLS access";
   2411   1.1  christos 		  return false;
   2412   1.1  christos 		}
   2413   1.1  christos 	    }
   2414   1.8  christos 	  else
   2415   1.1  christos 	    {
   2416   1.1  christos 	      if (xtensa_opcode_encode (isa, fmt, 0, sbuff, new_op) != 0)
   2417   1.1  christos 		{
   2418   1.1  christos 		  *error_message = "cannot encode NOP for TLS access";
   2419   1.1  christos 		  return false;
   2420   1.1  christos 		}
   2421   1.1  christos 	    }
   2422   1.1  christos 	  break;
   2423   1.1  christos 
   2424   1.1  christos 	case R_XTENSA_TLS_CALL:
   2425   1.1  christos 	  /* Read THREADPTR into the CALLX's return value register.  */
   2426   1.1  christos 	  new_op = xtensa_opcode_lookup (isa, "rur.threadptr");
   2427   1.1  christos 	  if (new_op == XTENSA_UNDEFINED
   2428   1.8  christos 	      || xtensa_opcode_encode (isa, fmt, 0, sbuff, new_op) != 0
   2429   1.1  christos 	      || xtensa_operand_set_field (isa, new_op, 0, fmt, 0,
   2430   1.1  christos 					   sbuff, dest_reg + 2) != 0)
   2431   1.1  christos 	    {
   2432   1.1  christos 	      *error_message = "cannot encode RUR.THREADPTR for TLS access";
   2433   1.1  christos 	      return false;
   2434   1.1  christos 	    }
   2435   1.1  christos 	  break;
   2436   1.1  christos 	}
   2437   1.1  christos     }
   2438   1.1  christos   else
   2439   1.1  christos     {
   2440   1.1  christos       switch (r_type)
   2441   1.1  christos 	{
   2442   1.1  christos 	case R_XTENSA_TLS_FUNC:
   2443   1.1  christos 	  new_op = xtensa_opcode_lookup (isa, "rur.threadptr");
   2444   1.1  christos 	  if (new_op == XTENSA_UNDEFINED
   2445   1.8  christos 	      || xtensa_opcode_encode (isa, fmt, 0, sbuff, new_op) != 0
   2446   1.1  christos 	      || xtensa_operand_set_field (isa, new_op, 0, fmt, 0,
   2447   1.1  christos 					   sbuff, dest_reg) != 0)
   2448   1.1  christos 	    {
   2449   1.1  christos 	      *error_message = "cannot encode RUR.THREADPTR for TLS access";
   2450   1.1  christos 	      return false;
   2451   1.8  christos 	    }
   2452   1.1  christos 	  break;
   2453   1.1  christos 
   2454   1.1  christos 	case R_XTENSA_TLS_ARG:
   2455   1.1  christos 	  /* Nothing to do.  Keep the original L32R instruction.  */
   2456   1.1  christos 	  return true;
   2457   1.1  christos 
   2458   1.1  christos 	case R_XTENSA_TLS_CALL:
   2459   1.1  christos 	  /* Add the CALLX's src register (holding the THREADPTR value)
   2460   1.1  christos 	     to the first argument register (holding the offset) and put
   2461   1.1  christos 	     the result in the CALLX's return value register.  */
   2462   1.1  christos 	  new_op = xtensa_opcode_lookup (isa, "add");
   2463   1.1  christos 	  if (new_op == XTENSA_UNDEFINED
   2464   1.1  christos 	      || xtensa_opcode_encode (isa, fmt, 0, sbuff, new_op) != 0
   2465   1.1  christos 	      || xtensa_operand_set_field (isa, new_op, 0, fmt, 0,
   2466   1.1  christos 					   sbuff, dest_reg + 2) != 0
   2467   1.1  christos 	      || xtensa_operand_set_field (isa, new_op, 1, fmt, 0,
   2468   1.8  christos 					   sbuff, dest_reg + 2) != 0
   2469   1.1  christos 	      || xtensa_operand_set_field (isa, new_op, 2, fmt, 0,
   2470   1.1  christos 					   sbuff, src_reg) != 0)
   2471   1.1  christos 	    {
   2472   1.1  christos 	      *error_message = "cannot encode ADD for TLS access";
   2473   1.1  christos 	      return false;
   2474   1.1  christos 	    }
   2475   1.1  christos 	  break;
   2476   1.6  christos 	}
   2477   1.1  christos     }
   2478   1.8  christos 
   2479   1.1  christos   xtensa_format_set_slot (isa, fmt, 0, ibuff, sbuff);
   2480   1.1  christos   xtensa_insnbuf_to_chars (isa, ibuff, contents + rel->r_offset,
   2481   1.1  christos 			   input_size - rel->r_offset);
   2482   1.1  christos 
   2483   1.1  christos   return true;
   2484   1.1  christos }
   2485   1.1  christos 
   2486   1.1  christos 
   2487   1.1  christos #define IS_XTENSA_TLS_RELOC(R_TYPE) \
   2488   1.1  christos   ((R_TYPE) == R_XTENSA_TLSDESC_FN \
   2489   1.1  christos    || (R_TYPE) == R_XTENSA_TLSDESC_ARG \
   2490   1.1  christos    || (R_TYPE) == R_XTENSA_TLS_DTPOFF \
   2491   1.1  christos    || (R_TYPE) == R_XTENSA_TLS_TPOFF \
   2492   1.1  christos    || (R_TYPE) == R_XTENSA_TLS_FUNC \
   2493   1.1  christos    || (R_TYPE) == R_XTENSA_TLS_ARG \
   2494   1.8  christos    || (R_TYPE) == R_XTENSA_TLS_CALL)
   2495   1.1  christos 
   2496   1.1  christos /* Relocate an Xtensa ELF section.  This is invoked by the linker for
   2497   1.1  christos    both relocatable and final links.  */
   2498   1.1  christos 
   2499   1.1  christos static int
   2500   1.1  christos elf_xtensa_relocate_section (bfd *output_bfd,
   2501   1.1  christos 			     struct bfd_link_info *info,
   2502   1.1  christos 			     bfd *input_bfd,
   2503   1.1  christos 			     asection *input_section,
   2504   1.1  christos 			     bfd_byte *contents,
   2505   1.1  christos 			     Elf_Internal_Rela *relocs,
   2506   1.1  christos 			     Elf_Internal_Sym *local_syms,
   2507   1.1  christos 			     asection **local_sections)
   2508   1.1  christos {
   2509   1.1  christos   struct elf_xtensa_link_hash_table *htab;
   2510   1.1  christos   Elf_Internal_Shdr *symtab_hdr;
   2511   1.1  christos   Elf_Internal_Rela *rel;
   2512   1.1  christos   Elf_Internal_Rela *relend;
   2513   1.1  christos   struct elf_link_hash_entry **sym_hashes;
   2514   1.1  christos   property_table_entry *lit_table = 0;
   2515   1.1  christos   int ltblsize = 0;
   2516   1.1  christos   char *local_got_tls_types;
   2517   1.1  christos   char *error_message = NULL;
   2518   1.1  christos   bfd_size_type input_size;
   2519   1.7  christos   int tls_type;
   2520   1.7  christos 
   2521   1.7  christos   if (!xtensa_default_isa)
   2522   1.8  christos     xtensa_default_isa = xtensa_isa_init (0, 0);
   2523   1.7  christos 
   2524   1.1  christos   if (!is_xtensa_elf (input_bfd))
   2525   1.1  christos     {
   2526   1.1  christos       bfd_set_error (bfd_error_wrong_format);
   2527   1.8  christos       return false;
   2528   1.1  christos     }
   2529   1.1  christos 
   2530   1.1  christos   htab = elf_xtensa_hash_table (info);
   2531   1.1  christos   if (htab == NULL)
   2532   1.1  christos     return false;
   2533   1.1  christos 
   2534   1.1  christos   symtab_hdr = &elf_tdata (input_bfd)->symtab_hdr;
   2535   1.1  christos   sym_hashes = elf_sym_hashes (input_bfd);
   2536   1.1  christos   local_got_tls_types = elf_xtensa_local_got_tls_type (input_bfd);
   2537   1.8  christos 
   2538   1.1  christos   if (elf_hash_table (info)->dynamic_sections_created)
   2539   1.8  christos     {
   2540   1.1  christos       ltblsize = xtensa_read_table_entries (input_bfd, input_section,
   2541   1.1  christos 					    &lit_table, XTENSA_LIT_SEC_NAME,
   2542   1.1  christos 					    true);
   2543   1.1  christos       if (ltblsize < 0)
   2544   1.1  christos 	return false;
   2545   1.1  christos     }
   2546   1.1  christos 
   2547   1.1  christos   input_size = bfd_get_section_limit (input_bfd, input_section);
   2548   1.1  christos 
   2549   1.1  christos   rel = relocs;
   2550   1.1  christos   relend = relocs + input_section->reloc_count;
   2551   1.1  christos   for (; rel < relend; rel++)
   2552   1.1  christos     {
   2553   1.1  christos       int r_type;
   2554   1.1  christos       reloc_howto_type *howto;
   2555   1.1  christos       unsigned long r_symndx;
   2556   1.1  christos       struct elf_link_hash_entry *h;
   2557   1.1  christos       Elf_Internal_Sym *sym;
   2558   1.8  christos       char sym_type;
   2559   1.8  christos       const char *name;
   2560   1.8  christos       asection *sec;
   2561   1.8  christos       bfd_vma relocation;
   2562   1.1  christos       bfd_reloc_status_type r;
   2563   1.1  christos       bool is_weak_undef;
   2564   1.1  christos       bool unresolved_reloc;
   2565   1.1  christos       bool warned;
   2566   1.1  christos       bool dynamic_symbol;
   2567   1.1  christos 
   2568   1.1  christos       r_type = ELF32_R_TYPE (rel->r_info);
   2569   1.1  christos       if (r_type == (int) R_XTENSA_GNU_VTINHERIT
   2570   1.1  christos 	  || r_type == (int) R_XTENSA_GNU_VTENTRY)
   2571   1.8  christos 	continue;
   2572   1.1  christos 
   2573   1.1  christos       if (r_type < 0 || r_type >= (int) R_XTENSA_max)
   2574   1.1  christos 	{
   2575   1.1  christos 	  bfd_set_error (bfd_error_bad_value);
   2576   1.1  christos 	  return false;
   2577   1.1  christos 	}
   2578   1.1  christos       howto = &elf_howto_table[r_type];
   2579   1.1  christos 
   2580   1.8  christos       r_symndx = ELF32_R_SYM (rel->r_info);
   2581   1.8  christos 
   2582   1.8  christos       h = NULL;
   2583   1.1  christos       sym = NULL;
   2584   1.3  christos       sec = NULL;
   2585   1.1  christos       is_weak_undef = false;
   2586   1.1  christos       unresolved_reloc = false;
   2587   1.1  christos       warned = false;
   2588   1.1  christos 
   2589   1.1  christos       if (howto->partial_inplace && !bfd_link_relocatable (info))
   2590   1.1  christos 	{
   2591   1.1  christos 	  /* Because R_XTENSA_32 was made partial_inplace to fix some
   2592   1.1  christos 	     problems with DWARF info in partial links, there may be
   2593   1.1  christos 	     an addend stored in the contents.  Take it out of there
   2594   1.1  christos 	     and move it back into the addend field of the reloc.  */
   2595   1.1  christos 	  rel->r_addend += bfd_get_32 (input_bfd, contents + rel->r_offset);
   2596   1.1  christos 	  bfd_put_32 (input_bfd, 0, contents + rel->r_offset);
   2597   1.1  christos 	}
   2598   1.1  christos 
   2599   1.1  christos       if (r_symndx < symtab_hdr->sh_info)
   2600   1.1  christos 	{
   2601   1.1  christos 	  sym = local_syms + r_symndx;
   2602   1.1  christos 	  sym_type = ELF32_ST_TYPE (sym->st_info);
   2603   1.8  christos 	  sec = local_sections[r_symndx];
   2604   1.3  christos 	  relocation = _bfd_elf_rela_local_sym (output_bfd, sym, &sec, rel);
   2605   1.1  christos 	}
   2606   1.1  christos       else
   2607   1.1  christos 	{
   2608   1.3  christos 	  bool ignored;
   2609   1.1  christos 
   2610   1.1  christos 	  RELOC_FOR_GLOBAL_SYMBOL (info, input_bfd, input_section, rel,
   2611   1.1  christos 				   r_symndx, symtab_hdr, sym_hashes,
   2612   1.1  christos 				   h, sec, relocation,
   2613   1.8  christos 				   unresolved_reloc, warned, ignored);
   2614   1.1  christos 
   2615   1.1  christos 	  if (relocation == 0
   2616   1.1  christos 	      && !unresolved_reloc
   2617   1.1  christos 	      && h->root.type == bfd_link_hash_undefweak)
   2618   1.1  christos 	    is_weak_undef = true;
   2619   1.1  christos 
   2620   1.1  christos 	  sym_type = h->type;
   2621   1.1  christos 	}
   2622   1.3  christos 
   2623   1.1  christos       if (sec != NULL && discarded_section (sec))
   2624   1.1  christos 	RELOC_AGAINST_DISCARDED_SECTION (info, input_bfd, input_section,
   2625   1.1  christos 					 rel, 1, relend, howto, 0, contents);
   2626   1.1  christos 
   2627   1.1  christos       if (bfd_link_relocatable (info))
   2628   1.1  christos 	{
   2629   1.1  christos 	  bfd_vma dest_addr;
   2630   1.1  christos 	  asection * sym_sec = get_elf_r_symndx_section (input_bfd, r_symndx);
   2631   1.1  christos 
   2632   1.1  christos 	  /* This is a relocatable link.
   2633   1.1  christos 	     1) If the reloc is against a section symbol, adjust
   2634   1.1  christos 	     according to the output section.
   2635   1.1  christos 	     2) If there is a new target for this relocation,
   2636   1.1  christos 	     the new target will be in the same output section.
   2637   1.1  christos 	     We adjust the relocation by the output section
   2638   1.1  christos 	     difference.  */
   2639   1.1  christos 
   2640   1.8  christos 	  if (relaxing_section)
   2641   1.1  christos 	    {
   2642   1.1  christos 	      /* Check if this references a section in another input file.  */
   2643   1.1  christos 	      if (!do_fix_for_relocatable_link (rel, input_bfd, input_section,
   2644   1.1  christos 						contents))
   2645   1.1  christos 		return false;
   2646   1.1  christos 	    }
   2647   1.1  christos 
   2648   1.1  christos 	  dest_addr = sym_sec->output_section->vma + sym_sec->output_offset
   2649   1.1  christos 	    + get_elf_r_symndx_offset (input_bfd, r_symndx) + rel->r_addend;
   2650   1.1  christos 
   2651   1.1  christos 	  if (r_type == R_XTENSA_ASM_SIMPLIFY)
   2652   1.1  christos 	    {
   2653   1.1  christos 	      error_message = NULL;
   2654   1.5  christos 	      /* Convert ASM_SIMPLIFY into the simpler relocation
   2655   1.5  christos 		 so that they never escape a relaxing link.  */
   2656   1.5  christos 	      r = contract_asm_expansion (contents, input_size, rel,
   2657   1.5  christos 					  &error_message);
   2658   1.1  christos 	      if (r != bfd_reloc_ok)
   2659   1.1  christos 		(*info->callbacks->reloc_dangerous)
   2660   1.1  christos 		  (info, error_message,
   2661   1.1  christos 		   input_bfd, input_section, rel->r_offset);
   2662   1.1  christos 
   2663   1.1  christos 	      r_type = ELF32_R_TYPE (rel->r_info);
   2664   1.1  christos 	    }
   2665   1.1  christos 
   2666   1.1  christos 	  /* This is a relocatable link, so we don't have to change
   2667   1.1  christos 	     anything unless the reloc is against a section symbol,
   2668   1.1  christos 	     in which case we have to adjust according to where the
   2669   1.1  christos 	     section symbol winds up in the output section.  */
   2670   1.1  christos 	  if (r_symndx < symtab_hdr->sh_info)
   2671   1.1  christos 	    {
   2672   1.1  christos 	      sym = local_syms + r_symndx;
   2673   1.1  christos 	      if (ELF_ST_TYPE (sym->st_info) == STT_SECTION)
   2674   1.1  christos 		{
   2675   1.1  christos 		  sec = local_sections[r_symndx];
   2676   1.1  christos 		  rel->r_addend += sec->output_offset + sym->st_value;
   2677   1.1  christos 		}
   2678   1.1  christos 	    }
   2679   1.1  christos 
   2680   1.1  christos 	  /* If there is an addend with a partial_inplace howto,
   2681   1.1  christos 	     then move the addend to the contents.  This is a hack
   2682   1.1  christos 	     to work around problems with DWARF in relocatable links
   2683   1.1  christos 	     with some previous version of BFD.  Now we can't easily get
   2684   1.1  christos 	     rid of the hack without breaking backward compatibility.... */
   2685   1.1  christos 	  r = bfd_reloc_ok;
   2686   1.8  christos 	  howto = &elf_howto_table[r_type];
   2687   1.1  christos 	  if (howto->partial_inplace && rel->r_addend)
   2688   1.1  christos 	    {
   2689   1.1  christos 	      r = elf_xtensa_do_reloc (howto, input_bfd, input_section,
   2690   1.1  christos 				       rel->r_addend, contents,
   2691   1.1  christos 				       rel->r_offset, false,
   2692   1.1  christos 				       &error_message);
   2693   1.1  christos 	      rel->r_addend = 0;
   2694   1.1  christos 	    }
   2695   1.1  christos 	  else
   2696   1.1  christos 	    {
   2697   1.1  christos 	      /* Put the correct bits in the target instruction, even
   2698   1.1  christos 		 though the relocation will still be present in the output
   2699   1.1  christos 		 file.  This makes disassembly clearer, as well as
   2700   1.1  christos 		 allowing loadable kernel modules to work without needing
   2701   1.1  christos 		 relocations on anything other than calls and l32r's.  */
   2702   1.1  christos 
   2703   1.1  christos 	      /* If it is not in the same section, there is nothing we can do.  */
   2704   1.8  christos 	      if (r_type >= R_XTENSA_SLOT0_OP && r_type <= R_XTENSA_SLOT14_OP &&
   2705   1.1  christos 		  sym_sec->output_section == input_section->output_section)
   2706   1.1  christos 		{
   2707   1.1  christos 		  r = elf_xtensa_do_reloc (howto, input_bfd, input_section,
   2708   1.1  christos 					   dest_addr, contents,
   2709   1.5  christos 					   rel->r_offset, false,
   2710   1.5  christos 					   &error_message);
   2711   1.5  christos 		}
   2712   1.1  christos 	    }
   2713   1.1  christos 	  if (r != bfd_reloc_ok)
   2714   1.1  christos 	    (*info->callbacks->reloc_dangerous)
   2715   1.1  christos 	      (info, error_message,
   2716   1.1  christos 	       input_bfd, input_section, rel->r_offset);
   2717   1.1  christos 
   2718   1.1  christos 	  /* Done with work for relocatable link; continue with next reloc.  */
   2719   1.1  christos 	  continue;
   2720   1.1  christos 	}
   2721   1.1  christos 
   2722   1.1  christos       /* This is a final link.  */
   2723   1.1  christos 
   2724   1.1  christos       if (relaxing_section)
   2725   1.1  christos 	{
   2726   1.1  christos 	  /* Check if this references a section in another input file.  */
   2727   1.1  christos 	  do_fix_for_final_link (rel, input_bfd, input_section, contents,
   2728   1.1  christos 				 &relocation);
   2729   1.1  christos 	}
   2730   1.6  christos 
   2731   1.6  christos       /* Sanity check the address.  */
   2732   1.6  christos       if (rel->r_offset >= input_size
   2733   1.6  christos 	  && ELF32_R_TYPE (rel->r_info) != R_XTENSA_NONE)
   2734   1.6  christos 	{
   2735   1.6  christos 	  _bfd_error_handler
   2736   1.1  christos 	    /* xgettext:c-format */
   2737   1.8  christos 	    (_("%pB(%pA+%#" PRIx64 "): "
   2738   1.1  christos 	       "relocation offset out of range (size=%#" PRIx64 ")"),
   2739   1.1  christos 	     input_bfd, input_section, (uint64_t) rel->r_offset,
   2740   1.1  christos 	     (uint64_t) input_size);
   2741   1.1  christos 	  bfd_set_error (bfd_error_bad_value);
   2742   1.1  christos 	  return false;
   2743   1.1  christos 	}
   2744   1.1  christos 
   2745   1.1  christos       if (h != NULL)
   2746   1.1  christos 	name = h->root.root.string;
   2747   1.7  christos       else
   2748   1.1  christos 	{
   2749   1.1  christos 	  name = (bfd_elf_string_from_elf_section
   2750   1.1  christos 		  (input_bfd, symtab_hdr->sh_link, sym->st_name));
   2751   1.1  christos 	  if (name == NULL || *name == '\0')
   2752   1.1  christos 	    name = bfd_section_name (sec);
   2753   1.1  christos 	}
   2754   1.1  christos 
   2755   1.1  christos       if (r_symndx != STN_UNDEF
   2756   1.1  christos 	  && r_type != R_XTENSA_NONE
   2757   1.6  christos 	  && (h == NULL
   2758   1.1  christos 	      || h->root.type == bfd_link_hash_defined
   2759   1.6  christos 	      || h->root.type == bfd_link_hash_defweak)
   2760   1.6  christos 	  && IS_XTENSA_TLS_RELOC (r_type) != (sym_type == STT_TLS))
   2761   1.6  christos 	{
   2762   1.6  christos 	  _bfd_error_handler
   2763   1.1  christos 	    ((sym_type == STT_TLS
   2764   1.1  christos 	      /* xgettext:c-format */
   2765   1.6  christos 	      ? _("%pB(%pA+%#" PRIx64 "): %s used with TLS symbol %s")
   2766   1.1  christos 	      /* xgettext:c-format */
   2767   1.1  christos 	      : _("%pB(%pA+%#" PRIx64 "): %s used with non-TLS symbol %s")),
   2768   1.1  christos 	     input_bfd,
   2769   1.1  christos 	     input_section,
   2770   1.1  christos 	     (uint64_t) rel->r_offset,
   2771   1.1  christos 	     howto->name,
   2772   1.1  christos 	     name);
   2773   1.1  christos 	}
   2774   1.1  christos 
   2775   1.1  christos       dynamic_symbol = elf_xtensa_dynamic_symbol_p (h, info);
   2776   1.1  christos 
   2777   1.1  christos       tls_type = GOT_UNKNOWN;
   2778   1.1  christos       if (h)
   2779   1.1  christos 	tls_type = elf_xtensa_hash_entry (h)->tls_type;
   2780   1.1  christos       else if (local_got_tls_types)
   2781   1.1  christos 	tls_type = local_got_tls_types [r_symndx];
   2782   1.1  christos 
   2783   1.1  christos       switch (r_type)
   2784   1.3  christos 	{
   2785   1.1  christos 	case R_XTENSA_32:
   2786   1.1  christos 	case R_XTENSA_PLT:
   2787   1.1  christos 	  if (elf_hash_table (info)->dynamic_sections_created
   2788   1.1  christos 	      && (input_section->flags & SEC_ALLOC) != 0
   2789   1.1  christos 	      && (dynamic_symbol || bfd_link_pic (info)))
   2790   1.1  christos 	    {
   2791   1.6  christos 	      Elf_Internal_Rela outrel;
   2792   1.1  christos 	      bfd_byte *loc;
   2793   1.6  christos 	      asection *srel;
   2794   1.1  christos 
   2795   1.1  christos 	      if (dynamic_symbol && r_type == R_XTENSA_PLT)
   2796   1.1  christos 		srel = htab->elf.srelplt;
   2797   1.1  christos 	      else
   2798   1.1  christos 		srel = htab->elf.srelgot;
   2799   1.1  christos 
   2800   1.1  christos 	      BFD_ASSERT (srel != NULL);
   2801   1.1  christos 
   2802   1.1  christos 	      outrel.r_offset =
   2803   1.1  christos 		_bfd_elf_section_offset (output_bfd, info,
   2804   1.1  christos 					 input_section, rel->r_offset);
   2805   1.1  christos 
   2806   1.1  christos 	      if ((outrel.r_offset | 1) == (bfd_vma) -1)
   2807   1.1  christos 		memset (&outrel, 0, sizeof outrel);
   2808   1.1  christos 	      else
   2809   1.1  christos 		{
   2810   1.1  christos 		  outrel.r_offset += (input_section->output_section->vma
   2811   1.1  christos 				      + input_section->output_offset);
   2812   1.1  christos 
   2813   1.1  christos 		  /* Complain if the relocation is in a read-only section
   2814   1.1  christos 		     and not in a literal pool.  */
   2815   1.1  christos 		  if ((input_section->flags & SEC_READONLY) != 0
   2816   1.5  christos 		      && !elf_xtensa_in_literal_pool (lit_table, ltblsize,
   2817   1.5  christos 						      outrel.r_offset))
   2818   1.5  christos 		    {
   2819   1.1  christos 		      error_message =
   2820   1.1  christos 			_("dynamic relocation in read-only section");
   2821   1.1  christos 		      (*info->callbacks->reloc_dangerous)
   2822   1.1  christos 			(info, error_message,
   2823   1.1  christos 			 input_bfd, input_section, rel->r_offset);
   2824   1.1  christos 		    }
   2825   1.1  christos 
   2826   1.1  christos 		  if (dynamic_symbol)
   2827   1.1  christos 		    {
   2828   1.1  christos 		      outrel.r_addend = rel->r_addend;
   2829   1.1  christos 		      rel->r_addend = 0;
   2830   1.1  christos 
   2831   1.1  christos 		      if (r_type == R_XTENSA_32)
   2832   1.1  christos 			{
   2833   1.1  christos 			  outrel.r_info =
   2834   1.1  christos 			    ELF32_R_INFO (h->dynindx, R_XTENSA_GLOB_DAT);
   2835   1.1  christos 			  relocation = 0;
   2836   1.1  christos 			}
   2837   1.1  christos 		      else /* r_type == R_XTENSA_PLT */
   2838   1.1  christos 			{
   2839   1.1  christos 			  outrel.r_info =
   2840   1.1  christos 			    ELF32_R_INFO (h->dynindx, R_XTENSA_JMP_SLOT);
   2841   1.1  christos 
   2842   1.1  christos 			  /* Create the PLT entry and set the initial
   2843   1.1  christos 			     contents of the literal entry to the address of
   2844   1.8  christos 			     the PLT entry.  */
   2845   1.1  christos 			  relocation =
   2846   1.6  christos 			    elf_xtensa_create_plt_entry (info, output_bfd,
   2847   1.1  christos 							 srel->reloc_count);
   2848   1.1  christos 			}
   2849   1.1  christos 		      unresolved_reloc = false;
   2850   1.1  christos 		    }
   2851   1.1  christos 		  else if (!is_weak_undef)
   2852   1.6  christos 		    {
   2853   1.6  christos 		      /* Generate a RELATIVE relocation.  */
   2854   1.6  christos 		      outrel.r_info = ELF32_R_INFO (0, R_XTENSA_RELATIVE);
   2855   1.6  christos 		      outrel.r_addend = 0;
   2856   1.1  christos 		    }
   2857   1.1  christos 		  else
   2858   1.1  christos 		    {
   2859   1.1  christos 		      continue;
   2860   1.1  christos 		    }
   2861   1.1  christos 		}
   2862   1.1  christos 
   2863   1.1  christos 	      loc = (srel->contents
   2864   1.1  christos 		     + srel->reloc_count++ * sizeof (Elf32_External_Rela));
   2865   1.1  christos 	      bfd_elf32_swap_reloca_out (output_bfd, &outrel, loc);
   2866   1.1  christos 	      BFD_ASSERT (sizeof (Elf32_External_Rela) * srel->reloc_count
   2867   1.1  christos 			  <= srel->size);
   2868   1.1  christos 	    }
   2869   1.1  christos 	  else if (r_type == R_XTENSA_ASM_EXPAND && dynamic_symbol)
   2870   1.1  christos 	    {
   2871   1.1  christos 	      /* This should only happen for non-PIC code, which is not
   2872   1.1  christos 		 supposed to be used on systems with dynamic linking.
   2873   1.1  christos 		 Just ignore these relocations.  */
   2874   1.1  christos 	      continue;
   2875   1.9  christos 	    }
   2876   1.1  christos 	  break;
   2877   1.1  christos 
   2878   1.1  christos 	case R_XTENSA_TLS_TPOFF:
   2879   1.1  christos 	  /* Switch to LE model for local symbols in an executable.  */
   2880   1.1  christos 	  if (! bfd_link_dll (info) && ! dynamic_symbol)
   2881   1.1  christos 	    {
   2882   1.1  christos 	      relocation = tpoff (info, relocation);
   2883   1.1  christos 	      break;
   2884   1.1  christos 	    }
   2885   1.1  christos 	  /* fall through */
   2886   1.1  christos 
   2887   1.9  christos 	case R_XTENSA_TLSDESC_FN:
   2888   1.1  christos 	case R_XTENSA_TLSDESC_ARG:
   2889   1.1  christos 	  {
   2890   1.1  christos 	    if (r_type == R_XTENSA_TLSDESC_FN)
   2891   1.1  christos 	      {
   2892   1.9  christos 		if (! bfd_link_dll (info) || (tls_type & GOT_TLS_IE) != 0)
   2893   1.1  christos 		  r_type = R_XTENSA_NONE;
   2894   1.1  christos 	      }
   2895   1.1  christos 	    else if (r_type == R_XTENSA_TLSDESC_ARG)
   2896   1.1  christos 	      {
   2897   1.1  christos 		if (bfd_link_dll (info))
   2898   1.1  christos 		  {
   2899   1.1  christos 		    if ((tls_type & GOT_TLS_IE) != 0)
   2900   1.1  christos 		      r_type = R_XTENSA_TLS_TPOFF;
   2901   1.1  christos 		  }
   2902   1.1  christos 		else
   2903   1.1  christos 		  {
   2904   1.1  christos 		    r_type = R_XTENSA_TLS_TPOFF;
   2905   1.1  christos 		    if (! dynamic_symbol)
   2906   1.1  christos 		      {
   2907   1.1  christos 			relocation = tpoff (info, relocation);
   2908   1.1  christos 			break;
   2909   1.1  christos 		      }
   2910   1.1  christos 		  }
   2911   1.1  christos 	      }
   2912   1.1  christos 
   2913   1.1  christos 	    if (r_type == R_XTENSA_NONE)
   2914   1.1  christos 	      /* Nothing to do here; skip to the next reloc.  */
   2915   1.1  christos 	      continue;
   2916   1.5  christos 
   2917   1.5  christos 	    if (! elf_hash_table (info)->dynamic_sections_created)
   2918   1.5  christos 	      {
   2919   1.1  christos 		error_message =
   2920   1.1  christos 		  _("TLS relocation invalid without dynamic sections");
   2921   1.1  christos 		(*info->callbacks->reloc_dangerous)
   2922   1.1  christos 		  (info, error_message,
   2923   1.1  christos 		   input_bfd, input_section, rel->r_offset);
   2924   1.6  christos 	      }
   2925   1.1  christos 	    else
   2926   1.1  christos 	      {
   2927   1.1  christos 		Elf_Internal_Rela outrel;
   2928   1.1  christos 		bfd_byte *loc;
   2929   1.1  christos 		asection *srel = htab->elf.srelgot;
   2930   1.1  christos 		int indx;
   2931   1.1  christos 
   2932   1.1  christos 		outrel.r_offset = (input_section->output_section->vma
   2933   1.1  christos 				   + input_section->output_offset
   2934   1.1  christos 				   + rel->r_offset);
   2935   1.1  christos 
   2936   1.1  christos 		/* Complain if the relocation is in a read-only section
   2937   1.1  christos 		   and not in a literal pool.  */
   2938   1.1  christos 		if ((input_section->flags & SEC_READONLY) != 0
   2939   1.5  christos 		    && ! elf_xtensa_in_literal_pool (lit_table, ltblsize,
   2940   1.5  christos 						     outrel.r_offset))
   2941   1.5  christos 		  {
   2942   1.1  christos 		    error_message =
   2943   1.1  christos 		      _("dynamic relocation in read-only section");
   2944   1.1  christos 		    (*info->callbacks->reloc_dangerous)
   2945   1.1  christos 		      (info, error_message,
   2946   1.1  christos 		       input_bfd, input_section, rel->r_offset);
   2947   1.1  christos 		  }
   2948   1.1  christos 
   2949   1.1  christos 		indx = h && h->dynindx != -1 ? h->dynindx : 0;
   2950   1.1  christos 		if (indx == 0)
   2951   1.1  christos 		  outrel.r_addend = relocation - dtpoff_base (info);
   2952   1.1  christos 		else
   2953   1.8  christos 		  outrel.r_addend = 0;
   2954   1.1  christos 		rel->r_addend = 0;
   2955   1.1  christos 
   2956   1.1  christos 		outrel.r_info = ELF32_R_INFO (indx, r_type);
   2957   1.1  christos 		relocation = 0;
   2958   1.1  christos 		unresolved_reloc = false;
   2959   1.1  christos 
   2960   1.1  christos 		BFD_ASSERT (srel);
   2961   1.1  christos 		loc = (srel->contents
   2962   1.1  christos 		       + srel->reloc_count++ * sizeof (Elf32_External_Rela));
   2963   1.1  christos 		bfd_elf32_swap_reloca_out (output_bfd, &outrel, loc);
   2964   1.1  christos 		BFD_ASSERT (sizeof (Elf32_External_Rela) * srel->reloc_count
   2965   1.1  christos 			    <= srel->size);
   2966   1.9  christos 	      }
   2967   1.1  christos 	  }
   2968   1.1  christos 	  break;
   2969   1.1  christos 
   2970   1.1  christos 	case R_XTENSA_TLS_DTPOFF:
   2971   1.1  christos 	  if (! bfd_link_dll (info))
   2972   1.1  christos 	    /* Switch from LD model to LE model.  */
   2973   1.1  christos 	    relocation = tpoff (info, relocation);
   2974   1.1  christos 	  else
   2975   1.1  christos 	    relocation -= dtpoff_base (info);
   2976   1.1  christos 	  break;
   2977   1.1  christos 
   2978   1.1  christos 	case R_XTENSA_TLS_FUNC:
   2979   1.8  christos 	case R_XTENSA_TLS_ARG:
   2980   1.1  christos 	case R_XTENSA_TLS_CALL:
   2981   1.1  christos 	  /* Check if optimizing to IE or LE model.  */
   2982   1.1  christos 	  if ((tls_type & GOT_TLS_IE) != 0)
   2983   1.5  christos 	    {
   2984   1.5  christos 	      bool is_ld_model =
   2985   1.5  christos 		(h && elf_xtensa_hash_entry (h) == htab->tlsbase);
   2986   1.1  christos 	      if (! replace_tls_insn (rel, input_bfd, input_section, contents,
   2987   1.1  christos 				      is_ld_model, &error_message))
   2988   1.1  christos 		(*info->callbacks->reloc_dangerous)
   2989   1.1  christos 		  (info, error_message,
   2990   1.1  christos 		   input_bfd, input_section, rel->r_offset);
   2991   1.1  christos 
   2992   1.1  christos 	      if (r_type != R_XTENSA_TLS_ARG || is_ld_model)
   2993   1.1  christos 		{
   2994   1.1  christos 		  /* Skip subsequent relocations on the same instruction.  */
   2995   1.1  christos 		  while (rel + 1 < relend && rel[1].r_offset == rel->r_offset)
   2996   1.1  christos 		    rel++;
   2997   1.1  christos 		}
   2998   1.1  christos 	    }
   2999   1.1  christos 	  continue;
   3000   1.1  christos 
   3001   1.1  christos 	default:
   3002   1.1  christos 	  if (elf_hash_table (info)->dynamic_sections_created
   3003   1.1  christos 	      && dynamic_symbol && (is_operand_relocation (r_type)
   3004   1.5  christos 				    || r_type == R_XTENSA_32_PCREL))
   3005   1.5  christos 	    {
   3006   1.1  christos 	      error_message =
   3007   1.1  christos 		vsprint_msg ("invalid relocation for dynamic symbol", ": %s",
   3008   1.1  christos 			     strlen (name) + 2, name);
   3009   1.1  christos 	      (*info->callbacks->reloc_dangerous)
   3010   1.1  christos 		(info, error_message, input_bfd, input_section, rel->r_offset);
   3011   1.1  christos 	      continue;
   3012   1.1  christos 	    }
   3013   1.1  christos 	  break;
   3014   1.1  christos 	}
   3015   1.1  christos 
   3016   1.1  christos       /* Dynamic relocs are not propagated for SEC_DEBUGGING sections
   3017   1.1  christos 	 because such sections are not SEC_ALLOC and thus ld.so will
   3018   1.1  christos 	 not process them.  */
   3019   1.1  christos       if (unresolved_reloc
   3020   1.6  christos 	  && !((input_section->flags & SEC_DEBUGGING) != 0
   3021   1.6  christos 	       && h->def_dynamic)
   3022   1.6  christos 	  && _bfd_elf_section_offset (output_bfd, info, input_section,
   3023   1.6  christos 				      rel->r_offset) != (bfd_vma) -1)
   3024   1.1  christos 	{
   3025   1.1  christos 	  _bfd_error_handler
   3026   1.6  christos 	    /* xgettext:c-format */
   3027   1.1  christos 	    (_("%pB(%pA+%#" PRIx64 "): "
   3028   1.1  christos 	       "unresolvable %s relocation against symbol `%s'"),
   3029   1.8  christos 	     input_bfd,
   3030   1.1  christos 	     input_section,
   3031   1.1  christos 	     (uint64_t) rel->r_offset,
   3032   1.1  christos 	     howto->name,
   3033   1.1  christos 	     name);
   3034   1.1  christos 	  return false;
   3035   1.1  christos 	}
   3036   1.1  christos 
   3037   1.1  christos       /* TLS optimizations may have changed r_type; update "howto".  */
   3038   1.1  christos       howto = &elf_howto_table[r_type];
   3039   1.1  christos 
   3040   1.1  christos       /* There's no point in calling bfd_perform_relocation here.
   3041   1.1  christos 	 Just go directly to our "special function".  */
   3042   1.1  christos       r = elf_xtensa_do_reloc (howto, input_bfd, input_section,
   3043   1.1  christos 			       relocation + rel->r_addend,
   3044   1.1  christos 			       contents, rel->r_offset, is_weak_undef,
   3045   1.1  christos 			       &error_message);
   3046   1.1  christos 
   3047   1.1  christos       if (r != bfd_reloc_ok && !warned)
   3048   1.1  christos 	{
   3049   1.1  christos 	  BFD_ASSERT (r == bfd_reloc_dangerous || r == bfd_reloc_other);
   3050   1.1  christos 	  BFD_ASSERT (error_message != NULL);
   3051   1.1  christos 
   3052   1.1  christos 	  if (rel->r_addend == 0)
   3053   1.1  christos 	    error_message = vsprint_msg (error_message, ": %s",
   3054   1.1  christos 					 strlen (name) + 2, name);
   3055   1.5  christos 	  else
   3056   1.5  christos 	    error_message = vsprint_msg (error_message, ": (%s+0x%x)",
   3057   1.1  christos 					 strlen (name) + 22,
   3058   1.1  christos 					 name, (int) rel->r_addend);
   3059   1.1  christos 
   3060   1.8  christos 	  (*info->callbacks->reloc_dangerous)
   3061   1.8  christos 	    (info, error_message, input_bfd, input_section, rel->r_offset);
   3062   1.1  christos 	}
   3063   1.8  christos     }
   3064   1.1  christos 
   3065   1.1  christos   free (lit_table);
   3066   1.1  christos   input_section->reloc_done = true;
   3067   1.1  christos 
   3068   1.1  christos   return true;
   3069   1.1  christos }
   3070   1.8  christos 
   3071   1.1  christos 
   3072   1.1  christos /* Finish up dynamic symbol handling.  There's not much to do here since
   3073   1.1  christos    the PLT and GOT entries are all set up by relocate_section.  */
   3074   1.1  christos 
   3075   1.1  christos static bool
   3076   1.1  christos elf_xtensa_finish_dynamic_symbol (bfd *output_bfd ATTRIBUTE_UNUSED,
   3077   1.1  christos 				  struct bfd_link_info *info ATTRIBUTE_UNUSED,
   3078   1.1  christos 				  struct elf_link_hash_entry *h,
   3079   1.1  christos 				  Elf_Internal_Sym *sym)
   3080   1.1  christos {
   3081   1.1  christos   if (h->needs_plt && !h->def_regular)
   3082   1.1  christos     {
   3083   1.1  christos       /* Mark the symbol as undefined, rather than as defined in
   3084   1.1  christos 	 the .plt section.  Leave the value alone.  */
   3085   1.1  christos       sym->st_shndx = SHN_UNDEF;
   3086   1.1  christos       /* If the symbol is weak, we do need to clear the value.
   3087   1.1  christos 	 Otherwise, the PLT entry would provide a definition for
   3088   1.1  christos 	 the symbol even if the symbol wasn't defined anywhere,
   3089   1.1  christos 	 and so the symbol would never be NULL.  */
   3090   1.3  christos       if (!h->ref_regular_nonweak)
   3091   1.1  christos 	sym->st_value = 0;
   3092   1.1  christos     }
   3093   1.1  christos 
   3094   1.8  christos   /* Mark _DYNAMIC and _GLOBAL_OFFSET_TABLE_ as absolute.  */
   3095   1.1  christos   if (h == elf_hash_table (info)->hdynamic
   3096   1.1  christos       || h == elf_hash_table (info)->hgot)
   3097   1.1  christos     sym->st_shndx = SHN_ABS;
   3098   1.1  christos 
   3099   1.1  christos   return true;
   3100   1.1  christos }
   3101   1.1  christos 
   3102   1.1  christos 
   3103   1.1  christos /* Combine adjacent literal table entries in the output.  Adjacent
   3104   1.1  christos    entries within each input section may have been removed during
   3105   1.1  christos    relaxation, but we repeat the process here, even though it's too late
   3106   1.1  christos    to shrink the output section, because it's important to minimize the
   3107   1.1  christos    number of literal table entries to reduce the start-up work for the
   3108   1.1  christos    runtime linker.  Returns the number of remaining table entries or -1
   3109   1.1  christos    on error.  */
   3110   1.1  christos 
   3111   1.1  christos static int
   3112   1.1  christos elf_xtensa_combine_prop_entries (bfd *output_bfd,
   3113   1.1  christos 				 asection *sxtlit,
   3114   1.1  christos 				 asection *sgotloc)
   3115   1.1  christos {
   3116   1.1  christos   bfd_byte *contents;
   3117   1.1  christos   property_table_entry *table;
   3118   1.8  christos   bfd_size_type section_size, sgotloc_size;
   3119   1.8  christos   bfd_vma offset;
   3120   1.8  christos   int n, m, num;
   3121   1.1  christos 
   3122   1.1  christos   section_size = sxtlit->size;
   3123   1.1  christos   if (section_size == 0)
   3124   1.1  christos     return 0;
   3125   1.1  christos 
   3126   1.1  christos   BFD_ASSERT (section_size % 8 == 0);
   3127   1.6  christos   num = section_size / 8;
   3128   1.1  christos 
   3129   1.1  christos   sgotloc_size = sgotloc->size;
   3130   1.1  christos   if (sgotloc_size != section_size)
   3131   1.1  christos     {
   3132   1.1  christos       _bfd_error_handler
   3133   1.1  christos 	(_("internal inconsistency in size of .got.loc section"));
   3134   1.1  christos       return -1;
   3135   1.1  christos     }
   3136   1.1  christos 
   3137   1.1  christos   table = bfd_malloc (num * sizeof (property_table_entry));
   3138   1.1  christos   if (table == 0)
   3139   1.1  christos     return -1;
   3140   1.1  christos 
   3141   1.1  christos   /* The ".xt.lit.plt" section has the SEC_IN_MEMORY flag set and this
   3142   1.1  christos      propagates to the output section, where it doesn't really apply and
   3143   1.8  christos      where it breaks the following call to bfd_malloc_and_get_section.  */
   3144   1.1  christos   sxtlit->flags &= ~SEC_IN_MEMORY;
   3145   1.1  christos 
   3146   1.1  christos   if (!bfd_malloc_and_get_section (output_bfd, sxtlit, &contents))
   3147   1.1  christos     {
   3148   1.1  christos       free (contents);
   3149   1.1  christos       free (table);
   3150   1.1  christos       return -1;
   3151   1.1  christos     }
   3152   1.1  christos 
   3153   1.1  christos   /* There should never be any relocations left at this point, so this
   3154   1.1  christos      is quite a bit easier than what is done during relaxation.  */
   3155   1.1  christos 
   3156   1.1  christos   /* Copy the raw contents into a property table array and sort it.  */
   3157   1.1  christos   offset = 0;
   3158   1.1  christos   for (n = 0; n < num; n++)
   3159   1.1  christos     {
   3160   1.1  christos       table[n].address = bfd_get_32 (output_bfd, &contents[offset]);
   3161   1.1  christos       table[n].size = bfd_get_32 (output_bfd, &contents[offset + 4]);
   3162   1.1  christos       offset += 8;
   3163   1.8  christos     }
   3164   1.1  christos   qsort (table, num, sizeof (property_table_entry), property_table_compare);
   3165   1.1  christos 
   3166   1.8  christos   for (n = 0; n < num; n++)
   3167   1.1  christos     {
   3168   1.1  christos       bool remove_entry = false;
   3169   1.1  christos 
   3170   1.1  christos       if (table[n].size == 0)
   3171   1.8  christos 	remove_entry = true;
   3172   1.1  christos       else if (n > 0
   3173   1.1  christos 	       && (table[n-1].address + table[n-1].size == table[n].address))
   3174   1.1  christos 	{
   3175   1.1  christos 	  table[n-1].size += table[n].size;
   3176   1.1  christos 	  remove_entry = true;
   3177   1.1  christos 	}
   3178   1.1  christos 
   3179   1.1  christos       if (remove_entry)
   3180   1.1  christos 	{
   3181   1.1  christos 	  for (m = n; m < num - 1; m++)
   3182   1.1  christos 	    {
   3183   1.1  christos 	      table[m].address = table[m+1].address;
   3184   1.1  christos 	      table[m].size = table[m+1].size;
   3185   1.1  christos 	    }
   3186   1.1  christos 
   3187   1.1  christos 	  n--;
   3188   1.1  christos 	  num--;
   3189   1.1  christos 	}
   3190   1.1  christos     }
   3191   1.1  christos 
   3192   1.1  christos   /* Copy the data back to the raw contents.  */
   3193   1.1  christos   offset = 0;
   3194   1.1  christos   for (n = 0; n < num; n++)
   3195   1.1  christos     {
   3196   1.1  christos       bfd_put_32 (output_bfd, table[n].address, &contents[offset]);
   3197   1.1  christos       bfd_put_32 (output_bfd, table[n].size, &contents[offset + 4]);
   3198   1.1  christos       offset += 8;
   3199   1.1  christos     }
   3200   1.1  christos 
   3201   1.1  christos   /* Clear the removed bytes.  */
   3202   1.1  christos   if ((bfd_size_type) (num * 8) < section_size)
   3203   1.1  christos     memset (&contents[num * 8], 0, section_size - num * 8);
   3204   1.1  christos 
   3205   1.1  christos   if (! bfd_set_section_contents (output_bfd, sxtlit, contents, 0,
   3206   1.1  christos 				  section_size))
   3207   1.1  christos     return -1;
   3208   1.1  christos 
   3209   1.1  christos   /* Copy the contents to ".got.loc".  */
   3210   1.1  christos   memcpy (sgotloc->contents, contents, section_size);
   3211   1.1  christos 
   3212   1.1  christos   free (contents);
   3213   1.1  christos   free (table);
   3214   1.1  christos   return num;
   3215   1.8  christos }
   3216   1.1  christos 
   3217   1.1  christos 
   3218   1.1  christos /* Finish up the dynamic sections.  */
   3219   1.1  christos 
   3220   1.1  christos static bool
   3221   1.7  christos elf_xtensa_finish_dynamic_sections (bfd *output_bfd,
   3222   1.1  christos 				    struct bfd_link_info *info)
   3223   1.1  christos {
   3224   1.1  christos   struct elf_xtensa_link_hash_table *htab;
   3225   1.1  christos   bfd *dynobj;
   3226   1.8  christos   asection *sdyn, *srelplt, *srelgot, *sgot, *sxtlit, *sgotloc;
   3227   1.1  christos   Elf32_External_Dyn *dyncon, *dynconend;
   3228   1.1  christos   int num_xtlit_entries = 0;
   3229   1.1  christos 
   3230   1.8  christos   if (! elf_hash_table (info)->dynamic_sections_created)
   3231   1.1  christos     return true;
   3232   1.1  christos 
   3233   1.1  christos   htab = elf_xtensa_hash_table (info);
   3234   1.1  christos   if (htab == NULL)
   3235   1.1  christos     return false;
   3236   1.1  christos 
   3237   1.1  christos   dynobj = elf_hash_table (info)->dynobj;
   3238   1.6  christos   sdyn = bfd_get_linker_section (dynobj, ".dynamic");
   3239   1.1  christos   BFD_ASSERT (sdyn != NULL);
   3240   1.1  christos 
   3241   1.1  christos   /* Set the first entry in the global offset table to the address of
   3242   1.1  christos      the dynamic section.  */
   3243   1.1  christos   sgot = htab->elf.sgot;
   3244   1.1  christos   if (sgot)
   3245   1.1  christos     {
   3246   1.1  christos       BFD_ASSERT (sgot->size == 4);
   3247   1.1  christos       if (sdyn == NULL)
   3248   1.1  christos 	bfd_put_32 (output_bfd, 0, sgot->contents);
   3249   1.1  christos       else
   3250   1.6  christos 	bfd_put_32 (output_bfd,
   3251   1.7  christos 		    sdyn->output_section->vma + sdyn->output_offset,
   3252   1.1  christos 		    sgot->contents);
   3253   1.1  christos     }
   3254   1.7  christos 
   3255   1.1  christos   srelplt = htab->elf.srelplt;
   3256   1.1  christos   srelgot = htab->elf.srelgot;
   3257   1.1  christos   if (srelplt && srelplt->size != 0)
   3258   1.1  christos     {
   3259   1.1  christos       asection *sgotplt, *spltlittbl;
   3260   1.1  christos       int chunk, plt_chunks, plt_entries;
   3261   1.1  christos       Elf_Internal_Rela irela;
   3262   1.1  christos       bfd_byte *loc;
   3263   1.1  christos       unsigned rtld_reloc;
   3264   1.1  christos 
   3265   1.1  christos       spltlittbl = htab->spltlittbl;
   3266   1.1  christos       BFD_ASSERT (srelgot != NULL && spltlittbl != NULL);
   3267   1.1  christos 
   3268   1.1  christos       /* Find the first XTENSA_RTLD relocation.  Presumably the rest
   3269   1.1  christos 	 of them follow immediately after....  */
   3270   1.1  christos       for (rtld_reloc = 0; rtld_reloc < srelgot->reloc_count; rtld_reloc++)
   3271   1.1  christos 	{
   3272   1.1  christos 	  loc = srelgot->contents + rtld_reloc * sizeof (Elf32_External_Rela);
   3273   1.1  christos 	  bfd_elf32_swap_reloca_in (output_bfd, loc, &irela);
   3274   1.1  christos 	  if (ELF32_R_TYPE (irela.r_info) == R_XTENSA_RTLD)
   3275   1.1  christos 	    break;
   3276   1.1  christos 	}
   3277   1.1  christos       BFD_ASSERT (rtld_reloc < srelgot->reloc_count);
   3278   1.1  christos 
   3279   1.1  christos       plt_entries = srelplt->size / sizeof (Elf32_External_Rela);
   3280   1.1  christos       plt_chunks =
   3281   1.1  christos 	(plt_entries + PLT_ENTRIES_PER_CHUNK - 1) / PLT_ENTRIES_PER_CHUNK;
   3282   1.1  christos 
   3283   1.1  christos       for (chunk = 0; chunk < plt_chunks; chunk++)
   3284   1.1  christos 	{
   3285   1.1  christos 	  int chunk_entries = 0;
   3286   1.1  christos 
   3287   1.1  christos 	  sgotplt = elf_xtensa_get_gotplt_section (info, chunk);
   3288   1.1  christos 	  BFD_ASSERT (sgotplt != NULL);
   3289   1.1  christos 
   3290   1.1  christos 	  /* Emit special RTLD relocations for the first two entries in
   3291   1.1  christos 	     each chunk of the .got.plt section.  */
   3292   1.1  christos 
   3293   1.1  christos 	  loc = srelgot->contents + rtld_reloc * sizeof (Elf32_External_Rela);
   3294   1.1  christos 	  bfd_elf32_swap_reloca_in (output_bfd, loc, &irela);
   3295   1.1  christos 	  BFD_ASSERT (ELF32_R_TYPE (irela.r_info) == R_XTENSA_RTLD);
   3296   1.1  christos 	  irela.r_offset = (sgotplt->output_section->vma
   3297   1.1  christos 			    + sgotplt->output_offset);
   3298   1.1  christos 	  irela.r_addend = 1; /* tell rtld to set value to resolver function */
   3299   1.1  christos 	  bfd_elf32_swap_reloca_out (output_bfd, &irela, loc);
   3300   1.1  christos 	  rtld_reloc += 1;
   3301   1.1  christos 	  BFD_ASSERT (rtld_reloc <= srelgot->reloc_count);
   3302   1.1  christos 
   3303   1.1  christos 	  /* Next literal immediately follows the first.  */
   3304   1.1  christos 	  loc += sizeof (Elf32_External_Rela);
   3305   1.1  christos 	  bfd_elf32_swap_reloca_in (output_bfd, loc, &irela);
   3306   1.1  christos 	  BFD_ASSERT (ELF32_R_TYPE (irela.r_info) == R_XTENSA_RTLD);
   3307   1.1  christos 	  irela.r_offset = (sgotplt->output_section->vma
   3308   1.1  christos 			    + sgotplt->output_offset + 4);
   3309   1.1  christos 	  /* Tell rtld to set value to object's link map.  */
   3310   1.1  christos 	  irela.r_addend = 2;
   3311   1.1  christos 	  bfd_elf32_swap_reloca_out (output_bfd, &irela, loc);
   3312   1.1  christos 	  rtld_reloc += 1;
   3313   1.1  christos 	  BFD_ASSERT (rtld_reloc <= srelgot->reloc_count);
   3314   1.1  christos 
   3315   1.1  christos 	  /* Fill in the literal table.  */
   3316   1.1  christos 	  if (chunk < plt_chunks - 1)
   3317   1.1  christos 	    chunk_entries = PLT_ENTRIES_PER_CHUNK;
   3318   1.1  christos 	  else
   3319   1.1  christos 	    chunk_entries = plt_entries - (chunk * PLT_ENTRIES_PER_CHUNK);
   3320   1.1  christos 
   3321   1.1  christos 	  BFD_ASSERT ((unsigned) (chunk + 1) * 8 <= spltlittbl->size);
   3322   1.1  christos 	  bfd_put_32 (output_bfd,
   3323   1.1  christos 		      sgotplt->output_section->vma + sgotplt->output_offset,
   3324   1.1  christos 		      spltlittbl->contents + (chunk * 8) + 0);
   3325   1.1  christos 	  bfd_put_32 (output_bfd,
   3326   1.1  christos 		      8 + (chunk_entries * 4),
   3327   1.1  christos 		      spltlittbl->contents + (chunk * 8) + 4);
   3328   1.1  christos 	}
   3329   1.1  christos 
   3330   1.1  christos      /* The .xt.lit.plt section has just been modified.  This must
   3331   1.1  christos 	happen before the code below which combines adjacent literal
   3332   1.1  christos 	table entries, and the .xt.lit.plt contents have to be forced to
   3333   1.1  christos 	the output here.  */
   3334   1.8  christos       if (! bfd_set_section_contents (output_bfd,
   3335   1.1  christos 				      spltlittbl->output_section,
   3336   1.1  christos 				      spltlittbl->contents,
   3337   1.1  christos 				      spltlittbl->output_offset,
   3338   1.1  christos 				      spltlittbl->size))
   3339   1.7  christos 	return false;
   3340   1.7  christos       /* Clear SEC_HAS_CONTENTS so the contents won't be output again.  */
   3341   1.7  christos       spltlittbl->flags &= ~SEC_HAS_CONTENTS;
   3342   1.7  christos     }
   3343   1.7  christos 
   3344   1.7  christos   /* All the dynamic relocations have been emitted at this point.
   3345   1.7  christos      Make sure the relocation sections are the correct size.  */
   3346   1.7  christos   if ((srelgot && srelgot->size != (sizeof (Elf32_External_Rela)
   3347   1.1  christos 				    * srelgot->reloc_count))
   3348   1.3  christos       || (srelplt && srelplt->size != (sizeof (Elf32_External_Rela)
   3349   1.1  christos 				       * srelplt->reloc_count)))
   3350   1.1  christos     abort ();
   3351   1.1  christos 
   3352   1.1  christos   /* Combine adjacent literal table entries.  */
   3353   1.1  christos   BFD_ASSERT (! bfd_link_relocatable (info));
   3354   1.1  christos   sxtlit = bfd_get_section_by_name (output_bfd, ".xt.lit");
   3355   1.1  christos   sgotloc = htab->sgotloc;
   3356   1.1  christos   BFD_ASSERT (sgotloc);
   3357   1.8  christos   if (sxtlit)
   3358   1.1  christos     {
   3359   1.1  christos       num_xtlit_entries =
   3360   1.1  christos 	elf_xtensa_combine_prop_entries (output_bfd, sxtlit, sgotloc);
   3361   1.1  christos       if (num_xtlit_entries < 0)
   3362   1.1  christos 	return false;
   3363   1.1  christos     }
   3364   1.1  christos 
   3365   1.1  christos   dyncon = (Elf32_External_Dyn *) sdyn->contents;
   3366   1.1  christos   dynconend = (Elf32_External_Dyn *) (sdyn->contents + sdyn->size);
   3367   1.1  christos   for (; dyncon < dynconend; dyncon++)
   3368   1.1  christos     {
   3369   1.1  christos       Elf_Internal_Dyn dyn;
   3370   1.1  christos 
   3371   1.1  christos       bfd_elf32_swap_dyn_in (dynobj, dyncon, &dyn);
   3372   1.1  christos 
   3373   1.1  christos       switch (dyn.d_tag)
   3374   1.1  christos 	{
   3375   1.1  christos 	default:
   3376   1.1  christos 	  break;
   3377   1.1  christos 
   3378   1.5  christos 	case DT_XTENSA_GOT_LOC_SZ:
   3379   1.5  christos 	  dyn.d_un.d_val = num_xtlit_entries;
   3380   1.1  christos 	  break;
   3381   1.1  christos 
   3382   1.1  christos 	case DT_XTENSA_GOT_LOC_OFF:
   3383   1.6  christos 	  dyn.d_un.d_ptr = (htab->sgotloc->output_section->vma
   3384   1.6  christos 			    + htab->sgotloc->output_offset);
   3385   1.1  christos 	  break;
   3386   1.1  christos 
   3387   1.1  christos 	case DT_PLTGOT:
   3388   1.6  christos 	  dyn.d_un.d_ptr = (htab->elf.sgot->output_section->vma
   3389   1.6  christos 			    + htab->elf.sgot->output_offset);
   3390   1.1  christos 	  break;
   3391   1.1  christos 
   3392   1.1  christos 	case DT_JMPREL:
   3393   1.6  christos 	  dyn.d_un.d_ptr = (htab->elf.srelplt->output_section->vma
   3394   1.1  christos 			    + htab->elf.srelplt->output_offset);
   3395   1.1  christos 	  break;
   3396   1.1  christos 
   3397   1.1  christos 	case DT_PLTRELSZ:
   3398   1.1  christos 	  dyn.d_un.d_val = htab->elf.srelplt->size;
   3399   1.1  christos 	  break;
   3400   1.8  christos 	}
   3401   1.1  christos 
   3402   1.1  christos       bfd_elf32_swap_dyn_out (output_bfd, &dyn, dyncon);
   3403   1.1  christos     }
   3404   1.1  christos 
   3405   1.1  christos   return true;
   3406   1.1  christos }
   3407   1.1  christos 
   3408   1.1  christos 
   3409   1.8  christos /* Functions for dealing with the e_flags field.  */
   3411   1.1  christos 
   3412   1.6  christos /* Merge backend specific data from an object file to the output
   3413   1.1  christos    object file when linking.  */
   3414   1.1  christos 
   3415   1.1  christos static bool
   3416   1.1  christos elf_xtensa_merge_private_bfd_data (bfd *ibfd, struct bfd_link_info *info)
   3417   1.6  christos {
   3418   1.8  christos   bfd *obfd = info->output_bfd;
   3419   1.1  christos   unsigned out_mach, in_mach;
   3420   1.1  christos   flagword out_flag, in_flag;
   3421   1.1  christos 
   3422   1.1  christos   /* Check if we have the same endianness.  */
   3423   1.8  christos   if (!_bfd_generic_verify_endian_match (ibfd, info))
   3424   1.1  christos     return false;
   3425   1.1  christos 
   3426   1.1  christos   /* Don't even pretend to support mixed-format linking.  */
   3427   1.1  christos   if (bfd_get_flavour (ibfd) != bfd_target_elf_flavour
   3428   1.1  christos       || bfd_get_flavour (obfd) != bfd_target_elf_flavour)
   3429   1.1  christos     return false;
   3430   1.1  christos 
   3431   1.1  christos   out_flag = elf_elfheader (obfd)->e_flags;
   3432   1.6  christos   in_flag = elf_elfheader (ibfd)->e_flags;
   3433   1.6  christos 
   3434   1.6  christos   out_mach = out_flag & EF_XTENSA_MACH;
   3435   1.1  christos   in_mach = in_flag & EF_XTENSA_MACH;
   3436   1.1  christos   if (out_mach != in_mach)
   3437   1.8  christos     {
   3438   1.1  christos       _bfd_error_handler
   3439   1.1  christos 	/* xgettext:c-format */
   3440   1.1  christos 	(_("%pB: incompatible machine type; output is 0x%x; input is 0x%x"),
   3441   1.1  christos 	 ibfd, out_mach, in_mach);
   3442   1.8  christos       bfd_set_error (bfd_error_wrong_format);
   3443   1.1  christos       return false;
   3444   1.1  christos     }
   3445   1.1  christos 
   3446   1.1  christos   if (! elf_flags_init (obfd))
   3447   1.1  christos     {
   3448   1.1  christos       elf_flags_init (obfd) = true;
   3449   1.1  christos       elf_elfheader (obfd)->e_flags = in_flag;
   3450   1.8  christos 
   3451   1.1  christos       if (bfd_get_arch (obfd) == bfd_get_arch (ibfd)
   3452   1.1  christos 	  && bfd_get_arch_info (obfd)->the_default)
   3453   1.3  christos 	return bfd_set_arch_mach (obfd, bfd_get_arch (ibfd),
   3454   1.1  christos 				  bfd_get_mach (ibfd));
   3455   1.1  christos 
   3456   1.3  christos       return true;
   3457   1.1  christos     }
   3458   1.1  christos 
   3459   1.8  christos   if ((out_flag & EF_XTENSA_XT_INSN) != (in_flag & EF_XTENSA_XT_INSN))
   3460   1.1  christos     elf_elfheader (obfd)->e_flags &= (~ EF_XTENSA_XT_INSN);
   3461   1.1  christos 
   3462   1.1  christos   if ((out_flag & EF_XTENSA_XT_LIT) != (in_flag & EF_XTENSA_XT_LIT))
   3463   1.8  christos     elf_elfheader (obfd)->e_flags &= (~ EF_XTENSA_XT_LIT);
   3464   1.1  christos 
   3465   1.1  christos   return true;
   3466   1.1  christos }
   3467   1.1  christos 
   3468   1.1  christos 
   3469   1.1  christos static bool
   3470   1.8  christos elf_xtensa_set_private_flags (bfd *abfd, flagword flags)
   3471   1.1  christos {
   3472   1.8  christos   BFD_ASSERT (!elf_flags_init (abfd)
   3473   1.1  christos 	      || elf_elfheader (abfd)->e_flags == flags);
   3474   1.1  christos 
   3475   1.1  christos   elf_elfheader (abfd)->e_flags |= flags;
   3476   1.8  christos   elf_flags_init (abfd) = true;
   3477   1.1  christos 
   3478   1.1  christos   return true;
   3479   1.1  christos }
   3480   1.1  christos 
   3481   1.1  christos 
   3482   1.1  christos static bool
   3483   1.1  christos elf_xtensa_print_private_bfd_data (bfd *abfd, void *farg)
   3484   1.1  christos {
   3485   1.1  christos   FILE *f = (FILE *) farg;
   3486   1.1  christos   flagword e_flags = elf_elfheader (abfd)->e_flags;
   3487   1.1  christos 
   3488   1.1  christos   fprintf (f, "\nXtensa header:\n");
   3489   1.1  christos   if ((e_flags & EF_XTENSA_MACH) == E_XTENSA_MACH)
   3490   1.1  christos     fprintf (f, "\nMachine     = Base\n");
   3491   1.1  christos   else
   3492   1.1  christos     fprintf (f, "\nMachine Id  = 0x%x\n", e_flags & EF_XTENSA_MACH);
   3493   1.1  christos 
   3494   1.1  christos   fprintf (f, "Insn tables = %s\n",
   3495   1.1  christos 	   (e_flags & EF_XTENSA_XT_INSN) ? "true" : "false");
   3496   1.1  christos 
   3497   1.1  christos   fprintf (f, "Literal tables = %s\n",
   3498   1.1  christos 	   (e_flags & EF_XTENSA_XT_LIT) ? "true" : "false");
   3499   1.1  christos 
   3500   1.8  christos   return _bfd_elf_print_private_bfd_data (abfd, farg);
   3501   1.1  christos }
   3502   1.1  christos 
   3503   1.1  christos 
   3504   1.1  christos /* Set the right machine number for an Xtensa ELF file.  */
   3505   1.1  christos 
   3506   1.1  christos static bool
   3507   1.1  christos elf_xtensa_object_p (bfd *abfd)
   3508   1.1  christos {
   3509   1.1  christos   int mach;
   3510   1.1  christos   unsigned long arch = elf_elfheader (abfd)->e_flags & EF_XTENSA_MACH;
   3511   1.1  christos 
   3512   1.8  christos   switch (arch)
   3513   1.1  christos     {
   3514   1.1  christos     case E_XTENSA_MACH:
   3515   1.1  christos       mach = bfd_mach_xtensa;
   3516   1.8  christos       break;
   3517   1.1  christos     default:
   3518   1.1  christos       return false;
   3519   1.1  christos     }
   3520   1.1  christos 
   3521   1.1  christos   (void) bfd_default_set_arch_mach (abfd, bfd_arch_xtensa, mach);
   3522   1.1  christos   return true;
   3523   1.1  christos }
   3524   1.8  christos 
   3525   1.7  christos 
   3526   1.1  christos /* The final processing done just before writing out an Xtensa ELF object
   3527   1.1  christos    file.  This gets the Xtensa architecture right based on the machine
   3528   1.7  christos    number.  */
   3529   1.1  christos 
   3530   1.1  christos static bool
   3531   1.1  christos elf_xtensa_final_write_processing (bfd *abfd)
   3532   1.1  christos {
   3533   1.1  christos   int mach;
   3534   1.1  christos   unsigned long val = elf_elfheader (abfd)->e_flags & EF_XTENSA_MACH;
   3535   1.1  christos 
   3536   1.7  christos   switch (mach = bfd_get_mach (abfd))
   3537   1.1  christos     {
   3538   1.1  christos     case bfd_mach_xtensa:
   3539   1.7  christos       val = E_XTENSA_MACH;
   3540   1.1  christos       break;
   3541   1.7  christos     default:
   3542   1.1  christos       break;
   3543   1.1  christos     }
   3544   1.1  christos 
   3545   1.1  christos   elf_elfheader (abfd)->e_flags &= ~EF_XTENSA_MACH;
   3546   1.3  christos   elf_elfheader (abfd)->e_flags |= val;
   3547   1.3  christos   return _bfd_elf_final_write_processing (abfd);
   3548   1.3  christos }
   3549   1.1  christos 
   3550   1.1  christos 
   3551   1.1  christos static enum elf_reloc_type_class
   3552   1.1  christos elf_xtensa_reloc_type_class (const struct bfd_link_info *info ATTRIBUTE_UNUSED,
   3553   1.1  christos 			     const asection *rel_sec ATTRIBUTE_UNUSED,
   3554   1.1  christos 			     const Elf_Internal_Rela *rela)
   3555   1.1  christos {
   3556   1.1  christos   switch ((int) ELF32_R_TYPE (rela->r_info))
   3557   1.1  christos     {
   3558   1.1  christos     case R_XTENSA_RELATIVE:
   3559   1.1  christos       return reloc_class_relative;
   3560   1.1  christos     case R_XTENSA_JMP_SLOT:
   3561   1.1  christos       return reloc_class_plt;
   3562   1.8  christos     default:
   3563   1.1  christos       return reloc_class_normal;
   3564   1.1  christos     }
   3565   1.1  christos }
   3566   1.1  christos 
   3567   1.1  christos 
   3568   1.1  christos static bool
   3570   1.1  christos elf_xtensa_discard_info_for_section (bfd *abfd,
   3571   1.1  christos 				     struct elf_reloc_cookie *cookie,
   3572   1.1  christos 				     struct bfd_link_info *info,
   3573   1.1  christos 				     asection *sec)
   3574   1.1  christos {
   3575   1.8  christos   bfd_byte *contents;
   3576   1.1  christos   bfd_vma offset, actual_offset;
   3577   1.1  christos   bfd_size_type removed_bytes = 0;
   3578   1.1  christos   bfd_size_type entry_size;
   3579   1.1  christos 
   3580   1.1  christos   if (sec->output_section
   3581   1.1  christos       && bfd_is_abs_section (sec->output_section))
   3582   1.1  christos     return false;
   3583   1.8  christos 
   3584   1.1  christos   if (xtensa_is_proptable_section (sec))
   3585   1.1  christos     entry_size = 12;
   3586   1.1  christos   else
   3587   1.8  christos     entry_size = 8;
   3588   1.1  christos 
   3589   1.1  christos   if (sec->size == 0 || sec->size % entry_size != 0)
   3590   1.1  christos     return false;
   3591   1.1  christos 
   3592   1.1  christos   contents = retrieve_contents (abfd, sec, info->keep_memory);
   3593   1.8  christos   if (!contents)
   3594   1.1  christos     return false;
   3595   1.1  christos 
   3596   1.1  christos   cookie->rels = retrieve_internal_relocs (abfd, sec, info->keep_memory);
   3597   1.1  christos   if (!cookie->rels)
   3598   1.1  christos     {
   3599   1.1  christos       release_contents (sec, contents);
   3600   1.1  christos       return false;
   3601   1.1  christos     }
   3602   1.1  christos 
   3603   1.1  christos   /* Sort the relocations.  They should already be in order when
   3604   1.1  christos      relaxation is enabled, but it might not be.  */
   3605   1.1  christos   qsort (cookie->rels, sec->reloc_count, sizeof (Elf_Internal_Rela),
   3606   1.1  christos 	 internal_reloc_compare);
   3607   1.1  christos 
   3608   1.1  christos   cookie->rel = cookie->rels;
   3609   1.1  christos   cookie->relend = cookie->rels + sec->reloc_count;
   3610   1.1  christos 
   3611   1.1  christos   for (offset = 0; offset < sec->size; offset += entry_size)
   3612   1.1  christos     {
   3613   1.1  christos       actual_offset = offset - removed_bytes;
   3614   1.1  christos 
   3615   1.1  christos       /* The ...symbol_deleted_p function will skip over relocs but it
   3616   1.1  christos 	 won't adjust their offsets, so do that here.  */
   3617   1.1  christos       while (cookie->rel < cookie->relend
   3618   1.1  christos 	     && cookie->rel->r_offset < offset)
   3619   1.1  christos 	{
   3620   1.1  christos 	  cookie->rel->r_offset -= removed_bytes;
   3621   1.1  christos 	  cookie->rel++;
   3622   1.1  christos 	}
   3623   1.1  christos 
   3624   1.1  christos       while (cookie->rel < cookie->relend
   3625   1.1  christos 	     && cookie->rel->r_offset == offset)
   3626   1.1  christos 	{
   3627   1.1  christos 	  if (bfd_elf_reloc_symbol_deleted_p (offset, cookie))
   3628   1.1  christos 	    {
   3629   1.1  christos 	      /* Remove the table entry.  (If the reloc type is NONE, then
   3630   1.1  christos 		 the entry has already been merged with another and deleted
   3631   1.1  christos 		 during relaxation.)  */
   3632   1.1  christos 	      if (ELF32_R_TYPE (cookie->rel->r_info) != R_XTENSA_NONE)
   3633   1.1  christos 		{
   3634   1.1  christos 		  /* Shift the contents up.  */
   3635   1.1  christos 		  if (offset + entry_size < sec->size)
   3636   1.1  christos 		    memmove (&contents[actual_offset],
   3637   1.1  christos 			     &contents[actual_offset + entry_size],
   3638   1.1  christos 			     sec->size - offset - entry_size);
   3639   1.1  christos 		  removed_bytes += entry_size;
   3640   1.1  christos 		}
   3641   1.1  christos 
   3642   1.1  christos 	      /* Remove this relocation.  */
   3643   1.1  christos 	      cookie->rel->r_info = ELF32_R_INFO (0, R_XTENSA_NONE);
   3644   1.1  christos 	    }
   3645   1.1  christos 
   3646   1.1  christos 	  /* Adjust the relocation offset for previous removals.  This
   3647   1.1  christos 	     should not be done before calling ...symbol_deleted_p
   3648   1.1  christos 	     because it might mess up the offset comparisons there.
   3649   1.1  christos 	     Make sure the offset doesn't underflow in the case where
   3650   1.1  christos 	     the first entry is removed.  */
   3651   1.1  christos 	  if (cookie->rel->r_offset >= removed_bytes)
   3652   1.1  christos 	    cookie->rel->r_offset -= removed_bytes;
   3653   1.1  christos 	  else
   3654   1.1  christos 	    cookie->rel->r_offset = 0;
   3655   1.1  christos 
   3656   1.1  christos 	  cookie->rel++;
   3657   1.1  christos 	}
   3658   1.1  christos     }
   3659   1.1  christos 
   3660   1.1  christos   if (removed_bytes != 0)
   3661   1.1  christos     {
   3662   1.1  christos       /* Adjust any remaining relocs (shouldn't be any).  */
   3663   1.1  christos       for (; cookie->rel < cookie->relend; cookie->rel++)
   3664   1.1  christos 	{
   3665   1.1  christos 	  if (cookie->rel->r_offset >= removed_bytes)
   3666   1.1  christos 	    cookie->rel->r_offset -= removed_bytes;
   3667   1.1  christos 	  else
   3668   1.1  christos 	    cookie->rel->r_offset = 0;
   3669   1.1  christos 	}
   3670   1.1  christos 
   3671   1.1  christos       /* Clear the removed bytes.  */
   3672   1.1  christos       memset (&contents[sec->size - removed_bytes], 0, removed_bytes);
   3673   1.1  christos 
   3674   1.1  christos       pin_contents (sec, contents);
   3675   1.1  christos       pin_internal_relocs (sec, cookie->rels);
   3676   1.1  christos 
   3677   1.1  christos       /* Shrink size.  */
   3678   1.1  christos       if (sec->rawsize == 0)
   3679   1.1  christos 	sec->rawsize = sec->size;
   3680   1.1  christos       sec->size -= removed_bytes;
   3681   1.1  christos 
   3682   1.1  christos       if (xtensa_is_littable_section (sec))
   3683   1.1  christos 	{
   3684   1.1  christos 	  asection *sgotloc = elf_xtensa_hash_table (info)->sgotloc;
   3685   1.1  christos 	  if (sgotloc)
   3686   1.1  christos 	    sgotloc->size -= removed_bytes;
   3687   1.1  christos 	}
   3688   1.1  christos     }
   3689   1.1  christos   else
   3690   1.1  christos     {
   3691   1.1  christos       release_contents (sec, contents);
   3692   1.8  christos       release_internal_relocs (sec, cookie->rels);
   3693   1.1  christos     }
   3694   1.1  christos 
   3695   1.1  christos   return (removed_bytes != 0);
   3696   1.1  christos }
   3697   1.1  christos 
   3698   1.8  christos 
   3699   1.1  christos static bool
   3700   1.1  christos elf_xtensa_discard_info (bfd *abfd,
   3701   1.1  christos 			 struct elf_reloc_cookie *cookie,
   3702   1.1  christos 			 struct bfd_link_info *info)
   3703   1.1  christos {
   3704   1.1  christos   asection *sec;
   3705   1.8  christos   bool changed = false;
   3706   1.1  christos 
   3707   1.1  christos   for (sec = abfd->sections; sec != NULL; sec = sec->next)
   3708   1.1  christos     {
   3709   1.1  christos       if (xtensa_is_property_section (sec))
   3710   1.1  christos 	{
   3711   1.1  christos 	  if (elf_xtensa_discard_info_for_section (abfd, cookie, info, sec))
   3712   1.1  christos 	    changed = true;
   3713   1.8  christos 	}
   3714   1.1  christos     }
   3715   1.1  christos 
   3716   1.1  christos   return changed;
   3717   1.1  christos }
   3718   1.1  christos 
   3719   1.1  christos 
   3720   1.1  christos static bool
   3721   1.1  christos elf_xtensa_ignore_discarded_relocs (asection *sec)
   3722   1.1  christos {
   3723   1.1  christos   return xtensa_is_property_section (sec);
   3724   1.1  christos }
   3725   1.1  christos 
   3726   1.1  christos 
   3727   1.1  christos static unsigned int
   3728   1.1  christos elf_xtensa_action_discarded (asection *sec)
   3729   1.1  christos {
   3730   1.1  christos   if (strcmp (".xt_except_table", sec->name) == 0)
   3731   1.1  christos     return 0;
   3732   1.1  christos 
   3733   1.1  christos   if (strcmp (".xt_except_desc", sec->name) == 0)
   3734   1.1  christos     return 0;
   3735   1.8  christos 
   3736   1.1  christos   return _bfd_elf_default_action_discarded (sec);
   3737   1.1  christos }
   3738   1.1  christos 
   3739   1.1  christos 
   3740   1.1  christos /* Support for core dump NOTE sections.  */
   3742   1.8  christos 
   3743   1.8  christos static bool
   3744   1.8  christos elf_xtensa_grok_prstatus (bfd *abfd, Elf_Internal_Note *note)
   3745   1.1  christos {
   3746   1.1  christos   int offset;
   3747   1.8  christos   unsigned int size;
   3748   1.8  christos 
   3749   1.1  christos   if (elf_tdata (abfd) == NULL
   3750   1.1  christos       || elf_tdata (abfd)->core == NULL)
   3751   1.3  christos     return false;
   3752   1.1  christos 
   3753   1.1  christos   /* The size for Xtensa is variable, so don't try to recognize the format
   3754   1.3  christos      based on the size.  Just assume this is GNU/Linux.  */
   3755   1.1  christos   if (note == NULL || note->descsz < 28)
   3756   1.1  christos     return false;
   3757   1.1  christos 
   3758   1.1  christos   /* pr_cursig */
   3759   1.1  christos   elf_tdata (abfd)->core->signal = bfd_get_16 (abfd, note->descdata + 12);
   3760   1.1  christos 
   3761   1.1  christos   /* pr_pid */
   3762   1.1  christos   elf_tdata (abfd)->core->lwpid = bfd_get_32 (abfd, note->descdata + 24);
   3763   1.1  christos 
   3764   1.1  christos   /* pr_reg */
   3765   1.8  christos   offset = 72;
   3766   1.1  christos   size = note->descsz - offset - 4;
   3767   1.1  christos 
   3768   1.1  christos   /* Make a ".reg/999" section.  */
   3769   1.1  christos   return _bfd_elfcore_make_pseudosection (abfd, ".reg",
   3770   1.1  christos 					  size, note->descpos + offset);
   3771   1.8  christos }
   3772   1.1  christos 
   3773   1.1  christos static bool
   3774   1.3  christos elf_xtensa_grok_psinfo (bfd *abfd, Elf_Internal_Note *note)
   3775   1.1  christos {
   3776   1.3  christos   switch (note->descsz)
   3777   1.1  christos     {
   3778   1.1  christos       default:
   3779   1.1  christos 	return false;
   3780   1.1  christos 
   3781   1.1  christos       case 128:		/* GNU/Linux elf_prpsinfo */
   3782   1.1  christos 	elf_tdata (abfd)->core->program
   3783   1.1  christos 	 = _bfd_elfcore_strndup (abfd, note->descdata + 32, 16);
   3784   1.1  christos 	elf_tdata (abfd)->core->command
   3785   1.3  christos 	 = _bfd_elfcore_strndup (abfd, note->descdata + 48, 80);
   3786   1.1  christos     }
   3787   1.1  christos 
   3788   1.1  christos   /* Note that for some reason, a spurious space is tacked
   3789   1.1  christos      onto the end of the args in some (at least one anyway)
   3790   1.1  christos      implementations, so strip it off if it exists.  */
   3791   1.1  christos 
   3792   1.8  christos   {
   3793   1.1  christos     char *command = elf_tdata (abfd)->core->command;
   3794   1.1  christos     int n = strlen (command);
   3795   1.1  christos 
   3796   1.1  christos     if (0 < n && command[n - 1] == ' ')
   3797   1.1  christos       command[n - 1] = '\0';
   3798   1.1  christos   }
   3799   1.1  christos 
   3800   1.1  christos   return true;
   3801   1.1  christos }
   3802   1.1  christos 
   3803   1.1  christos 
   3804   1.1  christos /* Generic Xtensa configurability stuff.  */
   3806   1.1  christos 
   3807   1.1  christos static xtensa_opcode callx0_op = XTENSA_UNDEFINED;
   3808   1.1  christos static xtensa_opcode callx4_op = XTENSA_UNDEFINED;
   3809   1.1  christos static xtensa_opcode callx8_op = XTENSA_UNDEFINED;
   3810   1.1  christos static xtensa_opcode callx12_op = XTENSA_UNDEFINED;
   3811   1.1  christos static xtensa_opcode call0_op = XTENSA_UNDEFINED;
   3812   1.1  christos static xtensa_opcode call4_op = XTENSA_UNDEFINED;
   3813   1.1  christos static xtensa_opcode call8_op = XTENSA_UNDEFINED;
   3814   1.1  christos static xtensa_opcode call12_op = XTENSA_UNDEFINED;
   3815   1.1  christos 
   3816   1.1  christos static void
   3817   1.1  christos init_call_opcodes (void)
   3818   1.1  christos {
   3819   1.1  christos   if (callx0_op == XTENSA_UNDEFINED)
   3820   1.1  christos     {
   3821   1.1  christos       callx0_op  = xtensa_opcode_lookup (xtensa_default_isa, "callx0");
   3822   1.1  christos       callx4_op  = xtensa_opcode_lookup (xtensa_default_isa, "callx4");
   3823   1.1  christos       callx8_op  = xtensa_opcode_lookup (xtensa_default_isa, "callx8");
   3824   1.8  christos       callx12_op = xtensa_opcode_lookup (xtensa_default_isa, "callx12");
   3825   1.1  christos       call0_op   = xtensa_opcode_lookup (xtensa_default_isa, "call0");
   3826   1.1  christos       call4_op   = xtensa_opcode_lookup (xtensa_default_isa, "call4");
   3827   1.1  christos       call8_op   = xtensa_opcode_lookup (xtensa_default_isa, "call8");
   3828   1.1  christos       call12_op  = xtensa_opcode_lookup (xtensa_default_isa, "call12");
   3829   1.1  christos     }
   3830   1.1  christos }
   3831   1.1  christos 
   3832   1.1  christos 
   3833   1.1  christos static bool
   3834   1.1  christos is_indirect_call_opcode (xtensa_opcode opcode)
   3835   1.8  christos {
   3836   1.1  christos   init_call_opcodes ();
   3837   1.1  christos   return (opcode == callx0_op
   3838   1.1  christos 	  || opcode == callx4_op
   3839   1.1  christos 	  || opcode == callx8_op
   3840   1.1  christos 	  || opcode == callx12_op);
   3841   1.1  christos }
   3842   1.1  christos 
   3843   1.1  christos 
   3844   1.1  christos static bool
   3845   1.1  christos is_direct_call_opcode (xtensa_opcode opcode)
   3846   1.8  christos {
   3847   1.1  christos   init_call_opcodes ();
   3848   1.1  christos   return (opcode == call0_op
   3849   1.1  christos 	  || opcode == call4_op
   3850   1.1  christos 	  || opcode == call8_op
   3851   1.1  christos 	  || opcode == call12_op);
   3852   1.1  christos }
   3853   1.1  christos 
   3854   1.1  christos 
   3855   1.1  christos static bool
   3856   1.1  christos is_windowed_call_opcode (xtensa_opcode opcode)
   3857   1.1  christos {
   3858   1.1  christos   init_call_opcodes ();
   3859   1.8  christos   return (opcode == call4_op
   3860   1.1  christos 	  || opcode == call8_op
   3861   1.1  christos 	  || opcode == call12_op
   3862   1.1  christos 	  || opcode == callx4_op
   3863   1.1  christos 	  || opcode == callx8_op
   3864   1.1  christos 	  || opcode == callx12_op);
   3865   1.1  christos }
   3866   1.1  christos 
   3867   1.1  christos 
   3868   1.1  christos static bool
   3869   1.1  christos get_indirect_call_dest_reg (xtensa_opcode opcode, unsigned *pdst)
   3870   1.1  christos {
   3871   1.1  christos   unsigned dst = (unsigned) -1;
   3872   1.1  christos 
   3873   1.1  christos   init_call_opcodes ();
   3874   1.1  christos   if (opcode == callx0_op)
   3875   1.8  christos     dst = 0;
   3876   1.1  christos   else if (opcode == callx4_op)
   3877   1.1  christos     dst = 4;
   3878   1.8  christos   else if (opcode == callx8_op)
   3879   1.1  christos     dst = 8;
   3880   1.1  christos   else if (opcode == callx12_op)
   3881   1.1  christos     dst = 12;
   3882   1.1  christos 
   3883   1.1  christos   if (dst == (unsigned) -1)
   3884   1.1  christos     return false;
   3885   1.8  christos 
   3886   1.1  christos   *pdst = dst;
   3887   1.1  christos   return true;
   3888   1.1  christos }
   3889   1.1  christos 
   3890   1.8  christos 
   3891   1.1  christos static xtensa_opcode
   3892   1.1  christos get_const16_opcode (void)
   3893   1.1  christos {
   3894   1.1  christos   static bool done_lookup = false;
   3895   1.1  christos   static xtensa_opcode const16_opcode = XTENSA_UNDEFINED;
   3896   1.1  christos   if (!done_lookup)
   3897   1.1  christos     {
   3898   1.1  christos       const16_opcode = xtensa_opcode_lookup (xtensa_default_isa, "const16");
   3899   1.1  christos       done_lookup = true;
   3900   1.8  christos     }
   3901   1.1  christos   return const16_opcode;
   3902   1.1  christos }
   3903   1.1  christos 
   3904   1.1  christos 
   3905   1.8  christos static xtensa_opcode
   3906   1.1  christos get_l32r_opcode (void)
   3907   1.1  christos {
   3908   1.1  christos   static xtensa_opcode l32r_opcode = XTENSA_UNDEFINED;
   3909   1.1  christos   static bool done_lookup = false;
   3910   1.1  christos 
   3911   1.1  christos   if (!done_lookup)
   3912   1.1  christos     {
   3913   1.1  christos       l32r_opcode = xtensa_opcode_lookup (xtensa_default_isa, "l32r");
   3914   1.1  christos       done_lookup = true;
   3915   1.1  christos     }
   3916   1.1  christos   return l32r_opcode;
   3917   1.1  christos }
   3918   1.1  christos 
   3919   1.1  christos 
   3920   1.1  christos static bfd_vma
   3921   1.1  christos l32r_offset (bfd_vma addr, bfd_vma pc)
   3922   1.1  christos {
   3923   1.1  christos   bfd_vma offset;
   3924   1.7  christos 
   3925   1.7  christos   offset = addr - ((pc+3) & -4);
   3926   1.7  christos   BFD_ASSERT ((offset & ((1 << 2) - 1)) == 0);
   3927   1.7  christos   offset = (signed int) offset >> 2;
   3928   1.8  christos   BFD_ASSERT ((signed int) offset >> 16 == -1);
   3929   1.7  christos   return offset;
   3930   1.7  christos }
   3931   1.7  christos 
   3932   1.8  christos 
   3933   1.7  christos static xtensa_opcode
   3934   1.7  christos get_rsr_lend_opcode (void)
   3935   1.7  christos {
   3936   1.7  christos   static xtensa_opcode rsr_lend_opcode = XTENSA_UNDEFINED;
   3937   1.7  christos   static bool done_lookup = false;
   3938   1.7  christos   if (!done_lookup)
   3939   1.7  christos     {
   3940   1.7  christos       rsr_lend_opcode = xtensa_opcode_lookup (xtensa_default_isa, "rsr.lend");
   3941   1.8  christos       done_lookup = true;
   3942   1.7  christos     }
   3943   1.7  christos   return rsr_lend_opcode;
   3944   1.7  christos }
   3945   1.8  christos 
   3946   1.7  christos static xtensa_opcode
   3947   1.7  christos get_wsr_lbeg_opcode (void)
   3948   1.7  christos {
   3949   1.7  christos   static xtensa_opcode wsr_lbeg_opcode = XTENSA_UNDEFINED;
   3950   1.7  christos   static bool done_lookup = false;
   3951   1.1  christos   if (!done_lookup)
   3952   1.1  christos     {
   3953   1.1  christos       wsr_lbeg_opcode = xtensa_opcode_lookup (xtensa_default_isa, "wsr.lbeg");
   3954   1.1  christos       done_lookup = true;
   3955   1.1  christos     }
   3956   1.1  christos   return wsr_lbeg_opcode;
   3957   1.1  christos }
   3958   1.1  christos 
   3959   1.1  christos 
   3960   1.1  christos static int
   3961   1.1  christos get_relocation_opnd (xtensa_opcode opcode, int r_type)
   3962   1.1  christos {
   3963   1.1  christos   xtensa_isa isa = xtensa_default_isa;
   3964   1.1  christos   int last_immed, last_opnd, opi;
   3965   1.1  christos 
   3966   1.1  christos   if (opcode == XTENSA_UNDEFINED)
   3967   1.1  christos     return XTENSA_UNDEFINED;
   3968   1.1  christos 
   3969   1.1  christos   /* Find the last visible PC-relative immediate operand for the opcode.
   3970   1.1  christos      If there are no PC-relative immediates, then choose the last visible
   3971   1.1  christos      immediate; otherwise, fail and return XTENSA_UNDEFINED.  */
   3972   1.1  christos   last_immed = XTENSA_UNDEFINED;
   3973   1.1  christos   last_opnd = xtensa_opcode_num_operands (isa, opcode);
   3974   1.1  christos   for (opi = last_opnd - 1; opi >= 0; opi--)
   3975   1.1  christos     {
   3976   1.1  christos       if (xtensa_operand_is_visible (isa, opcode, opi) == 0)
   3977   1.1  christos 	continue;
   3978   1.1  christos       if (xtensa_operand_is_PCrelative (isa, opcode, opi) == 1)
   3979   1.1  christos 	{
   3980   1.1  christos 	  last_immed = opi;
   3981   1.1  christos 	  break;
   3982   1.1  christos 	}
   3983   1.1  christos       if (last_immed == XTENSA_UNDEFINED
   3984   1.1  christos 	  && xtensa_operand_is_register (isa, opcode, opi) == 0)
   3985   1.1  christos 	last_immed = opi;
   3986   1.1  christos     }
   3987   1.1  christos   if (last_immed < 0)
   3988   1.1  christos     return XTENSA_UNDEFINED;
   3989   1.1  christos 
   3990   1.1  christos   /* If the operand number was specified in an old-style relocation,
   3991   1.1  christos      check for consistency with the operand computed above.  */
   3992   1.1  christos   if (r_type >= R_XTENSA_OP0 && r_type <= R_XTENSA_OP2)
   3993   1.1  christos     {
   3994   1.1  christos       int reloc_opnd = r_type - R_XTENSA_OP0;
   3995   1.1  christos       if (reloc_opnd != last_immed)
   3996   1.1  christos 	return XTENSA_UNDEFINED;
   3997   1.1  christos     }
   3998   1.1  christos 
   3999   1.1  christos   return last_immed;
   4000   1.1  christos }
   4001   1.1  christos 
   4002   1.1  christos 
   4003   1.1  christos int
   4004   1.1  christos get_relocation_slot (int r_type)
   4005   1.1  christos {
   4006   1.1  christos   switch (r_type)
   4007   1.1  christos     {
   4008   1.1  christos     case R_XTENSA_OP0:
   4009   1.1  christos     case R_XTENSA_OP1:
   4010   1.1  christos     case R_XTENSA_OP2:
   4011   1.1  christos       return 0;
   4012   1.1  christos 
   4013   1.1  christos     default:
   4014   1.1  christos       if (r_type >= R_XTENSA_SLOT0_OP && r_type <= R_XTENSA_SLOT14_OP)
   4015   1.1  christos 	return r_type - R_XTENSA_SLOT0_OP;
   4016   1.1  christos       if (r_type >= R_XTENSA_SLOT0_ALT && r_type <= R_XTENSA_SLOT14_ALT)
   4017   1.1  christos 	return r_type - R_XTENSA_SLOT0_ALT;
   4018   1.1  christos       break;
   4019   1.1  christos     }
   4020   1.1  christos 
   4021   1.1  christos   return XTENSA_UNDEFINED;
   4022   1.1  christos }
   4023   1.1  christos 
   4024   1.1  christos 
   4025   1.1  christos /* Get the opcode for a relocation.  */
   4026   1.1  christos 
   4027   1.1  christos static xtensa_opcode
   4028   1.1  christos get_relocation_opcode (bfd *abfd,
   4029   1.1  christos 		       asection *sec,
   4030   1.1  christos 		       bfd_byte *contents,
   4031   1.1  christos 		       Elf_Internal_Rela *irel)
   4032   1.1  christos {
   4033   1.1  christos   static xtensa_insnbuf ibuff = NULL;
   4034   1.1  christos   static xtensa_insnbuf sbuff = NULL;
   4035   1.1  christos   xtensa_isa isa = xtensa_default_isa;
   4036   1.1  christos   xtensa_format fmt;
   4037   1.1  christos   int slot;
   4038   1.1  christos 
   4039   1.1  christos   if (contents == NULL)
   4040   1.1  christos     return XTENSA_UNDEFINED;
   4041   1.1  christos 
   4042   1.1  christos   if (bfd_get_section_limit (abfd, sec) <= irel->r_offset)
   4043   1.1  christos     return XTENSA_UNDEFINED;
   4044   1.1  christos 
   4045   1.1  christos   if (ibuff == NULL)
   4046   1.1  christos     {
   4047   1.1  christos       ibuff = xtensa_insnbuf_alloc (isa);
   4048   1.1  christos       sbuff = xtensa_insnbuf_alloc (isa);
   4049   1.1  christos     }
   4050   1.1  christos 
   4051   1.1  christos   /* Decode the instruction.  */
   4052   1.1  christos   xtensa_insnbuf_from_chars (isa, ibuff, &contents[irel->r_offset],
   4053   1.1  christos 			     sec->size - irel->r_offset);
   4054   1.8  christos   fmt = xtensa_format_decode (isa, ibuff);
   4055   1.1  christos   slot = get_relocation_slot (ELF32_R_TYPE (irel->r_info));
   4056   1.1  christos   if (slot == XTENSA_UNDEFINED)
   4057   1.1  christos     return XTENSA_UNDEFINED;
   4058   1.1  christos   xtensa_format_get_slot (isa, fmt, slot, ibuff, sbuff);
   4059   1.1  christos   return xtensa_opcode_decode (isa, fmt, slot, sbuff);
   4060   1.1  christos }
   4061   1.1  christos 
   4062   1.8  christos 
   4063   1.1  christos bool
   4064   1.1  christos is_l32r_relocation (bfd *abfd,
   4065   1.1  christos 		    asection *sec,
   4066   1.1  christos 		    bfd_byte *contents,
   4067   1.1  christos 		    Elf_Internal_Rela *irel)
   4068   1.1  christos {
   4069   1.1  christos   xtensa_opcode opcode;
   4070   1.1  christos   if (!is_operand_relocation (ELF32_R_TYPE (irel->r_info)))
   4071   1.1  christos     return false;
   4072   1.1  christos   opcode = get_relocation_opcode (abfd, sec, contents, irel);
   4073   1.1  christos   return (opcode == get_l32r_opcode ());
   4074   1.1  christos }
   4075   1.1  christos 
   4076   1.1  christos 
   4077   1.1  christos static bfd_size_type
   4078   1.1  christos get_asm_simplify_size (bfd_byte *contents,
   4079   1.1  christos 		       bfd_size_type content_len,
   4080   1.1  christos 		       bfd_size_type offset)
   4081   1.3  christos {
   4082   1.1  christos   bfd_size_type insnlen, size = 0;
   4083   1.1  christos 
   4084   1.1  christos   /* Decode the size of the next two instructions.  */
   4085   1.1  christos   insnlen = insn_decode_len (contents, content_len, offset);
   4086   1.1  christos   if (insnlen == 0)
   4087   1.1  christos     return 0;
   4088   1.1  christos 
   4089   1.1  christos   size += insnlen;
   4090   1.1  christos 
   4091   1.8  christos   insnlen = insn_decode_len (contents, content_len, offset + size);
   4092   1.1  christos   if (insnlen == 0)
   4093   1.1  christos     return 0;
   4094   1.1  christos 
   4095   1.1  christos   size += insnlen;
   4096   1.1  christos   return size;
   4097   1.1  christos }
   4098   1.1  christos 
   4099   1.8  christos 
   4100   1.1  christos bool
   4101   1.1  christos is_alt_relocation (int r_type)
   4102   1.1  christos {
   4103   1.1  christos   return (r_type >= R_XTENSA_SLOT0_ALT
   4104   1.1  christos 	  && r_type <= R_XTENSA_SLOT14_ALT);
   4105   1.1  christos }
   4106   1.1  christos 
   4107   1.8  christos 
   4108   1.1  christos bool
   4109   1.1  christos is_operand_relocation (int r_type)
   4110   1.1  christos {
   4111   1.8  christos   switch (r_type)
   4112   1.1  christos     {
   4113   1.8  christos     case R_XTENSA_OP0:
   4114   1.1  christos     case R_XTENSA_OP1:
   4115   1.1  christos     case R_XTENSA_OP2:
   4116   1.1  christos       return true;
   4117   1.8  christos 
   4118   1.1  christos     default:
   4119   1.1  christos       if (r_type >= R_XTENSA_SLOT0_OP && r_type <= R_XTENSA_SLOT14_OP)
   4120   1.3  christos 	return true;
   4121   1.1  christos       if (r_type >= R_XTENSA_SLOT0_ALT && r_type <= R_XTENSA_SLOT14_ALT)
   4122   1.1  christos 	return true;
   4123   1.1  christos       break;
   4124   1.1  christos     }
   4125   1.1  christos 
   4126   1.1  christos   return false;
   4127   1.1  christos }
   4128   1.1  christos 
   4129   1.1  christos 
   4130   1.1  christos #define MIN_INSN_LENGTH 2
   4131   1.1  christos 
   4132   1.1  christos /* Return 0 if it fails to decode.  */
   4133   1.1  christos 
   4134   1.1  christos bfd_size_type
   4135   1.1  christos insn_decode_len (bfd_byte *contents,
   4136   1.1  christos 		 bfd_size_type content_len,
   4137   1.1  christos 		 bfd_size_type offset)
   4138   1.1  christos {
   4139   1.1  christos   int insn_len;
   4140   1.1  christos   xtensa_isa isa = xtensa_default_isa;
   4141   1.1  christos   xtensa_format fmt;
   4142   1.1  christos   static xtensa_insnbuf ibuff = NULL;
   4143   1.1  christos 
   4144   1.1  christos   if (offset + MIN_INSN_LENGTH > content_len)
   4145   1.1  christos     return 0;
   4146   1.1  christos 
   4147   1.1  christos   if (ibuff == NULL)
   4148   1.1  christos     ibuff = xtensa_insnbuf_alloc (isa);
   4149   1.1  christos   xtensa_insnbuf_from_chars (isa, ibuff, &contents[offset],
   4150   1.1  christos 			     content_len - offset);
   4151   1.7  christos   fmt = xtensa_format_decode (isa, ibuff);
   4152   1.7  christos   if (fmt == XTENSA_UNDEFINED)
   4153   1.7  christos     return 0;
   4154   1.7  christos   insn_len = xtensa_format_length (isa, fmt);
   4155   1.7  christos   if (insn_len ==  XTENSA_UNDEFINED)
   4156   1.7  christos     return 0;
   4157   1.7  christos   return insn_len;
   4158   1.7  christos }
   4159   1.7  christos 
   4160   1.7  christos int
   4161   1.7  christos insn_num_slots (bfd_byte *contents,
   4162   1.7  christos 		bfd_size_type content_len,
   4163   1.7  christos 		bfd_size_type offset)
   4164   1.7  christos {
   4165   1.7  christos   xtensa_isa isa = xtensa_default_isa;
   4166   1.7  christos   xtensa_format fmt;
   4167   1.7  christos   static xtensa_insnbuf ibuff = NULL;
   4168   1.7  christos 
   4169   1.7  christos   if (offset + MIN_INSN_LENGTH > content_len)
   4170   1.7  christos     return XTENSA_UNDEFINED;
   4171   1.7  christos 
   4172   1.7  christos   if (ibuff == NULL)
   4173   1.1  christos     ibuff = xtensa_insnbuf_alloc (isa);
   4174   1.1  christos   xtensa_insnbuf_from_chars (isa, ibuff, &contents[offset],
   4175   1.1  christos 			     content_len - offset);
   4176   1.1  christos   fmt = xtensa_format_decode (isa, ibuff);
   4177   1.1  christos   if (fmt == XTENSA_UNDEFINED)
   4178   1.1  christos     return XTENSA_UNDEFINED;
   4179   1.1  christos   return xtensa_format_num_slots (isa, fmt);
   4180   1.1  christos }
   4181   1.1  christos 
   4182   1.1  christos 
   4183   1.1  christos /* Decode the opcode for a single slot instruction.
   4184   1.1  christos    Return 0 if it fails to decode or the instruction is multi-slot.  */
   4185   1.1  christos 
   4186   1.1  christos xtensa_opcode
   4187   1.1  christos insn_decode_opcode (bfd_byte *contents,
   4188   1.1  christos 		    bfd_size_type content_len,
   4189   1.1  christos 		    bfd_size_type offset,
   4190   1.1  christos 		    int slot)
   4191   1.1  christos {
   4192   1.1  christos   xtensa_isa isa = xtensa_default_isa;
   4193   1.1  christos   xtensa_format fmt;
   4194   1.1  christos   static xtensa_insnbuf insnbuf = NULL;
   4195   1.1  christos   static xtensa_insnbuf slotbuf = NULL;
   4196   1.1  christos 
   4197   1.1  christos   if (offset + MIN_INSN_LENGTH > content_len)
   4198   1.1  christos     return XTENSA_UNDEFINED;
   4199   1.1  christos 
   4200   1.1  christos   if (insnbuf == NULL)
   4201   1.1  christos     {
   4202   1.1  christos       insnbuf = xtensa_insnbuf_alloc (isa);
   4203   1.1  christos       slotbuf = xtensa_insnbuf_alloc (isa);
   4204   1.1  christos     }
   4205   1.1  christos 
   4206   1.1  christos   xtensa_insnbuf_from_chars (isa, insnbuf, &contents[offset],
   4207   1.1  christos 			     content_len - offset);
   4208   1.1  christos   fmt = xtensa_format_decode (isa, insnbuf);
   4209   1.1  christos   if (fmt == XTENSA_UNDEFINED)
   4210   1.1  christos     return XTENSA_UNDEFINED;
   4211   1.1  christos 
   4212   1.1  christos   if (slot >= xtensa_format_num_slots (isa, fmt))
   4213   1.1  christos     return XTENSA_UNDEFINED;
   4214   1.8  christos 
   4215   1.1  christos   xtensa_format_get_slot (isa, fmt, slot, insnbuf, slotbuf);
   4216   1.1  christos   return xtensa_opcode_decode (isa, fmt, slot, slotbuf);
   4217   1.1  christos }
   4218   1.1  christos 
   4219   1.1  christos 
   4220   1.1  christos /* The offset is the offset in the contents.
   4221   1.1  christos    The address is the address of that offset.  */
   4222   1.8  christos 
   4223   1.1  christos static bool
   4224   1.1  christos check_branch_target_aligned (bfd_byte *contents,
   4225   1.1  christos 			     bfd_size_type content_length,
   4226   1.1  christos 			     bfd_vma offset,
   4227   1.8  christos 			     bfd_vma address)
   4228   1.1  christos {
   4229   1.1  christos   bfd_size_type insn_len = insn_decode_len (contents, content_length, offset);
   4230   1.1  christos   if (insn_len == 0)
   4231   1.1  christos     return false;
   4232   1.1  christos   return check_branch_target_aligned_address (address, insn_len);
   4233   1.1  christos }
   4234   1.1  christos 
   4235   1.1  christos 
   4236   1.1  christos static bool
   4237   1.1  christos check_loop_aligned (bfd_byte *contents,
   4238   1.1  christos 		    bfd_size_type content_length,
   4239   1.1  christos 		    bfd_vma offset,
   4240   1.8  christos 		    bfd_vma address)
   4241   1.8  christos {
   4242   1.1  christos   bfd_size_type loop_len, insn_len;
   4243   1.3  christos   xtensa_opcode opcode;
   4244   1.1  christos 
   4245   1.1  christos   opcode = insn_decode_opcode (contents, content_length, offset, 0);
   4246   1.1  christos   if (opcode == XTENSA_UNDEFINED
   4247   1.1  christos       || xtensa_opcode_is_loop (xtensa_default_isa, opcode) != 1)
   4248   1.8  christos     {
   4249   1.8  christos       BFD_ASSERT (false);
   4250   1.1  christos       return false;
   4251   1.1  christos     }
   4252   1.7  christos 
   4253   1.7  christos   loop_len = insn_decode_len (contents, content_length, offset);
   4254   1.7  christos   insn_len = insn_decode_len (contents, content_length, offset + loop_len);
   4255   1.7  christos   if (loop_len == 0 || insn_len == 0)
   4256   1.7  christos     {
   4257   1.7  christos       BFD_ASSERT (false);
   4258   1.7  christos       return false;
   4259   1.7  christos     }
   4260   1.7  christos 
   4261   1.7  christos   /* If this is relaxed loop, analyze first instruction of the actual loop
   4262   1.7  christos      body.  It must be at offset 27 from the loop instruction address.  */
   4263   1.7  christos   if (insn_len == 3
   4264   1.7  christos       && insn_num_slots (contents, content_length, offset + loop_len) == 1
   4265   1.7  christos       && insn_decode_opcode (contents, content_length,
   4266   1.1  christos 			     offset + loop_len, 0) == get_rsr_lend_opcode()
   4267   1.1  christos       && insn_decode_len (contents, content_length, offset + loop_len + 3) == 3
   4268   1.1  christos       && insn_num_slots (contents, content_length, offset + loop_len + 3) == 1
   4269   1.1  christos       && insn_decode_opcode (contents, content_length,
   4270   1.8  christos 			     offset + loop_len + 3, 0) == get_wsr_lbeg_opcode())
   4271   1.1  christos     {
   4272   1.1  christos       loop_len = 27;
   4273   1.1  christos       insn_len = insn_decode_len (contents, content_length, offset + loop_len);
   4274   1.1  christos     }
   4275   1.1  christos   return check_branch_target_aligned_address (address + loop_len, insn_len);
   4276   1.1  christos }
   4277   1.1  christos 
   4278   1.1  christos 
   4279   1.1  christos static bool
   4280   1.1  christos check_branch_target_aligned_address (bfd_vma addr, int len)
   4281   1.1  christos {
   4282   1.1  christos   if (len == 8)
   4283   1.1  christos     return (addr % 8 == 0);
   4284   1.1  christos   return ((addr >> 2) == ((addr + len - 1) >> 2));
   4285   1.1  christos }
   4286   1.1  christos 
   4287   1.1  christos 
   4288   1.1  christos /* Instruction widening and narrowing.  */
   4290   1.1  christos 
   4291   1.1  christos /* When FLIX is available we need to access certain instructions only
   4292   1.1  christos    when they are 16-bit or 24-bit instructions.  This table caches
   4293   1.1  christos    information about such instructions by walking through all the
   4294   1.1  christos    opcodes and finding the smallest single-slot format into which each
   4295   1.1  christos    can be encoded.  */
   4296   1.1  christos 
   4297   1.1  christos static xtensa_format *op_single_fmt_table = NULL;
   4298   1.1  christos 
   4299   1.1  christos 
   4300   1.1  christos static void
   4301   1.1  christos init_op_single_format_table (void)
   4302   1.1  christos {
   4303   1.1  christos   xtensa_isa isa = xtensa_default_isa;
   4304   1.1  christos   xtensa_insnbuf ibuf;
   4305   1.1  christos   xtensa_opcode opcode;
   4306   1.1  christos   xtensa_format fmt;
   4307   1.1  christos   int num_opcodes;
   4308   1.1  christos 
   4309   1.1  christos   if (op_single_fmt_table)
   4310   1.1  christos     return;
   4311   1.1  christos 
   4312   1.1  christos   ibuf = xtensa_insnbuf_alloc (isa);
   4313   1.1  christos   num_opcodes = xtensa_isa_num_opcodes (isa);
   4314   1.1  christos 
   4315   1.1  christos   op_single_fmt_table = (xtensa_format *)
   4316   1.1  christos     bfd_malloc (sizeof (xtensa_format) * num_opcodes);
   4317   1.1  christos   for (opcode = 0; opcode < num_opcodes; opcode++)
   4318   1.1  christos     {
   4319   1.1  christos       op_single_fmt_table[opcode] = XTENSA_UNDEFINED;
   4320   1.1  christos       for (fmt = 0; fmt < xtensa_isa_num_formats (isa); fmt++)
   4321   1.1  christos 	{
   4322   1.1  christos 	  if (xtensa_format_num_slots (isa, fmt) == 1
   4323   1.1  christos 	      && xtensa_opcode_encode (isa, fmt, 0, ibuf, opcode) == 0)
   4324   1.1  christos 	    {
   4325   1.1  christos 	      xtensa_opcode old_fmt = op_single_fmt_table[opcode];
   4326   1.1  christos 	      int fmt_length = xtensa_format_length (isa, fmt);
   4327   1.1  christos 	      if (old_fmt == XTENSA_UNDEFINED
   4328   1.1  christos 		  || fmt_length < xtensa_format_length (isa, old_fmt))
   4329   1.1  christos 		op_single_fmt_table[opcode] = fmt;
   4330   1.1  christos 	    }
   4331   1.1  christos 	}
   4332   1.1  christos     }
   4333   1.1  christos   xtensa_insnbuf_free (isa, ibuf);
   4334   1.1  christos }
   4335   1.1  christos 
   4336   1.1  christos 
   4337   1.1  christos static xtensa_format
   4338   1.1  christos get_single_format (xtensa_opcode opcode)
   4339   1.1  christos {
   4340   1.1  christos   init_op_single_format_table ();
   4341   1.1  christos   return op_single_fmt_table[opcode];
   4342   1.1  christos }
   4343   1.1  christos 
   4344   1.1  christos 
   4345   1.1  christos /* For the set of narrowable instructions we do NOT include the
   4346   1.1  christos    narrowings beqz -> beqz.n or bnez -> bnez.n because of complexities
   4347   1.8  christos    involved during linker relaxation that may require these to
   4348   1.1  christos    re-expand in some conditions.  Also, the narrowing "or" -> mov.n
   4349   1.1  christos    requires special case code to ensure it only works when op1 == op2.  */
   4350   1.1  christos 
   4351   1.1  christos struct string_pair
   4352   1.1  christos {
   4353   1.1  christos   const char *wide;
   4354   1.1  christos   const char *narrow;
   4355   1.1  christos };
   4356   1.1  christos 
   4357   1.1  christos const struct string_pair narrowable[] =
   4358   1.1  christos {
   4359   1.1  christos   { "add", "add.n" },
   4360   1.8  christos   { "addi", "addi.n" },
   4361   1.1  christos   { "addmi", "addi.n" },
   4362   1.1  christos   { "l32i", "l32i.n" },
   4363   1.1  christos   { "movi", "movi.n" },
   4364   1.1  christos   { "ret", "ret.n" },
   4365   1.1  christos   { "retw", "retw.n" },
   4366   1.1  christos   { "s32i", "s32i.n" },
   4367   1.1  christos   { "or", "mov.n" } /* special case only when op1 == op2 */
   4368   1.1  christos };
   4369   1.1  christos 
   4370   1.1  christos const struct string_pair widenable[] =
   4371   1.1  christos {
   4372   1.1  christos   { "add", "add.n" },
   4373   1.1  christos   { "addi", "addi.n" },
   4374   1.1  christos   { "addmi", "addi.n" },
   4375   1.1  christos   { "beqz", "beqz.n" },
   4376   1.1  christos   { "bnez", "bnez.n" },
   4377   1.1  christos   { "l32i", "l32i.n" },
   4378   1.1  christos   { "movi", "movi.n" },
   4379   1.1  christos   { "ret", "ret.n" },
   4380   1.1  christos   { "retw", "retw.n" },
   4381   1.1  christos   { "s32i", "s32i.n" },
   4382   1.1  christos   { "or", "mov.n" } /* special case only when op1 == op2 */
   4383   1.1  christos };
   4384   1.1  christos 
   4385   1.1  christos 
   4386   1.1  christos /* Check if an instruction can be "narrowed", i.e., changed from a standard
   4387   1.1  christos    3-byte instruction to a 2-byte "density" instruction.  If it is valid,
   4388   1.1  christos    return the instruction buffer holding the narrow instruction.  Otherwise,
   4389   1.1  christos    return 0.  The set of valid narrowing are specified by a string table
   4390   1.1  christos    but require some special case operand checks in some cases.  */
   4391   1.1  christos 
   4392   1.1  christos static xtensa_insnbuf
   4393   1.1  christos can_narrow_instruction (xtensa_insnbuf slotbuf,
   4394   1.1  christos 			xtensa_format fmt,
   4395   1.1  christos 			xtensa_opcode opcode)
   4396   1.1  christos {
   4397   1.1  christos   xtensa_isa isa = xtensa_default_isa;
   4398   1.1  christos   xtensa_format o_fmt;
   4399   1.1  christos   unsigned opi;
   4400   1.1  christos 
   4401   1.1  christos   static xtensa_insnbuf o_insnbuf = NULL;
   4402   1.8  christos   static xtensa_insnbuf o_slotbuf = NULL;
   4403   1.1  christos 
   4404   1.1  christos   if (o_insnbuf == NULL)
   4405   1.1  christos     {
   4406   1.1  christos       o_insnbuf = xtensa_insnbuf_alloc (isa);
   4407   1.1  christos       o_slotbuf = xtensa_insnbuf_alloc (isa);
   4408   1.1  christos     }
   4409   1.1  christos 
   4410   1.1  christos   for (opi = 0; opi < (sizeof (narrowable)/sizeof (struct string_pair)); opi++)
   4411   1.1  christos     {
   4412   1.1  christos       bool is_or = (strcmp ("or", narrowable[opi].wide) == 0);
   4413   1.1  christos 
   4414   1.1  christos       if (opcode == xtensa_opcode_lookup (isa, narrowable[opi].wide))
   4415   1.1  christos 	{
   4416   1.1  christos 	  uint32 value, newval;
   4417   1.1  christos 	  int i, operand_count, o_operand_count;
   4418   1.1  christos 	  xtensa_opcode o_opcode;
   4419   1.1  christos 
   4420   1.1  christos 	  /* Address does not matter in this case.  We might need to
   4421   1.1  christos 	     fix it to handle branches/jumps.  */
   4422   1.1  christos 	  bfd_vma self_address = 0;
   4423   1.1  christos 
   4424   1.1  christos 	  o_opcode = xtensa_opcode_lookup (isa, narrowable[opi].narrow);
   4425   1.1  christos 	  if (o_opcode == XTENSA_UNDEFINED)
   4426   1.1  christos 	    return 0;
   4427   1.1  christos 	  o_fmt = get_single_format (o_opcode);
   4428   1.1  christos 	  if (o_fmt == XTENSA_UNDEFINED)
   4429   1.1  christos 	    return 0;
   4430   1.1  christos 
   4431   1.1  christos 	  if (xtensa_format_length (isa, fmt) != 3
   4432   1.1  christos 	      || xtensa_format_length (isa, o_fmt) != 2)
   4433   1.1  christos 	    return 0;
   4434   1.1  christos 
   4435   1.1  christos 	  xtensa_format_encode (isa, o_fmt, o_insnbuf);
   4436   1.1  christos 	  operand_count = xtensa_opcode_num_operands (isa, opcode);
   4437   1.1  christos 	  o_operand_count = xtensa_opcode_num_operands (isa, o_opcode);
   4438   1.1  christos 
   4439   1.1  christos 	  if (xtensa_opcode_encode (isa, o_fmt, 0, o_slotbuf, o_opcode) != 0)
   4440   1.1  christos 	    return 0;
   4441   1.1  christos 
   4442   1.1  christos 	  if (!is_or)
   4443   1.1  christos 	    {
   4444   1.1  christos 	      if (xtensa_opcode_num_operands (isa, o_opcode) != operand_count)
   4445   1.1  christos 		return 0;
   4446   1.1  christos 	    }
   4447   1.1  christos 	  else
   4448   1.1  christos 	    {
   4449   1.1  christos 	      uint32 rawval0, rawval1, rawval2;
   4450   1.1  christos 
   4451   1.1  christos 	      if (o_operand_count + 1 != operand_count
   4452   1.1  christos 		  || xtensa_operand_get_field (isa, opcode, 0,
   4453   1.1  christos 					       fmt, 0, slotbuf, &rawval0) != 0
   4454   1.1  christos 		  || xtensa_operand_get_field (isa, opcode, 1,
   4455   1.1  christos 					       fmt, 0, slotbuf, &rawval1) != 0
   4456   1.1  christos 		  || xtensa_operand_get_field (isa, opcode, 2,
   4457   1.1  christos 					       fmt, 0, slotbuf, &rawval2) != 0
   4458   1.1  christos 		  || rawval1 != rawval2
   4459   1.1  christos 		  || rawval0 == rawval1 /* it is a nop */)
   4460   1.1  christos 		return 0;
   4461   1.1  christos 	    }
   4462   1.1  christos 
   4463   1.1  christos 	  for (i = 0; i < o_operand_count; ++i)
   4464   1.1  christos 	    {
   4465   1.1  christos 	      if (xtensa_operand_get_field (isa, opcode, i, fmt, 0,
   4466   1.1  christos 					    slotbuf, &value)
   4467   1.1  christos 		  || xtensa_operand_decode (isa, opcode, i, &value))
   4468   1.1  christos 		return 0;
   4469   1.1  christos 
   4470   1.1  christos 	      /* PC-relative branches need adjustment, but
   4471   1.1  christos 		 the PC-rel operand will always have a relocation.  */
   4472   1.1  christos 	      newval = value;
   4473   1.1  christos 	      if (xtensa_operand_do_reloc (isa, o_opcode, i, &newval,
   4474   1.1  christos 					   self_address)
   4475   1.1  christos 		  || xtensa_operand_encode (isa, o_opcode, i, &newval)
   4476   1.1  christos 		  || xtensa_operand_set_field (isa, o_opcode, i, o_fmt, 0,
   4477   1.1  christos 					       o_slotbuf, newval))
   4478   1.1  christos 		return 0;
   4479   1.1  christos 	    }
   4480   1.1  christos 
   4481   1.1  christos 	  if (xtensa_format_set_slot (isa, o_fmt, 0, o_insnbuf, o_slotbuf))
   4482   1.1  christos 	    return 0;
   4483   1.1  christos 
   4484   1.1  christos 	  return o_insnbuf;
   4485   1.8  christos 	}
   4486   1.1  christos     }
   4487   1.1  christos   return 0;
   4488   1.1  christos }
   4489   1.1  christos 
   4490   1.1  christos 
   4491   1.1  christos /* Attempt to narrow an instruction.  If the narrowing is valid, perform
   4492   1.1  christos    the action in-place directly into the contents and return TRUE.  Otherwise,
   4493   1.1  christos    the return value is FALSE and the contents are not modified.  */
   4494   1.1  christos 
   4495   1.1  christos static bool
   4496   1.1  christos narrow_instruction (bfd_byte *contents,
   4497   1.1  christos 		    bfd_size_type content_length,
   4498   1.1  christos 		    bfd_size_type offset)
   4499   1.1  christos {
   4500   1.1  christos   xtensa_opcode opcode;
   4501   1.1  christos   bfd_size_type insn_len;
   4502   1.1  christos   xtensa_isa isa = xtensa_default_isa;
   4503   1.1  christos   xtensa_format fmt;
   4504   1.1  christos   xtensa_insnbuf o_insnbuf;
   4505   1.1  christos 
   4506   1.1  christos   static xtensa_insnbuf insnbuf = NULL;
   4507   1.1  christos   static xtensa_insnbuf slotbuf = NULL;
   4508   1.8  christos 
   4509   1.1  christos   if (insnbuf == NULL)
   4510   1.1  christos     {
   4511   1.1  christos       insnbuf = xtensa_insnbuf_alloc (isa);
   4512   1.1  christos       slotbuf = xtensa_insnbuf_alloc (isa);
   4513   1.1  christos     }
   4514   1.1  christos 
   4515   1.1  christos   BFD_ASSERT (offset < content_length);
   4516   1.8  christos 
   4517   1.1  christos   if (content_length < 2)
   4518   1.1  christos     return false;
   4519   1.8  christos 
   4520   1.1  christos   /* We will hand-code a few of these for a little while.
   4521   1.1  christos      These have all been specified in the assembler aleady.  */
   4522   1.1  christos   xtensa_insnbuf_from_chars (isa, insnbuf, &contents[offset],
   4523   1.8  christos 			     content_length - offset);
   4524   1.1  christos   fmt = xtensa_format_decode (isa, insnbuf);
   4525   1.1  christos   if (xtensa_format_num_slots (isa, fmt) != 1)
   4526   1.8  christos     return false;
   4527   1.1  christos 
   4528   1.1  christos   if (xtensa_format_get_slot (isa, fmt, 0, insnbuf, slotbuf) != 0)
   4529   1.1  christos     return false;
   4530   1.1  christos 
   4531   1.1  christos   opcode = xtensa_opcode_decode (isa, fmt, 0, slotbuf);
   4532   1.1  christos   if (opcode == XTENSA_UNDEFINED)
   4533   1.8  christos     return false;
   4534   1.1  christos   insn_len = xtensa_format_length (isa, fmt);
   4535   1.1  christos   if (insn_len > content_length)
   4536   1.8  christos     return false;
   4537   1.1  christos 
   4538   1.1  christos   o_insnbuf = can_narrow_instruction (slotbuf, fmt, opcode);
   4539   1.1  christos   if (o_insnbuf)
   4540   1.1  christos     {
   4541   1.1  christos       xtensa_insnbuf_to_chars (isa, o_insnbuf, contents + offset,
   4542   1.1  christos 			       content_length - offset);
   4543   1.1  christos       return true;
   4544   1.1  christos     }
   4545   1.1  christos 
   4546   1.1  christos   return false;
   4547   1.1  christos }
   4548   1.1  christos 
   4549   1.1  christos 
   4550   1.1  christos /* Check if an instruction can be "widened", i.e., changed from a 2-byte
   4551   1.1  christos    "density" instruction to a standard 3-byte instruction.  If it is valid,
   4552   1.1  christos    return the instruction buffer holding the wide instruction.  Otherwise,
   4553   1.1  christos    return 0.  The set of valid widenings are specified by a string table
   4554   1.1  christos    but require some special case operand checks in some cases.  */
   4555   1.1  christos 
   4556   1.1  christos static xtensa_insnbuf
   4557   1.1  christos can_widen_instruction (xtensa_insnbuf slotbuf,
   4558   1.1  christos 		       xtensa_format fmt,
   4559   1.1  christos 		       xtensa_opcode opcode)
   4560   1.1  christos {
   4561   1.1  christos   xtensa_isa isa = xtensa_default_isa;
   4562   1.1  christos   xtensa_format o_fmt;
   4563   1.1  christos   unsigned opi;
   4564   1.1  christos 
   4565   1.1  christos   static xtensa_insnbuf o_insnbuf = NULL;
   4566   1.8  christos   static xtensa_insnbuf o_slotbuf = NULL;
   4567   1.8  christos 
   4568   1.8  christos   if (o_insnbuf == NULL)
   4569   1.1  christos     {
   4570   1.1  christos       o_insnbuf = xtensa_insnbuf_alloc (isa);
   4571   1.1  christos       o_slotbuf = xtensa_insnbuf_alloc (isa);
   4572   1.1  christos     }
   4573   1.1  christos 
   4574   1.1  christos   for (opi = 0; opi < (sizeof (widenable)/sizeof (struct string_pair)); opi++)
   4575   1.1  christos     {
   4576   1.1  christos       bool is_or = (strcmp ("or", widenable[opi].wide) == 0);
   4577   1.1  christos       bool is_branch = (strcmp ("beqz", widenable[opi].wide) == 0
   4578   1.1  christos 			|| strcmp ("bnez", widenable[opi].wide) == 0);
   4579   1.1  christos 
   4580   1.1  christos       if (opcode == xtensa_opcode_lookup (isa, widenable[opi].narrow))
   4581   1.1  christos 	{
   4582   1.1  christos 	  uint32 value, newval;
   4583   1.1  christos 	  int i, operand_count, o_operand_count, check_operand_count;
   4584   1.1  christos 	  xtensa_opcode o_opcode;
   4585   1.1  christos 
   4586   1.1  christos 	  /* Address does not matter in this case.  We might need to fix it
   4587   1.1  christos 	     to handle branches/jumps.  */
   4588   1.1  christos 	  bfd_vma self_address = 0;
   4589   1.1  christos 
   4590   1.1  christos 	  o_opcode = xtensa_opcode_lookup (isa, widenable[opi].wide);
   4591   1.1  christos 	  if (o_opcode == XTENSA_UNDEFINED)
   4592   1.1  christos 	    return 0;
   4593   1.1  christos 	  o_fmt = get_single_format (o_opcode);
   4594   1.1  christos 	  if (o_fmt == XTENSA_UNDEFINED)
   4595   1.1  christos 	    return 0;
   4596   1.1  christos 
   4597   1.1  christos 	  if (xtensa_format_length (isa, fmt) != 2
   4598   1.1  christos 	      || xtensa_format_length (isa, o_fmt) != 3)
   4599   1.1  christos 	    return 0;
   4600   1.1  christos 
   4601   1.1  christos 	  xtensa_format_encode (isa, o_fmt, o_insnbuf);
   4602   1.1  christos 	  operand_count = xtensa_opcode_num_operands (isa, opcode);
   4603   1.1  christos 	  o_operand_count = xtensa_opcode_num_operands (isa, o_opcode);
   4604   1.1  christos 	  check_operand_count = o_operand_count;
   4605   1.1  christos 
   4606   1.1  christos 	  if (xtensa_opcode_encode (isa, o_fmt, 0, o_slotbuf, o_opcode) != 0)
   4607   1.1  christos 	    return 0;
   4608   1.1  christos 
   4609   1.1  christos 	  if (!is_or)
   4610   1.1  christos 	    {
   4611   1.1  christos 	      if (xtensa_opcode_num_operands (isa, o_opcode) != operand_count)
   4612   1.1  christos 		return 0;
   4613   1.1  christos 	    }
   4614   1.1  christos 	  else
   4615   1.1  christos 	    {
   4616   1.1  christos 	      uint32 rawval0, rawval1;
   4617   1.1  christos 
   4618   1.1  christos 	      if (o_operand_count != operand_count + 1
   4619   1.1  christos 		  || xtensa_operand_get_field (isa, opcode, 0,
   4620   1.1  christos 					       fmt, 0, slotbuf, &rawval0) != 0
   4621   1.1  christos 		  || xtensa_operand_get_field (isa, opcode, 1,
   4622   1.1  christos 					       fmt, 0, slotbuf, &rawval1) != 0
   4623   1.1  christos 		  || rawval0 == rawval1 /* it is a nop */)
   4624   1.1  christos 		return 0;
   4625   1.1  christos 	    }
   4626   1.1  christos 	  if (is_branch)
   4627   1.1  christos 	    check_operand_count--;
   4628   1.1  christos 
   4629   1.1  christos 	  for (i = 0; i < check_operand_count; i++)
   4630   1.1  christos 	    {
   4631   1.1  christos 	      int new_i = i;
   4632   1.1  christos 	      if (is_or && i == o_operand_count - 1)
   4633   1.1  christos 		new_i = i - 1;
   4634   1.1  christos 	      if (xtensa_operand_get_field (isa, opcode, new_i, fmt, 0,
   4635   1.1  christos 					    slotbuf, &value)
   4636   1.1  christos 		  || xtensa_operand_decode (isa, opcode, new_i, &value))
   4637   1.1  christos 		return 0;
   4638   1.1  christos 
   4639   1.1  christos 	      /* PC-relative branches need adjustment, but
   4640   1.1  christos 		 the PC-rel operand will always have a relocation.  */
   4641   1.1  christos 	      newval = value;
   4642   1.1  christos 	      if (xtensa_operand_do_reloc (isa, o_opcode, i, &newval,
   4643   1.1  christos 					   self_address)
   4644   1.1  christos 		  || xtensa_operand_encode (isa, o_opcode, i, &newval)
   4645   1.1  christos 		  || xtensa_operand_set_field (isa, o_opcode, i, o_fmt, 0,
   4646   1.1  christos 					       o_slotbuf, newval))
   4647   1.1  christos 		return 0;
   4648   1.1  christos 	    }
   4649   1.3  christos 
   4650   1.1  christos 	  if (xtensa_format_set_slot (isa, o_fmt, 0, o_insnbuf, o_slotbuf))
   4651   1.1  christos 	    return 0;
   4652   1.1  christos 
   4653   1.1  christos 	  return o_insnbuf;
   4654   1.8  christos 	}
   4655   1.1  christos     }
   4656   1.1  christos   return 0;
   4657   1.1  christos }
   4658   1.1  christos 
   4659   1.1  christos 
   4660   1.1  christos /* Attempt to widen an instruction.  If the widening is valid, perform
   4661   1.1  christos    the action in-place directly into the contents and return TRUE.  Otherwise,
   4662   1.1  christos    the return value is FALSE and the contents are not modified.  */
   4663   1.1  christos 
   4664   1.1  christos static bool
   4665   1.1  christos widen_instruction (bfd_byte *contents,
   4666   1.1  christos 		   bfd_size_type content_length,
   4667   1.1  christos 		   bfd_size_type offset)
   4668   1.1  christos {
   4669   1.1  christos   xtensa_opcode opcode;
   4670   1.1  christos   bfd_size_type insn_len;
   4671   1.1  christos   xtensa_isa isa = xtensa_default_isa;
   4672   1.1  christos   xtensa_format fmt;
   4673   1.1  christos   xtensa_insnbuf o_insnbuf;
   4674   1.1  christos 
   4675   1.1  christos   static xtensa_insnbuf insnbuf = NULL;
   4676   1.1  christos   static xtensa_insnbuf slotbuf = NULL;
   4677   1.8  christos 
   4678   1.1  christos   if (insnbuf == NULL)
   4679   1.1  christos     {
   4680   1.1  christos       insnbuf = xtensa_insnbuf_alloc (isa);
   4681   1.1  christos       slotbuf = xtensa_insnbuf_alloc (isa);
   4682   1.1  christos     }
   4683   1.1  christos 
   4684   1.1  christos   BFD_ASSERT (offset < content_length);
   4685   1.8  christos 
   4686   1.1  christos   if (content_length < 2)
   4687   1.1  christos     return false;
   4688   1.8  christos 
   4689   1.1  christos   /* We will hand-code a few of these for a little while.
   4690   1.1  christos      These have all been specified in the assembler aleady.  */
   4691   1.1  christos   xtensa_insnbuf_from_chars (isa, insnbuf, &contents[offset],
   4692   1.8  christos 			     content_length - offset);
   4693   1.1  christos   fmt = xtensa_format_decode (isa, insnbuf);
   4694   1.1  christos   if (xtensa_format_num_slots (isa, fmt) != 1)
   4695   1.8  christos     return false;
   4696   1.1  christos 
   4697   1.1  christos   if (xtensa_format_get_slot (isa, fmt, 0, insnbuf, slotbuf) != 0)
   4698   1.1  christos     return false;
   4699   1.1  christos 
   4700   1.1  christos   opcode = xtensa_opcode_decode (isa, fmt, 0, slotbuf);
   4701   1.1  christos   if (opcode == XTENSA_UNDEFINED)
   4702   1.8  christos     return false;
   4703   1.1  christos   insn_len = xtensa_format_length (isa, fmt);
   4704   1.8  christos   if (insn_len > content_length)
   4705   1.1  christos     return false;
   4706   1.1  christos 
   4707   1.1  christos   o_insnbuf = can_widen_instruction (slotbuf, fmt, opcode);
   4708   1.1  christos   if (o_insnbuf)
   4709   1.1  christos     {
   4710   1.1  christos       xtensa_insnbuf_to_chars (isa, o_insnbuf, contents + offset,
   4711   1.1  christos 			       content_length - offset);
   4712   1.1  christos       return true;
   4713   1.1  christos     }
   4714   1.1  christos   return false;
   4715   1.1  christos }
   4716   1.1  christos 
   4717   1.1  christos 
   4718   1.1  christos /* Code for transforming CALLs at link-time.  */
   4720   1.1  christos 
   4721   1.1  christos static bfd_reloc_status_type
   4722   1.1  christos elf_xtensa_do_asm_simplify (bfd_byte *contents,
   4723   1.1  christos 			    bfd_vma address,
   4724   1.1  christos 			    bfd_vma content_length,
   4725   1.1  christos 			    char **error_message)
   4726   1.1  christos {
   4727   1.1  christos   static xtensa_insnbuf insnbuf = NULL;
   4728   1.1  christos   static xtensa_insnbuf slotbuf = NULL;
   4729   1.1  christos   xtensa_format core_format = XTENSA_UNDEFINED;
   4730   1.1  christos   xtensa_opcode opcode;
   4731   1.1  christos   xtensa_opcode direct_call_opcode;
   4732   1.1  christos   xtensa_isa isa = xtensa_default_isa;
   4733   1.6  christos   bfd_byte *chbuf = contents + address;
   4734   1.1  christos   int opn;
   4735   1.1  christos 
   4736   1.1  christos   if (insnbuf == NULL)
   4737   1.1  christos     {
   4738   1.1  christos       insnbuf = xtensa_insnbuf_alloc (isa);
   4739   1.1  christos       slotbuf = xtensa_insnbuf_alloc (isa);
   4740   1.1  christos     }
   4741   1.6  christos 
   4742   1.1  christos   if (content_length < address)
   4743   1.1  christos     {
   4744   1.3  christos       *error_message = _("attempt to convert L32R/CALLX to CALL failed");
   4745   1.1  christos       return bfd_reloc_other;
   4746   1.1  christos     }
   4747   1.1  christos 
   4748   1.1  christos   opcode = get_expanded_call_opcode (chbuf, content_length - address, 0);
   4749   1.3  christos   direct_call_opcode = swap_callx_for_call_opcode (opcode);
   4750   1.1  christos   if (direct_call_opcode == XTENSA_UNDEFINED)
   4751   1.1  christos     {
   4752   1.1  christos       *error_message = _("attempt to convert L32R/CALLX to CALL failed");
   4753   1.1  christos       return bfd_reloc_other;
   4754   1.1  christos     }
   4755   1.1  christos 
   4756   1.1  christos   /* Assemble a NOP ("or a1, a1, a1") into the 0 byte offset.  */
   4757   1.1  christos   core_format = xtensa_format_lookup (isa, "x24");
   4758   1.1  christos   opcode = xtensa_opcode_lookup (isa, "or");
   4759   1.1  christos   xtensa_opcode_encode (isa, core_format, 0, slotbuf, opcode);
   4760   1.1  christos   for (opn = 0; opn < 3; opn++)
   4761   1.1  christos     {
   4762   1.1  christos       uint32 regno = 1;
   4763   1.1  christos       xtensa_operand_encode (isa, opcode, opn, &regno);
   4764   1.1  christos       xtensa_operand_set_field (isa, opcode, opn, core_format, 0,
   4765   1.1  christos 				slotbuf, regno);
   4766   1.1  christos     }
   4767   1.1  christos   xtensa_format_encode (isa, core_format, insnbuf);
   4768   1.1  christos   xtensa_format_set_slot (isa, core_format, 0, insnbuf, slotbuf);
   4769   1.1  christos   xtensa_insnbuf_to_chars (isa, insnbuf, chbuf, content_length - address);
   4770   1.1  christos 
   4771   1.1  christos   /* Assemble a CALL ("callN 0") into the 3 byte offset.  */
   4772   1.1  christos   xtensa_opcode_encode (isa, core_format, 0, slotbuf, direct_call_opcode);
   4773   1.1  christos   xtensa_operand_set_field (isa, opcode, 0, core_format, 0, slotbuf, 0);
   4774   1.1  christos 
   4775   1.1  christos   xtensa_format_encode (isa, core_format, insnbuf);
   4776   1.1  christos   xtensa_format_set_slot (isa, core_format, 0, insnbuf, slotbuf);
   4777   1.1  christos   xtensa_insnbuf_to_chars (isa, insnbuf, chbuf + 3,
   4778   1.1  christos 			   content_length - address - 3);
   4779   1.1  christos 
   4780   1.1  christos   return bfd_reloc_ok;
   4781   1.1  christos }
   4782   1.1  christos 
   4783   1.1  christos 
   4784   1.1  christos static bfd_reloc_status_type
   4785   1.1  christos contract_asm_expansion (bfd_byte *contents,
   4786   1.1  christos 			bfd_vma content_length,
   4787   1.1  christos 			Elf_Internal_Rela *irel,
   4788   1.1  christos 			char **error_message)
   4789   1.1  christos {
   4790   1.1  christos   bfd_reloc_status_type retval =
   4791   1.1  christos     elf_xtensa_do_asm_simplify (contents, irel->r_offset, content_length,
   4792   1.1  christos 				error_message);
   4793   1.1  christos 
   4794   1.1  christos   if (retval != bfd_reloc_ok)
   4795   1.1  christos     return bfd_reloc_dangerous;
   4796   1.1  christos 
   4797   1.1  christos   /* Update the irel->r_offset field so that the right immediate and
   4798   1.1  christos      the right instruction are modified during the relocation.  */
   4799   1.1  christos   irel->r_offset += 3;
   4800   1.1  christos   irel->r_info = ELF32_R_INFO (ELF32_R_SYM (irel->r_info), R_XTENSA_SLOT0_OP);
   4801   1.1  christos   return bfd_reloc_ok;
   4802   1.1  christos }
   4803   1.1  christos 
   4804   1.1  christos 
   4805   1.1  christos static xtensa_opcode
   4806   1.1  christos swap_callx_for_call_opcode (xtensa_opcode opcode)
   4807   1.1  christos {
   4808   1.1  christos   init_call_opcodes ();
   4809   1.1  christos 
   4810   1.1  christos   if (opcode == callx0_op) return call0_op;
   4811   1.1  christos   if (opcode == callx4_op) return call4_op;
   4812   1.1  christos   if (opcode == callx8_op) return call8_op;
   4813   1.1  christos   if (opcode == callx12_op) return call12_op;
   4814   1.1  christos 
   4815   1.1  christos   /* Return XTENSA_UNDEFINED if the opcode is not an indirect call.  */
   4816   1.1  christos   return XTENSA_UNDEFINED;
   4817   1.3  christos }
   4818   1.8  christos 
   4819   1.1  christos 
   4820   1.1  christos /* Check if "buf" is pointing to a "L32R aN; CALLX aN" or "CONST16 aN;
   4821   1.1  christos    CONST16 aN; CALLX aN" sequence, and if so, return the CALLX opcode.
   4822   1.1  christos    If not, return XTENSA_UNDEFINED.  */
   4823   1.1  christos 
   4824   1.1  christos #define L32R_TARGET_REG_OPERAND 0
   4825   1.1  christos #define CONST16_TARGET_REG_OPERAND 0
   4826   1.1  christos #define CALLN_SOURCE_OPERAND 0
   4827   1.1  christos 
   4828   1.1  christos static xtensa_opcode
   4829   1.1  christos get_expanded_call_opcode (bfd_byte *buf, int bufsize, bool *p_uses_l32r)
   4830   1.1  christos {
   4831   1.1  christos   static xtensa_insnbuf insnbuf = NULL;
   4832   1.1  christos   static xtensa_insnbuf slotbuf = NULL;
   4833   1.1  christos   xtensa_format fmt;
   4834   1.1  christos   xtensa_opcode opcode;
   4835   1.1  christos   xtensa_isa isa = xtensa_default_isa;
   4836   1.1  christos   uint32 regno, const16_regno, call_regno;
   4837   1.1  christos   int offset = 0;
   4838   1.1  christos 
   4839   1.1  christos   if (insnbuf == NULL)
   4840   1.1  christos     {
   4841   1.1  christos       insnbuf = xtensa_insnbuf_alloc (isa);
   4842   1.1  christos       slotbuf = xtensa_insnbuf_alloc (isa);
   4843   1.1  christos     }
   4844   1.1  christos 
   4845   1.1  christos   xtensa_insnbuf_from_chars (isa, insnbuf, buf, bufsize);
   4846   1.1  christos   fmt = xtensa_format_decode (isa, insnbuf);
   4847   1.8  christos   if (fmt == XTENSA_UNDEFINED
   4848   1.1  christos       || xtensa_format_get_slot (isa, fmt, 0, insnbuf, slotbuf))
   4849   1.1  christos     return XTENSA_UNDEFINED;
   4850   1.1  christos 
   4851   1.1  christos   opcode = xtensa_opcode_decode (isa, fmt, 0, slotbuf);
   4852   1.1  christos   if (opcode == XTENSA_UNDEFINED)
   4853   1.1  christos     return XTENSA_UNDEFINED;
   4854   1.1  christos 
   4855   1.1  christos   if (opcode == get_l32r_opcode ())
   4856   1.1  christos     {
   4857   1.8  christos       if (p_uses_l32r)
   4858   1.1  christos 	*p_uses_l32r = true;
   4859   1.1  christos       if (xtensa_operand_get_field (isa, opcode, L32R_TARGET_REG_OPERAND,
   4860   1.1  christos 				    fmt, 0, slotbuf, &regno)
   4861   1.1  christos 	  || xtensa_operand_decode (isa, opcode, L32R_TARGET_REG_OPERAND,
   4862   1.1  christos 				    &regno))
   4863   1.1  christos 	return XTENSA_UNDEFINED;
   4864   1.1  christos     }
   4865   1.1  christos   else if (opcode == get_const16_opcode ())
   4866   1.1  christos     {
   4867   1.1  christos       if (p_uses_l32r)
   4868   1.1  christos 	*p_uses_l32r = false;
   4869   1.1  christos       if (xtensa_operand_get_field (isa, opcode, CONST16_TARGET_REG_OPERAND,
   4870   1.1  christos 				    fmt, 0, slotbuf, &regno)
   4871   1.1  christos 	  || xtensa_operand_decode (isa, opcode, CONST16_TARGET_REG_OPERAND,
   4872   1.1  christos 				    &regno))
   4873   1.1  christos 	return XTENSA_UNDEFINED;
   4874   1.1  christos 
   4875   1.1  christos       /* Check that the next instruction is also CONST16.  */
   4876   1.1  christos       offset += xtensa_format_length (isa, fmt);
   4877   1.1  christos       xtensa_insnbuf_from_chars (isa, insnbuf, buf + offset, bufsize - offset);
   4878   1.1  christos       fmt = xtensa_format_decode (isa, insnbuf);
   4879   1.1  christos       if (fmt == XTENSA_UNDEFINED
   4880   1.1  christos 	  || xtensa_format_get_slot (isa, fmt, 0, insnbuf, slotbuf))
   4881   1.1  christos 	return XTENSA_UNDEFINED;
   4882   1.1  christos       opcode = xtensa_opcode_decode (isa, fmt, 0, slotbuf);
   4883   1.1  christos       if (opcode != get_const16_opcode ())
   4884   1.1  christos 	return XTENSA_UNDEFINED;
   4885   1.1  christos 
   4886   1.1  christos       if (xtensa_operand_get_field (isa, opcode, CONST16_TARGET_REG_OPERAND,
   4887   1.1  christos 				    fmt, 0, slotbuf, &const16_regno)
   4888   1.1  christos 	  || xtensa_operand_decode (isa, opcode, CONST16_TARGET_REG_OPERAND,
   4889   1.1  christos 				    &const16_regno)
   4890   1.1  christos 	  || const16_regno != regno)
   4891   1.1  christos 	return XTENSA_UNDEFINED;
   4892   1.1  christos     }
   4893   1.3  christos   else
   4894   1.1  christos     return XTENSA_UNDEFINED;
   4895   1.1  christos 
   4896   1.1  christos   /* Next instruction should be an CALLXn with operand 0 == regno.  */
   4897   1.1  christos   offset += xtensa_format_length (isa, fmt);
   4898   1.1  christos   xtensa_insnbuf_from_chars (isa, insnbuf, buf + offset, bufsize - offset);
   4899   1.1  christos   fmt = xtensa_format_decode (isa, insnbuf);
   4900   1.1  christos   if (fmt == XTENSA_UNDEFINED
   4901   1.1  christos       || xtensa_format_get_slot (isa, fmt, 0, insnbuf, slotbuf))
   4902   1.1  christos     return XTENSA_UNDEFINED;
   4903   1.1  christos   opcode = xtensa_opcode_decode (isa, fmt, 0, slotbuf);
   4904   1.1  christos   if (opcode == XTENSA_UNDEFINED
   4905   1.1  christos       || !is_indirect_call_opcode (opcode))
   4906   1.1  christos     return XTENSA_UNDEFINED;
   4907   1.1  christos 
   4908   1.1  christos   if (xtensa_operand_get_field (isa, opcode, CALLN_SOURCE_OPERAND,
   4909   1.1  christos 				fmt, 0, slotbuf, &call_regno)
   4910   1.1  christos       || xtensa_operand_decode (isa, opcode, CALLN_SOURCE_OPERAND,
   4911   1.1  christos 				&call_regno))
   4912   1.1  christos     return XTENSA_UNDEFINED;
   4913   1.1  christos 
   4914   1.1  christos   if (call_regno != regno)
   4915   1.1  christos     return XTENSA_UNDEFINED;
   4916   1.1  christos 
   4917   1.1  christos   return opcode;
   4918   1.1  christos }
   4919   1.1  christos 
   4920   1.1  christos 
   4921   1.1  christos /* Data structures used during relaxation.  */
   4923   1.1  christos 
   4924   1.3  christos /* r_reloc: relocation values.  */
   4925   1.1  christos 
   4926   1.1  christos /* Through the relaxation process, we need to keep track of the values
   4927   1.1  christos    that will result from evaluating relocations.  The standard ELF
   4928   1.1  christos    relocation structure is not sufficient for this purpose because we're
   4929   1.1  christos    operating on multiple input files at once, so we need to know which
   4930   1.1  christos    input file a relocation refers to.  The r_reloc structure thus
   4931   1.1  christos    records both the input file (bfd) and ELF relocation.
   4932   1.1  christos 
   4933   1.1  christos    For efficiency, an r_reloc also contains a "target_offset" field to
   4934   1.1  christos    cache the target-section-relative offset value that is represented by
   4935   1.1  christos    the relocation.
   4936   1.1  christos 
   4937   1.1  christos    The r_reloc also contains a virtual offset that allows multiple
   4938   1.1  christos    inserted literals to be placed at the same "address" with
   4939   1.1  christos    different offsets.  */
   4940   1.1  christos 
   4941   1.1  christos typedef struct r_reloc_struct r_reloc;
   4942   1.1  christos 
   4943   1.1  christos struct r_reloc_struct
   4944   1.1  christos {
   4945   1.1  christos   bfd *abfd;
   4946   1.8  christos   Elf_Internal_Rela rela;
   4947   1.1  christos   bfd_vma target_offset;
   4948   1.1  christos   bfd_vma virtual_offset;
   4949   1.1  christos };
   4950   1.1  christos 
   4951   1.1  christos 
   4952   1.1  christos /* The r_reloc structure is included by value in literal_value, but not
   4953   1.1  christos    every literal_value has an associated relocation -- some are simple
   4954   1.1  christos    constants.  In such cases, we set all the fields in the r_reloc
   4955   1.1  christos    struct to zero.  The r_reloc_is_const function should be used to
   4956   1.1  christos    detect this case.  */
   4957   1.1  christos 
   4958   1.1  christos static bool
   4959   1.1  christos r_reloc_is_const (const r_reloc *r_rel)
   4960   1.1  christos {
   4961   1.1  christos   return (r_rel->abfd == NULL);
   4962   1.1  christos }
   4963   1.1  christos 
   4964   1.1  christos 
   4965   1.1  christos static bfd_vma
   4966   1.1  christos r_reloc_get_target_offset (const r_reloc *r_rel)
   4967   1.1  christos {
   4968   1.1  christos   bfd_vma target_offset;
   4969   1.1  christos   unsigned long r_symndx;
   4970   1.1  christos 
   4971   1.1  christos   BFD_ASSERT (!r_reloc_is_const (r_rel));
   4972   1.1  christos   r_symndx = ELF32_R_SYM (r_rel->rela.r_info);
   4973   1.1  christos   target_offset = get_elf_r_symndx_offset (r_rel->abfd, r_symndx);
   4974   1.1  christos   return (target_offset + r_rel->rela.r_addend);
   4975   1.1  christos }
   4976   1.1  christos 
   4977   1.1  christos 
   4978   1.1  christos static struct elf_link_hash_entry *
   4979   1.1  christos r_reloc_get_hash_entry (const r_reloc *r_rel)
   4980   1.1  christos {
   4981   1.1  christos   unsigned long r_symndx = ELF32_R_SYM (r_rel->rela.r_info);
   4982   1.8  christos   return get_elf_r_symndx_hash_entry (r_rel->abfd, r_symndx);
   4983   1.1  christos }
   4984   1.1  christos 
   4985   1.1  christos 
   4986   1.1  christos static asection *
   4987   1.8  christos r_reloc_get_section (const r_reloc *r_rel)
   4988   1.1  christos {
   4989   1.1  christos   unsigned long r_symndx = ELF32_R_SYM (r_rel->rela.r_info);
   4990   1.1  christos   return get_elf_r_symndx_section (r_rel->abfd, r_symndx);
   4991   1.1  christos }
   4992   1.1  christos 
   4993   1.8  christos 
   4994   1.8  christos static bool
   4995   1.1  christos r_reloc_is_defined (const r_reloc *r_rel)
   4996   1.1  christos {
   4997   1.1  christos   asection *sec;
   4998   1.1  christos   if (r_rel == NULL)
   4999   1.1  christos     return false;
   5000   1.1  christos 
   5001   1.1  christos   sec = r_reloc_get_section (r_rel);
   5002   1.1  christos   if (sec == bfd_abs_section_ptr
   5003   1.1  christos       || sec == bfd_com_section_ptr
   5004   1.1  christos       || sec == bfd_und_section_ptr)
   5005   1.1  christos     return false;
   5006   1.1  christos   return true;
   5007   1.1  christos }
   5008   1.1  christos 
   5009   1.1  christos 
   5010   1.1  christos static void
   5011   1.1  christos r_reloc_init (r_reloc *r_rel,
   5012   1.1  christos 	      bfd *abfd,
   5013   1.1  christos 	      Elf_Internal_Rela *irel,
   5014   1.1  christos 	      bfd_byte *contents,
   5015   1.1  christos 	      bfd_size_type content_length)
   5016   1.1  christos {
   5017   1.1  christos   int r_type;
   5018   1.1  christos   reloc_howto_type *howto;
   5019   1.1  christos 
   5020   1.1  christos   if (irel)
   5021   1.1  christos     {
   5022   1.1  christos       r_rel->rela = *irel;
   5023   1.1  christos       r_rel->abfd = abfd;
   5024   1.1  christos       r_rel->target_offset = r_reloc_get_target_offset (r_rel);
   5025   1.1  christos       r_rel->virtual_offset = 0;
   5026   1.1  christos       r_type = ELF32_R_TYPE (r_rel->rela.r_info);
   5027   1.1  christos       howto = &elf_howto_table[r_type];
   5028   1.1  christos       if (howto->partial_inplace)
   5029   1.1  christos 	{
   5030   1.1  christos 	  bfd_vma inplace_val;
   5031   1.1  christos 	  BFD_ASSERT (r_rel->rela.r_offset < content_length);
   5032   1.1  christos 
   5033   1.1  christos 	  inplace_val = bfd_get_32 (abfd, &contents[r_rel->rela.r_offset]);
   5034   1.1  christos 	  r_rel->target_offset += inplace_val;
   5035   1.1  christos 	}
   5036   1.1  christos     }
   5037   1.1  christos   else
   5038   1.1  christos     memset (r_rel, 0, sizeof (r_reloc));
   5039   1.1  christos }
   5040   1.1  christos 
   5041   1.1  christos 
   5042   1.1  christos #if DEBUG
   5043   1.1  christos 
   5044   1.1  christos static void
   5045   1.9  christos print_r_reloc (FILE *fp, const r_reloc *r_rel)
   5046   1.1  christos {
   5047   1.9  christos   if (r_reloc_is_defined (r_rel))
   5048   1.3  christos     {
   5049   1.1  christos       asection *sec = r_reloc_get_section (r_rel);
   5050   1.1  christos       fprintf (fp, " %s(%s + ", sec->owner->filename, sec->name);
   5051   1.1  christos     }
   5052   1.1  christos   else if (r_reloc_get_hash_entry (r_rel))
   5053   1.1  christos     fprintf (fp, " %s + ", r_reloc_get_hash_entry (r_rel)->root.root.string);
   5054   1.1  christos   else
   5055   1.1  christos     fprintf (fp, " ?? + ");
   5056   1.1  christos 
   5057   1.1  christos   fprintf (fp, "%" PRIx64, (uint64_t) r_rel->target_offset);
   5058   1.1  christos   if (r_rel->virtual_offset)
   5059   1.1  christos     fprintf (fp, " + %" PRIx64, (uint64_t) r_rel->virtual_offset);
   5060   1.1  christos 
   5061   1.1  christos   fprintf (fp, ")");
   5062   1.1  christos }
   5063   1.1  christos 
   5064   1.1  christos #endif /* DEBUG */
   5065   1.1  christos 
   5066   1.1  christos 
   5067   1.1  christos /* source_reloc: relocations that reference literals.  */
   5069   1.1  christos 
   5070   1.1  christos /* To determine whether literals can be coalesced, we need to first
   5071   1.1  christos    record all the relocations that reference the literals.  The
   5072   1.1  christos    source_reloc structure below is used for this purpose.  The
   5073   1.1  christos    source_reloc entries are kept in a per-literal-section array, sorted
   5074   1.1  christos    by offset within the literal section (i.e., target offset).
   5075   1.1  christos 
   5076   1.1  christos    The source_sec and r_rel.rela.r_offset fields identify the source of
   5077   1.1  christos    the relocation.  The r_rel field records the relocation value, i.e.,
   5078   1.1  christos    the offset of the literal being referenced.  The opnd field is needed
   5079   1.1  christos    to determine the range of the immediate field to which the relocation
   5080   1.8  christos    applies, so we can determine whether another literal with the same
   5081   1.8  christos    value is within range.  The is_null field is true when the relocation
   5082   1.1  christos    is being removed (e.g., when an L32R is being removed due to a CALLX
   5083   1.1  christos    that is converted to a direct CALL).  */
   5084   1.1  christos 
   5085   1.1  christos typedef struct source_reloc_struct source_reloc;
   5086   1.1  christos 
   5087   1.1  christos struct source_reloc_struct
   5088   1.1  christos {
   5089   1.1  christos   asection *source_sec;
   5090   1.1  christos   r_reloc r_rel;
   5091   1.8  christos   xtensa_opcode opcode;
   5092   1.1  christos   int opnd;
   5093   1.1  christos   bool is_null;
   5094   1.1  christos   bool is_abs_literal;
   5095   1.1  christos };
   5096   1.1  christos 
   5097   1.8  christos 
   5098   1.1  christos static void
   5099   1.1  christos init_source_reloc (source_reloc *reloc,
   5100   1.1  christos 		   asection *source_sec,
   5101   1.1  christos 		   const r_reloc *r_rel,
   5102   1.1  christos 		   xtensa_opcode opcode,
   5103   1.1  christos 		   int opnd,
   5104   1.1  christos 		   bool is_abs_literal)
   5105   1.1  christos {
   5106   1.1  christos   reloc->source_sec = source_sec;
   5107   1.1  christos   reloc->r_rel = *r_rel;
   5108   1.1  christos   reloc->opcode = opcode;
   5109   1.1  christos   reloc->opnd = opnd;
   5110   1.1  christos   reloc->is_null = false;
   5111   1.1  christos   reloc->is_abs_literal = is_abs_literal;
   5112   1.1  christos }
   5113   1.1  christos 
   5114   1.1  christos 
   5115   1.1  christos /* Find the source_reloc for a particular source offset and relocation
   5116   1.1  christos    type.  Note that the array is sorted by _target_ offset, so this is
   5117   1.1  christos    just a linear search.  */
   5118   1.1  christos 
   5119   1.1  christos static source_reloc *
   5120   1.1  christos find_source_reloc (source_reloc *src_relocs,
   5121   1.1  christos 		   int src_count,
   5122   1.1  christos 		   asection *sec,
   5123   1.1  christos 		   Elf_Internal_Rela *irel)
   5124   1.1  christos {
   5125   1.1  christos   int i;
   5126   1.1  christos 
   5127   1.1  christos   for (i = 0; i < src_count; i++)
   5128   1.1  christos     {
   5129   1.1  christos       if (src_relocs[i].source_sec == sec
   5130   1.1  christos 	  && src_relocs[i].r_rel.rela.r_offset == irel->r_offset
   5131   1.1  christos 	  && (ELF32_R_TYPE (src_relocs[i].r_rel.rela.r_info)
   5132   1.1  christos 	      == ELF32_R_TYPE (irel->r_info)))
   5133   1.1  christos 	return &src_relocs[i];
   5134   1.1  christos     }
   5135   1.1  christos 
   5136   1.1  christos   return NULL;
   5137   1.1  christos }
   5138   1.1  christos 
   5139   1.1  christos 
   5140   1.1  christos static int
   5141   1.1  christos source_reloc_compare (const void *ap, const void *bp)
   5142   1.1  christos {
   5143   1.1  christos   const source_reloc *a = (const source_reloc *) ap;
   5144   1.1  christos   const source_reloc *b = (const source_reloc *) bp;
   5145   1.1  christos 
   5146   1.1  christos   if (a->r_rel.target_offset != b->r_rel.target_offset)
   5147   1.1  christos     return (a->r_rel.target_offset - b->r_rel.target_offset);
   5148   1.1  christos 
   5149   1.1  christos   /* We don't need to sort on these criteria for correctness,
   5150   1.1  christos      but enforcing a more strict ordering prevents unstable qsort
   5151   1.1  christos      from behaving differently with different implementations.
   5152   1.1  christos      Without the code below we get correct but different results
   5153   1.1  christos      on Solaris 2.7 and 2.8.  We would like to always produce the
   5154   1.1  christos      same results no matter the host. */
   5155   1.1  christos 
   5156   1.1  christos   if ((!a->is_null) - (!b->is_null))
   5157   1.1  christos     return ((!a->is_null) - (!b->is_null));
   5158   1.1  christos   return internal_reloc_compare (&a->r_rel.rela, &b->r_rel.rela);
   5159   1.1  christos }
   5160   1.1  christos 
   5161   1.1  christos 
   5162   1.1  christos /* Literal values and value hash tables.  */
   5164   1.1  christos 
   5165   1.1  christos /* Literals with the same value can be coalesced.  The literal_value
   5166   1.1  christos    structure records the value of a literal: the "r_rel" field holds the
   5167   1.1  christos    information from the relocation on the literal (if there is one) and
   5168   1.3  christos    the "value" field holds the contents of the literal word itself.
   5169   1.1  christos 
   5170   1.8  christos    The value_map structure records a literal value along with the
   5171   1.1  christos    location of a literal holding that value.  The value_map hash table
   5172   1.1  christos    is indexed by the literal value, so that we can quickly check if a
   5173   1.1  christos    particular literal value has been seen before and is thus a candidate
   5174   1.1  christos    for coalescing.  */
   5175   1.1  christos 
   5176   1.1  christos typedef struct literal_value_struct literal_value;
   5177   1.1  christos typedef struct value_map_struct value_map;
   5178   1.1  christos typedef struct value_map_hash_table_struct value_map_hash_table;
   5179   1.1  christos 
   5180   1.1  christos struct literal_value_struct
   5181   1.1  christos {
   5182   1.1  christos   r_reloc r_rel;
   5183   1.1  christos   unsigned long value;
   5184   1.1  christos   bool is_abs_literal;
   5185   1.8  christos };
   5186   1.1  christos 
   5187   1.1  christos struct value_map_struct
   5188   1.1  christos {
   5189   1.1  christos   literal_value val;			/* The literal value.  */
   5190   1.1  christos   r_reloc loc;				/* Location of the literal.  */
   5191   1.1  christos   value_map *next;
   5192   1.1  christos };
   5193   1.1  christos 
   5194   1.8  christos struct value_map_hash_table_struct
   5195   1.1  christos {
   5196   1.1  christos   unsigned bucket_count;
   5197   1.1  christos   value_map **buckets;
   5198   1.1  christos   unsigned count;
   5199   1.1  christos   bool has_last_loc;
   5200   1.1  christos   r_reloc last_loc;
   5201   1.1  christos };
   5202   1.8  christos 
   5203   1.1  christos 
   5204   1.1  christos static void
   5205   1.8  christos init_literal_value (literal_value *lit,
   5206   1.1  christos 		    const r_reloc *r_rel,
   5207   1.1  christos 		    unsigned long value,
   5208   1.1  christos 		    bool is_abs_literal)
   5209   1.3  christos {
   5210   1.8  christos   lit->r_rel = *r_rel;
   5211   1.1  christos   lit->value = value;
   5212   1.1  christos   lit->is_abs_literal = is_abs_literal;
   5213   1.1  christos }
   5214   1.1  christos 
   5215   1.1  christos 
   5216   1.1  christos static bool
   5217   1.8  christos literal_value_equal (const literal_value *src1,
   5218   1.1  christos 		     const literal_value *src2,
   5219   1.1  christos 		     bool final_static_link)
   5220   1.8  christos {
   5221   1.3  christos   struct elf_link_hash_entry *h1, *h2;
   5222   1.1  christos 
   5223   1.8  christos   if (r_reloc_is_const (&src1->r_rel) != r_reloc_is_const (&src2->r_rel))
   5224   1.1  christos     return false;
   5225   1.1  christos 
   5226   1.8  christos   if (r_reloc_is_const (&src1->r_rel))
   5227   1.3  christos     return (src1->value == src2->value);
   5228   1.1  christos 
   5229   1.1  christos   if (ELF32_R_TYPE (src1->r_rel.rela.r_info)
   5230   1.1  christos       != ELF32_R_TYPE (src2->r_rel.rela.r_info))
   5231   1.1  christos     return false;
   5232   1.9  christos 
   5233   1.9  christos   if (src1->r_rel.target_offset != src2->r_rel.target_offset)
   5234   1.9  christos     return false;
   5235   1.9  christos 
   5236   1.9  christos   if (src1->r_rel.virtual_offset != src2->r_rel.virtual_offset)
   5237   1.9  christos     return false;
   5238   1.9  christos 
   5239   1.1  christos   if (src1->value != src2->value)
   5240   1.1  christos     return false;
   5241   1.1  christos 
   5242   1.1  christos   /* Now check for the same section (if defined) or the same elf_hash
   5243   1.1  christos      (if undefined or weak).  */
   5244   1.1  christos   h1 = r_reloc_get_hash_entry (&src1->r_rel);
   5245   1.1  christos   h2 = r_reloc_get_hash_entry (&src2->r_rel);
   5246   1.8  christos 
   5247   1.1  christos   /* Keep start_stop literals always unique to avoid dropping it due to them
   5248   1.1  christos      having late initialization.
   5249   1.1  christos      Now they are equal because initialized with zeroed values.  */
   5250   1.1  christos   if (h2 && h2->start_stop)
   5251   1.1  christos       return false;
   5252   1.8  christos 
   5253   1.1  christos   if (r_reloc_is_defined (&src1->r_rel)
   5254   1.1  christos       && (final_static_link
   5255   1.1  christos 	  || ((!h1 || h1->root.type != bfd_link_hash_defweak)
   5256   1.8  christos 	      && (!h2 || h2->root.type != bfd_link_hash_defweak))))
   5257   1.1  christos     {
   5258   1.8  christos       if (r_reloc_get_section (&src1->r_rel)
   5259   1.1  christos 	  != r_reloc_get_section (&src2->r_rel))
   5260   1.1  christos 	return false;
   5261   1.1  christos     }
   5262   1.1  christos   else
   5263   1.1  christos     {
   5264   1.1  christos       /* Require that the hash entries (i.e., symbols) be identical.  */
   5265   1.1  christos       if (h1 != h2 || h1 == 0)
   5266   1.1  christos 	return false;
   5267   1.1  christos     }
   5268   1.1  christos 
   5269   1.1  christos   if (src1->is_abs_literal != src2->is_abs_literal)
   5270   1.1  christos     return false;
   5271   1.1  christos 
   5272   1.1  christos   return true;
   5273   1.1  christos }
   5274   1.1  christos 
   5275   1.1  christos 
   5276   1.3  christos /* Must be power of 2.  */
   5277   1.1  christos #define INITIAL_HASH_RELOC_BUCKET_COUNT 1024
   5278   1.1  christos 
   5279   1.1  christos static value_map_hash_table *
   5280   1.1  christos value_map_hash_table_init (void)
   5281   1.8  christos {
   5282   1.1  christos   value_map_hash_table *values;
   5283   1.1  christos 
   5284   1.1  christos   values = (value_map_hash_table *)
   5285   1.1  christos     bfd_zmalloc (sizeof (value_map_hash_table));
   5286   1.1  christos   values->bucket_count = INITIAL_HASH_RELOC_BUCKET_COUNT;
   5287   1.1  christos   values->count = 0;
   5288   1.1  christos   values->buckets = (value_map **)
   5289   1.1  christos     bfd_zmalloc (sizeof (value_map *) * values->bucket_count);
   5290   1.1  christos   if (values->buckets == NULL)
   5291   1.1  christos     {
   5292   1.1  christos       free (values);
   5293   1.1  christos       return NULL;
   5294   1.1  christos     }
   5295   1.1  christos   values->has_last_loc = false;
   5296   1.1  christos 
   5297   1.1  christos   return values;
   5298   1.1  christos }
   5299   1.1  christos 
   5300   1.1  christos 
   5301   1.1  christos static void
   5302   1.1  christos value_map_hash_table_delete (value_map_hash_table *table)
   5303   1.1  christos {
   5304   1.1  christos   free (table->buckets);
   5305   1.1  christos   free (table);
   5306   1.1  christos }
   5307   1.1  christos 
   5308   1.1  christos 
   5309   1.1  christos static unsigned
   5310   1.1  christos hash_bfd_vma (bfd_vma val)
   5311   1.1  christos {
   5312   1.1  christos   return (val >> 2) + (val >> 10);
   5313   1.1  christos }
   5314   1.1  christos 
   5315   1.3  christos 
   5316   1.1  christos static unsigned
   5317   1.1  christos literal_value_hash (const literal_value *src)
   5318   1.1  christos {
   5319   1.1  christos   unsigned hash_val;
   5320   1.1  christos 
   5321   1.1  christos   hash_val = hash_bfd_vma (src->value);
   5322   1.1  christos   if (!r_reloc_is_const (&src->r_rel))
   5323   1.1  christos     {
   5324   1.1  christos       void *sec_or_hash;
   5325   1.1  christos 
   5326   1.1  christos       hash_val += hash_bfd_vma (src->is_abs_literal * 1000);
   5327   1.1  christos       hash_val += hash_bfd_vma (src->r_rel.target_offset);
   5328   1.1  christos       hash_val += hash_bfd_vma (src->r_rel.virtual_offset);
   5329   1.1  christos 
   5330   1.1  christos       /* Now check for the same section and the same elf_hash.  */
   5331   1.1  christos       if (r_reloc_is_defined (&src->r_rel))
   5332   1.8  christos 	sec_or_hash = r_reloc_get_section (&src->r_rel);
   5333   1.1  christos       else
   5334   1.1  christos 	sec_or_hash = r_reloc_get_hash_entry (&src->r_rel);
   5335   1.1  christos       hash_val += hash_bfd_vma ((bfd_vma) (size_t) sec_or_hash);
   5336   1.1  christos     }
   5337   1.1  christos   return hash_val;
   5338   1.1  christos }
   5339   1.1  christos 
   5340   1.1  christos 
   5341   1.1  christos /* Check if the specified literal_value has been seen before.  */
   5342   1.1  christos 
   5343   1.1  christos static value_map *
   5344   1.1  christos value_map_get_cached_value (value_map_hash_table *map,
   5345   1.1  christos 			    const literal_value *val,
   5346   1.1  christos 			    bool final_static_link)
   5347   1.1  christos {
   5348   1.1  christos   value_map *map_e;
   5349   1.1  christos   value_map *bucket;
   5350   1.1  christos   unsigned idx;
   5351   1.1  christos 
   5352   1.1  christos   idx = literal_value_hash (val);
   5353   1.1  christos   idx = idx & (map->bucket_count - 1);
   5354   1.1  christos   bucket = map->buckets[idx];
   5355   1.1  christos   for (map_e = bucket; map_e; map_e = map_e->next)
   5356   1.1  christos     {
   5357   1.8  christos       if (literal_value_equal (&map_e->val, val, final_static_link))
   5358   1.1  christos 	return map_e;
   5359   1.1  christos     }
   5360   1.1  christos   return NULL;
   5361   1.1  christos }
   5362   1.1  christos 
   5363   1.1  christos 
   5364   1.1  christos /* Record a new literal value.  It is illegal to call this if VALUE
   5365   1.1  christos    already has an entry here.  */
   5366   1.1  christos 
   5367   1.1  christos static value_map *
   5368   1.1  christos add_value_map (value_map_hash_table *map,
   5369   1.1  christos 	       const literal_value *val,
   5370   1.1  christos 	       const r_reloc *loc,
   5371   1.1  christos 	       bool final_static_link)
   5372   1.1  christos {
   5373   1.1  christos   value_map **bucket_p;
   5374   1.1  christos   unsigned idx;
   5375   1.1  christos 
   5376   1.1  christos   value_map *val_e = (value_map *) bfd_zmalloc (sizeof (value_map));
   5377   1.1  christos   if (val_e == NULL)
   5378   1.1  christos     {
   5379   1.1  christos       bfd_set_error (bfd_error_no_memory);
   5380   1.1  christos       return NULL;
   5381   1.3  christos     }
   5382   1.1  christos 
   5383   1.1  christos   BFD_ASSERT (!value_map_get_cached_value (map, val, final_static_link));
   5384   1.1  christos   val_e->val = *val;
   5385   1.1  christos   val_e->loc = *loc;
   5386   1.1  christos 
   5387   1.1  christos   idx = literal_value_hash (val);
   5388   1.1  christos   idx = idx & (map->bucket_count - 1);
   5389   1.1  christos   bucket_p = &map->buckets[idx];
   5390   1.1  christos 
   5391   1.6  christos   val_e->next = *bucket_p;
   5392   1.6  christos   *bucket_p = val_e;
   5393   1.1  christos   map->count++;
   5394   1.6  christos   /* FIXME: Consider resizing the hash table if we get too many entries.  */
   5395   1.6  christos 
   5396   1.6  christos   return val_e;
   5397   1.1  christos }
   5398   1.1  christos 
   5399   1.1  christos 
   5400   1.6  christos /* Lists of text actions (ta_) for narrowing, widening, longcall
   5402   1.6  christos    conversion, space fill, code & literal removal, etc.  */
   5403   1.6  christos 
   5404   1.6  christos /* The following text actions are generated:
   5405   1.6  christos 
   5406   1.1  christos    "ta_remove_insn"	    remove an instruction or instructions
   5407   1.6  christos    "ta_remove_longcall"	    convert longcall to call
   5408   1.1  christos    "ta_convert_longcall"    convert longcall to nop/call
   5409   1.1  christos    "ta_narrow_insn"	    narrow a wide instruction
   5410   1.1  christos    "ta_widen"		    widen a narrow instruction
   5411   1.1  christos    "ta_fill"		    add fill or remove fill
   5412   1.1  christos       removed < 0 is a fill; branches to the fill address will be
   5413   1.1  christos 	changed to address + fill size (e.g., address - removed)
   5414   1.1  christos       removed >= 0 branches to the fill address will stay unchanged
   5415   1.1  christos    "ta_remove_literal"	    remove a literal; this action is
   5416   1.1  christos 			    indicated when a literal is removed
   5417   1.1  christos 			    or replaced.
   5418   1.1  christos    "ta_add_literal"	    insert a new literal; this action is
   5419   1.1  christos 			    indicated when a literal has been moved.
   5420   1.6  christos 			    It may use a virtual_offset because
   5421   1.6  christos 			    multiple literals can be placed at the
   5422   1.6  christos 			    same location.
   5423   1.6  christos 
   5424   1.6  christos    For each of these text actions, we also record the number of bytes
   5425   1.6  christos    removed by performing the text action.  In the case of a "ta_widen"
   5426   1.1  christos    or a "ta_fill" that adds space, the removed_bytes will be negative.  */
   5427   1.1  christos 
   5428   1.1  christos typedef struct text_action_struct text_action;
   5429   1.1  christos typedef struct text_action_list_struct text_action_list;
   5430   1.1  christos typedef enum text_action_enum_t text_action_t;
   5431   1.1  christos 
   5432   1.1  christos enum text_action_enum_t
   5433   1.1  christos {
   5434   1.1  christos   ta_none,
   5435   1.1  christos   ta_remove_insn,	 /* removed = -size */
   5436   1.1  christos   ta_remove_longcall,	 /* removed = -size */
   5437   1.1  christos   ta_convert_longcall,	 /* removed = 0 */
   5438   1.1  christos   ta_narrow_insn,	 /* removed = -1 */
   5439   1.1  christos   ta_widen_insn,	 /* removed = +1 */
   5440   1.3  christos   ta_fill,		 /* removed = +size */
   5441   1.1  christos   ta_remove_literal,
   5442   1.3  christos   ta_add_literal
   5443   1.3  christos };
   5444   1.3  christos 
   5445   1.3  christos 
   5446   1.3  christos /* Structure for a text action record.  */
   5447   1.3  christos struct text_action_struct
   5448   1.1  christos {
   5449   1.3  christos   text_action_t action;
   5450   1.3  christos   asection *sec;	/* Optional */
   5451   1.3  christos   bfd_vma offset;
   5452   1.3  christos   bfd_vma virtual_offset;  /* Zero except for adding literals.  */
   5453   1.3  christos   int removed_bytes;
   5454   1.3  christos   literal_value value;	/* Only valid when adding literals.  */
   5455   1.3  christos };
   5456   1.3  christos 
   5457   1.1  christos struct removal_by_action_entry_struct
   5458   1.1  christos {
   5459   1.1  christos   bfd_vma offset;
   5460   1.1  christos   int removed;
   5461   1.1  christos   int eq_removed;
   5462   1.3  christos   int eq_removed_before_fill;
   5463   1.3  christos };
   5464   1.3  christos typedef struct removal_by_action_entry_struct removal_by_action_entry;
   5465   1.1  christos 
   5466   1.1  christos struct removal_by_action_map_struct
   5467   1.1  christos {
   5468   1.1  christos   unsigned n_entries;
   5469   1.1  christos   removal_by_action_entry *entry;
   5470   1.1  christos };
   5471   1.3  christos typedef struct removal_by_action_map_struct removal_by_action_map;
   5472   1.1  christos 
   5473   1.1  christos 
   5474   1.1  christos /* List of all of the actions taken on a text section.  */
   5475   1.1  christos struct text_action_list_struct
   5476   1.1  christos {
   5477   1.3  christos   unsigned count;
   5478   1.3  christos   splay_tree tree;
   5479   1.3  christos   removal_by_action_map map;
   5480   1.3  christos };
   5481   1.3  christos 
   5482   1.3  christos 
   5483   1.1  christos static text_action *
   5484   1.1  christos find_fill_action (text_action_list *l, asection *sec, bfd_vma offset)
   5485   1.1  christos {
   5486   1.1  christos   text_action a;
   5487   1.1  christos 
   5488   1.1  christos   /* It is not necessary to fill at the end of a section.  */
   5489   1.1  christos   if (sec->size == offset)
   5490   1.1  christos     return NULL;
   5491   1.1  christos 
   5492   1.1  christos   a.offset = offset;
   5493   1.1  christos   a.action = ta_fill;
   5494   1.1  christos 
   5495   1.1  christos   splay_tree_node node = splay_tree_lookup (l->tree, (splay_tree_key)&a);
   5496   1.1  christos   if (node)
   5497   1.1  christos     return (text_action *)node->value;
   5498   1.1  christos   return NULL;
   5499   1.1  christos }
   5500   1.1  christos 
   5501   1.1  christos 
   5502   1.1  christos static int
   5503   1.1  christos compute_removed_action_diff (const text_action *ta,
   5504   1.1  christos 			     asection *sec,
   5505   1.1  christos 			     bfd_vma offset,
   5506   1.1  christos 			     int removed,
   5507   1.1  christos 			     int removable_space)
   5508   1.1  christos {
   5509   1.1  christos   int new_removed;
   5510   1.1  christos   int current_removed = 0;
   5511   1.1  christos 
   5512   1.1  christos   if (ta)
   5513   1.1  christos     current_removed = ta->removed_bytes;
   5514   1.1  christos 
   5515   1.1  christos   BFD_ASSERT (ta == NULL || ta->offset == offset);
   5516   1.1  christos   BFD_ASSERT (ta == NULL || ta->action == ta_fill);
   5517   1.1  christos 
   5518   1.1  christos   /* It is not necessary to fill at the end of a section.  Clean this up.  */
   5519   1.1  christos   if (sec->size == offset)
   5520   1.1  christos     new_removed = removable_space - 0;
   5521   1.1  christos   else
   5522   1.1  christos     {
   5523   1.1  christos       int space;
   5524   1.1  christos       int added = -removed - current_removed;
   5525   1.1  christos       /* Ignore multiples of the section alignment.  */
   5526   1.1  christos       added = ((1 << sec->alignment_power) - 1) & added;
   5527   1.1  christos       new_removed = (-added);
   5528   1.1  christos 
   5529   1.1  christos       /* Modify for removable.  */
   5530   1.3  christos       space = removable_space - new_removed;
   5531   1.3  christos       new_removed = (removable_space
   5532   1.3  christos 		     - (((1 << sec->alignment_power) - 1) & space));
   5533   1.3  christos     }
   5534   1.3  christos   return (new_removed - current_removed);
   5535   1.3  christos }
   5536   1.3  christos 
   5537   1.3  christos 
   5538   1.3  christos static void
   5539   1.3  christos adjust_fill_action (text_action *ta, int fill_diff)
   5540   1.3  christos {
   5541   1.3  christos   ta->removed_bytes += fill_diff;
   5542   1.3  christos }
   5543   1.3  christos 
   5544   1.3  christos 
   5545   1.3  christos static int
   5546   1.3  christos text_action_compare (splay_tree_key a, splay_tree_key b)
   5547   1.3  christos {
   5548   1.3  christos   text_action *pa = (text_action *)a;
   5549   1.3  christos   text_action *pb = (text_action *)b;
   5550   1.3  christos   static const int action_priority[] =
   5551   1.3  christos     {
   5552   1.3  christos       [ta_fill] = 0,
   5553   1.3  christos       [ta_none] = 1,
   5554   1.3  christos       [ta_convert_longcall] = 2,
   5555   1.3  christos       [ta_narrow_insn] = 3,
   5556   1.3  christos       [ta_remove_insn] = 4,
   5557   1.3  christos       [ta_remove_longcall] = 5,
   5558   1.3  christos       [ta_remove_literal] = 6,
   5559   1.3  christos       [ta_widen_insn] = 7,
   5560   1.3  christos       [ta_add_literal] = 8,
   5561   1.3  christos     };
   5562   1.3  christos 
   5563   1.3  christos   if (pa->offset == pb->offset)
   5564   1.3  christos     {
   5565   1.3  christos       if (pa->action == pb->action)
   5566   1.3  christos 	  return 0;
   5567   1.3  christos       return action_priority[pa->action] - action_priority[pb->action];
   5568   1.3  christos     }
   5569   1.3  christos   else
   5570   1.3  christos     return pa->offset < pb->offset ? -1 : 1;
   5571   1.3  christos }
   5572   1.3  christos 
   5573   1.1  christos static text_action *
   5574   1.1  christos action_first (text_action_list *action_list)
   5575   1.1  christos {
   5576   1.1  christos   splay_tree_node node = splay_tree_min (action_list->tree);
   5577   1.1  christos   return node ? (text_action *)node->value : NULL;
   5578   1.3  christos }
   5579   1.1  christos 
   5580   1.1  christos static text_action *
   5581   1.1  christos action_next (text_action_list *action_list, text_action *action)
   5582   1.1  christos {
   5583   1.1  christos   splay_tree_node node = splay_tree_successor (action_list->tree,
   5584   1.1  christos 					       (splay_tree_key)action);
   5585   1.1  christos   return node ? (text_action *)node->value : NULL;
   5586   1.3  christos }
   5587   1.1  christos 
   5588   1.1  christos /* Add a modification action to the text.  For the case of adding or
   5589   1.1  christos    removing space, modify any current fill and assume that
   5590   1.1  christos    "unreachable_space" bytes can be freely contracted.  Note that a
   5591   1.1  christos    negative removed value is a fill.  */
   5592   1.1  christos 
   5593   1.1  christos static void
   5594   1.1  christos text_action_add (text_action_list *l,
   5595   1.1  christos 		 text_action_t action,
   5596   1.3  christos 		 asection *sec,
   5597   1.3  christos 		 bfd_vma offset,
   5598   1.3  christos 		 int removed)
   5599   1.3  christos {
   5600   1.1  christos   text_action *ta;
   5601   1.3  christos   text_action a;
   5602   1.3  christos 
   5603   1.3  christos   /* It is not necessary to fill at the end of a section.  */
   5604   1.3  christos   if (action == ta_fill && sec->size == offset)
   5605   1.3  christos     return;
   5606   1.3  christos 
   5607   1.3  christos   /* It is not necessary to fill 0 bytes.  */
   5608   1.1  christos   if (action == ta_fill && removed == 0)
   5609   1.1  christos     return;
   5610   1.3  christos 
   5611   1.3  christos   a.action = action;
   5612   1.1  christos   a.offset = offset;
   5613   1.1  christos 
   5614   1.1  christos   if (action == ta_fill)
   5615   1.1  christos     {
   5616   1.1  christos       splay_tree_node node = splay_tree_lookup (l->tree, (splay_tree_key)&a);
   5617   1.1  christos 
   5618   1.3  christos       if (node)
   5619   1.3  christos 	{
   5620   1.1  christos 	  ta = (text_action *)node->value;
   5621   1.1  christos 	  ta->removed_bytes += removed;
   5622   1.1  christos 	  return;
   5623   1.1  christos 	}
   5624   1.1  christos     }
   5625   1.1  christos   else
   5626   1.1  christos     BFD_ASSERT (splay_tree_lookup (l->tree, (splay_tree_key)&a) == NULL);
   5627   1.1  christos 
   5628   1.1  christos   ta = (text_action *) bfd_zmalloc (sizeof (text_action));
   5629   1.1  christos   ta->action = action;
   5630   1.1  christos   ta->sec = sec;
   5631   1.1  christos   ta->offset = offset;
   5632   1.1  christos   ta->removed_bytes = removed;
   5633   1.1  christos   splay_tree_insert (l->tree, (splay_tree_key)ta, (splay_tree_value)ta);
   5634   1.1  christos   ++l->count;
   5635   1.1  christos }
   5636   1.1  christos 
   5637   1.1  christos 
   5638   1.1  christos static void
   5639   1.1  christos text_action_add_literal (text_action_list *l,
   5640   1.1  christos 			 text_action_t action,
   5641   1.1  christos 			 const r_reloc *loc,
   5642   1.1  christos 			 const literal_value *value,
   5643   1.1  christos 			 int removed)
   5644   1.1  christos {
   5645   1.3  christos   text_action *ta;
   5646   1.3  christos   asection *sec = r_reloc_get_section (loc);
   5647   1.3  christos   bfd_vma offset = loc->target_offset;
   5648   1.3  christos   bfd_vma virtual_offset = loc->virtual_offset;
   5649   1.1  christos 
   5650   1.1  christos   BFD_ASSERT (action == ta_add_literal);
   5651   1.1  christos 
   5652   1.1  christos   /* Create a new record and fill it up.  */
   5653   1.1  christos   ta = (text_action *) bfd_zmalloc (sizeof (text_action));
   5654   1.1  christos   ta->action = action;
   5655   1.1  christos   ta->sec = sec;
   5656   1.1  christos   ta->offset = offset;
   5657   1.1  christos   ta->virtual_offset = virtual_offset;
   5658   1.1  christos   ta->value = *value;
   5659   1.3  christos   ta->removed_bytes = removed;
   5660   1.3  christos 
   5661   1.1  christos   BFD_ASSERT (splay_tree_lookup (l->tree, (splay_tree_key)ta) == NULL);
   5662   1.8  christos   splay_tree_insert (l->tree, (splay_tree_key)ta, (splay_tree_value)ta);
   5663   1.1  christos   ++l->count;
   5664   1.1  christos }
   5665   1.1  christos 
   5666   1.1  christos 
   5667   1.1  christos /* Find the total offset adjustment for the relaxations specified by
   5668   1.3  christos    text_actions, beginning from a particular starting action.  This is
   5669   1.3  christos    typically used from offset_with_removed_text to search an entire list of
   5670   1.3  christos    actions, but it may also be called directly when adjusting adjacent offsets
   5671   1.3  christos    so that each search may begin where the previous one left off.  */
   5672   1.3  christos 
   5673   1.3  christos static int
   5674   1.3  christos removed_by_actions (text_action_list *action_list,
   5675   1.1  christos 		    text_action **p_start_action,
   5676   1.1  christos 		    bfd_vma offset,
   5677   1.1  christos 		    bool before_fill)
   5678   1.1  christos {
   5679   1.1  christos   text_action *r;
   5680   1.1  christos   int removed = 0;
   5681   1.1  christos 
   5682   1.1  christos   r = *p_start_action;
   5683   1.1  christos   if (r)
   5684   1.1  christos     {
   5685   1.1  christos       splay_tree_node node = splay_tree_lookup (action_list->tree,
   5686   1.3  christos 						(splay_tree_key)r);
   5687   1.1  christos       BFD_ASSERT (node != NULL && r == (text_action *)node->value);
   5688   1.1  christos     }
   5689   1.1  christos 
   5690   1.1  christos   while (r)
   5691   1.1  christos     {
   5692   1.1  christos       if (r->offset > offset)
   5693   1.1  christos 	break;
   5694   1.3  christos 
   5695   1.1  christos       if (r->offset == offset
   5696   1.1  christos 	  && (before_fill || r->action != ta_fill || r->removed_bytes >= 0))
   5697   1.3  christos 	break;
   5698   1.3  christos 
   5699   1.8  christos       removed += r->removed_bytes;
   5700   1.1  christos 
   5701   1.1  christos       r = action_next (action_list, r);
   5702   1.1  christos     }
   5703   1.1  christos 
   5704   1.1  christos   *p_start_action = r;
   5705   1.1  christos   return removed;
   5706   1.3  christos }
   5707   1.3  christos 
   5708   1.3  christos 
   5709   1.3  christos static bfd_vma
   5710   1.3  christos offset_with_removed_text (text_action_list *action_list, bfd_vma offset)
   5711   1.3  christos {
   5712   1.3  christos   text_action *r = action_first (action_list);
   5713   1.3  christos 
   5714   1.8  christos   return offset - removed_by_actions (action_list, &r, offset, false);
   5715   1.3  christos }
   5716   1.3  christos 
   5717   1.3  christos 
   5718   1.3  christos static unsigned
   5719   1.3  christos action_list_count (text_action_list *action_list)
   5720   1.3  christos {
   5721   1.3  christos   return action_list->count;
   5722   1.3  christos }
   5723   1.3  christos 
   5724   1.3  christos typedef struct map_action_fn_context_struct map_action_fn_context;
   5725   1.3  christos struct map_action_fn_context_struct
   5726   1.3  christos {
   5727   1.3  christos   int removed;
   5728   1.3  christos   removal_by_action_map map;
   5729   1.3  christos   bool eq_complete;
   5730   1.3  christos };
   5731   1.8  christos 
   5732   1.3  christos static int
   5733   1.3  christos map_action_fn (splay_tree_node node, void *p)
   5734   1.3  christos {
   5735   1.3  christos   map_action_fn_context *ctx = p;
   5736   1.3  christos   text_action *r = (text_action *)node->value;
   5737   1.3  christos   removal_by_action_entry *ientry = ctx->map.entry + ctx->map.n_entries;
   5738   1.3  christos 
   5739   1.3  christos   if (ctx->map.n_entries && (ientry - 1)->offset == r->offset)
   5740   1.3  christos     {
   5741   1.8  christos       --ientry;
   5742   1.3  christos     }
   5743   1.3  christos   else
   5744   1.3  christos     {
   5745   1.3  christos       ++ctx->map.n_entries;
   5746   1.3  christos       ctx->eq_complete = false;
   5747   1.3  christos       ientry->offset = r->offset;
   5748   1.3  christos       ientry->eq_removed_before_fill = ctx->removed;
   5749   1.3  christos     }
   5750   1.3  christos 
   5751   1.3  christos   if (!ctx->eq_complete)
   5752   1.3  christos     {
   5753   1.3  christos       if (r->action != ta_fill || r->removed_bytes >= 0)
   5754   1.3  christos 	{
   5755   1.3  christos 	  ientry->eq_removed = ctx->removed;
   5756   1.3  christos 	  ctx->eq_complete = true;
   5757   1.3  christos 	}
   5758   1.3  christos       else
   5759   1.3  christos 	ientry->eq_removed = ctx->removed + r->removed_bytes;
   5760   1.3  christos     }
   5761   1.8  christos 
   5762   1.3  christos   ctx->removed += r->removed_bytes;
   5763   1.3  christos   ientry->removed = ctx->removed;
   5764   1.3  christos   return 0;
   5765   1.3  christos }
   5766   1.3  christos 
   5767   1.3  christos static void
   5768   1.3  christos map_removal_by_action (text_action_list *action_list)
   5769   1.8  christos {
   5770   1.3  christos   map_action_fn_context ctx;
   5771   1.3  christos 
   5772   1.3  christos   ctx.removed = 0;
   5773   1.3  christos   ctx.map.n_entries = 0;
   5774   1.3  christos   ctx.map.entry = bfd_malloc (action_list_count (action_list) *
   5775   1.3  christos 			      sizeof (removal_by_action_entry));
   5776   1.3  christos   ctx.eq_complete = false;
   5777   1.3  christos 
   5778   1.3  christos   splay_tree_foreach (action_list->tree, map_action_fn, &ctx);
   5779   1.3  christos   action_list->map = ctx.map;
   5780   1.3  christos }
   5781   1.3  christos 
   5782   1.3  christos static int
   5783   1.3  christos removed_by_actions_map (text_action_list *action_list, bfd_vma offset,
   5784   1.3  christos 			bool before_fill)
   5785   1.3  christos {
   5786   1.3  christos   unsigned a, b;
   5787   1.3  christos 
   5788   1.3  christos   if (!action_list->map.entry)
   5789   1.3  christos     map_removal_by_action (action_list);
   5790   1.3  christos 
   5791   1.3  christos   if (!action_list->map.n_entries)
   5792   1.3  christos     return 0;
   5793   1.3  christos 
   5794   1.3  christos   a = 0;
   5795   1.3  christos   b = action_list->map.n_entries;
   5796   1.3  christos 
   5797   1.1  christos   while (b - a > 1)
   5798   1.3  christos     {
   5799   1.3  christos       unsigned c = (a + b) / 2;
   5800   1.3  christos 
   5801   1.1  christos       if (action_list->map.entry[c].offset <= offset)
   5802   1.3  christos 	a = c;
   5803   1.3  christos       else
   5804   1.3  christos 	b = c;
   5805   1.3  christos     }
   5806   1.3  christos 
   5807   1.3  christos   if (action_list->map.entry[a].offset < offset)
   5808   1.3  christos     {
   5809   1.3  christos       return action_list->map.entry[a].removed;
   5810   1.3  christos     }
   5811   1.8  christos   else if (action_list->map.entry[a].offset == offset)
   5812   1.3  christos     {
   5813   1.1  christos       return before_fill ?
   5814   1.1  christos 	action_list->map.entry[a].eq_removed_before_fill :
   5815   1.1  christos 	action_list->map.entry[a].eq_removed;
   5816   1.1  christos     }
   5817   1.1  christos   else
   5818   1.1  christos     {
   5819   1.1  christos       return 0;
   5820   1.1  christos     }
   5821   1.3  christos }
   5822   1.1  christos 
   5823   1.3  christos static bfd_vma
   5824   1.3  christos offset_with_removed_text_map (text_action_list *action_list, bfd_vma offset)
   5825   1.3  christos {
   5826   1.3  christos   int removed = removed_by_actions_map (action_list, offset, false);
   5827   1.3  christos   return offset - removed;
   5828   1.3  christos }
   5829   1.3  christos 
   5830   1.3  christos 
   5831   1.3  christos /* The find_insn_action routine will only find non-fill actions.  */
   5832   1.3  christos 
   5833   1.3  christos static text_action *
   5834   1.3  christos find_insn_action (text_action_list *action_list, bfd_vma offset)
   5835   1.3  christos {
   5836   1.3  christos   static const text_action_t action[] =
   5837   1.3  christos     {
   5838   1.3  christos       ta_convert_longcall,
   5839   1.3  christos       ta_remove_longcall,
   5840   1.3  christos       ta_widen_insn,
   5841   1.1  christos       ta_narrow_insn,
   5842   1.1  christos       ta_remove_insn,
   5843   1.1  christos     };
   5844   1.1  christos   text_action a;
   5845   1.1  christos   unsigned i;
   5846   1.1  christos 
   5847   1.1  christos   a.offset = offset;
   5848   1.1  christos   for (i = 0; i < sizeof (action) / sizeof (*action); ++i)
   5849   1.3  christos     {
   5850   1.3  christos       splay_tree_node node;
   5851   1.3  christos 
   5852   1.3  christos       a.action = action[i];
   5853   1.3  christos       node = splay_tree_lookup (action_list->tree, (splay_tree_key)&a);
   5854   1.3  christos       if (node)
   5855   1.3  christos 	return (text_action *)node->value;
   5856   1.3  christos     }
   5857   1.3  christos   return NULL;
   5858   1.3  christos }
   5859   1.3  christos 
   5860   1.3  christos 
   5861   1.3  christos #if DEBUG
   5862   1.3  christos 
   5863   1.3  christos static void
   5864   1.3  christos print_action (FILE *fp, text_action *r)
   5865   1.3  christos {
   5866   1.3  christos   const char *t = "unknown";
   5867   1.3  christos   switch (r->action)
   5868   1.3  christos     {
   5869   1.3  christos     case ta_remove_insn:
   5870   1.3  christos       t = "remove_insn"; break;
   5871   1.3  christos     case ta_remove_longcall:
   5872   1.3  christos       t = "remove_longcall"; break;
   5873   1.3  christos     case ta_convert_longcall:
   5874   1.3  christos       t = "convert_longcall"; break;
   5875   1.3  christos     case ta_narrow_insn:
   5876   1.3  christos       t = "narrow_insn"; break;
   5877   1.3  christos     case ta_widen_insn:
   5878   1.3  christos       t = "widen_insn"; break;
   5879   1.3  christos     case ta_fill:
   5880   1.3  christos       t = "fill"; break;
   5881   1.3  christos     case ta_none:
   5882   1.3  christos       t = "none"; break;
   5883   1.3  christos     case ta_remove_literal:
   5884   1.3  christos       t = "remove_literal"; break;
   5885   1.3  christos     case ta_add_literal:
   5886   1.3  christos       t = "add_literal"; break;
   5887   1.3  christos     }
   5888   1.3  christos 
   5889   1.1  christos   fprintf (fp, "%s: %s[0x%lx] \"%s\" %d\n",
   5890   1.1  christos 	   r->sec->owner->filename,
   5891   1.1  christos 	   r->sec->name, (unsigned long) r->offset, t, r->removed_bytes);
   5892   1.3  christos }
   5893   1.1  christos 
   5894   1.1  christos static int
   5895   1.1  christos print_action_list_fn (splay_tree_node node, void *p)
   5896   1.1  christos {
   5897   1.1  christos   text_action *r = (text_action *)node->value;
   5898   1.1  christos 
   5899   1.1  christos   print_action (p, r);
   5900   1.1  christos   return 0;
   5901   1.1  christos }
   5902   1.1  christos 
   5903   1.1  christos static void
   5904   1.1  christos print_action_list (FILE *fp, text_action_list *action_list)
   5905   1.1  christos {
   5906   1.1  christos   fprintf (fp, "Text Action\n");
   5907   1.3  christos   splay_tree_foreach (action_list->tree, print_action_list_fn, fp);
   5908   1.1  christos }
   5909   1.1  christos 
   5910   1.1  christos #endif /* DEBUG */
   5911   1.1  christos 
   5912   1.1  christos 
   5913   1.1  christos /* Lists of literals being coalesced or removed.  */
   5915   1.1  christos 
   5916   1.1  christos /* In the usual case, the literal identified by "from" is being
   5917   1.3  christos    coalesced with another literal identified by "to".  If the literal is
   5918   1.3  christos    unused and is being removed altogether, "to.abfd" will be NULL.
   5919   1.3  christos    The removed_literal entries are kept on a per-section list, sorted
   5920   1.3  christos    by the "from" offset field.  */
   5921   1.3  christos 
   5922   1.3  christos typedef struct removed_literal_struct removed_literal;
   5923   1.1  christos typedef struct removed_literal_map_entry_struct removed_literal_map_entry;
   5924   1.1  christos typedef struct removed_literal_list_struct removed_literal_list;
   5925   1.1  christos 
   5926   1.1  christos struct removed_literal_struct
   5927   1.3  christos {
   5928   1.3  christos   r_reloc from;
   5929   1.3  christos   r_reloc to;
   5930   1.1  christos   removed_literal *next;
   5931   1.1  christos };
   5932   1.1  christos 
   5933   1.1  christos struct removed_literal_map_entry_struct
   5934   1.1  christos {
   5935   1.1  christos   bfd_vma addr;
   5936   1.1  christos   removed_literal *literal;
   5937   1.1  christos };
   5938   1.1  christos 
   5939   1.1  christos struct removed_literal_list_struct
   5940   1.1  christos {
   5941   1.1  christos   removed_literal *head;
   5942   1.1  christos   removed_literal *tail;
   5943   1.1  christos 
   5944   1.1  christos   unsigned n_map;
   5945   1.1  christos   removed_literal_map_entry *map;
   5946   1.1  christos };
   5947   1.1  christos 
   5948   1.1  christos 
   5949   1.1  christos /* Record that the literal at "from" is being removed.  If "to" is not
   5950   1.1  christos    NULL, the "from" literal is being coalesced with the "to" literal.  */
   5951   1.3  christos 
   5952   1.1  christos static void
   5953   1.3  christos add_removed_literal (removed_literal_list *removed_list,
   5954   1.1  christos 		     const r_reloc *from,
   5955   1.1  christos 		     const r_reloc *to)
   5956   1.1  christos {
   5957   1.1  christos   removed_literal *r, *new_r, *next_r;
   5958   1.1  christos 
   5959   1.1  christos   new_r = (removed_literal *) bfd_zmalloc (sizeof (removed_literal));
   5960   1.1  christos 
   5961   1.1  christos   new_r->from = *from;
   5962   1.1  christos   if (to)
   5963   1.1  christos     new_r->to = *to;
   5964   1.1  christos   else
   5965   1.1  christos     new_r->to.abfd = NULL;
   5966   1.3  christos   new_r->next = NULL;
   5967   1.1  christos 
   5968   1.1  christos   r = removed_list->head;
   5969   1.1  christos   if (r == NULL)
   5970   1.1  christos     {
   5971   1.1  christos       removed_list->head = new_r;
   5972   1.1  christos       removed_list->tail = new_r;
   5973   1.1  christos     }
   5974   1.1  christos   /* Special check for common case of append.  */
   5975   1.1  christos   else if (removed_list->tail->from.target_offset < from->target_offset)
   5976   1.1  christos     {
   5977   1.1  christos       removed_list->tail->next = new_r;
   5978   1.3  christos       removed_list->tail = new_r;
   5979   1.3  christos     }
   5980   1.3  christos   else
   5981   1.3  christos     {
   5982   1.3  christos       while (r->from.target_offset < from->target_offset && r->next)
   5983   1.3  christos 	{
   5984   1.3  christos 	  r = r->next;
   5985   1.3  christos 	}
   5986   1.3  christos       next_r = r->next;
   5987   1.3  christos       r->next = new_r;
   5988   1.3  christos       new_r->next = next_r;
   5989   1.3  christos       if (next_r == NULL)
   5990   1.3  christos 	removed_list->tail = new_r;
   5991   1.3  christos     }
   5992   1.3  christos }
   5993   1.3  christos 
   5994   1.3  christos static void
   5995   1.3  christos map_removed_literal (removed_literal_list *removed_list)
   5996   1.3  christos {
   5997   1.3  christos   unsigned n_map = 0;
   5998   1.3  christos   unsigned i;
   5999   1.3  christos   removed_literal_map_entry *map = NULL;
   6000   1.3  christos   removed_literal *r = removed_list->head;
   6001   1.3  christos 
   6002   1.3  christos   for (i = 0; r; ++i, r = r->next)
   6003   1.8  christos     {
   6004   1.8  christos       if (i == n_map)
   6005   1.3  christos 	{
   6006   1.8  christos 	  n_map = (n_map * 2) + 2;
   6007   1.3  christos 	  map = bfd_realloc (map, n_map * sizeof (*map));
   6008   1.3  christos 	}
   6009   1.8  christos       map[i].addr = r->from.target_offset;
   6010   1.3  christos       map[i].literal = r;
   6011   1.1  christos     }
   6012   1.1  christos   removed_list->map = map;
   6013   1.1  christos   removed_list->n_map = i;
   6014   1.1  christos }
   6015   1.1  christos 
   6016   1.1  christos static int
   6017   1.1  christos removed_literal_compare (const void *a, const void *b)
   6018   1.3  christos {
   6019   1.3  christos   const bfd_vma *key = a;
   6020   1.3  christos   const removed_literal_map_entry *memb = b;
   6021   1.3  christos 
   6022   1.3  christos   if (*key == memb->addr)
   6023   1.3  christos     return 0;
   6024   1.8  christos   else
   6025   1.8  christos     return *key < memb->addr ? -1 : 1;
   6026   1.8  christos }
   6027   1.8  christos 
   6028   1.8  christos /* Check if the list of removed literals contains an entry for the
   6029   1.8  christos    given address.  Return the entry if found.  */
   6030   1.8  christos 
   6031   1.8  christos static removed_literal *
   6032   1.8  christos find_removed_literal (removed_literal_list *removed_list, bfd_vma addr)
   6033   1.8  christos {
   6034   1.3  christos   removed_literal_map_entry *p;
   6035   1.3  christos   removed_literal *r = NULL;
   6036   1.1  christos 
   6037   1.1  christos   if (removed_list->map == NULL)
   6038   1.1  christos     map_removed_literal (removed_list);
   6039   1.1  christos 
   6040   1.1  christos   if (removed_list->map != NULL)
   6041   1.1  christos     {
   6042   1.1  christos       p = bsearch (&addr, removed_list->map, removed_list->n_map,
   6043   1.1  christos 		   sizeof (*removed_list->map), removed_literal_compare);
   6044   1.1  christos       if (p)
   6045   1.1  christos 	{
   6046   1.1  christos 	  while (p != removed_list->map && (p - 1)->addr == addr)
   6047   1.1  christos 	    --p;
   6048   1.1  christos 	  r = p->literal;
   6049   1.1  christos 	}
   6050   1.1  christos     }
   6051   1.1  christos   return r;
   6052   1.1  christos }
   6053   1.1  christos 
   6054   1.1  christos 
   6055   1.1  christos #if DEBUG
   6056   1.1  christos 
   6057   1.1  christos static void
   6058   1.1  christos print_removed_literals (FILE *fp, removed_literal_list *removed_list)
   6059   1.1  christos {
   6060   1.1  christos   removed_literal *r;
   6061   1.1  christos   r = removed_list->head;
   6062   1.1  christos   if (r)
   6063   1.1  christos     fprintf (fp, "Removed Literals\n");
   6064   1.1  christos   for (; r != NULL; r = r->next)
   6065   1.1  christos     {
   6066   1.1  christos       print_r_reloc (fp, &r->from);
   6067   1.1  christos       fprintf (fp, " => ");
   6068   1.1  christos       if (r->to.abfd == NULL)
   6069   1.8  christos 	fprintf (fp, "REMOVED");
   6070   1.8  christos       else
   6071   1.1  christos 	print_r_reloc (fp, &r->to);
   6072   1.1  christos       fprintf (fp, "\n");
   6073   1.1  christos     }
   6074   1.1  christos }
   6075   1.1  christos 
   6076   1.1  christos #endif /* DEBUG */
   6077   1.1  christos 
   6078   1.1  christos 
   6079   1.1  christos /* Per-section data for relaxation.  */
   6081   1.1  christos 
   6082   1.1  christos typedef struct reloc_bfd_fix_struct reloc_bfd_fix;
   6083   1.1  christos 
   6084   1.1  christos struct xtensa_relax_info_struct
   6085   1.1  christos {
   6086   1.1  christos   bool is_relaxable_literal_section;
   6087   1.1  christos   bool is_relaxable_asm_section;
   6088   1.1  christos   int visited;				/* Number of times visited.  */
   6089   1.3  christos 
   6090   1.1  christos   source_reloc *src_relocs;		/* Array[src_count].  */
   6091   1.1  christos   int src_count;
   6092   1.1  christos   int src_next;				/* Next src_relocs entry to assign.  */
   6093   1.1  christos 
   6094   1.1  christos   removed_literal_list removed_list;
   6095   1.1  christos   text_action_list action_list;
   6096   1.1  christos 
   6097   1.1  christos   reloc_bfd_fix *fix_list;
   6098   1.1  christos   reloc_bfd_fix *fix_array;
   6099   1.1  christos   unsigned fix_array_count;
   6100   1.1  christos 
   6101   1.8  christos   /* Support for expanding the reloc array that is stored
   6102   1.1  christos      in the section structure.  If the relocations have been
   6103   1.1  christos      reallocated, the newly allocated relocations will be referenced
   6104  1.10  christos      here along with the actual size allocated.  The relocation
   6105   1.1  christos      count will always be found in the section structure.  */
   6106  1.10  christos   Elf_Internal_Rela *allocated_relocs;
   6107  1.10  christos   unsigned relocs_count;
   6108  1.10  christos   unsigned allocated_relocs_count;
   6109  1.10  christos };
   6110   1.1  christos 
   6111   1.1  christos struct elf_xtensa_section_data
   6112   1.1  christos {
   6113   1.1  christos   struct bfd_elf_section_data elf;
   6114   1.1  christos   xtensa_relax_info relax_info;
   6115   1.1  christos };
   6116   1.1  christos 
   6117   1.1  christos 
   6118   1.1  christos static bool
   6119   1.1  christos elf_xtensa_new_section_hook (bfd *abfd, asection *sec)
   6120   1.1  christos {
   6121   1.1  christos   struct elf_xtensa_section_data *sdata;
   6122   1.1  christos 
   6123   1.1  christos   sdata = bfd_zalloc (abfd, sizeof (*sdata));
   6124   1.1  christos   if (sdata == NULL)
   6125   1.1  christos     return false;
   6126   1.1  christos   sec->used_by_bfd = sdata;
   6127   1.1  christos 
   6128   1.1  christos   return _bfd_elf_new_section_hook (abfd, sec);
   6129   1.1  christos }
   6130   1.1  christos 
   6131   1.1  christos 
   6132   1.1  christos static xtensa_relax_info *
   6133   1.1  christos get_xtensa_relax_info (asection *sec)
   6134   1.8  christos {
   6135   1.8  christos   struct elf_xtensa_section_data *section_data;
   6136   1.1  christos 
   6137   1.1  christos   /* No info available if no section or if it is an output section.  */
   6138   1.1  christos   if (!sec || sec == sec->output_section)
   6139   1.1  christos     return NULL;
   6140   1.1  christos 
   6141   1.1  christos   section_data = (struct elf_xtensa_section_data *) elf_section_data (sec);
   6142   1.1  christos   return &section_data->relax_info;
   6143   1.1  christos }
   6144   1.1  christos 
   6145   1.3  christos 
   6146   1.3  christos static void
   6147   1.3  christos init_xtensa_relax_info (asection *sec)
   6148   1.3  christos {
   6149   1.1  christos   xtensa_relax_info *relax_info = get_xtensa_relax_info (sec);
   6150   1.1  christos 
   6151   1.1  christos   relax_info->is_relaxable_literal_section = false;
   6152   1.1  christos   relax_info->is_relaxable_asm_section = false;
   6153   1.1  christos   relax_info->visited = 0;
   6154   1.3  christos 
   6155   1.1  christos   relax_info->src_relocs = NULL;
   6156   1.1  christos   relax_info->src_count = 0;
   6157   1.1  christos   relax_info->src_next = 0;
   6158   1.1  christos 
   6159   1.1  christos   relax_info->removed_list.head = NULL;
   6160   1.1  christos   relax_info->removed_list.tail = NULL;
   6161   1.1  christos 
   6162   1.1  christos   relax_info->action_list.tree = splay_tree_new (text_action_compare,
   6163   1.1  christos 						 NULL, NULL);
   6164   1.1  christos   relax_info->action_list.map.n_entries = 0;
   6165   1.1  christos   relax_info->action_list.map.entry = NULL;
   6166   1.1  christos 
   6167   1.1  christos   relax_info->fix_list = NULL;
   6168   1.1  christos   relax_info->fix_array = NULL;
   6169   1.1  christos   relax_info->fix_array_count = 0;
   6170   1.1  christos 
   6171   1.1  christos   relax_info->allocated_relocs = NULL;
   6172   1.1  christos   relax_info->relocs_count = 0;
   6173   1.1  christos   relax_info->allocated_relocs_count = 0;
   6174   1.3  christos }
   6175   1.1  christos 
   6176   1.1  christos 
   6177   1.8  christos /* Coalescing literals may require a relocation to refer to a section in
   6179   1.1  christos    a different input file, but the standard relocation information
   6180   1.1  christos    cannot express that.  Instead, the reloc_bfd_fix structures are used
   6181   1.1  christos    to "fix" the relocations that refer to sections in other input files.
   6182   1.1  christos    These structures are kept on per-section lists.  The "src_type" field
   6183   1.1  christos    records the relocation type in case there are multiple relocations on
   6184   1.1  christos    the same location.  FIXME: This is ugly; an alternative might be to
   6185   1.1  christos    add new symbols with the "owner" field to some other input file.  */
   6186   1.1  christos 
   6187   1.1  christos struct reloc_bfd_fix_struct
   6188   1.1  christos {
   6189   1.8  christos   asection *src_sec;
   6190   1.1  christos   bfd_vma src_offset;
   6191   1.1  christos   unsigned src_type;			/* Relocation type.  */
   6192   1.1  christos 
   6193   1.1  christos   asection *target_sec;
   6194   1.1  christos   bfd_vma target_offset;
   6195   1.1  christos   bool translated;
   6196   1.1  christos 
   6197   1.1  christos   reloc_bfd_fix *next;
   6198   1.1  christos };
   6199   1.1  christos 
   6200   1.1  christos 
   6201   1.1  christos static reloc_bfd_fix *
   6202   1.1  christos reloc_bfd_fix_init (asection *src_sec,
   6203   1.1  christos 		    bfd_vma src_offset,
   6204   1.1  christos 		    unsigned src_type,
   6205   1.1  christos 		    asection *target_sec,
   6206   1.1  christos 		    bfd_vma target_offset,
   6207   1.1  christos 		    bool translated)
   6208   1.1  christos {
   6209   1.1  christos   reloc_bfd_fix *fix;
   6210   1.1  christos 
   6211   1.1  christos   fix = (reloc_bfd_fix *) bfd_malloc (sizeof (reloc_bfd_fix));
   6212   1.1  christos   fix->src_sec = src_sec;
   6213   1.1  christos   fix->src_offset = src_offset;
   6214   1.1  christos   fix->src_type = src_type;
   6215   1.1  christos   fix->target_sec = target_sec;
   6216   1.1  christos   fix->target_offset = target_offset;
   6217   1.1  christos   fix->translated = translated;
   6218   1.1  christos 
   6219   1.1  christos   return fix;
   6220   1.1  christos }
   6221   1.1  christos 
   6222   1.1  christos 
   6223   1.1  christos static void
   6224   1.1  christos add_fix (asection *src_sec, reloc_bfd_fix *fix)
   6225   1.1  christos {
   6226   1.1  christos   xtensa_relax_info *relax_info;
   6227   1.1  christos 
   6228   1.1  christos   relax_info = get_xtensa_relax_info (src_sec);
   6229   1.1  christos   fix->next = relax_info->fix_list;
   6230   1.1  christos   relax_info->fix_list = fix;
   6231   1.1  christos }
   6232   1.1  christos 
   6233   1.1  christos 
   6234   1.1  christos static int
   6235   1.1  christos fix_compare (const void *ap, const void *bp)
   6236   1.1  christos {
   6237   1.1  christos   const reloc_bfd_fix *a = (const reloc_bfd_fix *) ap;
   6238   1.1  christos   const reloc_bfd_fix *b = (const reloc_bfd_fix *) bp;
   6239   1.1  christos 
   6240   1.1  christos   if (a->src_offset != b->src_offset)
   6241   1.1  christos     return (a->src_offset - b->src_offset);
   6242   1.1  christos   return (a->src_type - b->src_type);
   6243   1.1  christos }
   6244   1.1  christos 
   6245   1.1  christos 
   6246   1.1  christos static void
   6247   1.1  christos cache_fix_array (asection *sec)
   6248   1.1  christos {
   6249   1.1  christos   unsigned i, count = 0;
   6250   1.1  christos   reloc_bfd_fix *r;
   6251   1.1  christos   xtensa_relax_info *relax_info = get_xtensa_relax_info (sec);
   6252   1.1  christos 
   6253   1.1  christos   if (relax_info == NULL)
   6254   1.1  christos     return;
   6255   1.1  christos   if (relax_info->fix_list == NULL)
   6256   1.1  christos     return;
   6257   1.1  christos 
   6258   1.1  christos   for (r = relax_info->fix_list; r != NULL; r = r->next)
   6259   1.1  christos     count++;
   6260   1.1  christos 
   6261   1.1  christos   relax_info->fix_array =
   6262   1.1  christos     (reloc_bfd_fix *) bfd_malloc (sizeof (reloc_bfd_fix) * count);
   6263   1.1  christos   relax_info->fix_array_count = count;
   6264   1.1  christos 
   6265   1.1  christos   r = relax_info->fix_list;
   6266   1.1  christos   for (i = 0; i < count; i++, r = r->next)
   6267   1.1  christos     {
   6268   1.1  christos       relax_info->fix_array[count - 1 - i] = *r;
   6269   1.1  christos       relax_info->fix_array[count - 1 - i].next = NULL;
   6270   1.1  christos     }
   6271   1.1  christos 
   6272   1.1  christos   qsort (relax_info->fix_array, relax_info->fix_array_count,
   6273   1.1  christos 	 sizeof (reloc_bfd_fix), fix_compare);
   6274   1.1  christos }
   6275   1.1  christos 
   6276   1.1  christos 
   6277   1.1  christos static reloc_bfd_fix *
   6278   1.1  christos get_bfd_fix (asection *sec, bfd_vma offset, unsigned type)
   6279   1.1  christos {
   6280   1.1  christos   xtensa_relax_info *relax_info = get_xtensa_relax_info (sec);
   6281   1.1  christos   reloc_bfd_fix *rv;
   6282   1.1  christos   reloc_bfd_fix key;
   6283   1.1  christos 
   6284   1.1  christos   if (relax_info == NULL)
   6285   1.1  christos     return NULL;
   6286   1.1  christos   if (relax_info->fix_list == NULL)
   6287   1.1  christos     return NULL;
   6288   1.1  christos 
   6289   1.1  christos   if (relax_info->fix_array == NULL)
   6290   1.1  christos     cache_fix_array (sec);
   6291   1.1  christos 
   6292   1.1  christos   key.src_offset = offset;
   6293   1.1  christos   key.src_type = type;
   6294   1.1  christos   rv = bsearch (&key, relax_info->fix_array,  relax_info->fix_array_count,
   6295   1.1  christos 		sizeof (reloc_bfd_fix), fix_compare);
   6296   1.1  christos   return rv;
   6297   1.1  christos }
   6298   1.1  christos 
   6299   1.1  christos 
   6300   1.1  christos /* Section caching.  */
   6302   1.1  christos 
   6303   1.1  christos typedef struct section_cache_struct section_cache_t;
   6304   1.1  christos 
   6305   1.1  christos struct section_cache_struct
   6306   1.1  christos {
   6307   1.1  christos   asection *sec;
   6308   1.1  christos 
   6309   1.3  christos   bfd_byte *contents;		/* Cache of the section contents.  */
   6310   1.1  christos   bfd_size_type content_length;
   6311   1.1  christos 
   6312   1.1  christos   property_table_entry *ptbl;	/* Cache of the section property table.  */
   6313   1.1  christos   unsigned pte_count;
   6314   1.1  christos 
   6315   1.8  christos   Elf_Internal_Rela *relocs;	/* Cache of the section relocations.  */
   6316   1.1  christos   unsigned reloc_count;
   6317   1.1  christos };
   6318   1.1  christos 
   6319   1.1  christos 
   6320   1.8  christos static void
   6321   1.1  christos init_section_cache (section_cache_t *sec_cache)
   6322   1.1  christos {
   6323   1.1  christos   memset (sec_cache, 0, sizeof (*sec_cache));
   6324   1.1  christos }
   6325   1.1  christos 
   6326   1.1  christos 
   6327   1.1  christos static void
   6328   1.1  christos free_section_cache (section_cache_t *sec_cache)
   6329   1.1  christos {
   6330   1.1  christos   if (sec_cache->sec)
   6331   1.1  christos     {
   6332   1.1  christos       release_contents (sec_cache->sec, sec_cache->contents);
   6333   1.8  christos       release_internal_relocs (sec_cache->sec, sec_cache->relocs);
   6334   1.1  christos       free (sec_cache->ptbl);
   6335   1.8  christos     }
   6336   1.1  christos }
   6337   1.1  christos 
   6338   1.1  christos 
   6339   1.1  christos static bool
   6340   1.1  christos section_cache_section (section_cache_t *sec_cache,
   6341   1.1  christos 		       asection *sec,
   6342   1.1  christos 		       struct bfd_link_info *link_info)
   6343   1.1  christos {
   6344   1.1  christos   bfd *abfd;
   6345   1.1  christos   property_table_entry *prop_table = NULL;
   6346   1.1  christos   int ptblsize = 0;
   6347   1.1  christos   bfd_byte *contents = NULL;
   6348   1.1  christos   Elf_Internal_Rela *internal_relocs = NULL;
   6349   1.1  christos   bfd_size_type sec_size;
   6350   1.1  christos 
   6351   1.8  christos   if (sec == NULL)
   6352   1.1  christos     return false;
   6353   1.1  christos   if (sec == sec_cache->sec)
   6354   1.1  christos     return true;
   6355   1.1  christos 
   6356   1.3  christos   abfd = sec->owner;
   6357   1.3  christos   sec_size = bfd_get_section_limit (abfd, sec);
   6358   1.1  christos 
   6359   1.1  christos   /* Get the contents.  */
   6360   1.1  christos   contents = retrieve_contents (abfd, sec, link_info->keep_memory);
   6361   1.1  christos   if (contents == NULL && sec_size != 0)
   6362   1.1  christos     goto err;
   6363   1.1  christos 
   6364   1.1  christos   /* Get the relocations.  */
   6365   1.1  christos   internal_relocs = retrieve_internal_relocs (abfd, sec,
   6366   1.1  christos 					      link_info->keep_memory);
   6367   1.8  christos 
   6368   1.1  christos   /* Get the entry table.  */
   6369   1.1  christos   ptblsize = xtensa_read_table_entries (abfd, sec, &prop_table,
   6370   1.1  christos 					XTENSA_PROP_SEC_NAME, false);
   6371   1.1  christos   if (ptblsize < 0)
   6372   1.8  christos     goto err;
   6373   1.8  christos 
   6374   1.1  christos   /* Fill in the new section cache.  */
   6375   1.1  christos   free_section_cache (sec_cache);
   6376   1.1  christos   init_section_cache (sec_cache);
   6377   1.1  christos 
   6378   1.1  christos   sec_cache->sec = sec;
   6379   1.1  christos   sec_cache->contents = contents;
   6380   1.1  christos   sec_cache->content_length = sec_size;
   6381   1.1  christos   sec_cache->relocs = internal_relocs;
   6382   1.1  christos   sec_cache->reloc_count = sec->reloc_count;
   6383   1.1  christos   sec_cache->pte_count = ptblsize;
   6384   1.1  christos   sec_cache->ptbl = prop_table;
   6385   1.1  christos 
   6386   1.1  christos   return true;
   6387   1.1  christos 
   6388   1.1  christos  err:
   6389   1.1  christos   release_contents (sec, contents);
   6390   1.1  christos   release_internal_relocs (sec, internal_relocs);
   6391   1.1  christos   free (prop_table);
   6392   1.1  christos   return false;
   6393   1.1  christos }
   6394   1.1  christos 
   6395   1.1  christos 
   6396   1.1  christos /* Extended basic blocks.  */
   6398   1.1  christos 
   6399   1.1  christos /* An ebb_struct represents an Extended Basic Block.  Within this
   6400   1.1  christos    range, we guarantee that all instructions are decodable, the
   6401   1.1  christos    property table entries are contiguous, and no property table
   6402   1.1  christos    specifies a segment that cannot have instructions moved.  This
   6403   1.1  christos    structure contains caches of the contents, property table and
   6404   1.1  christos    relocations for the specified section for easy use.  The range is
   6405   1.1  christos    specified by ranges of indices for the byte offset, property table
   6406   1.1  christos    offsets and relocation offsets.  These must be consistent.  */
   6407   1.1  christos 
   6408   1.1  christos typedef struct ebb_struct ebb_t;
   6409   1.1  christos 
   6410   1.1  christos struct ebb_struct
   6411   1.8  christos {
   6412   1.1  christos   asection *sec;
   6413   1.1  christos 
   6414   1.1  christos   bfd_byte *contents;		/* Cache of the section contents.  */
   6415   1.1  christos   bfd_size_type content_length;
   6416   1.1  christos 
   6417   1.1  christos   property_table_entry *ptbl;	/* Cache of the section property table.  */
   6418   1.1  christos   unsigned pte_count;
   6419   1.1  christos 
   6420   1.1  christos   Elf_Internal_Rela *relocs;	/* Cache of the section relocations.  */
   6421   1.1  christos   unsigned reloc_count;
   6422   1.1  christos 
   6423   1.1  christos   bfd_vma start_offset;		/* Offset in section.  */
   6424   1.1  christos   unsigned start_ptbl_idx;	/* Offset in the property table.  */
   6425   1.1  christos   unsigned start_reloc_idx;	/* Offset in the relocations.  */
   6426   1.1  christos 
   6427   1.1  christos   bfd_vma end_offset;
   6428   1.1  christos   unsigned end_ptbl_idx;
   6429   1.1  christos   unsigned end_reloc_idx;
   6430   1.1  christos 
   6431   1.1  christos   bool ends_section;	/* Is this the last ebb in a section?  */
   6432   1.1  christos 
   6433   1.1  christos   /* The unreachable property table at the end of this set of blocks;
   6434   1.1  christos      NULL if the end is not an unreachable block.  */
   6435   1.1  christos   property_table_entry *ends_unreachable;
   6436   1.1  christos };
   6437   1.1  christos 
   6438   1.1  christos 
   6439   1.1  christos enum ebb_target_enum
   6440   1.1  christos {
   6441   1.1  christos   EBB_NO_ALIGN = 0,
   6442   1.1  christos   EBB_DESIRE_TGT_ALIGN,
   6443   1.1  christos   EBB_REQUIRE_TGT_ALIGN,
   6444   1.1  christos   EBB_REQUIRE_LOOP_ALIGN,
   6445   1.1  christos   EBB_REQUIRE_ALIGN
   6446   1.8  christos };
   6447   1.1  christos 
   6448   1.1  christos 
   6449   1.1  christos /* proposed_action_struct is similar to the text_action_struct except
   6450   1.1  christos    that is represents a potential transformation, not one that will
   6451   1.1  christos    occur.  We build a list of these for an extended basic block
   6452   1.1  christos    and use them to compute the actual actions desired.  We must be
   6453   1.1  christos    careful that the entire set of actual actions we perform do not
   6454   1.1  christos    break any relocations that would fit if the actions were not
   6455   1.1  christos    performed.  */
   6456   1.1  christos 
   6457   1.1  christos typedef struct proposed_action_struct proposed_action;
   6458   1.8  christos 
   6459   1.1  christos struct proposed_action_struct
   6460   1.1  christos {
   6461   1.1  christos   enum ebb_target_enum align_type; /* for the target alignment */
   6462   1.1  christos   bfd_vma alignment_pow;
   6463   1.1  christos   text_action_t action;
   6464   1.1  christos   bfd_vma offset;
   6465   1.8  christos   int removed_bytes;
   6466   1.1  christos   bool do_action; /* If false, then we will not perform the action.  */
   6467   1.1  christos };
   6468   1.1  christos 
   6469   1.1  christos 
   6470   1.1  christos /* The ebb_constraint_struct keeps a set of proposed actions for an
   6471   1.1  christos    extended basic block.   */
   6472   1.1  christos 
   6473   1.1  christos typedef struct ebb_constraint_struct ebb_constraint;
   6474   1.1  christos 
   6475   1.1  christos struct ebb_constraint_struct
   6476   1.1  christos {
   6477   1.1  christos   ebb_t ebb;
   6478   1.1  christos   bool start_movable;
   6479   1.1  christos 
   6480   1.1  christos   /* Bytes of extra space at the beginning if movable.  */
   6481   1.1  christos   int start_extra_space;
   6482   1.1  christos 
   6483   1.1  christos   enum ebb_target_enum start_align;
   6484   1.1  christos 
   6485   1.1  christos   bool end_movable;
   6486   1.1  christos 
   6487   1.1  christos   /* Bytes of extra space at the end if movable.  */
   6488   1.1  christos   int end_extra_space;
   6489   1.1  christos 
   6490   1.1  christos   unsigned action_count;
   6491   1.8  christos   unsigned action_allocated;
   6492   1.1  christos 
   6493   1.1  christos   /* Array of proposed actions.  */
   6494   1.1  christos   proposed_action *actions;
   6495   1.1  christos 
   6496   1.1  christos   /* Action alignments -- one for each proposed action.  */
   6497   1.1  christos   enum ebb_target_enum *action_aligns;
   6498   1.1  christos };
   6499   1.1  christos 
   6500   1.1  christos 
   6501   1.1  christos static void
   6502   1.1  christos init_ebb_constraint (ebb_constraint *c)
   6503   1.1  christos {
   6504   1.1  christos   memset (c, 0, sizeof (ebb_constraint));
   6505   1.1  christos }
   6506   1.1  christos 
   6507   1.1  christos 
   6508   1.1  christos static void
   6509   1.1  christos free_ebb_constraint (ebb_constraint *c)
   6510   1.1  christos {
   6511   1.1  christos   free (c->actions);
   6512   1.1  christos }
   6513   1.1  christos 
   6514   1.1  christos 
   6515   1.1  christos static void
   6516   1.1  christos init_ebb (ebb_t *ebb,
   6517   1.1  christos 	  asection *sec,
   6518   1.1  christos 	  bfd_byte *contents,
   6519   1.1  christos 	  bfd_size_type content_length,
   6520   1.1  christos 	  property_table_entry *prop_table,
   6521   1.1  christos 	  unsigned ptblsize,
   6522   1.1  christos 	  Elf_Internal_Rela *internal_relocs,
   6523   1.1  christos 	  unsigned reloc_count)
   6524   1.1  christos {
   6525   1.1  christos   memset (ebb, 0, sizeof (ebb_t));
   6526   1.1  christos   ebb->sec = sec;
   6527   1.1  christos   ebb->contents = contents;
   6528   1.8  christos   ebb->content_length = content_length;
   6529   1.8  christos   ebb->ptbl = prop_table;
   6530   1.1  christos   ebb->pte_count = ptblsize;
   6531   1.1  christos   ebb->relocs = internal_relocs;
   6532   1.1  christos   ebb->reloc_count = reloc_count;
   6533   1.8  christos   ebb->start_offset = 0;
   6534   1.1  christos   ebb->end_offset = ebb->content_length - 1;
   6535   1.1  christos   ebb->start_ptbl_idx = 0;
   6536   1.1  christos   ebb->end_ptbl_idx = ptblsize;
   6537   1.8  christos   ebb->start_reloc_idx = 0;
   6538   1.1  christos   ebb->end_reloc_idx = reloc_count;
   6539   1.8  christos }
   6540   1.8  christos 
   6541   1.1  christos 
   6542   1.1  christos /* Extend the ebb to all decodable contiguous sections.  The algorithm
   6543   1.1  christos    for building a basic block around an instruction is to push it
   6544   1.8  christos    forward until we hit the end of a section, an unreachable block or
   6545   1.1  christos    a block that cannot be transformed.  Then we push it backwards
   6546   1.1  christos    searching for similar conditions.  */
   6547   1.1  christos 
   6548   1.1  christos static bool extend_ebb_bounds_forward (ebb_t *);
   6549   1.1  christos static bool extend_ebb_bounds_backward (ebb_t *);
   6550   1.1  christos static bfd_size_type insn_block_decodable_len
   6551   1.1  christos   (bfd_byte *, bfd_size_type, bfd_vma, bfd_size_type);
   6552   1.1  christos 
   6553   1.1  christos static bool
   6554   1.1  christos extend_ebb_bounds (ebb_t *ebb)
   6555   1.1  christos {
   6556   1.1  christos   if (!extend_ebb_bounds_forward (ebb))
   6557   1.1  christos     return false;
   6558   1.1  christos   if (!extend_ebb_bounds_backward (ebb))
   6559   1.1  christos     return false;
   6560   1.1  christos   return true;
   6561   1.1  christos }
   6562   1.1  christos 
   6563   1.1  christos 
   6564   1.1  christos static bool
   6565   1.1  christos extend_ebb_bounds_forward (ebb_t *ebb)
   6566   1.1  christos {
   6567   1.6  christos   property_table_entry *the_entry, *new_entry;
   6568   1.6  christos 
   6569   1.6  christos   the_entry = &ebb->ptbl[ebb->end_ptbl_idx];
   6570   1.6  christos 
   6571   1.6  christos   /* Stop when (1) we cannot decode an instruction, (2) we are at
   6572   1.6  christos      the end of the property tables, (3) we hit a non-contiguous property
   6573   1.8  christos      table entry, (4) we hit a NO_TRANSFORM region.  */
   6574   1.1  christos 
   6575   1.1  christos   while (1)
   6576   1.1  christos     {
   6577   1.1  christos       bfd_vma entry_end;
   6578   1.8  christos       bfd_size_type insn_block_len;
   6579   1.1  christos 
   6580   1.1  christos       entry_end = the_entry->address - ebb->sec->vma + the_entry->size;
   6581   1.1  christos       insn_block_len =
   6582   1.1  christos 	insn_block_decodable_len (ebb->contents, ebb->content_length,
   6583   1.1  christos 				  ebb->end_offset,
   6584   1.1  christos 				  entry_end - ebb->end_offset);
   6585   1.1  christos       if (insn_block_len != (entry_end - ebb->end_offset))
   6586   1.1  christos 	{
   6587   1.1  christos 	  _bfd_error_handler
   6588   1.1  christos 	    /* xgettext:c-format */
   6589   1.8  christos 	    (_("%pB(%pA+%#" PRIx64 "): could not decode instruction; "
   6590   1.1  christos 	       "possible configuration mismatch"),
   6591   1.1  christos 	     ebb->sec->owner, ebb->sec,
   6592   1.1  christos 	     (uint64_t) (ebb->end_offset + insn_block_len));
   6593   1.1  christos 	  return false;
   6594   1.1  christos 	}
   6595   1.1  christos       ebb->end_offset += insn_block_len;
   6596   1.1  christos 
   6597   1.1  christos       if (ebb->end_offset == ebb->sec->size)
   6598   1.1  christos 	ebb->ends_section = true;
   6599   1.1  christos 
   6600   1.1  christos       /* Update the reloc counter.  */
   6601   1.1  christos       while (ebb->end_reloc_idx + 1 < ebb->reloc_count
   6602   1.1  christos 	     && (ebb->relocs[ebb->end_reloc_idx + 1].r_offset
   6603   1.1  christos 		 < ebb->end_offset))
   6604   1.1  christos 	{
   6605   1.1  christos 	  ebb->end_reloc_idx++;
   6606   1.1  christos 	}
   6607   1.1  christos 
   6608   1.8  christos       if (ebb->end_ptbl_idx + 1 == ebb->pte_count)
   6609   1.1  christos 	return true;
   6610   1.1  christos 
   6611   1.1  christos       new_entry = &ebb->ptbl[ebb->end_ptbl_idx + 1];
   6612   1.1  christos       if (((new_entry->flags & XTENSA_PROP_INSN) == 0)
   6613   1.1  christos 	  || ((new_entry->flags & XTENSA_PROP_NO_TRANSFORM) != 0)
   6614   1.1  christos 	  || ((the_entry->flags & XTENSA_PROP_ALIGN) != 0))
   6615   1.1  christos 	break;
   6616   1.1  christos 
   6617   1.1  christos       if (the_entry->address + the_entry->size != new_entry->address)
   6618   1.1  christos 	break;
   6619   1.8  christos 
   6620   1.1  christos       the_entry = new_entry;
   6621   1.1  christos       ebb->end_ptbl_idx++;
   6622   1.1  christos     }
   6623   1.8  christos 
   6624   1.1  christos   /* Quick check for an unreachable or end of file just at the end.  */
   6625   1.1  christos   if (ebb->end_ptbl_idx + 1 == ebb->pte_count)
   6626   1.1  christos     {
   6627   1.1  christos       if (ebb->end_offset == ebb->content_length)
   6628   1.1  christos 	ebb->ends_section = true;
   6629   1.1  christos     }
   6630   1.1  christos   else
   6631   1.1  christos     {
   6632   1.1  christos       new_entry = &ebb->ptbl[ebb->end_ptbl_idx + 1];
   6633   1.1  christos       if ((new_entry->flags & XTENSA_PROP_UNREACHABLE) != 0
   6634   1.1  christos 	  && the_entry->address + the_entry->size == new_entry->address)
   6635   1.1  christos 	ebb->ends_unreachable = new_entry;
   6636   1.1  christos     }
   6637   1.1  christos 
   6638   1.1  christos   /* Any other ending requires exact alignment.  */
   6639   1.1  christos   return true;
   6640   1.1  christos }
   6641   1.1  christos 
   6642   1.1  christos 
   6643   1.1  christos static bool
   6644   1.1  christos extend_ebb_bounds_backward (ebb_t *ebb)
   6645   1.1  christos {
   6646   1.6  christos   property_table_entry *the_entry, *new_entry;
   6647   1.6  christos 
   6648   1.6  christos   the_entry = &ebb->ptbl[ebb->start_ptbl_idx];
   6649   1.6  christos 
   6650   1.6  christos   /* Stop when (1) we cannot decode the instructions in the current entry.
   6651   1.6  christos      (2) we are at the beginning of the property tables, (3) we hit a
   6652   1.8  christos      non-contiguous property table entry, (4) we hit a NO_TRANSFORM region.  */
   6653   1.1  christos 
   6654   1.1  christos   while (1)
   6655   1.1  christos     {
   6656   1.1  christos       bfd_vma block_begin;
   6657   1.1  christos       bfd_size_type insn_block_len;
   6658   1.1  christos 
   6659   1.1  christos       block_begin = the_entry->address - ebb->sec->vma;
   6660   1.1  christos       insn_block_len =
   6661   1.1  christos 	insn_block_decodable_len (ebb->contents, ebb->content_length,
   6662   1.1  christos 				  block_begin,
   6663   1.1  christos 				  ebb->start_offset - block_begin);
   6664   1.1  christos       if (insn_block_len != ebb->start_offset - block_begin)
   6665   1.8  christos 	{
   6666   1.1  christos 	  _bfd_error_handler
   6667   1.1  christos 	    /* xgettext:c-format */
   6668   1.1  christos 	    (_("%pB(%pA+%#" PRIx64 "): could not decode instruction; "
   6669   1.1  christos 	       "possible configuration mismatch"),
   6670   1.1  christos 	     ebb->sec->owner, ebb->sec,
   6671   1.8  christos 	     (uint64_t) (ebb->end_offset + insn_block_len));
   6672   1.1  christos 	  return false;
   6673   1.8  christos 	}
   6674   1.1  christos       ebb->start_offset -= insn_block_len;
   6675   1.1  christos 
   6676   1.1  christos       /* Update the reloc counter.  */
   6677   1.1  christos       while (ebb->start_reloc_idx > 0
   6678   1.8  christos 	     && (ebb->relocs[ebb->start_reloc_idx - 1].r_offset
   6679   1.1  christos 		 >= ebb->start_offset))
   6680   1.1  christos 	{
   6681   1.1  christos 	  ebb->start_reloc_idx--;
   6682   1.1  christos 	}
   6683   1.1  christos 
   6684   1.1  christos       if (ebb->start_ptbl_idx == 0)
   6685   1.1  christos 	return true;
   6686   1.1  christos 
   6687   1.1  christos       new_entry = &ebb->ptbl[ebb->start_ptbl_idx - 1];
   6688   1.1  christos       if ((new_entry->flags & XTENSA_PROP_INSN) == 0
   6689   1.1  christos 	  || ((new_entry->flags & XTENSA_PROP_NO_TRANSFORM) != 0)
   6690   1.1  christos 	  || ((new_entry->flags & XTENSA_PROP_ALIGN) != 0))
   6691   1.1  christos 	return true;
   6692   1.1  christos       if (new_entry->address + new_entry->size != the_entry->address)
   6693   1.1  christos 	return true;
   6694   1.1  christos 
   6695   1.1  christos       the_entry = new_entry;
   6696   1.1  christos       ebb->start_ptbl_idx--;
   6697   1.1  christos     }
   6698   1.1  christos   return true;
   6699   1.1  christos }
   6700   1.1  christos 
   6701   1.1  christos 
   6702   1.1  christos static bfd_size_type
   6703   1.1  christos insn_block_decodable_len (bfd_byte *contents,
   6704   1.1  christos 			  bfd_size_type content_len,
   6705   1.1  christos 			  bfd_vma block_offset,
   6706   1.1  christos 			  bfd_size_type block_len)
   6707   1.1  christos {
   6708   1.1  christos   bfd_vma offset = block_offset;
   6709   1.1  christos 
   6710   1.8  christos   while (offset < block_offset + block_len)
   6711   1.1  christos     {
   6712   1.1  christos       bfd_size_type insn_len = 0;
   6713   1.1  christos 
   6714   1.1  christos       insn_len = insn_decode_len (contents, content_len, offset);
   6715   1.1  christos       if (insn_len == 0)
   6716   1.1  christos 	return (offset - block_offset);
   6717   1.1  christos       offset += insn_len;
   6718   1.1  christos     }
   6719   1.1  christos   return (offset - block_offset);
   6720   1.1  christos }
   6721   1.1  christos 
   6722   1.1  christos 
   6723   1.1  christos static void
   6724   1.1  christos ebb_propose_action (ebb_constraint *c,
   6725   1.8  christos 		    enum ebb_target_enum align_type,
   6726   1.1  christos 		    bfd_vma alignment_pow,
   6727   1.1  christos 		    text_action_t action,
   6728   1.1  christos 		    bfd_vma offset,
   6729   1.1  christos 		    int removed_bytes,
   6730   1.1  christos 		    bool do_action)
   6731   1.1  christos {
   6732   1.1  christos   proposed_action *act;
   6733   1.1  christos 
   6734   1.1  christos   if (c->action_allocated <= c->action_count)
   6735   1.1  christos     {
   6736   1.1  christos       unsigned new_allocated, i;
   6737   1.1  christos       proposed_action *new_actions;
   6738   1.1  christos 
   6739   1.1  christos       new_allocated = (c->action_count + 2) * 2;
   6740   1.1  christos       new_actions = (proposed_action *)
   6741   1.1  christos 	bfd_zmalloc (sizeof (proposed_action) * new_allocated);
   6742   1.1  christos 
   6743   1.1  christos       for (i = 0; i < c->action_count; i++)
   6744   1.1  christos 	new_actions[i] = c->actions[i];
   6745   1.1  christos       free (c->actions);
   6746   1.1  christos       c->actions = new_actions;
   6747   1.1  christos       c->action_allocated = new_allocated;
   6748   1.1  christos     }
   6749   1.1  christos 
   6750   1.1  christos   act = &c->actions[c->action_count];
   6751   1.1  christos   act->align_type = align_type;
   6752   1.8  christos   act->alignment_pow = alignment_pow;
   6753   1.1  christos   act->action = action;
   6754   1.1  christos   act->offset = offset;
   6755   1.1  christos   act->removed_bytes = removed_bytes;
   6756   1.1  christos   act->do_action = do_action;
   6757   1.1  christos 
   6758   1.1  christos   c->action_count++;
   6759   1.1  christos }
   6760   1.1  christos 
   6761   1.1  christos 
   6762   1.1  christos /* Access to internal relocations, section contents and symbols.  */
   6764   1.1  christos 
   6765   1.1  christos /* During relaxation, we need to modify relocations, section contents,
   6766   1.1  christos    and symbol definitions, and we need to keep the original values from
   6767   1.1  christos    being reloaded from the input files, i.e., we need to "pin" the
   6768   1.1  christos    modified values in memory.  We also want to continue to observe the
   6769   1.1  christos    setting of the "keep-memory" flag.  The following functions wrap the
   6770   1.1  christos    standard BFD functions to take care of this for us.  */
   6771   1.1  christos 
   6772   1.1  christos static Elf_Internal_Rela *
   6773   1.1  christos retrieve_internal_relocs (bfd *abfd, asection *sec, bool keep_memory)
   6774   1.1  christos {
   6775   1.1  christos   Elf_Internal_Rela *internal_relocs;
   6776   1.1  christos 
   6777   1.8  christos   if ((sec->flags & SEC_LINKER_CREATED) != 0)
   6778   1.1  christos     return NULL;
   6779   1.1  christos 
   6780   1.1  christos   internal_relocs = elf_section_data (sec)->relocs;
   6781   1.1  christos   if (internal_relocs == NULL)
   6782   1.1  christos     internal_relocs = (_bfd_elf_link_read_relocs
   6783   1.8  christos 		       (abfd, sec, NULL, NULL, keep_memory));
   6784   1.1  christos   return internal_relocs;
   6785   1.1  christos }
   6786   1.1  christos 
   6787   1.1  christos 
   6788   1.1  christos static void
   6789   1.1  christos pin_internal_relocs (asection *sec, Elf_Internal_Rela *internal_relocs)
   6790   1.3  christos {
   6791   1.1  christos   elf_section_data (sec)->relocs = internal_relocs;
   6792   1.1  christos }
   6793   1.1  christos 
   6794   1.1  christos 
   6795   1.8  christos static void
   6796   1.1  christos release_internal_relocs (asection *sec, Elf_Internal_Rela *internal_relocs)
   6797   1.1  christos {
   6798   1.3  christos   if (elf_section_data (sec)->relocs != internal_relocs)
   6799   1.1  christos     free (internal_relocs);
   6800   1.1  christos }
   6801   1.1  christos 
   6802   1.1  christos 
   6803   1.1  christos static bfd_byte *
   6804   1.1  christos retrieve_contents (bfd *abfd, asection *sec, bool keep_memory)
   6805   1.1  christos {
   6806   1.1  christos   bfd_byte *contents;
   6807   1.1  christos   bfd_size_type sec_size;
   6808   1.1  christos 
   6809   1.1  christos   sec_size = bfd_get_section_limit (abfd, sec);
   6810   1.1  christos   contents = elf_section_data (sec)->this_hdr.contents;
   6811   1.1  christos 
   6812   1.1  christos   if (contents == NULL && sec_size != 0)
   6813   1.1  christos     {
   6814   1.1  christos       if (!bfd_malloc_and_get_section (abfd, sec, &contents))
   6815   1.8  christos 	{
   6816   1.1  christos 	  free (contents);
   6817   1.1  christos 	  return NULL;
   6818   1.1  christos 	}
   6819   1.1  christos       if (keep_memory)
   6820   1.1  christos 	elf_section_data (sec)->this_hdr.contents = contents;
   6821   1.1  christos     }
   6822   1.1  christos   return contents;
   6823   1.1  christos }
   6824   1.1  christos 
   6825   1.1  christos 
   6826   1.1  christos static void
   6827   1.1  christos pin_contents (asection *sec, bfd_byte *contents)
   6828   1.1  christos {
   6829   1.1  christos   elf_section_data (sec)->this_hdr.contents = contents;
   6830   1.1  christos }
   6831   1.1  christos 
   6832   1.1  christos 
   6833   1.1  christos static void
   6834   1.1  christos release_contents (asection *sec, bfd_byte *contents)
   6835   1.1  christos {
   6836   1.1  christos   if (elf_section_data (sec)->this_hdr.contents != contents)
   6837   1.1  christos     free (contents);
   6838   1.1  christos }
   6839   1.1  christos 
   6840   1.1  christos 
   6841   1.1  christos static Elf_Internal_Sym *
   6842   1.1  christos retrieve_local_syms (bfd *input_bfd)
   6843   1.1  christos {
   6844   1.1  christos   Elf_Internal_Shdr *symtab_hdr;
   6845   1.1  christos   Elf_Internal_Sym *isymbuf;
   6846   1.8  christos   size_t locsymcount;
   6847   1.8  christos 
   6848   1.8  christos   symtab_hdr = &elf_tdata (input_bfd)->symtab_hdr;
   6849   1.8  christos   locsymcount = symtab_hdr->sh_info;
   6850   1.1  christos 
   6851   1.8  christos   isymbuf = (Elf_Internal_Sym *) symtab_hdr->contents;
   6852   1.1  christos   if (isymbuf == NULL && locsymcount != 0)
   6853   1.8  christos     isymbuf = bfd_elf_get_elf_syms (input_bfd, symtab_hdr, locsymcount, 0,
   6854   1.1  christos 				    NULL, NULL, NULL);
   6855   1.1  christos 
   6856   1.8  christos   /* Save the symbols for this input file so they won't be read again.  */
   6857   1.1  christos   if (isymbuf && isymbuf != (Elf_Internal_Sym *) symtab_hdr->contents)
   6858   1.8  christos     symtab_hdr->contents = (unsigned char *) isymbuf;
   6859   1.8  christos 
   6860   1.3  christos   return isymbuf;
   6861   1.8  christos }
   6862   1.3  christos 
   6863   1.3  christos 
   6864   1.1  christos /* Code for link-time relaxation.  */
   6866   1.1  christos 
   6867   1.1  christos /* Initialization for relaxation: */
   6868   1.1  christos static bool analyze_relocations (struct bfd_link_info *);
   6869   1.1  christos static bool find_relaxable_sections
   6870   1.8  christos   (bfd *, asection *, struct bfd_link_info *, bool *);
   6871   1.1  christos static bool collect_source_relocs
   6872   1.1  christos   (bfd *, asection *, struct bfd_link_info *);
   6873   1.1  christos static bool is_resolvable_asm_expansion
   6874   1.8  christos   (bfd *, asection *, bfd_byte *, Elf_Internal_Rela *, struct bfd_link_info *,
   6875   1.1  christos    bool *);
   6876   1.1  christos static Elf_Internal_Rela *find_associated_l32r_irel
   6877   1.8  christos   (bfd *, asection *, bfd_byte *, Elf_Internal_Rela *, Elf_Internal_Rela *);
   6878   1.1  christos static bool compute_text_actions
   6879   1.3  christos   (bfd *, asection *, struct bfd_link_info *);
   6880   1.8  christos static bool compute_ebb_proposed_actions (ebb_constraint *);
   6881   1.1  christos static bool compute_ebb_actions (ebb_constraint *);
   6882   1.8  christos typedef struct reloc_range_list_struct reloc_range_list;
   6883   1.1  christos static bool check_section_ebb_pcrels_fit
   6884   1.8  christos   (bfd *, asection *, bfd_byte *, Elf_Internal_Rela *,
   6885   1.8  christos    reloc_range_list *, const ebb_constraint *,
   6886   1.8  christos    const xtensa_opcode *);
   6887   1.1  christos static bool check_section_ebb_reduces (const ebb_constraint *);
   6888   1.8  christos static void text_action_add_proposed
   6889   1.1  christos   (text_action_list *, const ebb_constraint *, asection *);
   6890   1.1  christos 
   6891   1.1  christos /* First pass: */
   6892   1.1  christos static bool compute_removed_literals
   6893   1.8  christos   (bfd *, asection *, struct bfd_link_info *, value_map_hash_table *);
   6894   1.8  christos static Elf_Internal_Rela *get_irel_at_offset
   6895   1.8  christos   (asection *, Elf_Internal_Rela *, bfd_vma);
   6896   1.1  christos static bool is_removable_literal
   6897   1.1  christos   (const source_reloc *, int, const source_reloc *, int, asection *,
   6898   1.1  christos    property_table_entry *, int);
   6899   1.8  christos static bool remove_dead_literal
   6900   1.1  christos   (bfd *, asection *, struct bfd_link_info *, Elf_Internal_Rela *,
   6901   1.1  christos    Elf_Internal_Rela *, source_reloc *, property_table_entry *, int);
   6902   1.8  christos static bool identify_literal_placement
   6903   1.1  christos   (bfd *, asection *, bfd_byte *, struct bfd_link_info *,
   6904   1.1  christos    value_map_hash_table *, bool *, Elf_Internal_Rela *, int,
   6905   1.1  christos    source_reloc *, property_table_entry *, int, section_cache_t *,
   6906   1.8  christos    bool);
   6907   1.1  christos static bool relocations_reach (source_reloc *, int, const r_reloc *);
   6908   1.1  christos static bool coalesce_shared_literal
   6909   1.8  christos   (asection *, source_reloc *, property_table_entry *, int, value_map *);
   6910   1.1  christos static bool move_shared_literal
   6911   1.1  christos   (asection *, struct bfd_link_info *, source_reloc *, property_table_entry *,
   6912   1.1  christos    int, const r_reloc *, const literal_value *, section_cache_t *);
   6913   1.8  christos 
   6914   1.1  christos /* Second pass: */
   6915   1.1  christos static bool relax_section (bfd *, asection *, struct bfd_link_info *);
   6916   1.8  christos static bool translate_section_fixes (asection *);
   6917   1.1  christos static bool translate_reloc_bfd_fix (reloc_bfd_fix *);
   6918   1.1  christos static asection *translate_reloc (const r_reloc *, r_reloc *, asection *);
   6919   1.1  christos static void shrink_dynamic_reloc_sections
   6920   1.1  christos   (struct bfd_link_info *, bfd *, asection *, Elf_Internal_Rela *);
   6921   1.1  christos static bool move_literal
   6922   1.1  christos   (bfd *, struct bfd_link_info *, asection *, bfd_vma, bfd_byte *,
   6923   1.1  christos    xtensa_relax_info *, Elf_Internal_Rela **, const literal_value *);
   6924   1.8  christos static bool relax_property_section
   6925   1.8  christos   (bfd *, asection *, struct bfd_link_info *);
   6926   1.1  christos 
   6927   1.8  christos /* Third pass: */
   6928   1.8  christos static bool relax_section_symbols (bfd *, asection *);
   6929   1.1  christos 
   6930   1.8  christos 
   6931   1.1  christos static bool
   6932   1.1  christos elf_xtensa_relax_section (bfd *abfd,
   6933   1.1  christos 			  asection *sec,
   6934   1.8  christos 			  struct bfd_link_info *link_info,
   6935   1.1  christos 			  bool *again)
   6936   1.1  christos {
   6937   1.1  christos   static value_map_hash_table *values = NULL;
   6938   1.1  christos   static bool relocations_analyzed = false;
   6939   1.1  christos   xtensa_relax_info *relax_info;
   6940   1.1  christos 
   6941   1.1  christos   if (!relocations_analyzed)
   6942   1.1  christos     {
   6943   1.1  christos       /* Do some overall initialization for relaxation.  */
   6944   1.1  christos       values = value_map_hash_table_init ();
   6945   1.1  christos       if (values == NULL)
   6946   1.8  christos 	return false;
   6947   1.8  christos       relaxing_section = true;
   6948   1.1  christos       if (!analyze_relocations (link_info))
   6949   1.1  christos 	return false;
   6950   1.1  christos       relocations_analyzed = true;
   6951   1.1  christos     }
   6952   1.1  christos   *again = false;
   6953   1.1  christos 
   6954   1.1  christos   /* Don't mess with linker-created sections.  */
   6955   1.8  christos   if ((sec->flags & SEC_LINKER_CREATED) != 0)
   6956   1.8  christos     return true;
   6957   1.1  christos 
   6958   1.1  christos   relax_info = get_xtensa_relax_info (sec);
   6959   1.1  christos   BFD_ASSERT (relax_info != NULL);
   6960   1.1  christos 
   6961   1.8  christos   switch (relax_info->visited)
   6962   1.1  christos     {
   6963   1.1  christos     case 0:
   6964   1.1  christos       /* Note: It would be nice to fold this pass into
   6965   1.1  christos 	 analyze_relocations, but it is important for this step that the
   6966   1.8  christos 	 sections be examined in link order.  */
   6967   1.1  christos       if (!compute_removed_literals (abfd, sec, link_info, values))
   6968   1.1  christos 	return false;
   6969   1.1  christos       *again = true;
   6970   1.1  christos       break;
   6971   1.1  christos 
   6972   1.1  christos     case 1:
   6973   1.1  christos       if (values)
   6974   1.1  christos 	value_map_hash_table_delete (values);
   6975   1.1  christos       values = NULL;
   6976   1.1  christos       if (!relax_section (abfd, sec, link_info))
   6977   1.1  christos 	return false;
   6978   1.1  christos       *again = true;
   6979   1.1  christos       break;
   6980   1.1  christos 
   6981   1.1  christos     case 2:
   6982   1.1  christos       if (!relax_section_symbols (abfd, sec))
   6983   1.1  christos 	return false;
   6984   1.8  christos       break;
   6985   1.1  christos     }
   6986   1.1  christos 
   6987   1.1  christos   relax_info->visited++;
   6988   1.1  christos   return true;
   6989   1.8  christos }
   6990   1.1  christos 
   6991   1.1  christos 
   6992   1.3  christos /* Initialization for relaxation.  */
   6994   1.1  christos 
   6995   1.1  christos /* This function is called once at the start of relaxation.  It scans
   6996   1.1  christos    all the input sections and marks the ones that are relaxable (i.e.,
   6997   1.1  christos    literal sections with L32R relocations against them), and then
   6998   1.1  christos    collects source_reloc information for all the relocations against
   6999   1.3  christos    those relaxable sections.  During this process, it also detects
   7000   1.1  christos    longcalls, i.e., calls relaxed by the assembler into indirect
   7001   1.1  christos    calls, that can be optimized back into direct calls.  Within each
   7002   1.1  christos    extended basic block (ebb) containing an optimized longcall, it
   7003   1.8  christos    computes a set of "text actions" that can be performed to remove
   7004   1.1  christos    the L32R associated with the longcall while optionally preserving
   7005   1.1  christos    branch target alignments.  */
   7006   1.1  christos 
   7007   1.1  christos static bool
   7008   1.8  christos analyze_relocations (struct bfd_link_info *link_info)
   7009   1.1  christos {
   7010   1.1  christos   bfd *abfd;
   7011   1.3  christos   asection *sec;
   7012   1.1  christos   bool is_relaxable = false;
   7013   1.1  christos 
   7014   1.1  christos   /* Initialize the per-section relaxation info.  */
   7015   1.1  christos   for (abfd = link_info->input_bfds; abfd != NULL; abfd = abfd->link.next)
   7016   1.1  christos     for (sec = abfd->sections; sec != NULL; sec = sec->next)
   7017   1.1  christos       {
   7018   1.1  christos 	init_xtensa_relax_info (sec);
   7019   1.1  christos       }
   7020   1.1  christos 
   7021   1.1  christos   /* Mark relaxable sections (and count relocations against each one).  */
   7022   1.1  christos   for (abfd = link_info->input_bfds; abfd != NULL; abfd = abfd->link.next)
   7023   1.1  christos     for (sec = abfd->sections; sec != NULL; sec = sec->next)
   7024   1.1  christos       {
   7025   1.1  christos 	if (!find_relaxable_sections (abfd, sec, link_info, &is_relaxable))
   7026   1.1  christos 	  return false;
   7027   1.1  christos       }
   7028   1.3  christos 
   7029   1.1  christos   /* Bail out if there are no relaxable sections.  */
   7030   1.1  christos   if (!is_relaxable)
   7031   1.1  christos     return true;
   7032   1.8  christos 
   7033   1.1  christos   /* Allocate space for source_relocs.  */
   7034   1.1  christos   for (abfd = link_info->input_bfds; abfd != NULL; abfd = abfd->link.next)
   7035   1.1  christos     for (sec = abfd->sections; sec != NULL; sec = sec->next)
   7036   1.3  christos       {
   7037   1.1  christos 	xtensa_relax_info *relax_info;
   7038   1.1  christos 
   7039   1.1  christos 	relax_info = get_xtensa_relax_info (sec);
   7040   1.8  christos 	if (relax_info->is_relaxable_literal_section
   7041   1.1  christos 	    || relax_info->is_relaxable_asm_section)
   7042   1.1  christos 	  {
   7043   1.8  christos 	    relax_info->src_relocs = (source_reloc *)
   7044   1.1  christos 	      bfd_malloc (relax_info->src_count * sizeof (source_reloc));
   7045   1.1  christos 	  }
   7046   1.1  christos 	else
   7047   1.1  christos 	  relax_info->src_count = 0;
   7048   1.1  christos       }
   7049   1.1  christos 
   7050   1.1  christos   /* Collect info on relocations against each relaxable section.  */
   7051   1.1  christos   for (abfd = link_info->input_bfds; abfd != NULL; abfd = abfd->link.next)
   7052   1.1  christos     for (sec = abfd->sections; sec != NULL; sec = sec->next)
   7053   1.1  christos       {
   7054   1.1  christos 	if (!collect_source_relocs (abfd, sec, link_info))
   7055   1.1  christos 	  return false;
   7056   1.1  christos       }
   7057   1.8  christos 
   7058   1.1  christos   /* Compute the text actions.  */
   7059   1.1  christos   for (abfd = link_info->input_bfds; abfd != NULL; abfd = abfd->link.next)
   7060   1.1  christos     for (sec = abfd->sections; sec != NULL; sec = sec->next)
   7061   1.8  christos       {
   7062   1.1  christos 	if (!compute_text_actions (abfd, sec, link_info))
   7063   1.1  christos 	  return false;
   7064   1.1  christos       }
   7065   1.8  christos 
   7066   1.1  christos   return true;
   7067   1.1  christos }
   7068   1.8  christos 
   7069   1.1  christos 
   7070   1.1  christos /* Find all the sections that might be relaxed.  The motivation for
   7071   1.1  christos    this pass is that collect_source_relocs() needs to record _all_ the
   7072   1.3  christos    relocations that target each relaxable section.  That is expensive
   7073   1.1  christos    and unnecessary unless the target section is actually going to be
   7074   1.1  christos    relaxed.  This pass identifies all such sections by checking if
   7075   1.1  christos    they have L32Rs pointing to them.  In the process, the total number
   7076   1.1  christos    of relocations targeting each section is also counted so that we
   7077   1.1  christos    know how much space to allocate for source_relocs against each
   7078   1.8  christos    relaxable literal section.  */
   7079   1.1  christos 
   7080   1.1  christos static bool
   7081   1.1  christos find_relaxable_sections (bfd *abfd,
   7082   1.1  christos 			 asection *sec,
   7083   1.3  christos 			 struct bfd_link_info *link_info,
   7084   1.1  christos 			 bool *is_relaxable_p)
   7085   1.1  christos {
   7086   1.1  christos   Elf_Internal_Rela *internal_relocs;
   7087   1.1  christos   bfd_byte *contents;
   7088   1.1  christos   bool ok = true;
   7089   1.1  christos   unsigned i;
   7090   1.1  christos   xtensa_relax_info *source_relax_info;
   7091   1.1  christos   bool is_l32r_reloc;
   7092   1.1  christos 
   7093   1.1  christos   internal_relocs = retrieve_internal_relocs (abfd, sec,
   7094   1.1  christos 					      link_info->keep_memory);
   7095   1.1  christos   if (internal_relocs == NULL)
   7096   1.1  christos     return ok;
   7097   1.1  christos 
   7098   1.8  christos   contents = retrieve_contents (abfd, sec, link_info->keep_memory);
   7099   1.1  christos   if (contents == NULL && sec->size != 0)
   7100   1.1  christos     {
   7101   1.1  christos       ok = false;
   7102   1.1  christos       goto error_return;
   7103   1.8  christos     }
   7104   1.8  christos 
   7105   1.1  christos   source_relax_info = get_xtensa_relax_info (sec);
   7106   1.1  christos   for (i = 0; i < sec->reloc_count; i++)
   7107   1.1  christos     {
   7108   1.1  christos       Elf_Internal_Rela *irel = &internal_relocs[i];
   7109   1.1  christos       r_reloc r_rel;
   7110   1.1  christos       asection *target_sec;
   7111   1.1  christos       xtensa_relax_info *target_relax_info;
   7112   1.1  christos 
   7113   1.1  christos       /* If this section has not already been marked as "relaxable", and
   7114   1.1  christos 	 if it contains any ASM_EXPAND relocations (marking expanded
   7115   1.1  christos 	 longcalls) that can be optimized into direct calls, then mark
   7116   1.1  christos 	 the section as "relaxable".  */
   7117   1.6  christos       if (source_relax_info
   7118   1.1  christos 	  && !source_relax_info->is_relaxable_asm_section
   7119   1.8  christos 	  && ELF32_R_TYPE (irel->r_info) == R_XTENSA_ASM_EXPAND)
   7120   1.1  christos 	{
   7121   1.1  christos 	  bool is_reachable = false;
   7122   1.1  christos 	  if (is_resolvable_asm_expansion (abfd, sec, contents, irel,
   7123   1.1  christos 					   link_info, &is_reachable)
   7124   1.1  christos 	      && is_reachable)
   7125   1.1  christos 	    {
   7126   1.1  christos 	      source_relax_info->is_relaxable_asm_section = true;
   7127   1.1  christos 	      *is_relaxable_p = true;
   7128   1.1  christos 	    }
   7129   1.1  christos 	}
   7130   1.1  christos 
   7131   1.1  christos       r_reloc_init (&r_rel, abfd, irel, contents,
   7132   1.1  christos 		    bfd_get_section_limit (abfd, sec));
   7133   1.1  christos 
   7134   1.1  christos       target_sec = r_reloc_get_section (&r_rel);
   7135   1.1  christos       target_relax_info = get_xtensa_relax_info (target_sec);
   7136   1.8  christos       if (!target_relax_info)
   7137   1.8  christos 	continue;
   7138   1.1  christos 
   7139   1.1  christos       /* Count PC-relative operand relocations against the target section.
   7140   1.1  christos 	 Note: The conditions tested here must match the conditions under
   7141   1.1  christos 	 which init_source_reloc is called in collect_source_relocs().  */
   7142   1.1  christos       is_l32r_reloc = false;
   7143   1.1  christos       if (is_operand_relocation (ELF32_R_TYPE (irel->r_info)))
   7144   1.1  christos 	{
   7145   1.1  christos 	  xtensa_opcode opcode =
   7146   1.1  christos 	    get_relocation_opcode (abfd, sec, contents, irel);
   7147   1.1  christos 	  if (opcode != XTENSA_UNDEFINED)
   7148   1.1  christos 	    {
   7149   1.1  christos 	      is_l32r_reloc = (opcode == get_l32r_opcode ());
   7150   1.1  christos 	      if (!is_alt_relocation (ELF32_R_TYPE (irel->r_info))
   7151   1.1  christos 		  || is_l32r_reloc)
   7152   1.8  christos 		target_relax_info->src_count++;
   7153   1.1  christos 	    }
   7154   1.1  christos 	}
   7155   1.1  christos 
   7156   1.1  christos       if (is_l32r_reloc && r_reloc_is_defined (&r_rel))
   7157   1.1  christos 	{
   7158   1.1  christos 	  /* Mark the target section as relaxable.  */
   7159   1.8  christos 	  target_relax_info->is_relaxable_literal_section = true;
   7160   1.1  christos 	  *is_relaxable_p = true;
   7161   1.1  christos 	}
   7162   1.1  christos     }
   7163   1.3  christos 
   7164   1.1  christos  error_return:
   7165   1.3  christos   release_contents (sec, contents);
   7166   1.1  christos   release_internal_relocs (sec, internal_relocs);
   7167   1.1  christos   return ok;
   7168   1.1  christos }
   7169   1.1  christos 
   7170   1.1  christos 
   7171   1.1  christos /* Record _all_ the relocations that point to relaxable sections, and
   7172   1.8  christos    get rid of ASM_EXPAND relocs by either converting them to
   7173   1.1  christos    ASM_SIMPLIFY or by removing them.  */
   7174   1.1  christos 
   7175   1.1  christos static bool
   7176   1.1  christos collect_source_relocs (bfd *abfd,
   7177   1.3  christos 		       asection *sec,
   7178   1.1  christos 		       struct bfd_link_info *link_info)
   7179   1.1  christos {
   7180   1.1  christos   Elf_Internal_Rela *internal_relocs;
   7181   1.1  christos   bfd_byte *contents;
   7182   1.1  christos   bool ok = true;
   7183   1.1  christos   unsigned i;
   7184   1.1  christos   bfd_size_type sec_size;
   7185   1.1  christos 
   7186   1.1  christos   internal_relocs = retrieve_internal_relocs (abfd, sec,
   7187   1.1  christos 					      link_info->keep_memory);
   7188   1.1  christos   if (internal_relocs == NULL)
   7189   1.1  christos     return ok;
   7190   1.1  christos 
   7191   1.1  christos   sec_size = bfd_get_section_limit (abfd, sec);
   7192   1.1  christos   contents = retrieve_contents (abfd, sec, link_info->keep_memory);
   7193   1.1  christos   if (contents == NULL && sec_size != 0)
   7194   1.1  christos     {
   7195   1.8  christos       ok = false;
   7196   1.1  christos       goto error_return;
   7197   1.1  christos     }
   7198   1.1  christos 
   7199   1.1  christos   /* Record relocations against relaxable literal sections.  */
   7200   1.1  christos   for (i = 0; i < sec->reloc_count; i++)
   7201   1.1  christos     {
   7202   1.1  christos       Elf_Internal_Rela *irel = &internal_relocs[i];
   7203   1.1  christos       r_reloc r_rel;
   7204   1.1  christos       asection *target_sec;
   7205   1.1  christos       xtensa_relax_info *target_relax_info;
   7206   1.8  christos 
   7207   1.1  christos       r_reloc_init (&r_rel, abfd, irel, contents, sec_size);
   7208   1.1  christos 
   7209   1.1  christos       target_sec = r_reloc_get_section (&r_rel);
   7210   1.1  christos       target_relax_info = get_xtensa_relax_info (target_sec);
   7211   1.1  christos 
   7212   1.1  christos       if (target_relax_info
   7213   1.1  christos 	  && (target_relax_info->is_relaxable_literal_section
   7214   1.1  christos 	      || target_relax_info->is_relaxable_asm_section))
   7215   1.1  christos 	{
   7216   1.1  christos 	  xtensa_opcode opcode = XTENSA_UNDEFINED;
   7217   1.1  christos 	  int opnd = -1;
   7218   1.1  christos 	  bool is_abs_literal = false;
   7219   1.1  christos 
   7220   1.1  christos 	  if (is_alt_relocation (ELF32_R_TYPE (irel->r_info)))
   7221   1.1  christos 	    {
   7222   1.1  christos 	      /* None of the current alternate relocs are PC-relative,
   7223   1.1  christos 		 and only PC-relative relocs matter here.  However, we
   7224   1.1  christos 		 still need to record the opcode for literal
   7225   1.1  christos 		 coalescing.  */
   7226   1.1  christos 	      opcode = get_relocation_opcode (abfd, sec, contents, irel);
   7227   1.1  christos 	      if (opcode == get_l32r_opcode ())
   7228   1.1  christos 		{
   7229   1.1  christos 		  is_abs_literal = true;
   7230   1.1  christos 		  opnd = 1;
   7231   1.1  christos 		}
   7232   1.1  christos 	      else
   7233   1.1  christos 		opcode = XTENSA_UNDEFINED;
   7234   1.1  christos 	    }
   7235   1.3  christos 	  else if (is_operand_relocation (ELF32_R_TYPE (irel->r_info)))
   7236   1.1  christos 	    {
   7237   1.1  christos 	      opcode = get_relocation_opcode (abfd, sec, contents, irel);
   7238   1.8  christos 	      opnd = get_relocation_opnd (opcode, ELF32_R_TYPE (irel->r_info));
   7239   1.1  christos 	    }
   7240   1.1  christos 
   7241   1.1  christos 	  if (opcode != XTENSA_UNDEFINED)
   7242   1.1  christos 	    {
   7243   1.1  christos 	      int src_next = target_relax_info->src_next++;
   7244   1.1  christos 	      source_reloc *s_reloc = &target_relax_info->src_relocs[src_next];
   7245   1.1  christos 
   7246   1.1  christos 	      init_source_reloc (s_reloc, sec, &r_rel, opcode, opnd,
   7247   1.1  christos 				 is_abs_literal);
   7248   1.1  christos 	    }
   7249   1.1  christos 	}
   7250   1.1  christos     }
   7251   1.1  christos 
   7252   1.1  christos   /* Now get rid of ASM_EXPAND relocations.  At this point, the
   7253   1.1  christos      src_relocs array for the target literal section may still be
   7254   1.1  christos      incomplete, but it must at least contain the entries for the L32R
   7255   1.1  christos      relocations associated with ASM_EXPANDs because they were just
   7256   1.1  christos      added in the preceding loop over the relocations.  */
   7257   1.1  christos 
   7258   1.1  christos   for (i = 0; i < sec->reloc_count; i++)
   7259   1.1  christos     {
   7260   1.1  christos       Elf_Internal_Rela *irel = &internal_relocs[i];
   7261   1.1  christos       bool is_reachable;
   7262   1.1  christos 
   7263   1.1  christos       if (!is_resolvable_asm_expansion (abfd, sec, contents, irel, link_info,
   7264   1.1  christos 					&is_reachable))
   7265   1.1  christos 	continue;
   7266   1.1  christos 
   7267   1.1  christos       if (is_reachable)
   7268   1.1  christos 	{
   7269   1.1  christos 	  Elf_Internal_Rela *l32r_irel;
   7270   1.1  christos 	  r_reloc r_rel;
   7271   1.1  christos 	  asection *target_sec;
   7272   1.1  christos 	  xtensa_relax_info *target_relax_info;
   7273   1.1  christos 
   7274   1.3  christos 	  /* Mark the source_reloc for the L32R so that it will be
   7275   1.1  christos 	     removed in compute_removed_literals(), along with the
   7276   1.1  christos 	     associated literal.  */
   7277   1.1  christos 	  l32r_irel = find_associated_l32r_irel (abfd, sec, contents,
   7278   1.8  christos 						 irel, internal_relocs);
   7279   1.1  christos 	  if (l32r_irel == NULL)
   7280   1.1  christos 	    continue;
   7281   1.1  christos 
   7282   1.1  christos 	  r_reloc_init (&r_rel, abfd, l32r_irel, contents, sec_size);
   7283   1.1  christos 
   7284   1.1  christos 	  target_sec = r_reloc_get_section (&r_rel);
   7285   1.1  christos 	  target_relax_info = get_xtensa_relax_info (target_sec);
   7286   1.1  christos 
   7287   1.1  christos 	  if (target_relax_info
   7288   1.1  christos 	      && (target_relax_info->is_relaxable_literal_section
   7289   1.1  christos 		  || target_relax_info->is_relaxable_asm_section))
   7290   1.1  christos 	    {
   7291   1.1  christos 	      source_reloc *s_reloc;
   7292   1.1  christos 
   7293   1.1  christos 	      /* Search the source_relocs for the entry corresponding to
   7294   1.1  christos 		 the l32r_irel.  Note: The src_relocs array is not yet
   7295   1.1  christos 		 sorted, but it wouldn't matter anyway because we're
   7296   1.1  christos 		 searching by source offset instead of target offset.  */
   7297   1.1  christos 	      s_reloc = find_source_reloc (target_relax_info->src_relocs,
   7298   1.1  christos 					   target_relax_info->src_next,
   7299   1.1  christos 					   sec, l32r_irel);
   7300   1.1  christos 	      BFD_ASSERT (s_reloc);
   7301   1.1  christos 	      s_reloc->is_null = true;
   7302   1.1  christos 	    }
   7303   1.1  christos 
   7304   1.1  christos 	  /* Convert this reloc to ASM_SIMPLIFY.  */
   7305   1.1  christos 	  irel->r_info = ELF32_R_INFO (ELF32_R_SYM (irel->r_info),
   7306   1.1  christos 				       R_XTENSA_ASM_SIMPLIFY);
   7307   1.1  christos 	  l32r_irel->r_info = ELF32_R_INFO (0, R_XTENSA_NONE);
   7308   1.1  christos 
   7309   1.1  christos 	  pin_internal_relocs (sec, internal_relocs);
   7310   1.1  christos 	}
   7311   1.8  christos       else
   7312   1.1  christos 	{
   7313   1.1  christos 	  /* It is resolvable but doesn't reach.  We resolve now
   7314   1.1  christos 	     by eliminating the relocation -- the call will remain
   7315   1.1  christos 	     expanded into L32R/CALLX.  */
   7316   1.1  christos 	  irel->r_info = ELF32_R_INFO (0, R_XTENSA_NONE);
   7317   1.8  christos 	  pin_internal_relocs (sec, internal_relocs);
   7318   1.1  christos 	}
   7319   1.1  christos     }
   7320   1.7  christos 
   7321   1.7  christos  error_return:
   7322   1.7  christos   release_contents (sec, contents);
   7323   1.7  christos   release_internal_relocs (sec, internal_relocs);
   7324   1.7  christos   return ok;
   7325   1.1  christos }
   7326   1.1  christos 
   7327   1.1  christos 
   7328   1.1  christos /* Return TRUE if the asm expansion can be resolved.  Generally it can
   7329   1.1  christos    be resolved on a final link or when a partial link locates it in the
   7330   1.8  christos    same section as the target.  Set "is_reachable" flag if the target of
   7331   1.1  christos    the call is within the range of a direct call, given the current VMA
   7332   1.1  christos    for this section and the target section.  */
   7333   1.8  christos 
   7334   1.1  christos bool
   7335   1.1  christos is_resolvable_asm_expansion (bfd *abfd,
   7336   1.8  christos 			     asection *sec,
   7337   1.1  christos 			     bfd_byte *contents,
   7338   1.3  christos 			     Elf_Internal_Rela *irel,
   7339   1.8  christos 			     struct bfd_link_info *link_info,
   7340   1.1  christos 			     bool *is_reachable_p)
   7341   1.1  christos {
   7342   1.1  christos   asection *target_sec;
   7343   1.1  christos   asection *s;
   7344   1.1  christos   bfd_vma first_vma;
   7345   1.1  christos   bfd_vma last_vma;
   7346   1.8  christos   unsigned int first_align;
   7347   1.3  christos   unsigned int adjust;
   7348   1.1  christos   bfd_vma target_offset;
   7349   1.1  christos   r_reloc r_rel;
   7350   1.8  christos   xtensa_opcode opcode, direct_call_opcode;
   7351   1.1  christos   bfd_vma self_address;
   7352   1.1  christos   bfd_vma dest_address;
   7353   1.1  christos   bool uses_l32r;
   7354   1.1  christos   bfd_size_type sec_size;
   7355   1.8  christos 
   7356   1.1  christos   *is_reachable_p = false;
   7357   1.1  christos 
   7358   1.1  christos   if (contents == NULL)
   7359   1.1  christos     return false;
   7360   1.1  christos 
   7361   1.1  christos   if (ELF32_R_TYPE (irel->r_info) != R_XTENSA_ASM_EXPAND)
   7362   1.1  christos     return false;
   7363   1.1  christos 
   7364   1.1  christos   sec_size = bfd_get_section_limit (abfd, sec);
   7365   1.8  christos   opcode = get_expanded_call_opcode (contents + irel->r_offset,
   7366   1.3  christos 				     sec_size - irel->r_offset, &uses_l32r);
   7367   1.1  christos   /* Optimization of longcalls that use CONST16 is not yet implemented.  */
   7368   1.1  christos   if (!uses_l32r)
   7369   1.1  christos     return false;
   7370   1.3  christos 
   7371   1.1  christos   direct_call_opcode = swap_callx_for_call_opcode (opcode);
   7372   1.1  christos   if (direct_call_opcode == XTENSA_UNDEFINED)
   7373   1.8  christos     return false;
   7374   1.1  christos 
   7375   1.3  christos   /* Check and see that the target resolves.  */
   7376   1.3  christos   r_reloc_init (&r_rel, abfd, irel, contents, sec_size);
   7377   1.3  christos   if (!r_reloc_is_defined (&r_rel))
   7378   1.3  christos     return false;
   7379   1.3  christos 
   7380   1.3  christos   target_sec = r_reloc_get_section (&r_rel);
   7381   1.3  christos   target_offset = r_rel.target_offset;
   7382   1.3  christos 
   7383   1.3  christos   /* If the target is in a shared library, then it doesn't reach.  This
   7384   1.3  christos      isn't supposed to come up because the compiler should never generate
   7385   1.3  christos      non-PIC calls on systems that use shared libraries, but the linker
   7386   1.3  christos      shouldn't crash regardless.  */
   7387   1.3  christos   if (!target_sec->output_section)
   7388   1.3  christos     return false;
   7389   1.3  christos 
   7390   1.3  christos   /* For relocatable sections, we can only simplify when the output
   7391   1.3  christos      section of the target is the same as the output section of the
   7392   1.3  christos      source.  */
   7393   1.3  christos   if (bfd_link_relocatable (link_info)
   7394   1.3  christos       && (target_sec->output_section != sec->output_section
   7395   1.3  christos 	  || is_reloc_sym_weak (abfd, irel)))
   7396   1.3  christos     return false;
   7397   1.3  christos 
   7398   1.3  christos   if (target_sec->output_section != sec->output_section)
   7399   1.3  christos     {
   7400   1.3  christos       /* If the two sections are sufficiently far away that relaxation
   7401   1.3  christos 	 might take the call out of range, we can't simplify.  For
   7402   1.3  christos 	 example, a positive displacement call into another memory
   7403   1.3  christos 	 could get moved to a lower address due to literal removal,
   7404   1.3  christos 	 but the destination won't move, and so the displacment might
   7405   1.3  christos 	 get larger.
   7406   1.3  christos 
   7407   1.3  christos 	 If the displacement is negative, assume the destination could
   7408   1.3  christos 	 move as far back as the start of the output section.  The
   7409   1.3  christos 	 self_address will be at least as far into the output section
   7410   1.3  christos 	 as it is prior to relaxation.
   7411   1.3  christos 
   7412   1.3  christos 	 If the displacement is postive, assume the destination will be in
   7413   1.7  christos 	 it's pre-relaxed location (because relaxation only makes sections
   7414   1.7  christos 	 smaller).  The self_address could go all the way to the beginning
   7415   1.7  christos 	 of the output section.  */
   7416   1.7  christos 
   7417   1.7  christos       dest_address = target_sec->output_section->vma;
   7418   1.7  christos       self_address = sec->output_section->vma;
   7419   1.7  christos 
   7420   1.7  christos       if (sec->output_section->vma > target_sec->output_section->vma)
   7421   1.7  christos 	self_address += sec->output_offset + irel->r_offset + 3;
   7422   1.7  christos       else
   7423   1.7  christos 	dest_address += bfd_get_section_limit (abfd, target_sec->output_section);
   7424   1.7  christos       /* Call targets should be four-byte aligned.  */
   7425   1.7  christos       dest_address = (dest_address + 3) & ~3;
   7426   1.7  christos     }
   7427   1.7  christos   else
   7428   1.7  christos     {
   7429   1.7  christos 
   7430   1.7  christos       self_address = (sec->output_section->vma
   7431   1.7  christos 		      + sec->output_offset + irel->r_offset + 3);
   7432   1.7  christos       dest_address = (target_sec->output_section->vma
   7433   1.7  christos 		      + target_sec->output_offset + target_offset);
   7434   1.7  christos     }
   7435   1.7  christos 
   7436   1.7  christos   /* Adjust addresses with alignments for the worst case to see if call insn
   7437   1.7  christos      can fit.  Don't relax l32r + callx to call if the target can be out of
   7438   1.7  christos      range due to alignment.
   7439   1.7  christos      Caller and target addresses are highest and lowest address.
   7440   1.7  christos      Search all sections between caller and target, looking for max alignment.
   7441   1.7  christos      The adjustment is max alignment bytes.  If the alignment at the lowest
   7442   1.7  christos      address is less than the adjustment, apply the adjustment to highest
   7443   1.7  christos      address.  */
   7444   1.7  christos 
   7445   1.7  christos   /* Start from lowest address.
   7446   1.7  christos      Lowest address aligmnet is from input section.
   7447   1.7  christos      Initial alignment (adjust) is from input section.  */
   7448   1.7  christos   if (dest_address > self_address)
   7449   1.7  christos     {
   7450   1.7  christos       s = sec->output_section;
   7451   1.7  christos       last_vma = dest_address;
   7452   1.7  christos       first_align = sec->alignment_power;
   7453   1.7  christos       adjust = target_sec->alignment_power;
   7454   1.7  christos     }
   7455   1.7  christos   else
   7456   1.7  christos     {
   7457   1.7  christos       s = target_sec->output_section;
   7458   1.7  christos       last_vma = self_address;
   7459   1.7  christos       first_align = target_sec->alignment_power;
   7460   1.7  christos       adjust = sec->alignment_power;
   7461   1.7  christos     }
   7462   1.7  christos 
   7463   1.1  christos   first_vma = s->vma;
   7464   1.1  christos 
   7465   1.1  christos   /* Find the largest alignment in output section list.  */
   7466   1.1  christos   for (; s && s->vma >= first_vma && s->vma <= last_vma ; s = s->next)
   7467   1.1  christos     {
   7468   1.8  christos       if (s->alignment_power > adjust)
   7469   1.1  christos 	adjust = s->alignment_power;
   7470   1.8  christos     }
   7471   1.1  christos 
   7472   1.1  christos   if (adjust > first_align)
   7473   1.1  christos     {
   7474   1.1  christos       /* Alignment may enlarge the range, adjust highest address.  */
   7475   1.1  christos       adjust = 1 << adjust;
   7476   1.1  christos       if (dest_address > self_address)
   7477   1.1  christos 	{
   7478   1.1  christos 	  dest_address += adjust;
   7479   1.1  christos 	}
   7480   1.1  christos       else
   7481   1.1  christos 	{
   7482   1.1  christos 	  self_address += adjust;
   7483   1.3  christos 	}
   7484   1.1  christos     }
   7485   1.1  christos 
   7486   1.1  christos   *is_reachable_p = pcrel_reloc_fits (direct_call_opcode, 0,
   7487   1.1  christos 				      self_address, dest_address);
   7488   1.1  christos 
   7489   1.1  christos   if ((self_address >> CALL_SEGMENT_BITS) !=
   7490   1.1  christos       (dest_address >> CALL_SEGMENT_BITS))
   7491   1.1  christos     return false;
   7492   1.1  christos 
   7493   1.1  christos   return true;
   7494   1.1  christos }
   7495   1.1  christos 
   7496   1.1  christos 
   7497   1.1  christos static Elf_Internal_Rela *
   7498   1.1  christos find_associated_l32r_irel (bfd *abfd,
   7499   1.1  christos 			   asection *sec,
   7500   1.1  christos 			   bfd_byte *contents,
   7501   1.1  christos 			   Elf_Internal_Rela *other_irel,
   7502   1.1  christos 			   Elf_Internal_Rela *internal_relocs)
   7503   1.1  christos {
   7504   1.1  christos   unsigned i;
   7505   1.1  christos 
   7506   1.1  christos   for (i = 0; i < sec->reloc_count; i++)
   7507   1.1  christos     {
   7508   1.1  christos       Elf_Internal_Rela *irel = &internal_relocs[i];
   7509   1.1  christos 
   7510   1.1  christos       if (irel == other_irel)
   7511   1.1  christos 	continue;
   7512   1.1  christos       if (irel->r_offset != other_irel->r_offset)
   7513   1.1  christos 	continue;
   7514   1.1  christos       if (is_l32r_relocation (abfd, sec, contents, irel))
   7515   1.1  christos 	return irel;
   7516   1.3  christos     }
   7517   1.3  christos 
   7518   1.3  christos   return NULL;
   7519   1.8  christos }
   7520   1.3  christos 
   7521   1.3  christos 
   7522   1.3  christos static xtensa_opcode *
   7523   1.3  christos build_reloc_opcodes (bfd *abfd,
   7524   1.3  christos 		     asection *sec,
   7525   1.3  christos 		     bfd_byte *contents,
   7526   1.3  christos 		     Elf_Internal_Rela *internal_relocs)
   7527   1.3  christos {
   7528   1.3  christos   unsigned i;
   7529   1.3  christos   xtensa_opcode *reloc_opcodes =
   7530   1.3  christos     (xtensa_opcode *) bfd_malloc (sizeof (xtensa_opcode) * sec->reloc_count);
   7531   1.3  christos   for (i = 0; i < sec->reloc_count; i++)
   7532   1.3  christos     {
   7533   1.3  christos       Elf_Internal_Rela *irel = &internal_relocs[i];
   7534   1.3  christos       reloc_opcodes[i] = get_relocation_opcode (abfd, sec, contents, irel);
   7535   1.3  christos     }
   7536   1.3  christos   return reloc_opcodes;
   7537   1.3  christos }
   7538   1.8  christos 
   7539   1.3  christos struct reloc_range_struct
   7540   1.3  christos {
   7541   1.3  christos   bfd_vma addr;
   7542   1.3  christos   bool add; /* TRUE if start of a range, FALSE otherwise.  */
   7543   1.3  christos   /* Original irel index in the array of relocations for a section.  */
   7544   1.3  christos   unsigned irel_index;
   7545   1.3  christos };
   7546   1.3  christos typedef struct reloc_range_struct reloc_range;
   7547   1.3  christos 
   7548   1.3  christos typedef struct reloc_range_list_entry_struct reloc_range_list_entry;
   7549   1.3  christos struct reloc_range_list_entry_struct
   7550   1.3  christos {
   7551   1.3  christos   reloc_range_list_entry *next;
   7552   1.3  christos   reloc_range_list_entry *prev;
   7553   1.3  christos   Elf_Internal_Rela *irel;
   7554   1.3  christos   xtensa_opcode opcode;
   7555   1.3  christos   int opnum;
   7556   1.3  christos };
   7557   1.3  christos 
   7558   1.3  christos struct reloc_range_list_struct
   7559   1.3  christos {
   7560   1.3  christos   /* The rest of the structure is only meaningful when ok is TRUE.  */
   7561   1.3  christos   bool ok;
   7562   1.3  christos 
   7563   1.3  christos   unsigned n_range; /* Number of range markers.  */
   7564   1.3  christos   reloc_range *range; /* Sorted range markers.  */
   7565   1.3  christos 
   7566   1.3  christos   unsigned first; /* Index of a first range element in the list.  */
   7567   1.3  christos   unsigned last; /* One past index of a last range element in the list.  */
   7568   1.3  christos 
   7569   1.3  christos   unsigned n_list; /* Number of list elements.  */
   7570   1.3  christos   reloc_range_list_entry *reloc; /*  */
   7571   1.3  christos   reloc_range_list_entry list_root;
   7572   1.3  christos };
   7573   1.3  christos 
   7574   1.3  christos static int
   7575   1.3  christos reloc_range_compare (const void *a, const void *b)
   7576   1.3  christos {
   7577   1.3  christos   const reloc_range *ra = a;
   7578   1.3  christos   const reloc_range *rb = b;
   7579   1.8  christos 
   7580   1.3  christos   if (ra->addr != rb->addr)
   7581   1.3  christos     return ra->addr < rb->addr ? -1 : 1;
   7582   1.3  christos   if (ra->add != rb->add)
   7583   1.3  christos     return ra->add ? -1 : 1;
   7584   1.3  christos   return 0;
   7585   1.3  christos }
   7586   1.3  christos 
   7587   1.3  christos static void
   7588   1.3  christos build_reloc_ranges (bfd *abfd, asection *sec,
   7589   1.3  christos 		    bfd_byte *contents,
   7590   1.3  christos 		    Elf_Internal_Rela *internal_relocs,
   7591   1.3  christos 		    xtensa_opcode *reloc_opcodes,
   7592   1.3  christos 		    reloc_range_list *list)
   7593   1.3  christos {
   7594   1.3  christos   unsigned i;
   7595   1.3  christos   size_t n = 0;
   7596   1.3  christos   size_t max_n = 0;
   7597   1.3  christos   reloc_range *ranges = NULL;
   7598   1.3  christos   reloc_range_list_entry *reloc =
   7599   1.3  christos     bfd_malloc (sec->reloc_count * sizeof (*reloc));
   7600   1.3  christos 
   7601   1.3  christos   memset (list, 0, sizeof (*list));
   7602   1.3  christos   list->ok = true;
   7603   1.3  christos 
   7604   1.3  christos   for (i = 0; i < sec->reloc_count; i++)
   7605   1.3  christos     {
   7606   1.3  christos       Elf_Internal_Rela *irel = &internal_relocs[i];
   7607   1.3  christos       int r_type = ELF32_R_TYPE (irel->r_info);
   7608   1.3  christos       reloc_howto_type *howto = &elf_howto_table[r_type];
   7609   1.3  christos       r_reloc r_rel;
   7610   1.3  christos 
   7611   1.3  christos       if (r_type == R_XTENSA_ASM_SIMPLIFY
   7612   1.3  christos 	  || r_type == R_XTENSA_32_PCREL
   7613   1.3  christos 	  || !howto->pc_relative)
   7614   1.3  christos 	continue;
   7615   1.3  christos 
   7616   1.3  christos       r_reloc_init (&r_rel, abfd, irel, contents,
   7617   1.3  christos 		    bfd_get_section_limit (abfd, sec));
   7618   1.3  christos 
   7619   1.6  christos       if (r_reloc_get_section (&r_rel) != sec)
   7620   1.3  christos 	continue;
   7621   1.3  christos 
   7622   1.3  christos       if (n + 2 > max_n)
   7623   1.3  christos 	{
   7624   1.3  christos 	  max_n = (max_n + 2) * 2;
   7625   1.3  christos 	  ranges = bfd_realloc (ranges, max_n * sizeof (*ranges));
   7626   1.3  christos 	}
   7627   1.3  christos 
   7628   1.3  christos       ranges[n].addr = irel->r_offset;
   7629   1.3  christos       ranges[n + 1].addr = r_rel.target_offset;
   7630   1.3  christos 
   7631   1.3  christos       ranges[n].add = ranges[n].addr < ranges[n + 1].addr;
   7632   1.3  christos       ranges[n + 1].add = !ranges[n].add;
   7633   1.3  christos 
   7634   1.3  christos       ranges[n].irel_index = i;
   7635   1.3  christos       ranges[n + 1].irel_index = i;
   7636   1.3  christos 
   7637   1.8  christos       n += 2;
   7638   1.3  christos 
   7639   1.3  christos       reloc[i].irel = irel;
   7640   1.3  christos 
   7641   1.3  christos       /* Every relocation won't possibly be checked in the optimized version of
   7642   1.3  christos 	 check_section_ebb_pcrels_fit, so this needs to be done here.  */
   7643   1.3  christos       if (is_alt_relocation (ELF32_R_TYPE (irel->r_info)))
   7644   1.8  christos 	{
   7645   1.3  christos 	  /* None of the current alternate relocs are PC-relative,
   7646   1.3  christos 	     and only PC-relative relocs matter here.  */
   7647   1.3  christos 	}
   7648   1.3  christos       else
   7649   1.3  christos 	{
   7650   1.3  christos 	  xtensa_opcode opcode;
   7651   1.3  christos 	  int opnum;
   7652   1.3  christos 
   7653   1.3  christos 	  if (reloc_opcodes)
   7654   1.3  christos 	    opcode = reloc_opcodes[i];
   7655   1.3  christos 	  else
   7656   1.3  christos 	    opcode = get_relocation_opcode (abfd, sec, contents, irel);
   7657   1.3  christos 
   7658   1.3  christos 	  if (opcode == XTENSA_UNDEFINED)
   7659   1.3  christos 	    {
   7660   1.3  christos 	      list->ok = false;
   7661   1.3  christos 	      break;
   7662   1.3  christos 	    }
   7663   1.3  christos 
   7664   1.3  christos 	  opnum = get_relocation_opnd (opcode, ELF32_R_TYPE (irel->r_info));
   7665   1.3  christos 	  if (opnum == XTENSA_UNDEFINED)
   7666   1.3  christos 	    {
   7667   1.3  christos 	      list->ok = false;
   7668   1.3  christos 	      break;
   7669   1.3  christos 	    }
   7670   1.3  christos 
   7671   1.3  christos 	  /* Record relocation opcode and opnum as we've calculated them
   7672   1.3  christos 	     anyway and they won't change.  */
   7673   1.3  christos 	  reloc[i].opcode = opcode;
   7674   1.3  christos 	  reloc[i].opnum = opnum;
   7675   1.3  christos 	}
   7676   1.3  christos     }
   7677   1.3  christos 
   7678   1.3  christos   if (list->ok)
   7679   1.3  christos     {
   7680   1.3  christos       ranges = bfd_realloc (ranges, n * sizeof (*ranges));
   7681   1.3  christos       qsort (ranges, n, sizeof (*ranges), reloc_range_compare);
   7682   1.3  christos 
   7683   1.3  christos       list->n_range = n;
   7684   1.3  christos       list->range = ranges;
   7685   1.3  christos       list->reloc = reloc;
   7686   1.3  christos       list->list_root.prev = &list->list_root;
   7687   1.3  christos       list->list_root.next = &list->list_root;
   7688   1.3  christos     }
   7689   1.3  christos   else
   7690   1.3  christos     {
   7691   1.3  christos       free (ranges);
   7692   1.3  christos       free (reloc);
   7693   1.3  christos     }
   7694   1.3  christos }
   7695   1.3  christos 
   7696   1.3  christos static void reloc_range_list_append (reloc_range_list *list,
   7697   1.3  christos 				     unsigned irel_index)
   7698   1.3  christos {
   7699   1.3  christos   reloc_range_list_entry *entry = list->reloc + irel_index;
   7700   1.3  christos 
   7701   1.3  christos   entry->prev = list->list_root.prev;
   7702   1.3  christos   entry->next = &list->list_root;
   7703   1.3  christos   entry->prev->next = entry;
   7704   1.3  christos   entry->next->prev = entry;
   7705   1.3  christos   ++list->n_list;
   7706   1.3  christos }
   7707   1.3  christos 
   7708   1.3  christos static void reloc_range_list_remove (reloc_range_list *list,
   7709   1.3  christos 				     unsigned irel_index)
   7710   1.3  christos {
   7711   1.3  christos   reloc_range_list_entry *entry = list->reloc + irel_index;
   7712   1.3  christos 
   7713   1.3  christos   entry->next->prev = entry->prev;
   7714   1.3  christos   entry->prev->next = entry->next;
   7715   1.3  christos   --list->n_list;
   7716   1.3  christos }
   7717   1.3  christos 
   7718   1.3  christos /* Update relocation list object so that it lists all relocations that cross
   7719   1.3  christos    [first; last] range.  Range bounds should not decrease with successive
   7720   1.3  christos    invocations.  */
   7721   1.3  christos static void reloc_range_list_update_range (reloc_range_list *list,
   7722   1.3  christos 					   bfd_vma first, bfd_vma last)
   7723   1.3  christos {
   7724   1.3  christos   /* This should not happen: EBBs are iterated from lower addresses to higher.
   7725   1.3  christos      But even if that happens there's no need to break: just flush current list
   7726   1.3  christos      and start from scratch.  */
   7727   1.3  christos   if ((list->last > 0 && list->range[list->last - 1].addr > last) ||
   7728   1.3  christos       (list->first > 0 && list->range[list->first - 1].addr >= first))
   7729   1.3  christos     {
   7730   1.3  christos       list->first = 0;
   7731   1.1  christos       list->last = 0;
   7732   1.1  christos       list->n_list = 0;
   7733   1.1  christos       list->list_root.next = &list->list_root;
   7734   1.1  christos       list->list_root.prev = &list->list_root;
   7735   1.1  christos       fprintf (stderr, "%s: move backwards requested\n", __func__);
   7736   1.1  christos     }
   7737   1.1  christos 
   7738   1.1  christos   for (; list->last < list->n_range &&
   7739   1.1  christos        list->range[list->last].addr <= last; ++list->last)
   7740   1.1  christos     if (list->range[list->last].add)
   7741   1.1  christos       reloc_range_list_append (list, list->range[list->last].irel_index);
   7742   1.1  christos 
   7743   1.8  christos   for (; list->first < list->n_range &&
   7744   1.1  christos        list->range[list->first].addr < first; ++list->first)
   7745   1.1  christos     if (!list->range[list->first].add)
   7746   1.1  christos       reloc_range_list_remove (list, list->range[list->first].irel_index);
   7747   1.1  christos }
   7748   1.1  christos 
   7749   1.1  christos static void free_reloc_range_list (reloc_range_list *list)
   7750   1.1  christos {
   7751   1.1  christos   free (list->range);
   7752   1.8  christos   free (list->reloc);
   7753   1.1  christos }
   7754   1.1  christos 
   7755   1.1  christos /* The compute_text_actions function will build a list of potential
   7756   1.1  christos    transformation actions for code in the extended basic block of each
   7757   1.3  christos    longcall that is optimized to a direct call.  From this list we
   7758   1.1  christos    generate a set of actions to actually perform that optimizes for
   7759   1.1  christos    space and, if not using size_opt, maintains branch target
   7760   1.1  christos    alignments.
   7761   1.1  christos 
   7762   1.1  christos    These actions to be performed are placed on a per-section list.
   7763   1.1  christos    The actual changes are performed by relax_section() in the second
   7764   1.1  christos    pass.  */
   7765   1.1  christos 
   7766   1.1  christos bool
   7767   1.1  christos compute_text_actions (bfd *abfd,
   7768   1.1  christos 		      asection *sec,
   7769   1.1  christos 		      struct bfd_link_info *link_info)
   7770   1.1  christos {
   7771   1.1  christos   xtensa_opcode *reloc_opcodes = NULL;
   7772   1.1  christos   xtensa_relax_info *relax_info;
   7773   1.1  christos   bfd_byte *contents;
   7774   1.1  christos   Elf_Internal_Rela *internal_relocs;
   7775   1.1  christos   bool ok = true;
   7776   1.1  christos   unsigned i;
   7777   1.1  christos   property_table_entry *prop_table = 0;
   7778   1.8  christos   int ptblsize = 0;
   7779   1.1  christos   bfd_size_type sec_size;
   7780   1.1  christos   reloc_range_list relevant_relocs;
   7781   1.1  christos 
   7782   1.1  christos   relax_info = get_xtensa_relax_info (sec);
   7783   1.8  christos   BFD_ASSERT (relax_info);
   7784   1.1  christos   BFD_ASSERT (relax_info->src_next == relax_info->src_count);
   7785   1.1  christos 
   7786   1.8  christos   /* Do nothing if the section contains no optimized longcalls.  */
   7787   1.1  christos   if (!relax_info->is_relaxable_asm_section)
   7788   1.1  christos     return ok;
   7789   1.1  christos 
   7790   1.3  christos   internal_relocs = retrieve_internal_relocs (abfd, sec,
   7791   1.3  christos 					      link_info->keep_memory);
   7792   1.3  christos 
   7793   1.3  christos   if (internal_relocs)
   7794   1.3  christos     qsort (internal_relocs, sec->reloc_count, sizeof (Elf_Internal_Rela),
   7795   1.3  christos 	   internal_reloc_compare);
   7796   1.1  christos 
   7797   1.1  christos   sec_size = bfd_get_section_limit (abfd, sec);
   7798   1.1  christos   contents = retrieve_contents (abfd, sec, link_info->keep_memory);
   7799   1.1  christos   if (contents == NULL && sec_size != 0)
   7800   1.1  christos     {
   7801   1.1  christos       ok = false;
   7802   1.1  christos       goto error_return;
   7803   1.1  christos     }
   7804   1.1  christos 
   7805   1.1  christos   ptblsize = xtensa_read_table_entries (abfd, sec, &prop_table,
   7806   1.1  christos 					XTENSA_PROP_SEC_NAME, false);
   7807   1.1  christos   if (ptblsize < 0)
   7808   1.1  christos     {
   7809   1.1  christos       ok = false;
   7810   1.1  christos       goto error_return;
   7811   1.1  christos     }
   7812   1.1  christos 
   7813   1.6  christos   /* Precompute the opcode for each relocation.  */
   7814   1.6  christos   reloc_opcodes = build_reloc_opcodes (abfd, sec, contents, internal_relocs);
   7815   1.6  christos 
   7816   1.6  christos   build_reloc_ranges (abfd, sec, contents, internal_relocs, reloc_opcodes,
   7817   1.6  christos 		      &relevant_relocs);
   7818   1.6  christos 
   7819   1.1  christos   for (i = 0; i < sec->reloc_count; i++)
   7820   1.1  christos     {
   7821   1.1  christos       Elf_Internal_Rela *irel = &internal_relocs[i];
   7822   1.1  christos       bfd_vma r_offset;
   7823   1.1  christos       property_table_entry *the_entry;
   7824   1.1  christos       int ptbl_idx;
   7825   1.1  christos       ebb_t *ebb;
   7826   1.1  christos       ebb_constraint ebb_table;
   7827   1.1  christos       bfd_size_type simplify_size;
   7828   1.1  christos 
   7829   1.1  christos       if (irel && ELF32_R_TYPE (irel->r_info) != R_XTENSA_ASM_SIMPLIFY)
   7830   1.1  christos 	continue;
   7831   1.1  christos       r_offset = irel->r_offset;
   7832   1.1  christos 
   7833   1.1  christos       simplify_size = get_asm_simplify_size (contents, sec_size, r_offset);
   7834   1.1  christos       if (simplify_size == 0)
   7835   1.1  christos 	{
   7836   1.1  christos 	  _bfd_error_handler
   7837   1.1  christos 	    /* xgettext:c-format */
   7838   1.1  christos 	    (_("%pB(%pA+%#" PRIx64 "): could not decode instruction for "
   7839   1.1  christos 	       "XTENSA_ASM_SIMPLIFY relocation; "
   7840   1.1  christos 	       "possible configuration mismatch"),
   7841   1.1  christos 	     sec->owner, sec, (uint64_t) r_offset);
   7842   1.1  christos 	  continue;
   7843   1.1  christos 	}
   7844   1.1  christos 
   7845   1.1  christos       /* If the instruction table is not around, then don't do this
   7846   1.1  christos 	 relaxation.  */
   7847   1.1  christos       the_entry = elf_xtensa_find_property_entry (prop_table, ptblsize,
   7848   1.1  christos 						  sec->vma + irel->r_offset);
   7849   1.1  christos       if (the_entry == NULL || XTENSA_NO_NOP_REMOVAL)
   7850   1.1  christos 	{
   7851   1.1  christos 	  text_action_add (&relax_info->action_list,
   7852   1.1  christos 			   ta_convert_longcall, sec, r_offset,
   7853   1.1  christos 			   0);
   7854   1.1  christos 	  continue;
   7855   1.1  christos 	}
   7856   1.1  christos 
   7857   1.1  christos       /* If the next longcall happens to be at the same address as an
   7858   1.1  christos 	 unreachable section of size 0, then skip forward.  */
   7859   1.1  christos       ptbl_idx = the_entry - prop_table;
   7860   1.1  christos       while ((the_entry->flags & XTENSA_PROP_UNREACHABLE)
   7861   1.1  christos 	     && the_entry->size == 0
   7862   1.1  christos 	     && ptbl_idx + 1 < ptblsize
   7863   1.1  christos 	     && (prop_table[ptbl_idx + 1].address
   7864   1.1  christos 		 == prop_table[ptbl_idx].address))
   7865   1.1  christos 	{
   7866   1.3  christos 	  ptbl_idx++;
   7867   1.3  christos 	  the_entry++;
   7868   1.3  christos 	}
   7869   1.1  christos 
   7870   1.1  christos       if (the_entry->flags & XTENSA_PROP_NO_TRANSFORM)
   7871   1.1  christos 	  /* NO_REORDER is OK */
   7872   1.1  christos 	continue;
   7873   1.1  christos 
   7874   1.1  christos       init_ebb_constraint (&ebb_table);
   7875   1.1  christos       ebb = &ebb_table.ebb;
   7876   1.1  christos       init_ebb (ebb, sec, contents, sec_size, prop_table, ptblsize,
   7877   1.1  christos 		internal_relocs, sec->reloc_count);
   7878   1.1  christos       ebb->start_offset = r_offset + simplify_size;
   7879   1.1  christos       ebb->end_offset = r_offset + simplify_size;
   7880   1.1  christos       ebb->start_ptbl_idx = ptbl_idx;
   7881   1.1  christos       ebb->end_ptbl_idx = ptbl_idx;
   7882   1.1  christos       ebb->start_reloc_idx = i;
   7883   1.1  christos       ebb->end_reloc_idx = i;
   7884   1.1  christos 
   7885   1.1  christos       if (!extend_ebb_bounds (ebb)
   7886   1.1  christos 	  || !compute_ebb_proposed_actions (&ebb_table)
   7887   1.1  christos 	  || !compute_ebb_actions (&ebb_table)
   7888   1.1  christos 	  || !check_section_ebb_pcrels_fit (abfd, sec, contents,
   7889   1.1  christos 					    internal_relocs,
   7890   1.3  christos 					    &relevant_relocs,
   7891   1.3  christos 					    &ebb_table, reloc_opcodes)
   7892   1.1  christos 	  || !check_section_ebb_reduces (&ebb_table))
   7893   1.3  christos 	{
   7894   1.1  christos 	  /* If anything goes wrong or we get unlucky and something does
   7895   1.1  christos 	     not fit, with our plan because of expansion between
   7896   1.1  christos 	     critical branches, just convert to a NOP.  */
   7897   1.8  christos 
   7898   1.1  christos 	  text_action_add (&relax_info->action_list,
   7899   1.1  christos 			   ta_convert_longcall, sec, r_offset, 0);
   7900   1.8  christos 	  i = ebb_table.ebb.end_reloc_idx;
   7901   1.8  christos 	  free_ebb_constraint (&ebb_table);
   7902   1.1  christos 	  continue;
   7903   1.1  christos 	}
   7904   1.1  christos 
   7905   1.1  christos       text_action_add_proposed (&relax_info->action_list, &ebb_table, sec);
   7906   1.1  christos 
   7907   1.1  christos       /* Update the index so we do not go looking at the relocations
   7908   1.1  christos 	 we have already processed.  */
   7909   1.1  christos       i = ebb_table.ebb.end_reloc_idx;
   7910   1.8  christos       free_ebb_constraint (&ebb_table);
   7911   1.1  christos     }
   7912   1.1  christos 
   7913   1.1  christos   free_reloc_range_list (&relevant_relocs);
   7914   1.1  christos 
   7915   1.1  christos #if DEBUG
   7916   1.1  christos   if (action_list_count (&relax_info->action_list))
   7917   1.1  christos     print_action_list (stderr, &relax_info->action_list);
   7918   1.8  christos #endif
   7919   1.1  christos 
   7920   1.1  christos  error_return:
   7921   1.3  christos   release_contents (sec, contents);
   7922   1.1  christos   release_internal_relocs (sec, internal_relocs);
   7923   1.1  christos   free (prop_table);
   7924   1.1  christos   free (reloc_opcodes);
   7925   1.1  christos 
   7926   1.8  christos   return ok;
   7927   1.1  christos }
   7928   1.1  christos 
   7929   1.1  christos 
   7930   1.1  christos /* Do not widen an instruction if it is preceeded by a
   7931   1.1  christos    loop opcode.  It might cause misalignment.  */
   7932   1.1  christos 
   7933   1.1  christos static bool
   7934   1.1  christos prev_instr_is_a_loop (bfd_byte *contents,
   7935   1.1  christos 		      bfd_size_type content_length,
   7936   1.1  christos 		      bfd_size_type offset)
   7937   1.1  christos {
   7938   1.1  christos   xtensa_opcode prev_opcode;
   7939   1.1  christos 
   7940   1.1  christos   if (offset < 3)
   7941   1.1  christos     return false;
   7942   1.1  christos   prev_opcode = insn_decode_opcode (contents, content_length, offset-3, 0);
   7943   1.1  christos   return (xtensa_opcode_is_loop (xtensa_default_isa, prev_opcode) == 1);
   7944   1.1  christos }
   7945   1.1  christos 
   7946   1.1  christos 
   7947   1.1  christos /* Find all of the possible actions for an extended basic block.  */
   7948   1.1  christos 
   7949   1.1  christos bool
   7950   1.1  christos compute_ebb_proposed_actions (ebb_constraint *ebb_table)
   7951   1.1  christos {
   7952   1.1  christos   const ebb_t *ebb = &ebb_table->ebb;
   7953   1.1  christos   unsigned rel_idx = ebb->start_reloc_idx;
   7954   1.1  christos   property_table_entry *entry, *start_entry, *end_entry;
   7955   1.1  christos   bfd_vma offset = 0;
   7956   1.1  christos   xtensa_isa isa = xtensa_default_isa;
   7957   1.1  christos   xtensa_format fmt;
   7958   1.1  christos   static xtensa_insnbuf insnbuf = NULL;
   7959   1.1  christos   static xtensa_insnbuf slotbuf = NULL;
   7960   1.1  christos 
   7961   1.1  christos   if (insnbuf == NULL)
   7962   1.1  christos     {
   7963   1.1  christos       insnbuf = xtensa_insnbuf_alloc (isa);
   7964   1.1  christos       slotbuf = xtensa_insnbuf_alloc (isa);
   7965   1.1  christos     }
   7966   1.1  christos 
   7967   1.8  christos   start_entry = &ebb->ptbl[ebb->start_ptbl_idx];
   7968   1.1  christos   end_entry = &ebb->ptbl[ebb->end_ptbl_idx];
   7969   1.1  christos 
   7970   1.1  christos   for (entry = start_entry; entry <= end_entry; entry++)
   7971   1.3  christos     {
   7972   1.1  christos       bfd_vma start_offset, end_offset;
   7973   1.1  christos       bfd_size_type insn_len;
   7974   1.1  christos 
   7975   1.1  christos       start_offset = entry->address - ebb->sec->vma;
   7976   1.1  christos       end_offset = entry->address + entry->size - ebb->sec->vma;
   7977   1.1  christos 
   7978   1.8  christos       if (entry == start_entry)
   7979   1.1  christos 	start_offset = ebb->start_offset;
   7980   1.1  christos       if (entry == end_entry)
   7981   1.1  christos 	end_offset = ebb->end_offset;
   7982   1.1  christos       offset = start_offset;
   7983   1.1  christos 
   7984   1.1  christos       if (offset == entry->address - ebb->sec->vma
   7985   1.1  christos 	  && (entry->flags & XTENSA_PROP_INSN_BRANCH_TARGET) != 0)
   7986   1.1  christos 	{
   7987   1.1  christos 	  enum ebb_target_enum align_type = EBB_DESIRE_TGT_ALIGN;
   7988   1.1  christos 	  BFD_ASSERT (offset != end_offset);
   7989   1.1  christos 	  if (offset == end_offset)
   7990   1.1  christos 	    return false;
   7991   1.1  christos 
   7992   1.1  christos 	  insn_len = insn_decode_len (ebb->contents, ebb->content_length,
   7993   1.1  christos 				      offset);
   7994   1.1  christos 	  if (insn_len == 0)
   7995   1.1  christos 	    goto decode_error;
   7996   1.1  christos 
   7997   1.1  christos 	  if (check_branch_target_aligned_address (offset, insn_len))
   7998   1.1  christos 	    align_type = EBB_REQUIRE_TGT_ALIGN;
   7999   1.1  christos 
   8000   1.3  christos 	  ebb_propose_action (ebb_table, align_type, 0,
   8001   1.1  christos 			      ta_none, offset, 0, true);
   8002   1.1  christos 	}
   8003   1.1  christos 
   8004   1.1  christos       while (offset != end_offset)
   8005   1.1  christos 	{
   8006   1.1  christos 	  Elf_Internal_Rela *irel;
   8007   1.8  christos 	  xtensa_opcode opcode;
   8008   1.3  christos 
   8009   1.1  christos 	  while (rel_idx < ebb->end_reloc_idx
   8010   1.1  christos 		 && (ebb->relocs[rel_idx].r_offset < offset
   8011   1.1  christos 		     || (ebb->relocs[rel_idx].r_offset == offset
   8012   1.1  christos 			 && (ELF32_R_TYPE (ebb->relocs[rel_idx].r_info)
   8013   1.1  christos 			     != R_XTENSA_ASM_SIMPLIFY))))
   8014   1.1  christos 	    rel_idx++;
   8015   1.1  christos 
   8016   1.1  christos 	  /* Check for longcall.  */
   8017   1.1  christos 	  irel = &ebb->relocs[rel_idx];
   8018   1.1  christos 	  if (irel->r_offset == offset
   8019   1.1  christos 	      && ELF32_R_TYPE (irel->r_info) == R_XTENSA_ASM_SIMPLIFY)
   8020   1.1  christos 	    {
   8021   1.1  christos 	      bfd_size_type simplify_size;
   8022   1.1  christos 
   8023   1.1  christos 	      simplify_size = get_asm_simplify_size (ebb->contents,
   8024   1.1  christos 						     ebb->content_length,
   8025   1.1  christos 						     irel->r_offset);
   8026   1.1  christos 	      if (simplify_size == 0)
   8027   1.1  christos 		goto decode_error;
   8028   1.1  christos 
   8029   1.1  christos 	      ebb_propose_action (ebb_table, EBB_NO_ALIGN, 0,
   8030   1.1  christos 				  ta_convert_longcall, offset, 0, true);
   8031   1.1  christos 
   8032   1.1  christos 	      offset += simplify_size;
   8033   1.1  christos 	      continue;
   8034   1.1  christos 	    }
   8035   1.1  christos 
   8036   1.1  christos 	  if (offset + MIN_INSN_LENGTH > ebb->content_length)
   8037   1.1  christos 	    goto decode_error;
   8038   1.1  christos 	  xtensa_insnbuf_from_chars (isa, insnbuf, &ebb->contents[offset],
   8039   1.1  christos 				     ebb->content_length - offset);
   8040   1.1  christos 	  fmt = xtensa_format_decode (isa, insnbuf);
   8041   1.8  christos 	  if (fmt == XTENSA_UNDEFINED)
   8042   1.1  christos 	    goto decode_error;
   8043   1.1  christos 	  insn_len = xtensa_format_length (isa, fmt);
   8044   1.1  christos 	  if (insn_len == (bfd_size_type) XTENSA_UNDEFINED)
   8045   1.1  christos 	    goto decode_error;
   8046   1.1  christos 
   8047   1.1  christos 	  if (xtensa_format_num_slots (isa, fmt) != 1)
   8048   1.1  christos 	    {
   8049   1.1  christos 	      offset += insn_len;
   8050   1.8  christos 	      continue;
   8051   1.1  christos 	    }
   8052   1.1  christos 
   8053   1.1  christos 	  xtensa_format_get_slot (isa, fmt, 0, insnbuf, slotbuf);
   8054   1.1  christos 	  opcode = xtensa_opcode_decode (isa, fmt, 0, slotbuf);
   8055   1.1  christos 	  if (opcode == XTENSA_UNDEFINED)
   8056   1.8  christos 	    goto decode_error;
   8057   1.1  christos 
   8058   1.1  christos 	  if ((entry->flags & XTENSA_PROP_INSN_NO_DENSITY) == 0
   8059   1.1  christos 	      && (entry->flags & XTENSA_PROP_NO_TRANSFORM) == 0
   8060   1.1  christos 	      && can_narrow_instruction (slotbuf, fmt, opcode) != 0)
   8061   1.1  christos 	    {
   8062   1.1  christos 	      /* Add an instruction narrow action.  */
   8063   1.1  christos 	      ebb_propose_action (ebb_table, EBB_NO_ALIGN, 0,
   8064   1.1  christos 				  ta_narrow_insn, offset, 0, false);
   8065   1.1  christos 	    }
   8066   1.8  christos 	  else if ((entry->flags & XTENSA_PROP_NO_TRANSFORM) == 0
   8067   1.1  christos 		   && can_widen_instruction (slotbuf, fmt, opcode) != 0
   8068   1.1  christos 		   && ! prev_instr_is_a_loop (ebb->contents,
   8069   1.8  christos 					      ebb->content_length, offset))
   8070   1.1  christos 	    {
   8071   1.1  christos 	      /* Add an instruction widen action.  */
   8072   1.6  christos 	      ebb_propose_action (ebb_table, EBB_NO_ALIGN, 0,
   8073   1.6  christos 				  ta_widen_insn, offset, 0, false);
   8074   1.6  christos 	    }
   8075   1.6  christos 	  else if (xtensa_opcode_is_loop (xtensa_default_isa, opcode) == 1)
   8076   1.6  christos 	    {
   8077   1.8  christos 	      /* Check for branch targets.  */
   8078   1.1  christos 	      ebb_propose_action (ebb_table, EBB_REQUIRE_LOOP_ALIGN, 0,
   8079   1.1  christos 				  ta_none, offset, 0, true);
   8080   1.1  christos 	    }
   8081   1.1  christos 
   8082   1.1  christos 	  offset += insn_len;
   8083   1.1  christos 	}
   8084   1.1  christos     }
   8085   1.1  christos 
   8086   1.1  christos   if (ebb->ends_unreachable)
   8087   1.1  christos     {
   8088   1.1  christos       ebb_propose_action (ebb_table, EBB_NO_ALIGN, 0,
   8089   1.1  christos 			  ta_fill, ebb->end_offset, 0, true);
   8090   1.1  christos     }
   8091   1.1  christos 
   8092   1.1  christos   return true;
   8093   1.1  christos 
   8094   1.1  christos  decode_error:
   8095   1.1  christos   _bfd_error_handler
   8096   1.1  christos     /* xgettext:c-format */
   8097   1.1  christos     (_("%pB(%pA+%#" PRIx64 "): could not decode instruction; "
   8098   1.8  christos        "possible configuration mismatch"),
   8099   1.1  christos      ebb->sec->owner, ebb->sec, (uint64_t) offset);
   8100   1.1  christos   return false;
   8101   1.1  christos }
   8102   1.1  christos 
   8103   1.1  christos 
   8104   1.1  christos /* After all of the information has collected about the
   8105   1.1  christos    transformations possible in an EBB, compute the appropriate actions
   8106   1.1  christos    here in compute_ebb_actions.  We still must check later to make
   8107   1.1  christos    sure that the actions do not break any relocations.  The algorithm
   8108   1.1  christos    used here is pretty greedy.  Basically, it removes as many no-ops
   8109   1.1  christos    as possible so that the end of the EBB has the same alignment
   8110   1.1  christos    characteristics as the original.  First, it uses narrowing, then
   8111   1.1  christos    fill space at the end of the EBB, and finally widenings.  If that
   8112   1.1  christos    does not work, it tries again with one fewer no-op removed.  The
   8113   1.1  christos    optimization will only be performed if all of the branch targets
   8114   1.1  christos    that were aligned before transformation are also aligned after the
   8115   1.1  christos    transformation.
   8116   1.1  christos 
   8117   1.8  christos    When the size_opt flag is set, ignore the branch target alignments,
   8118   1.1  christos    narrow all wide instructions, and remove all no-ops unless the end
   8119   1.1  christos    of the EBB prevents it.  */
   8120   1.1  christos 
   8121   1.1  christos bool
   8122   1.1  christos compute_ebb_actions (ebb_constraint *ebb_table)
   8123   1.1  christos {
   8124   1.1  christos   unsigned i = 0;
   8125   1.1  christos   unsigned j;
   8126   1.1  christos   int removed_bytes = 0;
   8127   1.1  christos   ebb_t *ebb = &ebb_table->ebb;
   8128   1.1  christos   unsigned seg_idx_start = 0;
   8129   1.1  christos   unsigned seg_idx_end = 0;
   8130   1.1  christos 
   8131   1.1  christos   /* We perform this like the assembler relaxation algorithm: Start by
   8132   1.1  christos      assuming all instructions are narrow and all no-ops removed; then
   8133   1.1  christos      walk through....  */
   8134   1.1  christos 
   8135   1.1  christos   /* For each segment of this that has a solid constraint, check to
   8136   1.1  christos      see if there are any combinations that will keep the constraint.
   8137   1.1  christos      If so, use it.  */
   8138   1.1  christos   for (seg_idx_end = 0; seg_idx_end < ebb_table->action_count; seg_idx_end++)
   8139   1.1  christos     {
   8140   1.1  christos       bool requires_text_end_align = false;
   8141   1.1  christos       unsigned longcall_count = 0;
   8142   1.1  christos       unsigned longcall_convert_count = 0;
   8143   1.1  christos       unsigned narrowable_count = 0;
   8144   1.1  christos       unsigned narrowable_convert_count = 0;
   8145   1.1  christos       unsigned widenable_count = 0;
   8146   1.1  christos       unsigned widenable_convert_count = 0;
   8147   1.1  christos 
   8148   1.1  christos       proposed_action *action = NULL;
   8149   1.1  christos       int align = (1 << ebb_table->ebb.sec->alignment_power);
   8150   1.8  christos 
   8151   1.1  christos       seg_idx_start = seg_idx_end;
   8152   1.1  christos 
   8153   1.1  christos       for (i = seg_idx_start; i < ebb_table->action_count; i++)
   8154   1.1  christos 	{
   8155   1.1  christos 	  action = &ebb_table->actions[i];
   8156   1.1  christos 	  if (action->action == ta_convert_longcall)
   8157   1.1  christos 	    longcall_count++;
   8158   1.1  christos 	  if (action->action == ta_narrow_insn)
   8159   1.1  christos 	    narrowable_count++;
   8160   1.1  christos 	  if (action->action == ta_widen_insn)
   8161   1.1  christos 	    widenable_count++;
   8162   1.1  christos 	  if (action->action == ta_fill)
   8163   1.1  christos 	    break;
   8164   1.1  christos 	  if (action->align_type == EBB_REQUIRE_LOOP_ALIGN)
   8165   1.1  christos 	    break;
   8166   1.1  christos 	  if (action->align_type == EBB_REQUIRE_TGT_ALIGN
   8167   1.1  christos 	      && !elf32xtensa_size_opt)
   8168   1.1  christos 	    break;
   8169   1.1  christos 	}
   8170   1.1  christos       seg_idx_end = i;
   8171   1.1  christos 
   8172   1.1  christos       if (seg_idx_end == ebb_table->action_count && !ebb->ends_unreachable)
   8173   1.1  christos 	requires_text_end_align = true;
   8174   1.1  christos 
   8175   1.1  christos       if (elf32xtensa_size_opt && !requires_text_end_align
   8176   1.1  christos 	  && action->align_type != EBB_REQUIRE_LOOP_ALIGN
   8177   1.1  christos 	  && action->align_type != EBB_REQUIRE_TGT_ALIGN)
   8178   1.1  christos 	{
   8179   1.1  christos 	  longcall_convert_count = longcall_count;
   8180   1.1  christos 	  narrowable_convert_count = narrowable_count;
   8181   1.1  christos 	  widenable_convert_count = 0;
   8182   1.1  christos 	}
   8183   1.1  christos       else
   8184   1.1  christos 	{
   8185   1.1  christos 	  /* There is a constraint.  Convert the max number of longcalls.  */
   8186   1.1  christos 	  narrowable_convert_count = 0;
   8187   1.1  christos 	  longcall_convert_count = 0;
   8188   1.1  christos 	  widenable_convert_count = 0;
   8189   1.1  christos 
   8190   1.1  christos 	  for (j = 0; j < longcall_count; j++)
   8191   1.1  christos 	    {
   8192   1.1  christos 	      int removed = (longcall_count - j) * 3 & (align - 1);
   8193   1.1  christos 	      unsigned desire_narrow = (align - removed) & (align - 1);
   8194   1.1  christos 	      unsigned desire_widen = removed;
   8195   1.1  christos 	      if (desire_narrow <= narrowable_count)
   8196   1.1  christos 		{
   8197   1.1  christos 		  narrowable_convert_count = desire_narrow;
   8198   1.1  christos 		  narrowable_convert_count +=
   8199   1.1  christos 		    (align * ((narrowable_count - narrowable_convert_count)
   8200   1.1  christos 			      / align));
   8201   1.1  christos 		  longcall_convert_count = (longcall_count - j);
   8202   1.8  christos 		  widenable_convert_count = 0;
   8203   1.1  christos 		  break;
   8204   1.1  christos 		}
   8205   1.1  christos 	      if (desire_widen <= widenable_count && !elf32xtensa_size_opt)
   8206   1.1  christos 		{
   8207   1.1  christos 		  narrowable_convert_count = 0;
   8208   1.1  christos 		  longcall_convert_count = longcall_count - j;
   8209   1.1  christos 		  widenable_convert_count = desire_widen;
   8210   1.8  christos 		  break;
   8211   1.1  christos 		}
   8212   1.1  christos 	    }
   8213   1.1  christos 	}
   8214   1.1  christos 
   8215   1.1  christos       /* Now the number of conversions are saved.  Do them.  */
   8216   1.1  christos       for (i = seg_idx_start; i < seg_idx_end; i++)
   8217   1.1  christos 	{
   8218   1.8  christos 	  action = &ebb_table->actions[i];
   8219   1.1  christos 	  switch (action->action)
   8220   1.1  christos 	    {
   8221   1.1  christos 	    case ta_convert_longcall:
   8222   1.1  christos 	      if (longcall_convert_count != 0)
   8223   1.1  christos 		{
   8224   1.1  christos 		  action->action = ta_remove_longcall;
   8225   1.1  christos 		  action->do_action = true;
   8226   1.1  christos 		  action->removed_bytes += 3;
   8227   1.1  christos 		  longcall_convert_count--;
   8228   1.1  christos 		}
   8229   1.1  christos 	      break;
   8230   1.1  christos 	    case ta_narrow_insn:
   8231   1.1  christos 	      if (narrowable_convert_count != 0)
   8232   1.1  christos 		{
   8233   1.1  christos 		  action->do_action = true;
   8234   1.1  christos 		  action->removed_bytes += 1;
   8235   1.1  christos 		  narrowable_convert_count--;
   8236   1.1  christos 		}
   8237   1.1  christos 	      break;
   8238   1.1  christos 	    case ta_widen_insn:
   8239   1.1  christos 	      if (widenable_convert_count != 0)
   8240   1.1  christos 		{
   8241   1.1  christos 		  action->do_action = true;
   8242   1.8  christos 		  action->removed_bytes -= 1;
   8243   1.1  christos 		  widenable_convert_count--;
   8244   1.1  christos 		}
   8245   1.1  christos 	      break;
   8246   1.1  christos 	    default:
   8247   1.1  christos 	      break;
   8248   1.1  christos 	    }
   8249   1.1  christos 	}
   8250   1.1  christos     }
   8251   1.1  christos 
   8252   1.1  christos   /* Now we move on to some local opts.  Try to remove each of the
   8253   1.1  christos      remaining longcalls.  */
   8254   1.1  christos 
   8255   1.8  christos   if (ebb_table->ebb.ends_section || ebb_table->ebb.ends_unreachable)
   8256   1.1  christos     {
   8257   1.1  christos       removed_bytes = 0;
   8258   1.1  christos       for (i = 0; i < ebb_table->action_count; i++)
   8259   1.1  christos 	{
   8260   1.1  christos 	  int old_removed_bytes = removed_bytes;
   8261   1.1  christos 	  proposed_action *action = &ebb_table->actions[i];
   8262   1.1  christos 
   8263   1.1  christos 	  if (action->do_action && action->action == ta_convert_longcall)
   8264   1.1  christos 	    {
   8265   1.1  christos 	      bool bad_alignment = false;
   8266   1.8  christos 	      removed_bytes += 3;
   8267   1.1  christos 	      for (j = i + 1; j < ebb_table->action_count; j++)
   8268   1.1  christos 		{
   8269   1.1  christos 		  proposed_action *new_action = &ebb_table->actions[j];
   8270   1.1  christos 		  bfd_vma offset = new_action->offset;
   8271   1.1  christos 		  if (new_action->align_type == EBB_REQUIRE_TGT_ALIGN)
   8272   1.1  christos 		    {
   8273   1.1  christos 		      if (!check_branch_target_aligned
   8274   1.1  christos 			  (ebb_table->ebb.contents,
   8275   1.8  christos 			   ebb_table->ebb.content_length,
   8276   1.1  christos 			   offset, offset - removed_bytes))
   8277   1.8  christos 			{
   8278   1.1  christos 			  bad_alignment = true;
   8279   1.1  christos 			  break;
   8280   1.1  christos 			}
   8281   1.1  christos 		    }
   8282   1.1  christos 		  if (new_action->align_type == EBB_REQUIRE_LOOP_ALIGN)
   8283   1.1  christos 		    {
   8284   1.1  christos 		      if (!check_loop_aligned (ebb_table->ebb.contents,
   8285   1.8  christos 					       ebb_table->ebb.content_length,
   8286   1.1  christos 					       offset,
   8287   1.8  christos 					       offset - removed_bytes))
   8288   1.1  christos 			{
   8289   1.1  christos 			  bad_alignment = true;
   8290   1.1  christos 			  break;
   8291   1.1  christos 			}
   8292   1.1  christos 		    }
   8293   1.1  christos 		  if (new_action->action == ta_narrow_insn
   8294   1.1  christos 		      && !new_action->do_action
   8295   1.1  christos 		      && ebb_table->ebb.sec->alignment_power == 2)
   8296   1.1  christos 		    {
   8297   1.8  christos 		      /* Narrow an instruction and we are done.  */
   8298   1.1  christos 		      new_action->do_action = true;
   8299   1.1  christos 		      new_action->removed_bytes += 1;
   8300   1.1  christos 		      bad_alignment = false;
   8301   1.1  christos 		      break;
   8302   1.1  christos 		    }
   8303   1.1  christos 		  if (new_action->action == ta_widen_insn
   8304   1.1  christos 		      && new_action->do_action
   8305   1.1  christos 		      && ebb_table->ebb.sec->alignment_power == 2)
   8306   1.1  christos 		    {
   8307   1.1  christos 		      /* Narrow an instruction and we are done.  */
   8308   1.1  christos 		      new_action->do_action = false;
   8309   1.1  christos 		      new_action->removed_bytes += 1;
   8310   1.1  christos 		      bad_alignment = false;
   8311   1.1  christos 		      break;
   8312   1.1  christos 		    }
   8313   1.1  christos 		  if (new_action->do_action)
   8314   1.1  christos 		    removed_bytes += new_action->removed_bytes;
   8315   1.1  christos 		}
   8316   1.1  christos 	      if (!bad_alignment)
   8317   1.1  christos 		{
   8318   1.1  christos 		  action->removed_bytes += 3;
   8319   1.1  christos 		  action->action = ta_remove_longcall;
   8320   1.1  christos 		  action->do_action = true;
   8321   1.1  christos 		}
   8322   1.1  christos 	    }
   8323   1.1  christos 	  removed_bytes = old_removed_bytes;
   8324   1.1  christos 	  if (action->do_action)
   8325   1.1  christos 	    removed_bytes += action->removed_bytes;
   8326   1.6  christos 	}
   8327   1.1  christos     }
   8328   1.1  christos 
   8329   1.1  christos   removed_bytes = 0;
   8330   1.1  christos   for (i = 0; i < ebb_table->action_count; ++i)
   8331   1.1  christos     {
   8332   1.8  christos       proposed_action *action = &ebb_table->actions[i];
   8333   1.1  christos       if (action->do_action)
   8334   1.1  christos 	removed_bytes += action->removed_bytes;
   8335   1.1  christos     }
   8336   1.1  christos 
   8337   1.1  christos   if ((removed_bytes % (1 << ebb_table->ebb.sec->alignment_power)) != 0
   8338   1.1  christos       && ebb->ends_unreachable)
   8339   1.1  christos     {
   8340   1.1  christos       proposed_action *action;
   8341   1.1  christos       int br;
   8342   1.1  christos       int extra_space;
   8343   1.1  christos 
   8344   1.1  christos       BFD_ASSERT (ebb_table->action_count != 0);
   8345   1.6  christos       action = &ebb_table->actions[ebb_table->action_count - 1];
   8346   1.6  christos       BFD_ASSERT (action->action == ta_fill);
   8347   1.1  christos       BFD_ASSERT (ebb->ends_unreachable->flags & XTENSA_PROP_UNREACHABLE);
   8348   1.1  christos 
   8349   1.1  christos       extra_space = xtensa_compute_fill_extra_space (ebb->ends_unreachable);
   8350   1.1  christos       br = action->removed_bytes + removed_bytes + extra_space;
   8351   1.1  christos       br = br & ((1 << ebb->sec->alignment_power ) - 1);
   8352   1.1  christos 
   8353   1.1  christos       action->removed_bytes = extra_space - br;
   8354   1.1  christos     }
   8355   1.1  christos   return true;
   8356   1.1  christos }
   8357   1.3  christos 
   8358   1.1  christos 
   8359   1.1  christos /* The xlate_map is a sorted array of address mappings designed to
   8360   1.1  christos    answer the offset_with_removed_text() query with a binary search instead
   8361   1.1  christos    of a linear search through the section's action_list.  */
   8362   1.1  christos 
   8363   1.1  christos typedef struct xlate_map_entry xlate_map_entry_t;
   8364   1.1  christos typedef struct xlate_map xlate_map_t;
   8365   1.1  christos 
   8366   1.1  christos struct xlate_map_entry
   8367   1.1  christos {
   8368   1.1  christos   bfd_vma orig_address;
   8369   1.1  christos   bfd_vma new_address;
   8370   1.1  christos   unsigned size;
   8371   1.1  christos };
   8372   1.1  christos 
   8373   1.1  christos struct xlate_map
   8374   1.1  christos {
   8375   1.1  christos   unsigned entry_count;
   8376   1.1  christos   xlate_map_entry_t *entry;
   8377   1.6  christos };
   8378   1.1  christos 
   8379   1.1  christos 
   8380   1.1  christos static int
   8381   1.1  christos xlate_compare (const void *a_v, const void *b_v)
   8382   1.1  christos {
   8383   1.1  christos   const xlate_map_entry_t *a = (const xlate_map_entry_t *) a_v;
   8384   1.1  christos   const xlate_map_entry_t *b = (const xlate_map_entry_t *) b_v;
   8385   1.6  christos   if (a->orig_address < b->orig_address)
   8386   1.6  christos     return -1;
   8387   1.1  christos   if (a->orig_address > (b->orig_address + b->size - 1))
   8388   1.1  christos     return 1;
   8389   1.3  christos   return 0;
   8390   1.6  christos }
   8391   1.6  christos 
   8392   1.6  christos 
   8393   1.6  christos static bfd_vma
   8394   1.6  christos xlate_offset_with_removed_text (const xlate_map_t *map,
   8395   1.6  christos 				text_action_list *action_list,
   8396   1.6  christos 				bfd_vma offset)
   8397   1.6  christos {
   8398   1.1  christos   void *r;
   8399   1.1  christos   xlate_map_entry_t *e;
   8400   1.1  christos   struct xlate_map_entry se;
   8401   1.1  christos 
   8402   1.1  christos   if (map == NULL)
   8403   1.1  christos     return offset_with_removed_text (action_list, offset);
   8404   1.3  christos 
   8405   1.3  christos   if (map->entry_count == 0)
   8406   1.3  christos     return offset;
   8407   1.3  christos 
   8408   1.3  christos   se.orig_address = offset;
   8409   1.3  christos   r = bsearch (&se, map->entry, map->entry_count,
   8410   1.3  christos 	       sizeof (xlate_map_entry_t), &xlate_compare);
   8411   1.3  christos   e = (xlate_map_entry_t *) r;
   8412   1.3  christos 
   8413   1.3  christos   /* There could be a jump past the end of the section,
   8414   1.3  christos      allow it using the last xlate map entry to translate its address.  */
   8415   1.3  christos   if (e == NULL)
   8416   1.3  christos     {
   8417   1.3  christos       e = map->entry + map->entry_count - 1;
   8418   1.3  christos       if (xlate_compare (&se, e) <= 0)
   8419   1.3  christos 	e = NULL;
   8420   1.3  christos     }
   8421   1.3  christos   BFD_ASSERT (e != NULL);
   8422   1.3  christos   if (e == NULL)
   8423   1.3  christos     return offset;
   8424   1.3  christos   return e->new_address - e->orig_address + offset;
   8425   1.3  christos }
   8426   1.3  christos 
   8427   1.3  christos typedef struct xlate_map_context_struct xlate_map_context;
   8428   1.3  christos struct xlate_map_context_struct
   8429   1.3  christos {
   8430   1.3  christos   xlate_map_t *map;
   8431   1.3  christos   xlate_map_entry_t *current_entry;
   8432   1.3  christos   int removed;
   8433   1.3  christos };
   8434   1.3  christos 
   8435   1.3  christos static int
   8436   1.3  christos xlate_map_fn (splay_tree_node node, void *p)
   8437   1.3  christos {
   8438   1.3  christos   text_action *r = (text_action *)node->value;
   8439   1.3  christos   xlate_map_context *ctx = p;
   8440   1.3  christos   unsigned orig_size = 0;
   8441   1.3  christos 
   8442   1.3  christos   switch (r->action)
   8443   1.3  christos     {
   8444   1.3  christos     case ta_none:
   8445   1.3  christos     case ta_remove_insn:
   8446   1.3  christos     case ta_convert_longcall:
   8447   1.3  christos     case ta_remove_literal:
   8448   1.3  christos     case ta_add_literal:
   8449   1.3  christos       break;
   8450   1.3  christos     case ta_remove_longcall:
   8451   1.3  christos       orig_size = 6;
   8452   1.1  christos       break;
   8453   1.1  christos     case ta_narrow_insn:
   8454   1.1  christos       orig_size = 3;
   8455   1.1  christos       break;
   8456   1.1  christos     case ta_widen_insn:
   8457   1.1  christos       orig_size = 2;
   8458   1.1  christos       break;
   8459   1.1  christos     case ta_fill:
   8460   1.1  christos       break;
   8461   1.3  christos     }
   8462   1.3  christos   ctx->current_entry->size =
   8463   1.3  christos     r->offset + orig_size - ctx->current_entry->orig_address;
   8464   1.1  christos   if (ctx->current_entry->size != 0)
   8465   1.3  christos     {
   8466   1.1  christos       ctx->current_entry++;
   8467   1.1  christos       ctx->map->entry_count++;
   8468   1.1  christos     }
   8469   1.3  christos   ctx->current_entry->orig_address = r->offset + orig_size;
   8470   1.1  christos   ctx->removed += r->removed_bytes;
   8471   1.3  christos   ctx->current_entry->new_address = r->offset + orig_size - ctx->removed;
   8472   1.1  christos   ctx->current_entry->size = 0;
   8473   1.3  christos   return 0;
   8474   1.1  christos }
   8475   1.1  christos 
   8476   1.3  christos /* Build a binary searchable offset translation map from a section's
   8477   1.3  christos    action list.  */
   8478   1.3  christos 
   8479   1.3  christos static xlate_map_t *
   8480   1.3  christos build_xlate_map (asection *sec, xtensa_relax_info *relax_info)
   8481   1.3  christos {
   8482   1.3  christos   text_action_list *action_list = &relax_info->action_list;
   8483   1.3  christos   unsigned num_actions = 0;
   8484   1.1  christos   xlate_map_context ctx;
   8485   1.3  christos 
   8486   1.1  christos   ctx.map = (xlate_map_t *) bfd_malloc (sizeof (xlate_map_t));
   8487   1.3  christos 
   8488   1.3  christos   if (ctx.map == NULL)
   8489   1.3  christos     return NULL;
   8490   1.3  christos 
   8491   1.1  christos   num_actions = action_list_count (action_list);
   8492   1.3  christos   ctx.map->entry = (xlate_map_entry_t *)
   8493   1.1  christos     bfd_malloc (sizeof (xlate_map_entry_t) * (num_actions + 1));
   8494   1.1  christos   if (ctx.map->entry == NULL)
   8495   1.1  christos     {
   8496   1.1  christos       free (ctx.map);
   8497   1.1  christos       return NULL;
   8498   1.3  christos     }
   8499   1.1  christos   ctx.map->entry_count = 0;
   8500   1.1  christos 
   8501   1.1  christos   ctx.removed = 0;
   8502   1.8  christos   ctx.current_entry = &ctx.map->entry[0];
   8503   1.8  christos 
   8504   1.8  christos   ctx.current_entry->orig_address = 0;
   8505   1.8  christos   ctx.current_entry->new_address = 0;
   8506   1.1  christos   ctx.current_entry->size = 0;
   8507   1.1  christos 
   8508   1.1  christos   splay_tree_foreach (action_list->tree, xlate_map_fn, &ctx);
   8509   1.1  christos 
   8510   1.1  christos   ctx.current_entry->size = (bfd_get_section_limit (sec->owner, sec)
   8511   1.1  christos 			     - ctx.current_entry->orig_address);
   8512   1.1  christos   if (ctx.current_entry->size != 0)
   8513   1.8  christos     ctx.map->entry_count++;
   8514   1.1  christos 
   8515   1.1  christos   return ctx.map;
   8516   1.1  christos }
   8517   1.1  christos 
   8518   1.3  christos 
   8519   1.1  christos /* Free an offset translation map.  */
   8520   1.1  christos 
   8521   1.1  christos static void
   8522   1.1  christos free_xlate_map (xlate_map_t *map)
   8523   1.3  christos {
   8524   1.1  christos   if (map)
   8525   1.1  christos     {
   8526   1.8  christos       free (map->entry);
   8527   1.1  christos       free (map);
   8528   1.3  christos     }
   8529   1.1  christos }
   8530   1.1  christos 
   8531   1.1  christos 
   8532   1.1  christos /* Use check_section_ebb_pcrels_fit to make sure that all of the
   8533   1.1  christos    relocations in a section will fit if a proposed set of actions
   8534   1.1  christos    are performed.  */
   8535   1.1  christos 
   8536   1.1  christos static bool
   8537   1.1  christos check_section_ebb_pcrels_fit (bfd *abfd,
   8538   1.1  christos 			      asection *sec,
   8539   1.3  christos 			      bfd_byte *contents,
   8540   1.3  christos 			      Elf_Internal_Rela *internal_relocs,
   8541   1.3  christos 			      reloc_range_list *relevant_relocs,
   8542   1.3  christos 			      const ebb_constraint *constraint,
   8543   1.8  christos 			      const xtensa_opcode *reloc_opcodes)
   8544   1.3  christos {
   8545   1.3  christos   unsigned i, j;
   8546   1.3  christos   unsigned n = sec->reloc_count;
   8547   1.3  christos   Elf_Internal_Rela *irel;
   8548   1.3  christos   xlate_map_t *xmap = NULL;
   8549   1.3  christos   bool ok = true;
   8550   1.3  christos   xtensa_relax_info *relax_info;
   8551   1.3  christos   reloc_range_list_entry *entry = NULL;
   8552   1.3  christos 
   8553   1.3  christos   relax_info = get_xtensa_relax_info (sec);
   8554   1.3  christos 
   8555   1.3  christos   if (relax_info && sec->reloc_count > 100)
   8556   1.3  christos     {
   8557   1.3  christos       xmap = build_xlate_map (sec, relax_info);
   8558   1.3  christos       /* NULL indicates out of memory, but the slow version
   8559   1.3  christos 	 can still be used.  */
   8560   1.3  christos     }
   8561   1.3  christos 
   8562   1.3  christos   if (relevant_relocs && constraint->action_count)
   8563   1.3  christos     {
   8564   1.3  christos       if (!relevant_relocs->ok)
   8565   1.3  christos 	{
   8566   1.3  christos 	  ok = false;
   8567   1.3  christos 	  n = 0;
   8568   1.3  christos 	}
   8569   1.3  christos       else
   8570   1.3  christos 	{
   8571   1.3  christos 	  bfd_vma min_offset, max_offset;
   8572   1.3  christos 	  min_offset = max_offset = constraint->actions[0].offset;
   8573   1.1  christos 
   8574   1.1  christos 	  for (i = 1; i < constraint->action_count; ++i)
   8575   1.1  christos 	    {
   8576   1.1  christos 	      proposed_action *action = &constraint->actions[i];
   8577   1.1  christos 	      bfd_vma offset = action->offset;
   8578   1.1  christos 
   8579   1.1  christos 	      if (offset < min_offset)
   8580   1.1  christos 		min_offset = offset;
   8581   1.3  christos 	      if (offset > max_offset)
   8582   1.3  christos 		max_offset = offset;
   8583   1.3  christos 	    }
   8584   1.3  christos 	  reloc_range_list_update_range (relevant_relocs, min_offset,
   8585   1.3  christos 					 max_offset);
   8586   1.3  christos 	  n = relevant_relocs->n_list;
   8587   1.3  christos 	  entry = &relevant_relocs->list_root;
   8588   1.3  christos 	}
   8589   1.3  christos     }
   8590   1.1  christos   else
   8591   1.1  christos     {
   8592   1.1  christos       relevant_relocs = NULL;
   8593   1.1  christos     }
   8594   1.1  christos 
   8595   1.1  christos   for (i = 0; i < n; i++)
   8596   1.1  christos     {
   8597   1.1  christos       r_reloc r_rel;
   8598   1.1  christos       bfd_vma orig_self_offset, orig_target_offset;
   8599   1.1  christos       bfd_vma self_offset, target_offset;
   8600   1.1  christos       int r_type;
   8601   1.1  christos       reloc_howto_type *howto;
   8602   1.1  christos       int self_removed_bytes, target_removed_bytes;
   8603   1.1  christos 
   8604   1.1  christos       if (relevant_relocs)
   8605   1.1  christos 	{
   8606   1.1  christos 	  entry = entry->next;
   8607   1.1  christos 	  irel = entry->irel;
   8608   1.1  christos 	}
   8609   1.1  christos       else
   8610   1.1  christos 	{
   8611   1.1  christos 	  irel = internal_relocs + i;
   8612   1.1  christos 	}
   8613   1.1  christos       r_type = ELF32_R_TYPE (irel->r_info);
   8614   1.1  christos 
   8615   1.1  christos       howto = &elf_howto_table[r_type];
   8616   1.1  christos       /* We maintain the required invariant: PC-relative relocations
   8617   1.1  christos 	 that fit before linking must fit after linking.  Thus we only
   8618   1.1  christos 	 need to deal with relocations to the same section that are
   8619   1.1  christos 	 PC-relative.  */
   8620   1.1  christos       if (r_type == R_XTENSA_ASM_SIMPLIFY
   8621   1.1  christos 	  || r_type == R_XTENSA_32_PCREL
   8622   1.1  christos 	  || !howto->pc_relative)
   8623   1.1  christos 	continue;
   8624   1.1  christos 
   8625   1.1  christos       r_reloc_init (&r_rel, abfd, irel, contents,
   8626   1.1  christos 		    bfd_get_section_limit (abfd, sec));
   8627   1.1  christos 
   8628   1.1  christos       if (r_reloc_get_section (&r_rel) != sec)
   8629   1.1  christos 	continue;
   8630   1.1  christos 
   8631   1.1  christos       orig_self_offset = irel->r_offset;
   8632   1.1  christos       orig_target_offset = r_rel.target_offset;
   8633   1.1  christos 
   8634   1.1  christos       self_offset = orig_self_offset;
   8635   1.1  christos       target_offset = orig_target_offset;
   8636   1.1  christos 
   8637   1.1  christos       if (relax_info)
   8638   1.1  christos 	{
   8639   1.1  christos 	  self_offset =
   8640   1.1  christos 	    xlate_offset_with_removed_text (xmap, &relax_info->action_list,
   8641   1.1  christos 					    orig_self_offset);
   8642   1.1  christos 	  target_offset =
   8643   1.1  christos 	    xlate_offset_with_removed_text (xmap, &relax_info->action_list,
   8644   1.1  christos 					    orig_target_offset);
   8645   1.1  christos 	}
   8646   1.1  christos 
   8647   1.1  christos       self_removed_bytes = 0;
   8648   1.1  christos       target_removed_bytes = 0;
   8649   1.1  christos 
   8650   1.1  christos       for (j = 0; j < constraint->action_count; ++j)
   8651   1.1  christos 	{
   8652   1.1  christos 	  proposed_action *action = &constraint->actions[j];
   8653   1.1  christos 	  bfd_vma offset = action->offset;
   8654   1.1  christos 	  int removed_bytes = action->removed_bytes;
   8655   1.3  christos 	  if (offset < orig_self_offset
   8656   1.3  christos 	      || (offset == orig_self_offset && action->action == ta_fill
   8657   1.3  christos 		  && action->removed_bytes < 0))
   8658   1.3  christos 	    self_removed_bytes += removed_bytes;
   8659   1.3  christos 	  if (offset < orig_target_offset
   8660   1.1  christos 	      || (offset == orig_target_offset && action->action == ta_fill
   8661   1.1  christos 		  && action->removed_bytes < 0))
   8662   1.3  christos 	    target_removed_bytes += removed_bytes;
   8663   1.3  christos 	}
   8664   1.3  christos       self_offset -= self_removed_bytes;
   8665   1.3  christos       target_offset -= target_removed_bytes;
   8666   1.3  christos 
   8667   1.3  christos       /* Try to encode it.  Get the operand and check.  */
   8668   1.3  christos       if (is_alt_relocation (ELF32_R_TYPE (irel->r_info)))
   8669   1.8  christos 	{
   8670   1.3  christos 	  /* None of the current alternate relocs are PC-relative,
   8671   1.3  christos 	     and only PC-relative relocs matter here.  */
   8672   1.1  christos 	}
   8673   1.3  christos       else
   8674   1.3  christos 	{
   8675   1.3  christos 	  xtensa_opcode opcode;
   8676   1.8  christos 	  int opnum;
   8677   1.3  christos 
   8678   1.3  christos 	  if (relevant_relocs)
   8679   1.1  christos 	    {
   8680   1.1  christos 	      opcode = entry->opcode;
   8681   1.1  christos 	      opnum = entry->opnum;
   8682   1.1  christos 	    }
   8683   1.8  christos 	  else
   8684   1.1  christos 	    {
   8685   1.1  christos 	      if (reloc_opcodes)
   8686   1.1  christos 		opcode = reloc_opcodes[relevant_relocs ?
   8687   1.1  christos 		  (unsigned)(entry - relevant_relocs->reloc) : i];
   8688   1.1  christos 	      else
   8689   1.8  christos 		opcode = get_relocation_opcode (abfd, sec, contents, irel);
   8690   1.1  christos 	      if (opcode == XTENSA_UNDEFINED)
   8691   1.1  christos 		{
   8692   1.1  christos 		  ok = false;
   8693   1.1  christos 		  break;
   8694   1.1  christos 		}
   8695   1.8  christos 
   8696   1.1  christos 	      opnum = get_relocation_opnd (opcode, ELF32_R_TYPE (irel->r_info));
   8697   1.1  christos 	      if (opnum == XTENSA_UNDEFINED)
   8698   1.1  christos 		{
   8699   1.1  christos 		  ok = false;
   8700   1.1  christos 		  break;
   8701   1.1  christos 		}
   8702   1.1  christos 	    }
   8703   1.1  christos 
   8704   1.1  christos 	  if (!pcrel_reloc_fits (opcode, opnum, self_offset, target_offset))
   8705   1.1  christos 	    {
   8706   1.1  christos 	      ok = false;
   8707   1.1  christos 	      break;
   8708   1.8  christos 	    }
   8709   1.1  christos 	}
   8710   1.8  christos     }
   8711   1.1  christos 
   8712   1.1  christos   free_xlate_map (xmap);
   8713   1.1  christos 
   8714   1.1  christos   return ok;
   8715   1.1  christos }
   8716   1.1  christos 
   8717   1.1  christos 
   8718   1.1  christos static bool
   8719   1.1  christos check_section_ebb_reduces (const ebb_constraint *constraint)
   8720   1.1  christos {
   8721   1.1  christos   int removed = 0;
   8722   1.1  christos   unsigned i;
   8723   1.1  christos 
   8724   1.1  christos   for (i = 0; i < constraint->action_count; i++)
   8725   1.1  christos     {
   8726   1.1  christos       const proposed_action *action = &constraint->actions[i];
   8727   1.1  christos       if (action->do_action)
   8728   1.1  christos 	removed += action->removed_bytes;
   8729   1.1  christos     }
   8730   1.1  christos   if (removed < 0)
   8731   1.1  christos     return false;
   8732   1.1  christos 
   8733   1.1  christos   return true;
   8734   1.1  christos }
   8735   1.1  christos 
   8736   1.1  christos 
   8737   1.1  christos void
   8738   1.1  christos text_action_add_proposed (text_action_list *l,
   8739   1.1  christos 			  const ebb_constraint *ebb_table,
   8740   1.1  christos 			  asection *sec)
   8741   1.1  christos {
   8742   1.1  christos   unsigned i;
   8743   1.1  christos 
   8744   1.1  christos   for (i = 0; i < ebb_table->action_count; i++)
   8745   1.1  christos     {
   8746   1.1  christos       proposed_action *action = &ebb_table->actions[i];
   8747   1.1  christos 
   8748   1.1  christos       if (!action->do_action)
   8749   1.1  christos 	continue;
   8750   1.6  christos       switch (action->action)
   8751   1.1  christos 	{
   8752   1.1  christos 	case ta_remove_insn:
   8753   1.1  christos 	case ta_remove_longcall:
   8754   1.1  christos 	case ta_convert_longcall:
   8755   1.1  christos 	case ta_narrow_insn:
   8756   1.1  christos 	case ta_widen_insn:
   8757   1.1  christos 	case ta_fill:
   8758   1.1  christos 	case ta_remove_literal:
   8759   1.1  christos 	  text_action_add (l, action->action, sec, action->offset,
   8760   1.1  christos 			   action->removed_bytes);
   8761   1.1  christos 	  break;
   8762   1.1  christos 	case ta_none:
   8763   1.1  christos 	  break;
   8764   1.1  christos 	default:
   8765   1.1  christos 	  BFD_ASSERT (0);
   8766   1.1  christos 	  break;
   8767   1.1  christos 	}
   8768   1.1  christos     }
   8769   1.1  christos }
   8770   1.1  christos 
   8771   1.1  christos 
   8772   1.1  christos int
   8773   1.1  christos xtensa_compute_fill_extra_space (property_table_entry *entry)
   8774   1.1  christos {
   8775   1.1  christos   int fill_extra_space;
   8776   1.1  christos 
   8777   1.1  christos   if (!entry)
   8778   1.1  christos     return 0;
   8779   1.1  christos 
   8780   1.1  christos   if ((entry->flags & XTENSA_PROP_UNREACHABLE) == 0)
   8781   1.1  christos     return 0;
   8782   1.1  christos 
   8783   1.8  christos   fill_extra_space = entry->size;
   8784   1.1  christos   if ((entry->flags & XTENSA_PROP_ALIGN) != 0)
   8785   1.1  christos     {
   8786   1.1  christos       /* Fill bytes for alignment:
   8787   1.1  christos 	 (2**n)-1 - (addr + (2**n)-1) & (2**n -1) */
   8788   1.1  christos       int pow = GET_XTENSA_PROP_ALIGNMENT (entry->flags);
   8789   1.1  christos       int nsm = (1 << pow) - 1;
   8790   1.1  christos       bfd_vma addr = entry->address + entry->size;
   8791   1.1  christos       bfd_vma align_fill = nsm - ((addr + nsm) & nsm);
   8792   1.1  christos       fill_extra_space += align_fill;
   8793   1.8  christos     }
   8794   1.1  christos   return fill_extra_space;
   8795   1.1  christos }
   8796   1.1  christos 
   8797   1.8  christos 
   8798   1.1  christos /* First relaxation pass.  */
   8800   1.1  christos 
   8801   1.1  christos /* If the section contains relaxable literals, check each literal to
   8802   1.1  christos    see if it has the same value as another literal that has already
   8803   1.1  christos    been seen, either in the current section or a previous one.  If so,
   8804   1.1  christos    add an entry to the per-section list of removed literals.  The
   8805   1.1  christos    actual changes are deferred until the next pass.  */
   8806   1.1  christos 
   8807   1.1  christos static bool
   8808   1.1  christos compute_removed_literals (bfd *abfd,
   8809   1.1  christos 			  asection *sec,
   8810   1.3  christos 			  struct bfd_link_info *link_info,
   8811   1.1  christos 			  value_map_hash_table *values)
   8812   1.1  christos {
   8813   1.1  christos   xtensa_relax_info *relax_info;
   8814   1.1  christos   bfd_byte *contents;
   8815   1.1  christos   Elf_Internal_Rela *internal_relocs;
   8816   1.1  christos   source_reloc *src_relocs, *rel;
   8817   1.8  christos   bool ok = true;
   8818   1.1  christos   property_table_entry *prop_table = NULL;
   8819   1.1  christos   int ptblsize;
   8820   1.1  christos   int i, prev_i;
   8821   1.1  christos   bool last_loc_is_prev = false;
   8822   1.1  christos   bfd_vma last_target_offset = 0;
   8823   1.1  christos   section_cache_t target_sec_cache;
   8824   1.1  christos   bfd_size_type sec_size;
   8825   1.1  christos 
   8826   1.1  christos   init_section_cache (&target_sec_cache);
   8827   1.1  christos 
   8828   1.1  christos   /* Do nothing if it is not a relaxable literal section.  */
   8829   1.8  christos   relax_info = get_xtensa_relax_info (sec);
   8830   1.1  christos   BFD_ASSERT (relax_info);
   8831   1.1  christos   if (!relax_info->is_relaxable_literal_section)
   8832   1.8  christos     return ok;
   8833   1.1  christos 
   8834   1.1  christos   internal_relocs = retrieve_internal_relocs (abfd, sec,
   8835   1.1  christos 					      link_info->keep_memory);
   8836   1.1  christos 
   8837   1.1  christos   sec_size = bfd_get_section_limit (abfd, sec);
   8838   1.1  christos   contents = retrieve_contents (abfd, sec, link_info->keep_memory);
   8839   1.1  christos   if (contents == NULL && sec_size != 0)
   8840   1.1  christos     {
   8841   1.1  christos       ok = false;
   8842   1.1  christos       goto error_return;
   8843   1.1  christos     }
   8844   1.1  christos 
   8845   1.1  christos   /* Sort the source_relocs by target offset.  */
   8846   1.1  christos   src_relocs = relax_info->src_relocs;
   8847   1.1  christos   qsort (src_relocs, relax_info->src_count,
   8848   1.1  christos 	 sizeof (source_reloc), source_reloc_compare);
   8849   1.1  christos   qsort (internal_relocs, sec->reloc_count, sizeof (Elf_Internal_Rela),
   8850   1.1  christos 	 internal_reloc_compare);
   8851   1.1  christos 
   8852   1.1  christos   ptblsize = xtensa_read_table_entries (abfd, sec, &prop_table,
   8853   1.1  christos 					XTENSA_PROP_SEC_NAME, false);
   8854   1.1  christos   if (ptblsize < 0)
   8855   1.1  christos     {
   8856   1.1  christos       ok = false;
   8857   1.1  christos       goto error_return;
   8858   1.1  christos     }
   8859   1.1  christos 
   8860   1.1  christos   prev_i = -1;
   8861   1.1  christos   for (i = 0; i < relax_info->src_count; i++)
   8862   1.3  christos     {
   8863   1.1  christos       Elf_Internal_Rela *irel = NULL;
   8864   1.8  christos 
   8865   1.1  christos       rel = &src_relocs[i];
   8866   1.1  christos       if (get_l32r_opcode () != rel->opcode)
   8867   1.1  christos 	continue;
   8868   1.1  christos       irel = get_irel_at_offset (sec, internal_relocs,
   8869   1.3  christos 				 rel->r_rel.target_offset);
   8870   1.1  christos 
   8871   1.1  christos       /* If the relocation on this is not a simple R_XTENSA_32 or
   8872   1.1  christos 	 R_XTENSA_PLT then do not consider it.  This may happen when
   8873   1.1  christos 	 the difference of two symbols is used in a literal.  */
   8874   1.1  christos       if (irel && (ELF32_R_TYPE (irel->r_info) != R_XTENSA_32
   8875   1.8  christos 		   && ELF32_R_TYPE (irel->r_info) != R_XTENSA_PLT))
   8876   1.1  christos 	continue;
   8877   1.1  christos 
   8878   1.1  christos       /* If the target_offset for this relocation is the same as the
   8879   1.1  christos 	 previous relocation, then we've already considered whether the
   8880   1.1  christos 	 literal can be coalesced.  Skip to the next one....  */
   8881   1.1  christos       if (i != 0 && prev_i != -1
   8882   1.1  christos 	  && src_relocs[i-1].r_rel.target_offset == rel->r_rel.target_offset)
   8883   1.3  christos 	continue;
   8884   1.3  christos       prev_i = i;
   8885   1.1  christos 
   8886   1.1  christos       if (last_loc_is_prev &&
   8887   1.1  christos 	  last_target_offset + 4 != rel->r_rel.target_offset)
   8888   1.1  christos 	last_loc_is_prev = false;
   8889   1.8  christos 
   8890   1.1  christos       /* Check if the relocation was from an L32R that is being removed
   8891   1.1  christos 	 because a CALLX was converted to a direct CALL, and check if
   8892   1.1  christos 	 there are no other relocations to the literal.  */
   8893   1.1  christos       if (is_removable_literal (rel, i, src_relocs, relax_info->src_count,
   8894   1.1  christos 				sec, prop_table, ptblsize))
   8895   1.1  christos 	{
   8896   1.1  christos 	  if (!remove_dead_literal (abfd, sec, link_info, internal_relocs,
   8897   1.1  christos 				    irel, rel, prop_table, ptblsize))
   8898   1.1  christos 	    {
   8899   1.1  christos 	      ok = false;
   8900   1.8  christos 	      goto error_return;
   8901   1.8  christos 	    }
   8902   1.3  christos 	  last_target_offset = rel->r_rel.target_offset;
   8903   1.1  christos 	  continue;
   8904   1.1  christos 	}
   8905   1.1  christos 
   8906   1.1  christos       if (!identify_literal_placement (abfd, sec, contents, link_info,
   8907   1.1  christos 				       values,
   8908   1.1  christos 				       &last_loc_is_prev, irel,
   8909   1.1  christos 				       relax_info->src_count - i, rel,
   8910   1.1  christos 				       prop_table, ptblsize,
   8911   1.1  christos 				       &target_sec_cache, rel->is_abs_literal))
   8912   1.1  christos 	{
   8913   1.1  christos 	  ok = false;
   8914   1.1  christos 	  goto error_return;
   8915   1.1  christos 	}
   8916   1.1  christos       last_target_offset = rel->r_rel.target_offset;
   8917   1.1  christos     }
   8918   1.1  christos 
   8919   1.1  christos #if DEBUG
   8920   1.3  christos   print_removed_literals (stderr, &relax_info->removed_list);
   8921   1.1  christos   print_action_list (stderr, &relax_info->action_list);
   8922   1.1  christos #endif /* DEBUG */
   8923   1.1  christos 
   8924   1.1  christos  error_return:
   8925   1.1  christos   free (prop_table);
   8926   1.1  christos   free_section_cache (&target_sec_cache);
   8927   1.1  christos 
   8928   1.1  christos   release_contents (sec, contents);
   8929   1.1  christos   release_internal_relocs (sec, internal_relocs);
   8930   1.1  christos   return ok;
   8931   1.1  christos }
   8932   1.1  christos 
   8933   1.1  christos 
   8934   1.1  christos static Elf_Internal_Rela *
   8935   1.1  christos get_irel_at_offset (asection *sec,
   8936   1.1  christos 		    Elf_Internal_Rela *internal_relocs,
   8937   1.1  christos 		    bfd_vma offset)
   8938   1.1  christos {
   8939   1.1  christos   unsigned i;
   8940   1.1  christos   Elf_Internal_Rela *irel;
   8941   1.1  christos   unsigned r_type;
   8942   1.1  christos   Elf_Internal_Rela key;
   8943   1.1  christos 
   8944   1.1  christos   if (!internal_relocs)
   8945   1.1  christos     return NULL;
   8946   1.1  christos 
   8947   1.1  christos   key.r_offset = offset;
   8948   1.1  christos   irel = bsearch (&key, internal_relocs, sec->reloc_count,
   8949   1.1  christos 		  sizeof (Elf_Internal_Rela), internal_reloc_matches);
   8950   1.8  christos   if (!irel)
   8951   1.1  christos     return NULL;
   8952   1.1  christos 
   8953   1.1  christos   /* bsearch does not guarantee which will be returned if there are
   8954   1.1  christos      multiple matches.  We need the first that is not an alignment.  */
   8955   1.1  christos   i = irel - internal_relocs;
   8956   1.1  christos   while (i > 0)
   8957   1.1  christos     {
   8958   1.1  christos       if (internal_relocs[i-1].r_offset != offset)
   8959   1.1  christos 	break;
   8960   1.1  christos       i--;
   8961   1.1  christos     }
   8962   1.1  christos   for ( ; i < sec->reloc_count; i++)
   8963   1.8  christos     {
   8964   1.3  christos       irel = &internal_relocs[i];
   8965   1.3  christos       r_type = ELF32_R_TYPE (irel->r_info);
   8966   1.1  christos       if (irel->r_offset == offset && r_type != R_XTENSA_NONE)
   8967   1.1  christos 	return irel;
   8968   1.8  christos     }
   8969   1.1  christos 
   8970   1.1  christos   return NULL;
   8971   1.1  christos }
   8972   1.1  christos 
   8973   1.1  christos 
   8974   1.1  christos bool
   8975   1.8  christos is_removable_literal (const source_reloc *rel,
   8976   1.1  christos 		      int i,
   8977   1.1  christos 		      const source_reloc *src_relocs,
   8978   1.1  christos 		      int src_count,
   8979   1.1  christos 		      asection *sec,
   8980   1.8  christos 		      property_table_entry *prop_table,
   8981   1.1  christos 		      int ptblsize)
   8982   1.8  christos {
   8983   1.1  christos   const source_reloc *curr_rel;
   8984   1.1  christos   property_table_entry *entry;
   8985   1.1  christos 
   8986   1.8  christos   if (!rel->is_null)
   8987   1.1  christos     return false;
   8988   1.1  christos 
   8989   1.1  christos   entry = elf_xtensa_find_property_entry (prop_table, ptblsize,
   8990   1.1  christos 					  sec->vma + rel->r_rel.target_offset);
   8991   1.1  christos   if (entry && (entry->flags & XTENSA_PROP_NO_TRANSFORM))
   8992   1.1  christos     return false;
   8993   1.1  christos 
   8994   1.1  christos   for (++i; i < src_count; ++i)
   8995   1.1  christos     {
   8996   1.1  christos       curr_rel = &src_relocs[i];
   8997   1.1  christos       /* If all others have the same target offset....  */
   8998   1.1  christos       if (curr_rel->r_rel.target_offset != rel->r_rel.target_offset)
   8999   1.1  christos 	return true;
   9000   1.1  christos 
   9001   1.8  christos       if (!curr_rel->is_null
   9002   1.1  christos 	  && !xtensa_is_property_section (curr_rel->source_sec)
   9003   1.1  christos 	  && !(curr_rel->source_sec->flags & SEC_DEBUGGING))
   9004   1.1  christos 	return false;
   9005   1.1  christos     }
   9006   1.1  christos   return true;
   9007   1.1  christos }
   9008   1.1  christos 
   9009   1.1  christos 
   9010   1.1  christos bool
   9011   1.1  christos remove_dead_literal (bfd *abfd,
   9012   1.1  christos 		     asection *sec,
   9013   1.3  christos 		     struct bfd_link_info *link_info,
   9014   1.1  christos 		     Elf_Internal_Rela *internal_relocs,
   9015   1.1  christos 		     Elf_Internal_Rela *irel,
   9016   1.1  christos 		     source_reloc *rel,
   9017   1.1  christos 		     property_table_entry *prop_table,
   9018   1.1  christos 		     int ptblsize)
   9019   1.1  christos {
   9020   1.1  christos   property_table_entry *entry;
   9021   1.1  christos   xtensa_relax_info *relax_info;
   9022   1.1  christos 
   9023   1.1  christos   relax_info = get_xtensa_relax_info (sec);
   9024   1.1  christos   if (!relax_info)
   9025   1.1  christos     return false;
   9026   1.1  christos 
   9027   1.1  christos   entry = elf_xtensa_find_property_entry (prop_table, ptblsize,
   9028   1.1  christos 					  sec->vma + rel->r_rel.target_offset);
   9029   1.1  christos 
   9030   1.6  christos   /* Mark the unused literal so that it will be removed.  */
   9031   1.1  christos   add_removed_literal (&relax_info->removed_list, &rel->r_rel, NULL);
   9032   1.1  christos 
   9033   1.1  christos   text_action_add (&relax_info->action_list,
   9034   1.1  christos 		   ta_remove_literal, sec, rel->r_rel.target_offset, 4);
   9035   1.1  christos 
   9036   1.1  christos   /* If the section is 4-byte aligned, do not add fill.  */
   9037   1.1  christos   if (sec->alignment_power > 2)
   9038   1.1  christos     {
   9039   1.1  christos       int fill_extra_space;
   9040   1.1  christos       bfd_vma entry_sec_offset;
   9041   1.1  christos       text_action *fa;
   9042   1.1  christos       property_table_entry *the_add_entry;
   9043   1.1  christos       int removed_diff;
   9044   1.1  christos 
   9045   1.1  christos       if (entry)
   9046   1.1  christos 	entry_sec_offset = entry->address - sec->vma + entry->size;
   9047   1.1  christos       else
   9048   1.1  christos 	entry_sec_offset = rel->r_rel.target_offset + 4;
   9049   1.1  christos 
   9050   1.1  christos       /* If the literal range is at the end of the section,
   9051   1.1  christos 	 do not add fill.  */
   9052   1.1  christos       the_add_entry = elf_xtensa_find_property_entry (prop_table, ptblsize,
   9053   1.8  christos 						      entry_sec_offset);
   9054   1.1  christos       fill_extra_space = xtensa_compute_fill_extra_space (the_add_entry);
   9055   1.1  christos 
   9056   1.1  christos       fa = find_fill_action (&relax_info->action_list, sec, entry_sec_offset);
   9057   1.8  christos       removed_diff = compute_removed_action_diff (fa, sec, entry_sec_offset,
   9058   1.1  christos 						  -4, fill_extra_space);
   9059   1.1  christos       if (fa)
   9060   1.1  christos 	adjust_fill_action (fa, removed_diff);
   9061   1.1  christos       else
   9062   1.1  christos 	text_action_add (&relax_info->action_list,
   9063   1.8  christos 			 ta_fill, sec, entry_sec_offset, removed_diff);
   9064   1.1  christos     }
   9065   1.1  christos 
   9066   1.1  christos   /* Zero out the relocation on this literal location.  */
   9067   1.1  christos   if (irel)
   9068   1.1  christos     {
   9069   1.1  christos       if (elf_hash_table (link_info)->dynamic_sections_created)
   9070   1.8  christos 	shrink_dynamic_reloc_sections (link_info, abfd, sec, irel);
   9071   1.1  christos 
   9072   1.1  christos       irel->r_info = ELF32_R_INFO (0, R_XTENSA_NONE);
   9073   1.1  christos       pin_internal_relocs (sec, internal_relocs);
   9074   1.1  christos     }
   9075   1.8  christos 
   9076   1.1  christos   /* Do not modify "last_loc_is_prev".  */
   9077   1.1  christos   return true;
   9078   1.8  christos }
   9079   1.1  christos 
   9080   1.1  christos 
   9081   1.1  christos bool
   9082   1.1  christos identify_literal_placement (bfd *abfd,
   9083   1.8  christos 			    asection *sec,
   9084   1.1  christos 			    bfd_byte *contents,
   9085   1.1  christos 			    struct bfd_link_info *link_info,
   9086   1.1  christos 			    value_map_hash_table *values,
   9087   1.1  christos 			    bool *last_loc_is_prev_p,
   9088   1.3  christos 			    Elf_Internal_Rela *irel,
   9089   1.1  christos 			    int remaining_src_rels,
   9090   1.1  christos 			    source_reloc *rel,
   9091   1.1  christos 			    property_table_entry *prop_table,
   9092   1.1  christos 			    int ptblsize,
   9093   1.1  christos 			    section_cache_t *target_sec_cache,
   9094   1.1  christos 			    bool is_abs_literal)
   9095   1.1  christos {
   9096   1.1  christos   literal_value val;
   9097   1.1  christos   value_map *val_map;
   9098   1.1  christos   xtensa_relax_info *relax_info;
   9099   1.1  christos   bool literal_placed = false;
   9100   1.1  christos   r_reloc r_rel;
   9101   1.1  christos   unsigned long value;
   9102   1.1  christos   bool final_static_link;
   9103   1.1  christos   bfd_size_type sec_size;
   9104   1.1  christos 
   9105   1.1  christos   relax_info = get_xtensa_relax_info (sec);
   9106   1.1  christos   if (!relax_info)
   9107   1.1  christos     return false;
   9108   1.1  christos 
   9109   1.1  christos   sec_size = bfd_get_section_limit (abfd, sec);
   9110   1.1  christos 
   9111   1.1  christos   final_static_link =
   9112   1.1  christos     (!bfd_link_relocatable (link_info)
   9113   1.1  christos      && !elf_hash_table (link_info)->dynamic_sections_created);
   9114   1.1  christos 
   9115   1.1  christos   /* The placement algorithm first checks to see if the literal is
   9116   1.1  christos      already in the value map.  If so and the value map is reachable
   9117   1.1  christos      from all uses, then the literal is moved to that location.  If
   9118   1.1  christos      not, then we identify the last location where a fresh literal was
   9119   1.1  christos      placed.  If the literal can be safely moved there, then we do so.
   9120   1.1  christos      If not, then we assume that the literal is not to move and leave
   9121   1.8  christos      the literal where it is, marking it as the last literal
   9122   1.1  christos      location.  */
   9123   1.1  christos 
   9124   1.1  christos   /* Find the literal value.  */
   9125   1.1  christos   value = 0;
   9126   1.1  christos   r_reloc_init (&r_rel, abfd, irel, contents, sec_size);
   9127   1.3  christos   if (!irel)
   9128   1.1  christos     {
   9129   1.1  christos       BFD_ASSERT (rel->r_rel.target_offset < sec_size);
   9130   1.1  christos       value = bfd_get_32 (abfd, contents + rel->r_rel.target_offset);
   9131   1.1  christos     }
   9132   1.1  christos   init_literal_value (&val, &r_rel, value, is_abs_literal);
   9133   1.1  christos 
   9134   1.1  christos   /* Check if we've seen another literal with the same value that
   9135   1.1  christos      is in the same output section.  */
   9136   1.1  christos   val_map = value_map_get_cached_value (values, &val, final_static_link);
   9137   1.1  christos 
   9138   1.1  christos   if (val_map
   9139   1.1  christos       && (r_reloc_get_section (&val_map->loc)->output_section
   9140   1.3  christos 	  == sec->output_section)
   9141   1.1  christos       && relocations_reach (rel, remaining_src_rels, &val_map->loc)
   9142   1.1  christos       && coalesce_shared_literal (sec, rel, prop_table, ptblsize, val_map))
   9143   1.1  christos     {
   9144   1.8  christos       /* No change to last_loc_is_prev.  */
   9145   1.1  christos       literal_placed = true;
   9146   1.1  christos     }
   9147   1.1  christos 
   9148   1.1  christos   /* For relocatable links, do not try to move literals.  To do it
   9149   1.1  christos      correctly might increase the number of relocations in an input
   9150   1.1  christos      section making the default relocatable linking fail.  */
   9151   1.1  christos   if (!bfd_link_relocatable (link_info) && !literal_placed
   9152   1.1  christos       && values->has_last_loc && !(*last_loc_is_prev_p))
   9153   1.1  christos     {
   9154   1.1  christos       asection *target_sec = r_reloc_get_section (&values->last_loc);
   9155   1.1  christos       if (target_sec && target_sec->output_section == sec->output_section)
   9156   1.1  christos 	{
   9157   1.8  christos 	  /* Increment the virtual offset.  */
   9158   1.1  christos 	  r_reloc try_loc = values->last_loc;
   9159   1.1  christos 	  try_loc.virtual_offset += 4;
   9160   1.1  christos 
   9161   1.1  christos 	  /* There is a last loc that was in the same output section.  */
   9162   1.1  christos 	  if (relocations_reach (rel, remaining_src_rels, &try_loc)
   9163   1.8  christos 	      && move_shared_literal (sec, link_info, rel,
   9164   1.1  christos 				      prop_table, ptblsize,
   9165   1.1  christos 				      &try_loc, &val, target_sec_cache))
   9166   1.8  christos 	    {
   9167   1.1  christos 	      values->last_loc.virtual_offset += 4;
   9168   1.1  christos 	      literal_placed = true;
   9169   1.1  christos 	      if (!val_map)
   9170   1.1  christos 		val_map = add_value_map (values, &val, &try_loc,
   9171   1.1  christos 					 final_static_link);
   9172   1.1  christos 	      else
   9173   1.1  christos 		val_map->loc = try_loc;
   9174   1.1  christos 	    }
   9175   1.1  christos 	}
   9176   1.1  christos     }
   9177   1.1  christos 
   9178   1.1  christos   if (!literal_placed)
   9179   1.1  christos     {
   9180   1.1  christos       /* Nothing worked, leave the literal alone but update the last loc.  */
   9181   1.8  christos       values->has_last_loc = true;
   9182   1.1  christos       values->last_loc = rel->r_rel;
   9183   1.1  christos       if (!val_map)
   9184   1.1  christos 	val_map = add_value_map (values, &val, &rel->r_rel, final_static_link);
   9185   1.1  christos       else
   9186   1.1  christos 	val_map->loc = rel->r_rel;
   9187   1.1  christos       *last_loc_is_prev_p = true;
   9188   1.1  christos     }
   9189   1.1  christos 
   9190   1.1  christos   return true;
   9191   1.8  christos }
   9192   1.1  christos 
   9193   1.1  christos 
   9194   1.1  christos /* Check if the original relocations (presumably on L32R instructions)
   9195   1.1  christos    identified by reloc[0..N] can be changed to reference the literal
   9196   1.1  christos    identified by r_rel.  If r_rel is out of range for any of the
   9197   1.1  christos    original relocations, then we don't want to coalesce the original
   9198   1.1  christos    literal with the one at r_rel.  We only check reloc[0..N], where the
   9199   1.1  christos    offsets are all the same as for reloc[0] (i.e., they're all
   9200   1.1  christos    referencing the same literal) and where N is also bounded by the
   9201   1.1  christos    number of remaining entries in the "reloc" array.  The "reloc" array
   9202   1.1  christos    is sorted by target offset so we know all the entries for the same
   9203   1.1  christos    literal will be contiguous.  */
   9204   1.1  christos 
   9205   1.1  christos static bool
   9206   1.6  christos relocations_reach (source_reloc *reloc,
   9207   1.1  christos 		   int remaining_relocs,
   9208   1.1  christos 		   const r_reloc *r_rel)
   9209   1.8  christos {
   9210   1.1  christos   bfd_vma from_offset, source_address, dest_address;
   9211   1.1  christos   asection *sec;
   9212   1.1  christos   int i;
   9213   1.1  christos 
   9214   1.1  christos   if (!r_reloc_is_defined (r_rel))
   9215   1.1  christos     return false;
   9216   1.1  christos 
   9217   1.1  christos   sec = r_reloc_get_section (r_rel);
   9218   1.1  christos   from_offset = reloc[0].r_rel.target_offset;
   9219   1.1  christos 
   9220   1.1  christos   for (i = 0; i < remaining_relocs; i++)
   9221   1.1  christos     {
   9222   1.1  christos       if (reloc[i].r_rel.target_offset != from_offset)
   9223   1.1  christos 	break;
   9224   1.1  christos 
   9225   1.1  christos       /* Ignore relocations that have been removed.  */
   9226   1.1  christos       if (reloc[i].is_null)
   9227   1.1  christos 	continue;
   9228   1.1  christos 
   9229   1.8  christos       /* The original and new output section for these must be the same
   9230   1.1  christos 	 in order to coalesce.  */
   9231   1.1  christos       if (r_reloc_get_section (&reloc[i].r_rel)->output_section
   9232   1.1  christos 	  != sec->output_section)
   9233   1.8  christos 	return false;
   9234   1.1  christos 
   9235   1.1  christos       /* Absolute literals in the same output section can always be
   9236   1.1  christos 	 combined.  */
   9237   1.1  christos       if (reloc[i].is_abs_literal)
   9238   1.1  christos 	continue;
   9239   1.1  christos 
   9240   1.8  christos       /* A literal with no PC-relative relocations can be moved anywhere.  */
   9241   1.1  christos       if (reloc[i].opnd != -1)
   9242   1.1  christos 	{
   9243   1.1  christos 	  /* Otherwise, check to see that it fits.  */
   9244   1.1  christos 	  source_address = (reloc[i].source_sec->output_section->vma
   9245   1.1  christos 			    + reloc[i].source_sec->output_offset
   9246   1.1  christos 			    + reloc[i].r_rel.rela.r_offset);
   9247   1.1  christos 	  dest_address = (sec->output_section->vma
   9248   1.1  christos 			  + sec->output_offset
   9249   1.1  christos 			  + r_rel->target_offset);
   9250   1.1  christos 
   9251   1.1  christos 	  if (!pcrel_reloc_fits (reloc[i].opcode, reloc[i].opnd,
   9252   1.1  christos 				 source_address, dest_address))
   9253   1.1  christos 	    return false;
   9254   1.1  christos 	}
   9255   1.8  christos     }
   9256   1.1  christos 
   9257   1.1  christos   return true;
   9258   1.1  christos }
   9259   1.1  christos 
   9260   1.8  christos 
   9261   1.1  christos /* Move a literal to another literal location because it is
   9262   1.1  christos    the same as the other literal value.  */
   9263   1.1  christos 
   9264   1.1  christos static bool
   9265   1.1  christos coalesce_shared_literal (asection *sec,
   9266   1.1  christos 			 source_reloc *rel,
   9267   1.1  christos 			 property_table_entry *prop_table,
   9268   1.1  christos 			 int ptblsize,
   9269   1.3  christos 			 value_map *val_map)
   9270   1.1  christos {
   9271   1.1  christos   property_table_entry *entry;
   9272   1.1  christos   text_action *fa;
   9273   1.1  christos   property_table_entry *the_add_entry;
   9274   1.1  christos   int removed_diff;
   9275   1.1  christos   xtensa_relax_info *relax_info;
   9276   1.1  christos 
   9277   1.1  christos   relax_info = get_xtensa_relax_info (sec);
   9278   1.1  christos   if (!relax_info)
   9279   1.1  christos     return false;
   9280   1.1  christos 
   9281   1.1  christos   entry = elf_xtensa_find_property_entry
   9282   1.1  christos     (prop_table, ptblsize, sec->vma + rel->r_rel.target_offset);
   9283   1.1  christos   if (entry && (entry->flags & XTENSA_PROP_NO_TRANSFORM))
   9284   1.1  christos     return true;
   9285   1.1  christos 
   9286   1.1  christos   /* Mark that the literal will be coalesced.  */
   9287   1.1  christos   add_removed_literal (&relax_info->removed_list, &rel->r_rel, &val_map->loc);
   9288   1.1  christos 
   9289   1.1  christos   text_action_add (&relax_info->action_list,
   9290   1.1  christos 		   ta_remove_literal, sec, rel->r_rel.target_offset, 4);
   9291   1.1  christos 
   9292   1.1  christos   /* If the section is 4-byte aligned, do not add fill.  */
   9293   1.1  christos   if (sec->alignment_power > 2)
   9294   1.1  christos     {
   9295   1.1  christos       int fill_extra_space;
   9296   1.1  christos       bfd_vma entry_sec_offset;
   9297   1.8  christos 
   9298   1.1  christos       if (entry)
   9299   1.1  christos 	entry_sec_offset = entry->address - sec->vma + entry->size;
   9300   1.1  christos       else
   9301   1.1  christos 	entry_sec_offset = rel->r_rel.target_offset + 4;
   9302   1.1  christos 
   9303   1.1  christos       /* If the literal range is at the end of the section,
   9304   1.1  christos 	 do not add fill.  */
   9305   1.8  christos       fill_extra_space = 0;
   9306   1.1  christos       the_add_entry = elf_xtensa_find_property_entry (prop_table, ptblsize,
   9307   1.1  christos 						      entry_sec_offset);
   9308   1.1  christos       if (the_add_entry && (the_add_entry->flags & XTENSA_PROP_UNREACHABLE))
   9309   1.1  christos 	fill_extra_space = the_add_entry->size;
   9310   1.1  christos 
   9311   1.1  christos       fa = find_fill_action (&relax_info->action_list, sec, entry_sec_offset);
   9312   1.1  christos       removed_diff = compute_removed_action_diff (fa, sec, entry_sec_offset,
   9313   1.1  christos 						  -4, fill_extra_space);
   9314   1.1  christos       if (fa)
   9315   1.1  christos 	adjust_fill_action (fa, removed_diff);
   9316   1.1  christos       else
   9317   1.1  christos 	text_action_add (&relax_info->action_list,
   9318   1.1  christos 			 ta_fill, sec, entry_sec_offset, removed_diff);
   9319   1.1  christos     }
   9320   1.1  christos 
   9321   1.1  christos   return true;
   9322   1.8  christos }
   9323   1.1  christos 
   9324   1.1  christos 
   9325   1.1  christos /* Move a literal to another location.  This may actually increase the
   9326   1.1  christos    total amount of space used because of alignments so we need to do
   9327   1.8  christos    this carefully.  Also, it may make a branch go out of range.  */
   9328   1.1  christos 
   9329   1.1  christos static bool
   9330   1.1  christos move_shared_literal (asection *sec,
   9331   1.8  christos 		     struct bfd_link_info *link_info,
   9332   1.1  christos 		     source_reloc *rel,
   9333   1.1  christos 		     property_table_entry *prop_table,
   9334   1.1  christos 		     int ptblsize,
   9335   1.1  christos 		     const r_reloc *target_loc,
   9336   1.1  christos 		     const literal_value *lit_value,
   9337   1.1  christos 		     section_cache_t *target_sec_cache)
   9338   1.1  christos {
   9339   1.8  christos   property_table_entry *the_add_entry, *src_entry, *target_entry = NULL;
   9340   1.1  christos   text_action *fa, *target_fa;
   9341   1.1  christos   int removed_diff;
   9342   1.1  christos   xtensa_relax_info *relax_info, *target_relax_info;
   9343   1.1  christos   asection *target_sec;
   9344   1.1  christos   ebb_t *ebb;
   9345   1.8  christos   ebb_constraint ebb_table;
   9346   1.1  christos   bool relocs_fit;
   9347   1.1  christos 
   9348   1.3  christos   /* If this routine always returns FALSE, the literals that cannot be
   9349   1.1  christos      coalesced will not be moved.  */
   9350   1.1  christos   if (elf32xtensa_no_literal_movement)
   9351   1.1  christos     return false;
   9352   1.8  christos 
   9353   1.1  christos   relax_info = get_xtensa_relax_info (sec);
   9354   1.1  christos   if (!relax_info)
   9355   1.8  christos     return false;
   9356   1.1  christos 
   9357   1.1  christos   target_sec = r_reloc_get_section (target_loc);
   9358   1.1  christos   target_relax_info = get_xtensa_relax_info (target_sec);
   9359   1.3  christos 
   9360   1.1  christos   /* Literals to undefined sections may not be moved because they
   9361   1.1  christos      must report an error.  */
   9362   1.1  christos   if (bfd_is_und_section (target_sec))
   9363   1.1  christos     return false;
   9364   1.1  christos 
   9365   1.1  christos   src_entry = elf_xtensa_find_property_entry
   9366   1.1  christos     (prop_table, ptblsize, sec->vma + rel->r_rel.target_offset);
   9367   1.1  christos 
   9368   1.8  christos   if (!section_cache_section (target_sec_cache, target_sec, link_info))
   9369   1.1  christos     return false;
   9370   1.1  christos 
   9371   1.3  christos   target_entry = elf_xtensa_find_property_entry
   9372   1.1  christos     (target_sec_cache->ptbl, target_sec_cache->pte_count,
   9373   1.3  christos      target_sec->vma + target_loc->target_offset);
   9374   1.1  christos 
   9375   1.1  christos   if (!target_entry)
   9376   1.3  christos     return false;
   9377   1.8  christos 
   9378   1.1  christos   /* Make sure that we have not broken any branches.  */
   9379   1.1  christos   relocs_fit = false;
   9380   1.1  christos 
   9381   1.1  christos   init_ebb_constraint (&ebb_table);
   9382   1.3  christos   ebb = &ebb_table.ebb;
   9383   1.1  christos   init_ebb (ebb, target_sec_cache->sec, target_sec_cache->contents,
   9384   1.1  christos 	    target_sec_cache->content_length,
   9385   1.1  christos 	    target_sec_cache->ptbl, target_sec_cache->pte_count,
   9386   1.1  christos 	    target_sec_cache->relocs, target_sec_cache->reloc_count);
   9387   1.1  christos 
   9388   1.3  christos   /* Propose to add 4 bytes + worst-case alignment size increase to
   9389   1.1  christos      destination.  */
   9390   1.1  christos   ebb_propose_action (&ebb_table, EBB_NO_ALIGN, 0,
   9391   1.1  christos 		      ta_fill, target_loc->target_offset,
   9392   1.1  christos 		      -4 - (1 << target_sec->alignment_power), true);
   9393   1.1  christos 
   9394   1.1  christos   /* Check all of the PC-relative relocations to make sure they still fit.  */
   9395   1.1  christos   relocs_fit = check_section_ebb_pcrels_fit (target_sec->owner, target_sec,
   9396   1.1  christos 					     target_sec_cache->contents,
   9397   1.1  christos 					     target_sec_cache->relocs, NULL,
   9398   1.1  christos 					     &ebb_table, NULL);
   9399   1.1  christos 
   9400   1.1  christos   if (!relocs_fit)
   9401   1.1  christos     return false;
   9402   1.1  christos 
   9403   1.1  christos   text_action_add_literal (&target_relax_info->action_list,
   9404   1.1  christos 			   ta_add_literal, target_loc, lit_value, -4);
   9405   1.1  christos 
   9406   1.1  christos   if (target_sec->alignment_power > 2 && target_entry != src_entry)
   9407   1.1  christos     {
   9408   1.1  christos       /* May need to add or remove some fill to maintain alignment.  */
   9409   1.1  christos       int fill_extra_space;
   9410   1.1  christos       bfd_vma entry_sec_offset;
   9411   1.1  christos 
   9412   1.1  christos       entry_sec_offset =
   9413   1.1  christos 	target_entry->address - target_sec->vma + target_entry->size;
   9414   1.1  christos 
   9415   1.1  christos       /* If the literal range is at the end of the section,
   9416   1.1  christos 	 do not add fill.  */
   9417   1.1  christos       fill_extra_space = 0;
   9418   1.1  christos       the_add_entry =
   9419   1.1  christos 	elf_xtensa_find_property_entry (target_sec_cache->ptbl,
   9420   1.1  christos 					target_sec_cache->pte_count,
   9421   1.3  christos 					entry_sec_offset);
   9422   1.1  christos       if (the_add_entry && (the_add_entry->flags & XTENSA_PROP_UNREACHABLE))
   9423   1.1  christos 	fill_extra_space = the_add_entry->size;
   9424   1.1  christos 
   9425   1.1  christos       target_fa = find_fill_action (&target_relax_info->action_list,
   9426   1.1  christos 				    target_sec, entry_sec_offset);
   9427   1.1  christos       removed_diff = compute_removed_action_diff (target_fa, target_sec,
   9428   1.1  christos 						  entry_sec_offset, 4,
   9429   1.1  christos 						  fill_extra_space);
   9430   1.1  christos       if (target_fa)
   9431   1.1  christos 	adjust_fill_action (target_fa, removed_diff);
   9432   1.1  christos       else
   9433   1.1  christos 	text_action_add (&target_relax_info->action_list,
   9434   1.1  christos 			 ta_fill, target_sec, entry_sec_offset, removed_diff);
   9435   1.1  christos     }
   9436   1.1  christos 
   9437   1.1  christos   /* Mark that the literal will be moved to the new location.  */
   9438   1.1  christos   add_removed_literal (&relax_info->removed_list, &rel->r_rel, target_loc);
   9439   1.1  christos 
   9440   1.1  christos   /* Remove the literal.  */
   9441   1.1  christos   text_action_add (&relax_info->action_list,
   9442   1.1  christos 		   ta_remove_literal, sec, rel->r_rel.target_offset, 4);
   9443   1.1  christos 
   9444   1.1  christos   /* If the section is 4-byte aligned, do not add fill.  */
   9445   1.1  christos   if (sec->alignment_power > 2 && target_entry != src_entry)
   9446   1.1  christos     {
   9447   1.1  christos       int fill_extra_space;
   9448   1.1  christos       bfd_vma entry_sec_offset;
   9449   1.8  christos 
   9450   1.1  christos       if (src_entry)
   9451   1.1  christos 	entry_sec_offset = src_entry->address - sec->vma + src_entry->size;
   9452   1.1  christos       else
   9453   1.1  christos 	entry_sec_offset = rel->r_rel.target_offset+4;
   9454   1.1  christos 
   9455   1.3  christos       /* If the literal range is at the end of the section,
   9456   1.3  christos 	 do not add fill.  */
   9457   1.3  christos       fill_extra_space = 0;
   9458   1.3  christos       the_add_entry = elf_xtensa_find_property_entry (prop_table, ptblsize,
   9459   1.3  christos 						      entry_sec_offset);
   9460   1.3  christos       if (the_add_entry && (the_add_entry->flags & XTENSA_PROP_UNREACHABLE))
   9461   1.3  christos 	fill_extra_space = the_add_entry->size;
   9462   1.3  christos 
   9463   1.3  christos       fa = find_fill_action (&relax_info->action_list, sec, entry_sec_offset);
   9464   1.3  christos       removed_diff = compute_removed_action_diff (fa, sec, entry_sec_offset,
   9465   1.1  christos 						  -4, fill_extra_space);
   9466   1.1  christos       if (fa)
   9467   1.1  christos 	adjust_fill_action (fa, removed_diff);
   9468   1.1  christos       else
   9469   1.8  christos 	text_action_add (&relax_info->action_list,
   9470   1.1  christos 			 ta_fill, sec, entry_sec_offset, removed_diff);
   9471   1.1  christos     }
   9472   1.1  christos 
   9473   1.1  christos   return true;
   9474   1.1  christos }
   9475   1.8  christos 
   9476   1.1  christos 
   9477   1.8  christos /* Second relaxation pass.  */
   9479   1.1  christos 
   9480   1.1  christos static int
   9481   1.1  christos action_remove_bytes_fn (splay_tree_node node, void *p)
   9482   1.1  christos {
   9483   1.1  christos   bfd_size_type *final_size = p;
   9484   1.1  christos   text_action *action = (text_action *)node->value;
   9485   1.1  christos 
   9486   1.1  christos   *final_size -= action->removed_bytes;
   9487   1.1  christos   return 0;
   9488   1.1  christos }
   9489   1.1  christos 
   9490   1.1  christos /* Modify all of the relocations to point to the right spot, and if this
   9491   1.1  christos    is a relaxable section, delete the unwanted literals and fix the
   9492   1.1  christos    section size.  */
   9493   1.1  christos 
   9494   1.1  christos bool
   9495   1.3  christos relax_section (bfd *abfd, asection *sec, struct bfd_link_info *link_info)
   9496   1.1  christos {
   9497   1.3  christos   Elf_Internal_Rela *internal_relocs;
   9498   1.8  christos   xtensa_relax_info *relax_info;
   9499   1.1  christos   bfd_byte *contents;
   9500   1.1  christos   bool ok = true;
   9501   1.1  christos   unsigned i;
   9502   1.1  christos   bool rv = false;
   9503   1.8  christos   bool virtual_action;
   9504   1.1  christos   bfd_size_type sec_size;
   9505   1.1  christos 
   9506   1.1  christos   sec_size = bfd_get_section_limit (abfd, sec);
   9507   1.1  christos   relax_info = get_xtensa_relax_info (sec);
   9508   1.1  christos   BFD_ASSERT (relax_info);
   9509   1.1  christos 
   9510   1.1  christos   /* First translate any of the fixes that have been added already.  */
   9511   1.1  christos   translate_section_fixes (sec);
   9512   1.1  christos 
   9513   1.1  christos   /* Handle property sections (e.g., literal tables) specially.  */
   9514   1.1  christos   if (xtensa_is_property_section (sec))
   9515   1.1  christos     {
   9516   1.1  christos       BFD_ASSERT (!relax_info->is_relaxable_literal_section);
   9517   1.1  christos       return relax_property_section (abfd, sec, link_info);
   9518   1.1  christos     }
   9519   1.1  christos 
   9520   1.1  christos   internal_relocs = retrieve_internal_relocs (abfd, sec,
   9521   1.1  christos 					      link_info->keep_memory);
   9522   1.1  christos   if (!internal_relocs && !action_list_count (&relax_info->action_list))
   9523   1.1  christos     return true;
   9524   1.1  christos 
   9525   1.1  christos   contents = retrieve_contents (abfd, sec, link_info->keep_memory);
   9526   1.1  christos   if (contents == NULL && sec_size != 0)
   9527   1.1  christos     {
   9528   1.1  christos       ok = false;
   9529   1.1  christos       goto error_return;
   9530   1.1  christos     }
   9531   1.1  christos 
   9532   1.1  christos   if (internal_relocs)
   9533   1.1  christos     {
   9534   1.1  christos       for (i = 0; i < sec->reloc_count; i++)
   9535   1.1  christos 	{
   9536   1.1  christos 	  Elf_Internal_Rela *irel;
   9537   1.1  christos 	  xtensa_relax_info *target_relax_info;
   9538   1.1  christos 	  bfd_vma source_offset, old_source_offset;
   9539   1.1  christos 	  r_reloc r_rel;
   9540   1.1  christos 	  unsigned r_type;
   9541   1.1  christos 	  asection *target_sec;
   9542   1.1  christos 
   9543   1.1  christos 	  /* Locally change the source address.
   9544   1.1  christos 	     Translate the target to the new target address.
   9545   1.1  christos 	     If it points to this section and has been removed,
   9546   1.1  christos 	     NULLify it.
   9547   1.1  christos 	     Write it back.  */
   9548   1.3  christos 
   9549   1.1  christos 	  irel = &internal_relocs[i];
   9550   1.1  christos 	  source_offset = irel->r_offset;
   9551   1.1  christos 	  old_source_offset = source_offset;
   9552   1.1  christos 
   9553   1.1  christos 	  r_type = ELF32_R_TYPE (irel->r_info);
   9554   1.1  christos 	  r_reloc_init (&r_rel, abfd, irel, contents,
   9555   1.1  christos 			bfd_get_section_limit (abfd, sec));
   9556   1.1  christos 
   9557   1.1  christos 	  /* If this section could have changed then we may need to
   9558   1.1  christos 	     change the relocation's offset.  */
   9559   1.1  christos 
   9560   1.1  christos 	  if (relax_info->is_relaxable_literal_section
   9561   1.1  christos 	      || relax_info->is_relaxable_asm_section)
   9562   1.1  christos 	    {
   9563   1.1  christos 	      pin_internal_relocs (sec, internal_relocs);
   9564   1.1  christos 
   9565   1.1  christos 	      if (r_type != R_XTENSA_NONE
   9566   1.1  christos 		  && find_removed_literal (&relax_info->removed_list,
   9567   1.1  christos 					   irel->r_offset))
   9568   1.1  christos 		{
   9569   1.1  christos 		  /* Remove this relocation.  */
   9570   1.1  christos 		  if (elf_hash_table (link_info)->dynamic_sections_created)
   9571   1.1  christos 		    shrink_dynamic_reloc_sections (link_info, abfd, sec, irel);
   9572   1.1  christos 		  irel->r_info = ELF32_R_INFO (0, R_XTENSA_NONE);
   9573   1.1  christos 		  irel->r_offset = offset_with_removed_text_map
   9574   1.1  christos 		    (&relax_info->action_list, irel->r_offset);
   9575   1.3  christos 		  continue;
   9576   1.6  christos 		}
   9577   1.3  christos 
   9578   1.3  christos 	      if (r_type == R_XTENSA_ASM_SIMPLIFY)
   9579   1.3  christos 		{
   9580   1.3  christos 		  text_action *action =
   9581   1.1  christos 		    find_insn_action (&relax_info->action_list,
   9582   1.1  christos 				      irel->r_offset);
   9583   1.1  christos 		  if (action && (action->action == ta_convert_longcall
   9584   1.1  christos 				 || action->action == ta_remove_longcall))
   9585   1.1  christos 		    {
   9586   1.1  christos 		      bfd_reloc_status_type retval;
   9587   1.1  christos 		      char *error_message = NULL;
   9588   1.1  christos 
   9589   1.1  christos 		      retval = contract_asm_expansion (contents, sec_size,
   9590   1.1  christos 						       irel, &error_message);
   9591   1.3  christos 		      if (retval != bfd_reloc_ok)
   9592   1.1  christos 			{
   9593   1.1  christos 			  (*link_info->callbacks->reloc_dangerous)
   9594   1.1  christos 			    (link_info, error_message, abfd, sec,
   9595   1.1  christos 			     irel->r_offset);
   9596   1.1  christos 			  goto error_return;
   9597   1.1  christos 			}
   9598   1.1  christos 		      /* Update the action so that the code that moves
   9599   1.1  christos 			 the contents will do the right thing.  */
   9600   1.1  christos 		      /* ta_remove_longcall and ta_remove_insn actions are
   9601   1.1  christos 			 grouped together in the tree as well as
   9602   1.1  christos 			 ta_convert_longcall and ta_none, so that changes below
   9603   1.1  christos 			 can be done w/o removing and reinserting action into
   9604   1.1  christos 			 the tree.  */
   9605   1.1  christos 
   9606   1.1  christos 		      if (action->action == ta_remove_longcall)
   9607   1.1  christos 			action->action = ta_remove_insn;
   9608   1.1  christos 		      else
   9609   1.1  christos 			action->action = ta_none;
   9610   1.1  christos 		      /* Refresh the info in the r_rel.  */
   9611   1.1  christos 		      r_reloc_init (&r_rel, abfd, irel, contents, sec_size);
   9612   1.1  christos 		      r_type = ELF32_R_TYPE (irel->r_info);
   9613   1.1  christos 		    }
   9614   1.1  christos 		}
   9615   1.1  christos 
   9616   1.1  christos 	      source_offset = offset_with_removed_text_map
   9617   1.1  christos 		(&relax_info->action_list, irel->r_offset);
   9618   1.1  christos 	      irel->r_offset = source_offset;
   9619   1.1  christos 	    }
   9620   1.1  christos 
   9621   1.1  christos 	  /* If the target section could have changed then
   9622   1.1  christos 	     we may need to change the relocation's target offset.  */
   9623   1.1  christos 
   9624   1.1  christos 	  target_sec = r_reloc_get_section (&r_rel);
   9625   1.1  christos 
   9626   1.1  christos 	  /* For a reference to a discarded section from a DWARF section,
   9627   1.1  christos 	     i.e., where action_discarded is PRETEND, the symbol will
   9628   1.1  christos 	     eventually be modified to refer to the kept section (at least if
   9629   1.1  christos 	     the kept and discarded sections are the same size).  Anticipate
   9630   1.1  christos 	     that here and adjust things accordingly.  */
   9631   1.1  christos 	  if (! elf_xtensa_ignore_discarded_relocs (sec)
   9632   1.1  christos 	      && elf_xtensa_action_discarded (sec) == PRETEND
   9633   1.1  christos 	      && sec->sec_info_type != SEC_INFO_TYPE_STABS
   9634   1.1  christos 	      && target_sec != NULL
   9635   1.1  christos 	      && discarded_section (target_sec))
   9636   1.1  christos 	    {
   9637   1.1  christos 	      /* It would be natural to call _bfd_elf_check_kept_section
   9638   1.1  christos 		 here, but it's not exported from elflink.c.  It's also a
   9639   1.1  christos 		 fairly expensive check.  Adjusting the relocations to the
   9640   1.1  christos 		 discarded section is fairly harmless; it will only adjust
   9641   1.1  christos 		 some addends and difference values.  If it turns out that
   9642   1.1  christos 		 _bfd_elf_check_kept_section fails later, it won't matter,
   9643   1.1  christos 		 so just compare the section names to find the right group
   9644   1.1  christos 		 member.  */
   9645   1.1  christos 	      asection *kept = target_sec->kept_section;
   9646   1.1  christos 	      if (kept != NULL)
   9647   1.1  christos 		{
   9648   1.1  christos 		  if ((kept->flags & SEC_GROUP) != 0)
   9649   1.1  christos 		    {
   9650   1.1  christos 		      asection *first = elf_next_in_group (kept);
   9651   1.1  christos 		      asection *s = first;
   9652   1.1  christos 
   9653   1.1  christos 		      kept = NULL;
   9654   1.1  christos 		      while (s != NULL)
   9655   1.1  christos 			{
   9656   1.1  christos 			  if (strcmp (s->name, target_sec->name) == 0)
   9657   1.1  christos 			    {
   9658   1.1  christos 			      kept = s;
   9659   1.8  christos 			      break;
   9660   1.8  christos 			    }
   9661   1.8  christos 			  s = elf_next_in_group (s);
   9662   1.8  christos 			  if (s == first)
   9663   1.8  christos 			    break;
   9664   1.8  christos 			}
   9665   1.8  christos 		    }
   9666   1.1  christos 		}
   9667   1.3  christos 	      if (kept != NULL
   9668   1.3  christos 		  && ((target_sec->rawsize != 0
   9669   1.1  christos 		       ? target_sec->rawsize : target_sec->size)
   9670   1.1  christos 		      == (kept->rawsize != 0 ? kept->rawsize : kept->size)))
   9671   1.1  christos 		target_sec = kept;
   9672   1.1  christos 	    }
   9673   1.1  christos 
   9674   1.1  christos 	  target_relax_info = get_xtensa_relax_info (target_sec);
   9675   1.1  christos 	  if (target_relax_info
   9676   1.1  christos 	      && (target_relax_info->is_relaxable_literal_section
   9677   1.1  christos 		  || target_relax_info->is_relaxable_asm_section))
   9678   1.1  christos 	    {
   9679   1.1  christos 	      r_reloc new_reloc;
   9680   1.1  christos 	      target_sec = translate_reloc (&r_rel, &new_reloc, target_sec);
   9681   1.8  christos 
   9682   1.1  christos 	      if (r_type == R_XTENSA_DIFF8
   9683   1.3  christos 		  || r_type == R_XTENSA_DIFF16
   9684   1.1  christos 		  || r_type == R_XTENSA_DIFF32
   9685   1.1  christos 		  || r_type == R_XTENSA_PDIFF8
   9686   1.8  christos 		  || r_type == R_XTENSA_PDIFF16
   9687   1.1  christos 		  || r_type == R_XTENSA_PDIFF32
   9688   1.3  christos 		  || r_type == R_XTENSA_NDIFF8
   9689   1.1  christos 		  || r_type == R_XTENSA_NDIFF16
   9690   1.1  christos 		  || r_type == R_XTENSA_NDIFF32)
   9691   1.8  christos 		{
   9692   1.1  christos 		  bfd_signed_vma diff_value = 0;
   9693   1.3  christos 		  bfd_vma new_end_offset, diff_mask = 0;
   9694   1.1  christos 
   9695   1.8  christos 		  if (bfd_get_section_limit (abfd, sec) < old_source_offset)
   9696   1.8  christos 		    {
   9697   1.8  christos 		      (*link_info->callbacks->reloc_dangerous)
   9698   1.8  christos 			(link_info, _("invalid relocation address"),
   9699   1.8  christos 			 abfd, sec, old_source_offset);
   9700   1.8  christos 		      goto error_return;
   9701   1.8  christos 		    }
   9702   1.8  christos 
   9703   1.8  christos 		  switch (r_type)
   9704   1.8  christos 		    {
   9705   1.8  christos 		    case R_XTENSA_DIFF8:
   9706   1.8  christos 		      diff_mask = 0x7f;
   9707   1.8  christos 		      diff_value =
   9708   1.8  christos 			bfd_get_signed_8 (abfd, &contents[old_source_offset]);
   9709   1.8  christos 		      break;
   9710   1.8  christos 		    case R_XTENSA_DIFF16:
   9711   1.8  christos 		      diff_mask = 0x7fff;
   9712   1.8  christos 		      diff_value =
   9713   1.1  christos 			bfd_get_signed_16 (abfd, &contents[old_source_offset]);
   9714   1.1  christos 		      break;
   9715   1.8  christos 		    case R_XTENSA_DIFF32:
   9716   1.8  christos 		      diff_mask = 0x7fffffff;
   9717   1.8  christos 		      diff_value =
   9718   1.8  christos 			bfd_get_signed_32 (abfd, &contents[old_source_offset]);
   9719   1.8  christos 		      break;
   9720   1.3  christos 		    case R_XTENSA_PDIFF8:
   9721   1.1  christos 		    case R_XTENSA_NDIFF8:
   9722   1.1  christos 		      diff_mask = 0xff;
   9723   1.1  christos 		      diff_value =
   9724   1.1  christos 			bfd_get_8 (abfd, &contents[old_source_offset]);
   9725   1.1  christos 		      break;
   9726   1.1  christos 		    case R_XTENSA_PDIFF16:
   9727   1.1  christos 		    case R_XTENSA_NDIFF16:
   9728   1.3  christos 		      diff_mask = 0xffff;
   9729   1.1  christos 		      diff_value =
   9730   1.1  christos 			bfd_get_16 (abfd, &contents[old_source_offset]);
   9731   1.1  christos 		      break;
   9732   1.3  christos 		    case R_XTENSA_PDIFF32:
   9733   1.1  christos 		    case R_XTENSA_NDIFF32:
   9734   1.1  christos 		      diff_mask = 0xffffffff;
   9735   1.1  christos 		      diff_value =
   9736   1.3  christos 			bfd_get_32 (abfd, &contents[old_source_offset]);
   9737   1.1  christos 		      break;
   9738   1.1  christos 		    }
   9739   1.8  christos 
   9740   1.8  christos 		  if (r_type >= R_XTENSA_NDIFF8
   9741   1.8  christos 		      && r_type <= R_XTENSA_NDIFF32
   9742   1.8  christos 		      && diff_value)
   9743   1.8  christos 		    diff_value |= ~diff_mask;
   9744   1.8  christos 
   9745   1.8  christos 		  new_end_offset = offset_with_removed_text_map
   9746   1.8  christos 		    (&target_relax_info->action_list,
   9747   1.8  christos 		     r_rel.target_offset + diff_value);
   9748   1.8  christos 		  diff_value = new_end_offset - new_reloc.target_offset;
   9749   1.8  christos 
   9750   1.8  christos 		  switch (r_type)
   9751   1.8  christos 		    {
   9752   1.8  christos 		    case R_XTENSA_DIFF8:
   9753   1.8  christos 		      bfd_put_signed_8 (abfd, diff_value,
   9754   1.1  christos 				 &contents[old_source_offset]);
   9755   1.1  christos 		      break;
   9756   1.8  christos 		    case R_XTENSA_DIFF16:
   9757   1.8  christos 		      bfd_put_signed_16 (abfd, diff_value,
   9758   1.8  christos 				  &contents[old_source_offset]);
   9759   1.8  christos 		      break;
   9760   1.8  christos 		    case R_XTENSA_DIFF32:
   9761   1.8  christos 		      bfd_put_signed_32 (abfd, diff_value,
   9762   1.1  christos 				  &contents[old_source_offset]);
   9763   1.1  christos 		      break;
   9764   1.1  christos 		    case R_XTENSA_PDIFF8:
   9765   1.1  christos 		    case R_XTENSA_NDIFF8:
   9766   1.1  christos 		      bfd_put_8 (abfd, diff_value,
   9767   1.1  christos 				 &contents[old_source_offset]);
   9768   1.1  christos 		      break;
   9769   1.1  christos 		    case R_XTENSA_PDIFF16:
   9770   1.1  christos 		    case R_XTENSA_NDIFF16:
   9771   1.1  christos 		      bfd_put_16 (abfd, diff_value,
   9772   1.1  christos 				  &contents[old_source_offset]);
   9773   1.1  christos 		      break;
   9774   1.1  christos 		    case R_XTENSA_PDIFF32:
   9775   1.1  christos 		    case R_XTENSA_NDIFF32:
   9776   1.1  christos 		      bfd_put_32 (abfd, diff_value,
   9777   1.1  christos 				  &contents[old_source_offset]);
   9778   1.1  christos 		      break;
   9779   1.1  christos 		    }
   9780   1.1  christos 
   9781   1.1  christos 		  /* Check for overflow. Sign bits must be all zeroes or
   9782   1.1  christos 		     all ones.  When sign bits are all ones diff_value
   9783   1.1  christos 		     may not be zero.  */
   9784   1.1  christos 		  if (((diff_value & ~diff_mask) != 0
   9785   1.1  christos 		       && (diff_value & ~diff_mask) != ~diff_mask)
   9786   1.1  christos 		      || (diff_value && (bfd_vma) diff_value == ~diff_mask))
   9787   1.1  christos 		    {
   9788   1.1  christos 		      (*link_info->callbacks->reloc_dangerous)
   9789   1.1  christos 			(link_info, _("overflow after relaxation"),
   9790   1.1  christos 			 abfd, sec, old_source_offset);
   9791   1.8  christos 		      goto error_return;
   9792   1.1  christos 		    }
   9793   1.1  christos 
   9794   1.1  christos 		  pin_contents (sec, contents);
   9795   1.1  christos 		}
   9796   1.1  christos 
   9797   1.1  christos 	      /* If the relocation still references a section in the same
   9798   1.1  christos 		 input file, modify the relocation directly instead of
   9799   1.1  christos 		 adding a "fix" record.  */
   9800   1.3  christos 	      if (target_sec->owner == abfd)
   9801   1.1  christos 		{
   9802   1.1  christos 		  unsigned r_symndx = ELF32_R_SYM (new_reloc.rela.r_info);
   9803   1.1  christos 		  irel->r_info = ELF32_R_INFO (r_symndx, r_type);
   9804   1.1  christos 		  irel->r_addend = new_reloc.rela.r_addend;
   9805   1.1  christos 		  pin_internal_relocs (sec, internal_relocs);
   9806   1.1  christos 		}
   9807   1.1  christos 	      else
   9808   1.1  christos 		{
   9809   1.1  christos 		  bfd_vma addend_displacement;
   9810   1.1  christos 		  reloc_bfd_fix *fix;
   9811   1.1  christos 
   9812   1.1  christos 		  addend_displacement =
   9813   1.1  christos 		    new_reloc.target_offset + new_reloc.virtual_offset;
   9814   1.1  christos 		  fix = reloc_bfd_fix_init (sec, source_offset, r_type,
   9815   1.1  christos 					    target_sec,
   9816   1.3  christos 					    addend_displacement, true);
   9817   1.1  christos 		  add_fix (sec, fix);
   9818   1.1  christos 		}
   9819   1.1  christos 	    }
   9820   1.3  christos 	}
   9821   1.3  christos     }
   9822   1.1  christos 
   9823   1.1  christos   if ((relax_info->is_relaxable_literal_section
   9824   1.1  christos        || relax_info->is_relaxable_asm_section)
   9825   1.1  christos       && action_list_count (&relax_info->action_list))
   9826   1.1  christos     {
   9827   1.1  christos       /* Walk through the planned actions and build up a table
   9828   1.1  christos 	 of move, copy and fill records.  Use the move, copy and
   9829   1.1  christos 	 fill records to perform the actions once.  */
   9830   1.3  christos 
   9831   1.3  christos       bfd_size_type final_size, copy_size, orig_insn_size;
   9832   1.1  christos       bfd_byte *scratch = NULL;
   9833   1.8  christos       bfd_byte *dup_contents = NULL;
   9834   1.1  christos       bfd_size_type orig_size = sec->size;
   9835   1.1  christos       bfd_vma orig_dot = 0;
   9836   1.1  christos       bfd_vma orig_dot_copied = 0; /* Byte copied already from
   9837   1.1  christos 					    orig dot in physical memory.  */
   9838   1.1  christos       bfd_vma orig_dot_vo = 0; /* Virtual offset from orig_dot.  */
   9839   1.1  christos       bfd_vma dup_dot = 0;
   9840   1.1  christos 
   9841   1.1  christos       text_action *action;
   9842   1.1  christos 
   9843   1.1  christos       final_size = sec->size;
   9844   1.1  christos 
   9845   1.1  christos       splay_tree_foreach (relax_info->action_list.tree,
   9846   1.1  christos 			  action_remove_bytes_fn, &final_size);
   9847   1.1  christos       scratch = (bfd_byte *) bfd_zmalloc (final_size);
   9848   1.1  christos       dup_contents = (bfd_byte *) bfd_zmalloc (final_size);
   9849   1.1  christos 
   9850   1.1  christos       /* The dot is the current fill location.  */
   9851   1.1  christos #if DEBUG
   9852   1.1  christos       print_action_list (stderr, &relax_info->action_list);
   9853   1.1  christos #endif
   9854   1.1  christos 
   9855   1.1  christos       for (action = action_first (&relax_info->action_list); action;
   9856   1.1  christos 	   action = action_next (&relax_info->action_list, action))
   9857   1.1  christos 	{
   9858   1.1  christos 	  virtual_action = false;
   9859   1.1  christos 	  if (action->offset > orig_dot)
   9860   1.1  christos 	    {
   9861   1.1  christos 	      orig_dot += orig_dot_copied;
   9862   1.1  christos 	      orig_dot_copied = 0;
   9863   1.1  christos 	      orig_dot_vo = 0;
   9864   1.1  christos 	      /* Out of the virtual world.  */
   9865   1.1  christos 	    }
   9866   1.1  christos 
   9867   1.1  christos 	  if (action->offset > orig_dot)
   9868   1.1  christos 	    {
   9869   1.1  christos 	      copy_size = action->offset - orig_dot;
   9870   1.1  christos 	      memmove (&dup_contents[dup_dot], &contents[orig_dot], copy_size);
   9871   1.1  christos 	      orig_dot += copy_size;
   9872   1.1  christos 	      dup_dot += copy_size;
   9873   1.1  christos 	      BFD_ASSERT (action->offset == orig_dot);
   9874   1.1  christos 	    }
   9875   1.8  christos 	  else if (action->offset < orig_dot)
   9876   1.3  christos 	    {
   9877   1.1  christos 	      if (action->action == ta_fill
   9878   1.1  christos 		  && action->offset - action->removed_bytes == orig_dot)
   9879   1.1  christos 		{
   9880   1.1  christos 		  /* This is OK because the fill only effects the dup_dot.  */
   9881   1.1  christos 		}
   9882   1.1  christos 	      else if (action->action == ta_add_literal)
   9883   1.1  christos 		{
   9884   1.1  christos 		  /* TBD.  Might need to handle this.  */
   9885   1.1  christos 		}
   9886   1.1  christos 	    }
   9887   1.1  christos 	  if (action->offset == orig_dot)
   9888   1.1  christos 	    {
   9889   1.1  christos 	      if (action->virtual_offset > orig_dot_vo)
   9890   1.1  christos 		{
   9891   1.1  christos 		  if (orig_dot_vo == 0)
   9892   1.1  christos 		    {
   9893   1.1  christos 		      /* Need to copy virtual_offset bytes.  Probably four.  */
   9894   1.1  christos 		      copy_size = action->virtual_offset - orig_dot_vo;
   9895   1.1  christos 		      memmove (&dup_contents[dup_dot],
   9896   1.1  christos 			       &contents[orig_dot], copy_size);
   9897   1.1  christos 		      orig_dot_copied = copy_size;
   9898   1.1  christos 		      dup_dot += copy_size;
   9899   1.1  christos 		    }
   9900   1.1  christos 		  virtual_action = true;
   9901   1.1  christos 		}
   9902   1.1  christos 	      else
   9903   1.1  christos 		BFD_ASSERT (action->virtual_offset <= orig_dot_vo);
   9904   1.1  christos 	    }
   9905   1.1  christos 	  switch (action->action)
   9906   1.1  christos 	    {
   9907   1.1  christos 	    case ta_remove_literal:
   9908   1.1  christos 	    case ta_remove_insn:
   9909   1.1  christos 	      BFD_ASSERT (action->removed_bytes >= 0);
   9910   1.1  christos 	      orig_dot += action->removed_bytes;
   9911   1.1  christos 	      break;
   9912   1.1  christos 
   9913   1.1  christos 	    case ta_narrow_insn:
   9914   1.1  christos 	      orig_insn_size = 3;
   9915   1.1  christos 	      copy_size = 2;
   9916   1.1  christos 	      memmove (scratch, &contents[orig_dot], orig_insn_size);
   9917   1.1  christos 	      BFD_ASSERT (action->removed_bytes == 1);
   9918   1.1  christos 	      rv = narrow_instruction (scratch, final_size, 0);
   9919   1.1  christos 	      BFD_ASSERT (rv);
   9920   1.1  christos 	      memmove (&dup_contents[dup_dot], scratch, copy_size);
   9921   1.1  christos 	      orig_dot += orig_insn_size;
   9922   1.1  christos 	      dup_dot += copy_size;
   9923   1.1  christos 	      break;
   9924   1.1  christos 
   9925   1.1  christos 	    case ta_fill:
   9926   1.1  christos 	      if (action->removed_bytes >= 0)
   9927   1.1  christos 		orig_dot += action->removed_bytes;
   9928   1.1  christos 	      else
   9929   1.1  christos 		{
   9930   1.1  christos 		  /* Already zeroed in dup_contents.  Just bump the
   9931   1.1  christos 		     counters.  */
   9932   1.1  christos 		  dup_dot += (-action->removed_bytes);
   9933   1.1  christos 		}
   9934   1.1  christos 	      break;
   9935   1.1  christos 
   9936   1.1  christos 	    case ta_none:
   9937   1.1  christos 	      BFD_ASSERT (action->removed_bytes == 0);
   9938   1.1  christos 	      break;
   9939   1.1  christos 
   9940   1.1  christos 	    case ta_convert_longcall:
   9941   1.1  christos 	    case ta_remove_longcall:
   9942   1.1  christos 	      /* These will be removed or converted before we get here.  */
   9943   1.1  christos 	      BFD_ASSERT (0);
   9944   1.1  christos 	      break;
   9945   1.1  christos 
   9946   1.1  christos 	    case ta_widen_insn:
   9947   1.3  christos 	      orig_insn_size = 2;
   9948   1.1  christos 	      copy_size = 3;
   9949   1.1  christos 	      memmove (scratch, &contents[orig_dot], orig_insn_size);
   9950   1.1  christos 	      BFD_ASSERT (action->removed_bytes == -1);
   9951   1.1  christos 	      rv = widen_instruction (scratch, final_size, 0);
   9952   1.1  christos 	      BFD_ASSERT (rv);
   9953   1.1  christos 	      memmove (&dup_contents[dup_dot], scratch, copy_size);
   9954   1.1  christos 	      orig_dot += orig_insn_size;
   9955   1.1  christos 	      dup_dot += copy_size;
   9956   1.1  christos 	      break;
   9957   1.1  christos 
   9958   1.1  christos 	    case ta_add_literal:
   9959   1.1  christos 	      orig_insn_size = 0;
   9960   1.1  christos 	      copy_size = 4;
   9961   1.1  christos 	      BFD_ASSERT (action->removed_bytes == -4);
   9962   1.1  christos 	      /* TBD -- place the literal value here and insert
   9963   1.1  christos 		 into the table.  */
   9964   1.1  christos 	      memset (&dup_contents[dup_dot], 0, 4);
   9965   1.1  christos 	      pin_internal_relocs (sec, internal_relocs);
   9966   1.1  christos 	      pin_contents (sec, contents);
   9967   1.1  christos 
   9968   1.1  christos 	      if (!move_literal (abfd, link_info, sec, dup_dot, dup_contents,
   9969   1.1  christos 				 relax_info, &internal_relocs, &action->value))
   9970   1.1  christos 		goto error_return;
   9971   1.1  christos 
   9972   1.1  christos 	      if (virtual_action)
   9973   1.1  christos 		orig_dot_vo += copy_size;
   9974   1.1  christos 
   9975   1.1  christos 	      orig_dot += orig_insn_size;
   9976   1.1  christos 	      dup_dot += copy_size;
   9977   1.1  christos 	      break;
   9978   1.1  christos 
   9979   1.1  christos 	    default:
   9980   1.1  christos 	      /* Not implemented yet.  */
   9981   1.1  christos 	      BFD_ASSERT (0);
   9982   1.1  christos 	      break;
   9983   1.1  christos 	    }
   9984   1.1  christos 
   9985   1.1  christos 	  BFD_ASSERT (dup_dot <= final_size);
   9986   1.1  christos 	  BFD_ASSERT (orig_dot <= orig_size);
   9987   1.1  christos 	}
   9988   1.1  christos 
   9989   1.1  christos       orig_dot += orig_dot_copied;
   9990   1.1  christos       orig_dot_copied = 0;
   9991   1.1  christos 
   9992   1.1  christos       if (orig_dot != orig_size)
   9993   1.1  christos 	{
   9994   1.1  christos 	  copy_size = orig_size - orig_dot;
   9995   1.1  christos 	  BFD_ASSERT (orig_size > orig_dot);
   9996   1.1  christos 	  BFD_ASSERT (dup_dot + copy_size == final_size);
   9997   1.1  christos 	  memmove (&dup_contents[dup_dot], &contents[orig_dot], copy_size);
   9998   1.1  christos 	  orig_dot += copy_size;
   9999   1.1  christos 	  dup_dot += copy_size;
   10000   1.1  christos 	}
   10001   1.1  christos       BFD_ASSERT (orig_size == orig_dot);
   10002   1.1  christos       BFD_ASSERT (final_size == dup_dot);
   10003   1.1  christos 
   10004   1.1  christos       /* Move the dup_contents back.  */
   10005   1.1  christos       if (final_size > orig_size)
   10006   1.1  christos 	{
   10007   1.1  christos 	  /* Contents need to be reallocated.  Swap the dup_contents into
   10008   1.1  christos 	     contents.  */
   10009   1.1  christos 	  sec->contents = dup_contents;
   10010   1.1  christos 	  free (contents);
   10011   1.8  christos 	  contents = dup_contents;
   10012   1.1  christos 	  pin_contents (sec, contents);
   10013   1.1  christos 	}
   10014   1.1  christos       else
   10015   1.1  christos 	{
   10016   1.1  christos 	  BFD_ASSERT (final_size <= orig_size);
   10017   1.1  christos 	  memset (contents, 0, orig_size);
   10018   1.1  christos 	  memcpy (contents, dup_contents, final_size);
   10019   1.8  christos 	  free (dup_contents);
   10020   1.1  christos 	}
   10021   1.1  christos       free (scratch);
   10022   1.1  christos       pin_contents (sec, contents);
   10023   1.8  christos 
   10024   1.1  christos       if (sec->rawsize == 0)
   10025   1.8  christos 	sec->rawsize = sec->size;
   10026   1.1  christos       sec->size = final_size;
   10027   1.1  christos     }
   10028   1.1  christos 
   10029   1.1  christos  error_return:
   10030   1.1  christos   release_internal_relocs (sec, internal_relocs);
   10031   1.1  christos   release_contents (sec, contents);
   10032   1.8  christos   return ok;
   10033   1.1  christos }
   10034   1.1  christos 
   10035   1.1  christos 
   10036   1.1  christos static bool
   10037   1.1  christos translate_section_fixes (asection *sec)
   10038   1.1  christos {
   10039   1.1  christos   xtensa_relax_info *relax_info;
   10040   1.1  christos   reloc_bfd_fix *r;
   10041   1.1  christos 
   10042   1.8  christos   relax_info = get_xtensa_relax_info (sec);
   10043   1.1  christos   if (!relax_info)
   10044   1.1  christos     return true;
   10045   1.1  christos 
   10046   1.1  christos   for (r = relax_info->fix_list; r != NULL; r = r->next)
   10047   1.1  christos     if (!translate_reloc_bfd_fix (r))
   10048   1.1  christos       return false;
   10049   1.1  christos 
   10050   1.8  christos   return true;
   10051   1.8  christos }
   10052   1.1  christos 
   10053   1.1  christos 
   10054   1.1  christos /* Translate a fix given the mapping in the relax info for the target
   10055   1.1  christos    section.  If it has already been translated, no work is required.  */
   10056   1.1  christos 
   10057   1.1  christos static bool
   10058   1.1  christos translate_reloc_bfd_fix (reloc_bfd_fix *fix)
   10059   1.1  christos {
   10060   1.8  christos   reloc_bfd_fix new_fix;
   10061   1.8  christos   asection *sec;
   10062   1.1  christos   xtensa_relax_info *relax_info;
   10063   1.1  christos   removed_literal *removed;
   10064   1.1  christos   bfd_vma new_offset, target_offset;
   10065   1.1  christos 
   10066   1.1  christos   if (fix->translated)
   10067   1.1  christos     return true;
   10068   1.1  christos 
   10069  1.10  christos   sec = fix->target_sec;
   10070   1.1  christos   target_offset = fix->target_offset;
   10071   1.1  christos 
   10072   1.1  christos   relax_info = get_xtensa_relax_info (sec);
   10073   1.1  christos   if (!relax_info)
   10074   1.1  christos     {
   10075   1.1  christos       fix->translated = true;
   10076   1.1  christos       return true;
   10077   1.1  christos     }
   10078   1.3  christos 
   10079   1.1  christos   new_fix = *fix;
   10080   1.1  christos 
   10081   1.1  christos   /* The fix does not need to be translated if the section cannot change.  */
   10082   1.1  christos   if (!relax_info->is_relaxable_literal_section
   10083   1.1  christos       && !relax_info->is_relaxable_asm_section)
   10084   1.1  christos     {
   10085   1.1  christos       fix->translated = true;
   10086   1.1  christos       return true;
   10087   1.1  christos     }
   10088   1.3  christos 
   10089   1.1  christos   /* If the literal has been moved and this relocation was on an
   10090   1.1  christos      opcode, then the relocation should move to the new literal
   10091   1.1  christos      location.  Otherwise, the relocation should move within the
   10092   1.3  christos      section.  */
   10093   1.1  christos 
   10094   1.1  christos   removed = NULL;
   10095   1.1  christos   if (is_operand_relocation (fix->src_type))
   10096   1.1  christos     {
   10097   1.1  christos       /* Check if the original relocation is against a literal being
   10098   1.1  christos 	 removed.  */
   10099   1.8  christos       removed = find_removed_literal (&relax_info->removed_list,
   10100   1.1  christos 				      target_offset);
   10101   1.8  christos     }
   10102   1.1  christos 
   10103   1.1  christos   if (removed)
   10104   1.1  christos     {
   10105   1.1  christos       asection *new_sec;
   10106   1.1  christos 
   10107   1.1  christos       /* The fact that there is still a relocation to this literal indicates
   10108   1.1  christos 	 that the literal is being coalesced, not simply removed.  */
   10109   1.1  christos       BFD_ASSERT (removed->to.abfd != NULL);
   10110   1.1  christos 
   10111   1.1  christos       /* This was moved to some other address (possibly another section).  */
   10112   1.1  christos       new_sec = r_reloc_get_section (&removed->to);
   10113   1.1  christos       if (new_sec != sec)
   10114   1.8  christos 	{
   10115   1.1  christos 	  sec = new_sec;
   10116   1.8  christos 	  relax_info = get_xtensa_relax_info (sec);
   10117   1.1  christos 	  if (!relax_info ||
   10118   1.1  christos 	      (!relax_info->is_relaxable_literal_section
   10119   1.1  christos 	       && !relax_info->is_relaxable_asm_section))
   10120   1.1  christos 	    {
   10121   1.1  christos 	      target_offset = removed->to.target_offset;
   10122   1.1  christos 	      new_fix.target_sec = new_sec;
   10123   1.1  christos 	      new_fix.target_offset = target_offset;
   10124   1.1  christos 	      new_fix.translated = true;
   10125   1.1  christos 	      *fix = new_fix;
   10126   1.1  christos 	      return true;
   10127   1.1  christos 	    }
   10128   1.1  christos 	}
   10129   1.1  christos       target_offset = removed->to.target_offset;
   10130   1.1  christos       new_fix.target_sec = new_sec;
   10131   1.1  christos     }
   10132   1.1  christos 
   10133   1.1  christos   /* The target address may have been moved within its section.  */
   10134   1.1  christos   new_offset = offset_with_removed_text (&relax_info->action_list,
   10135   1.1  christos 					 target_offset);
   10136   1.1  christos 
   10137   1.1  christos   new_fix.target_offset = new_offset;
   10138   1.1  christos   new_fix.target_offset = new_offset;
   10139   1.1  christos   new_fix.translated = true;
   10140  1.10  christos   *fix = new_fix;
   10141   1.1  christos   return true;
   10142   1.1  christos }
   10143   1.1  christos 
   10144   1.1  christos 
   10145   1.1  christos /* Fix up a relocation to take account of removed literals.  */
   10146   1.1  christos 
   10147   1.1  christos static asection *
   10148   1.1  christos translate_reloc (const r_reloc *orig_rel, r_reloc *new_rel, asection *sec)
   10149   1.1  christos {
   10150   1.1  christos   xtensa_relax_info *relax_info;
   10151   1.1  christos   removed_literal *removed;
   10152   1.1  christos   bfd_vma target_offset, base_offset;
   10153   1.1  christos 
   10154   1.1  christos   *new_rel = *orig_rel;
   10155   1.1  christos 
   10156   1.1  christos   if (!r_reloc_is_defined (orig_rel))
   10157   1.1  christos     return sec ;
   10158   1.1  christos 
   10159   1.1  christos   relax_info = get_xtensa_relax_info (sec);
   10160   1.1  christos   BFD_ASSERT (relax_info && (relax_info->is_relaxable_literal_section
   10161   1.1  christos 			     || relax_info->is_relaxable_asm_section));
   10162   1.1  christos 
   10163   1.1  christos   target_offset = orig_rel->target_offset;
   10164   1.1  christos 
   10165   1.1  christos   removed = NULL;
   10166   1.1  christos   if (is_operand_relocation (ELF32_R_TYPE (orig_rel->rela.r_info)))
   10167   1.1  christos     {
   10168   1.1  christos       /* Check if the original relocation is against a literal being
   10169   1.1  christos 	 removed.  */
   10170   1.1  christos       removed = find_removed_literal (&relax_info->removed_list,
   10171   1.1  christos 				      target_offset);
   10172   1.1  christos     }
   10173   1.1  christos   if (removed && removed->to.abfd)
   10174   1.1  christos     {
   10175   1.1  christos       asection *new_sec;
   10176   1.1  christos 
   10177   1.1  christos       /* The fact that there is still a relocation to this literal indicates
   10178   1.1  christos 	 that the literal is being coalesced, not simply removed.  */
   10179   1.1  christos       BFD_ASSERT (removed->to.abfd != NULL);
   10180   1.1  christos 
   10181   1.1  christos       /* This was moved to some other address
   10182   1.3  christos 	 (possibly in another section).  */
   10183   1.8  christos       *new_rel = removed->to;
   10184   1.3  christos       new_sec = r_reloc_get_section (new_rel);
   10185   1.8  christos       if (new_sec != sec)
   10186   1.3  christos 	{
   10187   1.3  christos 	  sec = new_sec;
   10188   1.1  christos 	  relax_info = get_xtensa_relax_info (sec);
   10189   1.1  christos 	  if (!relax_info
   10190   1.1  christos 	      || (!relax_info->is_relaxable_literal_section
   10191   1.1  christos 		  && !relax_info->is_relaxable_asm_section))
   10192   1.1  christos 	    return sec;
   10193   1.1  christos 	}
   10194   1.3  christos       target_offset = new_rel->target_offset;
   10195   1.8  christos     }
   10196   1.3  christos 
   10197   1.8  christos   /* Find the base offset of the reloc symbol, excluding any addend from the
   10198   1.3  christos      reloc or from the section contents (for a partial_inplace reloc).  Then
   10199   1.3  christos      find the adjusted values of the offsets due to relaxation.  The base
   10200   1.1  christos      offset is needed to determine the change to the reloc's addend; the reloc
   10201   1.1  christos      addend should not be adjusted due to relaxations located before the base
   10202   1.1  christos      offset.  */
   10203   1.1  christos 
   10204   1.1  christos   base_offset = r_reloc_get_target_offset (new_rel) - new_rel->rela.r_addend;
   10205   1.1  christos   if (base_offset <= target_offset)
   10206   1.1  christos     {
   10207   1.1  christos       int base_removed = removed_by_actions_map (&relax_info->action_list,
   10208   1.1  christos 						 base_offset, false);
   10209   1.1  christos       int addend_removed = removed_by_actions_map (&relax_info->action_list,
   10210   1.1  christos 						   target_offset, false) -
   10211   1.1  christos 	base_removed;
   10212   1.1  christos 
   10213   1.1  christos       new_rel->target_offset = target_offset - base_removed - addend_removed;
   10214   1.1  christos       new_rel->rela.r_addend -= addend_removed;
   10215   1.1  christos     }
   10216   1.1  christos   else
   10217   1.1  christos     {
   10218   1.1  christos       /* Handle a negative addend.  The base offset comes first.  */
   10219   1.1  christos       int tgt_removed = removed_by_actions_map (&relax_info->action_list,
   10220   1.1  christos 						target_offset, false);
   10221   1.1  christos       int addend_removed = removed_by_actions_map (&relax_info->action_list,
   10222   1.1  christos 						   base_offset, false) -
   10223   1.1  christos 	tgt_removed;
   10224   1.1  christos 
   10225   1.1  christos       new_rel->target_offset = target_offset - tgt_removed;
   10226   1.1  christos       new_rel->rela.r_addend += addend_removed;
   10227   1.1  christos     }
   10228   1.1  christos 
   10229   1.8  christos   return sec;
   10230   1.1  christos }
   10231   1.1  christos 
   10232   1.1  christos 
   10233   1.1  christos /* For dynamic links, there may be a dynamic relocation for each
   10234   1.1  christos    literal.  The number of dynamic relocations must be computed in
   10235   1.1  christos    size_dynamic_sections, which occurs before relaxation.  When a
   10236   1.1  christos    literal is removed, this function checks if there is a corresponding
   10237   1.1  christos    dynamic relocation and shrinks the size of the appropriate dynamic
   10238   1.1  christos    relocation section accordingly.  At this point, the contents of the
   10239   1.1  christos    dynamic relocation sections have not yet been filled in, so there's
   10240   1.1  christos    nothing else that needs to be done.  */
   10241   1.1  christos 
   10242   1.1  christos static void
   10243   1.1  christos shrink_dynamic_reloc_sections (struct bfd_link_info *info,
   10244   1.1  christos 			       bfd *abfd,
   10245   1.1  christos 			       asection *input_section,
   10246   1.1  christos 			       Elf_Internal_Rela *rel)
   10247   1.1  christos {
   10248   1.1  christos   struct elf_xtensa_link_hash_table *htab;
   10249   1.1  christos   Elf_Internal_Shdr *symtab_hdr;
   10250   1.8  christos   struct elf_link_hash_entry **sym_hashes;
   10251   1.8  christos   unsigned long r_symndx;
   10252   1.8  christos   int r_type;
   10253   1.1  christos   struct elf_link_hash_entry *h;
   10254   1.1  christos   bool dynamic_symbol;
   10255   1.8  christos 
   10256   1.1  christos   htab = elf_xtensa_hash_table (info);
   10257   1.1  christos   if (htab == NULL)
   10258   1.1  christos     return;
   10259   1.6  christos 
   10260   1.8  christos   symtab_hdr = &elf_tdata (abfd)->symtab_hdr;
   10261   1.1  christos   sym_hashes = elf_sym_hashes (abfd);
   10262   1.1  christos 
   10263   1.6  christos   r_type = ELF32_R_TYPE (rel->r_info);
   10264   1.1  christos   r_symndx = ELF32_R_SYM (rel->r_info);
   10265   1.1  christos 
   10266   1.1  christos   if (r_symndx < symtab_hdr->sh_info)
   10267   1.1  christos     h = NULL;
   10268   1.1  christos   else
   10269   1.1  christos     h = sym_hashes[r_symndx - symtab_hdr->sh_info];
   10270   1.1  christos 
   10271   1.1  christos   dynamic_symbol = elf_xtensa_dynamic_symbol_p (h, info);
   10272   1.1  christos 
   10273   1.1  christos   if ((r_type == R_XTENSA_32 || r_type == R_XTENSA_PLT)
   10274   1.1  christos       && (input_section->flags & SEC_ALLOC) != 0
   10275   1.1  christos       && (dynamic_symbol
   10276   1.1  christos 	  || (bfd_link_pic (info)
   10277   1.1  christos 	      && (!h || h->root.type != bfd_link_hash_undefweak))))
   10278   1.1  christos     {
   10279   1.1  christos       asection *srel;
   10280   1.1  christos       bool is_plt = false;
   10281   1.1  christos 
   10282   1.1  christos       if (dynamic_symbol && r_type == R_XTENSA_PLT)
   10283   1.1  christos 	{
   10284   1.1  christos 	  srel = htab->elf.srelplt;
   10285   1.1  christos 	  is_plt = true;
   10286   1.1  christos 	}
   10287   1.1  christos       else
   10288   1.1  christos 	srel = htab->elf.srelgot;
   10289   1.1  christos 
   10290   1.1  christos       /* Reduce size of the .rela.* section by one reloc.  */
   10291   1.1  christos       BFD_ASSERT (srel != NULL);
   10292   1.6  christos       BFD_ASSERT (srel->size >= sizeof (Elf32_External_Rela));
   10293   1.1  christos       srel->size -= sizeof (Elf32_External_Rela);
   10294   1.1  christos 
   10295   1.1  christos       if (is_plt)
   10296   1.1  christos 	{
   10297   1.1  christos 	  asection *splt, *sgotplt, *srelgot;
   10298   1.1  christos 	  int reloc_index, chunk;
   10299   1.1  christos 
   10300   1.1  christos 	  /* Find the PLT reloc index of the entry being removed.  This
   10301   1.1  christos 	     is computed from the size of ".rela.plt".  It is needed to
   10302   1.1  christos 	     figure out which PLT chunk to resize.  Usually "last index
   10303   1.1  christos 	     = size - 1" since the index starts at zero, but in this
   10304   1.1  christos 	     context, the size has just been decremented so there's no
   10305   1.1  christos 	     need to subtract one.  */
   10306   1.1  christos 	  reloc_index = srel->size / sizeof (Elf32_External_Rela);
   10307   1.1  christos 
   10308   1.1  christos 	  chunk = reloc_index / PLT_ENTRIES_PER_CHUNK;
   10309   1.1  christos 	  splt = elf_xtensa_get_plt_section (info, chunk);
   10310   1.1  christos 	  sgotplt = elf_xtensa_get_gotplt_section (info, chunk);
   10311   1.1  christos 	  BFD_ASSERT (splt != NULL && sgotplt != NULL);
   10312   1.1  christos 
   10313   1.1  christos 	  /* Check if an entire PLT chunk has just been eliminated.  */
   10314   1.1  christos 	  if (reloc_index % PLT_ENTRIES_PER_CHUNK == 0)
   10315   1.1  christos 	    {
   10316   1.1  christos 	      /* The two magic GOT entries for that chunk can go away.  */
   10317   1.1  christos 	      srelgot = htab->elf.srelgot;
   10318   1.1  christos 	      BFD_ASSERT (srelgot != NULL);
   10319   1.1  christos 	      srelgot->reloc_count -= 2;
   10320   1.1  christos 	      srelgot->size -= 2 * sizeof (Elf32_External_Rela);
   10321   1.8  christos 	      sgotplt->size -= 8;
   10322   1.1  christos 
   10323   1.1  christos 	      /* There should be only one entry left (and it will be
   10324   1.1  christos 		 removed below).  */
   10325   1.1  christos 	      BFD_ASSERT (sgotplt->size == 4);
   10326   1.1  christos 	      BFD_ASSERT (splt->size == PLT_ENTRY_SIZE);
   10327   1.1  christos 	    }
   10328   1.1  christos 
   10329   1.1  christos 	  BFD_ASSERT (sgotplt->size >= 4);
   10330   1.1  christos 	  BFD_ASSERT (splt->size >= PLT_ENTRY_SIZE);
   10331   1.1  christos 
   10332   1.1  christos 	  sgotplt->size -= 4;
   10333   1.1  christos 	  splt->size -= PLT_ENTRY_SIZE;
   10334   1.1  christos 	}
   10335   1.1  christos     }
   10336   1.1  christos }
   10337   1.1  christos 
   10338   1.1  christos 
   10339   1.1  christos /* Take an r_rel and move it to another section.  This usually
   10340   1.1  christos    requires extending the interal_relocation array and pinning it.  If
   10341   1.1  christos    the original r_rel is from the same BFD, we can complete this here.
   10342   1.1  christos    Otherwise, we add a fix record to let the final link fix the
   10343   1.1  christos    appropriate address.  Contents and internal relocations for the
   10344   1.1  christos    section must be pinned after calling this routine.  */
   10345   1.1  christos 
   10346   1.1  christos static bool
   10347   1.1  christos move_literal (bfd *abfd,
   10348   1.1  christos 	      struct bfd_link_info *link_info,
   10349   1.1  christos 	      asection *sec,
   10350   1.1  christos 	      bfd_vma offset,
   10351   1.1  christos 	      bfd_byte *contents,
   10352   1.1  christos 	      xtensa_relax_info *relax_info,
   10353   1.1  christos 	      Elf_Internal_Rela **internal_relocs_p,
   10354   1.1  christos 	      const literal_value *lit)
   10355   1.1  christos {
   10356   1.1  christos   Elf_Internal_Rela *new_relocs = NULL;
   10357   1.1  christos   size_t new_relocs_count = 0;
   10358   1.3  christos   Elf_Internal_Rela this_rela;
   10359   1.1  christos   const r_reloc *r_rel;
   10360   1.1  christos 
   10361   1.1  christos   r_rel = &lit->r_rel;
   10362   1.8  christos   BFD_ASSERT (elf_section_data (sec)->relocs == *internal_relocs_p);
   10363   1.1  christos 
   10364   1.1  christos   if (r_reloc_is_const (r_rel))
   10365   1.1  christos     bfd_put_32 (abfd, lit->value, contents + offset);
   10366   1.1  christos   else
   10367   1.1  christos     {
   10368   1.1  christos       int r_type;
   10369   1.1  christos       unsigned i;
   10370   1.1  christos       reloc_bfd_fix *fix;
   10371   1.1  christos       unsigned insert_at;
   10372   1.1  christos 
   10373   1.1  christos       r_type = ELF32_R_TYPE (r_rel->rela.r_info);
   10374   1.1  christos 
   10375   1.1  christos       /* This is the difficult case.  We have to create a fix up.  */
   10376   1.1  christos       this_rela.r_offset = offset;
   10377   1.1  christos       this_rela.r_info = ELF32_R_INFO (0, r_type);
   10378   1.1  christos       this_rela.r_addend =
   10379   1.1  christos 	r_rel->target_offset - r_reloc_get_target_offset (r_rel);
   10380   1.1  christos       bfd_put_32 (abfd, lit->value, contents + offset);
   10381   1.1  christos 
   10382   1.1  christos       /* Currently, we cannot move relocations during a relocatable link.  */
   10383   1.1  christos       BFD_ASSERT (!bfd_link_relocatable (link_info));
   10384   1.1  christos       fix = reloc_bfd_fix_init (sec, offset, r_type,
   10385   1.1  christos 				r_reloc_get_section (r_rel),
   10386   1.1  christos 				r_rel->target_offset + r_rel->virtual_offset,
   10387   1.1  christos 				false);
   10388   1.1  christos       /* We also need to mark that relocations are needed here.  */
   10389   1.3  christos       sec->flags |= SEC_RELOC;
   10390   1.1  christos 
   10391   1.1  christos       translate_reloc_bfd_fix (fix);
   10392   1.1  christos       /* This fix has not yet been translated.  */
   10393   1.1  christos       add_fix (sec, fix);
   10394   1.1  christos 
   10395   1.1  christos       /* Add the relocation.  If we have already allocated our own
   10396   1.1  christos 	 space for the relocations and we have room for more, then use
   10397   1.8  christos 	 it.  Otherwise, allocate new space and move the literals.  */
   10398   1.1  christos       insert_at = sec->reloc_count;
   10399   1.1  christos       for (i = 0; i < sec->reloc_count; ++i)
   10400   1.1  christos 	{
   10401   1.1  christos 	  if (this_rela.r_offset < (*internal_relocs_p)[i].r_offset)
   10402   1.1  christos 	    {
   10403   1.1  christos 	      insert_at = i;
   10404   1.1  christos 	      break;
   10405   1.1  christos 	    }
   10406   1.1  christos 	}
   10407   1.1  christos 
   10408   1.1  christos       if (*internal_relocs_p != relax_info->allocated_relocs
   10409   1.3  christos 	  || sec->reloc_count + 1 > relax_info->allocated_relocs_count)
   10410   1.1  christos 	{
   10411   1.1  christos 	  BFD_ASSERT (relax_info->allocated_relocs == NULL
   10412   1.1  christos 		      || sec->reloc_count == relax_info->relocs_count);
   10413   1.1  christos 
   10414   1.1  christos 	  if (relax_info->allocated_relocs_count == 0)
   10415   1.1  christos 	    new_relocs_count = (sec->reloc_count + 2) * 2;
   10416   1.1  christos 	  else
   10417   1.1  christos 	    new_relocs_count = (relax_info->allocated_relocs_count + 2) * 2;
   10418   1.1  christos 
   10419   1.1  christos 	  new_relocs = (Elf_Internal_Rela *)
   10420   1.1  christos 	    bfd_zmalloc (sizeof (Elf_Internal_Rela) * (new_relocs_count));
   10421   1.1  christos 	  if (!new_relocs)
   10422   1.1  christos 	    return false;
   10423   1.1  christos 
   10424   1.1  christos 	  /* We could handle this more quickly by finding the split point.  */
   10425   1.1  christos 	  if (insert_at != 0)
   10426   1.1  christos 	    memcpy (new_relocs, *internal_relocs_p,
   10427   1.1  christos 		    insert_at * sizeof (Elf_Internal_Rela));
   10428   1.1  christos 
   10429   1.1  christos 	  new_relocs[insert_at] = this_rela;
   10430   1.1  christos 
   10431   1.1  christos 	  if (insert_at != sec->reloc_count)
   10432   1.1  christos 	    memcpy (new_relocs + insert_at + 1,
   10433   1.1  christos 		    (*internal_relocs_p) + insert_at,
   10434   1.1  christos 		    (sec->reloc_count - insert_at)
   10435   1.1  christos 		    * sizeof (Elf_Internal_Rela));
   10436   1.1  christos 
   10437   1.1  christos 	  if (*internal_relocs_p != relax_info->allocated_relocs)
   10438   1.1  christos 	    {
   10439   1.1  christos 	      /* The first time we re-allocate, we can only free the
   10440   1.1  christos 		 old relocs if they were allocated with bfd_malloc.
   10441   1.1  christos 		 This is not true when keep_memory is in effect.  */
   10442   1.1  christos 	      if (!link_info->keep_memory)
   10443   1.8  christos 		free (*internal_relocs_p);
   10444   1.1  christos 	    }
   10445   1.1  christos 	  else
   10446   1.1  christos 	    free (*internal_relocs_p);
   10447   1.1  christos 	  relax_info->allocated_relocs = new_relocs;
   10448   1.1  christos 	  relax_info->allocated_relocs_count = new_relocs_count;
   10449   1.1  christos 	  elf_section_data (sec)->relocs = new_relocs;
   10450   1.1  christos 	  sec->reloc_count++;
   10451   1.1  christos 	  relax_info->relocs_count = sec->reloc_count;
   10452   1.8  christos 	  *internal_relocs_p = new_relocs;
   10453   1.1  christos 	}
   10454   1.1  christos       else
   10455   1.1  christos 	{
   10456   1.1  christos 	  if (insert_at != sec->reloc_count)
   10457   1.1  christos 	    {
   10458   1.1  christos 	      unsigned idx;
   10459   1.1  christos 	      for (idx = sec->reloc_count; idx > insert_at; idx--)
   10460   1.8  christos 		(*internal_relocs_p)[idx] = (*internal_relocs_p)[idx-1];
   10461   1.8  christos 	    }
   10462   1.1  christos 	  (*internal_relocs_p)[insert_at] = this_rela;
   10463   1.1  christos 	  sec->reloc_count++;
   10464   1.1  christos 	  if (relax_info->allocated_relocs)
   10465   1.1  christos 	    relax_info->relocs_count = sec->reloc_count;
   10466   1.1  christos 	}
   10467   1.1  christos     }
   10468   1.3  christos   return true;
   10469   1.1  christos }
   10470   1.1  christos 
   10471   1.1  christos 
   10472   1.1  christos /* This is similar to relax_section except that when a target is moved,
   10473   1.8  christos    we shift addresses up.  We also need to modify the size.  This
   10474   1.1  christos    algorithm does NOT allow for relocations into the middle of the
   10475   1.1  christos    property sections.  */
   10476   1.1  christos 
   10477   1.1  christos static bool
   10478   1.1  christos relax_property_section (bfd *abfd,
   10479   1.1  christos 			asection *sec,
   10480   1.1  christos 			struct bfd_link_info *link_info)
   10481   1.1  christos {
   10482   1.1  christos   Elf_Internal_Rela *internal_relocs;
   10483   1.1  christos   bfd_byte *contents;
   10484   1.1  christos   unsigned i;
   10485   1.1  christos   bool ok = true;
   10486   1.1  christos   bool is_full_prop_section;
   10487   1.1  christos   size_t last_zfill_target_offset = 0;
   10488   1.1  christos   asection *last_zfill_target_sec = NULL;
   10489   1.1  christos   bfd_size_type sec_size;
   10490   1.1  christos   bfd_size_type entry_size;
   10491   1.1  christos 
   10492   1.1  christos   sec_size = bfd_get_section_limit (abfd, sec);
   10493   1.1  christos   internal_relocs = retrieve_internal_relocs (abfd, sec,
   10494   1.1  christos 					      link_info->keep_memory);
   10495   1.1  christos   contents = retrieve_contents (abfd, sec, link_info->keep_memory);
   10496   1.1  christos   if (contents == NULL && sec_size != 0)
   10497   1.1  christos     {
   10498   1.1  christos       ok = false;
   10499   1.1  christos       goto error_return;
   10500   1.1  christos     }
   10501   1.1  christos 
   10502   1.1  christos   is_full_prop_section = xtensa_is_proptable_section (sec);
   10503   1.1  christos   if (is_full_prop_section)
   10504   1.1  christos     entry_size = 12;
   10505   1.1  christos   else
   10506   1.1  christos     entry_size = 8;
   10507   1.1  christos 
   10508   1.1  christos   if (internal_relocs)
   10509   1.1  christos     {
   10510   1.1  christos       for (i = 0; i < sec->reloc_count; i++)
   10511   1.1  christos 	{
   10512   1.1  christos 	  Elf_Internal_Rela *irel;
   10513   1.1  christos 	  xtensa_relax_info *target_relax_info;
   10514   1.1  christos 	  unsigned r_type;
   10515   1.1  christos 	  asection *target_sec;
   10516   1.1  christos 	  literal_value val;
   10517   1.1  christos 	  bfd_byte *size_p, *flags_p;
   10518   1.1  christos 
   10519   1.1  christos 	  /* Locally change the source address.
   10520   1.1  christos 	     Translate the target to the new target address.
   10521   1.1  christos 	     If it points to this section and has been removed, MOVE IT.
   10522   1.1  christos 	     Also, don't forget to modify the associated SIZE at
   10523   1.1  christos 	     (offset + 4).  */
   10524   1.3  christos 
   10525   1.3  christos 	  irel = &internal_relocs[i];
   10526   1.8  christos 	  r_type = ELF32_R_TYPE (irel->r_info);
   10527   1.3  christos 	  if (r_type == R_XTENSA_NONE)
   10528   1.1  christos 	    continue;
   10529   1.1  christos 
   10530   1.1  christos 	  /* Find the literal value.  */
   10531   1.1  christos 	  r_reloc_init (&val.r_rel, abfd, irel, contents, sec_size);
   10532   1.1  christos 	  size_p = &contents[irel->r_offset + 4];
   10533   1.1  christos 	  flags_p = NULL;
   10534   1.1  christos 	  if (is_full_prop_section)
   10535   1.1  christos 	    flags_p = &contents[irel->r_offset + 8];
   10536   1.1  christos 	  BFD_ASSERT (irel->r_offset + entry_size <= sec_size);
   10537   1.1  christos 
   10538   1.1  christos 	  target_sec = r_reloc_get_section (&val.r_rel);
   10539   1.1  christos 	  target_relax_info = get_xtensa_relax_info (target_sec);
   10540   1.1  christos 
   10541   1.1  christos 	  if (target_relax_info
   10542   1.1  christos 	      && (target_relax_info->is_relaxable_literal_section
   10543   1.1  christos 		  || target_relax_info->is_relaxable_asm_section ))
   10544   1.1  christos 	    {
   10545   1.1  christos 	      /* Translate the relocation's destination.  */
   10546   1.1  christos 	      bfd_vma old_offset = val.r_rel.target_offset;
   10547   1.1  christos 	      bfd_vma new_offset;
   10548   1.1  christos 	      long old_size, new_size;
   10549   1.1  christos 	      int removed_by_old_offset =
   10550   1.1  christos 		removed_by_actions_map (&target_relax_info->action_list,
   10551   1.3  christos 					old_offset, false);
   10552   1.3  christos 	      new_offset = old_offset - removed_by_old_offset;
   10553   1.8  christos 
   10554   1.3  christos 	      /* Assert that we are not out of bounds.  */
   10555   1.1  christos 	      old_size = bfd_get_32 (abfd, size_p);
   10556   1.1  christos 	      new_size = old_size;
   10557   1.1  christos 
   10558   1.1  christos 	      if (old_size == 0)
   10559   1.1  christos 		{
   10560   1.1  christos 		  /* Only the first zero-sized unreachable entry is
   10561   1.1  christos 		     allowed to expand.  In this case the new offset
   10562   1.1  christos 		     should be the offset before the fill and the new
   10563   1.1  christos 		     size is the expansion size.  For other zero-sized
   10564   1.1  christos 		     entries the resulting size should be zero with an
   10565   1.1  christos 		     offset before or after the fill address depending
   10566   1.1  christos 		     on whether the expanding unreachable entry
   10567   1.1  christos 		     preceeds it.  */
   10568   1.1  christos 		  if (last_zfill_target_sec == 0
   10569   1.1  christos 		      || last_zfill_target_sec != target_sec
   10570   1.3  christos 		      || last_zfill_target_offset != old_offset)
   10571   1.3  christos 		    {
   10572   1.3  christos 		      bfd_vma new_end_offset = new_offset;
   10573   1.8  christos 
   10574   1.3  christos 		      /* Recompute the new_offset, but this time don't
   10575   1.3  christos 			 include any fill inserted by relaxation.  */
   10576   1.1  christos 		      removed_by_old_offset =
   10577   1.1  christos 			removed_by_actions_map (&target_relax_info->action_list,
   10578   1.1  christos 						old_offset, true);
   10579   1.1  christos 		      new_offset = old_offset - removed_by_old_offset;
   10580   1.1  christos 
   10581   1.1  christos 		      /* If it is not unreachable and we have not yet
   10582   1.1  christos 			 seen an unreachable at this address, place it
   10583   1.1  christos 			 before the fill address.  */
   10584   1.1  christos 		      if (flags_p && (bfd_get_32 (abfd, flags_p)
   10585   1.1  christos 				      & XTENSA_PROP_UNREACHABLE) != 0)
   10586   1.1  christos 			{
   10587   1.1  christos 			  new_size = new_end_offset - new_offset;
   10588   1.1  christos 
   10589   1.1  christos 			  last_zfill_target_sec = target_sec;
   10590   1.1  christos 			  last_zfill_target_offset = old_offset;
   10591   1.1  christos 			}
   10592   1.1  christos 		    }
   10593   1.1  christos 		}
   10594   1.1  christos 	      else
   10595   1.1  christos 		{
   10596   1.1  christos 		  int removed_by_old_offset_size =
   10597   1.3  christos 		    removed_by_actions_map (&target_relax_info->action_list,
   10598   1.1  christos 					    old_offset + old_size, true);
   10599   1.1  christos 		  new_size -= removed_by_old_offset_size - removed_by_old_offset;
   10600   1.1  christos 		}
   10601   1.1  christos 
   10602   1.1  christos 	      if (new_size != old_size)
   10603   1.1  christos 		{
   10604   1.1  christos 		  bfd_put_32 (abfd, new_size, size_p);
   10605   1.1  christos 		  pin_contents (sec, contents);
   10606   1.1  christos 		}
   10607   1.1  christos 
   10608   1.1  christos 	      if (new_offset != old_offset)
   10609   1.6  christos 		{
   10610   1.1  christos 		  bfd_vma diff = new_offset - old_offset;
   10611   1.1  christos 		  irel->r_addend += diff;
   10612   1.1  christos 		  pin_internal_relocs (sec, internal_relocs);
   10613   1.1  christos 		}
   10614   1.1  christos 	    }
   10615   1.1  christos 	}
   10616   1.1  christos     }
   10617   1.1  christos 
   10618   1.1  christos   /* Combine adjacent property table entries.  This is also done in
   10619   1.1  christos      finish_dynamic_sections() but at that point it's too late to
   10620   1.1  christos      reclaim the space in the output section, so we do this twice.  */
   10621   1.1  christos 
   10622   1.1  christos   if (internal_relocs && (!bfd_link_relocatable (link_info)
   10623   1.1  christos 			  || xtensa_is_littable_section (sec)))
   10624   1.1  christos     {
   10625   1.8  christos       Elf_Internal_Rela *last_irel = NULL;
   10626   1.1  christos       Elf_Internal_Rela *irel, *next_rel, *rel_end;
   10627   1.1  christos       int removed_bytes = 0;
   10628   1.1  christos       bfd_vma offset;
   10629   1.1  christos       flagword predef_flags;
   10630   1.1  christos 
   10631   1.1  christos       predef_flags = xtensa_get_property_predef_flags (sec);
   10632   1.1  christos 
   10633   1.1  christos       /* Walk over memory and relocations at the same time.
   10634   1.1  christos 	 This REQUIRES that the internal_relocs be sorted by offset.  */
   10635   1.1  christos       qsort (internal_relocs, sec->reloc_count, sizeof (Elf_Internal_Rela),
   10636   1.1  christos 	     internal_reloc_compare);
   10637   1.1  christos 
   10638   1.1  christos       pin_internal_relocs (sec, internal_relocs);
   10639   1.1  christos       pin_contents (sec, contents);
   10640   1.1  christos 
   10641   1.1  christos       next_rel = internal_relocs;
   10642   1.1  christos       rel_end = internal_relocs + sec->reloc_count;
   10643   1.1  christos 
   10644   1.1  christos       BFD_ASSERT (sec->size % entry_size == 0);
   10645   1.1  christos 
   10646   1.1  christos       for (offset = 0; offset < sec->size; offset += entry_size)
   10647   1.1  christos 	{
   10648   1.1  christos 	  Elf_Internal_Rela *offset_rel, *extra_rel;
   10649   1.1  christos 	  bfd_vma bytes_to_remove, size, actual_offset;
   10650   1.1  christos 	  bool remove_this_rel;
   10651   1.1  christos 	  flagword flags;
   10652   1.1  christos 
   10653   1.1  christos 	  /* Find the first relocation for the entry at the current offset.
   10654   1.1  christos 	     Adjust the offsets of any extra relocations for the previous
   10655   1.1  christos 	     entry.  */
   10656   1.1  christos 	  offset_rel = NULL;
   10657   1.1  christos 	  if (next_rel)
   10658   1.1  christos 	    {
   10659   1.1  christos 	      for (irel = next_rel; irel < rel_end; irel++)
   10660   1.1  christos 		{
   10661   1.1  christos 		  if ((irel->r_offset == offset
   10662   1.1  christos 		       && ELF32_R_TYPE (irel->r_info) != R_XTENSA_NONE)
   10663   1.1  christos 		      || irel->r_offset > offset)
   10664   1.1  christos 		    {
   10665   1.1  christos 		      offset_rel = irel;
   10666   1.1  christos 		      break;
   10667   1.1  christos 		    }
   10668   1.1  christos 		  irel->r_offset -= removed_bytes;
   10669   1.1  christos 		}
   10670   1.1  christos 	    }
   10671   1.1  christos 
   10672   1.1  christos 	  /* Find the next relocation (if there are any left).  */
   10673   1.1  christos 	  extra_rel = NULL;
   10674   1.1  christos 	  if (offset_rel)
   10675   1.1  christos 	    {
   10676   1.1  christos 	      for (irel = offset_rel + 1; irel < rel_end; irel++)
   10677   1.1  christos 		{
   10678   1.1  christos 		  if (ELF32_R_TYPE (irel->r_info) != R_XTENSA_NONE)
   10679   1.1  christos 		    {
   10680   1.1  christos 		      extra_rel = irel;
   10681   1.1  christos 		      break;
   10682   1.1  christos 		    }
   10683   1.1  christos 		}
   10684   1.1  christos 	    }
   10685   1.1  christos 
   10686   1.1  christos 	  /* Check if there are relocations on the current entry.  There
   10687   1.1  christos 	     should usually be a relocation on the offset field.  If there
   10688   1.1  christos 	     are relocations on the size or flags, then we can't optimize
   10689   1.1  christos 	     this entry.  Also, find the next relocation to examine on the
   10690   1.1  christos 	     next iteration.  */
   10691   1.1  christos 	  if (offset_rel)
   10692   1.1  christos 	    {
   10693   1.1  christos 	      if (offset_rel->r_offset >= offset + entry_size)
   10694   1.8  christos 		{
   10695   1.1  christos 		  next_rel = offset_rel;
   10696   1.1  christos 		  /* There are no relocations on the current entry, but we
   10697   1.1  christos 		     might still be able to remove it if the size is zero.  */
   10698   1.1  christos 		  offset_rel = NULL;
   10699   1.3  christos 		}
   10700   1.1  christos 	      else if (offset_rel->r_offset > offset
   10701   1.1  christos 		       || (extra_rel
   10702   1.1  christos 			   && extra_rel->r_offset < offset + entry_size))
   10703   1.1  christos 		{
   10704   1.1  christos 		  /* There is a relocation on the size or flags, so we can't
   10705   1.1  christos 		     do anything with this entry.  Continue with the next.  */
   10706   1.1  christos 		  next_rel = offset_rel;
   10707   1.1  christos 		  continue;
   10708   1.1  christos 		}
   10709   1.1  christos 	      else
   10710   1.1  christos 		{
   10711   1.8  christos 		  BFD_ASSERT (offset_rel->r_offset == offset);
   10712   1.1  christos 		  offset_rel->r_offset -= removed_bytes;
   10713   1.1  christos 		  next_rel = offset_rel + 1;
   10714   1.1  christos 		}
   10715   1.1  christos 	    }
   10716   1.1  christos 	  else
   10717   1.1  christos 	    next_rel = NULL;
   10718   1.1  christos 
   10719   1.1  christos 	  remove_this_rel = false;
   10720   1.1  christos 	  bytes_to_remove = 0;
   10721   1.1  christos 	  actual_offset = offset - removed_bytes;
   10722   1.1  christos 	  size = bfd_get_32 (abfd, &contents[actual_offset + 4]);
   10723   1.1  christos 
   10724   1.1  christos 	  if (is_full_prop_section)
   10725   1.1  christos 	    flags = bfd_get_32 (abfd, &contents[actual_offset + 8]);
   10726   1.1  christos 	  else
   10727   1.3  christos 	    flags = predef_flags;
   10728   1.1  christos 
   10729   1.1  christos 	  if (size == 0
   10730   1.1  christos 	      && (flags & XTENSA_PROP_ALIGN) == 0
   10731   1.1  christos 	      && (flags & XTENSA_PROP_UNREACHABLE) == 0)
   10732   1.1  christos 	    {
   10733   1.1  christos 	      /* Always remove entries with zero size and no alignment.  */
   10734   1.1  christos 	      bytes_to_remove = entry_size;
   10735   1.1  christos 	      if (offset_rel)
   10736   1.1  christos 		remove_this_rel = true;
   10737   1.1  christos 	    }
   10738   1.1  christos 	  else if (offset_rel
   10739   1.1  christos 		   && ELF32_R_TYPE (offset_rel->r_info) == R_XTENSA_32)
   10740   1.1  christos 	    {
   10741   1.1  christos 	      if (last_irel)
   10742   1.1  christos 		{
   10743   1.1  christos 		  flagword old_flags;
   10744   1.8  christos 		  bfd_vma old_size =
   10745   1.1  christos 		    bfd_get_32 (abfd, &contents[last_irel->r_offset + 4]);
   10746   1.1  christos 		  bfd_vma old_address =
   10747   1.1  christos 		    (last_irel->r_addend
   10748   1.1  christos 		     + bfd_get_32 (abfd, &contents[last_irel->r_offset]));
   10749   1.1  christos 		  bfd_vma new_address =
   10750   1.1  christos 		    (offset_rel->r_addend
   10751   1.1  christos 		     + bfd_get_32 (abfd, &contents[actual_offset]));
   10752   1.1  christos 		  if (is_full_prop_section)
   10753   1.1  christos 		    old_flags = bfd_get_32
   10754   1.1  christos 		      (abfd, &contents[last_irel->r_offset + 8]);
   10755   1.1  christos 		  else
   10756   1.1  christos 		    old_flags = predef_flags;
   10757   1.1  christos 
   10758   1.1  christos 		  if ((ELF32_R_SYM (offset_rel->r_info)
   10759   1.1  christos 		       == ELF32_R_SYM (last_irel->r_info))
   10760   1.1  christos 		      && old_address + old_size == new_address
   10761   1.1  christos 		      && old_flags == flags
   10762   1.1  christos 		      && (old_flags & XTENSA_PROP_INSN_BRANCH_TARGET) == 0
   10763   1.1  christos 		      && (old_flags & XTENSA_PROP_INSN_LOOP_TARGET) == 0)
   10764   1.1  christos 		    {
   10765   1.1  christos 		      /* Fix the old size.  */
   10766   1.1  christos 		      bfd_put_32 (abfd, old_size + size,
   10767   1.1  christos 				  &contents[last_irel->r_offset + 4]);
   10768   1.1  christos 		      bytes_to_remove = entry_size;
   10769   1.1  christos 		      remove_this_rel = true;
   10770   1.1  christos 		    }
   10771   1.1  christos 		  else
   10772   1.1  christos 		    last_irel = offset_rel;
   10773   1.1  christos 		}
   10774   1.1  christos 	      else
   10775   1.1  christos 		last_irel = offset_rel;
   10776   1.1  christos 	    }
   10777   1.1  christos 
   10778   1.1  christos 	  if (remove_this_rel)
   10779   1.1  christos 	    {
   10780   1.1  christos 	      offset_rel->r_info = ELF32_R_INFO (0, R_XTENSA_NONE);
   10781   1.1  christos 	      offset_rel->r_offset = 0;
   10782   1.1  christos 	    }
   10783   1.1  christos 
   10784   1.1  christos 	  if (bytes_to_remove != 0)
   10785   1.1  christos 	    {
   10786   1.1  christos 	      removed_bytes += bytes_to_remove;
   10787   1.1  christos 	      if (offset + bytes_to_remove < sec->size)
   10788   1.1  christos 		memmove (&contents[actual_offset],
   10789   1.1  christos 			 &contents[actual_offset + bytes_to_remove],
   10790   1.1  christos 			 sec->size - offset - bytes_to_remove);
   10791   1.1  christos 	    }
   10792   1.1  christos 	}
   10793   1.1  christos 
   10794   1.1  christos       if (removed_bytes)
   10795   1.1  christos 	{
   10796   1.1  christos 	  /* Fix up any extra relocations on the last entry.  */
   10797   1.1  christos 	  for (irel = next_rel; irel < rel_end; irel++)
   10798   1.1  christos 	    irel->r_offset -= removed_bytes;
   10799   1.1  christos 
   10800   1.1  christos 	  /* Clear the removed bytes.  */
   10801   1.1  christos 	  memset (&contents[sec->size - removed_bytes], 0, removed_bytes);
   10802   1.8  christos 
   10803   1.1  christos 	  if (sec->rawsize == 0)
   10804   1.1  christos 	    sec->rawsize = sec->size;
   10805   1.1  christos 	  sec->size -= removed_bytes;
   10806   1.1  christos 
   10807   1.1  christos 	  if (xtensa_is_littable_section (sec))
   10808   1.1  christos 	    {
   10809   1.1  christos 	      asection *sgotloc = elf_xtensa_hash_table (link_info)->sgotloc;
   10810   1.1  christos 	      if (sgotloc)
   10811   1.1  christos 		sgotloc->size -= removed_bytes;
   10812   1.1  christos 	    }
   10813   1.1  christos 	}
   10814   1.1  christos     }
   10815   1.1  christos 
   10816   1.8  christos  error_return:
   10817   1.1  christos   release_internal_relocs (sec, internal_relocs);
   10818   1.1  christos   release_contents (sec, contents);
   10819   1.1  christos   return ok;
   10820   1.1  christos }
   10821   1.1  christos 
   10822   1.1  christos 
   10823   1.1  christos /* Third relaxation pass.  */
   10825   1.1  christos 
   10826   1.1  christos /* Change symbol values to account for removed literals.  */
   10827   1.1  christos 
   10828   1.1  christos bool
   10829   1.1  christos relax_section_symbols (bfd *abfd, asection *sec)
   10830   1.1  christos {
   10831   1.1  christos   xtensa_relax_info *relax_info;
   10832   1.1  christos   unsigned int sec_shndx;
   10833   1.1  christos   Elf_Internal_Shdr *symtab_hdr;
   10834   1.3  christos   Elf_Internal_Sym *isymbuf;
   10835   1.8  christos   unsigned i, num_syms, num_locals;
   10836   1.1  christos 
   10837   1.3  christos   relax_info = get_xtensa_relax_info (sec);
   10838   1.1  christos   BFD_ASSERT (relax_info);
   10839   1.1  christos 
   10840   1.3  christos   if (!relax_info->is_relaxable_literal_section
   10841   1.8  christos       && !relax_info->is_relaxable_asm_section)
   10842   1.3  christos     return true;
   10843   1.1  christos 
   10844   1.1  christos   sec_shndx = _bfd_elf_section_from_bfd_section (abfd, sec);
   10845   1.1  christos 
   10846   1.1  christos   symtab_hdr = &elf_tdata (abfd)->symtab_hdr;
   10847   1.1  christos   isymbuf = retrieve_local_syms (abfd);
   10848   1.1  christos 
   10849   1.1  christos   num_syms = symtab_hdr->sh_size / sizeof (Elf32_External_Sym);
   10850   1.1  christos   num_locals = symtab_hdr->sh_info;
   10851   1.1  christos 
   10852   1.1  christos   /* Adjust the local symbols defined in this section.  */
   10853   1.1  christos   for (i = 0; i < num_locals; i++)
   10854   1.1  christos     {
   10855   1.1  christos       Elf_Internal_Sym *isym = &isymbuf[i];
   10856   1.1  christos 
   10857   1.1  christos       if (isym->st_shndx == sec_shndx)
   10858   1.1  christos 	{
   10859   1.1  christos 	  bfd_vma orig_addr = isym->st_value;
   10860   1.1  christos 	  int removed = removed_by_actions_map (&relax_info->action_list,
   10861   1.3  christos 						orig_addr, false);
   10862   1.8  christos 
   10863   1.1  christos 	  isym->st_value -= removed;
   10864   1.3  christos 	  if (ELF32_ST_TYPE (isym->st_info) == STT_FUNC)
   10865   1.1  christos 	    isym->st_size -=
   10866   1.1  christos 	      removed_by_actions_map (&relax_info->action_list,
   10867   1.1  christos 				      orig_addr + isym->st_size, false) -
   10868   1.3  christos 	      removed;
   10869   1.8  christos 	}
   10870   1.3  christos     }
   10871   1.1  christos 
   10872   1.1  christos   /* Now adjust the global symbols defined in this section.  */
   10873   1.1  christos   for (i = 0; i < (num_syms - num_locals); i++)
   10874   1.8  christos     {
   10875   1.1  christos       struct elf_link_hash_entry *sym_hash;
   10876   1.1  christos 
   10877   1.1  christos       sym_hash = elf_sym_hashes (abfd)[i];
   10878   1.1  christos 
   10879   1.1  christos       if (sym_hash->root.type == bfd_link_hash_warning)
   10880   1.8  christos 	sym_hash = (struct elf_link_hash_entry *) sym_hash->root.u.i.link;
   10881   1.1  christos 
   10882   1.1  christos       if ((sym_hash->root.type == bfd_link_hash_defined
   10883   1.1  christos 	   || sym_hash->root.type == bfd_link_hash_defweak)
   10884   1.1  christos 	  && sym_hash->root.u.def.section == sec)
   10885   1.1  christos 	{
   10886   1.1  christos 	  bfd_vma orig_addr = sym_hash->root.u.def.value;
   10887   1.1  christos 	  int removed = removed_by_actions_map (&relax_info->action_list,
   10888   1.1  christos 						orig_addr, false);
   10889   1.1  christos 
   10890   1.1  christos 	  sym_hash->root.u.def.value -= removed;
   10891   1.1  christos 
   10892   1.1  christos 	  if (sym_hash->type == STT_FUNC)
   10893   1.8  christos 	    sym_hash->size -=
   10894   1.1  christos 	      removed_by_actions_map (&relax_info->action_list,
   10895   1.1  christos 				      orig_addr + sym_hash->size, false) -
   10896   1.1  christos 	      removed;
   10897   1.8  christos 	}
   10898   1.1  christos     }
   10899   1.1  christos 
   10900   1.1  christos   return true;
   10901   1.1  christos }
   10902   1.1  christos 
   10903   1.1  christos 
   10904   1.1  christos /* "Fix" handling functions, called while performing relocations.  */
   10906   1.1  christos 
   10907   1.1  christos static bool
   10908   1.6  christos do_fix_for_relocatable_link (Elf_Internal_Rela *rel,
   10909   1.6  christos 			     bfd *input_bfd,
   10910   1.6  christos 			     asection *input_section,
   10911   1.6  christos 			     bfd_byte *contents)
   10912   1.1  christos {
   10913   1.8  christos   r_reloc r_rel;
   10914   1.1  christos   asection *sec, *old_sec;
   10915   1.1  christos   bfd_vma old_offset;
   10916   1.1  christos   int r_type = ELF32_R_TYPE (rel->r_info);
   10917   1.1  christos   reloc_bfd_fix *fix;
   10918   1.1  christos 
   10919   1.1  christos   if (r_type == R_XTENSA_NONE)
   10920   1.1  christos     return true;
   10921   1.1  christos 
   10922   1.1  christos   fix = get_bfd_fix (input_section, rel->r_offset, r_type);
   10923   1.8  christos   if (!fix)
   10924   1.1  christos     return true;
   10925   1.1  christos 
   10926   1.1  christos   r_reloc_init (&r_rel, input_bfd, rel, contents,
   10927   1.1  christos 		bfd_get_section_limit (input_bfd, input_section));
   10928   1.1  christos   old_sec = r_reloc_get_section (&r_rel);
   10929   1.1  christos   old_offset = r_rel.target_offset;
   10930   1.1  christos 
   10931   1.1  christos   if (!old_sec || !r_reloc_is_defined (&r_rel))
   10932   1.1  christos     {
   10933   1.1  christos       if (r_type != R_XTENSA_ASM_EXPAND)
   10934   1.1  christos 	{
   10935   1.1  christos 	  _bfd_error_handler
   10936   1.1  christos 	    /* xgettext:c-format */
   10937   1.1  christos 	    (_("%pB(%pA+%#" PRIx64 "): unexpected fix for %s relocation"),
   10938   1.1  christos 	     input_bfd, input_section, (uint64_t) rel->r_offset,
   10939   1.1  christos 	     elf_howto_table[r_type].name);
   10940   1.1  christos 	  return false;
   10941   1.1  christos 	}
   10942   1.1  christos       /* Leave it be.  Resolution will happen in a later stage.  */
   10943   1.1  christos     }
   10944   1.1  christos   else
   10945   1.1  christos     {
   10946   1.1  christos       sec = fix->target_sec;
   10947   1.1  christos       rel->r_addend += ((sec->output_offset + fix->target_offset)
   10948   1.1  christos 			- (old_sec->output_offset + old_offset));
   10949   1.1  christos     }
   10950   1.1  christos   return true;
   10951   1.1  christos }
   10952   1.1  christos 
   10953   1.1  christos 
   10954   1.1  christos static void
   10955   1.1  christos do_fix_for_final_link (Elf_Internal_Rela *rel,
   10956   1.1  christos 		       bfd *input_bfd,
   10957   1.1  christos 		       asection *input_section,
   10958   1.1  christos 		       bfd_byte *contents,
   10959   1.1  christos 		       bfd_vma *relocationp)
   10960   1.1  christos {
   10961   1.1  christos   asection *sec;
   10962   1.1  christos   int r_type = ELF32_R_TYPE (rel->r_info);
   10963   1.1  christos   reloc_bfd_fix *fix;
   10964   1.1  christos   bfd_vma fixup_diff;
   10965   1.1  christos 
   10966   1.1  christos   if (r_type == R_XTENSA_NONE)
   10967   1.1  christos     return;
   10968   1.1  christos 
   10969   1.1  christos   fix = get_bfd_fix (input_section, rel->r_offset, r_type);
   10970   1.6  christos   if (!fix)
   10971   1.1  christos     return;
   10972   1.1  christos 
   10973   1.6  christos   sec = fix->target_sec;
   10974   1.1  christos 
   10975   1.1  christos   fixup_diff = rel->r_addend;
   10976   1.1  christos   if (elf_howto_table[fix->src_type].partial_inplace)
   10977   1.1  christos     {
   10978   1.1  christos       bfd_vma inplace_val;
   10979   1.1  christos       BFD_ASSERT (fix->src_offset
   10980   1.1  christos 		  < bfd_get_section_limit (input_bfd, input_section));
   10981   1.1  christos       inplace_val = bfd_get_32 (input_bfd, &contents[fix->src_offset]);
   10982   1.1  christos       fixup_diff += inplace_val;
   10983   1.1  christos     }
   10984   1.1  christos 
   10985   1.6  christos   *relocationp = (sec->output_section->vma
   10986   1.1  christos 		  + sec->output_offset
   10987   1.1  christos 		  + fix->target_offset - fixup_diff);
   10988   1.6  christos }
   10989   1.1  christos 
   10990   1.1  christos 
   10991   1.1  christos /* Miscellaneous utility functions....  */
   10993   1.1  christos 
   10994   1.1  christos static asection *
   10995   1.1  christos elf_xtensa_get_plt_section (struct bfd_link_info *info, int chunk)
   10996   1.1  christos {
   10997   1.1  christos   bfd *dynobj;
   10998   1.1  christos   char plt_name[17];
   10999   1.1  christos 
   11000   1.1  christos   if (chunk == 0)
   11001   1.1  christos     return elf_hash_table (info)->splt;
   11002   1.1  christos 
   11003   1.1  christos   dynobj = elf_hash_table (info)->dynobj;
   11004   1.1  christos   sprintf (plt_name, ".plt.%u", chunk);
   11005   1.1  christos   return bfd_get_linker_section (dynobj, plt_name);
   11006   1.1  christos }
   11007   1.1  christos 
   11008   1.1  christos 
   11009   1.1  christos static asection *
   11010   1.1  christos elf_xtensa_get_gotplt_section (struct bfd_link_info *info, int chunk)
   11011   1.1  christos {
   11012   1.1  christos   bfd *dynobj;
   11013   1.1  christos   char got_name[21];
   11014   1.1  christos 
   11015   1.1  christos   if (chunk == 0)
   11016   1.1  christos     return elf_hash_table (info)->sgotplt;
   11017   1.1  christos 
   11018   1.1  christos   dynobj = elf_hash_table (info)->dynobj;
   11019   1.1  christos   sprintf (got_name, ".got.plt.%u", chunk);
   11020   1.1  christos   return bfd_get_linker_section (dynobj, got_name);
   11021   1.1  christos }
   11022   1.1  christos 
   11023   1.1  christos 
   11024   1.1  christos /* Get the input section for a given symbol index.
   11025   1.1  christos    If the symbol is:
   11026   1.1  christos    . a section symbol, return the section;
   11027   1.1  christos    . a common symbol, return the common section;
   11028   1.1  christos    . an undefined symbol, return the undefined section;
   11029   1.1  christos    . an indirect symbol, follow the links;
   11030   1.1  christos    . an absolute value, return the absolute section.  */
   11031   1.1  christos 
   11032   1.6  christos static asection *
   11033   1.6  christos get_elf_r_symndx_section (bfd *abfd, unsigned long r_symndx)
   11034   1.1  christos {
   11035   1.1  christos   Elf_Internal_Shdr *symtab_hdr = &elf_tdata (abfd)->symtab_hdr;
   11036   1.1  christos   asection *target_sec = NULL;
   11037   1.1  christos   if (r_symndx < symtab_hdr->sh_info)
   11038   1.1  christos     {
   11039   1.1  christos       Elf_Internal_Sym *isymbuf;
   11040   1.1  christos       unsigned int section_index;
   11041   1.1  christos 
   11042   1.1  christos       isymbuf = retrieve_local_syms (abfd);
   11043   1.1  christos       section_index = isymbuf[r_symndx].st_shndx;
   11044   1.1  christos 
   11045   1.1  christos       if (section_index == SHN_UNDEF)
   11046   1.1  christos 	target_sec = bfd_und_section_ptr;
   11047   1.1  christos       else if (section_index == SHN_ABS)
   11048   1.1  christos 	target_sec = bfd_abs_section_ptr;
   11049   1.1  christos       else if (section_index == SHN_COMMON)
   11050   1.1  christos 	target_sec = bfd_com_section_ptr;
   11051   1.1  christos       else
   11052   1.1  christos 	target_sec = bfd_section_from_elf_index (abfd, section_index);
   11053   1.1  christos     }
   11054   1.1  christos   else
   11055   1.1  christos     {
   11056   1.1  christos       unsigned long indx = r_symndx - symtab_hdr->sh_info;
   11057   1.1  christos       struct elf_link_hash_entry *h = elf_sym_hashes (abfd)[indx];
   11058   1.1  christos 
   11059   1.1  christos       while (h->root.type == bfd_link_hash_indirect
   11060   1.1  christos 	     || h->root.type == bfd_link_hash_warning)
   11061   1.1  christos 	h = (struct elf_link_hash_entry *) h->root.u.i.link;
   11062   1.1  christos 
   11063   1.1  christos       switch (h->root.type)
   11064   1.1  christos 	{
   11065   1.1  christos 	case bfd_link_hash_defined:
   11066   1.1  christos 	case  bfd_link_hash_defweak:
   11067   1.1  christos 	  target_sec = h->root.u.def.section;
   11068   1.1  christos 	  break;
   11069   1.1  christos 	case bfd_link_hash_common:
   11070   1.1  christos 	  target_sec = bfd_com_section_ptr;
   11071   1.1  christos 	  break;
   11072   1.1  christos 	case bfd_link_hash_undefined:
   11073   1.1  christos 	case bfd_link_hash_undefweak:
   11074   1.1  christos 	  target_sec = bfd_und_section_ptr;
   11075   1.1  christos 	  break;
   11076   1.1  christos 	default: /* New indirect warning.  */
   11077   1.1  christos 	  target_sec = bfd_und_section_ptr;
   11078   1.1  christos 	  break;
   11079   1.1  christos 	}
   11080   1.1  christos     }
   11081   1.1  christos   return target_sec;
   11082   1.1  christos }
   11083   1.1  christos 
   11084   1.1  christos 
   11085   1.1  christos static struct elf_link_hash_entry *
   11086   1.1  christos get_elf_r_symndx_hash_entry (bfd *abfd, unsigned long r_symndx)
   11087   1.1  christos {
   11088   1.1  christos   unsigned long indx;
   11089   1.1  christos   struct elf_link_hash_entry *h;
   11090   1.1  christos   Elf_Internal_Shdr *symtab_hdr = &elf_tdata (abfd)->symtab_hdr;
   11091   1.1  christos 
   11092   1.1  christos   if (r_symndx < symtab_hdr->sh_info)
   11093   1.1  christos     return NULL;
   11094   1.1  christos 
   11095   1.1  christos   indx = r_symndx - symtab_hdr->sh_info;
   11096   1.1  christos   h = elf_sym_hashes (abfd)[indx];
   11097   1.6  christos   while (h->root.type == bfd_link_hash_indirect
   11098   1.1  christos 	 || h->root.type == bfd_link_hash_warning)
   11099   1.1  christos     h = (struct elf_link_hash_entry *) h->root.u.i.link;
   11100   1.6  christos   return h;
   11101   1.1  christos }
   11102   1.1  christos 
   11103   1.1  christos 
   11104   1.1  christos /* Get the section-relative offset for a symbol number.  */
   11105   1.1  christos 
   11106   1.1  christos static bfd_vma
   11107   1.8  christos get_elf_r_symndx_offset (bfd *abfd, unsigned long r_symndx)
   11108   1.1  christos {
   11109   1.1  christos   Elf_Internal_Shdr *symtab_hdr = &elf_tdata (abfd)->symtab_hdr;
   11110   1.1  christos   bfd_vma offset = 0;
   11111   1.1  christos 
   11112   1.1  christos   if (r_symndx < symtab_hdr->sh_info)
   11113   1.1  christos     {
   11114   1.1  christos       Elf_Internal_Sym *isymbuf;
   11115   1.8  christos       isymbuf = retrieve_local_syms (abfd);
   11116   1.8  christos       offset = isymbuf[r_symndx].st_value;
   11117   1.1  christos     }
   11118   1.1  christos   else
   11119   1.1  christos     {
   11120   1.8  christos       unsigned long indx = r_symndx - symtab_hdr->sh_info;
   11121   1.1  christos       struct elf_link_hash_entry *h =
   11122   1.1  christos 	elf_sym_hashes (abfd)[indx];
   11123   1.1  christos 
   11124   1.1  christos       while (h->root.type == bfd_link_hash_indirect
   11125   1.1  christos 	     || h->root.type == bfd_link_hash_warning)
   11126   1.1  christos 	h = (struct elf_link_hash_entry *) h->root.u.i.link;
   11127   1.1  christos       if (h->root.type == bfd_link_hash_defined
   11128   1.1  christos 	  || h->root.type == bfd_link_hash_defweak)
   11129   1.1  christos 	offset = h->root.u.def.value;
   11130   1.8  christos     }
   11131   1.8  christos   return offset;
   11132   1.1  christos }
   11133   1.1  christos 
   11134   1.1  christos 
   11135   1.8  christos static bool
   11136   1.1  christos is_reloc_sym_weak (bfd *abfd, Elf_Internal_Rela *rel)
   11137   1.1  christos {
   11138   1.1  christos   unsigned long r_symndx = ELF32_R_SYM (rel->r_info);
   11139   1.1  christos   struct elf_link_hash_entry *h;
   11140   1.1  christos 
   11141   1.8  christos   h = get_elf_r_symndx_hash_entry (abfd, r_symndx);
   11142   1.1  christos   if (h && h->root.type == bfd_link_hash_defweak)
   11143   1.8  christos     return true;
   11144   1.1  christos   return false;
   11145   1.1  christos }
   11146   1.1  christos 
   11147   1.8  christos 
   11148   1.1  christos static bool
   11149   1.1  christos pcrel_reloc_fits (xtensa_opcode opc,
   11150   1.8  christos 		  int opnd,
   11151   1.8  christos 		  bfd_vma self_address,
   11152   1.8  christos 		  bfd_vma dest_address)
   11153   1.1  christos {
   11154   1.8  christos   xtensa_isa isa = xtensa_default_isa;
   11155   1.1  christos   uint32 valp = dest_address;
   11156   1.1  christos   if (xtensa_operand_do_reloc (isa, opc, opnd, &valp, self_address)
   11157   1.1  christos       || xtensa_operand_encode (isa, opc, opnd, &valp))
   11158   1.8  christos     return false;
   11159   1.1  christos   return true;
   11160   1.1  christos }
   11161   1.8  christos 
   11162   1.8  christos 
   11163   1.8  christos static bool
   11164   1.1  christos xtensa_is_property_section (asection *sec)
   11165   1.8  christos {
   11166   1.1  christos   if (xtensa_is_insntable_section (sec)
   11167   1.1  christos       || xtensa_is_littable_section (sec)
   11168   1.1  christos       || xtensa_is_proptable_section (sec))
   11169   1.8  christos     return true;
   11170   1.1  christos 
   11171   1.1  christos   return false;
   11172   1.8  christos }
   11173   1.8  christos 
   11174   1.8  christos 
   11175   1.1  christos static bool
   11176   1.8  christos xtensa_is_insntable_section (asection *sec)
   11177   1.1  christos {
   11178   1.1  christos   if (startswith (sec->name, XTENSA_INSN_SEC_NAME)
   11179   1.1  christos       || startswith (sec->name, ".gnu.linkonce.x."))
   11180   1.1  christos     return true;
   11181   1.1  christos 
   11182   1.1  christos   return false;
   11183   1.1  christos }
   11184   1.1  christos 
   11185   1.1  christos 
   11186   1.1  christos static bool
   11187   1.1  christos xtensa_is_littable_section (asection *sec)
   11188   1.1  christos {
   11189   1.1  christos   if (startswith (sec->name, XTENSA_LIT_SEC_NAME)
   11190   1.1  christos       || startswith (sec->name, ".gnu.linkonce.p."))
   11191   1.1  christos     return true;
   11192   1.1  christos 
   11193   1.1  christos   return false;
   11194   1.1  christos }
   11195   1.1  christos 
   11196   1.1  christos 
   11197   1.1  christos static bool
   11198   1.1  christos xtensa_is_proptable_section (asection *sec)
   11199   1.1  christos {
   11200   1.1  christos   if (startswith (sec->name, XTENSA_PROP_SEC_NAME)
   11201   1.1  christos       || startswith (sec->name, ".gnu.linkonce.prop."))
   11202   1.1  christos     return true;
   11203   1.1  christos 
   11204   1.1  christos   return false;
   11205   1.1  christos }
   11206   1.1  christos 
   11207   1.1  christos 
   11208   1.1  christos static int
   11209   1.1  christos internal_reloc_compare (const void *ap, const void *bp)
   11210   1.1  christos {
   11211   1.1  christos   const Elf_Internal_Rela *a = (const Elf_Internal_Rela *) ap;
   11212   1.1  christos   const Elf_Internal_Rela *b = (const Elf_Internal_Rela *) bp;
   11213   1.1  christos 
   11214   1.1  christos   if (a->r_offset != b->r_offset)
   11215   1.1  christos     return (a->r_offset - b->r_offset);
   11216   1.1  christos 
   11217   1.8  christos   /* We don't need to sort on these criteria for correctness,
   11218   1.1  christos      but enforcing a more strict ordering prevents unstable qsort
   11219   1.1  christos      from behaving differently with different implementations.
   11220   1.1  christos      Without the code below we get correct but different results
   11221   1.1  christos      on Solaris 2.7 and 2.8.  We would like to always produce the
   11222   1.3  christos      same results no matter the host.  */
   11223   1.1  christos 
   11224   1.1  christos   if (a->r_info != b->r_info)
   11225   1.1  christos     return (a->r_info - b->r_info);
   11226   1.1  christos 
   11227   1.1  christos   return (a->r_addend - b->r_addend);
   11228   1.1  christos }
   11229   1.1  christos 
   11230   1.6  christos 
   11231   1.6  christos static int
   11232   1.6  christos internal_reloc_matches (const void *ap, const void *bp)
   11233   1.6  christos {
   11234   1.6  christos   const Elf_Internal_Rela *a = (const Elf_Internal_Rela *) ap;
   11235   1.6  christos   const Elf_Internal_Rela *b = (const Elf_Internal_Rela *) bp;
   11236   1.6  christos 
   11237   1.6  christos   /* Check if one entry overlaps with the other; this shouldn't happen
   11238   1.6  christos      except when searching for a match.  */
   11239   1.6  christos   return (a->r_offset - b->r_offset);
   11240   1.6  christos }
   11241   1.6  christos 
   11242   1.6  christos 
   11243   1.6  christos /* Predicate function used to look up a section in a particular group.  */
   11244   1.6  christos 
   11245   1.6  christos static bool
   11246   1.6  christos match_section_group (bfd *abfd ATTRIBUTE_UNUSED, asection *sec, void *inf)
   11247   1.6  christos {
   11248   1.6  christos   const char *gname = inf;
   11249   1.1  christos   const char *group_name = elf_group_name (sec);
   11250   1.1  christos 
   11251  1.10  christos   return (group_name == gname
   11252   1.6  christos 	  || (group_name != NULL
   11253   1.8  christos 	      && gname != NULL
   11254   1.1  christos 	      && strcmp (group_name, gname) == 0));
   11255   1.1  christos }
   11256   1.1  christos 
   11257   1.1  christos 
   11258   1.1  christos static char *
   11259   1.1  christos xtensa_add_names (const char *base, const char *suffix)
   11260   1.1  christos {
   11261   1.1  christos   if (suffix)
   11262   1.1  christos     {
   11263   1.1  christos       size_t base_len = strlen (base);
   11264   1.6  christos       size_t suffix_len = strlen (suffix);
   11265   1.1  christos       char *str = bfd_malloc (base_len + suffix_len + 1);
   11266   1.8  christos 
   11267   1.1  christos       memcpy (str, base, base_len);
   11268   1.1  christos       memcpy (str + base_len, suffix, suffix_len + 1);
   11269   1.1  christos       return str;
   11270   1.3  christos     }
   11271   1.1  christos   else
   11272   1.3  christos     {
   11273   1.1  christos       return strdup (base);
   11274   1.1  christos     }
   11275   1.1  christos }
   11276   1.1  christos 
   11277   1.1  christos static int linkonce_len = sizeof (".gnu.linkonce.") - 1;
   11278   1.1  christos 
   11279   1.1  christos char *
   11280   1.1  christos xtensa_property_section_name (asection *sec, const char *base_name,
   11281   1.1  christos 			      bool separate_sections)
   11282   1.1  christos {
   11283   1.1  christos   const char *suffix, *group_name;
   11284   1.1  christos   char *prop_sec_name;
   11285   1.1  christos 
   11286   1.6  christos   group_name = elf_group_name (sec);
   11287   1.8  christos   if (group_name)
   11288   1.6  christos     {
   11289   1.1  christos       suffix = strrchr (sec->name, '.');
   11290   1.1  christos       if (suffix == sec->name)
   11291   1.1  christos 	suffix = 0;
   11292   1.6  christos       prop_sec_name = xtensa_add_names (base_name, suffix);
   11293   1.6  christos     }
   11294   1.6  christos   else if (startswith (sec->name, ".gnu.linkonce."))
   11295   1.6  christos     {
   11296   1.1  christos       char *linkonce_kind = 0;
   11297   1.1  christos 
   11298   1.1  christos       if (strcmp (base_name, XTENSA_INSN_SEC_NAME) == 0)
   11299   1.1  christos 	linkonce_kind = "x.";
   11300   1.1  christos       else if (strcmp (base_name, XTENSA_LIT_SEC_NAME) == 0)
   11301   1.1  christos 	linkonce_kind = "p.";
   11302   1.6  christos       else if (strcmp (base_name, XTENSA_PROP_SEC_NAME) == 0)
   11303   1.8  christos 	linkonce_kind = "prop.";
   11304   1.1  christos       else
   11305   1.1  christos 	abort ();
   11306   1.1  christos 
   11307   1.1  christos       prop_sec_name = (char *) bfd_malloc (strlen (sec->name)
   11308   1.6  christos 					   + strlen (linkonce_kind) + 1);
   11309   1.6  christos       memcpy (prop_sec_name, ".gnu.linkonce.", linkonce_len);
   11310   1.1  christos       strcpy (prop_sec_name + linkonce_len, linkonce_kind);
   11311   1.1  christos 
   11312   1.1  christos       suffix = sec->name + linkonce_len;
   11313   1.1  christos       /* For backward compatibility, replace "t." instead of inserting
   11314   1.1  christos 	 the new linkonce_kind (but not for "prop" sections).  */
   11315   1.1  christos       if (startswith (suffix, "t.") && linkonce_kind[1] == '.')
   11316   1.1  christos 	suffix += 2;
   11317   1.6  christos       strcat (prop_sec_name + linkonce_len, suffix);
   11318   1.6  christos     }
   11319   1.6  christos   else
   11320   1.6  christos     {
   11321   1.6  christos       prop_sec_name = xtensa_add_names (base_name,
   11322   1.6  christos 					separate_sections ? sec->name : NULL);
   11323   1.8  christos     }
   11324   1.6  christos 
   11325   1.6  christos   return prop_sec_name;
   11326   1.6  christos }
   11327   1.8  christos 
   11328   1.6  christos 
   11329   1.6  christos static asection *
   11330   1.6  christos xtensa_get_separate_property_section (asection *sec, const char *base_name,
   11331   1.6  christos 				      bool separate_section)
   11332   1.1  christos {
   11333   1.1  christos   char *prop_sec_name;
   11334   1.1  christos   asection *prop_sec;
   11335   1.1  christos 
   11336   1.1  christos   prop_sec_name = xtensa_property_section_name (sec, base_name,
   11337   1.1  christos 						separate_section);
   11338   1.1  christos   prop_sec = bfd_get_section_by_name_if (sec->owner, prop_sec_name,
   11339   1.1  christos 					 match_section_group,
   11340   1.1  christos 					 (void *) elf_group_name (sec));
   11341   1.1  christos   free (prop_sec_name);
   11342   1.1  christos   return prop_sec;
   11343   1.1  christos }
   11344   1.1  christos 
   11345   1.1  christos static asection *
   11346   1.1  christos xtensa_get_property_section (asection *sec, const char *base_name)
   11347   1.1  christos {
   11348   1.1  christos   asection *prop_sec;
   11349   1.1  christos 
   11350   1.1  christos   /* Try individual property section first.  */
   11351   1.1  christos   prop_sec = xtensa_get_separate_property_section (sec, base_name, true);
   11352   1.8  christos 
   11353   1.1  christos   /* Refer to a common property section if individual is not present.  */
   11354   1.1  christos   if (!prop_sec)
   11355   1.1  christos     prop_sec = xtensa_get_separate_property_section (sec, base_name, false);
   11356   1.1  christos 
   11357   1.1  christos   return prop_sec;
   11358   1.1  christos }
   11359   1.1  christos 
   11360   1.1  christos 
   11361   1.1  christos flagword
   11362   1.8  christos xtensa_get_property_predef_flags (asection *sec)
   11363   1.1  christos {
   11364   1.1  christos   if (xtensa_is_insntable_section (sec))
   11365   1.1  christos     return (XTENSA_PROP_INSN
   11366   1.1  christos 	    | XTENSA_PROP_NO_TRANSFORM
   11367   1.1  christos 	    | XTENSA_PROP_INSN_NO_REORDER);
   11368   1.1  christos 
   11369   1.1  christos   if (xtensa_is_littable_section (sec))
   11370   1.8  christos     return (XTENSA_PROP_LITERAL
   11371   1.1  christos 	    | XTENSA_PROP_NO_TRANSFORM
   11372   1.1  christos 	    | XTENSA_PROP_INSN_NO_REORDER);
   11373   1.1  christos 
   11374   1.1  christos   return 0;
   11375   1.1  christos }
   11376   1.6  christos 
   11377   1.1  christos 
   11378   1.1  christos /* Other functions called directly by the linker.  */
   11380   1.1  christos 
   11381   1.1  christos bool
   11382   1.1  christos xtensa_callback_required_dependence (bfd *abfd,
   11383   1.1  christos 				     asection *sec,
   11384   1.1  christos 				     struct bfd_link_info *link_info,
   11385   1.1  christos 				     deps_callback_t callback,
   11386   1.1  christos 				     void *closure)
   11387   1.1  christos {
   11388   1.1  christos   Elf_Internal_Rela *internal_relocs;
   11389   1.1  christos   bfd_byte *contents;
   11390   1.1  christos   unsigned i;
   11391   1.1  christos   bool ok = true;
   11392   1.1  christos   bfd_size_type sec_size;
   11393   1.1  christos 
   11394   1.1  christos   sec_size = bfd_get_section_limit (abfd, sec);
   11395   1.1  christos 
   11396   1.1  christos   /* ".plt*" sections have no explicit relocations but they contain L32R
   11397   1.1  christos      instructions that reference the corresponding ".got.plt*" sections.  */
   11398   1.1  christos   if ((sec->flags & SEC_LINKER_CREATED) != 0
   11399   1.1  christos       && startswith (sec->name, ".plt"))
   11400   1.1  christos     {
   11401   1.3  christos       asection *sgotplt;
   11402   1.1  christos 
   11403   1.1  christos       /* Find the corresponding ".got.plt*" section.  */
   11404   1.1  christos       if (sec->name[4] == '\0')
   11405   1.1  christos 	sgotplt = elf_hash_table (link_info)->sgotplt;
   11406   1.1  christos       else
   11407   1.1  christos 	{
   11408   1.1  christos 	  char got_name[14];
   11409   1.1  christos 	  int chunk = 0;
   11410   1.1  christos 
   11411   1.8  christos 	  BFD_ASSERT (sec->name[4] == '.');
   11412   1.1  christos 	  chunk = strtol (&sec->name[5], NULL, 10);
   11413   1.1  christos 
   11414   1.1  christos 	  sprintf (got_name, ".got.plt.%u", chunk);
   11415   1.1  christos 	  sgotplt = bfd_get_linker_section (sec->owner, got_name);
   11416   1.1  christos 	}
   11417   1.1  christos       BFD_ASSERT (sgotplt);
   11418   1.1  christos 
   11419   1.1  christos       /* Assume worst-case offsets: L32R at the very end of the ".plt"
   11420   1.1  christos 	 section referencing a literal at the very beginning of
   11421   1.1  christos 	 ".got.plt".  This is very close to the real dependence, anyway.  */
   11422   1.1  christos       (*callback) (sec, sec_size, sgotplt, 0, closure);
   11423   1.1  christos     }
   11424   1.1  christos 
   11425   1.1  christos   /* Only ELF files are supported for Xtensa.  Check here to avoid a segfault
   11426   1.1  christos      when building uclibc, which runs "ld -b binary /dev/null".  */
   11427   1.1  christos   if (bfd_get_flavour (abfd) != bfd_target_elf_flavour)
   11428   1.1  christos     return ok;
   11429   1.1  christos 
   11430   1.1  christos   internal_relocs = retrieve_internal_relocs (abfd, sec,
   11431   1.1  christos 					      link_info->keep_memory);
   11432   1.1  christos   if (internal_relocs == NULL
   11433   1.1  christos       || sec->reloc_count == 0)
   11434   1.1  christos     return ok;
   11435   1.1  christos 
   11436   1.1  christos   /* Cache the contents for the duration of this scan.  */
   11437   1.1  christos   contents = retrieve_contents (abfd, sec, link_info->keep_memory);
   11438   1.1  christos   if (contents == NULL && sec_size != 0)
   11439   1.1  christos     {
   11440   1.1  christos       ok = false;
   11441   1.1  christos       goto error_return;
   11442   1.1  christos     }
   11443   1.1  christos 
   11444   1.1  christos   if (!xtensa_default_isa)
   11445   1.1  christos     xtensa_default_isa = xtensa_isa_init (0, 0);
   11446   1.1  christos 
   11447   1.1  christos   for (i = 0; i < sec->reloc_count; i++)
   11448   1.1  christos     {
   11449   1.1  christos       Elf_Internal_Rela *irel = &internal_relocs[i];
   11450   1.1  christos       if (is_l32r_relocation (abfd, sec, contents, irel))
   11451   1.1  christos 	{
   11452   1.1  christos 	  r_reloc l32r_rel;
   11453   1.1  christos 	  asection *target_sec;
   11454   1.6  christos 	  bfd_vma target_offset;
   11455   1.6  christos 
   11456   1.6  christos 	  r_reloc_init (&l32r_rel, abfd, irel, contents, sec_size);
   11457   1.1  christos 	  target_sec = NULL;
   11458   1.1  christos 	  target_offset = 0;
   11459   1.1  christos 	  /* L32Rs must be local to the input file.  */
   11460   1.1  christos 	  if (r_reloc_is_defined (&l32r_rel))
   11461   1.3  christos 	    {
   11462   1.1  christos 	      target_sec = r_reloc_get_section (&l32r_rel);
   11463   1.3  christos 	      target_offset = l32r_rel.target_offset;
   11464   1.1  christos 	    }
   11465   1.1  christos 	  (*callback) (sec, irel->r_offset, target_sec, target_offset,
   11466   1.1  christos 		       closure);
   11467   1.1  christos 	}
   11468   1.1  christos     }
   11469   1.1  christos 
   11470   1.6  christos  error_return:
   11471   1.1  christos   release_internal_relocs (sec, internal_relocs);
   11472   1.1  christos   release_contents (sec, contents);
   11473   1.1  christos   return ok;
   11474   1.1  christos }
   11475   1.1  christos 
   11476   1.1  christos /* The default literal sections should always be marked as "code" (i.e.,
   11477   1.1  christos    SHF_EXECINSTR).  This is particularly important for the Linux kernel
   11478   1.1  christos    module loader so that the literals are not placed after the text.  */
   11479   1.6  christos static const struct bfd_elf_special_section elf_xtensa_special_sections[] =
   11480   1.1  christos {
   11481   1.1  christos   { STRING_COMMA_LEN (".fini.literal"), 0, SHT_PROGBITS, SHF_ALLOC + SHF_EXECINSTR },
   11482   1.1  christos   { STRING_COMMA_LEN (".init.literal"), 0, SHT_PROGBITS, SHF_ALLOC + SHF_EXECINSTR },
   11483   1.1  christos   { STRING_COMMA_LEN (".literal"),	0, SHT_PROGBITS, SHF_ALLOC + SHF_EXECINSTR },
   11484   1.1  christos   { STRING_COMMA_LEN (".xtensa.info"),	0, SHT_NOTE,	 0 },
   11485   1.1  christos   { NULL,			0,	0, 0,		 0 }
   11486   1.1  christos };
   11487   1.1  christos 
   11488   1.1  christos #define ELF_TARGET_ID			XTENSA_ELF_DATA
   11490   1.1  christos #ifndef ELF_ARCH
   11491   1.1  christos #define TARGET_LITTLE_SYM		xtensa_elf32_le_vec
   11492   1.1  christos #define TARGET_LITTLE_NAME		"elf32-xtensa-le"
   11493   1.1  christos #define TARGET_BIG_SYM			xtensa_elf32_be_vec
   11494   1.1  christos #define TARGET_BIG_NAME			"elf32-xtensa-be"
   11495   1.1  christos #define ELF_ARCH			bfd_arch_xtensa
   11496   1.1  christos 
   11497   1.1  christos #define ELF_MACHINE_CODE		EM_XTENSA
   11498   1.1  christos #define ELF_MACHINE_ALT1		EM_XTENSA_OLD
   11499   1.1  christos 
   11500   1.1  christos #define ELF_MAXPAGESIZE			0x1000
   11501   1.1  christos #endif /* ELF_ARCH */
   11502   1.1  christos 
   11503   1.1  christos #define elf_backend_can_gc_sections	1
   11504   1.1  christos #define elf_backend_can_refcount	1
   11505   1.1  christos #define elf_backend_plt_readonly	1
   11506   1.1  christos #define elf_backend_got_header_size	4
   11507   1.1  christos #define elf_backend_want_dynbss		0
   11508   1.1  christos #define elf_backend_want_got_plt	1
   11509   1.1  christos #define elf_backend_dtrel_excludes_plt	1
   11510  1.10  christos 
   11511  1.10  christos #define elf_info_to_howto		     elf_xtensa_info_to_howto_rela
   11512   1.6  christos 
   11513   1.1  christos #define bfd_elf32_mkobject		     elf_xtensa_mkobject
   11514   1.1  christos 
   11515   1.1  christos #define bfd_elf32_bfd_merge_private_bfd_data elf_xtensa_merge_private_bfd_data
   11516   1.1  christos #define bfd_elf32_new_section_hook	     elf_xtensa_new_section_hook
   11517   1.1  christos #define bfd_elf32_bfd_print_private_bfd_data elf_xtensa_print_private_bfd_data
   11518                 #define bfd_elf32_bfd_relax_section	     elf_xtensa_relax_section
   11519                 #define bfd_elf32_bfd_reloc_type_lookup	     elf_xtensa_reloc_type_lookup
   11520                 #define bfd_elf32_bfd_reloc_name_lookup \
   11521                   elf_xtensa_reloc_name_lookup
   11522                 #define bfd_elf32_bfd_set_private_flags	     elf_xtensa_set_private_flags
   11523                 #define bfd_elf32_bfd_link_hash_table_create elf_xtensa_link_hash_table_create
   11524                 
   11525                 #define elf_backend_adjust_dynamic_symbol    elf_xtensa_adjust_dynamic_symbol
   11526                 #define elf_backend_check_relocs	     elf_xtensa_check_relocs
   11527                 #define elf_backend_create_dynamic_sections  elf_xtensa_create_dynamic_sections
   11528                 #define elf_backend_discard_info	     elf_xtensa_discard_info
   11529                 #define elf_backend_ignore_discarded_relocs  elf_xtensa_ignore_discarded_relocs
   11530                 #define elf_backend_final_write_processing   elf_xtensa_final_write_processing
   11531                 #define elf_backend_finish_dynamic_sections  elf_xtensa_finish_dynamic_sections
   11532                 #define elf_backend_finish_dynamic_symbol    elf_xtensa_finish_dynamic_symbol
   11533                 #define elf_backend_gc_mark_hook	     elf_xtensa_gc_mark_hook
   11534                 #define elf_backend_grok_prstatus	     elf_xtensa_grok_prstatus
   11535                 #define elf_backend_grok_psinfo		     elf_xtensa_grok_psinfo
   11536                 #define elf_backend_hide_symbol		     elf_xtensa_hide_symbol
   11537                 #define elf_backend_object_p		     elf_xtensa_object_p
   11538                 #define elf_backend_reloc_type_class	     elf_xtensa_reloc_type_class
   11539                 #define elf_backend_relocate_section	     elf_xtensa_relocate_section
   11540                 #define elf_backend_late_size_sections	     elf_xtensa_late_size_sections
   11541                 #define elf_backend_early_size_sections	     elf_xtensa_early_size_sections
   11542                 #define elf_backend_omit_section_dynsym      _bfd_elf_omit_section_dynsym_all
   11543                 #define elf_backend_special_sections	     elf_xtensa_special_sections
   11544                 #define elf_backend_action_discarded	     elf_xtensa_action_discarded
   11545                 #define elf_backend_copy_indirect_symbol     elf_xtensa_copy_indirect_symbol
   11546                 
   11547                 #include "elf32-target.h"
   11548