/* 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;
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,
#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)
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))
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);
*func = NULL;
*line = 0;
- if (PRIV (dst_section) == NULL || !(abfd->flags & (EXEC_P | DYNAMIC)))
+ if (PRIV (dst_section) == NULL)
return FALSE;
if (PRIV (modules) == NULL)
sl->has_fixups = TRUE;
VEC_APPEND_EL (sl->lp, bfd_vma,
sect->output_section->vma + sect->output_offset + offset);
+ sect->output_section->flags |= SEC_RELOC;
}
+/* Add a code address fixup at address SECT + OFFSET to SHLIB. */
+
static void
alpha_vms_add_fixup_ca (struct bfd_link_info *info, bfd *src, bfd *shlib)
{
sl->has_fixups = TRUE;
VEC_APPEND_EL (sl->ca, bfd_vma,
sect->output_section->vma + sect->output_offset + offset);
+ sect->output_section->flags |= SEC_RELOC;
}
+/* Add a quad word relocation fixup at address SECT + OFFSET to SHLIB. */
+
static void
alpha_vms_add_fixup_qr (struct bfd_link_info *info, bfd *src,
bfd *shlib, bfd_vma vec)
r = VEC_APPEND (sl->qr, struct alpha_vms_vma_ref);
r->vma = sect->output_section->vma + sect->output_offset + offset;
r->ref = vec;
+ sect->output_section->flags |= SEC_RELOC;
}
static void
unsigned int shr ATTRIBUTE_UNUSED,
bfd_vma vec ATTRIBUTE_UNUSED)
{
+ /* Not yet supported. */
abort ();
}
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;
}
asection *dst;
asection *dmt;
+ if (info->relocatable)
+ {
+ /* 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;
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. */