d973ddf69e6aa4ea7ae52b15aedeaaffc7dac5e7
[deliverable/binutils-gdb.git] / bfd / elf32-bfin.c
1 /* ADI Blackfin BFD support for 32-bit ELF.
2 Copyright 2005, 2006 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 /* FUNCTION : bfin_pltpc_reloc
28 ABSTRACT : TODO : figure out how to handle pltpc relocs. */
29 static bfd_reloc_status_type
30 bfin_pltpc_reloc (
31 bfd *abfd ATTRIBUTE_UNUSED,
32 arelent *reloc_entry ATTRIBUTE_UNUSED,
33 asymbol *symbol ATTRIBUTE_UNUSED,
34 PTR data ATTRIBUTE_UNUSED,
35 asection *input_section ATTRIBUTE_UNUSED,
36 bfd *output_bfd ATTRIBUTE_UNUSED,
37 char **error_message ATTRIBUTE_UNUSED)
38 {
39 bfd_reloc_status_type flag = bfd_reloc_ok;
40 return flag;
41 }
42 \f
43
44 static bfd_reloc_status_type
45 bfin_pcrel24_reloc (bfd *abfd,
46 arelent *reloc_entry,
47 asymbol *symbol,
48 PTR data,
49 asection *input_section,
50 bfd *output_bfd,
51 char **error_message ATTRIBUTE_UNUSED)
52 {
53 bfd_vma relocation;
54 bfd_size_type addr = reloc_entry->address;
55 bfd_vma output_base = 0;
56 reloc_howto_type *howto = reloc_entry->howto;
57 asection *output_section;
58 bfd_boolean relocatable = (output_bfd != NULL);
59
60 if (reloc_entry->address > bfd_get_section_limit (abfd, input_section))
61 return bfd_reloc_outofrange;
62
63 if (bfd_is_und_section (symbol->section)
64 && (symbol->flags & BSF_WEAK) == 0
65 && !relocatable)
66 return bfd_reloc_undefined;
67
68 if (bfd_is_com_section (symbol->section))
69 relocation = 0;
70 else
71 relocation = symbol->value;
72
73 output_section = symbol->section->output_section;
74
75 if (relocatable)
76 output_base = 0;
77 else
78 output_base = output_section->vma;
79
80 if (!relocatable || !strcmp (symbol->name, symbol->section->name))
81 relocation += output_base + symbol->section->output_offset;
82
83 if (!relocatable && !strcmp (symbol->name, symbol->section->name))
84 relocation += reloc_entry->addend;
85
86 relocation -= input_section->output_section->vma + input_section->output_offset;
87 relocation -= reloc_entry->address;
88
89 if (howto->complain_on_overflow != complain_overflow_dont)
90 {
91 bfd_reloc_status_type status;
92 status = bfd_check_overflow (howto->complain_on_overflow,
93 howto->bitsize,
94 howto->rightshift,
95 bfd_arch_bits_per_address(abfd),
96 relocation);
97 if (status != bfd_reloc_ok)
98 return status;
99 }
100
101 /* if rightshift is 1 and the number odd, return error. */
102 if (howto->rightshift && (relocation & 0x01))
103 {
104 fprintf(stderr, "relocation should be even number\n");
105 return bfd_reloc_overflow;
106 }
107
108 relocation >>= (bfd_vma) howto->rightshift;
109 /* Shift everything up to where it's going to be used. */
110
111 relocation <<= (bfd_vma) howto->bitpos;
112
113 if (relocatable)
114 {
115 reloc_entry->address += input_section->output_offset;
116 reloc_entry->addend += symbol->section->output_offset;
117 }
118
119 {
120 short x;
121
122 /* We are getting reloc_entry->address 2 byte off from
123 the start of instruction. Assuming absolute postion
124 of the reloc data. But, following code had been written assuming
125 reloc address is starting at begining of instruction.
126 To compensate that I have increased the value of
127 relocation by 1 (effectively 2) and used the addr -2 instead of addr. */
128
129 relocation += 1;
130 x = bfd_get_16 (abfd, (bfd_byte *) data + addr - 2);
131 x = (x & 0xff00) | ((relocation >> 16) & 0xff);
132 bfd_put_16 (abfd, x, (unsigned char *) data + addr - 2);
133
134 x = bfd_get_16 (abfd, (bfd_byte *) data + addr);
135 x = relocation & 0xFFFF;
136 bfd_put_16 (abfd, x, (unsigned char *) data + addr );
137 }
138 return bfd_reloc_ok;
139 }
140
141 static bfd_reloc_status_type
142 bfin_imm16_reloc (bfd *abfd,
143 arelent *reloc_entry,
144 asymbol *symbol,
145 PTR data,
146 asection *input_section,
147 bfd *output_bfd,
148 char **error_message ATTRIBUTE_UNUSED)
149 {
150 bfd_vma relocation, x;
151 bfd_size_type reloc_addr = reloc_entry->address;
152 bfd_vma output_base = 0;
153 reloc_howto_type *howto = reloc_entry->howto;
154 asection *output_section;
155 bfd_boolean relocatable = (output_bfd != NULL);
156
157 /* Is the address of the relocation really within the section? */
158 if (reloc_entry->address > bfd_get_section_limit (abfd, input_section))
159 return bfd_reloc_outofrange;
160
161 if (bfd_is_und_section (symbol->section)
162 && (symbol->flags & BSF_WEAK) == 0
163 && !relocatable)
164 return bfd_reloc_undefined;
165
166 output_section = symbol->section->output_section;
167 relocation = symbol->value;
168
169 /* Convert input-section-relative symbol value to absolute. */
170 if (relocatable)
171 output_base = 0;
172 else
173 output_base = output_section->vma;
174
175 if (!relocatable || !strcmp (symbol->name, symbol->section->name))
176 relocation += output_base + symbol->section->output_offset;
177
178 /* Add in supplied addend. */
179 relocation += reloc_entry->addend;
180
181 if (relocatable)
182 {
183 reloc_entry->address += input_section->output_offset;
184 reloc_entry->addend += symbol->section->output_offset;
185 }
186 else
187 {
188 reloc_entry->addend = 0;
189 }
190
191 if (howto->complain_on_overflow != complain_overflow_dont)
192 {
193 bfd_reloc_status_type flag;
194 flag = bfd_check_overflow (howto->complain_on_overflow,
195 howto->bitsize,
196 howto->rightshift,
197 bfd_arch_bits_per_address(abfd),
198 relocation);
199 if (flag != bfd_reloc_ok)
200 return flag;
201 }
202
203 /* Here the variable relocation holds the final address of the
204 symbol we are relocating against, plus any addend. */
205
206 relocation >>= (bfd_vma) howto->rightshift;
207 x = relocation;
208 bfd_put_16 (abfd, x, (unsigned char *) data + reloc_addr);
209 return bfd_reloc_ok;
210 }
211
212
213 static bfd_reloc_status_type
214 bfin_byte4_reloc (bfd *abfd,
215 arelent *reloc_entry,
216 asymbol *symbol,
217 PTR data,
218 asection *input_section,
219 bfd *output_bfd,
220 char **error_message ATTRIBUTE_UNUSED)
221 {
222 bfd_vma relocation, x;
223 bfd_size_type addr = reloc_entry->address;
224 bfd_vma output_base = 0;
225 asection *output_section;
226 bfd_boolean relocatable = (output_bfd != NULL);
227
228 /* Is the address of the relocation really within the section? */
229 if (reloc_entry->address > bfd_get_section_limit (abfd, input_section))
230 return bfd_reloc_outofrange;
231
232 if (bfd_is_und_section (symbol->section)
233 && (symbol->flags & BSF_WEAK) == 0
234 && !relocatable)
235 return bfd_reloc_undefined;
236
237 output_section = symbol->section->output_section;
238 relocation = symbol->value;
239 /* Convert input-section-relative symbol value to absolute. */
240 if (relocatable)
241 output_base = 0;
242 else
243 output_base = output_section->vma;
244
245 if ((symbol->name
246 && symbol->section->name
247 && !strcmp (symbol->name, symbol->section->name))
248 || !relocatable)
249 {
250 relocation += output_base + symbol->section->output_offset;
251 }
252
253 relocation += reloc_entry->addend;
254
255 if (relocatable)
256 {
257 /* This output will be relocatable ... like ld -r. */
258 reloc_entry->address += input_section->output_offset;
259 reloc_entry->addend += symbol->section->output_offset;
260 }
261 else
262 {
263 reloc_entry->addend = 0;
264 }
265
266 /* Here the variable relocation holds the final address of the
267 symbol we are relocating against, plus any addend. */
268 x = relocation & 0xFFFF0000;
269 x >>=16;
270 bfd_put_16 (abfd, x, (unsigned char *) data + addr + 2);
271
272 x = relocation & 0x0000FFFF;
273 bfd_put_16 (abfd, x, (unsigned char *) data + addr);
274 return bfd_reloc_ok;
275 }
276
277 /* bfin_bfd_reloc handles the blackfin arithmetic relocations.
278 Use this instead of bfd_perform_relocation. */
279 static bfd_reloc_status_type
280 bfin_bfd_reloc (bfd *abfd,
281 arelent *reloc_entry,
282 asymbol *symbol,
283 PTR data,
284 asection *input_section,
285 bfd *output_bfd,
286 char **error_message ATTRIBUTE_UNUSED)
287 {
288 bfd_vma relocation;
289 bfd_size_type addr = reloc_entry->address;
290 bfd_vma output_base = 0;
291 reloc_howto_type *howto = reloc_entry->howto;
292 asection *output_section;
293 bfd_boolean relocatable = (output_bfd != NULL);
294
295 /* Is the address of the relocation really within the section? */
296 if (reloc_entry->address > bfd_get_section_limit (abfd, input_section))
297 return bfd_reloc_outofrange;
298
299 if (bfd_is_und_section (symbol->section)
300 && (symbol->flags & BSF_WEAK) == 0
301 && !relocatable)
302 return bfd_reloc_undefined;
303
304 /* Get symbol value. (Common symbols are special.) */
305 if (bfd_is_com_section (symbol->section))
306 relocation = 0;
307 else
308 relocation = symbol->value;
309
310 output_section = symbol->section->output_section;
311
312 /* Convert input-section-relative symbol value to absolute. */
313 if (relocatable)
314 output_base = 0;
315 else
316 output_base = output_section->vma;
317
318 if (!relocatable || !strcmp (symbol->name, symbol->section->name))
319 relocation += output_base + symbol->section->output_offset;
320
321 if (!relocatable && !strcmp (symbol->name, symbol->section->name))
322 {
323 /* Add in supplied addend. */
324 relocation += reloc_entry->addend;
325 }
326
327 /* Here the variable relocation holds the final address of the
328 symbol we are relocating against, plus any addend. */
329
330 if (howto->pc_relative == TRUE)
331 {
332 relocation -= input_section->output_section->vma + input_section->output_offset;
333
334 if (howto->pcrel_offset == TRUE)
335 relocation -= reloc_entry->address;
336 }
337
338 if (relocatable)
339 {
340 reloc_entry->address += input_section->output_offset;
341 reloc_entry->addend += symbol->section->output_offset;
342 }
343
344 if (howto->complain_on_overflow != complain_overflow_dont)
345 {
346 bfd_reloc_status_type status;
347
348 status = bfd_check_overflow (howto->complain_on_overflow,
349 howto->bitsize,
350 howto->rightshift,
351 bfd_arch_bits_per_address(abfd),
352 relocation);
353 if (status != bfd_reloc_ok)
354 return status;
355 }
356
357 /* If rightshift is 1 and the number odd, return error. */
358 if (howto->rightshift && (relocation & 0x01))
359 {
360 fprintf(stderr, "relocation should be even number\n");
361 return bfd_reloc_overflow;
362 }
363
364 relocation >>= (bfd_vma) howto->rightshift;
365
366 /* Shift everything up to where it's going to be used. */
367
368 relocation <<= (bfd_vma) howto->bitpos;
369
370 #define DOIT(x) \
371 x = ( (x & ~howto->dst_mask) | (relocation & howto->dst_mask))
372
373 /* handle 8 and 16 bit relocations here. */
374 switch (howto->size)
375 {
376 case 0:
377 {
378 char x = bfd_get_8 (abfd, (char *) data + addr);
379 DOIT (x);
380 bfd_put_8 (abfd, x, (unsigned char *) data + addr);
381 }
382 break;
383
384 case 1:
385 {
386 unsigned short x = bfd_get_16 (abfd, (bfd_byte *) data + addr);
387 DOIT (x);
388 bfd_put_16 (abfd, (bfd_vma) x, (unsigned char *) data + addr);
389 }
390 break;
391
392 default:
393 return bfd_reloc_other;
394 }
395
396 return bfd_reloc_ok;
397 }
398
399 /* HOWTO Table for blackfin.
400 Blackfin relocations are fairly complicated.
401 Some of the salient features are
402 a. Even numbered offsets. A number of (not all) relocations are
403 even numbered. This means that the rightmost bit is not stored.
404 Needs to right shift by 1 and check to see if value is not odd
405 b. A relocation can be an expression. An expression takes on
406 a variety of relocations arranged in a stack.
407 As a result, we cannot use the standard generic function as special
408 function. We will have our own, which is very similar to the standard
409 generic function except that it understands how to get the value from
410 the relocation stack. . */
411
412 #define BFIN_RELOC_MIN 0
413 #define BFIN_RELOC_MAX 0x13
414 #define BFIN_GNUEXT_RELOC_MIN 0x40
415 #define BFIN_GNUEXT_RELOC_MAX 0x43
416 #define BFIN_ARELOC_MIN 0xE0
417 #define BFIN_ARELOC_MAX 0xF3
418
419 static reloc_howto_type bfin_howto_table [] =
420 {
421 /* This reloc does nothing. . */
422 HOWTO (R_unused0, /* type. */
423 0, /* rightshift. */
424 2, /* size (0 = byte, 1 = short, 2 = long). */
425 32, /* bitsize. */
426 FALSE, /* pc_relative. */
427 0, /* bitpos. */
428 complain_overflow_bitfield, /* complain_on_overflow. */
429 bfd_elf_generic_reloc, /* special_function. */
430 "R_unused0", /* name. */
431 FALSE, /* partial_inplace. */
432 0, /* src_mask. */
433 0, /* dst_mask. */
434 FALSE), /* pcrel_offset. */
435
436 HOWTO (R_pcrel5m2, /* type. */
437 1, /* rightshift. */
438 1, /* size (0 = byte, 1 = short, 2 = long).. */
439 4, /* bitsize. */
440 TRUE, /* pc_relative. */
441 0, /* bitpos. */
442 complain_overflow_unsigned, /* complain_on_overflow. */
443 bfin_bfd_reloc, /* special_function. */
444 "R_pcrel5m2", /* name. */
445 FALSE, /* partial_inplace. */
446 0, /* src_mask. */
447 0x0000000F, /* dst_mask. */
448 FALSE), /* pcrel_offset. */
449
450 HOWTO (R_unused1, /* type. */
451 0, /* rightshift. */
452 2, /* size (0 = byte, 1 = short, 2 = long). */
453 32, /* bitsize. */
454 FALSE, /* pc_relative. */
455 0, /* bitpos. */
456 complain_overflow_bitfield, /* complain_on_overflow. */
457 bfd_elf_generic_reloc, /* special_function. */
458 "R_unused1", /* name. */
459 FALSE, /* partial_inplace. */
460 0, /* src_mask. */
461 0, /* dst_mask. */
462 FALSE), /* pcrel_offset. */
463
464 HOWTO (R_pcrel10, /* type. */
465 1, /* rightshift. */
466 1, /* size (0 = byte, 1 = short, 2 = long). */
467 10, /* bitsize. */
468 TRUE, /* pc_relative. */
469 0, /* bitpos. */
470 complain_overflow_signed, /* complain_on_overflow. */
471 bfin_bfd_reloc, /* special_function. */
472 "R_pcrel10", /* name. */
473 FALSE, /* partial_inplace. */
474 0, /* src_mask. */
475 0x000003FF, /* dst_mask. */
476 TRUE), /* pcrel_offset. */
477
478 HOWTO (R_pcrel12_jump, /* type. */
479 1, /* rightshift. */
480 /* the offset is actually 13 bit
481 aligned on a word boundary so
482 only 12 bits have to be used.
483 Right shift the rightmost bit.. */
484 1, /* size (0 = byte, 1 = short, 2 = long). */
485 12, /* bitsize. */
486 TRUE, /* pc_relative. */
487 0, /* bitpos. */
488 complain_overflow_signed, /* complain_on_overflow. */
489 bfin_bfd_reloc, /* special_function. */
490 "R_pcrel12_jump", /* name. */
491 FALSE, /* partial_inplace. */
492 0, /* src_mask. */
493 0x0FFF, /* dst_mask. */
494 TRUE), /* pcrel_offset. */
495
496 HOWTO (R_rimm16, /* type. */
497 0, /* rightshift. */
498 1, /* size (0 = byte, 1 = short, 2 = long). */
499 16, /* bitsize. */
500 FALSE, /* pc_relative. */
501 0, /* bitpos. */
502 complain_overflow_signed, /* complain_on_overflow. */
503 bfin_imm16_reloc, /* special_function. */
504 "R_rimm16", /* name. */
505 FALSE, /* partial_inplace. */
506 0, /* src_mask. */
507 0x0000FFFF, /* dst_mask. */
508 TRUE), /* pcrel_offset. */
509
510 HOWTO (R_luimm16, /* type. */
511 0, /* rightshift. */
512 1, /* size (0 = byte, 1 = short, 2 = long). */
513 16, /* bitsize. */
514 FALSE, /* pc_relative. */
515 0, /* bitpos. */
516 complain_overflow_dont, /* complain_on_overflow. */
517 bfin_imm16_reloc, /* special_function. */
518 "R_luimm16", /* name. */
519 FALSE, /* partial_inplace. */
520 0, /* src_mask. */
521 0x0000FFFF, /* dst_mask. */
522 TRUE), /* pcrel_offset. */
523
524 HOWTO (R_huimm16, /* type. */
525 16, /* rightshift. */
526 1, /* size (0 = byte, 1 = short, 2 = long). */
527 16, /* bitsize. */
528 FALSE, /* pc_relative. */
529 0, /* bitpos. */
530 complain_overflow_unsigned, /* complain_on_overflow. */
531 bfin_imm16_reloc, /* special_function. */
532 "R_huimm16", /* name. */
533 FALSE, /* partial_inplace. */
534 0, /* src_mask. */
535 0x0000FFFF, /* dst_mask. */
536 TRUE), /* pcrel_offset. */
537
538 HOWTO (R_pcrel12_jump_s, /* type. */
539 1, /* rightshift. */
540 1, /* size (0 = byte, 1 = short, 2 = long). */
541 12, /* bitsize. */
542 TRUE, /* pc_relative. */
543 0, /* bitpos. */
544 complain_overflow_signed, /* complain_on_overflow. */
545 bfin_bfd_reloc, /* special_function. */
546 "R_pcrel12_jump_s", /* name. */
547 FALSE, /* partial_inplace. */
548 0, /* src_mask. */
549 0x00000FFF, /* dst_mask. */
550 TRUE), /* pcrel_offset. */
551
552 HOWTO (R_pcrel24_jump_x, /* type. */
553 1, /* rightshift. */
554 2, /* size (0 = byte, 1 = short, 2 = long). */
555 24, /* bitsize. */
556 TRUE, /* pc_relative. */
557 0, /* bitpos. */
558 complain_overflow_signed, /* complain_on_overflow. */
559 bfin_pcrel24_reloc, /* special_function. */
560 "R_pcrel24_jump_x", /* name. */
561 FALSE, /* partial_inplace. */
562 0, /* src_mask. */
563 0x00FFFFFF, /* dst_mask. */
564 TRUE), /* pcrel_offset. */
565
566 HOWTO (R_pcrel24, /* type. */
567 1, /* rightshift. */
568 2, /* size (0 = byte, 1 = short, 2 = long). */
569 24, /* bitsize. */
570 TRUE, /* pc_relative. */
571 0, /* bitpos. */
572 complain_overflow_signed, /* complain_on_overflow. */
573 bfin_pcrel24_reloc, /* special_function. */
574 "R_pcrel24", /* name. */
575 FALSE, /* partial_inplace. */
576 0, /* src_mask. */
577 0x00FFFFFF, /* dst_mask. */
578 TRUE), /* pcrel_offset. */
579
580 HOWTO (R_unusedb, /* type. */
581 0, /* rightshift. */
582 2, /* size (0 = byte, 1 = short, 2 = long). */
583 32, /* bitsize. */
584 FALSE, /* pc_relative. */
585 0, /* bitpos. */
586 complain_overflow_dont, /* complain_on_overflow. */
587 bfd_elf_generic_reloc, /* special_function. */
588 "R_unusedb", /* name. */
589 FALSE, /* partial_inplace. */
590 0, /* src_mask. */
591 0, /* dst_mask. */
592 FALSE), /* pcrel_offset. */
593
594 HOWTO (R_unusedc, /* type. */
595 0, /* rightshift. */
596 2, /* size (0 = byte, 1 = short, 2 = long). */
597 32, /* bitsize. */
598 FALSE, /* pc_relative. */
599 0, /* bitpos. */
600 complain_overflow_dont, /* complain_on_overflow. */
601 bfd_elf_generic_reloc, /* special_function. */
602 "R_unusedc", /* name. */
603 FALSE, /* partial_inplace. */
604 0, /* src_mask. */
605 0, /* dst_mask. */
606 FALSE), /* pcrel_offset. */
607
608 HOWTO (R_pcrel24_jump_l, /* type. */
609 1, /* rightshift. */
610 2, /* size (0 = byte, 1 = short, 2 = long). */
611 24, /* bitsize. */
612 TRUE, /* pc_relative. */
613 0, /* bitpos. */
614 complain_overflow_signed, /* complain_on_overflow. */
615 bfin_pcrel24_reloc, /* special_function. */
616 "R_pcrel24_jump_l", /* name. */
617 FALSE, /* partial_inplace. */
618 0, /* src_mask. */
619 0x00FFFFFF, /* dst_mask. */
620 TRUE), /* pcrel_offset. */
621
622 HOWTO (R_pcrel24_call_x, /* type. */
623 1, /* rightshift. */
624 2, /* size (0 = byte, 1 = short, 2 = long). */
625 24, /* bitsize. */
626 TRUE, /* pc_relative. */
627 0, /* bitpos. */
628 complain_overflow_signed, /* complain_on_overflow. */
629 bfin_pcrel24_reloc, /* special_function. */
630 "R_pcrel24_call_x", /* name. */
631 FALSE, /* partial_inplace. */
632 0, /* src_mask. */
633 0x00FFFFFF, /* dst_mask. */
634 TRUE), /* pcrel_offset. */
635
636 HOWTO (R_var_eq_symb, /* type. */
637 0, /* rightshift. */
638 2, /* size (0 = byte, 1 = short, 2 = long). */
639 32, /* bitsize. */
640 FALSE, /* pc_relative. */
641 0, /* bitpos. */
642 complain_overflow_bitfield, /* complain_on_overflow. */
643 bfin_bfd_reloc, /* special_function. */
644 "R_var_eq_symb", /* name. */
645 FALSE, /* partial_inplace. */
646 0, /* src_mask. */
647 0, /* dst_mask. */
648 FALSE), /* pcrel_offset. */
649
650 HOWTO (R_byte_data, /* type. */
651 0, /* rightshift. */
652 0, /* size (0 = byte, 1 = short, 2 = long). */
653 8, /* bitsize. */
654 FALSE, /* pc_relative. */
655 0, /* bitpos. */
656 complain_overflow_unsigned, /* complain_on_overflow. */
657 bfin_bfd_reloc, /* special_function. */
658 "R_byte_data", /* name. */
659 FALSE, /* partial_inplace. */
660 0, /* src_mask. */
661 0xFF, /* dst_mask. */
662 TRUE), /* pcrel_offset. */
663
664 HOWTO (R_byte2_data, /* type. */
665 0, /* rightshift. */
666 1, /* size (0 = byte, 1 = short, 2 = long). */
667 16, /* bitsize. */
668 FALSE, /* pc_relative. */
669 0, /* bitpos. */
670 complain_overflow_signed, /* complain_on_overflow. */
671 bfin_bfd_reloc, /* special_function. */
672 "R_byte2_data", /* name. */
673 FALSE, /* partial_inplace. */
674 0, /* src_mask. */
675 0xFFFF, /* dst_mask. */
676 TRUE), /* pcrel_offset. */
677
678 HOWTO (R_byte4_data, /* type. */
679 0, /* rightshift. */
680 2, /* size (0 = byte, 1 = short, 2 = long). */
681 32, /* bitsize. */
682 FALSE, /* pc_relative. */
683 0, /* bitpos. */
684 complain_overflow_unsigned, /* complain_on_overflow. */
685 bfin_byte4_reloc, /* special_function. */
686 "R_byte4_data", /* name. */
687 FALSE, /* partial_inplace. */
688 0, /* src_mask. */
689 0xFFFFFFFF, /* dst_mask. */
690 TRUE), /* pcrel_offset. */
691
692 HOWTO (R_pcrel11, /* type. */
693 1, /* rightshift. */
694 1, /* size (0 = byte, 1 = short, 2 = long). */
695 10, /* bitsize. */
696 TRUE, /* pc_relative. */
697 0, /* bitpos. */
698 complain_overflow_unsigned, /* complain_on_overflow. */
699 bfin_bfd_reloc, /* special_function. */
700 "R_pcrel11", /* name. */
701 FALSE, /* partial_inplace. */
702 0, /* src_mask. */
703 0x000003FF, /* dst_mask. */
704 FALSE), /* pcrel_offset. */
705 };
706
707 static reloc_howto_type bfin_gnuext_howto_table [] =
708 {
709 HOWTO (R_pltpc, /* type. */
710 0, /* rightshift. */
711 1, /* size (0 = byte, 1 = short, 2 = long). */
712 16, /* bitsize. */
713 FALSE, /* pc_relative. */
714 0, /* bitpos. */
715 complain_overflow_bitfield, /* complain_on_overflow. */
716 bfin_pltpc_reloc, /* special_function. */
717 "R_pltpc", /* name. */
718 FALSE, /* partial_inplace. */
719 0xffff, /* src_mask. */
720 0xffff, /* dst_mask. */
721 FALSE), /* pcrel_offset. */
722
723 HOWTO (R_got, /* type. */
724 0, /* rightshift. */
725 1, /* size (0 = byte, 1 = short, 2 = long). */
726 16, /* bitsize. */
727 FALSE, /* pc_relative. */
728 0, /* bitpos. */
729 complain_overflow_bitfield, /* complain_on_overflow. */
730 bfd_elf_generic_reloc, /* special_function. */
731 "R_got", /* name. */
732 FALSE, /* partial_inplace. */
733 0x7fff, /* src_mask. */
734 0x7fff, /* dst_mask. */
735 FALSE), /* pcrel_offset. */
736
737 /* GNU extension to record C++ vtable hierarchy. */
738 HOWTO (R_BFIN_GNU_VTINHERIT, /* type. */
739 0, /* rightshift. */
740 2, /* size (0 = byte, 1 = short, 2 = long). */
741 0, /* bitsize. */
742 FALSE, /* pc_relative. */
743 0, /* bitpos. */
744 complain_overflow_dont, /* complain_on_overflow. */
745 NULL, /* special_function. */
746 "R_BFIN_GNU_VTINHERIT", /* name. */
747 FALSE, /* partial_inplace. */
748 0, /* src_mask. */
749 0, /* dst_mask. */
750 FALSE), /* pcrel_offset. */
751
752 /* GNU extension to record C++ vtable member usage. */
753 HOWTO (R_BFIN_GNU_VTENTRY, /* type. */
754 0, /* rightshift. */
755 2, /* size (0 = byte, 1 = short, 2 = long). */
756 0, /* bitsize. */
757 FALSE, /* pc_relative. */
758 0, /* bitpos. */
759 complain_overflow_dont, /* complain_on_overflow. */
760 _bfd_elf_rel_vtable_reloc_fn, /* special_function. */
761 "R_BFIN_GNU_VTENTRY", /* name. */
762 FALSE, /* partial_inplace. */
763 0, /* src_mask. */
764 0, /* dst_mask. */
765 FALSE) /* pcrel_offset. */
766 };
767
768 struct bfin_reloc_map
769 {
770 bfd_reloc_code_real_type bfd_reloc_val;
771 unsigned int bfin_reloc_val;
772 };
773
774 static const struct bfin_reloc_map bfin_reloc_map [] =
775 {
776 { BFD_RELOC_NONE, R_unused0 },
777 { BFD_RELOC_BFIN_5_PCREL, R_pcrel5m2 },
778 { BFD_RELOC_NONE, R_unused1 },
779 { BFD_RELOC_BFIN_10_PCREL, R_pcrel10 },
780 { BFD_RELOC_BFIN_12_PCREL_JUMP, R_pcrel12_jump },
781 { BFD_RELOC_BFIN_16_IMM, R_rimm16 },
782 { BFD_RELOC_BFIN_16_LOW, R_luimm16 },
783 { BFD_RELOC_BFIN_16_HIGH, R_huimm16 },
784 { BFD_RELOC_BFIN_12_PCREL_JUMP_S, R_pcrel12_jump_s },
785 { BFD_RELOC_24_PCREL, R_pcrel24 },
786 { BFD_RELOC_24_PCREL, R_pcrel24 },
787 { BFD_RELOC_BFIN_24_PCREL_JUMP_L, R_pcrel24_jump_l },
788 { BFD_RELOC_NONE, R_unusedb },
789 { BFD_RELOC_NONE, R_unusedc },
790 { BFD_RELOC_BFIN_24_PCREL_CALL_X, R_pcrel24_call_x },
791 { BFD_RELOC_8, R_byte_data },
792 { BFD_RELOC_16, R_byte2_data },
793 { BFD_RELOC_32, R_byte4_data },
794 { BFD_RELOC_BFIN_11_PCREL, R_pcrel11 },
795 { BFD_RELOC_BFIN_GOT, R_got },
796 { BFD_RELOC_BFIN_PLTPC, R_pltpc },
797 { BFD_RELOC_VTABLE_INHERIT, R_BFIN_GNU_VTINHERIT },
798 { BFD_RELOC_VTABLE_ENTRY, R_BFIN_GNU_VTENTRY },
799 };
800
801
802 static void
803 bfin_info_to_howto (bfd *abfd ATTRIBUTE_UNUSED,
804 arelent *cache_ptr,
805 Elf_Internal_Rela *dst)
806 {
807 unsigned int r_type;
808
809 r_type = ELF32_R_TYPE (dst->r_info);
810
811 if (r_type <= BFIN_RELOC_MAX)
812 cache_ptr->howto = &bfin_howto_table [r_type];
813
814 else if (r_type >= BFIN_GNUEXT_RELOC_MIN && r_type <= BFIN_GNUEXT_RELOC_MAX)
815 cache_ptr->howto = &bfin_gnuext_howto_table [r_type - BFIN_GNUEXT_RELOC_MIN];
816
817 else
818 cache_ptr->howto = (reloc_howto_type *) NULL;
819
820 }
821 /* Given a BFD reloc type, return the howto. */
822 static reloc_howto_type *
823 bfin_bfd_reloc_type_lookup (bfd * abfd ATTRIBUTE_UNUSED,
824 bfd_reloc_code_real_type code)
825 {
826 unsigned int i;
827 unsigned int r_type = BFIN_RELOC_MIN;
828
829 for (i = sizeof (bfin_reloc_map) / sizeof (bfin_reloc_map[0]); --i;)
830 if (bfin_reloc_map[i].bfd_reloc_val == code)
831 r_type = bfin_reloc_map[i].bfin_reloc_val;
832
833 if (r_type <= BFIN_RELOC_MAX && r_type > BFIN_RELOC_MIN)
834 return &bfin_howto_table [r_type];
835
836 else if (r_type >= BFIN_GNUEXT_RELOC_MIN && r_type <= BFIN_GNUEXT_RELOC_MAX)
837 return &bfin_gnuext_howto_table [r_type - BFIN_GNUEXT_RELOC_MIN];
838
839 return (reloc_howto_type *) NULL;
840
841 }
842 /* Given a bfin relocation type, return the howto. */
843 static reloc_howto_type *
844 bfin_reloc_type_lookup (bfd * abfd ATTRIBUTE_UNUSED,
845 unsigned int r_type)
846 {
847 if (r_type <= BFIN_RELOC_MAX)
848 return &bfin_howto_table [r_type];
849
850 else if (r_type >= BFIN_GNUEXT_RELOC_MIN && r_type <= BFIN_GNUEXT_RELOC_MAX)
851 return &bfin_gnuext_howto_table [r_type - BFIN_GNUEXT_RELOC_MIN];
852
853 return (reloc_howto_type *) NULL;
854
855 }
856
857 /* Return TRUE if the name is a local label.
858 bfin local labels begin with L$. */
859 static bfd_boolean
860 bfin_is_local_label_name (
861 bfd *abfd ATTRIBUTE_UNUSED,
862 const char *label)
863 {
864 if (label[0] == 'L' && label[1] == '$' )
865 return TRUE;
866
867 return _bfd_elf_is_local_label_name (abfd, label);
868 }
869
870
871 /* Look through the relocs for a section during the first phase, and
872 allocate space in the global offset table or procedure linkage
873 table. */
874
875 static bfd_boolean
876 bfin_check_relocs (bfd * abfd,
877 struct bfd_link_info *info,
878 asection *sec,
879 const Elf_Internal_Rela *relocs)
880 {
881 bfd *dynobj;
882 Elf_Internal_Shdr *symtab_hdr;
883 struct elf_link_hash_entry **sym_hashes;
884 bfd_signed_vma *local_got_refcounts;
885 const Elf_Internal_Rela *rel;
886 const Elf_Internal_Rela *rel_end;
887 asection *sgot;
888 asection *srelgot;
889 asection *sreloc;
890 if (info->relocatable)
891 return TRUE;
892
893 dynobj = elf_hash_table (info)->dynobj;
894 symtab_hdr = &elf_tdata (abfd)->symtab_hdr;
895 sym_hashes = elf_sym_hashes (abfd);
896 local_got_refcounts = elf_local_got_refcounts (abfd);
897
898 sgot = NULL;
899 srelgot = NULL;
900 sreloc = NULL;
901
902 rel_end = relocs + sec->reloc_count;
903 for (rel = relocs; rel < rel_end; rel++)
904 {
905 unsigned long r_symndx;
906 struct elf_link_hash_entry *h;
907
908 r_symndx = ELF32_R_SYM (rel->r_info);
909 if (r_symndx < symtab_hdr->sh_info)
910 h = NULL;
911 else
912 h = sym_hashes[r_symndx - symtab_hdr->sh_info];
913
914 switch (ELF32_R_TYPE (rel->r_info))
915 {
916 /* This relocation describes the C++ object vtable hierarchy.
917 Reconstruct it for later use during GC. */
918 case R_BFIN_GNU_VTINHERIT:
919 if (!bfd_elf_gc_record_vtinherit (abfd, sec, h, rel->r_offset))
920 return FALSE;
921 break;
922
923 /* This relocation describes which C++ vtable entries
924 are actually used. Record for later use during GC. */
925 case R_BFIN_GNU_VTENTRY:
926 if (!bfd_elf_gc_record_vtentry (abfd, sec, h, rel->r_addend))
927 return FALSE;
928 break;
929
930 case R_got:
931 if (h != NULL
932 && strcmp (h->root.root.string, "_GLOBAL_OFFSET_TABLE_") == 0)
933 break;
934 /* Fall through. */
935
936 if (dynobj == NULL)
937 {
938 /* Create the .got section. */
939 elf_hash_table (info)->dynobj = dynobj = abfd;
940 if (!_bfd_elf_create_got_section (dynobj, info))
941 return FALSE;
942 }
943
944 if (sgot == NULL)
945 {
946 sgot = bfd_get_section_by_name (dynobj, ".got");
947 BFD_ASSERT (sgot != NULL);
948 }
949
950 if (srelgot == NULL && (h != NULL || info->shared))
951 {
952 srelgot = bfd_get_section_by_name (dynobj, ".rela.got");
953 if (srelgot == NULL)
954 {
955 srelgot = bfd_make_section (dynobj, ".rela.got");
956 if (srelgot == NULL
957 || !bfd_set_section_flags (dynobj, srelgot,
958 (SEC_ALLOC
959 | SEC_LOAD
960 | SEC_HAS_CONTENTS
961 | SEC_IN_MEMORY
962 | SEC_LINKER_CREATED
963 | SEC_READONLY))
964 || !bfd_set_section_alignment (dynobj, srelgot, 2))
965 return FALSE;
966 }
967 }
968
969 if (h != NULL)
970 {
971 if (h->got.refcount == 0)
972 {
973 /* Make sure this symbol is output as a dynamic symbol. */
974 if (h->dynindx == -1 && !h->forced_local)
975 {
976 if (!bfd_elf_link_record_dynamic_symbol (info, h))
977 return FALSE;
978 }
979
980 /* Allocate space in the .got section. */
981 sgot->size += 4;
982 /* Allocate relocation space. */
983 srelgot->size += sizeof (Elf32_External_Rela);
984 }
985 h->got.refcount++;
986 }
987 else
988 {
989 /* This is a global offset table entry for a local symbol. */
990 if (local_got_refcounts == NULL)
991 {
992 bfd_size_type size;
993
994 size = symtab_hdr->sh_info;
995 size *= sizeof (bfd_signed_vma);
996 local_got_refcounts = ((bfd_signed_vma *)
997 bfd_zalloc (abfd, size));
998 if (local_got_refcounts == NULL)
999 return FALSE;
1000 elf_local_got_refcounts (abfd) = local_got_refcounts;
1001 }
1002 if (local_got_refcounts[r_symndx] == 0)
1003 {
1004 sgot->size += 4;
1005 if (info->shared)
1006 {
1007 /* If we are generating a shared object, we need to
1008 output a R_68K_RELATIVE reloc so that the dynamic
1009 linker can adjust this GOT entry. */
1010 srelgot->size += sizeof (Elf32_External_Rela);
1011 }
1012 }
1013 local_got_refcounts[r_symndx]++;
1014 }
1015 break;
1016
1017 default:
1018 break;
1019 }
1020 }
1021
1022 return TRUE;
1023 }
1024
1025 static enum elf_reloc_type_class
1026 elf32_bfin_reloc_type_class (const Elf_Internal_Rela * rela)
1027 {
1028 switch ((int) ELF32_R_TYPE (rela->r_info))
1029 {
1030 default:
1031 return reloc_class_normal;
1032 }
1033 }
1034
1035 static bfd_boolean
1036 bfin_relocate_section (bfd * output_bfd,
1037 struct bfd_link_info *info,
1038 bfd * input_bfd,
1039 asection * input_section,
1040 bfd_byte * contents,
1041 Elf_Internal_Rela * relocs,
1042 Elf_Internal_Sym * local_syms,
1043 asection ** local_sections)
1044 {
1045 bfd *dynobj;
1046 Elf_Internal_Shdr *symtab_hdr;
1047 struct elf_link_hash_entry **sym_hashes;
1048 bfd_vma *local_got_offsets;
1049 asection *sgot;
1050 asection *sreloc;
1051 Elf_Internal_Rela *rel;
1052 Elf_Internal_Rela *relend;
1053 int i = 0;
1054
1055 if (info->relocatable)
1056 return TRUE;
1057
1058 dynobj = elf_hash_table (info)->dynobj;
1059 symtab_hdr = &elf_tdata (input_bfd)->symtab_hdr;
1060 sym_hashes = elf_sym_hashes (input_bfd);
1061 local_got_offsets = elf_local_got_offsets (input_bfd);
1062
1063 sgot = NULL;
1064 sreloc = NULL;
1065
1066 rel = relocs;
1067 relend = relocs + input_section->reloc_count;
1068 for (; rel < relend; rel++, i++)
1069 {
1070 int r_type;
1071 reloc_howto_type *howto;
1072 unsigned long r_symndx;
1073 struct elf_link_hash_entry *h;
1074 Elf_Internal_Sym *sym;
1075 asection *sec;
1076 bfd_vma relocation = 0;
1077 bfd_boolean unresolved_reloc;
1078 bfd_reloc_status_type r;
1079 bfd_vma address;
1080
1081 r_type = ELF32_R_TYPE (rel->r_info);
1082 if (r_type < 0 || r_type >= 243)
1083 {
1084 bfd_set_error (bfd_error_bad_value);
1085 return FALSE;
1086 }
1087
1088 if (r_type == R_BFIN_GNU_VTENTRY
1089 || r_type == R_BFIN_GNU_VTINHERIT)
1090 continue;
1091
1092 howto = bfin_reloc_type_lookup (input_bfd, r_type);
1093 if (howto == NULL)
1094 {
1095 bfd_set_error (bfd_error_bad_value);
1096 return FALSE;
1097 }
1098 r_symndx = ELF32_R_SYM (rel->r_info);
1099
1100 h = NULL;
1101 sym = NULL;
1102 sec = NULL;
1103 unresolved_reloc = FALSE;
1104
1105 if (r_symndx < symtab_hdr->sh_info)
1106 {
1107 sym = local_syms + r_symndx;
1108 sec = local_sections[r_symndx];
1109 relocation = _bfd_elf_rela_local_sym (output_bfd, sym, &sec, rel);
1110 }
1111 else
1112 {
1113 bfd_boolean warned;
1114 h = NULL;
1115 RELOC_FOR_GLOBAL_SYMBOL (info, input_bfd, input_section, rel,
1116 r_symndx, symtab_hdr, sym_hashes,
1117 h, sec, relocation,
1118 unresolved_reloc, warned);
1119 }
1120
1121 address = rel->r_offset;
1122
1123 /* Then, process normally. */
1124 switch (r_type)
1125 {
1126 case R_BFIN_GNU_VTINHERIT:
1127 case R_BFIN_GNU_VTENTRY:
1128 return bfd_reloc_ok;
1129
1130 case R_got:
1131 /* Relocation is to the address of the entry for this symbol
1132 in the global offset table. */
1133 if (h != NULL
1134 && strcmp (h->root.root.string, "_GLOBAL_OFFSET_TABLE_") == 0)
1135 goto do_default;
1136 /* Fall through. */
1137 /* Relocation is the offset of the entry for this symbol in
1138 the global offset table. */
1139
1140 {
1141 bfd_vma off;
1142
1143 if (sgot == NULL)
1144 {
1145 sgot = bfd_get_section_by_name (dynobj, ".got");
1146 BFD_ASSERT (sgot != NULL);
1147 }
1148
1149 if (h != NULL)
1150 {
1151 bfd_boolean dyn;
1152
1153 off = h->got.offset;
1154 BFD_ASSERT (off != (bfd_vma) - 1);
1155 dyn = elf_hash_table (info)->dynamic_sections_created;
1156
1157 if (!WILL_CALL_FINISH_DYNAMIC_SYMBOL (dyn, info->shared, h)
1158 || (info->shared
1159 && (info->symbolic
1160 || h->dynindx == -1
1161 || h->forced_local)
1162 && h->def_regular))
1163 {
1164 /* This is actually a static link, or it is a
1165 -Bsymbolic link and the symbol is defined
1166 locally, or the symbol was forced to be local
1167 because of a version file.. We must initialize
1168 this entry in the global offset table. Since
1169 the offset must always be a multiple of 4, we
1170 use the least significant bit to record whether
1171 we have initialized it already.
1172
1173 When doing a dynamic link, we create a .rela.got
1174 relocation entry to initialize the value. This
1175 is done in the finish_dynamic_symbol routine. */
1176 if ((off & 1) != 0)
1177 off &= ~1;
1178 else
1179 {
1180 bfd_put_32 (output_bfd, relocation,
1181 sgot->contents + off);
1182 h->got.offset |= 1;
1183 }
1184 }
1185 else
1186 unresolved_reloc = FALSE;
1187 }
1188 else
1189 {
1190 BFD_ASSERT (local_got_offsets != NULL);
1191 off = local_got_offsets[r_symndx];
1192 BFD_ASSERT (off != (bfd_vma) - 1);
1193
1194 /* The offset must always be a multiple of 4. We use
1195 the least significant bit to record whether we have
1196 already generated the necessary reloc. */
1197 if ((off & 1) != 0)
1198 off &= ~1;
1199 else
1200 {
1201 bfd_put_32 (output_bfd, relocation, sgot->contents + off);
1202
1203 if (info->shared)
1204 {
1205 asection *s;
1206 Elf_Internal_Rela outrel;
1207 bfd_byte *loc;
1208
1209 s = bfd_get_section_by_name (dynobj, ".rela.got");
1210 BFD_ASSERT (s != NULL);
1211
1212 outrel.r_offset = (sgot->output_section->vma
1213 + sgot->output_offset + off);
1214 outrel.r_info =
1215 ELF32_R_INFO (0, R_pcrel24);
1216 outrel.r_addend = relocation;
1217 loc = s->contents;
1218 loc +=
1219 s->reloc_count++ * sizeof (Elf32_External_Rela);
1220 bfd_elf32_swap_reloca_out (output_bfd, &outrel, loc);
1221 }
1222
1223 local_got_offsets[r_symndx] |= 1;
1224 }
1225 }
1226
1227 relocation = sgot->output_offset + off;
1228 rel->r_addend = 0;
1229 /* bfin : preg = [preg + 17bitdiv4offset] relocation is div by 4. */
1230 relocation /= 4;
1231 }
1232 goto do_default;
1233
1234 case R_pcrel24:
1235 case R_pcrel24_jump_l:
1236 {
1237 bfd_vma x;
1238
1239 relocation += rel->r_addend;
1240
1241 /* Perform usual pc-relative correction. */
1242 relocation -= input_section->output_section->vma + input_section->output_offset;
1243 relocation -= address;
1244
1245 /* We are getting reloc_entry->address 2 byte off from
1246 the start of instruction. Assuming absolute postion
1247 of the reloc data. But, following code had been written assuming
1248 reloc address is starting at begining of instruction.
1249 To compensate that I have increased the value of
1250 relocation by 1 (effectively 2) and used the addr -2 instead of addr. */
1251
1252 relocation += 2;
1253 address -= 2;
1254
1255 relocation >>= 1;
1256
1257 x = bfd_get_16 (input_bfd, contents + address);
1258 x = (x & 0xff00) | ((relocation >> 16) & 0xff);
1259 bfd_put_16 (input_bfd, x, contents + address);
1260
1261 x = bfd_get_16 (input_bfd, contents + address + 2);
1262 x = relocation & 0xFFFF;
1263 bfd_put_16 (input_bfd, x, contents + address + 2);
1264 r = bfd_reloc_ok;
1265 }
1266 break;
1267
1268 default:
1269 do_default:
1270 r = _bfd_final_link_relocate (howto, input_bfd, input_section,
1271 contents, address,
1272 relocation, rel->r_addend);
1273
1274 break;
1275 }
1276
1277 /* Dynamic relocs are not propagated for SEC_DEBUGGING sections
1278 because such sections are not SEC_ALLOC and thus ld.so will
1279 not process them. */
1280 if (unresolved_reloc
1281 && !((input_section->flags & SEC_DEBUGGING) != 0 && h->def_dynamic))
1282 {
1283 (*_bfd_error_handler)
1284 (_("%B(%A+0x%lx): unresolvable relocation against symbol `%s'"),
1285 input_bfd,
1286 input_section, (long) rel->r_offset, h->root.root.string);
1287 return FALSE;
1288 }
1289
1290 if (r != bfd_reloc_ok)
1291 {
1292 const char *name;
1293
1294 if (h != NULL)
1295 name = h->root.root.string;
1296 else
1297 {
1298 name = bfd_elf_string_from_elf_section (input_bfd,
1299 symtab_hdr->sh_link,
1300 sym->st_name);
1301 if (name == NULL)
1302 return FALSE;
1303 if (*name == '\0')
1304 name = bfd_section_name (input_bfd, sec);
1305 }
1306
1307 if (r == bfd_reloc_overflow)
1308 {
1309 if (!(info->callbacks->reloc_overflow
1310 (info, (h ? &h->root : NULL), name, howto->name,
1311 (bfd_vma) 0, input_bfd, input_section, rel->r_offset)))
1312 return FALSE;
1313 }
1314 else
1315 {
1316 (*_bfd_error_handler)
1317 (_("%B(%A+0x%lx): reloc against `%s': error %d"),
1318 input_bfd, input_section,
1319 (long) rel->r_offset, name, (int) r);
1320 return FALSE;
1321 }
1322 }
1323 }
1324
1325 return TRUE;
1326 }
1327
1328 static asection *
1329 bfin_gc_mark_hook (asection * sec,
1330 struct bfd_link_info *info ATTRIBUTE_UNUSED,
1331 Elf_Internal_Rela * rel,
1332 struct elf_link_hash_entry *h,
1333 Elf_Internal_Sym * sym)
1334 {
1335 if (h != NULL)
1336 {
1337 switch (ELF32_R_TYPE (rel->r_info))
1338 {
1339
1340 case R_BFIN_GNU_VTINHERIT:
1341 case R_BFIN_GNU_VTENTRY:
1342 break;
1343
1344 default:
1345 switch (h->root.type)
1346 {
1347 default:
1348 break;
1349
1350 case bfd_link_hash_defined:
1351 case bfd_link_hash_defweak:
1352 return h->root.u.def.section;
1353
1354 case bfd_link_hash_common:
1355 return h->root.u.c.p->section;
1356 }
1357 }
1358 }
1359 else
1360 return bfd_section_from_elf_index (sec->owner, sym->st_shndx);
1361
1362 return NULL;
1363 }
1364
1365
1366 /* Update the got entry reference counts for the section being removed. */
1367
1368 static bfd_boolean
1369 bfin_gc_sweep_hook (bfd * abfd,
1370 struct bfd_link_info *info,
1371 asection * sec,
1372 const Elf_Internal_Rela * relocs)
1373 {
1374 Elf_Internal_Shdr *symtab_hdr;
1375 struct elf_link_hash_entry **sym_hashes;
1376 bfd_signed_vma *local_got_refcounts;
1377 const Elf_Internal_Rela *rel, *relend;
1378 bfd *dynobj;
1379 asection *sgot;
1380 asection *srelgot;
1381
1382 dynobj = elf_hash_table (info)->dynobj;
1383 if (dynobj == NULL)
1384 return TRUE;
1385
1386 symtab_hdr = &elf_tdata (abfd)->symtab_hdr;
1387 sym_hashes = elf_sym_hashes (abfd);
1388 local_got_refcounts = elf_local_got_refcounts (abfd);
1389
1390 sgot = bfd_get_section_by_name (dynobj, ".got");
1391 srelgot = bfd_get_section_by_name (dynobj, ".rela.got");
1392
1393 relend = relocs + sec->reloc_count;
1394 for (rel = relocs; rel < relend; rel++)
1395 {
1396 unsigned long r_symndx;
1397 struct elf_link_hash_entry *h;
1398
1399 switch (ELF32_R_TYPE (rel->r_info))
1400 {
1401 case R_got:
1402 r_symndx = ELF32_R_SYM (rel->r_info);
1403 if (r_symndx >= symtab_hdr->sh_info)
1404 {
1405 h = sym_hashes[r_symndx - symtab_hdr->sh_info];
1406 if (h->got.refcount > 0)
1407 {
1408 --h->got.refcount;
1409 if (h->got.refcount == 0)
1410 {
1411 /* We don't need the .got entry any more. */
1412 sgot->size -= 4;
1413 srelgot->size -= sizeof (Elf32_External_Rela);
1414 }
1415 }
1416 }
1417 else if (local_got_refcounts != NULL)
1418 {
1419 if (local_got_refcounts[r_symndx] > 0)
1420 {
1421 --local_got_refcounts[r_symndx];
1422 if (local_got_refcounts[r_symndx] == 0)
1423 {
1424 /* We don't need the .got entry any more. */
1425 sgot->size -= 4;
1426 if (info->shared)
1427 srelgot->size -= sizeof (Elf32_External_Rela);
1428 }
1429 }
1430 }
1431 break;
1432 default:
1433 break;
1434 }
1435 }
1436
1437 return TRUE;
1438 }
1439
1440
1441 /* Merge backend specific data from an object file to the output
1442 object file when linking. */
1443 static bfd_boolean
1444 elf32_bfin_merge_private_bfd_data (bfd * ibfd, bfd * obfd)
1445 {
1446 flagword out_flags;
1447 flagword in_flags;
1448
1449 if (bfd_get_flavour (ibfd) != bfd_target_elf_flavour
1450 || bfd_get_flavour (obfd) != bfd_target_elf_flavour)
1451 return TRUE;
1452
1453 in_flags = elf_elfheader (ibfd)->e_flags;
1454 out_flags = elf_elfheader (obfd)->e_flags;
1455
1456 if (!elf_flags_init (obfd))
1457 {
1458 elf_flags_init (obfd) = TRUE;
1459 elf_elfheader (obfd)->e_flags = in_flags;
1460 }
1461
1462 return TRUE;
1463 }
1464
1465
1466 static bfd_boolean
1467 elf32_bfin_set_private_flags (bfd * abfd, flagword flags)
1468 {
1469 elf_elfheader (abfd)->e_flags = flags;
1470 elf_flags_init (abfd) = TRUE;
1471 return TRUE;
1472 }
1473
1474
1475 /* Display the flags field. */
1476 static bfd_boolean
1477 elf32_bfin_print_private_bfd_data (bfd * abfd, PTR ptr)
1478 {
1479 FILE *file = (FILE *) ptr;
1480
1481 BFD_ASSERT (abfd != NULL && ptr != NULL);
1482
1483 /* Print normal ELF private data. */
1484 _bfd_elf_print_private_bfd_data (abfd, ptr);
1485
1486 /* Ignore init flag - it may not be set, despite the flags field
1487 containing valid data. */
1488
1489 /* xgettext:c-format */
1490 fprintf (file, _("private flags = %lx:"), elf_elfheader (abfd)->e_flags);
1491
1492 fputc ('\n', file);
1493
1494 return TRUE;
1495 }
1496
1497 /* bfin ELF linker hash entry. */
1498
1499 struct bfin_link_hash_entry
1500 {
1501 struct elf_link_hash_entry root;
1502
1503 /* Number of PC relative relocs copied for this symbol. */
1504 struct bfin_pcrel_relocs_copied *pcrel_relocs_copied;
1505 };
1506
1507 /* bfin ELF linker hash table. */
1508
1509 struct bfin_link_hash_table
1510 {
1511 struct elf_link_hash_table root;
1512
1513 /* Small local sym to section mapping cache. */
1514 struct sym_sec_cache sym_sec;
1515 };
1516
1517 #define bfin_hash_entry(ent) ((struct bfin_link_hash_entry *) (ent))
1518
1519 static struct bfd_hash_entry *
1520 bfin_link_hash_newfunc (struct bfd_hash_entry *entry,
1521 struct bfd_hash_table *table, const char *string)
1522 {
1523 struct bfd_hash_entry *ret = entry;
1524
1525 /* Allocate the structure if it has not already been allocated by a
1526 subclass. */
1527 if (ret == NULL)
1528 ret = bfd_hash_allocate (table, sizeof (struct bfin_link_hash_entry));
1529 if (ret == NULL)
1530 return ret;
1531
1532 /* Call the allocation method of the superclass. */
1533 ret = _bfd_elf_link_hash_newfunc (ret, table, string);
1534 if (ret != NULL)
1535 bfin_hash_entry (ret)->pcrel_relocs_copied = NULL;
1536
1537 return ret;
1538 }
1539
1540 /* Create an bfin ELF linker hash table. */
1541
1542 static struct bfd_link_hash_table *
1543 bfin_link_hash_table_create (bfd * abfd)
1544 {
1545 struct bfin_link_hash_table *ret;
1546 bfd_size_type amt = sizeof (struct bfin_link_hash_table);
1547
1548 ret = (struct bfin_link_hash_table *) bfd_malloc (amt);
1549 if (ret == (struct bfin_link_hash_table *) NULL)
1550 return NULL;
1551
1552 if (!_bfd_elf_link_hash_table_init (&ret->root, abfd,
1553 bfin_link_hash_newfunc,
1554 sizeof (struct bfin_link_hash_entry)))
1555 {
1556 free (ret);
1557 return NULL;
1558 }
1559
1560 ret->sym_sec.abfd = NULL;
1561
1562 return &ret->root.root;
1563 }
1564
1565 /* The size in bytes of an entry in the procedure linkage table. */
1566
1567 /* Finish up the dynamic sections. */
1568
1569 static bfd_boolean
1570 bfin_finish_dynamic_sections (bfd * output_bfd ATTRIBUTE_UNUSED,
1571 struct bfd_link_info *info)
1572 {
1573 bfd *dynobj;
1574 asection *sdyn;
1575
1576 dynobj = elf_hash_table (info)->dynobj;
1577
1578 sdyn = bfd_get_section_by_name (dynobj, ".dynamic");
1579
1580 if (elf_hash_table (info)->dynamic_sections_created)
1581 {
1582 Elf32_External_Dyn *dyncon, *dynconend;
1583
1584 BFD_ASSERT (sdyn != NULL);
1585
1586 dyncon = (Elf32_External_Dyn *) sdyn->contents;
1587 dynconend = (Elf32_External_Dyn *) (sdyn->contents + sdyn->size);
1588 for (; dyncon < dynconend; dyncon++)
1589 {
1590 Elf_Internal_Dyn dyn;
1591
1592 bfd_elf32_swap_dyn_in (dynobj, dyncon, &dyn);
1593
1594 }
1595
1596 }
1597 return TRUE;
1598 }
1599
1600 /* Finish up dynamic symbol handling. We set the contents of various
1601 dynamic sections here. */
1602
1603 static bfd_boolean
1604 bfin_finish_dynamic_symbol (bfd * output_bfd,
1605 struct bfd_link_info *info,
1606 struct elf_link_hash_entry *h,
1607 Elf_Internal_Sym * sym)
1608 {
1609 bfd *dynobj;
1610
1611 dynobj = elf_hash_table (info)->dynobj;
1612
1613 if (h->got.offset != (bfd_vma) - 1)
1614 {
1615 asection *sgot;
1616 asection *srela;
1617 Elf_Internal_Rela rela;
1618 bfd_byte *loc;
1619
1620 /* This symbol has an entry in the global offset table.
1621 Set it up. */
1622
1623 sgot = bfd_get_section_by_name (dynobj, ".got");
1624 srela = bfd_get_section_by_name (dynobj, ".rela.got");
1625 BFD_ASSERT (sgot != NULL && srela != NULL);
1626
1627 rela.r_offset = (sgot->output_section->vma
1628 + sgot->output_offset
1629 + (h->got.offset & ~(bfd_vma) 1));
1630
1631 /* If this is a -Bsymbolic link, and the symbol is defined
1632 locally, we just want to emit a RELATIVE reloc. Likewise if
1633 the symbol was forced to be local because of a version file.
1634 The entry in the global offset table will already have been
1635 initialized in the relocate_section function. */
1636 if (info->shared
1637 && (info->symbolic
1638 || h->dynindx == -1 || h->forced_local) && h->def_regular)
1639 {
1640 fprintf(stderr, "*** check this relocation %s\n", __FUNCTION__);
1641 rela.r_info = ELF32_R_INFO (0, R_pcrel24);
1642 rela.r_addend = bfd_get_signed_32 (output_bfd,
1643 (sgot->contents
1644 +
1645 (h->got.
1646 offset & ~(bfd_vma) 1)));
1647 }
1648 else
1649 {
1650 bfd_put_32 (output_bfd, (bfd_vma) 0,
1651 sgot->contents + (h->got.offset & ~(bfd_vma) 1));
1652 rela.r_info = ELF32_R_INFO (h->dynindx, R_got);
1653 rela.r_addend = 0;
1654 }
1655
1656 loc = srela->contents;
1657 loc += srela->reloc_count++ * sizeof (Elf32_External_Rela);
1658 bfd_elf32_swap_reloca_out (output_bfd, &rela, loc);
1659 }
1660
1661 if (h->needs_copy)
1662 {
1663 BFD_ASSERT (0);
1664 }
1665 /* Mark _DYNAMIC and _GLOBAL_OFFSET_TABLE_ as absolute. */
1666 if (strcmp (h->root.root.string, "_DYNAMIC") == 0
1667 || h == elf_hash_table (info)->hgot)
1668 sym->st_shndx = SHN_ABS;
1669
1670 return TRUE;
1671 }
1672
1673 /* Adjust a symbol defined by a dynamic object and referenced by a
1674 regular object. The current definition is in some section of the
1675 dynamic object, but we're not including those sections. We have to
1676 change the definition to something the rest of the link can
1677 understand. */
1678
1679 static bfd_boolean
1680 bfin_adjust_dynamic_symbol (struct bfd_link_info *info,
1681 struct elf_link_hash_entry *h)
1682 {
1683 bfd *dynobj;
1684 asection *s;
1685 unsigned int power_of_two;
1686
1687 dynobj = elf_hash_table (info)->dynobj;
1688
1689 /* Make sure we know what is going on here. */
1690 BFD_ASSERT (dynobj != NULL
1691 && (h->needs_plt
1692 || h->u.weakdef != NULL
1693 || (h->def_dynamic && h->ref_regular && !h->def_regular)));
1694
1695 /* If this is a function, put it in the procedure linkage table. We
1696 will fill in the contents of the procedure linkage table later,
1697 when we know the address of the .got section. */
1698 if (h->type == STT_FUNC || h->needs_plt)
1699 {
1700 BFD_ASSERT(0);
1701 }
1702
1703 /* If this is a weak symbol, and there is a real definition, the
1704 processor independent code will have arranged for us to see the
1705 real definition first, and we can just use the same value. */
1706 if (h->u.weakdef != NULL)
1707 {
1708 BFD_ASSERT (h->u.weakdef->root.type == bfd_link_hash_defined
1709 || h->u.weakdef->root.type == bfd_link_hash_defweak);
1710 h->root.u.def.section = h->u.weakdef->root.u.def.section;
1711 h->root.u.def.value = h->u.weakdef->root.u.def.value;
1712 return TRUE;
1713 }
1714
1715 /* This is a reference to a symbol defined by a dynamic object which
1716 is not a function. */
1717
1718 /* If we are creating a shared library, we must presume that the
1719 only references to the symbol are via the global offset table.
1720 For such cases we need not do anything here; the relocations will
1721 be handled correctly by relocate_section. */
1722 if (info->shared)
1723 return TRUE;
1724
1725 /* We must allocate the symbol in our .dynbss section, which will
1726 become part of the .bss section of the executable. There will be
1727 an entry for this symbol in the .dynsym section. The dynamic
1728 object will contain position independent code, so all references
1729 from the dynamic object to this symbol will go through the global
1730 offset table. The dynamic linker will use the .dynsym entry to
1731 determine the address it must put in the global offset table, so
1732 both the dynamic object and the regular object will refer to the
1733 same memory location for the variable. */
1734
1735 s = bfd_get_section_by_name (dynobj, ".dynbss");
1736 BFD_ASSERT (s != NULL);
1737
1738 /* We must generate a R_68K_COPY reloc to tell the dynamic linker to
1739 copy the initial value out of the dynamic object and into the
1740 runtime process image. We need to remember the offset into the
1741 .rela.bss section we are going to use. */
1742 if ((h->root.u.def.section->flags & SEC_ALLOC) != 0)
1743 {
1744 asection *srel;
1745
1746 srel = bfd_get_section_by_name (dynobj, ".rela.bss");
1747 BFD_ASSERT (srel != NULL);
1748 srel->size += sizeof (Elf32_External_Rela);
1749 h->needs_copy = 1;
1750 }
1751
1752 /* We need to figure out the alignment required for this symbol. I
1753 have no idea how ELF linkers handle this. */
1754 power_of_two = bfd_log2 (h->size);
1755 if (power_of_two > 3)
1756 power_of_two = 3;
1757
1758 /* Apply the required alignment. */
1759 s->size = BFD_ALIGN (s->size, (bfd_size_type) (1 << power_of_two));
1760 if (power_of_two > bfd_get_section_alignment (dynobj, s))
1761 {
1762 if (!bfd_set_section_alignment (dynobj, s, power_of_two))
1763 return FALSE;
1764 }
1765
1766 /* Define the symbol as being at this point in the section. */
1767 h->root.u.def.section = s;
1768 h->root.u.def.value = s->size;
1769
1770 /* Increment the section size to make room for the symbol. */
1771 s->size += h->size;
1772
1773 return TRUE;
1774 }
1775
1776 /* The bfin linker needs to keep track of the number of relocs that it
1777 decides to copy in check_relocs for each symbol. This is so that it
1778 can discard PC relative relocs if it doesn't need them when linking
1779 with -Bsymbolic. We store the information in a field extending the
1780 regular ELF linker hash table. */
1781
1782 /* This structure keeps track of the number of PC relative relocs we have
1783 copied for a given symbol. */
1784
1785 struct bfin_pcrel_relocs_copied
1786 {
1787 /* Next section. */
1788 struct bfin_pcrel_relocs_copied *next;
1789 /* A section in dynobj. */
1790 asection *section;
1791 /* Number of relocs copied in this section. */
1792 bfd_size_type count;
1793 };
1794
1795 /* This function is called via elf_link_hash_traverse if we are
1796 creating a shared object. In the -Bsymbolic case it discards the
1797 space allocated to copy PC relative relocs against symbols which
1798 are defined in regular objects. For the normal shared case, it
1799 discards space for pc-relative relocs that have become local due to
1800 symbol visibility changes. We allocated space for them in the
1801 check_relocs routine, but we won't fill them in in the
1802 relocate_section routine.
1803
1804 We also check whether any of the remaining relocations apply
1805 against a readonly section, and set the DF_TEXTREL flag in this
1806 case. */
1807
1808 static bfd_boolean
1809 bfin_discard_copies (struct elf_link_hash_entry *h, PTR inf)
1810 {
1811 struct bfd_link_info *info = (struct bfd_link_info *) inf;
1812 struct bfin_pcrel_relocs_copied *s;
1813
1814 if (h->root.type == bfd_link_hash_warning)
1815 h = (struct elf_link_hash_entry *) h->root.u.i.link;
1816
1817 if (!h->def_regular || (!info->symbolic && !h->forced_local))
1818 {
1819 if ((info->flags & DF_TEXTREL) == 0)
1820 {
1821 /* Look for relocations against read-only sections. */
1822 for (s = bfin_hash_entry (h)->pcrel_relocs_copied;
1823 s != NULL; s = s->next)
1824 if ((s->section->flags & SEC_READONLY) != 0)
1825 {
1826 info->flags |= DF_TEXTREL;
1827 break;
1828 }
1829 }
1830
1831 return TRUE;
1832 }
1833
1834 for (s = bfin_hash_entry (h)->pcrel_relocs_copied;
1835 s != NULL; s = s->next)
1836 s->section->size -= s->count * sizeof (Elf32_External_Rela);
1837
1838 return TRUE;
1839 }
1840
1841 /* Set the sizes of the dynamic sections. */
1842 #define ELF_DYNAMIC_INTERPRETER "/usr/lib/libc.so.1"
1843
1844 static bfd_boolean
1845 bfin_size_dynamic_sections (bfd * output_bfd ATTRIBUTE_UNUSED,
1846 struct bfd_link_info *info)
1847 {
1848 bfd *dynobj;
1849 asection *s;
1850 bfd_boolean relocs;
1851
1852 dynobj = elf_hash_table (info)->dynobj;
1853 BFD_ASSERT (dynobj != NULL);
1854
1855 if (elf_hash_table (info)->dynamic_sections_created)
1856 {
1857 /* Set the contents of the .interp section to the interpreter. */
1858 if (info->executable)
1859 {
1860 s = bfd_get_section_by_name (dynobj, ".interp");
1861 BFD_ASSERT (s != NULL);
1862 s->size = sizeof ELF_DYNAMIC_INTERPRETER;
1863 s->contents = (unsigned char *) ELF_DYNAMIC_INTERPRETER;
1864 }
1865 }
1866 else
1867 {
1868 /* We may have created entries in the .rela.got section.
1869 However, if we are not creating the dynamic sections, we will
1870 not actually use these entries. Reset the size of .rela.got,
1871 which will cause it to get stripped from the output file
1872 below. */
1873 s = bfd_get_section_by_name (dynobj, ".rela.got");
1874 if (s != NULL)
1875 s->size = 0;
1876 }
1877
1878 /* If this is a -Bsymbolic shared link, then we need to discard all
1879 PC relative relocs against symbols defined in a regular object.
1880 For the normal shared case we discard the PC relative relocs
1881 against symbols that have become local due to visibility changes.
1882 We allocated space for them in the check_relocs routine, but we
1883 will not fill them in in the relocate_section routine. */
1884 if (info->shared)
1885 elf_link_hash_traverse (elf_hash_table (info),
1886 bfin_discard_copies, (PTR) info);
1887
1888 /* The check_relocs and adjust_dynamic_symbol entry points have
1889 determined the sizes of the various dynamic sections. Allocate
1890 memory for them. */
1891 relocs = FALSE;
1892 for (s = dynobj->sections; s != NULL; s = s->next)
1893 {
1894 const char *name;
1895 bfd_boolean strip;
1896
1897 if ((s->flags & SEC_LINKER_CREATED) == 0)
1898 continue;
1899
1900 /* It's OK to base decisions on the section name, because none
1901 of the dynobj section names depend upon the input files. */
1902 name = bfd_get_section_name (dynobj, s);
1903
1904 strip = FALSE;
1905
1906 if (strncmp (name, ".rela", 5) == 0)
1907 {
1908 if (s->size == 0)
1909 {
1910 /* If we don't need this section, strip it from the
1911 output file. This is mostly to handle .rela.bss and
1912 .rela.plt. We must create both sections in
1913 create_dynamic_sections, because they must be created
1914 before the linker maps input sections to output
1915 sections. The linker does that before
1916 adjust_dynamic_symbol is called, and it is that
1917 function which decides whether anything needs to go
1918 into these sections. */
1919 strip = TRUE;
1920 }
1921 else
1922 {
1923 relocs = TRUE;
1924
1925 /* We use the reloc_count field as a counter if we need
1926 to copy relocs into the output file. */
1927 s->reloc_count = 0;
1928 }
1929 }
1930 else if (strncmp (name, ".got", 4) != 0)
1931 {
1932 /* It's not one of our sections, so don't allocate space. */
1933 continue;
1934 }
1935
1936 if (strip)
1937 {
1938 s->flags |= SEC_EXCLUDE;
1939 continue;
1940 }
1941
1942 /* Allocate memory for the section contents. */
1943 /* FIXME: This should be a call to bfd_alloc not bfd_zalloc.
1944 Unused entries should be reclaimed before the section's contents
1945 are written out, but at the moment this does not happen. Thus in
1946 order to prevent writing out garbage, we initialise the section's
1947 contents to zero. */
1948 s->contents = (bfd_byte *) bfd_zalloc (dynobj, s->size);
1949 if (s->contents == NULL && s->size != 0)
1950 return FALSE;
1951 }
1952
1953 if (elf_hash_table (info)->dynamic_sections_created)
1954 {
1955 /* Add some entries to the .dynamic section. We fill in the
1956 values later, in bfin_finish_dynamic_sections, but we
1957 must add the entries now so that we get the correct size for
1958 the .dynamic section. The DT_DEBUG entry is filled in by the
1959 dynamic linker and used by the debugger. */
1960 #define add_dynamic_entry(TAG, VAL) \
1961 _bfd_elf_add_dynamic_entry (info, TAG, VAL)
1962
1963 if (!info->shared)
1964 {
1965 if (!add_dynamic_entry (DT_DEBUG, 0))
1966 return FALSE;
1967 }
1968
1969
1970 if (relocs)
1971 {
1972 if (!add_dynamic_entry (DT_RELA, 0)
1973 || !add_dynamic_entry (DT_RELASZ, 0)
1974 || !add_dynamic_entry (DT_RELAENT,
1975 sizeof (Elf32_External_Rela)))
1976 return FALSE;
1977 }
1978
1979 if ((info->flags & DF_TEXTREL) != 0)
1980 {
1981 if (!add_dynamic_entry (DT_TEXTREL, 0))
1982 return FALSE;
1983 }
1984 }
1985 #undef add_dynamic_entry
1986
1987 return TRUE;
1988 }
1989
1990 /* Given a .data section and a .emreloc in-memory section, store
1991 relocation information into the .emreloc section which can be
1992 used at runtime to relocate the section. This is called by the
1993 linker when the --embedded-relocs switch is used. This is called
1994 after the add_symbols entry point has been called for all the
1995 objects, and before the final_link entry point is called. */
1996
1997 bfd_boolean bfd_bfin_elf32_create_embedded_relocs
1998 PARAMS ((bfd *, struct bfd_link_info *, asection *, asection *, char **));
1999
2000 bfd_boolean
2001 bfd_bfin_elf32_create_embedded_relocs (
2002 bfd *abfd,
2003 struct bfd_link_info *info,
2004 asection *datasec,
2005 asection *relsec,
2006 char **errmsg)
2007 {
2008 Elf_Internal_Shdr *symtab_hdr;
2009 Elf_Internal_Sym *isymbuf = NULL;
2010 Elf_Internal_Rela *internal_relocs = NULL;
2011 Elf_Internal_Rela *irel, *irelend;
2012 bfd_byte *p;
2013 bfd_size_type amt;
2014
2015 BFD_ASSERT (! info->relocatable);
2016
2017 *errmsg = NULL;
2018
2019 if (datasec->reloc_count == 0)
2020 return TRUE;
2021
2022 symtab_hdr = &elf_tdata (abfd)->symtab_hdr;
2023
2024 /* Get a copy of the native relocations. */
2025 internal_relocs = (_bfd_elf_link_read_relocs
2026 (abfd, datasec, (PTR) NULL, (Elf_Internal_Rela *) NULL,
2027 info->keep_memory));
2028 if (internal_relocs == NULL)
2029 goto error_return;
2030
2031 amt = (bfd_size_type) datasec->reloc_count * 12;
2032 relsec->contents = (bfd_byte *) bfd_alloc (abfd, amt);
2033 if (relsec->contents == NULL)
2034 goto error_return;
2035
2036 p = relsec->contents;
2037
2038 irelend = internal_relocs + datasec->reloc_count;
2039 for (irel = internal_relocs; irel < irelend; irel++, p += 12)
2040 {
2041 asection *targetsec;
2042
2043 /* We are going to write a four byte longword into the runtime
2044 reloc section. The longword will be the address in the data
2045 section which must be relocated. It is followed by the name
2046 of the target section NUL-padded or truncated to 8
2047 characters. */
2048
2049 /* We can only relocate absolute longword relocs at run time. */
2050 if (ELF32_R_TYPE (irel->r_info) != (int) R_byte4_data)
2051 {
2052 *errmsg = _("unsupported reloc type");
2053 bfd_set_error (bfd_error_bad_value);
2054 goto error_return;
2055 }
2056
2057 /* Get the target section referred to by the reloc. */
2058 if (ELF32_R_SYM (irel->r_info) < symtab_hdr->sh_info)
2059 {
2060 /* A local symbol. */
2061 Elf_Internal_Sym *isym;
2062
2063 /* Read this BFD's local symbols if we haven't done so already. */
2064 if (isymbuf == NULL)
2065 {
2066 isymbuf = (Elf_Internal_Sym *) symtab_hdr->contents;
2067 if (isymbuf == NULL)
2068 isymbuf = bfd_elf_get_elf_syms (abfd, symtab_hdr,
2069 symtab_hdr->sh_info, 0,
2070 NULL, NULL, NULL);
2071 if (isymbuf == NULL)
2072 goto error_return;
2073 }
2074
2075 isym = isymbuf + ELF32_R_SYM (irel->r_info);
2076 targetsec = bfd_section_from_elf_index (abfd, isym->st_shndx);
2077 }
2078 else
2079 {
2080 unsigned long indx;
2081 struct elf_link_hash_entry *h;
2082
2083 /* An external symbol. */
2084 indx = ELF32_R_SYM (irel->r_info) - symtab_hdr->sh_info;
2085 h = elf_sym_hashes (abfd)[indx];
2086 BFD_ASSERT (h != NULL);
2087 if (h->root.type == bfd_link_hash_defined
2088 || h->root.type == bfd_link_hash_defweak)
2089 targetsec = h->root.u.def.section;
2090 else
2091 targetsec = NULL;
2092 }
2093
2094 bfd_put_32 (abfd, irel->r_offset + datasec->output_offset, p);
2095 memset (p + 4, 0, 8);
2096 if (targetsec != NULL)
2097 strncpy ((char *) p + 4, targetsec->output_section->name, 8);
2098 }
2099
2100 if (isymbuf != NULL && symtab_hdr->contents != (unsigned char *) isymbuf)
2101 free (isymbuf);
2102 if (internal_relocs != NULL
2103 && elf_section_data (datasec)->relocs != internal_relocs)
2104 free (internal_relocs);
2105 return TRUE;
2106
2107 error_return:
2108 if (isymbuf != NULL && symtab_hdr->contents != (unsigned char *) isymbuf)
2109 free (isymbuf);
2110 if (internal_relocs != NULL
2111 && elf_section_data (datasec)->relocs != internal_relocs)
2112 free (internal_relocs);
2113 return FALSE;
2114 }
2115
2116 #define TARGET_LITTLE_SYM bfd_elf32_bfin_vec
2117 #define TARGET_LITTLE_NAME "elf32-bfin"
2118 #define ELF_ARCH bfd_arch_bfin
2119 #define ELF_MACHINE_CODE EM_BLACKFIN
2120 #define ELF_MAXPAGESIZE 0x1000
2121 #define elf_symbol_leading_char '_'
2122
2123 #define bfd_elf32_bfd_reloc_type_lookup bfin_bfd_reloc_type_lookup
2124 #define elf_info_to_howto bfin_info_to_howto
2125 #define elf_info_to_howto_rel 0
2126
2127 #define bfd_elf32_bfd_is_local_label_name \
2128 bfin_is_local_label_name
2129 #define bfin_hash_table(p) \
2130 ((struct bfin_link_hash_table *) (p)->hash)
2131
2132
2133
2134 #define elf_backend_create_dynamic_sections \
2135 _bfd_elf_create_dynamic_sections
2136 #define bfd_elf32_bfd_link_hash_table_create \
2137 bfin_link_hash_table_create
2138 #define bfd_elf32_bfd_final_link bfd_elf_gc_common_final_link
2139
2140 #define elf_backend_check_relocs bfin_check_relocs
2141 #define elf_backend_adjust_dynamic_symbol \
2142 bfin_adjust_dynamic_symbol
2143 #define elf_backend_size_dynamic_sections \
2144 bfin_size_dynamic_sections
2145 #define elf_backend_relocate_section bfin_relocate_section
2146 #define elf_backend_finish_dynamic_symbol \
2147 bfin_finish_dynamic_symbol
2148 #define elf_backend_finish_dynamic_sections \
2149 bfin_finish_dynamic_sections
2150 #define elf_backend_gc_mark_hook bfin_gc_mark_hook
2151 #define elf_backend_gc_sweep_hook bfin_gc_sweep_hook
2152 #define bfd_elf32_bfd_merge_private_bfd_data \
2153 elf32_bfin_merge_private_bfd_data
2154 #define bfd_elf32_bfd_set_private_flags \
2155 elf32_bfin_set_private_flags
2156 #define bfd_elf32_bfd_print_private_bfd_data \
2157 elf32_bfin_print_private_bfd_data
2158 #define elf_backend_reloc_type_class elf32_bfin_reloc_type_class
2159 #define elf_backend_can_gc_sections 1
2160 #define elf_backend_can_refcount 1
2161 #define elf_backend_want_got_plt 0
2162 #define elf_backend_plt_readonly 1
2163 #define elf_backend_want_plt_sym 0
2164 #define elf_backend_got_header_size 12
2165 #define elf_backend_rela_normal 1
2166
2167
2168 #include "elf32-target.h"
This page took 0.10952 seconds and 4 git commands to generate.