+ "alloc, load, noload, readonly, debug, code, data, rom, share, contents, merge, strings");
+ }
+
+ s = snext;
+ }
+ while (s != NULL);
+
+ return ret;
+}
+
+/* Parse symbol flags into a flagword, with a fatal error if the
+ string can't be parsed. */
+
+static flagword
+parse_symflags (const char *s, char **other)
+{
+ flagword ret;
+ const char *snext;
+ size_t len;
+
+ ret = BSF_NO_FLAGS;
+
+ do
+ {
+ snext = strchr (s, ',');
+ if (snext == NULL)
+ len = strlen (s);
+ else
+ {
+ len = snext - s;
+ ++snext;
+ }
+
+#define PARSE_FLAG(fname, fval) \
+ else if (len == sizeof fname - 1 \
+ && strncasecmp (fname, s, len) == 0) \
+ ret |= fval
+
+#define PARSE_OTHER(fname, fval) \
+ else if (len >= sizeof fname \
+ && strncasecmp (fname, s, sizeof fname - 1) == 0) \
+ fval = xstrndup (s + sizeof fname - 1, len - sizeof fname + 1)
+
+ if (0) ;
+ PARSE_FLAG ("local", BSF_LOCAL);
+ PARSE_FLAG ("global", BSF_GLOBAL);
+ PARSE_FLAG ("export", BSF_EXPORT);
+ PARSE_FLAG ("debug", BSF_DEBUGGING);
+ PARSE_FLAG ("function", BSF_FUNCTION);
+ PARSE_FLAG ("weak", BSF_WEAK);
+ PARSE_FLAG ("section", BSF_SECTION_SYM);
+ PARSE_FLAG ("constructor", BSF_CONSTRUCTOR);
+ PARSE_FLAG ("warning", BSF_WARNING);
+ PARSE_FLAG ("indirect", BSF_INDIRECT);
+ PARSE_FLAG ("file", BSF_FILE);
+ PARSE_FLAG ("object", BSF_OBJECT);
+ PARSE_FLAG ("synthetic", BSF_SYNTHETIC);
+ PARSE_FLAG ("indirect-function", BSF_GNU_INDIRECT_FUNCTION | BSF_FUNCTION);
+ PARSE_FLAG ("unique-object", BSF_GNU_UNIQUE | BSF_OBJECT);
+ PARSE_OTHER ("before=", *other);
+
+#undef PARSE_FLAG
+#undef PARSE_OTHER
+ else
+ {
+ char *copy;
+
+ copy = (char *) xmalloc (len + 1);
+ strncpy (copy, s, len);
+ copy[len] = '\0';
+ non_fatal (_("unrecognized symbol flag `%s'"), copy);
+ fatal (_("supported flags: %s"),
+ "local, global, export, debug, function, weak, section, "
+ "constructor, warning, indirect, file, object, synthetic, "
+ "indirect-function, unique-object, before=<othersym>");