ld: Support input section description keyword: REVERSE

PR 27565
  * ldlex.l: Add REVERSE.
  * ldgram.y: Allow REVERSE to be used wherever a sorting command can be used.
  * ld.h (struct wildcard_spec): Add 'reversed' field.
  * ldlang.h (lang_wild_statement_struct): Add 'filenames_reversed' field.
  * ldlang.c (compare_sections): Add reversed parameter. (wild_sort): Reverse the comparison if requested. (print_wild_statement): Handle the reversed field.
  * ld.texi: Document the new feature.
  * NEWS: Mention the new feature.
  * testsuite/ld-scripts/sort-file-reversed-1.d: New test driver.
  * testsuite/ld-scripts/sort-file-reversed-1.t: New test source.
  * testsuite/ld-scripts/sort-file-reversed-2.t: New test source.
  * testsuite/ld-scripts/sort-file-reversed-2.d: New test driver.
  * testsuite/ld-scripts/sort-sections-reversed-1.d: New test driver.
  * testsuite/ld-scripts/sort-sections-reversed-1.t: New test source.
  * testsuite/ld-scripts/sort-sections-reversed-2.t: New test source.
  * testsuite/ld-scripts/sort-sections-reversed-2.d: New test driver.
  * testsuite/ld-scripts/sort-sections-reversed-3.d: New test driver.
  * testsuite/ld-scripts/sort-sections-reversed-3.t: New test source.
This commit is contained in:
Nick Clifton
2023-11-01 13:51:17 +00:00
parent f514e6e480
commit 85921e9a25
18 changed files with 274 additions and 39 deletions

View 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;