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