* gas/hppa/reloc/reloc.exp: Minor fixes so that SOM & ELF can
[deliverable/binutils-gdb.git] / bfd / coffgen.c
CommitLineData
075caafd 1/* Support for the generic parts of COFF, for BFD.
85fe7cff 2 Copyright 1990, 1991, 1992, 1993 Free Software Foundation, Inc.
075caafd
ILT
3 Written by Cygnus Support.
4
5This file is part of BFD, the Binary File Descriptor library.
6
7This program is free software; you can redistribute it and/or modify
8it under the terms of the GNU General Public License as published by
9the Free Software Foundation; either version 2 of the License, or
10(at your option) any later version.
11
12This program is distributed in the hope that it will be useful,
13but WITHOUT ANY WARRANTY; without even the implied warranty of
14MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15GNU General Public License for more details.
16
17You should have received a copy of the GNU General Public License
18along with this program; if not, write to the Free Software
19Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
20
21/* Most of this hacked by Steve Chamberlain, sac@cygnus.com.
22 Split out of coffcode.h by Ian Taylor, ian@cygnus.com. */
23
24/* This file contains COFF code that is not dependent on any
25 particular COFF target. There is only one version of this file in
26 libbfd.a, so no target specific code may be put in here. Or, to
27 put it another way,
28
29 ********** DO NOT PUT TARGET SPECIFIC CODE IN THIS FILE **********
30
31 If you need to add some target specific behaviour, add a new hook
32 function to bfd_coff_backend_data.
33
34 Some of these functions are also called by the ECOFF routines.
35 Those functions may not use any COFF specific information, such as
36 coff_data (abfd). */
37
38#include "bfd.h"
39#include "sysdep.h"
40#include "libbfd.h"
41#include "coff/internal.h"
a8ba7cc6 42#include "seclet.h"
075caafd
ILT
43#include "libcoff.h"
44
45static asection bfd_debug_section = { "*DEBUG*" };
46
47/* Take a section header read from a coff file (in HOST byte order),
48 and make a BFD "section" out of it. This is used by ECOFF. */
49static boolean
50DEFUN(make_a_section_from_file,(abfd, hdr, target_index),
51 bfd *abfd AND
52 struct internal_scnhdr *hdr AND
53 unsigned int target_index)
54{
55 asection *return_section;
56 char *name;
57
58 /* Assorted wastage to null-terminate the name, thanks AT&T! */
59 name = bfd_alloc(abfd, sizeof (hdr->s_name)+1);
60 if (name == NULL) {
61 bfd_error = no_memory;
62 return false;
63 }
64 strncpy(name, (char *) &hdr->s_name[0], sizeof (hdr->s_name));
65 name[sizeof (hdr->s_name)] = 0;
66
67 return_section = bfd_make_section(abfd, name);
68 if (return_section == NULL)
69 return_section = bfd_coff_make_section_hook (abfd, name);
70 if (return_section == NULL)
71 return false;
72
73 /* s_paddr is presumed to be = to s_vaddr */
74
75 return_section->vma = hdr->s_vaddr;
76 return_section->_raw_size = hdr->s_size;
77 return_section->filepos = hdr->s_scnptr;
78 return_section->rel_filepos = hdr->s_relptr;
79 return_section->reloc_count = hdr->s_nreloc;
80
81 bfd_coff_set_alignment_hook (abfd, return_section, hdr);
82
83 return_section->line_filepos = hdr->s_lnnoptr;
84
85 return_section->lineno_count = hdr->s_nlnno;
86 return_section->userdata = NULL;
87 return_section->next = (asection *) NULL;
88 return_section->flags = bfd_coff_styp_to_sec_flags_hook (abfd, hdr);
89
90 return_section->target_index = target_index;
91
2d1e6c9c
KR
92 /* At least on i386-coff, the line number count for a shared library
93 section must be ignored. */
94 if ((return_section->flags & SEC_SHARED_LIBRARY) != 0)
95 return_section->lineno_count = 0;
96
075caafd
ILT
97 if (hdr->s_nreloc != 0)
98 return_section->flags |= SEC_RELOC;
99 /* FIXME: should this check 'hdr->s_size > 0' */
100 if (hdr->s_scnptr != 0)
101 return_section->flags |= SEC_HAS_CONTENTS;
102 return true;
103}
104
105/* Read in a COFF object and make it into a BFD. This is used by
106 ECOFF as well. */
107
108static
109bfd_target *
110DEFUN(coff_real_object_p,(abfd, nscns, internal_f, internal_a),
111 bfd *abfd AND
112 unsigned nscns AND
113 struct internal_filehdr *internal_f AND
114 struct internal_aouthdr *internal_a)
115{
116 PTR tdata;
117 size_t readsize; /* length of file_info */
118 unsigned int scnhsz;
119 char *external_sections;
120
121 /* Build a play area */
27f524a3 122 tdata = bfd_coff_mkobject_hook (abfd, (PTR) internal_f, (PTR) internal_a);
075caafd
ILT
123 if (tdata == NULL)
124 return 0;
125
126 scnhsz = bfd_coff_scnhsz (abfd);
127 readsize = nscns * scnhsz;
128 external_sections = (char *)bfd_alloc(abfd, readsize);
129
130 if (bfd_read((PTR)external_sections, 1, readsize, abfd) != readsize) {
131 goto fail;
132 }
133
134 /* Now copy data as required; construct all asections etc */
135 if (nscns != 0) {
136 unsigned int i;
137 for (i = 0; i < nscns; i++) {
138 struct internal_scnhdr tmp;
139 bfd_coff_swap_scnhdr_in(abfd, (PTR) (external_sections + i * scnhsz),
140 (PTR) &tmp);
141 make_a_section_from_file(abfd,&tmp, i+1);
142 }
143 }
144
145/* make_abs_section(abfd);*/
146
147 if (bfd_coff_set_arch_mach_hook (abfd, (PTR) internal_f) == false)
148 goto fail;
149
150 if (!(internal_f->f_flags & F_RELFLG))
151 abfd->flags |= HAS_RELOC;
152 if ((internal_f->f_flags & F_EXEC))
153 abfd->flags |= EXEC_P;
154 if (!(internal_f->f_flags & F_LNNO))
155 abfd->flags |= HAS_LINENO;
156 if (!(internal_f->f_flags & F_LSYMS))
157 abfd->flags |= HAS_LOCALS;
158
159
160 bfd_get_symcount(abfd) = internal_f->f_nsyms;
161 if (internal_f->f_nsyms)
162 abfd->flags |= HAS_SYMS;
163
27f524a3
ILT
164 if (internal_a != (struct internal_aouthdr *) NULL)
165 bfd_get_start_address (abfd) = internal_a->entry;
166 else
167 bfd_get_start_address (abfd) = 0;
075caafd
ILT
168
169 return abfd->xvec;
170 fail:
171 bfd_release(abfd, tdata);
172 return (bfd_target *)NULL;
173}
174
175/* Turn a COFF file into a BFD, but fail with wrong_format if it is
176 not a COFF file. This is also used by ECOFF. */
177
178bfd_target *
179DEFUN(coff_object_p,(abfd),
180 bfd *abfd)
181{
182 unsigned int filhsz;
183 unsigned int aoutsz;
184 int nscns;
185 PTR filehdr;
186 struct internal_filehdr internal_f;
187 struct internal_aouthdr internal_a;
188
189 bfd_error = system_call_error;
190
191 /* figure out how much to read */
192 filhsz = bfd_coff_filhsz (abfd);
193 aoutsz = bfd_coff_aoutsz (abfd);
194
195 filehdr = bfd_alloc (abfd, filhsz);
196 if (filehdr == NULL)
197 return 0;
198 if (bfd_read(filehdr, 1, filhsz, abfd) != filhsz)
199 return 0;
200 bfd_coff_swap_filehdr_in(abfd, filehdr, &internal_f);
201 bfd_release (abfd, filehdr);
202
203 if (bfd_coff_bad_format_hook (abfd, &internal_f) == false) {
204 bfd_error = wrong_format;
205 return 0;
206 }
207 nscns =internal_f.f_nscns;
208
209 if (internal_f.f_opthdr) {
210 PTR opthdr;
211
212 opthdr = bfd_alloc (abfd, aoutsz);
213 if (opthdr == NULL)
214 return 0;;
215 if (bfd_read(opthdr, 1,aoutsz, abfd) != aoutsz) {
216 return 0;
217 }
218 bfd_coff_swap_aouthdr_in(abfd, opthdr, (PTR)&internal_a);
219 }
220
221 /* Seek past the opt hdr stuff */
222 bfd_seek(abfd, (file_ptr) (internal_f.f_opthdr + filhsz), SEEK_SET);
223
27f524a3
ILT
224 return coff_real_object_p(abfd, nscns, &internal_f,
225 (internal_f.f_opthdr != 0
226 ? &internal_a
227 : (struct internal_aouthdr *) NULL));
075caafd
ILT
228}
229
230/* Get the BFD section from a COFF symbol section number. */
231
232struct sec *
233DEFUN(coff_section_from_bfd_index,(abfd, index),
234 bfd *abfd AND
235 int index)
236{
237 struct sec *answer = abfd->sections;
238
239 if (index == N_ABS)
240 {
241 return &bfd_abs_section;
242 }
243 if (index == N_UNDEF)
244 {
245 return &bfd_und_section;
246 }
247 if(index == N_DEBUG)
248 {
249 return &bfd_debug_section;
250
251 }
252
253 while (answer) {
254 if (answer->target_index == index)
255 return answer;
256 answer = answer->next;
257 }
258 BFD_ASSERT(0);
259 return &bfd_und_section; /* For gcc -W and lint. Never executed. */
260}
261
262/* Get the upper bound of a COFF symbol table. */
263
264unsigned int
265coff_get_symtab_upper_bound(abfd)
266bfd *abfd;
267{
268 if (!bfd_coff_slurp_symbol_table(abfd))
269 return 0;
270
271 return (bfd_get_symcount(abfd) + 1) * (sizeof(coff_symbol_type *));
272}
273
274
275/* Canonicalize a COFF symbol table. */
276
277unsigned int
278DEFUN(coff_get_symtab, (abfd, alocation),
279 bfd *abfd AND
280 asymbol **alocation)
281{
282 unsigned int counter = 0;
283 coff_symbol_type *symbase;
284 coff_symbol_type **location = (coff_symbol_type **) (alocation);
285 if (!bfd_coff_slurp_symbol_table(abfd))
286 return 0;
287
288 symbase = obj_symbols(abfd);
289 while (counter < bfd_get_symcount(abfd))
290 {
291 /* This nasty code looks at the symbol to decide whether or
292 not it is descibes a constructor/destructor entry point. It
293 is structured this way to (hopefully) speed non matches */
294#if 0
295 if (0 && symbase->symbol.name[9] == '$')
296 {
297 bfd_constructor_entry(abfd,
298 (asymbol **)location,
299 symbase->symbol.name[10] == 'I' ?
300 "CTOR" : "DTOR");
301 }
302#endif
303 *(location++) = symbase++;
304 counter++;
305 }
306 *location++ = 0;
307 return bfd_get_symcount(abfd);
308}
309
310/* Set lineno_count for the output sections of a COFF file. */
311
27f524a3 312int
075caafd
ILT
313DEFUN(coff_count_linenumbers,(abfd),
314 bfd *abfd)
315{
316 unsigned int limit = bfd_get_symcount(abfd);
317 unsigned int i;
27f524a3 318 int total = 0;
075caafd 319 asymbol **p;
27f524a3
ILT
320 {
321 asection *s = abfd->sections->output_section;
322 while (s) {
323 BFD_ASSERT(s->lineno_count == 0);
324 s = s->next;
325 }
326 }
075caafd
ILT
327
328
329 for (p = abfd->outsymbols, i = 0; i < limit; i++, p++) {
330 asymbol *q_maybe = *p;
331 if (bfd_asymbol_flavour(q_maybe) == bfd_target_coff_flavour) {
332 coff_symbol_type *q = coffsymbol(q_maybe);
333 if (q->lineno) {
334 /*
335 This symbol has a linenumber, increment the owning
336 section's linenumber count
337 */
338 alent *l = q->lineno;
339 q->symbol.section->output_section->lineno_count++;
27f524a3 340 total ++;
075caafd
ILT
341 l++;
342 while (l->line_number) {
27f524a3 343 total ++;
075caafd
ILT
344 q->symbol.section->output_section->lineno_count++;
345 l++;
346 }
347 }
348 }
349 }
27f524a3 350 return total;
075caafd
ILT
351}
352
353/* Takes a bfd and a symbol, returns a pointer to the coff specific
354 area of the symbol if there is one. */
355
356coff_symbol_type *
357DEFUN(coff_symbol_from,(ignore_abfd, symbol),
358 bfd *ignore_abfd AND
359 asymbol *symbol)
360{
361 if (bfd_asymbol_flavour(symbol) != bfd_target_coff_flavour)
362 return (coff_symbol_type *)NULL;
363
364 if (bfd_asymbol_bfd(symbol)->tdata.coff_obj_data == (coff_data_type*)NULL)
365 return (coff_symbol_type *)NULL;
366
367 return (coff_symbol_type *) symbol;
368}
369
370static void
371DEFUN(fixup_symbol_value,(coff_symbol_ptr, syment),
372coff_symbol_type *coff_symbol_ptr AND
373struct internal_syment *syment)
374{
375
376 /* Normalize the symbol flags */
e61cfdf8 377 if (bfd_is_com_section (coff_symbol_ptr->symbol.section)) {
075caafd
ILT
378 /* a common symbol is undefined with a value */
379 syment->n_scnum = N_UNDEF;
380 syment->n_value = coff_symbol_ptr->symbol.value;
381 }
382 else if (coff_symbol_ptr->symbol.flags & BSF_DEBUGGING) {
383 syment->n_value = coff_symbol_ptr->symbol.value;
384 }
385 else if (coff_symbol_ptr->symbol.section == & bfd_und_section) {
386 syment->n_scnum = N_UNDEF;
387 syment->n_value = 0;
388 }
389 else {
390 if (coff_symbol_ptr->symbol.section) {
391 syment->n_scnum =
392 coff_symbol_ptr->symbol.section->output_section->target_index;
393
394 syment->n_value =
395 coff_symbol_ptr->symbol.value +
396 coff_symbol_ptr->symbol.section->output_offset +
397 coff_symbol_ptr->symbol.section->output_section->vma;
398 }
399 else {
400 BFD_ASSERT(0);
401 /* This can happen, but I don't know why yet (steve@cygnus.com) */
402 syment->n_scnum = N_ABS;
403 syment->n_value = coff_symbol_ptr->symbol.value;
404 }
405 }
406}
407
408/* run through all the symbols in the symbol table and work out what
409 their indexes into the symbol table will be when output
410
411 Coff requires that each C_FILE symbol points to the next one in the
412 chain, and that the last one points to the first external symbol. We
413 do that here too.
414
415*/
416void
417DEFUN(coff_renumber_symbols,(bfd_ptr),
418 bfd *bfd_ptr)
419{
420 unsigned int symbol_count = bfd_get_symcount(bfd_ptr);
421 asymbol **symbol_ptr_ptr = bfd_ptr->outsymbols;
422 unsigned int native_index = 0;
423 struct internal_syment *last_file = (struct internal_syment *)NULL;
424 unsigned int symbol_index;
425
426 /* COFF demands that undefined symbols come after all other symbols.
427 Since we don't need to impose this extra knowledge on all our client
428 programs, deal with that here. Sort the symbol table; just move the
429 undefined symbols to the end, leaving the rest alone. */
430 /* @@ Do we have some condition we could test for, so we don't always
431 have to do this? I don't think relocatability is quite right, but
432 I'm not certain. [raeburn:19920508.1711EST] */
433 {
434 asymbol **newsyms;
435 int i;
436
437 newsyms = (asymbol **) bfd_alloc_by_size_t (bfd_ptr,
438 sizeof (asymbol *)
439 * (symbol_count + 1));
440 bfd_ptr->outsymbols = newsyms;
441 for (i = 0; i < symbol_count; i++)
442 if (symbol_ptr_ptr[i]->section != &bfd_und_section)
443 *newsyms++ = symbol_ptr_ptr[i];
444 for (i = 0; i < symbol_count; i++)
445 if (symbol_ptr_ptr[i]->section == &bfd_und_section)
446 *newsyms++ = symbol_ptr_ptr[i];
447 *newsyms = (asymbol *) NULL;
448 symbol_ptr_ptr = bfd_ptr->outsymbols;
449 }
450
451 for (symbol_index = 0; symbol_index < symbol_count; symbol_index++)
452 {
453 coff_symbol_type *coff_symbol_ptr = coff_symbol_from(bfd_ptr, symbol_ptr_ptr[symbol_index]);
454 if (coff_symbol_ptr && coff_symbol_ptr->native) {
455 combined_entry_type *s = coff_symbol_ptr->native;
456 int i;
457
458 if (s->u.syment.n_sclass == C_FILE)
459 {
460 if (last_file != (struct internal_syment *)NULL) {
461 last_file->n_value = native_index;
462 }
463 last_file = &(s->u.syment);
464 }
465 else {
466
467 /* Modify the symbol values according to their section and
468 type */
469
470 fixup_symbol_value(coff_symbol_ptr, &(s->u.syment));
471 }
472 for (i = 0; i < s->u.syment.n_numaux + 1; i++) {
473 s[i].offset = native_index ++;
474 }
475 }
476 else {
477 native_index++;
478 }
479 }
480 obj_conv_table_size (bfd_ptr) = native_index;
481}
482
483/*
484 Run thorough the symbol table again, and fix it so that all pointers to
485 entries are changed to the entries' index in the output symbol table.
486
487*/
488void
489DEFUN(coff_mangle_symbols,(bfd_ptr),
490 bfd *bfd_ptr)
491{
492 unsigned int symbol_count = bfd_get_symcount(bfd_ptr);
493 asymbol **symbol_ptr_ptr = bfd_ptr->outsymbols;
494 unsigned int symbol_index;
495
496 for (symbol_index = 0; symbol_index < symbol_count; symbol_index++)
497 {
498 coff_symbol_type *coff_symbol_ptr =
499 coff_symbol_from(bfd_ptr, symbol_ptr_ptr[symbol_index]);
500
501 if (coff_symbol_ptr && coff_symbol_ptr->native) {
502 int i;
503 combined_entry_type *s = coff_symbol_ptr->native;
504
505 for (i = 0; i < s->u.syment.n_numaux ; i++) {
506 combined_entry_type *a = s + i + 1;
507 if (a->fix_tag) {
508 a->u.auxent.x_sym.x_tagndx.l =
509 a->u.auxent.x_sym.x_tagndx.p->offset;
510 a->fix_tag = 0;
511 }
512 if (a->fix_end) {
513 a->u.auxent.x_sym.x_fcnary.x_fcn.x_endndx.l =
514 a->u.auxent.x_sym.x_fcnary.x_fcn.x_endndx.p->offset;
515 a->fix_end = 0;
516
517 }
518
519 }
520 }
521 }
522}
523
524static int string_size;
525
526static void
527DEFUN(coff_fix_symbol_name,(abfd, symbol, native),
528 bfd *abfd AND
529 asymbol *symbol AND
530 combined_entry_type *native)
531{
532 unsigned int name_length;
533 union internal_auxent *auxent;
534 char * name = ( char *)(symbol->name);
535
536 if (name == (char *) NULL) {
537 /* coff symbols always have names, so we'll make one up */
538 symbol->name = "strange";
539 name = (char *)symbol->name;
540 }
541 name_length = strlen(name);
542
543 if (native->u.syment.n_sclass == C_FILE) {
544 strncpy(native->u.syment._n._n_name, ".file", SYMNMLEN);
545 auxent = &(native+1)->u.auxent;
546
547 if (bfd_coff_long_filenames (abfd)) {
548 if (name_length <= FILNMLEN) {
549 strncpy(auxent->x_file.x_fname, name, FILNMLEN);
550 }
551 else {
552 auxent->x_file.x_n.x_offset = string_size + 4;
553 auxent->x_file.x_n.x_zeroes = 0;
554 string_size += name_length + 1;
555 }
556 }
557 else {
558 strncpy(auxent->x_file.x_fname, name, FILNMLEN);
559 if (name_length > FILNMLEN) {
560 name[FILNMLEN] = '\0';
561 }
562 }
563 }
564 else
565 { /* NOT A C_FILE SYMBOL */
566 if (name_length <= SYMNMLEN) {
567 /* This name will fit into the symbol neatly */
568 strncpy(native->u.syment._n._n_name, symbol->name, SYMNMLEN);
569 }
570 else {
571 native->u.syment._n._n_n._n_offset = string_size + 4;
572 native->u.syment._n._n_n._n_zeroes = 0;
573 string_size += name_length + 1;
574 }
575 }
576}
577
578#define set_index(symbol, idx) ((symbol)->udata =(PTR) (idx))
579
580static unsigned int
581DEFUN(coff_write_symbol,(abfd, symbol, native, written),
582bfd *abfd AND
583asymbol *symbol AND
584combined_entry_type *native AND
585unsigned int written)
586{
587 unsigned int numaux = native->u.syment.n_numaux;
588 int type = native->u.syment.n_type;
589 int class = native->u.syment.n_sclass;
590 PTR buf;
591 bfd_size_type symesz;
592
593 /* @@ bfd_debug_section isn't accessible outside this file, but we know
594 that C_FILE symbols belong there. So move them. */
595 if (native->u.syment.n_sclass == C_FILE)
596 symbol->section = &bfd_debug_section;
597
598 if (symbol->section == &bfd_abs_section)
599 {
600 native->u.syment.n_scnum = N_ABS;
601 }
602 else if (symbol->section == &bfd_debug_section)
603 {
604 native->u.syment.n_scnum = N_DEBUG;
605 }
606 else if (symbol->section == &bfd_und_section)
607 {
608 native->u.syment.n_scnum = N_UNDEF;
609 }
610 else
611 {
612 native->u.syment.n_scnum =
613 symbol->section->output_section->target_index;
614 }
615
616
617 coff_fix_symbol_name(abfd, symbol, native);
618
619 symesz = bfd_coff_symesz (abfd);
620 buf = bfd_alloc (abfd, symesz);
621 bfd_coff_swap_sym_out(abfd, &native->u.syment, buf);
622 bfd_write(buf, 1, symesz, abfd);
623 bfd_release (abfd, buf);
624
625 if (native->u.syment.n_numaux > 0)
626 {
627 bfd_size_type auxesz;
628 unsigned int j;
629
630 auxesz = bfd_coff_auxesz (abfd);
631 buf = bfd_alloc (abfd, auxesz);
632 for (j = 0; j < native->u.syment.n_numaux; j++)
633 {
634 bfd_coff_swap_aux_out(abfd,
635 &((native + j + 1)->u.auxent),
636 type,
637 class,
638 buf);
639 bfd_write(buf, 1, auxesz, abfd);
640 }
641 bfd_release (abfd, buf);
642 }
643 /*
644 Reuse somewhere in the symbol to keep the index
645 */
646 set_index(symbol, written);
647 return written + 1 + numaux;
648}
649
650
651static unsigned int
652DEFUN(coff_write_alien_symbol,(abfd, symbol, written),
653 bfd *abfd AND
654 asymbol *symbol AND
655 unsigned int written)
656{
657 /*
658 This symbol has been created by the loader, or come from a non
659 coff format. It has no native element to inherit, make our
660 own
661 */
662 combined_entry_type *native;
663 combined_entry_type dummy;
664 native = &dummy;
665 native->u.syment.n_type = T_NULL;
666 native->u.syment.n_flags = 0;
667 if (symbol->section == &bfd_und_section)
668 {
669 native->u.syment.n_scnum = N_UNDEF;
670 native->u.syment.n_value = symbol->value;
671 }
e61cfdf8 672 else if (bfd_is_com_section (symbol->section))
075caafd
ILT
673 {
674 native->u.syment.n_scnum = N_UNDEF;
675 native->u.syment.n_value = symbol->value;
676
677 }
678
679 else if (symbol->flags & BSF_DEBUGGING) {
680 /*
681 remove name so it doesn't take up any space
682 */
683 symbol->name = "";
684 }
685 else {
686 native->u.syment.n_scnum = symbol->section->output_section->target_index;
687 native->u.syment.n_value = symbol->value +
688 symbol->section->output_section->vma +
689 symbol->section->output_offset;
690 /* Copy the any flags from the the file hdr into the symbol */
691 {
692 coff_symbol_type *c = coff_symbol_from(abfd, symbol);
693 if (c != (coff_symbol_type *)NULL) {
694 native->u.syment.n_flags = bfd_asymbol_bfd(&c->symbol)->flags;
695 }
696 }
697 }
698
699 native->u.syment.n_type = 0;
700 if (symbol->flags & BSF_LOCAL)
701 native->u.syment.n_sclass = C_STAT;
702 else
703 native->u.syment.n_sclass = C_EXT;
704 native->u.syment.n_numaux = 0;
705
706 return coff_write_symbol(abfd, symbol, native, written);
707}
708
709static unsigned int
710DEFUN(coff_write_native_symbol,(abfd, symbol, written),
711bfd *abfd AND
712coff_symbol_type *symbol AND
713unsigned int written)
714{
715 /*
716 Does this symbol have an ascociated line number - if so then
717 make it remember this symbol index. Also tag the auxent of
718 this symbol to point to the right place in the lineno table
719 */
720 combined_entry_type *native = symbol->native;
721
722 alent *lineno = symbol->lineno;
723
724 if (lineno && !symbol->done_lineno) {
725 unsigned int count = 0;
726 lineno[count].u.offset = written;
727 if (native->u.syment.n_numaux) {
728 union internal_auxent *a = &((native+1)->u.auxent);
729
730 a->x_sym.x_fcnary.x_fcn.x_lnnoptr =
731 symbol->symbol.section->output_section->moving_line_filepos;
732 }
733 /*
734 And count and relocate all other linenumbers
735 */
736
737 count++;
738 while (lineno[count].line_number) {
739#if 0
740/* 13 april 92. sac
741I've been told this, but still need proof:
742> The second bug is also in `bfd/coffcode.h'. This bug causes the linker to screw
743> up the pc-relocations for all the line numbers in COFF code. This bug isn't
744> only specific to A29K implementations, but affects all systems using COFF
745> format binaries. Note that in COFF object files, the line number core offsets
746> output by the assembler are relative to the start of each procedure, not
747> to the start of the .text section. This patch relocates the line numbers
748> relative to the `native->u.syment.n_value' instead of the section virtual
749> address. modular!olson@cs.arizona.edu (Jon Olson)
750*/
751 lineno[count].u.offset += native->u.syment.n_value;
752
753#else
754 lineno[count].u.offset +=
755 symbol->symbol.section->output_section->vma +
756 symbol->symbol.section->output_offset;
757#endif
758 count++;
759 }
760 symbol->done_lineno = true;
761
762 symbol->symbol.section->output_section->moving_line_filepos +=
763 count * bfd_coff_linesz (abfd);
764 }
765 return coff_write_symbol(abfd, &( symbol->symbol), native,written);
766}
767
768void
769DEFUN(coff_write_symbols,(abfd),
770 bfd *abfd)
771{
772 unsigned int i;
773 unsigned int limit = bfd_get_symcount(abfd);
774 unsigned int written = 0;
775
776 asymbol **p;
777
778 string_size = 0;
779
780
781 /* Seek to the right place */
782 bfd_seek(abfd, obj_sym_filepos(abfd), SEEK_SET);
783
784 /* Output all the symbols we have */
785
786 written = 0;
787 for (p = abfd->outsymbols, i = 0; i < limit; i++, p++)
788 {
789 asymbol *symbol = *p;
790 coff_symbol_type *c_symbol = coff_symbol_from(abfd, symbol);
791
792 if (c_symbol == (coff_symbol_type *) NULL ||
793 c_symbol->native == (combined_entry_type *)NULL)
794 {
795 written = coff_write_alien_symbol(abfd, symbol, written);
796 }
797 else
798 {
799 written = coff_write_native_symbol(abfd, c_symbol, written);
800 }
801
802 }
803
804 bfd_get_symcount(abfd) = written;
805
806 /* Now write out strings */
807
808 if (string_size != 0)
809 {
810 unsigned int size = string_size + 4;
811 bfd_byte buffer[4];
812
813 bfd_h_put_32(abfd, size, buffer);
814 bfd_write((PTR) buffer, 1, sizeof(buffer), abfd);
815 for (p = abfd->outsymbols, i = 0;
816 i < limit;
817 i++, p++)
818 {
819 asymbol *q = *p;
820 size_t name_length = strlen(q->name);
821 int maxlen;
822 coff_symbol_type* c_symbol = coff_symbol_from(abfd, q);
823 maxlen = ((c_symbol != NULL && c_symbol->native != NULL) &&
824 (c_symbol->native->u.syment.n_sclass == C_FILE)) ?
825 FILNMLEN : SYMNMLEN;
826
827 if (name_length > maxlen) {
828 bfd_write((PTR) (q->name), 1, name_length + 1, abfd);
829 }
830 }
831 }
832 else {
833 /* We would normally not write anything here, but we'll write
834 out 4 so that any stupid coff reader which tries to read
2d1e6c9c
KR
835 the string table even when there isn't one won't croak. */
836 unsigned int size = 4;
837 bfd_byte buffer[4];
075caafd 838
2d1e6c9c
KR
839 bfd_h_put_32 (abfd, size, buffer);
840 bfd_write((PTR) buffer, 1, sizeof (buffer), abfd);
075caafd
ILT
841 }
842}
843
844void
845DEFUN(coff_write_linenumbers,(abfd),
846 bfd *abfd)
847{
848 asection *s;
849 bfd_size_type linesz;
850 PTR buff;
851
852 linesz = bfd_coff_linesz (abfd);
853 buff = bfd_alloc (abfd, linesz);
854 for (s = abfd->sections; s != (asection *) NULL; s = s->next) {
855 if (s->lineno_count) {
856 asymbol **q = abfd->outsymbols;
857 bfd_seek(abfd, s->line_filepos, SEEK_SET);
858 /* Find all the linenumbers in this section */
859 while (*q) {
860 asymbol *p = *q;
27f524a3
ILT
861 if (p->section->output_section == s) {
862 alent *l =
863 BFD_SEND(bfd_asymbol_bfd(p), _get_lineno, (bfd_asymbol_bfd(p), p));
864 if (l) {
865 /* Found a linenumber entry, output */
866 struct internal_lineno out;
867 memset( (PTR)&out, 0, sizeof(out));
868 out.l_lnno = 0;
075caafd
ILT
869 out.l_addr.l_symndx = l->u.offset;
870 bfd_coff_swap_lineno_out(abfd, &out, buff);
871 bfd_write(buff, 1, linesz, abfd);
872 l++;
27f524a3
ILT
873 while (l->line_number) {
874 out.l_lnno = l->line_number;
875 out.l_addr.l_symndx = l->u.offset;
876 bfd_coff_swap_lineno_out(abfd, &out, buff);
877 bfd_write(buff, 1, linesz, abfd);
878 l++;
879 }
075caafd
ILT
880 }
881 }
882 q++;
883 }
884 }
885 }
886 bfd_release (abfd, buff);
887}
888
889alent *
890DEFUN(coff_get_lineno,(ignore_abfd, symbol),
891 bfd *ignore_abfd AND
892 asymbol *symbol)
893{
894 return coffsymbol(symbol)->lineno;
895}
896
897asymbol *
898coff_section_symbol (abfd, name)
899 bfd *abfd;
900 char *name;
901{
902 asection *sec = bfd_make_section_old_way (abfd, name);
903 asymbol *sym;
904 combined_entry_type *csym;
905
906 sym = sec->symbol;
907 if (coff_symbol_from (abfd, sym))
908 csym = coff_symbol_from (abfd, sym)->native;
909 else
910 csym = 0;
911 /* Make sure back-end COFF stuff is there. */
912 if (csym == 0)
913 {
914 struct foo {
915 coff_symbol_type sym;
916 /* @@FIXME This shouldn't use a fixed size!! */
917 combined_entry_type e[10];
918 };
919 struct foo *f;
920 f = (struct foo *) bfd_alloc_by_size_t (abfd, sizeof (*f));
921 memset ((char *) f, 0, sizeof (*f));
922 coff_symbol_from (abfd, sym)->native = csym = f->e;
923 }
924 csym[0].u.syment.n_sclass = C_STAT;
925 csym[0].u.syment.n_numaux = 1;
926/* SF_SET_STATICS (sym); @@ ??? */
927 if (sec)
928 {
929 csym[1].u.auxent.x_scn.x_scnlen = sec->_raw_size;
930 csym[1].u.auxent.x_scn.x_nreloc = sec->reloc_count;
931 csym[1].u.auxent.x_scn.x_nlinno = sec->lineno_count;
932 }
933 else
934 {
935 csym[1].u.auxent.x_scn.x_scnlen = 0;
936 csym[1].u.auxent.x_scn.x_nreloc = 0;
937 csym[1].u.auxent.x_scn.x_nlinno = 0;
938 }
939 return sym;
940}
941
942/* This function transforms the offsets into the symbol table into
943 pointers to syments. */
944
945static void
946DEFUN(coff_pointerize_aux,(abfd, table_base, type, class, auxent),
947bfd *abfd AND
948combined_entry_type *table_base AND
949int type AND
950int class AND
951combined_entry_type *auxent)
952{
953 /* Don't bother if this is a file or a section */
954 if (class == C_STAT && type == T_NULL) return;
955 if (class == C_FILE) return;
956
957 /* Otherwise patch up */
958#define N_TMASK coff_data (abfd)->local_n_tmask
959#define N_BTSHFT coff_data (abfd)->local_n_btshft
960 if (ISFCN(type) || ISTAG(class) || class == C_BLOCK) {
961 auxent->u.auxent.x_sym.x_fcnary.x_fcn.x_endndx.p = table_base +
962 auxent->u.auxent.x_sym.x_fcnary.x_fcn.x_endndx.l;
963 auxent->fix_end = 1;
964 }
965 /* A negative tagndx is meaningless, but the SCO 3.2v4 cc can
966 generate one, so we must be careful to ignore it. */
967 if (auxent->u.auxent.x_sym.x_tagndx.l > 0) {
968 auxent->u.auxent.x_sym.x_tagndx.p =
969 table_base + auxent->u.auxent.x_sym.x_tagndx.l;
970 auxent->fix_tag = 1;
971 }
972}
973
974static char *
975DEFUN(build_string_table,(abfd),
976bfd *abfd)
977{
978 char string_table_size_buffer[4];
979 unsigned int string_table_size;
980 char *string_table;
981
982 /* At this point we should be "seek"'d to the end of the
983 symbols === the symbol table size. */
984 if (bfd_read((char *) string_table_size_buffer,
985 sizeof(string_table_size_buffer),
986 1, abfd) != sizeof(string_table_size)) {
987 bfd_error = system_call_error;
988 return (NULL);
989 } /* on error */
990
991 string_table_size = bfd_h_get_32(abfd, (bfd_byte *) string_table_size_buffer);
992
993 if ((string_table = (PTR) bfd_alloc(abfd, string_table_size -= 4)) == NULL) {
994 bfd_error = no_memory;
995 return (NULL);
996 } /* on mallocation error */
997 if (bfd_read(string_table, string_table_size, 1, abfd) != string_table_size) {
998 bfd_error = system_call_error;
999 return (NULL);
1000 }
1001 return string_table;
1002}
1003
1004/* Allocate space for the ".debug" section, and read it.
1005 We did not read the debug section until now, because
1006 we didn't want to go to the trouble until someone needed it. */
1007
1008static char *
1009DEFUN(build_debug_section,(abfd),
1010 bfd *abfd)
1011{
1012 char *debug_section;
1013 long position;
1014
1015 asection *sect = bfd_get_section_by_name (abfd, ".debug");
1016
1017 if (!sect) {
1018 bfd_error = no_debug_section;
1019 return NULL;
1020 }
1021
1022 debug_section = (PTR) bfd_alloc (abfd,
1023 bfd_get_section_size_before_reloc (sect));
1024 if (debug_section == NULL) {
1025 bfd_error = no_memory;
1026 return NULL;
1027 }
1028
1029 /* Seek to the beginning of the `.debug' section and read it.
1030 Save the current position first; it is needed by our caller.
1031 Then read debug section and reset the file pointer. */
1032
1033 position = bfd_tell (abfd);
1034 bfd_seek (abfd, sect->filepos, SEEK_SET);
1035 if (bfd_read (debug_section,
1036 bfd_get_section_size_before_reloc (sect), 1, abfd)
1037 != bfd_get_section_size_before_reloc(sect)) {
1038 bfd_error = system_call_error;
1039 return NULL;
1040 }
1041 bfd_seek (abfd, position, SEEK_SET);
1042 return debug_section;
1043}
1044
1045
1046/* Return a pointer to a malloc'd copy of 'name'. 'name' may not be
1047 \0-terminated, but will not exceed 'maxlen' characters. The copy *will*
1048 be \0-terminated. */
1049static char *
1050DEFUN(copy_name,(abfd, name, maxlen),
1051 bfd *abfd AND
1052 char *name AND
1053 int maxlen)
1054{
1055 int len;
1056 char *newname;
1057
1058 for (len = 0; len < maxlen; ++len) {
1059 if (name[len] == '\0') {
1060 break;
1061 }
1062 }
1063
1064 if ((newname = (PTR) bfd_alloc(abfd, len+1)) == NULL) {
1065 bfd_error = no_memory;
1066 return (NULL);
1067 }
1068 strncpy(newname, name, len);
1069 newname[len] = '\0';
1070 return newname;
1071}
1072
1073/* Read a symbol table into freshly bfd_allocated memory, swap it, and
1074 knit the symbol names into a normalized form. By normalized here I
1075 mean that all symbols have an n_offset pointer that points to a null-
1076 terminated string. */
1077
1078combined_entry_type *
1079DEFUN(coff_get_normalized_symtab,(abfd),
1080bfd *abfd)
1081{
1082 combined_entry_type *internal;
1083 combined_entry_type *internal_ptr;
1084 combined_entry_type *symbol_ptr;
1085 combined_entry_type *internal_end;
1086 bfd_size_type symesz;
1087 PTR raw;
1088 char *raw_src;
1089 char *raw_end;
1090 char *string_table = NULL;
1091 char *debug_section = NULL;
1092 unsigned long size;
1093
1094 unsigned int raw_size;
1095 if (obj_raw_syments(abfd) != (combined_entry_type *)NULL) {
1096 return obj_raw_syments(abfd);
1097 }
1098 if ((size = bfd_get_symcount(abfd) * sizeof(combined_entry_type)) == 0) {
1099 bfd_error = no_symbols;
1100 return (NULL);
1101 }
1102
1103 internal = (combined_entry_type *)bfd_alloc(abfd, size);
1104 internal_end = internal + bfd_get_symcount(abfd);
1105
1106 symesz = bfd_coff_symesz (abfd);
1107 raw_size = bfd_get_symcount(abfd) * symesz;
1108 raw = bfd_alloc(abfd,raw_size);
1109
1110 if (bfd_seek(abfd, obj_sym_filepos(abfd), SEEK_SET) == -1
1111 || bfd_read(raw, raw_size, 1, abfd) != raw_size) {
1112 bfd_error = system_call_error;
1113 return (NULL);
1114 }
1115 /* mark the end of the symbols */
1116 raw_end = (char *) raw + bfd_get_symcount(abfd) * symesz;
1117 /*
1118 FIXME SOMEDAY. A string table size of zero is very weird, but
1119 probably possible. If one shows up, it will probably kill us.
1120 */
1121
1122 /* Swap all the raw entries */
1123 for (raw_src = (char *) raw, internal_ptr = internal;
1124 raw_src < raw_end;
1125 raw_src += symesz, internal_ptr++) {
1126
1127 unsigned int i;
1128 bfd_coff_swap_sym_in(abfd, (PTR)raw_src, (PTR)&internal_ptr->u.syment);
1129 internal_ptr->fix_tag = 0;
1130 internal_ptr->fix_end = 0;
1131 symbol_ptr = internal_ptr;
85fe7cff 1132
075caafd
ILT
1133 for (i = 0;
1134 i < symbol_ptr->u.syment.n_numaux;
1135 i++)
1136 {
1137 internal_ptr++;
1138 raw_src += symesz;
1139
1140 internal_ptr->fix_tag = 0;
1141 internal_ptr->fix_end = 0;
1142 bfd_coff_swap_aux_in(abfd, (PTR) raw_src,
1143 symbol_ptr->u.syment.n_type,
1144 symbol_ptr->u.syment.n_sclass,
1145 &(internal_ptr->u.auxent));
1146 /* Remember that bal entries arn't pointerized */
1147 if (i != 1 || symbol_ptr->u.syment.n_sclass != C_LEAFPROC)
1148 {
1149
1150 coff_pointerize_aux(abfd,
1151 internal,
1152 symbol_ptr->u.syment.n_type,
1153 symbol_ptr->u.syment.n_sclass,
1154 internal_ptr);
1155 }
1156
1157 }
1158 }
1159
1160 /* Free all the raw stuff */
1161 bfd_release(abfd, raw);
1162
1163 for (internal_ptr = internal; internal_ptr < internal_end;
1164 internal_ptr ++)
1165 {
1166 if (internal_ptr->u.syment.n_sclass == C_FILE) {
1167 /* make a file symbol point to the name in the auxent, since
1168 the text ".file" is redundant */
1169 if ((internal_ptr+1)->u.auxent.x_file.x_n.x_zeroes == 0) {
1170 /* the filename is a long one, point into the string table */
1171 if (string_table == NULL) {
1172 string_table = build_string_table(abfd);
1173 }
1174
1175 internal_ptr->u.syment._n._n_n._n_offset =
e4b6b3e7 1176 (long) (string_table - 4 +
075caafd
ILT
1177 (internal_ptr+1)->u.auxent.x_file.x_n.x_offset);
1178 }
1179 else {
1180 /* ordinary short filename, put into memory anyway */
e4b6b3e7 1181 internal_ptr->u.syment._n._n_n._n_offset = (long)
075caafd
ILT
1182 copy_name(abfd, (internal_ptr+1)->u.auxent.x_file.x_fname,
1183 FILNMLEN);
1184 }
1185 }
1186 else {
1187 if (internal_ptr->u.syment._n._n_n._n_zeroes != 0) {
1188 /* This is a "short" name. Make it long. */
1189 unsigned long i = 0;
1190 char *newstring = NULL;
1191
1192 /* find the length of this string without walking into memory
1193 that isn't ours. */
1194 for (i = 0; i < 8; ++i) {
1195 if (internal_ptr->u.syment._n._n_name[i] == '\0') {
1196 break;
1197 } /* if end of string */
1198 } /* possible lengths of this string. */
1199
1200 if ((newstring = (PTR) bfd_alloc(abfd, ++i)) == NULL) {
1201 bfd_error = no_memory;
1202 return (NULL);
1203 } /* on error */
1204 memset(newstring, 0, i);
1205 strncpy(newstring, internal_ptr->u.syment._n._n_name, i-1);
e4b6b3e7 1206 internal_ptr->u.syment._n._n_n._n_offset = (long int) newstring;
075caafd
ILT
1207 internal_ptr->u.syment._n._n_n._n_zeroes = 0;
1208 }
1209 else if (!bfd_coff_symname_in_debug(abfd, &internal_ptr->u.syment)) {
1210 /* Long name already. Point symbol at the string in the table. */
1211 if (string_table == NULL) {
1212 string_table = build_string_table(abfd);
1213 }
e4b6b3e7 1214 internal_ptr->u.syment._n._n_n._n_offset = (long int)
075caafd
ILT
1215 (string_table - 4 + internal_ptr->u.syment._n._n_n._n_offset);
1216 }
1217 else {
1218 /* Long name in debug section. Very similar. */
1219 if (debug_section == NULL) {
1220 debug_section = build_debug_section(abfd);
1221 }
e4b6b3e7 1222 internal_ptr->u.syment._n._n_n._n_offset = (long int)
075caafd
ILT
1223 (debug_section + internal_ptr->u.syment._n._n_n._n_offset);
1224 }
1225 }
1226 internal_ptr += internal_ptr->u.syment.n_numaux;
1227 }
1228
1229 obj_raw_syments(abfd) = internal;
85fe7cff 1230 obj_raw_syment_count(abfd) = internal_ptr - internal;
075caafd
ILT
1231
1232 return (internal);
1233} /* coff_get_normalized_symtab() */
1234
1235unsigned int
1236DEFUN (coff_get_reloc_upper_bound, (abfd, asect),
1237 bfd *abfd AND
1238 sec_ptr asect)
1239{
1240 if (bfd_get_format(abfd) != bfd_object) {
1241 bfd_error = invalid_operation;
1242 return 0;
1243 }
1244 return (asect->reloc_count + 1) * sizeof(arelent *);
1245}
1246
1247asymbol *
1248DEFUN (coff_make_empty_symbol, (abfd),
1249 bfd *abfd)
1250{
1251 coff_symbol_type *new = (coff_symbol_type *) bfd_alloc(abfd, sizeof(coff_symbol_type));
1252 if (new == NULL) {
1253 bfd_error = no_memory;
1254 return (NULL);
1255 } /* on error */
1256 new->symbol.section = 0;
1257 new->native = 0;
1258 new->lineno = (alent *) NULL;
1259 new->done_lineno = false;
1260 new->symbol.the_bfd = abfd;
1261 return &new->symbol;
1262}
1263
2d1e6c9c
KR
1264/* Make a debugging symbol. */
1265
075caafd 1266asymbol *
2d1e6c9c
KR
1267coff_bfd_make_debug_symbol (abfd, ptr, sz)
1268 bfd *abfd;
1269 PTR ptr;
1270 unsigned long sz;
075caafd
ILT
1271{
1272 coff_symbol_type *new = (coff_symbol_type *) bfd_alloc(abfd, sizeof(coff_symbol_type));
1273 if (new == NULL) {
1274 bfd_error = no_memory;
1275 return (NULL);
1276 } /* on error */
1277 /* @@ This shouldn't be using a constant multiplier. */
1278 new->native = (combined_entry_type *) bfd_zalloc (abfd, sizeof (combined_entry_type) * 10);
1279 new->symbol.section = &bfd_debug_section;
1280 new->lineno = (alent *) NULL;
1281 new->done_lineno = false;
1282 new->symbol.the_bfd = abfd;
1283 return &new->symbol;
1284}
1285
2d1e6c9c
KR
1286void
1287coff_get_symbol_info (abfd, symbol, ret)
1288 bfd *abfd;
1289 asymbol *symbol;
1290 symbol_info *ret;
1291{
1292 bfd_symbol_info (symbol, ret);
1293}
1294
e61cfdf8
ILT
1295/* Print out information about COFF symbol. */
1296
075caafd 1297void
e61cfdf8
ILT
1298coff_print_symbol (abfd, filep, symbol, how)
1299 bfd *abfd;
1300 PTR filep;
1301 asymbol *symbol;
1302 bfd_print_symbol_type how;
075caafd 1303{
e61cfdf8
ILT
1304 FILE *file = (FILE *) filep;
1305
1306 switch (how)
1307 {
075caafd 1308 case bfd_print_symbol_name:
e61cfdf8 1309 fprintf (file, "%s", symbol->name);
075caafd 1310 break;
e61cfdf8 1311
075caafd 1312 case bfd_print_symbol_more:
e61cfdf8
ILT
1313 fprintf (file, "coff %s %s",
1314 coffsymbol(symbol)->native ? "n" : "g",
1315 coffsymbol(symbol)->lineno ? "l" : " ");
075caafd 1316 break;
075caafd 1317
e61cfdf8 1318 case bfd_print_symbol_all:
075caafd 1319 if (coffsymbol(symbol)->native)
075caafd 1320 {
e61cfdf8
ILT
1321 unsigned int aux;
1322 combined_entry_type *combined = coffsymbol (symbol)->native;
1323 combined_entry_type *root = obj_raw_syments (abfd);
1324 struct lineno_cache_entry *l = coffsymbol(symbol)->lineno;
1325
1326 fprintf (file,"[%3d]", combined - root);
1327
1328 fprintf (file,
1329 "(sc %2d)(fl 0x%02x)(ty %3x)(sc %3d) (nx %d) 0x%08x %s",
1330 combined->u.syment.n_scnum,
1331 combined->u.syment.n_flags,
1332 combined->u.syment.n_type,
1333 combined->u.syment.n_sclass,
1334 combined->u.syment.n_numaux,
1335 combined->u.syment.n_value,
1336 symbol->name);
1337
1338 for (aux = 0; aux < combined->u.syment.n_numaux; aux++)
1339 {
1340 combined_entry_type *auxp = combined + aux + 1;
1341 long tagndx;
1342
1343 if (auxp->fix_tag)
1344 tagndx = auxp->u.auxent.x_sym.x_tagndx.p - root;
1345 else
1346 tagndx = auxp->u.auxent.x_sym.x_tagndx.l;
1347
1348 fprintf (file, "\n");
1349 switch (combined->u.syment.n_sclass)
1350 {
1351 case C_FILE:
1352 fprintf (file, "File ");
1353 break;
1354 default:
1355
1356 fprintf (file, "AUX lnno %d size 0x%x tagndx %d",
1357 auxp->u.auxent.x_sym.x_misc.x_lnsz.x_lnno,
1358 auxp->u.auxent.x_sym.x_misc.x_lnsz.x_size,
1359 tagndx);
1360 break;
1361 }
075caafd 1362 }
075caafd 1363
e61cfdf8
ILT
1364 if (l)
1365 {
e4b6b3e7 1366 fprintf (file, "\n%s :", l->u.sym->name);
e61cfdf8
ILT
1367 l++;
1368 while (l->line_number)
1369 {
e4b6b3e7 1370 fprintf (file, "\n%4d : 0x%x",
e61cfdf8
ILT
1371 l->line_number,
1372 l->u.offset);
1373 l++;
1374 }
1375 }
1376 }
1377 else
075caafd 1378 {
e61cfdf8
ILT
1379 bfd_print_symbol_vandf ((PTR) file, symbol);
1380 fprintf (file, " %-5s %s %s %s",
1381 symbol->section->name,
1382 coffsymbol(symbol)->native ? "n" : "g",
1383 coffsymbol(symbol)->lineno ? "l" : " ",
1384 symbol->name);
075caafd 1385 }
075caafd
ILT
1386 }
1387}
1388
1389/* Provided a BFD, a section and an offset into the section, calculate
1390 and return the name of the source file and the line nearest to the
1391 wanted location. */
1392
1393boolean
1394DEFUN(coff_find_nearest_line,(abfd,
1395 section,
1396 ignore_symbols,
1397 offset,
1398 filename_ptr,
1399 functionname_ptr,
1400 line_ptr),
1401 bfd *abfd AND
1402 asection *section AND
1403 asymbol **ignore_symbols AND
1404 bfd_vma offset AND
1405 CONST char **filename_ptr AND
1406 CONST char **functionname_ptr AND
1407 unsigned int *line_ptr)
1408{
1409 static bfd *cache_abfd;
1410 static asection *cache_section;
1411 static bfd_vma cache_offset;
1412 static unsigned int cache_i;
85fe7cff
PB
1413 static CONST char *cache_function;
1414 static unsigned int line_base = 0;
075caafd
ILT
1415
1416 unsigned int i = 0;
1417 coff_data_type *cof = coff_data(abfd);
1418 /* Run through the raw syments if available */
1419 combined_entry_type *p;
1420 alent *l;
075caafd
ILT
1421
1422
1423 *filename_ptr = 0;
1424 *functionname_ptr = 0;
1425 *line_ptr = 0;
1426
1427 /* Don't try and find line numbers in a non coff file */
1428 if (abfd->xvec->flavour != bfd_target_coff_flavour)
1429 return false;
1430
1431 if (cof == NULL)
1432 return false;
1433
1434 p = cof->raw_syments;
1435
1436 for (i = 0; i < cof->raw_syment_count; i++) {
1437 if (p->u.syment.n_sclass == C_FILE) {
1438 /* File name has been moved into symbol */
1439 *filename_ptr = (char *) p->u.syment._n._n_n._n_offset;
1440 break;
1441 }
1442 p += 1 + p->u.syment.n_numaux;
1443 }
1444 /* Now wander though the raw linenumbers of the section */
1445 /*
1446 If this is the same BFD as we were previously called with and this is
1447 the same section, and the offset we want is further down then we can
1448 prime the lookup loop
1449 */
1450 if (abfd == cache_abfd &&
1451 section == cache_section &&
1452 offset >= cache_offset) {
1453 i = cache_i;
85fe7cff 1454 *functionname_ptr = cache_function;
075caafd
ILT
1455 }
1456 else {
1457 i = 0;
075caafd 1458 }
85fe7cff 1459 l = &section->lineno[i];
075caafd
ILT
1460
1461 for (; i < section->lineno_count; i++) {
1462 if (l->line_number == 0) {
1463 /* Get the symbol this line number points at */
1464 coff_symbol_type *coff = (coff_symbol_type *) (l->u.sym);
85fe7cff
PB
1465 if (coff->symbol.value > offset)
1466 break;
075caafd
ILT
1467 *functionname_ptr = coff->symbol.name;
1468 if (coff->native) {
1469 combined_entry_type *s = coff->native;
1470 s = s + 1 + s->u.syment.n_numaux;
1471 /*
1472 S should now point to the .bf of the function
1473 */
1474 if (s->u.syment.n_numaux) {
1475 /*
1476 The linenumber is stored in the auxent
1477 */
1478 union internal_auxent *a = &((s + 1)->u.auxent);
1479 line_base = a->x_sym.x_misc.x_lnsz.x_lnno;
85fe7cff 1480 *line_ptr = line_base;
075caafd
ILT
1481 }
1482 }
1483 }
1484 else {
1485 if (l->u.offset > offset)
1486 break;
85fe7cff 1487 *line_ptr = l->line_number + line_base - 1;
075caafd
ILT
1488 }
1489 l++;
1490 }
1491
1492 cache_abfd = abfd;
1493 cache_section = section;
1494 cache_offset = offset;
1495 cache_i = i;
85fe7cff 1496 cache_function = *functionname_ptr;
075caafd
ILT
1497
1498 return true;
1499}
1500
1501int
1502DEFUN(coff_sizeof_headers,(abfd, reloc),
1503 bfd *abfd AND
1504 boolean reloc)
1505{
1506 size_t size;
1507
1508 if (reloc == false) {
1509 size = bfd_coff_filhsz (abfd) + bfd_coff_aoutsz (abfd);
1510 }
1511 else {
1512 size = bfd_coff_filhsz (abfd);
1513 }
1514
1515 size += abfd->section_count * bfd_coff_scnhsz (abfd);
1516 return size;
1517}
This page took 0.111151 seconds and 4 git commands to generate.