daily update
[deliverable/binutils-gdb.git] / bfd / elf32-ip2k.c
CommitLineData
fd13ed0c 1/* Ubicom IP2xxx specific support for 32-bit ELF
b2a8e766 2 Copyright 2000, 2001, 2002, 2003, 2004 Free Software Foundation, Inc.
cf88bb9f
NC
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. */
28struct misc
29{
30 Elf_Internal_Shdr * symtab_hdr;
31 Elf_Internal_Rela * irelbase;
32 bfd_byte * contents;
fd13ed0c 33 Elf_Internal_Sym * isymbuf;
cf88bb9f
NC
34};
35
aecde77e
NC
36struct ip2k_opcode
37{
38 unsigned short opcode;
39 unsigned short mask;
40};
41
cf88bb9f 42/* Prototypes. */
b34976b6
AM
43static reloc_howto_type *ip2k_reloc_type_lookup
44 PARAMS ((bfd *, bfd_reloc_code_real_type));
aecde77e
NC
45static int ip2k_is_opcode
46 PARAMS ((bfd_byte *, const struct ip2k_opcode *));
b34976b6
AM
47static bfd_vma symbol_value
48 PARAMS ((bfd *, Elf_Internal_Shdr *, Elf_Internal_Sym *,
49 Elf_Internal_Rela *));
aecde77e
NC
50static void ip2k_get_mem
51 PARAMS ((bfd *, bfd_byte *, int, bfd_byte *));
52static bfd_vma ip2k_nominal_page_bits
53 PARAMS ((bfd *, asection *, bfd_vma, bfd_byte *));
54static bfd_boolean ip2k_test_page_insn
55 PARAMS ((bfd *, asection *, Elf_Internal_Rela *, struct misc *));
56static bfd_boolean ip2k_delete_page_insn
57 PARAMS ((bfd *, asection *, Elf_Internal_Rela *, bfd_boolean *, struct misc *));
58static int ip2k_is_switch_table_128
59 PARAMS ((bfd *, asection *, bfd_vma, bfd_byte *));
60static bfd_boolean ip2k_relax_switch_table_128
61 PARAMS ((bfd *, asection *, Elf_Internal_Rela *, bfd_boolean *, struct misc *));
62static int ip2k_is_switch_table_256
63 PARAMS ((bfd *, asection *, bfd_vma, bfd_byte *));
64static bfd_boolean ip2k_relax_switch_table_256
65 PARAMS ((bfd *, asection *, Elf_Internal_Rela *, bfd_boolean *, struct misc *));
66static bfd_boolean ip2k_elf_relax_section
67 PARAMS ((bfd *, asection *, struct bfd_link_info *, bfd_boolean *));
68static bfd_boolean ip2k_elf_relax_section_page
69 PARAMS ((bfd *, asection *, bfd_boolean *, struct misc *, unsigned long, unsigned long));
b34976b6
AM
70static void adjust_all_relocations
71 PARAMS ((bfd *, asection *, bfd_vma, bfd_vma, int, int));
72static bfd_boolean ip2k_elf_relax_delete_bytes
73 PARAMS ((bfd *, asection *, bfd_vma, int));
aecde77e
NC
74static void ip2k_info_to_howto_rela
75 PARAMS ((bfd *, arelent *, Elf_Internal_Rela *));
b34976b6
AM
76static bfd_reloc_status_type ip2k_final_link_relocate
77 PARAMS ((reloc_howto_type *, bfd *, asection *, bfd_byte *,
78 Elf_Internal_Rela *, bfd_vma));
79static 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 **));
aecde77e
NC
82static 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 *));
85static bfd_boolean ip2k_elf_gc_sweep_hook
86 PARAMS ((bfd *, struct bfd_link_info *, asection *,
87 const Elf_Internal_Rela *));
cf88bb9f 88
aecde77e 89static bfd_boolean ip2k_relaxed = FALSE;
cf88bb9f 90
aecde77e 91static const struct ip2k_opcode ip2k_page_opcode[] =
cf88bb9f 92{
aecde77e
NC
93 {0x0010, 0xFFF8}, /* page */
94 {0x0000, 0x0000},
cf88bb9f
NC
95};
96
aecde77e
NC
97#define IS_PAGE_OPCODE(code) \
98 ip2k_is_opcode (code, ip2k_page_opcode)
cf88bb9f 99
aecde77e 100static const struct ip2k_opcode ip2k_jmp_opcode[] =
cf88bb9f 101{
aecde77e
NC
102 {0xE000, 0xE000}, /* jmp */
103 {0x0000, 0x0000},
cf88bb9f
NC
104};
105
aecde77e
NC
106#define IS_JMP_OPCODE(code) \
107 ip2k_is_opcode (code, ip2k_jmp_opcode)
cf88bb9f 108
aecde77e 109static const struct ip2k_opcode ip2k_snc_opcode[] =
cf88bb9f 110{
aecde77e
NC
111 {0xA00B, 0xFFFF}, /* snc */
112 {0x0000, 0x0000},
cf88bb9f
NC
113};
114
aecde77e
NC
115#define IS_SNC_OPCODE(code) \
116 ip2k_is_opcode (code, ip2k_snc_opcode)
cf88bb9f 117
aecde77e 118static const struct ip2k_opcode ip2k_inc_1sp_opcode[] =
cf88bb9f 119{
aecde77e
NC
120 {0x2B81, 0xFFFF}, /* inc 1(SP) */
121 {0x0000, 0x0000},
cf88bb9f
NC
122};
123
aecde77e
NC
124#define IS_INC_1SP_OPCODE(code) \
125 ip2k_is_opcode (code, ip2k_inc_1sp_opcode)
cf88bb9f 126
aecde77e 127static const struct ip2k_opcode ip2k_add_2sp_w_opcode[] =
cf88bb9f 128{
aecde77e
NC
129 {0x1F82, 0xFFFF}, /* add 2(SP),w */
130 {0x0000, 0x0000},
cf88bb9f
NC
131};
132
aecde77e
NC
133#define IS_ADD_2SP_W_OPCODE(code) \
134 ip2k_is_opcode (code, ip2k_add_2sp_w_opcode)
cf88bb9f 135
aecde77e 136static const struct ip2k_opcode ip2k_add_w_wreg_opcode[] =
cf88bb9f 137{
aecde77e
NC
138 {0x1C0A, 0xFFFF}, /* add w,wreg */
139 {0x1E0A, 0xFFFF}, /* add wreg,w */
140 {0x0000, 0x0000},
cf88bb9f
NC
141};
142
aecde77e
NC
143#define IS_ADD_W_WREG_OPCODE(code) \
144 ip2k_is_opcode (code, ip2k_add_w_wreg_opcode)
145
146static const struct ip2k_opcode ip2k_add_pcl_w_opcode[] =
147{
148 {0x1E09, 0xFFFF}, /* add pcl,w */
149 {0x0000, 0x0000},
150};
cf88bb9f 151
aecde77e
NC
152#define IS_ADD_PCL_W_OPCODE(code) \
153 ip2k_is_opcode (code, ip2k_add_pcl_w_opcode)
cf88bb9f 154
aecde77e 155static const struct ip2k_opcode ip2k_skip_opcodes[] =
cf88bb9f 156{
aecde77e
NC
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},
cf88bb9f
NC
166};
167
aecde77e
NC
168#define IS_SKIP_OPCODE(code) \
169 ip2k_is_opcode (code, ip2k_skip_opcodes)
cf88bb9f 170
aecde77e 171/* Relocation tables. */
cf88bb9f
NC
172static 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 */ \
b34976b6 184 FALSE, /* partial_inplace */ \
cf88bb9f
NC
185 sm, /* src_mask */ \
186 dm, /* dst_mask */ \
187 pr) /* pcrel_offset */
188
aecde77e 189 /* This reloc does nothing. */
b34976b6 190 IP2K_HOWTO (R_IP2K_NONE, 0,2,32, FALSE, 0, "R_IP2K_NONE", 0, 0),
cf88bb9f 191 /* A 16 bit absolute relocation. */
b34976b6 192 IP2K_HOWTO (R_IP2K_16, 0,1,16, FALSE, 0, "R_IP2K_16", 0, 0xffff),
cf88bb9f 193 /* A 32 bit absolute relocation. */
b34976b6 194 IP2K_HOWTO (R_IP2K_32, 0,2,32, FALSE, 0, "R_IP2K_32", 0, 0xffffffff),
cf88bb9f 195 /* A 8-bit data relocation for the FR9 field. Ninth bit is computed specially. */
b34976b6 196 IP2K_HOWTO (R_IP2K_FR9, 0,1,9, FALSE, 0, "R_IP2K_FR9", 0, 0x00ff),
cf88bb9f 197 /* A 4-bit data relocation. */
b34976b6 198 IP2K_HOWTO (R_IP2K_BANK, 8,1,4, FALSE, 0, "R_IP2K_BANK", 0, 0x000f),
cf88bb9f 199 /* A 13-bit insn relocation - word address => right-shift 1 bit extra. */
b34976b6 200 IP2K_HOWTO (R_IP2K_ADDR16CJP, 1,1,13, FALSE, 0, "R_IP2K_ADDR16CJP", 0, 0x1fff),
cf88bb9f 201 /* A 3-bit insn relocation - word address => right-shift 1 bit extra. */
b34976b6 202 IP2K_HOWTO (R_IP2K_PAGE3, 14,1,3, FALSE, 0, "R_IP2K_PAGE3", 0, 0x0007),
cf88bb9f 203 /* Two 8-bit data relocations. */
b34976b6
AM
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),
cf88bb9f 206 /* Two 8-bit insn relocations. word address => right-shift 1 bit extra. */
b34976b6
AM
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),
cf88bb9f
NC
209
210 /* Special 1 bit relocation for SKIP instructions. */
b34976b6 211 IP2K_HOWTO (R_IP2K_PC_SKIP, 1,1,1, FALSE, 12, "R_IP2K_PC_SKIP", 0xfffe, 0x1000),
cf88bb9f 212 /* 16 bit word address. */
b34976b6 213 IP2K_HOWTO (R_IP2K_TEXT, 1,1,16, FALSE, 0, "R_IP2K_TEXT", 0, 0xffff),
cf88bb9f 214 /* A 7-bit offset relocation for the FR9 field. Eigth and ninth bit comes from insn. */
b34976b6 215 IP2K_HOWTO (R_IP2K_FR_OFFSET, 0,1,9, FALSE, 0, "R_IP2K_FR_OFFSET", 0x180, 0x007f),
cf88bb9f 216 /* Bits 23:16 of an address. */
b34976b6 217 IP2K_HOWTO (R_IP2K_EX8DATA, 16,1,8, FALSE, 0, "R_IP2K_EX8DATA", 0, 0x00ff),
cf88bb9f
NC
218};
219
220
aecde77e 221/* Map BFD reloc types to IP2K ELF reloc types. */
cf88bb9f
NC
222static reloc_howto_type *
223ip2k_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
aecde77e 230 include/elf/ip2k.h. */
cf88bb9f
NC
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:
aecde77e 265 /* Pacify gcc -Wall. */
cf88bb9f
NC
266 return NULL;
267 }
268 return NULL;
269}
270
aecde77e
NC
271static void
272ip2k_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
282static bfd_boolean
283ip2k_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)
cf88bb9f
NC
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
307static bfd_vma
fd13ed0c 308symbol_value (abfd, symtab_hdr, isymbuf, irel)
cf88bb9f
NC
309 bfd *abfd;
310 Elf_Internal_Shdr *symtab_hdr;
947216bf 311 Elf_Internal_Sym *isymbuf;
b34976b6 312 Elf_Internal_Rela *irel;
cf88bb9f
NC
313{
314 if (ELF32_R_SYM (irel->r_info) < symtab_hdr->sh_info)
315 {
fd13ed0c 316 Elf_Internal_Sym *isym;
cf88bb9f
NC
317 asection *sym_sec;
318
fd13ed0c
DC
319 isym = isymbuf + ELF32_R_SYM (irel->r_info);
320 if (isym->st_shndx == SHN_UNDEF)
cf88bb9f 321 sym_sec = bfd_und_section_ptr;
fd13ed0c 322 else if (isym->st_shndx == SHN_ABS)
cf88bb9f 323 sym_sec = bfd_abs_section_ptr;
fd13ed0c 324 else if (isym->st_shndx == SHN_COMMON)
cf88bb9f
NC
325 sym_sec = bfd_com_section_ptr;
326 else
fd13ed0c 327 sym_sec = bfd_section_from_elf_index (abfd, isym->st_shndx);
cf88bb9f 328
fd13ed0c 329 return isym->st_value + BASEADDR (sym_sec);
cf88bb9f
NC
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
aecde77e
NC
348/* Returns the expected page state for the given instruction not including
349 the effect of page instructions. */
350
351static bfd_vma
352ip2k_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
406static bfd_boolean
407ip2k_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
431static bfd_boolean
432ip2k_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
cf88bb9f
NC
457/* Determine if the instruction sequence matches that for
458 the prologue of a switch dispatch table with fewer than
459 128 entries.
b34976b6 460
cf88bb9f
NC
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
b34976b6 474
cf88bb9f
NC
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
aecde77e
NC
486static int
487ip2k_is_switch_table_128 (abfd, sec, addr, contents)
b34976b6 488 bfd *abfd ATTRIBUTE_UNUSED;
aecde77e 489 asection *sec;
cf88bb9f 490 bfd_vma addr;
aecde77e
NC
491 bfd_byte *contents;
492{
493 bfd_byte code[4];
494 int index = 0;
495
496 /* Check current page-jmp. */
eea6121a 497 if (addr + 4 > sec->size)
aecde77e
NC
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
527static bfd_boolean
528ip2k_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;
cf88bb9f
NC
533 struct misc *misc;
534{
aecde77e
NC
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 {
eea6121a 544 if (addr + 4 > sec->size)
aecde77e 545 break;
cf88bb9f 546
aecde77e
NC
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;
cf88bb9f 551
aecde77e
NC
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 }
cf88bb9f 559
aecde77e
NC
560 if (ireltest->r_offset != addr)
561 {
562 _bfd_error_handler (_("ip2k relaxer: switch table without complete matching relocation information."));
563 return FALSE;
564 }
cf88bb9f 565
aecde77e
NC
566 if (! ip2k_test_page_insn (abfd, sec, ireltest, misc))
567 /* Un-removable page insn => nothing can be done. */
568 return TRUE;
cf88bb9f 569
aecde77e
NC
570 addr += 4;
571 ireltest += 2;
572 }
cf88bb9f 573
aecde77e
NC
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)))
cf88bb9f 578 {
aecde77e
NC
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;
cf88bb9f 585
aecde77e 586 *again = TRUE;
cf88bb9f 587
aecde77e
NC
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;
cf88bb9f
NC
594 }
595
b34976b6 596 return TRUE;
cf88bb9f
NC
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.
b34976b6 602
cf88bb9f
NC
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
b34976b6 623
cf88bb9f
NC
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
aecde77e
NC
639static int
640ip2k_is_switch_table_256 (abfd, sec, addr, contents)
cf88bb9f 641 bfd *abfd ATTRIBUTE_UNUSED;
cf88bb9f
NC
642 asection *sec;
643 bfd_vma addr;
aecde77e 644 bfd_byte *contents;
cf88bb9f 645{
aecde77e
NC
646 bfd_byte code[16];
647 int index = 0;
648
649 /* Check current page-jmp. */
eea6121a 650 if (addr + 4 > sec->size)
aecde77e
NC
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)
cf88bb9f 660 {
aecde77e
NC
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;
cf88bb9f 691 }
cf88bb9f
NC
692}
693
b34976b6 694static bfd_boolean
aecde77e
NC
695ip2k_relax_switch_table_256 (abfd, sec, irel, again, misc)
696 bfd *abfd ATTRIBUTE_UNUSED;
cf88bb9f 697 asection *sec;
aecde77e
NC
698 Elf_Internal_Rela *irel;
699 bfd_boolean *again;
cf88bb9f
NC
700 struct misc *misc;
701{
aecde77e
NC
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)
cf88bb9f 711 {
eea6121a 712 if (addr + 4 > sec->size)
aecde77e 713 break;
cf88bb9f 714
aecde77e 715 ip2k_get_mem (abfd, misc->contents + addr, 4, code);
cf88bb9f 716
aecde77e
NC
717 if ((! IS_PAGE_OPCODE (code + 0))
718 || (! IS_JMP_OPCODE (code + 2)))
719 break;
cf88bb9f 720
aecde77e
NC
721 /* Validate relocation entry (every entry should have a matching
722 relocation entry). */
723 if (ireltest >= irelend)
cf88bb9f 724 {
aecde77e
NC
725 _bfd_error_handler (_("ip2k relaxer: switch table without complete matching relocation information."));
726 return FALSE;
cf88bb9f
NC
727 }
728
aecde77e 729 if (ireltest->r_offset != addr)
cf88bb9f 730 {
aecde77e
NC
731 _bfd_error_handler (_("ip2k relaxer: switch table without complete matching relocation information."));
732 return FALSE;
733 }
cf88bb9f 734
aecde77e
NC
735 if (!ip2k_test_page_insn (abfd, sec, ireltest, misc))
736 /* Un-removable page insn => nothing can be done. */
737 return TRUE;
cf88bb9f 738
aecde77e
NC
739 addr += 4;
740 ireltest += 2;
741 }
cf88bb9f 742
aecde77e
NC
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 }
cf88bb9f 761
aecde77e
NC
762 /* Delete first 3 opcodes. */
763 if (!ip2k_elf_relax_delete_bytes (abfd, sec, addr + 0, 6))
764 return FALSE;
cf88bb9f 765
aecde77e 766 *again = TRUE;
cf88bb9f 767
aecde77e
NC
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;
cf88bb9f
NC
774 }
775
b34976b6 776 return TRUE;
cf88bb9f
NC
777}
778
aecde77e
NC
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. */
cf88bb9f 788
b34976b6 789static bfd_boolean
cf88bb9f
NC
790ip2k_elf_relax_section (abfd, sec, link_info, again)
791 bfd *abfd;
792 asection *sec;
793 struct bfd_link_info *link_info;
b34976b6 794 bfd_boolean *again;
cf88bb9f 795{
fd13ed0c
DC
796 Elf_Internal_Shdr *symtab_hdr;
797 Elf_Internal_Rela *internal_relocs;
798 bfd_byte *contents = NULL;
799 Elf_Internal_Sym *isymbuf = NULL;
cf88bb9f 800 static asection * first_section = NULL;
aecde77e
NC
801 static unsigned long search_addr;
802 static unsigned long page_start = 0;
803 static unsigned long page_end = 0;
cf88bb9f 804 static unsigned int pass = 0;
aecde77e
NC
805 static bfd_boolean new_pass = FALSE;
806 static bfd_boolean changed = FALSE;
cf88bb9f
NC
807 struct misc misc;
808 asection *stab;
809
810 /* Assume nothing changes. */
b34976b6 811 *again = FALSE;
cf88bb9f
NC
812
813 if (first_section == NULL)
aecde77e
NC
814 {
815 ip2k_relaxed = TRUE;
816 first_section = sec;
817 }
cf88bb9f
NC
818
819 if (first_section == sec)
820 {
cf88bb9f 821 pass++;
aecde77e 822 new_pass = TRUE;
cf88bb9f
NC
823 }
824
cf88bb9f
NC
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. */
1049f94e 828 if (link_info->relocatable
cf88bb9f
NC
829 || (sec->flags & SEC_RELOC) == 0
830 || sec->reloc_count == 0
831 || (sec->flags & SEC_CODE) == 0)
b34976b6 832 return TRUE;
cf88bb9f 833
fd13ed0c 834 symtab_hdr = &elf_tdata (abfd)->symtab_hdr;
cf88bb9f 835
45d6a902
AM
836 internal_relocs = _bfd_elf_link_read_relocs (abfd, sec, NULL,
837 (Elf_Internal_Rela *)NULL,
838 link_info->keep_memory);
fd13ed0c
DC
839 if (internal_relocs == NULL)
840 goto error_return;
cf88bb9f
NC
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
45d6a902
AM
850 irelbase = _bfd_elf_link_read_relocs (abfd, stab, NULL,
851 (Elf_Internal_Rela *)NULL,
852 link_info->keep_memory);
cf88bb9f
NC
853 }
854
855 /* Get section contents cached copy if it exists. */
fd13ed0c 856 if (contents == NULL)
cf88bb9f 857 {
fd13ed0c
DC
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
cf88bb9f 862 {
fd13ed0c 863 /* Go get them off disk. */
eea6121a 864 if (!bfd_malloc_and_get_section (abfd, sec, &contents))
fd13ed0c 865 goto error_return;
cf88bb9f
NC
866 }
867 }
b34976b6 868
cf88bb9f 869 /* Read this BFD's symbols cached copy if it exists. */
fd13ed0c 870 if (isymbuf == NULL && symtab_hdr->sh_info != 0)
cf88bb9f 871 {
fd13ed0c
DC
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;
cf88bb9f
NC
879 }
880
fd13ed0c
DC
881 misc.symtab_hdr = symtab_hdr;
882 misc.isymbuf = isymbuf;
883 misc.irelbase = internal_relocs;
884 misc.contents = contents;
b34976b6 885
cf88bb9f 886 /* This is where all the relaxation actually get done. */
aecde77e 887 if ((pass == 1) || (new_pass && !changed))
cf88bb9f 888 {
aecde77e
NC
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 }
cf88bb9f 900
eea6121a
AM
901 if ((BASEADDR (sec) + sec->size < search_addr)
902 && (BASEADDR (sec) + sec->size > page_end))
aecde77e
NC
903 {
904 if (BASEADDR (sec) <= page_end)
905 search_addr = page_end + 1;
906 else
907 search_addr = BASEADDR (sec);
cf88bb9f 908
aecde77e
NC
909 /* Found a page => more work to do. */
910 *again = TRUE;
911 }
cf88bb9f
NC
912 }
913 else
914 {
aecde77e
NC
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 }
cf88bb9f 922
aecde77e 923 /* Only process sections in range. */
eea6121a 924 if ((BASEADDR (sec) + sec->size >= page_start)
aecde77e 925 && (BASEADDR (sec) <= page_end))
cf88bb9f 926 {
aecde77e
NC
927 if (!ip2k_elf_relax_section_page (abfd, sec, &changed, &misc, page_start, page_end))
928 return FALSE;
cf88bb9f 929 }
aecde77e 930 *again = TRUE;
cf88bb9f
NC
931 }
932
b34976b6 933 /* Perform some house keeping after relaxing the section. */
cf88bb9f 934
fd13ed0c
DC
935 if (isymbuf != NULL
936 && symtab_hdr->contents != (unsigned char *) isymbuf)
cf88bb9f
NC
937 {
938 if (! link_info->keep_memory)
fd13ed0c 939 free (isymbuf);
cf88bb9f 940 else
fd13ed0c 941 symtab_hdr->contents = (unsigned char *) isymbuf;
cf88bb9f
NC
942 }
943
fd13ed0c
DC
944 if (contents != NULL
945 && elf_section_data (sec)->this_hdr.contents != contents)
cf88bb9f
NC
946 {
947 if (! link_info->keep_memory)
fd13ed0c 948 free (contents);
cf88bb9f
NC
949 else
950 {
fd13ed0c
DC
951 /* Cache the section contents for elf_link_input_bfd. */
952 elf_section_data (sec)->this_hdr.contents = contents;
cf88bb9f 953 }
cf88bb9f
NC
954 }
955
fd13ed0c
DC
956 if (internal_relocs != NULL
957 && elf_section_data (sec)->relocs != internal_relocs)
958 free (internal_relocs);
cf88bb9f 959
b34976b6 960 return TRUE;
cf88bb9f 961
fd13ed0c
DC
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);
b34976b6 972 return FALSE;
cf88bb9f
NC
973}
974
aecde77e 975/* This function handles relaxation of a section in a specific page. */
cf88bb9f 976
b34976b6 977static bfd_boolean
aecde77e 978ip2k_elf_relax_section_page (abfd, sec, again, misc, page_start, page_end)
cf88bb9f
NC
979 bfd *abfd;
980 asection *sec;
b34976b6 981 bfd_boolean *again;
aecde77e
NC
982 struct misc *misc;
983 unsigned long page_start;
984 unsigned long page_end;
cf88bb9f
NC
985{
986 Elf_Internal_Rela *irelend = misc->irelbase + sec->reloc_count;
987 Elf_Internal_Rela *irel;
aecde77e
NC
988 int switch_table_128;
989 int switch_table_256;
990
4cc11e76 991 /* Walk thru the section looking for relaxation opportunities. */
cf88bb9f
NC
992 for (irel = misc->irelbase; irel < irelend; irel++)
993 {
aecde77e
NC
994 if (ELF32_R_TYPE (irel->r_info) != (int) R_IP2K_PAGE3)
995 /* Ignore non page instructions. */
996 continue;
cf88bb9f 997
aecde77e
NC
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;
cf88bb9f 1003
aecde77e
NC
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;
cf88bb9f 1007
aecde77e
NC
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);
cf88bb9f 1011
aecde77e
NC
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;
cf88bb9f 1015
aecde77e 1016 if (switch_table_128 == 0)
cf88bb9f 1017 {
aecde77e
NC
1018 if (!ip2k_relax_switch_table_128 (abfd, sec, irel, again, misc))
1019 return FALSE;
1020
1021 continue;
cf88bb9f 1022 }
cf88bb9f 1023
aecde77e
NC
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 }
b34976b6 1031
aecde77e
NC
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 }
cf88bb9f 1041
b34976b6 1042 return TRUE;
cf88bb9f
NC
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
1056static void
1057adjust_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;
fd13ed0c
DC
1066 Elf_Internal_Sym *isymbuf, *isym, *isymend;
1067 unsigned int shndx;
cf88bb9f
NC
1068 bfd_byte *contents;
1069 Elf_Internal_Rela *irel, *irelend, *irelbase;
fd13ed0c
DC
1070 struct elf_link_hash_entry **sym_hashes;
1071 struct elf_link_hash_entry **end_hashes;
1072 unsigned int symcount;
aecde77e 1073 asection *stab;
b34976b6 1074
cf88bb9f 1075 symtab_hdr = &elf_tdata (abfd)->symtab_hdr;
947216bf 1076 isymbuf = (Elf_Internal_Sym *) symtab_hdr->contents;
cf88bb9f
NC
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 {
cf88bb9f 1092 asection *sym_sec;
cf88bb9f
NC
1093
1094 /* A local symbol. */
fd13ed0c
DC
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)
cf88bb9f
NC
1099 {
1100 bfd_vma baseaddr = BASEADDR (sec);
fd13ed0c 1101 bfd_vma symval = BASEADDR (sym_sec) + isym->st_value
cf88bb9f
NC
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
aecde77e
NC
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;
eea6121a 1121 bfd_size_type stab_size = stab->rawsize ? stab->rawsize : stab->size;
aecde77e
NC
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 {
eea6121a
AM
1131 if (!bfd_malloc_and_get_section (abfd, stab, &stabcontents))
1132 {
1133 if (stabcontents != NULL)
1134 free (stabcontents);
1135 return;
1136 }
aecde77e
NC
1137
1138 /* We need to remember this. */
1139 elf_section_data (stab)->this_hdr.contents = stabcontents;
1140 }
1141
eea6121a 1142 stabend = stabcontents + stab_size;
aecde77e
NC
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
cf88bb9f
NC
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. */
fd13ed0c
DC
1251 isymend = isymbuf + symtab_hdr->sh_info;
1252 for (isym = isymbuf; isym < isymend; isym++)
cf88bb9f 1253 {
fd13ed0c
DC
1254 if (isym->st_shndx == shndx
1255 && addr <= isym->st_value
1256 && isym->st_value < endaddr)
1257 isym->st_value += count;
cf88bb9f
NC
1258 }
1259
fd13ed0c
DC
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++)
cf88bb9f 1266 {
fd13ed0c 1267 struct elf_link_hash_entry *sym_hash = *sym_hashes;
aecde77e 1268
fd13ed0c
DC
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 {
cf88bb9f
NC
1273 if (addr <= sym_hash->root.u.def.value
1274 && sym_hash->root.u.def.value < endaddr)
aecde77e 1275 sym_hash->root.u.def.value += count;
fd13ed0c 1276 }
cf88bb9f
NC
1277 }
1278
1279 return;
1280}
1281
cf88bb9f
NC
1282/* Delete some bytes from a section while relaxing. */
1283
b34976b6 1284static bfd_boolean
cf88bb9f
NC
1285ip2k_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;
eea6121a 1292 bfd_vma endaddr = sec->size;
cf88bb9f
NC
1293
1294 /* Actually delete the bytes. */
1295 memmove (contents + addr, contents + addr + count,
1296 endaddr - addr - count);
1297
eea6121a 1298 sec->size -= count;
cf88bb9f
NC
1299
1300 adjust_all_relocations (abfd, sec, addr + count, endaddr, -count, 0);
b34976b6 1301 return TRUE;
cf88bb9f
NC
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
1311static void
1312ip2k_info_to_howto_rela (abfd, cache_ptr, dst)
1313 bfd * abfd ATTRIBUTE_UNUSED;
1314 arelent * cache_ptr;
947216bf 1315 Elf_Internal_Rela * dst;
cf88bb9f
NC
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
1331static bfd_reloc_status_type
1332ip2k_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{
aecde77e 1341 static bfd_vma page_addr = 0;
cf88bb9f 1342
aecde77e 1343 bfd_reloc_status_type r = bfd_reloc_ok;
cf88bb9f
NC
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. */
cf88bb9f 1361 case R_IP2K_PAGE3:
aecde77e
NC
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 {
4cc11e76 1372 /* No preceding page instruction, verify that it isn't needed. */
aecde77e
NC
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 {
4cc11e76 1382 /* Preceding page instruction. Verify that the page instruction is
aecde77e
NC
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
cf88bb9f
NC
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.
cf88bb9f
NC
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
1049f94e 1440 necessary, and (if using Rela relocs and generating a relocatable
cf88bb9f
NC
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
1049f94e 1454 When generating relocatable output, this function must handle
cf88bb9f
NC
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
b34976b6 1460static bfd_boolean
cf88bb9f
NC
1461ip2k_elf_relocate_section (output_bfd, info, input_bfd, input_section,
1462 contents, relocs, local_syms, local_sections)
b34976b6
AM
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;
cf88bb9f 1471{
b34976b6
AM
1472 Elf_Internal_Shdr *symtab_hdr;
1473 struct elf_link_hash_entry **sym_hashes;
1474 Elf_Internal_Rela *rel;
1475 Elf_Internal_Rela *relend;
cf88bb9f 1476
1049f94e 1477 if (info->relocatable)
b34976b6 1478 return TRUE;
f0fe0e16 1479
cf88bb9f
NC
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;
b34976b6 1495
f0fe0e16 1496 /* This is a final link. */
cf88bb9f 1497 r_type = ELF32_R_TYPE (rel->r_info);
cf88bb9f 1498 r_symndx = ELF32_R_SYM (rel->r_info);
cf88bb9f
NC
1499 howto = ip2k_elf_howto_table + ELF32_R_TYPE (rel->r_info);
1500 h = NULL;
1501 sym = NULL;
1502 sec = NULL;
b34976b6 1503
cf88bb9f
NC
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;
b34976b6 1509
cf88bb9f
NC
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 {
560e09e9
NC
1516 bfd_boolean warned;
1517 bfd_boolean unresolved_reloc;
b34976b6 1518
b2a8e766
AM
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);
cf88bb9f
NC
1523
1524 name = h->root.root.string;
cf88bb9f
NC
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
dfeffb9f
L
1539 (info, (h ? &h->root : NULL), name, howto->name,
1540 (bfd_vma) 0, input_bfd, input_section, rel->r_offset);
cf88bb9f 1541 break;
b34976b6 1542
cf88bb9f
NC
1543 case bfd_reloc_undefined:
1544 r = info->callbacks->undefined_symbol
b34976b6 1545 (info, name, input_bfd, input_section, rel->r_offset, TRUE);
cf88bb9f 1546 break;
b34976b6 1547
cf88bb9f
NC
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)
b34976b6 1573 return FALSE;
cf88bb9f
NC
1574 }
1575 }
1576
b34976b6 1577 return TRUE;
cf88bb9f
NC
1578}
1579
1580static asection *
1581ip2k_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 {
cf88bb9f
NC
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))
aecde77e 1613 return bfd_section_from_elf_index (sec->owner, sym->st_shndx);
cf88bb9f
NC
1614 }
1615 return NULL;
1616}
1617
b34976b6 1618static bfd_boolean
cf88bb9f
NC
1619ip2k_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{
aecde77e 1625 /* We don't use got and plt entries for ip2k. */
b34976b6 1626 return TRUE;
cf88bb9f
NC
1627}
1628
cf88bb9f
NC
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
0d09fec6 1634#define ELF_MACHINE_ALT1 EM_IP2K_OLD
aecde77e 1635#define ELF_MAXPAGESIZE 1 /* No pages on the IP2K. */
cf88bb9f 1636
cf88bb9f
NC
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
f0fe0e16 1641#define elf_backend_rela_normal 1
cf88bb9f
NC
1642#define elf_backend_gc_mark_hook ip2k_elf_gc_mark_hook
1643#define elf_backend_gc_sweep_hook ip2k_elf_gc_sweep_hook
cf88bb9f
NC
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
cf88bb9f 1650#include "elf32-target.h"
This page took 0.221506 seconds and 4 git commands to generate.