OpenCores
URL https://opencores.org/ocsvn/or1k/or1k/trunk

Subversion Repositories or1k

[/] [or1k/] [tags/] [VER_5_3/] [gdb-5.3/] [bfd/] [stabs.c] - Blame information for rev 1765

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 1181 sfurman
/* Stabs in sections linking support.
2
   Copyright 1996, 1997, 1998, 1999, 2000, 2001
3
   Free Software Foundation, Inc.
4
   Written by Ian Lance Taylor, Cygnus Support.
5
 
6
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
9
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
11
(at your option) any later version.
12
 
13
This program is distributed in the hope that it will be useful,
14
but WITHOUT ANY WARRANTY; without even the implied warranty of
15
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16
GNU General Public License for more details.
17
 
18
You should have received a copy of the GNU General Public License
19
along with this program; if not, write to the Free Software
20
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
23
   on COFF and ELF.  */
24
 
25
#include "bfd.h"
26
#include "sysdep.h"
27
#include "libbfd.h"
28
#include "aout/stab_gnu.h"
29
#include "safe-ctype.h"
30
 
31
/* Stabs entries use a 12 byte format:
32
     4 byte string table index
33
     1 byte stab type
34
     1 byte stab other field
35
     2 byte stab desc field
36
     4 byte stab value
37
   FIXME: This will have to change for a 64 bit object format.
38
 
39
   The stabs symbols are divided into compilation units.  For the
40
   first entry in each unit, the type of 0, the value is the length of
41
   the string table for this unit, and the desc field is the number of
42
   stabs symbols for this unit.  */
43
 
44
#define STRDXOFF (0)
45
#define TYPEOFF (4)
46
#define OTHEROFF (5)
47
#define DESCOFF (6)
48
#define VALOFF (8)
49
#define STABSIZE (12)
50
 
51
/* A hash table used for header files with N_BINCL entries.  */
52
 
53
struct stab_link_includes_table
54
{
55
  struct bfd_hash_table root;
56
};
57
 
58
/* A linked list of totals that we have found for a particular header
59
   file.  */
60
 
61
struct stab_link_includes_totals
62
{
63
  struct stab_link_includes_totals *next;
64
  bfd_vma total;
65
};
66
 
67
/* An entry in the header file hash table.  */
68
 
69
struct stab_link_includes_entry
70
{
71
  struct bfd_hash_entry root;
72
  /* List of totals we have found for this file.  */
73
  struct stab_link_includes_totals *totals;
74
};
75
 
76
/* Look up an entry in an the header file hash table.  */
77
 
78
#define stab_link_includes_lookup(table, string, create, copy) \
79
  ((struct stab_link_includes_entry *) \
80
   bfd_hash_lookup (&(table)->root, (string), (create), (copy)))
81
 
82
/* This structure is used to hold a list of N_BINCL symbols, some of
83
   which might be converted into N_EXCL symbols.  */
84
 
85
struct stab_excl_list
86
{
87
  /* The next symbol to convert.  */
88
  struct stab_excl_list *next;
89
  /* The offset to this symbol in the section contents.  */
90
  bfd_size_type offset;
91
  /* The value to use for the symbol.  */
92
  bfd_vma val;
93
  /* The type of this symbol (N_BINCL or N_EXCL).  */
94
  int type;
95
};
96
 
97
/* This structure is stored with each .stab section.  */
98
 
99
struct stab_section_info
100
{
101
  /* This is a linked list of N_BINCL symbols which should be
102
     converted into N_EXCL symbols.  */
103
  struct stab_excl_list *excls;
104
 
105
  /* This is used to map input stab offsets within their sections
106
     to output stab offsets, to take into account stabs that have
107
     been deleted.  If it is NULL, the output offsets are the same
108
     as the input offsets, because no stabs have been deleted from
109
     this section.  Otherwise the i'th entry is the number of
110
     bytes of stabs that have been deleted prior to the i'th
111
     stab.  */
112
  bfd_size_type *cumulative_skips;
113
 
114
  /* This is an array of string indices.  For each stab symbol, we
115
     store the string index here.  If a stab symbol should not be
116
     included in the final output, the string index is -1.  */
117
  bfd_size_type stridxs[1];
118
};
119
 
120
/* This structure is used to keep track of stabs in sections
121
   information while linking.  */
122
 
123
struct stab_info
124
{
125
  /* A hash table used to hold stabs strings.  */
126
  struct bfd_strtab_hash *strings;
127
  /* The header file hash table.  */
128
  struct stab_link_includes_table includes;
129
  /* The first .stabstr section.  */
130
  asection *stabstr;
131
};
132
 
133
static struct bfd_hash_entry *stab_link_includes_newfunc
134
  PARAMS ((struct bfd_hash_entry *, struct bfd_hash_table *, const char *));
135
 
136
/* The function to create a new entry in the header file hash table.  */
137
 
138
static struct bfd_hash_entry *
139
stab_link_includes_newfunc (entry, table, string)
140
     struct bfd_hash_entry *entry;
141
     struct bfd_hash_table *table;
142
     const char *string;
143
{
144
  struct stab_link_includes_entry *ret =
145
    (struct stab_link_includes_entry *) entry;
146
 
147
  /* Allocate the structure if it has not already been allocated by a
148
     subclass.  */
149
  if (ret == (struct stab_link_includes_entry *) NULL)
150
    ret = ((struct stab_link_includes_entry *)
151
           bfd_hash_allocate (table,
152
                              sizeof (struct stab_link_includes_entry)));
153
  if (ret == (struct stab_link_includes_entry *) NULL)
154
    return (struct bfd_hash_entry *) ret;
155
 
156
  /* Call the allocation method of the superclass.  */
157
  ret = ((struct stab_link_includes_entry *)
158
         bfd_hash_newfunc ((struct bfd_hash_entry *) ret, table, string));
159
  if (ret)
160
    {
161
      /* Set local fields.  */
162
      ret->totals = NULL;
163
    }
164
 
165
  return (struct bfd_hash_entry *) ret;
166
}
167
 
168
/* This function is called for each input file from the add_symbols
169
   pass of the linker.  */
170
 
171
boolean
172
_bfd_link_section_stabs (abfd, psinfo, stabsec, stabstrsec, psecinfo)
173
     bfd *abfd;
174
     PTR *psinfo;
175
     asection *stabsec;
176
     asection *stabstrsec;
177
     PTR *psecinfo;
178
{
179
  boolean first;
180
  struct stab_info *sinfo;
181
  bfd_size_type count, amt;
182
  struct stab_section_info *secinfo;
183
  bfd_byte *stabbuf = NULL;
184
  bfd_byte *stabstrbuf = NULL;
185
  bfd_byte *sym, *symend;
186
  bfd_size_type stroff, next_stroff, skip;
187
  bfd_size_type *pstridx;
188
 
189
  if (stabsec->_raw_size == 0
190
      || stabstrsec->_raw_size == 0)
191
    {
192
      /* This file does not contain stabs debugging information.  */
193
      return true;
194
    }
195
 
196
  if (stabsec->_raw_size % STABSIZE != 0)
197
    {
198
      /* Something is wrong with the format of these stab symbols.
199
         Don't try to optimize them.  */
200
      return true;
201
    }
202
 
203
  if ((stabstrsec->flags & SEC_RELOC) != 0)
204
    {
205
      /* We shouldn't see relocations in the strings, and we aren't
206
         prepared to handle them.  */
207
      return true;
208
    }
209
 
210
  if ((stabsec->output_section != NULL
211
       && bfd_is_abs_section (stabsec->output_section))
212
      || (stabstrsec->output_section != NULL
213
          && bfd_is_abs_section (stabstrsec->output_section)))
214
    {
215
      /* At least one of the sections is being discarded from the
216
         link, so we should just ignore them.  */
217
      return true;
218
    }
219
 
220
  first = false;
221
 
222
  if (*psinfo == NULL)
223
    {
224
      /* Initialize the stabs information we need to keep track of.  */
225
      first = true;
226
      amt = sizeof (struct stab_info);
227
      *psinfo = (PTR) bfd_alloc (abfd, amt);
228
      if (*psinfo == NULL)
229
        goto error_return;
230
      sinfo = (struct stab_info *) *psinfo;
231
      sinfo->strings = _bfd_stringtab_init ();
232
      if (sinfo->strings == NULL)
233
        goto error_return;
234
      /* Make sure the first byte is zero.  */
235
      (void) _bfd_stringtab_add (sinfo->strings, "", true, true);
236
      if (! bfd_hash_table_init_n (&sinfo->includes.root,
237
                                   stab_link_includes_newfunc,
238
                                   251))
239
        goto error_return;
240
      sinfo->stabstr = bfd_make_section_anyway (abfd, ".stabstr");
241
      sinfo->stabstr->flags |= SEC_HAS_CONTENTS | SEC_READONLY | SEC_DEBUGGING;
242
    }
243
 
244
  sinfo = (struct stab_info *) *psinfo;
245
 
246
  /* Initialize the information we are going to store for this .stab
247
     section.  */
248
 
249
  count = stabsec->_raw_size / STABSIZE;
250
 
251
  amt = sizeof (struct stab_section_info);
252
  amt += (count - 1) * sizeof (bfd_size_type);
253
  *psecinfo = bfd_alloc (abfd, amt);
254
  if (*psecinfo == NULL)
255
    goto error_return;
256
 
257
  secinfo = (struct stab_section_info *) *psecinfo;
258
  secinfo->excls = NULL;
259
  secinfo->cumulative_skips = NULL;
260
  memset (secinfo->stridxs, 0, (size_t) count * sizeof (bfd_size_type));
261
 
262
  /* Read the stabs information from abfd.  */
263
 
264
  stabbuf = (bfd_byte *) bfd_malloc (stabsec->_raw_size);
265
  stabstrbuf = (bfd_byte *) bfd_malloc (stabstrsec->_raw_size);
266
  if (stabbuf == NULL || stabstrbuf == NULL)
267
    goto error_return;
268
 
269
  if (! bfd_get_section_contents (abfd, stabsec, stabbuf, (bfd_vma) 0,
270
                                  stabsec->_raw_size)
271
      || ! bfd_get_section_contents (abfd, stabstrsec, stabstrbuf, (bfd_vma) 0,
272
                                     stabstrsec->_raw_size))
273
    goto error_return;
274
 
275
  /* Look through the stabs symbols, work out the new string indices,
276
     and identify N_BINCL symbols which can be eliminated.  */
277
 
278
  stroff = 0;
279
  next_stroff = 0;
280
  skip = 0;
281
 
282
  symend = stabbuf + stabsec->_raw_size;
283
  for (sym = stabbuf, pstridx = secinfo->stridxs;
284
       sym < symend;
285
       sym += STABSIZE, ++pstridx)
286
    {
287
      bfd_size_type symstroff;
288
      int type;
289
      const char *string;
290
 
291
      if (*pstridx != 0)
292
        {
293
          /* This symbol has already been handled by an N_BINCL pass.  */
294
          continue;
295
        }
296
 
297
      type = sym[TYPEOFF];
298
 
299
      if (type == 0)
300
        {
301
          /* Special type 0 stabs indicate the offset to the next
302
             string table.  We only copy the very first one.  */
303
          stroff = next_stroff;
304
          next_stroff += bfd_get_32 (abfd, sym + 8);
305
          if (! first)
306
            {
307
              *pstridx = (bfd_size_type) -1;
308
              ++skip;
309
              continue;
310
            }
311
          first = false;
312
        }
313
 
314
      /* Store the string in the hash table, and record the index.  */
315
      symstroff = stroff + bfd_get_32 (abfd, sym + STRDXOFF);
316
      if (symstroff >= stabstrsec->_raw_size)
317
        {
318
          (*_bfd_error_handler)
319
            (_("%s(%s+0x%lx): Stabs entry has invalid string index."),
320
             bfd_archive_filename (abfd),
321
             bfd_get_section_name (abfd, stabsec),
322
             (long) (sym - stabbuf));
323
          bfd_set_error (bfd_error_bad_value);
324
          goto error_return;
325
        }
326
      string = (char *) stabstrbuf + symstroff;
327
      *pstridx = _bfd_stringtab_add (sinfo->strings, string, true, true);
328
 
329
      /* An N_BINCL symbol indicates the start of the stabs entries
330
         for a header file.  We need to scan ahead to the next N_EINCL
331
         symbol, ignoring nesting, adding up all the characters in the
332
         symbol names, not including the file numbers in types (the
333
         first number after an open parenthesis).  */
334
      if (type == N_BINCL)
335
        {
336
          bfd_vma val;
337
          int nest;
338
          bfd_byte *incl_sym;
339
          struct stab_link_includes_entry *incl_entry;
340
          struct stab_link_includes_totals *t;
341
          struct stab_excl_list *ne;
342
 
343
          val = 0;
344
          nest = 0;
345
          for (incl_sym = sym + STABSIZE;
346
               incl_sym < symend;
347
               incl_sym += STABSIZE)
348
            {
349
              int incl_type;
350
 
351
              incl_type = incl_sym[TYPEOFF];
352
              if (incl_type == 0)
353
                break;
354
              else if (incl_type == N_EINCL)
355
                {
356
                  if (nest == 0)
357
                    break;
358
                  --nest;
359
                }
360
              else if (incl_type == N_BINCL)
361
                ++nest;
362
              else if (nest == 0)
363
                {
364
                  const char *str;
365
 
366
                  str = ((char *) stabstrbuf
367
                         + stroff
368
                         + bfd_get_32 (abfd, incl_sym + STRDXOFF));
369
                  for (; *str != '\0'; str++)
370
                    {
371
                      val += *str;
372
                      if (*str == '(')
373
                        {
374
                          /* Skip the file number.  */
375
                          ++str;
376
                          while (ISDIGIT (*str))
377
                            ++str;
378
                          --str;
379
                        }
380
                    }
381
                }
382
            }
383
 
384
          /* If we have already included a header file with the same
385
             value, then replaced this one with an N_EXCL symbol.  */
386
          incl_entry = stab_link_includes_lookup (&sinfo->includes, string,
387
                                                  true, true);
388
          if (incl_entry == NULL)
389
            goto error_return;
390
 
391
          for (t = incl_entry->totals; t != NULL; t = t->next)
392
            if (t->total == val)
393
              break;
394
 
395
          /* Record this symbol, so that we can set the value
396
             correctly.  */
397
          amt = sizeof *ne;
398
          ne = (struct stab_excl_list *) bfd_alloc (abfd, amt);
399
          if (ne == NULL)
400
            goto error_return;
401
          ne->offset = sym - stabbuf;
402
          ne->val = val;
403
          ne->type = N_BINCL;
404
          ne->next = secinfo->excls;
405
          secinfo->excls = ne;
406
 
407
          if (t == NULL)
408
            {
409
              /* This is the first time we have seen this header file
410
                 with this set of stabs strings.  */
411
              t = ((struct stab_link_includes_totals *)
412
                   bfd_hash_allocate (&sinfo->includes.root, sizeof *t));
413
              if (t == NULL)
414
                goto error_return;
415
              t->total = val;
416
              t->next = incl_entry->totals;
417
              incl_entry->totals = t;
418
            }
419
          else
420
            {
421
              bfd_size_type *incl_pstridx;
422
 
423
              /* We have seen this header file before.  Tell the final
424
                 pass to change the type to N_EXCL.  */
425
              ne->type = N_EXCL;
426
 
427
              /* Mark the skipped symbols.  */
428
 
429
              nest = 0;
430
              for (incl_sym = sym + STABSIZE, incl_pstridx = pstridx + 1;
431
                   incl_sym < symend;
432
                   incl_sym += STABSIZE, ++incl_pstridx)
433
                {
434
                  int incl_type;
435
 
436
                  incl_type = incl_sym[TYPEOFF];
437
 
438
                  if (incl_type == N_EINCL)
439
                    {
440
                      if (nest == 0)
441
                        {
442
                          *incl_pstridx = (bfd_size_type) -1;
443
                          ++skip;
444
                          break;
445
                        }
446
                      --nest;
447
                    }
448
                  else if (incl_type == N_BINCL)
449
                    ++nest;
450
                  else if (nest == 0)
451
                    {
452
                      *incl_pstridx = (bfd_size_type) -1;
453
                      ++skip;
454
                    }
455
                }
456
            }
457
        }
458
    }
459
 
460
  free (stabbuf);
461
  stabbuf = NULL;
462
  free (stabstrbuf);
463
  stabstrbuf = NULL;
464
 
465
  /* We need to set the section sizes such that the linker will
466
     compute the output section sizes correctly.  We set the .stab
467
     size to not include the entries we don't want.  We set
468
     SEC_EXCLUDE for the .stabstr section, so that it will be dropped
469
     from the link.  We record the size of the strtab in the first
470
     .stabstr section we saw, and make sure we don't set SEC_EXCLUDE
471
     for that section.  */
472
  stabsec->_cooked_size = (count - skip) * STABSIZE;
473
  if (stabsec->_cooked_size == 0)
474
    stabsec->flags |= SEC_EXCLUDE;
475
  stabstrsec->flags |= SEC_EXCLUDE;
476
  sinfo->stabstr->_cooked_size = _bfd_stringtab_size (sinfo->strings);
477
 
478
  /* Calculate the `cumulative_skips' array now that stabs have been
479
     deleted for this section.  */
480
 
481
  if (skip != 0)
482
    {
483
      bfd_size_type i, offset;
484
      bfd_size_type *pskips;
485
 
486
      amt = count * sizeof (bfd_size_type);
487
      secinfo->cumulative_skips = (bfd_size_type *) bfd_alloc (abfd, amt);
488
      if (secinfo->cumulative_skips == NULL)
489
        goto error_return;
490
 
491
      pskips = secinfo->cumulative_skips;
492
      pstridx = secinfo->stridxs;
493
      offset = 0;
494
 
495
      for (i = 0; i < count; i++, pskips++, pstridx++)
496
        {
497
          *pskips = offset;
498
          if (*pstridx == (bfd_size_type) -1)
499
            offset += STABSIZE;
500
        }
501
 
502
      BFD_ASSERT (offset != 0);
503
    }
504
 
505
  return true;
506
 
507
 error_return:
508
  if (stabbuf != NULL)
509
    free (stabbuf);
510
  if (stabstrbuf != NULL)
511
    free (stabstrbuf);
512
  return false;
513
}
514
 
515
 
516
/* This function is called for each input file before the stab
517
   section is relocated.  It discards stab entries for discarded
518
   functions and variables.  The function returns true iff
519
   any entries have been deleted.
520
*/
521
 
522
boolean
523
_bfd_discard_section_stabs (abfd, stabsec, psecinfo,
524
                            reloc_symbol_deleted_p, cookie)
525
     bfd *abfd;
526
     asection *stabsec;
527
     PTR psecinfo;
528
     boolean (*reloc_symbol_deleted_p) PARAMS ((bfd_vma, PTR));
529
     PTR cookie;
530
{
531
  bfd_size_type count, amt;
532
  struct stab_section_info *secinfo;
533
  bfd_byte *stabbuf = NULL;
534
  bfd_byte *sym, *symend;
535
  bfd_size_type skip;
536
  bfd_size_type *pstridx;
537
  int deleting;
538
 
539
  if (stabsec->_raw_size == 0)
540
    {
541
      /* This file does not contain stabs debugging information.  */
542
      return false;
543
    }
544
 
545
  if (stabsec->_raw_size % STABSIZE != 0)
546
    {
547
      /* Something is wrong with the format of these stab symbols.
548
         Don't try to optimize them.  */
549
      return false;
550
    }
551
 
552
  if ((stabsec->output_section != NULL
553
       && bfd_is_abs_section (stabsec->output_section)))
554
    {
555
      /* At least one of the sections is being discarded from the
556
         link, so we should just ignore them.  */
557
      return false;
558
    }
559
 
560
  /* We should have initialized our data in _bfd_link_stab_sections.
561
     If there was some bizarre error reading the string sections, though,
562
     we might not have.  Bail rather than asserting.  */
563
  if (psecinfo == NULL)
564
    return false;
565
 
566
  count = stabsec->_raw_size / STABSIZE;
567
  secinfo = (struct stab_section_info *) psecinfo;
568
 
569
  /* Read the stabs information from abfd.  */
570
 
571
  stabbuf = (bfd_byte *) bfd_malloc (stabsec->_raw_size);
572
  if (stabbuf == NULL)
573
    goto error_return;
574
 
575
  if (! bfd_get_section_contents (abfd, stabsec, stabbuf, (bfd_vma) 0,
576
                                  stabsec->_raw_size))
577
    goto error_return;
578
 
579
  /* Look through the stabs symbols and discard any information for
580
     discarded functions.  */
581
 
582
  skip = 0;
583
  deleting = -1;
584
 
585
  symend = stabbuf + stabsec->_raw_size;
586
  for (sym = stabbuf, pstridx = secinfo->stridxs;
587
       sym < symend;
588
       sym += STABSIZE, ++pstridx)
589
    {
590
      int type;
591
 
592
      if (*pstridx == (bfd_size_type) -1)
593
        {
594
          /* This stab was deleted in a previous pass.  */
595
          continue;
596
        }
597
 
598
      type = sym[TYPEOFF];
599
 
600
      if (type == N_FUN)
601
        {
602
          int strx = bfd_get_32 (abfd, sym + STRDXOFF);
603
 
604
          if (strx == 0)
605
            {
606
              if (deleting)
607
                {
608
                  skip++;
609
                  *pstridx = -1;
610
                }
611
              deleting = -1;
612
              continue;
613
            }
614
          deleting = 0;
615
          if ((*reloc_symbol_deleted_p) (sym + VALOFF - stabbuf, cookie))
616
            deleting = 1;
617
        }
618
 
619
      if (deleting == 1)
620
        {
621
          *pstridx = -1;
622
          skip++;
623
        }
624
      else if (deleting == -1)
625
        {
626
          /* Outside of a function.  Check for deleted variables.  */
627
          if (type == N_STSYM || type == N_LCSYM)
628
            if ((*reloc_symbol_deleted_p) (sym + VALOFF - stabbuf, cookie))
629
              {
630
                *pstridx = -1;
631
                skip ++;
632
              }
633
          /* We should also check for N_GSYM entries which reference a
634
             deleted global, but those are less harmful to debuggers
635
             and would require parsing the stab strings.  */
636
        }
637
    }
638
 
639
  free (stabbuf);
640
  stabbuf = NULL;
641
 
642
  /* Shrink the stabsec as needed.  */
643
  stabsec->_cooked_size -= skip * STABSIZE;
644
  if (stabsec->_cooked_size == 0)
645
    stabsec->flags |= SEC_EXCLUDE;
646
 
647
  /* Recalculate the `cumulative_skips' array now that stabs have been
648
     deleted for this section.  */
649
 
650
  if (skip != 0)
651
    {
652
      bfd_size_type i, offset;
653
      bfd_size_type *pskips;
654
 
655
      if (secinfo->cumulative_skips == NULL)
656
        {
657
          amt = count * sizeof (bfd_size_type);
658
          secinfo->cumulative_skips = (bfd_size_type *) bfd_alloc (abfd, amt);
659
          if (secinfo->cumulative_skips == NULL)
660
            goto error_return;
661
        }
662
 
663
      pskips = secinfo->cumulative_skips;
664
      pstridx = secinfo->stridxs;
665
      offset = 0;
666
 
667
      for (i = 0; i < count; i++, pskips++, pstridx++)
668
        {
669
          *pskips = offset;
670
          if (*pstridx == (bfd_size_type) -1)
671
            offset += STABSIZE;
672
        }
673
 
674
      BFD_ASSERT (offset != 0);
675
    }
676
 
677
  return (skip > 0);
678
 
679
 error_return:
680
  if (stabbuf != NULL)
681
    free (stabbuf);
682
  return false;
683
}
684
 
685
/* Write out the stab section.  This is called with the relocated
686
   contents.  */
687
 
688
boolean
689
_bfd_write_section_stabs (output_bfd, psinfo, stabsec, psecinfo, contents)
690
     bfd *output_bfd;
691
     PTR *psinfo;
692
     asection *stabsec;
693
     PTR *psecinfo;
694
     bfd_byte *contents;
695
{
696
  struct stab_info *sinfo;
697
  struct stab_section_info *secinfo;
698
  struct stab_excl_list *e;
699
  bfd_byte *sym, *tosym, *symend;
700
  bfd_size_type *pstridx;
701
 
702
  sinfo = (struct stab_info *) *psinfo;
703
  secinfo = (struct stab_section_info *) *psecinfo;
704
 
705
  if (secinfo == NULL)
706
    return bfd_set_section_contents (output_bfd, stabsec->output_section,
707
                                     contents,
708
                                     (file_ptr) stabsec->output_offset,
709
                                     stabsec->_raw_size);
710
 
711
  /* Handle each N_BINCL entry.  */
712
  for (e = secinfo->excls; e != NULL; e = e->next)
713
    {
714
      bfd_byte *excl_sym;
715
 
716
      BFD_ASSERT (e->offset < stabsec->_raw_size);
717
      excl_sym = contents + e->offset;
718
      bfd_put_32 (output_bfd, e->val, excl_sym + VALOFF);
719
      excl_sym[TYPEOFF] = e->type;
720
    }
721
 
722
  /* Copy over all the stabs symbols, omitting the ones we don't want,
723
     and correcting the string indices for those we do want.  */
724
  tosym = contents;
725
  symend = contents + stabsec->_raw_size;
726
  for (sym = contents, pstridx = secinfo->stridxs;
727
       sym < symend;
728
       sym += STABSIZE, ++pstridx)
729
    {
730
      if (*pstridx != (bfd_size_type) -1)
731
        {
732
          if (tosym != sym)
733
            memcpy (tosym, sym, STABSIZE);
734
          bfd_put_32 (output_bfd, *pstridx, tosym + STRDXOFF);
735
 
736
          if (sym[TYPEOFF] == 0)
737
            {
738
              /* This is the header symbol for the stabs section.  We
739
                 don't really need one, since we have merged all the
740
                 input stabs sections into one, but we generate one
741
                 for the benefit of readers which expect to see one.  */
742
              BFD_ASSERT (sym == contents);
743
              bfd_put_32 (output_bfd, _bfd_stringtab_size (sinfo->strings),
744
                          tosym + VALOFF);
745
              bfd_put_16 (output_bfd,
746
                          stabsec->output_section->_raw_size / STABSIZE - 1,
747
                          tosym + DESCOFF);
748
            }
749
 
750
          tosym += STABSIZE;
751
        }
752
    }
753
 
754
  BFD_ASSERT ((bfd_size_type) (tosym - contents) == stabsec->_cooked_size);
755
 
756
  return bfd_set_section_contents (output_bfd, stabsec->output_section,
757
                                   contents, (file_ptr) stabsec->output_offset,
758
                                   stabsec->_cooked_size);
759
}
760
 
761
/* Write out the .stabstr section.  */
762
 
763
boolean
764
_bfd_write_stab_strings (output_bfd, psinfo)
765
     bfd *output_bfd;
766
     PTR *psinfo;
767
{
768
  struct stab_info *sinfo;
769
 
770
  sinfo = (struct stab_info *) *psinfo;
771
 
772
  if (sinfo == NULL)
773
    return true;
774
 
775
  if (bfd_is_abs_section (sinfo->stabstr->output_section))
776
    {
777
      /* The section was discarded from the link.  */
778
      return true;
779
    }
780
 
781
  BFD_ASSERT ((sinfo->stabstr->output_offset
782
               + _bfd_stringtab_size (sinfo->strings))
783
              <= sinfo->stabstr->output_section->_raw_size);
784
 
785
  if (bfd_seek (output_bfd,
786
                (file_ptr) (sinfo->stabstr->output_section->filepos
787
                            + sinfo->stabstr->output_offset),
788
                SEEK_SET) != 0)
789
    return false;
790
 
791
  if (! _bfd_stringtab_emit (output_bfd, sinfo->strings))
792
    return false;
793
 
794
  /* We no longer need the stabs information.  */
795
  _bfd_stringtab_free (sinfo->strings);
796
  bfd_hash_table_free (&sinfo->includes.root);
797
 
798
  return true;
799
}
800
 
801
/* Adjust an address in the .stab section.  Given OFFSET within
802
   STABSEC, this returns the new offset in the adjusted stab section,
803
   or -1 if the address refers to a stab which has been removed.  */
804
 
805
bfd_vma
806
_bfd_stab_section_offset (output_bfd, psinfo, stabsec, psecinfo, offset)
807
     bfd *output_bfd ATTRIBUTE_UNUSED;
808
     PTR *psinfo ATTRIBUTE_UNUSED;
809
     asection *stabsec;
810
     PTR *psecinfo;
811
     bfd_vma offset;
812
{
813
  struct stab_section_info *secinfo;
814
 
815
  secinfo = (struct stab_section_info *) *psecinfo;
816
 
817
  if (secinfo == NULL)
818
    return offset;
819
 
820
  if (offset >= stabsec->_raw_size)
821
    return offset - (stabsec->_cooked_size - stabsec->_raw_size);
822
 
823
  if (secinfo->cumulative_skips)
824
    {
825
      bfd_vma i;
826
 
827
      i = offset / STABSIZE;
828
 
829
      if (secinfo->stridxs [i] == (bfd_size_type) -1)
830
        return (bfd_vma) -1;
831
 
832
      return offset - secinfo->cumulative_skips [i];
833
    }
834
 
835
  return offset;
836
}

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.