*** empty log message ***
[deliverable/binutils-gdb.git] / bfd / elf32-bfin.c
CommitLineData
0f64bb02
CM
1/* ADI Blackfin BFD support for 32-bit ELF.
2 Copyright 2005 Free Software Foundation, Inc.
3
4 This file is part of BFD, the Binary File Descriptor library.
5
6 This program is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2 of the License, or
9 (at your option) any later version.
10
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
15
16 You should have received a copy of the GNU General Public License
17 along with this program; if not, write to the Free Software
18 Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301,
19 USA. */
20
21#include "bfd.h"
22#include "sysdep.h"
23#include "libbfd.h"
24#include "elf-bfd.h"
25#include "elf/bfin.h"
26
27/* Handling expression relocations for blackfin. Blackfin
28 will generate relocations in an expression form with a stack.
29 A relocation such as P1.H = _typenames-4000000;
30 will generate the following relocs at offset 4:
3100000004 R_expst_push _typenames
3200000004 R_expst_const .__constant
3300000004 R_expst_sub .__operator
3400000006 R_huimm16 .__operator
35
36 The .__constant and .__operator symbol names are fake.
37 Special case is a single relocation
38 P1.L = _typenames; generates
3900000002 R_luimm16 _typenames
40
41 Thus, if you get a R_luimm16, R_huimm16, R_imm16,
42 if the stack is not empty, pop the stack and
43 put the value, else do the normal thing
44 We will currently assume that the max the stack
45 would grow to is 100. . */
46
47#define RELOC_STACK_SIZE 100
48static bfd_vma reloc_stack[RELOC_STACK_SIZE];
49static unsigned int reloc_stack_tos = 0;
50
51#define is_reloc_stack_empty() ((reloc_stack_tos > 0) ? 0 : 1)
52
53static void
54reloc_stack_push (bfd_vma value)
55{
56 reloc_stack[reloc_stack_tos++] = value;
57}
58
59static bfd_vma
60reloc_stack_pop (void)
61{
62 return reloc_stack[--reloc_stack_tos];
63}
64
65static bfd_vma
66reloc_stack_operate (unsigned int oper)
67{
68 bfd_vma value;
69 switch (oper)
70 {
71 case R_add:
72 {
73 value =
74 reloc_stack[reloc_stack_tos - 2] + reloc_stack[reloc_stack_tos - 1];
75 reloc_stack_tos -= 2;
76 break;
77 }
78 case R_sub:
79 {
80 value =
81 reloc_stack[reloc_stack_tos - 2] - reloc_stack[reloc_stack_tos - 1];
82 reloc_stack_tos -= 2;
83 break;
84 }
85 case R_mult:
86 {
87 value =
88 reloc_stack[reloc_stack_tos - 2] * reloc_stack[reloc_stack_tos - 1];
89 reloc_stack_tos -= 2;
90 break;
91 }
92 case R_div:
93 {
94 if (reloc_stack[reloc_stack_tos - 1] == 0)
95 {
96 _bfd_abort (__FILE__, __LINE__, _("Division by zero. "));
97 }
98 else
99 {
100 value =
101 reloc_stack[reloc_stack_tos - 2] / reloc_stack[reloc_stack_tos - 1];
102 reloc_stack_tos -= 2;
103 }
104 break;
105 }
106 case R_mod:
107 {
108 value =
109 reloc_stack[reloc_stack_tos - 2] % reloc_stack[reloc_stack_tos - 1];
110 reloc_stack_tos -= 2;
111 break;
112 }
113 case R_lshift:
114 {
115 value =
116 reloc_stack[reloc_stack_tos - 2] << reloc_stack[reloc_stack_tos -
117 1];
118 reloc_stack_tos -= 2;
119 break;
120 }
121 case R_rshift:
122 {
123 value =
124 reloc_stack[reloc_stack_tos - 2] >> reloc_stack[reloc_stack_tos -
125 1];
126 reloc_stack_tos -= 2;
127 break;
128 }
129 case R_and:
130 {
131 value =
132 reloc_stack[reloc_stack_tos - 2] & reloc_stack[reloc_stack_tos - 1];
133 reloc_stack_tos -= 2;
134 break;
135 }
136 case R_or:
137 {
138 value =
139 reloc_stack[reloc_stack_tos - 2] | reloc_stack[reloc_stack_tos - 1];
140 reloc_stack_tos -= 2;
141 break;
142 }
143 case R_xor:
144 {
145 value =
146 reloc_stack[reloc_stack_tos - 2] ^ reloc_stack[reloc_stack_tos - 1];
147 reloc_stack_tos -= 2;
148 break;
149 }
150 case R_land:
151 {
152 value = reloc_stack[reloc_stack_tos - 2]
153 && reloc_stack[reloc_stack_tos - 1];
154 reloc_stack_tos -= 2;
155 break;
156 }
157 case R_lor:
158 {
159 value = reloc_stack[reloc_stack_tos - 2]
160 || reloc_stack[reloc_stack_tos - 1];
161 reloc_stack_tos -= 2;
162 break;
163 }
164 case R_neg:
165 {
166 value = -reloc_stack[reloc_stack_tos - 1];
167 reloc_stack_tos--;
168 break;
169 }
170 case R_comp:
171 {
172 value = ~reloc_stack[reloc_stack_tos - 1];
173 reloc_stack_tos -= 1;
174 break;
175 }
176 default:
177 {
178 fprintf (stderr, "bfin relocation : Internal bug\n");
179 return 0;
180 }
181 }
182
183 reloc_stack_push (value);
184
185 return value;
186}
187
188/* FUNCTION : bfin_pltpc_reloc
189 ABSTRACT : TODO : figure out how to handle pltpc relocs. */
190static bfd_reloc_status_type
191bfin_pltpc_reloc (
192 bfd *abfd ATTRIBUTE_UNUSED,
193 arelent *reloc_entry ATTRIBUTE_UNUSED,
194 asymbol *symbol ATTRIBUTE_UNUSED,
195 PTR data ATTRIBUTE_UNUSED,
196 asection *input_section ATTRIBUTE_UNUSED,
197 bfd *output_bfd ATTRIBUTE_UNUSED,
198 char **error_message ATTRIBUTE_UNUSED)
199{
200 bfd_reloc_status_type flag = bfd_reloc_ok;
201 return flag;
202}
203\f
204
205static bfd_reloc_status_type
206bfin_pcrel24_reloc (bfd *abfd,
207 arelent *reloc_entry,
208 asymbol *symbol,
209 PTR data,
210 asection *input_section,
211 bfd *output_bfd,
212 char **error_message ATTRIBUTE_UNUSED)
213{
214 bfd_vma relocation;
215 bfd_size_type addr = reloc_entry->address;
216 bfd_vma output_base = 0;
217 reloc_howto_type *howto = reloc_entry->howto;
218 asection *output_section;
219 bfd_boolean relocatable = (output_bfd != NULL);
220
221 if (reloc_entry->address > bfd_get_section_limit (abfd, input_section))
222 return bfd_reloc_outofrange;
223
224 if (!is_reloc_stack_empty ())
225 relocation = reloc_stack_pop();
226 else
227 {
228 if (bfd_is_und_section (symbol->section)
229 && (symbol->flags & BSF_WEAK) == 0
230 && !relocatable)
231 return bfd_reloc_undefined;
232
233 if (bfd_is_com_section (symbol->section))
234 relocation = 0;
235 else
236 relocation = symbol->value;
237
238 output_section = symbol->section->output_section;
239
240 if (relocatable)
241 output_base = 0;
242 else
243 output_base = output_section->vma;
244
245 if (!relocatable || !strcmp (symbol->name, symbol->section->name))
246 relocation += output_base + symbol->section->output_offset;
247
248 if (!relocatable && !strcmp (symbol->name, symbol->section->name))
249 relocation += reloc_entry->addend;
250 }
251
252 relocation -= input_section->output_section->vma + input_section->output_offset;
253 relocation -= reloc_entry->address;
254
255 if (howto->complain_on_overflow != complain_overflow_dont)
256 {
257 bfd_reloc_status_type status;
258 status= bfd_check_overflow (howto->complain_on_overflow,
259 howto->bitsize,
260 howto->rightshift,
261 bfd_arch_bits_per_address(abfd),
262 relocation);
263 if (status != bfd_reloc_ok)
264 return status;
265 }
266
267 /* if rightshift is 1 and the number odd, return error. */
268 if (howto->rightshift && (relocation & 0x01))
269 {
270 fprintf(stderr, "relocation should be even number\n");
271 return bfd_reloc_overflow;
272 }
273
274 relocation >>= (bfd_vma) howto->rightshift;
275 /* Shift everything up to where it's going to be used. */
276
277 relocation <<= (bfd_vma) howto->bitpos;
278
279 if (relocatable)
280 {
281 reloc_entry->address += input_section->output_offset;
282 reloc_entry->addend += symbol->section->output_offset;
283 }
284
285 {
286 short x;
287
288 /* We are getting reloc_entry->address 2 byte off from
289 the start of instruction. Assuming absolute postion
290 of the reloc data. But, following code had been written assuming
291 reloc address is starting at begining of instruction.
292 To compensate that I have increased the value of
293 relocation by 1 (effectively 2) and used the addr -2 instead of addr. */
294
295 relocation += 1;
296 x = bfd_get_16 (abfd, (bfd_byte *) data + addr - 2);
297 x = (x & 0xff00) | ((relocation >> 16) & 0xff);
298 bfd_put_16 (abfd, x, (unsigned char *) data + addr - 2);
299
300 x = bfd_get_16 (abfd, (bfd_byte *) data + addr);
301 x = relocation & 0xFFFF;
302 bfd_put_16 (abfd, x, (unsigned char *) data + addr );
303 }
304 return bfd_reloc_ok;
305}
306
307static bfd_reloc_status_type
308bfin_push_reloc (bfd *abfd ATTRIBUTE_UNUSED,
309 arelent *reloc_entry,
310 asymbol *symbol,
311 PTR data ATTRIBUTE_UNUSED,
312 asection *input_section,
313 bfd *output_bfd,
314 char **error_message ATTRIBUTE_UNUSED)
315{
316 bfd_vma relocation;
317 bfd_vma output_base = 0;
318 asection *output_section;
319 bfd_boolean relocatable = (output_bfd != NULL);
320
321 if (bfd_is_und_section (symbol->section)
322 && (symbol->flags & BSF_WEAK) == 0
323 && !relocatable)
324 return bfd_reloc_undefined;
325
326 /* Is the address of the relocation really within the section? */
327 if (reloc_entry->address > bfd_get_section_limit(abfd, input_section))
328 return bfd_reloc_outofrange;
329
330 output_section = symbol->section->output_section;
331 relocation = symbol->value;
332
333 /* Convert input-section-relative symbol value to absolute. */
334 if (relocatable)
335 output_base = 0;
336 else
337 output_base = output_section->vma;
338
339 if (!relocatable || !strcmp(symbol->name, symbol->section->name))
340 relocation += output_base + symbol->section->output_offset;
341
342 /* Add in supplied addend. */
343 relocation += reloc_entry->addend;
344
345 if (relocatable)
346 {
347 reloc_entry->address += input_section->output_offset;
348 reloc_entry->addend += symbol->section->output_offset;
349 }
350
351 /* Now that we have the value, push it. */
352 reloc_stack_push (relocation);
353
354 return bfd_reloc_ok;
355}
356
357static bfd_reloc_status_type
358bfin_oper_reloc (bfd *abfd ATTRIBUTE_UNUSED,
359 arelent *reloc_entry,
360 asymbol *symbol ATTRIBUTE_UNUSED,
361 PTR data ATTRIBUTE_UNUSED,
362 asection *input_section,
363 bfd *output_bfd,
364 char **error_message ATTRIBUTE_UNUSED)
365{
366 bfd_boolean relocatable = (output_bfd != NULL);
367
368 /* Just call the operation based on the reloc_type. */
369 reloc_stack_operate (reloc_entry->howto->type);
370
371 if (relocatable)
372 reloc_entry->address += input_section->output_offset;
373
374 return bfd_reloc_ok;
375}
376
377static bfd_reloc_status_type
378bfin_const_reloc (bfd *abfd ATTRIBUTE_UNUSED,
379 arelent *reloc_entry,
380 asymbol *symbol ATTRIBUTE_UNUSED,
381 PTR data ATTRIBUTE_UNUSED,
382 asection *input_section,
383 bfd *output_bfd,
384 char **error_message ATTRIBUTE_UNUSED)
385{
386 bfd_boolean relocatable = (output_bfd != NULL);
387
388 /* Push the addend portion of the relocation. */
389 reloc_stack_push (reloc_entry->addend);
390
391 if (relocatable)
392 reloc_entry->address += input_section->output_offset;
393
394 return bfd_reloc_ok;
395}
396
397static bfd_reloc_status_type
398bfin_imm16_reloc (bfd *abfd,
399 arelent *reloc_entry,
400 asymbol *symbol,
401 PTR data,
402 asection *input_section,
403 bfd *output_bfd,
404 char **error_message ATTRIBUTE_UNUSED)
405{
406 bfd_vma relocation, x;
407 bfd_size_type reloc_addr = reloc_entry->address;
408 bfd_vma output_base = 0;
409 reloc_howto_type *howto = reloc_entry->howto;
410 asection *output_section;
411 bfd_boolean relocatable = (output_bfd != NULL);
412
413 /* Is the address of the relocation really within the section? */
414 if (reloc_entry->address > bfd_get_section_limit (abfd, input_section))
415 return bfd_reloc_outofrange;
416
417 if (is_reloc_stack_empty ())
418 {
419 if (bfd_is_und_section (symbol->section)
420 && (symbol->flags & BSF_WEAK) == 0
421 && !relocatable)
422 return bfd_reloc_undefined;
423
424 output_section = symbol->section->output_section;
425 relocation = symbol->value;
426
427 /* Convert input-section-relative symbol value to absolute. */
428 if (relocatable)
429 output_base = 0;
430 else
431 output_base = output_section->vma;
432
433 if (!relocatable || !strcmp (symbol->name, symbol->section->name))
434 relocation += output_base + symbol->section->output_offset;
435
f4707595
JZ
436 /* Add in supplied addend. */
437 relocation += reloc_entry->addend;
0f64bb02
CM
438 }
439 else
440 {
441 relocation = reloc_stack_pop ();
442 }
443
444 if (relocatable)
445 {
446 reloc_entry->address += input_section->output_offset;
447 reloc_entry->addend += symbol->section->output_offset;
448 }
449 else
450 {
451 reloc_entry->addend = 0;
452 }
453
454 if (howto->complain_on_overflow != complain_overflow_dont)
455 {
456 bfd_reloc_status_type flag;
457 flag = bfd_check_overflow (howto->complain_on_overflow,
458 howto->bitsize,
459 howto->rightshift,
460 bfd_arch_bits_per_address(abfd),
461 relocation);
462 if (flag != bfd_reloc_ok)
463 return flag;
464 }
465
466
467 /* Here the variable relocation holds the final address of the
468 symbol we are relocating against, plus any addend. */
469
0f64bb02
CM
470 relocation >>= (bfd_vma) howto->rightshift;
471 x = relocation;
472 bfd_put_16 (abfd, x, (unsigned char *) data + reloc_addr);
473 return bfd_reloc_ok;
474}
475
476
477static bfd_reloc_status_type
478bfin_byte4_reloc (bfd *abfd,
479 arelent *reloc_entry,
480 asymbol *symbol,
481 PTR data,
482 asection *input_section,
483 bfd *output_bfd,
484 char **error_message ATTRIBUTE_UNUSED)
485{
486 bfd_vma relocation, x;
487 bfd_size_type addr = reloc_entry->address;
488 bfd_vma output_base = 0;
489 asection *output_section;
490 bfd_boolean relocatable = (output_bfd != NULL);
491
492 /* Is the address of the relocation really within the section? */
493 if (reloc_entry->address > bfd_get_section_limit (abfd, input_section))
494 return bfd_reloc_outofrange;
495
496 if (is_reloc_stack_empty ())
497 {
498 if (bfd_is_und_section (symbol->section)
499 && (symbol->flags & BSF_WEAK) == 0
500 && !relocatable)
501 return bfd_reloc_undefined;
502
503 output_section = symbol->section->output_section;
504 relocation = symbol->value;
505 /* Convert input-section-relative symbol value to absolute. */
506 if (relocatable)
507 output_base = 0;
508 else
509 output_base = output_section->vma;
510
511 if ((symbol->name
512 && symbol->section->name
513 && !strcmp (symbol->name, symbol->section->name))
514 || !relocatable)
515 {
516 relocation += output_base + symbol->section->output_offset;
517 }
518
519 relocation += reloc_entry->addend;
520 }
521 else
522 {
523 relocation = reloc_stack_pop();
524 relocation += reloc_entry->addend;
525 }
526
527 if (relocatable)
528 {
529 /* This output will be relocatable ... like ld -r. */
530 reloc_entry->address += input_section->output_offset;
531 reloc_entry->addend += symbol->section->output_offset;
532 }
533 else
534 {
535 reloc_entry->addend = 0;
536 }
537
538 /* Here the variable relocation holds the final address of the
539 symbol we are relocating against, plus any addend. */
540 x = relocation & 0xFFFF0000;
541 x >>=16;
542 bfd_put_16 (abfd, x, (unsigned char *) data + addr + 2);
543
544 x = relocation & 0x0000FFFF;
545 bfd_put_16 (abfd, x, (unsigned char *) data + addr);
546 return bfd_reloc_ok;
547}
548
549/* bfin_bfd_reloc handles the blackfin arithmetic relocations.
550 Use this instead of bfd_perform_relocation. */
551static bfd_reloc_status_type
552bfin_bfd_reloc (bfd *abfd,
553 arelent *reloc_entry,
554 asymbol *symbol,
555 PTR data,
556 asection *input_section,
557 bfd *output_bfd,
558 char **error_message ATTRIBUTE_UNUSED)
559{
560 bfd_vma relocation;
561 bfd_size_type addr = reloc_entry->address;
562 bfd_vma output_base = 0;
563 reloc_howto_type *howto = reloc_entry->howto;
564 asection *output_section;
565 bfd_boolean relocatable = (output_bfd != NULL);
566
567 /* Is the address of the relocation really within the section? */
568 if (reloc_entry->address > bfd_get_section_limit (abfd, input_section))
569 return bfd_reloc_outofrange;
570
571 if (is_reloc_stack_empty())
572 {
573 if (bfd_is_und_section (symbol->section)
574 && (symbol->flags & BSF_WEAK) == 0
575 && !relocatable)
576 return bfd_reloc_undefined;
577
578 /* Get symbol value. (Common symbols are special.) */
579 if (bfd_is_com_section (symbol->section))
580 relocation = 0;
581 else
582 relocation = symbol->value;
583
584 output_section = symbol->section->output_section;
585
586 /* Convert input-section-relative symbol value to absolute. */
587 if (relocatable)
588 output_base = 0;
589 else
590 output_base = output_section->vma;
591
592 if (!relocatable || !strcmp (symbol->name, symbol->section->name))
593 relocation += output_base + symbol->section->output_offset;
594
595 if (!relocatable && !strcmp (symbol->name, symbol->section->name))
596 {
597 /* Add in supplied addend. */
598 relocation += reloc_entry->addend;
599 }
600
601 }
602 else
603 {
604 relocation = reloc_stack_pop();
605 }
606
607 /* Here the variable relocation holds the final address of the
608 symbol we are relocating against, plus any addend. */
609
610 if (howto->pc_relative == TRUE)
611 {
612 relocation -= input_section->output_section->vma + input_section->output_offset;
613
614 if (howto->pcrel_offset == TRUE)
615 relocation -= reloc_entry->address;
616 }
617
618 if (relocatable)
619 {
620 reloc_entry->address += input_section->output_offset;
621 reloc_entry->addend += symbol->section->output_offset;
622 }
623
624 if (howto->complain_on_overflow != complain_overflow_dont)
625 {
626 bfd_reloc_status_type status;
627
628 status = bfd_check_overflow (howto->complain_on_overflow,
629 howto->bitsize,
630 howto->rightshift,
631 bfd_arch_bits_per_address(abfd),
632 relocation);
633 if (status != bfd_reloc_ok)
634 return status;
635 }
636
637 /* If rightshift is 1 and the number odd, return error. */
638 if (howto->rightshift && (relocation & 0x01))
639 {
640 fprintf(stderr, "relocation should be even number\n");
641 return bfd_reloc_overflow;
642 }
643
644 relocation >>= (bfd_vma) howto->rightshift;
645
646 /* Shift everything up to where it's going to be used. */
647
648 relocation <<= (bfd_vma) howto->bitpos;
649
650#define DOIT(x) \
651 x = ( (x & ~howto->dst_mask) | (relocation & howto->dst_mask))
652
653 /* handle 8 and 16 bit relocations here. */
654 switch (howto->size)
655 {
656 case 0:
657 {
658 char x = bfd_get_8 (abfd, (char *) data + addr);
659 DOIT (x);
660 bfd_put_8 (abfd, x, (unsigned char *) data + addr);
661 }
662 break;
663
664 case 1:
665 {
666 unsigned short x = bfd_get_16 (abfd, (bfd_byte *) data + addr);
667 DOIT (x);
668 bfd_put_16 (abfd, (bfd_vma) x, (unsigned char *) data + addr);
669 }
670 break;
671
672 default:
673 return bfd_reloc_other;
674 }
675
676 return bfd_reloc_ok;
677}
678
679#if 0
680static bfd_reloc_status_type bfin_bfd_reloc
681 PARAMS ((bfd *, arelent *, asymbol *, PTR, asection *, bfd *, char **));
682
683static bfd_reloc_status_type bfin_imm16_reloc
684 PARAMS ((bfd *, arelent *, asymbol *, PTR, asection *, bfd *, char **));
685
686static bfd_reloc_status_type bfin_pcrel24_reloc
687 PARAMS ((bfd *, arelent *, asymbol *, PTR, asection *, bfd *, char **));
688
689static bfd_reloc_status_type bfin_pltpc_reloc
690 PARAMS ((bfd *, arelent *, asymbol *, PTR, asection *, bfd *, char **));
691
692static bfd_reloc_status_type bfin_const_reloc
693 PARAMS ((bfd *, arelent *, asymbol *, PTR, asection *, bfd *, char **));
694
695static bfd_reloc_status_type bfin_oper_reloc
696 PARAMS ((bfd *, arelent *, asymbol *, PTR, asection *, bfd *, char **));
697
698static bfd_reloc_status_type bfin_byte4_reloc
699 PARAMS ((bfd *, arelent *, asymbol *, PTR, asection *, bfd *, char **));
700
701static bfd_reloc_status_type bfin_push_reloc
702 PARAMS ((bfd *, arelent *, asymbol *, PTR, asection *, bfd *, char **));
703
704static bfd_boolean bfin_is_local_label_name
705 PARAMS ((bfd *, const char *));
706#endif
707bfd_boolean bfd_bfin_elf32_create_embedded_relocs
708 PARAMS ((bfd *, struct bfd_link_info *, asection *, asection *, char **));
709
710
711/* HOWTO Table for blackfin.
712 Blackfin relocations are fairly complicated.
713 Some of the salient features are
714 a. Even numbered offsets. A number of (not all) relocations are
715 even numbered. This means that the rightmost bit is not stored.
716 Needs to right shift by 1 and check to see if value is not odd
717 b. A relocation can be an expression. An expression takes on
718 a variety of relocations arranged in a stack.
719 As a result, we cannot use the standard generic function as special
720 function. We will have our own, which is very similar to the standard
721 generic function except that it understands how to get the value from
722 the relocation stack. . */
723
724#define BFIN_RELOC_MIN 0
725#define BFIN_RELOC_MAX 0x13
726#define BFIN_GNUEXT_RELOC_MIN 0x40
727#define BFIN_GNUEXT_RELOC_MAX 0x43
728#define BFIN_ARELOC_MIN 0xE0
729#define BFIN_ARELOC_MAX 0xF3
730
731static reloc_howto_type bfin_howto_table [] =
732{
733 /* This reloc does nothing. . */
734 HOWTO (R_unused0, /* type. */
735 0, /* rightshift. */
736 2, /* size (0 = byte, 1 = short, 2 = long). */
737 32, /* bitsize. */
738 FALSE, /* pc_relative. */
739 0, /* bitpos. */
740 complain_overflow_bitfield, /* complain_on_overflow. */
741 bfd_elf_generic_reloc, /* special_function. */
742 "R_unused0", /* name. */
743 FALSE, /* partial_inplace. */
744 0, /* src_mask. */
745 0, /* dst_mask. */
746 FALSE), /* pcrel_offset. */
747
748 HOWTO (R_pcrel5m2, /* type. */
749 1, /* rightshift. */
750 1, /* size (0 = byte, 1 = short, 2 = long).. */
751 4, /* bitsize. */
752 TRUE, /* pc_relative. */
753 0, /* bitpos. */
754 complain_overflow_unsigned, /* complain_on_overflow. */
755 bfin_bfd_reloc, /* special_function. */
756 "R_pcrel5m2", /* name. */
757 FALSE, /* partial_inplace. */
f4707595 758 0, /* src_mask. */
0f64bb02
CM
759 0x0000000F, /* dst_mask. */
760 FALSE), /* pcrel_offset. */
761
762 HOWTO (R_unused1, /* type. */
763 0, /* rightshift. */
764 2, /* size (0 = byte, 1 = short, 2 = long). */
765 32, /* bitsize. */
766 FALSE, /* pc_relative. */
767 0, /* bitpos. */
768 complain_overflow_bitfield, /* complain_on_overflow. */
769 bfd_elf_generic_reloc, /* special_function. */
770 "R_unused1", /* name. */
771 FALSE, /* partial_inplace. */
772 0, /* src_mask. */
773 0, /* dst_mask. */
774 FALSE), /* pcrel_offset. */
775
776 HOWTO (R_pcrel10, /* type. */
777 1, /* rightshift. */
778 1, /* size (0 = byte, 1 = short, 2 = long). */
779 10, /* bitsize. */
780 TRUE, /* pc_relative. */
781 0, /* bitpos. */
782 complain_overflow_signed, /* complain_on_overflow. */
783 bfin_bfd_reloc, /* special_function. */
784 "R_pcrel10", /* name. */
785 FALSE, /* partial_inplace. */
f4707595 786 0, /* src_mask. */
0f64bb02
CM
787 0x000003FF, /* dst_mask. */
788 TRUE), /* pcrel_offset. */
789
790 HOWTO (R_pcrel12_jump, /* type. */
791 1, /* rightshift. */
792 /* the offset is actually 13 bit
793 aligned on a word boundary so
794 only 12 bits have to be used.
795 Right shift the rightmost bit.. */
796 1, /* size (0 = byte, 1 = short, 2 = long). */
797 12, /* bitsize. */
798 TRUE, /* pc_relative. */
799 0, /* bitpos. */
800 complain_overflow_signed, /* complain_on_overflow. */
801 bfin_bfd_reloc, /* special_function. */
802 "R_pcrel12_jump", /* name. */
803 FALSE, /* partial_inplace. */
f4707595 804 0, /* src_mask. */
0f64bb02
CM
805 0x0FFF, /* dst_mask. */
806 TRUE), /* pcrel_offset. */
807
808 HOWTO (R_rimm16, /* type. */
809 0, /* rightshift. */
810 1, /* size (0 = byte, 1 = short, 2 = long). */
811 16, /* bitsize. */
812 FALSE, /* pc_relative. */
813 0, /* bitpos. */
814 complain_overflow_signed, /* complain_on_overflow. */
815 bfin_imm16_reloc, /* special_function. */
816 "R_rimm16", /* name. */
817 FALSE, /* partial_inplace. */
f4707595 818 0, /* src_mask. */
0f64bb02
CM
819 0x0000FFFF, /* dst_mask. */
820 TRUE), /* pcrel_offset. */
821
822 HOWTO (R_luimm16, /* type. */
823 0, /* rightshift. */
824 1, /* size (0 = byte, 1 = short, 2 = long). */
825 16, /* bitsize. */
826 FALSE, /* pc_relative. */
827 0, /* bitpos. */
828 complain_overflow_dont, /* complain_on_overflow. */
829 bfin_imm16_reloc, /* special_function. */
830 "R_luimm16", /* name. */
831 FALSE, /* partial_inplace. */
f4707595 832 0, /* src_mask. */
0f64bb02
CM
833 0x0000FFFF, /* dst_mask. */
834 TRUE), /* pcrel_offset. */
835
836 HOWTO (R_huimm16, /* type. */
837 16, /* rightshift. */
838 1, /* size (0 = byte, 1 = short, 2 = long). */
839 16, /* bitsize. */
840 FALSE, /* pc_relative. */
841 0, /* bitpos. */
842 complain_overflow_unsigned, /* complain_on_overflow. */
843 bfin_imm16_reloc, /* special_function. */
844 "R_huimm16", /* name. */
845 FALSE, /* partial_inplace. */
f4707595 846 0, /* src_mask. */
0f64bb02
CM
847 0x0000FFFF, /* dst_mask. */
848 TRUE), /* pcrel_offset. */
849
850 HOWTO (R_pcrel12_jump_s, /* type. */
851 1, /* rightshift. */
852 1, /* size (0 = byte, 1 = short, 2 = long). */
853 12, /* bitsize. */
854 TRUE, /* pc_relative. */
855 0, /* bitpos. */
856 complain_overflow_signed, /* complain_on_overflow. */
857 bfin_bfd_reloc, /* special_function. */
858 "R_pcrel12_jump_s", /* name. */
859 FALSE, /* partial_inplace. */
f4707595 860 0, /* src_mask. */
0f64bb02
CM
861 0x00000FFF, /* dst_mask. */
862 TRUE), /* pcrel_offset. */
863
864 HOWTO (R_pcrel24_jump_x, /* type. */
865 1, /* rightshift. */
866 2, /* size (0 = byte, 1 = short, 2 = long). */
867 24, /* bitsize. */
868 TRUE, /* pc_relative. */
869 0, /* bitpos. */
870 complain_overflow_signed, /* complain_on_overflow. */
871 bfin_pcrel24_reloc, /* special_function. */
872 "R_pcrel24_jump_x", /* name. */
873 FALSE, /* partial_inplace. */
f4707595 874 0, /* src_mask. */
0f64bb02
CM
875 0x00FFFFFF, /* dst_mask. */
876 TRUE), /* pcrel_offset. */
877
878 HOWTO (R_pcrel24, /* type. */
879 1, /* rightshift. */
880 2, /* size (0 = byte, 1 = short, 2 = long). */
881 24, /* bitsize. */
882 TRUE, /* pc_relative. */
883 0, /* bitpos. */
884 complain_overflow_signed, /* complain_on_overflow. */
885 bfin_pcrel24_reloc, /* special_function. */
886 "R_pcrel24", /* name. */
887 FALSE, /* partial_inplace. */
f4707595 888 0, /* src_mask. */
0f64bb02
CM
889 0x00FFFFFF, /* dst_mask. */
890 TRUE), /* pcrel_offset. */
891
892 HOWTO (R_unusedb, /* type. */
893 0, /* rightshift. */
894 2, /* size (0 = byte, 1 = short, 2 = long). */
895 32, /* bitsize. */
896 FALSE, /* pc_relative. */
897 0, /* bitpos. */
898 complain_overflow_dont, /* complain_on_overflow. */
899 bfd_elf_generic_reloc, /* special_function. */
900 "R_unusedb", /* name. */
901 FALSE, /* partial_inplace. */
902 0, /* src_mask. */
903 0, /* dst_mask. */
904 FALSE), /* pcrel_offset. */
905
906 HOWTO (R_unusedc, /* type. */
907 0, /* rightshift. */
908 2, /* size (0 = byte, 1 = short, 2 = long). */
909 32, /* bitsize. */
910 FALSE, /* pc_relative. */
911 0, /* bitpos. */
912 complain_overflow_dont, /* complain_on_overflow. */
913 bfd_elf_generic_reloc, /* special_function. */
914 "R_unusedc", /* name. */
915 FALSE, /* partial_inplace. */
916 0, /* src_mask. */
917 0, /* dst_mask. */
918 FALSE), /* pcrel_offset. */
919
920 HOWTO (R_pcrel24_jump_l, /* type. */
921 1, /* rightshift. */
922 2, /* size (0 = byte, 1 = short, 2 = long). */
923 24, /* bitsize. */
924 TRUE, /* pc_relative. */
925 0, /* bitpos. */
926 complain_overflow_signed, /* complain_on_overflow. */
927 bfin_pcrel24_reloc, /* special_function. */
928 "R_pcrel24_jump_l", /* name. */
929 FALSE, /* partial_inplace. */
f4707595 930 0, /* src_mask. */
0f64bb02
CM
931 0x00FFFFFF, /* dst_mask. */
932 TRUE), /* pcrel_offset. */
933
934 HOWTO (R_pcrel24_call_x, /* type. */
935 1, /* rightshift. */
936 2, /* size (0 = byte, 1 = short, 2 = long). */
937 24, /* bitsize. */
938 TRUE, /* pc_relative. */
939 0, /* bitpos. */
940 complain_overflow_signed, /* complain_on_overflow. */
941 bfin_pcrel24_reloc, /* special_function. */
942 "R_pcrel24_call_x", /* name. */
943 FALSE, /* partial_inplace. */
f4707595 944 0, /* src_mask. */
0f64bb02
CM
945 0x00FFFFFF, /* dst_mask. */
946 TRUE), /* pcrel_offset. */
947
948 HOWTO (R_var_eq_symb, /* type. */
949 0, /* rightshift. */
950 2, /* size (0 = byte, 1 = short, 2 = long). */
951 32, /* bitsize. */
952 FALSE, /* pc_relative. */
953 0, /* bitpos. */
954 complain_overflow_bitfield, /* complain_on_overflow. */
955 bfin_bfd_reloc, /* special_function. */
956 "R_var_eq_symb", /* name. */
957 FALSE, /* partial_inplace. */
958 0, /* src_mask. */
959 0, /* dst_mask. */
960 FALSE), /* pcrel_offset. */
961
962 HOWTO (R_byte_data, /* type. */
963 0, /* rightshift. */
964 0, /* size (0 = byte, 1 = short, 2 = long). */
965 8, /* bitsize. */
966 FALSE, /* pc_relative. */
967 0, /* bitpos. */
968 complain_overflow_unsigned, /* complain_on_overflow. */
969 bfin_bfd_reloc, /* special_function. */
970 "R_byte_data", /* name. */
971 FALSE, /* partial_inplace. */
f4707595 972 0, /* src_mask. */
0f64bb02
CM
973 0xFF, /* dst_mask. */
974 TRUE), /* pcrel_offset. */
975
976 HOWTO (R_byte2_data, /* type. */
977 0, /* rightshift. */
978 1, /* size (0 = byte, 1 = short, 2 = long). */
979 16, /* bitsize. */
980 FALSE, /* pc_relative. */
981 0, /* bitpos. */
982 complain_overflow_signed, /* complain_on_overflow. */
983 bfin_bfd_reloc, /* special_function. */
984 "R_byte2_data", /* name. */
985 FALSE, /* partial_inplace. */
f4707595 986 0, /* src_mask. */
0f64bb02
CM
987 0xFFFF, /* dst_mask. */
988 TRUE), /* pcrel_offset. */
989
990 HOWTO (R_byte4_data, /* type. */
991 0, /* rightshift. */
992 2, /* size (0 = byte, 1 = short, 2 = long). */
993 32, /* bitsize. */
994 FALSE, /* pc_relative. */
995 0, /* bitpos. */
996 complain_overflow_unsigned, /* complain_on_overflow. */
997 bfin_byte4_reloc, /* special_function. */
998 "R_byte4_data", /* name. */
999 FALSE, /* partial_inplace. */
f4707595 1000 0, /* src_mask. */
0f64bb02
CM
1001 0xFFFFFFFF, /* dst_mask. */
1002 TRUE), /* pcrel_offset. */
1003
1004 HOWTO (R_pcrel11, /* type. */
1005 1, /* rightshift. */
1006 1, /* size (0 = byte, 1 = short, 2 = long). */
1007 10, /* bitsize. */
1008 TRUE, /* pc_relative. */
1009 0, /* bitpos. */
1010 complain_overflow_unsigned, /* complain_on_overflow. */
1011 bfin_bfd_reloc, /* special_function. */
1012 "R_pcrel11", /* name. */
1013 FALSE, /* partial_inplace. */
f4707595 1014 0, /* src_mask. */
0f64bb02
CM
1015 0x000003FF, /* dst_mask. */
1016 FALSE), /* pcrel_offset. */
1017};
1018
1019static reloc_howto_type bfin_areloc_howto_table [] =
1020{
1021 HOWTO (R_push,
1022 0,
1023 2,
1024 0,
1025 FALSE,
1026 0,
1027 complain_overflow_dont,
1028 bfin_push_reloc,
1029 "R_expst_push",
1030 FALSE,
1031 0,
1032 0,
1033 FALSE),
1034
1035 HOWTO (R_const,
1036 0,
1037 2,
1038 0,
1039 FALSE,
1040 0,
1041 complain_overflow_dont,
1042 bfin_const_reloc,
1043 "R_expst_const",
1044 FALSE,
1045 0,
1046 0,
1047 FALSE),
1048
1049 HOWTO (R_add,
1050 0,
1051 0,
1052 0,
1053 FALSE,
1054 0,
1055 complain_overflow_dont,
1056 bfin_oper_reloc,
1057 "R_expst_add",
1058 FALSE,
1059 0,
1060 0,
1061 FALSE),
1062
1063 HOWTO (R_sub,
1064 0,
1065 0,
1066 0,
1067 FALSE,
1068 0,
1069 complain_overflow_dont,
1070 bfin_oper_reloc,
1071 "R_expst_sub",
1072 FALSE,
1073 0,
1074 0,
1075 FALSE),
1076
1077 HOWTO (R_mult,
1078 0,
1079 0,
1080 0,
1081 FALSE,
1082 0,
1083 complain_overflow_dont,
1084 bfin_oper_reloc,
1085 "R_expst_mult",
1086 FALSE,
1087 0,
1088 0,
1089 FALSE),
1090
1091 HOWTO (R_div, /* type. */
1092 0, /* rightshift. */
1093 0, /* size (0 = byte, 1 = short, 2 = long). */
1094 0, /* bitsize. */
1095 FALSE, /* pc_relative. */
1096 0, /* bitpos. */
1097 complain_overflow_dont, /* complain_on_overflow. */
1098 bfin_oper_reloc, /* special_function. */
1099 "R_expst_div", /* name. */
1100 FALSE, /* partial_inplace. */
1101 0, /* src_mask. */
1102 0, /* dst_mask. */
1103 FALSE), /* pcrel_offset. */
1104
1105 HOWTO (R_mod, /* type. */
1106 0, /* rightshift. */
1107 0, /* size (0 = byte, 1 = short, 2 = long). */
1108 0, /* bitsize. */
1109 FALSE, /* pc_relative. */
1110 0, /* bitpos. */
1111 complain_overflow_dont, /* complain_on_overflow. */
1112 bfin_oper_reloc, /* special_function. */
1113 "R_expst_mod", /* name. */
1114 FALSE, /* partial_inplace. */
1115 0, /* src_mask. */
1116 0, /* dst_mask. */
1117 FALSE), /* pcrel_offset. */
1118
1119 HOWTO (R_lshift, /* type. */
1120 0, /* rightshift. */
1121 0, /* size (0 = byte, 1 = short, 2 = long). */
1122 0, /* bitsize. */
1123 FALSE, /* pc_relative. */
1124 0, /* bitpos. */
1125 complain_overflow_dont, /* complain_on_overflow. */
1126 bfin_oper_reloc, /* special_function. */
1127 "R_expst_lshift", /* name. */
1128 FALSE, /* partial_inplace. */
1129 0, /* src_mask. */
1130 0, /* dst_mask. */
1131 FALSE), /* pcrel_offset. */
1132
1133 HOWTO (R_rshift, /* type. */
1134 0, /* rightshift. */
1135 0, /* size (0 = byte, 1 = short, 2 = long). */
1136 0, /* bitsize. */
1137 FALSE, /* pc_relative. */
1138 0, /* bitpos. */
1139 complain_overflow_dont, /* complain_on_overflow. */
1140 bfin_oper_reloc, /* special_function. */
1141 "R_expst_rshift", /* name. */
1142 FALSE, /* partial_inplace. */
1143 0, /* src_mask. */
1144 0, /* dst_mask. */
1145 FALSE), /* pcrel_offset. */
1146
1147 HOWTO (R_and, /* type. */
1148 0, /* rightshift. */
1149 0, /* size (0 = byte, 1 = short, 2 = long). */
1150 0, /* bitsize. */
1151 FALSE, /* pc_relative. */
1152 0, /* bitpos. */
1153 complain_overflow_dont, /* complain_on_overflow. */
1154 bfin_oper_reloc, /* special_function. */
1155 "R_expst_and", /* name. */
1156 FALSE, /* partial_inplace. */
1157 0, /* src_mask. */
1158 0, /* dst_mask. */
1159 FALSE), /* pcrel_offset. */
1160
1161 HOWTO (R_or, /* type. */
1162 0, /* rightshift. */
1163 0, /* size (0 = byte, 1 = short, 2 = long). */
1164 0, /* bitsize. */
1165 FALSE, /* pc_relative. */
1166 0, /* bitpos. */
1167 complain_overflow_dont, /* complain_on_overflow. */
1168 bfin_oper_reloc, /* special_function. */
1169 "R_expst_or", /* name. */
1170 FALSE, /* partial_inplace. */
1171 0, /* src_mask. */
1172 0, /* dst_mask. */
1173 FALSE), /* pcrel_offset. */
1174
1175 HOWTO (R_xor, /* type. */
1176 0, /* rightshift. */
1177 0, /* size (0 = byte, 1 = short, 2 = long). */
1178 0, /* bitsize. */
1179 FALSE, /* pc_relative. */
1180 0, /* bitpos. */
1181 complain_overflow_dont, /* complain_on_overflow. */
1182 bfin_oper_reloc, /* special_function. */
1183 "R_expst_xor", /* name. */
1184 FALSE, /* partial_inplace. */
1185 0, /* src_mask. */
1186 0, /* dst_mask. */
1187 FALSE), /* pcrel_offset. */
1188
1189 HOWTO (R_land, /* type. */
1190 0, /* rightshift. */
1191 0, /* size (0 = byte, 1 = short, 2 = long). */
1192 0, /* bitsize. */
1193 FALSE, /* pc_relative. */
1194 0, /* bitpos. */
1195 complain_overflow_dont, /* complain_on_overflow. */
1196 bfin_oper_reloc, /* special_function. */
1197 "R_expst_land", /* name. */
1198 FALSE, /* partial_inplace. */
1199 0, /* src_mask. */
1200 0, /* dst_mask. */
1201 FALSE), /* pcrel_offset. */
1202
1203 HOWTO (R_lor, /* type. */
1204 0, /* rightshift. */
1205 0, /* size (0 = byte, 1 = short, 2 = long). */
1206 0, /* bitsize. */
1207 FALSE, /* pc_relative. */
1208 0, /* bitpos. */
1209 complain_overflow_dont, /* complain_on_overflow. */
1210 bfin_oper_reloc, /* special_function. */
1211 "R_expst_lor", /* name. */
1212 FALSE, /* partial_inplace. */
1213 0, /* src_mask. */
1214 0, /* dst_mask. */
1215 FALSE), /* pcrel_offset. */
1216
1217 HOWTO (R_len, /* type. */
1218 0, /* rightshift. */
1219 0, /* size (0 = byte, 1 = short, 2 = long). */
1220 0, /* bitsize. */
1221 FALSE, /* pc_relative. */
1222 0, /* bitpos. */
1223 complain_overflow_dont, /* complain_on_overflow. */
1224 bfin_oper_reloc, /* special_function. */
1225 "R_expst_len", /* name. */
1226 FALSE, /* partial_inplace. */
1227 0, /* src_mask. */
1228 0, /* dst_mask. */
1229 FALSE), /* pcrel_offset. */
1230
1231 HOWTO (R_neg, /* type. */
1232 0, /* rightshift. */
1233 0, /* size (0 = byte, 1 = short, 2 = long). */
1234 0, /* bitsize. */
1235 FALSE, /* pc_relative. */
1236 0, /* bitpos. */
1237 complain_overflow_dont, /* complain_on_overflow. */
1238 bfin_oper_reloc, /* special_function. */
1239 "R_expst_neg", /* name. */
1240 FALSE, /* partial_inplace. */
1241 0, /* src_mask. */
1242 0, /* dst_mask. */
1243 FALSE), /* pcrel_offset. */
1244
1245 HOWTO (R_comp, /* type. */
1246 0, /* rightshift. */
1247 0, /* size (0 = byte, 1 = short, 2 = long). */
1248 0, /* bitsize. */
1249 FALSE, /* pc_relative. */
1250 0, /* bitpos. */
1251 complain_overflow_dont, /* complain_on_overflow. */
1252 bfin_oper_reloc, /* special_function. */
1253 "R_expst_comp", /* name. */
1254 FALSE, /* partial_inplace. */
1255 0, /* src_mask. */
1256 0, /* dst_mask. */
1257 FALSE), /* pcrel_offset. */
1258
1259 HOWTO (R_page, /* type. */
1260 0, /* rightshift. */
1261 0, /* size (0 = byte, 1 = short, 2 = long). */
1262 0, /* bitsize. */
1263 FALSE, /* pc_relative. */
1264 0, /* bitpos. */
1265 complain_overflow_dont, /* complain_on_overflow. */
1266 bfin_oper_reloc, /* special_function. */
1267 "R_expst_page", /* name. */
1268 FALSE, /* partial_inplace. */
1269 0, /* src_mask. */
1270 0, /* dst_mask. */
1271 FALSE), /* pcrel_offset. */
1272
1273 HOWTO (R_hwpage, /* type. */
1274 0, /* rightshift. */
1275 0, /* size (0 = byte, 1 = short, 2 = long). */
1276 0, /* bitsize. */
1277 FALSE, /* pc_relative. */
1278 0, /* bitpos. */
1279 complain_overflow_dont, /* complain_on_overflow. */
1280 bfin_oper_reloc, /* special_function. */
1281 "R_expst_hwpage", /* name. */
1282 FALSE, /* partial_inplace. */
1283 0, /* src_mask. */
1284 0, /* dst_mask. */
1285 FALSE), /* pcrel_offset. */
1286
1287 HOWTO (R_addr, /* type. */
1288 0, /* rightshift. */
1289 0, /* size (0 = byte, 1 = short, 2 = long). */
1290 0, /* bitsize. */
1291 FALSE, /* pc_relative. */
1292 0, /* bitpos. */
1293 complain_overflow_dont, /* complain_on_overflow. */
1294 bfin_oper_reloc, /* special_function. */
1295 "R_expst_addr", /* name. */
1296 FALSE, /* partial_inplace. */
1297 0, /* src_mask. */
1298 0, /* dst_mask. */
1299 FALSE), /* pcrel_offset. */
1300};
1301
1302static reloc_howto_type bfin_gnuext_howto_table [] =
1303{
1304 HOWTO (R_pltpc, /* type. */
1305 0, /* rightshift. */
1306 1, /* size (0 = byte, 1 = short, 2 = long). */
1307 16, /* bitsize. */
1308 FALSE, /* pc_relative. */
1309 0, /* bitpos. */
1310 complain_overflow_bitfield, /* complain_on_overflow. */
1311 bfin_pltpc_reloc, /* special_function. */
1312 "R_pltpc", /* name. */
1313 FALSE, /* partial_inplace. */
1314 0xffff, /* src_mask. */
1315 0xffff, /* dst_mask. */
1316 FALSE), /* pcrel_offset. */
1317
1318 HOWTO (R_got, /* type. */
1319 0, /* rightshift. */
1320 1, /* size (0 = byte, 1 = short, 2 = long). */
1321 16, /* bitsize. */
1322 FALSE, /* pc_relative. */
1323 0, /* bitpos. */
1324 complain_overflow_bitfield, /* complain_on_overflow. */
1325 bfd_elf_generic_reloc, /* special_function. */
1326 "R_got", /* name. */
1327 FALSE, /* partial_inplace. */
1328 0x7fff, /* src_mask. */
1329 0x7fff, /* dst_mask. */
1330 FALSE), /* pcrel_offset. */
1331
1332/* GNU extension to record C++ vtable hierarchy. */
1333 HOWTO (R_BFIN_GNU_VTINHERIT, /* type. */
1334 0, /* rightshift. */
1335 2, /* size (0 = byte, 1 = short, 2 = long). */
1336 0, /* bitsize. */
1337 FALSE, /* pc_relative. */
1338 0, /* bitpos. */
1339 complain_overflow_dont, /* complain_on_overflow. */
1340 NULL, /* special_function. */
1341 "R_BFIN_GNU_VTINHERIT", /* name. */
1342 FALSE, /* partial_inplace. */
1343 0, /* src_mask. */
1344 0, /* dst_mask. */
1345 FALSE), /* pcrel_offset. */
1346
1347/* GNU extension to record C++ vtable member usage. */
1348 HOWTO (R_BFIN_GNU_VTENTRY, /* type. */
1349 0, /* rightshift. */
1350 2, /* size (0 = byte, 1 = short, 2 = long). */
1351 0, /* bitsize. */
1352 FALSE, /* pc_relative. */
1353 0, /* bitpos. */
1354 complain_overflow_dont, /* complain_on_overflow. */
1355 _bfd_elf_rel_vtable_reloc_fn, /* special_function. */
1356 "R_BFIN_GNU_VTENTRY", /* name. */
1357 FALSE, /* partial_inplace. */
1358 0, /* src_mask. */
1359 0, /* dst_mask. */
1360 FALSE) /* pcrel_offset. */
1361};
1362
1363struct bfin_reloc_map
1364{
1365 bfd_reloc_code_real_type bfd_reloc_val;
1366 unsigned int bfin_reloc_val;
1367};
1368
1369static const struct bfin_reloc_map bfin_reloc_map [] =
1370{
1371 { BFD_RELOC_NONE, R_unused0 },
1372 { BFD_RELOC_BFIN_5_PCREL, R_pcrel5m2 },
1373 { BFD_RELOC_NONE, R_unused1 },
1374 { BFD_RELOC_BFIN_10_PCREL, R_pcrel10 },
1375 { BFD_RELOC_BFIN_12_PCREL_JUMP, R_pcrel12_jump },
1376 { BFD_RELOC_BFIN_16_IMM, R_rimm16 },
1377 { BFD_RELOC_BFIN_16_LOW, R_luimm16 },
1378 { BFD_RELOC_BFIN_16_HIGH, R_huimm16 },
1379 { BFD_RELOC_BFIN_12_PCREL_JUMP_S, R_pcrel12_jump_s },
1380 { BFD_RELOC_24_PCREL, R_pcrel24 },
1381 { BFD_RELOC_24_PCREL, R_pcrel24 },
1382 { BFD_RELOC_BFIN_24_PCREL_JUMP_L, R_pcrel24_jump_l },
1383 { BFD_RELOC_NONE, R_unusedb },
1384 { BFD_RELOC_NONE, R_unusedc },
1385 { BFD_RELOC_BFIN_24_PCREL_CALL_X, R_pcrel24_call_x },
1386 { BFD_RELOC_8, R_byte_data },
1387 { BFD_RELOC_16, R_byte2_data },
1388 { BFD_RELOC_32, R_byte4_data },
1389 { BFD_RELOC_BFIN_11_PCREL, R_pcrel11 },
1390 { BFD_RELOC_BFIN_GOT, R_got },
1391 { BFD_RELOC_BFIN_PLTPC, R_pltpc },
1392 { BFD_RELOC_VTABLE_INHERIT, R_BFIN_GNU_VTINHERIT },
1393 { BFD_RELOC_VTABLE_ENTRY, R_BFIN_GNU_VTENTRY },
1394 { BFD_ARELOC_BFIN_PUSH, R_push },
1395 { BFD_ARELOC_BFIN_CONST, R_const },
1396 { BFD_ARELOC_BFIN_ADD, R_add },
1397 { BFD_ARELOC_BFIN_SUB, R_sub },
1398 { BFD_ARELOC_BFIN_MULT, R_mult },
1399 { BFD_ARELOC_BFIN_DIV, R_div },
1400 { BFD_ARELOC_BFIN_MOD, R_mod },
1401 { BFD_ARELOC_BFIN_LSHIFT, R_lshift },
1402 { BFD_ARELOC_BFIN_RSHIFT, R_rshift },
1403 { BFD_ARELOC_BFIN_AND, R_and },
1404 { BFD_ARELOC_BFIN_OR, R_or },
1405 { BFD_ARELOC_BFIN_XOR, R_xor },
1406 { BFD_ARELOC_BFIN_LAND, R_land },
1407 { BFD_ARELOC_BFIN_LOR, R_lor },
1408 { BFD_ARELOC_BFIN_LEN, R_len },
1409 { BFD_ARELOC_BFIN_NEG, R_neg },
1410 { BFD_ARELOC_BFIN_COMP, R_comp },
1411 { BFD_ARELOC_BFIN_PAGE, R_page },
1412 { BFD_ARELOC_BFIN_HWPAGE, R_hwpage },
1413 { BFD_ARELOC_BFIN_ADDR, R_addr }
1414
1415};
1416
1417
1418static void
1419bfin_info_to_howto (bfd *abfd ATTRIBUTE_UNUSED,
1420 arelent *cache_ptr,
1421 Elf_Internal_Rela *dst)
1422{
1423 unsigned int r_type;
1424
1425 r_type = ELF32_R_TYPE (dst->r_info);
1426
1427 if (r_type <= BFIN_RELOC_MAX)
1428 cache_ptr->howto = &bfin_howto_table [r_type];
1429
1430 else if (r_type >= BFIN_ARELOC_MIN && r_type <= BFIN_ARELOC_MAX)
1431 cache_ptr->howto = &bfin_areloc_howto_table [r_type - BFIN_ARELOC_MIN];
1432
1433 else if (r_type >= BFIN_GNUEXT_RELOC_MIN && r_type <= BFIN_GNUEXT_RELOC_MAX)
1434 cache_ptr->howto = &bfin_gnuext_howto_table [r_type - BFIN_GNUEXT_RELOC_MIN];
1435
1436 else
1437 cache_ptr->howto = (reloc_howto_type *) NULL;
1438
1439}
1440/* Given a BFD reloc type, return the howto. */
1441static reloc_howto_type *
1442bfin_bfd_reloc_type_lookup (bfd * abfd ATTRIBUTE_UNUSED,
1443 bfd_reloc_code_real_type code)
1444{
1445 unsigned int i;
1446 unsigned int r_type = BFIN_RELOC_MIN;
1447
1448 for (i = sizeof (bfin_reloc_map) / sizeof (bfin_reloc_map[0]); --i;)
1449 if (bfin_reloc_map[i].bfd_reloc_val == code)
1450 r_type = bfin_reloc_map[i].bfin_reloc_val;
1451
1452 if (r_type <= BFIN_RELOC_MAX && r_type > BFIN_RELOC_MIN)
1453 return &bfin_howto_table [r_type];
1454
1455 else if (r_type >= BFIN_ARELOC_MIN && r_type <= BFIN_ARELOC_MAX)
1456 return &bfin_areloc_howto_table [r_type - BFIN_ARELOC_MIN];
1457
1458 else if (r_type >= BFIN_GNUEXT_RELOC_MIN && r_type <= BFIN_GNUEXT_RELOC_MAX)
1459 return &bfin_gnuext_howto_table [r_type - BFIN_GNUEXT_RELOC_MIN];
1460
1461 return (reloc_howto_type *) NULL;
1462
1463}
1464/* Given a bfin relocation type, return the howto. */
1465static reloc_howto_type *
1466bfin_reloc_type_lookup (bfd * abfd ATTRIBUTE_UNUSED,
1467 unsigned int r_type)
1468{
1469 if (r_type <= BFIN_RELOC_MAX)
1470 return &bfin_howto_table [r_type];
1471
1472 else if (r_type >= BFIN_ARELOC_MIN && r_type <= BFIN_ARELOC_MAX)
1473 return &bfin_areloc_howto_table [r_type - BFIN_ARELOC_MIN];
1474
1475 else if (r_type >= BFIN_GNUEXT_RELOC_MIN && r_type <= BFIN_GNUEXT_RELOC_MAX)
1476 return &bfin_gnuext_howto_table [r_type - BFIN_GNUEXT_RELOC_MIN];
1477
1478 return (reloc_howto_type *) NULL;
1479
1480}
1481
1482/* Return TRUE if the name is a local label.
1483 bfin local labels begin with L$. */
1484static bfd_boolean
1485bfin_is_local_label_name (
1486 bfd *abfd ATTRIBUTE_UNUSED,
1487 const char *label)
1488{
1489 if (label[0] == 'L' && label[1] == '$' )
1490 return TRUE;
1491
1492 return _bfd_elf_is_local_label_name (abfd, label);
1493}
1494
1495
1496/* Look through the relocs for a section during the first phase, and
1497 allocate space in the global offset table or procedure linkage
1498 table. */
1499
1500static bfd_boolean
1501bfin_check_relocs (bfd * abfd,
1502 struct bfd_link_info *info,
1503 asection *sec,
1504 const Elf_Internal_Rela *relocs)
1505{
1506 bfd *dynobj;
1507 Elf_Internal_Shdr *symtab_hdr;
1508 struct elf_link_hash_entry **sym_hashes;
1509 bfd_signed_vma *local_got_refcounts;
1510 const Elf_Internal_Rela *rel;
1511 const Elf_Internal_Rela *rel_end;
1512 asection *sgot;
1513 asection *srelgot;
1514 asection *sreloc;
1515 if (info->relocatable)
1516 return TRUE;
1517
1518 dynobj = elf_hash_table (info)->dynobj;
1519 symtab_hdr = &elf_tdata (abfd)->symtab_hdr;
1520 sym_hashes = elf_sym_hashes (abfd);
1521 local_got_refcounts = elf_local_got_refcounts (abfd);
1522
1523 sgot = NULL;
1524 srelgot = NULL;
1525 sreloc = NULL;
1526
1527 rel_end = relocs + sec->reloc_count;
1528 for (rel = relocs; rel < rel_end; rel++)
1529 {
1530 unsigned long r_symndx;
1531 struct elf_link_hash_entry *h;
1532
1533 r_symndx = ELF32_R_SYM (rel->r_info);
1534 if (r_symndx < symtab_hdr->sh_info)
1535 h = NULL;
1536 else
1537 h = sym_hashes[r_symndx - symtab_hdr->sh_info];
1538
1539 switch (ELF32_R_TYPE (rel->r_info))
1540 {
1541 /* This relocation describes the C++ object vtable hierarchy.
1542 Reconstruct it for later use during GC. */
1543 case R_BFIN_GNU_VTINHERIT:
1544 if (!bfd_elf_gc_record_vtinherit (abfd, sec, h, rel->r_offset))
1545 return FALSE;
1546 break;
1547
1548 /* This relocation describes which C++ vtable entries
1549 are actually used. Record for later use during GC. */
1550 case R_BFIN_GNU_VTENTRY:
1551 if (!bfd_elf_gc_record_vtentry (abfd, sec, h, rel->r_addend))
1552 return FALSE;
1553 break;
1554
1555 case R_got:
1556 if (h != NULL
1557 && strcmp (h->root.root.string, "_GLOBAL_OFFSET_TABLE_") == 0)
1558 break;
1559 /* Fall through. */
1560
1561 if (dynobj == NULL)
1562 {
1563 /* Create the .got section. */
1564 elf_hash_table (info)->dynobj = dynobj = abfd;
1565 if (!_bfd_elf_create_got_section (dynobj, info))
1566 return FALSE;
1567 }
1568
1569 if (sgot == NULL)
1570 {
1571 sgot = bfd_get_section_by_name (dynobj, ".got");
1572 BFD_ASSERT (sgot != NULL);
1573 }
1574
1575 if (srelgot == NULL && (h != NULL || info->shared))
1576 {
1577 srelgot = bfd_get_section_by_name (dynobj, ".rela.got");
1578 if (srelgot == NULL)
1579 {
1580 srelgot = bfd_make_section (dynobj, ".rela.got");
1581 if (srelgot == NULL
1582 || !bfd_set_section_flags (dynobj, srelgot,
1583 (SEC_ALLOC
1584 | SEC_LOAD
1585 | SEC_HAS_CONTENTS
1586 | SEC_IN_MEMORY
1587 | SEC_LINKER_CREATED
1588 | SEC_READONLY))
1589 || !bfd_set_section_alignment (dynobj, srelgot, 2))
1590 return FALSE;
1591 }
1592 }
1593
1594 if (h != NULL)
1595 {
1596 if (h->got.refcount == 0)
1597 {
1598 /* Make sure this symbol is output as a dynamic symbol. */
1599 if (h->dynindx == -1 && !h->forced_local)
1600 {
1601 if (!bfd_elf_link_record_dynamic_symbol (info, h))
1602 return FALSE;
1603 }
1604
1605 /* Allocate space in the .got section. */
1606 sgot->size += 4;
1607 /* Allocate relocation space. */
1608 srelgot->size += sizeof (Elf32_External_Rela);
1609 }
1610 h->got.refcount++;
1611 }
1612 else
1613 {
1614 /* This is a global offset table entry for a local symbol. */
1615 if (local_got_refcounts == NULL)
1616 {
1617 bfd_size_type size;
1618
1619 size = symtab_hdr->sh_info;
1620 size *= sizeof (bfd_signed_vma);
1621 local_got_refcounts = ((bfd_signed_vma *)
1622 bfd_zalloc (abfd, size));
1623 if (local_got_refcounts == NULL)
1624 return FALSE;
1625 elf_local_got_refcounts (abfd) = local_got_refcounts;
1626 }
1627 if (local_got_refcounts[r_symndx] == 0)
1628 {
1629 sgot->size += 4;
1630 if (info->shared)
1631 {
1632 /* If we are generating a shared object, we need to
1633 output a R_68K_RELATIVE reloc so that the dynamic
1634 linker can adjust this GOT entry. */
1635 srelgot->size += sizeof (Elf32_External_Rela);
1636 }
1637 }
1638 local_got_refcounts[r_symndx]++;
1639 }
1640 break;
1641
1642 default:
1643 break;
1644 }
1645 }
1646
1647 return TRUE;
1648}
1649
1650static enum elf_reloc_type_class
1651elf32_bfin_reloc_type_class (const Elf_Internal_Rela * rela)
1652{
1653 switch ((int) ELF32_R_TYPE (rela->r_info))
1654 {
1655 default:
1656 return reloc_class_normal;
1657 }
1658}
f4707595 1659
0f64bb02
CM
1660static bfd_boolean
1661bfin_relocate_section (bfd * output_bfd,
1662 struct bfd_link_info *info,
1663 bfd * input_bfd,
1664 asection * input_section,
1665 bfd_byte * contents,
1666 Elf_Internal_Rela * relocs,
1667 Elf_Internal_Sym * local_syms,
1668 asection ** local_sections)
1669{
1670 bfd *dynobj;
1671 Elf_Internal_Shdr *symtab_hdr;
1672 struct elf_link_hash_entry **sym_hashes;
1673 bfd_vma *local_got_offsets;
1674 asection *sgot;
1675 asection *sreloc;
1676 Elf_Internal_Rela *rel;
1677 Elf_Internal_Rela *relend;
0f64bb02
CM
1678 int i = 0;
1679
1680 if (info->relocatable)
1681 return TRUE;
1682
1683 dynobj = elf_hash_table (info)->dynobj;
1684 symtab_hdr = &elf_tdata (input_bfd)->symtab_hdr;
1685 sym_hashes = elf_sym_hashes (input_bfd);
1686 local_got_offsets = elf_local_got_offsets (input_bfd);
1687
1688 sgot = NULL;
1689 sreloc = NULL;
1690
1691 rel = relocs;
1692 relend = relocs + input_section->reloc_count;
1693 for (; rel < relend; rel++, i++)
1694 {
1695 int r_type;
1696 reloc_howto_type *howto;
1697 unsigned long r_symndx;
1698 struct elf_link_hash_entry *h;
1699 Elf_Internal_Sym *sym;
1700 asection *sec;
1701 bfd_vma relocation = 0;
1702 bfd_boolean unresolved_reloc;
1703 bfd_reloc_status_type r;
f4707595 1704 bfd_vma address;
0f64bb02
CM
1705
1706 r_type = ELF32_R_TYPE (rel->r_info);
1707 if (r_type < 0 || r_type >= 243)
1708 {
1709 bfd_set_error (bfd_error_bad_value);
1710 return FALSE;
1711 }
1712
1713 if (r_type == R_BFIN_GNU_VTENTRY
1714 || r_type == R_BFIN_GNU_VTINHERIT)
1715 continue;
1716
1717 howto = bfin_reloc_type_lookup (input_bfd, r_type);
1718 if (howto == NULL)
1719 {
1720 bfd_set_error (bfd_error_bad_value);
1721 return FALSE;
1722 }
1723 r_symndx = ELF32_R_SYM (rel->r_info);
1724
1725 h = NULL;
1726 sym = NULL;
1727 sec = NULL;
1728 unresolved_reloc = FALSE;
1729
1730 if (r_symndx < symtab_hdr->sh_info)
1731 {
1732 sym = local_syms + r_symndx;
1733 sec = local_sections[r_symndx];
1734 relocation = _bfd_elf_rela_local_sym (output_bfd, sym, &sec, rel);
0f64bb02
CM
1735 }
1736 else
1737 {
1738 h = sym_hashes[r_symndx - symtab_hdr->sh_info];
1739
1740 while (h->root.type == bfd_link_hash_indirect
1741 || h->root.type == bfd_link_hash_warning)
1742 h = (struct elf_link_hash_entry *) h->root.u.i.link;
1743
1744 if (!
1745 (!strcmp (h->root.root.string, ".__constant")
1746 || !strcmp (h->root.root.string, ".__operator")))
1747 {
1748 bfd_boolean warned;
1749 h = NULL;
1750 RELOC_FOR_GLOBAL_SYMBOL (info, input_bfd, input_section, rel,
1751 r_symndx, symtab_hdr, sym_hashes,
1752 h, sec, relocation,
1753 unresolved_reloc, warned);
1754
1755 }
1756 }
1757
f4707595
JZ
1758 address = rel->r_offset;
1759 /* First, get stack relocs out of the way. */
1760 switch (r_type)
1761 {
1762 case R_push:
1763 reloc_stack_push (relocation + rel->r_addend);
1764 r = bfd_reloc_ok;
1765 goto done_reloc;
1766 case R_const:
1767 reloc_stack_push (rel->r_addend);
1768 r = bfd_reloc_ok;
1769 goto done_reloc;
1770 case R_add:
1771 case R_sub:
1772 case R_mult:
1773 case R_div:
1774 case R_mod:
1775 case R_lshift:
1776 case R_rshift:
1777 case R_neg:
1778 case R_and:
1779 case R_or:
1780 case R_xor:
1781 case R_land:
1782 case R_lor:
1783 case R_comp:
1784 case R_page:
1785 case R_hwpage:
1786 reloc_stack_operate (r_type);
1787 r = bfd_reloc_ok;
1788 goto done_reloc;
1789
1790 default:
1791 if (!is_reloc_stack_empty())
1792 relocation = reloc_stack_pop ();
1793 break;
1794 }
1795
1796 /* Then, process normally. */
0f64bb02
CM
1797 switch (r_type)
1798 {
1799 case R_BFIN_GNU_VTINHERIT:
1800 case R_BFIN_GNU_VTENTRY:
1801 return bfd_reloc_ok;
1802
1803 case R_got:
1804 /* Relocation is to the address of the entry for this symbol
1805 in the global offset table. */
1806 if (h != NULL
1807 && strcmp (h->root.root.string, "_GLOBAL_OFFSET_TABLE_") == 0)
f4707595 1808 goto do_default;
0f64bb02
CM
1809 /* Fall through. */
1810 /* Relocation is the offset of the entry for this symbol in
1811 the global offset table. */
1812
1813 {
1814 bfd_vma off;
1815
1816 if (sgot == NULL)
1817 {
1818 sgot = bfd_get_section_by_name (dynobj, ".got");
1819 BFD_ASSERT (sgot != NULL);
1820 }
1821
1822 if (h != NULL)
1823 {
1824 bfd_boolean dyn;
1825
1826 off = h->got.offset;
1827 BFD_ASSERT (off != (bfd_vma) - 1);
0f64bb02 1828 dyn = elf_hash_table (info)->dynamic_sections_created;
f4707595 1829
0f64bb02
CM
1830 if (!WILL_CALL_FINISH_DYNAMIC_SYMBOL (dyn, info->shared, h)
1831 || (info->shared
1832 && (info->symbolic
1833 || h->dynindx == -1
f4707595
JZ
1834 || h->forced_local)
1835 && h->def_regular))
0f64bb02
CM
1836 {
1837 /* This is actually a static link, or it is a
1838 -Bsymbolic link and the symbol is defined
1839 locally, or the symbol was forced to be local
1840 because of a version file.. We must initialize
1841 this entry in the global offset table. Since
1842 the offset must always be a multiple of 4, we
1843 use the least significant bit to record whether
1844 we have initialized it already.
1845
1846 When doing a dynamic link, we create a .rela.got
1847 relocation entry to initialize the value. This
1848 is done in the finish_dynamic_symbol routine. */
1849 if ((off & 1) != 0)
1850 off &= ~1;
1851 else
1852 {
1853 bfd_put_32 (output_bfd, relocation,
1854 sgot->contents + off);
1855 h->got.offset |= 1;
1856 }
1857 }
1858 else
1859 unresolved_reloc = FALSE;
1860 }
1861 else
1862 {
f4707595 1863 BFD_ASSERT (local_got_offsets != NULL);
0f64bb02 1864 off = local_got_offsets[r_symndx];
f4707595 1865 BFD_ASSERT (off != (bfd_vma) - 1);
0f64bb02
CM
1866
1867 /* The offset must always be a multiple of 4. We use
1868 the least significant bit to record whether we have
1869 already generated the necessary reloc. */
1870 if ((off & 1) != 0)
1871 off &= ~1;
1872 else
1873 {
0f64bb02
CM
1874 bfd_put_32 (output_bfd, relocation, sgot->contents + off);
1875
1876 if (info->shared)
1877 {
1878 asection *s;
1879 Elf_Internal_Rela outrel;
1880 bfd_byte *loc;
1881
1882 s = bfd_get_section_by_name (dynobj, ".rela.got");
1883 BFD_ASSERT (s != NULL);
1884
1885 outrel.r_offset = (sgot->output_section->vma
1886 + sgot->output_offset + off);
1887 outrel.r_info =
1888 ELF32_R_INFO (0, R_pcrel24);
1889 outrel.r_addend = relocation;
1890 loc = s->contents;
1891 loc +=
1892 s->reloc_count++ * sizeof (Elf32_External_Rela);
1893 bfd_elf32_swap_reloca_out (output_bfd, &outrel, loc);
1894 }
1895
1896 local_got_offsets[r_symndx] |= 1;
1897 }
1898 }
1899
1900 relocation = sgot->output_offset + off;
1901 rel->r_addend = 0;
1902 /* bfin : preg = [preg + 17bitdiv4offset] relocation is div by 4. */
1903 relocation /= 4;
1904 }
f4707595
JZ
1905 goto do_default;
1906
1907 case R_pcrel24:
1908 case R_pcrel24_jump_l:
1909 {
1910 bfd_vma x;
1911
1912 relocation += rel->r_addend;
1913
1914 /* Perform usual pc-relative correction. */
1915 relocation -= input_section->output_section->vma + input_section->output_offset;
1916 relocation -= address;
1917
1918 /* We are getting reloc_entry->address 2 byte off from
1919 the start of instruction. Assuming absolute postion
1920 of the reloc data. But, following code had been written assuming
1921 reloc address is starting at begining of instruction.
1922 To compensate that I have increased the value of
1923 relocation by 1 (effectively 2) and used the addr -2 instead of addr. */
1924
1925 relocation += 2;
1926 address -= 2;
1927
1928 relocation >>= 1;
1929
1930 x = bfd_get_16 (input_bfd, contents + address);
1931 x = (x & 0xff00) | ((relocation >> 16) & 0xff);
1932 bfd_put_16 (input_bfd, x, contents + address);
1933
1934 x = bfd_get_16 (input_bfd, contents + address + 2);
1935 x = relocation & 0xFFFF;
1936 bfd_put_16 (input_bfd, x, contents + address + 2);
1937 r = bfd_reloc_ok;
1938 }
0f64bb02
CM
1939 break;
1940
1941 default:
f4707595
JZ
1942 do_default:
1943 r = _bfd_final_link_relocate (howto, input_bfd, input_section,
1944 contents, address,
1945 relocation, rel->r_addend);
1946
0f64bb02
CM
1947 break;
1948 }
1949
f4707595 1950 done_reloc:
0f64bb02
CM
1951 /* Dynamic relocs are not propagated for SEC_DEBUGGING sections
1952 because such sections are not SEC_ALLOC and thus ld.so will
1953 not process them. */
1954 if (unresolved_reloc
1955 && !((input_section->flags & SEC_DEBUGGING) != 0 && h->def_dynamic))
1956 {
1957 (*_bfd_error_handler)
1958 (_("%B(%A+0x%lx): unresolvable relocation against symbol `%s'"),
1959 input_bfd,
1960 input_section, (long) rel->r_offset, h->root.root.string);
1961 return FALSE;
1962 }
1963
0f64bb02
CM
1964 if (r != bfd_reloc_ok)
1965 {
1966 const char *name;
1967
1968 if (h != NULL)
1969 name = h->root.root.string;
1970 else
1971 {
1972 name = bfd_elf_string_from_elf_section (input_bfd,
1973 symtab_hdr->sh_link,
1974 sym->st_name);
1975 if (name == NULL)
1976 return FALSE;
1977 if (*name == '\0')
1978 name = bfd_section_name (input_bfd, sec);
1979 }
1980
1981 if (r == bfd_reloc_overflow)
1982 {
1983 if (!(info->callbacks->reloc_overflow
1984 (info, (h ? &h->root : NULL), name, howto->name,
1985 (bfd_vma) 0, input_bfd, input_section, rel->r_offset)))
1986 return FALSE;
1987 }
1988 else
1989 {
1990 (*_bfd_error_handler)
1991 (_("%B(%A+0x%lx): reloc against `%s': error %d"),
1992 input_bfd, input_section,
1993 (long) rel->r_offset, name, (int) r);
1994 return FALSE;
1995 }
1996 }
1997 }
1998
1999 return TRUE;
2000}
2001
2002static asection *
2003bfin_gc_mark_hook (asection * sec,
2004 struct bfd_link_info *info ATTRIBUTE_UNUSED,
2005 Elf_Internal_Rela * rel,
2006 struct elf_link_hash_entry *h,
2007 Elf_Internal_Sym * sym)
2008{
2009 if (h != NULL)
2010 {
2011 switch (ELF32_R_TYPE (rel->r_info))
2012 {
2013
2014 case R_BFIN_GNU_VTINHERIT:
2015 case R_BFIN_GNU_VTENTRY:
2016 break;
2017
2018 default:
2019 switch (h->root.type)
2020 {
2021 default:
2022 break;
2023
2024 case bfd_link_hash_defined:
2025 case bfd_link_hash_defweak:
2026 return h->root.u.def.section;
2027
2028 case bfd_link_hash_common:
2029 return h->root.u.c.p->section;
2030 }
2031 }
2032 }
2033 else
2034 return bfd_section_from_elf_index (sec->owner, sym->st_shndx);
2035
2036 return NULL;
2037}
2038
2039
2040/* Update the got entry reference counts for the section being removed. */
2041
2042static bfd_boolean
2043bfin_gc_sweep_hook (bfd * abfd,
2044 struct bfd_link_info *info,
2045 asection * sec,
2046 const Elf_Internal_Rela * relocs)
2047{
2048 Elf_Internal_Shdr *symtab_hdr;
2049 struct elf_link_hash_entry **sym_hashes;
2050 bfd_signed_vma *local_got_refcounts;
2051 const Elf_Internal_Rela *rel, *relend;
2052 bfd *dynobj;
2053 asection *sgot;
2054 asection *srelgot;
2055
2056 dynobj = elf_hash_table (info)->dynobj;
2057 if (dynobj == NULL)
2058 return TRUE;
2059
2060 symtab_hdr = &elf_tdata (abfd)->symtab_hdr;
2061 sym_hashes = elf_sym_hashes (abfd);
2062 local_got_refcounts = elf_local_got_refcounts (abfd);
2063
2064 sgot = bfd_get_section_by_name (dynobj, ".got");
2065 srelgot = bfd_get_section_by_name (dynobj, ".rela.got");
2066
2067 relend = relocs + sec->reloc_count;
2068 for (rel = relocs; rel < relend; rel++)
2069 {
2070 unsigned long r_symndx;
2071 struct elf_link_hash_entry *h;
2072
2073 switch (ELF32_R_TYPE (rel->r_info))
2074 {
2075 case R_got:
2076 r_symndx = ELF32_R_SYM (rel->r_info);
2077 if (r_symndx >= symtab_hdr->sh_info)
2078 {
2079 h = sym_hashes[r_symndx - symtab_hdr->sh_info];
2080 if (h->got.refcount > 0)
2081 {
2082 --h->got.refcount;
2083 if (h->got.refcount == 0)
2084 {
2085 /* We don't need the .got entry any more. */
2086 sgot->size -= 4;
2087 srelgot->size -= sizeof (Elf32_External_Rela);
2088 }
2089 }
2090 }
2091 else if (local_got_refcounts != NULL)
2092 {
2093 if (local_got_refcounts[r_symndx] > 0)
2094 {
2095 --local_got_refcounts[r_symndx];
2096 if (local_got_refcounts[r_symndx] == 0)
2097 {
2098 /* We don't need the .got entry any more. */
2099 sgot->size -= 4;
2100 if (info->shared)
2101 srelgot->size -= sizeof (Elf32_External_Rela);
2102 }
2103 }
2104 }
2105 break;
2106 default:
2107 break;
2108 }
2109 }
2110
2111 return TRUE;
2112}
2113
2114
2115/* Merge backend specific data from an object file to the output
2116 object file when linking. */
2117static bfd_boolean
2118elf32_bfin_merge_private_bfd_data (bfd * ibfd, bfd * obfd)
2119{
2120 flagword out_flags;
2121 flagword in_flags;
2122
2123 if (bfd_get_flavour (ibfd) != bfd_target_elf_flavour
2124 || bfd_get_flavour (obfd) != bfd_target_elf_flavour)
2125 return TRUE;
2126
2127 in_flags = elf_elfheader (ibfd)->e_flags;
2128 out_flags = elf_elfheader (obfd)->e_flags;
2129
2130 if (!elf_flags_init (obfd))
2131 {
2132 elf_flags_init (obfd) = TRUE;
2133 elf_elfheader (obfd)->e_flags = in_flags;
2134 }
2135
2136 return TRUE;
2137}
2138
2139
2140static bfd_boolean
2141elf32_bfin_set_private_flags (bfd * abfd, flagword flags)
2142{
2143 elf_elfheader (abfd)->e_flags = flags;
2144 elf_flags_init (abfd) = TRUE;
2145 return TRUE;
2146}
2147
2148
2149/* Display the flags field. */
2150static bfd_boolean
2151elf32_bfin_print_private_bfd_data (bfd * abfd, PTR ptr)
2152{
2153 FILE *file = (FILE *) ptr;
2154
2155 BFD_ASSERT (abfd != NULL && ptr != NULL);
2156
2157 /* Print normal ELF private data. */
2158 _bfd_elf_print_private_bfd_data (abfd, ptr);
2159
2160 /* Ignore init flag - it may not be set, despite the flags field
2161 containing valid data. */
2162
2163 /* xgettext:c-format */
2164 fprintf (file, _("private flags = %lx:"), elf_elfheader (abfd)->e_flags);
2165
2166 fputc ('\n', file);
2167
2168 return TRUE;
2169}
2170
2171/* bfin ELF linker hash entry. */
2172
2173struct bfin_link_hash_entry
2174{
2175 struct elf_link_hash_entry root;
2176
2177 /* Number of PC relative relocs copied for this symbol. */
2178 struct bfin_pcrel_relocs_copied *pcrel_relocs_copied;
2179};
2180
2181/* bfin ELF linker hash table. */
2182
2183struct bfin_link_hash_table
2184{
2185 struct elf_link_hash_table root;
2186
2187 /* Small local sym to section mapping cache. */
2188 struct sym_sec_cache sym_sec;
2189};
2190
2191#define bfin_hash_entry(ent) ((struct bfin_link_hash_entry *) (ent))
2192
2193static struct bfd_hash_entry *
2194bfin_link_hash_newfunc (struct bfd_hash_entry *entry,
2195 struct bfd_hash_table *table, const char *string)
2196{
2197 struct bfd_hash_entry *ret = entry;
2198
2199 /* Allocate the structure if it has not already been allocated by a
2200 subclass. */
2201 if (ret == NULL)
2202 ret = bfd_hash_allocate (table, sizeof (struct bfin_link_hash_entry));
2203 if (ret == NULL)
2204 return ret;
2205
2206 /* Call the allocation method of the superclass. */
2207 ret = _bfd_elf_link_hash_newfunc (ret, table, string);
2208 if (ret != NULL)
2209 bfin_hash_entry (ret)->pcrel_relocs_copied = NULL;
2210
2211 return ret;
2212}
2213
2214/* Create an bfin ELF linker hash table. */
2215
2216static struct bfd_link_hash_table *
2217bfin_link_hash_table_create (bfd * abfd)
2218{
2219 struct bfin_link_hash_table *ret;
2220 bfd_size_type amt = sizeof (struct bfin_link_hash_table);
2221
2222 ret = (struct bfin_link_hash_table *) bfd_malloc (amt);
2223 if (ret == (struct bfin_link_hash_table *) NULL)
2224 return NULL;
2225
2226 if (!_bfd_elf_link_hash_table_init (&ret->root, abfd,
2227 bfin_link_hash_newfunc))
2228 {
2229 free (ret);
2230 return NULL;
2231 }
2232
2233 ret->sym_sec.abfd = NULL;
2234
2235 return &ret->root.root;
2236}
2237
2238/* The size in bytes of an entry in the procedure linkage table. */
2239
2240/* Finish up the dynamic sections. */
2241
2242static bfd_boolean
2243bfin_finish_dynamic_sections (bfd * output_bfd ATTRIBUTE_UNUSED,
2244 struct bfd_link_info *info)
2245{
2246 bfd *dynobj;
2247 asection *sdyn;
2248
2249 dynobj = elf_hash_table (info)->dynobj;
2250
2251 sdyn = bfd_get_section_by_name (dynobj, ".dynamic");
2252
2253 if (elf_hash_table (info)->dynamic_sections_created)
2254 {
2255 Elf32_External_Dyn *dyncon, *dynconend;
2256
2257 BFD_ASSERT (sdyn != NULL);
2258
2259 dyncon = (Elf32_External_Dyn *) sdyn->contents;
2260 dynconend = (Elf32_External_Dyn *) (sdyn->contents + sdyn->size);
2261 for (; dyncon < dynconend; dyncon++)
2262 {
2263 Elf_Internal_Dyn dyn;
2264
2265 bfd_elf32_swap_dyn_in (dynobj, dyncon, &dyn);
2266
2267 }
2268
2269 }
2270 return TRUE;
2271}
2272
2273/* Finish up dynamic symbol handling. We set the contents of various
2274 dynamic sections here. */
2275
2276static bfd_boolean
2277bfin_finish_dynamic_symbol (bfd * output_bfd,
2278 struct bfd_link_info *info,
2279 struct elf_link_hash_entry *h,
2280 Elf_Internal_Sym * sym)
2281{
2282 bfd *dynobj;
2283
2284 dynobj = elf_hash_table (info)->dynobj;
2285
2286 if (h->got.offset != (bfd_vma) - 1)
2287 {
2288 asection *sgot;
2289 asection *srela;
2290 Elf_Internal_Rela rela;
2291 bfd_byte *loc;
2292
2293 /* This symbol has an entry in the global offset table.
2294 Set it up. */
2295
2296 sgot = bfd_get_section_by_name (dynobj, ".got");
2297 srela = bfd_get_section_by_name (dynobj, ".rela.got");
2298 BFD_ASSERT (sgot != NULL && srela != NULL);
2299
2300 rela.r_offset = (sgot->output_section->vma
2301 + sgot->output_offset
2302 + (h->got.offset & ~(bfd_vma) 1));
2303
2304 /* If this is a -Bsymbolic link, and the symbol is defined
2305 locally, we just want to emit a RELATIVE reloc. Likewise if
2306 the symbol was forced to be local because of a version file.
2307 The entry in the global offset table will already have been
2308 initialized in the relocate_section function. */
2309 if (info->shared
2310 && (info->symbolic
2311 || h->dynindx == -1 || h->forced_local) && h->def_regular)
2312 {
2313fprintf(stderr, "*** check this relocation %s\n", __FUNCTION__);
2314 rela.r_info = ELF32_R_INFO (0, R_pcrel24);
2315 rela.r_addend = bfd_get_signed_32 (output_bfd,
2316 (sgot->contents
2317 +
2318 (h->got.
2319 offset & ~(bfd_vma) 1)));
2320 }
2321 else
2322 {
2323 bfd_put_32 (output_bfd, (bfd_vma) 0,
2324 sgot->contents + (h->got.offset & ~(bfd_vma) 1));
2325 rela.r_info = ELF32_R_INFO (h->dynindx, R_got);
2326 rela.r_addend = 0;
2327 }
2328
2329 loc = srela->contents;
2330 loc += srela->reloc_count++ * sizeof (Elf32_External_Rela);
2331 bfd_elf32_swap_reloca_out (output_bfd, &rela, loc);
2332 }
2333
2334 if (h->needs_copy)
2335 {
2336 BFD_ASSERT (0);
2337 }
2338 /* Mark _DYNAMIC and _GLOBAL_OFFSET_TABLE_ as absolute. */
2339 if (strcmp (h->root.root.string, "_DYNAMIC") == 0
22edb2f1 2340 || h == elf_hash_table (info)->hgot)
0f64bb02
CM
2341 sym->st_shndx = SHN_ABS;
2342
2343 return TRUE;
2344}
2345
2346/* Adjust a symbol defined by a dynamic object and referenced by a
2347 regular object. The current definition is in some section of the
2348 dynamic object, but we're not including those sections. We have to
2349 change the definition to something the rest of the link can
2350 understand. */
2351
2352static bfd_boolean
2353bfin_adjust_dynamic_symbol (struct bfd_link_info *info,
2354 struct elf_link_hash_entry *h)
2355{
2356 bfd *dynobj;
2357 asection *s;
2358 unsigned int power_of_two;
2359
2360 dynobj = elf_hash_table (info)->dynobj;
2361
2362 /* Make sure we know what is going on here. */
2363 BFD_ASSERT (dynobj != NULL
2364 && (h->needs_plt
2365 || h->u.weakdef != NULL
2366 || (h->def_dynamic && h->ref_regular && !h->def_regular)));
2367
2368 /* If this is a function, put it in the procedure linkage table. We
2369 will fill in the contents of the procedure linkage table later,
2370 when we know the address of the .got section. */
2371 if (h->type == STT_FUNC || h->needs_plt)
2372 {
2373 BFD_ASSERT(0);
2374 }
2375
2376 /* If this is a weak symbol, and there is a real definition, the
2377 processor independent code will have arranged for us to see the
2378 real definition first, and we can just use the same value. */
2379 if (h->u.weakdef != NULL)
2380 {
2381 BFD_ASSERT (h->u.weakdef->root.type == bfd_link_hash_defined
2382 || h->u.weakdef->root.type == bfd_link_hash_defweak);
2383 h->root.u.def.section = h->u.weakdef->root.u.def.section;
2384 h->root.u.def.value = h->u.weakdef->root.u.def.value;
2385 return TRUE;
2386 }
2387
2388 /* This is a reference to a symbol defined by a dynamic object which
2389 is not a function. */
2390
2391 /* If we are creating a shared library, we must presume that the
2392 only references to the symbol are via the global offset table.
2393 For such cases we need not do anything here; the relocations will
2394 be handled correctly by relocate_section. */
2395 if (info->shared)
2396 return TRUE;
2397
2398 /* We must allocate the symbol in our .dynbss section, which will
2399 become part of the .bss section of the executable. There will be
2400 an entry for this symbol in the .dynsym section. The dynamic
2401 object will contain position independent code, so all references
2402 from the dynamic object to this symbol will go through the global
2403 offset table. The dynamic linker will use the .dynsym entry to
2404 determine the address it must put in the global offset table, so
2405 both the dynamic object and the regular object will refer to the
2406 same memory location for the variable. */
2407
2408 s = bfd_get_section_by_name (dynobj, ".dynbss");
2409 BFD_ASSERT (s != NULL);
2410
2411 /* We must generate a R_68K_COPY reloc to tell the dynamic linker to
2412 copy the initial value out of the dynamic object and into the
2413 runtime process image. We need to remember the offset into the
2414 .rela.bss section we are going to use. */
2415 if ((h->root.u.def.section->flags & SEC_ALLOC) != 0)
2416 {
2417 asection *srel;
2418
2419 srel = bfd_get_section_by_name (dynobj, ".rela.bss");
2420 BFD_ASSERT (srel != NULL);
2421 srel->size += sizeof (Elf32_External_Rela);
2422 h->needs_copy = 1;
2423 }
2424
2425 /* We need to figure out the alignment required for this symbol. I
2426 have no idea how ELF linkers handle this. */
2427 power_of_two = bfd_log2 (h->size);
2428 if (power_of_two > 3)
2429 power_of_two = 3;
2430
2431 /* Apply the required alignment. */
2432 s->size = BFD_ALIGN (s->size, (bfd_size_type) (1 << power_of_two));
2433 if (power_of_two > bfd_get_section_alignment (dynobj, s))
2434 {
2435 if (!bfd_set_section_alignment (dynobj, s, power_of_two))
2436 return FALSE;
2437 }
2438
2439 /* Define the symbol as being at this point in the section. */
2440 h->root.u.def.section = s;
2441 h->root.u.def.value = s->size;
2442
2443 /* Increment the section size to make room for the symbol. */
2444 s->size += h->size;
2445
2446 return TRUE;
2447}
2448
2449/* The bfin linker needs to keep track of the number of relocs that it
2450 decides to copy in check_relocs for each symbol. This is so that it
2451 can discard PC relative relocs if it doesn't need them when linking
2452 with -Bsymbolic. We store the information in a field extending the
2453 regular ELF linker hash table. */
2454
2455/* This structure keeps track of the number of PC relative relocs we have
2456 copied for a given symbol. */
2457
2458struct bfin_pcrel_relocs_copied
2459{
2460 /* Next section. */
2461 struct bfin_pcrel_relocs_copied *next;
2462 /* A section in dynobj. */
2463 asection *section;
2464 /* Number of relocs copied in this section. */
2465 bfd_size_type count;
2466};
2467
2468/* This function is called via elf_link_hash_traverse if we are
2469 creating a shared object. In the -Bsymbolic case it discards the
2470 space allocated to copy PC relative relocs against symbols which
2471 are defined in regular objects. For the normal shared case, it
2472 discards space for pc-relative relocs that have become local due to
2473 symbol visibility changes. We allocated space for them in the
2474 check_relocs routine, but we won't fill them in in the
2475 relocate_section routine.
2476
2477 We also check whether any of the remaining relocations apply
2478 against a readonly section, and set the DF_TEXTREL flag in this
2479 case. */
2480
2481static bfd_boolean
2482bfin_discard_copies (struct elf_link_hash_entry *h, PTR inf)
2483{
2484 struct bfd_link_info *info = (struct bfd_link_info *) inf;
2485 struct bfin_pcrel_relocs_copied *s;
2486
2487 if (h->root.type == bfd_link_hash_warning)
2488 h = (struct elf_link_hash_entry *) h->root.u.i.link;
2489
2490 if (!h->def_regular || (!info->symbolic && !h->forced_local))
2491 {
2492 if ((info->flags & DF_TEXTREL) == 0)
2493 {
2494 /* Look for relocations against read-only sections. */
2495 for (s = bfin_hash_entry (h)->pcrel_relocs_copied;
2496 s != NULL; s = s->next)
2497 if ((s->section->flags & SEC_READONLY) != 0)
2498 {
2499 info->flags |= DF_TEXTREL;
2500 break;
2501 }
2502 }
2503
2504 return TRUE;
2505 }
2506
2507 for (s = bfin_hash_entry (h)->pcrel_relocs_copied;
2508 s != NULL; s = s->next)
2509 s->section->size -= s->count * sizeof (Elf32_External_Rela);
2510
2511 return TRUE;
2512}
2513
2514/* Set the sizes of the dynamic sections. */
2515#define ELF_DYNAMIC_INTERPRETER "/usr/lib/libc.so.1"
2516
2517static bfd_boolean
2518bfin_size_dynamic_sections (bfd * output_bfd ATTRIBUTE_UNUSED,
2519 struct bfd_link_info *info)
2520{
2521 bfd *dynobj;
2522 asection *s;
2523 bfd_boolean relocs;
2524
2525 dynobj = elf_hash_table (info)->dynobj;
2526 BFD_ASSERT (dynobj != NULL);
2527
2528 if (elf_hash_table (info)->dynamic_sections_created)
2529 {
2530 /* Set the contents of the .interp section to the interpreter. */
2531 if (info->executable)
2532 {
2533 s = bfd_get_section_by_name (dynobj, ".interp");
2534 BFD_ASSERT (s != NULL);
2535 s->size = sizeof ELF_DYNAMIC_INTERPRETER;
2536 s->contents = (unsigned char *) ELF_DYNAMIC_INTERPRETER;
2537 }
2538 }
2539 else
2540 {
2541 /* We may have created entries in the .rela.got section.
2542 However, if we are not creating the dynamic sections, we will
2543 not actually use these entries. Reset the size of .rela.got,
2544 which will cause it to get stripped from the output file
2545 below. */
2546 s = bfd_get_section_by_name (dynobj, ".rela.got");
2547 if (s != NULL)
2548 s->size = 0;
2549 }
2550
2551 /* If this is a -Bsymbolic shared link, then we need to discard all
2552 PC relative relocs against symbols defined in a regular object.
2553 For the normal shared case we discard the PC relative relocs
2554 against symbols that have become local due to visibility changes.
2555 We allocated space for them in the check_relocs routine, but we
2556 will not fill them in in the relocate_section routine. */
2557 if (info->shared)
2558 elf_link_hash_traverse (elf_hash_table (info),
2559 bfin_discard_copies, (PTR) info);
2560
2561 /* The check_relocs and adjust_dynamic_symbol entry points have
2562 determined the sizes of the various dynamic sections. Allocate
2563 memory for them. */
2564 relocs = FALSE;
2565 for (s = dynobj->sections; s != NULL; s = s->next)
2566 {
2567 const char *name;
2568 bfd_boolean strip;
2569
2570 if ((s->flags & SEC_LINKER_CREATED) == 0)
2571 continue;
2572
2573 /* It's OK to base decisions on the section name, because none
2574 of the dynobj section names depend upon the input files. */
2575 name = bfd_get_section_name (dynobj, s);
2576
2577 strip = FALSE;
2578
2579 if (strncmp (name, ".rela", 5) == 0)
2580 {
2581 if (s->size == 0)
2582 {
2583 /* If we don't need this section, strip it from the
2584 output file. This is mostly to handle .rela.bss and
2585 .rela.plt. We must create both sections in
2586 create_dynamic_sections, because they must be created
2587 before the linker maps input sections to output
2588 sections. The linker does that before
2589 adjust_dynamic_symbol is called, and it is that
2590 function which decides whether anything needs to go
2591 into these sections. */
2592 strip = TRUE;
2593 }
2594 else
2595 {
2596 relocs = TRUE;
2597
2598 /* We use the reloc_count field as a counter if we need
2599 to copy relocs into the output file. */
2600 s->reloc_count = 0;
2601 }
2602 }
2603 else if (strncmp (name, ".got", 4) != 0)
2604 {
2605 /* It's not one of our sections, so don't allocate space. */
2606 continue;
2607 }
2608
2609 if (strip)
2610 {
2611 s->flags |= SEC_EXCLUDE;
2612 continue;
2613 }
2614
2615 /* Allocate memory for the section contents. */
2616 /* FIXME: This should be a call to bfd_alloc not bfd_zalloc.
2617 Unused entries should be reclaimed before the section's contents
2618 are written out, but at the moment this does not happen. Thus in
2619 order to prevent writing out garbage, we initialise the section's
2620 contents to zero. */
2621 s->contents = (bfd_byte *) bfd_zalloc (dynobj, s->size);
2622 if (s->contents == NULL && s->size != 0)
2623 return FALSE;
2624 }
2625
2626 if (elf_hash_table (info)->dynamic_sections_created)
2627 {
2628 /* Add some entries to the .dynamic section. We fill in the
2629 values later, in bfin_finish_dynamic_sections, but we
2630 must add the entries now so that we get the correct size for
2631 the .dynamic section. The DT_DEBUG entry is filled in by the
2632 dynamic linker and used by the debugger. */
2633#define add_dynamic_entry(TAG, VAL) \
2634 _bfd_elf_add_dynamic_entry (info, TAG, VAL)
2635
2636 if (!info->shared)
2637 {
2638 if (!add_dynamic_entry (DT_DEBUG, 0))
2639 return FALSE;
2640 }
2641
2642
2643 if (relocs)
2644 {
2645 if (!add_dynamic_entry (DT_RELA, 0)
2646 || !add_dynamic_entry (DT_RELASZ, 0)
2647 || !add_dynamic_entry (DT_RELAENT,
2648 sizeof (Elf32_External_Rela)))
2649 return FALSE;
2650 }
2651
2652 if ((info->flags & DF_TEXTREL) != 0)
2653 {
2654 if (!add_dynamic_entry (DT_TEXTREL, 0))
2655 return FALSE;
2656 }
2657 }
2658#undef add_dynamic_entry
2659
2660 return TRUE;
2661}
2662
2663/* Given a .data section and a .emreloc in-memory section, store
2664 relocation information into the .emreloc section which can be
2665 used at runtime to relocate the section. This is called by the
2666 linker when the --embedded-relocs switch is used. This is called
2667 after the add_symbols entry point has been called for all the
2668 objects, and before the final_link entry point is called. */
2669
2670bfd_boolean
2671bfd_bfin_elf32_create_embedded_relocs (
2672 bfd *abfd,
2673 struct bfd_link_info *info,
2674 asection *datasec,
2675 asection *relsec,
2676 char **errmsg)
2677{
2678 Elf_Internal_Shdr *symtab_hdr;
2679 Elf_Internal_Sym *isymbuf = NULL;
2680 Elf_Internal_Rela *internal_relocs = NULL;
2681 Elf_Internal_Rela *irel, *irelend;
2682 bfd_byte *p;
2683 bfd_size_type amt;
2684
2685 BFD_ASSERT (! info->relocatable);
2686
2687 *errmsg = NULL;
2688
2689 if (datasec->reloc_count == 0)
2690 return TRUE;
2691
2692 symtab_hdr = &elf_tdata (abfd)->symtab_hdr;
2693
2694 /* Get a copy of the native relocations. */
2695 internal_relocs = (_bfd_elf_link_read_relocs
2696 (abfd, datasec, (PTR) NULL, (Elf_Internal_Rela *) NULL,
2697 info->keep_memory));
2698 if (internal_relocs == NULL)
2699 goto error_return;
2700
2701 amt = (bfd_size_type) datasec->reloc_count * 12;
2702 relsec->contents = (bfd_byte *) bfd_alloc (abfd, amt);
2703 if (relsec->contents == NULL)
2704 goto error_return;
2705
2706 p = relsec->contents;
2707
2708 irelend = internal_relocs + datasec->reloc_count;
2709 for (irel = internal_relocs; irel < irelend; irel++, p += 12)
2710 {
2711 asection *targetsec;
2712
2713 /* We are going to write a four byte longword into the runtime
2714 reloc section. The longword will be the address in the data
2715 section which must be relocated. It is followed by the name
2716 of the target section NUL-padded or truncated to 8
2717 characters. */
2718
2719 /* We can only relocate absolute longword relocs at run time. */
2720 if (ELF32_R_TYPE (irel->r_info) != (int) R_byte4_data)
2721 {
2722 *errmsg = _("unsupported reloc type");
2723 bfd_set_error (bfd_error_bad_value);
2724 goto error_return;
2725 }
2726
2727 /* Get the target section referred to by the reloc. */
2728 if (ELF32_R_SYM (irel->r_info) < symtab_hdr->sh_info)
2729 {
2730 /* A local symbol. */
2731 Elf_Internal_Sym *isym;
2732
2733 /* Read this BFD's local symbols if we haven't done so already. */
2734 if (isymbuf == NULL)
2735 {
2736 isymbuf = (Elf_Internal_Sym *) symtab_hdr->contents;
2737 if (isymbuf == NULL)
2738 isymbuf = bfd_elf_get_elf_syms (abfd, symtab_hdr,
2739 symtab_hdr->sh_info, 0,
2740 NULL, NULL, NULL);
2741 if (isymbuf == NULL)
2742 goto error_return;
2743 }
2744
2745 isym = isymbuf + ELF32_R_SYM (irel->r_info);
2746 targetsec = bfd_section_from_elf_index (abfd, isym->st_shndx);
2747 }
2748 else
2749 {
2750 unsigned long indx;
2751 struct elf_link_hash_entry *h;
2752
2753 /* An external symbol. */
2754 indx = ELF32_R_SYM (irel->r_info) - symtab_hdr->sh_info;
2755 h = elf_sym_hashes (abfd)[indx];
2756 BFD_ASSERT (h != NULL);
2757 if (h->root.type == bfd_link_hash_defined
2758 || h->root.type == bfd_link_hash_defweak)
2759 targetsec = h->root.u.def.section;
2760 else
2761 targetsec = NULL;
2762 }
2763
2764 bfd_put_32 (abfd, irel->r_offset + datasec->output_offset, p);
2765 memset (p + 4, 0, 8);
2766 if (targetsec != NULL)
9ba4c445 2767 strncpy ((char *) p + 4, targetsec->output_section->name, 8);
0f64bb02
CM
2768 }
2769
2770 if (isymbuf != NULL && symtab_hdr->contents != (unsigned char *) isymbuf)
2771 free (isymbuf);
2772 if (internal_relocs != NULL
2773 && elf_section_data (datasec)->relocs != internal_relocs)
2774 free (internal_relocs);
2775 return TRUE;
2776
2777error_return:
2778 if (isymbuf != NULL && symtab_hdr->contents != (unsigned char *) isymbuf)
2779 free (isymbuf);
2780 if (internal_relocs != NULL
2781 && elf_section_data (datasec)->relocs != internal_relocs)
2782 free (internal_relocs);
2783 return FALSE;
2784}
2785
2786#define TARGET_LITTLE_SYM bfd_elf32_bfin_vec
2787#define TARGET_LITTLE_NAME "elf32-bfin"
2788#define ELF_ARCH bfd_arch_bfin
2789#define ELF_MACHINE_CODE EM_BLACKFIN
2790#define ELF_MAXPAGESIZE 0x1000
2791#define elf_symbol_leading_char '_'
2792
2793#define bfd_elf32_bfd_reloc_type_lookup bfin_bfd_reloc_type_lookup
2794#define elf_info_to_howto bfin_info_to_howto
2795#define elf_info_to_howto_rel 0
2796
2797#define bfd_elf32_bfd_is_local_label_name \
2798 bfin_is_local_label_name
2799#define bfin_hash_table(p) \
2800 ((struct bfin_link_hash_table *) (p)->hash)
2801
2802
2803
2804#define elf_backend_create_dynamic_sections \
2805 _bfd_elf_create_dynamic_sections
2806#define bfd_elf32_bfd_link_hash_table_create \
2807 bfin_link_hash_table_create
2808#define bfd_elf32_bfd_final_link bfd_elf_gc_common_final_link
2809
2810#define elf_backend_check_relocs bfin_check_relocs
2811#define elf_backend_adjust_dynamic_symbol \
2812 bfin_adjust_dynamic_symbol
2813#define elf_backend_size_dynamic_sections \
2814 bfin_size_dynamic_sections
2815#define elf_backend_relocate_section bfin_relocate_section
2816#define elf_backend_finish_dynamic_symbol \
2817 bfin_finish_dynamic_symbol
2818#define elf_backend_finish_dynamic_sections \
2819 bfin_finish_dynamic_sections
2820#define elf_backend_gc_mark_hook bfin_gc_mark_hook
2821#define elf_backend_gc_sweep_hook bfin_gc_sweep_hook
2822#define bfd_elf32_bfd_merge_private_bfd_data \
2823 elf32_bfin_merge_private_bfd_data
2824#define bfd_elf32_bfd_set_private_flags \
2825 elf32_bfin_set_private_flags
2826#define bfd_elf32_bfd_print_private_bfd_data \
2827 elf32_bfin_print_private_bfd_data
2828#define elf_backend_reloc_type_class elf32_bfin_reloc_type_class
2829#define elf_backend_can_gc_sections 1
2830#define elf_backend_can_refcount 1
2831#define elf_backend_want_got_plt 0
2832#define elf_backend_plt_readonly 1
2833#define elf_backend_want_plt_sym 0
2834#define elf_backend_got_header_size 12
2835#define elf_backend_rela_normal 1
2836
2837
2838#include "elf32-target.h"
This page took 0.184784 seconds and 4 git commands to generate.