* emultempl/pe.em (debug_section_p): New bfd_map_over_sections hook.
[binutils.git] / bfd / vms-hdr.c
blob6ad84ddd2a539beddaa001db79d710a4f0632289
1 /* vms-hdr.c -- BFD back-end for VMS/VAX (openVMS/VAX) and
2 EVAX (openVMS/Alpha) files.
3 Copyright 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2005, 2006,
4 2007, 2008, 2009 Free Software Foundation, Inc.
6 HDR record handling functions
7 EMH record handling functions
9 EOM record handling functions
10 EEOM record handling functions
12 IHD record handling functions
13 EIHD record handling functions
15 ISD record handling functions
16 EISD record handling functions
18 IHS record handling functions
19 EIHS record handling functions
21 DBG record handling functions
22 EDBG record handling functions
24 TBT record handling functions
25 ETBT record handling functions
27 DST/DMT section handling functions
29 Written by Klaus K"ampf (kkaempf@rmi.de)
31 This program is free software; you can redistribute it and/or modify
32 it under the terms of the GNU General Public License as published by
33 the Free Software Foundation; either version 3 of the License, or
34 (at your option) any later version.
36 This program is distributed in the hope that it will be useful,
37 but WITHOUT ANY WARRANTY; without even the implied warranty of
38 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
39 GNU General Public License for more details.
41 You should have received a copy of the GNU General Public License
42 along with this program; if not, write to the Free Software
43 Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
44 MA 02110-1301, USA. */
46 #include "sysdep.h"
47 #include "bfd.h"
48 #include "bfdver.h"
49 #include "bfdlink.h"
50 #include "safe-ctype.h"
51 #include "libbfd.h"
53 #include "vms.h"
55 #ifdef HAVE_ALLOCA_H
56 #include <alloca.h>
57 #endif
59 static struct module *new_module (bfd *);
60 static void parse_module
61 (bfd *, struct module *, unsigned char *, unsigned int);
62 static struct module *build_module_list (bfd *);
63 static bfd_boolean module_find_nearest_line
64 (bfd *, struct module *, bfd_vma, const char **, const char **,
65 unsigned int *);
66 static int vms_slurp_debug (bfd *);
68 #define SET_MODULE_PARSED(m) \
69 do { if ((m)->name == NULL) (m)->name = ""; } while (0)
70 #define IS_MODULE_PARSED(m) ((m)->name != NULL)
73 /* Read & process emh record
74 return 0 on success, -1 on error. */
76 int
77 _bfd_vms_slurp_hdr (bfd *abfd, int objtype)
79 unsigned char *ptr;
80 unsigned char *vms_rec;
81 int subtype;
83 vms_rec = PRIV(vms_rec);
85 #if VMS_DEBUG
86 vms_debug(2, "HDR/EMH\n");
87 #endif
89 switch (objtype)
91 case OBJ_S_C_HDR:
92 subtype = vms_rec[1];
93 break;
94 case EOBJ_S_C_EMH:
95 subtype = bfd_getl16 (vms_rec + 4) + EVAX_OFFSET;
96 break;
97 default:
98 subtype = -1;
101 #if VMS_DEBUG
102 vms_debug(3, "subtype %d\n", subtype);
103 #endif
105 switch (subtype)
107 case MHD_S_C_MHD:
108 /* Module header. */
109 PRIV (hdr_data).hdr_b_strlvl = vms_rec[2];
110 PRIV (hdr_data).hdr_l_recsiz = bfd_getl16 (vms_rec + 3);
111 PRIV (hdr_data).hdr_t_name = _bfd_vms_save_counted_string (vms_rec + 5);
112 ptr = vms_rec + 5 + vms_rec[5] + 1;
113 PRIV (hdr_data).hdr_t_version = _bfd_vms_save_counted_string (ptr);
114 ptr += *ptr + 1;
115 PRIV (hdr_data).hdr_t_date = _bfd_vms_save_sized_string (ptr, 17);
116 break;
118 case MHD_S_C_LNM:
119 PRIV (hdr_data).hdr_c_lnm = _bfd_vms_save_sized_string (vms_rec, PRIV (rec_size - 2));
120 break;
122 case MHD_S_C_SRC:
123 PRIV (hdr_data).hdr_c_src = _bfd_vms_save_sized_string (vms_rec, PRIV (rec_size - 2));
124 break;
126 case MHD_S_C_TTL:
127 PRIV (hdr_data).hdr_c_ttl = _bfd_vms_save_sized_string (vms_rec, PRIV (rec_size - 2));
128 break;
130 case EMH_S_C_MHD + EVAX_OFFSET:
131 /* Module header. */
132 PRIV (hdr_data).hdr_b_strlvl = vms_rec[6];
133 PRIV (hdr_data).hdr_l_arch1 = bfd_getl32 (vms_rec + 8);
134 PRIV (hdr_data).hdr_l_arch2 = bfd_getl32 (vms_rec + 12);
135 PRIV (hdr_data).hdr_l_recsiz = bfd_getl32 (vms_rec + 16);
136 PRIV (hdr_data).hdr_t_name = _bfd_vms_save_counted_string (vms_rec + 20);
137 ptr = vms_rec + 20 + vms_rec[20] + 1;
138 PRIV (hdr_data).hdr_t_version =_bfd_vms_save_counted_string (ptr);
139 ptr += *ptr + 1;
140 PRIV (hdr_data).hdr_t_date = _bfd_vms_save_sized_string (ptr, 17);
141 break;
143 case EMH_S_C_LNM + EVAX_OFFSET:
144 PRIV (hdr_data).hdr_c_lnm = _bfd_vms_save_sized_string (vms_rec, PRIV (rec_size - 6));
145 break;
147 case EMH_S_C_SRC + EVAX_OFFSET:
148 PRIV (hdr_data).hdr_c_src = _bfd_vms_save_sized_string (vms_rec, PRIV (rec_size - 6));
149 break;
151 case EMH_S_C_TTL + EVAX_OFFSET:
152 PRIV (hdr_data).hdr_c_ttl = _bfd_vms_save_sized_string (vms_rec, PRIV (rec_size - 6));
153 break;
155 case MHD_S_C_CPR:
156 case MHD_S_C_MTC:
157 case MHD_S_C_GTX:
158 case EMH_S_C_CPR + EVAX_OFFSET:
159 case EMH_S_C_MTC + EVAX_OFFSET:
160 case EMH_S_C_GTX + EVAX_OFFSET:
161 break;
163 default:
164 bfd_set_error (bfd_error_wrong_format);
165 return -1;
168 return 0;
171 /* Output routines. */
173 /* Manufacture a VMS like time on a unix based system.
174 stolen from obj-vms.c. */
176 static unsigned char *
177 get_vms_time_string (void)
179 static unsigned char tbuf[18];
180 #ifndef VMS
181 #include <time.h>
183 char *pnt;
184 time_t timeb;
186 time (& timeb);
187 pnt = ctime (&timeb);
188 pnt[3] = 0;
189 pnt[7] = 0;
190 pnt[10] = 0;
191 pnt[16] = 0;
192 pnt[24] = 0;
193 sprintf ((char *) tbuf, "%2s-%3s-%s %s",
194 pnt + 8, pnt + 4, pnt + 20, pnt + 11);
195 #else
196 #include <starlet.h>
197 struct
199 int Size;
200 unsigned char *Ptr;
201 } Descriptor;
202 Descriptor.Size = 17;
203 Descriptor.Ptr = tbuf;
204 SYS$ASCTIM (0, &Descriptor, 0, 0);
205 #endif /* not VMS */
207 #if VMS_DEBUG
208 vms_debug (6, "vmstimestring:'%s'\n", tbuf);
209 #endif
211 return tbuf;
214 /* Write object header for bfd abfd. */
217 _bfd_vms_write_hdr (bfd *abfd, int objtype)
219 asymbol *symbol;
220 unsigned int symnum;
221 int had_case = 0;
222 int had_file = 0;
223 char version [256];
225 #if VMS_DEBUG
226 vms_debug (2, "vms_write_hdr (%p)\n", abfd);
227 #endif
229 _bfd_vms_output_alignment (abfd, 2);
231 /* MHD. */
232 if (objtype != OBJ_S_C_HDR)
234 _bfd_vms_output_begin (abfd, EOBJ_S_C_EMH, EMH_S_C_MHD);
235 _bfd_vms_output_short (abfd, EOBJ_S_C_STRLVL);
236 _bfd_vms_output_long (abfd, 0);
237 _bfd_vms_output_long (abfd, 0);
238 _bfd_vms_output_long (abfd, MAX_OUTREC_SIZE);
241 if (bfd_get_filename (abfd) != 0)
243 /* Strip path and suffix information. */
244 char *fname, *fout, *fptr;
246 fptr = bfd_get_filename (abfd);
247 fname = strdup (fptr);
249 /* Strip VMS path. */
250 fout = strrchr (fname, ']');
251 if (fout == NULL)
252 fout = strchr (fname, ':');
253 if (fout != NULL)
254 fout++;
255 else
256 fout = fname;
258 /* Strip UNIX path. */
259 fptr = strrchr (fout, '/');
260 if (fptr != NULL)
261 fout = fptr + 1;
263 /* Strip .obj suffix. */
264 fptr = strrchr (fout, '.');
265 if (fptr != 0 && strcasecmp (fptr, ".OBJ") == 0)
266 *fptr = 0;
268 /* Convert to upper case and truncate at 31 characters.
269 (VMS object file format restricts module name length to 31). */
270 fptr = fout;
271 while (*fptr != 0)
273 *fptr = TOUPPER (*fptr);
274 fptr++;
275 if (*fptr == ';' || (fptr - fout) >= 31)
276 *fptr = 0;
278 _bfd_vms_output_counted (abfd, fout);
279 free (fname);
281 else
282 _bfd_vms_output_counted (abfd, "NONAME");
284 _bfd_vms_output_counted (abfd, BFD_VERSION_STRING);
285 _bfd_vms_output_dump (abfd, get_vms_time_string (), EMH_DATE_LENGTH);
286 _bfd_vms_output_fill (abfd, 0, EMH_DATE_LENGTH);
287 _bfd_vms_output_flush (abfd);
289 /* LMN. */
290 _bfd_vms_output_begin (abfd, EOBJ_S_C_EMH, EMH_S_C_LNM);
291 snprintf (version, sizeof (version), "GAS BFD v%s", BFD_VERSION_STRING);
292 _bfd_vms_output_dump (abfd, (unsigned char *)version, strlen (version));
293 _bfd_vms_output_flush (abfd);
295 /* SRC. */
296 _bfd_vms_output_begin (abfd, EOBJ_S_C_EMH, EMH_S_C_SRC);
298 for (symnum = 0; symnum < abfd->symcount; symnum++)
300 symbol = abfd->outsymbols[symnum];
302 if (symbol->flags & BSF_FILE)
304 if (CONST_STRNEQ ((char *)symbol->name, "<CASE:"))
306 PRIV (flag_hash_long_names) = symbol->name[6] - '0';
307 PRIV (flag_show_after_trunc) = symbol->name[7] - '0';
309 if (had_file)
310 break;
311 had_case = 1;
312 continue;
315 _bfd_vms_output_dump (abfd, (unsigned char *) symbol->name,
316 (int) strlen (symbol->name));
317 if (had_case)
318 break;
319 had_file = 1;
323 if (symnum == abfd->symcount)
324 _bfd_vms_output_dump (abfd, (unsigned char *) STRING_COMMA_LEN ("noname"));
326 _bfd_vms_output_flush (abfd);
328 /* TTL. */
329 _bfd_vms_output_begin (abfd, EOBJ_S_C_EMH, EMH_S_C_TTL);
330 _bfd_vms_output_dump (abfd, (unsigned char *) STRING_COMMA_LEN ("TTL"));
331 _bfd_vms_output_flush (abfd);
333 /* CPR. */
334 _bfd_vms_output_begin (abfd, EOBJ_S_C_EMH, EMH_S_C_CPR);
335 _bfd_vms_output_dump (abfd,
336 (unsigned char *)"GNU BFD ported by Klaus Kämpf 1994-1996",
337 39);
338 _bfd_vms_output_flush (abfd);
340 return 0;
343 /* Process EOM/EEOM record
344 return 0 on success, -1 on error. */
347 _bfd_vms_slurp_eom (bfd *abfd, int objtype)
349 unsigned char *vms_rec;
351 #if VMS_DEBUG
352 vms_debug(2, "EOM/EEOM\n");
353 #endif
355 vms_rec = PRIV (vms_rec);
357 if ((objtype == OBJ_S_C_EOM)
358 || (objtype == OBJ_S_C_EOMW))
361 else
363 PRIV (eom_data).eom_l_total_lps
364 = bfd_getl32 (vms_rec + EEOM_S_L_TOTAL_LPS);
365 PRIV (eom_data).eom_w_comcod = bfd_getl16 (vms_rec + EEOM_S_W_COMCOD);
366 if (PRIV (eom_data).eom_w_comcod > 1)
368 (*_bfd_error_handler) (_("Object module NOT error-free !\n"));
369 bfd_set_error (bfd_error_bad_value);
370 return -1;
372 PRIV (eom_data).eom_has_transfer = FALSE;
373 if (PRIV (rec_size) > 10)
375 PRIV (eom_data).eom_has_transfer = TRUE;
376 PRIV (eom_data).eom_b_tfrflg = vms_rec[EEOM_S_B_TFRFLG];
377 PRIV (eom_data).eom_l_psindx
378 = bfd_getl32 (vms_rec + EEOM_S_L_PSINDX);
379 PRIV (eom_data).eom_l_tfradr
380 = bfd_getl32 (vms_rec + EEOM_S_L_TFRADR);
382 abfd->start_address = PRIV (eom_data).eom_l_tfradr;
385 return 0;
388 /* Write eom record for bfd abfd. */
391 _bfd_vms_write_eom (bfd *abfd, int objtype)
393 #if VMS_DEBUG
394 vms_debug (2, "vms_write_eom (%p, %d)\n", abfd, objtype);
395 #endif
397 _bfd_vms_output_begin (abfd, objtype, -1);
398 _bfd_vms_output_long (abfd, (unsigned long) (PRIV (vms_linkage_index) >> 1));
399 _bfd_vms_output_byte (abfd, 0); /* Completion code. */
400 _bfd_vms_output_byte (abfd, 0); /* Fill byte. */
402 if (bfd_get_start_address (abfd) != (bfd_vma)-1)
404 asection *section;
406 section = bfd_get_section_by_name (abfd, ".link");
407 if (section == 0)
409 bfd_set_error (bfd_error_nonrepresentable_section);
410 return -1;
412 _bfd_vms_output_short (abfd, 0);
413 _bfd_vms_output_long (abfd, (unsigned long) (section->index));
414 _bfd_vms_output_long (abfd,
415 (unsigned long) bfd_get_start_address (abfd));
416 _bfd_vms_output_long (abfd, 0);
419 _bfd_vms_output_end (abfd);
420 return 0;
423 /* Read & process IHD/EIHD record.
424 Return 0 on success, -1 on error */
426 _bfd_vms_slurp_ihd (bfd *abfd, unsigned int *isd_offset,
427 unsigned int *ihs_offset)
429 unsigned int imgtype, size;
430 bfd_vma symvva;
432 #if VMS_DEBUG
433 vms_debug (8, "_bfd_vms_slurp_ihd\n");
434 #endif
436 size = bfd_getl32 (PRIV (vms_rec) + EIHD_S_L_SIZE);
437 imgtype = bfd_getl32 (PRIV (vms_rec) + EIHD_S_L_IMGTYPE);
439 if (imgtype == EIHD_S_K_EXE)
440 abfd->flags |= EXEC_P;
442 symvva = bfd_getl64 (PRIV (vms_rec) + EIHD_S_Q_SYMVVA);
443 if (symvva != 0)
445 PRIV (symvva) = symvva;
446 abfd->flags |= DYNAMIC;
449 *isd_offset = bfd_getl32 (PRIV (vms_rec) + EIHD_S_L_ISDOFF);
450 *ihs_offset = bfd_getl32 (PRIV (vms_rec) + EIHD_S_L_SYMDBGOFF);
452 #if VMS_DEBUG
453 vms_debug (4, "EIHD record size %d imgtype %d symvva 0x%llx isd %d ihs %d\n",
454 size, imgtype, symvva, *isd_offset, *ihs_offset);
455 #endif
457 return 0;
460 /* Read & process ISD/EISD record
461 return 0 on success, -1 on error */
464 _bfd_vms_slurp_isd (bfd *abfd, unsigned int offset)
466 int section_count = 0;
467 unsigned char *p;
468 unsigned int rec_size;
470 #if VMS_DEBUG
471 vms_debug (8, "_bfd_vms_slurp_isd\n");
472 #endif
474 for (p = PRIV (vms_rec) + offset;
475 (rec_size = bfd_getl32 (p + EISD_S_L_EISDSIZE)) != 0;
476 p += rec_size)
478 unsigned long long vaddr = bfd_getl64 (p + EISD_S_Q_VIR_ADDR);
479 unsigned int size = bfd_getl32 (p + EISD_S_L_SECSIZE);
480 unsigned int flags = bfd_getl32 (p + EISD_S_L_FLAGS);
481 unsigned int vbn = bfd_getl32 (p + EISD_S_L_VBN);
482 char *name = NULL;
483 asection *section;
484 flagword bfd_flags;
486 #if VMS_DEBUG
487 vms_debug (4, "EISD record at 0x%x size 0x%x addr 0x%x bfd_flags 0x%x block %d\n",
488 p - PRIV (vms_rec), size, vaddr, flags, vbn);
489 #endif
491 /* VMS combines psects from .obj files into isects in the .exe. This
492 process doesn't preserve enough information to reliably determine
493 what's in each section without examining the data. This is
494 especially true of DWARF debug sections. */
495 bfd_flags = SEC_ALLOC;
497 if (flags & EISD_S_M_EXE)
498 bfd_flags |= SEC_CODE | SEC_HAS_CONTENTS | SEC_LOAD;
500 if (flags & EISD_S_M_NONSHRADR)
501 bfd_flags |= SEC_DATA | SEC_HAS_CONTENTS | SEC_LOAD;
503 if (!(flags & EISD_S_M_WRT))
504 bfd_flags |= SEC_READONLY;
506 if (flags & EISD_S_M_DZRO)
507 bfd_flags |= SEC_DATA;
509 if (flags & EISD_S_M_FIXUPVEC)
510 bfd_flags |= SEC_DATA | SEC_HAS_CONTENTS | SEC_LOAD;
512 if (flags & EISD_S_M_CRF)
513 bfd_flags |= SEC_HAS_CONTENTS | SEC_LOAD;
515 if (flags & EISD_S_M_GBL)
517 name = _bfd_vms_save_counted_string (p + EISD_S_T_GBLNAM);
518 bfd_flags |= SEC_COFF_SHARED_LIBRARY;
519 bfd_flags &= ~(SEC_ALLOC | SEC_LOAD);
521 else
523 name = (char*) bfd_alloc (abfd, 32);
524 sprintf (name, "$LOCAL_%03d$", section_count++);
527 section = bfd_make_section (abfd, name);
529 if (!section)
530 return -1;
532 section->filepos = vbn ? VMS_BLOCK_SIZE * (vbn - 1) : (unsigned int)-1;
533 section->size = size;
534 section->vma = vaddr;
536 if (!bfd_set_section_flags (abfd, section, bfd_flags))
537 return -1;
540 return 0;
543 /* Read & process IHS/EIHS record
544 return 0 on success, -1 on error */
546 _bfd_vms_slurp_ihs (bfd *abfd, unsigned int offset)
548 unsigned char *p = PRIV (vms_rec) + offset;
549 unsigned int gstvbn = bfd_getl32 (p + EIHS_S_L_GSTVBN);
550 unsigned int gstsize ATTRIBUTE_UNUSED = bfd_getl32 (p + EIHS_S_L_GSTSIZE);
551 unsigned int dstvbn = bfd_getl32 (p + EIHS_S_L_DSTVBN);
552 unsigned int dstsize = bfd_getl32 (p + EIHS_S_L_DSTSIZE);
553 unsigned int dmtvbn = bfd_getl32 (p + EIHS_S_L_DMTVBN);
554 unsigned int dmtbytes = bfd_getl32 (p + EIHS_S_L_DMTBYTES);
555 asection *section;
557 #if VMS_DEBUG
558 vms_debug (8, "_bfd_vms_slurp_ihs\n");
559 vms_debug (4, "EIHS record gstvbn %d gstsize %d dstvbn %d dstsize %d dmtvbn %d dmtbytes %d\n",
560 gstvbn, gstsize, dstvbn, dstsize, dmtvbn, dmtbytes);
561 #endif
563 if (dstvbn)
565 flagword bfd_flags = SEC_HAS_CONTENTS | SEC_DEBUGGING;
567 section = bfd_make_section (abfd, "$DST$");
568 if (!section)
569 return -1;
571 section->size = dstsize;
572 section->filepos = VMS_BLOCK_SIZE * (dstvbn - 1);
574 if (!bfd_set_section_flags (abfd, section, bfd_flags))
575 return -1;
577 PRIV (dst_section) = section;
578 abfd->flags |= (HAS_DEBUG | HAS_LINENO);
581 if (dmtvbn)
583 flagword bfd_flags = SEC_HAS_CONTENTS | SEC_DEBUGGING;
585 section = bfd_make_section (abfd, "$DMT$");
586 if (!section)
587 return -1;
589 section->size = dmtbytes;
590 section->filepos = VMS_BLOCK_SIZE * (dmtvbn - 1);
592 if (!bfd_set_section_flags (abfd, section, bfd_flags))
593 return -1;
596 if (gstvbn)
598 flagword bfd_flags = SEC_HAS_CONTENTS;
600 section = bfd_make_section (abfd, "$GST$");
601 if (!section)
602 return -1;
604 if (bfd_seek (abfd, VMS_BLOCK_SIZE * (gstvbn - 1), SEEK_SET))
606 bfd_set_error (bfd_error_file_truncated);
607 return -1;
610 if (_bfd_vms_slurp_object_records (abfd) != 0)
611 return -1;
613 section->filepos = VMS_BLOCK_SIZE * (gstvbn - 1);
614 section->size = bfd_tell (abfd) - section->filepos;
616 if (!bfd_set_section_flags (abfd, section, bfd_flags))
617 return -1;
619 abfd->flags |= HAS_SYMS;
622 return 0;
625 /* Build a new module for the specified BFD. */
627 static struct module *
628 new_module (bfd *abfd)
630 struct module *module
631 = (struct module *) bfd_zalloc (abfd, sizeof (struct module));
632 module->file_table_count = 16; /* Arbitrary. */
633 module->file_table
634 = bfd_malloc (module->file_table_count * sizeof (struct fileinfo));
635 return module;
638 /* Parse debug info for a module and internalize it. */
640 static void
641 parse_module (bfd *abfd, struct module *module, unsigned char *ptr,
642 unsigned int length)
644 unsigned char *maxptr = ptr + length, *src_ptr, *pcl_ptr;
645 unsigned int prev_linum = 0, curr_linenum = 0;
646 bfd_vma prev_pc = 0, curr_pc = 0;
647 struct srecinfo *curr_srec, *srec;
648 struct lineinfo *curr_line, *line;
649 struct funcinfo *funcinfo;
651 /* Initialize tables with zero element. */
652 curr_srec = (struct srecinfo *) bfd_zalloc (abfd, sizeof (struct srecinfo));
653 module->srec_table = curr_srec;
655 curr_line = (struct lineinfo *) bfd_zalloc (abfd, sizeof (struct lineinfo));
656 module->line_table = curr_line;
658 while (ptr < maxptr)
660 /* The first byte is not counted in the recorded length. */
661 int rec_length = bfd_getl16 (ptr) + 1;
662 int rec_type = bfd_getl16 (ptr + 2);
664 #if VMS_DEBUG
665 _bfd_vms_debug (2, "DST record: length %d, type %d\n",
666 rec_length, rec_type);
667 #endif
669 switch (rec_type)
671 case DST_S_C_MODBEG:
672 module->name
673 = _bfd_vms_save_counted_string (ptr + DST_S_B_MODBEG_NAME);
675 curr_pc = 0;
676 prev_pc = 0;
677 curr_linenum = 0;
678 prev_linum = 0;
680 #if VMS_DEBUG
681 _bfd_vms_debug (3, "module: %s\n", module->name);
682 #endif
683 break;
685 case DST_S_C_MODEND:
686 #if VMS_DEBUG
687 _bfd_vms_debug (3, "end module\n");
688 #endif
689 break;
691 case DST_S_C_RTNBEG:
692 funcinfo = (struct funcinfo *)
693 bfd_zalloc (abfd, sizeof (struct funcinfo));
694 funcinfo->name
695 = _bfd_vms_save_counted_string (ptr + DST_S_B_RTNBEG_NAME);
696 funcinfo->low = bfd_getl32 (ptr + DST_S_L_RTNBEG_ADDRESS);
697 funcinfo->next = module->func_table;
698 module->func_table = funcinfo;
700 #if VMS_DEBUG
701 _bfd_vms_debug (3, "routine: %s at 0x%x\n",
702 funcinfo->name, funcinfo->low);
703 #endif
704 break;
706 case DST_S_C_RTNEND:
707 module->func_table->high = module->func_table->low
708 + bfd_getl32 (ptr + DST_S_L_RTNEND_SIZE) - 1;
710 if (module->func_table->high > module->high)
711 module->high = module->func_table->high;
713 #if VMS_DEBUG
714 _bfd_vms_debug (3, "end routine\n");
715 #endif
716 break;
718 case DST_S_C_PROLOG:
719 #if VMS_DEBUG
720 _bfd_vms_debug (3, "prologue\n");
721 #endif
722 break;
724 case DST_S_C_EPILOG:
725 #if VMS_DEBUG
726 _bfd_vms_debug (3, "epilog\n");
727 #endif
728 break;
730 case DST_S_C_BLKBEG:
731 #if VMS_DEBUG
732 _bfd_vms_debug (3, "block\n");
733 #endif
734 break;
736 case DST_S_C_BLKEND:
737 #if VMS_DEBUG
738 _bfd_vms_debug (3, "end block\n");
739 #endif
740 break;
742 case DST_S_C_SOURCE:
743 src_ptr = ptr + DST_S_C_SOURCE_HEADER_SIZE;
745 #if VMS_DEBUG
746 _bfd_vms_debug (3, "source info\n");
747 #endif
749 while (src_ptr < ptr + rec_length)
751 int cmd = src_ptr[0], cmd_length, data;
753 switch (cmd)
755 case DST_S_C_SRC_DECLFILE:
757 unsigned int fileid
758 = bfd_getl16 (src_ptr + DST_S_W_SRC_DF_FILEID);
759 char *filename
760 = _bfd_vms_save_counted_string (src_ptr
761 + DST_S_B_SRC_DF_FILENAME);
763 while (fileid >= module->file_table_count)
765 module->file_table_count *= 2;
766 module->file_table
767 = bfd_realloc (module->file_table,
768 module->file_table_count
769 * sizeof (struct fileinfo));
772 module->file_table [fileid].name = filename;
773 module->file_table [fileid].srec = 1;
774 cmd_length = src_ptr[DST_S_B_SRC_DF_LENGTH] + 2;
775 #if VMS_DEBUG
776 _bfd_vms_debug (4, "DST_S_C_SRC_DECLFILE: %d, %s\n",
777 fileid,
778 module->file_table [fileid].name);
779 #endif
781 break;
783 case DST_S_C_SRC_DEFLINES_B:
784 /* Perform the association and set the next higher index
785 to the limit. */
786 data = src_ptr[DST_S_B_SRC_UNSBYTE];
787 srec = (struct srecinfo *)
788 bfd_zalloc (abfd, sizeof (struct srecinfo));
789 srec->line = curr_srec->line + data;
790 srec->srec = curr_srec->srec + data;
791 srec->sfile = curr_srec->sfile;
792 curr_srec->next = srec;
793 curr_srec = srec;
794 cmd_length = 2;
795 #if VMS_DEBUG
796 _bfd_vms_debug (4, "DST_S_C_SRC_DEFLINES_B: %d\n", data);
797 #endif
798 break;
800 case DST_S_C_SRC_DEFLINES_W:
801 /* Perform the association and set the next higher index
802 to the limit. */
803 data = bfd_getl16 (src_ptr + DST_S_W_SRC_UNSWORD);
804 srec = (struct srecinfo *)
805 bfd_zalloc (abfd, sizeof (struct srecinfo));
806 srec->line = curr_srec->line + data;
807 srec->srec = curr_srec->srec + data,
808 srec->sfile = curr_srec->sfile;
809 curr_srec->next = srec;
810 curr_srec = srec;
811 cmd_length = 3;
812 #if VMS_DEBUG
813 _bfd_vms_debug (4, "DST_S_C_SRC_DEFLINES_W: %d\n", data);
814 #endif
815 break;
817 case DST_S_C_SRC_INCRLNUM_B:
818 data = src_ptr[DST_S_B_SRC_UNSBYTE];
819 curr_srec->line += data;
820 cmd_length = 2;
821 #if VMS_DEBUG
822 _bfd_vms_debug (4, "DST_S_C_SRC_INCRLNUM_B: %d\n", data);
823 #endif
824 break;
826 case DST_S_C_SRC_SETFILE:
827 data = bfd_getl16 (src_ptr + DST_S_W_SRC_UNSWORD);
828 curr_srec->sfile = data;
829 curr_srec->srec = module->file_table[data].srec;
830 cmd_length = 3;
831 #if VMS_DEBUG
832 _bfd_vms_debug (4, "DST_S_C_SRC_SETFILE: %d\n", data);
833 #endif
834 break;
836 case DST_S_C_SRC_SETLNUM_L:
837 data = bfd_getl32 (src_ptr + DST_S_L_SRC_UNSLONG);
838 curr_srec->line = data;
839 cmd_length = 5;
840 #if VMS_DEBUG
841 _bfd_vms_debug (4, "DST_S_C_SRC_SETLNUM_L: %d\n", data);
842 #endif
843 break;
845 case DST_S_C_SRC_SETLNUM_W:
846 data = bfd_getl16 (src_ptr + DST_S_W_SRC_UNSWORD);
847 curr_srec->line = data;
848 cmd_length = 3;
849 #if VMS_DEBUG
850 _bfd_vms_debug (4, "DST_S_C_SRC_SETLNUM_W: %d\n", data);
851 #endif
852 break;
854 case DST_S_C_SRC_SETREC_L:
855 data = bfd_getl32 (src_ptr + DST_S_L_SRC_UNSLONG);
856 curr_srec->srec = data;
857 module->file_table[curr_srec->sfile].srec = data;
858 cmd_length = 5;
859 #if VMS_DEBUG
860 _bfd_vms_debug (4, "DST_S_C_SRC_SETREC_L: %d\n", data);
861 #endif
862 break;
864 case DST_S_C_SRC_SETREC_W:
865 data = bfd_getl16 (src_ptr + DST_S_W_SRC_UNSWORD);
866 curr_srec->srec = data;
867 module->file_table[curr_srec->sfile].srec = data;
868 cmd_length = 3;
869 #if VMS_DEBUG
870 _bfd_vms_debug (4, "DST_S_C_SRC_SETREC_W: %d\n", data);
871 #endif
872 break;
874 case DST_S_C_SRC_FORMFEED:
875 cmd_length = 1;
876 #if VMS_DEBUG
877 _bfd_vms_debug (4, "DST_S_C_SRC_FORMFEED\n");
878 #endif
879 break;
881 default:
882 (*_bfd_error_handler) (_("unknown source command %d"),
883 cmd);
884 cmd_length = 2;
885 break;
888 src_ptr += cmd_length;
890 break;
892 case DST_S_C_LINE_NUM:
893 pcl_ptr = ptr + DST_S_C_LINE_NUM_HEADER_SIZE;
895 #if VMS_DEBUG
896 _bfd_vms_debug (3, "line info\n");
897 #endif
899 while (pcl_ptr < ptr + rec_length)
901 /* The command byte is signed so we must sign-extend it. */
902 int cmd = ((signed char *)pcl_ptr)[0], cmd_length, data;
904 switch (cmd)
906 case DST_S_C_DELTA_PC_W:
907 data = bfd_getl16 (pcl_ptr + DST_S_W_PCLINE_UNSWORD);
908 curr_pc += data;
909 curr_linenum += 1;
910 cmd_length = 3;
911 #if VMS_DEBUG
912 _bfd_vms_debug (4, "DST_S_C_DELTA_PC_W: %d\n", data);
913 #endif
914 break;
916 case DST_S_C_DELTA_PC_L:
917 data = bfd_getl32 (pcl_ptr + DST_S_L_PCLINE_UNSLONG);
918 curr_pc += data;
919 curr_linenum += 1;
920 cmd_length = 5;
921 #if VMS_DEBUG
922 _bfd_vms_debug (4, "DST_S_C_DELTA_PC_L: %d\n", data);
923 #endif
924 break;
926 case DST_S_C_INCR_LINUM:
927 data = pcl_ptr[DST_S_B_PCLINE_UNSBYTE];
928 curr_linenum += data;
929 cmd_length = 2;
930 #if VMS_DEBUG
931 _bfd_vms_debug (4, "DST_S_C_INCR_LINUM: %d\n", data);
932 #endif
933 break;
935 case DST_S_C_INCR_LINUM_W:
936 data = bfd_getl16 (pcl_ptr + DST_S_W_PCLINE_UNSWORD);
937 curr_linenum += data;
938 cmd_length = 3;
939 #if VMS_DEBUG
940 _bfd_vms_debug (4, "DST_S_C_INCR_LINUM_W: %d\n", data);
941 #endif
942 break;
944 case DST_S_C_INCR_LINUM_L:
945 data = bfd_getl32 (pcl_ptr + DST_S_L_PCLINE_UNSLONG);
946 curr_linenum += data;
947 cmd_length = 5;
948 #if VMS_DEBUG
949 _bfd_vms_debug (4, "DST_S_C_INCR_LINUM_L: %d\n", data);
950 #endif
951 break;
953 case DST_S_C_SET_LINUM_INCR:
954 (*_bfd_error_handler)
955 (_("DST_S_C_SET_LINUM_INCR not implemented"));
956 cmd_length = 2;
957 break;
959 case DST_S_C_SET_LINUM_INCR_W:
960 (*_bfd_error_handler)
961 (_("DST_S_C_SET_LINUM_INCR_W not implemented"));
962 cmd_length = 3;
963 break;
965 case DST_S_C_RESET_LINUM_INCR:
966 (*_bfd_error_handler)
967 (_("DST_S_C_RESET_LINUM_INCR not implemented"));
968 cmd_length = 1;
969 break;
971 case DST_S_C_BEG_STMT_MODE:
972 (*_bfd_error_handler)
973 (_("DST_S_C_BEG_STMT_MODE not implemented"));
974 cmd_length = 1;
975 break;
977 case DST_S_C_END_STMT_MODE:
978 (*_bfd_error_handler)
979 (_("DST_S_C_END_STMT_MODE not implemented"));
980 cmd_length = 1;
981 break;
983 case DST_S_C_SET_LINUM_B:
984 data = pcl_ptr[DST_S_B_PCLINE_UNSBYTE];
985 curr_linenum = data;
986 cmd_length = 2;
987 #if VMS_DEBUG
988 _bfd_vms_debug (4, "DST_S_C_SET_LINUM_B: %d\n", data);
989 #endif
990 break;
992 case DST_S_C_SET_LINE_NUM:
993 data = bfd_getl16 (pcl_ptr + DST_S_W_PCLINE_UNSWORD);
994 curr_linenum = data;
995 cmd_length = 3;
996 #if VMS_DEBUG
997 _bfd_vms_debug (4, "DST_S_C_SET_LINE_NUM: %d\n", data);
998 #endif
999 break;
1001 case DST_S_C_SET_LINUM_L:
1002 data = bfd_getl32 (pcl_ptr + DST_S_L_PCLINE_UNSLONG);
1003 curr_linenum = data;
1004 cmd_length = 5;
1005 #if VMS_DEBUG
1006 _bfd_vms_debug (4, "DST_S_C_SET_LINUM_L: %d\n", data);
1007 #endif
1008 break;
1010 case DST_S_C_SET_PC:
1011 (*_bfd_error_handler)
1012 (_("DST_S_C_SET_PC not implemented"));
1013 cmd_length = 2;
1014 break;
1016 case DST_S_C_SET_PC_W:
1017 (*_bfd_error_handler)
1018 (_("DST_S_C_SET_PC_W not implemented"));
1019 cmd_length = 3;
1020 break;
1022 case DST_S_C_SET_PC_L:
1023 (*_bfd_error_handler)
1024 (_("DST_S_C_SET_PC_L not implemented"));
1025 cmd_length = 5;
1026 break;
1028 case DST_S_C_SET_STMTNUM:
1029 (*_bfd_error_handler)
1030 (_("DST_S_C_SET_STMTNUM not implemented"));
1031 cmd_length = 2;
1032 break;
1034 case DST_S_C_TERM:
1035 data = pcl_ptr[DST_S_B_PCLINE_UNSBYTE];
1036 curr_pc += data;
1037 cmd_length = 2;
1038 #if VMS_DEBUG
1039 _bfd_vms_debug (4, "DST_S_C_TERM: %d\n", data);
1040 #endif
1041 break;
1043 case DST_S_C_TERM_W:
1044 data = bfd_getl16 (pcl_ptr + DST_S_W_PCLINE_UNSWORD);
1045 curr_pc += data;
1046 cmd_length = 3;
1047 #if VMS_DEBUG
1048 _bfd_vms_debug (4, "DST_S_C_TERM_W: %d\n", data);
1049 #endif
1050 break;
1052 case DST_S_C_TERM_L:
1053 data = bfd_getl32 (pcl_ptr + DST_S_L_PCLINE_UNSLONG);
1054 curr_pc += data;
1055 cmd_length = 5;
1056 #if VMS_DEBUG
1057 _bfd_vms_debug (4, "DST_S_C_TERM_L: %d\n", data);
1058 #endif
1059 break;
1061 case DST_S_C_SET_ABS_PC:
1062 data = bfd_getl32 (pcl_ptr + DST_S_L_PCLINE_UNSLONG);
1063 curr_pc = data;
1064 cmd_length = 5;
1065 #if VMS_DEBUG
1066 _bfd_vms_debug (4, "DST_S_C_SET_ABS_PC: 0x%x\n", data);
1067 #endif
1068 break;
1070 default:
1071 if (cmd <= 0)
1073 curr_pc -= cmd;
1074 curr_linenum += 1;
1075 cmd_length = 1;
1076 #if VMS_DEBUG
1077 _bfd_vms_debug (4, "bump pc to 0x%llx and line to %d\n",
1078 curr_pc, curr_linenum);
1079 #endif
1081 else
1083 (*_bfd_error_handler) (_("unknown line command %d"),
1084 cmd);
1085 cmd_length = 2;
1087 break;
1090 if ((curr_linenum != prev_linum && curr_pc != prev_pc)
1091 || cmd <= 0
1092 || cmd == DST_S_C_DELTA_PC_L
1093 || cmd == DST_S_C_DELTA_PC_W)
1095 line = (struct lineinfo *)
1096 bfd_zalloc (abfd, sizeof (struct lineinfo));
1097 line->address = curr_pc;
1098 line->line = curr_linenum;
1100 curr_line->next = line;
1101 curr_line = line;
1103 prev_linum = curr_linenum;
1104 prev_pc = curr_pc;
1105 #if VMS_DEBUG
1106 _bfd_vms_debug (4, "-> correlate pc 0x%llx with line %d\n",
1107 curr_pc, curr_linenum);
1108 #endif
1111 pcl_ptr += cmd_length;
1113 break;
1115 case 0x17: /* Undocumented type used by DEC C to declare equates. */
1116 #if VMS_DEBUG
1117 _bfd_vms_debug (3, "undocumented type 0x17\n");
1118 #endif
1119 break;
1121 default:
1122 #if VMS_DEBUG
1123 _bfd_vms_debug (3, "ignoring record\n");
1124 #endif
1125 break;
1129 ptr += rec_length;
1132 /* Finalize tables with EOL marker. */
1133 srec = (struct srecinfo *) bfd_zalloc (abfd, sizeof (struct srecinfo));
1134 srec->line = (unsigned int) -1;
1135 srec->srec = (unsigned int) -1;
1136 curr_srec->next = srec;
1138 line = (struct lineinfo *) bfd_zalloc (abfd, sizeof (struct lineinfo));
1139 line->line = (unsigned int) -1;
1140 line->address = (bfd_vma) -1;
1141 curr_line->next = line;
1143 /* Advertise that this module has been parsed. This is needed
1144 because parsing can be either performed at module creation
1145 or deferred until debug info is consumed. */
1146 SET_MODULE_PARSED (module);
1149 /* Build the list of modules for the specified BFD. */
1151 static struct module *
1152 build_module_list (bfd *abfd)
1154 struct module *module, *list = NULL;
1155 asection *dmt;
1157 if ((dmt = bfd_get_section_by_name (abfd, "$DMT$")))
1159 /* We have a DMT section so this must be an image. Parse the
1160 section and build the list of modules. This is sufficient
1161 since we can compute the start address and the end address
1162 of every module from the section contents. */
1163 bfd_size_type size = bfd_get_section_size (dmt);
1164 unsigned char *ptr, *end;
1166 ptr = (unsigned char *) bfd_alloc (abfd, size);
1167 if (! ptr)
1168 return NULL;
1170 if (! bfd_get_section_contents (abfd, dmt, ptr, 0, size))
1171 return NULL;
1173 #if VMS_DEBUG
1174 _bfd_vms_debug (2, "DMT\n");
1175 #endif
1177 end = ptr + size;
1179 while (ptr < end)
1181 /* Each header declares a module with its start offset and size
1182 of debug info in the DST section, as well as the count of
1183 program sections (i.e. address spans) it contains. */
1184 int modbeg = bfd_getl32 (ptr + DBG_S_L_DMT_MODBEG);
1185 int size = bfd_getl32 (ptr + DBG_S_L_DST_SIZE);
1186 int count = bfd_getl16 (ptr + DBG_S_W_DMT_PSECT_COUNT);
1187 ptr += DBG_S_C_DMT_HEADER_SIZE;
1189 #if VMS_DEBUG
1190 _bfd_vms_debug (3, "module: modbeg = %d, size = %d, count = %d\n",
1191 modbeg, size, count);
1192 #endif
1194 /* We create a 'module' structure for each program section since
1195 we only support contiguous addresses in a 'module' structure.
1196 As a consequence, the actual debug info in the DST section is
1197 shared and can be parsed multiple times; that doesn't seem to
1198 cause problems in practice. */
1199 while (count-- > 0)
1201 int start = bfd_getl32 (ptr + DBG_S_L_DMT_PSECT_START);
1202 int length = bfd_getl32 (ptr + DBG_S_L_DMT_PSECT_LENGTH);
1203 module = new_module (abfd);
1204 module->modbeg = modbeg;
1205 module->size = size;
1206 module->low = start;
1207 module->high = start + length;
1208 module->next = list;
1209 list = module;
1210 ptr += DBG_S_C_DMT_PSECT_SIZE;
1212 #if VMS_DEBUG
1213 _bfd_vms_debug (4, "section: start = 0x%x, length = %d\n",
1214 start, length);
1215 #endif
1219 else
1221 /* We don't have a DMT section so this must be an object. Parse
1222 the module right now in order to compute its start address and
1223 end address. */
1224 module = new_module (abfd);
1225 parse_module (abfd, module, PRIV (dst_section)->contents,
1226 PRIV (dst_ptr_end) - PRIV (dst_section)->contents);
1227 list = module;
1230 return list;
1233 /* Calculate and return the name of the source file and the line nearest
1234 to the wanted location in the specified module. */
1236 static bfd_boolean
1237 module_find_nearest_line (bfd *abfd, struct module *module, bfd_vma addr,
1238 const char **file, const char **func,
1239 unsigned int *line)
1241 struct funcinfo *funcinfo;
1242 struct lineinfo *lineinfo;
1243 struct srecinfo *srecinfo;
1244 bfd_boolean ret = FALSE;
1246 /* Parse this module if that was not done at module creation. */
1247 if (! IS_MODULE_PARSED (module))
1249 unsigned int size = module->size;
1250 unsigned int modbeg = PRIV (dst_section)->filepos + module->modbeg;
1251 unsigned char *buffer = (unsigned char *) bfd_malloc (module->size);
1253 if (bfd_seek (abfd, modbeg, SEEK_SET) != 0
1254 || bfd_bread (buffer, size, abfd) != size)
1256 bfd_set_error (bfd_error_no_debug_section);
1257 return FALSE;
1260 parse_module (abfd, module, buffer, size);
1261 free (buffer);
1264 /* Find out the function (if any) that contains the address. */
1265 for (funcinfo = module->func_table; funcinfo; funcinfo = funcinfo->next)
1266 if (addr >= funcinfo->low && addr <= funcinfo->high)
1268 *func = funcinfo->name;
1269 ret = TRUE;
1270 break;
1273 /* Find out the source file and the line nearest to the address. */
1274 for (lineinfo = module->line_table; lineinfo; lineinfo = lineinfo->next)
1275 if (lineinfo->next && addr < lineinfo->next->address)
1277 for (srecinfo = module->srec_table; srecinfo; srecinfo = srecinfo->next)
1278 if (srecinfo->next && lineinfo->line < srecinfo->next->line)
1280 if (srecinfo->sfile > 0)
1282 *file = module->file_table[srecinfo->sfile].name;
1283 *line = srecinfo->srec + lineinfo->line - srecinfo->line;
1285 else
1287 *file = module->name;
1288 *line = lineinfo->line;
1290 return TRUE;
1293 break;
1296 return ret;
1299 /* Provided a BFD, a section and an offset into the section, calculate and
1300 return the name of the source file and the line nearest to the wanted
1301 location. */
1303 bfd_boolean
1304 _bfd_vms_find_nearest_dst_line (bfd *abfd, asection *section,
1305 asymbol **symbols ATTRIBUTE_UNUSED,
1306 bfd_vma offset, const char **file,
1307 const char **func, unsigned int *line)
1309 struct module *module;
1311 /* What address are we looking for? */
1312 bfd_vma addr = section->vma + offset;
1314 *file = NULL;
1315 *func = NULL;
1316 *line = 0;
1318 if (PRIV (dst_section) == NULL)
1319 return FALSE;
1321 if (PRIV (modules) == NULL)
1323 PRIV (modules) = build_module_list (abfd);
1324 if (PRIV (modules) == NULL)
1325 return FALSE;
1328 for (module = PRIV (modules); module; module = module->next)
1329 if (addr >= module->low && addr <= module->high)
1330 return module_find_nearest_line (abfd, module, addr, file, func, line);
1332 return FALSE;
1335 /* Process EDBG/ETBT record.
1336 Return 0 on success, -1 on error */
1338 static int
1339 vms_slurp_debug (bfd *abfd)
1341 if (PRIV (dst_section) == NULL)
1343 /* We have no way to find out beforehand how much debug info there
1344 is in an object file, so pick an initial amount and grow it as
1345 needed later. */
1346 flagword flags = SEC_HAS_CONTENTS | SEC_DEBUGGING | SEC_RELOC;
1347 asection *section = bfd_make_section (abfd, "$DST$");
1348 if (!section)
1349 return -1;
1350 section->size = 1024;
1351 if (!bfd_set_section_flags (abfd, section, flags))
1352 return -1;
1353 section->contents = ((unsigned char *)
1354 bfd_zmalloc (section->size));
1355 if (section->contents == NULL)
1356 return -1;
1357 section->filepos = (unsigned int)-1;
1358 PRIV (dst_section) = section;
1361 PRIV (image_section) = PRIV (dst_section);
1362 PRIV (image_ptr) = PRIV (dst_section)->contents;
1364 return _bfd_vms_slurp_tir (abfd, EOBJ_S_C_ETIR);
1367 /* Process DBG/EDBG record.
1368 Return 0 on success, -1 on error. */
1371 _bfd_vms_slurp_dbg (bfd *abfd, int objtype ATTRIBUTE_UNUSED)
1373 #if VMS_DEBUG
1374 _bfd_vms_debug (2, "DBG/EDBG\n");
1375 #endif
1377 abfd->flags |= (HAS_DEBUG | HAS_LINENO);
1379 return vms_slurp_debug (abfd);
1382 /* Process TBT/ETBT record.
1383 Return 0 on success, -1 on error. */
1386 _bfd_vms_slurp_tbt (bfd *abfd, int objtype ATTRIBUTE_UNUSED)
1388 #if VMS_DEBUG
1389 _bfd_vms_debug (2, "TBT/ETBT\n");
1390 #endif
1392 abfd->flags |= HAS_LINENO;
1394 return vms_slurp_debug (abfd);
1397 /* Write DBG/EDBG record. */
1400 _bfd_vms_write_dbg (bfd *abfd ATTRIBUTE_UNUSED, int objtype ATTRIBUTE_UNUSED)
1402 #if VMS_DEBUG
1403 _bfd_vms_debug (2, "vms_write_dbg (%p, objtype)\n", abfd, objtype);
1404 #endif
1406 return 0;
1409 /* Write TBT/ETBT record. */
1412 _bfd_vms_write_tbt (bfd *abfd ATTRIBUTE_UNUSED, int objtype ATTRIBUTE_UNUSED)
1414 #if VMS_DEBUG
1415 _bfd_vms_debug (2, "vms_write_tbt (%p, %d)\n", abfd, objtype);
1416 #endif
1418 return 0;