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