Index: gcc/config/arm/aout.h
===================================================================
--- gcc/config/arm/aout.h	(revision 171929)
+++ gcc/config/arm/aout.h	(working copy)
@@ -27,9 +27,13 @@
 #endif
 
 /* Switch to the text or data segment.  */
-#define TEXT_SECTION_ASM_OP  	"\t.text"
-#define DATA_SECTION_ASM_OP  	"\t.data"
-#define BSS_SECTION_ASM_OP   	"\t.bss"
+#define TEXT_SECTION_ASM_OP arm_text_section
+#define DATA_SECTION_ASM_OP arm_data_section
+#undef READONLY_DATA_SECTION_ASM_OP
+#define READONLY_DATA_SECTION_ASM_OP arm_readonly_data_section
+#define BSS_SECTION_ASM_OP arm_bss_section
+#undef TARGET_ASM_NAMED_SECTION
+#define TARGET_ASM_NAMED_SECTION arm_asm_named_section
 
 /* Note: If USER_LABEL_PREFIX or LOCAL_LABEL_PREFIX are changed,
    make sure that this change is reflected in the function
Index: gcc/config/arm/arm.c
===================================================================
--- gcc/config/arm/arm.c	(revision 171929)
+++ gcc/config/arm/arm.c	(working copy)
@@ -1050,6 +1050,11 @@
   return size_p ? 1 : current_tune->constant_limit;
 }
 
+const char *arm_text_section = "\t" ARM_DEFAULT_TEXT_SECTION_NAME;
+const char *arm_data_section = "\t" ARM_DEFAULT_DATA_SECTION_NAME;
+const char *arm_readonly_data_section = "\t.section " ARM_DEFAULT_READONLY_DATA_SECTION_NAME;
+const char *arm_bss_section = "\t" ARM_DEFAULT_BSS_SECTION_NAME;
+
 /* Emit an insn that's a simple single-set.  Both the operands must be known
    to be valid.  */
 inline static rtx
@@ -1995,6 +2000,35 @@
       flag_reorder_blocks = 1;
     }
 
+  if (strcmp(arm_text_string, ARM_DEFAULT_TEXT_SECTION_NAME))
+    {
+      #define ARM_TEXT_SECTION_FORMAT "\t.section\t%s,\"ax\",%%progbits\n"
+      char *tmp = XNEWVEC (char, strlen (arm_text_string) + sizeof (ARM_TEXT_SECTION_FORMAT) + 1);
+      sprintf (tmp, ARM_TEXT_SECTION_FORMAT, arm_text_string);
+      arm_text_section = tmp;
+    }
+  if (strcmp(arm_data_string, ARM_DEFAULT_DATA_SECTION_NAME))
+    {
+      #define ARM_DATA_SECTION_FORMAT "\t.section\t%s,\"aw\",%%progbits\n"
+      char *tmp = XNEWVEC (char, strlen (arm_data_string) + sizeof (ARM_DATA_SECTION_FORMAT) + 1);
+      sprintf (tmp, ARM_DATA_SECTION_FORMAT, arm_data_string);
+      arm_data_section = tmp;
+    }
+  if (strcmp(arm_readonly_data_string, ARM_DEFAULT_READONLY_DATA_SECTION_NAME))
+    {
+      #define ARM_READONLY_DATA_SECTION_FORMAT "\t.section\t%s,\"a\",%%progbits\n"
+      char *tmp = XNEWVEC (char, strlen (arm_data_string) + sizeof (ARM_READONLY_DATA_SECTION_FORMAT) + 1);
+      sprintf (tmp, ARM_READONLY_DATA_SECTION_FORMAT, arm_readonly_data_string);
+      arm_readonly_data_section = tmp;
+    }
+  if (strcmp(arm_bss_string, ARM_DEFAULT_BSS_SECTION_NAME))
+    {
+      #define ARM_BSS_SECTION_FORMAT "\t.section\t%s,\"aw\",%%nobits\n"
+      char *tmp = XNEWVEC (char, strlen (arm_bss_string) + sizeof (ARM_BSS_SECTION_FORMAT) + 1);
+      sprintf (tmp, ARM_BSS_SECTION_FORMAT, arm_bss_string);
+      arm_bss_section = tmp;
+    }
+
   if (flag_pic)
     /* Hoisting PIC address calculations more aggressively provides a small,
        but measurable, size reduction for PIC code.  Therefore, we decrease
@@ -2038,6 +2072,32 @@
   arm_add_gc_roots ();
 }
 
+void arm_asm_named_section (const char *name, unsigned int flags, tree t)
+{
+  char local[1024];  
+  if (strstr(name, ARM_DEFAULT_TEXT_SECTION_NAME)==name)
+    {
+      sprintf(local, "%s%s", arm_text_string, name+sizeof(ARM_DEFAULT_TEXT_SECTION_NAME)-1);
+      name = local;
+    }
+  else if (strstr(name, ARM_DEFAULT_DATA_SECTION_NAME)==name)
+    {
+      sprintf(local, "%s%s", arm_data_string, name+sizeof(ARM_DEFAULT_DATA_SECTION_NAME)-1);
+      name = local;
+    }
+  else if (strstr(name, ARM_DEFAULT_BSS_SECTION_NAME)==name)
+    {
+      sprintf(local, "%s%s", arm_bss_string, name+sizeof(ARM_DEFAULT_BSS_SECTION_NAME)-1);
+      name = local;
+    }
+  else if (strstr(name, ARM_DEFAULT_READONLY_DATA_SECTION_NAME)==name)
+    {
+      sprintf(local, "%s%s", arm_readonly_data_string, name+sizeof(ARM_DEFAULT_READONLY_DATA_SECTION_NAME)-1);
+      name = local;
+    } 
+  default_elf_asm_named_section(name, flags, t);
+}
+
 static void
 arm_add_gc_roots (void)
 {
Index: gcc/config/arm/arm.h
===================================================================
--- gcc/config/arm/arm.h	(revision 171929)
+++ gcc/config/arm/arm.h	(working copy)
@@ -1819,6 +1819,17 @@
   if (TARGET_THUMB2)			\
     thumb2_asm_output_opcode (STREAM);
 
+#define ARM_DEFAULT_TEXT_SECTION_NAME  ".text"
+#define ARM_DEFAULT_DATA_SECTION_NAME  ".data"
+#define ARM_DEFAULT_READONLY_DATA_SECTION_NAME  ".rodata"
+#define ARM_DEFAULT_BSS_SECTION_NAME ".bss"
+
+extern const char *arm_text_section;
+extern const char *arm_data_section;
+extern const char *arm_readonly_data_section;
+extern const char *arm_bss_section;
+void arm_asm_named_section (const char *name, unsigned int flags, tree t);
+
 /* The EABI specifies that constructors should go in .init_array.
    Other targets use .ctors for compatibility.  */
 #ifndef ARM_EABI_CTORS_SECTION_OP
Index: gcc/config/arm/arm.opt
===================================================================
--- gcc/config/arm/arm.opt	(revision 171929)
+++ gcc/config/arm/arm.opt	(working copy)
@@ -267,3 +267,19 @@
 munaligned-access
 Target Report Var(unaligned_access) Init(2)
 Enable unaligned word and halfword accesses to packed data.
+
+mtext=
+Target RejectNegative Joined Var(arm_text_string) Init(ARM_DEFAULT_TEXT_SECTION_NAME)
+-mtext=SECTION Put functions in SECTION
+
+mdata=
+Target RejectNegative Joined Var(arm_data_string) Init(ARM_DEFAULT_DATA_SECTION_NAME)
+-mdata=SECTION Put data in SECTION
+
+mrodata=
+Target RejectNegative Joined Var(arm_readonly_data_string) Init(ARM_DEFAULT_READONLY_DATA_SECTION_NAME)
+-mrodata=SECTION Put read-only data in SECTION
+
+mbss=
+Target RejectNegative Joined Var(arm_bss_string) Init(ARM_DEFAULT_BSS_SECTION_NAME)
+-mbss=SECTION Put zeroed data in SECTION
