elf32-ip2k.c revision 1.7 1 1.1 christos /* Ubicom IP2xxx specific support for 32-bit ELF
2 1.7 christos Copyright (C) 2000-2017 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.1 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.1 christos static bfd_boolean 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.1 christos HOWTO(t, /* type */ \
130 1.1 christos rs, /* rightshift */ \
131 1.1 christos s, /* size (0 = byte, 1 = short, 2 = long) */ \
132 1.1 christos bs, /* bitsize */ \
133 1.1 christos pr, /* pc_relative */ \
134 1.1 christos bp, /* bitpos */ \
135 1.1 christos complain_overflow_dont,/* complain_on_overflow */ \
136 1.1 christos bfd_elf_generic_reloc,/* special_function */ \
137 1.1 christos name, /* name */ \
138 1.1 christos FALSE, /* partial_inplace */ \
139 1.1 christos sm, /* src_mask */ \
140 1.1 christos dm, /* dst_mask */ \
141 1.1 christos pr) /* pcrel_offset */
142 1.1 christos
143 1.1 christos /* This reloc does nothing. */
144 1.5 christos IP2K_HOWTO (R_IP2K_NONE, 0,3,0, FALSE, 0, "R_IP2K_NONE", 0, 0),
145 1.1 christos /* A 16 bit absolute relocation. */
146 1.1 christos IP2K_HOWTO (R_IP2K_16, 0,1,16, FALSE, 0, "R_IP2K_16", 0, 0xffff),
147 1.1 christos /* A 32 bit absolute relocation. */
148 1.1 christos IP2K_HOWTO (R_IP2K_32, 0,2,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.1 christos IP2K_HOWTO (R_IP2K_FR9, 0,1,9, FALSE, 0, "R_IP2K_FR9", 0, 0x00ff),
151 1.1 christos /* A 4-bit data relocation. */
152 1.1 christos IP2K_HOWTO (R_IP2K_BANK, 8,1,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.1 christos IP2K_HOWTO (R_IP2K_ADDR16CJP, 1,1,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.1 christos IP2K_HOWTO (R_IP2K_PAGE3, 14,1,3, FALSE, 0, "R_IP2K_PAGE3", 0, 0x0007),
157 1.1 christos /* Two 8-bit data relocations. */
158 1.1 christos IP2K_HOWTO (R_IP2K_LO8DATA, 0,1,8, FALSE, 0, "R_IP2K_LO8DATA", 0, 0x00ff),
159 1.1 christos IP2K_HOWTO (R_IP2K_HI8DATA, 8,1,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.1 christos IP2K_HOWTO (R_IP2K_LO8INSN, 1,1,8, FALSE, 0, "R_IP2K_LO8INSN", 0, 0x00ff),
162 1.1 christos IP2K_HOWTO (R_IP2K_HI8INSN, 9,1,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.1 christos IP2K_HOWTO (R_IP2K_PC_SKIP, 1,1,1, FALSE, 12, "R_IP2K_PC_SKIP", 0xfffe, 0x1000),
166 1.1 christos /* 16 bit word address. */
167 1.1 christos IP2K_HOWTO (R_IP2K_TEXT, 1,1,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.1 christos IP2K_HOWTO (R_IP2K_FR_OFFSET, 0,1,9, FALSE, 0, "R_IP2K_FR_OFFSET", 0x180, 0x007f),
170 1.1 christos /* Bits 23:16 of an address. */
171 1.1 christos IP2K_HOWTO (R_IP2K_EX8DATA, 16,1,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.1 christos static bfd_boolean
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.1 christos return TRUE;
259 1.1 christos
260 1.1 christos opcodes ++;
261 1.1 christos }
262 1.1 christos
263 1.1 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.1 christos sc
318 1.1 christos page $nnn0
319 1.1 christos jmp $nnn0
320 1.1 christos add w,wreg
321 1.1 christos add pcl,w
322 1.1 christos addr=>
323 1.1 christos page $nnn1
324 1.1 christos jmp $nnn1
325 1.1 christos page $nnn2
326 1.1 christos jmp $nnn2
327 1.1 christos ...
328 1.1 christos page $nnnN
329 1.1 christos jmp $nnnN
330 1.1 christos
331 1.1 christos After relaxation.
332 1.1 christos sc
333 1.1 christos page $nnn0
334 1.1 christos jmp $nnn0
335 1.1 christos add pcl,w
336 1.1 christos addr=>
337 1.1 christos jmp $nnn1
338 1.1 christos jmp $nnn2
339 1.1 christos ...
340 1.1 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.1 christos push %lo8insn(label) ; Push address of table
388 1.1 christos push %hi8insn(label)
389 1.1 christos add w,wreg ; index*2 => offset
390 1.1 christos snc ; CARRY SET?
391 1.1 christos inc 1(sp) ; Propagate MSB into table address
392 1.1 christos add 2(sp),w ; Add low bits of offset to table address
393 1.1 christos snc ; and handle any carry-out
394 1.1 christos inc 1(sp)
395 1.1 christos addr=>
396 1.1 christos page __indjmp ; Do an indirect jump to that location
397 1.1 christos jmp __indjmp
398 1.1 christos label: ; case dispatch table starts here
399 1.1 christos page $nnn1
400 1.1 christos jmp $nnn1
401 1.1 christos page $nnn2
402 1.1 christos jmp $nnn2
403 1.1 christos ...
404 1.1 christos page $nnnN
405 1.1 christos jmp $nnnN
406 1.1 christos
407 1.1 christos After relaxation.
408 1.1 christos push %lo8insn(label) ; Push address of table
409 1.1 christos push %hi8insn(label)
410 1.1 christos add 2(sp),w ; Add low bits of offset to table address
411 1.1 christos snc ; and handle any carry-out
412 1.1 christos inc 1(sp)
413 1.1 christos addr=>
414 1.1 christos page __indjmp ; Do an indirect jump to that location
415 1.1 christos jmp __indjmp
416 1.1 christos label: ; case dispatch table starts here
417 1.1 christos jmp $nnn1
418 1.1 christos jmp $nnn2
419 1.1 christos ...
420 1.1 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.1 christos {
519 1.1 christos ip2k_get_mem (abfd, contents + addr - 2, 2, code);
520 1.1 christos if (IS_SKIP_OPCODE (code))
521 1.1 christos /* Page is conditional. */
522 1.1 christos continue;
523 1.1 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.1 christos static bfd_boolean
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.1 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.1 christos return FALSE;
553 1.1 christos
554 1.1 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.1 christos {
597 1.1 christos /* Get the value of the symbol referred to by the reloc. */
598 1.1 christos if (ELF32_R_SYM (irel->r_info) < symtab_hdr->sh_info)
599 1.1 christos {
600 1.1 christos asection *sym_sec;
601 1.1 christos
602 1.1 christos /* A local symbol. */
603 1.1 christos isym = isymbuf + ELF32_R_SYM (irel->r_info);
604 1.1 christos sym_sec = bfd_section_from_elf_index (abfd, isym->st_shndx);
605 1.1 christos
606 1.1 christos if (isym->st_shndx == shndx)
607 1.1 christos {
608 1.1 christos bfd_vma baseaddr = BASEADDR (sec);
609 1.1 christos bfd_vma symval = BASEADDR (sym_sec) + isym->st_value
610 1.1 christos + irel->r_addend;
611 1.1 christos
612 1.1 christos if ((baseaddr + addr + noadj) <= symval
613 1.1 christos && symval < (baseaddr + endaddr))
614 1.1 christos irel->r_addend += count;
615 1.1 christos }
616 1.1 christos }
617 1.1 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.1 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.1 christos if (stab)
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.1 christos if (stabcontents != NULL)
642 1.1 christos free (stabcontents);
643 1.1 christos return;
644 1.1 christos }
645 1.1 christos
646 1.1 christos /* We need to remember this. */
647 1.1 christos elf_section_data (stab)->this_hdr.contents = stabcontents;
648 1.1 christos }
649 1.1 christos
650 1.1 christos stabend = stabcontents + stab_size;
651 1.1 christos
652 1.1 christos for (irel = irelbase; irel < irelend; irel++)
653 1.1 christos {
654 1.1 christos if (ELF32_R_TYPE (irel->r_info) != R_IP2K_NONE)
655 1.1 christos {
656 1.1 christos /* Get the value of the symbol referred to by the reloc. */
657 1.1 christos if (ELF32_R_SYM (irel->r_info) < symtab_hdr->sh_info)
658 1.1 christos {
659 1.1 christos asection *sym_sec;
660 1.1 christos
661 1.1 christos /* A local symbol. */
662 1.1 christos isym = isymbuf + ELF32_R_SYM (irel->r_info);
663 1.1 christos sym_sec = bfd_section_from_elf_index (abfd, isym->st_shndx);
664 1.1 christos
665 1.1 christos if (sym_sec == sec)
666 1.1 christos {
667 1.1 christos const char *name;
668 1.1 christos unsigned char type;
669 1.1 christos bfd_vma value;
670 1.1 christos bfd_vma baseaddr = BASEADDR (sec);
671 1.1 christos bfd_vma symval = BASEADDR (sym_sec) + isym->st_value
672 1.1 christos + irel->r_addend;
673 1.1 christos
674 1.1 christos if ((baseaddr + addr) <= symval
675 1.1 christos && symval <= (baseaddr + endaddr))
676 1.1 christos irel->r_addend += count;
677 1.1 christos
678 1.1 christos /* Go hunt up a function and fix its line info if needed. */
679 1.1 christos stabp = stabcontents + irel->r_offset - 8;
680 1.1 christos
681 1.1 christos /* Go pullout the stab entry. */
682 1.1 christos type = bfd_h_get_8 (abfd, stabp + TYPEOFF);
683 1.1 christos value = bfd_h_get_32 (abfd, stabp + VALOFF);
684 1.1 christos
685 1.1 christos name = bfd_get_stab_name (type);
686 1.1 christos
687 1.1 christos if (strcmp (name, "FUN") == 0)
688 1.1 christos {
689 1.1 christos int function_adjusted = 0;
690 1.1 christos
691 1.1 christos if (symval > (baseaddr + addr))
692 1.1 christos /* Not in this function. */
693 1.1 christos continue;
694 1.1 christos
695 1.1 christos /* Hey we got a function hit. */
696 1.1 christos stabp += STABSIZE;
697 1.1 christos for (;stabp < stabend; stabp += STABSIZE)
698 1.1 christos {
699 1.1 christos /* Go pullout the stab entry. */
700 1.1 christos type = bfd_h_get_8 (abfd, stabp + TYPEOFF);
701 1.1 christos value = bfd_h_get_32 (abfd, stabp + VALOFF);
702 1.1 christos
703 1.1 christos name = bfd_get_stab_name (type);
704 1.1 christos
705 1.1 christos if (strcmp (name, "FUN") == 0)
706 1.1 christos {
707 1.1 christos /* Hit another function entry. */
708 1.1 christos if (function_adjusted)
709 1.1 christos {
710 1.1 christos /* Adjust the value. */
711 1.1 christos value += count;
712 1.1 christos
713 1.1 christos /* We need to put it back. */
714 1.1 christos bfd_h_put_32 (abfd, value,stabp + VALOFF);
715 1.1 christos }
716 1.1 christos
717 1.1 christos /* And then bale out. */
718 1.1 christos break;
719 1.1 christos }
720 1.1 christos
721 1.1 christos if (strcmp (name, "SLINE") == 0)
722 1.1 christos {
723 1.1 christos /* Got a line entry. */
724 1.1 christos if ((baseaddr + addr) <= (symval + value))
725 1.1 christos {
726 1.1 christos /* Adjust the line entry. */
727 1.1 christos value += count;
728 1.1 christos
729 1.1 christos /* We need to put it back. */
730 1.1 christos bfd_h_put_32 (abfd, value,stabp + VALOFF);
731 1.1 christos function_adjusted = 1;
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
742 1.1 christos /* When adding an instruction back it is sometimes necessary to move any
743 1.1 christos global or local symbol that was referencing the first instruction of
744 1.1 christos the moved block to refer to the first instruction of the inserted block.
745 1.1 christos
746 1.1 christos For example adding a PAGE instruction before a CALL or JMP requires
747 1.1 christos that any label on the CALL or JMP is moved to the PAGE insn. */
748 1.1 christos addr += noadj;
749 1.1 christos
750 1.1 christos /* Adjust the local symbols defined in this section. */
751 1.1 christos isymend = isymbuf + symtab_hdr->sh_info;
752 1.1 christos for (isym = isymbuf; isym < isymend; isym++)
753 1.1 christos {
754 1.1 christos if (isym->st_shndx == shndx
755 1.1 christos && addr <= isym->st_value
756 1.1 christos && isym->st_value < endaddr)
757 1.1 christos isym->st_value += count;
758 1.1 christos }
759 1.1 christos
760 1.1 christos /* Now adjust the global symbols defined in this section. */
761 1.1 christos symcount = (symtab_hdr->sh_size / sizeof (Elf32_External_Sym)
762 1.1 christos - symtab_hdr->sh_info);
763 1.1 christos sym_hashes = elf_sym_hashes (abfd);
764 1.1 christos end_hashes = sym_hashes + symcount;
765 1.1 christos for (; sym_hashes < end_hashes; sym_hashes++)
766 1.1 christos {
767 1.1 christos struct elf_link_hash_entry *sym_hash = *sym_hashes;
768 1.1 christos
769 1.1 christos if ((sym_hash->root.type == bfd_link_hash_defined
770 1.1 christos || sym_hash->root.type == bfd_link_hash_defweak)
771 1.1 christos && sym_hash->root.u.def.section == sec)
772 1.1 christos {
773 1.1 christos if (addr <= sym_hash->root.u.def.value
774 1.1 christos && sym_hash->root.u.def.value < endaddr)
775 1.1 christos sym_hash->root.u.def.value += count;
776 1.1 christos }
777 1.1 christos }
778 1.1 christos
779 1.1 christos return;
780 1.1 christos }
781 1.1 christos
782 1.1 christos /* Delete some bytes from a section while relaxing. */
783 1.1 christos
784 1.1 christos static bfd_boolean
785 1.1 christos ip2k_elf_relax_delete_bytes (bfd *abfd,
786 1.1 christos asection *sec,
787 1.1 christos bfd_vma addr,
788 1.1 christos int count)
789 1.1 christos {
790 1.1 christos bfd_byte *contents = elf_section_data (sec)->this_hdr.contents;
791 1.1 christos bfd_vma endaddr = sec->size;
792 1.1 christos
793 1.1 christos /* Actually delete the bytes. */
794 1.1 christos memmove (contents + addr, contents + addr + count,
795 1.1 christos endaddr - addr - count);
796 1.1 christos
797 1.1 christos sec->size -= count;
798 1.1 christos
799 1.1 christos adjust_all_relocations (abfd, sec, addr + count, endaddr, -count, 0);
800 1.1 christos return TRUE;
801 1.1 christos }
802 1.1 christos
803 1.1 christos static bfd_boolean
804 1.1 christos ip2k_delete_page_insn (bfd *abfd ATTRIBUTE_UNUSED,
805 1.1 christos asection *sec,
806 1.1 christos Elf_Internal_Rela *irel,
807 1.1 christos bfd_boolean *again,
808 1.1 christos struct misc *misc)
809 1.1 christos {
810 1.1 christos /* Note that we've changed the relocs, section contents, etc. */
811 1.1 christos elf_section_data (sec)->relocs = misc->irelbase;
812 1.1 christos elf_section_data (sec)->this_hdr.contents = misc->contents;
813 1.1 christos misc->symtab_hdr->contents = (bfd_byte *) misc->isymbuf;
814 1.1 christos
815 1.1 christos /* Fix the relocation's type. */
816 1.1 christos irel->r_info = ELF32_R_INFO (ELF32_R_SYM (irel->r_info), R_IP2K_NONE);
817 1.1 christos
818 1.1 christos /* Delete the PAGE insn. */
819 1.1 christos if (!ip2k_elf_relax_delete_bytes (abfd, sec, irel->r_offset, 2))
820 1.1 christos return FALSE;
821 1.1 christos
822 1.1 christos /* Modified => will need to iterate relaxation again. */
823 1.1 christos *again = TRUE;
824 1.1 christos
825 1.1 christos return TRUE;
826 1.1 christos }
827 1.1 christos
828 1.1 christos static bfd_boolean
829 1.1 christos ip2k_relax_switch_table_128 (bfd *abfd ATTRIBUTE_UNUSED,
830 1.1 christos asection *sec,
831 1.1 christos Elf_Internal_Rela *irel,
832 1.1 christos bfd_boolean *again,
833 1.1 christos struct misc *misc)
834 1.1 christos {
835 1.1 christos Elf_Internal_Rela *irelend = misc->irelbase + sec->reloc_count;
836 1.1 christos Elf_Internal_Rela *ireltest = irel;
837 1.1 christos bfd_byte code[4];
838 1.1 christos bfd_vma addr;
839 1.1 christos
840 1.1 christos /* Test all page instructions. */
841 1.1 christos addr = irel->r_offset;
842 1.1 christos while (1)
843 1.1 christos {
844 1.1 christos if (addr + 4 > sec->size)
845 1.1 christos break;
846 1.1 christos
847 1.1 christos ip2k_get_mem (abfd, misc->contents + addr, 4, code);
848 1.1 christos if ((! IS_PAGE_OPCODE (code + 0))
849 1.1 christos || (! IS_JMP_OPCODE (code + 2)))
850 1.1 christos break;
851 1.1 christos
852 1.1 christos /* Validate relocation entry (every entry should have a matching
853 1.1 christos relocation entry). */
854 1.1 christos if (ireltest >= irelend)
855 1.1 christos {
856 1.1 christos _bfd_error_handler (_("ip2k relaxer: switch table without complete matching relocation information."));
857 1.1 christos return FALSE;
858 1.1 christos }
859 1.1 christos
860 1.1 christos if (ireltest->r_offset != addr)
861 1.1 christos {
862 1.1 christos _bfd_error_handler (_("ip2k relaxer: switch table without complete matching relocation information."));
863 1.1 christos return FALSE;
864 1.1 christos }
865 1.1 christos
866 1.1 christos if (! ip2k_test_page_insn (abfd, sec, ireltest, misc))
867 1.1 christos /* Un-removable page insn => nothing can be done. */
868 1.1 christos return TRUE;
869 1.1 christos
870 1.1 christos addr += 4;
871 1.1 christos ireltest += 2;
872 1.1 christos }
873 1.1 christos
874 1.1 christos /* Relaxable. Adjust table header. */
875 1.1 christos ip2k_get_mem (abfd, misc->contents + irel->r_offset - 4, 4, code);
876 1.1 christos if ((! IS_ADD_W_WREG_OPCODE (code + 0))
877 1.1 christos || (! IS_ADD_PCL_W_OPCODE (code + 2)))
878 1.1 christos {
879 1.1 christos _bfd_error_handler (_("ip2k relaxer: switch table header corrupt."));
880 1.1 christos return FALSE;
881 1.1 christos }
882 1.1 christos
883 1.1 christos if (!ip2k_elf_relax_delete_bytes (abfd, sec, irel->r_offset - 4, 2))
884 1.1 christos return FALSE;
885 1.1 christos
886 1.1 christos *again = TRUE;
887 1.1 christos
888 1.1 christos /* Delete all page instructions in table. */
889 1.1 christos while (irel < ireltest)
890 1.1 christos {
891 1.1 christos if (!ip2k_delete_page_insn (abfd, sec, irel, again, misc))
892 1.1 christos return FALSE;
893 1.1 christos irel += 2;
894 1.1 christos }
895 1.1 christos
896 1.1 christos return TRUE;
897 1.1 christos }
898 1.1 christos
899 1.1 christos static bfd_boolean
900 1.1 christos ip2k_relax_switch_table_256 (bfd *abfd ATTRIBUTE_UNUSED,
901 1.1 christos asection *sec,
902 1.1 christos Elf_Internal_Rela *irel,
903 1.1 christos bfd_boolean *again,
904 1.1 christos struct misc *misc)
905 1.1 christos {
906 1.1 christos Elf_Internal_Rela *irelend = misc->irelbase + sec->reloc_count;
907 1.1 christos Elf_Internal_Rela *ireltest = irel;
908 1.1 christos bfd_byte code[12];
909 1.1 christos bfd_vma addr;
910 1.1 christos
911 1.1 christos /* Test all page instructions. */
912 1.1 christos addr = irel->r_offset;
913 1.1 christos
914 1.1 christos while (1)
915 1.1 christos {
916 1.1 christos if (addr + 4 > sec->size)
917 1.1 christos break;
918 1.1 christos
919 1.1 christos ip2k_get_mem (abfd, misc->contents + addr, 4, code);
920 1.1 christos
921 1.1 christos if ((! IS_PAGE_OPCODE (code + 0))
922 1.1 christos || (! IS_JMP_OPCODE (code + 2)))
923 1.1 christos break;
924 1.1 christos
925 1.1 christos /* Validate relocation entry (every entry should have a matching
926 1.1 christos relocation entry). */
927 1.1 christos if (ireltest >= irelend)
928 1.1 christos {
929 1.1 christos _bfd_error_handler (_("ip2k relaxer: switch table without complete matching relocation information."));
930 1.1 christos return FALSE;
931 1.1 christos }
932 1.1 christos
933 1.1 christos if (ireltest->r_offset != addr)
934 1.1 christos {
935 1.1 christos _bfd_error_handler (_("ip2k relaxer: switch table without complete matching relocation information."));
936 1.1 christos return FALSE;
937 1.1 christos }
938 1.1 christos
939 1.1 christos if (!ip2k_test_page_insn (abfd, sec, ireltest, misc))
940 1.1 christos /* Un-removable page insn => nothing can be done. */
941 1.1 christos return TRUE;
942 1.1 christos
943 1.1 christos addr += 4;
944 1.1 christos ireltest += 2;
945 1.1 christos }
946 1.1 christos
947 1.1 christos /* Relaxable. Adjust table header. */
948 1.1 christos ip2k_get_mem (abfd, misc->contents + irel->r_offset - 4, 2, code);
949 1.1 christos if (IS_PAGE_OPCODE (code))
950 1.1 christos addr = irel->r_offset - 16;
951 1.1 christos else
952 1.1 christos addr = irel->r_offset - 14;
953 1.1 christos
954 1.1 christos ip2k_get_mem (abfd, misc->contents + addr, 12, code);
955 1.1 christos if ((!IS_ADD_W_WREG_OPCODE (code + 0))
956 1.1 christos || (!IS_SNC_OPCODE (code + 2))
957 1.1 christos || (!IS_INC_1SP_OPCODE (code + 4))
958 1.1 christos || (!IS_ADD_2SP_W_OPCODE (code + 6))
959 1.1 christos || (!IS_SNC_OPCODE (code + 8))
960 1.1 christos || (!IS_INC_1SP_OPCODE (code + 10)))
961 1.1 christos {
962 1.1 christos _bfd_error_handler (_("ip2k relaxer: switch table header corrupt."));
963 1.1 christos return FALSE;
964 1.1 christos }
965 1.1 christos
966 1.1 christos /* Delete first 3 opcodes. */
967 1.1 christos if (!ip2k_elf_relax_delete_bytes (abfd, sec, addr + 0, 6))
968 1.1 christos return FALSE;
969 1.1 christos
970 1.1 christos *again = TRUE;
971 1.1 christos
972 1.1 christos /* Delete all page instructions in table. */
973 1.1 christos while (irel < ireltest)
974 1.1 christos {
975 1.1 christos if (!ip2k_delete_page_insn (abfd, sec, irel, again, misc))
976 1.1 christos return FALSE;
977 1.1 christos irel += 2;
978 1.1 christos }
979 1.1 christos
980 1.1 christos return TRUE;
981 1.1 christos }
982 1.1 christos
983 1.1 christos /* This function handles relaxation of a section in a specific page. */
984 1.1 christos
985 1.1 christos static bfd_boolean
986 1.1 christos ip2k_elf_relax_section_page (bfd *abfd,
987 1.1 christos asection *sec,
988 1.1 christos bfd_boolean *again,
989 1.1 christos struct misc *misc,
990 1.1 christos unsigned long page_start,
991 1.1 christos unsigned long page_end)
992 1.1 christos {
993 1.1 christos Elf_Internal_Rela *irelend = misc->irelbase + sec->reloc_count;
994 1.1 christos Elf_Internal_Rela *irel;
995 1.1 christos int switch_table_128;
996 1.1 christos int switch_table_256;
997 1.1 christos
998 1.1 christos /* Walk thru the section looking for relaxation opportunities. */
999 1.1 christos for (irel = misc->irelbase; irel < irelend; irel++)
1000 1.1 christos {
1001 1.1 christos if (ELF32_R_TYPE (irel->r_info) != (int) R_IP2K_PAGE3)
1002 1.1 christos /* Ignore non page instructions. */
1003 1.1 christos continue;
1004 1.1 christos
1005 1.1 christos if (BASEADDR (sec) + irel->r_offset < page_start)
1006 1.1 christos /* Ignore page instructions on earlier page - they have
1007 1.1 christos already been processed. Remember that there is code flow
1008 1.1 christos that crosses a page boundary. */
1009 1.1 christos continue;
1010 1.1 christos
1011 1.1 christos if (BASEADDR (sec) + irel->r_offset > page_end)
1012 1.1 christos /* Flow beyond end of page => nothing more to do for this page. */
1013 1.1 christos return TRUE;
1014 1.1 christos
1015 1.1 christos /* Detect switch tables. */
1016 1.1 christos switch_table_128 = ip2k_is_switch_table_128 (abfd, sec, irel->r_offset, misc->contents);
1017 1.1 christos switch_table_256 = ip2k_is_switch_table_256 (abfd, sec, irel->r_offset, misc->contents);
1018 1.1 christos
1019 1.1 christos if ((switch_table_128 > 0) || (switch_table_256 > 0))
1020 1.1 christos /* If the index is greater than 0 then it has already been processed. */
1021 1.1 christos continue;
1022 1.1 christos
1023 1.1 christos if (switch_table_128 == 0)
1024 1.1 christos {
1025 1.1 christos if (!ip2k_relax_switch_table_128 (abfd, sec, irel, again, misc))
1026 1.1 christos return FALSE;
1027 1.1 christos
1028 1.1 christos continue;
1029 1.1 christos }
1030 1.1 christos
1031 1.1 christos if (switch_table_256 == 0)
1032 1.1 christos {
1033 1.1 christos if (!ip2k_relax_switch_table_256 (abfd, sec, irel, again, misc))
1034 1.1 christos return FALSE;
1035 1.1 christos
1036 1.1 christos continue;
1037 1.1 christos }
1038 1.1 christos
1039 1.1 christos /* Simple relax. */
1040 1.1 christos if (ip2k_test_page_insn (abfd, sec, irel, misc))
1041 1.1 christos {
1042 1.1 christos if (!ip2k_delete_page_insn (abfd, sec, irel, again, misc))
1043 1.1 christos return FALSE;
1044 1.1 christos
1045 1.1 christos continue;
1046 1.1 christos }
1047 1.1 christos }
1048 1.1 christos
1049 1.1 christos return TRUE;
1050 1.1 christos }
1051 1.1 christos
1052 1.1 christos /* This function handles relaxing for the ip2k.
1053 1.1 christos
1054 1.1 christos Principle: Start with the first page and remove page instructions that
1055 1.1 christos are not require on this first page. By removing page instructions more
1056 1.1 christos code will fit into this page - repeat until nothing more can be achieved
1057 1.1 christos for this page. Move on to the next page.
1058 1.1 christos
1059 1.1 christos Processing the pages one at a time from the lowest page allows a removal
1060 1.1 christos only policy to be used - pages can be removed but are never reinserted. */
1061 1.1 christos
1062 1.1 christos static bfd_boolean
1063 1.1 christos ip2k_elf_relax_section (bfd *abfd,
1064 1.1 christos asection *sec,
1065 1.1 christos struct bfd_link_info *link_info,
1066 1.1 christos bfd_boolean *again)
1067 1.1 christos {
1068 1.1 christos Elf_Internal_Shdr *symtab_hdr;
1069 1.1 christos Elf_Internal_Rela *internal_relocs;
1070 1.1 christos bfd_byte *contents = NULL;
1071 1.1 christos Elf_Internal_Sym *isymbuf = NULL;
1072 1.1 christos static asection * first_section = NULL;
1073 1.1 christos static unsigned long search_addr;
1074 1.1 christos static unsigned long page_start = 0;
1075 1.1 christos static unsigned long page_end = 0;
1076 1.1 christos static unsigned int pass = 0;
1077 1.1 christos static bfd_boolean new_pass = FALSE;
1078 1.1 christos static bfd_boolean changed = FALSE;
1079 1.1 christos struct misc misc;
1080 1.1 christos
1081 1.1 christos /* Assume nothing changes. */
1082 1.1 christos *again = FALSE;
1083 1.1 christos
1084 1.1 christos if (first_section == NULL)
1085 1.1 christos {
1086 1.1 christos ip2k_relaxed = TRUE;
1087 1.1 christos first_section = sec;
1088 1.1 christos }
1089 1.1 christos
1090 1.1 christos if (first_section == sec)
1091 1.1 christos {
1092 1.1 christos pass++;
1093 1.1 christos new_pass = TRUE;
1094 1.1 christos }
1095 1.1 christos
1096 1.1 christos /* We don't have to do anything for a relocatable link,
1097 1.1 christos if this section does not have relocs, or if this is
1098 1.1 christos not a code section. */
1099 1.6 christos if (bfd_link_relocatable (link_info)
1100 1.1 christos || (sec->flags & SEC_RELOC) == 0
1101 1.1 christos || sec->reloc_count == 0
1102 1.1 christos || (sec->flags & SEC_CODE) == 0)
1103 1.1 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.1 christos we havn't relaxed yet. Note that the pass count is reset
1148 1.1 christos each time a page is complete in order to move on to the next page.
1149 1.1 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.1 christos new_pass = FALSE;
1154 1.1 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.1 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.1 christos new_pass = FALSE;
1175 1.1 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.1 christos if (!ip2k_elf_relax_section_page (abfd, sec, &changed, &misc, page_start, page_end))
1185 1.1 christos return FALSE;
1186 1.1 christos }
1187 1.1 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.1 christos if (internal_relocs != NULL
1214 1.1 christos && elf_section_data (sec)->relocs != internal_relocs)
1215 1.1 christos free (internal_relocs);
1216 1.1 christos
1217 1.1 christos return TRUE;
1218 1.1 christos
1219 1.1 christos error_return:
1220 1.1 christos if (isymbuf != NULL
1221 1.1 christos && symtab_hdr->contents != (unsigned char *) isymbuf)
1222 1.1 christos free (isymbuf);
1223 1.1 christos if (contents != NULL
1224 1.1 christos && elf_section_data (sec)->this_hdr.contents != contents)
1225 1.1 christos free (contents);
1226 1.1 christos if (internal_relocs != NULL
1227 1.1 christos && elf_section_data (sec)->relocs != internal_relocs)
1228 1.1 christos free (internal_relocs);
1229 1.1 christos return FALSE;
1230 1.1 christos }
1231 1.1 christos
1232 1.1 christos /* Set the howto pointer for a IP2K ELF reloc. */
1233 1.1 christos
1234 1.1 christos static void
1235 1.1 christos ip2k_info_to_howto_rela (bfd * abfd ATTRIBUTE_UNUSED,
1236 1.1 christos arelent * cache_ptr,
1237 1.1 christos Elf_Internal_Rela * dst)
1238 1.1 christos {
1239 1.1 christos unsigned int r_type;
1240 1.1 christos
1241 1.1 christos r_type = ELF32_R_TYPE (dst->r_info);
1242 1.3 christos if (r_type >= (unsigned int) R_IP2K_max)
1243 1.3 christos {
1244 1.7 christos /* xgettext:c-format */
1245 1.5 christos _bfd_error_handler (_("%B: invalid IP2K reloc number: %d"), abfd, r_type);
1246 1.3 christos r_type = 0;
1247 1.3 christos }
1248 1.1 christos cache_ptr->howto = & ip2k_elf_howto_table [r_type];
1249 1.1 christos }
1250 1.1 christos
1251 1.1 christos /* Perform a single relocation.
1252 1.1 christos By default we use the standard BFD routines. */
1253 1.1 christos
1254 1.1 christos static bfd_reloc_status_type
1255 1.1 christos ip2k_final_link_relocate (reloc_howto_type * howto,
1256 1.1 christos bfd * input_bfd,
1257 1.1 christos asection * input_section,
1258 1.1 christos bfd_byte * contents,
1259 1.1 christos Elf_Internal_Rela * rel,
1260 1.1 christos bfd_vma relocation)
1261 1.1 christos {
1262 1.1 christos static bfd_vma page_addr = 0;
1263 1.1 christos
1264 1.1 christos bfd_reloc_status_type r = bfd_reloc_ok;
1265 1.1 christos switch (howto->type)
1266 1.1 christos {
1267 1.1 christos /* Handle data space relocations. */
1268 1.1 christos case R_IP2K_FR9:
1269 1.1 christos case R_IP2K_BANK:
1270 1.1 christos if ((relocation & IP2K_DATA_MASK) == IP2K_DATA_VALUE)
1271 1.1 christos relocation &= ~IP2K_DATA_MASK;
1272 1.1 christos else
1273 1.1 christos r = bfd_reloc_notsupported;
1274 1.1 christos break;
1275 1.1 christos
1276 1.1 christos case R_IP2K_LO8DATA:
1277 1.1 christos case R_IP2K_HI8DATA:
1278 1.1 christos case R_IP2K_EX8DATA:
1279 1.1 christos break;
1280 1.1 christos
1281 1.1 christos /* Handle insn space relocations. */
1282 1.1 christos case R_IP2K_PAGE3:
1283 1.1 christos page_addr = BASEADDR (input_section) + rel->r_offset;
1284 1.1 christos if ((relocation & IP2K_INSN_MASK) == IP2K_INSN_VALUE)
1285 1.1 christos relocation &= ~IP2K_INSN_MASK;
1286 1.1 christos else
1287 1.1 christos r = bfd_reloc_notsupported;
1288 1.1 christos break;
1289 1.1 christos
1290 1.1 christos case R_IP2K_ADDR16CJP:
1291 1.1 christos if (BASEADDR (input_section) + rel->r_offset != page_addr + 2)
1292 1.1 christos {
1293 1.1 christos /* No preceding page instruction, verify that it isn't needed. */
1294 1.1 christos if (PAGENO (relocation + rel->r_addend) !=
1295 1.1 christos ip2k_nominal_page_bits (input_bfd, input_section,
1296 1.1 christos rel->r_offset, contents))
1297 1.7 christos /* xgettext:c-format */
1298 1.1 christos _bfd_error_handler (_("ip2k linker: missing page instruction at 0x%08lx (dest = 0x%08lx)."),
1299 1.1 christos BASEADDR (input_section) + rel->r_offset,
1300 1.1 christos relocation + rel->r_addend);
1301 1.1 christos }
1302 1.1 christos else if (ip2k_relaxed)
1303 1.1 christos {
1304 1.1 christos /* Preceding page instruction. Verify that the page instruction is
1305 1.1 christos really needed. One reason for the relaxation to miss a page is if
1306 1.1 christos the section is not marked as executable. */
1307 1.1 christos if (!ip2k_is_switch_table_128 (input_bfd, input_section,
1308 1.1 christos rel->r_offset - 2, contents)
1309 1.1 christos && !ip2k_is_switch_table_256 (input_bfd, input_section,
1310 1.1 christos rel->r_offset - 2, contents)
1311 1.1 christos && (PAGENO (relocation + rel->r_addend) ==
1312 1.1 christos ip2k_nominal_page_bits (input_bfd, input_section,
1313 1.1 christos rel->r_offset - 2, contents)))
1314 1.7 christos /* xgettext:c-format */
1315 1.1 christos _bfd_error_handler (_("ip2k linker: redundant page instruction at 0x%08lx (dest = 0x%08lx)."),
1316 1.1 christos page_addr,
1317 1.1 christos relocation + rel->r_addend);
1318 1.1 christos }
1319 1.1 christos if ((relocation & IP2K_INSN_MASK) == IP2K_INSN_VALUE)
1320 1.1 christos relocation &= ~IP2K_INSN_MASK;
1321 1.1 christos else
1322 1.1 christos r = bfd_reloc_notsupported;
1323 1.1 christos break;
1324 1.1 christos
1325 1.1 christos case R_IP2K_LO8INSN:
1326 1.1 christos case R_IP2K_HI8INSN:
1327 1.1 christos case R_IP2K_PC_SKIP:
1328 1.1 christos if ((relocation & IP2K_INSN_MASK) == IP2K_INSN_VALUE)
1329 1.1 christos relocation &= ~IP2K_INSN_MASK;
1330 1.1 christos else
1331 1.1 christos r = bfd_reloc_notsupported;
1332 1.1 christos break;
1333 1.1 christos
1334 1.1 christos case R_IP2K_16:
1335 1.1 christos /* If this is a relocation involving a TEXT
1336 1.1 christos symbol, reduce it to a word address. */
1337 1.1 christos if ((relocation & IP2K_INSN_MASK) == IP2K_INSN_VALUE)
1338 1.1 christos howto = &ip2k_elf_howto_table[ (int) R_IP2K_TEXT];
1339 1.1 christos break;
1340 1.1 christos
1341 1.1 christos /* Pass others through. */
1342 1.1 christos default:
1343 1.1 christos break;
1344 1.1 christos }
1345 1.1 christos
1346 1.1 christos /* Only install relocation if above tests did not disqualify it. */
1347 1.1 christos if (r == bfd_reloc_ok)
1348 1.1 christos r = _bfd_final_link_relocate (howto, input_bfd, input_section,
1349 1.1 christos contents, rel->r_offset,
1350 1.1 christos relocation, rel->r_addend);
1351 1.1 christos
1352 1.1 christos return r;
1353 1.1 christos }
1354 1.1 christos
1355 1.1 christos /* Relocate a IP2K ELF section.
1356 1.1 christos
1357 1.1 christos The RELOCATE_SECTION function is called by the new ELF backend linker
1358 1.1 christos to handle the relocations for a section.
1359 1.1 christos
1360 1.1 christos The relocs are always passed as Rela structures; if the section
1361 1.1 christos actually uses Rel structures, the r_addend field will always be
1362 1.1 christos zero.
1363 1.1 christos
1364 1.1 christos This function is responsible for adjusting the section contents as
1365 1.1 christos necessary, and (if using Rela relocs and generating a relocatable
1366 1.1 christos output file) adjusting the reloc addend as necessary.
1367 1.1 christos
1368 1.1 christos This function does not have to worry about setting the reloc
1369 1.1 christos address or the reloc symbol index.
1370 1.1 christos
1371 1.1 christos LOCAL_SYMS is a pointer to the swapped in local symbols.
1372 1.1 christos
1373 1.1 christos LOCAL_SECTIONS is an array giving the section in the input file
1374 1.1 christos corresponding to the st_shndx field of each local symbol.
1375 1.1 christos
1376 1.1 christos The global hash table entry for the global symbols can be found
1377 1.1 christos via elf_sym_hashes (input_bfd).
1378 1.1 christos
1379 1.1 christos When generating relocatable output, this function must handle
1380 1.1 christos STB_LOCAL/STT_SECTION symbols specially. The output symbol is
1381 1.1 christos going to be the section symbol corresponding to the output
1382 1.1 christos section, which means that the addend must be adjusted
1383 1.1 christos accordingly. */
1384 1.1 christos
1385 1.1 christos static bfd_boolean
1386 1.1 christos ip2k_elf_relocate_section (bfd *output_bfd ATTRIBUTE_UNUSED,
1387 1.1 christos struct bfd_link_info *info,
1388 1.1 christos bfd *input_bfd,
1389 1.1 christos asection *input_section,
1390 1.1 christos bfd_byte *contents,
1391 1.1 christos Elf_Internal_Rela *relocs,
1392 1.1 christos Elf_Internal_Sym *local_syms,
1393 1.1 christos asection **local_sections)
1394 1.1 christos {
1395 1.1 christos Elf_Internal_Shdr *symtab_hdr;
1396 1.1 christos struct elf_link_hash_entry **sym_hashes;
1397 1.1 christos Elf_Internal_Rela *rel;
1398 1.1 christos Elf_Internal_Rela *relend;
1399 1.1 christos
1400 1.1 christos symtab_hdr = & elf_tdata (input_bfd)->symtab_hdr;
1401 1.1 christos sym_hashes = elf_sym_hashes (input_bfd);
1402 1.1 christos relend = relocs + input_section->reloc_count;
1403 1.1 christos
1404 1.1 christos for (rel = relocs; rel < relend; rel ++)
1405 1.1 christos {
1406 1.1 christos reloc_howto_type * howto;
1407 1.1 christos unsigned long r_symndx;
1408 1.1 christos Elf_Internal_Sym * sym;
1409 1.1 christos asection * sec;
1410 1.1 christos struct elf_link_hash_entry * h;
1411 1.1 christos bfd_vma relocation;
1412 1.1 christos bfd_reloc_status_type r;
1413 1.1 christos const char * name = NULL;
1414 1.1 christos int r_type;
1415 1.1 christos
1416 1.1 christos r_type = ELF32_R_TYPE (rel->r_info);
1417 1.1 christos r_symndx = ELF32_R_SYM (rel->r_info);
1418 1.1 christos howto = ip2k_elf_howto_table + r_type;
1419 1.1 christos h = NULL;
1420 1.1 christos sym = NULL;
1421 1.1 christos sec = NULL;
1422 1.1 christos
1423 1.1 christos if (r_symndx < symtab_hdr->sh_info)
1424 1.1 christos {
1425 1.1 christos sym = local_syms + r_symndx;
1426 1.1 christos sec = local_sections [r_symndx];
1427 1.1 christos relocation = BASEADDR (sec) + sym->st_value;
1428 1.1 christos
1429 1.1 christos name = bfd_elf_string_from_elf_section
1430 1.1 christos (input_bfd, symtab_hdr->sh_link, sym->st_name);
1431 1.1 christos name = (name == NULL) ? bfd_section_name (input_bfd, sec) : name;
1432 1.1 christos }
1433 1.1 christos else
1434 1.1 christos {
1435 1.1 christos bfd_boolean warned, ignored;
1436 1.1 christos bfd_boolean unresolved_reloc;
1437 1.1 christos
1438 1.1 christos RELOC_FOR_GLOBAL_SYMBOL (info, input_bfd, input_section, rel,
1439 1.1 christos r_symndx, symtab_hdr, sym_hashes,
1440 1.1 christos h, sec, relocation,
1441 1.1 christos unresolved_reloc, warned, ignored);
1442 1.1 christos
1443 1.1 christos name = h->root.root.string;
1444 1.1 christos }
1445 1.1 christos
1446 1.1 christos if (sec != NULL && discarded_section (sec))
1447 1.1 christos RELOC_AGAINST_DISCARDED_SECTION (info, input_bfd, input_section,
1448 1.1 christos rel, 1, relend, howto, 0, contents);
1449 1.1 christos
1450 1.6 christos if (bfd_link_relocatable (info))
1451 1.1 christos continue;
1452 1.1 christos
1453 1.1 christos /* Finally, the sole IP2K-specific part. */
1454 1.1 christos r = ip2k_final_link_relocate (howto, input_bfd, input_section,
1455 1.1 christos contents, rel, relocation);
1456 1.1 christos
1457 1.1 christos if (r != bfd_reloc_ok)
1458 1.1 christos {
1459 1.1 christos const char * msg = NULL;
1460 1.1 christos
1461 1.1 christos switch (r)
1462 1.1 christos {
1463 1.1 christos case bfd_reloc_overflow:
1464 1.6 christos (*info->callbacks->reloc_overflow)
1465 1.1 christos (info, (h ? &h->root : NULL), name, howto->name,
1466 1.1 christos (bfd_vma) 0, input_bfd, input_section, rel->r_offset);
1467 1.1 christos break;
1468 1.1 christos
1469 1.1 christos case bfd_reloc_undefined:
1470 1.6 christos (*info->callbacks->undefined_symbol)
1471 1.1 christos (info, name, input_bfd, input_section, rel->r_offset, TRUE);
1472 1.1 christos break;
1473 1.1 christos
1474 1.1 christos case bfd_reloc_outofrange:
1475 1.1 christos msg = _("internal error: out of range error");
1476 1.1 christos break;
1477 1.1 christos
1478 1.1 christos /* This is how ip2k_final_link_relocate tells us of a non-kosher
1479 1.1 christos reference between insn & data address spaces. */
1480 1.1 christos case bfd_reloc_notsupported:
1481 1.1 christos if (sym != NULL) /* Only if it's not an unresolved symbol. */
1482 1.1 christos msg = _("unsupported relocation between data/insn address spaces");
1483 1.1 christos break;
1484 1.1 christos
1485 1.1 christos case bfd_reloc_dangerous:
1486 1.1 christos msg = _("internal error: dangerous relocation");
1487 1.1 christos break;
1488 1.1 christos
1489 1.1 christos default:
1490 1.1 christos msg = _("internal error: unknown error");
1491 1.1 christos break;
1492 1.1 christos }
1493 1.1 christos
1494 1.1 christos if (msg)
1495 1.6 christos (*info->callbacks->warning) (info, msg, name, input_bfd,
1496 1.6 christos input_section, rel->r_offset);
1497 1.1 christos }
1498 1.1 christos }
1499 1.1 christos
1500 1.1 christos return TRUE;
1501 1.1 christos }
1502 1.1 christos
1503 1.3 christos #define TARGET_BIG_SYM ip2k_elf32_vec
1504 1.1 christos #define TARGET_BIG_NAME "elf32-ip2k"
1505 1.1 christos
1506 1.1 christos #define ELF_ARCH bfd_arch_ip2k
1507 1.1 christos #define ELF_MACHINE_CODE EM_IP2K
1508 1.1 christos #define ELF_MACHINE_ALT1 EM_IP2K_OLD
1509 1.1 christos #define ELF_MAXPAGESIZE 1 /* No pages on the IP2K. */
1510 1.1 christos
1511 1.1 christos #define elf_info_to_howto_rel NULL
1512 1.1 christos #define elf_info_to_howto ip2k_info_to_howto_rela
1513 1.1 christos
1514 1.1 christos #define elf_backend_can_gc_sections 1
1515 1.1 christos #define elf_backend_rela_normal 1
1516 1.1 christos #define elf_backend_relocate_section ip2k_elf_relocate_section
1517 1.1 christos
1518 1.1 christos #define elf_symbol_leading_char '_'
1519 1.1 christos #define bfd_elf32_bfd_reloc_type_lookup ip2k_reloc_type_lookup
1520 1.1 christos #define bfd_elf32_bfd_reloc_name_lookup ip2k_reloc_name_lookup
1521 1.1 christos #define bfd_elf32_bfd_relax_section ip2k_elf_relax_section
1522 1.1 christos
1523 1.1 christos #include "elf32-target.h"
1524