Coverage Report

Created: 2025-06-24 06:45

/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
2
{
1221
2
  HDRR * const symhdr = &debug->symbolic_header;
1222
2
  asymbol **sym_ptr_ptr;
1223
2
  size_t c;
1224
1225
2
  sym_ptr_ptr = bfd_get_outsymbols (abfd);
1226
2
  if (sym_ptr_ptr == NULL)
1227
0
    return true;
1228
1229
2
  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
2
  return true;
1276
2
}
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
78.9k
{
1709
78.9k
  if (!debug->alloc_syments)
1710
78.2k
    {
1711
78.2k
      free (debug->line);
1712
78.2k
      free (debug->external_dnr);
1713
78.2k
      free (debug->external_pdr);
1714
78.2k
      free (debug->external_sym);
1715
78.2k
      free (debug->external_opt);
1716
78.2k
      free (debug->external_aux);
1717
78.2k
      free (debug->ss);
1718
78.2k
      free (debug->ssext);
1719
78.2k
      free (debug->external_fdr);
1720
78.2k
      free (debug->external_rfd);
1721
78.2k
      free (debug->external_ext);
1722
78.2k
    }
1723
78.9k
  debug->line= NULL;
1724
78.9k
  debug->external_dnr= NULL;
1725
78.9k
  debug->external_pdr= NULL;
1726
78.9k
  debug->external_sym= NULL;
1727
78.9k
  debug->external_opt= NULL;
1728
78.9k
  debug->external_aux= NULL;
1729
78.9k
  debug->ss= NULL;
1730
78.9k
  debug->ssext= NULL;
1731
78.9k
  debug->external_fdr= NULL;
1732
78.9k
  debug->external_rfd= NULL;
1733
78.9k
  debug->external_ext= NULL;
1734
78.9k
}
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
11.2k
{
1741
11.2k
  const struct ecoff_fdrtab_entry *lp =
1742
11.2k
    (const struct ecoff_fdrtab_entry *) leftp;
1743
11.2k
  const struct ecoff_fdrtab_entry *rp =
1744
11.2k
    (const struct ecoff_fdrtab_entry *) rightp;
1745
1746
11.2k
  if (lp->base_addr < rp->base_addr)
1747
3.87k
    return -1;
1748
7.36k
  if (lp->base_addr > rp->base_addr)
1749
5.31k
    return 1;
1750
2.04k
  return 0;
1751
7.36k
}
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
599
{
1765
599
  struct ecoff_fdrtab_entry *tab;
1766
599
  FDR *fdr_ptr;
1767
599
  FDR *fdr_start;
1768
599
  FDR *fdr_end;
1769
599
  bool stabs;
1770
599
  size_t len;
1771
599
  size_t amt;
1772
1773
599
  fdr_start = debug_info->fdr;
1774
599
  fdr_end = fdr_start + debug_info->symbolic_header.ifdMax;
1775
1776
  /* First, let's see how long the table needs to be.  */
1777
59.6k
  for (len = 0, fdr_ptr = fdr_start; fdr_ptr < fdr_end; fdr_ptr++)
1778
59.0k
    {
1779
      /* Sanity check fdr procedure descriptor pointer.  */
1780
59.0k
      long ipdMax = debug_info->symbolic_header.ipdMax;
1781
59.0k
      if (fdr_ptr->ipdFirst >= ipdMax
1782
59.0k
    || fdr_ptr->cpd < 0
1783
59.0k
    || fdr_ptr->cpd > ipdMax - fdr_ptr->ipdFirst)
1784
33.3k
  fdr_ptr->cpd = 0;
1785
      /* Skip FDRs that have no PDRs.  */
1786
59.0k
      if (fdr_ptr->cpd == 0)
1787
53.1k
  continue;
1788
5.90k
      ++len;
1789
5.90k
    }
1790
1791
  /* Now, create and fill in the table.  */
1792
599
  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
599
  line_info->fdrtab = (struct ecoff_fdrtab_entry*) bfd_zalloc (abfd, amt);
1798
599
  if (line_info->fdrtab == NULL)
1799
0
    return false;
1800
1801
599
  tab = line_info->fdrtab;
1802
59.6k
  for (fdr_ptr = fdr_start; fdr_ptr < fdr_end; fdr_ptr++)
1803
59.0k
    {
1804
59.0k
      if (fdr_ptr->cpd == 0)
1805
53.1k
  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
5.90k
      stabs = false;
1811
5.90k
      if (fdr_ptr->csym >= 2)
1812
4.00k
  {
1813
4.00k
    char *sym_ptr;
1814
4.00k
    SYMR sym;
1815
1816
4.00k
    if ((long) ((unsigned long) fdr_ptr->isymBase + 1) <= 0
1817
4.00k
        || fdr_ptr->isymBase + 1 >= debug_info->symbolic_header.isymMax)
1818
2.28k
      continue;
1819
1820
1.72k
    sym_ptr = ((char *) debug_info->external_sym
1821
1.72k
         + (fdr_ptr->isymBase + 1) * debug_swap->external_sym_size);
1822
1.72k
    (*debug_swap->swap_sym_in) (abfd, sym_ptr, &sym);
1823
1.72k
    if (fdr_ptr->issBase >= 0
1824
1.72k
        && fdr_ptr->issBase < debug_info->symbolic_header.issMax
1825
1.72k
        && sym.iss >= 0
1826
1.72k
        && sym.iss < (debug_info->symbolic_header.issMax
1827
369
          - fdr_ptr->issBase)
1828
1.72k
        && strcmp (debug_info->ss + fdr_ptr->issBase + sym.iss,
1829
63
       STABS_SYMBOL) == 0)
1830
0
      stabs = true;
1831
1.72k
  }
1832
1833
3.62k
      if (!stabs)
1834
3.62k
  {
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
3.62k
    tab->base_addr = fdr_ptr->adr;
1846
3.62k
  }
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
3.62k
      tab->fdr = fdr_ptr;
1854
3.62k
      ++tab;
1855
3.62k
    }
1856
599
  len = tab - line_info->fdrtab;
1857
599
  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
599
  qsort (line_info->fdrtab, len,
1864
599
   sizeof (struct ecoff_fdrtab_entry), cmp_fdrtab_entry);
1865
1866
599
  return true;
1867
599
}
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
9.25k
{
1874
9.25k
  long low, high, len;
1875
9.25k
  long mid = -1;
1876
9.25k
  struct ecoff_fdrtab_entry *tab;
1877
1878
9.25k
  len = line_info->fdrtab_len;
1879
9.25k
  if (len == 0)
1880
1.17k
    return -1;
1881
1882
8.08k
  tab = line_info->fdrtab;
1883
15.3k
  for (low = 0, high = len - 1 ; low != high ;)
1884
10.8k
    {
1885
10.8k
      mid = (high + low) / 2;
1886
10.8k
      if (offset >= tab[mid].base_addr && offset < tab[mid + 1].base_addr)
1887
3.50k
  goto find_min;
1888
1889
7.31k
      if (tab[mid].base_addr > offset)
1890
3.29k
  high = mid;
1891
4.01k
      else
1892
4.01k
  low = mid + 1;
1893
7.31k
    }
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
4.57k
  ++mid;
1901
1902
  /* Last entry is catch-all for all higher addresses.  */
1903
4.57k
  if (offset < tab[mid].base_addr)
1904
835
    return -1;
1905
1906
7.24k
 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
8.18k
  while (mid > 0 && tab[mid - 1].base_addr == tab[mid].base_addr)
1911
937
    --mid;
1912
1913
7.24k
  return mid;
1914
4.57k
}
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
9.25k
{
1925
9.25k
  struct ecoff_fdrtab_entry *tab;
1926
9.25k
  bfd_vma offset;
1927
9.25k
  bool stabs;
1928
9.25k
  FDR *fdr_ptr;
1929
9.25k
  int i;
1930
1931
  /* eraxxon: note that 'offset' is the full vma, not a section offset.  */
1932
9.25k
  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
9.25k
  if (line_info->fdrtab == NULL
1937
9.25k
      && !mk_fdrtab (abfd, debug_info, debug_swap, line_info))
1938
0
    return false;
1939
1940
9.25k
  tab = line_info->fdrtab;
1941
1942
  /* Find first FDR for address OFFSET.  */
1943
9.25k
  i = fdrtab_lookup (line_info, offset);
1944
9.25k
  if (i < 0)
1945
2.00k
    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
7.24k
  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
7.24k
  stabs = false;
2022
7.24k
  if (fdr_ptr->csym >= 2)
2023
539
    {
2024
539
      char *sym_ptr;
2025
539
      SYMR sym;
2026
2027
539
      if ((long) ((unsigned long) fdr_ptr->isymBase + 1) > 0
2028
539
    && fdr_ptr->isymBase + 1 < debug_info->symbolic_header.isymMax)
2029
539
  {
2030
539
    sym_ptr = ((char *) debug_info->external_sym
2031
539
         + (fdr_ptr->isymBase + 1) * debug_swap->external_sym_size);
2032
539
    (*debug_swap->swap_sym_in) (abfd, sym_ptr, &sym);
2033
539
    if (fdr_ptr->issBase >= 0
2034
539
        && fdr_ptr->issBase < debug_info->symbolic_header.issMax
2035
539
        && sym.iss >= 0
2036
539
        && sym.iss < (debug_info->symbolic_header.issMax
2037
220
          - fdr_ptr->issBase)
2038
539
        && strcmp (debug_info->ss + fdr_ptr->issBase + sym.iss,
2039
88
       STABS_SYMBOL) == 0)
2040
0
      stabs = true;
2041
539
  }
2042
539
    }
2043
2044
7.24k
  line_info->cache.filename = NULL;
2045
7.24k
  line_info->cache.functionname = NULL;
2046
7.24k
  line_info->cache.line_num = 0;
2047
2048
7.24k
  if (!stabs)
2049
7.24k
    {
2050
7.24k
      bfd_size_type external_pdr_size;
2051
7.24k
      char *pdr_ptr;
2052
7.24k
      char *best_pdr = NULL;
2053
7.24k
      FDR *best_fdr;
2054
7.24k
      bfd_signed_vma best_dist = -1;
2055
7.24k
      PDR pdr;
2056
7.24k
      unsigned char *line_ptr;
2057
7.24k
      unsigned char *line_end;
2058
7.24k
      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
7.24k
      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
7.24k
      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
7.24k
      best_fdr = NULL;
2128
7.24k
      do
2129
29.3k
  {
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
29.3k
    bfd_signed_vma dist = -1, min_dist = -1;
2134
29.3k
    char *pdr_hold = NULL;
2135
29.3k
    char *pdr_end;
2136
2137
29.3k
    fdr_ptr = tab[i].fdr;
2138
2139
29.3k
    pdr_ptr = ((char *) debug_info->external_pdr
2140
29.3k
         + fdr_ptr->ipdFirst * external_pdr_size);
2141
29.3k
    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
1.13M
    for (; pdr_ptr < pdr_end; pdr_ptr += external_pdr_size)
2148
1.10M
      {
2149
1.10M
        (*debug_swap->swap_pdr_in) (abfd, pdr_ptr, &pdr);
2150
1.10M
        if (offset >= (pdr.adr - 0x10 * pdr.prof))
2151
440k
    {
2152
440k
      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
440k
      if (!pdr_hold || (dist >= 0 && dist < min_dist))
2157
44.6k
        {
2158
44.6k
          min_dist = dist;
2159
44.6k
          pdr_hold = pdr_ptr;
2160
44.6k
        }
2161
440k
    }
2162
1.10M
      }
2163
2164
29.3k
    if (!best_pdr || (min_dist >= 0 && min_dist < best_dist))
2165
13.0k
      {
2166
13.0k
        best_dist = (bfd_vma) min_dist;
2167
13.0k
        best_fdr = fdr_ptr;
2168
13.0k
        best_pdr = pdr_hold;
2169
13.0k
      }
2170
    /* Continue looping until base_addr of next entry is different.  */
2171
29.3k
  }
2172
      /* eraxxon: We want to iterate over all FDRs.
2173
   See previous comment about 'fdrtab_lookup'.  */
2174
29.3k
      while (++i < line_info->fdrtab_len);
2175
2176
7.24k
      if (!best_fdr || !best_pdr)
2177
547
  return false;      /* Shouldn't happen...  */
2178
2179
      /* Phew, finally we got something that we can hold onto.  */
2180
6.69k
      fdr_ptr = best_fdr;
2181
6.69k
      pdr_ptr = best_pdr;
2182
6.69k
      (*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
6.69k
      line_ptr = line_end = debug_info->line;
2188
6.69k
      if (fdr_ptr->cbLineOffset < debug_info->symbolic_header.cbLine
2189
6.69k
    && fdr_ptr->cbLine <= (debug_info->symbolic_header.cbLine
2190
2.49k
         - fdr_ptr->cbLineOffset)
2191
6.69k
    && pdr.cbLineOffset <= (debug_info->symbolic_header.cbLine
2192
1.95k
          - fdr_ptr->cbLineOffset))
2193
1.30k
  {
2194
1.30k
    line_end += fdr_ptr->cbLineOffset + fdr_ptr->cbLine;
2195
1.30k
    line_ptr += fdr_ptr->cbLineOffset + pdr.cbLineOffset;
2196
1.30k
  }
2197
2198
      /* Make offset relative to procedure entry.  */
2199
6.69k
      offset -= pdr.adr - 0x10 * pdr.prof;
2200
6.69k
      lineno = pdr.lnLow;
2201
42.3k
      while (line_ptr < line_end)
2202
36.2k
  {
2203
36.2k
    int delta;
2204
36.2k
    unsigned int count;
2205
2206
36.2k
    delta = *line_ptr >> 4;
2207
36.2k
    if (delta >= 0x8)
2208
11.7k
      delta -= 0x10;
2209
36.2k
    count = (*line_ptr & 0xf) + 1;
2210
36.2k
    ++line_ptr;
2211
36.2k
    if (delta == -8)
2212
1.52k
      {
2213
1.52k
        delta = (((line_ptr[0]) & 0xff) << 8) + ((line_ptr[1]) & 0xff);
2214
1.52k
        if (delta >= 0x8000)
2215
764
    delta -= 0x10000;
2216
1.52k
        line_ptr += 2;
2217
1.52k
      }
2218
36.2k
    lineno += delta;
2219
36.2k
    if (offset < count * 4)
2220
665
      {
2221
665
        line_info->cache.stop += count * 4 - offset;
2222
665
        break;
2223
665
      }
2224
35.6k
    offset -= count * 4;
2225
35.6k
  }
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
6.69k
      if (fdr_ptr->rss == -1)
2230
124
  {
2231
124
    EXTR proc_ext;
2232
2233
124
    if (pdr.isym >= 0
2234
124
        && pdr.isym < debug_info->symbolic_header.iextMax)
2235
47
      {
2236
47
        (*debug_swap->swap_ext_in)
2237
47
    (abfd, ((char *) debug_info->external_ext
2238
47
      + pdr.isym * debug_swap->external_ext_size),
2239
47
     &proc_ext);
2240
47
        if (proc_ext.asym.iss >= 0
2241
47
      && proc_ext.asym.iss < debug_info->symbolic_header.issExtMax)
2242
13
    line_info->cache.functionname = (debug_info->ssext
2243
13
             + proc_ext.asym.iss);
2244
47
      }
2245
124
  }
2246
6.57k
      else if (fdr_ptr->issBase >= 0
2247
6.57k
         && fdr_ptr->issBase < debug_info->symbolic_header.issMax
2248
6.57k
         && fdr_ptr->rss >= 0
2249
6.57k
         && fdr_ptr->rss < (debug_info->symbolic_header.issMax
2250
682
          - fdr_ptr->issBase))
2251
557
  {
2252
557
    SYMR proc_sym;
2253
2254
557
    line_info->cache.filename = (debug_info->ss
2255
557
               + fdr_ptr->issBase
2256
557
               + fdr_ptr->rss);
2257
557
    if (fdr_ptr->isymBase >= 0
2258
557
        && fdr_ptr->isymBase < debug_info->symbolic_header.isymMax
2259
557
        && pdr.isym >= 0
2260
557
        && pdr.isym < (debug_info->symbolic_header.isymMax
2261
448
           - fdr_ptr->isymBase))
2262
162
      {
2263
162
        (*debug_swap->swap_sym_in)
2264
162
    (abfd, ((char *) debug_info->external_sym
2265
162
      + ((fdr_ptr->isymBase + pdr.isym)
2266
162
         * debug_swap->external_sym_size)),
2267
162
     &proc_sym);
2268
162
        if (proc_sym.iss >= 0
2269
162
      && proc_sym.iss < (debug_info->symbolic_header.issMax
2270
146
             - fdr_ptr->issBase))
2271
50
    line_info->cache.functionname = (debug_info->ss
2272
50
             + fdr_ptr->issBase
2273
50
             + proc_sym.iss);
2274
162
      }
2275
557
  }
2276
6.69k
      if (lineno == ilineNil)
2277
256
  lineno = 0;
2278
6.69k
      line_info->cache.line_num = lineno;
2279
6.69k
    }
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
6.69k
  return true;
2469
7.24k
}
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
9.84k
{
2484
9.84k
  offset += section->vma;
2485
2486
9.84k
  if (line_info->cache.sect == NULL
2487
9.84k
      || line_info->cache.sect != section
2488
9.84k
      || offset < line_info->cache.start
2489
9.84k
      || offset >= line_info->cache.stop)
2490
9.25k
    {
2491
9.25k
      line_info->cache.sect = section;
2492
9.25k
      line_info->cache.start = offset;
2493
9.25k
      line_info->cache.stop = offset;
2494
9.25k
      if (! lookup_line (abfd, debug_info, debug_swap, line_info))
2495
2.55k
  {
2496
2.55k
    line_info->cache.sect = NULL;
2497
2.55k
    return false;
2498
2.55k
  }
2499
9.25k
    }
2500
2501
7.29k
  *filename_ptr = line_info->cache.filename;
2502
7.29k
  *functionname_ptr = line_info->cache.functionname;
2503
7.29k
  *retline_ptr = line_info->cache.line_num;
2504
2505
7.29k
  return true;
2506
9.84k
}
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
}