daily update
[deliverable/binutils-gdb.git] / bfd / vms-alpha.c
index 1f6e97fde57729ca8fc964ce989d0782029826fd..53d0f153f925b3efd06db2b4fecdfc9f260694bb 100644 (file)
@@ -801,7 +801,7 @@ vms_get_remaining_object_record (bfd *abfd, int read_so_far)
   /* 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;
@@ -945,19 +945,19 @@ static const struct sec_flags_struct evax_section_flags[] =
       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,
@@ -972,12 +972,12 @@ static const struct sec_flags_struct evax_section_flags[] =
       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,
@@ -987,7 +987,7 @@ static const struct sec_flags_struct evax_section_flags[] =
       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,
@@ -1709,7 +1709,7 @@ _bfd_vms_slurp_etir (bfd *abfd, struct bfd_link_info *info)
 #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)
@@ -2901,7 +2901,11 @@ alpha_vms_create_eisd_for_section (bfd *abfd, asection *sec)
 
   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))
@@ -3748,7 +3752,7 @@ _bfd_vms_write_etir (bfd * abfd, int objtype ATTRIBUTE_UNUSED)
          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);
 
@@ -4706,7 +4710,7 @@ _bfd_vms_find_nearest_dst_line (bfd *abfd, asection *section,
   *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)
@@ -8017,8 +8021,11 @@ alpha_vms_add_fixup_lp (struct bfd_link_info *info, bfd *src, bfd *shlib)
   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)
 {
@@ -8031,8 +8038,11 @@ 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)
@@ -8048,6 +8058,7 @@ alpha_vms_add_fixup_qr (struct bfd_link_info *info, bfd *src,
   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
@@ -8055,6 +8066,7 @@ alpha_vms_add_fixup_lr (struct bfd_link_info *info ATTRIBUTE_UNUSED,
                         unsigned int shr ATTRIBUTE_UNUSED,
                         bfd_vma vec ATTRIBUTE_UNUSED)
 {
+  /* Not yet supported.  */
   abort ();
 }
 
@@ -8243,7 +8255,10 @@ alpha_vms_link_add_archive_symbols (bfd *abfd, struct bfd_link_info *info)
        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))
         {
@@ -8265,10 +8280,10 @@ alpha_vms_link_add_archive_symbols (bfd *abfd, struct bfd_link_info *info)
       /* 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;
@@ -8309,6 +8324,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;
@@ -8356,9 +8373,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)
@@ -8523,6 +8551,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;
 }
 
@@ -8612,6 +8667,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;
 
@@ -8714,7 +8777,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)
@@ -8732,6 +8796,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.  */
This page took 0.026477 seconds and 4 git commands to generate.