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

Subversion Repositories openrisc_me

[/] [openrisc/] [trunk/] [gnu-src/] [gdb-6.8/] [bfd/] [ecofflink.c] - Blame information for rev 247

Go to most recent revision | Details | Compare with Previous | View Log

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

powered by: WebSVN 2.1.0

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