2009-07-07 Tristan Gingold <gingold@adacore.com>
[deliverable/binutils-gdb.git] / bfd / vms-hdr.c
CommitLineData
252b5132
RH
1/* vms-hdr.c -- BFD back-end for VMS/VAX (openVMS/VAX) and
2 EVAX (openVMS/Alpha) files.
3db64b00 3 Copyright 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2005, 2006,
0c376465 4 2007, 2008, 2009 Free Software Foundation, Inc.
252b5132
RH
5
6 HDR record handling functions
7 EMH record handling functions
0c376465 8
252b5132
RH
9 EOM record handling functions
10 EEOM record handling functions
11
0c376465
TG
12 IHD record handling functions
13 EIHD record handling functions
14
15 ISD record handling functions
16 EISD record handling functions
17
18 IHS record handling functions
19 EIHS record handling functions
20
21 DBG record handling functions
22 EDBG record handling functions
23
24 TBT record handling functions
25 ETBT record handling functions
26
27 DST/DMT section handling functions
28
252b5132
RH
29 Written by Klaus K"ampf (kkaempf@rmi.de)
30
7920ce38
NC
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
cd123cb7 33 the Free Software Foundation; either version 3 of the License, or
7920ce38 34 (at your option) any later version.
252b5132 35
7920ce38
NC
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.
252b5132 40
7920ce38
NC
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
cd123cb7
NC
43 Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
44 MA 02110-1301, USA. */
252b5132 45
3db64b00 46#include "sysdep.h"
252b5132 47#include "bfd.h"
6a0735ef 48#include "bfdver.h"
252b5132 49#include "bfdlink.h"
3882b010 50#include "safe-ctype.h"
252b5132
RH
51#include "libbfd.h"
52
53#include "vms.h"
54
0c376465
TG
55static struct module *new_module (bfd *);
56static void parse_module
57 (bfd *, struct module *, unsigned char *, unsigned int);
58static struct module *build_module_list (bfd *);
59static bfd_boolean module_find_nearest_line
60 (bfd *, struct module *, bfd_vma, const char **, const char **,
61 unsigned int *);
62static int vms_slurp_debug (bfd *);
63
64#define SET_MODULE_PARSED(m) \
65 do { if ((m)->name == NULL) (m)->name = ""; } while (0)
66#define IS_MODULE_PARSED(m) ((m)->name != NULL)
67
68
252b5132 69/* Read & process emh record
7920ce38 70 return 0 on success, -1 on error. */
252b5132
RH
71
72int
7920ce38 73_bfd_vms_slurp_hdr (bfd *abfd, int objtype)
252b5132
RH
74{
75 unsigned char *ptr;
76 unsigned char *vms_rec;
77 int subtype;
78
79 vms_rec = PRIV(vms_rec);
80
81#if VMS_DEBUG
82 vms_debug(2, "HDR/EMH\n");
83#endif
84
85 switch (objtype)
86 {
7920ce38
NC
87 case OBJ_S_C_HDR:
88 subtype = vms_rec[1];
89 break;
90 case EOBJ_S_C_EMH:
91 subtype = bfd_getl16 (vms_rec + 4) + EVAX_OFFSET;
92 break;
93 default:
94 subtype = -1;
252b5132
RH
95 }
96
97#if VMS_DEBUG
98 vms_debug(3, "subtype %d\n", subtype);
99#endif
100
101 switch (subtype)
102 {
7920ce38
NC
103 case MHD_S_C_MHD:
104 /* Module header. */
105 PRIV (hdr_data).hdr_b_strlvl = vms_rec[2];
106 PRIV (hdr_data).hdr_l_recsiz = bfd_getl16 (vms_rec + 3);
107 PRIV (hdr_data).hdr_t_name = _bfd_vms_save_counted_string (vms_rec + 5);
108 ptr = vms_rec + 5 + vms_rec[5] + 1;
109 PRIV (hdr_data).hdr_t_version = _bfd_vms_save_counted_string (ptr);
110 ptr += *ptr + 1;
111 PRIV (hdr_data).hdr_t_date = _bfd_vms_save_sized_string (ptr, 17);
252b5132
RH
112 break;
113
7920ce38 114 case MHD_S_C_LNM:
0c376465 115 PRIV (hdr_data).hdr_c_lnm = _bfd_vms_save_sized_string (vms_rec, PRIV (rec_size - 2));
252b5132
RH
116 break;
117
7920ce38 118 case MHD_S_C_SRC:
0c376465 119 PRIV (hdr_data).hdr_c_src = _bfd_vms_save_sized_string (vms_rec, PRIV (rec_size - 2));
252b5132
RH
120 break;
121
7920ce38 122 case MHD_S_C_TTL:
0c376465 123 PRIV (hdr_data).hdr_c_ttl = _bfd_vms_save_sized_string (vms_rec, PRIV (rec_size - 2));
252b5132
RH
124 break;
125
7920ce38
NC
126 case EMH_S_C_MHD + EVAX_OFFSET:
127 /* Module header. */
128 PRIV (hdr_data).hdr_b_strlvl = vms_rec[6];
129 PRIV (hdr_data).hdr_l_arch1 = bfd_getl32 (vms_rec + 8);
130 PRIV (hdr_data).hdr_l_arch2 = bfd_getl32 (vms_rec + 12);
131 PRIV (hdr_data).hdr_l_recsiz = bfd_getl32 (vms_rec + 16);
132 PRIV (hdr_data).hdr_t_name = _bfd_vms_save_counted_string (vms_rec + 20);
133 ptr = vms_rec + 20 + vms_rec[20] + 1;
134 PRIV (hdr_data).hdr_t_version =_bfd_vms_save_counted_string (ptr);
135 ptr += *ptr + 1;
136 PRIV (hdr_data).hdr_t_date = _bfd_vms_save_sized_string (ptr, 17);
252b5132
RH
137 break;
138
7920ce38 139 case EMH_S_C_LNM + EVAX_OFFSET:
0c376465 140 PRIV (hdr_data).hdr_c_lnm = _bfd_vms_save_sized_string (vms_rec, PRIV (rec_size - 6));
252b5132
RH
141 break;
142
7920ce38 143 case EMH_S_C_SRC + EVAX_OFFSET:
0c376465 144 PRIV (hdr_data).hdr_c_src = _bfd_vms_save_sized_string (vms_rec, PRIV (rec_size - 6));
252b5132
RH
145 break;
146
7920ce38 147 case EMH_S_C_TTL + EVAX_OFFSET:
0c376465 148 PRIV (hdr_data).hdr_c_ttl = _bfd_vms_save_sized_string (vms_rec, PRIV (rec_size - 6));
252b5132
RH
149 break;
150
7920ce38
NC
151 case MHD_S_C_CPR:
152 case MHD_S_C_MTC:
153 case MHD_S_C_GTX:
154 case EMH_S_C_CPR + EVAX_OFFSET:
155 case EMH_S_C_MTC + EVAX_OFFSET:
156 case EMH_S_C_GTX + EVAX_OFFSET:
252b5132
RH
157 break;
158
7920ce38
NC
159 default:
160 bfd_set_error (bfd_error_wrong_format);
252b5132 161 return -1;
7920ce38 162 }
252b5132
RH
163
164 return 0;
165}
166
252b5132
RH
167/* Output routines. */
168
7dee875e 169/* Manufacture a VMS like time on a unix based system.
7920ce38 170 stolen from obj-vms.c. */
252b5132
RH
171
172static unsigned char *
7920ce38 173get_vms_time_string (void)
252b5132
RH
174{
175 static unsigned char tbuf[18];
176#ifndef VMS
177#include <time.h>
178
179 char *pnt;
180 time_t timeb;
7920ce38
NC
181
182 time (& timeb);
252b5132
RH
183 pnt = ctime (&timeb);
184 pnt[3] = 0;
185 pnt[7] = 0;
186 pnt[10] = 0;
187 pnt[16] = 0;
188 pnt[24] = 0;
f075ee0c
AM
189 sprintf ((char *) tbuf, "%2s-%3s-%s %s",
190 pnt + 8, pnt + 4, pnt + 20, pnt + 11);
252b5132
RH
191#else
192#include <starlet.h>
193 struct
194 {
195 int Size;
196 unsigned char *Ptr;
197 } Descriptor;
198 Descriptor.Size = 17;
199 Descriptor.Ptr = tbuf;
200 SYS$ASCTIM (0, &Descriptor, 0, 0);
201#endif /* not VMS */
202
203#if VMS_DEBUG
204 vms_debug (6, "vmstimestring:'%s'\n", tbuf);
205#endif
206
207 return tbuf;
208}
209
7920ce38 210/* Write object header for bfd abfd. */
252b5132
RH
211
212int
7920ce38 213_bfd_vms_write_hdr (bfd *abfd, int objtype)
252b5132
RH
214{
215 asymbol *symbol;
5f771d47 216 unsigned int symnum;
252b5132
RH
217 int had_case = 0;
218 int had_file = 0;
0c376465 219 char version [256];
252b5132 220
252b5132
RH
221#if VMS_DEBUG
222 vms_debug (2, "vms_write_hdr (%p)\n", abfd);
223#endif
224
225 _bfd_vms_output_alignment (abfd, 2);
226
7920ce38
NC
227 /* MHD. */
228 if (objtype != OBJ_S_C_HDR)
252b5132
RH
229 {
230 _bfd_vms_output_begin (abfd, EOBJ_S_C_EMH, EMH_S_C_MHD);
231 _bfd_vms_output_short (abfd, EOBJ_S_C_STRLVL);
232 _bfd_vms_output_long (abfd, 0);
233 _bfd_vms_output_long (abfd, 0);
234 _bfd_vms_output_long (abfd, MAX_OUTREC_SIZE);
235 }
236
237 if (bfd_get_filename (abfd) != 0)
238 {
7920ce38 239 /* Strip path and suffix information. */
252b5132
RH
240 char *fname, *fout, *fptr;
241
242 fptr = bfd_get_filename (abfd);
d387240a 243 fname = strdup (fptr);
0c376465
TG
244
245 /* Strip VMS path. */
252b5132 246 fout = strrchr (fname, ']');
0c376465 247 if (fout == NULL)
252b5132 248 fout = strchr (fname, ':');
0c376465 249 if (fout != NULL)
252b5132
RH
250 fout++;
251 else
252 fout = fname;
253
0c376465
TG
254 /* Strip UNIX path. */
255 fptr = strrchr (fout, '/');
256 if (fptr != NULL)
257 fout = fptr + 1;
258
7920ce38 259 /* Strip .obj suffix. */
0c376465
TG
260 fptr = strrchr (fout, '.');
261 if (fptr != 0 && strcasecmp (fptr, ".OBJ") == 0)
252b5132
RH
262 *fptr = 0;
263
0c376465
TG
264 /* Convert to upper case and truncate at 31 characters.
265 (VMS object file format restricts module name length to 31). */
252b5132
RH
266 fptr = fout;
267 while (*fptr != 0)
268 {
3882b010 269 *fptr = TOUPPER (*fptr);
252b5132 270 fptr++;
0c376465 271 if (*fptr == ';' || (fptr - fout) >= 31)
252b5132
RH
272 *fptr = 0;
273 }
274 _bfd_vms_output_counted (abfd, fout);
d387240a 275 free (fname);
252b5132
RH
276 }
277 else
278 _bfd_vms_output_counted (abfd, "NONAME");
279
e43d48cc 280 _bfd_vms_output_counted (abfd, BFD_VERSION_STRING);
0c376465
TG
281 _bfd_vms_output_dump (abfd, get_vms_time_string (), EMH_DATE_LENGTH);
282 _bfd_vms_output_fill (abfd, 0, EMH_DATE_LENGTH);
252b5132
RH
283 _bfd_vms_output_flush (abfd);
284
7920ce38 285 /* LMN. */
252b5132 286 _bfd_vms_output_begin (abfd, EOBJ_S_C_EMH, EMH_S_C_LNM);
0c376465
TG
287 snprintf (version, sizeof (version), "GAS BFD v%s", BFD_VERSION_STRING);
288 _bfd_vms_output_dump (abfd, (unsigned char *)version, strlen (version));
252b5132
RH
289 _bfd_vms_output_flush (abfd);
290
7920ce38 291 /* SRC. */
252b5132
RH
292 _bfd_vms_output_begin (abfd, EOBJ_S_C_EMH, EMH_S_C_SRC);
293
294 for (symnum = 0; symnum < abfd->symcount; symnum++)
295 {
296 symbol = abfd->outsymbols[symnum];
297
298 if (symbol->flags & BSF_FILE)
299 {
0112cd26 300 if (CONST_STRNEQ ((char *)symbol->name, "<CASE:"))
252b5132 301 {
7920ce38
NC
302 PRIV (flag_hash_long_names) = symbol->name[6] - '0';
303 PRIV (flag_show_after_trunc) = symbol->name[7] - '0';
252b5132
RH
304
305 if (had_file)
306 break;
307 had_case = 1;
308 continue;
309 }
310
dc810e39
AM
311 _bfd_vms_output_dump (abfd, (unsigned char *) symbol->name,
312 (int) strlen (symbol->name));
252b5132
RH
313 if (had_case)
314 break;
315 had_file = 1;
316 }
317 }
318
319 if (symnum == abfd->symcount)
0112cd26 320 _bfd_vms_output_dump (abfd, (unsigned char *) STRING_COMMA_LEN ("noname"));
252b5132
RH
321
322 _bfd_vms_output_flush (abfd);
323
7920ce38 324 /* TTL. */
252b5132 325 _bfd_vms_output_begin (abfd, EOBJ_S_C_EMH, EMH_S_C_TTL);
0112cd26 326 _bfd_vms_output_dump (abfd, (unsigned char *) STRING_COMMA_LEN ("TTL"));
252b5132
RH
327 _bfd_vms_output_flush (abfd);
328
7920ce38 329 /* CPR. */
252b5132
RH
330 _bfd_vms_output_begin (abfd, EOBJ_S_C_EMH, EMH_S_C_CPR);
331 _bfd_vms_output_dump (abfd,