1 /* Routines to link ECOFF debugging information.
2    Copyright (C) 1993-2016 Free Software Foundation, Inc.
3    Written by Ian Lance Taylor, Cygnus Support, <ian@cygnus.com>.
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 3 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., 51 Franklin Street - Fifth Floor, Boston,
20    MA 02110-1301, USA.  */
21 
22 #include "sysdep.h"
23 #include "bfd.h"
24 #include "bfdlink.h"
25 #include "libbfd.h"
26 #include "objalloc.h"
27 #include "aout/stab_gnu.h"
28 #include "coff/internal.h"
29 #include "coff/sym.h"
30 #include "coff/symconst.h"
31 #include "coff/ecoff.h"
32 #include "libcoff.h"
33 #include "libecoff.h"
34 
35 /* Routines to swap auxiliary information in and out.  I am assuming
36    that the auxiliary information format is always going to be target
37    independent.  */
38 
39 /* Swap in a type information record.
40    BIGEND says whether AUX symbols are big-endian or little-endian; this
41    info comes from the file header record (fh-fBigendian).  */
42 
43 void
_bfd_ecoff_swap_tir_in(int bigend,const struct tir_ext * ext_copy,TIR * intern)44 _bfd_ecoff_swap_tir_in (int bigend, const struct tir_ext *ext_copy,
45 			TIR *intern)
46 {
47   struct tir_ext ext[1];
48 
49   *ext = *ext_copy;		/* Make it reasonable to do in-place.  */
50 
51   /* now the fun stuff...  */
52   if (bigend)
53     {
54       intern->fBitfield   = 0 != (ext->t_bits1[0] & TIR_BITS1_FBITFIELD_BIG);
55       intern->continued   = 0 != (ext->t_bits1[0] & TIR_BITS1_CONTINUED_BIG);
56       intern->bt          = (ext->t_bits1[0] & TIR_BITS1_BT_BIG)
57                           >>                   TIR_BITS1_BT_SH_BIG;
58       intern->tq4         = (ext->t_tq45[0] & TIR_BITS_TQ4_BIG)
59 			  >>		      TIR_BITS_TQ4_SH_BIG;
60       intern->tq5         = (ext->t_tq45[0] & TIR_BITS_TQ5_BIG)
61 			  >>		      TIR_BITS_TQ5_SH_BIG;
62       intern->tq0         = (ext->t_tq01[0] & TIR_BITS_TQ0_BIG)
63 			  >>		      TIR_BITS_TQ0_SH_BIG;
64       intern->tq1         = (ext->t_tq01[0] & TIR_BITS_TQ1_BIG)
65 			  >>		      TIR_BITS_TQ1_SH_BIG;
66       intern->tq2         = (ext->t_tq23[0] & TIR_BITS_TQ2_BIG)
67 			  >>		      TIR_BITS_TQ2_SH_BIG;
68       intern->tq3         = (ext->t_tq23[0] & TIR_BITS_TQ3_BIG)
69 			  >>		      TIR_BITS_TQ3_SH_BIG;
70     }
71   else
72     {
73       intern->fBitfield   = 0 != (ext->t_bits1[0] & TIR_BITS1_FBITFIELD_LITTLE);
74       intern->continued   = 0 != (ext->t_bits1[0] & TIR_BITS1_CONTINUED_LITTLE);
75       intern->bt          = (ext->t_bits1[0] & TIR_BITS1_BT_LITTLE)
76 			  >>		    TIR_BITS1_BT_SH_LITTLE;
77       intern->tq4         = (ext->t_tq45[0] & TIR_BITS_TQ4_LITTLE)
78 			  >>		    TIR_BITS_TQ4_SH_LITTLE;
79       intern->tq5         = (ext->t_tq45[0] & TIR_BITS_TQ5_LITTLE)
80 			  >>		    TIR_BITS_TQ5_SH_LITTLE;
81       intern->tq0         = (ext->t_tq01[0] & TIR_BITS_TQ0_LITTLE)
82 			  >>		    TIR_BITS_TQ0_SH_LITTLE;
83       intern->tq1         = (ext->t_tq01[0] & TIR_BITS_TQ1_LITTLE)
84 			  >>		    TIR_BITS_TQ1_SH_LITTLE;
85       intern->tq2         = (ext->t_tq23[0] & TIR_BITS_TQ2_LITTLE)
86 			  >>		    TIR_BITS_TQ2_SH_LITTLE;
87       intern->tq3         = (ext->t_tq23[0] & TIR_BITS_TQ3_LITTLE)
88 			  >>		    TIR_BITS_TQ3_SH_LITTLE;
89     }
90 
91 #ifdef TEST
92   if (memcmp ((char *)ext, (char *)intern, sizeof (*intern)) != 0)
93     abort ();
94 #endif
95 }
96 
97 /* Swap out a type information record.
98    BIGEND says whether AUX symbols are big-endian or little-endian; this
99    info comes from the file header record (fh-fBigendian).  */
100 
101 void
_bfd_ecoff_swap_tir_out(int bigend,const TIR * intern_copy,struct tir_ext * ext)102 _bfd_ecoff_swap_tir_out (int bigend,
103 			 const TIR *intern_copy,
104 			 struct tir_ext *ext)
105 {
106   TIR intern[1];
107 
108   *intern = *intern_copy;	/* Make it reasonable to do in-place.  */
109 
110   /* now the fun stuff...  */
111   if (bigend)
112     {
113       ext->t_bits1[0] = ((intern->fBitfield ? TIR_BITS1_FBITFIELD_BIG : 0)
114 		       | (intern->continued ? TIR_BITS1_CONTINUED_BIG : 0)
115 		       | ((intern->bt << TIR_BITS1_BT_SH_BIG)
116 			  & TIR_BITS1_BT_BIG));
117       ext->t_tq45[0] = (((intern->tq4 << TIR_BITS_TQ4_SH_BIG)
118 		       & TIR_BITS_TQ4_BIG)
119 		      | ((intern->tq5 << TIR_BITS_TQ5_SH_BIG)
120 			 & TIR_BITS_TQ5_BIG));
121       ext->t_tq01[0] = (((intern->tq0 << TIR_BITS_TQ0_SH_BIG)
122 		       & TIR_BITS_TQ0_BIG)
123 		      | ((intern->tq1 << TIR_BITS_TQ1_SH_BIG)
124 			 & TIR_BITS_TQ1_BIG));
125       ext->t_tq23[0] = (((intern->tq2 << TIR_BITS_TQ2_SH_BIG)
126 		       & TIR_BITS_TQ2_BIG)
127 		      | ((intern->tq3 << TIR_BITS_TQ3_SH_BIG)
128 			 & TIR_BITS_TQ3_BIG));
129     }
130   else
131     {
132       ext->t_bits1[0] = ((intern->fBitfield ? TIR_BITS1_FBITFIELD_LITTLE : 0)
133 		       | (intern->continued ? TIR_BITS1_CONTINUED_LITTLE : 0)
134 		       | ((intern->bt << TIR_BITS1_BT_SH_LITTLE)
135 			  & TIR_BITS1_BT_LITTLE));
136       ext->t_tq45[0] = (((intern->tq4 << TIR_BITS_TQ4_SH_LITTLE)
137 		       & TIR_BITS_TQ4_LITTLE)
138 		      | ((intern->tq5 << TIR_BITS_TQ5_SH_LITTLE)
139 			 & TIR_BITS_TQ5_LITTLE));
140       ext->t_tq01[0] = (((intern->tq0 << TIR_BITS_TQ0_SH_LITTLE)
141 		       & TIR_BITS_TQ0_LITTLE)
142 		      | ((intern->tq1 << TIR_BITS_TQ1_SH_LITTLE)
143 			 & TIR_BITS_TQ1_LITTLE));
144       ext->t_tq23[0] = (((intern->tq2 << TIR_BITS_TQ2_SH_LITTLE)
145 		       & TIR_BITS_TQ2_LITTLE)
146 		      | ((intern->tq3 << TIR_BITS_TQ3_SH_LITTLE)
147 			 & TIR_BITS_TQ3_LITTLE));
148     }
149 
150 #ifdef TEST
151   if (memcmp ((char *)ext, (char *)intern, sizeof (*intern)) != 0)
152     abort ();
153 #endif
154 }
155 
156 /* Swap in a relative symbol record.  BIGEND says whether it is in
157    big-endian or little-endian format.*/
158 
159 void
_bfd_ecoff_swap_rndx_in(int bigend,const struct rndx_ext * ext_copy,RNDXR * intern)160 _bfd_ecoff_swap_rndx_in (int bigend,
161 			 const struct rndx_ext *ext_copy,
162 			 RNDXR *intern)
163 {
164   struct rndx_ext ext[1];
165 
166   *ext = *ext_copy;		/* Make it reasonable to do in-place.  */
167 
168   /* now the fun stuff...  */
169   if (bigend)
170     {
171       intern->rfd   = (ext->r_bits[0] << RNDX_BITS0_RFD_SH_LEFT_BIG)
172 		  | ((ext->r_bits[1] & RNDX_BITS1_RFD_BIG)
173 		    		    >> RNDX_BITS1_RFD_SH_BIG);
174       intern->index = ((ext->r_bits[1] & RNDX_BITS1_INDEX_BIG)
175 		    		    << RNDX_BITS1_INDEX_SH_LEFT_BIG)
176 		  | (ext->r_bits[2] << RNDX_BITS2_INDEX_SH_LEFT_BIG)
177 		  | (ext->r_bits[3] << RNDX_BITS3_INDEX_SH_LEFT_BIG);
178     }
179   else
180     {
181       intern->rfd   = (ext->r_bits[0] << RNDX_BITS0_RFD_SH_LEFT_LITTLE)
182 		  | ((ext->r_bits[1] & RNDX_BITS1_RFD_LITTLE)
183 		    		    << RNDX_BITS1_RFD_SH_LEFT_LITTLE);
184       intern->index = ((ext->r_bits[1] & RNDX_BITS1_INDEX_LITTLE)
185 		    		    >> RNDX_BITS1_INDEX_SH_LITTLE)
186 		  | (ext->r_bits[2] << RNDX_BITS2_INDEX_SH_LEFT_LITTLE)
187 		  | ((unsigned int) ext->r_bits[3]
188 		     << RNDX_BITS3_INDEX_SH_LEFT_LITTLE);
189     }
190 
191 #ifdef TEST
192   if (memcmp ((char *)ext, (char *)intern, sizeof (*intern)) != 0)
193     abort ();
194 #endif
195 }
196 
197 /* Swap out a relative symbol record.  BIGEND says whether it is in
198    big-endian or little-endian format.*/
199 
200 void
_bfd_ecoff_swap_rndx_out(int bigend,const RNDXR * intern_copy,struct rndx_ext * ext)201 _bfd_ecoff_swap_rndx_out (int bigend,
202 			  const RNDXR *intern_copy,
203 			  struct rndx_ext *ext)
204 {
205   RNDXR intern[1];
206 
207   *intern = *intern_copy;	/* Make it reasonable to do in-place.  */
208 
209   /* now the fun stuff...  */
210   if (bigend)
211     {
212       ext->r_bits[0] = intern->rfd >> RNDX_BITS0_RFD_SH_LEFT_BIG;
213       ext->r_bits[1] = (((intern->rfd << RNDX_BITS1_RFD_SH_BIG)
214 		       & RNDX_BITS1_RFD_BIG)
215 		      | ((intern->index >> RNDX_BITS1_INDEX_SH_LEFT_BIG)
216 			 & RNDX_BITS1_INDEX_BIG));
217       ext->r_bits[2] = intern->index >> RNDX_BITS2_INDEX_SH_LEFT_BIG;
218       ext->r_bits[3] = intern->index >> RNDX_BITS3_INDEX_SH_LEFT_BIG;
219     }
220   else
221     {
222       ext->r_bits[0] = intern->rfd >> RNDX_BITS0_RFD_SH_LEFT_LITTLE;
223       ext->r_bits[1] = (((intern->rfd >> RNDX_BITS1_RFD_SH_LEFT_LITTLE)
224 		       & RNDX_BITS1_RFD_LITTLE)
225 		      | ((intern->index << RNDX_BITS1_INDEX_SH_LITTLE)
226 			 & RNDX_BITS1_INDEX_LITTLE));
227       ext->r_bits[2] = intern->index >> RNDX_BITS2_INDEX_SH_LEFT_LITTLE;
228       ext->r_bits[3] = intern->index >> RNDX_BITS3_INDEX_SH_LEFT_LITTLE;
229     }
230 
231 #ifdef TEST
232   if (memcmp ((char *)ext, (char *)intern, sizeof (*intern)) != 0)
233     abort ();
234 #endif
235 }
236 
237 /* The minimum amount of data to allocate.  */
238 #define ALLOC_SIZE (4064)
239 
240 /* Add bytes to a buffer.  Return success.  */
241 
242 static bfd_boolean
ecoff_add_bytes(char ** buf,char ** bufend,size_t need)243 ecoff_add_bytes (char **buf, char **bufend, size_t need)
244 {
245   size_t have;
246   size_t want;
247   char *newbuf;
248 
249   have = *bufend - *buf;
250   if (have > need)
251     want = ALLOC_SIZE;
252   else
253     {
254       want = need - have;
255       if (want < ALLOC_SIZE)
256 	want = ALLOC_SIZE;
257     }
258   newbuf = (char *) bfd_realloc (*buf, (bfd_size_type) have + want);
259   if (newbuf == NULL)
260     return FALSE;
261   *buf = newbuf;
262   *bufend = *buf + have + want;
263   return TRUE;
264 }
265 
266 /* We keep a hash table which maps strings to numbers.  We use it to
267    map FDR names to indices in the output file, and to map local
268    strings when combining stabs debugging information.  */
269 
270 struct string_hash_entry
271 {
272   struct bfd_hash_entry root;
273   /* FDR index or string table offset.  */
274   long val;
275   /* Next entry in string table.  */
276   struct string_hash_entry *next;
277 };
278 
279 struct string_hash_table
280 {
281   struct bfd_hash_table table;
282 };
283 
284 /* Routine to create an entry in a string hash table.  */
285 
286 static struct bfd_hash_entry *
string_hash_newfunc(struct bfd_hash_entry * entry,struct bfd_hash_table * table,const char * string)287 string_hash_newfunc (struct bfd_hash_entry *entry,
288 		     struct bfd_hash_table *table,
289 		     const char *string)
290 {
291   struct string_hash_entry *ret = (struct string_hash_entry *) entry;
292 
293   /* Allocate the structure if it has not already been allocated by a
294      subclass.  */
295   if (ret == (struct string_hash_entry *) NULL)
296     ret = ((struct string_hash_entry *)
297 	   bfd_hash_allocate (table, sizeof (struct string_hash_entry)));
298   if (ret == (struct string_hash_entry *) NULL)
299     return NULL;
300 
301   /* Call the allocation method of the superclass.  */
302   ret = ((struct string_hash_entry *)
303 	 bfd_hash_newfunc ((struct bfd_hash_entry *) ret, table, string));
304 
305   if (ret)
306     {
307       /* Initialize the local fields.  */
308       ret->val = -1;
309       ret->next = NULL;
310     }
311 
312   return (struct bfd_hash_entry *) ret;
313 }
314 
315 /* Look up an entry in an string hash table.  */
316 
317 #define string_hash_lookup(t, string, create, copy) \
318   ((struct string_hash_entry *) \
319    bfd_hash_lookup (&(t)->table, (string), (create), (copy)))
320 
321 /* We can't afford to read in all the debugging information when we do
322    a link.  Instead, we build a list of these structures to show how
323    different parts of the input file map to the output file.  */
324 
325 struct shuffle
326 {
327   /* The next entry in this linked list.  */
328   struct shuffle *next;
329   /* The length of the information.  */
330   unsigned long size;
331   /* Whether this information comes from a file or not.  */
332   bfd_boolean filep;
333   union
334     {
335       struct
336 	{
337 	  /* The BFD the data comes from.  */
338 	  bfd *input_bfd;
339 	  /* The offset within input_bfd.  */
340 	  file_ptr offset;
341 	} file;
342       /* The data to be written out.  */
343       void * memory;
344     } u;
345 };
346 
347 /* This structure holds information across calls to
348    bfd_ecoff_debug_accumulate.  */
349 
350 struct accumulate
351 {
352   /* The FDR hash table.  */
353   struct string_hash_table fdr_hash;
354   /* The strings hash table.  */
355   struct string_hash_table str_hash;
356   /* Linked lists describing how to shuffle the input debug
357      information into the output file.  We keep a pointer to both the
358      head and the tail.  */
359   struct shuffle *line;
360   struct shuffle *line_end;
361   struct shuffle *pdr;
362   struct shuffle *pdr_end;
363   struct shuffle *sym;
364   struct shuffle *sym_end;
365   struct shuffle *opt;
366   struct shuffle *opt_end;
367   struct shuffle *aux;
368   struct shuffle *aux_end;
369   struct shuffle *ss;
370   struct shuffle *ss_end;
371   struct string_hash_entry *ss_hash;
372   struct string_hash_entry *ss_hash_end;
373   struct shuffle *fdr;
374   struct shuffle *fdr_end;
375   struct shuffle *rfd;
376   struct shuffle *rfd_end;
377   /* The size of the largest file shuffle.  */
378   unsigned long largest_file_shuffle;
379   /* An objalloc for debugging information.  */
380   struct objalloc *memory;
381 };
382 
383 /* Add a file entry to a shuffle list.  */
384 
385 static bfd_boolean
add_file_shuffle(struct accumulate * ainfo,struct shuffle ** head,struct shuffle ** tail,bfd * input_bfd,file_ptr offset,unsigned long size)386 add_file_shuffle (struct accumulate *ainfo,
387 		  struct shuffle **head,
388 		  struct shuffle **tail,
389 		  bfd *input_bfd,
390 		  file_ptr offset,
391 		  unsigned long size)
392 {
393   struct shuffle *n;
394 
395   if (*tail != (struct shuffle *) NULL
396       && (*tail)->filep
397       && (*tail)->u.file.input_bfd == input_bfd
398       && (*tail)->u.file.offset + (*tail)->size == (unsigned long) offset)
399     {
400       /* Just merge this entry onto the existing one.  */
401       (*tail)->size += size;
402       if ((*tail)->size > ainfo->largest_file_shuffle)
403 	ainfo->largest_file_shuffle = (*tail)->size;
404       return TRUE;
405     }
406 
407   n = (struct shuffle *) objalloc_alloc (ainfo->memory,
408 					 sizeof (struct shuffle));
409   if (!n)
410     {
411       bfd_set_error (bfd_error_no_memory);
412       return FALSE;
413     }
414   n->next = NULL;
415   n->size = size;
416   n->filep = TRUE;
417   n->u.file.input_bfd = input_bfd;
418   n->u.file.offset = offset;
419   if (*head == (struct shuffle *) NULL)
420     *head = n;
421   if (*tail != (struct shuffle *) NULL)
422     (*tail)->next = n;
423   *tail = n;
424   if (size > ainfo->largest_file_shuffle)
425     ainfo->largest_file_shuffle = size;
426   return TRUE;
427 }
428 
429 /* Add a memory entry to a shuffle list.  */
430 
431 static bfd_boolean
add_memory_shuffle(struct accumulate * ainfo,struct shuffle ** head,struct shuffle ** tail,bfd_byte * data,unsigned long size)432 add_memory_shuffle (struct accumulate *ainfo,
433 		    struct shuffle **head,
434 		    struct shuffle **tail,
435 		    bfd_byte *data,
436 		    unsigned long size)
437 {
438   struct shuffle *n;
439 
440   n = (struct shuffle *) objalloc_alloc (ainfo->memory,
441 					 sizeof (struct shuffle));
442   if (!n)
443     {
444       bfd_set_error (bfd_error_no_memory);
445       return FALSE;
446     }
447   n->next = NULL;
448   n->size = size;
449   n->filep = FALSE;
450   n->u.memory = data;
451   if (*head == (struct shuffle *) NULL)
452     *head = n;
453   if (*tail != (struct shuffle *) NULL)
454     (*tail)->next = n;
455   *tail = n;
456   return TRUE;
457 }
458 
459 /* Initialize the FDR hash table.  This returns a handle which is then
460    passed in to bfd_ecoff_debug_accumulate, et. al.  */
461 
462 void *
bfd_ecoff_debug_init(bfd * output_bfd ATTRIBUTE_UNUSED,struct ecoff_debug_info * output_debug,const struct ecoff_debug_swap * output_swap ATTRIBUTE_UNUSED,struct bfd_link_info * info)463 bfd_ecoff_debug_init (bfd *output_bfd ATTRIBUTE_UNUSED,
464 		      struct ecoff_debug_info *output_debug,
465 		      const struct ecoff_debug_swap *output_swap ATTRIBUTE_UNUSED,
466 		      struct bfd_link_info *info)
467 {
468   struct accumulate *ainfo;
469   bfd_size_type amt = sizeof (struct accumulate);
470 
471   ainfo = (struct accumulate *) bfd_malloc (amt);
472   if (!ainfo)
473     return NULL;
474   if (!bfd_hash_table_init_n (&ainfo->fdr_hash.table, string_hash_newfunc,
475 			      sizeof (struct string_hash_entry), 1021))
476     return NULL;
477 
478   ainfo->line = NULL;
479   ainfo->line_end = NULL;
480   ainfo->pdr = NULL;
481   ainfo->pdr_end = NULL;
482   ainfo->sym = NULL;
483   ainfo->sym_end = NULL;
484   ainfo->opt = NULL;
485   ainfo->opt_end = NULL;
486   ainfo->aux = NULL;
487   ainfo->aux_end = NULL;
488   ainfo->ss = NULL;
489   ainfo->ss_end = NULL;
490   ainfo->ss_hash = NULL;
491   ainfo->ss_hash_end = NULL;
492   ainfo->fdr = NULL;
493   ainfo->fdr_end = NULL;
494   ainfo->rfd = NULL;
495   ainfo->rfd_end = NULL;
496 
497   ainfo->largest_file_shuffle = 0;
498 
499   if (! bfd_link_relocatable (info))
500     {
501       if (!bfd_hash_table_init (&ainfo->str_hash.table, string_hash_newfunc,
502 				sizeof (struct string_hash_entry)))
503 	return NULL;
504 
505       /* The first entry in the string table is the empty string.  */
506       output_debug->symbolic_header.issMax = 1;
507     }
508 
509   ainfo->memory = objalloc_create ();
510   if (ainfo->memory == NULL)
511     {
512       bfd_set_error (bfd_error_no_memory);
513       return NULL;
514     }
515 
516   return ainfo;
517 }
518 
519 /* Free the accumulated debugging information.  */
520 
521 void
bfd_ecoff_debug_free(void * handle,bfd * output_bfd ATTRIBUTE_UNUSED,struct ecoff_debug_info * output_debug ATTRIBUTE_UNUSED,const struct ecoff_debug_swap * output_swap ATTRIBUTE_UNUSED,struct bfd_link_info * info)522 bfd_ecoff_debug_free (void * handle,
523 		      bfd *output_bfd ATTRIBUTE_UNUSED,
524 		      struct ecoff_debug_info *output_debug ATTRIBUTE_UNUSED,
525 		      const struct ecoff_debug_swap *output_swap ATTRIBUTE_UNUSED,
526 		      struct bfd_link_info *info)
527 {
528   struct accumulate *ainfo = (struct accumulate *) handle;
529 
530   bfd_hash_table_free (&ainfo->fdr_hash.table);
531 
532   if (! bfd_link_relocatable (info))
533     bfd_hash_table_free (&ainfo->str_hash.table);
534 
535   objalloc_free (ainfo->memory);
536 
537   free (ainfo);
538 }
539 
540 /* Accumulate the debugging information from INPUT_BFD into
541    OUTPUT_BFD.  The INPUT_DEBUG argument points to some ECOFF
542    debugging information which we want to link into the information
543    pointed to by the OUTPUT_DEBUG argument.  OUTPUT_SWAP and
544    INPUT_SWAP point to the swapping information needed.  INFO is the
545    linker information structure.  HANDLE is returned by
546    bfd_ecoff_debug_init.  */
547 
548 bfd_boolean
bfd_ecoff_debug_accumulate(void * handle,bfd * output_bfd,struct ecoff_debug_info * output_debug,const struct ecoff_debug_swap * output_swap,bfd * input_bfd,struct ecoff_debug_info * input_debug,const struct ecoff_debug_swap * input_swap,struct bfd_link_info * info)549 bfd_ecoff_debug_accumulate (void * handle,
550 			    bfd *output_bfd,
551 			    struct ecoff_debug_info *output_debug,
552 			    const struct ecoff_debug_swap *output_swap,
553 			    bfd *input_bfd,
554 			    struct ecoff_debug_info *input_debug,
555 			    const struct ecoff_debug_swap *input_swap,
556 			    struct bfd_link_info *info)
557 {
558   struct accumulate *ainfo = (struct accumulate *) handle;
559   void (* const swap_sym_in) (bfd *, void *, SYMR *)
560     = input_swap->swap_sym_in;
561   void (* const swap_rfd_in) (bfd *, void *, RFDT *)
562     = input_swap->swap_rfd_in;
563   void (* const swap_sym_out) (bfd *, const SYMR *, void *)
564     = output_swap->swap_sym_out;
565   void (* const swap_fdr_out) (bfd *, const FDR *, void *)
566     = output_swap->swap_fdr_out;
567   void (* const swap_rfd_out) (bfd *, const RFDT *, void *)
568     = output_swap->swap_rfd_out;
569   bfd_size_type external_pdr_size = output_swap->external_pdr_size;
570   bfd_size_type external_sym_size = output_swap->external_sym_size;
571   bfd_size_type external_opt_size = output_swap->external_opt_size;
572   bfd_size_type external_fdr_size = output_swap->external_fdr_size;
573   bfd_size_type external_rfd_size = output_swap->external_rfd_size;
574   HDRR * const output_symhdr = &output_debug->symbolic_header;
575   HDRR * const input_symhdr = &input_debug->symbolic_header;
576   bfd_vma section_adjust[scMax];
577   asection *sec;
578   bfd_byte *fdr_start;
579   bfd_byte *fdr_ptr;
580   bfd_byte *fdr_end;
581   bfd_size_type fdr_add;
582   unsigned int copied;
583   RFDT i;
584   unsigned long sz;
585   bfd_byte *rfd_out;
586   bfd_byte *rfd_in;
587   bfd_byte *rfd_end;
588   long newrfdbase = 0;
589   long oldrfdbase = 0;
590   bfd_byte *fdr_out;
591   bfd_size_type amt;
592 
593   /* Use section_adjust to hold the value to add to a symbol in a
594      particular section.  */
595   memset (section_adjust, 0, sizeof section_adjust);
596 
597 #define SET(name, indx) \
598   sec = bfd_get_section_by_name (input_bfd, name); \
599   if (sec != NULL) \
600     section_adjust[indx] = (sec->output_section->vma \
601 			    + sec->output_offset \
602 			    - sec->vma);
603 
604   SET (".text", scText);
605   SET (".data", scData);
606   SET (".bss", scBss);
607   SET (".sdata", scSData);
608   SET (".sbss", scSBss);
609   /* scRdata section may be either .rdata or .rodata.  */
610   SET (".rdata", scRData);
611   SET (".rodata", scRData);
612   SET (".init", scInit);
613   SET (".fini", scFini);
614   SET (".rconst", scRConst);
615 
616 #undef SET
617 
618   /* Find all the debugging information based on the FDR's.  We need
619      to handle them whether they are swapped or not.  */
620   if (input_debug->fdr != (FDR *) NULL)
621     {
622       fdr_start = (bfd_byte *) input_debug->fdr;
623       fdr_add = sizeof (FDR);
624     }
625   else
626     {
627       fdr_start = (bfd_byte *) input_debug->external_fdr;
628       fdr_add = input_swap->external_fdr_size;
629     }
630   fdr_end = fdr_start + input_symhdr->ifdMax * fdr_add;
631 
632   amt = input_symhdr->ifdMax;
633   amt *= sizeof (RFDT);
634   input_debug->ifdmap = (RFDT *) bfd_alloc (input_bfd, amt);
635 
636   sz = (input_symhdr->crfd + input_symhdr->ifdMax) * external_rfd_size;
637   rfd_out = (bfd_byte *) objalloc_alloc (ainfo->memory, sz);
638   if (!input_debug->ifdmap || !rfd_out)
639     {
640       bfd_set_error (bfd_error_no_memory);
641       return FALSE;
642     }
643   if (!add_memory_shuffle (ainfo, &ainfo->rfd, &ainfo->rfd_end, rfd_out, sz))
644     return FALSE;
645 
646   copied = 0;
647 
648   /* Look through the FDR's to see which ones we are going to include
649      in the final output.  We do not want duplicate FDR information
650      for header files, because ECOFF debugging is often very large.
651      When we find an FDR with no line information which can be merged,
652      we look it up in a hash table to ensure that we only include it
653      once.  We keep a table mapping FDR numbers to the final number
654      they get with the BFD, so that we can refer to it when we write
655      out the external symbols.  */
656   for (fdr_ptr = fdr_start, i = 0;
657        fdr_ptr < fdr_end;
658        fdr_ptr += fdr_add, i++, rfd_out += external_rfd_size)
659     {
660       FDR fdr;
661 
662       if (input_debug->fdr != (FDR *) NULL)
663 	fdr = *(FDR *) fdr_ptr;
664       else
665 	(*input_swap->swap_fdr_in) (input_bfd, fdr_ptr, &fdr);
666 
667       /* See if this FDR can be merged with an existing one.  */
668       if (fdr.cbLine == 0 && fdr.rss != -1 && fdr.fMerge)
669 	{
670 	  const char *name;
671 	  char *lookup;
672 	  struct string_hash_entry *fh;
673 
674 	  /* We look up a string formed from the file name and the
675 	     number of symbols and aux entries.  Sometimes an include
676 	     file will conditionally define a typedef or something
677 	     based on the order of include files.  Using the number of
678 	     symbols and aux entries as a hash reduces the chance that
679 	     we will merge symbol information that should not be
680 	     merged.  */
681 	  name = input_debug->ss + fdr.issBase + fdr.rss;
682 
683 	  lookup = (char *) bfd_malloc ((bfd_size_type) strlen (name) + 20);
684 	  if (lookup == NULL)
685 	    return FALSE;
686 	  sprintf (lookup, "%s %lx %lx", name, (unsigned long) fdr.csym,
687 		   (unsigned long) fdr.caux);
688 
689 	  fh = string_hash_lookup (&ainfo->fdr_hash, lookup, TRUE, TRUE);
690 	  free (lookup);
691 	  if (fh == (struct string_hash_entry *) NULL)
692 	    return FALSE;
693 
694 	  if (fh->val != -1)
695 	    {
696 	      input_debug->ifdmap[i] = fh->val;
697 	      (*swap_rfd_out) (output_bfd, input_debug->ifdmap + i, rfd_out);
698 
699 	      /* Don't copy this FDR.  */
700 	      continue;
701 	    }
702 
703 	  fh->val = output_symhdr->ifdMax + copied;
704 	}
705 
706       input_debug->ifdmap[i] = output_symhdr->ifdMax + copied;
707       (*swap_rfd_out) (output_bfd, input_debug->ifdmap + i, rfd_out);
708       ++copied;
709     }
710 
711   newrfdbase = output_symhdr->crfd;
712   output_symhdr->crfd += input_symhdr->ifdMax;
713 
714   /* Copy over any existing RFD's.  RFD's are only created by the
715      linker, so this will only happen for input files which are the
716      result of a partial link.  */
717   rfd_in = (bfd_byte *) input_debug->external_rfd;
718   rfd_end = rfd_in + input_symhdr->crfd * input_swap->external_rfd_size;
719   for (;
720        rfd_in < rfd_end;
721        rfd_in += input_swap->external_rfd_size)
722     {
723       RFDT rfd;
724 
725       (*swap_rfd_in) (input_bfd, rfd_in, &rfd);
726       BFD_ASSERT (rfd >= 0 && rfd < input_symhdr->ifdMax);
727       rfd = input_debug->ifdmap[rfd];
728       (*swap_rfd_out) (output_bfd, &rfd, rfd_out);
729       rfd_out += external_rfd_size;
730     }
731 
732   oldrfdbase = output_symhdr->crfd;
733   output_symhdr->crfd += input_symhdr->crfd;
734 
735   /* Look through the FDR's and copy over all associated debugging
736      information.  */
737   sz = copied * external_fdr_size;
738   fdr_out = (bfd_byte *) objalloc_alloc (ainfo->memory, sz);
739   if (!fdr_out)
740     {
741       bfd_set_error (bfd_error_no_memory);
742       return FALSE;
743     }
744   if (!add_memory_shuffle (ainfo, &ainfo->fdr, &ainfo->fdr_end, fdr_out, sz))
745     return FALSE;
746   for (fdr_ptr = fdr_start, i = 0;
747        fdr_ptr < fdr_end;
748        fdr_ptr += fdr_add, i++)
749     {
750       FDR fdr;
751       bfd_byte *sym_out;
752       bfd_byte *lraw_src;
753       bfd_byte *lraw_end;
754       bfd_boolean fgotfilename;
755 
756       if (input_debug->ifdmap[i] < output_symhdr->ifdMax)
757 	{
758 	  /* We are not copying this FDR.  */
759 	  continue;
760 	}
761 
762       if (input_debug->fdr != (FDR *) NULL)
763 	fdr = *(FDR *) fdr_ptr;
764       else
765 	(*input_swap->swap_fdr_in) (input_bfd, fdr_ptr, &fdr);
766 
767       /* FIXME: It is conceivable that this FDR points to the .init or
768 	 .fini section, in which case this will not do the right
769 	 thing.  */
770       fdr.adr += section_adjust[scText];
771 
772       /* Swap in the local symbols, adjust their values, and swap them
773 	 out again.  */
774       fgotfilename = FALSE;
775       sz = fdr.csym * external_sym_size;
776       sym_out = (bfd_byte *) objalloc_alloc (ainfo->memory, sz);
777       if (!sym_out)
778 	{
779 	  bfd_set_error (bfd_error_no_memory);
780 	  return FALSE;
781 	}
782       if (!add_memory_shuffle (ainfo, &ainfo->sym, &ainfo->sym_end, sym_out,
783 			       sz))
784 	return FALSE;
785       lraw_src = ((bfd_byte *) input_debug->external_sym
786 		  + fdr.isymBase * input_swap->external_sym_size);
787       lraw_end = lraw_src + fdr.csym * input_swap->external_sym_size;
788       for (;  lraw_src < lraw_end;  lraw_src += input_swap->external_sym_size)
789 	{
790 	  SYMR internal_sym;
791 
792 	  (*swap_sym_in) (input_bfd, lraw_src, &internal_sym);
793 
794 	  BFD_ASSERT (internal_sym.sc != scCommon
795 		      && internal_sym.sc != scSCommon);
796 
797 	  /* Adjust the symbol value if appropriate.  */
798 	  switch (internal_sym.st)
799 	    {
800 	    case stNil:
801 	      if (ECOFF_IS_STAB (&internal_sym))
802 		break;
803 	      /* Fall through.  */
804 	    case stGlobal:
805 	    case stStatic:
806 	    case stLabel:
807 	    case stProc:
808 	    case stStaticProc:
809 	      internal_sym.value += section_adjust[internal_sym.sc];
810 	      break;
811 
812 	    default:
813 	      break;
814 	    }
815 
816 	  /* If we are doing a final link, we hash all the strings in
817 	     the local symbol table together.  This reduces the amount
818 	     of space required by debugging information.  We don't do
819 	     this when performing a relocatable link because it would
820 	     prevent us from easily merging different FDR's.  */
821 	  if (! bfd_link_relocatable (info))
822 	    {
823 	      bfd_boolean ffilename;
824 	      const char *name;
825 
826 	      if (! fgotfilename && internal_sym.iss == fdr.rss)
827 		ffilename = TRUE;
828 	      else
829 		ffilename = FALSE;
830 
831 	      /* Hash the name into the string table.  */
832 	      name = input_debug->ss + fdr.issBase + internal_sym.iss;
833 	      if (*name == '\0')
834 		internal_sym.iss = 0;
835 	      else
836 		{
837 		  struct string_hash_entry *sh;
838 
839 		  sh = string_hash_lookup (&ainfo->str_hash, name, TRUE, TRUE);
840 		  if (sh == (struct string_hash_entry *) NULL)
841 		    return FALSE;
842 		  if (sh->val == -1)
843 		    {
844 		      sh->val = output_symhdr->issMax;
845 		      output_symhdr->issMax += strlen (name) + 1;
846 		      if (ainfo->ss_hash == (struct string_hash_entry *) NULL)
847 			ainfo->ss_hash = sh;
848 		      if (ainfo->ss_hash_end
849 			  != (struct string_hash_entry *) NULL)
850 			ainfo->ss_hash_end->next = sh;
851 		      ainfo->ss_hash_end = sh;
852 		    }
853 		  internal_sym.iss = sh->val;
854 		}
855 
856 	      if (ffilename)
857 		{
858 		  fdr.rss = internal_sym.iss;
859 		  fgotfilename = TRUE;
860 		}
861 	    }
862 
863 	  (*swap_sym_out) (output_bfd, &internal_sym, sym_out);
864 	  sym_out += external_sym_size;
865 	}
866 
867       fdr.isymBase = output_symhdr->isymMax;
868       output_symhdr->isymMax += fdr.csym;
869 
870       /* Copy the information that does not need swapping.  */
871 
872       /* FIXME: If we are relaxing, we need to adjust the line
873 	 numbers.  Frankly, forget it.  Anybody using stabs debugging
874 	 information will not use this line number information, and
875 	 stabs are adjusted correctly.  */
876       if (fdr.cbLine > 0)
877 	{
878 	  file_ptr pos = input_symhdr->cbLineOffset + fdr.cbLineOffset;
879 	  if (!add_file_shuffle (ainfo, &ainfo->line, &ainfo->line_end,
880 				 input_bfd, pos, (unsigned long) fdr.cbLine))
881 	    return FALSE;
882 	  fdr.ilineBase = output_symhdr->ilineMax;
883 	  fdr.cbLineOffset = output_symhdr->cbLine;
884 	  output_symhdr->ilineMax += fdr.cline;
885 	  output_symhdr->cbLine += fdr.cbLine;
886 	}
887       if (fdr.caux > 0)
888 	{
889 	  file_ptr pos = (input_symhdr->cbAuxOffset
890 			  + fdr.iauxBase * sizeof (union aux_ext));
891 	  if (!add_file_shuffle (ainfo, &ainfo->aux, &ainfo->aux_end,
892 				 input_bfd, pos,
893 				 fdr.caux * sizeof (union aux_ext)))
894 	    return FALSE;
895 	  fdr.iauxBase = output_symhdr->iauxMax;
896 	  output_symhdr->iauxMax += fdr.caux;
897 	}
898       if (! bfd_link_relocatable (info))
899 	{
900 
901 	  /* When are are hashing strings, we lie about the number of
902 	     strings attached to each FDR.  We need to set cbSs
903 	     because some versions of dbx apparently use it to decide
904 	     how much of the string table to read in.  */
905 	  fdr.issBase = 0;
906 	  fdr.cbSs = output_symhdr->issMax;
907 	}
908       else if (fdr.cbSs > 0)
909 	{
910 	  file_ptr pos = input_symhdr->cbSsOffset + fdr.issBase;
911 	  if (!add_file_shuffle (ainfo, &ainfo->ss, &ainfo->ss_end,
912 				 input_bfd, pos, (unsigned long) fdr.cbSs))
913 	    return FALSE;
914 	  fdr.issBase = output_symhdr->issMax;
915 	  output_symhdr->issMax += fdr.cbSs;
916 	}
917 
918       if (output_bfd->xvec->header_byteorder
919 	  == input_bfd->xvec->header_byteorder)
920 	{
921 	  /* The two BFD's have the same endianness, and we don't have
922 	     to adjust the PDR addresses, so simply copying the
923 	     information will suffice.  */
924 	  BFD_ASSERT (external_pdr_size == input_swap->external_pdr_size);
925 	  if (fdr.cpd > 0)
926 	    {
927 	      file_ptr pos = (input_symhdr->cbPdOffset
928 			      + fdr.ipdFirst * external_pdr_size);
929 	      unsigned long size = fdr.cpd * external_pdr_size;
930 	      if (!add_file_shuffle (ainfo, &ainfo->pdr, &ainfo->pdr_end,
931 				     input_bfd, pos, size))
932 		return FALSE;
933 	    }
934 	  BFD_ASSERT (external_opt_size == input_swap->external_opt_size);
935 	  if (fdr.copt > 0)
936 	    {
937 	      file_ptr pos = (input_symhdr->cbOptOffset
938 			      + fdr.ioptBase * external_opt_size);
939 	      unsigned long size = fdr.copt * external_opt_size;
940 	      if (!add_file_shuffle (ainfo, &ainfo->opt, &ainfo->opt_end,
941 				     input_bfd, pos, size))
942 		return FALSE;
943 	    }
944 	}
945       else
946 	{
947 	  bfd_size_type outsz, insz;
948 	  bfd_byte *in;
949 	  bfd_byte *end;
950 	  bfd_byte *out;
951 
952 	  /* The two BFD's have different endianness, so we must swap
953 	     everything in and out.  This code would always work, but
954 	     it would be unnecessarily slow in the normal case.  */
955 	  outsz = external_pdr_size;
956 	  insz = input_swap->external_pdr_size;
957 	  in = ((bfd_byte *) input_debug->external_pdr
958 		+ fdr.ipdFirst * insz);
959 	  end = in + fdr.cpd * insz;
960 	  sz = fdr.cpd * outsz;
961 	  out = (bfd_byte *) objalloc_alloc (ainfo->memory, sz);
962 	  if (!out)
963 	    {
964 	      bfd_set_error (bfd_error_no_memory);
965 	      return FALSE;
966 	    }
967 	  if (!add_memory_shuffle (ainfo, &ainfo->pdr, &ainfo->pdr_end, out,
968 				   sz))
969 	    return FALSE;
970 	  for (; in < end; in += insz, out += outsz)
971 	    {
972 	      PDR pdr;
973 
974 	      (*input_swap->swap_pdr_in) (input_bfd, in, &pdr);
975 	      (*output_swap->swap_pdr_out) (output_bfd, &pdr, out);
976 	    }
977 
978 	  /* Swap over the optimization information.  */
979 	  outsz = external_opt_size;
980 	  insz = input_swap->external_opt_size;
981 	  in = ((bfd_byte *) input_debug->external_opt
982 		+ fdr.ioptBase * insz);
983 	  end = in + fdr.copt * insz;
984 	  sz = fdr.copt * outsz;
985 	  out = (bfd_byte *) objalloc_alloc (ainfo->memory, sz);
986 	  if (!out)
987 	    {
988 	      bfd_set_error (bfd_error_no_memory);
989 	      return FALSE;
990 	    }
991 	  if (!add_memory_shuffle (ainfo, &ainfo->opt, &ainfo->opt_end, out,
992 				   sz))
993 	    return FALSE;
994 	  for (; in < end; in += insz, out += outsz)
995 	    {
996 	      OPTR opt;
997 
998 	      (*input_swap->swap_opt_in) (input_bfd, in, &opt);
999 	      (*output_swap->swap_opt_out) (output_bfd, &opt, out);
1000 	    }
1001 	}
1002 
1003       fdr.ipdFirst = output_symhdr->ipdMax;
1004       output_symhdr->ipdMax += fdr.cpd;
1005       fdr.ioptBase = output_symhdr->ioptMax;
1006       output_symhdr->ioptMax += fdr.copt;
1007 
1008       if (fdr.crfd <= 0)
1009 	{
1010 	  /* Point this FDR at the table of RFD's we created.  */
1011 	  fdr.rfdBase = newrfdbase;
1012 	  fdr.crfd = input_symhdr->ifdMax;
1013 	}
1014       else
1015 	{
1016 	  /* Point this FDR at the remapped RFD's.  */
1017 	  fdr.rfdBase += oldrfdbase;
1018 	}
1019 
1020       (*swap_fdr_out) (output_bfd, &fdr, fdr_out);
1021       fdr_out += external_fdr_size;
1022       ++output_symhdr->ifdMax;
1023     }
1024 
1025   return TRUE;
1026 }
1027 
1028 /* Add a string to the debugging information we are accumulating.
1029    Return the offset from the fdr string base.  */
1030 
1031 static long
ecoff_add_string(struct accumulate * ainfo,struct bfd_link_info * info,struct ecoff_debug_info * debug,FDR * fdr,const char * string)1032 ecoff_add_string (struct accumulate *ainfo,
1033 		  struct bfd_link_info *info,
1034 		  struct ecoff_debug_info *debug,
1035 		  FDR *fdr,
1036 		  const char *string)
1037 {
1038   HDRR *symhdr;
1039   size_t len;
1040   bfd_size_type ret;
1041 
1042   symhdr = &debug->symbolic_header;
1043   len = strlen (string);
1044   if (bfd_link_relocatable (info))
1045     {
1046       if (!add_memory_shuffle (ainfo, &ainfo->ss, &ainfo->ss_end,
1047                                (bfd_byte *) string, len + 1))
1048 	return -1;
1049       ret = symhdr->issMax;
1050       symhdr->issMax += len + 1;
1051       fdr->cbSs += len + 1;
1052     }
1053   else
1054     {
1055       struct string_hash_entry *sh;
1056 
1057       sh = string_hash_lookup (&ainfo->str_hash, string, TRUE, TRUE);
1058       if (sh == (struct string_hash_entry *) NULL)
1059 	return -1;
1060       if (sh->val == -1)
1061 	{
1062 	  sh->val = symhdr->issMax;
1063 	  symhdr->issMax += len + 1;
1064 	  if (ainfo->ss_hash == (struct string_hash_entry *) NULL)
1065 	    ainfo->ss_hash = sh;
1066 	  if (ainfo->ss_hash_end
1067 	      != (struct string_hash_entry *) NULL)
1068 	    ainfo->ss_hash_end->next = sh;
1069 	  ainfo->ss_hash_end = sh;
1070 	}
1071       ret = sh->val;
1072     }
1073 
1074   return ret;
1075 }
1076 
1077 /* Add debugging information from a non-ECOFF file.  */
1078 
1079 bfd_boolean
bfd_ecoff_debug_accumulate_other(void * handle,bfd * output_bfd,struct ecoff_debug_info * output_debug,const struct ecoff_debug_swap * output_swap,bfd * input_bfd,struct bfd_link_info * info)1080 bfd_ecoff_debug_accumulate_other (void * handle,
1081 				  bfd *output_bfd,
1082 				  struct ecoff_debug_info *output_debug,
1083 				  const struct ecoff_debug_swap *output_swap,
1084 				  bfd *input_bfd,
1085 				  struct bfd_link_info *info)
1086 {
1087   struct accumulate *ainfo = (struct accumulate *) handle;
1088   void (* const swap_sym_out) (bfd *, const SYMR *, void *)
1089     = output_swap->swap_sym_out;
1090   HDRR *output_symhdr = &output_debug->symbolic_header;
1091   FDR fdr;
1092   asection *sec;
1093   asymbol **symbols;
1094   asymbol **sym_ptr;
1095   asymbol **sym_end;
1096   long symsize;
1097   long symcount;
1098   void * external_fdr;
1099 
1100   memset (&fdr, 0, sizeof fdr);
1101 
1102   sec = bfd_get_section_by_name (input_bfd, ".text");
1103   if (sec != NULL)
1104     fdr.adr = sec->output_section->vma + sec->output_offset;
1105   else
1106     {
1107       /* FIXME: What about .init or .fini?  */
1108       fdr.adr = 0;
1109     }
1110 
1111   fdr.issBase = output_symhdr->issMax;
1112   fdr.cbSs = 0;
1113   fdr.rss = ecoff_add_string (ainfo, info, output_debug, &fdr,
1114 			      input_bfd->filename);
1115   if (fdr.rss == -1)
1116     return FALSE;
1117   fdr.isymBase = output_symhdr->isymMax;
1118 
1119   /* Get the local symbols from the input BFD.  */
1120   symsize = bfd_get_symtab_upper_bound (input_bfd);
1121   if (symsize < 0)
1122     return FALSE;
1123   symbols = (asymbol **) bfd_alloc (output_bfd, (bfd_size_type) symsize);
1124   if (symbols == (asymbol **) NULL)
1125     return FALSE;
1126   symcount = bfd_canonicalize_symtab (input_bfd, symbols);
1127   if (symcount < 0)
1128     return FALSE;
1129   sym_end = symbols + symcount;
1130 
1131   /* Handle the local symbols.  Any external symbols are handled
1132      separately.  */
1133   fdr.csym = 0;
1134   for (sym_ptr = symbols; sym_ptr != sym_end; sym_ptr++)
1135     {
1136       SYMR internal_sym;
1137       void * external_sym;
1138 
1139       if (((*sym_ptr)->flags & BSF_EXPORT) != 0)
1140 	continue;
1141       memset (&internal_sym, 0, sizeof internal_sym);
1142       internal_sym.iss = ecoff_add_string (ainfo, info, output_debug, &fdr,
1143 					   (*sym_ptr)->name);
1144 
1145       if (internal_sym.iss == -1)
1146 	return FALSE;
1147       if (bfd_is_com_section ((*sym_ptr)->section)
1148 	  || bfd_is_und_section ((*sym_ptr)->section))
1149 	internal_sym.value = (*sym_ptr)->value;
1150       else
1151 	internal_sym.value = ((*sym_ptr)->value
1152 			      + (*sym_ptr)->section->output_offset
1153 			      + (*sym_ptr)->section->output_section->vma);
1154       internal_sym.st = stNil;
1155       internal_sym.sc = scUndefined;
1156       internal_sym.index = indexNil;
1157 
1158       external_sym = objalloc_alloc (ainfo->memory,
1159 				     output_swap->external_sym_size);
1160       if (!external_sym)
1161 	{
1162 	  bfd_set_error (bfd_error_no_memory);
1163 	  return FALSE;
1164 	}
1165       (*swap_sym_out) (output_bfd, &internal_sym, external_sym);
1166       add_memory_shuffle (ainfo, &ainfo->sym, &ainfo->sym_end,
1167 			  (bfd_byte *) external_sym,
1168 			  (unsigned long) output_swap->external_sym_size);
1169       ++fdr.csym;
1170       ++output_symhdr->isymMax;
1171     }
1172 
1173   bfd_release (output_bfd, symbols);
1174 
1175   /* Leave everything else in the FDR zeroed out.  This will cause
1176      the lang field to be langC.  The fBigendian field will
1177      indicate little endian format, but it doesn't matter because
1178      it only applies to aux fields and there are none.  */
1179   external_fdr = objalloc_alloc (ainfo->memory,
1180 				 output_swap->external_fdr_size);
1181   if (!external_fdr)
1182     {
1183       bfd_set_error (bfd_error_no_memory);
1184       return FALSE;
1185     }
1186   (*output_swap->swap_fdr_out) (output_bfd, &fdr, external_fdr);
1187   add_memory_shuffle (ainfo, &ainfo->fdr, &ainfo->fdr_end,
1188 		      (bfd_byte *) external_fdr,
1189 		      (unsigned long) output_swap->external_fdr_size);
1190 
1191   ++output_symhdr->ifdMax;
1192 
1193   return TRUE;
1194 }
1195 
1196 /* Set up ECOFF debugging information for the external symbols.
1197    FIXME: This is done using a memory buffer, but it should be
1198    probably be changed to use a shuffle structure.  The assembler uses
1199    this interface, so that must be changed to do something else.  */
1200 
1201 bfd_boolean
bfd_ecoff_debug_externals(bfd * abfd,struct ecoff_debug_info * debug,const struct ecoff_debug_swap * swap,bfd_boolean relocatable,bfd_boolean (* get_extr)(asymbol *,EXTR *),void (* set_index)(asymbol *,bfd_size_type))1202 bfd_ecoff_debug_externals (bfd *abfd,
1203 			   struct ecoff_debug_info *debug,
1204 			   const struct ecoff_debug_swap *swap,
1205 			   bfd_boolean relocatable,
1206 			   bfd_boolean (*get_extr) (asymbol *, EXTR *),
1207 			   void (*set_index) (asymbol *, bfd_size_type))
1208 {
1209   HDRR * const symhdr = &debug->symbolic_header;
1210   asymbol **sym_ptr_ptr;
1211   size_t c;
1212 
1213   sym_ptr_ptr = bfd_get_outsymbols (abfd);
1214   if (sym_ptr_ptr == NULL)
1215     return TRUE;
1216 
1217   for (c = bfd_get_symcount (abfd); c > 0; c--, sym_ptr_ptr++)
1218     {
1219       asymbol *sym_ptr;
1220       EXTR esym;
1221 
1222       sym_ptr = *sym_ptr_ptr;
1223 
1224       /* Get the external symbol information.  */
1225       if (! (*get_extr) (sym_ptr, &esym))
1226 	continue;
1227 
1228       /* If we're producing an executable, move common symbols into
1229 	 bss.  */
1230       if (! relocatable)
1231 	{
1232 	  if (esym.asym.sc == scCommon)
1233 	    esym.asym.sc = scBss;
1234 	  else if (esym.asym.sc == scSCommon)
1235 	    esym.asym.sc = scSBss;
1236 	}
1237 
1238       if (bfd_is_com_section (sym_ptr->section)
1239 	  || bfd_is_und_section (sym_ptr->section)
1240 	  || sym_ptr->section->output_section == (asection *) NULL)
1241 	{
1242 	  /* FIXME: gas does not keep the value of a small undefined
1243 	     symbol in the symbol itself, because of relocation
1244 	     problems.  */
1245 	  if (esym.asym.sc != scSUndefined
1246 	      || esym.asym.value == 0
1247 	      || sym_ptr->value != 0)
1248 	    esym.asym.value = sym_ptr->value;
1249 	}
1250       else
1251 	esym.asym.value = (sym_ptr->value
1252 			   + sym_ptr->section->output_offset
1253 			   + sym_ptr->section->output_section->vma);
1254 
1255       if (set_index)
1256 	(*set_index) (sym_ptr, (bfd_size_type) symhdr->iextMax);
1257 
1258       if (! bfd_ecoff_debug_one_external (abfd, debug, swap,
1259 					  sym_ptr->name, &esym))
1260 	return FALSE;
1261     }
1262 
1263   return TRUE;
1264 }
1265 
1266 /* Add a single external symbol to the debugging information.  */
1267 
1268 bfd_boolean
bfd_ecoff_debug_one_external(bfd * abfd,struct ecoff_debug_info * debug,const struct ecoff_debug_swap * swap,const char * name,EXTR * esym)1269 bfd_ecoff_debug_one_external (bfd *abfd,
1270 			      struct ecoff_debug_info *debug,
1271 			      const struct ecoff_debug_swap *swap,
1272 			      const char *name,
1273 			      EXTR *esym)
1274 {
1275   const bfd_size_type external_ext_size = swap->external_ext_size;
1276   void (* const swap_ext_out) (bfd *, const EXTR *, void *)
1277     = swap->swap_ext_out;
1278   HDRR * const symhdr = &debug->symbolic_header;
1279   size_t namelen;
1280 
1281   namelen = strlen (name);
1282 
1283   if ((size_t) (debug->ssext_end - debug->ssext)
1284       < symhdr->issExtMax + namelen + 1)
1285     {
1286       if (! ecoff_add_bytes ((char **) &debug->ssext,
1287 			     (char **) &debug->ssext_end,
1288 			     symhdr->issExtMax + namelen + 1))
1289 	return FALSE;
1290     }
1291   if ((size_t) ((char *) debug->external_ext_end
1292 		- (char *) debug->external_ext)
1293       < (symhdr->iextMax + 1) * external_ext_size)
1294     {
1295       char *external_ext = (char *) debug->external_ext;
1296       char *external_ext_end = (char *) debug->external_ext_end;
1297       if (! ecoff_add_bytes ((char **) &external_ext,
1298 			     (char **) &external_ext_end,
1299 			     (symhdr->iextMax + 1) * (size_t) external_ext_size))
1300 	return FALSE;
1301       debug->external_ext = external_ext;
1302       debug->external_ext_end = external_ext_end;
1303     }
1304 
1305   esym->asym.iss = symhdr->issExtMax;
1306 
1307   (*swap_ext_out) (abfd, esym,
1308 		   ((char *) debug->external_ext
1309 		    + symhdr->iextMax * swap->external_ext_size));
1310 
1311   ++symhdr->iextMax;
1312 
1313   strcpy (debug->ssext + symhdr->issExtMax, name);
1314   symhdr->issExtMax += namelen + 1;
1315 
1316   return TRUE;
1317 }
1318 
1319 /* Align the ECOFF debugging information.  */
1320 
1321 static void
ecoff_align_debug(bfd * abfd ATTRIBUTE_UNUSED,struct ecoff_debug_info * debug,const struct ecoff_debug_swap * swap)1322 ecoff_align_debug (bfd *abfd ATTRIBUTE_UNUSED,
1323 		   struct ecoff_debug_info *debug,
1324 		   const struct ecoff_debug_swap *swap)
1325 {
1326   HDRR * const symhdr = &debug->symbolic_header;
1327   bfd_size_type debug_align, aux_align, rfd_align;
1328   size_t add;
1329 
1330   /* Adjust the counts so that structures are aligned.  */
1331   debug_align = swap->debug_align;
1332   aux_align = debug_align / sizeof (union aux_ext);
1333   rfd_align = debug_align / swap->external_rfd_size;
1334 
1335   add = debug_align - (symhdr->cbLine & (debug_align - 1));
1336   if (add != debug_align)
1337     {
1338       if (debug->line != (unsigned char *) NULL)
1339 	memset ((debug->line + symhdr->cbLine), 0, add);
1340       symhdr->cbLine += add;
1341     }
1342 
1343   add = debug_align - (symhdr->issMax & (debug_align - 1));
1344   if (add != debug_align)
1345     {
1346       if (debug->ss != (char *) NULL)
1347 	memset ((debug->ss + symhdr->issMax), 0, add);
1348       symhdr->issMax += add;
1349     }
1350 
1351   add = debug_align - (symhdr->issExtMax & (debug_align - 1));
1352   if (add != debug_align)
1353     {
1354       if (debug->ssext != (char *) NULL)
1355 	memset ((debug->ssext + symhdr->issExtMax), 0, add);
1356       symhdr->issExtMax += add;
1357     }
1358 
1359   add = aux_align - (symhdr->iauxMax & (aux_align - 1));
1360   if (add != aux_align)
1361     {
1362       if (debug->external_aux != (union aux_ext *) NULL)
1363 	memset ((debug->external_aux + symhdr->iauxMax), 0,
1364 		add * sizeof (union aux_ext));
1365       symhdr->iauxMax += add;
1366     }
1367 
1368   add = rfd_align - (symhdr->crfd & (rfd_align - 1));
1369   if (add != rfd_align)
1370     {
1371       if (debug->external_rfd != NULL)
1372 	memset (((char *) debug->external_rfd
1373 		 + symhdr->crfd * swap->external_rfd_size),
1374 		0, (size_t) (add * swap->external_rfd_size));
1375       symhdr->crfd += add;
1376     }
1377 }
1378 
1379 /* Return the size required by the ECOFF debugging information.  */
1380 
1381 bfd_size_type
bfd_ecoff_debug_size(bfd * abfd,struct ecoff_debug_info * debug,const struct ecoff_debug_swap * swap)1382 bfd_ecoff_debug_size (bfd *abfd,
1383 		      struct ecoff_debug_info *debug,
1384 		      const struct ecoff_debug_swap *swap)
1385 {
1386   bfd_size_type tot;
1387 
1388   ecoff_align_debug (abfd, debug, swap);
1389   tot = swap->external_hdr_size;
1390 
1391 #define ADD(count, size) \
1392   tot += debug->symbolic_header.count * size
1393 
1394   ADD (cbLine, sizeof (unsigned char));
1395   ADD (idnMax, swap->external_dnr_size);
1396   ADD (ipdMax, swap->external_pdr_size);
1397   ADD (isymMax, swap->external_sym_size);
1398   ADD (ioptMax, swap->external_opt_size);
1399   ADD (iauxMax, sizeof (union aux_ext));
1400   ADD (issMax, sizeof (char));
1401   ADD (issExtMax, sizeof (char));
1402   ADD (ifdMax, swap->external_fdr_size);
1403   ADD (crfd, swap->external_rfd_size);
1404   ADD (iextMax, swap->external_ext_size);
1405 
1406 #undef ADD
1407 
1408   return tot;
1409 }
1410 
1411 /* Write out the ECOFF symbolic header, given the file position it is
1412    going to be placed at.  This assumes that the counts are set
1413    correctly.  */
1414 
1415 static bfd_boolean
ecoff_write_symhdr(bfd * abfd,struct ecoff_debug_info * debug,const struct ecoff_debug_swap * swap,file_ptr where)1416 ecoff_write_symhdr (bfd *abfd,
1417 		    struct ecoff_debug_info *debug,
1418 		    const struct ecoff_debug_swap *swap,
1419 		    file_ptr where)
1420 {
1421   HDRR * const symhdr = &debug->symbolic_header;
1422   char *buff = NULL;
1423 
1424   ecoff_align_debug (abfd, debug, swap);
1425 
1426   /* Go to the right location in the file.  */
1427   if (bfd_seek (abfd, where, SEEK_SET) != 0)
1428     return FALSE;
1429 
1430   where += swap->external_hdr_size;
1431 
1432   symhdr->magic = swap->sym_magic;
1433 
1434   /* Fill in the file offsets.  */
1435 #define SET(offset, count, size) \
1436   if (symhdr->count == 0) \
1437     symhdr->offset = 0; \
1438   else \
1439     { \
1440       symhdr->offset = where; \
1441       where += symhdr->count * size; \
1442     }
1443 
1444   SET (cbLineOffset, cbLine, sizeof (unsigned char));
1445   SET (cbDnOffset, idnMax, swap->external_dnr_size);
1446   SET (cbPdOffset, ipdMax, swap->external_pdr_size);
1447   SET (cbSymOffset, isymMax, swap->external_sym_size);
1448   SET (cbOptOffset, ioptMax, swap->external_opt_size);
1449   SET (cbAuxOffset, iauxMax, sizeof (union aux_ext));
1450   SET (cbSsOffset, issMax, sizeof (char));
1451   SET (cbSsExtOffset, issExtMax, sizeof (char));
1452   SET (cbFdOffset, ifdMax, swap->external_fdr_size);
1453   SET (cbRfdOffset, crfd, swap->external_rfd_size);
1454   SET (cbExtOffset, iextMax, swap->external_ext_size);
1455 #undef SET
1456 
1457   buff = (char *) bfd_malloc (swap->external_hdr_size);
1458   if (buff == NULL && swap->external_hdr_size != 0)
1459     goto error_return;
1460 
1461   (*swap->swap_hdr_out) (abfd, symhdr, buff);
1462   if (bfd_bwrite (buff, swap->external_hdr_size, abfd)
1463       != swap->external_hdr_size)
1464     goto error_return;
1465 
1466   if (buff != NULL)
1467     free (buff);
1468   return TRUE;
1469  error_return:
1470   if (buff != NULL)
1471     free (buff);
1472   return FALSE;
1473 }
1474 
1475 /* Write out the ECOFF debugging information.  This function assumes
1476    that the information (the pointers and counts) in *DEBUG have been
1477    set correctly.  WHERE is the position in the file to write the
1478    information to.  This function fills in the file offsets in the
1479    symbolic header.  */
1480 
1481 bfd_boolean
bfd_ecoff_write_debug(bfd * abfd,struct ecoff_debug_info * debug,const struct ecoff_debug_swap * swap,file_ptr where)1482 bfd_ecoff_write_debug (bfd *abfd,
1483 		       struct ecoff_debug_info *debug,
1484 		       const struct ecoff_debug_swap *swap,
1485 		       file_ptr where)
1486 {
1487   HDRR * const symhdr = &debug->symbolic_header;
1488 
1489   if (! ecoff_write_symhdr (abfd, debug, swap, where))
1490     return FALSE;
1491 
1492 #define WRITE(ptr, count, size, offset) \
1493   BFD_ASSERT (symhdr->offset == 0 \
1494 	      || (bfd_vma) bfd_tell (abfd) == symhdr->offset); \
1495   if (bfd_bwrite (debug->ptr, (bfd_size_type) size * symhdr->count, abfd)\
1496       != size * symhdr->count) \
1497     return FALSE;
1498 
1499   WRITE (line, cbLine, sizeof (unsigned char), cbLineOffset);
1500   WRITE (external_dnr, idnMax, swap->external_dnr_size, cbDnOffset);
1501   WRITE (external_pdr, ipdMax, swap->external_pdr_size, cbPdOffset);
1502   WRITE (external_sym, isymMax, swap->external_sym_size, cbSymOffset);
1503   WRITE (external_opt, ioptMax, swap->external_opt_size, cbOptOffset);
1504   WRITE (external_aux, iauxMax, (bfd_size_type) sizeof (union aux_ext),
1505 	 cbAuxOffset);
1506   WRITE (ss, issMax, sizeof (char), cbSsOffset);
1507   WRITE (ssext, issExtMax, sizeof (char), cbSsExtOffset);
1508   WRITE (external_fdr, ifdMax, swap->external_fdr_size, cbFdOffset);
1509   WRITE (external_rfd, crfd, swap->external_rfd_size, cbRfdOffset);
1510   WRITE (external_ext, iextMax, swap->external_ext_size, cbExtOffset);
1511 #undef WRITE
1512 
1513   return TRUE;
1514 }
1515 
1516 /* Write out a shuffle list.  */
1517 
1518 
1519 static bfd_boolean
ecoff_write_shuffle(bfd * abfd,const struct ecoff_debug_swap * swap,struct shuffle * shuffle,void * space)1520 ecoff_write_shuffle (bfd *abfd,
1521 		     const struct ecoff_debug_swap *swap,
1522 		     struct shuffle *shuffle,
1523 		     void * space)
1524 {
1525   struct shuffle *l;
1526   unsigned long total;
1527 
1528   total = 0;
1529   for (l = shuffle; l != (struct shuffle *) NULL; l = l->next)
1530     {
1531       if (! l->filep)
1532 	{
1533 	  if (bfd_bwrite (l->u.memory, (bfd_size_type) l->size, abfd)
1534 	      != l->size)
1535 	    return FALSE;
1536 	}
1537       else
1538 	{
1539 	  if (bfd_seek (l->u.file.input_bfd, l->u.file.offset, SEEK_SET) != 0
1540 	      || bfd_bread (space, (bfd_size_type) l->size,
1541 			   l->u.file.input_bfd) != l->size
1542 	      || bfd_bwrite (space, (bfd_size_type) l->size, abfd) != l->size)
1543 	    return FALSE;
1544 	}
1545       total += l->size;
1546     }
1547 
1548   if ((total & (swap->debug_align - 1)) != 0)
1549     {
1550       unsigned int i;
1551       bfd_byte *s;
1552 
1553       i = swap->debug_align - (total & (swap->debug_align - 1));
1554       s = (bfd_byte *) bfd_zmalloc ((bfd_size_type) i);
1555       if (s == NULL && i != 0)
1556 	return FALSE;
1557 
1558       if (bfd_bwrite (s, (bfd_size_type) i, abfd) != i)
1559 	{
1560 	  free (s);
1561 	  return FALSE;
1562 	}
1563       free (s);
1564     }
1565 
1566   return TRUE;
1567 }
1568 
1569 /* Write out debugging information using accumulated linker
1570    information.  */
1571 
1572 bfd_boolean
bfd_ecoff_write_accumulated_debug(void * handle,bfd * abfd,struct ecoff_debug_info * debug,const struct ecoff_debug_swap * swap,struct bfd_link_info * info,file_ptr where)1573 bfd_ecoff_write_accumulated_debug (void * handle,
1574 				   bfd *abfd,
1575 				   struct ecoff_debug_info *debug,
1576 				   const struct ecoff_debug_swap *swap,
1577 				   struct bfd_link_info *info,
1578 				   file_ptr where)
1579 {
1580   struct accumulate *ainfo = (struct accumulate *) handle;
1581   void * space = NULL;
1582   bfd_size_type amt;
1583 
1584   if (! ecoff_write_symhdr (abfd, debug, swap, where))
1585     goto error_return;
1586 
1587   amt = ainfo->largest_file_shuffle;
1588   space = bfd_malloc (amt);
1589   if (space == NULL && ainfo->largest_file_shuffle != 0)
1590     goto error_return;
1591 
1592   if (! ecoff_write_shuffle (abfd, swap, ainfo->line, space)
1593       || ! ecoff_write_shuffle (abfd, swap, ainfo->pdr, space)
1594       || ! ecoff_write_shuffle (abfd, swap, ainfo->sym, space)
1595       || ! ecoff_write_shuffle (abfd, swap, ainfo->opt, space)
1596       || ! ecoff_write_shuffle (abfd, swap, ainfo->aux, space))
1597     goto error_return;
1598 
1599   /* The string table is written out from the hash table if this is a
1600      final link.  */
1601   if (bfd_link_relocatable (info))
1602     {
1603       BFD_ASSERT (ainfo->ss_hash == (struct string_hash_entry *) NULL);
1604       if (! ecoff_write_shuffle (abfd, swap, ainfo->ss, space))
1605 	goto error_return;
1606     }
1607   else
1608     {
1609       unsigned long total;
1610       bfd_byte null;
1611       struct string_hash_entry *sh;
1612 
1613       BFD_ASSERT (ainfo->ss == (struct shuffle *) NULL);
1614       null = 0;
1615       if (bfd_bwrite (&null, (bfd_size_type) 1, abfd) != 1)
1616 	goto error_return;
1617       total = 1;
1618       BFD_ASSERT (ainfo->ss_hash == NULL || ainfo->ss_hash->val == 1);
1619       for (sh = ainfo->ss_hash;
1620 	   sh != (struct string_hash_entry *) NULL;
1621 	   sh = sh->next)
1622 	{
1623 	  size_t len;
1624 
1625 	  len = strlen (sh->root.string);
1626 	  amt = len + 1;
1627 	  if (bfd_bwrite (sh->root.string, amt, abfd) != amt)
1628 	    goto error_return;
1629 	  total += len + 1;
1630 	}
1631 
1632       if ((total & (swap->debug_align - 1)) != 0)
1633 	{
1634 	  unsigned int i;
1635 	  bfd_byte *s;
1636 
1637 	  i = swap->debug_align - (total & (swap->debug_align - 1));
1638 	  s = (bfd_byte *) bfd_zmalloc ((bfd_size_type) i);
1639 	  if (s == NULL && i != 0)
1640 	    goto error_return;
1641 
1642 	  if (bfd_bwrite (s, (bfd_size_type) i, abfd) != i)
1643 	    {
1644 	      free (s);
1645 	      goto error_return;
1646 	    }
1647 	  free (s);
1648 	}
1649     }
1650 
1651   /* The external strings and symbol are not converted over to using
1652      shuffles.  FIXME: They probably should be.  */
1653   amt = debug->symbolic_header.issExtMax;
1654   if (bfd_bwrite (debug->ssext, amt, abfd) != amt)
1655     goto error_return;
1656   if ((debug->symbolic_header.issExtMax & (swap->debug_align - 1)) != 0)
1657     {
1658       unsigned int i;
1659       bfd_byte *s;
1660 
1661       i = (swap->debug_align
1662 	   - (debug->symbolic_header.issExtMax & (swap->debug_align - 1)));
1663       s = (bfd_byte *) bfd_zmalloc ((bfd_size_type) i);
1664       if (s == NULL && i != 0)
1665 	goto error_return;
1666 
1667       if (bfd_bwrite (s, (bfd_size_type) i, abfd) != i)
1668 	{
1669 	  free (s);
1670 	  goto error_return;
1671 	}
1672       free (s);
1673     }
1674 
1675   if (! ecoff_write_shuffle (abfd, swap, ainfo->fdr, space)
1676       || ! ecoff_write_shuffle (abfd, swap, ainfo->rfd, space))
1677     goto error_return;
1678 
1679   BFD_ASSERT (debug->symbolic_header.cbExtOffset == 0
1680 	      || (debug->symbolic_header.cbExtOffset
1681 		  == (bfd_vma) bfd_tell (abfd)));
1682 
1683   amt = debug->symbolic_header.iextMax * swap->external_ext_size;
1684   if (bfd_bwrite (debug->external_ext, amt, abfd) != amt)
1685     goto error_return;
1686 
1687   if (space != NULL)
1688     free (space);
1689   return TRUE;
1690 
1691  error_return:
1692   if (space != NULL)
1693     free (space);
1694   return FALSE;
1695 }
1696 
1697 /* Handle the find_nearest_line function for both ECOFF and MIPS ELF
1698    files.  */
1699 
1700 /* Compare FDR entries.  This is called via qsort.  */
1701 
1702 static int
cmp_fdrtab_entry(const void * leftp,const void * rightp)1703 cmp_fdrtab_entry (const void * leftp, const void * rightp)
1704 {
1705   const struct ecoff_fdrtab_entry *lp =
1706     (const struct ecoff_fdrtab_entry *) leftp;
1707   const struct ecoff_fdrtab_entry *rp =
1708     (const struct ecoff_fdrtab_entry *) rightp;
1709 
1710   if (lp->base_addr < rp->base_addr)
1711     return -1;
1712   if (lp->base_addr > rp->base_addr)
1713     return 1;
1714   return 0;
1715 }
1716 
1717 /* Each file descriptor (FDR) has a memory address, to simplify
1718    looking up an FDR by address, we build a table covering all FDRs
1719    that have a least one procedure descriptor in them.  The final
1720    table will be sorted by address so we can look it up via binary
1721    search.  */
1722 
1723 static bfd_boolean
mk_fdrtab(bfd * abfd,struct ecoff_debug_info * const debug_info,const struct ecoff_debug_swap * const debug_swap,struct ecoff_find_line * line_info)1724 mk_fdrtab (bfd *abfd,
1725 	   struct ecoff_debug_info * const debug_info,
1726 	   const struct ecoff_debug_swap * const debug_swap,
1727 	   struct ecoff_find_line *line_info)
1728 {
1729   struct ecoff_fdrtab_entry *tab;
1730   FDR *fdr_ptr;
1731   FDR *fdr_start;
1732   FDR *fdr_end;
1733   bfd_boolean stabs;
1734   long len;
1735   bfd_size_type amt;
1736 
1737   fdr_start = debug_info->fdr;
1738   fdr_end = fdr_start + debug_info->symbolic_header.ifdMax;
1739 
1740   /* First, let's see how long the table needs to be.  */
1741   for (len = 0, fdr_ptr = fdr_start; fdr_ptr < fdr_end; fdr_ptr++)
1742     {
1743       if (fdr_ptr->cpd == 0)	/* Skip FDRs that have no PDRs.  */
1744 	continue;
1745       ++len;
1746     }
1747 
1748   /* Now, create and fill in the table.  */
1749   amt = (bfd_size_type) len * sizeof (struct ecoff_fdrtab_entry);
1750   line_info->fdrtab = (struct ecoff_fdrtab_entry*) bfd_zalloc (abfd, amt);
1751   if (line_info->fdrtab == NULL)
1752     return FALSE;
1753   line_info->fdrtab_len = len;
1754 
1755   tab = line_info->fdrtab;
1756   for (fdr_ptr = fdr_start; fdr_ptr < fdr_end; fdr_ptr++)
1757     {
1758       if (fdr_ptr->cpd == 0)
1759 	continue;
1760 
1761       /* Check whether this file has stabs debugging information.  In
1762 	 a file with stabs debugging information, the second local
1763 	 symbol is named @stabs.  */
1764       stabs = FALSE;
1765       if (fdr_ptr->csym >= 2)
1766 	{
1767 	  char *sym_ptr;
1768 	  SYMR sym;
1769 
1770 	  sym_ptr = ((char *) debug_info->external_sym
1771 		     + (fdr_ptr->isymBase + 1) * debug_swap->external_sym_size);
1772 	  (*debug_swap->swap_sym_in) (abfd, sym_ptr, &sym);
1773 	  if (strcmp (debug_info->ss + fdr_ptr->issBase + sym.iss,
1774 		      STABS_SYMBOL) == 0)
1775 	    stabs = TRUE;
1776 	}
1777 
1778       if (!stabs)
1779 	{
1780 	  /* eraxxon: There are at least two problems with this computation:
1781 	     1) PDRs do *not* contain offsets but full vma's; and typically the
1782 	     address of the first PDR is the address of the FDR, which will
1783 	     make (most) of the results of the original computation 0!
1784 	     2) Once in a wacky while, the Compaq compiler generated PDR
1785 	     addresses do not equal the FDR vma, but they (the PDR address)
1786 	     are still vma's and not offsets.  Cf. comments in
1787 	     'lookup_line'.  */
1788 	  /* The address of the first PDR is the offset of that
1789 	     procedure relative to the beginning of file FDR.  */
1790 	  tab->base_addr = fdr_ptr->adr;
1791 	}
1792       else
1793 	{
1794 	  /* XXX I don't know about stabs, so this is a guess
1795 	     (davidm@cs.arizona.edu).  */
1796 	  tab->base_addr = fdr_ptr->adr;
1797 	}
1798       tab->fdr = fdr_ptr;
1799       ++tab;
1800     }
1801 
1802   /* Finally, the table is sorted in increasing memory-address order.
1803      The table is mostly sorted already, but there are cases (e.g.,
1804      static functions in include files), where this does not hold.
1805      Use "odump -PFv" to verify...  */
1806   qsort (line_info->fdrtab, (size_t) len,
1807 	 sizeof (struct ecoff_fdrtab_entry), cmp_fdrtab_entry);
1808 
1809   return TRUE;
1810 }
1811 
1812 /* Return index of first FDR that covers to OFFSET.  */
1813 
1814 static long
fdrtab_lookup(struct ecoff_find_line * line_info,bfd_vma offset)1815 fdrtab_lookup (struct ecoff_find_line *line_info, bfd_vma offset)
1816 {
1817   long low, high, len;
1818   long mid = -1;
1819   struct ecoff_fdrtab_entry *tab;
1820 
1821   len = line_info->fdrtab_len;
1822   if (len == 0)
1823     return -1;
1824 
1825   tab = line_info->fdrtab;
1826   for (low = 0, high = len - 1 ; low != high ;)
1827     {
1828       mid = (high + low) / 2;
1829       if (offset >= tab[mid].base_addr && offset < tab[mid + 1].base_addr)
1830 	goto find_min;
1831 
1832       if (tab[mid].base_addr > offset)
1833 	high = mid;
1834       else
1835 	low = mid + 1;
1836     }
1837 
1838   /* eraxxon: at this point 'offset' is either lower than the lowest entry or
1839      higher than the highest entry. In the former case high = low = mid = 0;
1840      we want to return -1.  In the latter case, low = high and mid = low - 1;
1841      we want to return the index of the highest entry.  Only in former case
1842      will the following 'catch-all' test be true.  */
1843   ++mid;
1844 
1845   /* Last entry is catch-all for all higher addresses.  */
1846   if (offset < tab[mid].base_addr)
1847     return -1;
1848 
1849  find_min:
1850 
1851   /* eraxxon: There may be multiple FDRs in the table with the
1852      same base_addr; make sure that we are at the first one.  */
1853   while (mid > 0 && tab[mid - 1].base_addr == tab[mid].base_addr)
1854     --mid;
1855 
1856   return mid;
1857 }
1858 
1859 /* Look up a line given an address, storing the information in
1860    LINE_INFO->cache.  */
1861 
1862 static bfd_boolean
lookup_line(bfd * abfd,struct ecoff_debug_info * const debug_info,const struct ecoff_debug_swap * const debug_swap,struct ecoff_find_line * line_info)1863 lookup_line (bfd *abfd,
1864 	     struct ecoff_debug_info * const debug_info,
1865 	     const struct ecoff_debug_swap * const debug_swap,
1866 	     struct ecoff_find_line *line_info)
1867 {
1868   struct ecoff_fdrtab_entry *tab;
1869   bfd_vma offset;
1870   bfd_boolean stabs;
1871   FDR *fdr_ptr;
1872   int i;
1873 
1874   /* eraxxon: note that 'offset' is the full vma, not a section offset.  */
1875   offset = line_info->cache.start;
1876 
1877   /* Build FDR table (sorted by object file's base-address) if we
1878      don't have it already.  */
1879   if (line_info->fdrtab == NULL
1880       && !mk_fdrtab (abfd, debug_info, debug_swap, line_info))
1881     return FALSE;
1882 
1883   tab = line_info->fdrtab;
1884 
1885   /* Find first FDR for address OFFSET.  */
1886   i = fdrtab_lookup (line_info, offset);
1887   if (i < 0)
1888     return FALSE;		/* no FDR, no fun...  */
1889 
1890   /* eraxxon: 'fdrtab_lookup' doesn't give what we want, at least for Compaq's
1891      C++ compiler 6.2.  Consider three FDRs with starting addresses of x, y,
1892      and z, respectively, such that x < y < z.  Assume further that
1893      y < 'offset' < z.  It is possible at times that the PDR for 'offset' is
1894      associated with FDR x and *not* with FDR y.  Erg!!
1895 
1896      From a binary dump of my C++ test case 'moo' using Compaq's coffobjanl
1897      (output format has been edited for our purposes):
1898 
1899      FDR [2]: (main.C): First instruction: 0x12000207c <x>
1900        PDR [5] for File [2]: LoopTest__Xv                 <0x1200020a0> (a)
1901        PDR [7] for File [2]: foo__Xv                      <0x120002168>
1902      FDR [1]: (-1):     First instruction: 0x1200020e8 <y>
1903        PDR [3] for File [1]:                              <0x120001ad0> (b)
1904      FDR [6]: (-1):     First instruction: 0x1200026f0 <z>
1905 
1906      (a) In the case of PDR5, the vma is such that the first few instructions
1907      of the procedure can be found.  But since the size of this procedure is
1908      160b, the vma will soon cross into the 'address space' of FDR1 and no
1909      debugging info will be found.  How repugnant!
1910 
1911      (b) It is also possible for a PDR to have a *lower* vma than its associated
1912      FDR; see FDR1 and PDR3.  Gross!
1913 
1914      Since the FDRs that are causing so much havok (in this case) 1) do not
1915      describe actual files (fdr.rss == -1), and 2) contain only compiler
1916      generated routines, I thought a simple fix would be to exclude them from
1917      the FDR table in 'mk_fdrtab'.  But, besides not knowing for certain
1918      whether this would be correct, it creates an additional problem.  If we
1919      happen to ask for source file info on a compiler generated (procedure)
1920      symbol -- which is still in the symbol table -- the result can be
1921      information from a real procedure!  This is because compiler generated
1922      procedures with vma's higher than the last FDR in the fdr table will be
1923      associated with a PDR from this FDR, specifically the PDR with the
1924      highest vma.  This wasn't a problem before, because each procedure had a
1925      PDR.  (Yes, this problem could be eliminated if we kept the size of the
1926      last PDR around, but things are already getting ugly).
1927 
1928      Probably, a better solution would be to have a sorted PDR table.  Each
1929      PDR would have a pointer to its FDR so file information could still be
1930      obtained.  A FDR table could still be constructed if necessary -- since
1931      it only contains pointers, not much extra memory would be used -- but
1932      the PDR table would be searched to locate debugging info.
1933 
1934      There is still at least one remaining issue.  Sometimes a FDR can have a
1935      bogus name, but contain PDRs that should belong to another FDR with a
1936      real name.  E.g:
1937 
1938      FDR [3]: 0000000120001b50 (/home/.../Array.H~alt~deccxx_5E5A62AD)
1939        PDR [a] for File [3]: 0000000120001b50
1940        PDR [b] for File [3]: 0000000120001cf0
1941        PDR [c] for File [3]: 0000000120001dc8
1942        PDR [d] for File [3]: 0000000120001e40
1943        PDR [e] for File [3]: 0000000120001eb8
1944        PDR [f] for File [3]: 0000000120001f4c
1945      FDR [4]: 0000000120001b50 (/home/.../Array.H)
1946 
1947      Here, FDR4 has the correct name, but should (seemingly) contain PDRa-f.
1948      The symbol table for PDR4 does contain symbols for PDRa-f, but so does
1949      the symbol table for FDR3.  However the former is different; perhaps this
1950      can be detected easily. (I'm not sure at this point.)  This problem only
1951      seems to be associated with files with templates.  I am assuming the idea
1952      is that there is a 'fake' FDR (with PDRs) for each differently typed set
1953      of templates that must be generated.  Currently, FDR4 is completely
1954      excluded from the FDR table in 'mk_fdrtab' because it contains no PDRs.
1955 
1956      Since I don't have time to prepare a real fix for this right now, be
1957      prepared for 'A Horrible Hack' to force the inspection of all non-stabs
1958      FDRs.  It's coming...  */
1959   fdr_ptr = tab[i].fdr;
1960 
1961   /* Check whether this file has stabs debugging information.  In a
1962      file with stabs debugging information, the second local symbol is
1963      named @stabs.  */
1964   stabs = FALSE;
1965   if (fdr_ptr->csym >= 2)
1966     {
1967       char *sym_ptr;
1968       SYMR sym;
1969 
1970       sym_ptr = ((char *) debug_info->external_sym
1971 		 + (fdr_ptr->isymBase + 1) * debug_swap->external_sym_size);
1972       (*debug_swap->swap_sym_in) (abfd, sym_ptr, &sym);
1973       if (strcmp (debug_info->ss + fdr_ptr->issBase + sym.iss,
1974 		  STABS_SYMBOL) == 0)
1975 	stabs = TRUE;
1976     }
1977 
1978   if (!stabs)
1979     {
1980       bfd_size_type external_pdr_size;
1981       char *pdr_ptr;
1982       char *best_pdr = NULL;
1983       FDR *best_fdr;
1984       bfd_signed_vma best_dist = -1;
1985       PDR pdr;
1986       unsigned char *line_ptr;
1987       unsigned char *line_end;
1988       int lineno;
1989       /* This file uses ECOFF debugging information.  Each FDR has a
1990          list of procedure descriptors (PDR).  The address in the FDR
1991          is the absolute address of the first procedure.  The address
1992          in the first PDR gives the offset of that procedure relative
1993          to the object file's base-address.  The addresses in
1994          subsequent PDRs specify each procedure's address relative to
1995          the object file's base-address.  To make things more juicy,
1996          whenever the PROF bit in the PDR is set, the real entry point
1997          of the procedure may be 16 bytes below what would normally be
1998          the procedure's entry point.  Instead, DEC came up with a
1999          wicked scheme to create profiled libraries "on the fly":
2000          instead of shipping a regular and a profiled version of each
2001          library, they insert 16 bytes of unused space in front of
2002          each procedure and set the "prof" bit in the PDR to indicate
2003          that there is a gap there (this is done automagically by "as"
2004          when option "-pg" is specified).  Thus, normally, you link
2005          against such a library and, except for lots of 16 byte gaps
2006          between functions, things will behave as usual.  However,
2007          when invoking "ld" with option "-pg", it will fill those gaps
2008          with code that calls mcount().  It then moves the function's
2009          entry point down by 16 bytes, and out pops a binary that has
2010          all functions profiled.
2011 
2012          NOTE: Neither FDRs nor PDRs are strictly sorted in memory
2013                order.  For example, when including header-files that
2014                define functions, the FDRs follow behind the including
2015                file, even though their code may have been generated at
2016                a lower address.  File coff-alpha.c from libbfd
2017                illustrates this (use "odump -PFv" to look at a file's
2018                FDR/PDR).  Similarly, PDRs are sometimes out of order
2019                as well.  An example of this is OSF/1 v3.0 libc's
2020                malloc.c.  I'm not sure why this happens, but it could
2021                be due to optimizations that reorder a function's
2022                position within an object-file.
2023 
2024          Strategy:
2025 
2026          On the first call to this function, we build a table of FDRs
2027          that is sorted by the base-address of the object-file the FDR
2028          is referring to.  Notice that each object-file may contain
2029          code from multiple source files (e.g., due to code defined in
2030          include files).  Thus, for any given base-address, there may
2031          be multiple FDRs (but this case is, fortunately, uncommon).
2032          lookup(addr) guarantees to return the first FDR that applies
2033          to address ADDR.  Thus, after invoking lookup(), we have a
2034          list of FDRs that may contain the PDR for ADDR.  Next, we
2035          walk through the PDRs of these FDRs and locate the one that
2036          is closest to ADDR (i.e., for which the difference between
2037          ADDR and the PDR's entry point is positive and minimal).
2038          Once, the right FDR and PDR are located, we simply walk
2039          through the line-number table to lookup the line-number that
2040          best matches ADDR.  Obviously, things could be sped up by
2041          keeping a sorted list of PDRs instead of a sorted list of
2042          FDRs.  However, this would increase space requirements
2043          considerably, which is undesirable.  */
2044       external_pdr_size = debug_swap->external_pdr_size;
2045 
2046       /* eraxxon: The Horrible Hack: Because of the problems above, set 'i'
2047 	 to 0 so we look through all FDRs.
2048 
2049 	 Because FDR's without any symbols are assumed to be non-stabs,
2050 	 searching through all FDRs may cause the following code to try to
2051 	 read stabs FDRs as ECOFF ones.  However, I don't think this will
2052 	 harm anything.  */
2053       i = 0;
2054 
2055       /* Search FDR list starting at tab[i] for the PDR that best matches
2056          OFFSET.  Normally, the FDR list is only one entry long.  */
2057       best_fdr = NULL;
2058       do
2059 	{
2060 	  /* eraxxon: 'dist' and 'min_dist' can be negative now
2061              because we iterate over every FDR rather than just ones
2062              with a base address less than or equal to 'offset'.  */
2063 	  bfd_signed_vma dist = -1, min_dist = -1;
2064 	  char *pdr_hold;
2065 	  char *pdr_end;
2066 
2067 	  fdr_ptr = tab[i].fdr;
2068 
2069 	  pdr_ptr = ((char *) debug_info->external_pdr
2070 		     + fdr_ptr->ipdFirst * external_pdr_size);
2071 	  pdr_end = pdr_ptr + fdr_ptr->cpd * external_pdr_size;
2072 	  (*debug_swap->swap_pdr_in) (abfd, pdr_ptr, &pdr);
2073 	  /* Find PDR that is closest to OFFSET.  If pdr.prof is set,
2074 	     the procedure entry-point *may* be 0x10 below pdr.adr.  We
2075 	     simply pretend that pdr.prof *implies* a lower entry-point.
2076 	     This is safe because it just means that may identify 4 NOPs
2077 	     in front of the function as belonging to the function.  */
2078 	  for (pdr_hold = NULL;
2079 	       pdr_ptr < pdr_end;
2080 	       (pdr_ptr += external_pdr_size,
2081 		(*debug_swap->swap_pdr_in) (abfd, pdr_ptr, &pdr)))
2082 	    {
2083 	      if (offset >= (pdr.adr - 0x10 * pdr.prof))
2084 		{
2085 		  dist = offset - (pdr.adr - 0x10 * pdr.prof);
2086 
2087 		  /* eraxxon: 'dist' can be negative now.  Note that
2088                      'min_dist' can be negative if 'pdr_hold' below is NULL.  */
2089 		  if (!pdr_hold || (dist >= 0 && dist < min_dist))
2090 		    {
2091 		      min_dist = dist;
2092 		      pdr_hold = pdr_ptr;
2093 		    }
2094 		}
2095 	    }
2096 
2097 	  if (!best_pdr || (min_dist >= 0 && min_dist < best_dist))
2098 	    {
2099 	      best_dist = (bfd_vma) min_dist;
2100 	      best_fdr = fdr_ptr;
2101 	      best_pdr = pdr_hold;
2102 	    }
2103 	  /* Continue looping until base_addr of next entry is different.  */
2104 	}
2105       /* eraxxon: We want to iterate over all FDRs.
2106 	 See previous comment about 'fdrtab_lookup'.  */
2107       while (++i < line_info->fdrtab_len);
2108 
2109       if (!best_fdr || !best_pdr)
2110 	return FALSE;			/* Shouldn't happen...  */
2111 
2112       /* Phew, finally we got something that we can hold onto.  */
2113       fdr_ptr = best_fdr;
2114       pdr_ptr = best_pdr;
2115       (*debug_swap->swap_pdr_in) (abfd, pdr_ptr, &pdr);
2116       /* Now we can look for the actual line number.  The line numbers
2117          are stored in a very funky format, which I won't try to
2118          describe.  The search is bounded by the end of the FDRs line
2119          number entries.  */
2120       line_end = debug_info->line + fdr_ptr->cbLineOffset + fdr_ptr->cbLine;
2121 
2122       /* Make offset relative to procedure entry.  */
2123       offset -= pdr.adr - 0x10 * pdr.prof;
2124       lineno = pdr.lnLow;
2125       line_ptr = debug_info->line + fdr_ptr->cbLineOffset + pdr.cbLineOffset;
2126       while (line_ptr < line_end)
2127 	{
2128 	  int delta;
2129 	  unsigned int count;
2130 
2131 	  delta = *line_ptr >> 4;
2132 	  if (delta >= 0x8)
2133 	    delta -= 0x10;
2134 	  count = (*line_ptr & 0xf) + 1;
2135 	  ++line_ptr;
2136 	  if (delta == -8)
2137 	    {
2138 	      delta = (((line_ptr[0]) & 0xff) << 8) + ((line_ptr[1]) & 0xff);
2139 	      if (delta >= 0x8000)
2140 		delta -= 0x10000;
2141 	      line_ptr += 2;
2142 	    }
2143 	  lineno += delta;
2144 	  if (offset < count * 4)
2145 	    {
2146 	      line_info->cache.stop += count * 4 - offset;
2147 	      break;
2148 	    }
2149 	  offset -= count * 4;
2150 	}
2151 
2152       /* If fdr_ptr->rss is -1, then this file does not have full
2153          symbols, at least according to gdb/mipsread.c.  */
2154       if (fdr_ptr->rss == -1)
2155 	{
2156 	  line_info->cache.filename = NULL;
2157 	  if (pdr.isym == -1)
2158 	    line_info->cache.functionname = NULL;
2159 	  else
2160 	    {
2161 	      EXTR proc_ext;
2162 
2163 	      (*debug_swap->swap_ext_in)
2164 		(abfd,
2165 		 ((char *) debug_info->external_ext
2166 		  + pdr.isym * debug_swap->external_ext_size),
2167 		 &proc_ext);
2168 	      line_info->cache.functionname = (debug_info->ssext
2169 					       + proc_ext.asym.iss);
2170 	    }
2171 	}
2172       else
2173 	{
2174 	  SYMR proc_sym;
2175 
2176 	  line_info->cache.filename = (debug_info->ss
2177 				       + fdr_ptr->issBase
2178 				       + fdr_ptr->rss);
2179 	  (*debug_swap->swap_sym_in)
2180 	    (abfd,
2181 	     ((char *) debug_info->external_sym
2182 	      + ((fdr_ptr->isymBase + pdr.isym)
2183 		 * debug_swap->external_sym_size)),
2184 	     &proc_sym);
2185 	  line_info->cache.functionname = (debug_info->ss
2186 					   + fdr_ptr->issBase
2187 					   + proc_sym.iss);
2188 	}
2189       if (lineno == ilineNil)
2190 	lineno = 0;
2191       line_info->cache.line_num = lineno;
2192     }
2193   else
2194     {
2195       bfd_size_type external_sym_size;
2196       const char *directory_name;
2197       const char *main_file_name;
2198       const char *current_file_name;
2199       const char *function_name;
2200       const char *line_file_name;
2201       bfd_vma low_func_vma;
2202       bfd_vma low_line_vma;
2203       bfd_boolean past_line;
2204       bfd_boolean past_fn;
2205       char *sym_ptr, *sym_ptr_end;
2206       size_t len, funclen;
2207       char *buffer = NULL;
2208 
2209       /* This file uses stabs debugging information.  When gcc is not
2210 	 optimizing, it will put the line number information before
2211 	 the function name stabs entry.  When gcc is optimizing, it
2212 	 will put the stabs entry for all the function first, followed
2213 	 by the line number information.  (This appears to happen
2214 	 because of the two output files used by the -mgpopt switch,
2215 	 which is implied by -O).  This means that we must keep
2216 	 looking through the symbols until we find both a line number
2217 	 and a function name which are beyond the address we want.  */
2218 
2219       line_info->cache.filename = NULL;
2220       line_info->cache.functionname = NULL;
2221       line_info->cache.line_num = 0;
2222 
2223       directory_name = NULL;
2224       main_file_name = NULL;
2225       current_file_name = NULL;
2226       function_name = NULL;
2227       line_file_name = NULL;
2228       low_func_vma = 0;
2229       low_line_vma = 0;
2230       past_line = FALSE;
2231       past_fn = FALSE;
2232 
2233       external_sym_size = debug_swap->external_sym_size;
2234 
2235       sym_ptr = ((char *) debug_info->external_sym
2236 		 + (fdr_ptr->isymBase + 2) * external_sym_size);
2237       sym_ptr_end = sym_ptr + (fdr_ptr->csym - 2) * external_sym_size;
2238       for (;
2239 	   sym_ptr < sym_ptr_end && (! past_line || ! past_fn);
2240 	   sym_ptr += external_sym_size)
2241 	{
2242 	  SYMR sym;
2243 
2244 	  (*debug_swap->swap_sym_in) (abfd, sym_ptr, &sym);
2245 
2246 	  if (ECOFF_IS_STAB (&sym))
2247 	    {
2248 	      switch (ECOFF_UNMARK_STAB (sym.index))
2249 		{
2250 		case N_SO:
2251 		  main_file_name = current_file_name =
2252 		    debug_info->ss + fdr_ptr->issBase + sym.iss;
2253 
2254 		  /* Check the next symbol to see if it is also an
2255                      N_SO symbol.  */
2256 		  if (sym_ptr + external_sym_size < sym_ptr_end)
2257 		    {
2258 		      SYMR nextsym;
2259 
2260 		      (*debug_swap->swap_sym_in) (abfd,
2261 						  sym_ptr + external_sym_size,
2262 						  &nextsym);
2263 		      if (ECOFF_IS_STAB (&nextsym)
2264 			  && ECOFF_UNMARK_STAB (nextsym.index) == N_SO)
2265 			{
2266  			  directory_name = current_file_name;
2267 			  main_file_name = current_file_name =
2268 			    debug_info->ss + fdr_ptr->issBase + nextsym.iss;
2269 			  sym_ptr += external_sym_size;
2270 			}
2271 		    }
2272 		  break;
2273 
2274 		case N_SOL:
2275 		  current_file_name =
2276 		    debug_info->ss + fdr_ptr->issBase + sym.iss;
2277 		  break;
2278 
2279 		case N_FUN:
2280 		  if (sym.value > offset)
2281 		    past_fn = TRUE;
2282 		  else if (sym.value >= low_func_vma)
2283 		    {
2284 		      low_func_vma = sym.value;
2285 		      function_name =
2286 			debug_info->ss + fdr_ptr->issBase + sym.iss;
2287 		    }
2288 		  break;
2289 		}
2290 	    }
2291 	  else if (sym.st == stLabel && sym.index != indexNil)
2292 	    {
2293 	      if (sym.value > offset)
2294 		past_line = TRUE;
2295 	      else if (sym.value >= low_line_vma)
2296 		{
2297 		  low_line_vma = sym.value;
2298 		  line_file_name = current_file_name;
2299 		  line_info->cache.line_num = sym.index;
2300 		}
2301 	    }
2302 	}
2303 
2304       if (line_info->cache.line_num != 0)
2305 	main_file_name = line_file_name;
2306 
2307       /* We need to remove the stuff after the colon in the function
2308          name.  We also need to put the directory name and the file
2309          name together.  */
2310       if (function_name == NULL)
2311 	len = funclen = 0;
2312       else
2313 	len = funclen = strlen (function_name) + 1;
2314 
2315       if (main_file_name != NULL
2316 	  && directory_name != NULL
2317 	  && main_file_name[0] != '/')
2318 	len += strlen (directory_name) + strlen (main_file_name) + 1;
2319 
2320       if (len != 0)
2321 	{
2322 	  if (line_info->find_buffer != NULL)
2323 	    free (line_info->find_buffer);
2324 	  buffer = (char *) bfd_malloc ((bfd_size_type) len);
2325 	  if (buffer == NULL)
2326 	    return FALSE;
2327 	  line_info->find_buffer = buffer;
2328 	}
2329 
2330       if (function_name != NULL)
2331 	{
2332 	  char *colon;
2333 
2334 	  strcpy (buffer, function_name);
2335 	  colon = strchr (buffer, ':');
2336 	  if (colon != NULL)
2337 	    *colon = '\0';
2338 	  line_info->cache.functionname = buffer;
2339 	}
2340 
2341       if (main_file_name != NULL)
2342 	{
2343 	  if (directory_name == NULL || main_file_name[0] == '/')
2344 	    line_info->cache.filename = main_file_name;
2345 	  else
2346 	    {
2347 	      sprintf (buffer + funclen, "%s%s", directory_name,
2348 		       main_file_name);
2349 	      line_info->cache.filename = buffer + funclen;
2350 	    }
2351 	}
2352     }
2353 
2354   return TRUE;
2355 }
2356 
2357 /* Do the work of find_nearest_line.  */
2358 
2359 bfd_boolean
_bfd_ecoff_locate_line(bfd * abfd,asection * section,bfd_vma offset,struct ecoff_debug_info * const debug_info,const struct ecoff_debug_swap * const debug_swap,struct ecoff_find_line * line_info,const char ** filename_ptr,const char ** functionname_ptr,unsigned int * retline_ptr)2360 _bfd_ecoff_locate_line (bfd *abfd,
2361 			asection *section,
2362 			bfd_vma offset,
2363 			struct ecoff_debug_info * const debug_info,
2364 			const struct ecoff_debug_swap * const debug_swap,
2365 			struct ecoff_find_line *line_info,
2366 			const char **filename_ptr,
2367 			const char **functionname_ptr,
2368 			unsigned int *retline_ptr)
2369 {
2370   offset += section->vma;
2371 
2372   if (line_info->cache.sect == NULL
2373       || line_info->cache.sect != section
2374       || offset < line_info->cache.start
2375       || offset >= line_info->cache.stop)
2376     {
2377       line_info->cache.sect = section;
2378       line_info->cache.start = offset;
2379       line_info->cache.stop = offset;
2380       if (! lookup_line (abfd, debug_info, debug_swap, line_info))
2381 	{
2382 	  line_info->cache.sect = NULL;
2383 	  return FALSE;
2384 	}
2385     }
2386 
2387   *filename_ptr = line_info->cache.filename;
2388   *functionname_ptr = line_info->cache.functionname;
2389   *retline_ptr = line_info->cache.line_num;
2390 
2391   return TRUE;
2392 }
2393 
2394 /* These routines copy symbolic information into a memory buffer.
2395 
2396    FIXME: The whole point of the shuffle code is to avoid storing
2397    everything in memory, since the linker is such a memory hog.  This
2398    code makes that effort useless.  It is only called by the MIPS ELF
2399    code when generating a shared library, so it is not that big a
2400    deal, but it should be fixed eventually.  */
2401 
2402 /* Collect a shuffle into a memory buffer.  */
2403 
2404 static bfd_boolean
ecoff_collect_shuffle(struct shuffle * l,bfd_byte * buff)2405 ecoff_collect_shuffle (struct shuffle *l, bfd_byte *buff)
2406 {
2407   unsigned long total;
2408 
2409   total = 0;
2410   for (; l != (struct shuffle *) NULL; l = l->next)
2411     {
2412       if (! l->filep)
2413 	memcpy (buff, l->u.memory, l->size);
2414       else
2415 	{
2416 	  if (bfd_seek (l->u.file.input_bfd, l->u.file.offset, SEEK_SET) != 0
2417 	      || (bfd_bread (buff, (bfd_size_type) l->size, l->u.file.input_bfd)
2418 		  != l->size))
2419 	    return FALSE;
2420 	}
2421       total += l->size;
2422       buff += l->size;
2423     }
2424 
2425   return TRUE;
2426 }
2427 
2428 /* Copy PDR information into a memory buffer.  */
2429 
2430 bfd_boolean
_bfd_ecoff_get_accumulated_pdr(void * handle,bfd_byte * buff)2431 _bfd_ecoff_get_accumulated_pdr (void * handle,
2432 				bfd_byte *buff)
2433 {
2434   struct accumulate *ainfo = (struct accumulate *) handle;
2435 
2436   return ecoff_collect_shuffle (ainfo->pdr, buff);
2437 }
2438 
2439 /* Copy symbol information into a memory buffer.  */
2440 
2441 bfd_boolean
_bfd_ecoff_get_accumulated_sym(void * handle,bfd_byte * buff)2442 _bfd_ecoff_get_accumulated_sym (void * handle, bfd_byte *buff)
2443 {
2444   struct accumulate *ainfo = (struct accumulate *) handle;
2445 
2446   return ecoff_collect_shuffle (ainfo->sym, buff);
2447 }
2448 
2449 /* Copy the string table into a memory buffer.  */
2450 
2451 bfd_boolean
_bfd_ecoff_get_accumulated_ss(void * handle,bfd_byte * buff)2452 _bfd_ecoff_get_accumulated_ss (void * handle, bfd_byte *buff)
2453 {
2454   struct accumulate *ainfo = (struct accumulate *) handle;
2455   struct string_hash_entry *sh;
2456   unsigned long total;
2457 
2458   /* The string table is written out from the hash table if this is a
2459      final link.  */
2460   BFD_ASSERT (ainfo->ss == (struct shuffle *) NULL);
2461   *buff++ = '\0';
2462   total = 1;
2463   BFD_ASSERT (ainfo->ss_hash == NULL || ainfo->ss_hash->val == 1);
2464   for (sh = ainfo->ss_hash;
2465        sh != (struct string_hash_entry *) NULL;
2466        sh = sh->next)
2467     {
2468       size_t len;
2469 
2470       len = strlen (sh->root.string);
2471       memcpy (buff, sh->root.string, len + 1);
2472       total += len + 1;
2473       buff += len + 1;
2474     }
2475 
2476   return TRUE;
2477 }
2478