Coverage Report

Created: 2023-06-29 07:06

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