* elf32-bfin.c (elf32_bfinfdpic_create_dynamic_sections): Always
[deliverable/binutils-gdb.git] / bfd / vms-hdr.c
... / ...
CommitLineData
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.
5
6 HDR record handling functions
7 EMH record handling functions
8
9 EOM record handling functions
10 EEOM record handling functions
11
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
29 Written by Klaus K"ampf (kkaempf@rmi.de)
30
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.
35
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.
40
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. */
45
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"
52
53#include "vms.h"
54
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
69/* Read & process emh record
70 return 0 on success, -1 on error. */
71
72int
73_bfd_vms_slurp_hdr (bfd *abfd, int objtype)
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 {
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;
95 }
96
97#if VMS_DEBUG
98 vms_debug(3, "subtype %d\n", subtype);
99#endif
100
101 switch (subtype)
102 {
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);
112 break;
113
114 case MHD_S_C_LNM:
115 PRIV (hdr_data).hdr_c_lnm = _bfd_vms_save_sized_string (vms_rec, PRIV (rec_size - 2));
116 break;
117
118 case MHD_S_C_SRC:
119 PRIV (hdr_data).hdr_c_src = _bfd_vms_save_sized_string (vms_rec, PRIV (rec_size - 2));
120 break;
121
122 case MHD_S_C_TTL:
123 PRIV (hdr_data).hdr_c_ttl = _bfd_vms_save_sized_string (vms_rec, PRIV (rec_size - 2));
124 break;
125
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);
137 break;
138
139 case EMH_S_C_LNM + EVAX_OFFSET:
140 PRIV (hdr_data).hdr_c_lnm = _bfd_vms_save_sized_string (vms_rec, PRIV (rec_size - 6));
141 break;
142
143 case EMH_S_C_SRC + EVAX_OFFSET:
144 PRIV (hdr_data).hdr_c_src = _bfd_vms_save_sized_string (vms_rec, PRIV (rec_size - 6));
145 break;
146
147 case EMH_S_C_TTL + EVAX_OFFSET:
148 PRIV (hdr_data).hdr_c_ttl = _bfd_vms_save_sized_string (vms_rec, PRIV (rec_size - 6));
149 break;
150
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:
157 break;
158
159 default:
160 bfd_set_error (bfd_error_wrong_format);
161 return -1;
162 }
163
164 return 0;
165}
166
167/* Output routines. */
168
169/* Manufacture a VMS like time on a unix based system.
170 stolen from obj-vms.c. */
171
172static unsigned char *
173get_vms_time_string (void)
174{
175 static unsigned char tbuf[18];
176#ifndef VMS
177#include <time.h>
178
179 char *pnt;
180 time_t timeb;
181
182 time (& timeb);
183 pnt = ctime (&timeb);
184 pnt[3] = 0;
185 pnt[7] = 0;
186 pnt[10] = 0;
187 pnt[16] = 0;
188 pnt[24] = 0;
189 sprintf ((char *) tbuf, "%2s-%3s-%s %s",
190 pnt + 8, pnt + 4, pnt + 20, pnt + 11);
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
210/* Write object header for bfd abfd. */
211
212int
213_bfd_vms_write_hdr (bfd *abfd, int objtype)
214{
215 asymbol *symbol;
216 unsigned int symnum;
217 int had_case = 0;
218 int had_file = 0;
219 char version [256];
220
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
227 /* MHD. */
228 if (objtype != OBJ_S_C_HDR)
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 {
239 /* Strip path and suffix information. */
240 char *fname, *fout, *fptr;
241
242 fptr = bfd_get_filename (abfd);
243 fname = strdup (fptr);
244
245 /* Strip VMS path. */
246 fout = strrchr (fname, ']');
247 if (fout == NULL)
248 fout = strchr (fname, ':');
249 if (fout != NULL)
250 fout++;
251 else
252 fout = fname;
253
254 /* Strip UNIX path. */
255 fptr = strrchr (fout, '/');
256 if (fptr != NULL)
257 fout = fptr + 1;
258
259 /* Strip .obj suffix. */
260 fptr = strrchr (fout, '.');
261 if (fptr != 0 && strcasecmp (fptr, ".OBJ") == 0)
262 *fptr = 0;
263
264 /* Convert to upper case and truncate at 31 characters.
265 (VMS object file format restricts module name length to 31). */
266 fptr = fout;
267 while (*fptr != 0)
268 {
269 *fptr = TOUPPER (*fptr);
270 fptr++;
271 if (*fptr == ';' || (fptr - fout) >= 31)
272 *fptr = 0;
273 }
274 _bfd_vms_output_counted (abfd, fout);
275 free (fname);
276 }
277 else
278 _bfd_vms_output_counted (abfd, "NONAME");
279
280 _bfd_vms_output_counted (abfd, BFD_VERSION_STRING);
281 _bfd_vms_output_dump (abfd, get_vms_time_string (), EMH_DATE_LENGTH);
282 _bfd_vms_output_fill (abfd, 0, EMH_DATE_LENGTH);
283 _bfd_vms_output_flush (abfd);
284
285 /* LMN. */
286 _bfd_vms_output_begin (abfd, EOBJ_S_C_EMH, EMH_S_C_LNM);
287 snprintf (version, sizeof (version), "GAS BFD v%s", BFD_VERSION_STRING);
288 _bfd_vms_output_dump (abfd, (unsigned char *)version, strlen (version));
289 _bfd_vms_output_flush (abfd);
290
291 /* SRC. */
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 {
300 if (CONST_STRNEQ ((char *)symbol->name, "<CASE:"))
301 {
302 PRIV (flag_hash_long_names) = symbol->name[6] - '0';
303 PRIV (flag_show_after_trunc) = symbol->name[7] - '0';
304
305 if (had_file)
306 break;
307 had_case = 1;
308 continue;
309 }
310
311 _bfd_vms_output_dump (abfd, (unsigned char *) symbol->name,
312 (int) strlen (symbol->name));
313 if (had_case)
314 break;
315 had_file = 1;
316 }
317 }
318
319 if (symnum == abfd->symcount)
320 _bfd_vms_output_dump (abfd, (unsigned char *) STRING_COMMA_LEN ("noname"));
321
322 _bfd_vms_output_flush (abfd);
323
324 /* TTL. */
325 _bfd_vms_output_begin (abfd, EOBJ_S_C_EMH, EMH_S_C_TTL);
326 _bfd_vms_output_dump (abfd, (unsigned char *) STRING_COMMA_LEN ("TTL"));
327 _bfd_vms_output_flush (abfd);
328
329 /* CPR. */
330 _bfd_vms_output_begin (abfd, EOBJ_S_C_EMH, EMH_S_C_CPR);
331 _bfd_vms_output_dump (abfd,