[vms/committed]: fix multiple section load (and misc)

Tristan Gingold gingold@adacore.com
Fri May 6 10:41:00 GMT 2011


Hi,

in alpha-vms.c, there was an assertion failure if several sections are loaded via get_section_contents.
Looks to be a large hole, but in fact this code is not used by ld, so it appears mainly in objdump.
This patch fixes this issue.

Also, comments were added, PTR removed for void *, and the conversion of flags between VMS and BFD
improved.

Committed on trunk.

Tristan.

bfd/
2011-05-06  Tristan Gingold  <gingold@adacore.com>

	* vms-alpha.c (evax_section_flags): Remove SEC_IN_MEMORY.
	(_bfd_vms_slurp_egsd): Rename old_flags to vms_flags.  Handle
	any code section.  Add comments.
	(alpha_vms_object_p): Use void * instead of PTR.
	(alpha_vms_create_eisd_for_section): Fix test for setting DZRO.
	(build_module_list): Guard against no DST section.  Add comments.
	(alpha_vms_link_output_symbol): Discard undefined symbols.
	(alpha_vms_get_section_contents): Simply memcpy if the section was
	already loaded.  Fix typo.
	(vms_new_section_hook): Use void * instead of PTR.
	(vms_alpha_vec): Ditto.

Index: bfd/vms-alpha.c
===================================================================
RCS file: /cvs/src/src/bfd/vms-alpha.c,v
retrieving revision 1.43
diff -c -r1.43 vms-alpha.c
*** bfd/vms-alpha.c	31 Mar 2011 11:08:40 -0000	1.43
--- bfd/vms-alpha.c	6 May 2011 10:36:25 -0000
***************
*** 304,309 ****
--- 304,310 ----
  
    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  */
***************
*** 992,998 ****
        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 }
    };
  
  /* Retrieve BFD section flags by name and size.  */
--- 993,999 ----
        EGPS__V_REL | EGPS__V_RD | EGPS__V_WRT,
        SEC_DATA,
        EGPS__V_REL | EGPS__V_RD | EGPS__V_WRT,
!       SEC_DATA | SEC_HAS_CONTENTS | SEC_ALLOC | SEC_LOAD }
    };
  
  /* Retrieve BFD section flags by name and size.  */
***************
*** 1129,1142 ****
            /* Program section definition.  */
  	  {
              struct vms_egps *egps = (struct vms_egps *)vms_rec;
!             flagword new_flags, old_flags;
              asection *section;
  
! 	    old_flags = bfd_getl16 (egps->flags);
  
!             if ((old_flags & EGPS__V_REL) == 0)
                {
!                 /* Use the global absolute section for all absolute sections.  */
                  section = bfd_abs_section_ptr;
                }
              else
--- 1130,1144 ----
            /* Program section definition.  */
  	  {
              struct vms_egps *egps = (struct vms_egps *)vms_rec;
!             flagword new_flags, vms_flags;
              asection *section;
  
! 	    vms_flags = bfd_getl16 (egps->flags);
  
!             if ((vms_flags & EGPS__V_REL) == 0)
                {
!                 /* Use the global absolute section for all
!                    absolute sections.  */
                  section = bfd_abs_section_ptr;
                }
              else
***************
*** 1154,1170 ****
                  section->size = bfd_getl32 (egps->alloc);
                  section->alignment_power = egps->align;
  
!                 vms_section_data (section)->flags = old_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)
                    {
                      new_flags |= SEC_HAS_CONTENTS;
!                     if (old_flags & EGPS__V_REL)
                        new_flags |= SEC_RELOC;
                    }
                  if (!bfd_set_section_flags (abfd, section, new_flags))
                    return FALSE;
  
--- 1156,1182 ----
                  section->size = bfd_getl32 (egps->alloc);
                  section->alignment_power = egps->align;
  
!                 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 (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 (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;
  
***************
*** 2425,2431 ****
  static const struct bfd_target *
  alpha_vms_object_p (bfd *abfd)
  {
!   PTR tdata_save = abfd->tdata.any;
    unsigned int test_len;
    unsigned char *buf;
  
--- 2437,2443 ----
  static const struct bfd_target *
  alpha_vms_object_p (bfd *abfd)
  {
!   void *tdata_save = abfd->tdata.any;
    unsigned int test_len;
    unsigned char *buf;
  
***************
*** 2908,2914 ****
    if (sec->flags & SEC_RELOC)
      eisd->u.eisd.flags |= EISD__M_WRT | EISD__M_CRF;
  
!   if (!(sec->flags & SEC_LOAD))
      {
        eisd->u.eisd.flags |= EISD__M_DZRO;
        eisd->u.eisd.flags &= ~EISD__M_CRF;
--- 2920,2926 ----
    if (sec->flags & SEC_RELOC)
      eisd->u.eisd.flags |= EISD__M_WRT | EISD__M_CRF;
  
!   if (!(sec->flags & SEC_HAS_CONTENTS))
      {
        eisd->u.eisd.flags |= EISD__M_DZRO;
        eisd->u.eisd.flags &= ~EISD__M_CRF;
***************
*** 4617,4622 ****
--- 4629,4639 ----
        /* 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;
***************
*** 4710,4718 ****
--- 4727,4737 ----
    *func = NULL;
    *line = 0;
  
+   /* 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);
***************
*** 8593,8600 ****
  
    switch (h->root.type)
      {
-     case bfd_link_hash_new:
      case bfd_link_hash_undefined:
        abort ();
      case bfd_link_hash_undefweak:
        return TRUE;
--- 8612,8620 ----
  
    switch (h->root.type)
      {
      case bfd_link_hash_undefined:
+       return TRUE;
+     case bfd_link_hash_new:
        abort ();
      case bfd_link_hash_undefweak:
        return TRUE;
***************
*** 8972,8980 ****
        return FALSE;
      }
  
!   /* Alloc in memory and read ETIRs.  */
!   BFD_ASSERT (section->contents == NULL);
  
    for (sec = abfd->sections; sec; sec = sec->next)
      {
        BFD_ASSERT (sec->contents == NULL);
--- 8992,9008 ----
        return FALSE;
      }
  
!   /* 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);
***************
*** 8989,8996 ****
    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;
    memcpy (buf, section->contents + offset, count);
    return TRUE;
  }
--- 9017,9024 ----
    if (!alpha_vms_read_sections_content (abfd, NULL))
      return FALSE;
    for (sec = abfd->sections; sec; sec = sec->next)
!     if (sec->contents)
!       sec->flags |= SEC_IN_MEMORY;
    memcpy (buf, section->contents + offset, count);
    return TRUE;
  }
***************
*** 9083,9089 ****
    vms_debug2 ((7, "%d: %s\n", section->index, section->name));
  
    amt = sizeof (struct vms_section_data_struct);
!   section->used_by_bfd = (PTR) bfd_zalloc (abfd, amt);
    if (section->used_by_bfd == NULL)
      return FALSE;
  
--- 9111,9117 ----
    vms_debug2 ((7, "%d: %s\n", section->index, section->name));
  
    amt = sizeof (struct vms_section_data_struct);
!   section->used_by_bfd = bfd_zalloc (abfd, amt);
    if (section->used_by_bfd == NULL)
      return FALSE;
  
***************
*** 9360,9364 ****
  
    NULL,
  
!   (PTR) 0
  };
--- 9388,9392 ----
  
    NULL,
  
!   NULL
  };



More information about the Binutils mailing list