1/* xSYM symbol-file support for BFD.
2   Copyright (C) 1999-2020 Free Software Foundation, Inc.
3
4   This file is part of BFD, the Binary File Descriptor library.
5
6   This program is free software; you can redistribute it and/or modify
7   it under the terms of the GNU General Public License as published by
8   the Free Software Foundation; either version 3 of the License, or
9   (at your option) any later version.
10
11   This program is distributed in the hope that it will be useful,
12   but WITHOUT ANY WARRANTY; without even the implied warranty of
13   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14   GNU General Public License for more details.
15
16   You should have received a copy of the GNU General Public License
17   along with this program; if not, write to the Free Software
18   Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
19   MA 02110-1301, USA.  */
20
21/* xSYM is the debugging format used by CodeWarrior on Mac OS classic.  */
22
23#include "sysdep.h"
24#include "alloca-conf.h"
25#include "xsym.h"
26#include "bfd.h"
27#include "libbfd.h"
28
29#define bfd_sym_close_and_cleanup		    _bfd_generic_close_and_cleanup
30#define bfd_sym_bfd_free_cached_info		    _bfd_generic_bfd_free_cached_info
31#define bfd_sym_new_section_hook		    _bfd_generic_new_section_hook
32#define bfd_sym_bfd_is_local_label_name		    bfd_generic_is_local_label_name
33#define bfd_sym_bfd_is_target_special_symbol	    _bfd_bool_bfd_asymbol_false
34#define bfd_sym_get_lineno			    _bfd_nosymbols_get_lineno
35#define bfd_sym_find_nearest_line		    _bfd_nosymbols_find_nearest_line
36#define bfd_sym_find_line			    _bfd_nosymbols_find_line
37#define bfd_sym_find_inliner_info		    _bfd_nosymbols_find_inliner_info
38#define bfd_sym_get_symbol_version_string	    _bfd_nosymbols_get_symbol_version_string
39#define bfd_sym_bfd_make_debug_symbol		    _bfd_nosymbols_bfd_make_debug_symbol
40#define bfd_sym_read_minisymbols		    _bfd_generic_read_minisymbols
41#define bfd_sym_minisymbol_to_symbol		    _bfd_generic_minisymbol_to_symbol
42#define bfd_sym_set_arch_mach			    _bfd_generic_set_arch_mach
43#define bfd_sym_get_section_contents		    _bfd_generic_get_section_contents
44#define bfd_sym_set_section_contents		    _bfd_generic_set_section_contents
45#define bfd_sym_bfd_get_relocated_section_contents  bfd_generic_get_relocated_section_contents
46#define bfd_sym_bfd_relax_section		    bfd_generic_relax_section
47#define bfd_sym_bfd_gc_sections			    bfd_generic_gc_sections
48#define bfd_sym_bfd_lookup_section_flags	    bfd_generic_lookup_section_flags
49#define bfd_sym_bfd_merge_sections		    bfd_generic_merge_sections
50#define bfd_sym_bfd_is_group_section		    bfd_generic_is_group_section
51#define bfd_sym_bfd_group_name			    bfd_generic_group_name
52#define bfd_sym_bfd_discard_group		    bfd_generic_discard_group
53#define bfd_sym_section_already_linked		    _bfd_generic_section_already_linked
54#define bfd_sym_bfd_define_common_symbol	    bfd_generic_define_common_symbol
55#define bfd_sym_bfd_link_hide_symbol		    _bfd_generic_link_hide_symbol
56#define bfd_sym_bfd_define_start_stop		    bfd_generic_define_start_stop
57#define bfd_sym_bfd_link_hash_table_create	    _bfd_generic_link_hash_table_create
58#define bfd_sym_bfd_link_add_symbols		    _bfd_generic_link_add_symbols
59#define bfd_sym_bfd_link_just_syms		    _bfd_generic_link_just_syms
60#define bfd_sym_bfd_copy_link_hash_symbol_type \
61  _bfd_generic_copy_link_hash_symbol_type
62#define bfd_sym_bfd_final_link			    _bfd_generic_final_link
63#define bfd_sym_bfd_link_split_section		    _bfd_generic_link_split_section
64#define bfd_sym_get_section_contents_in_window	    _bfd_generic_get_section_contents_in_window
65#define bfd_sym_bfd_link_check_relocs		    _bfd_generic_link_check_relocs
66
67extern const bfd_target sym_vec;
68
69static int
70pstrcmp (const char *as, const char *bs)
71{
72  const unsigned char *a = (const unsigned char *) as;
73  const unsigned char *b = (const unsigned char *) bs;
74  unsigned char clen;
75  int ret;
76
77  clen = (a[0] > b[0]) ? b[0] : a[0];
78  ret = memcmp (a + 1, b + 1, clen);
79  if (ret != 0)
80    return ret;
81
82  if (a[0] == b[0])
83    return 0;
84  else if (a[0] < b[0])
85    return -1;
86  else
87    return 1;
88}
89
90static unsigned long
91compute_offset (unsigned long first_page,
92		unsigned long page_size,
93		unsigned long entry_size,
94		unsigned long sym_index)
95{
96  unsigned long entries_per_page = page_size / entry_size;
97  unsigned long page_number = first_page + (sym_index / entries_per_page);
98  unsigned long page_offset = (sym_index % entries_per_page) * entry_size;
99
100  return (page_number * page_size) + page_offset;
101}
102
103bfd_boolean
104bfd_sym_mkobject (bfd *abfd ATTRIBUTE_UNUSED)
105{
106  return 1;
107}
108
109void
110bfd_sym_print_symbol (bfd *abfd ATTRIBUTE_UNUSED,
111		      void * afile ATTRIBUTE_UNUSED,
112		      asymbol *symbol ATTRIBUTE_UNUSED,
113		      bfd_print_symbol_type how ATTRIBUTE_UNUSED)
114{
115  return;
116}
117
118bfd_boolean
119bfd_sym_valid (bfd *abfd)
120{
121  if (abfd == NULL || abfd->xvec == NULL)
122    return 0;
123
124  return abfd->xvec == &sym_vec;
125}
126
127unsigned char *
128bfd_sym_read_name_table (bfd *abfd, bfd_sym_header_block *dshb)
129{
130  size_t table_size = dshb->dshb_nte.dti_page_count * dshb->dshb_page_size;
131  size_t table_offset = dshb->dshb_nte.dti_first_page * dshb->dshb_page_size;
132
133  if (bfd_seek (abfd, table_offset, SEEK_SET) != 0)
134    return FALSE;
135  return _bfd_alloc_and_read (abfd, table_size, table_size);
136}
137
138void
139bfd_sym_parse_file_reference_v32 (unsigned char *buf,
140				  size_t len,
141				  bfd_sym_file_reference *entry)
142{
143  BFD_ASSERT (len == 6);
144
145  entry->fref_frte_index = bfd_getb16 (buf);
146  entry->fref_offset = bfd_getb32 (buf + 2);
147}
148
149void
150bfd_sym_parse_disk_table_v32 (unsigned char *buf,
151			      size_t len,
152			      bfd_sym_table_info *table)
153{
154  BFD_ASSERT (len == 8);
155
156  table->dti_first_page = bfd_getb16 (buf);
157  table->dti_page_count = bfd_getb16 (buf + 2);
158  table->dti_object_count = bfd_getb32 (buf + 4);
159}
160
161void
162bfd_sym_parse_header_v32 (unsigned char *buf,
163			  size_t len,
164			  bfd_sym_header_block *header)
165{
166  BFD_ASSERT (len == 154);
167
168  memcpy (header->dshb_id, buf, 32);
169  header->dshb_page_size = bfd_getb16 (buf + 32);
170  header->dshb_hash_page = bfd_getb16 (buf + 34);
171  header->dshb_root_mte = bfd_getb16 (buf + 36);
172  header->dshb_mod_date = bfd_getb32 (buf + 38);
173
174  bfd_sym_parse_disk_table_v32 (buf + 42, 8, &header->dshb_frte);
175  bfd_sym_parse_disk_table_v32 (buf + 50, 8, &header->dshb_rte);
176  bfd_sym_parse_disk_table_v32 (buf + 58, 8, &header->dshb_mte);
177  bfd_sym_parse_disk_table_v32 (buf + 66, 8, &header->dshb_cmte);
178  bfd_sym_parse_disk_table_v32 (buf + 74, 8, &header->dshb_cvte);
179  bfd_sym_parse_disk_table_v32 (buf + 82, 8, &header->dshb_csnte);
180  bfd_sym_parse_disk_table_v32 (buf + 90, 8, &header->dshb_clte);
181  bfd_sym_parse_disk_table_v32 (buf + 98, 8, &header->dshb_ctte);
182  bfd_sym_parse_disk_table_v32 (buf + 106, 8, &header->dshb_tte);
183  bfd_sym_parse_disk_table_v32 (buf + 114, 8, &header->dshb_nte);
184  bfd_sym_parse_disk_table_v32 (buf + 122, 8, &header->dshb_tinfo);
185  bfd_sym_parse_disk_table_v32 (buf + 130, 8, &header->dshb_fite);
186  bfd_sym_parse_disk_table_v32 (buf + 138, 8, &header->dshb_const);
187
188  memcpy (&header->dshb_file_creator, buf + 146, 4);
189  memcpy (&header->dshb_file_type, buf + 150, 4);
190}
191
192int
193bfd_sym_read_header_v32 (bfd *abfd, bfd_sym_header_block *header)
194{
195  unsigned char buf[154];
196  long ret;
197
198  ret = bfd_bread (buf, 154, abfd);
199  if (ret != 154)
200    return -1;
201
202  bfd_sym_parse_header_v32 (buf, 154, header);
203
204  return 0;
205}
206
207int
208bfd_sym_read_header_v34 (bfd *abfd ATTRIBUTE_UNUSED,
209			 bfd_sym_header_block *header ATTRIBUTE_UNUSED)
210{
211  abort ();
212}
213
214int
215bfd_sym_read_header (bfd *abfd,
216		     bfd_sym_header_block *header,
217		     bfd_sym_version version)
218{
219  switch (version)
220    {
221    case BFD_SYM_VERSION_3_5:
222    case BFD_SYM_VERSION_3_4:
223      return bfd_sym_read_header_v34 (abfd, header);
224    case BFD_SYM_VERSION_3_3:
225    case BFD_SYM_VERSION_3_2:
226      return bfd_sym_read_header_v32 (abfd, header);
227    case BFD_SYM_VERSION_3_1:
228    default:
229      return 0;
230    }
231}
232
233int
234bfd_sym_read_version (bfd *abfd, bfd_sym_version *version)
235{
236  char version_string[32];
237  long ret;
238
239  ret = bfd_bread (version_string, sizeof (version_string), abfd);
240  if (ret != sizeof (version_string))
241    return -1;
242
243  if (pstrcmp (version_string, BFD_SYM_VERSION_STR_3_1) == 0)
244    *version = BFD_SYM_VERSION_3_1;
245  else if (pstrcmp (version_string, BFD_SYM_VERSION_STR_3_2) == 0)
246    *version = BFD_SYM_VERSION_3_2;
247  else if (pstrcmp (version_string, BFD_SYM_VERSION_STR_3_3) == 0)
248    *version = BFD_SYM_VERSION_3_3;
249  else if (pstrcmp (version_string, BFD_SYM_VERSION_STR_3_4) == 0)
250    *version = BFD_SYM_VERSION_3_4;
251  else if (pstrcmp (version_string, BFD_SYM_VERSION_STR_3_5) == 0)
252    *version = BFD_SYM_VERSION_3_5;
253  else
254    return -1;
255
256  return 0;
257}
258
259void
260bfd_sym_display_table_summary (FILE *f,
261			       bfd_sym_table_info *dti,
262			       const char *name)
263{
264  fprintf (f, "%-6s %13ld %13ld %13ld\n",
265	   name,
266	   dti->dti_first_page,
267	   dti->dti_page_count,
268	   dti->dti_object_count);
269}
270
271void
272bfd_sym_display_header (FILE *f, bfd_sym_header_block *dshb)
273{
274  fprintf (f, "            Version: %.*s\n", dshb->dshb_id[0], dshb->dshb_id + 1);
275  fprintf (f, "          Page Size: 0x%x\n", dshb->dshb_page_size);
276  fprintf (f, "          Hash Page: %lu\n", dshb->dshb_hash_page);
277  fprintf (f, "           Root MTE: %lu\n", dshb->dshb_root_mte);
278  fprintf (f, "  Modification Date: ");
279  fprintf (f, "[unimplemented]");
280  fprintf (f, " (0x%lx)\n", dshb->dshb_mod_date);
281
282  fprintf (f, "       File Creator:  %.4s  Type: %.4s\n\n",
283	   dshb->dshb_file_creator, dshb->dshb_file_type);
284
285  fprintf (f, "Table Name   First Page    Page Count   Object Count\n");
286  fprintf (f, "~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n");
287
288  bfd_sym_display_table_summary (f, &dshb->dshb_nte, "NTE");
289  bfd_sym_display_table_summary (f, &dshb->dshb_rte, "RTE");
290  bfd_sym_display_table_summary (f, &dshb->dshb_mte, "MTE");
291  bfd_sym_display_table_summary (f, &dshb->dshb_frte, "FRTE");
292  bfd_sym_display_table_summary (f, &dshb->dshb_cmte, "CMTE");
293  bfd_sym_display_table_summary (f, &dshb->dshb_cvte, "CVTE");
294  bfd_sym_display_table_summary (f, &dshb->dshb_csnte, "CSNTE");
295  bfd_sym_display_table_summary (f, &dshb->dshb_clte, "CLTE");
296  bfd_sym_display_table_summary (f, &dshb->dshb_ctte, "CTTE");
297  bfd_sym_display_table_summary (f, &dshb->dshb_tte, "TTE");
298  bfd_sym_display_table_summary (f, &dshb->dshb_tinfo, "TINFO");
299  bfd_sym_display_table_summary (f, &dshb->dshb_fite, "FITE");
300  bfd_sym_display_table_summary (f, &dshb->dshb_const, "CONST");
301
302  fprintf (f, "\n");
303}
304
305void
306bfd_sym_parse_resources_table_entry_v32 (unsigned char *buf,
307					 size_t len,
308					 bfd_sym_resources_table_entry *entry)
309{
310  BFD_ASSERT (len == 18);
311
312  memcpy (&entry->rte_res_type, buf, 4);
313  entry->rte_res_number = bfd_getb16 (buf + 4);
314  entry->rte_nte_index = bfd_getb32 (buf + 6);
315  entry->rte_mte_first = bfd_getb16 (buf + 10);
316  entry->rte_mte_last = bfd_getb16 (buf + 12);
317  entry->rte_res_size = bfd_getb32 (buf + 14);
318}
319
320void
321bfd_sym_parse_modules_table_entry_v33 (unsigned char *buf,
322				       size_t len,
323				       bfd_sym_modules_table_entry *entry)
324{
325  BFD_ASSERT (len == 46);
326
327  entry->mte_rte_index = bfd_getb16 (buf);
328  entry->mte_res_offset = bfd_getb32 (buf + 2);
329  entry->mte_size = bfd_getb32 (buf + 6);
330  entry->mte_kind = buf[10];
331  entry->mte_scope = buf[11];
332  entry->mte_parent = bfd_getb16 (buf + 12);
333  bfd_sym_parse_file_reference_v32 (buf + 14, 6, &entry->mte_imp_fref);
334  entry->mte_imp_end = bfd_getb32 (buf + 20);
335  entry->mte_nte_index = bfd_getb32 (buf + 24);
336  entry->mte_cmte_index = bfd_getb16 (buf + 28);
337  entry->mte_cvte_index = bfd_getb32 (buf + 30);
338  entry->mte_clte_index = bfd_getb16 (buf + 34);
339  entry->mte_ctte_index = bfd_getb16 (buf + 36);
340  entry->mte_csnte_idx_1 = bfd_getb32 (buf + 38);
341  entry->mte_csnte_idx_2 = bfd_getb32 (buf + 42);
342}
343
344void
345bfd_sym_parse_file_references_table_entry_v32 (unsigned char *buf,
346					       size_t len,
347					       bfd_sym_file_references_table_entry *entry)
348{
349  unsigned int type;
350
351  BFD_ASSERT (len == 10);
352
353  memset (entry, 0, sizeof (bfd_sym_file_references_table_entry));
354  type = bfd_getb16 (buf);
355
356  switch (type)
357    {
358    case BFD_SYM_END_OF_LIST_3_2:
359      entry->generic.type = BFD_SYM_END_OF_LIST;
360      break;
361
362    case BFD_SYM_FILE_NAME_INDEX_3_2:
363      entry->filename.type = BFD_SYM_FILE_NAME_INDEX;
364      entry->filename.nte_index = bfd_getb32 (buf + 2);
365      entry->filename.mod_date = bfd_getb32 (buf + 6);
366      break;
367
368    default:
369      entry->entry.mte_index = type;
370      entry->entry.file_offset = bfd_getb32 (buf + 2);
371    }
372}
373
374void
375bfd_sym_parse_contained_modules_table_entry_v32 (unsigned char *buf,
376						 size_t len,
377						 bfd_sym_contained_modules_table_entry *entry)
378{
379  unsigned int type;
380
381  BFD_ASSERT (len == 6);
382
383  memset (entry, 0, sizeof (bfd_sym_contained_modules_table_entry));
384  type = bfd_getb16 (buf);
385
386  switch (type)
387    {
388    case BFD_SYM_END_OF_LIST_3_2:
389      entry->generic.type = BFD_SYM_END_OF_LIST;
390      break;
391
392    default:
393      entry->entry.mte_index = type;
394      entry->entry.nte_index = bfd_getb32 (buf + 2);
395      break;
396    }
397}
398
399void
400bfd_sym_parse_contained_variables_table_entry_v32 (unsigned char *buf,
401						   size_t len,
402						   bfd_sym_contained_variables_table_entry *entry)
403{
404  unsigned int type;
405
406  BFD_ASSERT (len == 26);
407
408  memset (entry, 0, sizeof (bfd_sym_contained_variables_table_entry));
409  type = bfd_getb16 (buf);
410
411  switch (type)
412    {
413    case BFD_SYM_END_OF_LIST_3_2:
414      entry->generic.type = BFD_SYM_END_OF_LIST;
415      break;
416
417    case BFD_SYM_SOURCE_FILE_CHANGE_3_2:
418      entry->file.type = BFD_SYM_SOURCE_FILE_CHANGE;
419      bfd_sym_parse_file_reference_v32 (buf + 2, 6, &entry->file.fref);
420      break;
421
422    default:
423      entry->entry.tte_index = type;
424      entry->entry.nte_index = bfd_getb32 (buf + 2);
425      entry->entry.file_delta = bfd_getb16 (buf + 6);
426      entry->entry.scope = buf[8];
427      entry->entry.la_size = buf[9];
428
429      if (entry->entry.la_size == BFD_SYM_CVTE_SCA)
430	{
431	  entry->entry.address.scstruct.sca_kind = buf[10];
432	  entry->entry.address.scstruct.sca_class = buf[11];
433	  entry->entry.address.scstruct.sca_offset = bfd_getb32 (buf + 12);
434	}
435      else if (entry->entry.la_size <= BFD_SYM_CVTE_SCA)
436	{
437#if BFD_SYM_CVTE_SCA > 0
438	  memcpy (&entry->entry.address.lastruct.la, buf + 10,
439		  BFD_SYM_CVTE_SCA);
440#endif
441	  entry->entry.address.lastruct.la_kind = buf[23];
442	}
443      else if (entry->entry.la_size == BFD_SYM_CVTE_BIG_LA)
444	{
445	  entry->entry.address.biglastruct.big_la = bfd_getb32 (buf + 10);
446	  entry->entry.address.biglastruct.big_la_kind = buf[12];
447	}
448    }
449}
450
451void
452bfd_sym_parse_contained_statements_table_entry_v32 (unsigned char *buf,
453						    size_t len,
454						    bfd_sym_contained_statements_table_entry *entry)
455{
456  unsigned int type;
457
458  BFD_ASSERT (len == 8);
459
460  memset (entry, 0, sizeof (bfd_sym_contained_statements_table_entry));
461  type = bfd_getb16 (buf);
462
463  switch (type)
464    {
465    case BFD_SYM_END_OF_LIST_3_2:
466      entry->generic.type = BFD_SYM_END_OF_LIST;
467      break;
468
469    case BFD_SYM_SOURCE_FILE_CHANGE_3_2:
470      entry->file.type = BFD_SYM_SOURCE_FILE_CHANGE;
471      bfd_sym_parse_file_reference_v32 (buf + 2, 6, &entry->file.fref);
472      break;
473
474    default:
475      entry->entry.mte_index = type;
476      entry->entry.mte_offset = bfd_getb16 (buf + 2);
477      entry->entry.file_delta = bfd_getb32 (buf + 4);
478      break;
479    }
480}
481
482void
483bfd_sym_parse_contained_labels_table_entry_v32 (unsigned char *buf,
484						size_t len,
485						bfd_sym_contained_labels_table_entry *entry)
486{
487  unsigned int type;
488
489  BFD_ASSERT (len == 12);
490
491  memset (entry, 0, sizeof (bfd_sym_contained_labels_table_entry));
492  type = bfd_getb16 (buf);
493
494  switch (type)
495    {
496    case BFD_SYM_END_OF_LIST_3_2:
497      entry->generic.type = BFD_SYM_END_OF_LIST;
498      break;
499
500    case BFD_SYM_SOURCE_FILE_CHANGE_3_2:
501      entry->file.type = BFD_SYM_SOURCE_FILE_CHANGE;
502      bfd_sym_parse_file_reference_v32 (buf + 2, 6, &entry->file.fref);
503      break;
504
505    default:
506      entry->entry.mte_index = type;
507      entry->entry.mte_offset = bfd_getb16 (buf + 2);
508      entry->entry.nte_index = bfd_getb32 (buf + 4);
509      entry->entry.file_delta = bfd_getb16 (buf + 8);
510      entry->entry.scope = bfd_getb16 (buf + 10);
511      break;
512    }
513}
514
515void
516bfd_sym_parse_type_table_entry_v32 (unsigned char *buf,
517				    size_t len,
518				    bfd_sym_type_table_entry *entry)
519{
520  BFD_ASSERT (len == 4);
521
522  *entry = bfd_getb32 (buf);
523}
524
525int
526bfd_sym_fetch_resources_table_entry (bfd *abfd,
527				     bfd_sym_resources_table_entry *entry,
528				     unsigned long sym_index)
529{
530  void (*parser) (unsigned char *, size_t, bfd_sym_resources_table_entry *);
531  unsigned long offset;
532  unsigned long entry_size;
533  unsigned char buf[18];
534  bfd_sym_data_struct *sdata = NULL;
535
536  parser = NULL;
537  BFD_ASSERT (bfd_sym_valid (abfd));
538  sdata = abfd->tdata.sym_data;
539
540  if (sym_index == 0)
541    return -1;
542
543  switch (sdata->version)
544    {
545    case BFD_SYM_VERSION_3_5:
546    case BFD_SYM_VERSION_3_4:
547      return -1;
548
549    case BFD_SYM_VERSION_3_3:
550    case BFD_SYM_VERSION_3_2:
551      entry_size = 18;
552      parser = bfd_sym_parse_resources_table_entry_v32;
553      break;
554
555    case BFD_SYM_VERSION_3_1:
556    default:
557      return -1;
558    }
559  if (parser == NULL)
560    return -1;
561
562  offset = compute_offset (sdata->header.dshb_rte.dti_first_page,
563			   sdata->header.dshb_page_size,
564			   entry_size, sym_index);
565
566  if (bfd_seek (abfd, offset, SEEK_SET) < 0)
567    return -1;
568  if (bfd_bread (buf, entry_size, abfd) != entry_size)
569    return -1;
570
571  (*parser) (buf, entry_size, entry);
572
573  return 0;
574}
575
576int
577bfd_sym_fetch_modules_table_entry (bfd *abfd,
578				   bfd_sym_modules_table_entry *entry,
579				   unsigned long sym_index)
580{
581  void (*parser) (unsigned char *, size_t, bfd_sym_modules_table_entry *);
582  unsigned long offset;
583  unsigned long entry_size;
584  unsigned char buf[46];
585  bfd_sym_data_struct *sdata = NULL;
586
587  parser = NULL;
588  BFD_ASSERT (bfd_sym_valid (abfd));
589  sdata = abfd->tdata.sym_data;
590
591  if (sym_index == 0)
592    return -1;
593
594  switch (sdata->version)
595    {
596    case BFD_SYM_VERSION_3_5:
597    case BFD_SYM_VERSION_3_4:
598      return -1;
599
600    case BFD_SYM_VERSION_3_3:
601      entry_size = 46;
602      parser = bfd_sym_parse_modules_table_entry_v33;
603      break;
604
605    case BFD_SYM_VERSION_3_2:
606    case BFD_SYM_VERSION_3_1:
607    default:
608      return -1;
609    }
610  if (parser == NULL)
611    return -1;
612
613  offset = compute_offset (sdata->header.dshb_mte.dti_first_page,
614			   sdata->header.dshb_page_size,
615			   entry_size, sym_index);
616
617  if (bfd_seek (abfd, offset, SEEK_SET) < 0)
618    return -1;
619  if (bfd_bread (buf, entry_size, abfd) != entry_size)
620    return -1;
621
622  (*parser) (buf, entry_size, entry);
623
624  return 0;
625}
626
627int
628bfd_sym_fetch_file_references_table_entry (bfd *abfd,
629					   bfd_sym_file_references_table_entry *entry,
630					   unsigned long sym_index)
631{
632  void (*parser) (unsigned char *, size_t, bfd_sym_file_references_table_entry *);
633  unsigned long offset;
634  unsigned long entry_size = 0;
635  unsigned char buf[8];
636  bfd_sym_data_struct *sdata = NULL;
637
638  parser = NULL;
639  BFD_ASSERT (bfd_sym_valid (abfd));
640  sdata = abfd->tdata.sym_data;
641
642  if (sym_index == 0)
643    return -1;
644
645  switch (sdata->version)
646    {
647    case BFD_SYM_VERSION_3_3:
648    case BFD_SYM_VERSION_3_2:
649      entry_size = 10;
650      parser = bfd_sym_parse_file_references_table_entry_v32;
651      break;
652
653    case BFD_SYM_VERSION_3_5:
654    case BFD_SYM_VERSION_3_4:
655    case BFD_SYM_VERSION_3_1:
656    default:
657      break;
658    }
659
660  if (parser == NULL)
661    return -1;
662
663  offset = compute_offset (sdata->header.dshb_frte.dti_first_page,
664			   sdata->header.dshb_page_size,
665			   entry_size, sym_index);
666
667  if (bfd_seek (abfd, offset, SEEK_SET) < 0)
668    return -1;
669  if (bfd_bread (buf, entry_size, abfd) != entry_size)
670    return -1;
671
672  (*parser) (buf, entry_size, entry);
673
674  return 0;
675}
676
677int
678bfd_sym_fetch_contained_modules_table_entry (bfd *abfd,
679					     bfd_sym_contained_modules_table_entry *entry,
680					     unsigned long sym_index)
681{
682  void (*parser) (unsigned char *, size_t, bfd_sym_contained_modules_table_entry *);
683  unsigned long offset;
684  unsigned long entry_size = 0;
685  unsigned char buf[6];
686  bfd_sym_data_struct *sdata = NULL;
687
688  parser = NULL;
689  BFD_ASSERT (bfd_sym_valid (abfd));
690  sdata = abfd->tdata.sym_data;
691
692  if (sym_index == 0)
693    return -1;
694
695  switch (sdata->version)
696    {
697    case BFD_SYM_VERSION_3_3:
698    case BFD_SYM_VERSION_3_2:
699      entry_size = 6;
700      parser = bfd_sym_parse_contained_modules_table_entry_v32;
701      break;
702
703    case BFD_SYM_VERSION_3_5:
704    case BFD_SYM_VERSION_3_4:
705    case BFD_SYM_VERSION_3_1:
706    default:
707      break;
708    }
709
710  if (parser == NULL)
711    return -1;
712
713  offset = compute_offset (sdata->header.dshb_cmte.dti_first_page,
714			   sdata->header.dshb_page_size,
715			   entry_size, sym_index);
716
717  if (bfd_seek (abfd, offset, SEEK_SET) < 0)
718    return -1;
719  if (bfd_bread (buf, entry_size, abfd) != entry_size)
720    return -1;
721
722  (*parser) (buf, entry_size, entry);
723
724  return 0;
725}
726
727int
728bfd_sym_fetch_contained_variables_table_entry (bfd *abfd,
729					       bfd_sym_contained_variables_table_entry *entry,
730					       unsigned long sym_index)
731{
732  void (*parser) (unsigned char *, size_t, bfd_sym_contained_variables_table_entry *);
733  unsigned long offset;
734  unsigned long entry_size = 0;
735  unsigned char buf[26];
736  bfd_sym_data_struct *sdata = NULL;
737
738  parser = NULL;
739  BFD_ASSERT (bfd_sym_valid (abfd));
740  sdata = abfd->tdata.sym_data;
741
742  if (sym_index == 0)
743    return -1;
744
745  switch (sdata->version)
746    {
747    case BFD_SYM_VERSION_3_3:
748    case BFD_SYM_VERSION_3_2:
749      entry_size = 26;
750      parser = bfd_sym_parse_contained_variables_table_entry_v32;
751      break;
752
753    case BFD_SYM_VERSION_3_5:
754    case BFD_SYM_VERSION_3_4:
755    case BFD_SYM_VERSION_3_1:
756    default:
757      break;
758    }
759
760  if (parser == NULL)
761    return -1;
762
763  offset = compute_offset (sdata->header.dshb_cvte.dti_first_page,
764			   sdata->header.dshb_page_size,
765			   entry_size, sym_index);
766
767  if (bfd_seek (abfd, offset, SEEK_SET) < 0)
768    return -1;
769  if (bfd_bread (buf, entry_size, abfd) != entry_size)
770    return -1;
771
772  (*parser) (buf, entry_size, entry);
773
774  return 0;
775}
776
777int
778bfd_sym_fetch_contained_statements_table_entry (bfd *abfd,
779						bfd_sym_contained_statements_table_entry *entry,
780						unsigned long sym_index)
781{
782  void (*parser) (unsigned char *, size_t, bfd_sym_contained_statements_table_entry *);
783  unsigned long offset;
784  unsigned long entry_size = 0;
785  unsigned char buf[8];
786  bfd_sym_data_struct *sdata = NULL;
787
788  parser = NULL;
789  BFD_ASSERT (bfd_sym_valid (abfd));
790  sdata = abfd->tdata.sym_data;
791
792  if (sym_index == 0)
793    return -1;
794
795  switch (sdata->version)
796    {
797    case BFD_SYM_VERSION_3_3:
798    case BFD_SYM_VERSION_3_2:
799      entry_size = 8;
800      parser = bfd_sym_parse_contained_statements_table_entry_v32;
801      break;
802
803    case BFD_SYM_VERSION_3_5:
804    case BFD_SYM_VERSION_3_4:
805    case BFD_SYM_VERSION_3_1:
806    default:
807      break;
808    }
809
810  if (parser == NULL)
811    return -1;
812
813  offset = compute_offset (sdata->header.dshb_csnte.dti_first_page,
814			   sdata->header.dshb_page_size,
815			   entry_size, sym_index);
816
817  if (bfd_seek (abfd, offset, SEEK_SET) < 0)
818    return -1;
819  if (bfd_bread (buf, entry_size, abfd) != entry_size)
820    return -1;
821
822  (*parser) (buf, entry_size, entry);
823
824  return 0;
825}
826
827int
828bfd_sym_fetch_contained_labels_table_entry (bfd *abfd,
829					    bfd_sym_contained_labels_table_entry *entry,
830					    unsigned long sym_index)
831{
832  void (*parser) (unsigned char *, size_t, bfd_sym_contained_labels_table_entry *);
833  unsigned long offset;
834  unsigned long entry_size = 0;
835  unsigned char buf[12];
836  bfd_sym_data_struct *sdata = NULL;
837
838  parser = NULL;
839  BFD_ASSERT (bfd_sym_valid (abfd));
840  sdata = abfd->tdata.sym_data;
841
842  if (sym_index == 0)
843    return -1;
844
845  switch (sdata->version)
846    {
847    case BFD_SYM_VERSION_3_3:
848    case BFD_SYM_VERSION_3_2:
849      entry_size = 12;
850      parser = bfd_sym_parse_contained_labels_table_entry_v32;
851      break;
852
853    case BFD_SYM_VERSION_3_5:
854    case BFD_SYM_VERSION_3_4:
855    case BFD_SYM_VERSION_3_1:
856    default:
857      break;
858    }
859
860  if (parser == NULL)
861    return -1;
862
863  offset = compute_offset (sdata->header.dshb_clte.dti_first_page,
864			   sdata->header.dshb_page_size,
865			   entry_size, sym_index);
866
867  if (bfd_seek (abfd, offset, SEEK_SET) < 0)
868    return -1;
869  if (bfd_bread (buf, entry_size, abfd) != entry_size)
870    return -1;
871
872  (*parser) (buf, entry_size, entry);
873
874  return 0;
875}
876
877int
878bfd_sym_fetch_contained_types_table_entry (bfd *abfd,
879					   bfd_sym_contained_types_table_entry *entry,
880					   unsigned long sym_index)
881{
882  void (*parser) (unsigned char *, size_t, bfd_sym_contained_types_table_entry *);
883  unsigned long offset;
884  unsigned long entry_size = 0;
885  unsigned char buf[0];
886  bfd_sym_data_struct *sdata = NULL;
887
888  parser = NULL;
889  BFD_ASSERT (bfd_sym_valid (abfd));
890  sdata = abfd->tdata.sym_data;
891
892  if (sym_index == 0)
893    return -1;
894
895  switch (sdata->version)
896    {
897    case BFD_SYM_VERSION_3_3:
898    case BFD_SYM_VERSION_3_2:
899      entry_size = 0;
900      parser = NULL;
901      break;
902
903    case BFD_SYM_VERSION_3_5:
904    case BFD_SYM_VERSION_3_4:
905    case BFD_SYM_VERSION_3_1:
906    default:
907      break;
908    }
909
910  if (parser == NULL)
911    return -1;
912
913  offset = compute_offset (sdata->header.dshb_ctte.dti_first_page,
914			   sdata->header.dshb_page_size,
915			   entry_size, sym_index);
916
917  if (bfd_seek (abfd, offset, SEEK_SET) < 0)
918    return -1;
919  if (bfd_bread (buf, entry_size, abfd) != entry_size)
920    return -1;
921
922  (*parser) (buf, entry_size, entry);
923
924  return 0;
925}
926
927int
928bfd_sym_fetch_file_references_index_table_entry (bfd *abfd,
929						 bfd_sym_file_references_index_table_entry *entry,
930						 unsigned long sym_index)
931{
932  void (*parser) (unsigned char *, size_t, bfd_sym_file_references_index_table_entry *);
933  unsigned long offset;
934  unsigned long entry_size = 0;
935  unsigned char buf[0];
936  bfd_sym_data_struct *sdata = NULL;
937
938  parser = NULL;
939  BFD_ASSERT (bfd_sym_valid (abfd));
940  sdata = abfd->tdata.sym_data;
941
942  if (sym_index == 0)
943    return -1;
944
945  switch (sdata->version)
946    {
947    case BFD_SYM_VERSION_3_3:
948    case BFD_SYM_VERSION_3_2:
949      entry_size = 0;
950      parser = NULL;
951      break;
952
953    case BFD_SYM_VERSION_3_5:
954    case BFD_SYM_VERSION_3_4:
955    case BFD_SYM_VERSION_3_1:
956    default:
957      break;
958    }
959
960  if (parser == NULL)
961    return -1;
962
963  offset = compute_offset (sdata->header.dshb_fite.dti_first_page,
964			   sdata->header.dshb_page_size,
965			   entry_size, sym_index);
966
967  if (bfd_seek (abfd, offset, SEEK_SET) < 0)
968    return -1;
969  if (bfd_bread (buf, entry_size, abfd) != entry_size)
970    return -1;
971
972  (*parser) (buf, entry_size, entry);
973
974  return 0;
975}
976
977int
978bfd_sym_fetch_constant_pool_entry (bfd *abfd,
979				   bfd_sym_constant_pool_entry *entry,
980				   unsigned long sym_index)
981{
982  void (*parser) (unsigned char *, size_t, bfd_sym_constant_pool_entry *);
983  unsigned long offset;
984  unsigned long entry_size = 0;
985  unsigned char buf[0];
986  bfd_sym_data_struct *sdata = NULL;
987
988  parser = NULL;
989  BFD_ASSERT (bfd_sym_valid (abfd));
990  sdata = abfd->tdata.sym_data;
991
992  if (sym_index == 0)
993    return -1;
994
995  switch (sdata->version)
996    {
997    case BFD_SYM_VERSION_3_3:
998    case BFD_SYM_VERSION_3_2:
999      entry_size = 0;
1000      parser = NULL;
1001      break;
1002
1003    case BFD_SYM_VERSION_3_5:
1004    case BFD_SYM_VERSION_3_4:
1005    case BFD_SYM_VERSION_3_1:
1006    default:
1007      break;
1008    }
1009
1010  if (parser == NULL)
1011    return -1;
1012
1013  offset = compute_offset (sdata->header.dshb_fite.dti_first_page,
1014			   sdata->header.dshb_page_size,
1015			   entry_size, sym_index);
1016
1017  if (bfd_seek (abfd, offset, SEEK_SET) < 0)
1018    return -1;
1019  if (bfd_bread (buf, entry_size, abfd) != entry_size)
1020    return -1;
1021
1022  (*parser) (buf, entry_size, entry);
1023
1024  return 0;
1025}
1026
1027int
1028bfd_sym_fetch_type_table_entry (bfd *abfd,
1029				bfd_sym_type_table_entry *entry,
1030				unsigned long sym_index)
1031{
1032  void (*parser) (unsigned char *, size_t, bfd_sym_type_table_entry *);
1033  unsigned long offset;
1034  unsigned long entry_size = 0;
1035  unsigned char buf[4];
1036  bfd_sym_data_struct *sdata = NULL;
1037
1038  parser = NULL;
1039  BFD_ASSERT (bfd_sym_valid (abfd));
1040  sdata = abfd->tdata.sym_data;
1041
1042  switch (sdata->version)
1043    {
1044    case BFD_SYM_VERSION_3_3:
1045    case BFD_SYM_VERSION_3_2:
1046      entry_size = 4;
1047      parser = bfd_sym_parse_type_table_entry_v32;
1048      break;
1049
1050    case BFD_SYM_VERSION_3_5:
1051    case BFD_SYM_VERSION_3_4:
1052    case BFD_SYM_VERSION_3_1:
1053    default:
1054      break;
1055    }
1056
1057  if (parser == NULL)
1058    return -1;
1059
1060  offset = compute_offset (sdata->header.dshb_tte.dti_first_page,
1061			   sdata->header.dshb_page_size,
1062			   entry_size, sym_index);
1063
1064  if (bfd_seek (abfd, offset, SEEK_SET) < 0)
1065    return -1;
1066  if (bfd_bread (buf, entry_size, abfd) != entry_size)
1067    return -1;
1068
1069  (*parser) (buf, entry_size, entry);
1070
1071  return 0;
1072}
1073
1074int
1075bfd_sym_fetch_type_information_table_entry (bfd *abfd,
1076					    bfd_sym_type_information_table_entry *entry,
1077					    unsigned long offset)
1078{
1079  unsigned char buf[4];
1080
1081  BFD_ASSERT (bfd_sym_valid (abfd));
1082
1083  if (offset == 0)
1084    return -1;
1085
1086  if (bfd_seek (abfd, offset, SEEK_SET) < 0)
1087    return -1;
1088
1089  if (bfd_bread (buf, 4, abfd) != 4)
1090    return -1;
1091  entry->nte_index = bfd_getb32 (buf);
1092
1093  if (bfd_bread (buf, 2, abfd) != 2)
1094    return -1;
1095  entry->physical_size = bfd_getb16 (buf);
1096
1097  if (entry->physical_size & 0x8000)
1098    {
1099      if (bfd_bread (buf, 4, abfd) != 4)
1100	return -1;
1101      entry->physical_size &= 0x7fff;
1102      entry->logical_size = bfd_getb32 (buf);
1103      entry->offset = offset + 10;
1104    }
1105  else
1106    {
1107      if (bfd_bread (buf, 2, abfd) != 2)
1108	return -1;
1109      entry->physical_size &= 0x7fff;
1110      entry->logical_size = bfd_getb16 (buf);
1111      entry->offset = offset + 8;
1112    }
1113
1114  return 0;
1115}
1116
1117int
1118bfd_sym_fetch_type_table_information (bfd *abfd,
1119				      bfd_sym_type_information_table_entry *entry,
1120				      unsigned long sym_index)
1121{
1122  bfd_sym_type_table_entry tindex;
1123  bfd_sym_data_struct *sdata = NULL;
1124
1125  BFD_ASSERT (bfd_sym_valid (abfd));
1126  sdata = abfd->tdata.sym_data;
1127
1128  if (sdata->header.dshb_tte.dti_object_count <= 99)
1129    return -1;
1130  if (sym_index < 100)
1131    return -1;
1132
1133  if (bfd_sym_fetch_type_table_entry (abfd, &tindex, sym_index - 100) < 0)
1134    return -1;
1135  if (bfd_sym_fetch_type_information_table_entry (abfd, entry, tindex) < 0)
1136    return -1;
1137
1138  return 0;
1139}
1140
1141const unsigned char *
1142bfd_sym_symbol_name (bfd *abfd, unsigned long sym_index)
1143{
1144  bfd_sym_data_struct *sdata = NULL;
1145
1146  BFD_ASSERT (bfd_sym_valid (abfd));
1147  sdata = abfd->tdata.sym_data;
1148
1149  if (sym_index == 0)
1150    return (const unsigned char *) "";
1151
1152  sym_index *= 2;
1153  if ((sym_index / sdata->header.dshb_page_size)
1154      > sdata->header.dshb_nte.dti_page_count)
1155    return (const unsigned char *) "\09[INVALID]";
1156
1157  return (const unsigned char *) sdata->name_table + sym_index;
1158}
1159
1160const unsigned char *
1161bfd_sym_module_name (bfd *abfd, unsigned long sym_index)
1162{
1163  bfd_sym_modules_table_entry entry;
1164
1165  if (bfd_sym_fetch_modules_table_entry (abfd, &entry, sym_index) < 0)
1166    return (const unsigned char *) "\09[INVALID]";
1167
1168  return bfd_sym_symbol_name (abfd, entry.mte_nte_index);
1169}
1170
1171const char *
1172bfd_sym_unparse_storage_kind (enum bfd_sym_storage_kind kind)
1173{
1174  switch (kind)
1175    {
1176    case BFD_SYM_STORAGE_KIND_LOCAL: return "LOCAL";
1177    case BFD_SYM_STORAGE_KIND_VALUE: return "VALUE";
1178    case BFD_SYM_STORAGE_KIND_REFERENCE: return "REFERENCE";
1179    case BFD_SYM_STORAGE_KIND_WITH: return "WITH";
1180    default: return "[UNKNOWN]";
1181    }
1182}
1183
1184const char *
1185bfd_sym_unparse_storage_class (enum bfd_sym_storage_class kind)
1186{
1187  switch (kind)
1188    {
1189    case BFD_SYM_STORAGE_CLASS_REGISTER: return "REGISTER";
1190    case BFD_SYM_STORAGE_CLASS_GLOBAL: return "GLOBAL";
1191    case BFD_SYM_STORAGE_CLASS_FRAME_RELATIVE: return "FRAME_RELATIVE";
1192    case BFD_SYM_STORAGE_CLASS_STACK_RELATIVE: return "STACK_RELATIVE";
1193    case BFD_SYM_STORAGE_CLASS_ABSOLUTE: return "ABSOLUTE";
1194    case BFD_SYM_STORAGE_CLASS_CONSTANT: return "CONSTANT";
1195    case BFD_SYM_STORAGE_CLASS_RESOURCE: return "RESOURCE";
1196    case BFD_SYM_STORAGE_CLASS_BIGCONSTANT: return "BIGCONSTANT";
1197    default: return "[UNKNOWN]";
1198    }
1199}
1200
1201const char *
1202bfd_sym_unparse_module_kind (enum bfd_sym_module_kind kind)
1203{
1204  switch (kind)
1205    {
1206    case BFD_SYM_MODULE_KIND_NONE: return "NONE";
1207    case BFD_SYM_MODULE_KIND_PROGRAM: return "PROGRAM";
1208    case BFD_SYM_MODULE_KIND_UNIT: return "UNIT";
1209    case BFD_SYM_MODULE_KIND_PROCEDURE: return "PROCEDURE";
1210    case BFD_SYM_MODULE_KIND_FUNCTION: return "FUNCTION";
1211    case BFD_SYM_MODULE_KIND_DATA: return "DATA";
1212    case BFD_SYM_MODULE_KIND_BLOCK: return "BLOCK";
1213    default: return "[UNKNOWN]";
1214    }
1215}
1216
1217const char *
1218bfd_sym_unparse_symbol_scope (enum bfd_sym_symbol_scope scope)
1219{
1220  switch (scope)
1221    {
1222    case BFD_SYM_SYMBOL_SCOPE_LOCAL: return "LOCAL";
1223    case BFD_SYM_SYMBOL_SCOPE_GLOBAL: return "GLOBAL";
1224    default:
1225      return "[UNKNOWN]";
1226    }
1227}
1228
1229void
1230bfd_sym_print_file_reference (bfd *abfd,
1231			      FILE *f,
1232			      bfd_sym_file_reference *entry)
1233{
1234  bfd_sym_file_references_table_entry frtentry;
1235  int ret;
1236
1237  ret = bfd_sym_fetch_file_references_table_entry (abfd, &frtentry,
1238						   entry->fref_frte_index);
1239  fprintf (f, "FILE ");
1240
1241  if ((ret < 0) || (frtentry.generic.type != BFD_SYM_FILE_NAME_INDEX))
1242    fprintf (f, "[INVALID]");
1243  else
1244    fprintf (f, "\"%.*s\"",
1245	     bfd_sym_symbol_name (abfd, frtentry.filename.nte_index)[0],
1246	     &bfd_sym_symbol_name (abfd, frtentry.filename.nte_index)[1]);
1247
1248  fprintf (f, " (FRTE %lu)", entry->fref_frte_index);
1249}
1250
1251void
1252bfd_sym_print_resources_table_entry (bfd *abfd,
1253				     FILE *f,
1254				     bfd_sym_resources_table_entry *entry)
1255{
1256  fprintf (f, " \"%.*s\" (NTE %lu), type \"%.4s\", num %u, size %lu, MTE %lu -- %lu",
1257	   bfd_sym_symbol_name (abfd, entry->rte_nte_index)[0],
1258	   &bfd_sym_symbol_name (abfd, entry->rte_nte_index)[1],
1259	   entry->rte_nte_index, entry->rte_res_type, entry->rte_res_number,
1260	   entry->rte_res_size, entry->rte_mte_first, entry->rte_mte_last);
1261}
1262
1263void
1264bfd_sym_print_modules_table_entry (bfd *abfd,
1265				   FILE *f,
1266				   bfd_sym_modules_table_entry *entry)
1267{
1268  fprintf (f, "\"%.*s\" (NTE %lu)",
1269	   bfd_sym_symbol_name (abfd, entry->mte_nte_index)[0],
1270	   &bfd_sym_symbol_name (abfd, entry->mte_nte_index)[1],
1271	   entry->mte_nte_index);
1272
1273  fprintf (f, "\n            ");
1274
1275  bfd_sym_print_file_reference (abfd, f, &entry->mte_imp_fref);
1276  fprintf (f, " range %lu -- %lu",
1277	   entry->mte_imp_fref.fref_offset, entry->mte_imp_end);
1278
1279  fprintf (f, "\n            ");
1280
1281  fprintf (f, "kind %s", bfd_sym_unparse_module_kind (entry->mte_kind));
1282  fprintf (f, ", scope %s", bfd_sym_unparse_symbol_scope (entry->mte_scope));
1283
1284  fprintf (f, ", RTE %lu, offset %lu, size %lu",
1285	   entry->mte_rte_index, entry->mte_res_offset, entry->mte_size);
1286
1287  fprintf (f, "\n            ");
1288
1289  fprintf (f, "CMTE %lu, CVTE %lu, CLTE %lu, CTTE %lu, CSNTE1 %lu, CSNTE2 %lu",
1290	   entry->mte_cmte_index, entry->mte_cvte_index,
1291	   entry->mte_clte_index, entry->mte_ctte_index,
1292	   entry->mte_csnte_idx_1, entry->mte_csnte_idx_2);
1293
1294  if (entry->mte_parent != 0)
1295    fprintf (f, ", parent %lu", entry->mte_parent);
1296  else
1297    fprintf (f, ", no parent");
1298
1299  if (entry->mte_cmte_index != 0)
1300    fprintf (f, ", child %lu", entry->mte_cmte_index);
1301  else
1302    fprintf (f, ", no child");
1303}
1304
1305void
1306bfd_sym_print_file_references_table_entry (bfd *abfd,
1307					   FILE *f,
1308					   bfd_sym_file_references_table_entry *entry)
1309{
1310  switch (entry->generic.type)
1311    {
1312    case BFD_SYM_FILE_NAME_INDEX:
1313      fprintf (f, "FILE \"%.*s\" (NTE %lu), modtime ",
1314	       bfd_sym_symbol_name (abfd, entry->filename.nte_index)[0],
1315	       &bfd_sym_symbol_name (abfd, entry->filename.nte_index)[1],
1316	       entry->filename.nte_index);
1317
1318      fprintf (f, "[UNIMPLEMENTED]");
1319      /* printModDate (entry->filename.mod_date); */
1320      fprintf (f, " (0x%lx)", entry->filename.mod_date);
1321      break;
1322
1323    case BFD_SYM_END_OF_LIST:
1324      fprintf (f, "END");
1325      break;
1326
1327    default:
1328      fprintf (f, "\"%.*s\" (MTE %lu), offset %lu",
1329	       bfd_sym_module_name (abfd, entry->entry.mte_index)[0],
1330	       &bfd_sym_module_name (abfd, entry->entry.mte_index)[1],
1331	       entry->entry.mte_index,
1332	       entry->entry.file_offset);
1333      break;
1334    }
1335}
1336
1337void
1338bfd_sym_print_contained_modules_table_entry (bfd *abfd,
1339					     FILE *f,
1340					     bfd_sym_contained_modules_table_entry *entry)
1341{
1342  switch (entry->generic.type)
1343    {
1344    case BFD_SYM_END_OF_LIST:
1345      fprintf (f, "END");
1346      break;
1347
1348    default:
1349      fprintf (f, "\"%.*s\" (MTE %lu, NTE %lu)",
1350	       bfd_sym_module_name (abfd, entry->entry.mte_index)[0],
1351	       &bfd_sym_module_name (abfd, entry->entry.mte_index)[1],
1352	       entry->entry.mte_index,
1353	       entry->entry.nte_index);
1354      break;
1355    }
1356}
1357
1358void
1359bfd_sym_print_contained_variables_table_entry (bfd *abfd,
1360					       FILE *f,
1361					       bfd_sym_contained_variables_table_entry *entry)
1362{
1363  if (entry->generic.type == BFD_SYM_END_OF_LIST)
1364    {
1365      fprintf (f, "END");
1366      return;
1367    }
1368
1369  if (entry->generic.type == BFD_SYM_SOURCE_FILE_CHANGE)
1370    {
1371      bfd_sym_print_file_reference (abfd, f, &entry->file.fref);
1372      fprintf (f, " offset %lu", entry->file.fref.fref_offset);
1373      return;
1374    }
1375
1376  fprintf (f, "\"%.*s\" (NTE %lu)",
1377	   bfd_sym_symbol_name (abfd, entry->entry.nte_index)[0],
1378	   &bfd_sym_symbol_name (abfd, entry->entry.nte_index)[1],
1379	   entry->entry.nte_index);
1380
1381  fprintf (f, ", TTE %lu", entry->entry.tte_index);
1382  fprintf (f, ", offset %lu", entry->entry.file_delta);
1383  fprintf (f, ", scope %s", bfd_sym_unparse_symbol_scope (entry->entry.scope));
1384
1385  if (entry->entry.la_size == BFD_SYM_CVTE_SCA)
1386    fprintf (f, ", latype %s, laclass %s, laoffset %lu",
1387	     bfd_sym_unparse_storage_kind (entry->entry.address.scstruct.sca_kind),
1388	     bfd_sym_unparse_storage_class (entry->entry.address.scstruct.sca_class),
1389	     entry->entry.address.scstruct.sca_offset);
1390  else if (entry->entry.la_size <= BFD_SYM_CVTE_LA_MAX_SIZE)
1391    {
1392      unsigned long i;
1393
1394      fprintf (f, ", la [");
1395      for (i = 0; i < entry->entry.la_size; i++)
1396	fprintf (f, "0x%02x ", entry->entry.address.lastruct.la[i]);
1397      fprintf (f, "]");
1398    }
1399  else if (entry->entry.la_size == BFD_SYM_CVTE_BIG_LA)
1400    fprintf (f, ", bigla %lu, biglakind %u",
1401	     entry->entry.address.biglastruct.big_la,
1402	     entry->entry.address.biglastruct.big_la_kind);
1403
1404  else
1405    fprintf (f, ", la [INVALID]");
1406}
1407
1408void
1409bfd_sym_print_contained_statements_table_entry (bfd *abfd,
1410						FILE *f,
1411						bfd_sym_contained_statements_table_entry *entry)
1412{
1413  if (entry->generic.type == BFD_SYM_END_OF_LIST)
1414    {
1415      fprintf (f, "END");
1416      return;
1417    }
1418
1419  if (entry->generic.type == BFD_SYM_SOURCE_FILE_CHANGE)
1420    {
1421      bfd_sym_print_file_reference (abfd, f, &entry->file.fref);
1422      fprintf (f, " offset %lu", entry->file.fref.fref_offset);
1423      return;
1424    }
1425
1426  fprintf (f, "\"%.*s\" (MTE %lu), offset %lu, delta %lu",
1427	   bfd_sym_module_name (abfd, entry->entry.mte_index)[0],
1428	   &bfd_sym_module_name (abfd, entry->entry.mte_index)[1],
1429	   entry->entry.mte_index,
1430	   entry->entry.mte_offset,
1431	   entry->entry.file_delta);
1432}
1433
1434void
1435bfd_sym_print_contained_labels_table_entry (bfd *abfd,
1436					    FILE *f,
1437					    bfd_sym_contained_labels_table_entry *entry)
1438{
1439  if (entry->generic.type == BFD_SYM_END_OF_LIST)
1440    {
1441      fprintf (f, "END");
1442      return;
1443    }
1444
1445  if (entry->generic.type == BFD_SYM_SOURCE_FILE_CHANGE)
1446    {
1447      bfd_sym_print_file_reference (abfd, f, &entry->file.fref);
1448      fprintf (f, " offset %lu", entry->file.fref.fref_offset);
1449      return;
1450    }
1451
1452  fprintf (f, "\"%.*s\" (MTE %lu), offset %lu, delta %lu, scope %s",
1453	   bfd_sym_module_name (abfd, entry->entry.mte_index)[0],
1454	   &bfd_sym_module_name (abfd, entry->entry.mte_index)[1],
1455	   entry->entry.mte_index,
1456	   entry->entry.mte_offset,
1457	   entry->entry.file_delta,
1458	   bfd_sym_unparse_symbol_scope (entry->entry.scope));
1459}
1460
1461void
1462bfd_sym_print_contained_types_table_entry (bfd *abfd ATTRIBUTE_UNUSED,
1463					   FILE *f,
1464					   bfd_sym_contained_types_table_entry *entry ATTRIBUTE_UNUSED)
1465{
1466  fprintf (f, "[UNIMPLEMENTED]");
1467}
1468
1469const char *
1470bfd_sym_type_operator_name (unsigned char num)
1471{
1472  switch (num)
1473    {
1474    case 1: return "TTE";
1475    case 2: return "PointerTo";
1476    case 3: return "ScalarOf";
1477    case 4: return "ConstantOf";
1478    case 5: return "EnumerationOf";
1479    case 6: return "VectorOf";
1480    case 7: return "RecordOf";
1481    case 8: return "UnionOf";
1482    case 9: return "SubRangeOf";
1483    case 10: return "SetOf";
1484    case 11: return "NamedTypeOf";
1485    case 12: return "ProcOf";
1486    case 13: return "ValueOf";
1487    case 14: return "ArrayOf";
1488    default: return "[UNKNOWN OPERATOR]";
1489    }
1490}
1491
1492const char *
1493bfd_sym_type_basic_name (unsigned char num)
1494{
1495  switch (num)
1496    {
1497    case 0: return "void";
1498    case 1: return "pascal string";
1499    case 2: return "unsigned long";
1500    case 3: return "signed long";
1501    case 4: return "extended (10 bytes)";
1502    case 5: return "pascal boolean (1 byte)";
1503    case 6: return "unsigned byte";
1504    case 7: return "signed byte";
1505    case 8: return "character (1 byte)";
1506    case 9: return "wide character (2 bytes)";
1507    case 10: return "unsigned short";
1508    case 11: return "signed short";
1509    case 12: return "singled";
1510    case 13: return "double";
1511    case 14: return "extended (12 bytes)";
1512    case 15: return "computational (8 bytes)";
1513    case 16: return "c string";
1514    case 17: return "as-is string";
1515    default: return "[UNKNOWN BASIC TYPE]";
1516    }
1517}
1518
1519int
1520bfd_sym_fetch_long (unsigned char *buf,
1521		    unsigned long len,
1522		    unsigned long offset,
1523		    unsigned long *offsetptr,
1524		    long *value)
1525{
1526  int ret;
1527
1528  if (offset >= len)
1529    {
1530      *value = 0;
1531      offset += 0;
1532      ret = -1;
1533    }
1534  else if (! (buf[offset] & 0x80))
1535    {
1536      *value = buf[offset];
1537      offset += 1;
1538      ret = 0;
1539    }
1540  else if (buf[offset] == 0xc0)
1541    {
1542      if ((offset + 5) > len)
1543	{
1544	  *value = 0;
1545	  offset = len;
1546	  ret = -1;
1547	}
1548      else
1549	{
1550	  *value = bfd_getb32 (buf + offset + 1);
1551	  offset += 5;
1552	  ret = 0;
1553	}
1554    }
1555  else if ((buf[offset] & 0xc0) == 0xc0)
1556    {
1557      *value =  -(buf[offset] & 0x3f);
1558      offset += 1;
1559      ret = 0;
1560    }
1561  else if ((buf[offset] & 0xc0) == 0x80)
1562    {
1563      if ((offset + 2) > len)
1564	{
1565	  *value = 0;
1566	  offset = len;
1567	  ret = -1;
1568	}
1569      else
1570	{
1571	  *value = bfd_getb16 (buf + offset) & 0x3fff;
1572	  offset += 2;
1573	  ret = 0;
1574	}
1575    }
1576  else
1577    abort ();
1578
1579  if (offsetptr != NULL)
1580    *offsetptr = offset;
1581
1582  return ret;
1583}
1584
1585void
1586bfd_sym_print_type_information (bfd *abfd,
1587				FILE *f,
1588				unsigned char *buf,
1589				unsigned long len,
1590				unsigned long offset,
1591				unsigned long *offsetptr)
1592{
1593  unsigned int type;
1594
1595  if (offset >= len)
1596    {
1597      fprintf (f, "[NULL]");
1598
1599      if (offsetptr != NULL)
1600	*offsetptr = offset;
1601      return;
1602  }
1603
1604  type = buf[offset];
1605  offset++;
1606
1607  if (! (type & 0x80))
1608    {
1609      fprintf (f, "[%s] (0x%x)", bfd_sym_type_basic_name (type & 0x7f), type);
1610
1611      if (offsetptr != NULL)
1612	*offsetptr = offset;
1613      return;
1614    }
1615
1616  if (type & 0x40)
1617    fprintf (f, "[packed ");
1618  else
1619    fprintf (f, "[");
1620
1621  switch (type & 0x3f)
1622    {
1623    case 1:
1624      {
1625	long value;
1626	bfd_sym_type_information_table_entry tinfo;
1627
1628	bfd_sym_fetch_long (buf, len, offset, &offset, &value);
1629	if (value <= 0)
1630	  fprintf (f, "[INVALID]");
1631	else
1632	  {
1633	    if (bfd_sym_fetch_type_table_information (abfd, &tinfo, value) < 0)
1634	      fprintf (f, "[INVALID]");
1635	    else
1636	      fprintf (f, "\"%.*s\"",
1637		       bfd_sym_symbol_name (abfd, tinfo.nte_index)[0],
1638		       &bfd_sym_symbol_name (abfd, tinfo.nte_index)[1]);
1639	  }
1640	fprintf (f, " (TTE %lu)", (unsigned long) value);
1641	break;
1642      }
1643
1644    case 2:
1645      fprintf (f, "pointer (0x%x) to ", type);
1646      bfd_sym_print_type_information (abfd, f, buf, len, offset, &offset);
1647      break;
1648
1649    case 3:
1650      {
1651	long value;
1652
1653	fprintf (f, "scalar (0x%x) of ", type);
1654	bfd_sym_print_type_information (abfd, f, buf, len, offset, &offset);
1655	bfd_sym_fetch_long (buf, len, offset, &offset, &value);
1656	fprintf (f, " (%lu)", (unsigned long) value);
1657	break;
1658      }
1659
1660    case 5:
1661      {
1662	long lower, upper, nelem;
1663	int i;
1664
1665	fprintf (f, "enumeration (0x%x) of ", type);
1666	bfd_sym_print_type_information (abfd, f, buf, len, offset, &offset);
1667	bfd_sym_fetch_long (buf, len, offset, &offset, &lower);
1668	bfd_sym_fetch_long (buf, len, offset, &offset, &upper);
1669	bfd_sym_fetch_long (buf, len, offset, &offset, &nelem);
1670	fprintf (f, " from %lu to %lu with %lu elements: ",
1671		 (unsigned long) lower, (unsigned long) upper,
1672		 (unsigned long) nelem);
1673
1674	for (i = 0; i < nelem; i++)
1675	  {
1676	    fprintf (f, "\n                    ");
1677	    bfd_sym_print_type_information (abfd, f, buf, len, offset, &offset);
1678	  }
1679	break;
1680      }
1681
1682    case 6:
1683      fprintf (f, "vector (0x%x)", type);
1684      fprintf (f, "\n                index ");
1685      bfd_sym_print_type_information (abfd, f, buf, len, offset, &offset);
1686      fprintf (f, "\n                target ");
1687      bfd_sym_print_type_information (abfd, f, buf, len, offset, &offset);
1688      break;
1689
1690    case 7:
1691    case 8:
1692      {
1693	long nrec, eloff, i;
1694
1695	if ((type & 0x3f) == 7)
1696	  fprintf (f, "record (0x%x) of ", type);
1697	else
1698	  fprintf (f, "union (0x%x) of ", type);
1699
1700	bfd_sym_fetch_long (buf, len, offset, &offset, &nrec);
1701	fprintf (f, "%lu elements: ", (unsigned long) nrec);
1702
1703	for (i = 0; i < nrec; i++)
1704	  {
1705	    bfd_sym_fetch_long (buf, len, offset, &offset, &eloff);
1706	    fprintf (f, "\n                ");
1707	    fprintf (f, "offset %lu: ", (unsigned long) eloff);
1708	    bfd_sym_print_type_information (abfd, f, buf, len, offset, &offset);
1709	  }
1710	break;
1711      }
1712
1713    case 9:
1714      fprintf (f, "subrange (0x%x) of ", type);
1715      bfd_sym_print_type_information (abfd, f, buf, len, offset, &offset);
1716      fprintf (f, " lower ");
1717      bfd_sym_print_type_information (abfd, f, buf, len, offset, &offset);
1718      fprintf (f, " upper ");
1719      bfd_sym_print_type_information (abfd, f, buf, len, offset, &offset);
1720      break;
1721
1722  case 11:
1723    {
1724      long value;
1725
1726      fprintf (f, "named type (0x%x) ", type);
1727      bfd_sym_fetch_long (buf, len, offset, &offset, &value);
1728      if (value <= 0)
1729	fprintf (f, "[INVALID]");
1730      else
1731	fprintf (f, "\"%.*s\"",
1732		 bfd_sym_symbol_name (abfd, value)[0],
1733		 &bfd_sym_symbol_name (abfd, value)[1]);
1734
1735      fprintf (f, " (NTE %lu) with type ", (unsigned long) value);
1736      bfd_sym_print_type_information (abfd, f, buf, len, offset, &offset);
1737      break;
1738    }
1739
1740  default:
1741    fprintf (f, "%s (0x%x)", bfd_sym_type_operator_name (type), type);
1742    break;
1743    }
1744
1745  if (type == (0x40 | 0x6))
1746    {
1747      /* Vector.  */
1748      long n, width, m;
1749      long l;
1750      long i;
1751
1752      bfd_sym_fetch_long (buf, len, offset, &offset, &n);
1753      bfd_sym_fetch_long (buf, len, offset, &offset, &width);
1754      bfd_sym_fetch_long (buf, len, offset, &offset, &m);
1755      /* fprintf (f, "\n                "); */
1756      fprintf (f, " N %ld, width %ld, M %ld, ", n, width, m);
1757      for (i = 0; i < m; i++)
1758	{
1759	  bfd_sym_fetch_long (buf, len, offset, &offset, &l);
1760	  if (i != 0)
1761	    fprintf (f, " ");
1762	  fprintf (f, "%ld", l);
1763	}
1764    }
1765  else  if (type & 0x40)
1766    {
1767      /* Other packed type.  */
1768      long msb, lsb;
1769
1770      bfd_sym_fetch_long (buf, len, offset, &offset, &msb);
1771      bfd_sym_fetch_long (buf, len, offset, &offset, &lsb);
1772      /* fprintf (f, "\n                "); */
1773      fprintf (f, " msb %ld, lsb %ld", msb, lsb);
1774    }
1775
1776  fprintf (f, "]");
1777
1778  if (offsetptr != NULL)
1779    *offsetptr = offset;
1780}
1781
1782void
1783bfd_sym_print_type_information_table_entry (bfd *abfd,
1784					    FILE *f,
1785					    bfd_sym_type_information_table_entry *entry)
1786{
1787  unsigned char *buf;
1788  unsigned long offset;
1789  unsigned int i;
1790
1791  fprintf (f, "\"%.*s\" (NTE %lu), %lu bytes at %lu, logical size %lu",
1792	   bfd_sym_symbol_name (abfd, entry->nte_index)[0],
1793	   &bfd_sym_symbol_name (abfd, entry->nte_index)[1],
1794	   entry->nte_index,
1795	   entry->physical_size, entry->offset, entry->logical_size);
1796
1797  fprintf (f, "\n            ");
1798
1799  if (bfd_seek (abfd, entry->offset, SEEK_SET) != 0
1800      || (buf = _bfd_malloc_and_read (abfd, entry->physical_size,
1801				      entry->physical_size)) == NULL)
1802    {
1803      fprintf (f, "[ERROR]\n");
1804      return;
1805    }
1806
1807  fprintf (f, "[");
1808  for (i = 0; i < entry->physical_size; i++)
1809    {
1810      if (i == 0)
1811	fprintf (f, "0x%02x", buf[i]);
1812      else
1813	fprintf (f, " 0x%02x", buf[i]);
1814    }
1815
1816  fprintf (f, "]");
1817  fprintf (f, "\n            ");
1818
1819  bfd_sym_print_type_information (abfd, f, buf, entry->physical_size, 0, &offset);
1820
1821  if (offset != entry->physical_size)
1822    fprintf (f, "\n            [parser used %lu bytes instead of %lu]", offset, entry->physical_size);
1823  free (buf);
1824}
1825
1826void
1827bfd_sym_print_file_references_index_table_entry (bfd *abfd ATTRIBUTE_UNUSED,
1828						 FILE *f,
1829						 bfd_sym_file_references_index_table_entry *entry ATTRIBUTE_UNUSED)
1830{
1831  fprintf (f, "[UNIMPLEMENTED]");
1832}
1833
1834void
1835bfd_sym_print_constant_pool_entry (bfd *abfd ATTRIBUTE_UNUSED,
1836				   FILE *f,
1837				   bfd_sym_constant_pool_entry *entry ATTRIBUTE_UNUSED)
1838{
1839  fprintf (f, "[UNIMPLEMENTED]");
1840}
1841
1842unsigned char *
1843bfd_sym_display_name_table_entry (bfd *abfd,
1844				  FILE *f,
1845				  unsigned char *entry)
1846{
1847  unsigned long sym_index;
1848  unsigned long offset;
1849  bfd_sym_data_struct *sdata = NULL;
1850
1851  BFD_ASSERT (bfd_sym_valid (abfd));
1852  sdata = abfd->tdata.sym_data;
1853  sym_index = (entry - sdata->name_table) / 2;
1854
1855  if (sdata->version >= BFD_SYM_VERSION_3_4 && entry[0] == 255 && entry[1] == 0)
1856    {
1857      unsigned short length = bfd_getb16 (entry + 2);
1858      fprintf (f, "[%8lu] \"%.*s\"\n", sym_index, length, entry + 4);
1859      offset = 2 + length + 1;
1860    }
1861  else
1862    {
1863      if (! (entry[0] == 0 || (entry[0] == 1 && entry[1] == '\0')))
1864	fprintf (f, "[%8lu] \"%.*s\"\n", sym_index, entry[0], entry + 1);
1865
1866      if (sdata->version >= BFD_SYM_VERSION_3_4)
1867	offset = entry[0] + 2;
1868      else
1869	offset = entry[0] + 1;
1870    }
1871
1872  return (entry + offset + (offset % 2));
1873}
1874
1875void
1876bfd_sym_display_name_table (bfd *abfd, FILE *f)
1877{
1878  unsigned long name_table_len;
1879  unsigned char *name_table, *name_table_end, *cur;
1880  bfd_sym_data_struct *sdata = NULL;
1881
1882  BFD_ASSERT (bfd_sym_valid (abfd));
1883  sdata = abfd->tdata.sym_data;
1884
1885  name_table_len = sdata->header.dshb_nte.dti_page_count * sdata->header.dshb_page_size;
1886  name_table = sdata->name_table;
1887  name_table_end = name_table + name_table_len;
1888
1889  fprintf (f, "name table (NTE) contains %lu bytes:\n\n", name_table_len);
1890
1891  cur = name_table;
1892  for (;;)
1893    {
1894      cur = bfd_sym_display_name_table_entry (abfd, f, cur);
1895      if (cur >= name_table_end)
1896	break;
1897    }
1898}
1899
1900void
1901bfd_sym_display_resources_table (bfd *abfd, FILE *f)
1902{
1903  unsigned long i;
1904  bfd_sym_resources_table_entry entry;
1905  bfd_sym_data_struct *sdata = NULL;
1906
1907  BFD_ASSERT (bfd_sym_valid (abfd));
1908  sdata = abfd->tdata.sym_data;
1909
1910  fprintf (f, "resource table (RTE) contains %lu objects:\n\n",
1911	   sdata->header.dshb_rte.dti_object_count);
1912
1913  for (i = 1; i <= sdata->header.dshb_rte.dti_object_count; i++)
1914    {
1915      if (bfd_sym_fetch_resources_table_entry (abfd, &entry, i) < 0)
1916	fprintf (f, " [%8lu] [INVALID]\n", i);
1917      else
1918	{
1919	  fprintf (f, " [%8lu] ", i);
1920	  bfd_sym_print_resources_table_entry (abfd, f, &entry);
1921	  fprintf (f, "\n");
1922	}
1923    }
1924}
1925
1926void
1927bfd_sym_display_modules_table (bfd *abfd, FILE *f)
1928{
1929  unsigned long i;
1930  bfd_sym_modules_table_entry entry;
1931  bfd_sym_data_struct *sdata = NULL;
1932
1933  BFD_ASSERT (bfd_sym_valid (abfd));
1934  sdata = abfd->tdata.sym_data;
1935
1936  fprintf (f, "module table (MTE) contains %lu objects:\n\n",
1937	   sdata->header.dshb_mte.dti_object_count);
1938
1939  for (i = 1; i <= sdata->header.dshb_mte.dti_object_count; i++)
1940    {
1941      if (bfd_sym_fetch_modules_table_entry (abfd, &entry, i) < 0)
1942	fprintf (f, " [%8lu] [INVALID]\n", i);
1943      else
1944	{
1945	  fprintf (f, " [%8lu] ", i);
1946	  bfd_sym_print_modules_table_entry (abfd, f, &entry);
1947	  fprintf (f, "\n");
1948	}
1949    }
1950}
1951
1952void
1953bfd_sym_display_file_references_table (bfd *abfd, FILE *f)
1954{
1955  unsigned long i;
1956  bfd_sym_file_references_table_entry entry;
1957  bfd_sym_data_struct *sdata = NULL;
1958
1959  BFD_ASSERT (bfd_sym_valid (abfd));
1960  sdata = abfd->tdata.sym_data;
1961
1962  fprintf (f, "file reference table (FRTE) contains %lu objects:\n\n",
1963	   sdata->header.dshb_frte.dti_object_count);
1964
1965  for (i = 1; i <= sdata->header.dshb_frte.dti_object_count; i++)
1966    {
1967      if (bfd_sym_fetch_file_references_table_entry (abfd, &entry, i) < 0)
1968	fprintf (f, " [%8lu] [INVALID]\n", i);
1969      else
1970	{
1971	  fprintf (f, " [%8lu] ", i);
1972	  bfd_sym_print_file_references_table_entry (abfd, f, &entry);
1973	  fprintf (f, "\n");
1974	}
1975    }
1976}
1977
1978void
1979bfd_sym_display_contained_modules_table (bfd *abfd, FILE *f)
1980{
1981  unsigned long i;
1982  bfd_sym_contained_modules_table_entry entry;
1983  bfd_sym_data_struct *sdata = NULL;
1984
1985  BFD_ASSERT (bfd_sym_valid (abfd));
1986  sdata = abfd->tdata.sym_data;
1987
1988  fprintf (f, "contained modules table (CMTE) contains %lu objects:\n\n",
1989	   sdata->header.dshb_cmte.dti_object_count);
1990
1991  for (i = 1; i <= sdata->header.dshb_cmte.dti_object_count; i++)
1992    {
1993      if (bfd_sym_fetch_contained_modules_table_entry (abfd, &entry, i) < 0)
1994	fprintf (f, " [%8lu] [INVALID]\n", i);
1995      else
1996	{
1997	  fprintf (f, " [%8lu] ", i);
1998	  bfd_sym_print_contained_modules_table_entry (abfd, f, &entry);
1999	  fprintf (f, "\n");
2000	}
2001    }
2002}
2003
2004void
2005bfd_sym_display_contained_variables_table (bfd *abfd, FILE *f)
2006{
2007  unsigned long i;
2008  bfd_sym_contained_variables_table_entry entry;
2009  bfd_sym_data_struct *sdata = NULL;
2010
2011  BFD_ASSERT (bfd_sym_valid (abfd));
2012  sdata = abfd->tdata.sym_data;
2013
2014  fprintf (f, "contained variables table (CVTE) contains %lu objects:\n\n",
2015	   sdata->header.dshb_cvte.dti_object_count);
2016
2017  for (i = 1; i <= sdata->header.dshb_cvte.dti_object_count; i++)
2018    {
2019      if (bfd_sym_fetch_contained_variables_table_entry (abfd, &entry, i) < 0)
2020	fprintf (f, " [%8lu] [INVALID]\n", i);
2021      else
2022	{
2023	  fprintf (f, " [%8lu] ", i);
2024	  bfd_sym_print_contained_variables_table_entry (abfd, f, &entry);
2025	  fprintf (f, "\n");
2026	}
2027    }
2028
2029  fprintf (f, "\n");
2030}
2031
2032void
2033bfd_sym_display_contained_statements_table (bfd *abfd, FILE *f)
2034{
2035  unsigned long i;
2036  bfd_sym_contained_statements_table_entry entry;
2037  bfd_sym_data_struct *sdata = NULL;
2038
2039  BFD_ASSERT (bfd_sym_valid (abfd));
2040  sdata = abfd->tdata.sym_data;
2041
2042  fprintf (f, "contained statements table (CSNTE) contains %lu objects:\n\n",
2043	   sdata->header.dshb_csnte.dti_object_count);
2044
2045  for (i = 1; i <= sdata->header.dshb_csnte.dti_object_count; i++)
2046    {
2047      if (bfd_sym_fetch_contained_statements_table_entry (abfd, &entry, i) < 0)
2048	fprintf (f, " [%8lu] [INVALID]\n", i);
2049      else
2050	{
2051	  fprintf (f, " [%8lu] ", i);
2052	  bfd_sym_print_contained_statements_table_entry (abfd, f, &entry);
2053	  fprintf (f, "\n");
2054	}
2055    }
2056}
2057
2058void
2059bfd_sym_display_contained_labels_table (bfd *abfd, FILE *f)
2060{
2061  unsigned long i;
2062  bfd_sym_contained_labels_table_entry entry;
2063  bfd_sym_data_struct *sdata = NULL;
2064
2065  BFD_ASSERT (bfd_sym_valid (abfd));
2066  sdata = abfd->tdata.sym_data;
2067
2068  fprintf (f, "contained labels table (CLTE) contains %lu objects:\n\n",
2069	   sdata->header.dshb_clte.dti_object_count);
2070
2071  for (i = 1; i <= sdata->header.dshb_clte.dti_object_count; i++)
2072    {
2073      if (bfd_sym_fetch_contained_labels_table_entry (abfd, &entry, i) < 0)
2074	fprintf (f, " [%8lu] [INVALID]\n", i);
2075      else
2076	{
2077	  fprintf (f, " [%8lu] ", i);
2078	  bfd_sym_print_contained_labels_table_entry (abfd, f, &entry);
2079	  fprintf (f, "\n");
2080	}
2081    }
2082}
2083
2084void
2085bfd_sym_display_contained_types_table (bfd *abfd, FILE *f)
2086{
2087  unsigned long i;
2088  bfd_sym_contained_types_table_entry entry;
2089  bfd_sym_data_struct *sdata = NULL;
2090
2091  BFD_ASSERT (bfd_sym_valid (abfd));
2092  sdata = abfd->tdata.sym_data;
2093
2094  fprintf (f, "contained types table (CTTE) contains %lu objects:\n\n",
2095	   sdata->header.dshb_ctte.dti_object_count);
2096
2097  for (i = 1; i <= sdata->header.dshb_ctte.dti_object_count; i++)
2098    {
2099      if (bfd_sym_fetch_contained_types_table_entry (abfd, &entry, i) < 0)
2100	fprintf (f, " [%8lu] [INVALID]\n", i);
2101      else
2102	{
2103	  fprintf (f, " [%8lu] ", i);
2104	  bfd_sym_print_contained_types_table_entry (abfd, f, &entry);
2105	  fprintf (f, "\n");
2106	}
2107    }
2108}
2109
2110void
2111bfd_sym_display_file_references_index_table (bfd *abfd, FILE *f)
2112{
2113  unsigned long i;
2114  bfd_sym_file_references_index_table_entry entry;
2115  bfd_sym_data_struct *sdata = NULL;
2116
2117  BFD_ASSERT (bfd_sym_valid (abfd));
2118  sdata = abfd->tdata.sym_data;
2119
2120  fprintf (f, "file references index table (FITE) contains %lu objects:\n\n",
2121	   sdata->header.dshb_fite.dti_object_count);
2122
2123  for (i = 1; i <= sdata->header.dshb_fite.dti_object_count; i++)
2124    {
2125      if (bfd_sym_fetch_file_references_index_table_entry (abfd, &entry, i) < 0)
2126	fprintf (f, " [%8lu] [INVALID]\n", i);
2127      else
2128	{
2129	  fprintf (f, " [%8lu] ", i);
2130	  bfd_sym_print_file_references_index_table_entry (abfd, f, &entry);
2131	  fprintf (f, "\n");
2132	}
2133    }
2134}
2135
2136void
2137bfd_sym_display_constant_pool (bfd *abfd, FILE *f)
2138{
2139  unsigned long i;
2140  bfd_sym_constant_pool_entry entry;
2141  bfd_sym_data_struct *sdata = NULL;
2142
2143  BFD_ASSERT (bfd_sym_valid (abfd));
2144  sdata = abfd->tdata.sym_data;
2145
2146  fprintf (f, "constant pool (CONST) contains %lu objects:\n\n",
2147	   sdata->header.dshb_const.dti_object_count);
2148
2149  for (i = 1; i <= sdata->header.dshb_const.dti_object_count; i++)
2150    {
2151      if (bfd_sym_fetch_constant_pool_entry (abfd, &entry, i) < 0)
2152	fprintf (f, " [%8lu] [INVALID]\n", i);
2153      else
2154	{
2155	  fprintf (f, " [%8lu] ", i);
2156	  bfd_sym_print_constant_pool_entry (abfd, f, &entry);
2157	  fprintf (f, "\n");
2158	}
2159    }
2160}
2161
2162void
2163bfd_sym_display_type_information_table (bfd *abfd, FILE *f)
2164{
2165  unsigned long i;
2166  bfd_sym_type_table_entry sym_index;
2167  bfd_sym_type_information_table_entry entry;
2168  bfd_sym_data_struct *sdata = NULL;
2169
2170  BFD_ASSERT (bfd_sym_valid (abfd));
2171  sdata = abfd->tdata.sym_data;
2172
2173  if (sdata->header.dshb_tte.dti_object_count > 99)
2174    fprintf (f, "type table (TINFO) contains %lu objects:\n\n",
2175	     sdata->header.dshb_tte.dti_object_count - 99);
2176  else
2177    {
2178      fprintf (f, "type table (TINFO) contains [INVALID] objects:\n\n");
2179      return;
2180    }
2181
2182  for (i = 100; i <= sdata->header.dshb_tte.dti_object_count; i++)
2183    {
2184      if (bfd_sym_fetch_type_table_entry (abfd, &sym_index, i - 100) < 0)
2185	fprintf (f, " [%8lu] [INVALID]\n", i);
2186      else
2187	{
2188	  fprintf (f, " [%8lu] (TINFO %lu) ", i, sym_index);
2189
2190	  if (bfd_sym_fetch_type_information_table_entry (abfd, &entry, sym_index) < 0)
2191	    fprintf (f, "[INVALID]");
2192	  else
2193	    bfd_sym_print_type_information_table_entry (abfd, f, &entry);
2194
2195	  fprintf (f, "\n");
2196	}
2197    }
2198}
2199
2200int
2201bfd_sym_scan (bfd *abfd, bfd_sym_version version, bfd_sym_data_struct *mdata)
2202{
2203  asection *bfdsec;
2204  const char *name = "symbols";
2205
2206  mdata->name_table = 0;
2207  mdata->sbfd = abfd;
2208  mdata->version = version;
2209
2210  bfd_seek (abfd, 0, SEEK_SET);
2211  if (bfd_sym_read_header (abfd, &mdata->header, mdata->version) != 0)
2212    return -1;
2213
2214  mdata->name_table = bfd_sym_read_name_table (abfd, &mdata->header);
2215  if (mdata->name_table == NULL)
2216    return -1;
2217
2218  bfdsec = bfd_make_section_anyway_with_flags (abfd, name, SEC_HAS_CONTENTS);
2219  if (bfdsec == NULL)
2220    return -1;
2221
2222  bfdsec->vma = 0;
2223  bfdsec->lma = 0;
2224  bfdsec->size = 0;
2225  bfdsec->filepos = 0;
2226  bfdsec->alignment_power = 0;
2227
2228  abfd->tdata.sym_data = mdata;
2229
2230  return 0;
2231}
2232
2233bfd_cleanup
2234bfd_sym_object_p (bfd *abfd)
2235{
2236  bfd_sym_version version = -1;
2237  bfd_sym_data_struct *mdata;
2238
2239  bfd_seek (abfd, 0, SEEK_SET);
2240  if (bfd_sym_read_version (abfd, &version) != 0)
2241    goto wrong;
2242
2243  mdata = (bfd_sym_data_struct *) bfd_alloc (abfd, sizeof (*mdata));
2244  if (mdata == NULL)
2245    goto fail;
2246
2247  if (bfd_sym_scan (abfd, version, mdata) != 0)
2248    goto wrong;
2249
2250  return _bfd_no_cleanup;
2251
2252 wrong:
2253  bfd_set_error (bfd_error_wrong_format);
2254
2255 fail:
2256  return NULL;
2257}
2258
2259#define bfd_sym_make_empty_symbol _bfd_generic_make_empty_symbol
2260
2261void
2262bfd_sym_get_symbol_info (bfd *abfd ATTRIBUTE_UNUSED, asymbol *symbol, symbol_info *ret)
2263{
2264  bfd_symbol_info (symbol, ret);
2265}
2266
2267long
2268bfd_sym_get_symtab_upper_bound (bfd *abfd ATTRIBUTE_UNUSED)
2269{
2270  return 0;
2271}
2272
2273long
2274bfd_sym_canonicalize_symtab (bfd *abfd ATTRIBUTE_UNUSED, asymbol **sym ATTRIBUTE_UNUSED)
2275{
2276  return 0;
2277}
2278
2279int
2280bfd_sym_sizeof_headers (bfd *abfd ATTRIBUTE_UNUSED,
2281			struct bfd_link_info *info ATTRIBUTE_UNUSED)
2282{
2283  return 0;
2284}
2285
2286const bfd_target sym_vec =
2287{
2288  "sym",			/* Name.  */
2289  bfd_target_sym_flavour,	/* Flavour.  */
2290  BFD_ENDIAN_BIG,		/* Byteorder.  */
2291  BFD_ENDIAN_BIG,		/* Header byteorder.  */
2292  (HAS_RELOC | EXEC_P |		/* Object flags.  */
2293   HAS_LINENO | HAS_DEBUG |
2294   HAS_SYMS | HAS_LOCALS | DYNAMIC | WP_TEXT | D_PAGED),
2295  (SEC_ALLOC | SEC_LOAD | SEC_READONLY | SEC_CODE | SEC_DATA
2296   | SEC_ROM | SEC_HAS_CONTENTS), /* Section_flags.  */
2297  0,				/* Symbol_leading_char.  */
2298  ' ',				/* AR_pad_char.  */
2299  16,				/* AR_max_namelen.  */
2300  0,				/* match priority.  */
2301  bfd_getb64, bfd_getb_signed_64, bfd_putb64,
2302  bfd_getb32, bfd_getb_signed_32, bfd_putb32,
2303  bfd_getb16, bfd_getb_signed_16, bfd_putb16,	/* Data.  */
2304  bfd_getb64, bfd_getb_signed_64, bfd_putb64,
2305  bfd_getb32, bfd_getb_signed_32, bfd_putb32,
2306  bfd_getb16, bfd_getb_signed_16, bfd_putb16,	/* Hdrs.  */
2307  {				/* bfd_check_format.  */
2308    _bfd_dummy_target,
2309    bfd_sym_object_p,		/* bfd_check_format.  */
2310    _bfd_dummy_target,
2311    _bfd_dummy_target,
2312  },
2313  {				/* bfd_set_format.  */
2314    _bfd_bool_bfd_false_error,
2315    bfd_sym_mkobject,
2316    _bfd_bool_bfd_false_error,
2317    _bfd_bool_bfd_false_error,
2318  },
2319  {				/* bfd_write_contents.  */
2320    _bfd_bool_bfd_false_error,
2321    _bfd_bool_bfd_true,
2322    _bfd_bool_bfd_false_error,
2323    _bfd_bool_bfd_false_error,
2324  },
2325
2326  BFD_JUMP_TABLE_GENERIC (bfd_sym),
2327  BFD_JUMP_TABLE_COPY (_bfd_generic),
2328  BFD_JUMP_TABLE_CORE (_bfd_nocore),
2329  BFD_JUMP_TABLE_ARCHIVE (_bfd_noarchive),
2330  BFD_JUMP_TABLE_SYMBOLS (bfd_sym),
2331  BFD_JUMP_TABLE_RELOCS (_bfd_norelocs),
2332  BFD_JUMP_TABLE_WRITE (bfd_sym),
2333  BFD_JUMP_TABLE_LINK (bfd_sym),
2334  BFD_JUMP_TABLE_DYNAMIC (_bfd_nodynamic),
2335
2336  NULL,
2337
2338  NULL
2339};
2340