+/* 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>");
+ }
+
+ s = snext;
+ }
+ while (s != NULL);
+
+ return ret;
+}
+
+/* Find and optionally add an entry in the change_sections list.
+
+ We need to be careful in how we match section names because of the support
+ for wildcard characters. For example suppose that the user has invoked
+ objcopy like this:
+
+ --set-section-flags .debug_*=debug
+ --set-section-flags .debug_str=readonly,debug
+ --change-section-address .debug_*ranges=0x1000
+
+ With the idea that all debug sections will receive the DEBUG flag, the
+ .debug_str section will also receive the READONLY flag and the
+ .debug_ranges and .debug_aranges sections will have their address set to
+ 0x1000. (This may not make much sense, but it is just an example).
+
+ When adding the section name patterns to the section list we need to make
+ sure that previous entries do not match with the new entry, unless the
+ match is exact. (In which case we assume that the user is overriding
+ the previous entry with the new context).
+
+ When matching real section names to the section list we make use of the
+ wildcard characters, but we must do so in context. Eg if we are setting
+ section addresses then we match for .debug_ranges but not for .debug_info.
+
+ Finally, if ADD is false and we do find a match, we mark the section list
+ entry as used. */