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