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