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