vms.c
来自「基于4个mips核的noc设计」· C语言 代码 · 共 1,903 行 · 第 1/4 页
C
1,903 行
/* vms.c -- BFD back-end for VAX (openVMS/VAX) and EVAX (openVMS/Alpha) files. Copyright 1996, 1997, 1998, 1999, 2000, 2001 Free Software Foundation, Inc. Written by Klaus K"ampf (kkaempf@rmi.de)This program is free software; you can redistribute it and/or modifyit under the terms of the GNU General Public License as published bythe Free Software Foundation; either version 2 of the License, or(at your option) any later version.This program is distributed in the hope that it will be useful,but WITHOUT ANY WARRANTY; without even the implied warranty ofMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See theGNU General Public License for more details.You should have received a copy of the GNU General Public Licensealong with this program; if not, write to the Free SoftwareFoundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */#include "bfd.h"#include "sysdep.h"#include "bfdlink.h"#include "libbfd.h"#include "vms.h"static boolean vms_initialize PARAMS ((bfd *));static unsigned int priv_section_count;static boolean fill_section_ptr PARAMS ((struct bfd_hash_entry *, PTR));static boolean vms_fixup_sections PARAMS ((bfd *));static boolean copy_symbols PARAMS ((struct bfd_hash_entry *, PTR));static bfd_reloc_status_type reloc_nil PARAMS ((bfd *, arelent *, asymbol *, PTR, asection *, bfd *, char **));static const struct bfd_target *vms_object_p PARAMS ((bfd *abfd));static const struct bfd_target *vms_archive_p PARAMS ((bfd *abfd));static boolean vms_mkobject PARAMS ((bfd *abfd));static boolean vms_write_object_contents PARAMS ((bfd *abfd));static boolean vms_close_and_cleanup PARAMS ((bfd *abfd));static boolean vms_bfd_free_cached_info PARAMS ((bfd *abfd));static boolean vms_new_section_hook PARAMS ((bfd *abfd, asection *section));static boolean vms_get_section_contents PARAMS ((bfd *abfd, asection *section, PTR x1, file_ptr x2, bfd_size_type x3));static boolean vms_get_section_contents_in_window PARAMS ((bfd *abfd, asection *section, bfd_window *w, file_ptr offset, bfd_size_type count));static boolean vms_bfd_copy_private_bfd_data PARAMS ((bfd *src, bfd *dest));static boolean vms_bfd_copy_private_section_data PARAMS ((bfd *srcbfd, asection *srcsec, bfd *dstbfd, asection *dstsec));static boolean vms_bfd_copy_private_symbol_data PARAMS ((bfd *ibfd, asymbol *isym, bfd *obfd, asymbol *osym));static boolean vms_bfd_print_private_bfd_data PARAMS ((bfd *abfd, void *file));static char *vms_core_file_failing_command PARAMS ((bfd *abfd));static int vms_core_file_failing_signal PARAMS ((bfd *abfd));static boolean vms_core_file_matches_executable_p PARAMS ((bfd *abfd, bfd *bbfd));static boolean vms_slurp_armap PARAMS ((bfd *abfd));static boolean vms_slurp_extended_name_table PARAMS ((bfd *abfd));static boolean vms_construct_extended_name_table PARAMS ((bfd *abfd, char **tabloc, bfd_size_type *tablen, const char **name));static void vms_truncate_arname PARAMS ((bfd *abfd, CONST char *pathname, char *arhdr));static boolean vms_write_armap PARAMS ((bfd *arch, unsigned int elength, struct orl *map, unsigned int orl_count, int stridx));static PTR vms_read_ar_hdr PARAMS ((bfd *abfd));static bfd *vms_get_elt_at_index PARAMS ((bfd *abfd, symindex index));static bfd *vms_openr_next_archived_file PARAMS ((bfd *arch, bfd *prev));static boolean vms_update_armap_timestamp PARAMS ((bfd *abfd));static int vms_generic_stat_arch_elt PARAMS ((bfd *abfd, struct stat *stat));static long vms_get_symtab_upper_bound PARAMS ((bfd *abfd));static long vms_get_symtab PARAMS ((bfd *abfd, asymbol **symbols));static void vms_print_symbol PARAMS ((bfd *abfd, PTR file, asymbol *symbol, bfd_print_symbol_type how));static void vms_get_symbol_info PARAMS ((bfd *abfd, asymbol *symbol, symbol_info *ret));static boolean vms_bfd_is_local_label_name PARAMS ((bfd *abfd, const char *));static alent *vms_get_lineno PARAMS ((bfd *abfd, asymbol *symbol));static boolean vms_find_nearest_line PARAMS ((bfd *abfd, asection *section, asymbol **symbols, bfd_vma offset, const char **file, const char **func, unsigned int *line));static asymbol *vms_bfd_make_debug_symbol PARAMS ((bfd *abfd, void *ptr, unsigned long size));static long vms_read_minisymbols PARAMS ((bfd *abfd, boolean dynamic, PTR *minisymsp, unsigned int *sizep));static asymbol *vms_minisymbol_to_symbol PARAMS ((bfd *abfd, boolean dynamic, const PTR minisym, asymbol *sym));static long vms_get_reloc_upper_bound PARAMS ((bfd *abfd, asection *sect));static long vms_canonicalize_reloc PARAMS ((bfd *abfd, asection *srcsec, arelent **location, asymbol **symbols));static const struct reloc_howto_struct *vms_bfd_reloc_type_lookup PARAMS ((bfd *abfd, bfd_reloc_code_real_type code));static boolean vms_set_arch_mach PARAMS ((bfd *abfd, enum bfd_architecture arch, unsigned long mach));static boolean vms_set_section_contents PARAMS ((bfd *abfd, asection *section, PTR location, file_ptr offset, bfd_size_type count));static int vms_sizeof_headers PARAMS ((bfd *abfd, boolean reloc));static bfd_byte *vms_bfd_get_relocated_section_contents PARAMS ((bfd *abfd, struct bfd_link_info *link_info, struct bfd_link_order *link_order, bfd_byte *data, boolean relocateable, asymbol **symbols));static boolean vms_bfd_relax_section PARAMS ((bfd *abfd, asection *section, struct bfd_link_info *link_info, boolean *again));static boolean vms_bfd_gc_sections PARAMS ((bfd *abfd, struct bfd_link_info *link_info));static struct bfd_link_hash_table *vms_bfd_link_hash_table_create PARAMS ((bfd *abfd));static boolean vms_bfd_link_add_symbols PARAMS ((bfd *abfd, struct bfd_link_info *link_info));static boolean vms_bfd_final_link PARAMS ((bfd *abfd, struct bfd_link_info *link_info));static boolean vms_bfd_link_split_section PARAMS ((bfd *abfd, asection *section));static long vms_get_dynamic_symtab_upper_bound PARAMS ((bfd *abfd));static long vms_canonicalize_dynamic_symtab PARAMS ((bfd *abfd, asymbol **symbols));static long vms_get_dynamic_reloc_upper_bound PARAMS ((bfd *abfd));static long vms_canonicalize_dynamic_reloc PARAMS ((bfd *abfd, arelent **arel, asymbol **symbols));static boolean vms_bfd_merge_private_bfd_data PARAMS ((bfd *ibfd, bfd *obfd));static boolean vms_bfd_set_private_flags PARAMS ((bfd *abfd, flagword flags));#define vms_make_empty_symbol _bfd_vms_make_empty_symbol/*===========================================================================*/const bfd_target vms_alpha_vec ={ "vms-alpha", /* name */ bfd_target_evax_flavour, BFD_ENDIAN_LITTLE, /* data byte order is little */ BFD_ENDIAN_LITTLE, /* header byte order is little */ (HAS_RELOC | HAS_SYMS | WP_TEXT | D_PAGED), /* object flags */ (SEC_ALLOC | SEC_LOAD | SEC_RELOC | SEC_READONLY | SEC_CODE | SEC_DATA | SEC_HAS_CONTENTS | SEC_IN_MEMORY), /* sect flags */ 0, /* symbol_leading_char */ ' ', /* ar_pad_char */ 15, /* ar_max_namelen */ bfd_getl64, bfd_getl_signed_64, bfd_putl64, bfd_getl32, bfd_getl_signed_32, bfd_putl32, bfd_getl16, bfd_getl_signed_16, bfd_putl16, bfd_getl64, bfd_getl_signed_64, bfd_putl64, bfd_getl32, bfd_getl_signed_32, bfd_putl32, bfd_getl16, bfd_getl_signed_16, bfd_putl16, {_bfd_dummy_target, vms_object_p, /* bfd_check_format */ vms_archive_p, _bfd_dummy_target}, {bfd_false, vms_mkobject, /* bfd_set_format */ _bfd_generic_mkarchive, bfd_false}, {bfd_false, vms_write_object_contents, /* bfd_write_contents */ _bfd_write_archive_contents, bfd_false}, BFD_JUMP_TABLE_GENERIC (vms), BFD_JUMP_TABLE_COPY (vms), BFD_JUMP_TABLE_CORE (vms), BFD_JUMP_TABLE_ARCHIVE (vms), BFD_JUMP_TABLE_SYMBOLS (vms), BFD_JUMP_TABLE_RELOCS (vms), BFD_JUMP_TABLE_WRITE (vms), BFD_JUMP_TABLE_LINK (vms), BFD_JUMP_TABLE_DYNAMIC (vms), NULL, (PTR) 0};const bfd_target vms_vax_vec ={ "vms-vax", /* name */ bfd_target_ovax_flavour, BFD_ENDIAN_LITTLE, /* data byte order is little */ BFD_ENDIAN_LITTLE, /* header byte order is little */ (HAS_RELOC | HAS_SYMS /* object flags */ | WP_TEXT | D_PAGED | HAS_LINENO | HAS_DEBUG | HAS_LOCALS), (SEC_ALLOC | SEC_LOAD | SEC_RELOC | SEC_READONLY | SEC_CODE | SEC_DATA | SEC_HAS_CONTENTS | SEC_IN_MEMORY), /* sect flags */ 0, /* symbol_leading_char */ ' ', /* ar_pad_char */ 15, /* ar_max_namelen */ bfd_getl64, bfd_getl_signed_64, bfd_putl64, bfd_getl32, bfd_getl_signed_32, bfd_putl32, bfd_getl16, bfd_getl_signed_16, bfd_putl16, /* data */ bfd_getl64, bfd_getl_signed_64, bfd_putl64, bfd_getl32, bfd_getl_signed_32, bfd_putl32, bfd_getl16, bfd_getl_signed_16, bfd_putl16, /* hdrs */ {_bfd_dummy_target, vms_object_p, /* bfd_check_format */ vms_archive_p, _bfd_dummy_target}, {bfd_false, vms_mkobject, /* bfd_set_format */ _bfd_generic_mkarchive, bfd_false}, {bfd_false, vms_write_object_contents, /* bfd_write_contents */ _bfd_write_archive_contents, bfd_false}, BFD_JUMP_TABLE_GENERIC (vms), BFD_JUMP_TABLE_COPY (vms), BFD_JUMP_TABLE_CORE (vms), BFD_JUMP_TABLE_ARCHIVE (vms), BFD_JUMP_TABLE_SYMBOLS (vms), BFD_JUMP_TABLE_RELOCS (vms), BFD_JUMP_TABLE_WRITE (vms), BFD_JUMP_TABLE_LINK (vms), BFD_JUMP_TABLE_DYNAMIC (vms), NULL, (PTR) 0};/*===========================================================================*//* Initialize private data */static booleanvms_initialize (abfd) bfd *abfd;{ int i; if (abfd->tdata.any != 0) return true; bfd_set_start_address (abfd, (bfd_vma)-1); abfd->tdata.any = ((struct vms_private_data_struct*) bfd_malloc (sizeof (struct vms_private_data_struct))); if (abfd->tdata.any == 0) return false;#ifdef __ALPHA PRIV (is_vax) = 0;#else PRIV (is_vax) = 1;#endif PRIV (vms_buf) = 0; PRIV (buf_size) = 0; PRIV (rec_length) = 0; PRIV (file_format) = FF_UNKNOWN; PRIV (fixup_done) = false; PRIV (sections) = NULL; PRIV (stack) = ((struct stack_struct *) bfd_malloc (sizeof (struct stack_struct) * STACKSIZE)); if (PRIV (stack) == 0) { vms_init_no_mem1: free (abfd->tdata.any); abfd->tdata.any = 0; return false; } PRIV (stackptr) = 0; PRIV (vms_symbol_table) = ((struct bfd_hash_table *) bfd_malloc (sizeof (struct bfd_hash_table))); if (PRIV (vms_symbol_table) == 0) { vms_init_no_mem2: free (PRIV (stack)); PRIV (stack) = 0; goto vms_init_no_mem1; } if (!bfd_hash_table_init (PRIV (vms_symbol_table), _bfd_vms_hash_newfunc)) return false; PRIV (location_stack) = ((struct location_struct *) bfd_malloc (sizeof (struct location_struct) * LOCATION_SAVE_SIZE)); if (PRIV (location_stack) == 0) { vms_init_no_mem3: free (PRIV (vms_symbol_table)); PRIV (vms_symbol_table) = 0; goto vms_init_no_mem2; } for (i = 0; i < VMS_SECTION_COUNT; i++) PRIV (vms_section_table)[i] = NULL; PRIV (output_buf) = (unsigned char *) malloc (MAX_OUTREC_SIZE); if (PRIV (output_buf) == 0) { free (PRIV (location_stack)); PRIV (location_stack) = 0; goto vms_init_no_mem3; } PRIV (push_level) = 0; PRIV (pushed_size) = 0; PRIV (length_pos) = 2; PRIV (output_size) = 0; PRIV (output_alignment) = 1; return true;}/* Fill symbol->section with section ptr symbol->section is filled with the section index for defined symbols during reading the GSD/EGSD section. But we need the pointer to the bfd section later. It has the correct value for referenced (undefined section) symbols called from bfd_hash_traverse in vms_fixup_sections */static booleanfill_section_ptr (entry, sections) struct bfd_hash_entry *entry; PTR sections;{ asection *sec; asymbol *sym; sym = ((vms_symbol_entry *)entry)->symbol; sec = sym->section;#if VMS_DEBUG vms_debug (6, "fill_section_ptr: sym %p, sec %p\n", sym, sec);#endif /* fill forward references (these contain section number, not section ptr). */ if ((unsigned int) sec < priv_section_count) { sec = ((vms_symbol_entry *)entry)->symbol->section = ((asection **)sections)[(int)sec]; } if (strcmp (sym->name, sec->name) == 0) sym->flags |= BSF_SECTION_SYM; return true;}/* Fixup sections set up all pointers and arrays, counters and sizes are fixed now we build a private sections vector for easy access since sections are always referenced by an index number. alloc PRIV(sections) according to abfd->section_count copy abfd->sections to PRIV(sections) */static booleanvms_fixup_sections (abfd) bfd *abfd;{ if (PRIV (fixup_done)) return true; /* * traverse symbol table and fill in all section pointers */ /* can't provide section count as argument to fill_section_ptr(). */ priv_section_count = PRIV (section_count); bfd_hash_traverse (PRIV (vms_symbol_table), fill_section_ptr, (PTR) (PRIV (sections))); PRIV (fixup_done) = true; return true;}/*===========================================================================*//* Check the format for a file being read. Return a (bfd_target *) if it's an object file or zero if not. */static const struct bfd_target *vms_object_p (abfd) bfd *abfd;{ int err = 0; int prev_type; const struct bfd_target *target_vector = 0; const bfd_arch_info_type *arch = 0;#if VMS_DEBUG vms_debug (1, "vms_object_p(%p)\n", abfd);#endif if (!vms_initialize (abfd)) { fprintf (stderr, "vms_initialize () failed !!\n"); return 0; } if (bfd_seek (abfd, 0L, SEEK_SET)) { bfd_set_error (bfd_error_file_truncated); return 0; } prev_type = -1; do {#if VMS_DEBUG vms_debug (7, "reading at %08lx\n", bfd_tell(abfd));#endif if (_bfd_vms_next_record (abfd) < 0) {#if VMS_DEBUG vms_debug (2, "next_record failed\n");#endif bfd_set_error (bfd_error_wrong_format); return 0; } if ((prev_type == EOBJ_S_C_EGSD) && (PRIV (rec_type) != EOBJ_S_C_EGSD)) { if (vms_fixup_sections (abfd) == false) {#if VMS_DEBUG vms_debug (2, "vms_fixup_sections failed\n");#endif bfd_set_error (bfd_error_wrong_format); return 0; } } prev_type = PRIV (rec_type); if (target_vector == 0) { if (prev_type <= OBJ_S_C_MAXRECTYP) target_vector = &vms_vax_vec; else target_vector = &vms_alpha_vec; } switch (prev_type) { case OBJ_S_C_HDR: case EOBJ_S_C_EMH: err = _bfd_vms_slurp_hdr (abfd, prev_type); break; case OBJ_S_C_EOM: case OBJ_S_C_EOMW: case EOBJ_S_C_EEOM: err = _bfd_vms_slurp_eom (abfd, prev_type); break; case OBJ_S_C_GSD: case EOBJ_S_C_EGSD: err = _bfd_vms_slurp_gsd (abfd, prev_type); break; case OBJ_S_C_TIR: case EOBJ_S_C_ETIR: err = _bfd_vms_slurp_tir (abfd, prev_type); break; case OBJ_S_C_DBG: case EOBJ_S_C_EDBG: err = _bfd_vms_slurp_dbg (abfd, prev_type); break; case OBJ_S_C_TBT: case EOBJ_S_C_ETBT: err = _bfd_vms_slurp_tbt (abfd, prev_type); break; case OBJ_S_C_LNK: err = _bfd_vms_slurp_lnk (abfd, prev_type); break;
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?