Develop and Download Open Source Software

Browse Subversion Repository

Contents of /trunk/bfd/elf32-bfin.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 21 - (show annotations) (download) (as text)
Mon Jul 27 20:34:36 2009 UTC (14 years, 8 months ago) by monamour
File MIME type: text/x-csrc
File size: 175469 byte(s)
Update to HEAD.
1 /* ADI Blackfin BFD support for 32-bit ELF.
2 Copyright 2005, 2006, 2007 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 3 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,
19 MA 02110-1301, USA. */
20
21 #include "sysdep.h"
22 #include "bfd.h"
23 #include "libbfd.h"
24 #include "elf-bfd.h"
25 #include "elf/bfin.h"
26 #include "dwarf2.h"
27 #include "hashtab.h"
28
29 /* FUNCTION : bfin_pltpc_reloc
30 ABSTRACT : TODO : figure out how to handle pltpc relocs. */
31 static bfd_reloc_status_type
32 bfin_pltpc_reloc (
33 bfd *abfd ATTRIBUTE_UNUSED,
34 arelent *reloc_entry ATTRIBUTE_UNUSED,
35 asymbol *symbol ATTRIBUTE_UNUSED,
36 PTR data ATTRIBUTE_UNUSED,
37 asection *input_section ATTRIBUTE_UNUSED,
38 bfd *output_bfd ATTRIBUTE_UNUSED,
39 char **error_message ATTRIBUTE_UNUSED)
40 {
41 bfd_reloc_status_type flag = bfd_reloc_ok;
42 return flag;
43 }
44
45
46 static bfd_reloc_status_type
47 bfin_pcrel24_reloc (bfd *abfd,
48 arelent *reloc_entry,
49 asymbol *symbol,
50 PTR data,
51 asection *input_section,
52 bfd *output_bfd,
53 char **error_message ATTRIBUTE_UNUSED)
54 {
55 bfd_vma relocation;
56 bfd_size_type addr = reloc_entry->address;
57 bfd_vma output_base = 0;
58 reloc_howto_type *howto = reloc_entry->howto;
59 asection *output_section;
60 bfd_boolean relocatable = (output_bfd != NULL);
61
62 if (reloc_entry->address > bfd_get_section_limit (abfd, input_section))
63 return bfd_reloc_outofrange;
64
65 if (bfd_is_und_section (symbol->section)
66 && (symbol->flags & BSF_WEAK) == 0
67 && !relocatable)
68 return bfd_reloc_undefined;
69
70 if (bfd_is_com_section (symbol->section))
71 relocation = 0;
72 else
73 relocation = symbol->value;
74
75 output_section = symbol->section->output_section;
76
77 if (relocatable)
78 output_base = 0;
79 else
80 output_base = output_section->vma;
81
82 if (!relocatable || !strcmp (symbol->name, symbol->section->name))
83 relocation += output_base + symbol->section->output_offset;
84
85 if (!relocatable && !strcmp (symbol->name, symbol->section->name))
86 relocation += reloc_entry->addend;
87
88 relocation -= input_section->output_section->vma + input_section->output_offset;
89 relocation -= reloc_entry->address;
90
91 if (howto->complain_on_overflow != complain_overflow_dont)
92 {
93 bfd_reloc_status_type status;
94 status = bfd_check_overflow (howto->complain_on_overflow,
95 howto->bitsize,
96 howto->rightshift,
97 bfd_arch_bits_per_address(abfd),
98 relocation);
99 if (status != bfd_reloc_ok)
100 return status;
101 }
102
103 /* if rightshift is 1 and the number odd, return error. */
104 if (howto->rightshift && (relocation & 0x01))
105 {
106 fprintf(stderr, "relocation should be even number\n");
107 return bfd_reloc_overflow;
108 }
109
110 relocation >>= (bfd_vma) howto->rightshift;
111 /* Shift everything up to where it's going to be used. */
112
113 relocation <<= (bfd_vma) howto->bitpos;
114
115 if (relocatable)
116 {
117 reloc_entry->address += input_section->output_offset;
118 reloc_entry->addend += symbol->section->output_offset;
119 }
120
121 {
122 short x;
123
124 /* We are getting reloc_entry->address 2 byte off from
125 the start of instruction. Assuming absolute postion
126 of the reloc data. But, following code had been written assuming
127 reloc address is starting at begining of instruction.
128 To compensate that I have increased the value of
129 relocation by 1 (effectively 2) and used the addr -2 instead of addr. */
130
131 relocation += 1;
132 x = bfd_get_16 (abfd, (bfd_byte *) data + addr - 2);
133 x = (x & 0xff00) | ((relocation >> 16) & 0xff);
134 bfd_put_16 (abfd, x, (unsigned char *) data + addr - 2);
135
136 x = bfd_get_16 (abfd, (bfd_byte *) data + addr);
137 x = relocation & 0xFFFF;
138 bfd_put_16 (abfd, x, (unsigned char *) data + addr );
139 }
140 return bfd_reloc_ok;
141 }
142
143 static bfd_reloc_status_type
144 bfin_imm16_reloc (bfd *abfd,
145 arelent *reloc_entry,
146 asymbol *symbol,
147 PTR data,
148 asection *input_section,
149 bfd *output_bfd,
150 char **error_message ATTRIBUTE_UNUSED)
151 {
152 bfd_vma relocation, x;
153 bfd_size_type reloc_addr = reloc_entry->address;
154 bfd_vma output_base = 0;
155 reloc_howto_type *howto = reloc_entry->howto;
156 asection *output_section;
157 bfd_boolean relocatable = (output_bfd != NULL);
158
159 /* Is the address of the relocation really within the section? */
160 if (reloc_entry->address > bfd_get_section_limit (abfd, input_section))
161 return bfd_reloc_outofrange;
162
163 if (bfd_is_und_section (symbol->section)
164 && (symbol->flags & BSF_WEAK) == 0
165 && !relocatable)
166 return bfd_reloc_undefined;
167
168 output_section = symbol->section->output_section;
169 relocation = symbol->value;
170
171 /* Convert input-section-relative symbol value to absolute. */
172 if (relocatable)
173 output_base = 0;
174 else
175 output_base = output_section->vma;
176
177 if (!relocatable || !strcmp (symbol->name, symbol->section->name))
178 relocation += output_base + symbol->section->output_offset;
179
180 /* Add in supplied addend. */
181 relocation += reloc_entry->addend;
182
183 if (relocatable)
184 {
185 reloc_entry->address += input_section->output_offset;
186 reloc_entry->addend += symbol->section->output_offset;
187 }
188 else
189 {
190 reloc_entry->addend = 0;
191 }
192
193 if (howto->complain_on_overflow != complain_overflow_dont)
194 {
195 bfd_reloc_status_type flag;
196 flag = bfd_check_overflow (howto->complain_on_overflow,
197 howto->bitsize,
198 howto->rightshift,
199 bfd_arch_bits_per_address(abfd),
200 relocation);
201 if (flag != bfd_reloc_ok)
202 return flag;
203 }
204
205 /* Here the variable relocation holds the final address of the
206 symbol we are relocating against, plus any addend. */
207
208 relocation >>= (bfd_vma) howto->rightshift;
209 x = relocation;
210 bfd_put_16 (abfd, x, (unsigned char *) data + reloc_addr);
211 return bfd_reloc_ok;
212 }
213
214
215 static bfd_reloc_status_type
216 bfin_byte4_reloc (bfd *abfd,
217 arelent *reloc_entry,
218 asymbol *symbol,
219 PTR data,
220 asection *input_section,
221 bfd *output_bfd,
222 char **error_message ATTRIBUTE_UNUSED)
223 {
224 bfd_vma relocation, x;
225 bfd_size_type addr = reloc_entry->address;
226 bfd_vma output_base = 0;
227 asection *output_section;
228 bfd_boolean relocatable = (output_bfd != NULL);
229
230 /* Is the address of the relocation really within the section? */
231 if (reloc_entry->address > bfd_get_section_limit (abfd, input_section))
232 return bfd_reloc_outofrange;
233
234 if (bfd_is_und_section (symbol->section)
235 && (symbol->flags & BSF_WEAK) == 0
236 && !relocatable)
237 return bfd_reloc_undefined;
238
239 output_section = symbol->section->output_section;
240 relocation = symbol->value;
241 /* Convert input-section-relative symbol value to absolute. */
242 if (relocatable)
243 output_base = 0;
244 else
245 output_base = output_section->vma;
246
247 if ((symbol->name
248 && symbol->section->name
249 && !strcmp (symbol->name, symbol->section->name))
250 || !relocatable)
251 {
252 relocation += output_base + symbol->section->output_offset;
253 }
254
255 relocation += reloc_entry->addend;
256
257 if (relocatable)
258 {
259 /* This output will be relocatable ... like ld -r. */
260 reloc_entry->address += input_section->output_offset;
261 reloc_entry->addend += symbol->section->output_offset;
262 }
263 else
264 {
265 reloc_entry->addend = 0;
266 }
267
268 /* Here the variable relocation holds the final address of the
269 symbol we are relocating against, plus any addend. */
270 x = relocation & 0xFFFF0000;
271 x >>=16;
272 bfd_put_16 (abfd, x, (unsigned char *) data + addr + 2);
273
274 x = relocation & 0x0000FFFF;
275 bfd_put_16 (abfd, x, (unsigned char *) data + addr);
276 return bfd_reloc_ok;
277 }
278
279 /* bfin_bfd_reloc handles the blackfin arithmetic relocations.
280 Use this instead of bfd_perform_relocation. */
281 static bfd_reloc_status_type
282 bfin_bfd_reloc (bfd *abfd,
283 arelent *reloc_entry,
284 asymbol *symbol,
285 PTR data,
286 asection *input_section,
287 bfd *output_bfd,
288 char **error_message ATTRIBUTE_UNUSED)
289 {
290 bfd_vma relocation;
291 bfd_size_type addr = reloc_entry->address;
292 bfd_vma output_base = 0;
293 reloc_howto_type *howto = reloc_entry->howto;
294 asection *output_section;
295 bfd_boolean relocatable = (output_bfd != NULL);
296
297 /* Is the address of the relocation really within the section? */
298 if (reloc_entry->address > bfd_get_section_limit (abfd, input_section))
299 return bfd_reloc_outofrange;
300
301 if (bfd_is_und_section (symbol->section)
302 && (symbol->flags & BSF_WEAK) == 0
303 && !relocatable)
304 return bfd_reloc_undefined;
305
306 /* Get symbol value. (Common symbols are special.) */
307 if (bfd_is_com_section (symbol->section))
308 relocation = 0;
309 else
310 relocation = symbol->value;
311
312 output_section = symbol->section->output_section;
313
314 /* Convert input-section-relative symbol value to absolute. */
315 if (relocatable)
316 output_base = 0;
317 else
318 output_base = output_section->vma;
319
320 if (!relocatable || !strcmp (symbol->name, symbol->section->name))
321 relocation += output_base + symbol->section->output_offset;
322
323 if (!relocatable && !strcmp (symbol->name, symbol->section->name))
324 {
325 /* Add in supplied addend. */
326 relocation += reloc_entry->addend;
327 }
328
329 /* Here the variable relocation holds the final address of the
330 symbol we are relocating against, plus any addend. */
331
332 if (howto->pc_relative == TRUE)
333 {
334 relocation -= input_section->output_section->vma + input_section->output_offset;
335
336 if (howto->pcrel_offset == TRUE)
337 relocation -= reloc_entry->address;
338 }
339
340 if (relocatable)
341 {
342 reloc_entry->address += input_section->output_offset;
343 reloc_entry->addend += symbol->section->output_offset;
344 }
345
346 if (howto->complain_on_overflow != complain_overflow_dont)
347 {
348 bfd_reloc_status_type status;
349
350 status = bfd_check_overflow (howto->complain_on_overflow,
351 howto->bitsize,
352 howto->rightshift,
353 bfd_arch_bits_per_address(abfd),
354 relocation);
355 if (status != bfd_reloc_ok)
356 return status;
357 }
358
359 /* If rightshift is 1 and the number odd, return error. */
360 if (howto->rightshift && (relocation & 0x01))
361 {
362 fprintf(stderr, "relocation should be even number\n");
363 return bfd_reloc_overflow;
364 }
365
366 relocation >>= (bfd_vma) howto->rightshift;
367
368 /* Shift everything up to where it's going to be used. */
369
370 relocation <<= (bfd_vma) howto->bitpos;
371
372 #define DOIT(x) \
373 x = ( (x & ~howto->dst_mask) | (relocation & howto->dst_mask))
374
375 /* handle 8 and 16 bit relocations here. */
376 switch (howto->size)
377 {
378 case 0:
379 {
380 char x = bfd_get_8 (abfd, (char *) data + addr);
381 DOIT (x);
382 bfd_put_8 (abfd, x, (unsigned char *) data + addr);
383 }
384 break;
385
386 case 1:
387 {
388 unsigned short x = bfd_get_16 (abfd, (bfd_byte *) data + addr);
389 DOIT (x);
390 bfd_put_16 (abfd, (bfd_vma) x, (unsigned char *) data + addr);
391 }
392 break;
393
394 default:
395 return bfd_reloc_other;
396 }
397
398 return bfd_reloc_ok;
399 }
400
401 /* HOWTO Table for blackfin.
402 Blackfin relocations are fairly complicated.
403 Some of the salient features are
404 a. Even numbered offsets. A number of (not all) relocations are
405 even numbered. This means that the rightmost bit is not stored.
406 Needs to right shift by 1 and check to see if value is not odd
407 b. A relocation can be an expression. An expression takes on
408 a variety of relocations arranged in a stack.
409 As a result, we cannot use the standard generic function as special
410 function. We will have our own, which is very similar to the standard
411 generic function except that it understands how to get the value from
412 the relocation stack. . */
413
414 #define BFIN_RELOC_MIN 0
415 #define BFIN_RELOC_MAX 0x21
416 #define BFIN_GNUEXT_RELOC_MIN 0x40
417 #define BFIN_GNUEXT_RELOC_MAX 0x43
418 #define BFIN_ARELOC_MIN 0xE0
419 #define BFIN_ARELOC_MAX 0xF3
420
421 static reloc_howto_type bfin_howto_table [] =
422 {
423 /* This reloc does nothing. . */
424 HOWTO (R_unused0, /* type. */
425 0, /* rightshift. */
426 2, /* size (0 = byte, 1 = short, 2 = long). */
427 32, /* bitsize. */
428 FALSE, /* pc_relative. */
429 0, /* bitpos. */
430 complain_overflow_bitfield, /* complain_on_overflow. */
431 bfd_elf_generic_reloc, /* special_function. */
432 "R_unused0", /* name. */
433 FALSE, /* partial_inplace. */
434 0, /* src_mask. */
435 0, /* dst_mask. */
436 FALSE), /* pcrel_offset. */
437
438 HOWTO (R_pcrel5m2, /* type. */
439 1, /* rightshift. */
440 1, /* size (0 = byte, 1 = short, 2 = long).. */
441 4, /* bitsize. */
442 TRUE, /* pc_relative. */
443 0, /* bitpos. */
444 complain_overflow_unsigned, /* complain_on_overflow. */
445 bfin_bfd_reloc, /* special_function. */
446 "R_pcrel5m2", /* name. */
447 FALSE, /* partial_inplace. */
448 0, /* src_mask. */
449 0x0000000F, /* dst_mask. */
450 FALSE), /* pcrel_offset. */
451
452 HOWTO (R_unused1, /* type. */
453 0, /* rightshift. */
454 2, /* size (0 = byte, 1 = short, 2 = long). */
455 32, /* bitsize. */
456 FALSE, /* pc_relative. */
457 0, /* bitpos. */
458 complain_overflow_bitfield, /* complain_on_overflow. */
459 bfd_elf_generic_reloc, /* special_function. */
460 "R_unused1", /* name. */
461 FALSE, /* partial_inplace. */
462 0, /* src_mask. */
463 0, /* dst_mask. */
464 FALSE), /* pcrel_offset. */
465
466 HOWTO (R_pcrel10, /* type. */
467 1, /* rightshift. */
468 1, /* size (0 = byte, 1 = short, 2 = long). */
469 10, /* bitsize. */
470 TRUE, /* pc_relative. */
471 0, /* bitpos. */
472 complain_overflow_signed, /* complain_on_overflow. */
473 bfin_bfd_reloc, /* special_function. */
474 "R_pcrel10", /* name. */
475 FALSE, /* partial_inplace. */
476 0, /* src_mask. */
477 0x000003FF, /* dst_mask. */
478 TRUE), /* pcrel_offset. */
479
480 HOWTO (R_pcrel12_jump, /* type. */
481 1, /* rightshift. */
482 /* the offset is actually 13 bit
483 aligned on a word boundary so
484 only 12 bits have to be used.
485 Right shift the rightmost bit.. */
486 1, /* size (0 = byte, 1 = short, 2 = long). */
487 12, /* bitsize. */
488 TRUE, /* pc_relative. */
489 0, /* bitpos. */
490 complain_overflow_signed, /* complain_on_overflow. */
491 bfin_bfd_reloc, /* special_function. */
492 "R_pcrel12_jump", /* name. */
493 FALSE, /* partial_inplace. */
494 0, /* src_mask. */
495 0x0FFF, /* dst_mask. */
496 TRUE), /* pcrel_offset. */
497
498 HOWTO (R_rimm16, /* type. */
499 0, /* rightshift. */
500 1, /* size (0 = byte, 1 = short, 2 = long). */
501 16, /* bitsize. */
502 FALSE, /* pc_relative. */
503 0, /* bitpos. */
504 complain_overflow_signed, /* complain_on_overflow. */
505 bfin_imm16_reloc, /* special_function. */
506 "R_rimm16", /* name. */
507 FALSE, /* partial_inplace. */
508 0, /* src_mask. */
509 0x0000FFFF, /* dst_mask. */
510 TRUE), /* pcrel_offset. */
511
512 HOWTO (R_luimm16, /* type. */
513 0, /* rightshift. */
514 1, /* size (0 = byte, 1 = short, 2 = long). */
515 16, /* bitsize. */
516 FALSE, /* pc_relative. */
517 0, /* bitpos. */
518 complain_overflow_dont, /* complain_on_overflow. */
519 bfin_imm16_reloc, /* special_function. */
520 "R_luimm16", /* name. */
521 FALSE, /* partial_inplace. */
522 0, /* src_mask. */
523 0x0000FFFF, /* dst_mask. */
524 TRUE), /* pcrel_offset. */
525
526 HOWTO (R_huimm16, /* type. */
527 16, /* rightshift. */
528 1, /* size (0 = byte, 1 = short, 2 = long). */
529 16, /* bitsize. */
530 FALSE, /* pc_relative. */
531 0, /* bitpos. */
532 complain_overflow_unsigned, /* complain_on_overflow. */
533 bfin_imm16_reloc, /* special_function. */
534 "R_huimm16", /* name. */
535 FALSE, /* partial_inplace. */
536 0, /* src_mask. */
537 0x0000FFFF, /* dst_mask. */
538 TRUE), /* pcrel_offset. */
539
540 HOWTO (R_pcrel12_jump_s, /* type. */
541 1, /* rightshift. */
542 1, /* size (0 = byte, 1 = short, 2 = long). */
543 12, /* bitsize. */
544 TRUE, /* pc_relative. */
545 0, /* bitpos. */
546 complain_overflow_signed, /* complain_on_overflow. */
547 bfin_bfd_reloc, /* special_function. */
548 "R_pcrel12_jump_s", /* name. */
549 FALSE, /* partial_inplace. */
550 0, /* src_mask. */
551 0x00000FFF, /* dst_mask. */
552 TRUE), /* pcrel_offset. */
553
554 HOWTO (R_pcrel24_jump_x, /* type. */
555 1, /* rightshift. */
556 2, /* size (0 = byte, 1 = short, 2 = long). */
557 24, /* bitsize. */
558 TRUE, /* pc_relative. */
559 0, /* bitpos. */
560 complain_overflow_signed, /* complain_on_overflow. */
561 bfin_pcrel24_reloc, /* special_function. */
562 "R_pcrel24_jump_x", /* name. */
563 FALSE, /* partial_inplace. */
564 0, /* src_mask. */
565 0x00FFFFFF, /* dst_mask. */
566 TRUE), /* pcrel_offset. */
567
568 HOWTO (R_pcrel24, /* type. */
569 1, /* rightshift. */
570 2, /* size (0 = byte, 1 = short, 2 = long). */
571 24, /* bitsize. */
572 TRUE, /* pc_relative. */
573 0, /* bitpos. */
574 complain_overflow_signed, /* complain_on_overflow. */
575 bfin_pcrel24_reloc, /* special_function. */
576 "R_pcrel24", /* name. */
577 FALSE, /* partial_inplace. */
578 0, /* src_mask. */
579 0x00FFFFFF, /* dst_mask. */
580 TRUE), /* pcrel_offset. */
581
582 HOWTO (R_unusedb, /* type. */
583 0, /* rightshift. */
584 2, /* size (0 = byte, 1 = short, 2 = long). */
585 32, /* bitsize. */
586 FALSE, /* pc_relative. */
587 0, /* bitpos. */
588 complain_overflow_dont, /* complain_on_overflow. */
589 bfd_elf_generic_reloc, /* special_function. */
590 "R_unusedb", /* name. */
591 FALSE, /* partial_inplace. */
592 0, /* src_mask. */
593 0, /* dst_mask. */
594 FALSE), /* pcrel_offset. */
595
596 HOWTO (R_unusedc, /* type. */
597 0, /* rightshift. */
598 2, /* size (0 = byte, 1 = short, 2 = long). */
599 32, /* bitsize. */
600 FALSE, /* pc_relative. */
601 0, /* bitpos. */
602 complain_overflow_dont, /* complain_on_overflow. */
603 bfd_elf_generic_reloc, /* special_function. */
604 "R_unusedc", /* name. */
605 FALSE, /* partial_inplace. */
606 0, /* src_mask. */
607 0, /* dst_mask. */
608 FALSE), /* pcrel_offset. */
609
610 HOWTO (R_pcrel24_jump_l, /* type. */
611 1, /* rightshift. */
612 2, /* size (0 = byte, 1 = short, 2 = long). */
613 24, /* bitsize. */
614 TRUE, /* pc_relative. */
615 0, /* bitpos. */
616 complain_overflow_signed, /* complain_on_overflow. */
617 bfin_pcrel24_reloc, /* special_function. */
618 "R_pcrel24_jump_l", /* name. */
619 FALSE, /* partial_inplace. */
620 0, /* src_mask. */
621 0x00FFFFFF, /* dst_mask. */
622 TRUE), /* pcrel_offset. */
623
624 HOWTO (R_pcrel24_call_x, /* type. */
625 1, /* rightshift. */
626 2, /* size (0 = byte, 1 = short, 2 = long). */
627 24, /* bitsize. */
628 TRUE, /* pc_relative. */
629 0, /* bitpos. */
630 complain_overflow_signed, /* complain_on_overflow. */
631 bfin_pcrel24_reloc, /* special_function. */
632 "R_pcrel24_call_x", /* name. */
633 FALSE, /* partial_inplace. */
634 0, /* src_mask. */
635 0x00FFFFFF, /* dst_mask. */
636 TRUE), /* pcrel_offset. */
637
638 HOWTO (R_var_eq_symb, /* type. */
639 0, /* rightshift. */
640 2, /* size (0 = byte, 1 = short, 2 = long). */
641 32, /* bitsize. */
642 FALSE, /* pc_relative. */
643 0, /* bitpos. */
644 complain_overflow_bitfield, /* complain_on_overflow. */
645 bfin_bfd_reloc, /* special_function. */
646 "R_var_eq_symb", /* name. */
647 FALSE, /* partial_inplace. */
648 0, /* src_mask. */
649 0, /* dst_mask. */
650 FALSE), /* pcrel_offset. */
651
652 HOWTO (R_byte_data, /* type. */
653 0, /* rightshift. */
654 0, /* size (0 = byte, 1 = short, 2 = long). */
655 8, /* bitsize. */
656 FALSE, /* pc_relative. */
657 0, /* bitpos. */
658 complain_overflow_unsigned, /* complain_on_overflow. */
659 bfin_bfd_reloc, /* special_function. */
660 "R_byte_data", /* name. */
661 FALSE, /* partial_inplace. */
662 0, /* src_mask. */
663 0xFF, /* dst_mask. */
664 TRUE), /* pcrel_offset. */
665
666 HOWTO (R_byte2_data, /* type. */
667 0, /* rightshift. */
668 1, /* size (0 = byte, 1 = short, 2 = long). */
669 16, /* bitsize. */
670 FALSE, /* pc_relative. */
671 0, /* bitpos. */
672 complain_overflow_signed, /* complain_on_overflow. */
673 bfin_bfd_reloc, /* special_function. */
674 "R_byte2_data", /* name. */
675 FALSE, /* partial_inplace. */
676 0, /* src_mask. */
677 0xFFFF, /* dst_mask. */
678 TRUE), /* pcrel_offset. */
679
680 HOWTO (R_byte4_data, /* type. */
681 0, /* rightshift. */
682 2, /* size (0 = byte, 1 = short, 2 = long). */
683 32, /* bitsize. */
684 FALSE, /* pc_relative. */
685 0, /* bitpos. */
686 complain_overflow_unsigned, /* complain_on_overflow. */
687 bfin_byte4_reloc, /* special_function. */
688 "R_byte4_data", /* name. */
689 FALSE, /* partial_inplace. */
690 0, /* src_mask. */
691 0xFFFFFFFF, /* dst_mask. */
692 TRUE), /* pcrel_offset. */
693
694 HOWTO (R_pcrel11, /* type. */
695 1, /* rightshift. */
696 1, /* size (0 = byte, 1 = short, 2 = long). */
697 10, /* bitsize. */
698 TRUE, /* pc_relative. */
699 0, /* bitpos. */
700 complain_overflow_unsigned, /* complain_on_overflow. */
701 bfin_bfd_reloc, /* special_function. */
702 "R_pcrel11", /* name. */
703 FALSE, /* partial_inplace. */
704 0, /* src_mask. */
705 0x000003FF, /* dst_mask. */
706 FALSE), /* pcrel_offset. */
707
708
709 /* A 18-bit signed operand with the GOT offset for the address of
710 the symbol. */
711 HOWTO (R_BFIN_GOT17M4, /* type */
712 2, /* rightshift */
713 1, /* size (0 = byte, 1 = short, 2 = long) */
714 16, /* bitsize */
715 FALSE, /* pc_relative */
716 0, /* bitpos */
717 complain_overflow_signed, /* complain_on_overflow */
718 bfd_elf_generic_reloc, /* special_function */
719 "R_BFIN_GOT17M4", /* name */
720 FALSE, /* partial_inplace */
721 0xffff, /* src_mask */
722 0xffff, /* dst_mask */
723 FALSE), /* pcrel_offset */
724
725 /* The upper 16 bits of the GOT offset for the address of the
726 symbol. */
727 HOWTO (R_BFIN_GOTHI, /* type */
728 0, /* rightshift */
729 1, /* size (0 = byte, 1 = short, 2 = long) */
730 16, /* bitsize */
731 FALSE, /* pc_relative */
732 0, /* bitpos */
733 complain_overflow_dont, /* complain_on_overflow */
734 bfd_elf_generic_reloc, /* special_function */
735 "R_BFIN_GOTHI", /* name */
736 FALSE, /* partial_inplace */
737 0xffff, /* src_mask */
738 0xffff, /* dst_mask */
739 FALSE), /* pcrel_offset */
740
741 /* The lower 16 bits of the GOT offset for the address of the
742 symbol. */
743 HOWTO (R_BFIN_GOTLO, /* type */
744 0, /* rightshift */
745 1, /* size (0 = byte, 1 = short, 2 = long) */
746 16, /* bitsize */
747 FALSE, /* pc_relative */
748 0, /* bitpos */
749 complain_overflow_dont, /* complain_on_overflow */
750 bfd_elf_generic_reloc, /* special_function */
751 "R_BFIN_GOTLO", /* name */
752 FALSE, /* partial_inplace */
753 0xffff, /* src_mask */
754 0xffff, /* dst_mask */
755 FALSE), /* pcrel_offset */
756
757 /* The 32-bit address of the canonical descriptor of a function. */
758 HOWTO (R_BFIN_FUNCDESC, /* type */
759 0, /* rightshift */
760 2, /* size (0 = byte, 1 = short, 2 = long) */
761 32, /* bitsize */
762 FALSE, /* pc_relative */
763 0, /* bitpos */
764 complain_overflow_bitfield, /* complain_on_overflow */
765 bfd_elf_generic_reloc, /* special_function */
766 "R_BFIN_FUNCDESC", /* name */
767 FALSE, /* partial_inplace */
768 0xffffffff, /* src_mask */
769 0xffffffff, /* dst_mask */
770 FALSE), /* pcrel_offset */
771
772 /* A 12-bit signed operand with the GOT offset for the address of
773 canonical descriptor of a function. */
774 HOWTO (R_BFIN_FUNCDESC_GOT17M4, /* type */
775 2, /* rightshift */
776 1, /* size (0 = byte, 1 = short, 2 = long) */
777 16, /* bitsize */
778 FALSE, /* pc_relative */
779 0, /* bitpos */
780 complain_overflow_signed, /* complain_on_overflow */
781 bfd_elf_generic_reloc, /* special_function */
782 "R_BFIN_FUNCDESC_GOT17M4", /* name */
783 FALSE, /* partial_inplace */
784 0xffff, /* src_mask */
785 0xffff, /* dst_mask */
786 FALSE), /* pcrel_offset */
787
788 /* The upper 16 bits of the GOT offset for the address of the
789 canonical descriptor of a function. */
790 HOWTO (R_BFIN_FUNCDESC_GOTHI, /* type */
791 0, /* rightshift */
792 1, /* size (0 = byte, 1 = short, 2 = long) */
793 16, /* bitsize */
794 FALSE, /* pc_relative */
795 0, /* bitpos */
796 complain_overflow_dont, /* complain_on_overflow */
797 bfd_elf_generic_reloc, /* special_function */
798 "R_BFIN_FUNCDESC_GOTHI", /* name */
799 FALSE, /* partial_inplace */
800 0xffff, /* src_mask */
801 0xffff, /* dst_mask */
802 FALSE), /* pcrel_offset */
803
804 /* The lower 16 bits of the GOT offset for the address of the
805 canonical descriptor of a function. */
806 HOWTO (R_BFIN_FUNCDESC_GOTLO, /* type */
807 0, /* rightshift */
808 1, /* size (0 = byte, 1 = short, 2 = long) */
809 16, /* bitsize */
810 FALSE, /* pc_relative */
811 0, /* bitpos */
812 complain_overflow_dont, /* complain_on_overflow */
813 bfd_elf_generic_reloc, /* special_function */
814 "R_BFIN_FUNCDESC_GOTLO", /* name */
815 FALSE, /* partial_inplace */
816 0xffff, /* src_mask */
817 0xffff, /* dst_mask */
818 FALSE), /* pcrel_offset */
819
820 /* The 32-bit address of the canonical descriptor of a function. */
821 HOWTO (R_BFIN_FUNCDESC_VALUE, /* type */
822 0, /* rightshift */
823 2, /* size (0 = byte, 1 = short, 2 = long) */
824 64, /* bitsize */
825 FALSE, /* pc_relative */
826 0, /* bitpos */
827 complain_overflow_bitfield, /* complain_on_overflow */
828 bfd_elf_generic_reloc, /* special_function */
829 "R_BFIN_FUNCDESC_VALUE", /* name */
830 FALSE, /* partial_inplace */
831 0xffffffff, /* src_mask */
832 0xffffffff, /* dst_mask */
833 FALSE), /* pcrel_offset */
834
835 /* A 12-bit signed operand with the GOT offset for the address of
836 canonical descriptor of a function. */
837 HOWTO (R_BFIN_FUNCDESC_GOTOFF17M4, /* type */
838 2, /* rightshift */
839 1, /* size (0 = byte, 1 = short, 2 = long) */
840 16, /* bitsize */
841 FALSE, /* pc_relative */
842 0, /* bitpos */
843 complain_overflow_signed, /* complain_on_overflow */
844 bfd_elf_generic_reloc, /* special_function */
845 "R_BFIN_FUNCDESC_GOTOFF17M4", /* name */
846 FALSE, /* partial_inplace */
847 0xffff, /* src_mask */
848 0xffff, /* dst_mask */
849 FALSE), /* pcrel_offset */
850
851 /* The upper 16 bits of the GOT offset for the address of the
852 canonical descriptor of a function. */
853 HOWTO (R_BFIN_FUNCDESC_GOTOFFHI, /* type */
854 0, /* rightshift */
855 1, /* size (0 = byte, 1 = short, 2 = long) */
856 16, /* bitsize */
857 FALSE, /* pc_relative */
858 0, /* bitpos */
859 complain_overflow_dont, /* complain_on_overflow */
860 bfd_elf_generic_reloc, /* special_function */
861 "R_BFIN_FUNCDESC_GOTOFFHI", /* name */
862 FALSE, /* partial_inplace */
863 0xffff, /* src_mask */
864 0xffff, /* dst_mask */
865 FALSE), /* pcrel_offset */
866
867 /* The lower 16 bits of the GOT offset for the address of the
868 canonical descriptor of a function. */
869 HOWTO (R_BFIN_FUNCDESC_GOTOFFLO, /* type */
870 0, /* rightshift */
871 1, /* size (0 = byte, 1 = short, 2 = long) */
872 16, /* bitsize */
873 FALSE, /* pc_relative */
874 0, /* bitpos */
875 complain_overflow_dont, /* complain_on_overflow */
876 bfd_elf_generic_reloc, /* special_function */
877 "R_BFIN_FUNCDESC_GOTOFFLO", /* name */
878 FALSE, /* partial_inplace */
879 0xffff, /* src_mask */
880 0xffff, /* dst_mask */
881 FALSE), /* pcrel_offset */
882
883 /* A 12-bit signed operand with the GOT offset for the address of
884 the symbol. */
885 HOWTO (R_BFIN_GOTOFF17M4, /* type */
886 2, /* rightshift */
887 1, /* size (0 = byte, 1 = short, 2 = long) */
888 16, /* bitsize */
889 FALSE, /* pc_relative */
890 0, /* bitpos */
891 complain_overflow_signed, /* complain_on_overflow */
892 bfd_elf_generic_reloc, /* special_function */
893 "R_BFIN_GOTOFF17M4", /* name */
894 FALSE, /* partial_inplace */
895 0xffff, /* src_mask */
896 0xffff, /* dst_mask */
897 FALSE), /* pcrel_offset */
898
899 /* The upper 16 bits of the GOT offset for the address of the
900 symbol. */
901 HOWTO (R_BFIN_GOTOFFHI, /* type */
902 0, /* rightshift */
903 1, /* size (0 = byte, 1 = short, 2 = long) */
904 16, /* bitsize */
905 FALSE, /* pc_relative */
906 0, /* bitpos */
907 complain_overflow_dont, /* complain_on_overflow */
908 bfd_elf_generic_reloc, /* special_function */
909 "R_BFIN_GOTOFFHI", /* name */
910 FALSE, /* partial_inplace */
911 0xffff, /* src_mask */
912 0xffff, /* dst_mask */
913 FALSE), /* pcrel_offset */
914
915 /* The lower 16 bits of the GOT offset for the address of the
916 symbol. */
917 HOWTO (R_BFIN_GOTOFFLO, /* type */
918 0, /* rightshift */
919 1, /* size (0 = byte, 1 = short, 2 = long) */
920 16, /* bitsize */
921 FALSE, /* pc_relative */
922 0, /* bitpos */
923 complain_overflow_dont, /* complain_on_overflow */
924 bfd_elf_generic_reloc, /* special_function */
925 "R_BFIN_GOTOFFLO", /* name */
926 FALSE, /* partial_inplace */
927 0xffff, /* src_mask */
928 0xffff, /* dst_mask */
929 FALSE), /* pcrel_offset */
930 };
931
932 static reloc_howto_type bfin_gnuext_howto_table [] =
933 {
934 HOWTO (R_pltpc, /* type. */
935 0, /* rightshift. */
936 1, /* size (0 = byte, 1 = short, 2 = long). */
937 16, /* bitsize. */
938 FALSE, /* pc_relative. */
939 0, /* bitpos. */
940 complain_overflow_bitfield, /* complain_on_overflow. */
941 bfin_pltpc_reloc, /* special_function. */
942 "R_pltpc", /* name. */
943 FALSE, /* partial_inplace. */
944 0xffff, /* src_mask. */
945 0xffff, /* dst_mask. */
946 FALSE), /* pcrel_offset. */
947
948 HOWTO (R_got, /* type. */
949 0, /* rightshift. */
950 1, /* size (0 = byte, 1 = short, 2 = long). */
951 16, /* bitsize. */
952 FALSE, /* pc_relative. */
953 0, /* bitpos. */
954 complain_overflow_bitfield, /* complain_on_overflow. */
955 bfd_elf_generic_reloc, /* special_function. */
956 "R_got", /* name. */
957 FALSE, /* partial_inplace. */
958 0x7fff, /* src_mask. */
959 0x7fff, /* dst_mask. */
960 FALSE), /* pcrel_offset. */
961
962 /* GNU extension to record C++ vtable hierarchy. */
963 HOWTO (R_BFIN_GNU_VTINHERIT, /* type. */
964 0, /* rightshift. */
965 2, /* size (0 = byte, 1 = short, 2 = long). */
966 0, /* bitsize. */
967 FALSE, /* pc_relative. */
968 0, /* bitpos. */
969 complain_overflow_dont, /* complain_on_overflow. */
970 NULL, /* special_function. */
971 "R_BFIN_GNU_VTINHERIT", /* name. */
972 FALSE, /* partial_inplace. */
973 0, /* src_mask. */
974 0, /* dst_mask. */
975 FALSE), /* pcrel_offset. */
976
977 /* GNU extension to record C++ vtable member usage. */
978 HOWTO (R_BFIN_GNU_VTENTRY, /* type. */
979 0, /* rightshift. */
980 2, /* size (0 = byte, 1 = short, 2 = long). */
981 0, /* bitsize. */
982 FALSE, /* pc_relative. */
983 0, /* bitpos. */
984 complain_overflow_dont, /* complain_on_overflow. */
985 _bfd_elf_rel_vtable_reloc_fn, /* special_function. */
986 "R_BFIN_GNU_VTENTRY", /* name. */
987 FALSE, /* partial_inplace. */
988 0, /* src_mask. */
989 0, /* dst_mask. */
990 FALSE) /* pcrel_offset. */
991 };
992
993 struct bfin_reloc_map
994 {
995 bfd_reloc_code_real_type bfd_reloc_val;
996 unsigned int bfin_reloc_val;
997 };
998
999 static const struct bfin_reloc_map bfin_reloc_map [] =
1000 {
1001 { BFD_RELOC_NONE, R_unused0 },
1002 { BFD_RELOC_BFIN_5_PCREL, R_pcrel5m2 },
1003 { BFD_RELOC_NONE, R_unused1 },
1004 { BFD_RELOC_BFIN_10_PCREL, R_pcrel10 },
1005 { BFD_RELOC_BFIN_12_PCREL_JUMP, R_pcrel12_jump },
1006 { BFD_RELOC_BFIN_16_IMM, R_rimm16 },
1007 { BFD_RELOC_BFIN_16_LOW, R_luimm16 },
1008 { BFD_RELOC_BFIN_16_HIGH, R_huimm16 },
1009 { BFD_RELOC_BFIN_12_PCREL_JUMP_S, R_pcrel12_jump_s },
1010 { BFD_RELOC_24_PCREL, R_pcrel24 },
1011 { BFD_RELOC_24_PCREL, R_pcrel24 },
1012 { BFD_RELOC_BFIN_24_PCREL_JUMP_L, R_pcrel24_jump_l },
1013 { BFD_RELOC_NONE, R_unusedb },
1014 { BFD_RELOC_NONE, R_unusedc },
1015 { BFD_RELOC_BFIN_24_PCREL_CALL_X, R_pcrel24_call_x },
1016 { BFD_RELOC_8, R_byte_data },
1017 { BFD_RELOC_16, R_byte2_data },
1018 { BFD_RELOC_32, R_byte4_data },
1019 { BFD_RELOC_BFIN_11_PCREL, R_pcrel11 },
1020 { BFD_RELOC_BFIN_GOT, R_got },
1021 { BFD_RELOC_BFIN_PLTPC, R_pltpc },
1022
1023 { BFD_RELOC_BFIN_GOT17M4, R_BFIN_GOT17M4 },
1024 { BFD_RELOC_BFIN_GOTHI, R_BFIN_GOTHI },
1025 { BFD_RELOC_BFIN_GOTLO, R_BFIN_GOTLO },
1026 { BFD_RELOC_BFIN_FUNCDESC, R_BFIN_FUNCDESC },
1027 { BFD_RELOC_BFIN_FUNCDESC_GOT17M4, R_BFIN_FUNCDESC_GOT17M4 },
1028 { BFD_RELOC_BFIN_FUNCDESC_GOTHI, R_BFIN_FUNCDESC_GOTHI },
1029 { BFD_RELOC_BFIN_FUNCDESC_GOTLO, R_BFIN_FUNCDESC_GOTLO },
1030 { BFD_RELOC_BFIN_FUNCDESC_VALUE, R_BFIN_FUNCDESC_VALUE },
1031 { BFD_RELOC_BFIN_FUNCDESC_GOTOFF17M4, R_BFIN_FUNCDESC_GOTOFF17M4 },
1032 { BFD_RELOC_BFIN_FUNCDESC_GOTOFFHI, R_BFIN_FUNCDESC_GOTOFFHI },
1033 { BFD_RELOC_BFIN_FUNCDESC_GOTOFFLO, R_BFIN_FUNCDESC_GOTOFFLO },
1034 { BFD_RELOC_BFIN_GOTOFF17M4, R_BFIN_GOTOFF17M4 },
1035 { BFD_RELOC_BFIN_GOTOFFHI, R_BFIN_GOTOFFHI },
1036 { BFD_RELOC_BFIN_GOTOFFLO, R_BFIN_GOTOFFLO },
1037
1038 { BFD_RELOC_VTABLE_INHERIT, R_BFIN_GNU_VTINHERIT },
1039 { BFD_RELOC_VTABLE_ENTRY, R_BFIN_GNU_VTENTRY },
1040 };
1041
1042
1043 static void
1044 bfin_info_to_howto (bfd *abfd ATTRIBUTE_UNUSED,
1045 arelent *cache_ptr,
1046 Elf_Internal_Rela *dst)
1047 {
1048 unsigned int r_type;
1049
1050 r_type = ELF32_R_TYPE (dst->r_info);
1051
1052 if (r_type <= BFIN_RELOC_MAX)
1053 cache_ptr->howto = &bfin_howto_table [r_type];
1054
1055 else if (r_type >= BFIN_GNUEXT_RELOC_MIN && r_type <= BFIN_GNUEXT_RELOC_MAX)
1056 cache_ptr->howto = &bfin_gnuext_howto_table [r_type - BFIN_GNUEXT_RELOC_MIN];
1057
1058 else
1059 cache_ptr->howto = (reloc_howto_type *) NULL;
1060 }
1061
1062 /* Given a BFD reloc type, return the howto. */
1063 static reloc_howto_type *
1064 bfin_bfd_reloc_type_lookup (bfd * abfd ATTRIBUTE_UNUSED,
1065 bfd_reloc_code_real_type code)
1066 {
1067 unsigned int i;
1068 unsigned int r_type = BFIN_RELOC_MIN;
1069
1070 for (i = sizeof (bfin_reloc_map) / sizeof (bfin_reloc_map[0]); --i;)
1071 if (bfin_reloc_map[i].bfd_reloc_val == code)
1072 r_type = bfin_reloc_map[i].bfin_reloc_val;
1073
1074 if (r_type <= BFIN_RELOC_MAX && r_type > BFIN_RELOC_MIN)
1075 return &bfin_howto_table [r_type];
1076
1077 else if (r_type >= BFIN_GNUEXT_RELOC_MIN && r_type <= BFIN_GNUEXT_RELOC_MAX)
1078 return &bfin_gnuext_howto_table [r_type - BFIN_GNUEXT_RELOC_MIN];
1079
1080 return (reloc_howto_type *) NULL;
1081 }
1082
1083 static reloc_howto_type *
1084 bfin_bfd_reloc_name_lookup (bfd *abfd ATTRIBUTE_UNUSED,
1085 const char *r_name)
1086 {
1087 unsigned int i;
1088
1089 for (i = 0;
1090 i < (sizeof (bfin_howto_table)
1091 / sizeof (bfin_howto_table[0]));
1092 i++)
1093 if (bfin_howto_table[i].name != NULL
1094 && strcasecmp (bfin_howto_table[i].name, r_name) == 0)
1095 return &bfin_howto_table[i];
1096
1097 for (i = 0;
1098 i < (sizeof (bfin_gnuext_howto_table)
1099 / sizeof (bfin_gnuext_howto_table[0]));
1100 i++)
1101 if (bfin_gnuext_howto_table[i].name != NULL
1102 && strcasecmp (bfin_gnuext_howto_table[i].name, r_name) == 0)
1103 return &bfin_gnuext_howto_table[i];
1104
1105 return NULL;
1106 }
1107
1108 /* Given a bfin relocation type, return the howto. */
1109 static reloc_howto_type *
1110 bfin_reloc_type_lookup (bfd * abfd ATTRIBUTE_UNUSED,
1111 unsigned int r_type)
1112 {
1113 if (r_type <= BFIN_RELOC_MAX)
1114 return &bfin_howto_table [r_type];
1115
1116 else if (r_type >= BFIN_GNUEXT_RELOC_MIN && r_type <= BFIN_GNUEXT_RELOC_MAX)
1117 return &bfin_gnuext_howto_table [r_type - BFIN_GNUEXT_RELOC_MIN];
1118
1119 return (reloc_howto_type *) NULL;
1120 }
1121
1122 /* Return TRUE if the name is a local label.
1123 bfin local labels begin with L$. */
1124 static bfd_boolean
1125 bfin_is_local_label_name (
1126 bfd *abfd,
1127 const char *label)
1128 {
1129 if (label[0] == 'L' && label[1] == '$' )
1130 return TRUE;
1131
1132 return _bfd_elf_is_local_label_name (abfd, label);
1133 }
1134
1135 /* Look through the relocs for a section during the first phase, and
1136 allocate space in the global offset table or procedure linkage
1137 table. */
1138
1139 static bfd_boolean
1140 bfin_check_relocs (bfd * abfd,
1141 struct bfd_link_info *info,
1142 asection *sec,
1143 const Elf_Internal_Rela *relocs)
1144 {
1145 bfd *dynobj;
1146 Elf_Internal_Shdr *symtab_hdr;
1147 struct elf_link_hash_entry **sym_hashes;
1148 bfd_signed_vma *local_got_refcounts;
1149 const Elf_Internal_Rela *rel;
1150 const Elf_Internal_Rela *rel_end;
1151 asection *sgot;
1152 asection *srelgot;
1153 if (info->relocatable)
1154 return TRUE;
1155
1156 dynobj = elf_hash_table (info)->dynobj;
1157 symtab_hdr = &elf_tdata (abfd)->symtab_hdr;
1158 sym_hashes = elf_sym_hashes (abfd);
1159 local_got_refcounts = elf_local_got_refcounts (abfd);
1160
1161 sgot = NULL;
1162 srelgot = NULL;
1163
1164 rel_end = relocs + sec->reloc_count;
1165 for (rel = relocs; rel < rel_end; rel++)
1166 {
1167 unsigned long r_symndx;
1168 struct elf_link_hash_entry *h;
1169
1170 r_symndx = ELF32_R_SYM (rel->r_info);
1171 if (r_symndx < symtab_hdr->sh_info)
1172 h = NULL;
1173 else
1174 h = sym_hashes[r_symndx - symtab_hdr->sh_info];
1175
1176 switch (ELF32_R_TYPE (rel->r_info))
1177 {
1178 /* This relocation describes the C++ object vtable hierarchy.
1179 Reconstruct it for later use during GC. */
1180 case R_BFIN_GNU_VTINHERIT:
1181 if (!bfd_elf_gc_record_vtinherit (abfd, sec, h, rel->r_offset))
1182 return FALSE;
1183 break;
1184
1185 /* This relocation describes which C++ vtable entries
1186 are actually used. Record for later use during GC. */
1187 case R_BFIN_GNU_VTENTRY:
1188 BFD_ASSERT (h != NULL);
1189 if (h != NULL
1190 && !bfd_elf_gc_record_vtentry (abfd, sec, h, rel->r_addend))
1191 return FALSE;
1192 break;
1193
1194 case R_got:
1195 if (h != NULL
1196 && strcmp (h->root.root.string, "__GLOBAL_OFFSET_TABLE_") == 0)
1197 break;
1198 /* Fall through. */
1199
1200 if (dynobj == NULL)
1201 {
1202 /* Create the .got section. */
1203 elf_hash_table (info)->dynobj = dynobj = abfd;
1204 if (!_bfd_elf_create_got_section (dynobj, info))
1205 return FALSE;
1206 }
1207
1208 if (sgot == NULL)
1209 {
1210 sgot = bfd_get_section_by_name (dynobj, ".got");
1211 BFD_ASSERT (sgot != NULL);
1212 }
1213
1214 if (srelgot == NULL && (h != NULL || info->shared))
1215 {
1216 srelgot = bfd_get_section_by_name (dynobj, ".rela.got");
1217 if (srelgot == NULL)
1218 {
1219 flagword flags = (SEC_ALLOC | SEC_LOAD | SEC_HAS_CONTENTS
1220 | SEC_IN_MEMORY | SEC_LINKER_CREATED
1221 | SEC_READONLY);
1222 srelgot = bfd_make_section_with_flags (dynobj, ".rela.got",
1223 flags);
1224 if (srelgot == NULL
1225 || !bfd_set_section_alignment (dynobj, srelgot, 2))
1226 return FALSE;
1227 }
1228 }
1229
1230 if (h != NULL)
1231 {
1232 if (h->got.refcount == 0)
1233 {
1234 /* Make sure this symbol is output as a dynamic symbol. */
1235 if (h->dynindx == -1 && !h->forced_local)
1236 {
1237 if (!bfd_elf_link_record_dynamic_symbol (info, h))
1238 return FALSE;
1239 }
1240
1241 /* Allocate space in the .got section. */
1242 sgot->size += 4;
1243 /* Allocate relocation space. */
1244 srelgot->size += sizeof (Elf32_External_Rela);
1245 }
1246 h->got.refcount++;
1247 }
1248 else
1249 {
1250 /* This is a global offset table entry for a local symbol. */
1251 if (local_got_refcounts == NULL)
1252 {
1253 bfd_size_type size;
1254
1255 size = symtab_hdr->sh_info;
1256 size *= sizeof (bfd_signed_vma);
1257 local_got_refcounts = ((bfd_signed_vma *)
1258 bfd_zalloc (abfd, size));
1259 if (local_got_refcounts == NULL)
1260 return FALSE;
1261 elf_local_got_refcounts (abfd) = local_got_refcounts;
1262 }
1263 if (local_got_refcounts[r_symndx] == 0)
1264 {
1265 sgot->size += 4;
1266 if (info->shared)
1267 {
1268 /* If we are generating a shared object, we need to
1269 output a R_68K_RELATIVE reloc so that the dynamic
1270 linker can adjust this GOT entry. */
1271 srelgot->size += sizeof (Elf32_External_Rela);
1272 }
1273 }
1274 local_got_refcounts[r_symndx]++;
1275 }
1276 break;
1277
1278 default:
1279 break;
1280 }
1281 }
1282
1283 return TRUE;
1284 }
1285
1286 static enum elf_reloc_type_class
1287 elf32_bfin_reloc_type_class (const Elf_Internal_Rela * rela)
1288 {
1289 switch ((int) ELF32_R_TYPE (rela->r_info))
1290 {
1291 default:
1292 return reloc_class_normal;
1293 }
1294 }
1295
1296 static bfd_reloc_status_type
1297 bfin_final_link_relocate (Elf_Internal_Rela *rel, reloc_howto_type *howto,
1298 bfd *input_bfd, asection *input_section,
1299 bfd_byte *contents, bfd_vma address,
1300 bfd_vma value, bfd_vma addend)
1301 {
1302 int r_type = ELF32_R_TYPE (rel->r_info);
1303
1304 if (r_type == R_pcrel24 || r_type == R_pcrel24_jump_l)
1305 {
1306 bfd_reloc_status_type r = bfd_reloc_ok;
1307 bfd_vma x;
1308
1309 if (address > bfd_get_section_limit (input_bfd, input_section))
1310 return bfd_reloc_outofrange;
1311
1312 value += addend;
1313
1314 /* Perform usual pc-relative correction. */
1315 value -= input_section->output_section->vma + input_section->output_offset;
1316 value -= address;
1317
1318 /* We are getting reloc_entry->address 2 byte off from
1319 the start of instruction. Assuming absolute postion
1320 of the reloc data. But, following code had been written assuming
1321 reloc address is starting at begining of instruction.
1322 To compensate that I have increased the value of
1323 relocation by 1 (effectively 2) and used the addr -2 instead of addr. */
1324
1325 value += 2;
1326 address -= 2;
1327
1328 if ((value & 0xFF000000) != 0
1329 && (value & 0xFF000000) != 0xFF000000)
1330 r = bfd_reloc_overflow;
1331
1332 value >>= 1;
1333
1334 x = bfd_get_16 (input_bfd, contents + address);
1335 x = (x & 0xff00) | ((value >> 16) & 0xff);
1336 bfd_put_16 (input_bfd, x, contents + address);
1337
1338 x = bfd_get_16 (input_bfd, contents + address + 2);
1339 x = value & 0xFFFF;
1340 bfd_put_16 (input_bfd, x, contents + address + 2);
1341 return r;
1342 }
1343
1344 return _bfd_final_link_relocate (howto, input_bfd, input_section, contents,
1345 rel->r_offset, value, addend);
1346
1347 }
1348
1349 static bfd_boolean
1350 bfin_relocate_section (bfd * output_bfd,
1351 struct bfd_link_info *info,
1352 bfd * input_bfd,
1353 asection * input_section,
1354 bfd_byte * contents,
1355 Elf_Internal_Rela * relocs,
1356 Elf_Internal_Sym * local_syms,
1357 asection ** local_sections)
1358 {
1359 bfd *dynobj;
1360 Elf_Internal_Shdr *symtab_hdr;
1361 struct elf_link_hash_entry **sym_hashes;
1362 bfd_vma *local_got_offsets;
1363 asection *sgot;
1364 Elf_Internal_Rela *rel;
1365 Elf_Internal_Rela *relend;
1366 int i = 0;
1367
1368 dynobj = elf_hash_table (info)->dynobj;
1369 symtab_hdr = &elf_tdata (input_bfd)->symtab_hdr;
1370 sym_hashes = elf_sym_hashes (input_bfd);
1371 local_got_offsets = elf_local_got_offsets (input_bfd);
1372
1373 sgot = NULL;
1374
1375 rel = relocs;
1376 relend = relocs + input_section->reloc_count;
1377 for (; rel < relend; rel++, i++)
1378 {
1379 int r_type;
1380 reloc_howto_type *howto;
1381 unsigned long r_symndx;
1382 struct elf_link_hash_entry *h;
1383 Elf_Internal_Sym *sym;
1384 asection *sec;
1385 bfd_vma relocation = 0;
1386 bfd_boolean unresolved_reloc;
1387 bfd_reloc_status_type r;
1388 bfd_vma address;
1389
1390 r_type = ELF32_R_TYPE (rel->r_info);
1391 if (r_type < 0 || r_type >= 243)
1392 {
1393 bfd_set_error (bfd_error_bad_value);
1394 return FALSE;
1395 }
1396
1397 if (r_type == R_BFIN_GNU_VTENTRY
1398 || r_type == R_BFIN_GNU_VTINHERIT)
1399 continue;
1400
1401 howto = bfin_reloc_type_lookup (input_bfd, r_type);
1402 if (howto == NULL)
1403 {
1404 bfd_set_error (bfd_error_bad_value);
1405 return FALSE;
1406 }
1407 r_symndx = ELF32_R_SYM (rel->r_info);
1408
1409 h = NULL;
1410 sym = NULL;
1411 sec = NULL;
1412 unresolved_reloc = FALSE;
1413
1414 if (r_symndx < symtab_hdr->sh_info)
1415 {
1416 sym = local_syms + r_symndx;
1417 sec = local_sections[r_symndx];
1418 relocation = _bfd_elf_rela_local_sym (output_bfd, sym, &sec, rel);
1419 }
1420 else
1421 {
1422 bfd_boolean warned;
1423
1424 RELOC_FOR_GLOBAL_SYMBOL (info, input_bfd, input_section, rel,
1425 r_symndx, symtab_hdr, sym_hashes,
1426 h, sec, relocation,
1427 unresolved_reloc, warned);
1428 }
1429
1430 if (sec != NULL && elf_discarded_section (sec))
1431 {
1432 /* For relocs against symbols from removed linkonce sections,
1433 or sections discarded by a linker script, we just want the
1434 section contents zeroed. Avoid any special processing. */
1435 _bfd_clear_contents (howto, input_bfd, contents + rel->r_offset);
1436 rel->r_info = 0;
1437 rel->r_addend = 0;
1438 continue;
1439 }
1440
1441 if (info->relocatable)
1442 continue;
1443
1444 address = rel->r_offset;
1445
1446 /* Then, process normally. */
1447 switch (r_type)
1448 {
1449 case R_BFIN_GNU_VTINHERIT:
1450 case R_BFIN_GNU_VTENTRY:
1451 return bfd_reloc_ok;
1452
1453 case R_got:
1454 /* Relocation is to the address of the entry for this symbol
1455 in the global offset table. */
1456 if (h != NULL
1457 && strcmp (h->root.root.string, "__GLOBAL_OFFSET_TABLE_") == 0)
1458 goto do_default;
1459 /* Fall through. */
1460 /* Relocation is the offset of the entry for this symbol in
1461 the global offset table. */
1462
1463 {
1464 bfd_vma off;
1465
1466 if (dynobj == NULL)
1467 {
1468 /* Create the .got section. */
1469 elf_hash_table (info)->dynobj = dynobj = output_bfd;
1470 if (!_bfd_elf_create_got_section (dynobj, info))
1471 return FALSE;
1472 }
1473
1474 if (sgot == NULL)
1475 {
1476 sgot = bfd_get_section_by_name (dynobj, ".got");
1477 BFD_ASSERT (sgot != NULL);
1478 }
1479
1480 if (h != NULL)
1481 {
1482 bfd_boolean dyn;
1483
1484 off = h->got.offset;
1485 BFD_ASSERT (off != (bfd_vma) - 1);
1486 dyn = elf_hash_table (info)->dynamic_sections_created;
1487
1488 if (!WILL_CALL_FINISH_DYNAMIC_SYMBOL (dyn, info->shared, h)
1489 || (info->shared
1490 && (info->symbolic
1491 || h->dynindx == -1
1492 || h->forced_local)
1493 && h->def_regular))
1494 {
1495 /* This is actually a static link, or it is a
1496 -Bsymbolic link and the symbol is defined
1497 locally, or the symbol was forced to be local
1498 because of a version file.. We must initialize
1499 this entry in the global offset table. Since
1500 the offset must always be a multiple of 4, we
1501 use the least significant bit to record whether
1502 we have initialized it already.
1503
1504 When doing a dynamic link, we create a .rela.got
1505 relocation entry to initialize the value. This
1506 is done in the finish_dynamic_symbol routine. */
1507 if ((off & 1) != 0)
1508 off &= ~1;
1509 else
1510 {
1511 bfd_put_32 (output_bfd, relocation,
1512 sgot->contents + off);
1513 h->got.offset |= 1;
1514 }
1515 }
1516 else
1517 unresolved_reloc = FALSE;
1518 }
1519 else
1520 {
1521 BFD_ASSERT (local_got_offsets != NULL);
1522 off = local_got_offsets[r_symndx];
1523 BFD_ASSERT (off != (bfd_vma) - 1);
1524
1525 /* The offset must always be a multiple of 4. We use
1526 the least significant bit to record whether we have
1527 already generated the necessary reloc. */
1528 if ((off & 1) != 0)
1529 off &= ~1;
1530 else
1531 {
1532 bfd_put_32 (output_bfd, relocation, sgot->contents + off);
1533
1534 if (info->shared)
1535 {
1536 asection *s;
1537 Elf_Internal_Rela outrel;
1538 bfd_byte *loc;
1539
1540 s = bfd_get_section_by_name (dynobj, ".rela.got");
1541 BFD_ASSERT (s != NULL);
1542
1543 outrel.r_offset = (sgot->output_section->vma
1544 + sgot->output_offset + off);
1545 outrel.r_info =
1546 ELF32_R_INFO (0, R_pcrel24);
1547 outrel.r_addend = relocation;
1548 loc = s->contents;
1549 loc +=
1550 s->reloc_count++ * sizeof (Elf32_External_Rela);
1551 bfd_elf32_swap_reloca_out (output_bfd, &outrel, loc);
1552 }
1553
1554 local_got_offsets[r_symndx] |= 1;
1555 }
1556 }
1557
1558 relocation = sgot->output_offset + off;
1559 rel->r_addend = 0;
1560 /* bfin : preg = [preg + 17bitdiv4offset] relocation is div by 4. */
1561 relocation /= 4;
1562 }
1563 goto do_default;
1564
1565 default:
1566 do_default:
1567 r = bfin_final_link_relocate (rel, howto, input_bfd, input_section,
1568 contents, address,
1569 relocation, rel->r_addend);
1570
1571 break;
1572 }
1573
1574 /* Dynamic relocs are not propagated for SEC_DEBUGGING sections
1575 because such sections are not SEC_ALLOC and thus ld.so will
1576 not process them. */
1577 if (unresolved_reloc
1578 && !((input_section->flags & SEC_DEBUGGING) != 0 && h->def_dynamic))
1579 {
1580 (*_bfd_error_handler)
1581 (_("%B(%A+0x%lx): unresolvable relocation against symbol `%s'"),
1582 input_bfd,
1583 input_section, (long) rel->r_offset, h->root.root.string);
1584 return FALSE;
1585 }
1586
1587 if (r != bfd_reloc_ok)
1588 {
1589 const char *name;
1590
1591 if (h != NULL)
1592 name = h->root.root.string;
1593 else
1594 {
1595 name = bfd_elf_string_from_elf_section (input_bfd,
1596 symtab_hdr->sh_link,
1597 sym->st_name);
1598 if (name == NULL)
1599 return FALSE;
1600 if (*name == '\0')
1601 name = bfd_section_name (input_bfd, sec);
1602 }
1603
1604 if (r == bfd_reloc_overflow)
1605 {
1606 if (!(info->callbacks->reloc_overflow
1607 (info, (h ? &h->root : NULL), name, howto->name,
1608 (bfd_vma) 0, input_bfd, input_section, rel->r_offset)))
1609 return FALSE;
1610 }
1611 else
1612 {
1613 (*_bfd_error_handler)
1614 (_("%B(%A+0x%lx): reloc against `%s': error %d"),
1615 input_bfd, input_section,
1616 (long) rel->r_offset, name, (int) r);
1617 return FALSE;
1618 }
1619 }
1620 }
1621
1622 return TRUE;
1623 }
1624
1625 static asection *
1626 bfin_gc_mark_hook (asection * sec,
1627 struct bfd_link_info *info,
1628 Elf_Internal_Rela * rel,
1629 struct elf_link_hash_entry *h,
1630 Elf_Internal_Sym * sym)
1631 {
1632 if (h != NULL)
1633 switch (ELF32_R_TYPE (rel->r_info))
1634 {
1635 case R_BFIN_GNU_VTINHERIT:
1636 case R_BFIN_GNU_VTENTRY:
1637 return NULL;
1638 }
1639
1640 return _bfd_elf_gc_mark_hook (sec, info, rel, h, sym);
1641 }
1642
1643 /* Update the got entry reference counts for the section being removed. */
1644
1645 static bfd_boolean
1646 bfin_gc_sweep_hook (bfd * abfd,
1647 struct bfd_link_info *info,
1648 asection * sec,
1649 const Elf_Internal_Rela * relocs)
1650 {
1651 Elf_Internal_Shdr *symtab_hdr;
1652 struct elf_link_hash_entry **sym_hashes;
1653 bfd_signed_vma *local_got_refcounts;
1654 const Elf_Internal_Rela *rel, *relend;
1655 bfd *dynobj;
1656 asection *sgot;
1657 asection *srelgot;
1658
1659 dynobj = elf_hash_table (info)->dynobj;
1660 if (dynobj == NULL)
1661 return TRUE;
1662
1663 symtab_hdr = &elf_tdata (abfd)->symtab_hdr;
1664 sym_hashes = elf_sym_hashes (abfd);
1665 local_got_refcounts = elf_local_got_refcounts (abfd);
1666
1667 sgot = bfd_get_section_by_name (dynobj, ".got");
1668 srelgot = bfd_get_section_by_name (dynobj, ".rela.got");
1669
1670 relend = relocs + sec->reloc_count;
1671 for (rel = relocs; rel < relend; rel++)
1672 {
1673 unsigned long r_symndx;
1674 struct elf_link_hash_entry *h;
1675
1676 switch (ELF32_R_TYPE (rel->r_info))
1677 {
1678 case R_got:
1679 r_symndx = ELF32_R_SYM (rel->r_info);
1680 if (r_symndx >= symtab_hdr->sh_info)
1681 {
1682 h = sym_hashes[r_symndx - symtab_hdr->sh_info];
1683 if (h->got.refcount > 0)
1684 {
1685 --h->got.refcount;
1686 if (h->got.refcount == 0)
1687 {
1688 /* We don't need the .got entry any more. */
1689 sgot->size -= 4;
1690 srelgot->size -= sizeof (Elf32_External_Rela);
1691 }
1692 }
1693 }
1694 else if (local_got_refcounts != NULL)
1695 {
1696 if (local_got_refcounts[r_symndx] > 0)
1697 {
1698 --local_got_refcounts[r_symndx];
1699 if (local_got_refcounts[r_symndx] == 0)
1700 {
1701 /* We don't need the .got entry any more. */
1702 sgot->size -= 4;
1703 if (info->shared)
1704 srelgot->size -= sizeof (Elf32_External_Rela);
1705 }
1706 }
1707 }
1708 break;
1709 default:
1710 break;
1711 }
1712 }
1713 return TRUE;
1714 }
1715
1716 extern const bfd_target bfd_elf32_bfinfdpic_vec;
1717 #define IS_FDPIC(bfd) ((bfd)->xvec == &bfd_elf32_bfinfdpic_vec)
1718
1719 /* An extension of the elf hash table data structure, containing some
1720 additional Blackfin-specific data. */
1721 struct bfinfdpic_elf_link_hash_table
1722 {
1723 struct elf_link_hash_table elf;
1724
1725 /* A pointer to the .got section. */
1726 asection *sgot;
1727 /* A pointer to the .rel.got section. */
1728 asection *sgotrel;
1729 /* A pointer to the .rofixup section. */
1730 asection *sgotfixup;
1731 /* A pointer to the .plt section. */
1732 asection *splt;
1733 /* A pointer to the .rel.plt section. */
1734 asection *spltrel;
1735 /* GOT base offset. */
1736 bfd_vma got0;
1737 /* Location of the first non-lazy PLT entry, i.e., the number of
1738 bytes taken by lazy PLT entries. */
1739 bfd_vma plt0;
1740 /* A hash table holding information about which symbols were
1741 referenced with which PIC-related relocations. */
1742 struct htab *relocs_info;
1743 };
1744
1745 /* Get the Blackfin ELF linker hash table from a link_info structure. */
1746
1747 #define bfinfdpic_hash_table(info) \
1748 ((struct bfinfdpic_elf_link_hash_table *) ((info)->hash))
1749
1750 #define bfinfdpic_got_section(info) \
1751 (bfinfdpic_hash_table (info)->sgot)
1752 #define bfinfdpic_gotrel_section(info) \
1753 (bfinfdpic_hash_table (info)->sgotrel)
1754 #define bfinfdpic_gotfixup_section(info) \
1755 (bfinfdpic_hash_table (info)->sgotfixup)
1756 #define bfinfdpic_plt_section(info) \
1757 (bfinfdpic_hash_table (info)->splt)
1758 #define bfinfdpic_pltrel_section(info) \
1759 (bfinfdpic_hash_table (info)->spltrel)
1760 #define bfinfdpic_relocs_info(info) \
1761 (bfinfdpic_hash_table (info)->relocs_info)
1762 #define bfinfdpic_got_initial_offset(info) \
1763 (bfinfdpic_hash_table (info)->got0)
1764 #define bfinfdpic_plt_initial_offset(info) \
1765 (bfinfdpic_hash_table (info)->plt0)
1766
1767 /* The name of the dynamic interpreter. This is put in the .interp
1768 section. */
1769
1770 #define ELF_DYNAMIC_INTERPRETER "/lib/ld.so.1"
1771
1772 #define DEFAULT_STACK_SIZE 0x20000
1773
1774 /* This structure is used to collect the number of entries present in
1775 each addressable range of the got. */
1776 struct _bfinfdpic_dynamic_got_info
1777 {
1778 /* Several bits of information about the current link. */
1779 struct bfd_link_info *info;
1780 /* Total size needed for GOT entries within the 18- or 32-bit
1781 ranges. */
1782 bfd_vma got17m4, gothilo;
1783 /* Total size needed for function descriptor entries within the 18-
1784 or 32-bit ranges. */
1785 bfd_vma fd17m4, fdhilo;
1786 /* Total size needed function descriptor entries referenced in PLT
1787 entries, that would be profitable to place in offsets close to
1788 the PIC register. */
1789 bfd_vma fdplt;
1790 /* Total size needed by lazy PLT entries. */
1791 bfd_vma lzplt;
1792 /* Number of relocations carried over from input object files. */
1793 unsigned long relocs;
1794 /* Number of fixups introduced by relocations in input object files. */
1795 unsigned long fixups;
1796 };
1797
1798 /* Create a Blackfin ELF linker hash table. */
1799
1800 static struct bfd_link_hash_table *
1801 bfinfdpic_elf_link_hash_table_create (bfd *abfd)
1802 {
1803 struct bfinfdpic_elf_link_hash_table *ret;
1804 bfd_size_type amt = sizeof (struct bfinfdpic_elf_link_hash_table);
1805
1806 ret = bfd_zalloc (abfd, amt);
1807 if (ret == NULL)
1808 return NULL;
1809
1810 if (!_bfd_elf_link_hash_table_init (&ret->elf, abfd,
1811 _bfd_elf_link_hash_newfunc,
1812 sizeof (struct elf_link_hash_entry)))
1813 {
1814 free (ret);
1815 return NULL;
1816 }
1817
1818 return &ret->elf.root;
1819 }
1820
1821 /* Decide whether a reference to a symbol can be resolved locally or
1822 not. If the symbol is protected, we want the local address, but
1823 its function descriptor must be assigned by the dynamic linker. */
1824 #define BFINFDPIC_SYM_LOCAL(INFO, H) \
1825 (_bfd_elf_symbol_refs_local_p ((H), (INFO), 1) \
1826 || ! elf_hash_table (INFO)->dynamic_sections_created)
1827 #define BFINFDPIC_FUNCDESC_LOCAL(INFO, H) \
1828 ((H)->dynindx == -1 || ! elf_hash_table (INFO)->dynamic_sections_created)
1829
1830 /* This structure collects information on what kind of GOT, PLT or
1831 function descriptors are required by relocations that reference a
1832 certain symbol. */
1833 struct bfinfdpic_relocs_info
1834 {
1835 /* The index of the symbol, as stored in the relocation r_info, if
1836 we have a local symbol; -1 otherwise. */
1837 long symndx;
1838 union
1839 {
1840 /* The input bfd in which the symbol is defined, if it's a local
1841 symbol. */
1842 bfd *abfd;
1843 /* If symndx == -1, the hash table entry corresponding to a global
1844 symbol (even if it turns out to bind locally, in which case it
1845 should ideally be replaced with section's symndx + addend). */
1846 struct elf_link_hash_entry *h;
1847 } d;
1848 /* The addend of the relocation that references the symbol. */
1849 bfd_vma addend;
1850
1851 /* The fields above are used to identify an entry. The fields below
1852 contain information on how an entry is used and, later on, which
1853 locations it was assigned. */
1854 /* The following 2 fields record whether the symbol+addend above was
1855 ever referenced with a GOT relocation. The 17M4 suffix indicates a
1856 GOT17M4 relocation; hilo is used for GOTLO/GOTHI pairs. */
1857 unsigned got17m4;
1858 unsigned gothilo;
1859 /* Whether a FUNCDESC relocation references symbol+addend. */
1860 unsigned fd;
1861 /* Whether a FUNCDESC_GOT relocation references symbol+addend. */
1862 unsigned fdgot17m4;
1863 unsigned fdgothilo;
1864 /* Whether a FUNCDESC_GOTOFF relocation references symbol+addend. */
1865 unsigned fdgoff17m4;
1866 unsigned fdgoffhilo;
1867 /* Whether symbol+addend is referenced with GOTOFF17M4, GOTOFFLO or
1868 GOTOFFHI relocations. The addend doesn't really matter, since we
1869 envision that this will only be used to check whether the symbol
1870 is mapped to the same segment as the got. */
1871 unsigned gotoff;
1872 /* Whether symbol+addend is referenced by a LABEL24 relocation. */
1873 unsigned call;
1874 /* Whether symbol+addend is referenced by a 32 or FUNCDESC_VALUE
1875 relocation. */
1876 unsigned sym;
1877 /* Whether we need a PLT entry for a symbol. Should be implied by
1878 something like:
1879 (call && symndx == -1 && ! BFINFDPIC_SYM_LOCAL (info, d.h)) */
1880 unsigned plt:1;
1881 /* Whether a function descriptor should be created in this link unit
1882 for symbol+addend. Should be implied by something like:
1883 (plt || fdgotoff17m4 || fdgotofflohi
1884 || ((fd || fdgot17m4 || fdgothilo)
1885 && (symndx != -1 || BFINFDPIC_FUNCDESC_LOCAL (info, d.h)))) */
1886 unsigned privfd:1;
1887 /* Whether a lazy PLT entry is needed for this symbol+addend.
1888 Should be implied by something like:
1889 (privfd && symndx == -1 && ! BFINFDPIC_SYM_LOCAL (info, d.h)
1890 && ! (info->flags & DF_BIND_NOW)) */
1891 unsigned lazyplt:1;
1892 /* Whether we've already emitted GOT relocations and PLT entries as
1893 needed for this symbol. */
1894 unsigned done:1;
1895
1896 /* The number of R_byte4_data, R_BFIN_FUNCDESC and R_BFIN_FUNCDESC_VALUE
1897 relocations referencing the symbol. */
1898 unsigned relocs32, relocsfd, relocsfdv;
1899
1900 /* The number of .rofixups entries and dynamic relocations allocated
1901 for this symbol, minus any that might have already been used. */
1902 unsigned fixups, dynrelocs;
1903
1904 /* The offsets of the GOT entries assigned to symbol+addend, to the
1905 function descriptor's address, and to a function descriptor,
1906 respectively. Should be zero if unassigned. The offsets are
1907 counted from the value that will be assigned to the PIC register,
1908 not from the beginning of the .got section. */
1909 bfd_signed_vma got_entry, fdgot_entry, fd_entry;
1910 /* The offsets of the PLT entries assigned to symbol+addend,
1911 non-lazy and lazy, respectively. If unassigned, should be
1912 (bfd_vma)-1. */
1913 bfd_vma plt_entry, lzplt_entry;
1914 };
1915
1916 /* Compute a hash with the key fields of an bfinfdpic_relocs_info entry. */
1917 static hashval_t
1918 bfinfdpic_relocs_info_hash (const void *entry_)
1919 {
1920 const struct bfinfdpic_relocs_info *entry = entry_;
1921
1922 return (entry->symndx == -1
1923 ? (long) entry->d.h->root.root.hash
1924 : entry->symndx + (long) entry->d.abfd->id * 257) + entry->addend;
1925 }
1926
1927 /* Test whether the key fields of two bfinfdpic_relocs_info entries are
1928 identical. */
1929 static int
1930 bfinfdpic_relocs_info_eq (const void *entry1, const void *entry2)
1931 {
1932 const struct bfinfdpic_relocs_info *e1 = entry1;
1933 const struct bfinfdpic_relocs_info *e2 = entry2;
1934
1935 return e1->symndx == e2->symndx && e1->addend == e2->addend
1936 && (e1->symndx == -1 ? e1->d.h == e2->d.h : e1->d.abfd == e2->d.abfd);
1937 }
1938
1939 /* Find or create an entry in a hash table HT that matches the key
1940 fields of the given ENTRY. If it's not found, memory for a new
1941 entry is allocated in ABFD's obstack. */
1942 static struct bfinfdpic_relocs_info *
1943 bfinfdpic_relocs_info_find (struct htab *ht,
1944 bfd *abfd,
1945 const struct bfinfdpic_relocs_info *entry,
1946 enum insert_option insert)
1947 {
1948 struct bfinfdpic_relocs_info **loc =
1949 (struct bfinfdpic_relocs_info **) htab_find_slot (ht, entry, insert);
1950
1951 if (! loc)
1952 return NULL;
1953
1954 if (*loc)
1955 return *loc;
1956
1957 *loc = bfd_zalloc (abfd, sizeof (**loc));
1958
1959 if (! *loc)
1960 return *loc;
1961
1962 (*loc)->symndx = entry->symndx;
1963 (*loc)->d = entry->d;
1964 (*loc)->addend = entry->addend;
1965 (*loc)->plt_entry = (bfd_vma)-1;
1966 (*loc)->lzplt_entry = (bfd_vma)-1;
1967
1968 return *loc;
1969 }
1970
1971 /* Obtain the address of the entry in HT associated with H's symbol +
1972 addend, creating a new entry if none existed. ABFD is only used
1973 for memory allocation purposes. */
1974 inline static struct bfinfdpic_relocs_info *
1975 bfinfdpic_relocs_info_for_global (struct htab *ht,
1976 bfd *abfd,
1977 struct elf_link_hash_entry *h,
1978 bfd_vma addend,
1979 enum insert_option insert)
1980 {
1981 struct bfinfdpic_relocs_info entry;
1982
1983 entry.symndx = -1;
1984 entry.d.h = h;
1985 entry.addend = addend;
1986
1987 return bfinfdpic_relocs_info_find (ht, abfd, &entry, insert);
1988 }
1989
1990 /* Obtain the address of the entry in HT associated with the SYMNDXth
1991 local symbol of the input bfd ABFD, plus the addend, creating a new
1992 entry if none existed. */
1993 inline static struct bfinfdpic_relocs_info *
1994 bfinfdpic_relocs_info_for_local (struct htab *ht,
1995 bfd *abfd,
1996 long symndx,
1997 bfd_vma addend,
1998 enum insert_option insert)
1999 {
2000 struct bfinfdpic_relocs_info entry;
2001
2002 entry.symndx = symndx;
2003 entry.d.abfd = abfd;
2004 entry.addend = addend;
2005
2006 return bfinfdpic_relocs_info_find (ht, abfd, &entry, insert);
2007 }
2008
2009 /* Merge fields set by check_relocs() of two entries that end up being
2010 mapped to the same (presumably global) symbol. */
2011
2012 inline static void
2013 bfinfdpic_pic_merge_early_relocs_info (struct bfinfdpic_relocs_info *e2,
2014 struct bfinfdpic_relocs_info const *e1)
2015 {
2016 e2->got17m4 |= e1->got17m4;
2017 e2->gothilo |= e1->gothilo;
2018 e2->fd |= e1->fd;
2019 e2->fdgot17m4 |= e1->fdgot17m4;
2020 e2->fdgothilo |= e1->fdgothilo;
2021 e2->fdgoff17m4 |= e1->fdgoff17m4;
2022 e2->fdgoffhilo |= e1->fdgoffhilo;
2023 e2->gotoff |= e1->gotoff;
2024 e2->call |= e1->call;
2025 e2->sym |= e1->sym;
2026 }
2027
2028 /* Every block of 65535 lazy PLT entries shares a single call to the
2029 resolver, inserted in the 32768th lazy PLT entry (i.e., entry #
2030 32767, counting from 0). All other lazy PLT entries branch to it
2031 in a single instruction. */
2032
2033 #define LZPLT_RESOLVER_EXTRA 10
2034 #define LZPLT_NORMAL_SIZE 6
2035 #define LZPLT_ENTRIES 1362
2036
2037 #define BFINFDPIC_LZPLT_BLOCK_SIZE ((bfd_vma) LZPLT_NORMAL_SIZE * LZPLT_ENTRIES + LZPLT_RESOLVER_EXTRA)
2038 #define BFINFDPIC_LZPLT_RESOLV_LOC (LZPLT_NORMAL_SIZE * LZPLT_ENTRIES / 2)
2039
2040 /* Add a dynamic relocation to the SRELOC section. */
2041
2042 inline static bfd_vma
2043 _bfinfdpic_add_dyn_reloc (bfd *output_bfd, asection *sreloc, bfd_vma offset,
2044 int reloc_type, long dynindx, bfd_vma addend,
2045 struct bfinfdpic_relocs_info *entry)
2046 {
2047 Elf_Internal_Rela outrel;
2048 bfd_vma reloc_offset;
2049
2050 outrel.r_offset = offset;
2051 outrel.r_info = ELF32_R_INFO (dynindx, reloc_type);
2052 outrel.r_addend = addend;
2053
2054 reloc_offset = sreloc->reloc_count * sizeof (Elf32_External_Rel);
2055 BFD_ASSERT (reloc_offset < sreloc->size);
2056 bfd_elf32_swap_reloc_out (output_bfd, &outrel,
2057 sreloc->contents + reloc_offset);
2058 sreloc->reloc_count++;
2059
2060 /* If the entry's index is zero, this relocation was probably to a
2061 linkonce section that got discarded. We reserved a dynamic
2062 relocation, but it was for another entry than the one we got at
2063 the time of emitting the relocation. Unfortunately there's no
2064 simple way for us to catch this situation, since the relocation
2065 is cleared right before calling relocate_section, at which point
2066 we no longer know what the relocation used to point to. */
2067 if (entry->symndx)
2068 {
2069 BFD_ASSERT (entry->dynrelocs > 0);
2070 entry->dynrelocs--;
2071 }
2072
2073 return reloc_offset;
2074 }
2075
2076 /* Add a fixup to the ROFIXUP section. */
2077
2078 static bfd_vma
2079 _bfinfdpic_add_rofixup (bfd *output_bfd, asection *rofixup, bfd_vma offset,
2080 struct bfinfdpic_relocs_info *entry)
2081 {
2082 bfd_vma fixup_offset;
2083
2084 if (rofixup->flags & SEC_EXCLUDE)
2085 return -1;
2086
2087 fixup_offset = rofixup->reloc_count * 4;
2088 if (rofixup->contents)
2089 {
2090 BFD_ASSERT (fixup_offset < rofixup->size);
2091 bfd_put_32 (output_bfd, offset, rofixup->contents + fixup_offset);
2092 }
2093 rofixup->reloc_count++;
2094
2095 if (entry && entry->symndx)
2096 {
2097 /* See discussion about symndx == 0 in _bfinfdpic_add_dyn_reloc
2098 above. */
2099 BFD_ASSERT (entry->fixups > 0);
2100 entry->fixups--;
2101 }
2102
2103 return fixup_offset;
2104 }
2105
2106 /* Find the segment number in which OSEC, and output section, is
2107 located. */
2108
2109 static unsigned
2110 _bfinfdpic_osec_to_segment (bfd *output_bfd, asection *osec)
2111 {
2112 Elf_Internal_Phdr *p = _bfd_elf_find_segment_containing_section (output_bfd, osec);
2113
2114 return (p != NULL) ? p - elf_tdata (output_bfd)->phdr : -1;
2115 }
2116
2117 inline static bfd_boolean
2118 _bfinfdpic_osec_readonly_p (bfd *output_bfd, asection *osec)
2119 {
2120 unsigned seg = _bfinfdpic_osec_to_segment (output_bfd, osec);
2121
2122 return ! (elf_tdata (output_bfd)->phdr[seg].p_flags & PF_W);
2123 }
2124
2125 /* Generate relocations for GOT entries, function descriptors, and
2126 code for PLT and lazy PLT entries. */
2127
2128 inline static bfd_boolean
2129 _bfinfdpic_emit_got_relocs_plt_entries (struct bfinfdpic_relocs_info *entry,
2130 bfd *output_bfd,
2131 struct bfd_link_info *info,
2132 asection *sec,
2133 Elf_Internal_Sym *sym,
2134 bfd_vma addend)
2135
2136 {
2137 bfd_vma fd_lazy_rel_offset = (bfd_vma)-1;
2138 int dynindx = -1;
2139
2140 if (entry->done)
2141 return TRUE;
2142 entry->done = 1;
2143
2144 if (entry->got_entry || entry->fdgot_entry || entry->fd_entry)
2145 {
2146 /* If the symbol is dynamic, consider it for dynamic
2147 relocations, otherwise decay to section + offset. */
2148 if (entry->symndx == -1 && entry->d.h->dynindx != -1)
2149 dynindx = entry->d.h->dynindx;
2150 else
2151 {
2152 if (sec->output_section
2153 && ! bfd_is_abs_section (sec->output_section)
2154 && ! bfd_is_und_section (sec->output_section))
2155 dynindx = elf_section_data (sec->output_section)->dynindx;
2156 else
2157 dynindx = 0;
2158 }
2159 }
2160
2161 /* Generate relocation for GOT entry pointing to the symbol. */
2162 if (entry->got_entry)
2163 {
2164 int idx = dynindx;
2165 bfd_vma ad = addend;
2166
2167 /* If the symbol is dynamic but binds locally, use
2168 section+offset. */
2169 if (sec && (entry->symndx != -1
2170 || BFINFDPIC_SYM_LOCAL (info, entry->d.h)))
2171 {
2172 if (entry->symndx == -1)
2173 ad += entry->d.h->root.u.def.value;
2174 else
2175 ad += sym->st_value;
2176 ad += sec->output_offset;
2177 if (sec->output_section && elf_section_data (sec->output_section))
2178 idx = elf_section_data (sec->output_section)->dynindx;
2179 else
2180 idx = 0;
2181 }
2182
2183 /* If we're linking an executable at a fixed address, we can
2184 omit the dynamic relocation as long as the symbol is local to
2185 this module. */
2186 if (info->executable && !info->pie
2187 && (entry->symndx != -1
2188 || BFINFDPIC_SYM_LOCAL (info, entry->d.h)))
2189 {
2190 if (sec)
2191 ad += sec->output_section->vma;
2192 if (entry->symndx != -1
2193 || entry->d.h->root.type != bfd_link_hash_undefweak)
2194 _bfinfdpic_add_rofixup (output_bfd,
2195 bfinfdpic_gotfixup_section (info),
2196 bfinfdpic_got_section (info)->output_section
2197 ->vma
2198 + bfinfdpic_got_section (info)->output_offset
2199 + bfinfdpic_got_initial_offset (info)
2200 + entry->got_entry, entry);
2201 }
2202 else
2203 _bfinfdpic_add_dyn_reloc (output_bfd, bfinfdpic_gotrel_section (info),
2204 _bfd_elf_section_offset
2205 (output_bfd, info,
2206 bfinfdpic_got_section (info),
2207 bfinfdpic_got_initial_offset (info)
2208 + entry->got_entry)
2209 + bfinfdpic_got_section (info)
2210 ->output_section->vma
2211 + bfinfdpic_got_section (info)->output_offset,
2212 R_byte4_data, idx, ad, entry);
2213
2214 bfd_put_32 (output_bfd, ad,
2215 bfinfdpic_got_section (info)->contents
2216 + bfinfdpic_got_initial_offset (info)
2217 + entry->got_entry);
2218 }
2219
2220 /* Generate relocation for GOT entry pointing to a canonical
2221 function descriptor. */
2222 if (entry->fdgot_entry)
2223 {
2224 int reloc, idx;
2225 bfd_vma ad = 0;
2226
2227 if (! (entry->symndx == -1
2228 && entry->d.h->root.type == bfd_link_hash_undefweak
2229 && BFINFDPIC_SYM_LOCAL (info, entry->d.h)))
2230 {
2231 /* If the symbol is dynamic and there may be dynamic symbol
2232 resolution because we are, or are linked with, a shared
2233 library, emit a FUNCDESC relocation such that the dynamic
2234 linker will allocate the function descriptor. If the
2235 symbol needs a non-local function descriptor but binds
2236 locally (e.g., its visibility is protected, emit a
2237 dynamic relocation decayed to section+offset. */
2238 if (entry->symndx == -1
2239 && ! BFINFDPIC_FUNCDESC_LOCAL (info, entry->d.h)
2240 && BFINFDPIC_SYM_LOCAL (info, entry->d.h)
2241 && !(info->executable && !info->pie))
2242 {
2243 reloc = R_BFIN_FUNCDESC;
2244 idx = elf_section_data (entry->d.h->root.u.def.section
2245 ->output_section)->dynindx;
2246 ad = entry->d.h->root.u.def.section->output_offset
2247 + entry->d.h->root.u.def.value;
2248 }
2249 else if (entry->symndx == -1
2250 && ! BFINFDPIC_FUNCDESC_LOCAL (info, entry->d.h))
2251 {
2252 reloc = R_BFIN_FUNCDESC;
2253 idx = dynindx;
2254 ad = addend;
2255 if (ad)
2256 return FALSE;
2257 }
2258 else
2259 {
2260 /* Otherwise, we know we have a private function descriptor,
2261 so reference it directly. */
2262 if (elf_hash_table (info)->dynamic_sections_created)
2263 BFD_ASSERT (entry->privfd);
2264 reloc = R_byte4_data;
2265 idx = elf_section_data (bfinfdpic_got_section (info)
2266 ->output_section)->dynindx;
2267 ad = bfinfdpic_got_section (info)->output_offset
2268 + bfinfdpic_got_initial_offset (info) + entry->fd_entry;
2269 }
2270
2271 /* If there is room for dynamic symbol resolution, emit the
2272 dynamic relocation. However, if we're linking an
2273 executable at a fixed location, we won't have emitted a
2274 dynamic symbol entry for the got section, so idx will be
2275 zero, which means we can and should compute the address
2276 of the private descriptor ourselves. */
2277 if (info->executable && !info->pie
2278 && (entry->symndx != -1
2279 || BFINFDPIC_FUNCDESC_LOCAL (info, entry->d.h)))
2280 {
2281 ad += bfinfdpic_got_section (info)->output_section->vma;
2282 _bfinfdpic_add_rofixup (output_bfd,
2283 bfinfdpic_gotfixup_section (info),
2284 bfinfdpic_got_section (info)
2285 ->output_section->vma
2286 + bfinfdpic_got_section (info)
2287 ->output_offset
2288 + bfinfdpic_got_initial_offset (info)
2289 + entry->fdgot_entry, entry);
2290 }
2291 else
2292 _bfinfdpic_add_dyn_reloc (output_bfd,
2293 bfinfdpic_gotrel_section (info),
2294 _bfd_elf_section_offset
2295 (output_bfd, info,
2296 bfinfdpic_got_section (info),
2297 bfinfdpic_got_initial_offset (info)
2298 + entry->fdgot_entry)
2299 + bfinfdpic_got_section (info)
2300 ->output_section->vma
2301 + bfinfdpic_got_section (info)
2302 ->output_offset,
2303 reloc, idx, ad, entry);
2304 }
2305
2306 bfd_put_32 (output_bfd, ad,
2307 bfinfdpic_got_section (info)->contents
2308 + bfinfdpic_got_initial_offset (info)
2309 + entry->fdgot_entry);
2310 }
2311
2312 /* Generate relocation to fill in a private function descriptor in
2313 the GOT. */
2314 if (entry->fd_entry)
2315 {
2316 int idx = dynindx;
2317 bfd_vma ad = addend;
2318 bfd_vma ofst;
2319 long lowword, highword;
2320
2321 /* If the symbol is dynamic but binds locally, use
2322 section+offset. */
2323 if (sec && (entry->symndx != -1
2324 || BFINFDPIC_SYM_LOCAL (info, entry->d.h)))
2325 {
2326 if (entry->symndx == -1)
2327 ad += entry->d.h->root.u.def.value;
2328 else
2329 ad += sym->st_value;
2330 ad += sec->output_offset;
2331 if (sec->output_section && elf_section_data (sec->output_section))
2332 idx = elf_section_data (sec->output_section)->dynindx;
2333 else
2334 idx = 0;
2335 }
2336
2337 /* If we're linking an executable at a fixed address, we can
2338 omit the dynamic relocation as long as the symbol is local to
2339 this module. */
2340 if (info->executable && !info->pie
2341 && (entry->symndx != -1 || BFINFDPIC_SYM_LOCAL (info, entry->d.h)))
2342 {
2343 if (sec)
2344 ad += sec->output_section->vma;
2345 ofst = 0;
2346 if (entry->symndx != -1
2347 || entry->d.h->root.type != bfd_link_hash_undefweak)
2348 {
2349 _bfinfdpic_add_rofixup (output_bfd,
2350 bfinfdpic_gotfixup_section (info),
2351 bfinfdpic_got_section (info)
2352 ->output_section->vma
2353 + bfinfdpic_got_section (info)
2354 ->output_offset
2355 + bfinfdpic_got_initial_offset (info)
2356 + entry->fd_entry, entry);
2357 _bfinfdpic_add_rofixup (output_bfd,
2358 bfinfdpic_gotfixup_section (info),
2359 bfinfdpic_got_section (info)
2360 ->output_section->vma
2361 + bfinfdpic_got_section (info)
2362 ->output_offset
2363 + bfinfdpic_got_initial_offset (info)
2364 + entry->fd_entry + 4, entry);
2365 }
2366 }
2367 else
2368 {
2369 ofst
2370 = _bfinfdpic_add_dyn_reloc (output_bfd,
2371 entry->lazyplt
2372 ? bfinfdpic_pltrel_section (info)
2373 : bfinfdpic_gotrel_section (info),
2374 _bfd_elf_section_offset
2375 (output_bfd, info,
2376 bfinfdpic_got_section (info),
2377 bfinfdpic_got_initial_offset (info)
2378 + entry->fd_entry)
2379 + bfinfdpic_got_section (info)
2380 ->output_section->vma
2381 + bfinfdpic_got_section (info)
2382 ->output_offset,
2383 R_BFIN_FUNCDESC_VALUE, idx, ad, entry);
2384 }
2385
2386 /* If we've omitted the dynamic relocation, just emit the fixed
2387 addresses of the symbol and of the local GOT base offset. */
2388 if (info->executable && !info->pie && sec && sec->output_section)
2389 {
2390 lowword = ad;
2391 highword = bfinfdpic_got_section (info)->output_section->vma
2392 + bfinfdpic_got_section (info)->output_offset
2393 + bfinfdpic_got_initial_offset (info);
2394 }
2395 else if (entry->lazyplt)
2396 {
2397 if (ad)
2398 return FALSE;
2399
2400 fd_lazy_rel_offset = ofst;
2401
2402 /* A function descriptor used for lazy or local resolving is
2403 initialized such that its high word contains the output
2404 section index in which the PLT entries are located, and
2405 the low word contains the address of the lazy PLT entry
2406 entry point, that must be within the memory region
2407 assigned to that section. */
2408 lowword = entry->lzplt_entry + 4
2409 + bfinfdpic_plt_section (info)->output_offset
2410 + bfinfdpic_plt_section (info)->output_section->vma;
2411 highword = _bfinfdpic_osec_to_segment
2412 (output_bfd, bfinfdpic_plt_section (info)->output_section);
2413 }
2414 else
2415 {
2416 /* A function descriptor for a local function gets the index
2417 of the section. For a non-local function, it's
2418 disregarded. */
2419 lowword = ad;
2420 if (entry->symndx == -1 && entry->d.h->dynindx != -1
2421 && entry->d.h->dynindx == idx)
2422 highword = 0;
2423 else
2424 highword = _bfinfdpic_osec_to_segment
2425 (output_bfd, sec->output_section);
2426 }
2427
2428 bfd_put_32 (output_bfd, lowword,
2429 bfinfdpic_got_section (info)->contents
2430 + bfinfdpic_got_initial_offset (info)
2431 + entry->fd_entry);
2432 bfd_put_32 (output_bfd, highword,
2433 bfinfdpic_got_section (info)->contents
2434 + bfinfdpic_got_initial_offset (info)
2435 + entry->fd_entry + 4);
2436 }
2437
2438 /* Generate code for the PLT entry. */
2439 if (entry->plt_entry != (bfd_vma) -1)
2440 {
2441 bfd_byte *plt_code = bfinfdpic_plt_section (info)->contents
2442 + entry->plt_entry;
2443
2444 BFD_ASSERT (entry->fd_entry);
2445
2446 /* Figure out what kind of PLT entry we need, depending on the
2447 location of the function descriptor within the GOT. */
2448 if (entry->fd_entry >= -(1 << (18 - 1))
2449 && entry->fd_entry + 4 < (1 << (18 - 1)))
2450 {
2451 /* P1 = [P3 + fd_entry]; P3 = [P3 + fd_entry + 4] */
2452 bfd_put_32 (output_bfd,
2453 0xe519 | ((entry->fd_entry << 14) & 0xFFFF0000),
2454 plt_code);
2455 bfd_put_32 (output_bfd,
2456 0xe51b | (((entry->fd_entry + 4) << 14) & 0xFFFF0000),
2457 plt_code + 4);
2458 plt_code += 8;
2459 }
2460 else
2461 {
2462 /* P1.L = fd_entry; P1.H = fd_entry;
2463 P3 = P3 + P1;
2464 P1 = [P3];
2465 P3 = [P3 + 4]; */
2466 bfd_put_32 (output_bfd,
2467 0xe109 | (entry->fd_entry << 16),
2468 plt_code);
2469 bfd_put_32 (output_bfd,
2470 0xe149 | (entry->fd_entry & 0xFFFF0000),
2471 plt_code + 4);
2472 bfd_put_16 (output_bfd, 0x5ad9, plt_code + 8);
2473 bfd_put_16 (output_bfd, 0x9159, plt_code + 10);
2474 bfd_put_16 (output_bfd, 0xac5b, plt_code + 12);
2475 plt_code += 14;
2476 }
2477 /* JUMP (P1) */
2478 bfd_put_16 (output_bfd, 0x0051, plt_code);
2479 }
2480
2481 /* Generate code for the lazy PLT entry. */
2482 if (entry->lzplt_entry != (bfd_vma) -1)
2483 {
2484 bfd_byte *lzplt_code = bfinfdpic_plt_section (info)->contents
2485 + entry->lzplt_entry;
2486 bfd_vma resolverStub_addr;
2487
2488 bfd_put_32 (output_bfd, fd_lazy_rel_offset, lzplt_code);
2489 lzplt_code += 4;
2490
2491 resolverStub_addr = entry->lzplt_entry / BFINFDPIC_LZPLT_BLOCK_SIZE
2492 * BFINFDPIC_LZPLT_BLOCK_SIZE + BFINFDPIC_LZPLT_RESOLV_LOC;
2493 if (resolverStub_addr >= bfinfdpic_plt_initial_offset (info))
2494 resolverStub_addr = bfinfdpic_plt_initial_offset (info) - LZPLT_NORMAL_SIZE - LZPLT_RESOLVER_EXTRA;
2495
2496 if (entry->lzplt_entry == resolverStub_addr)
2497 {
2498 /* This is a lazy PLT entry that includes a resolver call.
2499 P2 = [P3];
2500 R3 = [P3 + 4];
2501 JUMP (P2); */
2502 bfd_put_32 (output_bfd,
2503 0xa05b915a,
2504 lzplt_code);
2505 bfd_put_16 (output_bfd, 0x0052, lzplt_code + 4);
2506 }
2507 else
2508 {
2509 /* JUMP.S resolverStub */
2510 bfd_put_16 (output_bfd,
2511 0x2000
2512 | (((resolverStub_addr - entry->lzplt_entry)
2513 / 2) & (((bfd_vma)1 << 12) - 1)),
2514 lzplt_code);
2515 }
2516 }
2517
2518 return TRUE;
2519 }
2520
2521 /* Relocate an Blackfin ELF section.
2522
2523 The RELOCATE_SECTION function is called by the new ELF backend linker
2524 to handle the relocations for a section.
2525
2526 The relocs are always passed as Rela structures; if the section
2527 actually uses Rel structures, the r_addend field will always be
2528 zero.
2529
2530 This function is responsible for adjusting the section contents as
2531 necessary, and (if using Rela relocs and generating a relocatable
2532 output file) adjusting the reloc addend as necessary.
2533
2534 This function does not have to worry about setting the reloc
2535 address or the reloc symbol index.
2536
2537 LOCAL_SYMS is a pointer to the swapped in local symbols.
2538
2539 LOCAL_SECTIONS is an array giving the section in the input file
2540 corresponding to the st_shndx field of each local symbol.
2541
2542 The global hash table entry for the global symbols can be found
2543 via elf_sym_hashes (input_bfd).
2544
2545 When generating relocatable output, this function must handle
2546 STB_LOCAL/STT_SECTION symbols specially. The output symbol is
2547 going to be the section symbol corresponding to the output
2548 section, which means that the addend must be adjusted
2549 accordingly. */
2550
2551 static bfd_boolean
2552 bfinfdpic_relocate_section (bfd * output_bfd,
2553 struct bfd_link_info *info,
2554 bfd * input_bfd,
2555 asection * input_section,
2556 bfd_byte * contents,
2557 Elf_Internal_Rela * relocs,
2558 Elf_Internal_Sym * local_syms,
2559 asection ** local_sections)
2560 {
2561 Elf_Internal_Shdr *symtab_hdr;
2562 struct elf_link_hash_entry **sym_hashes;
2563 Elf_Internal_Rela *rel;
2564 Elf_Internal_Rela *relend;
2565 unsigned isec_segment, got_segment, plt_segment,
2566 check_segment[2];
2567 int silence_segment_error = !(info->shared || info->pie);
2568
2569 symtab_hdr = & elf_tdata (input_bfd)->symtab_hdr;
2570 sym_hashes = elf_sym_hashes (input_bfd);
2571 relend = relocs + input_section->reloc_count;
2572
2573 isec_segment = _bfinfdpic_osec_to_segment (output_bfd,
2574 input_section->output_section);
2575 if (IS_FDPIC (output_bfd) && bfinfdpic_got_section (info))
2576 got_segment = _bfinfdpic_osec_to_segment (output_bfd,
2577 bfinfdpic_got_section (info)
2578 ->output_section);
2579 else
2580 got_segment = -1;
2581 if (IS_FDPIC (output_bfd) && elf_hash_table (info)->dynamic_sections_created)
2582 plt_segment = _bfinfdpic_osec_to_segment (output_bfd,
2583 bfinfdpic_plt_section (info)
2584 ->output_section);
2585 else
2586 plt_segment = -1;
2587
2588 for (rel = relocs; rel < relend; rel ++)
2589 {
2590 reloc_howto_type *howto;
2591 unsigned long r_symndx;
2592 Elf_Internal_Sym *sym;
2593 asection *sec;
2594 struct elf_link_hash_entry *h;
2595 bfd_vma relocation;
2596 bfd_reloc_status_type r;
2597 const char * name = NULL;
2598 int r_type;
2599 asection *osec;
2600 struct bfinfdpic_relocs_info *picrel;
2601 bfd_vma orig_addend = rel->r_addend;
2602
2603 r_type = ELF32_R_TYPE (rel->r_info);
2604
2605 if (r_type == R_BFIN_GNU_VTINHERIT
2606 || r_type == R_BFIN_GNU_VTENTRY)
2607 continue;
2608
2609 r_symndx = ELF32_R_SYM (rel->r_info);
2610 howto = bfin_reloc_type_lookup (input_bfd, r_type);
2611 if (howto == NULL)
2612 {
2613 bfd_set_error (bfd_error_bad_value);
2614 return FALSE;
2615 }
2616
2617 h = NULL;
2618 sym = NULL;
2619 sec = NULL;
2620
2621 if (r_symndx < symtab_hdr->sh_info)
2622 {
2623 sym = local_syms + r_symndx;
2624 osec = sec = local_sections [r_symndx];
2625 relocation = _bfd_elf_rela_local_sym (output_bfd, sym, &sec, rel);
2626
2627 name = bfd_elf_string_from_elf_section
2628 (input_bfd, symtab_hdr->sh_link, sym->st_name);
2629 name = (name == NULL) ? bfd_section_name (input_bfd, sec) : name;
2630 }
2631 else
2632 {
2633 bfd_boolean warned;
2634 bfd_boolean unresolved_reloc;
2635
2636 RELOC_FOR_GLOBAL_SYMBOL (info, input_bfd, input_section, rel,
2637 r_symndx, symtab_hdr, sym_hashes,
2638 h, sec, relocation,
2639 unresolved_reloc, warned);
2640 osec = sec;
2641 }
2642
2643 if (sec != NULL && elf_discarded_section (sec))
2644 {
2645 /* For relocs against symbols from removed linkonce sections,
2646 or sections discarded by a linker script, we just want the
2647 section contents zeroed. Avoid any special processing. */
2648 _bfd_clear_contents (howto, input_bfd, contents + rel->r_offset);
2649 rel->r_info = 0;
2650 rel->r_addend = 0;
2651 continue;
2652 }
2653
2654 if (info->relocatable)
2655 continue;
2656
2657 if (h != NULL
2658 && (h->root.type == bfd_link_hash_defined
2659 || h->root.type == bfd_link_hash_defweak)
2660 && !BFINFDPIC_SYM_LOCAL (info, h))
2661 {
2662 osec = sec = NULL;
2663 relocation = 0;
2664 }
2665
2666 switch (r_type)
2667 {
2668 case R_pcrel24:
2669 case R_pcrel24_jump_l:
2670 case R_byte4_data:
2671 if (! IS_FDPIC (output_bfd))
2672 goto non_fdpic;
2673
2674 case R_BFIN_GOT17M4:
2675 case R_BFIN_GOTHI:
2676 case R_BFIN_GOTLO:
2677 case R_BFIN_FUNCDESC_GOT17M4:
2678 case R_BFIN_FUNCDESC_GOTHI:
2679 case R_BFIN_FUNCDESC_GOTLO:
2680 case R_BFIN_GOTOFF17M4:
2681 case R_BFIN_GOTOFFHI:
2682 case R_BFIN_GOTOFFLO:
2683 case R_BFIN_FUNCDESC_GOTOFF17M4:
2684 case R_BFIN_FUNCDESC_GOTOFFHI:
2685 case R_BFIN_FUNCDESC_GOTOFFLO:
2686 case R_BFIN_FUNCDESC:
2687 case R_BFIN_FUNCDESC_VALUE:
2688 if (h != NULL)
2689 picrel = bfinfdpic_relocs_info_for_global (bfinfdpic_relocs_info
2690 (info), input_bfd, h,
2691 orig_addend, INSERT);
2692 else
2693 /* In order to find the entry we created before, we must
2694 use the original addend, not the one that may have been
2695 modified by _bfd_elf_rela_local_sym(). */
2696 picrel = bfinfdpic_relocs_info_for_local (bfinfdpic_relocs_info
2697 (info), input_bfd, r_symndx,
2698 orig_addend, INSERT);
2699 if (! picrel)
2700 return FALSE;
2701
2702 if (!_bfinfdpic_emit_got_relocs_plt_entries (picrel, output_bfd, info,
2703 osec, sym,
2704 rel->r_addend))
2705 {
2706 (*_bfd_error_handler)
2707 (_("%B: relocation at `%A+0x%x' references symbol `%s' with nonzero addend"),
2708 input_bfd, input_section, rel->r_offset, name);
2709 return FALSE;
2710
2711 }
2712
2713 break;
2714
2715 default:
2716 non_fdpic:
2717 picrel = NULL;
2718 if (h && ! BFINFDPIC_SYM_LOCAL (info, h))
2719 {
2720 info->callbacks->warning
2721 (info, _("relocation references symbol not defined in the module"),
2722 name, input_bfd, input_section, rel->r_offset);
2723 return FALSE;
2724 }
2725 break;
2726 }
2727
2728 switch (r_type)
2729 {
2730 case R_pcrel24:
2731 case R_pcrel24_jump_l:
2732 check_segment[0] = isec_segment;
2733 if (! IS_FDPIC (output_bfd))
2734 check_segment[1] = isec_segment;
2735 else if (picrel->plt)
2736 {
2737 relocation = bfinfdpic_plt_section (info)->output_section->vma
2738 + bfinfdpic_plt_section (info)->output_offset
2739 + picrel->plt_entry;
2740 check_segment[1] = plt_segment;
2741 }
2742 /* We don't want to warn on calls to undefined weak symbols,
2743 as calls to them must be protected by non-NULL tests
2744 anyway, and unprotected calls would invoke undefined
2745 behavior. */
2746 else if (picrel->symndx == -1
2747 && picrel->d.h->root.type == bfd_link_hash_undefweak)
2748 check_segment[1] = check_segment[0];
2749 else
2750 check_segment[1] = sec
2751 ? _bfinfdpic_osec_to_segment (output_bfd, sec->output_section)
2752 : (unsigned)-1;
2753 break;
2754
2755 case R_BFIN_GOT17M4:
2756 case R_BFIN_GOTHI:
2757 case R_BFIN_GOTLO:
2758 relocation = picrel->got_entry;
2759 check_segment[0] = check_segment[1] = got_segment;
2760 break;
2761
2762 case R_BFIN_FUNCDESC_GOT17M4:
2763 case R_BFIN_FUNCDESC_GOTHI:
2764 case R_BFIN_FUNCDESC_GOTLO:
2765 relocation = picrel->fdgot_entry;
2766 check_segment[0] = check_segment[1] = got_segment;
2767 break;
2768
2769 case R_BFIN_GOTOFFHI:
2770 case R_BFIN_GOTOFF17M4:
2771 case R_BFIN_GOTOFFLO:
2772 relocation -= bfinfdpic_got_section (info)->output_section->vma
2773 + bfinfdpic_got_section (info)->output_offset
2774 + bfinfdpic_got_initial_offset (info);
2775 check_segment[0] = got_segment;
2776 check_segment[1] = sec
2777 ? _bfinfdpic_osec_to_segment (output_bfd, sec->output_section)
2778 : (unsigned)-1;
2779 break;
2780
2781 case R_BFIN_FUNCDESC_GOTOFF17M4:
2782 case R_BFIN_FUNCDESC_GOTOFFHI:
2783 case R_BFIN_FUNCDESC_GOTOFFLO:
2784 relocation = picrel->fd_entry;
2785 check_segment[0] = check_segment[1] = got_segment;
2786 break;
2787
2788 case R_BFIN_FUNCDESC:
2789 {
2790 int dynindx;
2791 bfd_vma addend = rel->r_addend;
2792
2793 if (! (h && h->root.type == bfd_link_hash_undefweak
2794 && BFINFDPIC_SYM_LOCAL (info, h)))
2795 {
2796 /* If the symbol is dynamic and there may be dynamic
2797 symbol resolution because we are or are linked with a
2798 shared library, emit a FUNCDESC relocation such that
2799 the dynamic linker will allocate the function
2800 descriptor. If the symbol needs a non-local function
2801 descriptor but binds locally (e.g., its visibility is
2802 protected, emit a dynamic relocation decayed to
2803 section+offset. */
2804 if (h && ! BFINFDPIC_FUNCDESC_LOCAL (info, h)
2805 && BFINFDPIC_SYM_LOCAL (info, h)
2806 && !(info->executable && !info->pie))
2807 {
2808 dynindx = elf_section_data (h->root.u.def.section
2809 ->output_section)->dynindx;
2810 addend += h->root.u.def.section->output_offset
2811 + h->root.u.def.value;
2812 }
2813 else if (h && ! BFINFDPIC_FUNCDESC_LOCAL (info, h))
2814 {
2815 if (addend)
2816 {
2817 info->callbacks->warning
2818 (info, _("R_BFIN_FUNCDESC references dynamic symbol with nonzero addend"),
2819 name, input_bfd, input_section, rel->r_offset);
2820 return FALSE;
2821 }
2822 dynindx = h->dynindx;
2823 }
2824 else
2825 {
2826 /* Otherwise, we know we have a private function
2827 descriptor, so reference it directly. */
2828 BFD_ASSERT (picrel->privfd);
2829 r_type = R_byte4_data;
2830 dynindx = elf_section_data (bfinfdpic_got_section (info)
2831 ->output_section)->dynindx;
2832 addend = bfinfdpic_got_section (info)->output_offset
2833 + bfinfdpic_got_initial_offset (info)
2834 + picrel->fd_entry;
2835 }
2836
2837 /* If there is room for dynamic symbol resolution, emit
2838 the dynamic relocation. However, if we're linking an
2839 executable at a fixed location, we won't have emitted a
2840 dynamic symbol entry for the got section, so idx will
2841 be zero, which means we can and should compute the
2842 address of the private descriptor ourselves. */
2843 if (info->executable && !info->pie
2844 && (!h || BFINFDPIC_FUNCDESC_LOCAL (info, h)))
2845 {
2846 addend += bfinfdpic_got_section (info)->output_section->vma;
2847 if ((bfd_get_section_flags (output_bfd,
2848 input_section->output_section)
2849 & (SEC_ALLOC | SEC_LOAD)) == (SEC_ALLOC | SEC_LOAD))
2850 {
2851 if (_bfinfdpic_osec_readonly_p (output_bfd,
2852 input_section
2853 ->output_section))
2854 {
2855 info->callbacks->warning
2856 (info,
2857 _("cannot emit fixups in read-only section"),
2858 name, input_bfd, input_section, rel->r_offset);
2859 return FALSE;
2860 }
2861 _bfinfdpic_add_rofixup (output_bfd,
2862 bfinfdpic_gotfixup_section
2863 (info),
2864 _bfd_elf_section_offset
2865 (output_bfd, info,
2866 input_section, rel->r_offset)
2867 + input_section
2868 ->output_section->vma
2869 + input_section->output_offset,
2870 picrel);
2871 }
2872 }
2873 else if ((bfd_get_section_flags (output_bfd,
2874 input_section->output_section)
2875 & (SEC_ALLOC | SEC_LOAD)) == (SEC_ALLOC | SEC_LOAD))
2876 {
2877 bfd_vma offset;
2878
2879 if (_bfinfdpic_osec_readonly_p (output_bfd,
2880 input_section
2881 ->output_section))
2882 {
2883 info->callbacks->warning
2884 (info,
2885 _("cannot emit dynamic relocations in read-only section"),
2886 name, input_bfd, input_section, rel->r_offset);
2887 return FALSE;
2888 }
2889 offset = _bfd_elf_section_offset (output_bfd, info,
2890 input_section, rel->r_offset);
2891 /* Only output a reloc for a not deleted entry. */
2892 if (offset >= (bfd_vma) -2)
2893 _bfinfdpic_add_dyn_reloc (output_bfd,
2894 bfinfdpic_gotrel_section (info),
2895 0,
2896 R_unused0,
2897 dynindx, addend, picrel);
2898 else
2899 _bfinfdpic_add_dyn_reloc (output_bfd,
2900 bfinfdpic_gotrel_section (info),
2901 offset + input_section
2902 ->output_section->vma
2903 + input_section->output_offset,
2904 r_type,
2905 dynindx, addend, picrel);
2906 }
2907 else
2908 addend += bfinfdpic_got_section (info)->output_section->vma;
2909 }
2910
2911 /* We want the addend in-place because dynamic
2912 relocations are REL. Setting relocation to it should
2913 arrange for it to be installed. */
2914 relocation = addend - rel->r_addend;
2915 }
2916 check_segment[0] = check_segment[1] = got_segment;
2917 break;
2918
2919 case R_byte4_data:
2920 if (! IS_FDPIC (output_bfd))
2921 {
2922 check_segment[0] = check_segment[1] = -1;
2923 break;
2924 }
2925 /* Fall through. */
2926 case R_BFIN_FUNCDESC_VALUE:
2927 {
2928 int dynindx;
2929 bfd_vma addend = rel->r_addend;
2930 bfd_vma offset;
2931 offset = _bfd_elf_section_offset (output_bfd, info,
2932 input_section, rel->r_offset);
2933
2934 /* If the symbol is dynamic but binds locally, use
2935 section+offset. */
2936 if (h && ! BFINFDPIC_SYM_LOCAL (info, h))
2937 {
2938 if (addend && r_type == R_BFIN_FUNCDESC_VALUE)
2939 {
2940 info->callbacks->warning
2941 (info, _("R_BFIN_FUNCDESC_VALUE references dynamic symbol with nonzero addend"),
2942 name, input_bfd, input_section, rel->r_offset);
2943 return FALSE;
2944 }
2945 dynindx = h->dynindx;
2946 }
2947 else
2948 {
2949 if (h)
2950 addend += h->root.u.def.value;
2951 else
2952 addend += sym->st_value;
2953 if (osec)
2954 addend += osec->output_offset;
2955 if (osec && osec->output_section
2956 && ! bfd_is_abs_section (osec->output_section)
2957 && ! bfd_is_und_section (osec->output_section))
2958 dynindx = elf_section_data (osec->output_section)->dynindx;
2959 else
2960 dynindx = 0;
2961 }
2962
2963 /* If we're linking an executable at a fixed address, we
2964 can omit the dynamic relocation as long as the symbol
2965 is defined in the current link unit (which is implied
2966 by its output section not being NULL). */
2967 if (info->executable && !info->pie
2968 && (!h || BFINFDPIC_SYM_LOCAL (info, h)))
2969 {
2970 if (osec)
2971 addend += osec->output_section->vma;
2972 if (IS_FDPIC (input_bfd)
2973 && (bfd_get_section_flags (output_bfd,
2974 input_section->output_section)
2975 & (SEC_ALLOC | SEC_LOAD)) == (SEC_ALLOC | SEC_LOAD))
2976 {
2977 if (_bfinfdpic_osec_readonly_p (output_bfd,
2978 input_section
2979 ->output_section))
2980 {
2981 info->callbacks->warning
2982 (info,
2983 _("cannot emit fixups in read-only section"),
2984 name, input_bfd, input_section, rel->r_offset);
2985 return FALSE;
2986 }
2987 if (!h || h->root.type != bfd_link_hash_undefweak)
2988 {
2989 /* Only output a reloc for a not deleted entry. */
2990 if (offset >= (bfd_vma)-2)
2991 _bfinfdpic_add_rofixup (output_bfd,
2992 bfinfdpic_gotfixup_section
2993 (info), -1, picrel);
2994 else
2995 _bfinfdpic_add_rofixup (output_bfd,
2996 bfinfdpic_gotfixup_section
2997 (info),
2998 offset + input_section
2999 ->output_section->vma
3000 + input_section->output_offset,
3001 picrel);
3002
3003 if (r_type == R_BFIN_FUNCDESC_VALUE)
3004 {
3005 if (offset >= (bfd_vma)-2)
3006 _bfinfdpic_add_rofixup
3007 (output_bfd,
3008 bfinfdpic_gotfixup_section (info),
3009 -1, picrel);
3010 else
3011 _bfinfdpic_add_rofixup
3012 (output_bfd,
3013 bfinfdpic_gotfixup_section (info),
3014 offset + input_section->output_section->vma
3015 + input_section->output_offset + 4, picrel);
3016 }
3017 }
3018 }
3019 }
3020 else
3021 {
3022 if ((bfd_get_section_flags (output_bfd,
3023 input_section->output_section)
3024 & (SEC_ALLOC | SEC_LOAD)) == (SEC_ALLOC | SEC_LOAD))
3025 {
3026 if (_bfinfdpic_osec_readonly_p (output_bfd,
3027 input_section
3028 ->output_section))
3029 {
3030 info->callbacks->warning
3031 (info,
3032 _("cannot emit dynamic relocations in read-only section"),
3033 name, input_bfd, input_section, rel->r_offset);
3034 return FALSE;
3035 }
3036 /* Only output a reloc for a not deleted entry. */
3037 if (offset >= (bfd_vma)-2)
3038 _bfinfdpic_add_dyn_reloc (output_bfd,
3039 bfinfdpic_gotrel_section (info),
3040 0, R_unused0, dynindx, addend, picrel);
3041 else
3042 _bfinfdpic_add_dyn_reloc (output_bfd,
3043 bfinfdpic_gotrel_section (info),
3044 offset
3045 + input_section
3046 ->output_section->vma
3047 + input_section->output_offset,
3048 r_type, dynindx, addend, picrel);
3049 }
3050 else if (osec)
3051 addend += osec->output_section->vma;
3052 /* We want the addend in-place because dynamic
3053 relocations are REL. Setting relocation to it
3054 should arrange for it to be installed. */
3055 relocation = addend - rel->r_addend;
3056 }
3057
3058 if (r_type == R_BFIN_FUNCDESC_VALUE && offset < (bfd_vma)-2)
3059 {
3060 /* If we've omitted the dynamic relocation, just emit
3061 the fixed addresses of the symbol and of the local
3062 GOT base offset. */
3063 if (info->executable && !info->pie
3064 && (!h || BFINFDPIC_SYM_LOCAL (info, h)))
3065 bfd_put_32 (output_bfd,
3066 bfinfdpic_got_section (info)->output_section->vma
3067 + bfinfdpic_got_section (info)->output_offset
3068 + bfinfdpic_got_initial_offset (info),
3069 contents + rel->r_offset + 4);
3070 else
3071 /* A function descriptor used for lazy or local
3072 resolving is initialized such that its high word
3073 contains the output section index in which the
3074 PLT entries are located, and the low word
3075 contains the offset of the lazy PLT entry entry
3076 point into that section. */
3077 bfd_put_32 (output_bfd,
3078 h && ! BFINFDPIC_SYM_LOCAL (info, h)
3079 ? 0
3080 : _bfinfdpic_osec_to_segment (output_bfd,
3081 sec
3082 ->output_section),
3083 contents + rel->r_offset + 4);
3084 }
3085 }
3086 check_segment[0] = check_segment[1] = got_segment;
3087 break;
3088
3089 default:
3090 check_segment[0] = isec_segment;
3091 check_segment[1] = sec
3092 ? _bfinfdpic_osec_to_segment (output_bfd, sec->output_section)
3093 : (unsigned)-1;
3094 break;
3095 }
3096
3097 if (check_segment[0] != check_segment[1] && IS_FDPIC (output_bfd))
3098 {
3099 #if 1 /* If you take this out, remove the #error from fdpic-static-6.d
3100 in the ld testsuite. */
3101 /* This helps catch problems in GCC while we can't do more
3102 than static linking. The idea is to test whether the
3103 input file basename is crt0.o only once. */
3104 if (silence_segment_error == 1)
3105 silence_segment_error =
3106 (strlen (input_bfd->filename) == 6
3107 && strcmp (input_bfd->filename, "crt0.o") == 0)
3108 || (strlen (input_bfd->filename) > 6
3109 && strcmp (input_bfd->filename
3110 + strlen (input_bfd->filename) - 7,
3111 "/crt0.o") == 0)
3112 ? -1 : 0;
3113 #endif
3114 if (!silence_segment_error
3115 /* We don't want duplicate errors for undefined
3116 symbols. */
3117 && !(picrel && picrel->symndx == -1
3118 && picrel->d.h->root.type == bfd_link_hash_undefined))
3119 info->callbacks->warning
3120 (info,
3121 (info->shared || info->pie)
3122 ? _("relocations between different segments are not supported")
3123 : _("warning: relocation references a different segment"),
3124 name, input_bfd, input_section, rel->r_offset);
3125 if (!silence_segment_error && (info->shared || info->pie))
3126 return FALSE;
3127 elf_elfheader (output_bfd)->e_flags |= EF_BFIN_PIC;
3128 }
3129
3130 switch (r_type)
3131 {
3132 case R_BFIN_GOTOFFHI:
3133 /* We need the addend to be applied before we shift the
3134 value right. */
3135 relocation += rel->r_addend;
3136 /* Fall through. */
3137 case R_BFIN_GOTHI:
3138 case R_BFIN_FUNCDESC_GOTHI:
3139 case R_BFIN_FUNCDESC_GOTOFFHI:
3140 relocation >>= 16;
3141 /* Fall through. */
3142
3143 case R_BFIN_GOTLO:
3144 case R_BFIN_FUNCDESC_GOTLO:
3145 case R_BFIN_GOTOFFLO:
3146 case R_BFIN_FUNCDESC_GOTOFFLO:
3147 relocation &= 0xffff;
3148 break;
3149
3150 default:
3151 break;
3152 }
3153
3154 switch (r_type)
3155 {
3156 case R_pcrel24:
3157 case R_pcrel24_jump_l:
3158 if (! IS_FDPIC (output_bfd) || ! picrel->plt)
3159 break;
3160 /* Fall through. */
3161
3162 /* When referencing a GOT entry, a function descriptor or a
3163 PLT, we don't want the addend to apply to the reference,
3164 but rather to the referenced symbol. The actual entry
3165 will have already been created taking the addend into
3166 account, so cancel it out here. */
3167 case R_BFIN_GOT17M4:
3168 case R_BFIN_GOTHI:
3169 case R_BFIN_GOTLO:
3170 case R_BFIN_FUNCDESC_GOT17M4:
3171 case R_BFIN_FUNCDESC_GOTHI:
3172 case R_BFIN_FUNCDESC_GOTLO:
3173 case R_BFIN_FUNCDESC_GOTOFF17M4:
3174 case R_BFIN_FUNCDESC_GOTOFFHI:
3175 case R_BFIN_FUNCDESC_GOTOFFLO:
3176 /* Note that we only want GOTOFFHI, not GOTOFFLO or GOTOFF17M4
3177 here, since we do want to apply the addend to the others.
3178 Note that we've applied the addend to GOTOFFHI before we
3179 shifted it right. */
3180 case R_BFIN_GOTOFFHI:
3181 relocation -= rel->r_addend;
3182 break;
3183
3184 default:
3185 break;
3186 }
3187
3188 r = bfin_final_link_relocate (rel, howto, input_bfd, input_section,
3189 contents, rel->r_offset,
3190 relocation, rel->r_addend);
3191
3192 if (r != bfd_reloc_ok)
3193 {
3194 const char * msg = (const char *) NULL;
3195
3196 switch (r)
3197 {
3198 case bfd_reloc_overflow:
3199 r = info->callbacks->reloc_overflow
3200 (info, (h ? &h->root : NULL), name, howto->name,
3201 (bfd_vma) 0, input_bfd, input_section, rel->r_offset);
3202 break;
3203
3204 case bfd_reloc_undefined:
3205 r = info->callbacks->undefined_symbol
3206 (info, name, input_bfd, input_section, rel->r_offset, TRUE);
3207 break;
3208
3209 case bfd_reloc_outofrange:
3210 msg = _("internal error: out of range error");
3211 break;
3212
3213 case bfd_reloc_notsupported:
3214 msg = _("internal error: unsupported relocation error");
3215 break;
3216
3217 case bfd_reloc_dangerous:
3218 msg = _("internal error: dangerous relocation");
3219 break;
3220
3221 default:
3222 msg = _("internal error: unknown error");
3223 break;
3224 }
3225
3226 if (msg)
3227 r = info->callbacks->warning
3228 (info, msg, name, input_bfd, input_section, rel->r_offset);
3229
3230 if (! r)
3231 return FALSE;
3232 }
3233 }
3234
3235 return TRUE;
3236 }
3237
3238 /* Update the relocation information for the relocations of the section
3239 being removed. */
3240
3241 static bfd_boolean
3242 bfinfdpic_gc_sweep_hook (bfd *abfd,
3243 struct bfd_link_info *info,
3244 asection *sec,
3245 const Elf_Internal_Rela *relocs)
3246 {
3247 Elf_Internal_Shdr *symtab_hdr;
3248 struct elf_link_hash_entry **sym_hashes, **sym_hashes_end;
3249 const Elf_Internal_Rela *rel;
3250 const Elf_Internal_Rela *rel_end;
3251 struct bfinfdpic_relocs_info *picrel;
3252
3253 BFD_ASSERT (IS_FDPIC (abfd));
3254
3255 symtab_hdr = &elf_tdata (abfd)->symtab_hdr;
3256 sym_hashes = elf_sym_hashes (abfd);
3257 sym_hashes_end = sym_hashes + symtab_hdr->sh_size/sizeof(Elf32_External_Sym);
3258 if (!elf_bad_symtab (abfd))
3259 sym_hashes_end -= symtab_hdr->sh_info;
3260
3261 rel_end = relocs + sec->reloc_count;
3262 for (rel = relocs; rel < rel_end; rel++)
3263 {
3264 struct elf_link_hash_entry *h;
3265 unsigned long r_symndx;
3266
3267 r_symndx = ELF32_R_SYM (rel->r_info);
3268 if (r_symndx < symtab_hdr->sh_info)
3269 h = NULL;
3270 else
3271 h = sym_hashes[r_symndx - symtab_hdr->sh_info];
3272
3273 if (h != NULL)
3274 picrel = bfinfdpic_relocs_info_for_global (bfinfdpic_relocs_info (info),
3275 abfd, h,
3276 rel->r_addend, NO_INSERT);
3277 else
3278 picrel = bfinfdpic_relocs_info_for_local (bfinfdpic_relocs_info
3279 (info), abfd, r_symndx,
3280 rel->r_addend, NO_INSERT);
3281
3282 if (!picrel)
3283 return TRUE;
3284
3285 switch (ELF32_R_TYPE (rel->r_info))
3286 {
3287 case R_pcrel24:
3288 case R_pcrel24_jump_l:
3289 picrel->call--;
3290 break;
3291
3292 case R_BFIN_FUNCDESC_VALUE:
3293 picrel->relocsfdv--;
3294 if (bfd_get_section_flags (abfd, sec) & SEC_ALLOC)
3295 picrel->relocs32++;
3296 /* Fall through. */
3297
3298 case R_byte4_data:
3299 picrel->sym--;
3300 if (bfd_get_section_flags (abfd, sec) & SEC_ALLOC)
3301 picrel->relocs32--;
3302 break;
3303
3304 case R_BFIN_GOT17M4:
3305 picrel->got17m4--;
3306 break;
3307
3308 case R_BFIN_GOTHI:
3309 case R_BFIN_GOTLO:
3310 picrel->gothilo--;
3311 break;
3312
3313 case R_BFIN_FUNCDESC_GOT17M4:
3314 picrel->fdgot17m4--;
3315 break;
3316
3317 case R_BFIN_FUNCDESC_GOTHI:
3318 case R_BFIN_FUNCDESC_GOTLO:
3319 picrel->fdgothilo--;
3320 break;
3321
3322 case R_BFIN_GOTOFF17M4:
3323 case R_BFIN_GOTOFFHI:
3324 case R_BFIN_GOTOFFLO:
3325 picrel->gotoff--;
3326 break;
3327
3328 case R_BFIN_FUNCDESC_GOTOFF17M4:
3329 picrel->fdgoff17m4--;
3330 break;
3331
3332 case R_BFIN_FUNCDESC_GOTOFFHI:
3333 case R_BFIN_FUNCDESC_GOTOFFLO:
3334 picrel->fdgoffhilo--;
3335 break;
3336
3337 case R_BFIN_FUNCDESC:
3338 picrel->fd--;
3339 picrel->relocsfd--;
3340 break;
3341
3342 default:
3343 break;
3344 }
3345 }
3346
3347 return TRUE;
3348 }
3349
3350 /* We need dynamic symbols for every section, since segments can
3351 relocate independently. */
3352 static bfd_boolean
3353 _bfinfdpic_link_omit_section_dynsym (bfd *output_bfd ATTRIBUTE_UNUSED,
3354 struct bfd_link_info *info ATTRIBUTE_UNUSED,
3355 asection *p)
3356 {
3357 switch (elf_section_data (p)->this_hdr.sh_type)
3358 {
3359 case SHT_PROGBITS:
3360 case SHT_NOBITS:
3361 /* If sh_type is yet undecided, assume it could be
3362 SHT_PROGBITS/SHT_NOBITS. */
3363 case SHT_NULL:
3364 return FALSE;
3365
3366 /* There shouldn't be section relative relocations
3367 against any other section. */
3368 default:
3369 return TRUE;
3370 }
3371 }
3372
3373 /* Create a .got section, as well as its additional info field. This
3374 is almost entirely copied from
3375 elflink.c:_bfd_elf_create_got_section(). */
3376
3377 static bfd_boolean
3378 _bfin_create_got_section (bfd *abfd, struct bfd_link_info *info)
3379 {
3380 flagword flags, pltflags;
3381 asection *s;
3382 struct elf_link_hash_entry *h;
3383 const struct elf_backend_data *bed = get_elf_backend_data (abfd);
3384 int ptralign;
3385 int offset;
3386
3387 /* This function may be called more than once. */
3388 s = bfd_get_section_by_name (abfd, ".got");
3389 if (s != NULL && (s->flags & SEC_LINKER_CREATED) != 0)
3390 return TRUE;
3391
3392 /* Machine specific: although pointers are 32-bits wide, we want the
3393 GOT to be aligned to a 64-bit boundary, such that function
3394 descriptors in it can be accessed with 64-bit loads and
3395 stores. */
3396 ptralign = 3;
3397
3398 flags = (SEC_ALLOC | SEC_LOAD | SEC_HAS_CONTENTS | SEC_IN_MEMORY
3399 | SEC_LINKER_CREATED);
3400 pltflags = flags;
3401
3402 s = bfd_make_section_with_flags (abfd, ".got", flags);
3403 if (s == NULL
3404 || !bfd_set_section_alignment (abfd, s, ptralign))
3405 return FALSE;
3406
3407 if (bed->want_got_plt)
3408 {
3409 s = bfd_make_section_with_flags (abfd, ".got.plt", flags);
3410 if (s == NULL
3411 || !bfd_set_section_alignment (abfd, s, ptralign))
3412 return FALSE;
3413 }
3414
3415 if (bed->want_got_sym)
3416 {
3417 /* Define the symbol _GLOBAL_OFFSET_TABLE_ at the start of the .got
3418 (or .got.plt) section. We don't do this in the linker script
3419 because we don't want to define the symbol if we are not creating
3420 a global offset table. */
3421 h = _bfd_elf_define_linkage_sym (abfd, info, s, "__GLOBAL_OFFSET_TABLE_");
3422 elf_hash_table (info)->hgot = h;
3423 if (h == NULL)
3424 return FALSE;
3425
3426 /* Machine-specific: we want the symbol for executables as
3427 well. */
3428 if (! bfd_elf_link_record_dynamic_symbol (info, h))
3429 return FALSE;
3430 }
3431
3432 /* The first bit of the global offset table is the header. */
3433 s->size += bed->got_header_size;
3434
3435 /* This is the machine-specific part. Create and initialize section
3436 data for the got. */
3437 if (IS_FDPIC (abfd))
3438 {
3439 bfinfdpic_got_section (info) = s;
3440 bfinfdpic_relocs_info (info) = htab_try_create (1,
3441 bfinfdpic_relocs_info_hash,
3442 bfinfdpic_relocs_info_eq,
3443 (htab_del) NULL);
3444 if (! bfinfdpic_relocs_info (info))
3445 return FALSE;
3446
3447 s = bfd_make_section_with_flags (abfd, ".rel.got",
3448 (flags | SEC_READONLY));
3449 if (s == NULL
3450 || ! bfd_set_section_alignment (abfd, s, 2))
3451 return FALSE;
3452
3453 bfinfdpic_gotrel_section (info) = s;
3454
3455 /* Machine-specific. */
3456 s = bfd_make_section_with_flags (abfd, ".rofixup",
3457 (flags | SEC_READONLY));
3458 if (s == NULL
3459 || ! bfd_set_section_alignment (abfd, s, 2))
3460 return FALSE;
3461
3462 bfinfdpic_gotfixup_section (info) = s;
3463 offset = -2048;
3464 flags = BSF_GLOBAL;
3465 }
3466 else
3467 {
3468 offset = 2048;
3469 flags = BSF_GLOBAL | BSF_WEAK;
3470 }
3471
3472 return TRUE;
3473 }
3474
3475 /* Make sure the got and plt sections exist, and that our pointers in
3476 the link hash table point to them. */
3477
3478 static bfd_boolean
3479 elf32_bfinfdpic_create_dynamic_sections (bfd *abfd, struct bfd_link_info *info)
3480 {
3481 /* This is mostly copied from
3482 elflink.c:_bfd_elf_create_dynamic_sections(). */
3483 flagword flags, pltflags;
3484 asection *s;
3485 const struct elf_backend_data *bed = get_elf_backend_data (abfd);
3486
3487 /* We need to create .plt, .rel[a].plt, .got, .got.plt, .dynbss, and
3488 .rel[a].bss sections. */
3489
3490 flags = (SEC_ALLOC | SEC_LOAD | SEC_HAS_CONTENTS | SEC_IN_MEMORY
3491 | SEC_LINKER_CREATED);
3492
3493 pltflags = flags;
3494 pltflags |= SEC_CODE;
3495 if (bed->plt_not_loaded)
3496 pltflags &= ~ (SEC_CODE | SEC_LOAD | SEC_HAS_CONTENTS);
3497 if (bed->plt_readonly)