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