+// Return a relative priority of the section with the specified NAME
+// (a lower value meand a higher priority), or 0 if it should be compared
+// with others as strings.
+// The implementation of this function is copied from ld/ldlang.c.
+
+unsigned long
+Input_section_sorter::get_init_priority(const char* name)
+{
+ char* end;
+ unsigned long init_priority;
+
+ // GCC uses the following section names for the init_priority
+ // attribute with numerical values 101 and 65535 inclusive. A
+ // lower value means a higher priority.
+ //
+ // 1: .init_array.NNNN/.fini_array.NNNN: Where NNNN is the
+ // decimal numerical value of the init_priority attribute.
+ // The order of execution in .init_array is forward and
+ // .fini_array is backward.
+ // 2: .ctors.NNNN/.dtors.NNNN: Where NNNN is 65535 minus the
+ // decimal numerical value of the init_priority attribute.
+ // The order of execution in .ctors is backward and .dtors
+ // is forward.
+
+ if (strncmp(name, ".init_array.", 12) == 0
+ || strncmp(name, ".fini_array.", 12) == 0)
+ {
+ init_priority = strtoul(name + 12, &end, 10);
+ return *end ? 0 : init_priority;
+ }
+ else if (strncmp(name, ".ctors.", 7) == 0
+ || strncmp(name, ".dtors.", 7) == 0)
+ {
+ init_priority = strtoul(name + 7, &end, 10);
+ return *end ? 0 : 65535 - init_priority;
+ }
+
+ return 0;
+}
+