+/* This sorting function is used to get the notes into an order
+ that makes merging easy. */
+
+static int
+compare_gnu_build_notes (const void * data1, const void * data2)
+{
+ objcopy_internal_note * pnote1 = (objcopy_internal_note *) data1;
+ objcopy_internal_note * pnote2 = (objcopy_internal_note *) data2;
+
+ /* Sort notes based upon the attribute they record. */
+ int cmp = memcmp (pnote1->note.namedata + 3,
+ pnote2->note.namedata + 3,
+ pnote1->note.namesz < pnote2->note.namesz ?
+ pnote1->note.namesz - 3 : pnote2->note.namesz - 3);
+ if (cmp)
+ return cmp;
+
+ if (pnote1->end < pnote2->start)
+ return -1;
+ if (pnote1->start > pnote2->end)
+ return 1;
+
+ /* Overlaps - we should merge the two ranges. */
+ if (pnote1->start < pnote2->start)
+ return -1;
+ if (pnote1->end > pnote2->end)
+ return 1;
+ if (pnote1->end < pnote2->end)
+ return -1;
+
+ /* Put OPEN notes before function notes. */
+ if (is_open_note (pnote1) && ! is_open_note (pnote2))
+ return -1;
+ if (! is_open_note (pnote1) && is_open_note (pnote2))
+ return 1;
+
+ return 0;
+}
+
+/* This sorting function is used to get the notes into an order
+ that makes eliminating address ranges easier. */
+
+static int
+sort_gnu_build_notes (const void * data1, const void * data2)
+{
+ objcopy_internal_note * pnote1 = (objcopy_internal_note *) data1;
+ objcopy_internal_note * pnote2 = (objcopy_internal_note *) data2;
+
+ if (pnote1->note.type != pnote2->note.type)
+ {
+ /* Move deleted notes to the end. */
+ if (is_deleted_note (pnote1)) /* 1: OFD 2: OFD */
+ return 1;
+
+ /* Move OPEN notes to the start. */
+ if (is_open_note (pnote1)) /* 1: OF 2: OFD */
+ return -1;
+
+ if (is_deleted_note (pnote2)) /* 1: F 2: O D */
+ return -1;
+
+ return 1; /* 1: F 2: O */
+ }
+
+ /* Sort by starting address. */
+ if (pnote1->start < pnote2->start)
+ return -1;
+ if (pnote1->start > pnote2->start)
+ return 1;
+
+ /* Then by end address (bigger range first). */
+ if (pnote1->end > pnote2->end)
+ return -1;
+ if (pnote1->end < pnote2->end)
+ return 1;
+
+ /* Then by attribute type. */
+ if (pnote1->note.namesz > 4
+ && pnote2->note.namesz > 4
+ && pnote1->note.namedata[3] != pnote2->note.namedata[3])
+ return pnote1->note.namedata[3] - pnote2->note.namedata[3];
+
+ return 0;
+}
+