+/* Get the priority of a g++ global constructor or destructor from the
+ symbol name. */
+
+static int
+ctor_prio (const char *name)
+{
+ /* The name will look something like _GLOBAL_$I$65535$test02__Fv.
+ There might be extra leading underscores, and the $ characters
+ might be something else. The I might be a D. */
+
+ while (*name == '_')
+ ++name;
+
+ if (!CONST_STRNEQ (name, "GLOBAL_"))
+ return -1;
+
+ name += sizeof "GLOBAL_" - 1;
+
+ if (name[0] != name[2])
+ return -1;
+ if (name[1] != 'I' && name[1] != 'D')
+ return -1;
+ if (!ISDIGIT (name[3]))
+ return -1;
+
+ return atoi (name + 3);
+}
+
+/* This function is used to sort constructor elements by priority. It
+ is called via qsort. */
+
+static int
+ctor_cmp (const void *p1, const void *p2)
+{
+ const struct set_element *pe1 = *(const struct set_element **) p1;
+ const struct set_element *pe2 = *(const struct set_element **) p2;
+ const char *n1;
+ const char *n2;
+ int prio1;
+ int prio2;
+
+ n1 = pe1->name;
+ if (n1 == NULL)
+ n1 = "";
+ n2 = pe2->name;
+ if (n2 == NULL)
+ n2 = "";
+
+ /* We need to sort in reverse order by priority. When two
+ constructors have the same priority, we should maintain their
+ current relative position. */
+
+ prio1 = ctor_prio (n1);
+ prio2 = ctor_prio (n2);
+
+ /* We sort in reverse order because that is what g++ expects. */
+ if (prio1 < prio2)
+ return 1;
+ if (prio1 > prio2)
+ return -1;
+
+ /* Force a stable sort. */
+ if (pe1->u.idx < pe2->u.idx)
+ return -1;
+ if (pe1->u.idx > pe2->u.idx)
+ return 1;
+ return 0;
+}
+