/* vms.c -- BFD back-end for EVAX (openVMS/Alpha) files.
- Copyright 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005,
- 2006, 2007, 2008, 2009, 2010 Free Software Foundation, Inc.
+ Copyright (C) 1996-2016 Free Software Foundation, Inc.
Initial version written by Klaus Kaempf (kkaempf@rmi.de)
Major rewrite by Adacore.
struct module *modules; /* list of all compilation units */
+ /* The DST section. */
asection *dst_section;
unsigned int dst_ptr_offsets_count; /* # of offsets in following array */
struct vms_internal_eisd_map *gbl_eisd_tail;
/* linkage index counter used by conditional store commands */
- 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 */
+ unsigned int vms_linkage_index;
};
#define PRIV2(abfd, name) \
((struct vms_section_data_struct *)sec->used_by_bfd)
/* To be called from the debugger. */
-struct vms_private_data_struct *bfd_vms_get_data (bfd *abfd);
+struct vms_private_data_struct *bfd_vms_get_data (bfd *);
-static int vms_get_remaining_object_record (bfd *abfd, int read_so_far);
+static int vms_get_remaining_object_record (bfd *, unsigned int);
static bfd_boolean _bfd_vms_slurp_object_records (bfd * abfd);
static void alpha_vms_add_fixup_lp (struct bfd_link_info *, bfd *, bfd *);
static void alpha_vms_add_fixup_ca (struct bfd_link_info *, bfd *, bfd *);
bfd_vma);
static void alpha_vms_add_fixup_lr (struct bfd_link_info *, unsigned int,
bfd_vma);
-static void alpha_vms_add_lw_reloc (struct bfd_link_info *info);
-static void alpha_vms_add_qw_reloc (struct bfd_link_info *info);
+static void alpha_vms_add_lw_reloc (struct bfd_link_info *);
+static void alpha_vms_add_qw_reloc (struct bfd_link_info *);
struct vector_type
{
{
struct bfd_link_hash_table root;
- /* Vector of shared libaries. */
+ /* Vector of shared libraries. */
struct vector_type shrlibs;
/* Fixup section. */
asection *section;
flagword bfd_flags;
+ /* PR 17512: file: 3d9e9fe9. */
+ if (offset >= PRIV (recrd.rec_size))
+ return FALSE;
eisd = (struct vms_eisd *)(PRIV (recrd.rec) + offset);
rec_size = bfd_getl32 (eisd->eisdsize);
-
if (rec_size == 0)
break;
Return the size of the record or 0 on failure. */
static int
-vms_get_remaining_object_record (bfd *abfd, int read_so_far)
+vms_get_remaining_object_record (bfd *abfd, unsigned int read_so_far)
{
unsigned int to_read;
/* Extract record size. */
PRIV (recrd.rec_size) = bfd_getl16 (PRIV (recrd.rec) + 2);
- if (PRIV (recrd.rec_size) <= 0)
+ if (PRIV (recrd.rec_size) == 0)
{
bfd_set_error (bfd_error_file_truncated);
return 0;
return 0;
PRIV (recrd.buf_size) = to_read;
}
+ /* PR 17512: file: 025-1974-0.004. */
+ else if (to_read <= read_so_far)
+ return 0;
/* Read the remaining record. */
to_read -= read_so_far;
{
unsigned char *ptr;
unsigned char *vms_rec;
+ unsigned char *end;
int subtype;
vms_rec = PRIV (recrd.rec);
+ /* PR 17512: file: 62736583. */
+ end = PRIV (recrd.buf) + PRIV (recrd.buf_size);
vms_debug2 ((2, "HDR/EMH\n"));
{
case EMH__C_MHD:
/* Module header. */
+ if (vms_rec + 21 >= end)
+ goto fail;
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);
+ if ((vms_rec + 20 + vms_rec[20] + 1) >= end)
+ goto fail;
PRIV (hdr_data).hdr_t_name = _bfd_vms_save_counted_string (vms_rec + 20);
ptr = vms_rec + 20 + vms_rec[20] + 1;
+ if ((ptr + *ptr + 1) >= end)
+ goto fail;
PRIV (hdr_data).hdr_t_version =_bfd_vms_save_counted_string (ptr);
ptr += *ptr + 1;
+ if (ptr + 17 >= end)
+ goto fail;
PRIV (hdr_data).hdr_t_date = _bfd_vms_save_sized_string (ptr, 17);
break;
case EMH__C_LNM:
+ if (vms_rec + PRIV (recrd.rec_size - 6) > end)
+ goto fail;
PRIV (hdr_data).hdr_c_lnm =
_bfd_vms_save_sized_string (vms_rec, PRIV (recrd.rec_size - 6));
break;
case EMH__C_SRC:
+ if (vms_rec + PRIV (recrd.rec_size - 6) > end)
+ goto fail;
PRIV (hdr_data).hdr_c_src =
_bfd_vms_save_sized_string (vms_rec, PRIV (recrd.rec_size - 6));
break;
case EMH__C_TTL:
+ if (vms_rec + PRIV (recrd.rec_size - 6) > end)
+ goto fail;
PRIV (hdr_data).hdr_c_ttl =
_bfd_vms_save_sized_string (vms_rec, PRIV (recrd.rec_size - 6));
break;
break;
default:
+ fail:
bfd_set_error (bfd_error_wrong_format);
return FALSE;
}
0 },
{ EVAX_CODE_NAME,
EGPS__V_PIC | EGPS__V_REL | EGPS__V_SHR | EGPS__V_EXE,
- SEC_CODE,
+ SEC_CODE | SEC_READONLY,
EGPS__V_PIC | EGPS__V_REL | EGPS__V_SHR | EGPS__V_EXE,
- SEC_CODE | SEC_HAS_CONTENTS | SEC_ALLOC | SEC_LOAD },
+ SEC_CODE | SEC_READONLY | SEC_HAS_CONTENTS | SEC_ALLOC | SEC_LOAD },
{ EVAX_LITERAL_NAME,
EGPS__V_PIC | EGPS__V_REL | EGPS__V_SHR | EGPS__V_RD | EGPS__V_NOMOD,
SEC_DATA | SEC_READONLY,
EGPS__V_PIC | EGPS__V_REL | EGPS__V_SHR | EGPS__V_RD,
- SEC_DATA | SEC_HAS_CONTENTS | SEC_ALLOC | SEC_READONLY | SEC_LOAD },
+ SEC_DATA | SEC_READONLY | SEC_HAS_CONTENTS | SEC_ALLOC | SEC_LOAD },
{ EVAX_LINK_NAME,
EGPS__V_REL | EGPS__V_RD,
SEC_DATA | SEC_READONLY,
EGPS__V_REL | EGPS__V_RD,
- SEC_DATA | SEC_HAS_CONTENTS | SEC_ALLOC | SEC_READONLY | SEC_LOAD },
+ SEC_DATA | SEC_READONLY | SEC_HAS_CONTENTS | SEC_ALLOC | SEC_LOAD },
{ EVAX_DATA_NAME,
EGPS__V_REL | EGPS__V_RD | EGPS__V_WRT | EGPS__V_NOMOD,
SEC_DATA,
EGPS__V_PIC | EGPS__V_REL | EGPS__V_RD,
SEC_DATA | SEC_READONLY,
EGPS__V_PIC | EGPS__V_REL | EGPS__V_RD,
- SEC_DATA | SEC_HAS_CONTENTS | SEC_ALLOC | SEC_READONLY | SEC_LOAD },
+ SEC_DATA | SEC_READONLY | SEC_HAS_CONTENTS | SEC_ALLOC | SEC_LOAD },
{ EVAX_READONLY_NAME,
EGPS__V_PIC | EGPS__V_REL | EGPS__V_SHR | EGPS__V_RD | EGPS__V_NOMOD,
SEC_DATA | SEC_READONLY,
EGPS__V_PIC | EGPS__V_REL | EGPS__V_SHR | EGPS__V_RD,
- SEC_DATA | SEC_HAS_CONTENTS | SEC_ALLOC | SEC_READONLY | SEC_LOAD },
+ SEC_DATA | SEC_READONLY | SEC_HAS_CONTENTS | SEC_ALLOC | SEC_LOAD },
{ EVAX_LOCAL_NAME,
EGPS__V_REL | EGPS__V_RD | EGPS__V_WRT,
SEC_DATA,
EGPS__V_PIC | EGPS__V_OVR,
SEC_DATA | SEC_READONLY,
EGPS__V_PIC | EGPS__V_OVR,
- SEC_DATA | SEC_HAS_CONTENTS | SEC_ALLOC | SEC_READONLY | SEC_LOAD },
+ SEC_DATA | SEC_READONLY | SEC_HAS_CONTENTS | SEC_ALLOC | SEC_LOAD },
{ NULL,
EGPS__V_REL | EGPS__V_RD | EGPS__V_WRT,
SEC_DATA,
EGPS__V_REL | EGPS__V_RD | EGPS__V_WRT,
- SEC_IN_MEMORY | SEC_DATA | SEC_HAS_CONTENTS | SEC_ALLOC | SEC_LOAD }
+ SEC_DATA | SEC_HAS_CONTENTS | SEC_ALLOC | SEC_LOAD }
};
/* Retrieve BFD section flags by name and size. */
/* Program section definition. */
{
struct vms_egps *egps = (struct vms_egps *)vms_rec;
- flagword new_flags, old_flags;
+ flagword new_flags, vms_flags;
asection *section;
- old_flags = bfd_getl16 (egps->flags);
+ vms_flags = bfd_getl16 (egps->flags);
- if ((old_flags & EGPS__V_REL) == 0)
+ if ((vms_flags & EGPS__V_REL) == 0)
{
- /* Use the global absolute section for all absolute sections. */
+ /* Use the global absolute section for all
+ absolute sections. */
section = bfd_abs_section_ptr;
}
else
section->size = bfd_getl32 (egps->alloc);
section->alignment_power = egps->align;
- vms_section_data (section)->flags = old_flags;
+ vms_section_data (section)->flags = vms_flags;
vms_section_data (section)->no_flags = 0;
new_flags = vms_secflag_by_name (evax_section_flags, name,
section->size > 0);
- if (!(old_flags & EGPS__V_NOMOD) && section->size > 0)
+ if (section->size > 0)
+ new_flags |= SEC_LOAD;
+ if (!(vms_flags & EGPS__V_NOMOD) && section->size > 0)
{
+ /* Set RELOC and HAS_CONTENTS if the section is not
+ demand-zero and not empty. */
new_flags |= SEC_HAS_CONTENTS;
- if (old_flags & EGPS__V_REL)
+ if (vms_flags & EGPS__V_REL)
new_flags |= SEC_RELOC;
}
+ if (vms_flags & EGPS__V_EXE)
+ {
+ /* Set CODE if section is executable. */
+ new_flags |= SEC_CODE;
+ new_flags &= ~SEC_DATA;
+ }
if (!bfd_set_section_flags (abfd, section, new_flags))
return FALSE;
#if VMS_DEBUG
_bfd_vms_debug (4, "etir: %s(%d)\n",
_bfd_vms_etir_name (cmd), cmd);
- _bfd_hexdump (8, ptr, cmd_length - 4, (long) ptr);
+ _bfd_hexdump (8, ptr, cmd_length - 4, 0);
#endif
switch (cmd)
static const struct bfd_target *
alpha_vms_object_p (bfd *abfd)
{
- PTR tdata_save = abfd->tdata.any;
+ void *tdata_save = abfd->tdata.any;
unsigned int test_len;
unsigned char *buf;
PRIV (recrd.rec) = buf;
if (bfd_bread (buf, test_len, abfd) != test_len)
- {
- bfd_set_error (bfd_error_file_truncated);
- goto error_ret;
- }
+ goto err_wrong_format;
/* Is it an image? */
if ((bfd_getl32 (buf) == EIHD__K_MAJORID)
if (buf == NULL)
{
PRIV (recrd.buf) = NULL;
- bfd_set_error (bfd_error_no_memory);
goto error_ret;
}
PRIV (recrd.buf) = buf;
while (remaining > 0)
{
if (bfd_bread (buf + read_so_far, to_read, abfd) != to_read)
- {
- bfd_set_error (bfd_error_file_truncated);
- goto err_wrong_format;
- }
+ goto err_wrong_format;
read_so_far += to_read;
remaining -= to_read;
/* Reset the record pointer. */
PRIV (recrd.rec) = buf;
+ /* PR 17512: file: 7d7c57c2. */
+ if (PRIV (recrd.rec_size) < sizeof (struct vms_eihd))
+ goto error_ret;
vms_debug2 ((2, "file type is image\n"));
if (_bfd_vms_slurp_eihd (abfd, &eisd_offset, &eihs_offset) != TRUE)
_bfd_vms_output_alignment (recwr, 2);
_bfd_vms_output_begin (recwr, EOBJ__C_EEOM);
- _bfd_vms_output_long (recwr, (unsigned long) (PRIV (vms_linkage_index) >> 1));
+ _bfd_vms_output_long (recwr, PRIV (vms_linkage_index + 1) >> 1);
_bfd_vms_output_byte (recwr, 0); /* Completion code. */
_bfd_vms_output_byte (recwr, 0); /* Fill byte. */
return TRUE;
}
-/* This hash routine borrowed from GNU-EMACS, and strengthened
- slightly. ERY. */
-
-static int
-hash_string (const char *ptr)
-{
- const unsigned char *p = (unsigned char *) ptr;
- const unsigned char *end = p + strlen (ptr);
- unsigned char c;
- int hash = 0;
-
- while (p != end)
- {
- c = *p++;
- hash = ((hash << 3) + (hash << 15) + (hash >> 28) + c);
- }
- return hash;
-}
-
-/* Generate a length-hashed VMS symbol name (limited to maxlen chars). */
-
-static char *
-_bfd_vms_length_hash_symbol (bfd *abfd, const char *in, int maxlen)
-{
- unsigned long result;
- int in_len;
- char *new_name;
- const char *old_name;
- int i;
- static char outbuf[EOBJ__C_SYMSIZ + 1];
- char *out = outbuf;
-
-#if VMS_DEBUG
- vms_debug (4, "_bfd_vms_length_hash_symbol \"%s\"\n", in);
-#endif
-
- if (maxlen > EOBJ__C_SYMSIZ)
- maxlen = EOBJ__C_SYMSIZ;
-
- /* Save this for later. */
- new_name = out;
-
- /* We may need to truncate the symbol, save the hash for later. */
- in_len = strlen (in);
-
- result = (in_len > maxlen) ? hash_string (in) : 0;
-
- old_name = in;
-
- /* Do the length checking. */
- if (in_len <= maxlen)
- i = in_len;
- else
- {
- if (PRIV (flag_hash_long_names))
- i = maxlen - 9;
- else
- i = maxlen;
- }
-
- strncpy (out, in, (size_t) i);
- in += i;
- out += i;
-
- if ((in_len > maxlen)
- && PRIV (flag_hash_long_names))
- sprintf (out, "_%08lx", result);
- else
- *out = 0;
-
-#if VMS_DEBUG
- vms_debug (4, "--> [%d]\"%s\"\n", (int)strlen (outbuf), outbuf);
-#endif
-
- if (in_len > maxlen
- && PRIV (flag_hash_long_names)
- && PRIV (flag_show_after_trunc))
- printf (_("Symbol %s replaced by %s\n"), old_name, new_name);
-
- return outbuf;
-}
-
static void
vector_grow1 (struct vector_type *vec, size_t elsz)
{
if (sec->flags & SEC_CODE)
eisd->u.eisd.flags |= EISD__M_EXE;
- else if (!(sec->flags & SEC_READONLY))
+ if (!(sec->flags & SEC_READONLY))
eisd->u.eisd.flags |= EISD__M_WRT | EISD__M_CRF;
/* If relocations or fixup will be applied, make this isect writeable. */
if (sec->flags & SEC_RELOC)
eisd->u.eisd.flags |= EISD__M_WRT | EISD__M_CRF;
- if (!(sec->flags & SEC_LOAD))
+ if (!(sec->flags & SEC_HAS_CONTENTS))
{
eisd->u.eisd.flags |= EISD__M_DZRO;
eisd->u.eisd.flags &= ~EISD__M_CRF;
for (i = 0; i < PRIV (gsd_sym_count); i++)
{
struct vms_symbol_entry *sym = PRIV (syms)[i];
- char *hash;
bfd_vma val;
bfd_vma ep;
_bfd_vms_output_quad (recwr, ep);
_bfd_vms_output_quad (recwr, val);
_bfd_vms_output_long (recwr, 0);
- hash = _bfd_vms_length_hash_symbol (abfd, sym->name, EOBJ__C_SYMSIZ);
- _bfd_vms_output_counted (recwr, hash);
+ _bfd_vms_output_counted (recwr, sym->name);
_bfd_vms_output_end_subrec (recwr);
if ((i % 5) == 4)
_bfd_vms_output_end (abfd, recwr);
else if ((*sname == 'l') && (strcmp (sname, "lcomm") == 0))
sname = EVAX_LOCAL_NAME;
}
- else
- sname = _bfd_vms_length_hash_symbol (abfd, sname, EOBJ__C_SECSIZ);
if (bfd_is_com_section (section))
new_flags = (EGPS__V_OVR | EGPS__V_REL | EGPS__V_GBL | EGPS__V_RD
for (symnum = 0; symnum < abfd->symcount; symnum++)
{
- char *hash;
-
symbol = abfd->outsymbols[symnum];
old_flags = symbol->flags;
/* Work-around a missing feature: consider __main as the main entry
point. */
- if (*(symbol->name) == '_')
- {
- if (strcmp (symbol->name, "__main") == 0)
- bfd_set_start_address (abfd, (bfd_vma)symbol->value);
- }
+ if (symbol->name[0] == '_' && strcmp (symbol->name, "__main") == 0)
+ bfd_set_start_address (abfd, (bfd_vma)symbol->value);
/* Only put in the GSD the global and the undefined symbols. */
if (old_flags & BSF_FILE)
_bfd_vms_output_long (recwr, ca_psindx);
_bfd_vms_output_long (recwr, psindx);
}
- hash = _bfd_vms_length_hash_symbol (abfd, symbol->name, EOBJ__C_SYMSIZ);
- _bfd_vms_output_counted (recwr, hash);
+ _bfd_vms_output_counted (recwr, symbol->name);
_bfd_vms_output_end_subrec (recwr);
}
{
asymbol *symbol;
unsigned int symnum;
- int had_case = 0;
- int had_file = 0;
struct vms_rec_wr *recwr = &PRIV (recwr);
vms_debug2 ((2, "vms_write_ehdr (%p)\n", abfd));
if (symbol->flags & BSF_FILE)
{
- if (CONST_STRNEQ ((char *)symbol->name, "<CASE:"))
- {
- 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 (recwr, (unsigned char *) symbol->name,
(int) strlen (symbol->name));
- if (had_case)
- break;
- had_file = 1;
+ break;
}
}
_bfd_vms_output_alignment (recwr, 4);
- PRIV (vms_linkage_index) = 1;
+ PRIV (vms_linkage_index) = 0;
for (section = abfd->sections; section; section = section->next)
{
int pass2_in_progress = 0;
unsigned int irel;
- if (section->reloc_count <= 0)
+ if (section->reloc_count == 0)
(*_bfd_error_handler)
(_("SEC_RELOC with no relocs in section %s"), section->name);
asection *sec = sym->section;
bfd_boolean defer = defer_reloc_p (rptr);
unsigned int slen;
- char *hash;
if (pass2_in_progress)
{
{
bfd_vma addend = rptr->addend;
slen = strlen ((char *) sym->name);
- hash = _bfd_vms_length_hash_symbol
- (abfd, sym->name, EOBJ__C_SYMSIZ);
etir_output_check (abfd, section, curr_addr, slen);
if (addend)
{
_bfd_vms_output_begin_subrec (recwr, ETIR__C_STA_GBL);
- _bfd_vms_output_counted (recwr, hash);
+ _bfd_vms_output_counted (recwr, sym->name);
_bfd_vms_output_end_subrec (recwr);
_bfd_vms_output_begin_subrec (recwr, ETIR__C_STA_LW);
_bfd_vms_output_long (recwr, (unsigned long) addend);
{
_bfd_vms_output_begin_subrec
(recwr, ETIR__C_STO_GBL_LW);
- _bfd_vms_output_counted (recwr, hash);
+ _bfd_vms_output_counted (recwr, sym->name);
_bfd_vms_output_end_subrec (recwr);
}
}
{
bfd_vma addend = rptr->addend;
slen = strlen ((char *) sym->name);
- hash = _bfd_vms_length_hash_symbol
- (abfd, sym->name, EOBJ__C_SYMSIZ);
etir_output_check (abfd, section, curr_addr, slen);
if (addend)
{
_bfd_vms_output_begin_subrec (recwr, ETIR__C_STA_GBL);
- _bfd_vms_output_counted (recwr, hash);
+ _bfd_vms_output_counted (recwr, sym->name);
_bfd_vms_output_end_subrec (recwr);
_bfd_vms_output_begin_subrec (recwr, ETIR__C_STA_QW);
_bfd_vms_output_quad (recwr, addend);
else
{
_bfd_vms_output_begin_subrec (recwr, ETIR__C_STO_GBL);
- _bfd_vms_output_counted (recwr, hash);
+ _bfd_vms_output_counted (recwr, sym->name);
_bfd_vms_output_end_subrec (recwr);
}
}
etir_output_check (abfd, section, curr_addr, 64);
_bfd_vms_output_begin_subrec (recwr, ETIR__C_STC_LP_PSB);
_bfd_vms_output_long
- (recwr, (unsigned long) PRIV (vms_linkage_index));
- PRIV (vms_linkage_index) += 2;
- hash = _bfd_vms_length_hash_symbol
- (abfd, sym->name, EOBJ__C_SYMSIZ);
- _bfd_vms_output_counted (recwr, hash);
+ (recwr, (unsigned long) rptr->addend);
+ if (rptr->addend > PRIV (vms_linkage_index))
+ PRIV (vms_linkage_index) = rptr->addend;
+ _bfd_vms_output_counted (recwr, sym->name);
_bfd_vms_output_byte (recwr, 0);
_bfd_vms_output_end_subrec (recwr);
break;
case ALPHA_R_CODEADDR:
slen = strlen ((char *) sym->name);
- hash = _bfd_vms_length_hash_symbol
- (abfd, sym->name, EOBJ__C_SYMSIZ);
etir_output_check (abfd, section, curr_addr, slen);
_bfd_vms_output_begin_subrec (recwr, ETIR__C_STO_CA);
- _bfd_vms_output_counted (recwr, hash);
+ _bfd_vms_output_counted (recwr, sym->name);
_bfd_vms_output_end_subrec (recwr);
break;
_bfd_vms_output_begin_subrec (recwr, ETIR__C_STC_NOP_GBL);
_bfd_vms_output_long (recwr, (unsigned long) udata->lkindex);
_bfd_vms_output_long
- (recwr,
- (unsigned long) udata->enbsym->section->target_index);
+ (recwr, (unsigned long) section->target_index);
_bfd_vms_output_quad (recwr, rptr->address);
_bfd_vms_output_long (recwr, (unsigned long) 0x47ff041f);
_bfd_vms_output_long
- (recwr,
- (unsigned long) udata->enbsym->section->target_index);
+ (recwr, (unsigned long) section->target_index);
_bfd_vms_output_quad (recwr, rptr->addend);
- _bfd_vms_output_counted
- (recwr, _bfd_vms_length_hash_symbol
- (abfd, udata->origname, EOBJ__C_SYMSIZ));
+ _bfd_vms_output_counted (recwr, udata->origname);
_bfd_vms_output_end_subrec (recwr);
break;
_bfd_vms_output_long
(recwr, (unsigned long) udata->lkindex + 1);
_bfd_vms_output_long
- (recwr,
- (unsigned long) udata->enbsym->section->target_index);
+ (recwr, (unsigned long) section->target_index);
_bfd_vms_output_quad (recwr, rptr->address);
_bfd_vms_output_long (recwr, (unsigned long) 0x237B0000);
_bfd_vms_output_long
(recwr, (unsigned long) udata->bsym->section->target_index);
_bfd_vms_output_quad (recwr, rptr->addend);
- _bfd_vms_output_counted
- (recwr, _bfd_vms_length_hash_symbol
- (abfd, udata->origname, EOBJ__C_SYMSIZ));
+ _bfd_vms_output_counted (recwr, udata->origname);
_bfd_vms_output_end_subrec (recwr);
break;
_bfd_vms_output_begin_subrec (recwr, ETIR__C_STC_BOH_GBL);
_bfd_vms_output_long (recwr, (unsigned long) udata->lkindex);
_bfd_vms_output_long
- (recwr,
- (unsigned long) udata->enbsym->section->target_index);
+ (recwr, (unsigned long) section->target_index);
_bfd_vms_output_quad (recwr, rptr->address);
_bfd_vms_output_long (recwr, (unsigned long) 0xD3400000);
_bfd_vms_output_long
- (recwr,
- (unsigned long) udata->enbsym->section->target_index);
+ (recwr, (unsigned long) section->target_index);
_bfd_vms_output_quad (recwr, rptr->addend);
- _bfd_vms_output_counted
- (recwr, _bfd_vms_length_hash_symbol
- (abfd, udata->origname, EOBJ__C_SYMSIZ));
+ _bfd_vms_output_counted (recwr, udata->origname);
_bfd_vms_output_end_subrec (recwr);
break;
/* We don't have a DMT section so this must be an object. Parse
the module right now in order to compute its start address and
end address. */
+ void *dst = PRIV (dst_section)->contents;
+
+ if (dst == NULL)
+ return NULL;
+
module = new_module (abfd);
parse_module (abfd, module, PRIV (dst_section)->contents, -1);
list = module;
location. */
static bfd_boolean
-_bfd_vms_find_nearest_dst_line (bfd *abfd, asection *section,
- asymbol **symbols ATTRIBUTE_UNUSED,
- bfd_vma offset, const char **file,
- const char **func, unsigned int *line)
+_bfd_vms_find_nearest_line (bfd *abfd,
+ asymbol **symbols ATTRIBUTE_UNUSED,
+ asection *section,
+ bfd_vma offset,
+ const char **file,
+ const char **func,
+ unsigned int *line,
+ unsigned int *discriminator)
{
struct module *module;
*file = NULL;
*func = NULL;
*line = 0;
+ if (discriminator)
+ *discriminator = 0;
- if (PRIV (dst_section) == NULL || !(abfd->flags & (EXEC_P | DYNAMIC)))
+ /* We can't do anything if there is no DST (debug symbol table). */
+ if (PRIV (dst_section) == NULL)
return FALSE;
+ /* Create the module list - if not already done. */
if (PRIV (modules) == NULL)
{
PRIV (modules) = build_module_list (abfd);
(*_bfd_error_handler) (_("Invalid section index in ETIR"));
return FALSE;
}
+
sec = PRIV (sections)[cur_psect];
+ if (sec == bfd_abs_section_ptr)
+ {
+ (*_bfd_error_handler) (_("Relocation for non-REL psect"));
+ return FALSE;
+ }
+
vms_sec = vms_section_data (sec);
/* Allocate a reloc entry. */
vms_sec->reloc_max = 64;
sec->relocation = bfd_zmalloc
(vms_sec->reloc_max * sizeof (arelent));
- }
+ }
else
{
vms_sec->reloc_max *= 2;
unsigned char *rec, unsigned int rec_len)
{
unsigned int off = sizeof (struct vms_egsd);
- unsigned int sec_len;
+ unsigned int sec_len = 0;
fprintf (file, _(" %s (len=%u+%u):\n"), name,
(unsigned)(rec_len - sizeof (struct vms_eobjrec)),
}
if (lpfixoff != 0)
{
- fprintf (file, _(" Linkage Pairs Referece Fixups:\n"));
+ fprintf (file, _(" Linkage Pairs Reference Fixups:\n"));
evax_bfd_print_reference_fixups (file, buf + lpfixoff);
}
if (chgprtoff)
return FALSE;
if (element->archive_pass == -1 || element->archive_pass == pass)
- continue;
+ {
+ /* Next symbol if this archive is wrong or already handled. */
+ continue;
+ }
if (! bfd_check_format (element, bfd_object))
{
/* Unlike the generic linker, we know that this element provides
a definition for an undefined symbol and we know that we want
to include it. We don't need to check anything. */
- if (! (*info->callbacks->add_archive_element) (info, element,
- h->root.string))
+ if (!(*info->callbacks
+ ->add_archive_element) (info, element, h->root.string, &element))
return FALSE;
- if (! alpha_vms_link_add_object_symbols (element, info))
+ if (!alpha_vms_link_add_object_symbols (element, info))
return FALSE;
orig_element->archive_pass = pass;
unsigned int ca_sz = 0;
unsigned int qr_sz = 0;
unsigned int shrimg_cnt = 0;
+ unsigned int chgprt_num = 0;
+ unsigned int chgprt_sz = 0;
struct vms_eiaf *eiaf;
unsigned int off;
asection *sec;
if (ca_sz + lp_sz + qr_sz == 0)
return TRUE;
+ /* Add an eicp entry for the fixup itself. */
+ chgprt_num = 1;
+ for (sec = info->output_bfd->sections; sec != NULL; sec = sec->next)
+ {
+ /* This isect could be made RO or EXE after relocations are applied. */
+ if ((sec->flags & SEC_RELOC) != 0
+ && (sec->flags & (SEC_CODE | SEC_READONLY)) != 0)
+ chgprt_num++;
+ }
+ chgprt_sz = 4 + chgprt_num * sizeof (struct vms_eicp);
+
/* Allocate section content (round-up size) */
sz = sizeof (struct vms_eiaf) + shrimg_cnt * sizeof (struct vms_shl)
- + ca_sz + lp_sz + qr_sz;
+ + ca_sz + lp_sz + qr_sz + chgprt_sz;
sz = (sz + VMS_BLOCK_SIZE - 1) & ~(VMS_BLOCK_SIZE - 1);
content = bfd_zalloc (info->output_bfd, sz);
if (content == NULL)
}
}
+ /* Write the change protection table. */
+ bfd_putl32 (off, eiaf->chgprtoff);
+ bfd_putl32 (chgprt_num, content + off);
+ off += 4;
+
+ for (sec = info->output_bfd->sections; sec != NULL; sec = sec->next)
+ {
+ struct vms_eicp *eicp;
+ unsigned int prot;
+
+ if ((sec->flags & SEC_LINKER_CREATED) != 0 &&
+ strcmp (sec->name, "$FIXUP$") == 0)
+ prot = PRT__C_UREW;
+ else if ((sec->flags & SEC_RELOC) != 0
+ && (sec->flags & (SEC_CODE | SEC_READONLY)) != 0)
+ prot = PRT__C_UR;
+ else
+ continue;
+
+ eicp = (struct vms_eicp *)(content + off);
+ bfd_putl64 (sec->vma - t->base_addr, eicp->baseva);
+ bfd_putl32 ((sec->size + VMS_BLOCK_SIZE - 1) & ~(VMS_BLOCK_SIZE - 1),
+ eicp->size);
+ bfd_putl32 (prot, eicp->newprt);
+ off += sizeof (struct vms_eicp);
+ }
+
return TRUE;
}
-/* Called by bfd_link_hash_traverse to fill the symbol table.
+/* Called by bfd_hash_traverse to fill the symbol table.
Return FALSE in case of failure. */
static bfd_boolean
-alpha_vms_link_output_symbol (struct bfd_link_hash_entry *hc, void *infov)
+alpha_vms_link_output_symbol (struct bfd_hash_entry *bh, void *infov)
{
+ struct bfd_link_hash_entry *hc = (struct bfd_link_hash_entry *) bh;
struct bfd_link_info *info = (struct bfd_link_info *)infov;
- struct alpha_vms_link_hash_entry *h = (struct alpha_vms_link_hash_entry *)hc;
+ struct alpha_vms_link_hash_entry *h;
struct vms_symbol_entry *sym;
+ if (hc->type == bfd_link_hash_warning)
+ {
+ hc = hc->u.i.link;
+ if (hc->type == bfd_link_hash_new)
+ return TRUE;
+ }
+ h = (struct alpha_vms_link_hash_entry *) hc;
+
switch (h->root.type)
{
- case bfd_link_hash_new:
case bfd_link_hash_undefined:
+ return TRUE;
+ case bfd_link_hash_new:
+ case bfd_link_hash_warning:
abort ();
case bfd_link_hash_undefweak:
return TRUE;
case bfd_link_hash_common:
break;
case bfd_link_hash_indirect:
- case bfd_link_hash_warning:
return TRUE;
}
asection *dst;
asection *dmt;
+ if (bfd_link_relocatable (info))
+ {
+ /* FIXME: we do not yet support relocatable link. It is not obvious
+ how to do it for debug infos. */
+ (*info->callbacks->einfo)(_("%P: relocatable link is not supported\n"));
+ return FALSE;
+ }
+
bfd_get_outsymbols (abfd) = NULL;
bfd_get_symcount (abfd) = 0;
/* Generate the symbol table. */
BFD_ASSERT (PRIV (syms) == NULL);
if (info->strip != strip_all)
- bfd_link_hash_traverse (info->hash, alpha_vms_link_output_symbol, info);
+ bfd_hash_traverse (&info->hash->table, alpha_vms_link_output_symbol, info);
/* Find the entry point. */
if (bfd_get_start_address (abfd) == 0)
{
bfd *startbfd = NULL;
- for (sub = info->input_bfds; sub != NULL; sub = sub->link_next)
+ for (sub = info->input_bfds; sub != NULL; sub = sub->link.next)
{
/* Consider only VMS object files. */
if (sub->xvec != abfd->xvec)
PRIV (transfer_address[i++]) = 0;
}
- /* Allocate contents. */
+ /* Allocate contents.
+ Also compute the virtual base address. */
base_addr = (bfd_vma)-1;
last_addr = 0;
for (o = abfd->sections; o != NULL; o = o->next)
if (o->vma + o->size > last_addr)
last_addr = o->vma + o->size;
}
+ /* Clear the RELOC flags. Currently we don't support incremental
+ linking. We use the RELOC flag for computing the eicp entries. */
+ o->flags &= ~SEC_RELOC;
}
/* Create the fixup section. */
dmt = NULL;
/* Read all sections from the inputs. */
- for (sub = info->input_bfds; sub != NULL; sub = sub->link_next)
+ for (sub = info->input_bfds; sub != NULL; sub = sub->link.next)
{
if (sub->flags & DYNAMIC)
{
unsigned int off = 0;
/* For each object file (ie for each module). */
- for (sub = info->input_bfds; sub != NULL; sub = sub->link_next)
+ for (sub = info->input_bfds; sub != NULL; sub = sub->link.next)
{
asection *sub_dst;
struct vms_dmt_header *dmth = NULL;
return FALSE;
}
- /* Alloc in memory and read ETIRs. */
- BFD_ASSERT (section->contents == NULL);
+ /* If the section is already in memory, just copy it. */
+ if (section->flags & SEC_IN_MEMORY)
+ {
+ BFD_ASSERT (section->contents != NULL);
+ memcpy (buf, section->contents + offset, count);
+ return TRUE;
+ }
+ if (section->size == 0)
+ return TRUE;
+ /* Alloc in memory and read ETIRs. */
for (sec = abfd->sections; sec; sec = sec->next)
{
BFD_ASSERT (sec->contents == NULL);
if (!alpha_vms_read_sections_content (abfd, NULL))
return FALSE;
for (sec = abfd->sections; sec; sec = sec->next)
- if (section->contents)
- section->flags |= SEC_IN_MEMORY;
+ if (sec->contents)
+ sec->flags |= SEC_IN_MEMORY;
memcpy (buf, section->contents + offset, count);
return TRUE;
}
{
bfd_size_type amt;
- vms_debug2 ((1, "vms_new_section_hook (%p, [%d]%s)\n",
+ vms_debug2 ((1, "vms_new_section_hook (%p, [%u]%s)\n",
abfd, section->index, section->name));
- bfd_set_section_alignment (abfd, section, 0);
+ if (! bfd_set_section_alignment (abfd, section, 0))
+ return FALSE;
- vms_debug2 ((7, "%d: %s\n", section->index, section->name));
+ vms_debug2 ((7, "%u: %s\n", section->index, section->name));
amt = sizeof (struct vms_section_data_struct);
- section->used_by_bfd = (PTR) bfd_zalloc (abfd, amt);
+ section->used_by_bfd = bfd_zalloc (abfd, amt);
if (section->used_by_bfd == NULL)
return FALSE;
vms_bfd_is_local_label_name (bfd * abfd ATTRIBUTE_UNUSED,
const char *name)
{
- vms_debug2 ((1, "vms_bfd_is_local_label_name (%p, %s)\n", abfd, name));
return name[0] == '$';
}
\f
((bfd_boolean (*) (bfd *, asymbol *)) bfd_false)
#define alpha_vms_print_symbol vms_print_symbol
#define alpha_vms_get_symbol_info vms_get_symbol_info
+#define alpha_vms_get_symbol_version_string \
+ _bfd_nosymbols_get_symbol_version_string
+
#define alpha_vms_read_minisymbols _bfd_generic_read_minisymbols
#define alpha_vms_minisymbol_to_symbol _bfd_generic_minisymbol_to_symbol
#define alpha_vms_get_lineno _bfd_nosymbols_get_lineno
#define alpha_vms_find_inliner_info _bfd_nosymbols_find_inliner_info
#define alpha_vms_bfd_make_debug_symbol _bfd_nosymbols_bfd_make_debug_symbol
-#define alpha_vms_find_nearest_line _bfd_vms_find_nearest_dst_line
+#define alpha_vms_find_nearest_line _bfd_vms_find_nearest_line
+#define alpha_vms_find_line _bfd_nosymbols_find_line
#define alpha_vms_bfd_is_local_label_name vms_bfd_is_local_label_name
/* Generic table. */
#define alpha_vms_bfd_relax_section bfd_generic_relax_section
#define alpha_vms_bfd_gc_sections bfd_generic_gc_sections
+#define alpha_vms_bfd_lookup_section_flags bfd_generic_lookup_section_flags
#define alpha_vms_bfd_merge_sections bfd_generic_merge_sections
#define alpha_vms_bfd_is_group_section bfd_generic_is_group_section
#define alpha_vms_bfd_discard_group bfd_generic_discard_group
_bfd_generic_section_already_linked
#define alpha_vms_bfd_define_common_symbol bfd_generic_define_common_symbol
-#define alpha_vms_bfd_link_hash_table_free _bfd_generic_link_hash_table_free
#define alpha_vms_bfd_link_just_syms _bfd_generic_link_just_syms
#define alpha_vms_bfd_copy_link_hash_symbol_type \
_bfd_generic_copy_link_hash_symbol_type
_bfd_nodynamic_get_dynamic_reloc_upper_bound
#define alpha_vms_canonicalize_dynamic_reloc \
_bfd_nodynamic_canonicalize_dynamic_reloc
+#define alpha_vms_bfd_link_check_relocs _bfd_generic_link_check_relocs
-const bfd_target vms_alpha_vec =
+const bfd_target alpha_vms_vec =
{
"vms-alpha", /* Name. */
bfd_target_evax_flavour,
0, /* symbol_leading_char. */
' ', /* ar_pad_char. */
15, /* ar_max_namelen. */
+ 0, /* match priority. */
bfd_getl64, bfd_getl_signed_64, bfd_putl64,
bfd_getl32, bfd_getl_signed_32, bfd_putl32,
bfd_getl16, bfd_getl_signed_16, bfd_putl16,
NULL,
- (PTR) 0
+ NULL
};