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