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