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