]>
Commit | Line | Data |
---|---|---|
f33182aa | 1 | diff -uNdr binutils-2.17.50.0.18-old/bfd/Makefile.am binutils-2.17.50.0.18/bfd/Makefile.am |
2 | --- binutils-2.17.50.0.18-old/bfd/Makefile.am 2007-08-01 15:11:47.000000000 +0200 | |
3 | +++ binutils-2.17.50.0.18/bfd/Makefile.am 2007-10-20 16:45:33.000000000 +0200 | |
4 | @@ -208,6 +208,8 @@ | |
5 | coff-apollo.lo \ | |
6 | coff-arm.lo \ | |
7 | coff-aux.lo \ | |
8 | + coff-avr.lo \ | |
9 | + coff-ext-avr.lo \ | |
10 | coff-h8300.lo \ | |
11 | coff-h8500.lo \ | |
12 | coff-i386.lo \ | |
13 | @@ -387,6 +389,8 @@ | |
14 | coff-apollo.c \ | |
15 | coff-arm.c \ | |
16 | coff-aux.c \ | |
17 | + coff-avr.c \ | |
18 | + coff-ext-avr.c \ | |
19 | coff-h8300.c \ | |
20 | coff-h8500.c \ | |
21 | coff-i386.c \ | |
22 | @@ -1186,6 +1190,12 @@ | |
23 | coff-m68k.c $(INCDIR)/hashtab.h $(INCDIR)/coff/m68k.h \ | |
24 | $(INCDIR)/coff/internal.h libcoff.h $(INCDIR)/bfdlink.h \ | |
25 | coffcode.h coffswap.h | |
26 | +coff-avr.lo: coff-avr.c $(INCDIR)/filenames.h $(INCDIR)/coff/avr.h \ | |
27 | + $(INCDIR)/coff/external.h $(INCDIR)/coff/internal.h \ | |
28 | + libcoff.h $(INCDIR)/bfdlink.h coffcode.h coffswap.h | |
29 | +coff-ext-avr.lo: coff-ext-avr.c $(INCDIR)/filenames.h $(INCDIR)/coff/avr.h \ | |
30 | + $(INCDIR)/coff/external.h $(INCDIR)/coff/internal.h \ | |
31 | + libcoff.h $(INCDIR)/bfdlink.h coffcode.h coffswap.h | |
32 | coff-h8300.lo: coff-h8300.c $(INCDIR)/filenames.h $(INCDIR)/hashtab.h \ | |
33 | $(INCDIR)/bfdlink.h genlink.h $(INCDIR)/coff/h8300.h \ | |
34 | $(INCDIR)/coff/external.h $(INCDIR)/coff/internal.h \ | |
35 | diff -uNdr binutils-2.17.50.0.18-old/bfd/Makefile.in binutils-2.17.50.0.18/bfd/Makefile.in | |
36 | --- binutils-2.17.50.0.18-old/bfd/Makefile.in 2007-10-20 15:38:12.000000000 +0200 | |
37 | +++ binutils-2.17.50.0.18/bfd/Makefile.in 2007-10-20 16:45:33.000000000 +0200 | |
38 | @@ -458,6 +458,8 @@ | |
39 | coff-apollo.lo \ | |
40 | coff-arm.lo \ | |
41 | coff-aux.lo \ | |
42 | + coff-avr.lo \ | |
43 | + coff-ext-avr.lo \ | |
44 | coff-h8300.lo \ | |
45 | coff-h8500.lo \ | |
46 | coff-i386.lo \ | |
47 | @@ -637,6 +639,8 @@ | |
48 | coff-apollo.c \ | |
49 | coff-arm.c \ | |
50 | coff-aux.c \ | |
51 | + coff-avr.c \ | |
52 | + coff-ext-avr.c \ | |
53 | coff-h8300.c \ | |
54 | coff-h8500.c \ | |
55 | coff-i386.c \ | |
56 | @@ -1767,6 +1771,12 @@ | |
57 | coff-m68k.c $(INCDIR)/hashtab.h $(INCDIR)/coff/m68k.h \ | |
58 | $(INCDIR)/coff/internal.h libcoff.h $(INCDIR)/bfdlink.h \ | |
59 | coffcode.h coffswap.h | |
60 | +coff-avr.lo: coff-avr.c $(INCDIR)/filenames.h $(INCDIR)/coff/avr.h \ | |
61 | + $(INCDIR)/coff/external.h $(INCDIR)/coff/internal.h \ | |
62 | + libcoff.h $(INCDIR)/bfdlink.h coffcode.h coffswap.h | |
63 | +coff-ext-avr.lo: coff-ext-avr.c $(INCDIR)/filenames.h $(INCDIR)/coff/avr.h \ | |
64 | + $(INCDIR)/coff/external.h $(INCDIR)/coff/internal.h \ | |
65 | + libcoff.h $(INCDIR)/bfdlink.h coffcode.h coffswap.h | |
66 | coff-h8300.lo: coff-h8300.c $(INCDIR)/filenames.h $(INCDIR)/hashtab.h \ | |
67 | $(INCDIR)/bfdlink.h genlink.h $(INCDIR)/coff/h8300.h \ | |
68 | $(INCDIR)/coff/external.h $(INCDIR)/coff/internal.h \ | |
69 | diff -uNdr binutils-2.17.50.0.18-old/bfd/coff-avr.c binutils-2.17.50.0.18/bfd/coff-avr.c | |
70 | --- binutils-2.17.50.0.18-old/bfd/coff-avr.c 1970-01-01 01:00:00.000000000 +0100 | |
71 | +++ binutils-2.17.50.0.18/bfd/coff-avr.c 2007-10-20 16:45:33.000000000 +0200 | |
72 | @@ -0,0 +1,609 @@ | |
73 | +/* BFD back-end for Atmel AVR COFF files. | |
74 | + Copyright 1990, 1991, 1992, 1993, 1994, 1995, 1999, 2000, 2001, 2003 | |
75 | + Free Software Foundation, Inc. | |
76 | + Created mostly by substituting "avr" for "i860" in coff-i860.c | |
4cd5ba0f | 77 | + |
f33182aa | 78 | +This file is part of BFD, the Binary File Descriptor library. |
4cd5ba0f | 79 | + |
f33182aa | 80 | +This program is free software; you can redistribute it and/or modify |
81 | +it under the terms of the GNU General Public License as published by | |
82 | +the Free Software Foundation; either version 2 of the License, or | |
83 | +(at your option) any later version. | |
4cd5ba0f | 84 | + |
f33182aa | 85 | +This program is distributed in the hope that it will be useful, |
86 | +but WITHOUT ANY WARRANTY; without even the implied warranty of | |
87 | +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
88 | +GNU General Public License for more details. | |
4cd5ba0f | 89 | + |
f33182aa | 90 | +You should have received a copy of the GNU General Public License |
91 | +along with this program; if not, write to the Free Software | |
92 | +Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ | |
4cd5ba0f | 93 | + |
f33182aa | 94 | +#include "bfd.h" |
95 | +#include "sysdep.h" | |
96 | +#include "libbfd.h" | |
4cd5ba0f | 97 | + |
f33182aa | 98 | +#include "coff/avr.h" |
4cd5ba0f | 99 | + |
f33182aa | 100 | +#include "coff/internal.h" |
4cd5ba0f | 101 | + |
f33182aa | 102 | +#include "libcoff.h" |
4cd5ba0f | 103 | + |
f33182aa | 104 | +static bfd_reloc_status_type coff_avr_reloc |
105 | + PARAMS ((bfd *, arelent *, asymbol *, PTR, asection *, bfd *, char **)); | |
106 | +static reloc_howto_type *coff_avr_rtype_to_howto | |
107 | + PARAMS ((bfd *, asection *, struct internal_reloc *, | |
108 | + struct coff_link_hash_entry *, struct internal_syment *, | |
109 | + bfd_vma *)); | |
110 | +static const bfd_target * coff_avr_object_p PARAMS ((bfd *)); | |
4cd5ba0f | 111 | + |
f33182aa | 112 | +#define COFF_DEFAULT_SECTION_ALIGNMENT_POWER (2) |
113 | +/* The page size is a guess based on ELF. */ | |
4cd5ba0f | 114 | + |
f33182aa | 115 | +#define COFF_PAGE_SIZE 0x1000 |
4cd5ba0f | 116 | + |
f33182aa | 117 | +/* For some reason when using avr COFF the value stored in the .text |
118 | + section for a reference to a common symbol is the value itself plus | |
119 | + any desired offset. Ian Taylor, Cygnus Support. */ | |
4cd5ba0f | 120 | + |
f33182aa | 121 | +/* If we are producing relocateable output, we need to do some |
122 | + adjustments to the object file that are not done by the | |
123 | + bfd_perform_relocation function. This function is called by every | |
124 | + reloc type to make any required adjustments. */ | |
4cd5ba0f | 125 | + |
f33182aa | 126 | +static bfd_reloc_status_type |
127 | +coff_avr_reloc (abfd, reloc_entry, symbol, data, input_section, output_bfd, | |
128 | + error_message) | |
129 | + bfd *abfd; | |
130 | + arelent *reloc_entry; | |
131 | + asymbol *symbol; | |
132 | + PTR data; | |
133 | + asection *input_section ATTRIBUTE_UNUSED; | |
134 | + bfd *output_bfd; | |
135 | + char **error_message ATTRIBUTE_UNUSED; | |
136 | +{ | |
137 | + symvalue diff; | |
4cd5ba0f | 138 | + |
f33182aa | 139 | + if (output_bfd == (bfd *) NULL) |
140 | + return bfd_reloc_continue; | |
4cd5ba0f | 141 | + |
f33182aa | 142 | + if (bfd_is_com_section (symbol->section)) |
143 | + { | |
144 | + /* We are relocating a common symbol. The current value in the | |
145 | + object file is ORIG + OFFSET, where ORIG is the value of the | |
146 | + common symbol as seen by the object file when it was compiled | |
147 | + (this may be zero if the symbol was undefined) and OFFSET is | |
148 | + the offset into the common symbol (normally zero, but may be | |
149 | + non-zero when referring to a field in a common structure). | |
150 | + ORIG is the negative of reloc_entry->addend, which is set by | |
151 | + the CALC_ADDEND macro below. We want to replace the value in | |
152 | + the object file with NEW + OFFSET, where NEW is the value of | |
153 | + the common symbol which we are going to put in the final | |
154 | + object file. NEW is symbol->value. */ | |
155 | + diff = symbol->value + reloc_entry->addend; | |
156 | + } | |
157 | + else | |
158 | + { | |
159 | + /* For some reason bfd_perform_relocation always effectively | |
160 | + ignores the addend for a COFF target when producing | |
161 | + relocateable output. This seems to be always wrong for 860 | |
162 | + COFF, so we handle the addend here instead. */ | |
163 | + diff = reloc_entry->addend; | |
164 | + } | |
165 | + | |
166 | +#define DOIT(x) \ | |
167 | + x = ((x & ~howto->dst_mask) | (((x & howto->src_mask) + diff) & howto->dst_mask)) | |
168 | + | |
169 | + if (diff != 0) | |
170 | + { | |
171 | + reloc_howto_type *howto = reloc_entry->howto; | |
172 | + unsigned char *addr = (unsigned char *) data + reloc_entry->address; | |
173 | + | |
174 | + switch (howto->size) | |
4cd5ba0f | 175 | + { |
f33182aa | 176 | + case 0: |
177 | + { | |
178 | + char x = bfd_get_8 (abfd, addr); | |
179 | + DOIT (x); | |
180 | + bfd_put_8 (abfd, x, addr); | |
181 | + } | |
182 | + break; | |
4cd5ba0f | 183 | + |
f33182aa | 184 | + case 1: |
185 | + { | |
186 | + short x = bfd_get_16 (abfd, addr); | |
187 | + DOIT (x); | |
188 | + bfd_put_16 (abfd, (bfd_vma) x, addr); | |
189 | + } | |
190 | + break; | |
4cd5ba0f | 191 | + |
f33182aa | 192 | + case 2: |
193 | + { | |
194 | + long x = bfd_get_32 (abfd, addr); | |
195 | + DOIT (x); | |
196 | + bfd_put_32 (abfd, (bfd_vma) x, addr); | |
197 | + } | |
198 | + break; | |
4cd5ba0f | 199 | + |
f33182aa | 200 | + default: |
201 | + abort (); | |
4cd5ba0f | 202 | + } |
f33182aa | 203 | + } |
4cd5ba0f | 204 | + |
f33182aa | 205 | + /* Now let bfd_perform_relocation finish everything up. */ |
206 | + return bfd_reloc_continue; | |
207 | +} | |
486e8626 | 208 | + |
f33182aa | 209 | +#ifndef PCRELOFFSET |
210 | +#define PCRELOFFSET FALSE | |
211 | +#endif | |
212 | + | |
213 | +static reloc_howto_type howto_table[] = | |
4cd5ba0f | 214 | +{ |
f33182aa | 215 | + EMPTY_HOWTO (0), |
216 | + EMPTY_HOWTO (1), | |
217 | + EMPTY_HOWTO (2), | |
218 | + EMPTY_HOWTO (3), | |
219 | + EMPTY_HOWTO (4), | |
220 | + EMPTY_HOWTO (5), | |
221 | + HOWTO (R_DIR32, /* type */ | |
222 | + 0, /* rightshift */ | |
223 | + 2, /* size (0 = byte, 1 = short, 2 = long) */ | |
224 | + 32, /* bitsize */ | |
225 | + FALSE, /* pc_relative */ | |
226 | + 0, /* bitpos */ | |
227 | + complain_overflow_bitfield, /* complain_on_overflow */ | |
228 | + coff_avr_reloc, /* special_function */ | |
229 | + "dir32", /* name */ | |
230 | + TRUE, /* partial_inplace */ | |
231 | + 0xffffffff, /* src_mask */ | |
232 | + 0xffffffff, /* dst_mask */ | |
233 | + TRUE), /* pcrel_offset */ | |
234 | + /* {7}, */ | |
235 | + HOWTO (R_IMAGEBASE, /* type */ | |
236 | + 0, /* rightshift */ | |
237 | + 2, /* size (0 = byte, 1 = short, 2 = long) */ | |
238 | + 32, /* bitsize */ | |
239 | + FALSE, /* pc_relative */ | |
240 | + 0, /* bitpos */ | |
241 | + complain_overflow_bitfield, /* complain_on_overflow */ | |
242 | + coff_avr_reloc, /* special_function */ | |
243 | + "rva32", /* name */ | |
244 | + TRUE, /* partial_inplace */ | |
245 | + 0xffffffff, /* src_mask */ | |
246 | + 0xffffffff, /* dst_mask */ | |
247 | + FALSE), /* pcrel_offset */ | |
248 | + EMPTY_HOWTO (010), | |
249 | + EMPTY_HOWTO (011), | |
250 | + EMPTY_HOWTO (012), | |
251 | + EMPTY_HOWTO (013), | |
252 | + EMPTY_HOWTO (014), | |
253 | + EMPTY_HOWTO (015), | |
254 | + EMPTY_HOWTO (016), | |
255 | + HOWTO (R_RELBYTE, /* type */ | |
256 | + 0, /* rightshift */ | |
257 | + 0, /* size (0 = byte, 1 = short, 2 = long) */ | |
258 | + 8, /* bitsize */ | |
259 | + FALSE, /* pc_relative */ | |
260 | + 0, /* bitpos */ | |
261 | + complain_overflow_bitfield, /* complain_on_overflow */ | |
262 | + coff_avr_reloc, /* special_function */ | |
263 | + "8", /* name */ | |
264 | + TRUE, /* partial_inplace */ | |
265 | + 0x000000ff, /* src_mask */ | |
266 | + 0x000000ff, /* dst_mask */ | |
267 | + PCRELOFFSET), /* pcrel_offset */ | |
268 | + HOWTO (R_RELWORD, /* type */ | |
269 | + 0, /* rightshift */ | |
270 | + 1, /* size (0 = byte, 1 = short, 2 = long) */ | |
271 | + 16, /* bitsize */ | |
272 | + FALSE, /* pc_relative */ | |
273 | + 0, /* bitpos */ | |
274 | + complain_overflow_bitfield, /* complain_on_overflow */ | |
275 | + coff_avr_reloc, /* special_function */ | |
276 | + "16", /* name */ | |
277 | + TRUE, /* partial_inplace */ | |
278 | + 0x0000ffff, /* src_mask */ | |
279 | + 0x0000ffff, /* dst_mask */ | |
280 | + PCRELOFFSET), /* pcrel_offset */ | |
281 | + HOWTO (R_RELLONG, /* type */ | |
282 | + 0, /* rightshift */ | |
283 | + 2, /* size (0 = byte, 1 = short, 2 = long) */ | |
284 | + 32, /* bitsize */ | |
285 | + FALSE, /* pc_relative */ | |
286 | + 0, /* bitpos */ | |
287 | + complain_overflow_bitfield, /* complain_on_overflow */ | |
288 | + coff_avr_reloc, /* special_function */ | |
289 | + "32", /* name */ | |
290 | + TRUE, /* partial_inplace */ | |
291 | + 0xffffffff, /* src_mask */ | |
292 | + 0xffffffff, /* dst_mask */ | |
293 | + PCRELOFFSET), /* pcrel_offset */ | |
294 | + HOWTO (R_PCRBYTE, /* type */ | |
295 | + 0, /* rightshift */ | |
296 | + 0, /* size (0 = byte, 1 = short, 2 = long) */ | |
297 | + 8, /* bitsize */ | |
298 | + TRUE, /* pc_relative */ | |
299 | + 0, /* bitpos */ | |
300 | + complain_overflow_signed, /* complain_on_overflow */ | |
301 | + coff_avr_reloc, /* special_function */ | |
302 | + "DISP8", /* name */ | |
303 | + TRUE, /* partial_inplace */ | |
304 | + 0x000000ff, /* src_mask */ | |
305 | + 0x000000ff, /* dst_mask */ | |
306 | + PCRELOFFSET), /* pcrel_offset */ | |
307 | + HOWTO (R_PCRWORD, /* type */ | |
308 | + 0, /* rightshift */ | |
309 | + 1, /* size (0 = byte, 1 = short, 2 = long) */ | |
310 | + 16, /* bitsize */ | |
311 | + TRUE, /* pc_relative */ | |
312 | + 0, /* bitpos */ | |
313 | + complain_overflow_signed, /* complain_on_overflow */ | |
314 | + coff_avr_reloc, /* special_function */ | |
315 | + "DISP16", /* name */ | |
316 | + TRUE, /* partial_inplace */ | |
317 | + 0x0000ffff, /* src_mask */ | |
318 | + 0x0000ffff, /* dst_mask */ | |
319 | + PCRELOFFSET), /* pcrel_offset */ | |
320 | + HOWTO (R_PCRLONG, /* type */ | |
321 | + 0, /* rightshift */ | |
322 | + 2, /* size (0 = byte, 1 = short, 2 = long) */ | |
323 | + 32, /* bitsize */ | |
324 | + TRUE, /* pc_relative */ | |
325 | + 0, /* bitpos */ | |
326 | + complain_overflow_signed, /* complain_on_overflow */ | |
327 | + coff_avr_reloc, /* special_function */ | |
328 | + "DISP32", /* name */ | |
329 | + TRUE, /* partial_inplace */ | |
330 | + 0xffffffff, /* src_mask */ | |
331 | + 0xffffffff, /* dst_mask */ | |
332 | + PCRELOFFSET) /* pcrel_offset */ | |
333 | +}; | |
4cd5ba0f | 334 | + |
f33182aa | 335 | +/* Turn a howto into a reloc nunmber */ |
4cd5ba0f | 336 | + |
f33182aa | 337 | +#define SELECT_RELOC(x,howto) { x.r_type = howto->type; } |
338 | +#define BADMAG(x) AVRBADMAG(x) | |
339 | +#define AVR 1 /* Customize coffcode.h */ | |
4cd5ba0f | 340 | + |
f33182aa | 341 | +#define RTYPE2HOWTO(cache_ptr, dst) \ |
342 | + (cache_ptr)->howto = howto_table + (dst)->r_type; | |
4cd5ba0f | 343 | + |
f33182aa | 344 | +/* For AVR COFF a STYP_NOLOAD | STYP_BSS section is part of a shared |
345 | + library. On some other COFF targets STYP_BSS is normally | |
346 | + STYP_NOLOAD. */ | |
347 | +#define BSS_NOLOAD_IS_SHARED_LIBRARY | |
4cd5ba0f | 348 | + |
f33182aa | 349 | +/* Compute the addend of a reloc. If the reloc is to a common symbol, |
350 | + the object file contains the value of the common symbol. By the | |
351 | + time this is called, the linker may be using a different symbol | |
352 | + from a different object file with a different value. Therefore, we | |
353 | + hack wildly to locate the original symbol from this file so that we | |
354 | + can make the correct adjustment. This macro sets coffsym to the | |
355 | + symbol from the original file, and uses it to set the addend value | |
356 | + correctly. If this is not a common symbol, the usual addend | |
357 | + calculation is done, except that an additional tweak is needed for | |
358 | + PC relative relocs. | |
359 | + FIXME: This macro refers to symbols and asect; these are from the | |
360 | + calling function, not the macro arguments. */ | |
4cd5ba0f | 361 | + |
f33182aa | 362 | +#define CALC_ADDEND(abfd, ptr, reloc, cache_ptr) \ |
363 | + { \ | |
364 | + coff_symbol_type *coffsym = (coff_symbol_type *) NULL; \ | |
365 | + if (ptr && bfd_asymbol_bfd (ptr) != abfd) \ | |
366 | + coffsym = (obj_symbols (abfd) \ | |
367 | + + (cache_ptr->sym_ptr_ptr - symbols)); \ | |
368 | + else if (ptr) \ | |
369 | + coffsym = coff_symbol_from (abfd, ptr); \ | |
370 | + if (coffsym != (coff_symbol_type *) NULL \ | |
371 | + && coffsym->native->u.syment.n_scnum == 0) \ | |
372 | + cache_ptr->addend = - coffsym->native->u.syment.n_value; \ | |
373 | + else if (ptr && bfd_asymbol_bfd (ptr) == abfd \ | |
374 | + && ptr->section != (asection *) NULL) \ | |
375 | + cache_ptr->addend = - (ptr->section->vma + ptr->value); \ | |
376 | + else \ | |
377 | + cache_ptr->addend = 0; \ | |
378 | + if (ptr && howto_table[reloc.r_type].pc_relative) \ | |
379 | + cache_ptr->addend += asect->vma; \ | |
380 | + } | |
4cd5ba0f | 381 | + |
f33182aa | 382 | +/* We use the special COFF backend linker. */ |
383 | +#define coff_relocate_section _bfd_coff_generic_relocate_section | |
4cd5ba0f | 384 | + |
f33182aa | 385 | +static reloc_howto_type * |
386 | +coff_avr_rtype_to_howto (abfd, sec, rel, h, sym, addendp) | |
387 | + bfd *abfd ATTRIBUTE_UNUSED; | |
388 | + asection *sec; | |
389 | + struct internal_reloc *rel; | |
390 | + struct coff_link_hash_entry *h; | |
391 | + struct internal_syment *sym; | |
392 | + bfd_vma *addendp; | |
393 | +{ | |
4cd5ba0f | 394 | + |
f33182aa | 395 | + reloc_howto_type *howto; |
4cd5ba0f | 396 | + |
f33182aa | 397 | + howto = howto_table + rel->r_type; |
4cd5ba0f | 398 | + |
f33182aa | 399 | + if (howto->pc_relative) |
400 | + *addendp += sec->vma; | |
4cd5ba0f | 401 | + |
f33182aa | 402 | + if (sym != NULL && sym->n_scnum == 0 && sym->n_value != 0) |
403 | + { | |
404 | + /* This is a common symbol. The section contents include the | |
405 | + size (sym->n_value) as an addend. The relocate_section | |
406 | + function will be adding in the final value of the symbol. We | |
407 | + need to subtract out the current size in order to get the | |
408 | + correct result. */ | |
4cd5ba0f | 409 | + |
f33182aa | 410 | + BFD_ASSERT (h != NULL); |
4cd5ba0f | 411 | + |
f33182aa | 412 | + /* I think we *do* want to bypass this. If we don't, I have seen some data |
413 | + parameters get the wrong relcation address. If I link two versions | |
414 | + with and without this section bypassed and then do a binary comparison, | |
415 | + the addresses which are different can be looked up in the map. The | |
416 | + case in which this section has been bypassed has addresses which correspond | |
417 | + to values I can find in the map. */ | |
418 | + *addendp -= sym->n_value; | |
419 | + } | |
4cd5ba0f | 420 | + |
f33182aa | 421 | + /* If the output symbol is common (in which case this must be a |
422 | + relocateable link), we need to add in the final size of the | |
423 | + common symbol. */ | |
424 | + if (h != NULL && h->root.type == bfd_link_hash_common) | |
425 | + *addendp += h->root.u.c.size; | |
4cd5ba0f | 426 | + |
f33182aa | 427 | + return howto; |
428 | +} | |
4cd5ba0f | 429 | + |
f33182aa | 430 | +#define coff_rtype_to_howto coff_avr_rtype_to_howto |
4cd5ba0f | 431 | + |
f33182aa | 432 | +#include "coffcode.h" |
433 | + | |
434 | +static const bfd_target * | |
435 | +coff_avr_object_p(a) | |
436 | + bfd *a; | |
4cd5ba0f | 437 | +{ |
f33182aa | 438 | + return coff_object_p (a); |
439 | +} | |
4cd5ba0f | 440 | + |
f33182aa | 441 | +/* Handle all the abominations of AVR COFF: |
4cd5ba0f | 442 | + |
f33182aa | 443 | + Generic COFF always uses the D1 slot to indicate the "most |
444 | + important" derived type, and the D2...Dn slots for decreasing | |
445 | + importance. E. g., a function symbol will always have its DT_FCN | |
446 | + element in D1, an array its DT_ARY (its first DT_ARY in a | |
447 | + multi-dimensional array). In contrast, AVR COFF expects this most | |
448 | + important derived type specifier in the upmost Dn slot that is | |
449 | + allocated at all (i. e. that is != 0). | |
4cd5ba0f | 450 | + |
f33182aa | 451 | + Generic COFF says that "Any symbol that satisfies more than one |
452 | + condition [... for AUX entries] should have a union format in its | |
453 | + auxiliary entry." AVR COFF uses sepearate AUX entries for multiple | |
454 | + derived types, and in some cases (like the ISFCN one), even puts | |
455 | + the most important one into the last allocated AUX entry. We | |
456 | + join/split them here at the border as well. Note that when | |
457 | + generating AUX entries (where we need to split them), the n_numaux | |
458 | + field must already have been set up properly (e. g. in | |
459 | + binutils/wrcoff.c) since the entry renumbering and pointerization | |
460 | + would not work otherwise. Thus, we only split the information into | |
461 | + multiple records if n_numaux > 1. For similar reasons, we keep | |
462 | + n_numaux > 1 on input to keep the appropriate AUX entries | |
463 | + allocated, so a symbol can be reconstructed if it is being passed | |
464 | + through one of the GNU tools. | |
4cd5ba0f | 465 | + |
f33182aa | 466 | + Note that this adjustment is called after the symbol itself has |
467 | + been swapped in, but before the AUX entries are swapped in. This | |
468 | + is the only hook available that could swap (or merge) AUX entries | |
469 | + at all, so we have to operate on the external AUX entries still. */ | |
4cd5ba0f | 470 | + |
f33182aa | 471 | +void |
472 | +avr_coff_adjust_sym_in_post (abfd, ext, in) | |
473 | + bfd *abfd; | |
474 | + PTR ext; | |
475 | + PTR in; | |
476 | +{ | |
477 | + struct internal_syment *dst = (struct internal_syment *)in; | |
478 | + unsigned short dt, bt, ndt; | |
479 | + dt = dst->n_type & ~N_BTMASK; | |
480 | + bt = BTYPE (dst->n_type); | |
481 | + | |
482 | + /* Some AVR COFF producers seem to violate the COFF specs, and | |
483 | + produce symbols for tag names that have the C_FOO filled in | |
484 | + properly, but T_NULL as the base type value. Patch up here, | |
485 | + since some of our generic COFF tools (in particular | |
486 | + binutils/rdcoff.c) rely on the correct data. */ | |
487 | + if (bt == T_NULL) | |
488 | + switch (dst->n_sclass) | |
4cd5ba0f | 489 | + { |
f33182aa | 490 | + case C_STRTAG: |
491 | + bt = T_STRUCT; | |
492 | + break; | |
493 | + | |
494 | + case C_UNTAG: | |
495 | + bt = T_UNION; | |
496 | + break; | |
497 | + | |
498 | + case C_ENTAG: | |
499 | + bt = T_ENUM; | |
500 | + break; | |
4cd5ba0f | 501 | + } |
4cd5ba0f | 502 | + |
f33182aa | 503 | + /* Swap the derived type slots. */ |
504 | + if (dt != 0) | |
4cd5ba0f | 505 | + { |
f33182aa | 506 | + ndt = 0; |
507 | + while (dt != 0) | |
508 | + { | |
509 | + ndt = (ndt << N_TSHIFT) | (dt & (N_TMASK >> N_BTSHFT)); | |
510 | + dt >>= N_TSHIFT; | |
511 | + } | |
512 | + dst->n_type = (ndt << N_BTSHFT) | bt; | |
4cd5ba0f | 513 | + } |
f33182aa | 514 | + else |
515 | + dst->n_type = bt; | |
4cd5ba0f | 516 | + |
f33182aa | 517 | + /* If the derived type is function, and there is more than one AUX |
518 | + entry, swap the first and the last AUX entry, so the most | |
519 | + interesting one will become the first. | |
4cd5ba0f | 520 | + |
f33182aa | 521 | + If the fundamental type is a tagged type (struct/union/enum), try |
522 | + to find the AUX entry describing the tagged type (the one that | |
523 | + has x_sym.x_tagndx filled in), and merge the tag index into the | |
524 | + first AUX entry. Depending on the actual input file, there might | |
525 | + be further DT_PTR entries which we just ignore, since we could | |
526 | + not handle that information anyway. */ | |
527 | + if (dst->n_numaux > 1 && dst->n_sclass != C_FILE) | |
4cd5ba0f | 528 | + { |
f33182aa | 529 | + AUXENT caux, *auxp1, *auxp2; |
530 | + size_t symesz; | |
531 | + unsigned int i; | |
4cd5ba0f | 532 | + |
f33182aa | 533 | + symesz = bfd_coff_symesz (abfd); |
534 | + i = dst->n_numaux; | |
4cd5ba0f | 535 | + |
f33182aa | 536 | + auxp1 = (AUXENT *)((char *)ext + symesz); |
537 | + auxp2 = (AUXENT *)((char *)ext + i * symesz); | |
4cd5ba0f | 538 | + |
f33182aa | 539 | + if (ISFCN (dst->n_type) |
540 | + || (ISPTR(dst->n_type) | |
541 | + && (bt == T_STRUCT || bt == T_UNION || bt == T_ENUM))) | |
542 | + { | |
543 | + caux = *auxp2; | |
544 | + *auxp2 = *auxp1; | |
545 | + *auxp1 = caux; | |
546 | + } | |
547 | + else | |
548 | + caux = *auxp1; | |
4cd5ba0f | 549 | + |
f33182aa | 550 | + if ((ISFCN (dst->n_type) || ISARY (dst->n_type)) |
551 | + && (bt == T_STRUCT || bt == T_UNION || bt == T_ENUM)) | |
552 | + { | |
553 | + while (i > 1) | |
554 | + { | |
555 | + auxp2 = (AUXENT *)((char *)ext + i * symesz); | |
4cd5ba0f | 556 | + |
f33182aa | 557 | + if (auxp2->x_sym.x_tagndx[0] != 0 || auxp2->x_sym.x_tagndx[1] != 0 |
558 | + || auxp2->x_sym.x_tagndx[2] != 0 || auxp2->x_sym.x_tagndx[3] != 0) | |
559 | + { | |
560 | + memcpy (caux.x_sym.x_tagndx, auxp2->x_sym.x_tagndx, | |
561 | + 4 * sizeof (char)); | |
562 | + break; | |
563 | + } | |
564 | + i--; | |
565 | + } | |
566 | + if (i > 1) | |
567 | + *auxp1 = caux; | |
568 | + } | |
569 | + } | |
570 | +} | |
4cd5ba0f | 571 | + |
f33182aa | 572 | +/* When exporting an AVR COFF file, just undo all that has been done |
573 | + above. Again, we are called after the symbol itself has been | |
574 | + swapped out, but before the AUX entries are being written. | |
575 | + Unfortunately, we are only given a pointer to the symbol itself, so | |
576 | + we have to derive the pointer to the respective aux entries from | |
577 | + that address, which is a bit clumsy. */ | |
578 | +void | |
579 | +avr_coff_adjust_sym_out_post (abfd, in, ext) | |
580 | + bfd *abfd; | |
581 | + PTR in; | |
582 | + PTR ext; | |
4cd5ba0f | 583 | +{ |
f33182aa | 584 | + struct internal_syment *src = (struct internal_syment *)(in); |
585 | + struct external_syment *dst = (struct external_syment *)(ext); | |
586 | + unsigned short dt, bt, ndt; | |
4cd5ba0f | 587 | + |
f33182aa | 588 | + dt = src->n_type & ~N_BTMASK; |
589 | + bt = BTYPE (src->n_type); | |
4cd5ba0f | 590 | + |
f33182aa | 591 | + if (dt != 0) |
592 | + { | |
593 | + ndt = 0; | |
594 | + while (dt != 0) | |
595 | + { | |
596 | + ndt = (ndt << N_TSHIFT) | (dt & (N_TMASK >> N_BTSHFT)); | |
597 | + dt >>= N_TSHIFT; | |
598 | + } | |
599 | + H_PUT_16 (abfd, (ndt << N_BTSHFT) | bt, dst->e_type); | |
600 | + } | |
4cd5ba0f | 601 | + |
f33182aa | 602 | + if (src->n_numaux > 1 && src->n_sclass != C_FILE) |
603 | + { | |
604 | + combined_entry_type *srce, *dste; | |
605 | + char *hackp; | |
606 | + unsigned int i; | |
4cd5ba0f | 607 | + |
f33182aa | 608 | + /* Recover the original combinend_entry_type *. */ |
609 | + hackp = (char *)in; | |
610 | + hackp -= offsetof(combined_entry_type, u.syment); | |
611 | + srce = (combined_entry_type *)hackp; | |
612 | + srce++; | |
613 | + | |
614 | + /* We simply duplicate the first AUX entry as many times as | |
615 | + needed. Since COFF itself normally uses just a single AUX | |
616 | + entry for all the information, this will work -- each COFF | |
617 | + consumer will then just pick the fields it is particularly | |
618 | + interested in. This would not work for the AVR COFF specific | |
619 | + DT_PTR AUX entries, but we don't support them anyway. */ | |
620 | + for (i = 1; i < src->n_numaux; i++) | |
621 | + { | |
622 | + dste = srce + i; | |
623 | + *dste = *srce; | |
624 | + } | |
625 | + } | |
626 | +} | |
627 | + | |
628 | +const bfd_target | |
629 | +#ifdef TARGET_SYM | |
630 | + TARGET_SYM = | |
631 | +#else | |
632 | + avrcoff_vec = | |
633 | +#endif | |
4cd5ba0f | 634 | +{ |
f33182aa | 635 | +#ifdef TARGET_NAME |
636 | + TARGET_NAME, | |
637 | +#else | |
638 | + "coff-avr", /* name */ | |
639 | +#endif | |
640 | + bfd_target_coff_flavour, | |
641 | + BFD_ENDIAN_LITTLE, /* data byte order is little */ | |
642 | + BFD_ENDIAN_LITTLE, /* header byte order is little */ | |
4cd5ba0f | 643 | + |
f33182aa | 644 | + (HAS_RELOC | EXEC_P | /* object flags */ |
645 | + HAS_LINENO | HAS_DEBUG | | |
646 | + HAS_SYMS | HAS_LOCALS | WP_TEXT), | |
4cd5ba0f | 647 | + |
f33182aa | 648 | + (SEC_HAS_CONTENTS | SEC_ALLOC | SEC_LOAD | SEC_RELOC), /* section flags */ |
649 | + 0, /* leading char */ | |
650 | + '/', /* ar_pad_char */ | |
651 | + 15, /* ar_max_namelen */ | |
4cd5ba0f | 652 | + |
f33182aa | 653 | + bfd_getl64, bfd_getl_signed_64, bfd_putl64, |
654 | + bfd_getl32, bfd_getl_signed_32, bfd_putl32, | |
655 | + bfd_getl16, bfd_getl_signed_16, bfd_putl16, /* data */ | |
656 | + bfd_getl64, bfd_getl_signed_64, bfd_putl64, | |
657 | + bfd_getl32, bfd_getl_signed_32, bfd_putl32, | |
658 | + bfd_getl16, bfd_getl_signed_16, bfd_putl16, /* hdrs */ | |
4cd5ba0f | 659 | + |
f33182aa | 660 | +/* Note that we allow an object file to be treated as a core file as well. */ |
661 | + {_bfd_dummy_target, coff_avr_object_p, /* bfd_check_format */ | |
662 | + bfd_generic_archive_p, coff_avr_object_p}, | |
663 | + {bfd_false, coff_mkobject, _bfd_generic_mkarchive, /* bfd_set_format */ | |
664 | + bfd_false}, | |
665 | + {bfd_false, coff_write_object_contents, /* bfd_write_contents */ | |
666 | + _bfd_write_archive_contents, bfd_false}, | |
4cd5ba0f | 667 | + |
f33182aa | 668 | + BFD_JUMP_TABLE_GENERIC (coff), |
669 | + BFD_JUMP_TABLE_COPY (coff), | |
670 | + BFD_JUMP_TABLE_CORE (_bfd_nocore), | |
671 | + BFD_JUMP_TABLE_ARCHIVE (_bfd_archive_coff), | |
672 | + BFD_JUMP_TABLE_SYMBOLS (coff), | |
673 | + BFD_JUMP_TABLE_RELOCS (coff), | |
674 | + BFD_JUMP_TABLE_WRITE (coff), | |
675 | + BFD_JUMP_TABLE_LINK (coff), | |
676 | + BFD_JUMP_TABLE_DYNAMIC (_bfd_nodynamic), | |
4cd5ba0f | 677 | + |
f33182aa | 678 | + NULL, |
4cd5ba0f | 679 | + |
f33182aa | 680 | + COFF_SWAP_TABLE |
681 | +}; | |
682 | diff -uNdr binutils-2.17.50.0.18-old/bfd/coff-ext-avr.c binutils-2.17.50.0.18/bfd/coff-ext-avr.c | |
683 | --- binutils-2.17.50.0.18-old/bfd/coff-ext-avr.c 1970-01-01 01:00:00.000000000 +0100 | |
684 | +++ binutils-2.17.50.0.18/bfd/coff-ext-avr.c 2007-10-20 16:45:33.000000000 +0200 | |
685 | @@ -0,0 +1,424 @@ | |
686 | +/* BFD back-end for Atmel AVR "extended" COFF files. | |
687 | + Copyright 1990, 1991, 1992, 1993, 1994, 1995, 1999, 2000, 2001, 2003 | |
688 | + Free Software Foundation, Inc. | |
689 | + This is mostly the same as avr-coff, except of the presence of the | |
690 | + COFF optional header. | |
4cd5ba0f | 691 | + |
f33182aa | 692 | +This file is part of BFD, the Binary File Descriptor library. |
4cd5ba0f | 693 | + |
f33182aa | 694 | +This program is free software; you can redistribute it and/or modify |
695 | +it under the terms of the GNU General Public License as published by | |
696 | +the Free Software Foundation; either version 2 of the License, or | |
697 | +(at your option) any later version. | |
4cd5ba0f | 698 | + |
f33182aa | 699 | +This program is distributed in the hope that it will be useful, |
700 | +but WITHOUT ANY WARRANTY; without even the implied warranty of | |
701 | +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
702 | +GNU General Public License for more details. | |
4cd5ba0f | 703 | + |
f33182aa | 704 | +You should have received a copy of the GNU General Public License |
705 | +along with this program; if not, write to the Free Software | |
706 | +Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ | |
4cd5ba0f | 707 | + |
f33182aa | 708 | +#include "bfd.h" |
709 | +#include "sysdep.h" | |
710 | +#include "libbfd.h" | |
4cd5ba0f | 711 | + |
f33182aa | 712 | +#define AVR_EXT_COFF 1 |
713 | +#include "coff/avr.h" | |
4cd5ba0f | 714 | + |
f33182aa | 715 | +#include "coff/internal.h" |
4cd5ba0f | 716 | + |
f33182aa | 717 | +#include "libcoff.h" |
4cd5ba0f | 718 | + |
f33182aa | 719 | +static bfd_reloc_status_type coff_ext_avr_reloc |
720 | + PARAMS ((bfd *, arelent *, asymbol *, PTR, asection *, bfd *, char **)); | |
721 | +static reloc_howto_type *coff_ext_avr_rtype_to_howto | |
722 | + PARAMS ((bfd *, asection *, struct internal_reloc *, | |
723 | + struct coff_link_hash_entry *, struct internal_syment *, | |
724 | + bfd_vma *)); | |
725 | +static const bfd_target * coff_ext_avr_object_p PARAMS ((bfd *)); | |
4cd5ba0f | 726 | + |
f33182aa | 727 | +#define COFF_DEFAULT_SECTION_ALIGNMENT_POWER (2) |
728 | +/* The page size is a guess based on ELF. */ | |
4cd5ba0f | 729 | + |
f33182aa | 730 | +#define COFF_PAGE_SIZE 0x1000 |
4cd5ba0f | 731 | + |
f33182aa | 732 | +/* For some reason when using avr COFF the value stored in the .text |
733 | + section for a reference to a common symbol is the value itself plus | |
734 | + any desired offset. Ian Taylor, Cygnus Support. */ | |
4cd5ba0f | 735 | + |
f33182aa | 736 | +/* If we are producing relocateable output, we need to do some |
737 | + adjustments to the object file that are not done by the | |
738 | + bfd_perform_relocation function. This function is called by every | |
739 | + reloc type to make any required adjustments. */ | |
4cd5ba0f | 740 | + |
f33182aa | 741 | +static bfd_reloc_status_type |
742 | +coff_ext_avr_reloc (abfd, reloc_entry, symbol, data, input_section, output_bfd, | |
743 | + error_message) | |
744 | + bfd *abfd; | |
745 | + arelent *reloc_entry; | |
746 | + asymbol *symbol; | |
747 | + PTR data; | |
748 | + asection *input_section ATTRIBUTE_UNUSED; | |
749 | + bfd *output_bfd; | |
750 | + char **error_message ATTRIBUTE_UNUSED; | |
4cd5ba0f | 751 | +{ |
f33182aa | 752 | + symvalue diff; |
4cd5ba0f | 753 | + |
f33182aa | 754 | + if (output_bfd == (bfd *) NULL) |
755 | + return bfd_reloc_continue; | |
4cd5ba0f | 756 | + |
f33182aa | 757 | + if (bfd_is_com_section (symbol->section)) |
4cd5ba0f | 758 | + { |
f33182aa | 759 | + /* We are relocating a common symbol. The current value in the |
760 | + object file is ORIG + OFFSET, where ORIG is the value of the | |
761 | + common symbol as seen by the object file when it was compiled | |
762 | + (this may be zero if the symbol was undefined) and OFFSET is | |
763 | + the offset into the common symbol (normally zero, but may be | |
764 | + non-zero when referring to a field in a common structure). | |
765 | + ORIG is the negative of reloc_entry->addend, which is set by | |
766 | + the CALC_ADDEND macro below. We want to replace the value in | |
767 | + the object file with NEW + OFFSET, where NEW is the value of | |
768 | + the common symbol which we are going to put in the final | |
769 | + object file. NEW is symbol->value. */ | |
770 | + diff = symbol->value + reloc_entry->addend; | |
4cd5ba0f | 771 | + } |
f33182aa | 772 | + else |
4cd5ba0f | 773 | + { |
f33182aa | 774 | + /* For some reason bfd_perform_relocation always effectively |
775 | + ignores the addend for a COFF target when producing | |
776 | + relocateable output. This seems to be always wrong for 860 | |
777 | + COFF, so we handle the addend here instead. */ | |
778 | + diff = reloc_entry->addend; | |
779 | + } | |
4cd5ba0f | 780 | + |
f33182aa | 781 | +#define DOIT(x) \ |
782 | + x = ((x & ~howto->dst_mask) | (((x & howto->src_mask) + diff) & howto->dst_mask)) | |
4cd5ba0f | 783 | + |
f33182aa | 784 | + if (diff != 0) |
785 | + { | |
786 | + reloc_howto_type *howto = reloc_entry->howto; | |
787 | + unsigned char *addr = (unsigned char *) data + reloc_entry->address; | |
4cd5ba0f | 788 | + |
f33182aa | 789 | + switch (howto->size) |
790 | + { | |
791 | + case 0: | |
792 | + { | |
793 | + char x = bfd_get_8 (abfd, addr); | |
794 | + DOIT (x); | |
795 | + bfd_put_8 (abfd, x, addr); | |
796 | + } | |
797 | + break; | |
4cd5ba0f | 798 | + |
f33182aa | 799 | + case 1: |
800 | + { | |
801 | + short x = bfd_get_16 (abfd, addr); | |
802 | + DOIT (x); | |
803 | + bfd_put_16 (abfd, (bfd_vma) x, addr); | |
804 | + } | |
805 | + break; | |
4cd5ba0f | 806 | + |
f33182aa | 807 | + case 2: |
808 | + { | |
809 | + long x = bfd_get_32 (abfd, addr); | |
810 | + DOIT (x); | |
811 | + bfd_put_32 (abfd, (bfd_vma) x, addr); | |
812 | + } | |
813 | + break; | |
4cd5ba0f | 814 | + |
f33182aa | 815 | + default: |
816 | + abort (); | |
817 | + } | |
818 | + } | |
4cd5ba0f | 819 | + |
f33182aa | 820 | + /* Now let bfd_perform_relocation finish everything up. */ |
821 | + return bfd_reloc_continue; | |
4cd5ba0f ER |
822 | +} |
823 | + | |
f33182aa | 824 | +#ifndef PCRELOFFSET |
825 | +#define PCRELOFFSET FALSE | |
826 | +#endif | |
4cd5ba0f | 827 | + |
f33182aa | 828 | +static reloc_howto_type howto_table[] = |
4cd5ba0f | 829 | +{ |
f33182aa | 830 | + EMPTY_HOWTO (0), |
831 | + EMPTY_HOWTO (1), | |
832 | + EMPTY_HOWTO (2), | |
833 | + EMPTY_HOWTO (3), | |
834 | + EMPTY_HOWTO (4), | |
835 | + EMPTY_HOWTO (5), | |
836 | + HOWTO (R_DIR32, /* type */ | |
837 | + 0, /* rightshift */ | |
838 | + 2, /* size (0 = byte, 1 = short, 2 = long) */ | |
839 | + 32, /* bitsize */ | |
840 | + FALSE, /* pc_relative */ | |
841 | + 0, /* bitpos */ | |
842 | + complain_overflow_bitfield, /* complain_on_overflow */ | |
843 | + coff_ext_avr_reloc, /* special_function */ | |
844 | + "dir32", /* name */ | |
845 | + TRUE, /* partial_inplace */ | |
846 | + 0xffffffff, /* src_mask */ | |
847 | + 0xffffffff, /* dst_mask */ | |
848 | + TRUE), /* pcrel_offset */ | |
849 | + /* {7}, */ | |
850 | + HOWTO (R_IMAGEBASE, /* type */ | |
851 | + 0, /* rightshift */ | |
852 | + 2, /* size (0 = byte, 1 = short, 2 = long) */ | |
853 | + 32, /* bitsize */ | |
854 | + FALSE, /* pc_relative */ | |
855 | + 0, /* bitpos */ | |
856 | + complain_overflow_bitfield, /* complain_on_overflow */ | |
857 | + coff_ext_avr_reloc, /* special_function */ | |
858 | + "rva32", /* name */ | |
859 | + TRUE, /* partial_inplace */ | |
860 | + 0xffffffff, /* src_mask */ | |
861 | + 0xffffffff, /* dst_mask */ | |
862 | + FALSE), /* pcrel_offset */ | |
863 | + EMPTY_HOWTO (010), | |
864 | + EMPTY_HOWTO (011), | |
865 | + EMPTY_HOWTO (012), | |
866 | + EMPTY_HOWTO (013), | |
867 | + EMPTY_HOWTO (014), | |
868 | + EMPTY_HOWTO (015), | |
869 | + EMPTY_HOWTO (016), | |
870 | + HOWTO (R_RELBYTE, /* type */ | |
871 | + 0, /* rightshift */ | |
872 | + 0, /* size (0 = byte, 1 = short, 2 = long) */ | |
873 | + 8, /* bitsize */ | |
874 | + FALSE, /* pc_relative */ | |
875 | + 0, /* bitpos */ | |
876 | + complain_overflow_bitfield, /* complain_on_overflow */ | |
877 | + coff_ext_avr_reloc, /* special_function */ | |
878 | + "8", /* name */ | |
879 | + TRUE, /* partial_inplace */ | |
880 | + 0x000000ff, /* src_mask */ | |
881 | + 0x000000ff, /* dst_mask */ | |
882 | + PCRELOFFSET), /* pcrel_offset */ | |
883 | + HOWTO (R_RELWORD, /* type */ | |
884 | + 0, /* rightshift */ | |
885 | + 1, /* size (0 = byte, 1 = short, 2 = long) */ | |
886 | + 16, /* bitsize */ | |
887 | + FALSE, /* pc_relative */ | |
888 | + 0, /* bitpos */ | |
889 | + complain_overflow_bitfield, /* complain_on_overflow */ | |
890 | + coff_ext_avr_reloc, /* special_function */ | |
891 | + "16", /* name */ | |
892 | + TRUE, /* partial_inplace */ | |
893 | + 0x0000ffff, /* src_mask */ | |
894 | + 0x0000ffff, /* dst_mask */ | |
895 | + PCRELOFFSET), /* pcrel_offset */ | |
896 | + HOWTO (R_RELLONG, /* type */ | |
897 | + 0, /* rightshift */ | |
898 | + 2, /* size (0 = byte, 1 = short, 2 = long) */ | |
899 | + 32, /* bitsize */ | |
900 | + FALSE, /* pc_relative */ | |
901 | + 0, /* bitpos */ | |
902 | + complain_overflow_bitfield, /* complain_on_overflow */ | |
903 | + coff_ext_avr_reloc, /* special_function */ | |
904 | + "32", /* name */ | |
905 | + TRUE, /* partial_inplace */ | |
906 | + 0xffffffff, /* src_mask */ | |
907 | + 0xffffffff, /* dst_mask */ | |
908 | + PCRELOFFSET), /* pcrel_offset */ | |
909 | + HOWTO (R_PCRBYTE, /* type */ | |
910 | + 0, /* rightshift */ | |
911 | + 0, /* size (0 = byte, 1 = short, 2 = long) */ | |
912 | + 8, /* bitsize */ | |
913 | + TRUE, /* pc_relative */ | |
914 | + 0, /* bitpos */ | |
915 | + complain_overflow_signed, /* complain_on_overflow */ | |
916 | + coff_ext_avr_reloc, /* special_function */ | |
917 | + "DISP8", /* name */ | |
918 | + TRUE, /* partial_inplace */ | |
919 | + 0x000000ff, /* src_mask */ | |
920 | + 0x000000ff, /* dst_mask */ | |
921 | + PCRELOFFSET), /* pcrel_offset */ | |
922 | + HOWTO (R_PCRWORD, /* type */ | |
923 | + 0, /* rightshift */ | |
924 | + 1, /* size (0 = byte, 1 = short, 2 = long) */ | |
925 | + 16, /* bitsize */ | |
926 | + TRUE, /* pc_relative */ | |
927 | + 0, /* bitpos */ | |
928 | + complain_overflow_signed, /* complain_on_overflow */ | |
929 | + coff_ext_avr_reloc, /* special_function */ | |
930 | + "DISP16", /* name */ | |
931 | + TRUE, /* partial_inplace */ | |
932 | + 0x0000ffff, /* src_mask */ | |
933 | + 0x0000ffff, /* dst_mask */ | |
934 | + PCRELOFFSET), /* pcrel_offset */ | |
935 | + HOWTO (R_PCRLONG, /* type */ | |
936 | + 0, /* rightshift */ | |
937 | + 2, /* size (0 = byte, 1 = short, 2 = long) */ | |
938 | + 32, /* bitsize */ | |
939 | + TRUE, /* pc_relative */ | |
940 | + 0, /* bitpos */ | |
941 | + complain_overflow_signed, /* complain_on_overflow */ | |
942 | + coff_ext_avr_reloc, /* special_function */ | |
943 | + "DISP32", /* name */ | |
944 | + TRUE, /* partial_inplace */ | |
945 | + 0xffffffff, /* src_mask */ | |
946 | + 0xffffffff, /* dst_mask */ | |
947 | + PCRELOFFSET) /* pcrel_offset */ | |
948 | +}; | |
4cd5ba0f | 949 | + |
f33182aa | 950 | +/* Turn a howto into a reloc nunmber */ |
4cd5ba0f | 951 | + |
f33182aa | 952 | +#define SELECT_RELOC(x,howto) { x.r_type = howto->type; } |
953 | +#define BADMAG(x) AVRBADMAG(x) | |
954 | +#define AVR 1 /* Customize coffcode.h */ | |
4cd5ba0f | 955 | + |
f33182aa | 956 | +#define RTYPE2HOWTO(cache_ptr, dst) \ |
957 | + (cache_ptr)->howto = howto_table + (dst)->r_type; | |
4cd5ba0f | 958 | + |
f33182aa | 959 | +/* For AVR COFF a STYP_NOLOAD | STYP_BSS section is part of a shared |
960 | + library. On some other COFF targets STYP_BSS is normally | |
961 | + STYP_NOLOAD. */ | |
962 | +#define BSS_NOLOAD_IS_SHARED_LIBRARY | |
4cd5ba0f | 963 | + |
f33182aa | 964 | +/* Compute the addend of a reloc. If the reloc is to a common symbol, |
965 | + the object file contains the value of the common symbol. By the | |
966 | + time this is called, the linker may be using a different symbol | |
967 | + from a different object file with a different value. Therefore, we | |
968 | + hack wildly to locate the original symbol from this file so that we | |
969 | + can make the correct adjustment. This macro sets coffsym to the | |
970 | + symbol from the original file, and uses it to set the addend value | |
971 | + correctly. If this is not a common symbol, the usual addend | |
972 | + calculation is done, except that an additional tweak is needed for | |
973 | + PC relative relocs. | |
974 | + FIXME: This macro refers to symbols and asect; these are from the | |
975 | + calling function, not the macro arguments. */ | |
4cd5ba0f | 976 | + |
f33182aa | 977 | +#define CALC_ADDEND(abfd, ptr, reloc, cache_ptr) \ |
978 | + { \ | |
979 | + coff_symbol_type *coffsym = (coff_symbol_type *) NULL; \ | |
980 | + if (ptr && bfd_asymbol_bfd (ptr) != abfd) \ | |
981 | + coffsym = (obj_symbols (abfd) \ | |
982 | + + (cache_ptr->sym_ptr_ptr - symbols)); \ | |
983 | + else if (ptr) \ | |
984 | + coffsym = coff_symbol_from (abfd, ptr); \ | |
985 | + if (coffsym != (coff_symbol_type *) NULL \ | |
986 | + && coffsym->native->u.syment.n_scnum == 0) \ | |
987 | + cache_ptr->addend = - coffsym->native->u.syment.n_value; \ | |
988 | + else if (ptr && bfd_asymbol_bfd (ptr) == abfd \ | |
989 | + && ptr->section != (asection *) NULL) \ | |
990 | + cache_ptr->addend = - (ptr->section->vma + ptr->value); \ | |
991 | + else \ | |
992 | + cache_ptr->addend = 0; \ | |
993 | + if (ptr && howto_table[reloc.r_type].pc_relative) \ | |
994 | + cache_ptr->addend += asect->vma; \ | |
995 | + } | |
4cd5ba0f | 996 | + |
f33182aa | 997 | +/* We use the special COFF backend linker. */ |
998 | +#define coff_relocate_section _bfd_coff_generic_relocate_section | |
4cd5ba0f | 999 | + |
f33182aa | 1000 | +static reloc_howto_type * |
1001 | +coff_ext_avr_rtype_to_howto (abfd, sec, rel, h, sym, addendp) | |
1002 | + bfd *abfd ATTRIBUTE_UNUSED; | |
1003 | + asection *sec; | |
1004 | + struct internal_reloc *rel; | |
1005 | + struct coff_link_hash_entry *h; | |
1006 | + struct internal_syment *sym; | |
1007 | + bfd_vma *addendp; | |
4cd5ba0f | 1008 | +{ |
4cd5ba0f | 1009 | + |
f33182aa | 1010 | + reloc_howto_type *howto; |
4cd5ba0f | 1011 | + |
f33182aa | 1012 | + howto = howto_table + rel->r_type; |
4cd5ba0f | 1013 | + |
f33182aa | 1014 | + if (howto->pc_relative) |
1015 | + *addendp += sec->vma; | |
4cd5ba0f | 1016 | + |
f33182aa | 1017 | + if (sym != NULL && sym->n_scnum == 0 && sym->n_value != 0) |
1018 | + { | |
1019 | + /* This is a common symbol. The section contents include the | |
1020 | + size (sym->n_value) as an addend. The relocate_section | |
1021 | + function will be adding in the final value of the symbol. We | |
1022 | + need to subtract out the current size in order to get the | |
1023 | + correct result. */ | |
4cd5ba0f | 1024 | + |
f33182aa | 1025 | + BFD_ASSERT (h != NULL); |
4cd5ba0f | 1026 | + |
f33182aa | 1027 | + /* I think we *do* want to bypass this. If we don't, I have seen some data |
1028 | + parameters get the wrong relcation address. If I link two versions | |
1029 | + with and without this section bypassed and then do a binary comparison, | |
1030 | + the addresses which are different can be looked up in the map. The | |
1031 | + case in which this section has been bypassed has addresses which correspond | |
1032 | + to values I can find in the map. */ | |
1033 | + *addendp -= sym->n_value; | |
1034 | + } | |
4cd5ba0f | 1035 | + |
f33182aa | 1036 | + /* If the output symbol is common (in which case this must be a |
1037 | + relocateable link), we need to add in the final size of the | |
1038 | + common symbol. */ | |
1039 | + if (h != NULL && h->root.type == bfd_link_hash_common) | |
1040 | + *addendp += h->root.u.c.size; | |
4cd5ba0f | 1041 | + |
f33182aa | 1042 | + return howto; |
4cd5ba0f ER |
1043 | +} |
1044 | + | |
f33182aa | 1045 | +#define coff_rtype_to_howto coff_ext_avr_rtype_to_howto |
4cd5ba0f | 1046 | + |
f33182aa | 1047 | +#include "coffcode.h" |
4cd5ba0f | 1048 | + |
f33182aa | 1049 | +static const bfd_target * |
1050 | +coff_ext_avr_object_p(a) | |
1051 | + bfd *a; | |
4cd5ba0f | 1052 | +{ |
f33182aa | 1053 | + return coff_object_p (a); |
4cd5ba0f ER |
1054 | +} |
1055 | + | |
f33182aa | 1056 | +const bfd_target |
1057 | +#ifdef TARGET_SYM | |
1058 | + TARGET_SYM = | |
1059 | +#else | |
1060 | + avrextcoff_vec = | |
1061 | +#endif | |
4cd5ba0f | 1062 | +{ |
f33182aa | 1063 | +#ifdef TARGET_NAME |
1064 | + TARGET_NAME, | |
1065 | +#else | |
1066 | + "coff-ext-avr", /* name */ | |
1067 | +#endif | |
1068 | + bfd_target_coff_flavour, | |
1069 | + BFD_ENDIAN_LITTLE, /* data byte order is little */ | |
1070 | + BFD_ENDIAN_LITTLE, /* header byte order is little */ | |
4cd5ba0f | 1071 | + |
f33182aa | 1072 | + (HAS_RELOC | EXEC_P | /* object flags */ |
1073 | + HAS_LINENO | HAS_DEBUG | | |
1074 | + HAS_SYMS | HAS_LOCALS | WP_TEXT), | |
4cd5ba0f | 1075 | + |
f33182aa | 1076 | + (SEC_HAS_CONTENTS | SEC_ALLOC | SEC_LOAD | SEC_RELOC), /* section flags */ |
1077 | + 0, /* leading char */ | |
1078 | + '/', /* ar_pad_char */ | |
1079 | + 15, /* ar_max_namelen */ | |
4cd5ba0f | 1080 | + |
f33182aa | 1081 | + bfd_getl64, bfd_getl_signed_64, bfd_putl64, |
1082 | + bfd_getl32, bfd_getl_signed_32, bfd_putl32, | |
1083 | + bfd_getl16, bfd_getl_signed_16, bfd_putl16, /* data */ | |
1084 | + bfd_getl64, bfd_getl_signed_64, bfd_putl64, | |
1085 | + bfd_getl32, bfd_getl_signed_32, bfd_putl32, | |
1086 | + bfd_getl16, bfd_getl_signed_16, bfd_putl16, /* hdrs */ | |
4cd5ba0f | 1087 | + |
f33182aa | 1088 | +/* Note that we allow an object file to be treated as a core file as well. */ |
1089 | + {_bfd_dummy_target, coff_ext_avr_object_p, /* bfd_check_format */ | |
1090 | + bfd_generic_archive_p, coff_ext_avr_object_p}, | |
1091 | + {bfd_false, coff_mkobject, _bfd_generic_mkarchive, /* bfd_set_format */ | |
1092 | + bfd_false}, | |
1093 | + {bfd_false, coff_write_object_contents, /* bfd_write_contents */ | |
1094 | + _bfd_write_archive_contents, bfd_false}, | |
4cd5ba0f | 1095 | + |
f33182aa | 1096 | + BFD_JUMP_TABLE_GENERIC (coff), |
1097 | + BFD_JUMP_TABLE_COPY (coff), | |
1098 | + BFD_JUMP_TABLE_CORE (_bfd_nocore), | |
1099 | + BFD_JUMP_TABLE_ARCHIVE (_bfd_archive_coff), | |
1100 | + BFD_JUMP_TABLE_SYMBOLS (coff), | |
1101 | + BFD_JUMP_TABLE_RELOCS (coff), | |
1102 | + BFD_JUMP_TABLE_WRITE (coff), | |
1103 | + BFD_JUMP_TABLE_LINK (coff), | |
1104 | + BFD_JUMP_TABLE_DYNAMIC (_bfd_nodynamic), | |
4cd5ba0f | 1105 | + |
f33182aa | 1106 | + NULL, |
4cd5ba0f | 1107 | + |
f33182aa | 1108 | + COFF_SWAP_TABLE |
1109 | +}; | |
1110 | diff -uNdr binutils-2.17.50.0.18-old/bfd/coffcode.h binutils-2.17.50.0.18/bfd/coffcode.h | |
1111 | --- binutils-2.17.50.0.18-old/bfd/coffcode.h 2007-08-01 17:12:02.000000000 +0200 | |
1112 | +++ binutils-2.17.50.0.18/bfd/coffcode.h 2007-10-20 16:45:33.000000000 +0200 | |
1113 | @@ -1,3 +1,4 @@ | |
4cd5ba0f | 1114 | + |
f33182aa | 1115 | /* Support for the generic parts of most COFF variants, for BFD. |
1116 | Copyright 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, | |
1117 | 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007 | |
1118 | @@ -1767,6 +1768,17 @@ | |
1119 | coff->relocbase = 0; | |
1120 | coff->local_toc_sym_map = 0; | |
1121 | ||
1122 | + /* These members communicate important constants about the symbol | |
1123 | + table to GDB's symbol-reading code. These `constants' | |
1124 | + unfortunately vary among coff implementations... */ | |
1125 | + coff->local_n_btmask = N_BTMASK; | |
1126 | + coff->local_n_btshft = N_BTSHFT; | |
1127 | + coff->local_n_tmask = N_TMASK; | |
1128 | + coff->local_n_tshift = N_TSHIFT; | |
1129 | + coff->local_symesz = bfd_coff_symesz (abfd); | |
1130 | + coff->local_auxesz = bfd_coff_auxesz (abfd); | |
1131 | + coff->local_linesz = bfd_coff_linesz (abfd); | |
4cd5ba0f | 1132 | + |
f33182aa | 1133 | /* make_abs_section(abfd);*/ |
1134 | ||
1135 | return TRUE; | |
1136 | @@ -1791,17 +1803,6 @@ | |
1137 | ||
1138 | coff->sym_filepos = internal_f->f_symptr; | |
1139 | ||
1140 | - /* These members communicate important constants about the symbol | |
1141 | - table to GDB's symbol-reading code. These `constants' | |
1142 | - unfortunately vary among coff implementations... */ | |
1143 | - coff->local_n_btmask = N_BTMASK; | |
1144 | - coff->local_n_btshft = N_BTSHFT; | |
1145 | - coff->local_n_tmask = N_TMASK; | |
1146 | - coff->local_n_tshift = N_TSHIFT; | |
1147 | - coff->local_symesz = bfd_coff_symesz (abfd); | |
1148 | - coff->local_auxesz = bfd_coff_auxesz (abfd); | |
1149 | - coff->local_linesz = bfd_coff_linesz (abfd); | |
1150 | - | |
1151 | coff->timestamp = internal_f->f_timdat; | |
1152 | ||
1153 | obj_raw_syment_count (abfd) = | |
1154 | @@ -1928,6 +1929,11 @@ | |
1155 | } | |
1156 | break; | |
1157 | #endif | |
1158 | +#ifdef AVRMAGIC | |
1159 | + case AVRMAGIC: | |
1160 | + arch = bfd_arch_avr; | |
1161 | + break; | |
1162 | +#endif | |
1163 | #ifdef MC68MAGIC | |
1164 | case MC68MAGIC: | |
1165 | case M68MAGIC: | |
1166 | @@ -2724,6 +2730,13 @@ | |
1167 | return TRUE; | |
1168 | #endif | |
1169 | ||
1170 | +#ifdef AVRMAGIC | |
1171 | + case bfd_arch_avr: | |
1172 | + *magicp = AVRMAGIC; | |
1173 | + return TRUE; | |
1174 | + break; | |
1175 | +#endif | |
4cd5ba0f | 1176 | + |
f33182aa | 1177 | #ifdef PPCMAGIC |
1178 | case bfd_arch_powerpc: | |
1179 | *magicp = PPCMAGIC; | |
1180 | @@ -3520,6 +3533,11 @@ | |
1181 | section.s_page = coff_get_section_load_page (current); | |
1182 | #endif | |
1183 | ||
1184 | +#ifdef AVR | |
1185 | + /* AVR uses s_paddr the way GNU uses s_vaddr, and effectively | |
1186 | + ignores s_vaddr. */ | |
1187 | + section.s_paddr = current->vma; | |
1188 | +#endif | |
1189 | #ifdef COFF_WITH_PE | |
1190 | section.s_paddr = 0; | |
1191 | #endif | |
1192 | @@ -3864,6 +3882,17 @@ | |
1193 | internal_a.magic = ZMAGIC; | |
1194 | #endif | |
1195 | ||
1196 | +#ifdef AVR | |
1197 | + /* a.out is a dummy for non-extended COFF */ | |
1198 | + internal_a.magic = AVRAOUTMAGIC; | |
1199 | + /* Upper nibble of f_flags must be set for historical reasons. | |
1200 | + The upper byte remains blank on coff-avr, so undo the F_AR32WR | |
1201 | + setting performed above. */ | |
1202 | + internal_f.f_flags |= F_JUNK; | |
1203 | + internal_f.f_flags &= ~F_UNUSED; | |
1204 | +#define __A_MAGIC_SET__ | |
1205 | +#endif /* AVR */ | |
4cd5ba0f | 1206 | + |
f33182aa | 1207 | #if defined(PPC_PE) |
1208 | #define __A_MAGIC_SET__ | |
1209 | internal_a.magic = IMAGE_NT_OPTIONAL_HDR_MAGIC; | |
1210 | @@ -3931,8 +3960,16 @@ | |
1211 | #endif | |
1212 | } | |
1213 | ||
1214 | +#ifdef AVR_EXT_COFF | |
1215 | + /* Note that we do not set F_PTRINFO because the GNU toolchain | |
1216 | + doesn't provide any information about the target of a pointer, | |
1217 | + so we cannot derive which section our pointer target would be | |
1218 | + in. */ | |
1219 | + internal_a.vstamp = F_FULLPATHS | F_STRUCTINFO; | |
1220 | +#else | |
1221 | /* FIXME: Does anybody ever set this to another value? */ | |
1222 | internal_a.vstamp = 0; | |
1223 | +#endif | |
1224 | ||
1225 | /* Now should write relocs, strings, syms. */ | |
1226 | obj_sym_filepos (abfd) = sym_base; | |
1227 | @@ -4118,22 +4155,29 @@ | |
1228 | char * buff; | |
1229 | bfd_size_type amount = bfd_coff_aoutsz (abfd); | |
1230 | ||
1231 | - buff = bfd_malloc (amount); | |
1232 | - if (buff == NULL) | |
1233 | - return FALSE; | |
1234 | + /* Do not attempt to malloc() zero bytes. According to the | |
1235 | + C standard, the behaviour is implementation-defined, and | |
1236 | + malloc() might return NULL in that case, which would confuse | |
1237 | + us to assume an error where it actually isn't. */ | |
1238 | + if (amount != 0) | |
4cd5ba0f | 1239 | + { |
f33182aa | 1240 | + buff = bfd_malloc (amount); |
1241 | + if (buff == NULL) | |
1242 | + return FALSE; | |
1243 | ||
1244 | - coff_swap_aouthdr_out (abfd, & internal_a, buff); | |
1245 | - amount = bfd_bwrite (buff, amount, abfd); | |
1246 | + coff_swap_aouthdr_out (abfd, & internal_a, buff); | |
1247 | + amount = bfd_bwrite (buff, amount, abfd); | |
1248 | ||
1249 | - free (buff); | |
1250 | + free (buff); | |
1251 | ||
1252 | - if (amount != bfd_coff_aoutsz (abfd)) | |
1253 | - return FALSE; | |
1254 | + if (amount != bfd_coff_aoutsz (abfd)) | |
1255 | + return FALSE; | |
1256 | ||
1257 | #ifdef COFF_IMAGE_WITH_PE | |
1258 | - if (! coff_apply_checksum (abfd)) | |
1259 | - return FALSE; | |
1260 | + if (! coff_apply_checksum (abfd)) | |
1261 | + return FALSE; | |
1262 | #endif | |
1263 | + } | |
1264 | } | |
1265 | #ifdef RS6000COFF_C | |
1266 | else | |
1267 | @@ -4414,6 +4458,10 @@ | |
1268 | /* In PE, 0x69 (105) denotes a weak external symbol. */ | |
1269 | case C_NT_WEAK: | |
1270 | #endif | |
1271 | +#ifdef AVR | |
1272 | + /* Some AVR COFF compilers handle EXTDEF like EXT. */ | |
1273 | + case C_EXTDEF: /* external definition */ | |
1274 | +#endif | |
1275 | switch (coff_classify_symbol (abfd, &src->u.syment)) | |
1276 | { | |
1277 | case COFF_SYMBOL_GLOBAL: | |
1278 | @@ -4637,7 +4685,9 @@ | |
1279 | && src->u.syment.n_scnum == 0) | |
1280 | break; | |
1281 | /* Fall through. */ | |
1282 | +#if !defined(AVR) | |
1283 | case C_EXTDEF: /* External definition. */ | |
1284 | +#endif | |
1285 | case C_ULABEL: /* Undefined label. */ | |
1286 | case C_USTATIC: /* Undefined static. */ | |
1287 | #ifndef COFF_WITH_PE | |
1288 | diff -uNdr binutils-2.17.50.0.18-old/bfd/coffgen.c binutils-2.17.50.0.18/bfd/coffgen.c | |
1289 | --- binutils-2.17.50.0.18-old/bfd/coffgen.c 2007-08-01 15:11:47.000000000 +0200 | |
1290 | +++ binutils-2.17.50.0.18/bfd/coffgen.c 2007-10-20 16:45:33.000000000 +0200 | |
1291 | @@ -687,6 +687,20 @@ | |
1292 | if (last_file != NULL) | |
1293 | last_file->n_value = native_index; | |
1294 | last_file = &(s->u.syment); | |
1295 | + if (bfd_get_arch (bfd_ptr) == bfd_arch_avr | |
1296 | + && bfd_coff_long_filenames (bfd_ptr) | |
1297 | + && s->u.syment.n_numaux > 0) | |
1298 | + { | |
1299 | + /* AVR COFF records long filenames in successive aux | |
1300 | + records. Adjust the number of aux records | |
1301 | + required here, so the renumbering will account | |
1302 | + for them. */ | |
1303 | + unsigned int filnmlen = bfd_coff_filnmlen (bfd_ptr); | |
1304 | + unsigned int namelen = strlen (coff_symbol_ptr->symbol.name); | |
1305 | + unsigned int n = (namelen + filnmlen - 1) / filnmlen; | |
4cd5ba0f | 1306 | + |
f33182aa | 1307 | + s->u.syment.n_numaux = n > NAUXENTS? NAUXENTS: n; |
1308 | + } | |
1309 | } | |
1310 | else | |
1311 | /* Modify the symbol values according to their section and | |
1312 | @@ -815,6 +829,20 @@ | |
1313 | { | |
1314 | if (name_length <= filnmlen) | |
1315 | strncpy (auxent->x_file.x_fname, name, filnmlen); | |
1316 | + else if (bfd_get_arch (abfd) == bfd_arch_avr) | |
4cd5ba0f | 1317 | + { |
f33182aa | 1318 | + /* AVR COFF records long filenames in successive aux records. */ |
1319 | + int i = 1; | |
1320 | + while (name_length > filnmlen && i < NAUXENTS) | |
1321 | + { | |
1322 | + strncpy (auxent->x_file.x_fname, name, filnmlen); | |
1323 | + name += filnmlen; | |
1324 | + name_length -= filnmlen; | |
1325 | + i++; | |
1326 | + auxent = &(native + i)->u.auxent; | |
1327 | + } | |
1328 | + strncpy (auxent->x_file.x_fname, name, filnmlen); | |
4cd5ba0f | 1329 | + } |
f33182aa | 1330 | else |
1331 | { | |
1332 | auxent->x_file.x_n.x_offset = *string_size_p + STRING_SIZE_SIZE; | |
1333 | @@ -1218,7 +1246,11 @@ | |
1334 | if (bfd_bwrite (".file", (bfd_size_type) 6, abfd) != 6) | |
1335 | return FALSE; | |
1336 | } | |
1337 | - maxlen = bfd_coff_filnmlen (abfd); | |
1338 | + if (bfd_get_arch (abfd) == bfd_arch_avr) | |
1339 | + /* AVR COFF handles long file names in aux records. */ | |
1340 | + maxlen = name_length; | |
1341 | + else | |
1342 | + maxlen = bfd_coff_filnmlen (abfd); | |
1343 | } | |
1344 | else | |
1345 | maxlen = bfd_coff_force_symnames_in_strings (abfd) ? 0 : SYMNMLEN; | |
1346 | @@ -1655,14 +1687,27 @@ | |
1347 | { | |
1348 | /* Ordinary short filename, put into memory anyway. The | |
1349 | Microsoft PE tools sometimes store a filename in | |
1350 | - multiple AUX entries. */ | |
1351 | - if (internal_ptr->u.syment.n_numaux > 1 | |
1352 | - && coff_data (abfd)->pe) | |
1353 | - internal_ptr->u.syment._n._n_n._n_offset = | |
1354 | - ((bfd_hostptr_t) | |
1355 | - copy_name (abfd, | |
1356 | - (internal_ptr + 1)->u.auxent.x_file.x_fname, | |
1357 | - internal_ptr->u.syment.n_numaux * symesz)); | |
1358 | + multiple AUX entries. | |
1359 | + AVR COFF does it that way, too. */ | |
1360 | + if (internal_ptr->u.syment.n_numaux > 1 | |
1361 | + && (coff_data (abfd)->pe | |
1362 | + || (bfd_get_arch (abfd) == bfd_arch_avr))) | |
1363 | + { | |
1364 | + char *b; | |
1365 | + unsigned int i; | |
1366 | + | |
1367 | + /* We allocate enough storage to fit the contents of | |
1368 | + this many aux records, and simply append a \0. | |
1369 | + This ensures the string will always be | |
1370 | + terminated, even in the case where it just fit | |
1371 | + into the aux records. */ | |
1372 | + b = (char *) bfd_alloc (abfd, | |
1373 | + internal_ptr->u.syment.n_numaux * FILNMLEN + 1); | |
1374 | + internal_ptr->u.syment._n._n_n._n_offset = (long) b; | |
1375 | + b[internal_ptr->u.syment.n_numaux * FILNMLEN] = '\0'; | |
1376 | + for (i = 0; i < internal_ptr->u.syment.n_numaux; i++, b += FILNMLEN) | |
1377 | + memcpy (b, (internal_ptr + i + 1)->u.auxent.x_file.x_fname, FILNMLEN); | |
1378 | + } | |
1379 | else | |
1380 | internal_ptr->u.syment._n._n_n._n_offset = | |
1381 | ((bfd_hostptr_t) | |
1382 | @@ -1768,9 +1813,9 @@ | |
1383 | ||
1384 | if (new == NULL) | |
1385 | return NULL; | |
1386 | - /* @@ The 10 is a guess at a plausible maximum number of aux entries | |
1387 | - (but shouldn't be a constant). */ | |
1388 | - amt = sizeof (combined_entry_type) * 10; | |
1389 | + /* @@ The NAUXENTS is a guess at a plausible maximum number of aux | |
1390 | + entries (but shouldn't be a constant). */ | |
1391 | + amt = sizeof (combined_entry_type) * (NAUXENTS + 1); | |
1392 | new->native = bfd_zalloc (abfd, amt); | |
1393 | if (!new->native) | |
1394 | return NULL; | |
1395 | diff -uNdr binutils-2.17.50.0.18-old/bfd/coffswap.h binutils-2.17.50.0.18/bfd/coffswap.h | |
1396 | --- binutils-2.17.50.0.18-old/bfd/coffswap.h 2007-08-01 15:11:47.000000000 +0200 | |
1397 | +++ binutils-2.17.50.0.18/bfd/coffswap.h 2007-10-20 16:45:33.000000000 +0200 | |
1398 | @@ -383,7 +383,11 @@ | |
1399 | void * ext1, | |
1400 | int type, | |
1401 | int class, | |
1402 | - int indx, | |
1403 | + int indx | |
1404 | +#if defined(AVR) && __GNUC__ | |
1405 | + __attribute__((unused)) | |
1406 | +#endif | |
1407 | + , | |
1408 | int numaux, | |
1409 | void * in1) | |
1410 | { | |
1411 | @@ -409,9 +413,13 @@ | |
1412 | #else | |
1413 | if (numaux > 1) | |
1414 | { | |
1415 | +#if defined(AVR) | |
1416 | + memcpy (in->x_file.x_fname, ext->x_file.x_fname, sizeof (AUXENT)); | |
1417 | +#else | |
1418 | if (indx == 0) | |
1419 | memcpy (in->x_file.x_fname, ext->x_file.x_fname, | |
1420 | numaux * sizeof (AUXENT)); | |
1421 | +#endif | |
1422 | } | |
1423 | else | |
1424 | memcpy (in->x_file.x_fname, ext->x_file.x_fname, FILNMLEN); | |
1425 | diff -uNdr binutils-2.17.50.0.18-old/bfd/config.bfd binutils-2.17.50.0.18/bfd/config.bfd | |
1426 | --- binutils-2.17.50.0.18-old/bfd/config.bfd 2007-08-01 15:11:47.000000000 +0200 | |
1427 | +++ binutils-2.17.50.0.18/bfd/config.bfd 2007-10-20 16:45:33.000000000 +0200 | |
1428 | @@ -327,6 +327,7 @@ | |
1429 | ||
1430 | avr-*-*) | |
1431 | targ_defvec=bfd_elf32_avr_vec | |
1432 | + targ_selvecs="bfd_elf32_avr_vec avrcoff_vec avrextcoff_vec" | |
1433 | ;; | |
1434 | ||
1435 | bfin-*-*) | |
1436 | diff -uNdr binutils-2.17.50.0.18-old/bfd/configure binutils-2.17.50.0.18/bfd/configure | |
1437 | --- binutils-2.17.50.0.18-old/bfd/configure 2007-08-01 15:11:47.000000000 +0200 | |
1438 | +++ binutils-2.17.50.0.18/bfd/configure 2007-10-20 16:45:33.000000000 +0200 | |
1439 | @@ -19034,6 +19034,8 @@ | |
1440 | armpe_little_vec) tb="$tb pe-arm.lo peigen.lo cofflink.lo " ;; | |
1441 | armpei_big_vec) tb="$tb pei-arm.lo peigen.lo cofflink.lo " ;; | |
1442 | armpei_little_vec) tb="$tb pei-arm.lo peigen.lo cofflink.lo " ;; | |
1443 | + avrcoff_vec) tb="$tb coff-avr.lo cofflink.lo " ;; | |
1444 | + avrextcoff_vec) tb="$tb coff-ext-avr.lo cofflink.lo " ;; | |
1445 | b_out_vec_big_host) tb="$tb bout.lo aout32.lo" ;; | |
1446 | b_out_vec_little_host) tb="$tb bout.lo aout32.lo" ;; | |
1447 | bfd_efi_app_ia32_vec) tb="$tb efi-app-ia32.lo peigen.lo cofflink.lo" ;; | |
1448 | diff -uNdr binutils-2.17.50.0.18-old/bfd/configure.in binutils-2.17.50.0.18/bfd/configure.in | |
1449 | --- binutils-2.17.50.0.18-old/bfd/configure.in 2007-08-01 15:11:47.000000000 +0200 | |
1450 | +++ binutils-2.17.50.0.18/bfd/configure.in 2007-10-20 16:45:33.000000000 +0200 | |
1451 | @@ -612,6 +612,8 @@ | |
1452 | armpe_little_vec) tb="$tb pe-arm.lo peigen.lo cofflink.lo " ;; | |
1453 | armpei_big_vec) tb="$tb pei-arm.lo peigen.lo cofflink.lo " ;; | |
1454 | armpei_little_vec) tb="$tb pei-arm.lo peigen.lo cofflink.lo " ;; | |
1455 | + avrcoff_vec) tb="$tb coff-avr.lo cofflink.lo " ;; | |
1456 | + avrextcoff_vec) tb="$tb coff-ext-avr.lo cofflink.lo " ;; | |
1457 | b_out_vec_big_host) tb="$tb bout.lo aout32.lo" ;; | |
1458 | b_out_vec_little_host) tb="$tb bout.lo aout32.lo" ;; | |
1459 | bfd_efi_app_ia32_vec) tb="$tb efi-app-ia32.lo peigen.lo cofflink.lo" ;; | |
1460 | diff -uNdr binutils-2.17.50.0.18-old/bfd/targets.c binutils-2.17.50.0.18/bfd/targets.c | |
1461 | --- binutils-2.17.50.0.18-old/bfd/targets.c 2007-08-01 15:11:48.000000000 +0200 | |
1462 | +++ binutils-2.17.50.0.18/bfd/targets.c 2007-10-20 16:45:33.000000000 +0200 | |
1463 | @@ -558,6 +558,8 @@ | |
1464 | extern const bfd_target armpe_little_vec; | |
1465 | extern const bfd_target armpei_big_vec; | |
1466 | extern const bfd_target armpei_little_vec; | |
1467 | +extern const bfd_target avrcoff_vec; | |
1468 | +extern const bfd_target avrextcoff_vec; | |
1469 | extern const bfd_target b_out_vec_big_host; | |
1470 | extern const bfd_target b_out_vec_little_host; | |
1471 | extern const bfd_target bfd_efi_app_ia32_vec; | |
1472 | @@ -876,6 +878,8 @@ | |
1473 | &armpe_little_vec, | |
1474 | &armpei_big_vec, | |
1475 | &armpei_little_vec, | |
1476 | + &avrcoff_vec, | |
1477 | + &avrextcoff_vec, | |
1478 | &b_out_vec_big_host, | |
1479 | &b_out_vec_little_host, | |
1480 | &bfd_efi_app_ia32_vec, | |
1481 | diff -uNdr binutils-2.17.50.0.18-old/binutils/Makefile.am binutils-2.17.50.0.18/binutils/Makefile.am | |
1482 | --- binutils-2.17.50.0.18-old/binutils/Makefile.am 2007-08-01 15:11:48.000000000 +0200 | |
1483 | +++ binutils-2.17.50.0.18/binutils/Makefile.am 2007-10-20 16:45:33.000000000 +0200 | |
1484 | @@ -98,7 +98,7 @@ | |
1485 | resbin.c rescoff.c resrc.c resres.c \ | |
1486 | size.c srconv.c stabs.c strings.c sysdump.c \ | |
1487 | unwind-ia64.c version.c \ | |
1488 | - windres.c winduni.c wrstabs.c \ | |
1489 | + windres.c winduni.c wrcoff.c wrstabs.c \ | |
1490 | windmc.c mclex.c | |
1491 | ||
1492 | GENERATED_CFILES = \ | |
1493 | @@ -106,7 +106,7 @@ | |
1494 | defparse.c deflex.c nlmheader.c rcparse.c mcparse.c | |
1495 | ||
1496 | DEBUG_SRCS = rddbg.c debug.c stabs.c ieee.c rdcoff.c | |
1497 | -WRITE_DEBUG_SRCS = $(DEBUG_SRCS) wrstabs.c | |
1498 | +WRITE_DEBUG_SRCS = $(DEBUG_SRCS) wrstabs.c wrcoff.c | |
1499 | ||
1500 | # Code shared by all the binutils. | |
1501 | BULIBS = bucomm.c version.c filemode.c | |
1502 | diff -uNdr binutils-2.17.50.0.18-old/binutils/Makefile.in binutils-2.17.50.0.18/binutils/Makefile.in | |
1503 | --- binutils-2.17.50.0.18-old/binutils/Makefile.in 2007-08-01 15:11:48.000000000 +0200 | |
1504 | +++ binutils-2.17.50.0.18/binutils/Makefile.in 2007-10-20 16:45:33.000000000 +0200 | |
1505 | @@ -129,7 +129,7 @@ | |
1506 | nm_new_OBJECTS = $(am_nm_new_OBJECTS) | |
1507 | nm_new_LDADD = $(LDADD) | |
1508 | am__objects_2 = rddbg.$(OBJEXT) debug.$(OBJEXT) stabs.$(OBJEXT) \ | |
1509 | - ieee.$(OBJEXT) rdcoff.$(OBJEXT) | |
1510 | + ieee.$(OBJEXT) rdcoff.$(OBJEXT) wrcoff.$(OBJEXT) | |
1511 | am__objects_3 = $(am__objects_2) wrstabs.$(OBJEXT) | |
1512 | am_objcopy_OBJECTS = objcopy.$(OBJEXT) not-strip.$(OBJEXT) \ | |
1513 | rename.$(OBJEXT) $(am__objects_3) $(am__objects_1) | |
1514 | @@ -418,7 +418,7 @@ | |
1515 | resbin.c rescoff.c resrc.c resres.c \ | |
1516 | size.c srconv.c stabs.c strings.c sysdump.c \ | |
1517 | unwind-ia64.c version.c \ | |
1518 | - windres.c winduni.c wrstabs.c \ | |
1519 | + windres.c winduni.c wrcoff.c wrstabs.c \ | |
1520 | windmc.c mclex.c | |
1521 | ||
1522 | GENERATED_CFILES = \ | |
1523 | @@ -426,7 +426,7 @@ | |
1524 | defparse.c deflex.c nlmheader.c rcparse.c mcparse.c | |
1525 | ||
1526 | DEBUG_SRCS = rddbg.c debug.c stabs.c ieee.c rdcoff.c | |
1527 | -WRITE_DEBUG_SRCS = $(DEBUG_SRCS) wrstabs.c | |
1528 | +WRITE_DEBUG_SRCS = $(DEBUG_SRCS) wrstabs.c wrcoff.c | |
1529 | ||
1530 | # Code shared by all the binutils. | |
1531 | BULIBS = bucomm.c version.c filemode.c | |
1532 | diff -uNdr binutils-2.17.50.0.18-old/binutils/bucomm.c binutils-2.17.50.0.18/binutils/bucomm.c | |
1533 | --- binutils-2.17.50.0.18-old/binutils/bucomm.c 2007-08-01 15:11:49.000000000 +0200 | |
1534 | +++ binutils-2.17.50.0.18/binutils/bucomm.c 2007-10-20 16:45:33.000000000 +0200 | |
1535 | @@ -501,6 +501,32 @@ | |
1536 | return ret; | |
1537 | } | |
1538 | ||
1539 | +/* Return the basename of "file", i. e. everything minus whatever | |
1540 | + directory part has been provided. Stolen from bfd/archive.c. | |
1541 | + Should we also handle the VMS case (as in bfd/archive.c)? */ | |
1542 | +const char * | |
1543 | +bu_basename (file) | |
1544 | + const char *file; | |
1545 | +{ | |
1546 | + const char *filename = strrchr (file, '/'); | |
4cd5ba0f | 1547 | + |
f33182aa | 1548 | +#ifdef HAVE_DOS_BASED_FILE_SYSTEM |
1549 | + { | |
1550 | + /* We could have foo/bar\\baz, or foo\\bar, or d:bar. */ | |
1551 | + char *bslash = strrchr (file, '\\'); | |
1552 | + if (filename == NULL || (bslash != NULL && bslash > filename)) | |
1553 | + filename = bslash; | |
1554 | + if (filename == NULL && file[0] != '\0' && file[1] == ':') | |
1555 | + filename = file + 1; | |
1556 | + } | |
1557 | +#endif | |
1558 | + if (filename != (char *) NULL) | |
1559 | + filename++; | |
1560 | + else | |
1561 | + filename = file; | |
1562 | + return filename; | |
1563 | +} | |
4cd5ba0f | 1564 | + |
f33182aa | 1565 | /* Returns the size of the named file. If the file does not |
1566 | exist, or if it is not a real file, then a suitable non-fatal | |
1567 | error message is printed and zero is returned. */ | |
1568 | diff -uNdr binutils-2.17.50.0.18-old/binutils/bucomm.h binutils-2.17.50.0.18/binutils/bucomm.h | |
1569 | --- binutils-2.17.50.0.18-old/binutils/bucomm.h 2007-08-01 15:11:49.000000000 +0200 | |
1570 | +++ binutils-2.17.50.0.18/binutils/bucomm.h 2007-10-20 16:45:33.000000000 +0200 | |
1571 | @@ -54,6 +54,8 @@ | |
1572 | ||
1573 | off_t get_file_size (const char *); | |
1574 | ||
1575 | +const char *bu_basename PARAMS ((const char *)); | |
4cd5ba0f | 1576 | + |
f33182aa | 1577 | extern char *program_name; |
1578 | ||
1579 | /* filemode.c */ | |
1580 | diff -uNdr binutils-2.17.50.0.18-old/binutils/budbg.h binutils-2.17.50.0.18/binutils/budbg.h | |
1581 | --- binutils-2.17.50.0.18-old/binutils/budbg.h 2007-08-01 15:11:49.000000000 +0200 | |
1582 | +++ binutils-2.17.50.0.18/binutils/budbg.h 2007-10-20 16:45:33.000000000 +0200 | |
1583 | @@ -51,8 +51,11 @@ | |
1584 | ||
1585 | extern bfd_boolean write_ieee_debugging_info (bfd *, void *); | |
1586 | ||
1587 | -/* Routine used to read COFF debugging information. */ | |
1588 | +/* Routine used to read and write COFF debugging information. */ | |
1589 | ||
1590 | extern bfd_boolean parse_coff (bfd *, asymbol **, long, void *); | |
1591 | ||
1592 | +extern bfd_boolean write_coff_debugging_info | |
1593 | + (bfd *abfd, void *, long *symcountp, asymbol ***); | |
4cd5ba0f | 1594 | + |
f33182aa | 1595 | #endif |
1596 | diff -uNdr binutils-2.17.50.0.18-old/binutils/debug.c binutils-2.17.50.0.18/binutils/debug.c | |
1597 | --- binutils-2.17.50.0.18-old/binutils/debug.c 2007-08-01 15:11:49.000000000 +0200 | |
1598 | +++ binutils-2.17.50.0.18/binutils/debug.c 2007-10-20 16:45:33.000000000 +0200 | |
1599 | @@ -31,6 +31,7 @@ | |
1600 | #include <assert.h> | |
1601 | #include "bfd.h" | |
1602 | #include "libiberty.h" | |
1603 | +#include "bucomm.h" | |
1604 | #include "debug.h" | |
1605 | ||
1606 | /* Global information we keep for debugging. A pointer to this | |
1607 | @@ -552,6 +553,19 @@ | |
1608 | struct debug_type *t; | |
1609 | }; | |
1610 | ||
1611 | +/* Simple list, used for pathname translations. */ | |
1612 | +struct xlat_list | |
1613 | +{ | |
1614 | + /* Next string on list. */ | |
1615 | + struct xlat_list *next; | |
1616 | + /* Old part to match against. */ | |
1617 | + const char *old; | |
1618 | + size_t olen; | |
1619 | + /* New part to replace. */ | |
1620 | + const char *newstr; | |
1621 | + size_t nlen; | |
1622 | +}; | |
4cd5ba0f | 1623 | + |
f33182aa | 1624 | /* Local functions. */ |
1625 | ||
1626 | static void debug_error (const char *); | |
1627 | @@ -588,6 +602,11 @@ | |
1628 | (struct debug_handle *, struct debug_type *, struct debug_type *); | |
1629 | static bfd_boolean debug_class_type_samep | |
1630 | (struct debug_handle *, struct debug_type *, struct debug_type *); | |
1631 | +static const char *debug_xlat_pathname (const char *); | |
4cd5ba0f | 1632 | + |
f33182aa | 1633 | +/* List of pathname translations. */ |
1634 | +static struct xlat_list *xlat, *xltail; | |
1635 | +static bfd_boolean xlat_basename; | |
1636 | \f | |
1637 | /* Issue an error message. */ | |
1638 | ||
1639 | @@ -680,6 +699,8 @@ | |
1640 | ||
1641 | if (name == NULL) | |
1642 | name = ""; | |
1643 | + else | |
1644 | + name = debug_xlat_pathname (name); | |
1645 | ||
1646 | nfile = (struct debug_file *) xmalloc (sizeof *nfile); | |
1647 | memset (nfile, 0, sizeof *nfile); | |
1648 | @@ -720,6 +741,8 @@ | |
1649 | ||
1650 | if (name == NULL) | |
1651 | name = ""; | |
1652 | + else | |
1653 | + name = debug_xlat_pathname (name); | |
1654 | ||
1655 | if (info->current_unit == NULL) | |
1656 | { | |
1657 | @@ -3370,3 +3393,69 @@ | |
1658 | ||
1659 | return TRUE; | |
1660 | } | |
4cd5ba0f | 1661 | + |
f33182aa | 1662 | +/* Register a pathname translation. */ |
1663 | +void | |
1664 | +debug_register_pathname_xlat (oname, nname) | |
1665 | + const char *oname; | |
1666 | + const char *nname; | |
1667 | +{ | |
1668 | + struct xlat_list *xlp; | |
4cd5ba0f | 1669 | + |
f33182aa | 1670 | + /* Special case: if oname is given as NULL, this means the |
1671 | + --basename option has been given to objcopy. */ | |
1672 | + if (oname == NULL) | |
4cd5ba0f | 1673 | + { |
f33182aa | 1674 | + xlat_basename = TRUE; |
1675 | + return; | |
4cd5ba0f ER |
1676 | + } |
1677 | + | |
f33182aa | 1678 | + xlp = (struct xlat_list *) xmalloc (sizeof (struct xlat_list)); |
1679 | + xlp->next = NULL; | |
1680 | + if (xlat == NULL) | |
1681 | + xlat = xltail = xlp; | |
1682 | + else | |
4cd5ba0f | 1683 | + { |
f33182aa | 1684 | + xltail->next = xlp; |
1685 | + xltail = xlp; | |
4cd5ba0f | 1686 | + } |
f33182aa | 1687 | + xlp->old = oname; |
1688 | + xlp->newstr = nname; | |
1689 | + xlp->olen = strlen (oname); | |
1690 | + xlp->nlen = strlen (nname); | |
1691 | +} | |
4cd5ba0f | 1692 | + |
f33182aa | 1693 | +/* Try to translate a pathname. */ |
1694 | +static const char * | |
1695 | +debug_xlat_pathname (oname) | |
1696 | + const char *oname; | |
1697 | +{ | |
1698 | + struct xlat_list *xlp; | |
1699 | + char *cp; | |
1700 | + size_t olen; | |
4cd5ba0f | 1701 | + |
f33182aa | 1702 | + if (xlat_basename) |
1703 | + return bu_basename (oname); | |
4cd5ba0f | 1704 | + |
f33182aa | 1705 | + olen = strlen (oname); |
1706 | + for (xlp = xlat; xlp; xlp = xlp->next) | |
4cd5ba0f | 1707 | + { |
f33182aa | 1708 | + if (xlp->olen > olen) |
1709 | + /* This cannot be our turn. */ | |
1710 | + continue; | |
1711 | + /* Since we have pre-computed all our length values to avoid | |
1712 | + repetitively computing them, just use memcmp() since it's | |
1713 | + faster than strcmp(). */ | |
1714 | + if (memcmp (xlp->old, oname, xlp->olen) == 0) | |
1715 | + { | |
1716 | + cp = (char *) xmalloc (olen + xlp->nlen - xlp->olen + 1); | |
1717 | + memcpy (cp, xlp->newstr, xlp->nlen); | |
1718 | + memcpy (cp + xlp->nlen, oname + xlp->olen, | |
1719 | + olen - xlp->olen + 1); | |
1720 | + return cp; | |
1721 | + } | |
4cd5ba0f ER |
1722 | + } |
1723 | + | |
f33182aa | 1724 | + /* Not found, pass the original name on. */ |
1725 | + return oname; | |
4cd5ba0f | 1726 | +} |
f33182aa | 1727 | diff -uNdr binutils-2.17.50.0.18-old/binutils/debug.h binutils-2.17.50.0.18/binutils/debug.h |
1728 | --- binutils-2.17.50.0.18-old/binutils/debug.h 2007-08-01 15:11:49.000000000 +0200 | |
1729 | +++ binutils-2.17.50.0.18/binutils/debug.h 2007-10-20 16:45:33.000000000 +0200 | |
1730 | @@ -440,6 +440,12 @@ | |
1731 | ||
1732 | extern bfd_boolean debug_start_source (void *, const char *); | |
1733 | ||
1734 | +/* Register a pathname translation for source (and include) filenames. | |
1735 | + This is used by the --change-pathname option of objcopy. */ | |
4cd5ba0f | 1736 | + |
f33182aa | 1737 | +extern void debug_register_pathname_xlat |
1738 | + PARAMS ((const char *, const char *)); | |
4cd5ba0f | 1739 | + |
f33182aa | 1740 | /* Record a function definition. This implicitly starts a function |
1741 | block. The debug_type argument is the type of the return value. | |
1742 | The bfd_boolean indicates whether the function is globally visible. | |
1743 | diff -uNdr binutils-2.17.50.0.18-old/binutils/objcopy.c binutils-2.17.50.0.18/binutils/objcopy.c | |
1744 | --- binutils-2.17.50.0.18-old/binutils/objcopy.c 2007-08-01 15:11:49.000000000 +0200 | |
1745 | +++ binutils-2.17.50.0.18/binutils/objcopy.c 2007-10-20 16:45:33.000000000 +0200 | |
1746 | @@ -32,6 +32,7 @@ | |
1747 | #include "elf-bfd.h" | |
1748 | #include <sys/stat.h> | |
1749 | #include "libbfd.h" | |
1750 | +#include "debug.h" | |
1751 | ||
1752 | /* A list of symbols to explicitly strip out, or to keep. A linked | |
1753 | list is good enough for a small number from the command line, but | |
1754 | @@ -272,7 +273,9 @@ | |
1755 | OPTION_PURE, | |
1756 | OPTION_IMPURE, | |
1757 | OPTION_EXTRACT_SYMBOL, | |
1758 | - OPTION_REVERSE_BYTES | |
1759 | + OPTION_REVERSE_BYTES, | |
1760 | + OPTION_CHANGE_PATHNAME, | |
1761 | + OPTION_BASENAME | |
1762 | }; | |
1763 | ||
1764 | /* Options to handle if running as "strip". */ | |
1765 | @@ -316,10 +319,12 @@ | |
1766 | {"adjust-section-vma", required_argument, 0, OPTION_CHANGE_SECTION_ADDRESS}, | |
1767 | {"adjust-warnings", no_argument, 0, OPTION_CHANGE_WARNINGS}, | |
1768 | {"alt-machine-code", required_argument, 0, OPTION_ALT_MACH_CODE}, | |
1769 | + {"basename", no_argument, 0, OPTION_BASENAME}, | |
1770 | {"binary-architecture", required_argument, 0, 'B'}, | |
1771 | {"byte", required_argument, 0, 'b'}, | |
1772 | {"change-addresses", required_argument, 0, OPTION_CHANGE_ADDRESSES}, | |
1773 | {"change-leading-char", no_argument, 0, OPTION_CHANGE_LEADING_CHAR}, | |
1774 | + {"change-pathname", required_argument, 0, OPTION_CHANGE_PATHNAME}, | |
1775 | {"change-section-address", required_argument, 0, OPTION_CHANGE_SECTION_ADDRESS}, | |
1776 | {"change-section-lma", required_argument, 0, OPTION_CHANGE_SECTION_LMA}, | |
1777 | {"change-section-vma", required_argument, 0, OPTION_CHANGE_SECTION_VMA}, | |
1778 | @@ -504,6 +509,8 @@ | |
1779 | --prefix-alloc-sections <prefix>\n\ | |
1780 | Add <prefix> to start of every allocatable\n\ | |
1781 | section name\n\ | |
1782 | + --change-pathname <old>=<new> Change debug pathnames from <old> to <new>\n\ | |
1783 | + --basename Strip directory part from debug pathnames\n\ | |
1784 | -v --verbose List all object files modified\n\ | |
1785 | @<file> Read options from <file>\n\ | |
1786 | -V --version Display this program's version number\n\ | |
1787 | @@ -911,6 +918,8 @@ | |
1788 | asymbol **from = isyms, **to = osyms; | |
1789 | long src_count = 0, dst_count = 0; | |
1790 | int relocatable = (abfd->flags & (EXEC_P | DYNAMIC)) == 0; | |
1791 | + bfd_boolean need_for_debugging = convert_debugging | |
1792 | + && bfd_get_arch (abfd) == bfd_arch_avr; | |
1793 | ||
1794 | for (; src_count < symcount; src_count++) | |
1795 | { | |
1796 | @@ -1010,9 +1019,10 @@ | |
1797 | || bfd_is_com_section (bfd_get_section (sym))) | |
1798 | keep = strip_symbols != STRIP_UNNEEDED; | |
1799 | else if ((flags & BSF_DEBUGGING) != 0) /* Debugging symbol. */ | |
1800 | - keep = (strip_symbols != STRIP_DEBUG | |
1801 | - && strip_symbols != STRIP_UNNEEDED | |
1802 | - && ! convert_debugging); | |
1803 | + keep = need_for_debugging | |
1804 | + || (strip_symbols != STRIP_DEBUG | |
1805 | + && strip_symbols != STRIP_UNNEEDED | |
1806 | + && ! convert_debugging); | |
1807 | else if (bfd_coff_get_comdat_section (abfd, bfd_get_section (sym))) | |
1808 | /* COMDAT sections store special information in local | |
1809 | symbols, so we cannot risk stripping any of them. */ | |
1810 | @@ -2579,6 +2589,10 @@ | |
1811 | return write_ieee_debugging_info (obfd, dhandle); | |
1812 | ||
1813 | if (bfd_get_flavour (obfd) == bfd_target_coff_flavour | |
1814 | + && bfd_get_arch (obfd) == bfd_arch_avr) | |
1815 | + return write_coff_debugging_info (obfd, dhandle, symcountp, symppp); | |
4cd5ba0f | 1816 | + |
f33182aa | 1817 | + if (bfd_get_flavour (obfd) == bfd_target_coff_flavour |
1818 | || bfd_get_flavour (obfd) == bfd_target_elf_flavour) | |
1819 | { | |
1820 | bfd_byte *syms, *strings; | |
1821 | @@ -3280,6 +3294,30 @@ | |
1822 | prefix_alloc_sections_string = optarg; | |
1823 | break; | |
1824 | ||
1825 | + case OPTION_CHANGE_PATHNAME: | |
4cd5ba0f | 1826 | + { |
f33182aa | 1827 | + const char *s; |
1828 | + int len; | |
1829 | + char *name; | |
4cd5ba0f | 1830 | + |
f33182aa | 1831 | + s = strchr (optarg, '='); |
1832 | + if (s == NULL) | |
1833 | + fatal (_("bad format for %s"), "--change-pathname"); | |
4cd5ba0f | 1834 | + |
f33182aa | 1835 | + len = s - optarg; |
1836 | + name = (char *) xmalloc (len + 1); | |
1837 | + strncpy (name, optarg, len); | |
1838 | + name[len] = '\0'; | |
4cd5ba0f | 1839 | + |
f33182aa | 1840 | + debug_register_pathname_xlat (name, s + 1); |
1841 | + } | |
1842 | + break; | |
4cd5ba0f | 1843 | + |
f33182aa | 1844 | + case OPTION_BASENAME: |
1845 | + /* very special case of pathname translation */ | |
1846 | + debug_register_pathname_xlat (NULL, NULL); | |
1847 | + break; | |
4cd5ba0f | 1848 | + |
f33182aa | 1849 | case OPTION_READONLY_TEXT: |
1850 | bfd_flags_to_set |= WP_TEXT; | |
1851 | bfd_flags_to_clear &= ~WP_TEXT; | |
1852 | diff -uNdr binutils-2.17.50.0.18-old/binutils/rdcoff.c binutils-2.17.50.0.18/binutils/rdcoff.c | |
1853 | --- binutils-2.17.50.0.18-old/binutils/rdcoff.c 2007-08-01 15:11:49.000000000 +0200 | |
1854 | +++ binutils-2.17.50.0.18/binutils/rdcoff.c 2007-10-20 16:45:33.000000000 +0200 | |
1855 | @@ -82,6 +82,9 @@ | |
1856 | struct coff_slots *slots; | |
1857 | /* Basic types. */ | |
1858 | debug_type basic[T_MAX + 1]; | |
1859 | + /* Some general information, kept here for convenience. */ | |
1860 | + size_t intsize; /* sizeof (int) */ | |
1861 | + size_t doublesize; /* sizeof (double) */ | |
1862 | }; | |
1863 | ||
1864 | static debug_type *coff_get_slot (struct coff_types *, int); | |
1865 | @@ -101,6 +104,7 @@ | |
1866 | (bfd *, struct coff_types *, asymbol *, long, struct internal_syment *, | |
1867 | void *, debug_type, bfd_boolean); | |
1868 | static bfd_boolean external_coff_symbol_p (int sym_class); | |
1869 | +static bfd_vma coff_convert_register (bfd *, bfd_vma); | |
1870 | \f | |
1871 | /* Return the slot for a type. */ | |
1872 | ||
1873 | @@ -271,8 +275,7 @@ | |
1874 | break; | |
1875 | ||
1876 | case T_INT: | |
1877 | - /* FIXME: Perhaps the size should depend upon the architecture. */ | |
1878 | - ret = debug_make_int_type (dhandle, 4, FALSE); | |
1879 | + ret = debug_make_int_type (dhandle, types->intsize, FALSE); | |
1880 | name = "int"; | |
1881 | break; | |
1882 | ||
1883 | @@ -287,7 +290,7 @@ | |
1884 | break; | |
1885 | ||
1886 | case T_DOUBLE: | |
1887 | - ret = debug_make_float_type (dhandle, 8); | |
1888 | + ret = debug_make_float_type (dhandle, types->doublesize); | |
1889 | name = "double"; | |
1890 | break; | |
1891 | ||
1892 | @@ -307,7 +310,7 @@ | |
1893 | break; | |
1894 | ||
1895 | case T_UINT: | |
1896 | - ret = debug_make_int_type (dhandle, 4, TRUE); | |
1897 | + ret = debug_make_int_type (dhandle, types->intsize, TRUE); | |
1898 | name = "unsigned int"; | |
1899 | break; | |
1900 | ||
1901 | @@ -565,6 +568,8 @@ | |
1902 | ||
1903 | case C_WEAKEXT: | |
1904 | case C_EXT: | |
1905 | + /* AVR COFF abuses C_EXTDEF */ | |
1906 | + case C_EXTDEF: | |
1907 | if (! debug_record_variable (dhandle, bfd_asymbol_name (sym), type, | |
1908 | DEBUG_GLOBAL, bfd_asymbol_value (sym))) | |
1909 | return FALSE; | |
1910 | @@ -580,9 +585,9 @@ | |
1911 | break; | |
1912 | ||
1913 | case C_REG: | |
1914 | - /* FIXME: We may need to convert the register number. */ | |
1915 | if (! debug_record_variable (dhandle, bfd_asymbol_name (sym), type, | |
1916 | - DEBUG_REGISTER, bfd_asymbol_value (sym))) | |
1917 | + DEBUG_REGISTER, | |
1918 | + coff_convert_register (abfd, bfd_asymbol_value (sym)))) | |
1919 | return FALSE; | |
1920 | break; | |
1921 | ||
1922 | @@ -596,9 +601,9 @@ | |
1923 | break; | |
1924 | ||
1925 | case C_REGPARM: | |
1926 | - /* FIXME: We may need to convert the register number. */ | |
1927 | if (! debug_record_parameter (dhandle, bfd_asymbol_name (sym), type, | |
1928 | - DEBUG_PARM_REG, bfd_asymbol_value (sym))) | |
1929 | + DEBUG_PARM_REG, | |
1930 | + coff_convert_register (abfd, bfd_asymbol_value (sym)))) | |
1931 | return FALSE; | |
1932 | break; | |
1933 | ||
1934 | @@ -648,6 +653,28 @@ | |
1935 | return FALSE; | |
1936 | } | |
1937 | ||
1938 | +static bfd_vma | |
1939 | +coff_convert_register (abfd, val) | |
1940 | + bfd *abfd; | |
1941 | + bfd_vma val; | |
1942 | +{ | |
4cd5ba0f | 1943 | + |
f33182aa | 1944 | + switch (bfd_get_arch (abfd)) |
4cd5ba0f | 1945 | + { |
f33182aa | 1946 | + case bfd_arch_avr: |
1947 | + /* AVR COFF wants to describe up to four registers by the four | |
1948 | + bytes of the 32-bit value. Unused bytes are filled with | |
1949 | + 0xff. In theory, this would allow for non-contiguous | |
1950 | + register usage to hold a single value, but hopefully, no | |
1951 | + compiler is going to use that feature. We could not handle | |
1952 | + it anyway. */ | |
1953 | + return val & 0xff; | |
4cd5ba0f | 1954 | + |
f33182aa | 1955 | + default: |
1956 | + return val; | |
1957 | + } | |
4cd5ba0f ER |
1958 | +} |
1959 | + | |
f33182aa | 1960 | /* This is the main routine. It looks through all the symbols and |
1961 | handles them. */ | |
1962 | ||
1963 | @@ -674,6 +701,17 @@ | |
1964 | types.slots = NULL; | |
1965 | for (i = 0; i <= T_MAX; i++) | |
1966 | types.basic[i] = DEBUG_TYPE_NULL; | |
1967 | + switch (bfd_get_arch (abfd)) | |
1968 | + { | |
1969 | + case bfd_arch_avr: | |
1970 | + types.intsize = 2; | |
1971 | + types.doublesize = 4; | |
1972 | + break; | |
4cd5ba0f | 1973 | + |
f33182aa | 1974 | + default: |
1975 | + types.intsize = 4; | |
1976 | + types.doublesize = 8; | |
1977 | + } | |
1978 | ||
1979 | next_c_file = -1; | |
1980 | fnname = NULL; | |
1981 | @@ -734,7 +772,6 @@ | |
1982 | switch (syment.n_sclass) | |
1983 | { | |
1984 | case C_EFCN: | |
1985 | - case C_EXTDEF: | |
1986 | case C_ULABEL: | |
1987 | case C_USTATIC: | |
1988 | case C_LINE: | |
1989 | @@ -757,6 +794,8 @@ | |
1990 | /* Fall through. */ | |
1991 | case C_WEAKEXT: | |
1992 | case C_EXT: | |
1993 | + /* AVR COFF abuses C_EXTDEF for C_EXT */ | |
1994 | + case C_EXTDEF: | |
1995 | if (ISFCN (syment.n_type)) | |
1996 | { | |
1997 | fnname = name; | |
1998 | diff -uNdr binutils-2.17.50.0.18-old/binutils/wrcoff.c binutils-2.17.50.0.18/binutils/wrcoff.c | |
1999 | --- binutils-2.17.50.0.18-old/binutils/wrcoff.c 1970-01-01 01:00:00.000000000 +0100 | |
2000 | +++ binutils-2.17.50.0.18/binutils/wrcoff.c 2007-10-20 16:45:53.000000000 +0200 | |
2001 | @@ -0,0 +1,3408 @@ | |
2002 | +/* wrcoff.c -- Generate (AVR) COFF debugging information | |
2003 | + Copyright 2003 Free Software Foundation, Inc. | |
4cd5ba0f | 2004 | + |
f33182aa | 2005 | + Written by Joerg Wunsch. |
4cd5ba0f | 2006 | + |
f33182aa | 2007 | + This file is part of GNU Binutils. |
4cd5ba0f | 2008 | + |
f33182aa | 2009 | + This program is free software; you can redistribute it and/or modify |
2010 | + it under the terms of the GNU General Public License as published by | |
2011 | + the Free Software Foundation; either version 2 of the License, or | |
2012 | + (at your option) any later version. | |
4cd5ba0f | 2013 | + |
f33182aa | 2014 | + This program is distributed in the hope that it will be useful, |
2015 | + but WITHOUT ANY WARRANTY; without even the implied warranty of | |
2016 | + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
2017 | + GNU General Public License for more details. | |
4cd5ba0f | 2018 | + |
f33182aa | 2019 | + You should have received a copy of the GNU General Public License |
2020 | + along with this program; if not, write to the Free Software | |
2021 | + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA | |
2022 | + 02111-1307, USA. */ | |
4cd5ba0f | 2023 | + |
f33182aa | 2024 | +/* This file contains code which writes out COFF debugging |
2025 | + information. By now, this has only been tested on the AVR | |
2026 | + platform, though any attempt has been made to keep the conversion | |
2027 | + applicable to possible other COFF debugging consumers as well. */ | |
4cd5ba0f | 2028 | + |
f33182aa | 2029 | +#include <assert.h> |
2030 | +#include "sysdep.h" | |
2031 | +#include "bfd.h" | |
2032 | +#include "coff/internal.h" | |
2033 | +#include "bucomm.h" | |
2034 | +#include "libiberty.h" | |
2035 | +#include "safe-ctype.h" | |
2036 | +#include "debug.h" | |
2037 | +#include "budbg.h" | |
4cd5ba0f | 2038 | + |
f33182aa | 2039 | +/* Enabling COFF_DEBUG will trace the internal callback functions and |
2040 | + their parameters as debug_write() calls them. */ | |
2041 | +//#define COFF_DEBUG 1 | |
4cd5ba0f | 2042 | + |
f33182aa | 2043 | +#include "libcoff.h" |
4cd5ba0f | 2044 | + |
f33182aa | 2045 | +#define N_TMASK (coff_data (info->abfd)->local_n_tmask) |
2046 | +#define N_BTSHFT (coff_data (info->abfd)->local_n_btshft) | |
2047 | +#define N_BTMASK (coff_data (info->abfd)->local_n_btmask) | |
2048 | +#define N_TSHIFT (coff_data (info->abfd)->local_n_tshift) | |
4cd5ba0f | 2049 | + |
f33182aa | 2050 | +/* Structure of local symbols per compilation unit. */ |
2051 | +struct coff_compilation_unit | |
4cd5ba0f | 2052 | +{ |
f33182aa | 2053 | + const char *fname; |
2054 | + asymbol **syms; | |
2055 | + long nsyms, totsyms; | |
2056 | +}; | |
4cd5ba0f | 2057 | + |
f33182aa | 2058 | +enum ts_kind |
2059 | +{ | |
2060 | + TS_EMPTY, | |
2061 | + TS_VOID, | |
2062 | + TS_INT, | |
2063 | + TS_FLOAT, | |
2064 | + TS_COMPLEX, | |
2065 | + TS_ENUM, | |
2066 | + TS_POINTER, | |
2067 | + TS_FUNC, | |
2068 | + TS_ARRAY, | |
2069 | + TS_STRUCT, | |
2070 | + TS_NONE = -1 | |
2071 | +}; | |
4cd5ba0f | 2072 | + |
f33182aa | 2073 | +/* Structure defining the pre-defined types. */ |
2074 | +struct coff_predef_type | |
2075 | +{ | |
2076 | + enum ts_kind kind; | |
2077 | + unsigned int size; /* in bytes */ | |
2078 | + bfd_boolean isunsigned; | |
2079 | + int slot; | |
2080 | +}; | |
4cd5ba0f | 2081 | + |
f33182aa | 2082 | +struct coff_type_stack; |
2083 | +struct coff_hash_entry; | |
4cd5ba0f | 2084 | + |
f33182aa | 2085 | +struct coff_struct_fields |
4cd5ba0f | 2086 | +{ |
f33182aa | 2087 | + const char *name; |
2088 | + bfd_vma bitpos; | |
2089 | + bfd_vma bitsize; | |
2090 | + enum debug_visibility visibility; | |
2091 | + struct coff_type_stack *types; | |
2092 | +}; | |
4cd5ba0f | 2093 | + |
f33182aa | 2094 | +/* Our type stack. */ |
2095 | +struct coff_type_stack | |
2096 | +{ | |
2097 | + struct coff_type_stack *next; | |
2098 | + enum ts_kind tsk; | |
2099 | + union | |
2100 | + { | |
2101 | + /* TS_INT */ | |
2102 | + struct | |
2103 | + { | |
2104 | + unsigned int size; | |
2105 | + bfd_boolean isunsigned; | |
2106 | + } | |
2107 | + ts_int; | |
4cd5ba0f | 2108 | + |
f33182aa | 2109 | + /* TS_FLOAT */ |
2110 | + struct | |
2111 | + { | |
2112 | + unsigned int size; | |
2113 | + } | |
2114 | + ts_float; | |
4cd5ba0f | 2115 | + |
f33182aa | 2116 | + /* TS_ENUM */ |
2117 | + struct | |
4cd5ba0f | 2118 | + { |
f33182aa | 2119 | + union |
4cd5ba0f | 2120 | + { |
f33182aa | 2121 | + const char *fixtag; |
2122 | + char *malloctag; | |
4cd5ba0f | 2123 | + } |
f33182aa | 2124 | + tag; |
2125 | + bfd_boolean tagismalloced; | |
2126 | + const char **names; | |
2127 | + bfd_signed_vma *vals; | |
2128 | + struct coff_enum_hash_entry *ehash; | |
2129 | + } | |
2130 | + ts_enum; | |
4cd5ba0f | 2131 | + |
f33182aa | 2132 | + /* TS_FUNC */ |
2133 | + struct | |
4cd5ba0f | 2134 | + { |
f33182aa | 2135 | + struct coff_type_stack *savedts; |
4cd5ba0f | 2136 | + } |
f33182aa | 2137 | + ts_func; |
4cd5ba0f | 2138 | + |
f33182aa | 2139 | + /* TS_ARRAY */ |
2140 | + struct | |
4cd5ba0f | 2141 | + { |
f33182aa | 2142 | + bfd_signed_vma low; |
2143 | + bfd_signed_vma high; | |
4cd5ba0f | 2144 | + } |
f33182aa | 2145 | + ts_array; |
4cd5ba0f | 2146 | + |
f33182aa | 2147 | + /* TS_STRUCT */ |
2148 | + struct | |
4cd5ba0f | 2149 | + { |
f33182aa | 2150 | + union |
2151 | + { | |
2152 | + const char *fixtag; | |
2153 | + char *malloctag; | |
2154 | + } | |
2155 | + tag; | |
2156 | + bfd_boolean tagismalloced; | |
2157 | + unsigned int id; | |
2158 | + bfd_boolean isstruct; | |
2159 | + unsigned int size; | |
2160 | + long nfields; | |
2161 | + struct coff_struct_fields *fields; | |
2162 | + struct coff_type_stack *savedts; | |
2163 | + struct coff_struct_hash_entry *shash; | |
4cd5ba0f | 2164 | + } |
f33182aa | 2165 | + ts_struct; |
2166 | + } | |
2167 | + u; | |
2168 | +}; | |
4cd5ba0f | 2169 | + |
f33182aa | 2170 | +struct coff_name_type_hash_table |
2171 | +{ | |
2172 | + struct bfd_hash_table root; | |
2173 | +}; | |
4cd5ba0f | 2174 | + |
f33182aa | 2175 | +struct coff_name_type_hash_entry |
2176 | +{ | |
2177 | + struct bfd_hash_entry root; | |
2178 | + /* Information for this name. */ | |
2179 | + struct coff_type_stack *types; | |
2180 | + bfd_boolean emitted; | |
2181 | +}; | |
4cd5ba0f | 2182 | + |
f33182aa | 2183 | +struct coff_struct_hash_table |
2184 | +{ | |
2185 | + struct bfd_hash_table root; | |
2186 | +}; | |
4cd5ba0f | 2187 | + |
f33182aa | 2188 | +struct coff_struct_hash_entry |
2189 | +{ | |
2190 | + struct bfd_hash_entry root; | |
2191 | + /* Information for this name. */ | |
2192 | + struct coff_type_stack *types; | |
2193 | + bfd_boolean emitted; | |
2194 | + combined_entry_type *native; | |
2195 | + /* list of symbol indices that need fixing */ | |
2196 | + long *fixidxs; | |
2197 | + unsigned nfixidxs; | |
2198 | +}; | |
4cd5ba0f | 2199 | + |
f33182aa | 2200 | +struct coff_enum_hash_table |
2201 | +{ | |
2202 | + struct bfd_hash_table root; | |
2203 | +}; | |
4cd5ba0f | 2204 | + |
f33182aa | 2205 | +struct coff_enum_hash_entry |
4cd5ba0f | 2206 | +{ |
f33182aa | 2207 | + struct bfd_hash_entry root; |
2208 | + /* Information for this name. */ | |
2209 | + struct coff_type_stack *types; | |
2210 | + bfd_boolean emitted; | |
2211 | + combined_entry_type *native; | |
2212 | + /* list of symbol indices that need fixing */ | |
2213 | + long *fixidxs; | |
2214 | + unsigned nfixidxs; | |
2215 | +}; | |
4cd5ba0f | 2216 | + |
f33182aa | 2217 | +/* COFF private symbol data. Used as a cookie to pass data around |
2218 | + between various processing stages. The generic COFF handling code | |
2219 | + doesn't use any private data. */ | |
2220 | +struct coff_private_symdata | |
2221 | +{ | |
2222 | + unsigned int size; /* size of symbol, used in AVR register | |
2223 | + translation */ | |
2224 | + struct coff_struct_hash_entry *shash; /* TS_STRUCT hash for fixups */ | |
2225 | + struct coff_enum_hash_entry *ehash; /* TS_ENUM hash for fixups */ | |
2226 | +}; | |
4cd5ba0f | 2227 | + |
f33182aa | 2228 | +/* Stack of tags that need endndx fixing. */ |
2229 | +struct coff_fix_stack | |
2230 | +{ | |
2231 | + struct coff_fix_stack *next; | |
2232 | + combined_entry_type *native; | |
2233 | +}; | |
4cd5ba0f | 2234 | + |
f33182aa | 2235 | +/* This is the handle passed through debug_write. */ |
4cd5ba0f | 2236 | + |
f33182aa | 2237 | +struct coff_write_handle |
4cd5ba0f | 2238 | +{ |
f33182aa | 2239 | + /* The BFD. */ |
2240 | + bfd *abfd; | |
2241 | + /* Pointers to .text and .data sections, can be used as defaults if | |
2242 | + no other information is available. */ | |
2243 | + asection *textsect; | |
2244 | + asection *datasect; | |
2245 | + /* Some special flags. */ | |
2246 | + unsigned long flags; | |
2247 | + /* Flags describing architecture options. */ | |
2248 | +#define COFF_FL_AVR 0x0001 /* COFF is for AVR platform. */ | |
2249 | +#define COFF_FL_EXT_AVR 0x0002 /* AVR "extended" COFF */ | |
2250 | + /* Flags describing internal status information. */ | |
2251 | +#define COFF_FL_FIX_ENDNDX 0x10000 /* apply endndx fix at next symbol */ | |
2252 | +#define COFF_FL_START_FCN 0x20000 /* begin of function pending */ | |
2253 | +#define COFF_FL_FIX_BB 0x40000 /* fix last ".bb" symbol */ | |
2254 | + /* List of our compilation units, from input symbol table. */ | |
2255 | + struct coff_compilation_unit *units; | |
2256 | + long nunits; | |
2257 | + struct coff_compilation_unit *currentfile; | |
2258 | + /* Global symbols from input symbol table. */ | |
2259 | + asymbol **globals; | |
2260 | + long nglobals; | |
2261 | + /* Section syms for named sections. */ | |
2262 | + coff_symbol_type **secsyms; | |
2263 | + long nsecsyms; | |
2264 | + /* Our COFF symbols. */ | |
2265 | + asymbol **syms; | |
2266 | + long nsyms; | |
2267 | + /* Total line number count. */ | |
2268 | + unsigned long totlnos; | |
2269 | + /* Size of standard objects on this arch. */ | |
2270 | + unsigned int pointersize; | |
2271 | + unsigned int enumsize; | |
2272 | + /* Pending information when starting a function. We have to defer | |
2273 | + almost everything, some actions can be taken when seeing the | |
2274 | + starting block of that function, some will even have to wait | |
2275 | + until we see the end of the function. */ | |
2276 | + const char *funname; /* name of function */ | |
2277 | + bfd_boolean funglobal; /* global/local function? */ | |
2278 | + unsigned int lastlno; /* last line number seen so far */ | |
2279 | + long funcindex; /* index of ".func" symbol in syms */ | |
2280 | + unsigned int nlnos; /* line numbers recorded for this function*/ | |
2281 | + bfd_vma endaddr; /* last .eb address we have seen so far */ | |
2282 | + unsigned int funlno; /* first line number in function */ | |
2283 | + coff_symbol_type **fargs; /* function arguments */ | |
2284 | + unsigned int nfargs; | |
2285 | + asection *funcsection; /* section the current function is using */ | |
2286 | + /* Type information */ | |
2287 | + struct coff_type_stack *tstack; | |
2288 | + struct coff_name_type_hash_table types; | |
2289 | + struct coff_struct_hash_table structs; | |
2290 | + struct coff_enum_hash_table enums; | |
2291 | + unsigned nenums; /* counter for anonymous enum tags */ | |
2292 | + /* Stack of pending endndx fixes, see coff_record_symbol(). */ | |
2293 | + struct coff_fix_stack *fixes; | |
2294 | +}; | |
4cd5ba0f | 2295 | + |
f33182aa | 2296 | +/* Predefined types, default to usual 32-bit architectures. |
2297 | + Arch-dependant different byte sizes will be tuned upon entering | |
2298 | + write_coff_debugging_info(). The table is looked up from front to | |
2299 | + end, so we put `more popular' types that might have the same size | |
2300 | + as other types first (e. g. "int" precedes "long" and "short"). */ | |
2301 | +static struct coff_predef_type coff_predef_types[] = | |
4cd5ba0f | 2302 | +{ |
f33182aa | 2303 | + { TS_INT, 4, FALSE, 4 }, /* signed int */ |
2304 | + { TS_INT, 1, FALSE, 2 }, /* signed char */ | |
2305 | + { TS_INT, 2, FALSE, 3 }, /* signed short */ | |
2306 | + { TS_INT, 4, FALSE, 5 }, /* long int */ | |
2307 | + { TS_FLOAT, 8, FALSE, 7 }, /* double */ | |
2308 | + { TS_FLOAT, 4, FALSE, 6 }, /* float */ | |
2309 | + { TS_INT, 4, TRUE, 14 }, /* unsigned int */ | |
2310 | + { TS_INT, 1, TRUE, 12 }, /* unsigned char */ | |
2311 | + { TS_INT, 2, TRUE, 13 }, /* unsigned short */ | |
2312 | + { TS_INT, 4, TRUE, 15 }, /* unsigned long */ | |
2313 | +}; | |
4cd5ba0f | 2314 | + |
f33182aa | 2315 | +static bfd_boolean coff_copy_symbols |
2316 | + PARAMS ((struct coff_write_handle *, long, asymbol **)); | |
2317 | +static asymbol *coff_find_symbol | |
2318 | + PARAMS ((struct coff_write_handle *, const char *, bfd_boolean, bfd_boolean)); | |
2319 | +static void coff_record_symbol | |
2320 | + PARAMS ((struct coff_write_handle *, coff_symbol_type *)); | |
2321 | +static symvalue coff_fixup_avr_register PARAMS ((symvalue, int)); | |
2322 | +static struct bfd_hash_entry *coff_name_type_newfunc | |
2323 | + PARAMS ((struct bfd_hash_entry *, struct bfd_hash_table *, const char *)); | |
2324 | +static bfd_boolean coff_free_type_info | |
2325 | + PARAMS ((struct coff_name_type_hash_entry *, PTR)); | |
2326 | +static struct bfd_hash_entry *coff_struct_newfunc | |
2327 | + PARAMS ((struct bfd_hash_entry *, struct bfd_hash_table *, const char *)); | |
2328 | +static bfd_boolean coff_free_struct_info | |
2329 | + PARAMS ((struct coff_struct_hash_entry *, PTR)); | |
2330 | +static struct bfd_hash_entry *coff_enum_newfunc | |
2331 | + PARAMS ((struct bfd_hash_entry *, struct bfd_hash_table *, const char *)); | |
2332 | +static bfd_boolean coff_free_enum_info | |
2333 | + PARAMS ((struct coff_enum_hash_entry *, PTR)); | |
2334 | +static unsigned int coff_get_fundamental_type | |
2335 | + PARAMS ((struct coff_write_handle *, struct coff_type_stack *)); | |
2336 | +static bfd_boolean coff_make_typed_symbol | |
2337 | + PARAMS ((struct coff_write_handle *, coff_symbol_type **, enum ts_kind)); | |
2338 | +static bfd_boolean coff_emit_struct | |
2339 | + PARAMS ((struct coff_write_handle *, struct coff_type_stack *, | |
2340 | + struct coff_struct_hash_entry *)); | |
2341 | +static bfd_boolean coff_emit_enum | |
2342 | + PARAMS ((struct coff_write_handle *, struct coff_type_stack *, | |
2343 | + struct coff_enum_hash_entry *)); | |
2344 | +static bfd_boolean coff_emit_ndebug_sym | |
2345 | + PARAMS ((struct coff_write_handle *, asymbol *, bfd_boolean)); | |
4cd5ba0f | 2346 | + |
f33182aa | 2347 | +static bfd_boolean coff_start_compilation_unit PARAMS ((PTR, const char *)); |
2348 | +static bfd_boolean coff_start_source PARAMS ((PTR, const char *)); | |
2349 | +static bfd_boolean coff_empty_type PARAMS ((PTR)); | |
2350 | +static bfd_boolean coff_void_type PARAMS ((PTR)); | |
2351 | +static bfd_boolean coff_int_type PARAMS ((PTR, unsigned int, bfd_boolean)); | |
2352 | +static bfd_boolean coff_float_type PARAMS ((PTR, unsigned int)); | |
2353 | +static bfd_boolean coff_complex_type PARAMS ((PTR, unsigned int)); | |
2354 | +static bfd_boolean coff_bool_type PARAMS ((PTR, unsigned int)); | |
2355 | +static bfd_boolean coff_enum_type | |
2356 | + PARAMS ((PTR, const char *, const char **, bfd_signed_vma *)); | |
2357 | +static bfd_boolean coff_pointer_type PARAMS ((PTR)); | |
2358 | +static bfd_boolean coff_function_type PARAMS ((PTR, int, bfd_boolean)); | |
2359 | +static bfd_boolean coff_reference_type PARAMS ((PTR)); | |
2360 | +static bfd_boolean coff_range_type PARAMS ((PTR, bfd_signed_vma, bfd_signed_vma)); | |
2361 | +static bfd_boolean coff_array_type | |
2362 | + PARAMS ((PTR, bfd_signed_vma, bfd_signed_vma, bfd_boolean)); | |
2363 | +static bfd_boolean coff_set_type PARAMS ((PTR, bfd_boolean)); | |
2364 | +static bfd_boolean coff_offset_type PARAMS ((PTR)); | |
2365 | +static bfd_boolean coff_method_type PARAMS ((PTR, bfd_boolean, int, bfd_boolean)); | |
2366 | +static bfd_boolean coff_const_type PARAMS ((PTR)); | |
2367 | +static bfd_boolean coff_volatile_type PARAMS ((PTR)); | |
2368 | +static bfd_boolean coff_start_struct_type | |
2369 | + PARAMS ((PTR, const char *, unsigned int, bfd_boolean, unsigned int)); | |
2370 | +static bfd_boolean coff_struct_field | |
2371 | + PARAMS ((PTR, const char *, bfd_vma, bfd_vma, enum debug_visibility)); | |
2372 | +static bfd_boolean coff_end_struct_type PARAMS ((PTR)); | |
2373 | +static bfd_boolean coff_start_class_type | |
2374 | + PARAMS ((PTR, const char *, unsigned int, bfd_boolean, unsigned int, bfd_boolean, | |
2375 | + bfd_boolean)); | |
2376 | +static bfd_boolean coff_class_static_member | |
2377 | + PARAMS ((PTR, const char *, const char *, enum debug_visibility)); | |
2378 | +static bfd_boolean coff_class_baseclass | |
2379 | + PARAMS ((PTR, bfd_vma, bfd_boolean, enum debug_visibility)); | |
2380 | +static bfd_boolean coff_class_start_method PARAMS ((PTR, const char *)); | |
2381 | +static bfd_boolean coff_class_method_variant | |
2382 | + PARAMS ((PTR, const char *, enum debug_visibility, bfd_boolean, bfd_boolean, | |
2383 | + bfd_vma, bfd_boolean)); | |
2384 | +static bfd_boolean coff_class_static_method_variant | |
2385 | + PARAMS ((PTR, const char *, enum debug_visibility, bfd_boolean, bfd_boolean)); | |
2386 | +static bfd_boolean coff_class_end_method PARAMS ((PTR)); | |
2387 | +static bfd_boolean coff_end_class_type PARAMS ((PTR)); | |
2388 | +static bfd_boolean coff_typedef_type PARAMS ((PTR, const char *)); | |
2389 | +static bfd_boolean coff_tag_type | |
2390 | + PARAMS ((PTR, const char *, unsigned int, enum debug_type_kind)); | |
2391 | +static bfd_boolean coff_typdef PARAMS ((PTR, const char *)); | |
2392 | +static bfd_boolean coff_tag PARAMS ((PTR, const char *)); | |
2393 | +static bfd_boolean coff_int_constant PARAMS ((PTR, const char *, bfd_vma)); | |
2394 | +static bfd_boolean coff_float_constant PARAMS ((PTR, const char *, double)); | |
2395 | +static bfd_boolean coff_typed_constant PARAMS ((PTR, const char *, bfd_vma)); | |
2396 | +static bfd_boolean coff_variable | |
2397 | + PARAMS ((PTR, const char *, enum debug_var_kind, bfd_vma)); | |
2398 | +static bfd_boolean coff_start_function PARAMS ((PTR, const char *, bfd_boolean)); | |
2399 | +static bfd_boolean coff_function_parameter | |
2400 | + PARAMS ((PTR, const char *, enum debug_parm_kind, bfd_vma)); | |
2401 | +static bfd_boolean coff_start_block PARAMS ((PTR, bfd_vma)); | |
2402 | +static bfd_boolean coff_end_block PARAMS ((PTR, bfd_vma)); | |
2403 | +static bfd_boolean coff_end_function PARAMS ((PTR)); | |
2404 | +static bfd_boolean coff_lineno | |
2405 | + PARAMS ((PTR, const char *, unsigned long, bfd_vma)); | |
4cd5ba0f | 2406 | + |
f33182aa | 2407 | +static const struct debug_write_fns coff_fns = |
4cd5ba0f | 2408 | +{ |
f33182aa | 2409 | + coff_start_compilation_unit, |
2410 | + coff_start_source, | |
2411 | + coff_empty_type, | |
2412 | + coff_void_type, | |
2413 | + coff_int_type, | |
2414 | + coff_float_type, | |
2415 | + coff_complex_type, | |
2416 | + coff_bool_type, | |
2417 | + coff_enum_type, | |
2418 | + coff_pointer_type, | |
2419 | + coff_function_type, | |
2420 | + coff_reference_type, | |
2421 | + coff_range_type, | |
2422 | + coff_array_type, | |
2423 | + coff_set_type, | |
2424 | + coff_offset_type, | |
2425 | + coff_method_type, | |
2426 | + coff_const_type, | |
2427 | + coff_volatile_type, | |
2428 | + coff_start_struct_type, | |
2429 | + coff_struct_field, | |
2430 | + coff_end_struct_type, | |
2431 | + coff_start_class_type, | |
2432 | + coff_class_static_member, | |
2433 | + coff_class_baseclass, | |
2434 | + coff_class_start_method, | |
2435 | + coff_class_method_variant, | |
2436 | + coff_class_static_method_variant, | |
2437 | + coff_class_end_method, | |
2438 | + coff_end_class_type, | |
2439 | + coff_typedef_type, | |
2440 | + coff_tag_type, | |
2441 | + coff_typdef, | |
2442 | + coff_tag, | |
2443 | + coff_int_constant, | |
2444 | + coff_float_constant, | |
2445 | + coff_typed_constant, | |
2446 | + coff_variable, | |
2447 | + coff_start_function, | |
2448 | + coff_function_parameter, | |
2449 | + coff_start_block, | |
2450 | + coff_end_block, | |
2451 | + coff_end_function, | |
2452 | + coff_lineno | |
2453 | +}; | |
2454 | +\f | |
2455 | +/* | |
2456 | + * Copy our input (non-debugging) symbols. Local symbols will be | |
2457 | + * maintained in one bucket per each compilation unit, global (and | |
2458 | + * weak) symbols will be kept in a simple array. | |
2459 | + */ | |
4cd5ba0f | 2460 | +static bfd_boolean |
f33182aa | 2461 | +coff_copy_symbols (info, count, sympp) |
2462 | + struct coff_write_handle *info; | |
2463 | + long count; | |
2464 | + asymbol **sympp; | |
4cd5ba0f | 2465 | +{ |
f33182aa | 2466 | + asymbol *osym; |
2467 | + long i; | |
2468 | + struct coff_compilation_unit *up; | |
4cd5ba0f | 2469 | + |
f33182aa | 2470 | + up = NULL; |
4cd5ba0f | 2471 | + |
f33182aa | 2472 | + for (i = 0; i < count; i++) |
2473 | + { | |
2474 | + osym = sympp[i]; | |
4cd5ba0f | 2475 | + |
f33182aa | 2476 | + /* Try to figure out the .text and .data sections from our input |
2477 | + symbols as we walk them. Unfortunately, this ought to be the | |
2478 | + /input/ section pointers, so their ->output_section is | |
2479 | + non-NULL. That's why we can't simply walk through all the | |
2480 | + sections of our abfd since this is describing the output | |
2481 | + only. */ | |
2482 | + if (info->textsect == NULL && osym->section->flags & SEC_CODE) | |
2483 | + /* Assume this to be our .text section. */ | |
2484 | + info->textsect = osym->section; | |
2485 | + else if (info->datasect == NULL && osym->section->flags & SEC_DATA) | |
2486 | + /* Assume this to be our .data section. */ | |
2487 | + info->datasect = osym->section; | |
4cd5ba0f | 2488 | + |
f33182aa | 2489 | + if (osym->flags & BSF_FILE) |
2490 | + { | |
2491 | + /* New file name. */ | |
2492 | + long l; | |
4cd5ba0f | 2493 | + |
f33182aa | 2494 | + up = NULL; |
4cd5ba0f | 2495 | + |
f33182aa | 2496 | + /* Well, maybe an old one actually? If so, append it there. |
2497 | + This can happen for files that contribute to multiple | |
2498 | + (input) sections that were concatenated by the linker | |
2499 | + (like crt1.S). */ | |
2500 | + for (l = 0; l < info->nunits; l++) | |
2501 | + { | |
2502 | + if (strcmp (info->units[l].fname, osym->name) == 0) | |
2503 | + { | |
2504 | + up = info->units + l; | |
2505 | + break; | |
2506 | + } | |
2507 | + } | |
4cd5ba0f | 2508 | + |
f33182aa | 2509 | + if (up == NULL) |
2510 | + { | |
2511 | + info->units = (struct coff_compilation_unit *) | |
2512 | + xrealloc (info->units, | |
2513 | + ++info->nunits * sizeof(struct coff_compilation_unit)); | |
2514 | + up = info->units + (info->nunits - 1); | |
2515 | + up->fname = osym->name; | |
2516 | + up->syms = NULL; | |
2517 | + up->nsyms = up->totsyms = 0; | |
2518 | + } | |
2519 | + } | |
2520 | + else if (osym->flags & (BSF_GLOBAL | BSF_WEAK)) | |
2521 | + { | |
2522 | + /* Global (or weak) symbols are recorded outside compilation | |
2523 | + units. */ | |
2524 | + info->globals = (asymbol **) | |
2525 | + xrealloc (info->globals, ++info->nglobals * sizeof(asymbol *)); | |
2526 | + info->globals[info->nglobals - 1] = osym; | |
2527 | + continue; | |
2528 | + } | |
2529 | + else if (!bfd_is_const_section(osym->section)) | |
2530 | + { | |
2531 | + if (osym->flags & BSF_SECTION_SYM) | |
2532 | + { | |
2533 | + coff_symbol_type *csymp; | |
2534 | + /* Just record them by now, they'll be fixed up later. */ | |
4cd5ba0f | 2535 | + |
f33182aa | 2536 | + if (info->nsyms == 0 && (info->flags & COFF_FL_AVR) == 0) |
2537 | + { | |
2538 | + /* Very first symbol, fake a compilation unit name | |
2539 | + for it. Historical precedence seems to dictate | |
2540 | + this, but AVR COFF does not use that. */ | |
2541 | + csymp = (coff_symbol_type *) | |
2542 | + coff_bfd_make_debug_symbol (info->abfd, 0, 0); | |
2543 | + if (csymp == NULL) | |
2544 | + return FALSE; | |
4cd5ba0f | 2545 | + |
f33182aa | 2546 | + csymp->symbol.name = xstrdup ("<fake>"); |
2547 | + csymp->symbol.value = 0; | |
2548 | + csymp->symbol.udata.p = NULL; | |
2549 | + csymp->native->u.syment.n_sclass = C_FILE; | |
2550 | + /* force filename into aux entry */ | |
2551 | + csymp->native->u.syment.n_numaux = 1; | |
2552 | + coff_record_symbol (info, csymp); | |
2553 | + } | |
4cd5ba0f | 2554 | + |
f33182aa | 2555 | + /* convert to COFF native section symbol */ |
2556 | + csymp = (coff_symbol_type *) | |
2557 | + coff_bfd_make_debug_symbol (info->abfd, 0, 0); | |
2558 | + if (csymp == NULL) | |
2559 | + return FALSE; | |
4cd5ba0f | 2560 | + |
f33182aa | 2561 | + csymp->symbol.name = xstrdup (osym->section->name); |
2562 | + csymp->symbol.value = osym->section->output_section->vma; | |
2563 | + csymp->symbol.flags = BSF_DEBUGGING | BSF_SECTION_SYM; | |
2564 | + csymp->symbol.section = osym->section; | |
2565 | + csymp->symbol.udata.p = NULL; | |
2566 | + csymp->native->fix_scnlen = 1; | |
2567 | + csymp->native->u.syment.n_sclass = C_STAT; | |
2568 | + csymp->native->u.syment.n_type = T_NULL; | |
2569 | + csymp->native->u.syment.n_numaux = 1; | |
4cd5ba0f | 2570 | + |
f33182aa | 2571 | + coff_record_symbol (info, csymp); |
4cd5ba0f | 2572 | + |
f33182aa | 2573 | + info->secsyms = (coff_symbol_type **) |
2574 | + xrealloc (info->secsyms, | |
2575 | + ++info->nsecsyms * sizeof(coff_symbol_type *)); | |
2576 | + info->secsyms[info->nsecsyms - 1] = csymp; | |
2577 | + } | |
2578 | + else | |
2579 | + { | |
2580 | + /* Local symbol in a named section, will be recorded | |
2581 | + within the respective compilation unit. */ | |
2582 | + if (up == NULL) | |
2583 | + { | |
2584 | + fprintf (stderr, | |
2585 | + _("Discarding local symbol outside any compilation unit")); | |
2586 | + if (osym->name) | |
2587 | + fprintf (stderr, ": %s", osym->name); | |
2588 | + putc ('\n', stderr); | |
2589 | + } | |
2590 | + else | |
2591 | + { | |
2592 | + up->syms = (asymbol **) | |
2593 | + xrealloc (up->syms, ++up->nsyms * sizeof(asymbol *)); | |
2594 | + up->syms[up->nsyms - 1] = osym; | |
2595 | + up->totsyms = up->nsyms; | |
2596 | + continue; | |
2597 | + } | |
2598 | + } | |
2599 | + } | |
2600 | + } | |
4cd5ba0f ER |
2601 | + |
2602 | + return TRUE; | |
2603 | +} | |
2604 | + | |
f33182aa | 2605 | +/* Find a name in the symbol table. If found, the respective entry in |
2606 | + the symbol vector is zeroed, so after processing all debugging | |
2607 | + symbols, only non-debugging symbols will remain. */ | |
2608 | +static asymbol * | |
2609 | +coff_find_symbol (info, name, isfunction, global) | |
2610 | + struct coff_write_handle *info; | |
2611 | + const char *name; | |
2612 | + bfd_boolean isfunction; | |
2613 | + bfd_boolean global; | |
2614 | +{ | |
2615 | + asymbol *symp; | |
2616 | + long i; | |
2617 | + size_t namelen; | |
4cd5ba0f | 2618 | + |
f33182aa | 2619 | + if (global) |
2620 | + { | |
2621 | + for (i = 0; i < info->nglobals; i++) | |
2622 | + { | |
2623 | + symp = info->globals[i]; | |
2624 | + if (symp == NULL) | |
2625 | + continue; | |
2626 | + if (strcmp (name, symp->name) == 0 | |
2627 | + && ((symp->flags & BSF_FUNCTION) != 0) == (isfunction == TRUE)) | |
2628 | + { | |
2629 | + info->globals[i] = NULL; | |
2630 | + return symp; | |
2631 | + } | |
2632 | + } | |
2633 | + return NULL; | |
2634 | + } | |
4cd5ba0f | 2635 | + |
f33182aa | 2636 | + if (info->currentfile == NULL) |
2637 | + return NULL; | |
4cd5ba0f | 2638 | + |
f33182aa | 2639 | + /* For local symbols, the match optionally stops at a dot in the |
2640 | + symtab symbol's name; this is used by gcc to indicate | |
2641 | + function-scope static symbols (e. g. symbol "foo" will become | |
2642 | + "foo.1" in function scope). */ | |
2643 | + namelen = strlen (name); | |
2644 | + for (i = 0; i < info->currentfile->nsyms; i++) | |
4cd5ba0f | 2645 | + { |
f33182aa | 2646 | + symp = info->currentfile->syms[i]; |
2647 | + if (symp == NULL) | |
2648 | + continue; | |
2649 | + if (strncmp (name, symp->name, namelen) == 0 | |
2650 | + && (symp->name[namelen] == '\0' || symp->name[namelen] == '.') | |
2651 | + && ((symp->flags & BSF_FUNCTION) != 0) == (isfunction == TRUE)) | |
2652 | + { | |
2653 | + info->currentfile->syms[i] = NULL; | |
2654 | + info->currentfile->totsyms--; | |
2655 | + return symp; | |
2656 | + } | |
4cd5ba0f | 2657 | + } |
f33182aa | 2658 | + return NULL; |
4cd5ba0f ER |
2659 | +} |
2660 | + | |
f33182aa | 2661 | +static void |
2662 | +coff_record_symbol (info, csymp) | |
2663 | + struct coff_write_handle *info; | |
2664 | + coff_symbol_type *csymp; | |
4cd5ba0f | 2665 | +{ |
f33182aa | 2666 | + struct coff_private_symdata *priv; |
4cd5ba0f | 2667 | + |
f33182aa | 2668 | + info->syms = (asymbol **) xrealloc (info->syms, |
2669 | + ++info->nsyms * sizeof (asymbol *)); | |
2670 | + info->syms[info->nsyms - 1] = (asymbol *)csymp; | |
4cd5ba0f | 2671 | + |
f33182aa | 2672 | + if ((priv = csymp->symbol.udata.p) != NULL) |
2673 | + { | |
2674 | + if (priv->shash != NULL) | |
2675 | + { | |
2676 | + struct coff_struct_hash_entry *shash = priv->shash; | |
2677 | + shash->fixidxs = (long *) | |
2678 | + xrealloc (shash->fixidxs, ++shash->nfixidxs * sizeof (long)); | |
2679 | + shash->fixidxs[shash->nfixidxs - 1] = info->nsyms - 1; | |
2680 | + } | |
2681 | + if (priv->ehash != NULL) | |
2682 | + { | |
2683 | + struct coff_enum_hash_entry *ehash = priv->ehash; | |
2684 | + ehash->fixidxs = (long *) | |
2685 | + xrealloc (ehash->fixidxs, ++ehash->nfixidxs * sizeof (long)); | |
2686 | + ehash->fixidxs[ehash->nfixidxs - 1] = info->nsyms - 1; | |
2687 | + } | |
2688 | + free (priv); | |
2689 | + csymp->symbol.udata.p = NULL; | |
2690 | + } | |
4cd5ba0f | 2691 | + |
f33182aa | 2692 | + /* If there are any pending endndx fixes, pop the last element from |
2693 | + that stack, and record the current symbol for fixing. We need to | |
2694 | + do this here since we need to record our current csymp->native | |
2695 | + (where that csymp is completely unrelated to whatever symbol was | |
2696 | + previously generated that requested the fixup). The stack of | |
2697 | + pending fixes is required since several endndx fixes could be | |
2698 | + nested, e. g. the start of a function has a pending fix that | |
2699 | + needs to point to the first symbol after the function, but there | |
2700 | + could be an anonymous struct definition inside that function's | |
2701 | + local variables where the endndx needs to point after the last | |
2702 | + symbol of this struct. Also, structs and unions could be nested. | |
4cd5ba0f | 2703 | + |
f33182aa | 2704 | + Each call to coff_record_symbol() can fix at most one endndx |
2705 | + (even if more are pending in the stack), but that's OK. | |
4cd5ba0f | 2706 | + |
f33182aa | 2707 | + Note that bfd/coffgen.c converts that csymp->native into a |
2708 | + symtable slot number after coff_renumber_symbols() has been | |
2709 | + run. */ | |
2710 | + if (info->flags & COFF_FL_FIX_ENDNDX) | |
2711 | + { | |
2712 | + struct coff_fix_stack *fsp, *ofsp; | |
2713 | + union internal_auxent *aux; | |
4cd5ba0f | 2714 | + |
f33182aa | 2715 | + assert (info->fixes != NULL); |
4cd5ba0f | 2716 | + |
f33182aa | 2717 | + fsp = info->fixes; |
2718 | + ofsp = NULL; | |
2719 | + while (fsp->next != NULL) | |
2720 | + { | |
2721 | + ofsp = fsp; | |
2722 | + fsp = fsp->next; | |
2723 | + } | |
2724 | + if (ofsp == NULL) | |
2725 | + info->fixes = NULL; | |
2726 | + else | |
2727 | + ofsp->next = NULL; | |
4cd5ba0f | 2728 | + |
f33182aa | 2729 | + aux = &(fsp->native->u.auxent); |
2730 | + fsp->native->fix_end = 1; | |
2731 | + aux->x_sym.x_fcnary.x_fcn.x_endndx.p = csymp->native; | |
2732 | + free (fsp); | |
4cd5ba0f | 2733 | + |
f33182aa | 2734 | + info->flags &= ~COFF_FL_FIX_ENDNDX; |
2735 | + } | |
4cd5ba0f ER |
2736 | +} |
2737 | + | |
f33182aa | 2738 | +/* Fixup AVR COFF register handling: they don't only mention the |
2739 | + starting register number, but all registers, each within one byte | |
2740 | + of the value. Unused register positions are filled up with | |
2741 | + 0xff. */ | |
2742 | +static symvalue | |
2743 | +coff_fixup_avr_register (val, size) | |
2744 | + symvalue val; | |
2745 | + int size; | |
4cd5ba0f | 2746 | +{ |
f33182aa | 2747 | + union |
2748 | + { | |
2749 | + unsigned char c[4]; | |
2750 | + symvalue v; | |
2751 | + } u; | |
4cd5ba0f | 2752 | + |
f33182aa | 2753 | + u.c[1] = u.c[2] = u.c[3] = 0xff; |
2754 | + u.c[0] = val; | |
2755 | + if (size > 8) | |
2756 | + u.c[1] = val + 1; | |
2757 | + if (size > 16) | |
2758 | + { | |
2759 | + u.c[2] = val + 2; | |
2760 | + u.c[3] = val + 3; | |
2761 | + } | |
4cd5ba0f | 2762 | + |
f33182aa | 2763 | + return u.v; |
4cd5ba0f ER |
2764 | +} |
2765 | + | |
f33182aa | 2766 | +/* Initialize an entry in the hash tables. */ |
4cd5ba0f | 2767 | + |
f33182aa | 2768 | +static struct bfd_hash_entry * |
2769 | +coff_name_type_newfunc (entry, table, string) | |
2770 | + struct bfd_hash_entry *entry; | |
2771 | + struct bfd_hash_table *table; | |
2772 | + const char *string; | |
4cd5ba0f | 2773 | +{ |
f33182aa | 2774 | + struct coff_name_type_hash_entry *ret = |
2775 | + (struct coff_name_type_hash_entry *) entry; | |
4cd5ba0f | 2776 | + |
f33182aa | 2777 | + /* Allocate the structure if it has not already been allocated by a |
2778 | + subclass. */ | |
2779 | + if (ret == NULL) | |
2780 | + ret = ((struct coff_name_type_hash_entry *) | |
2781 | + bfd_hash_allocate (table, sizeof *ret)); | |
2782 | + if (ret == NULL) | |
2783 | + return NULL; | |
4cd5ba0f | 2784 | + |
f33182aa | 2785 | + /* Call the allocation method of the superclass. */ |
2786 | + ret = ((struct coff_name_type_hash_entry *) | |
2787 | + bfd_hash_newfunc ((struct bfd_hash_entry *) ret, table, string)); | |
2788 | + if (ret) | |
2789 | + { | |
2790 | + /* Set local fields. */ | |
2791 | + ret->types = NULL; | |
2792 | + ret->emitted = FALSE; | |
2793 | + } | |
4cd5ba0f | 2794 | + |
f33182aa | 2795 | + return (struct bfd_hash_entry *) ret; |
4cd5ba0f ER |
2796 | +} |
2797 | + | |
f33182aa | 2798 | +static struct bfd_hash_entry * |
2799 | +coff_struct_newfunc (entry, table, string) | |
2800 | + struct bfd_hash_entry *entry; | |
2801 | + struct bfd_hash_table *table; | |
2802 | + const char *string; | |
4cd5ba0f | 2803 | +{ |
f33182aa | 2804 | + struct coff_struct_hash_entry *ret = |
2805 | + (struct coff_struct_hash_entry *) entry; | |
4cd5ba0f | 2806 | + |
f33182aa | 2807 | + /* Allocate the structure if it has not already been allocated by a |
2808 | + subclass. */ | |
2809 | + if (ret == NULL) | |
2810 | + ret = ((struct coff_struct_hash_entry *) | |
2811 | + bfd_hash_allocate (table, sizeof *ret)); | |
2812 | + if (ret == NULL) | |
2813 | + return NULL; | |
4cd5ba0f | 2814 | + |
f33182aa | 2815 | + /* Call the allocation method of the superclass. */ |
2816 | + ret = ((struct coff_struct_hash_entry *) | |
2817 | + bfd_hash_newfunc ((struct bfd_hash_entry *) ret, table, string)); | |
2818 | + if (ret) | |
4cd5ba0f | 2819 | + { |
f33182aa | 2820 | + /* Set local fields. */ |
2821 | + ret->types = NULL; | |
2822 | + ret->emitted = FALSE; | |
2823 | + ret->fixidxs = NULL; | |
2824 | + ret->nfixidxs = 0; | |
2825 | + ret->native = NULL; | |
4cd5ba0f ER |
2826 | + } |
2827 | + | |
f33182aa | 2828 | + return (struct bfd_hash_entry *) ret; |
4cd5ba0f ER |
2829 | +} |
2830 | + | |
f33182aa | 2831 | +static struct bfd_hash_entry * |
2832 | +coff_enum_newfunc (entry, table, string) | |
2833 | + struct bfd_hash_entry *entry; | |
2834 | + struct bfd_hash_table *table; | |
2835 | + const char *string; | |
4cd5ba0f | 2836 | +{ |
f33182aa | 2837 | + struct coff_enum_hash_entry *ret = |
2838 | + (struct coff_enum_hash_entry *) entry; | |
4cd5ba0f | 2839 | + |
f33182aa | 2840 | + /* Allocate the structure if it has not already been allocated by a |
2841 | + subclass. */ | |
2842 | + if (ret == NULL) | |
2843 | + ret = ((struct coff_enum_hash_entry *) | |
2844 | + bfd_hash_allocate (table, sizeof *ret)); | |
2845 | + if (ret == NULL) | |
2846 | + return NULL; | |
4cd5ba0f | 2847 | + |
f33182aa | 2848 | + /* Call the allocation method of the superclass. */ |
2849 | + ret = ((struct coff_enum_hash_entry *) | |
2850 | + bfd_hash_newfunc ((struct bfd_hash_entry *) ret, table, string)); | |
2851 | + if (ret) | |
2852 | + { | |
2853 | + /* Set local fields. */ | |
2854 | + ret->types = NULL; | |
2855 | + ret->emitted = FALSE; | |
2856 | + ret->fixidxs = NULL; | |
2857 | + ret->nfixidxs = 0; | |
2858 | + ret->native = NULL; | |
2859 | + } | |
4cd5ba0f | 2860 | + |
f33182aa | 2861 | + return (struct bfd_hash_entry *) ret; |
4cd5ba0f ER |
2862 | +} |
2863 | + | |
f33182aa | 2864 | +/* Look up an entry in the hash tables. */ |
4cd5ba0f | 2865 | + |
f33182aa | 2866 | +#define coff_name_type_hash_lookup(table, string, create, copy) \ |
2867 | + ((struct coff_name_type_hash_entry *) \ | |
2868 | + bfd_hash_lookup (&(table)->root, (string), (create), (copy))) | |
4cd5ba0f | 2869 | + |
f33182aa | 2870 | +/* Traverse the hash table. */ |
4cd5ba0f | 2871 | + |
f33182aa | 2872 | +#define coff_name_type_hash_traverse(table, func, info) \ |
2873 | + (bfd_hash_traverse \ | |
2874 | + (&(table)->root, \ | |
2875 | + (bfd_boolean (*) PARAMS ((struct bfd_hash_entry *, PTR))) (func), \ | |
2876 | + (info))) | |
4cd5ba0f | 2877 | + |
f33182aa | 2878 | +#define coff_struct_hash_lookup(table, string, create, copy) \ |
2879 | + ((struct coff_struct_hash_entry *) \ | |
2880 | + bfd_hash_lookup (&(table)->root, (string), (create), (copy))) | |
4cd5ba0f | 2881 | + |
f33182aa | 2882 | +/* Traverse the hash table. */ |
4cd5ba0f | 2883 | + |
f33182aa | 2884 | +#define coff_struct_hash_traverse(table, func, info) \ |
2885 | + (bfd_hash_traverse \ | |
2886 | + (&(table)->root, \ | |
2887 | + (bfd_boolean (*) PARAMS ((struct bfd_hash_entry *, PTR))) (func), \ | |
2888 | + (info))) | |
4cd5ba0f | 2889 | + |
f33182aa | 2890 | +#define coff_enum_hash_lookup(table, string, create, copy) \ |
2891 | + ((struct coff_enum_hash_entry *) \ | |
2892 | + bfd_hash_lookup (&(table)->root, (string), (create), (copy))) | |
4cd5ba0f | 2893 | + |
f33182aa | 2894 | +/* Traverse the hash table. */ |
4cd5ba0f | 2895 | + |
f33182aa | 2896 | +#define coff_enum_hash_traverse(table, func, info) \ |
2897 | + (bfd_hash_traverse \ | |
2898 | + (&(table)->root, \ | |
2899 | + (bfd_boolean (*) PARAMS ((struct bfd_hash_entry *, PTR))) (func), \ | |
2900 | + (info))) | |
4cd5ba0f | 2901 | + |
f33182aa | 2902 | +#define coff_push_type(kind) \ |
2903 | + tst = (struct coff_type_stack *) xmalloc (sizeof (struct coff_type_stack)); \ | |
2904 | + memset (tst, 0, sizeof (*tst)); \ | |
2905 | + tst->next = info->tstack; \ | |
2906 | + tst->tsk = kind; \ | |
2907 | + info->tstack = tst | |
2908 | + | |
2909 | +#define coff_pop_type() \ | |
2910 | + tst = info->tstack; \ | |
2911 | + if (tst == NULL) { \ | |
2912 | + fprintf (stderr, _("empty type stack in coff_pop_type()\n")); \ | |
2913 | + return FALSE; \ | |
2914 | + } \ | |
2915 | + info->tstack = tst->next; \ | |
2916 | + tst->next = NULL | |
2917 | + | |
2918 | +#define coff_complain_unsupp(s) \ | |
2919 | + fprintf (stderr, _("%s type not supported in %s\n"), \ | |
2920 | + s, info->abfd->xvec->name); \ | |
2921 | + return FALSE | |
4cd5ba0f | 2922 | + |
f33182aa | 2923 | +/* These function is called via the hash traverse routine when freeing |
2924 | + a hash table (at the end of a translation unit). */ | |
4cd5ba0f | 2925 | +static bfd_boolean |
f33182aa | 2926 | +coff_free_type_info (h, p) |
2927 | + struct coff_name_type_hash_entry *h; | |
4cd5ba0f ER |
2928 | + PTR p ATTRIBUTE_UNUSED; |
2929 | +{ | |
f33182aa | 2930 | + struct coff_type_stack *tst, *otst; |
4cd5ba0f | 2931 | + |
f33182aa | 2932 | + for (tst = h->types; tst != NULL;) |
2933 | + { | |
2934 | + otst = tst; | |
2935 | + tst = tst->next; | |
2936 | + free (otst); | |
2937 | + } | |
4cd5ba0f ER |
2938 | + return TRUE; |
2939 | +} | |
2940 | + | |
4cd5ba0f | 2941 | +static bfd_boolean |
f33182aa | 2942 | +coff_free_struct_info (h, p) |
2943 | + struct coff_struct_hash_entry *h; | |
4cd5ba0f ER |
2944 | + PTR p ATTRIBUTE_UNUSED; |
2945 | +{ | |
f33182aa | 2946 | + struct coff_type_stack *tst, *otst, *xtst, *xotst; |
2947 | + struct coff_struct_fields *fp; | |
2948 | + long i; | |
4cd5ba0f | 2949 | + |
f33182aa | 2950 | + for (tst = h->types; tst != NULL;) |
2951 | + { | |
2952 | + otst = tst; | |
2953 | + if (tst->u.ts_struct.tagismalloced) | |
2954 | + free (tst->u.ts_struct.tag.malloctag); | |
2955 | + for (i = 0, fp = tst->u.ts_struct.fields; | |
2956 | + i < tst->u.ts_struct.nfields; | |
2957 | + i++, fp++) | |
2958 | + { | |
2959 | + xtst = fp->types; | |
2960 | + while (xtst != NULL) | |
2961 | + { | |
2962 | + xotst = xtst->next; | |
2963 | + free (xtst); | |
2964 | + xtst = xotst; | |
2965 | + } | |
2966 | + } | |
2967 | + free (tst->u.ts_struct.fields); | |
2968 | + tst = tst->next; | |
2969 | + free (otst); | |
2970 | + } | |
4cd5ba0f ER |
2971 | + return TRUE; |
2972 | +} | |
2973 | + | |
4cd5ba0f | 2974 | +static bfd_boolean |
f33182aa | 2975 | +coff_free_enum_info (h, p) |
2976 | + struct coff_enum_hash_entry *h; | |
2977 | + PTR p ATTRIBUTE_UNUSED; | |
4cd5ba0f | 2978 | +{ |
f33182aa | 2979 | + struct coff_type_stack *tst, *otst; |
4cd5ba0f | 2980 | + |
f33182aa | 2981 | + for (tst = h->types; tst != NULL;) |
4cd5ba0f | 2982 | + { |
f33182aa | 2983 | + otst = tst; |
2984 | + if (tst->u.ts_enum.tagismalloced) | |
2985 | + free (tst->u.ts_enum.tag.malloctag); | |
2986 | + tst = tst->next; | |
2987 | + free (otst); | |
4cd5ba0f | 2988 | + } |
f33182aa | 2989 | + return TRUE; |
2990 | +} | |
4cd5ba0f | 2991 | + |
f33182aa | 2992 | +static unsigned int |
2993 | +coff_get_fundamental_type (info, tst) | |
2994 | + struct coff_write_handle *info ATTRIBUTE_UNUSED; | |
2995 | + struct coff_type_stack *tst; | |
2996 | +{ | |
2997 | + size_t i; | |
2998 | + | |
2999 | + /* See if one of our predefined types will fit. */ | |
3000 | + if (tst->tsk == TS_INT) | |
4cd5ba0f | 3001 | + { |
f33182aa | 3002 | + for (i = 0; |
3003 | + i < sizeof coff_predef_types / sizeof (struct coff_predef_type); | |
3004 | + i++) | |
4cd5ba0f | 3005 | + { |
f33182aa | 3006 | + if (coff_predef_types[i].kind == TS_INT |
3007 | + && coff_predef_types[i].size == tst->u.ts_int.size | |
3008 | + && coff_predef_types[i].isunsigned == tst->u.ts_int.isunsigned) | |
3009 | + return coff_predef_types[i].slot; | |
4cd5ba0f | 3010 | + } |
f33182aa | 3011 | + fprintf (stderr, |
3012 | + _("%ssigned %d-bit integer type not available in COFF\n"), | |
3013 | + tst->u.ts_int.isunsigned? "un": "", tst->u.ts_int.size * 8); | |
4cd5ba0f | 3014 | + } |
f33182aa | 3015 | + else |
4cd5ba0f | 3016 | + { |
f33182aa | 3017 | + for (i = 0; |
3018 | + i < sizeof coff_predef_types / sizeof (struct coff_predef_type); | |
3019 | + i++) | |
4cd5ba0f | 3020 | + { |
f33182aa | 3021 | + if (coff_predef_types[i].kind == TS_FLOAT |
3022 | + && coff_predef_types[i].size == tst->u.ts_float.size) | |
3023 | + return coff_predef_types[i].slot; | |
4cd5ba0f | 3024 | + } |
f33182aa | 3025 | + fprintf (stderr, _("%d-bit float type not available in COFF\n"), |
3026 | + tst->u.ts_float.size * 8); | |
4cd5ba0f ER |
3027 | + } |
3028 | + | |
f33182aa | 3029 | + return T_NULL; |
4cd5ba0f ER |
3030 | +} |
3031 | + | |
4cd5ba0f | 3032 | +static bfd_boolean |
f33182aa | 3033 | +coff_make_typed_symbol (info, csympp, stopat) |
3034 | + struct coff_write_handle *info; | |
3035 | + coff_symbol_type **csympp; | |
3036 | + enum ts_kind stopat; | |
4cd5ba0f | 3037 | +{ |
f33182aa | 3038 | + struct coff_type_stack *tst; |
3039 | + union internal_auxent *aux; | |
3040 | + struct coff_struct_hash_entry *shash; | |
3041 | + struct coff_enum_hash_entry *ehash; | |
3042 | + struct coff_private_symdata *priv; | |
3043 | + unsigned int type, numaux, arydim, size, i, nele, nderived; | |
3044 | + const char *name; | |
3045 | + bfd_boolean oldavrcoff = (info->flags & (COFF_FL_AVR | COFF_FL_EXT_AVR)) | |
3046 | + == COFF_FL_AVR; | |
4cd5ba0f | 3047 | + |
f33182aa | 3048 | + /* Synthesize a new internal COFF symbol. */ |
3049 | + *csympp = (coff_symbol_type *) coff_bfd_make_debug_symbol (info->abfd, 0, 0); | |
3050 | + if (*csympp == NULL) | |
3051 | + return FALSE; | |
4cd5ba0f | 3052 | + |
f33182aa | 3053 | + priv = (struct coff_private_symdata *) xmalloc (sizeof *priv); |
3054 | + memset (priv, 0, sizeof *priv); | |
4cd5ba0f | 3055 | + |
f33182aa | 3056 | + type = arydim = size = nderived = 0; |
4cd5ba0f | 3057 | + |
f33182aa | 3058 | + aux = &(((*csympp)->native + 1)->u.auxent); |
4cd5ba0f | 3059 | + |
f33182aa | 3060 | + /* Now, walk the type stack, and see how we could convert the info |
3061 | + we've got to what COFF understands. */ | |
3062 | + for (;;) | |
3063 | + { | |
3064 | + if (info->tstack == NULL) | |
3065 | + break; | |
4cd5ba0f | 3066 | + |
f33182aa | 3067 | + /* If we have been advised to not pop the entire stack, stop |
3068 | + here. */ | |
3069 | + if (info->tstack->tsk == stopat && info->tstack->next == NULL) | |
3070 | + break; | |
4cd5ba0f | 3071 | + |
f33182aa | 3072 | + coff_pop_type (); |
4cd5ba0f | 3073 | + |
f33182aa | 3074 | + switch (tst->tsk) |
3075 | + { | |
3076 | + case TS_NONE: | |
3077 | + /* cannot happen */ | |
3078 | + break; | |
4cd5ba0f | 3079 | + |
f33182aa | 3080 | + case TS_EMPTY: |
3081 | + if (info->tstack != NULL && info->tstack->tsk != stopat) | |
3082 | + fprintf (stderr, _("empty type not last on type stack\n")); | |
3083 | + /* type |= T_NULL; */ | |
3084 | + break; | |
4cd5ba0f | 3085 | + |
f33182aa | 3086 | + case TS_VOID: |
3087 | + if (info->tstack != NULL && info->tstack->tsk != stopat) | |
3088 | + fprintf (stderr, _("void type not last on type stack\n")); | |
3089 | + type |= T_VOID; | |
3090 | + break; | |
4cd5ba0f | 3091 | + |
f33182aa | 3092 | + case TS_INT: |
3093 | + if (info->tstack != NULL && info->tstack->tsk != stopat) | |
3094 | + fprintf (stderr, _("int type not last on type stack\n")); | |
3095 | + type |= coff_get_fundamental_type (info, tst); | |
3096 | + if (size == 0) | |
3097 | + size = tst->u.ts_int.size; | |
3098 | + break; | |
4cd5ba0f | 3099 | + |
f33182aa | 3100 | + case TS_FLOAT: |
3101 | + if (info->tstack != NULL && info->tstack->tsk != stopat) | |
3102 | + fprintf (stderr, _("float type not last on type stack\n")); | |
3103 | + type |= coff_get_fundamental_type (info, tst); | |
3104 | + if (size == 0) | |
3105 | + size = tst->u.ts_float.size; | |
3106 | + break; | |
4cd5ba0f | 3107 | + |
f33182aa | 3108 | + case TS_POINTER: |
3109 | + nderived++; | |
3110 | + type = ((type & ~N_BTMASK) << N_TSHIFT) | (DT_PTR << N_BTSHFT); | |
3111 | + size = info->pointersize; | |
3112 | + break; | |
4cd5ba0f | 3113 | + |
f33182aa | 3114 | + case TS_FUNC: |
3115 | + nderived++; | |
3116 | + type = ((type & ~N_BTMASK) << N_TSHIFT) | (DT_FCN << N_BTSHFT); | |
3117 | + /* AUX entry for DT_FCN will be filled in elsewhere. */ | |
3118 | + break; | |
4cd5ba0f | 3119 | + |
f33182aa | 3120 | + case TS_ARRAY: |
3121 | + /* We need to limit arydim so the assignment below won't | |
3122 | + overwrite random locations. */ | |
3123 | + if (arydim >= DIMNUM) | |
3124 | + { | |
3125 | + fprintf (stderr, | |
3126 | + _("More than %d array dimensions, result is invalid.\n"), | |
3127 | + DIMNUM); | |
3128 | + arydim = DIMNUM - 1; | |
3129 | + } | |
3130 | + nderived++; | |
3131 | + type = ((type & ~N_BTMASK) << N_TSHIFT) | (DT_ARY << N_BTSHFT); | |
3132 | + aux->x_sym.x_fcnary.x_ary.x_dimen[arydim++] = | |
3133 | + tst->u.ts_array.high - tst->u.ts_array.low + 1; | |
4cd5ba0f | 3134 | + |
f33182aa | 3135 | + break; |
4cd5ba0f | 3136 | + |
f33182aa | 3137 | + case TS_COMPLEX: |
3138 | + coff_complain_unsupp (_("complex")); | |
4cd5ba0f | 3139 | + |
f33182aa | 3140 | + case TS_ENUM: |
3141 | + type |= T_ENUM; | |
3142 | + if (size == 0) | |
3143 | + size = info->enumsize; | |
4cd5ba0f | 3144 | + |
f33182aa | 3145 | + if (tst->u.ts_enum.ehash != NULL) |
3146 | + { | |
3147 | + /* enum tag will be fixed later. */ | |
3148 | + priv->ehash = tst->u.ts_enum.ehash; | |
3149 | + break; | |
3150 | + } | |
3151 | + if (tst->u.ts_enum.tagismalloced) | |
3152 | + name = tst->u.ts_enum.tag.malloctag; | |
3153 | + else | |
3154 | + name = tst->u.ts_enum.tag.fixtag; | |
3155 | + ehash = coff_enum_hash_lookup (&info->enums, name, | |
3156 | + TRUE, tst->u.ts_enum.tagismalloced); | |
3157 | + if (ehash == NULL) | |
3158 | + return FALSE; | |
3159 | + if (!ehash->emitted) | |
3160 | + { | |
3161 | + if (ehash->types == NULL) | |
3162 | + { | |
3163 | + ehash->types = (struct coff_type_stack *) | |
3164 | + xmalloc (sizeof (struct coff_type_stack)); | |
3165 | + memcpy (ehash->types, tst, sizeof (struct coff_type_stack)); | |
3166 | + } | |
3167 | + ehash->emitted = TRUE; | |
3168 | + coff_emit_enum (info, tst, ehash); | |
3169 | + if (ehash->nfixidxs != 0) | |
3170 | + { | |
3171 | + coff_symbol_type *symp; | |
3172 | + unsigned i; | |
4cd5ba0f | 3173 | + |
f33182aa | 3174 | + for (i = 0; i < ehash->nfixidxs; i++) |
3175 | + { | |
3176 | + combined_entry_type *np; | |
4cd5ba0f | 3177 | + |
f33182aa | 3178 | + symp = (coff_symbol_type *) info->syms[ehash->fixidxs[i]]; |
3179 | + symp->native->u.syment.n_type &= ~N_BTMASK; | |
3180 | + symp->native->u.syment.n_type |= T_ENUM; | |
4cd5ba0f | 3181 | + |
f33182aa | 3182 | + if (oldavrcoff) |
3183 | + continue; | |
4cd5ba0f | 3184 | + |
f33182aa | 3185 | + np = symp->native + 1; |
3186 | + np->fix_tag = 1; | |
3187 | + np->u.auxent.x_sym.x_tagndx.p = ehash->native; | |
3188 | + if (np->u.auxent.x_sym.x_misc.x_fsize == 0) | |
3189 | + np->u.auxent.x_sym.x_misc.x_lnsz.x_size = size; | |
3190 | + } | |
4cd5ba0f | 3191 | + |
f33182aa | 3192 | + free (ehash->fixidxs); |
3193 | + ehash->nfixidxs = 0; | |
3194 | + } | |
3195 | + } | |
3196 | + if (!oldavrcoff) | |
3197 | + { | |
3198 | + ((*csympp)->native + 1)->fix_tag = 1; | |
3199 | + aux->x_sym.x_tagndx.p = ehash->native; | |
3200 | + if (aux->x_sym.x_misc.x_fsize == 0) | |
3201 | + aux->x_sym.x_misc.x_lnsz.x_size = size; | |
3202 | + } | |
3203 | + break; | |
4cd5ba0f | 3204 | + |
f33182aa | 3205 | + case TS_STRUCT: |
3206 | + if (tst->u.ts_struct.isstruct) | |
3207 | + type |= T_STRUCT; | |
3208 | + else | |
3209 | + type |= T_UNION; | |
3210 | + if (size == 0) | |
3211 | + size = tst->u.ts_struct.size; | |
4cd5ba0f | 3212 | + |
f33182aa | 3213 | + if (tst->u.ts_struct.shash != NULL) |
3214 | + { | |
3215 | + /* struct tag will be fixed later. */ | |
3216 | + priv->shash = tst->u.ts_struct.shash; | |
3217 | + break; | |
3218 | + } | |
3219 | + if (tst->u.ts_struct.tagismalloced) | |
3220 | + name = tst->u.ts_struct.tag.malloctag; | |
3221 | + else | |
3222 | + name = tst->u.ts_struct.tag.fixtag; | |
3223 | + shash = coff_struct_hash_lookup (&info->structs, name, | |
3224 | + TRUE, tst->u.ts_struct.tagismalloced); | |
3225 | + if (shash == NULL) | |
3226 | + return FALSE; | |
3227 | + if (!shash->emitted) | |
3228 | + { | |
3229 | + if (shash->types == NULL) | |
3230 | + { | |
3231 | + shash->types = (struct coff_type_stack *) | |
3232 | + xmalloc (sizeof (struct coff_type_stack)); | |
3233 | + memcpy (shash->types, tst, sizeof (struct coff_type_stack)); | |
3234 | + } | |
3235 | + shash->emitted = TRUE; | |
3236 | + coff_emit_struct (info, tst, shash); | |
3237 | + if (shash->nfixidxs != 0) | |
3238 | + { | |
3239 | + coff_symbol_type *symp; | |
3240 | + unsigned i; | |
4cd5ba0f | 3241 | + |
f33182aa | 3242 | + for (i = 0; i < shash->nfixidxs; i++) |
3243 | + { | |
3244 | + combined_entry_type *np; | |
4cd5ba0f | 3245 | + |
f33182aa | 3246 | + symp = (coff_symbol_type *) info->syms[shash->fixidxs[i]]; |
3247 | + symp->native->u.syment.n_type &= ~N_BTMASK; | |
3248 | + if (tst->u.ts_struct.isstruct) | |
3249 | + symp->native->u.syment.n_type |= T_STRUCT; | |
3250 | + else | |
3251 | + symp->native->u.syment.n_type |= T_UNION; | |
4cd5ba0f | 3252 | + |
f33182aa | 3253 | + if (oldavrcoff) |
3254 | + continue; | |
4cd5ba0f | 3255 | + |
f33182aa | 3256 | + np = symp->native + 1; |
3257 | + np->fix_tag = 1; | |
3258 | + np->u.auxent.x_sym.x_tagndx.p = shash->native; | |
3259 | + if (np->u.auxent.x_sym.x_misc.x_fsize == 0) | |
3260 | + np->u.auxent.x_sym.x_misc.x_lnsz.x_size = size; | |
3261 | + } | |
4cd5ba0f | 3262 | + |
f33182aa | 3263 | + free (shash->fixidxs); |
3264 | + shash->nfixidxs = 0; | |
3265 | + } | |
3266 | + } | |
3267 | + if (!oldavrcoff) | |
3268 | + { | |
3269 | + ((*csympp)->native + 1)->fix_tag = 1; | |
3270 | + aux->x_sym.x_tagndx.p = shash->native; | |
3271 | + if (aux->x_sym.x_misc.x_fsize == 0) | |
3272 | + aux->x_sym.x_misc.x_lnsz.x_size = size; | |
3273 | + } | |
3274 | + break; | |
3275 | + } | |
3276 | + free (tst); | |
3277 | + } | |
4cd5ba0f | 3278 | + |
f33182aa | 3279 | + if (nderived > 6) |
3280 | + fprintf (stderr, | |
3281 | + _("More than 6 derived type specifiers, result is invalid.\n")); | |
4cd5ba0f | 3282 | + |
f33182aa | 3283 | + /* Our type computation so far used the reverse order for derived |
3284 | + type specifiers. Fix this here if there was more than one | |
3285 | + derived type specifier. */ | |
3286 | + if (nderived > 1) | |
3287 | + { | |
3288 | + unsigned int nty, bty; | |
3289 | + bty = type & N_BTMASK; | |
3290 | + type = type >> N_BTSHFT; | |
3291 | + nty = 0; | |
3292 | + while (nderived-- > 0) | |
3293 | + { | |
3294 | + nty = (nty << N_TSHIFT) | (type & (N_TMASK >> N_BTSHFT)); | |
3295 | + type >>= N_TSHIFT; | |
3296 | + } | |
3297 | + type = (nty << N_BTSHFT) | bty; | |
3298 | + } | |
4cd5ba0f | 3299 | + |
f33182aa | 3300 | + if (ISARY (type)) |
3301 | + { | |
3302 | + /* Compute size of entire array. */ | |
3303 | + for (i = 0, nele = 1; i < arydim; i++) | |
3304 | + nele *= aux->x_sym.x_fcnary.x_ary.x_dimen[i]; | |
3305 | + aux->x_sym.x_misc.x_lnsz.x_size = size * nele; | |
3306 | + } | |
4cd5ba0f | 3307 | + |
f33182aa | 3308 | + numaux = 0; |
3309 | + if (ISARY (type) || ISFCN (type)) | |
3310 | + numaux++; | |
3311 | + if ((BTYPE (type) == T_STRUCT || BTYPE (type) == T_UNION | |
3312 | + || BTYPE (type) == T_ENUM) | |
3313 | + && !oldavrcoff) | |
3314 | + numaux++; | |
3315 | + /* Only AVR COFF uses multiple AUX entries. */ | |
3316 | + if (numaux > 1 && (info->flags & COFF_FL_AVR) == 0) | |
3317 | + numaux = 1; | |
4cd5ba0f | 3318 | + |
f33182aa | 3319 | + priv->size = size; |
3320 | + (*csympp)->symbol.udata.p = priv; | |
3321 | + (*csympp)->native->u.syment.n_type = type; | |
3322 | + (*csympp)->native->u.syment.n_numaux = numaux; | |
4cd5ba0f | 3323 | + |
f33182aa | 3324 | + /* If the fundamental type comes out as T_NULL, this means we don't |
3325 | + have any type information. Just don't emit any aux entries in | |
3326 | + that case, and drop any derived type information as well. */ | |
3327 | + if (BTYPE (type) == T_NULL) | |
3328 | + { | |
3329 | + printf ("coff_make_typed_symbol() -> T_NULL\n"); | |
3330 | + //(*csympp)->native->u.syment.n_type = T_NULL; | |
3331 | + (*csympp)->native->u.syment.n_numaux = 0; | |
3332 | + } | |
4cd5ba0f | 3333 | + |
f33182aa | 3334 | + return TRUE; |
3335 | +} | |
4cd5ba0f | 3336 | + |
f33182aa | 3337 | +static bfd_boolean coff_emit_struct (info, tst, shash) |
3338 | + struct coff_write_handle *info; | |
3339 | + struct coff_type_stack *tst; | |
3340 | + struct coff_struct_hash_entry *shash; | |
3341 | +{ | |
3342 | + coff_symbol_type *csymp, *scsymp, *ecsymp; | |
3343 | + union internal_auxent *aux; | |
3344 | + struct coff_fix_stack *fixp, *ofp; | |
3345 | + bfd_boolean isstruct = tst->u.ts_struct.isstruct; | |
3346 | + bfd_boolean isbitfield = FALSE; | |
3347 | + struct coff_type_stack *savedtst; | |
3348 | + struct coff_struct_fields *fp; | |
3349 | + unsigned short sclass; | |
3350 | + long i; | |
4cd5ba0f | 3351 | + |
f33182aa | 3352 | + if ((info->flags & (COFF_FL_AVR | COFF_FL_EXT_AVR)) == |
3353 | + COFF_FL_AVR) | |
3354 | + /* old AVR COFF doesn't support struct debugging */ | |
3355 | + return TRUE; | |
4cd5ba0f | 3356 | + |
f33182aa | 3357 | + /* Synthesize a new internal COFF symbol for the struct/union. */ |
3358 | + scsymp = (coff_symbol_type *) coff_bfd_make_debug_symbol (info->abfd, 0, 0); | |
3359 | + if (scsymp == NULL) | |
3360 | + return FALSE; | |
4cd5ba0f | 3361 | + |
f33182aa | 3362 | + if (tst->u.ts_struct.tagismalloced) |
3363 | + scsymp->symbol.name = xstrdup (tst->u.ts_struct.tag.malloctag); | |
3364 | + else | |
3365 | + scsymp->symbol.name = tst->u.ts_struct.tag.fixtag; | |
3366 | + scsymp->symbol.flags = BSF_NOT_AT_END; | |
3367 | + scsymp->symbol.section = bfd_und_section_ptr; | |
3368 | + scsymp->native->u.syment.n_sclass = isstruct? C_STRTAG: C_UNTAG; | |
3369 | + scsymp->native->u.syment.n_type = isstruct? T_STRUCT: T_UNION; | |
3370 | + scsymp->native->u.syment.n_numaux = 1; | |
3371 | + scsymp->symbol.udata.p = NULL; | |
3372 | + scsymp->symbol.value = 0; | |
4cd5ba0f | 3373 | + |
f33182aa | 3374 | + shash->native = scsymp->native; |
4cd5ba0f | 3375 | + |
f33182aa | 3376 | + /* Synthesize a new internal COFF symbol for the end of struct/union. */ |
3377 | + ecsymp = (coff_symbol_type *) coff_bfd_make_debug_symbol (info->abfd, 0, 0); | |
3378 | + if (ecsymp == NULL) | |
3379 | + return FALSE; | |
4cd5ba0f | 3380 | + |
f33182aa | 3381 | + ecsymp->symbol.name = ".eos"; |
3382 | + ecsymp->symbol.flags = BSF_NOT_AT_END; | |
3383 | + /* We need to use the com section here since bfd/coffgen.c | |
3384 | + translates this into an N_UNDEF one without clobbering the | |
3385 | + value. */ | |
3386 | + ecsymp->symbol.section = bfd_com_section_ptr; | |
3387 | + ecsymp->native->u.syment.n_sclass = C_EOS; | |
3388 | + ecsymp->symbol.udata.p = NULL; | |
3389 | + ecsymp->symbol.value = tst->u.ts_struct.size; | |
3390 | + ecsymp->native->u.syment.n_numaux = 1; | |
3391 | + (ecsymp->native + 1)->fix_tag = 1; | |
3392 | + aux = &((ecsymp->native + 1)->u.auxent); | |
3393 | + aux->x_sym.x_tagndx.p = scsymp->native; | |
3394 | + aux->x_sym.x_misc.x_lnsz.x_size = tst->u.ts_struct.size; | |
4cd5ba0f | 3395 | + |
f33182aa | 3396 | + coff_record_symbol (info, scsymp); |
4cd5ba0f | 3397 | + |
f33182aa | 3398 | + savedtst = info->tstack; |
4cd5ba0f | 3399 | + |
f33182aa | 3400 | + if (isstruct) |
4cd5ba0f | 3401 | + { |
f33182aa | 3402 | + /* First, make a quick walk along all the fields, and figure out |
3403 | + * whether we've got a genuine struct or a bitfield struct. */ | |
3404 | + for (i = 0, fp = tst->u.ts_struct.fields; | |
3405 | + i < tst->u.ts_struct.nfields; | |
3406 | + i++, fp++) | |
3407 | + if (fp->bitsize % 8 != 0) | |
3408 | + { | |
3409 | + isbitfield = TRUE; | |
3410 | + break; | |
3411 | + } | |
4cd5ba0f ER |
3412 | + } |
3413 | + | |
f33182aa | 3414 | + sclass = isstruct? (isbitfield? C_FIELD: C_MOS): C_MOU; |
3415 | + | |
3416 | + for (i = 0, fp = tst->u.ts_struct.fields; | |
3417 | + i < tst->u.ts_struct.nfields; | |
3418 | + i++, fp++) | |
4cd5ba0f | 3419 | + { |
f33182aa | 3420 | + if (strlen (fp->name) == 0) |
4cd5ba0f | 3421 | + { |
f33182aa | 3422 | + /* empty name could happen inside bitfield */ |
3423 | + fp->types = NULL; | |
3424 | + continue; | |
4cd5ba0f | 3425 | + } |
4cd5ba0f | 3426 | + |
f33182aa | 3427 | + info->tstack = fp->types; |
3428 | + if (!coff_make_typed_symbol (info, &csymp, TS_NONE)) | |
3429 | + return FALSE; | |
4cd5ba0f | 3430 | + |
f33182aa | 3431 | + csymp->symbol.name = xstrdup (fp->name); |
3432 | + csymp->symbol.flags = BSF_NOT_AT_END; | |
3433 | + csymp->symbol.section = bfd_com_section_ptr; | |
3434 | + csymp->native->u.syment.n_sclass = sclass; | |
3435 | + csymp->symbol.value = isbitfield? fp->bitpos: fp->bitpos / 8; | |
3436 | + if (isbitfield) | |
4cd5ba0f | 3437 | + { |
f33182aa | 3438 | + csymp->native->u.syment.n_numaux = 1; |
3439 | + aux = &((csymp->native + 1)->u.auxent); | |
3440 | + aux->x_sym.x_misc.x_lnsz.x_size = fp->bitsize; | |
4cd5ba0f | 3441 | + } |
4cd5ba0f | 3442 | + |
f33182aa | 3443 | + coff_record_symbol (info, csymp); |
3444 | + | |
3445 | + fp->types = NULL; | |
3446 | + } | |
3447 | + | |
3448 | + info->tstack = savedtst; | |
3449 | + | |
3450 | + /* Record our endndx field for later fixing. */ | |
3451 | + fixp = (struct coff_fix_stack *) xmalloc (sizeof (struct coff_fix_stack)); | |
3452 | + fixp->native = scsymp->native + 1; /* points to first AUX */ | |
3453 | + fixp->next = NULL; | |
3454 | + if (info->fixes == NULL) | |
3455 | + info->fixes = fixp; | |
3456 | + else | |
3457 | + { | |
3458 | + for (ofp = info->fixes; ofp->next != NULL;) | |
3459 | + ofp = ofp->next; | |
3460 | + ofp->next = fixp; | |
4cd5ba0f | 3461 | + } |
f33182aa | 3462 | + |
3463 | + coff_record_symbol (info, ecsymp); | |
3464 | + info->flags |= COFF_FL_FIX_ENDNDX; | |
3465 | + | |
4cd5ba0f ER |
3466 | + return TRUE; |
3467 | +} | |
3468 | + | |
f33182aa | 3469 | +static bfd_boolean coff_emit_enum (info, tst, ehash) |
3470 | + struct coff_write_handle *info; | |
3471 | + struct coff_type_stack *tst; | |
3472 | + struct coff_enum_hash_entry *ehash; | |
4cd5ba0f | 3473 | +{ |
f33182aa | 3474 | + coff_symbol_type *csymp, *scsymp, *ecsymp; |
3475 | + union internal_auxent *aux; | |
3476 | + struct coff_fix_stack *fixp, *ofp; | |
3477 | + int i; | |
4cd5ba0f | 3478 | + |
f33182aa | 3479 | + if ((info->flags & (COFF_FL_AVR | COFF_FL_EXT_AVR)) == |
3480 | + COFF_FL_AVR) | |
3481 | + /* old AVR COFF doesn't support enum debugging */ | |
3482 | + return TRUE; | |
4cd5ba0f | 3483 | + |
f33182aa | 3484 | + /* Synthesize a new internal COFF symbol for the enum. */ |
3485 | + scsymp = (coff_symbol_type *) coff_bfd_make_debug_symbol (info->abfd, 0, 0); | |
3486 | + if (scsymp == NULL) | |
3487 | + return FALSE; | |
4cd5ba0f | 3488 | + |
f33182aa | 3489 | + if (tst->u.ts_enum.tagismalloced) |
3490 | + scsymp->symbol.name = xstrdup (tst->u.ts_enum.tag.malloctag); | |
4cd5ba0f | 3491 | + else |
f33182aa | 3492 | + scsymp->symbol.name = tst->u.ts_enum.tag.fixtag; |
3493 | + scsymp->symbol.flags = BSF_NOT_AT_END; | |
3494 | + scsymp->symbol.section = bfd_und_section_ptr; | |
3495 | + scsymp->native->u.syment.n_sclass = C_ENTAG; | |
3496 | + scsymp->native->u.syment.n_type = T_ENUM; | |
3497 | + scsymp->native->u.syment.n_numaux = 1; | |
3498 | + scsymp->symbol.udata.p = NULL; | |
3499 | + scsymp->symbol.value = 0; | |
3500 | + | |
3501 | + ehash->native = scsymp->native; | |
3502 | + | |
3503 | + /* Synthesize a new internal COFF symbol for the end of struct/union. */ | |
3504 | + ecsymp = (coff_symbol_type *) coff_bfd_make_debug_symbol (info->abfd, 0, 0); | |
3505 | + if (ecsymp == NULL) | |
4cd5ba0f | 3506 | + return FALSE; |
4cd5ba0f | 3507 | + |
f33182aa | 3508 | + ecsymp->symbol.name = ".eos"; |
3509 | + ecsymp->symbol.flags = BSF_NOT_AT_END; | |
3510 | + /* We need to use the com section here since bfd/coffgen.c | |
3511 | + translates this into an N_UNDEF one without clobbering the | |
3512 | + value. */ | |
3513 | + ecsymp->symbol.section = bfd_com_section_ptr; | |
3514 | + ecsymp->native->u.syment.n_sclass = C_EOS; | |
3515 | + ecsymp->symbol.udata.p = NULL; | |
3516 | + ecsymp->symbol.value = info->enumsize; | |
3517 | + ecsymp->native->u.syment.n_numaux = 1; | |
3518 | + (ecsymp->native + 1)->fix_tag = 1; | |
3519 | + aux = &((ecsymp->native + 1)->u.auxent); | |
3520 | + aux->x_sym.x_tagndx.p = scsymp->native; | |
3521 | + aux->x_sym.x_misc.x_lnsz.x_size = info->enumsize; | |
4cd5ba0f | 3522 | + |
f33182aa | 3523 | + coff_record_symbol (info, scsymp); |
4cd5ba0f | 3524 | + |
f33182aa | 3525 | + for (i = 0;; i++) |
3526 | + { | |
3527 | + const char *name = tst->u.ts_enum.names[i]; | |
3528 | + if (name == NULL) | |
3529 | + break; | |
3530 | + | |
3531 | + /* Synthesize a new internal COFF symbol for the enum. */ | |
3532 | + csymp = (coff_symbol_type *) coff_bfd_make_debug_symbol (info->abfd, 0, 0); | |
3533 | + if (csymp == NULL) | |
4cd5ba0f ER |
3534 | + return FALSE; |
3535 | + | |
3536 | + csymp->symbol.name = xstrdup (name); | |
3537 | + csymp->symbol.flags = BSF_NOT_AT_END; | |
3538 | + csymp->symbol.section = bfd_com_section_ptr; | |
f33182aa | 3539 | + csymp->native->u.syment.n_sclass = C_MOE; |
3540 | + csymp->symbol.udata.p = NULL; | |
3541 | + csymp->symbol.value = tst->u.ts_enum.vals[i]; | |
4cd5ba0f ER |
3542 | + |
3543 | + coff_record_symbol (info, csymp); | |
3544 | + } | |
4cd5ba0f | 3545 | + |
f33182aa | 3546 | + /* Record our endndx field for later fixing. */ |
3547 | + fixp = (struct coff_fix_stack *) xmalloc (sizeof (struct coff_fix_stack)); | |
3548 | + fixp->native = scsymp->native + 1; /* points to first AUX */ | |
3549 | + fixp->next = NULL; | |
3550 | + if (info->fixes == NULL) | |
3551 | + info->fixes = fixp; | |
3552 | + else | |
4cd5ba0f | 3553 | + { |
f33182aa | 3554 | + for (ofp = info->fixes; ofp->next != NULL;) |
3555 | + ofp = ofp->next; | |
3556 | + ofp->next = fixp; | |
4cd5ba0f ER |
3557 | + } |
3558 | + | |
f33182aa | 3559 | + coff_record_symbol (info, ecsymp); |
3560 | + info->flags |= COFF_FL_FIX_ENDNDX; | |
4cd5ba0f ER |
3561 | + |
3562 | + return TRUE; | |
3563 | +} | |
3564 | + | |
f33182aa | 3565 | +/* Emit a non-debugging symbol that came from the input symbol table, |
3566 | + and has not been claimed by one of the debugging symbols. */ | |
4cd5ba0f | 3567 | +static bfd_boolean |
f33182aa | 3568 | +coff_emit_ndebug_sym (info, osymp, localp) |
3569 | + struct coff_write_handle *info; | |
3570 | + asymbol *osymp; | |
3571 | + bfd_boolean localp; | |
4cd5ba0f | 3572 | +{ |
f33182aa | 3573 | + coff_symbol_type *csymp; |
4cd5ba0f | 3574 | + |
f33182aa | 3575 | + /* Create new COFF symbol. */ |
3576 | + csymp = (coff_symbol_type *) coff_bfd_make_debug_symbol (info->abfd, 0, 0); | |
3577 | + if (csymp == NULL) | |
3578 | + return FALSE; | |
4cd5ba0f | 3579 | + |
f33182aa | 3580 | + csymp->symbol.name = xstrdup (osymp->name); |
3581 | + csymp->symbol.value = osymp->value; | |
3582 | + csymp->symbol.flags = localp? BSF_LOCAL: BSF_GLOBAL; | |
3583 | + csymp->symbol.section = osymp->section; | |
3584 | + csymp->symbol.udata.p = NULL; | |
3585 | + csymp->native->u.syment.n_sclass = localp? C_STAT: C_EXT; | |
3586 | + csymp->native->u.syment.n_type = T_NULL; | |
3587 | + | |
3588 | + coff_record_symbol (info, csymp); | |
4cd5ba0f ER |
3589 | + |
3590 | + return TRUE; | |
3591 | +} | |
f33182aa | 3592 | +\f |
3593 | +/* The general routine to write out COFF debugging information. This | |
3594 | + synthesizes and accumulates the COFF symbols. Actual symbol table | |
3595 | + output is performed later on by the BFD functions. ABFD is the BFD | |
3596 | + and DHANDLE is the handle for the debugging information. symcountp | |
3597 | + and symppp point to the incoming (parsed) symbol list on entry, and | |
3598 | + will be updated to point to the new symbol table's values upon | |
3599 | + exit. */ | |
4cd5ba0f | 3600 | + |
f33182aa | 3601 | +bfd_boolean |
3602 | +write_coff_debugging_info (abfd, dhandle, symcountp, symppp) | |
3603 | + bfd *abfd; | |
3604 | + PTR dhandle; | |
3605 | + long *symcountp; | |
3606 | + asymbol ***symppp; | |
4cd5ba0f | 3607 | +{ |
f33182aa | 3608 | + struct coff_write_handle info; |
3609 | + long i, l; | |
3610 | + asymbol *symp; | |
3611 | + struct coff_compilation_unit *up; | |
3612 | + coff_symbol_type *csymp; | |
4cd5ba0f | 3613 | + |
f33182aa | 3614 | + memset ((void *)&info, 0, sizeof info); |
4cd5ba0f | 3615 | + |
f33182aa | 3616 | + info.abfd = abfd; |
4cd5ba0f | 3617 | + |
f33182aa | 3618 | + info.pointersize = info.enumsize = 4; |
4cd5ba0f | 3619 | + |
f33182aa | 3620 | + switch (bfd_get_arch (abfd)) |
3621 | + { | |
3622 | + case bfd_arch_avr: | |
3623 | + info.flags |= COFF_FL_AVR; | |
3624 | + if (strcmp (abfd->xvec->name, "coff-ext-avr") == 0) | |
3625 | + info.flags |= COFF_FL_EXT_AVR; | |
3626 | + /* Fix the builtin type sizes. */ | |
3627 | + coff_predef_types[0].size = 2; /* sizeof(int) == 2 */ | |
3628 | + coff_predef_types[4].size = 4; /* sizeof(double) == 4 */ | |
3629 | + coff_predef_types[6].size = 2; /* sizeof(unsigned int) == 2 */ | |
3630 | + info.pointersize = info.enumsize = 2; | |
3631 | + break; | |
4cd5ba0f | 3632 | + |
f33182aa | 3633 | + default: |
3634 | + ; | |
3635 | + } | |
4cd5ba0f | 3636 | + |
f33182aa | 3637 | + coff_copy_symbols(&info, *symcountp, *symppp); |
4cd5ba0f | 3638 | + |
f33182aa | 3639 | + if (info.textsect == NULL) |
3640 | + { | |
3641 | + fprintf (stderr, _("Warning: no \"text\" section found in output file\n")); | |
3642 | + info.textsect = bfd_abs_section_ptr; | |
3643 | + } | |
3644 | + if (info.datasect == NULL) | |
3645 | + { | |
3646 | + fprintf (stderr, _("Warning: no \"data\" section found in output file\n")); | |
3647 | + info.datasect = bfd_abs_section_ptr; | |
3648 | + } | |
4cd5ba0f | 3649 | + |
f33182aa | 3650 | + if (! bfd_hash_table_init (&info.types.root, coff_name_type_newfunc, |
3651 | + sizeof(struct coff_name_type_hash_entry))) | |
3652 | + return FALSE; | |
4cd5ba0f | 3653 | + |
f33182aa | 3654 | + if (! bfd_hash_table_init (&info.structs.root, coff_struct_newfunc, |
3655 | + sizeof(struct coff_struct_hash_entry))) | |
3656 | + return FALSE; | |
4cd5ba0f | 3657 | + |
f33182aa | 3658 | + if (! bfd_hash_table_init (&info.enums.root, coff_enum_newfunc, |
3659 | + sizeof(struct coff_enum_hash_entry))) | |
3660 | + return FALSE; | |
4cd5ba0f | 3661 | + |
f33182aa | 3662 | + if (! debug_write (dhandle, &coff_fns, (PTR) &info)) |
3663 | + return FALSE; | |
4cd5ba0f | 3664 | + |
f33182aa | 3665 | + /* If there is an old compilation unit that has got any local |
3666 | + non-debugging symbols left over, send them out now. */ | |
3667 | + if (info.currentfile != NULL && info.currentfile->totsyms != 0) | |
3668 | + for (i = 0; i < info.currentfile->nsyms; i++) | |
3669 | + { | |
3670 | + up = info.currentfile; | |
4cd5ba0f | 3671 | + |
f33182aa | 3672 | + if (up->syms[i] != NULL) |
3673 | + { | |
3674 | + coff_emit_ndebug_sym (&info, up->syms[i], TRUE); | |
3675 | + up->syms[i] = NULL; | |
3676 | + up->totsyms--; | |
3677 | + } | |
3678 | + } | |
4cd5ba0f | 3679 | + |
f33182aa | 3680 | + /* See whether there are any non-debugging symbols left from the |
3681 | + input symbol table. First look at all local symbols which must | |
3682 | + be from entire compilation units we didn't see yet in the | |
3683 | + debugging information, because anything else has already been | |
3684 | + handled at the end of each compilation unit (like in the loop | |
3685 | + immediately above). Any compilation unit that has already been | |
3686 | + processed that way is supposed to have its "totsyms" counted down | |
3687 | + to 0 now, so we can skip them. | |
4cd5ba0f | 3688 | + |
f33182aa | 3689 | + Finally, put out all remaining global non-debugging symbols. */ |
3690 | + for (l = 0; l < info.nunits; l++) | |
3691 | + { | |
3692 | + const char *bn; | |
4cd5ba0f | 3693 | + |
f33182aa | 3694 | + up = info.units + l; |
3695 | + if (up->totsyms == 0) | |
3696 | + continue; | |
4cd5ba0f | 3697 | + |
f33182aa | 3698 | + /* Create COFF symbol for this compilation unit. */ |
3699 | + csymp = (coff_symbol_type *) coff_bfd_make_debug_symbol (info.abfd, 0, 0); | |
3700 | + if (csymp == NULL) | |
3701 | + return FALSE; | |
4cd5ba0f | 3702 | + |
f33182aa | 3703 | + bn = bu_basename (up->fname); |
4cd5ba0f | 3704 | + |
f33182aa | 3705 | + if (bfd_coff_long_filenames (info.abfd)) |
3706 | + csymp->symbol.name = up->fname; | |
3707 | + else | |
3708 | + csymp->symbol.name = bn; | |
4cd5ba0f | 3709 | + |
f33182aa | 3710 | + csymp->symbol.value = 0; |
3711 | + csymp->symbol.udata.p = NULL; | |
3712 | + csymp->native->u.syment.n_sclass = C_FILE; | |
3713 | + csymp->native->u.syment.n_numaux = 1; /* force filename into aux entry */ | |
3714 | + coff_record_symbol (&info, csymp); | |
3715 | + | |
3716 | + for (i = 0; i < up->nsyms; i++) | |
4cd5ba0f | 3717 | + { |
f33182aa | 3718 | + symp = up->syms[i]; |
3719 | + if (symp == NULL) | |
3720 | + continue; | |
3721 | + | |
3722 | + coff_emit_ndebug_sym (&info, symp, TRUE); | |
4cd5ba0f ER |
3723 | + } |
3724 | + } | |
3725 | + | |
f33182aa | 3726 | + for (i = 0; i < info.nglobals; i++) |
3727 | + { | |
3728 | + symp = info.globals[i]; | |
3729 | + if (symp == NULL) | |
3730 | + continue; | |
4cd5ba0f | 3731 | + |
f33182aa | 3732 | + coff_emit_ndebug_sym (&info, symp, FALSE); |
3733 | + } | |
4cd5ba0f | 3734 | + |
f33182aa | 3735 | + /* Fixup the AUX entries for the section symbols we have emitted |
3736 | + earlier (so they are guaranteed to be at the beginning of the | |
3737 | + symbol table). In particular, the line number count (which we | |
3738 | + only have for the text section) is known right now. */ | |
3739 | + for (i = 0; i < info.nsecsyms; i++) | |
3740 | + { | |
3741 | + union internal_auxent *aux; | |
4cd5ba0f | 3742 | + |
f33182aa | 3743 | + csymp = info.secsyms[i]; |
4cd5ba0f | 3744 | + |
f33182aa | 3745 | + aux = &((csymp->native + 1)->u.auxent); |
3746 | + aux->x_scn.x_scnlen = csymp->symbol.section->output_section->rawsize; | |
3747 | + aux->x_scn.x_nreloc = csymp->symbol.section->reloc_count; | |
3748 | + if (csymp->symbol.section == info.textsect) | |
3749 | + aux->x_scn.x_nlinno = info.totlnos; | |
3750 | + } | |
3751 | + free (info.secsyms); | |
4cd5ba0f | 3752 | + |
f33182aa | 3753 | + coff_name_type_hash_traverse (&info.types, coff_free_type_info, NULL); |
3754 | + bfd_hash_table_free (&info.types.root); | |
4cd5ba0f | 3755 | + |
f33182aa | 3756 | + coff_struct_hash_traverse (&info.structs, coff_free_struct_info, NULL); |
3757 | + bfd_hash_table_free (&info.structs.root); | |
4cd5ba0f | 3758 | + |
f33182aa | 3759 | + coff_enum_hash_traverse (&info.enums, coff_free_enum_info, NULL); |
3760 | + bfd_hash_table_free (&info.enums.root); | |
3761 | + | |
3762 | + /* FIXME: free all the other stuff remembered in "info". */ | |
3763 | + | |
3764 | + free (*symppp); | |
3765 | + | |
3766 | + *symcountp = info.nsyms; | |
3767 | + *symppp = (asymbol **)info.syms; | |
4cd5ba0f ER |
3768 | + |
3769 | + return TRUE; | |
3770 | +} | |
3771 | + | |
f33182aa | 3772 | +/* Start writing out information for a compilation unit. */ |
4cd5ba0f ER |
3773 | + |
3774 | +static bfd_boolean | |
f33182aa | 3775 | +coff_start_compilation_unit (p, filename) |
4cd5ba0f | 3776 | + PTR p; |
f33182aa | 3777 | + const char *filename; |
4cd5ba0f ER |
3778 | +{ |
3779 | + struct coff_write_handle *info = (struct coff_write_handle *) p; | |
f33182aa | 3780 | + long i; |
3781 | + const char *bn; | |
3782 | + bfd_boolean found; | |
4cd5ba0f | 3783 | + coff_symbol_type *csymp; |
4cd5ba0f ER |
3784 | + |
3785 | +#if COFF_DEBUG | |
f33182aa | 3786 | + printf ("coff_start_compilation_unit(%s)\n", filename); |
4cd5ba0f ER |
3787 | +#endif |
3788 | + | |
f33182aa | 3789 | + /* If there is an old compilation unit that has got any local |
3790 | + non-debugging symbols left over, send them out now. */ | |
3791 | + if (info->currentfile != NULL && info->currentfile->totsyms != 0) | |
3792 | + for (i = 0; i < info->currentfile->nsyms; i++) | |
3793 | + { | |
3794 | + struct coff_compilation_unit *up = info->currentfile; | |
4cd5ba0f | 3795 | + |
f33182aa | 3796 | + if (up->syms[i] != NULL) |
3797 | + { | |
3798 | + coff_emit_ndebug_sym (info, up->syms[i], TRUE); | |
3799 | + up->syms[i] = NULL; | |
3800 | + up->totsyms--; | |
3801 | + } | |
3802 | + } | |
4cd5ba0f | 3803 | + |
f33182aa | 3804 | + /* symtab (and thus COFF debugging) symbols can only transfer the |
3805 | + basename of the file, so strip the dirname */ | |
3806 | + bn = bu_basename (filename); | |
4cd5ba0f | 3807 | + |
f33182aa | 3808 | + for (i = 0, found = FALSE; i < info->nunits; i++) |
4cd5ba0f | 3809 | + { |
f33182aa | 3810 | + if (strcmp (info->units[i].fname, bn) == 0) |
3811 | + { | |
3812 | + info->currentfile = info->units + i; | |
3813 | + found = TRUE; | |
3814 | + break; | |
3815 | + } | |
3816 | + } | |
3817 | + if (!found) | |
3818 | + { | |
3819 | + fprintf(stderr, | |
3820 | + _("Warning: file %s not found in symbol table, ignoring\n"), | |
3821 | + filename); | |
3822 | + info->currentfile = NULL; | |
3823 | + return TRUE; | |
4cd5ba0f ER |
3824 | + } |
3825 | + | |
f33182aa | 3826 | + /* Synthesize a new internal COFF symbol. */ |
3827 | + csymp = (coff_symbol_type *) coff_bfd_make_debug_symbol (info->abfd, 0, 0); | |
3828 | + if (csymp == NULL) | |
3829 | + return FALSE; | |
4cd5ba0f | 3830 | + |
f33182aa | 3831 | + /* Note that coff_fix_symbol_name() [coffgen.c] will fix this for |
3832 | + us: the symbol name will be replaced by ".file", and the filename | |
3833 | + will be moved to the aux entries. We use the long name obtained | |
3834 | + from the debugging information (that includes the full path) if | |
3835 | + our COFF format supports long filenames, otherwise we only use | |
3836 | + the basename of the file. */ | |
3837 | + if (bfd_coff_long_filenames (info->abfd)) | |
3838 | + csymp->symbol.name = filename; | |
3839 | + else | |
3840 | + csymp->symbol.name = bn; | |
3841 | + csymp->symbol.value = 0; | |
3842 | + csymp->symbol.udata.p = NULL; | |
3843 | + csymp->native->u.syment.n_sclass = C_FILE; | |
3844 | + csymp->native->u.syment.n_numaux = 1; /* force filename into aux entry */ | |
3845 | + coff_record_symbol (info, csymp); | |
4cd5ba0f ER |
3846 | + |
3847 | + return TRUE; | |
3848 | +} | |
3849 | + | |
f33182aa | 3850 | +/* Start writing out information for a particular source file. */ |
4cd5ba0f ER |
3851 | + |
3852 | +static bfd_boolean | |
f33182aa | 3853 | +coff_start_source (p, filename) |
3854 | + PTR p ATTRIBUTE_UNUSED; | |
3855 | + const char *filename ATTRIBUTE_UNUSED; | |
4cd5ba0f | 3856 | +{ |
4cd5ba0f ER |
3857 | + |
3858 | +#if COFF_DEBUG | |
f33182aa | 3859 | + printf ("coff_start_source(%s)\n", filename); |
4cd5ba0f ER |
3860 | +#endif |
3861 | + | |
f33182aa | 3862 | + /* COFF cannot handle include filenames. */ |
4cd5ba0f | 3863 | + |
f33182aa | 3864 | + return TRUE; |
3865 | +} | |
4cd5ba0f | 3866 | + |
f33182aa | 3867 | +/* Push an empty type. This shouldn't normally happen. */ |
4cd5ba0f | 3868 | + |
f33182aa | 3869 | +static bfd_boolean |
3870 | +coff_empty_type (p) | |
3871 | + PTR p; | |
3872 | +{ | |
3873 | + struct coff_write_handle *info = (struct coff_write_handle *) p; | |
3874 | + struct coff_type_stack *tst; | |
4cd5ba0f | 3875 | + |
f33182aa | 3876 | +#if COFF_DEBUG |
3877 | + printf ("coff_empty_type()\n"); | |
3878 | +#endif | |
4cd5ba0f | 3879 | + |
f33182aa | 3880 | + coff_push_type (TS_EMPTY); |
4cd5ba0f ER |
3881 | + |
3882 | + return TRUE; | |
3883 | +} | |
3884 | + | |
f33182aa | 3885 | +/* Push a void type. */ |
4cd5ba0f ER |
3886 | + |
3887 | +static bfd_boolean | |
f33182aa | 3888 | +coff_void_type (p) |
4cd5ba0f | 3889 | + PTR p; |
4cd5ba0f ER |
3890 | +{ |
3891 | + struct coff_write_handle *info = (struct coff_write_handle *) p; | |
f33182aa | 3892 | + struct coff_type_stack *tst; |
4cd5ba0f ER |
3893 | + |
3894 | +#if COFF_DEBUG | |
f33182aa | 3895 | + printf ("coff_void_type()\n"); |
4cd5ba0f ER |
3896 | +#endif |
3897 | + | |
f33182aa | 3898 | + coff_push_type (TS_VOID); |
4cd5ba0f ER |
3899 | + |
3900 | + return TRUE; | |
3901 | +} | |
3902 | + | |
f33182aa | 3903 | +/* Push an integer type. */ |
4cd5ba0f ER |
3904 | + |
3905 | +static bfd_boolean | |
f33182aa | 3906 | +coff_int_type (p, size, unsignedp) |
4cd5ba0f | 3907 | + PTR p; |
f33182aa | 3908 | + unsigned int size; |
3909 | + bfd_boolean unsignedp; | |
4cd5ba0f ER |
3910 | +{ |
3911 | + struct coff_write_handle *info = (struct coff_write_handle *) p; | |
f33182aa | 3912 | + struct coff_type_stack *tst; |
4cd5ba0f ER |
3913 | + |
3914 | +#if COFF_DEBUG | |
f33182aa | 3915 | + printf ("coff_int_type(%d, %d)\n", size, unsignedp); |
4cd5ba0f ER |
3916 | +#endif |
3917 | + | |
f33182aa | 3918 | + coff_push_type (TS_INT); |
3919 | + tst->u.ts_int.size = size; | |
3920 | + tst->u.ts_int.isunsigned = unsignedp; | |
4cd5ba0f | 3921 | + |
f33182aa | 3922 | + return TRUE; |
3923 | +} | |
4cd5ba0f | 3924 | + |
f33182aa | 3925 | +/* Push a floating point type. */ |
4cd5ba0f | 3926 | + |
f33182aa | 3927 | +static bfd_boolean |
3928 | +coff_float_type (p, size) | |
3929 | + PTR p; | |
3930 | + unsigned int size; | |
3931 | +{ | |
3932 | + struct coff_write_handle *info = (struct coff_write_handle *) p; | |
3933 | + struct coff_type_stack *tst; | |
4cd5ba0f | 3934 | + |
f33182aa | 3935 | +#if COFF_DEBUG |
3936 | + printf ("coff_float_type(%d)\n", size); | |
3937 | +#endif | |
4cd5ba0f | 3938 | + |
f33182aa | 3939 | + coff_push_type (TS_FLOAT); |
3940 | + tst->u.ts_float.size = size; | |
4cd5ba0f ER |
3941 | + |
3942 | + return TRUE; | |
3943 | +} | |
3944 | + | |
f33182aa | 3945 | +/* Push a complex type. */ |
4cd5ba0f ER |
3946 | + |
3947 | +static bfd_boolean | |
f33182aa | 3948 | +coff_complex_type (p, size) |
4cd5ba0f | 3949 | + PTR p; |
f33182aa | 3950 | + unsigned int size ATTRIBUTE_UNUSED; |
4cd5ba0f ER |
3951 | +{ |
3952 | + struct coff_write_handle *info = (struct coff_write_handle *) p; | |
f33182aa | 3953 | + struct coff_type_stack *tst; |
4cd5ba0f ER |
3954 | + |
3955 | +#if COFF_DEBUG | |
f33182aa | 3956 | + printf ("coff_complex_type(%d)\n", size); |
4cd5ba0f ER |
3957 | +#endif |
3958 | + | |
f33182aa | 3959 | + coff_push_type (TS_COMPLEX); |
4cd5ba0f | 3960 | + |
f33182aa | 3961 | + return TRUE; |
3962 | +} | |
4cd5ba0f | 3963 | + |
f33182aa | 3964 | +/* Push a bfd_boolean type. */ |
4cd5ba0f | 3965 | + |
f33182aa | 3966 | +static bfd_boolean |
3967 | +coff_bool_type (p, size) | |
3968 | + PTR p; | |
3969 | + unsigned int size; | |
3970 | +{ | |
3971 | + struct coff_write_handle *info = (struct coff_write_handle *) p; | |
3972 | + struct coff_type_stack *tst; | |
4cd5ba0f | 3973 | + |
f33182aa | 3974 | +#if COFF_DEBUG |
3975 | + printf ("coff_bool_type(%d)\n", size); | |
3976 | +#endif | |
4cd5ba0f | 3977 | + |
f33182aa | 3978 | + coff_push_type (TS_INT); |
3979 | + tst->u.ts_int.size = size; | |
3980 | + tst->u.ts_int.isunsigned = TRUE; | |
4cd5ba0f ER |
3981 | + |
3982 | + return TRUE; | |
3983 | +} | |
4cd5ba0f | 3984 | + |
f33182aa | 3985 | +/* Push an enum type. */ |
4cd5ba0f | 3986 | + |
f33182aa | 3987 | +static bfd_boolean |
3988 | +coff_enum_type (p, tag, names, vals) | |
3989 | + PTR p; | |
3990 | + const char *tag; | |
3991 | + const char **names; | |
3992 | + bfd_signed_vma *vals; | |
3993 | +{ | |
3994 | + struct coff_write_handle *info = (struct coff_write_handle *) p; | |
3995 | + struct coff_type_stack *tst; | |
3996 | + char buf[20]; | |
4cd5ba0f | 3997 | + |
f33182aa | 3998 | +#if COFF_DEBUG |
3999 | + int idx; | |
4000 | + printf ("coff_enum_type(%s [", tag); | |
4001 | + for (idx = 0; names[idx] != NULL; idx++) | |
4002 | + printf ("%s -> %d, ", names[idx], (int)vals[idx]); | |
4003 | + printf ("])\n"); | |
4004 | +#endif | |
4cd5ba0f | 4005 | + |
f33182aa | 4006 | + coff_push_type (TS_ENUM); |
4cd5ba0f | 4007 | + |
f33182aa | 4008 | + if (tag == NULL) |
4009 | + { | |
4010 | + sprintf(buf, ".%dfake", info->nenums++); | |
4011 | + tst->u.ts_enum.tag.malloctag = xstrdup (buf); | |
4012 | + tst->u.ts_enum.tagismalloced = TRUE; | |
4013 | + } | |
4014 | + else | |
4015 | + tst->u.ts_enum.tag.fixtag = tag; | |
4016 | + tst->u.ts_enum.names = names; | |
4017 | + tst->u.ts_enum.vals = vals; | |
4cd5ba0f | 4018 | + |
f33182aa | 4019 | + return TRUE; |
4020 | +} | |
4cd5ba0f | 4021 | + |
f33182aa | 4022 | +/* Push a pointer type. */ |
4cd5ba0f | 4023 | + |
f33182aa | 4024 | +static bfd_boolean |
4025 | +coff_pointer_type (p) | |
4026 | + PTR p; | |
4027 | +{ | |
4028 | + struct coff_write_handle *info = (struct coff_write_handle *) p; | |
4029 | + struct coff_type_stack *tst; | |
4cd5ba0f | 4030 | + |
f33182aa | 4031 | +#if COFF_DEBUG |
4032 | + printf ("coff_pointer_type()\n"); | |
4033 | +#endif | |
4cd5ba0f | 4034 | + |
f33182aa | 4035 | + coff_push_type (TS_POINTER); |
4cd5ba0f | 4036 | + |
f33182aa | 4037 | + return TRUE; |
4038 | +} | |
4cd5ba0f | 4039 | + |
f33182aa | 4040 | +/* Push a function type. */ |
4cd5ba0f | 4041 | + |
f33182aa | 4042 | +static bfd_boolean |
4043 | +coff_function_type (p, argcount, varargs) | |
4044 | + PTR p; | |
4045 | + int argcount; | |
4046 | + bfd_boolean varargs ATTRIBUTE_UNUSED; | |
4cd5ba0f | 4047 | +{ |
f33182aa | 4048 | + struct coff_write_handle *info = (struct coff_write_handle *) p; |
4049 | + struct coff_type_stack *tst; | |
4cd5ba0f | 4050 | + |
f33182aa | 4051 | +#if COFF_DEBUG |
4052 | + printf ("coff_function_type(%d, %d)\n", argcount, varargs); | |
4053 | +#endif | |
4cd5ba0f | 4054 | + |
f33182aa | 4055 | + coff_push_type (TS_FUNC); |
4056 | + | |
4057 | + /* FIXME should properly discard function arguments */ | |
4058 | + if (argcount > -1) | |
4cd5ba0f | 4059 | + { |
f33182aa | 4060 | + fprintf (stderr, |
4061 | + _("coff_function_type() called with positive argcount\n")); | |
4062 | + return FALSE; | |
4cd5ba0f ER |
4063 | + } |
4064 | + | |
f33182aa | 4065 | + return TRUE; |
4066 | +} | |
4cd5ba0f | 4067 | + |
f33182aa | 4068 | +/* Push a reference type. */ |
4cd5ba0f | 4069 | + |
f33182aa | 4070 | +static bfd_boolean |
4071 | +coff_reference_type (p) | |
4072 | + PTR p; | |
4073 | +{ | |
4074 | + struct coff_write_handle *info = (struct coff_write_handle *) p; | |
4cd5ba0f | 4075 | + |
f33182aa | 4076 | +#if COFF_DEBUG |
4077 | + printf ("coff_reference_type()\n"); | |
4078 | +#endif | |
4cd5ba0f | 4079 | + |
f33182aa | 4080 | + coff_complain_unsupp (_("reference")); |
4cd5ba0f | 4081 | + |
f33182aa | 4082 | + return TRUE; |
4cd5ba0f ER |
4083 | +} |
4084 | + | |
f33182aa | 4085 | +/* Push a range type. */ |
4cd5ba0f | 4086 | + |
f33182aa | 4087 | +static bfd_boolean |
4088 | +coff_range_type (p, low, high) | |
4089 | + PTR p; | |
4090 | + bfd_signed_vma low ATTRIBUTE_UNUSED; | |
4091 | + bfd_signed_vma high ATTRIBUTE_UNUSED; | |
4cd5ba0f | 4092 | +{ |
f33182aa | 4093 | + struct coff_write_handle *info = (struct coff_write_handle *) p; |
4cd5ba0f | 4094 | + |
f33182aa | 4095 | +#if COFF_DEBUG |
4096 | + printf ("coff_range_type([%d..%d)\n", (int)low, (int)high); | |
4097 | +#endif | |
4cd5ba0f | 4098 | + |
f33182aa | 4099 | + coff_complain_unsupp (_("range")); |
4cd5ba0f | 4100 | + |
f33182aa | 4101 | + return TRUE; |
4102 | +} | |
4cd5ba0f | 4103 | + |
f33182aa | 4104 | +/* Push an array type. */ |
4cd5ba0f | 4105 | + |
f33182aa | 4106 | +static bfd_boolean |
4107 | +coff_array_type (p, low, high, stringp) | |
4108 | + PTR p; | |
4109 | + bfd_signed_vma low; | |
4110 | + bfd_signed_vma high; | |
4111 | + bfd_boolean stringp; | |
4112 | +{ | |
4113 | + struct coff_write_handle *info = (struct coff_write_handle *) p; | |
4114 | + struct coff_type_stack *tst; | |
4cd5ba0f | 4115 | + |
f33182aa | 4116 | +#if COFF_DEBUG |
4117 | + printf ("coff_array_type([%d..%d], %d)\n", | |
4118 | + (int)low, (int)high, stringp); | |
4119 | +#endif | |
4cd5ba0f | 4120 | + |
f33182aa | 4121 | + /* Pop the range type, but ignore it. COFF doesn't use it. */ |
4122 | + coff_pop_type (); | |
4cd5ba0f | 4123 | + |
f33182aa | 4124 | + /* FIXME What to do here? */ |
4125 | + if (stringp) | |
4126 | + { | |
4127 | + fprintf(stderr, _("coff_array_type(): stringp == TRUE\n")); | |
4128 | + return FALSE; | |
4129 | + } | |
4130 | + | |
4131 | + coff_push_type (TS_ARRAY); | |
4132 | + tst->u.ts_array.low = low; | |
4133 | + tst->u.ts_array.high = high; | |
4134 | + | |
4135 | + return TRUE; | |
4136 | +} | |
4137 | + | |
4138 | +/* Push a set type. */ | |
4139 | + | |
4140 | +static bfd_boolean | |
4141 | +coff_set_type (p, bitstringp) | |
4142 | + PTR p; | |
4143 | + bfd_boolean bitstringp ATTRIBUTE_UNUSED; | |
4cd5ba0f | 4144 | +{ |
f33182aa | 4145 | + struct coff_write_handle *info = (struct coff_write_handle *) p; |
4cd5ba0f | 4146 | + |
f33182aa | 4147 | +#if COFF_DEBUG |
4148 | + printf ("coff_set_type(%d)\n", bitstringp); | |
4149 | +#endif | |
4cd5ba0f | 4150 | + |
f33182aa | 4151 | + coff_complain_unsupp (_("set")); |
4cd5ba0f | 4152 | + |
f33182aa | 4153 | + return TRUE; |
4154 | +} | |
4cd5ba0f | 4155 | + |
f33182aa | 4156 | +/* Push an offset type. */ |
4cd5ba0f | 4157 | + |
f33182aa | 4158 | +static bfd_boolean |
4159 | +coff_offset_type (p) | |
4160 | + PTR p; | |
4161 | +{ | |
4162 | + struct coff_write_handle *info = (struct coff_write_handle *) p; | |
4cd5ba0f | 4163 | + |
f33182aa | 4164 | +#if COFF_DEBUG |
4165 | + printf ("coff_offset_type()\n"); | |
4166 | +#endif | |
4cd5ba0f | 4167 | + |
f33182aa | 4168 | + coff_complain_unsupp (_("offset")); |
4cd5ba0f | 4169 | + |
f33182aa | 4170 | + return TRUE; |
4cd5ba0f ER |
4171 | +} |
4172 | + | |
f33182aa | 4173 | +/* Push a method type. */ |
4cd5ba0f | 4174 | + |
f33182aa | 4175 | +static bfd_boolean |
4176 | +coff_method_type (p, domainp, argcount, varargs) | |
4177 | + PTR p; | |
4178 | + bfd_boolean domainp ATTRIBUTE_UNUSED; | |
4179 | + int argcount ATTRIBUTE_UNUSED; | |
4180 | + bfd_boolean varargs ATTRIBUTE_UNUSED; | |
4cd5ba0f | 4181 | +{ |
f33182aa | 4182 | + struct coff_write_handle *info = (struct coff_write_handle *) p; |
4cd5ba0f | 4183 | + |
f33182aa | 4184 | +#if COFF_DEBUG |
4185 | + printf ("coff_method_type(%d, %d, %d)\n", | |
4186 | + domainp, argcount, varargs); | |
4187 | +#endif | |
4cd5ba0f | 4188 | + |
f33182aa | 4189 | + coff_complain_unsupp (_("method")); |
4cd5ba0f | 4190 | + |
f33182aa | 4191 | + return TRUE; |
4192 | +} | |
4cd5ba0f | 4193 | + |
f33182aa | 4194 | +/* Push a const version of a type. */ |
4cd5ba0f | 4195 | + |
f33182aa | 4196 | +static bfd_boolean |
4197 | +coff_const_type (p) | |
4198 | + PTR p ATTRIBUTE_UNUSED; | |
4cd5ba0f | 4199 | +{ |
4cd5ba0f | 4200 | + |
f33182aa | 4201 | +#if COFF_DEBUG |
4202 | + printf ("coff_const_type()\n"); | |
4203 | +#endif | |
4cd5ba0f | 4204 | + |
f33182aa | 4205 | + /* const modifier is ignored by COFF */ |
4cd5ba0f | 4206 | + |
f33182aa | 4207 | + return TRUE; |
4208 | +} | |
4cd5ba0f | 4209 | + |
f33182aa | 4210 | +/* Push a volatile version of a type. */ |
4cd5ba0f | 4211 | + |
f33182aa | 4212 | +static bfd_boolean |
4213 | +coff_volatile_type (p) | |
4214 | + PTR p ATTRIBUTE_UNUSED; | |
4215 | +{ | |
4cd5ba0f | 4216 | + |
f33182aa | 4217 | +#if COFF_DEBUG |
4218 | + printf ("coff_volatile_type()\n"); | |
4219 | +#endif | |
4cd5ba0f | 4220 | + |
f33182aa | 4221 | + /* volatile modifier is ignored by COFF */ |
4cd5ba0f | 4222 | + |
f33182aa | 4223 | + return TRUE; |
4224 | +} | |
4cd5ba0f | 4225 | + |
f33182aa | 4226 | +/* Start outputting a struct. */ |
4cd5ba0f | 4227 | + |
f33182aa | 4228 | +static bfd_boolean |
4229 | +coff_start_struct_type (p, tag, id, structp, size) | |
4230 | + PTR p; | |
4231 | + const char *tag; | |
4232 | + unsigned int id; | |
4233 | + bfd_boolean structp; | |
4234 | + unsigned int size; | |
4235 | +{ | |
4236 | + struct coff_write_handle *info = (struct coff_write_handle *) p; | |
4237 | + struct coff_type_stack *tst, *savedts; | |
4238 | + struct coff_struct_hash_entry *shash; | |
4239 | + char buf[20]; | |
4240 | + const char *name; | |
4cd5ba0f | 4241 | + |
f33182aa | 4242 | +#if COFF_DEBUG |
4243 | + printf ("coff_start_struct_type(%s, %d, %d, %d)\n", | |
4244 | + tag, id, structp, size); | |
4245 | +#endif | |
4246 | + | |
4247 | + savedts = info->tstack; | |
4248 | + info->tstack = NULL; | |
4249 | + | |
4250 | + coff_push_type (TS_STRUCT); | |
4251 | + | |
4252 | + if (tag == NULL) | |
4253 | + { | |
4254 | + sprintf(buf, ".%dfake", id); | |
4255 | + name = tst->u.ts_struct.tag.malloctag = xstrdup (buf); | |
4256 | + tst->u.ts_struct.tagismalloced = TRUE; | |
4257 | + } | |
4258 | + else | |
4259 | + name = tst->u.ts_struct.tag.fixtag = tag; | |
4260 | + tst->u.ts_struct.id = id; | |
4261 | + tst->u.ts_struct.isstruct = structp; | |
4262 | + tst->u.ts_struct.size = size; | |
4263 | + tst->u.ts_struct.savedts = savedts; | |
4264 | + | |
4265 | + shash = coff_struct_hash_lookup (&info->structs, name, FALSE, FALSE); | |
4266 | + if (shash != NULL && shash->types != NULL) | |
4267 | + { | |
4268 | +#if COFF_DEBUG | |
4269 | + printf ("new %s definition for %s\n", | |
4270 | + tst->u.ts_struct.isstruct? "struct": "union", name); | |
4271 | +#endif | |
4272 | + coff_free_struct_info (shash, NULL); | |
4273 | + shash->types = NULL; | |
4274 | + shash->emitted = FALSE; | |
4cd5ba0f | 4275 | + } |
f33182aa | 4276 | + else |
4277 | + (void)coff_struct_hash_lookup (&info->structs, name, | |
4278 | + TRUE, tst->u.ts_struct.tagismalloced); | |
4279 | + | |
4280 | + return TRUE; | |
4cd5ba0f ER |
4281 | +} |
4282 | + | |
f33182aa | 4283 | +/* Add a field to a struct. */ |
4284 | + | |
4285 | +static bfd_boolean | |
4286 | +coff_struct_field (p, name, bitpos, bitsize, visibility) | |
4287 | + PTR p; | |
4288 | + const char *name; | |
4289 | + bfd_vma bitpos; | |
4290 | + bfd_vma bitsize; | |
4291 | + enum debug_visibility visibility; | |
4cd5ba0f | 4292 | +{ |
f33182aa | 4293 | + struct coff_write_handle *info = (struct coff_write_handle *) p; |
4294 | + struct coff_type_stack *tst, *otst; | |
4295 | + struct coff_struct_fields *fp; | |
4296 | + struct coff_struct_hash_entry *shash; | |
4297 | + struct coff_enum_hash_entry *ehash; | |
4298 | + const char *tag; | |
4cd5ba0f | 4299 | + |
f33182aa | 4300 | +#if COFF_DEBUG |
4301 | + printf ("coff_struct_field(%s, %d, %d, %d)\n", | |
4302 | + name, (int)bitpos, (int)bitsize, (int)visibility); | |
4303 | +#endif | |
4cd5ba0f | 4304 | + |
f33182aa | 4305 | + /* Find the last element on the type stack. */ |
4306 | + assert (info->tstack != NULL); | |
4307 | + for (tst = info->tstack, otst = NULL; tst->next != NULL;) | |
4cd5ba0f | 4308 | + { |
f33182aa | 4309 | + otst = tst; |
4310 | + tst = tst->next; | |
4311 | + } | |
4312 | + if (otst != NULL) | |
4313 | + otst->next = NULL; | |
4314 | + | |
4315 | + if (tst->tsk != TS_STRUCT) | |
4316 | + { | |
4317 | + fprintf (stderr, "coff_struct_field() not within structure definition\n"); | |
4318 | + return FALSE; | |
4319 | + } | |
4320 | + tst->u.ts_struct.fields = (struct coff_struct_fields *) | |
4321 | + xrealloc (tst->u.ts_struct.fields, | |
4322 | + ++tst->u.ts_struct.nfields * sizeof (struct coff_struct_fields)); | |
4323 | + fp = tst->u.ts_struct.fields + (tst->u.ts_struct.nfields - 1); | |
4324 | + fp->name = name; | |
4325 | + fp->bitpos = bitpos; | |
4326 | + fp->bitsize = bitsize; | |
4327 | + fp->visibility = visibility; | |
4328 | + otst = fp->types = info->tstack; | |
4329 | + while (otst->next != NULL) | |
4330 | + otst = otst->next; | |
4331 | + if (otst->tsk == TS_STRUCT && otst->u.ts_struct.shash == NULL) | |
4332 | + { | |
4333 | + if (otst->u.ts_struct.tagismalloced) | |
4334 | + tag = otst->u.ts_struct.tag.malloctag; | |
4335 | + else | |
4336 | + tag = otst->u.ts_struct.tag.fixtag; | |
4337 | + shash = coff_struct_hash_lookup (&info->structs, tag, FALSE, FALSE); | |
4338 | + assert (shash != NULL); | |
4339 | + if (!shash->emitted) | |
4cd5ba0f | 4340 | + { |
f33182aa | 4341 | + if (shash->types == NULL) |
4342 | + { | |
4343 | + shash->types = (struct coff_type_stack *) | |
4344 | + xmalloc (sizeof (struct coff_type_stack)); | |
4345 | + memcpy (shash->types, otst, sizeof (struct coff_type_stack)); | |
4346 | + } | |
4347 | + shash->emitted = TRUE; | |
4348 | + coff_emit_struct (info, otst, shash); | |
4cd5ba0f | 4349 | + } |
4cd5ba0f | 4350 | + } |
f33182aa | 4351 | + else if (otst->tsk == TS_ENUM) |
4cd5ba0f | 4352 | + { |
f33182aa | 4353 | + if (otst->u.ts_enum.tagismalloced) |
4354 | + tag = otst->u.ts_enum.tag.malloctag; | |
4355 | + else | |
4356 | + tag = otst->u.ts_enum.tag.fixtag; | |
4357 | + ehash = coff_enum_hash_lookup (&info->enums, tag, TRUE, FALSE); | |
4358 | + assert (ehash != NULL); | |
4359 | + if (!ehash->emitted) | |
4cd5ba0f | 4360 | + { |
f33182aa | 4361 | + if (ehash->types == NULL) |
4362 | + { | |
4363 | + ehash->types = (struct coff_type_stack *) | |
4364 | + xmalloc (sizeof (struct coff_type_stack)); | |
4365 | + memcpy (ehash->types, otst, sizeof (struct coff_type_stack)); | |
4366 | + } | |
4367 | + ehash->emitted = TRUE; | |
4368 | + coff_emit_enum (info, otst, ehash); | |
4cd5ba0f ER |
4369 | + } |
4370 | + } | |
f33182aa | 4371 | + |
4372 | + info->tstack = tst; | |
4373 | + | |
4374 | + return TRUE; | |
4cd5ba0f ER |
4375 | +} |
4376 | + | |
f33182aa | 4377 | +/* Finish up a struct. */ |
4378 | + | |
4379 | +static bfd_boolean | |
4380 | +coff_end_struct_type (p) | |
4381 | + PTR p; | |
4cd5ba0f | 4382 | +{ |
f33182aa | 4383 | + struct coff_write_handle *info = (struct coff_write_handle *) p; |
4384 | + struct coff_type_stack *tst, *savedts; | |
4385 | + | |
4386 | +#if COFF_DEBUG | |
4387 | + printf ("coff_end_struct_type()\n"); | |
4cd5ba0f | 4388 | +#endif |
4cd5ba0f | 4389 | + |
f33182aa | 4390 | + /* Our struct definition should be the only type stack element by |
4391 | + now. */ | |
4392 | + assert (info->tstack != NULL); | |
4393 | + tst = info->tstack; | |
4394 | + if (tst->tsk != TS_STRUCT || tst->next != NULL) | |
4395 | + { | |
4396 | + fprintf (stderr, "coff_struct_field() not within structure definition\n"); | |
4397 | + return FALSE; | |
4398 | + } | |
4cd5ba0f | 4399 | + |
f33182aa | 4400 | + /* Restore saved type stack, and push our now complete struct |
4401 | + definition on top. */ | |
4402 | + savedts = tst->u.ts_struct.savedts; | |
4403 | + tst->u.ts_struct.savedts = info->tstack; | |
4404 | + info->tstack = savedts; | |
4405 | + tst->next = info->tstack; | |
4406 | + info->tstack = tst; | |
4cd5ba0f | 4407 | + |
f33182aa | 4408 | + return TRUE; |
4409 | +} | |
4cd5ba0f | 4410 | + |
f33182aa | 4411 | +/* Start outputting a class. */ |
4cd5ba0f | 4412 | + |
f33182aa | 4413 | +static bfd_boolean |
4414 | +coff_start_class_type (p, tag, id, structp, size, vptr, ownvptr) | |
4415 | + PTR p; | |
4416 | + const char *tag ATTRIBUTE_UNUSED; | |
4417 | + unsigned int id ATTRIBUTE_UNUSED; | |
4418 | + bfd_boolean structp ATTRIBUTE_UNUSED; | |
4419 | + unsigned int size ATTRIBUTE_UNUSED; | |
4420 | + bfd_boolean vptr ATTRIBUTE_UNUSED; | |
4421 | + bfd_boolean ownvptr ATTRIBUTE_UNUSED; | |
4422 | +{ | |
4423 | + struct coff_write_handle *info = (struct coff_write_handle *) p; | |
4cd5ba0f | 4424 | + |
f33182aa | 4425 | +#if COFF_DEBUG |
4426 | + printf ("coff_start_class_type(%s, %d, %d, %d, %d, %d)\n", | |
4427 | + tag, id, structp, size, vptr, ownvptr); | |
4428 | +#endif | |
4cd5ba0f | 4429 | + |
f33182aa | 4430 | + coff_complain_unsupp (_("class")); |
4cd5ba0f | 4431 | + |
f33182aa | 4432 | + return TRUE; |
4433 | +} | |
4cd5ba0f | 4434 | + |
f33182aa | 4435 | +/* Add a static member to the class on the type stack. */ |
4cd5ba0f | 4436 | + |
f33182aa | 4437 | +static bfd_boolean |
4438 | +coff_class_static_member (p, name, physname, visibility) | |
4439 | + PTR p ATTRIBUTE_UNUSED; | |
4440 | + const char *name ATTRIBUTE_UNUSED; | |
4441 | + const char *physname ATTRIBUTE_UNUSED; | |
4442 | + enum debug_visibility visibility ATTRIBUTE_UNUSED; | |
4443 | +{ | |
4cd5ba0f | 4444 | + |
f33182aa | 4445 | +#if COFF_DEBUG |
4446 | + printf ("coff_class_static_member(%s, %s, %d)\n", | |
4447 | + name, physname, (int)visibility); | |
4448 | +#endif | |
4cd5ba0f | 4449 | + |
f33182aa | 4450 | + return TRUE; |
4451 | +} | |
4cd5ba0f | 4452 | + |
f33182aa | 4453 | +/* Add a base class to the class on the type stack. */ |
4cd5ba0f | 4454 | + |
f33182aa | 4455 | +static bfd_boolean |
4456 | +coff_class_baseclass (p, bitpos, virtual, visibility) | |
4457 | + PTR p ATTRIBUTE_UNUSED; | |
4458 | + bfd_vma bitpos ATTRIBUTE_UNUSED; | |
4459 | + bfd_boolean virtual ATTRIBUTE_UNUSED; | |
4460 | + enum debug_visibility visibility ATTRIBUTE_UNUSED; | |
4461 | +{ | |
4cd5ba0f | 4462 | + |
f33182aa | 4463 | +#if COFF_DEBUG |
4464 | + printf ("coff_class_baseclass(%d, %d, %d)\n", | |
4465 | + (int)bitpos, virtual, (int)visibility); | |
4466 | +#endif | |
4cd5ba0f | 4467 | + |
f33182aa | 4468 | + return TRUE; |
4469 | +} | |
4cd5ba0f | 4470 | + |
f33182aa | 4471 | +/* Start adding a method to the class on the type stack. */ |
4cd5ba0f | 4472 | + |
f33182aa | 4473 | +static bfd_boolean |
4474 | +coff_class_start_method (p, name) | |
4475 | + PTR p ATTRIBUTE_UNUSED; | |
4476 | + const char *name ATTRIBUTE_UNUSED; | |
4477 | +{ | |
4cd5ba0f | 4478 | + |
f33182aa | 4479 | +#if COFF_DEBUG |
4480 | + printf ("coff_class_start_method(%s)\n", name); | |
4481 | +#endif | |
4cd5ba0f | 4482 | + |
f33182aa | 4483 | + return TRUE; |
4484 | +} | |
4cd5ba0f | 4485 | + |
f33182aa | 4486 | +/* Add a variant to the current method. */ |
4487 | + | |
4488 | +static bfd_boolean | |
4489 | +coff_class_method_variant (p, physname, visibility, constp, volatilep, | |
4490 | + voffset, contextp) | |
4491 | + PTR p ATTRIBUTE_UNUSED; | |
4492 | + const char *physname ATTRIBUTE_UNUSED; | |
4493 | + enum debug_visibility visibility ATTRIBUTE_UNUSED; | |
4494 | + bfd_boolean constp ATTRIBUTE_UNUSED; | |
4495 | + bfd_boolean volatilep ATTRIBUTE_UNUSED; | |
4496 | + bfd_vma voffset ATTRIBUTE_UNUSED; | |
4497 | + bfd_boolean contextp ATTRIBUTE_UNUSED; | |
4cd5ba0f | 4498 | +{ |
4cd5ba0f | 4499 | + |
f33182aa | 4500 | +#if COFF_DEBUG |
4501 | + printf ("coff_class_method_variant(%s, %d, %d, %d, %d, %d)\n", | |
4502 | + physname, (int)visibility, constp, volatilep, | |
4503 | + (int)voffset, contextp); | |
4504 | +#endif | |
4cd5ba0f | 4505 | + |
f33182aa | 4506 | + return TRUE; |
4507 | +} | |
4cd5ba0f | 4508 | + |
f33182aa | 4509 | +/* Add a static variant to the current method. */ |
4cd5ba0f | 4510 | + |
f33182aa | 4511 | +static bfd_boolean |
4512 | +coff_class_static_method_variant (p, physname, visibility, constp, volatilep) | |
4513 | + PTR p ATTRIBUTE_UNUSED; | |
4514 | + const char *physname ATTRIBUTE_UNUSED; | |
4515 | + enum debug_visibility visibility ATTRIBUTE_UNUSED; | |
4516 | + bfd_boolean constp ATTRIBUTE_UNUSED; | |
4517 | + bfd_boolean volatilep ATTRIBUTE_UNUSED; | |
4518 | +{ | |
4cd5ba0f | 4519 | + |
f33182aa | 4520 | +#if COFF_DEBUG |
4521 | + printf ("coff_class_static_method_variant(%s, %d, %d, %d)\n", | |
4522 | + physname, (int)visibility, constp, volatilep); | |
4523 | +#endif | |
4cd5ba0f | 4524 | + |
f33182aa | 4525 | + return TRUE; |
4526 | +} | |
4cd5ba0f | 4527 | + |
f33182aa | 4528 | +/* Finish up a method. */ |
4cd5ba0f | 4529 | + |
f33182aa | 4530 | +static bfd_boolean |
4531 | +coff_class_end_method (p) | |
4532 | + PTR p ATTRIBUTE_UNUSED; | |
4533 | +{ | |
4cd5ba0f | 4534 | + |
f33182aa | 4535 | +#if COFF_DEBUG |
4536 | + printf ("coff_class_end_method()\n"); | |
4537 | +#endif | |
4538 | + | |
4539 | + return TRUE; | |
4cd5ba0f ER |
4540 | +} |
4541 | + | |
f33182aa | 4542 | +/* Finish up a class. */ |
4543 | + | |
4544 | +static bfd_boolean | |
4545 | +coff_end_class_type (p) | |
4546 | + PTR p ATTRIBUTE_UNUSED; | |
4547 | +{ | |
4548 | + | |
4549 | +#if COFF_DEBUG | |
4550 | + printf ("coff_end_class_type()\n"); | |
4cd5ba0f ER |
4551 | +#endif |
4552 | + | |
f33182aa | 4553 | + return TRUE; |
4554 | +} | |
4555 | + | |
4556 | +/* Push a typedef which was previously defined. */ | |
4557 | + | |
4558 | +static bfd_boolean | |
4559 | +coff_typedef_type (p, name) | |
4560 | + PTR p; | |
4561 | + const char *name; | |
4cd5ba0f | 4562 | +{ |
f33182aa | 4563 | + struct coff_write_handle *info = (struct coff_write_handle *) p; |
4564 | + struct coff_name_type_hash_entry *nthash; | |
4565 | + struct coff_type_stack *tst, *newchain, *newst, *temp; | |
4cd5ba0f | 4566 | + |
f33182aa | 4567 | +#if COFF_DEBUG |
4568 | + printf ("coff_typedef_type(%s)\n", name); | |
4569 | +#endif | |
4cd5ba0f | 4570 | + |
f33182aa | 4571 | + nthash = coff_name_type_hash_lookup (&info->types, name, FALSE, FALSE); |
4cd5ba0f | 4572 | + |
f33182aa | 4573 | + /* nthash should never be NULL, since that would imply that the |
4574 | + generic debugging code has asked for a typedef which it has not | |
4575 | + yet defined. */ | |
4576 | + assert (nthash != NULL); | |
4cd5ba0f | 4577 | + |
f33182aa | 4578 | + /* Just push the entire type stack snapshot we've got on top of the |
4579 | + existing typestack. See coff_typdef() below for how this | |
4580 | + works. We need to copy over each element however, since anybody | |
4581 | + popping elements off the typestack is supposed to free() each of | |
4582 | + them. */ | |
4cd5ba0f | 4583 | + |
f33182aa | 4584 | + for (tst = nthash->types, temp = newst = newchain = NULL; tst != NULL;) |
4cd5ba0f | 4585 | + { |
f33182aa | 4586 | + temp = newst; |
4587 | + newst = (struct coff_type_stack *) xmalloc (sizeof (*newst)); | |
4588 | + if (newchain == NULL) | |
4589 | + newchain = newst; | |
4590 | + memcpy (newst, tst, sizeof (*newst)); | |
4591 | + if (temp != NULL) | |
4592 | + temp->next = newst; | |
4cd5ba0f | 4593 | + |
f33182aa | 4594 | + tst = tst->next; |
4cd5ba0f | 4595 | + } |
f33182aa | 4596 | + newst->next = info->tstack; |
4597 | + info->tstack = newchain; | |
4cd5ba0f | 4598 | + |
f33182aa | 4599 | + return TRUE; |
4cd5ba0f ER |
4600 | +} |
4601 | + | |
f33182aa | 4602 | +/* Push a struct, union or class tag. */ |
4cd5ba0f | 4603 | + |
f33182aa | 4604 | +static bfd_boolean |
4605 | +coff_tag_type (p, name, id, kind) | |
4606 | + PTR p; | |
4607 | + const char *name; | |
4608 | + unsigned int id ATTRIBUTE_UNUSED; | |
4609 | + enum debug_type_kind kind; | |
4cd5ba0f | 4610 | +{ |
f33182aa | 4611 | + struct coff_write_handle *info = (struct coff_write_handle *) p; |
4612 | + struct coff_type_stack *tst, *newchain, *newst, *temp; | |
4613 | + struct coff_struct_hash_entry *shash; | |
4614 | + struct coff_enum_hash_entry *ehash; | |
4615 | + char buf[20]; | |
4616 | + bfd_boolean needcopy = FALSE; | |
4617 | + bfd_boolean isstruct = TRUE; | |
4cd5ba0f | 4618 | + |
f33182aa | 4619 | +#if COFF_DEBUG |
4620 | + printf ("coff_tag_type(%s, %d, %d)\n", | |
4621 | + name, id, kind); | |
4cd5ba0f | 4622 | +#endif |
4cd5ba0f | 4623 | + |
f33182aa | 4624 | + if (name == NULL) |
4625 | + { | |
4626 | + sprintf(buf, ".%dfake", id); | |
4627 | + needcopy = TRUE; | |
4628 | + } | |
4cd5ba0f | 4629 | + |
f33182aa | 4630 | + switch (kind) |
4631 | + { | |
4632 | + case DEBUG_KIND_UNION: | |
4633 | + case DEBUG_KIND_UNION_CLASS: | |
4634 | + isstruct = FALSE; | |
4635 | + /* FALLTHROUGH */ | |
4636 | + case DEBUG_KIND_STRUCT: | |
4637 | + case DEBUG_KIND_CLASS: | |
4638 | + shash = coff_struct_hash_lookup (&info->structs, | |
4639 | + name == NULL? buf: name, TRUE, needcopy); | |
4640 | + assert (shash != NULL); | |
4641 | + tst = shash->types; | |
4642 | + if (tst == NULL) | |
4643 | + { | |
4644 | + /* This is a reference to a tag that has not yet been | |
4645 | + defined (i. e., a forward reference). Synthesize a | |
4646 | + ts_struct entry by now, and mark it for later fixup. */ | |
4647 | + tst = (struct coff_type_stack *) xmalloc (sizeof *tst); | |
4648 | + memset (tst, 0, sizeof *tst); | |
4649 | + tst->tsk = TS_STRUCT; | |
4650 | + tst->u.ts_struct.isstruct = isstruct; | |
4651 | + tst->u.ts_struct.shash = shash; | |
4652 | + } | |
4653 | + docopystack: | |
4654 | + /* Just push the entire type stack snapshot we've got on top of the | |
4655 | + existing typestack. See coff_typdef() below for how this | |
4656 | + works. We need to copy over each element however, since anybody | |
4657 | + popping elements off the typestack is supposed to free() each of | |
4658 | + them. */ | |
4659 | + for (temp = newst = newchain = NULL; tst != NULL;) | |
4660 | + { | |
4661 | + temp = newst; | |
4662 | + newst = (struct coff_type_stack *) xmalloc (sizeof (*newst)); | |
4663 | + if (newchain == NULL) | |
4664 | + newchain = newst; | |
4665 | + memcpy (newst, tst, sizeof (*newst)); | |
4666 | + if (temp != NULL) | |
4667 | + temp->next = newst; | |
4cd5ba0f | 4668 | + |
f33182aa | 4669 | + tst = tst->next; |
4670 | + } | |
4671 | + if (newst) | |
4672 | + { | |
4673 | + newst->next = info->tstack; | |
4674 | + info->tstack = newchain; | |
4675 | + } | |
4676 | + break; | |
4cd5ba0f | 4677 | + |
f33182aa | 4678 | + case DEBUG_KIND_ENUM: |
4679 | + ehash = coff_enum_hash_lookup (&info->enums, | |
4680 | + name == NULL? buf: name, TRUE, needcopy); | |
4681 | + assert (ehash != NULL); | |
4682 | + tst = ehash->types; | |
4683 | + if (tst == NULL) | |
4684 | + { | |
4685 | + /* This is a reference to a tag that has not yet been | |
4686 | + defined (i. e., a forward reference). Synthesize a | |
4687 | + ts_enum entry by now, and mark it for later fixup. */ | |
4688 | + tst = (struct coff_type_stack *) xmalloc (sizeof *tst); | |
4689 | + memset (tst, 0, sizeof *tst); | |
4690 | + tst->tsk = TS_ENUM; | |
4691 | + tst->u.ts_enum.ehash = ehash; | |
4692 | + } | |
4693 | + goto docopystack; | |
4cd5ba0f | 4694 | + |
f33182aa | 4695 | + default: |
4696 | + fprintf (stderr, _("illegal kind %d in coff_tag_type()\n"), | |
4697 | + (int)kind); | |
4698 | + return FALSE; | |
4699 | + } | |
4700 | + return TRUE; | |
4701 | +} | |
4cd5ba0f | 4702 | + |
f33182aa | 4703 | +/* Define a typedef. */ |
4cd5ba0f | 4704 | + |
f33182aa | 4705 | +static bfd_boolean |
4706 | +coff_typdef (p, name) | |
4707 | + PTR p; | |
4708 | + const char *name; | |
4709 | +{ | |
4710 | + struct coff_write_handle *info = (struct coff_write_handle *) p; | |
4711 | + struct coff_name_type_hash_entry *nthash; | |
4cd5ba0f | 4712 | + |
f33182aa | 4713 | +#if COFF_DEBUG |
4714 | + printf ("coff_typdef(%s)\n", name); | |
4cd5ba0f ER |
4715 | +#endif |
4716 | + | |
f33182aa | 4717 | + /* COFF cannot really handle typedefs. While there is the option to |
4718 | + mark a symbol using the storage class C_TPDEF (so the COFF reader | |
4719 | + will know that name), there is no way to place a reference to | |
4720 | + that typedef into the just 16 bits COFF reserves for all of its | |
4721 | + type information. Thus, any use of the typedef must always fully | |
4722 | + dereference the typedef again. We do this by "snapshotting" the | |
4723 | + current type stack under the name of our typedef, and later on, | |
4724 | + when BFD debugging tells us to make use of the typedef (in | |
4725 | + coff_typedef_type()), we just look it up, and push all we've got | |
4726 | + completely onto the type stack again. */ | |
4cd5ba0f | 4727 | + |
f33182aa | 4728 | + if (info->tstack == NULL) |
4729 | + { | |
4730 | + fprintf (stderr, _("coff_typdef() on an empty type stack\n")); | |
4731 | + return FALSE; | |
4732 | + } | |
4733 | + | |
4734 | + nthash = coff_name_type_hash_lookup (&info->types, name, FALSE, FALSE); | |
4735 | + if (nthash != NULL) | |
4736 | + { | |
4737 | +#if COFF_DEBUG | |
4738 | + printf ("new typedef for %s\n", name); | |
4cd5ba0f | 4739 | +#endif |
f33182aa | 4740 | + coff_free_type_info (nthash, NULL); |
4741 | + } | |
4742 | + else | |
4743 | + nthash = coff_name_type_hash_lookup (&info->types, name, TRUE, FALSE); | |
4744 | + if (nthash == NULL) | |
4745 | + return FALSE; | |
4746 | + nthash->types = info->tstack; | |
4747 | + | |
4748 | + /* If the typestack is "sufficiently complex", emit a C_TPDEF symbol | |
4749 | + for it. We assume it to be sufficiently complex if there are | |
4750 | + either at least two derived types, or one derived type where the | |
4751 | + base type is not a simple scalar one. */ | |
4752 | + if (!nthash->emitted | |
4753 | + && info->tstack->next != NULL | |
4754 | + && (info->tstack->next->next != NULL || info->tstack->next->tsk >= TS_ENUM)) | |
4755 | + { | |
4756 | + struct coff_type_stack *newchain, *otst, *tst, *ntst; | |
4757 | + coff_symbol_type *csymp; | |
4758 | + | |
4759 | + nthash->emitted = TRUE; | |
4760 | + | |
4761 | + for (tst = info->tstack, newchain = otst = NULL; | |
4762 | + tst != NULL; | |
4763 | + tst = tst->next) | |
4cd5ba0f | 4764 | + { |
f33182aa | 4765 | + ntst = (struct coff_type_stack *) |
4766 | + xmalloc (sizeof (struct coff_type_stack)); | |
4767 | + memcpy (ntst, tst, sizeof (struct coff_type_stack)); | |
4768 | + if (otst == NULL) | |
4769 | + newchain = ntst; | |
4770 | + else | |
4771 | + otst->next = ntst; | |
4772 | + otst = ntst; | |
4cd5ba0f | 4773 | + } |
f33182aa | 4774 | + info->tstack = newchain; |
4775 | + if (!coff_make_typed_symbol (info, &csymp, TS_NONE)) | |
4776 | + return FALSE; | |
4777 | + | |
4778 | + csymp->symbol.name = xstrdup (name); | |
4779 | + csymp->symbol.flags = BSF_NOT_AT_END; | |
4780 | + csymp->symbol.section = bfd_com_section_ptr; | |
4781 | + csymp->native->u.syment.n_sclass = C_TPDEF; | |
4782 | + csymp->symbol.value = 0; | |
4783 | + | |
4784 | + coff_record_symbol (info, csymp); | |
4785 | + } | |
4786 | + info->tstack = NULL; | |
4787 | + | |
4788 | + return TRUE; | |
4789 | +} | |
4790 | + | |
4791 | +/* Define a tag. */ | |
4792 | + | |
4793 | +static bfd_boolean | |
4794 | +coff_tag (p, tag) | |
4795 | + PTR p; | |
4796 | + const char *tag; | |
4797 | +{ | |
4798 | + struct coff_write_handle *info = (struct coff_write_handle *) p; | |
4799 | + struct coff_type_stack *tst = NULL; | |
4800 | + struct coff_struct_hash_entry *shash; | |
4801 | + struct coff_enum_hash_entry *ehash; | |
4802 | + | |
4803 | + | |
4804 | +#if COFF_DEBUG | |
4805 | + printf ("coff_tag(%s)\n", tag); | |
4cd5ba0f | 4806 | +#endif |
f33182aa | 4807 | + |
4808 | + if (info->tstack == NULL) | |
4809 | + { | |
4810 | + fprintf (stderr, _("coff_tag() called on an empty typestack\n")); | |
4811 | + return FALSE; | |
4812 | + } | |
4813 | + | |
4814 | + switch (info->tstack->tsk) | |
4815 | + { | |
4816 | + case TS_STRUCT: | |
4817 | + shash = coff_struct_hash_lookup (&info->structs, tag, FALSE, FALSE); | |
4818 | + assert (shash != NULL); | |
4819 | + shash->types = info->tstack; | |
4820 | + info->tstack = NULL; | |
4821 | + break; | |
4822 | + | |
4823 | + case TS_ENUM: | |
4824 | + ehash = coff_enum_hash_lookup (&info->enums, tag, FALSE, FALSE); | |
4825 | + if (ehash != NULL && ehash->types != NULL) | |
4826 | + { | |
4827 | +#if COFF_DEBUG | |
4828 | + printf ("new enum definition for %s\n", tag); | |
4cd5ba0f | 4829 | +#endif |
f33182aa | 4830 | + coff_free_enum_info (ehash, NULL); |
4831 | + } | |
4832 | + else | |
4833 | + ehash = coff_enum_hash_lookup (&info->enums, tag, TRUE, FALSE); | |
4834 | + if (ehash == NULL) | |
4835 | + return FALSE; | |
4836 | + ehash->types = info->tstack; | |
4837 | + info->tstack = NULL; | |
4838 | + break; | |
4cd5ba0f | 4839 | + |
f33182aa | 4840 | + default: |
4841 | + fprintf (stderr, _("Illegal typestack (%d) in coff_tag()\n"), tst->tsk); | |
4842 | + return FALSE; | |
4843 | + } | |
4844 | + | |
4845 | + return TRUE; | |
4846 | +} | |
4847 | + | |
4848 | +/* Define an integer constant. */ | |
4849 | + | |
4850 | +static bfd_boolean | |
4851 | +coff_int_constant (p, name, val) | |
4852 | + PTR p; | |
4853 | + const char *name ATTRIBUTE_UNUSED; | |
4854 | + bfd_vma val ATTRIBUTE_UNUSED; | |
4855 | +{ | |
4856 | + struct coff_write_handle *info = (struct coff_write_handle *) p; | |
4857 | + | |
4858 | +#if COFF_DEBUG | |
4859 | + printf ("coff_int_constant(%s, %d)\n", name, (int)val); | |
4cd5ba0f | 4860 | +#endif |
f33182aa | 4861 | + |
4862 | + coff_complain_unsupp (_("int constant")); | |
4863 | + | |
4864 | + return TRUE; | |
4865 | +} | |
4866 | + | |
4867 | +/* Define a floating point constant. */ | |
4868 | + | |
4869 | +static bfd_boolean | |
4870 | +coff_float_constant (p, name, val) | |
4871 | + PTR p; | |
4872 | + const char *name ATTRIBUTE_UNUSED; | |
4873 | + double val ATTRIBUTE_UNUSED; | |
4874 | +{ | |
4875 | + struct coff_write_handle *info = (struct coff_write_handle *) p; | |
4876 | + | |
4877 | +#if COFF_DEBUG | |
4878 | + printf ("coff_float_constant(%s, %g)\n", name, val); | |
4879 | +#endif | |
4880 | + | |
4881 | + coff_complain_unsupp (_("float constant")); | |
4882 | + | |
4883 | + return TRUE; | |
4884 | +} | |
4885 | + | |
4886 | +/* Define a typed constant. */ | |
4887 | + | |
4888 | +static bfd_boolean | |
4889 | +coff_typed_constant (p, name, val) | |
4890 | + PTR p; | |
4891 | + const char *name ATTRIBUTE_UNUSED; | |
4892 | + bfd_vma val ATTRIBUTE_UNUSED; | |
4893 | +{ | |
4894 | + struct coff_write_handle *info = (struct coff_write_handle *) p; | |
4895 | + | |
4896 | +#if COFF_DEBUG | |
4897 | + printf ("coff_typed_constant(%s, %d)\n", name, (int)val); | |
4898 | +#endif | |
4899 | + | |
4900 | + coff_complain_unsupp (_("typed constant")); | |
4901 | + | |
4902 | + return TRUE; | |
4903 | +} | |
4904 | + | |
4905 | +/* Record a variable. */ | |
4906 | + | |
4907 | +static bfd_boolean | |
4908 | +coff_variable (p, name, kind, val) | |
4909 | + PTR p; | |
4910 | + const char *name; | |
4911 | + enum debug_var_kind kind; | |
4912 | + bfd_vma val; | |
4913 | +{ | |
4914 | + struct coff_write_handle *info = (struct coff_write_handle *) p; | |
4915 | + unsigned char class; | |
4916 | + asymbol *symp = NULL; | |
4917 | + coff_symbol_type *csymp; | |
4918 | + bfd_boolean global = FALSE; | |
4919 | + flagword flags = BSF_LOCAL; | |
4920 | + bfd_vma vmadiff = 0; | |
4921 | + | |
4922 | +#if COFF_DEBUG | |
4923 | + printf ("coff_variable(%s, %d, %d)\n", | |
4924 | + name, (int)kind, (int)val); | |
4925 | +#endif | |
4926 | + | |
4927 | + switch (kind) | |
4928 | + { | |
4929 | + default: | |
4930 | + abort (); | |
4931 | + | |
4932 | + case DEBUG_GLOBAL: | |
4933 | + flags = BSF_GLOBAL; | |
4934 | + global = TRUE; | |
4935 | + /* AVR COFF historically used C_EXTDEF for global variables, and | |
4936 | + C_EXT for global functions. Since some AVR COFF consumers | |
4937 | + apparently depend on this, we mimic this behaviour as | |
4938 | + well. */ | |
4939 | + class = info->flags & COFF_FL_AVR? C_EXTDEF: C_EXT; | |
4940 | + break; | |
4941 | + | |
4942 | + case DEBUG_STATIC: | |
4943 | + case DEBUG_LOCAL_STATIC: | |
4944 | + class = C_STAT; | |
4945 | + break; | |
4946 | + | |
4947 | + case DEBUG_LOCAL: | |
4948 | + class = C_AUTO; | |
4949 | + break; | |
4950 | + | |
4951 | + case DEBUG_REGISTER: | |
4952 | + class = C_REG; | |
4953 | + break; | |
4954 | + } | |
4955 | + | |
4956 | + if (!coff_make_typed_symbol (info, &csymp, TS_NONE)) | |
4957 | + return FALSE; | |
4958 | + | |
4959 | + if (class == C_REG && (info->flags & COFF_FL_AVR) != 0) | |
4960 | + { | |
4961 | + struct coff_private_symdata *priv = (struct coff_private_symdata *) | |
4962 | + csymp->symbol.udata.p; | |
4963 | + val = coff_fixup_avr_register (val, priv->size * 8); | |
4964 | + } | |
4965 | + | |
4966 | + csymp->symbol.name = name; | |
4967 | + csymp->symbol.flags = flags; /* Note: this clears BSF_DEBUGGING. */ | |
4968 | + | |
4969 | + /* Match the debugging symbol against the input symtab symbols. If | |
4970 | + we found one, use the section information from it. Otherwise, we | |
4971 | + are lost here and just use the absolute section that was | |
4972 | + predeclared by coff_bfd_make_debug_symbol(). C_REG and C_AUTO | |
4973 | + symbols (which we do not attempt to lookup in the symtab symbols | |
4974 | + at all) go into the ABS section anyway. */ | |
4975 | + if (class != C_REG && class != C_AUTO) | |
4976 | + { | |
4977 | + symp = coff_find_symbol (info, name, FALSE, global); | |
4978 | + if (symp) | |
4979 | + { | |
4980 | + csymp->symbol.section = symp->section; | |
4981 | + vmadiff = symp->section->vma; | |
4982 | + } | |
4983 | + } | |
4984 | + | |
4985 | + /* Symbols are relative to section vma. */ | |
4986 | + csymp->symbol.value = val - vmadiff; | |
4987 | + csymp->native->u.syment.n_sclass = class; | |
4988 | + coff_record_symbol (info, csymp); | |
4989 | + | |
4990 | + return TRUE; | |
4991 | +} | |
4992 | + | |
4993 | +/* Start outputting a function. */ | |
4994 | + | |
4995 | +static bfd_boolean | |
4996 | +coff_start_function (p, name, globalp) | |
4997 | + PTR p; | |
4998 | + const char *name; | |
4999 | + bfd_boolean globalp; | |
5000 | +{ | |
5001 | + struct coff_write_handle *info = (struct coff_write_handle *) p; | |
5002 | + struct coff_type_stack *tst, *savedts; | |
5003 | + | |
5004 | +#if COFF_DEBUG | |
5005 | + printf ("coff_start_function(%s, %d)\n", | |
5006 | + name, globalp); | |
5007 | +#endif | |
5008 | + | |
5009 | + savedts = info->tstack; | |
5010 | + info->tstack = NULL; | |
5011 | + | |
5012 | + coff_push_type (TS_FUNC); | |
5013 | + | |
5014 | + if (info->funname != NULL) | |
5015 | + { | |
5016 | + fprintf (stderr, | |
5017 | + _("coff_start_function() called twice, pending %s, new %s\n"), | |
5018 | + info->funname, name); | |
5019 | + return FALSE; | |
5020 | + } | |
5021 | + info->funname = name; | |
5022 | + info->funglobal = globalp; | |
5023 | + info->flags |= COFF_FL_START_FCN; | |
5024 | + tst->u.ts_func.savedts = savedts; | |
5025 | + | |
5026 | + return TRUE; | |
5027 | +} | |
5028 | + | |
5029 | +/* Output a function parameter. */ | |
5030 | + | |
5031 | +static bfd_boolean | |
5032 | +coff_function_parameter (p, name, kind, val) | |
5033 | + PTR p; | |
5034 | + const char *name; | |
5035 | + enum debug_parm_kind kind; | |
5036 | + bfd_vma val; | |
5037 | +{ | |
5038 | + struct coff_write_handle *info = (struct coff_write_handle *) p; | |
5039 | + coff_symbol_type *csymp; | |
5040 | + unsigned char class; | |
5041 | + | |
5042 | +#if COFF_DEBUG | |
5043 | + printf ("coff_function_parameter(%s, %d, %d)\n", | |
5044 | + name, (int)kind, (int)val); | |
5045 | +#endif | |
5046 | + | |
5047 | + switch (kind) | |
5048 | + { | |
5049 | + default: | |
5050 | + abort (); | |
5051 | + | |
5052 | + case DEBUG_PARM_STACK: | |
5053 | + class = C_ARG; | |
5054 | + break; | |
5055 | + | |
5056 | + case DEBUG_PARM_REG: | |
5057 | + class = C_REGPARM; | |
5058 | + break; | |
5059 | + | |
5060 | + case DEBUG_PARM_REFERENCE: | |
5061 | + case DEBUG_PARM_REF_REG: | |
5062 | + fprintf (stderr, _("Reference parameters not available in COFF\n")); | |
5063 | + return TRUE; | |
5064 | + } | |
5065 | + | |
5066 | + if (!coff_make_typed_symbol (info, &csymp, TS_FUNC)) | |
5067 | + return FALSE; | |
5068 | + | |
5069 | + if (class == C_REGPARM && (info->flags & COFF_FL_AVR) != 0) | |
5070 | + { | |
5071 | + struct coff_private_symdata *priv = (struct coff_private_symdata *) | |
5072 | + csymp->symbol.udata.p; | |
5073 | + val = coff_fixup_avr_register (val, priv->size * 8); | |
5074 | + } | |
5075 | + | |
5076 | + csymp->symbol.name = name; | |
5077 | + csymp->symbol.value = val; | |
5078 | + csymp->symbol.flags |= BSF_LOCAL; | |
5079 | + csymp->native->u.syment.n_sclass = class; | |
5080 | + | |
5081 | + /* Since function parameters precede the actual function definition, | |
5082 | + defer their output until the function has been created. */ | |
5083 | + info->fargs = (coff_symbol_type **) | |
5084 | + xrealloc (info->fargs, ++info->nfargs * sizeof (coff_symbol_type *)); | |
5085 | + info->fargs[info->nfargs - 1] = csymp; | |
5086 | + | |
5087 | + return TRUE; | |
5088 | +} | |
5089 | + | |
5090 | +/* Start a block. */ | |
5091 | + | |
5092 | +static bfd_boolean | |
5093 | +coff_start_block (p, addr) | |
5094 | + PTR p; | |
5095 | + bfd_vma addr; | |
5096 | +{ | |
5097 | + struct coff_write_handle *info = (struct coff_write_handle *) p; | |
5098 | + struct coff_type_stack *tst, *otst; | |
5099 | + struct coff_fix_stack *fixp, *ofp; | |
5100 | + asymbol *symp; | |
5101 | + coff_symbol_type *csymp; | |
5102 | + unsigned int i; | |
5103 | + bfd_boolean is_start_fcn; | |
5104 | + | |
5105 | +#if COFF_DEBUG | |
5106 | + printf ("coff_start_block(%#x)\n", (int)addr); | |
5107 | +#endif | |
5108 | + | |
5109 | + is_start_fcn = info->flags & COFF_FL_START_FCN; | |
5110 | + | |
5111 | + if (is_start_fcn) | |
5112 | + { | |
5113 | + /* This is the starting block of a function. We are going to | |
5114 | + write three symbols here, one for the function itself, one | |
5115 | + ".bf" symbol to indicate the begin of the function, and | |
5116 | + finally one ".bb" for the first block inside the function. */ | |
5117 | + info->flags &= ~COFF_FL_START_FCN; | |
5118 | + | |
5119 | + /* Our function definition should be the only type stack element | |
5120 | + by now. */ | |
5121 | + assert (info->tstack != NULL); | |
5122 | + tst = info->tstack; | |
5123 | + if (tst->tsk != TS_FUNC || tst->next != NULL) | |
5124 | + { | |
5125 | + fprintf (stderr, | |
5126 | + _("coff_start_block() not within function definition\n")); | |
5127 | + return FALSE; | |
5128 | + } | |
5129 | + | |
5130 | + /* Restore saved type stack, and push our now complete function | |
5131 | + definition on top. */ | |
5132 | + info->tstack = tst->u.ts_func.savedts; | |
5133 | + tst->next = info->tstack; | |
5134 | + info->tstack = tst; | |
5135 | + | |
5136 | + if (info->currentfile == NULL) | |
5137 | + { | |
5138 | + fprintf (stderr, | |
5139 | + _("Warning: ignoring function %s() outside any compilation unit\n"), | |
5140 | + info->funname); | |
5141 | + for (tst = info->tstack, otst = NULL; tst != NULL;) | |
5142 | + { | |
5143 | + otst = tst; | |
5144 | + tst = otst->next; | |
5145 | + if (otst->tsk == TS_ENUM && | |
5146 | + otst->u.ts_enum.tagismalloced) | |
5147 | + free (otst->u.ts_enum.tag.malloctag); | |
5148 | + else if (otst->tsk == TS_STRUCT && | |
5149 | + otst->u.ts_struct.tagismalloced) | |
5150 | + free (otst->u.ts_struct.tag.malloctag); | |
5151 | + free (otst); | |
5152 | + } | |
5153 | + info->tstack = NULL; | |
5154 | + info->funname = NULL; | |
5155 | + | |
5156 | + return TRUE; | |
5157 | + } | |
5158 | + | |
5159 | + if (!coff_make_typed_symbol (info, &csymp, TS_NONE)) | |
5160 | + return FALSE; | |
5161 | + | |
5162 | + csymp->symbol.name = info->funname; | |
5163 | + csymp->symbol.flags = BSF_FUNCTION | | |
5164 | + (info->funglobal? BSF_GLOBAL: BSF_LOCAL); | |
5165 | + symp = coff_find_symbol (info, info->funname, TRUE, info->funglobal); | |
5166 | + if (symp == NULL) | |
5167 | + { | |
5168 | + fprintf (stderr, | |
5169 | + _("function %s not found in symbol table, defaulting to \"text\" section\n"), | |
5170 | + info->funname); | |
5171 | + csymp->symbol.section = info->funcsection = info->textsect; | |
5172 | + } | |
5173 | + else | |
5174 | + csymp->symbol.section = info->funcsection = symp->section; | |
5175 | + | |
5176 | + /* Symbol addresses are relative to section vma. */ | |
5177 | + csymp->symbol.value = addr - info->funcsection->vma; | |
5178 | + csymp->native->u.syment.n_sclass = info->funglobal? C_EXT: C_STAT; | |
5179 | + /* Create two initial line number entries. The first one holds | |
5180 | + the function symbol, the second one is the trailing record | |
5181 | + that is required by coffgen.c::coff_write_native_symbol() to | |
5182 | + have a line number of zero. */ | |
5183 | + csymp->lineno = (alent *) xmalloc (2 * sizeof (alent)); | |
5184 | + memset (csymp->lineno, 0, 2 * sizeof (alent)); | |
5185 | + info->nlnos = 2; | |
5186 | + info->totlnos++; | |
5187 | + csymp->lineno[0].u.sym = (asymbol *)csymp; | |
5188 | + coff_record_symbol (info, csymp); | |
5189 | + info->funcindex = info->nsyms - 1; /* remember for later */ | |
5190 | + /* Record our endndx field for later fixing. */ | |
5191 | + fixp = (struct coff_fix_stack *) xmalloc (sizeof (struct coff_fix_stack)); | |
5192 | + fixp->native = csymp->native + 1; /* points to first AUX */ | |
5193 | + fixp->next = NULL; | |
5194 | + if (info->fixes == NULL) | |
5195 | + info->fixes = fixp; | |
5196 | + else | |
5197 | + { | |
5198 | + for (ofp = info->fixes; ofp->next != NULL;) | |
5199 | + ofp = ofp->next; | |
5200 | + ofp->next = fixp; | |
5201 | + } | |
5202 | + | |
5203 | + csymp = (coff_symbol_type *) coff_bfd_make_debug_symbol (info->abfd, 0, 0); | |
5204 | + if (csymp == NULL) | |
5205 | + return FALSE; | |
5206 | + | |
5207 | + csymp->symbol.name = ".bf"; | |
5208 | + csymp->native->u.syment.n_sclass = C_FCN; | |
5209 | + csymp->native->u.syment.n_numaux = 1; | |
5210 | + csymp->symbol.value = addr - info->funcsection->vma; | |
5211 | + csymp->symbol.section = info->funcsection; | |
5212 | + csymp->symbol.udata.p = NULL; | |
5213 | + coff_record_symbol (info, csymp); | |
5214 | + } | |
5215 | + | |
5216 | + if (info->funname == NULL) | |
5217 | + return TRUE; | |
5218 | + | |
5219 | + csymp = (coff_symbol_type *) coff_bfd_make_debug_symbol (info->abfd, 0, 0); | |
5220 | + if (csymp == NULL) | |
5221 | + return FALSE; | |
5222 | + | |
5223 | + csymp->symbol.name = ".bb"; | |
5224 | + csymp->native->u.syment.n_sclass = C_BLOCK; | |
5225 | + csymp->native->u.syment.n_numaux = 1; | |
5226 | + csymp->symbol.value = addr - info->funcsection->vma; | |
5227 | + csymp->symbol.section = info->funcsection; | |
5228 | + csymp->symbol.udata.p = NULL; | |
5229 | + coff_record_symbol (info, csymp); | |
5230 | + | |
5231 | + info->flags |= COFF_FL_FIX_BB; | |
5232 | + | |
5233 | + /* Output any pending function parameters, if any. */ | |
5234 | + if (is_start_fcn && info->nfargs) | |
5235 | + { | |
5236 | + for (i = 0; i < info->nfargs; i++) | |
5237 | + coff_record_symbol (info, info->fargs[i]); | |
5238 | + | |
5239 | + free (info->fargs); | |
5240 | + info->fargs = NULL; | |
5241 | + info->nfargs = 0; | |
5242 | + } | |
5243 | + | |
5244 | + return TRUE; | |
5245 | +} | |
5246 | + | |
5247 | +/* End a block. */ | |
5248 | + | |
5249 | +static bfd_boolean | |
5250 | +coff_end_block (p, addr) | |
5251 | + PTR p; | |
5252 | + bfd_vma addr; | |
5253 | +{ | |
5254 | + struct coff_write_handle *info = (struct coff_write_handle *) p; | |
5255 | + coff_symbol_type *csymp; | |
5256 | + union internal_auxent *aux; | |
5257 | + | |
5258 | +#if COFF_DEBUG | |
5259 | + printf ("coff_end_block(%#x)\n", (int)addr); | |
4cd5ba0f | 5260 | +#endif |
f33182aa | 5261 | + |
5262 | + if (info->funname == NULL) | |
5263 | + return TRUE; | |
5264 | + | |
5265 | + csymp = (coff_symbol_type *) coff_bfd_make_debug_symbol (info->abfd, 0, 0); | |
5266 | + if (csymp == NULL) | |
5267 | + return FALSE; | |
5268 | + | |
5269 | + csymp->symbol.name = ".eb"; | |
5270 | + csymp->symbol.value = addr - info->funcsection->vma; | |
5271 | + csymp->native->u.syment.n_sclass = C_BLOCK; | |
5272 | + csymp->native->u.syment.n_numaux = 1; | |
5273 | + csymp->symbol.udata.p = NULL; | |
5274 | + csymp->symbol.section = info->funcsection; | |
5275 | + aux = &((csymp->native + 1)->u.auxent); | |
5276 | + aux->x_sym.x_misc.x_lnsz.x_lnno = info->lastlno; | |
5277 | + coff_record_symbol (info, csymp); | |
5278 | + | |
5279 | + info->endaddr = addr; | |
5280 | + | |
5281 | + return TRUE; | |
5282 | +} | |
5283 | + | |
5284 | +/* End a function. */ | |
5285 | + | |
5286 | +static bfd_boolean | |
5287 | +coff_end_function (p) | |
5288 | + PTR p; | |
5289 | +{ | |
5290 | + struct coff_write_handle *info = (struct coff_write_handle *) p; | |
5291 | + coff_symbol_type *csymp; | |
5292 | + union internal_auxent *aux; | |
5293 | + | |
5294 | +#if COFF_DEBUG | |
5295 | + printf ("coff_end_function()\n"); | |
5296 | +#endif | |
5297 | + | |
5298 | + if (info->funname == NULL) | |
5299 | + return TRUE; | |
5300 | + | |
5301 | + csymp = (coff_symbol_type *) coff_bfd_make_debug_symbol (info->abfd, 0, 0); | |
5302 | + if (csymp == NULL) | |
5303 | + return FALSE; | |
5304 | + | |
5305 | + csymp->symbol.name = ".ef"; | |
5306 | + csymp->symbol.value = info->endaddr - info->funcsection->vma; | |
5307 | + csymp->native->u.syment.n_sclass = C_FCN; | |
5308 | + csymp->native->u.syment.n_numaux = 1; | |
5309 | + csymp->symbol.udata.p = NULL; | |
5310 | + csymp->symbol.section = info->funcsection; | |
5311 | + aux = &((csymp->native + 1)->u.auxent); | |
5312 | + aux->x_sym.x_misc.x_lnsz.x_lnno = info->lastlno; | |
5313 | + | |
5314 | + coff_record_symbol (info, csymp); | |
5315 | + | |
5316 | + csymp = (coff_symbol_type *) info->syms[info->funcindex]; | |
5317 | + aux = &((csymp->native + 1)->u.auxent); | |
5318 | + aux->x_sym.x_misc.x_fsize = info->endaddr - csymp->symbol.value; | |
5319 | + | |
5320 | + info->flags |= COFF_FL_FIX_ENDNDX; | |
5321 | + info->funname = NULL; | |
5322 | + | |
5323 | + return TRUE; | |
5324 | +} | |
5325 | + | |
5326 | +/* Output a line number. */ | |
5327 | + | |
5328 | +static bfd_boolean | |
5329 | +coff_lineno (p, file, lineno, addr) | |
5330 | + PTR p; | |
5331 | + const char *file ATTRIBUTE_UNUSED; | |
5332 | + unsigned long lineno; | |
5333 | + bfd_vma addr; | |
5334 | +{ | |
5335 | + struct coff_write_handle *info = (struct coff_write_handle *) p; | |
5336 | + coff_symbol_type *csymp; | |
5337 | + union internal_auxent *aux; | |
5338 | + long i; | |
5339 | + | |
5340 | +#if COFF_DEBUG | |
5341 | + printf ("coff_lineno(%s, %ld, %d)\n", | |
5342 | + file, lineno, (int)addr); | |
5343 | +#endif | |
5344 | + | |
5345 | + /* COFF can inherently only handle line numbers inside of functions. | |
5346 | + If we are not inside a function, punt. */ | |
5347 | + if (info->funname == NULL) | |
5348 | + return TRUE; | |
5349 | + | |
5350 | + if (info->nlnos == 2) | |
5351 | + { | |
5352 | + /* This is the first line number of this function. Fix the line | |
5353 | + number for the .bf symbol immediately following the start of | |
5354 | + function. We also have to remember the starting line number | |
5355 | + of our function since all line number entries are relative to | |
5356 | + it in COFF. Since regular line numbers must always be | |
5357 | + non-zero, we artificially force the function to start one | |
5358 | + line earlier. */ | |
5359 | + csymp = (coff_symbol_type *) info->syms[info->funcindex + 1]; | |
5360 | + aux = &((csymp->native + 1)->u.auxent); | |
5361 | + aux->x_sym.x_misc.x_lnsz.x_lnno = lineno; | |
5362 | + info->funlno = lineno - 1; | |
5363 | + } | |
5364 | + | |
5365 | + if (info->flags & COFF_FL_FIX_BB) | |
5366 | + { | |
5367 | + /* This is the first line number after one (or more) .bb | |
5368 | + symbols. Fix them. In order to cope with multiple blocks | |
5369 | + starting at the same line number, we walk back the list of | |
5370 | + symbols until we find a C_BLOCK one that had already been | |
5371 | + fixed, or until we find a C_FCN symbol (presumably, the start | |
5372 | + of our current function). */ | |
5373 | + info->flags &= ~COFF_FL_FIX_BB; | |
5374 | + | |
5375 | + for (i = info->nsyms - 1; i >= 0; i--) | |
5376 | + { | |
5377 | + csymp = (coff_symbol_type *) info->syms[i]; | |
5378 | + if (csymp->native->u.syment.n_sclass == C_FCN) | |
5379 | + break; | |
5380 | + if (csymp->native->u.syment.n_sclass == C_BLOCK) | |
5381 | + { | |
5382 | + aux = &((csymp->native + 1)->u.auxent); | |
5383 | + if (aux->x_sym.x_misc.x_lnsz.x_lnno != 0) | |
5384 | + /* already set up properly */ | |
5385 | + break; | |
5386 | + aux->x_sym.x_misc.x_lnsz.x_lnno = lineno; | |
5387 | + } | |
5388 | + } | |
5389 | + } | |
5390 | + | |
5391 | + csymp = (coff_symbol_type *) info->syms[info->funcindex]; | |
5392 | + csymp->lineno = (alent *) xrealloc (csymp->lineno, | |
5393 | + ++info->nlnos * sizeof (alent)); | |
5394 | + memset (csymp->lineno + info->nlnos - 1, 0, sizeof (alent)); | |
5395 | + if (lineno > info->funlno) | |
5396 | + csymp->lineno[info->nlnos - 2].line_number = lineno - info->funlno; | |
5397 | + else | |
5398 | + /* Line number unreasonable. Can e. g. happen for a line number | |
5399 | + from an include file, which we cannot process in COFF. Just | |
5400 | + set it to the first line, to avoid generating a large unsigned | |
5401 | + short (~ 65000) line number. */ | |
5402 | + csymp->lineno[info->nlnos - 2].line_number = 1; | |
5403 | + csymp->lineno[info->nlnos - 2].u.offset = addr; | |
5404 | + | |
5405 | + info->lastlno = lineno; | |
5406 | + info->totlnos++; | |
5407 | + | |
5408 | + return TRUE; | |
5409 | +} | |
5410 | diff -uNdr binutils-2.17.50.0.18-old/include/coff/avr.h binutils-2.17.50.0.18/include/coff/avr.h | |
5411 | --- binutils-2.17.50.0.18-old/include/coff/avr.h 1970-01-01 01:00:00.000000000 +0100 | |
5412 | +++ binutils-2.17.50.0.18/include/coff/avr.h 2007-10-20 16:45:33.000000000 +0200 | |
4cd5ba0f ER |
5413 | @@ -0,0 +1,110 @@ |
5414 | +/* coff information for Atmel AVR. | |
5415 | + | |
5416 | + Copyright 2001 Free Software Foundation, Inc. | |
5417 | + | |
5418 | + This program is free software; you can redistribute it and/or modify | |
5419 | + it under the terms of the GNU General Public License as published by | |
5420 | + the Free Software Foundation; either version 2 of the License, or | |
5421 | + (at your option) any later version. | |
5422 | + | |
5423 | + This program is distributed in the hope that it will be useful, | |
5424 | + but WITHOUT ANY WARRANTY; without even the implied warranty of | |
5425 | + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
5426 | + GNU General Public License for more details. | |
5427 | + | |
5428 | + You should have received a copy of the GNU General Public License | |
5429 | + along with this program; if not, write to the Free Software | |
5430 | + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ | |
5431 | + | |
5432 | +/* This file was hacked from i860.h */ | |
5433 | + | |
5434 | +#define L_LNNO_SIZE 2 | |
5435 | +#include "coff/external.h" | |
5436 | + | |
5437 | +/* Bits for f_flags: | |
5438 | + F_RELFLG relocation info stripped from file | |
5439 | + F_EXEC file is executable (no unresolved external references) | |
5440 | + F_LNNO line numbers stripped from file | |
5441 | + F_LSYMS local symbols stripped from file */ | |
5442 | + | |
5443 | +#define F_RELFLG (0x0001) | |
5444 | +#define F_EXEC (0x0002) | |
5445 | +#define F_LNNO (0x0004) | |
5446 | +#define F_LSYMS (0x0008) | |
5447 | +/* Upper nibble of flags always needs to be set. This used to be | |
5448 | + * undocumented, recent information from Atmel says that bit 7 used to | |
5449 | + * differentiate between an old vendor-specific deviation of the | |
5450 | + * format and the current format. */ | |
5451 | +#define F_JUNK (0x00f0) | |
5452 | +#define F_UNUSED (0xff00) | |
5453 | + | |
5454 | +#define AVRMAGIC 0xa12 | |
5455 | + | |
5456 | +#undef AOUTSZ | |
5457 | +#ifdef AVR_EXT_COFF | |
5458 | + | |
5459 | +/* AVR "extended" COFF format. This uses the optional header ("a.out" | |
5460 | + header) to inform the consumer about some additional features that | |
5461 | + are supported. */ | |
5462 | +#define COFF_LONG_FILENAMES yes /* long filenames supported in consecutive aux entries */ | |
5463 | +#define AOUTSZ 28 /* size of optional header in "extended" COFF */ | |
5464 | + | |
5465 | +/* Flags in the optional header; they are stored in the vstamp field. */ | |
5466 | +#define F_FULLPATHS 0x0001 /* long filenames supported */ | |
5467 | +#define F_STRUCTINFO 0x0002 /* structure information contained */ | |
5468 | +#define F_PTRINFO 0x0004 /* inter-segment pointers supported */ | |
5469 | + | |
5470 | +#else /* old AVR COFF */ | |
5471 | + | |
5472 | +#define AOUTSZ 0 /* no a.out for AVR */ | |
5473 | +#endif | |
5474 | + | |
5475 | +/* #define AVRAOUTMAGIC 0x406 */ /* "general" magic number of optional header */ | |
5476 | +/* | |
5477 | + * The following magic number causes AVR Studio 4.x to recognize | |
5478 | + * avr-gcc/GNU binutils produced AVR extended COFF files. By now, | |
5479 | + * the only special treatment for them is that the contents of .data | |
5480 | + * will be appended after .text in the simulator flash. | |
5481 | + * | |
5482 | + * 0x9cc has been chosen since it resembles "gcc". ;-) | |
5483 | + */ | |
5484 | +#define AVRAOUTMAGIC 0x9cc /* "gcc" magic number */ | |
5485 | + | |
5486 | +/* By matching not only the magic number, but also the size of the | |
5487 | + optional a.out header, we can differentiate between both | |
5488 | + formats. */ | |
5489 | +#define AVRBADMAG(x) ((x).f_magic != AVRMAGIC || (x).f_opthdr != AOUTSZ) | |
5490 | + | |
5491 | +/* AVR COFF has several anomalities in the way the handle the derived | |
5492 | + type information, and AUX entries, mainly because they apparently | |
5493 | + didn't bother to learn how COFF is supposed to work before they | |
5494 | + started. We fix many of them at the export/import boundary, so all | |
5495 | + the internal generic COFF handling will work mostly as designed. */ | |
5496 | + | |
5497 | +/* NB: these functions are only defined in bfd/coff-avr.c, but also | |
5498 | + used in coff-ext-avr.c, so the latter can only be configured if the | |
5499 | + former is also present. This is certainly always the case | |
5500 | + anyway. */ | |
5501 | +extern void avr_coff_adjust_sym_in_post | |
5502 | + PARAMS((bfd *, PTR, PTR)); | |
5503 | + | |
5504 | +extern void avr_coff_adjust_sym_out_post | |
5505 | + PARAMS((bfd *, PTR, PTR)); | |
5506 | + | |
5507 | +#define COFF_ADJUST_SYM_IN_POST(ABFD, EXT, INT) \ | |
5508 | + avr_coff_adjust_sym_in_post (ABFD, EXT, INT) | |
5509 | + | |
5510 | +#define COFF_ADJUST_SYM_OUT_POST(ABFD, INT, EXT) \ | |
5511 | + avr_coff_adjust_sym_out_post (ABFD, INT, EXT) | |
5512 | + | |
5513 | +/********************** RELOCATION DIRECTIVES **********************/ | |
5514 | + | |
5515 | +struct external_reloc | |
5516 | +{ | |
5517 | + char r_vaddr[4]; | |
5518 | + char r_symndx[4]; | |
5519 | + char r_type[2]; | |
5520 | +}; | |
5521 | + | |
5522 | +#define RELOC struct external_reloc | |
5523 | +#define RELSZ 10 | |
f33182aa | 5524 | diff -uNdr binutils-2.17.50.0.18-old/include/coff/internal.h binutils-2.17.50.0.18/include/coff/internal.h |
5525 | --- binutils-2.17.50.0.18-old/include/coff/internal.h 2007-08-01 15:11:51.000000000 +0200 | |
5526 | +++ binutils-2.17.50.0.18/include/coff/internal.h 2007-10-20 16:45:33.000000000 +0200 | |
5527 | @@ -630,6 +630,8 @@ | |
4cd5ba0f ER |
5528 | |
5529 | }; | |
5530 | ||
5531 | +#define NAUXENTS 10 /* number of pre-allocated aux entries */ | |
5532 | + | |
5533 | /********************** RELOCATION DIRECTIVES **********************/ | |
5534 | ||
5535 | struct internal_reloc |