This is the mail archive of the binutils@sourceware.org mailing list for the binutils project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[vms/committed]: generate and write the GST


Hi,

the GST is the global symbol table, ie the symbol table in a executable.  With this patch, the linker
is now able to write it, which is required to debug an executable.

Tristan.

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

	* vms-alpha.c: Update comments.
	(alpha_vms_write_exec): Set lnkflags.  Write the GST.
	(alpha_vms_link_output_symbol): New function.
	(alpha_vms_bfd_final_link): Generate the VMS symbol table.
	Set dst_section private field.
	(alpha_vms_bfd_final_link): Remove code that set dst_section.


Index: vms-alpha.c
===================================================================
RCS file: /cvs/src/src/bfd/vms-alpha.c,v
retrieving revision 1.17
diff -c -r1.17 vms-alpha.c
*** vms-alpha.c	25 May 2010 12:41:16 -0000	1.17
--- vms-alpha.c	26 May 2010 08:54:17 -0000
***************
*** 21,35 ****
     MA 02110-1301, USA.  */
  
  /* TODO:
!    o  DMT
     o  PIC
     o  Generation of shared image
-    o  Generation of GST in image
     o  Relocation optimizations
     o  EISD for the stack
     o  Vectors isect
     o  64 bits sections
     o  Entry point
     ...
  */
  
--- 21,36 ----
     MA 02110-1301, USA.  */
  
  /* TODO:
!    o  overlayed sections
     o  PIC
     o  Generation of shared image
     o  Relocation optimizations
     o  EISD for the stack
     o  Vectors isect
     o  64 bits sections
     o  Entry point
+    o  LIB$INITIALIZE
+    o  protected sections (for messages)
     ...
  */
  
***************
*** 1631,1637 ****
          return RELC_SHR_BASE + PRIV2 (h->sym->owner, shr_index);
        else
          {
!           /* Can this happen ?  I'd like to see an example.  */
            abort ();
          }
      }
--- 1632,1639 ----
          return RELC_SHR_BASE + PRIV2 (h->sym->owner, shr_index);
        else
          {
!           /* Can this happen (non-relocatable symg) ?  I'd like to see
!              an example.  */
            abort ();
          }
      }
***************
*** 2934,2939 ****
--- 2936,2943 ----
    struct vms_internal_eisd_map *eisd;
    asection *dst;
    asection *dmt;
+   file_ptr gst_filepos = 0;
+   unsigned int lnkflags = 0;
  
    /* Build the EIHD.  */
    PRIV (file_pos) = EIHD__C_LENGTH;
***************
*** 2962,2968 ****
  
    bfd_putl32 ((sizeof (eihd) + VMS_BLOCK_SIZE - 1) / VMS_BLOCK_SIZE,
                eihd.hdrblkcnt);
-   bfd_putl32 (0, eihd.lnkflags);
    bfd_putl32 (0, eihd.ident);
    bfd_putl32 (0, eihd.sysver);
  
--- 2966,2971 ----
***************
*** 3115,3123 ****
--- 3118,3134 ----
  
        if (dmt != NULL)
          {
+           lnkflags |= EIHD__M_DBGDMT;
            bfd_putl32 ((dmt->filepos / VMS_BLOCK_SIZE) + 1, eihs->dmtvbn);
            bfd_putl32 (dmt->size, eihs->dmtsize);
          }
+       if (PRIV (gsd_sym_count) != 0)
+         {
+           alpha_vms_file_position_block (abfd);
+           gst_filepos = PRIV (file_pos);
+           bfd_putl32 ((gst_filepos / VMS_BLOCK_SIZE) + 1, eihs->gstvbn);
+           bfd_putl32 ((PRIV (gsd_sym_count) + 4) / 5 + 4, eihs->gstsize);
+         }
      }
  
    /* Write EISD in hdr.  */
***************
*** 3127,3132 ****
--- 3138,3144 ----
        (eisd, (struct vms_eisd *)((char *)&eihd + eisd->file_pos));
  
    /* Write first block.  */
+   bfd_putl32 (lnkflags, eihd.lnkflags);
    if (bfd_bwrite (&eihd, sizeof (eihd), abfd) != sizeof (eihd))
      return FALSE;
  
***************
*** 3178,3183 ****
--- 3190,3257 ----
          }
      }
  
+   /* Write GST.  */
+   if (gst_filepos != 0)
+     {
+       struct vms_rec_wr *recwr = &PRIV (recwr);
+       unsigned int i;
+ 
+       _bfd_vms_write_emh (abfd);
+       _bfd_vms_write_lmn (abfd, "GNU LD");
+ 
+       /* PSC for the absolute section.  */
+       _bfd_vms_output_begin (recwr, EOBJ__C_EGSD);
+       _bfd_vms_output_long (recwr, 0);
+       _bfd_vms_output_begin_subrec (recwr, EGSD__C_PSC);
+       _bfd_vms_output_short (recwr, 0);
+       _bfd_vms_output_short (recwr, EGPS__V_PIC | EGPS__V_LIB | EGPS__V_RD);
+       _bfd_vms_output_long (recwr, 0);
+       _bfd_vms_output_counted (recwr, ".$$ABS$$.");
+       _bfd_vms_output_end_subrec (recwr);
+       _bfd_vms_output_end (abfd, recwr);
+ 
+       for (i = 0; i < PRIV (gsd_sym_count); i++)
+         {
+           struct vms_symbol_entry *sym = PRIV (syms)[i];
+           char *hash;
+           bfd_vma val;
+           bfd_vma ep;
+ 
+           if ((i % 5) == 0)
+             {
+               _bfd_vms_output_alignment (recwr, 8);
+               _bfd_vms_output_begin (recwr, EOBJ__C_EGSD);
+               _bfd_vms_output_long (recwr, 0);
+             }
+           _bfd_vms_output_begin_subrec (recwr, EGSD__C_SYMG);
+           _bfd_vms_output_short (recwr, 0); /* Data type, alignment.  */
+           _bfd_vms_output_short (recwr, sym->flags);
+ 
+           if (sym->code_section)
+             ep = alpha_vms_get_sym_value (sym->code_section, sym->code_value);
+           else
+             {
+               BFD_ASSERT (sym->code_value == 0);
+               ep = 0;
+             }
+           val = alpha_vms_get_sym_value (sym->section, sym->value);
+           _bfd_vms_output_quad
+             (recwr, sym->typ == EGSD__C_SYMG ? sym->symbol_vector : val);
+ 	  _bfd_vms_output_quad (recwr, ep);
+ 	  _bfd_vms_output_quad (recwr, val);
+ 	  _bfd_vms_output_long (recwr, 0);
+           hash = _bfd_vms_length_hash_symbol (abfd, sym->name, EOBJ__C_SYMSIZ);
+           _bfd_vms_output_counted (recwr, hash);
+           _bfd_vms_output_end_subrec (recwr);
+           if ((i % 5) == 4)
+             _bfd_vms_output_end (abfd, recwr);
+         }
+       if ((i % 5) != 0)
+         _bfd_vms_output_end (abfd, recwr);
+ 
+       if (!_bfd_vms_write_eeom (abfd))
+         return FALSE;
+     }
    return TRUE;
  }
  

***************
*** 8422,8427 ****
--- 8496,8575 ----
    return TRUE;
  }
  
+ /* Called by bfd_link_hash_traverse to fill the symbol table.
+    Return FALSE in case of failure.  */
+ 
+ static bfd_boolean
+ alpha_vms_link_output_symbol (struct bfd_link_hash_entry *hc, void *infov)
+ {
+   struct bfd_link_info *info = (struct bfd_link_info *)infov;
+   struct alpha_vms_link_hash_entry *h = (struct alpha_vms_link_hash_entry *)hc;
+   struct vms_symbol_entry *sym;
+ 
+   switch (h->root.type)
+     {
+     case bfd_link_hash_new:
+     case bfd_link_hash_undefined:
+       abort ();
+     case bfd_link_hash_undefweak:
+       return TRUE;
+     case bfd_link_hash_defined:
+     case bfd_link_hash_defweak:
+       {
+         asection *sec = h->root.u.def.section;
+ 
+         /* FIXME: this is certainly a symbol from a dynamic library.  */
+         if (bfd_is_abs_section (sec))
+           return TRUE;
+ 
+         if (sec->owner->flags & DYNAMIC)
+           return TRUE;
+       }
+       break;
+     case bfd_link_hash_common:
+       break;
+     case bfd_link_hash_indirect:
+     case bfd_link_hash_warning:
+       return TRUE;
+     }
+ 
+   /* Do not write not kept symbols.  */
+   if (info->strip == strip_some
+       && bfd_hash_lookup (info->keep_hash, h->root.root.string,
+                           FALSE, FALSE) != NULL)
+     return TRUE;
+ 
+   if (h->sym == NULL)
+     {
+       /* This symbol doesn't come from a VMS object.  So we suppose it is
+          a data.  */
+       int len = strlen (h->root.root.string);
+ 
+       sym = (struct vms_symbol_entry *)bfd_zalloc (info->output_bfd,
+                                                    sizeof (*sym) + len);
+       if (sym == NULL)
+         abort ();
+       sym->namelen = len;
+       memcpy (sym->name, h->root.root.string, len);
+       sym->name[len] = 0;
+       sym->owner = info->output_bfd;
+ 
+       sym->typ = EGSD__C_SYMG;
+       sym->data_type = 0;
+       sym->flags = EGSY__V_DEF | EGSY__V_REL;
+       sym->symbol_vector = h->root.u.def.value;
+       sym->section = h->root.u.def.section;
+       sym->value = h->root.u.def.value;
+     }
+   else
+     sym = h->sym;
+ 
+   if (!add_symbol_entry (info->output_bfd, sym))
+     return FALSE;
+ 
+   return TRUE;
+ }
+ 
  static bfd_boolean
  alpha_vms_bfd_final_link (bfd *abfd, struct bfd_link_info *info)
  {
***************
*** 8476,8481 ****
--- 8624,8634 ----
      }
  #endif
  
+   /* Generate the symbol table.  */
+   BFD_ASSERT (PRIV (syms) == NULL);
+   if (info->strip != strip_all)
+     bfd_link_hash_traverse (info->hash, alpha_vms_link_output_symbol, info);
+ 
    /* Find the entry point.  */
    if (bfd_get_start_address (abfd) == 0)
      {
***************
*** 8548,8558 ****
    alpha_vms_link_hash (info)->base_addr = base_addr;
  
    /* Create the DMT section, if necessary.  */
!   dst = PRIV (dst_section);
    if (dst != NULL && dst->size == 0)
      dst = NULL;
    if (dst != NULL)
      {
        dmt = bfd_make_section_anyway_with_flags
          (info->output_bfd, "$DMT$",
  
    /* Create the DMT section, if necessary.  */
!   BFD_ASSERT (PRIV (dst_section) == NULL);
!   dst = bfd_get_section_by_name (abfd, "$DST$");
    if (dst != NULL && dst->size == 0)
      dst = NULL;
    if (dst != NULL)
      {
+       PRIV (dst_section) = dst;
        dmt = bfd_make_section_anyway_with_flags
          (info->output_bfd, "$DMT$",
           SEC_DEBUGGING | SEC_HAS_CONTENTS | SEC_LINKER_CREATED);
***************
*** 8819,8827 ****
    if (section->used_by_bfd == NULL)
      return FALSE;
  
-   if (strcmp (bfd_get_section_name (abfd, section), "$DST$") == 0)
-     PRIV (dst_section) = section;
- 
    /* Create the section symbol.  */
    return _bfd_generic_new_section_hook (abfd, section);
  }
--- 8974,8979 ----


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]