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