diff options
author | Tristan Gingold <gingold@adacore.com> | 2010-08-04 10:45:51 +0000 |
---|---|---|
committer | Tristan Gingold <gingold@adacore.com> | 2010-08-04 10:45:51 +0000 |
commit | 66d42fd91efea700e952accace19abd4ff5a1225 (patch) | |
tree | b7b9dc1a9775518b756dcd2eb198a33e6e94d410 /bfd | |
parent | fa5ab3ce1186d861c72a99f9c1e65c8454b88ae3 (diff) | |
download | binutils-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')
-rw-r--r-- | bfd/ChangeLog | 4 | ||||
-rw-r--r-- | bfd/vms-alpha.c | 56 |
2 files changed, 58 insertions, 2 deletions
diff --git a/bfd/ChangeLog b/bfd/ChangeLog index 06b8335d6b..61eb5bc5d4 100644 --- a/bfd/ChangeLog +++ b/bfd/ChangeLog @@ -1,5 +1,9 @@ 2010-08-04 Tristan Gingold <gingold@adacore.com> + * vms-alpha.c (alpha_vms_build_fixups): Write the EICP. + +2010-08-04 Tristan Gingold <gingold@adacore.com> + * vms-alpha.c (alpha_vms_create_eisd_for_section): Make writable sections with relocs. (alpha_vms_add_fixup_lp): Set SEC_RELOC flag. 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. */ |