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