-/* evax-egsd.c -- BFD back-end for ALPHA EVAX (openVMS/AXP) files.
- Copyright 1996 Free Software Foundation Inc.
+/* evax-egsd.c -- BFD back-end for ALPHA EVAX (openVMS/Alpha) files.
+ Copyright 1996, 1997 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รคmpf (kkaempf@progis.de)
+ 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
#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 */
flagword flags_hassize; /* flags we set if the section has a size > 0 */
};
-/* just a dummy flag array since i don't understand it yet */
+/* These flags are deccrtl/vaxcrtl (openVMS 6.2) compatible */
static struct sec_flags_struct evax_section_flags[] = {
{ EVAX_ABS_NAME,
(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_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) },
(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_READONLY_NAME,
- (EGPS_S_V_PIC|EGPS_S_V_REL|EGPS_S_V_SHR|EGPS_S_V_RD),
+ { 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_SHR|EGPS_S_V_RD),
+ (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_LITERAL_NAME,
- (EGPS_S_V_PIC|EGPS_S_V_REL|EGPS_S_V_SHR|EGPS_S_V_RD),
+ { 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),
}
else /* symbol reference */
{
-#if EVAX_DEBUG
- evax_debug(3, "egsd sym ref #%d (%s, %04x=%s)\n", abfd->symcount, evax_rec+9, old_flags, flag2str(gsyflagdesc, old_flags));
-#endif
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);
}
char dummy_name[10];
char *sname;
flagword new_flags, old_flags;
- char uname[200];
char *nptr, *uptr;
#if EVAX_DEBUG
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);
- _bfd_evax_output_short (abfd,
- evax_esecflag_by_name (sname,
- section->_raw_size));
+ 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);
}
old_flags = symbol->flags;
- if (((old_flags & BSF_GLOBAL) == 0) /* not xdef */
+ 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 */
_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)
+ if (old_flags & (BSF_GLOBAL|BSF_WEAK))
{
new_flags |= EGSY_S_V_DEF;
if (!bfd_is_abs_section (symbol->section))
}
_bfd_evax_output_short (abfd, new_flags);
- if (old_flags & BSF_GLOBAL) /* symbol definition */
+ if (old_flags & (BSF_GLOBAL|BSF_WEAK)) /* symbol definition */
{
if (old_flags & BSF_FUNCTION)
{
_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, FIXME */
+ _bfd_evax_output_long (abfd, symbol->section->index);/* L_PSINDX */
}
}
- if (strlen ((char *)symbol->name) > 198)
- {
- (*_bfd_error_handler) ("Name '%s' too long\n", symbol->name);
- abort ();
- }
- nptr = (char *)symbol->name;
- uptr = uname;
- while (*nptr)
- {
- if (islower (*nptr))
- *uptr = toupper (*nptr);
- else
- *uptr = *nptr;
- uptr++;
- nptr++;
- }
- *uptr = 0;
- _bfd_evax_output_counted (abfd, uname);
+ _bfd_evax_output_counted (abfd, _bfd_evax_length_hash_symbol (abfd, symbol->name, EOBJ_S_C_SYMSIZ));
_bfd_evax_output_flush (abfd);