summaryrefslogtreecommitdiff
path: root/bfd/vms-alpha.c
diff options
context:
space:
mode:
authorTristan Gingold <gingold@adacore.com>2010-08-04 10:45:51 +0000
committerTristan Gingold <gingold@adacore.com>2010-08-04 10:45:51 +0000
commit66d42fd91efea700e952accace19abd4ff5a1225 (patch)
treeb7b9dc1a9775518b756dcd2eb198a33e6e94d410 /bfd/vms-alpha.c
parentfa5ab3ce1186d861c72a99f9c1e65c8454b88ae3 (diff)
downloadbinutils-redhat-66d42fd91efea700e952accace19abd4ff5a1225.tar.gz
2010-08-04 Tristan Gingold <gingold@adacore.com>
* vms-alpha.c (alpha_vms_build_fixups): Write the EICP. (alpha_vms_bfd_final_link): Explicitly forbid relocatable links. Clear the SEC_RELOC flag.
Diffstat (limited to 'bfd/vms-alpha.c')
-rw-r--r--bfd/vms-alpha.c56
1 files changed, 54 insertions, 2 deletions
diff --git a/bfd/vms-alpha.c b/bfd/vms-alpha.c
index e500cd4d00..5d38d1df2c 100644
--- a/bfd/vms-alpha.c
+++ b/bfd/vms-alpha.c
@@ -8321,6 +8321,8 @@ alpha_vms_build_fixups (struct bfd_link_info *info)
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;
@@ -8368,9 +8370,20 @@ alpha_vms_build_fixups (struct bfd_link_info *info)
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)
@@ -8535,6 +8548,33 @@ alpha_vms_build_fixups (struct bfd_link_info *info)
}
}
+ /* 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;
}
@@ -8624,6 +8664,14 @@ alpha_vms_bfd_final_link (bfd *abfd, struct bfd_link_info *info)
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;
@@ -8726,7 +8774,8 @@ alpha_vms_bfd_final_link (bfd *abfd, struct bfd_link_info *info)
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)
@@ -8744,6 +8793,9 @@ alpha_vms_bfd_final_link (bfd *abfd, struct bfd_link_info *info)
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. */