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 Free Software Foundation, Inc. 4 5 HDR record handling functions 6 EMH record handling functions 7 and 8 EOM record handling functions 9 EEOM record handling functions 10 11 Written by Klaus K"ampf (kkaempf@rmi.de) 12 13 This program is free software; you can redistribute it and/or modify 14 it under the terms of the GNU General Public License as published by 15 the Free Software Foundation; either version 2 of the License, or 16 (at your option) any later version. 17 18 This program is distributed in the hope that it will be useful, 19 but WITHOUT ANY WARRANTY; without even the implied warranty of 20 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 21 GNU General Public License for more details. 22 23 You should have received a copy of the GNU General Public License 24 along with this program; if not, write to the Free Software 25 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ 26 27 #include <ctype.h> 28 29 #include "bfd.h" 30 #include "sysdep.h" 31 #include "bfdlink.h" 32 #include "libbfd.h" 33 34 #include "vms.h" 35 36 #ifdef HAVE_ALLOCA_H 37 #include <alloca.h> 38 #endif 39 /*---------------------------------------------------------------------------*/ 40 41 /* Read & process emh record 42 return 0 on success, -1 on error */ 43 44 int 45 _bfd_vms_slurp_hdr (abfd, objtype) 46 bfd *abfd; 47 int objtype; 48 { 49 unsigned char *ptr; 50 unsigned char *vms_rec; 51 int subtype; 52 53 vms_rec = PRIV(vms_rec); 54 55 #if VMS_DEBUG 56 vms_debug(2, "HDR/EMH\n"); 57 #endif 58 59 switch (objtype) 60 { 61 case OBJ_S_C_HDR: 62 subtype = vms_rec[1]; 63 break; 64 case EOBJ_S_C_EMH: 65 subtype = bfd_getl16 (vms_rec + 4) + EVAX_OFFSET; 66 break; 67 default: 68 subtype = -1; 69 } 70 71 #if VMS_DEBUG 72 vms_debug(3, "subtype %d\n", subtype); 73 #endif 74 75 switch (subtype) 76 { 77 78 case MHD_S_C_MHD: 79 /* 80 * module header 81 */ 82 PRIV(hdr_data).hdr_b_strlvl = vms_rec[2]; 83 PRIV(hdr_data).hdr_l_recsiz = bfd_getl16 (vms_rec + 3); 84 PRIV(hdr_data).hdr_t_name = _bfd_vms_save_counted_string (vms_rec + 5); 85 ptr = vms_rec + 5 + vms_rec[5] + 1; 86 PRIV(hdr_data).hdr_t_version = _bfd_vms_save_counted_string (ptr); 87 ptr += *ptr + 1; 88 PRIV(hdr_data).hdr_t_date = _bfd_vms_save_sized_string (ptr, 17); 89 90 break; 91 92 case MHD_S_C_LNM: 93 /* 94 * 95 */ 96 PRIV(hdr_data).hdr_c_lnm = _bfd_vms_save_sized_string (vms_rec, PRIV(rec_length-2)); 97 break; 98 99 case MHD_S_C_SRC: 100 /* 101 * 102 */ 103 PRIV(hdr_data).hdr_c_src = _bfd_vms_save_sized_string (vms_rec, PRIV(rec_length-2)); 104 break; 105 106 case MHD_S_C_TTL: 107 /* 108 * 109 */ 110 PRIV(hdr_data).hdr_c_ttl = _bfd_vms_save_sized_string (vms_rec, PRIV(rec_length-2)); 111 break; 112 113 case MHD_S_C_CPR: 114 /* 115 * 116 */ 117 break; 118 119 case MHD_S_C_MTC: 120 /* 121 * 122 */ 123 break; 124 125 case MHD_S_C_GTX: 126 /* 127 * 128 */ 129 break; 130 131 case EMH_S_C_MHD + EVAX_OFFSET: 132 /* 133 * module header 134 */ 135 PRIV(hdr_data).hdr_b_strlvl = vms_rec[6]; 136 PRIV(hdr_data).hdr_l_arch1 = bfd_getl32 (vms_rec + 8); 137 PRIV(hdr_data).hdr_l_arch2 = bfd_getl32 (vms_rec + 12); 138 PRIV(hdr_data).hdr_l_recsiz = bfd_getl32 (vms_rec + 16); 139 PRIV(hdr_data).hdr_t_name = 140 _bfd_vms_save_counted_string (vms_rec + 20); 141 ptr = vms_rec + 20 + vms_rec[20] + 1; 142 PRIV(hdr_data).hdr_t_version = 143 _bfd_vms_save_counted_string (ptr); 144 ptr += *ptr + 1; 145 PRIV(hdr_data).hdr_t_date = 146 _bfd_vms_save_sized_string (ptr, 17); 147 148 break; 149 150 case EMH_S_C_LNM + EVAX_OFFSET: 151 /* 152 * 153 */ 154 PRIV(hdr_data).hdr_c_lnm = 155 _bfd_vms_save_sized_string (vms_rec, PRIV(rec_length-6)); 156 break; 157 158 case EMH_S_C_SRC + EVAX_OFFSET: 159 /* 160 * 161 */ 162 PRIV(hdr_data).hdr_c_src = 163 _bfd_vms_save_sized_string (vms_rec, PRIV(rec_length-6)); 164 break; 165 166 case EMH_S_C_TTL + EVAX_OFFSET: 167 /* 168 * 169 */ 170 PRIV(hdr_data).hdr_c_ttl = 171 _bfd_vms_save_sized_string (vms_rec, PRIV(rec_length-6)); 172 break; 173 174 case EMH_S_C_CPR + EVAX_OFFSET: 175 /* 176 * 177 */ 178 break; 179 180 case EMH_S_C_MTC + EVAX_OFFSET: 181 /* 182 * 183 */ 184 break; 185 186 case EMH_S_C_GTX + EVAX_OFFSET: 187 /* 188 * 189 */ 190 break; 191 192 default: 193 bfd_set_error (bfd_error_wrong_format); 194 return -1; 195 196 } /* switch */ 197 198 return 0; 199 } 200 201 /*-----------------------------------------------------------------------------*/ 202 /* Output routines. */ 203 204 /* Manufacure a VMS like time on a unix based system. 205 stolen from obj-vms.c */ 206 207 static unsigned char * 208 get_vms_time_string () 209 { 210 static unsigned char tbuf[18]; 211 #ifndef VMS 212 #include <time.h> 213 214 char *pnt; 215 time_t timeb; 216 time (&timeb); 217 pnt = ctime (&timeb); 218 pnt[3] = 0; 219 pnt[7] = 0; 220 pnt[10] = 0; 221 pnt[16] = 0; 222 pnt[24] = 0; 223 sprintf (tbuf, "%2s-%3s-%s %s", pnt + 8, pnt + 4, pnt + 20, pnt + 11); 224 #else 225 #include <starlet.h> 226 struct 227 { 228 int Size; 229 unsigned char *Ptr; 230 } Descriptor; 231 Descriptor.Size = 17; 232 Descriptor.Ptr = tbuf; 233 SYS$ASCTIM (0, &Descriptor, 0, 0); 234 #endif /* not VMS */ 235 236 #if VMS_DEBUG 237 vms_debug (6, "vmstimestring:'%s'\n", tbuf); 238 #endif 239 240 return tbuf; 241 } 242 243 /* write object header for bfd abfd */ 244 245 int 246 _bfd_vms_write_hdr (abfd, objtype) 247 bfd *abfd; 248 int objtype; 249 { 250 asymbol *symbol; 251 unsigned int symnum; 252 int had_case = 0; 253 int had_file = 0; 254 255 #if VMS_DEBUG 256 vms_debug (2, "vms_write_hdr (%p)\n", abfd); 257 #endif 258 259 _bfd_vms_output_alignment (abfd, 2); 260 261 /* MHD */ 262 263 if (objtype == OBJ_S_C_HDR) 264 { 265 } 266 else 267 { 268 _bfd_vms_output_begin (abfd, EOBJ_S_C_EMH, EMH_S_C_MHD); 269 _bfd_vms_output_short (abfd, EOBJ_S_C_STRLVL); 270 _bfd_vms_output_long (abfd, 0); 271 _bfd_vms_output_long (abfd, 0); 272 _bfd_vms_output_long (abfd, MAX_OUTREC_SIZE); 273 } 274 275 if (bfd_get_filename (abfd) != 0) 276 { 277 /* strip path and suffix information */ 278 279 char *fname, *fout, *fptr; 280 281 fptr = bfd_get_filename (abfd); 282 fname = (char *) alloca (strlen (fptr) + 1); 283 strcpy (fname, fptr); 284 fout = strrchr (fname, ']'); 285 if (fout == 0) 286 fout = strchr (fname, ':'); 287 if (fout != 0) 288 fout++; 289 else 290 fout = fname; 291 292 /* strip .obj suffix */ 293 294 fptr = strrchr (fname, '.'); 295 if ((fptr != 0) 296 && (strcasecmp (fptr, ".OBJ") == 0)) 297 *fptr = 0; 298 299 fptr = fout; 300 while (*fptr != 0) 301 { 302 if (islower (*fptr)) 303 *fptr = toupper (*fptr); 304 fptr++; 305 if ((*fptr == ';') 306 || ((fptr - fout) > 31)) 307 *fptr = 0; 308 } 309 _bfd_vms_output_counted (abfd, fout); 310 } 311 else 312 _bfd_vms_output_counted (abfd, "NONAME"); 313 314 _bfd_vms_output_counted (abfd, BFD_VERSION); 315 _bfd_vms_output_dump (abfd, get_vms_time_string (), 17); 316 _bfd_vms_output_fill (abfd, 0, 17); 317 _bfd_vms_output_flush (abfd); 318 319 /* LMN */ 320 321 _bfd_vms_output_begin (abfd, EOBJ_S_C_EMH, EMH_S_C_LNM); 322 _bfd_vms_output_dump (abfd, (unsigned char *)"GAS proGIS", 10); 323 _bfd_vms_output_flush (abfd); 324 325 /* SRC */ 326 327 _bfd_vms_output_begin (abfd, EOBJ_S_C_EMH, EMH_S_C_SRC); 328 329 for (symnum = 0; symnum < abfd->symcount; symnum++) 330 { 331 symbol = abfd->outsymbols[symnum]; 332 333 if (symbol->flags & BSF_FILE) 334 { 335 if (strncmp ((char *)symbol->name, "<CASE:", 6) == 0) 336 { 337 PRIV(flag_hash_long_names) = symbol->name[6] - '0'; 338 PRIV(flag_show_after_trunc) = symbol->name[7] - '0'; 339 340 if (had_file) 341 break; 342 had_case = 1; 343 continue; 344 } 345 346 _bfd_vms_output_dump (abfd, (unsigned char *)symbol->name, strlen (symbol->name)); 347 if (had_case) 348 break; 349 had_file = 1; 350 } 351 } 352 353 if (symnum == abfd->symcount) 354 _bfd_vms_output_dump (abfd, (unsigned char *)"noname", 6); 355 356 _bfd_vms_output_flush (abfd); 357 358 /* TTL */ 359 360 _bfd_vms_output_begin (abfd, EOBJ_S_C_EMH, EMH_S_C_TTL); 361 _bfd_vms_output_dump (abfd, (unsigned char *)"TTL", 3); 362 _bfd_vms_output_flush (abfd); 363 364 /* CPR */ 365 366 _bfd_vms_output_begin (abfd, EOBJ_S_C_EMH, EMH_S_C_CPR); 367 _bfd_vms_output_dump (abfd, 368 (unsigned char *)"GNU BFD ported by Klaus K�mpf 1994-1996", 369 39); 370 _bfd_vms_output_flush (abfd); 371 372 return 0; 373 } 374 375 /*-----------------------------------------------------------------------------*/ 376 377 /* Process EOM/EEOM record 378 return 0 on success, -1 on error */ 379 380 int 381 _bfd_vms_slurp_eom (abfd, objtype) 382 bfd *abfd; 383 int objtype; 384 { 385 unsigned char *vms_rec; 386 387 #if VMS_DEBUG 388 vms_debug(2, "EOM/EEOM\n"); 389 #endif 390 391 vms_rec = PRIV(vms_rec); 392 393 if ((objtype == OBJ_S_C_EOM) 394 || (objtype == OBJ_S_C_EOMW)) 395 { 396 } 397 else 398 { 399 PRIV(eom_data).eom_l_total_lps = bfd_getl32 (vms_rec + 4); 400 PRIV(eom_data).eom_b_comcod = *(vms_rec + 8); 401 if (PRIV(eom_data).eom_b_comcod > 1) 402 { 403 (*_bfd_error_handler) (_("Object module NOT error-free !\n")); 404 bfd_set_error (bfd_error_bad_value); 405 return -1; 406 } 407 PRIV(eom_data).eom_has_transfer = false; 408 if (PRIV(rec_size) > 10) 409 { 410 PRIV(eom_data).eom_has_transfer = true; 411 PRIV(eom_data).eom_b_tfrflg = *(vms_rec + 9); 412 PRIV(eom_data).eom_l_psindx = bfd_getl32 (vms_rec + 12); 413 PRIV(eom_data).eom_l_tfradr = bfd_getl32 (vms_rec + 16); 414 415 abfd->start_address = PRIV(eom_data).eom_l_tfradr; 416 } 417 } 418 return 0; 419 } 420 421 /* Write eom record for bfd abfd */ 422 423 int 424 _bfd_vms_write_eom (abfd, objtype) 425 bfd *abfd; 426 int objtype; 427 { 428 #if VMS_DEBUG 429 vms_debug (2, "vms_write_eom (%p, %d)\n", abfd, objtype); 430 #endif 431 432 _bfd_vms_output_begin (abfd, objtype, -1); 433 _bfd_vms_output_long (abfd, (unsigned long) (PRIV(vms_linkage_index) >> 1)); 434 _bfd_vms_output_byte (abfd, 0); /* completion code */ 435 _bfd_vms_output_byte (abfd, 0); /* fill byte */ 436 437 if (bfd_get_start_address (abfd) != (bfd_vma)-1) 438 { 439 asection *section; 440 441 section = bfd_get_section_by_name (abfd, ".link"); 442 if (section == 0) 443 { 444 bfd_set_error (bfd_error_nonrepresentable_section); 445 return -1; 446 } 447 _bfd_vms_output_short (abfd, 0); 448 _bfd_vms_output_long (abfd, (unsigned long) (section->index)); 449 _bfd_vms_output_long (abfd, 450 (unsigned long) bfd_get_start_address (abfd)); 451 _bfd_vms_output_long (abfd, 0); 452 } 453 454 _bfd_vms_output_end (abfd); 455 return 0; 456 } 457