2010-01-27 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
e4d2e665 237 /* Create module name from filename. */
252b5132
RH
238 if (bfd_get_filename (abfd) != 0)
239 {
7920ce38 240 /* Strip path and suffix information. */
252b5132
RH
241 char *fname, *fout, *fptr;
242
243 fptr = bfd_get_filename (abfd);
d387240a 244 fname = strdup (fptr);
0c376465
TG
245
246 /* Strip VMS path. */
252b5132 247 fout = strrchr (fname, ']');
0c376465 248 if (fout == NULL)
252b5132 249 fout = strchr (fname, ':');
0c376465 250 if (fout != NULL)
252b5132
RH
251 fout++;
252 else
253 fout = fname;
254
0c376465
TG
255 /* Strip UNIX path. */
256 fptr = strrchr (fout, '/');
257 if (fptr != NULL)
258 fout = fptr + 1;
259
e4d2e665 260 /* Strip suffix. */
0c376465 261 fptr = strrchr (fout, '.');
e4d2e665 262 if (fptr != 0)
252b5132
RH
263 *fptr = 0;
264
0c376465
TG
265 /* Convert to upper case and truncate at 31 characters.
266 (VMS object file format restricts module name length to 31). */
252b5132
RH
267 fptr = fout;
268 while (*fptr != 0)
269 {
3882b010 270 *fptr = TOUPPER (*fptr);
252b5132 271 fptr++;
0c376465 272 if (*fptr == ';' || (fptr - fout) >= 31)
252b5132
RH
273 *fptr = 0;
274 }
275 _bfd_vms_output_counted (abfd, fout);
d387240a 276 free (fname);
252b5132
RH
277 }
278 else
279 _bfd_vms_output_counted (abfd, "NONAME");
280
e43d48cc 281 _bfd_vms_output_counted (abfd, BFD_VERSION_STRING);
0c376465
TG
282 _bfd_vms_output_dump (abfd, get_vms_time_string (), EMH_DATE_LENGTH);
283 _bfd_vms_output_fill (abfd, 0, EMH_DATE_LENGTH);
252b5132
RH
284 _bfd_vms_output_flush (abfd);
285
7920ce38 286 /* LMN. */
252b5132 287 _bfd_vms_output_begin (abfd, EOBJ_S_C_EMH, EMH_S_C_LNM);
0c376465
TG
288 snprintf (version, sizeof (version), "GAS BFD v%s", BFD_VERSION_STRING);
289 _bfd_vms_output_dump (abfd, (unsigned char *)version, strlen (version));
252b5132
RH
290 _bfd_vms_output_flush (abfd);
291
7920ce38 292 /* SRC. */
252b5132
RH
293 _bfd_vms_output_begin (abfd, EOBJ_S_C_EMH, EMH_S_C_SRC);
294
295 for (symnum = 0; symnum < abfd->symcount; symnum++)
296 {
297 symbol = abfd->outsymbols[symnum];
298
299 if (symbol->flags & BSF_FILE)
300 {
0112cd26 301 if (CONST_STRNEQ ((char *)symbol->name, "<CASE:"))
252b5132 302 {
7920ce38
NC
303 PRIV (flag_hash_long_names) = symbol->name[6] - '0';
304 PRIV (flag_show_after_trunc) = symbol->name[7] - '0';
252b5132
RH
305
306 if (had_file)
307 break;
308 had_case = 1;
309 continue;
310 }
311
dc810e39
AM
312 _bfd_vms_output_dump (abfd, (unsigned char *) symbol->name,
313 (int) strlen (symbol->name));
252b5132
RH
314 if (had_case)
315 break;
316 had_file = 1;
317 }
318 }
319
320 if (symnum == abfd->symcount)
0112cd26 321 _bfd_vms_output_dump (abfd, (unsigned char *) STRING_COMMA_LEN ("noname"));
252b5132
RH
322
323 _bfd_vms_output_flush (abfd);
324
7920ce38 325 /* TTL. */
252b5132 326 _bfd_vms_output_begin (abfd, EOBJ_S_C_EMH, EMH_S_C_TTL);
0112cd26 327 _bfd_vms_output_dump (abfd, (unsigned char *) STRING_COMMA_LEN ("TTL"));
252b5132
RH
328 _bfd_vms_output_flush (abfd);
329
7920ce38 330 /* CPR. */
252b5132
RH
331 _bfd_vms_output_begin (abfd, EOBJ_S_C_EMH, EMH_S_C_CPR);
332 _bfd_vms_output_dump (abfd,