* aoutx.h (NAME(aout,find_nearest_line)): Recognize N_SOL symbols,
[deliverable/binutils-gdb.git] / bfd / coffcode.h
CommitLineData
6d7c88c3 1/* Support for the generic parts of most COFF variants, for BFD.
7a8b18b6
SC
2 Copyright (C) 1990-1991 Free Software Foundation, Inc.
3 Written by Cygnus Support.
0f268757 4
7a8b18b6 5This file is part of BFD, the Binary File Descriptor library.
0f268757 6
7a8b18b6
SC
7This program is free software; you can redistribute it and/or modify
8it under the terms of the GNU General Public License as published by
9the Free Software Foundation; either version 2 of the License, or
10(at your option) any later version.
0f268757 11
7a8b18b6
SC
12This program is distributed in the hope that it will be useful,
13but WITHOUT ANY WARRANTY; without even the implied warranty of
14MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15GNU General Public License for more details.
0f268757 16
7a8b18b6
SC
17You should have received a copy of the GNU General Public License
18along with this program; if not, write to the Free Software
19Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
6f715d66 20
9fda1a39 21/*
6f715d66 22
9fda1a39
SC
23SECTION
24 coff backends
25
9fda1a39
SC
26 BFD supports a number of different flavours of coff format.
27 The major difference between formats are the sizes and
28 alignments of fields in structures on disk, and the occasional
29 extra field.
30
31 Coff in all its varieties is implimented with a few common
32 files and a number of implementation specific files. For
33 example, The 88k bcs coff format is implemented in the file
34 @code{coff-m88k.c}. This file @code{#include}s
35 @code{coff-m88k.h} which defines the external structure of the
36 coff format for the 88k, and @code{internalcoff.h} which
37 defines the internal structure. @code{coff-m88k.c} also
38 defines pthe relocations used by the 88k format
39 @xref{Relocations}. Then the major portion of coff code is
40 included (@code{coffcode.h}) which defines the methods used to
41 act upon the types defined in @code{coff-m88k.h} and
42 @code{internalcoff.h}.
43
44
45 The Intel i960 processor version of coff is implemented in
46 @code{coff-i960.c}. This file has the same structure as
47 @code{coff-m88k.c}, except that it includes @code{coff-i960.h}
48 rather than @code{coff-m88k.h}.
49
50SUBSECTION
51 Porting To A New Version of Coff
52
9fda1a39
SC
53 The recommended method is to select from the existing
54 implimentations the version of coff which is most like the one
55 you want to use, for our purposes, we'll say that i386 coff is
56 the one you select, and that your coff flavour is called foo.
57 Copy the @code{i386coff.c} to @code{foocoff.c}, copy
58 @code{../include/i386coff.h} to @code{../include/foocoff.h}
59 and add the lines to @code{targets.c} and @code{Makefile.in}
60 so that your new back end is used. Alter the shapes of the
61 structures in @code{../include/foocoff.h} so that they match
62 what you need. You will probably also have to add
63 @code{#ifdef}s to the code in @code{internalcoff.h} and
64 @code{coffcode.h} if your version of coff is too wild.
65
66 You can verify that your new BFD backend works quite simply by
67 building @code{objdump} from the @code{binutils} directory,
68 and making sure that its version of what's going on at your
69 host systems idea (assuming it has the pretty standard coff
70 dump utility (usually called @code{att-dump} or just
71 @code{dump})) are the same. Then clean up your code, and send
72 what you've done to Cygnus. Then your stuff will be in the
73 next release, and you won't have to keep integrating it.
74
75SUBSECTION
76 How The Coff Backend Works
77
78SUBSUBSECTION
79 Bit Twiddling
80
9fda1a39
SC
81 Each flavour of coff supported in BFD has its own header file
82 descibing the external layout of the structures. There is also
83 an internal description of the coff layout (in
84 @code{internalcoff.h}) file (@code{}). A major function of the
85 coff backend is swapping the bytes and twiddling the bits to
86 translate the external form of the structures into the normal
87 internal form. This is all performed in the
88 @code{bfd_swap}_@i{thing}_@i{direction} routines. Some
89 elements are different sizes between different versions of
90 coff, it is the duty of the coff version specific include file
91 to override the definitions of various packing routines in
92 @code{coffcode.h}. Eg the size of line number entry in coff is
93 sometimes 16 bits, and sometimes 32 bits. @code{#define}ing
94 @code{PUT_LNSZ_LNNO} and @code{GET_LNSZ_LNNO} will select the
95 correct one. No doubt, some day someone will find a version of
96 coff which has a varying field size not catered for at the
97 moment. To port BFD, that person will have to add more @code{#defines}.
98 Three of the bit twiddling routines are exported to
99 @code{gdb}; @code{coff_swap_aux_in}, @code{coff_swap_sym_in}
100 and @code{coff_swap_linno_in}. @code{GDB} reads the symbol
101 table on its own, but uses BFD to fix things up. More of the
102 bit twiddlers are exported for @code{gas};
103 @code{coff_swap_aux_out}, @code{coff_swap_sym_out},
104 @code{coff_swap_lineno_out}, @code{coff_swap_reloc_out},
105 @code{coff_swap_filehdr_out}, @code{coff_swap_aouthdr_out},
106 @code{coff_swap_scnhdr_out}. @code{Gas} currently keeps track
107 of all the symbol table and reloc drudgery itself, thereby
108 saving the internal BFD overhead, but uses BFD to swap things
109 on the way out, making cross ports much safer. This also
110 allows BFD (and thus the linker) to use the same header files
111 as @code{gas}, which makes one avenue to disaster disappear.
112
113SUBSUBSECTION
114 Symbol Reading
115
9fda1a39
SC
116 The simple canonical form for symbols used by BFD is not rich
117 enough to keep all the information available in a coff symbol
118 table. The back end gets around this by keeping the original
119 symbol table around, "behind the scenes".
120
121 When a symbol table is requested (through a call to
122 @code{bfd_canonicalize_symtab}, a request gets through to
123 @code{get_normalized_symtab}. This reads the symbol table from
124 the coff file and swaps all the structures inside into the
125 internal form. It also fixes up all the pointers in the table
126 (represented in the file by offsets from the first symbol in
127 the table) into physical pointers to elements in the new
128 internal table. This involves some work since the meanings of
129 fields changes depending upon context; a field that is a
130 pointer to another structure in the symbol table at one moment
131 may be the size in bytes of a structure in the next. Another
132 pass is made over the table. All symbols which mark file names
616ebcfd 133 (<<C_FILE>> symbols) are modified so that the internal
9fda1a39
SC
134 string points to the value in the auxent (the real filename)
135 rather than the normal text associated with the symbol
136 (@code{".file"}).
137
138 At this time the symbol names are moved around. Coff stores
139 all symbols less than nine characters long physically
140 within the symbol table, longer strings are kept at the end of
141 the file in the string table. This pass moves all strings
142 into memory, and replaces them with pointers to the strings.
143
144
145 The symbol table is massaged once again, this time to create
146 the canonical table used by the BFD application. Each symbol
147 is inspected in turn, and a decision made (using the
148 @code{sclass} field) about the various flags to set in the
149 @code{asymbol} @xref{Symbols}. The generated canonical table
150 shares strings with the hidden internal symbol table.
151
152 Any linenumbers are read from the coff file too, and attached
153 to the symbols which own the functions the linenumbers belong to.
154
155SUBSUBSECTION
156 Symbol Writing
157
9fda1a39
SC
158 Writing a symbol to a coff file which didn't come from a coff
159 file will lose any debugging information. The @code{asymbol}
160 structure remembers the BFD from which was born, and on output
161 the back end makes sure that the same destination target as
162 source target is present.
163
164 When the symbols have come from a coff file then all the
165 debugging information is preserved.
166
167 Symbol tables are provided for writing to the back end in a
168 vector of pointers to pointers. This allows applications like
169 the linker to accumulate and output large symbol tables
170 without having to do too much byte copying.
171
9fda1a39
SC
172 This function runs through the provided symbol table and
173 patches each symbol marked as a file place holder
174 (@code{C_FILE}) to point to the next file place holder in the
175 list. It also marks each @code{offset} field in the list with
176 the offset from the first symbol of the current symbol.
177
178 Another function of this procedure is to turn the canonical
179 value form of BFD into the form used by coff. Internally, BFD
180 expects symbol values to be offsets from a section base; so a
181 symbol physically at 0x120, but in a section starting at
182 0x100, would have the value 0x20. Coff expects symbols to
183 contain their final value, so symbols have their values
184 changed at this point to reflect their sum with their owning
185 section. Note that this transformation uses the
186 <<output_section>> field of the @code{asymbol}'s
187 @code{asection} @xref{Sections}.
188
189 o coff_mangle_symbols
616ebcfd 190
9fda1a39
SC
191 This routine runs though the provided symbol table and uses
192 the offsets generated by the previous pass and the pointers
193 generated when the symbol table was read in to create the
194 structured hierachy required by coff. It changes each pointer
195 to a symbol to an index into the symbol table of the symbol
196 being referenced.
197
198 o coff_write_symbols
616ebcfd 199
9fda1a39
SC
200 This routine runs through the symbol table and patches up the
201 symbols from their internal form into the coff way, calls the
202 bit twiddlers and writes out the tabel to the file.
6f715d66 203
9fda1a39 204*/
6f715d66 205
9fda1a39 206/*
616ebcfd
SC
207INTERNAL_DEFINITION
208 coff_symbol_type
6f715d66 209
616ebcfd 210DESCRIPTION
9fda1a39
SC
211 The hidden information for an asymbol is described in a
212 coff_ptr_struct, which is typedefed to a combined_entry_type
6f715d66 213
616ebcfd
SC
214CODE_FRAGMENT
215.typedef struct coff_ptr_struct
216.{
217.
218. {* Remembers the offset from the first symbol in the file for
219. this symbol. Generated by coff_renumber_symbols. *}
220.unsigned int offset;
221.
222. {* Should the tag field of this symbol be renumbered.
223. Created by coff_pointerize_aux. *}
224.char fix_tag;
225.
226. {* Should the endidx field of this symbol be renumbered.
227. Created by coff_pointerize_aux. *}
228.char fix_end;
229.
230. {* The container for the symbol structure as read and translated
231. from the file. *}
232.
233.union {
234. union internal_auxent auxent;
235. struct internal_syment syment;
236. } u;
237.} combined_entry_type;
238.
239.
240.{* Each canonical asymbol really looks like this: *}
241.
242.typedef struct coff_symbol_struct
243.{
244. {* The actual symbol which the rest of BFD works with *}
245.asymbol symbol;
246.
247. {* A pointer to the hidden information for this symbol *}
248.combined_entry_type *native;
249.
250. {* A pointer to the linenumber information for this symbol *}
251.struct lineno_cache_entry *lineno;
252.
253.} coff_symbol_type;
6f715d66 254
6f715d66 255
0f268757
SC
256*/
257
0f268757
SC
258/* Most of this hacked by Steve Chamberlain, steve@cygnus.com */
259
0f268757
SC
260
261#define PUTWORD bfd_h_put_32
262#define PUTHALF bfd_h_put_16
6d7c88c3 263#define PUTBYTE bfd_h_put_8
6f715d66
SC
264
265#ifndef GET_FCN_LNNOPTR
41f50af0 266#define GET_FCN_LNNOPTR(abfd, ext) bfd_h_get_32(abfd, (bfd_byte *) ext->x_sym.x_fcnary.x_fcn.x_lnnoptr)
6f715d66
SC
267#endif
268
269#ifndef GET_FCN_ENDNDX
41f50af0 270#define GET_FCN_ENDNDX(abfd, ext) bfd_h_get_32(abfd, (bfd_byte *) ext->x_sym.x_fcnary.x_fcn.x_endndx)
6f715d66
SC
271#endif
272
273#ifndef PUT_FCN_LNNOPTR
41f50af0 274#define PUT_FCN_LNNOPTR(abfd, in, ext) PUTWORD(abfd, in, (bfd_byte *) ext->x_sym.x_fcnary.x_fcn.x_lnnoptr)
6f715d66
SC
275#endif
276#ifndef PUT_FCN_ENDNDX
41f50af0 277#define PUT_FCN_ENDNDX(abfd, in, ext) PUTWORD(abfd, in, (bfd_byte *) ext->x_sym.x_fcnary.x_fcn.x_endndx)
6f715d66
SC
278#endif
279#ifndef GET_LNSZ_LNNO
41f50af0 280#define GET_LNSZ_LNNO(abfd, ext) bfd_h_get_16(abfd, (bfd_byte *) ext->x_sym.x_misc.x_lnsz.x_lnno)
6f715d66
SC
281#endif
282#ifndef GET_LNSZ_SIZE
41f50af0 283#define GET_LNSZ_SIZE(abfd, ext) bfd_h_get_16(abfd, (bfd_byte *) ext->x_sym.x_misc.x_lnsz.x_size)
6f715d66
SC
284#endif
285#ifndef PUT_LNSZ_LNNO
41f50af0 286#define PUT_LNSZ_LNNO(abfd, in, ext) bfd_h_put_16(abfd, in, (bfd_byte *)ext->x_sym.x_misc.x_lnsz.x_lnno)
6f715d66
SC
287#endif
288#ifndef PUT_LNSZ_SIZE
41f50af0 289#define PUT_LNSZ_SIZE(abfd, in, ext) bfd_h_put_16(abfd, in, (bfd_byte*) ext->x_sym.x_misc.x_lnsz.x_size)
6f715d66 290#endif
cbdc7909 291#ifndef GET_SCN_SCNLEN
41f50af0 292#define GET_SCN_SCNLEN(abfd, ext) bfd_h_get_32(abfd, (bfd_byte *) ext->x_scn.x_scnlen)
6f715d66
SC
293#endif
294#ifndef GET_SCN_NRELOC
41f50af0 295#define GET_SCN_NRELOC(abfd, ext) bfd_h_get_16(abfd, (bfd_byte *)ext->x_scn.x_nreloc)
6f715d66
SC
296#endif
297#ifndef GET_SCN_NLINNO
41f50af0 298#define GET_SCN_NLINNO(abfd, ext) bfd_h_get_16(abfd, (bfd_byte *)ext->x_scn.x_nlinno)
6f715d66 299#endif
cbdc7909 300#ifndef PUT_SCN_SCNLEN
41f50af0 301#define PUT_SCN_SCNLEN(abfd,in, ext) bfd_h_put_32(abfd, in, (bfd_byte *) ext->x_scn.x_scnlen)
6f715d66
SC
302#endif
303#ifndef PUT_SCN_NRELOC
41f50af0 304#define PUT_SCN_NRELOC(abfd,in, ext) bfd_h_put_16(abfd, in, (bfd_byte *)ext->x_scn.x_nreloc)
6f715d66
SC
305#endif
306#ifndef PUT_SCN_NLINNO
85e0c721
SC
307#define PUT_SCN_NLINNO(abfd,in, ext) bfd_h_put_16(abfd,in, (bfd_byte *) ext->x_scn.x_nlinno)
308#endif
309#ifndef GET_LINENO_LNNO
310#define GET_LINENO_LNNO(abfd, ext) bfd_h_get_16(abfd, (bfd_byte *) (ext->l_lnno));
311#endif
8c4a1ace 312#ifndef PUT_LINENO_LNNO
85e0c721 313#define PUT_LINENO_LNNO(abfd,val, ext) bfd_h_put_16(abfd,val, (bfd_byte *) (ext->l_lnno));
0f268757 314#endif
0f268757
SC
315
316\f
317/* void warning(); */
6f715d66 318
cbdc7909
JG
319/*
320 * Return a word with STYP_* (scnhdr.s_flags) flags set to represent the
41f50af0
SC
321 * incoming SEC_* flags. The inverse of this function is styp_to_sec_flags().
322 * NOTE: If you add to/change this routine, you should mirror the changes
323 * in styp_to_sec_flags().
324 */
cbdc7909 325static long
41f50af0
SC
326DEFUN(sec_to_styp_flags, (sec_name, sec_flags),
327 CONST char * sec_name AND
328 flagword sec_flags)
329{
330 long styp_flags = 0;
331
332 if (!strcmp(sec_name, _TEXT)) {
333 return((long)STYP_TEXT);
334 } else if (!strcmp(sec_name, _DATA)) {
335 return((long)STYP_DATA);
336 } else if (!strcmp(sec_name, _BSS)) {
337 return((long)STYP_BSS);
8c4a1ace
JG
338#ifdef _COMMENT
339 } else if (!strcmp(sec_name, _COMMENT)) {
340 return((long)STYP_INFO);
341#endif /* _COMMENT */
cbdc7909 342 }
41f50af0
SC
343
344/* Try and figure out what it should be */
cbdc7909
JG
345 if (sec_flags & SEC_CODE) styp_flags = STYP_TEXT;
346 if (sec_flags & SEC_DATA) styp_flags = STYP_DATA;
347 else if (sec_flags & SEC_READONLY)
41f50af0 348#ifdef STYP_LIT /* 29k readonly text/data section */
cbdc7909 349 styp_flags = STYP_LIT;
41f50af0 350#else
cbdc7909 351 styp_flags = STYP_TEXT;
41f50af0
SC
352#endif /* STYP_LIT */
353 else if (sec_flags & SEC_LOAD) styp_flags = STYP_TEXT;
354
355 if (styp_flags == 0) styp_flags = STYP_BSS;
356
357 return(styp_flags);
358}
cbdc7909 359/*
41f50af0 360 * Return a word with SEC_* flags set to represent the incoming
cbdc7909
JG
361 * STYP_* flags (from scnhdr.s_flags). The inverse of this
362 * function is sec_to_styp_flags().
41f50af0
SC
363 * NOTE: If you add to/change this routine, you should mirror the changes
364 * in sec_to_styp_flags().
365 */
cbdc7909 366static flagword
41f50af0
SC
367DEFUN(styp_to_sec_flags, (styp_flags),
368 long styp_flags)
369{
370 flagword sec_flags=0;
371
372 if ((styp_flags & STYP_TEXT) || (styp_flags & STYP_DATA))
373 sec_flags = (SEC_LOAD | SEC_ALLOC);
374 else if (styp_flags & STYP_BSS)
375 sec_flags = SEC_ALLOC;
376
377#ifdef STYP_LIT /* A29k readonly text/data section type */
378 if ((styp_flags & STYP_LIT) == STYP_LIT)
379 sec_flags = (SEC_LOAD | SEC_ALLOC | SEC_READONLY);
380#endif /* STYP_LIT */
853f0a70
JG
381#ifdef STYP_OTHER_LOAD /* Other loaded sections */
382 if (styp_flags & STYP_OTHER_LOAD)
383 sec_flags = (SEC_LOAD | SEC_ALLOC);
384#endif /* STYP_SDATA */
41f50af0
SC
385
386 return(sec_flags);
387}
0f268757 388
fb3be09b
JG
389#define get_index(symbol) ((int) (symbol)->value)
390#define set_index(symbol, idx) ((symbol)->value = (idx))
0f268757 391
6f715d66
SC
392/* **********************************************************************
393Here are all the routines for swapping the structures seen in the
cbdc7909 394outside world into the internal forms.
0f268757
SC
395*/
396
397
2700c3c7 398static void
0f268757
SC
399DEFUN(bfd_swap_reloc_in,(abfd, reloc_src, reloc_dst),
400 bfd *abfd AND
401 RELOC *reloc_src AND
402 struct internal_reloc *reloc_dst)
403{
41f50af0
SC
404 reloc_dst->r_vaddr = bfd_h_get_32(abfd, (bfd_byte *)reloc_src->r_vaddr);
405 reloc_dst->r_symndx = bfd_h_get_32(abfd, (bfd_byte *) reloc_src->r_symndx);
cbdc7909
JG
406
407#ifdef RS6000COFF_C
408 reloc_dst->r_type = bfd_h_get_8(abfd, reloc_src->r_type);
409 reloc_dst->r_size = bfd_h_get_8(abfd, reloc_src->r_size);
410#else
41f50af0 411 reloc_dst->r_type = bfd_h_get_16(abfd, (bfd_byte *) reloc_src->r_type);
cbdc7909
JG
412#endif
413
3b4f1a5d 414#ifdef SWAP_IN_RELOC_OFFSET
9898b929
JG
415 reloc_dst->r_offset = SWAP_IN_RELOC_OFFSET(abfd,
416 (bfd_byte *) reloc_src->r_offset);
0f268757
SC
417#endif
418}
419
2700c3c7 420
0d740984
SC
421static unsigned int
422DEFUN(coff_swap_reloc_out,(abfd, src, dst),
423 bfd *abfd AND
424 PTR src AND
425 PTR dst)
0f268757 426{
0d740984
SC
427 struct internal_reloc *reloc_src = (struct internal_reloc *)src;
428 struct external_reloc *reloc_dst = (struct external_reloc *)dst;
41f50af0
SC
429 bfd_h_put_32(abfd, reloc_src->r_vaddr, (bfd_byte *) reloc_dst->r_vaddr);
430 bfd_h_put_32(abfd, reloc_src->r_symndx, (bfd_byte *) reloc_dst->r_symndx);
3b4f1a5d
SC
431 bfd_h_put_16(abfd, reloc_src->r_type, (bfd_byte *)
432 reloc_dst->r_type);
433
434#ifdef SWAP_OUT_RELOC_OFFSET
435 SWAP_OUT_RELOC_OFFSET(abfd,
436 reloc_src->r_offset,
437 (bfd_byte *) reloc_dst->r_offset);
438#endif
439#ifdef SWAP_OUT_RELOC_EXTRA
440 SWAP_OUT_RELOC_EXTRA(abfd,reloc_src, reloc_dst);
0f268757 441#endif
3b4f1a5d 442
0d740984 443 return sizeof(struct external_reloc);
0f268757
SC
444}
445
2700c3c7 446static void
0f268757
SC
447DEFUN(bfd_swap_filehdr_in,(abfd, filehdr_src, filehdr_dst),
448 bfd *abfd AND
449 FILHDR *filehdr_src AND
450 struct internal_filehdr *filehdr_dst)
451{
41f50af0
SC
452 filehdr_dst->f_magic = bfd_h_get_16(abfd, (bfd_byte *) filehdr_src->f_magic);
453 filehdr_dst->f_nscns = bfd_h_get_16(abfd, (bfd_byte *)filehdr_src-> f_nscns);
454 filehdr_dst->f_timdat = bfd_h_get_32(abfd, (bfd_byte *)filehdr_src-> f_timdat);
455 filehdr_dst->f_symptr = bfd_h_get_32(abfd, (bfd_byte *)filehdr_src-> f_symptr);
456 filehdr_dst->f_nsyms = bfd_h_get_32(abfd, (bfd_byte *)filehdr_src-> f_nsyms);
457 filehdr_dst->f_opthdr = bfd_h_get_16(abfd, (bfd_byte *)filehdr_src-> f_opthdr);
458 filehdr_dst->f_flags = bfd_h_get_16(abfd, (bfd_byte *)filehdr_src-> f_flags);
0f268757
SC
459}
460
0d740984
SC
461static unsigned int
462DEFUN(coff_swap_filehdr_out,(abfd, in, out),
463 bfd *abfd AND
464 PTR in AND
465 PTR out)
0f268757 466{
0d740984
SC
467 struct internal_filehdr *filehdr_in = (struct internal_filehdr *)in;
468 FILHDR *filehdr_out = (FILHDR *)out;
41f50af0
SC
469 bfd_h_put_16(abfd, filehdr_in->f_magic, (bfd_byte *) filehdr_out->f_magic);
470 bfd_h_put_16(abfd, filehdr_in->f_nscns, (bfd_byte *) filehdr_out->f_nscns);
471 bfd_h_put_32(abfd, filehdr_in->f_timdat, (bfd_byte *) filehdr_out->f_timdat);
472 bfd_h_put_32(abfd, filehdr_in->f_symptr, (bfd_byte *) filehdr_out->f_symptr);
473 bfd_h_put_32(abfd, filehdr_in->f_nsyms, (bfd_byte *) filehdr_out->f_nsyms);
474 bfd_h_put_16(abfd, filehdr_in->f_opthdr, (bfd_byte *) filehdr_out->f_opthdr);
475 bfd_h_put_16(abfd, filehdr_in->f_flags, (bfd_byte *) filehdr_out->f_flags);
0d740984 476 return sizeof(FILHDR);
0f268757
SC
477}
478
479
7a8b18b6 480#ifndef NO_COFF_SYMBOLS
2700c3c7 481
cbdc7909 482static void
6f715d66 483DEFUN(coff_swap_sym_in,(abfd, ext1, in1),
0f268757 484 bfd *abfd AND
6f715d66
SC
485 PTR ext1 AND
486 PTR in1)
0f268757 487{
6f715d66
SC
488 SYMENT *ext = (SYMENT *)ext1;
489 struct internal_syment *in = (struct internal_syment *)in1;
490
0f268757
SC
491 if( ext->e.e_name[0] == 0) {
492 in->_n._n_n._n_zeroes = 0;
41f50af0 493 in->_n._n_n._n_offset = bfd_h_get_32(abfd, (bfd_byte *) ext->e.e.e_offset);
0f268757
SC
494 }
495 else {
fb3be09b
JG
496#if SYMNMLEN != E_SYMNMLEN
497 -> Error, we need to cope with truncating or extending SYMNMLEN!;
498#else
0f268757 499 memcpy(in->_n._n_name, ext->e.e_name, SYMNMLEN);
fb3be09b 500#endif
0f268757 501 }
41f50af0
SC
502 in->n_value = bfd_h_get_32(abfd, (bfd_byte *) ext->e_value);
503 in->n_scnum = bfd_h_get_16(abfd, (bfd_byte *) ext->e_scnum);
0f268757 504 if (sizeof(ext->e_type) == 2){
41f50af0 505 in->n_type = bfd_h_get_16(abfd, (bfd_byte *) ext->e_type);
0f268757
SC
506 }
507 else {
41f50af0 508 in->n_type = bfd_h_get_32(abfd, (bfd_byte *) ext->e_type);
0f268757
SC
509 }
510 in->n_sclass = bfd_h_get_8(abfd, ext->e_sclass);
511 in->n_numaux = bfd_h_get_8(abfd, ext->e_numaux);
512}
513
0d740984
SC
514static unsigned int
515DEFUN(coff_swap_sym_out,(abfd, inp, extp),
516 bfd *abfd AND
517 PTR inp AND
518 PTR extp)
0f268757 519{
0d740984
SC
520 struct internal_syment *in = (struct internal_syment *)inp;
521 SYMENT *ext =(SYMENT *)extp;
0f268757 522 if(in->_n._n_name[0] == 0) {
41f50af0
SC
523 bfd_h_put_32(abfd, 0, (bfd_byte *) ext->e.e.e_zeroes);
524 bfd_h_put_32(abfd, in->_n._n_n._n_offset, (bfd_byte *) ext->e.e.e_offset);
0f268757
SC
525 }
526 else {
fb3be09b 527#if SYMNMLEN != E_SYMNMLEN
0d740984 528 -> Error, we need to cope with truncating or extending SYMNMLEN!;
fb3be09b 529#else
0f268757 530 memcpy(ext->e.e_name, in->_n._n_name, SYMNMLEN);
fb3be09b 531#endif
0f268757 532 }
41f50af0
SC
533 bfd_h_put_32(abfd, in->n_value , (bfd_byte *) ext->e_value);
534 bfd_h_put_16(abfd, in->n_scnum , (bfd_byte *) ext->e_scnum);
cbdc7909 535 if (sizeof(ext->e_type) == 2)
0f268757 536 {
41f50af0 537 bfd_h_put_16(abfd, in->n_type , (bfd_byte *) ext->e_type);
0f268757
SC
538 }
539 else
540 {
41f50af0 541 bfd_h_put_32(abfd, in->n_type , (bfd_byte *) ext->e_type);
0f268757
SC
542 }
543 bfd_h_put_8(abfd, in->n_sclass , ext->e_sclass);
544 bfd_h_put_8(abfd, in->n_numaux , ext->e_numaux);
0d740984 545 return sizeof(SYMENT);
0f268757
SC
546}
547
2700c3c7 548static void
6f715d66 549DEFUN(coff_swap_aux_in,(abfd, ext1, type, class, in1),
0f268757 550 bfd *abfd AND
fb3be09b 551 PTR ext1 AND
0f268757
SC
552 int type AND
553 int class AND
fb3be09b 554 PTR in1)
0f268757 555{
6f715d66
SC
556 AUXENT *ext = (AUXENT *)ext1;
557 union internal_auxent *in = (union internal_auxent *)in1;
0f268757
SC
558 switch (class) {
559 case C_FILE:
560 if (ext->x_file.x_fname[0] == 0) {
561 in->x_file.x_n.x_zeroes = 0;
6d7c88c3
JG
562 in->x_file.x_n.x_offset =
563 bfd_h_get_32(abfd, (bfd_byte *) ext->x_file.x_n.x_offset);
2099685b 564 } else {
fb3be09b
JG
565#if FILNMLEN != E_FILNMLEN
566 -> Error, we need to cope with truncating or extending FILNMLEN!;
567#else
568 memcpy (in->x_file.x_fname, ext->x_file.x_fname, FILNMLEN);
569#endif
0f268757 570 }
6d7c88c3 571 break;
0f268757 572
6d7c88c3
JG
573 /* RS/6000 "csect" auxents */
574#ifdef RS6000COFF_C
575 case C_EXT:
576 case C_HIDEXT:
577 in->x_csect.x_scnlen = bfd_h_get_32 (abfd, (bfd_byte *) ext->x_csect.x_scnlen);
578 in->x_csect.x_parmhash = bfd_h_get_32 (abfd, (bfd_byte *) ext->x_csect.x_parmhash);
579 in->x_csect.x_snhash = bfd_h_get_16 (abfd, (bfd_byte *) ext->x_csect.x_snhash);
580 /* We don't have to hack bitfields in x_smtyp because it's defined by
581 shifts-and-ands, which are equivalent on all byte orders. */
582 in->x_csect.x_smtyp = bfd_h_get_8 (abfd, (bfd_byte *) ext->x_csect.x_smtyp);
583 in->x_csect.x_smclas = bfd_h_get_8 (abfd, (bfd_byte *) ext->x_csect.x_smclas);
584 in->x_csect.x_stab = bfd_h_get_32 (abfd, (bfd_byte *) ext->x_csect.x_stab);
585 in->x_csect.x_snstab = bfd_h_get_16 (abfd, (bfd_byte *) ext->x_csect.x_snstab);
0f268757 586 break;
6d7c88c3
JG
587#endif
588
0f268757
SC
589 case C_STAT:
590#ifdef C_LEAFSTAT
591 case C_LEAFSTAT:
592#endif
593 case C_HIDDEN:
594 if (type == T_NULL) {
6f715d66
SC
595 in->x_scn.x_scnlen = GET_SCN_SCNLEN(abfd, ext);
596 in->x_scn.x_nreloc = GET_SCN_NRELOC(abfd, ext);
597 in->x_scn.x_nlinno = GET_SCN_NLINNO(abfd, ext);
0f268757
SC
598 break;
599 }
600 default:
41f50af0 601 in->x_sym.x_tagndx.l = bfd_h_get_32(abfd, (bfd_byte *) ext->x_sym.x_tagndx);
6f715d66 602#ifndef NO_TVNDX
41f50af0 603 in->x_sym.x_tvndx = bfd_h_get_16(abfd, (bfd_byte *) ext->x_sym.x_tvndx);
6f715d66 604#endif
0f268757
SC
605
606 if (ISARY(type) || class == C_BLOCK) {
fb3be09b
JG
607#if DIMNUM != E_DIMNUM
608 -> Error, we need to cope with truncating or extending DIMNUM!;
609#else
41f50af0
SC
610 in->x_sym.x_fcnary.x_ary.x_dimen[0] = bfd_h_get_16(abfd, (bfd_byte *) ext->x_sym.x_fcnary.x_ary.x_dimen[0]);
611 in->x_sym.x_fcnary.x_ary.x_dimen[1] = bfd_h_get_16(abfd, (bfd_byte *) ext->x_sym.x_fcnary.x_ary.x_dimen[1]);
612 in->x_sym.x_fcnary.x_ary.x_dimen[2] = bfd_h_get_16(abfd, (bfd_byte *) ext->x_sym.x_fcnary.x_ary.x_dimen[2]);
613 in->x_sym.x_fcnary.x_ary.x_dimen[3] = bfd_h_get_16(abfd, (bfd_byte *) ext->x_sym.x_fcnary.x_ary.x_dimen[3]);
fb3be09b 614#endif
0f268757 615 }
6f715d66
SC
616 in->x_sym.x_fcnary.x_fcn.x_lnnoptr = GET_FCN_LNNOPTR(abfd, ext);
617 in->x_sym.x_fcnary.x_fcn.x_endndx.l = GET_FCN_ENDNDX(abfd, ext);
618
0f268757 619 if (ISFCN(type)) {
41f50af0 620 in->x_sym.x_misc.x_fsize = bfd_h_get_32(abfd, (bfd_byte *) ext->x_sym.x_misc.x_fsize);
0f268757
SC
621 }
622 else {
6f715d66
SC
623 in->x_sym.x_misc.x_lnsz.x_lnno = GET_LNSZ_LNNO(abfd, ext);
624 in->x_sym.x_misc.x_lnsz.x_size = GET_LNSZ_SIZE(abfd, ext);
0f268757
SC
625 }
626 }
627}
628
0d740984
SC
629static unsigned int
630DEFUN(coff_swap_aux_out,(abfd, inp, type, class, extp),
0f268757 631 bfd *abfd AND
0d740984
SC
632 PTR inp AND
633 int type AND
634 int class AND
635 PTR extp)
0f268757 636{
0d740984
SC
637 union internal_auxent *in = (union internal_auxent *)inp;
638 AUXENT *ext = (AUXENT *)extp;
0f268757
SC
639 switch (class) {
640 case C_FILE:
641 if (in->x_file.x_fname[0] == 0) {
cbdc7909 642 PUTWORD(abfd, 0, (bfd_byte *) ext->x_file.x_n.x_zeroes);
0d740984
SC
643 PUTWORD(abfd,
644 in->x_file.x_n.x_offset,
645 (bfd_byte *) ext->x_file.x_n.x_offset);
0f268757 646 }
6f715d66 647 else {
fb3be09b 648#if FILNMLEN != E_FILNMLEN
0d740984 649 -> Error, we need to cope with truncating or extending FILNMLEN!;
fb3be09b
JG
650#else
651 memcpy (ext->x_file.x_fname, in->x_file.x_fname, FILNMLEN);
652#endif
cbdc7909 653 }
0f268757 654 break;
6d7c88c3
JG
655
656#ifdef RS6000COFF_C
657 /* RS/6000 "csect" auxents */
658 case C_EXT:
659 case C_HIDEXT:
660 PUTWORD (abfd, in->x_csect.x_scnlen, ext->x_csect.x_scnlen);
661 PUTWORD (abfd, in->x_csect.x_parmhash, ext->x_csect.x_parmhash);
662 PUTHALF (abfd, in->x_csect.x_snhash, ext->x_csect.x_snhash);
663 /* We don't have to hack bitfields in x_smtyp because it's defined by
664 shifts-and-ands, which are equivalent on all byte orders. */
665 PUTBYTE (abfd, in->x_csect.x_smtyp, ext->x_csect.x_smtyp);
666 PUTBYTE (abfd, in->x_csect.x_smclas, ext->x_csect.x_smclas);
667 PUTWORD (abfd, in->x_csect.x_stab, ext->x_csect.x_stab);
668 PUTHALF (abfd, in->x_csect.x_snstab, ext->x_csect.x_snstab);
669 break;
670#endif
671
0f268757
SC
672 case C_STAT:
673#ifdef C_LEAFSTAT
674 case C_LEAFSTAT:
675#endif
676 case C_HIDDEN:
677 if (type == T_NULL) {
6f715d66
SC
678 PUT_SCN_SCNLEN(abfd, in->x_scn.x_scnlen, ext);
679 PUT_SCN_NRELOC(abfd, in->x_scn.x_nreloc, ext);
680 PUT_SCN_NLINNO(abfd, in->x_scn.x_nlinno, ext);
0f268757
SC
681 break;
682 }
683 default:
41f50af0 684 PUTWORD(abfd, in->x_sym.x_tagndx.l, (bfd_byte *) ext->x_sym.x_tagndx);
6f715d66 685#ifndef NO_TVNDX
41f50af0 686 PUTWORD(abfd, in->x_sym.x_tvndx , (bfd_byte *) ext->x_sym.x_tvndx);
6f715d66 687#endif
0f268757 688
0f268757 689 if (ISFCN(type)) {
41f50af0 690 PUTWORD(abfd, in->x_sym.x_misc.x_fsize, (bfd_byte *) ext->x_sym.x_misc.x_fsize);
6f715d66
SC
691 PUT_FCN_LNNOPTR(abfd, in->x_sym.x_fcnary.x_fcn.x_lnnoptr, ext);
692 PUT_FCN_ENDNDX(abfd, in->x_sym.x_fcnary.x_fcn.x_endndx.l, ext);
0f268757
SC
693 }
694 else {
6f715d66
SC
695
696 if (ISARY(type) || class == C_BLOCK) {
fb3be09b 697#if DIMNUM != E_DIMNUM
0d740984 698 -> Error, we need to cope with truncating or extending DIMNUM!;
fb3be09b 699#else
41f50af0
SC
700 bfd_h_put_16(abfd, in->x_sym.x_fcnary.x_ary.x_dimen[0], (bfd_byte *)ext->x_sym.x_fcnary.x_ary.x_dimen[0]);
701 bfd_h_put_16(abfd, in->x_sym.x_fcnary.x_ary.x_dimen[1], (bfd_byte *)ext->x_sym.x_fcnary.x_ary.x_dimen[1]);
702 bfd_h_put_16(abfd, in->x_sym.x_fcnary.x_ary.x_dimen[2], (bfd_byte *)ext->x_sym.x_fcnary.x_ary.x_dimen[2]);
703 bfd_h_put_16(abfd, in->x_sym.x_fcnary.x_ary.x_dimen[3], (bfd_byte *)ext->x_sym.x_fcnary.x_ary.x_dimen[3]);
fb3be09b 704#endif
6f715d66 705 }
0d740984
SC
706 PUT_LNSZ_LNNO(abfd, in->x_sym.x_misc.x_lnsz.x_lnno, ext);
707 PUT_LNSZ_SIZE(abfd, in->x_sym.x_misc.x_lnsz.x_size, ext);
6f715d66
SC
708
709 PUT_FCN_LNNOPTR(abfd, in->x_sym.x_fcnary.x_fcn.x_lnnoptr, ext);
710 PUT_FCN_ENDNDX(abfd, in->x_sym.x_fcnary.x_fcn.x_endndx.l, ext);
711
712
0f268757
SC
713 }
714 }
0d740984 715return sizeof(AUXENT);
0f268757
SC
716}
717
7a8b18b6
SC
718#endif /* NO_COFF_SYMBOLS */
719
720#ifndef NO_COFF_LINENOS
721
6f715d66
SC
722static void
723DEFUN(coff_swap_lineno_in,(abfd, ext1, in1),
0f268757 724 bfd *abfd AND
6f715d66
SC
725 PTR ext1 AND
726 PTR in1)
0f268757 727{
6f715d66
SC
728 LINENO *ext = (LINENO *)ext1;
729 struct internal_lineno *in = (struct internal_lineno *)in1;
730
41f50af0 731 in->l_addr.l_symndx = bfd_h_get_32(abfd, (bfd_byte *) ext->l_addr.l_symndx);
85e0c721 732 in->l_lnno = GET_LINENO_LNNO(abfd, ext);
0f268757
SC
733}
734
0d740984
SC
735static unsigned int
736DEFUN(coff_swap_lineno_out,(abfd, inp, outp),
737 bfd *abfd AND
738 PTR inp AND
739 PTR outp)
0f268757 740{
0d740984
SC
741 struct internal_lineno *in = (struct internal_lineno *)inp;
742 struct external_lineno *ext = (struct external_lineno *)outp;
85e0c721
SC
743 PUTWORD(abfd, in->l_addr.l_symndx, (bfd_byte *)
744 ext->l_addr.l_symndx);
745
746 PUT_LINENO_LNNO (abfd, in->l_lnno, ext);
0d740984 747 return sizeof(struct external_lineno);
0f268757
SC
748}
749
7a8b18b6 750#endif /* NO_COFF_LINENOS */
0f268757
SC
751
752
cbdc7909 753static void
6f715d66 754DEFUN(bfd_swap_aouthdr_in,(abfd, aouthdr_ext1, aouthdr_int1),
0f268757 755 bfd *abfd AND
6f715d66
SC
756 PTR aouthdr_ext1 AND
757 PTR aouthdr_int1)
0f268757 758{
6f715d66
SC
759 AOUTHDR *aouthdr_ext = (AOUTHDR *) aouthdr_ext1;
760 struct internal_aouthdr *aouthdr_int = (struct internal_aouthdr *)aouthdr_int1;
761
41f50af0
SC
762 aouthdr_int->magic = bfd_h_get_16(abfd, (bfd_byte *) aouthdr_ext->magic);
763 aouthdr_int->vstamp = bfd_h_get_16(abfd, (bfd_byte *) aouthdr_ext->vstamp);
764 aouthdr_int->tsize = bfd_h_get_32(abfd, (bfd_byte *) aouthdr_ext->tsize);
765 aouthdr_int->dsize = bfd_h_get_32(abfd, (bfd_byte *) aouthdr_ext->dsize);
766 aouthdr_int->bsize = bfd_h_get_32(abfd, (bfd_byte *) aouthdr_ext->bsize);
767 aouthdr_int->entry = bfd_h_get_32(abfd, (bfd_byte *) aouthdr_ext->entry);
768 aouthdr_int->text_start = bfd_h_get_32(abfd, (bfd_byte *) aouthdr_ext->text_start);
769 aouthdr_int->data_start = bfd_h_get_32(abfd, (bfd_byte *) aouthdr_ext->data_start);
0f268757 770#ifdef I960
41f50af0 771 aouthdr_int->tagentries = bfd_h_get_32(abfd, (bfd_byte *) aouthdr_ext->tagentries);
0f268757 772#endif
cbdc7909
JG
773
774#ifdef RS6000COFF_C
775 aouthdr_int->o_toc = bfd_h_get_32(abfd, aouthdr_ext->o_toc);
776 aouthdr_int->o_snentry = bfd_h_get_16(abfd, aouthdr_ext->o_snentry);
777 aouthdr_int->o_sntext = bfd_h_get_16(abfd, aouthdr_ext->o_sntext);
778 aouthdr_int->o_sndata = bfd_h_get_16(abfd, aouthdr_ext->o_sndata);
779 aouthdr_int->o_sntoc = bfd_h_get_16(abfd, aouthdr_ext->o_sntoc);
780 aouthdr_int->o_snloader = bfd_h_get_16(abfd, aouthdr_ext->o_snloader);
781 aouthdr_int->o_snbss = bfd_h_get_16(abfd, aouthdr_ext->o_snbss);
782 aouthdr_int->o_algntext = bfd_h_get_16(abfd, aouthdr_ext->o_algntext);
783 aouthdr_int->o_algndata = bfd_h_get_16(abfd, aouthdr_ext->o_algndata);
784 aouthdr_int->o_modtype = bfd_h_get_16(abfd, aouthdr_ext->o_modtype);
785 aouthdr_int->o_maxstack = bfd_h_get_32(abfd, aouthdr_ext->o_maxstack);
786#endif
0f268757
SC
787}
788
0d740984
SC
789static unsigned int
790DEFUN(coff_swap_aouthdr_out,(abfd, in, out),
791 bfd *abfd AND
792 PTR in AND
793 PTR out)
0f268757 794{
0d740984
SC
795 struct internal_aouthdr *aouthdr_in = (struct internal_aouthdr *)in;
796 AOUTHDR *aouthdr_out = (AOUTHDR *)out;
41f50af0
SC
797 bfd_h_put_16(abfd, aouthdr_in->magic, (bfd_byte *) aouthdr_out->magic);
798 bfd_h_put_16(abfd, aouthdr_in->vstamp, (bfd_byte *) aouthdr_out->vstamp);
799 bfd_h_put_32(abfd, aouthdr_in->tsize, (bfd_byte *) aouthdr_out->tsize);
800 bfd_h_put_32(abfd, aouthdr_in->dsize, (bfd_byte *) aouthdr_out->dsize);
801 bfd_h_put_32(abfd, aouthdr_in->bsize, (bfd_byte *) aouthdr_out->bsize);
802 bfd_h_put_32(abfd, aouthdr_in->entry, (bfd_byte *) aouthdr_out->entry);
0d740984
SC
803 bfd_h_put_32(abfd, aouthdr_in->text_start,
804 (bfd_byte *) aouthdr_out->text_start);
41f50af0 805 bfd_h_put_32(abfd, aouthdr_in->data_start, (bfd_byte *) aouthdr_out->data_start);
0f268757 806#ifdef I960
41f50af0 807 bfd_h_put_32(abfd, aouthdr_in->tagentries, (bfd_byte *) aouthdr_out->tagentries);
0f268757 808#endif
0d740984 809 return sizeof(AOUTHDR);
0f268757
SC
810}
811
cbdc7909 812static void
2700c3c7 813DEFUN(coff_swap_scnhdr_in,(abfd, scnhdr_ext, scnhdr_int),
0f268757
SC
814 bfd *abfd AND
815 SCNHDR *scnhdr_ext AND
816 struct internal_scnhdr *scnhdr_int)
817{
818 memcpy(scnhdr_int->s_name, scnhdr_ext->s_name, sizeof(scnhdr_int->s_name));
41f50af0
SC
819 scnhdr_int->s_vaddr = bfd_h_get_32(abfd, (bfd_byte *) scnhdr_ext->s_vaddr);
820 scnhdr_int->s_paddr = bfd_h_get_32(abfd, (bfd_byte *) scnhdr_ext->s_paddr);
821 scnhdr_int->s_size = bfd_h_get_32(abfd, (bfd_byte *) scnhdr_ext->s_size);
822 scnhdr_int->s_scnptr = bfd_h_get_32(abfd, (bfd_byte *) scnhdr_ext->s_scnptr);
823 scnhdr_int->s_relptr = bfd_h_get_32(abfd, (bfd_byte *) scnhdr_ext->s_relptr);
824 scnhdr_int->s_lnnoptr = bfd_h_get_32(abfd, (bfd_byte *) scnhdr_ext->s_lnnoptr);
825 scnhdr_int->s_flags = bfd_h_get_32(abfd, (bfd_byte *) scnhdr_ext->s_flags);
6f715d66 826#if defined(M88)
41f50af0
SC
827 scnhdr_int->s_nreloc = bfd_h_get_32(abfd, (bfd_byte *) scnhdr_ext->s_nreloc);
828 scnhdr_int->s_nlnno = bfd_h_get_32(abfd, (bfd_byte *) scnhdr_ext->s_nlnno);
6f715d66 829#else
41f50af0
SC
830 scnhdr_int->s_nreloc = bfd_h_get_16(abfd, (bfd_byte *) scnhdr_ext->s_nreloc);
831 scnhdr_int->s_nlnno = bfd_h_get_16(abfd, (bfd_byte *) scnhdr_ext->s_nlnno);
6f715d66 832#endif
0f268757 833#ifdef I960
41f50af0 834 scnhdr_int->s_align = bfd_h_get_32(abfd, (bfd_byte *) scnhdr_ext->s_align);
0f268757
SC
835#endif
836}
837
cbdc7909 838static unsigned int
0d740984
SC
839DEFUN(coff_swap_scnhdr_out,(abfd, in, out),
840 bfd *abfd AND
841 PTR in AND
842 PTR out)
0f268757 843{
0d740984
SC
844 struct internal_scnhdr *scnhdr_int = (struct internal_scnhdr *)in;
845 SCNHDR *scnhdr_ext = (SCNHDR *)out;
0f268757 846 memcpy(scnhdr_ext->s_name, scnhdr_int->s_name, sizeof(scnhdr_int->s_name));
41f50af0
SC
847 PUTWORD(abfd, scnhdr_int->s_vaddr, (bfd_byte *) scnhdr_ext->s_vaddr);
848 PUTWORD(abfd, scnhdr_int->s_paddr, (bfd_byte *) scnhdr_ext->s_paddr);
849 PUTWORD(abfd, scnhdr_int->s_size, (bfd_byte *) scnhdr_ext->s_size);
850 PUTWORD(abfd, scnhdr_int->s_scnptr, (bfd_byte *) scnhdr_ext->s_scnptr);
851 PUTWORD(abfd, scnhdr_int->s_relptr, (bfd_byte *) scnhdr_ext->s_relptr);
852 PUTWORD(abfd, scnhdr_int->s_lnnoptr, (bfd_byte *) scnhdr_ext->s_lnnoptr);
2f8d9c1c 853 PUTWORD(abfd, scnhdr_int->s_flags, (bfd_byte *) scnhdr_ext->s_flags);
6f715d66 854#if defined(M88)
41f50af0 855 PUTWORD(abfd, scnhdr_int->s_nlnno, (bfd_byte *) scnhdr_ext->s_nlnno);
41f50af0 856 PUTWORD(abfd, scnhdr_int->s_nreloc, (bfd_byte *) scnhdr_ext->s_nreloc);
6f715d66 857#else
41f50af0 858 PUTHALF(abfd, scnhdr_int->s_nlnno, (bfd_byte *) scnhdr_ext->s_nlnno);
41f50af0 859 PUTHALF(abfd, scnhdr_int->s_nreloc, (bfd_byte *) scnhdr_ext->s_nreloc);
6f715d66
SC
860#endif
861
cbdc7909 862#if defined(I960)
41f50af0 863 PUTWORD(abfd, scnhdr_int->s_align, (bfd_byte *) scnhdr_ext->s_align);
0f268757 864#endif
0d740984 865 return sizeof(SCNHDR);
0f268757
SC
866}
867
6f715d66 868
0f268757
SC
869/*
870 initialize a section structure with information peculiar to this
871 particular implementation of coff
872*/
873
874static boolean
875DEFUN(coff_new_section_hook,(abfd_ignore, section_ignore),
876 bfd *abfd_ignore AND
877 asection *section_ignore)
878{
6f715d66 879 section_ignore->alignment_power = abfd_ignore->xvec->align_power_min;
0f268757
SC
880 return true;
881}
882
883/* Take a section header read from a coff file (in HOST byte order),
884 and make a BFD "section" out of it. */
885static boolean
886DEFUN(make_a_section_from_file,(abfd, hdr),
887 bfd *abfd AND
888 struct internal_scnhdr *hdr)
889{
890 asection *return_section;
891
892 {
893 /* Assorted wastage to null-terminate the name, thanks AT&T! */
894 char *name = bfd_alloc(abfd, sizeof (hdr->s_name)+1);
895 if (name == NULL) {
896 bfd_error = no_memory;
897 return false;
898 }
899 strncpy(name, (char *) &hdr->s_name[0], sizeof (hdr->s_name));
900 name[sizeof (hdr->s_name)] = 0;
901
902 return_section = bfd_make_section(abfd, name);
cbdc7909
JG
903 if (return_section == NULL)
904 return false;
0f268757
SC
905 }
906
907 /* s_paddr is presumed to be = to s_vaddr */
908#define assign(to, from) return_section->to = hdr->from
909 assign(vma, s_vaddr);
910 /* assign (vma, s_vaddr); */
911 assign(size, s_size);
912 assign(filepos, s_scnptr);
913 assign(rel_filepos, s_relptr);
914 assign(reloc_count, s_nreloc);
915#ifdef I960
916 {
917 /* FIXME, use a temp var rather than alignment_power */
918 assign(alignment_power, s_align);
919 {
920 unsigned int i;
921 for (i = 0; i < 32; i++) {
922 if ((1 << i) >= (int) (return_section->alignment_power)) {
923 return_section->alignment_power = i;
924 break;
925 }
926 }
927 }
928 }
929#endif
930 assign(line_filepos, s_lnnoptr);
931 /*
932 return_section->linesize = hdr->s_nlnno * sizeof (struct lineno);
933 */
934
0f268757
SC
935 return_section->lineno_count = hdr->s_nlnno;
936 return_section->userdata = NULL;
937 return_section->next = (asection *) NULL;
41f50af0
SC
938 return_section->flags = styp_to_sec_flags(hdr->s_flags);
939
0f268757
SC
940
941 if (hdr->s_nreloc != 0)
942 return_section->flags |= SEC_RELOC;
41f50af0 943 /* FIXME: should this check 'hdr->s_size > 0' */
0f268757
SC
944 if (hdr->s_scnptr != 0)
945 return_section->flags |= SEC_HAS_CONTENTS;
946 return true;
947}
948static boolean
949DEFUN(coff_mkobject,(abfd),
950 bfd *abfd)
951{
952 set_tdata (abfd, bfd_zalloc (abfd,sizeof(coff_data_type)));
953 if (coff_data(abfd) == 0) {
954 bfd_error = no_memory;
955 return false;
956 }
957 coff_data(abfd)->relocbase = 0;
958 return true;
959}
960
961static
962bfd_target *
963DEFUN(coff_real_object_p,(abfd, nscns, internal_f, internal_a),
964 bfd *abfd AND
965 unsigned nscns AND
966 struct internal_filehdr *internal_f AND
967 struct internal_aouthdr *internal_a)
968{
969 coff_data_type *coff;
0d740984
SC
970 enum bfd_architecture arch;
971 long machine;
0f268757
SC
972 size_t readsize; /* length of file_info */
973 SCNHDR *external_sections;
cbdc7909 974
0f268757
SC
975 /* Build a play area */
976 if (coff_mkobject(abfd) != true)
977 return 0;
978 coff = coff_data(abfd);
cbdc7909
JG
979
980
0f268757 981 external_sections = (SCNHDR *)bfd_alloc(abfd, readsize = (nscns * SCNHSZ));
cbdc7909 982
0f268757
SC
983 if (bfd_read((PTR)external_sections, 1, readsize, abfd) != readsize) {
984 goto fail;
985 }
cbdc7909
JG
986
987
0f268757
SC
988 /* Now copy data as required; construct all asections etc */
989 coff->symbol_index_slew = 0;
990 coff->relocbase =0;
991 coff->raw_syment_count = 0;
992 coff->raw_linenos = 0;
993 coff->raw_syments = 0;
994 coff->sym_filepos =0;
995 coff->flags = internal_f->f_flags;
996 if (nscns != 0) {
997 unsigned int i;
998 for (i = 0; i < nscns; i++) {
999 struct internal_scnhdr tmp;
2700c3c7 1000 coff_swap_scnhdr_in(abfd, external_sections + i, &tmp);
0f268757
SC
1001 make_a_section_from_file(abfd,&tmp);
1002 }
1003 }
1004 /* Determine the machine architecture and type. */
0d740984 1005machine = 0;
0f268757 1006 switch (internal_f->f_magic) {
20fdc627
SC
1007#ifdef I386MAGIC
1008 case I386MAGIC:
0d740984
SC
1009 arch = bfd_arch_i386;
1010 machine = 0;
20fdc627
SC
1011 break;
1012#endif
cbdc7909
JG
1013
1014#ifdef A29K_MAGIC_BIG
41f50af0
SC
1015 case A29K_MAGIC_BIG:
1016 case A29K_MAGIC_LITTLE:
0d740984
SC
1017 arch = bfd_arch_a29k;
1018 machine = 0;
41f50af0
SC
1019 break;
1020#endif
cbdc7909 1021
0f268757 1022#ifdef MIPS
20fdc627
SC
1023 case MIPS_MAGIC_1:
1024 case MIPS_MAGIC_2:
1025 case MIPS_MAGIC_3:
0d740984
SC
1026 arch = bfd_arch_mips;
1027 machine = 0;
0f268757
SC
1028 break;
1029#endif
cbdc7909 1030
0f268757
SC
1031#ifdef MC68MAGIC
1032 case MC68MAGIC:
1033 case M68MAGIC:
0d740984
SC
1034 arch = bfd_arch_m68k;
1035 machine = 68020;
0f268757
SC
1036 break;
1037#endif
1038#ifdef MC88MAGIC
1039 case MC88MAGIC:
1040 case MC88DMAGIC:
1041 case MC88OMAGIC:
0d740984
SC
1042 arch = bfd_arch_m88k;
1043 machine = 88100;
0f268757
SC
1044 break;
1045#endif
1046#ifdef I960
1047#ifdef I960ROMAGIC
1048 case I960ROMAGIC:
1049 case I960RWMAGIC:
0d740984 1050 arch = bfd_arch_i960;
cbdc7909 1051 switch (F_I960TYPE & internal_f->f_flags)
0f268757
SC
1052 {
1053 default:
1054 case F_I960CORE:
0d740984 1055 machine = bfd_mach_i960_core;
0f268757
SC
1056 break;
1057 case F_I960KB:
0d740984 1058 machine = bfd_mach_i960_kb_sb;
0f268757 1059 break;
0d740984
SC
1060 case F_I960MC:
1061 machine = bfd_mach_i960_mc;
0f268757
SC
1062 break;
1063 case F_I960XA:
0d740984 1064 machine = bfd_mach_i960_xa;
0f268757
SC
1065 break;
1066 case F_I960CA:
0d740984 1067 machine = bfd_mach_i960_ca;
0f268757
SC
1068 break;
1069 case F_I960KA:
0d740984 1070 machine = bfd_mach_i960_ka_sa;
0f268757 1071 break;
0f268757
SC
1072 }
1073 break;
1074#endif
1075#endif
cbdc7909
JG
1076
1077#ifdef U802ROMAGIC
1078 case U802ROMAGIC:
1079 case U802WRMAGIC:
1080 case U802TOCMAGIC:
1081 arch = bfd_arch_rs6000;
1082 machine = 6000;
1083 break;
1084#endif
1085
3b4f1a5d
SC
1086#ifdef H8300MAGIC
1087 case H8300MAGIC:
1088 arch = bfd_arch_h8300;
1089 machine = 0;
1090 break;
1091#endif
cbdc7909 1092
0f268757 1093 default: /* Unreadable input file type */
0d740984 1094 arch = bfd_arch_obscure;
0f268757
SC
1095 break;
1096 }
cbdc7909 1097
0d740984 1098 bfd_default_set_arch_mach(abfd, arch, machine);
0f268757
SC
1099 if (!(internal_f->f_flags & F_RELFLG))
1100 abfd->flags |= HAS_RELOC;
1101 if ((internal_f->f_flags & F_EXEC))
1102 abfd->flags |= EXEC_P;
1103 if (!(internal_f->f_flags & F_LNNO))
1104 abfd->flags |= HAS_LINENO;
1105 if (!(internal_f->f_flags & F_LSYMS))
1106 abfd->flags |= HAS_LOCALS;
cbdc7909
JG
1107
1108
0f268757
SC
1109 bfd_get_symcount(abfd) = internal_f->f_nsyms;
1110 if (internal_f->f_nsyms)
1111 abfd->flags |= HAS_SYMS;
cbdc7909 1112
0f268757 1113 coff->sym_filepos = internal_f->f_symptr;
cbdc7909 1114
fb3be09b 1115 /* These members communicate important constants about the symbol table
0d740984
SC
1116 to GDB's symbol-reading code. These `constants' unfortunately vary
1117 from coff implementation to implementation... */
fb3be09b
JG
1118#ifndef NO_COFF_SYMBOLS
1119 coff->local_n_btmask = N_BTMASK;
1120 coff->local_n_btshft = N_BTSHFT;
1121 coff->local_n_tmask = N_TMASK;
1122 coff->local_n_tshift = N_TSHIFT;
1123 coff->local_symesz = SYMESZ;
1124 coff->local_auxesz = AUXESZ;
1125 coff->local_linesz = LINESZ;
1126#endif
cbdc7909 1127
0f268757
SC
1128 coff->symbols = (coff_symbol_type *) NULL;
1129 bfd_get_start_address(abfd) = internal_f->f_opthdr ? internal_a->entry : 0;
cbdc7909 1130
0f268757
SC
1131 return abfd->xvec;
1132 fail:
1133 bfd_release(abfd, coff);
1134 return (bfd_target *)NULL;
1135}
1136
1137static bfd_target *
1138DEFUN(coff_object_p,(abfd),
1139 bfd *abfd)
6f715d66
SC
1140{
1141 int nscns;
1142 FILHDR filehdr;
1143 AOUTHDR opthdr;
1144 struct internal_filehdr internal_f;
1145 struct internal_aouthdr internal_a;
cbdc7909 1146
6f715d66 1147 bfd_error = system_call_error;
cbdc7909 1148
6f715d66
SC
1149 /* figure out how much to read */
1150 if (bfd_read((PTR) &filehdr, 1, FILHSZ, abfd) != FILHSZ)
1151 return 0;
cbdc7909 1152
6f715d66 1153 bfd_swap_filehdr_in(abfd, &filehdr, &internal_f);
cbdc7909 1154
6f715d66
SC
1155 if (BADMAG(internal_f)) {
1156 bfd_error = wrong_format;
1157 return 0;
1158 }
1159 nscns =internal_f.f_nscns;
cbdc7909 1160
6f715d66
SC
1161 if (internal_f.f_opthdr) {
1162 if (bfd_read((PTR) &opthdr, 1,AOUTSZ, abfd) != AOUTSZ) {
1163 return 0;
0f268757 1164 }
7d003262 1165 bfd_swap_aouthdr_in(abfd, (char *)&opthdr, (char *)&internal_a);
6f715d66 1166 }
cbdc7909 1167
6f715d66
SC
1168 /* Seek past the opt hdr stuff */
1169 bfd_seek(abfd, internal_f.f_opthdr + FILHSZ, SEEK_SET);
cbdc7909 1170
6f715d66
SC
1171 /* if the optional header is NULL or not the correct size then
1172 quit; the only difference I can see between m88k dgux headers (MC88DMAGIC)
1173 and Intel 960 readwrite headers (I960WRMAGIC) is that the
1174 optional header is of a different size.
cbdc7909 1175
6f715d66
SC
1176 But the mips keeps extra stuff in it's opthdr, so dont check
1177 when doing that
1178 */
cbdc7909 1179
0d740984 1180#if defined(M88) || defined(I960)
6f715d66
SC
1181 if (internal_f.f_opthdr != 0 && AOUTSZ != internal_f.f_opthdr)
1182 return (bfd_target *)NULL;
0f268757 1183#endif
cbdc7909 1184
6f715d66
SC
1185 return coff_real_object_p(abfd, nscns, &internal_f, &internal_a);
1186}
0f268757
SC
1187
1188
1189
7a8b18b6 1190#ifndef NO_COFF_LINENOS
0f268757 1191
cbdc7909 1192static void
0f268757
SC
1193DEFUN(coff_count_linenumbers,(abfd),
1194 bfd *abfd)
6f715d66
SC
1195{
1196 unsigned int limit = bfd_get_symcount(abfd);
1197 unsigned int i;
1198 asymbol **p;
1199 {
1200 asection *s = abfd->sections->output_section;
1201 while (s) {
1202 BFD_ASSERT(s->lineno_count == 0);
1203 s = s->next;
20fdc627 1204 }
6f715d66 1205 }
cbdc7909
JG
1206
1207
6f715d66
SC
1208 for (p = abfd->outsymbols, i = 0; i < limit; i++, p++) {
1209 asymbol *q_maybe = *p;
0d740984 1210 if (q_maybe->the_bfd->xvec->flavour == bfd_target_coff_flavour) {
6f715d66
SC
1211 coff_symbol_type *q = coffsymbol(q_maybe);
1212 if (q->lineno) {
1213 /*
1214 This symbol has a linenumber, increment the owning
1215 section's linenumber count
1216 */
1217 alent *l = q->lineno;
1218 q->symbol.section->output_section->lineno_count++;
1219 l++;
1220 while (l->line_number) {
20fdc627
SC
1221 q->symbol.section->output_section->lineno_count++;
1222 l++;
0f268757 1223 }
20fdc627 1224 }
0f268757 1225 }
20fdc627 1226 }
6f715d66 1227}
0f268757 1228
7a8b18b6
SC
1229#endif /* NO_COFF_LINENOS */
1230
1231#ifndef NO_COFF_SYMBOLS
1232
cbdc7909 1233/*
0d740984
SC
1234 Takes a bfd and a symbol, returns a pointer to the coff specific area
1235 of the symbol if there is one.
1236 */
7a8b18b6 1237static coff_symbol_type *
fb3be09b
JG
1238DEFUN(coff_symbol_from,(ignore_abfd, symbol),
1239 bfd *ignore_abfd AND
7a8b18b6
SC
1240 asymbol *symbol)
1241{
cbdc7909 1242 if (symbol->the_bfd->xvec->flavour != bfd_target_coff_flavour)
7a8b18b6 1243 return (coff_symbol_type *)NULL;
cbdc7909 1244
7a8b18b6
SC
1245 if (symbol->the_bfd->tdata == (PTR)NULL)
1246 return (coff_symbol_type *)NULL;
cbdc7909 1247
7a8b18b6
SC
1248 return (coff_symbol_type *) symbol;
1249}
1250
0f268757 1251
0f268757 1252
6f715d66
SC
1253static void
1254DEFUN(fixup_symbol_value,(coff_symbol_ptr, syment),
1255coff_symbol_type *coff_symbol_ptr AND
1256struct internal_syment *syment)
1257{
0f268757 1258
6f715d66
SC
1259 /* Normalize the symbol flags */
1260 if (coff_symbol_ptr->symbol.flags & BSF_FORT_COMM) {
1261 /* a common symbol is undefined with a value */
1262 syment->n_scnum = N_UNDEF;
1263 syment->n_value = coff_symbol_ptr->symbol.value;
1264 }
1265 else if (coff_symbol_ptr->symbol.flags & BSF_DEBUGGING) {
1266 syment->n_value = coff_symbol_ptr->symbol.value;
1267 }
1268 else if (coff_symbol_ptr->symbol.flags & BSF_UNDEFINED) {
1269 syment->n_scnum = N_UNDEF;
1270 syment->n_value = 0;
cbdc7909 1271 }
6f715d66
SC
1272 else if (coff_symbol_ptr->symbol.flags & BSF_ABSOLUTE) {
1273 syment->n_scnum = N_ABS;
1274 syment->n_value = coff_symbol_ptr->symbol.value;
cbdc7909 1275 }
6f715d66 1276 else {
f58809fd 1277 if (coff_symbol_ptr->symbol.section) {
cbdc7909 1278 syment->n_scnum =
f58809fd 1279 coff_symbol_ptr->symbol.section->output_section->index+1;
cbdc7909
JG
1280
1281 syment->n_value =
f58809fd 1282 coff_symbol_ptr->symbol.value +
6f715d66 1283 coff_symbol_ptr->symbol.section->output_offset +
f58809fd
SC
1284 coff_symbol_ptr->symbol.section->output_section->vma;
1285 }
1286 else {
1287 /* This can happen, but I don't know why yet (steve@cygnus.com) */
1288 syment->n_scnum = N_ABS;
cbdc7909 1289 syment->n_value = coff_symbol_ptr->symbol.value;
f58809fd 1290 }
6f715d66
SC
1291 }
1292}
0f268757 1293
6f715d66 1294/* run through all the symbols in the symbol table and work out what
cbdc7909 1295 their indexes into the symbol table will be when output
0f268757 1296
6f715d66
SC
1297 Coff requires that each C_FILE symbol points to the next one in the
1298 chain, and that the last one points to the first external symbol. We
1299 do that here too.
0f268757 1300
6f715d66
SC
1301*/
1302static void
1303DEFUN(coff_renumber_symbols,(bfd_ptr),
1304 bfd *bfd_ptr)
1305{
1306 unsigned int symbol_count = bfd_get_symcount(bfd_ptr);
1307 asymbol **symbol_ptr_ptr = bfd_ptr->outsymbols;
1308 unsigned int native_index = 0;
1309 struct internal_syment *last_file = (struct internal_syment *)NULL;
1310 unsigned int symbol_index;
cbdc7909 1311 for (symbol_index = 0; symbol_index < symbol_count; symbol_index++)
6f715d66
SC
1312 {
1313 coff_symbol_type *coff_symbol_ptr = coff_symbol_from(bfd_ptr, symbol_ptr_ptr[symbol_index]);
1314 if (coff_symbol_ptr && coff_symbol_ptr->native) {
1315 combined_entry_type *s = coff_symbol_ptr->native;
1316 int i;
0f268757 1317
cbdc7909 1318 if (s->u.syment.n_sclass == C_FILE)
6f715d66
SC
1319 {
1320 if (last_file != (struct internal_syment *)NULL) {
1321 last_file->n_value = native_index;
1322 }
1323 last_file = &(s->u.syment);
1324 }
1325 else {
0f268757 1326
6f715d66
SC
1327 /* Modify the symbol values according to their section and
1328 type */
0f268757 1329
6f715d66
SC
1330 fixup_symbol_value(coff_symbol_ptr, &(s->u.syment));
1331 }
1332 for (i = 0; i < s->u.syment.n_numaux + 1; i++) {
1333 s[i].offset = native_index ++;
1334 }
1335 }
1336 else {
1337 native_index++;
1338 }
1339 }
1340}
0f268757 1341
0f268757 1342
41f50af0 1343/*
6f715d66
SC
1344 Run thorough the symbol table again, and fix it so that all pointers to
1345 entries are changed to the entries' index in the output symbol table.
0f268757 1346
6f715d66 1347*/
cbdc7909 1348static void
0f268757
SC
1349DEFUN(coff_mangle_symbols,(bfd_ptr),
1350 bfd *bfd_ptr)
6f715d66
SC
1351{
1352 unsigned int symbol_count = bfd_get_symcount(bfd_ptr);
1353 asymbol **symbol_ptr_ptr = bfd_ptr->outsymbols;
6f715d66
SC
1354 unsigned int symbol_index;
1355
cbdc7909 1356 for (symbol_index = 0; symbol_index < symbol_count; symbol_index++)
6f715d66 1357 {
cbdc7909
JG
1358 coff_symbol_type *coff_symbol_ptr =
1359 coff_symbol_from(bfd_ptr, symbol_ptr_ptr[symbol_index]);
1360
1361 if (coff_symbol_ptr && coff_symbol_ptr->native) {
6f715d66
SC
1362 int i;
1363 combined_entry_type *s = coff_symbol_ptr->native;
1364
6f715d66
SC
1365 for (i = 0; i < s->u.syment.n_numaux ; i++) {
1366 combined_entry_type *a = s + i + 1;
1367 if (a->fix_tag) {
cbdc7909
JG
1368 a->u.auxent.x_sym.x_tagndx.l =
1369 a->u.auxent.x_sym.x_tagndx.p->offset;
6f715d66
SC
1370 }
1371 if (a->fix_end) {
1372 a->u.auxent.x_sym.x_fcnary.x_fcn.x_endndx.l =
1373 a->u.auxent.x_sym.x_fcnary.x_fcn.x_endndx.p->offset;
1374 }
1375
1376 }
1377 }
1378 }
1379}
1380
cbdc7909 1381static int string_size;
6f715d66 1382static void
fb3be09b
JG
1383DEFUN(coff_fix_symbol_name,(ignore_abfd, symbol, native),
1384 bfd *ignore_abfd AND
6f715d66
SC
1385 asymbol *symbol AND
1386 combined_entry_type *native)
1387{
1388 unsigned int name_length;
1389 union internal_auxent *auxent;
41f50af0 1390 char * name = ( char *)(symbol->name);
6f715d66
SC
1391
1392 if (name == (char *) NULL) {
fb3be09b
JG
1393 /* coff symbols always have names, so we'll make one up */
1394 symbol->name = "strange";
41f50af0 1395 name = (char *)symbol->name;
6f715d66
SC
1396 }
1397 name_length = strlen(name);
cbdc7909 1398
6f715d66
SC
1399 if (native->u.syment.n_sclass == C_FILE) {
1400 strncpy(native->u.syment._n._n_name, ".file", SYMNMLEN);
1401 auxent = &(native+1)->u.auxent;
cbdc7909 1402
6f715d66
SC
1403#ifdef COFF_LONG_FILENAMES
1404 if (name_length <= FILNMLEN) {
1405 strncpy(auxent->x_file.x_fname, name, FILNMLEN);
1406 }
1407 else {
1408 auxent->x_file.x_n.x_offset = string_size + 4;
1409 auxent->x_file.x_n.x_zeroes = 0;
1410 string_size += name_length + 1;
1411 }
1412#else
1413 strncpy(auxent->x_file.x_fname, name, FILNMLEN);
1414 if (name_length > FILNMLEN) {
1415 name[FILNMLEN] = '\0';
1416 }
1417#endif
1418 }
1419 else
1420 { /* NOT A C_FILE SYMBOL */
1421 if (name_length <= SYMNMLEN) {
1422 /* This name will fit into the symbol neatly */
1423 strncpy(native->u.syment._n._n_name, symbol->name, SYMNMLEN);
1424 }
1425 else {
1426 native->u.syment._n._n_n._n_offset = string_size + 4;
1427 native->u.syment._n._n_n._n_zeroes = 0;
1428 string_size += name_length + 1;
1429 }
1430 }
1431}
1432
1433
1434
cbdc7909 1435static unsigned int
6f715d66
SC
1436DEFUN(coff_write_symbol,(abfd, symbol, native, written),
1437bfd *abfd AND
1438asymbol *symbol AND
1439combined_entry_type *native AND
1440unsigned int written)
1441{
1442 unsigned int numaux = native->u.syment.n_numaux;
1443 int type = native->u.syment.n_type;
1444 int class = native->u.syment.n_sclass;
1445 SYMENT buf;
1446 unsigned int j;
1447
1448 coff_fix_symbol_name(abfd, symbol, native);
1449 coff_swap_sym_out(abfd, &native->u.syment, &buf);
1450 bfd_write((PTR)& buf, 1, SYMESZ, abfd);
cbdc7909 1451 for (j = 0; j != native->u.syment.n_numaux; j++)
6f715d66
SC
1452 {
1453 AUXENT buf1;
f58809fd 1454 bzero((PTR)&buf, AUXESZ);
6f715d66
SC
1455 coff_swap_aux_out(abfd,
1456 &( (native + j + 1)->u.auxent), type, class, &buf1);
1457 bfd_write((PTR) (&buf1), 1, AUXESZ, abfd);
1458 }
1459 /*
1460 Reuse somewhere in the symbol to keep the index
1461 */
1462 set_index(symbol, written);
1463 return written + 1 + numaux;
1464}
1465
1466
1467static unsigned int
1468DEFUN(coff_write_alien_symbol,(abfd, symbol, written),
1469 bfd *abfd AND
1470 asymbol *symbol AND
1471 unsigned int written)
1472{
1473 /*
1474 This symbol has been created by the loader, or come from a non
1475 coff format. It has no native element to inherit, make our
1476 own
1477 */
1478 combined_entry_type *native;
1479 combined_entry_type dummy;
1480 native = &dummy;
1481 native->u.syment.n_type = T_NULL;
1482#ifdef I960
1483 native->u.syment.n_flags = 0;
1484#endif
1485 if (symbol->flags & BSF_ABSOLUTE) {
1486 native->u.syment.n_scnum = N_ABS;
1487 native->u.syment.n_value = symbol->value;
1488 }
1489 else if (symbol->flags & (BSF_UNDEFINED | BSF_FORT_COMM)) {
1490 native->u.syment.n_scnum = N_UNDEF;
1491 native->u.syment.n_value = symbol->value;
1492 }
1493 else if (symbol->flags & BSF_DEBUGGING) {
1494 /*
1495 remove name so it doesn't take up any space
1496 */
1497 symbol->name = "";
1498 }
1499 else {
1500 native->u.syment.n_scnum = symbol->section->output_section->index +
1501 1;
1502 native->u.syment.n_value = symbol->value +
1503 symbol->section->output_section->vma +
1504 symbol->section->output_offset;
1505#ifdef I960
1506 /* Copy the any flags from the the file hdr into the symbol */
1507 {
1508 coff_symbol_type *c = coff_symbol_from(abfd, symbol);
1509 if (c != (coff_symbol_type *)NULL) {
1510 native->u.syment.n_flags = c->symbol.the_bfd->flags;
1511 }
1512 }
1513#endif
1514 }
cbdc7909 1515
6f715d66
SC
1516#ifdef HASPAD1
1517 native->u.syment.pad1[0] = 0;
1518 native->u.syment.pad1[0] = 0;
1519#endif
cbdc7909 1520
6f715d66
SC
1521 native->u.syment.n_type = 0;
1522 if (symbol->flags & BSF_LOCAL)
1523 native->u.syment.n_sclass = C_STAT;
cbdc7909 1524 else
6f715d66
SC
1525 native->u.syment.n_sclass = C_EXT;
1526 native->u.syment.n_numaux = 0;
1527
1528 return coff_write_symbol(abfd, symbol, native, written);
1529}
1530
cbdc7909 1531static unsigned int
6f715d66
SC
1532DEFUN(coff_write_native_symbol,(abfd, symbol, written),
1533bfd *abfd AND
1534coff_symbol_type *symbol AND
1535unsigned int written)
1536{
1537 /*
1538 Does this symbol have an ascociated line number - if so then
1539 make it remember this symbol index. Also tag the auxent of
1540 this symbol to point to the right place in the lineno table
1541 */
1542 combined_entry_type *native = symbol->native;
1543
1544 alent *lineno = symbol->lineno;
1545
1546 if (lineno) {
1547 unsigned int count = 0;
1548 lineno[count].u.offset = written;
1549 if (native->u.syment.n_numaux) {
1550 union internal_auxent *a = &((native+1)->u.auxent);
cbdc7909
JG
1551
1552 a->x_sym.x_fcnary.x_fcn.x_lnnoptr =
6f715d66
SC
1553 symbol->symbol.section->output_section->moving_line_filepos;
1554 }
1555 /*
1556 And count and relocate all other linenumbers
1557 */
1558 count++;
1559 while (lineno[count].line_number) {
1560 lineno[count].u.offset +=
1561 symbol->symbol.section->output_section->vma +
1562 symbol->symbol.section->output_offset;
1563 count++;
1564 }
1565 symbol->symbol.section->output_section->moving_line_filepos +=
1566 count * LINESZ;
6f715d66
SC
1567 }
1568 return coff_write_symbol(abfd, &( symbol->symbol), native,written);
1569}
1570
cbdc7909 1571static void
0f268757 1572DEFUN(coff_write_symbols,(abfd),
6f715d66 1573 bfd *abfd)
0f268757
SC
1574{
1575 unsigned int i;
1576 unsigned int limit = bfd_get_symcount(abfd);
1577 unsigned int written = 0;
6f715d66 1578
0f268757 1579 asymbol **p;
6f715d66
SC
1580
1581 string_size = 0;
cbdc7909
JG
1582
1583
0f268757
SC
1584 /* Seek to the right place */
1585 bfd_seek(abfd, obj_sym_filepos(abfd), SEEK_SET);
cbdc7909 1586
0f268757 1587 /* Output all the symbols we have */
cbdc7909 1588
0f268757 1589 written = 0;
cbdc7909 1590 for (p = abfd->outsymbols, i = 0; i < limit; i++, p++)
0f268757 1591 {
6f715d66
SC
1592 asymbol *symbol = *p;
1593 coff_symbol_type *c_symbol = coff_symbol_from(abfd, symbol);
6f715d66
SC
1594
1595 if (c_symbol == (coff_symbol_type *) NULL ||
1596 c_symbol->native == (combined_entry_type *)NULL)
1597 {
1598 written = coff_write_alien_symbol(abfd, symbol, written);
0f268757 1599 }
6f715d66
SC
1600 else
1601 {
1602 written = coff_write_native_symbol(abfd, c_symbol, written);
1603 }
1604
0f268757 1605 }
6f715d66 1606
0f268757 1607 bfd_get_symcount(abfd) = written;
6f715d66 1608
0f268757 1609 /* Now write out strings */
cbdc7909
JG
1610
1611 if (string_size != 0)
6f715d66
SC
1612 {
1613 unsigned int size = string_size + 4;
fb3be09b
JG
1614 bfd_byte buffer[4];
1615
7a8b18b6
SC
1616 bfd_h_put_32(abfd, size, buffer);
1617 bfd_write((PTR) buffer, 1, sizeof(buffer), abfd);
cbdc7909
JG
1618 for (p = abfd->outsymbols, i = 0;
1619 i < limit;
1620 i++, p++)
6f715d66
SC
1621 {
1622 asymbol *q = *p;
1623 size_t name_length = strlen(q->name);
1624 int maxlen;
1625 coff_symbol_type* c_symbol = coff_symbol_from(abfd, q);
7a8b18b6
SC
1626 maxlen = ((c_symbol != NULL && c_symbol->native != NULL) &&
1627 (c_symbol->native->u.syment.n_sclass == C_FILE)) ?
6f715d66 1628 FILNMLEN : SYMNMLEN;
cbdc7909 1629
6f715d66
SC
1630 if (name_length > maxlen) {
1631 bfd_write((PTR) (q->name), 1, name_length + 1, abfd);
1632 }
1633 }
1634 }
0f268757
SC
1635 else {
1636 /* We would normally not write anything here, but we'll write
1637 out 4 so that any stupid coff reader which tries to read
1638 the string table even when there isn't one won't croak.
1639 */
cbdc7909 1640
0f268757
SC
1641 uint32e_type size = 4;
1642 size = size;
1643 bfd_write((PTR)&size, 1, sizeof(size), abfd);
cbdc7909 1644
0f268757 1645 }
0f268757 1646}
7a8b18b6 1647
9fda1a39
SC
1648/*
1649SUBSUBSECTION
1650 Writing Relocations
1651
9fda1a39
SC
1652 To write relocations, all the back end does is step though the
1653 canonical relocation table, and create an
1654 @code{internal_reloc}. The symbol index to use is removed from
1655 the @code{offset} field in the symbol table supplied, the
1656 address comes directly from the sum of the section base
1657 address and the relocation offset and the type is dug directly
1658 from the howto field. Then the @code{internal_reloc} is
1659 swapped into the shape of an @code{external_reloc} and written
1660 out to disk.
1661
6f715d66 1662*/
0f268757 1663
cbdc7909 1664static void
6f715d66
SC
1665DEFUN(coff_write_relocs,(abfd),
1666 bfd *abfd)
1667{
1668 asection *s;
1669 for (s = abfd->sections; s != (asection *) NULL; s = s->next) {
1670 unsigned int i;
1671 struct external_reloc dst;
cbdc7909 1672
6f715d66
SC
1673 arelent **p = s->orelocation;
1674 bfd_seek(abfd, s->rel_filepos, SEEK_SET);
1675 for (i = 0; i < s->reloc_count; i++) {
1676 struct internal_reloc n;
1677 arelent *q = p[i];
1678 memset((PTR)&n, 0, sizeof(n));
1679 n.r_vaddr = q->address + s->vma;
1680 if (q->sym_ptr_ptr) {
1681 n.r_symndx = get_index((*(q->sym_ptr_ptr)));
1682 }
0f268757 1683#ifdef SELECT_RELOC
6f715d66
SC
1684 /* Work out reloc type from what is required */
1685 SELECT_RELOC(n.r_type, q->howto);
0f268757 1686#else
6f715d66 1687 n.r_type = q->howto->type;
0f268757 1688#endif
0d740984 1689 coff_swap_reloc_out(abfd, &n, &dst);
6f715d66 1690 bfd_write((PTR) &n, 1, RELSZ, abfd);
0f268757
SC
1691 }
1692 }
6f715d66 1693}
fb3be09b 1694#endif /* NO_COFF_SYMBOLS */
0f268757 1695
7a8b18b6
SC
1696#ifndef NO_COFF_LINENOS
1697
cbdc7909 1698static void
0f268757
SC
1699DEFUN(coff_write_linenumbers,(abfd),
1700 bfd *abfd)
6f715d66
SC
1701{
1702 asection *s;
1703 for (s = abfd->sections; s != (asection *) NULL; s = s->next) {
1704 if (s->lineno_count) {
1705 asymbol **q = abfd->outsymbols;
1706 bfd_seek(abfd, s->line_filepos, SEEK_SET);
1707 /* Find all the linenumbers in this section */
1708 while (*q) {
1709 asymbol *p = *q;
1710 alent *l = BFD_SEND(p->the_bfd, _get_lineno, (p->the_bfd, p));
1711 if (l) {
1712 /* Found a linenumber entry, output */
1713 struct internal_lineno out;
1714 LINENO buff;
1715 memset( (PTR)&out, 0, sizeof(out));
1716 out.l_lnno = 0;
1717 out.l_addr.l_symndx = l->u.offset;
1718 coff_swap_lineno_out(abfd, &out, &buff);
1719 bfd_write((PTR) &buff, 1, LINESZ, abfd);
1720 l++;
1721 while (l->line_number) {
1722 out.l_lnno = l->line_number;
0f268757 1723 out.l_addr.l_symndx = l->u.offset;
2700c3c7 1724 coff_swap_lineno_out(abfd, &out, &buff);
0f268757
SC
1725 bfd_write((PTR) &buff, 1, LINESZ, abfd);
1726 l++;
0f268757 1727 }
0f268757 1728 }
6f715d66 1729 q++;
0f268757
SC
1730 }
1731 }
1732 }
6f715d66 1733}
0f268757 1734
7a8b18b6
SC
1735static alent *
1736DEFUN(coff_get_lineno,(ignore_abfd, symbol),
1737 bfd *ignore_abfd AND
1738 asymbol *symbol)
1739{
1740 return coffsymbol(symbol)->lineno;
1741}
1742
1743#endif /* NO_COFF_LINENOS */
0f268757
SC
1744
1745static asymbol *
1746coff_make_empty_symbol(abfd)
1747bfd *abfd;
6f715d66
SC
1748{
1749 coff_symbol_type *new = (coff_symbol_type *) bfd_alloc(abfd, sizeof(coff_symbol_type));
1750 if (new == NULL) {
1751 bfd_error = no_memory;
1752 return (NULL);
1753 } /* on error */
1754 new->native = 0;
1755 new->lineno = (alent *) NULL;
1756 new->symbol.the_bfd = abfd;
1757 return &new->symbol;
1758}
0f268757 1759
7a8b18b6
SC
1760#ifndef NO_COFF_SYMBOLS
1761
cbdc7909 1762static void
ee32cba6 1763DEFUN(coff_print_symbol,(ignore_abfd, filep, symbol, how),
6f715d66 1764 bfd *ignore_abfd AND
41f50af0 1765 PTR filep AND
6f715d66 1766 asymbol *symbol AND
0d740984 1767 bfd_print_symbol_type how)
6f715d66 1768{
41f50af0 1769 FILE *file = (FILE *)filep;
6f715d66 1770 switch (how) {
3b4f1a5d
SC
1771 case bfd_print_symbol_name:
1772 fprintf(file, "%s", symbol->name);
1773 break;
1774 case bfd_print_symbol_more:
1775 fprintf(file, "coff %lx %lx", (unsigned long) coffsymbol(symbol)->native,
1776 (unsigned long) coffsymbol(symbol)->lineno);
1777 break;
1778 case bfd_print_symbol_nm:
1779
1780 {
1781 CONST char *section_name = symbol->section == (asection *) NULL ?
1782 "*abs" : symbol->section->name;
1783 bfd_print_symbol_vandf((PTR) file, symbol);
1784
1785
1786 fprintf(file, " %-5s %s %s %s",
1787 section_name,
1788 coffsymbol(symbol)->native ? "n" : "g",
1789 coffsymbol(symbol)->lineno ? "l" : " ",
1790 symbol->name);
1791 }
1792
1793
1794 break;
1795 case bfd_print_symbol_all:
1796 /* Print out the symbols in a reasonable way */
1797 {
1798 CONST char *section_name = symbol->section == (asection *) NULL ?
1799 "*abs" : symbol->section->name;
1800
1801
1802 if (coffsymbol(symbol)->native)
6f715d66 1803 {
3b4f1a5d
SC
1804 unsigned int aux;
1805 combined_entry_type *combined = coffsymbol(symbol)->native;
1806 combined_entry_type *root = obj_raw_syments(ignore_abfd);
1807
1808fprintf(file,"[%3d]",
1809 combined - root);
1810
cbdc7909 1811
3b4f1a5d
SC
1812 fprintf(file, "(sc %2d)(fl%4x)(ty%3x)(sc%3d) nx(%d) %08x %s",
1813 combined->u.syment.n_scnum,
1814 combined->u.syment.n_flags,
1815 combined->u.syment.n_type,
1816 combined->u.syment.n_sclass,
1817 combined->u.syment.n_numaux,
1818 combined->u.syment.n_value,
1819 symbol->name
1820 );
1821 for (aux = 0; aux < combined->u.syment.n_numaux; aux++)
1822 {
1823 fprintf(file,"\n");
1824 switch (combined->u.syment.n_sclass) {
1825 case C_FILE:
1826 fprintf(file, "File ");
1827 break;
1828 default:
616ebcfd 1829 fprintf(file, "AUX lnno %x size %x",
3b4f1a5d
SC
1830 combined[aux+1].u.auxent.x_sym.x_misc.x_lnsz.x_lnno,
1831 combined[aux+1].u.auxent.x_sym.x_misc.x_lnsz.x_size);
1832 break;
1833
1834 }
cbdc7909 1835
3b4f1a5d
SC
1836 }
1837
1838
1839
1840
1841 }
1842
1843 else {
1844 bfd_print_symbol_vandf((PTR) file, symbol);
1845 fprintf(file, " %-5s %s %s %s",
1846 section_name,
1847 coffsymbol(symbol)->native ? "n" : "g",
1848 coffsymbol(symbol)->lineno ? "l" : " ",
1849 symbol->name);
1850 }
1851
1852 }
1853
1854 }
6f715d66 1855}
0f268757 1856
7a8b18b6
SC
1857#endif /* NO_COFF_SYMBOLS */
1858
1859/* Set flags and magic number of a coff file from architecture and machine
1860 type. Result is true if we can represent the arch&type, false if not. */
0f268757 1861
0f268757 1862static boolean
6f715d66
SC
1863DEFUN(coff_set_flags,(abfd, magicp, flagsp),
1864 bfd *abfd AND
1865 unsigned *magicp AND
1866 unsigned short *flagsp)
1867{
0d740984 1868 switch (bfd_get_arch(abfd)) {
cbdc7909 1869
0f268757 1870#ifdef I960ROMAGIC
cbdc7909 1871
3b4f1a5d 1872 case bfd_arch_i960:
cbdc7909 1873
6f715d66
SC
1874 {
1875 unsigned flags;
1876 *magicp = I960ROMAGIC;
1877 /*
1878 ((bfd_get_file_flags(abfd) & WP_TEXT) ? I960ROMAGIC :
1879 I960RWMAGIC); FIXME???
1880 */
0d740984 1881 switch (bfd_get_mach(abfd)) {
6f715d66
SC
1882 case bfd_mach_i960_core:
1883 flags = F_I960CORE;
1884 break;
1885 case bfd_mach_i960_kb_sb:
1886 flags = F_I960KB;
1887 break;
1888 case bfd_mach_i960_mc:
1889 flags = F_I960MC;
1890 break;
1891 case bfd_mach_i960_xa:
1892 flags = F_I960XA;
1893 break;
1894 case bfd_mach_i960_ca:
1895 flags = F_I960CA;
1896 break;
1897 case bfd_mach_i960_ka_sa:
1898 flags = F_I960KA;
1899 break;
1900 default:
1901 return false;
0f268757 1902 }
6f715d66
SC
1903 *flagsp = flags;
1904 return true;
1905 }
1906 break;
0f268757
SC
1907#endif
1908#ifdef MIPS
6f715d66
SC
1909 case bfd_arch_mips:
1910 *magicp = MIPS_MAGIC_2;
1911 return true;
1912 break;
0f268757 1913#endif
20fdc627 1914#ifdef I386MAGIC
6f715d66
SC
1915 case bfd_arch_i386:
1916 *magicp = I386MAGIC;
1917 return true;
20fdc627 1918#endif
0f268757 1919#ifdef MC68MAGIC
6f715d66
SC
1920 case bfd_arch_m68k:
1921 *magicp = MC68MAGIC;
1922 return true;
0f268757 1923#endif
cbdc7909 1924
0f268757 1925#ifdef MC88MAGIC
3b4f1a5d
SC
1926 case bfd_arch_m88k:
1927 *magicp = MC88OMAGIC;
1928 return true;
1929 break;
1930#endif
1931#ifdef H8300MAGIC
1932 case bfd_arch_h8300:
1933 *magicp = H8300MAGIC;
1934 return true;
1935 break;
0f268757 1936#endif
41f50af0 1937#ifdef A29K_MAGIC_BIG
3b4f1a5d
SC
1938 case bfd_arch_a29k:
1939 if (abfd->xvec->byteorder_big_p)
1940 *magicp = A29K_MAGIC_BIG;
1941 else
1942 *magicp = A29K_MAGIC_LITTLE;
1943 return true;
1944 break;
41f50af0 1945#endif
cbdc7909
JG
1946
1947#ifdef U802TOCMAGIC
1948 case bfd_arch_rs6000:
1949 *magicp = U802TOCMAGIC;
1950 break;
1951#endif
1952
6f715d66 1953 default: /* Unknown architecture */
8acc9e05 1954 /* return false; -- fall through to "return false" below, to avoid
cbdc7909 1955 "statement never reached" errors on the one below. */
8acc9e05 1956 break;
0f268757 1957 }
cbdc7909 1958
6f715d66
SC
1959 return false;
1960}
0f268757
SC
1961
1962
1963static boolean
6f715d66
SC
1964DEFUN(coff_set_arch_mach,(abfd, arch, machine),
1965 bfd *abfd AND
1966 enum bfd_architecture arch AND
1967 unsigned long machine)
1968{
0d740984
SC
1969 unsigned dummy1;
1970 unsigned short dummy2;
1971 bfd_default_set_arch_mach(abfd, arch, machine);
1972
1973 if (arch != bfd_arch_unknown &&
1974 coff_set_flags(abfd, &dummy1, &dummy2) != true)
1975 return false; /* We can't represent this type */
1976 return true; /* We're easy ... */
1977}
0f268757
SC
1978
1979
1980/* Calculate the file position for each section. */
1981
cbdc7909 1982static void
6f715d66
SC
1983DEFUN(coff_compute_section_file_positions,(abfd),
1984 bfd *abfd)
1985{
85e0c721
SC
1986 asection *current;
1987 asection *previous = (asection *)NULL;
1988 file_ptr sofar = FILHSZ;
1989 file_ptr old_sofar;
1990 if (bfd_get_start_address(abfd))
1991 {
1992 /* A start address may have been added to the original file. In this
1993 case it will need an optional header to record it. */
1994 abfd->flags |= EXEC_P;
1995 }
1996
1997 if (abfd->flags & EXEC_P)
1998 sofar += AOUTSZ;
cbdc7909 1999
85e0c721
SC
2000 sofar += abfd->section_count * SCNHSZ;
2001 for (current = abfd->sections;
2002 current != (asection *)NULL;
2003 current = current->next) {
cbdc7909 2004
85e0c721
SC
2005 /* Only deal with sections which have contents */
2006 if (!(current->flags & SEC_HAS_CONTENTS))
2007 continue;
cbdc7909 2008
85e0c721
SC
2009 /* Align the sections in the file to the same boundary on
2010 which they are aligned in virtual memory. I960 doesn't
2011 do this (FIXME) so we can stay in sync with Intel. 960
2012 doesn't yet page from files... */
0f268757 2013#ifndef I960
85e0c721
SC
2014 {
2015 /* make sure this section is aligned on the right boundary - by
2016 padding the previous section up if necessary */
2017
2018 old_sofar= sofar;
8c4a1ace 2019 sofar = BFD_ALIGN(sofar, 1 << current->alignment_power);
85e0c721
SC
2020 if (previous != (asection *)NULL) {
2021 previous->size += sofar - old_sofar;
2022 }
2023 }
2024
0f268757 2025#endif
85e0c721
SC
2026 /* FIXME, in demand paged files, the low order bits of the file
2027 offset must match the low order bits of the virtual address.
2028 "Low order" is apparently implementation defined. Add code
2029 here to round sofar up to match the virtual address. */
cbdc7909 2030
85e0c721
SC
2031 current->filepos = sofar;
2032
2033 /* make sure that this section is of the right size too */
2034 old_sofar = sofar += current->size;
8c4a1ace 2035 sofar = BFD_ALIGN(sofar, 1 << current->alignment_power);
85e0c721
SC
2036 current->size += sofar - old_sofar ;
2037
2038 previous = current;
2039 }
2040 obj_relocbase(abfd) = sofar;
6f715d66 2041}
0f268757
SC
2042
2043
2044
2045
2046/* SUPPRESS 558 */
2047/* SUPPRESS 529 */
2048static boolean
2049DEFUN(coff_write_object_contents,(abfd),
6f715d66
SC
2050 bfd *abfd)
2051 {
2052 asection *current;
2053 boolean hasrelocs = false;
2054 boolean haslinno = false;
2055 file_ptr reloc_base;
2056 file_ptr lineno_base;
2057 file_ptr sym_base;
2058 file_ptr scn_base;
2059 file_ptr data_base;
2060 unsigned long reloc_size = 0;
2061 unsigned long lnno_size = 0;
2062 asection *text_sec = NULL;
2063 asection *data_sec = NULL;
2064 asection *bss_sec = NULL;
cbdc7909 2065
6f715d66
SC
2066 struct internal_filehdr internal_f;
2067 struct internal_aouthdr internal_a;
cbdc7909
JG
2068
2069
6f715d66 2070 bfd_error = system_call_error;
cbdc7909
JG
2071
2072
6f715d66
SC
2073 if(abfd->output_has_begun == false) {
2074 coff_compute_section_file_positions(abfd);
2075 }
cbdc7909 2076
6f715d66
SC
2077 if (abfd->sections != (asection *)NULL) {
2078 scn_base = abfd->sections->filepos;
0f268757
SC
2079 }
2080 else {
2081 scn_base = 0;
2082 }
2083 if (bfd_seek(abfd, scn_base, SEEK_SET) != 0)
2084 return false;
2085 reloc_base = obj_relocbase(abfd);
cbdc7909 2086
0f268757
SC
2087 /* Make a pass through the symbol table to count line number entries and
2088 put them into the correct asections */
cbdc7909 2089
7a8b18b6 2090#ifndef NO_COFF_LINENOS
0f268757 2091 coff_count_linenumbers(abfd);
7a8b18b6 2092#endif
0f268757 2093 data_base = scn_base;
cbdc7909 2094
0f268757 2095 /* Work out the size of the reloc and linno areas */
cbdc7909 2096
0f268757
SC
2097 for (current = abfd->sections; current != NULL; current = current->next) {
2098 reloc_size += current->reloc_count * RELSZ;
7a8b18b6 2099#ifndef NO_COFF_LINENOS
0f268757 2100 lnno_size += current->lineno_count * LINESZ;
7a8b18b6 2101#endif
0f268757
SC
2102 data_base += SCNHSZ;
2103 }
cbdc7909 2104
0f268757
SC
2105 lineno_base = reloc_base + reloc_size;
2106 sym_base = lineno_base + lnno_size;
cbdc7909 2107
0f268757
SC
2108 /* Indicate in each section->line_filepos its actual file address */
2109 for (current = abfd->sections; current != NULL; current = current->next) {
2110 if (current->lineno_count) {
2111 current->line_filepos = lineno_base;
2112 current->moving_line_filepos = lineno_base;
7a8b18b6 2113#ifndef NO_COFF_LINENOS
0f268757 2114 lineno_base += current->lineno_count * LINESZ;
7a8b18b6 2115#endif
0f268757
SC
2116 }
2117 else {
2118 current->line_filepos = 0;
2119 }
2120 if (current->reloc_count) {
2121 current->rel_filepos = reloc_base;
2122 reloc_base += current->reloc_count * sizeof(struct internal_reloc);
2123 }
2124 else {
2125 current->rel_filepos = 0;
2126 }
2127 }
cbdc7909 2128
0f268757 2129 /* Write section headers to the file. */
cbdc7909 2130
0f268757
SC
2131 bfd_seek(abfd,
2132 (file_ptr) ((abfd->flags & EXEC_P) ?
2133 (FILHSZ + AOUTSZ) : FILHSZ),
2134 SEEK_SET);
cbdc7909 2135
0f268757
SC
2136 {
2137#if 0
2138 unsigned int pad = abfd->flags & D_PAGED ? data_base : 0;
2139#endif
2140 unsigned int pad = 0;
cbdc7909 2141
0f268757
SC
2142 for (current = abfd->sections; current != NULL; current = current->next) {
2143 struct internal_scnhdr section;
2144 strncpy(&(section.s_name[0]), current->name, 8);
2145 section.s_vaddr = current->vma + pad;
2146 section.s_paddr = current->vma + pad;
2147 section.s_size = current->size - pad;
2148 /*
2149 If this section has no size or is unloadable then the scnptr
2150 will be 0 too
2151 */
2152 if (current->size - pad == 0 ||
2153 (current->flags & SEC_LOAD) == 0) {
2154 section.s_scnptr = 0;
0f268757
SC
2155 }
2156 else {
2157 section.s_scnptr = current->filepos;
2158 }
2159 section.s_relptr = current->rel_filepos;
2160 section.s_lnnoptr = current->line_filepos;
2161 section.s_nreloc = current->reloc_count;
2162 section.s_nlnno = current->lineno_count;
2163 if (current->reloc_count != 0)
2164 hasrelocs = true;
2165 if (current->lineno_count != 0)
2166 haslinno = true;
cbdc7909 2167
41f50af0
SC
2168 section.s_flags = sec_to_styp_flags(current->name,current->flags);
2169
0f268757
SC
2170 if (!strcmp(current->name, _TEXT)) {
2171 text_sec = current;
41f50af0 2172 } else if (!strcmp(current->name, _DATA)) {
0f268757 2173 data_sec = current;
41f50af0 2174 } else if (!strcmp(current->name, _BSS)) {
0f268757 2175 bss_sec = current;
cbdc7909
JG
2176 }
2177
0f268757
SC
2178#ifdef I960
2179 section.s_align = (current->alignment_power
2180 ? 1 << current->alignment_power
2181 : 0);
2182
2183#endif
2184 {
2185 SCNHDR buff;
2186
0d740984 2187 coff_swap_scnhdr_out(abfd, &section, &buff);
0f268757
SC
2188 bfd_write((PTR) (&buff), 1, SCNHSZ, abfd);
2189
2190 }
2191 pad = 0;
2192 }
2193 }
2194
2195 /* OK, now set up the filehdr... */
2196 internal_f.f_nscns = abfd->section_count;
2197 /*
2198 We will NOT put a fucking timestamp in the header here. Every time you
2199 put it back, I will come in and take it out again. I'm sorry. This
2200 field does not belong here. We fill it with a 0 so it compares the
2201 same but is not a reasonable time. -- gnu@cygnus.com
2202 */
2203 /*
2204 Well, I like it, so I'm conditionally compiling it in.
2205 steve@cygnus.com
2206 */
2207#ifdef COFF_TIMESTAMP
2208 internal_f.f_timdat = time(0);
2209#else
2210 internal_f.f_timdat = 0;
2211#endif
2212
2213 if (bfd_get_symcount(abfd) != 0)
2214 internal_f.f_symptr = sym_base;
2215 else
2216 internal_f.f_symptr = 0;
2217
2218 internal_f.f_flags = 0;
2219
2220 if (abfd->flags & EXEC_P)
2221 internal_f.f_opthdr = AOUTSZ;
2222 else
2223 internal_f.f_opthdr = 0;
2224
2225 if (!hasrelocs)
2226 internal_f.f_flags |= F_RELFLG;
2227 if (!haslinno)
2228 internal_f.f_flags |= F_LNNO;
2229 if (0 == bfd_get_symcount(abfd))
2230 internal_f.f_flags |= F_LSYMS;
2231 if (abfd->flags & EXEC_P)
2232 internal_f.f_flags |= F_EXEC;
2233#if M88
2234 internal_f.f_flags |= F_AR32W;
2235#else
2236 if (!abfd->xvec->byteorder_big_p)
2237 internal_f.f_flags |= F_AR32WR;
2238#endif
2239 /*
2240 FIXME, should do something about the other byte orders and
2241 architectures.
2242 */
2243
2244 /* Set up architecture-dependent stuff */
2245
41f50af0
SC
2246 { unsigned int magic = 0;
2247 unsigned short flags = 0;
2248 coff_set_flags(abfd, &magic, &flags);
0f268757 2249 internal_f.f_magic = magic;
2f8d9c1c 2250 internal_f.f_flags |= flags;
0f268757
SC
2251 /* ...and the "opt"hdr... */
2252
cbdc7909 2253#ifdef A29K
41f50af0
SC
2254# ifdef ULTRA3 /* NYU's machine */
2255 /* FIXME: This is a bogus check. I really want to see if there
2256 * is a .shbss or a .shdata section, if so then set the magic
2257 * number to indicate a shared data executable.
cbdc7909 2258 */
41f50af0
SC
2259 if (internal_f.f_nscns >= 7)
2260 internal_a.magic = SHMAGIC; /* Shared magic */
2261 else
2262# endif /* ULTRA3 */
2263 internal_a.magic = NMAGIC; /* Assume separate i/d */
2264#define __A_MAGIC_SET__
2265#endif /* A29K */
0f268757 2266#ifdef I960
cbdc7909 2267 internal_a.magic = (magic == I960ROMAGIC ? NMAGIC : OMAGIC);
41f50af0
SC
2268#define __A_MAGIC_SET__
2269#endif /* I960 */
0f268757 2270#if M88
41f50af0 2271#define __A_MAGIC_SET__
0f268757 2272 internal_a.magic = PAGEMAGICBCS;
41f50af0
SC
2273#endif /* M88 */
2274
2275#if M68 || I386 || MIPS
2276#define __A_MAGIC_SET__
cbdc7909 2277 /* Never was anything here for the 68k */
41f50af0
SC
2278#endif /* M88 */
2279
cbdc7909
JG
2280#if RS6000COFF_C
2281#define __A_MAGIC_SET__
2282 internal_a.magic = (abfd->flags & D_PAGED)? RS6K_AOUTHDR_ZMAGIC:
2283 (abfd->flags & WP_TEXT)? RS6K_AOUTHDR_NMAGIC:
2284 RS6K_AOUTHDR_OMAGIC;
2285#endif
2286
41f50af0
SC
2287#ifndef __A_MAGIC_SET__
2288# include "Your aouthdr magic number is not being set!"
2289#else
2290# undef __A_MAGIC_SET__
0f268757
SC
2291#endif
2292 }
2293 /* Now should write relocs, strings, syms */
2294 obj_sym_filepos(abfd) = sym_base;
2295
7a8b18b6 2296#ifndef NO_COFF_SYMBOLS
0f268757 2297 if (bfd_get_symcount(abfd) != 0) {
6f715d66 2298 coff_renumber_symbols(abfd);
0f268757
SC
2299 coff_mangle_symbols(abfd);
2300 coff_write_symbols(abfd);
2301 coff_write_linenumbers(abfd);
2302 coff_write_relocs(abfd);
2303 }
7a8b18b6 2304#endif /* NO_COFF_SYMBOLS */
0f268757
SC
2305 if (text_sec) {
2306 internal_a.tsize = text_sec->size;
2307 internal_a.text_start =text_sec->size ? text_sec->vma : 0;
2308 }
2309 if (data_sec) {
2310 internal_a.dsize = data_sec->size;
2311 internal_a.data_start = data_sec->size ? data_sec->vma : 0;
2312 }
2313 if (bss_sec) {
2314 internal_a.bsize = bss_sec->size;
2315 }
2316
2317 internal_a.entry = bfd_get_start_address(abfd);
2318 internal_f.f_nsyms = bfd_get_symcount(abfd);
2319
2320 /* now write them */
2321 if (bfd_seek(abfd, 0L, SEEK_SET) != 0)
2322 return false;
2323 {
2324 FILHDR buff;
0d740984 2325 coff_swap_filehdr_out(abfd, &internal_f, &buff);
0f268757
SC
2326 bfd_write((PTR) &buff, 1, FILHSZ, abfd);
2327 }
2328 if (abfd->flags & EXEC_P) {
2329 AOUTHDR buff;
0d740984 2330 coff_swap_aouthdr_out(abfd, &internal_a, &buff);
0f268757
SC
2331 bfd_write((PTR) &buff, 1, AOUTSZ, abfd);
2332 }
2333 return true;
6f715d66
SC
2334}
2335
7a8b18b6
SC
2336#ifndef NO_COFF_SYMBOLS
2337
6f715d66
SC
2338/*
2339this function transforms the offsets into the symbol table into
2340pointers to syments.
2341*/
2342
2343
2344static void
fb3be09b
JG
2345DEFUN(coff_pointerize_aux,(ignore_abfd, table_base, type, class, auxent),
2346bfd *ignore_abfd AND
6f715d66
SC
2347combined_entry_type *table_base AND
2348int type AND
2349int class AND
2350combined_entry_type *auxent)
2351{
2352 /* Don't bother if this is a file or a section */
2353 if (class == C_STAT && type == T_NULL) return;
2354 if (class == C_FILE) return;
2355
2356 /* Otherwise patch up */
2357 if (ISFCN(type) || ISTAG(class) || class == C_BLOCK) {
2358 auxent->u.auxent.x_sym.x_fcnary.x_fcn.x_endndx.p = table_base +
2359 auxent->u.auxent.x_sym.x_fcnary.x_fcn.x_endndx.l;
2360 auxent->fix_end = 1;
2361 }
7a8b18b6
SC
2362 if (auxent->u.auxent.x_sym.x_tagndx.l != 0) {
2363 auxent->u.auxent.x_sym.x_tagndx.p = table_base + auxent->u.auxent.x_sym.x_tagndx.l;
2364 auxent->fix_tag = 1;
2365 }
6f715d66
SC
2366}
2367
7a8b18b6 2368#endif /* NO_COFF_SYMBOLS */
0f268757
SC
2369
2370static boolean
6f715d66
SC
2371DEFUN(coff_set_section_contents,(abfd, section, location, offset, count),
2372 bfd *abfd AND
2373 sec_ptr section AND
2374 PTR location AND
2375 file_ptr offset AND
41f50af0 2376 bfd_size_type count)
0f268757
SC
2377{
2378 if (abfd->output_has_begun == false) /* set by bfd.c handler */
2379 coff_compute_section_file_positions(abfd);
2380
2381 bfd_seek(abfd, (file_ptr) (section->filepos + offset), SEEK_SET);
2382
2383 if (count != 0) {
2384 return (bfd_write(location, 1, count, abfd) == count) ? true : false;
2385 }
2386 return true;
2387}
2388#if 0
2389static boolean
2390coff_close_and_cleanup(abfd)
2391 bfd *abfd;
2392{
2393 if (!bfd_read_p(abfd))
2394 switch (abfd->format) {
2395 case bfd_archive:
2396 if (!_bfd_write_archive_contents(abfd))
2397 return false;
2398 break;
2399 case bfd_object:
2400 if (!coff_write_object_contents(abfd))
2401 return false;
2402 break;
2403 default:
2404 bfd_error = invalid_operation;
2405 return false;
2406 }
2407
2408 /* We depend on bfd_close to free all the memory on the obstack. */
2409 /* FIXME if bfd_release is not using obstacks! */
2410 return true;
2411}
2412
2413#endif
cbdc7909 2414static PTR
0f268757
SC
2415buy_and_read(abfd, where, seek_direction, size)
2416 bfd *abfd;
2417 file_ptr where;
2418 int seek_direction;
2419 size_t size;
2420{
2421 PTR area = (PTR) bfd_alloc(abfd, size);
2422 if (!area) {
2423 bfd_error = no_memory;
2424 return (NULL);
2425 }
2426 bfd_seek(abfd, where, seek_direction);
2427 if (bfd_read(area, 1, size, abfd) != size) {
2428 bfd_error = system_call_error;
2429 return (NULL);
2430 } /* on error */
2431 return (area);
2432} /* buy_and_read() */
2433
6f715d66 2434
7a8b18b6 2435#ifndef NO_COFF_SYMBOLS
6f715d66
SC
2436
2437static char *
2438DEFUN(build_string_table,(abfd),
2439bfd *abfd)
0f268757 2440{
6f715d66
SC
2441 char string_table_size_buffer[4];
2442 unsigned int string_table_size;
2443 char *string_table;
cbdc7909
JG
2444
2445 /* At this point we should be "seek"'d to the end of the
2446 symbols === the symbol table size. */
6f715d66
SC
2447 if (bfd_read((char *) string_table_size_buffer,
2448 sizeof(string_table_size_buffer),
2449 1, abfd) != sizeof(string_table_size)) {
2450 bfd_error = system_call_error;
2451 return (NULL);
2452 } /* on error */
cbdc7909 2453
41f50af0 2454 string_table_size = bfd_h_get_32(abfd, (bfd_byte *) string_table_size_buffer);
cbdc7909 2455
6f715d66
SC
2456 if ((string_table = (PTR) bfd_alloc(abfd, string_table_size -= 4)) == NULL) {
2457 bfd_error = no_memory;
2458 return (NULL);
2459 } /* on mallocation error */
2460 if (bfd_read(string_table, string_table_size, 1, abfd) != string_table_size) {
2461 bfd_error = system_call_error;
2462 return (NULL);
cbdc7909 2463 }
6f715d66
SC
2464 return string_table;
2465}
0f268757 2466
cbdc7909
JG
2467/* Allocate space for the ".debug" section, and read it.
2468 We did not read the debug section until now, because
2469 we didn't want to go to the trouble until someone needed it. */
2470
2471static char *
2472DEFUN(build_debug_section,(abfd),
2473 bfd *abfd)
2474{
2475 char *debug_section;
2476 long position;
2477
2478 asection *sect = bfd_get_section_by_name (abfd, ".debug");
2479
2480 if (!sect) {
2481 bfd_error = no_debug_section;
2482 return NULL;
2483 }
2484
2485 debug_section = (PTR) bfd_alloc (abfd, bfd_section_size (abfd, sect));
2486 if (debug_section == NULL) {
2487 bfd_error = no_memory;
2488 return NULL;
2489 }
2490
2491 /* Seek to the beginning of the `.debug' section and read it.
2492 Save the current position first; it is needed by our caller.
2493 Then read debug section and reset the file pointer. */
2494
2495 position = bfd_tell (abfd);
2496 bfd_seek (abfd, sect->filepos, SEEK_SET);
2497 if (bfd_read (debug_section, bfd_section_size (abfd, sect), 1, abfd)
2498 != bfd_section_size (abfd, sect)) {
2499 bfd_error = system_call_error;
2500 return NULL;
2501 }
2502 bfd_seek (abfd, position, SEEK_SET);
2503 return debug_section;
2504}
2505
2506
fb3be09b
JG
2507/* Return a pointer to a malloc'd copy of 'name'. 'name' may not be
2508 \0-terminated, but will not exceed 'maxlen' characters. The copy *will*
2509 be \0-terminated. */
2510static char *
2511DEFUN(copy_name,(abfd, name, maxlen),
2512 bfd *abfd AND
2513 char *name AND
2514 int maxlen)
2515{
2516 int len;
2517 char *newname;
cbdc7909 2518
fb3be09b
JG
2519 for (len = 0; len < maxlen; ++len) {
2520 if (name[len] == '\0') {
2521 break;
2522 }
2523 }
cbdc7909 2524
fb3be09b
JG
2525 if ((newname = (PTR) bfd_alloc(abfd, len+1)) == NULL) {
2526 bfd_error = no_memory;
2527 return (NULL);
2528 }
2529 strncpy(newname, name, len);
2530 newname[len] = '\0';
2531 return newname;
2532}
2533
2534
cbdc7909
JG
2535/* Read a symbol table into freshly bfd_allocated memory, swap it, and
2536 knit the symbol names into a normalized form. By normalized here I
2537 mean that all symbols have an n_offset pointer that points to a null-
2538 terminated string. */
2539
2540#ifndef SYMNAME_IN_DEBUG
2541#define SYMNAME_IN_DEBUG(x) 0
2542#endif
0f268757 2543
6f715d66 2544static combined_entry_type *
0f268757
SC
2545DEFUN(get_normalized_symtab,(abfd),
2546bfd *abfd)
2547{
6f715d66
SC
2548 combined_entry_type *internal;
2549 combined_entry_type *internal_ptr;
2550 combined_entry_type *internal_end;
0f268757
SC
2551 SYMENT *raw;
2552 SYMENT *raw_src;
2553 SYMENT *raw_end;
2554 char *string_table = NULL;
cbdc7909 2555 char *debug_section = NULL;
0f268757 2556 unsigned long size;
6f715d66 2557
0f268757 2558 unsigned int raw_size;
6f715d66 2559 if (obj_raw_syments(abfd) != (combined_entry_type *)NULL) {
0f268757
SC
2560 return obj_raw_syments(abfd);
2561 }
6f715d66 2562 if ((size = bfd_get_symcount(abfd) * sizeof(combined_entry_type)) == 0) {
0f268757
SC
2563 bfd_error = no_symbols;
2564 return (NULL);
2565 }
2566
6f715d66 2567 internal = (combined_entry_type *)bfd_alloc(abfd, size);
0f268757
SC
2568 internal_end = internal + bfd_get_symcount(abfd);
2569
2570 raw_size = bfd_get_symcount(abfd) * SYMESZ;
2571 raw = (SYMENT *)bfd_alloc(abfd,raw_size);
2572
2573 if (bfd_seek(abfd, obj_sym_filepos(abfd), SEEK_SET) == -1
2574 || bfd_read((PTR)raw, raw_size, 1, abfd) != raw_size) {
2575 bfd_error = system_call_error;
2576 return (NULL);
2577 }
2578 /* mark the end of the symbols */
2579 raw_end = raw + bfd_get_symcount(abfd);
2580 /*
2581 FIXME SOMEDAY. A string table size of zero is very weird, but
2582 probably possible. If one shows up, it will probably kill us.
2583 */
2584
2585 /* Swap all the raw entries */
cbdc7909
JG
2586 for (raw_src = raw, internal_ptr = internal;
2587 raw_src < raw_end;
2588 raw_src++, internal_ptr++) {
2589
0f268757 2590 unsigned int i;
cbdc7909 2591 coff_swap_sym_in(abfd, (char *)raw_src, (char *)&internal_ptr->u.syment);
6f715d66
SC
2592 internal_ptr->fix_tag = 0;
2593 internal_ptr->fix_end = 0;
2594
cbdc7909
JG
2595 for (i = internal_ptr->u.syment.n_numaux;
2596 i;
2597 --i, raw_src++, internal_ptr++) {
2598
6f715d66
SC
2599 (internal_ptr+1)->fix_tag = 0;
2600 (internal_ptr+1)->fix_end = 0;
2601
cbdc7909
JG
2602 coff_swap_aux_in(abfd, (char *)(raw_src +1),
2603 internal_ptr->u.syment.n_type,
2604 internal_ptr->u.syment.n_sclass,
2605 &(internal_ptr+1)->u.auxent);
6f715d66 2606
cbdc7909 2607 coff_pointerize_aux(abfd,
6f715d66
SC
2608 internal,
2609 internal_ptr->u.syment.n_type,
2610 internal_ptr->u.syment.n_sclass,
2611 internal_ptr +1);
0f268757
SC
2612 }
2613 }
cbdc7909 2614
0f268757 2615 /* Free all the raw stuff */
0d740984 2616 bfd_release(abfd, raw);
0f268757 2617
6f715d66 2618 for (internal_ptr = internal; internal_ptr < internal_end;
cbdc7909 2619 internal_ptr ++)
6f715d66
SC
2620 {
2621 if (internal_ptr->u.syment.n_sclass == C_FILE) {
2622 /* make a file symbol point to the name in the auxent, since
2623 the text ".file" is redundant */
2624 if ((internal_ptr+1)->u.auxent.x_file.x_n.x_zeroes == 0) {
cbdc7909 2625 /* the filename is a long one, point into the string table */
6f715d66
SC
2626 if (string_table == NULL) {
2627 string_table = build_string_table(abfd);
2628 }
0f268757 2629
6f715d66
SC
2630 internal_ptr->u.syment._n._n_n._n_offset =
2631 (int) (string_table - 4 +
2632 (internal_ptr+1)->u.auxent.x_file.x_n.x_offset);
2633 }
2634 else {
2635 /* ordinary short filename, put into memory anyway */
2636 internal_ptr->u.syment._n._n_n._n_offset = (int)
cbdc7909
JG
2637 copy_name(abfd, (internal_ptr+1)->u.auxent.x_file.x_fname,
2638 FILNMLEN);
6f715d66
SC
2639 }
2640 }
2641 else {
2642 if (internal_ptr->u.syment._n._n_n._n_zeroes != 0) {
cbdc7909 2643 /* This is a "short" name. Make it long. */
6f715d66
SC
2644 unsigned long i = 0;
2645 char *newstring = NULL;
cbdc7909
JG
2646
2647 /* find the length of this string without walking into memory
2648 that isn't ours. */
6f715d66
SC
2649 for (i = 0; i < 8; ++i) {
2650 if (internal_ptr->u.syment._n._n_name[i] == '\0') {
2651 break;
2652 } /* if end of string */
2653 } /* possible lengths of this string. */
cbdc7909 2654
6f715d66
SC
2655 if ((newstring = (PTR) bfd_alloc(abfd, ++i)) == NULL) {
2656 bfd_error = no_memory;
2657 return (NULL);
2658 } /* on error */
2659 bzero(newstring, i);
2660 strncpy(newstring, internal_ptr->u.syment._n._n_name, i-1);
2661 internal_ptr->u.syment._n._n_n._n_offset = (int) newstring;
2662 internal_ptr->u.syment._n._n_n._n_zeroes = 0;
6f715d66 2663 }
cbdc7909
JG
2664 else if (!SYMNAME_IN_DEBUG(&internal_ptr->u.syment)) {
2665 /* Long name already. Point symbol at the string in the table. */
6f715d66
SC
2666 if (string_table == NULL) {
2667 string_table = build_string_table(abfd);
2668 }
cbdc7909
JG
2669 internal_ptr->u.syment._n._n_n._n_offset = (int)
2670 (string_table - 4 + internal_ptr->u.syment._n._n_n._n_offset);
2671 }
2672 else {
2673 /* Long name in debug section. Very similar. */
2674 if (debug_section == NULL) {
2675 debug_section = build_debug_section(abfd);
2676 }
2677 internal_ptr->u.syment._n._n_n._n_offset = (int)
2678 (debug_section + internal_ptr->u.syment._n._n_n._n_offset);
2679 }
6f715d66
SC
2680 }
2681 internal_ptr += internal_ptr->u.syment.n_numaux;
cbdc7909 2682 }
0f268757 2683
0f268757 2684 obj_raw_syments(abfd) = internal;
cbdc7909 2685
0f268757
SC
2686 return (internal);
2687} /* get_normalized_symtab() */
2688
7a8b18b6
SC
2689#endif /* NO_COFF_SYMBOLS */
2690
0f268757
SC
2691static
2692struct sec *
2693DEFUN(section_from_bfd_index,(abfd, index),
2694 bfd *abfd AND
2695 int index)
2696{
2697 if (index > 0) {
2698 struct sec *answer = abfd->sections;
2699 while (--index) {
2700 answer = answer->next;
2701 }
2702 return answer;
2703 }
2704 return 0;
2705}
2706
7a8b18b6 2707#ifndef NO_COFF_LINENOS
0f268757 2708
9fda1a39
SC
2709/*
2710SUBSUBSECTION
2711 Reading Linenumbers
2712
9fda1a39
SC
2713 Creating the linenumber table is done by reading in the entire
2714 coff linenumber table, and creating another table for internal use.
6f715d66 2715
9fda1a39
SC
2716 A coff line number table is structured so that each function
2717 is marked as having a line number of 0. Each line within the
2718 function is an offset from the first line in the function. The
2719 base of the line number information for the table is stored in
2720 the symbol associated with the function.
6f715d66 2721
9fda1a39
SC
2722 The information is copied from the external to the internal
2723 table, and each symbol which marks a function is marked by
2724 pointing its...
6f715d66 2725
9fda1a39 2726 How does this work ?
6f715d66
SC
2727
2728*/
0f268757
SC
2729
2730static boolean
2731coff_slurp_line_table(abfd, asect)
2732bfd *abfd;
2733asection *asect;
2734 {
2735 LINENO *native_lineno;
2736 alent *lineno_cache;
cbdc7909 2737
0f268757 2738 BFD_ASSERT(asect->lineno == (alent *) NULL);
cbdc7909 2739
0f268757
SC
2740 native_lineno = (LINENO *) buy_and_read(abfd,
2741 asect->line_filepos,
2742 SEEK_SET,
2743 (size_t) (LINESZ *
2744 asect->lineno_count));
2745 lineno_cache =
2746 (alent *) bfd_alloc(abfd, (size_t) ((asect->lineno_count + 1) * sizeof(alent)));
2747 if (lineno_cache == NULL) {
2748 bfd_error = no_memory;
2749 return false;
cbdc7909 2750 } else {
0f268757
SC
2751 unsigned int counter = 0;
2752 alent *cache_ptr = lineno_cache;
2753 LINENO *src = native_lineno;
cbdc7909 2754
0f268757
SC
2755 while (counter < asect->lineno_count) {
2756 struct internal_lineno dst;
2700c3c7 2757 coff_swap_lineno_in(abfd, src, &dst);
0f268757 2758 cache_ptr->line_number = dst.l_lnno;
cbdc7909 2759
0f268757
SC
2760 if (cache_ptr->line_number == 0) {
2761 coff_symbol_type *sym =
2762 (coff_symbol_type *) (dst.l_addr.l_symndx
6f715d66 2763 + obj_raw_syments(abfd))->u.syment._n._n_n._n_zeroes;
0f268757
SC
2764 cache_ptr->u.sym = (asymbol *) sym;
2765 sym->lineno = cache_ptr;
2766 }
2767 else {
2768 cache_ptr->u.offset = dst.l_addr.l_paddr
2769 - bfd_section_vma(abfd, asect);
2770 } /* If no linenumber expect a symbol index */
cbdc7909 2771
0f268757
SC
2772 cache_ptr++;
2773 src++;
2774 counter++;
2775 }
2776 cache_ptr->line_number = 0;
cbdc7909 2777
0f268757
SC
2778 }
2779 asect->lineno = lineno_cache;
2780 /* FIXME, free native_lineno here, or use alloca or something. */
2781 return true;
2782 } /* coff_slurp_line_table() */
2783
7a8b18b6
SC
2784#endif /* NO_COFF_LINENOS */
2785
2786#ifndef NO_COFF_LINENOS
2787
0f268757
SC
2788static boolean
2789DEFUN(coff_slurp_symbol_table,(abfd),
2790 bfd *abfd)
6f715d66
SC
2791{
2792 combined_entry_type *native_symbols;
2793 coff_symbol_type *cached_area;
2794 unsigned int *table_ptr;
cbdc7909 2795
6f715d66
SC
2796 unsigned int number_of_symbols = 0;
2797 if (obj_symbols(abfd))
2798 return true;
2799 bfd_seek(abfd, obj_sym_filepos(abfd), SEEK_SET);
cbdc7909 2800
6f715d66
SC
2801 /* Read in the symbol table */
2802 if ((native_symbols = get_normalized_symtab(abfd)) == NULL) {
2803 return (false);
2804 } /* on error */
cbdc7909 2805
6f715d66
SC
2806 /* Allocate enough room for all the symbols in cached form */
2807 cached_area =
2808 (coff_symbol_type *)
2809 bfd_alloc(abfd, (size_t) (bfd_get_symcount(abfd) * sizeof(coff_symbol_type)));
cbdc7909 2810
6f715d66
SC
2811 if (cached_area == NULL) {
2812 bfd_error = no_memory;
2813 return false;
2814 } /* on error */
2815 table_ptr =
2816 (unsigned int *)
2817 bfd_alloc(abfd, (size_t) (bfd_get_symcount(abfd) * sizeof(unsigned int)));
cbdc7909 2818
6f715d66
SC
2819 if (table_ptr == NULL) {
2820 bfd_error = no_memory;
2821 return false;
85e0c721
SC
2822 }
2823 else
2824 {
6f715d66
SC
2825 coff_symbol_type *dst = cached_area;
2826 unsigned int last_native_index = bfd_get_symcount(abfd);
2827 unsigned int this_index = 0;
2828 while (this_index < last_native_index) {
2829 combined_entry_type *src = native_symbols + this_index;
2830 table_ptr[this_index] = number_of_symbols;
2831 dst->symbol.the_bfd = abfd;
cbdc7909 2832
6f715d66
SC
2833 dst->symbol.name = (char *)(src->u.syment._n._n_n._n_offset);
2834 /*
2835 We use the native name field to point to the cached field
2836 */
2837 src->u.syment._n._n_n._n_zeroes = (int) dst;
2838 dst->symbol.section = section_from_bfd_index(abfd,
2839 src->u.syment.n_scnum);
2840 switch (src->u.syment.n_sclass) {
0f268757 2841#ifdef I960
6f715d66 2842 case C_LEAFEXT:
0f268757 2843#if 0
6f715d66
SC
2844 dst->symbol.value = src->u.syment.n_value - dst->symbol.section->vma;
2845 dst->symbol.flags = BSF_EXPORT | BSF_GLOBAL;
2846 dst->symbol.flags |= BSF_NOT_AT_END;
0f268757 2847#endif
6f715d66 2848 /* Fall through to next case */
cbdc7909 2849
0f268757 2850#endif
cbdc7909 2851
6f715d66 2852 case C_EXT:
cbdc7909
JG
2853#ifdef RS6000COFF_C
2854 case C_HIDEXT:
2855#endif
6f715d66
SC
2856 if ((src->u.syment.n_scnum) == 0) {
2857 if ((src->u.syment.n_value) == 0) {
2858 dst->symbol.flags = BSF_UNDEFINED;
2859 dst->symbol.value= 0;
2860 }
2861 else {
2862 dst->symbol.flags = BSF_FORT_COMM;
2863 dst->symbol.value = (src->u.syment.n_value);
2864 }
2865 }
2866 else {
2867 /*
2868 Base the value as an index from the base of the
2869 section
2870 */
2871 if (dst->symbol.section == (asection *) NULL) {
2872 dst->symbol.flags = BSF_EXPORT | BSF_GLOBAL | BSF_ABSOLUTE;
2873 dst->symbol.value = src->u.syment.n_value;
0f268757
SC
2874 }
2875 else {
6f715d66
SC
2876 dst->symbol.flags = BSF_EXPORT | BSF_GLOBAL;
2877 dst->symbol.value = src->u.syment.n_value - dst->symbol.section->vma;
2878 }
2879 if (ISFCN((src->u.syment.n_type))) {
0f268757 2880 /*
6f715d66
SC
2881 A function ext does not go at the end of a file
2882 */
2883 dst->symbol.flags |= BSF_NOT_AT_END;
0f268757 2884 }
6f715d66 2885 }
85e0c721
SC
2886
2887
6f715d66 2888 break;
cbdc7909 2889
6f715d66 2890 case C_STAT: /* static */
0f268757 2891#ifdef I960
6f715d66 2892 case C_LEAFSTAT: /* static leaf procedure */
0f268757 2893#endif
6f715d66 2894 case C_LABEL: /* label */
0d740984
SC
2895 if (src->u.syment.n_scnum == -2)
2896 dst->symbol.flags = BSF_DEBUGGING;
2897 else
2898 dst->symbol.flags = BSF_LOCAL;
6f715d66 2899 /*
0d740984
SC
2900 Base the value as an index from the base of the section, if
2901 there is one
6f715d66 2902 */
0d740984
SC
2903 if (dst->symbol.section)
2904 dst->symbol.value = (src->u.syment.n_value) -
2905 dst->symbol.section->vma;
2906 else
2907 dst->symbol.value = (src->u.syment.n_value) ;
6f715d66 2908 break;
cbdc7909 2909
6f715d66
SC
2910 case C_MOS: /* member of structure */
2911 case C_EOS: /* end of structure */
41f50af0
SC
2912#ifdef NOTDEF /* C_AUTOARG has the same value */
2913#ifdef C_GLBLREG
2914 case C_GLBLREG: /* A29k-specific storage class */
2915#endif
2916#endif
6f715d66
SC
2917 case C_REGPARM: /* register parameter */
2918 case C_REG: /* register variable */
0f268757 2919#ifdef C_AUTOARG
6f715d66 2920 case C_AUTOARG: /* 960-specific storage class */
0f268757 2921#endif
6f715d66 2922 case C_TPDEF: /* type definition */
6f715d66
SC
2923 case C_ARG:
2924 case C_AUTO: /* automatic variable */
2925 case C_FIELD: /* bit field */
2926 case C_ENTAG: /* enumeration tag */
2927 case C_MOE: /* member of enumeration */
2928 case C_MOU: /* member of union */
2929 case C_UNTAG: /* union tag */
6f715d66
SC
2930 dst->symbol.flags = BSF_DEBUGGING;
2931 dst->symbol.value = (src->u.syment.n_value);
2932 break;
cbdc7909 2933
6f715d66
SC
2934 case C_FILE: /* file name */
2935 case C_STRTAG: /* structure tag */
cbdc7909
JG
2936#ifdef RS6000COFF_C
2937 case C_BINCL: /* beginning of include file */
2938 case C_EINCL: /* ending of include file */
2939 case C_GSYM:
2940 case C_LSYM:
2941 case C_PSYM:
2942 case C_RSYM:
2943 case C_RPSYM:
2944 case C_STSYM:
2945 case C_DECL:
2946 case C_ENTRY:
2947 case C_FUN:
2948 case C_BSTAT:
2949 case C_ESTAT:
2950#endif
6f715d66
SC
2951 dst->symbol.flags = BSF_DEBUGGING;
2952 dst->symbol.value = (src->u.syment.n_value);
6f715d66 2953 break;
cbdc7909 2954
6f715d66
SC
2955 case C_BLOCK: /* ".bb" or ".eb" */
2956 case C_FCN: /* ".bf" or ".ef" */
41f50af0 2957 case C_EFCN: /* physical end of function */
6f715d66
SC
2958 dst->symbol.flags = BSF_LOCAL;
2959 /*
2960 Base the value as an index from the base of the section
2961 */
2962 dst->symbol.value = (src->u.syment.n_value) - dst->symbol.section->vma;
6f715d66 2963 break;
cbdc7909 2964
6f715d66
SC
2965 case C_NULL:
2966 case C_EXTDEF: /* external definition */
2967 case C_ULABEL: /* undefined label */
2968 case C_USTATIC: /* undefined static */
2969 case C_LINE: /* line # reformatted as symbol table entry */
2970 case C_ALIAS: /* duplicate tag */
2971 case C_HIDDEN: /* ext symbol in dmert public lib */
6f715d66 2972 default:
cbdc7909
JG
2973
2974 fprintf(stderr,"Unrecognized storage class %d\n",
41f50af0 2975 src->u.syment.n_sclass);
6f715d66
SC
2976 abort();
2977 dst->symbol.flags = BSF_DEBUGGING;
2978 dst->symbol.value = (src->u.syment.n_value);
6f715d66
SC
2979 break;
2980 }
cbdc7909 2981
6f715d66 2982 BFD_ASSERT(dst->symbol.flags != 0);
cbdc7909 2983
6f715d66 2984 dst->native = src;
cbdc7909 2985
6f715d66
SC
2986 dst->symbol.udata = 0;
2987 dst->lineno = (alent *) NULL;
2988 this_index += (src->u.syment.n_numaux) + 1;
2989 dst++;
2990 number_of_symbols++;
2991 } /* walk the native symtab */
2992 } /* bfdize the native symtab */
cbdc7909 2993
6f715d66
SC
2994 obj_symbols(abfd) = cached_area;
2995 obj_raw_syments(abfd) = native_symbols;
cbdc7909 2996
6f715d66
SC
2997 bfd_get_symcount(abfd) = number_of_symbols;
2998 obj_convert(abfd) = table_ptr;
2999 /* Slurp the line tables for each section too */
3000 {
3001 asection *p;
3002 p = abfd->sections;
3003 while (p) {
3004 coff_slurp_line_table(abfd, p);
3005 p = p->next;
0f268757 3006 }
6f715d66
SC
3007 }
3008 return true;
3009} /* coff_slurp_symbol_table() */
0f268757
SC
3010
3011static unsigned int
3012coff_get_symtab_upper_bound(abfd)
3013bfd *abfd;
3014 {
3015 if (!coff_slurp_symbol_table(abfd))
3016 return 0;
cbdc7909 3017
0f268757
SC
3018 return (bfd_get_symcount(abfd) + 1) * (sizeof(coff_symbol_type *));
3019 }
3020
3021
3022static unsigned int
85e0c721
SC
3023DEFUN(coff_get_symtab, (abfd, alocation),
3024 bfd *abfd AND
3025 asymbol **alocation)
3026{
0f268757
SC
3027 unsigned int counter = 0;
3028 coff_symbol_type *symbase;
3029 coff_symbol_type **location = (coff_symbol_type **) (alocation);
3030 if (!coff_slurp_symbol_table(abfd))
85e0c721
SC
3031 return 0;
3032
3033 symbase = obj_symbols(abfd);
3034 while (counter < bfd_get_symcount(abfd))
3035 {
3036 /* This nasty code looks at the symbol to decide whether or
3037 not it is descibes a constructor/destructor entry point. It
3038 is structured this way to (hopefully) speed non matches */
3b4f1a5d
SC
3039#if 0
3040 if (0 && symbase->symbol.name[9] == '$')
85e0c721
SC
3041 {
3042 bfd_constructor_entry(abfd,
3043 (asymbol **)location,
3044 symbase->symbol.name[10] == 'I' ?
3045 "CTOR" : "DTOR");
3046 }
3b4f1a5d 3047#endif
85e0c721
SC
3048 *(location++) = symbase++;
3049 counter++;
3050 }
0f268757
SC
3051 *location++ = 0;
3052 return bfd_get_symcount(abfd);
85e0c721 3053}
0f268757 3054
7a8b18b6
SC
3055#endif /* NO_COFF_SYMBOLS */
3056
0f268757
SC
3057static unsigned int
3058coff_get_reloc_upper_bound(abfd, asect)
3059bfd *abfd;
3060sec_ptr asect;
3061 {
3062 if (bfd_get_format(abfd) != bfd_object) {
3063 bfd_error = invalid_operation;
3064 return 0;
3065 }
3066 return (asect->reloc_count + 1) * sizeof(arelent *);
3067 }
3068
9fda1a39
SC
3069/*
3070SUBSUBSECTION
3071 Reading Relocations
3072
9fda1a39
SC
3073 Coff relocations are easily transformed into the internal BFD form
3074 (@code{arelent}).
3075
3076 Reading a coff relocation table is done in the following stages:
3077
3078 o The entire coff relocation table is read into memory.
3079
3080 o Each relocation is processed in turn, first it is swapped from the
3081 external to the internal form.
3082
3083 o The symbol referenced in the relocation's symbol index is
3084 turned intoa pointer into the canonical symbol table. Note
3085 that this table is the same as the one returned by a call to
3086 @code{bfd_canonicalize_symtab}. The back end will call the
3087 routine and save the result if a canonicalization hasn't been done.
3088
3089 o The reloc index is turned into a pointer to a howto
3090 structure, in a back end specific way. For instance, the 386
3091 and 960 use the @code{r_type} to directly produce an index
3092 into a howto table vector; the 88k subtracts a number from the
3093 @code{r_type} field and creates an addend field.
3094
3095
6f715d66
SC
3096*/
3097
3b4f1a5d
SC
3098#ifndef CALC_ADDEND
3099#define CALC_ADDEND(abfd, ptr, reloc, cache_ptr) \
3100 if (ptr && ptr->the_bfd == abfd \
3101 && ptr->section != (asection *) NULL \
3102 && ((ptr->flags & BSF_OLD_COMMON)== 0)) \
3103 { \
3104 cache_ptr->addend = -(ptr->section->vma + ptr->value); \
3105 } \
3106 else { \
3107 cache_ptr->addend = 0; \
3108 }
3109#endif
3110
0f268757
SC
3111static boolean
3112DEFUN(coff_slurp_reloc_table,(abfd, asect, symbols),
3113 bfd *abfd AND
3114 sec_ptr asect AND
3115 asymbol **symbols)
85e0c721 3116{
3b4f1a5d
SC
3117 RELOC *native_relocs;
3118 arelent *reloc_cache;
3119 arelent *cache_ptr;
3120
3121 unsigned int idx;
3122
3123 if (asect->relocation)
3124 return true;
3125 if (asect->reloc_count == 0)
3126 return true;
3127 if (asect->flags & SEC_CONSTRUCTOR)
3128 return true;
7a8b18b6 3129#ifndef NO_COFF_SYMBOLS
3b4f1a5d
SC
3130 if (!coff_slurp_symbol_table(abfd))
3131 return false;
3132#endif
3133 native_relocs =
3134 (RELOC *) buy_and_read(abfd,
3135 asect->rel_filepos,
3136 SEEK_SET,
3137 (size_t) (RELSZ *
3138 asect->reloc_count));
3139 reloc_cache = (arelent *)
3140 bfd_alloc(abfd, (size_t) (asect->reloc_count * sizeof(arelent)));
3141
3142 if (reloc_cache == NULL) {
3143 bfd_error = no_memory;
3144 return false;
3145 }
3146
3147
3148 for (idx = 0; idx < asect->reloc_count; idx ++)
3149 {
616ebcfd 3150#ifdef RELOC_PROCESSING
3b4f1a5d 3151 struct internal_reloc dst;
3b4f1a5d
SC
3152 struct external_reloc *src;
3153
3154 cache_ptr = reloc_cache + idx;
3155 src = native_relocs + idx;
3b4f1a5d
SC
3156 bfd_swap_reloc_in(abfd, src, &dst);
3157
9898b929
JG
3158 RELOC_PROCESSING(cache_ptr, &dst, symbols, abfd, asect);
3159#else
616ebcfd
SC
3160 struct internal_reloc dst;
3161 asymbol *ptr;
3162 struct external_reloc *src;
3163
3164 cache_ptr = reloc_cache + idx;
3165 src = native_relocs + idx;
3166
3167 bfd_swap_reloc_in(abfd, src, &dst);
3168
9898b929
JG
3169
3170 cache_ptr->address = dst.r_vaddr;
3171
3b4f1a5d
SC
3172 if (dst.r_symndx != -1)
3173 {
9898b929
JG
3174 cache_ptr->sym_ptr_ptr = symbols + obj_convert(abfd)[dst.r_symndx];
3175 ptr = *(cache_ptr->sym_ptr_ptr);
3b4f1a5d
SC
3176 }
3177 else
3178 {
9898b929
JG
3179 cache_ptr->sym_ptr_ptr = 0;
3180 ptr = 0;
3b4f1a5d
SC
3181
3182 }
85e0c721 3183
3b4f1a5d
SC
3184 /*
3185 The symbols definitions that we have read in have been
3186 relocated as if their sections started at 0. But the offsets
3187 refering to the symbols in the raw data have not been
3188 modified, so we have to have a negative addend to compensate.
3189
3190 Note that symbols which used to be common must be left alone */
cbdc7909 3191
3b4f1a5d
SC
3192 /* Calculate any reloc addend by looking at the symbol */
3193 CALC_ADDEND(abfd, ptr, dst, cache_ptr);
cbdc7909 3194
3b4f1a5d
SC
3195 cache_ptr->address -= asect->vma;
3196 cache_ptr->section = (asection *) NULL;
20fdc627 3197
3b4f1a5d
SC
3198 /* Fill in the cache_ptr->howto field from dst.r_type */
3199 RTYPE2HOWTO(cache_ptr, dst);
9898b929
JG
3200#endif
3201
3202 }
cbdc7909 3203
3b4f1a5d
SC
3204 asect->relocation = reloc_cache;
3205 return true;
85e0c721 3206}
0f268757
SC
3207
3208
3209/* This is stupid. This function should be a boolean predicate */
3210static unsigned int
85e0c721
SC
3211DEFUN(coff_canonicalize_reloc, (abfd, section, relptr, symbols),
3212bfd *abfd AND
3213sec_ptr section AND
3214arelent **relptr AND
3215asymbol **symbols)
3216{
0f268757
SC
3217 arelent *tblptr = section->relocation;
3218 unsigned int count = 0;
cbdc7909 3219
cbdc7909 3220
85e0c721
SC
3221 if (section->flags & SEC_CONSTRUCTOR)
3222 {
3223 /* this section has relocs made up by us, they are not in the
3224 file, so take them out of their chain and place them into
3225 the data area provided */
3226 arelent_chain *chain = section->constructor_chain;
3227 for (count = 0; count < section->reloc_count; count ++)
3228 {
3229 *relptr ++ = &chain->relent;
3230 chain = chain->next;
3231 }
3232
3233 }
3234 else
3235 {
3236 coff_slurp_reloc_table(abfd, section, symbols);
3237
3238
3239 tblptr = section->relocation;
3240 if (!tblptr)
3241 return 0;
3242
3243 for (; count++ < section->reloc_count;)
3244 *relptr++ = tblptr++;
cbdc7909 3245
85e0c721
SC
3246
3247 }
3248 *relptr = 0;
0f268757 3249 return section->reloc_count;
85e0c721 3250}
0f268757 3251
7a8b18b6 3252#ifndef NO_COFF_SYMBOLS
0f268757
SC
3253
3254/*
6724ff46 3255provided a BFD, a section and an offset into the section, calculate and
0f268757
SC
3256return the name of the source file and the line nearest to the wanted
3257location.
3258*/
3259
3260static boolean
3261DEFUN(coff_find_nearest_line,(abfd,
3262 section,
fb3be09b 3263 ignore_symbols,
0f268757
SC
3264 offset,
3265 filename_ptr,
3266 functionname_ptr,
3267 line_ptr),
3268 bfd *abfd AND
3269 asection *section AND
fb3be09b 3270 asymbol **ignore_symbols AND
0f268757
SC
3271 bfd_vma offset AND
3272 CONST char **filename_ptr AND
3273 CONST char **functionname_ptr AND
3274 unsigned int *line_ptr)
3275{
3276 static bfd *cache_abfd;
3277 static asection *cache_section;
3278 static bfd_vma cache_offset;
3279 static unsigned int cache_i;
3280 static alent *cache_l;
cbdc7909 3281
0f268757 3282 unsigned int i = 0;
fb3be09b 3283 coff_data_type *cof = coff_data(abfd);
0f268757 3284 /* Run through the raw syments if available */
6f715d66 3285 combined_entry_type *p;
0f268757
SC
3286 alent *l;
3287 unsigned int line_base = 0;
cbdc7909
JG
3288
3289
0f268757
SC
3290 *filename_ptr = 0;
3291 *functionname_ptr = 0;
3292 *line_ptr = 0;
cbdc7909 3293
0f268757 3294 /* Don't try and find line numbers in a non coff file */
0d740984 3295 if (abfd->xvec->flavour != bfd_target_coff_flavour)
0f268757 3296 return false;
cbdc7909 3297
fb3be09b 3298 if (cof == NULL)
0f268757 3299 return false;
6f715d66 3300
0f268757 3301 p = cof->raw_syments;
cbdc7909 3302
0f268757 3303 for (i = 0; i < cof->raw_syment_count; i++) {
6f715d66
SC
3304 if (p->u.syment.n_sclass == C_FILE) {
3305 /* File name has been moved into symbol */
3306 *filename_ptr = (char *) p->u.syment._n._n_n._n_offset;
0f268757
SC
3307 break;
3308 }
6f715d66 3309 p += 1 + p->u.syment.n_numaux;
0f268757
SC
3310 }
3311 /* Now wander though the raw linenumbers of the section */
3312 /*
6724ff46 3313 If this is the same BFD as we were previously called with and this is
0f268757
SC
3314 the same section, and the offset we want is further down then we can
3315 prime the lookup loop
3316 */
3317 if (abfd == cache_abfd &&
3318 section == cache_section &&
3319 offset >= cache_offset) {
3320 i = cache_i;
3321 l = cache_l;
3322 }
3323 else {
3324 i = 0;
3325 l = section->lineno;
3326 }
cbdc7909 3327
0f268757
SC
3328 for (; i < section->lineno_count; i++) {
3329 if (l->line_number == 0) {
3330 /* Get the symbol this line number points at */
3331 coff_symbol_type *coff = (coff_symbol_type *) (l->u.sym);
3332 *functionname_ptr = coff->symbol.name;
3333 if (coff->native) {
6f715d66
SC
3334 combined_entry_type *s = coff->native;
3335 s = s + 1 + s->u.syment.n_numaux;
0f268757
SC
3336 /*
3337 S should now point to the .bf of the function
3338 */
6f715d66 3339 if (s->u.syment.n_numaux) {
0f268757
SC
3340 /*
3341 The linenumber is stored in the auxent
3342 */
6f715d66 3343 union internal_auxent *a = &((s + 1)->u.auxent);
0f268757
SC
3344 line_base = a->x_sym.x_misc.x_lnsz.x_lnno;
3345 }
3346 }
3347 }
3348 else {
3349 if (l->u.offset > offset)
3350 break;
3351 *line_ptr = l->line_number + line_base + 1;
3352 }
3353 l++;
3354 }
cbdc7909 3355
0f268757
SC
3356 cache_abfd = abfd;
3357 cache_section = section;
3358 cache_offset = offset;
3359 cache_i = i;
3360 cache_l = l;
6f715d66 3361
0f268757
SC
3362 return true;
3363}
3364
3365#ifdef GNU960
3366file_ptr
3367coff_sym_filepos(abfd)
3368bfd *abfd;
3369 {
3370 return obj_sym_filepos(abfd);
3371 }
3372#endif
3373
7a8b18b6
SC
3374#endif /* NO_COFF_SYMBOLS */
3375
0f268757 3376
cbdc7909 3377static int
0f268757
SC
3378DEFUN(coff_sizeof_headers,(abfd, reloc),
3379 bfd *abfd AND
3380 boolean reloc)
85e0c721 3381{
0f268757 3382 size_t size;
cbdc7909 3383
0f268757 3384 if (reloc == false) {
85e0c721 3385 size = FILHSZ + AOUTSZ;
0f268757
SC
3386 }
3387 else {
85e0c721 3388 size = FILHSZ;
0f268757 3389 }
cbdc7909 3390
0f268757
SC
3391 size += abfd->section_count * SCNHSZ;
3392 return size;
85e0c721 3393}
0f268757
SC
3394
3395
3396#define coff_core_file_failing_command _bfd_dummy_core_file_failing_command
3397#define coff_core_file_failing_signal _bfd_dummy_core_file_failing_signal
3398#define coff_core_file_matches_executable_p _bfd_dummy_core_file_matches_executable_p
3399#define coff_slurp_armap bfd_slurp_coff_armap
3400#define coff_slurp_extended_name_table _bfd_slurp_extended_name_table
3401#define coff_truncate_arname bfd_dont_truncate_arname
3402#define coff_openr_next_archived_file bfd_generic_openr_next_archived_file
3403#define coff_generic_stat_arch_elt bfd_generic_stat_arch_elt
3404#define coff_get_section_contents bfd_generic_get_section_contents
3405#define coff_close_and_cleanup bfd_generic_close_and_cleanup
6f715d66
SC
3406
3407#define coff_bfd_debug_info_start bfd_void
3408#define coff_bfd_debug_info_end bfd_void
41f50af0 3409#define coff_bfd_debug_info_accumulate (PROTO(void,(*),(bfd*, struct sec *))) bfd_void
This page took 0.339865 seconds and 4 git commands to generate.