Back to index

cell-binutils  2.17cvs20070401
vms.c
Go to the documentation of this file.
00001 /* vms.c -- BFD back-end for VAX (openVMS/VAX) and
00002    EVAX (openVMS/Alpha) files.
00003    Copyright 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005,
00004    2006, 2007 Free Software Foundation, Inc.
00005 
00006    Written by Klaus K"ampf (kkaempf@rmi.de)
00007 
00008    This program is free software; you can redistribute it and/or modify
00009    it under the terms of the GNU General Public License as published by
00010    the Free Software Foundation; either version 2 of the License, or
00011    (at your option) any later version.
00012 
00013    This program is distributed in the hope that it will be useful,
00014    but WITHOUT ANY WARRANTY; without even the implied warranty of
00015    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00016    GNU General Public License for more details.
00017 
00018    You should have received a copy of the GNU General Public License
00019    along with this program; if not, write to the Free Software
00020    Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA.  */
00021 
00022 #include "bfd.h"
00023 #include "sysdep.h"
00024 #include "bfdlink.h"
00025 #include "libbfd.h"
00026 
00027 #include "vms.h"
00028 
00029 #define vms_bfd_is_target_special_symbol ((bfd_boolean (*) (bfd *, asymbol *)) bfd_false)
00030 #define vms_make_empty_symbol             _bfd_generic_make_empty_symbol
00031 #define vms_bfd_link_just_syms            _bfd_generic_link_just_syms
00032 #define vms_bfd_is_group_section          bfd_generic_is_group_section
00033 #define vms_bfd_discard_group             bfd_generic_discard_group
00034 #define vms_section_already_linked        _bfd_generic_section_already_linked
00035 #define vms_bfd_copy_private_header_data  _bfd_generic_bfd_copy_private_header_data
00036 #define vms_get_synthetic_symtab          _bfd_nodynamic_get_synthetic_symtab
00037 
00038 static unsigned int priv_section_count;
00039 extern const bfd_target vms_vax_vec;
00040 extern const bfd_target vms_alpha_vec;
00041 
00042 /* Initialize private data.  */
00043 
00044 static bfd_boolean
00045 vms_initialize (bfd * abfd)
00046 {
00047   int i;
00048   bfd_size_type amt;
00049 
00050   bfd_set_start_address (abfd, (bfd_vma) -1);
00051 
00052   amt = sizeof (struct vms_private_data_struct);
00053   abfd->tdata.any = bfd_alloc (abfd, amt);
00054   if (abfd->tdata.any == NULL)
00055     return FALSE;
00056 
00057 #ifdef __ALPHA
00058   PRIV (is_vax) = FALSE;
00059 #else
00060   PRIV (is_vax) = TRUE;
00061 #endif
00062   PRIV (vms_buf) = NULL;
00063   PRIV (buf_size) = 0;
00064   PRIV (rec_length) = 0;
00065   PRIV (file_format) = FF_UNKNOWN;
00066   PRIV (fixup_done) = FALSE;
00067   PRIV (sections) = NULL;
00068 
00069   amt = sizeof (struct stack_struct) * STACKSIZE;
00070   PRIV (stack) = bfd_alloc (abfd, amt);
00071   if (PRIV (stack) == NULL)
00072     goto error_ret1;
00073   PRIV (stackptr) = 0;
00074 
00075   amt = sizeof (struct bfd_hash_table);
00076   PRIV (vms_symbol_table) = bfd_alloc (abfd, amt);
00077   if (PRIV (vms_symbol_table) == NULL)
00078     goto error_ret1;
00079 
00080   if (!bfd_hash_table_init (PRIV (vms_symbol_table), _bfd_vms_hash_newfunc,
00081                          sizeof (vms_symbol_entry)))
00082     goto error_ret1;
00083 
00084   amt = sizeof (struct location_struct) * LOCATION_SAVE_SIZE;
00085   PRIV (location_stack) = bfd_alloc (abfd, amt);
00086   if (PRIV (location_stack) == NULL)
00087     goto error_ret2;
00088 
00089   for (i = 0; i < VMS_SECTION_COUNT; i++)
00090     PRIV (vms_section_table)[i] = NULL;
00091 
00092   amt = MAX_OUTREC_SIZE;
00093   PRIV (output_buf) = bfd_alloc (abfd, amt);
00094   if (PRIV (output_buf) == NULL)
00095     goto error_ret2;
00096 
00097   PRIV (push_level) = 0;
00098   PRIV (pushed_size) = 0;
00099   PRIV (length_pos) = 2;
00100   PRIV (output_size) = 0;
00101   PRIV (output_alignment) = 1;
00102 
00103   return TRUE;
00104 
00105  error_ret2:
00106   bfd_hash_table_free (PRIV (vms_symbol_table));
00107  error_ret1:
00108   bfd_release (abfd, abfd->tdata.any);
00109   abfd->tdata.any = NULL;
00110   return FALSE;
00111 }
00112 
00113 /* Fill symbol->section with section ptr
00114    symbol->section is filled with the section index for defined symbols
00115    during reading the GSD/EGSD section. But we need the pointer to the
00116    bfd section later.
00117 
00118    It has the correct value for referenced (undefined section) symbols
00119 
00120    called from bfd_hash_traverse in vms_fixup_sections.  */
00121 
00122 static bfd_boolean
00123 fill_section_ptr (struct bfd_hash_entry * entry, void * sections)
00124 {
00125   asection *sec;
00126   asymbol *sym;
00127 
00128   sym = ((vms_symbol_entry *) entry)->symbol;
00129   sec = sym->section;
00130 
00131 #if VMS_DEBUG
00132   vms_debug (6, "fill_section_ptr: sym %p, sec %p\n", sym, sec);
00133 #endif
00134 
00135   /* Fill forward references (these contain section number, not section ptr).  */
00136   if ((unsigned int) (size_t) sec < priv_section_count)
00137     sec = ((vms_symbol_entry *) entry)->symbol->section =
00138       ((asection **) sections)[(unsigned int) (size_t) sec];
00139 
00140   if (strcmp (sym->name, sec->name) == 0)
00141     sym->flags |= BSF_SECTION_SYM;
00142 
00143   return TRUE;
00144 }
00145 
00146 /* Fixup sections
00147    set up all pointers and arrays, counters and sizes are fixed now
00148 
00149    we build a private sections vector for easy access since sections
00150    are always referenced by an index number.
00151 
00152    alloc PRIV(sections) according to abfd->section_count
00153        copy abfd->sections to PRIV(sections).  */
00154 
00155 static bfd_boolean
00156 vms_fixup_sections (bfd * abfd)
00157 {
00158   if (PRIV (fixup_done))
00159     return TRUE;
00160 
00161   /* Traverse symbol table and fill in all section pointers.  */
00162 
00163   /* Can't provide section count as argument to fill_section_ptr().  */
00164   priv_section_count = PRIV (section_count);
00165   bfd_hash_traverse (PRIV (vms_symbol_table), fill_section_ptr, (PRIV (sections)));
00166 
00167   PRIV (fixup_done) = TRUE;
00168 
00169   return TRUE;
00170 }
00171 
00172 /* Check the format for a file being read.
00173    Return a (bfd_target *) if it's an object file or zero if not.  */
00174 
00175 static const struct bfd_target *
00176 vms_object_p (bfd * abfd)
00177 {
00178   int err = 0;
00179   int prev_type;
00180   const struct bfd_target *target_vector = NULL;
00181   const bfd_arch_info_type *arch = NULL;
00182   void * tdata_save = abfd->tdata.any;
00183   bfd_vma saddr_save = bfd_get_start_address (abfd);
00184 
00185 #if VMS_DEBUG
00186   vms_debug (1, "vms_object_p (%p)\n", abfd);
00187 #endif
00188 
00189   if (!vms_initialize (abfd))
00190     goto error_ret;
00191 
00192   if (bfd_seek (abfd, (file_ptr) 0, SEEK_SET))
00193     goto err_wrong_format;
00194 
00195   prev_type = -1;
00196 
00197   do
00198     {
00199 #if VMS_DEBUG
00200       vms_debug (7, "reading at %08lx\n", bfd_tell (abfd));
00201 #endif
00202       if (_bfd_vms_next_record (abfd) < 0)
00203        {
00204 #if VMS_DEBUG
00205          vms_debug (2, "next_record failed\n");
00206 #endif
00207          goto err_wrong_format;
00208        }
00209 
00210       if ((prev_type == EOBJ_S_C_EGSD)
00211           && (PRIV (rec_type) != EOBJ_S_C_EGSD))
00212        {
00213          if (! vms_fixup_sections (abfd))
00214            {
00215 #if VMS_DEBUG
00216              vms_debug (2, "vms_fixup_sections failed\n");
00217 #endif
00218              goto err_wrong_format;
00219            }
00220        }
00221 
00222       prev_type = PRIV (rec_type);
00223 
00224       if (target_vector == NULL)
00225        {
00226          if (prev_type <= OBJ_S_C_MAXRECTYP)
00227            target_vector = & vms_vax_vec;
00228          else
00229            target_vector = & vms_alpha_vec;
00230        }
00231 
00232       switch (prev_type)
00233        {
00234          case OBJ_S_C_HDR:
00235          case EOBJ_S_C_EMH:
00236            err = _bfd_vms_slurp_hdr (abfd, prev_type);
00237            break;
00238          case OBJ_S_C_EOM:
00239          case OBJ_S_C_EOMW:
00240          case EOBJ_S_C_EEOM:
00241            err = _bfd_vms_slurp_eom (abfd, prev_type);
00242            break;
00243          case OBJ_S_C_GSD:
00244          case EOBJ_S_C_EGSD:
00245            err = _bfd_vms_slurp_gsd (abfd, prev_type);
00246            break;
00247          case OBJ_S_C_TIR:
00248          case EOBJ_S_C_ETIR:
00249            err = _bfd_vms_slurp_tir (abfd, prev_type);
00250            break;
00251          case OBJ_S_C_DBG:
00252          case EOBJ_S_C_EDBG:
00253            err = _bfd_vms_slurp_dbg (abfd, prev_type);
00254            break;
00255          case OBJ_S_C_TBT:
00256          case EOBJ_S_C_ETBT:
00257            err = _bfd_vms_slurp_tbt (abfd, prev_type);
00258            break;
00259          case OBJ_S_C_LNK:
00260            err = _bfd_vms_slurp_lnk (abfd, prev_type);
00261            break;
00262          default:
00263            err = -1;
00264        }
00265       if (err != 0)
00266        {
00267 #if VMS_DEBUG
00268          vms_debug (2, "slurp type %d failed with %d\n", prev_type, err);
00269 #endif
00270          goto err_wrong_format;
00271        }
00272     }
00273   while ((prev_type != EOBJ_S_C_EEOM) && (prev_type != OBJ_S_C_EOM) && (prev_type != OBJ_S_C_EOMW));
00274 
00275   if (target_vector == & vms_vax_vec)
00276     {
00277       if (! vms_fixup_sections (abfd))
00278        {
00279 #if VMS_DEBUG
00280          vms_debug (2, "vms_fixup_sections failed\n");
00281 #endif
00282          goto err_wrong_format;
00283        }
00284 
00285       /* Set arch_info to vax.  */
00286 
00287       arch = bfd_scan_arch ("vax");
00288       PRIV (is_vax) = TRUE;
00289 #if VMS_DEBUG
00290       vms_debug (2, "arch is vax\n");
00291 #endif
00292     }
00293   else if (target_vector == & vms_alpha_vec)
00294     {
00295       /* Set arch_info to alpha.   */
00296 
00297       arch = bfd_scan_arch ("alpha");
00298       PRIV (is_vax) = FALSE;
00299 #if VMS_DEBUG
00300       vms_debug (2, "arch is alpha\n");
00301 #endif
00302     }
00303 
00304   if (arch == NULL)
00305     {
00306 #if VMS_DEBUG
00307       vms_debug (2, "arch not found\n");
00308 #endif
00309       goto err_wrong_format;
00310     }
00311   abfd->arch_info = arch;
00312 
00313   return target_vector;
00314 
00315  err_wrong_format:
00316   bfd_set_error (bfd_error_wrong_format);
00317  error_ret:
00318   if (abfd->tdata.any != tdata_save && abfd->tdata.any != NULL)
00319     bfd_release (abfd, abfd->tdata.any);
00320   abfd->tdata.any = tdata_save;
00321   bfd_set_start_address (abfd, saddr_save);
00322   return NULL;
00323 }
00324 
00325 /* Check the format for a file being read.
00326    Return a (bfd_target *) if it's an archive file or zero.  */
00327 
00328 static const struct bfd_target *
00329 vms_archive_p (bfd * abfd ATTRIBUTE_UNUSED)
00330 {
00331 #if VMS_DEBUG
00332   vms_debug (1, "vms_archive_p (%p)\n", abfd);
00333 #endif
00334 
00335   return NULL;
00336 }
00337 
00338 /* Set the format of a file being written.  */
00339 
00340 static bfd_boolean
00341 vms_mkobject (bfd * abfd)
00342 {
00343 #if VMS_DEBUG
00344   vms_debug (1, "vms_mkobject (%p)\n", abfd);
00345 #endif
00346 
00347   if (!vms_initialize (abfd))
00348     return FALSE;
00349 
00350   {
00351 #ifdef __VAX
00352     const bfd_arch_info_type *arch = bfd_scan_arch ("vax");
00353 #else
00354     const bfd_arch_info_type *arch = bfd_scan_arch ("alpha");
00355 #endif
00356     if (arch == NULL)
00357       {
00358        bfd_set_error (bfd_error_wrong_format);
00359        return FALSE;
00360       }
00361     abfd->arch_info = arch;
00362   }
00363 
00364   return TRUE;
00365 }
00366 
00367 /* Write cached information into a file being written, at bfd_close.  */
00368 
00369 static bfd_boolean
00370 vms_write_object_contents (bfd * abfd)
00371 {
00372 #if VMS_DEBUG
00373   vms_debug (1, "vms_write_object_contents (%p)\n", abfd);
00374 #endif
00375 
00376   if (abfd->section_count > 0)                   /* we have sections */
00377     {
00378       if (PRIV (is_vax))
00379        {
00380          if (_bfd_vms_write_hdr (abfd, OBJ_S_C_HDR) != 0)
00381            return FALSE;
00382          if (_bfd_vms_write_gsd (abfd, OBJ_S_C_GSD) != 0)
00383            return FALSE;
00384          if (_bfd_vms_write_tir (abfd, OBJ_S_C_TIR) != 0)
00385            return FALSE;
00386          if (_bfd_vms_write_tbt (abfd, OBJ_S_C_TBT) != 0)
00387            return FALSE;
00388          if (_bfd_vms_write_dbg (abfd, OBJ_S_C_DBG) != 0)
00389            return FALSE;
00390          if (abfd->section_count > 255)
00391            {
00392              if (_bfd_vms_write_eom (abfd, OBJ_S_C_EOMW) != 0)
00393               return FALSE;
00394            }
00395          else
00396            {
00397              if (_bfd_vms_write_eom (abfd, OBJ_S_C_EOM) != 0)
00398               return FALSE;
00399            }
00400        }
00401       else
00402        {
00403          if (_bfd_vms_write_hdr (abfd, EOBJ_S_C_EMH) != 0)
00404            return FALSE;
00405          if (_bfd_vms_write_gsd (abfd, EOBJ_S_C_EGSD) != 0)
00406            return FALSE;
00407          if (_bfd_vms_write_tir (abfd, EOBJ_S_C_ETIR) != 0)
00408            return FALSE;
00409          if (_bfd_vms_write_tbt (abfd, EOBJ_S_C_ETBT) != 0)
00410            return FALSE;
00411          if (_bfd_vms_write_dbg (abfd, EOBJ_S_C_EDBG) != 0)
00412            return FALSE;
00413          if (_bfd_vms_write_eom (abfd, EOBJ_S_C_EEOM) != 0)
00414            return FALSE;
00415        }
00416     }
00417   return TRUE;
00418 }
00419 
00420 /* 4.1, generic.  */
00421 
00422 /* Called when the BFD is being closed to do any necessary cleanup.  */
00423 
00424 static bfd_boolean
00425 vms_close_and_cleanup (bfd * abfd)
00426 {
00427 #if VMS_DEBUG
00428   vms_debug (1, "vms_close_and_cleanup (%p)\n", abfd);
00429 #endif
00430   if (abfd == NULL)
00431     return TRUE;
00432 
00433   if (PRIV (vms_buf) != NULL)
00434     free (PRIV (vms_buf));
00435 
00436   if (PRIV (sections) != NULL)
00437     free (PRIV (sections));
00438 
00439   if (PRIV (vms_symbol_table))
00440     bfd_hash_table_free (PRIV (vms_symbol_table));
00441 
00442   bfd_release (abfd, abfd->tdata.any);
00443   abfd->tdata.any = NULL;
00444 
00445   return TRUE;
00446 }
00447 
00448 /* Ask the BFD to free all cached information.  */
00449 
00450 static bfd_boolean
00451 vms_bfd_free_cached_info (bfd * abfd ATTRIBUTE_UNUSED)
00452 {
00453 #if VMS_DEBUG
00454   vms_debug (1, "vms_bfd_free_cached_info (%p)\n", abfd);
00455 #endif
00456   return TRUE;
00457 }
00458 
00459 /* Called when a new section is created.  */
00460 
00461 static bfd_boolean
00462 vms_new_section_hook (bfd * abfd, asection *section)
00463 {
00464   /* Count hasn't been incremented yet.  */
00465   unsigned int section_count = abfd->section_count + 1;
00466 
00467 #if VMS_DEBUG
00468   vms_debug (1, "vms_new_section_hook (%p, [%d]%s), count %d\n",
00469             abfd, section->index, section->name, section_count);
00470 #endif
00471   bfd_set_section_alignment (abfd, section, 4);
00472 
00473   if (section_count > PRIV (section_count))
00474     {
00475       bfd_size_type amt = section_count;
00476       amt *= sizeof (asection *);
00477       PRIV (sections) = bfd_realloc (PRIV (sections), amt);
00478       if (PRIV (sections) == NULL)
00479        return FALSE;
00480       PRIV (section_count) = section_count;
00481     }
00482 #if VMS_DEBUG
00483   vms_debug (6, "section_count: %d\n", PRIV (section_count));
00484 #endif
00485   PRIV (sections)[section->index] = section;
00486 #if VMS_DEBUG
00487   vms_debug (7, "%d: %s\n", section->index, section->name);
00488 #endif
00489 
00490   return _bfd_generic_new_section_hook (abfd, section);
00491 }
00492 
00493 /* Read the contents of a section.
00494    buf points to a buffer of buf_size bytes to be filled with
00495    section data (starting at offset into section)  */
00496 
00497 static bfd_boolean
00498 vms_get_section_contents (bfd * abfd ATTRIBUTE_UNUSED,
00499                        asection *section ATTRIBUTE_UNUSED,
00500                        void * buf ATTRIBUTE_UNUSED,
00501                        file_ptr offset ATTRIBUTE_UNUSED,
00502                        bfd_size_type buf_size ATTRIBUTE_UNUSED)
00503 {
00504 #if VMS_DEBUG
00505   vms_debug (1, "vms_get_section_contents (%p, %s, %p, off %ld, size %d)\n",
00506                abfd, section->name, buf, offset, (int)buf_size);
00507 #endif
00508 
00509   /* Shouldn't be called, since all sections are IN_MEMORY.  */
00510   return FALSE;
00511 }
00512 
00513 /* Read the contents of a section.
00514    buf points to a buffer of buf_size bytes to be filled with
00515    section data (starting at offset into section).  */
00516 
00517 static bfd_boolean
00518 vms_get_section_contents_in_window (bfd * abfd ATTRIBUTE_UNUSED,
00519                                 asection *section ATTRIBUTE_UNUSED,
00520                                 bfd_window *w ATTRIBUTE_UNUSED,
00521                                 file_ptr offset ATTRIBUTE_UNUSED,
00522                                 bfd_size_type count ATTRIBUTE_UNUSED)
00523 {
00524 #if VMS_DEBUG
00525   vms_debug (1, "vms_get_section_contents_in_window (%p, %s, %p, off %ld, count %d)\n",
00526                abfd, section->name, w, offset, (int)count);
00527 #endif
00528 
00529   /* Shouldn't be called, since all sections are IN_MEMORY.  */
00530   return FALSE;
00531 }
00532 
00533 /* Part 4.2, copy private data.  */
00534 
00535 /* Called to copy BFD general private data from one object file
00536    to another.  */
00537 
00538 static bfd_boolean
00539 vms_bfd_copy_private_bfd_data (bfd *src ATTRIBUTE_UNUSED,
00540                             bfd *dest ATTRIBUTE_UNUSED)
00541 {
00542 #if VMS_DEBUG
00543   vms_debug (1, "vms_bfd_copy_private_bfd_data (%p, %p)\n", src, dest);
00544 #endif
00545   return TRUE;
00546 }
00547 
00548 /* Merge private BFD information from the BFD @var{ibfd} to the
00549    the output file BFD @var{obfd} when linking.  Return <<TRUE>>
00550    on success, <<FALSE>> on error.  Possible error returns are:
00551 
00552    o <<bfd_error_no_memory>> -
00553      Not enough memory exists to create private data for @var{obfd}.  */
00554 
00555 static bfd_boolean
00556 vms_bfd_merge_private_bfd_data (bfd * ibfd ATTRIBUTE_UNUSED,
00557                             bfd * obfd ATTRIBUTE_UNUSED)
00558 {
00559 #if VMS_DEBUG
00560   vms_debug (1,"vms_bfd_merge_private_bfd_data (%p, %p)\n", ibfd, obfd);
00561 #endif
00562   return TRUE;
00563 }
00564 
00565 /* Set private BFD flag information in the BFD @var{abfd}.
00566    Return <<TRUE>> on success, <<FALSE>> on error.  Possible error
00567    returns are:
00568 
00569    o <<bfd_error_no_memory>> -
00570      Not enough memory exists to create private data for @var{obfd}.  */
00571 
00572 static bfd_boolean
00573 vms_bfd_set_private_flags (bfd * abfd ATTRIBUTE_UNUSED,
00574                         flagword flags ATTRIBUTE_UNUSED)
00575 {
00576 #if VMS_DEBUG
00577   vms_debug (1,"vms_bfd_set_private_flags (%p, %lx)\n", abfd, (long)flags);
00578 #endif
00579   return TRUE;
00580 }
00581 
00582 /* Called to copy BFD private section data from one object file
00583    to another.  */
00584 
00585 static bfd_boolean
00586 vms_bfd_copy_private_section_data (bfd *srcbfd ATTRIBUTE_UNUSED,
00587                                asection *srcsec ATTRIBUTE_UNUSED,
00588                                bfd *dstbfd ATTRIBUTE_UNUSED,
00589                                asection *dstsec ATTRIBUTE_UNUSED)
00590 {
00591 #if VMS_DEBUG
00592   vms_debug (1, "vms_bfd_copy_private_section_data (%p, %s, %p, %s)\n",
00593                srcbfd, srcsec->name, dstbfd, dstsec->name);
00594 #endif
00595   return TRUE;
00596 }
00597 
00598 /* Called to copy BFD private symbol data from one object file
00599    to another.  */
00600 
00601 static bfd_boolean
00602 vms_bfd_copy_private_symbol_data (bfd *ibfd ATTRIBUTE_UNUSED,
00603                               asymbol *isym ATTRIBUTE_UNUSED,
00604                               bfd *obfd ATTRIBUTE_UNUSED,
00605                               asymbol *osym ATTRIBUTE_UNUSED)
00606 {
00607 #if VMS_DEBUG
00608   vms_debug (1, "vms_bfd_copy_private_symbol_data (%p, %s, %p, %s)\n",
00609                ibfd, isym->name, obfd, osym->name);
00610 #endif
00611   return TRUE;
00612 }
00613 
00614 /* Part 4.3, core file.  */
00615 
00616 /* Return a read-only string explaining which program was running
00617    when it failed and produced the core file abfd.  */
00618 
00619 static char *
00620 vms_core_file_failing_command (bfd * abfd ATTRIBUTE_UNUSED)
00621 {
00622 #if VMS_DEBUG
00623   vms_debug (1, "vms_core_file_failing_command (%p)\n", abfd);
00624 #endif
00625   return NULL;
00626 }
00627 
00628 /* Returns the signal number which caused the core dump which
00629    generated the file the BFD abfd is attached to.  */
00630 
00631 static int
00632 vms_core_file_failing_signal (bfd * abfd ATTRIBUTE_UNUSED)
00633 {
00634 #if VMS_DEBUG
00635   vms_debug (1, "vms_core_file_failing_signal (%p)\n", abfd);
00636 #endif
00637   return 0;
00638 }
00639 
00640 /* Return TRUE if the core file attached to core_bfd was generated
00641    by a run of the executable file attached to exec_bfd, FALSE otherwise.  */
00642 
00643 static bfd_boolean
00644 vms_core_file_matches_executable_p (bfd * abfd ATTRIBUTE_UNUSED,
00645                                 bfd *bbfd ATTRIBUTE_UNUSED)
00646 {
00647 #if VMS_DEBUG
00648   vms_debug (1, "vms_core_file_matches_executable_p (%p, %p)\n", abfd, bbfd);
00649 #endif
00650   return FALSE;
00651 }
00652 
00653 /* Part 4.4, archive.  */
00654 
00655 /* ??? do something with an archive map.
00656    Return FALSE on error, TRUE otherwise.  */
00657 
00658 static bfd_boolean
00659 vms_slurp_armap (bfd * abfd ATTRIBUTE_UNUSED)
00660 {
00661 #if VMS_DEBUG
00662   vms_debug (1, "vms_slurp_armap (%p)\n", abfd);
00663 #endif
00664   return FALSE;
00665 }
00666 
00667 /* ??? do something with an extended name table.
00668    Return FALSE on error, TRUE otherwise.  */
00669 
00670 static bfd_boolean
00671 vms_slurp_extended_name_table (bfd * abfd ATTRIBUTE_UNUSED)
00672 {
00673 #if VMS_DEBUG
00674   vms_debug (1, "vms_slurp_extended_name_table (%p)\n", abfd);
00675 #endif
00676   return FALSE;
00677 }
00678 
00679 /* ??? do something with an extended name table.
00680    Return FALSE on error, TRUE otherwise.  */
00681 
00682 static bfd_boolean
00683 vms_construct_extended_name_table (bfd * abfd ATTRIBUTE_UNUSED,
00684                                char **tabloc ATTRIBUTE_UNUSED,
00685                                bfd_size_type *tablen ATTRIBUTE_UNUSED,
00686                                const char **name ATTRIBUTE_UNUSED)
00687 {
00688 #if VMS_DEBUG
00689   vms_debug (1, "vms_construct_extended_name_table (%p)\n", abfd);
00690 #endif
00691   return FALSE;
00692 }
00693 
00694 /* Truncate the name of an archive to match system-dependent restrictions.  */
00695 
00696 static void
00697 vms_truncate_arname (bfd * abfd ATTRIBUTE_UNUSED,
00698                    const char *pathname ATTRIBUTE_UNUSED,
00699                    char *arhdr ATTRIBUTE_UNUSED)
00700 {
00701 #if VMS_DEBUG
00702   vms_debug (1, "vms_truncate_arname (%p, %s, %s)\n", abfd, pathname, arhdr);
00703 #endif
00704   return;
00705 }
00706 
00707 /* ??? write archive map.  */
00708 
00709 static bfd_boolean
00710 vms_write_armap (bfd *arch ATTRIBUTE_UNUSED,
00711                unsigned int elength ATTRIBUTE_UNUSED,
00712                struct orl *map ATTRIBUTE_UNUSED,
00713                unsigned int orl_count ATTRIBUTE_UNUSED,
00714                int stridx ATTRIBUTE_UNUSED)
00715 {
00716 #if VMS_DEBUG
00717   vms_debug (1, "vms_write_armap (%p, %d, %p, %d %d)\n",
00718        arch, elength, map, orl_count, stridx);
00719 #endif
00720   return TRUE;
00721 }
00722 
00723 /* Read archive header ???  */
00724 
00725 static void *
00726 vms_read_ar_hdr (bfd * abfd ATTRIBUTE_UNUSED)
00727 {
00728 #if VMS_DEBUG
00729   vms_debug (1, "vms_read_ar_hdr (%p)\n", abfd);
00730 #endif
00731   return NULL;
00732 }
00733 
00734 /* Provided a BFD, @var{archive}, containing an archive and NULL, open
00735    an input BFD on the first contained element and returns that.
00736    Subsequent calls should pass the archive and the previous return value
00737    to return a created BFD to the next contained element.
00738    NULL is returned when there are no more.  */
00739 
00740 static bfd *
00741 vms_openr_next_archived_file (bfd *arch ATTRIBUTE_UNUSED,
00742                            bfd *prev ATTRIBUTE_UNUSED)
00743 {
00744 #if VMS_DEBUG
00745   vms_debug (1, "vms_openr_next_archived_file (%p, %p)\n", arch, prev);
00746 #endif
00747   return NULL;
00748 }
00749 
00750 /* Return the BFD which is referenced by the symbol in ABFD indexed by
00751    INDEX.  INDEX should have been returned by bfd_get_next_mapent.  */
00752 
00753 static bfd *
00754 vms_get_elt_at_index (bfd * abfd, symindex index)
00755 {
00756 #if VMS_DEBUG
00757   vms_debug (1, "vms_get_elt_at_index (%p, %p)\n", abfd, index);
00758 #endif
00759   return _bfd_generic_get_elt_at_index (abfd, index);
00760 }
00761 
00762 /* ???
00763    -> bfd_generic_stat_arch_elt.  */
00764 
00765 static int
00766 vms_generic_stat_arch_elt (bfd * abfd, struct stat *st)
00767 {
00768 #if VMS_DEBUG
00769   vms_debug (1, "vms_generic_stat_arch_elt (%p, %p)\n", abfd, st);
00770 #endif
00771   return bfd_generic_stat_arch_elt (abfd, st);
00772 }
00773 
00774 /* This is a new function in bfd 2.5.  */
00775 
00776 static bfd_boolean
00777 vms_update_armap_timestamp (bfd * abfd ATTRIBUTE_UNUSED)
00778 {
00779 #if VMS_DEBUG
00780   vms_debug (1, "vms_update_armap_timestamp (%p)\n", abfd);
00781 #endif
00782   return TRUE;
00783 }
00784 
00785 /* Part 4.5, symbols.  */
00786 
00787 /* Return the number of bytes required to store a vector of pointers
00788    to asymbols for all the symbols in the BFD abfd, including a
00789    terminal NULL pointer. If there are no symbols in the BFD,
00790    then return 0.  If an error occurs, return -1.  */
00791 
00792 static long
00793 vms_get_symtab_upper_bound (bfd * abfd)
00794 {
00795 #if VMS_DEBUG
00796   vms_debug (1, "vms_get_symtab_upper_bound (%p), %d symbols\n", abfd, PRIV (gsd_sym_count));
00797 #endif
00798   return (PRIV (gsd_sym_count) + 1) * sizeof (asymbol *);
00799 }
00800 
00801 /* Copy symbols from hash table to symbol vector
00802 
00803    called from bfd_hash_traverse in vms_canonicalize_symtab
00804    init counter to 0 if entry == 0.  */
00805 
00806 static bfd_boolean
00807 copy_symbols (struct bfd_hash_entry *entry, void * arg)
00808 {
00809   bfd * abfd = (bfd *) arg;
00810 
00811   if (entry == NULL) /* Init counter.  */
00812     PRIV (symnum) = 0;
00813   else               /* Fill vector, inc counter.  */
00814     PRIV (symcache)[PRIV (symnum)++] = ((vms_symbol_entry *)entry)->symbol;
00815 
00816   return TRUE;
00817 }
00818 
00819 /* Read the symbols from the BFD abfd, and fills in the vector
00820    location with pointers to the symbols and a trailing NULL.
00821 
00822    Return number of symbols read.   */
00823 
00824 static long
00825 vms_canonicalize_symtab (bfd * abfd, asymbol **symbols)
00826 {
00827 #if VMS_DEBUG
00828   vms_debug (1, "vms_canonicalize_symtab (%p, <ret>)\n", abfd);
00829 #endif
00830 
00831   /* Init counter.  */
00832   copy_symbols (NULL, abfd);
00833 
00834   /* Traverse table and fill symbols vector.  */
00835   PRIV (symcache) = symbols;
00836   bfd_hash_traverse (PRIV (vms_symbol_table), copy_symbols, abfd);
00837 
00838   symbols[PRIV (gsd_sym_count)] = NULL;
00839 
00840   return PRIV (gsd_sym_count);
00841 }
00842 
00843 /* Print symbol to file according to how. how is one of
00844    bfd_print_symbol_name    just print the name
00845    bfd_print_symbol_more    print more (???)
00846    bfd_print_symbol_all     print all we know, which is not much right now :-).  */
00847 
00848 static void
00849 vms_print_symbol (bfd * abfd,
00850                 void * file,
00851                 asymbol *symbol,
00852                 bfd_print_symbol_type how)
00853 {
00854 #if VMS_DEBUG
00855   vms_debug (1, "vms_print_symbol (%p, %p, %p, %d)\n", abfd, file, symbol, how);
00856 #endif
00857 
00858   switch (how)
00859     {
00860       case bfd_print_symbol_name:
00861       case bfd_print_symbol_more:
00862        fprintf ((FILE *)file," %s", symbol->name);
00863       break;
00864 
00865       case bfd_print_symbol_all:
00866        {
00867          const char *section_name = symbol->section->name;
00868 
00869          bfd_print_symbol_vandf (abfd, file, symbol);
00870 
00871          fprintf ((FILE *) file," %-8s %s", section_name, symbol->name);
00872         }
00873       break;
00874     }
00875 }
00876 
00877 /* Return information about symbol in ret.
00878 
00879    fill type, value and name
00880    type:
00881        A      absolute
00882        B      bss segment symbol
00883        C      common symbol
00884        D      data segment symbol
00885        f      filename
00886        t      a static function symbol
00887        T      text segment symbol
00888        U      undefined
00889        -      debug.  */
00890 
00891 static void
00892 vms_get_symbol_info (bfd * abfd ATTRIBUTE_UNUSED,
00893                    asymbol *symbol,
00894                    symbol_info *ret)
00895 {
00896   asection *sec;
00897 
00898 #if VMS_DEBUG
00899   vms_debug (1, "vms_get_symbol_info (%p, %p, %p)\n", abfd, symbol, ret);
00900 #endif
00901 
00902   sec = symbol->section;
00903 
00904   if (ret == NULL)
00905     return;
00906 
00907   if (bfd_is_com_section (sec))
00908     ret->type = 'C';
00909   else if (bfd_is_abs_section (sec))
00910     ret->type = 'A';
00911   else if (bfd_is_und_section (sec))
00912     ret->type = 'U';
00913   else if (bfd_is_ind_section (sec))
00914     ret->type = 'I';
00915   else if (bfd_get_section_flags (abfd, sec) & SEC_CODE)
00916     ret->type = 'T';
00917   else if (bfd_get_section_flags (abfd, sec) & SEC_DATA)
00918     ret->type = 'D';
00919   else if (bfd_get_section_flags (abfd, sec) & SEC_ALLOC)
00920     ret->type = 'B';
00921   else
00922     ret->type = '-';
00923 
00924   if (ret->type != 'U')
00925     ret->value = symbol->value + symbol->section->vma;
00926   else
00927     ret->value = 0;
00928   ret->name = symbol->name;
00929 }
00930 
00931 /* Return TRUE if the given symbol sym in the BFD abfd is
00932    a compiler generated local label, else return FALSE.  */
00933 
00934 static bfd_boolean
00935 vms_bfd_is_local_label_name (bfd * abfd ATTRIBUTE_UNUSED,
00936                           const char *name)
00937 {
00938 #if VMS_DEBUG
00939   vms_debug (1, "vms_bfd_is_local_label_name (%p, %s)\n", abfd, name);
00940 #endif
00941   return name[0] == '$';
00942 }
00943 
00944 /* Get source line number for symbol.  */
00945 
00946 static alent *
00947 vms_get_lineno (bfd * abfd ATTRIBUTE_UNUSED,
00948               asymbol *symbol ATTRIBUTE_UNUSED)
00949 {
00950 #if VMS_DEBUG
00951   vms_debug (1, "vms_get_lineno (%p, %p)\n", abfd, symbol);
00952 #endif
00953   return NULL;
00954 }
00955 
00956 /* Provided a BFD, a section and an offset into the section, calculate and
00957    return the name of the source file and the line nearest to the wanted
00958    location.  */
00959 
00960 static bfd_boolean
00961 vms_find_nearest_line (bfd * abfd ATTRIBUTE_UNUSED,
00962                      asection *section ATTRIBUTE_UNUSED,
00963                      asymbol **symbols ATTRIBUTE_UNUSED,
00964                      bfd_vma offset ATTRIBUTE_UNUSED,
00965                      const char **file ATTRIBUTE_UNUSED,
00966                      const char **func ATTRIBUTE_UNUSED,
00967                      unsigned int *line ATTRIBUTE_UNUSED)
00968 {
00969 #if VMS_DEBUG
00970   vms_debug (1, "vms_find_nearest_line (%p, %s, %p, %ld, <ret>, <ret>, <ret>)\n",
00971              abfd, section->name, symbols, (long int)offset);
00972 #endif
00973   return FALSE;
00974 }
00975 
00976 static bfd_boolean
00977 vms_find_inliner_info (bfd * abfd ATTRIBUTE_UNUSED,
00978                      const char **file ATTRIBUTE_UNUSED,
00979                      const char **func ATTRIBUTE_UNUSED,
00980                      unsigned int *line ATTRIBUTE_UNUSED)
00981 {
00982 #if VMS_DEBUG
00983   vms_debug (1, "vms_find_inliner_info (%p, <ret>, <ret>, <ret>)\n",
00984             abfd);
00985 #endif
00986   return FALSE;
00987 }
00988 
00989 /* Back-door to allow format-aware applications to create debug symbols
00990    while using BFD for everything else.  Currently used by the assembler
00991    when creating COFF files.  */
00992 
00993 static asymbol *
00994 vms_bfd_make_debug_symbol (bfd * abfd ATTRIBUTE_UNUSED,
00995                         void *ptr ATTRIBUTE_UNUSED,
00996                         unsigned long size ATTRIBUTE_UNUSED)
00997 {
00998 #if VMS_DEBUG
00999   vms_debug (1, "vms_bfd_make_debug_symbol (%p, %p, %ld)\n", abfd, ptr, size);
01000 #endif
01001   return NULL;
01002 }
01003 
01004 /* Read minisymbols.  For minisymbols, we use the unmodified a.out
01005    symbols.  The minisymbol_to_symbol function translates these into
01006    BFD asymbol structures.  */
01007 
01008 static long
01009 vms_read_minisymbols (bfd * abfd,
01010                     bfd_boolean dynamic,
01011                     void * *minisymsp,
01012                     unsigned int *sizep)
01013 {
01014 #if VMS_DEBUG
01015   vms_debug (1, "vms_read_minisymbols (%p, %d, %p, %d)\n", abfd, dynamic, minisymsp, *sizep);
01016 #endif
01017   return _bfd_generic_read_minisymbols (abfd, dynamic, minisymsp, sizep);
01018 }
01019 
01020 /* Convert a minisymbol to a BFD asymbol.  A minisymbol is just an
01021    unmodified a.out symbol.  The SYM argument is a structure returned
01022    by bfd_make_empty_symbol, which we fill in here.  */
01023 
01024 static asymbol *
01025 vms_minisymbol_to_symbol (bfd * abfd,
01026                        bfd_boolean dynamic,
01027                        const void * minisym,
01028                        asymbol *sym)
01029 {
01030 #if VMS_DEBUG
01031   vms_debug (1, "vms_minisymbol_to_symbol (%p, %d, %p, %p)\n", abfd, dynamic, minisym, sym);
01032 #endif
01033   return _bfd_generic_minisymbol_to_symbol (abfd, dynamic, minisym, sym);
01034 }
01035 
01036 /* Part 4.6, relocations.  */
01037 
01038 /* Return the number of bytes required to store the relocation information
01039    associated with section sect attached to bfd abfd.
01040    If an error occurs, return -1.  */
01041 
01042 static long
01043 vms_get_reloc_upper_bound (bfd * abfd ATTRIBUTE_UNUSED,
01044                         asection *section ATTRIBUTE_UNUSED)
01045 {
01046 #if VMS_DEBUG
01047   vms_debug (1, "vms_get_reloc_upper_bound (%p, %s)\n", abfd, section->name);
01048 #endif
01049   return -1L;
01050 }
01051 
01052 /* Call the back end associated with the open BFD abfd and translate the
01053    external form of the relocation information attached to sec into the
01054    internal canonical form.  Place the table into memory at loc, which has
01055    been preallocated, usually by a call to bfd_get_reloc_upper_bound.
01056    Returns the number of relocs, or -1 on error.  */
01057 
01058 static long
01059 vms_canonicalize_reloc (bfd * abfd ATTRIBUTE_UNUSED,
01060                      asection *section ATTRIBUTE_UNUSED,
01061                      arelent **location ATTRIBUTE_UNUSED,
01062                      asymbol **symbols ATTRIBUTE_UNUSED)
01063 {
01064 #if VMS_DEBUG
01065   vms_debug (1, "vms_canonicalize_reloc (%p, %s, <ret>, <ret>)\n", abfd, section->name);
01066 #endif
01067   return FALSE;
01068 }
01069 
01070 /* This is just copied from ecoff-alpha, needs to be fixed probably.  */
01071 
01072 /* How to process the various reloc types.  */
01073 
01074 static bfd_reloc_status_type
01075 reloc_nil (bfd * abfd ATTRIBUTE_UNUSED,
01076           arelent *reloc ATTRIBUTE_UNUSED,
01077           asymbol *sym ATTRIBUTE_UNUSED,
01078           void * data ATTRIBUTE_UNUSED,
01079           asection *sec ATTRIBUTE_UNUSED,
01080           bfd *output_bfd ATTRIBUTE_UNUSED,
01081           char **error_message ATTRIBUTE_UNUSED)
01082 {
01083 #if VMS_DEBUG
01084   vms_debug (1, "reloc_nil (abfd %p, output_bfd %p)\n", abfd, output_bfd);
01085   vms_debug (2, "In section %s, symbol %s\n",
01086        sec->name, sym->name);
01087   vms_debug (2, "reloc sym %s, addr %08lx, addend %08lx, reloc is a %s\n",
01088               reloc->sym_ptr_ptr[0]->name,
01089               (unsigned long)reloc->address,
01090               (unsigned long)reloc->addend, reloc->howto->name);
01091   vms_debug (2, "data at %p\n", data);
01092   /*  _bfd_hexdump (2, data, bfd_get_reloc_size (reloc->howto), 0); */
01093 #endif
01094 
01095   return bfd_reloc_ok;
01096 }
01097 
01098 /* In case we're on a 32-bit machine, construct a 64-bit "-1" value
01099    from smaller values.  Start with zero, widen, *then* decrement.  */
01100 #define MINUS_ONE    (((bfd_vma)0) - 1)
01101 
01102 static reloc_howto_type alpha_howto_table[] =
01103 {
01104   HOWTO (ALPHA_R_IGNORE,    /* Type.  */
01105         0,                  /* Rightshift.  */
01106         0,                  /* Size (0 = byte, 1 = short, 2 = long).  */
01107         8,                  /* Bitsize.  */
01108         TRUE,               /* PC relative.  */
01109         0,                  /* Bitpos.  */
01110         complain_overflow_dont,/* Complain_on_overflow.  */
01111         reloc_nil,          /* Special_function.  */
01112         "IGNORE",           /* Name.  */
01113         TRUE,               /* Partial_inplace.  */
01114         0,                  /* Source mask */
01115         0,                  /* Dest mask.  */
01116         TRUE),                     /* PC rel offset.  */
01117 
01118   /* A 64 bit reference to a symbol.  */
01119   HOWTO (ALPHA_R_REFQUAD,   /* Type.  */
01120         0,                  /* Rightshift.  */
01121         4,                  /* Size (0 = byte, 1 = short, 2 = long).  */
01122         64,                 /* Bitsize.  */
01123         FALSE,                     /* PC relative.  */
01124         0,                  /* Bitpos.  */
01125         complain_overflow_bitfield, /* Complain_on_overflow.  */
01126         reloc_nil,          /* Special_function.  */
01127         "REFQUAD",          /* Name.  */
01128         TRUE,               /* Partial_inplace.  */
01129         MINUS_ONE,          /* Source mask.  */
01130         MINUS_ONE,          /* Dest mask.  */
01131         FALSE),             /* PC rel offset.  */
01132 
01133   /* A 21 bit branch.  The native assembler generates these for
01134      branches within the text segment, and also fills in the PC
01135      relative offset in the instruction.  */
01136   HOWTO (ALPHA_R_BRADDR,    /* Type.  */
01137         2,                  /* Rightshift.  */
01138         2,                  /* Size (0 = byte, 1 = short, 2 = long).  */
01139         21,                 /* Bitsize.  */
01140         TRUE,               /* PC relative.  */
01141         0,                  /* Bitpos.  */
01142         complain_overflow_signed, /* Complain_on_overflow.  */
01143         reloc_nil,          /* Special_function.  */
01144         "BRADDR",           /* Name.  */
01145         TRUE,               /* Partial_inplace.  */
01146         0x1fffff,           /* Source mask.  */
01147         0x1fffff,           /* Dest mask.  */
01148         FALSE),             /* PC rel offset.  */
01149 
01150   /* A hint for a jump to a register.  */
01151   HOWTO (ALPHA_R_HINT,             /* Type.  */
01152         2,                  /* Rightshift.  */
01153         1,                  /* Size (0 = byte, 1 = short, 2 = long).  */
01154         14,                 /* Bitsize.  */
01155         TRUE,               /* PC relative.  */
01156         0,                  /* Bitpos.  */
01157         complain_overflow_dont,/* Complain_on_overflow.  */
01158         reloc_nil,          /* Special_function.  */
01159         "HINT",             /* Name.  */
01160         TRUE,               /* Partial_inplace.  */
01161         0x3fff,             /* Source mask.  */
01162         0x3fff,             /* Dest mask.  */
01163         FALSE),             /* PC rel offset.  */
01164 
01165   /* 16 bit PC relative offset.  */
01166   HOWTO (ALPHA_R_SREL16,    /* Type.  */
01167         0,                  /* Rightshift.  */
01168         1,                  /* Size (0 = byte, 1 = short, 2 = long).  */
01169         16,                 /* Bitsize.  */
01170         TRUE,               /* PC relative.  */
01171         0,                  /* Bitpos.  */
01172         complain_overflow_signed, /* Complain_on_overflow.  */
01173         reloc_nil,          /* Special_function.  */
01174         "SREL16",           /* Name.  */
01175         TRUE,               /* Partial_inplace.  */
01176         0xffff,             /* Source mask.  */
01177         0xffff,             /* Dest mask.  */
01178         FALSE),             /* PC rel offset.  */
01179 
01180   /* 32 bit PC relative offset.  */
01181   HOWTO (ALPHA_R_SREL32,    /* Type.  */
01182         0,                  /* Rightshift.  */
01183         2,                  /* Size (0 = byte, 1 = short, 2 = long).  */
01184         32,                 /* Bitsize.  */
01185         TRUE,               /* PC relative.  */
01186         0,                  /* Bitpos.  */
01187         complain_overflow_signed, /* Complain_on_overflow.  */
01188         reloc_nil,          /* Special_function.  */
01189         "SREL32",           /* Name.  */
01190         TRUE,               /* Partial_inplace.  */
01191         0xffffffff,         /* Source mask.  */
01192         0xffffffff,         /* Dest mask.  */
01193         FALSE),             /* PC rel offset.  */
01194 
01195   /* A 64 bit PC relative offset.  */
01196   HOWTO (ALPHA_R_SREL64,    /* Type.  */
01197         0,                  /* Rightshift.  */
01198         4,                  /* Size (0 = byte, 1 = short, 2 = long).  */
01199         64,                 /* Bitsize.  */
01200         TRUE,               /* PC relative.  */
01201         0,                  /* Bitpos.  */
01202         complain_overflow_signed, /* Complain_on_overflow.  */
01203         reloc_nil,          /* Special_function.  */
01204         "SREL64",           /* Name.  */
01205         TRUE,               /* Partial_inplace.  */
01206         MINUS_ONE,          /* Source mask.  */
01207         MINUS_ONE,          /* Dest mask.  */
01208         FALSE),             /* PC rel offset.  */
01209 
01210   /* Push a value on the reloc evaluation stack.  */
01211   HOWTO (ALPHA_R_OP_PUSH,   /* Type.  */
01212         0,                  /* Rightshift.  */
01213         0,                  /* Size (0 = byte, 1 = short, 2 = long).  */
01214         0,                  /* Bitsize.  */
01215         FALSE,                     /* PC relative.  */
01216         0,                  /* Bitpos.  */
01217         complain_overflow_dont,/* Complain_on_overflow.  */
01218         reloc_nil,          /* Special_function.  */
01219         "OP_PUSH",          /* Name.  */
01220         FALSE,                     /* Partial_inplace.  */
01221         0,                  /* Source mask.  */
01222         0,                  /* Dest mask.  */
01223         FALSE),             /* PC rel offset.  */
01224 
01225   /* Store the value from the stack at the given address.  Store it in
01226      a bitfield of size r_size starting at bit position r_offset.  */
01227   HOWTO (ALPHA_R_OP_STORE,  /* Type.  */
01228         0,                  /* Rightshift.  */
01229         4,                  /* Size (0 = byte, 1 = short, 2 = long).  */
01230         64,                 /* Bitsize.  */
01231         FALSE,                     /* PC relative.  */
01232         0,                  /* Bitpos.  */
01233         complain_overflow_dont,/* Complain_on_overflow.  */
01234         reloc_nil,          /* Special_function.  */
01235         "OP_STORE",         /* Name.  */
01236         FALSE,                     /* Partial_inplace.  */
01237         0,                  /* Source mask.  */
01238         MINUS_ONE,          /* Dest mask.  */
01239         FALSE),             /* PC rel offset.  */
01240 
01241   /* Subtract the reloc address from the value on the top of the
01242      relocation stack.  */
01243   HOWTO (ALPHA_R_OP_PSUB,   /* Type.  */
01244         0,                  /* Rightshift.  */
01245         0,                  /* Size (0 = byte, 1 = short, 2 = long).  */
01246         0,                  /* Bitsize.  */
01247         FALSE,                     /* PC relative.  */
01248         0,                  /* Bitpos.  */
01249         complain_overflow_dont,/* Complain_on_overflow.  */
01250         reloc_nil,          /* Special_function.  */
01251         "OP_PSUB",          /* Name.  */
01252         FALSE,                     /* Partial_inplace.  */
01253         0,                  /* Source mask.  */
01254         0,                  /* Dest mask.  */
01255         FALSE),             /* PC rel offset.  */
01256 
01257   /* Shift the value on the top of the relocation stack right by the
01258      given value.  */
01259   HOWTO (ALPHA_R_OP_PRSHIFT,       /* Type.  */
01260         0,                  /* Rightshift.  */
01261         0,                  /* Size (0 = byte, 1 = short, 2 = long).  */
01262         0,                  /* Bitsize.  */
01263         FALSE,                     /* PC relative.  */
01264         0,                  /* Bitpos.  */
01265         complain_overflow_dont,/* Complain_on_overflow.  */
01266         reloc_nil,          /* Special_function.  */
01267         "OP_PRSHIFT",              /* Name.  */
01268         FALSE,                     /* Partial_inplace.  */
01269         0,                  /* Source mask.  */
01270         0,                  /* Dest mask.  */
01271         FALSE),             /* PC rel offset.  */
01272 
01273   /* Hack. Linkage is done by linker.  */
01274   HOWTO (ALPHA_R_LINKAGE,   /* Type.  */
01275         0,                  /* Rightshift.  */
01276         8,                  /* Size (0 = byte, 1 = short, 2 = long).  */
01277         256,                /* Bitsize.  */
01278         FALSE,                     /* PC relative.  */
01279         0,                  /* Bitpos.  */
01280         complain_overflow_dont,/* Complain_on_overflow.  */
01281         reloc_nil,          /* Special_function.  */
01282         "LINKAGE",          /* Name.  */
01283         FALSE,                     /* Partial_inplace.  */
01284         0,                  /* Source mask.  */
01285         0,                  /* Dest mask.  */
01286         FALSE),             /* PC rel offset.  */
01287 
01288   /* A 32 bit reference to a symbol.  */
01289   HOWTO (ALPHA_R_REFLONG,   /* Type.  */
01290         0,                  /* Rightshift.  */
01291         2,                  /* Size (0 = byte, 1 = short, 2 = long).  */
01292         32,                 /* Bitsize.  */
01293         FALSE,                     /* PC relative.  */
01294         0,                  /* Bitpos.  */
01295         complain_overflow_bitfield, /* Complain_on_overflow.  */
01296         reloc_nil,          /* Special_function.  */
01297         "REFLONG",          /* Name.  */
01298         TRUE,               /* Partial_inplace.  */
01299         0xffffffff,         /* Source mask.  */
01300         0xffffffff,         /* Dest mask.  */
01301         FALSE),             /* PC rel offset.  */
01302 
01303   /* A 64 bit reference to a procedure, written as 32 bit value.  */
01304   HOWTO (ALPHA_R_CODEADDR,  /* Type.  */
01305         0,                  /* Rightshift.  */
01306         4,                  /* Size (0 = byte, 1 = short, 2 = long).  */
01307         64,                 /* Bitsize.  */
01308         FALSE,                     /* PC relative.  */
01309         0,                  /* Bitpos.  */
01310         complain_overflow_signed,/* Complain_on_overflow.  */
01311         reloc_nil,          /* Special_function.  */
01312         "CODEADDR",         /* Name.  */
01313         FALSE,                     /* Partial_inplace.  */
01314         0xffffffff,         /* Source mask.  */
01315         0xffffffff,         /* Dest mask.  */
01316         FALSE),             /* PC rel offset.  */
01317 
01318 };
01319 
01320 /* Return a pointer to a howto structure which, when invoked, will perform
01321    the relocation code on data from the architecture noted.  */
01322 
01323 static const struct reloc_howto_struct *
01324 vms_bfd_reloc_type_lookup (bfd * abfd ATTRIBUTE_UNUSED,
01325                         bfd_reloc_code_real_type code)
01326 {
01327   int alpha_type;
01328 
01329 #if VMS_DEBUG
01330   vms_debug (1, "vms_bfd_reloc_type_lookup (%p, %d)\t", abfd, code);
01331 #endif
01332 
01333   switch (code)
01334     {
01335       case BFD_RELOC_16:           alpha_type = ALPHA_R_SREL16;       break;
01336       case BFD_RELOC_32:           alpha_type = ALPHA_R_REFLONG;      break;
01337       case BFD_RELOC_64:           alpha_type = ALPHA_R_REFQUAD;      break;
01338       case BFD_RELOC_CTOR:         alpha_type = ALPHA_R_REFQUAD;      break;
01339       case BFD_RELOC_23_PCREL_S2:  alpha_type = ALPHA_R_BRADDR;       break;
01340       case BFD_RELOC_ALPHA_HINT:   alpha_type = ALPHA_R_HINT;  break;
01341       case BFD_RELOC_16_PCREL:            alpha_type = ALPHA_R_SREL16;       break;
01342       case BFD_RELOC_32_PCREL:            alpha_type = ALPHA_R_SREL32;       break;
01343       case BFD_RELOC_64_PCREL:            alpha_type = ALPHA_R_SREL64;       break;
01344       case BFD_RELOC_ALPHA_LINKAGE:       alpha_type = ALPHA_R_LINKAGE;      break;
01345       case BFD_RELOC_ALPHA_CODEADDR:      alpha_type = ALPHA_R_CODEADDR;     break;
01346       default:
01347        (*_bfd_error_handler) ("reloc (%d) is *UNKNOWN*", code);
01348        return NULL;
01349     }
01350 #if VMS_DEBUG
01351   vms_debug (2, "reloc is %s\n", alpha_howto_table[alpha_type].name);
01352 #endif
01353   return & alpha_howto_table[alpha_type];
01354 }
01355 
01356 static reloc_howto_type *
01357 vms_bfd_reloc_name_lookup (bfd *abfd ATTRIBUTE_UNUSED,
01358                         const char *r_name)
01359 {
01360   unsigned int i;
01361 
01362   for (i = 0;
01363        i < sizeof (alpha_howto_table) / sizeof (alpha_howto_table[0]);
01364        i++)
01365     if (alpha_howto_table[i].name != NULL
01366        && strcasecmp (alpha_howto_table[i].name, r_name) == 0)
01367       return &alpha_howto_table[i];
01368 
01369   return NULL;
01370 }
01371 
01372 /* Part 4.7, writing an object file.  */
01373 
01374 /* Set the architecture and machine type in BFD abfd to arch and mach.
01375    Find the correct pointer to a structure and insert it into the arch_info
01376    pointer.  */
01377 
01378 static bfd_boolean
01379 vms_set_arch_mach (bfd * abfd,
01380                  enum bfd_architecture arch ATTRIBUTE_UNUSED,
01381                  unsigned long mach ATTRIBUTE_UNUSED)
01382 {
01383 #if VMS_DEBUG
01384   vms_debug (1, "vms_set_arch_mach (%p, %d, %ld)\n", abfd, arch, mach);
01385 #endif
01386   abfd->arch_info = bfd_scan_arch ("alpha");
01387 
01388   return TRUE;
01389 }
01390 
01391 /* Sets the contents of the section section in BFD abfd to the data starting
01392    in memory at data. The data is written to the output section starting at
01393    offset offset for count bytes.
01394 
01395    Normally TRUE is returned, else FALSE. Possible error returns are:
01396    o bfd_error_no_contents - The output section does not have the
01397        SEC_HAS_CONTENTS attribute, so nothing can be written to it.
01398    o and some more too  */
01399 
01400 static bfd_boolean
01401 vms_set_section_contents (bfd * abfd,
01402                        asection *section,
01403                        const void * location,
01404                        file_ptr offset,
01405                        bfd_size_type count)
01406 {
01407 #if VMS_DEBUG
01408   vms_debug (1, "vms_set_section_contents (%p, sec %s, loc %p, off %ld, count %d)\n",
01409             abfd, section->name, location, (long int)offset, (int)count);
01410   vms_debug (2, "size %d\n", (int) section->size);
01411 #endif
01412   return _bfd_save_vms_section (abfd, section, location, offset, count);
01413 }
01414 
01415 /* Part 4.8, linker.  */
01416 
01417 /* Get the size of the section headers.  */
01418 
01419 static int
01420 vms_sizeof_headers (bfd * abfd ATTRIBUTE_UNUSED,
01421                   struct bfd_link_info *info ATTRIBUTE_UNUSED)
01422 {
01423 #if VMS_DEBUG
01424   vms_debug (1, "vms_sizeof_headers (%p, %s)\n", abfd, (reloc)?"True":"False");
01425 #endif
01426   return 0;
01427 }
01428 
01429 /* Provides default handling of relocation effort for back ends
01430    which can't be bothered to do it efficiently.  */
01431 
01432 static bfd_byte *
01433 vms_bfd_get_relocated_section_contents (bfd * abfd ATTRIBUTE_UNUSED,
01434                                    struct bfd_link_info *link_info ATTRIBUTE_UNUSED,
01435                                    struct bfd_link_order *link_order ATTRIBUTE_UNUSED,
01436                                    bfd_byte *data ATTRIBUTE_UNUSED,
01437                                    bfd_boolean relocatable ATTRIBUTE_UNUSED,
01438                                    asymbol **symbols ATTRIBUTE_UNUSED)
01439 {
01440 #if VMS_DEBUG
01441   vms_debug (1, "vms_bfd_get_relocated_section_contents (%p, %p, %p, %p, %s, %p)\n",
01442             abfd, link_info, link_order, data, (relocatable)?"True":"False", symbols);
01443 #endif
01444   return NULL;
01445 }
01446 
01447 /* ???  */
01448 
01449 static bfd_boolean
01450 vms_bfd_relax_section (bfd * abfd ATTRIBUTE_UNUSED,
01451                      asection *section ATTRIBUTE_UNUSED,
01452                      struct bfd_link_info *link_info ATTRIBUTE_UNUSED,
01453                      bfd_boolean *again ATTRIBUTE_UNUSED)
01454 {
01455 #if VMS_DEBUG
01456   vms_debug (1, "vms_bfd_relax_section (%p, %s, %p, <ret>)\n",
01457             abfd, section->name, link_info);
01458 #endif
01459   return TRUE;
01460 }
01461 
01462 static bfd_boolean
01463 vms_bfd_gc_sections (bfd * abfd ATTRIBUTE_UNUSED,
01464                    struct bfd_link_info *link_info ATTRIBUTE_UNUSED)
01465 {
01466 #if VMS_DEBUG
01467   vms_debug (1, "vms_bfd_gc_sections (%p, %p)\n", abfd, link_info);
01468 #endif
01469   return TRUE;
01470 }
01471 
01472 static bfd_boolean
01473 vms_bfd_merge_sections (bfd * abfd ATTRIBUTE_UNUSED,
01474                      struct bfd_link_info *link_info ATTRIBUTE_UNUSED)
01475 {
01476 #if VMS_DEBUG
01477   vms_debug (1, "vms_bfd_merge_sections (%p, %p)\n", abfd, link_info);
01478 #endif
01479   return TRUE;
01480 }
01481 
01482 /* Create a hash table for the linker.  Different backends store
01483    different information in this table.  */
01484 
01485 static struct bfd_link_hash_table *
01486 vms_bfd_link_hash_table_create (bfd * abfd ATTRIBUTE_UNUSED)
01487 {
01488 #if VMS_DEBUG
01489   vms_debug (1, "vms_bfd_link_hash_table_create (%p)\n", abfd);
01490 #endif
01491   return NULL;
01492 }
01493 
01494 /* Free a linker hash table.  */
01495 
01496 static void
01497 vms_bfd_link_hash_table_free (struct bfd_link_hash_table *hash ATTRIBUTE_UNUSED)
01498 {
01499 #if VMS_DEBUG
01500   vms_debug (1, "vms_bfd_link_hash_table_free (%p)\n", abfd);
01501 #endif
01502 }
01503 
01504 /* Add symbols from this object file into the hash table.  */
01505 
01506 static bfd_boolean
01507 vms_bfd_link_add_symbols (bfd * abfd ATTRIBUTE_UNUSED,
01508                        struct bfd_link_info *link_info ATTRIBUTE_UNUSED)
01509 {
01510 #if VMS_DEBUG
01511   vms_debug (1, "vms_bfd_link_add_symbols (%p, %p)\n", abfd, link_info);
01512 #endif
01513   return FALSE;
01514 }
01515 
01516 /* Do a link based on the link_order structures attached to each
01517    section of the BFD.  */
01518 
01519 static bfd_boolean
01520 vms_bfd_final_link (bfd * abfd ATTRIBUTE_UNUSED,
01521                   struct bfd_link_info *link_info ATTRIBUTE_UNUSED)
01522 {
01523 #if VMS_DEBUG
01524   vms_debug (1, "vms_bfd_final_link (%p, %p)\n", abfd, link_info);
01525 #endif
01526   return TRUE;
01527 }
01528 
01529 /* Should this section be split up into smaller pieces during linking.  */
01530 
01531 static bfd_boolean
01532 vms_bfd_link_split_section (bfd * abfd ATTRIBUTE_UNUSED,
01533                          asection *section ATTRIBUTE_UNUSED)
01534 {
01535 #if VMS_DEBUG
01536   vms_debug (1, "vms_bfd_link_split_section (%p, %s)\n", abfd, section->name);
01537 #endif
01538   return FALSE;
01539 }
01540 
01541 /* Part 4.9, dynamic symbols and relocations.  */
01542 
01543 /* Get the amount of memory required to hold the dynamic symbols.  */
01544 
01545 static long
01546 vms_get_dynamic_symtab_upper_bound (bfd * abfd ATTRIBUTE_UNUSED)
01547 {
01548 #if VMS_DEBUG
01549   vms_debug (1, "vms_get_dynamic_symtab_upper_bound (%p)\n", abfd);
01550 #endif
01551   return 0;
01552 }
01553 
01554 static bfd_boolean
01555 vms_bfd_print_private_bfd_data (bfd * abfd ATTRIBUTE_UNUSED,
01556                             void *file ATTRIBUTE_UNUSED)
01557 {
01558 #if VMS_DEBUG
01559   vms_debug (1, "vms_bfd_print_private_bfd_data (%p)\n", abfd);
01560 #endif
01561   return FALSE;
01562 }
01563 
01564 /* Read in the dynamic symbols.  */
01565 
01566 static long
01567 vms_canonicalize_dynamic_symtab (bfd * abfd ATTRIBUTE_UNUSED,
01568                              asymbol **symbols ATTRIBUTE_UNUSED)
01569 {
01570 #if VMS_DEBUG
01571   vms_debug (1, "vms_canonicalize_dynamic_symtab (%p, <ret>)\n", abfd);
01572 #endif
01573   return 0L;
01574 }
01575 
01576 /* Get the amount of memory required to hold the dynamic relocs.  */
01577 
01578 static long
01579 vms_get_dynamic_reloc_upper_bound (bfd * abfd ATTRIBUTE_UNUSED)
01580 {
01581 #if VMS_DEBUG
01582   vms_debug (1, "vms_get_dynamic_reloc_upper_bound (%p)\n", abfd);
01583 #endif
01584   return 0L;
01585 }
01586 
01587 /* Read in the dynamic relocs.  */
01588 
01589 static long
01590 vms_canonicalize_dynamic_reloc (bfd * abfd ATTRIBUTE_UNUSED,
01591                             arelent **arel ATTRIBUTE_UNUSED,
01592                             asymbol **symbols ATTRIBUTE_UNUSED)
01593 {
01594 #if VMS_DEBUG
01595   vms_debug (1, "vms_canonicalize_dynamic_reloc (%p)\n", abfd);
01596 #endif
01597   return 0L;
01598 }
01599 
01600 const bfd_target vms_alpha_vec =
01601 {
01602   "vms-alpha",                     /* Name.  */
01603   bfd_target_evax_flavour,
01604   BFD_ENDIAN_LITTLE,        /* Data byte order is little.  */
01605   BFD_ENDIAN_LITTLE,        /* Header byte order is little.  */
01606 
01607   (HAS_RELOC | HAS_SYMS
01608    | WP_TEXT | D_PAGED),    /* Object flags.  */
01609   (SEC_ALLOC | SEC_LOAD | SEC_RELOC
01610    | SEC_READONLY | SEC_CODE | SEC_DATA
01611    | SEC_HAS_CONTENTS | SEC_IN_MEMORY),          /* Sect flags.  */
01612   0,                        /* Symbol_leading_char.  */
01613   ' ',                      /* AR_pad_char.  */
01614   15,                       /* AR_max_namelen.  */
01615   bfd_getl64, bfd_getl_signed_64, bfd_putl64,
01616   bfd_getl32, bfd_getl_signed_32, bfd_putl32,
01617   bfd_getl16, bfd_getl_signed_16, bfd_putl16,
01618   bfd_getl64, bfd_getl_signed_64, bfd_putl64,
01619   bfd_getl32, bfd_getl_signed_32, bfd_putl32,
01620   bfd_getl16, bfd_getl_signed_16, bfd_putl16,
01621 
01622   {_bfd_dummy_target, vms_object_p,              /* bfd_check_format.  */
01623    vms_archive_p, _bfd_dummy_target},
01624   {bfd_false, vms_mkobject,               /* bfd_set_format.  */
01625    _bfd_generic_mkarchive, bfd_false},
01626   {bfd_false, vms_write_object_contents,  /* bfd_write_contents.  */
01627    _bfd_write_archive_contents, bfd_false},
01628 
01629   BFD_JUMP_TABLE_GENERIC (vms),
01630   BFD_JUMP_TABLE_COPY (vms),
01631   BFD_JUMP_TABLE_CORE (vms),
01632   BFD_JUMP_TABLE_ARCHIVE (vms),
01633   BFD_JUMP_TABLE_SYMBOLS (vms),
01634   BFD_JUMP_TABLE_RELOCS (vms),
01635   BFD_JUMP_TABLE_WRITE (vms),
01636   BFD_JUMP_TABLE_LINK (vms),
01637   BFD_JUMP_TABLE_DYNAMIC (vms),
01638 
01639   NULL,
01640 
01641   NULL
01642 };
01643 
01644 const bfd_target vms_vax_vec =
01645 {
01646   "vms-vax",                /* Name.  */
01647   bfd_target_ovax_flavour,
01648   BFD_ENDIAN_LITTLE,        /* Data byte order is little.  */
01649   BFD_ENDIAN_LITTLE,        /* Header byte order is little.  */
01650 
01651   (HAS_RELOC | HAS_SYMS     /* Object flags.  */
01652    | WP_TEXT | D_PAGED
01653    | HAS_LINENO | HAS_DEBUG | HAS_LOCALS),
01654 
01655   (SEC_ALLOC | SEC_LOAD | SEC_RELOC
01656    | SEC_READONLY | SEC_CODE | SEC_DATA
01657    | SEC_HAS_CONTENTS | SEC_IN_MEMORY),          /* Sect flags.  */
01658   0,                        /* Symbol_leading_char.  */
01659   ' ',                      /* AR_pad_char.  */
01660   15,                       /* AR_max_namelen.  */
01661   bfd_getl64, bfd_getl_signed_64, bfd_putl64,
01662   bfd_getl32, bfd_getl_signed_32, bfd_putl32,
01663   bfd_getl16, bfd_getl_signed_16, bfd_putl16, /* Data.  */
01664   bfd_getl64, bfd_getl_signed_64, bfd_putl64,
01665   bfd_getl32, bfd_getl_signed_32, bfd_putl32,
01666   bfd_getl16, bfd_getl_signed_16, bfd_putl16, /* Headers.  */
01667 
01668   {_bfd_dummy_target, vms_object_p,              /* bfd_check_format.  */
01669    vms_archive_p, _bfd_dummy_target},
01670   {bfd_false, vms_mkobject,               /* bfd_set_format.  */
01671    _bfd_generic_mkarchive, bfd_false},
01672   {bfd_false, vms_write_object_contents,  /* bfd_write_contents.  */
01673    _bfd_write_archive_contents, bfd_false},
01674 
01675   BFD_JUMP_TABLE_GENERIC (vms),
01676   BFD_JUMP_TABLE_COPY (vms),
01677   BFD_JUMP_TABLE_CORE (vms),
01678   BFD_JUMP_TABLE_ARCHIVE (vms),
01679   BFD_JUMP_TABLE_SYMBOLS (vms),
01680   BFD_JUMP_TABLE_RELOCS (vms),
01681   BFD_JUMP_TABLE_WRITE (vms),
01682   BFD_JUMP_TABLE_LINK (vms),
01683   BFD_JUMP_TABLE_DYNAMIC (vms),
01684 
01685   NULL,
01686 
01687   NULL
01688 };