* subsegs.h (segment_info_type): If MANY_SEGMENTS and not
authorIan Lance Taylor <ian@airs.com>
Thu, 2 May 1996 02:32:52 +0000 (02:32 +0000)
committerIan Lance Taylor <ian@airs.com>
Thu, 2 May 1996 02:32:52 +0000 (02:32 +0000)
BFD_ASSEMBLER, add name field.
* config/obj-coff.c (coff_header_append): Handle long section
names.
(crawl_symbols): Just use the name field for the symbol name,
without worrying about null byte termination.
(w_strings): Handle long section names.
(write_object_file): Likewise.  Also, use the name field, rather
than scnhdr.s_name.
(obj_coff_add_segment): Permit long section names.
(obj_coff_init_stab_section): Use the name field, rather than
scnhdr.s_name.
(adjust_stab_section): Likewise.
* config/te-pe.h (COFF_LONG_SECTION_NAMES): Define.

gas/ChangeLog
gas/config/obj-coff.c
gas/subsegs.h

index 0250fe6..0241327 100644 (file)
@@ -1,5 +1,20 @@
 Wed May  1 13:38:17 1996  Ian Lance Taylor  <ian@cygnus.com>
 
+       * subsegs.h (segment_info_type): If MANY_SEGMENTS and not
+       BFD_ASSEMBLER, add name field.
+       * config/obj-coff.c (coff_header_append): Handle long section
+       names.
+       (crawl_symbols): Just use the name field for the symbol name,
+       without worrying about null byte termination.
+       (w_strings): Handle long section names.
+       (write_object_file): Likewise.  Also, use the name field, rather
+       than scnhdr.s_name.
+       (obj_coff_add_segment): Permit long section names.
+       (obj_coff_init_stab_section): Use the name field, rather than
+       scnhdr.s_name.
+       (adjust_stab_section): Likewise.
+       * config/te-pe.h (COFF_LONG_SECTION_NAMES): Define.
+
        * config/tc-i960.c (brtab_emit): Don't set fx_im_disp field.
        (mem_fmt): Likewise.
        (md_apply_fix): Don't check fx_im_disp field.
index 087e250..3497ab2 100644 (file)
@@ -1922,12 +1922,29 @@ coff_header_append (abfd, h)
 
   for (i = SEG_E0; i < SEG_LAST; i++)
     {
+#ifdef COFF_LONG_SECTION_NAMES
+      unsigned long string_size = 4;
+#endif
+
       if (segment_info[i].scnhdr.s_name[0])
        {
-         unsigned int size =
-         bfd_coff_swap_scnhdr_out (abfd,
-                                   &(segment_info[i].scnhdr),
-                                   buffer);
+         unsigned int size;
+
+#ifdef COFF_LONG_SECTION_NAMES
+         /* Support long section names as found in PE.  This code
+             must coordinate with that in write_object_file and
+             w_strings.  */
+         if (strlen (segment_info[i].name) > SCNNMLEN)
+           {
+             memset (segment_info[i].scnhdr.s_name, 0, SCNNMLEN);
+             sprintf (segment_info[i].scnhdr.s_name, "/%d", string_size);
+             string_size += strlen (segment_info[i].scnhdr.name) + 1;
+           }
+#endif
+
+         size = bfd_coff_swap_scnhdr_out (abfd,
+                                          &(segment_info[i].scnhdr),
+                                          buffer);
          if (size == 0)
            as_bad ("bfd_coff_swap_scnhdr_out failed");
          bfd_write (buffer, size, 1, abfd);
@@ -2891,17 +2908,9 @@ crawl_symbols (h, abfd)
 
 
   for (i = SEG_E0; i < SEG_LAST; i++)
-    {
-      if (segment_info[i].scnhdr.s_name[0])
-       {
-         char name[9];
-
-         strncpy (name, segment_info[i].scnhdr.s_name, 8);
-         name[8] = '\0';
-         segment_info[i].dot = c_section_symbol (name, i - SEG_E0 + 1);
-       }
-    }
-
+    if (segment_info[i].scnhdr.s_name[0])
+      segment_info[i].dot = c_section_symbol (segment_info[i].name,
+                                             i - SEG_E0 + 1);
 
   /* Take all the externals out and put them into another chain */
   H_SET_SYMBOL_TABLE_SIZE (h, yank_symbols ());
@@ -2934,6 +2943,24 @@ w_strings (where)
   /* Gotta do md_ byte-ordering stuff for string_byte_count first - KWK */
   md_number_to_chars (where, (valueT) string_byte_count, 4);
   where += 4;
+
+#ifdef COFF_LONG_SECTION_NAMES
+  /* Support long section names as found in PE.  This code must
+     coordinate with that in coff_header_append and write_object_file.  */
+  for (i = SEG_E0; i < SEG_LAST; i++)
+    {
+      if (segment_info[i].scnhdr.s_name[0]
+         && strlen (segment_info[i].name) > SCNNMLEN)
+       {
+         unsigned int size;
+
+         size = strlen (segment_info[i].name) + 1;
+         memcpy (where, segment_info[i].name, size);
+         where += size;
+       }
+    }
+#endif /* COFF_LONG_SECTION_NAMES */
+
   for (symbolP = symbol_rootP;
        symbolP;
        symbolP = symbol_next (symbolP))
@@ -3120,6 +3147,19 @@ write_object_file ()
        {
          H_SET_NUMBER_OF_SECTIONS (&headers,
                                    H_GET_NUMBER_OF_SECTIONS (&headers) + 1);
+
+#ifdef COFF_LONG_SECTION_NAMES
+         /* Support long section names as found in PE.  This code
+            must coordinate with that in coff_header_append and
+            w_strings.  */
+         {
+           unsigned int len;
+
+           len = strlen (segment_info[i].name);
+           if (len > SCNNMLEN)
+             string_byte_count += len + 1;
+         }
+#endif /* COFF_LONG_SECTION_NAMES */
        }
 
       size = size_section (abfd, (unsigned int) i);
@@ -3159,7 +3199,7 @@ write_object_file ()
      correctly. */
   for (i = SEG_E0; i < SEG_UNKNOWN; i++)
     {
-      name = segment_info[i].scnhdr.s_name;
+      name = segment_info[i].name;
 
       if (name != NULL
          && strncmp (".stab", name, 5) == 0
@@ -3240,16 +3280,16 @@ obj_coff_add_segment (name)
   unsigned int len;
   unsigned int i;
 
-  /* Find out if we've already got a section of this name.  */
-  len = strlen (name);
-  if (len < sizeof (segment_info[i].scnhdr.s_name))
-    ++len;
-  else
-    len = sizeof (segment_info[i].scnhdr.s_name);
+#ifndef COFF_LONG_SECTION_NAMES
+  char buf[SCNNMLEN + 1];
+
+  strncpy (buf, name, SCNNMLEN);
+  buf[SCNNMLEN] = '\0';
+  name = buf;
+#endif
+
   for (i = SEG_E0; i < SEG_LAST && segment_info[i].scnhdr.s_name[0]; i++)
-    if (strncmp (segment_info[i].scnhdr.s_name, name, len) == 0
-       && (len == sizeof (segment_info[i].scnhdr.s_name)
-           || segment_info[i].scnhdr.s_name[len] == '\0'))
+    if (strcmp (name, segment_info[i].name) == 0)
       return (segT) i;
 
   if (i == SEG_LAST)
@@ -3262,6 +3302,7 @@ obj_coff_add_segment (name)
   strncpy (segment_info[i].scnhdr.s_name, name,
           sizeof (segment_info[i].scnhdr.s_name));
   segment_info[i].scnhdr.s_flags = STYP_REG;
+  segment_info[i].name = xstrdup (name);
 
   return (segT) i;
 }
@@ -4081,8 +4122,8 @@ obj_coff_init_stab_section (seg)
   /* Zero it out. */
   memset (p, 0, 12);
   as_where (&file, (unsigned int *) NULL);
-  stabstr_name = (char *) alloca (strlen (segment_info[seg].scnhdr.s_name) + 4);
-  strcpy (stabstr_name, segment_info[seg].scnhdr.s_name);
+  stabstr_name = (char *) alloca (strlen (segment_info[seg].name) + 4);
+  strcpy (stabstr_name, segment_info[seg].name);
   strcat (stabstr_name, "str");
   stroff = get_stab_string_offset (file, stabstr_name);
   know (stroff == 1);
@@ -4104,14 +4145,14 @@ adjust_stab_section(abfd, seg)
 
   /* Look for the associated string table section. */
 
-  secname = segment_info[seg].scnhdr.s_name;
+  secname = segment_info[seg].name;
   name = (char *) alloca (strlen (secname) + 4);
   strcpy (name, secname);
   strcat (name, "str");
 
   for (i = SEG_E0; i < SEG_UNKNOWN; i++)
     {
-      name2 = segment_info[i].scnhdr.s_name;
+      name2 = segment_info[i].name;
       if (name2 != NULL && strncmp(name2, name, 8) == 0)
        {
          stabstrseg = i;
index 2d3a100..7d71e8b 100644 (file)
@@ -16,7 +16,7 @@
 
    You should have received a copy of the GNU General Public License
    along with GAS; see the file COPYING.  If not, write to
-   the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.  */
+   the Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
 
 /*
  * For every sub-segment the user mentions in the ASsembler program,
@@ -37,6 +37,8 @@
  * represent code fragments, for that sub-segment, forward chained.
  */
 
+#include "obstack.h"
+
 struct frchain                 /* control building of a frag chain */
 {                              /* FRCH = FRagment CHain control */
   struct frag *frch_root;      /* 1st struct frag in chain, or NULL */
@@ -49,6 +51,7 @@ struct frchain                        /* control building of a frag chain */
   fixS *fix_tail;              /* Last fixup for this subsegment.  */
 #endif
   struct obstack frch_obstack; /* for objects in this frag chain */
+  fragS *frch_frag_now;                /* frag_now for this subsegment */
 };
 
 typedef struct frchain frchainS;
@@ -56,7 +59,7 @@ typedef struct frchain frchainS;
 /* All subsegments' chains hang off here.  NULL means no frchains yet.  */
 extern frchainS *frchain_root;
 
-/* Frchain we are assembling into now That is, the current segment's
+/* Frchain we are assembling into now That is, the current segment's
    frag chain, even if it contains no (complete) frags. */
 extern frchainS *frchain_now;
 
@@ -64,14 +67,14 @@ extern frchainS *frchain_now;
 typedef struct
 {
   frchainS *frchainP;
-  int hadone : 1;
+  unsigned int hadone : 1;
 
   /* This field is set if this is a .bss section which does not really
      have any contents.  Once upon a time a .bss section did not have
      any frags, but that is no longer true.  This field prevent the
      SEC_HAS_CONTENTS flag from being set for the section even if
      there are frags.  */
-  int bss : 1;
+  unsigned int bss : 1;
 
   int user_stuff;
 
@@ -82,7 +85,10 @@ typedef struct
 
 #if defined (MANY_SEGMENTS) && !defined (BFD_ASSEMBLER)
   struct internal_scnhdr scnhdr;
+  enum linkonce_type linkonce;
+  const char *name;
 #endif
+
   symbolS *dot;
 
   struct lineno_list *lineno_list_head;
@@ -131,6 +137,15 @@ extern segment_info_type segment_info[];
 extern frchainS *data0_frchainP;
 extern frchainS *bss0_frchainP;
 
+/* Dummy so stuff can compile.  Should never be used.  */
+struct seg_info_trash {
+  struct {
+    unsigned stab_string_size : 1;
+  } stabu;
+  unsigned hadone : 1;
+};
+#define seg_info(S)    (abort (), (struct seg_info_trash *) 0)
+
 #endif
 
 #endif /* ! BFD_ASSEMBLER */