]>
Commit | Line | Data |
---|---|---|
31ce1ede JR |
1 | diff -Naurp bfd/elf32-avr.c bfd/elf32-avr.c |
2 | --- bfd/elf32-avr.c 2013-01-02 16:27:32.000000000 +0530 | |
3 | +++ bfd/elf32-avr.c 2013-01-02 16:28:50.000000000 +0530 | |
4 | @@ -34,6 +34,15 @@ static bfd_boolean debug_relax = FALSE; | |
5 | /* Enable debugging printout at stdout with this variable. */ | |
6 | static bfd_boolean debug_stubs = FALSE; | |
7 | ||
8 | +static bfd_reloc_status_type | |
9 | +bfd_elf_avr_diff_reloc (bfd *abfd, | |
10 | + arelent *reloc_entry, | |
11 | + asymbol *symbol, | |
12 | + void *data, | |
13 | + asection *input_section, | |
14 | + bfd *output_bfd, | |
15 | + char **error_message); | |
16 | + | |
17 | /* Hash table initialization and handling. Code is taken from the hppa port | |
18 | and adapted to the needs of AVR. */ | |
19 | ||
20 | @@ -573,6 +582,45 @@ static reloc_howto_type elf_avr_howto_ta | |
21 | 0xffff, /* src_mask */ | |
22 | 0xffff, /* dst_mask */ | |
23 | FALSE), /* pcrel_offset */ | |
24 | + HOWTO (R_AVR_DIFF8, /* type */ | |
25 | + 0, /* rightshift */ | |
26 | + 0, /* size (0 = byte, 1 = short, 2 = long) */ | |
27 | + 8, /* bitsize */ | |
28 | + FALSE, /* pc_relative */ | |
29 | + 0, /* bitpos */ | |
30 | + complain_overflow_bitfield, /* complain_on_overflow */ | |
31 | + bfd_elf_avr_diff_reloc, /* special_function */ | |
32 | + "R_AVR_DIFF8", /* name */ | |
33 | + FALSE, /* partial_inplace */ | |
34 | + 0, /* src_mask */ | |
35 | + 0xff, /* dst_mask */ | |
36 | + FALSE), /* pcrel_offset */ | |
37 | + HOWTO (R_AVR_DIFF16, /* type */ | |
38 | + 0, /* rightshift */ | |
39 | + 1, /* size (0 = byte, 1 = short, 2 = long) */ | |
40 | + 16, /* bitsize */ | |
41 | + FALSE, /* pc_relative */ | |
42 | + 0, /* bitpos */ | |
43 | + complain_overflow_bitfield, /* complain_on_overflow */ | |
44 | + bfd_elf_avr_diff_reloc, /* special_function */ | |
45 | + "R_AVR_DIFF16", /* name */ | |
46 | + FALSE, /* partial_inplace */ | |
47 | + 0, /* src_mask */ | |
48 | + 0xffff, /* dst_mask */ | |
49 | + FALSE), /* pcrel_offset */ | |
50 | + HOWTO (R_AVR_DIFF32, /* type */ | |
51 | + 0, /* rightshift */ | |
52 | + 2, /* size (0 = byte, 1 = short, 2 = long) */ | |
53 | + 32, /* bitsize */ | |
54 | + FALSE, /* pc_relative */ | |
55 | + 0, /* bitpos */ | |
56 | + complain_overflow_bitfield, /* complain_on_overflow */ | |
57 | + bfd_elf_avr_diff_reloc, /* special_function */ | |
58 | + "R_AVR_DIFF32", /* name */ | |
59 | + FALSE, /* partial_inplace */ | |
60 | + 0, /* src_mask */ | |
61 | + 0xffffffff, /* dst_mask */ | |
62 | + FALSE) /* pcrel_offset */ | |
63 | }; | |
64 | ||
65 | /* Map BFD reloc types to AVR ELF reloc types. */ | |
66 | @@ -615,7 +663,10 @@ static const struct avr_reloc_map avr_re | |
67 | { BFD_RELOC_AVR_8_LO, R_AVR_8_LO8 }, | |
68 | { BFD_RELOC_AVR_8_HI, R_AVR_8_HI8 }, | |
69 | { BFD_RELOC_AVR_8_HLO, R_AVR_8_HLO8 }, | |
70 | - { BFD_RELOC_AVR_7_LDS16, R_AVR_7_LDS16 } | |
71 | + { BFD_RELOC_AVR_7_LDS16, R_AVR_7_LDS16 }, | |
72 | + { BFD_RELOC_AVR_DIFF8, R_AVR_DIFF8 }, | |
73 | + { BFD_RELOC_AVR_DIFF16, R_AVR_DIFF16 }, | |
74 | + { BFD_RELOC_AVR_DIFF32, R_AVR_DIFF32 } | |
75 | }; | |
76 | ||
77 | /* Meant to be filled one day with the wrap around address for the | |
78 | @@ -823,6 +874,22 @@ avr_get_stub_addr (bfd_vma srel, | |
79 | return 0x020000; | |
80 | } | |
81 | ||
82 | +/* Perform a diff relocation. Nothing to do, as the difference value is already | |
83 | + written into the section's contents. */ | |
84 | + | |
85 | +static bfd_reloc_status_type | |
86 | +bfd_elf_avr_diff_reloc (bfd *abfd ATTRIBUTE_UNUSED, | |
87 | + arelent *reloc_entry ATTRIBUTE_UNUSED, | |
88 | + asymbol *symbol ATTRIBUTE_UNUSED, | |
89 | + void *data ATTRIBUTE_UNUSED, | |
90 | + asection *input_section ATTRIBUTE_UNUSED, | |
91 | + bfd *output_bfd ATTRIBUTE_UNUSED, | |
92 | + char **error_message ATTRIBUTE_UNUSED) | |
93 | +{ | |
94 | + return bfd_reloc_ok; | |
95 | +} | |
96 | + | |
97 | + | |
98 | /* Perform a single relocation. By default we use the standard BFD | |
99 | routines, but a few relocs, we have to do them ourselves. */ | |
100 | ||
101 | @@ -1186,6 +1253,13 @@ avr_final_link_relocate (reloc_howto_typ | |
102 | bfd_put_16 (input_bfd, (bfd_vma) srel &0x00ffff, contents); | |
103 | break; | |
104 | ||
105 | + case R_AVR_DIFF8: | |
106 | + case R_AVR_DIFF16: | |
107 | + case R_AVR_DIFF32: | |
108 | + /* Nothing to do here, as contents already contains the diff value. */ | |
109 | + r = bfd_reloc_ok; | |
110 | + break; | |
111 | + | |
112 | default: | |
113 | r = _bfd_final_link_relocate (howto, input_bfd, input_section, | |
114 | contents, rel->r_offset, | |
115 | @@ -1502,6 +1576,99 @@ elf32_avr_object_p (bfd *abfd) | |
116 | e_set); | |
117 | } | |
118 | ||
119 | +/* Returns whether the relocation type passed is a diff reloc. */ | |
120 | + | |
121 | +static bfd_boolean | |
122 | +elf32_avr_is_diff_reloc (Elf_Internal_Rela *irel) | |
123 | +{ | |
124 | + return (ELF32_R_TYPE (irel->r_info) == R_AVR_DIFF8 | |
125 | + ||ELF32_R_TYPE (irel->r_info) == R_AVR_DIFF16 | |
126 | + || ELF32_R_TYPE (irel->r_info) == R_AVR_DIFF32); | |
127 | +} | |
128 | + | |
129 | +/* Reduce the value written in the section by count if the shrinked insn address | |
130 | + happens to fall between the two symbols for which this diff reloc was | |
131 | + emitted. */ | |
132 | + | |
133 | +static void | |
134 | +elf32_avr_adjust_diff_reloc_value (bfd *abfd, | |
135 | + struct bfd_section *isec, | |
136 | + Elf_Internal_Rela *irel, | |
137 | + bfd_vma symval, | |
138 | + bfd_vma shrinked_insn_address, | |
139 | + int count) | |
140 | +{ | |
141 | + unsigned char *isec_contents = elf_section_data (isec)->this_hdr.contents; | |
142 | + if (isec_contents == NULL) | |
143 | + { | |
144 | + if (! bfd_malloc_and_get_section (abfd, isec, &isec_contents)) | |
145 | + return; | |
146 | + } | |
147 | + | |
148 | + isec_contents += irel->r_offset; | |
149 | + | |
150 | + /* Read value written in object file. */ | |
151 | + bfd_vma x = 0; | |
152 | + switch (ELF32_R_TYPE (irel->r_info)) | |
153 | + { | |
154 | + case R_AVR_DIFF8: | |
155 | + { | |
156 | + x = *isec_contents; | |
157 | + break; | |
158 | + } | |
159 | + case R_AVR_DIFF16: | |
160 | + { | |
161 | + x = bfd_get_16 (abfd, isec_contents); | |
162 | + break; | |
163 | + } | |
164 | + case R_AVR_DIFF32: | |
165 | + { | |
166 | + x = bfd_get_32 (abfd, isec_contents); | |
167 | + break; | |
168 | + } | |
169 | + default: | |
170 | + { | |
171 | + BFD_FAIL(); | |
172 | + } | |
173 | + } | |
174 | + | |
175 | + /* For a diff reloc sym1 - sym2 the diff at assembly time (x) is written | |
176 | + into the object file. sym2's value is represented as | |
177 | + <start_of_section> + addend. Check if the shrinked insn falls between | |
178 | + sym1 and sym2. */ | |
179 | + | |
180 | + bfd_vma end_address = symval + irel->r_addend; | |
181 | + bfd_vma start_address = end_address - x; | |
182 | + | |
183 | + if (shrinked_insn_address >= start_address && | |
184 | + shrinked_insn_address <= end_address) | |
185 | + { | |
186 | + switch (ELF32_R_TYPE (irel->r_info)) | |
187 | + { | |
188 | + case R_AVR_DIFF8: | |
189 | + { | |
190 | + *isec_contents = (x - count); | |
191 | + break; | |
192 | + } | |
193 | + case R_AVR_DIFF16: | |
194 | + { | |
195 | + bfd_put_16 (abfd, (x - count) & 0xFFFF, isec_contents); | |
196 | + break; | |
197 | + } | |
198 | + case R_AVR_DIFF32: | |
199 | + { | |
200 | + bfd_put_32 (abfd, (x - count) & 0xFFFFFFFF, isec_contents); | |
201 | + break; | |
202 | + } | |
203 | + default: | |
204 | + { | |
205 | + BFD_FAIL(); | |
206 | + } | |
207 | + } | |
208 | + | |
209 | + elf_section_data (isec)->this_hdr.contents = isec_contents - irel->r_offset; | |
210 | + } | |
211 | +} | |
212 | ||
213 | /* Delete some bytes from a section while changing the size of an instruction. | |
214 | The parameter "addr" denotes the section-relative offset pointing just | |
215 | @@ -1640,6 +1807,14 @@ elf32_avr_relax_delete_bytes (bfd *abfd, | |
216 | if (symval <= shrinked_insn_address | |
217 | && (symval + irel->r_addend) > shrinked_insn_address) | |
218 | { | |
219 | + if (elf32_avr_is_diff_reloc (irel)) | |
220 | + { | |
221 | + elf32_avr_adjust_diff_reloc_value (abfd, isec, irel, | |
222 | + symval, | |
223 | + shrinked_insn_address, | |
224 | + count); | |
225 | + } | |
226 | + | |
227 | irel->r_addend -= count; | |
228 | ||
229 | if (debug_relax) | |
230 | diff -Naurp bfd/reloc.c bfd/reloc.c | |
231 | --- bfd/reloc.c 2013-01-02 16:27:32.000000000 +0530 | |
232 | +++ bfd/reloc.c 2013-01-02 16:28:50.000000000 +0530 | |
233 | @@ -4414,6 +4414,19 @@ ENUM | |
234 | ENUMDOC | |
235 | This is a 7 bit reloc for the AVR that stores offset for 16bit sts/lds | |
236 | instructions supported only by Tiny core | |
237 | +ENUM | |
238 | + BFD_RELOC_AVR_DIFF8 | |
239 | +ENUMX | |
240 | + BFD_RELOC_AVR_DIFF16 | |
241 | +ENUMX | |
242 | + BFD_RELOC_AVR_DIFF32 | |
243 | +ENUMDOC | |
244 | + AVR relocations to mark the difference of two local symbols. | |
245 | + These are only needed to support linker relaxation and can be ignored | |
246 | + when not relaxing. The field is set to the value of the difference | |
247 | + assuming no relaxation. The relocation encodes the position of the | |
248 | + second symbol so the linker can determine whether to adjust the field | |
249 | + value. | |
250 | ||
251 | ENUM | |
252 | BFD_RELOC_RL78_NEG8 | |
253 | diff -Naurp gas/config/tc-avr.c gas/config/tc-avr.c | |
254 | --- gas/config/tc-avr.c 2013-01-02 16:28:02.000000000 +0530 | |
255 | +++ gas/config/tc-avr.c 2013-01-02 16:28:50.000000000 +0530 | |
256 | @@ -342,9 +342,11 @@ struct avr_opt_s | |
257 | int all_opcodes; /* -mall-opcodes: accept all known AVR opcodes. */ | |
258 | int no_skip_bug; /* -mno-skip-bug: no warnings for skipping 2-word insns. */ | |
259 | int no_wrap; /* -mno-wrap: reject rjmp/rcall with 8K wrap-around. */ | |
260 | + int link_relax; /* -mlink-relax: generate relocations for linker | |
261 | + relaxation. */ | |
262 | }; | |
263 | ||
264 | -static struct avr_opt_s avr_opt = { 0, 0, 0 }; | |
265 | +static struct avr_opt_s avr_opt = { 0, 0, 0, 0 }; | |
266 | ||
267 | const char EXP_CHARS[] = "eE"; | |
268 | const char FLT_CHARS[] = "dD"; | |
269 | @@ -404,7 +406,8 @@ enum options | |
270 | { | |
271 | OPTION_ALL_OPCODES = OPTION_MD_BASE + 1, | |
272 | OPTION_NO_SKIP_BUG, | |
273 | - OPTION_NO_WRAP | |
274 | + OPTION_NO_WRAP, | |
275 | + OPTION_LINK_RELAX | |
276 | }; | |
277 | ||
278 | struct option md_longopts[] = | |
279 | @@ -413,6 +416,7 @@ struct option md_longopts[] = | |
280 | { "mall-opcodes", no_argument, NULL, OPTION_ALL_OPCODES }, | |
281 | { "mno-skip-bug", no_argument, NULL, OPTION_NO_SKIP_BUG }, | |
282 | { "mno-wrap", no_argument, NULL, OPTION_NO_WRAP }, | |
283 | + { "mlink-relax", no_argument, NULL, OPTION_LINK_RELAX }, | |
284 | { NULL, no_argument, NULL, 0 } | |
285 | }; | |
286 | ||
287 | @@ -518,7 +522,9 @@ md_show_usage (FILE *stream) | |
288 | " -mno-skip-bug disable warnings for skipping two-word instructions\n" | |
289 | " (default for avr4, avr5)\n" | |
290 | " -mno-wrap reject rjmp/rcall instructions with 8K wrap-around\n" | |
291 | - " (default for avr3, avr5)\n")); | |
292 | + " (default for avr3, avr5)\n" | |
293 | + " -mlink-relax generate relocations for linker relaxation\n" | |
294 | + )); | |
295 | show_mcu_list (stream); | |
296 | } | |
297 | ||
298 | @@ -580,6 +586,9 @@ md_parse_option (int c, char *arg) | |
299 | case OPTION_NO_WRAP: | |
300 | avr_opt.no_wrap = 1; | |
301 | return 1; | |
302 | + case OPTION_LINK_RELAX: | |
303 | + avr_opt.link_relax = 1; | |
304 | + return 1; | |
305 | } | |
306 | ||
307 | return 0; | |
308 | @@ -630,6 +639,7 @@ md_begin (void) | |
309 | } | |
310 | ||
311 | bfd_set_arch_mach (stdoutput, TARGET_ARCH, avr_mcu->mach); | |
312 | + linkrelax = avr_opt.link_relax; | |
313 | } | |
314 | ||
315 | /* Resolve STR as a constant expression and return the result. | |
316 | @@ -1205,6 +1215,53 @@ md_pcrel_from_section (fixS *fixp, segT | |
317 | return fixp->fx_frag->fr_address + fixp->fx_where; | |
318 | } | |
319 | ||
320 | +static bfd_boolean | |
321 | +relaxable_section (asection *sec) | |
322 | +{ | |
323 | + return (sec->flags & SEC_DEBUGGING) == 0; | |
324 | +} | |
325 | + | |
326 | +/* Does whatever the xtensa port does. */ | |
327 | +int | |
328 | +avr_validate_fix_sub (fixS *fix) | |
329 | +{ | |
330 | + segT add_symbol_segment, sub_symbol_segment; | |
331 | + | |
332 | + /* The difference of two symbols should be resolved by the assembler when | |
333 | + linkrelax is not set. If the linker may relax the section containing | |
334 | + the symbols, then an Xtensa DIFF relocation must be generated so that | |
335 | + the linker knows to adjust the difference value. */ | |
336 | + if (!linkrelax || fix->fx_addsy == NULL) | |
337 | + return 0; | |
338 | + | |
339 | + /* Make sure both symbols are in the same segment, and that segment is | |
340 | + "normal" and relaxable. If the segment is not "normal", then the | |
341 | + fix is not valid. If the segment is not "relaxable", then the fix | |
342 | + should have been handled earlier. */ | |
343 | + add_symbol_segment = S_GET_SEGMENT (fix->fx_addsy); | |
344 | + if (! SEG_NORMAL (add_symbol_segment) || | |
345 | + ! relaxable_section (add_symbol_segment)) | |
346 | + return 0; | |
347 | + | |
348 | + sub_symbol_segment = S_GET_SEGMENT (fix->fx_subsy); | |
349 | + return (sub_symbol_segment == add_symbol_segment); | |
350 | +} | |
351 | + | |
352 | +/* TC_FORCE_RELOCATION hook */ | |
353 | + | |
354 | +/* If linkrelax is turned on, and the symbol to relocate | |
355 | + against is in a relaxable segment, don't compute the value - | |
356 | + generate a relocation instead. */ | |
357 | +int | |
358 | +avr_force_relocation (fixS *fix) | |
359 | +{ | |
360 | + if (linkrelax && fix->fx_addsy | |
361 | + && relaxable_section (S_GET_SEGMENT (fix->fx_addsy))) | |
362 | + return 1; | |
363 | + | |
364 | + return generic_force_reloc (fix); | |
365 | +} | |
366 | + | |
367 | /* GAS will call this for each fixup. It should store the correct | |
368 | value in the object file. */ | |
369 | ||
370 | @@ -1228,11 +1285,46 @@ md_apply_fix (fixS *fixP, valueT * valP, | |
371 | fixP->fx_done = 1; | |
372 | } | |
373 | } | |
374 | + else if (linkrelax && fixP->fx_subsy) | |
375 | + { | |
376 | + /* For a subtraction relocation expression, generate one | |
377 | + of the DIFF relocs, with the value being the difference. | |
378 | + Note that a sym1 - sym2 expression is adjusted into a | |
379 | + section_start_sym + sym2_offset_from_section_start - sym1 | |
380 | + expression. fixP->fx_addsy holds the section start symbol, | |
381 | + fixP->fx_offset holds sym2's offset, and fixP->fx_subsy | |
382 | + holds sym1. Calculate and write value, but leave fx_offset | |
383 | + as is - during relaxation, fx_offset - value gives sym1's value */ | |
384 | + | |
385 | + switch (fixP->fx_r_type) | |
386 | + { | |
387 | + case BFD_RELOC_8: | |
388 | + fixP->fx_r_type = BFD_RELOC_AVR_DIFF8; | |
389 | + break; | |
390 | + case BFD_RELOC_16: | |
391 | + fixP->fx_r_type = BFD_RELOC_AVR_DIFF16; | |
392 | + break; | |
393 | + case BFD_RELOC_32: | |
394 | + fixP->fx_r_type = BFD_RELOC_AVR_DIFF32; | |
395 | + break; | |
396 | + default: | |
397 | + as_bad_where (fixP->fx_file, fixP->fx_line, _("expression too complex")); | |
398 | + break; | |
399 | + } | |
400 | + | |
401 | + value = S_GET_VALUE (fixP->fx_addsy) + | |
402 | + fixP->fx_offset - S_GET_VALUE (fixP->fx_subsy); | |
403 | ||
404 | + fixP->fx_subsy = NULL; | |
405 | + } | |
406 | /* We don't actually support subtracting a symbol. */ | |
407 | if (fixP->fx_subsy != (symbolS *) NULL) | |
408 | as_bad_where (fixP->fx_file, fixP->fx_line, _("expression too complex")); | |
409 | ||
410 | + /* For the DIFF relocs, write the value into the object file while still | |
411 | + keeping fx_done FALSE, as both the difference (recorded in the object file) | |
412 | + and the sym offset (part of fixP) are needed at link relax time */ | |
413 | + where = (unsigned char *) fixP->fx_frag->fr_literal + fixP->fx_where; | |
414 | switch (fixP->fx_r_type) | |
415 | { | |
416 | default: | |
417 | @@ -1242,6 +1334,19 @@ md_apply_fix (fixS *fixP, valueT * valP, | |
418 | case BFD_RELOC_AVR_13_PCREL: | |
419 | case BFD_RELOC_32: | |
420 | case BFD_RELOC_16: | |
421 | + break; | |
422 | + case BFD_RELOC_AVR_DIFF8: | |
423 | + if (value > 255 || value < -128) | |
424 | + as_warn_where (fixP->fx_file, fixP->fx_line, | |
425 | + _("operand out of range: %ld"), value); | |
426 | + *where = value; | |
427 | + break; | |
428 | + case BFD_RELOC_AVR_DIFF16: | |
429 | + bfd_putl16 ((bfd_vma) value, where); | |
430 | + break; | |
431 | + case BFD_RELOC_AVR_DIFF32: | |
432 | + bfd_putl16 ((bfd_vma) value, where); | |
433 | + break; | |
434 | case BFD_RELOC_AVR_CALL: | |
435 | break; | |
436 | } | |
437 | diff -Naurp gas/config/tc-avr.h gas/config/tc-avr.h | |
438 | --- gas/config/tc-avr.h 2011-03-29 23:46:15.000000000 +0530 | |
439 | +++ gas/config/tc-avr.h 2013-01-02 16:28:50.000000000 +0530 | |
440 | @@ -93,6 +93,18 @@ extern void avr_cons_fix_new (fragS *,in | |
441 | visible symbols can be overridden. */ | |
442 | #define EXTERN_FORCE_RELOC 0 | |
443 | ||
444 | +/* If defined, this macro allows control over whether fixups for a | |
445 | + given section will be processed when the linkrelax variable is | |
446 | + set. Define it to zero and handle things in md_apply_fix instead.*/ | |
447 | +#define TC_LINKRELAX_FIXUP(SEG) 0 | |
448 | + | |
449 | +/* If this macro returns non-zero, it guarantees that a relocation will be emitted | |
450 | + even when the value can be resolved locally. Do that if linkrelax is turned on */ | |
451 | +#define TC_FORCE_RELOCATION(fix) avr_force_relocation (fix) | |
452 | +#define TC_FORCE_RELOCATION_SUB_SAME(fix, seg) \ | |
453 | + (! SEG_NORMAL (seg) || avr_force_relocation (fix)) | |
454 | +extern int avr_force_relocation (struct fix *); | |
455 | + | |
456 | /* Values passed to md_apply_fix don't include the symbol value. */ | |
457 | #define MD_APPLY_SYM_VALUE(FIX) 0 | |
458 | ||
459 | @@ -144,6 +156,12 @@ extern long md_pcrel_from_section (struc | |
460 | { \ | |
461 | goto SKIP; \ | |
462 | } | |
463 | + | |
464 | +/* This macro is evaluated for any fixup with a fx_subsy that | |
465 | + fixup_segment cannot reduce to a number. If the macro returns | |
466 | + false an error will be reported. */ | |
467 | +#define TC_VALIDATE_FIX_SUB(fix, seg) avr_validate_fix_sub (fix) | |
468 | +extern int avr_validate_fix_sub (struct fix *); | |
469 | ||
470 | /* This target is buggy, and sets fix size too large. */ | |
471 | #define TC_FX_SIZE_SLACK(FIX) 2 | |
472 | diff -Naurp include/elf/avr.h include/elf/avr.h | |
473 | --- include/elf/avr.h 2013-01-02 16:27:32.000000000 +0530 | |
474 | +++ include/elf/avr.h 2013-01-02 16:28:50.000000000 +0530 | |
475 | @@ -83,6 +83,9 @@ START_RELOC_NUMBERS (elf_avr_reloc_type) | |
476 | RELOC_NUMBER (R_AVR_8_HI8, 28) | |
477 | RELOC_NUMBER (R_AVR_8_HLO8, 29) | |
478 | RELOC_NUMBER (R_AVR_7_LDS16, 30) | |
479 | + RELOC_NUMBER (R_AVR_DIFF8, 31) | |
480 | + RELOC_NUMBER (R_AVR_DIFF16, 32) | |
481 | + RELOC_NUMBER (R_AVR_DIFF32, 33) | |
482 | END_RELOC_NUMBERS (R_AVR_max) | |
483 | ||
484 | #endif /* _ELF_AVR_H */ |