1 1.1 christos /* ft32-specific support for 32-bit ELF. 2 1.1.1.7 christos Copyright (C) 2013-2024 Free Software Foundation, Inc. 3 1.1 christos 4 1.1 christos Copied from elf32-moxie.c which is.. 5 1.1.1.7 christos Copyright (C) 2009-2024 Free Software Foundation, Inc. 6 1.1 christos Free Software Foundation, Inc. 7 1.1 christos 8 1.1 christos This file is part of BFD, the Binary File Descriptor library. 9 1.1 christos 10 1.1 christos This program is free software; you can redistribute it and/or modify 11 1.1 christos it under the terms of the GNU General Public License as published by 12 1.1 christos the Free Software Foundation; either version 3 of the License, or 13 1.1 christos (at your option) any later version. 14 1.1 christos 15 1.1 christos This program is distributed in the hope that it will be useful, 16 1.1 christos but WITHOUT ANY WARRANTY; without even the implied warranty of 17 1.1 christos MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 18 1.1 christos GNU General Public License for more details. 19 1.1 christos 20 1.1 christos You should have received a copy of the GNU General Public License 21 1.1 christos along with this program; if not, write to the Free Software 22 1.1 christos Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, 23 1.1 christos MA 02110-1301, USA. */ 24 1.1 christos 25 1.1 christos #include "sysdep.h" 26 1.1 christos #include "bfd.h" 27 1.1 christos #include "libbfd.h" 28 1.1 christos #include "elf-bfd.h" 29 1.1 christos #include "elf/ft32.h" 30 1.1.1.4 christos #include "opcode/ft32.h" 31 1.1 christos 32 1.1.1.6 christos static bool debug_relax = false; 33 1.1.1.4 christos 34 1.1.1.4 christos static bfd_reloc_status_type 35 1.1.1.4 christos bfd_elf_ft32_diff_reloc (bfd *, arelent *, asymbol *, void *, 36 1.1.1.4 christos asection *, bfd *, char **); 37 1.1 christos 38 1.1 christos static reloc_howto_type ft32_elf_howto_table [] = 39 1.1 christos { 40 1.1 christos /* This reloc does nothing. */ 41 1.1 christos HOWTO (R_FT32_NONE, /* type */ 42 1.1 christos 0, /* rightshift */ 43 1.1.1.6 christos 0, /* size */ 44 1.1.1.6 christos 0, /* bitsize */ 45 1.1.1.6 christos false, /* pc_relative */ 46 1.1 christos 0, /* bitpos */ 47 1.1.1.6 christos complain_overflow_dont, /* complain_on_overflow */ 48 1.1 christos bfd_elf_generic_reloc, /* special_function */ 49 1.1 christos "R_FT32_NONE", /* name */ 50 1.1.1.6 christos false, /* partial_inplace */ 51 1.1 christos 0, /* src_mask */ 52 1.1 christos 0, /* dst_mask */ 53 1.1.1.6 christos false), /* pcrel_offset */ 54 1.1 christos 55 1.1 christos /* A 32 bit absolute relocation. */ 56 1.1 christos 57 1.1 christos HOWTO (R_FT32_32, /* type */ 58 1.1 christos 0, /* rightshift */ 59 1.1.1.6 christos 4, /* size */ 60 1.1 christos 32, /* bitsize */ 61 1.1.1.6 christos false, /* pc_relative */ 62 1.1 christos 0, /* bitpos */ 63 1.1 christos complain_overflow_bitfield, /* complain_on_overflow */ 64 1.1 christos bfd_elf_generic_reloc, /* special_function */ 65 1.1 christos "R_FT32_32", /* name */ 66 1.1.1.6 christos false, /* partial_inplace */ 67 1.1 christos 0x00000000, /* src_mask */ 68 1.1 christos 0xffffffff, /* dst_mask */ 69 1.1.1.6 christos false), /* pcrel_offset */ 70 1.1 christos 71 1.1 christos HOWTO (R_FT32_16, /* type */ 72 1.1 christos 0, /* rightshift */ 73 1.1.1.6 christos 2, /* size */ 74 1.1 christos 16, /* bitsize */ 75 1.1.1.6 christos false, /* pc_relative */ 76 1.1 christos 0, /* bitpos */ 77 1.1.1.4 christos complain_overflow_dont, /* complain_on_overflow */ 78 1.1 christos bfd_elf_generic_reloc, /* special_function */ 79 1.1 christos "R_FT32_16", /* name */ 80 1.1.1.6 christos false, /* partial_inplace */ 81 1.1 christos 0x00000000, /* src_mask */ 82 1.1 christos 0x0000ffff, /* dst_mask */ 83 1.1.1.6 christos false), /* pcrel_offset */ 84 1.1 christos 85 1.1 christos HOWTO (R_FT32_8, /* type */ 86 1.1 christos 0, /* rightshift */ 87 1.1.1.6 christos 1, /* size */ 88 1.1 christos 8, /* bitsize */ 89 1.1.1.6 christos false, /* pc_relative */ 90 1.1 christos 0, /* bitpos */ 91 1.1 christos complain_overflow_signed, /* complain_on_overflow */ 92 1.1 christos bfd_elf_generic_reloc, /* special_function */ 93 1.1 christos "R_FT32_8", /* name */ 94 1.1.1.6 christos false, /* partial_inplace */ 95 1.1 christos 0x00000000, /* src_mask */ 96 1.1 christos 0x000000ff, /* dst_mask */ 97 1.1.1.6 christos false), /* pcrel_offset */ 98 1.1 christos 99 1.1 christos HOWTO (R_FT32_10, /* type */ 100 1.1 christos 0, /* rightshift */ 101 1.1.1.6 christos 2, /* size */ 102 1.1 christos 10, /* bitsize */ 103 1.1.1.6 christos false, /* pc_relative */ 104 1.1 christos 4, /* bitpos */ 105 1.1.1.4 christos complain_overflow_bitfield, /* complain_on_overflow */ 106 1.1 christos bfd_elf_generic_reloc, /* special_function */ 107 1.1 christos "R_FT32_10", /* name */ 108 1.1.1.6 christos false, /* partial_inplace */ 109 1.1 christos 0x00000000, /* src_mask */ 110 1.1 christos 0x00003ff0, /* dst_mask */ 111 1.1.1.6 christos false), /* pcrel_offset */ 112 1.1 christos 113 1.1 christos HOWTO (R_FT32_20, /* type */ 114 1.1 christos 0, /* rightshift */ 115 1.1.1.6 christos 4, /* size */ 116 1.1 christos 20, /* bitsize */ 117 1.1.1.6 christos false, /* pc_relative */ 118 1.1 christos 0, /* bitpos */ 119 1.1 christos complain_overflow_dont, /* complain_on_overflow */ 120 1.1 christos bfd_elf_generic_reloc, /* special_function */ 121 1.1 christos "R_FT32_20", /* name */ 122 1.1.1.6 christos false, /* partial_inplace */ 123 1.1 christos 0x00000000, /* src_mask */ 124 1.1 christos 0x000fffff, /* dst_mask */ 125 1.1.1.6 christos false), /* pcrel_offset */ 126 1.1 christos 127 1.1 christos HOWTO (R_FT32_17, /* type */ 128 1.1 christos 0, /* rightshift */ 129 1.1.1.6 christos 4, /* size */ 130 1.1 christos 17, /* bitsize */ 131 1.1.1.6 christos false, /* pc_relative */ 132 1.1 christos 0, /* bitpos */ 133 1.1 christos complain_overflow_dont, /* complain_on_overflow */ 134 1.1 christos bfd_elf_generic_reloc, /* special_function */ 135 1.1 christos "R_FT32_17", /* name */ 136 1.1.1.6 christos false, /* partial_inplace */ 137 1.1 christos 0x00000000, /* src_mask */ 138 1.1 christos 0x0001ffff, /* dst_mask */ 139 1.1.1.6 christos false), /* pcrel_offset */ 140 1.1 christos 141 1.1 christos HOWTO (R_FT32_18, /* type */ 142 1.1 christos 2, /* rightshift */ 143 1.1.1.6 christos 4, /* size */ 144 1.1 christos 18, /* bitsize */ 145 1.1.1.6 christos false, /* pc_relative */ 146 1.1 christos 0, /* bitpos */ 147 1.1.1.4 christos complain_overflow_dont, /* complain_on_overflow */ 148 1.1 christos bfd_elf_generic_reloc, /* special_function */ 149 1.1 christos "R_FT32_18", /* name */ 150 1.1.1.6 christos false, /* partial_inplace */ 151 1.1 christos 0x00000000, /* src_mask */ 152 1.1 christos 0x0003ffff, /* dst_mask */ 153 1.1.1.6 christos false), /* pcrel_offset */ 154 1.1 christos 155 1.1.1.4 christos HOWTO (R_FT32_RELAX, /* type */ 156 1.1.1.4 christos 0, /* rightshift */ 157 1.1.1.6 christos 2, /* size */ 158 1.1.1.4 christos 10, /* bitsize */ 159 1.1.1.6 christos false, /* pc_relative */ 160 1.1.1.4 christos 4, /* bitpos */ 161 1.1.1.4 christos complain_overflow_signed, /* complain_on_overflow */ 162 1.1.1.4 christos bfd_elf_generic_reloc, /* special_function */ 163 1.1.1.4 christos "R_FT32_RELAX", /* name */ 164 1.1.1.6 christos false, /* partial_inplace */ 165 1.1.1.4 christos 0x00000000, /* src_mask */ 166 1.1.1.4 christos 0x00000000, /* dst_mask */ 167 1.1.1.6 christos false), /* pcrel_offset */ 168 1.1.1.4 christos 169 1.1.1.4 christos HOWTO (R_FT32_SC0, /* type */ 170 1.1.1.4 christos 0, /* rightshift */ 171 1.1.1.6 christos 2, /* size */ 172 1.1.1.4 christos 10, /* bitsize */ 173 1.1.1.6 christos false, /* pc_relative */ 174 1.1.1.4 christos 4, /* bitpos */ 175 1.1.1.4 christos complain_overflow_signed, /* complain_on_overflow */ 176 1.1.1.4 christos bfd_elf_generic_reloc, /* special_function */ 177 1.1.1.4 christos "R_FT32_SC0", /* name */ 178 1.1.1.6 christos false, /* partial_inplace */ 179 1.1.1.4 christos 0x00000000, /* src_mask */ 180 1.1.1.4 christos 0x00000000, /* dst_mask */ 181 1.1.1.6 christos false), /* pcrel_offset */ 182 1.1.1.4 christos HOWTO (R_FT32_SC1, /* type */ 183 1.1.1.4 christos 2, /* rightshift */ 184 1.1.1.6 christos 4, /* size */ 185 1.1.1.4 christos 22, /* bitsize */ 186 1.1.1.6 christos true, /* pc_relative */ 187 1.1.1.4 christos 7, /* bitpos */ 188 1.1.1.4 christos complain_overflow_dont, /* complain_on_overflow */ 189 1.1.1.4 christos bfd_elf_generic_reloc, /* special_function */ 190 1.1.1.4 christos "R_FT32_SC1", /* name */ 191 1.1.1.6 christos true, /* partial_inplace */ 192 1.1.1.4 christos 0x07ffff80, /* src_mask */ 193 1.1.1.4 christos 0x07ffff80, /* dst_mask */ 194 1.1.1.6 christos false), /* pcrel_offset */ 195 1.1.1.4 christos HOWTO (R_FT32_15, /* type */ 196 1.1.1.4 christos 0, /* rightshift */ 197 1.1.1.6 christos 4, /* size */ 198 1.1.1.4 christos 15, /* bitsize */ 199 1.1.1.6 christos false, /* pc_relative */ 200 1.1.1.4 christos 0, /* bitpos */ 201 1.1.1.4 christos complain_overflow_dont, /* complain_on_overflow */ 202 1.1.1.4 christos bfd_elf_generic_reloc, /* special_function */ 203 1.1.1.4 christos "R_FT32_15", /* name */ 204 1.1.1.6 christos false, /* partial_inplace */ 205 1.1.1.4 christos 0x00000000, /* src_mask */ 206 1.1.1.4 christos 0x00007fff, /* dst_mask */ 207 1.1.1.6 christos false), /* pcrel_offset */ 208 1.1.1.4 christos HOWTO (R_FT32_DIFF32, /* type */ 209 1.1.1.4 christos 0, /* rightshift */ 210 1.1.1.6 christos 4, /* size */ 211 1.1.1.4 christos 32, /* bitsize */ 212 1.1.1.6 christos false, /* pc_relative */ 213 1.1.1.4 christos 0, /* bitpos */ 214 1.1.1.4 christos complain_overflow_dont, /* complain_on_overflow */ 215 1.1.1.4 christos bfd_elf_ft32_diff_reloc, /* special_function */ 216 1.1.1.4 christos "R_FT32_DIFF32", /* name */ 217 1.1.1.6 christos false, /* partial_inplace */ 218 1.1.1.4 christos 0, /* src_mask */ 219 1.1.1.4 christos 0xffffffff, /* dst_mask */ 220 1.1.1.6 christos false), /* pcrel_offset */ 221 1.1 christos }; 222 1.1 christos 223 1.1 christos /* Map BFD reloc types to FT32 ELF reloc types. */ 225 1.1 christos 226 1.1 christos struct ft32_reloc_map 227 1.1 christos { 228 1.1 christos bfd_reloc_code_real_type bfd_reloc_val; 229 1.1 christos unsigned int ft32_reloc_val; 230 1.1 christos }; 231 1.1 christos 232 1.1 christos static const struct ft32_reloc_map ft32_reloc_map [] = 233 1.1.1.4 christos { 234 1.1.1.4 christos { BFD_RELOC_NONE, R_FT32_NONE }, 235 1.1.1.4 christos { BFD_RELOC_32, R_FT32_32 }, 236 1.1.1.4 christos { BFD_RELOC_16, R_FT32_16 }, 237 1.1.1.4 christos { BFD_RELOC_8, R_FT32_8 }, 238 1.1.1.4 christos { BFD_RELOC_FT32_10, R_FT32_10 }, 239 1.1.1.4 christos { BFD_RELOC_FT32_20, R_FT32_20 }, 240 1.1.1.4 christos { BFD_RELOC_FT32_17, R_FT32_17 }, 241 1.1.1.4 christos { BFD_RELOC_FT32_18, R_FT32_18 }, 242 1.1.1.4 christos { BFD_RELOC_FT32_RELAX, R_FT32_RELAX }, 243 1.1.1.4 christos { BFD_RELOC_FT32_SC0, R_FT32_SC0 }, 244 1.1.1.4 christos { BFD_RELOC_FT32_SC1, R_FT32_SC1 }, 245 1.1.1.4 christos { BFD_RELOC_FT32_15, R_FT32_15 }, 246 1.1 christos { BFD_RELOC_FT32_DIFF32, R_FT32_DIFF32 }, 247 1.1 christos }; 248 1.1.1.4 christos 249 1.1.1.4 christos /* Perform a diff relocation. Nothing to do, as the difference value is 250 1.1.1.4 christos already written into the section's contents. */ 251 1.1.1.4 christos 252 1.1.1.4 christos static bfd_reloc_status_type 253 1.1.1.4 christos bfd_elf_ft32_diff_reloc (bfd *abfd ATTRIBUTE_UNUSED, 254 1.1.1.4 christos arelent *reloc_entry ATTRIBUTE_UNUSED, 255 1.1.1.4 christos asymbol *symbol ATTRIBUTE_UNUSED, 256 1.1.1.4 christos void *data ATTRIBUTE_UNUSED, 257 1.1.1.4 christos asection *input_section ATTRIBUTE_UNUSED, 258 1.1.1.4 christos bfd *output_bfd ATTRIBUTE_UNUSED, 259 1.1.1.4 christos char **error_message ATTRIBUTE_UNUSED) 260 1.1.1.4 christos { 261 1.1.1.4 christos return bfd_reloc_ok; 262 1.1.1.4 christos } 263 1.1 christos 264 1.1 christos static reloc_howto_type * 265 1.1 christos ft32_reloc_type_lookup (bfd *abfd ATTRIBUTE_UNUSED, 266 1.1 christos bfd_reloc_code_real_type code) 267 1.1 christos { 268 1.1 christos unsigned int i; 269 1.1.1.6 christos 270 1.1 christos for (i = 0; i < sizeof (ft32_reloc_map) / sizeof (ft32_reloc_map[0]); i++) 271 1.1 christos if (ft32_reloc_map [i].bfd_reloc_val == code) 272 1.1 christos return & ft32_elf_howto_table [ft32_reloc_map[i].ft32_reloc_val]; 273 1.1 christos 274 1.1 christos return NULL; 275 1.1 christos } 276 1.1 christos 277 1.1 christos static reloc_howto_type * 278 1.1 christos ft32_reloc_name_lookup (bfd *abfd ATTRIBUTE_UNUSED, const char *r_name) 279 1.1 christos { 280 1.1 christos unsigned int i; 281 1.1 christos 282 1.1 christos for (i = 0; 283 1.1 christos i < sizeof (ft32_elf_howto_table) / sizeof (ft32_elf_howto_table[0]); 284 1.1 christos i++) 285 1.1 christos if (ft32_elf_howto_table[i].name != NULL 286 1.1 christos && strcasecmp (ft32_elf_howto_table[i].name, r_name) == 0) 287 1.1 christos return &ft32_elf_howto_table[i]; 288 1.1 christos 289 1.1 christos return NULL; 290 1.1 christos } 291 1.1 christos 292 1.1 christos /* Set the howto pointer for an FT32 ELF reloc. */ 293 1.1.1.6 christos 294 1.1.1.4 christos static bool 295 1.1 christos ft32_info_to_howto_rela (bfd *abfd, 296 1.1 christos arelent *cache_ptr, 297 1.1 christos Elf_Internal_Rela *dst) 298 1.1 christos { 299 1.1 christos unsigned int r_type; 300 1.1 christos 301 1.1.1.4 christos r_type = ELF32_R_TYPE (dst->r_info); 302 1.1.1.4 christos if (r_type >= (unsigned int) R_FT32_max) 303 1.1.1.4 christos { 304 1.1.1.4 christos /* xgettext:c-format */ 305 1.1.1.4 christos _bfd_error_handler (_("%pB: unsupported relocation type %#x"), 306 1.1.1.4 christos abfd, r_type); 307 1.1.1.6 christos bfd_set_error (bfd_error_bad_value); 308 1.1.1.4 christos return false; 309 1.1.1.4 christos } 310 1.1 christos 311 1.1.1.4 christos cache_ptr->howto = & ft32_elf_howto_table [r_type]; 312 1.1 christos return cache_ptr->howto != NULL; 313 1.1.1.4 christos } 314 1.1 christos 315 1.1 christos /* Relocate an FT32 ELF section. 316 1.1 christos 317 1.1 christos The RELOCATE_SECTION function is called by the new ELF backend linker 318 1.1 christos to handle the relocations for a section. 319 1.1 christos 320 1.1 christos The relocs are always passed as Rela structures; if the section 321 1.1 christos actually uses Rel structures, the r_addend field will always be 322 1.1 christos zero. 323 1.1 christos 324 1.1 christos This function is responsible for adjusting the section contents as 325 1.1 christos necessary, and (if using Rela relocs and generating a relocatable 326 1.1 christos output file) adjusting the reloc addend as necessary. 327 1.1 christos 328 1.1 christos This function does not have to worry about setting the reloc 329 1.1 christos address or the reloc symbol index. 330 1.1 christos 331 1.1 christos LOCAL_SYMS is a pointer to the swapped in local symbols. 332 1.1 christos 333 1.1 christos LOCAL_SECTIONS is an array giving the section in the input file 334 1.1 christos corresponding to the st_shndx field of each local symbol. 335 1.1 christos 336 1.1 christos The global hash table entry for the global symbols can be found 337 1.1 christos via elf_sym_hashes (input_bfd). 338 1.1 christos 339 1.1 christos When generating relocatable output, this function must handle 340 1.1 christos STB_LOCAL/STT_SECTION symbols specially. The output symbol is 341 1.1 christos going to be the section symbol corresponding to the output 342 1.1 christos section, which means that the addend must be adjusted 343 1.1 christos accordingly. */ 344 1.1.1.6 christos 345 1.1 christos static int 346 1.1 christos ft32_elf_relocate_section (bfd *output_bfd, 347 1.1 christos struct bfd_link_info *info, 348 1.1 christos bfd *input_bfd, 349 1.1 christos asection *input_section, 350 1.1 christos bfd_byte *contents, 351 1.1 christos Elf_Internal_Rela *relocs, 352 1.1 christos Elf_Internal_Sym *local_syms, 353 1.1 christos asection **local_sections) 354 1.1 christos { 355 1.1 christos Elf_Internal_Shdr *symtab_hdr; 356 1.1 christos struct elf_link_hash_entry **sym_hashes; 357 1.1 christos Elf_Internal_Rela *rel; 358 1.1 christos Elf_Internal_Rela *relend; 359 1.1 christos 360 1.1 christos symtab_hdr = & elf_tdata (input_bfd)->symtab_hdr; 361 1.1 christos sym_hashes = elf_sym_hashes (input_bfd); 362 1.1 christos relend = relocs + input_section->reloc_count; 363 1.1 christos 364 1.1 christos for (rel = relocs; rel < relend; rel ++) 365 1.1 christos { 366 1.1 christos reloc_howto_type *howto; 367 1.1 christos unsigned long r_symndx; 368 1.1 christos Elf_Internal_Sym *sym; 369 1.1 christos asection *sec; 370 1.1 christos struct elf_link_hash_entry *h; 371 1.1 christos bfd_vma relocation; 372 1.1 christos bfd_reloc_status_type r; 373 1.1 christos const char *name; 374 1.1 christos int r_type; 375 1.1 christos 376 1.1 christos r_type = ELF32_R_TYPE (rel->r_info); 377 1.1 christos r_symndx = ELF32_R_SYM (rel->r_info); 378 1.1 christos howto = ft32_elf_howto_table + r_type; 379 1.1 christos h = NULL; 380 1.1 christos sym = NULL; 381 1.1 christos sec = NULL; 382 1.1 christos 383 1.1 christos if (r_symndx < symtab_hdr->sh_info) 384 1.1 christos { 385 1.1 christos sym = local_syms + r_symndx; 386 1.1 christos sec = local_sections [r_symndx]; 387 1.1 christos relocation = _bfd_elf_rela_local_sym (output_bfd, sym, &sec, rel); 388 1.1 christos 389 1.1 christos name = bfd_elf_string_from_elf_section 390 1.1.1.5 christos (input_bfd, symtab_hdr->sh_link, sym->st_name); 391 1.1 christos name = name == NULL ? bfd_section_name (sec) : name; 392 1.1 christos } 393 1.1 christos else 394 1.1.1.6 christos { 395 1.1 christos bool unresolved_reloc, warned, ignored; 396 1.1 christos 397 1.1 christos RELOC_FOR_GLOBAL_SYMBOL (info, input_bfd, input_section, rel, 398 1.1 christos r_symndx, symtab_hdr, sym_hashes, 399 1.1 christos h, sec, relocation, 400 1.1 christos unresolved_reloc, warned, ignored); 401 1.1 christos 402 1.1 christos name = h->root.root.string; 403 1.1 christos } 404 1.1 christos 405 1.1 christos if (sec != NULL && discarded_section (sec)) 406 1.1 christos RELOC_AGAINST_DISCARDED_SECTION (info, input_bfd, input_section, 407 1.1 christos rel, 1, relend, howto, 0, contents); 408 1.1.1.2 christos 409 1.1 christos if (bfd_link_relocatable (info)) 410 1.1 christos continue; 411 1.1.1.4 christos 412 1.1.1.4 christos switch (howto->type) 413 1.1.1.4 christos { 414 1.1.1.4 christos case R_FT32_SC0: 415 1.1.1.4 christos { 416 1.1.1.4 christos unsigned int insn; 417 1.1.1.4 christos int offset; 418 1.1.1.4 christos unsigned int code15[2]; 419 1.1.1.4 christos 420 1.1.1.4 christos insn = bfd_get_32 (input_bfd, contents + rel->r_offset); 421 1.1.1.4 christos ft32_split_shortcode (insn, code15); 422 1.1.1.4 christos 423 1.1.1.4 christos offset = (int)relocation; 424 1.1.1.4 christos offset += (int)(rel->r_addend - rel->r_offset); 425 1.1.1.4 christos offset -= (input_section->output_section->vma + 426 1.1.1.4 christos input_section->output_offset); 427 1.1.1.4 christos if ((offset < -1024) || (offset >= 1024)) 428 1.1.1.4 christos { 429 1.1.1.4 christos r = bfd_reloc_outofrange; 430 1.1.1.4 christos break; 431 1.1.1.4 christos } 432 1.1.1.4 christos code15[0] |= ((offset / 4) & 511); 433 1.1.1.4 christos insn = ft32_merge_shortcode (code15); 434 1.1.1.4 christos bfd_put_32 (input_bfd, insn, contents + rel->r_offset); 435 1.1.1.4 christos } 436 1.1.1.4 christos r = bfd_reloc_ok; 437 1.1.1.4 christos break; 438 1.1.1.4 christos 439 1.1.1.4 christos case R_FT32_SC1: 440 1.1.1.4 christos { 441 1.1.1.4 christos unsigned int insn; 442 1.1.1.4 christos int offset; 443 1.1.1.4 christos unsigned int code15[2]; 444 1.1.1.4 christos 445 1.1.1.4 christos insn = bfd_get_32 (input_bfd, contents + rel->r_offset); 446 1.1.1.4 christos ft32_split_shortcode (insn, code15); 447 1.1.1.4 christos 448 1.1.1.4 christos offset = (int)relocation; 449 1.1.1.4 christos offset += (int)(rel->r_addend - rel->r_offset); 450 1.1.1.4 christos offset -= (input_section->output_section->vma + 451 1.1.1.4 christos input_section->output_offset); 452 1.1.1.4 christos if ((offset < -1024) || (offset >= 1024)) 453 1.1.1.4 christos { 454 1.1.1.4 christos r = bfd_reloc_outofrange; 455 1.1.1.4 christos break; 456 1.1.1.4 christos } 457 1.1.1.4 christos code15[1] |= ((offset / 4) & 511); 458 1.1.1.4 christos insn = ft32_merge_shortcode (code15); 459 1.1.1.4 christos bfd_put_32 (input_bfd, insn, contents + rel->r_offset); 460 1.1.1.4 christos } 461 1.1.1.4 christos r = bfd_reloc_ok; 462 1.1.1.4 christos break; 463 1.1.1.4 christos 464 1.1.1.4 christos case R_FT32_DIFF32: 465 1.1.1.4 christos r = bfd_reloc_ok; 466 1.1.1.4 christos break; 467 1.1.1.4 christos 468 1.1.1.4 christos default: 469 1.1.1.4 christos r = _bfd_final_link_relocate (howto, input_bfd, input_section, 470 1.1.1.4 christos contents, rel->r_offset, 471 1.1.1.4 christos relocation, rel->r_addend); 472 1.1.1.4 christos break; 473 1.1 christos } 474 1.1 christos 475 1.1 christos if (r != bfd_reloc_ok) 476 1.1 christos { 477 1.1 christos const char * msg = NULL; 478 1.1 christos 479 1.1 christos switch (r) 480 1.1 christos { 481 1.1.1.2 christos case bfd_reloc_overflow: 482 1.1 christos (*info->callbacks->reloc_overflow) 483 1.1 christos (info, (h ? &h->root : NULL), name, howto->name, 484 1.1 christos (bfd_vma) 0, input_bfd, input_section, rel->r_offset); 485 1.1 christos break; 486 1.1 christos 487 1.1.1.2 christos case bfd_reloc_undefined: 488 1.1.1.6 christos (*info->callbacks->undefined_symbol) 489 1.1 christos (info, name, input_bfd, input_section, rel->r_offset, true); 490 1.1 christos break; 491 1.1 christos 492 1.1 christos case bfd_reloc_outofrange: 493 1.1 christos msg = _("internal error: out of range error"); 494 1.1 christos break; 495 1.1 christos 496 1.1 christos case bfd_reloc_notsupported: 497 1.1 christos msg = _("internal error: unsupported relocation error"); 498 1.1 christos break; 499 1.1 christos 500 1.1 christos case bfd_reloc_dangerous: 501 1.1 christos msg = _("internal error: dangerous relocation"); 502 1.1 christos break; 503 1.1 christos 504 1.1 christos default: 505 1.1 christos msg = _("internal error: unknown error"); 506 1.1 christos break; 507 1.1 christos } 508 1.1 christos 509 1.1.1.2 christos if (msg) 510 1.1.1.2 christos (*info->callbacks->warning) (info, msg, name, input_bfd, 511 1.1 christos input_section, rel->r_offset); 512 1.1 christos } 513 1.1 christos } 514 1.1.1.6 christos 515 1.1 christos return true; 516 1.1 christos } 517 1.1.1.4 christos 518 1.1.1.4 christos /* Relaxation. */ 520 1.1.1.4 christos 521 1.1.1.4 christos static bool 522 1.1.1.4 christos ft32_reloc_shortable 523 1.1.1.4 christos (bfd * abfd, 524 1.1.1.4 christos asection * sec, 525 1.1.1.4 christos Elf_Internal_Sym * isymbuf ATTRIBUTE_UNUSED, 526 1.1.1.4 christos bfd_byte * contents, 527 1.1.1.4 christos bfd_vma pc ATTRIBUTE_UNUSED, 528 1.1.1.4 christos Elf_Internal_Rela * irel, 529 1.1.1.4 christos unsigned int * sc) 530 1.1.1.4 christos { 531 1.1.1.4 christos Elf_Internal_Shdr *symtab_hdr ATTRIBUTE_UNUSED; 532 1.1.1.4 christos bfd_vma symval; 533 1.1.1.4 christos 534 1.1.1.4 christos enum elf_ft32_reloc_type r_type; 535 1.1.1.4 christos reloc_howto_type *howto = NULL; 536 1.1.1.4 christos unsigned int insn; 537 1.1.1.4 christos int offset; 538 1.1.1.4 christos bfd_vma dot, value; 539 1.1.1.4 christos 540 1.1.1.4 christos r_type = ELF32_R_TYPE (irel->r_info); 541 1.1.1.4 christos howto = &ft32_elf_howto_table [r_type]; 542 1.1.1.4 christos 543 1.1.1.4 christos symtab_hdr = &elf_tdata (abfd)->symtab_hdr; 544 1.1.1.4 christos 545 1.1.1.4 christos /* Get the value of the symbol referred to by the reloc. */ 546 1.1.1.4 christos if (ELF32_R_SYM (irel->r_info) < symtab_hdr->sh_info) 547 1.1.1.4 christos { 548 1.1.1.4 christos /* A local symbol. */ 549 1.1.1.4 christos Elf_Internal_Sym *isym; 550 1.1.1.4 christos asection *sym_sec; 551 1.1.1.4 christos 552 1.1.1.4 christos isym = isymbuf + ELF32_R_SYM (irel->r_info); 553 1.1.1.4 christos sym_sec = bfd_section_from_elf_index (abfd, isym->st_shndx); 554 1.1.1.4 christos symval = isym->st_value; 555 1.1.1.4 christos /* If the reloc is absolute, it will not have 556 1.1.1.4 christos a symbol or section associated with it. */ 557 1.1.1.4 christos if (sym_sec) 558 1.1.1.4 christos symval += sym_sec->output_section->vma 559 1.1.1.4 christos + sym_sec->output_offset; 560 1.1.1.4 christos } 561 1.1.1.4 christos else 562 1.1.1.4 christos { 563 1.1.1.4 christos unsigned long indx; 564 1.1.1.4 christos struct elf_link_hash_entry *h; 565 1.1.1.4 christos 566 1.1.1.4 christos /* An external symbol. */ 567 1.1.1.4 christos indx = ELF32_R_SYM (irel->r_info) - symtab_hdr->sh_info; 568 1.1.1.4 christos h = elf_sym_hashes (abfd)[indx]; 569 1.1.1.4 christos BFD_ASSERT (h != NULL); 570 1.1.1.4 christos if (h->root.type != bfd_link_hash_defined 571 1.1.1.4 christos && h->root.type != bfd_link_hash_defweak) 572 1.1.1.4 christos /* This appears to be a reference to an undefined 573 1.1.1.6 christos symbol. Just ignore it--it will be caught by the 574 1.1.1.4 christos regular reloc processing. */ 575 1.1.1.4 christos return false; 576 1.1.1.4 christos 577 1.1.1.4 christos symval = (h->root.u.def.value 578 1.1.1.4 christos + h->root.u.def.section->output_section->vma 579 1.1.1.4 christos + h->root.u.def.section->output_offset); 580 1.1.1.4 christos } 581 1.1.1.4 christos 582 1.1.1.4 christos switch (r_type) 583 1.1.1.4 christos { 584 1.1.1.4 christos case R_FT32_8: 585 1.1.1.4 christos case R_FT32_10: 586 1.1.1.4 christos case R_FT32_16: 587 1.1.1.4 christos case R_FT32_20: 588 1.1.1.6 christos case R_FT32_RELAX: 589 1.1.1.4 christos if (symval != 0) 590 1.1.1.4 christos return false; 591 1.1.1.4 christos insn = bfd_get_32 (abfd, contents + irel->r_offset); 592 1.1.1.4 christos insn |= ((symval + irel->r_addend) << howto->bitpos) & howto->dst_mask; 593 1.1.1.4 christos return ft32_shortcode (insn, sc); 594 1.1.1.4 christos 595 1.1.1.4 christos case R_FT32_18: 596 1.1.1.4 christos insn = bfd_get_32 (abfd, contents + irel->r_offset); 597 1.1.1.4 christos /* Get the address of this instruction. */ 598 1.1.1.4 christos dot = (sec->output_section->vma 599 1.1.1.4 christos + sec->output_offset + irel->r_offset); 600 1.1.1.4 christos value = symval + irel->r_addend; 601 1.1.1.4 christos offset = (value - dot) / 4; 602 1.1.1.4 christos 603 1.1.1.4 christos if ((dot > 0x8c) && (-256 <= offset) && (offset < 256)) 604 1.1.1.4 christos { 605 1.1.1.6 christos switch (insn) 606 1.1.1.6 christos { 607 1.1.1.6 christos case 0x00200000: *sc = (3 << 13) | (0 << 9); return true; 608 1.1.1.6 christos case 0x00280000: *sc = (3 << 13) | (1 << 9); return true; 609 1.1.1.6 christos case 0x00600000: *sc = (3 << 13) | (2 << 9); return true; 610 1.1.1.6 christos case 0x00680000: *sc = (3 << 13) | (3 << 9); return true; 611 1.1.1.6 christos case 0x00a00000: *sc = (3 << 13) | (4 << 9); return true; 612 1.1.1.6 christos case 0x00a80000: *sc = (3 << 13) | (5 << 9); return true; 613 1.1.1.6 christos case 0x00e00000: *sc = (3 << 13) | (6 << 9); return true; 614 1.1.1.6 christos case 0x00e80000: *sc = (3 << 13) | (7 << 9); return true; 615 1.1.1.6 christos case 0x01200000: *sc = (3 << 13) | (8 << 9); return true; 616 1.1.1.6 christos case 0x01280000: *sc = (3 << 13) | (9 << 9); return true; 617 1.1.1.6 christos case 0x01600000: *sc = (3 << 13) | (10 << 9); return true; 618 1.1.1.6 christos case 0x01680000: *sc = (3 << 13) | (11 << 9); return true; 619 1.1.1.4 christos case 0x01a00000: *sc = (3 << 13) | (12 << 9); return true; 620 1.1.1.6 christos case 0x01a80000: *sc = (3 << 13) | (13 << 9); return true; 621 1.1.1.6 christos 622 1.1.1.4 christos case 0x00300000: *sc = (3 << 13) | (14 << 9); return true; 623 1.1.1.4 christos case 0x00340000: *sc = (3 << 13) | (15 << 9); return true; 624 1.1.1.4 christos 625 1.1.1.4 christos default: 626 1.1.1.4 christos break; 627 1.1.1.4 christos } 628 1.1.1.4 christos } 629 1.1.1.4 christos break; 630 1.1.1.4 christos 631 1.1.1.4 christos default: 632 1.1.1.6 christos break; 633 1.1.1.4 christos } 634 1.1.1.4 christos return false; 635 1.1.1.4 christos } 636 1.1.1.4 christos 637 1.1.1.6 christos /* Returns whether the relocation type passed is a diff reloc. */ 638 1.1.1.4 christos 639 1.1.1.4 christos static bool 640 1.1.1.4 christos elf32_ft32_is_diff_reloc (Elf_Internal_Rela *irel) 641 1.1.1.4 christos { 642 1.1.1.4 christos return (ELF32_R_TYPE (irel->r_info) == R_FT32_DIFF32); 643 1.1.1.4 christos } 644 1.1.1.4 christos 645 1.1.1.4 christos /* Reduce the diff value written in the section by count if the shrinked 646 1.1.1.4 christos insn address happens to fall between the two symbols for which this 647 1.1.1.6 christos diff reloc was emitted. */ 648 1.1.1.4 christos 649 1.1.1.4 christos static bool 650 1.1.1.4 christos elf32_ft32_adjust_diff_reloc_value (bfd *abfd, 651 1.1.1.4 christos struct bfd_section *isec, 652 1.1.1.4 christos Elf_Internal_Rela *irel, 653 1.1.1.4 christos bfd_vma symval, 654 1.1.1.4 christos bfd_vma shrinked_insn_address, 655 1.1.1.4 christos int count) 656 1.1.1.4 christos { 657 1.1.1.4 christos unsigned char * reloc_contents = NULL; 658 1.1.1.4 christos unsigned char * isec_contents = elf_section_data (isec)->this_hdr.contents; 659 1.1.1.4 christos bfd_signed_vma x = 0; 660 1.1.1.4 christos bfd_vma sym2_address; 661 1.1.1.4 christos bfd_vma sym1_address; 662 1.1.1.4 christos bfd_vma start_address; 663 1.1.1.4 christos bfd_vma end_address; 664 1.1.1.4 christos 665 1.1.1.4 christos 666 1.1.1.4 christos if (isec_contents == NULL) 667 1.1.1.6 christos { 668 1.1.1.4 christos if (! bfd_malloc_and_get_section (abfd, isec, &isec_contents)) 669 1.1.1.4 christos return false; 670 1.1.1.4 christos 671 1.1.1.4 christos elf_section_data (isec)->this_hdr.contents = isec_contents; 672 1.1.1.4 christos } 673 1.1.1.4 christos 674 1.1.1.4 christos reloc_contents = isec_contents + irel->r_offset; 675 1.1.1.4 christos 676 1.1.1.4 christos /* Read value written in object file. */ 677 1.1.1.4 christos switch (ELF32_R_TYPE (irel->r_info)) 678 1.1.1.4 christos { 679 1.1.1.4 christos case R_FT32_DIFF32: 680 1.1.1.4 christos x = bfd_get_signed_32 (abfd, reloc_contents); 681 1.1.1.4 christos break; 682 1.1.1.6 christos 683 1.1.1.4 christos default: 684 1.1.1.4 christos return false; 685 1.1.1.4 christos } 686 1.1.1.4 christos 687 1.1.1.4 christos /* For a diff reloc sym1 - sym2 the diff at assembly time (x) is written 688 1.1.1.4 christos into the object file at the reloc offset. sym2's logical value is 689 1.1.1.4 christos symval (<start_of_section>) + reloc addend. Compute the start and end 690 1.1.1.4 christos addresses and check if the shrinked insn falls between sym1 and sym2. */ 691 1.1.1.4 christos sym2_address = symval + irel->r_addend; 692 1.1.1.4 christos sym1_address = sym2_address - x; 693 1.1.1.4 christos 694 1.1.1.4 christos /* Don't assume sym2 is bigger than sym1 - the difference 695 1.1.1.4 christos could be negative. Compute start and end addresses, and 696 1.1.1.4 christos use those to see if they span shrinked_insn_address. */ 697 1.1.1.4 christos start_address = sym1_address < sym2_address ? sym1_address : sym2_address; 698 1.1.1.4 christos end_address = sym1_address > sym2_address ? sym1_address : sym2_address; 699 1.1.1.4 christos 700 1.1.1.4 christos if (shrinked_insn_address >= start_address 701 1.1.1.4 christos && shrinked_insn_address < end_address) 702 1.1.1.4 christos { 703 1.1.1.4 christos /* Reduce the diff value by count bytes and write it back into section 704 1.1.1.4 christos contents. */ 705 1.1.1.4 christos bfd_signed_vma new_diff = x < 0 ? x + count : x - count; 706 1.1.1.4 christos 707 1.1.1.4 christos if (sym2_address > shrinked_insn_address) 708 1.1.1.4 christos irel->r_addend -= count; 709 1.1.1.4 christos 710 1.1.1.4 christos switch (ELF32_R_TYPE (irel->r_info)) 711 1.1.1.4 christos { 712 1.1.1.4 christos case R_FT32_DIFF32: 713 1.1.1.4 christos bfd_put_signed_32 (abfd, new_diff & 0xFFFFFFFF, reloc_contents); 714 1.1.1.4 christos break; 715 1.1.1.6 christos 716 1.1.1.4 christos default: 717 1.1.1.4 christos return false; 718 1.1.1.4 christos } 719 1.1.1.6 christos } 720 1.1.1.4 christos 721 1.1.1.4 christos return true; 722 1.1.1.6 christos } 723 1.1.1.4 christos 724 1.1.1.4 christos static bool 725 1.1.1.4 christos elf32_ft32_adjust_reloc_if_spans_insn (bfd *abfd, 726 1.1.1.4 christos asection *isec, 727 1.1.1.4 christos Elf_Internal_Rela *irel, bfd_vma symval, 728 1.1.1.4 christos bfd_vma shrinked_insn_address, 729 1.1.1.4 christos bfd_vma shrink_boundary, 730 1.1.1.4 christos int count) 731 1.1.1.4 christos { 732 1.1.1.4 christos 733 1.1.1.4 christos if (elf32_ft32_is_diff_reloc (irel)) 734 1.1.1.4 christos { 735 1.1.1.4 christos if (!elf32_ft32_adjust_diff_reloc_value (abfd, isec, irel, 736 1.1.1.4 christos symval, 737 1.1.1.6 christos shrinked_insn_address, 738 1.1.1.4 christos count)) 739 1.1.1.4 christos return false; 740 1.1.1.4 christos } 741 1.1.1.4 christos else 742 1.1.1.6 christos { 743 1.1.1.4 christos bfd_vma reloc_value = symval + irel->r_addend; 744 1.1.1.6 christos bool addend_within_shrink_boundary = 745 1.1.1.4 christos (reloc_value <= shrink_boundary); 746 1.1.1.4 christos bool reloc_spans_insn = 747 1.1.1.4 christos (symval <= shrinked_insn_address 748 1.1.1.4 christos && reloc_value > shrinked_insn_address 749 1.1.1.4 christos && addend_within_shrink_boundary); 750 1.1.1.6 christos 751 1.1.1.4 christos if (! reloc_spans_insn) 752 1.1.1.4 christos return true; 753 1.1.1.4 christos 754 1.1.1.4 christos irel->r_addend -= count; 755 1.1.1.4 christos 756 1.1.1.4 christos if (debug_relax) 757 1.1.1.6 christos printf ("Relocation's addend needed to be fixed \n"); 758 1.1.1.4 christos } 759 1.1.1.4 christos return true; 760 1.1.1.4 christos } 761 1.1.1.4 christos 762 1.1.1.6 christos /* Delete some bytes from a section while relaxing. */ 763 1.1.1.4 christos 764 1.1.1.4 christos static bool 765 1.1.1.4 christos elf32_ft32_relax_delete_bytes (struct bfd_link_info *link_info, bfd * abfd, 766 1.1.1.4 christos asection * sec, bfd_vma addr, int count) 767 1.1.1.4 christos { 768 1.1.1.4 christos Elf_Internal_Shdr *symtab_hdr; 769 1.1.1.4 christos unsigned int sec_shndx; 770 1.1.1.4 christos bfd_byte *contents; 771 1.1.1.4 christos Elf_Internal_Rela *irel, *irelend; 772 1.1.1.4 christos bfd_vma toaddr; 773 1.1.1.4 christos Elf_Internal_Sym *isym; 774 1.1.1.4 christos Elf_Internal_Sym *isymend; 775 1.1.1.4 christos struct elf_link_hash_entry **sym_hashes; 776 1.1.1.4 christos struct elf_link_hash_entry **end_hashes; 777 1.1.1.4 christos struct elf_link_hash_entry **start_hashes; 778 1.1.1.4 christos unsigned int symcount; 779 1.1.1.4 christos Elf_Internal_Sym *isymbuf = NULL; 780 1.1.1.4 christos 781 1.1.1.4 christos symtab_hdr = &elf_tdata (abfd)->symtab_hdr; 782 1.1.1.4 christos sec_shndx = _bfd_elf_section_from_bfd_section (abfd, sec); 783 1.1.1.4 christos 784 1.1.1.4 christos contents = elf_section_data (sec)->this_hdr.contents; 785 1.1.1.4 christos 786 1.1.1.4 christos toaddr = sec->size; 787 1.1.1.4 christos 788 1.1.1.4 christos irel = elf_section_data (sec)->relocs; 789 1.1.1.4 christos irelend = irel + sec->reloc_count; 790 1.1.1.4 christos 791 1.1.1.4 christos /* Actually delete the bytes. */ 792 1.1.1.4 christos memmove (contents + addr, contents + addr + count, 793 1.1.1.4 christos (size_t) (toaddr - addr - count)); 794 1.1.1.4 christos sec->size -= count; 795 1.1.1.4 christos 796 1.1.1.4 christos /* Adjust all the relocs. */ 797 1.1.1.4 christos for (irel = elf_section_data (sec)->relocs; irel < irelend; irel++) 798 1.1.1.4 christos /* Get the new reloc address. */ 799 1.1.1.4 christos if ((irel->r_offset > addr && irel->r_offset < toaddr)) 800 1.1.1.4 christos irel->r_offset -= count; 801 1.1.1.4 christos 802 1.1.1.4 christos /* The reloc's own addresses are now ok. However, we need to readjust 803 1.1.1.4 christos the reloc's addend, i.e. the reloc's value if two conditions are met: 804 1.1.1.4 christos 1.) the reloc is relative to a symbol in this section that 805 1.1.1.4 christos is located in front of the shrinked instruction 806 1.1.1.4 christos 2.) symbol plus addend end up behind the shrinked instruction. 807 1.1.1.4 christos 808 1.1.1.4 christos The most common case where this happens are relocs relative to 809 1.1.1.4 christos the section-start symbol. 810 1.1.1.4 christos 811 1.1.1.4 christos This step needs to be done for all of the sections of the bfd. */ 812 1.1.1.4 christos { 813 1.1.1.4 christos struct bfd_section *isec; 814 1.1.1.4 christos 815 1.1.1.4 christos for (isec = abfd->sections; isec; isec = isec->next) 816 1.1.1.4 christos { 817 1.1.1.4 christos bfd_vma symval; 818 1.1.1.4 christos bfd_vma shrinked_insn_address; 819 1.1.1.4 christos 820 1.1.1.4 christos if (isec->reloc_count == 0) 821 1.1.1.4 christos continue; 822 1.1.1.4 christos 823 1.1.1.4 christos shrinked_insn_address = (sec->output_section->vma 824 1.1.1.4 christos + sec->output_offset + addr - count); 825 1.1.1.4 christos 826 1.1.1.4 christos irel = elf_section_data (isec)->relocs; 827 1.1.1.6 christos /* PR 12161: Read in the relocs for this section if necessary. */ 828 1.1.1.4 christos if (irel == NULL) 829 1.1.1.4 christos irel = _bfd_elf_link_read_relocs (abfd, isec, NULL, NULL, true); 830 1.1.1.4 christos 831 1.1.1.4 christos for (irelend = irel + isec->reloc_count; irel < irelend; irel++) 832 1.1.1.4 christos { 833 1.1.1.4 christos /* Read this BFD's local symbols if we haven't done 834 1.1.1.4 christos so already. */ 835 1.1.1.4 christos if (isymbuf == NULL && symtab_hdr->sh_info != 0) 836 1.1.1.4 christos { 837 1.1.1.4 christos isymbuf = (Elf_Internal_Sym *) symtab_hdr->contents; 838 1.1.1.4 christos if (isymbuf == NULL) 839 1.1.1.4 christos isymbuf = bfd_elf_get_elf_syms (abfd, symtab_hdr, 840 1.1.1.4 christos symtab_hdr->sh_info, 0, 841 1.1.1.6 christos NULL, NULL, NULL); 842 1.1.1.4 christos if (isymbuf == NULL) 843 1.1.1.4 christos return false; 844 1.1.1.4 christos } 845 1.1.1.4 christos 846 1.1.1.4 christos /* Get the value of the symbol referred to by the reloc. */ 847 1.1.1.4 christos if (ELF32_R_SYM (irel->r_info) < symtab_hdr->sh_info) 848 1.1.1.4 christos { 849 1.1.1.4 christos /* A local symbol. */ 850 1.1.1.4 christos asection *sym_sec; 851 1.1.1.4 christos 852 1.1.1.4 christos isym = isymbuf + ELF32_R_SYM (irel->r_info); 853 1.1.1.4 christos sym_sec = bfd_section_from_elf_index (abfd, isym->st_shndx); 854 1.1.1.4 christos symval = isym->st_value; 855 1.1.1.4 christos /* If the reloc is absolute, it will not have 856 1.1.1.4 christos a symbol or section associated with it. */ 857 1.1.1.4 christos if (sym_sec == sec) 858 1.1.1.4 christos { 859 1.1.1.4 christos symval += sym_sec->output_section->vma 860 1.1.1.4 christos + sym_sec->output_offset; 861 1.1.1.4 christos 862 1.1.1.4 christos if (debug_relax) 863 1.1.1.4 christos printf ("Checking if the relocation's " 864 1.1.1.4 christos "addend needs corrections.\n" 865 1.1.1.4 christos "Address of anchor symbol: 0x%x \n" 866 1.1.1.4 christos "Address of relocation target: 0x%x \n" 867 1.1.1.4 christos "Address of relaxed insn: 0x%x \n", 868 1.1.1.4 christos (unsigned int) symval, 869 1.1.1.4 christos (unsigned int) (symval + irel->r_addend), 870 1.1.1.4 christos (unsigned int) shrinked_insn_address); 871 1.1.1.4 christos 872 1.1.1.4 christos if (symval <= shrinked_insn_address 873 1.1.1.4 christos && (symval + irel->r_addend) > shrinked_insn_address) 874 1.1.1.4 christos { 875 1.1.1.4 christos /* If there is an alignment boundary, we only need to 876 1.1.1.4 christos adjust addends that end up below the boundary. */ 877 1.1.1.4 christos bfd_vma shrink_boundary = (toaddr 878 1.1.1.4 christos + sec->output_section->vma 879 1.1.1.4 christos + sec->output_offset); 880 1.1.1.4 christos 881 1.1.1.4 christos if (debug_relax) 882 1.1.1.4 christos printf 883 1.1.1.4 christos ("Relocation's addend needed to be fixed \n"); 884 1.1.1.4 christos 885 1.1.1.4 christos if (!elf32_ft32_adjust_reloc_if_spans_insn (abfd, isec, 886 1.1.1.4 christos irel, symval, 887 1.1.1.4 christos shrinked_insn_address, 888 1.1.1.6 christos shrink_boundary, 889 1.1.1.4 christos count)) 890 1.1.1.4 christos return false; 891 1.1.1.4 christos } 892 1.1.1.4 christos } 893 1.1.1.4 christos /* else reference symbol is absolute. No adjustment needed. */ 894 1.1.1.4 christos } 895 1.1.1.4 christos /* else...Reference symbol is extern. No need for adjusting 896 1.1.1.4 christos the addend. */ 897 1.1.1.4 christos } 898 1.1.1.4 christos } 899 1.1.1.4 christos } 900 1.1.1.4 christos 901 1.1.1.4 christos /* Adjust the local symbols defined in this section. */ 902 1.1.1.4 christos symtab_hdr = &elf_tdata (abfd)->symtab_hdr; 903 1.1.1.4 christos isym = (Elf_Internal_Sym *) symtab_hdr->contents; 904 1.1.1.4 christos if (isym) 905 1.1.1.4 christos { 906 1.1.1.4 christos for (isymend = isym + symtab_hdr->sh_info; isym < isymend; isym++) 907 1.1.1.4 christos { 908 1.1.1.4 christos if (isym->st_shndx == sec_shndx 909 1.1.1.4 christos && isym->st_value > addr && isym->st_value < toaddr) 910 1.1.1.4 christos isym->st_value -= count; 911 1.1.1.4 christos } 912 1.1.1.4 christos } 913 1.1.1.4 christos 914 1.1.1.4 christos /* Now adjust the global symbols defined in this section. */ 915 1.1.1.4 christos symcount = (symtab_hdr->sh_size / sizeof (Elf32_External_Sym) 916 1.1.1.4 christos - symtab_hdr->sh_info); 917 1.1.1.4 christos sym_hashes = start_hashes = elf_sym_hashes (abfd); 918 1.1.1.4 christos end_hashes = sym_hashes + symcount; 919 1.1.1.4 christos 920 1.1.1.4 christos for (; sym_hashes < end_hashes; sym_hashes++) 921 1.1.1.4 christos { 922 1.1.1.4 christos struct elf_link_hash_entry *sym_hash = *sym_hashes; 923 1.1.1.4 christos 924 1.1.1.4 christos /* The '--wrap SYMBOL' option is causing a pain when the object file, 925 1.1.1.4 christos containing the definition of __wrap_SYMBOL, includes a direct 926 1.1.1.4 christos call to SYMBOL as well. Since both __wrap_SYMBOL and SYMBOL reference 927 1.1.1.4 christos the same symbol (which is __wrap_SYMBOL), but still exist as two 928 1.1.1.4 christos different symbols in 'sym_hashes', we don't want to adjust 929 1.1.1.4 christos the global symbol __wrap_SYMBOL twice. 930 1.1.1.4 christos This check is only relevant when symbols are being wrapped. */ 931 1.1.1.4 christos if (link_info->wrap_hash != NULL) 932 1.1.1.4 christos { 933 1.1.1.4 christos struct elf_link_hash_entry **cur_sym_hashes; 934 1.1.1.4 christos 935 1.1.1.4 christos /* Loop only over the symbols whom been already checked. */ 936 1.1.1.4 christos for (cur_sym_hashes = start_hashes; cur_sym_hashes < sym_hashes; 937 1.1.1.4 christos cur_sym_hashes++) 938 1.1.1.4 christos /* If the current symbol is identical to 'sym_hash', that means 939 1.1.1.4 christos the symbol was already adjusted (or at least checked). */ 940 1.1.1.4 christos if (*cur_sym_hashes == sym_hash) 941 1.1.1.4 christos break; 942 1.1.1.4 christos 943 1.1.1.4 christos /* Don't adjust the symbol again. */ 944 1.1.1.4 christos if (cur_sym_hashes < sym_hashes) 945 1.1.1.4 christos continue; 946 1.1.1.4 christos } 947 1.1.1.4 christos 948 1.1.1.4 christos if ((sym_hash->root.type == bfd_link_hash_defined 949 1.1.1.4 christos || sym_hash->root.type == bfd_link_hash_defweak) 950 1.1.1.4 christos && sym_hash->root.u.def.section == sec 951 1.1.1.4 christos && sym_hash->root.u.def.value > addr 952 1.1.1.4 christos && sym_hash->root.u.def.value < toaddr) 953 1.1.1.4 christos sym_hash->root.u.def.value -= count; 954 1.1.1.6 christos } 955 1.1.1.4 christos 956 1.1.1.4 christos return true; 957 1.1.1.4 christos } 958 1.1.1.4 christos 959 1.1.1.6 christos /* Return TRUE if LOC can be a target of a branch, jump or call. */ 960 1.1.1.4 christos 961 1.1.1.4 christos static bool 962 1.1.1.4 christos elf32_ft32_relax_is_branch_target (struct bfd_link_info *link_info, 963 1.1.1.4 christos bfd * abfd, asection * sec, 964 1.1.1.4 christos bfd_vma loc) 965 1.1.1.4 christos { 966 1.1.1.4 christos Elf_Internal_Shdr *symtab_hdr; 967 1.1.1.4 christos Elf_Internal_Rela *irel, *irelend; 968 1.1.1.4 christos Elf_Internal_Sym *isym; 969 1.1.1.4 christos Elf_Internal_Sym *isymbuf = NULL; 970 1.1.1.4 christos bfd_vma symval; 971 1.1.1.4 christos struct bfd_section *isec; 972 1.1.1.4 christos 973 1.1.1.4 christos struct elf_link_hash_entry **sym_hashes; 974 1.1.1.4 christos struct elf_link_hash_entry **end_hashes; 975 1.1.1.4 christos struct elf_link_hash_entry **start_hashes; 976 1.1.1.4 christos unsigned int symcount; 977 1.1.1.4 christos 978 1.1.1.4 christos symtab_hdr = &elf_tdata (abfd)->symtab_hdr; 979 1.1.1.4 christos 980 1.1.1.4 christos /* Now we check for relocations pointing to ret. */ 981 1.1.1.4 christos for (isec = abfd->sections; isec; isec = isec->next) 982 1.1.1.4 christos { 983 1.1.1.6 christos irel = elf_section_data (isec)->relocs; 984 1.1.1.4 christos if (irel == NULL) 985 1.1.1.4 christos irel = _bfd_elf_link_read_relocs (abfd, isec, NULL, NULL, true); 986 1.1.1.4 christos 987 1.1.1.4 christos irelend = irel + isec->reloc_count; 988 1.1.1.4 christos 989 1.1.1.4 christos for (; irel < irelend; irel++) 990 1.1.1.4 christos { 991 1.1.1.4 christos /* Read this BFD's local symbols if we haven't done 992 1.1.1.4 christos so already. */ 993 1.1.1.4 christos if (isymbuf == NULL && symtab_hdr->sh_info != 0) 994 1.1.1.4 christos { 995 1.1.1.4 christos isymbuf = (Elf_Internal_Sym *) symtab_hdr->contents; 996 1.1.1.4 christos if (isymbuf == NULL) 997 1.1.1.4 christos isymbuf = bfd_elf_get_elf_syms (abfd, symtab_hdr, 998 1.1.1.4 christos symtab_hdr->sh_info, 0, 999 1.1.1.6 christos NULL, NULL, NULL); 1000 1.1.1.4 christos if (isymbuf == NULL) 1001 1.1.1.4 christos return false; 1002 1.1.1.4 christos } 1003 1.1.1.4 christos 1004 1.1.1.4 christos /* Get the value of the symbol referred to by the reloc. */ 1005 1.1.1.4 christos if (ELF32_R_SYM (irel->r_info) < symtab_hdr->sh_info) 1006 1.1.1.4 christos { 1007 1.1.1.4 christos /* A local symbol. */ 1008 1.1.1.4 christos asection *sym_sec; 1009 1.1.1.4 christos 1010 1.1.1.4 christos isym = isymbuf + ELF32_R_SYM (irel->r_info); 1011 1.1.1.4 christos sym_sec = bfd_section_from_elf_index (abfd, isym->st_shndx); 1012 1.1.1.4 christos symval = isym->st_value; 1013 1.1.1.4 christos /* If the reloc is absolute, it will not have 1014 1.1.1.4 christos a symbol or section associated with it. */ 1015 1.1.1.4 christos if (sym_sec == sec) 1016 1.1.1.4 christos { 1017 1.1.1.4 christos symval += sym_sec->output_section->vma 1018 1.1.1.4 christos + sym_sec->output_offset; 1019 1.1.1.4 christos 1020 1.1.1.4 christos if (debug_relax) 1021 1.1.1.4 christos printf ("0x%x: Address of anchor symbol: 0x%x " 1022 1.1.1.4 christos "Address of relocation target: 0x%x \n", 1023 1.1.1.4 christos (unsigned int) irel->r_offset, 1024 1.1.1.4 christos (unsigned int) symval, 1025 1.1.1.6 christos (unsigned int) (symval + irel->r_addend)); 1026 1.1.1.4 christos if ((irel->r_addend) == loc) 1027 1.1.1.4 christos return true; 1028 1.1.1.4 christos } 1029 1.1.1.4 christos } 1030 1.1.1.4 christos } 1031 1.1.1.4 christos } 1032 1.1.1.4 christos 1033 1.1.1.4 christos symcount = (symtab_hdr->sh_size / sizeof (Elf32_External_Sym) 1034 1.1.1.4 christos - symtab_hdr->sh_info); 1035 1.1.1.4 christos sym_hashes = start_hashes = elf_sym_hashes (abfd); 1036 1.1.1.4 christos end_hashes = sym_hashes + symcount; 1037 1.1.1.4 christos 1038 1.1.1.4 christos for (; sym_hashes < end_hashes; sym_hashes++) 1039 1.1.1.4 christos { 1040 1.1.1.4 christos struct elf_link_hash_entry *sym_hash = *sym_hashes; 1041 1.1.1.4 christos 1042 1.1.1.4 christos /* The '--wrap SYMBOL' option is causing a pain when the object file, 1043 1.1.1.4 christos containing the definition of __wrap_SYMBOL, includes a direct 1044 1.1.1.4 christos call to SYMBOL as well. Since both __wrap_SYMBOL and SYMBOL reference 1045 1.1.1.4 christos the same symbol (which is __wrap_SYMBOL), but still exist as two 1046 1.1.1.4 christos different symbols in 'sym_hashes', we don't want to adjust 1047 1.1.1.4 christos the global symbol __wrap_SYMBOL twice. 1048 1.1.1.4 christos This check is only relevant when symbols are being wrapped. */ 1049 1.1.1.4 christos if (link_info->wrap_hash != NULL) 1050 1.1.1.4 christos { 1051 1.1.1.4 christos struct elf_link_hash_entry **cur_sym_hashes; 1052 1.1.1.4 christos 1053 1.1.1.4 christos /* Loop only over the symbols whom been already checked. */ 1054 1.1.1.4 christos for (cur_sym_hashes = start_hashes; cur_sym_hashes < sym_hashes; 1055 1.1.1.4 christos cur_sym_hashes++) 1056 1.1.1.4 christos /* If the current symbol is identical to 'sym_hash', that means 1057 1.1.1.4 christos the symbol was already adjusted (or at least checked). */ 1058 1.1.1.4 christos if (*cur_sym_hashes == sym_hash) 1059 1.1.1.4 christos break; 1060 1.1.1.4 christos 1061 1.1.1.4 christos /* Don't adjust the symbol again. */ 1062 1.1.1.4 christos if (cur_sym_hashes < sym_hashes) 1063 1.1.1.4 christos continue; 1064 1.1.1.4 christos } 1065 1.1.1.4 christos 1066 1.1.1.4 christos if ((sym_hash->root.type == bfd_link_hash_defined 1067 1.1.1.4 christos || sym_hash->root.type == bfd_link_hash_defweak) 1068 1.1.1.6 christos && sym_hash->root.u.def.section == sec 1069 1.1.1.4 christos && sym_hash->root.u.def.value == loc) 1070 1.1.1.4 christos return true; 1071 1.1.1.6 christos } 1072 1.1.1.4 christos 1073 1.1.1.4 christos return false; 1074 1.1.1.6 christos } 1075 1.1.1.6 christos 1076 1.1.1.6 christos static bool 1077 1.1.1.6 christos ft32_elf_relax_section (bfd *abfd, 1078 1.1.1.6 christos asection *sec, 1079 1.1.1.4 christos struct bfd_link_info *link_info, 1080 1.1.1.4 christos bool *again) 1081 1.1.1.4 christos { 1082 1.1.1.4 christos Elf_Internal_Rela * free_relocs = NULL; 1083 1.1.1.4 christos Elf_Internal_Rela * internal_relocs; 1084 1.1.1.4 christos Elf_Internal_Rela * irelend; 1085 1.1.1.4 christos Elf_Internal_Rela * irel; 1086 1.1.1.4 christos bfd_byte * contents = NULL; 1087 1.1.1.4 christos Elf_Internal_Shdr * symtab_hdr; 1088 1.1.1.4 christos Elf_Internal_Sym * isymbuf = NULL; 1089 1.1.1.6 christos 1090 1.1.1.4 christos /* Assume nothing changes. */ 1091 1.1.1.4 christos *again = false; 1092 1.1.1.4 christos 1093 1.1.1.4 christos /* We don't have to do anything for a relocatable link, if 1094 1.1.1.4 christos this section does not have relocs, or if this is not a 1095 1.1.1.4 christos code section. */ 1096 1.1.1.7 christos if (bfd_link_relocatable (link_info) 1097 1.1.1.7 christos || sec->reloc_count == 0 1098 1.1.1.4 christos || (sec->flags & SEC_RELOC) == 0 1099 1.1.1.6 christos || (sec->flags & SEC_HAS_CONTENTS) == 0 1100 1.1.1.4 christos || (sec->flags & SEC_CODE) == 0) 1101 1.1.1.4 christos return true; 1102 1.1.1.4 christos 1103 1.1.1.4 christos /* Get the section contents. */ 1104 1.1.1.4 christos if (elf_section_data (sec)->this_hdr.contents != NULL) 1105 1.1.1.4 christos contents = elf_section_data (sec)->this_hdr.contents; 1106 1.1.1.4 christos /* Go get them off disk. */ 1107 1.1.1.4 christos else 1108 1.1.1.4 christos { 1109 1.1.1.4 christos if (! bfd_malloc_and_get_section (abfd, sec, &contents)) 1110 1.1.1.4 christos goto error_return; 1111 1.1.1.4 christos elf_section_data (sec)->this_hdr.contents = contents; 1112 1.1.1.4 christos } 1113 1.1.1.4 christos 1114 1.1.1.4 christos symtab_hdr = &elf_tdata (abfd)->symtab_hdr; 1115 1.1.1.4 christos 1116 1.1.1.4 christos /* Read this BFD's local symbols if we haven't done so already. */ 1117 1.1.1.4 christos if (isymbuf == NULL && symtab_hdr->sh_info != 0) 1118 1.1.1.4 christos { 1119 1.1.1.4 christos isymbuf = (Elf_Internal_Sym *) symtab_hdr->contents; 1120 1.1.1.4 christos if (isymbuf == NULL) 1121 1.1.1.4 christos isymbuf = bfd_elf_get_elf_syms (abfd, symtab_hdr, 1122 1.1.1.4 christos symtab_hdr->sh_info, 0, 1123 1.1.1.4 christos NULL, NULL, NULL); 1124 1.1.1.4 christos if (isymbuf == NULL) 1125 1.1.1.4 christos goto error_return; 1126 1.1.1.4 christos symtab_hdr->contents = (unsigned char *) isymbuf; 1127 1.1.1.4 christos } 1128 1.1.1.4 christos 1129 1.1.1.4 christos internal_relocs = _bfd_elf_link_read_relocs (abfd, sec, NULL, NULL, 1130 1.1.1.4 christos link_info->keep_memory); 1131 1.1.1.4 christos if (internal_relocs == NULL) 1132 1.1.1.4 christos goto error_return; 1133 1.1.1.4 christos if (! link_info->keep_memory) 1134 1.1.1.4 christos free_relocs = internal_relocs; 1135 1.1.1.4 christos 1136 1.1.1.4 christos /* Walk through them looking for relaxing opportunities. */ 1137 1.1.1.4 christos irelend = internal_relocs + sec->reloc_count; 1138 1.1.1.4 christos 1139 1.1.1.4 christos /* Test every adjacent pair of relocs. If both have shortcodes, 1140 1.1.1.4 christos fuse them and delete the relocs. */ 1141 1.1.1.4 christos irel = internal_relocs; 1142 1.1.1.4 christos while (irel < irelend - 1) 1143 1.1.1.4 christos { 1144 1.1.1.4 christos Elf_Internal_Rela * irel_next = irel + 1; 1145 1.1.1.4 christos unsigned int sc0, sc1; 1146 1.1.1.4 christos bfd_vma pc; 1147 1.1.1.4 christos 1148 1.1.1.4 christos pc = irel->r_offset; 1149 1.1.1.4 christos 1150 1.1.1.4 christos if (((pc + 4) == (irel_next->r_offset)) 1151 1.1.1.4 christos && ft32_reloc_shortable (abfd, sec, isymbuf, contents, pc, irel, 1152 1.1.1.4 christos &sc0) 1153 1.1.1.4 christos && ft32_reloc_shortable (abfd, sec, isymbuf, contents, pc, 1154 1.1.1.4 christos irel_next, &sc1) 1155 1.1.1.4 christos && !elf32_ft32_relax_is_branch_target (link_info, abfd, sec, 1156 1.1.1.4 christos irel_next->r_offset)) 1157 1.1.1.4 christos { 1158 1.1.1.4 christos unsigned int code30 = (sc1 << 15) | sc0; 1159 1.1.1.4 christos unsigned int code27 = code30 >> 3; 1160 1.1.1.4 christos unsigned int code3 = code30 & 7; 1161 1.1.1.4 christos static const unsigned char pat3[] = {2, 3, 4, 5, 6, 9, 10, 14}; 1162 1.1.1.4 christos unsigned int pattern = pat3[code3]; 1163 1.1.1.4 christos unsigned int fused = (pattern << 27) | code27; 1164 1.1.1.4 christos 1165 1.1.1.4 christos /* Move second reloc to same place as first. */ 1166 1.1.1.4 christos irel_next->r_offset = irel->r_offset; 1167 1.1.1.4 christos 1168 1.1.1.4 christos /* Change both relocs to R_FT32_NONE. */ 1169 1.1.1.4 christos 1170 1.1.1.4 christos if (ELF32_R_TYPE (irel->r_info) == R_FT32_18) 1171 1.1.1.4 christos { 1172 1.1.1.4 christos irel->r_info = ELF32_R_INFO (ELF32_R_SYM (irel->r_info), 1173 1.1.1.4 christos R_FT32_SC0); 1174 1.1.1.4 christos } 1175 1.1.1.4 christos else 1176 1.1.1.4 christos { 1177 1.1.1.4 christos irel->r_info = ELF32_R_INFO (ELF32_R_SYM (irel->r_info), 1178 1.1.1.4 christos R_FT32_NONE); 1179 1.1.1.4 christos } 1180 1.1.1.4 christos 1181 1.1.1.4 christos if (ELF32_R_TYPE (irel_next->r_info) == R_FT32_18) 1182 1.1.1.4 christos { 1183 1.1.1.4 christos irel_next->r_info = ELF32_R_INFO (ELF32_R_SYM (irel_next->r_info), 1184 1.1.1.4 christos R_FT32_SC1); 1185 1.1.1.4 christos } 1186 1.1.1.4 christos else 1187 1.1.1.4 christos { 1188 1.1.1.4 christos irel_next->r_info = ELF32_R_INFO (ELF32_R_SYM (irel->r_info), 1189 1.1.1.4 christos R_FT32_NONE); 1190 1.1.1.4 christos } 1191 1.1.1.4 christos 1192 1.1.1.4 christos /* Replace the first insn with the fused version. */ 1193 1.1.1.4 christos bfd_put_32 (abfd, fused, contents + irel->r_offset); 1194 1.1.1.4 christos 1195 1.1.1.4 christos /* Delete the second insn. */ 1196 1.1.1.4 christos if (!elf32_ft32_relax_delete_bytes (link_info, abfd, sec, 1197 1.1.1.4 christos irel->r_offset + 4, 4)) 1198 1.1.1.4 christos goto error_return; 1199 1.1.1.4 christos 1200 1.1.1.6 christos /* That will change things, so, we should relax again. 1201 1.1.1.4 christos Note that this is not required, and it may be slow. */ 1202 1.1.1.4 christos *again = true; 1203 1.1.1.4 christos 1204 1.1.1.4 christos irel += 2; 1205 1.1.1.4 christos } 1206 1.1.1.4 christos else 1207 1.1.1.4 christos { 1208 1.1.1.4 christos irel += 1; 1209 1.1.1.4 christos } 1210 1.1.1.4 christos } 1211 1.1.1.4 christos 1212 1.1.1.4 christos if (isymbuf != NULL 1213 1.1.1.4 christos && symtab_hdr->contents != (unsigned char *) isymbuf) 1214 1.1.1.4 christos { 1215 1.1.1.4 christos if (! link_info->keep_memory) 1216 1.1.1.4 christos free (isymbuf); 1217 1.1.1.4 christos else 1218 1.1.1.4 christos /* Cache the symbols for elf_link_input_bfd. */ 1219 1.1.1.4 christos symtab_hdr->contents = (unsigned char *) isymbuf; 1220 1.1.1.4 christos } 1221 1.1.1.4 christos 1222 1.1.1.4 christos if (contents != NULL 1223 1.1.1.4 christos && elf_section_data (sec)->this_hdr.contents != contents) 1224 1.1.1.4 christos { 1225 1.1.1.4 christos if (! link_info->keep_memory) 1226 1.1.1.4 christos free (contents); 1227 1.1.1.4 christos else 1228 1.1.1.4 christos /* Cache the section contents for elf_link_input_bfd. */ 1229 1.1.1.4 christos elf_section_data (sec)->this_hdr.contents = contents; 1230 1.1.1.4 christos 1231 1.1.1.5 christos } 1232 1.1.1.4 christos 1233 1.1.1.4 christos if (elf_section_data (sec)->relocs != internal_relocs) 1234 1.1.1.6 christos free (internal_relocs); 1235 1.1.1.4 christos 1236 1.1.1.4 christos return true; 1237 1.1.1.5 christos 1238 1.1.1.4 christos error_return: 1239 1.1.1.6 christos free (free_relocs); 1240 1.1.1.4 christos 1241 1.1.1.4 christos return true; 1242 1.1 christos } 1243 1.1 christos 1244 1.1 christos #define ELF_ARCH bfd_arch_ft32 1246 1.1 christos #define ELF_MACHINE_CODE EM_FT32 1247 1.1 christos #define ELF_MAXPAGESIZE 0x1 1248 1.1 christos 1249 1.1 christos #define TARGET_LITTLE_SYM ft32_elf32_vec 1250 1.1 christos #define TARGET_LITTLE_NAME "elf32-ft32" 1251 1.1 christos 1252 1.1 christos #define elf_info_to_howto_rel NULL 1253 1.1 christos #define elf_info_to_howto ft32_info_to_howto_rela 1254 1.1 christos #define elf_backend_relocate_section ft32_elf_relocate_section 1255 1.1 christos 1256 1.1 christos #define elf_backend_can_gc_sections 1 1257 1.1 christos #define elf_backend_rela_normal 1 1258 1.1 christos 1259 1.1.1.4 christos #define bfd_elf32_bfd_reloc_type_lookup ft32_reloc_type_lookup 1260 1.1.1.4 christos #define bfd_elf32_bfd_reloc_name_lookup ft32_reloc_name_lookup 1261 1.1 christos 1262 #define bfd_elf32_bfd_relax_section ft32_elf_relax_section 1263 1264 #include "elf32-target.h" 1265