Now full of documentation. Yum Yum.
[deliverable/binutils-gdb.git] / bfd / coffcode.h
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
5 This file is part of BFD, the Binary File Diddler.
6
7 BFD is free software; you can redistribute it and/or modify it under the
8 terms of the GNU General Public License as published by the Free Software
9 Foundation; either version 1, or (at your option) any later version.
10
11 BFD is distributed in the hope that it will be useful, but WITHOUT ANY
12 WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
13 FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
14 details.
15
16 You should have received a copy of the GNU General Public License along with
17 BFD; see the file COPYING. If not, write to the Free Software Foundation,
18 675 Mass Ave, Cambridge, MA 02139, USA.
19 */
20
21 /*doc*
22 @section coff backends
23
24 BFD supports a number of different flavours of coff format. The major
25 difference between formats are the sizes and alignments of fields in
26 structures on disk, and the occasional extra field.
27
28 Coff in all its varieties is implimented with a few common files and a
29 number of implementation specific files. For example, The 88k bcs coff
30 format is implemented in the file @code{m88k-bcs.c}. This file
31 @code{#include}s @code{m88k-bcs.h} which defines the external
32 structure of the coff format for the 88k, and @code{internalcoff.h}
33 which defines the internal structure. @code{m88k-bcs.c} also defines
34 the relocations used by the 88k format @xref{Relocations}. Then the
35 major portion of coff code is included (@code{coffcode.h}) which
36 defines the methods used to act upon the types defined in
37 @code{m88k-bcs.h} and @code{internalcoff.h}.
38
39 The 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
42 than @code{m88k-bcs.h}.
43
44 @subsection Porting To A New Version of Coff
45
46 The recommended method is to select from the existing implimentations
47 the version of coff which is most like the one you want to use, for
48 our purposes, we'll say that i386 coff is the one you select, and that
49 your coff flavour is called foo. Copy the @code{i386coff.c} to @code{foocoff.c},
50 copy @code{../include/i386coff.h} to @code{../include/foocoff.h} and
51 add the lines to @code{targets.c} and @code{Makefile.in} so that your
52 new back end is used.
53
54 Alter the shapes of the structures in @code{../include/foocoff.h} so
55 that 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
59 You can verify that your new bfd backend works quite simply by
60 building @code{objdump} from the @code{binutils} directory, and
61 making sure that its version of what's going on at your host systems
62 idea (assuming it has the pretty standard coff dump utility (usually
63 called @code{att-dump} or just @code{dump})) are the same.
64
65 Then clean up your code, and send what you've done to Cygnus. Then your stuff
66 will be in the next release, and you won't have to keep integrating
67 it.
68
69 @subsection How The Coff Backend Works
70
71 @subsubsection Bit Twiddling
72 Each flavour of coff supported in bfd has its own header file
73 descibing the external layout of the structures. There is also an
74 internal description of the coff layout (in @code{internalcoff.h})
75 file (@code{}). A major function of the coff backend is swapping the
76 bytes and twiddling the bits to translate the external form of the
77 structures into the normal internal form. This is all performed in the
78 @code{bfd_swap}_@i{thing}_@i{direction} routines. Some elements are
79 different sizes between different versions of coff, it is the duty of
80 the coff version specific include file to override the definitions of
81 various packing routines in @code{coffcode.h}. Eg the size of line
82 number 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
84 select the correct one. No doubt, some day someone will find a version
85 of coff which has a varying field size not catered for at the moment.
86 To port bfd, that person will have to add more @code{#defines}.
87
88 Three 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
91 own, but uses bfd to fix things up.
92
93 @subsubsection Symbol Reading
94 The simple canonical form for symbols used by bfd is not rich enough
95 to keep all the information available in a coff symbol table. The back
96 end gets around this by keeping the original symbol table around,
97 "behind the sceens".
98
99 When 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
102 coff file and swaps all the structures inside into the internal form.
103 It also fixes up all the pointers in the table (represented in the file
104 by offsets from the first symbol in the table) into physical pointers
105 to elements in the new internal table. This involves some work since
106 the meanings of fields changes depending upon context; a field that is a
107 pointer to another structure in the symbol table at one moment may be
108 the size in bytes of a structure in the next.
109
110 Another pass is made over the table. All symbols which mark file names
111 (@code{C_FILE} symbols) are modified so that the internal string
112 points to the value in the auxent (the real filename) rather than the
113 normal text associated with the symbol (@code{".file"}).
114
115 At this time the symbol names are moved around. Coff stores all
116 symbols less than nine characters long physically within the symbol
117 table, longer strings are kept at the end of the file in the string
118 table. This pass moves all strings into memory, and replaces them with
119 pointers to the strings.
120
121 The symbol table is massaged once again, this time to create the
122 canonical table used by the bfd application. Each symbol is inspected
123 in turn, and a decision made (using the @code{sclass} field) about the
124 various flags to set in the @code{asymbol} @xref{Symbols}. The
125 generated canonical table shares strings with the hidden internal
126 symbol table.
127
128 Any linenumbers are read from the coff file too, and attatched to the
129 symbols which own the functions the linenumbers belong to.
130
131 @subsubsection Symbol Writing
132 Writing a symbol to a coff file which didn't come from a coff file
133 will lose any debugging information. The @code{asymbol} structure
134 remembers the bfd from which was born, and on output the back end
135 makes sure that the same destination target as source target is
136 present.
137
138 When the symbols have come from a coff file then all the debugging
139 information is preserved.
140
141 Symbol tables are provided for writing to the back end in a vector of
142 pointers to pointers. This allows applications like the linker to
143 accumulate and output large symbol tables without having to do too
144 much byte copying.
145
146 The symbol table is not output to a writable bfd until it is closed.
147 The order of operations on the canonical symbol table at that point
148 are:
149 @table @code
150 @item coff_renumber_symbols
151 This function runs through the provided symbol table and patches each
152 symbol marked as a file place holder (@code{C_FILE}) to point to the
153 next file place holder in the list. It also marks each @code{offset}
154 field in the list with the offset from the first symbol of the current
155 symbol.
156
157 Another function of this procedure is to turn the canonical value form
158 of bfd into the form used by coff. Internally, bfd expects symbol
159 values to be offsets from a section base; so a symbol physically at
160 0x120, but in a section starting at 0x100, would have the value 0x20.
161 Coff expects symbols to contain their final value, so symbols have
162 their values changed at this point to reflect their sum with their
163 owning 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
167 This routine runs though the provided symbol table and uses the
168 offsets generated by the previous pass and the pointers generated when
169 the symbol table was read in to create the structured hierachy
170 required by coff. It changes each pointer to a symbol to an index into
171 the symbol table of the symbol being referenced.
172 @item coff_write_symbols
173 This routine runs through the symbol table and patches up the symbols
174 from their internal form into the coff way, calls the bit twiddlers
175 and writes out the tabel to the file.
176 @end table
177 */
178
179 /*proto*
180
181 The hidden information for an asymbol is:
182
183 *+++
184
185 $ typedef struct coff_ptr_struct
186 $ {
187
188 Remembers the offset from the first symbol in the file for this
189 symbol. Generated by @code{coff_renumber_symbols}.
190
191 $ unsigned int offset;
192
193 Should the tag field of this symbol be renumbered.
194 Created by @code{coff_pointerize_aux}.
195
196 $ char fix_tag;
197
198 Should the endidx field of this symbol be renumbered.
199 Created by @code{coff_pointerize_aux}.
200
201 $ char fix_end;
202
203 The 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
214 Each canonical asymbol really looks like this:
215
216 *+++
217
218 $ typedef struct coff_symbol_struct
219 $ {
220
221 The actual symbol which the rest of bfd works with
222
223 $ asymbol symbol;
224
225 A pointer to the hidden information for this symbol
226
227 $ combined_entry_type *native;
228
229 A pointer to the linenumber information for this symbol
230
231 $ struct lineno_cache_entry *lineno;
232 $ } coff_symbol_type;
233
234 *---
235
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
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
253
254 #define PUTWORD bfd_h_put_32
255 #define PUTHALF bfd_h_put_16
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)
300 #endif
301
302
303 \f
304 /* void warning(); */
305
306
307 static int
308 DEFUN(get_index,(symbol),
309 asymbol *symbol)
310 {
311 return (int) symbol->value;
312 }
313
314 static void
315 DEFUN(set_index,(symbol, idx),
316 asymbol *symbol AND
317 unsigned int idx)
318 {
319 symbol->value = idx;
320 }
321
322
323 /* **********************************************************************
324 Here are all the routines for swapping the structures seen in the
325 outside world into the internal forms.
326 */
327
328
329 static void
330 DEFUN(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
343
344 static void
345 DEFUN(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
359 static void
360 DEFUN(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
374 static void
375 DEFUN(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
390
391 static void
392 DEFUN(coff_swap_sym_in,(abfd, ext1, in1),
393 bfd *abfd AND
394 PTR ext1 AND
395 PTR in1)
396 {
397 SYMENT *ext = (SYMENT *)ext1;
398 struct internal_syment *in = (struct internal_syment *)in1;
399
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
419 static void
420 DEFUN(coff_swap_sym_out,(abfd,in, ext),
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
446 static void
447 DEFUN(coff_swap_aux_in,(abfd, ext1, type, class, in1),
448 bfd *abfd AND
449 PTR ext1 AND
450 int type AND
451 int class AND
452 PTR in1)
453 {
454 AUXENT *ext = (AUXENT *)ext1;
455 union internal_auxent *in = (union internal_auxent *)in1;
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);
461 } else {
462 memcpy (in->x_file.x_fname, ext->x_file.x_fname,
463 sizeof (in->x_file.x_fname));
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) {
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);
476 break;
477 }
478 default:
479 in->x_sym.x_tagndx.l = bfd_h_get_32(abfd, ext->x_sym.x_tagndx);
480 #ifndef NO_TVNDX
481 in->x_sym.x_tvndx = bfd_h_get_16(abfd, ext->x_sym.x_tvndx);
482 #endif
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 }
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
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 {
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);
499 }
500 }
501 }
502
503 static void
504 DEFUN(coff_swap_aux_out,(abfd, in, type, class, ext),
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 }
517 else {
518 memcpy ( ext->x_file.x_fname,in->x_file.x_fname,
519 sizeof (in->x_file.x_fname));
520 }
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) {
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);
532 break;
533 }
534 default:
535 PUTWORD(abfd, in->x_sym.x_tagndx.l, ext->x_sym.x_tagndx);
536 #ifndef NO_TVNDX
537 PUTWORD(abfd, in->x_sym.x_tvndx , ext->x_sym.x_tvndx);
538 #endif
539
540 if (ISFCN(type)) {
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);
544 }
545 else {
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
561 }
562 }
563 }
564
565 static void
566 DEFUN(coff_swap_lineno_in,(abfd, ext1, in1),
567 bfd *abfd AND
568 PTR ext1 AND
569 PTR in1)
570 {
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
580 }
581
582 static void
583 DEFUN(coff_swap_lineno_out,(abfd, in, ext),
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);
589 #if defined(M88)
590 PUTWORD(abfd, in->l_lnno, ext->l_lnno);
591 #else
592 PUTHALF(abfd, in->l_lnno, ext->l_lnno);
593 #endif
594 }
595
596
597
598
599 static void
600 DEFUN(bfd_swap_aouthdr_in,(abfd, aouthdr_ext1, aouthdr_int1),
601 bfd *abfd AND
602 PTR aouthdr_ext1 AND
603 PTR aouthdr_int1)
604 {
605 AOUTHDR *aouthdr_ext = (AOUTHDR *) aouthdr_ext1;
606 struct internal_aouthdr *aouthdr_int = (struct internal_aouthdr *)aouthdr_int1;
607
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
621 static void
622 DEFUN(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
640 static void
641 DEFUN(coff_swap_scnhdr_in,(abfd, scnhdr_ext, scnhdr_int),
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);
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
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);
660 #endif
661 #ifdef I960
662 scnhdr_int->s_align = bfd_h_get_32(abfd, scnhdr_ext->s_align);
663 #endif
664 }
665
666 static void
667 DEFUN(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);
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
684 PUTHALF(abfd, scnhdr_int->s_nlnno, scnhdr_ext->s_nlnno);
685 PUTHALF(abfd, scnhdr_int->s_flags, scnhdr_ext->s_flags);
686 #endif
687
688 #if defined(I960)
689 PUTWORD(abfd, scnhdr_int->s_align, scnhdr_ext->s_align);
690 #endif
691 }
692
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 */
699 static char *
700 DEFUN(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
723 /*
724 initialize a section structure with information peculiar to this
725 particular implementation of coff
726 */
727
728 static boolean
729 DEFUN(coff_new_section_hook,(abfd_ignore, section_ignore),
730 bfd *abfd_ignore AND
731 asection *section_ignore)
732 {
733 section_ignore->alignment_power = abfd_ignore->xvec->align_power_min;
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. */
739 static boolean
740 DEFUN(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 }
803 static boolean
804 DEFUN(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
816 static
817 bfd_target *
818 DEFUN(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;
825
826 size_t readsize; /* length of file_info */
827 SCNHDR *external_sections;
828
829 /* Build a play area */
830 if (coff_mkobject(abfd) != true)
831 return 0;
832 coff = coff_data(abfd);
833
834
835 external_sections = (SCNHDR *)bfd_alloc(abfd, readsize = (nscns * SCNHSZ));
836
837 if (bfd_read((PTR)external_sections, 1, readsize, abfd) != readsize) {
838 goto fail;
839 }
840
841
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;
854 coff_swap_scnhdr_in(abfd, external_sections + i, &tmp);
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) {
861 #ifdef I386MAGIC
862 case I386MAGIC:
863 abfd->obj_arch = bfd_arch_i386;
864 abfd->obj_machine = 0;
865 break;
866 #endif
867 #ifdef MIPS
868 case MIPS_MAGIC_1:
869 case MIPS_MAGIC_2:
870 case MIPS_MAGIC_3:
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
955 static bfd_target *
956 DEFUN(coff_object_p,(abfd),
957 bfd *abfd)
958 {
959 int nscns;
960 FILHDR filehdr;
961 AOUTHDR opthdr;
962 struct internal_filehdr internal_f;
963 struct internal_aouthdr internal_a;
964
965 bfd_error = system_call_error;
966
967 /* figure out how much to read */
968 if (bfd_read((PTR) &filehdr, 1, FILHSZ, abfd) != FILHSZ)
969 return 0;
970
971 bfd_swap_filehdr_in(abfd, &filehdr, &internal_f);
972
973 if (BADMAG(internal_f)) {
974 bfd_error = wrong_format;
975 return 0;
976 }
977 nscns =internal_f.f_nscns;
978
979 if (internal_f.f_opthdr) {
980 if (bfd_read((PTR) &opthdr, 1,AOUTSZ, abfd) != AOUTSZ) {
981 return 0;
982 }
983 bfd_swap_aouthdr_in(abfd, &opthdr, &internal_a);
984 }
985
986 /* Seek past the opt hdr stuff */
987 bfd_seek(abfd, internal_f.f_opthdr + FILHSZ, SEEK_SET);
988
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 */
997
998 #ifndef MIPS
999 if (internal_f.f_opthdr != 0 && AOUTSZ != internal_f.f_opthdr)
1000 return (bfd_target *)NULL;
1001 #endif
1002
1003 return coff_real_object_p(abfd, nscns, &internal_f, &internal_a);
1004 }
1005
1006
1007
1008
1009 /*
1010 Takes a bfd and a symbol, returns a pointer to the coff specific area
1011 of the symbol if there is one.
1012 */
1013 static coff_symbol_type *
1014 DEFUN(coff_symbol_from,(abfd, symbol),
1015 bfd *abfd AND
1016 asymbol *symbol)
1017 {
1018 if (symbol->the_bfd->xvec->flavour != bfd_target_coff_flavour_enum)
1019 return (coff_symbol_type *)NULL;
1020
1021 if (symbol->the_bfd->tdata == (PTR)NULL)
1022 return (coff_symbol_type *)NULL;
1023
1024 return (coff_symbol_type *) symbol;
1025 }
1026
1027
1028
1029
1030
1031
1032
1033 static void
1034 DEFUN(coff_count_linenumbers,(abfd),
1035 bfd *abfd)
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;
1045 }
1046 }
1047
1048
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) {
1062 q->symbol.section->output_section->lineno_count++;
1063 l++;
1064 }
1065 }
1066 }
1067 }
1068 }
1069
1070
1071
1072 static void
1073 DEFUN(fixup_symbol_value,(coff_symbol_ptr, syment),
1074 coff_symbol_type *coff_symbol_ptr AND
1075 struct internal_syment *syment)
1076 {
1077
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 }
1105
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
1108
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.
1112
1113 */
1114 static void
1115 DEFUN(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;
1129
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 {
1138
1139 /* Modify the symbol values according to their section and
1140 type */
1141
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 }
1153
1154
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.
1158
1159 */
1160 static void
1161 DEFUN(coff_mangle_symbols,(bfd_ptr),
1162 bfd *bfd_ptr)
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
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 */
1216 native_index++;
1217 }
1218 else {
1219 struct internal_syment *syment = coff_symbol_ptr->native;
1220 if (syment == (struct internal_syment *)NULL) {
1221 native_index++;
1222 }
1223 else {
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;
1229 }
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
1260 #ifdef C_LEAFEXT
1261 || syment->n_sclass == C_LEAFEXT
1262 || syment->n_sclass == C_LEAFSTAT
1263 #endif
1264 )
1265 && last_fcn != (struct internal_syment *)NULL)
1266 {
1267 union internal_auxent *auxent = (union internal_auxent *)(last_fcn+1);
1268 auxent->x_sym.x_fcnary.x_fcn.x_endndx.l = native_index;
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 */
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;
1281 /* Now point the eos to the structure */
1282 auxent = (union internal_auxent *)(syment+1);
1283 auxent->x_sym.x_tagndx.l = last_tagndx->_n._n_n._n_offset;
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);
1289 auxent->x_sym.x_fcnary.x_fcn.x_endndx.l = native_index + syment->n_numaux + 1;
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);
1342 /* auxent->x_sym.x_tagndx = base[auxent->x_sym.x_tagndx]._n._n_n._n_offset;*/
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
1364 #endif
1365 static int string_size;
1366 static void
1367 DEFUN(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;
1374 CONST 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
1420 static unsigned int
1421 DEFUN(coff_write_symbol,(abfd, symbol, native, written),
1422 bfd *abfd AND
1423 asymbol *symbol AND
1424 combined_entry_type *native AND
1425 unsigned 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
1451 static unsigned int
1452 DEFUN(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
1515 static unsigned int
1516 DEFUN(coff_write_native_symbol,(abfd, symbol, written),
1517 bfd *abfd AND
1518 coff_symbol_type *symbol AND
1519 unsigned 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
1556 static void
1557 DEFUN(coff_write_symbols,(abfd),
1558 bfd *abfd)
1559 {
1560 unsigned int i;
1561 unsigned int limit = bfd_get_symcount(abfd);
1562 unsigned int written = 0;
1563
1564 asymbol **p;
1565
1566 string_size = 0;
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;
1575 for (p = abfd->outsymbols, i = 0; i < limit; i++, p++)
1576 {
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);
1586 }
1587 else
1588 {
1589 written = coff_write_native_symbol(abfd, c_symbol, written);
1590 }
1591
1592 }
1593
1594 bfd_get_symcount(abfd) = written;
1595
1596 /* Now write out strings */
1597
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 }
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 }
1628 }
1629 /*doc*
1630 @subsubsection Writing Relocations
1631 To write a relocations, all the back end does is step though the
1632 canonical relocation table, and create an @code{internal_reloc}. The
1633 symbol index to use is removed from the @code{offset} field in the
1634 symbol table supplied, the address comes directly from the sum of the
1635 section base address and the relocation offset and the type is dug
1636 directly from the howto field.
1637
1638 Then the @code{internal_reloc} is swapped into the shape of an
1639 @code{external_reloc} and written out to disk.
1640 */
1641
1642 static void
1643 DEFUN(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;
1650
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 }
1661 #ifdef SELECT_RELOC
1662 /* Work out reloc type from what is required */
1663 SELECT_RELOC(n.r_type, q->howto);
1664 #else
1665 n.r_type = q->howto->type;
1666 #endif
1667 bfd_swap_reloc_out(abfd, &n, &dst);
1668 bfd_write((PTR) &n, 1, RELSZ, abfd);
1669 }
1670 }
1671 }
1672
1673 static void
1674 DEFUN(coff_write_linenumbers,(abfd),
1675 bfd *abfd)
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;
1698 out.l_addr.l_symndx = l->u.offset;
1699 coff_swap_lineno_out(abfd, &out, &buff);
1700 bfd_write((PTR) &buff, 1, LINESZ, abfd);
1701 l++;
1702 }
1703 }
1704 q++;
1705 }
1706 }
1707 }
1708 }
1709
1710
1711 static asymbol *
1712 coff_make_empty_symbol(abfd)
1713 bfd *abfd;
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 }
1725
1726 static void
1727 DEFUN(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);
1746
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 }
1753
1754
1755 break;
1756 }
1757 }
1758
1759 static alent *
1760 DEFUN(coff_get_lineno,(ignore_abfd, symbol),
1761 bfd *ignore_abfd AND
1762 asymbol *symbol)
1763 {
1764 return coffsymbol(symbol)->lineno;
1765 }
1766
1767 /*
1768 Set flags and magic number of a coff file from architecture and machine
1769 type. Result is true if we can represent the arch&type, false if not.
1770 */
1771 static boolean
1772 DEFUN(coff_set_flags,(abfd, magicp, flagsp),
1773 bfd *abfd AND
1774 unsigned *magicp AND
1775 unsigned short *flagsp)
1776 {
1777
1778 switch (abfd->obj_arch) {
1779
1780 #ifdef I960ROMAGIC
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;
1812 }
1813 *flagsp = flags;
1814 return true;
1815 }
1816 break;
1817 #endif
1818 #ifdef MIPS
1819 case bfd_arch_mips:
1820 *magicp = MIPS_MAGIC_2;
1821 return true;
1822 break;
1823 #endif
1824 #ifdef I386MAGIC
1825 case bfd_arch_i386:
1826 *magicp = I386MAGIC;
1827 return true;
1828 #endif
1829 #ifdef MC68MAGIC
1830 case bfd_arch_m68k:
1831 *magicp = MC68MAGIC;
1832 return true;
1833 #endif
1834
1835 #ifdef MC88MAGIC
1836 case bfd_arch_m88k:
1837 *magicp = MC88OMAGIC;
1838 return true;
1839 break;
1840 #endif
1841
1842 default: /* Unknown architecture */
1843 return false;
1844 }
1845
1846 return false;
1847 }
1848
1849
1850 static boolean
1851 DEFUN(coff_set_arch_mach,(abfd, arch, machine),
1852 bfd *abfd AND
1853 enum bfd_architecture arch AND
1854 unsigned long machine)
1855 {
1856 unsigned dummy1;
1857 unsigned short dummy2;
1858 abfd->obj_arch = arch;
1859 abfd->obj_machine = machine;
1860 if (arch != bfd_arch_unknown &&
1861 coff_set_flags(abfd, &dummy1, &dummy2) != true)
1862 return false; /* We can't represent this type */
1863 return true; /* We're easy ... */
1864 }
1865
1866
1867 /* Calculate the file position for each section. */
1868
1869 static void
1870 DEFUN(coff_compute_section_file_positions,(abfd),
1871 bfd *abfd)
1872 {
1873 asection *current;
1874 file_ptr sofar = FILHSZ;
1875 if (bfd_get_start_address(abfd)) {
1876 /*
1877 A start address may have been added to the original file. In this
1878 case it will need an optional header to record it.
1879 */
1880 abfd->flags |= EXEC_P;
1881 }
1882 if (abfd->flags & EXEC_P)
1883 sofar += AOUTSZ;
1884
1885
1886 sofar += abfd->section_count * SCNHSZ;
1887 for (current = abfd->sections;
1888 current != (asection *)NULL;
1889 current = current->next) {
1890 /* Only deal with sections which have contents */
1891 if (!(current->flags & SEC_HAS_CONTENTS))
1892 continue;
1893
1894 /* Align the sections in the file to the same boundary on
1895 which they are aligned in virtual memory. I960 doesn't
1896 do this (FIXME) so we can stay in sync with Intel. 960
1897 doesn't yet page from files... */
1898 #ifndef I960
1899 sofar = ALIGN(sofar, 1 << current->alignment_power);
1900 #endif
1901 /* FIXME, in demand paged files, the low order bits of the file
1902 offset must match the low order bits of the virtual address.
1903 "Low order" is apparently implementation defined. Add code
1904 here to round sofar up to match the virtual address. */
1905
1906 current->filepos = sofar;
1907 sofar += current->size;
1908 }
1909 obj_relocbase(abfd) = sofar;
1910 }
1911
1912
1913
1914
1915 /* SUPPRESS 558 */
1916 /* SUPPRESS 529 */
1917 static boolean
1918 DEFUN(coff_write_object_contents,(abfd),
1919 bfd *abfd)
1920 {
1921 asection *current;
1922 boolean hasrelocs = false;
1923 boolean haslinno = false;
1924 file_ptr reloc_base;
1925 file_ptr lineno_base;
1926 file_ptr sym_base;
1927 file_ptr scn_base;
1928 file_ptr data_base;
1929 unsigned long reloc_size = 0;
1930 unsigned long lnno_size = 0;
1931 asection *text_sec = NULL;
1932 asection *data_sec = NULL;
1933 asection *bss_sec = NULL;
1934
1935 struct internal_filehdr internal_f;
1936 struct internal_aouthdr internal_a;
1937
1938 struct icofdata *coff = obj_icof(abfd);
1939
1940
1941 bfd_error = system_call_error;
1942
1943
1944 if(abfd->output_has_begun == false) {
1945 coff_compute_section_file_positions(abfd);
1946 }
1947
1948 if (abfd->sections != (asection *)NULL) {
1949 scn_base = abfd->sections->filepos;
1950 }
1951 else {
1952 scn_base = 0;
1953 }
1954 if (bfd_seek(abfd, scn_base, SEEK_SET) != 0)
1955 return false;
1956 reloc_base = obj_relocbase(abfd);
1957
1958 /* Make a pass through the symbol table to count line number entries and
1959 put them into the correct asections */
1960
1961 coff_count_linenumbers(abfd);
1962 data_base = scn_base;
1963
1964 /* Work out the size of the reloc and linno areas */
1965
1966 for (current = abfd->sections; current != NULL; current = current->next) {
1967 reloc_size += current->reloc_count * RELSZ;
1968 lnno_size += current->lineno_count * LINESZ;
1969 data_base += SCNHSZ;
1970 }
1971
1972 lineno_base = reloc_base + reloc_size;
1973 sym_base = lineno_base + lnno_size;
1974
1975 /* Indicate in each section->line_filepos its actual file address */
1976 for (current = abfd->sections; current != NULL; current = current->next) {
1977 if (current->lineno_count) {
1978 current->line_filepos = lineno_base;
1979 current->moving_line_filepos = lineno_base;
1980 lineno_base += current->lineno_count * LINESZ;
1981 }
1982 else {
1983 current->line_filepos = 0;
1984 }
1985 if (current->reloc_count) {
1986 current->rel_filepos = reloc_base;
1987 reloc_base += current->reloc_count * sizeof(struct internal_reloc);
1988 }
1989 else {
1990 current->rel_filepos = 0;
1991 }
1992 }
1993
1994 /* Write section headers to the file. */
1995
1996 bfd_seek(abfd,
1997 (file_ptr) ((abfd->flags & EXEC_P) ?
1998 (FILHSZ + AOUTSZ) : FILHSZ),
1999 SEEK_SET);
2000
2001 {
2002 #if 0
2003 unsigned int pad = abfd->flags & D_PAGED ? data_base : 0;
2004 #endif
2005 unsigned int pad = 0;
2006
2007 for (current = abfd->sections; current != NULL; current = current->next) {
2008 struct internal_scnhdr section;
2009 strncpy(&(section.s_name[0]), current->name, 8);
2010 section.s_vaddr = current->vma + pad;
2011 section.s_paddr = current->vma + pad;
2012 section.s_size = current->size - pad;
2013 /*
2014 If this section has no size or is unloadable then the scnptr
2015 will be 0 too
2016 */
2017 if (current->size - pad == 0 ||
2018 (current->flags & SEC_LOAD) == 0) {
2019 section.s_scnptr = 0;
2020
2021 }
2022 else {
2023 section.s_scnptr = current->filepos;
2024 }
2025 section.s_relptr = current->rel_filepos;
2026 section.s_lnnoptr = current->line_filepos;
2027 section.s_nreloc = current->reloc_count;
2028 section.s_nlnno = current->lineno_count;
2029 if (current->reloc_count != 0)
2030 hasrelocs = true;
2031 if (current->lineno_count != 0)
2032 haslinno = true;
2033
2034 if (!strcmp(current->name, _TEXT)) {
2035 text_sec = current;
2036 section.s_flags = STYP_TEXT; /* kinda stupid */
2037 }
2038 else if (!strcmp(current->name, _DATA)) {
2039 data_sec = current;
2040 section.s_flags = STYP_DATA; /* kinda stupid */
2041 }
2042 else if (!strcmp(current->name, _BSS)) {
2043 bss_sec = current;
2044 section.s_flags = STYP_BSS; /* kinda stupid */
2045 }
2046
2047
2048 #ifdef I960
2049 section.s_align = (current->alignment_power
2050 ? 1 << current->alignment_power
2051 : 0);
2052
2053 #endif
2054 {
2055 SCNHDR buff;
2056
2057 swap_scnhdr_out(abfd, &section, &buff);
2058 bfd_write((PTR) (&buff), 1, SCNHSZ, abfd);
2059
2060 }
2061 pad = 0;
2062 }
2063 }
2064
2065 /* OK, now set up the filehdr... */
2066 internal_f.f_nscns = abfd->section_count;
2067 /*
2068 We will NOT put a fucking timestamp in the header here. Every time you
2069 put it back, I will come in and take it out again. I'm sorry. This
2070 field does not belong here. We fill it with a 0 so it compares the
2071 same but is not a reasonable time. -- gnu@cygnus.com
2072 */
2073 /*
2074 Well, I like it, so I'm conditionally compiling it in.
2075 steve@cygnus.com
2076 */
2077 #ifdef COFF_TIMESTAMP
2078 internal_f.f_timdat = time(0);
2079 #else
2080 internal_f.f_timdat = 0;
2081 #endif
2082
2083 if (bfd_get_symcount(abfd) != 0)
2084 internal_f.f_symptr = sym_base;
2085 else
2086 internal_f.f_symptr = 0;
2087
2088 internal_f.f_flags = 0;
2089
2090 if (abfd->flags & EXEC_P)
2091 internal_f.f_opthdr = AOUTSZ;
2092 else
2093 internal_f.f_opthdr = 0;
2094
2095 if (!hasrelocs)
2096 internal_f.f_flags |= F_RELFLG;
2097 if (!haslinno)
2098 internal_f.f_flags |= F_LNNO;
2099 if (0 == bfd_get_symcount(abfd))
2100 internal_f.f_flags |= F_LSYMS;
2101 if (abfd->flags & EXEC_P)
2102 internal_f.f_flags |= F_EXEC;
2103 #if M88
2104 internal_f.f_flags |= F_AR32W;
2105 #else
2106 if (!abfd->xvec->byteorder_big_p)
2107 internal_f.f_flags |= F_AR32WR;
2108 #endif
2109 /*
2110 FIXME, should do something about the other byte orders and
2111 architectures.
2112 */
2113
2114 /* Set up architecture-dependent stuff */
2115
2116 { int magic = 0;
2117 int flags = 0;
2118 coff_set_flags(abfd, &magic, &internal_f.f_flags);
2119 internal_f.f_magic = magic;
2120 /* ...and the "opt"hdr... */
2121
2122 #ifdef I960
2123 internal_a.magic = (magic == I960ROMAGIC ? NMAGIC : OMAGIC);
2124 #endif
2125 #if M88
2126 internal_a.magic = PAGEMAGICBCS;
2127 #endif
2128 }
2129 /* Now should write relocs, strings, syms */
2130 obj_sym_filepos(abfd) = sym_base;
2131
2132 if (bfd_get_symcount(abfd) != 0) {
2133 coff_renumber_symbols(abfd);
2134 coff_mangle_symbols(abfd);
2135 coff_write_symbols(abfd);
2136 coff_write_linenumbers(abfd);
2137 coff_write_relocs(abfd);
2138 }
2139 if (text_sec) {
2140 internal_a.tsize = text_sec->size;
2141 internal_a.text_start =text_sec->size ? text_sec->vma : 0;
2142 }
2143 if (data_sec) {
2144 internal_a.dsize = data_sec->size;
2145 internal_a.data_start = data_sec->size ? data_sec->vma : 0;
2146 }
2147 if (bss_sec) {
2148 internal_a.bsize = bss_sec->size;
2149 }
2150
2151 internal_a.entry = bfd_get_start_address(abfd);
2152 internal_f.f_nsyms = bfd_get_symcount(abfd);
2153
2154 /* now write them */
2155 if (bfd_seek(abfd, 0L, SEEK_SET) != 0)
2156 return false;
2157 {
2158 FILHDR buff;
2159 bfd_swap_filehdr_out(abfd, &internal_f, &buff);
2160 bfd_write((PTR) &buff, 1, FILHSZ, abfd);
2161 }
2162 if (abfd->flags & EXEC_P) {
2163 AOUTHDR buff;
2164 bfd_swap_aouthdr_out(abfd, &internal_a, &buff);
2165 bfd_write((PTR) &buff, 1, AOUTSZ, abfd);
2166 }
2167 return true;
2168 }
2169
2170 /*
2171 this function transforms the offsets into the symbol table into
2172 pointers to syments.
2173 */
2174
2175
2176 static void
2177 DEFUN(coff_pointerize_aux,(abfd, table_base, type, class, auxent),
2178 bfd *abfd AND
2179 combined_entry_type *table_base AND
2180 int type AND
2181 int class AND
2182 combined_entry_type *auxent)
2183 {
2184 /* Don't bother if this is a file or a section */
2185 if (class == C_STAT && type == T_NULL) return;
2186 if (class == C_FILE) return;
2187
2188 /* Otherwise patch up */
2189 if (ISFCN(type) || ISTAG(class) || class == C_BLOCK) {
2190 auxent->u.auxent.x_sym.x_fcnary.x_fcn.x_endndx.p = table_base +
2191 auxent->u.auxent.x_sym.x_fcnary.x_fcn.x_endndx.l;
2192 auxent->fix_end = 1;
2193 }
2194 if (auxent->u.auxent.x_sym.x_tagndx.l != 0) {
2195 auxent->u.auxent.x_sym.x_tagndx.p = table_base + auxent->u.auxent.x_sym.x_tagndx.l;
2196 auxent->fix_tag = 1;
2197 }
2198
2199
2200
2201 }
2202
2203 static boolean
2204 DEFUN(coff_set_section_contents,(abfd, section, location, offset, count),
2205 bfd *abfd AND
2206 sec_ptr section AND
2207 PTR location AND
2208 file_ptr offset AND
2209 size_t count)
2210 {
2211 if (abfd->output_has_begun == false) /* set by bfd.c handler */
2212 coff_compute_section_file_positions(abfd);
2213
2214 bfd_seek(abfd, (file_ptr) (section->filepos + offset), SEEK_SET);
2215
2216 if (count != 0) {
2217 return (bfd_write(location, 1, count, abfd) == count) ? true : false;
2218 }
2219 return true;
2220 }
2221 #if 0
2222 static boolean
2223 coff_close_and_cleanup(abfd)
2224 bfd *abfd;
2225 {
2226 if (!bfd_read_p(abfd))
2227 switch (abfd->format) {
2228 case bfd_archive:
2229 if (!_bfd_write_archive_contents(abfd))
2230 return false;
2231 break;
2232 case bfd_object:
2233 if (!coff_write_object_contents(abfd))
2234 return false;
2235 break;
2236 default:
2237 bfd_error = invalid_operation;
2238 return false;
2239 }
2240
2241 /* We depend on bfd_close to free all the memory on the obstack. */
2242 /* FIXME if bfd_release is not using obstacks! */
2243 return true;
2244 }
2245
2246 #endif
2247 static PTR
2248 buy_and_read(abfd, where, seek_direction, size)
2249 bfd *abfd;
2250 file_ptr where;
2251 int seek_direction;
2252 size_t size;
2253 {
2254 PTR area = (PTR) bfd_alloc(abfd, size);
2255 if (!area) {
2256 bfd_error = no_memory;
2257 return (NULL);
2258 }
2259 bfd_seek(abfd, where, seek_direction);
2260 if (bfd_read(area, 1, size, abfd) != size) {
2261 bfd_error = system_call_error;
2262 return (NULL);
2263 } /* on error */
2264 return (area);
2265 } /* buy_and_read() */
2266
2267
2268
2269 static char *
2270 DEFUN(build_string_table,(abfd),
2271 bfd *abfd)
2272 {
2273 char string_table_size_buffer[4];
2274 unsigned int string_table_size;
2275 char *string_table;
2276 /*
2277 At this point we should be "seek"'d to the end of the
2278 symbols === the symbol table size.
2279 */
2280
2281 if (bfd_read((char *) string_table_size_buffer,
2282 sizeof(string_table_size_buffer),
2283 1, abfd) != sizeof(string_table_size)) {
2284 bfd_error = system_call_error;
2285 return (NULL);
2286 } /* on error */
2287
2288 string_table_size = bfd_h_get_32(abfd, string_table_size_buffer);
2289
2290 if ((string_table = (PTR) bfd_alloc(abfd, string_table_size -= 4)) == NULL) {
2291 bfd_error = no_memory;
2292 return (NULL);
2293 } /* on mallocation error */
2294 if (bfd_read(string_table, string_table_size, 1, abfd) != string_table_size) {
2295 bfd_error = system_call_error;
2296 return (NULL);
2297 }
2298 return string_table;
2299 }
2300
2301 /*
2302 read a symbol table into freshly mallocated memory, swap it, and knit the
2303 symbol names into a normalized form. By normalized here I mean that all
2304 symbols have an n_offset pointer that points to a NULL terminated string.
2305 Oh, and the first symbol MUST be a C_FILE. If there wasn't one there
2306 before, put one there.
2307 */
2308
2309 static combined_entry_type *
2310 DEFUN(get_normalized_symtab,(abfd),
2311 bfd *abfd)
2312 {
2313
2314 combined_entry_type *internal;
2315 combined_entry_type *internal_ptr;
2316 combined_entry_type *internal_end;
2317 SYMENT *raw;
2318 SYMENT *raw_src;
2319 SYMENT *raw_end;
2320 char *string_table = NULL;
2321 unsigned long size;
2322
2323 unsigned long string_table_size = 0;
2324 unsigned int raw_size;
2325 if (obj_raw_syments(abfd) != (combined_entry_type *)NULL) {
2326 return obj_raw_syments(abfd);
2327 }
2328 if ((size = bfd_get_symcount(abfd) * sizeof(combined_entry_type)) == 0) {
2329 bfd_error = no_symbols;
2330 return (NULL);
2331 }
2332
2333 internal = (combined_entry_type *)bfd_alloc(abfd, size);
2334 internal_end = internal + bfd_get_symcount(abfd);
2335
2336 raw_size = bfd_get_symcount(abfd) * SYMESZ;
2337 raw = (SYMENT *)bfd_alloc(abfd,raw_size);
2338
2339 if (bfd_seek(abfd, obj_sym_filepos(abfd), SEEK_SET) == -1
2340 || bfd_read((PTR)raw, raw_size, 1, abfd) != raw_size) {
2341 bfd_error = system_call_error;
2342 return (NULL);
2343 }
2344 /* mark the end of the symbols */
2345 raw_end = raw + bfd_get_symcount(abfd);
2346 /*
2347 FIXME SOMEDAY. A string table size of zero is very weird, but
2348 probably possible. If one shows up, it will probably kill us.
2349 */
2350
2351 /* Swap all the raw entries */
2352 for (raw_src = raw, internal_ptr = internal; raw_src < raw_end; raw_src++, internal_ptr++) {
2353 unsigned int i;
2354 coff_swap_sym_in(abfd, raw_src,&internal_ptr->u.syment);
2355 internal_ptr->fix_tag = 0;
2356 internal_ptr->fix_end = 0;
2357
2358 for (i = internal_ptr->u.syment.n_numaux; i; --i, raw_src++, internal_ptr++) {
2359 (internal_ptr+1)->fix_tag = 0;
2360 (internal_ptr+1)->fix_end = 0;
2361
2362 coff_swap_aux_in(abfd, (AUXENT *)(raw_src +1), internal_ptr->u.syment.n_type,
2363 internal_ptr->u.syment.n_sclass, & (internal_ptr+1)->u.auxent);
2364
2365 coff_pointerize_aux(abfd,
2366 internal,
2367 internal_ptr->u.syment.n_type,
2368 internal_ptr->u.syment.n_sclass,
2369 internal_ptr +1);
2370 }
2371 }
2372
2373 /* Free all the raw stuff */
2374 bfd_release(abfd, raw_src);
2375
2376 for (internal_ptr = internal; internal_ptr < internal_end;
2377 internal_ptr ++)
2378 {
2379 if (internal_ptr->u.syment.n_sclass == C_FILE) {
2380 /* make a file symbol point to the name in the auxent, since
2381 the text ".file" is redundant */
2382 if ((internal_ptr+1)->u.auxent.x_file.x_n.x_zeroes == 0) {
2383 /* the filename is a long one, point into the string table
2384 */
2385 if (string_table == NULL) {
2386 string_table = build_string_table(abfd);
2387 }
2388
2389 internal_ptr->u.syment._n._n_n._n_offset =
2390 (int) (string_table - 4 +
2391 (internal_ptr+1)->u.auxent.x_file.x_n.x_offset);
2392 }
2393 else {
2394 /* ordinary short filename, put into memory anyway */
2395 internal_ptr->u.syment._n._n_n._n_offset = (int)
2396 copy_name(abfd, (internal_ptr+1)->u.auxent.x_file.x_fname, FILNMLEN);
2397
2398 }
2399 }
2400 else {
2401 if (internal_ptr->u.syment._n._n_n._n_zeroes != 0) {
2402 /*
2403 This is a "short" name. Make it long.
2404 */
2405 unsigned long i = 0;
2406 char *newstring = NULL;
2407 /*
2408 find the length of this string without walking into memory
2409 that isn't ours.
2410 */
2411
2412 for (i = 0; i < 8; ++i) {
2413 if (internal_ptr->u.syment._n._n_name[i] == '\0') {
2414 break;
2415 } /* if end of string */
2416 } /* possible lengths of this string. */
2417
2418 if ((newstring = (PTR) bfd_alloc(abfd, ++i)) == NULL) {
2419 bfd_error = no_memory;
2420 return (NULL);
2421 } /* on error */
2422 bzero(newstring, i);
2423 strncpy(newstring, internal_ptr->u.syment._n._n_name, i-1);
2424 internal_ptr->u.syment._n._n_n._n_offset = (int) newstring;
2425 internal_ptr->u.syment._n._n_n._n_zeroes = 0;
2426
2427 }
2428 else {
2429 /* This is a long name already. Just point it at the string in memory. */
2430 if (string_table == NULL) {
2431 string_table = build_string_table(abfd);
2432 }
2433 internal_ptr->u.syment._n._n_n._n_offset =
2434 (int) (string_table - 4 + internal_ptr->u.syment._n._n_n._n_offset);
2435 }
2436 }
2437 internal_ptr += internal_ptr->u.syment.n_numaux;
2438 }
2439
2440 obj_raw_syments(abfd) = internal;
2441 obj_string_table(abfd) = string_table;
2442
2443 return (internal);
2444 } /* get_normalized_symtab() */
2445
2446 static
2447 struct sec *
2448 DEFUN(section_from_bfd_index,(abfd, index),
2449 bfd *abfd AND
2450 int index)
2451 {
2452 if (index > 0) {
2453 struct sec *answer = abfd->sections;
2454 while (--index) {
2455 answer = answer->next;
2456 }
2457 return answer;
2458 }
2459 return 0;
2460 }
2461
2462
2463
2464 /*doc*
2465 @subsubsection Reading Linenumbers
2466 Createing the linenumber table is done by reading in the entire coff
2467 linenumber table, and creating another table for internal use.
2468
2469 A coff line number table is structured so that each
2470 function is marked as having a line number of 0. Each line within the
2471 function is an offset from the first line in the function. The base of
2472 the line number information for the table is stored in the symbol
2473 associated with the function.
2474
2475 The information is copied from the external to the internal table, and
2476 each symbol which marks a function is marked by pointing its...
2477
2478 **How does this work ?**
2479
2480 */
2481
2482 static boolean
2483 coff_slurp_line_table(abfd, asect)
2484 bfd *abfd;
2485 asection *asect;
2486 {
2487 LINENO *native_lineno;
2488 alent *lineno_cache;
2489
2490 BFD_ASSERT(asect->lineno == (alent *) NULL);
2491
2492 native_lineno = (LINENO *) buy_and_read(abfd,
2493 asect->line_filepos,
2494 SEEK_SET,
2495 (size_t) (LINESZ *
2496 asect->lineno_count));
2497 lineno_cache =
2498 (alent *) bfd_alloc(abfd, (size_t) ((asect->lineno_count + 1) * sizeof(alent)));
2499 if (lineno_cache == NULL) {
2500 bfd_error = no_memory;
2501 return false;
2502 } else {
2503 unsigned int counter = 0;
2504 alent *cache_ptr = lineno_cache;
2505 LINENO *src = native_lineno;
2506
2507 while (counter < asect->lineno_count) {
2508 struct internal_lineno dst;
2509 coff_swap_lineno_in(abfd, src, &dst);
2510 cache_ptr->line_number = dst.l_lnno;
2511
2512 if (cache_ptr->line_number == 0) {
2513 coff_symbol_type *sym =
2514 (coff_symbol_type *) (dst.l_addr.l_symndx
2515 + obj_symbol_slew(abfd)
2516 + obj_raw_syments(abfd))->u.syment._n._n_n._n_zeroes;
2517 cache_ptr->u.sym = (asymbol *) sym;
2518 sym->lineno = cache_ptr;
2519 }
2520 else {
2521 cache_ptr->u.offset = dst.l_addr.l_paddr
2522 - bfd_section_vma(abfd, asect);
2523 } /* If no linenumber expect a symbol index */
2524
2525 cache_ptr++;
2526 src++;
2527 counter++;
2528 }
2529 cache_ptr->line_number = 0;
2530
2531 }
2532 asect->lineno = lineno_cache;
2533 /* FIXME, free native_lineno here, or use alloca or something. */
2534 return true;
2535 } /* coff_slurp_line_table() */
2536
2537 static boolean
2538 DEFUN(coff_slurp_symbol_table,(abfd),
2539 bfd *abfd)
2540 {
2541 combined_entry_type *native_symbols;
2542 coff_symbol_type *cached_area;
2543 unsigned int *table_ptr;
2544
2545 unsigned int number_of_symbols = 0;
2546 if (obj_symbols(abfd))
2547 return true;
2548 bfd_seek(abfd, obj_sym_filepos(abfd), SEEK_SET);
2549
2550 /* Read in the symbol table */
2551 if ((native_symbols = get_normalized_symtab(abfd)) == NULL) {
2552 return (false);
2553 } /* on error */
2554
2555
2556 /* Allocate enough room for all the symbols in cached form */
2557 cached_area =
2558 (coff_symbol_type *)
2559 bfd_alloc(abfd, (size_t) (bfd_get_symcount(abfd) * sizeof(coff_symbol_type)));
2560
2561 if (cached_area == NULL) {
2562 bfd_error = no_memory;
2563 return false;
2564 } /* on error */
2565 table_ptr =
2566 (unsigned int *)
2567 bfd_alloc(abfd, (size_t) (bfd_get_symcount(abfd) * sizeof(unsigned int)));
2568
2569 if (table_ptr == NULL) {
2570 bfd_error = no_memory;
2571 return false;
2572 } else {
2573 coff_symbol_type *dst = cached_area;
2574 unsigned int last_native_index = bfd_get_symcount(abfd);
2575 unsigned int this_index = 0;
2576 while (this_index < last_native_index) {
2577 combined_entry_type *src = native_symbols + this_index;
2578 table_ptr[this_index] = number_of_symbols;
2579 dst->symbol.the_bfd = abfd;
2580
2581 dst->symbol.name = (char *)(src->u.syment._n._n_n._n_offset);
2582 /*
2583 We use the native name field to point to the cached field
2584 */
2585 src->u.syment._n._n_n._n_zeroes = (int) dst;
2586 dst->symbol.section = section_from_bfd_index(abfd,
2587 src->u.syment.n_scnum);
2588 switch (src->u.syment.n_sclass) {
2589 #ifdef I960
2590 case C_LEAFEXT:
2591 #if 0
2592 dst->symbol.value = src->u.syment.n_value - dst->symbol.section->vma;
2593 dst->symbol.flags = BSF_EXPORT | BSF_GLOBAL;
2594 dst->symbol.flags |= BSF_NOT_AT_END;
2595 #endif
2596 /* Fall through to next case */
2597
2598 #endif
2599
2600 case C_EXT:
2601 if ((src->u.syment.n_scnum) == 0) {
2602 if ((src->u.syment.n_value) == 0) {
2603 dst->symbol.flags = BSF_UNDEFINED;
2604 dst->symbol.value= 0;
2605 }
2606 else {
2607 dst->symbol.flags = BSF_FORT_COMM;
2608 dst->symbol.value = (src->u.syment.n_value);
2609 }
2610 }
2611 else {
2612 /*
2613 Base the value as an index from the base of the
2614 section
2615 */
2616 if (dst->symbol.section == (asection *) NULL) {
2617 dst->symbol.flags = BSF_EXPORT | BSF_GLOBAL | BSF_ABSOLUTE;
2618 dst->symbol.value = src->u.syment.n_value;
2619 }
2620 else {
2621 dst->symbol.flags = BSF_EXPORT | BSF_GLOBAL;
2622 dst->symbol.value = src->u.syment.n_value - dst->symbol.section->vma;
2623 }
2624 if (ISFCN((src->u.syment.n_type))) {
2625 /*
2626 A function ext does not go at the end of a file
2627 */
2628 dst->symbol.flags |= BSF_NOT_AT_END;
2629 }
2630 }
2631
2632 break;
2633 case C_STAT: /* static */
2634 #ifdef I960
2635 case C_LEAFSTAT: /* static leaf procedure */
2636 #endif
2637 case C_LABEL: /* label */
2638 dst->symbol.flags = BSF_LOCAL;
2639 /*
2640 Base the value as an index from the base of the section
2641 */
2642 dst->symbol.value = (src->u.syment.n_value) - dst->symbol.section->vma;
2643 break;
2644
2645 case C_MOS: /* member of structure */
2646 case C_EOS: /* end of structure */
2647 case C_REGPARM: /* register parameter */
2648 case C_REG: /* register variable */
2649 #ifdef C_AUTOARG
2650 case C_AUTOARG: /* 960-specific storage class */
2651 #endif
2652 case C_TPDEF: /* type definition */
2653
2654 case C_ARG:
2655 case C_AUTO: /* automatic variable */
2656 case C_FIELD: /* bit field */
2657 case C_ENTAG: /* enumeration tag */
2658 case C_MOE: /* member of enumeration */
2659 case C_MOU: /* member of union */
2660 case C_UNTAG: /* union tag */
2661
2662 dst->symbol.flags = BSF_DEBUGGING;
2663 dst->symbol.value = (src->u.syment.n_value);
2664 break;
2665
2666 case C_FILE: /* file name */
2667 case C_STRTAG: /* structure tag */
2668 dst->symbol.flags = BSF_DEBUGGING;
2669 dst->symbol.value = (src->u.syment.n_value);
2670
2671 break;
2672 case C_BLOCK: /* ".bb" or ".eb" */
2673 case C_FCN: /* ".bf" or ".ef" */
2674 dst->symbol.flags = BSF_LOCAL;
2675 /*
2676 Base the value as an index from the base of the section
2677 */
2678 dst->symbol.value = (src->u.syment.n_value) - dst->symbol.section->vma;
2679
2680 break;
2681 case C_EFCN: /* physical end of function */
2682 case C_NULL:
2683 case C_EXTDEF: /* external definition */
2684 case C_ULABEL: /* undefined label */
2685 case C_USTATIC: /* undefined static */
2686 case C_LINE: /* line # reformatted as symbol table entry */
2687 case C_ALIAS: /* duplicate tag */
2688 case C_HIDDEN: /* ext symbol in dmert public lib */
2689
2690 default:
2691
2692 abort();
2693 dst->symbol.flags = BSF_DEBUGGING;
2694 dst->symbol.value = (src->u.syment.n_value);
2695
2696 break;
2697 }
2698
2699 BFD_ASSERT(dst->symbol.flags != 0);
2700
2701 dst->native = src;
2702
2703 dst->symbol.udata = 0;
2704 dst->lineno = (alent *) NULL;
2705 this_index += (src->u.syment.n_numaux) + 1;
2706 dst++;
2707 number_of_symbols++;
2708 } /* walk the native symtab */
2709 } /* bfdize the native symtab */
2710
2711 obj_symbols(abfd) = cached_area;
2712 obj_raw_syments(abfd) = native_symbols;
2713
2714 bfd_get_symcount(abfd) = number_of_symbols;
2715 obj_convert(abfd) = table_ptr;
2716 /* Slurp the line tables for each section too */
2717 {
2718 asection *p;
2719 p = abfd->sections;
2720 while (p) {
2721 coff_slurp_line_table(abfd, p);
2722 p = p->next;
2723 }
2724 }
2725 return true;
2726 } /* coff_slurp_symbol_table() */
2727
2728 static unsigned int
2729 coff_get_symtab_upper_bound(abfd)
2730 bfd *abfd;
2731 {
2732 if (!coff_slurp_symbol_table(abfd))
2733 return 0;
2734
2735 return (bfd_get_symcount(abfd) + 1) * (sizeof(coff_symbol_type *));
2736 }
2737
2738
2739 static unsigned int
2740 coff_get_symtab(abfd, alocation)
2741 bfd *abfd;
2742 asymbol **alocation;
2743 {
2744 unsigned int counter = 0;
2745 coff_symbol_type *symbase;
2746 coff_symbol_type **location = (coff_symbol_type **) (alocation);
2747 if (!coff_slurp_symbol_table(abfd))
2748 return 0;
2749
2750 for (symbase = obj_symbols(abfd); counter++ < bfd_get_symcount(abfd);)
2751 *(location++) = symbase++;
2752 *location++ = 0;
2753 return bfd_get_symcount(abfd);
2754 }
2755
2756 static unsigned int
2757 coff_get_reloc_upper_bound(abfd, asect)
2758 bfd *abfd;
2759 sec_ptr asect;
2760 {
2761 if (bfd_get_format(abfd) != bfd_object) {
2762 bfd_error = invalid_operation;
2763 return 0;
2764 }
2765 return (asect->reloc_count + 1) * sizeof(arelent *);
2766 }
2767
2768 /*doc*
2769 @subsubsection Reading Relocations
2770 Coff relocations are easily transformed into the internal bfd form
2771 (@code{arelent}).
2772
2773 Reading a coff relocation table is done in the following stages:
2774 @itemize @bullet
2775 @item
2776 The entire coff relocation table is read into memory.
2777 @item
2778 Each relocation is processed in turn, first it is swapped from the
2779 external to the internal form.
2780 @item
2781 The symbol referenced in the relocation's symbol index is turned into
2782 a pointer into the canonical symbol table. Note that this table is the
2783 same as the one returned by a call to @code{bfd_canonicalize_symtab}.
2784 The back end will call the routine and save the result if a
2785 canonicalization hasn't been done.
2786 @item
2787 The reloc index is turned into a pointer to a howto structure, in a
2788 back end specific way. For instance, the 386 and 960 use the
2789 @code{r_type} to directly produce an index into a howto table vector;
2790 the 88k subtracts a number from the @code{r_type} field and creates an
2791 addend field.
2792 @end itemize
2793 */
2794
2795 static boolean
2796 DEFUN(coff_slurp_reloc_table,(abfd, asect, symbols),
2797 bfd *abfd AND
2798 sec_ptr asect AND
2799 asymbol **symbols)
2800 {
2801 RELOC *native_relocs;
2802 arelent *reloc_cache;
2803 if (asect->relocation)
2804 return true;
2805 if (asect->reloc_count == 0)
2806 return true;
2807 if (!coff_slurp_symbol_table(abfd))
2808 return false;
2809 native_relocs =
2810 (RELOC *) buy_and_read(abfd,
2811 asect->rel_filepos,
2812 SEEK_SET,
2813 (size_t) (RELSZ *
2814 asect->reloc_count));
2815 reloc_cache = (arelent *)
2816 bfd_alloc(abfd, (size_t) (asect->reloc_count * sizeof(arelent)));
2817
2818 if (reloc_cache == NULL) {
2819 bfd_error = no_memory;
2820 return false;
2821 } { /* on error */
2822 arelent *cache_ptr;
2823 RELOC *src;
2824 for (cache_ptr = reloc_cache,
2825 src = native_relocs;
2826 cache_ptr < reloc_cache + asect->reloc_count;
2827 cache_ptr++,
2828 src++) {
2829 struct internal_reloc dst;
2830 asymbol *ptr;
2831 bfd_swap_reloc_in(abfd, src, &dst);
2832 dst.r_symndx += obj_symbol_slew(abfd);
2833 cache_ptr->sym_ptr_ptr = symbols + obj_convert(abfd)[dst.r_symndx];
2834
2835 ptr = *(cache_ptr->sym_ptr_ptr);
2836 cache_ptr->address = dst.r_vaddr;
2837 /*
2838 The symbols definitions that we have read in have been
2839 relocated as if their sections started at 0. But the offsets
2840 refering to the symbols in the raw data have not been
2841 modified, so we have to have a negative addend to compensate.
2842
2843 Note that symbols which used to be common must be left alone
2844 */
2845
2846 if (ptr->the_bfd == abfd
2847 && ptr->section != (asection *) NULL
2848 && ((ptr->flags & BSF_OLD_COMMON)== 0))
2849 {
2850 #ifndef M88
2851 cache_ptr->addend = -(ptr->section->vma + ptr->value);
2852 #else
2853 cache_ptr->addend = 0;
2854 #endif
2855
2856 }
2857 else {
2858 cache_ptr->addend = 0;
2859 }
2860
2861 cache_ptr->address -= asect->vma;
2862
2863 cache_ptr->section = (asection *) NULL;
2864
2865 #if I386
2866 cache_ptr->howto = howto_table + dst.r_type;
2867 #endif
2868 #if I960
2869 cache_ptr->howto = howto_table + dst.r_type;
2870 #endif
2871 #if M68
2872 cache_ptr->howto = howto_table + dst.r_type - R_RELBYTE;
2873 #endif
2874 #if M88
2875 if (dst.r_type >= R_PCR16L && dst.r_type <= R_VRT32) {
2876 cache_ptr->howto = howto_table + dst.r_type - R_PCR16L;
2877 cache_ptr->addend += dst.r_offset << 16;
2878 }
2879 else {
2880 BFD_ASSERT(0);
2881 }
2882 #endif
2883
2884 }
2885
2886 }
2887
2888 asect->relocation = reloc_cache;
2889 return true;
2890 }
2891
2892
2893 /* This is stupid. This function should be a boolean predicate */
2894 static unsigned int
2895 coff_canonicalize_reloc(abfd, section, relptr, symbols)
2896 bfd *abfd;
2897 sec_ptr section;
2898 arelent **relptr;
2899 asymbol **symbols;
2900 {
2901 arelent *tblptr = section->relocation;
2902 unsigned int count = 0;
2903 if (!(tblptr || coff_slurp_reloc_table(abfd, section, symbols)))
2904 return 0;
2905 tblptr = section->relocation;
2906 if (!tblptr)
2907 return 0;
2908
2909 for (; count++ < section->reloc_count;)
2910 *relptr++ = tblptr++;
2911
2912 *relptr = 0;
2913
2914 return section->reloc_count;
2915 }
2916
2917
2918 /*
2919 provided a bfd, a section and an offset into the section, calculate and
2920 return the name of the source file and the line nearest to the wanted
2921 location.
2922 */
2923
2924 static boolean
2925 DEFUN(coff_find_nearest_line,(abfd,
2926 section,
2927 symbols,
2928 offset,
2929 filename_ptr,
2930 functionname_ptr,
2931 line_ptr),
2932 bfd *abfd AND
2933 asection *section AND
2934 asymbol **symbols AND
2935 bfd_vma offset AND
2936 CONST char **filename_ptr AND
2937 CONST char **functionname_ptr AND
2938 unsigned int *line_ptr)
2939 {
2940 static bfd *cache_abfd;
2941 static asection *cache_section;
2942 static bfd_vma cache_offset;
2943 static unsigned int cache_i;
2944 static alent *cache_l;
2945
2946 unsigned int i = 0;
2947 struct icofdata *cof = obj_icof(abfd);
2948 /* Run through the raw syments if available */
2949 combined_entry_type *p;
2950 alent *l;
2951 unsigned int line_base = 0;
2952
2953
2954 *filename_ptr = 0;
2955 *functionname_ptr = 0;
2956 *line_ptr = 0;
2957
2958 /* Don't try and find line numbers in a non coff file */
2959 if (abfd->xvec->flavour != bfd_target_coff_flavour_enum)
2960 return false;
2961
2962 if (cof == (struct icofdata *)NULL)
2963 return false;
2964
2965 p = cof->raw_syments;
2966
2967 for (i = 0; i < cof->raw_syment_count; i++) {
2968 if (p->u.syment.n_sclass == C_FILE) {
2969 /* File name has been moved into symbol */
2970 *filename_ptr = (char *) p->u.syment._n._n_n._n_offset;
2971 break;
2972 }
2973 p += 1 + p->u.syment.n_numaux;
2974 }
2975 /* Now wander though the raw linenumbers of the section */
2976 /*
2977 If this is the same bfd as we were previously called with and this is
2978 the same section, and the offset we want is further down then we can
2979 prime the lookup loop
2980 */
2981 if (abfd == cache_abfd &&
2982 section == cache_section &&
2983 offset >= cache_offset) {
2984 i = cache_i;
2985 l = cache_l;
2986 }
2987 else {
2988 i = 0;
2989 l = section->lineno;
2990 }
2991
2992 for (; i < section->lineno_count; i++) {
2993 if (l->line_number == 0) {
2994 /* Get the symbol this line number points at */
2995 coff_symbol_type *coff = (coff_symbol_type *) (l->u.sym);
2996 *functionname_ptr = coff->symbol.name;
2997 if (coff->native) {
2998 combined_entry_type *s = coff->native;
2999 s = s + 1 + s->u.syment.n_numaux;
3000 /*
3001 S should now point to the .bf of the function
3002 */
3003 if (s->u.syment.n_numaux) {
3004 /*
3005 The linenumber is stored in the auxent
3006 */
3007 union internal_auxent *a = &((s + 1)->u.auxent);
3008 line_base = a->x_sym.x_misc.x_lnsz.x_lnno;
3009 }
3010 }
3011 }
3012 else {
3013 if (l->u.offset > offset)
3014 break;
3015 *line_ptr = l->line_number + line_base + 1;
3016 }
3017 l++;
3018 }
3019
3020 cache_abfd = abfd;
3021 cache_section = section;
3022 cache_offset = offset;
3023 cache_i = i;
3024 cache_l = l;
3025
3026 return true;
3027 }
3028
3029 #ifdef GNU960
3030 file_ptr
3031 coff_sym_filepos(abfd)
3032 bfd *abfd;
3033 {
3034 return obj_sym_filepos(abfd);
3035 }
3036 #endif
3037
3038
3039 static int
3040 DEFUN(coff_sizeof_headers,(abfd, reloc),
3041 bfd *abfd AND
3042 boolean reloc)
3043 {
3044 size_t size;
3045
3046 if (reloc == false) {
3047 size = FILHSZ + AOUTSZ;
3048 }
3049 else {
3050 size = FILHSZ;
3051 }
3052
3053 size += abfd->section_count * SCNHSZ;
3054 return size;
3055 }
3056
3057
3058 #define coff_core_file_failing_command _bfd_dummy_core_file_failing_command
3059 #define coff_core_file_failing_signal _bfd_dummy_core_file_failing_signal
3060 #define coff_core_file_matches_executable_p _bfd_dummy_core_file_matches_executable_p
3061 #define coff_slurp_armap bfd_slurp_coff_armap
3062 #define coff_slurp_extended_name_table _bfd_slurp_extended_name_table
3063 #define coff_truncate_arname bfd_dont_truncate_arname
3064 #define coff_openr_next_archived_file bfd_generic_openr_next_archived_file
3065 #define coff_generic_stat_arch_elt bfd_generic_stat_arch_elt
3066 #define coff_get_section_contents bfd_generic_get_section_contents
3067 #define coff_close_and_cleanup bfd_generic_close_and_cleanup
3068
3069 #define coff_bfd_debug_info_start bfd_void
3070 #define coff_bfd_debug_info_end bfd_void
3071 #define coff_bfd_debug_info_accumulate bfd_void
This page took 0.094181 seconds and 4 git commands to generate.