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