]> git.ipfire.org Git - thirdparty/binutils-gdb.git/blob - bfd/coffgen.c
Mon Jan 25 15:27:36 1993 Ian Lance Taylor (ian@cygnus.com)
[thirdparty/binutils-gdb.git] / bfd / coffgen.c
1 /* Support for the generic parts of COFF, for BFD.
2 Copyright 1990, 1991, 1992 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 /* 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"
42 #include "seclet.h"
43 #include "libcoff.h"
44
45 static 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. */
49 static boolean
50 DEFUN(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
103 static
104 bfd_target *
105 DEFUN(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 */
117 tdata = bfd_coff_mkobject_hook (abfd, (PTR) internal_f, (PTR) internal_a);
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
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;
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
173 bfd_target *
174 DEFUN(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
219 return coff_real_object_p(abfd, nscns, &internal_f,
220 (internal_f.f_opthdr != 0
221 ? &internal_a
222 : (struct internal_aouthdr *) NULL));
223 }
224
225 /* Get the BFD section from a COFF symbol section number. */
226
227 struct sec *
228 DEFUN(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
259 unsigned int
260 coff_get_symtab_upper_bound(abfd)
261 bfd *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
272 unsigned int
273 DEFUN(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
307 int
308 DEFUN(coff_count_linenumbers,(abfd),
309 bfd *abfd)
310 {
311 unsigned int limit = bfd_get_symcount(abfd);
312 unsigned int i;
313 int total = 0;
314 asymbol **p;
315 {
316 asection *s = abfd->sections->output_section;
317 while (s) {
318 BFD_ASSERT(s->lineno_count == 0);
319 s = s->next;
320 }
321 }
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++;
335 total ++;
336 l++;
337 while (l->line_number) {
338 total ++;
339 q->symbol.section->output_section->lineno_count++;
340 l++;
341 }
342 }
343 }
344 }
345 return total;
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
351 coff_symbol_type *
352 DEFUN(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
365 static void
366 DEFUN(fixup_symbol_value,(coff_symbol_ptr, syment),
367 coff_symbol_type *coff_symbol_ptr AND
368 struct internal_syment *syment)
369 {
370
371 /* Normalize the symbol flags */
372 if (coff_symbol_ptr->symbol.section == &bfd_com_section) {
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 */
411 void
412 DEFUN(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 */
483 void
484 DEFUN(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
519 static int string_size;
520
521 static void
522 DEFUN(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
575 static unsigned int
576 DEFUN(coff_write_symbol,(abfd, symbol, native, written),
577 bfd *abfd AND
578 asymbol *symbol AND
579 combined_entry_type *native AND
580 unsigned 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
646 static unsigned int
647 DEFUN(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 }
667 else if (symbol->section == &bfd_com_section)
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
704 static unsigned int
705 DEFUN(coff_write_native_symbol,(abfd, symbol, written),
706 bfd *abfd AND
707 coff_symbol_type *symbol AND
708 unsigned 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
736 I'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
763 void
764 DEFUN(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
840 void
841 DEFUN(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;
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;
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++;
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 }
876 }
877 }
878 q++;
879 }
880 }
881 }
882 bfd_release (abfd, buff);
883 }
884
885 alent *
886 DEFUN(coff_get_lineno,(ignore_abfd, symbol),
887 bfd *ignore_abfd AND
888 asymbol *symbol)
889 {
890 return coffsymbol(symbol)->lineno;
891 }
892
893 asymbol *
894 coff_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
941 static void
942 DEFUN(coff_pointerize_aux,(abfd, table_base, type, class, auxent),
943 bfd *abfd AND
944 combined_entry_type *table_base AND
945 int type AND
946 int class AND
947 combined_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
970 static char *
971 DEFUN(build_string_table,(abfd),
972 bfd *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
1004 static char *
1005 DEFUN(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. */
1045 static char *
1046 DEFUN(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
1074 combined_entry_type *
1075 DEFUN(coff_get_normalized_symtab,(abfd),
1076 bfd *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;
1128
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;
1226
1227 return (internal);
1228 } /* coff_get_normalized_symtab() */
1229
1230 unsigned int
1231 DEFUN (coff_get_reloc_upper_bound, (abfd, asect),
1232 bfd *abfd AND
1233 sec_ptr asect)
1234 {
1235 if (bfd_get_format(abfd) != bfd_object) {
1236 bfd_error = invalid_operation;
1237 return 0;
1238 }
1239 return (asect->reloc_count + 1) * sizeof(arelent *);
1240 }
1241
1242 asymbol *
1243 DEFUN (coff_make_empty_symbol, (abfd),
1244 bfd *abfd)
1245 {
1246 coff_symbol_type *new = (coff_symbol_type *) bfd_alloc(abfd, sizeof(coff_symbol_type));
1247 if (new == NULL) {
1248 bfd_error = no_memory;
1249 return (NULL);
1250 } /* on error */
1251 new->symbol.section = 0;
1252 new->native = 0;
1253 new->lineno = (alent *) NULL;
1254 new->done_lineno = false;
1255 new->symbol.the_bfd = abfd;
1256 return &new->symbol;
1257 }
1258
1259 asymbol *
1260 DEFUN (coff_make_debug_symbol, (abfd, ptr, sz),
1261 bfd *abfd AND
1262 PTR ptr AND
1263 unsigned long sz)
1264 {
1265 coff_symbol_type *new = (coff_symbol_type *) bfd_alloc(abfd, sizeof(coff_symbol_type));
1266 if (new == NULL) {
1267 bfd_error = no_memory;
1268 return (NULL);
1269 } /* on error */
1270 /* @@ This shouldn't be using a constant multiplier. */
1271 new->native = (combined_entry_type *) bfd_zalloc (abfd, sizeof (combined_entry_type) * 10);
1272 new->symbol.section = &bfd_debug_section;
1273 new->lineno = (alent *) NULL;
1274 new->done_lineno = false;
1275 new->symbol.the_bfd = abfd;
1276 return &new->symbol;
1277 }
1278
1279 void
1280 DEFUN(coff_print_symbol,(abfd, filep, symbol, how),
1281 bfd *abfd AND
1282 PTR filep AND
1283 asymbol *symbol AND
1284 bfd_print_symbol_type how)
1285 {
1286 FILE *file = (FILE *)filep;
1287 switch (how) {
1288 case bfd_print_symbol_name:
1289 fprintf(file, "%s", symbol->name);
1290 break;
1291 case bfd_print_symbol_more:
1292 fprintf(file, "coff %lx %lx", (unsigned long) coffsymbol(symbol)->native,
1293 (unsigned long) coffsymbol(symbol)->lineno);
1294 break;
1295 case bfd_print_symbol_nm:
1296
1297 {
1298 CONST char *section_name = symbol->section->name;
1299 bfd_print_symbol_vandf((PTR) file, symbol);
1300
1301
1302 fprintf(file, " %-5s %s %s %s",
1303 section_name,
1304 coffsymbol(symbol)->native ? "n" : "g",
1305 coffsymbol(symbol)->lineno ? "l" : " ",
1306 symbol->name);
1307 }
1308
1309
1310 break;
1311 case bfd_print_symbol_all:
1312 /* Print out the symbols in a reasonable way */
1313 {
1314 CONST char *section_name = symbol->section->name;
1315
1316
1317 if (coffsymbol(symbol)->native)
1318 {
1319 unsigned int aux;
1320 combined_entry_type *combined = coffsymbol(symbol)->native;
1321 combined_entry_type *root = obj_raw_syments(abfd);
1322
1323 fprintf(file,"[%3d]",
1324 combined - root);
1325
1326
1327 fprintf(file, "(sc %2d)(fl%4x)(ty%3x)(sc%3d) nx(%d) %08x %s",
1328 combined->u.syment.n_scnum,
1329 combined->u.syment.n_flags,
1330 combined->u.syment.n_type,
1331 combined->u.syment.n_sclass,
1332 combined->u.syment.n_numaux,
1333 combined->u.syment.n_value,
1334 symbol->name
1335 );
1336 for (aux = 0; aux < combined->u.syment.n_numaux; aux++)
1337 {
1338 fprintf(file,"\n");
1339 switch (combined->u.syment.n_sclass) {
1340 case C_FILE:
1341 fprintf(file, "File ");
1342 break;
1343 default:
1344 fprintf(file, "AUX lnno %x size %x tagndx %x",
1345 combined[aux+1].u.auxent.x_sym.x_misc.x_lnsz.x_lnno,
1346 combined[aux+1].u.auxent.x_sym.x_misc.x_lnsz.x_size,
1347 combined[aux+1].u.auxent.x_sym.x_tagndx.l);
1348 break;
1349
1350 }
1351
1352 }
1353
1354 {
1355 struct lineno_cache_entry *l = coffsymbol(symbol)->lineno;
1356 if (l)
1357 {
1358 printf("\n%s :", l->u.sym->name);
1359 l++;
1360 while (l->line_number)
1361 {
1362 printf("\n%4d : %x",
1363 l->line_number,
1364 l->u.offset);
1365 l++;
1366
1367 }
1368 }
1369 }
1370
1371
1372
1373 }
1374
1375 else {
1376 bfd_print_symbol_vandf((PTR) file, symbol);
1377 fprintf(file, " %-5s %s %s %s",
1378 section_name,
1379 coffsymbol(symbol)->native ? "n" : "g",
1380 coffsymbol(symbol)->lineno ? "l" : " ",
1381 symbol->name);
1382 }
1383
1384 }
1385
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
1393 boolean
1394 DEFUN(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;
1413 static alent *cache_l;
1414
1415 unsigned int i = 0;
1416 coff_data_type *cof = coff_data(abfd);
1417 /* Run through the raw syments if available */
1418 combined_entry_type *p;
1419 alent *l;
1420 unsigned int line_base = 0;
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;
1454 l = cache_l;
1455 }
1456 else {
1457 i = 0;
1458 l = section->lineno;
1459 }
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);
1465 *functionname_ptr = coff->symbol.name;
1466 if (coff->native) {
1467 combined_entry_type *s = coff->native;
1468 s = s + 1 + s->u.syment.n_numaux;
1469 /*
1470 S should now point to the .bf of the function
1471 */
1472 if (s->u.syment.n_numaux) {
1473 /*
1474 The linenumber is stored in the auxent
1475 */
1476 union internal_auxent *a = &((s + 1)->u.auxent);
1477 line_base = a->x_sym.x_misc.x_lnsz.x_lnno;
1478 }
1479 }
1480 }
1481 else {
1482 if (l->u.offset > offset)
1483 break;
1484 *line_ptr = l->line_number + line_base + 1;
1485 }
1486 l++;
1487 }
1488
1489 cache_abfd = abfd;
1490 cache_section = section;
1491 cache_offset = offset;
1492 cache_i = i;
1493 cache_l = l;
1494
1495 return true;
1496 }
1497
1498 int
1499 DEFUN(coff_sizeof_headers,(abfd, reloc),
1500 bfd *abfd AND
1501 boolean reloc)
1502 {
1503 size_t size;
1504
1505 if (reloc == false) {
1506 size = bfd_coff_filhsz (abfd) + bfd_coff_aoutsz (abfd);
1507 }
1508 else {
1509 size = bfd_coff_filhsz (abfd);
1510 }
1511
1512 size += abfd->section_count * bfd_coff_scnhsz (abfd);
1513 return size;
1514 }