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