1 1.1 christos /* Ubicom IP2xxx specific support for 32-bit ELF 2 1.11 christos Copyright (C) 2000-2024 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 modify 7 1.1 christos it under the terms of the GNU General Public License as published by 8 1.1 christos the Free Software Foundation; either version 3 of the License, or 9 1.1 christos (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, 12 1.1 christos but WITHOUT ANY WARRANTY; without even the implied warranty of 13 1.1 christos MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 1.1 christos GNU 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, 19 1.1 christos MA 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 #include "libbfd.h" 24 1.1 christos #include "elf-bfd.h" 25 1.1 christos #include "elf/ip2k.h" 26 1.1 christos 27 1.1 christos /* Struct used to pass miscellaneous paramaters which 28 1.1 christos helps to avoid overly long parameter lists. */ 29 1.1 christos struct misc 30 1.1 christos { 31 1.1 christos Elf_Internal_Shdr * symtab_hdr; 32 1.1 christos Elf_Internal_Rela * irelbase; 33 1.8 christos bfd_byte * contents; 34 1.1 christos Elf_Internal_Sym * isymbuf; 35 1.1 christos }; 36 1.1 christos 37 1.1 christos struct ip2k_opcode 38 1.1 christos { 39 1.1 christos unsigned short opcode; 40 1.1 christos unsigned short mask; 41 1.1 christos }; 42 1.1 christos 43 1.10 christos static bool ip2k_relaxed = false; 44 1.1 christos 45 1.1 christos static const struct ip2k_opcode ip2k_page_opcode[] = 46 1.1 christos { 47 1.1 christos {0x0010, 0xFFF8}, /* Page. */ 48 1.1 christos {0x0000, 0x0000}, 49 1.1 christos }; 50 1.1 christos 51 1.1 christos #define IS_PAGE_OPCODE(code) \ 52 1.1 christos ip2k_is_opcode (code, ip2k_page_opcode) 53 1.1 christos 54 1.1 christos static const struct ip2k_opcode ip2k_jmp_opcode[] = 55 1.1 christos { 56 1.1 christos {0xE000, 0xE000}, /* Jmp. */ 57 1.1 christos {0x0000, 0x0000}, 58 1.1 christos }; 59 1.1 christos 60 1.1 christos #define IS_JMP_OPCODE(code) \ 61 1.1 christos ip2k_is_opcode (code, ip2k_jmp_opcode) 62 1.1 christos 63 1.1 christos static const struct ip2k_opcode ip2k_snc_opcode[] = 64 1.1 christos { 65 1.1 christos {0xA00B, 0xFFFF}, /* Snc. */ 66 1.1 christos {0x0000, 0x0000}, 67 1.1 christos }; 68 1.1 christos 69 1.1 christos #define IS_SNC_OPCODE(code) \ 70 1.1 christos ip2k_is_opcode (code, ip2k_snc_opcode) 71 1.1 christos 72 1.1 christos static const struct ip2k_opcode ip2k_inc_1sp_opcode[] = 73 1.1 christos { 74 1.1 christos {0x2B81, 0xFFFF}, /* Inc 1(SP). */ 75 1.1 christos {0x0000, 0x0000}, 76 1.1 christos }; 77 1.1 christos 78 1.1 christos #define IS_INC_1SP_OPCODE(code) \ 79 1.1 christos ip2k_is_opcode (code, ip2k_inc_1sp_opcode) 80 1.1 christos 81 1.1 christos static const struct ip2k_opcode ip2k_add_2sp_w_opcode[] = 82 1.1 christos { 83 1.1 christos {0x1F82, 0xFFFF}, /* Add 2(SP),w. */ 84 1.1 christos {0x0000, 0x0000}, 85 1.1 christos }; 86 1.1 christos 87 1.1 christos #define IS_ADD_2SP_W_OPCODE(code) \ 88 1.1 christos ip2k_is_opcode (code, ip2k_add_2sp_w_opcode) 89 1.1 christos 90 1.1 christos static const struct ip2k_opcode ip2k_add_w_wreg_opcode[] = 91 1.1 christos { 92 1.1 christos {0x1C0A, 0xFFFF}, /* Add w,wreg. */ 93 1.1 christos {0x1E0A, 0xFFFF}, /* Add wreg,w. */ 94 1.1 christos {0x0000, 0x0000}, 95 1.1 christos }; 96 1.1 christos 97 1.1 christos #define IS_ADD_W_WREG_OPCODE(code) \ 98 1.1 christos ip2k_is_opcode (code, ip2k_add_w_wreg_opcode) 99 1.1 christos 100 1.1 christos static const struct ip2k_opcode ip2k_add_pcl_w_opcode[] = 101 1.1 christos { 102 1.1 christos {0x1E09, 0xFFFF}, /* Add pcl,w. */ 103 1.1 christos {0x0000, 0x0000}, 104 1.1 christos }; 105 1.1 christos 106 1.1 christos #define IS_ADD_PCL_W_OPCODE(code) \ 107 1.1 christos ip2k_is_opcode (code, ip2k_add_pcl_w_opcode) 108 1.1 christos 109 1.1 christos static const struct ip2k_opcode ip2k_skip_opcodes[] = 110 1.1 christos { 111 1.1 christos {0xB000, 0xF000}, /* sb */ 112 1.1 christos {0xA000, 0xF000}, /* snb */ 113 1.1 christos {0x7600, 0xFE00}, /* cse/csne #lit */ 114 1.1 christos {0x5800, 0xFC00}, /* incsnz */ 115 1.1 christos {0x4C00, 0xFC00}, /* decsnz */ 116 1.1 christos {0x4000, 0xFC00}, /* cse/csne */ 117 1.1 christos {0x3C00, 0xFC00}, /* incsz */ 118 1.1 christos {0x2C00, 0xFC00}, /* decsz */ 119 1.1 christos {0x0000, 0x0000}, 120 1.1 christos }; 121 1.1 christos 122 1.1 christos #define IS_SKIP_OPCODE(code) \ 123 1.1 christos ip2k_is_opcode (code, ip2k_skip_opcodes) 124 1.1 christos 125 1.1 christos /* Relocation tables. */ 126 1.1 christos static reloc_howto_type ip2k_elf_howto_table [] = 127 1.1 christos { 128 1.1 christos #define IP2K_HOWTO(t,rs,s,bs,pr,bp,name,sm,dm) \ 129 1.8 christos HOWTO(t, /* type */ \ 130 1.8 christos rs, /* rightshift */ \ 131 1.8 christos s, /* size (0 = byte, 1 = short, 2 = long) */ \ 132 1.8 christos bs, /* bitsize */ \ 133 1.8 christos pr, /* pc_relative */ \ 134 1.8 christos bp, /* bitpos */ \ 135 1.8 christos complain_overflow_dont,/* complain_on_overflow */ \ 136 1.8 christos bfd_elf_generic_reloc,/* special_function */ \ 137 1.8 christos name, /* name */ \ 138 1.10 christos false, /* partial_inplace */ \ 139 1.8 christos sm, /* src_mask */ \ 140 1.8 christos dm, /* dst_mask */ \ 141 1.8 christos pr) /* pcrel_offset */ 142 1.1 christos 143 1.1 christos /* This reloc does nothing. */ 144 1.10 christos IP2K_HOWTO (R_IP2K_NONE, 0,0,0, false, 0, "R_IP2K_NONE", 0, 0), 145 1.1 christos /* A 16 bit absolute relocation. */ 146 1.10 christos IP2K_HOWTO (R_IP2K_16, 0,2,16, false, 0, "R_IP2K_16", 0, 0xffff), 147 1.1 christos /* A 32 bit absolute relocation. */ 148 1.10 christos IP2K_HOWTO (R_IP2K_32, 0,4,32, false, 0, "R_IP2K_32", 0, 0xffffffff), 149 1.1 christos /* A 8-bit data relocation for the FR9 field. Ninth bit is computed specially. */ 150 1.10 christos IP2K_HOWTO (R_IP2K_FR9, 0,2,9, false, 0, "R_IP2K_FR9", 0, 0x00ff), 151 1.1 christos /* A 4-bit data relocation. */ 152 1.10 christos IP2K_HOWTO (R_IP2K_BANK, 8,2,4, false, 0, "R_IP2K_BANK", 0, 0x000f), 153 1.1 christos /* A 13-bit insn relocation - word address => right-shift 1 bit extra. */ 154 1.10 christos IP2K_HOWTO (R_IP2K_ADDR16CJP, 1,2,13, false, 0, "R_IP2K_ADDR16CJP", 0, 0x1fff), 155 1.1 christos /* A 3-bit insn relocation - word address => right-shift 1 bit extra. */ 156 1.10 christos IP2K_HOWTO (R_IP2K_PAGE3, 14,2,3, false, 0, "R_IP2K_PAGE3", 0, 0x0007), 157 1.1 christos /* Two 8-bit data relocations. */ 158 1.10 christos IP2K_HOWTO (R_IP2K_LO8DATA, 0,2,8, false, 0, "R_IP2K_LO8DATA", 0, 0x00ff), 159 1.10 christos IP2K_HOWTO (R_IP2K_HI8DATA, 8,2,8, false, 0, "R_IP2K_HI8DATA", 0, 0x00ff), 160 1.1 christos /* Two 8-bit insn relocations. word address => right-shift 1 bit extra. */ 161 1.10 christos IP2K_HOWTO (R_IP2K_LO8INSN, 1,2,8, false, 0, "R_IP2K_LO8INSN", 0, 0x00ff), 162 1.10 christos IP2K_HOWTO (R_IP2K_HI8INSN, 9,2,8, false, 0, "R_IP2K_HI8INSN", 0, 0x00ff), 163 1.1 christos 164 1.1 christos /* Special 1 bit relocation for SKIP instructions. */ 165 1.10 christos IP2K_HOWTO (R_IP2K_PC_SKIP, 1,2,1, false, 12, "R_IP2K_PC_SKIP", 0xfffe, 0x1000), 166 1.1 christos /* 16 bit word address. */ 167 1.10 christos IP2K_HOWTO (R_IP2K_TEXT, 1,2,16, false, 0, "R_IP2K_TEXT", 0, 0xffff), 168 1.1 christos /* A 7-bit offset relocation for the FR9 field. Eigth and ninth bit comes from insn. */ 169 1.10 christos IP2K_HOWTO (R_IP2K_FR_OFFSET, 0,2,9, false, 0, "R_IP2K_FR_OFFSET", 0x180, 0x007f), 170 1.1 christos /* Bits 23:16 of an address. */ 171 1.10 christos IP2K_HOWTO (R_IP2K_EX8DATA, 16,2,8, false, 0, "R_IP2K_EX8DATA", 0, 0x00ff), 172 1.1 christos }; 173 1.1 christos 174 1.1 christos 175 1.1 christos /* Map BFD reloc types to IP2K ELF reloc types. */ 176 1.1 christos 177 1.1 christos static reloc_howto_type * 178 1.1 christos ip2k_reloc_type_lookup (bfd * abfd ATTRIBUTE_UNUSED, 179 1.1 christos bfd_reloc_code_real_type code) 180 1.1 christos { 181 1.1 christos /* Note that the ip2k_elf_howto_table is indxed by the R_ 182 1.1 christos constants. Thus, the order that the howto records appear in the 183 1.1 christos table *must* match the order of the relocation types defined in 184 1.1 christos include/elf/ip2k.h. */ 185 1.1 christos 186 1.1 christos switch (code) 187 1.1 christos { 188 1.1 christos case BFD_RELOC_NONE: 189 1.1 christos return &ip2k_elf_howto_table[ (int) R_IP2K_NONE]; 190 1.1 christos case BFD_RELOC_16: 191 1.1 christos return &ip2k_elf_howto_table[ (int) R_IP2K_16]; 192 1.1 christos case BFD_RELOC_32: 193 1.1 christos return &ip2k_elf_howto_table[ (int) R_IP2K_32]; 194 1.1 christos case BFD_RELOC_IP2K_FR9: 195 1.1 christos return &ip2k_elf_howto_table[ (int) R_IP2K_FR9]; 196 1.1 christos case BFD_RELOC_IP2K_BANK: 197 1.1 christos return &ip2k_elf_howto_table[ (int) R_IP2K_BANK]; 198 1.1 christos case BFD_RELOC_IP2K_ADDR16CJP: 199 1.1 christos return &ip2k_elf_howto_table[ (int) R_IP2K_ADDR16CJP]; 200 1.1 christos case BFD_RELOC_IP2K_PAGE3: 201 1.1 christos return &ip2k_elf_howto_table[ (int) R_IP2K_PAGE3]; 202 1.1 christos case BFD_RELOC_IP2K_LO8DATA: 203 1.1 christos return &ip2k_elf_howto_table[ (int) R_IP2K_LO8DATA]; 204 1.1 christos case BFD_RELOC_IP2K_HI8DATA: 205 1.1 christos return &ip2k_elf_howto_table[ (int) R_IP2K_HI8DATA]; 206 1.1 christos case BFD_RELOC_IP2K_LO8INSN: 207 1.1 christos return &ip2k_elf_howto_table[ (int) R_IP2K_LO8INSN]; 208 1.1 christos case BFD_RELOC_IP2K_HI8INSN: 209 1.1 christos return &ip2k_elf_howto_table[ (int) R_IP2K_HI8INSN]; 210 1.1 christos case BFD_RELOC_IP2K_PC_SKIP: 211 1.1 christos return &ip2k_elf_howto_table[ (int) R_IP2K_PC_SKIP]; 212 1.1 christos case BFD_RELOC_IP2K_TEXT: 213 1.1 christos return &ip2k_elf_howto_table[ (int) R_IP2K_TEXT]; 214 1.1 christos case BFD_RELOC_IP2K_FR_OFFSET: 215 1.1 christos return &ip2k_elf_howto_table[ (int) R_IP2K_FR_OFFSET]; 216 1.1 christos case BFD_RELOC_IP2K_EX8DATA: 217 1.1 christos return &ip2k_elf_howto_table[ (int) R_IP2K_EX8DATA]; 218 1.1 christos default: 219 1.1 christos /* Pacify gcc -Wall. */ 220 1.1 christos return NULL; 221 1.1 christos } 222 1.1 christos return NULL; 223 1.1 christos } 224 1.1 christos 225 1.1 christos static reloc_howto_type * 226 1.1 christos ip2k_reloc_name_lookup (bfd *abfd ATTRIBUTE_UNUSED, const char *r_name) 227 1.1 christos { 228 1.1 christos unsigned int i; 229 1.1 christos 230 1.1 christos for (i = 0; 231 1.1 christos i < sizeof (ip2k_elf_howto_table) / sizeof (ip2k_elf_howto_table[0]); 232 1.1 christos i++) 233 1.1 christos if (ip2k_elf_howto_table[i].name != NULL 234 1.1 christos && strcasecmp (ip2k_elf_howto_table[i].name, r_name) == 0) 235 1.1 christos return &ip2k_elf_howto_table[i]; 236 1.1 christos 237 1.1 christos return NULL; 238 1.1 christos } 239 1.1 christos 240 1.1 christos static void 241 1.1 christos ip2k_get_mem (bfd *abfd ATTRIBUTE_UNUSED, 242 1.1 christos bfd_byte *addr, 243 1.1 christos int length, 244 1.1 christos bfd_byte *ptr) 245 1.1 christos { 246 1.1 christos while (length --) 247 1.1 christos * ptr ++ = bfd_get_8 (abfd, addr ++); 248 1.1 christos } 249 1.1 christos 250 1.10 christos static bool 251 1.1 christos ip2k_is_opcode (bfd_byte *code, const struct ip2k_opcode *opcodes) 252 1.1 christos { 253 1.1 christos unsigned short insn = (code[0] << 8) | code[1]; 254 1.1 christos 255 1.1 christos while (opcodes->mask != 0) 256 1.1 christos { 257 1.1 christos if ((insn & opcodes->mask) == opcodes->opcode) 258 1.10 christos return true; 259 1.1 christos 260 1.1 christos opcodes ++; 261 1.1 christos } 262 1.1 christos 263 1.10 christos return false; 264 1.1 christos } 265 1.1 christos 266 1.1 christos #define PAGENO(ABSADDR) ((ABSADDR) & 0xFFFFC000) 267 1.1 christos #define BASEADDR(SEC) ((SEC)->output_section->vma + (SEC)->output_offset) 268 1.1 christos 269 1.1 christos #define UNDEFINED_SYMBOL (~(bfd_vma)0) 270 1.1 christos 271 1.1 christos /* Return the value of the symbol associated with the relocation IREL. */ 272 1.1 christos 273 1.1 christos static bfd_vma 274 1.1 christos symbol_value (bfd *abfd, 275 1.1 christos Elf_Internal_Shdr *symtab_hdr, 276 1.1 christos Elf_Internal_Sym *isymbuf, 277 1.1 christos Elf_Internal_Rela *irel) 278 1.1 christos { 279 1.1 christos if (ELF32_R_SYM (irel->r_info) < symtab_hdr->sh_info) 280 1.1 christos { 281 1.1 christos Elf_Internal_Sym *isym; 282 1.1 christos asection *sym_sec; 283 1.1 christos 284 1.1 christos isym = isymbuf + ELF32_R_SYM (irel->r_info); 285 1.1 christos if (isym->st_shndx == SHN_UNDEF) 286 1.1 christos sym_sec = bfd_und_section_ptr; 287 1.1 christos else if (isym->st_shndx == SHN_ABS) 288 1.1 christos sym_sec = bfd_abs_section_ptr; 289 1.1 christos else if (isym->st_shndx == SHN_COMMON) 290 1.1 christos sym_sec = bfd_com_section_ptr; 291 1.1 christos else 292 1.1 christos sym_sec = bfd_section_from_elf_index (abfd, isym->st_shndx); 293 1.1 christos 294 1.1 christos return isym->st_value + BASEADDR (sym_sec); 295 1.1 christos } 296 1.1 christos else 297 1.1 christos { 298 1.1 christos unsigned long indx; 299 1.1 christos struct elf_link_hash_entry *h; 300 1.1 christos 301 1.1 christos indx = ELF32_R_SYM (irel->r_info) - symtab_hdr->sh_info; 302 1.1 christos h = elf_sym_hashes (abfd)[indx]; 303 1.1 christos BFD_ASSERT (h != NULL); 304 1.1 christos 305 1.1 christos if (h->root.type != bfd_link_hash_defined 306 1.1 christos && h->root.type != bfd_link_hash_defweak) 307 1.1 christos return UNDEFINED_SYMBOL; 308 1.1 christos 309 1.1 christos return (h->root.u.def.value + BASEADDR (h->root.u.def.section)); 310 1.1 christos } 311 1.1 christos } 312 1.1 christos 313 1.1 christos /* Determine if the instruction sequence matches that for 314 1.1 christos the prologue of a switch dispatch table with fewer than 315 1.1 christos 128 entries. 316 1.1 christos 317 1.8 christos sc 318 1.8 christos page $nnn0 319 1.8 christos jmp $nnn0 320 1.8 christos add w,wreg 321 1.8 christos add pcl,w 322 1.1 christos addr=> 323 1.8 christos page $nnn1 324 1.8 christos jmp $nnn1 325 1.8 christos page $nnn2 326 1.8 christos jmp $nnn2 327 1.8 christos ... 328 1.8 christos page $nnnN 329 1.8 christos jmp $nnnN 330 1.1 christos 331 1.1 christos After relaxation. 332 1.8 christos sc 333 1.8 christos page $nnn0 334 1.8 christos jmp $nnn0 335 1.8 christos add pcl,w 336 1.1 christos addr=> 337 1.8 christos jmp $nnn1 338 1.8 christos jmp $nnn2 339 1.8 christos ... 340 1.8 christos jmp $nnnN */ 341 1.1 christos 342 1.1 christos static int 343 1.1 christos ip2k_is_switch_table_128 (bfd *abfd ATTRIBUTE_UNUSED, 344 1.1 christos asection *sec, 345 1.1 christos bfd_vma addr, 346 1.1 christos bfd_byte *contents) 347 1.1 christos { 348 1.1 christos bfd_byte code[4]; 349 1.1 christos int table_index = 0; 350 1.1 christos 351 1.1 christos /* Check current page-jmp. */ 352 1.1 christos if (addr + 4 > sec->size) 353 1.1 christos return -1; 354 1.1 christos 355 1.1 christos ip2k_get_mem (abfd, contents + addr, 4, code); 356 1.1 christos 357 1.1 christos if ((! IS_PAGE_OPCODE (code + 0)) 358 1.1 christos || (! IS_JMP_OPCODE (code + 2))) 359 1.1 christos return -1; 360 1.1 christos 361 1.1 christos /* Search back. */ 362 1.1 christos while (1) 363 1.1 christos { 364 1.1 christos if (addr < 4) 365 1.1 christos return -1; 366 1.1 christos 367 1.1 christos /* Check previous 2 instructions. */ 368 1.1 christos ip2k_get_mem (abfd, contents + addr - 4, 4, code); 369 1.1 christos if ((IS_ADD_W_WREG_OPCODE (code + 0)) 370 1.1 christos && (IS_ADD_PCL_W_OPCODE (code + 2))) 371 1.1 christos return table_index; 372 1.1 christos 373 1.1 christos if ((! IS_PAGE_OPCODE (code + 0)) 374 1.1 christos || (! IS_JMP_OPCODE (code + 2))) 375 1.1 christos return -1; 376 1.1 christos 377 1.1 christos table_index++; 378 1.1 christos addr -= 4; 379 1.1 christos } 380 1.1 christos } 381 1.1 christos 382 1.1 christos /* Determine if the instruction sequence matches that for 383 1.1 christos the prologue switch dispatch table with fewer than 384 1.1 christos 256 entries but more than 127. 385 1.1 christos 386 1.1 christos Before relaxation. 387 1.8 christos push %lo8insn(label) ; Push address of table 388 1.8 christos push %hi8insn(label) 389 1.8 christos add w,wreg ; index*2 => offset 390 1.8 christos snc ; CARRY SET? 391 1.8 christos inc 1(sp) ; Propagate MSB into table address 392 1.8 christos add 2(sp),w ; Add low bits of offset to table address 393 1.8 christos snc ; and handle any carry-out 394 1.8 christos inc 1(sp) 395 1.1 christos addr=> 396 1.8 christos page __indjmp ; Do an indirect jump to that location 397 1.8 christos jmp __indjmp 398 1.8 christos label: ; case dispatch table starts here 399 1.8 christos page $nnn1 400 1.8 christos jmp $nnn1 401 1.8 christos page $nnn2 402 1.8 christos jmp $nnn2 403 1.8 christos ... 404 1.8 christos page $nnnN 405 1.8 christos jmp $nnnN 406 1.1 christos 407 1.1 christos After relaxation. 408 1.8 christos push %lo8insn(label) ; Push address of table 409 1.8 christos push %hi8insn(label) 410 1.8 christos add 2(sp),w ; Add low bits of offset to table address 411 1.8 christos snc ; and handle any carry-out 412 1.8 christos inc 1(sp) 413 1.1 christos addr=> 414 1.8 christos page __indjmp ; Do an indirect jump to that location 415 1.8 christos jmp __indjmp 416 1.8 christos label: ; case dispatch table starts here 417 1.8 christos jmp $nnn1 418 1.8 christos jmp $nnn2 419 1.8 christos ... 420 1.8 christos jmp $nnnN */ 421 1.1 christos 422 1.1 christos static int 423 1.1 christos ip2k_is_switch_table_256 (bfd *abfd ATTRIBUTE_UNUSED, 424 1.1 christos asection *sec, 425 1.1 christos bfd_vma addr, 426 1.1 christos bfd_byte *contents) 427 1.1 christos { 428 1.1 christos bfd_byte code[16]; 429 1.1 christos int table_index = 0; 430 1.1 christos 431 1.1 christos /* Check current page-jmp. */ 432 1.1 christos if (addr + 4 > sec->size) 433 1.1 christos return -1; 434 1.1 christos 435 1.1 christos ip2k_get_mem (abfd, contents + addr, 4, code); 436 1.1 christos if ((! IS_PAGE_OPCODE (code + 0)) 437 1.1 christos || (! IS_JMP_OPCODE (code + 2))) 438 1.1 christos return -1; 439 1.1 christos 440 1.1 christos /* Search back. */ 441 1.1 christos while (1) 442 1.1 christos { 443 1.1 christos if (addr < 16) 444 1.1 christos return -1; 445 1.1 christos 446 1.1 christos /* Check previous 8 instructions. */ 447 1.1 christos ip2k_get_mem (abfd, contents + addr - 16, 16, code); 448 1.1 christos if ((IS_ADD_W_WREG_OPCODE (code + 0)) 449 1.1 christos && (IS_SNC_OPCODE (code + 2)) 450 1.1 christos && (IS_INC_1SP_OPCODE (code + 4)) 451 1.1 christos && (IS_ADD_2SP_W_OPCODE (code + 6)) 452 1.1 christos && (IS_SNC_OPCODE (code + 8)) 453 1.1 christos && (IS_INC_1SP_OPCODE (code + 10)) 454 1.1 christos && (IS_PAGE_OPCODE (code + 12)) 455 1.1 christos && (IS_JMP_OPCODE (code + 14))) 456 1.1 christos return table_index; 457 1.1 christos 458 1.1 christos if ((IS_ADD_W_WREG_OPCODE (code + 2)) 459 1.1 christos && (IS_SNC_OPCODE (code + 4)) 460 1.1 christos && (IS_INC_1SP_OPCODE (code + 6)) 461 1.1 christos && (IS_ADD_2SP_W_OPCODE (code + 8)) 462 1.1 christos && (IS_SNC_OPCODE (code + 10)) 463 1.1 christos && (IS_INC_1SP_OPCODE (code + 12)) 464 1.1 christos && (IS_JMP_OPCODE (code + 14))) 465 1.1 christos return table_index; 466 1.1 christos 467 1.1 christos if ((! IS_PAGE_OPCODE (code + 0)) 468 1.1 christos || (! IS_JMP_OPCODE (code + 2))) 469 1.1 christos return -1; 470 1.1 christos 471 1.1 christos table_index++; 472 1.1 christos addr -= 4; 473 1.1 christos } 474 1.1 christos } 475 1.1 christos 476 1.1 christos /* Returns the expected page state for the given instruction not including 477 1.1 christos the effect of page instructions. */ 478 1.1 christos 479 1.1 christos static bfd_vma 480 1.1 christos ip2k_nominal_page_bits (bfd *abfd ATTRIBUTE_UNUSED, 481 1.1 christos asection *sec, 482 1.1 christos bfd_vma addr, 483 1.1 christos bfd_byte *contents) 484 1.1 christos { 485 1.1 christos bfd_vma page = PAGENO (BASEADDR (sec) + addr); 486 1.1 christos 487 1.1 christos /* Check if section flows into this page. If not then the page 488 1.1 christos bits are assumed to match the PC. This will be true unless 489 1.1 christos the user has a page instruction without a call/jump, in which 490 1.1 christos case they are on their own. */ 491 1.1 christos if (PAGENO (BASEADDR (sec)) == page) 492 1.1 christos return page; 493 1.1 christos 494 1.1 christos /* Section flows across page boundary. The page bits should match 495 1.1 christos the PC unless there is a possible flow from the previous page, 496 1.1 christos in which case it is not possible to determine the value of the 497 1.1 christos page bits. */ 498 1.1 christos while (PAGENO (BASEADDR (sec) + addr - 2) == page) 499 1.1 christos { 500 1.1 christos bfd_byte code[2]; 501 1.1 christos 502 1.1 christos addr -= 2; 503 1.1 christos ip2k_get_mem (abfd, contents + addr, 2, code); 504 1.1 christos if (!IS_PAGE_OPCODE (code)) 505 1.1 christos continue; 506 1.1 christos 507 1.1 christos /* Found a page instruction, check if jump table. */ 508 1.1 christos if (ip2k_is_switch_table_128 (abfd, sec, addr, contents) != -1) 509 1.1 christos /* Jump table => page is conditional. */ 510 1.1 christos continue; 511 1.1 christos 512 1.1 christos if (ip2k_is_switch_table_256 (abfd, sec, addr, contents) != -1) 513 1.1 christos /* Jump table => page is conditional. */ 514 1.1 christos continue; 515 1.1 christos 516 1.1 christos /* Found a page instruction, check if conditional. */ 517 1.1 christos if (addr >= 2) 518 1.8 christos { 519 1.1 christos ip2k_get_mem (abfd, contents + addr - 2, 2, code); 520 1.8 christos if (IS_SKIP_OPCODE (code)) 521 1.1 christos /* Page is conditional. */ 522 1.1 christos continue; 523 1.8 christos } 524 1.1 christos 525 1.1 christos /* Unconditional page instruction => page bits should be correct. */ 526 1.1 christos return page; 527 1.1 christos } 528 1.1 christos 529 1.1 christos /* Flow from previous page => page bits are impossible to determine. */ 530 1.1 christos return 0; 531 1.1 christos } 532 1.1 christos 533 1.10 christos static bool 534 1.1 christos ip2k_test_page_insn (bfd *abfd ATTRIBUTE_UNUSED, 535 1.1 christos asection *sec, 536 1.1 christos Elf_Internal_Rela *irel, 537 1.1 christos struct misc *misc) 538 1.1 christos { 539 1.1 christos bfd_vma symval; 540 1.1 christos 541 1.1 christos /* Get the value of the symbol referred to by the reloc. */ 542 1.1 christos symval = symbol_value (abfd, misc->symtab_hdr, misc->isymbuf, irel); 543 1.1 christos if (symval == UNDEFINED_SYMBOL) 544 1.1 christos /* This appears to be a reference to an undefined 545 1.1 christos symbol. Just ignore it--it will be caught by the 546 1.1 christos regular reloc processing. */ 547 1.10 christos return false; 548 1.1 christos 549 1.1 christos /* Test if we can delete this page instruction. */ 550 1.1 christos if (PAGENO (symval + irel->r_addend) != 551 1.1 christos ip2k_nominal_page_bits (abfd, sec, irel->r_offset, misc->contents)) 552 1.10 christos return false; 553 1.1 christos 554 1.10 christos return true; 555 1.1 christos } 556 1.1 christos 557 1.1 christos /* Parts of a Stabs entry. */ 558 1.1 christos 559 1.1 christos #define STRDXOFF 0 560 1.1 christos #define TYPEOFF 4 561 1.1 christos #define OTHEROFF 5 562 1.1 christos #define DESCOFF 6 563 1.1 christos #define VALOFF 8 564 1.1 christos #define STABSIZE 12 565 1.1 christos 566 1.1 christos /* Adjust all the relocations entries after adding or inserting instructions. */ 567 1.1 christos 568 1.1 christos static void 569 1.1 christos adjust_all_relocations (bfd *abfd, 570 1.1 christos asection *sec, 571 1.1 christos bfd_vma addr, 572 1.1 christos bfd_vma endaddr, 573 1.1 christos int count, 574 1.1 christos int noadj) 575 1.1 christos { 576 1.1 christos Elf_Internal_Shdr *symtab_hdr; 577 1.1 christos Elf_Internal_Sym *isymbuf, *isym, *isymend; 578 1.1 christos unsigned int shndx; 579 1.1 christos Elf_Internal_Rela *irel, *irelend, *irelbase; 580 1.1 christos struct elf_link_hash_entry **sym_hashes; 581 1.1 christos struct elf_link_hash_entry **end_hashes; 582 1.1 christos unsigned int symcount; 583 1.1 christos asection *stab; 584 1.1 christos 585 1.1 christos symtab_hdr = &elf_tdata (abfd)->symtab_hdr; 586 1.1 christos isymbuf = (Elf_Internal_Sym *) symtab_hdr->contents; 587 1.1 christos 588 1.1 christos shndx = _bfd_elf_section_from_bfd_section (abfd, sec); 589 1.1 christos 590 1.1 christos irelbase = elf_section_data (sec)->relocs; 591 1.1 christos irelend = irelbase + sec->reloc_count; 592 1.1 christos 593 1.1 christos for (irel = irelbase; irel < irelend; irel++) 594 1.1 christos { 595 1.1 christos if (ELF32_R_TYPE (irel->r_info) != R_IP2K_NONE) 596 1.8 christos { 597 1.8 christos /* Get the value of the symbol referred to by the reloc. */ 598 1.8 christos if (ELF32_R_SYM (irel->r_info) < symtab_hdr->sh_info) 599 1.8 christos { 600 1.8 christos asection *sym_sec; 601 1.1 christos 602 1.8 christos /* A local symbol. */ 603 1.1 christos isym = isymbuf + ELF32_R_SYM (irel->r_info); 604 1.8 christos sym_sec = bfd_section_from_elf_index (abfd, isym->st_shndx); 605 1.1 christos 606 1.8 christos if (isym->st_shndx == shndx) 607 1.8 christos { 608 1.8 christos bfd_vma baseaddr = BASEADDR (sec); 609 1.8 christos bfd_vma symval = BASEADDR (sym_sec) + isym->st_value 610 1.8 christos + irel->r_addend; 611 1.8 christos 612 1.8 christos if ((baseaddr + addr + noadj) <= symval 613 1.8 christos && symval < (baseaddr + endaddr)) 614 1.8 christos irel->r_addend += count; 615 1.8 christos } 616 1.8 christos } 617 1.8 christos } 618 1.1 christos 619 1.1 christos /* Do this only for PC space relocations. */ 620 1.1 christos if (addr <= irel->r_offset && irel->r_offset < endaddr) 621 1.8 christos irel->r_offset += count; 622 1.1 christos } 623 1.1 christos 624 1.1 christos /* Now fix the stab relocations. */ 625 1.1 christos stab = bfd_get_section_by_name (abfd, ".stab"); 626 1.11 christos if (stab && stab->reloc_count != 0) 627 1.1 christos { 628 1.1 christos bfd_byte *stabcontents, *stabend, *stabp; 629 1.1 christos bfd_size_type stab_size = stab->rawsize ? stab->rawsize : stab->size; 630 1.1 christos 631 1.1 christos irelbase = elf_section_data (stab)->relocs; 632 1.1 christos irelend = irelbase + stab->reloc_count; 633 1.1 christos 634 1.1 christos /* Pull out the contents of the stab section. */ 635 1.1 christos if (elf_section_data (stab)->this_hdr.contents != NULL) 636 1.1 christos stabcontents = elf_section_data (stab)->this_hdr.contents; 637 1.1 christos else 638 1.1 christos { 639 1.1 christos if (!bfd_malloc_and_get_section (abfd, stab, &stabcontents)) 640 1.1 christos { 641 1.9 christos free (stabcontents); 642 1.1 christos return; 643 1.1 christos } 644 1.1 christos 645 1.1 christos /* We need to remember this. */ 646 1.1 christos elf_section_data (stab)->this_hdr.contents = stabcontents; 647 1.1 christos } 648 1.1 christos 649 1.1 christos stabend = stabcontents + stab_size; 650 1.1 christos 651 1.1 christos for (irel = irelbase; irel < irelend; irel++) 652 1.1 christos { 653 1.1 christos if (ELF32_R_TYPE (irel->r_info) != R_IP2K_NONE) 654 1.1 christos { 655 1.1 christos /* Get the value of the symbol referred to by the reloc. */ 656 1.1 christos if (ELF32_R_SYM (irel->r_info) < symtab_hdr->sh_info) 657 1.1 christos { 658 1.1 christos asection *sym_sec; 659 1.1 christos 660 1.1 christos /* A local symbol. */ 661 1.1 christos isym = isymbuf + ELF32_R_SYM (irel->r_info); 662 1.1 christos sym_sec = bfd_section_from_elf_index (abfd, isym->st_shndx); 663 1.1 christos 664 1.1 christos if (sym_sec == sec) 665 1.1 christos { 666 1.1 christos const char *name; 667 1.1 christos unsigned char type; 668 1.1 christos bfd_vma value; 669 1.1 christos bfd_vma baseaddr = BASEADDR (sec); 670 1.1 christos bfd_vma symval = BASEADDR (sym_sec) + isym->st_value 671 1.1 christos + irel->r_addend; 672 1.1 christos 673 1.1 christos if ((baseaddr + addr) <= symval 674 1.1 christos && symval <= (baseaddr + endaddr)) 675 1.1 christos irel->r_addend += count; 676 1.1 christos 677 1.1 christos /* Go hunt up a function and fix its line info if needed. */ 678 1.1 christos stabp = stabcontents + irel->r_offset - 8; 679 1.1 christos 680 1.1 christos /* Go pullout the stab entry. */ 681 1.1 christos type = bfd_h_get_8 (abfd, stabp + TYPEOFF); 682 1.1 christos value = bfd_h_get_32 (abfd, stabp + VALOFF); 683 1.1 christos 684 1.1 christos name = bfd_get_stab_name (type); 685 1.1 christos 686 1.1 christos if (strcmp (name, "FUN") == 0) 687 1.1 christos { 688 1.1 christos int function_adjusted = 0; 689 1.1 christos 690 1.1 christos if (symval > (baseaddr + addr)) 691 1.1 christos /* Not in this function. */ 692 1.1 christos continue; 693 1.1 christos 694 1.1 christos /* Hey we got a function hit. */ 695 1.1 christos stabp += STABSIZE; 696 1.1 christos for (;stabp < stabend; stabp += STABSIZE) 697 1.1 christos { 698 1.1 christos /* Go pullout the stab entry. */ 699 1.1 christos type = bfd_h_get_8 (abfd, stabp + TYPEOFF); 700 1.1 christos value = bfd_h_get_32 (abfd, stabp + VALOFF); 701 1.1 christos 702 1.1 christos name = bfd_get_stab_name (type); 703 1.1 christos 704 1.1 christos if (strcmp (name, "FUN") == 0) 705 1.1 christos { 706 1.1 christos /* Hit another function entry. */ 707 1.1 christos if (function_adjusted) 708 1.1 christos { 709 1.1 christos /* Adjust the value. */ 710 1.1 christos value += count; 711 1.1 christos 712 1.1 christos /* We need to put it back. */ 713 1.1 christos bfd_h_put_32 (abfd, value,stabp + VALOFF); 714 1.1 christos } 715 1.1 christos 716 1.1 christos /* And then bale out. */ 717 1.1 christos break; 718 1.1 christos } 719 1.1 christos 720 1.1 christos if (strcmp (name, "SLINE") == 0) 721 1.1 christos { 722 1.1 christos /* Got a line entry. */ 723 1.1 christos if ((baseaddr + addr) <= (symval + value)) 724 1.1 christos { 725 1.1 christos /* Adjust the line entry. */ 726 1.1 christos value += count; 727 1.1 christos 728 1.1 christos /* We need to put it back. */ 729 1.1 christos bfd_h_put_32 (abfd, value,stabp + VALOFF); 730 1.1 christos function_adjusted = 1; 731 1.1 christos } 732 1.1 christos } 733 1.1 christos } 734 1.1 christos } 735 1.1 christos } 736 1.1 christos } 737 1.1 christos } 738 1.1 christos } 739 1.1 christos } 740 1.1 christos 741 1.1 christos /* When adding an instruction back it is sometimes necessary to move any 742 1.1 christos global or local symbol that was referencing the first instruction of 743 1.1 christos the moved block to refer to the first instruction of the inserted block. 744 1.1 christos 745 1.1 christos For example adding a PAGE instruction before a CALL or JMP requires 746 1.1 christos that any label on the CALL or JMP is moved to the PAGE insn. */ 747 1.1 christos addr += noadj; 748 1.1 christos 749 1.1 christos /* Adjust the local symbols defined in this section. */ 750 1.1 christos isymend = isymbuf + symtab_hdr->sh_info; 751 1.1 christos for (isym = isymbuf; isym < isymend; isym++) 752 1.1 christos { 753 1.1 christos if (isym->st_shndx == shndx 754 1.1 christos && addr <= isym->st_value 755 1.1 christos && isym->st_value < endaddr) 756 1.1 christos isym->st_value += count; 757 1.1 christos } 758 1.1 christos 759 1.1 christos /* Now adjust the global symbols defined in this section. */ 760 1.1 christos symcount = (symtab_hdr->sh_size / sizeof (Elf32_External_Sym) 761 1.1 christos - symtab_hdr->sh_info); 762 1.1 christos sym_hashes = elf_sym_hashes (abfd); 763 1.1 christos end_hashes = sym_hashes + symcount; 764 1.1 christos for (; sym_hashes < end_hashes; sym_hashes++) 765 1.1 christos { 766 1.1 christos struct elf_link_hash_entry *sym_hash = *sym_hashes; 767 1.1 christos 768 1.1 christos if ((sym_hash->root.type == bfd_link_hash_defined 769 1.1 christos || sym_hash->root.type == bfd_link_hash_defweak) 770 1.1 christos && sym_hash->root.u.def.section == sec) 771 1.1 christos { 772 1.8 christos if (addr <= sym_hash->root.u.def.value 773 1.8 christos && sym_hash->root.u.def.value < endaddr) 774 1.1 christos sym_hash->root.u.def.value += count; 775 1.1 christos } 776 1.1 christos } 777 1.1 christos 778 1.1 christos return; 779 1.1 christos } 780 1.1 christos 781 1.1 christos /* Delete some bytes from a section while relaxing. */ 782 1.1 christos 783 1.10 christos static bool 784 1.1 christos ip2k_elf_relax_delete_bytes (bfd *abfd, 785 1.1 christos asection *sec, 786 1.1 christos bfd_vma addr, 787 1.1 christos int count) 788 1.1 christos { 789 1.1 christos bfd_byte *contents = elf_section_data (sec)->this_hdr.contents; 790 1.1 christos bfd_vma endaddr = sec->size; 791 1.1 christos 792 1.1 christos /* Actually delete the bytes. */ 793 1.1 christos memmove (contents + addr, contents + addr + count, 794 1.1 christos endaddr - addr - count); 795 1.1 christos 796 1.1 christos sec->size -= count; 797 1.1 christos 798 1.1 christos adjust_all_relocations (abfd, sec, addr + count, endaddr, -count, 0); 799 1.10 christos return true; 800 1.1 christos } 801 1.1 christos 802 1.10 christos static bool 803 1.1 christos ip2k_delete_page_insn (bfd *abfd ATTRIBUTE_UNUSED, 804 1.1 christos asection *sec, 805 1.1 christos Elf_Internal_Rela *irel, 806 1.10 christos bool *again, 807 1.1 christos struct misc *misc) 808 1.1 christos { 809 1.1 christos /* Note that we've changed the relocs, section contents, etc. */ 810 1.1 christos elf_section_data (sec)->relocs = misc->irelbase; 811 1.1 christos elf_section_data (sec)->this_hdr.contents = misc->contents; 812 1.1 christos misc->symtab_hdr->contents = (bfd_byte *) misc->isymbuf; 813 1.1 christos 814 1.1 christos /* Fix the relocation's type. */ 815 1.1 christos irel->r_info = ELF32_R_INFO (ELF32_R_SYM (irel->r_info), R_IP2K_NONE); 816 1.1 christos 817 1.1 christos /* Delete the PAGE insn. */ 818 1.1 christos if (!ip2k_elf_relax_delete_bytes (abfd, sec, irel->r_offset, 2)) 819 1.10 christos return false; 820 1.1 christos 821 1.1 christos /* Modified => will need to iterate relaxation again. */ 822 1.10 christos *again = true; 823 1.1 christos 824 1.10 christos return true; 825 1.1 christos } 826 1.1 christos 827 1.10 christos static bool 828 1.1 christos ip2k_relax_switch_table_128 (bfd *abfd ATTRIBUTE_UNUSED, 829 1.1 christos asection *sec, 830 1.1 christos Elf_Internal_Rela *irel, 831 1.10 christos bool *again, 832 1.1 christos struct misc *misc) 833 1.1 christos { 834 1.1 christos Elf_Internal_Rela *irelend = misc->irelbase + sec->reloc_count; 835 1.1 christos Elf_Internal_Rela *ireltest = irel; 836 1.1 christos bfd_byte code[4]; 837 1.1 christos bfd_vma addr; 838 1.1 christos 839 1.1 christos /* Test all page instructions. */ 840 1.1 christos addr = irel->r_offset; 841 1.1 christos while (1) 842 1.1 christos { 843 1.1 christos if (addr + 4 > sec->size) 844 1.1 christos break; 845 1.1 christos 846 1.1 christos ip2k_get_mem (abfd, misc->contents + addr, 4, code); 847 1.1 christos if ((! IS_PAGE_OPCODE (code + 0)) 848 1.1 christos || (! IS_JMP_OPCODE (code + 2))) 849 1.1 christos break; 850 1.1 christos 851 1.1 christos /* Validate relocation entry (every entry should have a matching 852 1.8 christos relocation entry). */ 853 1.1 christos if (ireltest >= irelend) 854 1.8 christos { 855 1.1 christos _bfd_error_handler (_("ip2k relaxer: switch table without complete matching relocation information.")); 856 1.10 christos return false; 857 1.8 christos } 858 1.1 christos 859 1.1 christos if (ireltest->r_offset != addr) 860 1.8 christos { 861 1.1 christos _bfd_error_handler (_("ip2k relaxer: switch table without complete matching relocation information.")); 862 1.10 christos return false; 863 1.8 christos } 864 1.1 christos 865 1.1 christos if (! ip2k_test_page_insn (abfd, sec, ireltest, misc)) 866 1.1 christos /* Un-removable page insn => nothing can be done. */ 867 1.10 christos return true; 868 1.1 christos 869 1.1 christos addr += 4; 870 1.1 christos ireltest += 2; 871 1.1 christos } 872 1.1 christos 873 1.1 christos /* Relaxable. Adjust table header. */ 874 1.1 christos ip2k_get_mem (abfd, misc->contents + irel->r_offset - 4, 4, code); 875 1.1 christos if ((! IS_ADD_W_WREG_OPCODE (code + 0)) 876 1.1 christos || (! IS_ADD_PCL_W_OPCODE (code + 2))) 877 1.1 christos { 878 1.1 christos _bfd_error_handler (_("ip2k relaxer: switch table header corrupt.")); 879 1.10 christos return false; 880 1.1 christos } 881 1.1 christos 882 1.1 christos if (!ip2k_elf_relax_delete_bytes (abfd, sec, irel->r_offset - 4, 2)) 883 1.10 christos return false; 884 1.1 christos 885 1.10 christos *again = true; 886 1.1 christos 887 1.1 christos /* Delete all page instructions in table. */ 888 1.1 christos while (irel < ireltest) 889 1.1 christos { 890 1.1 christos if (!ip2k_delete_page_insn (abfd, sec, irel, again, misc)) 891 1.10 christos return false; 892 1.1 christos irel += 2; 893 1.1 christos } 894 1.1 christos 895 1.10 christos return true; 896 1.1 christos } 897 1.1 christos 898 1.10 christos static bool 899 1.1 christos ip2k_relax_switch_table_256 (bfd *abfd ATTRIBUTE_UNUSED, 900 1.1 christos asection *sec, 901 1.1 christos Elf_Internal_Rela *irel, 902 1.10 christos bool *again, 903 1.1 christos struct misc *misc) 904 1.1 christos { 905 1.1 christos Elf_Internal_Rela *irelend = misc->irelbase + sec->reloc_count; 906 1.1 christos Elf_Internal_Rela *ireltest = irel; 907 1.1 christos bfd_byte code[12]; 908 1.1 christos bfd_vma addr; 909 1.1 christos 910 1.1 christos /* Test all page instructions. */ 911 1.1 christos addr = irel->r_offset; 912 1.1 christos 913 1.1 christos while (1) 914 1.1 christos { 915 1.1 christos if (addr + 4 > sec->size) 916 1.1 christos break; 917 1.1 christos 918 1.1 christos ip2k_get_mem (abfd, misc->contents + addr, 4, code); 919 1.1 christos 920 1.1 christos if ((! IS_PAGE_OPCODE (code + 0)) 921 1.1 christos || (! IS_JMP_OPCODE (code + 2))) 922 1.1 christos break; 923 1.1 christos 924 1.1 christos /* Validate relocation entry (every entry should have a matching 925 1.8 christos relocation entry). */ 926 1.1 christos if (ireltest >= irelend) 927 1.8 christos { 928 1.8 christos _bfd_error_handler (_("ip2k relaxer: switch table without complete matching relocation information.")); 929 1.10 christos return false; 930 1.8 christos } 931 1.1 christos 932 1.1 christos if (ireltest->r_offset != addr) 933 1.8 christos { 934 1.8 christos _bfd_error_handler (_("ip2k relaxer: switch table without complete matching relocation information.")); 935 1.10 christos return false; 936 1.8 christos } 937 1.1 christos 938 1.1 christos if (!ip2k_test_page_insn (abfd, sec, ireltest, misc)) 939 1.1 christos /* Un-removable page insn => nothing can be done. */ 940 1.10 christos return true; 941 1.1 christos 942 1.1 christos addr += 4; 943 1.1 christos ireltest += 2; 944 1.1 christos } 945 1.1 christos 946 1.1 christos /* Relaxable. Adjust table header. */ 947 1.1 christos ip2k_get_mem (abfd, misc->contents + irel->r_offset - 4, 2, code); 948 1.1 christos if (IS_PAGE_OPCODE (code)) 949 1.1 christos addr = irel->r_offset - 16; 950 1.1 christos else 951 1.1 christos addr = irel->r_offset - 14; 952 1.1 christos 953 1.1 christos ip2k_get_mem (abfd, misc->contents + addr, 12, code); 954 1.1 christos if ((!IS_ADD_W_WREG_OPCODE (code + 0)) 955 1.1 christos || (!IS_SNC_OPCODE (code + 2)) 956 1.1 christos || (!IS_INC_1SP_OPCODE (code + 4)) 957 1.1 christos || (!IS_ADD_2SP_W_OPCODE (code + 6)) 958 1.1 christos || (!IS_SNC_OPCODE (code + 8)) 959 1.1 christos || (!IS_INC_1SP_OPCODE (code + 10))) 960 1.1 christos { 961 1.1 christos _bfd_error_handler (_("ip2k relaxer: switch table header corrupt.")); 962 1.10 christos return false; 963 1.1 christos } 964 1.1 christos 965 1.1 christos /* Delete first 3 opcodes. */ 966 1.1 christos if (!ip2k_elf_relax_delete_bytes (abfd, sec, addr + 0, 6)) 967 1.10 christos return false; 968 1.1 christos 969 1.10 christos *again = true; 970 1.1 christos 971 1.1 christos /* Delete all page instructions in table. */ 972 1.1 christos while (irel < ireltest) 973 1.1 christos { 974 1.1 christos if (!ip2k_delete_page_insn (abfd, sec, irel, again, misc)) 975 1.10 christos return false; 976 1.1 christos irel += 2; 977 1.1 christos } 978 1.1 christos 979 1.10 christos return true; 980 1.1 christos } 981 1.1 christos 982 1.1 christos /* This function handles relaxation of a section in a specific page. */ 983 1.1 christos 984 1.10 christos static bool 985 1.1 christos ip2k_elf_relax_section_page (bfd *abfd, 986 1.1 christos asection *sec, 987 1.10 christos bool *again, 988 1.1 christos struct misc *misc, 989 1.1 christos unsigned long page_start, 990 1.1 christos unsigned long page_end) 991 1.1 christos { 992 1.1 christos Elf_Internal_Rela *irelend = misc->irelbase + sec->reloc_count; 993 1.1 christos Elf_Internal_Rela *irel; 994 1.1 christos int switch_table_128; 995 1.1 christos int switch_table_256; 996 1.1 christos 997 1.1 christos /* Walk thru the section looking for relaxation opportunities. */ 998 1.1 christos for (irel = misc->irelbase; irel < irelend; irel++) 999 1.1 christos { 1000 1.1 christos if (ELF32_R_TYPE (irel->r_info) != (int) R_IP2K_PAGE3) 1001 1.1 christos /* Ignore non page instructions. */ 1002 1.1 christos continue; 1003 1.1 christos 1004 1.1 christos if (BASEADDR (sec) + irel->r_offset < page_start) 1005 1.1 christos /* Ignore page instructions on earlier page - they have 1006 1.1 christos already been processed. Remember that there is code flow 1007 1.1 christos that crosses a page boundary. */ 1008 1.1 christos continue; 1009 1.1 christos 1010 1.1 christos if (BASEADDR (sec) + irel->r_offset > page_end) 1011 1.1 christos /* Flow beyond end of page => nothing more to do for this page. */ 1012 1.10 christos return true; 1013 1.1 christos 1014 1.1 christos /* Detect switch tables. */ 1015 1.1 christos switch_table_128 = ip2k_is_switch_table_128 (abfd, sec, irel->r_offset, misc->contents); 1016 1.1 christos switch_table_256 = ip2k_is_switch_table_256 (abfd, sec, irel->r_offset, misc->contents); 1017 1.1 christos 1018 1.1 christos if ((switch_table_128 > 0) || (switch_table_256 > 0)) 1019 1.1 christos /* If the index is greater than 0 then it has already been processed. */ 1020 1.1 christos continue; 1021 1.1 christos 1022 1.1 christos if (switch_table_128 == 0) 1023 1.1 christos { 1024 1.1 christos if (!ip2k_relax_switch_table_128 (abfd, sec, irel, again, misc)) 1025 1.10 christos return false; 1026 1.1 christos 1027 1.1 christos continue; 1028 1.1 christos } 1029 1.1 christos 1030 1.1 christos if (switch_table_256 == 0) 1031 1.1 christos { 1032 1.1 christos if (!ip2k_relax_switch_table_256 (abfd, sec, irel, again, misc)) 1033 1.10 christos return false; 1034 1.1 christos 1035 1.1 christos continue; 1036 1.1 christos } 1037 1.1 christos 1038 1.1 christos /* Simple relax. */ 1039 1.1 christos if (ip2k_test_page_insn (abfd, sec, irel, misc)) 1040 1.1 christos { 1041 1.1 christos if (!ip2k_delete_page_insn (abfd, sec, irel, again, misc)) 1042 1.10 christos return false; 1043 1.1 christos 1044 1.1 christos continue; 1045 1.1 christos } 1046 1.1 christos } 1047 1.1 christos 1048 1.10 christos return true; 1049 1.1 christos } 1050 1.1 christos 1051 1.1 christos /* This function handles relaxing for the ip2k. 1052 1.1 christos 1053 1.1 christos Principle: Start with the first page and remove page instructions that 1054 1.1 christos are not require on this first page. By removing page instructions more 1055 1.1 christos code will fit into this page - repeat until nothing more can be achieved 1056 1.1 christos for this page. Move on to the next page. 1057 1.1 christos 1058 1.1 christos Processing the pages one at a time from the lowest page allows a removal 1059 1.1 christos only policy to be used - pages can be removed but are never reinserted. */ 1060 1.1 christos 1061 1.10 christos static bool 1062 1.1 christos ip2k_elf_relax_section (bfd *abfd, 1063 1.1 christos asection *sec, 1064 1.1 christos struct bfd_link_info *link_info, 1065 1.10 christos bool *again) 1066 1.1 christos { 1067 1.1 christos Elf_Internal_Shdr *symtab_hdr; 1068 1.1 christos Elf_Internal_Rela *internal_relocs; 1069 1.1 christos bfd_byte *contents = NULL; 1070 1.1 christos Elf_Internal_Sym *isymbuf = NULL; 1071 1.1 christos static asection * first_section = NULL; 1072 1.1 christos static unsigned long search_addr; 1073 1.1 christos static unsigned long page_start = 0; 1074 1.1 christos static unsigned long page_end = 0; 1075 1.1 christos static unsigned int pass = 0; 1076 1.10 christos static bool new_pass = false; 1077 1.10 christos static bool changed = false; 1078 1.1 christos struct misc misc; 1079 1.1 christos 1080 1.1 christos /* Assume nothing changes. */ 1081 1.10 christos *again = false; 1082 1.1 christos 1083 1.1 christos if (first_section == NULL) 1084 1.1 christos { 1085 1.10 christos ip2k_relaxed = true; 1086 1.1 christos first_section = sec; 1087 1.1 christos } 1088 1.1 christos 1089 1.1 christos if (first_section == sec) 1090 1.1 christos { 1091 1.1 christos pass++; 1092 1.10 christos new_pass = true; 1093 1.1 christos } 1094 1.1 christos 1095 1.1 christos /* We don't have to do anything for a relocatable link, 1096 1.1 christos if this section does not have relocs, or if this is 1097 1.1 christos not a code section. */ 1098 1.6 christos if (bfd_link_relocatable (link_info) 1099 1.11 christos || sec->reloc_count == 0 1100 1.1 christos || (sec->flags & SEC_RELOC) == 0 1101 1.11 christos || (sec->flags & SEC_HAS_CONTENTS) == 0 1102 1.1 christos || (sec->flags & SEC_CODE) == 0) 1103 1.10 christos return true; 1104 1.1 christos 1105 1.1 christos symtab_hdr = &elf_tdata (abfd)->symtab_hdr; 1106 1.1 christos 1107 1.1 christos internal_relocs = _bfd_elf_link_read_relocs (abfd, sec, NULL, NULL, 1108 1.1 christos link_info->keep_memory); 1109 1.1 christos if (internal_relocs == NULL) 1110 1.1 christos goto error_return; 1111 1.1 christos 1112 1.1 christos /* Get section contents cached copy if it exists. */ 1113 1.1 christos if (contents == NULL) 1114 1.1 christos { 1115 1.1 christos /* Get cached copy if it exists. */ 1116 1.1 christos if (elf_section_data (sec)->this_hdr.contents != NULL) 1117 1.1 christos contents = elf_section_data (sec)->this_hdr.contents; 1118 1.1 christos else 1119 1.1 christos { 1120 1.1 christos /* Go get them off disk. */ 1121 1.1 christos if (!bfd_malloc_and_get_section (abfd, sec, &contents)) 1122 1.1 christos goto error_return; 1123 1.1 christos } 1124 1.1 christos } 1125 1.1 christos 1126 1.1 christos /* Read this BFD's symbols cached copy if it exists. */ 1127 1.1 christos if (isymbuf == NULL && symtab_hdr->sh_info != 0) 1128 1.1 christos { 1129 1.1 christos isymbuf = (Elf_Internal_Sym *) symtab_hdr->contents; 1130 1.1 christos if (isymbuf == NULL) 1131 1.1 christos isymbuf = bfd_elf_get_elf_syms (abfd, symtab_hdr, 1132 1.1 christos symtab_hdr->sh_info, 0, 1133 1.1 christos NULL, NULL, NULL); 1134 1.1 christos if (isymbuf == NULL) 1135 1.1 christos goto error_return; 1136 1.1 christos } 1137 1.1 christos 1138 1.1 christos misc.symtab_hdr = symtab_hdr; 1139 1.1 christos misc.isymbuf = isymbuf; 1140 1.1 christos misc.irelbase = internal_relocs; 1141 1.1 christos misc.contents = contents; 1142 1.1 christos 1143 1.1 christos /* This is where all the relaxation actually get done. */ 1144 1.1 christos if ((pass == 1) || (new_pass && !changed)) 1145 1.1 christos { 1146 1.1 christos /* On the first pass we simply search for the lowest page that 1147 1.8 christos we havn't relaxed yet. Note that the pass count is reset 1148 1.8 christos each time a page is complete in order to move on to the next page. 1149 1.8 christos If we can't find any more pages then we are finished. */ 1150 1.1 christos if (new_pass) 1151 1.1 christos { 1152 1.1 christos pass = 1; 1153 1.10 christos new_pass = false; 1154 1.10 christos changed = true; /* Pre-initialize to break out of pass 1. */ 1155 1.1 christos search_addr = 0xFFFFFFFF; 1156 1.1 christos } 1157 1.1 christos 1158 1.1 christos if ((BASEADDR (sec) + sec->size < search_addr) 1159 1.1 christos && (BASEADDR (sec) + sec->size > page_end)) 1160 1.1 christos { 1161 1.1 christos if (BASEADDR (sec) <= page_end) 1162 1.1 christos search_addr = page_end + 1; 1163 1.1 christos else 1164 1.1 christos search_addr = BASEADDR (sec); 1165 1.1 christos 1166 1.1 christos /* Found a page => more work to do. */ 1167 1.10 christos *again = true; 1168 1.1 christos } 1169 1.1 christos } 1170 1.1 christos else 1171 1.1 christos { 1172 1.1 christos if (new_pass) 1173 1.1 christos { 1174 1.10 christos new_pass = false; 1175 1.10 christos changed = false; 1176 1.1 christos page_start = PAGENO (search_addr); 1177 1.1 christos page_end = page_start | 0x00003FFF; 1178 1.1 christos } 1179 1.1 christos 1180 1.1 christos /* Only process sections in range. */ 1181 1.1 christos if ((BASEADDR (sec) + sec->size >= page_start) 1182 1.1 christos && (BASEADDR (sec) <= page_end)) 1183 1.1 christos { 1184 1.8 christos if (!ip2k_elf_relax_section_page (abfd, sec, &changed, &misc, page_start, page_end)) 1185 1.10 christos return false; 1186 1.1 christos } 1187 1.10 christos *again = true; 1188 1.1 christos } 1189 1.1 christos 1190 1.1 christos /* Perform some house keeping after relaxing the section. */ 1191 1.1 christos 1192 1.1 christos if (isymbuf != NULL 1193 1.1 christos && symtab_hdr->contents != (unsigned char *) isymbuf) 1194 1.1 christos { 1195 1.1 christos if (! link_info->keep_memory) 1196 1.1 christos free (isymbuf); 1197 1.1 christos else 1198 1.1 christos symtab_hdr->contents = (unsigned char *) isymbuf; 1199 1.1 christos } 1200 1.1 christos 1201 1.1 christos if (contents != NULL 1202 1.1 christos && elf_section_data (sec)->this_hdr.contents != contents) 1203 1.1 christos { 1204 1.1 christos if (! link_info->keep_memory) 1205 1.1 christos free (contents); 1206 1.1 christos else 1207 1.1 christos { 1208 1.1 christos /* Cache the section contents for elf_link_input_bfd. */ 1209 1.1 christos elf_section_data (sec)->this_hdr.contents = contents; 1210 1.1 christos } 1211 1.1 christos } 1212 1.1 christos 1213 1.9 christos if (elf_section_data (sec)->relocs != internal_relocs) 1214 1.1 christos free (internal_relocs); 1215 1.1 christos 1216 1.10 christos return true; 1217 1.1 christos 1218 1.1 christos error_return: 1219 1.9 christos if (symtab_hdr->contents != (unsigned char *) isymbuf) 1220 1.1 christos free (isymbuf); 1221 1.9 christos if (elf_section_data (sec)->this_hdr.contents != contents) 1222 1.1 christos free (contents); 1223 1.9 christos if (elf_section_data (sec)->relocs != internal_relocs) 1224 1.1 christos free (internal_relocs); 1225 1.10 christos return false; 1226 1.1 christos } 1227 1.1 christos 1228 1.1 christos /* Set the howto pointer for a IP2K ELF reloc. */ 1229 1.1 christos 1230 1.10 christos static bool 1231 1.8 christos ip2k_info_to_howto_rela (bfd * abfd, 1232 1.1 christos arelent * cache_ptr, 1233 1.1 christos Elf_Internal_Rela * dst) 1234 1.1 christos { 1235 1.1 christos unsigned int r_type; 1236 1.1 christos 1237 1.1 christos r_type = ELF32_R_TYPE (dst->r_info); 1238 1.3 christos if (r_type >= (unsigned int) R_IP2K_max) 1239 1.3 christos { 1240 1.7 christos /* xgettext:c-format */ 1241 1.8 christos _bfd_error_handler (_("%pB: unsupported relocation type %#x"), 1242 1.8 christos abfd, r_type); 1243 1.8 christos bfd_set_error (bfd_error_bad_value); 1244 1.10 christos return false; 1245 1.3 christos } 1246 1.1 christos cache_ptr->howto = & ip2k_elf_howto_table [r_type]; 1247 1.10 christos return true; 1248 1.1 christos } 1249 1.1 christos 1250 1.1 christos /* Perform a single relocation. 1251 1.1 christos By default we use the standard BFD routines. */ 1252 1.1 christos 1253 1.1 christos static bfd_reloc_status_type 1254 1.1 christos ip2k_final_link_relocate (reloc_howto_type * howto, 1255 1.8 christos bfd * input_bfd, 1256 1.8 christos asection * input_section, 1257 1.8 christos bfd_byte * contents, 1258 1.1 christos Elf_Internal_Rela * rel, 1259 1.8 christos bfd_vma relocation) 1260 1.1 christos { 1261 1.1 christos static bfd_vma page_addr = 0; 1262 1.1 christos 1263 1.1 christos bfd_reloc_status_type r = bfd_reloc_ok; 1264 1.1 christos switch (howto->type) 1265 1.1 christos { 1266 1.1 christos /* Handle data space relocations. */ 1267 1.1 christos case R_IP2K_FR9: 1268 1.1 christos case R_IP2K_BANK: 1269 1.1 christos if ((relocation & IP2K_DATA_MASK) == IP2K_DATA_VALUE) 1270 1.1 christos relocation &= ~IP2K_DATA_MASK; 1271 1.1 christos else 1272 1.1 christos r = bfd_reloc_notsupported; 1273 1.1 christos break; 1274 1.1 christos 1275 1.1 christos case R_IP2K_LO8DATA: 1276 1.1 christos case R_IP2K_HI8DATA: 1277 1.1 christos case R_IP2K_EX8DATA: 1278 1.1 christos break; 1279 1.1 christos 1280 1.1 christos /* Handle insn space relocations. */ 1281 1.1 christos case R_IP2K_PAGE3: 1282 1.1 christos page_addr = BASEADDR (input_section) + rel->r_offset; 1283 1.1 christos if ((relocation & IP2K_INSN_MASK) == IP2K_INSN_VALUE) 1284 1.1 christos relocation &= ~IP2K_INSN_MASK; 1285 1.1 christos else 1286 1.1 christos r = bfd_reloc_notsupported; 1287 1.1 christos break; 1288 1.1 christos 1289 1.1 christos case R_IP2K_ADDR16CJP: 1290 1.1 christos if (BASEADDR (input_section) + rel->r_offset != page_addr + 2) 1291 1.1 christos { 1292 1.1 christos /* No preceding page instruction, verify that it isn't needed. */ 1293 1.1 christos if (PAGENO (relocation + rel->r_addend) != 1294 1.1 christos ip2k_nominal_page_bits (input_bfd, input_section, 1295 1.8 christos rel->r_offset, contents)) 1296 1.7 christos /* xgettext:c-format */ 1297 1.8 christos _bfd_error_handler 1298 1.8 christos (_("ip2k linker: missing page instruction " 1299 1.8 christos "at %#" PRIx64 " (dest = %#" PRIx64 ")"), 1300 1.8 christos (uint64_t) (BASEADDR (input_section) + rel->r_offset), 1301 1.8 christos (uint64_t) (relocation + rel->r_addend)); 1302 1.8 christos } 1303 1.1 christos else if (ip2k_relaxed) 1304 1.8 christos { 1305 1.8 christos /* Preceding page instruction. Verify that the page instruction is 1306 1.8 christos really needed. One reason for the relaxation to miss a page is if 1307 1.8 christos the section is not marked as executable. */ 1308 1.1 christos if (!ip2k_is_switch_table_128 (input_bfd, input_section, 1309 1.1 christos rel->r_offset - 2, contents) 1310 1.1 christos && !ip2k_is_switch_table_256 (input_bfd, input_section, 1311 1.1 christos rel->r_offset - 2, contents) 1312 1.1 christos && (PAGENO (relocation + rel->r_addend) == 1313 1.1 christos ip2k_nominal_page_bits (input_bfd, input_section, 1314 1.1 christos rel->r_offset - 2, contents))) 1315 1.7 christos /* xgettext:c-format */ 1316 1.8 christos _bfd_error_handler 1317 1.8 christos (_("ip2k linker: redundant page instruction " 1318 1.8 christos "at %#" PRIx64 " (dest = %#" PRIx64 ")"), 1319 1.8 christos (uint64_t) page_addr, 1320 1.8 christos (uint64_t) (relocation + rel->r_addend)); 1321 1.8 christos } 1322 1.1 christos if ((relocation & IP2K_INSN_MASK) == IP2K_INSN_VALUE) 1323 1.1 christos relocation &= ~IP2K_INSN_MASK; 1324 1.1 christos else 1325 1.1 christos r = bfd_reloc_notsupported; 1326 1.1 christos break; 1327 1.1 christos 1328 1.1 christos case R_IP2K_LO8INSN: 1329 1.1 christos case R_IP2K_HI8INSN: 1330 1.1 christos case R_IP2K_PC_SKIP: 1331 1.1 christos if ((relocation & IP2K_INSN_MASK) == IP2K_INSN_VALUE) 1332 1.1 christos relocation &= ~IP2K_INSN_MASK; 1333 1.1 christos else 1334 1.1 christos r = bfd_reloc_notsupported; 1335 1.1 christos break; 1336 1.1 christos 1337 1.1 christos case R_IP2K_16: 1338 1.1 christos /* If this is a relocation involving a TEXT 1339 1.1 christos symbol, reduce it to a word address. */ 1340 1.1 christos if ((relocation & IP2K_INSN_MASK) == IP2K_INSN_VALUE) 1341 1.1 christos howto = &ip2k_elf_howto_table[ (int) R_IP2K_TEXT]; 1342 1.1 christos break; 1343 1.1 christos 1344 1.1 christos /* Pass others through. */ 1345 1.1 christos default: 1346 1.1 christos break; 1347 1.1 christos } 1348 1.1 christos 1349 1.1 christos /* Only install relocation if above tests did not disqualify it. */ 1350 1.1 christos if (r == bfd_reloc_ok) 1351 1.1 christos r = _bfd_final_link_relocate (howto, input_bfd, input_section, 1352 1.1 christos contents, rel->r_offset, 1353 1.1 christos relocation, rel->r_addend); 1354 1.1 christos 1355 1.1 christos return r; 1356 1.1 christos } 1357 1.1 christos 1358 1.1 christos /* Relocate a IP2K ELF section. 1359 1.1 christos 1360 1.1 christos The RELOCATE_SECTION function is called by the new ELF backend linker 1361 1.1 christos to handle the relocations for a section. 1362 1.1 christos 1363 1.1 christos The relocs are always passed as Rela structures; if the section 1364 1.1 christos actually uses Rel structures, the r_addend field will always be 1365 1.1 christos zero. 1366 1.1 christos 1367 1.1 christos This function is responsible for adjusting the section contents as 1368 1.1 christos necessary, and (if using Rela relocs and generating a relocatable 1369 1.1 christos output file) adjusting the reloc addend as necessary. 1370 1.1 christos 1371 1.1 christos This function does not have to worry about setting the reloc 1372 1.1 christos address or the reloc symbol index. 1373 1.1 christos 1374 1.1 christos LOCAL_SYMS is a pointer to the swapped in local symbols. 1375 1.1 christos 1376 1.1 christos LOCAL_SECTIONS is an array giving the section in the input file 1377 1.1 christos corresponding to the st_shndx field of each local symbol. 1378 1.1 christos 1379 1.1 christos The global hash table entry for the global symbols can be found 1380 1.1 christos via elf_sym_hashes (input_bfd). 1381 1.1 christos 1382 1.1 christos When generating relocatable output, this function must handle 1383 1.1 christos STB_LOCAL/STT_SECTION symbols specially. The output symbol is 1384 1.1 christos going to be the section symbol corresponding to the output 1385 1.1 christos section, which means that the addend must be adjusted 1386 1.1 christos accordingly. */ 1387 1.1 christos 1388 1.10 christos static int 1389 1.1 christos ip2k_elf_relocate_section (bfd *output_bfd ATTRIBUTE_UNUSED, 1390 1.1 christos struct bfd_link_info *info, 1391 1.1 christos bfd *input_bfd, 1392 1.1 christos asection *input_section, 1393 1.1 christos bfd_byte *contents, 1394 1.1 christos Elf_Internal_Rela *relocs, 1395 1.1 christos Elf_Internal_Sym *local_syms, 1396 1.1 christos asection **local_sections) 1397 1.1 christos { 1398 1.1 christos Elf_Internal_Shdr *symtab_hdr; 1399 1.1 christos struct elf_link_hash_entry **sym_hashes; 1400 1.1 christos Elf_Internal_Rela *rel; 1401 1.1 christos Elf_Internal_Rela *relend; 1402 1.1 christos 1403 1.1 christos symtab_hdr = & elf_tdata (input_bfd)->symtab_hdr; 1404 1.1 christos sym_hashes = elf_sym_hashes (input_bfd); 1405 1.1 christos relend = relocs + input_section->reloc_count; 1406 1.1 christos 1407 1.1 christos for (rel = relocs; rel < relend; rel ++) 1408 1.1 christos { 1409 1.8 christos reloc_howto_type * howto; 1410 1.8 christos unsigned long r_symndx; 1411 1.8 christos Elf_Internal_Sym * sym; 1412 1.8 christos asection * sec; 1413 1.1 christos struct elf_link_hash_entry * h; 1414 1.8 christos bfd_vma relocation; 1415 1.8 christos bfd_reloc_status_type r; 1416 1.8 christos const char * name = NULL; 1417 1.8 christos int r_type; 1418 1.1 christos 1419 1.1 christos r_type = ELF32_R_TYPE (rel->r_info); 1420 1.1 christos r_symndx = ELF32_R_SYM (rel->r_info); 1421 1.1 christos howto = ip2k_elf_howto_table + r_type; 1422 1.1 christos h = NULL; 1423 1.1 christos sym = NULL; 1424 1.1 christos sec = NULL; 1425 1.1 christos 1426 1.1 christos if (r_symndx < symtab_hdr->sh_info) 1427 1.1 christos { 1428 1.1 christos sym = local_syms + r_symndx; 1429 1.1 christos sec = local_sections [r_symndx]; 1430 1.1 christos relocation = BASEADDR (sec) + sym->st_value; 1431 1.1 christos 1432 1.1 christos name = bfd_elf_string_from_elf_section 1433 1.1 christos (input_bfd, symtab_hdr->sh_link, sym->st_name); 1434 1.9 christos name = name == NULL ? bfd_section_name (sec) : name; 1435 1.1 christos } 1436 1.1 christos else 1437 1.1 christos { 1438 1.10 christos bool warned, ignored; 1439 1.10 christos bool unresolved_reloc; 1440 1.1 christos 1441 1.1 christos RELOC_FOR_GLOBAL_SYMBOL (info, input_bfd, input_section, rel, 1442 1.1 christos r_symndx, symtab_hdr, sym_hashes, 1443 1.1 christos h, sec, relocation, 1444 1.1 christos unresolved_reloc, warned, ignored); 1445 1.1 christos 1446 1.1 christos name = h->root.root.string; 1447 1.1 christos } 1448 1.1 christos 1449 1.1 christos if (sec != NULL && discarded_section (sec)) 1450 1.1 christos RELOC_AGAINST_DISCARDED_SECTION (info, input_bfd, input_section, 1451 1.1 christos rel, 1, relend, howto, 0, contents); 1452 1.1 christos 1453 1.6 christos if (bfd_link_relocatable (info)) 1454 1.1 christos continue; 1455 1.1 christos 1456 1.1 christos /* Finally, the sole IP2K-specific part. */ 1457 1.1 christos r = ip2k_final_link_relocate (howto, input_bfd, input_section, 1458 1.1 christos contents, rel, relocation); 1459 1.1 christos 1460 1.1 christos if (r != bfd_reloc_ok) 1461 1.1 christos { 1462 1.1 christos const char * msg = NULL; 1463 1.1 christos 1464 1.1 christos switch (r) 1465 1.1 christos { 1466 1.1 christos case bfd_reloc_overflow: 1467 1.6 christos (*info->callbacks->reloc_overflow) 1468 1.1 christos (info, (h ? &h->root : NULL), name, howto->name, 1469 1.1 christos (bfd_vma) 0, input_bfd, input_section, rel->r_offset); 1470 1.1 christos break; 1471 1.1 christos 1472 1.1 christos case bfd_reloc_undefined: 1473 1.6 christos (*info->callbacks->undefined_symbol) 1474 1.10 christos (info, name, input_bfd, input_section, rel->r_offset, true); 1475 1.1 christos break; 1476 1.1 christos 1477 1.1 christos case bfd_reloc_outofrange: 1478 1.1 christos msg = _("internal error: out of range error"); 1479 1.1 christos break; 1480 1.1 christos 1481 1.1 christos /* This is how ip2k_final_link_relocate tells us of a non-kosher 1482 1.8 christos reference between insn & data address spaces. */ 1483 1.1 christos case bfd_reloc_notsupported: 1484 1.8 christos if (sym != NULL) /* Only if it's not an unresolved symbol. */ 1485 1.8 christos msg = _("unsupported relocation between data/insn address spaces"); 1486 1.1 christos break; 1487 1.1 christos 1488 1.1 christos case bfd_reloc_dangerous: 1489 1.1 christos msg = _("internal error: dangerous relocation"); 1490 1.1 christos break; 1491 1.1 christos 1492 1.1 christos default: 1493 1.1 christos msg = _("internal error: unknown error"); 1494 1.1 christos break; 1495 1.1 christos } 1496 1.1 christos 1497 1.1 christos if (msg) 1498 1.6 christos (*info->callbacks->warning) (info, msg, name, input_bfd, 1499 1.6 christos input_section, rel->r_offset); 1500 1.1 christos } 1501 1.1 christos } 1502 1.1 christos 1503 1.10 christos return true; 1504 1.1 christos } 1505 1.1 christos 1506 1.3 christos #define TARGET_BIG_SYM ip2k_elf32_vec 1507 1.1 christos #define TARGET_BIG_NAME "elf32-ip2k" 1508 1.1 christos 1509 1.1 christos #define ELF_ARCH bfd_arch_ip2k 1510 1.1 christos #define ELF_MACHINE_CODE EM_IP2K 1511 1.1 christos #define ELF_MACHINE_ALT1 EM_IP2K_OLD 1512 1.1 christos #define ELF_MAXPAGESIZE 1 /* No pages on the IP2K. */ 1513 1.1 christos 1514 1.1 christos #define elf_info_to_howto_rel NULL 1515 1.1 christos #define elf_info_to_howto ip2k_info_to_howto_rela 1516 1.1 christos 1517 1.8 christos #define elf_backend_can_gc_sections 1 1518 1.1 christos #define elf_backend_rela_normal 1 1519 1.1 christos #define elf_backend_relocate_section ip2k_elf_relocate_section 1520 1.1 christos 1521 1.1 christos #define elf_symbol_leading_char '_' 1522 1.1 christos #define bfd_elf32_bfd_reloc_type_lookup ip2k_reloc_type_lookup 1523 1.1 christos #define bfd_elf32_bfd_reloc_name_lookup ip2k_reloc_name_lookup 1524 1.1 christos #define bfd_elf32_bfd_relax_section ip2k_elf_relax_section 1525 1.1 christos 1526 1.1 christos #include "elf32-target.h" 1527