]> git.ipfire.org Git - thirdparty/binutils-gdb.git/blame - bfd/elf32-msp430.c
ld: Add -z separate-code tests to frame.exp
[thirdparty/binutils-gdb.git] / bfd / elf32-msp430.c
CommitLineData
2469cfa2 1/* MSP430-specific support for 32-bit ELF
219d1afa 2 Copyright (C) 2002-2018 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
1ade7175
NC
29static bfd_reloc_status_type
30rl78_sym_diff_handler (bfd * abfd,
31 arelent * reloc,
32 asymbol * sym ATTRIBUTE_UNUSED,
33 void * addr ATTRIBUTE_UNUSED,
34 asection * input_sec,
35 bfd * out_bfd ATTRIBUTE_UNUSED,
36 char ** error_message ATTRIBUTE_UNUSED)
37{
38 bfd_size_type octets;
39 octets = reloc->address * bfd_octets_per_byte (abfd);
40
41 /* Catch the case where bfd_install_relocation would return
42 bfd_reloc_outofrange because the SYM_DIFF reloc is being used in a very
43 small section. It does not actually matter if this happens because all
44 that SYM_DIFF does is compute a (4-byte) value. A second reloc then uses
45 this value, and it is that reloc that must fit into the section.
46
47 This happens in eg, gcc/testsuite/gcc.c-torture/compile/labels-3.c. */
48 if ((octets + bfd_get_reloc_size (reloc->howto))
49 > bfd_get_section_limit_octets (abfd, input_sec))
50 return bfd_reloc_ok;
51 return bfd_reloc_continue;
52}
53
2469cfa2
NC
54static reloc_howto_type elf_msp430_howto_table[] =
55{
56 HOWTO (R_MSP430_NONE, /* type */
57 0, /* rightshift */
6346d5ca
AM
58 3, /* size (0 = byte, 1 = short, 2 = long) */
59 0, /* bitsize */
2469cfa2
NC
60 FALSE, /* pc_relative */
61 0, /* bitpos */
6346d5ca 62 complain_overflow_dont,/* complain_on_overflow */
2469cfa2
NC
63 bfd_elf_generic_reloc, /* special_function */
64 "R_MSP430_NONE", /* name */
65 FALSE, /* partial_inplace */
66 0, /* src_mask */
67 0, /* dst_mask */
68 FALSE), /* pcrel_offset */
69
70 HOWTO (R_MSP430_32, /* type */
71 0, /* rightshift */
72 2, /* size (0 = byte, 1 = short, 2 = long) */
73 32, /* bitsize */
74 FALSE, /* pc_relative */
75 0, /* bitpos */
b18c562e 76 complain_overflow_bitfield,/* complain_on_overflow */
2469cfa2
NC
77 bfd_elf_generic_reloc, /* special_function */
78 "R_MSP430_32", /* name */
79 FALSE, /* partial_inplace */
80 0xffffffff, /* src_mask */
81 0xffffffff, /* dst_mask */
82 FALSE), /* pcrel_offset */
83
df301bfc 84 /* A 10 bit PC relative relocation. */
2469cfa2
NC
85 HOWTO (R_MSP430_10_PCREL, /* type */
86 1, /* rightshift */
87 1, /* size (0 = byte, 1 = short, 2 = long) */
88 10, /* bitsize */
89 TRUE, /* pc_relative */
90 0, /* bitpos */
b18c562e 91 complain_overflow_bitfield,/* complain_on_overflow */
2469cfa2 92 bfd_elf_generic_reloc, /* special_function */
13761a11 93 "R_MSP430_10_PCREL", /* name */
2469cfa2 94 FALSE, /* partial_inplace */
df301bfc
NC
95 0x3ff, /* src_mask */
96 0x3ff, /* dst_mask */
2469cfa2
NC
97 TRUE), /* pcrel_offset */
98
99 /* A 16 bit absolute relocation. */
100 HOWTO (R_MSP430_16, /* type */
101 0, /* rightshift */
102 1, /* size (0 = byte, 1 = short, 2 = long) */
103 16, /* bitsize */
104 FALSE, /* pc_relative */
105 0, /* bitpos */
106 complain_overflow_dont,/* complain_on_overflow */
107 bfd_elf_generic_reloc, /* special_function */
108 "R_MSP430_16", /* name */
109 FALSE, /* partial_inplace */
b18c562e 110 0, /* src_mask */
2469cfa2
NC
111 0xffff, /* dst_mask */
112 FALSE), /* pcrel_offset */
113
13761a11 114 /* A 16 bit PC relative relocation for command address. */
2469cfa2
NC
115 HOWTO (R_MSP430_16_PCREL, /* type */
116 1, /* rightshift */
117 1, /* size (0 = byte, 1 = short, 2 = long) */
118 16, /* bitsize */
119 TRUE, /* pc_relative */
120 0, /* bitpos */
121 complain_overflow_dont,/* complain_on_overflow */
122 bfd_elf_generic_reloc, /* special_function */
123 "R_MSP430_16_PCREL", /* name */
124 FALSE, /* partial_inplace */
b18c562e 125 0, /* src_mask */
2469cfa2
NC
126 0xffff, /* dst_mask */
127 TRUE), /* pcrel_offset */
128
129 /* A 16 bit absolute relocation, byte operations. */
130 HOWTO (R_MSP430_16_BYTE, /* type */
131 0, /* rightshift */
132 1, /* size (0 = byte, 1 = short, 2 = long) */
133 16, /* bitsize */
134 FALSE, /* pc_relative */
135 0, /* bitpos */
136 complain_overflow_dont,/* complain_on_overflow */
137 bfd_elf_generic_reloc, /* special_function */
138 "R_MSP430_16_BYTE", /* name */
139 FALSE, /* partial_inplace */
140 0xffff, /* src_mask */
141 0xffff, /* dst_mask */
142 FALSE), /* pcrel_offset */
143
144 /* A 16 bit absolute relocation for command address. */
145 HOWTO (R_MSP430_16_PCREL_BYTE,/* type */
146 1, /* rightshift */
147 1, /* size (0 = byte, 1 = short, 2 = long) */
148 16, /* bitsize */
149 TRUE, /* pc_relative */
150 0, /* bitpos */
151 complain_overflow_dont,/* complain_on_overflow */
152 bfd_elf_generic_reloc, /* special_function */
b18c562e 153 "R_MSP430_16_PCREL_BYTE",/* name */
2469cfa2
NC
154 FALSE, /* partial_inplace */
155 0xffff, /* src_mask */
156 0xffff, /* dst_mask */
b18c562e
NC
157 TRUE), /* pcrel_offset */
158
df301bfc 159 /* A 10 bit PC relative relocation for complicated polymorphs. */
b18c562e
NC
160 HOWTO (R_MSP430_2X_PCREL, /* type */
161 1, /* rightshift */
162 2, /* size (0 = byte, 1 = short, 2 = long) */
163 10, /* bitsize */
164 TRUE, /* pc_relative */
165 0, /* bitpos */
166 complain_overflow_bitfield,/* complain_on_overflow */
167 bfd_elf_generic_reloc, /* special_function */
168 "R_MSP430_2X_PCREL", /* name */
169 FALSE, /* partial_inplace */
df301bfc
NC
170 0x3ff, /* src_mask */
171 0x3ff, /* dst_mask */
b18c562e
NC
172 TRUE), /* pcrel_offset */
173
174 /* A 16 bit relaxable relocation for command address. */
175 HOWTO (R_MSP430_RL_PCREL, /* type */
176 1, /* rightshift */
177 1, /* size (0 = byte, 1 = short, 2 = long) */
178 16, /* bitsize */
179 TRUE, /* pc_relative */
180 0, /* bitpos */
181 complain_overflow_dont,/* complain_on_overflow */
182 bfd_elf_generic_reloc, /* special_function */
183 "R_MSP430_RL_PCREL", /* name */
184 FALSE, /* partial_inplace */
185 0, /* src_mask */
186 0xffff, /* dst_mask */
2469cfa2 187 TRUE) /* pcrel_offset */
13761a11
NC
188
189 /* A 8-bit absolute relocation. */
190 , HOWTO (R_MSP430_8, /* type */
191 0, /* rightshift */
192 0, /* size (0 = byte, 1 = short, 2 = long) */
193 8, /* bitsize */
194 FALSE, /* pc_relative */
195 0, /* bitpos */
196 complain_overflow_dont,/* complain_on_overflow */
197 bfd_elf_generic_reloc, /* special_function */
198 "R_MSP430_8", /* name */
199 FALSE, /* partial_inplace */
200 0, /* src_mask */
201 0xffff, /* dst_mask */
202 FALSE), /* pcrel_offset */
203
204 /* Together with a following reloc, allows for the difference
205 between two symbols to be the real addend of the second reloc. */
206 HOWTO (R_MSP430_SYM_DIFF, /* type */
207 0, /* rightshift */
208 2, /* size (0 = byte, 1 = short, 2 = long) */
209 32, /* bitsize */
210 FALSE, /* pc_relative */
211 0, /* bitpos */
212 complain_overflow_dont,/* complain_on_overflow */
1ade7175 213 rl78_sym_diff_handler, /* special handler. */
13761a11
NC
214 "R_MSP430_SYM_DIFF", /* name */
215 FALSE, /* partial_inplace */
216 0xffffffff, /* src_mask */
217 0xffffffff, /* dst_mask */
1b786873 218 FALSE) /* pcrel_offset */
13761a11
NC
219};
220
221static reloc_howto_type elf_msp430x_howto_table[] =
222{
223 HOWTO (R_MSP430_NONE, /* type */
224 0, /* rightshift */
6346d5ca
AM
225 3, /* size (0 = byte, 1 = short, 2 = long) */
226 0, /* bitsize */
13761a11
NC
227 FALSE, /* pc_relative */
228 0, /* bitpos */
6346d5ca 229 complain_overflow_dont,/* complain_on_overflow */
13761a11
NC
230 bfd_elf_generic_reloc, /* special_function */
231 "R_MSP430_NONE", /* name */
232 FALSE, /* partial_inplace */
233 0, /* src_mask */
234 0, /* dst_mask */
235 FALSE), /* pcrel_offset */
236
237 HOWTO (R_MSP430_ABS32, /* type */
238 0, /* rightshift */
239 2, /* size (0 = byte, 1 = short, 2 = long) */
240 32, /* bitsize */
241 FALSE, /* pc_relative */
242 0, /* bitpos */
243 complain_overflow_bitfield,/* complain_on_overflow */
244 bfd_elf_generic_reloc, /* special_function */
245 "R_MSP430_ABS32", /* name */
246 FALSE, /* partial_inplace */
247 0xffffffff, /* src_mask */
248 0xffffffff, /* dst_mask */
249 FALSE), /* pcrel_offset */
250
251 HOWTO (R_MSP430_ABS16, /* type */
252 0, /* rightshift */
253 1, /* size (0 = byte, 1 = short, 2 = long) */
254 16, /* bitsize */
255 FALSE, /* pc_relative */
256 0, /* bitpos */
257 complain_overflow_dont,/* complain_on_overflow */
258 bfd_elf_generic_reloc, /* special_function */
259 "R_MSP430_ABS16", /* name */
260 FALSE, /* partial_inplace */
261 0, /* src_mask */
262 0xffff, /* dst_mask */
263 FALSE), /* pcrel_offset */
264
265 HOWTO (R_MSP430_ABS8, /* type */
266 0, /* rightshift */
267 0, /* size (0 = byte, 1 = short, 2 = long) */
268 8, /* bitsize */
269 FALSE, /* pc_relative */
270 0, /* bitpos */
271 complain_overflow_bitfield,/* complain_on_overflow */
272 bfd_elf_generic_reloc, /* special_function */
273 "R_MSP430_ABS8", /* name */
274 FALSE, /* partial_inplace */
275 0xff, /* src_mask */
276 0xff, /* dst_mask */
277 FALSE), /* pcrel_offset */
278
279 HOWTO (R_MSP430_PCR16, /* type */
280 1, /* rightshift */
281 1, /* size (0 = byte, 1 = short, 2 = long) */
282 16, /* bitsize */
283 TRUE, /* pc_relative */
284 0, /* bitpos */
285 complain_overflow_dont,/* complain_on_overflow */
286 bfd_elf_generic_reloc, /* special_function */
287 "R_MSP430_PCR16", /* name */
288 FALSE, /* partial_inplace */
289 0, /* src_mask */
290 0xffff, /* dst_mask */
291 TRUE), /* pcrel_offset */
292
293 HOWTO (R_MSP430X_PCR20_EXT_SRC,/* type */
294 0, /* rightshift */
295 2, /* size (0 = byte, 1 = short, 2 = long) */
296 32, /* bitsize */
297 TRUE, /* pc_relative */
298 0, /* bitpos */
299 complain_overflow_dont,/* complain_on_overflow */
300 bfd_elf_generic_reloc, /* special_function */
301 "R_MSP430X_PCR20_EXT_SRC",/* name */
302 FALSE, /* partial_inplace */
303 0, /* src_mask */
304 0xffff, /* dst_mask */
305 TRUE), /* pcrel_offset */
306
307 HOWTO (R_MSP430X_PCR20_EXT_DST,/* type */
308 0, /* rightshift */
309 2, /* size (0 = byte, 1 = short, 2 = long) */
310 32, /* bitsize */
311 TRUE, /* pc_relative */
312 0, /* bitpos */
313 complain_overflow_dont,/* complain_on_overflow */
314 bfd_elf_generic_reloc, /* special_function */
315 "R_MSP430X_PCR20_EXT_DST",/* name */
316 FALSE, /* partial_inplace */
317 0, /* src_mask */
318 0xffff, /* dst_mask */
319 TRUE), /* pcrel_offset */
320
321 HOWTO (R_MSP430X_PCR20_EXT_ODST,/* type */
322 0, /* rightshift */
323 2, /* size (0 = byte, 1 = short, 2 = long) */
324 32, /* bitsize */
325 TRUE, /* pc_relative */
326 0, /* bitpos */
327 complain_overflow_dont,/* complain_on_overflow */
328 bfd_elf_generic_reloc, /* special_function */
329 "R_MSP430X_PCR20_EXT_ODST",/* name */
330 FALSE, /* partial_inplace */
331 0, /* src_mask */
332 0xffff, /* dst_mask */
333 TRUE), /* pcrel_offset */
334
335 HOWTO (R_MSP430X_ABS20_EXT_SRC,/* type */
336 0, /* rightshift */
337 2, /* size (0 = byte, 1 = short, 2 = long) */
338 32, /* bitsize */
339 TRUE, /* pc_relative */
340 0, /* bitpos */
341 complain_overflow_dont,/* complain_on_overflow */
342 bfd_elf_generic_reloc, /* special_function */
343 "R_MSP430X_ABS20_EXT_SRC",/* name */
344 FALSE, /* partial_inplace */
345 0, /* src_mask */
346 0xffff, /* dst_mask */
347 TRUE), /* pcrel_offset */
348
349 HOWTO (R_MSP430X_ABS20_EXT_DST,/* type */
350 0, /* rightshift */
351 2, /* size (0 = byte, 1 = short, 2 = long) */
352 32, /* bitsize */
353 TRUE, /* pc_relative */
354 0, /* bitpos */
355 complain_overflow_dont,/* complain_on_overflow */
356 bfd_elf_generic_reloc, /* special_function */
357 "R_MSP430X_ABS20_EXT_DST",/* name */
358 FALSE, /* partial_inplace */
359 0, /* src_mask */
360 0xffff, /* dst_mask */
361 TRUE), /* pcrel_offset */
362
363 HOWTO (R_MSP430X_ABS20_EXT_ODST,/* type */
364 0, /* rightshift */
365 2, /* size (0 = byte, 1 = short, 2 = long) */
366 32, /* bitsize */
367 TRUE, /* pc_relative */
368 0, /* bitpos */
369 complain_overflow_dont,/* complain_on_overflow */
370 bfd_elf_generic_reloc, /* special_function */
371 "R_MSP430X_ABS20_EXT_ODST",/* name */
372 FALSE, /* partial_inplace */
373 0, /* src_mask */
374 0xffff, /* dst_mask */
375 TRUE), /* pcrel_offset */
376
377 HOWTO (R_MSP430X_ABS20_ADR_SRC,/* type */
378 0, /* rightshift */
379 2, /* size (0 = byte, 1 = short, 2 = long) */
380 32, /* bitsize */
381 TRUE, /* pc_relative */
382 0, /* bitpos */
383 complain_overflow_dont,/* complain_on_overflow */
384 bfd_elf_generic_reloc, /* special_function */
385 "R_MSP430X_ABS20_ADR_SRC",/* name */
386 FALSE, /* partial_inplace */
387 0, /* src_mask */
388 0xffff, /* dst_mask */
389 TRUE), /* pcrel_offset */
390
391 HOWTO (R_MSP430X_ABS20_ADR_DST,/* type */
392 0, /* rightshift */
393 2, /* size (0 = byte, 1 = short, 2 = long) */
394 32, /* bitsize */
395 TRUE, /* pc_relative */
396 0, /* bitpos */
397 complain_overflow_dont,/* complain_on_overflow */
398 bfd_elf_generic_reloc, /* special_function */
399 "R_MSP430X_ABS20_ADR_DST",/* name */
400 FALSE, /* partial_inplace */
401 0, /* src_mask */
402 0xffff, /* dst_mask */
403 TRUE), /* pcrel_offset */
404
405 HOWTO (R_MSP430X_PCR16, /* type */
406 0, /* rightshift */
407 2, /* size (0 = byte, 1 = short, 2 = long) */
408 32, /* bitsize */
409 TRUE, /* pc_relative */
410 0, /* bitpos */
411 complain_overflow_dont,/* complain_on_overflow */
412 bfd_elf_generic_reloc, /* special_function */
413 "R_MSP430X_PCR16", /* name */
414 FALSE, /* partial_inplace */
415 0, /* src_mask */
416 0xffff, /* dst_mask */
417 TRUE), /* pcrel_offset */
418
419 HOWTO (R_MSP430X_PCR20_CALL, /* type */
420 0, /* rightshift */
421 2, /* size (0 = byte, 1 = short, 2 = long) */
422 32, /* bitsize */
423 TRUE, /* pc_relative */
424 0, /* bitpos */
425 complain_overflow_dont,/* complain_on_overflow */
426 bfd_elf_generic_reloc, /* special_function */
427 "R_MSP430X_PCR20_CALL",/* name */
428 FALSE, /* partial_inplace */
429 0, /* src_mask */
430 0xffff, /* dst_mask */
431 TRUE), /* pcrel_offset */
432
433 HOWTO (R_MSP430X_ABS16, /* type */
434 0, /* rightshift */
435 2, /* size (0 = byte, 1 = short, 2 = long) */
436 32, /* bitsize */
437 TRUE, /* pc_relative */
438 0, /* bitpos */
439 complain_overflow_dont,/* complain_on_overflow */
440 bfd_elf_generic_reloc, /* special_function */
441 "R_MSP430X_ABS16", /* name */
442 FALSE, /* partial_inplace */
443 0, /* src_mask */
444 0xffff, /* dst_mask */
445 TRUE), /* pcrel_offset */
446
447 HOWTO (R_MSP430_ABS_HI16, /* type */
448 0, /* rightshift */
449 2, /* size (0 = byte, 1 = short, 2 = long) */
450 32, /* bitsize */
451 TRUE, /* pc_relative */
452 0, /* bitpos */
453 complain_overflow_dont,/* complain_on_overflow */
454 bfd_elf_generic_reloc, /* special_function */
455 "R_MSP430_ABS_HI16", /* name */
456 FALSE, /* partial_inplace */
457 0, /* src_mask */
458 0xffff, /* dst_mask */
459 TRUE), /* pcrel_offset */
460
461 HOWTO (R_MSP430_PREL31, /* type */
462 0, /* rightshift */
463 2, /* size (0 = byte, 1 = short, 2 = long) */
464 32, /* bitsize */
465 TRUE, /* pc_relative */
466 0, /* bitpos */
467 complain_overflow_dont,/* complain_on_overflow */
468 bfd_elf_generic_reloc, /* special_function */
469 "R_MSP430_PREL31", /* name */
470 FALSE, /* partial_inplace */
471 0, /* src_mask */
472 0xffff, /* dst_mask */
07d6d2b8 473 TRUE), /* pcrel_offset */
13761a11
NC
474
475 EMPTY_HOWTO (R_MSP430_EHTYPE),
1b786873 476
df301bfc 477 /* A 10 bit PC relative relocation. */
13761a11
NC
478 HOWTO (R_MSP430X_10_PCREL, /* type */
479 1, /* rightshift */
480 1, /* size (0 = byte, 1 = short, 2 = long) */
481 10, /* bitsize */
482 TRUE, /* pc_relative */
483 0, /* bitpos */
484 complain_overflow_bitfield,/* complain_on_overflow */
485 bfd_elf_generic_reloc, /* special_function */
486 "R_MSP430X_10_PCREL", /* name */
487 FALSE, /* partial_inplace */
df301bfc
NC
488 0x3ff, /* src_mask */
489 0x3ff, /* dst_mask */
07d6d2b8 490 TRUE), /* pcrel_offset */
13761a11 491
df301bfc 492 /* A 10 bit PC relative relocation for complicated polymorphs. */
13761a11
NC
493 HOWTO (R_MSP430X_2X_PCREL, /* type */
494 1, /* rightshift */
495 2, /* size (0 = byte, 1 = short, 2 = long) */
496 10, /* bitsize */
497 TRUE, /* pc_relative */
498 0, /* bitpos */
499 complain_overflow_bitfield,/* complain_on_overflow */
500 bfd_elf_generic_reloc, /* special_function */
501 "R_MSP430X_2X_PCREL", /* name */
502 FALSE, /* partial_inplace */
df301bfc
NC
503 0x3ff, /* src_mask */
504 0x3ff, /* dst_mask */
13761a11
NC
505 TRUE), /* pcrel_offset */
506
507 /* Together with a following reloc, allows for the difference
508 between two symbols to be the real addend of the second reloc. */
509 HOWTO (R_MSP430X_SYM_DIFF, /* type */
510 0, /* rightshift */
511 2, /* size (0 = byte, 1 = short, 2 = long) */
512 32, /* bitsize */
513 FALSE, /* pc_relative */
514 0, /* bitpos */
515 complain_overflow_dont,/* complain_on_overflow */
1ade7175 516 rl78_sym_diff_handler, /* special handler. */
13761a11
NC
517 "R_MSP430X_SYM_DIFF", /* name */
518 FALSE, /* partial_inplace */
519 0xffffffff, /* src_mask */
520 0xffffffff, /* dst_mask */
1b786873 521 FALSE) /* pcrel_offset */
2469cfa2
NC
522};
523
524/* Map BFD reloc types to MSP430 ELF reloc types. */
525
526struct msp430_reloc_map
527{
528 bfd_reloc_code_real_type bfd_reloc_val;
529 unsigned int elf_reloc_val;
530};
531
532static const struct msp430_reloc_map msp430_reloc_map[] =
13761a11 533{
07d6d2b8
AM
534 {BFD_RELOC_NONE, R_MSP430_NONE},
535 {BFD_RELOC_32, R_MSP430_32},
536 {BFD_RELOC_MSP430_10_PCREL, R_MSP430_10_PCREL},
537 {BFD_RELOC_16, R_MSP430_16_BYTE},
538 {BFD_RELOC_MSP430_16_PCREL, R_MSP430_16_PCREL},
539 {BFD_RELOC_MSP430_16, R_MSP430_16},
13761a11 540 {BFD_RELOC_MSP430_16_PCREL_BYTE, R_MSP430_16_PCREL_BYTE},
07d6d2b8
AM
541 {BFD_RELOC_MSP430_16_BYTE, R_MSP430_16_BYTE},
542 {BFD_RELOC_MSP430_2X_PCREL, R_MSP430_2X_PCREL},
543 {BFD_RELOC_MSP430_RL_PCREL, R_MSP430_RL_PCREL},
544 {BFD_RELOC_8, R_MSP430_8},
545 {BFD_RELOC_MSP430_SYM_DIFF, R_MSP430_SYM_DIFF}
13761a11
NC
546};
547
548static const struct msp430_reloc_map msp430x_reloc_map[] =
549{
07d6d2b8
AM
550 {BFD_RELOC_NONE, R_MSP430_NONE},
551 {BFD_RELOC_32, R_MSP430_ABS32},
552 {BFD_RELOC_16, R_MSP430_ABS16},
553 {BFD_RELOC_8, R_MSP430_ABS8},
554 {BFD_RELOC_MSP430_ABS8, R_MSP430_ABS8},
13761a11
NC
555 {BFD_RELOC_MSP430X_PCR20_EXT_SRC, R_MSP430X_PCR20_EXT_SRC},
556 {BFD_RELOC_MSP430X_PCR20_EXT_DST, R_MSP430X_PCR20_EXT_DST},
557 {BFD_RELOC_MSP430X_PCR20_EXT_ODST, R_MSP430X_PCR20_EXT_ODST},
558 {BFD_RELOC_MSP430X_ABS20_EXT_SRC, R_MSP430X_ABS20_EXT_SRC},
559 {BFD_RELOC_MSP430X_ABS20_EXT_DST, R_MSP430X_ABS20_EXT_DST},
560 {BFD_RELOC_MSP430X_ABS20_EXT_ODST, R_MSP430X_ABS20_EXT_ODST},
561 {BFD_RELOC_MSP430X_ABS20_ADR_SRC, R_MSP430X_ABS20_ADR_SRC},
562 {BFD_RELOC_MSP430X_ABS20_ADR_DST, R_MSP430X_ABS20_ADR_DST},
07d6d2b8 563 {BFD_RELOC_MSP430X_PCR16, R_MSP430X_PCR16},
13761a11 564 {BFD_RELOC_MSP430X_PCR20_CALL, R_MSP430X_PCR20_CALL},
07d6d2b8
AM
565 {BFD_RELOC_MSP430X_ABS16, R_MSP430X_ABS16},
566 {BFD_RELOC_MSP430_ABS_HI16, R_MSP430_ABS_HI16},
567 {BFD_RELOC_MSP430_PREL31, R_MSP430_PREL31},
568 {BFD_RELOC_MSP430_10_PCREL, R_MSP430X_10_PCREL},
569 {BFD_RELOC_MSP430_2X_PCREL, R_MSP430X_2X_PCREL},
570 {BFD_RELOC_MSP430_RL_PCREL, R_MSP430X_PCR16},
571 {BFD_RELOC_MSP430_SYM_DIFF, R_MSP430X_SYM_DIFF}
13761a11
NC
572};
573
574static inline bfd_boolean
575uses_msp430x_relocs (bfd * abfd)
576{
6d00b590 577 extern const bfd_target msp430_elf32_ti_vec;
13761a11
NC
578
579 return bfd_get_mach (abfd) == bfd_mach_msp430x
6d00b590 580 || abfd->xvec == & msp430_elf32_ti_vec;
13761a11 581}
2469cfa2
NC
582
583static reloc_howto_type *
b18c562e
NC
584bfd_elf32_bfd_reloc_type_lookup (bfd * abfd ATTRIBUTE_UNUSED,
585 bfd_reloc_code_real_type code)
2469cfa2
NC
586{
587 unsigned int i;
588
13761a11
NC
589 if (uses_msp430x_relocs (abfd))
590 {
591 for (i = ARRAY_SIZE (msp430x_reloc_map); i--;)
592 if (msp430x_reloc_map[i].bfd_reloc_val == code)
593 return elf_msp430x_howto_table + msp430x_reloc_map[i].elf_reloc_val;
594 }
595 else
596 {
597 for (i = 0; i < ARRAY_SIZE (msp430_reloc_map); i++)
598 if (msp430_reloc_map[i].bfd_reloc_val == code)
599 return &elf_msp430_howto_table[msp430_reloc_map[i].elf_reloc_val];
600 }
2469cfa2
NC
601
602 return NULL;
603}
604
157090f7
AM
605static reloc_howto_type *
606bfd_elf32_bfd_reloc_name_lookup (bfd *abfd ATTRIBUTE_UNUSED,
607 const char *r_name)
608{
609 unsigned int i;
610
13761a11
NC
611 if (uses_msp430x_relocs (abfd))
612 {
613 for (i = ARRAY_SIZE (elf_msp430x_howto_table); i--;)
614 if (elf_msp430x_howto_table[i].name != NULL
615 && strcasecmp (elf_msp430x_howto_table[i].name, r_name) == 0)
616 return elf_msp430x_howto_table + i;
617 }
618 else
619 {
620 for (i = 0;
621 i < (sizeof (elf_msp430_howto_table)
622 / sizeof (elf_msp430_howto_table[0]));
623 i++)
624 if (elf_msp430_howto_table[i].name != NULL
625 && strcasecmp (elf_msp430_howto_table[i].name, r_name) == 0)
626 return &elf_msp430_howto_table[i];
627 }
157090f7
AM
628
629 return NULL;
630}
631
2469cfa2
NC
632/* Set the howto pointer for an MSP430 ELF reloc. */
633
634static void
b18c562e
NC
635msp430_info_to_howto_rela (bfd * abfd ATTRIBUTE_UNUSED,
636 arelent * cache_ptr,
637 Elf_Internal_Rela * dst)
2469cfa2
NC
638{
639 unsigned int r_type;
640
641 r_type = ELF32_R_TYPE (dst->r_info);
13761a11
NC
642
643 if (uses_msp430x_relocs (abfd))
644 {
5860e3f8
NC
645 if (r_type >= (unsigned int) R_MSP430x_max)
646 {
695344c0 647 /* xgettext:c-format */
64d29018 648 _bfd_error_handler (_("%B: invalid MSP430X reloc number: %d"), abfd, r_type);
5860e3f8
NC
649 r_type = 0;
650 }
13761a11
NC
651 cache_ptr->howto = elf_msp430x_howto_table + r_type;
652 return;
653 }
654
5860e3f8
NC
655 if (r_type >= (unsigned int) R_MSP430_max)
656 {
695344c0 657 /* xgettext:c-format */
64d29018 658 _bfd_error_handler (_("%B: invalid MSP430 reloc number: %d"), abfd, r_type);
5860e3f8
NC
659 r_type = 0;
660 }
2469cfa2
NC
661 cache_ptr->howto = &elf_msp430_howto_table[r_type];
662}
663
2469cfa2
NC
664/* Look through the relocs for a section during the first phase.
665 Since we don't do .gots or .plts, we just need to consider the
666 virtual table relocs for gc. */
667
668static bfd_boolean
b18c562e
NC
669elf32_msp430_check_relocs (bfd * abfd, struct bfd_link_info * info,
670 asection * sec, const Elf_Internal_Rela * relocs)
2469cfa2
NC
671{
672 Elf_Internal_Shdr *symtab_hdr;
5582a088 673 struct elf_link_hash_entry **sym_hashes;
2469cfa2
NC
674 const Elf_Internal_Rela *rel;
675 const Elf_Internal_Rela *rel_end;
676
0e1862bb 677 if (bfd_link_relocatable (info))
2469cfa2
NC
678 return TRUE;
679
680 symtab_hdr = &elf_tdata (abfd)->symtab_hdr;
681 sym_hashes = elf_sym_hashes (abfd);
2469cfa2
NC
682
683 rel_end = relocs + sec->reloc_count;
684 for (rel = relocs; rel < rel_end; rel++)
685 {
686 struct elf_link_hash_entry *h;
687 unsigned long r_symndx;
688
689 r_symndx = ELF32_R_SYM (rel->r_info);
690 if (r_symndx < symtab_hdr->sh_info)
691 h = NULL;
692 else
973a3492
L
693 {
694 h = sym_hashes[r_symndx - symtab_hdr->sh_info];
695 while (h->root.type == bfd_link_hash_indirect
696 || h->root.type == bfd_link_hash_warning)
697 h = (struct elf_link_hash_entry *) h->root.u.i.link;
698 }
2469cfa2
NC
699 }
700
701 return TRUE;
702}
703
704/* Perform a single relocation. By default we use the standard BFD
705 routines, but a few relocs, we have to do them ourselves. */
706
707static bfd_reloc_status_type
07d6d2b8
AM
708msp430_final_link_relocate (reloc_howto_type * howto,
709 bfd * input_bfd,
710 asection * input_section,
711 bfd_byte * contents,
712 Elf_Internal_Rela * rel,
713 bfd_vma relocation,
13761a11 714 struct bfd_link_info * info)
2469cfa2 715{
13761a11
NC
716 static asection * sym_diff_section;
717 static bfd_vma sym_diff_value;
718
719 struct bfd_elf_section_data * esd = elf_section_data (input_section);
2469cfa2
NC
720 bfd_reloc_status_type r = bfd_reloc_ok;
721 bfd_vma x;
722 bfd_signed_vma srel;
13761a11
NC
723 bfd_boolean is_rel_reloc = FALSE;
724
725 if (uses_msp430x_relocs (input_bfd))
726 {
727 /* See if we have a REL type relocation. */
728 is_rel_reloc = (esd->rel.hdr != NULL);
729 /* Sanity check - only one type of relocation per section.
730 FIXME: Theoretically it is possible to have both types,
731 but if that happens how can we distinguish between the two ? */
732 BFD_ASSERT (! is_rel_reloc || ! esd->rela.hdr);
733 /* If we are using a REL relocation then the addend should be empty. */
734 BFD_ASSERT (! is_rel_reloc || rel->r_addend == 0);
735 }
2469cfa2 736
13761a11 737 if (sym_diff_section != NULL)
2469cfa2 738 {
13761a11 739 BFD_ASSERT (sym_diff_section == input_section);
1b786873 740
13761a11
NC
741 if (uses_msp430x_relocs (input_bfd))
742 switch (howto->type)
743 {
744 case R_MSP430_ABS32:
745 /* If we are computing a 32-bit value for the location lists
746 and the result is 0 then we add one to the value. A zero
747 value can result because of linker relaxation deleteing
748 prologue instructions and using a value of 1 (for the begin
749 and end offsets in the location list entry) results in a
750 nul entry which does not prevent the following entries from
751 being parsed. */
752 if (relocation == sym_diff_value
753 && strcmp (input_section->name, ".debug_loc") == 0)
754 ++ relocation;
755 /* Fall through. */
756 case R_MSP430_ABS16:
757 case R_MSP430X_ABS16:
758 case R_MSP430_ABS8:
759 BFD_ASSERT (! is_rel_reloc);
760 relocation -= sym_diff_value;
761 break;
762
763 default:
764 return bfd_reloc_dangerous;
765 }
766 else
767 switch (howto->type)
768 {
769 case R_MSP430_32:
770 case R_MSP430_16:
771 case R_MSP430_16_BYTE:
772 case R_MSP430_8:
773 relocation -= sym_diff_value;
774 break;
775
776 default:
777 return bfd_reloc_dangerous;
778 }
1b786873 779
13761a11
NC
780 sym_diff_section = NULL;
781 }
782
783 if (uses_msp430x_relocs (input_bfd))
784 switch (howto->type)
785 {
786 case R_MSP430X_SYM_DIFF:
787 /* Cache the input section and value.
788 The offset is unreliable, since relaxation may
789 have reduced the following reloc's offset. */
790 BFD_ASSERT (! is_rel_reloc);
791 sym_diff_section = input_section;
792 sym_diff_value = relocation;
793 return bfd_reloc_ok;
794
795 case R_MSP430_ABS16:
796 contents += rel->r_offset;
797 srel = (bfd_signed_vma) relocation;
798 if (is_rel_reloc)
799 srel += bfd_get_16 (input_bfd, contents);
800 else
801 srel += rel->r_addend;
802 bfd_put_16 (input_bfd, srel & 0xffff, contents);
803 break;
804
805 case R_MSP430X_10_PCREL:
806 contents += rel->r_offset;
807 srel = (bfd_signed_vma) relocation;
808 if (is_rel_reloc)
809 srel += bfd_get_16 (input_bfd, contents) & 0x3ff;
810 else
811 srel += rel->r_addend;
812 srel -= rel->r_offset;
813 srel -= 2; /* Branch instructions add 2 to the PC... */
814 srel -= (input_section->output_section->vma +
815 input_section->output_offset);
816 if (srel & 1)
817 return bfd_reloc_outofrange;
818
819 /* MSP430 addresses commands as words. */
820 srel >>= 1;
821
822 /* Check for an overflow. */
823 if (srel < -512 || srel > 511)
824 {
825 if (info->disable_target_specific_optimizations < 0)
826 {
827 static bfd_boolean warned = FALSE;
828 if (! warned)
829 {
830 info->callbacks->warning
831 (info,
832 _("Try enabling relaxation to avoid relocation truncations"),
833 NULL, input_bfd, input_section, relocation);
834 warned = TRUE;
835 }
836 }
837 return bfd_reloc_overflow;
838 }
839
840 x = bfd_get_16 (input_bfd, contents);
841 x = (x & 0xfc00) | (srel & 0x3ff);
842 bfd_put_16 (input_bfd, x, contents);
843 break;
844
845 case R_MSP430X_PCR20_EXT_ODST:
3f307074 846 /* [0,4]+[48,16] = ---F ---- ---- FFFF */
13761a11
NC
847 contents += rel->r_offset;
848 srel = (bfd_signed_vma) relocation;
849 if (is_rel_reloc)
850 {
851 bfd_vma addend;
852 addend = (bfd_get_16 (input_bfd, contents) & 0xf) << 16;
3f307074 853 addend |= bfd_get_16 (input_bfd, contents + 6);
13761a11 854 srel += addend;
1b786873 855
13761a11
NC
856 }
857 else
858 srel += rel->r_addend;
859 srel -= rel->r_offset;
860 srel -= (input_section->output_section->vma +
861 input_section->output_offset);
862 bfd_put_16 (input_bfd, (srel & 0xffff), contents + 6);
863 x = bfd_get_16 (input_bfd, contents);
864 x = (x & 0xfff0) | ((srel >> 16) & 0xf);
865 bfd_put_16 (input_bfd, x, contents);
866 break;
867
868 case R_MSP430X_ABS20_EXT_SRC:
3f307074 869 /* [7,4]+[32,16] = -78- ---- FFFF */
13761a11
NC
870 contents += rel->r_offset;
871 srel = (bfd_signed_vma) relocation;
872 if (is_rel_reloc)
873 {
874 bfd_vma addend;
875 addend = (bfd_get_16 (input_bfd, contents) & 0x0780) << 9;
3f307074 876 addend |= bfd_get_16 (input_bfd, contents + 4);
13761a11
NC
877 srel += addend;
878 }
879 else
880 srel += rel->r_addend;
881 bfd_put_16 (input_bfd, (srel & 0xffff), contents + 4);
882 srel >>= 16;
883 x = bfd_get_16 (input_bfd, contents);
884 x = (x & 0xf87f) | ((srel << 7) & 0x0780);
885 bfd_put_16 (input_bfd, x, contents);
886 break;
887
888 case R_MSP430_16_PCREL:
889 contents += rel->r_offset;
890 srel = (bfd_signed_vma) relocation;
891 if (is_rel_reloc)
892 srel += bfd_get_16 (input_bfd, contents);
893 else
894 srel += rel->r_addend;
895 srel -= rel->r_offset;
896 /* Only branch instructions add 2 to the PC... */
897 srel -= (input_section->output_section->vma +
898 input_section->output_offset);
899 if (srel & 1)
900 return bfd_reloc_outofrange;
901 bfd_put_16 (input_bfd, srel & 0xffff, contents);
902 break;
903
904 case R_MSP430X_PCR20_EXT_DST:
3f307074 905 /* [0,4]+[32,16] = ---F ---- FFFF */
13761a11
NC
906 contents += rel->r_offset;
907 srel = (bfd_signed_vma) relocation;
908 if (is_rel_reloc)
909 {
910 bfd_vma addend;
911 addend = (bfd_get_16 (input_bfd, contents) & 0xf) << 16;
3f307074 912 addend |= bfd_get_16 (input_bfd, contents + 4);
13761a11
NC
913 srel += addend;
914 }
915 else
916 srel += rel->r_addend;
917 srel -= rel->r_offset;
918 srel -= (input_section->output_section->vma +
919 input_section->output_offset);
920 bfd_put_16 (input_bfd, (srel & 0xffff), contents + 4);
921 srel >>= 16;
922 x = bfd_get_16 (input_bfd, contents);
923 x = (x & 0xfff0) | (srel & 0xf);
924 bfd_put_16 (input_bfd, x, contents);
925 break;
926
927 case R_MSP430X_PCR20_EXT_SRC:
3f307074 928 /* [7,4]+[32,16] = -78- ---- FFFF */
13761a11
NC
929 contents += rel->r_offset;
930 srel = (bfd_signed_vma) relocation;
931 if (is_rel_reloc)
932 {
933 bfd_vma addend;
934 addend = ((bfd_get_16 (input_bfd, contents) & 0x0780) << 9);
3f307074 935 addend |= bfd_get_16 (input_bfd, contents + 4);
13761a11
NC
936 srel += addend;;
937 }
938 else
939 srel += rel->r_addend;
940 srel -= rel->r_offset;
941 /* Only branch instructions add 2 to the PC... */
942 srel -= (input_section->output_section->vma +
943 input_section->output_offset);
944 bfd_put_16 (input_bfd, (srel & 0xffff), contents + 4);
945 srel >>= 16;
946 x = bfd_get_16 (input_bfd, contents);
947 x = (x & 0xf87f) | ((srel << 7) & 0x0780);
948 bfd_put_16 (input_bfd, x, contents);
949 break;
950
951 case R_MSP430_ABS8:
952 contents += rel->r_offset;
953 srel = (bfd_signed_vma) relocation;
954 if (is_rel_reloc)
955 srel += bfd_get_8 (input_bfd, contents);
956 else
957 srel += rel->r_addend;
958 bfd_put_8 (input_bfd, srel & 0xff, contents);
959 break;
960
961 case R_MSP430X_ABS20_EXT_DST:
3f307074 962 /* [0,4]+[32,16] = ---F ---- FFFF */
13761a11
NC
963 contents += rel->r_offset;
964 srel = (bfd_signed_vma) relocation;
965 if (is_rel_reloc)
3f307074
DD
966 {
967 bfd_vma addend;
968 addend = (bfd_get_16 (input_bfd, contents) & 0xf) << 16;
969 addend |= bfd_get_16 (input_bfd, contents + 4);
970 srel += addend;
971 }
13761a11
NC
972 else
973 srel += rel->r_addend;
974 bfd_put_16 (input_bfd, (srel & 0xffff), contents + 4);
975 srel >>= 16;
976 x = bfd_get_16 (input_bfd, contents);
977 x = (x & 0xfff0) | (srel & 0xf);
978 bfd_put_16 (input_bfd, x, contents);
979 break;
980
981 case R_MSP430X_ABS20_EXT_ODST:
3f307074 982 /* [0,4]+[48,16] = ---F ---- ---- FFFF */
13761a11
NC
983 contents += rel->r_offset;
984 srel = (bfd_signed_vma) relocation;
985 if (is_rel_reloc)
986 {
987 bfd_vma addend;
988 addend = (bfd_get_16 (input_bfd, contents) & 0xf) << 16;
3f307074 989 addend |= bfd_get_16 (input_bfd, contents + 6);
13761a11
NC
990 srel += addend;
991 }
992 else
993 srel += rel->r_addend;
994 bfd_put_16 (input_bfd, (srel & 0xffff), contents + 6);
995 srel >>= 16;
996 x = bfd_get_16 (input_bfd, contents);
997 x = (x & 0xfff0) | (srel & 0xf);
998 bfd_put_16 (input_bfd, x, contents);
999 break;
1000
1001 case R_MSP430X_ABS20_ADR_SRC:
3f307074 1002 /* [8,4]+[16,16] = -F-- FFFF */
13761a11
NC
1003 contents += rel->r_offset;
1004 srel = (bfd_signed_vma) relocation;
1005 if (is_rel_reloc)
1006 {
1007 bfd_vma addend;
1008
1009 addend = ((bfd_get_16 (input_bfd, contents) & 0xf00) << 8);
3f307074 1010 addend |= bfd_get_16 (input_bfd, contents + 2);
13761a11
NC
1011 srel += addend;
1012 }
1013 else
1014 srel += rel->r_addend;
1015 bfd_put_16 (input_bfd, (srel & 0xffff), contents + 2);
1016 srel >>= 16;
1017 x = bfd_get_16 (input_bfd, contents);
1018 x = (x & 0xf0ff) | ((srel << 8) & 0x0f00);
1019 bfd_put_16 (input_bfd, x, contents);
1020 break;
1021
1022 case R_MSP430X_ABS20_ADR_DST:
3f307074 1023 /* [0,4]+[16,16] = ---F FFFF */
13761a11
NC
1024 contents += rel->r_offset;
1025 srel = (bfd_signed_vma) relocation;
1026 if (is_rel_reloc)
1027 {
1028 bfd_vma addend;
1029 addend = ((bfd_get_16 (input_bfd, contents) & 0xf) << 16);
3f307074 1030 addend |= bfd_get_16 (input_bfd, contents + 2);
13761a11
NC
1031 srel += addend;
1032 }
1033 else
1034 srel += rel->r_addend;
1035 bfd_put_16 (input_bfd, (srel & 0xffff), contents + 2);
1036 srel >>= 16;
1037 x = bfd_get_16 (input_bfd, contents);
1038 x = (x & 0xfff0) | (srel & 0xf);
1039 bfd_put_16 (input_bfd, x, contents);
1040 break;
1041
1042 case R_MSP430X_ABS16:
1043 contents += rel->r_offset;
1044 srel = (bfd_signed_vma) relocation;
1045 if (is_rel_reloc)
1046 srel += bfd_get_16 (input_bfd, contents);
1047 else
1048 srel += rel->r_addend;
1049 x = srel;
1050 if (x > 0xffff)
1b786873 1051 return bfd_reloc_overflow;
13761a11
NC
1052 bfd_put_16 (input_bfd, srel & 0xffff, contents);
1053 break;
1054
1055 case R_MSP430_ABS_HI16:
1056 /* The EABI specifies that this must be a RELA reloc. */
1057 BFD_ASSERT (! is_rel_reloc);
1058 contents += rel->r_offset;
1059 srel = (bfd_signed_vma) relocation;
1060 srel += rel->r_addend;
1061 bfd_put_16 (input_bfd, (srel >> 16) & 0xffff, contents);
1062 break;
1b786873 1063
13761a11 1064 case R_MSP430X_PCR20_CALL:
3f307074 1065 /* [0,4]+[16,16] = ---F FFFF*/
13761a11
NC
1066 contents += rel->r_offset;
1067 srel = (bfd_signed_vma) relocation;
1068 if (is_rel_reloc)
1069 {
1070 bfd_vma addend;
1071 addend = (bfd_get_16 (input_bfd, contents) & 0xf) << 16;
3f307074 1072 addend |= bfd_get_16 (input_bfd, contents + 2);
13761a11
NC
1073 srel += addend;
1074 }
1075 else
1076 srel += rel->r_addend;
1077 srel -= rel->r_offset;
1078 srel -= (input_section->output_section->vma +
1079 input_section->output_offset);
1080 bfd_put_16 (input_bfd, srel & 0xffff, contents + 2);
1081 srel >>= 16;
1082 x = bfd_get_16 (input_bfd, contents);
1083 x = (x & 0xfff0) | (srel & 0xf);
1084 bfd_put_16 (input_bfd, x, contents);
1085 break;
1b786873 1086
13761a11
NC
1087 case R_MSP430X_PCR16:
1088 contents += rel->r_offset;
1089 srel = (bfd_signed_vma) relocation;
1090 if (is_rel_reloc)
1091 srel += bfd_get_16 (input_bfd, contents);
1092 else
1093 srel += rel->r_addend;
1094 srel -= rel->r_offset;
1095 srel -= (input_section->output_section->vma +
1096 input_section->output_offset);
1097 bfd_put_16 (input_bfd, srel & 0xffff, contents);
1098 break;
1b786873 1099
13761a11
NC
1100 case R_MSP430_PREL31:
1101 contents += rel->r_offset;
1102 srel = (bfd_signed_vma) relocation;
1103 if (is_rel_reloc)
1104 srel += (bfd_get_32 (input_bfd, contents) & 0x7fffffff);
1105 else
1106 srel += rel->r_addend;
1107 srel += rel->r_addend;
1108 x = bfd_get_32 (input_bfd, contents);
1109 x = (x & 0x80000000) | ((srel >> 31) & 0x7fffffff);
1110 bfd_put_32 (input_bfd, x, contents);
1111 break;
1b786873 1112
13761a11
NC
1113 default:
1114 r = _bfd_final_link_relocate (howto, input_bfd, input_section,
1115 contents, rel->r_offset,
1116 relocation, rel->r_addend);
1117 }
1118 else
1119 switch (howto->type)
1120 {
2469cfa2
NC
1121 case R_MSP430_10_PCREL:
1122 contents += rel->r_offset;
1123 srel = (bfd_signed_vma) relocation;
1124 srel += rel->r_addend;
1125 srel -= rel->r_offset;
1126 srel -= 2; /* Branch instructions add 2 to the PC... */
1127 srel -= (input_section->output_section->vma +
1128 input_section->output_offset);
1129
1130 if (srel & 1)
1131 return bfd_reloc_outofrange;
1132
1133 /* MSP430 addresses commands as words. */
1134 srel >>= 1;
1135
1136 /* Check for an overflow. */
1137 if (srel < -512 || srel > 511)
13761a11
NC
1138 {
1139 if (info->disable_target_specific_optimizations < 0)
1140 {
1141 static bfd_boolean warned = FALSE;
1142 if (! warned)
1143 {
1144 info->callbacks->warning
1145 (info,
1146 _("Try enabling relaxation to avoid relocation truncations"),
1147 NULL, input_bfd, input_section, relocation);
1148 warned = TRUE;
1149 }
1150 }
1151 return bfd_reloc_overflow;
1152 }
1b786873 1153
2469cfa2
NC
1154 x = bfd_get_16 (input_bfd, contents);
1155 x = (x & 0xfc00) | (srel & 0x3ff);
1156 bfd_put_16 (input_bfd, x, contents);
1157 break;
1158
b18c562e
NC
1159 case R_MSP430_2X_PCREL:
1160 contents += rel->r_offset;
1161 srel = (bfd_signed_vma) relocation;
1162 srel += rel->r_addend;
1163 srel -= rel->r_offset;
1164 srel -= 2; /* Branch instructions add 2 to the PC... */
1165 srel -= (input_section->output_section->vma +
1166 input_section->output_offset);
1167
1168 if (srel & 1)
1169 return bfd_reloc_outofrange;
1170
1171 /* MSP430 addresses commands as words. */
1172 srel >>= 1;
1173
1174 /* Check for an overflow. */
1175 if (srel < -512 || srel > 511)
1176 return bfd_reloc_overflow;
1177
1178 x = bfd_get_16 (input_bfd, contents);
1179 x = (x & 0xfc00) | (srel & 0x3ff);
1180 bfd_put_16 (input_bfd, x, contents);
1181 /* Handle second jump instruction. */
1182 x = bfd_get_16 (input_bfd, contents - 2);
1183 srel += 1;
1184 x = (x & 0xfc00) | (srel & 0x3ff);
1185 bfd_put_16 (input_bfd, x, contents - 2);
1186 break;
1187
b18c562e 1188 case R_MSP430_RL_PCREL:
77bf820f 1189 case R_MSP430_16_PCREL:
2469cfa2
NC
1190 contents += rel->r_offset;
1191 srel = (bfd_signed_vma) relocation;
1192 srel += rel->r_addend;
1193 srel -= rel->r_offset;
1194 /* Only branch instructions add 2 to the PC... */
1195 srel -= (input_section->output_section->vma +
1196 input_section->output_offset);
1197
1198 if (srel & 1)
1199 return bfd_reloc_outofrange;
1200
1201 bfd_put_16 (input_bfd, srel & 0xffff, contents);
1202 break;
1203
1204 case R_MSP430_16_PCREL_BYTE:
1205 contents += rel->r_offset;
1206 srel = (bfd_signed_vma) relocation;
1207 srel += rel->r_addend;
1208 srel -= rel->r_offset;
1209 /* Only branch instructions add 2 to the PC... */
1210 srel -= (input_section->output_section->vma +
1211 input_section->output_offset);
1212
1213 bfd_put_16 (input_bfd, srel & 0xffff, contents);
1214 break;
1215
1216 case R_MSP430_16_BYTE:
1217 contents += rel->r_offset;
1218 srel = (bfd_signed_vma) relocation;
1219 srel += rel->r_addend;
1220 bfd_put_16 (input_bfd, srel & 0xffff, contents);
1221 break;
1222
1223 case R_MSP430_16:
1224 contents += rel->r_offset;
1225 srel = (bfd_signed_vma) relocation;
1226 srel += rel->r_addend;
1227
1228 if (srel & 1)
1229 return bfd_reloc_notsupported;
1230
1231 bfd_put_16 (input_bfd, srel & 0xffff, contents);
1232 break;
1233
13761a11
NC
1234 case R_MSP430_8:
1235 contents += rel->r_offset;
1236 srel = (bfd_signed_vma) relocation;
1237 srel += rel->r_addend;
1238
1239 bfd_put_8 (input_bfd, srel & 0xff, contents);
1240 break;
1b786873 1241
13761a11
NC
1242 case R_MSP430_SYM_DIFF:
1243 /* Cache the input section and value.
1244 The offset is unreliable, since relaxation may
1245 have reduced the following reloc's offset. */
1246 sym_diff_section = input_section;
1247 sym_diff_value = relocation;
1248 return bfd_reloc_ok;
1249
1250 default:
1251 r = _bfd_final_link_relocate (howto, input_bfd, input_section,
1252 contents, rel->r_offset,
1253 relocation, rel->r_addend);
1254 }
2469cfa2
NC
1255
1256 return r;
1257}
1258
1259/* Relocate an MSP430 ELF section. */
1260
1261static bfd_boolean
b18c562e
NC
1262elf32_msp430_relocate_section (bfd * output_bfd ATTRIBUTE_UNUSED,
1263 struct bfd_link_info * info,
1264 bfd * input_bfd,
1265 asection * input_section,
1266 bfd_byte * contents,
1267 Elf_Internal_Rela * relocs,
1268 Elf_Internal_Sym * local_syms,
1269 asection ** local_sections)
2469cfa2
NC
1270{
1271 Elf_Internal_Shdr *symtab_hdr;
1272 struct elf_link_hash_entry **sym_hashes;
1273 Elf_Internal_Rela *rel;
1274 Elf_Internal_Rela *relend;
1275
1276 symtab_hdr = &elf_tdata (input_bfd)->symtab_hdr;
1277 sym_hashes = elf_sym_hashes (input_bfd);
1278 relend = relocs + input_section->reloc_count;
1279
1280 for (rel = relocs; rel < relend; rel++)
1281 {
1282 reloc_howto_type *howto;
1283 unsigned long r_symndx;
1284 Elf_Internal_Sym *sym;
1285 asection *sec;
1286 struct elf_link_hash_entry *h;
1287 bfd_vma relocation;
1288 bfd_reloc_status_type r;
1289 const char *name = NULL;
1290 int r_type;
1291
2469cfa2
NC
1292 r_type = ELF32_R_TYPE (rel->r_info);
1293 r_symndx = ELF32_R_SYM (rel->r_info);
13761a11
NC
1294
1295 if (uses_msp430x_relocs (input_bfd))
1296 howto = elf_msp430x_howto_table + r_type;
1297 else
1298 howto = elf_msp430_howto_table + r_type;
1299
2469cfa2
NC
1300 h = NULL;
1301 sym = NULL;
1302 sec = NULL;
1303
1304 if (r_symndx < symtab_hdr->sh_info)
1305 {
1306 sym = local_syms + r_symndx;
1307 sec = local_sections[r_symndx];
8517fae7 1308 relocation = _bfd_elf_rela_local_sym (output_bfd, sym, &sec, rel);
2469cfa2
NC
1309
1310 name = bfd_elf_string_from_elf_section
1311 (input_bfd, symtab_hdr->sh_link, sym->st_name);
13761a11 1312 name = (name == NULL || * name == 0) ? bfd_section_name (input_bfd, sec) : name;
2469cfa2
NC
1313 }
1314 else
1315 {
62d887d4 1316 bfd_boolean unresolved_reloc, warned, ignored;
2469cfa2 1317
b2a8e766
AM
1318 RELOC_FOR_GLOBAL_SYMBOL (info, input_bfd, input_section, rel,
1319 r_symndx, symtab_hdr, sym_hashes,
1320 h, sec, relocation,
62d887d4 1321 unresolved_reloc, warned, ignored);
13761a11 1322 name = h->root.root.string;
2469cfa2
NC
1323 }
1324
dbaa2011 1325 if (sec != NULL && discarded_section (sec))
e4067dbb 1326 RELOC_AGAINST_DISCARDED_SECTION (info, input_bfd, input_section,
545fd46b 1327 rel, 1, relend, howto, 0, contents);
ab96bf03 1328
0e1862bb 1329 if (bfd_link_relocatable (info))
ab96bf03
AM
1330 continue;
1331
2469cfa2 1332 r = msp430_final_link_relocate (howto, input_bfd, input_section,
13761a11 1333 contents, rel, relocation, info);
2469cfa2
NC
1334
1335 if (r != bfd_reloc_ok)
1336 {
1337 const char *msg = (const char *) NULL;
1338
1339 switch (r)
1340 {
1341 case bfd_reloc_overflow:
1a72702b 1342 (*info->callbacks->reloc_overflow)
13761a11 1343 (info, (h ? &h->root : NULL), name, howto->name,
1a72702b 1344 (bfd_vma) 0, input_bfd, input_section, rel->r_offset);
2469cfa2
NC
1345 break;
1346
1347 case bfd_reloc_undefined:
1a72702b
AM
1348 (*info->callbacks->undefined_symbol)
1349 (info, name, input_bfd, input_section, rel->r_offset, TRUE);
2469cfa2
NC
1350 break;
1351
1352 case bfd_reloc_outofrange:
13761a11 1353 msg = _("internal error: branch/jump to an odd address detected");
2469cfa2
NC
1354 break;
1355
1356 case bfd_reloc_notsupported:
1357 msg = _("internal error: unsupported relocation error");
1358 break;
1359
1360 case bfd_reloc_dangerous:
1361 msg = _("internal error: dangerous relocation");
1362 break;
1363
1364 default:
1365 msg = _("internal error: unknown error");
1366 break;
1367 }
1368
1369 if (msg)
1a72702b
AM
1370 (*info->callbacks->warning) (info, msg, name, input_bfd,
1371 input_section, rel->r_offset);
2469cfa2
NC
1372 }
1373
1374 }
1375
1376 return TRUE;
1377}
1378
1379/* The final processing done just before writing out a MSP430 ELF object
1380 file. This gets the MSP430 architecture right based on the machine
1381 number. */
1382
1383static void
b18c562e
NC
1384bfd_elf_msp430_final_write_processing (bfd * abfd,
1385 bfd_boolean linker ATTRIBUTE_UNUSED)
2469cfa2
NC
1386{
1387 unsigned long val;
1388
1389 switch (bfd_get_mach (abfd))
1390 {
1391 default:
13761a11
NC
1392 case bfd_mach_msp110: val = E_MSP430_MACH_MSP430x11x1; break;
1393 case bfd_mach_msp11: val = E_MSP430_MACH_MSP430x11; break;
1394 case bfd_mach_msp12: val = E_MSP430_MACH_MSP430x12; break;
1395 case bfd_mach_msp13: val = E_MSP430_MACH_MSP430x13; break;
1396 case bfd_mach_msp14: val = E_MSP430_MACH_MSP430x14; break;
1397 case bfd_mach_msp15: val = E_MSP430_MACH_MSP430x15; break;
1398 case bfd_mach_msp16: val = E_MSP430_MACH_MSP430x16; break;
1399 case bfd_mach_msp31: val = E_MSP430_MACH_MSP430x31; break;
1400 case bfd_mach_msp32: val = E_MSP430_MACH_MSP430x32; break;
1401 case bfd_mach_msp33: val = E_MSP430_MACH_MSP430x33; break;
1402 case bfd_mach_msp41: val = E_MSP430_MACH_MSP430x41; break;
1403 case bfd_mach_msp42: val = E_MSP430_MACH_MSP430x42; break;
1404 case bfd_mach_msp43: val = E_MSP430_MACH_MSP430x43; break;
1405 case bfd_mach_msp44: val = E_MSP430_MACH_MSP430x44; break;
1406 case bfd_mach_msp20: val = E_MSP430_MACH_MSP430x20; break;
1407 case bfd_mach_msp22: val = E_MSP430_MACH_MSP430x22; break;
1408 case bfd_mach_msp23: val = E_MSP430_MACH_MSP430x23; break;
1409 case bfd_mach_msp24: val = E_MSP430_MACH_MSP430x24; break;
1410 case bfd_mach_msp26: val = E_MSP430_MACH_MSP430x26; break;
1411 case bfd_mach_msp46: val = E_MSP430_MACH_MSP430x46; break;
1412 case bfd_mach_msp47: val = E_MSP430_MACH_MSP430x47; break;
1413 case bfd_mach_msp54: val = E_MSP430_MACH_MSP430x54; break;
1414 case bfd_mach_msp430x: val = E_MSP430_MACH_MSP430X; break;
2469cfa2
NC
1415 }
1416
1417 elf_elfheader (abfd)->e_machine = EM_MSP430;
1418 elf_elfheader (abfd)->e_flags &= ~EF_MSP430_MACH;
1419 elf_elfheader (abfd)->e_flags |= val;
1420}
1421
1422/* Set the right machine number. */
1423
1424static bfd_boolean
b18c562e 1425elf32_msp430_object_p (bfd * abfd)
2469cfa2
NC
1426{
1427 int e_set = bfd_mach_msp14;
1428
1429 if (elf_elfheader (abfd)->e_machine == EM_MSP430
1430 || elf_elfheader (abfd)->e_machine == EM_MSP430_OLD)
1431 {
1432 int e_mach = elf_elfheader (abfd)->e_flags & EF_MSP430_MACH;
1433
1434 switch (e_mach)
1435 {
1436 default:
13761a11
NC
1437 case E_MSP430_MACH_MSP430x11: e_set = bfd_mach_msp11; break;
1438 case E_MSP430_MACH_MSP430x11x1: e_set = bfd_mach_msp110; break;
1439 case E_MSP430_MACH_MSP430x12: e_set = bfd_mach_msp12; break;
1440 case E_MSP430_MACH_MSP430x13: e_set = bfd_mach_msp13; break;
1441 case E_MSP430_MACH_MSP430x14: e_set = bfd_mach_msp14; break;
1442 case E_MSP430_MACH_MSP430x15: e_set = bfd_mach_msp15; break;
1443 case E_MSP430_MACH_MSP430x16: e_set = bfd_mach_msp16; break;
1444 case E_MSP430_MACH_MSP430x31: e_set = bfd_mach_msp31; break;
1445 case E_MSP430_MACH_MSP430x32: e_set = bfd_mach_msp32; break;
1446 case E_MSP430_MACH_MSP430x33: e_set = bfd_mach_msp33; break;
1447 case E_MSP430_MACH_MSP430x41: e_set = bfd_mach_msp41; break;
1448 case E_MSP430_MACH_MSP430x42: e_set = bfd_mach_msp42; break;
1449 case E_MSP430_MACH_MSP430x43: e_set = bfd_mach_msp43; break;
1450 case E_MSP430_MACH_MSP430x44: e_set = bfd_mach_msp44; break;
1451 case E_MSP430_MACH_MSP430x20: e_set = bfd_mach_msp20; break;
1452 case E_MSP430_MACH_MSP430x22: e_set = bfd_mach_msp22; break;
1453 case E_MSP430_MACH_MSP430x23: e_set = bfd_mach_msp23; break;
1454 case E_MSP430_MACH_MSP430x24: e_set = bfd_mach_msp24; break;
1455 case E_MSP430_MACH_MSP430x26: e_set = bfd_mach_msp26; break;
1456 case E_MSP430_MACH_MSP430x46: e_set = bfd_mach_msp46; break;
1457 case E_MSP430_MACH_MSP430x47: e_set = bfd_mach_msp47; break;
1458 case E_MSP430_MACH_MSP430x54: e_set = bfd_mach_msp54; break;
1459 case E_MSP430_MACH_MSP430X: e_set = bfd_mach_msp430x; break;
2469cfa2
NC
1460 }
1461 }
1b786873 1462
2469cfa2
NC
1463 return bfd_default_set_arch_mach (abfd, bfd_arch_msp430, e_set);
1464}
1465
b18c562e
NC
1466/* These functions handle relaxing for the msp430.
1467 Relaxation required only in two cases:
1468 - Bad hand coding like jumps from one section to another or
1469 from file to file.
77bf820f 1470 - Sibling calls. This will affect only 'jump label' polymorph. Without
b18c562e
NC
1471 relaxing this enlarges code by 2 bytes. Sibcalls implemented but
1472 do not work in gcc's port by the reason I do not know.
13761a11
NC
1473 - To convert out of range conditional jump instructions (found inside
1474 a function) into inverted jumps over an unconditional branch instruction.
b18c562e
NC
1475 Anyway, if a relaxation required, user should pass -relax option to the
1476 linker.
1477
1478 There are quite a few relaxing opportunities available on the msp430:
1479
1480 ================================================================
1481
1482 1. 3 words -> 1 word
1483
07d6d2b8
AM
1484 eq == jeq label jne +4; br lab
1485 ne != jne label jeq +4; br lab
1486 lt < jl label jge +4; br lab
1487 ltu < jlo label lhs +4; br lab
1488 ge >= jge label jl +4; br lab
1489 geu >= jhs label jlo +4; br lab
b18c562e
NC
1490
1491 2. 4 words -> 1 word
1492
07d6d2b8 1493 ltn < jn jn +2; jmp +4; br lab
b18c562e
NC
1494
1495 3. 4 words -> 2 words
1496
07d6d2b8
AM
1497 gt > jeq +2; jge label jeq +6; jl +4; br label
1498 gtu > jeq +2; jhs label jeq +6; jlo +4; br label
b18c562e
NC
1499
1500 4. 4 words -> 2 words and 2 labels
1501
07d6d2b8
AM
1502 leu <= jeq label; jlo label jeq +2; jhs +4; br label
1503 le <= jeq label; jl label jeq +2; jge +4; br label
b18c562e
NC
1504 =================================================================
1505
1506 codemap for first cases is (labels masked ):
1507 eq: 0x2002,0x4010,0x0000 -> 0x2400
1508 ne: 0x2402,0x4010,0x0000 -> 0x2000
1509 lt: 0x3402,0x4010,0x0000 -> 0x3800
1510 ltu: 0x2c02,0x4010,0x0000 -> 0x2800
1511 ge: 0x3802,0x4010,0x0000 -> 0x3400
1512 geu: 0x2802,0x4010,0x0000 -> 0x2c00
1513
1514 second case:
1515 ltn: 0x3001,0x3c02,0x4010,0x0000 -> 0x3000
1516
1517 third case:
1518 gt: 0x2403,0x3802,0x4010,0x0000 -> 0x2401,0x3400
1519 gtu: 0x2403,0x2802,0x4010,0x0000 -> 0x2401,0x2c00
1520
1521 fourth case:
1522 leu: 0x2401,0x2c02,0x4010,0x0000 -> 0x2400,0x2800
1523 le: 0x2401,0x3402,0x4010,0x0000 -> 0x2400,0x3800
1524
1525 Unspecified case :)
1526 jump: 0x4010,0x0000 -> 0x3c00. */
1527
1528#define NUMB_RELAX_CODES 12
1529static struct rcodes_s
1530{
1531 int f0, f1; /* From code. */
1532 int t0, t1; /* To code. */
1533 int labels; /* Position of labels: 1 - one label at first
1534 word, 2 - one at second word, 3 - two
1535 labels at both. */
1536 int cdx; /* Words to match. */
1537 int bs; /* Shrink bytes. */
1538 int off; /* Offset from old label for new code. */
1539 int ncl; /* New code length. */
1540} rcode[] =
07d6d2b8 1541{/* lab,cdx,bs,off,ncl */
b18c562e
NC
1542 { 0x0000, 0x0000, 0x3c00, 0x0000, 1, 0, 2, 2, 2}, /* jump */
1543 { 0x0000, 0x2002, 0x2400, 0x0000, 1, 1, 4, 4, 2}, /* eq */
1544 { 0x0000, 0x2402, 0x2000, 0x0000, 1, 1, 4, 4, 2}, /* ne */
1545 { 0x0000, 0x3402, 0x3800, 0x0000, 1, 1, 4, 4, 2}, /* lt */
1546 { 0x0000, 0x2c02, 0x2800, 0x0000, 1, 1, 4, 4, 2}, /* ltu */
1547 { 0x0000, 0x3802, 0x3400, 0x0000, 1, 1, 4, 4, 2}, /* ge */
1548 { 0x0000, 0x2802, 0x2c00, 0x0000, 1, 1, 4, 4, 2}, /* geu */
1549 { 0x3001, 0x3c02, 0x3000, 0x0000, 1, 2, 6, 6, 2}, /* ltn */
1550 { 0x2403, 0x3802, 0x2401, 0x3400, 2, 2, 4, 6, 4}, /* gt */
1551 { 0x2403, 0x2802, 0x2401, 0x2c00, 2, 2, 4, 6, 4}, /* gtu */
1552 { 0x2401, 0x2c02, 0x2400, 0x2800, 3, 2, 4, 6, 4}, /* leu , 2 labels */
1553 { 0x2401, 0x2c02, 0x2400, 0x2800, 3, 2, 4, 6, 4}, /* le , 2 labels */
07d6d2b8 1554 { 0, 0, 0, 0, 0, 0, 0, 0, 0}
b18c562e
NC
1555};
1556
1557/* Return TRUE if a symbol exists at the given address. */
1558
1559static bfd_boolean
1560msp430_elf_symbol_address_p (bfd * abfd,
1561 asection * sec,
1562 Elf_Internal_Sym * isym,
1563 bfd_vma addr)
1564{
1565 Elf_Internal_Shdr *symtab_hdr;
1566 unsigned int sec_shndx;
1567 Elf_Internal_Sym *isymend;
1568 struct elf_link_hash_entry **sym_hashes;
1569 struct elf_link_hash_entry **end_hashes;
1570 unsigned int symcount;
1571
1572 sec_shndx = _bfd_elf_section_from_bfd_section (abfd, sec);
1573
1574 /* Examine all the local symbols. */
1575 symtab_hdr = &elf_tdata (abfd)->symtab_hdr;
1576 for (isymend = isym + symtab_hdr->sh_info; isym < isymend; isym++)
1577 if (isym->st_shndx == sec_shndx && isym->st_value == addr)
1578 return TRUE;
1579
1580 symcount = (symtab_hdr->sh_size / sizeof (Elf32_External_Sym)
1581 - symtab_hdr->sh_info);
1582 sym_hashes = elf_sym_hashes (abfd);
1583 end_hashes = sym_hashes + symcount;
1584 for (; sym_hashes < end_hashes; sym_hashes++)
1585 {
1586 struct elf_link_hash_entry *sym_hash = *sym_hashes;
1587
1588 if ((sym_hash->root.type == bfd_link_hash_defined
1589 || sym_hash->root.type == bfd_link_hash_defweak)
1590 && sym_hash->root.u.def.section == sec
1591 && sym_hash->root.u.def.value == addr)
1592 return TRUE;
1593 }
1594
1595 return FALSE;
1596}
1597
13761a11
NC
1598/* Adjust all local symbols defined as '.section + 0xXXXX' (.section has
1599 sec_shndx) referenced from current and other sections. */
1600
046aeb74 1601static bfd_boolean
13761a11
NC
1602msp430_elf_relax_adjust_locals (bfd * abfd, asection * sec, bfd_vma addr,
1603 int count, unsigned int sec_shndx,
1604 bfd_vma toaddr)
046aeb74
DD
1605{
1606 Elf_Internal_Shdr *symtab_hdr;
1607 Elf_Internal_Rela *irel;
1608 Elf_Internal_Rela *irelend;
1609 Elf_Internal_Sym *isym;
1610
1611 irel = elf_section_data (sec)->relocs;
13761a11
NC
1612 if (irel == NULL)
1613 return TRUE;
1614
046aeb74
DD
1615 irelend = irel + sec->reloc_count;
1616 symtab_hdr = & elf_tdata (abfd)->symtab_hdr;
1617 isym = (Elf_Internal_Sym *) symtab_hdr->contents;
bceec4b9 1618
13761a11 1619 for (;irel < irelend; irel++)
046aeb74 1620 {
bceec4b9 1621 unsigned int sidx = ELF32_R_SYM(irel->r_info);
046aeb74 1622 Elf_Internal_Sym *lsym = isym + sidx;
bceec4b9 1623
1ade7175 1624 /* Adjust symbols referenced by .sec+0xXX. */
bceec4b9
DD
1625 if (irel->r_addend > addr && irel->r_addend < toaddr
1626 && sidx < symtab_hdr->sh_info
046aeb74
DD
1627 && lsym->st_shndx == sec_shndx)
1628 irel->r_addend -= count;
1629 }
1b786873 1630
046aeb74
DD
1631 return TRUE;
1632}
1633
b18c562e
NC
1634/* Delete some bytes from a section while relaxing. */
1635
1636static bfd_boolean
1637msp430_elf_relax_delete_bytes (bfd * abfd, asection * sec, bfd_vma addr,
1638 int count)
1639{
1640 Elf_Internal_Shdr *symtab_hdr;
1641 unsigned int sec_shndx;
1642 bfd_byte *contents;
1643 Elf_Internal_Rela *irel;
1644 Elf_Internal_Rela *irelend;
b18c562e
NC
1645 bfd_vma toaddr;
1646 Elf_Internal_Sym *isym;
1647 Elf_Internal_Sym *isymend;
1648 struct elf_link_hash_entry **sym_hashes;
1649 struct elf_link_hash_entry **end_hashes;
1650 unsigned int symcount;
046aeb74 1651 asection *p;
b18c562e
NC
1652
1653 sec_shndx = _bfd_elf_section_from_bfd_section (abfd, sec);
1654
1655 contents = elf_section_data (sec)->this_hdr.contents;
1656
b18c562e
NC
1657 toaddr = sec->size;
1658
1659 irel = elf_section_data (sec)->relocs;
1660 irelend = irel + sec->reloc_count;
1661
1662 /* Actually delete the bytes. */
1663 memmove (contents + addr, contents + addr + count,
1664 (size_t) (toaddr - addr - count));
1665 sec->size -= count;
1666
1667 /* Adjust all the relocs. */
fa9ee72b
DD
1668 symtab_hdr = & elf_tdata (abfd)->symtab_hdr;
1669 isym = (Elf_Internal_Sym *) symtab_hdr->contents;
13761a11 1670 for (; irel < irelend; irel++)
fa9ee72b 1671 {
fa9ee72b
DD
1672 /* Get the new reloc address. */
1673 if ((irel->r_offset > addr && irel->r_offset < toaddr))
1674 irel->r_offset -= count;
fa9ee72b 1675 }
b18c562e 1676
046aeb74 1677 for (p = abfd->sections; p != NULL; p = p->next)
13761a11 1678 msp430_elf_relax_adjust_locals (abfd,p,addr,count,sec_shndx,toaddr);
1b786873 1679
b18c562e
NC
1680 /* Adjust the local symbols defined in this section. */
1681 symtab_hdr = & elf_tdata (abfd)->symtab_hdr;
1682 isym = (Elf_Internal_Sym *) symtab_hdr->contents;
1683 for (isymend = isym + symtab_hdr->sh_info; isym < isymend; isym++)
0f8f0c57
NC
1684 {
1685 const char * name;
1686
1687 name = bfd_elf_string_from_elf_section
1688 (abfd, symtab_hdr->sh_link, isym->st_name);
1689 name = (name == NULL || * name == 0) ? bfd_section_name (abfd, sec) : name;
1690
1691 if (isym->st_shndx != sec_shndx)
1692 continue;
1b786873 1693
0f8f0c57
NC
1694 if (isym->st_value > addr
1695 && (isym->st_value < toaddr
1696 /* We also adjust a symbol at the end of the section if its name is
1697 on the list below. These symbols are used for debug info
1698 generation and they refer to the end of the current section, not
1699 the start of the next section. */
1700 || (isym->st_value == toaddr
1701 && name != NULL
1702 && (CONST_STRNEQ (name, ".Letext")
1703 || CONST_STRNEQ (name, ".LFE")))))
1704 {
1705 if (isym->st_value < addr + count)
1706 isym->st_value = addr;
1707 else
1708 isym->st_value -= count;
1709 }
1710 /* Adjust the function symbol's size as well. */
1711 else if (ELF_ST_TYPE (isym->st_info) == STT_FUNC
1712 && isym->st_value + isym->st_size > addr
1713 && isym->st_value + isym->st_size < toaddr)
1714 isym->st_size -= count;
1715 }
b18c562e
NC
1716
1717 /* Now adjust the global symbols defined in this section. */
1718 symcount = (symtab_hdr->sh_size / sizeof (Elf32_External_Sym)
1719 - symtab_hdr->sh_info);
1720 sym_hashes = elf_sym_hashes (abfd);
1721 end_hashes = sym_hashes + symcount;
1722 for (; sym_hashes < end_hashes; sym_hashes++)
1723 {
1724 struct elf_link_hash_entry *sym_hash = *sym_hashes;
1725
1726 if ((sym_hash->root.type == bfd_link_hash_defined
1727 || sym_hash->root.type == bfd_link_hash_defweak)
1728 && sym_hash->root.u.def.section == sec
1729 && sym_hash->root.u.def.value > addr
1730 && sym_hash->root.u.def.value < toaddr)
0f8f0c57
NC
1731 {
1732 if (sym_hash->root.u.def.value < addr + count)
1733 sym_hash->root.u.def.value = addr;
1734 else
1735 sym_hash->root.u.def.value -= count;
1736 }
1737 /* Adjust the function symbol's size as well. */
1738 else if (sym_hash->root.type == bfd_link_hash_defined
1739 && sym_hash->root.u.def.section == sec
1740 && sym_hash->type == STT_FUNC
1741 && sym_hash->root.u.def.value + sym_hash->size > addr
1742 && sym_hash->root.u.def.value + sym_hash->size < toaddr)
1743 sym_hash->size -= count;
b18c562e
NC
1744 }
1745
1746 return TRUE;
1747}
1748
13761a11
NC
1749/* Insert two words into a section whilst relaxing. */
1750
1751static bfd_byte *
1752msp430_elf_relax_add_two_words (bfd * abfd, asection * sec, bfd_vma addr,
1753 int word1, int word2)
1754{
1755 Elf_Internal_Shdr *symtab_hdr;
1756 unsigned int sec_shndx;
1757 bfd_byte *contents;
1758 Elf_Internal_Rela *irel;
1759 Elf_Internal_Rela *irelend;
1760 Elf_Internal_Sym *isym;
1761 Elf_Internal_Sym *isymend;
1762 struct elf_link_hash_entry **sym_hashes;
1763 struct elf_link_hash_entry **end_hashes;
1764 unsigned int symcount;
1765 bfd_vma sec_end;
1766 asection *p;
1767
1768 contents = elf_section_data (sec)->this_hdr.contents;
1769 sec_end = sec->size;
1770
1771 /* Make space for the new words. */
1772 contents = bfd_realloc (contents, sec_end + 4);
1773 memmove (contents + addr + 4, contents + addr, sec_end - addr);
1774
1775 /* Insert the new words. */
1776 bfd_put_16 (abfd, word1, contents + addr);
1777 bfd_put_16 (abfd, word2, contents + addr + 2);
1778
1779 /* Update the section information. */
1780 sec->size += 4;
1b786873 1781 elf_section_data (sec)->this_hdr.contents = contents;
13761a11
NC
1782
1783 /* Adjust all the relocs. */
1784 irel = elf_section_data (sec)->relocs;
1785 irelend = irel + sec->reloc_count;
1786
1787 for (; irel < irelend; irel++)
1788 if ((irel->r_offset >= addr && irel->r_offset < sec_end))
1789 irel->r_offset += 4;
1790
1791 /* Adjust the local symbols defined in this section. */
1792 sec_shndx = _bfd_elf_section_from_bfd_section (abfd, sec);
1793 for (p = abfd->sections; p != NULL; p = p->next)
1794 msp430_elf_relax_adjust_locals (abfd, p, addr, -4,
1795 sec_shndx, sec_end);
1796
1797 /* Adjust the global symbols affected by the move. */
1798 symtab_hdr = & elf_tdata (abfd)->symtab_hdr;
1799 isym = (Elf_Internal_Sym *) symtab_hdr->contents;
1800 for (isymend = isym + symtab_hdr->sh_info; isym < isymend; isym++)
1801 if (isym->st_shndx == sec_shndx
1802 && isym->st_value >= addr && isym->st_value < sec_end)
1803 isym->st_value += 4;
1804
1805 /* Now adjust the global symbols defined in this section. */
1806 symcount = (symtab_hdr->sh_size / sizeof (Elf32_External_Sym)
1807 - symtab_hdr->sh_info);
1808 sym_hashes = elf_sym_hashes (abfd);
1809 end_hashes = sym_hashes + symcount;
1810 for (; sym_hashes < end_hashes; sym_hashes++)
1811 {
1812 struct elf_link_hash_entry *sym_hash = *sym_hashes;
1813
1814 if ((sym_hash->root.type == bfd_link_hash_defined
1815 || sym_hash->root.type == bfd_link_hash_defweak)
1816 && sym_hash->root.u.def.section == sec
1817 && sym_hash->root.u.def.value >= addr
1818 && sym_hash->root.u.def.value < sec_end)
1819 sym_hash->root.u.def.value += 4;
1820 }
1821
1822 return contents;
1823}
1b786873 1824
b18c562e
NC
1825static bfd_boolean
1826msp430_elf_relax_section (bfd * abfd, asection * sec,
1827 struct bfd_link_info * link_info,
1828 bfd_boolean * again)
1829{
1830 Elf_Internal_Shdr * symtab_hdr;
1831 Elf_Internal_Rela * internal_relocs;
1832 Elf_Internal_Rela * irel;
1833 Elf_Internal_Rela * irelend;
07d6d2b8 1834 bfd_byte * contents = NULL;
b18c562e
NC
1835 Elf_Internal_Sym * isymbuf = NULL;
1836
1837 /* Assume nothing changes. */
1838 *again = FALSE;
1839
1840 /* We don't have to do anything for a relocatable link, if
1841 this section does not have relocs, or if this is not a
1842 code section. */
0e1862bb 1843 if (bfd_link_relocatable (link_info)
13761a11
NC
1844 || (sec->flags & SEC_RELOC) == 0
1845 || sec->reloc_count == 0 || (sec->flags & SEC_CODE) == 0)
b18c562e
NC
1846 return TRUE;
1847
1848 symtab_hdr = & elf_tdata (abfd)->symtab_hdr;
1849
1850 /* Get a copy of the native relocations. */
1851 internal_relocs =
1852 _bfd_elf_link_read_relocs (abfd, sec, NULL, NULL, link_info->keep_memory);
1853 if (internal_relocs == NULL)
1854 goto error_return;
1855
1856 /* Walk through them looking for relaxing opportunities. */
1857 irelend = internal_relocs + sec->reloc_count;
13761a11
NC
1858
1859 /* Do code size growing relocs first. */
b18c562e
NC
1860 for (irel = internal_relocs; irel < irelend; irel++)
1861 {
1862 bfd_vma symval;
1863
1864 /* If this isn't something that can be relaxed, then ignore
07d6d2b8 1865 this reloc. */
13761a11 1866 if (uses_msp430x_relocs (abfd)
07d6d2b8 1867 && ELF32_R_TYPE (irel->r_info) == (int) R_MSP430X_10_PCREL)
13761a11
NC
1868 ;
1869 else if (! uses_msp430x_relocs (abfd)
07d6d2b8 1870 && ELF32_R_TYPE (irel->r_info) == (int) R_MSP430_10_PCREL)
13761a11
NC
1871 ;
1872 else
b18c562e
NC
1873 continue;
1874
1875 /* Get the section contents if we haven't done so already. */
1876 if (contents == NULL)
1877 {
1878 /* Get cached copy if it exists. */
1879 if (elf_section_data (sec)->this_hdr.contents != NULL)
1880 contents = elf_section_data (sec)->this_hdr.contents;
1881 else if (! bfd_malloc_and_get_section (abfd, sec, &contents))
1882 goto error_return;
1883 }
1884
1885 /* Read this BFD's local symbols if we haven't done so already. */
1886 if (isymbuf == NULL && symtab_hdr->sh_info != 0)
1887 {
1888 isymbuf = (Elf_Internal_Sym *) symtab_hdr->contents;
1889 if (isymbuf == NULL)
1890 isymbuf = bfd_elf_get_elf_syms (abfd, symtab_hdr,
1891 symtab_hdr->sh_info, 0,
1892 NULL, NULL, NULL);
1893 if (isymbuf == NULL)
1894 goto error_return;
1895 }
1896
1897 /* Get the value of the symbol referred to by the reloc. */
1898 if (ELF32_R_SYM (irel->r_info) < symtab_hdr->sh_info)
1899 {
1900 /* A local symbol. */
1901 Elf_Internal_Sym *isym;
1902 asection *sym_sec;
1903
1904 isym = isymbuf + ELF32_R_SYM (irel->r_info);
1905 if (isym->st_shndx == SHN_UNDEF)
1906 sym_sec = bfd_und_section_ptr;
1907 else if (isym->st_shndx == SHN_ABS)
1908 sym_sec = bfd_abs_section_ptr;
1909 else if (isym->st_shndx == SHN_COMMON)
1910 sym_sec = bfd_com_section_ptr;
1911 else
1912 sym_sec = bfd_section_from_elf_index (abfd, isym->st_shndx);
1913 symval = (isym->st_value
1914 + sym_sec->output_section->vma + sym_sec->output_offset);
1915 }
1916 else
1917 {
1918 unsigned long indx;
1919 struct elf_link_hash_entry *h;
1920
1921 /* An external symbol. */
1922 indx = ELF32_R_SYM (irel->r_info) - symtab_hdr->sh_info;
1923 h = elf_sym_hashes (abfd)[indx];
1924 BFD_ASSERT (h != NULL);
1925
1926 if (h->root.type != bfd_link_hash_defined
1927 && h->root.type != bfd_link_hash_defweak)
1928 /* This appears to be a reference to an undefined
1929 symbol. Just ignore it--it will be caught by the
1930 regular reloc processing. */
1931 continue;
1932
1933 symval = (h->root.u.def.value
1934 + h->root.u.def.section->output_section->vma
1935 + h->root.u.def.section->output_offset);
1936 }
1937
1938 /* For simplicity of coding, we are going to modify the section
07d6d2b8
AM
1939 contents, the section relocs, and the BFD symbol table. We
1940 must tell the rest of the code not to free up this
1941 information. It would be possible to instead create a table
1942 of changes which have to be made, as is done in coff-mips.c;
1943 that would be more work, but would require less memory when
1944 the linker is run. */
b18c562e 1945
13761a11
NC
1946 bfd_signed_vma value = symval;
1947 int opcode;
b18c562e 1948
13761a11
NC
1949 /* Compute the value that will be relocated. */
1950 value += irel->r_addend;
1951 /* Convert to PC relative. */
1952 value -= (sec->output_section->vma + sec->output_offset);
1953 value -= irel->r_offset;
1954 value -= 2;
1955 /* Scale. */
1956 value >>= 1;
b18c562e 1957
13761a11
NC
1958 /* If it is in range then no modifications are needed. */
1959 if (value >= -512 && value <= 511)
1960 continue;
b18c562e 1961
13761a11
NC
1962 /* Get the opcode. */
1963 opcode = bfd_get_16 (abfd, contents + irel->r_offset);
1b786873 1964
13761a11
NC
1965 /* Compute the new opcode. We are going to convert:
1966 J<cond> label
1967 into:
1968 J<inv-cond> 1f
1969 BR[A] #label
07d6d2b8 1970 1: */
13761a11
NC
1971 switch (opcode & 0xfc00)
1972 {
1b786873 1973 case 0x3800: opcode = 0x3402; break; /* Jl -> Jge +2 */
13761a11
NC
1974 case 0x3400: opcode = 0x3802; break; /* Jge -> Jl +2 */
1975 case 0x2c00: opcode = 0x2802; break; /* Jhs -> Jlo +2 */
1976 case 0x2800: opcode = 0x2c02; break; /* Jlo -> Jhs +2 */
1977 case 0x2400: opcode = 0x2002; break; /* Jeq -> Jne +2 */
1978 case 0x2000: opcode = 0x2402; break; /* jne -> Jeq +2 */
1979 case 0x3000: /* jn */
1980 /* There is no direct inverse of the Jn insn.
1981 FIXME: we could do this as:
07d6d2b8
AM
1982 Jn 1f
1983 br 2f
13761a11 1984 1: br label
07d6d2b8 1985 2: */
13761a11
NC
1986 continue;
1987 default:
1988 /* Not a conditional branch instruction. */
1989 /* fprintf (stderr, "unrecog: %x\n", opcode); */
2d071cfc 1990 continue;
13761a11 1991 }
b18c562e 1992
13761a11
NC
1993 /* Note that we've changed the relocs, section contents, etc. */
1994 elf_section_data (sec)->relocs = internal_relocs;
1995 elf_section_data (sec)->this_hdr.contents = contents;
1996 symtab_hdr->contents = (unsigned char *) isymbuf;
b18c562e 1997
13761a11
NC
1998 /* Install the new opcode. */
1999 bfd_put_16 (abfd, opcode, contents + irel->r_offset);
b18c562e 2000
13761a11
NC
2001 /* Insert the new branch instruction. */
2002 if (uses_msp430x_relocs (abfd))
2003 {
1b786873 2004 /* Insert an absolute branch (aka MOVA) instruction. */
13761a11
NC
2005 contents = msp430_elf_relax_add_two_words
2006 (abfd, sec, irel->r_offset + 2, 0x0080, 0x0000);
2007
2008 /* Update the relocation to point to the inserted branch
2009 instruction. Note - we are changing a PC-relative reloc
2010 into an absolute reloc, but this is OK because we have
2011 arranged with the assembler to have the reloc's value be
2012 a (local) symbol, not a section+offset value. */
2013 irel->r_offset += 2;
2014 irel->r_info = ELF32_R_INFO (ELF32_R_SYM (irel->r_info),
2015 R_MSP430X_ABS20_ADR_SRC);
2016 }
2017 else
2018 {
2019 contents = msp430_elf_relax_add_two_words
2020 (abfd, sec, irel->r_offset + 2, 0x4030, 0x0000);
2021
2022 /* See comment above about converting a 10-bit PC-rel
2023 relocation into a 16-bit absolute relocation. */
2024 irel->r_offset += 4;
2025 irel->r_info = ELF32_R_INFO (ELF32_R_SYM (irel->r_info),
2026 R_MSP430_16);
2027 }
b18c562e 2028
13761a11
NC
2029 /* Growing the section may mean that other
2030 conditional branches need to be fixed. */
2031 *again = TRUE;
2032 }
b18c562e 2033
13761a11
NC
2034 for (irel = internal_relocs; irel < irelend; irel++)
2035 {
2036 bfd_vma symval;
2037
2038 /* Get the section contents if we haven't done so already. */
2039 if (contents == NULL)
2040 {
2041 /* Get cached copy if it exists. */
2042 if (elf_section_data (sec)->this_hdr.contents != NULL)
2043 contents = elf_section_data (sec)->this_hdr.contents;
2044 else if (! bfd_malloc_and_get_section (abfd, sec, &contents))
2045 goto error_return;
2046 }
2047
2048 /* Read this BFD's local symbols if we haven't done so already. */
2049 if (isymbuf == NULL && symtab_hdr->sh_info != 0)
2050 {
2051 isymbuf = (Elf_Internal_Sym *) symtab_hdr->contents;
2052 if (isymbuf == NULL)
2053 isymbuf = bfd_elf_get_elf_syms (abfd, symtab_hdr,
2054 symtab_hdr->sh_info, 0,
2055 NULL, NULL, NULL);
2056 if (isymbuf == NULL)
2057 goto error_return;
2058 }
2059
2060 /* Get the value of the symbol referred to by the reloc. */
2061 if (ELF32_R_SYM (irel->r_info) < symtab_hdr->sh_info)
2062 {
2063 /* A local symbol. */
2064 Elf_Internal_Sym *isym;
2065 asection *sym_sec;
2066
2067 isym = isymbuf + ELF32_R_SYM (irel->r_info);
2068 if (isym->st_shndx == SHN_UNDEF)
2069 sym_sec = bfd_und_section_ptr;
2070 else if (isym->st_shndx == SHN_ABS)
2071 sym_sec = bfd_abs_section_ptr;
2072 else if (isym->st_shndx == SHN_COMMON)
2073 sym_sec = bfd_com_section_ptr;
2074 else
2075 sym_sec = bfd_section_from_elf_index (abfd, isym->st_shndx);
2076 symval = (isym->st_value
2077 + sym_sec->output_section->vma + sym_sec->output_offset);
2078 }
2079 else
2080 {
2081 unsigned long indx;
2082 struct elf_link_hash_entry *h;
2083
2084 /* An external symbol. */
2085 indx = ELF32_R_SYM (irel->r_info) - symtab_hdr->sh_info;
2086 h = elf_sym_hashes (abfd)[indx];
2087 BFD_ASSERT (h != NULL);
2088
2089 if (h->root.type != bfd_link_hash_defined
2090 && h->root.type != bfd_link_hash_defweak)
2091 /* This appears to be a reference to an undefined
2092 symbol. Just ignore it--it will be caught by the
2093 regular reloc processing. */
2094 continue;
2095
2096 symval = (h->root.u.def.value
2097 + h->root.u.def.section->output_section->vma
2098 + h->root.u.def.section->output_offset);
2099 }
2100
2101 /* For simplicity of coding, we are going to modify the section
2102 contents, the section relocs, and the BFD symbol table. We
2103 must tell the rest of the code not to free up this
2104 information. It would be possible to instead create a table
2105 of changes which have to be made, as is done in coff-mips.c;
2106 that would be more work, but would require less memory when
2107 the linker is run. */
2108
2109 /* Try to turn a 16bit pc-relative branch into a 10bit pc-relative
2110 branch. */
1b786873 2111 /* Paranoia? paranoia... */
23d4663e
NC
2112 if (! uses_msp430x_relocs (abfd)
2113 && ELF32_R_TYPE (irel->r_info) == (int) R_MSP430_RL_PCREL)
13761a11
NC
2114 {
2115 bfd_vma value = symval;
2116
2117 /* Deal with pc-relative gunk. */
2118 value -= (sec->output_section->vma + sec->output_offset);
2119 value -= irel->r_offset;
2120 value += irel->r_addend;
2121
2122 /* See if the value will fit in 10 bits, note the high value is
2123 1016 as the target will be two bytes closer if we are
2124 able to relax. */
2125 if ((long) value < 1016 && (long) value > -1016)
2126 {
2127 int code0 = 0, code1 = 0, code2 = 0;
2128 int i;
2129 struct rcodes_s *rx;
2130
2131 /* Get the opcode. */
2132 if (irel->r_offset >= 6)
2133 code0 = bfd_get_16 (abfd, contents + irel->r_offset - 6);
2134
2135 if (irel->r_offset >= 4)
2136 code1 = bfd_get_16 (abfd, contents + irel->r_offset - 4);
2137
2138 code2 = bfd_get_16 (abfd, contents + irel->r_offset - 2);
2139
2140 if (code2 != 0x4010)
2141 continue;
2142
2143 /* Check r4 and r3. */
2144 for (i = NUMB_RELAX_CODES - 1; i >= 0; i--)
2145 {
2146 rx = &rcode[i];
2147 if (rx->cdx == 2 && rx->f0 == code0 && rx->f1 == code1)
2148 break;
2149 else if (rx->cdx == 1 && rx->f1 == code1)
2150 break;
2151 else if (rx->cdx == 0) /* This is an unconditional jump. */
2152 break;
2153 }
2154
2155 /* Check labels:
b18c562e 2156 .Label0: ; we do not care about this label
13761a11 2157 jeq +6
b18c562e 2158 .Label1: ; make sure there is no label here
13761a11 2159 jl +4
b18c562e 2160 .Label2: ; make sure there is no label here
13761a11
NC
2161 br .Label_dst
2162
2163 So, if there is .Label1 or .Label2 we cannot relax this code.
2164 This actually should not happen, cause for relaxable
2165 instructions we use RL_PCREL reloc instead of 16_PCREL.
2166 Will change this in the future. */
2167
2168 if (rx->cdx > 0
2169 && msp430_elf_symbol_address_p (abfd, sec, isymbuf,
2170 irel->r_offset - 2))
2171 continue;
2172 if (rx->cdx > 1
2173 && msp430_elf_symbol_address_p (abfd, sec, isymbuf,
2174 irel->r_offset - 4))
2175 continue;
2176
2177 /* Note that we've changed the relocs, section contents, etc. */
2178 elf_section_data (sec)->relocs = internal_relocs;
2179 elf_section_data (sec)->this_hdr.contents = contents;
2180 symtab_hdr->contents = (unsigned char *) isymbuf;
2181
2182 /* Fix the relocation's type. */
2183 if (uses_msp430x_relocs (abfd))
2184 {
2185 if (rx->labels == 3) /* Handle special cases. */
2186 irel->r_info = ELF32_R_INFO (ELF32_R_SYM (irel->r_info),
2187 R_MSP430X_2X_PCREL);
2188 else
2189 irel->r_info = ELF32_R_INFO (ELF32_R_SYM (irel->r_info),
2190 R_MSP430X_10_PCREL);
2191 }
2192 else
2193 {
2194 if (rx->labels == 3) /* Handle special cases. */
2195 irel->r_info = ELF32_R_INFO (ELF32_R_SYM (irel->r_info),
2196 R_MSP430_2X_PCREL);
2197 else
2198 irel->r_info = ELF32_R_INFO (ELF32_R_SYM (irel->r_info),
2199 R_MSP430_10_PCREL);
2200 }
2201
2202 /* Fix the opcode right way. */
2203 bfd_put_16 (abfd, rx->t0, contents + irel->r_offset - rx->off);
2204 if (rx->t1)
2205 bfd_put_16 (abfd, rx->t1,
2206 contents + irel->r_offset - rx->off + 2);
2207
2208 /* Delete bytes. */
2209 if (!msp430_elf_relax_delete_bytes (abfd, sec,
2210 irel->r_offset - rx->off +
2211 rx->ncl, rx->bs))
2212 goto error_return;
2213
2214 /* Handle unconditional jumps. */
2215 if (rx->cdx == 0)
2216 irel->r_offset -= 2;
2217
2218 /* That will change things, so, we should relax again.
2219 Note that this is not required, and it may be slow. */
2220 *again = TRUE;
2221 }
2222 }
23d4663e
NC
2223
2224 /* Try to turn a 16-bit absolute branch into a 10-bit pc-relative
2225 branch. */
133193b8
NC
2226 if ((uses_msp430x_relocs (abfd)
2227 && ELF32_R_TYPE (irel->r_info) == R_MSP430X_ABS16)
2228 || (! uses_msp430x_relocs (abfd)
2229 && ELF32_R_TYPE (irel->r_info) == R_MSP430_16))
23d4663e
NC
2230 {
2231 bfd_vma value = symval;
2232
2d071cfc 2233 value -= (sec->output_section->vma + sec->output_offset);
23d4663e
NC
2234 value -= irel->r_offset;
2235 value += irel->r_addend;
1b786873 2236
23d4663e
NC
2237 /* See if the value will fit in 10 bits, note the high value is
2238 1016 as the target will be two bytes closer if we are
2239 able to relax. */
2240 if ((long) value < 1016 && (long) value > -1016)
2241 {
2242 int code2;
2243
2244 /* Get the opcode. */
2245 code2 = bfd_get_16 (abfd, contents + irel->r_offset - 2);
2246 if (code2 != 0x4030)
2247 continue;
2248 /* FIXME: check r4 and r3 ? */
2249 /* FIXME: Handle 0x4010 as well ? */
2250
2251 /* Note that we've changed the relocs, section contents, etc. */
2252 elf_section_data (sec)->relocs = internal_relocs;
2253 elf_section_data (sec)->this_hdr.contents = contents;
2254 symtab_hdr->contents = (unsigned char *) isymbuf;
2255
2256 /* Fix the relocation's type. */
2257 if (uses_msp430x_relocs (abfd))
2258 {
2259 irel->r_info = ELF32_R_INFO (ELF32_R_SYM (irel->r_info),
2260 R_MSP430X_10_PCREL);
2261 }
2262 else
2263 {
2264 irel->r_info = ELF32_R_INFO (ELF32_R_SYM (irel->r_info),
2265 R_MSP430_10_PCREL);
2266 }
2267
2268 /* Fix the opcode right way. */
2269 bfd_put_16 (abfd, 0x3c00, contents + irel->r_offset - 2);
2270 irel->r_offset -= 2;
2271
2272 /* Delete bytes. */
2273 if (!msp430_elf_relax_delete_bytes (abfd, sec,
2274 irel->r_offset + 2, 2))
2275 goto error_return;
2276
2277 /* That will change things, so, we should relax again.
2278 Note that this is not required, and it may be slow. */
2279 *again = TRUE;
2280 }
2281 }
13761a11 2282 }
b18c562e
NC
2283
2284 if (isymbuf != NULL && symtab_hdr->contents != (unsigned char *) isymbuf)
2285 {
2286 if (!link_info->keep_memory)
2287 free (isymbuf);
2288 else
2289 {
2290 /* Cache the symbols for elf_link_input_bfd. */
2291 symtab_hdr->contents = (unsigned char *) isymbuf;
2292 }
2293 }
2294
2295 if (contents != NULL
2296 && elf_section_data (sec)->this_hdr.contents != contents)
2297 {
2298 if (!link_info->keep_memory)
2299 free (contents);
2300 else
2301 {
2302 /* Cache the section contents for elf_link_input_bfd. */
2303 elf_section_data (sec)->this_hdr.contents = contents;
2304 }
2305 }
2306
2307 if (internal_relocs != NULL
2308 && elf_section_data (sec)->relocs != internal_relocs)
2309 free (internal_relocs);
2310
2311 return TRUE;
2312
2313error_return:
2314 if (isymbuf != NULL && symtab_hdr->contents != (unsigned char *) isymbuf)
2315 free (isymbuf);
2316 if (contents != NULL
2317 && elf_section_data (sec)->this_hdr.contents != contents)
2318 free (contents);
2319 if (internal_relocs != NULL
2320 && elf_section_data (sec)->relocs != internal_relocs)
2321 free (internal_relocs);
2322
2323 return FALSE;
2324}
2325
13761a11
NC
2326/* Handle an MSP430 specific section when reading an object file.
2327 This is called when bfd_section_from_shdr finds a section with
2328 an unknown type. */
2329
2330static bfd_boolean
2331elf32_msp430_section_from_shdr (bfd *abfd,
2332 Elf_Internal_Shdr * hdr,
2333 const char *name,
2334 int shindex)
2335{
2336 switch (hdr->sh_type)
2337 {
2338 case SHT_MSP430_SEC_FLAGS:
2339 case SHT_MSP430_SYM_ALIASES:
2340 case SHT_MSP430_ATTRIBUTES:
2341 return _bfd_elf_make_section_from_shdr (abfd, hdr, name, shindex);
2342 default:
2343 return FALSE;
2344 }
2345}
2346
2347static bfd_boolean
2348elf32_msp430_obj_attrs_handle_unknown (bfd *abfd, int tag)
2349{
2350 _bfd_error_handler
695344c0 2351 /* xgettext:c-format */
13761a11
NC
2352 (_("Warning: %B: Unknown MSPABI object attribute %d"),
2353 abfd, tag);
2354 return TRUE;
2355}
2356
2357/* Determine whether an object attribute tag takes an integer, a
2358 string or both. */
2359
2360static int
2361elf32_msp430_obj_attrs_arg_type (int tag)
2362{
2363 if (tag == Tag_compatibility)
2364 return ATTR_TYPE_FLAG_INT_VAL | ATTR_TYPE_FLAG_STR_VAL;
2365
2366 if (tag < 32)
2367 return ATTR_TYPE_FLAG_INT_VAL;
2368
2369 return (tag & 1) != 0 ? ATTR_TYPE_FLAG_STR_VAL : ATTR_TYPE_FLAG_INT_VAL;
2370}
2371
2372static inline const char *
2373isa_type (int isa)
2374{
2375 switch (isa)
2376 {
2377 case 1: return "MSP430";
2378 case 2: return "MSP430X";
2379 default: return "unknown";
2380 }
2381}
2382
2383static inline const char *
2384code_model (int model)
2385{
2386 switch (model)
2387 {
2388 case 1: return "small";
2389 case 2: return "large";
2390 default: return "unknown";
2391 }
2392}
2393
2394static inline const char *
2395data_model (int model)
2396{
2397 switch (model)
2398 {
2399 case 1: return "small";
2400 case 2: return "large";
2401 case 3: return "restricted large";
2402 default: return "unknown";
2403 }
2404}
2405
2406/* Merge MSPABI object attributes from IBFD into OBFD.
2407 Raise an error if there are conflicting attributes. */
2408
2409static bfd_boolean
50e03d47 2410elf32_msp430_merge_mspabi_attributes (bfd *ibfd, struct bfd_link_info *info)
13761a11 2411{
50e03d47 2412 bfd *obfd = info->output_bfd;
13761a11
NC
2413 obj_attribute *in_attr;
2414 obj_attribute *out_attr;
2415 bfd_boolean result = TRUE;
2416 static bfd * first_input_bfd = NULL;
2417
2418 /* Skip linker created files. */
2419 if (ibfd->flags & BFD_LINKER_CREATED)
2420 return TRUE;
2421
2422 /* If this is the first real object just copy the attributes. */
2423 if (!elf_known_obj_attributes_proc (obfd)[0].i)
2424 {
2425 _bfd_elf_copy_obj_attributes (ibfd, obfd);
2426
2427 out_attr = elf_known_obj_attributes_proc (obfd);
2428
2429 /* Use the Tag_null value to indicate that
2430 the attributes have been initialized. */
2431 out_attr[0].i = 1;
2432
2433 first_input_bfd = ibfd;
2434 return TRUE;
2435 }
2436
2437 in_attr = elf_known_obj_attributes_proc (ibfd);
2438 out_attr = elf_known_obj_attributes_proc (obfd);
2439
2440 /* The ISAs must be the same. */
2441 if (in_attr[OFBA_MSPABI_Tag_ISA].i != out_attr[OFBA_MSPABI_Tag_ISA].i)
2442 {
2443 _bfd_error_handler
695344c0 2444 /* xgettext:c-format */
13761a11 2445 (_("error: %B uses %s instructions but %B uses %s"),
c08bb8dd
AM
2446 ibfd, isa_type (in_attr[OFBA_MSPABI_Tag_ISA].i),
2447 first_input_bfd, isa_type (out_attr[OFBA_MSPABI_Tag_ISA].i));
13761a11
NC
2448 result = FALSE;
2449 }
2450
2451 /* The code models must be the same. */
2452 if (in_attr[OFBA_MSPABI_Tag_Code_Model].i !=
2453 out_attr[OFBA_MSPABI_Tag_Code_Model].i)
2454 {
2455 _bfd_error_handler
695344c0 2456 /* xgettext:c-format */
13761a11 2457 (_("error: %B uses the %s code model whereas %B uses the %s code model"),
c08bb8dd
AM
2458 ibfd, code_model (in_attr[OFBA_MSPABI_Tag_Code_Model].i),
2459 first_input_bfd, code_model (out_attr[OFBA_MSPABI_Tag_Code_Model].i));
13761a11
NC
2460 result = FALSE;
2461 }
2462
2463 /* The large code model is only supported by the MSP430X. */
2464 if (in_attr[OFBA_MSPABI_Tag_Code_Model].i == 2
2465 && out_attr[OFBA_MSPABI_Tag_ISA].i != 2)
2466 {
2467 _bfd_error_handler
695344c0 2468 /* xgettext:c-format */
13761a11
NC
2469 (_("error: %B uses the large code model but %B uses MSP430 instructions"),
2470 ibfd, first_input_bfd);
2471 result = FALSE;
2472 }
2473
2474 /* The data models must be the same. */
2475 if (in_attr[OFBA_MSPABI_Tag_Data_Model].i !=
2476 out_attr[OFBA_MSPABI_Tag_Data_Model].i)
2477 {
2478 _bfd_error_handler
695344c0 2479 /* xgettext:c-format */
13761a11 2480 (_("error: %B uses the %s data model whereas %B uses the %s data model"),
c08bb8dd
AM
2481 ibfd, data_model (in_attr[OFBA_MSPABI_Tag_Data_Model].i),
2482 first_input_bfd, data_model (out_attr[OFBA_MSPABI_Tag_Data_Model].i));
13761a11
NC
2483 result = FALSE;
2484 }
2485
2486 /* The small code model requires the use of the small data model. */
2487 if (in_attr[OFBA_MSPABI_Tag_Code_Model].i == 1
2488 && out_attr[OFBA_MSPABI_Tag_Data_Model].i != 1)
2489 {
2490 _bfd_error_handler
695344c0 2491 /* xgettext:c-format */
13761a11
NC
2492 (_("error: %B uses the small code model but %B uses the %s data model"),
2493 ibfd, first_input_bfd,
2494 data_model (out_attr[OFBA_MSPABI_Tag_Data_Model].i));
2495 result = FALSE;
2496 }
2497
2498 /* The large data models are only supported by the MSP430X. */
2499 if (in_attr[OFBA_MSPABI_Tag_Data_Model].i > 1
2500 && out_attr[OFBA_MSPABI_Tag_ISA].i != 2)
2501 {
2502 _bfd_error_handler
695344c0 2503 /* xgettext:c-format */
13761a11 2504 (_("error: %B uses the %s data model but %B only uses MSP430 instructions"),
c08bb8dd
AM
2505 ibfd, data_model (in_attr[OFBA_MSPABI_Tag_Data_Model].i),
2506 first_input_bfd);
13761a11
NC
2507 result = FALSE;
2508 }
1b786873 2509
13761a11
NC
2510 return result;
2511}
2512
2513/* Merge backend specific data from an object file to the output
2514 object file when linking. */
2515
2516static bfd_boolean
50e03d47 2517elf32_msp430_merge_private_bfd_data (bfd *ibfd, struct bfd_link_info *info)
13761a11 2518{
50e03d47 2519 bfd *obfd = info->output_bfd;
13761a11
NC
2520 /* Make sure that the machine number reflects the most
2521 advanced version of the MSP architecture required. */
2522#define max(a,b) ((a) > (b) ? (a) : (b))
2523 if (bfd_get_mach (ibfd) != bfd_get_mach (obfd))
2524 bfd_default_set_arch_mach (obfd, bfd_get_arch (obfd),
2525 max (bfd_get_mach (ibfd), bfd_get_mach (obfd)));
2526#undef max
2527
50e03d47 2528 return elf32_msp430_merge_mspabi_attributes (ibfd, info);
13761a11
NC
2529}
2530
13761a11
NC
2531static bfd_boolean
2532msp430_elf_is_target_special_symbol (bfd *abfd, asymbol *sym)
2533{
2534 return _bfd_elf_is_local_label_name (abfd, sym->name);
2535}
2536
79559014
NC
2537static bfd_boolean
2538uses_large_model (bfd *abfd)
2539{
2540 obj_attribute * attr;
2541
2542 if (abfd->flags & BFD_LINKER_CREATED)
2543 return FALSE;
2544
2545 attr = elf_known_obj_attributes_proc (abfd);
2546 if (attr == NULL)
2547 return FALSE;
2548
2549 return attr[OFBA_MSPABI_Tag_Code_Model].i == 2;
2550}
2551
2552static unsigned int
76c20d54
AM
2553elf32_msp430_eh_frame_address_size (bfd *abfd,
2554 const asection *sec ATTRIBUTE_UNUSED)
79559014
NC
2555{
2556 return uses_large_model (abfd) ? 4 : 2;
2557}
2558
13761a11
NC
2559/* This is gross. The MSP430 EABI says that (sec 11.5):
2560
2561 "An implementation may choose to use Rel or Rela
2562 type relocations for other relocations."
2563
2564 But it also says that:
1b786873 2565
13761a11
NC
2566 "Certain relocations are identified as Rela only. [snip]
2567 Where Rela is specified, an implementation must honor
2568 this requirement."
2569
2570 There is one relocation marked as requiring RELA - R_MSP430_ABS_HI16 - but
2571 to keep things simple we choose to use RELA relocations throughout. The
2572 problem is that the TI compiler generates REL relocations, so we have to
2573 be able to accept those as well. */
2574
2575#define elf_backend_may_use_rel_p 1
2576#define elf_backend_may_use_rela_p 1
2577#define elf_backend_default_use_rela_p 1
2578
07d6d2b8 2579#undef elf_backend_obj_attrs_vendor
13761a11 2580#define elf_backend_obj_attrs_vendor "mspabi"
07d6d2b8 2581#undef elf_backend_obj_attrs_section
13761a11 2582#define elf_backend_obj_attrs_section ".MSP430.attributes"
07d6d2b8 2583#undef elf_backend_obj_attrs_section_type
13761a11 2584#define elf_backend_obj_attrs_section_type SHT_MSP430_ATTRIBUTES
07d6d2b8
AM
2585#define elf_backend_section_from_shdr elf32_msp430_section_from_shdr
2586#define elf_backend_obj_attrs_handle_unknown elf32_msp430_obj_attrs_handle_unknown
2587#undef elf_backend_obj_attrs_arg_type
13761a11 2588#define elf_backend_obj_attrs_arg_type elf32_msp430_obj_attrs_arg_type
13761a11 2589#define bfd_elf32_bfd_merge_private_bfd_data elf32_msp430_merge_private_bfd_data
79559014 2590#define elf_backend_eh_frame_address_size elf32_msp430_eh_frame_address_size
2469cfa2
NC
2591
2592#define ELF_ARCH bfd_arch_msp430
2593#define ELF_MACHINE_CODE EM_MSP430
2594#define ELF_MACHINE_ALT1 EM_MSP430_OLD
13761a11 2595#define ELF_MAXPAGESIZE 4
d1036acb 2596#define ELF_OSABI ELFOSABI_STANDALONE
2469cfa2 2597
07d6d2b8 2598#define TARGET_LITTLE_SYM msp430_elf32_vec
2469cfa2
NC
2599#define TARGET_LITTLE_NAME "elf32-msp430"
2600
07d6d2b8
AM
2601#define elf_info_to_howto msp430_info_to_howto_rela
2602#define elf_info_to_howto_rel NULL
2603#define elf_backend_relocate_section elf32_msp430_relocate_section
2604#define elf_backend_check_relocs elf32_msp430_check_relocs
2605#define elf_backend_can_gc_sections 1
2469cfa2
NC
2606#define elf_backend_final_write_processing bfd_elf_msp430_final_write_processing
2607#define elf_backend_object_p elf32_msp430_object_p
b18c562e 2608#define bfd_elf32_bfd_relax_section msp430_elf_relax_section
13761a11
NC
2609#define bfd_elf32_bfd_is_target_special_symbol msp430_elf_is_target_special_symbol
2610
07d6d2b8 2611#undef elf32_bed
13761a11
NC
2612#define elf32_bed elf32_msp430_bed
2613
2614#include "elf32-target.h"
2615
2616/* The TI compiler sets the OSABI field to ELFOSABI_NONE. */
07d6d2b8
AM
2617#undef TARGET_LITTLE_SYM
2618#define TARGET_LITTLE_SYM msp430_elf32_ti_vec
13761a11 2619
07d6d2b8 2620#undef elf32_bed
13761a11
NC
2621#define elf32_bed elf32_msp430_ti_bed
2622
1b786873 2623#undef ELF_OSABI
13761a11
NC
2624#define ELF_OSABI ELFOSABI_NONE
2625
2626static const struct bfd_elf_special_section msp430_ti_elf_special_sections[] =
2627{
07d6d2b8 2628 /* prefix, prefix_length, suffix_len, type, attributes. */
13761a11
NC
2629 { STRING_COMMA_LEN (".TI.symbol.alias"), 0, SHT_MSP430_SYM_ALIASES, 0 },
2630 { STRING_COMMA_LEN (".TI.section.flags"), 0, SHT_MSP430_SEC_FLAGS, 0 },
2631 { STRING_COMMA_LEN ("_TI_build_attrib"), 0, SHT_MSP430_ATTRIBUTES, 0 },
07d6d2b8 2632 { NULL, 0, 0, 0, 0 }
13761a11 2633};
2469cfa2 2634
07d6d2b8
AM
2635#undef elf_backend_special_sections
2636#define elf_backend_special_sections msp430_ti_elf_special_sections
b6518b38 2637
2469cfa2 2638#include "elf32-target.h"