gdb: add target_ops::supports_displaced_step
[deliverable/binutils-gdb.git] / bfd / elf32-ip2k.c
CommitLineData
fd13ed0c 1/* Ubicom IP2xxx specific support for 32-bit ELF
b3adc24a 2 Copyright (C) 2000-2020 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;
07d6d2b8 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) \
07d6d2b8
AM
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 */ \
138 FALSE, /* partial_inplace */ \
139 sm, /* src_mask */ \
140 dm, /* dst_mask */ \
141 pr) /* pcrel_offset */
cf88bb9f 142
aecde77e 143 /* This reloc does nothing. */
6346d5ca 144 IP2K_HOWTO (R_IP2K_NONE, 0,3,0, 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
07d6d2b8
AM
317 sc
318 page $nnn0
319 jmp $nnn0
320 add w,wreg
321 add pcl,w
cf88bb9f 322 addr=>
07d6d2b8
AM
323 page $nnn1
324 jmp $nnn1
325 page $nnn2
326 jmp $nnn2
327 ...
328 page $nnnN
329 jmp $nnnN
b34976b6 330
cf88bb9f 331 After relaxation.
07d6d2b8
AM
332 sc
333 page $nnn0
334 jmp $nnn0
335 add pcl,w
cf88bb9f 336 addr=>
07d6d2b8
AM
337 jmp $nnn1
338 jmp $nnn2
339 ...
340 jmp $nnnN */
cf88bb9f 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 386 Before relaxation.
07d6d2b8
AM
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)
cf88bb9f 395 addr=>
07d6d2b8
AM
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 407 After relaxation.
07d6d2b8
AM
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)
cf88bb9f 413 addr=>
07d6d2b8
AM
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 */
cf88bb9f 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)
07d6d2b8 518 {
47b0e7ad 519 ip2k_get_mem (abfd, contents + addr - 2, 2, code);
07d6d2b8 520 if (IS_SKIP_OPCODE (code))
47b0e7ad
NC
521 /* Page is conditional. */
522 continue;
07d6d2b8 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 595 if (ELF32_R_TYPE (irel->r_info) != R_IP2K_NONE)
07d6d2b8
AM
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
07d6d2b8 602 /* A local symbol. */
47b0e7ad 603 isym = isymbuf + ELF32_R_SYM (irel->r_info);
07d6d2b8 604 sym_sec = bfd_section_from_elf_index (abfd, isym->st_shndx);
cf88bb9f 605
07d6d2b8
AM
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
07d6d2b8
AM
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)
07d6d2b8 621 irel->r_offset += count;
47b0e7ad 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 {
c9594989 641 free (stabcontents);
47b0e7ad
NC
642 return;
643 }
644
645 /* We need to remember this. */
646 elf_section_data (stab)->this_hdr.contents = stabcontents;
647 }
648
649 stabend = stabcontents + stab_size;
650
651 for (irel = irelbase; irel < irelend; irel++)
652 {
653 if (ELF32_R_TYPE (irel->r_info) != R_IP2K_NONE)
654 {
655 /* Get the value of the symbol referred to by the reloc. */
656 if (ELF32_R_SYM (irel->r_info) < symtab_hdr->sh_info)
657 {
658 asection *sym_sec;
68ffbac6 659
47b0e7ad
NC
660 /* A local symbol. */
661 isym = isymbuf + ELF32_R_SYM (irel->r_info);
662 sym_sec = bfd_section_from_elf_index (abfd, isym->st_shndx);
68ffbac6 663
47b0e7ad
NC
664 if (sym_sec == sec)
665 {
666 const char *name;
c7e2358a 667 unsigned char type;
47b0e7ad
NC
668 bfd_vma value;
669 bfd_vma baseaddr = BASEADDR (sec);
670 bfd_vma symval = BASEADDR (sym_sec) + isym->st_value
671 + irel->r_addend;
68ffbac6 672
47b0e7ad
NC
673 if ((baseaddr + addr) <= symval
674 && symval <= (baseaddr + endaddr))
675 irel->r_addend += count;
676
677 /* Go hunt up a function and fix its line info if needed. */
68ffbac6 678 stabp = stabcontents + irel->r_offset - 8;
47b0e7ad
NC
679
680 /* Go pullout the stab entry. */
47b0e7ad 681 type = bfd_h_get_8 (abfd, stabp + TYPEOFF);
47b0e7ad 682 value = bfd_h_get_32 (abfd, stabp + VALOFF);
68ffbac6 683
47b0e7ad 684 name = bfd_get_stab_name (type);
68ffbac6 685
47b0e7ad
NC
686 if (strcmp (name, "FUN") == 0)
687 {
688 int function_adjusted = 0;
689
690 if (symval > (baseaddr + addr))
691 /* Not in this function. */
692 continue;
693
694 /* Hey we got a function hit. */
695 stabp += STABSIZE;
696 for (;stabp < stabend; stabp += STABSIZE)
697 {
698 /* Go pullout the stab entry. */
47b0e7ad 699 type = bfd_h_get_8 (abfd, stabp + TYPEOFF);
47b0e7ad
NC
700 value = bfd_h_get_32 (abfd, stabp + VALOFF);
701
702 name = bfd_get_stab_name (type);
703
704 if (strcmp (name, "FUN") == 0)
705 {
706 /* Hit another function entry. */
707 if (function_adjusted)
708 {
709 /* Adjust the value. */
710 value += count;
68ffbac6 711
47b0e7ad
NC
712 /* We need to put it back. */
713 bfd_h_put_32 (abfd, value,stabp + VALOFF);
714 }
715
716 /* And then bale out. */
717 break;
718 }
719
720 if (strcmp (name, "SLINE") == 0)
721 {
722 /* Got a line entry. */
723 if ((baseaddr + addr) <= (symval + value))
724 {
725 /* Adjust the line entry. */
726 value += count;
727
728 /* We need to put it back. */
729 bfd_h_put_32 (abfd, value,stabp + VALOFF);
730 function_adjusted = 1;
731 }
732 }
733 }
734 }
735 }
736 }
737 }
738 }
cf88bb9f
NC
739 }
740
47b0e7ad
NC
741 /* When adding an instruction back it is sometimes necessary to move any
742 global or local symbol that was referencing the first instruction of
743 the moved block to refer to the first instruction of the inserted block.
744
745 For example adding a PAGE instruction before a CALL or JMP requires
746 that any label on the CALL or JMP is moved to the PAGE insn. */
747 addr += noadj;
748
749 /* Adjust the local symbols defined in this section. */
750 isymend = isymbuf + symtab_hdr->sh_info;
751 for (isym = isymbuf; isym < isymend; isym++)
cf88bb9f 752 {
47b0e7ad
NC
753 if (isym->st_shndx == shndx
754 && addr <= isym->st_value
755 && isym->st_value < endaddr)
756 isym->st_value += count;
757 }
758
759 /* Now adjust the global symbols defined in this section. */
760 symcount = (symtab_hdr->sh_size / sizeof (Elf32_External_Sym)
761 - symtab_hdr->sh_info);
762 sym_hashes = elf_sym_hashes (abfd);
763 end_hashes = sym_hashes + symcount;
764 for (; sym_hashes < end_hashes; sym_hashes++)
765 {
766 struct elf_link_hash_entry *sym_hash = *sym_hashes;
767
768 if ((sym_hash->root.type == bfd_link_hash_defined
769 || sym_hash->root.type == bfd_link_hash_defweak)
770 && sym_hash->root.u.def.section == sec)
cf88bb9f 771 {
07d6d2b8
AM
772 if (addr <= sym_hash->root.u.def.value
773 && sym_hash->root.u.def.value < endaddr)
47b0e7ad 774 sym_hash->root.u.def.value += count;
cf88bb9f
NC
775 }
776 }
b34976b6 777
47b0e7ad
NC
778 return;
779}
780
781/* Delete some bytes from a section while relaxing. */
782
783static bfd_boolean
784ip2k_elf_relax_delete_bytes (bfd *abfd,
785 asection *sec,
786 bfd_vma addr,
787 int count)
788{
789 bfd_byte *contents = elf_section_data (sec)->this_hdr.contents;
790 bfd_vma endaddr = sec->size;
791
792 /* Actually delete the bytes. */
793 memmove (contents + addr, contents + addr + count,
794 endaddr - addr - count);
795
796 sec->size -= count;
797
798 adjust_all_relocations (abfd, sec, addr + count, endaddr, -count, 0);
799 return TRUE;
800}
801
802static bfd_boolean
803ip2k_delete_page_insn (bfd *abfd ATTRIBUTE_UNUSED,
804 asection *sec,
805 Elf_Internal_Rela *irel,
806 bfd_boolean *again,
807 struct misc *misc)
808{
809 /* Note that we've changed the relocs, section contents, etc. */
810 elf_section_data (sec)->relocs = misc->irelbase;
811 elf_section_data (sec)->this_hdr.contents = misc->contents;
812 misc->symtab_hdr->contents = (bfd_byte *) misc->isymbuf;
813
814 /* Fix the relocation's type. */
815 irel->r_info = ELF32_R_INFO (ELF32_R_SYM (irel->r_info), R_IP2K_NONE);
816
817 /* Delete the PAGE insn. */
818 if (!ip2k_elf_relax_delete_bytes (abfd, sec, irel->r_offset, 2))
819 return FALSE;
68ffbac6 820
47b0e7ad
NC
821 /* Modified => will need to iterate relaxation again. */
822 *again = TRUE;
68ffbac6 823
47b0e7ad
NC
824 return TRUE;
825}
826
827static bfd_boolean
828ip2k_relax_switch_table_128 (bfd *abfd ATTRIBUTE_UNUSED,
829 asection *sec,
830 Elf_Internal_Rela *irel,
831 bfd_boolean *again,
832 struct misc *misc)
833{
834 Elf_Internal_Rela *irelend = misc->irelbase + sec->reloc_count;
835 Elf_Internal_Rela *ireltest = irel;
836 bfd_byte code[4];
837 bfd_vma addr;
68ffbac6 838
47b0e7ad
NC
839 /* Test all page instructions. */
840 addr = irel->r_offset;
841 while (1)
842 {
843 if (addr + 4 > sec->size)
844 break;
845
846 ip2k_get_mem (abfd, misc->contents + addr, 4, code);
847 if ((! IS_PAGE_OPCODE (code + 0))
848 || (! IS_JMP_OPCODE (code + 2)))
849 break;
850
851 /* Validate relocation entry (every entry should have a matching
07d6d2b8 852 relocation entry). */
47b0e7ad 853 if (ireltest >= irelend)
07d6d2b8 854 {
47b0e7ad 855 _bfd_error_handler (_("ip2k relaxer: switch table without complete matching relocation information."));
07d6d2b8
AM
856 return FALSE;
857 }
47b0e7ad
NC
858
859 if (ireltest->r_offset != addr)
07d6d2b8 860 {
47b0e7ad 861 _bfd_error_handler (_("ip2k relaxer: switch table without complete matching relocation information."));
07d6d2b8
AM
862 return FALSE;
863 }
47b0e7ad
NC
864
865 if (! ip2k_test_page_insn (abfd, sec, ireltest, misc))
866 /* Un-removable page insn => nothing can be done. */
867 return TRUE;
868
869 addr += 4;
870 ireltest += 2;
871 }
872
873 /* Relaxable. Adjust table header. */
874 ip2k_get_mem (abfd, misc->contents + irel->r_offset - 4, 4, code);
875 if ((! IS_ADD_W_WREG_OPCODE (code + 0))
876 || (! IS_ADD_PCL_W_OPCODE (code + 2)))
877 {
878 _bfd_error_handler (_("ip2k relaxer: switch table header corrupt."));
879 return FALSE;
880 }
881
882 if (!ip2k_elf_relax_delete_bytes (abfd, sec, irel->r_offset - 4, 2))
883 return FALSE;
884
885 *again = TRUE;
886
887 /* Delete all page instructions in table. */
888 while (irel < ireltest)
889 {
890 if (!ip2k_delete_page_insn (abfd, sec, irel, again, misc))
891 return FALSE;
892 irel += 2;
893 }
894
895 return TRUE;
896}
897
898static bfd_boolean
899ip2k_relax_switch_table_256 (bfd *abfd ATTRIBUTE_UNUSED,
900 asection *sec,
901 Elf_Internal_Rela *irel,
902 bfd_boolean *again,
903 struct misc *misc)
904{
905 Elf_Internal_Rela *irelend = misc->irelbase + sec->reloc_count;
906 Elf_Internal_Rela *ireltest = irel;
907 bfd_byte code[12];
908 bfd_vma addr;
68ffbac6 909
47b0e7ad
NC
910 /* Test all page instructions. */
911 addr = irel->r_offset;
912
913 while (1)
cf88bb9f 914 {
47b0e7ad
NC
915 if (addr + 4 > sec->size)
916 break;
cf88bb9f 917
47b0e7ad 918 ip2k_get_mem (abfd, misc->contents + addr, 4, code);
b34976b6 919
47b0e7ad
NC
920 if ((! IS_PAGE_OPCODE (code + 0))
921 || (! IS_JMP_OPCODE (code + 2)))
922 break;
cf88bb9f 923
47b0e7ad 924 /* Validate relocation entry (every entry should have a matching
07d6d2b8 925 relocation entry). */
47b0e7ad 926 if (ireltest >= irelend)
07d6d2b8
AM
927 {
928 _bfd_error_handler (_("ip2k relaxer: switch table without complete matching relocation information."));
929 return FALSE;
930 }
cf88bb9f 931
47b0e7ad 932 if (ireltest->r_offset != addr)
07d6d2b8
AM
933 {
934 _bfd_error_handler (_("ip2k relaxer: switch table without complete matching relocation information."));
935 return FALSE;
936 }
cf88bb9f 937
47b0e7ad
NC
938 if (!ip2k_test_page_insn (abfd, sec, ireltest, misc))
939 /* Un-removable page insn => nothing can be done. */
940 return TRUE;
941
942 addr += 4;
943 ireltest += 2;
cf88bb9f
NC
944 }
945
47b0e7ad
NC
946 /* Relaxable. Adjust table header. */
947 ip2k_get_mem (abfd, misc->contents + irel->r_offset - 4, 2, code);
948 if (IS_PAGE_OPCODE (code))
949 addr = irel->r_offset - 16;
950 else
951 addr = irel->r_offset - 14;
cf88bb9f 952
47b0e7ad
NC
953 ip2k_get_mem (abfd, misc->contents + addr, 12, code);
954 if ((!IS_ADD_W_WREG_OPCODE (code + 0))
955 || (!IS_SNC_OPCODE (code + 2))
956 || (!IS_INC_1SP_OPCODE (code + 4))
957 || (!IS_ADD_2SP_W_OPCODE (code + 6))
958 || (!IS_SNC_OPCODE (code + 8))
959 || (!IS_INC_1SP_OPCODE (code + 10)))
cf88bb9f 960 {
47b0e7ad
NC
961 _bfd_error_handler (_("ip2k relaxer: switch table header corrupt."));
962 return FALSE;
cf88bb9f
NC
963 }
964
47b0e7ad
NC
965 /* Delete first 3 opcodes. */
966 if (!ip2k_elf_relax_delete_bytes (abfd, sec, addr + 0, 6))
967 return FALSE;
968
969 *again = TRUE;
970
971 /* Delete all page instructions in table. */
972 while (irel < ireltest)
cf88bb9f 973 {
47b0e7ad
NC
974 if (!ip2k_delete_page_insn (abfd, sec, irel, again, misc))
975 return FALSE;
976 irel += 2;
cf88bb9f
NC
977 }
978
b34976b6 979 return TRUE;
cf88bb9f
NC
980}
981
aecde77e 982/* This function handles relaxation of a section in a specific page. */
cf88bb9f 983
b34976b6 984static bfd_boolean
47b0e7ad
NC
985ip2k_elf_relax_section_page (bfd *abfd,
986 asection *sec,
987 bfd_boolean *again,
988 struct misc *misc,
989 unsigned long page_start,
990 unsigned long page_end)
cf88bb9f
NC
991{
992 Elf_Internal_Rela *irelend = misc->irelbase + sec->reloc_count;
993 Elf_Internal_Rela *irel;
aecde77e
NC
994 int switch_table_128;
995 int switch_table_256;
68ffbac6 996
4cc11e76 997 /* Walk thru the section looking for relaxation opportunities. */
cf88bb9f
NC
998 for (irel = misc->irelbase; irel < irelend; irel++)
999 {
aecde77e
NC
1000 if (ELF32_R_TYPE (irel->r_info) != (int) R_IP2K_PAGE3)
1001 /* Ignore non page instructions. */
1002 continue;
cf88bb9f 1003
aecde77e
NC
1004 if (BASEADDR (sec) + irel->r_offset < page_start)
1005 /* Ignore page instructions on earlier page - they have
1006 already been processed. Remember that there is code flow
1007 that crosses a page boundary. */
1008 continue;
cf88bb9f 1009
aecde77e
NC
1010 if (BASEADDR (sec) + irel->r_offset > page_end)
1011 /* Flow beyond end of page => nothing more to do for this page. */
1012 return TRUE;
cf88bb9f 1013
aecde77e
NC
1014 /* Detect switch tables. */
1015 switch_table_128 = ip2k_is_switch_table_128 (abfd, sec, irel->r_offset, misc->contents);
1016 switch_table_256 = ip2k_is_switch_table_256 (abfd, sec, irel->r_offset, misc->contents);
cf88bb9f 1017
aecde77e
NC
1018 if ((switch_table_128 > 0) || (switch_table_256 > 0))
1019 /* If the index is greater than 0 then it has already been processed. */
1020 continue;
cf88bb9f 1021
aecde77e 1022 if (switch_table_128 == 0)
cf88bb9f 1023 {
aecde77e
NC
1024 if (!ip2k_relax_switch_table_128 (abfd, sec, irel, again, misc))
1025 return FALSE;
1026
1027 continue;
cf88bb9f 1028 }
cf88bb9f 1029
aecde77e
NC
1030 if (switch_table_256 == 0)
1031 {
1032 if (!ip2k_relax_switch_table_256 (abfd, sec, irel, again, misc))
1033 return FALSE;
1034
1035 continue;
1036 }
b34976b6 1037
aecde77e
NC
1038 /* Simple relax. */
1039 if (ip2k_test_page_insn (abfd, sec, irel, misc))
1040 {
1041 if (!ip2k_delete_page_insn (abfd, sec, irel, again, misc))
1042 return FALSE;
1043
1044 continue;
1045 }
1046 }
cf88bb9f 1047
b34976b6 1048 return TRUE;
cf88bb9f
NC
1049}
1050
47b0e7ad 1051/* This function handles relaxing for the ip2k.
aecde77e 1052
47b0e7ad
NC
1053 Principle: Start with the first page and remove page instructions that
1054 are not require on this first page. By removing page instructions more
1055 code will fit into this page - repeat until nothing more can be achieved
1056 for this page. Move on to the next page.
aecde77e 1057
47b0e7ad
NC
1058 Processing the pages one at a time from the lowest page allows a removal
1059 only policy to be used - pages can be removed but are never reinserted. */
aecde77e 1060
47b0e7ad
NC
1061static bfd_boolean
1062ip2k_elf_relax_section (bfd *abfd,
1063 asection *sec,
1064 struct bfd_link_info *link_info,
1065 bfd_boolean *again)
1066{
1067 Elf_Internal_Shdr *symtab_hdr;
1068 Elf_Internal_Rela *internal_relocs;
1069 bfd_byte *contents = NULL;
1070 Elf_Internal_Sym *isymbuf = NULL;
1071 static asection * first_section = NULL;
1072 static unsigned long search_addr;
1073 static unsigned long page_start = 0;
1074 static unsigned long page_end = 0;
1075 static unsigned int pass = 0;
1076 static bfd_boolean new_pass = FALSE;
1077 static bfd_boolean changed = FALSE;
1078 struct misc misc;
aecde77e 1079
47b0e7ad
NC
1080 /* Assume nothing changes. */
1081 *again = FALSE;
aecde77e 1082
47b0e7ad
NC
1083 if (first_section == NULL)
1084 {
1085 ip2k_relaxed = TRUE;
1086 first_section = sec;
1087 }
aecde77e 1088
47b0e7ad
NC
1089 if (first_section == sec)
1090 {
1091 pass++;
1092 new_pass = TRUE;
1093 }
aecde77e 1094
47b0e7ad
NC
1095 /* We don't have to do anything for a relocatable link,
1096 if this section does not have relocs, or if this is
1097 not a code section. */
0e1862bb 1098 if (bfd_link_relocatable (link_info)
47b0e7ad
NC
1099 || (sec->flags & SEC_RELOC) == 0
1100 || sec->reloc_count == 0
1101 || (sec->flags & SEC_CODE) == 0)
1102 return TRUE;
aecde77e 1103
47b0e7ad 1104 symtab_hdr = &elf_tdata (abfd)->symtab_hdr;
aecde77e 1105
47b0e7ad
NC
1106 internal_relocs = _bfd_elf_link_read_relocs (abfd, sec, NULL, NULL,
1107 link_info->keep_memory);
1108 if (internal_relocs == NULL)
1109 goto error_return;
aecde77e 1110
47b0e7ad
NC
1111 /* Get section contents cached copy if it exists. */
1112 if (contents == NULL)
cf88bb9f 1113 {
47b0e7ad
NC
1114 /* Get cached copy if it exists. */
1115 if (elf_section_data (sec)->this_hdr.contents != NULL)
1116 contents = elf_section_data (sec)->this_hdr.contents;
1117 else
1118 {
1119 /* Go get them off disk. */
1120 if (!bfd_malloc_and_get_section (abfd, sec, &contents))
1121 goto error_return;
1122 }
cf88bb9f
NC
1123 }
1124
47b0e7ad
NC
1125 /* Read this BFD's symbols cached copy if it exists. */
1126 if (isymbuf == NULL && symtab_hdr->sh_info != 0)
cf88bb9f 1127 {
47b0e7ad
NC
1128 isymbuf = (Elf_Internal_Sym *) symtab_hdr->contents;
1129 if (isymbuf == NULL)
1130 isymbuf = bfd_elf_get_elf_syms (abfd, symtab_hdr,
1131 symtab_hdr->sh_info, 0,
1132 NULL, NULL, NULL);
1133 if (isymbuf == NULL)
1134 goto error_return;
1135 }
aecde77e 1136
47b0e7ad
NC
1137 misc.symtab_hdr = symtab_hdr;
1138 misc.isymbuf = isymbuf;
1139 misc.irelbase = internal_relocs;
1140 misc.contents = contents;
1141
1142 /* This is where all the relaxation actually get done. */
1143 if ((pass == 1) || (new_pass && !changed))
1144 {
1145 /* On the first pass we simply search for the lowest page that
07d6d2b8
AM
1146 we havn't relaxed yet. Note that the pass count is reset
1147 each time a page is complete in order to move on to the next page.
1148 If we can't find any more pages then we are finished. */
47b0e7ad 1149 if (new_pass)
fd13ed0c 1150 {
47b0e7ad
NC
1151 pass = 1;
1152 new_pass = FALSE;
1153 changed = TRUE; /* Pre-initialize to break out of pass 1. */
1154 search_addr = 0xFFFFFFFF;
1155 }
1156
1157 if ((BASEADDR (sec) + sec->size < search_addr)
1158 && (BASEADDR (sec) + sec->size > page_end))
1159 {
1160 if (BASEADDR (sec) <= page_end)
1161 search_addr = page_end + 1;
1162 else
1163 search_addr = BASEADDR (sec);
1164
1165 /* Found a page => more work to do. */
1166 *again = TRUE;
fd13ed0c 1167 }
cf88bb9f 1168 }
47b0e7ad
NC
1169 else
1170 {
1171 if (new_pass)
1172 {
1173 new_pass = FALSE;
1174 changed = FALSE;
1175 page_start = PAGENO (search_addr);
1176 page_end = page_start | 0x00003FFF;
1177 }
cf88bb9f 1178
47b0e7ad
NC
1179 /* Only process sections in range. */
1180 if ((BASEADDR (sec) + sec->size >= page_start)
1181 && (BASEADDR (sec) <= page_end))
1182 {
07d6d2b8 1183 if (!ip2k_elf_relax_section_page (abfd, sec, &changed, &misc, page_start, page_end))
47b0e7ad
NC
1184 return FALSE;
1185 }
1186 *again = TRUE;
1187 }
cf88bb9f 1188
47b0e7ad 1189 /* Perform some house keeping after relaxing the section. */
cf88bb9f 1190
47b0e7ad
NC
1191 if (isymbuf != NULL
1192 && symtab_hdr->contents != (unsigned char *) isymbuf)
1193 {
1194 if (! link_info->keep_memory)
1195 free (isymbuf);
1196 else
1197 symtab_hdr->contents = (unsigned char *) isymbuf;
1198 }
cf88bb9f 1199
47b0e7ad
NC
1200 if (contents != NULL
1201 && elf_section_data (sec)->this_hdr.contents != contents)
1202 {
1203 if (! link_info->keep_memory)
1204 free (contents);
1205 else
1206 {
1207 /* Cache the section contents for elf_link_input_bfd. */
1208 elf_section_data (sec)->this_hdr.contents = contents;
1209 }
1210 }
cf88bb9f 1211
c9594989 1212 if (elf_section_data (sec)->relocs != internal_relocs)
47b0e7ad 1213 free (internal_relocs);
cf88bb9f 1214
b34976b6 1215 return TRUE;
cf88bb9f 1216
47b0e7ad 1217 error_return:
c9594989 1218 if (symtab_hdr->contents != (unsigned char *) isymbuf)
47b0e7ad 1219 free (isymbuf);
c9594989 1220 if (elf_section_data (sec)->this_hdr.contents != contents)
47b0e7ad 1221 free (contents);
c9594989 1222 if (elf_section_data (sec)->relocs != internal_relocs)
47b0e7ad
NC
1223 free (internal_relocs);
1224 return FALSE;
1225}
cf88bb9f
NC
1226
1227/* Set the howto pointer for a IP2K ELF reloc. */
1228
f3185997 1229static bfd_boolean
0aa13fee 1230ip2k_info_to_howto_rela (bfd * abfd,
47b0e7ad
NC
1231 arelent * cache_ptr,
1232 Elf_Internal_Rela * dst)
cf88bb9f
NC
1233{
1234 unsigned int r_type;
1235
1236 r_type = ELF32_R_TYPE (dst->r_info);
5860e3f8
NC
1237 if (r_type >= (unsigned int) R_IP2K_max)
1238 {
695344c0 1239 /* xgettext:c-format */
0aa13fee
AM
1240 _bfd_error_handler (_("%pB: unsupported relocation type %#x"),
1241 abfd, r_type);
f3185997
NC
1242 bfd_set_error (bfd_error_bad_value);
1243 return FALSE;
5860e3f8 1244 }
47b0e7ad 1245 cache_ptr->howto = & ip2k_elf_howto_table [r_type];
f3185997 1246 return TRUE;
cf88bb9f
NC
1247}
1248
1249/* Perform a single relocation.
1250 By default we use the standard BFD routines. */
1251
1252static bfd_reloc_status_type
47b0e7ad 1253ip2k_final_link_relocate (reloc_howto_type * howto,
07d6d2b8
AM
1254 bfd * input_bfd,
1255 asection * input_section,
1256 bfd_byte * contents,
47b0e7ad 1257 Elf_Internal_Rela * rel,
07d6d2b8 1258 bfd_vma relocation)
cf88bb9f 1259{
aecde77e 1260 static bfd_vma page_addr = 0;
cf88bb9f 1261
aecde77e 1262 bfd_reloc_status_type r = bfd_reloc_ok;
cf88bb9f
NC
1263 switch (howto->type)
1264 {
1265 /* Handle data space relocations. */
1266 case R_IP2K_FR9:
1267 case R_IP2K_BANK:
1268 if ((relocation & IP2K_DATA_MASK) == IP2K_DATA_VALUE)
1269 relocation &= ~IP2K_DATA_MASK;
1270 else
1271 r = bfd_reloc_notsupported;
1272 break;
1273
1274 case R_IP2K_LO8DATA:
1275 case R_IP2K_HI8DATA:
1276 case R_IP2K_EX8DATA:
1277 break;
1278
1279 /* Handle insn space relocations. */
cf88bb9f 1280 case R_IP2K_PAGE3:
aecde77e
NC
1281 page_addr = BASEADDR (input_section) + rel->r_offset;
1282 if ((relocation & IP2K_INSN_MASK) == IP2K_INSN_VALUE)
1283 relocation &= ~IP2K_INSN_MASK;
1284 else
1285 r = bfd_reloc_notsupported;
1286 break;
1287
1288 case R_IP2K_ADDR16CJP:
1289 if (BASEADDR (input_section) + rel->r_offset != page_addr + 2)
1290 {
4cc11e76 1291 /* No preceding page instruction, verify that it isn't needed. */
aecde77e
NC
1292 if (PAGENO (relocation + rel->r_addend) !=
1293 ip2k_nominal_page_bits (input_bfd, input_section,
07d6d2b8 1294 rel->r_offset, contents))
695344c0 1295 /* xgettext:c-format */
2dcf00ce
AM
1296 _bfd_error_handler
1297 (_("ip2k linker: missing page instruction "
1298 "at %#" PRIx64 " (dest = %#" PRIx64 ")"),
1299 (uint64_t) (BASEADDR (input_section) + rel->r_offset),
1300 (uint64_t) (relocation + rel->r_addend));
07d6d2b8 1301 }
aecde77e 1302 else if (ip2k_relaxed)
07d6d2b8
AM
1303 {
1304 /* Preceding page instruction. Verify that the page instruction is
1305 really needed. One reason for the relaxation to miss a page is if
1306 the section is not marked as executable. */
47b0e7ad
NC
1307 if (!ip2k_is_switch_table_128 (input_bfd, input_section,
1308 rel->r_offset - 2, contents)
1309 && !ip2k_is_switch_table_256 (input_bfd, input_section,
1310 rel->r_offset - 2, contents)
1311 && (PAGENO (relocation + rel->r_addend) ==
1312 ip2k_nominal_page_bits (input_bfd, input_section,
1313 rel->r_offset - 2, contents)))
695344c0 1314 /* xgettext:c-format */
2dcf00ce
AM
1315 _bfd_error_handler
1316 (_("ip2k linker: redundant page instruction "
1317 "at %#" PRIx64 " (dest = %#" PRIx64 ")"),
1318 (uint64_t) page_addr,
1319 (uint64_t) (relocation + rel->r_addend));
07d6d2b8 1320 }
aecde77e
NC
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
NC
1401
1402 symtab_hdr = & elf_tdata (input_bfd)->symtab_hdr;
1403 sym_hashes = elf_sym_hashes (input_bfd);
1404 relend = relocs + input_section->reloc_count;
1405
1406 for (rel = relocs; rel < relend; rel ++)
1407 {
07d6d2b8
AM
1408 reloc_howto_type * howto;
1409 unsigned long r_symndx;
1410 Elf_Internal_Sym * sym;
1411 asection * sec;
cf88bb9f 1412 struct elf_link_hash_entry * h;
07d6d2b8
AM
1413 bfd_vma relocation;
1414 bfd_reloc_status_type r;
1415 const char * name = NULL;
1416 int r_type;
b34976b6 1417
cf88bb9f 1418 r_type = ELF32_R_TYPE (rel->r_info);
cf88bb9f 1419 r_symndx = ELF32_R_SYM (rel->r_info);
c7e2358a 1420 howto = ip2k_elf_howto_table + r_type;
cf88bb9f
NC
1421 h = NULL;
1422 sym = NULL;
1423 sec = NULL;
b34976b6 1424
cf88bb9f
NC
1425 if (r_symndx < symtab_hdr->sh_info)
1426 {
1427 sym = local_syms + r_symndx;
1428 sec = local_sections [r_symndx];
1429 relocation = BASEADDR (sec) + sym->st_value;
b34976b6 1430
cf88bb9f
NC
1431 name = bfd_elf_string_from_elf_section
1432 (input_bfd, symtab_hdr->sh_link, sym->st_name);
fd361982 1433 name = name == NULL ? bfd_section_name (sec) : name;
cf88bb9f
NC
1434 }
1435 else
1436 {
62d887d4 1437 bfd_boolean warned, ignored;
560e09e9 1438 bfd_boolean unresolved_reloc;
b34976b6 1439
b2a8e766
AM
1440 RELOC_FOR_GLOBAL_SYMBOL (info, input_bfd, input_section, rel,
1441 r_symndx, symtab_hdr, sym_hashes,
1442 h, sec, relocation,
62d887d4 1443 unresolved_reloc, warned, ignored);
cf88bb9f
NC
1444
1445 name = h->root.root.string;
cf88bb9f
NC
1446 }
1447
dbaa2011 1448 if (sec != NULL && discarded_section (sec))
e4067dbb 1449 RELOC_AGAINST_DISCARDED_SECTION (info, input_bfd, input_section,
545fd46b 1450 rel, 1, relend, howto, 0, contents);
ab96bf03 1451
0e1862bb 1452 if (bfd_link_relocatable (info))
ab96bf03
AM
1453 continue;
1454
cf88bb9f
NC
1455 /* Finally, the sole IP2K-specific part. */
1456 r = ip2k_final_link_relocate (howto, input_bfd, input_section,
1457 contents, rel, relocation);
1458
1459 if (r != bfd_reloc_ok)
1460 {
47b0e7ad 1461 const char * msg = NULL;
cf88bb9f
NC
1462
1463 switch (r)
1464 {
1465 case bfd_reloc_overflow:
1a72702b 1466 (*info->callbacks->reloc_overflow)
dfeffb9f
L
1467 (info, (h ? &h->root : NULL), name, howto->name,
1468 (bfd_vma) 0, input_bfd, input_section, rel->r_offset);
cf88bb9f 1469 break;
b34976b6 1470
cf88bb9f 1471 case bfd_reloc_undefined:
1a72702b 1472 (*info->callbacks->undefined_symbol)
b34976b6 1473 (info, name, input_bfd, input_section, rel->r_offset, TRUE);
cf88bb9f 1474 break;
b34976b6 1475
cf88bb9f
NC
1476 case bfd_reloc_outofrange:
1477 msg = _("internal error: out of range error");
1478 break;
1479
1480 /* This is how ip2k_final_link_relocate tells us of a non-kosher
07d6d2b8 1481 reference between insn & data address spaces. */
cf88bb9f 1482 case bfd_reloc_notsupported:
07d6d2b8
AM
1483 if (sym != NULL) /* Only if it's not an unresolved symbol. */
1484 msg = _("unsupported relocation between data/insn address spaces");
cf88bb9f
NC
1485 break;
1486
1487 case bfd_reloc_dangerous:
1488 msg = _("internal error: dangerous relocation");
1489 break;
1490
1491 default:
1492 msg = _("internal error: unknown error");
1493 break;
1494 }
1495
1496 if (msg)
1a72702b
AM
1497 (*info->callbacks->warning) (info, msg, name, input_bfd,
1498 input_section, rel->r_offset);
cf88bb9f
NC
1499 }
1500 }
1501
b34976b6 1502 return TRUE;
cf88bb9f
NC
1503}
1504
6d00b590 1505#define TARGET_BIG_SYM ip2k_elf32_vec
cf88bb9f
NC
1506#define TARGET_BIG_NAME "elf32-ip2k"
1507
1508#define ELF_ARCH bfd_arch_ip2k
1509#define ELF_MACHINE_CODE EM_IP2K
0d09fec6 1510#define ELF_MACHINE_ALT1 EM_IP2K_OLD
aecde77e 1511#define ELF_MAXPAGESIZE 1 /* No pages on the IP2K. */
cf88bb9f 1512
cf88bb9f
NC
1513#define elf_info_to_howto_rel NULL
1514#define elf_info_to_howto ip2k_info_to_howto_rela
1515
07d6d2b8 1516#define elf_backend_can_gc_sections 1
f0fe0e16 1517#define elf_backend_rela_normal 1
cf88bb9f
NC
1518#define elf_backend_relocate_section ip2k_elf_relocate_section
1519
1520#define elf_symbol_leading_char '_'
1521#define bfd_elf32_bfd_reloc_type_lookup ip2k_reloc_type_lookup
157090f7 1522#define bfd_elf32_bfd_reloc_name_lookup ip2k_reloc_name_lookup
cf88bb9f
NC
1523#define bfd_elf32_bfd_relax_section ip2k_elf_relax_section
1524
cf88bb9f 1525#include "elf32-target.h"
This page took 0.964865 seconds and 4 git commands to generate.