The attached patches fix support for -ffunction-sections and
-fdata-sections in mspgcc 3.2.3.

  mspgcc-gcc3.3-fdata-sections.patch

    Fixes to mspgcc's gcc3.[23] support for -ffunction-sections
    and -fdata-sections.
  
  gcc-3.2.3-ffunction-section_warning.patch

    Patch to gcc-3.2.3 core that disables bogus
    -ffunction-section warning.  The right thing to do would be
    to fix mspgcc so that gcc core knows it's using the ELF
    file format, but I don't know how to do that.
  
  binutils-2.17-fdata-sections.patch

    Fixes msp430 linker script templates to support -fdata-sections.

Is this the proper forum for msp430 binutils patches, or should
I submit them directly to the binutils mailing list?

For that matter, is this the proper forum for mspgcc patches?

-- 
Grant Edwards
[email protected]
Index: gcc-3.3/gcc/config/msp430/msp430.c
===================================================================
RCS file: /cvsroot/mspgcc/gcc/gcc-3.3/gcc/config/msp430/msp430.c,v
retrieving revision 1.93
diff -U10 -r1.93 msp430.c
--- gcc-3.3/gcc/config/msp430/msp430.c  13 Feb 2007 15:24:40 -0000      1.93
+++ gcc-3.3/gcc/config/msp430/msp430.c  28 Mar 2007 19:28:11 -0000
@@ -2014,40 +2014,33 @@
 /* Sets section name for declaration DECL */
 void
 unique_section (decl, reloc)
      tree decl;
      int reloc ATTRIBUTE_UNUSED;
 {
   int len;
   const char *name, *prefix;
   char *string;
   name = IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (decl));
-  /* Strip off any encoding in name.  */
   STRIP_NAME_ENCODING (name, name);
 
-  if (TREE_CODE (decl) == FUNCTION_DECL)
-    {
-      if (flag_function_sections)
-       prefix = ".text.";
-      else
-       prefix = ".text";
-    }
-  else
-    abort ();
-
-  if (flag_function_sections)
-    {
-      len = strlen (name) + strlen (prefix);
-      string = alloca (len + 1);
-      sprintf (string, "%s%s", prefix, name);
-      DECL_SECTION_NAME (decl) = build_string (len, string);
-    }
+  if ((TREE_CODE (decl) == FUNCTION_DECL) || DECL_READONLY_SECTION (decl, 0))
+    prefix = ".text.";
+  else if ((DECL_INITIAL (decl) == 0) || (DECL_INITIAL (decl) == 
error_mark_node))
+    prefix = ".bss.";
+  else
+    prefix = ".data.";
+
+  len = strlen (name) + strlen (prefix);
+  string = alloca (len + 1);
+  sprintf (string, "%s%s", prefix, name);
+  DECL_SECTION_NAME (decl) = build_string (len, string);
 }
 
 
 /* Output section name to file FILE
    We make the section read-only and executable for a function decl,
    read-only for a const data decl, and writable for a non-const data decl.  */
 
 void
 asm_output_section_name (file, decl, name, reloc)
      FILE *file;
Index: gcc-3.3/gcc/config/msp430/msp430.h
===================================================================
RCS file: /cvsroot/mspgcc/gcc/gcc-3.3/gcc/config/msp430/msp430.h,v
retrieving revision 1.38
diff -U10 -r1.38 msp430.h
--- gcc-3.3/gcc/config/msp430/msp430.h  13 Jan 2007 14:29:50 -0000      1.38
+++ gcc-3.3/gcc/config/msp430/msp430.h  28 Mar 2007 19:28:15 -0000
@@ -2044,80 +2044,79 @@
            {                                           \
                asm_fprintf ((FILE), "_%U%s", (NAME));  \
            }                                           \
            else                                        \
                asm_fprintf ((FILE), "%U%s", (NAME));   \
        }                                               \
        else                                            \
                asm_fprintf ((FILE), "%U%s", (NAME));   \
 } while(0)
 
+/* macros to output uninitialized variable definitions */
 
+/* Return a non-zero value if DECL has a section attribute.  */
+#define IN_NAMED_SECTION(DECL)                                           \
+  ((TREE_CODE (DECL) == FUNCTION_DECL || TREE_CODE (DECL) == VAR_DECL)    \
+   && DECL_SECTION_NAME (DECL) != NULL_TREE)
+
+#undef  ASM_OUTPUT_ALIGNED_DECL_COMMON
+#define ASM_OUTPUT_ALIGNED_DECL_COMMON(FILE, DECL, NAME, SIZE, ALIGN)   \
+  do                                                                    \
+    {                                                                   \
+      char *p = NAME;                                                   \
+      if(*p == '*' || *p == '@' ) p++;                                  \
+      if(*p >= '0' && *p <= '9' ) break;                                \
+      if (IN_NAMED_SECTION (DECL))                                      \
+        named_section (DECL, NULL, 0);                                  \
+      else                                                              \
+         bss_section ();                                                \
+                                                                        \
+      ASM_GLOBALIZE_LABEL (FILE, NAME);                                 \
+      ASM_OUTPUT_ALIGN (FILE, floor_log2 (ALIGN / BITS_PER_UNIT));      \
+                                                                        \
+      last_assemble_variable_decl = DECL;                               \
+      ASM_DECLARE_OBJECT_NAME (FILE, NAME, DECL);                       \
+      ASM_OUTPUT_SKIP (FILE, SIZE ? SIZE : 1);                          \
+    }                                                                   \
+  while (0)
 
 
-#define ASM_OUTPUT_COMMON(STREAM, NAME, SIZE, ROUNDED) \
-do {                                                   \
-     char *p = NAME;                                   \
-     if(*p == '*' || *p == '@' ) p++;                  \
-     if(*p >= '0' && *p <= '9' ) break;                        \
-     fputs ("\t.comm ", (STREAM));                     \
-     assemble_name ((STREAM), (NAME));                 \
-     fprintf ((STREAM), ",%d%s", (SIZE), (SIZE)>1?",2\n":"\n");\
-} while (0)
-/* A C statement (sans semicolon) to output to the stdio stream
-   STREAM the assembler definition of a common-label named NAME whose
-   size is SIZE bytes.  The variable ROUNDED is the size rounded up
-   to whatever alignment the caller wants.
-
-   Use the expression `assemble_name (STREAM, NAME)' to output the
-   name itself; before and after that, output the additional
-   assembler syntax for defining the name, and a newline.
-
-   This macro controls how the assembler definitions of uninitialized
-   common global variables are output.  */
-
-#define ASM_OUTPUT_LOCAL(STREAM, NAME, SIZE, ROUNDED)  \
-do {                                                   \
-     char *p = NAME;                                   \
-     if(*p == '*' || *p == '@' ) p++;                  \
-     if(*p >= '0' && *p <= '9' ) break;                        \
-     fputs ("\t.local ", (STREAM));                    \
-     assemble_name ((STREAM), (NAME));                 \
-     fputs ("\n",(STREAM));                            \
-     fputs ("\t.comm ", (STREAM));                             \
-     assemble_name ((STREAM), (NAME));                 \
-     fprintf ((STREAM), ",%d%s", (SIZE),(SIZE)>1?",2\n":"\n");\
-} while (0)
-/* A C statement (sans semicolon) to output to the stdio stream
-   STREAM the assembler definition of a local-common-label named NAME
-   whose size is SIZE bytes.  The variable ROUNDED is the size
-   rounded up to whatever alignment the caller wants.
-
-   Use the expression `assemble_name (STREAM, NAME)' to output the
-   name itself; before and after that, output the additional
-   assembler syntax for defining the name, and a newline.
+#undef  ASM_OUTPUT_ALIGNED_DECL_LOCAL
+#define ASM_OUTPUT_ALIGNED_DECL_LOCAL(FILE, DECL, NAME, SIZE, ALIGN)    \
+  do                                                                    \
+    {                                                                   \
+      char *p = NAME;                                                   \
+      if(*p == '*' || *p == '@' ) p++;                                  \
+      if(*p >= '0' && *p <= '9' ) break;                                \
+      if ((DECL) != NULL && IN_NAMED_SECTION (DECL))                    \
+        named_section (DECL, NULL, 0);                                  \
+      else                                                              \
+        bss_section ();                                                 \
+                                                                        \
+      ASM_OUTPUT_ALIGN (FILE, floor_log2 (ALIGN / BITS_PER_UNIT));      \
+      ASM_OUTPUT_LABEL (FILE, NAME);                                    \
+      fprintf (FILE, "\t.space\t%d\n", SIZE);                           \
+    }                                                                   \
+  while (0)
+
 
-   This macro controls how the assembler definitions of uninitialized
-   static variables are output.  */
 
 #define BSS_SECTION_ASM_OP     "\t.section\t.bss"
 /* If defined, a C expression whose value is a string containing the
    assembler operation to identify the following data as
    uninitialized global data.  If not defined, and neither
    'ASM_OUTPUT_BSS' nor 'ASM_OUTPUT_ALIGNED_BSS' are defined,
    uninitialized global data will be output in the data section if
    -fno-common' is passed, otherwise 'ASM_OUTPUT_COMMON' will be
    used.
 */
 
-
-
 #define ASM_OUTPUT_LABEL(STREAM, NAME)         \
 {                                              \
   assemble_name (STREAM, NAME);                        \
   fprintf (STREAM, ":\n");                     \
 }
 /* A C statement (sans semicolon) to output to the stdio stream
    STREAM the assembler definition of a label named NAME.  Use the
    expression `assemble_name (STREAM, NAME)' to output the name
    itself; before and after that, output the additional assembler
    syntax for defining the name, and a newline.  */
Only in .: disable-ffunction-section_warning.patch
diff -r -U10 ../gcc-3.2.3-orig/gcc/toplev.c ./gcc/toplev.c
--- ../gcc-3.2.3-orig/gcc/toplev.c      2003-02-21 23:37:46.000000000 -0600
+++ ./gcc/toplev.c      2007-03-27 11:18:26.000000000 -0500
@@ -5031,22 +5031,22 @@
 
   /* This combination of options isn't handled for i386 targets and doesn't
      make much sense anyway, so don't allow it.  */
   if (flag_prefetch_loop_arrays && optimize_size)
     {
       warning ("-fprefetch-loop-arrays is not supported with -Os");
       flag_prefetch_loop_arrays = 0;
     }
 
 #ifndef OBJECT_FORMAT_ELF
-  if (flag_function_sections && write_symbols != NO_DEBUG)
-    warning ("-ffunction-sections may affect debugging on some targets");
+//  if (flag_function_sections && write_symbols != NO_DEBUG)
+//    warning ("-ffunction-sections may affect debugging on some targets");
 #endif
 }
 
 /* Language-independent initialization, before language-dependent
    initialization.  */
 static void
 lang_independent_init ()
 {
   decl_printable_name = decl_name;
   lang_expand_expr = (lang_expand_expr_t) do_abort;
diff -r -U9 ../binutils-2.17-orig/ld/scripttempl/elf32msp430_3.sc 
./ld/scripttempl/elf32msp430_3.sc
--- ../binutils-2.17-orig/ld/scripttempl/elf32msp430_3.sc       2003-04-09 
06:07:51.000000000 -0500
+++ ./ld/scripttempl/elf32msp430_3.sc   2007-03-28 11:38:30.000000000 -0500
@@ -69,89 +69,91 @@
   .rel.bss     ${RELOCATING-0} : { *(.rel.bss)          }
   .rela.bss    ${RELOCATING-0} : { *(.rela.bss)         }
   .rel.plt     ${RELOCATING-0} : { *(.rel.plt)          }
   .rela.plt    ${RELOCATING-0} : { *(.rela.plt)         }
 
   /* Internal text space.  */
   .text :
   {
     ${RELOCATING+. = ALIGN(2);}
-    *(.init)
-    *(.init0)  /* Start here after reset.  */
-    *(.init1)
-    *(.init2)
-    *(.init3)
-    *(.init4)
-    *(.init5)
-    *(.init6)  /* C++ constructors.  */
-    *(.init7)
-    *(.init8)
-    *(.init9)  /* Call main().  */
+    KEEP(*(.init))
+    KEEP(*(.init0))  /* Start here after reset.  */
+    KEEP(*(.init1))
+    KEEP(*(.init2))
+    KEEP(*(.init3))
+    KEEP(*(.init4))
+    KEEP(*(.init5))
+    KEEP(*(.init6))  /* C++ constructors.  */
+    KEEP(*(.init7))
+    KEEP(*(.init8))
+    KEEP(*(.init9))  /* Call main().  */
 
     ${CONSTRUCTING+ __ctors_start = . ; }
     ${CONSTRUCTING+ *(.ctors) }
     ${CONSTRUCTING+ __ctors_end = . ; }
     ${CONSTRUCTING+ __dtors_start = . ; }
     ${CONSTRUCTING+ *(.dtors) }
     ${CONSTRUCTING+ __dtors_end = . ; }
 
     ${RELOCATING+. = ALIGN(2);}
     *(.text)
     ${RELOCATING+. = ALIGN(2);}
     *(.text.*)
 
     ${RELOCATING+. = ALIGN(2);}
-    *(.fini9)
-    *(.fini8)
-    *(.fini7)
-    *(.fini6)  /* C++ destructors.  */
-    *(.fini5)
-    *(.fini4)
-    *(.fini3)
-    *(.fini2)
-    *(.fini1)
-    *(.fini0)  /* Infinite loop after program termination.  */
-    *(.fini)
+    KEEP(*(.fini9))
+    KEEP(*(.fini8))
+    KEEP(*(.fini7))
+    KEEP(*(.fini6))  /* C++ destructors.  */
+    KEEP(*(.fini5))
+    KEEP(*(.fini4))
+    KEEP(*(.fini3))
+    KEEP(*(.fini2))
+    KEEP(*(.fini1))
+    KEEP(*(.fini0))  /* Infinite loop after program termination.  */
+    KEEP(*(.fini))
 
     ${RELOCATING+ _etext = . ; }
   } ${RELOCATING+ > text}
 
   .data ${RELOCATING-0} : ${RELOCATING+AT (ADDR (.text) + SIZEOF (.text))}
   {  
     ${RELOCATING+ PROVIDE (__data_start = .) ; }
     *(.data)
+    *(SORT_BY_ALIGNMENT(.data.*))
     *(.gnu.linkonce.d*)
     ${RELOCATING+. = ALIGN(2);}
     ${RELOCATING+ _edata = . ; }
   } ${RELOCATING+ > data}
   
   .bss ${RELOCATING+ SIZEOF(.data) + ADDR(.data)} :
   {
     ${RELOCATING+ PROVIDE (__bss_start = .) ; }
     *(.bss)
+    *(SORT_BY_ALIGNMENT(.bss.*))
     *(COMMON)
     ${RELOCATING+ PROVIDE (__bss_end = .) ; }
     ${RELOCATING+ _end = . ;  }
   } ${RELOCATING+ > data}
 
   .noinit ${RELOCATING+ SIZEOF(.bss) + ADDR(.bss)} :
   {
     ${RELOCATING+ PROVIDE (__noinit_start = .) ; }
     *(.noinit)
     *(COMMON)
     ${RELOCATING+ PROVIDE (__noinit_end = .) ; }
     ${RELOCATING+ _end = . ;  }
   } ${RELOCATING+ > data}
 
   .vectors ${RELOCATING-0}:
   {
     ${RELOCATING+ PROVIDE (__vectors_start = .) ; }
-    *(.vectors*)
+    KEEP(*(.vectors*))
     ${RELOCATING+ _vectors_end = . ; }
   } ${RELOCATING+ > vectors}
 
   /* Stabs debugging sections.  */
   .stab 0 : { *(.stab) } 
   .stabstr 0 : { *(.stabstr) }
   .stab.excl 0 : { *(.stab.excl) }
   .stab.exclstr 0 : { *(.stab.exclstr) }
   .stab.index 0 : { *(.stab.index) }
diff -r -U9 ../binutils-2.17-orig/ld/scripttempl/elf32msp430.sc 
./ld/scripttempl/elf32msp430.sc
--- ../binutils-2.17-orig/ld/scripttempl/elf32msp430.sc 2004-08-25 
07:54:10.000000000 -0500
+++ ./ld/scripttempl/elf32msp430.sc     2007-03-28 11:41:49.000000000 -0500
@@ -93,63 +93,64 @@
   .rel.bss     ${RELOCATING-0} : { *(.rel.bss)          }
   .rela.bss    ${RELOCATING-0} : { *(.rela.bss)         }
   .rel.plt     ${RELOCATING-0} : { *(.rel.plt)          }
   .rela.plt    ${RELOCATING-0} : { *(.rela.plt)         }
 
   /* Internal text space.  */
   .text :
   {
     ${RELOCATING+. = ALIGN(2);}
-    *(.init)
-    *(.init0)  /* Start here after reset.  */
-    *(.init1)
-    *(.init2)  /* Copy data loop  */
-    *(.init3)
-    *(.init4)  /* Clear bss  */
-    *(.init5)
-    *(.init6)  /* C++ constructors.  */
-    *(.init7)
-    *(.init8)
-    *(.init9)  /* Call main().  */
+    KEEP(*(.init))
+    KEEP(*(.init0))  /* Start here after reset.  */
+    KEEP(*(.init1))
+    KEEP(*(.init2))  /* Copy data loop */
+    KEEP(*(.init3))
+    KEEP(*(.init4))  /* Clear bss */
+    KEEP(*(.init5))
+    KEEP(*(.init6))  /* C++ constructors.  */
+    KEEP(*(.init7))
+    KEEP(*(.init8))
+    KEEP(*(.init9))  /* Call main().  */
 
     ${CONSTRUCTING+ __ctors_start = . ; }
     ${CONSTRUCTING+ *(.ctors) }
     ${CONSTRUCTING+ __ctors_end = . ; }
     ${CONSTRUCTING+ __dtors_start = . ; }
     ${CONSTRUCTING+ *(.dtors) }
     ${CONSTRUCTING+ __dtors_end = . ; }
 
     ${RELOCATING+. = ALIGN(2);}
     *(.text)
     ${RELOCATING+. = ALIGN(2);}
     *(.text.*)
 
     ${RELOCATING+. = ALIGN(2);}
-    *(.fini9)  /*   */
-    *(.fini8)
-    *(.fini7)
-    *(.fini6)  /* C++ destructors.  */
-    *(.fini5)
-    *(.fini4)
-    *(.fini3)
-    *(.fini2)
-    *(.fini1)
-    *(.fini0)  /* Infinite loop after program termination.  */
-    *(.fini)
+    KEEP(*(.fini9))
+    KEEP(*(.fini8))
+    KEEP(*(.fini7))
+    KEEP(*(.fini6))  /* C++ destructors.  */
+    KEEP(*(.fini5))
+    KEEP(*(.fini4))
+    KEEP(*(.fini3))
+    KEEP(*(.fini2))
+    KEEP(*(.fini1))
+    KEEP(*(.fini0))  /* Infinite loop after program termination.  */
+    KEEP(*(.fini))
 
     _etext = .;
   } ${RELOCATING+ > text}
 
   .data ${RELOCATING-0} : ${RELOCATING+AT (ADDR (.text) + SIZEOF (.text))}
   {  
     ${RELOCATING+ PROVIDE (__data_start = .) ; }
     ${RELOCATING+. = ALIGN(2);}
     *(.data)
+    *(SORT_BY_ALIGNMENT(.data.*))
     ${RELOCATING+. = ALIGN(2);}
     *(.gnu.linkonce.d*)
     ${RELOCATING+. = ALIGN(2);}
     ${RELOCATING+ _edata = . ; }
   } ${RELOCATING+ > data}
   
   /* Bootloader.  */
   .bootloader ${RELOCATING-0} :
   {
@@ -173,36 +174,37 @@
     *(.infomemnobits)
     ${RELOCATING+. = ALIGN(2);}
     *(.infomemnobits.*)
   } ${RELOCATING+ > infomemnobits}
 
   .bss ${RELOCATING+ SIZEOF(.data) + ADDR(.data)} :
   {
     ${RELOCATING+ PROVIDE (__bss_start = .) ; }
     *(.bss)
+    *(SORT_BY_ALIGNMENT(.bss.*))
     *(COMMON)
     ${RELOCATING+ PROVIDE (__bss_end = .) ; }
     ${RELOCATING+ _end = . ;  }
   } ${RELOCATING+ > data}
 
   .noinit ${RELOCATING+ SIZEOF(.bss) + ADDR(.bss)} :
   {
     ${RELOCATING+ PROVIDE (__noinit_start = .) ; }
     *(.noinit)
     *(COMMON)
     ${RELOCATING+ PROVIDE (__noinit_end = .) ; }
     ${RELOCATING+ _end = . ;  }
   } ${RELOCATING+ > data}
 
   .vectors ${RELOCATING-0}:
   {
     ${RELOCATING+ PROVIDE (__vectors_start = .) ; }
-    *(.vectors*)
+    KEEP(*(.vectors*))
     ${RELOCATING+ _vectors_end = . ; }
   } ${RELOCATING+ > vectors}
 
   ${HEAP_SECTION_MSP430}
 
   /* Stabs for profiling information*/
   .profiler 0 : { *(.profiler) }
   
   /* Stabs debugging sections.  */

Reply via email to