+ default:
+ {
+ char *bad_msg = _("unrecognized .section attribute: want a,w,x,M,S,G,T");
+#ifdef md_elf_section_letter
+ bfd_vma md_attr = md_elf_section_letter (*str, &bad_msg);
+ if (md_attr > 0)
+ attr |= md_attr;
+ else
+#endif
+ as_fatal ("%s", bad_msg);
+ }
+ break;
+ }
+ str++, len--;
+ }
+
+ return attr;
+}
+
+static int
+obj_elf_section_type (char *str, size_t len, bfd_boolean warn)
+{
+ if (len == 8 && strncmp (str, "progbits", 8) == 0)
+ return SHT_PROGBITS;
+ if (len == 6 && strncmp (str, "nobits", 6) == 0)
+ return SHT_NOBITS;
+ if (len == 4 && strncmp (str, "note", 4) == 0)
+ return SHT_NOTE;
+ if (len == 10 && strncmp (str, "init_array", 10) == 0)
+ return SHT_INIT_ARRAY;
+ if (len == 10 && strncmp (str, "fini_array", 10) == 0)
+ return SHT_FINI_ARRAY;
+ if (len == 13 && strncmp (str, "preinit_array", 13) == 0)
+ return SHT_PREINIT_ARRAY;
+
+#ifdef md_elf_section_type
+ {
+ int md_type = md_elf_section_type (str, len);
+ if (md_type >= 0)
+ return md_type;
+ }
+#endif
+
+ if (warn)
+ as_warn (_("unrecognized section type"));
+ return 0;
+}
+
+static bfd_vma
+obj_elf_section_word (char *str, size_t len, int *type)
+{
+ int ret;
+
+ if (len == 5 && strncmp (str, "write", 5) == 0)
+ return SHF_WRITE;
+ if (len == 5 && strncmp (str, "alloc", 5) == 0)
+ return SHF_ALLOC;
+ if (len == 9 && strncmp (str, "execinstr", 9) == 0)
+ return SHF_EXECINSTR;
+ if (len == 3 && strncmp (str, "tls", 3) == 0)
+ return SHF_TLS;
+
+#ifdef md_elf_section_word
+ {
+ bfd_vma md_attr = md_elf_section_word (str, len);
+ if (md_attr > 0)
+ return md_attr;
+ }
+#endif
+
+ ret = obj_elf_section_type (str, len, FALSE);
+ if (ret != 0)
+ *type = ret;
+ else
+ as_warn (_("unrecognized section attribute"));
+
+ return 0;
+}
+
+/* Get name of section. */
+static char *
+obj_elf_section_name (void)
+{
+ char *name;
+
+ SKIP_WHITESPACE ();
+ if (*input_line_pointer == '"')
+ {
+ int dummy;
+
+ name = demand_copy_C_string (&dummy);
+ if (name == NULL)
+ {
+ ignore_rest_of_line ();
+ return NULL;
+ }
+ }
+ else
+ {
+ char *end = input_line_pointer;
+
+ while (0 == strchr ("\n\t,; ", *end))
+ end++;
+ if (end == input_line_pointer)
+ {
+ as_bad (_("missing name"));
+ ignore_rest_of_line ();
+ return NULL;
+ }
+
+ name = xmalloc (end - input_line_pointer + 1);
+ memcpy (name, input_line_pointer, end - input_line_pointer);
+ name[end - input_line_pointer] = '\0';
+#ifdef tc_canonicalize_section_name
+ name = tc_canonicalize_section_name (name);
+#endif
+ input_line_pointer = end;
+ }
+ SKIP_WHITESPACE ();
+ return name;
+}
+
+void
+obj_elf_section (int push)
+{
+ char *name, *group_name, *beg;
+ int type, dummy;
+ bfd_vma attr;
+ int entsize;
+ int linkonce;
+ subsegT new_subsection = -1;
+
+#ifndef TC_I370
+ if (flag_mri)
+ {
+ char mri_type;
+
+#ifdef md_flush_pending_output
+ md_flush_pending_output ();
+#endif
+
+ previous_section = now_seg;
+ previous_subsection = now_subseg;
+
+ s_mri_sect (&mri_type);
+
+#ifdef md_elf_section_change_hook
+ md_elf_section_change_hook ();
+#endif
+
+ return;
+ }
+#endif /* ! defined (TC_I370) */
+
+ name = obj_elf_section_name ();
+ if (name == NULL)
+ return;
+ type = SHT_NULL;
+ attr = 0;
+ group_name = NULL;
+ entsize = 0;
+ linkonce = 0;
+
+ if (*input_line_pointer == ',')
+ {
+ /* Skip the comma. */
+ ++input_line_pointer;
+ SKIP_WHITESPACE ();