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