1999-08-08 Mark Elbrecht <snowball3@bigfoot.com>
authorIan Lance Taylor <ian@airs.com>
Mon, 9 Aug 1999 02:56:16 +0000 (02:56 +0000)
committerIan Lance Taylor <ian@airs.com>
Mon, 9 Aug 1999 02:56:16 +0000 (02:56 +0000)
* libcoff-in.h (struct coff_section_alignment_entry): Define.
* coffcode.h (coff_set_custom_section_alignment): New static
function.
(coff_section_alignment_table): New static array.
(coff_new_section_hook): Use coff_set_customer_section_alignment.
* coff-go32.c (COFF_SECTION_ALIGNMENT_ENTRIES): Define.
* coff-stgo32.c (COFF_SECTION_ALIGNMENT_ENTRIES): Define.
* libcoff.h: Rebuild.

bfd/ChangeLog
bfd/coff-go32.c
bfd/coff-stgo32.c
bfd/coffcode.h
bfd/libcoff-in.h
bfd/libcoff.h

index 95532c4f98a99b3be862dc97e47d089bd6ee8883..6a8758ca280ae691b93c230522ee7977da45de72 100644 (file)
@@ -1,3 +1,14 @@
+1999-08-08  Mark Elbrecht  <snowball3@bigfoot.com>
+
+       * libcoff-in.h (struct coff_section_alignment_entry): Define.
+       * coffcode.h (coff_set_custom_section_alignment): New static
+       function.
+       (coff_section_alignment_table): New static array.
+       (coff_new_section_hook): Use coff_set_customer_section_alignment.
+       * coff-go32.c (COFF_SECTION_ALIGNMENT_ENTRIES): Define.
+       * coff-stgo32.c (COFF_SECTION_ALIGNMENT_ENTRIES): Define.
+       * libcoff.h: Rebuild.
+
 1999-08-08  Ian Lance Taylor  <ian@zembu.com>
 
        * Makefile.am: Rename .dep* files to DEP*.  Change DEP variable to
index 0b783a07a7d44bb429cc76bf73842beb0b3ff1d8..15b4e36a09300cdd0574decab0848d756746e097 100644 (file)
@@ -24,4 +24,16 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
 #define COFF_LONG_SECTION_NAMES
 #define COFF_SUPPORT_GNU_LINKONCE
 
+#define COFF_SECTION_ALIGNMENT_ENTRIES \
+{ COFF_SECTION_NAME_EXACT_MATCH (".data"), \
+  COFF_ALIGNMENT_FIELD_EMPTY, COFF_ALIGNMENT_FIELD_EMPTY, 4 }, \
+{ COFF_SECTION_NAME_EXACT_MATCH (".text"), \
+  COFF_ALIGNMENT_FIELD_EMPTY, COFF_ALIGNMENT_FIELD_EMPTY, 4 }, \
+{ COFF_SECTION_NAME_PARTIAL_MATCH (".gnu.linkonce.d"), \
+  COFF_ALIGNMENT_FIELD_EMPTY, COFF_ALIGNMENT_FIELD_EMPTY, 4 }, \
+{ COFF_SECTION_NAME_PARTIAL_MATCH (".gnu.linkonce.t"), \
+  COFF_ALIGNMENT_FIELD_EMPTY, COFF_ALIGNMENT_FIELD_EMPTY, 4 }, \
+{ COFF_SECTION_NAME_PARTIAL_MATCH (".gnu.linkonce.r"), \
+  COFF_ALIGNMENT_FIELD_EMPTY, COFF_ALIGNMENT_FIELD_EMPTY, 4 }
+
 #include "coff-i386.c"
index 9115e3c8183758b91a67b45d3a2881accef4e4f5..26dba40b5e3d3ade8ef9c5b9b55afb96cf2ed1de 100644 (file)
 #define COFF_LONG_SECTION_NAMES
 #define COFF_SUPPORT_GNU_LINKONCE
 
+#define COFF_SECTION_ALIGNMENT_ENTRIES \
+{ COFF_SECTION_NAME_EXACT_MATCH (".data"), \
+  COFF_ALIGNMENT_FIELD_EMPTY, COFF_ALIGNMENT_FIELD_EMPTY, 4 }, \
+{ COFF_SECTION_NAME_EXACT_MATCH (".text"), \
+  COFF_ALIGNMENT_FIELD_EMPTY, COFF_ALIGNMENT_FIELD_EMPTY, 4 }
+
 #include "bfd.h"
 
 /* At first the prototypes */
index 301e5f79c0ce6de4274c14b4d1efbc8ca274822e..1f393946dcb8965135a463e6fb1f9222094a020d 100644 (file)
@@ -315,6 +315,9 @@ CODE_FRAGMENT
 static long sec_to_styp_flags PARAMS ((const char *, flagword));
 static flagword styp_to_sec_flags PARAMS ((bfd *, PTR, const char *));
 static boolean coff_bad_format_hook PARAMS ((bfd *, PTR));
+static void coff_set_custom_section_alignment
+  PARAMS ((bfd *, asection *, const struct coff_section_alignment_entry *,
+          unsigned int));
 static boolean coff_new_section_hook PARAMS ((bfd *, asection *));
 static boolean coff_set_arch_mach_hook PARAMS ((bfd *, PTR));
 static boolean coff_write_relocs PARAMS ((bfd *, int));
@@ -1076,15 +1079,73 @@ coff_bad_format_hook (abfd, filehdr)
   return true;
 }
 
-/*
-   initialize a section structure with information peculiar to this
-   particular implementation of coff
-*/
+/* Check whether this section uses an alignment other than the
+   default.  */
+
+static void
+coff_set_custom_section_alignment (abfd, section, alignment_table, table_size)
+     bfd *abfd ATTRIBUTE_UNUSED;
+     asection *section;
+     const struct coff_section_alignment_entry *alignment_table;
+     const unsigned int table_size;
+{
+  const unsigned int default_alignment = COFF_DEFAULT_SECTION_ALIGNMENT_POWER;
+  unsigned int i;
+
+  for (i = 0; i < table_size; ++i)
+    {
+      const char *secname = bfd_get_section_name (abfd, section);
+      if (alignment_table[i].comparison_length == (unsigned int) -1
+         ? strcmp (alignment_table[i].name, secname) == 0
+         : strncmp (alignment_table[i].name, secname,
+                    alignment_table[i].comparison_length) == 0)
+       break;
+    }
+  if (i >= table_size)
+    return;
+
+  if (alignment_table[i].default_alignment_min != COFF_ALIGNMENT_FIELD_EMPTY
+      && default_alignment < alignment_table[i].default_alignment_min)
+    return;
+
+  if (alignment_table[i].default_alignment_max != COFF_ALIGNMENT_FIELD_EMPTY
+      && default_alignment > alignment_table[i].default_alignment_max)
+    return;
+
+  section->alignment_power = alignment_table[i].alignment_power;
+}
+
+/* Custom section alignment records.  */
+
+static const struct coff_section_alignment_entry
+coff_section_alignment_table[] =
+{
+#ifdef COFF_SECTION_ALIGNMENT_ENTRIES
+  COFF_SECTION_ALIGNMENT_ENTRIES,
+#endif
+  /* There must not be any gaps between .stabstr sections.  */
+  { COFF_SECTION_NAME_PARTIAL_MATCH (".stabstr"),
+    1, COFF_ALIGNMENT_FIELD_EMPTY, 0 },
+  /* The .stab section must be aligned to 2**2 at most, to avoid gaps.  */
+  { COFF_SECTION_NAME_PARTIAL_MATCH (".stab"),
+    3, COFF_ALIGNMENT_FIELD_EMPTY, 2 },
+  /* Similarly for the .ctors and .dtors sections.  */
+  { COFF_SECTION_NAME_EXACT_MATCH (".ctors"),
+    3, COFF_ALIGNMENT_FIELD_EMPTY, 2 },
+  { COFF_SECTION_NAME_EXACT_MATCH (".dtors"),
+    3, COFF_ALIGNMENT_FIELD_EMPTY, 2 }
+};
+
+static const unsigned int coff_section_alignment_table_size =
+  sizeof coff_section_alignment_table / sizeof coff_section_alignment_table[0];
+
+/* Initialize a section structure with information peculiar to this
+   particular implementation of COFF.  */
 
 static boolean
 coff_new_section_hook (abfd, section)
-     bfd * abfd;
-     asection * section;
+     bfd *abfd;
+     asection *section;
 {
   combined_entry_type *native;
 
@@ -1120,22 +1181,9 @@ coff_new_section_hook (abfd, section)
 
   coffsymbol (section->symbol)->native = native;
 
-  /* The .stab section must be aligned to 2**2 at most, because
-     otherwise there may be gaps in the section which gdb will not
-     know how to interpret.  Examining the section name is a hack, but
-     that is also how gdb locates the section.
-     We need to handle the .ctors and .dtors sections similarly, to
-     avoid introducing null words in the tables.  */
-  if (COFF_DEFAULT_SECTION_ALIGNMENT_POWER > 2
-      && (strncmp (section->name, ".stab", 5) == 0
-         || strcmp (section->name, ".ctors") == 0
-         || strcmp (section->name, ".dtors") == 0))
-    section->alignment_power = 2;
-
-  /* Similarly, the .stabstr section must be aligned to 2**0 at most.  */
-  if (COFF_DEFAULT_SECTION_ALIGNMENT_POWER > 0
-      && strncmp (section->name, ".stabstr", 8) == 0)
-    section->alignment_power = 0;
+  coff_set_custom_section_alignment (abfd, section,
+                                    coff_section_alignment_table,
+                                    coff_section_alignment_table_size);
 
   return true;
 }
index dae881f288c793084e8ebde279c471931beb4149..a0362ca9f105773584c64b4704532f09c0e3b511 100644 (file)
@@ -1,5 +1,5 @@
 /* BFD COFF object file private structure.
-   Copyright (C) 1990, 91, 92, 93, 94, 95, 96, 97, 1998
+   Copyright (C) 1990, 91, 92, 93, 94, 95, 96, 97, 98, 1999
    Free Software Foundation, Inc.
    Written by Cygnus Support.
 
@@ -467,6 +467,41 @@ struct coff_final_link_info
   struct internal_reloc *internal_relocs;
 };
 
+/* Most COFF variants have no way to record the alignment of a
+   section.  This struct is used to set a specific alignment based on
+   the name of the section.  */
+
+struct coff_section_alignment_entry
+{
+  /* The section name.  */
+  const char *name;
+
+  /* This is either (unsigned int) -1, indicating that the section
+     name must match exactly, or it is the number of letters which
+     must match at the start of the name.  */
+  unsigned int comparison_length;
+
+  /* These macros may be used to fill in the first two fields in a
+     structure initialization.  */
+#define COFF_SECTION_NAME_EXACT_MATCH(name) (name), ((unsigned int) -1)
+#define COFF_SECTION_NAME_PARTIAL_MATCH(name) (name), (sizeof (name) - 1)
+
+  /* Only use this entry if the default section alignment for this
+     target is at least that much (as a power of two).  If this field
+     is COFF_ALIGNMENT_FIELD_EMPTY, it should be ignored.  */
+  unsigned int default_alignment_min;
+
+  /* Only use this entry if the default section alignment for this
+     target is no greater than this (as a power of two).  If this
+     field is COFF_ALIGNMENT_FIELD_EMPTY, it should be ignored.  */
+  unsigned int default_alignment_max;
+
+#define COFF_ALIGNMENT_FIELD_EMPTY ((unsigned int) -1)
+
+  /* The desired alignment for this section (as a power of two).  */
+  unsigned int alignment_power;
+};
+
 extern struct bfd_hash_entry *_bfd_coff_link_hash_newfunc
   PARAMS ((struct bfd_hash_entry *, struct bfd_hash_table *, const char *));
 extern boolean _bfd_coff_link_hash_table_init
index 229668ed586751ab9036fbadd91e3d4dac69b000..fb3d5be73d9474244bc4a81874b0dee45877f8bc 100644 (file)
@@ -1,5 +1,5 @@
 /* BFD COFF object file private structure.
-   Copyright (C) 1990, 91, 92, 93, 94, 95, 96, 97, 1998
+   Copyright (C) 1990, 91, 92, 93, 94, 95, 96, 97, 98, 1999
    Free Software Foundation, Inc.
    Written by Cygnus Support.
 
@@ -467,6 +467,41 @@ struct coff_final_link_info
   struct internal_reloc *internal_relocs;
 };
 
+/* Most COFF variants have no way to record the alignment of a
+   section.  This struct is used to set a specific alignment based on
+   the name of the section.  */
+
+struct coff_section_alignment_entry
+{
+  /* The section name.  */
+  const char *name;
+
+  /* This is either (unsigned int) -1, indicating that the section
+     name must match exactly, or it is the number of letters which
+     must match at the start of the name.  */
+  unsigned int comparison_length;
+
+  /* These macros may be used to fill in the first two fields in a
+     structure initialization.  */
+#define COFF_SECTION_NAME_EXACT_MATCH(name) (name), ((unsigned int) -1)
+#define COFF_SECTION_NAME_PARTIAL_MATCH(name) (name), (sizeof (name) - 1)
+
+  /* Only use this entry if the default section alignment for this
+     target is at least that much (as a power of two).  If this field
+     is COFF_ALIGNMENT_FIELD_EMPTY, it should be ignored.  */
+  unsigned int default_alignment_min;
+
+  /* Only use this entry if the default section alignment for this
+     target is no greater than this (as a power of two).  If this
+     field is COFF_ALIGNMENT_FIELD_EMPTY, it should be ignored.  */
+  unsigned int default_alignment_max;
+
+#define COFF_ALIGNMENT_FIELD_EMPTY ((unsigned int) -1)
+
+  /* The desired alignment for this section (as a power of two).  */
+  unsigned int alignment_power;
+};
+
 extern struct bfd_hash_entry *_bfd_coff_link_hash_newfunc
   PARAMS ((struct bfd_hash_entry *, struct bfd_hash_table *, const char *));
 extern boolean _bfd_coff_link_hash_table_init