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