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