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