vms-tir.c
来自「基于4个mips核的noc设计」· C语言 代码 · 共 2,461 行 · 第 1/4 页
C
2,461 行
/* vms-tir.c -- BFD back-end for VAX (openVMS/VAX) and EVAX (openVMS/Alpha) files. Copyright 1996, 1997, 1998, 1999, 2000 Free Software Foundation, Inc. TIR record handling functions ETIR record handling functions go and read the openVMS linker manual (esp. appendix B) if you don't know what's going on here :-) 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. *//* The following type abbreviations are used: cs counted string (ascii string with length byte) by byte (1 byte) sh short (2 byte, 16 bit) lw longword (4 byte, 32 bit) qw quadword (8 byte, 64 bit) da data stream */#include <ctype.h>#include "bfd.h"#include "sysdep.h"#include "bfdlink.h"#include "libbfd.h"#include "vms.h"static void image_set_ptr PARAMS ((bfd *abfd, int psect, uquad offset));static void image_inc_ptr PARAMS ((bfd *abfd, uquad offset));static void image_dump PARAMS ((bfd *abfd, unsigned char *ptr, int size, int offset));static void image_write_b PARAMS ((bfd *abfd, unsigned int value));static void image_write_w PARAMS ((bfd *abfd, unsigned int value));static void image_write_l PARAMS ((bfd *abfd, unsigned long value));static void image_write_q PARAMS ((bfd *abfd, uquad value));/*-----------------------------------------------------------------------------*/static intcheck_section (abfd, size) bfd *abfd; int size;{ int offset; offset = PRIV(image_ptr) - PRIV(image_section)->contents; if ((bfd_size_type) (offset + size) > PRIV(image_section)->_raw_size) { PRIV(image_section)->contents = bfd_realloc (PRIV(image_section)->contents, offset + size); if (PRIV(image_section)->contents == 0) { (*_bfd_error_handler) (_("No Mem !")); return -1; } PRIV(image_section)->_raw_size = offset + size; PRIV(image_ptr) = PRIV(image_section)->contents + offset; } return 0;}/* routines to fill sections contents during tir/etir read *//* Initialize image buffer pointer to be filled */static voidimage_set_ptr (abfd, psect, offset) bfd *abfd; int psect; uquad offset;{#if VMS_DEBUG _bfd_vms_debug (4, "image_set_ptr (%d=%s, %d)\n", psect, PRIV(sections)[psect]->name, offset);#endif PRIV(image_ptr) = PRIV(sections)[psect]->contents + offset; PRIV(image_section) = PRIV(sections)[psect]; return;}/* Increment image buffer pointer by offset */static voidimage_inc_ptr (abfd, offset) bfd *abfd; uquad offset;{#if VMS_DEBUG _bfd_vms_debug (4, "image_inc_ptr (%d)\n", offset);#endif PRIV(image_ptr) += offset; return;}/* Dump multiple bytes to section image */static voidimage_dump (abfd, ptr, size, offset) bfd *abfd; unsigned char *ptr; int size; int offset ATTRIBUTE_UNUSED;{#if VMS_DEBUG _bfd_vms_debug (8, "image_dump from (%p, %d) to (%p)\n", ptr, size, PRIV(image_ptr)); _bfd_hexdump (9, ptr, size, offset);#endif if (PRIV(is_vax) && check_section (abfd, size)) return; while (size-- > 0) *PRIV(image_ptr)++ = *ptr++; return;}/* Write byte to section image */static voidimage_write_b (abfd, value) bfd *abfd; unsigned int value;{#if VMS_DEBUG _bfd_vms_debug (6, "image_write_b(%02x)\n", (int)value);#endif if (PRIV(is_vax) && check_section (abfd, 1)) return; *PRIV(image_ptr)++ = (value & 0xff); return;}/* Write 2-byte word to image */static voidimage_write_w (abfd, value) bfd *abfd; unsigned int value;{#if VMS_DEBUG _bfd_vms_debug (6, "image_write_w(%04x)\n", (int)value);#endif if (PRIV(is_vax) && check_section (abfd, 2)) return; bfd_putl16 (value, PRIV(image_ptr)); PRIV(image_ptr) += 2; return;}/* Write 4-byte long to image */static voidimage_write_l (abfd, value) bfd *abfd; unsigned long value;{#if VMS_DEBUG _bfd_vms_debug (6, "image_write_l (%08lx)\n", value);#endif if (PRIV(is_vax) && check_section (abfd, 4)) return; bfd_putl32 (value, PRIV(image_ptr)); PRIV(image_ptr) += 4; return;}/* Write 8-byte quad to image */static voidimage_write_q (abfd, value) bfd *abfd; uquad value;{#if VMS_DEBUG _bfd_vms_debug (6, "image_write_q (%016lx)\n", value);#endif if (PRIV(is_vax) && check_section (abfd, 8)) return; bfd_putl64 (value, PRIV(image_ptr)); PRIV(image_ptr) += 8; return;}#define HIGHBIT(op) ((op & 0x80000000L) == 0x80000000L)/* etir_sta vms stack commands handle sta_xxx commands in etir section ptr points to data area in record see table B-8 of the openVMS linker manual */static booleanetir_sta (abfd, cmd, ptr) bfd *abfd; int cmd; unsigned char *ptr;{#if VMS_DEBUG _bfd_vms_debug (5, "etir_sta %d/%x\n", cmd, cmd); _bfd_hexdump (8, ptr, 16, (int)ptr);#endif switch (cmd) { /* stack */ /* stack global arg: cs symbol name stack 32 bit value of symbol (high bits set to 0) */ case ETIR_S_C_STA_GBL: { char *name; vms_symbol_entry *entry; name = _bfd_vms_save_counted_string (ptr); entry = (vms_symbol_entry *) bfd_hash_lookup (PRIV(vms_symbol_table), name, false, false); if (entry == (vms_symbol_entry *)NULL) {#if VMS_DEBUG _bfd_vms_debug (3, "ETIR_S_C_STA_GBL: no symbol \"%s\"\n", name);#endif _bfd_vms_push (abfd, (uquad)0, -1); } else { _bfd_vms_push (abfd, (uquad) (entry->symbol->value), -1); } } break; /* stack longword arg: lw value stack 32 bit value, sign extend to 64 bit */ case ETIR_S_C_STA_LW: _bfd_vms_push (abfd, (uquad)bfd_getl32 (ptr), -1); break; /* stack global arg: qw value stack 64 bit value of symbol */ case ETIR_S_C_STA_QW: _bfd_vms_push (abfd, (uquad)bfd_getl64(ptr), -1); break; /* stack psect base plus quadword offset arg: lw section index qw signed quadword offset (low 32 bits) stack qw argument and section index (see ETIR_S_C_STO_OFF, ETIR_S_C_CTL_SETRB) */ case ETIR_S_C_STA_PQ: { uquad dummy; unsigned int psect; psect = bfd_getl32 (ptr); if (psect >= PRIV(section_count)) { (*_bfd_error_handler) (_("Bad section index in ETIR_S_C_STA_PQ")); bfd_set_error (bfd_error_bad_value); return false; } dummy = bfd_getl64 (ptr+4); _bfd_vms_push (abfd, dummy, psect); } break; /* all not supported */ case ETIR_S_C_STA_LI: case ETIR_S_C_STA_MOD: case ETIR_S_C_STA_CKARG: (*_bfd_error_handler) (_("Unsupported STA cmd %d"), cmd); return false; break; default: (*_bfd_error_handler) (_("Reserved STA cmd %d"), cmd); return false; break; }#if VMS_DEBUG _bfd_vms_debug (5, "etir_sta true\n");#endif return true;}/* etir_sto vms store commands handle sto_xxx commands in etir section ptr points to data area in record see table B-9 of the openVMS linker manual */static booleanetir_sto (abfd, cmd, ptr) bfd *abfd; int cmd; unsigned char *ptr;{ uquad dummy; int psect;#if VMS_DEBUG _bfd_vms_debug (5, "etir_sto %d/%x\n", cmd, cmd); _bfd_hexdump (8, ptr, 16, (int)ptr);#endif switch (cmd) { /* store byte: pop stack, write byte arg: - */ case ETIR_S_C_STO_B: dummy = _bfd_vms_pop (abfd, &psect);#if 0 if (is_share) /* FIXME */ (*_bfd_error_handler) ("ETIR_S_C_STO_B: byte fixups not supported");#endif image_write_b (abfd, dummy & 0xff); /* FIXME: check top bits */ break; /* store word: pop stack, write word arg: - */ case ETIR_S_C_STO_W: dummy = _bfd_vms_pop (abfd, &psect);#if 0 if (is_share) /* FIXME */ (*_bfd_error_handler) ("ETIR_S_C_STO_B: word fixups not supported");#endif image_write_w (abfd, dummy & 0xffff); /* FIXME: check top bits */ break; /* store longword: pop stack, write longword arg: - */ case ETIR_S_C_STO_LW: dummy = _bfd_vms_pop (abfd, &psect); dummy += (PRIV(sections)[psect])->vma; image_write_l (abfd, dummy & 0xffffffff);/* FIXME: check top bits */ break; /* store quadword: pop stack, write quadword arg: - */ case ETIR_S_C_STO_QW: dummy = _bfd_vms_pop (abfd, &psect); dummy += (PRIV(sections)[psect])->vma; image_write_q (abfd, dummy); /* FIXME: check top bits */ break; /* store immediate repeated: pop stack for repeat count arg: lw byte count da data */ case ETIR_S_C_STO_IMMR: { unsigned long size; size = bfd_getl32 (ptr); dummy = (unsigned long)_bfd_vms_pop (abfd, NULL); while (dummy-- > 0L) image_dump (abfd, ptr+4, size, 0); } break; /* store global: write symbol value arg: cs global symbol name */ case ETIR_S_C_STO_GBL: { vms_symbol_entry *entry; char *name; name = _bfd_vms_save_counted_string (ptr); entry = (vms_symbol_entry *)bfd_hash_lookup (PRIV(vms_symbol_table), name, false, false); if (entry == (vms_symbol_entry *)NULL) { (*_bfd_error_handler) (_("ETIR_S_C_STO_GBL: no symbol \"%s\""), name); return false; } else image_write_q (abfd, (uquad) (entry->symbol->value)); /* FIXME, reloc */ } break; /* store code address: write address of entry point arg: cs global symbol name (procedure) */ case ETIR_S_C_STO_CA: { vms_symbol_entry *entry; char *name; name = _bfd_vms_save_counted_string (ptr); entry = (vms_symbol_entry *) bfd_hash_lookup (PRIV(vms_symbol_table), name, false, false); if (entry == (vms_symbol_entry *)NULL) { (*_bfd_error_handler) (_("ETIR_S_C_STO_CA: no symbol \"%s\""), name); return false; } else image_write_q (abfd, (uquad) (entry->symbol->value)); /* FIXME, reloc */ } break; /* not supported */ case ETIR_S_C_STO_RB: case ETIR_S_C_STO_AB: (*_bfd_error_handler) (_("ETIR_S_C_STO_RB/AB: Not supported")); break; /* store offset to psect: pop stack, add low 32 bits to base of psect arg: - */ case ETIR_S_C_STO_OFF: { uquad q; int psect; q = _bfd_vms_pop (abfd, &psect); q += (PRIV(sections)[psect])->vma; image_write_q (abfd, q); } break; /* store immediate arg: lw count of bytes da data */ case ETIR_S_C_STO_IMM: { int size; size = bfd_getl32 (ptr); image_dump (abfd, ptr+4, size, 0); } break; /* this code is 'reserved to digital' according to the openVMS linker manual, however it is generated by the DEC C compiler and defined in the include file. FIXME, since the following is just a guess store global longword: store 32bit value of symbol arg: cs symbol name */ case ETIR_S_C_STO_GBL_LW: { vms_symbol_entry *entry; char *name; name = _bfd_vms_save_counted_string (ptr); entry = (vms_symbol_entry *)bfd_hash_lookup (PRIV(vms_symbol_table), name, false, false); if (entry == (vms_symbol_entry *)NULL) {#if VMS_DEBUG _bfd_vms_debug (3, "ETIR_S_C_STO_GBL_LW: no symbol \"%s\"\n", name);#endif image_write_l (abfd, (unsigned long)0); /* FIXME, reloc */ } else image_write_l (abfd, (unsigned long) (entry->symbol->value)); /* FIXME, reloc */ } break; /* not supported */ case ETIR_S_C_STO_LP_PSB: (*_bfd_error_handler) (_("ETIR_S_C_STO_LP_PSB: Not supported")); break; /* */ case ETIR_S_C_STO_HINT_GBL: (*_bfd_error_handler) (_("ETIR_S_C_STO_HINT_GBL: not implemented")); break; /* */ case ETIR_S_C_STO_HINT_PS: (*_bfd_error_handler) (_("ETIR_S_C_STO_HINT_PS: not implemented")); break; default: (*_bfd_error_handler) (_("Reserved STO cmd %d"), cmd); break; } return true;}/* stack operator commands all 32 bit signed arithmetic all word just like a stack calculator arguments are popped from stack, results are pushed on stack see table B-10 of the openVMS linker manual */static booleanetir_opr (abfd, cmd, ptr) bfd *abfd; int cmd; unsigned char *ptr ATTRIBUTE_UNUSED;{ long op1, op2;#if VMS_DEBUG _bfd_vms_debug (5, "etir_opr %d/%x\n", cmd, cmd); _bfd_hexdump (8, ptr, 16, (int)ptr);#endif switch (cmd) { /* operation */ /* no-op */ case ETIR_S_C_OPR_NOP: break; /* add */ case ETIR_S_C_OPR_ADD: op1 = (long)_bfd_vms_pop (abfd, NULL); op2 = (long)_bfd_vms_pop (abfd, NULL); _bfd_vms_push (abfd, (uquad) (op1 + op2), -1); break; /* subtract */ case ETIR_S_C_OPR_SUB: op1 = (long)_bfd_vms_pop (abfd, NULL); op2 = (long)_bfd_vms_pop (abfd, NULL); _bfd_vms_push (abfd, (uquad) (op2 - op1), -1); break; /* multiply */ case ETIR_S_C_OPR_MUL: op1 = (long)_bfd_vms_pop (abfd, NULL); op2 = (long)_bfd_vms_pop (abfd, NULL); _bfd_vms_push (abfd, (uquad) (op1 * op2), -1); break; /* divide */ case ETIR_S_C_OPR_DIV: op1 = (long)_bfd_vms_pop (abfd, NULL); op2 = (long)_bfd_vms_pop (abfd, NULL); if (op2 == 0) _bfd_vms_push (abfd, (uquad)0L, -1); else _bfd_vms_push (abfd, (uquad) (op2 / op1), -1); break; /* logical and */ case ETIR_S_C_OPR_AND: op1 = (long)_bfd_vms_pop (abfd, NULL); op2 = (long)_bfd_vms_pop (abfd, NULL); _bfd_vms_push (abfd, (uquad) (op1 & op2), -1); break; /* logical inclusive or */
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?