Back to index

cell-binutils  2.17cvs20070401
ecofflink.c
Go to the documentation of this file.
00001 /* Routines to link ECOFF debugging information.
00002    Copyright 1993, 1994, 1995, 1996, 1997, 1999, 2000, 2001, 2002, 2003,
00003    2004, 2005, 2006 Free Software Foundation, Inc.
00004    Written by Ian Lance Taylor, Cygnus Support, <ian@cygnus.com>.
00005 
00006    This file is part of BFD, the Binary File Descriptor library.
00007 
00008    This program is free software; you can redistribute it and/or modify
00009    it under the terms of the GNU General Public License as published by
00010    the Free Software Foundation; either version 2 of the License, or
00011    (at your option) any later version.
00012 
00013    This program is distributed in the hope that it will be useful,
00014    but WITHOUT ANY WARRANTY; without even the implied warranty of
00015    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00016    GNU General Public License for more details.
00017 
00018    You should have received a copy of the GNU General Public License
00019    along with this program; if not, write to the Free Software
00020    Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA.  */
00021 
00022 #include "bfd.h"
00023 #include "sysdep.h"
00024 #include "bfdlink.h"
00025 #include "libbfd.h"
00026 #include "objalloc.h"
00027 #include "aout/stab_gnu.h"
00028 #include "coff/internal.h"
00029 #include "coff/sym.h"
00030 #include "coff/symconst.h"
00031 #include "coff/ecoff.h"
00032 #include "libcoff.h"
00033 #include "libecoff.h"
00034 
00035 static bfd_boolean ecoff_add_bytes
00036   PARAMS ((char **buf, char **bufend, size_t need));
00037 static struct bfd_hash_entry *string_hash_newfunc
00038   PARAMS ((struct bfd_hash_entry *, struct bfd_hash_table *,
00039           const char *));
00040 static void ecoff_align_debug
00041   PARAMS ((bfd *abfd, struct ecoff_debug_info *debug,
00042           const struct ecoff_debug_swap *swap));
00043 static bfd_boolean ecoff_write_symhdr
00044   PARAMS ((bfd *, struct ecoff_debug_info *, const struct ecoff_debug_swap *,
00045           file_ptr where));
00046 static int cmp_fdrtab_entry
00047   PARAMS ((const PTR, const PTR));
00048 static bfd_boolean mk_fdrtab
00049   PARAMS ((bfd *, struct ecoff_debug_info * const,
00050           const struct ecoff_debug_swap * const, struct ecoff_find_line *));
00051 static long fdrtab_lookup
00052   PARAMS ((struct ecoff_find_line *, bfd_vma));
00053 static bfd_boolean lookup_line
00054   PARAMS ((bfd *, struct ecoff_debug_info * const,
00055           const struct ecoff_debug_swap * const, struct ecoff_find_line *));
00056 
00057 /* Routines to swap auxiliary information in and out.  I am assuming
00058    that the auxiliary information format is always going to be target
00059    independent.  */
00060 
00061 /* Swap in a type information record.
00062    BIGEND says whether AUX symbols are big-endian or little-endian; this
00063    info comes from the file header record (fh-fBigendian).  */
00064 
00065 void
00066 _bfd_ecoff_swap_tir_in (bigend, ext_copy, intern)
00067      int bigend;
00068      const struct tir_ext *ext_copy;
00069      TIR *intern;
00070 {
00071   struct tir_ext ext[1];
00072 
00073   *ext = *ext_copy;         /* Make it reasonable to do in-place.  */
00074 
00075   /* now the fun stuff...  */
00076   if (bigend) {
00077     intern->fBitfield   = 0 != (ext->t_bits1[0] & TIR_BITS1_FBITFIELD_BIG);
00078     intern->continued   = 0 != (ext->t_bits1[0] & TIR_BITS1_CONTINUED_BIG);
00079     intern->bt          = (ext->t_bits1[0] & TIR_BITS1_BT_BIG)
00080                      >>                TIR_BITS1_BT_SH_BIG;
00081     intern->tq4         = (ext->t_tq45[0] & TIR_BITS_TQ4_BIG)
00082                      >>                TIR_BITS_TQ4_SH_BIG;
00083     intern->tq5         = (ext->t_tq45[0] & TIR_BITS_TQ5_BIG)
00084                      >>                TIR_BITS_TQ5_SH_BIG;
00085     intern->tq0         = (ext->t_tq01[0] & TIR_BITS_TQ0_BIG)
00086                      >>                TIR_BITS_TQ0_SH_BIG;
00087     intern->tq1         = (ext->t_tq01[0] & TIR_BITS_TQ1_BIG)
00088                      >>                TIR_BITS_TQ1_SH_BIG;
00089     intern->tq2         = (ext->t_tq23[0] & TIR_BITS_TQ2_BIG)
00090                      >>                TIR_BITS_TQ2_SH_BIG;
00091     intern->tq3         = (ext->t_tq23[0] & TIR_BITS_TQ3_BIG)
00092                      >>                TIR_BITS_TQ3_SH_BIG;
00093   } else {
00094     intern->fBitfield   = 0 != (ext->t_bits1[0] & TIR_BITS1_FBITFIELD_LITTLE);
00095     intern->continued   = 0 != (ext->t_bits1[0] & TIR_BITS1_CONTINUED_LITTLE);
00096     intern->bt          = (ext->t_bits1[0] & TIR_BITS1_BT_LITTLE)
00097                      >>                TIR_BITS1_BT_SH_LITTLE;
00098     intern->tq4         = (ext->t_tq45[0] & TIR_BITS_TQ4_LITTLE)
00099                      >>                TIR_BITS_TQ4_SH_LITTLE;
00100     intern->tq5         = (ext->t_tq45[0] & TIR_BITS_TQ5_LITTLE)
00101                      >>                TIR_BITS_TQ5_SH_LITTLE;
00102     intern->tq0         = (ext->t_tq01[0] & TIR_BITS_TQ0_LITTLE)
00103                      >>                TIR_BITS_TQ0_SH_LITTLE;
00104     intern->tq1         = (ext->t_tq01[0] & TIR_BITS_TQ1_LITTLE)
00105                      >>                TIR_BITS_TQ1_SH_LITTLE;
00106     intern->tq2         = (ext->t_tq23[0] & TIR_BITS_TQ2_LITTLE)
00107                      >>                TIR_BITS_TQ2_SH_LITTLE;
00108     intern->tq3         = (ext->t_tq23[0] & TIR_BITS_TQ3_LITTLE)
00109                      >>                TIR_BITS_TQ3_SH_LITTLE;
00110   }
00111 
00112 #ifdef TEST
00113   if (memcmp ((char *)ext, (char *)intern, sizeof (*intern)) != 0)
00114     abort ();
00115 #endif
00116 }
00117 
00118 /* Swap out a type information record.
00119    BIGEND says whether AUX symbols are big-endian or little-endian; this
00120    info comes from the file header record (fh-fBigendian).  */
00121 
00122 void
00123 _bfd_ecoff_swap_tir_out (bigend, intern_copy, ext)
00124      int bigend;
00125      const TIR *intern_copy;
00126      struct tir_ext *ext;
00127 {
00128   TIR intern[1];
00129 
00130   *intern = *intern_copy;   /* Make it reasonable to do in-place.  */
00131 
00132   /* now the fun stuff...  */
00133   if (bigend) {
00134     ext->t_bits1[0] = ((intern->fBitfield ? TIR_BITS1_FBITFIELD_BIG : 0)
00135                      | (intern->continued ? TIR_BITS1_CONTINUED_BIG : 0)
00136                      | ((intern->bt << TIR_BITS1_BT_SH_BIG)
00137                        & TIR_BITS1_BT_BIG));
00138     ext->t_tq45[0] = (((intern->tq4 << TIR_BITS_TQ4_SH_BIG)
00139                      & TIR_BITS_TQ4_BIG)
00140                     | ((intern->tq5 << TIR_BITS_TQ5_SH_BIG)
00141                       & TIR_BITS_TQ5_BIG));
00142     ext->t_tq01[0] = (((intern->tq0 << TIR_BITS_TQ0_SH_BIG)
00143                      & TIR_BITS_TQ0_BIG)
00144                     | ((intern->tq1 << TIR_BITS_TQ1_SH_BIG)
00145                       & TIR_BITS_TQ1_BIG));
00146     ext->t_tq23[0] = (((intern->tq2 << TIR_BITS_TQ2_SH_BIG)
00147                      & TIR_BITS_TQ2_BIG)
00148                     | ((intern->tq3 << TIR_BITS_TQ3_SH_BIG)
00149                       & TIR_BITS_TQ3_BIG));
00150   } else {
00151     ext->t_bits1[0] = ((intern->fBitfield ? TIR_BITS1_FBITFIELD_LITTLE : 0)
00152                      | (intern->continued ? TIR_BITS1_CONTINUED_LITTLE : 0)
00153                      | ((intern->bt << TIR_BITS1_BT_SH_LITTLE)
00154                        & TIR_BITS1_BT_LITTLE));
00155     ext->t_tq45[0] = (((intern->tq4 << TIR_BITS_TQ4_SH_LITTLE)
00156                      & TIR_BITS_TQ4_LITTLE)
00157                     | ((intern->tq5 << TIR_BITS_TQ5_SH_LITTLE)
00158                       & TIR_BITS_TQ5_LITTLE));
00159     ext->t_tq01[0] = (((intern->tq0 << TIR_BITS_TQ0_SH_LITTLE)
00160                      & TIR_BITS_TQ0_LITTLE)
00161                     | ((intern->tq1 << TIR_BITS_TQ1_SH_LITTLE)
00162                       & TIR_BITS_TQ1_LITTLE));
00163     ext->t_tq23[0] = (((intern->tq2 << TIR_BITS_TQ2_SH_LITTLE)
00164                      & TIR_BITS_TQ2_LITTLE)
00165                     | ((intern->tq3 << TIR_BITS_TQ3_SH_LITTLE)
00166                       & TIR_BITS_TQ3_LITTLE));
00167   }
00168 
00169 #ifdef TEST
00170   if (memcmp ((char *)ext, (char *)intern, sizeof (*intern)) != 0)
00171     abort ();
00172 #endif
00173 }
00174 
00175 /* Swap in a relative symbol record.  BIGEND says whether it is in
00176    big-endian or little-endian format.*/
00177 
00178 void
00179 _bfd_ecoff_swap_rndx_in (bigend, ext_copy, intern)
00180      int bigend;
00181      const struct rndx_ext *ext_copy;
00182      RNDXR *intern;
00183 {
00184   struct rndx_ext ext[1];
00185 
00186   *ext = *ext_copy;         /* Make it reasonable to do in-place.  */
00187 
00188   /* now the fun stuff...  */
00189   if (bigend) {
00190     intern->rfd   = (ext->r_bits[0] << RNDX_BITS0_RFD_SH_LEFT_BIG)
00191                 | ((ext->r_bits[1] & RNDX_BITS1_RFD_BIG)
00192                                 >> RNDX_BITS1_RFD_SH_BIG);
00193     intern->index = ((ext->r_bits[1] & RNDX_BITS1_INDEX_BIG)
00194                                 << RNDX_BITS1_INDEX_SH_LEFT_BIG)
00195                 | (ext->r_bits[2] << RNDX_BITS2_INDEX_SH_LEFT_BIG)
00196                 | (ext->r_bits[3] << RNDX_BITS3_INDEX_SH_LEFT_BIG);
00197   } else {
00198     intern->rfd   = (ext->r_bits[0] << RNDX_BITS0_RFD_SH_LEFT_LITTLE)
00199                 | ((ext->r_bits[1] & RNDX_BITS1_RFD_LITTLE)
00200                                 << RNDX_BITS1_RFD_SH_LEFT_LITTLE);
00201     intern->index = ((ext->r_bits[1] & RNDX_BITS1_INDEX_LITTLE)
00202                                 >> RNDX_BITS1_INDEX_SH_LITTLE)
00203                 | (ext->r_bits[2] << RNDX_BITS2_INDEX_SH_LEFT_LITTLE)
00204                 | ((unsigned int) ext->r_bits[3]
00205                    << RNDX_BITS3_INDEX_SH_LEFT_LITTLE);
00206   }
00207 
00208 #ifdef TEST
00209   if (memcmp ((char *)ext, (char *)intern, sizeof (*intern)) != 0)
00210     abort ();
00211 #endif
00212 }
00213 
00214 /* Swap out a relative symbol record.  BIGEND says whether it is in
00215    big-endian or little-endian format.*/
00216 
00217 void
00218 _bfd_ecoff_swap_rndx_out (bigend, intern_copy, ext)
00219      int bigend;
00220      const RNDXR *intern_copy;
00221      struct rndx_ext *ext;
00222 {
00223   RNDXR intern[1];
00224 
00225   *intern = *intern_copy;   /* Make it reasonable to do in-place.  */
00226 
00227   /* now the fun stuff...  */
00228   if (bigend) {
00229     ext->r_bits[0] = intern->rfd >> RNDX_BITS0_RFD_SH_LEFT_BIG;
00230     ext->r_bits[1] = (((intern->rfd << RNDX_BITS1_RFD_SH_BIG)
00231                      & RNDX_BITS1_RFD_BIG)
00232                     | ((intern->index >> RNDX_BITS1_INDEX_SH_LEFT_BIG)
00233                       & RNDX_BITS1_INDEX_BIG));
00234     ext->r_bits[2] = intern->index >> RNDX_BITS2_INDEX_SH_LEFT_BIG;
00235     ext->r_bits[3] = intern->index >> RNDX_BITS3_INDEX_SH_LEFT_BIG;
00236   } else {
00237     ext->r_bits[0] = intern->rfd >> RNDX_BITS0_RFD_SH_LEFT_LITTLE;
00238     ext->r_bits[1] = (((intern->rfd >> RNDX_BITS1_RFD_SH_LEFT_LITTLE)
00239                      & RNDX_BITS1_RFD_LITTLE)
00240                     | ((intern->index << RNDX_BITS1_INDEX_SH_LITTLE)
00241                       & RNDX_BITS1_INDEX_LITTLE));
00242     ext->r_bits[2] = intern->index >> RNDX_BITS2_INDEX_SH_LEFT_LITTLE;
00243     ext->r_bits[3] = intern->index >> RNDX_BITS3_INDEX_SH_LEFT_LITTLE;
00244   }
00245 
00246 #ifdef TEST
00247   if (memcmp ((char *)ext, (char *)intern, sizeof (*intern)) != 0)
00248     abort ();
00249 #endif
00250 }
00251 
00252 /* The minimum amount of data to allocate.  */
00253 #define ALLOC_SIZE (4064)
00254 
00255 /* Add bytes to a buffer.  Return success.  */
00256 
00257 static bfd_boolean
00258 ecoff_add_bytes (buf, bufend, need)
00259      char **buf;
00260      char **bufend;
00261      size_t need;
00262 {
00263   size_t have;
00264   size_t want;
00265   char *newbuf;
00266 
00267   have = *bufend - *buf;
00268   if (have > need)
00269     want = ALLOC_SIZE;
00270   else
00271     {
00272       want = need - have;
00273       if (want < ALLOC_SIZE)
00274        want = ALLOC_SIZE;
00275     }
00276   newbuf = (char *) bfd_realloc (*buf, (bfd_size_type) have + want);
00277   if (newbuf == NULL)
00278     return FALSE;
00279   *buf = newbuf;
00280   *bufend = *buf + have + want;
00281   return TRUE;
00282 }
00283 
00284 /* We keep a hash table which maps strings to numbers.  We use it to
00285    map FDR names to indices in the output file, and to map local
00286    strings when combining stabs debugging information.  */
00287 
00288 struct string_hash_entry
00289 {
00290   struct bfd_hash_entry root;
00291   /* FDR index or string table offset.  */
00292   long val;
00293   /* Next entry in string table.  */
00294   struct string_hash_entry *next;
00295 };
00296 
00297 struct string_hash_table
00298 {
00299   struct bfd_hash_table table;
00300 };
00301 
00302 /* Routine to create an entry in a string hash table.  */
00303 
00304 static struct bfd_hash_entry *
00305 string_hash_newfunc (entry, table, string)
00306      struct bfd_hash_entry *entry;
00307      struct bfd_hash_table *table;
00308      const char *string;
00309 {
00310   struct string_hash_entry *ret = (struct string_hash_entry *) entry;
00311 
00312   /* Allocate the structure if it has not already been allocated by a
00313      subclass.  */
00314   if (ret == (struct string_hash_entry *) NULL)
00315     ret = ((struct string_hash_entry *)
00316           bfd_hash_allocate (table, sizeof (struct string_hash_entry)));
00317   if (ret == (struct string_hash_entry *) NULL)
00318     return NULL;
00319 
00320   /* Call the allocation method of the superclass.  */
00321   ret = ((struct string_hash_entry *)
00322         bfd_hash_newfunc ((struct bfd_hash_entry *) ret, table, string));
00323 
00324   if (ret)
00325     {
00326       /* Initialize the local fields.  */
00327       ret->val = -1;
00328       ret->next = NULL;
00329     }
00330 
00331   return (struct bfd_hash_entry *) ret;
00332 }
00333 
00334 /* Look up an entry in an string hash table.  */
00335 
00336 #define string_hash_lookup(t, string, create, copy) \
00337   ((struct string_hash_entry *) \
00338    bfd_hash_lookup (&(t)->table, (string), (create), (copy)))
00339 
00340 /* We can't afford to read in all the debugging information when we do
00341    a link.  Instead, we build a list of these structures to show how
00342    different parts of the input file map to the output file.  */
00343 
00344 struct shuffle
00345 {
00346   /* The next entry in this linked list.  */
00347   struct shuffle *next;
00348   /* The length of the information.  */
00349   unsigned long size;
00350   /* Whether this information comes from a file or not.  */
00351   bfd_boolean filep;
00352   union
00353     {
00354       struct
00355        {
00356          /* The BFD the data comes from.  */
00357          bfd *input_bfd;
00358          /* The offset within input_bfd.  */
00359          file_ptr offset;
00360        } file;
00361       /* The data to be written out.  */
00362       PTR memory;
00363     } u;
00364 };
00365 
00366 /* This structure holds information across calls to
00367    bfd_ecoff_debug_accumulate.  */
00368 
00369 struct accumulate
00370 {
00371   /* The FDR hash table.  */
00372   struct string_hash_table fdr_hash;
00373   /* The strings hash table.  */
00374   struct string_hash_table str_hash;
00375   /* Linked lists describing how to shuffle the input debug
00376      information into the output file.  We keep a pointer to both the
00377      head and the tail.  */
00378   struct shuffle *line;
00379   struct shuffle *line_end;
00380   struct shuffle *pdr;
00381   struct shuffle *pdr_end;
00382   struct shuffle *sym;
00383   struct shuffle *sym_end;
00384   struct shuffle *opt;
00385   struct shuffle *opt_end;
00386   struct shuffle *aux;
00387   struct shuffle *aux_end;
00388   struct shuffle *ss;
00389   struct shuffle *ss_end;
00390   struct string_hash_entry *ss_hash;
00391   struct string_hash_entry *ss_hash_end;
00392   struct shuffle *fdr;
00393   struct shuffle *fdr_end;
00394   struct shuffle *rfd;
00395   struct shuffle *rfd_end;
00396   /* The size of the largest file shuffle.  */
00397   unsigned long largest_file_shuffle;
00398   /* An objalloc for debugging information.  */
00399   struct objalloc *memory;
00400 };
00401 
00402 /* Add a file entry to a shuffle list.  */
00403 
00404 static bfd_boolean add_file_shuffle
00405   PARAMS ((struct accumulate *, struct shuffle **, struct shuffle **,
00406           bfd *, file_ptr, unsigned long));
00407 
00408 static bfd_boolean
00409 add_file_shuffle (ainfo, head, tail, input_bfd, offset, size)
00410      struct accumulate *ainfo;
00411      struct shuffle **head;
00412      struct shuffle **tail;
00413      bfd *input_bfd;
00414      file_ptr offset;
00415      unsigned long size;
00416 {
00417   struct shuffle *n;
00418 
00419   if (*tail != (struct shuffle *) NULL
00420       && (*tail)->filep
00421       && (*tail)->u.file.input_bfd == input_bfd
00422       && (*tail)->u.file.offset + (*tail)->size == (unsigned long) offset)
00423     {
00424       /* Just merge this entry onto the existing one.  */
00425       (*tail)->size += size;
00426       if ((*tail)->size > ainfo->largest_file_shuffle)
00427        ainfo->largest_file_shuffle = (*tail)->size;
00428       return TRUE;
00429     }
00430 
00431   n = (struct shuffle *) objalloc_alloc (ainfo->memory,
00432                                     sizeof (struct shuffle));
00433   if (!n)
00434     {
00435       bfd_set_error (bfd_error_no_memory);
00436       return FALSE;
00437     }
00438   n->next = NULL;
00439   n->size = size;
00440   n->filep = TRUE;
00441   n->u.file.input_bfd = input_bfd;
00442   n->u.file.offset = offset;
00443   if (*head == (struct shuffle *) NULL)
00444     *head = n;
00445   if (*tail != (struct shuffle *) NULL)
00446     (*tail)->next = n;
00447   *tail = n;
00448   if (size > ainfo->largest_file_shuffle)
00449     ainfo->largest_file_shuffle = size;
00450   return TRUE;
00451 }
00452 
00453 /* Add a memory entry to a shuffle list.  */
00454 
00455 static bfd_boolean add_memory_shuffle
00456   PARAMS ((struct accumulate *, struct shuffle **head, struct shuffle **tail,
00457           bfd_byte *data, unsigned long size));
00458 
00459 static bfd_boolean
00460 add_memory_shuffle (ainfo, head, tail, data, size)
00461      struct accumulate *ainfo;
00462      struct shuffle **head;
00463      struct shuffle **tail;
00464      bfd_byte *data;
00465      unsigned long size;
00466 {
00467   struct shuffle *n;
00468 
00469   n = (struct shuffle *) objalloc_alloc (ainfo->memory,
00470                                     sizeof (struct shuffle));
00471   if (!n)
00472     {
00473       bfd_set_error (bfd_error_no_memory);
00474       return FALSE;
00475     }
00476   n->next = NULL;
00477   n->size = size;
00478   n->filep = FALSE;
00479   n->u.memory = (PTR) data;
00480   if (*head == (struct shuffle *) NULL)
00481     *head = n;
00482   if (*tail != (struct shuffle *) NULL)
00483     (*tail)->next = n;
00484   *tail = n;
00485   return TRUE;
00486 }
00487 
00488 /* Initialize the FDR hash table.  This returns a handle which is then
00489    passed in to bfd_ecoff_debug_accumulate, et. al.  */
00490 
00491 PTR
00492 bfd_ecoff_debug_init (output_bfd, output_debug, output_swap, info)
00493      bfd *output_bfd ATTRIBUTE_UNUSED;
00494      struct ecoff_debug_info *output_debug;
00495      const struct ecoff_debug_swap *output_swap ATTRIBUTE_UNUSED;
00496      struct bfd_link_info *info;
00497 {
00498   struct accumulate *ainfo;
00499   bfd_size_type amt = sizeof (struct accumulate);
00500 
00501   ainfo = (struct accumulate *) bfd_malloc (amt);
00502   if (!ainfo)
00503     return NULL;
00504   if (!bfd_hash_table_init_n (&ainfo->fdr_hash.table, string_hash_newfunc,
00505                            sizeof (struct string_hash_entry), 1021))
00506     return NULL;
00507 
00508   ainfo->line = NULL;
00509   ainfo->line_end = NULL;
00510   ainfo->pdr = NULL;
00511   ainfo->pdr_end = NULL;
00512   ainfo->sym = NULL;
00513   ainfo->sym_end = NULL;
00514   ainfo->opt = NULL;
00515   ainfo->opt_end = NULL;
00516   ainfo->aux = NULL;
00517   ainfo->aux_end = NULL;
00518   ainfo->ss = NULL;
00519   ainfo->ss_end = NULL;
00520   ainfo->ss_hash = NULL;
00521   ainfo->ss_hash_end = NULL;
00522   ainfo->fdr = NULL;
00523   ainfo->fdr_end = NULL;
00524   ainfo->rfd = NULL;
00525   ainfo->rfd_end = NULL;
00526 
00527   ainfo->largest_file_shuffle = 0;
00528 
00529   if (! info->relocatable)
00530     {
00531       if (!bfd_hash_table_init (&ainfo->str_hash.table, string_hash_newfunc,
00532                             sizeof (struct string_hash_entry)))
00533        return NULL;
00534 
00535       /* The first entry in the string table is the empty string.  */
00536       output_debug->symbolic_header.issMax = 1;
00537     }
00538 
00539   ainfo->memory = objalloc_create ();
00540   if (ainfo->memory == NULL)
00541     {
00542       bfd_set_error (bfd_error_no_memory);
00543       return NULL;
00544     }
00545 
00546   return (PTR) ainfo;
00547 }
00548 
00549 /* Free the accumulated debugging information.  */
00550 
00551 void
00552 bfd_ecoff_debug_free (handle, output_bfd, output_debug, output_swap, info)
00553      PTR handle;
00554      bfd *output_bfd ATTRIBUTE_UNUSED;
00555      struct ecoff_debug_info *output_debug ATTRIBUTE_UNUSED;
00556      const struct ecoff_debug_swap *output_swap ATTRIBUTE_UNUSED;
00557      struct bfd_link_info *info;
00558 {
00559   struct accumulate *ainfo = (struct accumulate *) handle;
00560 
00561   bfd_hash_table_free (&ainfo->fdr_hash.table);
00562 
00563   if (! info->relocatable)
00564     bfd_hash_table_free (&ainfo->str_hash.table);
00565 
00566   objalloc_free (ainfo->memory);
00567 
00568   free (ainfo);
00569 }
00570 
00571 /* Accumulate the debugging information from INPUT_BFD into
00572    OUTPUT_BFD.  The INPUT_DEBUG argument points to some ECOFF
00573    debugging information which we want to link into the information
00574    pointed to by the OUTPUT_DEBUG argument.  OUTPUT_SWAP and
00575    INPUT_SWAP point to the swapping information needed.  INFO is the
00576    linker information structure.  HANDLE is returned by
00577    bfd_ecoff_debug_init.  */
00578 
00579 bfd_boolean
00580 bfd_ecoff_debug_accumulate (handle, output_bfd, output_debug, output_swap,
00581                          input_bfd, input_debug, input_swap,
00582                          info)
00583      PTR handle;
00584      bfd *output_bfd;
00585      struct ecoff_debug_info *output_debug;
00586      const struct ecoff_debug_swap *output_swap;
00587      bfd *input_bfd;
00588      struct ecoff_debug_info *input_debug;
00589      const struct ecoff_debug_swap *input_swap;
00590      struct bfd_link_info *info;
00591 {
00592   struct accumulate *ainfo = (struct accumulate *) handle;
00593   void (* const swap_sym_in) PARAMS ((bfd *, PTR, SYMR *))
00594     = input_swap->swap_sym_in;
00595   void (* const swap_rfd_in) PARAMS ((bfd *, PTR, RFDT *))
00596     = input_swap->swap_rfd_in;
00597   void (* const swap_sym_out) PARAMS ((bfd *, const SYMR *, PTR))
00598     = output_swap->swap_sym_out;
00599   void (* const swap_fdr_out) PARAMS ((bfd *, const FDR *, PTR))
00600     = output_swap->swap_fdr_out;
00601   void (* const swap_rfd_out) PARAMS ((bfd *, const RFDT *, PTR))
00602     = output_swap->swap_rfd_out;
00603   bfd_size_type external_pdr_size = output_swap->external_pdr_size;
00604   bfd_size_type external_sym_size = output_swap->external_sym_size;
00605   bfd_size_type external_opt_size = output_swap->external_opt_size;
00606   bfd_size_type external_fdr_size = output_swap->external_fdr_size;
00607   bfd_size_type external_rfd_size = output_swap->external_rfd_size;
00608   HDRR * const output_symhdr = &output_debug->symbolic_header;
00609   HDRR * const input_symhdr = &input_debug->symbolic_header;
00610   bfd_vma section_adjust[scMax];
00611   asection *sec;
00612   bfd_byte *fdr_start;
00613   bfd_byte *fdr_ptr;
00614   bfd_byte *fdr_end;
00615   bfd_size_type fdr_add;
00616   unsigned int copied;
00617   RFDT i;
00618   unsigned long sz;
00619   bfd_byte *rfd_out;
00620   bfd_byte *rfd_in;
00621   bfd_byte *rfd_end;
00622   long newrfdbase = 0;
00623   long oldrfdbase = 0;
00624   bfd_byte *fdr_out;
00625   bfd_size_type amt;
00626 
00627   /* Use section_adjust to hold the value to add to a symbol in a
00628      particular section.  */
00629   memset ((PTR) section_adjust, 0, sizeof section_adjust);
00630 
00631 #define SET(name, indx) \
00632   sec = bfd_get_section_by_name (input_bfd, name); \
00633   if (sec != NULL) \
00634     section_adjust[indx] = (sec->output_section->vma \
00635                          + sec->output_offset \
00636                          - sec->vma);
00637 
00638   SET (".text", scText);
00639   SET (".data", scData);
00640   SET (".bss", scBss);
00641   SET (".sdata", scSData);
00642   SET (".sbss", scSBss);
00643   /* scRdata section may be either .rdata or .rodata.  */
00644   SET (".rdata", scRData);
00645   SET (".rodata", scRData);
00646   SET (".init", scInit);
00647   SET (".fini", scFini);
00648   SET (".rconst", scRConst);
00649 
00650 #undef SET
00651 
00652   /* Find all the debugging information based on the FDR's.  We need
00653      to handle them whether they are swapped or not.  */
00654   if (input_debug->fdr != (FDR *) NULL)
00655     {
00656       fdr_start = (bfd_byte *) input_debug->fdr;
00657       fdr_add = sizeof (FDR);
00658     }
00659   else
00660     {
00661       fdr_start = (bfd_byte *) input_debug->external_fdr;
00662       fdr_add = input_swap->external_fdr_size;
00663     }
00664   fdr_end = fdr_start + input_symhdr->ifdMax * fdr_add;
00665 
00666   amt = input_symhdr->ifdMax;
00667   amt *= sizeof (RFDT);
00668   input_debug->ifdmap = (RFDT *) bfd_alloc (input_bfd, amt);
00669 
00670   sz = (input_symhdr->crfd + input_symhdr->ifdMax) * external_rfd_size;
00671   rfd_out = (bfd_byte *) objalloc_alloc (ainfo->memory, sz);
00672   if (!input_debug->ifdmap || !rfd_out)
00673     {
00674       bfd_set_error (bfd_error_no_memory);
00675       return FALSE;
00676     }
00677   if (!add_memory_shuffle (ainfo, &ainfo->rfd, &ainfo->rfd_end, rfd_out, sz))
00678     return FALSE;
00679 
00680   copied = 0;
00681 
00682   /* Look through the FDR's to see which ones we are going to include
00683      in the final output.  We do not want duplicate FDR information
00684      for header files, because ECOFF debugging is often very large.
00685      When we find an FDR with no line information which can be merged,
00686      we look it up in a hash table to ensure that we only include it
00687      once.  We keep a table mapping FDR numbers to the final number
00688      they get with the BFD, so that we can refer to it when we write
00689      out the external symbols.  */
00690   for (fdr_ptr = fdr_start, i = 0;
00691        fdr_ptr < fdr_end;
00692        fdr_ptr += fdr_add, i++, rfd_out += external_rfd_size)
00693     {
00694       FDR fdr;
00695 
00696       if (input_debug->fdr != (FDR *) NULL)
00697        fdr = *(FDR *) fdr_ptr;
00698       else
00699        (*input_swap->swap_fdr_in) (input_bfd, (PTR) fdr_ptr, &fdr);
00700 
00701       /* See if this FDR can be merged with an existing one.  */
00702       if (fdr.cbLine == 0 && fdr.rss != -1 && fdr.fMerge)
00703        {
00704          const char *name;
00705          char *lookup;
00706          struct string_hash_entry *fh;
00707 
00708          /* We look up a string formed from the file name and the
00709             number of symbols and aux entries.  Sometimes an include
00710             file will conditionally define a typedef or something
00711             based on the order of include files.  Using the number of
00712             symbols and aux entries as a hash reduces the chance that
00713             we will merge symbol information that should not be
00714             merged.  */
00715          name = input_debug->ss + fdr.issBase + fdr.rss;
00716 
00717          lookup = (char *) bfd_malloc ((bfd_size_type) strlen (name) + 20);
00718          if (lookup == NULL)
00719            return FALSE;
00720          sprintf (lookup, "%s %lx %lx", name, fdr.csym, fdr.caux);
00721 
00722          fh = string_hash_lookup (&ainfo->fdr_hash, lookup, TRUE, TRUE);
00723          free (lookup);
00724          if (fh == (struct string_hash_entry *) NULL)
00725            return FALSE;
00726 
00727          if (fh->val != -1)
00728            {
00729              input_debug->ifdmap[i] = fh->val;
00730              (*swap_rfd_out) (output_bfd, input_debug->ifdmap + i,
00731                             (PTR) rfd_out);
00732 
00733              /* Don't copy this FDR.  */
00734              continue;
00735            }
00736 
00737          fh->val = output_symhdr->ifdMax + copied;
00738        }
00739 
00740       input_debug->ifdmap[i] = output_symhdr->ifdMax + copied;
00741       (*swap_rfd_out) (output_bfd, input_debug->ifdmap + i, (PTR) rfd_out);
00742       ++copied;
00743     }
00744 
00745   newrfdbase = output_symhdr->crfd;
00746   output_symhdr->crfd += input_symhdr->ifdMax;
00747 
00748   /* Copy over any existing RFD's.  RFD's are only created by the
00749      linker, so this will only happen for input files which are the
00750      result of a partial link.  */
00751   rfd_in = (bfd_byte *) input_debug->external_rfd;
00752   rfd_end = rfd_in + input_symhdr->crfd * input_swap->external_rfd_size;
00753   for (;
00754        rfd_in < rfd_end;
00755        rfd_in += input_swap->external_rfd_size)
00756     {
00757       RFDT rfd;
00758 
00759       (*swap_rfd_in) (input_bfd, (PTR) rfd_in, &rfd);
00760       BFD_ASSERT (rfd >= 0 && rfd < input_symhdr->ifdMax);
00761       rfd = input_debug->ifdmap[rfd];
00762       (*swap_rfd_out) (output_bfd, &rfd, (PTR) rfd_out);
00763       rfd_out += external_rfd_size;
00764     }
00765 
00766   oldrfdbase = output_symhdr->crfd;
00767   output_symhdr->crfd += input_symhdr->crfd;
00768 
00769   /* Look through the FDR's and copy over all associated debugging
00770      information.  */
00771   sz = copied * external_fdr_size;
00772   fdr_out = (bfd_byte *) objalloc_alloc (ainfo->memory, sz);
00773   if (!fdr_out)
00774     {
00775       bfd_set_error (bfd_error_no_memory);
00776       return FALSE;
00777     }
00778   if (!add_memory_shuffle (ainfo, &ainfo->fdr, &ainfo->fdr_end, fdr_out, sz))
00779     return FALSE;
00780   for (fdr_ptr = fdr_start, i = 0;
00781        fdr_ptr < fdr_end;
00782        fdr_ptr += fdr_add, i++)
00783     {
00784       FDR fdr;
00785       bfd_byte *sym_out;
00786       bfd_byte *lraw_src;
00787       bfd_byte *lraw_end;
00788       bfd_boolean fgotfilename;
00789 
00790       if (input_debug->ifdmap[i] < output_symhdr->ifdMax)
00791        {
00792          /* We are not copying this FDR.  */
00793          continue;
00794        }
00795 
00796       if (input_debug->fdr != (FDR *) NULL)
00797        fdr = *(FDR *) fdr_ptr;
00798       else
00799        (*input_swap->swap_fdr_in) (input_bfd, (PTR) fdr_ptr, &fdr);
00800 
00801       /* FIXME: It is conceivable that this FDR points to the .init or
00802         .fini section, in which case this will not do the right
00803         thing.  */
00804       fdr.adr += section_adjust[scText];
00805 
00806       /* Swap in the local symbols, adjust their values, and swap them
00807         out again.  */
00808       fgotfilename = FALSE;
00809       sz = fdr.csym * external_sym_size;
00810       sym_out = (bfd_byte *) objalloc_alloc (ainfo->memory, sz);
00811       if (!sym_out)
00812        {
00813          bfd_set_error (bfd_error_no_memory);
00814          return FALSE;
00815        }
00816       if (!add_memory_shuffle (ainfo, &ainfo->sym, &ainfo->sym_end, sym_out,
00817                             sz))
00818        return FALSE;
00819       lraw_src = ((bfd_byte *) input_debug->external_sym
00820                 + fdr.isymBase * input_swap->external_sym_size);
00821       lraw_end = lraw_src + fdr.csym * input_swap->external_sym_size;
00822       for (;  lraw_src < lraw_end;  lraw_src += input_swap->external_sym_size)
00823        {
00824          SYMR internal_sym;
00825 
00826          (*swap_sym_in) (input_bfd, (PTR) lraw_src, &internal_sym);
00827 
00828          BFD_ASSERT (internal_sym.sc != scCommon
00829                     && internal_sym.sc != scSCommon);
00830 
00831          /* Adjust the symbol value if appropriate.  */
00832          switch (internal_sym.st)
00833            {
00834            case stNil:
00835              if (ECOFF_IS_STAB (&internal_sym))
00836               break;
00837              /* Fall through.  */
00838            case stGlobal:
00839            case stStatic:
00840            case stLabel:
00841            case stProc:
00842            case stStaticProc:
00843              internal_sym.value += section_adjust[internal_sym.sc];
00844              break;
00845 
00846            default:
00847              break;
00848            }
00849 
00850          /* If we are doing a final link, we hash all the strings in
00851             the local symbol table together.  This reduces the amount
00852             of space required by debugging information.  We don't do
00853             this when performing a relocatable link because it would
00854             prevent us from easily merging different FDR's.  */
00855          if (! info->relocatable)
00856            {
00857              bfd_boolean ffilename;
00858              const char *name;
00859 
00860              if (! fgotfilename && internal_sym.iss == fdr.rss)
00861               ffilename = TRUE;
00862              else
00863               ffilename = FALSE;
00864 
00865              /* Hash the name into the string table.  */
00866              name = input_debug->ss + fdr.issBase + internal_sym.iss;
00867              if (*name == '\0')
00868               internal_sym.iss = 0;
00869              else
00870               {
00871                 struct string_hash_entry *sh;
00872 
00873                 sh = string_hash_lookup (&ainfo->str_hash, name, TRUE, TRUE);
00874                 if (sh == (struct string_hash_entry *) NULL)
00875                   return FALSE;
00876                 if (sh->val == -1)
00877                   {
00878                     sh->val = output_symhdr->issMax;
00879                     output_symhdr->issMax += strlen (name) + 1;
00880                     if (ainfo->ss_hash == (struct string_hash_entry *) NULL)
00881                      ainfo->ss_hash = sh;
00882                     if (ainfo->ss_hash_end
00883                        != (struct string_hash_entry *) NULL)
00884                      ainfo->ss_hash_end->next = sh;
00885                     ainfo->ss_hash_end = sh;
00886                   }
00887                 internal_sym.iss = sh->val;
00888               }
00889 
00890              if (ffilename)
00891               {
00892                 fdr.rss = internal_sym.iss;
00893                 fgotfilename = TRUE;
00894               }
00895            }
00896 
00897          (*swap_sym_out) (output_bfd, &internal_sym, sym_out);
00898          sym_out += external_sym_size;
00899        }
00900 
00901       fdr.isymBase = output_symhdr->isymMax;
00902       output_symhdr->isymMax += fdr.csym;
00903 
00904       /* Copy the information that does not need swapping.  */
00905 
00906       /* FIXME: If we are relaxing, we need to adjust the line
00907         numbers.  Frankly, forget it.  Anybody using stabs debugging
00908         information will not use this line number information, and
00909         stabs are adjusted correctly.  */
00910       if (fdr.cbLine > 0)
00911        {
00912          file_ptr pos = input_symhdr->cbLineOffset + fdr.cbLineOffset;
00913          if (!add_file_shuffle (ainfo, &ainfo->line, &ainfo->line_end,
00914                              input_bfd, pos, (unsigned long) fdr.cbLine))
00915            return FALSE;
00916          fdr.ilineBase = output_symhdr->ilineMax;
00917          fdr.cbLineOffset = output_symhdr->cbLine;
00918          output_symhdr->ilineMax += fdr.cline;
00919          output_symhdr->cbLine += fdr.cbLine;
00920        }
00921       if (fdr.caux > 0)
00922        {
00923          file_ptr pos = (input_symhdr->cbAuxOffset
00924                        + fdr.iauxBase * sizeof (union aux_ext));
00925          if (!add_file_shuffle (ainfo, &ainfo->aux, &ainfo->aux_end,
00926                              input_bfd, pos,
00927                              fdr.caux * sizeof (union aux_ext)))
00928            return FALSE;
00929          fdr.iauxBase = output_symhdr->iauxMax;
00930          output_symhdr->iauxMax += fdr.caux;
00931        }
00932       if (! info->relocatable)
00933        {
00934 
00935          /* When are are hashing strings, we lie about the number of
00936             strings attached to each FDR.  We need to set cbSs
00937             because some versions of dbx apparently use it to decide
00938             how much of the string table to read in.  */
00939          fdr.issBase = 0;
00940          fdr.cbSs = output_symhdr->issMax;
00941        }
00942       else if (fdr.cbSs > 0)
00943        {
00944          file_ptr pos = input_symhdr->cbSsOffset + fdr.issBase;
00945          if (!add_file_shuffle (ainfo, &ainfo->ss, &ainfo->ss_end,
00946                              input_bfd, pos, (unsigned long) fdr.cbSs))
00947            return FALSE;
00948          fdr.issBase = output_symhdr->issMax;
00949          output_symhdr->issMax += fdr.cbSs;
00950        }
00951 
00952       if (output_bfd->xvec->header_byteorder
00953          == input_bfd->xvec->header_byteorder)
00954        {
00955          /* The two BFD's have the same endianness, and we don't have
00956             to adjust the PDR addresses, so simply copying the
00957             information will suffice.  */
00958          BFD_ASSERT (external_pdr_size == input_swap->external_pdr_size);
00959          if (fdr.cpd > 0)
00960            {
00961              file_ptr pos = (input_symhdr->cbPdOffset
00962                            + fdr.ipdFirst * external_pdr_size);
00963              unsigned long size = fdr.cpd * external_pdr_size;
00964              if (!add_file_shuffle (ainfo, &ainfo->pdr, &ainfo->pdr_end,
00965                                  input_bfd, pos, size))
00966               return FALSE;
00967            }
00968          BFD_ASSERT (external_opt_size == input_swap->external_opt_size);
00969          if (fdr.copt > 0)
00970            {
00971              file_ptr pos = (input_symhdr->cbOptOffset
00972                            + fdr.ioptBase * external_opt_size);
00973              unsigned long size = fdr.copt * external_opt_size;
00974              if (!add_file_shuffle (ainfo, &ainfo->opt, &ainfo->opt_end,
00975                                  input_bfd, pos, size))
00976               return FALSE;
00977            }
00978        }
00979       else
00980        {
00981          bfd_size_type outsz, insz;
00982          bfd_byte *in;
00983          bfd_byte *end;
00984          bfd_byte *out;
00985 
00986          /* The two BFD's have different endianness, so we must swap
00987             everything in and out.  This code would always work, but
00988             it would be unnecessarily slow in the normal case.  */
00989          outsz = external_pdr_size;
00990          insz = input_swap->external_pdr_size;
00991          in = ((bfd_byte *) input_debug->external_pdr
00992               + fdr.ipdFirst * insz);
00993          end = in + fdr.cpd * insz;
00994          sz = fdr.cpd * outsz;
00995          out = (bfd_byte *) objalloc_alloc (ainfo->memory, sz);
00996          if (!out)
00997            {
00998              bfd_set_error (bfd_error_no_memory);
00999              return FALSE;
01000            }
01001          if (!add_memory_shuffle (ainfo, &ainfo->pdr, &ainfo->pdr_end, out,
01002                                sz))
01003            return FALSE;
01004          for (; in < end; in += insz, out += outsz)
01005            {
01006              PDR pdr;
01007 
01008              (*input_swap->swap_pdr_in) (input_bfd, (PTR) in, &pdr);
01009              (*output_swap->swap_pdr_out) (output_bfd, &pdr, (PTR) out);
01010            }
01011 
01012          /* Swap over the optimization information.  */
01013          outsz = external_opt_size;
01014          insz = input_swap->external_opt_size;
01015          in = ((bfd_byte *) input_debug->external_opt
01016               + fdr.ioptBase * insz);
01017          end = in + fdr.copt * insz;
01018          sz = fdr.copt * outsz;
01019          out = (bfd_byte *) objalloc_alloc (ainfo->memory, sz);
01020          if (!out)
01021            {
01022              bfd_set_error (bfd_error_no_memory);
01023              return FALSE;
01024            }
01025          if (!add_memory_shuffle (ainfo, &ainfo->opt, &ainfo->opt_end, out,
01026                                sz))
01027            return FALSE;
01028          for (; in < end; in += insz, out += outsz)
01029            {
01030              OPTR opt;
01031 
01032              (*input_swap->swap_opt_in) (input_bfd, (PTR) in, &opt);
01033              (*output_swap->swap_opt_out) (output_bfd, &opt, (PTR) out);
01034            }
01035        }
01036 
01037       fdr.ipdFirst = output_symhdr->ipdMax;
01038       output_symhdr->ipdMax += fdr.cpd;
01039       fdr.ioptBase = output_symhdr->ioptMax;
01040       output_symhdr->ioptMax += fdr.copt;
01041 
01042       if (fdr.crfd <= 0)
01043        {
01044          /* Point this FDR at the table of RFD's we created.  */
01045          fdr.rfdBase = newrfdbase;
01046          fdr.crfd = input_symhdr->ifdMax;
01047        }
01048       else
01049        {
01050          /* Point this FDR at the remapped RFD's.  */
01051          fdr.rfdBase += oldrfdbase;
01052        }
01053 
01054       (*swap_fdr_out) (output_bfd, &fdr, fdr_out);
01055       fdr_out += external_fdr_size;
01056       ++output_symhdr->ifdMax;
01057     }
01058 
01059   return TRUE;
01060 }
01061 
01062 /* Add a string to the debugging information we are accumulating.
01063    Return the offset from the fdr string base.  */
01064 
01065 static long ecoff_add_string
01066   PARAMS ((struct accumulate *, struct bfd_link_info *,
01067           struct ecoff_debug_info *, FDR *fdr, const char *string));
01068 
01069 static long
01070 ecoff_add_string (ainfo, info, debug, fdr, string)
01071      struct accumulate *ainfo;
01072      struct bfd_link_info *info;
01073      struct ecoff_debug_info *debug;
01074      FDR *fdr;
01075      const char *string;
01076 {
01077   HDRR *symhdr;
01078   size_t len;
01079   bfd_size_type ret;
01080 
01081   symhdr = &debug->symbolic_header;
01082   len = strlen (string);
01083   if (info->relocatable)
01084     {
01085       if (!add_memory_shuffle (ainfo, &ainfo->ss, &ainfo->ss_end, (PTR) string,
01086                             len + 1))
01087        return -1;
01088       ret = symhdr->issMax;
01089       symhdr->issMax += len + 1;
01090       fdr->cbSs += len + 1;
01091     }
01092   else
01093     {
01094       struct string_hash_entry *sh;
01095 
01096       sh = string_hash_lookup (&ainfo->str_hash, string, TRUE, TRUE);
01097       if (sh == (struct string_hash_entry *) NULL)
01098        return -1;
01099       if (sh->val == -1)
01100        {
01101          sh->val = symhdr->issMax;
01102          symhdr->issMax += len + 1;
01103          if (ainfo->ss_hash == (struct string_hash_entry *) NULL)
01104            ainfo->ss_hash = sh;
01105          if (ainfo->ss_hash_end
01106              != (struct string_hash_entry *) NULL)
01107            ainfo->ss_hash_end->next = sh;
01108          ainfo->ss_hash_end = sh;
01109        }
01110       ret = sh->val;
01111     }
01112 
01113   return ret;
01114 }
01115 
01116 /* Add debugging information from a non-ECOFF file.  */
01117 
01118 bfd_boolean
01119 bfd_ecoff_debug_accumulate_other (handle, output_bfd, output_debug,
01120                               output_swap, input_bfd, info)
01121      PTR handle;
01122      bfd *output_bfd;
01123      struct ecoff_debug_info *output_debug;
01124      const struct ecoff_debug_swap *output_swap;
01125      bfd *input_bfd;
01126      struct bfd_link_info *info;
01127 {
01128   struct accumulate *ainfo = (struct accumulate *) handle;
01129   void (* const swap_sym_out) PARAMS ((bfd *, const SYMR *, PTR))
01130     = output_swap->swap_sym_out;
01131   HDRR *output_symhdr = &output_debug->symbolic_header;
01132   FDR fdr;
01133   asection *sec;
01134   asymbol **symbols;
01135   asymbol **sym_ptr;
01136   asymbol **sym_end;
01137   long symsize;
01138   long symcount;
01139   PTR external_fdr;
01140 
01141   memset ((PTR) &fdr, 0, sizeof fdr);
01142 
01143   sec = bfd_get_section_by_name (input_bfd, ".text");
01144   if (sec != NULL)
01145     fdr.adr = sec->output_section->vma + sec->output_offset;
01146   else
01147     {
01148       /* FIXME: What about .init or .fini?  */
01149       fdr.adr = 0;
01150     }
01151 
01152   fdr.issBase = output_symhdr->issMax;
01153   fdr.cbSs = 0;
01154   fdr.rss = ecoff_add_string (ainfo, info, output_debug, &fdr,
01155                            input_bfd->filename);
01156   if (fdr.rss == -1)
01157     return FALSE;
01158   fdr.isymBase = output_symhdr->isymMax;
01159 
01160   /* Get the local symbols from the input BFD.  */
01161   symsize = bfd_get_symtab_upper_bound (input_bfd);
01162   if (symsize < 0)
01163     return FALSE;
01164   symbols = (asymbol **) bfd_alloc (output_bfd, (bfd_size_type) symsize);
01165   if (symbols == (asymbol **) NULL)
01166     return FALSE;
01167   symcount = bfd_canonicalize_symtab (input_bfd, symbols);
01168   if (symcount < 0)
01169     return FALSE;
01170   sym_end = symbols + symcount;
01171 
01172   /* Handle the local symbols.  Any external symbols are handled
01173      separately.  */
01174   fdr.csym = 0;
01175   for (sym_ptr = symbols; sym_ptr != sym_end; sym_ptr++)
01176     {
01177       SYMR internal_sym;
01178       PTR external_sym;
01179 
01180       if (((*sym_ptr)->flags & BSF_EXPORT) != 0)
01181        continue;
01182       memset ((PTR) &internal_sym, 0, sizeof internal_sym);
01183       internal_sym.iss = ecoff_add_string (ainfo, info, output_debug, &fdr,
01184                                       (*sym_ptr)->name);
01185 
01186       if (internal_sym.iss == -1)
01187        return FALSE;
01188       if (bfd_is_com_section ((*sym_ptr)->section)
01189          || bfd_is_und_section ((*sym_ptr)->section))
01190        internal_sym.value = (*sym_ptr)->value;
01191       else
01192        internal_sym.value = ((*sym_ptr)->value
01193                            + (*sym_ptr)->section->output_offset
01194                            + (*sym_ptr)->section->output_section->vma);
01195       internal_sym.st = stNil;
01196       internal_sym.sc = scUndefined;
01197       internal_sym.index = indexNil;
01198 
01199       external_sym = (PTR) objalloc_alloc (ainfo->memory,
01200                                       output_swap->external_sym_size);
01201       if (!external_sym)
01202        {
01203          bfd_set_error (bfd_error_no_memory);
01204          return FALSE;
01205        }
01206       (*swap_sym_out) (output_bfd, &internal_sym, external_sym);
01207       add_memory_shuffle (ainfo, &ainfo->sym, &ainfo->sym_end,
01208                        external_sym,
01209                        (unsigned long) output_swap->external_sym_size);
01210       ++fdr.csym;
01211       ++output_symhdr->isymMax;
01212     }
01213 
01214   bfd_release (output_bfd, (PTR) symbols);
01215 
01216   /* Leave everything else in the FDR zeroed out.  This will cause
01217      the lang field to be langC.  The fBigendian field will
01218      indicate little endian format, but it doesn't matter because
01219      it only applies to aux fields and there are none.  */
01220   external_fdr = (PTR) objalloc_alloc (ainfo->memory,
01221                                    output_swap->external_fdr_size);
01222   if (!external_fdr)
01223     {
01224       bfd_set_error (bfd_error_no_memory);
01225       return FALSE;
01226     }
01227   (*output_swap->swap_fdr_out) (output_bfd, &fdr, external_fdr);
01228   add_memory_shuffle (ainfo, &ainfo->fdr, &ainfo->fdr_end,
01229                     external_fdr,
01230                     (unsigned long) output_swap->external_fdr_size);
01231 
01232   ++output_symhdr->ifdMax;
01233 
01234   return TRUE;
01235 }
01236 
01237 /* Set up ECOFF debugging information for the external symbols.
01238    FIXME: This is done using a memory buffer, but it should be
01239    probably be changed to use a shuffle structure.  The assembler uses
01240    this interface, so that must be changed to do something else.  */
01241 
01242 bfd_boolean
01243 bfd_ecoff_debug_externals (abfd, debug, swap, relocatable, get_extr,
01244                         set_index)
01245      bfd *abfd;
01246      struct ecoff_debug_info *debug;
01247      const struct ecoff_debug_swap *swap;
01248      bfd_boolean relocatable;
01249      bfd_boolean (*get_extr) PARAMS ((asymbol *, EXTR *));
01250      void (*set_index) PARAMS ((asymbol *, bfd_size_type));
01251 {
01252   HDRR * const symhdr = &debug->symbolic_header;
01253   asymbol **sym_ptr_ptr;
01254   size_t c;
01255 
01256   sym_ptr_ptr = bfd_get_outsymbols (abfd);
01257   if (sym_ptr_ptr == NULL)
01258     return TRUE;
01259 
01260   for (c = bfd_get_symcount (abfd); c > 0; c--, sym_ptr_ptr++)
01261     {
01262       asymbol *sym_ptr;
01263       EXTR esym;
01264 
01265       sym_ptr = *sym_ptr_ptr;
01266 
01267       /* Get the external symbol information.  */
01268       if (! (*get_extr) (sym_ptr, &esym))
01269        continue;
01270 
01271       /* If we're producing an executable, move common symbols into
01272         bss.  */
01273       if (! relocatable)
01274        {
01275          if (esym.asym.sc == scCommon)
01276            esym.asym.sc = scBss;
01277          else if (esym.asym.sc == scSCommon)
01278            esym.asym.sc = scSBss;
01279        }
01280 
01281       if (bfd_is_com_section (sym_ptr->section)
01282          || bfd_is_und_section (sym_ptr->section)
01283          || sym_ptr->section->output_section == (asection *) NULL)
01284        {
01285          /* FIXME: gas does not keep the value of a small undefined
01286             symbol in the symbol itself, because of relocation
01287             problems.  */
01288          if (esym.asym.sc != scSUndefined
01289              || esym.asym.value == 0
01290              || sym_ptr->value != 0)
01291            esym.asym.value = sym_ptr->value;
01292        }
01293       else
01294        esym.asym.value = (sym_ptr->value
01295                         + sym_ptr->section->output_offset
01296                         + sym_ptr->section->output_section->vma);
01297 
01298       if (set_index)
01299        (*set_index) (sym_ptr, (bfd_size_type) symhdr->iextMax);
01300 
01301       if (! bfd_ecoff_debug_one_external (abfd, debug, swap,
01302                                      sym_ptr->name, &esym))
01303        return FALSE;
01304     }
01305 
01306   return TRUE;
01307 }
01308 
01309 /* Add a single external symbol to the debugging information.  */
01310 
01311 bfd_boolean
01312 bfd_ecoff_debug_one_external (abfd, debug, swap, name, esym)
01313      bfd *abfd;
01314      struct ecoff_debug_info *debug;
01315      const struct ecoff_debug_swap *swap;
01316      const char *name;
01317      EXTR *esym;
01318 {
01319   const bfd_size_type external_ext_size = swap->external_ext_size;
01320   void (* const swap_ext_out) PARAMS ((bfd *, const EXTR *, PTR))
01321     = swap->swap_ext_out;
01322   HDRR * const symhdr = &debug->symbolic_header;
01323   size_t namelen;
01324 
01325   namelen = strlen (name);
01326 
01327   if ((size_t) (debug->ssext_end - debug->ssext)
01328       < symhdr->issExtMax + namelen + 1)
01329     {
01330       if (! ecoff_add_bytes ((char **) &debug->ssext,
01331                           (char **) &debug->ssext_end,
01332                           symhdr->issExtMax + namelen + 1))
01333        return FALSE;
01334     }
01335   if ((size_t) ((char *) debug->external_ext_end
01336               - (char *) debug->external_ext)
01337       < (symhdr->iextMax + 1) * external_ext_size)
01338     {
01339       char *external_ext = debug->external_ext;
01340       char *external_ext_end = debug->external_ext_end;
01341       if (! ecoff_add_bytes ((char **) &external_ext,
01342                           (char **) &external_ext_end,
01343                           (symhdr->iextMax + 1) * (size_t) external_ext_size))
01344        return FALSE;
01345       debug->external_ext = external_ext;
01346       debug->external_ext_end = external_ext_end;
01347     }
01348 
01349   esym->asym.iss = symhdr->issExtMax;
01350 
01351   (*swap_ext_out) (abfd, esym,
01352                  ((char *) debug->external_ext
01353                   + symhdr->iextMax * swap->external_ext_size));
01354 
01355   ++symhdr->iextMax;
01356 
01357   strcpy (debug->ssext + symhdr->issExtMax, name);
01358   symhdr->issExtMax += namelen + 1;
01359 
01360   return TRUE;
01361 }
01362 
01363 /* Align the ECOFF debugging information.  */
01364 
01365 static void
01366 ecoff_align_debug (abfd, debug, swap)
01367      bfd *abfd ATTRIBUTE_UNUSED;
01368      struct ecoff_debug_info *debug;
01369      const struct ecoff_debug_swap *swap;
01370 {
01371   HDRR * const symhdr = &debug->symbolic_header;
01372   bfd_size_type debug_align, aux_align, rfd_align;
01373   size_t add;
01374 
01375   /* Adjust the counts so that structures are aligned.  */
01376   debug_align = swap->debug_align;
01377   aux_align = debug_align / sizeof (union aux_ext);
01378   rfd_align = debug_align / swap->external_rfd_size;
01379 
01380   add = debug_align - (symhdr->cbLine & (debug_align - 1));
01381   if (add != debug_align)
01382     {
01383       if (debug->line != (unsigned char *) NULL)
01384        memset ((PTR) (debug->line + symhdr->cbLine), 0, add);
01385       symhdr->cbLine += add;
01386     }
01387 
01388   add = debug_align - (symhdr->issMax & (debug_align - 1));
01389   if (add != debug_align)
01390     {
01391       if (debug->ss != (char *) NULL)
01392        memset ((PTR) (debug->ss + symhdr->issMax), 0, add);
01393       symhdr->issMax += add;
01394     }
01395 
01396   add = debug_align - (symhdr->issExtMax & (debug_align - 1));
01397   if (add != debug_align)
01398     {
01399       if (debug->ssext != (char *) NULL)
01400        memset ((PTR) (debug->ssext + symhdr->issExtMax), 0, add);
01401       symhdr->issExtMax += add;
01402     }
01403 
01404   add = aux_align - (symhdr->iauxMax & (aux_align - 1));
01405   if (add != aux_align)
01406     {
01407       if (debug->external_aux != (union aux_ext *) NULL)
01408        memset ((PTR) (debug->external_aux + symhdr->iauxMax), 0,
01409               add * sizeof (union aux_ext));
01410       symhdr->iauxMax += add;
01411     }
01412 
01413   add = rfd_align - (symhdr->crfd & (rfd_align - 1));
01414   if (add != rfd_align)
01415     {
01416       if (debug->external_rfd != (PTR) NULL)
01417        memset ((PTR) ((char *) debug->external_rfd
01418                      + symhdr->crfd * swap->external_rfd_size),
01419               0, (size_t) (add * swap->external_rfd_size));
01420       symhdr->crfd += add;
01421     }
01422 }
01423 
01424 /* Return the size required by the ECOFF debugging information.  */
01425 
01426 bfd_size_type
01427 bfd_ecoff_debug_size (abfd, debug, swap)
01428      bfd *abfd;
01429      struct ecoff_debug_info *debug;
01430      const struct ecoff_debug_swap *swap;
01431 {
01432   bfd_size_type tot;
01433 
01434   ecoff_align_debug (abfd, debug, swap);
01435   tot = swap->external_hdr_size;
01436 
01437 #define ADD(count, size) \
01438   tot += debug->symbolic_header.count * size
01439 
01440   ADD (cbLine, sizeof (unsigned char));
01441   ADD (idnMax, swap->external_dnr_size);
01442   ADD (ipdMax, swap->external_pdr_size);
01443   ADD (isymMax, swap->external_sym_size);
01444   ADD (ioptMax, swap->external_opt_size);
01445   ADD (iauxMax, sizeof (union aux_ext));
01446   ADD (issMax, sizeof (char));
01447   ADD (issExtMax, sizeof (char));
01448   ADD (ifdMax, swap->external_fdr_size);
01449   ADD (crfd, swap->external_rfd_size);
01450   ADD (iextMax, swap->external_ext_size);
01451 
01452 #undef ADD
01453 
01454   return tot;
01455 }
01456 
01457 /* Write out the ECOFF symbolic header, given the file position it is
01458    going to be placed at.  This assumes that the counts are set
01459    correctly.  */
01460 
01461 static bfd_boolean
01462 ecoff_write_symhdr (abfd, debug, swap, where)
01463      bfd *abfd;
01464      struct ecoff_debug_info *debug;
01465      const struct ecoff_debug_swap *swap;
01466      file_ptr where;
01467 {
01468   HDRR * const symhdr = &debug->symbolic_header;
01469   char *buff = NULL;
01470 
01471   ecoff_align_debug (abfd, debug, swap);
01472 
01473   /* Go to the right location in the file.  */
01474   if (bfd_seek (abfd, where, SEEK_SET) != 0)
01475     return FALSE;
01476 
01477   where += swap->external_hdr_size;
01478 
01479   symhdr->magic = swap->sym_magic;
01480 
01481   /* Fill in the file offsets.  */
01482 #define SET(offset, count, size) \
01483   if (symhdr->count == 0) \
01484     symhdr->offset = 0; \
01485   else \
01486     { \
01487       symhdr->offset = where; \
01488       where += symhdr->count * size; \
01489     }
01490 
01491   SET (cbLineOffset, cbLine, sizeof (unsigned char));
01492   SET (cbDnOffset, idnMax, swap->external_dnr_size);
01493   SET (cbPdOffset, ipdMax, swap->external_pdr_size);
01494   SET (cbSymOffset, isymMax, swap->external_sym_size);
01495   SET (cbOptOffset, ioptMax, swap->external_opt_size);
01496   SET (cbAuxOffset, iauxMax, sizeof (union aux_ext));
01497   SET (cbSsOffset, issMax, sizeof (char));
01498   SET (cbSsExtOffset, issExtMax, sizeof (char));
01499   SET (cbFdOffset, ifdMax, swap->external_fdr_size);
01500   SET (cbRfdOffset, crfd, swap->external_rfd_size);
01501   SET (cbExtOffset, iextMax, swap->external_ext_size);
01502 #undef SET
01503 
01504   buff = (PTR) bfd_malloc (swap->external_hdr_size);
01505   if (buff == NULL && swap->external_hdr_size != 0)
01506     goto error_return;
01507 
01508   (*swap->swap_hdr_out) (abfd, symhdr, buff);
01509   if (bfd_bwrite (buff, swap->external_hdr_size, abfd)
01510       != swap->external_hdr_size)
01511     goto error_return;
01512 
01513   if (buff != NULL)
01514     free (buff);
01515   return TRUE;
01516  error_return:
01517   if (buff != NULL)
01518     free (buff);
01519   return FALSE;
01520 }
01521 
01522 /* Write out the ECOFF debugging information.  This function assumes
01523    that the information (the pointers and counts) in *DEBUG have been
01524    set correctly.  WHERE is the position in the file to write the
01525    information to.  This function fills in the file offsets in the
01526    symbolic header.  */
01527 
01528 bfd_boolean
01529 bfd_ecoff_write_debug (abfd, debug, swap, where)
01530      bfd *abfd;
01531      struct ecoff_debug_info *debug;
01532      const struct ecoff_debug_swap *swap;
01533      file_ptr where;
01534 {
01535   HDRR * const symhdr = &debug->symbolic_header;
01536 
01537   if (! ecoff_write_symhdr (abfd, debug, swap, where))
01538     return FALSE;
01539 
01540 #define WRITE(ptr, count, size, offset) \
01541   BFD_ASSERT (symhdr->offset == 0 \
01542              || (bfd_vma) bfd_tell (abfd) == symhdr->offset); \
01543   if (bfd_bwrite ((PTR) debug->ptr, (bfd_size_type) size * symhdr->count, abfd)\
01544       != size * symhdr->count) \
01545     return FALSE;
01546 
01547   WRITE (line, cbLine, sizeof (unsigned char), cbLineOffset);
01548   WRITE (external_dnr, idnMax, swap->external_dnr_size, cbDnOffset);
01549   WRITE (external_pdr, ipdMax, swap->external_pdr_size, cbPdOffset);
01550   WRITE (external_sym, isymMax, swap->external_sym_size, cbSymOffset);
01551   WRITE (external_opt, ioptMax, swap->external_opt_size, cbOptOffset);
01552   WRITE (external_aux, iauxMax, (bfd_size_type) sizeof (union aux_ext),
01553         cbAuxOffset);
01554   WRITE (ss, issMax, sizeof (char), cbSsOffset);
01555   WRITE (ssext, issExtMax, sizeof (char), cbSsExtOffset);
01556   WRITE (external_fdr, ifdMax, swap->external_fdr_size, cbFdOffset);
01557   WRITE (external_rfd, crfd, swap->external_rfd_size, cbRfdOffset);
01558   WRITE (external_ext, iextMax, swap->external_ext_size, cbExtOffset);
01559 #undef WRITE
01560 
01561   return TRUE;
01562 }
01563 
01564 /* Write out a shuffle list.  */
01565 
01566 static bfd_boolean ecoff_write_shuffle
01567   PARAMS ((bfd *, const struct ecoff_debug_swap *, struct shuffle *,
01568           PTR space));
01569 
01570 static bfd_boolean
01571 ecoff_write_shuffle (abfd, swap, shuffle, space)
01572      bfd *abfd;
01573      const struct ecoff_debug_swap *swap;
01574      struct shuffle *shuffle;
01575      PTR space;
01576 {
01577   register struct shuffle *l;
01578   unsigned long total;
01579 
01580   total = 0;
01581   for (l = shuffle; l != (struct shuffle *) NULL; l = l->next)
01582     {
01583       if (! l->filep)
01584        {
01585          if (bfd_bwrite (l->u.memory, (bfd_size_type) l->size, abfd)
01586              != l->size)
01587            return FALSE;
01588        }
01589       else
01590        {
01591          if (bfd_seek (l->u.file.input_bfd, l->u.file.offset, SEEK_SET) != 0
01592              || bfd_bread (space, (bfd_size_type) l->size,
01593                         l->u.file.input_bfd) != l->size
01594              || bfd_bwrite (space, (bfd_size_type) l->size, abfd) != l->size)
01595            return FALSE;
01596        }
01597       total += l->size;
01598     }
01599 
01600   if ((total & (swap->debug_align - 1)) != 0)
01601     {
01602       unsigned int i;
01603       bfd_byte *s;
01604 
01605       i = swap->debug_align - (total & (swap->debug_align - 1));
01606       s = (bfd_byte *) bfd_zmalloc ((bfd_size_type) i);
01607       if (s == NULL && i != 0)
01608        return FALSE;
01609 
01610       if (bfd_bwrite ((PTR) s, (bfd_size_type) i, abfd) != i)
01611        {
01612          free (s);
01613          return FALSE;
01614        }
01615       free (s);
01616     }
01617 
01618   return TRUE;
01619 }
01620 
01621 /* Write out debugging information using accumulated linker
01622    information.  */
01623 
01624 bfd_boolean
01625 bfd_ecoff_write_accumulated_debug (handle, abfd, debug, swap, info, where)
01626      PTR handle;
01627      bfd *abfd;
01628      struct ecoff_debug_info *debug;
01629      const struct ecoff_debug_swap *swap;
01630      struct bfd_link_info *info;
01631      file_ptr where;
01632 {
01633   struct accumulate *ainfo = (struct accumulate *) handle;
01634   PTR space = NULL;
01635   bfd_size_type amt;
01636 
01637   if (! ecoff_write_symhdr (abfd, debug, swap, where))
01638     goto error_return;
01639 
01640   amt = ainfo->largest_file_shuffle;
01641   space = (PTR) bfd_malloc (amt);
01642   if (space == NULL && ainfo->largest_file_shuffle != 0)
01643     goto error_return;
01644 
01645   if (! ecoff_write_shuffle (abfd, swap, ainfo->line, space)
01646       || ! ecoff_write_shuffle (abfd, swap, ainfo->pdr, space)
01647       || ! ecoff_write_shuffle (abfd, swap, ainfo->sym, space)
01648       || ! ecoff_write_shuffle (abfd, swap, ainfo->opt, space)
01649       || ! ecoff_write_shuffle (abfd, swap, ainfo->aux, space))
01650     goto error_return;
01651 
01652   /* The string table is written out from the hash table if this is a
01653      final link.  */
01654   if (info->relocatable)
01655     {
01656       BFD_ASSERT (ainfo->ss_hash == (struct string_hash_entry *) NULL);
01657       if (! ecoff_write_shuffle (abfd, swap, ainfo->ss, space))
01658        goto error_return;
01659     }
01660   else
01661     {
01662       unsigned long total;
01663       bfd_byte null;
01664       struct string_hash_entry *sh;
01665 
01666       BFD_ASSERT (ainfo->ss == (struct shuffle *) NULL);
01667       null = 0;
01668       if (bfd_bwrite ((PTR) &null, (bfd_size_type) 1, abfd) != 1)
01669        goto error_return;
01670       total = 1;
01671       BFD_ASSERT (ainfo->ss_hash == NULL || ainfo->ss_hash->val == 1);
01672       for (sh = ainfo->ss_hash;
01673           sh != (struct string_hash_entry *) NULL;
01674           sh = sh->next)
01675        {
01676          size_t len;
01677 
01678          len = strlen (sh->root.string);
01679          amt = len + 1;
01680          if (bfd_bwrite ((PTR) sh->root.string, amt, abfd) != amt)
01681            goto error_return;
01682          total += len + 1;
01683        }
01684 
01685       if ((total & (swap->debug_align - 1)) != 0)
01686        {
01687          unsigned int i;
01688          bfd_byte *s;
01689 
01690          i = swap->debug_align - (total & (swap->debug_align - 1));
01691          s = (bfd_byte *) bfd_zmalloc ((bfd_size_type) i);
01692          if (s == NULL && i != 0)
01693            goto error_return;
01694 
01695          if (bfd_bwrite ((PTR) s, (bfd_size_type) i, abfd) != i)
01696            {
01697              free (s);
01698              goto error_return;
01699            }
01700          free (s);
01701        }
01702     }
01703 
01704   /* The external strings and symbol are not converted over to using
01705      shuffles.  FIXME: They probably should be.  */
01706   amt = debug->symbolic_header.issExtMax;
01707   if (bfd_bwrite (debug->ssext, amt, abfd) != amt)
01708     goto error_return;
01709   if ((debug->symbolic_header.issExtMax & (swap->debug_align - 1)) != 0)
01710     {
01711       unsigned int i;
01712       bfd_byte *s;
01713 
01714       i = (swap->debug_align
01715           - (debug->symbolic_header.issExtMax & (swap->debug_align - 1)));
01716       s = (bfd_byte *) bfd_zmalloc ((bfd_size_type) i);
01717       if (s == NULL && i != 0)
01718        goto error_return;
01719 
01720       if (bfd_bwrite ((PTR) s, (bfd_size_type) i, abfd) != i)
01721        {
01722          free (s);
01723          goto error_return;
01724        }
01725       free (s);
01726     }
01727 
01728   if (! ecoff_write_shuffle (abfd, swap, ainfo->fdr, space)
01729       || ! ecoff_write_shuffle (abfd, swap, ainfo->rfd, space))
01730     goto error_return;
01731 
01732   BFD_ASSERT (debug->symbolic_header.cbExtOffset == 0
01733              || (debug->symbolic_header.cbExtOffset
01734                 == (bfd_vma) bfd_tell (abfd)));
01735 
01736   amt = debug->symbolic_header.iextMax * swap->external_ext_size;
01737   if (bfd_bwrite (debug->external_ext, amt, abfd) != amt)
01738     goto error_return;
01739 
01740   if (space != NULL)
01741     free (space);
01742   return TRUE;
01743 
01744  error_return:
01745   if (space != NULL)
01746     free (space);
01747   return FALSE;
01748 }
01749 
01750 /* Handle the find_nearest_line function for both ECOFF and MIPS ELF
01751    files.  */
01752 
01753 /* Compare FDR entries.  This is called via qsort.  */
01754 
01755 static int
01756 cmp_fdrtab_entry (leftp, rightp)
01757      const PTR leftp;
01758      const PTR rightp;
01759 {
01760   const struct ecoff_fdrtab_entry *lp =
01761     (const struct ecoff_fdrtab_entry *) leftp;
01762   const struct ecoff_fdrtab_entry *rp =
01763     (const struct ecoff_fdrtab_entry *) rightp;
01764 
01765   if (lp->base_addr < rp->base_addr)
01766     return -1;
01767   if (lp->base_addr > rp->base_addr)
01768     return 1;
01769   return 0;
01770 }
01771 
01772 /* Each file descriptor (FDR) has a memory address, to simplify
01773    looking up an FDR by address, we build a table covering all FDRs
01774    that have a least one procedure descriptor in them.  The final
01775    table will be sorted by address so we can look it up via binary
01776    search.  */
01777 
01778 static bfd_boolean
01779 mk_fdrtab (abfd, debug_info, debug_swap, line_info)
01780      bfd *abfd;
01781      struct ecoff_debug_info * const debug_info;
01782      const struct ecoff_debug_swap * const debug_swap;
01783      struct ecoff_find_line *line_info;
01784 {
01785   struct ecoff_fdrtab_entry *tab;
01786   FDR *fdr_ptr;
01787   FDR *fdr_start;
01788   FDR *fdr_end;
01789   bfd_boolean stabs;
01790   long len;
01791   bfd_size_type amt;
01792 
01793   fdr_start = debug_info->fdr;
01794   fdr_end = fdr_start + debug_info->symbolic_header.ifdMax;
01795 
01796   /* First, let's see how long the table needs to be.  */
01797   for (len = 0, fdr_ptr = fdr_start; fdr_ptr < fdr_end; fdr_ptr++)
01798     {
01799       if (fdr_ptr->cpd == 0)       /* Skip FDRs that have no PDRs.  */
01800        continue;
01801       ++len;
01802     }
01803 
01804   /* Now, create and fill in the table.  */
01805   amt = (bfd_size_type) len * sizeof (struct ecoff_fdrtab_entry);
01806   line_info->fdrtab = (struct ecoff_fdrtab_entry*) bfd_zalloc (abfd, amt);
01807   if (line_info->fdrtab == NULL)
01808     return FALSE;
01809   line_info->fdrtab_len = len;
01810 
01811   tab = line_info->fdrtab;
01812   for (fdr_ptr = fdr_start; fdr_ptr < fdr_end; fdr_ptr++)
01813     {
01814       if (fdr_ptr->cpd == 0)
01815        continue;
01816 
01817       /* Check whether this file has stabs debugging information.  In
01818         a file with stabs debugging information, the second local
01819         symbol is named @stabs.  */
01820       stabs = FALSE;
01821       if (fdr_ptr->csym >= 2)
01822        {
01823          char *sym_ptr;
01824          SYMR sym;
01825 
01826          sym_ptr = ((char *) debug_info->external_sym
01827                    + (fdr_ptr->isymBase + 1) * debug_swap->external_sym_size);
01828          (*debug_swap->swap_sym_in) (abfd, sym_ptr, &sym);
01829          if (strcmp (debug_info->ss + fdr_ptr->issBase + sym.iss,
01830                     STABS_SYMBOL) == 0)
01831            stabs = TRUE;
01832        }
01833 
01834       if (!stabs)
01835        {
01836          /* eraxxon: There are at least two problems with this computation:
01837             1) PDRs do *not* contain offsets but full vma's; and typically the
01838             address of the first PDR is the address of the FDR, which will
01839             make (most) of the results of the original computation 0!
01840             2) Once in a wacky while, the Compaq compiler generated PDR
01841             addresses do not equal the FDR vma, but they (the PDR address)
01842             are still vma's and not offsets.  Cf. comments in
01843             'lookup_line'.  */
01844          /* The address of the first PDR is the offset of that
01845             procedure relative to the beginning of file FDR.  */
01846          tab->base_addr = fdr_ptr->adr; 
01847        }
01848       else
01849        {
01850          /* XXX I don't know about stabs, so this is a guess
01851             (davidm@cs.arizona.edu).  */
01852          tab->base_addr = fdr_ptr->adr;
01853        }
01854       tab->fdr = fdr_ptr;
01855       ++tab;
01856     }
01857 
01858   /* Finally, the table is sorted in increasing memory-address order.
01859      The table is mostly sorted already, but there are cases (e.g.,
01860      static functions in include files), where this does not hold.
01861      Use "odump -PFv" to verify...  */
01862   qsort ((PTR) line_info->fdrtab, (size_t) len,
01863         sizeof (struct ecoff_fdrtab_entry), cmp_fdrtab_entry);
01864 
01865   return TRUE;
01866 }
01867 
01868 /* Return index of first FDR that covers to OFFSET.  */
01869 
01870 static long
01871 fdrtab_lookup (line_info, offset)
01872      struct ecoff_find_line *line_info;
01873      bfd_vma offset;
01874 {
01875   long low, high, len;
01876   long mid = -1;
01877   struct ecoff_fdrtab_entry *tab;
01878 
01879   len = line_info->fdrtab_len;
01880   if (len == 0)
01881     return -1;
01882 
01883   tab = line_info->fdrtab;
01884   for (low = 0, high = len - 1 ; low != high ;)
01885     {
01886       mid = (high + low) / 2;
01887       if (offset >= tab[mid].base_addr && offset < tab[mid + 1].base_addr)
01888        goto find_min;
01889 
01890       if (tab[mid].base_addr > offset)
01891        high = mid;
01892       else
01893        low = mid + 1;
01894     }
01895 
01896   /* eraxxon: at this point 'offset' is either lower than the lowest entry or
01897      higher than the highest entry. In the former case high = low = mid = 0;
01898      we want to return -1.  In the latter case, low = high and mid = low - 1;
01899      we want to return the index of the highest entry.  Only in former case
01900      will the following 'catch-all' test be true.  */
01901   ++mid;
01902 
01903   /* Last entry is catch-all for all higher addresses.  */
01904   if (offset < tab[mid].base_addr)
01905     return -1;
01906 
01907  find_min:
01908 
01909   /* eraxxon: There may be multiple FDRs in the table with the
01910      same base_addr; make sure that we are at the first one.  */
01911   while (mid > 0 && tab[mid - 1].base_addr == tab[mid].base_addr)
01912     --mid;
01913 
01914   return mid;
01915 }
01916 
01917 /* Look up a line given an address, storing the information in
01918    LINE_INFO->cache.  */
01919 
01920 static bfd_boolean
01921 lookup_line (abfd, debug_info, debug_swap, line_info)
01922      bfd *abfd;
01923      struct ecoff_debug_info * const debug_info;
01924      const struct ecoff_debug_swap * const debug_swap;
01925      struct ecoff_find_line *line_info;
01926 {
01927   struct ecoff_fdrtab_entry *tab;
01928   bfd_vma offset;
01929   bfd_boolean stabs;
01930   FDR *fdr_ptr;
01931   int i;
01932 
01933   /* eraxxon: note that 'offset' is the full vma, not a section offset.  */
01934   offset = line_info->cache.start;
01935 
01936   /* Build FDR table (sorted by object file's base-address) if we
01937      don't have it already.  */
01938   if (line_info->fdrtab == NULL
01939       && !mk_fdrtab (abfd, debug_info, debug_swap, line_info))
01940     return FALSE;
01941 
01942   tab = line_info->fdrtab;
01943 
01944   /* Find first FDR for address OFFSET.  */
01945   i = fdrtab_lookup (line_info, offset);
01946   if (i < 0)
01947     return FALSE;           /* no FDR, no fun...  */
01948   
01949   /* eraxxon: 'fdrtab_lookup' doesn't give what we want, at least for Compaq's
01950      C++ compiler 6.2.  Consider three FDRs with starting addresses of x, y,
01951      and z, respectively, such that x < y < z.  Assume further that
01952      y < 'offset' < z.  It is possible at times that the PDR for 'offset' is
01953      associated with FDR x and *not* with FDR y.  Erg!!
01954 
01955      From a binary dump of my C++ test case 'moo' using Compaq's coffobjanl
01956      (output format has been edited for our purposes):
01957 
01958      FDR [2]: (main.C): First instruction: 0x12000207c <x>
01959        PDR [5] for File [2]: LoopTest__Xv                 <0x1200020a0> (a)
01960        PDR [7] for File [2]: foo__Xv                      <0x120002168>
01961      FDR [1]: (-1):     First instruction: 0x1200020e8 <y>
01962        PDR [3] for File [1]:                              <0x120001ad0> (b)
01963      FDR [6]: (-1):     First instruction: 0x1200026f0 <z>
01964 
01965      (a) In the case of PDR5, the vma is such that the first few instructions
01966      of the procedure can be found.  But since the size of this procedure is
01967      160b, the vma will soon cross into the 'address space' of FDR1 and no
01968      debugging info will be found.  How repugnant!
01969 
01970      (b) It is also possible for a PDR to have a *lower* vma than its associated
01971      FDR; see FDR1 and PDR3.  Gross!
01972 
01973      Since the FDRs that are causing so much havok (in this case) 1) do not
01974      describe actual files (fdr.rss == -1), and 2) contain only compiler
01975      generated routines, I thought a simple fix would be to exclude them from
01976      the FDR table in 'mk_fdrtab'.  But, besides not knowing for certain
01977      whether this would be correct, it creates an additional problem.  If we
01978      happen to ask for source file info on a compiler generated (procedure)
01979      symbol -- which is still in the symbol table -- the result can be
01980      information from a real procedure!  This is because compiler generated
01981      procedures with vma's higher than the last FDR in the fdr table will be
01982      associated with a PDR from this FDR, specifically the PDR with the
01983      highest vma.  This wasn't a problem before, because each procedure had a
01984      PDR.  (Yes, this problem could be eliminated if we kept the size of the
01985      last PDR around, but things are already getting ugly).
01986 
01987      Probably, a better solution would be to have a sorted PDR table.  Each
01988      PDR would have a pointer to its FDR so file information could still be
01989      obtained.  A FDR table could still be constructed if necessary -- since
01990      it only contains pointers, not much extra memory would be used -- but
01991      the PDR table would be searched to locate debugging info.
01992 
01993      There is still at least one remaining issue.  Sometimes a FDR can have a
01994      bogus name, but contain PDRs that should belong to another FDR with a
01995      real name.  E.g:
01996 
01997      FDR [3]: 0000000120001b50 (/home/.../Array.H~alt~deccxx_5E5A62AD)
01998        PDR [a] for File [3]: 0000000120001b50
01999        PDR [b] for File [3]: 0000000120001cf0
02000        PDR [c] for File [3]: 0000000120001dc8
02001        PDR [d] for File [3]: 0000000120001e40
02002        PDR [e] for File [3]: 0000000120001eb8
02003        PDR [f] for File [3]: 0000000120001f4c
02004      FDR [4]: 0000000120001b50 (/home/.../Array.H)
02005 
02006      Here, FDR4 has the correct name, but should (seemingly) contain PDRa-f.
02007      The symbol table for PDR4 does contain symbols for PDRa-f, but so does
02008      the symbol table for FDR3.  However the former is different; perhaps this
02009      can be detected easily. (I'm not sure at this point.)  This problem only
02010      seems to be associated with files with templates.  I am assuming the idea
02011      is that there is a 'fake' FDR (with PDRs) for each differently typed set
02012      of templates that must be generated.  Currently, FDR4 is completely
02013      excluded from the FDR table in 'mk_fdrtab' because it contains no PDRs.
02014 
02015      Since I don't have time to prepare a real fix for this right now, be
02016      prepared for 'A Horrible Hack' to force the inspection of all non-stabs
02017      FDRs.  It's coming...  */
02018   fdr_ptr = tab[i].fdr;
02019 
02020   /* Check whether this file has stabs debugging information.  In a
02021      file with stabs debugging information, the second local symbol is
02022      named @stabs.  */
02023   stabs = FALSE;
02024   if (fdr_ptr->csym >= 2)
02025     {
02026       char *sym_ptr;
02027       SYMR sym;
02028 
02029       sym_ptr = ((char *) debug_info->external_sym
02030                + (fdr_ptr->isymBase + 1) * debug_swap->external_sym_size);
02031       (*debug_swap->swap_sym_in) (abfd, sym_ptr, &sym);
02032       if (strcmp (debug_info->ss + fdr_ptr->issBase + sym.iss,
02033                 STABS_SYMBOL) == 0)
02034        stabs = TRUE;
02035     }
02036 
02037   if (!stabs)
02038     {
02039       bfd_size_type external_pdr_size;
02040       char *pdr_ptr;
02041       char *best_pdr = NULL;
02042       FDR *best_fdr;
02043       bfd_signed_vma best_dist = -1;
02044       PDR pdr;
02045       unsigned char *line_ptr;
02046       unsigned char *line_end;
02047       int lineno;
02048       /* This file uses ECOFF debugging information.  Each FDR has a
02049          list of procedure descriptors (PDR).  The address in the FDR
02050          is the absolute address of the first procedure.  The address
02051          in the first PDR gives the offset of that procedure relative
02052          to the object file's base-address.  The addresses in
02053          subsequent PDRs specify each procedure's address relative to
02054          the object file's base-address.  To make things more juicy,
02055          whenever the PROF bit in the PDR is set, the real entry point
02056          of the procedure may be 16 bytes below what would normally be
02057          the procedure's entry point.  Instead, DEC came up with a
02058          wicked scheme to create profiled libraries "on the fly":
02059          instead of shipping a regular and a profiled version of each
02060          library, they insert 16 bytes of unused space in front of
02061          each procedure and set the "prof" bit in the PDR to indicate
02062          that there is a gap there (this is done automagically by "as"
02063          when option "-pg" is specified).  Thus, normally, you link
02064          against such a library and, except for lots of 16 byte gaps
02065          between functions, things will behave as usual.  However,
02066          when invoking "ld" with option "-pg", it will fill those gaps
02067          with code that calls mcount().  It then moves the function's
02068          entry point down by 16 bytes, and out pops a binary that has
02069          all functions profiled.
02070 
02071          NOTE: Neither FDRs nor PDRs are strictly sorted in memory
02072                order.  For example, when including header-files that
02073                define functions, the FDRs follow behind the including
02074                file, even though their code may have been generated at
02075                a lower address.  File coff-alpha.c from libbfd
02076                illustrates this (use "odump -PFv" to look at a file's
02077                FDR/PDR).  Similarly, PDRs are sometimes out of order
02078                as well.  An example of this is OSF/1 v3.0 libc's
02079                malloc.c.  I'm not sure why this happens, but it could
02080                be due to optimizations that reorder a function's
02081                position within an object-file.
02082 
02083          Strategy:
02084 
02085          On the first call to this function, we build a table of FDRs
02086          that is sorted by the base-address of the object-file the FDR
02087          is referring to.  Notice that each object-file may contain
02088          code from multiple source files (e.g., due to code defined in
02089          include files).  Thus, for any given base-address, there may
02090          be multiple FDRs (but this case is, fortunately, uncommon).
02091          lookup(addr) guarantees to return the first FDR that applies
02092          to address ADDR.  Thus, after invoking lookup(), we have a
02093          list of FDRs that may contain the PDR for ADDR.  Next, we
02094          walk through the PDRs of these FDRs and locate the one that
02095          is closest to ADDR (i.e., for which the difference between
02096          ADDR and the PDR's entry point is positive and minimal).
02097          Once, the right FDR and PDR are located, we simply walk
02098          through the line-number table to lookup the line-number that
02099          best matches ADDR.  Obviously, things could be sped up by
02100          keeping a sorted list of PDRs instead of a sorted list of
02101          FDRs.  However, this would increase space requirements
02102          considerably, which is undesirable.  */
02103       external_pdr_size = debug_swap->external_pdr_size;
02104 
02105       /* eraxxon: The Horrible Hack: Because of the problems above, set 'i'
02106         to 0 so we look through all FDRs.
02107 
02108         Because FDR's without any symbols are assumed to be non-stabs,
02109         searching through all FDRs may cause the following code to try to
02110         read stabs FDRs as ECOFF ones.  However, I don't think this will
02111         harm anything.  */
02112       i = 0;
02113       
02114       /* Search FDR list starting at tab[i] for the PDR that best matches
02115          OFFSET.  Normally, the FDR list is only one entry long.  */
02116       best_fdr = NULL;
02117       do
02118        {
02119          /* eraxxon: 'dist' and 'min_dist' can be negative now
02120              because we iterate over every FDR rather than just ones
02121              with a base address less than or equal to 'offset'.  */
02122          bfd_signed_vma dist = -1, min_dist = -1;
02123          char *pdr_hold;
02124          char *pdr_end;
02125 
02126          fdr_ptr = tab[i].fdr;
02127 
02128          pdr_ptr = ((char *) debug_info->external_pdr
02129                    + fdr_ptr->ipdFirst * external_pdr_size);
02130          pdr_end = pdr_ptr + fdr_ptr->cpd * external_pdr_size;
02131          (*debug_swap->swap_pdr_in) (abfd, (PTR) pdr_ptr, &pdr);
02132          /* Find PDR that is closest to OFFSET.  If pdr.prof is set,
02133             the procedure entry-point *may* be 0x10 below pdr.adr.  We
02134             simply pretend that pdr.prof *implies* a lower entry-point.
02135             This is safe because it just means that may identify 4 NOPs
02136             in front of the function as belonging to the function.  */
02137          for (pdr_hold = NULL;
02138               pdr_ptr < pdr_end;
02139               (pdr_ptr += external_pdr_size,
02140               (*debug_swap->swap_pdr_in) (abfd, (PTR) pdr_ptr, &pdr)))
02141            {
02142              if (offset >= (pdr.adr - 0x10 * pdr.prof))
02143               {
02144                 dist = offset - (pdr.adr - 0x10 * pdr.prof);
02145 
02146                 /* eraxxon: 'dist' can be negative now.  Note that
02147                      'min_dist' can be negative if 'pdr_hold' below is NULL.  */
02148                 if (!pdr_hold || (dist >= 0 && dist < min_dist))
02149                   {
02150                     min_dist = dist;
02151                     pdr_hold = pdr_ptr;
02152                   }
02153               }
02154            }
02155 
02156          if (!best_pdr || (min_dist >= 0 && min_dist < best_dist))
02157            {
02158              best_dist = (bfd_vma) min_dist;  
02159              best_fdr = fdr_ptr;
02160              best_pdr = pdr_hold;
02161            }
02162          /* Continue looping until base_addr of next entry is different.  */
02163        }
02164       /* eraxxon: We want to iterate over all FDRs.
02165         See previous comment about 'fdrtab_lookup'.  */
02166       while (++i < line_info->fdrtab_len);
02167 
02168       if (!best_fdr || !best_pdr)
02169        return FALSE;               /* Shouldn't happen...  */
02170 
02171       /* Phew, finally we got something that we can hold onto.  */
02172       fdr_ptr = best_fdr;
02173       pdr_ptr = best_pdr;
02174       (*debug_swap->swap_pdr_in) (abfd, (PTR) pdr_ptr, &pdr);
02175       /* Now we can look for the actual line number.  The line numbers
02176          are stored in a very funky format, which I won't try to
02177          describe.  The search is bounded by the end of the FDRs line
02178          number entries.  */
02179       line_end = debug_info->line + fdr_ptr->cbLineOffset + fdr_ptr->cbLine;
02180 
02181       /* Make offset relative to procedure entry.  */
02182       offset -= pdr.adr - 0x10 * pdr.prof;
02183       lineno = pdr.lnLow;
02184       line_ptr = debug_info->line + fdr_ptr->cbLineOffset + pdr.cbLineOffset;
02185       while (line_ptr < line_end)
02186        {
02187          int delta;
02188          unsigned int count;
02189 
02190          delta = *line_ptr >> 4;
02191          if (delta >= 0x8)
02192            delta -= 0x10;
02193          count = (*line_ptr & 0xf) + 1;
02194          ++line_ptr;
02195          if (delta == -8)
02196            {
02197              delta = (((line_ptr[0]) & 0xff) << 8) + ((line_ptr[1]) & 0xff);
02198              if (delta >= 0x8000)
02199               delta -= 0x10000;
02200              line_ptr += 2;
02201            }
02202          lineno += delta;
02203          if (offset < count * 4)
02204            {
02205              line_info->cache.stop += count * 4 - offset;
02206              break;
02207            }
02208          offset -= count * 4;
02209        }
02210 
02211       /* If fdr_ptr->rss is -1, then this file does not have full
02212          symbols, at least according to gdb/mipsread.c.  */
02213       if (fdr_ptr->rss == -1)
02214        {
02215          line_info->cache.filename = NULL;
02216          if (pdr.isym == -1)
02217            line_info->cache.functionname = NULL;
02218          else
02219            {
02220              EXTR proc_ext;
02221 
02222              (*debug_swap->swap_ext_in)
02223               (abfd,
02224                ((char *) debug_info->external_ext
02225                 + pdr.isym * debug_swap->external_ext_size),
02226                &proc_ext);
02227              line_info->cache.functionname = (debug_info->ssext
02228                                           + proc_ext.asym.iss);
02229            }
02230        }
02231       else
02232        {
02233          SYMR proc_sym;
02234 
02235          line_info->cache.filename = (debug_info->ss
02236                                    + fdr_ptr->issBase
02237                                    + fdr_ptr->rss);
02238          (*debug_swap->swap_sym_in)
02239            (abfd,
02240             ((char *) debug_info->external_sym
02241              + ((fdr_ptr->isymBase + pdr.isym)
02242                * debug_swap->external_sym_size)),
02243             &proc_sym);
02244          line_info->cache.functionname = (debug_info->ss
02245                                       + fdr_ptr->issBase
02246                                       + proc_sym.iss);
02247        }
02248       if (lineno == ilineNil)
02249        lineno = 0;
02250       line_info->cache.line_num = lineno;
02251     }
02252   else
02253     {
02254       bfd_size_type external_sym_size;
02255       const char *directory_name;
02256       const char *main_file_name;
02257       const char *current_file_name;
02258       const char *function_name;
02259       const char *line_file_name;
02260       bfd_vma low_func_vma;
02261       bfd_vma low_line_vma;
02262       bfd_boolean past_line;
02263       bfd_boolean past_fn;
02264       char *sym_ptr, *sym_ptr_end;
02265       size_t len, funclen;
02266       char *buffer = NULL;
02267 
02268       /* This file uses stabs debugging information.  When gcc is not
02269         optimizing, it will put the line number information before
02270         the function name stabs entry.  When gcc is optimizing, it
02271         will put the stabs entry for all the function first, followed
02272         by the line number information.  (This appears to happen
02273         because of the two output files used by the -mgpopt switch,
02274         which is implied by -O).  This means that we must keep
02275         looking through the symbols until we find both a line number
02276         and a function name which are beyond the address we want.  */
02277 
02278       line_info->cache.filename = NULL;
02279       line_info->cache.functionname = NULL;
02280       line_info->cache.line_num = 0;
02281 
02282       directory_name = NULL;
02283       main_file_name = NULL;
02284       current_file_name = NULL;
02285       function_name = NULL;
02286       line_file_name = NULL;
02287       low_func_vma = 0;
02288       low_line_vma = 0;
02289       past_line = FALSE;
02290       past_fn = FALSE;
02291 
02292       external_sym_size = debug_swap->external_sym_size;
02293 
02294       sym_ptr = ((char *) debug_info->external_sym
02295                + (fdr_ptr->isymBase + 2) * external_sym_size);
02296       sym_ptr_end = sym_ptr + (fdr_ptr->csym - 2) * external_sym_size;
02297       for (;
02298           sym_ptr < sym_ptr_end && (! past_line || ! past_fn);
02299           sym_ptr += external_sym_size)
02300        {
02301          SYMR sym;
02302 
02303          (*debug_swap->swap_sym_in) (abfd, sym_ptr, &sym);
02304 
02305          if (ECOFF_IS_STAB (&sym))
02306            {
02307              switch (ECOFF_UNMARK_STAB (sym.index))
02308               {
02309               case N_SO:
02310                 main_file_name = current_file_name =
02311                   debug_info->ss + fdr_ptr->issBase + sym.iss;
02312 
02313                 /* Check the next symbol to see if it is also an
02314                      N_SO symbol.  */
02315                 if (sym_ptr + external_sym_size < sym_ptr_end)
02316                   {
02317                     SYMR nextsym;
02318 
02319                     (*debug_swap->swap_sym_in) (abfd,
02320                                             sym_ptr + external_sym_size,
02321                                             &nextsym);
02322                     if (ECOFF_IS_STAB (&nextsym)
02323                        && ECOFF_UNMARK_STAB (nextsym.index) == N_SO)
02324                      {
02325                        directory_name = current_file_name;
02326                        main_file_name = current_file_name =
02327                          debug_info->ss + fdr_ptr->issBase + nextsym.iss;
02328                        sym_ptr += external_sym_size;
02329                      }
02330                   }
02331                 break;
02332 
02333               case N_SOL:
02334                 current_file_name =
02335                   debug_info->ss + fdr_ptr->issBase + sym.iss;
02336                 break;
02337 
02338               case N_FUN:
02339                 if (sym.value > offset)
02340                   past_fn = TRUE;
02341                 else if (sym.value >= low_func_vma)
02342                   {
02343                     low_func_vma = sym.value;
02344                     function_name =
02345                      debug_info->ss + fdr_ptr->issBase + sym.iss;
02346                   }
02347                 break;
02348               }
02349            }
02350          else if (sym.st == stLabel && sym.index != indexNil)
02351            {
02352              if (sym.value > offset)
02353               past_line = TRUE;
02354              else if (sym.value >= low_line_vma)
02355               {
02356                 low_line_vma = sym.value;
02357                 line_file_name = current_file_name;
02358                 line_info->cache.line_num = sym.index;
02359               }
02360            }
02361        }
02362 
02363       if (line_info->cache.line_num != 0)
02364        main_file_name = line_file_name;
02365 
02366       /* We need to remove the stuff after the colon in the function
02367          name.  We also need to put the directory name and the file
02368          name together.  */
02369       if (function_name == NULL)
02370        len = funclen = 0;
02371       else
02372        len = funclen = strlen (function_name) + 1;
02373 
02374       if (main_file_name != NULL
02375          && directory_name != NULL
02376          && main_file_name[0] != '/')
02377        len += strlen (directory_name) + strlen (main_file_name) + 1;
02378 
02379       if (len != 0)
02380        {
02381          if (line_info->find_buffer != NULL)
02382            free (line_info->find_buffer);
02383          buffer = (char *) bfd_malloc ((bfd_size_type) len);
02384          if (buffer == NULL)
02385            return FALSE;
02386          line_info->find_buffer = buffer;
02387        }
02388 
02389       if (function_name != NULL)
02390        {
02391          char *colon;
02392 
02393          strcpy (buffer, function_name);
02394          colon = strchr (buffer, ':');
02395          if (colon != NULL)
02396            *colon = '\0';
02397          line_info->cache.functionname = buffer;
02398        }
02399 
02400       if (main_file_name != NULL)
02401        {
02402          if (directory_name == NULL || main_file_name[0] == '/')
02403            line_info->cache.filename = main_file_name;
02404          else
02405            {
02406              sprintf (buffer + funclen, "%s%s", directory_name,
02407                      main_file_name);
02408              line_info->cache.filename = buffer + funclen;
02409            }
02410        }
02411     }
02412 
02413   return TRUE;
02414 }
02415 
02416 /* Do the work of find_nearest_line.  */
02417 
02418 bfd_boolean
02419 _bfd_ecoff_locate_line (abfd, section, offset, debug_info, debug_swap,
02420                      line_info, filename_ptr, functionname_ptr, retline_ptr)
02421      bfd *abfd;
02422      asection *section;
02423      bfd_vma offset;
02424      struct ecoff_debug_info * const debug_info;
02425      const struct ecoff_debug_swap * const debug_swap;
02426      struct ecoff_find_line *line_info;
02427      const char **filename_ptr;
02428      const char **functionname_ptr;
02429      unsigned int *retline_ptr;
02430 {
02431   offset += section->vma;
02432 
02433   if (line_info->cache.sect == NULL
02434       || line_info->cache.sect != section
02435       || offset < line_info->cache.start
02436       || offset >= line_info->cache.stop)
02437     {
02438       line_info->cache.sect = section;
02439       line_info->cache.start = offset;
02440       line_info->cache.stop = offset;
02441       if (! lookup_line (abfd, debug_info, debug_swap, line_info))
02442        {
02443          line_info->cache.sect = NULL;
02444          return FALSE;
02445        }
02446     }
02447 
02448   *filename_ptr = line_info->cache.filename;
02449   *functionname_ptr = line_info->cache.functionname;
02450   *retline_ptr = line_info->cache.line_num;
02451 
02452   return TRUE;
02453 }
02454 
02455 /* These routines copy symbolic information into a memory buffer.
02456 
02457    FIXME: The whole point of the shuffle code is to avoid storing
02458    everything in memory, since the linker is such a memory hog.  This
02459    code makes that effort useless.  It is only called by the MIPS ELF
02460    code when generating a shared library, so it is not that big a
02461    deal, but it should be fixed eventually.  */
02462 
02463 /* Collect a shuffle into a memory buffer.  */
02464 
02465 static bfd_boolean ecoff_collect_shuffle
02466   PARAMS ((struct shuffle *, bfd_byte *));
02467 
02468 static bfd_boolean
02469 ecoff_collect_shuffle (l, buff)
02470      struct shuffle *l;
02471      bfd_byte *buff;
02472 {
02473   unsigned long total;
02474 
02475   total = 0;
02476   for (; l != (struct shuffle *) NULL; l = l->next)
02477     {
02478       if (! l->filep)
02479        memcpy (buff, l->u.memory, l->size);
02480       else
02481        {
02482          if (bfd_seek (l->u.file.input_bfd, l->u.file.offset, SEEK_SET) != 0
02483              || (bfd_bread (buff, (bfd_size_type) l->size, l->u.file.input_bfd)
02484                 != l->size))
02485            return FALSE;
02486        }
02487       total += l->size;
02488       buff += l->size;
02489     }
02490 
02491   return TRUE;
02492 }
02493 
02494 /* Copy PDR information into a memory buffer.  */
02495 
02496 bfd_boolean
02497 _bfd_ecoff_get_accumulated_pdr (handle, buff)
02498      PTR handle;
02499      bfd_byte *buff;
02500 {
02501   struct accumulate *ainfo = (struct accumulate *) handle;
02502 
02503   return ecoff_collect_shuffle (ainfo->pdr, buff);
02504 }
02505 
02506 /* Copy symbol information into a memory buffer.  */
02507 
02508 bfd_boolean
02509 _bfd_ecoff_get_accumulated_sym (handle, buff)
02510      PTR handle;
02511      bfd_byte *buff;
02512 {
02513   struct accumulate *ainfo = (struct accumulate *) handle;
02514 
02515   return ecoff_collect_shuffle (ainfo->sym, buff);
02516 }
02517 
02518 /* Copy the string table into a memory buffer.  */
02519 
02520 bfd_boolean
02521 _bfd_ecoff_get_accumulated_ss (handle, buff)
02522      PTR handle;
02523      bfd_byte *buff;
02524 {
02525   struct accumulate *ainfo = (struct accumulate *) handle;
02526   struct string_hash_entry *sh;
02527   unsigned long total;
02528 
02529   /* The string table is written out from the hash table if this is a
02530      final link.  */
02531   BFD_ASSERT (ainfo->ss == (struct shuffle *) NULL);
02532   *buff++ = '\0';
02533   total = 1;
02534   BFD_ASSERT (ainfo->ss_hash == NULL || ainfo->ss_hash->val == 1);
02535   for (sh = ainfo->ss_hash;
02536        sh != (struct string_hash_entry *) NULL;
02537        sh = sh->next)
02538     {
02539       size_t len;
02540 
02541       len = strlen (sh->root.string);
02542       memcpy (buff, (PTR) sh->root.string, len + 1);
02543       total += len + 1;
02544       buff += len + 1;
02545     }
02546 
02547   return TRUE;
02548 }