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