]> git.ipfire.org Git - thirdparty/binutils-gdb.git/blobdiff - ld/ldlang.c
ld: Support input section description keyword: REVERSE
[thirdparty/binutils-gdb.git] / ld / ldlang.c
index c20247a27d0d3b109c8197f817df92a695c89caf..566c2b8326ffe56e30048e5e9eb764ffe6ff1b08 100644 (file)
@@ -539,7 +539,7 @@ get_init_priority (const asection *sec)
 /* Compare sections ASEC and BSEC according to SORT.  */
 
 static int
-compare_section (sort_type sort, asection *asec, asection *bsec)
+compare_section (sort_type sort, asection *asec, asection *bsec, bool reversed)
 {
   int ret;
   int a_priority, b_priority;
@@ -554,7 +554,10 @@ compare_section (sort_type sort, asection *asec, asection *bsec)
       b_priority = get_init_priority (bsec);
       if (a_priority < 0 || b_priority < 0)
        goto sort_by_name;
-      ret = a_priority - b_priority;
+      if (reversed)
+       ret = b_priority - a_priority;
+      else
+       ret = a_priority - b_priority;
       if (ret)
        break;
       else
@@ -568,11 +571,17 @@ compare_section (sort_type sort, asection *asec, asection *bsec)
 
     case by_name:
     sort_by_name:
-      ret = strcmp (bfd_section_name (asec), bfd_section_name (bsec));
+      if (reversed)
+       ret = strcmp (bfd_section_name (bsec), bfd_section_name (asec));
+      else
+       ret = strcmp (bfd_section_name (asec), bfd_section_name (bsec));
       break;
 
     case by_name_alignment:
-      ret = strcmp (bfd_section_name (asec), bfd_section_name (bsec));
+      if (reversed)
+       ret = strcmp (bfd_section_name (bsec), bfd_section_name (asec));
+      else
+       ret = strcmp (bfd_section_name (asec), bfd_section_name (bsec));
       if (ret)
        break;
       /* Fall through.  */
@@ -647,7 +656,11 @@ wild_sort (lang_wild_statement_type *wild,
          else
            ln = sort_filename (lsec->owner);
 
-         i = filename_cmp (fn, ln);
+         if (wild->filenames_reversed)
+           i = filename_cmp (ln, fn);
+         else
+           i = filename_cmp (fn, ln);
+
          if (i > 0)
            { tree = &((*tree)->right); continue; }
          else if (i < 0)
@@ -660,7 +673,11 @@ wild_sort (lang_wild_statement_type *wild,
              if (la)
                ln = sort_filename (lsec->owner);
 
-             i = filename_cmp (fn, ln);
+             if (wild->filenames_reversed)
+               i = filename_cmp (ln, fn);
+             else
+               i = filename_cmp (fn, ln);
+             
              if (i > 0)
                { tree = &((*tree)->right); continue; }
              else if (i < 0)
@@ -673,7 +690,7 @@ wild_sort (lang_wild_statement_type *wild,
 
       /* Find the correct node to append this section.  */
       if (sec && sec->spec.sorted != none && sec->spec.sorted != by_none
-         && compare_section (sec->spec.sorted, section, (*tree)->section) < 0)
+         && compare_section (sec->spec.sorted, section, (*tree)->section, sec->spec.reversed) < 0)
        tree = &((*tree)->left);
       else
        tree = &((*tree)->right);
@@ -5151,10 +5168,14 @@ print_wild_statement (lang_wild_statement_type *w,
 
   if (w->filenames_sorted)
     minfo ("SORT_BY_NAME(");
+  if (w->filenames_reversed)
+    minfo ("REVERSE(");
   if (w->filename != NULL)
     minfo ("%s", w->filename);
   else
     minfo ("*");
+  if (w->filenames_reversed)
+    minfo (")");
   if (w->filenames_sorted)
     minfo (")");
 
@@ -5199,6 +5220,12 @@ print_wild_statement (lang_wild_statement_type *w,
          break;
        }
 
+      if (sec->spec.reversed)
+       {
+         minfo ("REVERSE(");
+         closing_paren++;
+       }
+
       if (sec->spec.exclude_name_list != NULL)
        {
          name_list *tmp;
@@ -8500,9 +8527,10 @@ lang_add_wild (struct wildcard_spec *filespec,
   if (filespec != NULL)
     {
       new_stmt->filename = filespec->name;
-      new_stmt->filenames_sorted = filespec->sorted == by_name;
+      new_stmt->filenames_sorted = (filespec->sorted == by_name || filespec->reversed);
       new_stmt->section_flag_list = filespec->section_flag_list;
       new_stmt->exclude_name_list = filespec->exclude_name_list;
+      new_stmt->filenames_reversed = filespec->reversed;
     }
   new_stmt->section_list = section_list;
   new_stmt->keep_sections = keep_sections;