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