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