[VMS/committed] Generate the DMT

Tristan Gingold gingold@adacore.com
Mon May 3 12:16:00 GMT 2010


Hi,

with this patch, bfd is able to generate the DMT (Debug Module Table), which is required to debug.
Also, the DST (Debug Symbol Table) is now correctly written.  Previously it was corrupted in some cases.
A few comments have been added to improve readability.

Tristan.

bfd/
2010-05-03  Tristan Gingold  <gingold@adacore.com>

	* vms-alpha.c: Add comments.
	(struct vms_private_data_struct): Remove image_autoextend field.
	(dst_check_allocation): Removed.
	(image_write): Remove call to dst_check_allocation.
	(vms_slurp_debug): Do not set image_autoextend.  Adjust section
	size.
	(_bfd_vms_slurp_object_records): Remove useless new_type variable.
	(alpha_vms_write_exec): Use dst_section to get the dst section.
	Write the dmt section.
	(evax_bfd_print_image): Also print the dst size in hexa.  Fix typo.
	(alpha_vms_read_sections_content): Do not set image_autoextend.

include/vms/
2010-05-03  Tristan Gingold  <gingold@adacore.com>

	* dmt.h: Improve comments.

Index: bfd/vms-alpha.c
===================================================================
RCS file: /cvs/src/src/bfd/vms-alpha.c,v
retrieving revision 1.4
diff -c -r1.4 vms-alpha.c
*** bfd/vms-alpha.c	30 Apr 2010 09:40:42 -0000	1.4
--- bfd/vms-alpha.c	3 May 2010 11:01:37 -0000
***************
*** 89,94 ****
--- 89,95 ----
  #define ALPHA_R_BSR		15
  #define ALPHA_R_LDA		16
  #define ALPHA_R_BOH		17
+ 
  /* These are used with DST_S_C_LINE_NUM.  */
  #define DST_S_C_LINE_NUM_HEADER_SIZE 4
  
***************
*** 291,297 ****
    /* Content reading.  */
    asection *image_section;		/* section for image_ptr  */
    file_ptr image_offset;		/* Offset for image_ptr.  */
-   bfd_boolean image_autoextend;		/* Resize section if necessary.  */
  
    struct module *modules;		/* list of all compilation units */
  
--- 292,297 ----
***************
*** 1383,1412 ****
    return PRIV (dst_ptr_offsets)[loc];
  }
  
- /* Check that the DST section is big enough for the specified
-    amount of bytes.  */
- 
- static void
- dst_check_allocation (bfd *abfd, unsigned int size)
- {
-   asection *section = PRIV (image_section);
- 
-   section->size += size;
- 
-   /* Grow the section as necessary */
-   if (section->size <= section->rawsize)
-     return;
-   do
-     {
-       if (section->rawsize == 0)
-         section->rawsize = 1024;
-       else
-         section->rawsize *= 2;
-     }
-   while (section->size > section->rawsize);
-   section->contents = bfd_realloc (section->contents, section->rawsize);
- }
- 
  /* Write multiple bytes to section image.  */
  
  static bfd_boolean
--- 1383,1388 ----
***************
*** 1418,1426 ****
    _bfd_hexdump (9, ptr, size, 0);
  #endif
  
-   if (PRIV (image_autoextend))
-     dst_check_allocation (abfd, size);
- 
    if (PRIV (image_section)->contents != NULL)
      {
        asection *sec = PRIV (image_section);
--- 1394,1399 ----
***************
*** 1667,1672 ****
--- 1640,1649 ----
      return vma + sec->vma;
  }
  
+ /* Read an ETIR record from ABFD.  If INFO is not null, put the content into
+    the output section (used during linking).
+    Return FALSE in case of error.  */
+ 
  static bfd_boolean
  _bfd_vms_slurp_etir (bfd *abfd, struct bfd_link_info *info)
  {
***************
*** 2263,2273 ****
  
    PRIV (image_section) = section;
    PRIV (image_offset) = section->size;
-   PRIV (image_autoextend) = FALSE;
  
    if (!_bfd_vms_slurp_etir (abfd, NULL))
      return FALSE;
  
    return TRUE;
  }
  
--- 2240,2250 ----
  
    PRIV (image_section) = section;
    PRIV (image_offset) = section->size;
  
    if (!_bfd_vms_slurp_etir (abfd, NULL))
      return FALSE;
  
+   section->size = PRIV (image_offset);
    return TRUE;
  }
  
***************
*** 2279,2285 ****
  {
    vms_debug2 ((2, "EDBG\n"));
  
!   abfd->flags |= (HAS_DEBUG | HAS_LINENO);
  
    return vms_slurp_debug (abfd);
  }
--- 2256,2262 ----
  {
    vms_debug2 ((2, "EDBG\n"));
  
!   abfd->flags |= HAS_DEBUG | HAS_LINENO;
  
    return vms_slurp_debug (abfd);
  }
***************
*** 2334,2354 ****
  static bfd_boolean
  _bfd_vms_slurp_object_records (bfd * abfd)
  {
!   int err, new_type, type = -1;
  
    do
      {
        vms_debug2 ((7, "reading at %08lx\n", (unsigned long)bfd_tell (abfd)));
  
!       new_type = _bfd_vms_get_object_record (abfd);
!       if (new_type < 0)
  	{
  	  vms_debug2 ((2, "next_record failed\n"));
  	  return FALSE;
  	}
  
-       type = new_type;
- 
        switch (type)
  	{
          case EOBJ__C_EMH:
--- 2311,2330 ----
  static bfd_boolean
  _bfd_vms_slurp_object_records (bfd * abfd)
  {
!   bfd_boolean err;
!   int type;
  
    do
      {
        vms_debug2 ((7, "reading at %08lx\n", (unsigned long)bfd_tell (abfd)));
  
!       type = _bfd_vms_get_object_record (abfd);
!       if (type < 0)
  	{
  	  vms_debug2 ((2, "next_record failed\n"));
  	  return FALSE;
  	}
  
        switch (type)
  	{
          case EOBJ__C_EMH:
***************
*** 2598,2603 ****
--- 2574,2581 ----
    PRIV (file_pos) -= (PRIV (file_pos) % VMS_BLOCK_SIZE);
  }
  
+ /* Convert from internal structure SRC to external structure DST.  */
+ 
  static void
  alpha_vms_swap_eisd_out (struct vms_internal_eisd_map *src,
                           struct vms_eisd *dst)
***************
*** 2636,2641 ****
--- 2614,2622 ----
    PRIV (gbl_eisd_tail) = eisd;
  }
  
+ /* Create an EISD for shared image SHRIMG.
+    Return FALSE in case of error.  */
+ 
  static bfd_boolean
  alpha_vms_create_eisd_for_shared (bfd *abfd, bfd *shrimg)
  {
***************
*** 2677,2682 ****
--- 2658,2666 ----
    return TRUE;
  }
  
+ /* Create an EISD for section SEC.
+    Return FALSE in case of failure.  */
+ 
  static bfd_boolean
  alpha_vms_create_eisd_for_section (bfd *abfd, asection *sec)
  {
***************
*** 2732,2737 ****
--- 2716,2724 ----
    return TRUE;
  }
  
+ /* Layout executable ABFD and write it to the disk.
+    Return FALSE in case of failure.  */
+ 
  static bfd_boolean
  alpha_vms_write_exec (bfd *abfd)
  {
***************
*** 2743,2749 ****
--- 2730,2738 ----
    struct vms_internal_eisd_map *first_eisd;
    struct vms_internal_eisd_map *eisd;
    asection *dst;
+   asection *dmt;
  
+   /* Build the EIHD.  */
    PRIV (file_pos) = EIHD__C_LENGTH;
  
    memset (&eihd, 0, sizeof (eihd));
***************
*** 2821,2829 ****
    eihi->imgbid[0] = 0;
  
    /* Alloc EIHS.  */
!   dst = bfd_get_section_by_name (abfd, "$DST$");
!   if (dst == NULL || dst->size == 0)
!     dst = bfd_get_section_by_name (abfd, "$TBT$");
    if (dst != NULL && dst->size != 0)
      {
        eihs = (struct vms_eihs *)((char *) &eihd + PRIV (file_pos));
--- 2810,2817 ----
    eihi->imgbid[0] = 0;
  
    /* Alloc EIHS.  */
!   dst = PRIV (dst_section);
!   dmt = bfd_get_section_by_name (abfd, "$DMT$");
    if (dst != NULL && dst->size != 0)
      {
        eihs = (struct vms_eihs *)((char *) &eihd + PRIV (file_pos));
***************
*** 2840,2846 ****
        bfd_putl32 (0, eihs->dmtsize);
      }
  
!   /* One per section.  */
    for (sec = abfd->sections; sec; sec = sec->next)
      {
        if (!alpha_vms_create_eisd_for_section (abfd, sec))
--- 2828,2834 ----
        bfd_putl32 (0, eihs->dmtsize);
      }
  
!   /* One EISD per section.  */
    for (sec = abfd->sections; sec; sec = sec->next)
      {
        if (!alpha_vms_create_eisd_for_section (abfd, sec))
***************
*** 2920,2925 ****
--- 2908,2919 ----
      {
        bfd_putl32 ((dst->filepos / VMS_BLOCK_SIZE) + 1, eihs->dstvbn);
        bfd_putl32 (dst->size, eihs->dstsize);
+ 
+       if (dmt != NULL)
+         {
+           bfd_putl32 ((dmt->filepos / VMS_BLOCK_SIZE) + 1, eihs->dmtvbn);
+           bfd_putl32 (dmt->size, eihs->dmtsize);
+         }
      }
  
    /* Write EISD in hdr.  */
***************
*** 7362,7369 ****
                 (unsigned)bfd_getl32 (eihs.minorid));
        dst_vbn = bfd_getl32 (eihs.dstvbn);
        dst_size = bfd_getl32 (eihs.dstsize);
!       fprintf (file, _(" debug symbol table : vbn: %u, size: %u\n"),
!                dst_vbn, dst_size);
        gst_vbn = bfd_getl32 (eihs.gstvbn);
        gst_size = bfd_getl32 (eihs.gstsize);
        fprintf (file, _(" global symbol table: vbn: %u, records: %u\n"),
--- 7356,7363 ----
                 (unsigned)bfd_getl32 (eihs.minorid));
        dst_vbn = bfd_getl32 (eihs.dstvbn);
        dst_size = bfd_getl32 (eihs.dstsize);
!       fprintf (file, _(" debug symbol table : vbn: %u, size: %u (0x%x)\n"),
!                dst_vbn, dst_size, dst_size);
        gst_vbn = bfd_getl32 (eihs.gstvbn);
        gst_size = bfd_getl32 (eihs.gstsize);
        fprintf (file, _(" global symbol table: vbn: %u, records: %u\n"),
***************
*** 7499,7505 ****
              }
            count = bfd_getl16 (dmth.psect_count);
            fprintf (file,
!                    _(" module address: 0x%08x, size: 0x%08x, (%u psect)\n"),
                     (unsigned)bfd_getl32 (dmth.modbeg),
                     (unsigned)bfd_getl32 (dmth.size), count);
            dmt_size -= sizeof (dmth);
--- 7493,7499 ----
              }
            count = bfd_getl16 (dmth.psect_count);
            fprintf (file,
!                    _(" module address: 0x%08x, size: 0x%08x, (%u psects)\n"),
                     (unsigned)bfd_getl32 (dmth.modbeg),
                     (unsigned)bfd_getl32 (dmth.size), count);
            dmt_size -= sizeof (dmth);
***************
*** 7745,7751 ****
  
  /* Linking.  */
  
! /* Slurp an ordered set of VMS object records.  */
  
  static bfd_boolean
  alpha_vms_read_sections_content (bfd *abfd, struct bfd_link_info *info)
--- 7739,7745 ----
  
  /* Linking.  */
  
! /* Slurp ETIR/EDBG/ETBT VMS object records.  */
  
  static bfd_boolean
  alpha_vms_read_sections_content (bfd *abfd, struct bfd_link_info *info)
***************
*** 7758,7765 ****
    if (bfd_seek (abfd, 0, SEEK_SET) != 0)
      return FALSE;
  
-   PRIV (image_autoextend) = FALSE;
- 
    cur_section = NULL;
    cur_offset = 0;
  
--- 7752,7757 ----
***************
*** 7769,7774 ****
--- 7761,7767 ----
      {
        if (info->strip == strip_all || info->strip == strip_debugger)
          {
+           /* Discard the DST section.  */
            dst_offset = 0;
            dst_section = NULL;
          }
***************
*** 7805,7813 ****
              continue;
            PRIV (image_section) = dst_section;
            PRIV (image_offset) = dst_offset;
-           PRIV (image_autoextend) = TRUE;
            res = _bfd_vms_slurp_etir (abfd, info);
-           PRIV (image_autoextend) = FALSE;
            dst_offset = PRIV (image_offset);
            break;
          case EOBJ__C_EEOM:
--- 7798,7804 ----
***************
*** 8372,8377 ****
--- 8363,8369 ----
    asection *fixupsec;
    bfd_vma base_addr;
    bfd_vma last_addr;
+   asection *dst;
  
    bfd_get_outsymbols (abfd) = NULL;
    bfd_get_symcount (abfd) = 0;
***************
*** 8415,8421 ****
      }
  #endif
  
!   /* Find entry point.  */
    if (bfd_get_start_address (abfd) == 0)
      {
        bfd *startbfd = NULL;
--- 8407,8413 ----
      }
  #endif
  
!   /* Find the entry point.  */
    if (bfd_get_start_address (abfd) == 0)
      {
        bfd *startbfd = NULL;
***************
*** 8454,8460 ****
          }
      }
  
!   /* Allocate content.  */
    base_addr = (bfd_vma)-1;
    last_addr = 0;
    for (o = abfd->sections; o != NULL; o = o->next)
--- 8446,8452 ----
          }
      }
  
!   /* Allocate contents.  */
    base_addr = (bfd_vma)-1;
    last_addr = 0;
    for (o = abfd->sections; o != NULL; o = o->next)
***************
*** 8474,8479 ****
--- 8466,8472 ----
          }
      }
  
+   /* Create the fixup section.  */
    fixupsec = bfd_make_section_anyway_with_flags
      (info->output_bfd, "$FIXUP$",
       SEC_ALLOC | SEC_LOAD | SEC_HAS_CONTENTS | SEC_LINKER_CREATED);
***************
*** 8524,8529 ****
--- 8517,8607 ----
    if (!alpha_vms_build_fixups (info))
      return FALSE;
  
+   /* Compute the DMT.  */
+   dst = PRIV (dst_section);
+   if (dst != NULL && dst->size == 0)
+     dst = NULL;
+   if (dst != NULL)
+     {
+       asection *dmt;
+       int pass;
+       unsigned char *contents = NULL;
+ 
+       dmt = bfd_make_section_anyway_with_flags
+         (info->output_bfd, "$DMT$",
+          SEC_DEBUGGING | SEC_HAS_CONTENTS | SEC_LINKER_CREATED);
+       if (dmt == NULL)
+         return FALSE;
+ 
+       /* In pass 1, compute the size.  In pass 2, write the DMT contents.  */
+       for (pass = 0; pass < 2; pass++)
+         {
+           unsigned int off = 0;
+ 
+           /* For each object file (ie for each module).  */
+           for (sub = info->input_bfds; sub != NULL; sub = sub->link_next)
+             {
+               asection *sub_dst;
+               struct vms_dmt_header *dmth = NULL;
+               unsigned int psect_count;
+ 
+               /* Skip this module if it has no DST.  */
+               sub_dst = PRIV2 (sub, dst_section);
+               if (sub_dst == NULL || sub_dst->size == 0)
+                 continue;
+ 
+               if (pass == 1)
+                 {
+                   /* Write the header.  */
+                   dmth = (struct vms_dmt_header *)(contents + off);
+                   bfd_putl32 (sub_dst->output_offset, dmth->modbeg);
+                   bfd_putl32 (sub_dst->size, dmth->size);
+                 }
+ 
+               off += sizeof (struct vms_dmt_header);
+               psect_count = 0;
+ 
+               /* For each section (ie for each psect).  */
+               for (o = sub->sections; o != NULL; o = o->next)
+                 {
+                   /* Only consider interesting sections.  */
+                   if (!(o->flags & SEC_ALLOC))
+                     continue;
+                   if (o->flags & SEC_LINKER_CREATED)
+                     continue;
+ 
+                   if (pass == 1)
+                     {
+                       /* Write an entry.  */
+                       struct vms_dmt_psect *dmtp;
+ 
+                       dmtp = (struct vms_dmt_psect *)(contents + off);
+                       bfd_putl32 (o->output_offset + o->output_section->vma,
+                                   dmtp->start);
+                       bfd_putl32 (o->size, dmtp->length);
+                       psect_count++;
+                     }
+                   off += sizeof (struct vms_dmt_psect);
+                 }
+               if (pass == 1)
+                 bfd_putl32 (psect_count, dmth->psect_count);
+             }
+ 
+           if (pass == 0)
+             {
+               contents = bfd_zalloc (info->output_bfd, off);
+               if (contents == NULL)
+                 return FALSE;
+               dmt->contents = contents;
+               dmt->size = off;
+             }
+           else
+             {
+               BFD_ASSERT (off == dmt->size);
+             }
+         }
+     }
+ 
    return TRUE;
  }
  
Index: include/vms/dmt.h
===================================================================
RCS file: /cvs/src/src/include/vms/dmt.h,v
retrieving revision 1.1
diff -c -r1.1 dmt.h
*** include/vms/dmt.h	17 Feb 2010 10:12:48 -0000	1.1
--- include/vms/dmt.h	3 May 2010 11:01:38 -0000
***************
*** 25,34 ****
  
  struct vms_dmt_header
  {
!   /* Address of the module.  */
    unsigned char modbeg[4];
  
!   /* Size of the module.  */
    unsigned char size[4];
  
    /* Number of psect for this module.  */
--- 25,34 ----
  
  struct vms_dmt_header
  {
!   /* Offset in the DST of the module.  */
    unsigned char modbeg[4];
  
!   /* Size of the DST chunk for this module.  */
    unsigned char size[4];
  
    /* Number of psect for this module.  */
***************
*** 39,45 ****
--- 39,48 ----
  
  struct vms_dmt_psect
  {
+   /* Address of the psect.  */
    unsigned char start[4];
+ 
+   /* Length of the psect.  */
    unsigned char length[4];
  };
  #endif /* _VMS_DMT_H */



More information about the Binutils mailing list