Thu Jul 2 14:59:42 1998 Klaus Kaempf <kkaempf@rmi.de>

Merge of vax/vms (read-only) support
	* configure.com: Support Vax target.
	* makefile.vms: Support Vax target.
        * vms.h: Renamed from evax.h, merged vax/vms (read-only) support.
	* vms.c: Renamed from evax-alpha.c, merged vax/vms (read-only)
	support.
	* vms-hdr.c: Renamed from evax-emh.c, merged vax/vms (read-only)
	support.
	* vms-gsd.c: Renamed from evax-egsd.c, merged vax/vms (read-only)
	support.
	* vms-tir.c: Renamed from evax-etir.c, merged vax/vms (read-only)
	support.
	* vms-misc.c: Renamed from evax-misc.c, merged vax/vms (read-only)
	support.
	* libbfd.c (real_read): Use unbuffered read on VMS/Vax.
	* targets.c (bfd_target_ovax_flavour): New flavour.
	(vms_alpha_vec): Renamed from evax_alpha_vec.
	(vms_vax_vec): New.
	(target_vector): Update accordingly.
	* config.bfd (alpha*-*-*vms*): Use vms_alpha_vec, not
	evax_alpha_vec.
	(vax*-*-*vms*): New target.
	* Makefile.am: Update for renamed files.  Rebuild dependencies.
	* bfd-in2.h: Rebuild.
	* configure.in, Makefile.in, aclocal.m4: Rebuild.
This commit is contained in:
Ian Lance Taylor 1998-07-02 18:41:08 +00:00
parent 8d3c21b3d4
commit 0dc4c667ac
14 changed files with 4945 additions and 4901 deletions

View File

@ -179,12 +179,6 @@ elfcore.h
elflink.c
elflink.h
elfxx-target.h
evax-alpha.c
evax-egsd.c
evax-emh.c
evax-etir.c
evax-misc.c
evax.h
format.c
freebsd.h
gen-aout.c
@ -287,6 +281,12 @@ tekhex.c
trad-core.c
vaxnetbsd.c
versados.c
vms.c
vms.h
vms-gsd.c
vms-hdr.c
vms-misc.c
vms-tir.c
xcofflink.c
Things-to-lose:

View File

@ -1,3 +1,38 @@
Thu Jul 2 14:59:42 1998 Klaus Kaempf <kkaempf@rmi.de>
Merge of vax/vms (read-only) support
* configure.com: Support Vax target.
* makefile.vms: Support Vax target.
* vms.h: Renamed from evax.h, merged vax/vms (read-only) support.
* vms.c: Renamed from evax-alpha.c, merged vax/vms (read-only)
support.
* vms-hdr.c: Renamed from evax-emh.c, merged vax/vms (read-only)
support.
* vms-gsd.c: Renamed from evax-egsd.c, merged vax/vms (read-only)
support.
* vms-tir.c: Renamed from evax-etir.c, merged vax/vms (read-only)
support.
* vms-misc.c: Renamed from evax-misc.c, merged vax/vms (read-only)
support.
* libbfd.c (real_read): Use unbuffered read on VMS/Vax.
* targets.c (bfd_target_ovax_flavour): New flavour.
(vms_alpha_vec): Renamed from evax_alpha_vec.
(vms_vax_vec): New.
(target_vector): Update accordingly.
* config.bfd (alpha*-*-*vms*): Use vms_alpha_vec, not
evax_alpha_vec.
(vax*-*-*vms*): New target.
* Makefile.am: Update for renamed files. Rebuild dependencies.
* bfd-in2.h: Rebuild.
* configure.in, Makefile.in, aclocal.m4: Rebuild.
Thu Jul 2 13:31:55 1998 Ian Lance Taylor <ian@cygnus.com>
Based on patch from Matt Semersky <matts@scd.hp.com>:
* linker.c (_bfd_generic_final_link): Force a trailing NULL
pointer on abfd->outsymbols.
(generic_add_output_symbol): Handle NULL sym parameter.
Wed Jul 1 17:05:53 1998 Nick Clifton <nickc@cygnus.com>
* elf.c (copy_private_bfd_data): Add support for changing VMA or

View File

@ -76,7 +76,7 @@ case "${targ}" in
targ_selvecs=ecoffalpha_little_vec
;;
alpha*-*-*vms*)
targ_defvec=evax_alpha_vec
targ_defvec=vms_alpha_vec
;;
alpha*-*-*)
targ_defvec=ecoffalpha_little_vec
@ -610,6 +610,10 @@ case "${targ}" in
;;
#endif
vax*-*-*vms*)
targ_defvec=vms_vax_vec
;;
we32k-*-*)
targ_defvec=we32kcoff_vec
;;
@ -648,3 +652,16 @@ case "${targ}" in
exit 1
;;
esac
# If we support any ELF target, then automatically add support for the
# generic ELF targets. This permits an objdump with some ELF support
# to be used on an arbitrary ELF file for anything other than
# relocation information.
case "${targ_defvec} ${targ_selvecs}" in
*bfd_elf64*)
targ_selvecs="${targ_selvecs} bfd_elf64_little_generic_vec bfd_elf64_big_generic_vec bfd_elf32_little_generic_vec bfd_elf32_big_generic_vec"
;;
*bfd_elf32*)
targ_selvecs="${targ_selvecs} bfd_elf32_little_generic_vec bfd_elf32_big_generic_vec"
;;
esac

File diff suppressed because it is too large Load Diff

View File

@ -1,596 +0,0 @@
/* evax-egsd.c -- BFD back-end for ALPHA EVAX (openVMS/Alpha) files.
Copyright 1996, 1997, 1998 Free Software Foundation Inc.
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@progis.de)
of proGIS Softwareentwicklung, Aachen, Germany
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the 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 of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
#include <ctype.h>
#include "bfd.h"
#include "sysdep.h"
#include "bfdlink.h"
#include "libbfd.h"
#include "evax.h"
/*-----------------------------------------------------------------------------*/
/* sections every evax object file has */
#define EVAX_ABS_NAME "$ABS$"
#define EVAX_CODE_NAME "$CODE$"
#define EVAX_LINK_NAME "$LINK$"
#define EVAX_DATA_NAME "$DATA$"
#define EVAX_BSS_NAME "$BSS$"
#define EVAX_READONLYADDR_NAME "$READONLY_ADDR$"
#define EVAX_READONLY_NAME "$READONLY$"
#define EVAX_LITERAL_NAME "$LITERAL$"
#define EVAX_COMMON_NAME "$COMMON$"
#define EVAX_LOCAL_NAME "$LOCAL$"
struct sec_flags_struct {
char *name; /* name of section */
int eflags_always;
flagword flags_always; /* flags we set always */
int eflags_hassize;
flagword flags_hassize; /* flags we set if the section has a size > 0 */
};
/* These flags are deccrtl/vaxcrtl (openVMS 6.2) compatible */
static struct sec_flags_struct evax_section_flags[] = {
{ EVAX_ABS_NAME,
(EGPS_S_V_SHR),
(SEC_DATA),
(EGPS_S_V_SHR),
(SEC_IN_MEMORY|SEC_DATA|SEC_HAS_CONTENTS|SEC_ALLOC|SEC_LOAD) },
{ EVAX_CODE_NAME,
(EGPS_S_V_PIC|EGPS_S_V_REL|EGPS_S_V_SHR|EGPS_S_V_EXE),
(SEC_CODE),
(EGPS_S_V_PIC|EGPS_S_V_REL|EGPS_S_V_SHR|EGPS_S_V_EXE),
(SEC_IN_MEMORY|SEC_CODE|SEC_HAS_CONTENTS|SEC_ALLOC|SEC_LOAD) },
{ EVAX_LITERAL_NAME,
(EGPS_S_V_PIC|EGPS_S_V_REL|EGPS_S_V_SHR|EGPS_S_V_RD|EGPS_S_V_NOMOD),
(SEC_DATA|SEC_READONLY),
(EGPS_S_V_PIC|EGPS_S_V_REL|EGPS_S_V_SHR|EGPS_S_V_RD),
(SEC_IN_MEMORY|SEC_DATA|SEC_HAS_CONTENTS|SEC_ALLOC|SEC_READONLY|SEC_LOAD) },
{ EVAX_LINK_NAME,
(EGPS_S_V_REL|EGPS_S_V_RD),
(SEC_DATA|SEC_READONLY),
(EGPS_S_V_REL|EGPS_S_V_RD),
(SEC_IN_MEMORY|SEC_DATA|SEC_HAS_CONTENTS|SEC_ALLOC|SEC_READONLY|SEC_LOAD) },
{ EVAX_DATA_NAME,
(EGPS_S_V_REL|EGPS_S_V_RD|EGPS_S_V_WRT|EGPS_S_V_NOMOD),
(SEC_DATA),
(EGPS_S_V_REL|EGPS_S_V_RD|EGPS_S_V_WRT),
(SEC_IN_MEMORY|SEC_DATA|SEC_HAS_CONTENTS|SEC_ALLOC|SEC_LOAD) },
{ EVAX_BSS_NAME,
(EGPS_S_V_REL|EGPS_S_V_RD|EGPS_S_V_WRT|EGPS_S_V_NOMOD),
(SEC_NO_FLAGS),
(EGPS_S_V_REL|EGPS_S_V_RD|EGPS_S_V_WRT|EGPS_S_V_NOMOD),
(SEC_IN_MEMORY|SEC_HAS_CONTENTS|SEC_ALLOC|SEC_LOAD) },
{ EVAX_READONLYADDR_NAME,
(EGPS_S_V_PIC|EGPS_S_V_REL|EGPS_S_V_RD),
(SEC_DATA|SEC_READONLY),
(EGPS_S_V_PIC|EGPS_S_V_REL|EGPS_S_V_RD),
(SEC_IN_MEMORY|SEC_DATA|SEC_HAS_CONTENTS|SEC_ALLOC|SEC_READONLY|SEC_LOAD) },
{ EVAX_READONLY_NAME,
(EGPS_S_V_PIC|EGPS_S_V_REL|EGPS_S_V_SHR|EGPS_S_V_RD|EGPS_S_V_NOMOD),
(SEC_DATA|SEC_READONLY),
(EGPS_S_V_PIC|EGPS_S_V_REL|EGPS_S_V_SHR|EGPS_S_V_RD),
(SEC_IN_MEMORY|SEC_DATA|SEC_HAS_CONTENTS|SEC_ALLOC|SEC_READONLY|SEC_LOAD) },
{ EVAX_LOCAL_NAME,
(EGPS_S_V_REL|EGPS_S_V_RD|EGPS_S_V_WRT),
(SEC_DATA),
(EGPS_S_V_REL|EGPS_S_V_RD|EGPS_S_V_WRT),
(SEC_IN_MEMORY|SEC_DATA|SEC_HAS_CONTENTS|SEC_ALLOC|SEC_LOAD) },
{ NULL,
(EGPS_S_V_REL|EGPS_S_V_RD|EGPS_S_V_WRT),
(SEC_DATA),
(EGPS_S_V_REL|EGPS_S_V_RD|EGPS_S_V_WRT),
(SEC_IN_MEMORY|SEC_DATA|SEC_HAS_CONTENTS|SEC_ALLOC|SEC_LOAD) }
};
/* Retrieve bfd section flags by name and size */
static flagword
evax_secflag_by_name(name, size)
char *name;
int size;
{
int i = 0;
while (evax_section_flags[i].name != NULL)
{
if (strcmp (name, evax_section_flags[i].name) == 0)
{
if (size > 0)
return evax_section_flags[i].flags_hassize;
else
return evax_section_flags[i].flags_always;
}
i++;
}
if (size > 0)
return evax_section_flags[i].flags_hassize;
return evax_section_flags[i].flags_always;
}
/* Retrieve evax section flags by name and size */
static flagword
evax_esecflag_by_name(name, size)
char *name;
int size;
{
int i = 0;
while (evax_section_flags[i].name != NULL)
{
if (strcmp (name, evax_section_flags[i].name) == 0)
{
if (size > 0)
return evax_section_flags[i].eflags_hassize;
else
return evax_section_flags[i].eflags_always;
}
i++;
}
if (size > 0)
return evax_section_flags[i].eflags_hassize;
return evax_section_flags[i].eflags_always;
}
/*-----------------------------------------------------------------------------*/
#if EVAX_DEBUG
/* debug */
struct flagdescstruct { char *name; flagword value; };
/* Convert flag to printable string */
static char *
flag2str(flagdesc, flags)
struct flagdescstruct *flagdesc;
flagword flags;
{
static char res[64];
int next = 0;
res[0] = 0;
while (flagdesc->name != NULL)
{
if ((flags & flagdesc->value) != 0)
{
if (next)
strcat(res, ",");
else
next = 1;
strcat (res, flagdesc->name);
}
flagdesc++;
}
return res;
}
#endif
/*-----------------------------------------------------------------------------*/
/* input routines */
/* Process EGSD record
return 0 on success, -1 on error */
int
_bfd_evax_slurp_egsd (abfd)
bfd *abfd;
{
#if EVAX_DEBUG
static struct flagdescstruct gpsflagdesc[] =
{
{ "PIC", 0x0001 },
{ "LIB", 0x0002 },
{ "OVR", 0x0004 },
{ "REL", 0x0008 },
{ "GBL", 0x0010 },
{ "SHR", 0x0020 },
{ "EXE", 0x0040 },
{ "RD", 0x0080 },
{ "WRT", 0x0100 },
{ "VEC", 0x0200 },
{ "NOMOD", 0x0400 },
{ "COM", 0x0800 },
{ NULL, 0 }
};
static struct flagdescstruct gsyflagdesc[] =
{
{ "WEAK", 0x0001 },
{ "DEF", 0x0002 },
{ "UNI", 0x0004 },
{ "REL", 0x0008 },
{ "COMM", 0x0010 },
{ "VECEP", 0x0020 },
{ "NORM", 0x0040 },
{ NULL, 0 }
};
#endif
int gsd_type, gsd_size;
asection *section;
unsigned char *evax_rec;
flagword new_flags, old_flags;
char *name;
asymbol *symbol;
evax_symbol_entry *entry;
unsigned long base_addr;
unsigned long align_addr;
#if EVAX_DEBUG
evax_debug (2, "EGSD\n");
#endif
PRIV(evax_rec) += 8; /* skip type, size, l_temp */
PRIV(rec_size) -= 8;
/* calculate base address for each section */
base_addr = 0L;
abfd->symcount = 0;
while (PRIV(rec_size) > 0)
{
evax_rec = PRIV(evax_rec);
_bfd_evax_get_header_values (abfd, evax_rec, &gsd_type, &gsd_size);
switch (gsd_type)
{
case EGSD_S_C_PSC:
{
/* program section definition */
name = _bfd_evax_save_counted_string ((char *)evax_rec+12);
section = bfd_make_section (abfd, name);
if (!section)
return -1;
old_flags = bfd_getl16 (evax_rec + 6);
section->_raw_size = bfd_getl32 (evax_rec + 8); /* allocation */
new_flags = evax_secflag_by_name (name, (int) section->_raw_size);
if (old_flags & EGPS_S_V_REL)
new_flags |= SEC_RELOC;
if (!bfd_set_section_flags (abfd, section, new_flags))
return -1;
section->alignment_power = evax_rec[4];
align_addr = (1 << section->alignment_power);
if ((base_addr % align_addr) != 0)
base_addr += (align_addr - (base_addr % align_addr));
section->vma = (bfd_vma)base_addr;
base_addr += section->_raw_size;
section->contents = ((unsigned char *)
bfd_malloc (section->_raw_size));
if (section->contents == NULL)
return -1;
memset (section->contents, 0, (size_t) section->_raw_size);
section->_cooked_size = section->_raw_size;
#if EVAX_DEBUG
evax_debug(3, "egsd psc %d (%s, flags %04x=%s) ",
section->index, name, old_flags, flag2str(gpsflagdesc, old_flags));
evax_debug(3, "%d bytes at 0x%08lx (mem %p)\n",
section->_raw_size, section->vma, section->contents);
#endif
}
break;
case EGSD_S_C_SYM:
{
/* symbol specification (definition or reference) */
symbol = _bfd_evax_make_empty_symbol (abfd);
if (symbol == 0)
return -1;
old_flags = bfd_getl16 (evax_rec + 6);
new_flags = BSF_NO_FLAGS;
if (old_flags & EGSY_S_V_WEAK)
new_flags |= BSF_WEAK;
if (evax_rec[6] & EGSY_S_V_DEF) /* symbol definition */
{
symbol->name =
_bfd_evax_save_counted_string ((char *)evax_rec+32);
if (old_flags & EGSY_S_V_NORM)
{ /* proc def */
new_flags |= BSF_FUNCTION;
}
symbol->value = bfd_getl64 (evax_rec+8);
symbol->section = (asection *)((unsigned long) bfd_getl32 (evax_rec+28));
#if EVAX_DEBUG
evax_debug(3, "egsd sym def #%d (%s, %d, %04x=%s)\n", abfd->symcount,
symbol->name, (int)symbol->section, old_flags, flag2str(gsyflagdesc, old_flags));
#endif
}
else /* symbol reference */
{
symbol->name =
_bfd_evax_save_counted_string ((char *)evax_rec+8);
#if EVAX_DEBUG
evax_debug(3, "egsd sym ref #%d (%s, %04x=%s)\n", abfd->symcount,
symbol->name, old_flags, flag2str(gsyflagdesc, old_flags));
#endif
symbol->section = bfd_make_section (abfd, BFD_UND_SECTION_NAME);
}
symbol->flags = new_flags;
/* save symbol in evax_symbol_table */
entry = (evax_symbol_entry *) bfd_hash_lookup (PRIV(evax_symbol_table), symbol->name, true, false);
if (entry == (evax_symbol_entry *)NULL)
{
bfd_set_error (bfd_error_no_memory);
return -1;
}
if (entry->symbol != (asymbol *)NULL)
{ /* FIXME ?, DEC C generates this */
#if EVAX_DEBUG
evax_debug(3, "EGSD_S_C_SYM: duplicate \"%s\"\n", symbol->name);
#endif
}
else
{
entry->symbol = symbol;
PRIV(egsd_sym_count)++;
abfd->symcount++;
}
}
break;
case EGSD_S_C_IDC:
break;
default:
(*_bfd_error_handler) (_("unknown egsd subtype %d"), gsd_type);
bfd_set_error (bfd_error_bad_value);
return -1;
} /* switch */
PRIV(rec_size) -= gsd_size;
PRIV(evax_rec) += gsd_size;
} /* while (recsize > 0) */
if (abfd->symcount > 0)
abfd->flags |= HAS_SYMS;
return 0;
}
/*-----------------------------------------------------------------------------*/
/* output routines */
/* Write section and symbol directory of bfd abfd */
int
_bfd_evax_write_egsd (abfd)
bfd *abfd;
{
asection *section;
asymbol *symbol;
int symnum;
int last_index = -1;
char dummy_name[10];
char *sname;
flagword new_flags, old_flags;
char *nptr, *uptr;
#if EVAX_DEBUG
evax_debug (2, "evax_write_egsd(%p)\n", abfd);
#endif
/* output sections */
section = abfd->sections;
#if EVAX_DEBUG
evax_debug (3, "%d sections found\n", abfd->section_count);
#endif
/* egsd is quadword aligned */
_bfd_evax_output_alignment (abfd, 8);
_bfd_evax_output_begin (abfd, EOBJ_S_C_EGSD, -1);
_bfd_evax_output_long (abfd, 0);
_bfd_evax_output_push (abfd); /* prepare output for subrecords */
while (section != 0)
{
#if EVAX_DEBUG
evax_debug (3, "Section #%d %s, %d bytes\n", section->index, section->name, (int)section->_raw_size);
#endif
/* 13 bytes egsd, max 31 chars name -> should be 44 bytes */
if (_bfd_evax_output_check (abfd, 64) < 0)
{
_bfd_evax_output_pop (abfd);
_bfd_evax_output_end (abfd);
_bfd_evax_output_begin (abfd, EOBJ_S_C_EGSD, -1);
_bfd_evax_output_long (abfd, 0);
_bfd_evax_output_push (abfd); /* prepare output for subrecords */
}
/* Create dummy sections to keep consecutive indices */
while (section->index - last_index > 1)
{
#if EVAX_DEBUG
evax_debug (3, "index %d, last %d\n", section->index, last_index);
#endif
_bfd_evax_output_begin (abfd, EGSD_S_C_PSC, -1);
_bfd_evax_output_short (abfd, 0);
_bfd_evax_output_short (abfd, 0);
_bfd_evax_output_long (abfd, 0);
sprintf (dummy_name, ".DUMMY%02d", last_index);
_bfd_evax_output_counted (abfd, dummy_name);
_bfd_evax_output_flush (abfd);
last_index++;
}
/* Don't know if this is neccesary for the linker but for now it keeps
evax_slurp_egsd happy */
sname = (char *)section->name;
if (*sname == '.')
{
sname++;
if ((*sname == 't') && (strcmp (sname, "text") == 0))
sname = EVAX_CODE_NAME;
else if ((*sname == 'd') && (strcmp (sname, "data") == 0))
sname = EVAX_DATA_NAME;
else if ((*sname == 'b') && (strcmp (sname, "bss") == 0))
sname = EVAX_BSS_NAME;
else if ((*sname == 'l') && (strcmp (sname, "link") == 0))
sname = EVAX_LINK_NAME;
else if ((*sname == 'r') && (strcmp (sname, "rdata") == 0))
sname = EVAX_READONLY_NAME;
else if ((*sname == 'l') && (strcmp (sname, "literal") == 0))
sname = EVAX_LITERAL_NAME;
else if ((*sname == 'c') && (strcmp (sname, "comm") == 0))
sname = EVAX_COMMON_NAME;
else if ((*sname == 'l') && (strcmp (sname, "lcomm") == 0))
sname = EVAX_LOCAL_NAME;
}
else
sname = _bfd_evax_length_hash_symbol (abfd, sname, EOBJ_S_C_SECSIZ);
_bfd_evax_output_begin (abfd, EGSD_S_C_PSC, -1);
_bfd_evax_output_short (abfd, section->alignment_power & 0xff);
if (bfd_is_com_section (section))
{
new_flags = (EGPS_S_V_OVR|EGPS_S_V_REL|EGPS_S_V_GBL|EGPS_S_V_RD|EGPS_S_V_WRT|EGPS_S_V_NOMOD|EGPS_S_V_COM);
}
else
{
new_flags = evax_esecflag_by_name (sname, section->_raw_size);
}
_bfd_evax_output_short (abfd, new_flags);
_bfd_evax_output_long (abfd, section->_raw_size);
_bfd_evax_output_counted (abfd, sname);
_bfd_evax_output_flush (abfd);
last_index = section->index;
section = section->next;
}
/* output symbols */
#if EVAX_DEBUG
evax_debug (3, "%d symbols found\n", abfd->symcount);
#endif
bfd_set_start_address (abfd, (bfd_vma)-1);
for (symnum = 0; symnum < abfd->symcount; symnum++)
{
symbol = abfd->outsymbols[symnum];
if (*(symbol->name) == '_')
{
if (strcmp (symbol->name, "__main") == 0)
bfd_set_start_address (abfd, (bfd_vma)symbol->value);
}
old_flags = symbol->flags;
if (old_flags & BSF_FILE)
continue;
if (((old_flags & (BSF_GLOBAL|BSF_WEAK)) == 0) /* not xdef */
&& (!bfd_is_und_section (symbol->section))) /* and not xref */
continue; /* dont output */
/* 13 bytes egsd, max 64 chars name -> should be 77 bytes */
if (_bfd_evax_output_check (abfd, 80) < 0)
{
_bfd_evax_output_pop (abfd);
_bfd_evax_output_end (abfd);
_bfd_evax_output_begin (abfd, EOBJ_S_C_EGSD, -1);
_bfd_evax_output_long (abfd, 0);
_bfd_evax_output_push (abfd); /* prepare output for subrecords */
}
_bfd_evax_output_begin (abfd, EGSD_S_C_SYM, -1);
_bfd_evax_output_short (abfd, 0); /* data type, alignment */
new_flags = 0;
if (old_flags & BSF_WEAK)
new_flags |= EGSY_S_V_WEAK;
if (bfd_is_com_section (symbol->section)) /* .comm */
new_flags |= (EGSY_S_V_WEAK|EGSY_S_V_COMM);
if (old_flags & BSF_FUNCTION)
{
new_flags |= EGSY_S_V_NORM;
new_flags |= EGSY_S_V_REL;
}
if (old_flags & (BSF_GLOBAL|BSF_WEAK))
{
new_flags |= EGSY_S_V_DEF;
if (!bfd_is_abs_section (symbol->section))
new_flags |= EGSY_S_V_REL;
}
_bfd_evax_output_short (abfd, new_flags);
if (old_flags & (BSF_GLOBAL|BSF_WEAK)) /* symbol definition */
{
if (old_flags & BSF_FUNCTION)
{
_bfd_evax_output_quad (abfd, symbol->value);
_bfd_evax_output_quad (abfd,
((asymbol *)(symbol->udata.p))->value);
_bfd_evax_output_long (abfd,
(((asymbol *)(symbol->udata.p))
->section->index));
_bfd_evax_output_long (abfd, symbol->section->index);
}
else
{
_bfd_evax_output_quad (abfd, symbol->value); /* L_VALUE */
_bfd_evax_output_quad (abfd, 0); /* L_CODE_ADDRESS */
_bfd_evax_output_long (abfd, 0); /* L_CA_PSINDX */
_bfd_evax_output_long (abfd, symbol->section->index);/* L_PSINDX */
}
}
_bfd_evax_output_counted (abfd, _bfd_evax_length_hash_symbol (abfd, symbol->name, EOBJ_S_C_SYMSIZ));
_bfd_evax_output_flush (abfd);
}
_bfd_evax_output_alignment (abfd, 8);
_bfd_evax_output_pop (abfd);
_bfd_evax_output_end (abfd);
return 0;
}

View File

@ -1,372 +0,0 @@
/* evax-emh.c -- BFD back-end for ALPHA EVAX (openVMS/Alpha) files.
Copyright 1996, 1997, 1998 Free Software Foundation, Inc.
EMH record handling functions
and
EEOM record handling functions
Written by Klaus K"ampf (kkaempf@progis.de)
of proGIS Softwareentwicklung, Aachen, Germany
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the 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 of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
#include <ctype.h>
#include "bfd.h"
#include "sysdep.h"
#include "bfdlink.h"
#include "libbfd.h"
#include "evax.h"
/*---------------------------------------------------------------------------*/
/* Read & process emh record
return 0 on success, -1 on error */
int
_bfd_evax_slurp_emh (abfd)
bfd *abfd;
{
unsigned char *ptr;
unsigned char *evax_rec;
evax_rec = PRIV(evax_rec);
#if EVAX_DEBUG
evax_debug(2, "EMH\n");
#endif
switch (bfd_getl16 (evax_rec + 4))
{
case EMH_S_C_MHD:
/*
* module header
*/
PRIV(emh_data).emh_b_strlvl = evax_rec[6];
PRIV(emh_data).emh_l_arch1 = bfd_getl32 (evax_rec + 8);
PRIV(emh_data).emh_l_arch2 = bfd_getl32 (evax_rec + 12);
PRIV(emh_data).emh_l_recsiz = bfd_getl32 (evax_rec + 16);
PRIV(emh_data).emh_t_name =
_bfd_evax_save_counted_string ((char *)evax_rec + 20);
ptr = evax_rec + 20 + evax_rec[20] + 1;
PRIV(emh_data).emh_t_version =
_bfd_evax_save_counted_string ((char *)ptr);
ptr += *ptr + 1;
PRIV(emh_data).emh_t_date =
_bfd_evax_save_sized_string ((char *)ptr, 17);
break;
case EMH_S_C_LNM:
/*
*
*/
PRIV(emh_data).emh_c_lnm =
_bfd_evax_save_sized_string ((char *)evax_rec, PRIV(rec_length-6));
break;
case EMH_S_C_SRC:
/*
*
*/
PRIV(emh_data).emh_c_src =
_bfd_evax_save_sized_string ((char *)evax_rec, PRIV(rec_length-6));
break;
case EMH_S_C_TTL:
/*
*
*/
PRIV(emh_data).emh_c_ttl =
_bfd_evax_save_sized_string ((char *)evax_rec, PRIV(rec_length-6));
break;
case EMH_S_C_CPR:
/*
*
*/
break;
case EMH_S_C_MTC:
/*
*
*/
break;
case EMH_S_C_GTX:
/*
*
*/
break;
default:
bfd_set_error (bfd_error_wrong_format);
return -1;
} /* switch */
return 0;
}
/*-----------------------------------------------------------------------------*/
/* Output routines. */
/* Manufacure a VMS like time on a unix based system.
stolen from obj-vms.c */
static unsigned char *
get_vms_time_string ()
{
static unsigned char tbuf[18];
#ifndef VMS
#include <time.h>
char *pnt;
time_t timeb;
time (&timeb);
pnt = ctime (&timeb);
pnt[3] = 0;
pnt[7] = 0;
pnt[10] = 0;
pnt[16] = 0;
pnt[24] = 0;
sprintf (tbuf, "%2s-%3s-%s %s", pnt + 8, pnt + 4, pnt + 20, pnt + 11);
#else
#include <starlet.h>
struct
{
int Size;
unsigned char *Ptr;
} Descriptor;
Descriptor.Size = 17;
Descriptor.Ptr = tbuf;
SYS$ASCTIM (0, &Descriptor, 0, 0);
#endif /* not VMS */
#if EVAX_DEBUG
evax_debug (6, "vmstimestring:'%s'\n", tbuf);
#endif
return tbuf;
}
/* write object header for bfd abfd */
int
_bfd_evax_write_emh (abfd)
bfd *abfd;
{
asymbol *symbol;
int symnum;
int had_case = 0;
int had_file = 0;
#if EVAX_DEBUG
evax_debug (2, "evax_write_emh(%p)\n", abfd);
#endif
_bfd_evax_output_alignment (abfd, 2);
/* MHD */
_bfd_evax_output_begin (abfd, EOBJ_S_C_EMH, EMH_S_C_MHD);
_bfd_evax_output_short (abfd, EOBJ_S_C_STRLVL);
_bfd_evax_output_long (abfd, 0);
_bfd_evax_output_long (abfd, 0);
_bfd_evax_output_long (abfd, MAX_OUTREC_SIZE);
if (bfd_get_filename (abfd) != 0)
{
/* strip path and suffix information */
char *fname, *fout, *fptr;
fptr = bfd_get_filename (abfd);
fname = (char *) alloca (strlen (fptr) + 1);
strcpy (fname, fptr);
fout = strrchr (fname, ']');
if (fout == 0)
fout = strchr (fname, ':');
if (fout != 0)
fout++;
else
fout = fname;
/* strip .obj suffix */
fptr = strrchr (fname, '.');
if ((fptr != 0)
&& (strcasecmp (fptr, ".OBJ") == 0))
*fptr = 0;
fptr = fout;
while (*fptr != 0)
{
if (islower (*fptr))
*fptr = toupper (*fptr);
fptr++;
if ((*fptr == ';')
|| ((fptr - fout) > 31))
*fptr = 0;
}
_bfd_evax_output_counted (abfd, fout);
}
else
_bfd_evax_output_counted (abfd, "NONAME");
_bfd_evax_output_counted (abfd, BFD_VERSION);
_bfd_evax_output_dump (abfd, get_vms_time_string (), 17);
_bfd_evax_output_fill (abfd, 0, 17);
_bfd_evax_output_flush (abfd);
/* LMN */
_bfd_evax_output_begin (abfd, EOBJ_S_C_EMH, EMH_S_C_LNM);
_bfd_evax_output_dump (abfd, (unsigned char *)"GAS proGIS", 10);
_bfd_evax_output_flush (abfd);
/* SRC */
_bfd_evax_output_begin (abfd, EOBJ_S_C_EMH, EMH_S_C_SRC);
for (symnum = 0; symnum < abfd->symcount; symnum++)
{
symbol = abfd->outsymbols[symnum];
if (symbol->flags & BSF_FILE)
{
char *s;
if (strncmp ((char *)symbol->name, "<CASE:", 6) == 0)
{
PRIV(flag_hash_long_names) = symbol->name[6] - '0';
PRIV(flag_show_after_trunc) = symbol->name[7] - '0';
if (had_file)
break;
had_case = 1;
continue;
}
_bfd_evax_output_dump (abfd, (unsigned char *)symbol->name, strlen (symbol->name));
if (had_case)
break;
had_file = 1;
}
}
if (symnum == abfd->symcount)
_bfd_evax_output_dump (abfd, (unsigned char *)"noname", 6);
_bfd_evax_output_flush (abfd);
/* TTL */
_bfd_evax_output_begin (abfd, EOBJ_S_C_EMH, EMH_S_C_TTL);
_bfd_evax_output_dump (abfd, (unsigned char *)"TTL", 3);
_bfd_evax_output_flush (abfd);
/* CPR */
_bfd_evax_output_begin (abfd, EOBJ_S_C_EMH, EMH_S_C_CPR);
_bfd_evax_output_dump (abfd,
(unsigned char *)"GNU BFD ported by Klaus Kämpf 1994-1996",
39);
_bfd_evax_output_flush (abfd);
return 0;
}
/*-----------------------------------------------------------------------------*/
/* Process EEOM record
return 0 on success, -1 on error */
int
_bfd_evax_slurp_eeom (abfd)
bfd *abfd;
{
unsigned char *evax_rec;
#if EVAX_DEBUG
evax_debug(2, "EEOM\n");
#endif
evax_rec = PRIV(evax_rec);
PRIV(eeom_data).eeom_l_total_lps = bfd_getl32 (evax_rec + 4);
PRIV(eeom_data).eeom_b_comcod = *(evax_rec + 8);
if (PRIV(eeom_data).eeom_b_comcod > 1)
{
(*_bfd_error_handler) (_("Object module NOT error-free !\n"));
bfd_set_error (bfd_error_bad_value);
return -1;
}
PRIV(eeom_data).eeom_has_transfer = false;
if (PRIV(rec_size) > 10)
{
PRIV(eeom_data).eeom_has_transfer = true;
PRIV(eeom_data).eeom_b_tfrflg = *(evax_rec + 9);
PRIV(eeom_data).eeom_l_psindx = bfd_getl32 (evax_rec + 12);
PRIV(eeom_data).eeom_l_tfradr = bfd_getl32 (evax_rec + 16);
abfd->start_address = PRIV(eeom_data).eeom_l_tfradr;
}
return 0;
}
/* Write eom record for bfd abfd */
int
_bfd_evax_write_eeom (abfd)
bfd *abfd;
{
#if EVAX_DEBUG
evax_debug (2, "evax_write_eeom(%p)\n", abfd);
#endif
_bfd_evax_output_begin (abfd,EOBJ_S_C_EEOM, -1);
_bfd_evax_output_long (abfd, (unsigned long)(PRIV(evax_linkage_index) >> 1));
_bfd_evax_output_byte (abfd, 0); /* completion code */
_bfd_evax_output_byte (abfd, 0); /* fill byte */
if (bfd_get_start_address (abfd) != (bfd_vma)-1)
{
asection *section;
section = bfd_get_section_by_name (abfd, ".link");
if (section == 0)
{
bfd_set_error (bfd_error_nonrepresentable_section);
return -1;
}
_bfd_evax_output_short (abfd, 0);
_bfd_evax_output_long (abfd, (unsigned long)(section->index));
_bfd_evax_output_long (abfd,
(unsigned long) bfd_get_start_address (abfd));
_bfd_evax_output_long (abfd, 0);
}
_bfd_evax_output_end (abfd);
return 0;
}

File diff suppressed because it is too large Load Diff

View File

@ -1,383 +0,0 @@
/* evax.h -- Header file for ALPHA EVAX (openVMS/Alpha) support.
Copyright 1996, 1997 Free Software Foundation, Inc.
Written by Klaus K"ampf (kkaempf@progis.de)
of proGIS Softwareentwicklung, Aachen, Germany
This file is part of BFD, the Binary File Descriptor library.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the 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 of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
#ifndef EVAX_H
#define EVAX_H
/* EVAX Text, information and relocation record (ETIR) definitions. */
#define ETIR_S_C_MINSTACOD 0 /* Minimum store code */
#define ETIR_S_C_STA_GBL 0 /* Stack global symbol value */
#define ETIR_S_C_STA_LW 1 /* Stack longword */
#define ETIR_S_C_STA_QW 2 /* Stack quadword */
#define ETIR_S_C_STA_PQ 3 /* Stack psect base plus quadword offset */
#define ETIR_S_C_STA_LI 4 /* Stack literal */
#define ETIR_S_C_STA_MOD 5 /* Stack module */
#define ETIR_S_C_STA_CKARG 6 /* Check Arguments */
#define ETIR_S_C_MAXSTACOD 6 /* Maximum stack code */
#define ETIR_S_C_MINSTOCOD 50 /* Minimum store code */
#define ETIR_S_C_STO_B 50 /* Store byte */
#define ETIR_S_C_STO_W 51 /* Store word */
#define ETIR_S_C_STO_LW 52 /* Store longword */
#define ETIR_S_C_STO_QW 53 /* Store quadword */
#define ETIR_S_C_STO_IMMR 54 /* Store immediate Repeated */
#define ETIR_S_C_STO_GBL 55 /* Store global */
#define ETIR_S_C_STO_CA 56 /* Store code address */
#define ETIR_S_C_STO_RB 57 /* Store relative branch */
#define ETIR_S_C_STO_AB 58 /* Store absolute branch */
#define ETIR_S_C_STO_OFF 59 /* Store offset within psect */
#define ETIR_S_C_STO_IMM 61 /* Store immediate */
#define ETIR_S_C_STO_GBL_LW 62 /* Store global Longword */
#define ETIR_S_C_STO_LP_PSB 63 /* STO_LP_PSB not valid in level 2 use STC_LP_PSB */
#define ETIR_S_C_STO_HINT_GBL 64 /* Store 14 bit HINT at global address */
#define ETIR_S_C_STO_HINT_PS 65 /* Store 14 bit HINT at psect + offset */
#define ETIR_S_C_MAXSTOCOD 65 /* Maximum store code */
#define ETIR_S_C_MINOPRCOD 100 /* Minimum operate code */
#define ETIR_S_C_OPR_NOP 100 /* No-op */
#define ETIR_S_C_OPR_ADD 101 /* Add */
#define ETIR_S_C_OPR_SUB 102 /* Subtract */
#define ETIR_S_C_OPR_MUL 103 /* Multiply */
#define ETIR_S_C_OPR_DIV 104 /* Divide */
#define ETIR_S_C_OPR_AND 105 /* Logical AND */
#define ETIR_S_C_OPR_IOR 106 /* Logical inclusive OR */
#define ETIR_S_C_OPR_EOR 107 /* Logical exclusive OR */
#define ETIR_S_C_OPR_NEG 108 /* Negate */
#define ETIR_S_C_OPR_COM 109 /* Complement */
#define ETIR_S_C_OPR_INSV 110 /* Insert bit field */
#define ETIR_S_C_OPR_ASH 111 /* Arithmetic shift */
#define ETIR_S_C_OPR_USH 112 /* Unsigned shift */
#define ETIR_S_C_OPR_ROT 113 /* Rotate */
#define ETIR_S_C_OPR_SEL 114 /* Select one of three longwords on top of stack */
#define ETIR_S_C_OPR_REDEF 115 /* Redefine this symbol after pass 2 */
#define ETIR_S_C_OPR_DFLIT 116 /* Define a literal */
#define ETIR_S_C_MAXOPRCOD 116 /* Maximum operate code */
#define ETIR_S_C_MINCTLCOD 150 /* Minimum control code */
#define ETIR_S_C_CTL_SETRB 150 /* Set relocation base */
#define ETIR_S_C_CTL_AUGRB 151 /* Augment relocation base */
#define ETIR_S_C_CTL_DFLOC 152 /* Define debug location */
#define ETIR_S_C_CTL_STLOC 153 /* Set debug location */
#define ETIR_S_C_CTL_STKDL 154 /* Stack debug location */
#define ETIR_S_C_MAXCTLCOD 154 /* Maximum control code */
#define ETIR_S_C_MINSTCCOD 200 /* Minimum store-conditional code */
#define ETIR_S_C_STC_LP 200 /* Store-conditional Linkage Pair */
#define ETIR_S_C_STC_LP_PSB 201 /* Store-conditional Linkage Pair with Procedure Signature */
#define ETIR_S_C_STC_GBL 202 /* Store-conditional Address at global address */
#define ETIR_S_C_STC_GCA 203 /* Store-conditional Code Address at global address */
#define ETIR_S_C_STC_PS 204 /* Store-conditional Address at psect + offset */
#define ETIR_S_C_STC_NOP_GBL 205 /* Store-conditional NOP at address of global */
#define ETIR_S_C_STC_NOP_PS 206 /* Store-conditional NOP at pect + offset */
#define ETIR_S_C_STC_BSR_GBL 207 /* Store-conditional BSR at global address */
#define ETIR_S_C_STC_BSR_PS 208 /* Store-conditional BSR at pect + offset */
#define ETIR_S_C_STC_LDA_GBL 209 /* Store-conditional LDA at global address */
#define ETIR_S_C_STC_LDA_PS 210 /* Store-conditional LDA at psect + offset */
#define ETIR_S_C_STC_BOH_GBL 211 /* Store-conditional BSR or Hint at global address */
#define ETIR_S_C_STC_BOH_PS 212 /* Store-conditional BSR or Hint at pect + offset */
#define ETIR_S_C_STC_NBH_GBL 213 /* Store-conditional NOP,BSR or HINT at global address */
#define ETIR_S_C_STC_NBH_PS 214 /* Store-conditional NOP,BSR or HINT at psect + offset */
#define ETIR_S_C_MAXSTCCOD 214 /* Maximum store-conditional code */
/* EVAX Global symbol definition record (EGSD). */
#define EGSD_S_K_ENTRIES 2 /* Offset to first entry in record */
#define EGSD_S_C_ENTRIES 2 /* Offset to first entry in record */
#define EGSD_S_C_PSC 0 /* Psect definition */
#define EGSD_S_C_SYM 1 /* Symbol specification */
#define EGSD_S_C_IDC 2 /* Random entity check */
#define EGSD_S_C_SPSC 5 /* Shareable image psect definition */
#define EGSD_S_C_SYMV 6 /* Vectored (dual-valued) versions of SYM, */
#define EGSD_S_C_SYMM 7 /* Masked versions of SYM, */
#define EGSD_S_C_SYMG 8 /* EGST - gst version of SYM */
#define EGSD_S_C_MAXRECTYP 8 /* Maximum entry type defined */
#define EGPS_S_V_PIC 0x0001
#define EGPS_S_V_LIB 0x0002
#define EGPS_S_V_OVR 0x0004
#define EGPS_S_V_REL 0x0008
#define EGPS_S_V_GBL 0x0010
#define EGPS_S_V_SHR 0x0020
#define EGPS_S_V_EXE 0x0040
#define EGPS_S_V_RD 0x0080
#define EGPS_S_V_WRT 0x0100
#define EGPS_S_V_VEC 0x0200
#define EGPS_S_V_NOMOD 0x0400
#define EGPS_S_V_COM 0x0800
#define EGSY_S_V_WEAK 0x0001
#define EGSY_S_V_DEF 0x0002
#define EGSY_S_V_UNI 0x0004
#define EGSY_S_V_REL 0x0008
#define EGSY_S_V_COMM 0x0010
#define EGSY_S_V_VECEP 0x0020
#define EGSY_S_V_NORM 0x0040
/* EVAX Module header record (EMH) definitions. */
#define EMH_S_C_MHD 0 /* Main header record */
#define EMH_S_C_LNM 1 /* Language name and version */
#define EMH_S_C_SRC 2 /* Source file specification */
#define EMH_S_C_TTL 3 /* Title text of module */
#define EMH_S_C_CPR 4 /* Copyright notice */
#define EMH_S_C_MTC 5 /* Maintenance status */
#define EMH_S_C_GTX 6 /* General text */
#define EMH_S_C_MAXHDRTYP 6 /* Maximum allowable type */
/* evax-alpha.c. */
extern asymbol *_bfd_evax_make_empty_symbol PARAMS ((bfd *abfd));
/* evax-egsd.c. */
extern int _bfd_evax_slurp_egsd PARAMS ((bfd *abfd));
extern int _bfd_evax_write_egsd PARAMS ((bfd *abfd));
/* evax-emh.c. */
extern int _bfd_evax_slurp_emh PARAMS ((bfd *abfd));
extern int _bfd_evax_write_emh PARAMS ((bfd *abfd));
extern int _bfd_evax_slurp_eeom PARAMS ((bfd *abfd));
extern int _bfd_evax_write_eeom PARAMS ((bfd *abfd));
/* evax-etir.c. */
extern int _bfd_evax_slurp_etir PARAMS ((bfd *abfd));
extern int _bfd_evax_slurp_edbg PARAMS ((bfd *abfd));
extern int _bfd_evax_slurp_etbt PARAMS ((bfd *abfd));
extern int _bfd_evax_write_etir PARAMS ((bfd *abfd));
extern int _bfd_evax_write_etbt PARAMS ((bfd *abfd));
extern int _bfd_evax_write_edbg PARAMS ((bfd *abfd));
/* The r_type field in a reloc is one of the following values. */
#define ALPHA_R_IGNORE 0
#define ALPHA_R_REFQUAD 1
#define ALPHA_R_BRADDR 2
#define ALPHA_R_HINT 3
#define ALPHA_R_SREL16 4
#define ALPHA_R_SREL32 5
#define ALPHA_R_SREL64 6
#define ALPHA_R_OP_PUSH 7
#define ALPHA_R_OP_STORE 8
#define ALPHA_R_OP_PSUB 9
#define ALPHA_R_OP_PRSHIFT 10
#define ALPHA_R_LINKAGE 11
#define ALPHA_R_REFLONG 12
#define ALPHA_R_CODEADDR 13
/* Object language definitions. */
#define EOBJ_S_C_EMH 8 /*EVAX module header record */
#define EOBJ_S_C_EEOM 9 /*EVAX end of module record */
#define EOBJ_S_C_EGSD 10 /*EVAX global symbol definition record */
#define EOBJ_S_C_ETIR 11 /*EVAX text information record */
#define EOBJ_S_C_EDBG 12 /*EVAX Debugger information record */
#define EOBJ_S_C_ETBT 13 /*EVAX Traceback information record */
#define EOBJ_S_C_MAXRECTYP 13 /*Last assigned record type */
#define EOBJ_S_K_SUBTYP 4
#define EOBJ_S_C_SUBTYP 4
#define EOBJ_S_C_MAXRECSIZ 8192 /*Maximum legal record size */
#define EOBJ_S_C_STRLVL 2 /*Structure level */
#define EOBJ_S_C_SYMSIZ 64 /*Maximum symbol length */
#define EOBJ_S_C_SECSIZ 31 /*Maximum section name length */
#define EOBJ_S_C_STOREPLIM -1 /*Maximum repeat count on store commands */
#define EOBJ_S_C_PSCALILIM 16 /*Maximum p-sect alignment */
/* Miscellaneous definitions. */
#if __GNUC__
typedef unsigned long long uquad;
#else
typedef unsigned long uquad;
#endif
#define MAX_OUTREC_SIZE 4096
#define MIN_OUTREC_LUFT 64
typedef struct _evax_section {
unsigned char *contents;
bfd_vma offset;
bfd_size_type size;
struct _evax_section *next;
} evax_section;
extern boolean _bfd_save_evax_section
PARAMS ((bfd *abfd, asection *section, PTR data, file_ptr offset,
bfd_size_type count));
extern evax_section *_bfd_get_evax_section PARAMS ((bfd *abfd, int index));
typedef struct _evax_reloc {
struct _evax_reloc *next;
arelent *reloc;
asection *section;
} evax_reloc;
/* evax module header */
struct emh_struc {
int emh_b_strlvl;
long emh_l_arch1;
long emh_l_arch2;
long emh_l_recsiz;
char *emh_t_name;
char *emh_t_version;
char *emh_t_date;
char *emh_c_lnm;
char *emh_c_src;
char *emh_c_ttl;
};
/* evax end of module */
struct eeom_struc {
long eeom_l_total_lps;
unsigned char eeom_b_comcod;
boolean eeom_has_transfer;
unsigned char eeom_b_tfrflg;
long eeom_l_psindx;
long eeom_l_tfradr;
};
enum file_format_enum { FF_UNKNOWN, FF_FOREIGN, FF_NATIVE };
typedef struct evax_symbol_struct {
struct bfd_hash_entry bfd_hash;
asymbol *symbol;
} evax_symbol_entry;
/* stack value for push/pop commands */
struct stack_struct {
uquad value;
int psect;
};
#define STACKSIZE 50
/* location stack definitions for CTL_DFLOC, CTL_STLOC, and CTL_STKDL */
struct location_struct {
unsigned long value;
int psect;
};
#define LOCATION_SAVE_SIZE 32
#define EVAX_SECTION_COUNT 1024
struct evax_private_data_struct {
boolean fixup_done; /* Flag to indicate if all
section pointers and PRIV(sections)
are set up correctly */
unsigned char *evax_buf; /* buffer to record */
int buf_size; /* max size of buffer */
unsigned char *evax_rec; /* actual record ptr */
int rec_length; /* remaining record length */
int rec_size; /* actual record size */
int rec_type; /* actual record type */
enum file_format_enum file_format;
struct emh_struc emh_data; /* data from EMH record */
struct eeom_struc eeom_data; /* data from EEOM record */
int egsd_sec_count; /* # of EGSD sections */
asection **sections; /* vector of EGSD sections */
int egsd_sym_count; /* # of EGSD symbols */
asymbol **symbols; /* vector of EGSD symbols */
struct proc_value *procedure;
struct stack_struct *stack;
int stackptr;
evax_section *evax_section_table[EVAX_SECTION_COUNT];
struct bfd_hash_table *evax_symbol_table;
struct symbol_cache_entry **symcache;
int symnum;
struct location_struct *location_stack;
unsigned char *image_ptr; /* a pointer to section->contents */
unsigned char pdsc[8]; /* procedure descriptor */
/* Output routine storage */
unsigned char *output_buf; /* output data */
int push_level;
int pushed_size;
int length_pos;
int output_size;
int output_alignment;
/* linkage index counter
used by conditional store commands (ETIR_S_C_STC_) */
int evax_linkage_index;
/* see tc-alpha.c of gas for a description. */
int flag_hash_long_names; /* -+, hash instead of truncate */
int flag_show_after_trunc; /* -H, show hashing/truncation */
};
#define PRIV(name) ((struct evax_private_data_struct *)abfd->tdata.any)->name
#if EVAX_DEBUG
extern void _bfd_evax_debug PARAMS((int level, char *format, ...));
extern void _bfd_hexdump
PARAMS ((int level, unsigned char *ptr, int size, int offset));
#define evax_debug _bfd_evax_debug
#endif
extern struct bfd_hash_entry *_bfd_evax_hash_newfunc
PARAMS ((struct bfd_hash_entry *entry, struct bfd_hash_table *table,
const char *string));
extern void _bfd_evax_get_header_values
PARAMS ((bfd *abfd, unsigned char *buf, int *type, int *length));
extern int _bfd_evax_get_record PARAMS ((bfd *abfd));
extern int _bfd_evax_next_record PARAMS ((bfd *abfd));
extern char *_bfd_evax_save_sized_string PARAMS ((char *str, int size));
extern char *_bfd_evax_save_counted_string PARAMS ((char *ptr));
extern void _bfd_evax_push PARAMS ((bfd *abfd, uquad val, int psect));
extern uquad _bfd_evax_pop PARAMS ((bfd *abfd, int *psect));
extern boolean _bfd_save_evax_section
PARAMS ((bfd *abfd, asection *section, PTR data, file_ptr offset,
bfd_size_type count));
extern void _bfd_evax_output_begin
PARAMS ((bfd *abfd, int rectype, int rechead));
extern void _bfd_evax_output_alignment PARAMS ((bfd *abfd, int alignto));
extern void _bfd_evax_output_push PARAMS ((bfd *abfd));
extern void _bfd_evax_output_pop PARAMS ((bfd *abfd));
extern void _bfd_evax_output_flush PARAMS ((bfd *abfd));
extern void _bfd_evax_output_end PARAMS ((bfd *abfd));
extern int _bfd_evax_output_check PARAMS ((bfd *abfd, int size));
extern void _bfd_evax_output_byte PARAMS ((bfd *abfd, unsigned int value));
extern void _bfd_evax_output_short PARAMS ((bfd *abfd, unsigned int value));
extern void _bfd_evax_output_long PARAMS ((bfd *abfd, unsigned long value));
extern void _bfd_evax_output_quad PARAMS ((bfd *abfd, uquad value));
extern void _bfd_evax_output_counted PARAMS ((bfd *abfd, char *value));
extern void _bfd_evax_output_dump PARAMS ((bfd *abfd, unsigned char *data,
int length));
extern void _bfd_evax_output_fill PARAMS ((bfd *abfd, int value, int length));
extern char *_bfd_evax_length_hash_symbol PARAMS ((bfd *abfd, const char *in, int maxlen));
#endif /* EVAX_H */

View File

@ -109,12 +109,6 @@ elf64-sparc.c
elf64.c
elfcode.h
elflink.c
evax-alpha.c
evax-egsd.c
evax-emh.c
evax-etir.c
evax-misc.c
evax.h
format.c
genlink.h
go32stub.h
@ -197,4 +191,10 @@ tekhex.c
trad-core.c
vaxnetbsd.c
versados.c
vms-gsd.c
vms-hdr.c
vms-misc.c
vms-tir.c
vms.c
vms.h
xcofflink.c

920
bfd/vms-gsd.c Normal file
View File

@ -0,0 +1,920 @@
/* vms-gsd.c -- BFD back-end for VAX (openVMS/VAX) and
EVAX (openVMS/Alpha) files.
Copyright 1996, 1997, 1998 Free Software Foundation Inc.
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 modify
it under the terms of the GNU General Public License as published by
the 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 of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
#include <ctype.h>
#include "bfd.h"
#include "sysdep.h"
#include "bfdlink.h"
#include "libbfd.h"
#include "vms.h"
/*-----------------------------------------------------------------------------*/
/* typical sections for vax object files */
#define VAX_CODE_NAME "$CODE"
#define VAX_DATA_NAME "$DATA"
#define VAX_ADDRESS_DATA_NAME "$ADDRESS_DATA"
/* typical sections for evax object files */
#define EVAX_ABS_NAME "$ABS$"
#define EVAX_CODE_NAME "$CODE$"
#define EVAX_LINK_NAME "$LINK$"
#define EVAX_DATA_NAME "$DATA$"
#define EVAX_BSS_NAME "$BSS$"
#define EVAX_READONLYADDR_NAME "$READONLY_ADDR$"
#define EVAX_READONLY_NAME "$READONLY$"
#define EVAX_LITERAL_NAME "$LITERAL$"
#define EVAX_COMMON_NAME "$COMMON$"
#define EVAX_LOCAL_NAME "$LOCAL$"
struct sec_flags_struct {
char *name; /* name of section */
int vflags_always;
flagword flags_always; /* flags we set always */
int vflags_hassize;
flagword flags_hassize; /* flags we set if the section has a size > 0 */
};
/* These flags are deccrtl/vaxcrtl (openVMS 6.2 VAX) compatible */
static struct sec_flags_struct vax_section_flags[] = {
{ VAX_CODE_NAME,
(GPS_S_M_PIC|GPS_S_M_REL|GPS_S_M_SHR|GPS_S_M_EXE|GPS_S_M_RD),
(SEC_CODE),
(GPS_S_M_PIC|GPS_S_M_REL|GPS_S_M_SHR|GPS_S_M_EXE|GPS_S_M_RD),
(SEC_IN_MEMORY|SEC_CODE|SEC_HAS_CONTENTS|SEC_ALLOC|SEC_LOAD) },
{ VAX_DATA_NAME,
(GPS_S_M_PIC|GPS_S_M_REL|GPS_S_M_RD|GPS_S_M_WRT),
(SEC_DATA),
(GPS_S_M_PIC|GPS_S_M_REL|GPS_S_M_RD|GPS_S_M_WRT),
(SEC_IN_MEMORY|SEC_DATA|SEC_HAS_CONTENTS|SEC_ALLOC|SEC_LOAD) },
{ VAX_ADDRESS_DATA_NAME,
(GPS_S_M_PIC|GPS_S_M_REL|GPS_S_M_RD),
(SEC_DATA|SEC_READONLY),
(GPS_S_M_PIC|GPS_S_M_REL|GPS_S_M_RD),
(SEC_IN_MEMORY|SEC_DATA|SEC_HAS_CONTENTS|SEC_ALLOC|SEC_READONLY|SEC_LOAD) },
{ NULL,
(GPS_S_M_PIC|GPS_S_M_OVR|GPS_S_M_REL|GPS_S_M_GBL|GPS_S_M_RD|GPS_S_M_WRT),
(SEC_DATA),
(GPS_S_M_PIC|GPS_S_M_OVR|GPS_S_M_REL|GPS_S_M_GBL|GPS_S_M_RD|GPS_S_M_WRT),
(SEC_IN_MEMORY|SEC_DATA|SEC_HAS_CONTENTS|SEC_ALLOC|SEC_LOAD) }
};
/* These flags are deccrtl/vaxcrtl (openVMS 6.2 Alpha) compatible */
static struct sec_flags_struct evax_section_flags[] = {
{ EVAX_ABS_NAME,
(EGPS_S_V_SHR),
(SEC_DATA),
(EGPS_S_V_SHR),
(SEC_IN_MEMORY|SEC_DATA|SEC_HAS_CONTENTS|SEC_ALLOC|SEC_LOAD) },
{ EVAX_CODE_NAME,
(EGPS_S_V_PIC|EGPS_S_V_REL|EGPS_S_V_SHR|EGPS_S_V_EXE),
(SEC_CODE),
(EGPS_S_V_PIC|EGPS_S_V_REL|EGPS_S_V_SHR|EGPS_S_V_EXE),
(SEC_IN_MEMORY|SEC_CODE|SEC_HAS_CONTENTS|SEC_ALLOC|SEC_LOAD) },
{ EVAX_LITERAL_NAME,
(EGPS_S_V_PIC|EGPS_S_V_REL|EGPS_S_V_SHR|EGPS_S_V_RD|EGPS_S_V_NOMOD),
(SEC_DATA|SEC_READONLY),
(EGPS_S_V_PIC|EGPS_S_V_REL|EGPS_S_V_SHR|EGPS_S_V_RD),
(SEC_IN_MEMORY|SEC_DATA|SEC_HAS_CONTENTS|SEC_ALLOC|SEC_READONLY|SEC_LOAD) },
{ EVAX_LINK_NAME,
(EGPS_S_V_REL|EGPS_S_V_RD),
(SEC_DATA|SEC_READONLY),
(EGPS_S_V_REL|EGPS_S_V_RD),
(SEC_IN_MEMORY|SEC_DATA|SEC_HAS_CONTENTS|SEC_ALLOC|SEC_READONLY|SEC_LOAD) },
{ EVAX_DATA_NAME,
(EGPS_S_V_REL|EGPS_S_V_RD|EGPS_S_V_WRT|EGPS_S_V_NOMOD),
(SEC_DATA),
(EGPS_S_V_REL|EGPS_S_V_RD|EGPS_S_V_WRT),
(SEC_IN_MEMORY|SEC_DATA|SEC_HAS_CONTENTS|SEC_ALLOC|SEC_LOAD) },
{ EVAX_BSS_NAME,
(EGPS_S_V_REL|EGPS_S_V_RD|EGPS_S_V_WRT|EGPS_S_V_NOMOD),
(SEC_NO_FLAGS),
(EGPS_S_V_REL|EGPS_S_V_RD|EGPS_S_V_WRT|EGPS_S_V_NOMOD),
(SEC_IN_MEMORY|SEC_HAS_CONTENTS|SEC_ALLOC|SEC_LOAD) },
{ EVAX_READONLYADDR_NAME,
(EGPS_S_V_PIC|EGPS_S_V_REL|EGPS_S_V_RD),
(SEC_DATA|SEC_READONLY),
(EGPS_S_V_PIC|EGPS_S_V_REL|EGPS_S_V_RD),
(SEC_IN_MEMORY|SEC_DATA|SEC_HAS_CONTENTS|SEC_ALLOC|SEC_READONLY|SEC_LOAD) },
{ EVAX_READONLY_NAME,
(EGPS_S_V_PIC|EGPS_S_V_REL|EGPS_S_V_SHR|EGPS_S_V_RD|EGPS_S_V_NOMOD),
(SEC_DATA|SEC_READONLY),
(EGPS_S_V_PIC|EGPS_S_V_REL|EGPS_S_V_SHR|EGPS_S_V_RD),
(SEC_IN_MEMORY|SEC_DATA|SEC_HAS_CONTENTS|SEC_ALLOC|SEC_READONLY|SEC_LOAD) },
{ EVAX_LOCAL_NAME,
(EGPS_S_V_REL|EGPS_S_V_RD|EGPS_S_V_WRT),
(SEC_DATA),
(EGPS_S_V_REL|EGPS_S_V_RD|EGPS_S_V_WRT),
(SEC_IN_MEMORY|SEC_DATA|SEC_HAS_CONTENTS|SEC_ALLOC|SEC_LOAD) },
{ NULL,
(EGPS_S_V_REL|EGPS_S_V_RD|EGPS_S_V_WRT),
(SEC_DATA),
(EGPS_S_V_REL|EGPS_S_V_RD|EGPS_S_V_WRT),
(SEC_IN_MEMORY|SEC_DATA|SEC_HAS_CONTENTS|SEC_ALLOC|SEC_LOAD) }
};
/* Retrieve bfd section flags by name and size */
static flagword
vms_secflag_by_name (abfd, section_flags, name, size)
bfd *abfd;
struct sec_flags_struct *section_flags;
char *name;
int size;
{
int i = 0;
while (section_flags[i].name != NULL)
{
if ((PRIV(is_vax)?
strcasecmp (name, section_flags[i].name):
strcmp (name, section_flags[i].name)) == 0)
{
if (size > 0)
return section_flags[i].flags_hassize;
else
return section_flags[i].flags_always;
}
i++;
}
if (size > 0)
return section_flags[i].flags_hassize;
return section_flags[i].flags_always;
}
/* Retrieve vms section flags by name and size */
static flagword
vms_esecflag_by_name (section_flags, name, size)
struct sec_flags_struct *section_flags;
char *name;
int size;
{
int i = 0;
while (section_flags[i].name != NULL)
{
if (strcmp (name, section_flags[i].name) == 0)
{
if (size > 0)
return section_flags[i].vflags_hassize;
else
return section_flags[i].vflags_always;
}
i++;
}
if (size > 0)
return section_flags[i].vflags_hassize;
return section_flags[i].vflags_always;
}
/*-----------------------------------------------------------------------------*/
#if VMS_DEBUG
/* debug */
struct flagdescstruct { char *name; flagword value; };
/* Convert flag to printable string */
static char *
flag2str(flagdesc, flags)
struct flagdescstruct *flagdesc;
flagword flags;
{
static char res[64];
int next = 0;
res[0] = 0;
while (flagdesc->name != NULL)
{
if ((flags & flagdesc->value) != 0)
{
if (next)
strcat(res, ",");
else
next = 1;
strcat (res, flagdesc->name);
}
flagdesc++;
}
return res;
}
#endif
/*-----------------------------------------------------------------------------*/
/* input routines */
/* Process GSD/EGSD record
return 0 on success, -1 on error */
int
_bfd_vms_slurp_gsd (abfd, objtype)
bfd *abfd;
int objtype;
{
#if VMS_DEBUG
static struct flagdescstruct gpsflagdesc[] =
{
{ "PIC", 0x0001 },
{ "LIB", 0x0002 },
{ "OVR", 0x0004 },
{ "REL", 0x0008 },
{ "GBL", 0x0010 },
{ "SHR", 0x0020 },
{ "EXE", 0x0040 },
{ "RD", 0x0080 },
{ "WRT", 0x0100 },
{ "VEC", 0x0200 },
{ "NOMOD", 0x0400 },
{ "COM", 0x0800 },
{ NULL, 0 }
};
static struct flagdescstruct gsyflagdesc[] =
{
{ "WEAK", 0x0001 },
{ "DEF", 0x0002 },
{ "UNI", 0x0004 },
{ "REL", 0x0008 },
{ "COMM", 0x0010 },
{ "VECEP", 0x0020 },
{ "NORM", 0x0040 },
{ NULL, 0 }
};
#endif
int gsd_type, gsd_size;
asection *section;
unsigned char *vms_rec;
flagword new_flags, old_flags;
char *name;
asymbol *symbol;
vms_symbol_entry *entry;
unsigned long base_addr;
unsigned long align_addr;
static int psect_idx = 0;
#if VMS_DEBUG
vms_debug (2, "GSD/EGSD (%d/%x)\n", objtype, objtype);
#endif
switch (objtype)
{
case EOBJ_S_C_EGSD:
PRIV(vms_rec) += 8; /* skip type, size, l_temp */
PRIV(rec_size) -= 8;
break;
case OBJ_S_C_GSD:
PRIV(vms_rec) += 1;
PRIV(rec_size) -= 1;
break;
default:
return -1;
}
/* calculate base address for each section */
base_addr = 0L;
abfd->symcount = 0;
while (PRIV(rec_size) > 0)
{
vms_rec = PRIV(vms_rec);
if (objtype == OBJ_S_C_GSD)
{
gsd_type = *vms_rec;
}
else
{
_bfd_vms_get_header_values (abfd, vms_rec, &gsd_type, &gsd_size);
gsd_type += EVAX_OFFSET;
}
#if VMS_DEBUG
vms_debug (3, "gsd_type %d\n", gsd_type);
#endif
switch (gsd_type)
{
case GSD_S_C_PSC:
{
/*
* program section definition
*/
asection *old_section = 0;
#if VMS_DEBUG
vms_debug (4, "GSD_S_C_PSC\n");
#endif
/* If this section isn't a bfd section. */
if (PRIV(is_vax) && (psect_idx < (abfd->section_count-1)))
{
/* check for temporary section from TIR record. */
if (psect_idx < PRIV(section_count))
old_section = PRIV(sections)[psect_idx];
else
old_section = 0;
}
name = _bfd_vms_save_counted_string (vms_rec + 8);
section = bfd_make_section (abfd, name);
if (!section)
{
fprintf (stderr, "bfd_make_section (%s) failed\n", name);
return -1;
}
old_flags = bfd_getl16 (vms_rec + 2);
section->_raw_size = bfd_getl32(vms_rec + 4); /* allocation */
new_flags = vms_secflag_by_name (abfd, vax_section_flags, name, section->_raw_size);
if (old_flags & EGPS_S_V_REL)
new_flags |= SEC_RELOC;
if (old_flags & GPS_S_M_OVR)
new_flags |= SEC_IS_COMMON;
if (!bfd_set_section_flags (abfd, section, new_flags))
{
fprintf (stderr, "bfd_set_section_flags (%s, %x) failed\n", name, new_flags);
return -1;
}
section->alignment_power = vms_rec[1];
align_addr = (1 << section->alignment_power);
if ((base_addr % align_addr) != 0)
base_addr += (align_addr - (base_addr % align_addr));
section->vma = (bfd_vma)base_addr;
base_addr += section->_raw_size;
/* global section is common symbol */
if (old_flags & GPS_S_M_GBL)
{
entry = _bfd_vms_enter_symbol (abfd, name);
if (entry == (vms_symbol_entry *)NULL)
{
bfd_set_error (bfd_error_no_memory);
return -1;
}
symbol = entry->symbol;
symbol->value = 0;
symbol->section = section;
symbol->flags = (BSF_GLOBAL|BSF_SECTION_SYM|BSF_OLD_COMMON);
}
/* copy saved contents if old_section set */
if (old_section != 0)
{
section->contents = old_section->contents;
if (section->_raw_size < old_section->_raw_size)
{
fprintf (stderr, "Size mismatch section %s=%d, %s=%d\n", old_section->name, old_section->_raw_size, section->name, section->_raw_size);
return -1;
}
else if (section->_raw_size > old_section->_raw_size)
{
section->contents = ((unsigned char *)
bfd_realloc (old_section->contents, section->_raw_size));
if (section->contents == NULL)
{
bfd_set_error (bfd_error_no_memory);
return -1;
}
}
}
else
{
section->contents = ((unsigned char *)
bfd_malloc (section->_raw_size));
if (section->contents == NULL)
{
bfd_set_error (bfd_error_no_memory);
return -1;
}
memset (section->contents, 0, (size_t)section->_raw_size);
}
section->_cooked_size = section->_raw_size;
#if VMS_DEBUG
vms_debug (4, "gsd psc %d (%s, flags %04x=%s) ",
section->index, name, old_flags, flag2str (gpsflagdesc, old_flags));
vms_debug (4, "%d bytes at 0x%08lx (mem %p)\n",
section->_raw_size, section->vma, section->contents);
#endif
gsd_size = vms_rec[8] + 9;
psect_idx++;
}
break;
case GSD_S_C_EPM:
case GSD_S_C_EPMW:
#if VMS_DEBUG
vms_debug(4, "gsd epm\n");
#endif
/*FALLTHRU*/
case GSD_S_C_SYM:
case GSD_S_C_SYMW:
{
int name_offset, value_offset;
/*
* symbol specification (definition or reference)
*/
#if VMS_DEBUG
vms_debug (4, "GSD_S_C_SYM(W)\n");
#endif
old_flags = bfd_getl16 (vms_rec + 2);
new_flags = BSF_NO_FLAGS;
if (old_flags & GSY_S_M_WEAK)
new_flags |= BSF_WEAK;
switch (gsd_type)
{
case GSD_S_C_EPM:
name_offset = 11;
value_offset = 5;
new_flags |= BSF_FUNCTION;
break;
case GSD_S_C_EPMW:
name_offset = 12;
value_offset = 6;
new_flags |= BSF_FUNCTION;
break;
case GSD_S_C_SYM:
if (old_flags & GSY_S_M_DEF) /* symbol definition */
name_offset = 9;
else
name_offset = 4;
value_offset = 5;
break;
case GSD_S_C_SYMW:
if (old_flags & GSY_S_M_DEF) /* symbol definition */
name_offset = 10;
else
name_offset = 5;
value_offset = 6;
break;
}
/* save symbol in vms_symbol_table */
entry = _bfd_vms_enter_symbol (abfd,
_bfd_vms_save_counted_string (vms_rec + name_offset));
if (entry == (vms_symbol_entry *)NULL)
{
bfd_set_error (bfd_error_no_memory);
return -1;
}
symbol = entry->symbol;
if (old_flags & GSY_S_M_DEF) /* symbol definition */
{
int psect;
symbol->value = bfd_getl32 (vms_rec+value_offset);
if ((gsd_type == GSD_S_C_SYMW)
|| (gsd_type == GSD_S_C_EPMW))
psect = bfd_getl16 (vms_rec + value_offset - 2);
else
psect = vms_rec[value_offset-1];
symbol->section = (asection *)psect;
#if VMS_DEBUG
vms_debug(4, "gsd sym def #%d (%s, %d [%p], %04x=%s)\n", abfd->symcount,
symbol->name, (int)symbol->section, symbol->section, old_flags, flag2str(gsyflagdesc, old_flags));
#endif
}
else /* symbol reference */
{
symbol->section = bfd_make_section (abfd, BFD_UND_SECTION_NAME);
#if VMS_DEBUG
vms_debug (4, "gsd sym ref #%d (%s, %s [%p], %04x=%s)\n", abfd->symcount,
symbol->name, symbol->section->name, symbol->section, old_flags, flag2str (gsyflagdesc, old_flags));
#endif
}
gsd_size = vms_rec[name_offset] + name_offset + 1;
symbol->flags = new_flags;
}
break;
case GSD_S_C_PRO:
case GSD_S_C_PROW:
#if VMS_DEBUG
vms_debug(4, "gsd pro\n");
#endif
break;
case GSD_S_C_IDC:
#if VMS_DEBUG
vms_debug(4, "gsd idc\n");
#endif
break;
case GSD_S_C_ENV:
#if VMS_DEBUG
vms_debug(4, "gsd env\n");
#endif
break;
case GSD_S_C_LSY:
#if VMS_DEBUG
vms_debug(4, "gsd lsy\n");
#endif
break;
case GSD_S_C_LEPM:
#if VMS_DEBUG
vms_debug(4, "gsd lepm\n");
#endif
break;
case GSD_S_C_LPRO:
#if VMS_DEBUG
vms_debug(4, "gsd lpro\n");
#endif
break;
case GSD_S_C_SPSC:
#if VMS_DEBUG
vms_debug(4, "gsd spsc\n");
#endif
break;
case GSD_S_C_SYMV:
#if VMS_DEBUG
vms_debug(4, "gsd symv\n");
#endif
break;
case GSD_S_C_EPMV:
#if VMS_DEBUG
vms_debug(4, "gsd epmv\n");
#endif
break;
case GSD_S_C_PROV:
#if VMS_DEBUG
vms_debug(4, "gsd prov\n");
#endif
break;
case EGSD_S_C_PSC + EVAX_OFFSET:
{
/* program section definition */
name = _bfd_vms_save_counted_string (vms_rec+12);
section = bfd_make_section (abfd, name);
if (!section)
return -1;
old_flags = bfd_getl16 (vms_rec + 6);
section->_raw_size = bfd_getl32 (vms_rec + 8); /* allocation */
new_flags = vms_secflag_by_name (abfd, evax_section_flags, name, (int) section->_raw_size);
if (old_flags & EGPS_S_V_REL)
new_flags |= SEC_RELOC;
if (!bfd_set_section_flags (abfd, section, new_flags))
return -1;
section->alignment_power = vms_rec[4];
align_addr = (1 << section->alignment_power);
if ((base_addr % align_addr) != 0)
base_addr += (align_addr - (base_addr % align_addr));
section->vma = (bfd_vma)base_addr;
base_addr += section->_raw_size;
section->contents = ((unsigned char *)
bfd_malloc (section->_raw_size));
if (section->contents == NULL)
return -1;
memset (section->contents, 0, (size_t) section->_raw_size);
section->_cooked_size = section->_raw_size;
#if VMS_DEBUG
vms_debug(4, "egsd psc %d (%s, flags %04x=%s) ",
section->index, name, old_flags, flag2str(gpsflagdesc, old_flags));
vms_debug(4, "%d bytes at 0x%08lx (mem %p)\n",
section->_raw_size, section->vma, section->contents);
#endif
}
break;
case EGSD_S_C_SYM + EVAX_OFFSET:
{
/* symbol specification (definition or reference) */
symbol = _bfd_vms_make_empty_symbol (abfd);
if (symbol == 0)
return -1;
old_flags = bfd_getl16 (vms_rec + 6);
new_flags = BSF_NO_FLAGS;
if (old_flags & EGSY_S_V_WEAK)
new_flags |= BSF_WEAK;
if (vms_rec[6] & EGSY_S_V_DEF) /* symbol definition */
{
symbol->name =
_bfd_vms_save_counted_string (vms_rec+32);
if (old_flags & EGSY_S_V_NORM)
{ /* proc def */
new_flags |= BSF_FUNCTION;
}
symbol->value = bfd_getl64 (vms_rec+8);
symbol->section = (asection *)((unsigned long) bfd_getl32 (vms_rec+28));
#if VMS_DEBUG
vms_debug(4, "egsd sym def #%d (%s, %d, %04x=%s)\n", abfd->symcount,
symbol->name, (int)symbol->section, old_flags, flag2str(gsyflagdesc, old_flags));
#endif
}
else /* symbol reference */
{
symbol->name =
_bfd_vms_save_counted_string (vms_rec+8);
#if VMS_DEBUG
vms_debug(4, "egsd sym ref #%d (%s, %04x=%s)\n", abfd->symcount,
symbol->name, old_flags, flag2str(gsyflagdesc, old_flags));
#endif
symbol->section = bfd_make_section (abfd, BFD_UND_SECTION_NAME);
}
symbol->flags = new_flags;
/* save symbol in vms_symbol_table */
entry = (vms_symbol_entry *) bfd_hash_lookup (PRIV(vms_symbol_table), symbol->name, true, false);
if (entry == (vms_symbol_entry *)NULL)
{
bfd_set_error (bfd_error_no_memory);
return -1;
}
if (entry->symbol != (asymbol *)NULL)
{ /* FIXME ?, DEC C generates this */
#if VMS_DEBUG
vms_debug(4, "EGSD_S_C_SYM: duplicate \"%s\"\n", symbol->name);
#endif
}
else
{
entry->symbol = symbol;
PRIV(gsd_sym_count)++;
abfd->symcount++;
}
}
break;
case EGSD_S_C_IDC + EVAX_OFFSET:
break;
default:
(*_bfd_error_handler) (_("unknown gsd/egsd subtype %d"), gsd_type);
bfd_set_error (bfd_error_bad_value);
return -1;
} /* switch */
PRIV(rec_size) -= gsd_size;
PRIV(vms_rec) += gsd_size;
} /* while (recsize > 0) */
if (abfd->symcount > 0)
abfd->flags |= HAS_SYMS;
return 0;
}
/*-----------------------------------------------------------------------------*/
/* output routines */
/* Write section and symbol directory of bfd abfd */
int
_bfd_vms_write_gsd (abfd, objtype)
bfd *abfd;
int objtype;
{
asection *section;
asymbol *symbol;
int symnum;
int last_index = -1;
char dummy_name[10];
char *sname;
flagword new_flags, old_flags;
char *nptr, *uptr;
#if VMS_DEBUG
vms_debug (2, "vms_write_gsd (%p, %d)\n", abfd, objtype);
#endif
/* output sections */
section = abfd->sections;
#if VMS_DEBUG
vms_debug (3, "%d sections found\n", abfd->section_count);
#endif
/* egsd is quadword aligned */
_bfd_vms_output_alignment (abfd, 8);
_bfd_vms_output_begin (abfd, EOBJ_S_C_EGSD, -1);
_bfd_vms_output_long (abfd, 0);
_bfd_vms_output_push (abfd); /* prepare output for subrecords */
while (section != 0)
{
#if VMS_DEBUG
vms_debug (3, "Section #%d %s, %d bytes\n", section->index, section->name, (int)section->_raw_size);
#endif
/* 13 bytes egsd, max 31 chars name -> should be 44 bytes */
if (_bfd_vms_output_check (abfd, 64) < 0)
{
_bfd_vms_output_pop (abfd);
_bfd_vms_output_end (abfd);
_bfd_vms_output_begin (abfd, EOBJ_S_C_EGSD, -1);
_bfd_vms_output_long (abfd, 0);
_bfd_vms_output_push (abfd); /* prepare output for subrecords */
}
/* Create dummy sections to keep consecutive indices */
while (section->index - last_index > 1)
{
#if VMS_DEBUG
vms_debug (3, "index %d, last %d\n", section->index, last_index);
#endif
_bfd_vms_output_begin (abfd, EGSD_S_C_PSC, -1);
_bfd_vms_output_short (abfd, 0);
_bfd_vms_output_short (abfd, 0);
_bfd_vms_output_long (abfd, 0);
sprintf (dummy_name, ".DUMMY%02d", last_index);
_bfd_vms_output_counted (abfd, dummy_name);
_bfd_vms_output_flush (abfd);
last_index++;
}
/* Don't know if this is neccesary for the linker but for now it keeps
vms_slurp_gsd happy */
sname = (char *)section->name;
if (*sname == '.')
{
sname++;
if ((*sname == 't') && (strcmp (sname, "text") == 0))
sname = PRIV(is_vax)?VAX_CODE_NAME:EVAX_CODE_NAME;
else if ((*sname == 'd') && (strcmp (sname, "data") == 0))
sname = PRIV(is_vax)?VAX_DATA_NAME:EVAX_DATA_NAME;
else if ((*sname == 'b') && (strcmp (sname, "bss") == 0))
sname = EVAX_BSS_NAME;
else if ((*sname == 'l') && (strcmp (sname, "link") == 0))
sname = EVAX_LINK_NAME;
else if ((*sname == 'r') && (strcmp (sname, "rdata") == 0))
sname = EVAX_READONLY_NAME;
else if ((*sname == 'l') && (strcmp (sname, "literal") == 0))
sname = EVAX_LITERAL_NAME;
else if ((*sname == 'c') && (strcmp (sname, "comm") == 0))
sname = EVAX_COMMON_NAME;
else if ((*sname == 'l') && (strcmp (sname, "lcomm") == 0))
sname = EVAX_LOCAL_NAME;
}
else
sname = _bfd_vms_length_hash_symbol (abfd, sname, EOBJ_S_C_SECSIZ);
_bfd_vms_output_begin (abfd, EGSD_S_C_PSC, -1);
_bfd_vms_output_short (abfd, section->alignment_power & 0xff);
if (bfd_is_com_section (section))
{
new_flags = (EGPS_S_V_OVR|EGPS_S_V_REL|EGPS_S_V_GBL|EGPS_S_V_RD|EGPS_S_V_WRT|EGPS_S_V_NOMOD|EGPS_S_V_COM);
}
else
{
new_flags = vms_esecflag_by_name (evax_section_flags, sname, section->_raw_size);
}
_bfd_vms_output_short (abfd, new_flags);
_bfd_vms_output_long (abfd, section->_raw_size);
_bfd_vms_output_counted (abfd, sname);
_bfd_vms_output_flush (abfd);
last_index = section->index;
section = section->next;
}
/* output symbols */
#if VMS_DEBUG
vms_debug (3, "%d symbols found\n", abfd->symcount);
#endif
bfd_set_start_address (abfd, (bfd_vma)-1);
for (symnum = 0; symnum < abfd->symcount; symnum++)
{
symbol = abfd->outsymbols[symnum];
if (*(symbol->name) == '_')
{
if (strcmp (symbol->name, "__main") == 0)
bfd_set_start_address (abfd, (bfd_vma)symbol->value);
}
old_flags = symbol->flags;
if (old_flags & BSF_FILE)
continue;
if (((old_flags & (BSF_GLOBAL|BSF_WEAK)) == 0) /* not xdef */
&& (!bfd_is_und_section (symbol->section))) /* and not xref */
continue; /* dont output */
/* 13 bytes egsd, max 64 chars name -> should be 77 bytes */
if (_bfd_vms_output_check (abfd, 80) < 0)
{
_bfd_vms_output_pop (abfd);
_bfd_vms_output_end (abfd);
_bfd_vms_output_begin (abfd, EOBJ_S_C_EGSD, -1);
_bfd_vms_output_long (abfd, 0);
_bfd_vms_output_push (abfd); /* prepare output for subrecords */
}
_bfd_vms_output_begin (abfd, EGSD_S_C_SYM, -1);
_bfd_vms_output_short (abfd, 0); /* data type, alignment */
new_flags = 0;
if (old_flags & BSF_WEAK)
new_flags |= EGSY_S_V_WEAK;
if (bfd_is_com_section (symbol->section)) /* .comm */
new_flags |= (EGSY_S_V_WEAK|EGSY_S_V_COMM);
if (old_flags & BSF_FUNCTION)
{
new_flags |= EGSY_S_V_NORM;
new_flags |= EGSY_S_V_REL;
}
if (old_flags & (BSF_GLOBAL|BSF_WEAK))
{
new_flags |= EGSY_S_V_DEF;
if (!bfd_is_abs_section (symbol->section))
new_flags |= EGSY_S_V_REL;
}
_bfd_vms_output_short (abfd, new_flags);
if (old_flags & (BSF_GLOBAL|BSF_WEAK)) /* symbol definition */
{
if (old_flags & BSF_FUNCTION)
{
_bfd_vms_output_quad (abfd, symbol->value);
_bfd_vms_output_quad (abfd,
((asymbol *)(symbol->udata.p))->value);
_bfd_vms_output_long (abfd,
(((asymbol *)(symbol->udata.p))
->section->index));
_bfd_vms_output_long (abfd, symbol->section->index);
}
else
{
_bfd_vms_output_quad (abfd, symbol->value); /* L_VALUE */
_bfd_vms_output_quad (abfd, 0); /* L_CODE_ADDRESS */
_bfd_vms_output_long (abfd, 0); /* L_CA_PSINDX */
_bfd_vms_output_long (abfd, symbol->section->index);/* L_PSINDX */
}
}
_bfd_vms_output_counted (abfd, _bfd_vms_length_hash_symbol (abfd, symbol->name, EOBJ_S_C_SYMSIZ));
_bfd_vms_output_flush (abfd);
}
_bfd_vms_output_alignment (abfd, 8);
_bfd_vms_output_pop (abfd);
_bfd_vms_output_end (abfd);
return 0;
}

461
bfd/vms-hdr.c Normal file
View File

@ -0,0 +1,461 @@
/* vms-hdr.c -- BFD back-end for VMS/VAX (openVMS/VAX) and
EVAX (openVMS/Alpha) files.
Copyright 1996, 1997, 1998 Free Software Foundation, Inc.
HDR record handling functions
EMH record handling functions
and
EOM record handling functions
EEOM record handling functions
Written by Klaus K"ampf (kkaempf@rmi.de)
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the 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 of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
#include <ctype.h>
#include "bfd.h"
#include "sysdep.h"
#include "bfdlink.h"
#include "libbfd.h"
#include "vms.h"
/*---------------------------------------------------------------------------*/
/* Read & process emh record
return 0 on success, -1 on error */
int
_bfd_vms_slurp_hdr (abfd, objtype)
bfd *abfd;
int objtype;
{
unsigned char *ptr;
unsigned char *vms_rec;
int subtype;
vms_rec = PRIV(vms_rec);
#if VMS_DEBUG
vms_debug(2, "HDR/EMH\n");
#endif
switch (objtype)
{
case OBJ_S_C_HDR:
subtype = vms_rec[1];
break;
case EOBJ_S_C_EMH:
subtype = bfd_getl16 (vms_rec + 4) + EVAX_OFFSET;
break;
default:
subtype = -1;
}
#if VMS_DEBUG
vms_debug(3, "subtype %d\n", subtype);
#endif
switch (subtype)
{
case MHD_S_C_MHD:
/*
* module header
*/
PRIV(hdr_data).hdr_b_strlvl = vms_rec[2];
PRIV(hdr_data).hdr_l_recsiz = bfd_getl16 (vms_rec + 3);
PRIV(hdr_data).hdr_t_name = _bfd_vms_save_counted_string (vms_rec + 5);
ptr = vms_rec + 5 + vms_rec[5] + 1;
PRIV(hdr_data).hdr_t_version = _bfd_vms_save_counted_string (ptr);
ptr += *ptr + 1;
PRIV(hdr_data).hdr_t_date = _bfd_vms_save_sized_string (ptr, 17);
break;
case MHD_S_C_LNM:
/*
*
*/
PRIV(hdr_data).hdr_c_lnm = _bfd_vms_save_sized_string (vms_rec, PRIV(rec_length-2));
break;
case MHD_S_C_SRC:
/*
*
*/
PRIV(hdr_data).hdr_c_src = _bfd_vms_save_sized_string (vms_rec, PRIV(rec_length-2));
break;
case MHD_S_C_TTL:
/*
*
*/
PRIV(hdr_data).hdr_c_ttl = _bfd_vms_save_sized_string (vms_rec, PRIV(rec_length-2));
break;
case MHD_S_C_CPR:
/*
*
*/
break;
case MHD_S_C_MTC:
/*
*
*/
break;
case MHD_S_C_GTX:
/*
*
*/
break;
case EMH_S_C_MHD + EVAX_OFFSET:
/*
* module header
*/
PRIV(hdr_data).hdr_b_strlvl = vms_rec[6];
PRIV(hdr_data).hdr_l_arch1 = bfd_getl32 (vms_rec + 8);
PRIV(hdr_data).hdr_l_arch2 = bfd_getl32 (vms_rec + 12);
PRIV(hdr_data).hdr_l_recsiz = bfd_getl32 (vms_rec + 16);
PRIV(hdr_data).hdr_t_name =
_bfd_vms_save_counted_string (vms_rec + 20);
ptr = vms_rec + 20 + vms_rec[20] + 1;
PRIV(hdr_data).hdr_t_version =
_bfd_vms_save_counted_string (ptr);
ptr += *ptr + 1;
PRIV(hdr_data).hdr_t_date =
_bfd_vms_save_sized_string (ptr, 17);
break;
case EMH_S_C_LNM + EVAX_OFFSET:
/*
*
*/
PRIV(hdr_data).hdr_c_lnm =
_bfd_vms_save_sized_string (vms_rec, PRIV(rec_length-6));
break;
case EMH_S_C_SRC + EVAX_OFFSET:
/*
*
*/
PRIV(hdr_data).hdr_c_src =
_bfd_vms_save_sized_string (vms_rec, PRIV(rec_length-6));
break;
case EMH_S_C_TTL + EVAX_OFFSET:
/*
*
*/
PRIV(hdr_data).hdr_c_ttl =
_bfd_vms_save_sized_string (vms_rec, PRIV(rec_length-6));
break;
case EMH_S_C_CPR + EVAX_OFFSET:
/*
*
*/
break;
case EMH_S_C_MTC + EVAX_OFFSET:
/*
*
*/
break;
case EMH_S_C_GTX + EVAX_OFFSET:
/*
*
*/
break;
default:
bfd_set_error (bfd_error_wrong_format);
return -1;
} /* switch */
return 0;
}
/*-----------------------------------------------------------------------------*/
/* Output routines. */
/* Manufacure a VMS like time on a unix based system.
stolen from obj-vms.c */
static unsigned char *
get_vms_time_string ()
{
static unsigned char tbuf[18];
#ifndef VMS
#include <time.h>
char *pnt;
time_t timeb;
time (&timeb);
pnt = ctime (&timeb);
pnt[3] = 0;
pnt[7] = 0;
pnt[10] = 0;
pnt[16] = 0;
pnt[24] = 0;
sprintf (tbuf, "%2s-%3s-%s %s", pnt + 8, pnt + 4, pnt + 20, pnt + 11);
#else
#include <starlet.h>
struct
{
int Size;
unsigned char *Ptr;
} Descriptor;
Descriptor.Size = 17;
Descriptor.Ptr = tbuf;
SYS$ASCTIM (0, &Descriptor, 0, 0);
#endif /* not VMS */
#if VMS_DEBUG
vms_debug (6, "vmstimestring:'%s'\n", tbuf);
#endif
return tbuf;
}
/* write object header for bfd abfd */
int
_bfd_vms_write_hdr (abfd, objtype)
bfd *abfd;
int objtype;
{
asymbol *symbol;
int symnum;
int had_case = 0;
int had_file = 0;
#if VMS_DEBUG
vms_debug (2, "vms_write_hdr (%p)\n", abfd);
#endif
_bfd_vms_output_alignment (abfd, 2);
/* MHD */
if (objtype == OBJ_S_C_HDR)
{
}
else
{
_bfd_vms_output_begin (abfd, EOBJ_S_C_EMH, EMH_S_C_MHD);
_bfd_vms_output_short (abfd, EOBJ_S_C_STRLVL);
_bfd_vms_output_long (abfd, 0);
_bfd_vms_output_long (abfd, 0);
_bfd_vms_output_long (abfd, MAX_OUTREC_SIZE);
}
if (bfd_get_filename (abfd) != 0)
{
/* strip path and suffix information */
char *fname, *fout, *fptr;
fptr = bfd_get_filename (abfd);
fname = (char *) alloca (strlen (fptr) + 1);
strcpy (fname, fptr);
fout = strrchr (fname, ']');
if (fout == 0)
fout = strchr (fname, ':');
if (fout != 0)
fout++;
else
fout = fname;
/* strip .obj suffix */
fptr = strrchr (fname, '.');
if ((fptr != 0)
&& (strcasecmp (fptr, ".OBJ") == 0))
*fptr = 0;
fptr = fout;
while (*fptr != 0)
{
if (islower (*fptr))
*fptr = toupper (*fptr);
fptr++;
if ((*fptr == ';')
|| ((fptr - fout) > 31))
*fptr = 0;
}
_bfd_vms_output_counted (abfd, fout);
}
else
_bfd_vms_output_counted (abfd, "NONAME");
_bfd_vms_output_counted (abfd, BFD_VERSION);
_bfd_vms_output_dump (abfd, get_vms_time_string (), 17);
_bfd_vms_output_fill (abfd, 0, 17);
_bfd_vms_output_flush (abfd);
/* LMN */
_bfd_vms_output_begin (abfd, EOBJ_S_C_EMH, EMH_S_C_LNM);
_bfd_vms_output_dump (abfd, (unsigned char *)"GAS proGIS", 10);
_bfd_vms_output_flush (abfd);
/* SRC */
_bfd_vms_output_begin (abfd, EOBJ_S_C_EMH, EMH_S_C_SRC);
for (symnum = 0; symnum < abfd->symcount; symnum++)
{
symbol = abfd->outsymbols[symnum];
if (symbol->flags & BSF_FILE)
{
char *s;
if (strncmp ((char *)symbol->name, "<CASE:", 6) == 0)
{
PRIV(flag_hash_long_names) = symbol->name[6] - '0';
PRIV(flag_show_after_trunc) = symbol->name[7] - '0';
if (had_file)
break;
had_case = 1;
continue;
}
_bfd_vms_output_dump (abfd, (unsigned char *)symbol->name, strlen (symbol->name));
if (had_case)
break;
had_file = 1;
}
}
if (symnum == abfd->symcount)
_bfd_vms_output_dump (abfd, (unsigned char *)"noname", 6);
_bfd_vms_output_flush (abfd);
/* TTL */
_bfd_vms_output_begin (abfd, EOBJ_S_C_EMH, EMH_S_C_TTL);
_bfd_vms_output_dump (abfd, (unsigned char *)"TTL", 3);
_bfd_vms_output_flush (abfd);
/* CPR */
_bfd_vms_output_begin (abfd, EOBJ_S_C_EMH, EMH_S_C_CPR);
_bfd_vms_output_dump (abfd,
(unsigned char *)"GNU BFD ported by Klaus Kämpf 1994-1996",
39);
_bfd_vms_output_flush (abfd);
return 0;
}
/*-----------------------------------------------------------------------------*/
/* Process EOM/EEOM record
return 0 on success, -1 on error */
int
_bfd_vms_slurp_eom (abfd, objtype)
bfd *abfd;
int objtype;
{
unsigned char *vms_rec;
#if VMS_DEBUG
vms_debug(2, "EOM/EEOM\n");
#endif
vms_rec = PRIV(vms_rec);
if ((objtype == OBJ_S_C_EOM)
|| (objtype == OBJ_S_C_EOMW))
{
}
else
{
PRIV(eom_data).eom_l_total_lps = bfd_getl32 (vms_rec + 4);
PRIV(eom_data).eom_b_comcod = *(vms_rec + 8);
if (PRIV(eom_data).eom_b_comcod > 1)
{
(*_bfd_error_handler) (_("Object module NOT error-free !\n"));
bfd_set_error (bfd_error_bad_value);
return -1;
}
PRIV(eom_data).eom_has_transfer = false;
if (PRIV(rec_size) > 10)
{
PRIV(eom_data).eom_has_transfer = true;
PRIV(eom_data).eom_b_tfrflg = *(vms_rec + 9);
PRIV(eom_data).eom_l_psindx = bfd_getl32 (vms_rec + 12);
PRIV(eom_data).eom_l_tfradr = bfd_getl32 (vms_rec + 16);
abfd->start_address = PRIV(eom_data).eom_l_tfradr;
}
}
return 0;
}
/* Write eom record for bfd abfd */
int
_bfd_vms_write_eom (abfd, objtype)
bfd *abfd;
int objtype;
{
#if VMS_DEBUG
vms_debug (2, "vms_write_eom (%p, %d)\n", abfd, objtype);
#endif
_bfd_vms_output_begin (abfd, objtype, -1);
_bfd_vms_output_long (abfd, (unsigned long)(PRIV(vms_linkage_index) >> 1));
_bfd_vms_output_byte (abfd, 0); /* completion code */
_bfd_vms_output_byte (abfd, 0); /* fill byte */
if (bfd_get_start_address (abfd) != (bfd_vma)-1)
{
asection *section;
section = bfd_get_section_by_name (abfd, ".link");
if (section == 0)
{
bfd_set_error (bfd_error_nonrepresentable_section);
return -1;
}
_bfd_vms_output_short (abfd, 0);
_bfd_vms_output_long (abfd, (unsigned long)(section->index));
_bfd_vms_output_long (abfd,
(unsigned long) bfd_get_start_address (abfd));
_bfd_vms_output_long (abfd, 0);
}
_bfd_vms_output_end (abfd);
return 0;
}

File diff suppressed because it is too large Load Diff

2489
bfd/vms-tir.c Normal file

File diff suppressed because it is too large Load Diff

675
bfd/vms.h Normal file
View File

@ -0,0 +1,675 @@
#undef vms
/* vms.h -- Header file for VMS (Alpha and Vax) support.
Copyright 1996, 1997 Free Software Foundation, Inc.
Written by Klaus K"ampf (kkaempf@rmi.de)
This file is part of BFD, the Binary File Descriptor library.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the 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 of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
#ifndef VMS_H
#define VMS_H
/* Constants starting with 'Exxx_' are for openVMS/Alpha (EVAX object language) */
/* VMS Text, information and relocation record (TIR/ETIR) definitions. */
#define TIR_S_C_STA_GBL 0
#define TIR_S_C_STA_SB 1
#define TIR_S_C_STA_SW 2
#define TIR_S_C_STA_LW 3
#define TIR_S_C_STA_PB 4
#define TIR_S_C_STA_PW 5
#define TIR_S_C_STA_PL 6
#define TIR_S_C_STA_UB 7
#define TIR_S_C_STA_UW 8
#define TIR_S_C_STA_BFI 9
#define TIR_S_C_STA_WFI 10
#define TIR_S_C_STA_LFI 11
#define TIR_S_C_STA_EPM 12
#define TIR_S_C_STA_CKARG 13
#define TIR_S_C_STA_WPB 14
#define TIR_S_C_STA_WPW 15
#define TIR_S_C_STA_WPL 16
#define TIR_S_C_STA_LSY 17
#define TIR_S_C_STA_LIT 18
#define TIR_S_C_STA_LEPM 19
#define TIR_S_C_MAXSTACOD 19
#define TIR_S_C_MINSTOCOD 20
#define TIR_S_C_STO_SB 20
#define TIR_S_C_STO_SW 21
#define TIR_S_C_STO_L 22
#define TIR_S_C_STO_LW 22
#define TIR_S_C_STO_BD 23
#define TIR_S_C_STO_WD 24
#define TIR_S_C_STO_LD 25
#define TIR_S_C_STO_LI 26
#define TIR_S_C_STO_PIDR 27
#define TIR_S_C_STO_PICR 28
#define TIR_S_C_STO_RSB 29
#define TIR_S_C_STO_RSW 30
#define TIR_S_C_STO_RL 31
#define TIR_S_C_STO_VPS 32
#define TIR_S_C_STO_USB 33
#define TIR_S_C_STO_USW 34
#define TIR_S_C_STO_RUB 35
#define TIR_S_C_STO_RUW 36
#define TIR_S_C_STO_B 37
#define TIR_S_C_STO_W 38
#define TIR_S_C_STO_RB 39
#define TIR_S_C_STO_RW 40
#define TIR_S_C_STO_RIVB 41
#define TIR_S_C_STO_PIRR 42
#define TIR_S_C_MAXSTOCOD 42
#define TIR_S_C_MINOPRCOD 50
#define TIR_S_C_OPR_NOP 50
#define TIR_S_C_OPR_ADD 51
#define TIR_S_C_OPR_SUB 52
#define TIR_S_C_OPR_MUL 53
#define TIR_S_C_OPR_DIV 54
#define TIR_S_C_OPR_AND 55
#define TIR_S_C_OPR_IOR 56
#define TIR_S_C_OPR_EOR 57
#define TIR_S_C_OPR_NEG 58
#define TIR_S_C_OPR_COM 59
#define TIR_S_C_OPR_INSV 60
#define TIR_S_C_OPR_ASH 61
#define TIR_S_C_OPR_USH 62
#define TIR_S_C_OPR_ROT 63
#define TIR_S_C_OPR_SEL 64
#define TIR_S_C_OPR_REDEF 65
#define TIR_S_C_OPR_DFLIT 66
#define TIR_S_C_MAXOPRCOD 66
#define TIR_S_C_MINCTLCOD 80
#define TIR_S_C_CTL_SETRB 80
#define TIR_S_C_CTL_AUGRB 81
#define TIR_S_C_CTL_DFLOC 82
#define TIR_S_C_CTL_STLOC 83
#define TIR_S_C_CTL_STKDL 84
#define TIR_S_C_MAXCTLCOD 84
#define ETIR_S_C_MINSTACOD 0 /* Minimum store code */
#define ETIR_S_C_STA_GBL 0 /* Stack global symbol value */
#define ETIR_S_C_STA_LW 1 /* Stack longword */
#define ETIR_S_C_STA_QW 2 /* Stack quadword */
#define ETIR_S_C_STA_PQ 3 /* Stack psect base plus quadword offset */
#define ETIR_S_C_STA_LI 4 /* Stack literal */
#define ETIR_S_C_STA_MOD 5 /* Stack module */
#define ETIR_S_C_STA_CKARG 6 /* Check Arguments */
#define ETIR_S_C_MAXSTACOD 6 /* Maximum stack code */
#define ETIR_S_C_MINSTOCOD 50 /* Minimum store code */
#define ETIR_S_C_STO_B 50 /* Store byte */
#define ETIR_S_C_STO_W 51 /* Store word */
#define ETIR_S_C_STO_LW 52 /* Store longword */
#define ETIR_S_C_STO_QW 53 /* Store quadword */
#define ETIR_S_C_STO_IMMR 54 /* Store immediate Repeated */
#define ETIR_S_C_STO_GBL 55 /* Store global */
#define ETIR_S_C_STO_CA 56 /* Store code address */
#define ETIR_S_C_STO_RB 57 /* Store relative branch */
#define ETIR_S_C_STO_AB 58 /* Store absolute branch */
#define ETIR_S_C_STO_OFF 59 /* Store offset within psect */
#define ETIR_S_C_STO_IMM 61 /* Store immediate */
#define ETIR_S_C_STO_GBL_LW 62 /* Store global Longword */
#define ETIR_S_C_STO_LP_PSB 63 /* STO_LP_PSB not valid in level 2 use STC_LP_PSB */
#define ETIR_S_C_STO_HINT_GBL 64 /* Store 14 bit HINT at global address */
#define ETIR_S_C_STO_HINT_PS 65 /* Store 14 bit HINT at psect + offset */
#define ETIR_S_C_MAXSTOCOD 65 /* Maximum store code */
#define ETIR_S_C_MINOPRCOD 100 /* Minimum operate code */
#define ETIR_S_C_OPR_NOP 100 /* No-op */
#define ETIR_S_C_OPR_ADD 101 /* Add */
#define ETIR_S_C_OPR_SUB 102 /* Subtract */
#define ETIR_S_C_OPR_MUL 103 /* Multiply */
#define ETIR_S_C_OPR_DIV 104 /* Divide */
#define ETIR_S_C_OPR_AND 105 /* Logical AND */
#define ETIR_S_C_OPR_IOR 106 /* Logical inclusive OR */
#define ETIR_S_C_OPR_EOR 107 /* Logical exclusive OR */
#define ETIR_S_C_OPR_NEG 108 /* Negate */
#define ETIR_S_C_OPR_COM 109 /* Complement */
#define ETIR_S_C_OPR_INSV 110 /* Insert bit field */
#define ETIR_S_C_OPR_ASH 111 /* Arithmetic shift */
#define ETIR_S_C_OPR_USH 112 /* Unsigned shift */
#define ETIR_S_C_OPR_ROT 113 /* Rotate */
#define ETIR_S_C_OPR_SEL 114 /* Select one of three longwords on top of stack */
#define ETIR_S_C_OPR_REDEF 115 /* Redefine this symbol after pass 2 */
#define ETIR_S_C_OPR_DFLIT 116 /* Define a literal */
#define ETIR_S_C_MAXOPRCOD 116 /* Maximum operate code */
#define ETIR_S_C_MINCTLCOD 150 /* Minimum control code */
#define ETIR_S_C_CTL_SETRB 150 /* Set relocation base */
#define ETIR_S_C_CTL_AUGRB 151 /* Augment relocation base */
#define ETIR_S_C_CTL_DFLOC 152 /* Define debug location */
#define ETIR_S_C_CTL_STLOC 153 /* Set debug location */
#define ETIR_S_C_CTL_STKDL 154 /* Stack debug location */
#define ETIR_S_C_MAXCTLCOD 154 /* Maximum control code */
#define ETIR_S_C_MINSTCCOD 200 /* Minimum store-conditional code */
#define ETIR_S_C_STC_LP 200 /* Store-conditional Linkage Pair */
#define ETIR_S_C_STC_LP_PSB 201 /* Store-conditional Linkage Pair with Procedure Signature */
#define ETIR_S_C_STC_GBL 202 /* Store-conditional Address at global address */
#define ETIR_S_C_STC_GCA 203 /* Store-conditional Code Address at global address */
#define ETIR_S_C_STC_PS 204 /* Store-conditional Address at psect + offset */
#define ETIR_S_C_STC_NOP_GBL 205 /* Store-conditional NOP at address of global */
#define ETIR_S_C_STC_NOP_PS 206 /* Store-conditional NOP at pect + offset */
#define ETIR_S_C_STC_BSR_GBL 207 /* Store-conditional BSR at global address */
#define ETIR_S_C_STC_BSR_PS 208 /* Store-conditional BSR at pect + offset */
#define ETIR_S_C_STC_LDA_GBL 209 /* Store-conditional LDA at global address */
#define ETIR_S_C_STC_LDA_PS 210 /* Store-conditional LDA at psect + offset */
#define ETIR_S_C_STC_BOH_GBL 211 /* Store-conditional BSR or Hint at global address */
#define ETIR_S_C_STC_BOH_PS 212 /* Store-conditional BSR or Hint at pect + offset */
#define ETIR_S_C_STC_NBH_GBL 213 /* Store-conditional NOP,BSR or HINT at global address */
#define ETIR_S_C_STC_NBH_PS 214 /* Store-conditional NOP,BSR or HINT at psect + offset */
#define ETIR_S_C_MAXSTCCOD 214 /* Maximum store-conditional code */
/* VMS Global symbol definition record (GSD/EGSD). */
#define GSD_S_K_ENTRIES 1
#define GSD_S_C_ENTRIES 1
#define GSD_S_C_PSC 0
#define GSD_S_C_SYM 1
#define GSD_S_C_EPM 2
#define GSD_S_C_PRO 3
#define GSD_S_C_SYMW 4
#define GSD_S_C_EPMW 5
#define GSD_S_C_PROW 6
#define GSD_S_C_IDC 7
#define GSD_S_C_ENV 8
#define GSD_S_C_LSY 9
#define GSD_S_C_LEPM 10
#define GSD_S_C_LPRO 11
#define GSD_S_C_SPSC 12
#define GSD_S_C_SYMV 13
#define GSD_S_C_EPMV 14
#define GSD_S_C_PROV 15
#define GSD_S_C_MAXRECTYP 15
#define EGSD_S_K_ENTRIES 2 /* Offset to first entry in record */
#define EGSD_S_C_ENTRIES 2 /* Offset to first entry in record */
#define EGSD_S_C_PSC 0 /* Psect definition */
#define EGSD_S_C_SYM 1 /* Symbol specification */
#define EGSD_S_C_IDC 2 /* Random entity check */
#define EGSD_S_C_SPSC 5 /* Shareable image psect definition */
#define EGSD_S_C_SYMV 6 /* Vectored (dual-valued) versions of SYM, */
#define EGSD_S_C_SYMM 7 /* Masked versions of SYM, */
#define EGSD_S_C_SYMG 8 /* EGST - gst version of SYM */
#define EGSD_S_C_MAXRECTYP 8 /* Maximum entry type defined */
#define GPS_S_M_PIC 1
#define GPS_S_M_LIB 2
#define GPS_S_M_OVR 4
#define GPS_S_M_REL 8
#define GPS_S_M_GBL 16
#define GPS_S_M_SHR 32
#define GPS_S_M_EXE 64
#define GPS_S_M_RD 128
#define GPS_S_M_WRT 256
#define GPS_S_M_VEC 512
#define GPS_S_K_NAME 9
#define GPS_S_C_NAME 9
#define EGPS_S_V_PIC 0x0001
#define EGPS_S_V_LIB 0x0002
#define EGPS_S_V_OVR 0x0004
#define EGPS_S_V_REL 0x0008
#define EGPS_S_V_GBL 0x0010
#define EGPS_S_V_SHR 0x0020
#define EGPS_S_V_EXE 0x0040
#define EGPS_S_V_RD 0x0080
#define EGPS_S_V_WRT 0x0100
#define EGPS_S_V_VEC 0x0200
#define EGPS_S_V_NOMOD 0x0400
#define EGPS_S_V_COM 0x0800
#define GSY_S_M_WEAK 1
#define GSY_S_M_DEF 2
#define GSY_S_M_UNI 4
#define GSY_S_M_REL 8
#define EGSY_S_V_WEAK 0x0001
#define EGSY_S_V_DEF 0x0002
#define EGSY_S_V_UNI 0x0004
#define EGSY_S_V_REL 0x0008
#define EGSY_S_V_COMM 0x0010
#define EGSY_S_V_VECEP 0x0020
#define EGSY_S_V_NORM 0x0040
#define LSY_S_M_DEF 2
#define LSY_S_M_REL 8
#define ENV_S_M_DEF 1
#define ENV_S_M_NESTED 2
/*
* Debugger symbol definitions: These are done by hand, as no
* machine-readable version seems
* to be available.
*/
#define DST_S_C_C 7 /* Language == "C" */
#define DST_S_C_CXX 15 /* Language == "C++" */
#define DST_S_C_VERSION 153
#define DST_S_C_SOURCE 155 /* Source file */
#define DST_S_C_PROLOG 162
#define DST_S_C_BLKBEG 176 /* Beginning of block */
#define DST_S_C_BLKEND 177 /* End of block */
#define DST_S_C_ENTRY 181
#define DST_S_C_PSECT 184
#define DST_S_C_LINE_NUM 185 /* Line Number */
#define DST_S_C_LBLORLIT 186
#define DST_S_C_LABEL 187
#define DST_S_C_MODBEG 188 /* Beginning of module */
#define DST_S_C_MODEND 189 /* End of module */
#define DST_S_C_RTNBEG 190 /* Beginning of routine */
#define DST_S_C_RTNEND 191 /* End of routine */
#define DST_S_C_DELTA_PC_W 1 /* Incr PC */
#define DST_S_C_INCR_LINUM 2 /* Incr Line # */
#define DST_S_C_INCR_LINUM_W 3 /* Incr Line # */
#define DST_S_C_SET_LINUM_INCR 4
#define DST_S_C_SET_LINUM_INCR_W 5
#define DST_S_C_RESET_LINUM_INCR 6
#define DST_S_C_BEG_STMT_MODE 7
#define DST_S_C_END_STMT_MODE 8
#define DST_S_C_SET_LINE_NUM 9 /* Set Line # */
#define DST_S_C_SET_PC 10
#define DST_S_C_SET_PC_W 11
#define DST_S_C_SET_PC_L 12
#define DST_S_C_SET_STMTNUM 13
#define DST_S_C_TERM 14 /* End of lines */
#define DST_S_C_TERM_W 15 /* End of lines */
#define DST_S_C_SET_ABS_PC 16 /* Set PC */
#define DST_S_C_DELTA_PC_L 17 /* Incr PC */
#define DST_S_C_INCR_LINUM_L 18 /* Incr Line # */
#define DST_S_C_SET_LINUM_B 19 /* Set Line # */
#define DST_S_C_SET_LINUM_L 20 /* Set Line # */
#define DST_S_C_TERM_L 21 /* End of lines */
/* these are used with DST_S_C_SOURCE */
#define DST_S_C_SRC_DECLFILE 1 /* Declare source file */
#define DST_S_C_SRC_SETFILE 2 /* Set source file */
#define DST_S_C_SRC_SETREC_L 3 /* Set record, longword value */
#define DST_S_C_SRC_SETREC_W 4 /* Set record, word value */
#define DST_S_C_SRC_DEFLINES_W 10 /* # of line, word counter */
#define DST_S_C_SRC_DEFLINES_B 11 /* # of line, byte counter */
#define DST_S_C_SRC_FORMFEED 16 /* ^L counts as a record */
/* the following are the codes for the various data types. Anything not on
* the list is included under 'advanced_type'
*/
#define DBG_S_C_UCHAR 0x02
#define DBG_S_C_USINT 0x03
#define DBG_S_C_ULINT 0x04
#define DBG_S_C_UQUAD 0x05
#define DBG_S_C_SCHAR 0x06
#define DBG_S_C_SSINT 0x07
#define DBG_S_C_SLINT 0x08
#define DBG_S_C_SQUAD 0x09
#define DBG_S_C_REAL4 0x0a
#define DBG_S_C_REAL8 0x0b /* D_float double */
#define DBG_S_C_COMPLX4 0x0c /* 2xF_float complex float */
#define DBG_S_C_COMPLX8 0x0d /* 2xD_float complex double */
#define DBG_S_C_REAL8_G 0x1b /* G_float double */
#define DBG_S_C_COMPLX8_G 0x1d /* 2xG_float complex double */
#define DBG_S_C_FUNCTION_ADDR 0x17
#define DBG_S_C_ADVANCED_TYPE 0xa3
/* Some of these are just for future reference. [pr]
*/
#define DBG_S_C_UBITA 0x01 /* unsigned, aligned bit field */
#define DBG_S_C_UBITU 0x22 /* unsigned, unaligned bit field */
#define DBG_S_C_SBITA 0x29 /* signed, aligned bit field */
#define DBG_S_C_SBITU 0x2a /* signed, unaligned bit field */
#define DBG_S_C_CSTRING 0x2e /* asciz ('\0' terminated) string */
#define DBG_S_C_WCHAR 0x38 /* wchar_t */
/* These are descriptor class codes.
*/
#define DSC_K_CLASS_S 0x01 /* static (fixed length) */
#define DSC_K_CLASS_D 0x02 /* dynamic string (not via malloc!) */
#define DSC_K_CLASS_A 0x04 /* array */
#define DSC_K_CLASS_UBS 0x0d /* unaligned bit string */
/* These are the codes that are used to generate the definitions of struct
* union and enum records
*/
#define DBG_S_C_ENUM_ITEM 0xa4
#define DBG_S_C_ENUM_START 0xa5
#define DBG_S_C_ENUM_END 0xa6
#define DBG_S_C_STRUCT_ITEM DST_K_VFLAGS_BITOFFS /* 0xff */
#define DBG_S_C_STRUCT_START 0xab
#define DBG_S_C_STRUCT_END 0xac
#define DST_K_TYPSPEC 0xaf /* type specification */
/* These codes are used in the generation of the symbol definition records
*/
#define DST_K_VFLAGS_NOVAL 0x80 /* struct definition only */
#define DST_K_VFLAGS_DSC 0xfa /* descriptor used */
#define DST_K_VFLAGS_TVS 0xfb /* trailing value specified */
#define DST_K_VS_FOLLOWS 0xfd /* value spec follows */
#define DST_K_VFLAGS_BITOFFS 0xff /* value contains bit offset */
#define DST_K_VALKIND_LITERAL 0
#define DST_K_VALKIND_ADDR 1
#define DST_K_VALKIND_DESC 2
#define DST_K_VALKIND_REG 3
#define DST_K_REG_VAX_AP 0x0c /* R12 */
#define DST_K_REG_VAX_FP 0x0d /* R13 */
#define DST_K_REG_VAX_SP 0x0e /* R14 */
#define DST_V_VALKIND 0 /* offset of valkind field */
#define DST_V_INDIRECT 2 /* offset to indirect bit */
#define DST_V_DISP 3 /* offset to displacement bit */
#define DST_V_REGNUM 4 /* offset to register number */
#define DST_M_INDIRECT (1<<DST_V_INDIRECT)
#define DST_M_DISP (1<<DST_V_DISP)
#define DBG_C_FUNCTION_PARAM /* 0xc9 */ \
(DST_K_VALKIND_ADDR|DST_M_DISP|(DST_K_REG_VAX_AP<<DST_V_REGNUM))
#define DBG_C_LOCAL_SYM /* 0xd9 */ \
(DST_K_VALKIND_ADDR|DST_M_DISP|(DST_K_REG_VAX_FP<<DST_V_REGNUM))
/* Kinds of value specifications
*/
#define DST_K_VS_ALLOC_SPLIT 3 /* split lifetime */
/* Kinds of type specifications
*/
#define DST_K_TS_ATOM 0x01 /* atomic type specification */
#define DST_K_TS_DSC 0x02 /* descriptor type spec */
#define DST_K_TS_IND 0x03 /* indirect type specification */
#define DST_K_TS_TPTR 0x04 /* typed pointer type spec */
#define DST_K_TS_PTR 0x05 /* pointer type spec */
#define DST_K_TS_ARRAY 0x07 /* array type spec */
#define DST_K_TS_NOV_LENG 0x0e /* novel length type spec */
/* These are the codes that are used in the suffix records to determine the
* actual data type
*/
#define DBG_S_C_BASIC DST_K_TS_ATOM
#define DBG_S_C_BASIC_ARRAY DST_K_TS_DSC
#define DBG_S_C_STRUCT DST_K_TS_IND
#define DBG_S_C_POINTER DST_K_TS_TPTR
#define DBG_S_C_VOID DST_K_TS_PTR
#define DBG_S_C_COMPLEX_ARRAY DST_K_TS_ARRAY
/* VMS Module header record (EMH) definitions. */
#define MHD_S_C_MHD 0
#define MHD_S_C_LNM 1
#define MHD_S_C_SRC 2
#define MHD_S_C_TTL 3
#define MHD_S_C_CPR 4
#define MHD_S_C_MTC 5
#define MHD_S_C_GTX 6
#define MHD_S_C_MAXHDRTYP 6
#define EMH_S_C_MHD 0 /* Main header record */
#define EMH_S_C_LNM 1 /* Language name and version */
#define EMH_S_C_SRC 2 /* Source file specification */
#define EMH_S_C_TTL 3 /* Title text of module */
#define EMH_S_C_CPR 4 /* Copyright notice */
#define EMH_S_C_MTC 5 /* Maintenance status */
#define EMH_S_C_GTX 6 /* General text */
#define EMH_S_C_MAXHDRTYP 6 /* Maximum allowable type */
/* vms.c. */
extern asymbol *_bfd_vms_make_empty_symbol PARAMS ((bfd *abfd));
/* vms-gsd.c. */
extern int _bfd_vms_slurp_gsd PARAMS ((bfd *abfd, int objtype));
extern int _bfd_vms_write_gsd PARAMS ((bfd *abfd, int objtype));
/* vms-mhd.c. */
extern int _bfd_vms_slurp_hdr PARAMS ((bfd *abfd, int objtype));
extern int _bfd_vms_write_hdr PARAMS ((bfd *abfd, int objtype));
extern int _bfd_vms_slurp_eom PARAMS ((bfd *abfd, int objtype));
extern int _bfd_vms_write_eom PARAMS ((bfd *abfd, int objtype));
/* vms-tir.c. */
extern int _bfd_vms_slurp_tir PARAMS ((bfd *abfd, int objtype));
extern int _bfd_vms_slurp_dbg PARAMS ((bfd *abfd, int objtype));
extern int _bfd_vms_slurp_tbt PARAMS ((bfd *abfd, int objtype));
extern int _bfd_vms_slurp_lnk PARAMS ((bfd *abfd, int objtype));
extern int _bfd_vms_write_tir PARAMS ((bfd *abfd, int objtype));
extern int _bfd_vms_write_tbt PARAMS ((bfd *abfd, int objtype));
extern int _bfd_vms_write_dbg PARAMS ((bfd *abfd, int objtype));
/* The r_type field in a reloc is one of the following values. */
#define ALPHA_R_IGNORE 0
#define ALPHA_R_REFQUAD 1
#define ALPHA_R_BRADDR 2
#define ALPHA_R_HINT 3
#define ALPHA_R_SREL16 4
#define ALPHA_R_SREL32 5
#define ALPHA_R_SREL64 6
#define ALPHA_R_OP_PUSH 7
#define ALPHA_R_OP_STORE 8
#define ALPHA_R_OP_PSUB 9
#define ALPHA_R_OP_PRSHIFT 10
#define ALPHA_R_LINKAGE 11
#define ALPHA_R_REFLONG 12
#define ALPHA_R_CODEADDR 13
/* Object language definitions. */
#define OBJ_S_C_HDR 0 /*VAX module header record */
#define OBJ_S_C_GSD 1 /*VAX global symbol definition record */
#define OBJ_S_C_TIR 2 /*VAX text information record */
#define OBJ_S_C_EOM 3 /*VAX end of module record */
#define OBJ_S_C_DBG 4 /*VAX Debugger information record */
#define OBJ_S_C_TBT 5 /*VAX Traceback information record */
#define OBJ_S_C_LNK 6 /*VAX linker options record */
#define OBJ_S_C_EOMW 7 /*VAX end of module word-psect record */
#define OBJ_S_C_MAXRECTYP 7 /*VAX Last assigned record type */
#define EOBJ_S_C_EMH 8 /*EVAX module header record */
#define EOBJ_S_C_EEOM 9 /*EVAX end of module record */
#define EOBJ_S_C_EGSD 10 /*EVAX global symbol definition record */
#define EOBJ_S_C_ETIR 11 /*EVAX text information record */
#define EOBJ_S_C_EDBG 12 /*EVAX Debugger information record */
#define EOBJ_S_C_ETBT 13 /*EVAX Traceback information record */
#define EOBJ_S_C_MAXRECTYP 13 /*EVAX Last assigned record type */
#define OBJ_S_K_SUBTYP 1
#define OBJ_S_C_SUBTYP 1
#define EOBJ_S_K_SUBTYP 4
#define EOBJ_S_C_SUBTYP 4
#define OBJ_S_C_MAXRECSIZ 2048 /*Maximum legal record size */
#define EOBJ_S_C_MAXRECSIZ 8192 /*Maximum legal record size */
#define OBJ_S_C_STRLVL 0 /*Structure level */
#define EOBJ_S_C_STRLVL 2 /*Structure level */
#define OBJ_S_C_SYMSIZ 31 /*Maximum symbol length */
#define EOBJ_S_C_SYMSIZ 64 /*Maximum symbol length */
#define EOBJ_S_C_SECSIZ 31 /*Maximum section name length */
#define OBJ_S_C_STOREPLIM -1 /*Maximum repeat count on store commands */
#define EOBJ_S_C_STOREPLIM -1 /*Maximum repeat count on store commands */
#define OBJ_S_C_PSCALILIM 9 /*Maximum p-sect alignment */
#define EOBJ_S_C_PSCALILIM 16 /*Maximum p-sect alignment */
#define EVAX_OFFSET 256 /*type offset for EVAX codes in switch */
/* Miscellaneous definitions. */
#if __GNUC__
typedef unsigned long long uquad;
#else
typedef unsigned long uquad;
#endif
#define MAX_OUTREC_SIZE 4096
#define MIN_OUTREC_LUFT 64
typedef struct _vms_section {
unsigned char *contents;
bfd_vma offset;
bfd_size_type size;
struct _vms_section *next;
} vms_section;
extern boolean _bfd_save_vms_section
PARAMS ((bfd *abfd, asection *section, PTR data, file_ptr offset,
bfd_size_type count));
extern vms_section *_bfd_get_vms_section PARAMS ((bfd *abfd, int index));
typedef struct _vms_reloc {
struct _vms_reloc *next;
arelent *reloc;
asection *section;
} vms_reloc;
/* vms module header */
struct hdr_struc {
int hdr_b_strlvl;
long hdr_l_arch1;
long hdr_l_arch2;
long hdr_l_recsiz;
char *hdr_t_name;
char *hdr_t_version;
char *hdr_t_date;
char *hdr_c_lnm;
char *hdr_c_src;
char *hdr_c_ttl;
};
/* vms end of module */
struct eom_struc {
long eom_l_total_lps;
unsigned char eom_b_comcod;
boolean eom_has_transfer;
unsigned char eom_b_tfrflg;
long eom_l_psindx;
long eom_l_tfradr;
};
enum file_format_enum { FF_UNKNOWN, FF_FOREIGN, FF_NATIVE, FF_VAX };
typedef struct vms_symbol_struct {
struct bfd_hash_entry bfd_hash;
asymbol *symbol;
} vms_symbol_entry;
/* stack value for push/pop commands */
struct stack_struct {
uquad value;
int psect;
};
#define STACKSIZE 8192
/* location stack definitions for CTL_DFLOC, CTL_STLOC, and CTL_STKDL */
struct location_struct {
unsigned long value;
int psect;
};
#define LOCATION_SAVE_SIZE 32
#define VMS_SECTION_COUNT 1024
struct vms_private_data_struct {
int is_vax;
boolean fixup_done; /* Flag to indicate if all
section pointers and PRIV(sections)
are set up correctly */
unsigned char *vms_buf; /* buffer to record */
int buf_size; /* max size of buffer */
unsigned char *vms_rec; /* actual record ptr */
int rec_length; /* remaining record length */
int rec_size; /* actual record size */
int rec_type; /* actual record type */
enum file_format_enum file_format;
struct hdr_struc hdr_data; /* data from HDR/EMH record */
struct eom_struc eom_data; /* data from EOM/EEOM record */
int section_count; /* # of sections in following array */
asection **sections; /* array of GSD/EGSD sections */
int gsd_sym_count; /* # of GSD/EGSD symbols */
asymbol **symbols; /* vector of GSD/EGSD symbols */
struct proc_value *procedure;
struct stack_struct *stack;
int stackptr;
vms_section *vms_section_table[VMS_SECTION_COUNT];
struct bfd_hash_table *vms_symbol_table;
struct symbol_cache_entry **symcache;
int symnum;
struct location_struct *location_stack;
asection *image_section; /* section for image_ptr */
unsigned char *image_ptr; /* a pointer to section->contents */
unsigned char pdsc[8]; /* procedure descriptor */
/* Output routine storage */
unsigned char *output_buf; /* output data */
int push_level;
int pushed_size;
int length_pos;
int output_size;
int output_alignment;
/* linkage index counter
used by conditional store commands (ETIR_S_C_STC_) */
int vms_linkage_index;
/* see tc-alpha.c of gas for a description. */
int flag_hash_long_names; /* -+, hash instead of truncate */
int flag_show_after_trunc; /* -H, show hashing/truncation */
};
#define PRIV(name) ((struct vms_private_data_struct *)abfd->tdata.any)->name
#define SECTION_NAME_TEMPLATE "__SEC__%d"
#if VMS_DEBUG
extern void _bfd_vms_debug PARAMS((int level, char *format, ...));
extern void _bfd_hexdump
PARAMS ((int level, unsigned char *ptr, int size, int offset));
#define vms_debug _bfd_vms_debug
#endif
extern struct bfd_hash_entry *_bfd_vms_hash_newfunc
PARAMS ((struct bfd_hash_entry *entry, struct bfd_hash_table *table,
const char *string));
extern void _bfd_vms_get_header_values
PARAMS ((bfd *abfd, unsigned char *buf, int *type, int *length));
extern int _bfd_vms_get_record PARAMS ((bfd *abfd));
extern int _bfd_vms_next_record PARAMS ((bfd *abfd));
extern char *_bfd_vms_save_sized_string PARAMS ((unsigned char *str, int size));
extern char *_bfd_vms_save_counted_string PARAMS ((unsigned char *ptr));
extern void _bfd_vms_push PARAMS ((bfd *abfd, uquad val, int psect));
extern uquad _bfd_vms_pop PARAMS ((bfd *abfd, int *psect));
extern boolean _bfd_save_vms_section
PARAMS ((bfd *abfd, asection *section, PTR data, file_ptr offset,
bfd_size_type count));
extern void _bfd_vms_output_begin
PARAMS ((bfd *abfd, int rectype, int rechead));
extern void _bfd_vms_output_alignment PARAMS ((bfd *abfd, int alignto));
extern void _bfd_vms_output_push PARAMS ((bfd *abfd));
extern void _bfd_vms_output_pop PARAMS ((bfd *abfd));
extern void _bfd_vms_output_flush PARAMS ((bfd *abfd));
extern void _bfd_vms_output_end PARAMS ((bfd *abfd));
extern int _bfd_vms_output_check PARAMS ((bfd *abfd, int size));
extern void _bfd_vms_output_byte PARAMS ((bfd *abfd, unsigned int value));
extern void _bfd_vms_output_short PARAMS ((bfd *abfd, unsigned int value));
extern void _bfd_vms_output_long PARAMS ((bfd *abfd, unsigned long value));
extern void _bfd_vms_output_quad PARAMS ((bfd *abfd, uquad value));
extern void _bfd_vms_output_counted PARAMS ((bfd *abfd, char *value));
extern void _bfd_vms_output_dump PARAMS ((bfd *abfd, unsigned char *data,
int length));
extern void _bfd_vms_output_fill PARAMS ((bfd *abfd, int value, int length));
extern char *_bfd_vms_length_hash_symbol PARAMS ((bfd *abfd, const char *in, int maxlen));
extern vms_symbol_entry *_bfd_vms_enter_symbol PARAMS ((bfd *abfd, char *name));
#endif /* VMS_H */