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

Subversion Repositories or1k

[/] [or1k/] [trunk/] [gdb-5.0/] [bfd/] [ecofflink.c] - Blame information for rev 1765

Details | Compare with Previous | View Log

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

powered by: WebSVN 2.1.0

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