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