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