MSP430: Enable relaxation of relocs in JMP instructions
[deliverable/binutils-gdb.git] / bfd / elf32-msp430.c
CommitLineData
2469cfa2 1/* MSP430-specific support for 32-bit ELF
b3adc24a 2 Copyright (C) 2002-2020 Free Software Foundation, Inc.
2469cfa2
NC
3 Contributed by Dmitry Diky <diwil@mail.ru>
4
5 This file is part of BFD, the Binary File Descriptor library.
6
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
cd123cb7 9 the Free Software Foundation; either version 3 of the License, or
2469cfa2
NC
10 (at your option) any later version.
11
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.
16
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
cd123cb7
NC
19 Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
20 MA 02110-1301, USA. */
2469cfa2 21
2469cfa2 22#include "sysdep.h"
3db64b00 23#include "bfd.h"
2469cfa2
NC
24#include "libiberty.h"
25#include "libbfd.h"
26#include "elf-bfd.h"
27#include "elf/msp430.h"
28
d60f5448
JL
29static bfd_boolean debug_relocs = 0;
30
bb294208
AM
31/* All users of this file have bfd_octets_per_byte (abfd, sec) == 1. */
32#define OCTETS_PER_BYTE(ABFD, SEC) 1
33
1ade7175
NC
34static bfd_reloc_status_type
35rl78_sym_diff_handler (bfd * abfd,
36 arelent * reloc,
37 asymbol * sym ATTRIBUTE_UNUSED,
38 void * addr ATTRIBUTE_UNUSED,
39 asection * input_sec,
40 bfd * out_bfd ATTRIBUTE_UNUSED,
41 char ** error_message ATTRIBUTE_UNUSED)
42{
43 bfd_size_type octets;
bb294208 44 octets = reloc->address * OCTETS_PER_BYTE (abfd, input_sec);
1ade7175
NC
45
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.
51
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))
55 return bfd_reloc_ok;
56 return bfd_reloc_continue;
57}
58
2469cfa2
NC
59static reloc_howto_type elf_msp430_howto_table[] =
60{
61 HOWTO (R_MSP430_NONE, /* type */
62 0, /* rightshift */
6346d5ca
AM
63 3, /* size (0 = byte, 1 = short, 2 = long) */
64 0, /* bitsize */
2469cfa2
NC
65 FALSE, /* pc_relative */
66 0, /* bitpos */
6346d5ca 67 complain_overflow_dont,/* complain_on_overflow */
2469cfa2
NC
68 bfd_elf_generic_reloc, /* special_function */
69 "R_MSP430_NONE", /* name */
70 FALSE, /* partial_inplace */
71 0, /* src_mask */
72 0, /* dst_mask */
73 FALSE), /* pcrel_offset */
74
75 HOWTO (R_MSP430_32, /* type */
76 0, /* rightshift */
77 2, /* size (0 = byte, 1 = short, 2 = long) */
78 32, /* bitsize */
79 FALSE, /* pc_relative */
80 0, /* bitpos */
b18c562e 81 complain_overflow_bitfield,/* complain_on_overflow */
2469cfa2
NC
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 */
88
df301bfc 89 /* A 10 bit PC relative relocation. */
2469cfa2
NC
90 HOWTO (R_MSP430_10_PCREL, /* type */
91 1, /* rightshift */
92 1, /* size (0 = byte, 1 = short, 2 = long) */
93 10, /* bitsize */
94 TRUE, /* pc_relative */
95 0, /* bitpos */
b18c562e 96 complain_overflow_bitfield,/* complain_on_overflow */
2469cfa2 97 bfd_elf_generic_reloc, /* special_function */
13761a11 98 "R_MSP430_10_PCREL", /* name */
2469cfa2 99 FALSE, /* partial_inplace */
df301bfc
NC
100 0x3ff, /* src_mask */
101 0x3ff, /* dst_mask */
2469cfa2
NC
102 TRUE), /* pcrel_offset */
103
104 /* A 16 bit absolute relocation. */
105 HOWTO (R_MSP430_16, /* type */
106 0, /* rightshift */
107 1, /* size (0 = byte, 1 = short, 2 = long) */
108 16, /* bitsize */
109 FALSE, /* pc_relative */
110 0, /* bitpos */
111 complain_overflow_dont,/* complain_on_overflow */
112 bfd_elf_generic_reloc, /* special_function */
113 "R_MSP430_16", /* name */
114 FALSE, /* partial_inplace */
b18c562e 115 0, /* src_mask */
2469cfa2
NC
116 0xffff, /* dst_mask */
117 FALSE), /* pcrel_offset */
118
13761a11 119 /* A 16 bit PC relative relocation for command address. */
2469cfa2
NC
120 HOWTO (R_MSP430_16_PCREL, /* type */
121 1, /* rightshift */
122 1, /* size (0 = byte, 1 = short, 2 = long) */
123 16, /* bitsize */
124 TRUE, /* pc_relative */
125 0, /* bitpos */
126 complain_overflow_dont,/* complain_on_overflow */
127 bfd_elf_generic_reloc, /* special_function */
128 "R_MSP430_16_PCREL", /* name */
129 FALSE, /* partial_inplace */
b18c562e 130 0, /* src_mask */
2469cfa2
NC
131 0xffff, /* dst_mask */
132 TRUE), /* pcrel_offset */
133
134 /* A 16 bit absolute relocation, byte operations. */
135 HOWTO (R_MSP430_16_BYTE, /* type */
136 0, /* rightshift */
137 1, /* size (0 = byte, 1 = short, 2 = long) */
138 16, /* bitsize */
139 FALSE, /* pc_relative */
140 0, /* bitpos */
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 */
148
149 /* A 16 bit absolute relocation for command address. */
150 HOWTO (R_MSP430_16_PCREL_BYTE,/* type */
151 1, /* rightshift */
152 1, /* size (0 = byte, 1 = short, 2 = long) */
153 16, /* bitsize */
154 TRUE, /* pc_relative */
155 0, /* bitpos */
156 complain_overflow_dont,/* complain_on_overflow */
157 bfd_elf_generic_reloc, /* special_function */
b18c562e 158 "R_MSP430_16_PCREL_BYTE",/* name */
2469cfa2
NC
159 FALSE, /* partial_inplace */
160 0xffff, /* src_mask */
161 0xffff, /* dst_mask */
b18c562e
NC
162 TRUE), /* pcrel_offset */
163
df301bfc 164 /* A 10 bit PC relative relocation for complicated polymorphs. */
b18c562e
NC
165 HOWTO (R_MSP430_2X_PCREL, /* type */
166 1, /* rightshift */
167 2, /* size (0 = byte, 1 = short, 2 = long) */
168 10, /* bitsize */
169 TRUE, /* pc_relative */
170 0, /* bitpos */
171 complain_overflow_bitfield,/* complain_on_overflow */
172 bfd_elf_generic_reloc, /* special_function */
173 "R_MSP430_2X_PCREL", /* name */
174 FALSE, /* partial_inplace */
df301bfc
NC
175 0x3ff, /* src_mask */
176 0x3ff, /* dst_mask */
b18c562e
NC
177 TRUE), /* pcrel_offset */
178
179 /* A 16 bit relaxable relocation for command address. */
180 HOWTO (R_MSP430_RL_PCREL, /* type */
181 1, /* rightshift */
182 1, /* size (0 = byte, 1 = short, 2 = long) */
183 16, /* bitsize */
184 TRUE, /* pc_relative */
185 0, /* bitpos */
186 complain_overflow_dont,/* complain_on_overflow */
187 bfd_elf_generic_reloc, /* special_function */
188 "R_MSP430_RL_PCREL", /* name */
189 FALSE, /* partial_inplace */
190 0, /* src_mask */
191 0xffff, /* dst_mask */
2469cfa2 192 TRUE) /* pcrel_offset */
13761a11
NC
193
194 /* A 8-bit absolute relocation. */
195 , HOWTO (R_MSP430_8, /* type */
196 0, /* rightshift */
197 0, /* size (0 = byte, 1 = short, 2 = long) */
198 8, /* bitsize */
199 FALSE, /* pc_relative */
200 0, /* bitpos */
201 complain_overflow_dont,/* complain_on_overflow */
202 bfd_elf_generic_reloc, /* special_function */
203 "R_MSP430_8", /* name */
204 FALSE, /* partial_inplace */
205 0, /* src_mask */
206 0xffff, /* dst_mask */
207 FALSE), /* pcrel_offset */
208
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 */
212 0, /* rightshift */
213 2, /* size (0 = byte, 1 = short, 2 = long) */
214 32, /* bitsize */
215 FALSE, /* pc_relative */
216 0, /* bitpos */
217 complain_overflow_dont,/* complain_on_overflow */
1ade7175 218 rl78_sym_diff_handler, /* special handler. */
13761a11
NC
219 "R_MSP430_SYM_DIFF", /* name */
220 FALSE, /* partial_inplace */
221 0xffffffff, /* src_mask */
222 0xffffffff, /* dst_mask */
1b786873 223 FALSE) /* pcrel_offset */
13761a11
NC
224};
225
226static reloc_howto_type elf_msp430x_howto_table[] =
227{
228 HOWTO (R_MSP430_NONE, /* type */
229 0, /* rightshift */
6346d5ca
AM
230 3, /* size (0 = byte, 1 = short, 2 = long) */
231 0, /* bitsize */
13761a11
NC
232 FALSE, /* pc_relative */
233 0, /* bitpos */
6346d5ca 234 complain_overflow_dont,/* complain_on_overflow */
13761a11
NC
235 bfd_elf_generic_reloc, /* special_function */
236 "R_MSP430_NONE", /* name */
237 FALSE, /* partial_inplace */
238 0, /* src_mask */
239 0, /* dst_mask */
240 FALSE), /* pcrel_offset */
241
242 HOWTO (R_MSP430_ABS32, /* type */
243 0, /* rightshift */
244 2, /* size (0 = byte, 1 = short, 2 = long) */
245 32, /* bitsize */
246 FALSE, /* pc_relative */
247 0, /* bitpos */
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 */
255
256 HOWTO (R_MSP430_ABS16, /* type */
257 0, /* rightshift */
258 1, /* size (0 = byte, 1 = short, 2 = long) */
259 16, /* bitsize */
260 FALSE, /* pc_relative */
261 0, /* bitpos */
262 complain_overflow_dont,/* complain_on_overflow */
263 bfd_elf_generic_reloc, /* special_function */
264 "R_MSP430_ABS16", /* name */
265 FALSE, /* partial_inplace */
266 0, /* src_mask */
267 0xffff, /* dst_mask */
268 FALSE), /* pcrel_offset */
269
270 HOWTO (R_MSP430_ABS8, /* type */
271 0, /* rightshift */
272 0, /* size (0 = byte, 1 = short, 2 = long) */
273 8, /* bitsize */
274 FALSE, /* pc_relative */
275 0, /* bitpos */
276 complain_overflow_bitfield,/* complain_on_overflow */
277 bfd_elf_generic_reloc, /* special_function */
278 "R_MSP430_ABS8", /* name */
279 FALSE, /* partial_inplace */
280 0xff, /* src_mask */
281 0xff, /* dst_mask */
282 FALSE), /* pcrel_offset */
283
284 HOWTO (R_MSP430_PCR16, /* type */
285 1, /* rightshift */
286 1, /* size (0 = byte, 1 = short, 2 = long) */
287 16, /* bitsize */
288 TRUE, /* pc_relative */
289 0, /* bitpos */
290 complain_overflow_dont,/* complain_on_overflow */
291 bfd_elf_generic_reloc, /* special_function */
292 "R_MSP430_PCR16", /* name */
293 FALSE, /* partial_inplace */
294 0, /* src_mask */
295 0xffff, /* dst_mask */
296 TRUE), /* pcrel_offset */
297
298 HOWTO (R_MSP430X_PCR20_EXT_SRC,/* type */
299 0, /* rightshift */
300 2, /* size (0 = byte, 1 = short, 2 = long) */
301 32, /* bitsize */
302 TRUE, /* pc_relative */
303 0, /* bitpos */
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 */
308 0, /* src_mask */
309 0xffff, /* dst_mask */
310 TRUE), /* pcrel_offset */
311
312 HOWTO (R_MSP430X_PCR20_EXT_DST,/* type */
313 0, /* rightshift */
314 2, /* size (0 = byte, 1 = short, 2 = long) */
315 32, /* bitsize */
316 TRUE, /* pc_relative */
317 0, /* bitpos */
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 */
322 0, /* src_mask */
323 0xffff, /* dst_mask */
324 TRUE), /* pcrel_offset */
325
326 HOWTO (R_MSP430X_PCR20_EXT_ODST,/* type */
327 0, /* rightshift */
328 2, /* size (0 = byte, 1 = short, 2 = long) */
329 32, /* bitsize */
330 TRUE, /* pc_relative */
331 0, /* bitpos */
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 */
336 0, /* src_mask */
337 0xffff, /* dst_mask */
338 TRUE), /* pcrel_offset */
339
340 HOWTO (R_MSP430X_ABS20_EXT_SRC,/* type */
341 0, /* rightshift */
342 2, /* size (0 = byte, 1 = short, 2 = long) */
343 32, /* bitsize */
344 TRUE, /* pc_relative */
345 0, /* bitpos */
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 */
350 0, /* src_mask */
351 0xffff, /* dst_mask */
352 TRUE), /* pcrel_offset */
353
354 HOWTO (R_MSP430X_ABS20_EXT_DST,/* type */
355 0, /* rightshift */
356 2, /* size (0 = byte, 1 = short, 2 = long) */
357 32, /* bitsize */
358 TRUE, /* pc_relative */
359 0, /* bitpos */
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 */
364 0, /* src_mask */
365 0xffff, /* dst_mask */
366 TRUE), /* pcrel_offset */
367
368 HOWTO (R_MSP430X_ABS20_EXT_ODST,/* type */
369 0, /* rightshift */
370 2, /* size (0 = byte, 1 = short, 2 = long) */
371 32, /* bitsize */
372 TRUE, /* pc_relative */
373 0, /* bitpos */
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 */
378 0, /* src_mask */
379 0xffff, /* dst_mask */
380 TRUE), /* pcrel_offset */
381
382 HOWTO (R_MSP430X_ABS20_ADR_SRC,/* type */
383 0, /* rightshift */
384 2, /* size (0 = byte, 1 = short, 2 = long) */
385 32, /* bitsize */
386 TRUE, /* pc_relative */
387 0, /* bitpos */
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 */
392 0, /* src_mask */
393 0xffff, /* dst_mask */
394 TRUE), /* pcrel_offset */
395
396 HOWTO (R_MSP430X_ABS20_ADR_DST,/* type */
397 0, /* rightshift */
398 2, /* size (0 = byte, 1 = short, 2 = long) */
399 32, /* bitsize */
400 TRUE, /* pc_relative */
401 0, /* bitpos */
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 */
406 0, /* src_mask */
407 0xffff, /* dst_mask */
408 TRUE), /* pcrel_offset */
409
410 HOWTO (R_MSP430X_PCR16, /* type */
411 0, /* rightshift */
412 2, /* size (0 = byte, 1 = short, 2 = long) */
413 32, /* bitsize */
414 TRUE, /* pc_relative */
415 0, /* bitpos */
416 complain_overflow_dont,/* complain_on_overflow */
417 bfd_elf_generic_reloc, /* special_function */
418 "R_MSP430X_PCR16", /* name */
419 FALSE, /* partial_inplace */
420 0, /* src_mask */
421 0xffff, /* dst_mask */
422 TRUE), /* pcrel_offset */
423
424 HOWTO (R_MSP430X_PCR20_CALL, /* type */
425 0, /* rightshift */
426 2, /* size (0 = byte, 1 = short, 2 = long) */
427 32, /* bitsize */
428 TRUE, /* pc_relative */
429 0, /* bitpos */
430 complain_overflow_dont,/* complain_on_overflow */
431 bfd_elf_generic_reloc, /* special_function */
432 "R_MSP430X_PCR20_CALL",/* name */
433 FALSE, /* partial_inplace */
434 0, /* src_mask */
435 0xffff, /* dst_mask */
436 TRUE), /* pcrel_offset */
437
438 HOWTO (R_MSP430X_ABS16, /* type */
439 0, /* rightshift */
440 2, /* size (0 = byte, 1 = short, 2 = long) */
441 32, /* bitsize */
442 TRUE, /* pc_relative */
443 0, /* bitpos */
444 complain_overflow_dont,/* complain_on_overflow */
445 bfd_elf_generic_reloc, /* special_function */
446 "R_MSP430X_ABS16", /* name */
447 FALSE, /* partial_inplace */
448 0, /* src_mask */
449 0xffff, /* dst_mask */
450 TRUE), /* pcrel_offset */
451
452 HOWTO (R_MSP430_ABS_HI16, /* type */
453 0, /* rightshift */
454 2, /* size (0 = byte, 1 = short, 2 = long) */
455 32, /* bitsize */
456 TRUE, /* pc_relative */
457 0, /* bitpos */
458 complain_overflow_dont,/* complain_on_overflow */
459 bfd_elf_generic_reloc, /* special_function */
460 "R_MSP430_ABS_HI16", /* name */
461 FALSE, /* partial_inplace */
462 0, /* src_mask */
463 0xffff, /* dst_mask */
464 TRUE), /* pcrel_offset */
465
466 HOWTO (R_MSP430_PREL31, /* type */
467 0, /* rightshift */
468 2, /* size (0 = byte, 1 = short, 2 = long) */
469 32, /* bitsize */
470 TRUE, /* pc_relative */
471 0, /* bitpos */
472 complain_overflow_dont,/* complain_on_overflow */
473 bfd_elf_generic_reloc, /* special_function */
474 "R_MSP430_PREL31", /* name */
475 FALSE, /* partial_inplace */
476 0, /* src_mask */
477 0xffff, /* dst_mask */
07d6d2b8 478 TRUE), /* pcrel_offset */
13761a11
NC
479
480 EMPTY_HOWTO (R_MSP430_EHTYPE),
1b786873 481
df301bfc 482 /* A 10 bit PC relative relocation. */
13761a11
NC
483 HOWTO (R_MSP430X_10_PCREL, /* type */
484 1, /* rightshift */
485 1, /* size (0 = byte, 1 = short, 2 = long) */
486 10, /* bitsize */
487 TRUE, /* pc_relative */
488 0, /* bitpos */
489 complain_overflow_bitfield,/* complain_on_overflow */
490 bfd_elf_generic_reloc, /* special_function */
491 "R_MSP430X_10_PCREL", /* name */
492 FALSE, /* partial_inplace */
df301bfc
NC
493 0x3ff, /* src_mask */
494 0x3ff, /* dst_mask */
07d6d2b8 495 TRUE), /* pcrel_offset */
13761a11 496
df301bfc 497 /* A 10 bit PC relative relocation for complicated polymorphs. */
13761a11
NC
498 HOWTO (R_MSP430X_2X_PCREL, /* type */
499 1, /* rightshift */
500 2, /* size (0 = byte, 1 = short, 2 = long) */
501 10, /* bitsize */
502 TRUE, /* pc_relative */
503 0, /* bitpos */
504 complain_overflow_bitfield,/* complain_on_overflow */
505 bfd_elf_generic_reloc, /* special_function */
506 "R_MSP430X_2X_PCREL", /* name */
507 FALSE, /* partial_inplace */
df301bfc
NC
508 0x3ff, /* src_mask */
509 0x3ff, /* dst_mask */
13761a11
NC
510 TRUE), /* pcrel_offset */
511
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 */
515 0, /* rightshift */
516 2, /* size (0 = byte, 1 = short, 2 = long) */
517 32, /* bitsize */
518 FALSE, /* pc_relative */
519 0, /* bitpos */
520 complain_overflow_dont,/* complain_on_overflow */
1ade7175 521 rl78_sym_diff_handler, /* special handler. */
13761a11
NC
522 "R_MSP430X_SYM_DIFF", /* name */
523 FALSE, /* partial_inplace */
524 0xffffffff, /* src_mask */
525 0xffffffff, /* dst_mask */
1b786873 526 FALSE) /* pcrel_offset */
2469cfa2
NC
527};
528
529/* Map BFD reloc types to MSP430 ELF reloc types. */
530
531struct msp430_reloc_map
532{
533 bfd_reloc_code_real_type bfd_reloc_val;
534 unsigned int elf_reloc_val;
535};
536
537static const struct msp430_reloc_map msp430_reloc_map[] =
13761a11 538{
07d6d2b8
AM
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},
13761a11 545 {BFD_RELOC_MSP430_16_PCREL_BYTE, R_MSP430_16_PCREL_BYTE},
07d6d2b8
AM
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}
13761a11
NC
551};
552
553static const struct msp430_reloc_map msp430x_reloc_map[] =
554{
07d6d2b8
AM
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},
13761a11
NC
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},
07d6d2b8 568 {BFD_RELOC_MSP430X_PCR16, R_MSP430X_PCR16},
13761a11 569 {BFD_RELOC_MSP430X_PCR20_CALL, R_MSP430X_PCR20_CALL},
07d6d2b8
AM
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}
13761a11
NC
577};
578
579static inline bfd_boolean
580uses_msp430x_relocs (bfd * abfd)
581{
6d00b590 582 extern const bfd_target msp430_elf32_ti_vec;
13761a11
NC
583
584 return bfd_get_mach (abfd) == bfd_mach_msp430x
6d00b590 585 || abfd->xvec == & msp430_elf32_ti_vec;
13761a11 586}
2469cfa2
NC
587
588static reloc_howto_type *
b18c562e
NC
589bfd_elf32_bfd_reloc_type_lookup (bfd * abfd ATTRIBUTE_UNUSED,
590 bfd_reloc_code_real_type code)
2469cfa2
NC
591{
592 unsigned int i;
593
13761a11
NC
594 if (uses_msp430x_relocs (abfd))
595 {
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;
599 }
600 else
601 {
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];
605 }
2469cfa2
NC
606
607 return NULL;
608}
609
157090f7
AM
610static reloc_howto_type *
611bfd_elf32_bfd_reloc_name_lookup (bfd *abfd ATTRIBUTE_UNUSED,
612 const char *r_name)
613{
614 unsigned int i;
615
13761a11
NC
616 if (uses_msp430x_relocs (abfd))
617 {
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;
622 }
623 else
624 {
625 for (i = 0;
626 i < (sizeof (elf_msp430_howto_table)
627 / sizeof (elf_msp430_howto_table[0]));
628 i++)
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];
632 }
157090f7
AM
633
634 return NULL;
635}
636
2469cfa2
NC
637/* Set the howto pointer for an MSP430 ELF reloc. */
638
f3185997 639static bfd_boolean
0aa13fee 640msp430_info_to_howto_rela (bfd * abfd,
b18c562e
NC
641 arelent * cache_ptr,
642 Elf_Internal_Rela * dst)
2469cfa2
NC
643{
644 unsigned int r_type;
645
646 r_type = ELF32_R_TYPE (dst->r_info);
13761a11
NC
647
648 if (uses_msp430x_relocs (abfd))
649 {
5860e3f8
NC
650 if (r_type >= (unsigned int) R_MSP430x_max)
651 {
695344c0 652 /* xgettext:c-format */
0aa13fee
AM
653 _bfd_error_handler (_("%pB: unsupported relocation type %#x"),
654 abfd, r_type);
f3185997
NC
655 bfd_set_error (bfd_error_bad_value);
656 return FALSE;
5860e3f8 657 }
13761a11 658 cache_ptr->howto = elf_msp430x_howto_table + r_type;
13761a11 659 }
f3185997 660 else if (r_type >= (unsigned int) R_MSP430_max)
5860e3f8 661 {
695344c0 662 /* xgettext:c-format */
0aa13fee
AM
663 _bfd_error_handler (_("%pB: unsupported relocation type %#x"),
664 abfd, r_type);
f3185997
NC
665 bfd_set_error (bfd_error_bad_value);
666 return FALSE;
5860e3f8 667 }
f3185997
NC
668 else
669 cache_ptr->howto = &elf_msp430_howto_table[r_type];
670
671 return TRUE;
2469cfa2
NC
672}
673
2469cfa2
NC
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. */
677
678static bfd_boolean
b18c562e
NC
679elf32_msp430_check_relocs (bfd * abfd, struct bfd_link_info * info,
680 asection * sec, const Elf_Internal_Rela * relocs)
2469cfa2
NC
681{
682 Elf_Internal_Shdr *symtab_hdr;
5582a088 683 struct elf_link_hash_entry **sym_hashes;
2469cfa2
NC
684 const Elf_Internal_Rela *rel;
685 const Elf_Internal_Rela *rel_end;
686
0e1862bb 687 if (bfd_link_relocatable (info))
2469cfa2
NC
688 return TRUE;
689
690 symtab_hdr = &elf_tdata (abfd)->symtab_hdr;
691 sym_hashes = elf_sym_hashes (abfd);
2469cfa2
NC
692
693 rel_end = relocs + sec->reloc_count;
694 for (rel = relocs; rel < rel_end; rel++)
695 {
696 struct elf_link_hash_entry *h;
697 unsigned long r_symndx;
698
699 r_symndx = ELF32_R_SYM (rel->r_info);
700 if (r_symndx < symtab_hdr->sh_info)
701 h = NULL;
702 else
973a3492
L
703 {
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;
708 }
2469cfa2
NC
709 }
710
711 return TRUE;
712}
713
714/* Perform a single relocation. By default we use the standard BFD
715 routines, but a few relocs, we have to do them ourselves. */
716
717static bfd_reloc_status_type
07d6d2b8
AM
718msp430_final_link_relocate (reloc_howto_type * howto,
719 bfd * input_bfd,
720 asection * input_section,
721 bfd_byte * contents,
722 Elf_Internal_Rela * rel,
723 bfd_vma relocation,
13761a11 724 struct bfd_link_info * info)
2469cfa2 725{
13761a11
NC
726 static asection * sym_diff_section;
727 static bfd_vma sym_diff_value;
728
729 struct bfd_elf_section_data * esd = elf_section_data (input_section);
2469cfa2
NC
730 bfd_reloc_status_type r = bfd_reloc_ok;
731 bfd_vma x;
732 bfd_signed_vma srel;
13761a11
NC
733 bfd_boolean is_rel_reloc = FALSE;
734
735 if (uses_msp430x_relocs (input_bfd))
736 {
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);
745 }
2469cfa2 746
d60f5448
JL
747 if (debug_relocs)
748 printf ("writing relocation (%p) at 0x%lx type: %d\n", rel,
749 input_section->output_section->vma + input_section->output_offset
750 + rel->r_offset, howto->type);
13761a11 751 if (sym_diff_section != NULL)
2469cfa2 752 {
13761a11 753 BFD_ASSERT (sym_diff_section == input_section);
1b786873 754
13761a11
NC
755 if (uses_msp430x_relocs (input_bfd))
756 switch (howto->type)
757 {
758 case R_MSP430_ABS32:
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
765 being parsed. */
766 if (relocation == sym_diff_value
767 && strcmp (input_section->name, ".debug_loc") == 0)
768 ++ relocation;
769 /* Fall through. */
770 case R_MSP430_ABS16:
771 case R_MSP430X_ABS16:
772 case R_MSP430_ABS8:
773 BFD_ASSERT (! is_rel_reloc);
774 relocation -= sym_diff_value;
775 break;
776
777 default:
778 return bfd_reloc_dangerous;
779 }
780 else
781 switch (howto->type)
782 {
783 case R_MSP430_32:
784 case R_MSP430_16:
785 case R_MSP430_16_BYTE:
786 case R_MSP430_8:
787 relocation -= sym_diff_value;
788 break;
789
790 default:
791 return bfd_reloc_dangerous;
792 }
1b786873 793
13761a11
NC
794 sym_diff_section = NULL;
795 }
796
797 if (uses_msp430x_relocs (input_bfd))
798 switch (howto->type)
799 {
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;
807 return bfd_reloc_ok;
808
809 case R_MSP430_ABS16:
810 contents += rel->r_offset;
811 srel = (bfd_signed_vma) relocation;
812 if (is_rel_reloc)
813 srel += bfd_get_16 (input_bfd, contents);
814 else
815 srel += rel->r_addend;
816 bfd_put_16 (input_bfd, srel & 0xffff, contents);
817 break;
818
819 case R_MSP430X_10_PCREL:
820 contents += rel->r_offset;
821 srel = (bfd_signed_vma) relocation;
822 if (is_rel_reloc)
823 srel += bfd_get_16 (input_bfd, contents) & 0x3ff;
824 else
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);
830 if (srel & 1)
831 return bfd_reloc_outofrange;
832
833 /* MSP430 addresses commands as words. */
834 srel >>= 1;
835
836 /* Check for an overflow. */
837 if (srel < -512 || srel > 511)
838 {
839 if (info->disable_target_specific_optimizations < 0)
840 {
841 static bfd_boolean warned = FALSE;
842 if (! warned)
843 {
844 info->callbacks->warning
845 (info,
38f14ab8 846 _("try enabling relaxation to avoid relocation truncations"),
13761a11
NC
847 NULL, input_bfd, input_section, relocation);
848 warned = TRUE;
849 }
850 }
851 return bfd_reloc_overflow;
852 }
853
854 x = bfd_get_16 (input_bfd, contents);
855 x = (x & 0xfc00) | (srel & 0x3ff);
856 bfd_put_16 (input_bfd, x, contents);
857 break;
858
859 case R_MSP430X_PCR20_EXT_ODST:
3f307074 860 /* [0,4]+[48,16] = ---F ---- ---- FFFF */
13761a11
NC
861 contents += rel->r_offset;
862 srel = (bfd_signed_vma) relocation;
863 if (is_rel_reloc)
864 {
865 bfd_vma addend;
866 addend = (bfd_get_16 (input_bfd, contents) & 0xf) << 16;
3f307074 867 addend |= bfd_get_16 (input_bfd, contents + 6);
13761a11 868 srel += addend;
1b786873 869
13761a11
NC
870 }
871 else
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);
880 break;
881
882 case R_MSP430X_ABS20_EXT_SRC:
3f307074 883 /* [7,4]+[32,16] = -78- ---- FFFF */
13761a11
NC
884 contents += rel->r_offset;
885 srel = (bfd_signed_vma) relocation;
886 if (is_rel_reloc)
887 {
888 bfd_vma addend;
889 addend = (bfd_get_16 (input_bfd, contents) & 0x0780) << 9;
3f307074 890 addend |= bfd_get_16 (input_bfd, contents + 4);
13761a11
NC
891 srel += addend;
892 }
893 else
894 srel += rel->r_addend;
895 bfd_put_16 (input_bfd, (srel & 0xffff), contents + 4);
896 srel >>= 16;
897 x = bfd_get_16 (input_bfd, contents);
898 x = (x & 0xf87f) | ((srel << 7) & 0x0780);
899 bfd_put_16 (input_bfd, x, contents);
900 break;
901
902 case R_MSP430_16_PCREL:
903 contents += rel->r_offset;
904 srel = (bfd_signed_vma) relocation;
905 if (is_rel_reloc)
906 srel += bfd_get_16 (input_bfd, contents);
907 else
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);
913 if (srel & 1)
914 return bfd_reloc_outofrange;
915 bfd_put_16 (input_bfd, srel & 0xffff, contents);
916 break;
917
918 case R_MSP430X_PCR20_EXT_DST:
3f307074 919 /* [0,4]+[32,16] = ---F ---- FFFF */
13761a11
NC
920 contents += rel->r_offset;
921 srel = (bfd_signed_vma) relocation;
922 if (is_rel_reloc)
923 {
924 bfd_vma addend;
925 addend = (bfd_get_16 (input_bfd, contents) & 0xf) << 16;
3f307074 926 addend |= bfd_get_16 (input_bfd, contents + 4);
13761a11
NC
927 srel += addend;
928 }
929 else
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);
935 srel >>= 16;
936 x = bfd_get_16 (input_bfd, contents);
937 x = (x & 0xfff0) | (srel & 0xf);
938 bfd_put_16 (input_bfd, x, contents);
939 break;
940
941 case R_MSP430X_PCR20_EXT_SRC:
3f307074 942 /* [7,4]+[32,16] = -78- ---- FFFF */
13761a11
NC
943 contents += rel->r_offset;
944 srel = (bfd_signed_vma) relocation;
945 if (is_rel_reloc)
946 {
947 bfd_vma addend;
948 addend = ((bfd_get_16 (input_bfd, contents) & 0x0780) << 9);
3f307074 949 addend |= bfd_get_16 (input_bfd, contents + 4);
13761a11
NC
950 srel += addend;;
951 }
952 else
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);
959 srel >>= 16;
960 x = bfd_get_16 (input_bfd, contents);
961 x = (x & 0xf87f) | ((srel << 7) & 0x0780);
962 bfd_put_16 (input_bfd, x, contents);
963 break;
964
965 case R_MSP430_ABS8:
966 contents += rel->r_offset;
967 srel = (bfd_signed_vma) relocation;
968 if (is_rel_reloc)
969 srel += bfd_get_8 (input_bfd, contents);
970 else
971 srel += rel->r_addend;
972 bfd_put_8 (input_bfd, srel & 0xff, contents);
973 break;
974
975 case R_MSP430X_ABS20_EXT_DST:
3f307074 976 /* [0,4]+[32,16] = ---F ---- FFFF */
13761a11
NC
977 contents += rel->r_offset;
978 srel = (bfd_signed_vma) relocation;
979 if (is_rel_reloc)
3f307074
DD
980 {
981 bfd_vma addend;
982 addend = (bfd_get_16 (input_bfd, contents) & 0xf) << 16;
983 addend |= bfd_get_16 (input_bfd, contents + 4);
984 srel += addend;
985 }
13761a11
NC
986 else
987 srel += rel->r_addend;
988 bfd_put_16 (input_bfd, (srel & 0xffff), contents + 4);
989 srel >>= 16;
990 x = bfd_get_16 (input_bfd, contents);
991 x = (x & 0xfff0) | (srel & 0xf);
992 bfd_put_16 (input_bfd, x, contents);
993 break;
994
995 case R_MSP430X_ABS20_EXT_ODST:
3f307074 996 /* [0,4]+[48,16] = ---F ---- ---- FFFF */
13761a11
NC
997 contents += rel->r_offset;
998 srel = (bfd_signed_vma) relocation;
999 if (is_rel_reloc)
1000 {
1001 bfd_vma addend;
1002 addend = (bfd_get_16 (input_bfd, contents) & 0xf) << 16;
3f307074 1003 addend |= bfd_get_16 (input_bfd, contents + 6);
13761a11
NC
1004 srel += addend;
1005 }
1006 else
1007 srel += rel->r_addend;
1008 bfd_put_16 (input_bfd, (srel & 0xffff), contents + 6);
1009 srel >>= 16;
1010 x = bfd_get_16 (input_bfd, contents);
1011 x = (x & 0xfff0) | (srel & 0xf);
1012 bfd_put_16 (input_bfd, x, contents);
1013 break;
1014
1015 case R_MSP430X_ABS20_ADR_SRC:
3f307074 1016 /* [8,4]+[16,16] = -F-- FFFF */
13761a11
NC
1017 contents += rel->r_offset;
1018 srel = (bfd_signed_vma) relocation;
1019 if (is_rel_reloc)
1020 {
1021 bfd_vma addend;
1022
1023 addend = ((bfd_get_16 (input_bfd, contents) & 0xf00) << 8);
3f307074 1024 addend |= bfd_get_16 (input_bfd, contents + 2);
13761a11
NC
1025 srel += addend;
1026 }
1027 else
1028 srel += rel->r_addend;
1029 bfd_put_16 (input_bfd, (srel & 0xffff), contents + 2);
1030 srel >>= 16;
1031 x = bfd_get_16 (input_bfd, contents);
1032 x = (x & 0xf0ff) | ((srel << 8) & 0x0f00);
1033 bfd_put_16 (input_bfd, x, contents);
1034 break;
1035
1036 case R_MSP430X_ABS20_ADR_DST:
3f307074 1037 /* [0,4]+[16,16] = ---F FFFF */
13761a11
NC
1038 contents += rel->r_offset;
1039 srel = (bfd_signed_vma) relocation;
1040 if (is_rel_reloc)
1041 {
1042 bfd_vma addend;
1043 addend = ((bfd_get_16 (input_bfd, contents) & 0xf) << 16);
3f307074 1044 addend |= bfd_get_16 (input_bfd, contents + 2);
13761a11
NC
1045 srel += addend;
1046 }
1047 else
1048 srel += rel->r_addend;
1049 bfd_put_16 (input_bfd, (srel & 0xffff), contents + 2);
1050 srel >>= 16;
1051 x = bfd_get_16 (input_bfd, contents);
1052 x = (x & 0xfff0) | (srel & 0xf);
1053 bfd_put_16 (input_bfd, x, contents);
1054 break;
1055
1056 case R_MSP430X_ABS16:
1057 contents += rel->r_offset;
1058 srel = (bfd_signed_vma) relocation;
1059 if (is_rel_reloc)
1060 srel += bfd_get_16 (input_bfd, contents);
1061 else
1062 srel += rel->r_addend;
1063 x = srel;
1064 if (x > 0xffff)
1b786873 1065 return bfd_reloc_overflow;
13761a11
NC
1066 bfd_put_16 (input_bfd, srel & 0xffff, contents);
1067 break;
1068
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);
1076 break;
1b786873 1077
13761a11 1078 case R_MSP430X_PCR20_CALL:
3f307074 1079 /* [0,4]+[16,16] = ---F FFFF*/
13761a11
NC
1080 contents += rel->r_offset;
1081 srel = (bfd_signed_vma) relocation;
1082 if (is_rel_reloc)
1083 {
1084 bfd_vma addend;
1085 addend = (bfd_get_16 (input_bfd, contents) & 0xf) << 16;
3f307074 1086 addend |= bfd_get_16 (input_bfd, contents + 2);
13761a11
NC
1087 srel += addend;
1088 }
1089 else
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);
1095 srel >>= 16;
1096 x = bfd_get_16 (input_bfd, contents);
1097 x = (x & 0xfff0) | (srel & 0xf);
1098 bfd_put_16 (input_bfd, x, contents);
1099 break;
1b786873 1100
13761a11
NC
1101 case R_MSP430X_PCR16:
1102 contents += rel->r_offset;
1103 srel = (bfd_signed_vma) relocation;
1104 if (is_rel_reloc)
1105 srel += bfd_get_16 (input_bfd, contents);
1106 else
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);
1112 break;
1b786873 1113
13761a11
NC
1114 case R_MSP430_PREL31:
1115 contents += rel->r_offset;
1116 srel = (bfd_signed_vma) relocation;
1117 if (is_rel_reloc)
1118 srel += (bfd_get_32 (input_bfd, contents) & 0x7fffffff);
1119 else
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);
1125 break;
1b786873 1126
13761a11
NC
1127 default:
1128 r = _bfd_final_link_relocate (howto, input_bfd, input_section,
1129 contents, rel->r_offset,
1130 relocation, rel->r_addend);
1131 }
1132 else
1133 switch (howto->type)
1134 {
2469cfa2
NC
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);
1143
1144 if (srel & 1)
1145 return bfd_reloc_outofrange;
1146
1147 /* MSP430 addresses commands as words. */
1148 srel >>= 1;
1149
1150 /* Check for an overflow. */
1151 if (srel < -512 || srel > 511)
13761a11
NC
1152 {
1153 if (info->disable_target_specific_optimizations < 0)
1154 {
1155 static bfd_boolean warned = FALSE;
1156 if (! warned)
1157 {
1158 info->callbacks->warning
1159 (info,
38f14ab8 1160 _("try enabling relaxation to avoid relocation truncations"),
13761a11
NC
1161 NULL, input_bfd, input_section, relocation);
1162 warned = TRUE;
1163 }
1164 }
1165 return bfd_reloc_overflow;
1166 }
1b786873 1167
2469cfa2
NC
1168 x = bfd_get_16 (input_bfd, contents);
1169 x = (x & 0xfc00) | (srel & 0x3ff);
1170 bfd_put_16 (input_bfd, x, contents);
1171 break;
1172
b18c562e
NC
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);
1181
1182 if (srel & 1)
1183 return bfd_reloc_outofrange;
1184
1185 /* MSP430 addresses commands as words. */
1186 srel >>= 1;
1187
1188 /* Check for an overflow. */
1189 if (srel < -512 || srel > 511)
1190 return bfd_reloc_overflow;
1191
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);
1197 srel += 1;
1198 x = (x & 0xfc00) | (srel & 0x3ff);
1199 bfd_put_16 (input_bfd, x, contents - 2);
1200 break;
1201
b18c562e 1202 case R_MSP430_RL_PCREL:
77bf820f 1203 case R_MSP430_16_PCREL:
2469cfa2
NC
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);
1211
1212 if (srel & 1)
1213 return bfd_reloc_outofrange;
1214
1215 bfd_put_16 (input_bfd, srel & 0xffff, contents);
1216 break;
1217
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);
1226
1227 bfd_put_16 (input_bfd, srel & 0xffff, contents);
1228 break;
1229
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);
1235 break;
1236
1237 case R_MSP430_16:
1238 contents += rel->r_offset;
1239 srel = (bfd_signed_vma) relocation;
1240 srel += rel->r_addend;
1241
1242 if (srel & 1)
1243 return bfd_reloc_notsupported;
1244
1245 bfd_put_16 (input_bfd, srel & 0xffff, contents);
1246 break;
1247
13761a11
NC
1248 case R_MSP430_8:
1249 contents += rel->r_offset;
1250 srel = (bfd_signed_vma) relocation;
1251 srel += rel->r_addend;
1252
1253 bfd_put_8 (input_bfd, srel & 0xff, contents);
1254 break;
1b786873 1255
13761a11
NC
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;
1263
1264 default:
1265 r = _bfd_final_link_relocate (howto, input_bfd, input_section,
1266 contents, rel->r_offset,
1267 relocation, rel->r_addend);
1268 }
2469cfa2
NC
1269
1270 return r;
1271}
1272
1273/* Relocate an MSP430 ELF section. */
1274
1275static bfd_boolean
b18c562e
NC
1276elf32_msp430_relocate_section (bfd * output_bfd ATTRIBUTE_UNUSED,
1277 struct bfd_link_info * info,
1278 bfd * input_bfd,
1279 asection * input_section,
1280 bfd_byte * contents,
1281 Elf_Internal_Rela * relocs,
1282 Elf_Internal_Sym * local_syms,
1283 asection ** local_sections)
2469cfa2
NC
1284{
1285 Elf_Internal_Shdr *symtab_hdr;
1286 struct elf_link_hash_entry **sym_hashes;
1287 Elf_Internal_Rela *rel;
1288 Elf_Internal_Rela *relend;
1289
1290 symtab_hdr = &elf_tdata (input_bfd)->symtab_hdr;
1291 sym_hashes = elf_sym_hashes (input_bfd);
1292 relend = relocs + input_section->reloc_count;
1293
1294 for (rel = relocs; rel < relend; rel++)
1295 {
1296 reloc_howto_type *howto;
1297 unsigned long r_symndx;
1298 Elf_Internal_Sym *sym;
1299 asection *sec;
1300 struct elf_link_hash_entry *h;
1301 bfd_vma relocation;
1302 bfd_reloc_status_type r;
1303 const char *name = NULL;
1304 int r_type;
1305
2469cfa2
NC
1306 r_type = ELF32_R_TYPE (rel->r_info);
1307 r_symndx = ELF32_R_SYM (rel->r_info);
13761a11
NC
1308
1309 if (uses_msp430x_relocs (input_bfd))
1310 howto = elf_msp430x_howto_table + r_type;
1311 else
1312 howto = elf_msp430_howto_table + r_type;
1313
2469cfa2
NC
1314 h = NULL;
1315 sym = NULL;
1316 sec = NULL;
1317
1318 if (r_symndx < symtab_hdr->sh_info)
1319 {
1320 sym = local_syms + r_symndx;
1321 sec = local_sections[r_symndx];
8517fae7 1322 relocation = _bfd_elf_rela_local_sym (output_bfd, sym, &sec, rel);
2469cfa2
NC
1323
1324 name = bfd_elf_string_from_elf_section
1325 (input_bfd, symtab_hdr->sh_link, sym->st_name);
fd361982 1326 name = name == NULL || *name == 0 ? bfd_section_name (sec) : name;
2469cfa2
NC
1327 }
1328 else
1329 {
62d887d4 1330 bfd_boolean unresolved_reloc, warned, ignored;
2469cfa2 1331
b2a8e766
AM
1332 RELOC_FOR_GLOBAL_SYMBOL (info, input_bfd, input_section, rel,
1333 r_symndx, symtab_hdr, sym_hashes,
1334 h, sec, relocation,
62d887d4 1335 unresolved_reloc, warned, ignored);
13761a11 1336 name = h->root.root.string;
2469cfa2
NC
1337 }
1338
dbaa2011 1339 if (sec != NULL && discarded_section (sec))
e4067dbb 1340 RELOC_AGAINST_DISCARDED_SECTION (info, input_bfd, input_section,
545fd46b 1341 rel, 1, relend, howto, 0, contents);
ab96bf03 1342
0e1862bb 1343 if (bfd_link_relocatable (info))
ab96bf03
AM
1344 continue;
1345
2469cfa2 1346 r = msp430_final_link_relocate (howto, input_bfd, input_section,
13761a11 1347 contents, rel, relocation, info);
2469cfa2
NC
1348
1349 if (r != bfd_reloc_ok)
1350 {
1351 const char *msg = (const char *) NULL;
1352
1353 switch (r)
1354 {
1355 case bfd_reloc_overflow:
1a72702b 1356 (*info->callbacks->reloc_overflow)
13761a11 1357 (info, (h ? &h->root : NULL), name, howto->name,
1a72702b 1358 (bfd_vma) 0, input_bfd, input_section, rel->r_offset);
2469cfa2
NC
1359 break;
1360
1361 case bfd_reloc_undefined:
1a72702b
AM
1362 (*info->callbacks->undefined_symbol)
1363 (info, name, input_bfd, input_section, rel->r_offset, TRUE);
2469cfa2
NC
1364 break;
1365
1366 case bfd_reloc_outofrange:
13761a11 1367 msg = _("internal error: branch/jump to an odd address detected");
2469cfa2
NC
1368 break;
1369
1370 case bfd_reloc_notsupported:
1371 msg = _("internal error: unsupported relocation error");
1372 break;
1373
1374 case bfd_reloc_dangerous:
1375 msg = _("internal error: dangerous relocation");
1376 break;
1377
1378 default:
1379 msg = _("internal error: unknown error");
1380 break;
1381 }
1382
1383 if (msg)
1a72702b
AM
1384 (*info->callbacks->warning) (info, msg, name, input_bfd,
1385 input_section, rel->r_offset);
2469cfa2
NC
1386 }
1387
1388 }
1389
1390 return TRUE;
1391}
1392
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
1395 number. */
1396
cc364be6
AM
1397static bfd_boolean
1398bfd_elf_msp430_final_write_processing (bfd *abfd)
2469cfa2
NC
1399{
1400 unsigned long val;
1401
1402 switch (bfd_get_mach (abfd))
1403 {
1404 default:
13761a11
NC
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;
2469cfa2
NC
1428 }
1429
1430 elf_elfheader (abfd)->e_machine = EM_MSP430;
1431 elf_elfheader (abfd)->e_flags &= ~EF_MSP430_MACH;
1432 elf_elfheader (abfd)->e_flags |= val;
cc364be6 1433 return _bfd_elf_final_write_processing (abfd);
2469cfa2
NC
1434}
1435
1436/* Set the right machine number. */
1437
1438static bfd_boolean
b18c562e 1439elf32_msp430_object_p (bfd * abfd)
2469cfa2
NC
1440{
1441 int e_set = bfd_mach_msp14;
1442
1443 if (elf_elfheader (abfd)->e_machine == EM_MSP430
1444 || elf_elfheader (abfd)->e_machine == EM_MSP430_OLD)
1445 {
1446 int e_mach = elf_elfheader (abfd)->e_flags & EF_MSP430_MACH;
1447
1448 switch (e_mach)
1449 {
1450 default:
13761a11
NC
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;
2469cfa2
NC
1474 }
1475 }
1b786873 1476
2469cfa2
NC
1477 return bfd_default_set_arch_mach (abfd, bfd_arch_msp430, e_set);
1478}
1479
b18c562e
NC
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
1483 from file to file.
77bf820f 1484 - Sibling calls. This will affect only 'jump label' polymorph. Without
b18c562e
NC
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.
13761a11
NC
1487 - To convert out of range conditional jump instructions (found inside
1488 a function) into inverted jumps over an unconditional branch instruction.
b18c562e
NC
1489 Anyway, if a relaxation required, user should pass -relax option to the
1490 linker.
1491
1492 There are quite a few relaxing opportunities available on the msp430:
1493
1494 ================================================================
1495
1496 1. 3 words -> 1 word
1497
07d6d2b8
AM
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
b18c562e
NC
1504
1505 2. 4 words -> 1 word
1506
07d6d2b8 1507 ltn < jn jn +2; jmp +4; br lab
b18c562e
NC
1508
1509 3. 4 words -> 2 words
1510
07d6d2b8
AM
1511 gt > jeq +2; jge label jeq +6; jl +4; br label
1512 gtu > jeq +2; jhs label jeq +6; jlo +4; br label
b18c562e
NC
1513
1514 4. 4 words -> 2 words and 2 labels
1515
07d6d2b8
AM
1516 leu <= jeq label; jlo label jeq +2; jhs +4; br label
1517 le <= jeq label; jl label jeq +2; jge +4; br label
b18c562e
NC
1518 =================================================================
1519
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
1527
1528 second case:
1529 ltn: 0x3001,0x3c02,0x4010,0x0000 -> 0x3000
1530
1531 third case:
1532 gt: 0x2403,0x3802,0x4010,0x0000 -> 0x2401,0x3400
1533 gtu: 0x2403,0x2802,0x4010,0x0000 -> 0x2401,0x2c00
1534
1535 fourth case:
1536 leu: 0x2401,0x2c02,0x4010,0x0000 -> 0x2400,0x2800
1537 le: 0x2401,0x3402,0x4010,0x0000 -> 0x2400,0x3800
1538
1539 Unspecified case :)
1540 jump: 0x4010,0x0000 -> 0x3c00. */
1541
1542#define NUMB_RELAX_CODES 12
1543static struct rcodes_s
1544{
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
1549 labels at both. */
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. */
1554} rcode[] =
07d6d2b8 1555{/* lab,cdx,bs,off,ncl */
b18c562e
NC
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 */
07d6d2b8 1568 { 0, 0, 0, 0, 0, 0, 0, 0, 0}
b18c562e
NC
1569};
1570
1571/* Return TRUE if a symbol exists at the given address. */
1572
1573static bfd_boolean
1574msp430_elf_symbol_address_p (bfd * abfd,
1575 asection * sec,
1576 Elf_Internal_Sym * isym,
1577 bfd_vma addr)
1578{
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;
1585
1586 sec_shndx = _bfd_elf_section_from_bfd_section (abfd, sec);
1587
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)
1592 return TRUE;
1593
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++)
1599 {
1600 struct elf_link_hash_entry *sym_hash = *sym_hashes;
1601
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)
1606 return TRUE;
1607 }
1608
1609 return FALSE;
1610}
1611
13761a11
NC
1612/* Adjust all local symbols defined as '.section + 0xXXXX' (.section has
1613 sec_shndx) referenced from current and other sections. */
1614
046aeb74 1615static bfd_boolean
13761a11
NC
1616msp430_elf_relax_adjust_locals (bfd * abfd, asection * sec, bfd_vma addr,
1617 int count, unsigned int sec_shndx,
1618 bfd_vma toaddr)
046aeb74
DD
1619{
1620 Elf_Internal_Shdr *symtab_hdr;
1621 Elf_Internal_Rela *irel;
1622 Elf_Internal_Rela *irelend;
1623 Elf_Internal_Sym *isym;
1624
1625 irel = elf_section_data (sec)->relocs;
13761a11
NC
1626 if (irel == NULL)
1627 return TRUE;
1628
046aeb74
DD
1629 irelend = irel + sec->reloc_count;
1630 symtab_hdr = & elf_tdata (abfd)->symtab_hdr;
1631 isym = (Elf_Internal_Sym *) symtab_hdr->contents;
bceec4b9 1632
13761a11 1633 for (;irel < irelend; irel++)
046aeb74 1634 {
bceec4b9 1635 unsigned int sidx = ELF32_R_SYM(irel->r_info);
046aeb74 1636 Elf_Internal_Sym *lsym = isym + sidx;
bceec4b9 1637
1ade7175 1638 /* Adjust symbols referenced by .sec+0xXX. */
bceec4b9
DD
1639 if (irel->r_addend > addr && irel->r_addend < toaddr
1640 && sidx < symtab_hdr->sh_info
046aeb74
DD
1641 && lsym->st_shndx == sec_shndx)
1642 irel->r_addend -= count;
1643 }
1b786873 1644
046aeb74
DD
1645 return TRUE;
1646}
1647
b18c562e
NC
1648/* Delete some bytes from a section while relaxing. */
1649
1650static bfd_boolean
1651msp430_elf_relax_delete_bytes (bfd * abfd, asection * sec, bfd_vma addr,
1652 int count)
1653{
1654 Elf_Internal_Shdr *symtab_hdr;
1655 unsigned int sec_shndx;
1656 bfd_byte *contents;
1657 Elf_Internal_Rela *irel;
1658 Elf_Internal_Rela *irelend;
b18c562e
NC
1659 bfd_vma toaddr;
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;
046aeb74 1665 asection *p;
b18c562e
NC
1666
1667 sec_shndx = _bfd_elf_section_from_bfd_section (abfd, sec);
1668
1669 contents = elf_section_data (sec)->this_hdr.contents;
1670
b18c562e 1671 toaddr = sec->size;
d60f5448
JL
1672 if (debug_relocs)
1673 printf (" deleting %d bytes between 0x%lx to 0x%lx\n",
1674 count, addr, toaddr);
b18c562e
NC
1675
1676 irel = elf_section_data (sec)->relocs;
1677 irelend = irel + sec->reloc_count;
1678
1679 /* Actually delete the bytes. */
1680 memmove (contents + addr, contents + addr + count,
1681 (size_t) (toaddr - addr - count));
1682 sec->size -= count;
1683
1684 /* Adjust all the relocs. */
fa9ee72b
DD
1685 symtab_hdr = & elf_tdata (abfd)->symtab_hdr;
1686 isym = (Elf_Internal_Sym *) symtab_hdr->contents;
13761a11 1687 for (; irel < irelend; irel++)
fa9ee72b 1688 {
fa9ee72b
DD
1689 /* Get the new reloc address. */
1690 if ((irel->r_offset > addr && irel->r_offset < toaddr))
1691 irel->r_offset -= count;
fa9ee72b 1692 }
b18c562e 1693
046aeb74 1694 for (p = abfd->sections; p != NULL; p = p->next)
13761a11 1695 msp430_elf_relax_adjust_locals (abfd,p,addr,count,sec_shndx,toaddr);
1b786873 1696
b18c562e
NC
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++)
0f8f0c57
NC
1701 {
1702 const char * name;
1703
1704 name = bfd_elf_string_from_elf_section
1705 (abfd, symtab_hdr->sh_link, isym->st_name);
fd361982 1706 name = name == NULL || *name == 0 ? bfd_section_name (sec) : name;
0f8f0c57
NC
1707
1708 if (isym->st_shndx != sec_shndx)
1709 continue;
1b786873 1710
0f8f0c57
NC
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
1718 && name != NULL
1719 && (CONST_STRNEQ (name, ".Letext")
1720 || CONST_STRNEQ (name, ".LFE")))))
1721 {
d60f5448
JL
1722 if (debug_relocs)
1723 printf (" adjusting value of local symbol %s from 0x%lx ",
1724 name, isym->st_value);
0f8f0c57
NC
1725 if (isym->st_value < addr + count)
1726 isym->st_value = addr;
1727 else
1728 isym->st_value -= count;
d60f5448
JL
1729 if (debug_relocs)
1730 printf ("to 0x%lx\n", isym->st_value);
0f8f0c57
NC
1731 }
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;
1737 }
b18c562e
NC
1738
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++)
1745 {
1746 struct elf_link_hash_entry *sym_hash = *sym_hashes;
1747
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)
0f8f0c57
NC
1753 {
1754 if (sym_hash->root.u.def.value < addr + count)
1755 sym_hash->root.u.def.value = addr;
1756 else
1757 sym_hash->root.u.def.value -= count;
1758 }
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;
b18c562e
NC
1766 }
1767
1768 return TRUE;
1769}
1770
8d6cb116 1771/* Insert one or two words into a section whilst relaxing. */
13761a11
NC
1772
1773static bfd_byte *
8d6cb116
JL
1774msp430_elf_relax_add_words (bfd * abfd, asection * sec, bfd_vma addr,
1775 int num_words, int word1, int word2)
13761a11
NC
1776{
1777 Elf_Internal_Shdr *symtab_hdr;
1778 unsigned int sec_shndx;
1779 bfd_byte *contents;
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;
1787 bfd_vma sec_end;
1788 asection *p;
d60f5448 1789 if (debug_relocs)
8d6cb116 1790 printf (" adding %d words at 0x%lx\n", num_words,
d60f5448 1791 sec->output_section->vma + sec->output_offset + addr);
13761a11
NC
1792
1793 contents = elf_section_data (sec)->this_hdr.contents;
1794 sec_end = sec->size;
8d6cb116 1795 int num_bytes = num_words * 2;
13761a11
NC
1796
1797 /* Make space for the new words. */
8d6cb116
JL
1798 contents = bfd_realloc (contents, sec_end + num_bytes);
1799 memmove (contents + addr + num_bytes, contents + addr, sec_end - addr);
13761a11
NC
1800
1801 /* Insert the new words. */
1802 bfd_put_16 (abfd, word1, contents + addr);
8d6cb116
JL
1803 if (num_words == 2)
1804 bfd_put_16 (abfd, word2, contents + addr + 2);
13761a11
NC
1805
1806 /* Update the section information. */
8d6cb116 1807 sec->size += num_bytes;
1b786873 1808 elf_section_data (sec)->this_hdr.contents = contents;
13761a11
NC
1809
1810 /* Adjust all the relocs. */
1811 irel = elf_section_data (sec)->relocs;
1812 irelend = irel + sec->reloc_count;
1813
1814 for (; irel < irelend; irel++)
1815 if ((irel->r_offset >= addr && irel->r_offset < sec_end))
8d6cb116 1816 irel->r_offset += num_bytes;
13761a11
NC
1817
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)
8d6cb116 1821 msp430_elf_relax_adjust_locals (abfd, p, addr, -num_bytes,
13761a11
NC
1822 sec_shndx, sec_end);
1823
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)
d60f5448
JL
1830 {
1831 if (debug_relocs)
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),
8d6cb116
JL
1835 isym->st_value, isym->st_value + num_bytes);
1836 isym->st_value += num_bytes;
d60f5448 1837 }
13761a11
NC
1838
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++)
1845 {
1846 struct elf_link_hash_entry *sym_hash = *sym_hashes;
1847
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)
8d6cb116 1853 sym_hash->root.u.def.value += num_bytes;
13761a11
NC
1854 }
1855
1856 return contents;
1857}
1b786873 1858
b18c562e
NC
1859static bfd_boolean
1860msp430_elf_relax_section (bfd * abfd, asection * sec,
1861 struct bfd_link_info * link_info,
1862 bfd_boolean * again)
1863{
1864 Elf_Internal_Shdr * symtab_hdr;
1865 Elf_Internal_Rela * internal_relocs;
1866 Elf_Internal_Rela * irel;
1867 Elf_Internal_Rela * irelend;
07d6d2b8 1868 bfd_byte * contents = NULL;
b18c562e
NC
1869 Elf_Internal_Sym * isymbuf = NULL;
1870
1871 /* Assume nothing changes. */
1872 *again = FALSE;
1873
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
1876 code section. */
0e1862bb 1877 if (bfd_link_relocatable (link_info)
13761a11
NC
1878 || (sec->flags & SEC_RELOC) == 0
1879 || sec->reloc_count == 0 || (sec->flags & SEC_CODE) == 0)
b18c562e
NC
1880 return TRUE;
1881
d60f5448
JL
1882 if (debug_relocs)
1883 printf ("Relaxing %s (%p), output_offset: 0x%lx sec size: 0x%lx\n",
1884 sec->name, sec, sec->output_offset, sec->size);
1885
b18c562e
NC
1886 symtab_hdr = & elf_tdata (abfd)->symtab_hdr;
1887
1888 /* Get a copy of the native relocations. */
1889 internal_relocs =
1890 _bfd_elf_link_read_relocs (abfd, sec, NULL, NULL, link_info->keep_memory);
1891 if (internal_relocs == NULL)
1892 goto error_return;
1893
1894 /* Walk through them looking for relaxing opportunities. */
1895 irelend = internal_relocs + sec->reloc_count;
13761a11 1896
d60f5448
JL
1897 if (debug_relocs)
1898 printf (" trying code size growing relocs\n");
13761a11 1899 /* Do code size growing relocs first. */
b18c562e
NC
1900 for (irel = internal_relocs; irel < irelend; irel++)
1901 {
1902 bfd_vma symval;
1903
1904 /* If this isn't something that can be relaxed, then ignore
07d6d2b8 1905 this reloc. */
13761a11 1906 if (uses_msp430x_relocs (abfd)
07d6d2b8 1907 && ELF32_R_TYPE (irel->r_info) == (int) R_MSP430X_10_PCREL)
13761a11
NC
1908 ;
1909 else if (! uses_msp430x_relocs (abfd)
07d6d2b8 1910 && ELF32_R_TYPE (irel->r_info) == (int) R_MSP430_10_PCREL)
13761a11
NC
1911 ;
1912 else
b18c562e
NC
1913 continue;
1914
1915 /* Get the section contents if we haven't done so already. */
1916 if (contents == NULL)
1917 {
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))
1922 goto error_return;
1923 }
1924
1925 /* Read this BFD's local symbols if we haven't done so already. */
1926 if (isymbuf == NULL && symtab_hdr->sh_info != 0)
1927 {
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,
1932 NULL, NULL, NULL);
1933 if (isymbuf == NULL)
1934 goto error_return;
1935 }
1936
1937 /* Get the value of the symbol referred to by the reloc. */
1938 if (ELF32_R_SYM (irel->r_info) < symtab_hdr->sh_info)
1939 {
1940 /* A local symbol. */
1941 Elf_Internal_Sym *isym;
1942 asection *sym_sec;
1943
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;
1951 else
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);
d60f5448
JL
1955
1956 if (debug_relocs)
1957 printf (" processing reloc at 0x%lx for local sym: %s "
1958 "st_value: 0x%lx adj value: 0x%lx\n", sec->output_offset
1959 + sec->output_section->vma + irel->r_offset,
1960 bfd_elf_string_from_elf_section (abfd, symtab_hdr->sh_link,
1961 isym->st_name),
1962 isym->st_value, symval);
b18c562e
NC
1963 }
1964 else
1965 {
1966 unsigned long indx;
1967 struct elf_link_hash_entry *h;
1968
1969 /* An external symbol. */
1970 indx = ELF32_R_SYM (irel->r_info) - symtab_hdr->sh_info;
1971 h = elf_sym_hashes (abfd)[indx];
1972 BFD_ASSERT (h != NULL);
1973
1974 if (h->root.type != bfd_link_hash_defined
1975 && h->root.type != bfd_link_hash_defweak)
1976 /* This appears to be a reference to an undefined
1977 symbol. Just ignore it--it will be caught by the
1978 regular reloc processing. */
1979 continue;
1980
1981 symval = (h->root.u.def.value
1982 + h->root.u.def.section->output_section->vma
1983 + h->root.u.def.section->output_offset);
d60f5448
JL
1984 if (debug_relocs)
1985 printf (" processing reloc at 0x%lx for global sym: %s "
1986 "st_value: 0x%lx adj value: 0x%lx\n", sec->output_offset
1987 + sec->output_section->vma + irel->r_offset,
1988 h->root.root.string, h->root.u.def.value, symval);
b18c562e
NC
1989 }
1990
1991 /* For simplicity of coding, we are going to modify the section
07d6d2b8
AM
1992 contents, the section relocs, and the BFD symbol table. We
1993 must tell the rest of the code not to free up this
1994 information. It would be possible to instead create a table
1995 of changes which have to be made, as is done in coff-mips.c;
1996 that would be more work, but would require less memory when
1997 the linker is run. */
b18c562e 1998
13761a11
NC
1999 bfd_signed_vma value = symval;
2000 int opcode;
b18c562e 2001
13761a11
NC
2002 /* Compute the value that will be relocated. */
2003 value += irel->r_addend;
2004 /* Convert to PC relative. */
2005 value -= (sec->output_section->vma + sec->output_offset);
2006 value -= irel->r_offset;
2007 value -= 2;
d60f5448 2008
13761a11
NC
2009 /* Scale. */
2010 value >>= 1;
b18c562e 2011
13761a11
NC
2012 /* If it is in range then no modifications are needed. */
2013 if (value >= -512 && value <= 511)
2014 continue;
b18c562e 2015
13761a11
NC
2016 /* Get the opcode. */
2017 opcode = bfd_get_16 (abfd, contents + irel->r_offset);
1b786873 2018
13761a11 2019 /* Compute the new opcode. We are going to convert:
8d6cb116
JL
2020 JMP label
2021 into:
2022 BR[A] label
2023 or
13761a11 2024 J<cond> label
8d6cb116 2025 into:
13761a11
NC
2026 J<inv-cond> 1f
2027 BR[A] #label
07d6d2b8 2028 1: */
13761a11
NC
2029 switch (opcode & 0xfc00)
2030 {
1b786873 2031 case 0x3800: opcode = 0x3402; break; /* Jl -> Jge +2 */
13761a11
NC
2032 case 0x3400: opcode = 0x3802; break; /* Jge -> Jl +2 */
2033 case 0x2c00: opcode = 0x2802; break; /* Jhs -> Jlo +2 */
2034 case 0x2800: opcode = 0x2c02; break; /* Jlo -> Jhs +2 */
2035 case 0x2400: opcode = 0x2002; break; /* Jeq -> Jne +2 */
2036 case 0x2000: opcode = 0x2402; break; /* jne -> Jeq +2 */
2037 case 0x3000: /* jn */
2038 /* There is no direct inverse of the Jn insn.
2039 FIXME: we could do this as:
07d6d2b8
AM
2040 Jn 1f
2041 br 2f
13761a11 2042 1: br label
07d6d2b8 2043 2: */
13761a11 2044 continue;
8d6cb116
JL
2045 case 0x3c00:
2046 if (uses_msp430x_relocs (abfd))
2047 opcode = 0x0080; /* JMP -> BRA */
2048 else
2049 opcode = 0x4030; /* JMP -> BR */
2050 break;
13761a11 2051 default:
8d6cb116 2052 /* Unhandled branch instruction. */
13761a11 2053 /* fprintf (stderr, "unrecog: %x\n", opcode); */
2d071cfc 2054 continue;
13761a11 2055 }
b18c562e 2056
13761a11
NC
2057 /* Note that we've changed the relocs, section contents, etc. */
2058 elf_section_data (sec)->relocs = internal_relocs;
2059 elf_section_data (sec)->this_hdr.contents = contents;
2060 symtab_hdr->contents = (unsigned char *) isymbuf;
b18c562e 2061
13761a11
NC
2062 /* Install the new opcode. */
2063 bfd_put_16 (abfd, opcode, contents + irel->r_offset);
b18c562e 2064
13761a11
NC
2065 /* Insert the new branch instruction. */
2066 if (uses_msp430x_relocs (abfd))
2067 {
d60f5448
JL
2068 if (debug_relocs)
2069 printf (" R_MSP430X_10_PCREL -> R_MSP430X_ABS20_ADR_SRC "
2070 "(growing with new opcode 0x%x)\n", opcode);
2071
8d6cb116
JL
2072 /* Insert an absolute branch (aka MOVA) instruction.
2073 Note that bits 19:16 of the address are stored in the first word
2074 of the insn, so this is where r_offset will point to. */
2075 if (opcode == 0x0080)
2076 {
2077 /* If we're inserting a BRA because we are converting from a JMP,
2078 then only add one word for destination address; the BRA opcode
2079 has already been written. */
2080 contents = msp430_elf_relax_add_words
2081 (abfd, sec, irel->r_offset + 2, 1, 0x0000, 0);
2082 }
2083 else
2084 {
2085 contents = msp430_elf_relax_add_words
2086 (abfd, sec, irel->r_offset + 2, 2, 0x0080, 0x0000);
2087 /* Update the relocation to point to the inserted branch
2088 instruction. Note - we are changing a PC-relative reloc
2089 into an absolute reloc, but this is OK because we have
2090 arranged with the assembler to have the reloc's value be
2091 a (local) symbol, not a section+offset value. */
2092 irel->r_offset += 2;
2093 }
13761a11 2094
13761a11
NC
2095 irel->r_info = ELF32_R_INFO (ELF32_R_SYM (irel->r_info),
2096 R_MSP430X_ABS20_ADR_SRC);
2097 }
2098 else
2099 {
d60f5448
JL
2100 if (debug_relocs)
2101 printf (" R_MSP430_10_PCREL -> R_MSP430_16 "
2102 "(growing with new opcode 0x%x)\n", opcode);
8d6cb116
JL
2103 if (opcode == 0x4030)
2104 {
2105 /* If we're inserting a BR because we are converting from a JMP,
2106 then only add one word for destination address; the BR opcode
2107 has already been written. */
2108 contents = msp430_elf_relax_add_words
2109 (abfd, sec, irel->r_offset + 2, 1, 0x0000, 0);
2110 irel->r_offset += 2;
2111 }
2112 else
2113 {
2114 contents = msp430_elf_relax_add_words
2115 (abfd, sec, irel->r_offset + 2, 2, 0x4030, 0x0000);
2116 /* See comment above about converting a 10-bit PC-rel
2117 relocation into a 16-bit absolute relocation. */
2118 irel->r_offset += 4;
2119 }
13761a11
NC
2120 irel->r_info = ELF32_R_INFO (ELF32_R_SYM (irel->r_info),
2121 R_MSP430_16);
2122 }
b18c562e 2123
13761a11
NC
2124 /* Growing the section may mean that other
2125 conditional branches need to be fixed. */
2126 *again = TRUE;
2127 }
b18c562e 2128
d60f5448
JL
2129 if (debug_relocs)
2130 printf (" trying code size shrinking relocs\n");
2131
13761a11
NC
2132 for (irel = internal_relocs; irel < irelend; irel++)
2133 {
2134 bfd_vma symval;
2135
2136 /* Get the section contents if we haven't done so already. */
2137 if (contents == NULL)
2138 {
2139 /* Get cached copy if it exists. */
2140 if (elf_section_data (sec)->this_hdr.contents != NULL)
2141 contents = elf_section_data (sec)->this_hdr.contents;
2142 else if (! bfd_malloc_and_get_section (abfd, sec, &contents))
2143 goto error_return;
2144 }
2145
2146 /* Read this BFD's local symbols if we haven't done so already. */
2147 if (isymbuf == NULL && symtab_hdr->sh_info != 0)
2148 {
2149 isymbuf = (Elf_Internal_Sym *) symtab_hdr->contents;
2150 if (isymbuf == NULL)
2151 isymbuf = bfd_elf_get_elf_syms (abfd, symtab_hdr,
2152 symtab_hdr->sh_info, 0,
2153 NULL, NULL, NULL);
2154 if (isymbuf == NULL)
2155 goto error_return;
2156 }
2157
2158 /* Get the value of the symbol referred to by the reloc. */
2159 if (ELF32_R_SYM (irel->r_info) < symtab_hdr->sh_info)
2160 {
2161 /* A local symbol. */
2162 Elf_Internal_Sym *isym;
2163 asection *sym_sec;
2164
2165 isym = isymbuf + ELF32_R_SYM (irel->r_info);
2166 if (isym->st_shndx == SHN_UNDEF)
2167 sym_sec = bfd_und_section_ptr;
2168 else if (isym->st_shndx == SHN_ABS)
2169 sym_sec = bfd_abs_section_ptr;
2170 else if (isym->st_shndx == SHN_COMMON)
2171 sym_sec = bfd_com_section_ptr;
2172 else
2173 sym_sec = bfd_section_from_elf_index (abfd, isym->st_shndx);
2174 symval = (isym->st_value
2175 + sym_sec->output_section->vma + sym_sec->output_offset);
d60f5448
JL
2176
2177 if (debug_relocs)
2178 printf (" processing reloc at 0x%lx for local sym: %s "
2179 "st_value: 0x%lx adj value: 0x%lx\n", sec->output_offset
2180 + sec->output_section->vma + irel->r_offset,
2181 bfd_elf_string_from_elf_section
2182 (abfd, symtab_hdr->sh_link, isym->st_name),
2183 isym->st_value, symval);
13761a11
NC
2184 }
2185 else
2186 {
2187 unsigned long indx;
2188 struct elf_link_hash_entry *h;
2189
2190 /* An external symbol. */
2191 indx = ELF32_R_SYM (irel->r_info) - symtab_hdr->sh_info;
2192 h = elf_sym_hashes (abfd)[indx];
2193 BFD_ASSERT (h != NULL);
2194
2195 if (h->root.type != bfd_link_hash_defined
2196 && h->root.type != bfd_link_hash_defweak)
2197 /* This appears to be a reference to an undefined
2198 symbol. Just ignore it--it will be caught by the
2199 regular reloc processing. */
2200 continue;
2201
2202 symval = (h->root.u.def.value
2203 + h->root.u.def.section->output_section->vma
2204 + h->root.u.def.section->output_offset);
d60f5448
JL
2205 if (debug_relocs)
2206 printf (" processing reloc at 0x%lx for global sym: %s "
2207 "st_value: 0x%lx adj value: 0x%lx\n", sec->output_offset
2208 + sec->output_section->vma + irel->r_offset,
2209 h->root.root.string, h->root.u.def.value, symval);
13761a11
NC
2210 }
2211
2212 /* For simplicity of coding, we are going to modify the section
2213 contents, the section relocs, and the BFD symbol table. We
2214 must tell the rest of the code not to free up this
2215 information. It would be possible to instead create a table
2216 of changes which have to be made, as is done in coff-mips.c;
2217 that would be more work, but would require less memory when
2218 the linker is run. */
2219
2220 /* Try to turn a 16bit pc-relative branch into a 10bit pc-relative
2221 branch. */
1b786873 2222 /* Paranoia? paranoia... */
23d4663e
NC
2223 if (! uses_msp430x_relocs (abfd)
2224 && ELF32_R_TYPE (irel->r_info) == (int) R_MSP430_RL_PCREL)
13761a11
NC
2225 {
2226 bfd_vma value = symval;
2227
2228 /* Deal with pc-relative gunk. */
2229 value -= (sec->output_section->vma + sec->output_offset);
2230 value -= irel->r_offset;
2231 value += irel->r_addend;
2232
2233 /* See if the value will fit in 10 bits, note the high value is
2234 1016 as the target will be two bytes closer if we are
2235 able to relax. */
2236 if ((long) value < 1016 && (long) value > -1016)
2237 {
2238 int code0 = 0, code1 = 0, code2 = 0;
2239 int i;
2240 struct rcodes_s *rx;
2241
2242 /* Get the opcode. */
2243 if (irel->r_offset >= 6)
2244 code0 = bfd_get_16 (abfd, contents + irel->r_offset - 6);
2245
2246 if (irel->r_offset >= 4)
2247 code1 = bfd_get_16 (abfd, contents + irel->r_offset - 4);
2248
2249 code2 = bfd_get_16 (abfd, contents + irel->r_offset - 2);
2250
2251 if (code2 != 0x4010)
2252 continue;
2253
2254 /* Check r4 and r3. */
2255 for (i = NUMB_RELAX_CODES - 1; i >= 0; i--)
2256 {
2257 rx = &rcode[i];
2258 if (rx->cdx == 2 && rx->f0 == code0 && rx->f1 == code1)
2259 break;
2260 else if (rx->cdx == 1 && rx->f1 == code1)
2261 break;
2262 else if (rx->cdx == 0) /* This is an unconditional jump. */
2263 break;
2264 }
2265
2266 /* Check labels:
b18c562e 2267 .Label0: ; we do not care about this label
13761a11 2268 jeq +6
b18c562e 2269 .Label1: ; make sure there is no label here
13761a11 2270 jl +4
b18c562e 2271 .Label2: ; make sure there is no label here
13761a11
NC
2272 br .Label_dst
2273
2274 So, if there is .Label1 or .Label2 we cannot relax this code.
2275 This actually should not happen, cause for relaxable
2276 instructions we use RL_PCREL reloc instead of 16_PCREL.
2277 Will change this in the future. */
2278
2279 if (rx->cdx > 0
2280 && msp430_elf_symbol_address_p (abfd, sec, isymbuf,
2281 irel->r_offset - 2))
2282 continue;
2283 if (rx->cdx > 1
2284 && msp430_elf_symbol_address_p (abfd, sec, isymbuf,
2285 irel->r_offset - 4))
2286 continue;
2287
2288 /* Note that we've changed the relocs, section contents, etc. */
2289 elf_section_data (sec)->relocs = internal_relocs;
2290 elf_section_data (sec)->this_hdr.contents = contents;
2291 symtab_hdr->contents = (unsigned char *) isymbuf;
2292
d60f5448
JL
2293 if (debug_relocs)
2294 printf (" R_MSP430_RL_PCREL -> ");
13761a11
NC
2295 /* Fix the relocation's type. */
2296 if (uses_msp430x_relocs (abfd))
2297 {
2298 if (rx->labels == 3) /* Handle special cases. */
2299 irel->r_info = ELF32_R_INFO (ELF32_R_SYM (irel->r_info),
2300 R_MSP430X_2X_PCREL);
2301 else
2302 irel->r_info = ELF32_R_INFO (ELF32_R_SYM (irel->r_info),
2303 R_MSP430X_10_PCREL);
2304 }
2305 else
2306 {
2307 if (rx->labels == 3) /* Handle special cases. */
d60f5448
JL
2308 {
2309 irel->r_info = ELF32_R_INFO (ELF32_R_SYM (irel->r_info),
2310 R_MSP430_2X_PCREL);
2311 if (debug_relocs)
2312 printf ("R_MSP430_2X_PCREL (shrinking with new opcode"
2313 " 0x%x)\n", rx->t0);
2314 }
13761a11 2315 else
d60f5448
JL
2316 {
2317 irel->r_info = ELF32_R_INFO (ELF32_R_SYM (irel->r_info),
2318 R_MSP430_10_PCREL);
2319 if (debug_relocs)
2320 printf ("R_MSP430_10_PCREL (shrinking with new opcode"
2321 " 0x%x)\n", rx->t0);
2322 }
13761a11
NC
2323 }
2324
2325 /* Fix the opcode right way. */
2326 bfd_put_16 (abfd, rx->t0, contents + irel->r_offset - rx->off);
2327 if (rx->t1)
2328 bfd_put_16 (abfd, rx->t1,
2329 contents + irel->r_offset - rx->off + 2);
2330
2331 /* Delete bytes. */
2332 if (!msp430_elf_relax_delete_bytes (abfd, sec,
2333 irel->r_offset - rx->off +
2334 rx->ncl, rx->bs))
2335 goto error_return;
2336
2337 /* Handle unconditional jumps. */
2338 if (rx->cdx == 0)
2339 irel->r_offset -= 2;
2340
2341 /* That will change things, so, we should relax again.
2342 Note that this is not required, and it may be slow. */
2343 *again = TRUE;
2344 }
2345 }
23d4663e
NC
2346
2347 /* Try to turn a 16-bit absolute branch into a 10-bit pc-relative
2348 branch. */
133193b8
NC
2349 if ((uses_msp430x_relocs (abfd)
2350 && ELF32_R_TYPE (irel->r_info) == R_MSP430X_ABS16)
2351 || (! uses_msp430x_relocs (abfd)
2352 && ELF32_R_TYPE (irel->r_info) == R_MSP430_16))
23d4663e
NC
2353 {
2354 bfd_vma value = symval;
2355
2d071cfc 2356 value -= (sec->output_section->vma + sec->output_offset);
23d4663e
NC
2357 value -= irel->r_offset;
2358 value += irel->r_addend;
1b786873 2359
23d4663e
NC
2360 /* See if the value will fit in 10 bits, note the high value is
2361 1016 as the target will be two bytes closer if we are
2362 able to relax. */
2363 if ((long) value < 1016 && (long) value > -1016)
2364 {
2365 int code2;
2366
2367 /* Get the opcode. */
2368 code2 = bfd_get_16 (abfd, contents + irel->r_offset - 2);
2369 if (code2 != 0x4030)
2370 continue;
2371 /* FIXME: check r4 and r3 ? */
2372 /* FIXME: Handle 0x4010 as well ? */
2373
2374 /* Note that we've changed the relocs, section contents, etc. */
2375 elf_section_data (sec)->relocs = internal_relocs;
2376 elf_section_data (sec)->this_hdr.contents = contents;
2377 symtab_hdr->contents = (unsigned char *) isymbuf;
2378
2379 /* Fix the relocation's type. */
2380 if (uses_msp430x_relocs (abfd))
2381 {
2382 irel->r_info = ELF32_R_INFO (ELF32_R_SYM (irel->r_info),
2383 R_MSP430X_10_PCREL);
d60f5448
JL
2384 if (debug_relocs)
2385 printf (" R_MSP430X_16 -> R_MSP430X_10_PCREL ");
23d4663e
NC
2386 }
2387 else
2388 {
2389 irel->r_info = ELF32_R_INFO (ELF32_R_SYM (irel->r_info),
2390 R_MSP430_10_PCREL);
d60f5448
JL
2391 if (debug_relocs)
2392 printf (" R_MSP430_16 -> R_MSP430_10_PCREL ");
23d4663e 2393 }
d60f5448
JL
2394 if (debug_relocs)
2395 printf ("(shrinking with new opcode 0x3c00)\n");
23d4663e
NC
2396
2397 /* Fix the opcode right way. */
2398 bfd_put_16 (abfd, 0x3c00, contents + irel->r_offset - 2);
2399 irel->r_offset -= 2;
2400
2401 /* Delete bytes. */
2402 if (!msp430_elf_relax_delete_bytes (abfd, sec,
2403 irel->r_offset + 2, 2))
2404 goto error_return;
2405
2406 /* That will change things, so, we should relax again.
2407 Note that this is not required, and it may be slow. */
2408 *again = TRUE;
2409 }
2410 }
13761a11 2411 }
b18c562e
NC
2412
2413 if (isymbuf != NULL && symtab_hdr->contents != (unsigned char *) isymbuf)
2414 {
2415 if (!link_info->keep_memory)
2416 free (isymbuf);
2417 else
2418 {
2419 /* Cache the symbols for elf_link_input_bfd. */
2420 symtab_hdr->contents = (unsigned char *) isymbuf;
2421 }
2422 }
2423
2424 if (contents != NULL
2425 && elf_section_data (sec)->this_hdr.contents != contents)
2426 {
2427 if (!link_info->keep_memory)
2428 free (contents);
2429 else
2430 {
2431 /* Cache the section contents for elf_link_input_bfd. */
2432 elf_section_data (sec)->this_hdr.contents = contents;
2433 }
2434 }
2435
2436 if (internal_relocs != NULL
2437 && elf_section_data (sec)->relocs != internal_relocs)
2438 free (internal_relocs);
2439
2440 return TRUE;
2441
2442error_return:
2443 if (isymbuf != NULL && symtab_hdr->contents != (unsigned char *) isymbuf)
2444 free (isymbuf);
2445 if (contents != NULL
2446 && elf_section_data (sec)->this_hdr.contents != contents)
2447 free (contents);
2448 if (internal_relocs != NULL
2449 && elf_section_data (sec)->relocs != internal_relocs)
2450 free (internal_relocs);
2451
2452 return FALSE;
2453}
2454
13761a11
NC
2455/* Handle an MSP430 specific section when reading an object file.
2456 This is called when bfd_section_from_shdr finds a section with
2457 an unknown type. */
2458
2459static bfd_boolean
2460elf32_msp430_section_from_shdr (bfd *abfd,
2461 Elf_Internal_Shdr * hdr,
2462 const char *name,
2463 int shindex)
2464{
2465 switch (hdr->sh_type)
2466 {
2467 case SHT_MSP430_SEC_FLAGS:
2468 case SHT_MSP430_SYM_ALIASES:
2469 case SHT_MSP430_ATTRIBUTES:
2470 return _bfd_elf_make_section_from_shdr (abfd, hdr, name, shindex);
2471 default:
2472 return FALSE;
2473 }
2474}
2475
2476static bfd_boolean
2477elf32_msp430_obj_attrs_handle_unknown (bfd *abfd, int tag)
2478{
2479 _bfd_error_handler
695344c0 2480 /* xgettext:c-format */
38f14ab8 2481 (_("warning: %pB: unknown MSPABI object attribute %d"),
13761a11
NC
2482 abfd, tag);
2483 return TRUE;
2484}
2485
2486/* Determine whether an object attribute tag takes an integer, a
2487 string or both. */
2488
2489static int
2490elf32_msp430_obj_attrs_arg_type (int tag)
2491{
2492 if (tag == Tag_compatibility)
2493 return ATTR_TYPE_FLAG_INT_VAL | ATTR_TYPE_FLAG_STR_VAL;
2494
2495 if (tag < 32)
2496 return ATTR_TYPE_FLAG_INT_VAL;
2497
2498 return (tag & 1) != 0 ? ATTR_TYPE_FLAG_STR_VAL : ATTR_TYPE_FLAG_INT_VAL;
2499}
2500
2501static inline const char *
2502isa_type (int isa)
2503{
2504 switch (isa)
2505 {
2506 case 1: return "MSP430";
2507 case 2: return "MSP430X";
2508 default: return "unknown";
2509 }
2510}
2511
2512static inline const char *
2513code_model (int model)
2514{
2515 switch (model)
2516 {
2517 case 1: return "small";
2518 case 2: return "large";
2519 default: return "unknown";
2520 }
2521}
2522
2523static inline const char *
2524data_model (int model)
2525{
2526 switch (model)
2527 {
2528 case 1: return "small";
2529 case 2: return "large";
2530 case 3: return "restricted large";
2531 default: return "unknown";
2532 }
2533}
2534
c0ea7c52 2535/* Merge MSPABI and GNU object attributes from IBFD into OBFD.
13761a11
NC
2536 Raise an error if there are conflicting attributes. */
2537
2538static bfd_boolean
c0ea7c52 2539elf32_msp430_merge_msp430_attributes (bfd *ibfd, struct bfd_link_info *info)
13761a11 2540{
50e03d47 2541 bfd *obfd = info->output_bfd;
c0ea7c52
JL
2542 obj_attribute *in_msp_attr, *in_gnu_attr;
2543 obj_attribute *out_msp_attr, *out_gnu_attr;
13761a11
NC
2544 bfd_boolean result = TRUE;
2545 static bfd * first_input_bfd = NULL;
2546
2547 /* Skip linker created files. */
2548 if (ibfd->flags & BFD_LINKER_CREATED)
2549 return TRUE;
2550
ca94519e
JL
2551 /* LTO can create temporary files for linking which may not have an attribute
2552 section. */
2553 if (ibfd->lto_output
2554 && bfd_get_section_by_name (ibfd, ".MSP430.attributes") == NULL)
2555 return TRUE;
2556
13761a11
NC
2557 /* If this is the first real object just copy the attributes. */
2558 if (!elf_known_obj_attributes_proc (obfd)[0].i)
2559 {
2560 _bfd_elf_copy_obj_attributes (ibfd, obfd);
2561
c0ea7c52 2562 out_msp_attr = elf_known_obj_attributes_proc (obfd);
13761a11
NC
2563
2564 /* Use the Tag_null value to indicate that
2565 the attributes have been initialized. */
c0ea7c52 2566 out_msp_attr[0].i = 1;
13761a11
NC
2567
2568 first_input_bfd = ibfd;
2569 return TRUE;
2570 }
2571
c0ea7c52
JL
2572 in_msp_attr = elf_known_obj_attributes_proc (ibfd);
2573 out_msp_attr = elf_known_obj_attributes_proc (obfd);
2574 in_gnu_attr = elf_known_obj_attributes (ibfd) [OBJ_ATTR_GNU];
2575 out_gnu_attr = elf_known_obj_attributes (obfd) [OBJ_ATTR_GNU];
13761a11
NC
2576
2577 /* The ISAs must be the same. */
c0ea7c52 2578 if (in_msp_attr[OFBA_MSPABI_Tag_ISA].i != out_msp_attr[OFBA_MSPABI_Tag_ISA].i)
13761a11
NC
2579 {
2580 _bfd_error_handler
695344c0 2581 /* xgettext:c-format */
871b3ab2 2582 (_("error: %pB uses %s instructions but %pB uses %s"),
c0ea7c52
JL
2583 ibfd, isa_type (in_msp_attr[OFBA_MSPABI_Tag_ISA].i),
2584 first_input_bfd, isa_type (out_msp_attr[OFBA_MSPABI_Tag_ISA].i));
13761a11
NC
2585 result = FALSE;
2586 }
2587
2588 /* The code models must be the same. */
c0ea7c52
JL
2589 if (in_msp_attr[OFBA_MSPABI_Tag_Code_Model].i
2590 != out_msp_attr[OFBA_MSPABI_Tag_Code_Model].i)
13761a11
NC
2591 {
2592 _bfd_error_handler
695344c0 2593 /* xgettext:c-format */
871b3ab2 2594 (_("error: %pB uses the %s code model whereas %pB uses the %s code model"),
c0ea7c52
JL
2595 ibfd, code_model (in_msp_attr[OFBA_MSPABI_Tag_Code_Model].i),
2596 first_input_bfd,
2597 code_model (out_msp_attr[OFBA_MSPABI_Tag_Code_Model].i));
13761a11
NC
2598 result = FALSE;
2599 }
2600
2601 /* The large code model is only supported by the MSP430X. */
c0ea7c52
JL
2602 if (in_msp_attr[OFBA_MSPABI_Tag_Code_Model].i == 2
2603 && out_msp_attr[OFBA_MSPABI_Tag_ISA].i != 2)
13761a11
NC
2604 {
2605 _bfd_error_handler
695344c0 2606 /* xgettext:c-format */
871b3ab2 2607 (_("error: %pB uses the large code model but %pB uses MSP430 instructions"),
13761a11
NC
2608 ibfd, first_input_bfd);
2609 result = FALSE;
2610 }
2611
2612 /* The data models must be the same. */
c0ea7c52
JL
2613 if (in_msp_attr[OFBA_MSPABI_Tag_Data_Model].i
2614 != out_msp_attr[OFBA_MSPABI_Tag_Data_Model].i)
13761a11
NC
2615 {
2616 _bfd_error_handler
695344c0 2617 /* xgettext:c-format */
871b3ab2 2618 (_("error: %pB uses the %s data model whereas %pB uses the %s data model"),
c0ea7c52
JL
2619 ibfd, data_model (in_msp_attr[OFBA_MSPABI_Tag_Data_Model].i),
2620 first_input_bfd,
2621 data_model (out_msp_attr[OFBA_MSPABI_Tag_Data_Model].i));
13761a11
NC
2622 result = FALSE;
2623 }
2624
2625 /* The small code model requires the use of the small data model. */
c0ea7c52
JL
2626 if (in_msp_attr[OFBA_MSPABI_Tag_Code_Model].i == 1
2627 && out_msp_attr[OFBA_MSPABI_Tag_Data_Model].i != 1)
13761a11
NC
2628 {
2629 _bfd_error_handler
695344c0 2630 /* xgettext:c-format */
871b3ab2 2631 (_("error: %pB uses the small code model but %pB uses the %s data model"),
13761a11 2632 ibfd, first_input_bfd,
c0ea7c52 2633 data_model (out_msp_attr[OFBA_MSPABI_Tag_Data_Model].i));
13761a11
NC
2634 result = FALSE;
2635 }
2636
2637 /* The large data models are only supported by the MSP430X. */
c0ea7c52
JL
2638 if (in_msp_attr[OFBA_MSPABI_Tag_Data_Model].i > 1
2639 && out_msp_attr[OFBA_MSPABI_Tag_ISA].i != 2)
13761a11
NC
2640 {
2641 _bfd_error_handler
695344c0 2642 /* xgettext:c-format */
871b3ab2 2643 (_("error: %pB uses the %s data model but %pB only uses MSP430 instructions"),
c0ea7c52 2644 ibfd, data_model (in_msp_attr[OFBA_MSPABI_Tag_Data_Model].i),
c08bb8dd 2645 first_input_bfd);
13761a11
NC
2646 result = FALSE;
2647 }
1b786873 2648
c0ea7c52
JL
2649 /* Just ignore the data region unless the large memory model is in use.
2650 We have already checked that ibfd and obfd use the same memory model. */
2651 if ((in_msp_attr[OFBA_MSPABI_Tag_Code_Model].i
2652 == OFBA_MSPABI_Val_Code_Model_LARGE)
2653 && (in_msp_attr[OFBA_MSPABI_Tag_Data_Model].i
2654 == OFBA_MSPABI_Val_Data_Model_LARGE))
2655 {
2656 /* We cannot allow "lower region only" to be linked with any other
2657 values (i.e. ANY or NONE).
2658 Before this attribute existed, "ANY" region was the default. */
2659 bfd_boolean ibfd_lower_region_used
2660 = (in_gnu_attr[Tag_GNU_MSP430_Data_Region].i
2661 == Val_GNU_MSP430_Data_Region_Lower);
2662 bfd_boolean obfd_lower_region_used
2663 = (out_gnu_attr[Tag_GNU_MSP430_Data_Region].i
2664 == Val_GNU_MSP430_Data_Region_Lower);
2665 if (ibfd_lower_region_used != obfd_lower_region_used)
2666 {
2667 _bfd_error_handler
2668 (_("error: %pB can use the upper region for data, "
2669 "but %pB assumes data is exclusively in lower memory"),
2670 ibfd_lower_region_used ? obfd : ibfd,
2671 ibfd_lower_region_used ? ibfd : obfd);
2672 result = FALSE;
2673 }
2674 }
2675
13761a11
NC
2676 return result;
2677}
2678
2679/* Merge backend specific data from an object file to the output
2680 object file when linking. */
2681
2682static bfd_boolean
50e03d47 2683elf32_msp430_merge_private_bfd_data (bfd *ibfd, struct bfd_link_info *info)
13761a11 2684{
50e03d47 2685 bfd *obfd = info->output_bfd;
13761a11
NC
2686 /* Make sure that the machine number reflects the most
2687 advanced version of the MSP architecture required. */
2688#define max(a,b) ((a) > (b) ? (a) : (b))
2689 if (bfd_get_mach (ibfd) != bfd_get_mach (obfd))
2690 bfd_default_set_arch_mach (obfd, bfd_get_arch (obfd),
2691 max (bfd_get_mach (ibfd), bfd_get_mach (obfd)));
2692#undef max
2693
c0ea7c52 2694 return elf32_msp430_merge_msp430_attributes (ibfd, info);
13761a11
NC
2695}
2696
13761a11
NC
2697static bfd_boolean
2698msp430_elf_is_target_special_symbol (bfd *abfd, asymbol *sym)
2699{
2700 return _bfd_elf_is_local_label_name (abfd, sym->name);
2701}
2702
79559014
NC
2703static bfd_boolean
2704uses_large_model (bfd *abfd)
2705{
2706 obj_attribute * attr;
2707
2708 if (abfd->flags & BFD_LINKER_CREATED)
2709 return FALSE;
2710
2711 attr = elf_known_obj_attributes_proc (abfd);
2712 if (attr == NULL)
2713 return FALSE;
2714
2715 return attr[OFBA_MSPABI_Tag_Code_Model].i == 2;
2716}
2717
2718static unsigned int
76c20d54
AM
2719elf32_msp430_eh_frame_address_size (bfd *abfd,
2720 const asection *sec ATTRIBUTE_UNUSED)
79559014
NC
2721{
2722 return uses_large_model (abfd) ? 4 : 2;
2723}
2724
13761a11
NC
2725/* This is gross. The MSP430 EABI says that (sec 11.5):
2726
2727 "An implementation may choose to use Rel or Rela
2728 type relocations for other relocations."
2729
2730 But it also says that:
1b786873 2731
13761a11
NC
2732 "Certain relocations are identified as Rela only. [snip]
2733 Where Rela is specified, an implementation must honor
2734 this requirement."
2735
2736 There is one relocation marked as requiring RELA - R_MSP430_ABS_HI16 - but
2737 to keep things simple we choose to use RELA relocations throughout. The
2738 problem is that the TI compiler generates REL relocations, so we have to
2739 be able to accept those as well. */
2740
2741#define elf_backend_may_use_rel_p 1
2742#define elf_backend_may_use_rela_p 1
2743#define elf_backend_default_use_rela_p 1
2744
07d6d2b8 2745#undef elf_backend_obj_attrs_vendor
13761a11 2746#define elf_backend_obj_attrs_vendor "mspabi"
07d6d2b8 2747#undef elf_backend_obj_attrs_section
13761a11 2748#define elf_backend_obj_attrs_section ".MSP430.attributes"
07d6d2b8 2749#undef elf_backend_obj_attrs_section_type
13761a11 2750#define elf_backend_obj_attrs_section_type SHT_MSP430_ATTRIBUTES
07d6d2b8
AM
2751#define elf_backend_section_from_shdr elf32_msp430_section_from_shdr
2752#define elf_backend_obj_attrs_handle_unknown elf32_msp430_obj_attrs_handle_unknown
2753#undef elf_backend_obj_attrs_arg_type
13761a11 2754#define elf_backend_obj_attrs_arg_type elf32_msp430_obj_attrs_arg_type
13761a11 2755#define bfd_elf32_bfd_merge_private_bfd_data elf32_msp430_merge_private_bfd_data
79559014 2756#define elf_backend_eh_frame_address_size elf32_msp430_eh_frame_address_size
2469cfa2
NC
2757
2758#define ELF_ARCH bfd_arch_msp430
2759#define ELF_MACHINE_CODE EM_MSP430
2760#define ELF_MACHINE_ALT1 EM_MSP430_OLD
13761a11 2761#define ELF_MAXPAGESIZE 4
d1036acb 2762#define ELF_OSABI ELFOSABI_STANDALONE
2469cfa2 2763
07d6d2b8 2764#define TARGET_LITTLE_SYM msp430_elf32_vec
2469cfa2
NC
2765#define TARGET_LITTLE_NAME "elf32-msp430"
2766
07d6d2b8
AM
2767#define elf_info_to_howto msp430_info_to_howto_rela
2768#define elf_info_to_howto_rel NULL
2769#define elf_backend_relocate_section elf32_msp430_relocate_section
2770#define elf_backend_check_relocs elf32_msp430_check_relocs
2771#define elf_backend_can_gc_sections 1
2469cfa2
NC
2772#define elf_backend_final_write_processing bfd_elf_msp430_final_write_processing
2773#define elf_backend_object_p elf32_msp430_object_p
b18c562e 2774#define bfd_elf32_bfd_relax_section msp430_elf_relax_section
13761a11
NC
2775#define bfd_elf32_bfd_is_target_special_symbol msp430_elf_is_target_special_symbol
2776
07d6d2b8 2777#undef elf32_bed
13761a11
NC
2778#define elf32_bed elf32_msp430_bed
2779
2780#include "elf32-target.h"
2781
2782/* The TI compiler sets the OSABI field to ELFOSABI_NONE. */
07d6d2b8
AM
2783#undef TARGET_LITTLE_SYM
2784#define TARGET_LITTLE_SYM msp430_elf32_ti_vec
13761a11 2785
07d6d2b8 2786#undef elf32_bed
13761a11
NC
2787#define elf32_bed elf32_msp430_ti_bed
2788
1b786873 2789#undef ELF_OSABI
13761a11
NC
2790#define ELF_OSABI ELFOSABI_NONE
2791
2792static const struct bfd_elf_special_section msp430_ti_elf_special_sections[] =
2793{
07d6d2b8 2794 /* prefix, prefix_length, suffix_len, type, attributes. */
13761a11
NC
2795 { STRING_COMMA_LEN (".TI.symbol.alias"), 0, SHT_MSP430_SYM_ALIASES, 0 },
2796 { STRING_COMMA_LEN (".TI.section.flags"), 0, SHT_MSP430_SEC_FLAGS, 0 },
2797 { STRING_COMMA_LEN ("_TI_build_attrib"), 0, SHT_MSP430_ATTRIBUTES, 0 },
07d6d2b8 2798 { NULL, 0, 0, 0, 0 }
13761a11 2799};
2469cfa2 2800
07d6d2b8
AM
2801#undef elf_backend_special_sections
2802#define elf_backend_special_sections msp430_ti_elf_special_sections
b6518b38 2803
2469cfa2 2804#include "elf32-target.h"
This page took 1.058311 seconds and 4 git commands to generate.