/[gcl]/gcl/binutils/bfd/stabs.c
ViewVC logotype

Diff of /gcl/binutils/bfd/stabs.c

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

revision 1.1.1.1 by camm, Fri Aug 9 05:35:47 2002 UTC revision 1.2 by camm, Fri Sep 9 23:32:15 2005 UTC
# Line 1  Line 1 
1  /* Stabs in sections linking support.  /* Stabs in sections linking support.
2     Copyright 1996, 1997, 1998, 1999, 2000, 2001     Copyright 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004
3     Free Software Foundation, Inc.     Free Software Foundation, Inc.
4     Written by Ian Lance Taylor, Cygnus Support.     Written by Ian Lance Taylor, Cygnus Support.
5    
6  This file is part of BFD, the Binary File Descriptor library.     This file is part of BFD, the Binary File Descriptor library.
7    
8  This program is free software; you can redistribute it and/or modify     This program is free software; you can redistribute it and/or modify
9  it under the terms of the GNU General Public License as published by     it under the terms of the GNU General Public License as published by
10  the Free Software Foundation; either version 2 of the License, or     the Free Software Foundation; either version 2 of the License, or
11  (at your option) any later version.     (at your option) any later version.
12    
13  This program is distributed in the hope that it will be useful,     This program is distributed in the hope that it will be useful,
14  but WITHOUT ANY WARRANTY; without even the implied warranty of     but WITHOUT ANY WARRANTY; without even the implied warranty of
15  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16  GNU General Public License for more details.     GNU General Public License for more details.
17    
18  You should have received a copy of the GNU General Public License     You should have received a copy of the GNU General Public License
19  along with this program; if not, write to the Free Software     along with this program; if not, write to the Free Software
20  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */     Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
21    
22  /* This file contains support for linking stabs in sections, as used  /* This file contains support for linking stabs in sections, as used
23     on COFF and ELF.  */     on COFF and ELF.  */
# Line 48  Foundation, Inc., 59 Temple Place - Suit Line 48  Foundation, Inc., 59 Temple Place - Suit
48  #define VALOFF (8)  #define VALOFF (8)
49  #define STABSIZE (12)  #define STABSIZE (12)
50    
 /* A hash table used for header files with N_BINCL entries.  */  
   
 struct stab_link_includes_table  
 {  
   struct bfd_hash_table root;  
 };  
   
51  /* A linked list of totals that we have found for a particular header  /* A linked list of totals that we have found for a particular header
52     file.  */     file.  A total is a unique identifier for a particular BINCL...EINCL
53       sequence of STABs that can be used to identify duplicate sequences.
54       It consists of three fields, 'sum_chars' which is the sum of all the
55       STABS characters; 'num_chars' which is the number of these charactes
56       and 'symb' which is a buffer of all the symbols in the sequence.  This
57       buffer is only checked as a last resort.  */
58    
59  struct stab_link_includes_totals  struct stab_link_includes_totals
60  {  {
61    struct stab_link_includes_totals *next;    struct stab_link_includes_totals *next;
62    bfd_vma total;    bfd_vma sum_chars;  /* Accumulated sum of STABS characters.  */
63      bfd_vma num_chars;  /* Number of STABS characters.  */
64      const char* symb;   /* The STABS characters themselves.  */
65  };  };
66    
67  /* An entry in the header file hash table.  */  /* An entry in the header file hash table.  */
# Line 73  struct stab_link_includes_entry Line 73  struct stab_link_includes_entry
73    struct stab_link_includes_totals *totals;    struct stab_link_includes_totals *totals;
74  };  };
75    
 /* Look up an entry in an the header file hash table.  */  
   
 #define stab_link_includes_lookup(table, string, create, copy) \  
   ((struct stab_link_includes_entry *) \  
    bfd_hash_lookup (&(table)->root, (string), (create), (copy)))  
   
76  /* This structure is used to hold a list of N_BINCL symbols, some of  /* This structure is used to hold a list of N_BINCL symbols, some of
77     which might be converted into N_EXCL symbols.  */     which might be converted into N_EXCL symbols.  */
78    
# Line 117  struct stab_section_info Line 111  struct stab_section_info
111    bfd_size_type stridxs[1];    bfd_size_type stridxs[1];
112  };  };
113    
 /* This structure is used to keep track of stabs in sections  
    information while linking.  */  
   
 struct stab_info  
 {  
   /* A hash table used to hold stabs strings.  */  
   struct bfd_strtab_hash *strings;  
   /* The header file hash table.  */  
   struct stab_link_includes_table includes;  
   /* The first .stabstr section.  */  
   asection *stabstr;  
 };  
   
114  static struct bfd_hash_entry *stab_link_includes_newfunc  static struct bfd_hash_entry *stab_link_includes_newfunc
115    PARAMS ((struct bfd_hash_entry *, struct bfd_hash_table *, const char *));    PARAMS ((struct bfd_hash_entry *, struct bfd_hash_table *, const char *));
116    
# Line 168  stab_link_includes_newfunc (entry, table Line 149  stab_link_includes_newfunc (entry, table
149  /* This function is called for each input file from the add_symbols  /* This function is called for each input file from the add_symbols
150     pass of the linker.  */     pass of the linker.  */
151    
152  boolean  bfd_boolean
153  _bfd_link_section_stabs (abfd, psinfo, stabsec, stabstrsec, psecinfo)  _bfd_link_section_stabs (abfd, sinfo, stabsec, stabstrsec, psecinfo, pstring_offset)
154       bfd *abfd;       bfd *abfd;
155       PTR *psinfo;       struct stab_info *sinfo;
156       asection *stabsec;       asection *stabsec;
157       asection *stabstrsec;       asection *stabstrsec;
158       PTR *psecinfo;       PTR *psecinfo;
159         bfd_size_type *pstring_offset;
160  {  {
161    boolean first;    bfd_boolean first;
   struct stab_info *sinfo;  
162    bfd_size_type count, amt;    bfd_size_type count, amt;
163    struct stab_section_info *secinfo;    struct stab_section_info *secinfo;
164    bfd_byte *stabbuf = NULL;    bfd_byte *stabbuf = NULL;
# Line 186  _bfd_link_section_stabs (abfd, psinfo, s Line 167  _bfd_link_section_stabs (abfd, psinfo, s
167    bfd_size_type stroff, next_stroff, skip;    bfd_size_type stroff, next_stroff, skip;
168    bfd_size_type *pstridx;    bfd_size_type *pstridx;
169    
170    if (stabsec->_raw_size == 0    if (stabsec->size == 0
171        || stabstrsec->_raw_size == 0)        || stabstrsec->size == 0)
172      {      {
173        /* This file does not contain stabs debugging information.  */        /* This file does not contain stabs debugging information.  */
174        return true;        return TRUE;
175      }      }
176    
177    if (stabsec->_raw_size % STABSIZE != 0)    if (stabsec->size % STABSIZE != 0)
178      {      {
179        /* Something is wrong with the format of these stab symbols.        /* Something is wrong with the format of these stab symbols.
180           Don't try to optimize them.  */           Don't try to optimize them.  */
181        return true;        return TRUE;
182      }      }
183    
184    if ((stabstrsec->flags & SEC_RELOC) != 0)    if ((stabstrsec->flags & SEC_RELOC) != 0)
185      {      {
186        /* We shouldn't see relocations in the strings, and we aren't        /* We shouldn't see relocations in the strings, and we aren't
187           prepared to handle them.  */           prepared to handle them.  */
188        return true;        return TRUE;
189      }      }
190    
191    if ((stabsec->output_section != NULL    if ((stabsec->output_section != NULL
# Line 213  _bfd_link_section_stabs (abfd, psinfo, s Line 194  _bfd_link_section_stabs (abfd, psinfo, s
194            && bfd_is_abs_section (stabstrsec->output_section)))            && bfd_is_abs_section (stabstrsec->output_section)))
195      {      {
196        /* At least one of the sections is being discarded from the        /* At least one of the sections is being discarded from the
197           link, so we should just ignore them.  */           link, so we should just ignore them.  */
198        return true;        return TRUE;
199      }      }
200    
201    first = false;    first = FALSE;
202    
203    if (*psinfo == NULL)    if (sinfo->stabstr == NULL)
204      {      {
205        /* Initialize the stabs information we need to keep track of.  */        /* Initialize the stabs information we need to keep track of.  */
206        first = true;        first = TRUE;
       amt = sizeof (struct stab_info);  
       *psinfo = (PTR) bfd_alloc (abfd, amt);  
       if (*psinfo == NULL)  
         goto error_return;  
       sinfo = (struct stab_info *) *psinfo;  
207        sinfo->strings = _bfd_stringtab_init ();        sinfo->strings = _bfd_stringtab_init ();
208        if (sinfo->strings == NULL)        if (sinfo->strings == NULL)
209          goto error_return;          goto error_return;
210        /* Make sure the first byte is zero.  */        /* Make sure the first byte is zero.  */
211        (void) _bfd_stringtab_add (sinfo->strings, "", true, true);        (void) _bfd_stringtab_add (sinfo->strings, "", TRUE, TRUE);
212        if (! bfd_hash_table_init_n (&sinfo->includes.root,        if (! bfd_hash_table_init_n (&sinfo->includes,
213                                     stab_link_includes_newfunc,                                     stab_link_includes_newfunc,
214                                     251))                                     251))
215          goto error_return;          goto error_return;
216        sinfo->stabstr = bfd_make_section_anyway (abfd, ".stabstr");        sinfo->stabstr = bfd_make_section_anyway (abfd, ".stabstr");
217        sinfo->stabstr->flags |= SEC_HAS_CONTENTS | SEC_READONLY | SEC_DEBUGGING;        if (sinfo->stabstr == NULL)
218            goto error_return;
219          sinfo->stabstr->flags |= (SEC_HAS_CONTENTS | SEC_READONLY
220                                    | SEC_DEBUGGING | SEC_LINKER_CREATED);
221      }      }
222    
   sinfo = (struct stab_info *) *psinfo;  
   
223    /* Initialize the information we are going to store for this .stab    /* Initialize the information we are going to store for this .stab
224       section.  */       section.  */
225    
226    count = stabsec->_raw_size / STABSIZE;    count = stabsec->size / STABSIZE;
227    
228    amt = sizeof (struct stab_section_info);    amt = sizeof (struct stab_section_info);
229    amt += (count - 1) * sizeof (bfd_size_type);    amt += (count - 1) * sizeof (bfd_size_type);
# Line 256  _bfd_link_section_stabs (abfd, psinfo, s Line 233  _bfd_link_section_stabs (abfd, psinfo, s
233    
234    secinfo = (struct stab_section_info *) *psecinfo;    secinfo = (struct stab_section_info *) *psecinfo;
235    secinfo->excls = NULL;    secinfo->excls = NULL;
236      stabsec->rawsize = stabsec->size;
237    secinfo->cumulative_skips = NULL;    secinfo->cumulative_skips = NULL;
238    memset (secinfo->stridxs, 0, (size_t) count * sizeof (bfd_size_type));    memset (secinfo->stridxs, 0, (size_t) count * sizeof (bfd_size_type));
239    
240    /* Read the stabs information from abfd.  */    /* Read the stabs information from abfd.  */
241    
242    stabbuf = (bfd_byte *) bfd_malloc (stabsec->_raw_size);    if (!bfd_malloc_and_get_section (abfd, stabsec, &stabbuf)
243    stabstrbuf = (bfd_byte *) bfd_malloc (stabstrsec->_raw_size);        || !bfd_malloc_and_get_section (abfd, stabstrsec, &stabstrbuf))
   if (stabbuf == NULL || stabstrbuf == NULL)  
     goto error_return;  
   
   if (! bfd_get_section_contents (abfd, stabsec, stabbuf, (bfd_vma) 0,  
                                   stabsec->_raw_size)  
       || ! bfd_get_section_contents (abfd, stabstrsec, stabstrbuf, (bfd_vma) 0,  
                                      stabstrsec->_raw_size))  
244      goto error_return;      goto error_return;
245    
246    /* Look through the stabs symbols, work out the new string indices,    /* Look through the stabs symbols, work out the new string indices,
247       and identify N_BINCL symbols which can be eliminated.  */       and identify N_BINCL symbols which can be eliminated.  */
248    
249    stroff = 0;    stroff = 0;
250    next_stroff = 0;    /* The stabs sections can be split when
251         -split-by-reloc/-split-by-file is used.  We must keep track of
252         each stab section's place in the single concatenated string
253         table.  */
254      next_stroff = pstring_offset ? *pstring_offset : 0;
255    skip = 0;    skip = 0;
256    
257    symend = stabbuf + stabsec->_raw_size;    symend = stabbuf + stabsec->size;
258    for (sym = stabbuf, pstridx = secinfo->stridxs;    for (sym = stabbuf, pstridx = secinfo->stridxs;
259         sym < symend;         sym < symend;
260         sym += STABSIZE, ++pstridx)         sym += STABSIZE, ++pstridx)
# Line 299  _bfd_link_section_stabs (abfd, psinfo, s Line 274  _bfd_link_section_stabs (abfd, psinfo, s
274        if (type == 0)        if (type == 0)
275          {          {
276            /* Special type 0 stabs indicate the offset to the next            /* Special type 0 stabs indicate the offset to the next
277               string table.  We only copy the very first one.  */               string table.  We only copy the very first one.  */
278            stroff = next_stroff;            stroff = next_stroff;
279            next_stroff += bfd_get_32 (abfd, sym + 8);            next_stroff += bfd_get_32 (abfd, sym + 8);
280              if (pstring_offset)
281                *pstring_offset = next_stroff;
282            if (! first)            if (! first)
283              {              {
284                *pstridx = (bfd_size_type) -1;                *pstridx = (bfd_size_type) -1;
285                ++skip;                ++skip;
286                continue;                continue;
287              }              }
288            first = false;            first = FALSE;
289          }          }
290    
291        /* Store the string in the hash table, and record the index.  */        /* Store the string in the hash table, and record the index.  */
292        symstroff = stroff + bfd_get_32 (abfd, sym + STRDXOFF);        symstroff = stroff + bfd_get_32 (abfd, sym + STRDXOFF);
293        if (symstroff >= stabstrsec->_raw_size)        if (symstroff >= stabstrsec->size)
294          {          {
295            (*_bfd_error_handler)            (*_bfd_error_handler)
296              (_("%s(%s+0x%lx): Stabs entry has invalid string index."),              (_("%B(%A+0x%lx): Stabs entry has invalid string index."),
297               bfd_archive_filename (abfd),               abfd, stabsec, (long) (sym - stabbuf));
              bfd_get_section_name (abfd, stabsec),  
              (long) (sym - stabbuf));  
298            bfd_set_error (bfd_error_bad_value);            bfd_set_error (bfd_error_bad_value);
299            goto error_return;            goto error_return;
300          }          }
301        string = (char *) stabstrbuf + symstroff;        string = (char *) stabstrbuf + symstroff;
302        *pstridx = _bfd_stringtab_add (sinfo->strings, string, true, true);        *pstridx = _bfd_stringtab_add (sinfo->strings, string, TRUE, TRUE);
303    
304        /* An N_BINCL symbol indicates the start of the stabs entries        /* An N_BINCL symbol indicates the start of the stabs entries
305           for a header file.  We need to scan ahead to the next N_EINCL           for a header file.  We need to scan ahead to the next N_EINCL
306           symbol, ignoring nesting, adding up all the characters in the           symbol, ignoring nesting, adding up all the characters in the
307           symbol names, not including the file numbers in types (the           symbol names, not including the file numbers in types (the
308           first number after an open parenthesis).  */           first number after an open parenthesis).  */
309        if (type == N_BINCL)        if (type == (int) N_BINCL)
310          {          {
311            bfd_vma val;            bfd_vma sum_chars;
312              bfd_vma num_chars;
313              bfd_vma buf_len = 0;
314              char * symb;
315              char * symb_rover;
316            int nest;            int nest;
317            bfd_byte *incl_sym;            bfd_byte * incl_sym;
318            struct stab_link_includes_entry *incl_entry;            struct stab_link_includes_entry * incl_entry;
319            struct stab_link_includes_totals *t;            struct stab_link_includes_totals * t;
320            struct stab_excl_list *ne;            struct stab_excl_list * ne;
321    
322            val = 0;            symb = symb_rover = NULL;
323              sum_chars = num_chars = 0;
324            nest = 0;            nest = 0;
325    
326            for (incl_sym = sym + STABSIZE;            for (incl_sym = sym + STABSIZE;
327                 incl_sym < symend;                 incl_sym < symend;
328                 incl_sym += STABSIZE)                 incl_sym += STABSIZE)
# Line 351  _bfd_link_section_stabs (abfd, psinfo, s Line 332  _bfd_link_section_stabs (abfd, psinfo, s
332                incl_type = incl_sym[TYPEOFF];                incl_type = incl_sym[TYPEOFF];
333                if (incl_type == 0)                if (incl_type == 0)
334                  break;                  break;
335                else if (incl_type == N_EINCL)                else if (incl_type == (int) N_EXCL)
336                    continue;
337                  else if (incl_type == (int) N_EINCL)
338                  {                  {
339                    if (nest == 0)                    if (nest == 0)
340                      break;                      break;
341                    --nest;                    --nest;
342                  }                  }
343                else if (incl_type == N_BINCL)                else if (incl_type == (int) N_BINCL)
344                  ++nest;                  ++nest;
345                else if (nest == 0)                else if (nest == 0)
346                  {                  {
# Line 368  _bfd_link_section_stabs (abfd, psinfo, s Line 351  _bfd_link_section_stabs (abfd, psinfo, s
351                           + bfd_get_32 (abfd, incl_sym + STRDXOFF));                           + bfd_get_32 (abfd, incl_sym + STRDXOFF));
352                    for (; *str != '\0'; str++)                    for (; *str != '\0'; str++)
353                      {                      {
354                        val += *str;                        if (num_chars >= buf_len)
355                            {
356                              buf_len += 32 * 1024;
357                              symb = bfd_realloc (symb, buf_len);
358                              if (symb == NULL)
359                                goto error_return;
360                              symb_rover = symb + num_chars;
361                            }
362                          * symb_rover ++ = * str;
363                          sum_chars += *str;
364                          num_chars ++;
365                        if (*str == '(')                        if (*str == '(')
366                          {                          {
367                            /* Skip the file number.  */                            /* Skip the file number.  */
# Line 381  _bfd_link_section_stabs (abfd, psinfo, s Line 374  _bfd_link_section_stabs (abfd, psinfo, s
374                  }                  }
375              }              }
376    
377              BFD_ASSERT (num_chars == (bfd_vma) (symb_rover - symb));
378    
379            /* If we have already included a header file with the same            /* If we have already included a header file with the same
380               value, then replaced this one with an N_EXCL symbol.  */               value, then replaced this one with an N_EXCL symbol.  */
381            incl_entry = stab_link_includes_lookup (&sinfo->includes, string,            incl_entry = (struct stab_link_includes_entry * )
382                                                    true, true);              bfd_hash_lookup (&sinfo->includes, string, TRUE, TRUE);
383            if (incl_entry == NULL)            if (incl_entry == NULL)
384              goto error_return;              goto error_return;
385    
386            for (t = incl_entry->totals; t != NULL; t = t->next)            for (t = incl_entry->totals; t != NULL; t = t->next)
387              if (t->total == val)              if (t->sum_chars == sum_chars
388                    && t->num_chars == num_chars
389                    && memcmp (t->symb, symb, num_chars) == 0)
390                break;                break;
391    
392            /* Record this symbol, so that we can set the value            /* Record this symbol, so that we can set the value
393               correctly.  */               correctly.  */
394            amt = sizeof *ne;            amt = sizeof *ne;
395            ne = (struct stab_excl_list *) bfd_alloc (abfd, amt);            ne = (struct stab_excl_list *) bfd_alloc (abfd, amt);
396            if (ne == NULL)            if (ne == NULL)
397              goto error_return;              goto error_return;
398            ne->offset = sym - stabbuf;            ne->offset = sym - stabbuf;
399            ne->val = val;            ne->val = sum_chars;
400            ne->type = N_BINCL;            ne->type = (int) N_BINCL;
401            ne->next = secinfo->excls;            ne->next = secinfo->excls;
402            secinfo->excls = ne;            secinfo->excls = ne;
403    
# Line 409  _bfd_link_section_stabs (abfd, psinfo, s Line 406  _bfd_link_section_stabs (abfd, psinfo, s
406                /* This is the first time we have seen this header file                /* This is the first time we have seen this header file
407                   with this set of stabs strings.  */                   with this set of stabs strings.  */
408                t = ((struct stab_link_includes_totals *)                t = ((struct stab_link_includes_totals *)
409                     bfd_hash_allocate (&sinfo->includes.root, sizeof *t));                     bfd_hash_allocate (&sinfo->includes, sizeof *t));
410                if (t == NULL)                if (t == NULL)
411                  goto error_return;                  goto error_return;
412                t->total = val;                t->sum_chars = sum_chars;
413                  t->num_chars = num_chars;
414                  t->symb = bfd_realloc (symb, num_chars); /* Trim data down.  */
415                t->next = incl_entry->totals;                t->next = incl_entry->totals;
416                incl_entry->totals = t;                incl_entry->totals = t;
417              }              }
# Line 422  _bfd_link_section_stabs (abfd, psinfo, s Line 421  _bfd_link_section_stabs (abfd, psinfo, s
421    
422                /* We have seen this header file before.  Tell the final                /* We have seen this header file before.  Tell the final
423                   pass to change the type to N_EXCL.  */                   pass to change the type to N_EXCL.  */
424                ne->type = N_EXCL;                ne->type = (int) N_EXCL;
425    
426                  /* Free off superfluous symbols.  */
427                  free (symb);
428    
429                /* Mark the skipped symbols.  */                /* Mark the skipped symbols.  */
430    
# Line 435  _bfd_link_section_stabs (abfd, psinfo, s Line 437  _bfd_link_section_stabs (abfd, psinfo, s
437    
438                    incl_type = incl_sym[TYPEOFF];                    incl_type = incl_sym[TYPEOFF];
439    
440                    if (incl_type == N_EINCL)                    if (incl_type == (int) N_EINCL)
441                      {                      {
442                        if (nest == 0)                        if (nest == 0)
443                          {                          {
# Line 445  _bfd_link_section_stabs (abfd, psinfo, s Line 447  _bfd_link_section_stabs (abfd, psinfo, s
447                          }                          }
448                        --nest;                        --nest;
449                      }                      }
450                    else if (incl_type == N_BINCL)                    else if (incl_type == (int) N_BINCL)
451                      ++nest;                      ++nest;
452                      else if (incl_type == (int) N_EXCL)
453                        /* Keep existing exclusion marks.  */
454                        continue;  
455                    else if (nest == 0)                    else if (nest == 0)
456                      {                      {
457                        *incl_pstridx = (bfd_size_type) -1;                        *incl_pstridx = (bfd_size_type) -1;
# Line 469  _bfd_link_section_stabs (abfd, psinfo, s Line 474  _bfd_link_section_stabs (abfd, psinfo, s
474       from the link.  We record the size of the strtab in the first       from the link.  We record the size of the strtab in the first
475       .stabstr section we saw, and make sure we don't set SEC_EXCLUDE       .stabstr section we saw, and make sure we don't set SEC_EXCLUDE
476       for that section.  */       for that section.  */
477    stabsec->_cooked_size = (count - skip) * STABSIZE;    stabsec->size = (count - skip) * STABSIZE;
478    if (stabsec->_cooked_size == 0)    if (stabsec->size == 0)
479      stabsec->flags |= SEC_EXCLUDE;      stabsec->flags |= SEC_EXCLUDE;
480    stabstrsec->flags |= SEC_EXCLUDE;    stabstrsec->flags |= SEC_EXCLUDE;
481    sinfo->stabstr->_cooked_size = _bfd_stringtab_size (sinfo->strings);    sinfo->stabstr->size = _bfd_stringtab_size (sinfo->strings);
482    
483    /* Calculate the `cumulative_skips' array now that stabs have been    /* Calculate the `cumulative_skips' array now that stabs have been
484       deleted for this section.  */       deleted for this section.  */
# Line 502  _bfd_link_section_stabs (abfd, psinfo, s Line 507  _bfd_link_section_stabs (abfd, psinfo, s
507        BFD_ASSERT (offset != 0);        BFD_ASSERT (offset != 0);
508      }      }
509    
510    return true;    return TRUE;
511    
512   error_return:   error_return:
513    if (stabbuf != NULL)    if (stabbuf != NULL)
514      free (stabbuf);      free (stabbuf);
515    if (stabstrbuf != NULL)    if (stabstrbuf != NULL)
516      free (stabstrbuf);      free (stabstrbuf);
517    return false;    return FALSE;
518  }  }
   
519    
520  /* This function is called for each input file before the stab  /* This function is called for each input file before the stab
521     section is relocated.  It discards stab entries for discarded     section is relocated.  It discards stab entries for discarded
522     functions and variables.  The function returns true iff     functions and variables.  The function returns TRUE iff
523     any entries have been deleted.     any entries have been deleted.
524  */  */
525    
526  boolean  bfd_boolean
527  _bfd_discard_section_stabs (abfd, stabsec, psecinfo,  _bfd_discard_section_stabs (abfd, stabsec, psecinfo,
528                              reloc_symbol_deleted_p, cookie)                              reloc_symbol_deleted_p, cookie)
529       bfd *abfd;       bfd *abfd;
530       asection *stabsec;       asection *stabsec;
531       PTR psecinfo;       PTR psecinfo;
532       boolean (*reloc_symbol_deleted_p) PARAMS ((bfd_vma, PTR));       bfd_boolean (*reloc_symbol_deleted_p) PARAMS ((bfd_vma, PTR));
533       PTR cookie;       PTR cookie;
534  {  {
535    bfd_size_type count, amt;    bfd_size_type count, amt;
# Line 536  _bfd_discard_section_stabs (abfd, stabse Line 540  _bfd_discard_section_stabs (abfd, stabse
540    bfd_size_type *pstridx;    bfd_size_type *pstridx;
541    int deleting;    int deleting;
542    
543    if (stabsec->_raw_size == 0)    if (stabsec->size == 0)
544      {      {
545        /* This file does not contain stabs debugging information.  */        /* This file does not contain stabs debugging information.  */
546        return false;        return FALSE;
547      }      }
548    
549    if (stabsec->_raw_size % STABSIZE != 0)    if (stabsec->size % STABSIZE != 0)
550      {      {
551        /* Something is wrong with the format of these stab symbols.        /* Something is wrong with the format of these stab symbols.
552           Don't try to optimize them.  */           Don't try to optimize them.  */
553        return false;        return FALSE;
554      }      }
555    
556    if ((stabsec->output_section != NULL    if ((stabsec->output_section != NULL
557         && bfd_is_abs_section (stabsec->output_section)))         && bfd_is_abs_section (stabsec->output_section)))
558      {      {
559        /* At least one of the sections is being discarded from the        /* At least one of the sections is being discarded from the
560           link, so we should just ignore them.  */           link, so we should just ignore them.  */
561        return false;        return FALSE;
562      }      }
563    
564    /* We should have initialized our data in _bfd_link_stab_sections.    /* We should have initialized our data in _bfd_link_stab_sections.
565       If there was some bizarre error reading the string sections, though,       If there was some bizarre error reading the string sections, though,
566       we might not have.  Bail rather than asserting.  */       we might not have.  Bail rather than asserting.  */
567    if (psecinfo == NULL)    if (psecinfo == NULL)
568      return false;      return FALSE;
569    
570    count = stabsec->_raw_size / STABSIZE;    count = stabsec->rawsize / STABSIZE;
571    secinfo = (struct stab_section_info *) psecinfo;    secinfo = (struct stab_section_info *) psecinfo;
572    
573    /* Read the stabs information from abfd.  */    /* Read the stabs information from abfd.  */
574    
575    stabbuf = (bfd_byte *) bfd_malloc (stabsec->_raw_size);    if (!bfd_malloc_and_get_section (abfd, stabsec, &stabbuf))
   if (stabbuf == NULL)  
     goto error_return;  
   
   if (! bfd_get_section_contents (abfd, stabsec, stabbuf, (bfd_vma) 0,  
                                   stabsec->_raw_size))  
576      goto error_return;      goto error_return;
577    
578    /* Look through the stabs symbols and discard any information for    /* Look through the stabs symbols and discard any information for
# Line 582  _bfd_discard_section_stabs (abfd, stabse Line 581  _bfd_discard_section_stabs (abfd, stabse
581    skip = 0;    skip = 0;
582    deleting = -1;    deleting = -1;
583    
584    symend = stabbuf + stabsec->_raw_size;    symend = stabbuf + stabsec->rawsize;
585    for (sym = stabbuf, pstridx = secinfo->stridxs;    for (sym = stabbuf, pstridx = secinfo->stridxs;
586         sym < symend;         sym < symend;
587         sym += STABSIZE, ++pstridx)         sym += STABSIZE, ++pstridx)
# Line 597  _bfd_discard_section_stabs (abfd, stabse Line 596  _bfd_discard_section_stabs (abfd, stabse
596    
597        type = sym[TYPEOFF];        type = sym[TYPEOFF];
598    
599        if (type == N_FUN)        if (type == (int) N_FUN)
600          {          {
601            int strx = bfd_get_32 (abfd, sym + STRDXOFF);            int strx = bfd_get_32 (abfd, sym + STRDXOFF);
602    
# Line 624  _bfd_discard_section_stabs (abfd, stabse Line 623  _bfd_discard_section_stabs (abfd, stabse
623        else if (deleting == -1)        else if (deleting == -1)
624          {          {
625            /* Outside of a function.  Check for deleted variables.  */            /* Outside of a function.  Check for deleted variables.  */
626            if (type == N_STSYM || type == N_LCSYM)            if (type == (int) N_STSYM || type == (int) N_LCSYM)
627              if ((*reloc_symbol_deleted_p) (sym + VALOFF - stabbuf, cookie))              if ((*reloc_symbol_deleted_p) (sym + VALOFF - stabbuf, cookie))
628                {                {
629                  *pstridx = -1;                  *pstridx = -1;
# Line 640  _bfd_discard_section_stabs (abfd, stabse Line 639  _bfd_discard_section_stabs (abfd, stabse
639    stabbuf = NULL;    stabbuf = NULL;
640    
641    /* Shrink the stabsec as needed.  */    /* Shrink the stabsec as needed.  */
642    stabsec->_cooked_size -= skip * STABSIZE;    stabsec->size -= skip * STABSIZE;
643    if (stabsec->_cooked_size == 0)    if (stabsec->size == 0)
644      stabsec->flags |= SEC_EXCLUDE;      stabsec->flags |= SEC_EXCLUDE;
645    
646    /* Recalculate the `cumulative_skips' array now that stabs have been    /* Recalculate the `cumulative_skips' array now that stabs have been
# Line 674  _bfd_discard_section_stabs (abfd, stabse Line 673  _bfd_discard_section_stabs (abfd, stabse
673        BFD_ASSERT (offset != 0);        BFD_ASSERT (offset != 0);
674      }      }
675    
676    return (skip > 0);    return skip > 0;
677    
678   error_return:   error_return:
679    if (stabbuf != NULL)    if (stabbuf != NULL)
680      free (stabbuf);      free (stabbuf);
681    return false;    return FALSE;
682  }  }
683    
684  /* Write out the stab section.  This is called with the relocated  /* Write out the stab section.  This is called with the relocated
685     contents.  */     contents.  */
686    
687  boolean  bfd_boolean
688  _bfd_write_section_stabs (output_bfd, psinfo, stabsec, psecinfo, contents)  _bfd_write_section_stabs (output_bfd, sinfo, stabsec, psecinfo, contents)
689       bfd *output_bfd;       bfd *output_bfd;
690       PTR *psinfo;       struct stab_info *sinfo;
691       asection *stabsec;       asection *stabsec;
692       PTR *psecinfo;       PTR *psecinfo;
693       bfd_byte *contents;       bfd_byte *contents;
694  {  {
   struct stab_info *sinfo;  
695    struct stab_section_info *secinfo;    struct stab_section_info *secinfo;
696    struct stab_excl_list *e;    struct stab_excl_list *e;
697    bfd_byte *sym, *tosym, *symend;    bfd_byte *sym, *tosym, *symend;
698    bfd_size_type *pstridx;    bfd_size_type *pstridx;
699    
   sinfo = (struct stab_info *) *psinfo;  
700    secinfo = (struct stab_section_info *) *psecinfo;    secinfo = (struct stab_section_info *) *psecinfo;
701    
702    if (secinfo == NULL)    if (secinfo == NULL)
703      return bfd_set_section_contents (output_bfd, stabsec->output_section,      return bfd_set_section_contents (output_bfd, stabsec->output_section,
704                                       contents,                                       contents, stabsec->output_offset,
705                                       (file_ptr) stabsec->output_offset,                                       stabsec->size);
                                      stabsec->_raw_size);  
706    
707    /* Handle each N_BINCL entry.  */    /* Handle each N_BINCL entry.  */
708    for (e = secinfo->excls; e != NULL; e = e->next)    for (e = secinfo->excls; e != NULL; e = e->next)
709      {      {
710        bfd_byte *excl_sym;        bfd_byte *excl_sym;
711    
712        BFD_ASSERT (e->offset < stabsec->_raw_size);        BFD_ASSERT (e->offset < stabsec->rawsize);
713        excl_sym = contents + e->offset;        excl_sym = contents + e->offset;
714        bfd_put_32 (output_bfd, e->val, excl_sym + VALOFF);        bfd_put_32 (output_bfd, e->val, excl_sym + VALOFF);
715        excl_sym[TYPEOFF] = e->type;        excl_sym[TYPEOFF] = e->type;
# Line 722  _bfd_write_section_stabs (output_bfd, ps Line 718  _bfd_write_section_stabs (output_bfd, ps
718    /* Copy over all the stabs symbols, omitting the ones we don't want,    /* Copy over all the stabs symbols, omitting the ones we don't want,
719       and correcting the string indices for those we do want.  */       and correcting the string indices for those we do want.  */
720    tosym = contents;    tosym = contents;
721    symend = contents + stabsec->_raw_size;    symend = contents + stabsec->rawsize;
722    for (sym = contents, pstridx = secinfo->stridxs;    for (sym = contents, pstridx = secinfo->stridxs;
723         sym < symend;         sym < symend;
724         sym += STABSIZE, ++pstridx)         sym += STABSIZE, ++pstridx)
# Line 736  _bfd_write_section_stabs (output_bfd, ps Line 732  _bfd_write_section_stabs (output_bfd, ps
732            if (sym[TYPEOFF] == 0)            if (sym[TYPEOFF] == 0)
733              {              {
734                /* This is the header symbol for the stabs section.  We                /* This is the header symbol for the stabs section.  We
735                   don't really need one, since we have merged all the                   don't really need one, since we have merged all the
736                   input stabs sections into one, but we generate one                   input stabs sections into one, but we generate one
737                   for the benefit of readers which expect to see one.  */                   for the benefit of readers which expect to see one.  */
738                BFD_ASSERT (sym == contents);                BFD_ASSERT (sym == contents);
739                bfd_put_32 (output_bfd, _bfd_stringtab_size (sinfo->strings),                bfd_put_32 (output_bfd, _bfd_stringtab_size (sinfo->strings),
740                            tosym + VALOFF);                            tosym + VALOFF);
741                bfd_put_16 (output_bfd,                bfd_put_16 (output_bfd,
742                            stabsec->output_section->_raw_size / STABSIZE - 1,                            stabsec->output_section->size / STABSIZE - 1,
743                            tosym + DESCOFF);                            tosym + DESCOFF);
744              }              }
745    
# Line 751  _bfd_write_section_stabs (output_bfd, ps Line 747  _bfd_write_section_stabs (output_bfd, ps
747          }          }
748      }      }
749    
750    BFD_ASSERT ((bfd_size_type) (tosym - contents) == stabsec->_cooked_size);    BFD_ASSERT ((bfd_size_type) (tosym - contents) == stabsec->size);
751    
752    return bfd_set_section_contents (output_bfd, stabsec->output_section,    return bfd_set_section_contents (output_bfd, stabsec->output_section,
753                                     contents, (file_ptr) stabsec->output_offset,                                     contents, (file_ptr) stabsec->output_offset,
754                                     stabsec->_cooked_size);                                     stabsec->size);
755  }  }
756    
757  /* Write out the .stabstr section.  */  /* Write out the .stabstr section.  */
758    
759  boolean  bfd_boolean
760  _bfd_write_stab_strings (output_bfd, psinfo)  _bfd_write_stab_strings (output_bfd, sinfo)
761       bfd *output_bfd;       bfd *output_bfd;
762       PTR *psinfo;       struct stab_info *sinfo;
763  {  {
   struct stab_info *sinfo;  
   
   sinfo = (struct stab_info *) *psinfo;  
   
   if (sinfo == NULL)  
     return true;  
   
764    if (bfd_is_abs_section (sinfo->stabstr->output_section))    if (bfd_is_abs_section (sinfo->stabstr->output_section))
765      {      {
766        /* The section was discarded from the link.  */        /* The section was discarded from the link.  */
767        return true;        return TRUE;
768      }      }
769    
770    BFD_ASSERT ((sinfo->stabstr->output_offset    BFD_ASSERT ((sinfo->stabstr->output_offset
771                 + _bfd_stringtab_size (sinfo->strings))                 + _bfd_stringtab_size (sinfo->strings))
772                <= sinfo->stabstr->output_section->_raw_size);                <= sinfo->stabstr->output_section->size);
773    
774    if (bfd_seek (output_bfd,    if (bfd_seek (output_bfd,
775                  (file_ptr) (sinfo->stabstr->output_section->filepos                  (file_ptr) (sinfo->stabstr->output_section->filepos
776                              + sinfo->stabstr->output_offset),                              + sinfo->stabstr->output_offset),
777                  SEEK_SET) != 0)                  SEEK_SET) != 0)
778      return false;      return FALSE;
779    
780    if (! _bfd_stringtab_emit (output_bfd, sinfo->strings))    if (! _bfd_stringtab_emit (output_bfd, sinfo->strings))
781      return false;      return FALSE;
782    
783    /* We no longer need the stabs information.  */    /* We no longer need the stabs information.  */
784    _bfd_stringtab_free (sinfo->strings);    _bfd_stringtab_free (sinfo->strings);
785    bfd_hash_table_free (&sinfo->includes.root);    bfd_hash_table_free (&sinfo->includes);
786    
787    return true;    return TRUE;
788  }  }
789    
790  /* Adjust an address in the .stab section.  Given OFFSET within  /* Adjust an address in the .stab section.  Given OFFSET within
# Line 803  _bfd_write_stab_strings (output_bfd, psi Line 792  _bfd_write_stab_strings (output_bfd, psi
792     or -1 if the address refers to a stab which has been removed.  */     or -1 if the address refers to a stab which has been removed.  */
793    
794  bfd_vma  bfd_vma
795  _bfd_stab_section_offset (output_bfd, psinfo, stabsec, psecinfo, offset)  _bfd_stab_section_offset (stabsec, psecinfo, offset)
      bfd *output_bfd ATTRIBUTE_UNUSED;  
      PTR *psinfo ATTRIBUTE_UNUSED;  
796       asection *stabsec;       asection *stabsec;
797       PTR *psecinfo;       PTR psecinfo;
798       bfd_vma offset;       bfd_vma offset;
799  {  {
800    struct stab_section_info *secinfo;    struct stab_section_info *secinfo;
801    
802    secinfo = (struct stab_section_info *) *psecinfo;    secinfo = (struct stab_section_info *) psecinfo;
803    
804    if (secinfo == NULL)    if (secinfo == NULL)
805      return offset;      return offset;
806    
807    if (offset >= stabsec->_raw_size)    if (offset >= stabsec->rawsize)
808      return offset - (stabsec->_cooked_size - stabsec->_raw_size);      return offset - stabsec->rawsize + stabsec->size;
809    
810    if (secinfo->cumulative_skips)    if (secinfo->cumulative_skips)
811      {      {

Legend:
Removed from v.1.1.1.1  
changed lines
  Added in v.1.2

savannah-hackers-public@gnu.org
ViewVC Help
Powered by ViewVC 1.1.26