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