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