]>
Commit | Line | Data |
---|---|---|
4cd5ba0f ER |
1 | diff -Nur bfd/archures.c bfd/archures.c |
2 | --- bfd/archures.c 2006-03-06 14:42:03.000000000 +0100 | |
3 | +++ bfd/archures.c 2006-08-28 20:01:10.714097550 +0200 | |
4 | @@ -334,6 +334,7 @@ | |
5 | .#define bfd_mach_avr3 3 | |
6 | .#define bfd_mach_avr4 4 | |
7 | .#define bfd_mach_avr5 5 | |
8 | +.#define bfd_mach_avr6 6 | |
9 | . bfd_arch_bfin, {* ADI Blackfin *} | |
10 | .#define bfd_mach_bfin 1 | |
11 | . bfd_arch_cr16c, {* National Semiconductor CompactRISC. *} | |
12 | diff -Nur bfd/bfd-in2.h bfd/bfd-in2.h | |
13 | --- bfd/bfd-in2.h 2006-03-26 01:38:42.000000000 +0100 | |
14 | +++ bfd/bfd-in2.h 2006-08-28 20:01:10.743095447 +0200 | |
15 | @@ -1931,6 +1931,7 @@ | |
16 | #define bfd_mach_avr3 3 | |
17 | #define bfd_mach_avr4 4 | |
18 | #define bfd_mach_avr5 5 | |
19 | +#define bfd_mach_avr6 6 | |
20 | bfd_arch_bfin, /* ADI Blackfin */ | |
21 | #define bfd_mach_bfin 1 | |
22 | bfd_arch_cr16c, /* National Semiconductor CompactRISC. */ | |
23 | @@ -3539,10 +3540,22 @@ | |
24 | command address) into 8 bit immediate value of LDI insn. */ | |
25 | BFD_RELOC_AVR_LO8_LDI_PM, | |
26 | ||
27 | +/* This is a 16 bit reloc for the AVR that stores 8 bit value | |
28 | +(command address) into 8 bit immediate value of LDI insn. If the address | |
29 | +is beyond the 128k boundary, the linker inserts a jump stub for this reloc | |
30 | +in the lower 128k. */ | |
31 | + BFD_RELOC_AVR_LO8_LDI_GS, | |
32 | + | |
33 | /* This is a 16 bit reloc for the AVR that stores 8 bit value (high 8 bit | |
34 | of command address) into 8 bit immediate value of LDI insn. */ | |
35 | BFD_RELOC_AVR_HI8_LDI_PM, | |
36 | ||
37 | +/* This is a 16 bit reloc for the AVR that stores 8 bit value (high 8 bit | |
38 | +of command address) into 8 bit immediate value of LDI insn. If the address | |
39 | +is beyond the 128k boundary, the linker inserts a jump stub for this reloc | |
40 | +below 128k. */ | |
41 | + BFD_RELOC_AVR_HI8_LDI_GS, | |
42 | + | |
43 | /* This is a 16 bit reloc for the AVR that stores 8 bit value (most high 8 bit | |
44 | of command address) into 8 bit immediate value of LDI insn. */ | |
45 | BFD_RELOC_AVR_HH8_LDI_PM, | |
46 | diff -Nur bfd/cpu-avr.c bfd/cpu-avr.c | |
47 | --- bfd/cpu-avr.c 2006-03-03 16:54:23.000000000 +0100 | |
48 | +++ bfd/cpu-avr.c 2006-08-28 20:01:10.771093417 +0200 | |
49 | @@ -82,7 +82,10 @@ | |
50 | N (16, bfd_mach_avr4, "avr:4", FALSE, & arch_info_struct[4]), | |
51 | ||
52 | /* ATmega161, ATmega163, ATmega32, AT94K. */ | |
53 | - N (22, bfd_mach_avr5, "avr:5", FALSE, NULL) | |
54 | + N (22, bfd_mach_avr5, "avr:5", FALSE, & arch_info_struct[5]), | |
55 | + | |
56 | + /* ATmega256x. */ | |
57 | + N (22, bfd_mach_avr6, "avr:6", FALSE, NULL) | |
58 | }; | |
59 | ||
60 | const bfd_arch_info_type bfd_avr_arch = | |
61 | diff -Nur bfd/elf32-avr.c bfd/elf32-avr.c | |
62 | --- bfd/elf32-avr.c 2006-03-03 16:54:23.000000000 +0100 | |
63 | +++ bfd/elf32-avr.c 2006-08-28 20:18:20.796399347 +0200 | |
64 | @@ -25,6 +25,92 @@ | |
65 | #include "libbfd.h" | |
66 | #include "elf-bfd.h" | |
67 | #include "elf/avr.h" | |
68 | +#include "elf32-avr.h" | |
69 | + | |
70 | +/* Enable debugging printout at stdout with this variable. */ | |
71 | +static bfd_boolean debug_relax = FALSE; | |
72 | + | |
73 | +/* Enable debugging printout at stdout with this variable. */ | |
74 | +static bfd_boolean debug_stubs = FALSE; | |
75 | + | |
76 | +/* Hash table initialization and handling. Code is taken from the hppa port | |
77 | + and adapted to the needs of AVR. */ | |
78 | + | |
79 | +/* We use two hash tables to hold information for linking avr objects. | |
80 | + | |
81 | + The first is the elf32_avr_link_hash_tablse which is derived from the | |
82 | + stanard ELF linker hash table. We use this as a place to attach the other | |
83 | + hash table and some static information. | |
84 | + | |
85 | + The second is the stub hash table which is derived from the base BFD | |
86 | + hash table. The stub hash table holds the information on the linker | |
87 | + stubs. */ | |
88 | + | |
89 | +struct elf32_avr_stub_hash_entry | |
90 | +{ | |
91 | + /* Base hash table entry structure. */ | |
92 | + struct bfd_hash_entry bh_root; | |
93 | + | |
94 | + /* Offset within stub_sec of the beginning of this stub. */ | |
95 | + bfd_vma stub_offset; | |
96 | + | |
97 | + /* Given the symbol's value and its section we can determine its final | |
98 | + value when building the stubs (so the stub knows where to jump). */ | |
99 | + bfd_vma target_value; | |
100 | + | |
101 | + /* This way we could mark stubs to be no longer necessary. */ | |
102 | + bfd_boolean is_actually_needed; | |
103 | +}; | |
104 | + | |
105 | +struct elf32_avr_link_hash_table | |
106 | +{ | |
107 | + /* The main hash table. */ | |
108 | + struct elf_link_hash_table etab; | |
109 | + | |
110 | + /* The stub hash table. */ | |
111 | + struct bfd_hash_table bstab; | |
112 | + | |
113 | + bfd_boolean no_stubs; | |
114 | + | |
115 | + /* Linker stub bfd. */ | |
116 | + bfd *stub_bfd; | |
117 | + | |
118 | + /* The stub section. */ | |
119 | + asection *stub_sec; | |
120 | + | |
121 | + /* Usually 0, unless we are generating code for a bootloader. Will | |
122 | + be initialized by elf32_avr_size_stubs to the vma offset of the | |
123 | + output section associated with the stub section. */ | |
124 | + bfd_vma vector_base; | |
125 | + | |
126 | + /* Assorted information used by elf32_avr_size_stubs. */ | |
127 | + unsigned int bfd_count; | |
128 | + int top_index; | |
129 | + asection ** input_list; | |
130 | + Elf_Internal_Sym ** all_local_syms; | |
131 | + | |
132 | + /* Tables for mapping vma beyond the 128k boundary to the address of the | |
133 | + corresponding stub. (AMT) | |
134 | + "amt_max_entry_cnt" reflects the number of entries that memory is allocated | |
135 | + for in the "amt_stub_offsets" and "amt_destination_addr" arrays. | |
136 | + "amt_entry_cnt" informs how many of these entries actually contain | |
137 | + useful data. */ | |
138 | + unsigned int amt_entry_cnt; | |
139 | + unsigned int amt_max_entry_cnt; | |
140 | + bfd_vma * amt_stub_offsets; | |
141 | + bfd_vma * amt_destination_addr; | |
142 | +}; | |
143 | + | |
144 | +/* Various hash macros and functions. */ | |
145 | +#define avr_link_hash_table(p) \ | |
146 | + ((struct elf32_avr_link_hash_table *) ((p)->hash)) | |
147 | + | |
148 | +#define avr_stub_hash_entry(ent) \ | |
149 | + ((struct elf32_avr_stub_hash_entry *)(ent)) | |
150 | + | |
151 | +#define avr_stub_hash_lookup(table, string, create, copy) \ | |
152 | + ((struct elf32_avr_stub_hash_entry *) \ | |
153 | + bfd_hash_lookup ((table), (string), (create), (copy))) | |
154 | ||
155 | static reloc_howto_type elf_avr_howto_table[] = | |
156 | { | |
157 | @@ -101,7 +187,8 @@ | |
158 | 0xffff, /* dst_mask */ | |
159 | FALSE), /* pcrel_offset */ | |
160 | ||
161 | - /* A 16 bit absolute relocation for command address. */ | |
162 | + /* A 16 bit absolute relocation for command address | |
163 | + Will be changed when linker stubs are needed. */ | |
164 | HOWTO (R_AVR_16_PM, /* type */ | |
165 | 1, /* rightshift */ | |
166 | 1, /* size (0 = byte, 1 = short, 2 = long) */ | |
167 | @@ -207,7 +294,7 @@ | |
168 | 0xffff, /* dst_mask */ | |
169 | FALSE), /* pcrel_offset */ | |
170 | /* A low 8 bit absolute relocation of 24 bit program memory address. | |
171 | - For LDI command. */ | |
172 | + For LDI command. Will not be changed when linker stubs are needed. */ | |
173 | HOWTO (R_AVR_LO8_LDI_PM, /* type */ | |
174 | 1, /* rightshift */ | |
175 | 1, /* size (0 = byte, 1 = short, 2 = long) */ | |
176 | @@ -221,8 +308,8 @@ | |
177 | 0xffff, /* src_mask */ | |
178 | 0xffff, /* dst_mask */ | |
179 | FALSE), /* pcrel_offset */ | |
180 | - /* A high 8 bit absolute relocation of 16 bit program memory address. | |
181 | - For LDI command. */ | |
182 | + /* A low 8 bit absolute relocation of 24 bit program memory address. | |
183 | + For LDI command. Will not be changed when linker stubs are needed. */ | |
184 | HOWTO (R_AVR_HI8_LDI_PM, /* type */ | |
185 | 9, /* rightshift */ | |
186 | 1, /* size (0 = byte, 1 = short, 2 = long) */ | |
187 | @@ -236,8 +323,8 @@ | |
188 | 0xffff, /* src_mask */ | |
189 | 0xffff, /* dst_mask */ | |
190 | FALSE), /* pcrel_offset */ | |
191 | - /* A high 8 bit absolute relocation of 24 bit program memory address. | |
192 | - For LDI command. */ | |
193 | + /* A low 8 bit absolute relocation of 24 bit program memory address. | |
194 | + For LDI command. Will not be changed when linker stubs are needed. */ | |
195 | HOWTO (R_AVR_HH8_LDI_PM, /* type */ | |
196 | 17, /* rightshift */ | |
197 | 1, /* size (0 = byte, 1 = short, 2 = long) */ | |
198 | @@ -251,8 +338,8 @@ | |
199 | 0xffff, /* src_mask */ | |
200 | 0xffff, /* dst_mask */ | |
201 | FALSE), /* pcrel_offset */ | |
202 | - /* A low 8 bit absolute relocation of a negative 24 bit | |
203 | - program memory address. For LDI command. */ | |
204 | + /* A low 8 bit absolute relocation of 24 bit program memory address. | |
205 | + For LDI command. Will not be changed when linker stubs are needed. */ | |
206 | HOWTO (R_AVR_LO8_LDI_PM_NEG, /* type */ | |
207 | 1, /* rightshift */ | |
208 | 1, /* size (0 = byte, 1 = short, 2 = long) */ | |
209 | @@ -266,8 +353,8 @@ | |
210 | 0xffff, /* src_mask */ | |
211 | 0xffff, /* dst_mask */ | |
212 | FALSE), /* pcrel_offset */ | |
213 | - /* A high 8 bit absolute relocation of a negative 16 bit | |
214 | - program memory address. For LDI command. */ | |
215 | + /* A low 8 bit absolute relocation of 24 bit program memory address. | |
216 | + For LDI command. Will not be changed when linker stubs are needed. */ | |
217 | HOWTO (R_AVR_HI8_LDI_PM_NEG, /* type */ | |
218 | 9, /* rightshift */ | |
219 | 1, /* size (0 = byte, 1 = short, 2 = long) */ | |
220 | @@ -281,8 +368,8 @@ | |
221 | 0xffff, /* src_mask */ | |
222 | 0xffff, /* dst_mask */ | |
223 | FALSE), /* pcrel_offset */ | |
224 | - /* A high 8 bit absolute relocation of a negative 24 bit | |
225 | - program memory address. For LDI command. */ | |
226 | + /* A low 8 bit absolute relocation of 24 bit program memory address. | |
227 | + For LDI command. Will not be changed when linker stubs are needed. */ | |
228 | HOWTO (R_AVR_HH8_LDI_PM_NEG, /* type */ | |
229 | 17, /* rightshift */ | |
230 | 1, /* size (0 = byte, 1 = short, 2 = long) */ | |
231 | @@ -382,7 +469,37 @@ | |
232 | FALSE, /* partial_inplace */ | |
233 | 0xffff, /* src_mask */ | |
234 | 0xffff, /* dst_mask */ | |
235 | - FALSE) /* pcrel_offset */ | |
236 | + FALSE), /* pcrel_offset */ | |
237 | + /* A low 8 bit absolute relocation of 24 bit program memory address. | |
238 | + For LDI command. Will be changed when linker stubs are needed. */ | |
239 | + HOWTO (R_AVR_LO8_LDI_GS, /* type */ | |
240 | + 1, /* rightshift */ | |
241 | + 1, /* size (0 = byte, 1 = short, 2 = long) */ | |
242 | + 8, /* bitsize */ | |
243 | + FALSE, /* pc_relative */ | |
244 | + 0, /* bitpos */ | |
245 | + complain_overflow_dont, /* complain_on_overflow */ | |
246 | + bfd_elf_generic_reloc, /* special_function */ | |
247 | + "R_AVR_LO8_LDI_GS", /* name */ | |
248 | + FALSE, /* partial_inplace */ | |
249 | + 0xffff, /* src_mask */ | |
250 | + 0xffff, /* dst_mask */ | |
251 | + FALSE), /* pcrel_offset */ | |
252 | + /* A low 8 bit absolute relocation of 24 bit program memory address. | |
253 | + For LDI command. Will be changed when linker stubs are needed. */ | |
254 | + HOWTO (R_AVR_HI8_LDI_GS, /* type */ | |
255 | + 9, /* rightshift */ | |
256 | + 1, /* size (0 = byte, 1 = short, 2 = long) */ | |
257 | + 8, /* bitsize */ | |
258 | + FALSE, /* pc_relative */ | |
259 | + 0, /* bitpos */ | |
260 | + complain_overflow_dont, /* complain_on_overflow */ | |
261 | + bfd_elf_generic_reloc, /* special_function */ | |
262 | + "R_AVR_HI8_LDI_GS", /* name */ | |
263 | + FALSE, /* partial_inplace */ | |
264 | + 0xffff, /* src_mask */ | |
265 | + 0xffff, /* dst_mask */ | |
266 | + FALSE) /* pcrel_offset */ | |
267 | }; | |
268 | ||
269 | /* Map BFD reloc types to AVR ELF reloc types. */ | |
270 | @@ -393,7 +510,7 @@ | |
271 | unsigned int elf_reloc_val; | |
272 | }; | |
273 | ||
274 | - static const struct avr_reloc_map avr_reloc_map[] = | |
275 | +static const struct avr_reloc_map avr_reloc_map[] = | |
276 | { | |
277 | { BFD_RELOC_NONE, R_AVR_NONE }, | |
278 | { BFD_RELOC_32, R_AVR_32 }, | |
279 | @@ -410,7 +527,9 @@ | |
280 | { BFD_RELOC_AVR_HH8_LDI_NEG, R_AVR_HH8_LDI_NEG }, | |
281 | { BFD_RELOC_AVR_MS8_LDI_NEG, R_AVR_MS8_LDI_NEG }, | |
282 | { BFD_RELOC_AVR_LO8_LDI_PM, R_AVR_LO8_LDI_PM }, | |
283 | + { BFD_RELOC_AVR_LO8_LDI_GS, R_AVR_LO8_LDI_GS }, | |
284 | { BFD_RELOC_AVR_HI8_LDI_PM, R_AVR_HI8_LDI_PM }, | |
285 | + { BFD_RELOC_AVR_HI8_LDI_GS, R_AVR_HI8_LDI_GS }, | |
286 | { BFD_RELOC_AVR_HH8_LDI_PM, R_AVR_HH8_LDI_PM }, | |
287 | { BFD_RELOC_AVR_LO8_LDI_PM_NEG, R_AVR_LO8_LDI_PM_NEG }, | |
288 | { BFD_RELOC_AVR_HI8_LDI_PM_NEG, R_AVR_HI8_LDI_PM_NEG }, | |
289 | @@ -429,8 +548,101 @@ | |
290 | that we will never suggest a wrap-around jump during relaxation. | |
291 | The logic of the source code later on assumes that in | |
292 | avr_pc_wrap_around one single bit is set. */ | |
293 | +static bfd_vma avr_pc_wrap_around = 0x10000000; | |
294 | + | |
295 | +/* If this variable holds a value different from zero, the linker relaxation | |
296 | + machine will try to optimize call/ret sequences by a single jump | |
297 | + instruction. This option could be switched off by a linker switch. */ | |
298 | +static int avr_replace_call_ret_sequences = 1; | |
299 | +\f | |
300 | +/* Initialize an entry in the stub hash table. */ | |
301 | + | |
302 | +static struct bfd_hash_entry * | |
303 | +stub_hash_newfunc (struct bfd_hash_entry *entry, | |
304 | + struct bfd_hash_table *table, | |
305 | + const char *string) | |
306 | +{ | |
307 | + /* Allocate the structure if it has not already been allocated by a | |
308 | + subclass. */ | |
309 | + if (entry == NULL) | |
310 | + { | |
311 | + entry = bfd_hash_allocate (table, | |
312 | + sizeof (struct elf32_avr_stub_hash_entry)); | |
313 | + if (entry == NULL) | |
314 | + return entry; | |
315 | + } | |
316 | + | |
317 | + /* Call the allocation method of the superclass. */ | |
318 | + entry = bfd_hash_newfunc (entry, table, string); | |
319 | + if (entry != NULL) | |
320 | + { | |
321 | + struct elf32_avr_stub_hash_entry *hsh; | |
322 | ||
323 | -unsigned int avr_pc_wrap_around = 0x10000000; | |
324 | + /* Initialize the local fields. */ | |
325 | + hsh = avr_stub_hash_entry (entry); | |
326 | + hsh->stub_offset = 0; | |
327 | + hsh->target_value = 0; | |
328 | + } | |
329 | + | |
330 | + return entry; | |
331 | +} | |
332 | + | |
333 | +/* Create the derived linker hash table. The AVR ELF port uses the derived | |
334 | + hash table to keep information specific to the AVR ELF linker (without | |
335 | + using static variables). */ | |
336 | + | |
337 | +static struct bfd_link_hash_table * | |
338 | +elf32_avr_link_hash_table_create (bfd *abfd) | |
339 | +{ | |
340 | + struct elf32_avr_link_hash_table *htab; | |
341 | + bfd_size_type amt = sizeof (*htab); | |
342 | + | |
343 | + htab = bfd_malloc (amt); | |
344 | + if (htab == NULL) | |
345 | + return NULL; | |
346 | + | |
347 | + if (!_bfd_elf_link_hash_table_init (&htab->etab, abfd, | |
348 | + _bfd_elf_link_hash_newfunc, | |
349 | + sizeof (struct elf_link_hash_entry))) | |
350 | + { | |
351 | + free (htab); | |
352 | + return NULL; | |
353 | + } | |
354 | + | |
355 | + /* Init the stub hash table too. */ | |
356 | + if (!bfd_hash_table_init (&htab->bstab, stub_hash_newfunc, | |
357 | + sizeof (struct elf32_avr_stub_hash_entry))) | |
358 | + return NULL; | |
359 | + | |
360 | + htab->stub_bfd = NULL; | |
361 | + htab->stub_sec = NULL; | |
362 | + | |
363 | + /* Initialize the address mapping table. */ | |
364 | + htab->amt_stub_offsets = NULL; | |
365 | + htab->amt_destination_addr = NULL; | |
366 | + htab->amt_entry_cnt = 0; | |
367 | + htab->amt_max_entry_cnt = 0; | |
368 | + | |
369 | + return &htab->etab.root; | |
370 | +} | |
371 | + | |
372 | +/* Free the derived linker hash table. */ | |
373 | + | |
374 | +static void | |
375 | +elf32_avr_link_hash_table_free (struct bfd_link_hash_table *btab) | |
376 | +{ | |
377 | + struct elf32_avr_link_hash_table *htab | |
378 | + = (struct elf32_avr_link_hash_table *) btab; | |
379 | + | |
380 | + /* Free the address mapping table. */ | |
381 | + if (htab->amt_stub_offsets != NULL) | |
382 | + free (htab->amt_stub_offsets); | |
383 | + if (htab->amt_destination_addr != NULL) | |
384 | + free (htab->amt_destination_addr); | |
385 | + | |
386 | + bfd_hash_table_free (&htab->bstab); | |
387 | + _bfd_generic_link_hash_table_free (btab); | |
388 | +} | |
389 | ||
390 | /* Calculates the effective distance of a pc relative jump/call. */ | |
391 | static int | |
392 | @@ -564,20 +776,57 @@ | |
393 | return TRUE; | |
394 | } | |
395 | ||
396 | +static bfd_boolean | |
397 | +avr_stub_is_required_for_16_bit_reloc (bfd_vma relocation) | |
398 | +{ | |
399 | + return (relocation >= 0x020000); | |
400 | +} | |
401 | + | |
402 | +/* Returns the address of the corresponding stub if there is one. | |
403 | + Returns otherwise an address above 0x020000. This function | |
404 | + could also be used, if there is no knowledge on the section where | |
405 | + the destination is found. */ | |
406 | + | |
407 | +static bfd_vma | |
408 | +avr_get_stub_addr (bfd_vma srel, | |
409 | + struct elf32_avr_link_hash_table *htab) | |
410 | +{ | |
411 | + unsigned int index; | |
412 | + bfd_vma stub_sec_addr = | |
413 | + (htab->stub_sec->output_section->vma + | |
414 | + htab->stub_sec->output_offset); | |
415 | + | |
416 | + for (index = 0; index < htab->amt_max_entry_cnt; index ++) | |
417 | + if (htab->amt_destination_addr[index] == srel) | |
418 | + return htab->amt_stub_offsets[index] + stub_sec_addr; | |
419 | + | |
420 | + /* Return an address that could not be reached by 16 bit relocs. */ | |
421 | + return 0x020000; | |
422 | +} | |
423 | + | |
424 | /* Perform a single relocation. By default we use the standard BFD | |
425 | routines, but a few relocs, we have to do them ourselves. */ | |
426 | ||
427 | static bfd_reloc_status_type | |
428 | -avr_final_link_relocate (reloc_howto_type * howto, | |
429 | - bfd * input_bfd, | |
430 | - asection * input_section, | |
431 | - bfd_byte * contents, | |
432 | - Elf_Internal_Rela * rel, | |
433 | - bfd_vma relocation) | |
434 | +avr_final_link_relocate (reloc_howto_type * howto, | |
435 | + bfd * input_bfd, | |
436 | + asection * input_section, | |
437 | + bfd_byte * contents, | |
438 | + Elf_Internal_Rela * rel, | |
439 | + bfd_vma relocation, | |
440 | + struct elf32_avr_link_hash_table * htab) | |
441 | { | |
442 | bfd_reloc_status_type r = bfd_reloc_ok; | |
443 | bfd_vma x; | |
444 | bfd_signed_vma srel; | |
445 | + bfd_signed_vma reloc_addr; | |
446 | + bfd_boolean use_stubs = FALSE; | |
447 | + /* Usually is 0, unless we are generating code for a bootloader. */ | |
448 | + bfd_signed_vma base_addr = htab->vector_base; | |
449 | + | |
450 | + /* Absolute addr of the reloc in the final excecutable. */ | |
451 | + reloc_addr = rel->r_offset + input_section->output_section->vma | |
452 | + + input_section->output_offset; | |
453 | ||
454 | switch (howto->type) | |
455 | { | |
456 | @@ -748,9 +997,31 @@ | |
457 | bfd_put_16 (input_bfd, x, contents); | |
458 | break; | |
459 | ||
460 | + case R_AVR_LO8_LDI_GS: | |
461 | + use_stubs = (!htab->no_stubs); | |
462 | + /* Fall through. */ | |
463 | case R_AVR_LO8_LDI_PM: | |
464 | contents += rel->r_offset; | |
465 | srel = (bfd_signed_vma) relocation + rel->r_addend; | |
466 | + | |
467 | + if (use_stubs | |
468 | + && avr_stub_is_required_for_16_bit_reloc (srel - base_addr)) | |
469 | + { | |
470 | + bfd_vma old_srel = srel; | |
471 | + | |
472 | + /* We need to use the address of the stub instead. */ | |
473 | + srel = avr_get_stub_addr (srel, htab); | |
474 | + if (debug_stubs) | |
475 | + printf ("LD: Using jump stub (at 0x%x) with destination 0x%x for " | |
476 | + "reloc at address 0x%x.\n", | |
477 | + (unsigned int) srel, | |
478 | + (unsigned int) old_srel, | |
479 | + (unsigned int) reloc_addr); | |
480 | + | |
481 | + if (avr_stub_is_required_for_16_bit_reloc (srel - base_addr)) | |
482 | + return bfd_reloc_outofrange; | |
483 | + } | |
484 | + | |
485 | if (srel & 1) | |
486 | return bfd_reloc_outofrange; | |
487 | srel = srel >> 1; | |
488 | @@ -759,9 +1030,31 @@ | |
489 | bfd_put_16 (input_bfd, x, contents); | |
490 | break; | |
491 | ||
492 | + case R_AVR_HI8_LDI_GS: | |
493 | + use_stubs = (!htab->no_stubs); | |
494 | + /* Fall through. */ | |
495 | case R_AVR_HI8_LDI_PM: | |
496 | contents += rel->r_offset; | |
497 | srel = (bfd_signed_vma) relocation + rel->r_addend; | |
498 | + | |
499 | + if (use_stubs | |
500 | + && avr_stub_is_required_for_16_bit_reloc (srel - base_addr)) | |
501 | + { | |
502 | + bfd_vma old_srel = srel; | |
503 | + | |
504 | + /* We need to use the address of the stub instead. */ | |
505 | + srel = avr_get_stub_addr (srel, htab); | |
506 | + if (debug_stubs) | |
507 | + printf ("LD: Using jump stub (at 0x%x) with destination 0x%x for " | |
508 | + "reloc at address 0x%x.\n", | |
509 | + (unsigned int) srel, | |
510 | + (unsigned int) old_srel, | |
511 | + (unsigned int) reloc_addr); | |
512 | + | |
513 | + if (avr_stub_is_required_for_16_bit_reloc (srel - base_addr)) | |
514 | + return bfd_reloc_outofrange; | |
515 | + } | |
516 | + | |
517 | if (srel & 1) | |
518 | return bfd_reloc_outofrange; | |
519 | srel = srel >> 1; | |
520 | @@ -833,6 +1126,35 @@ | |
521 | bfd_put_16 (input_bfd, (bfd_vma) srel & 0xffff, contents+2); | |
522 | break; | |
523 | ||
524 | + case R_AVR_16_PM: | |
525 | + use_stubs = (!htab->no_stubs); | |
526 | + contents += rel->r_offset; | |
527 | + srel = (bfd_signed_vma) relocation + rel->r_addend; | |
528 | + | |
529 | + if (use_stubs | |
530 | + && avr_stub_is_required_for_16_bit_reloc (srel - base_addr)) | |
531 | + { | |
532 | + bfd_vma old_srel = srel; | |
533 | + | |
534 | + /* We need to use the address of the stub instead. */ | |
535 | + srel = avr_get_stub_addr (srel,htab); | |
536 | + if (debug_stubs) | |
537 | + printf ("LD: Using jump stub (at 0x%x) with destination 0x%x for " | |
538 | + "reloc at address 0x%x.\n", | |
539 | + (unsigned int) srel, | |
540 | + (unsigned int) old_srel, | |
541 | + (unsigned int) reloc_addr); | |
542 | + | |
543 | + if (avr_stub_is_required_for_16_bit_reloc (srel - base_addr)) | |
544 | + return bfd_reloc_outofrange; | |
545 | + } | |
546 | + | |
547 | + if (srel & 1) | |
548 | + return bfd_reloc_outofrange; | |
549 | + srel = srel >> 1; | |
550 | + bfd_put_16 (input_bfd, (bfd_vma) srel &0x00ffff, contents); | |
551 | + break; | |
552 | + | |
553 | default: | |
554 | r = _bfd_final_link_relocate (howto, input_bfd, input_section, | |
555 | contents, rel->r_offset, | |
556 | @@ -858,6 +1180,7 @@ | |
557 | struct elf_link_hash_entry ** sym_hashes; | |
558 | Elf_Internal_Rela * rel; | |
559 | Elf_Internal_Rela * relend; | |
560 | + struct elf32_avr_link_hash_table * htab = avr_link_hash_table (info); | |
561 | ||
562 | if (info->relocatable) | |
563 | return TRUE; | |
564 | @@ -909,7 +1232,7 @@ | |
565 | } | |
566 | ||
567 | r = avr_final_link_relocate (howto, input_bfd, input_section, | |
568 | - contents, rel, relocation); | |
569 | + contents, rel, relocation, htab); | |
570 | ||
571 | if (r != bfd_reloc_ok) | |
572 | { | |
573 | @@ -990,6 +1313,10 @@ | |
574 | case bfd_mach_avr5: | |
575 | val = E_AVR_MACH_AVR5; | |
576 | break; | |
577 | + | |
578 | + case bfd_mach_avr6: | |
579 | + val = E_AVR_MACH_AVR6; | |
580 | + break; | |
581 | } | |
582 | ||
583 | elf_elfheader (abfd)->e_machine = EM_AVR; | |
584 | @@ -1032,6 +1359,10 @@ | |
585 | case E_AVR_MACH_AVR5: | |
586 | e_set = bfd_mach_avr5; | |
587 | break; | |
588 | + | |
589 | + case E_AVR_MACH_AVR6: | |
590 | + e_set = bfd_mach_avr6; | |
591 | + break; | |
592 | } | |
593 | } | |
594 | return bfd_default_set_arch_mach (abfd, bfd_arch_avr, | |
595 | @@ -1039,9 +1370,6 @@ | |
596 | } | |
597 | ||
598 | ||
599 | -/* Enable debugging printout at stdout with a value of 1. */ | |
600 | -#define DEBUG_RELAX 0 | |
601 | - | |
602 | /* Delete some bytes from a section while changing the size of an instruction. | |
603 | The parameter "addr" denotes the section-relative offset pointing just | |
604 | behind the shrinked instruction. "addr+count" point at the first | |
605 | @@ -1101,7 +1429,7 @@ | |
606 | if ((irel->r_offset > addr | |
607 | && irel->r_offset < toaddr)) | |
608 | { | |
609 | - if (DEBUG_RELAX) | |
610 | + if (debug_relax) | |
611 | printf ("Relocation at address 0x%x needs to be moved.\n" | |
612 | "Old section offset: 0x%x, New section offset: 0x%x \n", | |
613 | (unsigned int) old_reloc_address, | |
614 | @@ -1148,7 +1476,7 @@ | |
615 | symval += sym_sec->output_section->vma | |
616 | + sym_sec->output_offset; | |
617 | ||
618 | - if (DEBUG_RELAX) | |
619 | + if (debug_relax) | |
620 | printf ("Checking if the relocation's " | |
621 | "addend needs corrections.\n" | |
622 | "Address of anchor symbol: 0x%x \n" | |
623 | @@ -1163,7 +1491,7 @@ | |
624 | { | |
625 | irel->r_addend -= count; | |
626 | ||
627 | - if (DEBUG_RELAX) | |
628 | + if (debug_relax) | |
629 | printf ("Anchor symbol and relocation target bracket " | |
630 | "shrinked insn address.\n" | |
631 | "Need for new addend : 0x%x\n", | |
632 | @@ -1238,7 +1566,7 @@ | |
633 | contains 4-byte jump instructions whose relative offset must not | |
634 | be changed. */ | |
635 | ||
636 | -static bfd_boolean | |
637 | +static bfd_boolean | |
638 | elf32_avr_relax_section (bfd *abfd, | |
639 | asection *sec, | |
640 | struct bfd_link_info *link_info, | |
641 | @@ -1251,10 +1579,37 @@ | |
642 | Elf_Internal_Sym *isymbuf = NULL; | |
643 | static asection *last_input_section = NULL; | |
644 | static Elf_Internal_Rela *last_reloc = NULL; | |
645 | + struct elf32_avr_link_hash_table *htab; | |
646 | + | |
647 | + htab = avr_link_hash_table (link_info); | |
648 | ||
649 | /* Assume nothing changes. */ | |
650 | *again = FALSE; | |
651 | ||
652 | + if ((!htab->no_stubs) && (sec == htab->stub_sec)) | |
653 | + { | |
654 | + /* We are just relaxing the stub section. | |
655 | + Let's calculate the size needed again. */ | |
656 | + bfd_size_type last_estimated_stub_section_size = htab->stub_sec->size; | |
657 | + | |
658 | + if (debug_relax) | |
659 | + printf ("Relaxing the stub section. Size prior to this pass: %i\n", | |
660 | + (int) last_estimated_stub_section_size); | |
661 | + | |
662 | + elf32_avr_size_stubs (htab->stub_sec->output_section->owner, | |
663 | + link_info, FALSE); | |
664 | + | |
665 | + /* Check if the number of trampolines changed. */ | |
666 | + if (last_estimated_stub_section_size != htab->stub_sec->size) | |
667 | + *again = TRUE; | |
668 | + | |
669 | + if (debug_relax) | |
670 | + printf ("Size of stub section after this pass: %i\n", | |
671 | + (int) htab->stub_sec->size); | |
672 | + | |
673 | + return TRUE; | |
674 | + } | |
675 | + | |
676 | /* We don't have to do anything for a relocatable link, if | |
677 | this section does not have relocs, or if this is not a | |
678 | code section. */ | |
679 | @@ -1421,7 +1776,7 @@ | |
680 | unsigned char code_msb; | |
681 | unsigned char code_lsb; | |
682 | ||
683 | - if (DEBUG_RELAX) | |
684 | + if (debug_relax) | |
685 | printf ("shrinking jump/call instruction at address 0x%x" | |
686 | " in section %s\n\n", | |
687 | (int) dot, sec->name); | |
688 | @@ -1496,8 +1851,9 @@ | |
689 | + sec->output_offset + irel->r_offset); | |
690 | ||
691 | /* Here we look for rcall/ret or call/ret sequences that could be | |
692 | - safely replaced by rjmp/ret or jmp/ret */ | |
693 | - if (0xd0 == (code_msb & 0xf0)) | |
694 | + safely replaced by rjmp/ret or jmp/ret. */ | |
695 | + if (((code_msb & 0xf0) == 0xd0) | |
696 | + && avr_replace_call_ret_sequences) | |
697 | { | |
698 | /* This insn is a rcall. */ | |
699 | unsigned char next_insn_msb = 0; | |
700 | @@ -1517,7 +1873,7 @@ | |
701 | into a rjmp instruction. */ | |
702 | code_msb &= 0xef; | |
703 | bfd_put_8 (abfd, code_msb, contents + irel->r_offset + 1); | |
704 | - if (DEBUG_RELAX) | |
705 | + if (debug_relax) | |
706 | printf ("converted rcall/ret sequence at address 0x%x" | |
707 | " into rjmp/ret sequence. Section is %s\n\n", | |
708 | (int) dot, sec->name); | |
709 | @@ -1526,7 +1882,8 @@ | |
710 | } | |
711 | } | |
712 | else if ((0x94 == (code_msb & 0xfe)) | |
713 | - && (0x0e == (code_lsb & 0x0e))) | |
714 | + && (0x0e == (code_lsb & 0x0e)) | |
715 | + && avr_replace_call_ret_sequences) | |
716 | { | |
717 | /* This insn is a call. */ | |
718 | unsigned char next_insn_msb = 0; | |
719 | @@ -1547,7 +1904,7 @@ | |
720 | ||
721 | code_lsb &= 0xfd; | |
722 | bfd_put_8 (abfd, code_lsb, contents + irel->r_offset); | |
723 | - if (DEBUG_RELAX) | |
724 | + if (debug_relax) | |
725 | printf ("converted call/ret sequence at address 0x%x" | |
726 | " into jmp/ret sequence. Section is %s\n\n", | |
727 | (int) dot, sec->name); | |
728 | @@ -1590,10 +1947,10 @@ | |
729 | ||
730 | address_of_ret = dot + insn_size; | |
731 | ||
732 | - if (DEBUG_RELAX && (insn_size == 2)) | |
733 | + if (debug_relax && (insn_size == 2)) | |
734 | printf ("found rjmp / ret sequence at address 0x%x\n", | |
735 | (int) dot); | |
736 | - if (DEBUG_RELAX && (insn_size == 4)) | |
737 | + if (debug_relax && (insn_size == 4)) | |
738 | printf ("found jmp / ret sequence at address 0x%x\n", | |
739 | (int) dot); | |
740 | ||
741 | @@ -1630,7 +1987,7 @@ | |
742 | there_is_preceeding_non_skip_insn = 0; | |
743 | ||
744 | if (there_is_preceeding_non_skip_insn == 0) | |
745 | - if (DEBUG_RELAX) | |
746 | + if (debug_relax) | |
747 | printf ("preceeding skip insn prevents deletion of" | |
748 | " ret insn at addr 0x%x in section %s\n", | |
749 | (int) dot + 2, sec->name); | |
750 | @@ -1666,7 +2023,7 @@ | |
751 | && isym->st_shndx == sec_shndx) | |
752 | { | |
753 | deleting_ret_is_safe = 0; | |
754 | - if (DEBUG_RELAX) | |
755 | + if (debug_relax) | |
756 | printf ("local label prevents deletion of ret " | |
757 | "insn at address 0x%x\n", | |
758 | (int) dot + insn_size); | |
759 | @@ -1695,7 +2052,7 @@ | |
760 | && sym_hash->root.u.def.value == section_offset_of_ret_insn) | |
761 | { | |
762 | deleting_ret_is_safe = 0; | |
763 | - if (DEBUG_RELAX) | |
764 | + if (debug_relax) | |
765 | printf ("global label prevents deletion of " | |
766 | "ret insn at address 0x%x\n", | |
767 | (int) dot + insn_size); | |
768 | @@ -1772,7 +2129,7 @@ | |
769 | if (address_of_ret == reloc_target) | |
770 | { | |
771 | deleting_ret_is_safe = 0; | |
772 | - if (DEBUG_RELAX) | |
773 | + if (debug_relax) | |
774 | printf ("ret from " | |
775 | "rjmp/jmp ret sequence at address" | |
776 | " 0x%x could not be deleted. ret" | |
777 | @@ -1784,7 +2141,7 @@ | |
778 | ||
779 | if (deleting_ret_is_safe) | |
780 | { | |
781 | - if (DEBUG_RELAX) | |
782 | + if (debug_relax) | |
783 | printf ("unreachable ret instruction " | |
784 | "at address 0x%x deleted.\n", | |
785 | (int) dot + insn_size); | |
786 | @@ -1952,6 +2309,614 @@ | |
787 | } | |
788 | ||
789 | ||
790 | +/* Determines the hash entry name for a particular reloc. It consists of | |
791 | + the identifier of the symbol section and the added reloc addend and | |
792 | + symbol offset relative to the section the symbol is attached to. */ | |
793 | + | |
794 | +static char * | |
795 | +avr_stub_name (const asection *symbol_section, | |
796 | + const bfd_vma symbol_offset, | |
797 | + const Elf_Internal_Rela *rela) | |
798 | +{ | |
799 | + char *stub_name; | |
800 | + bfd_size_type len; | |
801 | + | |
802 | + len = 8 + 1 + 8 + 1 + 1; | |
803 | + stub_name = bfd_malloc (len); | |
804 | + | |
805 | + sprintf (stub_name, "%08x+%08x", | |
806 | + symbol_section->id & 0xffffffff, | |
807 | + (unsigned int) ((rela->r_addend & 0xffffffff) + symbol_offset)); | |
808 | + | |
809 | + return stub_name; | |
810 | +} | |
811 | + | |
812 | + | |
813 | +/* Add a new stub entry to the stub hash. Not all fields of the new | |
814 | + stub entry are initialised. */ | |
815 | + | |
816 | +static struct elf32_avr_stub_hash_entry * | |
817 | +avr_add_stub (const char *stub_name, | |
818 | + struct elf32_avr_link_hash_table *htab) | |
819 | +{ | |
820 | + struct elf32_avr_stub_hash_entry *hsh; | |
821 | + | |
822 | + /* Enter this entry into the linker stub hash table. */ | |
823 | + hsh = avr_stub_hash_lookup (&htab->bstab, stub_name, TRUE, FALSE); | |
824 | + | |
825 | + if (hsh == NULL) | |
826 | + { | |
827 | + (*_bfd_error_handler) (_("%B: cannot create stub entry %s"), | |
828 | + NULL, stub_name); | |
829 | + return NULL; | |
830 | + } | |
831 | + | |
832 | + hsh->stub_offset = 0; | |
833 | + return hsh; | |
834 | +} | |
835 | + | |
836 | +/* We assume that there is already space allocated for the stub section | |
837 | + contents and that before building the stubs the section size is | |
838 | + initialized to 0. We assume that within the stub hash table entry, | |
839 | + the absolute position of the jmp target has been written in the | |
840 | + target_value field. We write here the offset of the generated jmp insn | |
841 | + relative to the trampoline section start to the stub_offset entry in | |
842 | + the stub hash table entry. */ | |
843 | + | |
844 | +static bfd_boolean | |
845 | +avr_build_one_stub (struct bfd_hash_entry *bh, void *in_arg) | |
846 | +{ | |
847 | + struct elf32_avr_stub_hash_entry *hsh; | |
848 | + struct bfd_link_info *info; | |
849 | + struct elf32_avr_link_hash_table *htab; | |
850 | + bfd *stub_bfd; | |
851 | + bfd_byte *loc; | |
852 | + bfd_vma target; | |
853 | + bfd_vma starget; | |
854 | + | |
855 | + /* Basic opcode */ | |
856 | + bfd_vma jmp_insn = 0x0000940c; | |
857 | + | |
858 | + /* Massage our args to the form they really have. */ | |
859 | + hsh = avr_stub_hash_entry (bh); | |
860 | + | |
861 | + if (!hsh->is_actually_needed) | |
862 | + return TRUE; | |
863 | + | |
864 | + info = (struct bfd_link_info *) in_arg; | |
865 | + | |
866 | + htab = avr_link_hash_table (info); | |
867 | + | |
868 | + target = hsh->target_value; | |
869 | + | |
870 | + /* Make a note of the offset within the stubs for this entry. */ | |
871 | + hsh->stub_offset = htab->stub_sec->size; | |
872 | + loc = htab->stub_sec->contents + hsh->stub_offset; | |
873 | + | |
874 | + stub_bfd = htab->stub_sec->owner; | |
875 | + | |
876 | + if (debug_stubs) | |
877 | + printf ("Building one Stub. Address: 0x%x, Offset: 0x%x\n", | |
878 | + (unsigned int) target, | |
879 | + (unsigned int) hsh->stub_offset); | |
880 | + | |
881 | + /* We now have to add the information on the jump target to the bare | |
882 | + opcode bits already set in jmp_insn. */ | |
883 | + | |
884 | + /* Check for the alignment of the address. */ | |
885 | + if (target & 1) | |
886 | + return FALSE; | |
887 | + | |
888 | + starget = target >> 1; | |
889 | + jmp_insn |= ((starget & 0x10000) | ((starget << 3) & 0x1f00000)) >> 16; | |
890 | + bfd_put_16 (stub_bfd, jmp_insn, loc); | |
891 | + bfd_put_16 (stub_bfd, (bfd_vma) starget & 0xffff, loc + 2); | |
892 | + | |
893 | + htab->stub_sec->size += 4; | |
894 | + | |
895 | + /* Now add the entries in the address mapping table if there is still | |
896 | + space left. */ | |
897 | + { | |
898 | + unsigned int nr; | |
899 | + | |
900 | + nr = htab->amt_entry_cnt + 1; | |
901 | + if (nr <= htab->amt_max_entry_cnt) | |
902 | + { | |
903 | + htab->amt_entry_cnt = nr; | |
904 | + | |
905 | + htab->amt_stub_offsets[nr - 1] = hsh->stub_offset; | |
906 | + htab->amt_destination_addr[nr - 1] = target; | |
907 | + } | |
908 | + } | |
909 | + | |
910 | + return TRUE; | |
911 | +} | |
912 | + | |
913 | +static bfd_boolean | |
914 | +avr_mark_stub_not_to_be_necessary (struct bfd_hash_entry *bh, | |
915 | + void *in_arg) | |
916 | +{ | |
917 | + struct elf32_avr_stub_hash_entry *hsh; | |
918 | + struct elf32_avr_link_hash_table *htab; | |
919 | + | |
920 | + htab = in_arg; | |
921 | + hsh = avr_stub_hash_entry (bh); | |
922 | + hsh->is_actually_needed = FALSE; | |
923 | + | |
924 | + return TRUE; | |
925 | +} | |
926 | + | |
927 | +static bfd_boolean | |
928 | +avr_size_one_stub (struct bfd_hash_entry *bh, void *in_arg) | |
929 | +{ | |
930 | + struct elf32_avr_stub_hash_entry *hsh; | |
931 | + struct elf32_avr_link_hash_table *htab; | |
932 | + int size; | |
933 | + | |
934 | + /* Massage our args to the form they really have. */ | |
935 | + hsh = avr_stub_hash_entry (bh); | |
936 | + htab = in_arg; | |
937 | + | |
938 | + if (hsh->is_actually_needed) | |
939 | + size = 4; | |
940 | + else | |
941 | + size = 0; | |
942 | + | |
943 | + htab->stub_sec->size += size; | |
944 | + return TRUE; | |
945 | +} | |
946 | + | |
947 | +void | |
948 | +elf32_avr_setup_params (struct bfd_link_info *info, | |
949 | + bfd *avr_stub_bfd, | |
950 | + asection *avr_stub_section, | |
951 | + bfd_boolean no_stubs, | |
952 | + bfd_boolean deb_stubs, | |
953 | + bfd_boolean deb_relax, | |
954 | + bfd_vma pc_wrap_around, | |
955 | + bfd_boolean call_ret_replacement) | |
956 | +{ | |
957 | + struct elf32_avr_link_hash_table *htab = avr_link_hash_table(info); | |
958 | + | |
959 | + htab->stub_sec = avr_stub_section; | |
960 | + htab->stub_bfd = avr_stub_bfd; | |
961 | + htab->no_stubs = no_stubs; | |
962 | + | |
963 | + debug_relax = deb_relax; | |
964 | + debug_stubs = deb_stubs; | |
965 | + avr_pc_wrap_around = pc_wrap_around; | |
966 | + avr_replace_call_ret_sequences = call_ret_replacement; | |
967 | +} | |
968 | + | |
969 | + | |
970 | +/* Set up various things so that we can make a list of input sections | |
971 | + for each output section included in the link. Returns -1 on error, | |
972 | + 0 when no stubs will be needed, and 1 on success. It also sets | |
973 | + information on the stubs bfd and the stub section in the info | |
974 | + struct. */ | |
975 | + | |
976 | +int | |
977 | +elf32_avr_setup_section_lists (bfd *output_bfd, | |
978 | + struct bfd_link_info *info) | |
979 | +{ | |
980 | + bfd *input_bfd; | |
981 | + unsigned int bfd_count; | |
982 | + int top_id, top_index; | |
983 | + asection *section; | |
984 | + asection **input_list, **list; | |
985 | + bfd_size_type amt; | |
986 | + struct elf32_avr_link_hash_table *htab = avr_link_hash_table(info); | |
987 | + | |
988 | + if (htab->no_stubs) | |
989 | + return 0; | |
990 | + | |
991 | + /* Count the number of input BFDs and find the top input section id. */ | |
992 | + for (input_bfd = info->input_bfds, bfd_count = 0, top_id = 0; | |
993 | + input_bfd != NULL; | |
994 | + input_bfd = input_bfd->link_next) | |
995 | + { | |
996 | + bfd_count += 1; | |
997 | + for (section = input_bfd->sections; | |
998 | + section != NULL; | |
999 | + section = section->next) | |
1000 | + if (top_id < section->id) | |
1001 | + top_id = section->id; | |
1002 | + } | |
1003 | + | |
1004 | + htab->bfd_count = bfd_count; | |
1005 | + | |
1006 | + /* We can't use output_bfd->section_count here to find the top output | |
1007 | + section index as some sections may have been removed, and | |
1008 | + strip_excluded_output_sections doesn't renumber the indices. */ | |
1009 | + for (section = output_bfd->sections, top_index = 0; | |
1010 | + section != NULL; | |
1011 | + section = section->next) | |
1012 | + if (top_index < section->index) | |
1013 | + top_index = section->index; | |
1014 | + | |
1015 | + htab->top_index = top_index; | |
1016 | + amt = sizeof (asection *) * (top_index + 1); | |
1017 | + input_list = bfd_malloc (amt); | |
1018 | + htab->input_list = input_list; | |
1019 | + if (input_list == NULL) | |
1020 | + return -1; | |
1021 | + | |
1022 | + /* For sections we aren't interested in, mark their entries with a | |
1023 | + value we can check later. */ | |
1024 | + list = input_list + top_index; | |
1025 | + do | |
1026 | + *list = bfd_abs_section_ptr; | |
1027 | + while (list-- != input_list); | |
1028 | + | |
1029 | + for (section = output_bfd->sections; | |
1030 | + section != NULL; | |
1031 | + section = section->next) | |
1032 | + if ((section->flags & SEC_CODE) != 0) | |
1033 | + input_list[section->index] = NULL; | |
1034 | + | |
1035 | + return 1; | |
1036 | +} | |
1037 | + | |
1038 | + | |
1039 | +/* Read in all local syms for all input bfds, and create hash entries | |
1040 | + for export stubs if we are building a multi-subspace shared lib. | |
1041 | + Returns -1 on error, 0 otherwise. */ | |
1042 | + | |
1043 | +static int | |
1044 | +get_local_syms (bfd *input_bfd, struct bfd_link_info *info) | |
1045 | +{ | |
1046 | + unsigned int bfd_indx; | |
1047 | + Elf_Internal_Sym *local_syms, **all_local_syms; | |
1048 | + struct elf32_avr_link_hash_table *htab = avr_link_hash_table (info); | |
1049 | + | |
1050 | + /* We want to read in symbol extension records only once. To do this | |
1051 | + we need to read in the local symbols in parallel and save them for | |
1052 | + later use; so hold pointers to the local symbols in an array. */ | |
1053 | + bfd_size_type amt = sizeof (Elf_Internal_Sym *) * htab->bfd_count; | |
1054 | + all_local_syms = bfd_zmalloc (amt); | |
1055 | + htab->all_local_syms = all_local_syms; | |
1056 | + if (all_local_syms == NULL) | |
1057 | + return -1; | |
1058 | + | |
1059 | + /* Walk over all the input BFDs, swapping in local symbols. | |
1060 | + If we are creating a shared library, create hash entries for the | |
1061 | + export stubs. */ | |
1062 | + for (bfd_indx = 0; | |
1063 | + input_bfd != NULL; | |
1064 | + input_bfd = input_bfd->link_next, bfd_indx++) | |
1065 | + { | |
1066 | + Elf_Internal_Shdr *symtab_hdr; | |
1067 | + | |
1068 | + /* We'll need the symbol table in a second. */ | |
1069 | + symtab_hdr = &elf_tdata (input_bfd)->symtab_hdr; | |
1070 | + if (symtab_hdr->sh_info == 0) | |
1071 | + continue; | |
1072 | + | |
1073 | + /* We need an array of the local symbols attached to the input bfd. */ | |
1074 | + local_syms = (Elf_Internal_Sym *) symtab_hdr->contents; | |
1075 | + if (local_syms == NULL) | |
1076 | + { | |
1077 | + local_syms = bfd_elf_get_elf_syms (input_bfd, symtab_hdr, | |
1078 | + symtab_hdr->sh_info, 0, | |
1079 | + NULL, NULL, NULL); | |
1080 | + /* Cache them for elf_link_input_bfd. */ | |
1081 | + symtab_hdr->contents = (unsigned char *) local_syms; | |
1082 | + } | |
1083 | + if (local_syms == NULL) | |
1084 | + return -1; | |
1085 | + | |
1086 | + all_local_syms[bfd_indx] = local_syms; | |
1087 | + } | |
1088 | + | |
1089 | + return 0; | |
1090 | +} | |
1091 | + | |
1092 | +#define ADD_DUMMY_STUBS_FOR_DEBUGGING 0 | |
1093 | + | |
1094 | +bfd_boolean | |
1095 | +elf32_avr_size_stubs (bfd *output_bfd, | |
1096 | + struct bfd_link_info *info, | |
1097 | + bfd_boolean is_prealloc_run) | |
1098 | +{ | |
1099 | + struct elf32_avr_link_hash_table *htab; | |
1100 | + int stub_changed = 0; | |
1101 | + | |
1102 | + htab = avr_link_hash_table (info); | |
1103 | + | |
1104 | + /* At this point we initialize htab->vector_base | |
1105 | + To the start of the text output section. */ | |
1106 | + htab->vector_base = htab->stub_sec->output_section->vma; | |
1107 | + | |
1108 | + if (get_local_syms (info->input_bfds, info)) | |
1109 | + { | |
1110 | + if (htab->all_local_syms) | |
1111 | + goto error_ret_free_local; | |
1112 | + return FALSE; | |
1113 | + } | |
1114 | + | |
1115 | + if (ADD_DUMMY_STUBS_FOR_DEBUGGING) | |
1116 | + { | |
1117 | + struct elf32_avr_stub_hash_entry *test; | |
1118 | + | |
1119 | + test = avr_add_stub ("Hugo",htab); | |
1120 | + test->target_value = 0x123456; | |
1121 | + test->stub_offset = 13; | |
1122 | + | |
1123 | + test = avr_add_stub ("Hugo2",htab); | |
1124 | + test->target_value = 0x84210; | |
1125 | + test->stub_offset = 14; | |
1126 | + } | |
1127 | + | |
1128 | + while (1) | |
1129 | + { | |
1130 | + bfd *input_bfd; | |
1131 | + unsigned int bfd_indx; | |
1132 | + | |
1133 | + /* We will have to re-generate the stub hash table each time anything | |
1134 | + in memory has changed. */ | |
1135 | + | |
1136 | + bfd_hash_traverse (&htab->bstab, avr_mark_stub_not_to_be_necessary, htab); | |
1137 | + for (input_bfd = info->input_bfds, bfd_indx = 0; | |
1138 | + input_bfd != NULL; | |
1139 | + input_bfd = input_bfd->link_next, bfd_indx++) | |
1140 | + { | |
1141 | + Elf_Internal_Shdr *symtab_hdr; | |
1142 | + asection *section; | |
1143 | + Elf_Internal_Sym *local_syms; | |
1144 | + | |
1145 | + /* We'll need the symbol table in a second. */ | |
1146 | + symtab_hdr = &elf_tdata (input_bfd)->symtab_hdr; | |
1147 | + if (symtab_hdr->sh_info == 0) | |
1148 | + continue; | |
1149 | + | |
1150 | + local_syms = htab->all_local_syms[bfd_indx]; | |
1151 | + | |
1152 | + /* Walk over each section attached to the input bfd. */ | |
1153 | + for (section = input_bfd->sections; | |
1154 | + section != NULL; | |
1155 | + section = section->next) | |
1156 | + { | |
1157 | + Elf_Internal_Rela *internal_relocs, *irelaend, *irela; | |
1158 | + | |
1159 | + /* If there aren't any relocs, then there's nothing more | |
1160 | + to do. */ | |
1161 | + if ((section->flags & SEC_RELOC) == 0 | |
1162 | + || section->reloc_count == 0) | |
1163 | + continue; | |
1164 | + | |
1165 | + /* If this section is a link-once section that will be | |
1166 | + discarded, then don't create any stubs. */ | |
1167 | + if (section->output_section == NULL | |
1168 | + || section->output_section->owner != output_bfd) | |
1169 | + continue; | |
1170 | + | |
1171 | + /* Get the relocs. */ | |
1172 | + internal_relocs | |
1173 | + = _bfd_elf_link_read_relocs (input_bfd, section, NULL, NULL, | |
1174 | + info->keep_memory); | |
1175 | + if (internal_relocs == NULL) | |
1176 | + goto error_ret_free_local; | |
1177 | + | |
1178 | + /* Now examine each relocation. */ | |
1179 | + irela = internal_relocs; | |
1180 | + irelaend = irela + section->reloc_count; | |
1181 | + for (; irela < irelaend; irela++) | |
1182 | + { | |
1183 | + unsigned int r_type, r_indx; | |
1184 | + struct elf32_avr_stub_hash_entry *hsh; | |
1185 | + asection *sym_sec; | |
1186 | + bfd_vma sym_value; | |
1187 | + bfd_vma destination; | |
1188 | + struct elf_link_hash_entry *hh; | |
1189 | + char *stub_name; | |
1190 | + | |
1191 | + r_type = ELF32_R_TYPE (irela->r_info); | |
1192 | + r_indx = ELF32_R_SYM (irela->r_info); | |
1193 | + | |
1194 | + /* Only look for 16 bit GS relocs. No other reloc will need a | |
1195 | + stub. */ | |
1196 | + if (!((r_type == R_AVR_16_PM) | |
1197 | + || (r_type == R_AVR_LO8_LDI_GS) | |
1198 | + || (r_type == R_AVR_HI8_LDI_GS))) | |
1199 | + continue; | |
1200 | + | |
1201 | + /* Now determine the call target, its name, value, | |
1202 | + section. */ | |
1203 | + sym_sec = NULL; | |
1204 | + sym_value = 0; | |
1205 | + destination = 0; | |
1206 | + hh = NULL; | |
1207 | + if (r_indx < symtab_hdr->sh_info) | |
1208 | + { | |
1209 | + /* It's a local symbol. */ | |
1210 | + Elf_Internal_Sym *sym; | |
1211 | + Elf_Internal_Shdr *hdr; | |
1212 | + | |
1213 | + sym = local_syms + r_indx; | |
1214 | + hdr = elf_elfsections (input_bfd)[sym->st_shndx]; | |
1215 | + sym_sec = hdr->bfd_section; | |
1216 | + if (ELF_ST_TYPE (sym->st_info) != STT_SECTION) | |
1217 | + sym_value = sym->st_value; | |
1218 | + destination = (sym_value + irela->r_addend | |
1219 | + + sym_sec->output_offset | |
1220 | + + sym_sec->output_section->vma); | |
1221 | + } | |
1222 | + else | |
1223 | + { | |
1224 | + /* It's an external symbol. */ | |
1225 | + int e_indx; | |
1226 | + | |
1227 | + e_indx = r_indx - symtab_hdr->sh_info; | |
1228 | + hh = elf_sym_hashes (input_bfd)[e_indx]; | |
1229 | + | |
1230 | + while (hh->root.type == bfd_link_hash_indirect | |
1231 | + || hh->root.type == bfd_link_hash_warning) | |
1232 | + hh = (struct elf_link_hash_entry *) | |
1233 | + (hh->root.u.i.link); | |
1234 | + | |
1235 | + if (hh->root.type == bfd_link_hash_defined | |
1236 | + || hh->root.type == bfd_link_hash_defweak) | |
1237 | + { | |
1238 | + sym_sec = hh->root.u.def.section; | |
1239 | + sym_value = hh->root.u.def.value; | |
1240 | + if (sym_sec->output_section != NULL) | |
1241 | + destination = (sym_value + irela->r_addend | |
1242 | + + sym_sec->output_offset | |
1243 | + + sym_sec->output_section->vma); | |
1244 | + } | |
1245 | + else if (hh->root.type == bfd_link_hash_undefweak) | |
1246 | + { | |
1247 | + if (! info->shared) | |
1248 | + continue; | |
1249 | + } | |
1250 | + else if (hh->root.type == bfd_link_hash_undefined) | |
1251 | + { | |
1252 | + if (! (info->unresolved_syms_in_objects == RM_IGNORE | |
1253 | + && (ELF_ST_VISIBILITY (hh->other) | |
1254 | + == STV_DEFAULT))) | |
1255 | + continue; | |
1256 | + } | |
1257 | + else | |
1258 | + { | |
1259 | + bfd_set_error (bfd_error_bad_value); | |
1260 | + | |
1261 | + error_ret_free_internal: | |
1262 | + if (elf_section_data (section)->relocs == NULL) | |
1263 | + free (internal_relocs); | |
1264 | + goto error_ret_free_local; | |
1265 | + } | |
1266 | + } | |
1267 | + | |
1268 | + if (! avr_stub_is_required_for_16_bit_reloc | |
1269 | + (destination - htab->vector_base)) | |
1270 | + { | |
1271 | + if (!is_prealloc_run) | |
1272 | + /* We are having a reloc that does't need a stub. */ | |
1273 | + continue; | |
1274 | + | |
1275 | + /* We don't right now know if a stub will be needed. | |
1276 | + Let's rather be on the safe side. */ | |
1277 | + } | |
1278 | + | |
1279 | + /* Get the name of this stub. */ | |
1280 | + stub_name = avr_stub_name (sym_sec, sym_value, irela); | |
1281 | + | |
1282 | + if (!stub_name) | |
1283 | + goto error_ret_free_internal; | |
1284 | + | |
1285 | + | |
1286 | + hsh = avr_stub_hash_lookup (&htab->bstab, | |
1287 | + stub_name, | |
1288 | + FALSE, FALSE); | |
1289 | + if (hsh != NULL) | |
1290 | + { | |
1291 | + /* The proper stub has already been created. Mark it | |
1292 | + to be used and write the possibly changed destination | |
1293 | + value. */ | |
1294 | + hsh->is_actually_needed = TRUE; | |
1295 | + hsh->target_value = destination; | |
1296 | + free (stub_name); | |
1297 | + continue; | |
1298 | + } | |
1299 | + | |
1300 | + hsh = avr_add_stub (stub_name, htab); | |
1301 | + if (hsh == NULL) | |
1302 | + { | |
1303 | + free (stub_name); | |
1304 | + goto error_ret_free_internal; | |
1305 | + } | |
1306 | + | |
1307 | + hsh->is_actually_needed = TRUE; | |
1308 | + hsh->target_value = destination; | |
1309 | + | |
1310 | + if (debug_stubs) | |
1311 | + printf ("Adding stub with destination 0x%x to the" | |
1312 | + " hash table.\n", (unsigned int) destination); | |
1313 | + if (debug_stubs) | |
1314 | + printf ("(Pre-Alloc run: %i)\n", is_prealloc_run); | |
1315 | + | |
1316 | + stub_changed = TRUE; | |
1317 | + } | |
1318 | + | |
1319 | + /* We're done with the internal relocs, free them. */ | |
1320 | + if (elf_section_data (section)->relocs == NULL) | |
1321 | + free (internal_relocs); | |
1322 | + } | |
1323 | + } | |
1324 | + | |
1325 | + /* Re-Calculate the number of needed stubs. */ | |
1326 | + htab->stub_sec->size = 0; | |
1327 | + bfd_hash_traverse (&htab->bstab, avr_size_one_stub, htab); | |
1328 | + | |
1329 | + if (!stub_changed) | |
1330 | + break; | |
1331 | + | |
1332 | + stub_changed = FALSE; | |
1333 | + } | |
1334 | + | |
1335 | + free (htab->all_local_syms); | |
1336 | + return TRUE; | |
1337 | + | |
1338 | + error_ret_free_local: | |
1339 | + free (htab->all_local_syms); | |
1340 | + return FALSE; | |
1341 | +} | |
1342 | + | |
1343 | + | |
1344 | +/* Build all the stubs associated with the current output file. The | |
1345 | + stubs are kept in a hash table attached to the main linker hash | |
1346 | + table. We also set up the .plt entries for statically linked PIC | |
1347 | + functions here. This function is called via hppaelf_finish in the | |
1348 | + linker. */ | |
1349 | + | |
1350 | +bfd_boolean | |
1351 | +elf32_avr_build_stubs (struct bfd_link_info *info) | |
1352 | +{ | |
1353 | + asection *stub_sec; | |
1354 | + struct bfd_hash_table *table; | |
1355 | + struct elf32_avr_link_hash_table *htab; | |
1356 | + bfd_size_type total_size = 0; | |
1357 | + | |
1358 | + htab = avr_link_hash_table (info); | |
1359 | + | |
1360 | + /* In case that there were several stub sections: */ | |
1361 | + for (stub_sec = htab->stub_bfd->sections; | |
1362 | + stub_sec != NULL; | |
1363 | + stub_sec = stub_sec->next) | |
1364 | + { | |
1365 | + bfd_size_type size; | |
1366 | + | |
1367 | + /* Allocate memory to hold the linker stubs. */ | |
1368 | + size = stub_sec->size; | |
1369 | + total_size += size; | |
1370 | + | |
1371 | + stub_sec->contents = bfd_zalloc (htab->stub_bfd, size); | |
1372 | + if (stub_sec->contents == NULL && size != 0) | |
1373 | + return FALSE; | |
1374 | + stub_sec->size = 0; | |
1375 | + } | |
1376 | + | |
1377 | + /* Allocate memory for the adress mapping table. */ | |
1378 | + htab->amt_entry_cnt = 0; | |
1379 | + htab->amt_max_entry_cnt = total_size / 4; | |
1380 | + htab->amt_stub_offsets = bfd_malloc (sizeof (bfd_vma) | |
1381 | + * htab->amt_max_entry_cnt); | |
1382 | + htab->amt_destination_addr = bfd_malloc (sizeof (bfd_vma) | |
1383 | + * htab->amt_max_entry_cnt ); | |
1384 | + | |
1385 | + if (debug_stubs) | |
1386 | + printf ("Allocating %i entries in the AMT\n", htab->amt_max_entry_cnt); | |
1387 | + | |
1388 | + /* Build the stubs as directed by the stub hash table. */ | |
1389 | + table = &htab->bstab; | |
1390 | + bfd_hash_traverse (table, avr_build_one_stub, info); | |
1391 | + | |
1392 | + if (debug_stubs) | |
1393 | + printf ("Final Stub section Size: %i\n", (int) htab->stub_sec->size); | |
1394 | + | |
1395 | + return TRUE; | |
1396 | +} | |
1397 | + | |
1398 | #define ELF_ARCH bfd_arch_avr | |
1399 | #define ELF_MACHINE_CODE EM_AVR | |
1400 | #define ELF_MACHINE_ALT1 EM_AVR_OLD | |
1401 | @@ -1960,6 +2925,9 @@ | |
1402 | #define TARGET_LITTLE_SYM bfd_elf32_avr_vec | |
1403 | #define TARGET_LITTLE_NAME "elf32-avr" | |
1404 | ||
1405 | +#define bfd_elf32_bfd_link_hash_table_create elf32_avr_link_hash_table_create | |
1406 | +#define bfd_elf32_bfd_link_hash_table_free elf32_avr_link_hash_table_free | |
1407 | + | |
1408 | #define elf_info_to_howto avr_info_to_howto_rela | |
1409 | #define elf_info_to_howto_rel NULL | |
1410 | #define elf_backend_relocate_section elf32_avr_relocate_section | |
1411 | diff -Nur bfd/elf32-avr.h bfd/elf32-avr.h | |
1412 | --- bfd/elf32-avr.h 1970-01-01 01:00:00.000000000 +0100 | |
1413 | +++ bfd/elf32-avr.h 2006-08-28 20:01:10.805090951 +0200 | |
1414 | @@ -0,0 +1,38 @@ | |
1415 | +/* AVR-specific support for 32-bit ELF. | |
1416 | + Copyright 2006 Free Software Foundation, Inc. | |
1417 | + | |
1418 | + Written by Bjoern Haase <bjoern.m.haase@web.de> | |
1419 | + | |
1420 | + This file is part of BFD, the Binary File Descriptor library. | |
1421 | + | |
1422 | + This program is free software; you can redistribute it and/or modify | |
1423 | + it under the terms of the GNU General Public License as published by | |
1424 | + the Free Software Foundation; either version 2 of the License, or | |
1425 | + (at your option) any later version. | |
1426 | + | |
1427 | + This program is distributed in the hope that it will be useful, | |
1428 | + but WITHOUT ANY WARRANTY; without even the implied warranty of | |
1429 | + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
1430 | + GNU General Public License for more details. | |
1431 | + | |
1432 | + You should have received a copy of the GNU General Public License | |
1433 | + along with this program; if not, write to the Free Software | |
1434 | + Foundation, Inc., 51 Franklin Street - Fifth Floor, | |
1435 | + Boston, MA 02110-1301, USA. */ | |
1436 | + | |
1437 | + | |
1438 | +/* These four functions will be called from the ld back-end. */ | |
1439 | + | |
1440 | +extern void | |
1441 | +elf32_avr_setup_params (struct bfd_link_info *, bfd *, asection *, | |
1442 | + bfd_boolean, bfd_boolean, bfd_boolean, | |
1443 | + bfd_vma, bfd_boolean); | |
1444 | + | |
1445 | +extern int | |
1446 | +elf32_avr_setup_section_lists (bfd *, struct bfd_link_info *); | |
1447 | + | |
1448 | +extern bfd_boolean | |
1449 | +elf32_avr_size_stubs (bfd *, struct bfd_link_info *, bfd_boolean); | |
1450 | + | |
1451 | +extern bfd_boolean | |
1452 | +elf32_avr_build_stubs (struct bfd_link_info *); | |
1453 | diff -Nur bfd/libbfd.h bfd/libbfd.h | |
1454 | --- bfd/libbfd.h 2006-03-26 01:38:42.000000000 +0100 | |
1455 | +++ bfd/libbfd.h 2006-08-28 20:02:16.912297073 +0200 | |
1456 | @@ -1509,7 +1509,9 @@ | |
1457 | "BFD_RELOC_AVR_HH8_LDI_NEG", | |
1458 | "BFD_RELOC_AVR_MS8_LDI_NEG", | |
1459 | "BFD_RELOC_AVR_LO8_LDI_PM", | |
1460 | + "BFD_RELOC_AVR_LO8_LDI_GS", | |
1461 | "BFD_RELOC_AVR_HI8_LDI_PM", | |
1462 | + "BFD_RELOC_AVR_HI8_LDI_GS", | |
1463 | "BFD_RELOC_AVR_HH8_LDI_PM", | |
1464 | "BFD_RELOC_AVR_LO8_LDI_PM_NEG", | |
1465 | "BFD_RELOC_AVR_HI8_LDI_PM_NEG", | |
1466 | diff -Nur bfd/reloc.c bfd/reloc.c | |
1467 | --- bfd/reloc.c 2006-03-26 01:38:42.000000000 +0100 | |
1468 | +++ bfd/reloc.c 2006-08-28 20:02:16.936295332 +0200 | |
1469 | @@ -3666,11 +3666,25 @@ | |
1470 | This is a 16 bit reloc for the AVR that stores 8 bit value (usually | |
1471 | command address) into 8 bit immediate value of LDI insn. | |
1472 | ENUM | |
1473 | + BFD_RELOC_AVR_LO8_LDI_GS | |
1474 | +ENUMDOC | |
1475 | + This is a 16 bit reloc for the AVR that stores 8 bit value | |
1476 | + (command address) into 8 bit immediate value of LDI insn. If the address | |
1477 | + is beyond the 128k boundary, the linker inserts a jump stub for this reloc | |
1478 | + in the lower 128k. | |
1479 | +ENUM | |
1480 | BFD_RELOC_AVR_HI8_LDI_PM | |
1481 | ENUMDOC | |
1482 | This is a 16 bit reloc for the AVR that stores 8 bit value (high 8 bit | |
1483 | of command address) into 8 bit immediate value of LDI insn. | |
1484 | ENUM | |
1485 | + BFD_RELOC_AVR_HI8_LDI_GS | |
1486 | +ENUMDOC | |
1487 | + This is a 16 bit reloc for the AVR that stores 8 bit value (high 8 bit | |
1488 | + of command address) into 8 bit immediate value of LDI insn. If the address | |
1489 | + is beyond the 128k boundary, the linker inserts a jump stub for this reloc | |
1490 | + below 128k. | |
1491 | +ENUM | |
1492 | BFD_RELOC_AVR_HH8_LDI_PM | |
1493 | ENUMDOC | |
1494 | This is a 16 bit reloc for the AVR that stores 8 bit value (most high 8 bit | |
1495 | diff -Nur gas/config/tc-avr.c gas/config/tc-avr.c | |
1496 | --- gas/config/tc-avr.c 2006-04-07 17:18:08.000000000 +0200 | |
1497 | +++ gas/config/tc-avr.c 2006-08-28 20:02:16.948294462 +0200 | |
1498 | @@ -63,89 +63,92 @@ | |
1499 | ||
1500 | static struct mcu_type_s mcu_types[] = | |
1501 | { | |
1502 | - {"avr1", AVR_ISA_TINY1, bfd_mach_avr1}, | |
1503 | - {"avr2", AVR_ISA_TINY2, bfd_mach_avr2}, | |
1504 | - {"avr3", AVR_ISA_M103, bfd_mach_avr3}, | |
1505 | - {"avr4", AVR_ISA_M8, bfd_mach_avr4}, | |
1506 | - {"avr5", AVR_ISA_ALL, bfd_mach_avr5}, | |
1507 | - {"at90s1200", AVR_ISA_1200, bfd_mach_avr1}, | |
1508 | - {"attiny10", AVR_ISA_TINY1, bfd_mach_avr1}, /* XXX -> tn11 */ | |
1509 | - {"attiny11", AVR_ISA_TINY1, bfd_mach_avr1}, | |
1510 | - {"attiny12", AVR_ISA_TINY1, bfd_mach_avr1}, | |
1511 | - {"attiny15", AVR_ISA_TINY1, bfd_mach_avr1}, | |
1512 | - {"attiny28", AVR_ISA_TINY1, bfd_mach_avr1}, | |
1513 | - {"at90s2313", AVR_ISA_2xxx, bfd_mach_avr2}, | |
1514 | - {"at90s2323", AVR_ISA_2xxx, bfd_mach_avr2}, | |
1515 | - {"at90s2333", AVR_ISA_2xxx, bfd_mach_avr2}, /* XXX -> 4433 */ | |
1516 | - {"at90s2343", AVR_ISA_2xxx, bfd_mach_avr2}, | |
1517 | - {"attiny22", AVR_ISA_2xxx, bfd_mach_avr2}, /* XXX -> 2343 */ | |
1518 | - {"attiny26", AVR_ISA_2xxx, bfd_mach_avr2}, | |
1519 | - {"at90s4433", AVR_ISA_2xxx, bfd_mach_avr2}, | |
1520 | - {"at90s4414", AVR_ISA_2xxx, bfd_mach_avr2}, /* XXX -> 8515 */ | |
1521 | - {"at90s4434", AVR_ISA_2xxx, bfd_mach_avr2}, /* XXX -> 8535 */ | |
1522 | - {"at90s8515", AVR_ISA_2xxx, bfd_mach_avr2}, | |
1523 | - {"at90s8535", AVR_ISA_2xxx, bfd_mach_avr2}, | |
1524 | - {"at90c8534", AVR_ISA_2xxx, bfd_mach_avr2}, | |
1525 | - {"at86rf401", AVR_ISA_2xxx, bfd_mach_avr2}, | |
1526 | - {"attiny13", AVR_ISA_TINY2, bfd_mach_avr2}, | |
1527 | - {"attiny2313",AVR_ISA_TINY2, bfd_mach_avr2}, | |
1528 | - {"attiny261", AVR_ISA_TINY2, bfd_mach_avr2}, | |
1529 | - {"attiny461", AVR_ISA_TINY2, bfd_mach_avr2}, | |
1530 | - {"attiny861", AVR_ISA_TINY2, bfd_mach_avr2}, | |
1531 | - {"attiny24", AVR_ISA_TINY2, bfd_mach_avr2}, | |
1532 | - {"attiny44", AVR_ISA_TINY2, bfd_mach_avr2}, | |
1533 | - {"attiny84", AVR_ISA_TINY2, bfd_mach_avr2}, | |
1534 | - {"attiny25", AVR_ISA_TINY2, bfd_mach_avr2}, | |
1535 | - {"attiny45", AVR_ISA_TINY2, bfd_mach_avr2}, | |
1536 | - {"attiny85", AVR_ISA_TINY2, bfd_mach_avr2}, | |
1537 | - {"atmega603", AVR_ISA_M603, bfd_mach_avr3}, /* XXX -> m103 */ | |
1538 | - {"atmega103", AVR_ISA_M103, bfd_mach_avr3}, | |
1539 | - {"at43usb320",AVR_ISA_M103, bfd_mach_avr3}, | |
1540 | - {"at43usb355",AVR_ISA_M603, bfd_mach_avr3}, | |
1541 | - {"at76c711", AVR_ISA_M603, bfd_mach_avr3}, | |
1542 | - {"atmega48", AVR_ISA_PWMx, bfd_mach_avr4}, | |
1543 | - {"atmega8", AVR_ISA_M8, bfd_mach_avr4}, | |
1544 | - {"atmega83", AVR_ISA_M8, bfd_mach_avr4}, /* XXX -> m8535 */ | |
1545 | - {"atmega85", AVR_ISA_M8, bfd_mach_avr4}, /* XXX -> m8 */ | |
1546 | - {"atmega88", AVR_ISA_PWMx, bfd_mach_avr4}, | |
1547 | - {"atmega8515",AVR_ISA_M8, bfd_mach_avr4}, | |
1548 | - {"atmega8535",AVR_ISA_M8, bfd_mach_avr4}, | |
1549 | - {"at90pwm2", AVR_ISA_PWMx, bfd_mach_avr4}, | |
1550 | - {"at90pwm3", AVR_ISA_PWMx, bfd_mach_avr4}, | |
1551 | - {"atmega16", AVR_ISA_M323, bfd_mach_avr5}, | |
1552 | - {"atmega161", AVR_ISA_M161, bfd_mach_avr5}, | |
1553 | - {"atmega162", AVR_ISA_M323, bfd_mach_avr5}, | |
1554 | - {"atmega163", AVR_ISA_M161, bfd_mach_avr5}, | |
1555 | - {"atmega164", AVR_ISA_M323, bfd_mach_avr5}, | |
1556 | - {"atmega165", AVR_ISA_M323, bfd_mach_avr5}, | |
1557 | - {"atmega168", AVR_ISA_M323, bfd_mach_avr5}, | |
1558 | - {"atmega169", AVR_ISA_M323, bfd_mach_avr5}, | |
1559 | - {"atmega32", AVR_ISA_M323, bfd_mach_avr5}, | |
1560 | - {"atmega323", AVR_ISA_M323, bfd_mach_avr5}, | |
1561 | - {"atmega324", AVR_ISA_M323, bfd_mach_avr5}, | |
1562 | - {"atmega325", AVR_ISA_M323, bfd_mach_avr5}, | |
1563 | - {"atmega329", AVR_ISA_M323, bfd_mach_avr5}, | |
1564 | - {"atmega3250",AVR_ISA_M323, bfd_mach_avr5}, | |
1565 | - {"atmega3290",AVR_ISA_M323, bfd_mach_avr5}, | |
1566 | - {"atmega406", AVR_ISA_M323, bfd_mach_avr5}, | |
1567 | - {"atmega64", AVR_ISA_M323, bfd_mach_avr5}, | |
1568 | - {"atmega640", AVR_ISA_M323, bfd_mach_avr5}, | |
1569 | - {"atmega644", AVR_ISA_M323, bfd_mach_avr5}, | |
1570 | - {"atmega128", AVR_ISA_M128, bfd_mach_avr5}, | |
1571 | - {"atmega1280",AVR_ISA_M128, bfd_mach_avr5}, | |
1572 | - {"atmega1281",AVR_ISA_M128, bfd_mach_avr5}, | |
1573 | - {"atmega645", AVR_ISA_M323, bfd_mach_avr5}, | |
1574 | - {"atmega649", AVR_ISA_M323, bfd_mach_avr5}, | |
1575 | - {"atmega6450",AVR_ISA_M323, bfd_mach_avr5}, | |
1576 | - {"atmega6490",AVR_ISA_M323, bfd_mach_avr5}, | |
1577 | - {"at90can32" ,AVR_ISA_M323, bfd_mach_avr5}, | |
1578 | - {"at90can64" ,AVR_ISA_M323, bfd_mach_avr5}, | |
1579 | - {"at90can128",AVR_ISA_M128, bfd_mach_avr5}, | |
1580 | + {"avr1", AVR_ISA_TINY1, bfd_mach_avr1}, | |
1581 | + {"avr2", AVR_ISA_TINY2, bfd_mach_avr2}, | |
1582 | + {"avr3", AVR_ISA_M103, bfd_mach_avr3}, | |
1583 | + {"avr4", AVR_ISA_M8, bfd_mach_avr4}, | |
1584 | + {"avr5", AVR_ISA_ALL, bfd_mach_avr5}, | |
1585 | + {"avr6", AVR_ISA_ALL, bfd_mach_avr6}, | |
1586 | + {"at90s1200", AVR_ISA_1200, bfd_mach_avr1}, | |
1587 | + {"attiny10", AVR_ISA_TINY1, bfd_mach_avr1}, /* XXX -> tn11 */ | |
1588 | + {"attiny11", AVR_ISA_TINY1, bfd_mach_avr1}, | |
1589 | + {"attiny12", AVR_ISA_TINY1, bfd_mach_avr1}, | |
1590 | + {"attiny15", AVR_ISA_TINY1, bfd_mach_avr1}, | |
1591 | + {"attiny28", AVR_ISA_TINY1, bfd_mach_avr1}, | |
1592 | + {"at90s2313", AVR_ISA_2xxx, bfd_mach_avr2}, | |
1593 | + {"at90s2323", AVR_ISA_2xxx, bfd_mach_avr2}, | |
1594 | + {"at90s2333", AVR_ISA_2xxx, bfd_mach_avr2}, /* XXX -> 4433 */ | |
1595 | + {"at90s2343", AVR_ISA_2xxx, bfd_mach_avr2}, | |
1596 | + {"attiny22", AVR_ISA_2xxx, bfd_mach_avr2}, /* XXX -> 2343 */ | |
1597 | + {"attiny26", AVR_ISA_2xxx, bfd_mach_avr2}, | |
1598 | + {"at90s4433", AVR_ISA_2xxx, bfd_mach_avr2}, | |
1599 | + {"at90s4414", AVR_ISA_2xxx, bfd_mach_avr2}, /* XXX -> 8515 */ | |
1600 | + {"at90s4434", AVR_ISA_2xxx, bfd_mach_avr2}, /* XXX -> 8535 */ | |
1601 | + {"at90s8515", AVR_ISA_2xxx, bfd_mach_avr2}, | |
1602 | + {"at90s8535", AVR_ISA_2xxx, bfd_mach_avr2}, | |
1603 | + {"at90c8534", AVR_ISA_2xxx, bfd_mach_avr2}, | |
1604 | + {"at86rf401", AVR_ISA_2xxx, bfd_mach_avr2}, | |
1605 | + {"attiny13", AVR_ISA_TINY2, bfd_mach_avr2}, | |
1606 | + {"attiny2313", AVR_ISA_TINY2, bfd_mach_avr2}, | |
1607 | + {"attiny261", AVR_ISA_TINY2, bfd_mach_avr2}, | |
1608 | + {"attiny461", AVR_ISA_TINY2, bfd_mach_avr2}, | |
1609 | + {"attiny861", AVR_ISA_TINY2, bfd_mach_avr2}, | |
1610 | + {"attiny24", AVR_ISA_TINY2, bfd_mach_avr2}, | |
1611 | + {"attiny44", AVR_ISA_TINY2, bfd_mach_avr2}, | |
1612 | + {"attiny84", AVR_ISA_TINY2, bfd_mach_avr2}, | |
1613 | + {"attiny25", AVR_ISA_TINY2, bfd_mach_avr2}, | |
1614 | + {"attiny45", AVR_ISA_TINY2, bfd_mach_avr2}, | |
1615 | + {"attiny85", AVR_ISA_TINY2, bfd_mach_avr2}, | |
1616 | + {"atmega603", AVR_ISA_M603, bfd_mach_avr3}, /* XXX -> m103 */ | |
1617 | + {"atmega103", AVR_ISA_M103, bfd_mach_avr3}, | |
1618 | + {"at43usb320", AVR_ISA_M103, bfd_mach_avr3}, | |
1619 | + {"at43usb355", AVR_ISA_M603, bfd_mach_avr3}, | |
1620 | + {"at76c711", AVR_ISA_M603, bfd_mach_avr3}, | |
1621 | + {"atmega48", AVR_ISA_PWMx, bfd_mach_avr4}, | |
1622 | + {"atmega8", AVR_ISA_M8, bfd_mach_avr4}, | |
1623 | + {"atmega83", AVR_ISA_M8, bfd_mach_avr4}, /* XXX -> m8535 */ | |
1624 | + {"atmega85", AVR_ISA_M8, bfd_mach_avr4}, /* XXX -> m8 */ | |
1625 | + {"atmega88", AVR_ISA_PWMx, bfd_mach_avr4}, | |
1626 | + {"atmega8515", AVR_ISA_M8, bfd_mach_avr4}, | |
1627 | + {"atmega8535", AVR_ISA_M8, bfd_mach_avr4}, | |
1628 | + {"at90pwm2", AVR_ISA_PWMx, bfd_mach_avr4}, | |
1629 | + {"at90pwm3", AVR_ISA_PWMx, bfd_mach_avr4}, | |
1630 | + {"atmega16", AVR_ISA_M323, bfd_mach_avr5}, | |
1631 | + {"atmega161", AVR_ISA_M161, bfd_mach_avr5}, | |
1632 | + {"atmega162", AVR_ISA_M323, bfd_mach_avr5}, | |
1633 | + {"atmega163", AVR_ISA_M161, bfd_mach_avr5}, | |
1634 | + {"atmega164", AVR_ISA_M323, bfd_mach_avr5}, | |
1635 | + {"atmega165", AVR_ISA_M323, bfd_mach_avr5}, | |
1636 | + {"atmega168", AVR_ISA_M323, bfd_mach_avr5}, | |
1637 | + {"atmega169", AVR_ISA_M323, bfd_mach_avr5}, | |
1638 | + {"atmega32", AVR_ISA_M323, bfd_mach_avr5}, | |
1639 | + {"atmega323", AVR_ISA_M323, bfd_mach_avr5}, | |
1640 | + {"atmega324", AVR_ISA_M323, bfd_mach_avr5}, | |
1641 | + {"atmega325", AVR_ISA_M323, bfd_mach_avr5}, | |
1642 | + {"atmega329", AVR_ISA_M323, bfd_mach_avr5}, | |
1643 | + {"atmega3250", AVR_ISA_M323, bfd_mach_avr5}, | |
1644 | + {"atmega3290", AVR_ISA_M323, bfd_mach_avr5}, | |
1645 | + {"atmega406", AVR_ISA_M323, bfd_mach_avr5}, | |
1646 | + {"atmega64", AVR_ISA_M323, bfd_mach_avr5}, | |
1647 | + {"atmega640", AVR_ISA_M323, bfd_mach_avr5}, | |
1648 | + {"atmega644", AVR_ISA_M323, bfd_mach_avr5}, | |
1649 | + {"atmega128", AVR_ISA_M128, bfd_mach_avr5}, | |
1650 | + {"atmega1280", AVR_ISA_M128, bfd_mach_avr5}, | |
1651 | + {"atmega1281", AVR_ISA_M128, bfd_mach_avr5}, | |
1652 | + {"atmega645", AVR_ISA_M323, bfd_mach_avr5}, | |
1653 | + {"atmega649", AVR_ISA_M323, bfd_mach_avr5}, | |
1654 | + {"atmega6450", AVR_ISA_M323, bfd_mach_avr5}, | |
1655 | + {"atmega6490", AVR_ISA_M323, bfd_mach_avr5}, | |
1656 | + {"at90can32" , AVR_ISA_M323, bfd_mach_avr5}, | |
1657 | + {"at90can64" , AVR_ISA_M323, bfd_mach_avr5}, | |
1658 | + {"at90can128", AVR_ISA_M128, bfd_mach_avr5}, | |
1659 | {"at90usb646", AVR_ISA_M323, bfd_mach_avr5}, | |
1660 | {"at90usb647", AVR_ISA_M323, bfd_mach_avr5}, | |
1661 | {"at90usb1286",AVR_ISA_M128, bfd_mach_avr5}, | |
1662 | {"at90usb1287",AVR_ISA_M128, bfd_mach_avr5}, | |
1663 | - {"at94k", AVR_ISA_94K, bfd_mach_avr5}, | |
1664 | + {"at94k", AVR_ISA_94K, bfd_mach_avr5}, | |
1665 | + {"atmega2560", AVR_ISA_ALL, bfd_mach_avr6}, | |
1666 | + {"atmega2561", AVR_ISA_ALL, bfd_mach_avr6}, | |
1667 | {NULL, 0, 0} | |
1668 | }; | |
1669 | ||
1670 | @@ -512,7 +515,7 @@ | |
1671 | if (exp->X_op == O_constant) | |
1672 | { | |
1673 | int x = exp->X_add_number; | |
1674 | - | |
1675 | + | |
1676 | if (x < -255 || x > 255) | |
1677 | as_warn (_("constant out of 8-bit range: %d"), x); | |
1678 | } | |
1679 | @@ -544,6 +547,8 @@ | |
1680 | char *tmp; | |
1681 | char op[8]; | |
1682 | int mod; | |
1683 | + int linker_stubs_should_be_generated = 0; | |
1684 | + | |
1685 | tmp = str; | |
1686 | ||
1687 | str = extract_word (str, op, sizeof (op)); | |
1688 | @@ -551,7 +556,7 @@ | |
1689 | if (op[0]) | |
1690 | { | |
1691 | mod_index m; | |
1692 | - | |
1693 | + | |
1694 | m.ptr = hash_find (avr_mod_hash, op); | |
1695 | mod = m.index; | |
1696 | ||
1697 | @@ -564,11 +569,14 @@ | |
1698 | ||
1699 | if (*str == '(') | |
1700 | { | |
1701 | + bfd_reloc_code_real_type reloc_to_return; | |
1702 | int neg_p = 0; | |
1703 | ||
1704 | ++str; | |
1705 | ||
1706 | if (strncmp ("pm(", str, 3) == 0 | |
1707 | + || strncmp ("gs(",str,3) == 0 | |
1708 | + || strncmp ("-(gs(",str,5) == 0 | |
1709 | || strncmp ("-(pm(", str, 5) == 0) | |
1710 | { | |
1711 | if (HAVE_PM_P (mod)) | |
1712 | @@ -579,6 +587,9 @@ | |
1713 | else | |
1714 | as_bad (_("illegal expression")); | |
1715 | ||
1716 | + if (str[0] == 'g' || str[2] == 'g') | |
1717 | + linker_stubs_should_be_generated = 1; | |
1718 | + | |
1719 | if (*str == '-') | |
1720 | { | |
1721 | neg_p = 1; | |
1722 | @@ -610,7 +621,24 @@ | |
1723 | } | |
1724 | while (closes--); | |
1725 | ||
1726 | - return neg_p ? EXP_MOD_NEG_RELOC (mod) : EXP_MOD_RELOC (mod); | |
1727 | + reloc_to_return = | |
1728 | + neg_p ? EXP_MOD_NEG_RELOC (mod) : EXP_MOD_RELOC (mod); | |
1729 | + if (linker_stubs_should_be_generated) | |
1730 | + { | |
1731 | + switch (reloc_to_return) | |
1732 | + { | |
1733 | + case BFD_RELOC_AVR_LO8_LDI_PM: | |
1734 | + reloc_to_return = BFD_RELOC_AVR_LO8_LDI_GS; | |
1735 | + break; | |
1736 | + case BFD_RELOC_AVR_HI8_LDI_PM: | |
1737 | + reloc_to_return = BFD_RELOC_AVR_HI8_LDI_GS; | |
1738 | + break; | |
1739 | + | |
1740 | + default: | |
1741 | + break; /* as_warn (_("expression dangerous with linker stubs")); *//* Bjoern agreed. :) */ | |
1742 | + } | |
1743 | + } | |
1744 | + return reloc_to_return; | |
1745 | } | |
1746 | } | |
1747 | } | |
1748 | @@ -1227,7 +1255,7 @@ | |
1749 | return NULL; | |
1750 | } | |
1751 | ||
1752 | - /* We are dealing with two symbols defined in the same section. | |
1753 | + /* We are dealing with two symbols defined in the same section. | |
1754 | Let us fix-up them here. */ | |
1755 | value += S_GET_VALUE (fixp->fx_addsy); | |
1756 | value -= S_GET_VALUE (fixp->fx_subsy); | |
1757 | @@ -1310,7 +1338,8 @@ | |
1758 | static int exp_mod_pm = 0; | |
1759 | ||
1760 | /* Parse special CONS expression: pm (expression) | |
1761 | - which is used for addressing to a program memory. | |
1762 | + or alternatively: gs (expression). | |
1763 | + These are used for addressing program memory. | |
1764 | Relocation: BFD_RELOC_AVR_16_PM. */ | |
1765 | ||
1766 | void | |
1767 | @@ -1324,10 +1353,13 @@ | |
1768 | ||
1769 | if (nbytes == 2) | |
1770 | { | |
1771 | - char *pm_name = "pm"; | |
1772 | - int len = strlen (pm_name); | |
1773 | + char *pm_name1 = "pm"; | |
1774 | + char *pm_name2 = "gs"; | |
1775 | + int len = strlen (pm_name1); | |
1776 | + /* len must be the same for both pm identifiers. */ | |
1777 | ||
1778 | - if (strncasecmp (input_line_pointer, pm_name, len) == 0) | |
1779 | + if (strncasecmp (input_line_pointer, pm_name1, len) == 0 | |
1780 | + || strncasecmp (input_line_pointer, pm_name2, len) == 0) | |
1781 | { | |
1782 | input_line_pointer = skip_space (input_line_pointer + len); | |
1783 | ||
1784 | diff -Nur gas/config/tc-avr.h gas/config/tc-avr.h | |
1785 | --- gas/config/tc-avr.h 2006-05-17 18:04:30.000000000 +0200 | |
1786 | +++ gas/config/tc-avr.h 2006-08-28 20:02:16.952294172 +0200 | |
1787 | @@ -125,16 +125,21 @@ | |
1788 | We will need them in case that we want to do linker relaxation. | |
1789 | We could in principle keep these fixups in gas when not relaxing. | |
1790 | However, there is no serious performance penilty when making the linker | |
1791 | - make the fixup work. */ | |
1792 | -#define TC_VALIDATE_FIX(FIXP,SEG,SKIP) \ | |
1793 | - if ( (FIXP->fx_r_type == BFD_RELOC_AVR_7_PCREL \ | |
1794 | - || FIXP->fx_r_type == BFD_RELOC_AVR_13_PCREL \ | |
1795 | - || FIXP->fx_r_type == BFD_RELOC_AVR_LO8_LDI_PM \ | |
1796 | - || FIXP->fx_r_type == BFD_RELOC_AVR_HI8_LDI_PM \ | |
1797 | - || FIXP->fx_r_type == BFD_RELOC_AVR_HH8_LDI_PM \ | |
1798 | - || FIXP->fx_r_type == BFD_RELOC_AVR_16_PM) \ | |
1799 | - && (FIXP->fx_addsy)) \ | |
1800 | - { \ | |
1801 | - goto SKIP; \ | |
1802 | + make the fixup work. Check also that fx_addsy is not NULL, in order to make | |
1803 | + sure that the fixup refers to some sort of lable. */ | |
1804 | +#define TC_VALIDATE_FIX(FIXP,SEG,SKIP) \ | |
1805 | + if ( (FIXP->fx_r_type == BFD_RELOC_AVR_7_PCREL \ | |
1806 | + || FIXP->fx_r_type == BFD_RELOC_AVR_13_PCREL \ | |
1807 | + || FIXP->fx_r_type == BFD_RELOC_AVR_LO8_LDI_PM \ | |
1808 | + || FIXP->fx_r_type == BFD_RELOC_AVR_LO8_LDI_GS \ | |
1809 | + || FIXP->fx_r_type == BFD_RELOC_AVR_HI8_LDI_PM \ | |
1810 | + || FIXP->fx_r_type == BFD_RELOC_AVR_HI8_LDI_GS \ | |
1811 | + || FIXP->fx_r_type == BFD_RELOC_AVR_HH8_LDI_PM \ | |
1812 | + || FIXP->fx_r_type == BFD_RELOC_AVR_LO8_LDI_PM_NEG \ | |
1813 | + || FIXP->fx_r_type == BFD_RELOC_AVR_HI8_LDI_PM_NEG \ | |
1814 | + || FIXP->fx_r_type == BFD_RELOC_AVR_HH8_LDI_PM_NEG \ | |
1815 | + || FIXP->fx_r_type == BFD_RELOC_AVR_16_PM) \ | |
1816 | + && (FIXP->fx_addsy)) \ | |
1817 | + { \ | |
1818 | + goto SKIP; \ | |
1819 | } | |
1820 | - | |
1821 | diff -Nur include/elf/avr.h include/elf/avr.h | |
1822 | --- include/elf/avr.h 2006-03-03 16:25:30.000000000 +0100 | |
1823 | +++ include/elf/avr.h 2006-08-28 20:02:16.998290837 +0200 | |
1824 | @@ -1,5 +1,5 @@ | |
1825 | /* AVR ELF support for BFD. | |
1826 | - Copyright 1999, 2000, 2004 Free Software Foundation, Inc. | |
1827 | + Copyright 1999, 2000, 2004, 2006 Free Software Foundation, Inc. | |
1828 | Contributed by Denis Chertykov <denisc@overta.ru> | |
1829 | ||
1830 | This file is part of BFD, the Binary File Descriptor library. | |
1831 | @@ -35,6 +35,7 @@ | |
1832 | #define E_AVR_MACH_AVR3 3 | |
1833 | #define E_AVR_MACH_AVR4 4 | |
1834 | #define E_AVR_MACH_AVR5 5 | |
1835 | +#define E_AVR_MACH_AVR6 6 | |
1836 | ||
1837 | /* Relocations. */ | |
1838 | START_RELOC_NUMBERS (elf_avr_reloc_type) | |
1839 | @@ -62,6 +63,8 @@ | |
1840 | RELOC_NUMBER (R_AVR_6_ADIW, 21) | |
1841 | RELOC_NUMBER (R_AVR_MS8_LDI, 22) | |
1842 | RELOC_NUMBER (R_AVR_MS8_LDI_NEG, 23) | |
1843 | + RELOC_NUMBER (R_AVR_LO8_LDI_GS, 24) | |
1844 | + RELOC_NUMBER (R_AVR_HI8_LDI_GS, 25) | |
1845 | END_RELOC_NUMBERS (R_AVR_max) | |
1846 | ||
1847 | #endif /* _ELF_AVR_H */ | |
1848 | diff -Nur include/elf/ChangeLog include/elf/ChangeLog | |
1849 | --- include/elf/ChangeLog 2006-03-22 10:28:12.000000000 +0100 | |
1850 | +++ include/elf/ChangeLog 2006-08-28 20:02:17.001290619 +0200 | |
1851 | @@ -1,3 +1,7 @@ | |
1852 | +2006-05-24 Bjoern Haase <bjoern.m.haase@web.de> | |
1853 | + | |
1854 | + * avr.h: Add E_AVR_MACH_AVR6, R_AVR_LO8_LDI_GS and R_AVR_HI8_LDI_GS. | |
1855 | + | |
1856 | 2006-03-22 Richard Sandiford <richard@codesourcery.com> | |
1857 | Daniel Jacobowitz <dan@codesourcery.com> | |
1858 | Phil Edwards <phil@codesourcery.com> | |
1859 | diff -Nur ld/configure.tgt ld/configure.tgt | |
1860 | --- ld/configure.tgt 2006-04-05 14:41:57.000000000 +0200 | |
1861 | +++ ld/configure.tgt 2006-08-28 20:02:17.029288589 +0200 | |
1862 | @@ -81,7 +81,7 @@ | |
1863 | xscale-*-elf) targ_emul=armelf | |
1864 | ;; | |
1865 | avr-*-*) targ_emul=avr2 | |
1866 | - targ_extra_emuls="avr1 avr3 avr4 avr5" | |
1867 | + targ_extra_emuls="avr1 avr3 avr4 avr5 avr6" | |
1868 | ;; | |
1869 | bfin-*-elf) targ_emul=elf32bfin; targ_extra_emuls="elf32bfinfd" ;; | |
1870 | bfin-*-uclinux*) targ_emul=elf32bfin; targ_extra_emuls="elf32bfinfd" ;; | |
1871 | diff -Nur ld/emulparams/avr1.sh ld/emulparams/avr1.sh | |
1872 | --- ld/emulparams/avr1.sh 2002-05-16 21:51:08.000000000 +0200 | |
1873 | +++ ld/emulparams/avr1.sh 2006-08-28 20:02:17.031288444 +0200 | |
1874 | @@ -4,7 +4,8 @@ | |
1875 | OUTPUT_FORMAT="elf32-avr" | |
1876 | MAXPAGESIZE=1 | |
1877 | EMBEDDED=yes | |
1878 | -TEMPLATE_NAME=generic | |
1879 | +TEMPLATE_NAME=elf32 | |
1880 | ||
1881 | TEXT_LENGTH=8K | |
1882 | DATA_LENGTH=0 | |
1883 | +EXTRA_EM_FILE=avrelf | |
1884 | diff -Nur ld/emulparams/avr2.sh ld/emulparams/avr2.sh | |
1885 | --- ld/emulparams/avr2.sh 2002-05-16 21:51:08.000000000 +0200 | |
1886 | +++ ld/emulparams/avr2.sh 2006-08-28 20:02:17.033288299 +0200 | |
1887 | @@ -4,7 +4,8 @@ | |
1888 | OUTPUT_FORMAT="elf32-avr" | |
1889 | MAXPAGESIZE=1 | |
1890 | EMBEDDED=yes | |
1891 | -TEMPLATE_NAME=generic | |
1892 | +TEMPLATE_NAME=elf32 | |
1893 | ||
1894 | TEXT_LENGTH=8K | |
1895 | DATA_LENGTH=0xffa0 | |
1896 | +EXTRA_EM_FILE=avrelf | |
1897 | diff -Nur ld/emulparams/avr3.sh ld/emulparams/avr3.sh | |
1898 | --- ld/emulparams/avr3.sh 2002-05-16 21:51:08.000000000 +0200 | |
1899 | +++ ld/emulparams/avr3.sh 2006-08-28 20:02:17.036288081 +0200 | |
1900 | @@ -4,7 +4,8 @@ | |
1901 | OUTPUT_FORMAT="elf32-avr" | |
1902 | MAXPAGESIZE=1 | |
1903 | EMBEDDED=yes | |
1904 | -TEMPLATE_NAME=generic | |
1905 | +TEMPLATE_NAME=elf32 | |
1906 | ||
1907 | TEXT_LENGTH=128K | |
1908 | DATA_LENGTH=0xffa0 | |
1909 | +EXTRA_EM_FILE=avrelf | |
1910 | diff -Nur ld/emulparams/avr4.sh ld/emulparams/avr4.sh | |
1911 | --- ld/emulparams/avr4.sh 2002-05-16 21:51:08.000000000 +0200 | |
1912 | +++ ld/emulparams/avr4.sh 2006-08-28 20:02:17.038287936 +0200 | |
1913 | @@ -4,7 +4,8 @@ | |
1914 | OUTPUT_FORMAT="elf32-avr" | |
1915 | MAXPAGESIZE=1 | |
1916 | EMBEDDED=yes | |
1917 | -TEMPLATE_NAME=generic | |
1918 | +TEMPLATE_NAME=elf32 | |
1919 | ||
1920 | TEXT_LENGTH=8K | |
1921 | DATA_LENGTH=0xffa0 | |
1922 | +EXTRA_EM_FILE=avrelf | |
1923 | diff -Nur ld/emulparams/avr5.sh ld/emulparams/avr5.sh | |
1924 | --- ld/emulparams/avr5.sh 2002-05-16 21:51:08.000000000 +0200 | |
1925 | +++ ld/emulparams/avr5.sh 2006-08-28 20:02:17.040287791 +0200 | |
1926 | @@ -4,7 +4,8 @@ | |
1927 | OUTPUT_FORMAT="elf32-avr" | |
1928 | MAXPAGESIZE=1 | |
1929 | EMBEDDED=yes | |
1930 | -TEMPLATE_NAME=generic | |
1931 | +TEMPLATE_NAME=elf32 | |
1932 | ||
1933 | TEXT_LENGTH=128K | |
1934 | DATA_LENGTH=0xffa0 | |
1935 | +EXTRA_EM_FILE=avrelf | |
1936 | diff -Nur ld/emulparams/avr6.sh ld/emulparams/avr6.sh | |
1937 | --- ld/emulparams/avr6.sh 1970-01-01 01:00:00.000000000 +0100 | |
1938 | +++ ld/emulparams/avr6.sh 2006-08-28 20:02:17.043287574 +0200 | |
1939 | @@ -0,0 +1,11 @@ | |
1940 | +ARCH=avr:6 | |
1941 | +MACHINE= | |
1942 | +SCRIPT_NAME=avr | |
1943 | +OUTPUT_FORMAT="elf32-avr" | |
1944 | +MAXPAGESIZE=1 | |
1945 | +EMBEDDED=yes | |
1946 | +TEMPLATE_NAME=elf32 | |
1947 | + | |
1948 | +TEXT_LENGTH=1024K | |
1949 | +DATA_LENGTH=0xffa0 | |
1950 | +EXTRA_EM_FILE=avrelf | |
1951 | diff -Nur ld/emultempl/avrelf.em ld/emultempl/avrelf.em | |
1952 | --- ld/emultempl/avrelf.em 1970-01-01 01:00:00.000000000 +0100 | |
1953 | +++ ld/emultempl/avrelf.em 2006-08-28 20:02:17.047287284 +0200 | |
1954 | @@ -0,0 +1,267 @@ | |
1955 | +# This shell script emits a C file. -*- C -*- | |
1956 | +# Copyright 2006 | |
1957 | +# Free Software Foundation, Inc. | |
1958 | +# | |
1959 | +# This file is part of GLD, the Gnu Linker. | |
1960 | +# | |
1961 | +# This program is free software; you can redistribute it and/or modify | |
1962 | +# it under the terms of the GNU General Public License as published by | |
1963 | +# the Free Software Foundation; either version 2 of the License, or | |
1964 | +# (at your option) any later version. | |
1965 | +# | |
1966 | +# This program is distributed in the hope that it will be useful, | |
1967 | +# but WITHOUT ANY WARRANTY; without even the implied warranty of | |
1968 | +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
1969 | +# GNU General Public License for more details. | |
1970 | +# | |
1971 | +# You should have received a copy of the GNU General Public License | |
1972 | +# along with this program; if not, write to the Free Software | |
1973 | +# Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, | |
1974 | +# MA 02110-1301 USA. | |
1975 | + | |
1976 | +# This file is sourced from elf32.em, and defines extra avr-elf | |
1977 | +# specific routines. It is used to generate the trampolines for the avr6 | |
1978 | +# family devices where one needs to address the issue that it is not possible | |
1979 | +# to reach the whole program memory by using 16 bit pointers. | |
1980 | + | |
1981 | +cat >>e${EMULATION_NAME}.c <<EOF | |
1982 | + | |
1983 | +#include "elf32-avr.h" | |
1984 | +#include "ldctor.h" | |
1985 | + | |
1986 | +/* The fake file and it's corresponding section meant to hold | |
1987 | + the linker stubs if needed. */ | |
1988 | + | |
1989 | +static lang_input_statement_type *stub_file; | |
1990 | +static asection *avr_stub_section; | |
1991 | + | |
1992 | +/* Variables set by the command-line parameters and transfered | |
1993 | + to the bfd without use of global shared variables. */ | |
1994 | + | |
1995 | +static bfd_boolean avr_no_stubs = FALSE; | |
1996 | +static bfd_boolean avr_debug_relax = FALSE; | |
1997 | +static bfd_boolean avr_debug_stubs = FALSE; | |
1998 | +static bfd_boolean avr_replace_call_ret_sequences = TRUE; | |
1999 | +static bfd_vma avr_pc_wrap_around = 0x10000000; | |
2000 | + | |
2001 | +/* Transfers information to the bfd frontend. */ | |
2002 | + | |
2003 | +static void | |
2004 | +avr_elf_set_global_bfd_parameters (void) | |
2005 | +{ | |
2006 | + elf32_avr_setup_params (& link_info, | |
2007 | + stub_file->the_bfd, | |
2008 | + avr_stub_section, | |
2009 | + avr_no_stubs, | |
2010 | + avr_debug_stubs, | |
2011 | + avr_debug_relax, | |
2012 | + avr_pc_wrap_around, | |
2013 | + avr_replace_call_ret_sequences); | |
2014 | +} | |
2015 | + | |
2016 | + | |
2017 | +/* Makes a conservative estimate of the trampoline section size that could | |
2018 | + be corrected later on. */ | |
2019 | + | |
2020 | +static void | |
2021 | +avr_elf_${EMULATION_NAME}_before_allocation (void) | |
2022 | +{ | |
2023 | + int ret; | |
2024 | + | |
2025 | + gld${EMULATION_NAME}_before_allocation (); | |
2026 | + | |
2027 | + /* We only need stubs for the avr6 family. */ | |
2028 | + if (strcmp ("${EMULATION_NAME}","avr6")) | |
2029 | + avr_no_stubs = TRUE; | |
2030 | + | |
2031 | + avr_elf_set_global_bfd_parameters (); | |
2032 | + | |
2033 | + /* If generating a relocatable output file, then | |
2034 | + we don't have to generate the trampolines. */ | |
2035 | + if (link_info.relocatable) | |
2036 | + avr_no_stubs = TRUE; | |
2037 | + | |
2038 | + if (avr_no_stubs) | |
2039 | + return; | |
2040 | + | |
2041 | + ret = elf32_avr_setup_section_lists (output_bfd, &link_info); | |
2042 | + | |
2043 | + if (ret < 0) | |
2044 | + einfo ("%X%P: can not setup the input section list: %E\n"); | |
2045 | + | |
2046 | + if (ret <= 0) | |
2047 | + return; | |
2048 | + | |
2049 | + /* Call into the BFD backend to do the real "stub"-work. */ | |
2050 | + if (! elf32_avr_size_stubs (output_bfd, &link_info, TRUE)) | |
2051 | + einfo ("%X%P: can not size stub section: %E\n"); | |
2052 | +} | |
2053 | + | |
2054 | +/* This is called before the input files are opened. We create a new | |
2055 | + fake input file to hold the stub section and generate the section itself. */ | |
2056 | + | |
2057 | +static void | |
2058 | +avr_elf_create_output_section_statements (void) | |
2059 | +{ | |
2060 | + flagword flags; | |
2061 | + | |
2062 | + stub_file = lang_add_input_file ("linker stubs", | |
2063 | + lang_input_file_is_fake_enum, | |
2064 | + NULL); | |
2065 | + | |
2066 | + stub_file->the_bfd = bfd_create ("linker stubs", output_bfd); | |
2067 | + if (stub_file->the_bfd == NULL | |
2068 | + || !bfd_set_arch_mach (stub_file->the_bfd, | |
2069 | + bfd_get_arch (output_bfd), | |
2070 | + bfd_get_mach (output_bfd))) | |
2071 | + { | |
2072 | + einfo ("%X%P: can not create stub BFD %E\n"); | |
2073 | + return; | |
2074 | + } | |
2075 | + | |
2076 | + /* Now we add the stub section. */ | |
2077 | + | |
2078 | + avr_stub_section = bfd_make_section_anyway (stub_file->the_bfd, | |
2079 | + ".trampolines"); | |
2080 | + if (avr_stub_section == NULL) | |
2081 | + goto err_ret; | |
2082 | + | |
2083 | + flags = (SEC_ALLOC | SEC_LOAD | SEC_READONLY | SEC_CODE | |
2084 | + | SEC_HAS_CONTENTS | SEC_RELOC | SEC_IN_MEMORY | SEC_KEEP); | |
2085 | + if (!bfd_set_section_flags (stub_file->the_bfd, avr_stub_section, flags)) | |
2086 | + goto err_ret; | |
2087 | + | |
2088 | + avr_stub_section->alignment_power = 1; | |
2089 | + | |
2090 | + ldlang_add_file (stub_file); | |
2091 | + | |
2092 | + return; | |
2093 | + | |
2094 | + err_ret: | |
2095 | + einfo ("%X%P: can not make stub section: %E\n"); | |
2096 | + return; | |
2097 | +} | |
2098 | + | |
2099 | +/* Re-calculates the size of the stubs so that we won't waste space. */ | |
2100 | + | |
2101 | +static void | |
2102 | +avr_elf_finish (void) | |
2103 | +{ | |
2104 | + if (!avr_no_stubs) | |
2105 | + { | |
2106 | + /* Now build the linker stubs. */ | |
2107 | + if (stub_file->the_bfd->sections != NULL) | |
2108 | + { | |
2109 | + /* Call again the trampoline analyzer to initialize the trampoline | |
2110 | + stubs with the correct symbol addresses. Since there could have | |
2111 | + been relaxation, the symbol addresses that were found during | |
2112 | + first call may no longer be correct. */ | |
2113 | + if (!elf32_avr_size_stubs (output_bfd, &link_info, FALSE)) | |
2114 | + { | |
2115 | + einfo ("%X%P: can not size stub section: %E\n"); | |
2116 | + return; | |
2117 | + } | |
2118 | + | |
2119 | + if (!elf32_avr_build_stubs (&link_info)) | |
2120 | + einfo ("%X%P: can not build stubs: %E\n"); | |
2121 | + } | |
2122 | + } | |
2123 | + | |
2124 | + gld${EMULATION_NAME}_finish (); | |
2125 | +} | |
2126 | + | |
2127 | + | |
2128 | +EOF | |
2129 | + | |
2130 | + | |
2131 | +PARSE_AND_LIST_PROLOGUE=' | |
2132 | + | |
2133 | +#define OPTION_NO_CALL_RET_REPLACEMENT 301 | |
2134 | +#define OPTION_PMEM_WRAP_AROUND 302 | |
2135 | +#define OPTION_NO_STUBS 303 | |
2136 | +#define OPTION_DEBUG_STUBS 304 | |
2137 | +#define OPTION_DEBUG_RELAX 305 | |
2138 | +' | |
2139 | + | |
2140 | +PARSE_AND_LIST_LONGOPTS=' | |
2141 | + { "no-call-ret-replacement", no_argument, | |
2142 | + NULL, OPTION_NO_CALL_RET_REPLACEMENT}, | |
2143 | + { "pmem-wrap-around", required_argument, | |
2144 | + NULL, OPTION_PMEM_WRAP_AROUND}, | |
2145 | + { "no-stubs", no_argument, | |
2146 | + NULL, OPTION_NO_STUBS}, | |
2147 | + { "debug-stubs", no_argument, | |
2148 | + NULL, OPTION_DEBUG_STUBS}, | |
2149 | + { "debug-relax", no_argument, | |
2150 | + NULL, OPTION_DEBUG_RELAX}, | |
2151 | +' | |
2152 | + | |
2153 | +PARSE_AND_LIST_OPTIONS=' | |
2154 | + fprintf (file, _(" --pmem-wrap-around=<val> " | |
2155 | + "Make the linker relaxation machine assume that a\n" | |
2156 | + " " | |
2157 | + "program counter wrap-around occures at address\n" | |
2158 | + " " | |
2159 | + "<val>. Supported values are 16k, 32k and 64k.\n")); | |
2160 | + fprintf (file, _(" --no-call-ret-replacement " | |
2161 | + "The relaxation machine normally will\n" | |
2162 | + " " | |
2163 | + "substitute two immediately following call/ret\n" | |
2164 | + " " | |
2165 | + "instructions by a single jump instruction.\n" | |
2166 | + " " | |
2167 | + "This option disables this optimization.\n")); | |
2168 | + fprintf (file, _(" --no-stubs " | |
2169 | + "If the linker detects to attempt to access\n" | |
2170 | + " " | |
2171 | + "an instruction beyond 128k by a reloc that\n" | |
2172 | + " " | |
2173 | + "is limited to 128k max, it inserts a jump\n" | |
2174 | + " " | |
2175 | + "stub. You can de-active this with this switch.\n")); | |
2176 | + fprintf (file, _(" --debug-stubs Used for debugging avr-ld.\n")); | |
2177 | + fprintf (file, _(" --debug-relax Used for debugging avr-ld.\n")); | |
2178 | +' | |
2179 | + | |
2180 | +PARSE_AND_LIST_ARGS_CASES=' | |
2181 | + | |
2182 | + case OPTION_PMEM_WRAP_AROUND: | |
2183 | + { | |
2184 | + /* This variable is defined in the bfd library. */ | |
2185 | + if ((!strcmp (optarg,"32k")) || (!strcmp (optarg,"32K"))) | |
2186 | + avr_pc_wrap_around = 32768; | |
2187 | + else if ((!strcmp (optarg,"16k")) || (!strcmp (optarg,"16K"))) | |
2188 | + avr_pc_wrap_around = 16384; | |
2189 | + else if ((!strcmp (optarg,"64k")) || (!strcmp (optarg,"64K"))) | |
2190 | + avr_pc_wrap_around = 0x10000; | |
2191 | + else | |
2192 | + return FALSE; | |
2193 | + } | |
2194 | + break; | |
2195 | + | |
2196 | + case OPTION_DEBUG_STUBS: | |
2197 | + avr_debug_stubs = TRUE; | |
2198 | + break; | |
2199 | + | |
2200 | + case OPTION_DEBUG_RELAX: | |
2201 | + avr_debug_relax = TRUE; | |
2202 | + break; | |
2203 | + | |
2204 | + case OPTION_NO_STUBS: | |
2205 | + avr_no_stubs = TRUE; | |
2206 | + break; | |
2207 | + | |
2208 | + case OPTION_NO_CALL_RET_REPLACEMENT: | |
2209 | + { | |
2210 | + /* This variable is defined in the bfd library. */ | |
2211 | + avr_replace_call_ret_sequences = FALSE; | |
2212 | + } | |
2213 | + break; | |
2214 | +' | |
2215 | + | |
2216 | +# | |
2217 | +# Put these extra avr-elf routines in ld_${EMULATION_NAME}_emulation | |
2218 | +# | |
2219 | +LDEMUL_BEFORE_ALLOCATION=avr_elf_${EMULATION_NAME}_before_allocation | |
2220 | +LDEMUL_FINISH=avr_elf_finish | |
2221 | +LDEMUL_CREATE_OUTPUT_SECTION_STATEMENTS=avr_elf_create_output_section_statements | |
2222 | diff -Nur ld/Makefile.am ld/Makefile.am | |
2223 | --- ld/Makefile.am 2006-06-03 06:45:50.000000000 +0200 | |
2224 | +++ ld/Makefile.am 2006-08-28 20:02:17.055286703 +0200 | |
2225 | @@ -133,6 +133,7 @@ | |
2226 | eavr3.o \ | |
2227 | eavr4.o \ | |
2228 | eavr5.o \ | |
2229 | + eavr6.o \ | |
2230 | ecoff_i860.o \ | |
2231 | ecoff_sparc.o \ | |
2232 | ecrisaout.o \ | |
2233 | @@ -595,6 +596,10 @@ | |
2234 | $(srcdir)/emultempl/generic.em $(srcdir)/scripttempl/avr.sc \ | |
2235 | ${GEN_DEPENDS} | |
2236 | ${GENSCRIPTS} avr5 "$(tdir_avr2)" | |
2237 | +eavr6.c: $(srcdir)/emulparams/avr6.sh \ | |
2238 | + $(srcdir)/emultempl/generic.em $(srcdir)/scripttempl/avr.sc \ | |
2239 | + ${GEN_DEPENDS} | |
2240 | + ${GENSCRIPTS} avr6 "$(tdir_avr2)" | |
2241 | ecoff_i860.c: $(srcdir)/emulparams/coff_i860.sh \ | |
2242 | $(srcdir)/emultempl/generic.em $(srcdir)/scripttempl/i860coff.sc ${GEN_DEPENDS} | |
2243 | ${GENSCRIPTS} coff_i860 "$(tdir_coff_i860)" | |
2244 | diff -Nur ld/Makefile.in ld/Makefile.in | |
2245 | --- ld/Makefile.in 2006-06-03 06:45:50.000000000 +0200 | |
2246 | +++ ld/Makefile.in 2006-08-28 20:02:17.072285471 +0200 | |
2247 | @@ -357,6 +357,7 @@ | |
2248 | eavr3.o \ | |
2249 | eavr4.o \ | |
2250 | eavr5.o \ | |
2251 | + eavr6.o \ | |
2252 | ecoff_i860.o \ | |
2253 | ecoff_sparc.o \ | |
2254 | ecrisaout.o \ | |
2255 | @@ -1406,6 +1407,10 @@ | |
2256 | $(srcdir)/emultempl/generic.em $(srcdir)/scripttempl/avr.sc \ | |
2257 | ${GEN_DEPENDS} | |
2258 | ${GENSCRIPTS} avr5 "$(tdir_avr2)" | |
2259 | +eavr6.c: $(srcdir)/emulparams/avr6.sh \ | |
2260 | + $(srcdir)/emultempl/generic.em $(srcdir)/scripttempl/avr.sc \ | |
2261 | + ${GEN_DEPENDS} | |
2262 | + ${GENSCRIPTS} avr6 "$(tdir_avr2)" | |
2263 | ecoff_i860.c: $(srcdir)/emulparams/coff_i860.sh \ | |
2264 | $(srcdir)/emultempl/generic.em $(srcdir)/scripttempl/i860coff.sc ${GEN_DEPENDS} | |
2265 | ${GENSCRIPTS} coff_i860 "$(tdir_coff_i860)" | |
2266 | diff -Nur ld/scripttempl/avr.sc ld/scripttempl/avr.sc | |
2267 | --- ld/scripttempl/avr.sc 2006-03-03 16:25:31.000000000 +0100 | |
2268 | +++ ld/scripttempl/avr.sc 2006-08-28 20:02:17.078285036 +0200 | |
2269 | @@ -71,12 +71,32 @@ | |
2270 | .rel.plt ${RELOCATING-0} : { *(.rel.plt) } | |
2271 | .rela.plt ${RELOCATING-0} : { *(.rela.plt) } | |
2272 | ||
2273 | - /* Internal text space or external memory */ | |
2274 | + /* Internal text space or external memory. */ | |
2275 | .text : | |
2276 | { | |
2277 | *(.vectors) | |
2278 | KEEP(*(.vectors)) | |
2279 | ||
2280 | + /* For data that needs to reside in the lower 64k of progmem. */ | |
2281 | + *(.progmem.gcc*) | |
2282 | + *(.progmem*) | |
2283 | + ${RELOCATING+. = ALIGN(2);} | |
2284 | + | |
2285 | + ${CONSTRUCTING+ __trampolines_start = . ; } | |
2286 | + /* The jump trampolines for the 16-bit limited relocs will reside here. */ | |
2287 | + *(.trampolines) | |
2288 | + *(.trampolines*) | |
2289 | + ${CONSTRUCTING+ __trampolines_end = . ; } | |
2290 | + | |
2291 | + /* For future tablejump instruction arrays for 3 byte pc devices. | |
2292 | + We don't relax jump/call instructions within these sections. */ | |
2293 | + *(.jumptables) | |
2294 | + *(.jumptables*) | |
2295 | + | |
2296 | + /* For code that needs to reside in the lower 128k progmem. */ | |
2297 | + *(.lowtext) | |
2298 | + *(.lowtext*) | |
2299 | + | |
2300 | ${CONSTRUCTING+ __ctors_start = . ; } | |
2301 | ${CONSTRUCTING+ *(.ctors) } | |
2302 | ${CONSTRUCTING+ __ctors_end = . ; } | |
2303 | @@ -86,18 +106,8 @@ | |
2304 | KEEP(SORT(*)(.ctors)) | |
2305 | KEEP(SORT(*)(.dtors)) | |
2306 | ||
2307 | - /* For data that needs to reside in the lower 64k of progmem */ | |
2308 | - *(.progmem.gcc*) | |
2309 | - *(.progmem*) | |
2310 | - ${RELOCATING+. = ALIGN(2);} | |
2311 | - | |
2312 | - /* for future tablejump instruction arrays for 3 byte pc devices */ | |
2313 | - *(.jumptables) | |
2314 | - *(.jumptables*) | |
2315 | - /* for code that needs to reside in the lower 128k progmem */ | |
2316 | - *(.lowtext) | |
2317 | - *(.lowtext*) | |
2318 | - | |
2319 | + /* From this point on, we don't bother about wether the insns are | |
2320 | + below or above the 16 bits boundary. */ | |
2321 | *(.init0) /* Start here after reset. */ | |
2322 | KEEP (*(.init0)) | |
2323 | *(.init1) |