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