* bfd-in.h (STRING_AND_COMMA): New macro. Takes one constant string as its
[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.
0112cd26 3 Copyright 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2005, 2006
b34976b6 4 Free Software Foundation, Inc.
252b5132
RH
5
6 HDR record handling functions
7 EMH record handling functions
8 and
9 EOM record handling functions
10 EEOM record handling functions
11
12 Written by Klaus K"ampf (kkaempf@rmi.de)
13
7920ce38
NC
14 This program is free software; you can redistribute it and/or modify
15 it under the terms of the GNU General Public License as published by
16 the Free Software Foundation; either version 2 of the License, or
17 (at your option) any later version.
252b5132 18
7920ce38
NC
19 This program is distributed in the hope that it will be useful,
20 but WITHOUT ANY WARRANTY; without even the implied warranty of
21 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
22 GNU General Public License for more details.
252b5132 23
7920ce38
NC
24 You should have received a copy of the GNU General Public License
25 along with this program; if not, write to the Free Software
3e110533 26 Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA. */
252b5132 27
252b5132 28#include "bfd.h"
6a0735ef 29#include "bfdver.h"
252b5132
RH
30#include "sysdep.h"
31#include "bfdlink.h"
3882b010 32#include "safe-ctype.h"
252b5132
RH
33#include "libbfd.h"
34
35#include "vms.h"
36
23ccc829
NC
37#ifdef HAVE_ALLOCA_H
38#include <alloca.h>
39#endif
524f76c9 40
252b5132 41/* Read & process emh record
7920ce38 42 return 0 on success, -1 on error. */
252b5132
RH
43
44int
7920ce38 45_bfd_vms_slurp_hdr (bfd *abfd, int objtype)
252b5132
RH
46{
47 unsigned char *ptr;
48 unsigned char *vms_rec;
49 int subtype;
50
51 vms_rec = PRIV(vms_rec);
52
53#if VMS_DEBUG
54 vms_debug(2, "HDR/EMH\n");
55#endif
56
57 switch (objtype)
58 {
7920ce38
NC
59 case OBJ_S_C_HDR:
60 subtype = vms_rec[1];
61 break;
62 case EOBJ_S_C_EMH:
63 subtype = bfd_getl16 (vms_rec + 4) + EVAX_OFFSET;
64 break;
65 default:
66 subtype = -1;
252b5132
RH
67 }
68
69#if VMS_DEBUG
70 vms_debug(3, "subtype %d\n", subtype);
71#endif
72
73 switch (subtype)
74 {
7920ce38
NC
75 case MHD_S_C_MHD:
76 /* Module header. */
77 PRIV (hdr_data).hdr_b_strlvl = vms_rec[2];
78 PRIV (hdr_data).hdr_l_recsiz = bfd_getl16 (vms_rec + 3);
79 PRIV (hdr_data).hdr_t_name = _bfd_vms_save_counted_string (vms_rec + 5);
80 ptr = vms_rec + 5 + vms_rec[5] + 1;
81 PRIV (hdr_data).hdr_t_version = _bfd_vms_save_counted_string (ptr);
82 ptr += *ptr + 1;
83 PRIV (hdr_data).hdr_t_date = _bfd_vms_save_sized_string (ptr, 17);
252b5132
RH
84 break;
85
7920ce38
NC
86 case MHD_S_C_LNM:
87 PRIV (hdr_data).hdr_c_lnm = _bfd_vms_save_sized_string (vms_rec, PRIV (rec_length - 2));
252b5132
RH
88 break;
89
7920ce38
NC
90 case MHD_S_C_SRC:
91 PRIV (hdr_data).hdr_c_src = _bfd_vms_save_sized_string (vms_rec, PRIV (rec_length - 2));
252b5132
RH
92 break;
93
7920ce38
NC
94 case MHD_S_C_TTL:
95 PRIV (hdr_data).hdr_c_ttl = _bfd_vms_save_sized_string (vms_rec, PRIV (rec_length - 2));
252b5132
RH
96 break;
97
7920ce38
NC
98 case EMH_S_C_MHD + EVAX_OFFSET:
99 /* Module header. */
100 PRIV (hdr_data).hdr_b_strlvl = vms_rec[6];
101 PRIV (hdr_data).hdr_l_arch1 = bfd_getl32 (vms_rec + 8);
102 PRIV (hdr_data).hdr_l_arch2 = bfd_getl32 (vms_rec + 12);
103 PRIV (hdr_data).hdr_l_recsiz = bfd_getl32 (vms_rec + 16);
104 PRIV (hdr_data).hdr_t_name = _bfd_vms_save_counted_string (vms_rec + 20);
105 ptr = vms_rec + 20 + vms_rec[20] + 1;
106 PRIV (hdr_data).hdr_t_version =_bfd_vms_save_counted_string (ptr);
107 ptr += *ptr + 1;
108 PRIV (hdr_data).hdr_t_date = _bfd_vms_save_sized_string (ptr, 17);
252b5132
RH
109 break;
110
7920ce38
NC
111 case EMH_S_C_LNM + EVAX_OFFSET:
112 PRIV (hdr_data).hdr_c_lnm = _bfd_vms_save_sized_string (vms_rec, PRIV (rec_length - 6));
252b5132
RH
113 break;
114
7920ce38
NC
115 case EMH_S_C_SRC + EVAX_OFFSET:
116 PRIV (hdr_data).hdr_c_src = _bfd_vms_save_sized_string (vms_rec, PRIV (rec_length - 6));
252b5132
RH
117 break;
118
7920ce38
NC
119 case EMH_S_C_TTL + EVAX_OFFSET:
120 PRIV (hdr_data).hdr_c_ttl = _bfd_vms_save_sized_string (vms_rec, PRIV (rec_length - 6));
252b5132
RH
121 break;
122
7920ce38
NC
123 case MHD_S_C_CPR:
124 case MHD_S_C_MTC:
125 case MHD_S_C_GTX:
126 case EMH_S_C_CPR + EVAX_OFFSET:
127 case EMH_S_C_MTC + EVAX_OFFSET:
128 case EMH_S_C_GTX + EVAX_OFFSET:
252b5132
RH
129 break;
130
7920ce38
NC
131 default:
132 bfd_set_error (bfd_error_wrong_format);
252b5132 133 return -1;
7920ce38 134 }
252b5132
RH
135
136 return 0;
137}
138
252b5132
RH
139/* Output routines. */
140
7dee875e 141/* Manufacture a VMS like time on a unix based system.
7920ce38 142 stolen from obj-vms.c. */
252b5132
RH
143
144static unsigned char *
7920ce38 145get_vms_time_string (void)
252b5132
RH
146{
147 static unsigned char tbuf[18];
148#ifndef VMS
149#include <time.h>
150
151 char *pnt;
152 time_t timeb;
7920ce38
NC
153
154 time (& timeb);
252b5132
RH
155 pnt = ctime (&timeb);
156 pnt[3] = 0;
157 pnt[7] = 0;
158 pnt[10] = 0;
159 pnt[16] = 0;
160 pnt[24] = 0;
f075ee0c
AM
161 sprintf ((char *) tbuf, "%2s-%3s-%s %s",
162 pnt + 8, pnt + 4, pnt + 20, pnt + 11);
252b5132
RH
163#else
164#include <starlet.h>
165 struct
166 {
167 int Size;
168 unsigned char *Ptr;
169 } Descriptor;
170 Descriptor.Size = 17;
171 Descriptor.Ptr = tbuf;
172 SYS$ASCTIM (0, &Descriptor, 0, 0);
173#endif /* not VMS */
174
175#if VMS_DEBUG
176 vms_debug (6, "vmstimestring:'%s'\n", tbuf);
177#endif
178
179 return tbuf;
180}
181
7920ce38 182/* Write object header for bfd abfd. */
252b5132
RH
183
184int
7920ce38 185_bfd_vms_write_hdr (bfd *abfd, int objtype)
252b5132
RH
186{
187 asymbol *symbol;
5f771d47 188 unsigned int symnum;
252b5132
RH
189 int had_case = 0;
190 int had_file = 0;
191
252b5132
RH
192#if VMS_DEBUG
193 vms_debug (2, "vms_write_hdr (%p)\n", abfd);
194#endif
195
196 _bfd_vms_output_alignment (abfd, 2);
197
7920ce38
NC
198 /* MHD. */
199 if (objtype != OBJ_S_C_HDR)
252b5132
RH
200 {
201 _bfd_vms_output_begin (abfd, EOBJ_S_C_EMH, EMH_S_C_MHD);
202 _bfd_vms_output_short (abfd, EOBJ_S_C_STRLVL);
203 _bfd_vms_output_long (abfd, 0);
204 _bfd_vms_output_long (abfd, 0);
205 _bfd_vms_output_long (abfd, MAX_OUTREC_SIZE);
206 }
207
208 if (bfd_get_filename (abfd) != 0)
209 {
7920ce38 210 /* Strip path and suffix information. */
252b5132
RH
211 char *fname, *fout, *fptr;
212
213 fptr = bfd_get_filename (abfd);
7920ce38 214 fname = alloca (strlen (fptr) + 1);
252b5132
RH
215 strcpy (fname, fptr);
216 fout = strrchr (fname, ']');
217 if (fout == 0)
218 fout = strchr (fname, ':');
219 if (fout != 0)
220 fout++;
221 else
222 fout = fname;
223
7920ce38 224 /* Strip .obj suffix. */
252b5132
RH
225 fptr = strrchr (fname, '.');
226 if ((fptr != 0)
227 && (strcasecmp (fptr, ".OBJ") == 0))
228 *fptr = 0;
229
230 fptr = fout;
231 while (*fptr != 0)
232 {
3882b010 233 *fptr = TOUPPER (*fptr);
252b5132
RH
234 fptr++;
235 if ((*fptr == ';')
236 || ((fptr - fout) > 31))
237 *fptr = 0;
238 }
239 _bfd_vms_output_counted (abfd, fout);
240 }
241 else
242 _bfd_vms_output_counted (abfd, "NONAME");
243
e43d48cc 244 _bfd_vms_output_counted (abfd, BFD_VERSION_STRING);
252b5132
RH
245 _bfd_vms_output_dump (abfd, get_vms_time_string (), 17);
246 _bfd_vms_output_fill (abfd, 0, 17);
247 _bfd_vms_output_flush (abfd);
248
7920ce38 249 /* LMN. */
252b5132 250 _bfd_vms_output_begin (abfd, EOBJ_S_C_EMH, EMH_S_C_LNM);
0112cd26 251 _bfd_vms_output_dump (abfd, (unsigned char *) STRING_COMMA_LEN ("GAS proGIS"));
252b5132
RH
252 _bfd_vms_output_flush (abfd);
253
7920ce38 254 /* SRC. */
252b5132
RH
255 _bfd_vms_output_begin (abfd, EOBJ_S_C_EMH, EMH_S_C_SRC);
256
257 for (symnum = 0; symnum < abfd->symcount; symnum++)
258 {
259 symbol = abfd->outsymbols[symnum];
260
261 if (symbol->flags & BSF_FILE)
262 {
0112cd26 263 if (CONST_STRNEQ ((char *)symbol->name, "<CASE:"))
252b5132 264 {
7920ce38
NC
265 PRIV (flag_hash_long_names) = symbol->name[6] - '0';
266 PRIV (flag_show_after_trunc) = symbol->name[7] - '0';
252b5132
RH
267
268 if (had_file)
269 break;
270 had_case = 1;
271 continue;
272 }
273
dc810e39
AM
274 _bfd_vms_output_dump (abfd, (unsigned char *) symbol->name,
275 (int) strlen (symbol->name));
252b5132
RH
276 if (had_case)
277 break;
278 had_file = 1;
279 }
280 }
281
282 if (symnum == abfd->symcount)
0112cd26 283 _bfd_vms_output_dump (abfd, (unsigned char *) STRING_COMMA_LEN ("noname"));
252b5132
RH
284
285 _bfd_vms_output_flush (abfd);
286
7920ce38 287 /* TTL. */
252b5132 288 _bfd_vms_output_begin (abfd, EOBJ_S_C_EMH, EMH_S_C_TTL);
0112cd26 289 _bfd_vms_output_dump (abfd, (unsigned char *) STRING_COMMA_LEN ("TTL"));
252b5132
RH
290 _bfd_vms_output_flush (abfd);
291
7920ce38 292 /* CPR. */
252b5132
RH
293 _bfd_vms_output_begin (abfd, EOBJ_S_C_EMH, EMH_S_C_CPR);
294 _bfd_vms_output_dump (abfd,