Coverage Report

Created: 2025-07-08 11:15

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