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, ®no); 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, ®no) 4861 1.1 christos || xtensa_operand_decode (isa, opcode, L32R_TARGET_REG_OPERAND, 4862 1.1 christos ®no)) 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, ®no) 4871 1.1 christos || xtensa_operand_decode (isa, opcode, CONST16_TARGET_REG_OPERAND, 4872 1.1 christos ®no)) 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 §ion_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