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