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