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