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