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