{
       asection *snew, *as;
       bfd_boolean place_after = place->stmt == NULL;
+      bfd_boolean insert_after = TRUE;
 
       snew = os->bfd_section;
 
          asection *after_sec;
          /* True if we need to insert the orphan section after a
             specific section to maintain output note section order.  */
-         bfd_boolean after_sec_note;
+         bfd_boolean after_sec_note = FALSE;
+
+         static asection *first_orphan_note = NULL;
 
          /* Group and sort output note section by alignments in
             ascending order.  */
          if (elf_section_type (s) == SHT_NOTE
              && (s->flags & SEC_LOAD) != 0)
            {
-             /* Search forward for the last output note section
-                with equal or larger alignments.  */
-             asection *first_note = NULL;
+             /* Search from the beginning for the last output note
+                section with equal or larger alignments.  NB: Don't
+                place orphan note section after non-note sections.  */
 
-             for (sec = as;
+             first_orphan_note = NULL;
+             for (sec = link_info.output_bfd->sections;
                   (sec != NULL
                    && !bfd_is_abs_section (sec));
                   sec = sec->next)
                    && elf_section_type (sec) == SHT_NOTE
                    && (sec->flags & SEC_LOAD) != 0)
                  {
-                   if (!first_note)
-                     first_note = sec;
+                   if (!first_orphan_note)
+                     first_orphan_note = sec;
                    if (sec->alignment_power >= s->alignment_power)
                      after_sec = sec;
                  }
+               else if (first_orphan_note)
+                 {
+                   /* Stop if there is non-note section after the first
+                      orphan note section.  */
+                   break;
+                 }
 
-             if (after_sec)
-               after_sec_note = TRUE;
-             else
+             /* If this will be the first orphan note section, it can
+                be placed at the default location.  */
+             after_sec_note = first_orphan_note != NULL;
+             if (after_sec == NULL && after_sec_note)
                {
-                 /* Search backward for the first output note section
-                    as well as the last output note section with equal
-                    or larger alignments.  */
-                 after_sec = NULL;
-                 for (sec = as;
-                      (sec != NULL
-                       && !bfd_is_abs_section (sec));
-                      sec = sec->prev)
-                   if (sec != snew
-                       && elf_section_type (sec) == SHT_NOTE
-                       && (sec->flags & SEC_LOAD) != 0)
-                     {
-                       first_note = sec;
-                       if (!after_sec
-                           && sec->alignment_power >= s->alignment_power)
-                         after_sec = sec;
-                     }
-
-                 /* If this will be the first note section, it can be
-                    placed at the default location.  */
-                 after_sec_note = first_note != NULL;
-                 if (after_sec == NULL && after_sec_note)
-                   {
-                     /* If all output note sections have smaller
-                        alignments, place the section before all
-                        output note sections.  AFTER_SEC will be
-                        NULL if FIRST_NOTE is the first output
-                        section.  */
-                     after_sec = first_note->prev;
-                   }
+                 /* If all output note sections have smaller
+                    alignments, place the section before all
+                    output orphan note sections.  */
+                 after_sec = first_orphan_note;
+                 insert_after = FALSE;
                }
            }
-         else
+         else if (first_orphan_note)
            {
-             /* Don't place non-note sections in the middle of note
-                sections.  */
+             /* Don't place non-note sections in the middle of orphan
+                note sections.  */
              after_sec_note = TRUE;
              after_sec = as;
              for (sec = as->next;
            {
              if (after_sec)
                {
-                 /* Insert OS after AFTER_SEC output statement.  */
-                 lang_output_section_statement_type *stmt;
-                 for (stmt = after;
-                      stmt != NULL;
-                      stmt = stmt->next)
-                   if (stmt->bfd_section == after_sec)
+                 /* Search forward to insert OS after AFTER_SEC output
+                    statement.  */
+                 lang_output_section_statement_type *stmt, *next;
+                 bfd_boolean found = FALSE;
+                 for (stmt = after; stmt != NULL; stmt = next)
+                   {
+                     next = stmt->next;
+                     if (insert_after)
+                       {
+                         if (stmt->bfd_section == after_sec)
+                           {
+                             place_after = TRUE;
+                             found = TRUE;
+                             after = stmt;
+                             break;
+                           }
+                       }
+                     else
+                       {
+                         /* If INSERT_AFTER is FALSE, place OS before
+                            AFTER_SEC output statement.  */
+                         if (next && next->bfd_section == after_sec)
+                           {
+                             place_after = TRUE;
+                             found = TRUE;
+                             after = stmt;
+                             break;
+                           }
+                       }
+                   }
+
+                 /* Search backward to insert OS after AFTER_SEC output
+                    statement.  */
+                 if (!found)
+                   for (stmt = after; stmt != NULL; stmt = stmt->prev)
                      {
-                       place_after = TRUE;
-                       after = stmt;
-                       break;
+                       if (insert_after)
+                         {
+                           if (stmt->bfd_section == after_sec)
+                             {
+                               place_after = TRUE;
+                               after = stmt;
+                               break;
+                             }
+                         }
+                       else
+                         {
+                           /* If INSERT_AFTER is FALSE, place OS before
+                              AFTER_SEC output statement.  */
+                           if (stmt->next->bfd_section == after_sec)
+                             {
+                               place_after = TRUE;
+                               after = stmt;
+                               break;
+                             }
+                         }
                      }
                }
 
-             if (after_sec == NULL || after_sec->next != snew)
+             if (after_sec == NULL
+                 || (insert_after && after_sec->next != snew)
+                 || (!insert_after && after_sec->prev != snew))
                {
                  /* Unlink the section.  */
                  bfd_section_list_remove (link_info.output_bfd, snew);
                  /* Place SNEW after AFTER_SEC.  If AFTER_SEC is NULL,
                     prepend SNEW.  */
                  if (after_sec)
-                   bfd_section_list_insert_after (link_info.output_bfd,
-                                                  after_sec, snew);
+                   {
+                     if (insert_after)
+                       bfd_section_list_insert_after (link_info.output_bfd,
+                                                      after_sec, snew);
+                     else
+                       bfd_section_list_insert_before (link_info.output_bfd,
+                                                      after_sec, snew);
+                   }
                  else
                    bfd_section_list_prepend (link_info.output_bfd, snew);
                }