[time to file a PR on cvs...]
[deliverable/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 /* make sure that this section is of the right size too */
2208 old_sofar = sofar += current->_raw_size;
2209 sofar = BFD_ALIGN(sofar, 1 << current->alignment_power);
2210 current->_raw_size += sofar - old_sofar ;
2211
2212 previous = current;
2213 }
2214 obj_relocbase(abfd) = sofar;
2215 }
2216
2217 #ifndef NO_COFF_SYMBOLS
2218 static asymbol *
2219 coff_section_symbol (abfd, name)
2220 bfd *abfd;
2221 char *name;
2222 {
2223 asection *sec = bfd_get_section_by_name (abfd, name);
2224 asymbol *sym;
2225 combined_entry_type *csym;
2226
2227 if (!sec)
2228 {
2229 /* create empty symbol */
2230 abort ();
2231 }
2232 sym = sec->symbol;
2233 if (coff_symbol_from (abfd, sym))
2234 csym = coff_symbol_from (abfd, sym)->native;
2235 else
2236 csym = 0;
2237 /* Make sure back-end COFF stuff is there. */
2238 if (csym == 0)
2239 {
2240 struct foo {
2241 coff_symbol_type sym;
2242 /* @@FIXME This shouldn't use a fixed size!! */
2243 combined_entry_type e[10];
2244 };
2245 struct foo *f;
2246 f = (struct foo *) bfd_alloc_by_size_t (abfd, sizeof (*f));
2247 bzero ((char *) f, sizeof (*f));
2248 coff_symbol_from (abfd, sym)->native = csym = f->e;
2249 }
2250 csym[0].u.syment.n_sclass = C_STAT;
2251 csym[0].u.syment.n_numaux = 1;
2252 /* SF_SET_STATICS (sym); @@ ??? */
2253 if (sec)
2254 {
2255 csym[1].u.auxent.x_scn.x_scnlen = sec->_raw_size;
2256 csym[1].u.auxent.x_scn.x_nreloc = sec->reloc_count;
2257 csym[1].u.auxent.x_scn.x_nlinno = sec->lineno_count;
2258 }
2259 else
2260 {
2261 csym[1].u.auxent.x_scn.x_scnlen = 0;
2262 csym[1].u.auxent.x_scn.x_nreloc = 0;
2263 csym[1].u.auxent.x_scn.x_nlinno = 0;
2264 }
2265 return sym;
2266 }
2267
2268 /* If .file, .text, .data, .bss symbols are missing, add them. */
2269 /* @@ Should we only be adding missing symbols, or overriding the aux
2270 values for existing section symbols? */
2271 static void
2272 coff_add_missing_symbols (abfd)
2273 bfd *abfd;
2274 {
2275 unsigned int nsyms = bfd_get_symcount (abfd);
2276 asymbol **sympp = abfd->outsymbols;
2277 asymbol **sympp2;
2278 unsigned int i;
2279 int need_text = 1, need_data = 1, need_bss = 1, need_file = 1;
2280 coff_data_type *cdata = coff_data (abfd);
2281
2282 for (i = 0; i < nsyms; i++)
2283 {
2284 coff_symbol_type *csym = coff_symbol_from (abfd, sympp[i]);
2285 CONST char *name;
2286
2287 if (csym->native && csym->native->u.syment.n_sclass == C_FILE)
2288 {
2289 need_file = 0;
2290 continue;
2291 }
2292 name = csym->symbol.name;
2293 if (!name)
2294 continue;
2295 if (!strcmp (name, _TEXT))
2296 need_text = 0;
2297 else if (!strcmp (name, _DATA))
2298 need_data = 0;
2299 else if (!strcmp (name, _BSS))
2300 need_bss = 0;
2301 }
2302 /* Now i == bfd_get_symcount (abfd). */
2303 /* @@ For now, don't deal with .file symbol. */
2304 need_file = 0;
2305
2306 if (!need_text && !need_data && !need_bss && !need_file)
2307 return;
2308 nsyms += need_text + need_data + need_bss + need_file;
2309 sympp2 = (asymbol**) bfd_alloc_by_size_t (abfd, nsyms * sizeof (asymbol *));
2310 memcpy (sympp2, sympp, i * sizeof (asymbol *));
2311 if (need_file)
2312 {
2313 /* @@ Generate fake .file symbol, in sympp2[i], and increment i. */
2314 abort ();
2315 }
2316 if (need_text)
2317 sympp2[i++] = coff_section_symbol (abfd, _TEXT);
2318 if (need_data)
2319 sympp2[i++] = coff_section_symbol (abfd, _DATA);
2320 if (need_bss)
2321 sympp2[i++] = coff_section_symbol (abfd, _BSS);
2322 assert (i == nsyms);
2323 bfd_set_symtab (abfd, sympp2, nsyms);
2324 }
2325 #endif /* NO_COFF_SYMBOLS */
2326
2327 /* SUPPRESS 558 */
2328 /* SUPPRESS 529 */
2329 static boolean
2330 DEFUN(coff_write_object_contents,(abfd),
2331 bfd *abfd)
2332 {
2333 asection *current;
2334 unsigned int count;
2335
2336 boolean hasrelocs = false;
2337 boolean haslinno = false;
2338 file_ptr reloc_base;
2339 file_ptr lineno_base;
2340 file_ptr sym_base;
2341 file_ptr scn_base;
2342 file_ptr data_base;
2343 unsigned long reloc_size = 0;
2344 unsigned long lnno_size = 0;
2345 asection *text_sec = NULL;
2346 asection *data_sec = NULL;
2347 asection *bss_sec = NULL;
2348
2349 struct internal_filehdr internal_f;
2350 struct internal_aouthdr internal_a;
2351
2352
2353 bfd_error = system_call_error;
2354 /* Number the output sections, starting from one on the first section
2355 with a name which doesn't start with a *.
2356 @@ The code doesn't make this check. Is it supposed to be done,
2357 or isn't it?? */
2358 count = 1;
2359 for (current = abfd->sections; current != (asection *)NULL;
2360 current = current->next)
2361 {
2362 current->target_index = count;
2363 count++;
2364 }
2365
2366
2367
2368
2369
2370 if(abfd->output_has_begun == false) {
2371 coff_compute_section_file_positions(abfd);
2372 }
2373
2374 if (abfd->sections != (asection *)NULL) {
2375 scn_base = abfd->sections->filepos;
2376 }
2377 else {
2378 scn_base = 0;
2379 }
2380 if (bfd_seek(abfd, scn_base, SEEK_SET) != 0)
2381 return false;
2382 reloc_base = obj_relocbase(abfd);
2383
2384 /* Make a pass through the symbol table to count line number entries and
2385 put them into the correct asections */
2386
2387 #ifndef NO_COFF_LINENOS
2388 coff_count_linenumbers(abfd);
2389 #endif
2390 data_base = scn_base;
2391
2392 /* Work out the size of the reloc and linno areas */
2393
2394 for (current = abfd->sections; current != NULL; current =
2395 current->next)
2396 {
2397 /* We give section headers to +ve indexes */
2398 if (current->target_index > 0)
2399 {
2400
2401 reloc_size += current->reloc_count * RELSZ;
2402 #ifndef NO_COFF_LINENOS
2403 lnno_size += current->lineno_count * LINESZ;
2404 #endif
2405 data_base += SCNHSZ;
2406 }
2407
2408 }
2409
2410 lineno_base = reloc_base + reloc_size;
2411 sym_base = lineno_base + lnno_size;
2412
2413 /* Indicate in each section->line_filepos its actual file address */
2414 for (current = abfd->sections; current != NULL; current =
2415 current->next)
2416 {
2417 if (current->target_index > 0)
2418 {
2419
2420 if (current->lineno_count) {
2421 current->line_filepos = lineno_base;
2422 current->moving_line_filepos = lineno_base;
2423 #ifndef NO_COFF_LINENOS
2424 lineno_base += current->lineno_count * LINESZ;
2425 #endif
2426 }
2427 else {
2428 current->line_filepos = 0;
2429 }
2430 if (current->reloc_count) {
2431 current->rel_filepos = reloc_base;
2432 reloc_base += current->reloc_count * RELSZ;
2433 }
2434 else {
2435 current->rel_filepos = 0;
2436 }
2437 }
2438 }
2439
2440
2441
2442 /* Write section headers to the file. */
2443 internal_f.f_nscns = 0;
2444 bfd_seek(abfd,
2445 (file_ptr) ((abfd->flags & EXEC_P) ?
2446 (FILHSZ + AOUTSZ) : FILHSZ),
2447 SEEK_SET);
2448
2449 {
2450 #if 0
2451 unsigned int pad = abfd->flags & D_PAGED ? data_base : 0;
2452 #endif
2453 unsigned int pad = 0;
2454
2455 for (current = abfd->sections;
2456 current != NULL;
2457 current = current->next) {
2458 struct internal_scnhdr section;
2459 if (current->target_index > 0)
2460 {
2461 internal_f.f_nscns ++;
2462 strncpy(&(section.s_name[0]), current->name, 8);
2463 section.s_vaddr = current->vma + pad;
2464 section.s_paddr = current->vma + pad;
2465 section.s_size = current->_raw_size - pad;
2466 /*
2467 If this section has no size or is unloadable then the scnptr
2468 will be 0 too
2469 */
2470 if (current->_raw_size - pad == 0 ||
2471 (current->flags & SEC_LOAD) == 0) {
2472 section.s_scnptr = 0;
2473 }
2474 else {
2475 section.s_scnptr = current->filepos;
2476 }
2477 section.s_relptr = current->rel_filepos;
2478 section.s_lnnoptr = current->line_filepos;
2479 section.s_nreloc = current->reloc_count;
2480 section.s_nlnno = current->lineno_count;
2481 if (current->reloc_count != 0)
2482 hasrelocs = true;
2483 if (current->lineno_count != 0)
2484 haslinno = true;
2485
2486 section.s_flags = sec_to_styp_flags(current->name,current->flags);
2487
2488 if (!strcmp(current->name, _TEXT)) {
2489 text_sec = current;
2490 } else if (!strcmp(current->name, _DATA)) {
2491 data_sec = current;
2492 } else if (!strcmp(current->name, _BSS)) {
2493 bss_sec = current;
2494 }
2495
2496 #ifdef I960
2497 section.s_align = (current->alignment_power
2498 ? 1 << current->alignment_power
2499 : 0);
2500
2501 #endif
2502 {
2503 SCNHDR buff;
2504
2505 coff_swap_scnhdr_out(abfd, &section, &buff);
2506 bfd_write((PTR) (&buff), 1, SCNHSZ, abfd);
2507
2508 }
2509
2510 pad = 0;
2511 }
2512 }
2513 }
2514
2515
2516 /* OK, now set up the filehdr... */
2517
2518 /* Don't include the internal abs section in the section count */
2519
2520 /*
2521 We will NOT put a fucking timestamp in the header here. Every time you
2522 put it back, I will come in and take it out again. I'm sorry. This
2523 field does not belong here. We fill it with a 0 so it compares the
2524 same but is not a reasonable time. -- gnu@cygnus.com
2525 */
2526 /*
2527 Well, I like it, and now we have *customers* who have requested it,
2528 so I'm conditionally compiling it in.
2529
2530 sac@cygnus.com
2531 */
2532 #ifndef NOCOFF_TIMESTAMP
2533 internal_f.f_timdat = time(0);
2534 #else
2535 internal_f.f_timdat = 0;
2536 #endif
2537
2538 if (bfd_get_symcount(abfd) != 0)
2539 internal_f.f_symptr = sym_base;
2540 else
2541 internal_f.f_symptr = 0;
2542
2543 internal_f.f_flags = 0;
2544
2545 if (abfd->flags & EXEC_P)
2546 internal_f.f_opthdr = AOUTSZ;
2547 else
2548 internal_f.f_opthdr = 0;
2549
2550 if (!hasrelocs)
2551 internal_f.f_flags |= F_RELFLG;
2552 if (!haslinno)
2553 internal_f.f_flags |= F_LNNO;
2554 if (0 == bfd_get_symcount(abfd))
2555 internal_f.f_flags |= F_LSYMS;
2556 if (abfd->flags & EXEC_P)
2557 internal_f.f_flags |= F_EXEC;
2558
2559 if (!abfd->xvec->byteorder_big_p)
2560 internal_f.f_flags |= F_AR32WR;
2561 else
2562 internal_f.f_flags |= F_AR32W;
2563
2564 /*
2565 FIXME, should do something about the other byte orders and
2566 architectures.
2567 */
2568
2569 /* Set up architecture-dependent stuff */
2570
2571 { unsigned int magic = 0;
2572 unsigned short flags = 0;
2573 coff_set_flags(abfd, &magic, &flags);
2574 internal_f.f_magic = magic;
2575 internal_f.f_flags |= flags;
2576 /* ...and the "opt"hdr... */
2577
2578 #ifdef A29K
2579 # ifdef ULTRA3 /* NYU's machine */
2580 /* FIXME: This is a bogus check. I really want to see if there
2581 * is a .shbss or a .shdata section, if so then set the magic
2582 * number to indicate a shared data executable.
2583 */
2584 if (internal_f.f_nscns >= 7)
2585 internal_a.magic = SHMAGIC; /* Shared magic */
2586 else
2587 # endif /* ULTRA3 */
2588 internal_a.magic = NMAGIC; /* Assume separate i/d */
2589 #define __A_MAGIC_SET__
2590 #endif /* A29K */
2591 #ifdef I960
2592 internal_a.magic = (magic == I960ROMAGIC ? NMAGIC : OMAGIC);
2593 #define __A_MAGIC_SET__
2594 #endif /* I960 */
2595 #if M88
2596 #define __A_MAGIC_SET__
2597 internal_a.magic = PAGEMAGICBCS;
2598 #endif /* M88 */
2599
2600 #if M68 || I386 || MIPS
2601 #define __A_MAGIC_SET__
2602 /* Never was anything here for the 68k */
2603 #endif /* M88 */
2604
2605 #if RS6000COFF_C
2606 #define __A_MAGIC_SET__
2607 internal_a.magic = (abfd->flags & D_PAGED)? RS6K_AOUTHDR_ZMAGIC:
2608 (abfd->flags & WP_TEXT)? RS6K_AOUTHDR_NMAGIC:
2609 RS6K_AOUTHDR_OMAGIC;
2610 #endif
2611
2612 #ifndef __A_MAGIC_SET__
2613 # include "Your aouthdr magic number is not being set!"
2614 #else
2615 # undef __A_MAGIC_SET__
2616 #endif
2617 }
2618 /* Now should write relocs, strings, syms */
2619 obj_sym_filepos(abfd) = sym_base;
2620
2621 #ifndef NO_COFF_SYMBOLS
2622 if (bfd_get_symcount(abfd) != 0) {
2623 coff_add_missing_symbols (abfd);
2624 coff_renumber_symbols(abfd);
2625 coff_mangle_symbols(abfd);
2626 coff_write_symbols(abfd);
2627 coff_write_linenumbers(abfd);
2628 coff_write_relocs(abfd);
2629 }
2630 #endif /* NO_COFF_SYMBOLS */
2631 if (text_sec) {
2632 internal_a.tsize = bfd_get_section_size_before_reloc(text_sec);
2633 internal_a.text_start = internal_a.tsize ? text_sec->vma : 0;
2634 }
2635 if (data_sec) {
2636 internal_a.dsize = bfd_get_section_size_before_reloc(data_sec);
2637 internal_a.data_start = internal_a.dsize ? data_sec->vma : 0;
2638 }
2639 if (bss_sec) {
2640 internal_a.bsize = bfd_get_section_size_before_reloc(bss_sec);
2641 }
2642
2643 internal_a.entry = bfd_get_start_address(abfd);
2644 internal_f.f_nsyms = bfd_get_symcount(abfd);
2645
2646 /* now write them */
2647 if (bfd_seek(abfd, 0L, SEEK_SET) != 0)
2648 return false;
2649 {
2650 FILHDR buff;
2651 coff_swap_filehdr_out(abfd, (PTR)&internal_f, (PTR)&buff);
2652 bfd_write((PTR) &buff, 1, FILHSZ, abfd);
2653 }
2654 if (abfd->flags & EXEC_P) {
2655 AOUTHDR buff;
2656 coff_swap_aouthdr_out(abfd, (PTR)&internal_a, (PTR)&buff);
2657 bfd_write((PTR) &buff, 1, AOUTSZ, abfd);
2658 }
2659 return true;
2660 }
2661
2662 #ifndef NO_COFF_SYMBOLS
2663
2664 /*
2665 this function transforms the offsets into the symbol table into
2666 pointers to syments.
2667 */
2668
2669
2670 static void
2671 DEFUN(coff_pointerize_aux,(ignore_abfd, table_base, type, class, auxent),
2672 bfd *ignore_abfd AND
2673 combined_entry_type *table_base AND
2674 int type AND
2675 int class AND
2676 combined_entry_type *auxent)
2677 {
2678 /* Don't bother if this is a file or a section */
2679 if (class == C_STAT && type == T_NULL) return;
2680 if (class == C_FILE) return;
2681
2682 /* Otherwise patch up */
2683 if (ISFCN(type) || ISTAG(class) || class == C_BLOCK) {
2684 auxent->u.auxent.x_sym.x_fcnary.x_fcn.x_endndx.p = table_base +
2685 auxent->u.auxent.x_sym.x_fcnary.x_fcn.x_endndx.l;
2686 auxent->fix_end = 1;
2687 }
2688 if (auxent->u.auxent.x_sym.x_tagndx.l != 0) {
2689 auxent->u.auxent.x_sym.x_tagndx.p =
2690 table_base + auxent->u.auxent.x_sym.x_tagndx.l;
2691 auxent->fix_tag = 1;
2692 }
2693 }
2694
2695 #endif /* NO_COFF_SYMBOLS */
2696
2697 static boolean
2698 DEFUN(coff_set_section_contents,(abfd, section, location, offset, count),
2699 bfd *abfd AND
2700 sec_ptr section AND
2701 PTR location AND
2702 file_ptr offset AND
2703 bfd_size_type count)
2704 {
2705 if (abfd->output_has_begun == false) /* set by bfd.c handler */
2706 coff_compute_section_file_positions(abfd);
2707
2708 bfd_seek(abfd, (file_ptr) (section->filepos + offset), SEEK_SET);
2709
2710 if (count != 0) {
2711 return (bfd_write(location, 1, count, abfd) == count) ? true : false;
2712 }
2713 return true;
2714 }
2715 #if 0
2716 static boolean
2717 coff_close_and_cleanup(abfd)
2718 bfd *abfd;
2719 {
2720 if (!bfd_read_p(abfd))
2721 switch (abfd->format) {
2722 case bfd_archive:
2723 if (!_bfd_write_archive_contents(abfd))
2724 return false;
2725 break;
2726 case bfd_object:
2727 if (!coff_write_object_contents(abfd))
2728 return false;
2729 break;
2730 default:
2731 bfd_error = invalid_operation;
2732 return false;
2733 }
2734
2735 /* We depend on bfd_close to free all the memory on the obstack. */
2736 /* FIXME if bfd_release is not using obstacks! */
2737 return true;
2738 }
2739
2740 #endif
2741 static PTR
2742 buy_and_read(abfd, where, seek_direction, size)
2743 bfd *abfd;
2744 file_ptr where;
2745 int seek_direction;
2746 size_t size;
2747 {
2748 PTR area = (PTR) bfd_alloc(abfd, size);
2749 if (!area) {
2750 bfd_error = no_memory;
2751 return (NULL);
2752 }
2753 bfd_seek(abfd, where, seek_direction);
2754 if (bfd_read(area, 1, size, abfd) != size) {
2755 bfd_error = system_call_error;
2756 return (NULL);
2757 } /* on error */
2758 return (area);
2759 } /* buy_and_read() */
2760
2761
2762 #ifndef NO_COFF_SYMBOLS
2763
2764 static char *
2765 DEFUN(build_string_table,(abfd),
2766 bfd *abfd)
2767 {
2768 char string_table_size_buffer[4];
2769 unsigned int string_table_size;
2770 char *string_table;
2771
2772 /* At this point we should be "seek"'d to the end of the
2773 symbols === the symbol table size. */
2774 if (bfd_read((char *) string_table_size_buffer,
2775 sizeof(string_table_size_buffer),
2776 1, abfd) != sizeof(string_table_size)) {
2777 bfd_error = system_call_error;
2778 return (NULL);
2779 } /* on error */
2780
2781 string_table_size = bfd_h_get_32(abfd, (bfd_byte *) string_table_size_buffer);
2782
2783 if ((string_table = (PTR) bfd_alloc(abfd, string_table_size -= 4)) == NULL) {
2784 bfd_error = no_memory;
2785 return (NULL);
2786 } /* on mallocation error */
2787 if (bfd_read(string_table, string_table_size, 1, abfd) != string_table_size) {
2788 bfd_error = system_call_error;
2789 return (NULL);
2790 }
2791 return string_table;
2792 }
2793
2794 /* Allocate space for the ".debug" section, and read it.
2795 We did not read the debug section until now, because
2796 we didn't want to go to the trouble until someone needed it. */
2797
2798 static char *
2799 DEFUN(build_debug_section,(abfd),
2800 bfd *abfd)
2801 {
2802 char *debug_section;
2803 long position;
2804
2805 asection *sect = bfd_get_section_by_name (abfd, ".debug");
2806
2807 if (!sect) {
2808 bfd_error = no_debug_section;
2809 return NULL;
2810 }
2811
2812 debug_section = (PTR) bfd_alloc (abfd,
2813 bfd_get_section_size_before_reloc (sect));
2814 if (debug_section == NULL) {
2815 bfd_error = no_memory;
2816 return NULL;
2817 }
2818
2819 /* Seek to the beginning of the `.debug' section and read it.
2820 Save the current position first; it is needed by our caller.
2821 Then read debug section and reset the file pointer. */
2822
2823 position = bfd_tell (abfd);
2824 bfd_seek (abfd, sect->filepos, SEEK_SET);
2825 if (bfd_read (debug_section,
2826 bfd_get_section_size_before_reloc (sect), 1, abfd)
2827 != bfd_get_section_size_before_reloc(sect)) {
2828 bfd_error = system_call_error;
2829 return NULL;
2830 }
2831 bfd_seek (abfd, position, SEEK_SET);
2832 return debug_section;
2833 }
2834
2835
2836 /* Return a pointer to a malloc'd copy of 'name'. 'name' may not be
2837 \0-terminated, but will not exceed 'maxlen' characters. The copy *will*
2838 be \0-terminated. */
2839 static char *
2840 DEFUN(copy_name,(abfd, name, maxlen),
2841 bfd *abfd AND
2842 char *name AND
2843 int maxlen)
2844 {
2845 int len;
2846 char *newname;
2847
2848 for (len = 0; len < maxlen; ++len) {
2849 if (name[len] == '\0') {
2850 break;
2851 }
2852 }
2853
2854 if ((newname = (PTR) bfd_alloc(abfd, len+1)) == NULL) {
2855 bfd_error = no_memory;
2856 return (NULL);
2857 }
2858 strncpy(newname, name, len);
2859 newname[len] = '\0';
2860 return newname;
2861 }
2862
2863
2864 /* Read a symbol table into freshly bfd_allocated memory, swap it, and
2865 knit the symbol names into a normalized form. By normalized here I
2866 mean that all symbols have an n_offset pointer that points to a null-
2867 terminated string. */
2868
2869 #ifndef SYMNAME_IN_DEBUG
2870 #define SYMNAME_IN_DEBUG(x) 0
2871 #endif
2872
2873 static combined_entry_type *
2874 DEFUN(get_normalized_symtab,(abfd),
2875 bfd *abfd)
2876 {
2877 combined_entry_type *internal;
2878 combined_entry_type *internal_ptr;
2879 combined_entry_type *symbol_ptr;
2880 combined_entry_type *internal_end;
2881 SYMENT *raw;
2882 SYMENT *raw_src;
2883 SYMENT *raw_end;
2884 char *string_table = NULL;
2885 char *debug_section = NULL;
2886 unsigned long size;
2887
2888 unsigned int raw_size;
2889 if (obj_raw_syments(abfd) != (combined_entry_type *)NULL) {
2890 return obj_raw_syments(abfd);
2891 }
2892 if ((size = bfd_get_symcount(abfd) * sizeof(combined_entry_type)) == 0) {
2893 bfd_error = no_symbols;
2894 return (NULL);
2895 }
2896
2897 internal = (combined_entry_type *)bfd_alloc(abfd, size);
2898 internal_end = internal + bfd_get_symcount(abfd);
2899
2900 raw_size = bfd_get_symcount(abfd) * SYMESZ;
2901 raw = (SYMENT *)bfd_alloc(abfd,raw_size);
2902
2903 if (bfd_seek(abfd, obj_sym_filepos(abfd), SEEK_SET) == -1
2904 || bfd_read((PTR)raw, raw_size, 1, abfd) != raw_size) {
2905 bfd_error = system_call_error;
2906 return (NULL);
2907 }
2908 /* mark the end of the symbols */
2909 raw_end = raw + bfd_get_symcount(abfd);
2910 /*
2911 FIXME SOMEDAY. A string table size of zero is very weird, but
2912 probably possible. If one shows up, it will probably kill us.
2913 */
2914
2915 /* Swap all the raw entries */
2916 for (raw_src = raw, internal_ptr = internal;
2917 raw_src < raw_end;
2918 raw_src++, internal_ptr++) {
2919
2920 unsigned int i;
2921 coff_swap_sym_in(abfd, (PTR)raw_src, (PTR)&internal_ptr->u.syment);
2922 internal_ptr->fix_tag = 0;
2923 internal_ptr->fix_end = 0;
2924 symbol_ptr = internal_ptr;
2925
2926 for (i = 0;
2927 i < symbol_ptr->u.syment.n_numaux;
2928 i++)
2929 {
2930 internal_ptr++;
2931 raw_src++;
2932
2933 internal_ptr->fix_tag = 0;
2934 internal_ptr->fix_end = 0;
2935 coff_swap_aux_in(abfd, (char *)(raw_src),
2936 symbol_ptr->u.syment.n_type,
2937 symbol_ptr->u.syment.n_sclass,
2938 &(internal_ptr->u.auxent));
2939 /* Remember that bal entries arn't pointerized */
2940 if (i != 1 || symbol_ptr->u.syment.n_sclass != C_LEAFPROC)
2941 {
2942
2943 coff_pointerize_aux(abfd,
2944 internal,
2945 symbol_ptr->u.syment.n_type,
2946 symbol_ptr->u.syment.n_sclass,
2947 internal_ptr);
2948 }
2949
2950 }
2951 }
2952
2953 /* Free all the raw stuff */
2954 bfd_release(abfd, raw);
2955
2956 for (internal_ptr = internal; internal_ptr < internal_end;
2957 internal_ptr ++)
2958 {
2959 if (internal_ptr->u.syment.n_sclass == C_FILE) {
2960 /* make a file symbol point to the name in the auxent, since
2961 the text ".file" is redundant */
2962 if ((internal_ptr+1)->u.auxent.x_file.x_n.x_zeroes == 0) {
2963 /* the filename is a long one, point into the string table */
2964 if (string_table == NULL) {
2965 string_table = build_string_table(abfd);
2966 }
2967
2968 internal_ptr->u.syment._n._n_n._n_offset =
2969 (int) (string_table - 4 +
2970 (internal_ptr+1)->u.auxent.x_file.x_n.x_offset);
2971 }
2972 else {
2973 /* ordinary short filename, put into memory anyway */
2974 internal_ptr->u.syment._n._n_n._n_offset = (int)
2975 copy_name(abfd, (internal_ptr+1)->u.auxent.x_file.x_fname,
2976 FILNMLEN);
2977 }
2978 }
2979 else {
2980 if (internal_ptr->u.syment._n._n_n._n_zeroes != 0) {
2981 /* This is a "short" name. Make it long. */
2982 unsigned long i = 0;
2983 char *newstring = NULL;
2984
2985 /* find the length of this string without walking into memory
2986 that isn't ours. */
2987 for (i = 0; i < 8; ++i) {
2988 if (internal_ptr->u.syment._n._n_name[i] == '\0') {
2989 break;
2990 } /* if end of string */
2991 } /* possible lengths of this string. */
2992
2993 if ((newstring = (PTR) bfd_alloc(abfd, ++i)) == NULL) {
2994 bfd_error = no_memory;
2995 return (NULL);
2996 } /* on error */
2997 bzero(newstring, i);
2998 strncpy(newstring, internal_ptr->u.syment._n._n_name, i-1);
2999 internal_ptr->u.syment._n._n_n._n_offset = (int) newstring;
3000 internal_ptr->u.syment._n._n_n._n_zeroes = 0;
3001 }
3002 else if (!SYMNAME_IN_DEBUG(&internal_ptr->u.syment)) {
3003 /* Long name already. Point symbol at the string in the table. */
3004 if (string_table == NULL) {
3005 string_table = build_string_table(abfd);
3006 }
3007 internal_ptr->u.syment._n._n_n._n_offset = (int)
3008 (string_table - 4 + internal_ptr->u.syment._n._n_n._n_offset);
3009 }
3010 else {
3011 /* Long name in debug section. Very similar. */
3012 if (debug_section == NULL) {
3013 debug_section = build_debug_section(abfd);
3014 }
3015 internal_ptr->u.syment._n._n_n._n_offset = (int)
3016 (debug_section + internal_ptr->u.syment._n._n_n._n_offset);
3017 }
3018 }
3019 internal_ptr += internal_ptr->u.syment.n_numaux;
3020 }
3021
3022 obj_raw_syments(abfd) = internal;
3023
3024 return (internal);
3025 } /* get_normalized_symtab() */
3026
3027 #endif /* NO_COFF_SYMBOLS */
3028
3029 static
3030 struct sec *
3031 DEFUN(section_from_bfd_index,(abfd, index),
3032 bfd *abfd AND
3033 int index)
3034 {
3035 struct sec *answer = abfd->sections;
3036
3037 if (index == N_ABS)
3038 {
3039 return &bfd_abs_section;
3040 }
3041 if (index == N_UNDEF)
3042 {
3043 return &bfd_und_section;
3044 }
3045 if(index == N_DEBUG)
3046 {
3047 return &bfd_debug_section;
3048
3049 }
3050
3051 while (answer) {
3052 if (answer->target_index == index)
3053 return answer;
3054 answer = answer->next;
3055 }
3056 BFD_ASSERT(0);
3057 return &bfd_und_section; /* For gcc -W and lint. Never executed. */
3058 }
3059
3060 #ifndef NO_COFF_LINENOS
3061
3062 /*
3063 SUBSUBSECTION
3064 Reading Linenumbers
3065
3066 Creating the linenumber table is done by reading in the entire
3067 coff linenumber table, and creating another table for internal use.
3068
3069 A coff line number table is structured so that each function
3070 is marked as having a line number of 0. Each line within the
3071 function is an offset from the first line in the function. The
3072 base of the line number information for the table is stored in
3073 the symbol associated with the function.
3074
3075 The information is copied from the external to the internal
3076 table, and each symbol which marks a function is marked by
3077 pointing its...
3078
3079 How does this work ?
3080
3081 */
3082
3083 static boolean
3084 coff_slurp_line_table(abfd, asect)
3085 bfd *abfd;
3086 asection *asect;
3087 {
3088 LINENO *native_lineno;
3089 alent *lineno_cache;
3090
3091 BFD_ASSERT(asect->lineno == (alent *) NULL);
3092
3093 native_lineno = (LINENO *) buy_and_read(abfd,
3094 asect->line_filepos,
3095 SEEK_SET,
3096 (size_t) (LINESZ *
3097 asect->lineno_count));
3098 lineno_cache =
3099 (alent *) bfd_alloc(abfd, (size_t) ((asect->lineno_count + 1) * sizeof(alent)));
3100 if (lineno_cache == NULL) {
3101 bfd_error = no_memory;
3102 return false;
3103 } else {
3104 unsigned int counter = 0;
3105 alent *cache_ptr = lineno_cache;
3106 LINENO *src = native_lineno;
3107
3108 while (counter < asect->lineno_count) {
3109 struct internal_lineno dst;
3110 coff_swap_lineno_in(abfd, src, &dst);
3111 cache_ptr->line_number = dst.l_lnno;
3112
3113 if (cache_ptr->line_number == 0) {
3114 coff_symbol_type *sym =
3115 (coff_symbol_type *) (dst.l_addr.l_symndx
3116 + obj_raw_syments(abfd))->u.syment._n._n_n._n_zeroes;
3117 cache_ptr->u.sym = (asymbol *) sym;
3118 sym->lineno = cache_ptr;
3119 }
3120 else {
3121 cache_ptr->u.offset = dst.l_addr.l_paddr
3122 - bfd_section_vma(abfd, asect);
3123 } /* If no linenumber expect a symbol index */
3124
3125 cache_ptr++;
3126 src++;
3127 counter++;
3128 }
3129 cache_ptr->line_number = 0;
3130
3131 }
3132 asect->lineno = lineno_cache;
3133 /* FIXME, free native_lineno here, or use alloca or something. */
3134 return true;
3135 } /* coff_slurp_line_table() */
3136
3137 #endif /* NO_COFF_LINENOS */
3138
3139 #ifndef NO_COFF_LINENOS
3140
3141 static boolean
3142 DEFUN(coff_slurp_symbol_table,(abfd),
3143 bfd *abfd)
3144 {
3145 combined_entry_type *native_symbols;
3146 coff_symbol_type *cached_area;
3147 unsigned int *table_ptr;
3148
3149 unsigned int number_of_symbols = 0;
3150 if (obj_symbols(abfd))
3151 return true;
3152 bfd_seek(abfd, obj_sym_filepos(abfd), SEEK_SET);
3153
3154 /* Read in the symbol table */
3155 if ((native_symbols = get_normalized_symtab(abfd)) == NULL) {
3156 return (false);
3157 } /* on error */
3158
3159 /* Allocate enough room for all the symbols in cached form */
3160 cached_area =
3161 (coff_symbol_type *)
3162 bfd_alloc(abfd, (size_t) (bfd_get_symcount(abfd) * sizeof(coff_symbol_type)));
3163
3164 if (cached_area == NULL) {
3165 bfd_error = no_memory;
3166 return false;
3167 } /* on error */
3168 table_ptr =
3169 (unsigned int *)
3170 bfd_alloc(abfd, (size_t) (bfd_get_symcount(abfd) * sizeof(unsigned int)));
3171
3172 if (table_ptr == NULL) {
3173 bfd_error = no_memory;
3174 return false;
3175 }
3176 else
3177 {
3178 coff_symbol_type *dst = cached_area;
3179 unsigned int last_native_index = bfd_get_symcount(abfd);
3180 unsigned int this_index = 0;
3181 while (this_index < last_native_index) {
3182 combined_entry_type *src = native_symbols + this_index;
3183 table_ptr[this_index] = number_of_symbols;
3184 dst->symbol.the_bfd = abfd;
3185
3186 dst->symbol.name = (char *)(src->u.syment._n._n_n._n_offset);
3187 /*
3188 We use the native name field to point to the cached field
3189 */
3190 src->u.syment._n._n_n._n_zeroes = (int) dst;
3191 dst->symbol.section = section_from_bfd_index(abfd,
3192 src->u.syment.n_scnum);
3193 dst->symbol.flags = 0;
3194 dst->done_lineno = false;
3195
3196 switch (src->u.syment.n_sclass) {
3197 #ifdef I960
3198 case C_LEAFEXT:
3199 #if 0
3200 dst->symbol.value = src->u.syment.n_value - dst->symbol.section->vma;
3201 dst->symbol.flags = BSF_EXPORT | BSF_GLOBAL;
3202 dst->symbol.flags |= BSF_NOT_AT_END;
3203 #endif
3204 /* Fall through to next case */
3205
3206 #endif
3207
3208 case C_EXT:
3209 #ifdef RS6000COFF_C
3210 case C_HIDEXT:
3211 #endif
3212 if ((src->u.syment.n_scnum) == 0) {
3213 if ((src->u.syment.n_value) == 0) {
3214 dst->symbol.section = &bfd_und_section;
3215 dst->symbol.value= 0;
3216 }
3217 else {
3218 dst->symbol.section = &bfd_com_section;
3219 dst->symbol.value = (src->u.syment.n_value);
3220 }
3221 }
3222 else {
3223 /*
3224 Base the value as an index from the base of the
3225 section
3226 */
3227
3228 dst->symbol.flags = BSF_EXPORT | BSF_GLOBAL;
3229 dst->symbol.value = src->u.syment.n_value - dst->symbol.section->vma;
3230
3231 if (ISFCN((src->u.syment.n_type))) {
3232 /*
3233 A function ext does not go at the end of a file
3234 */
3235 dst->symbol.flags |= BSF_NOT_AT_END;
3236 }
3237 }
3238
3239
3240 break;
3241
3242 case C_STAT: /* static */
3243 #ifdef I960
3244 case C_LEAFSTAT: /* static leaf procedure */
3245 #endif
3246 case C_LABEL: /* label */
3247 if (src->u.syment.n_scnum == -2)
3248 dst->symbol.flags = BSF_DEBUGGING;
3249 else
3250 dst->symbol.flags = BSF_LOCAL;
3251 /*
3252 Base the value as an index from the base of the section, if
3253 there is one
3254 */
3255 if (dst->symbol.section)
3256 dst->symbol.value = (src->u.syment.n_value) -
3257 dst->symbol.section->vma;
3258 else
3259 dst->symbol.value = (src->u.syment.n_value) ;
3260 break;
3261
3262 case C_MOS: /* member of structure */
3263 case C_EOS: /* end of structure */
3264 #ifdef NOTDEF /* C_AUTOARG has the same value */
3265 #ifdef C_GLBLREG
3266 case C_GLBLREG: /* A29k-specific storage class */
3267 #endif
3268 #endif
3269 case C_REGPARM: /* register parameter */
3270 case C_REG: /* register variable */
3271 #ifdef C_AUTOARG
3272 case C_AUTOARG: /* 960-specific storage class */
3273 #endif
3274 case C_TPDEF: /* type definition */
3275 case C_ARG:
3276 case C_AUTO: /* automatic variable */
3277 case C_FIELD: /* bit field */
3278 case C_ENTAG: /* enumeration tag */
3279 case C_MOE: /* member of enumeration */
3280 case C_MOU: /* member of union */
3281 case C_UNTAG: /* union tag */
3282 dst->symbol.flags = BSF_DEBUGGING;
3283 dst->symbol.value = (src->u.syment.n_value);
3284 break;
3285
3286 case C_FILE: /* file name */
3287 case C_STRTAG: /* structure tag */
3288 #ifdef RS6000COFF_C
3289 case C_BINCL: /* beginning of include file */
3290 case C_EINCL: /* ending of include file */
3291 case C_GSYM:
3292 case C_LSYM:
3293 case C_PSYM:
3294 case C_RSYM:
3295 case C_RPSYM:
3296 case C_STSYM:
3297 case C_DECL:
3298 case C_ENTRY:
3299 case C_FUN:
3300 case C_BSTAT:
3301 case C_ESTAT:
3302 #endif
3303 dst->symbol.flags = BSF_DEBUGGING;
3304 dst->symbol.value = (src->u.syment.n_value);
3305 break;
3306
3307 case C_BLOCK: /* ".bb" or ".eb" */
3308 case C_FCN: /* ".bf" or ".ef" */
3309 case C_EFCN: /* physical end of function */
3310 dst->symbol.flags = BSF_LOCAL;
3311 /*
3312 Base the value as an index from the base of the section
3313 */
3314 dst->symbol.value = (src->u.syment.n_value) - dst->symbol.section->vma;
3315 break;
3316
3317 case C_NULL:
3318 case C_EXTDEF: /* external definition */
3319 case C_ULABEL: /* undefined label */
3320 case C_USTATIC: /* undefined static */
3321 case C_LINE: /* line # reformatted as symbol table entry */
3322 case C_ALIAS: /* duplicate tag */
3323 case C_HIDDEN: /* ext symbol in dmert public lib */
3324 default:
3325
3326 fprintf(stderr,"Unrecognized storage class %d\n",
3327 src->u.syment.n_sclass);
3328 /* abort();*/
3329 dst->symbol.flags = BSF_DEBUGGING;
3330 dst->symbol.value = (src->u.syment.n_value);
3331 break;
3332 }
3333
3334 /* BFD_ASSERT(dst->symbol.flags != 0);*/
3335
3336 dst->native = src;
3337
3338 dst->symbol.udata = 0;
3339 dst->lineno = (alent *) NULL;
3340 this_index += (src->u.syment.n_numaux) + 1;
3341 dst++;
3342 number_of_symbols++;
3343 } /* walk the native symtab */
3344 } /* bfdize the native symtab */
3345
3346 obj_symbols(abfd) = cached_area;
3347 obj_raw_syments(abfd) = native_symbols;
3348
3349 obj_conv_table_size (abfd) = bfd_get_symcount (abfd);
3350 bfd_get_symcount(abfd) = number_of_symbols;
3351 obj_convert(abfd) = table_ptr;
3352 /* Slurp the line tables for each section too */
3353 {
3354 asection *p;
3355 p = abfd->sections;
3356 while (p) {
3357 coff_slurp_line_table(abfd, p);
3358 p = p->next;
3359 }
3360 }
3361 return true;
3362 } /* coff_slurp_symbol_table() */
3363
3364 static unsigned int
3365 coff_get_symtab_upper_bound(abfd)
3366 bfd *abfd;
3367 {
3368 if (!coff_slurp_symbol_table(abfd))
3369 return 0;
3370
3371 return (bfd_get_symcount(abfd) + 1) * (sizeof(coff_symbol_type *));
3372 }
3373
3374
3375 static unsigned int
3376 DEFUN(coff_get_symtab, (abfd, alocation),
3377 bfd *abfd AND
3378 asymbol **alocation)
3379 {
3380 unsigned int counter = 0;
3381 coff_symbol_type *symbase;
3382 coff_symbol_type **location = (coff_symbol_type **) (alocation);
3383 if (!coff_slurp_symbol_table(abfd))
3384 return 0;
3385
3386 symbase = obj_symbols(abfd);
3387 while (counter < bfd_get_symcount(abfd))
3388 {
3389 /* This nasty code looks at the symbol to decide whether or
3390 not it is descibes a constructor/destructor entry point. It
3391 is structured this way to (hopefully) speed non matches */
3392 #if 0
3393 if (0 && symbase->symbol.name[9] == '$')
3394 {
3395 bfd_constructor_entry(abfd,
3396 (asymbol **)location,
3397 symbase->symbol.name[10] == 'I' ?
3398 "CTOR" : "DTOR");
3399 }
3400 #endif
3401 *(location++) = symbase++;
3402 counter++;
3403 }
3404 *location++ = 0;
3405 return bfd_get_symcount(abfd);
3406 }
3407
3408 #endif /* NO_COFF_SYMBOLS */
3409
3410 static unsigned int
3411 coff_get_reloc_upper_bound(abfd, asect)
3412 bfd *abfd;
3413 sec_ptr asect;
3414 {
3415 if (bfd_get_format(abfd) != bfd_object) {
3416 bfd_error = invalid_operation;
3417 return 0;
3418 }
3419 return (asect->reloc_count + 1) * sizeof(arelent *);
3420 }
3421
3422 /*
3423 SUBSUBSECTION
3424 Reading Relocations
3425
3426 Coff relocations are easily transformed into the internal BFD form
3427 (@code{arelent}).
3428
3429 Reading a coff relocation table is done in the following stages:
3430
3431 o The entire coff relocation table is read into memory.
3432
3433 o Each relocation is processed in turn, first it is swapped from the
3434 external to the internal form.
3435
3436 o The symbol referenced in the relocation's symbol index is
3437 turned intoa pointer into the canonical symbol table. Note
3438 that this table is the same as the one returned by a call to
3439 @code{bfd_canonicalize_symtab}. The back end will call the
3440 routine and save the result if a canonicalization hasn't been done.
3441
3442 o The reloc index is turned into a pointer to a howto
3443 structure, in a back end specific way. For instance, the 386
3444 and 960 use the @code{r_type} to directly produce an index
3445 into a howto table vector; the 88k subtracts a number from the
3446 @code{r_type} field and creates an addend field.
3447
3448
3449 */
3450
3451 #ifndef CALC_ADDEND
3452 #define CALC_ADDEND(abfd, ptr, reloc, cache_ptr) \
3453 if (ptr && ptr->the_bfd == abfd \
3454 && ((ptr->flags & BSF_OLD_COMMON)== 0)) \
3455 { \
3456 cache_ptr->addend = -(ptr->section->vma + ptr->value); \
3457 } \
3458 else { \
3459 cache_ptr->addend = 0; \
3460 }
3461 #endif
3462
3463 static boolean
3464 DEFUN(coff_slurp_reloc_table,(abfd, asect, symbols),
3465 bfd *abfd AND
3466 sec_ptr asect AND
3467 asymbol **symbols)
3468 {
3469 RELOC *native_relocs;
3470 arelent *reloc_cache;
3471 arelent *cache_ptr;
3472
3473 unsigned int idx;
3474
3475 if (asect->relocation)
3476 return true;
3477 if (asect->reloc_count == 0)
3478 return true;
3479 if (asect->flags & SEC_CONSTRUCTOR)
3480 return true;
3481 #ifndef NO_COFF_SYMBOLS
3482 if (!coff_slurp_symbol_table(abfd))
3483 return false;
3484 #endif
3485 native_relocs =
3486 (RELOC *) buy_and_read(abfd,
3487 asect->rel_filepos,
3488 SEEK_SET,
3489 (size_t) (RELSZ *
3490 asect->reloc_count));
3491 reloc_cache = (arelent *)
3492 bfd_alloc(abfd, (size_t) (asect->reloc_count * sizeof(arelent)));
3493
3494 if (reloc_cache == NULL) {
3495 bfd_error = no_memory;
3496 return false;
3497 }
3498
3499
3500 for (idx = 0; idx < asect->reloc_count; idx ++)
3501 {
3502 #ifdef RELOC_PROCESSING
3503 struct internal_reloc dst;
3504 struct external_reloc *src;
3505
3506 cache_ptr = reloc_cache + idx;
3507 src = native_relocs + idx;
3508 bfd_swap_reloc_in(abfd, src, &dst);
3509
3510 RELOC_PROCESSING(cache_ptr, &dst, symbols, abfd, asect);
3511 #else
3512 struct internal_reloc dst;
3513 asymbol *ptr;
3514 struct external_reloc *src;
3515
3516 cache_ptr = reloc_cache + idx;
3517 src = native_relocs + idx;
3518
3519 bfd_swap_reloc_in(abfd, src, &dst);
3520
3521
3522 cache_ptr->address = dst.r_vaddr;
3523
3524 if (dst.r_symndx != -1)
3525 {
3526 /* @@ Should never be greater than count of symbols! */
3527 if (dst.r_symndx >= obj_conv_table_size (abfd))
3528 abort ();
3529 cache_ptr->sym_ptr_ptr = symbols + obj_convert(abfd)[dst.r_symndx];
3530 ptr = *(cache_ptr->sym_ptr_ptr);
3531 }
3532 else
3533 {
3534 cache_ptr->sym_ptr_ptr= bfd_abs_section.symbol_ptr_ptr;
3535 ptr = 0;
3536 }
3537
3538 /*
3539 The symbols definitions that we have read in have been
3540 relocated as if their sections started at 0. But the offsets
3541 refering to the symbols in the raw data have not been
3542 modified, so we have to have a negative addend to compensate.
3543
3544 Note that symbols which used to be common must be left alone */
3545
3546 /* Calculate any reloc addend by looking at the symbol */
3547 CALC_ADDEND(abfd, ptr, dst, cache_ptr);
3548
3549 cache_ptr->address -= asect->vma;
3550 /* !! cache_ptr->section = (asection *) NULL;*/
3551
3552 /* Fill in the cache_ptr->howto field from dst.r_type */
3553 RTYPE2HOWTO(cache_ptr, &dst);
3554 #endif
3555
3556 }
3557
3558 asect->relocation = reloc_cache;
3559 return true;
3560 }
3561
3562
3563 /* This is stupid. This function should be a boolean predicate */
3564 static unsigned int
3565 DEFUN(coff_canonicalize_reloc, (abfd, section, relptr, symbols),
3566 bfd *abfd AND
3567 sec_ptr section AND
3568 arelent **relptr AND
3569 asymbol **symbols)
3570 {
3571 arelent *tblptr = section->relocation;
3572 unsigned int count = 0;
3573
3574
3575 if (section->flags & SEC_CONSTRUCTOR)
3576 {
3577 /* this section has relocs made up by us, they are not in the
3578 file, so take them out of their chain and place them into
3579 the data area provided */
3580 arelent_chain *chain = section->constructor_chain;
3581 for (count = 0; count < section->reloc_count; count ++)
3582 {
3583 *relptr ++ = &chain->relent;
3584 chain = chain->next;
3585 }
3586
3587 }
3588 else
3589 {
3590 coff_slurp_reloc_table(abfd, section, symbols);
3591
3592
3593 tblptr = section->relocation;
3594 if (!tblptr)
3595 return 0;
3596
3597 for (; count++ < section->reloc_count;)
3598 *relptr++ = tblptr++;
3599
3600
3601 }
3602 *relptr = 0;
3603 return section->reloc_count;
3604 }
3605
3606 #ifndef NO_COFF_SYMBOLS
3607
3608 /*
3609 provided a BFD, a section and an offset into the section, calculate and
3610 return the name of the source file and the line nearest to the wanted
3611 location.
3612 */
3613
3614 static boolean
3615 DEFUN(coff_find_nearest_line,(abfd,
3616 section,
3617 ignore_symbols,
3618 offset,
3619 filename_ptr,
3620 functionname_ptr,
3621 line_ptr),
3622 bfd *abfd AND
3623 asection *section AND
3624 asymbol **ignore_symbols AND
3625 bfd_vma offset AND
3626 CONST char **filename_ptr AND
3627 CONST char **functionname_ptr AND
3628 unsigned int *line_ptr)
3629 {
3630 static bfd *cache_abfd;
3631 static asection *cache_section;
3632 static bfd_vma cache_offset;
3633 static unsigned int cache_i;
3634 static alent *cache_l;
3635
3636 unsigned int i = 0;
3637 coff_data_type *cof = coff_data(abfd);
3638 /* Run through the raw syments if available */
3639 combined_entry_type *p;
3640 alent *l;
3641 unsigned int line_base = 0;
3642
3643
3644 *filename_ptr = 0;
3645 *functionname_ptr = 0;
3646 *line_ptr = 0;
3647
3648 /* Don't try and find line numbers in a non coff file */
3649 if (abfd->xvec->flavour != bfd_target_coff_flavour)
3650 return false;
3651
3652 if (cof == NULL)
3653 return false;
3654
3655 p = cof->raw_syments;
3656
3657 for (i = 0; i < cof->raw_syment_count; i++) {
3658 if (p->u.syment.n_sclass == C_FILE) {
3659 /* File name has been moved into symbol */
3660 *filename_ptr = (char *) p->u.syment._n._n_n._n_offset;
3661 break;
3662 }
3663 p += 1 + p->u.syment.n_numaux;
3664 }
3665 /* Now wander though the raw linenumbers of the section */
3666 /*
3667 If this is the same BFD as we were previously called with and this is
3668 the same section, and the offset we want is further down then we can
3669 prime the lookup loop
3670 */
3671 if (abfd == cache_abfd &&
3672 section == cache_section &&
3673 offset >= cache_offset) {
3674 i = cache_i;
3675 l = cache_l;
3676 }
3677 else {
3678 i = 0;
3679 l = section->lineno;
3680 }
3681
3682 for (; i < section->lineno_count; i++) {
3683 if (l->line_number == 0) {
3684 /* Get the symbol this line number points at */
3685 coff_symbol_type *coff = (coff_symbol_type *) (l->u.sym);
3686 *functionname_ptr = coff->symbol.name;
3687 if (coff->native) {
3688 combined_entry_type *s = coff->native;
3689 s = s + 1 + s->u.syment.n_numaux;
3690 /*
3691 S should now point to the .bf of the function
3692 */
3693 if (s->u.syment.n_numaux) {
3694 /*
3695 The linenumber is stored in the auxent
3696 */
3697 union internal_auxent *a = &((s + 1)->u.auxent);
3698 line_base = a->x_sym.x_misc.x_lnsz.x_lnno;
3699 }
3700 }
3701 }
3702 else {
3703 if (l->u.offset > offset)
3704 break;
3705 *line_ptr = l->line_number + line_base + 1;
3706 }
3707 l++;
3708 }
3709
3710 cache_abfd = abfd;
3711 cache_section = section;
3712 cache_offset = offset;
3713 cache_i = i;
3714 cache_l = l;
3715
3716 return true;
3717 }
3718
3719 #ifdef GNU960
3720 file_ptr
3721 coff_sym_filepos(abfd)
3722 bfd *abfd;
3723 {
3724 return obj_sym_filepos(abfd);
3725 }
3726 #endif
3727
3728 #endif /* NO_COFF_SYMBOLS */
3729
3730
3731 static int
3732 DEFUN(coff_sizeof_headers,(abfd, reloc),
3733 bfd *abfd AND
3734 boolean reloc)
3735 {
3736 size_t size;
3737
3738 if (reloc == false) {
3739 size = FILHSZ + AOUTSZ;
3740 }
3741 else {
3742 size = FILHSZ;
3743 }
3744
3745 size += abfd->section_count * SCNHSZ;
3746 return size;
3747 }
3748
3749 static bfd_vma
3750 DEFUN(get_value,(reloc, seclet),
3751 arelent *reloc AND
3752 bfd_seclet_type *seclet)
3753 {
3754 bfd_vma value;
3755 asymbol *symbol = *(reloc->sym_ptr_ptr);
3756 /* A symbol holds a pointer to a section, and an offset from the
3757 base of the section. To relocate, we find where the section will
3758 live in the output and add that in */
3759
3760 if (symbol->section == &bfd_und_section)
3761 {
3762 /* Ouch, this is an undefined symbol.. */
3763 bfd_error_vector.undefined_symbol(reloc, seclet);
3764 value = symbol->value;
3765 }
3766 else
3767 {
3768 value = symbol->value +
3769 symbol->section->output_offset +
3770 symbol->section->output_section->vma;
3771 }
3772
3773
3774 /* Add the value contained in the relocation */
3775 value += (short)((reloc->addend) & 0xffff);
3776
3777 return value;
3778 }
3779
3780 static void
3781 DEFUN(perform_slip,(s, slip, input_section, value),
3782 asymbol **s AND
3783 unsigned int slip AND
3784 asection *input_section AND
3785 bfd_vma value)
3786 {
3787
3788 /* Find all symbols past this point, and make them know
3789 what's happened */
3790 while (*s)
3791 {
3792 asymbol *p = *s;
3793 if (p->section == input_section)
3794 {
3795 /* This was pointing into this section, so mangle it */
3796 if (p->value > value)
3797 {
3798 p->value -=2;
3799 }
3800 }
3801 s++;
3802
3803 }
3804 }
3805 static int
3806 DEFUN(movb1,(input_section, symbols, r, shrink),
3807 asection *input_section AND
3808 asymbol **symbols AND
3809 arelent *r AND
3810 unsigned int shrink)
3811 {
3812 bfd_vma value = get_value(r,0);
3813
3814 if (value >= 0xff00)
3815 {
3816
3817 /* Change the reloc type from 16bit, possible 8 to 8bit
3818 possible 16 */
3819 r->howto = r->howto + 1;
3820 /* The place to relc moves back by one */
3821 r->address -=1;
3822
3823 /* This will be two bytes smaller in the long run */
3824 shrink +=2 ;
3825 perform_slip(symbols, 2, input_section, r->address - shrink +1);
3826
3827
3828 }
3829 return shrink;
3830 }
3831
3832 static int
3833 DEFUN(jmp1,(input_section, symbols, r, shrink),
3834 asection *input_section AND
3835 asymbol **symbols AND
3836 arelent *r AND
3837 unsigned int shrink)
3838 {
3839
3840
3841 bfd_vma value = get_value(r, 0);
3842
3843 bfd_vma dot = input_section->output_section->vma +
3844 input_section->output_offset + r->address;
3845 bfd_vma gap;
3846
3847 /* See if the address we're looking at within 127 bytes of where
3848 we are, if so then we can use a small branch rather than the
3849 jump we were going to */
3850
3851 gap = value - (dot - shrink);
3852
3853
3854 if (-120 < (long)gap && (long)gap < 120 )
3855 {
3856
3857 /* Change the reloc type from 16bit, possible 8 to 8bit
3858 possible 16 */
3859 r->howto = r->howto + 1;
3860 /* The place to relc moves back by one */
3861 r->address -=1;
3862
3863 /* This will be two bytes smaller in the long run */
3864 shrink +=2 ;
3865 perform_slip(symbols, 2, input_section, r->address-shrink +1);
3866
3867
3868 }
3869 return shrink;
3870 }
3871
3872 static boolean
3873 DEFUN(bfd_coff_relax_section,(abfd, i, symbols),
3874 bfd *abfd AND
3875 asection *i AND
3876 asymbol **symbols)
3877 {
3878
3879 /* Get enough memory to hold the stuff */
3880 bfd *input_bfd = i->owner;
3881 asection *input_section = i;
3882 int shrink = 0 ;
3883 boolean new = false;
3884
3885 bfd_size_type reloc_size = bfd_get_reloc_upper_bound(input_bfd,
3886 input_section);
3887 arelent **reloc_vector = (arelent **)bfd_xmalloc(reloc_size);
3888
3889 /* Get the relocs and think about them */
3890 if (bfd_canonicalize_reloc(input_bfd,
3891 input_section,
3892 reloc_vector,
3893 symbols))
3894 {
3895 arelent **parent;
3896 for (parent = reloc_vector; *parent; parent++)
3897 {
3898 arelent *r = *parent;
3899 switch (r->howto->type) {
3900 case R_MOVB2:
3901 case R_JMP2:
3902
3903 shrink+=2;
3904 break;
3905
3906 case R_MOVB1:
3907 shrink = movb1(input_section, symbols, r, shrink);
3908 new = true;
3909
3910 break;
3911 case R_JMP1:
3912 shrink = jmp1(input_section, symbols, r, shrink);
3913 new = true;
3914
3915 break;
3916 }
3917 }
3918
3919 }
3920 input_section->_cooked_size -= shrink;
3921 free((char *)reloc_vector);
3922 return new;
3923 }
3924
3925 static bfd_byte *
3926 DEFUN(bfd_coff_get_relocated_section_contents,(in_abfd, seclet, data),
3927 bfd *in_abfd AND
3928 bfd_seclet_type *seclet AND
3929 bfd_byte *data)
3930
3931 {
3932 /* Get enough memory to hold the stuff */
3933 bfd *input_bfd = seclet->u.indirect.section->owner;
3934 asection *input_section = seclet->u.indirect.section;
3935 bfd_size_type reloc_size = bfd_get_reloc_upper_bound(input_bfd,
3936 input_section);
3937 arelent **reloc_vector = (arelent **)bfd_xmalloc(reloc_size);
3938
3939 /* read in the section */
3940 bfd_get_section_contents(input_bfd,
3941 input_section,
3942 data,
3943 0,
3944 input_section->_raw_size);
3945
3946
3947 if (bfd_canonicalize_reloc(input_bfd,
3948 input_section,
3949 reloc_vector,
3950 seclet->u.indirect.symbols) )
3951 {
3952 arelent **parent = reloc_vector;
3953 arelent *reloc ;
3954
3955
3956
3957 unsigned int dst_address = 0;
3958 unsigned int src_address = 0;
3959 unsigned int run;
3960 unsigned int idx;
3961
3962 /* Find how long a run we can do */
3963 while (dst_address < seclet->size)
3964 {
3965
3966 reloc = *parent;
3967 if (reloc)
3968 {
3969 /* Note that the relaxing didn't tie up the addresses in the
3970 relocation, so we use the original address to work out the
3971 run of non-relocated data */
3972 run = reloc->address - src_address;
3973 parent++;
3974
3975 }
3976 else
3977 {
3978 run = seclet->size - dst_address;
3979 }
3980 /* Copy the bytes */
3981 for (idx = 0; idx < run; idx++)
3982 {
3983 data[dst_address++] = data[src_address++];
3984 }
3985
3986 /* Now do the relocation */
3987
3988 if (reloc)
3989 {
3990 switch (reloc->howto->type)
3991 {
3992 case R_JMP2:
3993 /* Speciial relaxed type */
3994 {
3995 bfd_vma dot = seclet->offset + dst_address + seclet->u.indirect.section->output_section->vma;
3996 int gap = get_value(reloc,seclet)-dot-1;
3997 if ((gap & ~0xff ) != 0 &&((gap & 0xff00)!= 0xff00)) abort();
3998
3999 bfd_put_8(in_abfd,gap, data+dst_address);
4000
4001 switch (data[dst_address-1])
4002 {
4003
4004 case 0x5e:
4005 /* jsr -> bsr */
4006 bfd_put_8(in_abfd, 0x55, data+dst_address-1);
4007 break;
4008 case 0x5a:
4009 /* jmp ->bra */
4010 bfd_put_8(in_abfd, 0x40, data+dst_address-1);
4011 break;
4012
4013 default:
4014 abort();
4015
4016 }
4017
4018
4019
4020
4021 dst_address++;
4022 src_address+=3;
4023
4024 break;
4025 }
4026
4027
4028 case R_MOVB2:
4029 /* Special relaxed type, there will be a gap between where we
4030 get stuff from and where we put stuff to now
4031
4032 for a mov.b @aa:16 -> mov.b @aa:8
4033 opcode 0x6a 0x0y offset
4034 -> 0x2y off
4035 */
4036 if (data[dst_address-1] != 0x6a)
4037 abort();
4038 switch (data[dst_address] & 0xf0)
4039 {
4040 case 0x00:
4041 /* Src is memory */
4042 data[dst_address-1] = (data[src_address] & 0xf) | 0x20;
4043 break;
4044 case 0x80:
4045 /* Src is reg */
4046 data[dst_address-1] = (data[src_address] & 0xf) | 0x30;
4047 break;
4048 default:
4049 abort();
4050 }
4051
4052 /* the offset must fit ! after all, what was all the relaxing
4053 about ? */
4054
4055 bfd_put_8(in_abfd, get_value(reloc, seclet), data + dst_address);
4056
4057 /* Note the magic - src goes up by two bytes, but dst by only
4058 one */
4059 dst_address+=1;
4060 src_address+=3;
4061
4062 break;
4063 /* PCrel 8 bits */
4064 case R_PCRBYTE:
4065 {
4066 bfd_vma dot = seclet->offset + dst_address + seclet->u.indirect.section->output_section->vma;
4067 int gap = get_value(reloc,seclet)-dot;
4068 if (gap > 127 || gap < -128)
4069 {
4070 bfd_error_vector.reloc_value_truncated(reloc, seclet);
4071 }
4072
4073 bfd_put_8(in_abfd,gap, data+dst_address);
4074 dst_address++;
4075 src_address++;
4076
4077 break;
4078 }
4079
4080 case R_RELBYTE:
4081 {
4082 unsigned int gap =get_value(reloc,seclet);
4083 if (gap > 256)
4084 {
4085 bfd_error_vector.reloc_value_truncated(reloc, seclet);
4086 }
4087
4088 bfd_put_8(in_abfd, gap, data+dst_address);
4089 dst_address+=1;
4090 src_address+=1;
4091
4092
4093 }
4094 break;
4095 case R_JMP1:
4096 /* A relword which would have like to have been a pcrel */
4097 case R_MOVB1:
4098 /* A relword which would like to have been modified but
4099 didn't make it */
4100 case R_RELWORD:
4101 bfd_put_16(in_abfd, get_value(reloc,seclet), data+dst_address);
4102 dst_address+=2;
4103 src_address+=2;
4104 break;
4105
4106 default:
4107 abort();
4108 }
4109 }
4110 }
4111 }
4112 free((char *)reloc_vector);
4113 return data;
4114
4115 }
4116
4117
4118 #define coff_core_file_failing_command _bfd_dummy_core_file_failing_command
4119 #define coff_core_file_failing_signal _bfd_dummy_core_file_failing_signal
4120 #define coff_core_file_matches_executable_p _bfd_dummy_core_file_matches_executable_p
4121 #define coff_slurp_armap bfd_slurp_coff_armap
4122 #define coff_slurp_extended_name_table _bfd_slurp_extended_name_table
4123 #define coff_truncate_arname bfd_dont_truncate_arname
4124 #define coff_openr_next_archived_file bfd_generic_openr_next_archived_file
4125 #define coff_generic_stat_arch_elt bfd_generic_stat_arch_elt
4126 #define coff_get_section_contents bfd_generic_get_section_contents
4127 #define coff_close_and_cleanup bfd_generic_close_and_cleanup
4128
4129 #define coff_bfd_debug_info_start bfd_void
4130 #define coff_bfd_debug_info_end bfd_void
4131 #define coff_bfd_debug_info_accumulate (PROTO(void,(*),(bfd*, struct sec *))) bfd_void
4132 #define coff_bfd_get_relocated_section_contents bfd_generic_get_relocated_section_contents
4133 #define coff_bfd_relax_section bfd_generic_relax_section
4134
This page took 0.114796 seconds and 4 git commands to generate.