]> git.ipfire.org Git - thirdparty/binutils-gdb.git/blame - bfd/elf32-cr16.c
Re: MSP430: Support relocations for subtract expressions in .uleb128 directives
[thirdparty/binutils-gdb.git] / bfd / elf32-cr16.c
CommitLineData
3d3d428f 1/* BFD back-end for National Semiconductor's CR16 ELF
b3adc24a 2 Copyright (C) 2007-2020 Free Software Foundation, Inc.
3d3d428f
NC
3 Written by M R Swami Reddy.
4
5 This file is part of BFD, the Binary File Descriptor library.
6
7 This program is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
cd123cb7 9 the Free Software Foundation; either version 3 of the License, or
3d3d428f
NC
10 (at your option) any later version.
11
12 This program is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
16
17 You should have received a copy of the GNU General Public License
18 along with this program; if not, write to the Free Software Foundation,
19 Inc., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA. */
20
21#include "sysdep.h"
22#include "bfd.h"
23#include "bfdlink.h"
24#include "libbfd.h"
25#include "libiberty.h"
26#include "elf-bfd.h"
27#include "elf/cr16.h"
ca05ca5e 28#include "elf32-cr16.h"
3d3d428f 29
99706f30
SR
30/* The cr16 linker needs to keep track of the number of relocs that
31 it decides to copy in check_relocs for each symbol. This is so
32 that it can discard PC relative relocs if it doesn't need them when
33 linking with -Bsymbolic. We store the information in a field
34 extending the regular ELF linker hash table. */
35
4dfe6ac6
NC
36struct elf32_cr16_link_hash_entry
37{
99706f30
SR
38 /* The basic elf link hash table entry. */
39 struct elf_link_hash_entry root;
40
41 /* For function symbols, the number of times this function is
42 called directly (ie by name). */
43 unsigned int direct_calls;
44
45 /* For function symbols, the size of this function's stack
46 (if <= 255 bytes). We stuff this into "call" instructions
47 to this target when it's valid and profitable to do so.
48
49 This does not include stack allocated by movm! */
50 unsigned char stack_size;
51
52 /* For function symbols, arguments (if any) for movm instruction
53 in the prologue. We stuff this value into "call" instructions
54 to the target when it's valid and profitable to do so. */
55 unsigned char movm_args;
56
57 /* For function symbols, the amount of stack space that would be allocated
58 by the movm instruction. This is redundant with movm_args, but we
59 add it to the hash table to avoid computing it over and over. */
60 unsigned char movm_stack_size;
61
62/* Used to mark functions which have had redundant parts of their
63 prologue deleted. */
64#define CR16_DELETED_PROLOGUE_BYTES 0x1
65 unsigned char flags;
66
67 /* Calculated value. */
68 bfd_vma value;
69};
70
3d3d428f
NC
71/* cr16_reloc_map array maps BFD relocation enum into a CRGAS relocation type. */
72
73struct cr16_reloc_map
74{
75 bfd_reloc_code_real_type bfd_reloc_enum; /* BFD relocation enum. */
07d6d2b8 76 unsigned short cr16_reloc_type; /* CR16 relocation type. */
3d3d428f
NC
77};
78
79static const struct cr16_reloc_map cr16_reloc_map[R_CR16_MAX] =
80{
07d6d2b8
AM
81 {BFD_RELOC_NONE, R_CR16_NONE},
82 {BFD_RELOC_CR16_NUM8, R_CR16_NUM8},
3d3d428f
NC
83 {BFD_RELOC_CR16_NUM16, R_CR16_NUM16},
84 {BFD_RELOC_CR16_NUM32, R_CR16_NUM32},
85 {BFD_RELOC_CR16_NUM32a, R_CR16_NUM32a},
86 {BFD_RELOC_CR16_REGREL4, R_CR16_REGREL4},
87 {BFD_RELOC_CR16_REGREL4a, R_CR16_REGREL4a},
88 {BFD_RELOC_CR16_REGREL14, R_CR16_REGREL14},
89 {BFD_RELOC_CR16_REGREL14a, R_CR16_REGREL14a},
90 {BFD_RELOC_CR16_REGREL16, R_CR16_REGREL16},
91 {BFD_RELOC_CR16_REGREL20, R_CR16_REGREL20},
92 {BFD_RELOC_CR16_REGREL20a, R_CR16_REGREL20a},
93 {BFD_RELOC_CR16_ABS20, R_CR16_ABS20},
94 {BFD_RELOC_CR16_ABS24, R_CR16_ABS24},
07d6d2b8
AM
95 {BFD_RELOC_CR16_IMM4, R_CR16_IMM4},
96 {BFD_RELOC_CR16_IMM8, R_CR16_IMM8},
3d3d428f
NC
97 {BFD_RELOC_CR16_IMM16, R_CR16_IMM16},
98 {BFD_RELOC_CR16_IMM20, R_CR16_IMM20},
99 {BFD_RELOC_CR16_IMM24, R_CR16_IMM24},
100 {BFD_RELOC_CR16_IMM32, R_CR16_IMM32},
101 {BFD_RELOC_CR16_IMM32a, R_CR16_IMM32a},
102 {BFD_RELOC_CR16_DISP4, R_CR16_DISP4},
103 {BFD_RELOC_CR16_DISP8, R_CR16_DISP8},
104 {BFD_RELOC_CR16_DISP16, R_CR16_DISP16},
105 {BFD_RELOC_CR16_DISP24, R_CR16_DISP24},
7fac7ff4
NC
106 {BFD_RELOC_CR16_DISP24a, R_CR16_DISP24a},
107 {BFD_RELOC_CR16_SWITCH8, R_CR16_SWITCH8},
108 {BFD_RELOC_CR16_SWITCH16, R_CR16_SWITCH16},
99706f30
SR
109 {BFD_RELOC_CR16_SWITCH32, R_CR16_SWITCH32},
110 {BFD_RELOC_CR16_GOT_REGREL20, R_CR16_GOT_REGREL20},
111 {BFD_RELOC_CR16_GOTC_REGREL20, R_CR16_GOTC_REGREL20},
112 {BFD_RELOC_CR16_GLOB_DAT, R_CR16_GLOB_DAT}
3d3d428f
NC
113};
114
115static reloc_howto_type cr16_elf_howto_table[] =
116{
07d6d2b8
AM
117 HOWTO (R_CR16_NONE, /* type */
118 0, /* rightshift */
119 3, /* size */
120 0, /* bitsize */
121 FALSE, /* pc_relative */
122 0, /* bitpos */
123 complain_overflow_dont, /* complain_on_overflow */
124 bfd_elf_generic_reloc, /* special_function */
125 "R_CR16_NONE", /* name */
126 FALSE, /* partial_inplace */
127 0, /* src_mask */
128 0, /* dst_mask */
129 FALSE), /* pcrel_offset */
130
131 HOWTO (R_CR16_NUM8, /* type */
132 0, /* rightshift */
133 0, /* size */
134 8, /* bitsize */
135 FALSE, /* pc_relative */
136 0, /* bitpos */
137 complain_overflow_bitfield,/* complain_on_overflow */
138 bfd_elf_generic_reloc, /* special_function */
139 "R_CR16_NUM8", /* name */
140 FALSE, /* partial_inplace */
141 0x0, /* src_mask */
142 0xff, /* dst_mask */
143 FALSE), /* pcrel_offset */
144
145 HOWTO (R_CR16_NUM16, /* type */
146 0, /* rightshift */
147 1, /* size */
148 16, /* bitsize */
149 FALSE, /* pc_relative */
150 0, /* bitpos */
151 complain_overflow_bitfield,/* complain_on_overflow */
152 bfd_elf_generic_reloc, /* special_function */
153 "R_CR16_NUM16", /* name */
154 FALSE, /* partial_inplace */
155 0x0, /* src_mask */
156 0xffff, /* dst_mask */
157 FALSE), /* pcrel_offset */
158
159 HOWTO (R_CR16_NUM32, /* type */
160 0, /* rightshift */
161 2, /* size */
162 32, /* bitsize */
163 FALSE, /* pc_relative */
164 0, /* bitpos */
165 complain_overflow_bitfield,/* complain_on_overflow */
166 bfd_elf_generic_reloc, /* special_function */
167 "R_CR16_NUM32", /* name */
168 FALSE, /* partial_inplace */
169 0x0, /* src_mask */
170 0xffffffff, /* dst_mask */
171 FALSE), /* pcrel_offset */
172
173 HOWTO (R_CR16_NUM32a, /* type */
174 1, /* rightshift */
175 2, /* size */
176 32, /* bitsize */
177 FALSE, /* pc_relative */
178 0, /* bitpos */
179 complain_overflow_bitfield,/* complain_on_overflow */
180 bfd_elf_generic_reloc, /* special_function */
181 "R_CR16_NUM32a", /* name */
182 FALSE, /* partial_inplace */
183 0x0, /* src_mask */
184 0xffffffff, /* dst_mask */
185 FALSE), /* pcrel_offset */
186
187 HOWTO (R_CR16_REGREL4, /* type */
188 0, /* rightshift */
189 0, /* size */
190 4, /* bitsize */
191 FALSE, /* pc_relative */
192 0, /* bitpos */
193 complain_overflow_bitfield,/* complain_on_overflow */
194 bfd_elf_generic_reloc, /* special_function */
195 "R_CR16_REGREL4", /* name */
196 FALSE, /* partial_inplace */
197 0x0, /* src_mask */
198 0xf, /* dst_mask */
199 FALSE), /* pcrel_offset */
200
201 HOWTO (R_CR16_REGREL4a, /* type */
202 0, /* rightshift */
203 0, /* size */
204 4, /* bitsize */
205 FALSE, /* pc_relative */
206 0, /* bitpos */
207 complain_overflow_bitfield,/* complain_on_overflow */
208 bfd_elf_generic_reloc, /* special_function */
209 "R_CR16_REGREL4a", /* name */
210 FALSE, /* partial_inplace */
211 0x0, /* src_mask */
212 0xf, /* dst_mask */
213 FALSE), /* pcrel_offset */
214
215 HOWTO (R_CR16_REGREL14, /* type */
216 0, /* rightshift */
217 1, /* size */
218 14, /* bitsize */
219 FALSE, /* pc_relative */
220 0, /* bitpos */
221 complain_overflow_bitfield,/* complain_on_overflow */
222 bfd_elf_generic_reloc, /* special_function */
223 "R_CR16_REGREL14", /* name */
224 FALSE, /* partial_inplace */
225 0x0, /* src_mask */
226 0x3fff, /* dst_mask */
227 FALSE), /* pcrel_offset */
228
229 HOWTO (R_CR16_REGREL14a, /* type */
230 0, /* rightshift */
231 1, /* size */
232 14, /* bitsize */
233 FALSE, /* pc_relative */
234 0, /* bitpos */
235 complain_overflow_bitfield,/* complain_on_overflow */
236 bfd_elf_generic_reloc, /* special_function */
237 "R_CR16_REGREL14a", /* name */
238 FALSE, /* partial_inplace */
239 0x0, /* src_mask */
240 0x3fff, /* dst_mask */
241 FALSE), /* pcrel_offset */
242
243 HOWTO (R_CR16_REGREL16, /* type */
244 0, /* rightshift */
245 1, /* size */
246 16, /* bitsize */
247 FALSE, /* pc_relative */
248 0, /* bitpos */
249 complain_overflow_bitfield,/* complain_on_overflow */
250 bfd_elf_generic_reloc, /* special_function */
251 "R_CR16_REGREL16", /* name */
252 FALSE, /* partial_inplace */
253 0x0, /* src_mask */
254 0xffff, /* dst_mask */
255 FALSE), /* pcrel_offset */
256
257 HOWTO (R_CR16_REGREL20, /* type */
258 0, /* rightshift */
259 2, /* size */
260 20, /* bitsize */
261 FALSE, /* pc_relative */
262 0, /* bitpos */
263 complain_overflow_bitfield,/* complain_on_overflow */
264 bfd_elf_generic_reloc, /* special_function */
265 "R_CR16_REGREL20", /* name */
266 FALSE, /* partial_inplace */
267 0x0, /* src_mask */
268 0xfffff, /* dst_mask */
269 FALSE), /* pcrel_offset */
270
271 HOWTO (R_CR16_REGREL20a, /* type */
272 0, /* rightshift */
273 2, /* size */
274 20, /* bitsize */
275 FALSE, /* pc_relative */
276 0, /* bitpos */
277 complain_overflow_bitfield,/* complain_on_overflow */
278 bfd_elf_generic_reloc, /* special_function */
279 "R_CR16_REGREL20a", /* name */
280 FALSE, /* partial_inplace */
281 0x0, /* src_mask */
282 0xfffff, /* dst_mask */
283 FALSE), /* pcrel_offset */
284
285 HOWTO (R_CR16_ABS20, /* type */
286 0, /* rightshift */
287 2, /* size */
288 20, /* bitsize */
289 FALSE, /* pc_relative */
290 0, /* bitpos */
291 complain_overflow_bitfield,/* complain_on_overflow */
292 bfd_elf_generic_reloc, /* special_function */
293 "R_CR16_ABS20", /* name */
294 FALSE, /* partial_inplace */
295 0x0, /* src_mask */
296 0xfffff, /* dst_mask */
297 FALSE), /* pcrel_offset */
298
299 HOWTO (R_CR16_ABS24, /* type */
300 0, /* rightshift */
301 2, /* size */
302 24, /* bitsize */
303 FALSE, /* pc_relative */
304 0, /* bitpos */
305 complain_overflow_bitfield,/* complain_on_overflow */
306 bfd_elf_generic_reloc, /* special_function */
307 "R_CR16_ABS24", /* name */
308 FALSE, /* partial_inplace */
309 0x0, /* src_mask */
310 0xffffff, /* dst_mask */
311 FALSE), /* pcrel_offset */
312
313 HOWTO (R_CR16_IMM4, /* type */
314 0, /* rightshift */
315 0, /* size */
316 4, /* bitsize */
317 FALSE, /* pc_relative */
318 0, /* bitpos */
319 complain_overflow_bitfield,/* complain_on_overflow */
320 bfd_elf_generic_reloc, /* special_function */
321 "R_CR16_IMM4", /* name */
322 FALSE, /* partial_inplace */
323 0x0, /* src_mask */
324 0xf, /* dst_mask */
325 FALSE), /* pcrel_offset */
326
327 HOWTO (R_CR16_IMM8, /* type */
328 0, /* rightshift */
329 0, /* size */
330 8, /* bitsize */
331 FALSE, /* pc_relative */
332 0, /* bitpos */
333 complain_overflow_bitfield,/* complain_on_overflow */
334 bfd_elf_generic_reloc, /* special_function */
335 "R_CR16_IMM8", /* name */
336 FALSE, /* partial_inplace */
337 0x0, /* src_mask */
338 0xff, /* dst_mask */
339 FALSE), /* pcrel_offset */
340
341 HOWTO (R_CR16_IMM16, /* type */
342 0, /* rightshift */
343 1, /* size */
344 16, /* bitsize */
345 FALSE, /* pc_relative */
346 0, /* bitpos */
347 complain_overflow_bitfield,/* complain_on_overflow */
348 bfd_elf_generic_reloc, /* special_function */
349 "R_CR16_IMM16", /* name */
350 FALSE, /* partial_inplace */
351 0x0, /* src_mask */
352 0xffff, /* dst_mask */
353 FALSE), /* pcrel_offset */
354
355 HOWTO (R_CR16_IMM20, /* type */
356 0, /* rightshift */
357 2, /* size */
358 20, /* bitsize */
359 FALSE, /* pc_relative */
360 0, /* bitpos */
361 complain_overflow_bitfield,/* complain_on_overflow */
362 bfd_elf_generic_reloc, /* special_function */
363 "R_CR16_IMM20", /* name */
364 FALSE, /* partial_inplace */
365 0x0, /* src_mask */
366 0xfffff, /* dst_mask */
367 FALSE), /* pcrel_offset */
368
369 HOWTO (R_CR16_IMM24, /* type */
370 0, /* rightshift */
371 2, /* size */
372 24, /* bitsize */
373 FALSE, /* pc_relative */
374 0, /* bitpos */
375 complain_overflow_bitfield,/* complain_on_overflow */
376 bfd_elf_generic_reloc, /* special_function */
377 "R_CR16_IMM24", /* name */
378 FALSE, /* partial_inplace */
379 0x0, /* src_mask */
380 0xffffff, /* dst_mask */
381 FALSE), /* pcrel_offset */
382
383 HOWTO (R_CR16_IMM32, /* type */
384 0, /* rightshift */
385 2, /* size */
386 32, /* bitsize */
387 FALSE, /* pc_relative */
388 0, /* bitpos */
389 complain_overflow_bitfield,/* complain_on_overflow */
390 bfd_elf_generic_reloc, /* special_function */
391 "R_CR16_IMM32", /* name */
392 FALSE, /* partial_inplace */
393 0x0, /* src_mask */
394 0xffffffff, /* dst_mask */
395 FALSE), /* pcrel_offset */
396
397 HOWTO (R_CR16_IMM32a, /* type */
398 1, /* rightshift */
399 2, /* size */
400 32, /* bitsize */
401 FALSE, /* pc_relative */
402 0, /* bitpos */
403 complain_overflow_bitfield,/* complain_on_overflow */
404 bfd_elf_generic_reloc, /* special_function */
405 "R_CR16_IMM32a", /* name */
406 FALSE, /* partial_inplace */
407 0x0, /* src_mask */
408 0xffffffff, /* dst_mask */
409 FALSE), /* pcrel_offset */
410
411 HOWTO (R_CR16_DISP4, /* type */
412 1, /* rightshift */
413 0, /* size (0 = byte, 1 = short, 2 = long) */
414 4, /* bitsize */
415 TRUE, /* pc_relative */
416 0, /* bitpos */
417 complain_overflow_unsigned, /* complain_on_overflow */
418 bfd_elf_generic_reloc, /* special_function */
419 "R_CR16_DISP4", /* name */
420 FALSE, /* partial_inplace */
421 0x0, /* src_mask */
422 0xf, /* dst_mask */
423 FALSE), /* pcrel_offset */
424
425 HOWTO (R_CR16_DISP8, /* type */
426 1, /* rightshift */
427 0, /* size (0 = byte, 1 = short, 2 = long) */
428 8, /* bitsize */
429 TRUE, /* pc_relative */
430 0, /* bitpos */
431 complain_overflow_unsigned, /* complain_on_overflow */
432 bfd_elf_generic_reloc, /* special_function */
433 "R_CR16_DISP8", /* name */
434 FALSE, /* partial_inplace */
435 0x0, /* src_mask */
436 0x1ff, /* dst_mask */
437 FALSE), /* pcrel_offset */
438
439 HOWTO (R_CR16_DISP16, /* type */
440 0, /* rightshift REVIITS: To sync with WinIDEA*/
441 1, /* size (0 = byte, 1 = short, 2 = long) */
442 16, /* bitsize */
443 TRUE, /* pc_relative */
444 0, /* bitpos */
445 complain_overflow_unsigned, /* complain_on_overflow */
446 bfd_elf_generic_reloc, /* special_function */
447 "R_CR16_DISP16", /* name */
448 FALSE, /* partial_inplace */
449 0x0, /* src_mask */
450 0x1ffff, /* dst_mask */
451 FALSE), /* pcrel_offset */
3d3d428f
NC
452 /* REVISIT: DISP24 should be left-shift by 2 as per ISA doc
453 but its not done, to sync with WinIDEA and CR16 4.1 tools */
07d6d2b8
AM
454 HOWTO (R_CR16_DISP24, /* type */
455 0, /* rightshift */
456 2, /* size (0 = byte, 1 = short, 2 = long) */
457 24, /* bitsize */
458 TRUE, /* pc_relative */
459 0, /* bitpos */
460 complain_overflow_unsigned, /* complain_on_overflow */
461 bfd_elf_generic_reloc, /* special_function */
462 "R_CR16_DISP24", /* name */
463 FALSE, /* partial_inplace */
464 0x0, /* src_mask */
465 0x1ffffff, /* dst_mask */
466 FALSE), /* pcrel_offset */
467
468 HOWTO (R_CR16_DISP24a, /* type */
469 0, /* rightshift */
470 2, /* size (0 = byte, 1 = short, 2 = long) */
471 24, /* bitsize */
472 TRUE, /* pc_relative */
473 0, /* bitpos */
474 complain_overflow_unsigned, /* complain_on_overflow */
475 bfd_elf_generic_reloc, /* special_function */
476 "R_CR16_DISP24a", /* name */
477 FALSE, /* partial_inplace */
478 0x0, /* src_mask */
479 0xffffff, /* dst_mask */
480 FALSE), /* pcrel_offset */
7fac7ff4
NC
481
482 /* An 8 bit switch table entry. This is generated for an expression
483 such as ``.byte L1 - L2''. The offset holds the difference
484 between the reloc address and L2. */
07d6d2b8
AM
485 HOWTO (R_CR16_SWITCH8, /* type */
486 0, /* rightshift */
487 0, /* size (0 = byte, 1 = short, 2 = long) */
488 8, /* bitsize */
489 FALSE, /* pc_relative */
490 0, /* bitpos */
491 complain_overflow_unsigned, /* complain_on_overflow */
492 bfd_elf_generic_reloc, /* special_function */
493 "R_CR16_SWITCH8", /* name */
494 FALSE, /* partial_inplace */
495 0x0, /* src_mask */
496 0xff, /* dst_mask */
497 TRUE), /* pcrel_offset */
7fac7ff4
NC
498
499 /* A 16 bit switch table entry. This is generated for an expression
500 such as ``.word L1 - L2''. The offset holds the difference
501 between the reloc address and L2. */
07d6d2b8
AM
502 HOWTO (R_CR16_SWITCH16, /* type */
503 0, /* rightshift */
504 1, /* size (0 = byte, 1 = short, 2 = long) */
505 16, /* bitsize */
506 FALSE, /* pc_relative */
507 0, /* bitpos */
508 complain_overflow_unsigned, /* complain_on_overflow */
509 bfd_elf_generic_reloc, /* special_function */
510 "R_CR16_SWITCH16", /* name */
511 FALSE, /* partial_inplace */
512 0x0, /* src_mask */
513 0xffff, /* dst_mask */
514 TRUE), /* pcrel_offset */
7fac7ff4
NC
515
516 /* A 32 bit switch table entry. This is generated for an expression
517 such as ``.long L1 - L2''. The offset holds the difference
518 between the reloc address and L2. */
07d6d2b8
AM
519 HOWTO (R_CR16_SWITCH32, /* type */
520 0, /* rightshift */
521 2, /* size (0 = byte, 1 = short, 2 = long) */
522 32, /* bitsize */
523 FALSE, /* pc_relative */
524 0, /* bitpos */
525 complain_overflow_unsigned, /* complain_on_overflow */
526 bfd_elf_generic_reloc, /* special_function */
527 "R_CR16_SWITCH32", /* name */
528 FALSE, /* partial_inplace */
529 0x0, /* src_mask */
530 0xffffffff, /* dst_mask */
531 TRUE), /* pcrel_offset */
532
533 HOWTO (R_CR16_GOT_REGREL20, /* type */
534 0, /* rightshift */
535 2, /* size */
536 20, /* bitsize */
537 FALSE, /* pc_relative */
538 0, /* bitpos */
539 complain_overflow_bitfield,/* complain_on_overflow */
540 bfd_elf_generic_reloc, /* special_function */
541 "R_CR16_GOT_REGREL20", /* name */
542 TRUE, /* partial_inplace */
543 0x0, /* src_mask */
544 0xfffff, /* dst_mask */
545 FALSE), /* pcrel_offset */
546
547 HOWTO (R_CR16_GOTC_REGREL20, /* type */
548 0, /* rightshift */
549 2, /* size */
550 20, /* bitsize */
551 FALSE, /* pc_relative */
552 0, /* bitpos */
553 complain_overflow_bitfield,/* complain_on_overflow */
554 bfd_elf_generic_reloc, /* special_function */
555 "R_CR16_GOTC_REGREL20", /* name */
556 TRUE, /* partial_inplace */
557 0x0, /* src_mask */
558 0xfffff, /* dst_mask */
559 FALSE), /* pcrel_offset */
560
561 HOWTO (R_CR16_GLOB_DAT, /* type */
562 0, /* rightshift */
563 2, /* size (0 = byte, 1 = short, 2 = long) */
564 32, /* bitsize */
565 FALSE, /* pc_relative */
566 0, /* bitpos */
567 complain_overflow_unsigned, /* complain_on_overflow */
568 bfd_elf_generic_reloc, /* special_function */
569 "R_CR16_GLOB_DAT", /* name */
570 FALSE, /* partial_inplace */
571 0x0, /* src_mask */
572 0xffffffff, /* dst_mask */
573 TRUE) /* pcrel_offset */
3d3d428f
NC
574};
575
99706f30
SR
576
577/* Create the GOT section. */
578
579static bfd_boolean
580_bfd_cr16_elf_create_got_section (bfd * abfd, struct bfd_link_info * info)
581{
582 flagword flags;
583 asection * s;
584 struct elf_link_hash_entry * h;
585 const struct elf_backend_data * bed = get_elf_backend_data (abfd);
ce558b89 586 struct elf_link_hash_table *htab = elf_hash_table (info);
99706f30
SR
587 int ptralign;
588
589 /* This function may be called more than once. */
ce558b89 590 if (htab->sgot != NULL)
99706f30
SR
591 return TRUE;
592
593 switch (bed->s->arch_size)
594 {
595 case 16:
596 ptralign = 1;
597 break;
598
599 case 32:
600 ptralign = 2;
601 break;
602
603 default:
604 bfd_set_error (bfd_error_bad_value);
605 return FALSE;
606 }
607
608 flags = (SEC_ALLOC | SEC_LOAD | SEC_HAS_CONTENTS | SEC_IN_MEMORY
07d6d2b8 609 | SEC_LINKER_CREATED);
99706f30 610
3d4d4302 611 s = bfd_make_section_anyway_with_flags (abfd, ".got", flags);
ce558b89 612 htab->sgot= s;
99706f30 613 if (s == NULL
fd361982 614 || !bfd_set_section_alignment (s, ptralign))
99706f30
SR
615 return FALSE;
616
617 if (bed->want_got_plt)
618 {
3d4d4302 619 s = bfd_make_section_anyway_with_flags (abfd, ".got.plt", flags);
ce558b89 620 htab->sgotplt = s;
99706f30 621 if (s == NULL
fd361982 622 || !bfd_set_section_alignment (s, ptralign))
07d6d2b8 623 return FALSE;
99706f30
SR
624 }
625
626 /* Define the symbol _GLOBAL_OFFSET_TABLE_ at the start of the .got
627 (or .got.plt) section. We don't do this in the linker script
628 because we don't want to define the symbol if we are not creating
629 a global offset table. */
630 h = _bfd_elf_define_linkage_sym (abfd, info, s, "_GLOBAL_OFFSET_TABLE_");
ce558b89 631 htab->hgot = h;
99706f30
SR
632 if (h == NULL)
633 return FALSE;
634
635 /* The first bit of the global offset table is the header. */
636 s->size += bed->got_header_size;
637
638 return TRUE;
639}
640
641
3d3d428f
NC
642/* Retrieve a howto ptr using a BFD reloc_code. */
643
644static reloc_howto_type *
0aa13fee 645elf_cr16_reloc_type_lookup (bfd *abfd,
07d6d2b8 646 bfd_reloc_code_real_type code)
3d3d428f
NC
647{
648 unsigned int i;
649
650 for (i = 0; i < R_CR16_MAX; i++)
651 if (code == cr16_reloc_map[i].bfd_reloc_enum)
652 return &cr16_elf_howto_table[cr16_reloc_map[i].cr16_reloc_type];
653
0aa13fee
AM
654 _bfd_error_handler (_("%pB: unsupported relocation type %#x"),
655 abfd, code);
3d3d428f
NC
656 return NULL;
657}
658
659static reloc_howto_type *
660elf_cr16_reloc_name_lookup (bfd *abfd ATTRIBUTE_UNUSED,
07d6d2b8 661 const char *r_name)
3d3d428f
NC
662{
663 unsigned int i;
664
665 for (i = 0; ARRAY_SIZE (cr16_elf_howto_table); i++)
666 if (cr16_elf_howto_table[i].name != NULL
07d6d2b8 667 && strcasecmp (cr16_elf_howto_table[i].name, r_name) == 0)
3d3d428f
NC
668 return cr16_elf_howto_table + i;
669
670 return NULL;
671}
672
673/* Retrieve a howto ptr using an internal relocation entry. */
674
f3185997 675static bfd_boolean
0aa13fee 676elf_cr16_info_to_howto (bfd *abfd, arelent *cache_ptr,
07d6d2b8 677 Elf_Internal_Rela *dst)
3d3d428f
NC
678{
679 unsigned int r_type = ELF32_R_TYPE (dst->r_info);
680
cd21f5da
NC
681 if (r_type >= R_CR16_MAX)
682 {
695344c0 683 /* xgettext:c-format */
0aa13fee 684 _bfd_error_handler (_("%pB: unsupported relocation type %#x"),
4eca0228 685 abfd, r_type);
cd21f5da 686 bfd_set_error (bfd_error_bad_value);
f3185997 687 return FALSE;
cd21f5da 688 }
99706f30 689 cache_ptr->howto = cr16_elf_howto_table + r_type;
f3185997 690 return TRUE;
99706f30
SR
691}
692
693/* Look through the relocs for a section during the first phase.
694 Since we don't do .gots or .plts, we just need to consider the
695 virtual table relocs for gc. */
696
697static bfd_boolean
698cr16_elf_check_relocs (bfd *abfd, struct bfd_link_info *info, asection *sec,
07d6d2b8 699 const Elf_Internal_Rela *relocs)
99706f30
SR
700{
701 Elf_Internal_Shdr *symtab_hdr;
702 Elf_Internal_Sym * isymbuf = NULL;
703 struct elf_link_hash_entry **sym_hashes, **sym_hashes_end;
704 const Elf_Internal_Rela *rel;
705 const Elf_Internal_Rela *rel_end;
706 bfd * dynobj;
707 bfd_vma * local_got_offsets;
708 asection * sgot;
709 asection * srelgot;
710
711 sgot = NULL;
712 srelgot = NULL;
713 bfd_boolean result = FALSE;
714
0e1862bb 715 if (bfd_link_relocatable (info))
99706f30
SR
716 return TRUE;
717
718 symtab_hdr = &elf_tdata (abfd)->symtab_hdr;
719 sym_hashes = elf_sym_hashes (abfd);
720 sym_hashes_end = sym_hashes + symtab_hdr->sh_size/sizeof (Elf32_External_Sym);
721 if (!elf_bad_symtab (abfd))
722 sym_hashes_end -= symtab_hdr->sh_info;
723
724 dynobj = elf_hash_table (info)->dynobj;
725 local_got_offsets = elf_local_got_offsets (abfd);
726 rel_end = relocs + sec->reloc_count;
727 for (rel = relocs; rel < rel_end; rel++)
728 {
729 struct elf_link_hash_entry *h;
730 unsigned long r_symndx;
731
732 r_symndx = ELF32_R_SYM (rel->r_info);
733 if (r_symndx < symtab_hdr->sh_info)
07d6d2b8 734 h = NULL;
99706f30 735 else
07d6d2b8
AM
736 {
737 h = sym_hashes[r_symndx - symtab_hdr->sh_info];
738 while (h->root.type == bfd_link_hash_indirect
739 || h->root.type == bfd_link_hash_warning)
740 h = (struct elf_link_hash_entry *) h->root.u.i.link;
741 }
99706f30
SR
742
743 /* Some relocs require a global offset table. */
744 if (dynobj == NULL)
07d6d2b8
AM
745 {
746 switch (ELF32_R_TYPE (rel->r_info))
747 {
748 case R_CR16_GOT_REGREL20:
749 case R_CR16_GOTC_REGREL20:
750 elf_hash_table (info)->dynobj = dynobj = abfd;
751 if (! _bfd_cr16_elf_create_got_section (dynobj, info))
752 goto fail;
753 break;
754
755 default:
756 break;
757 }
758 }
99706f30
SR
759
760 switch (ELF32_R_TYPE (rel->r_info))
07d6d2b8
AM
761 {
762 case R_CR16_GOT_REGREL20:
763 case R_CR16_GOTC_REGREL20:
764 /* This symbol requires a global offset table entry. */
99706f30 765
ce558b89
AM
766 sgot = elf_hash_table (info)->sgot;
767 srelgot = elf_hash_table (info)->srelgot;
768 BFD_ASSERT (sgot != NULL && srelgot != NULL);
99706f30 769
07d6d2b8
AM
770 if (h != NULL)
771 {
772 if (h->got.offset != (bfd_vma) -1)
773 /* We have already allocated space in the .got. */
774 break;
775
776 h->got.offset = sgot->size;
777
778 /* Make sure this symbol is output as a dynamic symbol. */
779 if (h->dynindx == -1)
780 {
781 if (! bfd_elf_link_record_dynamic_symbol (info, h))
782 goto fail;
783 }
784
785 srelgot->size += sizeof (Elf32_External_Rela);
786 }
787 else
788 {
789 /* This is a global offset table entry for a local
790 symbol. */
791 if (local_got_offsets == NULL)
792 {
793 size_t size;
794 unsigned int i;
795
796 size = symtab_hdr->sh_info * sizeof (bfd_vma);
797 local_got_offsets = (bfd_vma *) bfd_alloc (abfd, size);
798
799 if (local_got_offsets == NULL)
800 goto fail;
801
802 elf_local_got_offsets (abfd) = local_got_offsets;
803
804 for (i = 0; i < symtab_hdr->sh_info; i++)
805 local_got_offsets[i] = (bfd_vma) -1;
806 }
807
808 if (local_got_offsets[r_symndx] != (bfd_vma) -1)
809 /* We have already allocated space in the .got. */
810 break;
811
812 local_got_offsets[r_symndx] = sgot->size;
813
814 if (bfd_link_executable (info))
815 /* If we are generating a shared object, we need to
816 output a R_CR16_RELATIVE reloc so that the dynamic
817 linker can adjust this GOT entry. */
818 srelgot->size += sizeof (Elf32_External_Rela);
819 }
820
821 sgot->size += 4;
822 break;
823
824 }
99706f30
SR
825 }
826
c9594989
AM
827 result = TRUE;
828 fail:
829 free (isymbuf);
99706f30
SR
830
831 return result;
3d3d428f
NC
832}
833
834/* Perform a relocation as part of a final link. */
835
836static bfd_reloc_status_type
837cr16_elf_final_link_relocate (reloc_howto_type *howto,
07d6d2b8
AM
838 bfd *input_bfd,
839 bfd *output_bfd ATTRIBUTE_UNUSED,
840 asection *input_section,
841 bfd_byte *contents,
842 bfd_vma offset,
843 bfd_vma Rvalue,
844 bfd_vma addend,
845 struct elf_link_hash_entry * h,
846 unsigned long symndx ATTRIBUTE_UNUSED,
847 struct bfd_link_info *info ATTRIBUTE_UNUSED,
848 asection *sec ATTRIBUTE_UNUSED,
849 int is_local ATTRIBUTE_UNUSED)
3d3d428f
NC
850{
851 unsigned short r_type = howto->type;
852 bfd_byte *hit_data = contents + offset;
853 bfd_vma reloc_bits, check, Rvalue1;
99706f30 854
3d3d428f
NC
855 switch (r_type)
856 {
857 case R_CR16_IMM4:
7fac7ff4
NC
858 case R_CR16_IMM20:
859 case R_CR16_ABS20:
860 break;
861
3d3d428f
NC
862 case R_CR16_IMM8:
863 case R_CR16_IMM16:
3d3d428f
NC
864 case R_CR16_IMM32:
865 case R_CR16_IMM32a:
866 case R_CR16_REGREL4:
867 case R_CR16_REGREL4a:
868 case R_CR16_REGREL14:
869 case R_CR16_REGREL14a:
870 case R_CR16_REGREL16:
871 case R_CR16_REGREL20:
99706f30
SR
872 case R_CR16_REGREL20a:
873 case R_CR16_GOT_REGREL20:
874 case R_CR16_GOTC_REGREL20:
3d3d428f
NC
875 case R_CR16_ABS24:
876 case R_CR16_DISP16:
877 case R_CR16_DISP24:
878 /* 'hit_data' is relative to the start of the instruction, not the
07d6d2b8 879 relocation offset. Advance it to account for the exact offset. */
3d3d428f
NC
880 hit_data += 2;
881 break;
882
883 case R_CR16_NONE:
884 return bfd_reloc_ok;
885 break;
886
887 case R_CR16_DISP4:
7fac7ff4 888 if (is_local)
07d6d2b8 889 Rvalue += -1;
7fac7ff4
NC
890 break;
891
3d3d428f
NC
892 case R_CR16_DISP8:
893 case R_CR16_DISP24a:
7fac7ff4 894 if (is_local)
07d6d2b8 895 Rvalue -= -1;
7fac7ff4
NC
896 break;
897
898 case R_CR16_SWITCH8:
899 case R_CR16_SWITCH16:
900 case R_CR16_SWITCH32:
3d3d428f 901 /* We only care about the addend, where the difference between
07d6d2b8 902 expressions is kept. */
7fac7ff4 903 Rvalue = 0;
68ffbac6 904
3d3d428f
NC
905 default:
906 break;
907 }
908
909 if (howto->pc_relative)
910 {
911 /* Subtract the address of the section containing the location. */
912 Rvalue -= (input_section->output_section->vma
07d6d2b8 913 + input_section->output_offset);
3d3d428f
NC
914 /* Subtract the position of the location within the section. */
915 Rvalue -= offset;
916 }
917
918 /* Add in supplied addend. */
919 Rvalue += addend;
920
921 /* Complain if the bitfield overflows, whether it is considered
922 as signed or unsigned. */
923 check = Rvalue >> howto->rightshift;
924
34d8e6d0 925 reloc_bits = ((bfd_vma) 1 << (howto->bitsize - 1) << 1) - 1;
3d3d428f 926
99706f30
SR
927 /* For GOT and GOTC relocs no boundary checks applied. */
928 if (!((r_type == R_CR16_GOT_REGREL20)
929 || (r_type == R_CR16_GOTC_REGREL20)))
3d3d428f 930 {
99706f30 931 if (((bfd_vma) check & ~reloc_bits) != 0
07d6d2b8
AM
932 && (((bfd_vma) check & ~reloc_bits)
933 != (-(bfd_vma) 1 & ~reloc_bits)))
934 {
935 /* The above right shift is incorrect for a signed
936 value. See if turning on the upper bits fixes the
937 overflow. */
938 if (howto->rightshift && (bfd_signed_vma) Rvalue < 0)
939 {
940 check |= ((bfd_vma) - 1
941 & ~((bfd_vma) - 1
942 >> howto->rightshift));
943
944 if (((bfd_vma) check & ~reloc_bits)
945 != (-(bfd_vma) 1 & ~reloc_bits))
946 return bfd_reloc_overflow;
947 }
948 else
949 return bfd_reloc_overflow;
950 }
3d3d428f 951
99706f30
SR
952 /* Drop unwanted bits from the value we are relocating to. */
953 Rvalue >>= (bfd_vma) howto->rightshift;
3d3d428f 954
99706f30
SR
955 /* Apply dst_mask to select only relocatable part of the insn. */
956 Rvalue &= howto->dst_mask;
957 }
3d3d428f
NC
958
959 switch (howto->size)
960 {
961 case 0:
07d6d2b8
AM
962 if (r_type == R_CR16_DISP8)
963 {
964 Rvalue1 = bfd_get_16 (input_bfd, hit_data);
965 Rvalue = ((Rvalue1 & 0xf000) | ((Rvalue << 4) & 0xf00)
966 | (Rvalue1 & 0x00f0) | (Rvalue & 0xf));
967 bfd_put_16 (input_bfd, Rvalue, hit_data);
968 }
969 else if (r_type == R_CR16_IMM4)
970 {
971 Rvalue1 = bfd_get_16 (input_bfd, hit_data);
972 Rvalue = (((Rvalue1 & 0xff) << 8) | ((Rvalue << 4) & 0xf0)
973 | ((Rvalue1 & 0x0f00) >> 8));
974 bfd_put_16 (input_bfd, Rvalue, hit_data);
975 }
976 else if (r_type == R_CR16_DISP4)
977 {
978 Rvalue1 = bfd_get_16 (input_bfd, hit_data);
979 Rvalue = (Rvalue1 | ((Rvalue & 0xf) << 4));
980 bfd_put_16 (input_bfd, Rvalue, hit_data);
981 }
982 else
983 {
984 bfd_put_8 (input_bfd, (unsigned char) Rvalue, hit_data);
985 }
986 break;
3d3d428f
NC
987
988 case 1:
07d6d2b8
AM
989 if (r_type == R_CR16_DISP16)
990 {
991 Rvalue |= (bfd_get_16 (input_bfd, hit_data));
992 Rvalue = ((Rvalue & 0xfffe) | ((Rvalue >> 16) & 0x1));
993 }
994 if (r_type == R_CR16_IMM16)
995 {
996 Rvalue1 = bfd_get_16 (input_bfd, hit_data);
997
998 /* Add or subtract the offset value. */
999 if (Rvalue1 & 0x8000)
1000 Rvalue -= (~Rvalue1 + 1) & 0xffff;
1001 else
1002 Rvalue += Rvalue1;
1003
1004 /* Check for range. */
1005 if ((long) Rvalue > 0xffff || (long) Rvalue < 0x0)
1006 return bfd_reloc_overflow;
1007 }
1008
1009 bfd_put_16 (input_bfd, Rvalue, hit_data);
1010 break;
3d3d428f
NC
1011
1012 case 2:
07d6d2b8
AM
1013 if ((r_type == R_CR16_ABS20) || (r_type == R_CR16_IMM20))
1014 {
1015 Rvalue1 = (bfd_get_16 (input_bfd, hit_data + 2)
1016 | (((bfd_get_16 (input_bfd, hit_data) & 0xf) <<16)));
1017
1018 /* Add or subtract the offset value. */
1019 if (Rvalue1 & 0x80000)
1020 Rvalue -= (~Rvalue1 + 1) & 0xfffff;
1021 else
1022 Rvalue += Rvalue1;
1023
1024 /* Check for range. */
1025 if ((long) Rvalue > 0xfffff || (long) Rvalue < 0x0)
1026 return bfd_reloc_overflow;
1027
1028 bfd_put_16 (input_bfd, ((bfd_get_16 (input_bfd, hit_data) & 0xfff0)
1029 | ((Rvalue >> 16) & 0xf)), hit_data);
1030 bfd_put_16 (input_bfd, (Rvalue) & 0xffff, hit_data + 2);
1031 }
1032 else if (r_type == R_CR16_GOT_REGREL20)
1033 {
1034 asection *sgot = elf_hash_table (info)->sgot;
1035
1036 if (h != NULL)
1037 {
1038 bfd_vma off;
1039
1040 off = h->got.offset;
1041 BFD_ASSERT (off != (bfd_vma) -1);
1042
1043 if (! elf_hash_table (info)->dynamic_sections_created
1044 || SYMBOL_REFERENCES_LOCAL (info, h))
1045 /* This is actually a static link, or it is a
1046 -Bsymbolic link and the symbol is defined
1047 locally, or the symbol was forced to be local
1048 because of a version file. We must initialize
1049 this entry in the global offset table.
1050 When doing a dynamic link, we create a .rela.got
1051 relocation entry to initialize the value. This
1052 is done in the finish_dynamic_symbol routine. */
1053 bfd_put_32 (output_bfd, Rvalue, sgot->contents + off);
1054
1055 Rvalue = sgot->output_offset + off;
1056 }
1057 else
1058 {
1059 bfd_vma off;
1060
1061 off = elf_local_got_offsets (input_bfd)[symndx];
1062 bfd_put_32 (output_bfd,Rvalue, sgot->contents + off);
1063
1064 Rvalue = sgot->output_offset + off;
1065 }
1066
1067 Rvalue += addend;
1068
1069 /* REVISIT: if ((long) Rvalue > 0xffffff ||
1070 (long) Rvalue < -0x800000). */
1071 if ((long) Rvalue > 0xffffff || (long) Rvalue < 0)
1072 return bfd_reloc_overflow;
1073
1074
1075 bfd_put_16 (input_bfd, (bfd_get_16 (input_bfd, hit_data))
1076 | (((Rvalue >> 16) & 0xf) << 8), hit_data);
1077 bfd_put_16 (input_bfd, (Rvalue) & 0xffff, hit_data + 2);
1078
1079 }
1080 else if (r_type == R_CR16_GOTC_REGREL20)
1081 {
1082 asection *sgot = elf_hash_table (info)->sgot;
1083
1084 if (h != NULL)
1085 {
1086 bfd_vma off;
1087
1088 off = h->got.offset;
1089 BFD_ASSERT (off != (bfd_vma) -1);
1090
1091 Rvalue >>=1; /* For code symbols. */
1092
1093 if (! elf_hash_table (info)->dynamic_sections_created
1094 || SYMBOL_REFERENCES_LOCAL (info, h))
1095 /* This is actually a static link, or it is a
1096 -Bsymbolic link and the symbol is defined
1097 locally, or the symbol was forced to be local
1098 because of a version file. We must initialize
1099 this entry in the global offset table.
1100 When doing a dynamic link, we create a .rela.got
1101 relocation entry to initialize the value. This
1102 is done in the finish_dynamic_symbol routine. */
1103 bfd_put_32 (output_bfd, Rvalue, sgot->contents + off);
1104
1105 Rvalue = sgot->output_offset + off;
1106 }
1107 else
1108 {
1109 bfd_vma off;
1110
1111 off = elf_local_got_offsets (input_bfd)[symndx];
1112 Rvalue >>= 1;
1113 bfd_put_32 (output_bfd,Rvalue, sgot->contents + off);
1114 Rvalue = sgot->output_offset + off;
1115 }
1116
1117 Rvalue += addend;
1118
1119 /* Check if any value in DISP. */
1120 Rvalue1 =((bfd_get_32 (input_bfd, hit_data) >>16)
1121 | (((bfd_get_32 (input_bfd, hit_data) & 0xfff) >> 8) <<16));
1122
1123 /* Add or subtract the offset value. */
1124 if (Rvalue1 & 0x80000)
1125 Rvalue -= (~Rvalue1 + 1) & 0xfffff;
1126 else
1127 Rvalue += Rvalue1;
1128
1129 /* Check for range. */
1130 /* REVISIT: if ((long) Rvalue > 0xffffff
1131 || (long) Rvalue < -0x800000). */
1132 if ((long) Rvalue > 0xffffff || (long) Rvalue < 0)
1133 return bfd_reloc_overflow;
1134
1135 bfd_put_16 (input_bfd, (bfd_get_16 (input_bfd, hit_data))
1136 | (((Rvalue >> 16) & 0xf) << 8), hit_data);
1137 bfd_put_16 (input_bfd, (Rvalue) & 0xffff, hit_data + 2);
1138 }
1139 else
1140 {
1141 if (r_type == R_CR16_ABS24)
1142 {
1143 Rvalue1 = ((bfd_get_32 (input_bfd, hit_data) >> 16)
1144 | (((bfd_get_32 (input_bfd, hit_data) & 0xfff) >> 8) <<16)
1145 | (((bfd_get_32 (input_bfd, hit_data) & 0xf) <<20)));
1146
1147 /* Add or subtract the offset value. */
1148 if (Rvalue1 & 0x800000)
1149 Rvalue -= (~Rvalue1 + 1) & 0xffffff;
1150 else
1151 Rvalue += Rvalue1;
1152
1153 /* Check for Range. */
1154 if ((long) Rvalue > 0xffffff || (long) Rvalue < 0x0)
1155 return bfd_reloc_overflow;
1156
1157 Rvalue = ((((Rvalue >> 20) & 0xf) | (((Rvalue >> 16) & 0xf)<<8)
1158 | (bfd_get_32 (input_bfd, hit_data) & 0xf0f0))
1159 | ((Rvalue & 0xffff) << 16));
1160 }
1161 else if (r_type == R_CR16_DISP24)
1162 {
1163 Rvalue = ((((Rvalue >> 20)& 0xf) | (((Rvalue >>16) & 0xf)<<8)
1164 | (bfd_get_16 (input_bfd, hit_data)))
1165 | (((Rvalue & 0xfffe) | ((Rvalue >> 24) & 0x1)) << 16));
1166 }
1167 else if ((r_type == R_CR16_IMM32) || (r_type == R_CR16_IMM32a))
1168 {
1169 Rvalue1 =((((bfd_get_32 (input_bfd, hit_data)) >> 16) &0xffff)
1170 | (((bfd_get_32 (input_bfd, hit_data)) &0xffff)) << 16);
1171
1172 /* Add or subtract the offset value. */
1173 if (Rvalue1 & 0x80000000)
1174 Rvalue -= (~Rvalue1 + 1) & 0xffffffff;
1175 else
1176 Rvalue += Rvalue1;
1177
1178 /* Check for range. */
1179 if (Rvalue > 0xffffffff || (long) Rvalue < 0x0)
1180 return bfd_reloc_overflow;
1181
1182 Rvalue = (((Rvalue >> 16)& 0xffff) | (Rvalue & 0xffff) << 16);
1183 }
1184 else if (r_type == R_CR16_DISP24a)
1185 {
1186 Rvalue = (((Rvalue & 0xfffffe) | (Rvalue >> 23)));
1187 Rvalue = ((Rvalue >> 16) & 0xff) | ((Rvalue & 0xffff) << 16)
1188 | (bfd_get_32 (input_bfd, hit_data));
1189 }
1190 else if ((r_type == R_CR16_REGREL20)
1191 || (r_type == R_CR16_REGREL20a))
1192 {
1193 Rvalue1 = ((bfd_get_32 (input_bfd, hit_data) >> 16)
1194 | (((bfd_get_32 (input_bfd, hit_data) & 0xfff) >> 8) <<16));
1195 /* Add or subtract the offset value. */
1196 if (Rvalue1 & 0x80000)
1197 Rvalue -= (~Rvalue1 + 1) & 0xfffff;
1198 else
1199 Rvalue += Rvalue1;
1200
1201 /* Check for range. */
1202 if ((long) Rvalue > 0xfffff || (long) Rvalue < 0x0)
1203 return bfd_reloc_overflow;
1204
1205 Rvalue = (((((Rvalue >> 20)& 0xf) | (((Rvalue >>16) & 0xf)<<8)
1206 | ((Rvalue & 0xffff) << 16)))
1207 | (bfd_get_32 (input_bfd, hit_data) & 0xf0ff));
1208
1209 }
1210 else if (r_type == R_CR16_NUM32)
1211 {
1212 Rvalue1 = (bfd_get_32 (input_bfd, hit_data));
1213
1214 /* Add or subtract the offset value */
1215 if (Rvalue1 & 0x80000000)
1216 Rvalue -= (~Rvalue1 + 1) & 0xffffffff;
1217 else
1218 Rvalue += Rvalue1;
1219
1220 /* Check for Ranga */
1221 if (Rvalue > 0xffffffff)
1222 return bfd_reloc_overflow;
1223 }
1224
1225 bfd_put_32 (input_bfd, Rvalue, hit_data);
1226 }
1227 break;
3d3d428f
NC
1228
1229 default:
07d6d2b8 1230 return bfd_reloc_notsupported;
3d3d428f
NC
1231 }
1232
1233 return bfd_reloc_ok;
1234}
1235
1236/* Delete some bytes from a section while relaxing. */
1237
1238static bfd_boolean
1239elf32_cr16_relax_delete_bytes (struct bfd_link_info *link_info, bfd *abfd,
07d6d2b8 1240 asection *sec, bfd_vma addr, int count)
3d3d428f
NC
1241{
1242 Elf_Internal_Shdr *symtab_hdr;
1243 unsigned int sec_shndx;
1244 bfd_byte *contents;
1245 Elf_Internal_Rela *irel, *irelend;
3d3d428f
NC
1246 bfd_vma toaddr;
1247 Elf_Internal_Sym *isym;
1248 Elf_Internal_Sym *isymend;
1249 struct elf_link_hash_entry **sym_hashes;
1250 struct elf_link_hash_entry **end_hashes;
1251 struct elf_link_hash_entry **start_hashes;
1252 unsigned int symcount;
1253
1254 sec_shndx = _bfd_elf_section_from_bfd_section (abfd, sec);
1255
1256 contents = elf_section_data (sec)->this_hdr.contents;
1257
3d3d428f
NC
1258 toaddr = sec->size;
1259
1260 irel = elf_section_data (sec)->relocs;
1261 irelend = irel + sec->reloc_count;
1262
1263 /* Actually delete the bytes. */
1264 memmove (contents + addr, contents + addr + count,
07d6d2b8 1265 (size_t) (toaddr - addr - count));
3d3d428f
NC
1266 sec->size -= count;
1267
1268 /* Adjust all the relocs. */
1269 for (irel = elf_section_data (sec)->relocs; irel < irelend; irel++)
1270 /* Get the new reloc address. */
1271 if ((irel->r_offset > addr && irel->r_offset < toaddr))
07d6d2b8 1272 irel->r_offset -= count;
3d3d428f
NC
1273
1274 /* Adjust the local symbols defined in this section. */
1275 symtab_hdr = &elf_tdata (abfd)->symtab_hdr;
1276 isym = (Elf_Internal_Sym *) symtab_hdr->contents;
1277 for (isymend = isym + symtab_hdr->sh_info; isym < isymend; isym++)
1278 {
1279 if (isym->st_shndx == sec_shndx
07d6d2b8
AM
1280 && isym->st_value > addr
1281 && isym->st_value < toaddr)
1282 {
1283 /* Adjust the addend of SWITCH relocations in this section,
1284 which reference this local symbol. */
99706f30 1285#if 0
07d6d2b8
AM
1286 for (irel = elf_section_data (sec)->relocs; irel < irelend; irel++)
1287 {
1288 unsigned long r_symndx;
1289 Elf_Internal_Sym *rsym;
1290 bfd_vma addsym, subsym;
1291
1292 /* Skip if not a SWITCH relocation. */
1293 if (ELF32_R_TYPE (irel->r_info) != (int) R_CR16_SWITCH8
1294 && ELF32_R_TYPE (irel->r_info) != (int) R_CR16_SWITCH16
1295 && ELF32_R_TYPE (irel->r_info) != (int) R_CR16_SWITCH32)
1296 continue;
1297
1298 r_symndx = ELF32_R_SYM (irel->r_info);
1299 rsym = (Elf_Internal_Sym *) symtab_hdr->contents + r_symndx;
1300
1301 /* Skip if not the local adjusted symbol. */
1302 if (rsym != isym)
1303 continue;
1304
1305 addsym = isym->st_value;
1306 subsym = addsym - irel->r_addend;
1307
1308 /* Fix the addend only when -->> (addsym > addr >= subsym). */
1309 if (subsym <= addr)
1310 irel->r_addend -= count;
1311 else
1312 continue;
1313 }
99706f30 1314#endif
3d3d428f 1315
07d6d2b8
AM
1316 isym->st_value -= count;
1317 }
3d3d428f
NC
1318 }
1319
1320 /* Now adjust the global symbols defined in this section. */
1321 symcount = (symtab_hdr->sh_size / sizeof (Elf32_External_Sym)
07d6d2b8 1322 - symtab_hdr->sh_info);
3d3d428f
NC
1323 sym_hashes = start_hashes = elf_sym_hashes (abfd);
1324 end_hashes = sym_hashes + symcount;
1325
1326 for (; sym_hashes < end_hashes; sym_hashes++)
1327 {
1328 struct elf_link_hash_entry *sym_hash = *sym_hashes;
1329
1330 /* The '--wrap SYMBOL' option is causing a pain when the object file,
07d6d2b8
AM
1331 containing the definition of __wrap_SYMBOL, includes a direct
1332 call to SYMBOL as well. Since both __wrap_SYMBOL and SYMBOL reference
1333 the same symbol (which is __wrap_SYMBOL), but still exist as two
1334 different symbols in 'sym_hashes', we don't want to adjust
1335 the global symbol __wrap_SYMBOL twice.
1336 This check is only relevant when symbols are being wrapped. */
3d3d428f 1337 if (link_info->wrap_hash != NULL)
07d6d2b8
AM
1338 {
1339 struct elf_link_hash_entry **cur_sym_hashes;
1340
1341 /* Loop only over the symbols whom been already checked. */
1342 for (cur_sym_hashes = start_hashes; cur_sym_hashes < sym_hashes;
1343 cur_sym_hashes++)
1344 /* If the current symbol is identical to 'sym_hash', that means
1345 the symbol was already adjusted (or at least checked). */
1346 if (*cur_sym_hashes == sym_hash)
1347 break;
1348
1349 /* Don't adjust the symbol again. */
1350 if (cur_sym_hashes < sym_hashes)
1351 continue;
1352 }
3d3d428f
NC
1353
1354 if ((sym_hash->root.type == bfd_link_hash_defined
07d6d2b8
AM
1355 || sym_hash->root.type == bfd_link_hash_defweak)
1356 && sym_hash->root.u.def.section == sec
1357 && sym_hash->root.u.def.value > addr
1358 && sym_hash->root.u.def.value < toaddr)
1359 sym_hash->root.u.def.value -= count;
3d3d428f
NC
1360 }
1361
1362 return TRUE;
1363}
1364
1365/* Relocate a CR16 ELF section. */
1366
1367static bfd_boolean
1368elf32_cr16_relocate_section (bfd *output_bfd, struct bfd_link_info *info,
07d6d2b8
AM
1369 bfd *input_bfd, asection *input_section,
1370 bfd_byte *contents, Elf_Internal_Rela *relocs,
1371 Elf_Internal_Sym *local_syms,
1372 asection **local_sections)
3d3d428f
NC
1373{
1374 Elf_Internal_Shdr *symtab_hdr;
1375 struct elf_link_hash_entry **sym_hashes;
1376 Elf_Internal_Rela *rel, *relend;
1377
3d3d428f
NC
1378 symtab_hdr = &elf_tdata (input_bfd)->symtab_hdr;
1379 sym_hashes = elf_sym_hashes (input_bfd);
1380
1381 rel = relocs;
1382 relend = relocs + input_section->reloc_count;
1383 for (; rel < relend; rel++)
1384 {
1385 int r_type;
1386 reloc_howto_type *howto;
1387 unsigned long r_symndx;
1388 Elf_Internal_Sym *sym;
1389 asection *sec;
1390 struct elf_link_hash_entry *h;
1391 bfd_vma relocation;
1392 bfd_reloc_status_type r;
1393
1394 r_symndx = ELF32_R_SYM (rel->r_info);
1395 r_type = ELF32_R_TYPE (rel->r_info);
1396 howto = cr16_elf_howto_table + (r_type);
1397
1398 h = NULL;
1399 sym = NULL;
1400 sec = NULL;
1401 if (r_symndx < symtab_hdr->sh_info)
07d6d2b8
AM
1402 {
1403 sym = local_syms + r_symndx;
1404 sec = local_sections[r_symndx];
1405 relocation = _bfd_elf_rela_local_sym (output_bfd, sym, &sec, rel);
1406 }
3d3d428f 1407 else
07d6d2b8
AM
1408 {
1409 bfd_boolean unresolved_reloc, warned, ignored;
3d3d428f 1410
07d6d2b8
AM
1411 RELOC_FOR_GLOBAL_SYMBOL (info, input_bfd, input_section, rel,
1412 r_symndx, symtab_hdr, sym_hashes,
1413 h, sec, relocation,
1414 unresolved_reloc, warned, ignored);
1415 }
3d3d428f 1416
dbaa2011 1417 if (sec != NULL && discarded_section (sec))
e4067dbb 1418 RELOC_AGAINST_DISCARDED_SECTION (info, input_bfd, input_section,
545fd46b 1419 rel, 1, relend, howto, 0, contents);
1004c3e1 1420
0e1862bb 1421 if (bfd_link_relocatable (info))
07d6d2b8 1422 continue;
1004c3e1 1423
3d3d428f 1424 r = cr16_elf_final_link_relocate (howto, input_bfd, output_bfd,
07d6d2b8
AM
1425 input_section,
1426 contents, rel->r_offset,
1427 relocation, rel->r_addend,
1428 (struct elf_link_hash_entry *) h,
1429 r_symndx,
1430 info, sec, h == NULL);
3d3d428f
NC
1431
1432 if (r != bfd_reloc_ok)
07d6d2b8
AM
1433 {
1434 const char *name;
1435 const char *msg = NULL;
1436
1437 if (h != NULL)
1438 name = h->root.root.string;
1439 else
1440 {
1441 name = (bfd_elf_string_from_elf_section
1442 (input_bfd, symtab_hdr->sh_link, sym->st_name));
1443 if (name == NULL || *name == '\0')
fd361982 1444 name = bfd_section_name (sec);
07d6d2b8
AM
1445 }
1446
1447 switch (r)
1448 {
1449 case bfd_reloc_overflow:
1a72702b
AM
1450 (*info->callbacks->reloc_overflow)
1451 (info, (h ? &h->root : NULL), name, howto->name,
1452 (bfd_vma) 0, input_bfd, input_section, rel->r_offset);
07d6d2b8 1453 break;
3d3d428f 1454
07d6d2b8 1455 case bfd_reloc_undefined:
1a72702b
AM
1456 (*info->callbacks->undefined_symbol)
1457 (info, name, input_bfd, input_section, rel->r_offset, TRUE);
07d6d2b8 1458 break;
3d3d428f 1459
07d6d2b8
AM
1460 case bfd_reloc_outofrange:
1461 msg = _("internal error: out of range error");
1462 goto common_error;
3d3d428f 1463
07d6d2b8
AM
1464 case bfd_reloc_notsupported:
1465 msg = _("internal error: unsupported relocation error");
1466 goto common_error;
3d3d428f 1467
07d6d2b8
AM
1468 case bfd_reloc_dangerous:
1469 msg = _("internal error: dangerous error");
1470 goto common_error;
3d3d428f 1471
07d6d2b8
AM
1472 default:
1473 msg = _("internal error: unknown error");
1474 /* Fall through. */
3d3d428f 1475
07d6d2b8 1476 common_error:
1a72702b
AM
1477 (*info->callbacks->warning) (info, msg, name, input_bfd,
1478 input_section, rel->r_offset);
07d6d2b8
AM
1479 break;
1480 }
1481 }
3d3d428f
NC
1482 }
1483
1484 return TRUE;
1485}
1486
1487/* This is a version of bfd_generic_get_relocated_section_contents
1488 which uses elf32_cr16_relocate_section. */
1489
1490static bfd_byte *
1491elf32_cr16_get_relocated_section_contents (bfd *output_bfd,
07d6d2b8
AM
1492 struct bfd_link_info *link_info,
1493 struct bfd_link_order *link_order,
1494 bfd_byte *data,
1495 bfd_boolean relocatable,
1496 asymbol **symbols)
3d3d428f
NC
1497{
1498 Elf_Internal_Shdr *symtab_hdr;
1499 asection *input_section = link_order->u.indirect.section;
1500 bfd *input_bfd = input_section->owner;
1501 asection **sections = NULL;
1502 Elf_Internal_Rela *internal_relocs = NULL;
1503 Elf_Internal_Sym *isymbuf = NULL;
1504
1505 /* We only need to handle the case of relaxing, or of having a
1506 particular set of section contents, specially. */
1507 if (relocatable
1508 || elf_section_data (input_section)->this_hdr.contents == NULL)
1509 return bfd_generic_get_relocated_section_contents (output_bfd, link_info,
07d6d2b8
AM
1510 link_order, data,
1511 relocatable,
1512 symbols);
3d3d428f
NC
1513
1514 symtab_hdr = &elf_tdata (input_bfd)->symtab_hdr;
1515
1516 memcpy (data, elf_section_data (input_section)->this_hdr.contents,
07d6d2b8 1517 (size_t) input_section->size);
3d3d428f
NC
1518
1519 if ((input_section->flags & SEC_RELOC) != 0
1520 && input_section->reloc_count > 0)
1521 {
1522 Elf_Internal_Sym *isym;
1523 Elf_Internal_Sym *isymend;
1524 asection **secpp;
1525 bfd_size_type amt;
1526
1527 internal_relocs = _bfd_elf_link_read_relocs (input_bfd, input_section,
07d6d2b8 1528 NULL, NULL, FALSE);
3d3d428f 1529 if (internal_relocs == NULL)
07d6d2b8 1530 goto error_return;
3d3d428f
NC
1531
1532 if (symtab_hdr->sh_info != 0)
07d6d2b8
AM
1533 {
1534 isymbuf = (Elf_Internal_Sym *) symtab_hdr->contents;
1535 if (isymbuf == NULL)
1536 isymbuf = bfd_elf_get_elf_syms (input_bfd, symtab_hdr,
1537 symtab_hdr->sh_info, 0,
1538 NULL, NULL, NULL);
1539 if (isymbuf == NULL)
1540 goto error_return;
1541 }
3d3d428f
NC
1542
1543 amt = symtab_hdr->sh_info;
1544 amt *= sizeof (asection *);
1545 sections = bfd_malloc (amt);
1546 if (sections == NULL && amt != 0)
07d6d2b8 1547 goto error_return;
3d3d428f
NC
1548
1549 isymend = isymbuf + symtab_hdr->sh_info;
1550 for (isym = isymbuf, secpp = sections; isym < isymend; ++isym, ++secpp)
07d6d2b8
AM
1551 {
1552 asection *isec;
3d3d428f 1553
07d6d2b8
AM
1554 if (isym->st_shndx == SHN_UNDEF)
1555 isec = bfd_und_section_ptr;
1556 else if (isym->st_shndx == SHN_ABS)
1557 isec = bfd_abs_section_ptr;
1558 else if (isym->st_shndx == SHN_COMMON)
1559 isec = bfd_com_section_ptr;
1560 else
1561 isec = bfd_section_from_elf_index (input_bfd, isym->st_shndx);
3d3d428f 1562
07d6d2b8
AM
1563 *secpp = isec;
1564 }
3d3d428f
NC
1565
1566 if (! elf32_cr16_relocate_section (output_bfd, link_info, input_bfd,
07d6d2b8
AM
1567 input_section, data, internal_relocs,
1568 isymbuf, sections))
1569 goto error_return;
3d3d428f 1570
c9594989
AM
1571 free (sections);
1572 if (symtab_hdr->contents != (unsigned char *) isymbuf)
07d6d2b8 1573 free (isymbuf);
3d3d428f 1574 if (elf_section_data (input_section)->relocs != internal_relocs)
07d6d2b8 1575 free (internal_relocs);
3d3d428f
NC
1576 }
1577
1578 return data;
1579
1580 error_return:
c9594989
AM
1581 free (sections);
1582 if (symtab_hdr->contents != (unsigned char *) isymbuf)
3d3d428f 1583 free (isymbuf);
c9594989 1584 if (elf_section_data (input_section)->relocs != internal_relocs)
3d3d428f
NC
1585 free (internal_relocs);
1586 return NULL;
1587}
1588
99706f30
SR
1589/* Assorted hash table functions. */
1590
1591/* Initialize an entry in the link hash table. */
1592
1593/* Create an entry in an CR16 ELF linker hash table. */
1594
1595static struct bfd_hash_entry *
1596elf32_cr16_link_hash_newfunc (struct bfd_hash_entry *entry,
07d6d2b8
AM
1597 struct bfd_hash_table *table,
1598 const char *string)
99706f30
SR
1599{
1600 struct elf32_cr16_link_hash_entry *ret =
1601 (struct elf32_cr16_link_hash_entry *) entry;
1602
1603 /* Allocate the structure if it has not already been allocated by a
1604 subclass. */
1605 if (ret == (struct elf32_cr16_link_hash_entry *) NULL)
1606 ret = ((struct elf32_cr16_link_hash_entry *)
07d6d2b8
AM
1607 bfd_hash_allocate (table,
1608 sizeof (struct elf32_cr16_link_hash_entry)));
99706f30
SR
1609 if (ret == (struct elf32_cr16_link_hash_entry *) NULL)
1610 return (struct bfd_hash_entry *) ret;
1611
1612 /* Call the allocation method of the superclass. */
1613 ret = ((struct elf32_cr16_link_hash_entry *)
07d6d2b8
AM
1614 _bfd_elf_link_hash_newfunc ((struct bfd_hash_entry *) ret,
1615 table, string));
99706f30
SR
1616 if (ret != (struct elf32_cr16_link_hash_entry *) NULL)
1617 {
1618 ret->direct_calls = 0;
1619 ret->stack_size = 0;
1620 ret->movm_args = 0;
1621 ret->movm_stack_size = 0;
1622 ret->flags = 0;
1623 ret->value = 0;
1624 }
1625
1626 return (struct bfd_hash_entry *) ret;
1627}
1628
1629/* Create an cr16 ELF linker hash table. */
1630
1631static struct bfd_link_hash_table *
1632elf32_cr16_link_hash_table_create (bfd *abfd)
1633{
4dfe6ac6 1634 struct elf_link_hash_table *ret;
986f0783 1635 size_t amt = sizeof (struct elf_link_hash_table);
99706f30 1636
7bf52ea2 1637 ret = (struct elf_link_hash_table *) bfd_zmalloc (amt);
4dfe6ac6 1638 if (ret == (struct elf_link_hash_table *) NULL)
99706f30
SR
1639 return NULL;
1640
4dfe6ac6 1641 if (!_bfd_elf_link_hash_table_init (ret, abfd,
07d6d2b8
AM
1642 elf32_cr16_link_hash_newfunc,
1643 sizeof (struct elf32_cr16_link_hash_entry),
4dfe6ac6 1644 GENERIC_ELF_DATA))
99706f30
SR
1645 {
1646 free (ret);
1647 return NULL;
1648 }
1649
4dfe6ac6 1650 return &ret->root;
99706f30
SR
1651}
1652
99706f30
SR
1653static unsigned long
1654elf_cr16_mach (flagword flags)
1655{
1656 switch (flags)
1657 {
1658 case EM_CR16:
1659 default:
1660 return bfd_mach_cr16;
1661 }
1662}
1663
1664/* The final processing done just before writing out a CR16 ELF object
1665 file. This gets the CR16 architecture right based on the machine
1666 number. */
1667
cc364be6
AM
1668static bfd_boolean
1669_bfd_cr16_elf_final_write_processing (bfd *abfd)
99706f30
SR
1670{
1671 unsigned long val;
1672 switch (bfd_get_mach (abfd))
1673 {
1674 default:
1675 case bfd_mach_cr16:
07d6d2b8
AM
1676 val = EM_CR16;
1677 break;
99706f30 1678 }
cc364be6
AM
1679 elf_elfheader (abfd)->e_flags |= val;
1680 return _bfd_elf_final_write_processing (abfd);
99706f30
SR
1681}
1682
1683
1684static bfd_boolean
1685_bfd_cr16_elf_object_p (bfd *abfd)
1686{
1687 bfd_default_set_arch_mach (abfd, bfd_arch_cr16,
07d6d2b8 1688 elf_cr16_mach (elf_elfheader (abfd)->e_flags));
99706f30
SR
1689 return TRUE;
1690}
1691
1692/* Merge backend specific data from an object file to the output
1693 object file when linking. */
1694
1695static bfd_boolean
50e03d47 1696_bfd_cr16_elf_merge_private_bfd_data (bfd *ibfd, struct bfd_link_info *info)
99706f30 1697{
50e03d47
AM
1698 bfd *obfd = info->output_bfd;
1699
99706f30
SR
1700 if (bfd_get_flavour (ibfd) != bfd_target_elf_flavour
1701 || bfd_get_flavour (obfd) != bfd_target_elf_flavour)
1702 return TRUE;
1703
1704 if (bfd_get_arch (obfd) == bfd_get_arch (ibfd)
1705 && bfd_get_mach (obfd) < bfd_get_mach (ibfd))
1706 {
1707 if (! bfd_set_arch_mach (obfd, bfd_get_arch (ibfd),
07d6d2b8
AM
1708 bfd_get_mach (ibfd)))
1709 return FALSE;
99706f30
SR
1710 }
1711
1712 return TRUE;
1713}
1714
1715
3d3d428f
NC
1716/* This function handles relaxing for the CR16.
1717
1718 There's quite a few relaxing opportunites available on the CR16:
1719
07d6d2b8
AM
1720 * bcond:24 -> bcond:16 1 byte
1721 * bcond:16 -> bcond:8 1 byte
1722 * arithmetic imm32 -> arithmetic imm20 12 bits
1723 * arithmetic imm20/imm16 -> arithmetic imm4 12/16 bits
3d3d428f
NC
1724
1725 Symbol- and reloc-reading infrastructure copied from elf-m10200.c. */
1726
1727static bfd_boolean
1728elf32_cr16_relax_section (bfd *abfd, asection *sec,
07d6d2b8 1729 struct bfd_link_info *link_info, bfd_boolean *again)
3d3d428f
NC
1730{
1731 Elf_Internal_Shdr *symtab_hdr;
1732 Elf_Internal_Rela *internal_relocs;
1733 Elf_Internal_Rela *irel, *irelend;
1734 bfd_byte *contents = NULL;
1735 Elf_Internal_Sym *isymbuf = NULL;
1736
1737 /* Assume nothing changes. */
1738 *again = FALSE;
1739
1740 /* We don't have to do anything for a relocatable link, if
1741 this section does not have relocs, or if this is not a
1742 code section. */
0e1862bb 1743 if (bfd_link_relocatable (link_info)
3d3d428f
NC
1744 || (sec->flags & SEC_RELOC) == 0
1745 || sec->reloc_count == 0
1746 || (sec->flags & SEC_CODE) == 0)
1747 return TRUE;
1748
1749 symtab_hdr = &elf_tdata (abfd)->symtab_hdr;
1750
1751 /* Get a copy of the native relocations. */
1752 internal_relocs = _bfd_elf_link_read_relocs (abfd, sec, NULL, NULL,
07d6d2b8 1753 link_info->keep_memory);
3d3d428f
NC
1754 if (internal_relocs == NULL)
1755 goto error_return;
1756
1757 /* Walk through them looking for relaxing opportunities. */
1758 irelend = internal_relocs + sec->reloc_count;
1759 for (irel = internal_relocs; irel < irelend; irel++)
1760 {
1761 bfd_vma symval;
1762
1763 /* If this isn't something that can be relaxed, then ignore
07d6d2b8 1764 this reloc. */
3d3d428f 1765 if (ELF32_R_TYPE (irel->r_info) != (int) R_CR16_DISP16
07d6d2b8
AM
1766 && ELF32_R_TYPE (irel->r_info) != (int) R_CR16_DISP24
1767 && ELF32_R_TYPE (irel->r_info) != (int) R_CR16_IMM32
1768 && ELF32_R_TYPE (irel->r_info) != (int) R_CR16_IMM20
1769 && ELF32_R_TYPE (irel->r_info) != (int) R_CR16_IMM16)
1770 continue;
3d3d428f
NC
1771
1772 /* Get the section contents if we haven't done so already. */
1773 if (contents == NULL)
07d6d2b8
AM
1774 {
1775 /* Get cached copy if it exists. */
1776 if (elf_section_data (sec)->this_hdr.contents != NULL)
1777 contents = elf_section_data (sec)->this_hdr.contents;
1778 /* Go get them off disk. */
1779 else if (!bfd_malloc_and_get_section (abfd, sec, &contents))
1780 goto error_return;
1781 }
3d3d428f
NC
1782
1783 /* Read this BFD's local symbols if we haven't done so already. */
1784 if (isymbuf == NULL && symtab_hdr->sh_info != 0)
07d6d2b8
AM
1785 {
1786 isymbuf = (Elf_Internal_Sym *) symtab_hdr->contents;
1787 if (isymbuf == NULL)
1788 isymbuf = bfd_elf_get_elf_syms (abfd, symtab_hdr,
1789 symtab_hdr->sh_info, 0,
1790 NULL, NULL, NULL);
1791 if (isymbuf == NULL)
1792 goto error_return;
1793 }
3d3d428f
NC
1794
1795 /* Get the value of the symbol referred to by the reloc. */
1796 if (ELF32_R_SYM (irel->r_info) < symtab_hdr->sh_info)
07d6d2b8
AM
1797 {
1798 /* A local symbol. */
1799 Elf_Internal_Sym *isym;
1800 asection *sym_sec;
1801
1802 isym = isymbuf + ELF32_R_SYM (irel->r_info);
1803 if (isym->st_shndx == SHN_UNDEF)
1804 sym_sec = bfd_und_section_ptr;
1805 else if (isym->st_shndx == SHN_ABS)
1806 sym_sec = bfd_abs_section_ptr;
1807 else if (isym->st_shndx == SHN_COMMON)
1808 sym_sec = bfd_com_section_ptr;
1809 else
1810 sym_sec = bfd_section_from_elf_index (abfd, isym->st_shndx);
1811 symval = (isym->st_value
1812 + sym_sec->output_section->vma
1813 + sym_sec->output_offset);
1814 }
3d3d428f 1815 else
07d6d2b8
AM
1816 {
1817 unsigned long indx;
1818 struct elf_link_hash_entry *h;
1819
1820 /* An external symbol. */
1821 indx = ELF32_R_SYM (irel->r_info) - symtab_hdr->sh_info;
1822 h = elf_sym_hashes (abfd)[indx];
1823 BFD_ASSERT (h != NULL);
1824
1825 if (h->root.type != bfd_link_hash_defined
1826 && h->root.type != bfd_link_hash_defweak)
1827 /* This appears to be a reference to an undefined
1828 symbol. Just ignore it--it will be caught by the
1829 regular reloc processing. */
1830 continue;
1831
1832 symval = (h->root.u.def.value
1833 + h->root.u.def.section->output_section->vma
1834 + h->root.u.def.section->output_offset);
1835 }
3d3d428f
NC
1836
1837 /* For simplicity of coding, we are going to modify the section
07d6d2b8
AM
1838 contents, the section relocs, and the BFD symbol table. We
1839 must tell the rest of the code not to free up this
1840 information. It would be possible to instead create a table
1841 of changes which have to be made, as is done in coff-mips.c;
1842 that would be more work, but would require less memory when
1843 the linker is run. */
3d3d428f
NC
1844
1845 /* Try to turn a 24 branch/call into a 16bit relative
07d6d2b8 1846 branch/call. */
3d3d428f 1847 if (ELF32_R_TYPE (irel->r_info) == (int) R_CR16_DISP24)
07d6d2b8
AM
1848 {
1849 bfd_vma value = symval;
1850
1851 /* Deal with pc-relative gunk. */
1852 value -= (sec->output_section->vma + sec->output_offset);
1853 value -= irel->r_offset;
1854 value += irel->r_addend;
1855
1856 /* See if the value will fit in 16 bits, note the high value is
1857 0xfffe + 2 as the target will be two bytes closer if we are
1858 able to relax. */
1859 if ((long) value < 0x10000 && (long) value > -0x10002)
1860 {
1861 unsigned int code;
1862
1863 /* Get the opcode. */
1864 code = (unsigned int) bfd_get_32 (abfd, contents + irel->r_offset);
1865
1866 /* Verify it's a 'bcond' and fix the opcode. */
1867 if ((code & 0xffff) == 0x0010)
1868 bfd_put_16 (abfd, 0x1800 | ((0xf & (code >> 20)) << 4), contents + irel->r_offset);
1869 else
1870 continue;
1871
1872 /* Note that we've changed the relocs, section contents, etc. */
1873 elf_section_data (sec)->relocs = internal_relocs;
1874 elf_section_data (sec)->this_hdr.contents = contents;
1875 symtab_hdr->contents = (unsigned char *) isymbuf;
1876
1877 /* Fix the relocation's type. */
1878 irel->r_info = ELF32_R_INFO (ELF32_R_SYM (irel->r_info),
1879 R_CR16_DISP16);
1880
1881 /* Delete two bytes of data. */
1882 if (!elf32_cr16_relax_delete_bytes (link_info, abfd, sec,
1883 irel->r_offset + 2, 2))
1884 goto error_return;
1885
1886 /* That will change things, so, we should relax again.
1887 Note that this is not required, and it may be slow. */
1888 *again = TRUE;
1889 }
1890 }
3d3d428f 1891
99706f30 1892 /* Try to turn a 16bit pc-relative branch into an
07d6d2b8 1893 8bit pc-relative branch. */
3d3d428f 1894 if (ELF32_R_TYPE (irel->r_info) == (int) R_CR16_DISP16)
07d6d2b8
AM
1895 {
1896 bfd_vma value = symval;
1897
1898 /* Deal with pc-relative gunk. */
1899 value -= (sec->output_section->vma + sec->output_offset);
1900 value -= irel->r_offset;
1901 value += irel->r_addend;
1902
1903 /* See if the value will fit in 8 bits, note the high value is
1904 0xfc + 2 as the target will be two bytes closer if we are
1905 able to relax. */
1906 /*if ((long) value < 0x1fa && (long) value > -0x100) REVISIT:range */
1907 if ((long) value < 0xfa && (long) value > -0x100)
1908 {
1909 unsigned short code;
1910
1911 /* Get the opcode. */
1912 code = (unsigned short) bfd_get_16 (abfd, contents + irel->r_offset);
1913
1914 /* Verify it's a 'bcond' and fix the opcode. */
1915 if ((code & 0xff0f) == 0x1800)
1916 bfd_put_16 (abfd, (code & 0xf0f0), contents + irel->r_offset);
1917 else
1918 continue;
1919
1920 /* Note that we've changed the relocs, section contents, etc. */
1921 elf_section_data (sec)->relocs = internal_relocs;
1922 elf_section_data (sec)->this_hdr.contents = contents;
1923 symtab_hdr->contents = (unsigned char *) isymbuf;
1924
1925 /* Fix the relocation's type. */
1926 irel->r_info = ELF32_R_INFO (ELF32_R_SYM (irel->r_info),
1927 R_CR16_DISP8);
1928
1929 /* Delete two bytes of data. */
1930 if (!elf32_cr16_relax_delete_bytes (link_info, abfd, sec,
1931 irel->r_offset + 2, 2))
1932 goto error_return;
1933
1934 /* That will change things, so, we should relax again.
1935 Note that this is not required, and it may be slow. */
1936 *again = TRUE;
1937 }
1938 }
3d3d428f 1939
99706f30 1940 /* Try to turn a 32-bit IMM address into a 20/16-bit IMM address */
3d3d428f 1941 if (ELF32_R_TYPE (irel->r_info) == (int) R_CR16_IMM32)
07d6d2b8
AM
1942 {
1943 bfd_vma value = symval;
1944 unsigned short is_add_mov = 0;
1945 bfd_vma value1 = 0;
1946
1947 /* Get the existing value from the mcode */
1948 value1 = ((bfd_get_32 (abfd, contents + irel->r_offset + 2) >> 16)
1949 |(((bfd_get_32 (abfd, contents + irel->r_offset + 2) & 0xffff) << 16)));
1950
1951 /* See if the value will fit in 20 bits. */
1952 if ((long) (value + value1) < 0xfffff && (long) (value + value1) > 0)
1953 {
1954 unsigned short code;
1955
1956 /* Get the opcode. */
1957 code = (unsigned short) bfd_get_16 (abfd, contents + irel->r_offset);
1958
1959 /* Verify it's a 'arithmetic ADDD or MOVD instruction'.
1960 For ADDD and MOVD only, convert to IMM32 -> IMM20. */
1961
1962 if (((code & 0xfff0) == 0x0070) || ((code & 0xfff0) == 0x0020))
1963 is_add_mov = 1;
1964
1965 if (is_add_mov)
1966 {
1967 /* Note that we've changed the relocs, section contents,
1968 etc. */
1969 elf_section_data (sec)->relocs = internal_relocs;
1970 elf_section_data (sec)->this_hdr.contents = contents;
1971 symtab_hdr->contents = (unsigned char *) isymbuf;
1972
1973 /* Fix the opcode. */
1974 if ((code & 0xfff0) == 0x0070) /* For movd. */
1975 bfd_put_8 (abfd, 0x05, contents + irel->r_offset + 1);
1976 else /* code == 0x0020 for addd. */
1977 bfd_put_8 (abfd, 0x04, contents + irel->r_offset + 1);
1978
1979 bfd_put_8 (abfd, (code & 0xf) << 4, contents + irel->r_offset);
1980
1981 /* If existing value is nagavive adjust approriately
1982 place the 16-20bits (ie 4 bit) in new opcode,
1983 as the 0xffffxxxx, the higher 2 byte values removed. */
1984 if (value1 & 0x80000000)
1985 bfd_put_8 (abfd, (0x0f | (bfd_get_8(abfd, contents + irel->r_offset))), contents + irel->r_offset);
1986 else
1987 bfd_put_8 (abfd, (((value1 >> 16)&0xf) | (bfd_get_8(abfd, contents + irel->r_offset))), contents + irel->r_offset);
1988
1989 /* Fix the relocation's type. */
1990 irel->r_info = ELF32_R_INFO (ELF32_R_SYM (irel->r_info),
1991 R_CR16_IMM20);
1992
1993 /* Delete two bytes of data. */
1994 if (!elf32_cr16_relax_delete_bytes (link_info, abfd, sec,
1995 irel->r_offset + 2, 2))
1996 goto error_return;
1997
1998 /* That will change things, so, we should relax again.
1999 Note that this is not required, and it may be slow. */
2000 *again = TRUE;
2001 }
2002 }
2003
2004 /* See if the value will fit in 16 bits. */
2005 if ((!is_add_mov)
2006 && ((long)(value + value1) < 0x7fff && (long)(value + value1) > 0))
2007 {
2008 unsigned short code;
2009
2010 /* Get the opcode. */
2011 code = (unsigned short) bfd_get_16 (abfd, contents + irel->r_offset);
2012
2013 /* Note that we've changed the relocs, section contents, etc. */
2014 elf_section_data (sec)->relocs = internal_relocs;
2015 elf_section_data (sec)->this_hdr.contents = contents;
2016 symtab_hdr->contents = (unsigned char *) isymbuf;
2017
2018 /* Fix the opcode. */
2019 if ((code & 0xf0) == 0x70) /* For movd. */
2020 bfd_put_8 (abfd, 0x54, contents + irel->r_offset + 1);
2021 else if ((code & 0xf0) == 0x20) /* For addd. */
2022 bfd_put_8 (abfd, 0x60, contents + irel->r_offset + 1);
2023 else if ((code & 0xf0) == 0x90) /* For cmpd. */
2024 bfd_put_8 (abfd, 0x56, contents + irel->r_offset + 1);
2025 else
2026 continue;
2027
2028 bfd_put_8 (abfd, 0xb0 | (code & 0xf), contents + irel->r_offset);
2029
2030 /* If existing value is nagavive adjust approriately
2031 place the 12-16bits (ie 4 bit) in new opcode,
2032 as the 0xfffffxxx, the higher 2 byte values removed. */
2033 if (value1 & 0x80000000)
2034 bfd_put_8 (abfd, (0x0f | (bfd_get_8(abfd, contents + irel->r_offset))), contents + irel->r_offset);
2035 else
2036 bfd_put_16 (abfd, value1, contents + irel->r_offset + 2);
2037
2038
2039 /* Fix the relocation's type. */
2040 irel->r_info = ELF32_R_INFO (ELF32_R_SYM (irel->r_info),
2041 R_CR16_IMM16);
2042
2043 /* Delete two bytes of data. */
2044 if (!elf32_cr16_relax_delete_bytes (link_info, abfd, sec,
2045 irel->r_offset + 2, 2))
2046 goto error_return;
2047
2048 /* That will change things, so, we should relax again.
2049 Note that this is not required, and it may be slow. */
2050 *again = TRUE;
2051 }
2052 }
7fac7ff4 2053
99706f30
SR
2054#if 0
2055 /* Try to turn a 16bit immediate address into a 4bit
07d6d2b8 2056 immediate address. */
68ffbac6 2057 if ((ELF32_R_TYPE (irel->r_info) == (int) R_CR16_IMM20)
07d6d2b8
AM
2058 || (ELF32_R_TYPE (irel->r_info) == (int) R_CR16_IMM16))
2059 {
2060 bfd_vma value = symval;
2061 bfd_vma value1 = 0;
2062
2063 /* Get the existing value from the mcode */
2064 value1 = ((bfd_get_16 (abfd, contents + irel->r_offset + 2) & 0xffff));
2065
2066 if (ELF32_R_TYPE (irel->r_info) == (int) R_CR16_IMM20)
2067 {
2068 value1 |= ((bfd_get_16 (abfd, contents + irel->r_offset + 1) & 0xf000) << 0x4);
2069 }
2070
2071 /* See if the value will fit in 4 bits. */
2072 if ((((long) (value + value1)) < 0xf)
2073 && (((long) (value + value1)) > 0))
2074 {
2075 unsigned short code;
2076
2077 /* Get the opcode. */
2078 code = (unsigned short) bfd_get_16 (abfd, contents + irel->r_offset);
2079
2080 /* Note that we've changed the relocs, section contents, etc. */
2081 elf_section_data (sec)->relocs = internal_relocs;
2082 elf_section_data (sec)->this_hdr.contents = contents;
2083 symtab_hdr->contents = (unsigned char *) isymbuf;
2084
2085 /* Fix the opcode. */
2086 if (((code & 0x0f00) == 0x0400) || ((code & 0x0f00) == 0x0500))
2087 {
2088 if ((code & 0x0f00) == 0x0400) /* For movd imm20. */
2089 bfd_put_8 (abfd, 0x60, contents + irel->r_offset);
2090 else /* For addd imm20. */
2091 bfd_put_8 (abfd, 0x54, contents + irel->r_offset);
2092 bfd_put_8 (abfd, (code & 0xf0) >> 4, contents + irel->r_offset + 1);
2093 }
2094 else
2095 {
2096 if ((code & 0xfff0) == 0x56b0) /* For cmpd imm16. */
2097 bfd_put_8 (abfd, 0x56, contents + irel->r_offset);
2098 else if ((code & 0xfff0) == 0x54b0) /* For movd imm16. */
2099 bfd_put_8 (abfd, 0x54, contents + irel->r_offset);
2100 else if ((code & 0xfff0) == 0x58b0) /* For movb imm16. */
2101 bfd_put_8 (abfd, 0x58, contents + irel->r_offset);
2102 else if ((code & 0xfff0) == 0x5Ab0) /* For movw imm16. */
2103 bfd_put_8 (abfd, 0x5A, contents + irel->r_offset);
2104 else if ((code & 0xfff0) == 0x60b0) /* For addd imm16. */
2105 bfd_put_8 (abfd, 0x60, contents + irel->r_offset);
2106 else if ((code & 0xfff0) == 0x30b0) /* For addb imm16. */
2107 bfd_put_8 (abfd, 0x30, contents + irel->r_offset);
2108 else if ((code & 0xfff0) == 0x2Cb0) /* For addub imm16. */
2109 bfd_put_8 (abfd, 0x2C, contents + irel->r_offset);
2110 else if ((code & 0xfff0) == 0x32b0) /* For adduw imm16. */
2111 bfd_put_8 (abfd, 0x32, contents + irel->r_offset);
2112 else if ((code & 0xfff0) == 0x38b0) /* For subb imm16. */
2113 bfd_put_8 (abfd, 0x38, contents + irel->r_offset);
2114 else if ((code & 0xfff0) == 0x3Cb0) /* For subcb imm16. */
2115 bfd_put_8 (abfd, 0x3C, contents + irel->r_offset);
2116 else if ((code & 0xfff0) == 0x3Fb0) /* For subcw imm16. */
2117 bfd_put_8 (abfd, 0x3F, contents + irel->r_offset);
2118 else if ((code & 0xfff0) == 0x3Ab0) /* For subw imm16. */
2119 bfd_put_8 (abfd, 0x3A, contents + irel->r_offset);
2120 else if ((code & 0xfff0) == 0x50b0) /* For cmpb imm16. */
2121 bfd_put_8 (abfd, 0x50, contents + irel->r_offset);
2122 else if ((code & 0xfff0) == 0x52b0) /* For cmpw imm16. */
2123 bfd_put_8 (abfd, 0x52, contents + irel->r_offset);
2124 else
2125 continue;
2126
2127 bfd_put_8 (abfd, (code & 0xf), contents + irel->r_offset + 1);
2128 }
2129
2130 /* Fix the relocation's type. */
2131 irel->r_info = ELF32_R_INFO (ELF32_R_SYM (irel->r_info),
2132 R_CR16_IMM4);
2133
2134 /* Delete two bytes of data. */
2135 if (!elf32_cr16_relax_delete_bytes (link_info, abfd, sec,
2136 irel->r_offset + 2, 2))
2137 goto error_return;
2138
2139 /* That will change things, so, we should relax again.
2140 Note that this is not required, and it may be slow. */
2141 *again = TRUE;
2142 }
2143 }
99706f30 2144#endif
3d3d428f
NC
2145 }
2146
2147 if (isymbuf != NULL
2148 && symtab_hdr->contents != (unsigned char *) isymbuf)
2149 {
2150 if (! link_info->keep_memory)
07d6d2b8 2151 free (isymbuf);
3d3d428f 2152 else
99706f30
SR
2153 /* Cache the symbols for elf_link_input_bfd. */
2154 symtab_hdr->contents = (unsigned char *) isymbuf;
3d3d428f
NC
2155 }
2156
2157 if (contents != NULL
2158 && elf_section_data (sec)->this_hdr.contents != contents)
2159 {
2160 if (! link_info->keep_memory)
07d6d2b8 2161 free (contents);
3d3d428f 2162 else
99706f30
SR
2163 /* Cache the section contents for elf_link_input_bfd. */
2164 elf_section_data (sec)->this_hdr.contents = contents;
68ffbac6 2165
3d3d428f
NC
2166 }
2167
c9594989 2168 if (elf_section_data (sec)->relocs != internal_relocs)
3d3d428f
NC
2169 free (internal_relocs);
2170
2171 return TRUE;
2172
2173 error_return:
c9594989 2174 if (symtab_hdr->contents != (unsigned char *) isymbuf)
3d3d428f 2175 free (isymbuf);
c9594989 2176 if (elf_section_data (sec)->this_hdr.contents != contents)
3d3d428f 2177 free (contents);
c9594989 2178 if (elf_section_data (sec)->relocs != internal_relocs)
3d3d428f
NC
2179 free (internal_relocs);
2180
2181 return FALSE;
2182}
2183
2184static asection *
2185elf32_cr16_gc_mark_hook (asection *sec,
07d6d2b8
AM
2186 struct bfd_link_info *info,
2187 Elf_Internal_Rela *rel,
2188 struct elf_link_hash_entry *h,
2189 Elf_Internal_Sym *sym)
3d3d428f 2190{
fb34365b 2191 return _bfd_elf_gc_mark_hook (sec, info, rel, h, sym);
3d3d428f
NC
2192}
2193
99706f30
SR
2194/* Create dynamic sections when linking against a dynamic object. */
2195
2196static bfd_boolean
2197_bfd_cr16_elf_create_dynamic_sections (bfd *abfd, struct bfd_link_info *info)
2198{
2199 flagword flags;
2200 asection * s;
2201 const struct elf_backend_data * bed = get_elf_backend_data (abfd);
ce558b89 2202 struct elf_link_hash_table *htab = elf_hash_table (info);
99706f30
SR
2203 int ptralign = 0;
2204
2205 switch (bed->s->arch_size)
2206 {
2207 case 16:
2208 ptralign = 1;
2209 break;
2210
2211 case 32:
2212 ptralign = 2;
2213 break;
2214
2215 default:
2216 bfd_set_error (bfd_error_bad_value);
2217 return FALSE;
2218 }
2219
2220 /* We need to create .plt, .rel[a].plt, .got, .got.plt, .dynbss, and
2221 .rel[a].bss sections. */
2222
2223 flags = (SEC_ALLOC | SEC_LOAD | SEC_HAS_CONTENTS | SEC_IN_MEMORY
07d6d2b8 2224 | SEC_LINKER_CREATED);
99706f30 2225
3d4d4302
AM
2226 s = bfd_make_section_anyway_with_flags (abfd,
2227 (bed->default_use_rela_p
2228 ? ".rela.plt" : ".rel.plt"),
2229 flags | SEC_READONLY);
ce558b89 2230 htab->srelplt = s;
99706f30 2231 if (s == NULL
fd361982 2232 || !bfd_set_section_alignment (s, ptralign))
99706f30
SR
2233 return FALSE;
2234
2235 if (! _bfd_cr16_elf_create_got_section (abfd, info))
2236 return FALSE;
2237
99706f30
SR
2238 if (bed->want_dynbss)
2239 {
2240 /* The .dynbss section is a place to put symbols which are defined
07d6d2b8
AM
2241 by dynamic objects, are referenced by regular objects, and are
2242 not functions. We must allocate space for them in the process
2243 image and use a R_*_COPY reloc to tell the dynamic linker to
2244 initialize them at run time. The linker script puts the .dynbss
2245 section into the .bss section of the final image. */
3d4d4302
AM
2246 s = bfd_make_section_anyway_with_flags (abfd, ".dynbss",
2247 SEC_ALLOC | SEC_LINKER_CREATED);
99706f30 2248 if (s == NULL)
07d6d2b8 2249 return FALSE;
99706f30
SR
2250
2251 /* The .rel[a].bss section holds copy relocs. This section is not
07d6d2b8
AM
2252 normally needed. We need to create it here, though, so that the
2253 linker will map it to an output section. We can't just create it
2254 only if we need it, because we will not know whether we need it
2255 until we have seen all the input files, and the first time the
2256 main linker code calls BFD after examining all the input files
2257 (size_dynamic_sections) the input sections have already been
2258 mapped to the output sections. If the section turns out not to
2259 be needed, we can discard it later. We will never need this
2260 section when generating a shared object, since they do not use
2261 copy relocs. */
0e1862bb 2262 if (! bfd_link_executable (info))
07d6d2b8
AM
2263 {
2264 s = bfd_make_section_anyway_with_flags (abfd,
3d4d4302
AM
2265 (bed->default_use_rela_p
2266 ? ".rela.bss" : ".rel.bss"),
2267 flags | SEC_READONLY);
07d6d2b8 2268 if (s == NULL
fd361982 2269 || !bfd_set_section_alignment (s, ptralign))
07d6d2b8
AM
2270 return FALSE;
2271 }
99706f30
SR
2272 }
2273
2274 return TRUE;
2275}
2276\f
2277/* Adjust a symbol defined by a dynamic object and referenced by a
2278 regular object. The current definition is in some section of the
2279 dynamic object, but we're not including those sections. We have to
2280 change the definition to something the rest of the link can
2281 understand. */
2282
2283static bfd_boolean
2284_bfd_cr16_elf_adjust_dynamic_symbol (struct bfd_link_info * info,
07d6d2b8 2285 struct elf_link_hash_entry * h)
99706f30
SR
2286{
2287 bfd * dynobj;
2288 asection * s;
2289
2290 dynobj = elf_hash_table (info)->dynobj;
2291
2292 /* Make sure we know what is going on here. */
2293 BFD_ASSERT (dynobj != NULL
07d6d2b8
AM
2294 && (h->needs_plt
2295 || h->is_weakalias
2296 || (h->def_dynamic
2297 && h->ref_regular
2298 && !h->def_regular)));
99706f30
SR
2299
2300 /* If this is a function, put it in the procedure linkage table. We
2301 will fill in the contents of the procedure linkage table later,
2302 when we know the address of the .got section. */
2303 if (h->type == STT_FUNC
2304 || h->needs_plt)
2305 {
0e1862bb 2306 if (! bfd_link_executable (info)
07d6d2b8
AM
2307 && !h->def_dynamic
2308 && !h->ref_dynamic)
2309 {
2310 /* This case can occur if we saw a PLT reloc in an input
2311 file, but the symbol was never referred to by a dynamic
2312 object. In such a case, we don't actually need to build
2313 a procedure linkage table, and we can just do a REL32
2314 reloc instead. */
2315 BFD_ASSERT (h->needs_plt);
2316 return TRUE;
2317 }
99706f30
SR
2318
2319 /* Make sure this symbol is output as a dynamic symbol. */
2320 if (h->dynindx == -1)
07d6d2b8
AM
2321 {
2322 if (! bfd_elf_link_record_dynamic_symbol (info, h))
2323 return FALSE;
2324 }
99706f30
SR
2325
2326 /* We also need to make an entry in the .got.plt section, which
07d6d2b8 2327 will be placed in the .got section by the linker script. */
99706f30 2328
ce558b89 2329 s = elf_hash_table (info)->sgotplt;
99706f30
SR
2330 BFD_ASSERT (s != NULL);
2331 s->size += 4;
2332
2333 /* We also need to make an entry in the .rela.plt section. */
2334
ce558b89 2335 s = elf_hash_table (info)->srelplt;
99706f30
SR
2336 BFD_ASSERT (s != NULL);
2337 s->size += sizeof (Elf32_External_Rela);
2338
2339 return TRUE;
2340 }
2341
2342 /* If this is a weak symbol, and there is a real definition, the
2343 processor independent code will have arranged for us to see the
2344 real definition first, and we can just use the same value. */
60d67dc8 2345 if (h->is_weakalias)
99706f30 2346 {
60d67dc8
AM
2347 struct elf_link_hash_entry *def = weakdef (h);
2348 BFD_ASSERT (def->root.type == bfd_link_hash_defined);
2349 h->root.u.def.section = def->root.u.def.section;
2350 h->root.u.def.value = def->root.u.def.value;
99706f30
SR
2351 return TRUE;
2352 }
2353
2354 /* This is a reference to a symbol defined by a dynamic object which
2355 is not a function. */
2356
2357 /* If we are creating a shared library, we must presume that the
2358 only references to the symbol are via the global offset table.
2359 For such cases we need not do anything here; the relocations will
2360 be handled correctly by relocate_section. */
0e1862bb 2361 if (bfd_link_executable (info))
99706f30
SR
2362 return TRUE;
2363
2364 /* If there are no references to this symbol that do not use the
2365 GOT, we don't need to generate a copy reloc. */
2366 if (!h->non_got_ref)
2367 return TRUE;
2368
99706f30
SR
2369 /* We must allocate the symbol in our .dynbss section, which will
2370 become part of the .bss section of the executable. There will be
2371 an entry for this symbol in the .dynsym section. The dynamic
2372 object will contain position independent code, so all references
2373 from the dynamic object to this symbol will go through the global
2374 offset table. The dynamic linker will use the .dynsym entry to
2375 determine the address it must put in the global offset table, so
2376 both the dynamic object and the regular object will refer to the
2377 same memory location for the variable. */
2378
3d4d4302 2379 s = bfd_get_linker_section (dynobj, ".dynbss");
99706f30
SR
2380 BFD_ASSERT (s != NULL);
2381
2382 /* We must generate a R_CR16_COPY reloc to tell the dynamic linker to
2383 copy the initial value out of the dynamic object and into the
2384 runtime process image. We need to remember the offset into the
2385 .rela.bss section we are going to use. */
1d7e9d18 2386 if ((h->root.u.def.section->flags & SEC_ALLOC) != 0 && h->size != 0)
99706f30
SR
2387 {
2388 asection * srel;
2389
3d4d4302 2390 srel = bfd_get_linker_section (dynobj, ".rela.bss");
99706f30
SR
2391 BFD_ASSERT (srel != NULL);
2392 srel->size += sizeof (Elf32_External_Rela);
2393 h->needs_copy = 1;
2394 }
2395
6cabe1ea 2396 return _bfd_elf_adjust_dynamic_copy (info, h, s);
99706f30
SR
2397}
2398
2399/* Set the sizes of the dynamic sections. */
2400
2401static bfd_boolean
2402_bfd_cr16_elf_size_dynamic_sections (bfd * output_bfd,
07d6d2b8 2403 struct bfd_link_info * info)
99706f30
SR
2404{
2405 bfd * dynobj;
2406 asection * s;
99706f30 2407 bfd_boolean relocs;
99706f30
SR
2408
2409 dynobj = elf_hash_table (info)->dynobj;
2410 BFD_ASSERT (dynobj != NULL);
2411
2412 if (elf_hash_table (info)->dynamic_sections_created)
2413 {
2414 /* Set the contents of the .interp section to the interpreter. */
9b8b325a 2415 if (bfd_link_executable (info) && !info->nointerp)
07d6d2b8 2416 {
99706f30 2417#if 0
07d6d2b8
AM
2418 s = bfd_get_linker_section (dynobj, ".interp");
2419 BFD_ASSERT (s != NULL);
2420 s->size = sizeof ELF_DYNAMIC_INTERPRETER;
2421 s->contents = (unsigned char *) ELF_DYNAMIC_INTERPRETER;
99706f30 2422#endif
07d6d2b8 2423 }
99706f30
SR
2424 }
2425 else
2426 {
2427 /* We may have created entries in the .rela.got section.
07d6d2b8
AM
2428 However, if we are not creating the dynamic sections, we will
2429 not actually use these entries. Reset the size of .rela.got,
2430 which will cause it to get stripped from the output file
2431 below. */
ce558b89 2432 s = elf_hash_table (info)->srelgot;
99706f30 2433 if (s != NULL)
07d6d2b8 2434 s->size = 0;
99706f30
SR
2435 }
2436
2437 /* The check_relocs and adjust_dynamic_symbol entry points have
2438 determined the sizes of the various dynamic sections. Allocate
2439 memory for them. */
99706f30 2440 relocs = FALSE;
99706f30
SR
2441 for (s = dynobj->sections; s != NULL; s = s->next)
2442 {
2443 const char * name;
2444
2445 if ((s->flags & SEC_LINKER_CREATED) == 0)
07d6d2b8 2446 continue;
99706f30
SR
2447
2448 /* It's OK to base decisions on the section name, because none
07d6d2b8 2449 of the dynobj section names depend upon the input files. */
fd361982 2450 name = bfd_section_name (s);
99706f30
SR
2451
2452 if (strcmp (name, ".plt") == 0)
07d6d2b8
AM
2453 {
2454 /* Remember whether there is a PLT. */
3084d7a2 2455 ;
07d6d2b8 2456 }
99706f30 2457 else if (CONST_STRNEQ (name, ".rela"))
07d6d2b8
AM
2458 {
2459 if (s->size != 0)
2460 {
07d6d2b8
AM
2461 /* Remember whether there are any reloc sections other
2462 than .rela.plt. */
2463 if (strcmp (name, ".rela.plt") != 0)
3084d7a2 2464 relocs = TRUE;
07d6d2b8
AM
2465
2466 /* We use the reloc_count field as a counter if we need
2467 to copy relocs into the output file. */
2468 s->reloc_count = 0;
2469 }
2470 }
99706f30 2471 else if (! CONST_STRNEQ (name, ".got")
07d6d2b8
AM
2472 && strcmp (name, ".dynbss") != 0)
2473 /* It's not one of our sections, so don't allocate space. */
2474 continue;
99706f30
SR
2475
2476 if (s->size == 0)
07d6d2b8
AM
2477 {
2478 /* If we don't need this section, strip it from the
2479 output file. This is mostly to handle .rela.bss and
2480 .rela.plt. We must create both sections in
2481 create_dynamic_sections, because they must be created
2482 before the linker maps input sections to output
2483 sections. The linker does that before
2484 adjust_dynamic_symbol is called, and it is that
2485 function which decides whether anything needs to go
2486 into these sections. */
2487 s->flags |= SEC_EXCLUDE;
2488 continue;
2489 }
2490
2491 if ((s->flags & SEC_HAS_CONTENTS) == 0)
2492 continue;
99706f30
SR
2493
2494 /* Allocate memory for the section contents. We use bfd_zalloc
07d6d2b8
AM
2495 here in case unused entries are not reclaimed before the
2496 section's contents are written out. This should not happen,
2497 but this way if it does, we get a R_CR16_NONE reloc
2498 instead of garbage. */
99706f30
SR
2499 s->contents = (bfd_byte *) bfd_zalloc (dynobj, s->size);
2500 if (s->contents == NULL)
07d6d2b8 2501 return FALSE;
99706f30
SR
2502 }
2503
3084d7a2 2504 return _bfd_elf_add_dynamic_tags (output_bfd, info, relocs);
99706f30
SR
2505}
2506
2507/* Finish up dynamic symbol handling. We set the contents of various
2508 dynamic sections here. */
2509
2510static bfd_boolean
2511_bfd_cr16_elf_finish_dynamic_symbol (bfd * output_bfd,
07d6d2b8
AM
2512 struct bfd_link_info * info,
2513 struct elf_link_hash_entry * h,
2514 Elf_Internal_Sym * sym)
99706f30
SR
2515{
2516 bfd * dynobj;
2517
2518 dynobj = elf_hash_table (info)->dynobj;
2519
2520 if (h->got.offset != (bfd_vma) -1)
2521 {
07d6d2b8
AM
2522 asection * sgot;
2523 asection * srel;
99706f30
SR
2524 Elf_Internal_Rela rel;
2525
2526 /* This symbol has an entry in the global offset table. Set it up. */
2527
ce558b89
AM
2528 sgot = elf_hash_table (info)->sgot;
2529 srel = elf_hash_table (info)->srelgot;
99706f30
SR
2530 BFD_ASSERT (sgot != NULL && srel != NULL);
2531
2532 rel.r_offset = (sgot->output_section->vma
07d6d2b8
AM
2533 + sgot->output_offset
2534 + (h->got.offset & ~1));
99706f30
SR
2535
2536 /* If this is a -Bsymbolic link, and the symbol is defined
07d6d2b8
AM
2537 locally, we just want to emit a RELATIVE reloc. Likewise if
2538 the symbol was forced to be local because of a version file.
2539 The entry in the global offset table will already have been
2540 initialized in the relocate_section function. */
0e1862bb 2541 if (bfd_link_executable (info)
07d6d2b8
AM
2542 && (info->symbolic || h->dynindx == -1)
2543 && h->def_regular)
2544 {
2545 rel.r_info = ELF32_R_INFO (0, R_CR16_GOT_REGREL20);
2546 rel.r_addend = (h->root.u.def.value
2547 + h->root.u.def.section->output_section->vma
2548 + h->root.u.def.section->output_offset);
2549 }
99706f30 2550 else
07d6d2b8
AM
2551 {
2552 bfd_put_32 (output_bfd, (bfd_vma) 0, sgot->contents + h->got.offset);
2553 rel.r_info = ELF32_R_INFO (h->dynindx, R_CR16_GOT_REGREL20);
2554 rel.r_addend = 0;
2555 }
99706f30
SR
2556
2557 bfd_elf32_swap_reloca_out (output_bfd, &rel,
07d6d2b8
AM
2558 (bfd_byte *) ((Elf32_External_Rela *) srel->contents
2559 + srel->reloc_count));
99706f30
SR
2560 ++ srel->reloc_count;
2561 }
2562
2563 if (h->needs_copy)
2564 {
07d6d2b8 2565 asection * s;
99706f30
SR
2566 Elf_Internal_Rela rel;
2567
2568 /* This symbol needs a copy reloc. Set it up. */
2569 BFD_ASSERT (h->dynindx != -1
07d6d2b8
AM
2570 && (h->root.type == bfd_link_hash_defined
2571 || h->root.type == bfd_link_hash_defweak));
99706f30 2572
3d4d4302 2573 s = bfd_get_linker_section (dynobj, ".rela.bss");
99706f30
SR
2574 BFD_ASSERT (s != NULL);
2575
2576 rel.r_offset = (h->root.u.def.value
07d6d2b8
AM
2577 + h->root.u.def.section->output_section->vma
2578 + h->root.u.def.section->output_offset);
99706f30
SR
2579 rel.r_info = ELF32_R_INFO (h->dynindx, R_CR16_GOT_REGREL20);
2580 rel.r_addend = 0;
2581 bfd_elf32_swap_reloca_out (output_bfd, &rel,
07d6d2b8
AM
2582 (bfd_byte *) ((Elf32_External_Rela *) s->contents
2583 + s->reloc_count));
99706f30
SR
2584 ++ s->reloc_count;
2585 }
2586
2587 /* Mark _DYNAMIC and _GLOBAL_OFFSET_TABLE_ as absolute. */
9637f6ef 2588 if (h == elf_hash_table (info)->hdynamic
99706f30
SR
2589 || h == elf_hash_table (info)->hgot)
2590 sym->st_shndx = SHN_ABS;
2591
2592 return TRUE;
2593}
2594
2595/* Finish up the dynamic sections. */
2596
2597static bfd_boolean
2598_bfd_cr16_elf_finish_dynamic_sections (bfd * output_bfd,
07d6d2b8 2599 struct bfd_link_info * info)
99706f30
SR
2600{
2601 bfd * dynobj;
2602 asection * sgot;
2603 asection * sdyn;
2604
2605 dynobj = elf_hash_table (info)->dynobj;
2606
ce558b89 2607 sgot = elf_hash_table (info)->sgotplt;
99706f30 2608 BFD_ASSERT (sgot != NULL);
3d4d4302 2609 sdyn = bfd_get_linker_section (dynobj, ".dynamic");
99706f30
SR
2610
2611 if (elf_hash_table (info)->dynamic_sections_created)
2612 {
2613 Elf32_External_Dyn * dyncon;
2614 Elf32_External_Dyn * dynconend;
2615
2616 BFD_ASSERT (sdyn != NULL);
2617
2618 dyncon = (Elf32_External_Dyn *) sdyn->contents;
2619 dynconend = (Elf32_External_Dyn *) (sdyn->contents + sdyn->size);
2620
2621 for (; dyncon < dynconend; dyncon++)
07d6d2b8
AM
2622 {
2623 Elf_Internal_Dyn dyn;
2624 asection * s;
2625
2626 bfd_elf32_swap_dyn_in (dynobj, dyncon, &dyn);
2627
2628 switch (dyn.d_tag)
2629 {
2630 default:
2631 break;
2632
2633 case DT_PLTGOT:
2634 s = elf_hash_table (info)->sgotplt;
2635 goto get_vma;
2636
2637 case DT_JMPREL:
2638 s = elf_hash_table (info)->srelplt;
2639 get_vma:
2640 dyn.d_un.d_ptr = s->output_section->vma + s->output_offset;
2641 bfd_elf32_swap_dyn_out (output_bfd, &dyn, dyncon);
2642 break;
2643
2644 case DT_PLTRELSZ:
2645 s = elf_hash_table (info)->srelplt;
2646 dyn.d_un.d_val = s->size;
2647 bfd_elf32_swap_dyn_out (output_bfd, &dyn, dyncon);
2648 break;
2649 }
2650 }
99706f30
SR
2651
2652 }
2653
2654 /* Fill in the first three entries in the global offset table. */
2655 if (sgot->size > 0)
2656 {
2657 if (sdyn == NULL)
07d6d2b8 2658 bfd_put_32 (output_bfd, (bfd_vma) 0, sgot->contents);
99706f30 2659 else
07d6d2b8
AM
2660 bfd_put_32 (output_bfd,
2661 sdyn->output_section->vma + sdyn->output_offset,
2662 sgot->contents);
99706f30
SR
2663 }
2664
2665 elf_section_data (sgot->output_section)->this_hdr.sh_entsize = 4;
2666
2667 return TRUE;
2668}
2669
2670/* Given a .data.rel section and a .emreloc in-memory section, store
2671 relocation information into the .emreloc section which can be
2672 used at runtime to relocate the section. This is called by the
2673 linker when the --embedded-relocs switch is used. This is called
2674 after the add_symbols entry point has been called for all the
2675 objects, and before the final_link entry point is called. */
2676
2677bfd_boolean
2678bfd_cr16_elf32_create_embedded_relocs (bfd *abfd,
07d6d2b8
AM
2679 struct bfd_link_info *info,
2680 asection *datasec,
2681 asection *relsec,
2682 char **errmsg)
99706f30
SR
2683{
2684 Elf_Internal_Shdr *symtab_hdr;
2685 Elf_Internal_Sym *isymbuf = NULL;
2686 Elf_Internal_Rela *internal_relocs = NULL;
2687 Elf_Internal_Rela *irel, *irelend;
2688 bfd_byte *p;
2689 bfd_size_type amt;
2690
0e1862bb 2691 BFD_ASSERT (! bfd_link_relocatable (info));
99706f30
SR
2692
2693 *errmsg = NULL;
2694
2695 if (datasec->reloc_count == 0)
2696 return TRUE;
2697
2698 symtab_hdr = &elf_tdata (abfd)->symtab_hdr;
2699
2700 /* Get a copy of the native relocations. */
2701 internal_relocs = (_bfd_elf_link_read_relocs
07d6d2b8 2702 (abfd, datasec, NULL, NULL, info->keep_memory));
99706f30
SR
2703 if (internal_relocs == NULL)
2704 goto error_return;
2705
2706 amt = (bfd_size_type) datasec->reloc_count * 8;
2707 relsec->contents = (bfd_byte *) bfd_alloc (abfd, amt);
2708 if (relsec->contents == NULL)
2709 goto error_return;
2710
2711 p = relsec->contents;
2712
2713 irelend = internal_relocs + datasec->reloc_count;
2714 for (irel = internal_relocs; irel < irelend; irel++, p += 8)
2715 {
2716 asection *targetsec;
2717
2718 /* We are going to write a four byte longword into the runtime
2719 reloc section. The longword will be the address in the data
2720 section which must be relocated. It is followed by the name
2721 of the target section NUL-padded or truncated to 8
2722 characters. */
2723
2724 /* We can only relocate absolute longword relocs at run time. */
2725 if (!((ELF32_R_TYPE (irel->r_info) == (int) R_CR16_NUM32a)
07d6d2b8
AM
2726 || (ELF32_R_TYPE (irel->r_info) == (int) R_CR16_NUM32)))
2727 {
0aa13fee 2728 *errmsg = _("unsupported relocation type");
07d6d2b8
AM
2729 bfd_set_error (bfd_error_bad_value);
2730 goto error_return;
2731 }
99706f30
SR
2732
2733 /* Get the target section referred to by the reloc. */
2734 if (ELF32_R_SYM (irel->r_info) < symtab_hdr->sh_info)
07d6d2b8
AM
2735 {
2736 /* A local symbol. */
2737 Elf_Internal_Sym *isym;
2738
2739 /* Read this BFD's local symbols if we haven't done so already. */
2740 if (isymbuf == NULL)
2741 {
2742 isymbuf = (Elf_Internal_Sym *) symtab_hdr->contents;
2743 if (isymbuf == NULL)
2744 isymbuf = bfd_elf_get_elf_syms (abfd, symtab_hdr,
2745 symtab_hdr->sh_info, 0,
2746 NULL, NULL, NULL);
2747 if (isymbuf == NULL)
2748 goto error_return;
2749 }
2750
2751 isym = isymbuf + ELF32_R_SYM (irel->r_info);
2752 targetsec = bfd_section_from_elf_index (abfd, isym->st_shndx);
2753 }
99706f30 2754 else
07d6d2b8
AM
2755 {
2756 unsigned long indx;
2757 struct elf_link_hash_entry *h;
2758
2759 /* An external symbol. */
2760 indx = ELF32_R_SYM (irel->r_info) - symtab_hdr->sh_info;
2761 h = elf_sym_hashes (abfd)[indx];
2762 BFD_ASSERT (h != NULL);
2763 if (h->root.type == bfd_link_hash_defined
2764 || h->root.type == bfd_link_hash_defweak)
2765 targetsec = h->root.u.def.section;
2766 else
2767 targetsec = NULL;
2768 }
99706f30
SR
2769
2770 bfd_put_32 (abfd, irel->r_offset + datasec->output_offset, p);
2771 memset (p + 4, 0, 4);
2772 if ((ELF32_R_TYPE (irel->r_info) == (int) R_CR16_NUM32a)
07d6d2b8
AM
2773 && (targetsec != NULL) )
2774 strncpy ((char *) p + 4, targetsec->output_section->name, 4);
99706f30
SR
2775 }
2776
c9594989 2777 if (symtab_hdr->contents != (unsigned char *) isymbuf)
99706f30 2778 free (isymbuf);
c9594989 2779 if (elf_section_data (datasec)->relocs != internal_relocs)
99706f30
SR
2780 free (internal_relocs);
2781 return TRUE;
2782
dc1e8a47 2783 error_return:
c9594989 2784 if (symtab_hdr->contents != (unsigned char *) isymbuf)
99706f30 2785 free (isymbuf);
c9594989 2786 if (elf_section_data (datasec)->relocs != internal_relocs)
99706f30
SR
2787 free (internal_relocs);
2788 return FALSE;
2789}
2790
2791
2792/* Classify relocation types, such that combreloc can sort them
2793 properly. */
2794
2795static enum elf_reloc_type_class
7e612e98
AM
2796_bfd_cr16_elf_reloc_type_class (const struct bfd_link_info *info ATTRIBUTE_UNUSED,
2797 const asection *rel_sec ATTRIBUTE_UNUSED,
2798 const Elf_Internal_Rela *rela)
99706f30
SR
2799{
2800 switch ((int) ELF32_R_TYPE (rela->r_info))
2801 {
2802 case R_CR16_GOT_REGREL20:
2803 case R_CR16_GOTC_REGREL20:
2804 return reloc_class_relative;
2805 default:
2806 return reloc_class_normal;
2807 }
2808}
2809
3d3d428f 2810/* Definitions for setting CR16 target vector. */
07d6d2b8
AM
2811#define TARGET_LITTLE_SYM cr16_elf32_vec
2812#define TARGET_LITTLE_NAME "elf32-cr16"
2813#define ELF_ARCH bfd_arch_cr16
2814#define ELF_MACHINE_CODE EM_CR16
2815#define ELF_MACHINE_ALT1 EM_CR16_OLD
2816#define ELF_MAXPAGESIZE 0x1
2817#define elf_symbol_leading_char '_'
2818
2819#define bfd_elf32_bfd_reloc_type_lookup elf_cr16_reloc_type_lookup
2820#define bfd_elf32_bfd_reloc_name_lookup elf_cr16_reloc_name_lookup
2821#define elf_info_to_howto elf_cr16_info_to_howto
f3185997 2822#define elf_info_to_howto_rel NULL
07d6d2b8
AM
2823#define elf_backend_relocate_section elf32_cr16_relocate_section
2824#define bfd_elf32_bfd_relax_section elf32_cr16_relax_section
3d3d428f 2825#define bfd_elf32_bfd_get_relocated_section_contents \
07d6d2b8
AM
2826 elf32_cr16_get_relocated_section_contents
2827#define elf_backend_gc_mark_hook elf32_cr16_gc_mark_hook
2828#define elf_backend_can_gc_sections 1
2829#define elf_backend_rela_normal 1
2830#define elf_backend_check_relocs cr16_elf_check_relocs
99706f30
SR
2831/* So we can set bits in e_flags. */
2832#define elf_backend_final_write_processing \
07d6d2b8
AM
2833 _bfd_cr16_elf_final_write_processing
2834#define elf_backend_object_p _bfd_cr16_elf_object_p
99706f30
SR
2835
2836#define bfd_elf32_bfd_merge_private_bfd_data \
07d6d2b8 2837 _bfd_cr16_elf_merge_private_bfd_data
99706f30
SR
2838
2839
2840#define bfd_elf32_bfd_link_hash_table_create \
07d6d2b8 2841 elf32_cr16_link_hash_table_create
99706f30
SR
2842
2843#define elf_backend_create_dynamic_sections \
07d6d2b8 2844 _bfd_cr16_elf_create_dynamic_sections
99706f30 2845#define elf_backend_adjust_dynamic_symbol \
07d6d2b8 2846 _bfd_cr16_elf_adjust_dynamic_symbol
99706f30 2847#define elf_backend_size_dynamic_sections \
07d6d2b8 2848 _bfd_cr16_elf_size_dynamic_sections
d00dd7dc 2849#define elf_backend_omit_section_dynsym _bfd_elf_omit_section_dynsym_all
99706f30 2850#define elf_backend_finish_dynamic_symbol \
07d6d2b8 2851 _bfd_cr16_elf_finish_dynamic_symbol
99706f30 2852#define elf_backend_finish_dynamic_sections \
07d6d2b8 2853 _bfd_cr16_elf_finish_dynamic_sections
99706f30
SR
2854
2855#define elf_backend_reloc_type_class _bfd_cr16_elf_reloc_type_class
2856
2857
07d6d2b8
AM
2858#define elf_backend_want_got_plt 1
2859#define elf_backend_plt_readonly 1
2860#define elf_backend_want_plt_sym 0
2861#define elf_backend_got_header_size 12
64f52338 2862#define elf_backend_dtrel_excludes_plt 1
3d3d428f
NC
2863
2864#include "elf32-target.h"