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