1 /* MSP430-specific support for 32-bit ELF
2 Copyright (C) 2002-2020 Free Software Foundation, Inc.
3 Contributed by Dmitry Diky <diwil@mail.ru>
5 This file is part of BFD, the Binary File Descriptor library.
7 This program is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 3 of the License, or
10 (at your option) any later version.
12 This program is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
17 You should have received a copy of the GNU General Public License
18 along with this program; if not, write to the Free Software
19 Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
20 MA 02110-1301, USA. */
24 #include "libiberty.h"
27 #include "elf/msp430.h"
29 static bfd_boolean debug_relocs
= 0;
31 /* All users of this file have bfd_octets_per_byte (abfd, sec) == 1. */
32 #define OCTETS_PER_BYTE(ABFD, SEC) 1
34 static bfd_reloc_status_type
35 rl78_sym_diff_handler (bfd
* abfd
,
37 asymbol
* sym ATTRIBUTE_UNUSED
,
38 void * addr ATTRIBUTE_UNUSED
,
40 bfd
* out_bfd ATTRIBUTE_UNUSED
,
41 char ** error_message ATTRIBUTE_UNUSED
)
44 octets
= reloc
->address
* OCTETS_PER_BYTE (abfd
, input_sec
);
46 /* Catch the case where bfd_install_relocation would return
47 bfd_reloc_outofrange because the SYM_DIFF reloc is being used in a very
48 small section. It does not actually matter if this happens because all
49 that SYM_DIFF does is compute a (4-byte) value. A second reloc then uses
50 this value, and it is that reloc that must fit into the section.
52 This happens in eg, gcc/testsuite/gcc.c-torture/compile/labels-3.c. */
53 if ((octets
+ bfd_get_reloc_size (reloc
->howto
))
54 > bfd_get_section_limit_octets (abfd
, input_sec
))
56 return bfd_reloc_continue
;
59 static reloc_howto_type elf_msp430_howto_table
[] =
61 HOWTO (R_MSP430_NONE
, /* type */
63 3, /* size (0 = byte, 1 = short, 2 = long) */
65 FALSE
, /* pc_relative */
67 complain_overflow_dont
,/* complain_on_overflow */
68 bfd_elf_generic_reloc
, /* special_function */
69 "R_MSP430_NONE", /* name */
70 FALSE
, /* partial_inplace */
73 FALSE
), /* pcrel_offset */
75 HOWTO (R_MSP430_32
, /* type */
77 2, /* size (0 = byte, 1 = short, 2 = long) */
79 FALSE
, /* pc_relative */
81 complain_overflow_bitfield
,/* complain_on_overflow */
82 bfd_elf_generic_reloc
, /* special_function */
83 "R_MSP430_32", /* name */
84 FALSE
, /* partial_inplace */
85 0xffffffff, /* src_mask */
86 0xffffffff, /* dst_mask */
87 FALSE
), /* pcrel_offset */
89 /* A 10 bit PC relative relocation. */
90 HOWTO (R_MSP430_10_PCREL
, /* type */
92 1, /* size (0 = byte, 1 = short, 2 = long) */
94 TRUE
, /* pc_relative */
96 complain_overflow_bitfield
,/* complain_on_overflow */
97 bfd_elf_generic_reloc
, /* special_function */
98 "R_MSP430_10_PCREL", /* name */
99 FALSE
, /* partial_inplace */
100 0x3ff, /* src_mask */
101 0x3ff, /* dst_mask */
102 TRUE
), /* pcrel_offset */
104 /* A 16 bit absolute relocation. */
105 HOWTO (R_MSP430_16
, /* type */
107 1, /* size (0 = byte, 1 = short, 2 = long) */
109 FALSE
, /* pc_relative */
111 complain_overflow_dont
,/* complain_on_overflow */
112 bfd_elf_generic_reloc
, /* special_function */
113 "R_MSP430_16", /* name */
114 FALSE
, /* partial_inplace */
116 0xffff, /* dst_mask */
117 FALSE
), /* pcrel_offset */
119 /* A 16 bit PC relative relocation for command address. */
120 HOWTO (R_MSP430_16_PCREL
, /* type */
122 1, /* size (0 = byte, 1 = short, 2 = long) */
124 TRUE
, /* pc_relative */
126 complain_overflow_dont
,/* complain_on_overflow */
127 bfd_elf_generic_reloc
, /* special_function */
128 "R_MSP430_16_PCREL", /* name */
129 FALSE
, /* partial_inplace */
131 0xffff, /* dst_mask */
132 TRUE
), /* pcrel_offset */
134 /* A 16 bit absolute relocation, byte operations. */
135 HOWTO (R_MSP430_16_BYTE
, /* type */
137 1, /* size (0 = byte, 1 = short, 2 = long) */
139 FALSE
, /* pc_relative */
141 complain_overflow_dont
,/* complain_on_overflow */
142 bfd_elf_generic_reloc
, /* special_function */
143 "R_MSP430_16_BYTE", /* name */
144 FALSE
, /* partial_inplace */
145 0xffff, /* src_mask */
146 0xffff, /* dst_mask */
147 FALSE
), /* pcrel_offset */
149 /* A 16 bit absolute relocation for command address. */
150 HOWTO (R_MSP430_16_PCREL_BYTE
,/* type */
152 1, /* size (0 = byte, 1 = short, 2 = long) */
154 TRUE
, /* pc_relative */
156 complain_overflow_dont
,/* complain_on_overflow */
157 bfd_elf_generic_reloc
, /* special_function */
158 "R_MSP430_16_PCREL_BYTE",/* name */
159 FALSE
, /* partial_inplace */
160 0xffff, /* src_mask */
161 0xffff, /* dst_mask */
162 TRUE
), /* pcrel_offset */
164 /* A 10 bit PC relative relocation for complicated polymorphs. */
165 HOWTO (R_MSP430_2X_PCREL
, /* type */
167 2, /* size (0 = byte, 1 = short, 2 = long) */
169 TRUE
, /* pc_relative */
171 complain_overflow_bitfield
,/* complain_on_overflow */
172 bfd_elf_generic_reloc
, /* special_function */
173 "R_MSP430_2X_PCREL", /* name */
174 FALSE
, /* partial_inplace */
175 0x3ff, /* src_mask */
176 0x3ff, /* dst_mask */
177 TRUE
), /* pcrel_offset */
179 /* A 16 bit relaxable relocation for command address. */
180 HOWTO (R_MSP430_RL_PCREL
, /* type */
182 1, /* size (0 = byte, 1 = short, 2 = long) */
184 TRUE
, /* pc_relative */
186 complain_overflow_dont
,/* complain_on_overflow */
187 bfd_elf_generic_reloc
, /* special_function */
188 "R_MSP430_RL_PCREL", /* name */
189 FALSE
, /* partial_inplace */
191 0xffff, /* dst_mask */
192 TRUE
) /* pcrel_offset */
194 /* A 8-bit absolute relocation. */
195 , HOWTO (R_MSP430_8
, /* type */
197 0, /* size (0 = byte, 1 = short, 2 = long) */
199 FALSE
, /* pc_relative */
201 complain_overflow_dont
,/* complain_on_overflow */
202 bfd_elf_generic_reloc
, /* special_function */
203 "R_MSP430_8", /* name */
204 FALSE
, /* partial_inplace */
206 0xffff, /* dst_mask */
207 FALSE
), /* pcrel_offset */
209 /* Together with a following reloc, allows for the difference
210 between two symbols to be the real addend of the second reloc. */
211 HOWTO (R_MSP430_SYM_DIFF
, /* type */
213 2, /* size (0 = byte, 1 = short, 2 = long) */
215 FALSE
, /* pc_relative */
217 complain_overflow_dont
,/* complain_on_overflow */
218 rl78_sym_diff_handler
, /* special handler. */
219 "R_MSP430_SYM_DIFF", /* name */
220 FALSE
, /* partial_inplace */
221 0xffffffff, /* src_mask */
222 0xffffffff, /* dst_mask */
223 FALSE
) /* pcrel_offset */
226 static reloc_howto_type elf_msp430x_howto_table
[] =
228 HOWTO (R_MSP430_NONE
, /* type */
230 3, /* size (0 = byte, 1 = short, 2 = long) */
232 FALSE
, /* pc_relative */
234 complain_overflow_dont
,/* complain_on_overflow */
235 bfd_elf_generic_reloc
, /* special_function */
236 "R_MSP430_NONE", /* name */
237 FALSE
, /* partial_inplace */
240 FALSE
), /* pcrel_offset */
242 HOWTO (R_MSP430_ABS32
, /* type */
244 2, /* size (0 = byte, 1 = short, 2 = long) */
246 FALSE
, /* pc_relative */
248 complain_overflow_bitfield
,/* complain_on_overflow */
249 bfd_elf_generic_reloc
, /* special_function */
250 "R_MSP430_ABS32", /* name */
251 FALSE
, /* partial_inplace */
252 0xffffffff, /* src_mask */
253 0xffffffff, /* dst_mask */
254 FALSE
), /* pcrel_offset */
256 HOWTO (R_MSP430_ABS16
, /* type */
258 1, /* size (0 = byte, 1 = short, 2 = long) */
260 FALSE
, /* pc_relative */
262 complain_overflow_dont
,/* complain_on_overflow */
263 bfd_elf_generic_reloc
, /* special_function */
264 "R_MSP430_ABS16", /* name */
265 FALSE
, /* partial_inplace */
267 0xffff, /* dst_mask */
268 FALSE
), /* pcrel_offset */
270 HOWTO (R_MSP430_ABS8
, /* type */
272 0, /* size (0 = byte, 1 = short, 2 = long) */
274 FALSE
, /* pc_relative */
276 complain_overflow_bitfield
,/* complain_on_overflow */
277 bfd_elf_generic_reloc
, /* special_function */
278 "R_MSP430_ABS8", /* name */
279 FALSE
, /* partial_inplace */
282 FALSE
), /* pcrel_offset */
284 HOWTO (R_MSP430_PCR16
, /* type */
286 1, /* size (0 = byte, 1 = short, 2 = long) */
288 TRUE
, /* pc_relative */
290 complain_overflow_dont
,/* complain_on_overflow */
291 bfd_elf_generic_reloc
, /* special_function */
292 "R_MSP430_PCR16", /* name */
293 FALSE
, /* partial_inplace */
295 0xffff, /* dst_mask */
296 TRUE
), /* pcrel_offset */
298 HOWTO (R_MSP430X_PCR20_EXT_SRC
,/* type */
300 2, /* size (0 = byte, 1 = short, 2 = long) */
302 TRUE
, /* pc_relative */
304 complain_overflow_dont
,/* complain_on_overflow */
305 bfd_elf_generic_reloc
, /* special_function */
306 "R_MSP430X_PCR20_EXT_SRC",/* name */
307 FALSE
, /* partial_inplace */
309 0xffff, /* dst_mask */
310 TRUE
), /* pcrel_offset */
312 HOWTO (R_MSP430X_PCR20_EXT_DST
,/* type */
314 2, /* size (0 = byte, 1 = short, 2 = long) */
316 TRUE
, /* pc_relative */
318 complain_overflow_dont
,/* complain_on_overflow */
319 bfd_elf_generic_reloc
, /* special_function */
320 "R_MSP430X_PCR20_EXT_DST",/* name */
321 FALSE
, /* partial_inplace */
323 0xffff, /* dst_mask */
324 TRUE
), /* pcrel_offset */
326 HOWTO (R_MSP430X_PCR20_EXT_ODST
,/* type */
328 2, /* size (0 = byte, 1 = short, 2 = long) */
330 TRUE
, /* pc_relative */
332 complain_overflow_dont
,/* complain_on_overflow */
333 bfd_elf_generic_reloc
, /* special_function */
334 "R_MSP430X_PCR20_EXT_ODST",/* name */
335 FALSE
, /* partial_inplace */
337 0xffff, /* dst_mask */
338 TRUE
), /* pcrel_offset */
340 HOWTO (R_MSP430X_ABS20_EXT_SRC
,/* type */
342 2, /* size (0 = byte, 1 = short, 2 = long) */
344 TRUE
, /* pc_relative */
346 complain_overflow_dont
,/* complain_on_overflow */
347 bfd_elf_generic_reloc
, /* special_function */
348 "R_MSP430X_ABS20_EXT_SRC",/* name */
349 FALSE
, /* partial_inplace */
351 0xffff, /* dst_mask */
352 TRUE
), /* pcrel_offset */
354 HOWTO (R_MSP430X_ABS20_EXT_DST
,/* type */
356 2, /* size (0 = byte, 1 = short, 2 = long) */
358 TRUE
, /* pc_relative */
360 complain_overflow_dont
,/* complain_on_overflow */
361 bfd_elf_generic_reloc
, /* special_function */
362 "R_MSP430X_ABS20_EXT_DST",/* name */
363 FALSE
, /* partial_inplace */
365 0xffff, /* dst_mask */
366 TRUE
), /* pcrel_offset */
368 HOWTO (R_MSP430X_ABS20_EXT_ODST
,/* type */
370 2, /* size (0 = byte, 1 = short, 2 = long) */
372 TRUE
, /* pc_relative */
374 complain_overflow_dont
,/* complain_on_overflow */
375 bfd_elf_generic_reloc
, /* special_function */
376 "R_MSP430X_ABS20_EXT_ODST",/* name */
377 FALSE
, /* partial_inplace */
379 0xffff, /* dst_mask */
380 TRUE
), /* pcrel_offset */
382 HOWTO (R_MSP430X_ABS20_ADR_SRC
,/* type */
384 2, /* size (0 = byte, 1 = short, 2 = long) */
386 TRUE
, /* pc_relative */
388 complain_overflow_dont
,/* complain_on_overflow */
389 bfd_elf_generic_reloc
, /* special_function */
390 "R_MSP430X_ABS20_ADR_SRC",/* name */
391 FALSE
, /* partial_inplace */
393 0xffff, /* dst_mask */
394 TRUE
), /* pcrel_offset */
396 HOWTO (R_MSP430X_ABS20_ADR_DST
,/* type */
398 2, /* size (0 = byte, 1 = short, 2 = long) */
400 TRUE
, /* pc_relative */
402 complain_overflow_dont
,/* complain_on_overflow */
403 bfd_elf_generic_reloc
, /* special_function */
404 "R_MSP430X_ABS20_ADR_DST",/* name */
405 FALSE
, /* partial_inplace */
407 0xffff, /* dst_mask */
408 TRUE
), /* pcrel_offset */
410 HOWTO (R_MSP430X_PCR16
, /* type */
412 2, /* size (0 = byte, 1 = short, 2 = long) */
414 TRUE
, /* pc_relative */
416 complain_overflow_dont
,/* complain_on_overflow */
417 bfd_elf_generic_reloc
, /* special_function */
418 "R_MSP430X_PCR16", /* name */
419 FALSE
, /* partial_inplace */
421 0xffff, /* dst_mask */
422 TRUE
), /* pcrel_offset */
424 HOWTO (R_MSP430X_PCR20_CALL
, /* type */
426 2, /* size (0 = byte, 1 = short, 2 = long) */
428 TRUE
, /* pc_relative */
430 complain_overflow_dont
,/* complain_on_overflow */
431 bfd_elf_generic_reloc
, /* special_function */
432 "R_MSP430X_PCR20_CALL",/* name */
433 FALSE
, /* partial_inplace */
435 0xffff, /* dst_mask */
436 TRUE
), /* pcrel_offset */
438 HOWTO (R_MSP430X_ABS16
, /* type */
440 2, /* size (0 = byte, 1 = short, 2 = long) */
442 TRUE
, /* pc_relative */
444 complain_overflow_dont
,/* complain_on_overflow */
445 bfd_elf_generic_reloc
, /* special_function */
446 "R_MSP430X_ABS16", /* name */
447 FALSE
, /* partial_inplace */
449 0xffff, /* dst_mask */
450 TRUE
), /* pcrel_offset */
452 HOWTO (R_MSP430_ABS_HI16
, /* type */
454 2, /* size (0 = byte, 1 = short, 2 = long) */
456 TRUE
, /* pc_relative */
458 complain_overflow_dont
,/* complain_on_overflow */
459 bfd_elf_generic_reloc
, /* special_function */
460 "R_MSP430_ABS_HI16", /* name */
461 FALSE
, /* partial_inplace */
463 0xffff, /* dst_mask */
464 TRUE
), /* pcrel_offset */
466 HOWTO (R_MSP430_PREL31
, /* type */
468 2, /* size (0 = byte, 1 = short, 2 = long) */
470 TRUE
, /* pc_relative */
472 complain_overflow_dont
,/* complain_on_overflow */
473 bfd_elf_generic_reloc
, /* special_function */
474 "R_MSP430_PREL31", /* name */
475 FALSE
, /* partial_inplace */
477 0xffff, /* dst_mask */
478 TRUE
), /* pcrel_offset */
480 EMPTY_HOWTO (R_MSP430_EHTYPE
),
482 /* A 10 bit PC relative relocation. */
483 HOWTO (R_MSP430X_10_PCREL
, /* type */
485 1, /* size (0 = byte, 1 = short, 2 = long) */
487 TRUE
, /* pc_relative */
489 complain_overflow_bitfield
,/* complain_on_overflow */
490 bfd_elf_generic_reloc
, /* special_function */
491 "R_MSP430X_10_PCREL", /* name */
492 FALSE
, /* partial_inplace */
493 0x3ff, /* src_mask */
494 0x3ff, /* dst_mask */
495 TRUE
), /* pcrel_offset */
497 /* A 10 bit PC relative relocation for complicated polymorphs. */
498 HOWTO (R_MSP430X_2X_PCREL
, /* type */
500 2, /* size (0 = byte, 1 = short, 2 = long) */
502 TRUE
, /* pc_relative */
504 complain_overflow_bitfield
,/* complain_on_overflow */
505 bfd_elf_generic_reloc
, /* special_function */
506 "R_MSP430X_2X_PCREL", /* name */
507 FALSE
, /* partial_inplace */
508 0x3ff, /* src_mask */
509 0x3ff, /* dst_mask */
510 TRUE
), /* pcrel_offset */
512 /* Together with a following reloc, allows for the difference
513 between two symbols to be the real addend of the second reloc. */
514 HOWTO (R_MSP430X_SYM_DIFF
, /* type */
516 2, /* size (0 = byte, 1 = short, 2 = long) */
518 FALSE
, /* pc_relative */
520 complain_overflow_dont
,/* complain_on_overflow */
521 rl78_sym_diff_handler
, /* special handler. */
522 "R_MSP430X_SYM_DIFF", /* name */
523 FALSE
, /* partial_inplace */
524 0xffffffff, /* src_mask */
525 0xffffffff, /* dst_mask */
526 FALSE
) /* pcrel_offset */
529 /* Map BFD reloc types to MSP430 ELF reloc types. */
531 struct msp430_reloc_map
533 bfd_reloc_code_real_type bfd_reloc_val
;
534 unsigned int elf_reloc_val
;
537 static const struct msp430_reloc_map msp430_reloc_map
[] =
539 {BFD_RELOC_NONE
, R_MSP430_NONE
},
540 {BFD_RELOC_32
, R_MSP430_32
},
541 {BFD_RELOC_MSP430_10_PCREL
, R_MSP430_10_PCREL
},
542 {BFD_RELOC_16
, R_MSP430_16_BYTE
},
543 {BFD_RELOC_MSP430_16_PCREL
, R_MSP430_16_PCREL
},
544 {BFD_RELOC_MSP430_16
, R_MSP430_16
},
545 {BFD_RELOC_MSP430_16_PCREL_BYTE
, R_MSP430_16_PCREL_BYTE
},
546 {BFD_RELOC_MSP430_16_BYTE
, R_MSP430_16_BYTE
},
547 {BFD_RELOC_MSP430_2X_PCREL
, R_MSP430_2X_PCREL
},
548 {BFD_RELOC_MSP430_RL_PCREL
, R_MSP430_RL_PCREL
},
549 {BFD_RELOC_8
, R_MSP430_8
},
550 {BFD_RELOC_MSP430_SYM_DIFF
, R_MSP430_SYM_DIFF
}
553 static const struct msp430_reloc_map msp430x_reloc_map
[] =
555 {BFD_RELOC_NONE
, R_MSP430_NONE
},
556 {BFD_RELOC_32
, R_MSP430_ABS32
},
557 {BFD_RELOC_16
, R_MSP430_ABS16
},
558 {BFD_RELOC_8
, R_MSP430_ABS8
},
559 {BFD_RELOC_MSP430_ABS8
, R_MSP430_ABS8
},
560 {BFD_RELOC_MSP430X_PCR20_EXT_SRC
, R_MSP430X_PCR20_EXT_SRC
},
561 {BFD_RELOC_MSP430X_PCR20_EXT_DST
, R_MSP430X_PCR20_EXT_DST
},
562 {BFD_RELOC_MSP430X_PCR20_EXT_ODST
, R_MSP430X_PCR20_EXT_ODST
},
563 {BFD_RELOC_MSP430X_ABS20_EXT_SRC
, R_MSP430X_ABS20_EXT_SRC
},
564 {BFD_RELOC_MSP430X_ABS20_EXT_DST
, R_MSP430X_ABS20_EXT_DST
},
565 {BFD_RELOC_MSP430X_ABS20_EXT_ODST
, R_MSP430X_ABS20_EXT_ODST
},
566 {BFD_RELOC_MSP430X_ABS20_ADR_SRC
, R_MSP430X_ABS20_ADR_SRC
},
567 {BFD_RELOC_MSP430X_ABS20_ADR_DST
, R_MSP430X_ABS20_ADR_DST
},
568 {BFD_RELOC_MSP430X_PCR16
, R_MSP430X_PCR16
},
569 {BFD_RELOC_MSP430X_PCR20_CALL
, R_MSP430X_PCR20_CALL
},
570 {BFD_RELOC_MSP430X_ABS16
, R_MSP430X_ABS16
},
571 {BFD_RELOC_MSP430_ABS_HI16
, R_MSP430_ABS_HI16
},
572 {BFD_RELOC_MSP430_PREL31
, R_MSP430_PREL31
},
573 {BFD_RELOC_MSP430_10_PCREL
, R_MSP430X_10_PCREL
},
574 {BFD_RELOC_MSP430_2X_PCREL
, R_MSP430X_2X_PCREL
},
575 {BFD_RELOC_MSP430_RL_PCREL
, R_MSP430X_PCR16
},
576 {BFD_RELOC_MSP430_SYM_DIFF
, R_MSP430X_SYM_DIFF
}
579 static inline bfd_boolean
580 uses_msp430x_relocs (bfd
* abfd
)
582 extern const bfd_target msp430_elf32_ti_vec
;
584 return bfd_get_mach (abfd
) == bfd_mach_msp430x
585 || abfd
->xvec
== & msp430_elf32_ti_vec
;
588 static reloc_howto_type
*
589 bfd_elf32_bfd_reloc_type_lookup (bfd
* abfd ATTRIBUTE_UNUSED
,
590 bfd_reloc_code_real_type code
)
594 if (uses_msp430x_relocs (abfd
))
596 for (i
= ARRAY_SIZE (msp430x_reloc_map
); i
--;)
597 if (msp430x_reloc_map
[i
].bfd_reloc_val
== code
)
598 return elf_msp430x_howto_table
+ msp430x_reloc_map
[i
].elf_reloc_val
;
602 for (i
= 0; i
< ARRAY_SIZE (msp430_reloc_map
); i
++)
603 if (msp430_reloc_map
[i
].bfd_reloc_val
== code
)
604 return &elf_msp430_howto_table
[msp430_reloc_map
[i
].elf_reloc_val
];
610 static reloc_howto_type
*
611 bfd_elf32_bfd_reloc_name_lookup (bfd
*abfd ATTRIBUTE_UNUSED
,
616 if (uses_msp430x_relocs (abfd
))
618 for (i
= ARRAY_SIZE (elf_msp430x_howto_table
); i
--;)
619 if (elf_msp430x_howto_table
[i
].name
!= NULL
620 && strcasecmp (elf_msp430x_howto_table
[i
].name
, r_name
) == 0)
621 return elf_msp430x_howto_table
+ i
;
626 i
< (sizeof (elf_msp430_howto_table
)
627 / sizeof (elf_msp430_howto_table
[0]));
629 if (elf_msp430_howto_table
[i
].name
!= NULL
630 && strcasecmp (elf_msp430_howto_table
[i
].name
, r_name
) == 0)
631 return &elf_msp430_howto_table
[i
];
637 /* Set the howto pointer for an MSP430 ELF reloc. */
640 msp430_info_to_howto_rela (bfd
* abfd
,
642 Elf_Internal_Rela
* dst
)
646 r_type
= ELF32_R_TYPE (dst
->r_info
);
648 if (uses_msp430x_relocs (abfd
))
650 if (r_type
>= (unsigned int) R_MSP430x_max
)
652 /* xgettext:c-format */
653 _bfd_error_handler (_("%pB: unsupported relocation type %#x"),
655 bfd_set_error (bfd_error_bad_value
);
658 cache_ptr
->howto
= elf_msp430x_howto_table
+ r_type
;
660 else if (r_type
>= (unsigned int) R_MSP430_max
)
662 /* xgettext:c-format */
663 _bfd_error_handler (_("%pB: unsupported relocation type %#x"),
665 bfd_set_error (bfd_error_bad_value
);
669 cache_ptr
->howto
= &elf_msp430_howto_table
[r_type
];
674 /* Look through the relocs for a section during the first phase.
675 Since we don't do .gots or .plts, we just need to consider the
676 virtual table relocs for gc. */
679 elf32_msp430_check_relocs (bfd
* abfd
, struct bfd_link_info
* info
,
680 asection
* sec
, const Elf_Internal_Rela
* relocs
)
682 Elf_Internal_Shdr
*symtab_hdr
;
683 struct elf_link_hash_entry
**sym_hashes
;
684 const Elf_Internal_Rela
*rel
;
685 const Elf_Internal_Rela
*rel_end
;
687 if (bfd_link_relocatable (info
))
690 symtab_hdr
= &elf_tdata (abfd
)->symtab_hdr
;
691 sym_hashes
= elf_sym_hashes (abfd
);
693 rel_end
= relocs
+ sec
->reloc_count
;
694 for (rel
= relocs
; rel
< rel_end
; rel
++)
696 struct elf_link_hash_entry
*h
;
697 unsigned long r_symndx
;
699 r_symndx
= ELF32_R_SYM (rel
->r_info
);
700 if (r_symndx
< symtab_hdr
->sh_info
)
704 h
= sym_hashes
[r_symndx
- symtab_hdr
->sh_info
];
705 while (h
->root
.type
== bfd_link_hash_indirect
706 || h
->root
.type
== bfd_link_hash_warning
)
707 h
= (struct elf_link_hash_entry
*) h
->root
.u
.i
.link
;
714 /* Perform a single relocation. By default we use the standard BFD
715 routines, but a few relocs, we have to do them ourselves. */
717 static bfd_reloc_status_type
718 msp430_final_link_relocate (reloc_howto_type
* howto
,
720 asection
* input_section
,
722 Elf_Internal_Rela
* rel
,
724 struct bfd_link_info
* info
)
726 static asection
* sym_diff_section
;
727 static bfd_vma sym_diff_value
;
729 struct bfd_elf_section_data
* esd
= elf_section_data (input_section
);
730 bfd_reloc_status_type r
= bfd_reloc_ok
;
733 bfd_boolean is_rel_reloc
= FALSE
;
735 if (uses_msp430x_relocs (input_bfd
))
737 /* See if we have a REL type relocation. */
738 is_rel_reloc
= (esd
->rel
.hdr
!= NULL
);
739 /* Sanity check - only one type of relocation per section.
740 FIXME: Theoretically it is possible to have both types,
741 but if that happens how can we distinguish between the two ? */
742 BFD_ASSERT (! is_rel_reloc
|| ! esd
->rela
.hdr
);
743 /* If we are using a REL relocation then the addend should be empty. */
744 BFD_ASSERT (! is_rel_reloc
|| rel
->r_addend
== 0);
748 printf ("writing relocation (%p) at 0x%lx type: %d\n", rel
,
749 (long) (input_section
->output_section
->vma
+ input_section
->output_offset
750 + rel
->r_offset
), howto
->type
);
751 if (sym_diff_section
!= NULL
)
753 BFD_ASSERT (sym_diff_section
== input_section
);
755 if (uses_msp430x_relocs (input_bfd
))
759 /* If we are computing a 32-bit value for the location lists
760 and the result is 0 then we add one to the value. A zero
761 value can result because of linker relaxation deleteing
762 prologue instructions and using a value of 1 (for the begin
763 and end offsets in the location list entry) results in a
764 nul entry which does not prevent the following entries from
766 if (relocation
== sym_diff_value
767 && strcmp (input_section
->name
, ".debug_loc") == 0)
771 case R_MSP430X_ABS16
:
773 BFD_ASSERT (! is_rel_reloc
);
774 relocation
-= sym_diff_value
;
778 return bfd_reloc_dangerous
;
785 case R_MSP430_16_BYTE
:
787 relocation
-= sym_diff_value
;
791 return bfd_reloc_dangerous
;
794 sym_diff_section
= NULL
;
797 if (uses_msp430x_relocs (input_bfd
))
800 case R_MSP430X_SYM_DIFF
:
801 /* Cache the input section and value.
802 The offset is unreliable, since relaxation may
803 have reduced the following reloc's offset. */
804 BFD_ASSERT (! is_rel_reloc
);
805 sym_diff_section
= input_section
;
806 sym_diff_value
= relocation
;
810 contents
+= rel
->r_offset
;
811 srel
= (bfd_signed_vma
) relocation
;
813 srel
+= bfd_get_16 (input_bfd
, contents
);
815 srel
+= rel
->r_addend
;
816 bfd_put_16 (input_bfd
, srel
& 0xffff, contents
);
819 case R_MSP430X_10_PCREL
:
820 contents
+= rel
->r_offset
;
821 srel
= (bfd_signed_vma
) relocation
;
823 srel
+= bfd_get_16 (input_bfd
, contents
) & 0x3ff;
825 srel
+= rel
->r_addend
;
826 srel
-= rel
->r_offset
;
827 srel
-= 2; /* Branch instructions add 2 to the PC... */
828 srel
-= (input_section
->output_section
->vma
+
829 input_section
->output_offset
);
831 return bfd_reloc_outofrange
;
833 /* MSP430 addresses commands as words. */
836 /* Check for an overflow. */
837 if (srel
< -512 || srel
> 511)
839 if (info
->disable_target_specific_optimizations
< 0)
841 static bfd_boolean warned
= FALSE
;
844 info
->callbacks
->warning
846 _("try enabling relaxation to avoid relocation truncations"),
847 NULL
, input_bfd
, input_section
, relocation
);
851 return bfd_reloc_overflow
;
854 x
= bfd_get_16 (input_bfd
, contents
);
855 x
= (x
& 0xfc00) | (srel
& 0x3ff);
856 bfd_put_16 (input_bfd
, x
, contents
);
859 case R_MSP430X_PCR20_EXT_ODST
:
860 /* [0,4]+[48,16] = ---F ---- ---- FFFF */
861 contents
+= rel
->r_offset
;
862 srel
= (bfd_signed_vma
) relocation
;
866 addend
= (bfd_get_16 (input_bfd
, contents
) & 0xf) << 16;
867 addend
|= bfd_get_16 (input_bfd
, contents
+ 6);
872 srel
+= rel
->r_addend
;
873 srel
-= rel
->r_offset
;
874 srel
-= (input_section
->output_section
->vma
+
875 input_section
->output_offset
);
876 bfd_put_16 (input_bfd
, (srel
& 0xffff), contents
+ 6);
877 x
= bfd_get_16 (input_bfd
, contents
);
878 x
= (x
& 0xfff0) | ((srel
>> 16) & 0xf);
879 bfd_put_16 (input_bfd
, x
, contents
);
882 case R_MSP430X_ABS20_EXT_SRC
:
883 /* [7,4]+[32,16] = -78- ---- FFFF */
884 contents
+= rel
->r_offset
;
885 srel
= (bfd_signed_vma
) relocation
;
889 addend
= (bfd_get_16 (input_bfd
, contents
) & 0x0780) << 9;
890 addend
|= bfd_get_16 (input_bfd
, contents
+ 4);
894 srel
+= rel
->r_addend
;
895 bfd_put_16 (input_bfd
, (srel
& 0xffff), contents
+ 4);
897 x
= bfd_get_16 (input_bfd
, contents
);
898 x
= (x
& 0xf87f) | ((srel
<< 7) & 0x0780);
899 bfd_put_16 (input_bfd
, x
, contents
);
902 case R_MSP430_16_PCREL
:
903 contents
+= rel
->r_offset
;
904 srel
= (bfd_signed_vma
) relocation
;
906 srel
+= bfd_get_16 (input_bfd
, contents
);
908 srel
+= rel
->r_addend
;
909 srel
-= rel
->r_offset
;
910 /* Only branch instructions add 2 to the PC... */
911 srel
-= (input_section
->output_section
->vma
+
912 input_section
->output_offset
);
914 return bfd_reloc_outofrange
;
915 bfd_put_16 (input_bfd
, srel
& 0xffff, contents
);
918 case R_MSP430X_PCR20_EXT_DST
:
919 /* [0,4]+[32,16] = ---F ---- FFFF */
920 contents
+= rel
->r_offset
;
921 srel
= (bfd_signed_vma
) relocation
;
925 addend
= (bfd_get_16 (input_bfd
, contents
) & 0xf) << 16;
926 addend
|= bfd_get_16 (input_bfd
, contents
+ 4);
930 srel
+= rel
->r_addend
;
931 srel
-= rel
->r_offset
;
932 srel
-= (input_section
->output_section
->vma
+
933 input_section
->output_offset
);
934 bfd_put_16 (input_bfd
, (srel
& 0xffff), contents
+ 4);
936 x
= bfd_get_16 (input_bfd
, contents
);
937 x
= (x
& 0xfff0) | (srel
& 0xf);
938 bfd_put_16 (input_bfd
, x
, contents
);
941 case R_MSP430X_PCR20_EXT_SRC
:
942 /* [7,4]+[32,16] = -78- ---- FFFF */
943 contents
+= rel
->r_offset
;
944 srel
= (bfd_signed_vma
) relocation
;
948 addend
= ((bfd_get_16 (input_bfd
, contents
) & 0x0780) << 9);
949 addend
|= bfd_get_16 (input_bfd
, contents
+ 4);
953 srel
+= rel
->r_addend
;
954 srel
-= rel
->r_offset
;
955 /* Only branch instructions add 2 to the PC... */
956 srel
-= (input_section
->output_section
->vma
+
957 input_section
->output_offset
);
958 bfd_put_16 (input_bfd
, (srel
& 0xffff), contents
+ 4);
960 x
= bfd_get_16 (input_bfd
, contents
);
961 x
= (x
& 0xf87f) | ((srel
<< 7) & 0x0780);
962 bfd_put_16 (input_bfd
, x
, contents
);
966 contents
+= rel
->r_offset
;
967 srel
= (bfd_signed_vma
) relocation
;
969 srel
+= bfd_get_8 (input_bfd
, contents
);
971 srel
+= rel
->r_addend
;
972 bfd_put_8 (input_bfd
, srel
& 0xff, contents
);
975 case R_MSP430X_ABS20_EXT_DST
:
976 /* [0,4]+[32,16] = ---F ---- FFFF */
977 contents
+= rel
->r_offset
;
978 srel
= (bfd_signed_vma
) relocation
;
982 addend
= (bfd_get_16 (input_bfd
, contents
) & 0xf) << 16;
983 addend
|= bfd_get_16 (input_bfd
, contents
+ 4);
987 srel
+= rel
->r_addend
;
988 bfd_put_16 (input_bfd
, (srel
& 0xffff), contents
+ 4);
990 x
= bfd_get_16 (input_bfd
, contents
);
991 x
= (x
& 0xfff0) | (srel
& 0xf);
992 bfd_put_16 (input_bfd
, x
, contents
);
995 case R_MSP430X_ABS20_EXT_ODST
:
996 /* [0,4]+[48,16] = ---F ---- ---- FFFF */
997 contents
+= rel
->r_offset
;
998 srel
= (bfd_signed_vma
) relocation
;
1002 addend
= (bfd_get_16 (input_bfd
, contents
) & 0xf) << 16;
1003 addend
|= bfd_get_16 (input_bfd
, contents
+ 6);
1007 srel
+= rel
->r_addend
;
1008 bfd_put_16 (input_bfd
, (srel
& 0xffff), contents
+ 6);
1010 x
= bfd_get_16 (input_bfd
, contents
);
1011 x
= (x
& 0xfff0) | (srel
& 0xf);
1012 bfd_put_16 (input_bfd
, x
, contents
);
1015 case R_MSP430X_ABS20_ADR_SRC
:
1016 /* [8,4]+[16,16] = -F-- FFFF */
1017 contents
+= rel
->r_offset
;
1018 srel
= (bfd_signed_vma
) relocation
;
1023 addend
= ((bfd_get_16 (input_bfd
, contents
) & 0xf00) << 8);
1024 addend
|= bfd_get_16 (input_bfd
, contents
+ 2);
1028 srel
+= rel
->r_addend
;
1029 bfd_put_16 (input_bfd
, (srel
& 0xffff), contents
+ 2);
1031 x
= bfd_get_16 (input_bfd
, contents
);
1032 x
= (x
& 0xf0ff) | ((srel
<< 8) & 0x0f00);
1033 bfd_put_16 (input_bfd
, x
, contents
);
1036 case R_MSP430X_ABS20_ADR_DST
:
1037 /* [0,4]+[16,16] = ---F FFFF */
1038 contents
+= rel
->r_offset
;
1039 srel
= (bfd_signed_vma
) relocation
;
1043 addend
= ((bfd_get_16 (input_bfd
, contents
) & 0xf) << 16);
1044 addend
|= bfd_get_16 (input_bfd
, contents
+ 2);
1048 srel
+= rel
->r_addend
;
1049 bfd_put_16 (input_bfd
, (srel
& 0xffff), contents
+ 2);
1051 x
= bfd_get_16 (input_bfd
, contents
);
1052 x
= (x
& 0xfff0) | (srel
& 0xf);
1053 bfd_put_16 (input_bfd
, x
, contents
);
1056 case R_MSP430X_ABS16
:
1057 contents
+= rel
->r_offset
;
1058 srel
= (bfd_signed_vma
) relocation
;
1060 srel
+= bfd_get_16 (input_bfd
, contents
);
1062 srel
+= rel
->r_addend
;
1065 return bfd_reloc_overflow
;
1066 bfd_put_16 (input_bfd
, srel
& 0xffff, contents
);
1069 case R_MSP430_ABS_HI16
:
1070 /* The EABI specifies that this must be a RELA reloc. */
1071 BFD_ASSERT (! is_rel_reloc
);
1072 contents
+= rel
->r_offset
;
1073 srel
= (bfd_signed_vma
) relocation
;
1074 srel
+= rel
->r_addend
;
1075 bfd_put_16 (input_bfd
, (srel
>> 16) & 0xffff, contents
);
1078 case R_MSP430X_PCR20_CALL
:
1079 /* [0,4]+[16,16] = ---F FFFF*/
1080 contents
+= rel
->r_offset
;
1081 srel
= (bfd_signed_vma
) relocation
;
1085 addend
= (bfd_get_16 (input_bfd
, contents
) & 0xf) << 16;
1086 addend
|= bfd_get_16 (input_bfd
, contents
+ 2);
1090 srel
+= rel
->r_addend
;
1091 srel
-= rel
->r_offset
;
1092 srel
-= (input_section
->output_section
->vma
+
1093 input_section
->output_offset
);
1094 bfd_put_16 (input_bfd
, srel
& 0xffff, contents
+ 2);
1096 x
= bfd_get_16 (input_bfd
, contents
);
1097 x
= (x
& 0xfff0) | (srel
& 0xf);
1098 bfd_put_16 (input_bfd
, x
, contents
);
1101 case R_MSP430X_PCR16
:
1102 contents
+= rel
->r_offset
;
1103 srel
= (bfd_signed_vma
) relocation
;
1105 srel
+= bfd_get_16 (input_bfd
, contents
);
1107 srel
+= rel
->r_addend
;
1108 srel
-= rel
->r_offset
;
1109 srel
-= (input_section
->output_section
->vma
+
1110 input_section
->output_offset
);
1111 bfd_put_16 (input_bfd
, srel
& 0xffff, contents
);
1114 case R_MSP430_PREL31
:
1115 contents
+= rel
->r_offset
;
1116 srel
= (bfd_signed_vma
) relocation
;
1118 srel
+= (bfd_get_32 (input_bfd
, contents
) & 0x7fffffff);
1120 srel
+= rel
->r_addend
;
1121 srel
+= rel
->r_addend
;
1122 x
= bfd_get_32 (input_bfd
, contents
);
1123 x
= (x
& 0x80000000) | ((srel
>> 31) & 0x7fffffff);
1124 bfd_put_32 (input_bfd
, x
, contents
);
1128 r
= _bfd_final_link_relocate (howto
, input_bfd
, input_section
,
1129 contents
, rel
->r_offset
,
1130 relocation
, rel
->r_addend
);
1133 switch (howto
->type
)
1135 case R_MSP430_10_PCREL
:
1136 contents
+= rel
->r_offset
;
1137 srel
= (bfd_signed_vma
) relocation
;
1138 srel
+= rel
->r_addend
;
1139 srel
-= rel
->r_offset
;
1140 srel
-= 2; /* Branch instructions add 2 to the PC... */
1141 srel
-= (input_section
->output_section
->vma
+
1142 input_section
->output_offset
);
1145 return bfd_reloc_outofrange
;
1147 /* MSP430 addresses commands as words. */
1150 /* Check for an overflow. */
1151 if (srel
< -512 || srel
> 511)
1153 if (info
->disable_target_specific_optimizations
< 0)
1155 static bfd_boolean warned
= FALSE
;
1158 info
->callbacks
->warning
1160 _("try enabling relaxation to avoid relocation truncations"),
1161 NULL
, input_bfd
, input_section
, relocation
);
1165 return bfd_reloc_overflow
;
1168 x
= bfd_get_16 (input_bfd
, contents
);
1169 x
= (x
& 0xfc00) | (srel
& 0x3ff);
1170 bfd_put_16 (input_bfd
, x
, contents
);
1173 case R_MSP430_2X_PCREL
:
1174 contents
+= rel
->r_offset
;
1175 srel
= (bfd_signed_vma
) relocation
;
1176 srel
+= rel
->r_addend
;
1177 srel
-= rel
->r_offset
;
1178 srel
-= 2; /* Branch instructions add 2 to the PC... */
1179 srel
-= (input_section
->output_section
->vma
+
1180 input_section
->output_offset
);
1183 return bfd_reloc_outofrange
;
1185 /* MSP430 addresses commands as words. */
1188 /* Check for an overflow. */
1189 if (srel
< -512 || srel
> 511)
1190 return bfd_reloc_overflow
;
1192 x
= bfd_get_16 (input_bfd
, contents
);
1193 x
= (x
& 0xfc00) | (srel
& 0x3ff);
1194 bfd_put_16 (input_bfd
, x
, contents
);
1195 /* Handle second jump instruction. */
1196 x
= bfd_get_16 (input_bfd
, contents
- 2);
1198 x
= (x
& 0xfc00) | (srel
& 0x3ff);
1199 bfd_put_16 (input_bfd
, x
, contents
- 2);
1202 case R_MSP430_RL_PCREL
:
1203 case R_MSP430_16_PCREL
:
1204 contents
+= rel
->r_offset
;
1205 srel
= (bfd_signed_vma
) relocation
;
1206 srel
+= rel
->r_addend
;
1207 srel
-= rel
->r_offset
;
1208 /* Only branch instructions add 2 to the PC... */
1209 srel
-= (input_section
->output_section
->vma
+
1210 input_section
->output_offset
);
1213 return bfd_reloc_outofrange
;
1215 bfd_put_16 (input_bfd
, srel
& 0xffff, contents
);
1218 case R_MSP430_16_PCREL_BYTE
:
1219 contents
+= rel
->r_offset
;
1220 srel
= (bfd_signed_vma
) relocation
;
1221 srel
+= rel
->r_addend
;
1222 srel
-= rel
->r_offset
;
1223 /* Only branch instructions add 2 to the PC... */
1224 srel
-= (input_section
->output_section
->vma
+
1225 input_section
->output_offset
);
1227 bfd_put_16 (input_bfd
, srel
& 0xffff, contents
);
1230 case R_MSP430_16_BYTE
:
1231 contents
+= rel
->r_offset
;
1232 srel
= (bfd_signed_vma
) relocation
;
1233 srel
+= rel
->r_addend
;
1234 bfd_put_16 (input_bfd
, srel
& 0xffff, contents
);
1238 contents
+= rel
->r_offset
;
1239 srel
= (bfd_signed_vma
) relocation
;
1240 srel
+= rel
->r_addend
;
1243 return bfd_reloc_notsupported
;
1245 bfd_put_16 (input_bfd
, srel
& 0xffff, contents
);
1249 contents
+= rel
->r_offset
;
1250 srel
= (bfd_signed_vma
) relocation
;
1251 srel
+= rel
->r_addend
;
1253 bfd_put_8 (input_bfd
, srel
& 0xff, contents
);
1256 case R_MSP430_SYM_DIFF
:
1257 /* Cache the input section and value.
1258 The offset is unreliable, since relaxation may
1259 have reduced the following reloc's offset. */
1260 sym_diff_section
= input_section
;
1261 sym_diff_value
= relocation
;
1262 return bfd_reloc_ok
;
1265 r
= _bfd_final_link_relocate (howto
, input_bfd
, input_section
,
1266 contents
, rel
->r_offset
,
1267 relocation
, rel
->r_addend
);
1273 /* Relocate an MSP430 ELF section. */
1276 elf32_msp430_relocate_section (bfd
* output_bfd ATTRIBUTE_UNUSED
,
1277 struct bfd_link_info
* info
,
1279 asection
* input_section
,
1280 bfd_byte
* contents
,
1281 Elf_Internal_Rela
* relocs
,
1282 Elf_Internal_Sym
* local_syms
,
1283 asection
** local_sections
)
1285 Elf_Internal_Shdr
*symtab_hdr
;
1286 struct elf_link_hash_entry
**sym_hashes
;
1287 Elf_Internal_Rela
*rel
;
1288 Elf_Internal_Rela
*relend
;
1290 symtab_hdr
= &elf_tdata (input_bfd
)->symtab_hdr
;
1291 sym_hashes
= elf_sym_hashes (input_bfd
);
1292 relend
= relocs
+ input_section
->reloc_count
;
1294 for (rel
= relocs
; rel
< relend
; rel
++)
1296 reloc_howto_type
*howto
;
1297 unsigned long r_symndx
;
1298 Elf_Internal_Sym
*sym
;
1300 struct elf_link_hash_entry
*h
;
1302 bfd_reloc_status_type r
;
1303 const char *name
= NULL
;
1306 r_type
= ELF32_R_TYPE (rel
->r_info
);
1307 r_symndx
= ELF32_R_SYM (rel
->r_info
);
1309 if (uses_msp430x_relocs (input_bfd
))
1310 howto
= elf_msp430x_howto_table
+ r_type
;
1312 howto
= elf_msp430_howto_table
+ r_type
;
1318 if (r_symndx
< symtab_hdr
->sh_info
)
1320 sym
= local_syms
+ r_symndx
;
1321 sec
= local_sections
[r_symndx
];
1322 relocation
= _bfd_elf_rela_local_sym (output_bfd
, sym
, &sec
, rel
);
1324 name
= bfd_elf_string_from_elf_section
1325 (input_bfd
, symtab_hdr
->sh_link
, sym
->st_name
);
1326 name
= name
== NULL
|| *name
== 0 ? bfd_section_name (sec
) : name
;
1330 bfd_boolean unresolved_reloc
, warned
, ignored
;
1332 RELOC_FOR_GLOBAL_SYMBOL (info
, input_bfd
, input_section
, rel
,
1333 r_symndx
, symtab_hdr
, sym_hashes
,
1335 unresolved_reloc
, warned
, ignored
);
1336 name
= h
->root
.root
.string
;
1339 if (sec
!= NULL
&& discarded_section (sec
))
1340 RELOC_AGAINST_DISCARDED_SECTION (info
, input_bfd
, input_section
,
1341 rel
, 1, relend
, howto
, 0, contents
);
1343 if (bfd_link_relocatable (info
))
1346 r
= msp430_final_link_relocate (howto
, input_bfd
, input_section
,
1347 contents
, rel
, relocation
, info
);
1349 if (r
!= bfd_reloc_ok
)
1351 const char *msg
= (const char *) NULL
;
1355 case bfd_reloc_overflow
:
1356 (*info
->callbacks
->reloc_overflow
)
1357 (info
, (h
? &h
->root
: NULL
), name
, howto
->name
,
1358 (bfd_vma
) 0, input_bfd
, input_section
, rel
->r_offset
);
1361 case bfd_reloc_undefined
:
1362 (*info
->callbacks
->undefined_symbol
)
1363 (info
, name
, input_bfd
, input_section
, rel
->r_offset
, TRUE
);
1366 case bfd_reloc_outofrange
:
1367 msg
= _("internal error: branch/jump to an odd address detected");
1370 case bfd_reloc_notsupported
:
1371 msg
= _("internal error: unsupported relocation error");
1374 case bfd_reloc_dangerous
:
1375 msg
= _("internal error: dangerous relocation");
1379 msg
= _("internal error: unknown error");
1384 (*info
->callbacks
->warning
) (info
, msg
, name
, input_bfd
,
1385 input_section
, rel
->r_offset
);
1393 /* The final processing done just before writing out a MSP430 ELF object
1394 file. This gets the MSP430 architecture right based on the machine
1398 bfd_elf_msp430_final_write_processing (bfd
*abfd
)
1402 switch (bfd_get_mach (abfd
))
1405 case bfd_mach_msp110
: val
= E_MSP430_MACH_MSP430x11x1
; break;
1406 case bfd_mach_msp11
: val
= E_MSP430_MACH_MSP430x11
; break;
1407 case bfd_mach_msp12
: val
= E_MSP430_MACH_MSP430x12
; break;
1408 case bfd_mach_msp13
: val
= E_MSP430_MACH_MSP430x13
; break;
1409 case bfd_mach_msp14
: val
= E_MSP430_MACH_MSP430x14
; break;
1410 case bfd_mach_msp15
: val
= E_MSP430_MACH_MSP430x15
; break;
1411 case bfd_mach_msp16
: val
= E_MSP430_MACH_MSP430x16
; break;
1412 case bfd_mach_msp31
: val
= E_MSP430_MACH_MSP430x31
; break;
1413 case bfd_mach_msp32
: val
= E_MSP430_MACH_MSP430x32
; break;
1414 case bfd_mach_msp33
: val
= E_MSP430_MACH_MSP430x33
; break;
1415 case bfd_mach_msp41
: val
= E_MSP430_MACH_MSP430x41
; break;
1416 case bfd_mach_msp42
: val
= E_MSP430_MACH_MSP430x42
; break;
1417 case bfd_mach_msp43
: val
= E_MSP430_MACH_MSP430x43
; break;
1418 case bfd_mach_msp44
: val
= E_MSP430_MACH_MSP430x44
; break;
1419 case bfd_mach_msp20
: val
= E_MSP430_MACH_MSP430x20
; break;
1420 case bfd_mach_msp22
: val
= E_MSP430_MACH_MSP430x22
; break;
1421 case bfd_mach_msp23
: val
= E_MSP430_MACH_MSP430x23
; break;
1422 case bfd_mach_msp24
: val
= E_MSP430_MACH_MSP430x24
; break;
1423 case bfd_mach_msp26
: val
= E_MSP430_MACH_MSP430x26
; break;
1424 case bfd_mach_msp46
: val
= E_MSP430_MACH_MSP430x46
; break;
1425 case bfd_mach_msp47
: val
= E_MSP430_MACH_MSP430x47
; break;
1426 case bfd_mach_msp54
: val
= E_MSP430_MACH_MSP430x54
; break;
1427 case bfd_mach_msp430x
: val
= E_MSP430_MACH_MSP430X
; break;
1430 elf_elfheader (abfd
)->e_machine
= EM_MSP430
;
1431 elf_elfheader (abfd
)->e_flags
&= ~EF_MSP430_MACH
;
1432 elf_elfheader (abfd
)->e_flags
|= val
;
1433 return _bfd_elf_final_write_processing (abfd
);
1436 /* Set the right machine number. */
1439 elf32_msp430_object_p (bfd
* abfd
)
1441 int e_set
= bfd_mach_msp14
;
1443 if (elf_elfheader (abfd
)->e_machine
== EM_MSP430
1444 || elf_elfheader (abfd
)->e_machine
== EM_MSP430_OLD
)
1446 int e_mach
= elf_elfheader (abfd
)->e_flags
& EF_MSP430_MACH
;
1451 case E_MSP430_MACH_MSP430x11
: e_set
= bfd_mach_msp11
; break;
1452 case E_MSP430_MACH_MSP430x11x1
: e_set
= bfd_mach_msp110
; break;
1453 case E_MSP430_MACH_MSP430x12
: e_set
= bfd_mach_msp12
; break;
1454 case E_MSP430_MACH_MSP430x13
: e_set
= bfd_mach_msp13
; break;
1455 case E_MSP430_MACH_MSP430x14
: e_set
= bfd_mach_msp14
; break;
1456 case E_MSP430_MACH_MSP430x15
: e_set
= bfd_mach_msp15
; break;
1457 case E_MSP430_MACH_MSP430x16
: e_set
= bfd_mach_msp16
; break;
1458 case E_MSP430_MACH_MSP430x31
: e_set
= bfd_mach_msp31
; break;
1459 case E_MSP430_MACH_MSP430x32
: e_set
= bfd_mach_msp32
; break;
1460 case E_MSP430_MACH_MSP430x33
: e_set
= bfd_mach_msp33
; break;
1461 case E_MSP430_MACH_MSP430x41
: e_set
= bfd_mach_msp41
; break;
1462 case E_MSP430_MACH_MSP430x42
: e_set
= bfd_mach_msp42
; break;
1463 case E_MSP430_MACH_MSP430x43
: e_set
= bfd_mach_msp43
; break;
1464 case E_MSP430_MACH_MSP430x44
: e_set
= bfd_mach_msp44
; break;
1465 case E_MSP430_MACH_MSP430x20
: e_set
= bfd_mach_msp20
; break;
1466 case E_MSP430_MACH_MSP430x22
: e_set
= bfd_mach_msp22
; break;
1467 case E_MSP430_MACH_MSP430x23
: e_set
= bfd_mach_msp23
; break;
1468 case E_MSP430_MACH_MSP430x24
: e_set
= bfd_mach_msp24
; break;
1469 case E_MSP430_MACH_MSP430x26
: e_set
= bfd_mach_msp26
; break;
1470 case E_MSP430_MACH_MSP430x46
: e_set
= bfd_mach_msp46
; break;
1471 case E_MSP430_MACH_MSP430x47
: e_set
= bfd_mach_msp47
; break;
1472 case E_MSP430_MACH_MSP430x54
: e_set
= bfd_mach_msp54
; break;
1473 case E_MSP430_MACH_MSP430X
: e_set
= bfd_mach_msp430x
; break;
1477 return bfd_default_set_arch_mach (abfd
, bfd_arch_msp430
, e_set
);
1480 /* These functions handle relaxing for the msp430.
1481 Relaxation required only in two cases:
1482 - Bad hand coding like jumps from one section to another or
1484 - Sibling calls. This will affect only 'jump label' polymorph. Without
1485 relaxing this enlarges code by 2 bytes. Sibcalls implemented but
1486 do not work in gcc's port by the reason I do not know.
1487 - To convert out of range conditional jump instructions (found inside
1488 a function) into inverted jumps over an unconditional branch instruction.
1489 Anyway, if a relaxation required, user should pass -relax option to the
1492 There are quite a few relaxing opportunities available on the msp430:
1494 ================================================================
1496 1. 3 words -> 1 word
1498 eq == jeq label jne +4; br lab
1499 ne != jne label jeq +4; br lab
1500 lt < jl label jge +4; br lab
1501 ltu < jlo label lhs +4; br lab
1502 ge >= jge label jl +4; br lab
1503 geu >= jhs label jlo +4; br lab
1505 2. 4 words -> 1 word
1507 ltn < jn jn +2; jmp +4; br lab
1509 3. 4 words -> 2 words
1511 gt > jeq +2; jge label jeq +6; jl +4; br label
1512 gtu > jeq +2; jhs label jeq +6; jlo +4; br label
1514 4. 4 words -> 2 words and 2 labels
1516 leu <= jeq label; jlo label jeq +2; jhs +4; br label
1517 le <= jeq label; jl label jeq +2; jge +4; br label
1518 =================================================================
1520 codemap for first cases is (labels masked ):
1521 eq: 0x2002,0x4010,0x0000 -> 0x2400
1522 ne: 0x2402,0x4010,0x0000 -> 0x2000
1523 lt: 0x3402,0x4010,0x0000 -> 0x3800
1524 ltu: 0x2c02,0x4010,0x0000 -> 0x2800
1525 ge: 0x3802,0x4010,0x0000 -> 0x3400
1526 geu: 0x2802,0x4010,0x0000 -> 0x2c00
1529 ltn: 0x3001,0x3c02,0x4010,0x0000 -> 0x3000
1532 gt: 0x2403,0x3802,0x4010,0x0000 -> 0x2401,0x3400
1533 gtu: 0x2403,0x2802,0x4010,0x0000 -> 0x2401,0x2c00
1536 leu: 0x2401,0x2c02,0x4010,0x0000 -> 0x2400,0x2800
1537 le: 0x2401,0x3402,0x4010,0x0000 -> 0x2400,0x3800
1540 jump: 0x4010,0x0000 -> 0x3c00. */
1542 #define NUMB_RELAX_CODES 12
1543 static struct rcodes_s
1545 int f0
, f1
; /* From code. */
1546 int t0
, t1
; /* To code. */
1547 int labels
; /* Position of labels: 1 - one label at first
1548 word, 2 - one at second word, 3 - two
1550 int cdx
; /* Words to match. */
1551 int bs
; /* Shrink bytes. */
1552 int off
; /* Offset from old label for new code. */
1553 int ncl
; /* New code length. */
1555 {/* lab,cdx,bs,off,ncl */
1556 { 0x0000, 0x0000, 0x3c00, 0x0000, 1, 0, 2, 2, 2}, /* jump */
1557 { 0x0000, 0x2002, 0x2400, 0x0000, 1, 1, 4, 4, 2}, /* eq */
1558 { 0x0000, 0x2402, 0x2000, 0x0000, 1, 1, 4, 4, 2}, /* ne */
1559 { 0x0000, 0x3402, 0x3800, 0x0000, 1, 1, 4, 4, 2}, /* lt */
1560 { 0x0000, 0x2c02, 0x2800, 0x0000, 1, 1, 4, 4, 2}, /* ltu */
1561 { 0x0000, 0x3802, 0x3400, 0x0000, 1, 1, 4, 4, 2}, /* ge */
1562 { 0x0000, 0x2802, 0x2c00, 0x0000, 1, 1, 4, 4, 2}, /* geu */
1563 { 0x3001, 0x3c02, 0x3000, 0x0000, 1, 2, 6, 6, 2}, /* ltn */
1564 { 0x2403, 0x3802, 0x2401, 0x3400, 2, 2, 4, 6, 4}, /* gt */
1565 { 0x2403, 0x2802, 0x2401, 0x2c00, 2, 2, 4, 6, 4}, /* gtu */
1566 { 0x2401, 0x2c02, 0x2400, 0x2800, 3, 2, 4, 6, 4}, /* leu , 2 labels */
1567 { 0x2401, 0x2c02, 0x2400, 0x2800, 3, 2, 4, 6, 4}, /* le , 2 labels */
1568 { 0, 0, 0, 0, 0, 0, 0, 0, 0}
1571 /* Return TRUE if a symbol exists at the given address. */
1574 msp430_elf_symbol_address_p (bfd
* abfd
,
1576 Elf_Internal_Sym
* isym
,
1579 Elf_Internal_Shdr
*symtab_hdr
;
1580 unsigned int sec_shndx
;
1581 Elf_Internal_Sym
*isymend
;
1582 struct elf_link_hash_entry
**sym_hashes
;
1583 struct elf_link_hash_entry
**end_hashes
;
1584 unsigned int symcount
;
1586 sec_shndx
= _bfd_elf_section_from_bfd_section (abfd
, sec
);
1588 /* Examine all the local symbols. */
1589 symtab_hdr
= &elf_tdata (abfd
)->symtab_hdr
;
1590 for (isymend
= isym
+ symtab_hdr
->sh_info
; isym
< isymend
; isym
++)
1591 if (isym
->st_shndx
== sec_shndx
&& isym
->st_value
== addr
)
1594 symcount
= (symtab_hdr
->sh_size
/ sizeof (Elf32_External_Sym
)
1595 - symtab_hdr
->sh_info
);
1596 sym_hashes
= elf_sym_hashes (abfd
);
1597 end_hashes
= sym_hashes
+ symcount
;
1598 for (; sym_hashes
< end_hashes
; sym_hashes
++)
1600 struct elf_link_hash_entry
*sym_hash
= *sym_hashes
;
1602 if ((sym_hash
->root
.type
== bfd_link_hash_defined
1603 || sym_hash
->root
.type
== bfd_link_hash_defweak
)
1604 && sym_hash
->root
.u
.def
.section
== sec
1605 && sym_hash
->root
.u
.def
.value
== addr
)
1612 /* Adjust all local symbols defined as '.section + 0xXXXX' (.section has
1613 sec_shndx) referenced from current and other sections. */
1616 msp430_elf_relax_adjust_locals (bfd
* abfd
, asection
* sec
, bfd_vma addr
,
1617 int count
, unsigned int sec_shndx
,
1620 Elf_Internal_Shdr
*symtab_hdr
;
1621 Elf_Internal_Rela
*irel
;
1622 Elf_Internal_Rela
*irelend
;
1623 Elf_Internal_Sym
*isym
;
1625 irel
= elf_section_data (sec
)->relocs
;
1629 irelend
= irel
+ sec
->reloc_count
;
1630 symtab_hdr
= & elf_tdata (abfd
)->symtab_hdr
;
1631 isym
= (Elf_Internal_Sym
*) symtab_hdr
->contents
;
1633 for (;irel
< irelend
; irel
++)
1635 unsigned int sidx
= ELF32_R_SYM(irel
->r_info
);
1636 Elf_Internal_Sym
*lsym
= isym
+ sidx
;
1638 /* Adjust symbols referenced by .sec+0xXX. */
1639 if (irel
->r_addend
> addr
&& irel
->r_addend
< toaddr
1640 && sidx
< symtab_hdr
->sh_info
1641 && lsym
->st_shndx
== sec_shndx
)
1642 irel
->r_addend
-= count
;
1648 /* Delete some bytes from a section while relaxing. */
1651 msp430_elf_relax_delete_bytes (bfd
* abfd
, asection
* sec
, bfd_vma addr
,
1654 Elf_Internal_Shdr
*symtab_hdr
;
1655 unsigned int sec_shndx
;
1657 Elf_Internal_Rela
*irel
;
1658 Elf_Internal_Rela
*irelend
;
1660 Elf_Internal_Sym
*isym
;
1661 Elf_Internal_Sym
*isymend
;
1662 struct elf_link_hash_entry
**sym_hashes
;
1663 struct elf_link_hash_entry
**end_hashes
;
1664 unsigned int symcount
;
1667 sec_shndx
= _bfd_elf_section_from_bfd_section (abfd
, sec
);
1669 contents
= elf_section_data (sec
)->this_hdr
.contents
;
1673 printf (" deleting %d bytes between 0x%lx to 0x%lx\n",
1674 count
, (long) addr
, (long) toaddr
);
1676 irel
= elf_section_data (sec
)->relocs
;
1677 irelend
= irel
+ sec
->reloc_count
;
1679 /* Actually delete the bytes. */
1680 memmove (contents
+ addr
, contents
+ addr
+ count
,
1681 (size_t) (toaddr
- addr
- count
));
1684 /* Adjust all the relocs. */
1685 symtab_hdr
= & elf_tdata (abfd
)->symtab_hdr
;
1686 isym
= (Elf_Internal_Sym
*) symtab_hdr
->contents
;
1687 for (; irel
< irelend
; irel
++)
1689 /* Get the new reloc address. */
1690 if ((irel
->r_offset
> addr
&& irel
->r_offset
< toaddr
))
1691 irel
->r_offset
-= count
;
1694 for (p
= abfd
->sections
; p
!= NULL
; p
= p
->next
)
1695 msp430_elf_relax_adjust_locals (abfd
,p
,addr
,count
,sec_shndx
,toaddr
);
1697 /* Adjust the local symbols defined in this section. */
1698 symtab_hdr
= & elf_tdata (abfd
)->symtab_hdr
;
1699 isym
= (Elf_Internal_Sym
*) symtab_hdr
->contents
;
1700 for (isymend
= isym
+ symtab_hdr
->sh_info
; isym
< isymend
; isym
++)
1704 name
= bfd_elf_string_from_elf_section
1705 (abfd
, symtab_hdr
->sh_link
, isym
->st_name
);
1706 name
= name
== NULL
|| *name
== 0 ? bfd_section_name (sec
) : name
;
1708 if (isym
->st_shndx
!= sec_shndx
)
1711 if (isym
->st_value
> addr
1712 && (isym
->st_value
< toaddr
1713 /* We also adjust a symbol at the end of the section if its name is
1714 on the list below. These symbols are used for debug info
1715 generation and they refer to the end of the current section, not
1716 the start of the next section. */
1717 || (isym
->st_value
== toaddr
1719 && (CONST_STRNEQ (name
, ".Letext")
1720 || CONST_STRNEQ (name
, ".LFE")))))
1723 printf (" adjusting value of local symbol %s from 0x%lx ",
1724 name
, (long) isym
->st_value
);
1725 if (isym
->st_value
< addr
+ count
)
1726 isym
->st_value
= addr
;
1728 isym
->st_value
-= count
;
1730 printf ("to 0x%lx\n", (long) isym
->st_value
);
1732 /* Adjust the function symbol's size as well. */
1733 else if (ELF_ST_TYPE (isym
->st_info
) == STT_FUNC
1734 && isym
->st_value
+ isym
->st_size
> addr
1735 && isym
->st_value
+ isym
->st_size
< toaddr
)
1736 isym
->st_size
-= count
;
1739 /* Now adjust the global symbols defined in this section. */
1740 symcount
= (symtab_hdr
->sh_size
/ sizeof (Elf32_External_Sym
)
1741 - symtab_hdr
->sh_info
);
1742 sym_hashes
= elf_sym_hashes (abfd
);
1743 end_hashes
= sym_hashes
+ symcount
;
1744 for (; sym_hashes
< end_hashes
; sym_hashes
++)
1746 struct elf_link_hash_entry
*sym_hash
= *sym_hashes
;
1748 if ((sym_hash
->root
.type
== bfd_link_hash_defined
1749 || sym_hash
->root
.type
== bfd_link_hash_defweak
)
1750 && sym_hash
->root
.u
.def
.section
== sec
1751 && sym_hash
->root
.u
.def
.value
> addr
1752 && sym_hash
->root
.u
.def
.value
< toaddr
)
1754 if (sym_hash
->root
.u
.def
.value
< addr
+ count
)
1755 sym_hash
->root
.u
.def
.value
= addr
;
1757 sym_hash
->root
.u
.def
.value
-= count
;
1759 /* Adjust the function symbol's size as well. */
1760 else if (sym_hash
->root
.type
== bfd_link_hash_defined
1761 && sym_hash
->root
.u
.def
.section
== sec
1762 && sym_hash
->type
== STT_FUNC
1763 && sym_hash
->root
.u
.def
.value
+ sym_hash
->size
> addr
1764 && sym_hash
->root
.u
.def
.value
+ sym_hash
->size
< toaddr
)
1765 sym_hash
->size
-= count
;
1771 /* Insert one or two words into a section whilst relaxing. */
1774 msp430_elf_relax_add_words (bfd
* abfd
, asection
* sec
, bfd_vma addr
,
1775 int num_words
, int word1
, int word2
)
1777 Elf_Internal_Shdr
*symtab_hdr
;
1778 unsigned int sec_shndx
;
1780 Elf_Internal_Rela
*irel
;
1781 Elf_Internal_Rela
*irelend
;
1782 Elf_Internal_Sym
*isym
;
1783 Elf_Internal_Sym
*isymend
;
1784 struct elf_link_hash_entry
**sym_hashes
;
1785 struct elf_link_hash_entry
**end_hashes
;
1786 unsigned int symcount
;
1790 printf (" adding %d words at 0x%lx\n", num_words
,
1791 (long) (sec
->output_section
->vma
+ sec
->output_offset
+ addr
));
1793 contents
= elf_section_data (sec
)->this_hdr
.contents
;
1794 sec_end
= sec
->size
;
1795 int num_bytes
= num_words
* 2;
1797 /* Make space for the new words. */
1798 contents
= bfd_realloc (contents
, sec_end
+ num_bytes
);
1799 memmove (contents
+ addr
+ num_bytes
, contents
+ addr
, sec_end
- addr
);
1801 /* Insert the new words. */
1802 bfd_put_16 (abfd
, word1
, contents
+ addr
);
1804 bfd_put_16 (abfd
, word2
, contents
+ addr
+ 2);
1806 /* Update the section information. */
1807 sec
->size
+= num_bytes
;
1808 elf_section_data (sec
)->this_hdr
.contents
= contents
;
1810 /* Adjust all the relocs. */
1811 irel
= elf_section_data (sec
)->relocs
;
1812 irelend
= irel
+ sec
->reloc_count
;
1814 for (; irel
< irelend
; irel
++)
1815 if ((irel
->r_offset
>= addr
&& irel
->r_offset
< sec_end
))
1816 irel
->r_offset
+= num_bytes
;
1818 /* Adjust the local symbols defined in this section. */
1819 sec_shndx
= _bfd_elf_section_from_bfd_section (abfd
, sec
);
1820 for (p
= abfd
->sections
; p
!= NULL
; p
= p
->next
)
1821 msp430_elf_relax_adjust_locals (abfd
, p
, addr
, -num_bytes
,
1822 sec_shndx
, sec_end
);
1824 /* Adjust the global symbols affected by the move. */
1825 symtab_hdr
= & elf_tdata (abfd
)->symtab_hdr
;
1826 isym
= (Elf_Internal_Sym
*) symtab_hdr
->contents
;
1827 for (isymend
= isym
+ symtab_hdr
->sh_info
; isym
< isymend
; isym
++)
1828 if (isym
->st_shndx
== sec_shndx
1829 && isym
->st_value
>= addr
&& isym
->st_value
< sec_end
)
1832 printf (" adjusting value of local symbol %s from 0x%lx to "
1833 "0x%lx\n", bfd_elf_string_from_elf_section
1834 (abfd
, symtab_hdr
->sh_link
, isym
->st_name
),
1835 (long) isym
->st_value
, (long)(isym
->st_value
+ num_bytes
));
1836 isym
->st_value
+= num_bytes
;
1839 /* Now adjust the global symbols defined in this section. */
1840 symcount
= (symtab_hdr
->sh_size
/ sizeof (Elf32_External_Sym
)
1841 - symtab_hdr
->sh_info
);
1842 sym_hashes
= elf_sym_hashes (abfd
);
1843 end_hashes
= sym_hashes
+ symcount
;
1844 for (; sym_hashes
< end_hashes
; sym_hashes
++)
1846 struct elf_link_hash_entry
*sym_hash
= *sym_hashes
;
1848 if ((sym_hash
->root
.type
== bfd_link_hash_defined
1849 || sym_hash
->root
.type
== bfd_link_hash_defweak
)
1850 && sym_hash
->root
.u
.def
.section
== sec
1851 && sym_hash
->root
.u
.def
.value
>= addr
1852 && sym_hash
->root
.u
.def
.value
< sec_end
)
1853 sym_hash
->root
.u
.def
.value
+= num_bytes
;
1860 msp430_elf_relax_section (bfd
* abfd
, asection
* sec
,
1861 struct bfd_link_info
* link_info
,
1862 bfd_boolean
* again
)
1864 Elf_Internal_Shdr
* symtab_hdr
;
1865 Elf_Internal_Rela
* internal_relocs
;
1866 Elf_Internal_Rela
* irel
;
1867 Elf_Internal_Rela
* irelend
;
1868 bfd_byte
* contents
= NULL
;
1869 Elf_Internal_Sym
* isymbuf
= NULL
;
1871 /* Assume nothing changes. */
1874 /* We don't have to do anything for a relocatable link, if
1875 this section does not have relocs, or if this is not a
1877 if (bfd_link_relocatable (link_info
)
1878 || (sec
->flags
& SEC_RELOC
) == 0
1879 || sec
->reloc_count
== 0 || (sec
->flags
& SEC_CODE
) == 0)
1883 printf ("Relaxing %s (%p), output_offset: 0x%lx sec size: 0x%lx\n",
1884 sec
->name
, sec
, (long) sec
->output_offset
, (long) sec
->size
);
1886 symtab_hdr
= & elf_tdata (abfd
)->symtab_hdr
;
1888 /* Get a copy of the native relocations. */
1890 _bfd_elf_link_read_relocs (abfd
, sec
, NULL
, NULL
, link_info
->keep_memory
);
1891 if (internal_relocs
== NULL
)
1894 /* Walk through them looking for relaxing opportunities. */
1895 irelend
= internal_relocs
+ sec
->reloc_count
;
1898 printf (" trying code size growing relocs\n");
1899 /* Do code size growing relocs first. */
1900 for (irel
= internal_relocs
; irel
< irelend
; irel
++)
1904 /* If this isn't something that can be relaxed, then ignore
1906 if (uses_msp430x_relocs (abfd
)
1907 && ELF32_R_TYPE (irel
->r_info
) == (int) R_MSP430X_10_PCREL
)
1909 else if (! uses_msp430x_relocs (abfd
)
1910 && ELF32_R_TYPE (irel
->r_info
) == (int) R_MSP430_10_PCREL
)
1915 /* Get the section contents if we haven't done so already. */
1916 if (contents
== NULL
)
1918 /* Get cached copy if it exists. */
1919 if (elf_section_data (sec
)->this_hdr
.contents
!= NULL
)
1920 contents
= elf_section_data (sec
)->this_hdr
.contents
;
1921 else if (! bfd_malloc_and_get_section (abfd
, sec
, &contents
))
1925 /* Read this BFD's local symbols if we haven't done so already. */
1926 if (isymbuf
== NULL
&& symtab_hdr
->sh_info
!= 0)
1928 isymbuf
= (Elf_Internal_Sym
*) symtab_hdr
->contents
;
1929 if (isymbuf
== NULL
)
1930 isymbuf
= bfd_elf_get_elf_syms (abfd
, symtab_hdr
,
1931 symtab_hdr
->sh_info
, 0,
1933 if (isymbuf
== NULL
)
1937 /* Get the value of the symbol referred to by the reloc. */
1938 if (ELF32_R_SYM (irel
->r_info
) < symtab_hdr
->sh_info
)
1940 /* A local symbol. */
1941 Elf_Internal_Sym
*isym
;
1944 isym
= isymbuf
+ ELF32_R_SYM (irel
->r_info
);
1945 if (isym
->st_shndx
== SHN_UNDEF
)
1946 sym_sec
= bfd_und_section_ptr
;
1947 else if (isym
->st_shndx
== SHN_ABS
)
1948 sym_sec
= bfd_abs_section_ptr
;
1949 else if (isym
->st_shndx
== SHN_COMMON
)
1950 sym_sec
= bfd_com_section_ptr
;
1952 sym_sec
= bfd_section_from_elf_index (abfd
, isym
->st_shndx
);
1953 symval
= (isym
->st_value
1954 + sym_sec
->output_section
->vma
+ sym_sec
->output_offset
);
1957 printf (" processing reloc at 0x%lx for local sym: %s "
1958 "st_value: 0x%lx adj value: 0x%lx\n",
1959 (long) (sec
->output_offset
+ sec
->output_section
->vma
1961 bfd_elf_string_from_elf_section (abfd
, symtab_hdr
->sh_link
,
1963 (long) isym
->st_value
, (long) symval
);
1968 struct elf_link_hash_entry
*h
;
1970 /* An external symbol. */
1971 indx
= ELF32_R_SYM (irel
->r_info
) - symtab_hdr
->sh_info
;
1972 h
= elf_sym_hashes (abfd
)[indx
];
1973 BFD_ASSERT (h
!= NULL
);
1975 if (h
->root
.type
!= bfd_link_hash_defined
1976 && h
->root
.type
!= bfd_link_hash_defweak
)
1977 /* This appears to be a reference to an undefined
1978 symbol. Just ignore it--it will be caught by the
1979 regular reloc processing. */
1982 symval
= (h
->root
.u
.def
.value
1983 + h
->root
.u
.def
.section
->output_section
->vma
1984 + h
->root
.u
.def
.section
->output_offset
);
1986 printf (" processing reloc at 0x%lx for global sym: %s "
1987 "st_value: 0x%lx adj value: 0x%lx\n",
1988 (long) (sec
->output_offset
+ sec
->output_section
->vma
1990 h
->root
.root
.string
, (long) h
->root
.u
.def
.value
,
1994 /* For simplicity of coding, we are going to modify the section
1995 contents, the section relocs, and the BFD symbol table. We
1996 must tell the rest of the code not to free up this
1997 information. It would be possible to instead create a table
1998 of changes which have to be made, as is done in coff-mips.c;
1999 that would be more work, but would require less memory when
2000 the linker is run. */
2002 bfd_signed_vma value
= symval
;
2005 /* Compute the value that will be relocated. */
2006 value
+= irel
->r_addend
;
2007 /* Convert to PC relative. */
2008 value
-= (sec
->output_section
->vma
+ sec
->output_offset
);
2009 value
-= irel
->r_offset
;
2015 /* If it is in range then no modifications are needed. */
2016 if (value
>= -512 && value
<= 511)
2019 /* Get the opcode. */
2020 opcode
= bfd_get_16 (abfd
, contents
+ irel
->r_offset
);
2022 /* Compute the new opcode. We are going to convert:
2032 switch (opcode
& 0xfc00)
2034 case 0x3800: opcode
= 0x3402; break; /* Jl -> Jge +2 */
2035 case 0x3400: opcode
= 0x3802; break; /* Jge -> Jl +2 */
2036 case 0x2c00: opcode
= 0x2802; break; /* Jhs -> Jlo +2 */
2037 case 0x2800: opcode
= 0x2c02; break; /* Jlo -> Jhs +2 */
2038 case 0x2400: opcode
= 0x2002; break; /* Jeq -> Jne +2 */
2039 case 0x2000: opcode
= 0x2402; break; /* jne -> Jeq +2 */
2040 case 0x3000: /* jn */
2041 /* There is no direct inverse of the Jn insn.
2042 FIXME: we could do this as:
2049 if (uses_msp430x_relocs (abfd
))
2050 opcode
= 0x0080; /* JMP -> BRA */
2052 opcode
= 0x4030; /* JMP -> BR */
2055 /* Unhandled branch instruction. */
2056 /* fprintf (stderr, "unrecog: %x\n", opcode); */
2060 /* Note that we've changed the relocs, section contents, etc. */
2061 elf_section_data (sec
)->relocs
= internal_relocs
;
2062 elf_section_data (sec
)->this_hdr
.contents
= contents
;
2063 symtab_hdr
->contents
= (unsigned char *) isymbuf
;
2065 /* Install the new opcode. */
2066 bfd_put_16 (abfd
, opcode
, contents
+ irel
->r_offset
);
2068 /* Insert the new branch instruction. */
2069 if (uses_msp430x_relocs (abfd
))
2072 printf (" R_MSP430X_10_PCREL -> R_MSP430X_ABS20_ADR_SRC "
2073 "(growing with new opcode 0x%x)\n", opcode
);
2075 /* Insert an absolute branch (aka MOVA) instruction.
2076 Note that bits 19:16 of the address are stored in the first word
2077 of the insn, so this is where r_offset will point to. */
2078 if (opcode
== 0x0080)
2080 /* If we're inserting a BRA because we are converting from a JMP,
2081 then only add one word for destination address; the BRA opcode
2082 has already been written. */
2083 contents
= msp430_elf_relax_add_words
2084 (abfd
, sec
, irel
->r_offset
+ 2, 1, 0x0000, 0);
2088 contents
= msp430_elf_relax_add_words
2089 (abfd
, sec
, irel
->r_offset
+ 2, 2, 0x0080, 0x0000);
2090 /* Update the relocation to point to the inserted branch
2091 instruction. Note - we are changing a PC-relative reloc
2092 into an absolute reloc, but this is OK because we have
2093 arranged with the assembler to have the reloc's value be
2094 a (local) symbol, not a section+offset value. */
2095 irel
->r_offset
+= 2;
2098 irel
->r_info
= ELF32_R_INFO (ELF32_R_SYM (irel
->r_info
),
2099 R_MSP430X_ABS20_ADR_SRC
);
2104 printf (" R_MSP430_10_PCREL -> R_MSP430_16 "
2105 "(growing with new opcode 0x%x)\n", opcode
);
2106 if (opcode
== 0x4030)
2108 /* If we're inserting a BR because we are converting from a JMP,
2109 then only add one word for destination address; the BR opcode
2110 has already been written. */
2111 contents
= msp430_elf_relax_add_words
2112 (abfd
, sec
, irel
->r_offset
+ 2, 1, 0x0000, 0);
2113 irel
->r_offset
+= 2;
2117 contents
= msp430_elf_relax_add_words
2118 (abfd
, sec
, irel
->r_offset
+ 2, 2, 0x4030, 0x0000);
2119 /* See comment above about converting a 10-bit PC-rel
2120 relocation into a 16-bit absolute relocation. */
2121 irel
->r_offset
+= 4;
2123 irel
->r_info
= ELF32_R_INFO (ELF32_R_SYM (irel
->r_info
),
2127 /* Growing the section may mean that other
2128 conditional branches need to be fixed. */
2133 printf (" trying code size shrinking relocs\n");
2135 for (irel
= internal_relocs
; irel
< irelend
; irel
++)
2139 /* Get the section contents if we haven't done so already. */
2140 if (contents
== NULL
)
2142 /* Get cached copy if it exists. */
2143 if (elf_section_data (sec
)->this_hdr
.contents
!= NULL
)
2144 contents
= elf_section_data (sec
)->this_hdr
.contents
;
2145 else if (! bfd_malloc_and_get_section (abfd
, sec
, &contents
))
2149 /* Read this BFD's local symbols if we haven't done so already. */
2150 if (isymbuf
== NULL
&& symtab_hdr
->sh_info
!= 0)
2152 isymbuf
= (Elf_Internal_Sym
*) symtab_hdr
->contents
;
2153 if (isymbuf
== NULL
)
2154 isymbuf
= bfd_elf_get_elf_syms (abfd
, symtab_hdr
,
2155 symtab_hdr
->sh_info
, 0,
2157 if (isymbuf
== NULL
)
2161 /* Get the value of the symbol referred to by the reloc. */
2162 if (ELF32_R_SYM (irel
->r_info
) < symtab_hdr
->sh_info
)
2164 /* A local symbol. */
2165 Elf_Internal_Sym
*isym
;
2168 isym
= isymbuf
+ ELF32_R_SYM (irel
->r_info
);
2169 if (isym
->st_shndx
== SHN_UNDEF
)
2170 sym_sec
= bfd_und_section_ptr
;
2171 else if (isym
->st_shndx
== SHN_ABS
)
2172 sym_sec
= bfd_abs_section_ptr
;
2173 else if (isym
->st_shndx
== SHN_COMMON
)
2174 sym_sec
= bfd_com_section_ptr
;
2176 sym_sec
= bfd_section_from_elf_index (abfd
, isym
->st_shndx
);
2177 symval
= (isym
->st_value
2178 + sym_sec
->output_section
->vma
+ sym_sec
->output_offset
);
2181 printf (" processing reloc at 0x%lx for local sym: %s "
2182 "st_value: 0x%lx adj value: 0x%lx\n",
2183 (long) (sec
->output_offset
+ sec
->output_section
->vma
2185 bfd_elf_string_from_elf_section
2186 (abfd
, symtab_hdr
->sh_link
, isym
->st_name
),
2187 (long) isym
->st_value
, (long) symval
);
2192 struct elf_link_hash_entry
*h
;
2194 /* An external symbol. */
2195 indx
= ELF32_R_SYM (irel
->r_info
) - symtab_hdr
->sh_info
;
2196 h
= elf_sym_hashes (abfd
)[indx
];
2197 BFD_ASSERT (h
!= NULL
);
2199 if (h
->root
.type
!= bfd_link_hash_defined
2200 && h
->root
.type
!= bfd_link_hash_defweak
)
2201 /* This appears to be a reference to an undefined
2202 symbol. Just ignore it--it will be caught by the
2203 regular reloc processing. */
2206 symval
= (h
->root
.u
.def
.value
2207 + h
->root
.u
.def
.section
->output_section
->vma
2208 + h
->root
.u
.def
.section
->output_offset
);
2210 printf (" processing reloc at 0x%lx for global sym: %s "
2211 "st_value: 0x%lx adj value: 0x%lx\n", (long)
2212 (sec
->output_offset
+ sec
->output_section
->vma
2214 h
->root
.root
.string
, (long) h
->root
.u
.def
.value
,
2218 /* For simplicity of coding, we are going to modify the section
2219 contents, the section relocs, and the BFD symbol table. We
2220 must tell the rest of the code not to free up this
2221 information. It would be possible to instead create a table
2222 of changes which have to be made, as is done in coff-mips.c;
2223 that would be more work, but would require less memory when
2224 the linker is run. */
2226 /* Try to turn a 16bit pc-relative branch into a 10bit pc-relative
2228 /* Paranoia? paranoia... */
2229 if (! uses_msp430x_relocs (abfd
)
2230 && ELF32_R_TYPE (irel
->r_info
) == (int) R_MSP430_RL_PCREL
)
2232 bfd_vma value
= symval
;
2234 /* Deal with pc-relative gunk. */
2235 value
-= (sec
->output_section
->vma
+ sec
->output_offset
);
2236 value
-= irel
->r_offset
;
2237 value
+= irel
->r_addend
;
2239 /* See if the value will fit in 10 bits, note the high value is
2240 1016 as the target will be two bytes closer if we are
2242 if ((long) value
< 1016 && (long) value
> -1016)
2244 int code0
= 0, code1
= 0, code2
= 0;
2246 struct rcodes_s
*rx
;
2248 /* Get the opcode. */
2249 if (irel
->r_offset
>= 6)
2250 code0
= bfd_get_16 (abfd
, contents
+ irel
->r_offset
- 6);
2252 if (irel
->r_offset
>= 4)
2253 code1
= bfd_get_16 (abfd
, contents
+ irel
->r_offset
- 4);
2255 code2
= bfd_get_16 (abfd
, contents
+ irel
->r_offset
- 2);
2257 if (code2
!= 0x4010)
2260 /* Check r4 and r3. */
2261 for (i
= NUMB_RELAX_CODES
- 1; i
>= 0; i
--)
2264 if (rx
->cdx
== 2 && rx
->f0
== code0
&& rx
->f1
== code1
)
2266 else if (rx
->cdx
== 1 && rx
->f1
== code1
)
2268 else if (rx
->cdx
== 0) /* This is an unconditional jump. */
2273 .Label0: ; we do not care about this label
2275 .Label1: ; make sure there is no label here
2277 .Label2: ; make sure there is no label here
2280 So, if there is .Label1 or .Label2 we cannot relax this code.
2281 This actually should not happen, cause for relaxable
2282 instructions we use RL_PCREL reloc instead of 16_PCREL.
2283 Will change this in the future. */
2286 && msp430_elf_symbol_address_p (abfd
, sec
, isymbuf
,
2287 irel
->r_offset
- 2))
2290 && msp430_elf_symbol_address_p (abfd
, sec
, isymbuf
,
2291 irel
->r_offset
- 4))
2294 /* Note that we've changed the relocs, section contents, etc. */
2295 elf_section_data (sec
)->relocs
= internal_relocs
;
2296 elf_section_data (sec
)->this_hdr
.contents
= contents
;
2297 symtab_hdr
->contents
= (unsigned char *) isymbuf
;
2300 printf (" R_MSP430_RL_PCREL -> ");
2301 /* Fix the relocation's type. */
2302 if (uses_msp430x_relocs (abfd
))
2304 if (rx
->labels
== 3) /* Handle special cases. */
2305 irel
->r_info
= ELF32_R_INFO (ELF32_R_SYM (irel
->r_info
),
2306 R_MSP430X_2X_PCREL
);
2308 irel
->r_info
= ELF32_R_INFO (ELF32_R_SYM (irel
->r_info
),
2309 R_MSP430X_10_PCREL
);
2313 if (rx
->labels
== 3) /* Handle special cases. */
2315 irel
->r_info
= ELF32_R_INFO (ELF32_R_SYM (irel
->r_info
),
2318 printf ("R_MSP430_2X_PCREL (shrinking with new opcode"
2319 " 0x%x)\n", rx
->t0
);
2323 irel
->r_info
= ELF32_R_INFO (ELF32_R_SYM (irel
->r_info
),
2326 printf ("R_MSP430_10_PCREL (shrinking with new opcode"
2327 " 0x%x)\n", rx
->t0
);
2331 /* Fix the opcode right way. */
2332 bfd_put_16 (abfd
, rx
->t0
, contents
+ irel
->r_offset
- rx
->off
);
2334 bfd_put_16 (abfd
, rx
->t1
,
2335 contents
+ irel
->r_offset
- rx
->off
+ 2);
2338 if (!msp430_elf_relax_delete_bytes (abfd
, sec
,
2339 irel
->r_offset
- rx
->off
+
2343 /* Handle unconditional jumps. */
2345 irel
->r_offset
-= 2;
2347 /* That will change things, so, we should relax again.
2348 Note that this is not required, and it may be slow. */
2353 /* Try to turn a 16-bit absolute branch into a 10-bit pc-relative
2355 if ((uses_msp430x_relocs (abfd
)
2356 && ELF32_R_TYPE (irel
->r_info
) == R_MSP430X_ABS16
)
2357 || (! uses_msp430x_relocs (abfd
)
2358 && ELF32_R_TYPE (irel
->r_info
) == R_MSP430_16
))
2360 bfd_vma value
= symval
;
2362 value
-= (sec
->output_section
->vma
+ sec
->output_offset
);
2363 value
-= irel
->r_offset
;
2364 value
+= irel
->r_addend
;
2366 /* See if the value will fit in 10 bits, note the high value is
2367 1016 as the target will be two bytes closer if we are
2369 if ((long) value
< 1016 && (long) value
> -1016)
2371 int code1
, code2
, opcode
;
2373 /* Get the opcode. */
2374 code2
= bfd_get_16 (abfd
, contents
+ irel
->r_offset
- 2);
2375 if (code2
!= 0x4030) /* BR -> JMP */
2377 /* FIXME: check r4 and r3 ? */
2378 /* FIXME: Handle 0x4010 as well ? */
2380 /* Note that we've changed the relocs, section contents, etc. */
2381 elf_section_data (sec
)->relocs
= internal_relocs
;
2382 elf_section_data (sec
)->this_hdr
.contents
= contents
;
2383 symtab_hdr
->contents
= (unsigned char *) isymbuf
;
2385 /* Fix the relocation's type. */
2386 if (uses_msp430x_relocs (abfd
))
2388 irel
->r_info
= ELF32_R_INFO (ELF32_R_SYM (irel
->r_info
),
2389 R_MSP430X_10_PCREL
);
2391 printf (" R_MSP430X_16 -> R_MSP430X_10_PCREL ");
2395 irel
->r_info
= ELF32_R_INFO (ELF32_R_SYM (irel
->r_info
),
2398 printf (" R_MSP430_16 -> R_MSP430_10_PCREL ");
2400 /* If we're trying to shrink a BR[A] after previously having
2401 grown a JMP for this reloc, then we have a sequence like
2406 The opcode for J<cond> has the target hard-coded as 2 words
2407 ahead of the insn, instead of using a reloc.
2408 This means we cannot rely on any of the helper functions to
2409 update this hard-coded jump destination if we remove the
2410 BR[A] insn, so we must explicitly update it here.
2411 This does mean that we can remove the entire branch
2412 instruction, and invert the conditional jump, saving us 4
2413 bytes rather than only 2 if we detected this in the normal
2415 code1
= bfd_get_16 (abfd
, contents
+ irel
->r_offset
- 4);
2418 case 0x3802: opcode
= 0x3401; break; /* Jl +2 -> Jge +1 */
2419 case 0x3402: opcode
= 0x3801; break; /* Jge +2 -> Jl +1 */
2420 case 0x2c02: opcode
= 0x2801; break; /* Jhs +2 -> Jlo +1 */
2421 case 0x2802: opcode
= 0x2c01; break; /* Jlo +2 -> Jhs +1 */
2422 case 0x2402: opcode
= 0x2001; break; /* Jeq +2 -> Jne +1 */
2423 case 0x2002: opcode
= 0x2401; break; /* jne +2 -> Jeq +1 */
2424 case 0x3002: /* jn +2 */
2425 /* FIXME: There is no direct inverse of the Jn insn. */
2428 /* The previous opcode does not have a hard-coded jump
2429 that we added when previously relaxing, so relax the
2430 current branch as normal. */
2435 printf ("(shrinking with new opcode 0x%x)\n", opcode
);
2437 if (opcode
!= 0x3c00)
2439 /* Invert the opcode of the conditional jump. */
2440 bfd_put_16 (abfd
, opcode
, contents
+ irel
->r_offset
- 4);
2441 irel
->r_offset
-= 4;
2443 /* Delete 4 bytes - the full BR insn. */
2444 if (!msp430_elf_relax_delete_bytes (abfd
, sec
,
2445 irel
->r_offset
+ 2, 4))
2450 /* Fix the opcode right way. */
2451 bfd_put_16 (abfd
, opcode
, contents
+ irel
->r_offset
- 2);
2452 irel
->r_offset
-= 2;
2455 if (!msp430_elf_relax_delete_bytes (abfd
, sec
,
2456 irel
->r_offset
+ 2, 2))
2460 /* That will change things, so, we should relax again.
2461 Note that this is not required, and it may be slow. */
2467 if (isymbuf
!= NULL
&& symtab_hdr
->contents
!= (unsigned char *) isymbuf
)
2469 if (!link_info
->keep_memory
)
2473 /* Cache the symbols for elf_link_input_bfd. */
2474 symtab_hdr
->contents
= (unsigned char *) isymbuf
;
2478 if (contents
!= NULL
2479 && elf_section_data (sec
)->this_hdr
.contents
!= contents
)
2481 if (!link_info
->keep_memory
)
2485 /* Cache the section contents for elf_link_input_bfd. */
2486 elf_section_data (sec
)->this_hdr
.contents
= contents
;
2490 if (internal_relocs
!= NULL
2491 && elf_section_data (sec
)->relocs
!= internal_relocs
)
2492 free (internal_relocs
);
2497 if (isymbuf
!= NULL
&& symtab_hdr
->contents
!= (unsigned char *) isymbuf
)
2499 if (contents
!= NULL
2500 && elf_section_data (sec
)->this_hdr
.contents
!= contents
)
2502 if (internal_relocs
!= NULL
2503 && elf_section_data (sec
)->relocs
!= internal_relocs
)
2504 free (internal_relocs
);
2509 /* Handle an MSP430 specific section when reading an object file.
2510 This is called when bfd_section_from_shdr finds a section with
2514 elf32_msp430_section_from_shdr (bfd
*abfd
,
2515 Elf_Internal_Shdr
* hdr
,
2519 switch (hdr
->sh_type
)
2521 case SHT_MSP430_SEC_FLAGS
:
2522 case SHT_MSP430_SYM_ALIASES
:
2523 case SHT_MSP430_ATTRIBUTES
:
2524 return _bfd_elf_make_section_from_shdr (abfd
, hdr
, name
, shindex
);
2531 elf32_msp430_obj_attrs_handle_unknown (bfd
*abfd
, int tag
)
2534 /* xgettext:c-format */
2535 (_("warning: %pB: unknown MSPABI object attribute %d"),
2540 /* Determine whether an object attribute tag takes an integer, a
2544 elf32_msp430_obj_attrs_arg_type (int tag
)
2546 if (tag
== Tag_compatibility
)
2547 return ATTR_TYPE_FLAG_INT_VAL
| ATTR_TYPE_FLAG_STR_VAL
;
2550 return ATTR_TYPE_FLAG_INT_VAL
;
2552 return (tag
& 1) != 0 ? ATTR_TYPE_FLAG_STR_VAL
: ATTR_TYPE_FLAG_INT_VAL
;
2555 static inline const char *
2560 case 1: return "MSP430";
2561 case 2: return "MSP430X";
2562 default: return "unknown";
2566 static inline const char *
2567 code_model (int model
)
2571 case 1: return "small";
2572 case 2: return "large";
2573 default: return "unknown";
2577 static inline const char *
2578 data_model (int model
)
2582 case 1: return "small";
2583 case 2: return "large";
2584 case 3: return "restricted large";
2585 default: return "unknown";
2589 /* Merge MSPABI and GNU object attributes from IBFD into OBFD.
2590 Raise an error if there are conflicting attributes. */
2593 elf32_msp430_merge_msp430_attributes (bfd
*ibfd
, struct bfd_link_info
*info
)
2595 bfd
*obfd
= info
->output_bfd
;
2596 obj_attribute
*in_msp_attr
, *in_gnu_attr
;
2597 obj_attribute
*out_msp_attr
, *out_gnu_attr
;
2598 bfd_boolean result
= TRUE
;
2599 static bfd
* first_input_bfd
= NULL
;
2601 /* Skip linker created files. */
2602 if (ibfd
->flags
& BFD_LINKER_CREATED
)
2605 /* LTO can create temporary files for linking which may not have an attribute
2607 if (ibfd
->lto_output
2608 && bfd_get_section_by_name (ibfd
, ".MSP430.attributes") == NULL
)
2611 /* If this is the first real object just copy the attributes. */
2612 if (!elf_known_obj_attributes_proc (obfd
)[0].i
)
2614 _bfd_elf_copy_obj_attributes (ibfd
, obfd
);
2616 out_msp_attr
= elf_known_obj_attributes_proc (obfd
);
2618 /* Use the Tag_null value to indicate that
2619 the attributes have been initialized. */
2620 out_msp_attr
[0].i
= 1;
2622 first_input_bfd
= ibfd
;
2626 in_msp_attr
= elf_known_obj_attributes_proc (ibfd
);
2627 out_msp_attr
= elf_known_obj_attributes_proc (obfd
);
2628 in_gnu_attr
= elf_known_obj_attributes (ibfd
) [OBJ_ATTR_GNU
];
2629 out_gnu_attr
= elf_known_obj_attributes (obfd
) [OBJ_ATTR_GNU
];
2631 /* The ISAs must be the same. */
2632 if (in_msp_attr
[OFBA_MSPABI_Tag_ISA
].i
!= out_msp_attr
[OFBA_MSPABI_Tag_ISA
].i
)
2635 /* xgettext:c-format */
2636 (_("error: %pB uses %s instructions but %pB uses %s"),
2637 ibfd
, isa_type (in_msp_attr
[OFBA_MSPABI_Tag_ISA
].i
),
2638 first_input_bfd
, isa_type (out_msp_attr
[OFBA_MSPABI_Tag_ISA
].i
));
2642 /* The code models must be the same. */
2643 if (in_msp_attr
[OFBA_MSPABI_Tag_Code_Model
].i
2644 != out_msp_attr
[OFBA_MSPABI_Tag_Code_Model
].i
)
2647 /* xgettext:c-format */
2648 (_("error: %pB uses the %s code model whereas %pB uses the %s code model"),
2649 ibfd
, code_model (in_msp_attr
[OFBA_MSPABI_Tag_Code_Model
].i
),
2651 code_model (out_msp_attr
[OFBA_MSPABI_Tag_Code_Model
].i
));
2655 /* The large code model is only supported by the MSP430X. */
2656 if (in_msp_attr
[OFBA_MSPABI_Tag_Code_Model
].i
== 2
2657 && out_msp_attr
[OFBA_MSPABI_Tag_ISA
].i
!= 2)
2660 /* xgettext:c-format */
2661 (_("error: %pB uses the large code model but %pB uses MSP430 instructions"),
2662 ibfd
, first_input_bfd
);
2666 /* The data models must be the same. */
2667 if (in_msp_attr
[OFBA_MSPABI_Tag_Data_Model
].i
2668 != out_msp_attr
[OFBA_MSPABI_Tag_Data_Model
].i
)
2671 /* xgettext:c-format */
2672 (_("error: %pB uses the %s data model whereas %pB uses the %s data model"),
2673 ibfd
, data_model (in_msp_attr
[OFBA_MSPABI_Tag_Data_Model
].i
),
2675 data_model (out_msp_attr
[OFBA_MSPABI_Tag_Data_Model
].i
));
2679 /* The small code model requires the use of the small data model. */
2680 if (in_msp_attr
[OFBA_MSPABI_Tag_Code_Model
].i
== 1
2681 && out_msp_attr
[OFBA_MSPABI_Tag_Data_Model
].i
!= 1)
2684 /* xgettext:c-format */
2685 (_("error: %pB uses the small code model but %pB uses the %s data model"),
2686 ibfd
, first_input_bfd
,
2687 data_model (out_msp_attr
[OFBA_MSPABI_Tag_Data_Model
].i
));
2691 /* The large data models are only supported by the MSP430X. */
2692 if (in_msp_attr
[OFBA_MSPABI_Tag_Data_Model
].i
> 1
2693 && out_msp_attr
[OFBA_MSPABI_Tag_ISA
].i
!= 2)
2696 /* xgettext:c-format */
2697 (_("error: %pB uses the %s data model but %pB only uses MSP430 instructions"),
2698 ibfd
, data_model (in_msp_attr
[OFBA_MSPABI_Tag_Data_Model
].i
),
2703 /* Just ignore the data region unless the large memory model is in use.
2704 We have already checked that ibfd and obfd use the same memory model. */
2705 if ((in_msp_attr
[OFBA_MSPABI_Tag_Code_Model
].i
2706 == OFBA_MSPABI_Val_Code_Model_LARGE
)
2707 && (in_msp_attr
[OFBA_MSPABI_Tag_Data_Model
].i
2708 == OFBA_MSPABI_Val_Data_Model_LARGE
))
2710 /* We cannot allow "lower region only" to be linked with any other
2711 values (i.e. ANY or NONE).
2712 Before this attribute existed, "ANY" region was the default. */
2713 bfd_boolean ibfd_lower_region_used
2714 = (in_gnu_attr
[Tag_GNU_MSP430_Data_Region
].i
2715 == Val_GNU_MSP430_Data_Region_Lower
);
2716 bfd_boolean obfd_lower_region_used
2717 = (out_gnu_attr
[Tag_GNU_MSP430_Data_Region
].i
2718 == Val_GNU_MSP430_Data_Region_Lower
);
2719 if (ibfd_lower_region_used
!= obfd_lower_region_used
)
2722 (_("error: %pB can use the upper region for data, "
2723 "but %pB assumes data is exclusively in lower memory"),
2724 ibfd_lower_region_used
? obfd
: ibfd
,
2725 ibfd_lower_region_used
? ibfd
: obfd
);
2733 /* Merge backend specific data from an object file to the output
2734 object file when linking. */
2737 elf32_msp430_merge_private_bfd_data (bfd
*ibfd
, struct bfd_link_info
*info
)
2739 bfd
*obfd
= info
->output_bfd
;
2740 /* Make sure that the machine number reflects the most
2741 advanced version of the MSP architecture required. */
2742 #define max(a,b) ((a) > (b) ? (a) : (b))
2743 if (bfd_get_mach (ibfd
) != bfd_get_mach (obfd
))
2744 bfd_default_set_arch_mach (obfd
, bfd_get_arch (obfd
),
2745 max (bfd_get_mach (ibfd
), bfd_get_mach (obfd
)));
2748 return elf32_msp430_merge_msp430_attributes (ibfd
, info
);
2752 msp430_elf_is_target_special_symbol (bfd
*abfd
, asymbol
*sym
)
2754 return _bfd_elf_is_local_label_name (abfd
, sym
->name
);
2758 uses_large_model (bfd
*abfd
)
2760 obj_attribute
* attr
;
2762 if (abfd
->flags
& BFD_LINKER_CREATED
)
2765 attr
= elf_known_obj_attributes_proc (abfd
);
2769 return attr
[OFBA_MSPABI_Tag_Code_Model
].i
== 2;
2773 elf32_msp430_eh_frame_address_size (bfd
*abfd
,
2774 const asection
*sec ATTRIBUTE_UNUSED
)
2776 return uses_large_model (abfd
) ? 4 : 2;
2779 /* This is gross. The MSP430 EABI says that (sec 11.5):
2781 "An implementation may choose to use Rel or Rela
2782 type relocations for other relocations."
2784 But it also says that:
2786 "Certain relocations are identified as Rela only. [snip]
2787 Where Rela is specified, an implementation must honor
2790 There is one relocation marked as requiring RELA - R_MSP430_ABS_HI16 - but
2791 to keep things simple we choose to use RELA relocations throughout. The
2792 problem is that the TI compiler generates REL relocations, so we have to
2793 be able to accept those as well. */
2795 #define elf_backend_may_use_rel_p 1
2796 #define elf_backend_may_use_rela_p 1
2797 #define elf_backend_default_use_rela_p 1
2799 #undef elf_backend_obj_attrs_vendor
2800 #define elf_backend_obj_attrs_vendor "mspabi"
2801 #undef elf_backend_obj_attrs_section
2802 #define elf_backend_obj_attrs_section ".MSP430.attributes"
2803 #undef elf_backend_obj_attrs_section_type
2804 #define elf_backend_obj_attrs_section_type SHT_MSP430_ATTRIBUTES
2805 #define elf_backend_section_from_shdr elf32_msp430_section_from_shdr
2806 #define elf_backend_obj_attrs_handle_unknown elf32_msp430_obj_attrs_handle_unknown
2807 #undef elf_backend_obj_attrs_arg_type
2808 #define elf_backend_obj_attrs_arg_type elf32_msp430_obj_attrs_arg_type
2809 #define bfd_elf32_bfd_merge_private_bfd_data elf32_msp430_merge_private_bfd_data
2810 #define elf_backend_eh_frame_address_size elf32_msp430_eh_frame_address_size
2812 #define ELF_ARCH bfd_arch_msp430
2813 #define ELF_MACHINE_CODE EM_MSP430
2814 #define ELF_MACHINE_ALT1 EM_MSP430_OLD
2815 #define ELF_MAXPAGESIZE 4
2816 #define ELF_OSABI ELFOSABI_STANDALONE
2818 #define TARGET_LITTLE_SYM msp430_elf32_vec
2819 #define TARGET_LITTLE_NAME "elf32-msp430"
2821 #define elf_info_to_howto msp430_info_to_howto_rela
2822 #define elf_info_to_howto_rel NULL
2823 #define elf_backend_relocate_section elf32_msp430_relocate_section
2824 #define elf_backend_check_relocs elf32_msp430_check_relocs
2825 #define elf_backend_can_gc_sections 1
2826 #define elf_backend_final_write_processing bfd_elf_msp430_final_write_processing
2827 #define elf_backend_object_p elf32_msp430_object_p
2828 #define bfd_elf32_bfd_relax_section msp430_elf_relax_section
2829 #define bfd_elf32_bfd_is_target_special_symbol msp430_elf_is_target_special_symbol
2832 #define elf32_bed elf32_msp430_bed
2834 #include "elf32-target.h"
2836 /* The TI compiler sets the OSABI field to ELFOSABI_NONE. */
2837 #undef TARGET_LITTLE_SYM
2838 #define TARGET_LITTLE_SYM msp430_elf32_ti_vec
2841 #define elf32_bed elf32_msp430_ti_bed
2844 #define ELF_OSABI ELFOSABI_NONE
2846 static const struct bfd_elf_special_section msp430_ti_elf_special_sections
[] =
2848 /* prefix, prefix_length, suffix_len, type, attributes. */
2849 { STRING_COMMA_LEN (".TI.symbol.alias"), 0, SHT_MSP430_SYM_ALIASES
, 0 },
2850 { STRING_COMMA_LEN (".TI.section.flags"), 0, SHT_MSP430_SEC_FLAGS
, 0 },
2851 { STRING_COMMA_LEN ("_TI_build_attrib"), 0, SHT_MSP430_ATTRIBUTES
, 0 },
2852 { NULL
, 0, 0, 0, 0 }
2855 #undef elf_backend_special_sections
2856 #define elf_backend_special_sections msp430_ti_elf_special_sections
2858 #include "elf32-target.h"