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