Only use wild_sort_fast
there's no reason why the tree-based variant can't always be used when sorting is required, it merely needs to also support filename sorting and have a fast path for insertion at end (aka rightmost tree leaf). The filename sorting isn't tested anywhere and the only scripttempl that uses it is avr (for 'SORT(*)(.ctors)'), and I believe even there it was a mistake. Either way, this adds a testcase for filename sorting as well. Then the non-BST based sorting can be simplified to only support the fast case of no sorting required at all (at the same time renaming the two variants to _sort and _nosort).
This commit is contained in:
parent
049522cae9
commit
af31506c31
302
ld/ldlang.c
302
ld/ldlang.c
@ -556,30 +556,92 @@ compare_section (sort_type sort, asection *asec, asection *bsec)
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Build a Binary Search Tree to sort sections, unlike insertion sort
|
/* PE puts the sort key in the input statement. */
|
||||||
used in wild_sort(). BST is considerably faster if the number of
|
|
||||||
of sections are large. */
|
static const char *
|
||||||
|
sort_filename (bfd *abfd)
|
||||||
|
{
|
||||||
|
lang_input_statement_type *is = bfd_usrdata (abfd);
|
||||||
|
if (is->sort_key)
|
||||||
|
return is->sort_key;
|
||||||
|
return bfd_get_filename (abfd);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Handle wildcard sorting. This returns the place in a binary search tree
|
||||||
|
where this FILE:SECTION should be inserted for wild statement WILD where
|
||||||
|
the spec SEC was the matching one. The tree is later linearized. */
|
||||||
|
|
||||||
static lang_section_bst_type **
|
static lang_section_bst_type **
|
||||||
wild_sort_fast (lang_wild_statement_type *wild,
|
wild_sort (lang_wild_statement_type *wild,
|
||||||
struct wildcard_list *sec,
|
struct wildcard_list *sec,
|
||||||
lang_input_statement_type *file ATTRIBUTE_UNUSED,
|
lang_input_statement_type *file,
|
||||||
asection *section)
|
asection *section)
|
||||||
{
|
{
|
||||||
lang_section_bst_type **tree;
|
lang_section_bst_type **tree;
|
||||||
|
|
||||||
tree = &wild->tree;
|
|
||||||
if (!wild->filenames_sorted
|
if (!wild->filenames_sorted
|
||||||
&& (sec == NULL || sec->spec.sorted == none))
|
&& (sec == NULL || sec->spec.sorted == none
|
||||||
|
|| sec->spec.sorted == by_none))
|
||||||
{
|
{
|
||||||
/* Append at the right end of tree. */
|
/* We might be called even if _this_ spec doesn't need sorting,
|
||||||
while (*tree)
|
in which case we simply append at the right end of tree. */
|
||||||
tree = &((*tree)->right);
|
return wild->rightmost;
|
||||||
return tree;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
tree = &wild->tree;
|
||||||
while (*tree)
|
while (*tree)
|
||||||
{
|
{
|
||||||
|
/* Sorting by filename takes precedence over sorting by section
|
||||||
|
name. */
|
||||||
|
|
||||||
|
if (wild->filenames_sorted)
|
||||||
|
{
|
||||||
|
const char *fn, *ln;
|
||||||
|
bool fa, la;
|
||||||
|
int i;
|
||||||
|
asection *lsec = (*tree)->section;
|
||||||
|
|
||||||
|
/* The PE support for the .idata section as generated by
|
||||||
|
dlltool assumes that files will be sorted by the name of
|
||||||
|
the archive and then the name of the file within the
|
||||||
|
archive. */
|
||||||
|
|
||||||
|
fa = file->the_bfd->my_archive != NULL;
|
||||||
|
if (fa)
|
||||||
|
fn = sort_filename (file->the_bfd->my_archive);
|
||||||
|
else
|
||||||
|
fn = sort_filename (file->the_bfd);
|
||||||
|
|
||||||
|
la = lsec->owner->my_archive != NULL;
|
||||||
|
if (la)
|
||||||
|
ln = sort_filename (lsec->owner->my_archive);
|
||||||
|
else
|
||||||
|
ln = sort_filename (lsec->owner);
|
||||||
|
|
||||||
|
i = filename_cmp (fn, ln);
|
||||||
|
if (i > 0)
|
||||||
|
{ tree = &((*tree)->right); continue; }
|
||||||
|
else if (i < 0)
|
||||||
|
{ tree = &((*tree)->left); continue; }
|
||||||
|
|
||||||
|
if (fa || la)
|
||||||
|
{
|
||||||
|
if (fa)
|
||||||
|
fn = sort_filename (file->the_bfd);
|
||||||
|
if (la)
|
||||||
|
ln = sort_filename (lsec->owner);
|
||||||
|
|
||||||
|
i = filename_cmp (fn, ln);
|
||||||
|
if (i > 0)
|
||||||
|
{ tree = &((*tree)->right); continue; }
|
||||||
|
else if (i < 0)
|
||||||
|
{ tree = &((*tree)->left); continue; }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Here either the files are not sorted by name, or we are
|
||||||
|
looking at the sections for this file. */
|
||||||
|
|
||||||
/* Find the correct node to append this section. */
|
/* Find the correct node to append this section. */
|
||||||
if (compare_section (sec->spec.sorted, section, (*tree)->section) < 0)
|
if (compare_section (sec->spec.sorted, section, (*tree)->section) < 0)
|
||||||
tree = &((*tree)->left);
|
tree = &((*tree)->left);
|
||||||
@ -590,10 +652,10 @@ wild_sort_fast (lang_wild_statement_type *wild,
|
|||||||
return tree;
|
return tree;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Use wild_sort_fast to build a BST to sort sections. */
|
/* Use wild_sort to build a BST to sort sections. */
|
||||||
|
|
||||||
static void
|
static void
|
||||||
output_section_callback_fast (lang_wild_statement_type *ptr,
|
output_section_callback_sort (lang_wild_statement_type *ptr,
|
||||||
struct wildcard_list *sec,
|
struct wildcard_list *sec,
|
||||||
asection *section,
|
asection *section,
|
||||||
lang_input_statement_type *file,
|
lang_input_statement_type *file,
|
||||||
@ -614,9 +676,13 @@ output_section_callback_fast (lang_wild_statement_type *ptr,
|
|||||||
node->section = section;
|
node->section = section;
|
||||||
node->pattern = ptr->section_list;
|
node->pattern = ptr->section_list;
|
||||||
|
|
||||||
tree = wild_sort_fast (ptr, sec, file, section);
|
tree = wild_sort (ptr, sec, file, section);
|
||||||
if (tree != NULL)
|
if (tree != NULL)
|
||||||
*tree = node;
|
{
|
||||||
|
*tree = node;
|
||||||
|
if (tree == ptr->rightmost)
|
||||||
|
ptr->rightmost = &node->right;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Convert a sorted sections' BST back to list form. */
|
/* Convert a sorted sections' BST back to list form. */
|
||||||
@ -629,7 +695,8 @@ output_section_callback_tree_to_list (lang_wild_statement_type *ptr,
|
|||||||
if (tree->left)
|
if (tree->left)
|
||||||
output_section_callback_tree_to_list (ptr, tree->left, output);
|
output_section_callback_tree_to_list (ptr, tree->left, output);
|
||||||
|
|
||||||
lang_add_section (&ptr->children, tree->section, tree->pattern, NULL,
|
lang_add_section (&ptr->children, tree->section, tree->pattern,
|
||||||
|
ptr->section_flag_list,
|
||||||
(lang_output_section_statement_type *) output);
|
(lang_output_section_statement_type *) output);
|
||||||
|
|
||||||
if (tree->right)
|
if (tree->right)
|
||||||
@ -887,6 +954,7 @@ analyze_walk_wild_section_handler (lang_wild_statement_type *ptr)
|
|||||||
ptr->handler_data[2] = NULL;
|
ptr->handler_data[2] = NULL;
|
||||||
ptr->handler_data[3] = NULL;
|
ptr->handler_data[3] = NULL;
|
||||||
ptr->tree = NULL;
|
ptr->tree = NULL;
|
||||||
|
ptr->rightmost = &ptr->tree;
|
||||||
|
|
||||||
for (sec = ptr->section_list; sec != NULL; sec = sec->next)
|
for (sec = ptr->section_list; sec != NULL; sec = sec->next)
|
||||||
{
|
{
|
||||||
@ -2777,113 +2845,17 @@ lang_add_section (lang_statement_list_type *ptr,
|
|||||||
new_section->pattern = pattern;
|
new_section->pattern = pattern;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* PE puts the sort key in the input statement. */
|
|
||||||
|
|
||||||
static const char *
|
|
||||||
sort_filename (bfd *abfd)
|
|
||||||
{
|
|
||||||
lang_input_statement_type *is = bfd_usrdata (abfd);
|
|
||||||
if (is->sort_key)
|
|
||||||
return is->sort_key;
|
|
||||||
return bfd_get_filename (abfd);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Handle wildcard sorting. This returns the lang_input_section which
|
|
||||||
should follow the one we are going to create for SECTION and FILE,
|
|
||||||
based on the sorting requirements of WILD. It returns NULL if the
|
|
||||||
new section should just go at the end of the current list. */
|
|
||||||
|
|
||||||
static lang_statement_union_type *
|
|
||||||
wild_sort (lang_wild_statement_type *wild,
|
|
||||||
struct wildcard_list *sec,
|
|
||||||
lang_input_statement_type *file,
|
|
||||||
asection *section)
|
|
||||||
{
|
|
||||||
lang_statement_union_type *l;
|
|
||||||
|
|
||||||
if (!wild->filenames_sorted
|
|
||||||
&& (sec == NULL || sec->spec.sorted == none))
|
|
||||||
return NULL;
|
|
||||||
|
|
||||||
for (l = wild->children.head; l != NULL; l = l->header.next)
|
|
||||||
{
|
|
||||||
lang_input_section_type *ls;
|
|
||||||
|
|
||||||
if (l->header.type != lang_input_section_enum)
|
|
||||||
continue;
|
|
||||||
ls = &l->input_section;
|
|
||||||
|
|
||||||
/* Sorting by filename takes precedence over sorting by section
|
|
||||||
name. */
|
|
||||||
|
|
||||||
if (wild->filenames_sorted)
|
|
||||||
{
|
|
||||||
const char *fn, *ln;
|
|
||||||
bool fa, la;
|
|
||||||
int i;
|
|
||||||
|
|
||||||
/* The PE support for the .idata section as generated by
|
|
||||||
dlltool assumes that files will be sorted by the name of
|
|
||||||
the archive and then the name of the file within the
|
|
||||||
archive. */
|
|
||||||
|
|
||||||
fa = file->the_bfd->my_archive != NULL;
|
|
||||||
if (fa)
|
|
||||||
fn = sort_filename (file->the_bfd->my_archive);
|
|
||||||
else
|
|
||||||
fn = sort_filename (file->the_bfd);
|
|
||||||
|
|
||||||
la = ls->section->owner->my_archive != NULL;
|
|
||||||
if (la)
|
|
||||||
ln = sort_filename (ls->section->owner->my_archive);
|
|
||||||
else
|
|
||||||
ln = sort_filename (ls->section->owner);
|
|
||||||
|
|
||||||
i = filename_cmp (fn, ln);
|
|
||||||
if (i > 0)
|
|
||||||
continue;
|
|
||||||
else if (i < 0)
|
|
||||||
break;
|
|
||||||
|
|
||||||
if (fa || la)
|
|
||||||
{
|
|
||||||
if (fa)
|
|
||||||
fn = sort_filename (file->the_bfd);
|
|
||||||
if (la)
|
|
||||||
ln = sort_filename (ls->section->owner);
|
|
||||||
|
|
||||||
i = filename_cmp (fn, ln);
|
|
||||||
if (i > 0)
|
|
||||||
continue;
|
|
||||||
else if (i < 0)
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Here either the files are not sorted by name, or we are
|
|
||||||
looking at the sections for this file. */
|
|
||||||
|
|
||||||
if (sec != NULL
|
|
||||||
&& sec->spec.sorted != none
|
|
||||||
&& sec->spec.sorted != by_none)
|
|
||||||
if (compare_section (sec->spec.sorted, section, ls->section) < 0)
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
return l;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Expand a wild statement for a particular FILE. SECTION may be
|
/* Expand a wild statement for a particular FILE. SECTION may be
|
||||||
NULL, in which case it is a wild card. */
|
NULL, in which case it is a wild card. This assumes that the
|
||||||
|
wild statement doesn't need any sorting (of filenames or sections). */
|
||||||
|
|
||||||
static void
|
static void
|
||||||
output_section_callback (lang_wild_statement_type *ptr,
|
output_section_callback_nosort (lang_wild_statement_type *ptr,
|
||||||
struct wildcard_list *sec,
|
struct wildcard_list *sec ATTRIBUTE_UNUSED,
|
||||||
asection *section,
|
asection *section,
|
||||||
lang_input_statement_type *file,
|
lang_input_statement_type *file ATTRIBUTE_UNUSED,
|
||||||
void *output)
|
void *output)
|
||||||
{
|
{
|
||||||
lang_statement_union_type *before;
|
|
||||||
lang_output_section_statement_type *os;
|
lang_output_section_statement_type *os;
|
||||||
|
|
||||||
os = (lang_output_section_statement_type *) output;
|
os = (lang_output_section_statement_type *) output;
|
||||||
@ -2892,40 +2864,8 @@ output_section_callback (lang_wild_statement_type *ptr,
|
|||||||
if (unique_section_p (section, os))
|
if (unique_section_p (section, os))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
before = wild_sort (ptr, sec, file, section);
|
lang_add_section (&ptr->children, section, ptr->section_list,
|
||||||
|
ptr->section_flag_list, os);
|
||||||
/* Here BEFORE points to the lang_input_section which
|
|
||||||
should follow the one we are about to add. If BEFORE
|
|
||||||
is NULL, then the section should just go at the end
|
|
||||||
of the current list. */
|
|
||||||
|
|
||||||
if (before == NULL)
|
|
||||||
lang_add_section (&ptr->children, section, ptr->section_list,
|
|
||||||
ptr->section_flag_list, os);
|
|
||||||
else
|
|
||||||
{
|
|
||||||
lang_statement_list_type list;
|
|
||||||
lang_statement_union_type **pp;
|
|
||||||
|
|
||||||
lang_list_init (&list);
|
|
||||||
lang_add_section (&list, section, ptr->section_list,
|
|
||||||
ptr->section_flag_list, os);
|
|
||||||
|
|
||||||
/* If we are discarding the section, LIST.HEAD will
|
|
||||||
be NULL. */
|
|
||||||
if (list.head != NULL)
|
|
||||||
{
|
|
||||||
ASSERT (list.head->header.next == NULL);
|
|
||||||
|
|
||||||
for (pp = &ptr->children.head;
|
|
||||||
*pp != before;
|
|
||||||
pp = &(*pp)->header.next)
|
|
||||||
ASSERT (*pp != NULL);
|
|
||||||
|
|
||||||
list.head->header.next = *pp;
|
|
||||||
*pp = list.head;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Check if all sections in a wild statement for a particular FILE
|
/* Check if all sections in a wild statement for a particular FILE
|
||||||
@ -3236,23 +3176,22 @@ wild (lang_wild_statement_type *s,
|
|||||||
{
|
{
|
||||||
struct wildcard_list *sec;
|
struct wildcard_list *sec;
|
||||||
|
|
||||||
if (s->handler_data[0]
|
if (s->filenames_sorted || s->any_specs_sorted)
|
||||||
&& s->handler_data[0]->spec.sorted == by_name
|
|
||||||
&& !s->filenames_sorted)
|
|
||||||
{
|
{
|
||||||
lang_section_bst_type *tree;
|
lang_section_bst_type *tree;
|
||||||
|
|
||||||
walk_wild (s, output_section_callback_fast, output);
|
walk_wild (s, output_section_callback_sort, output);
|
||||||
|
|
||||||
tree = s->tree;
|
tree = s->tree;
|
||||||
if (tree)
|
if (tree)
|
||||||
{
|
{
|
||||||
output_section_callback_tree_to_list (s, tree, output);
|
output_section_callback_tree_to_list (s, tree, output);
|
||||||
s->tree = NULL;
|
s->tree = NULL;
|
||||||
|
s->rightmost = &s->tree;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
walk_wild (s, output_section_callback, output);
|
walk_wild (s, output_section_callback_nosort, output);
|
||||||
|
|
||||||
if (default_common_section == NULL)
|
if (default_common_section == NULL)
|
||||||
for (sec = s->section_list; sec != NULL; sec = sec->next)
|
for (sec = s->section_list; sec != NULL; sec = sec->next)
|
||||||
@ -4210,22 +4149,25 @@ update_wild_statements (lang_statement_union_type *s)
|
|||||||
/* Don't sort .init/.fini sections. */
|
/* Don't sort .init/.fini sections. */
|
||||||
if (strcmp (sec->spec.name, ".init") != 0
|
if (strcmp (sec->spec.name, ".init") != 0
|
||||||
&& strcmp (sec->spec.name, ".fini") != 0)
|
&& strcmp (sec->spec.name, ".fini") != 0)
|
||||||
switch (sec->spec.sorted)
|
{
|
||||||
{
|
switch (sec->spec.sorted)
|
||||||
case none:
|
{
|
||||||
sec->spec.sorted = sort_section;
|
case none:
|
||||||
break;
|
sec->spec.sorted = sort_section;
|
||||||
case by_name:
|
break;
|
||||||
if (sort_section == by_alignment)
|
case by_name:
|
||||||
sec->spec.sorted = by_name_alignment;
|
if (sort_section == by_alignment)
|
||||||
break;
|
sec->spec.sorted = by_name_alignment;
|
||||||
case by_alignment:
|
break;
|
||||||
if (sort_section == by_name)
|
case by_alignment:
|
||||||
sec->spec.sorted = by_alignment_name;
|
if (sort_section == by_name)
|
||||||
break;
|
sec->spec.sorted = by_alignment_name;
|
||||||
default:
|
break;
|
||||||
break;
|
default:
|
||||||
}
|
break;
|
||||||
|
}
|
||||||
|
s->wild_statement.any_specs_sorted = true;
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case lang_constructors_statement_enum:
|
case lang_constructors_statement_enum:
|
||||||
@ -8253,7 +8195,9 @@ lang_process (void)
|
|||||||
|
|
||||||
ldemul_after_check_relocs ();
|
ldemul_after_check_relocs ();
|
||||||
|
|
||||||
/* Update wild statements. */
|
/* Update wild statements in case the user gave --sort-section.
|
||||||
|
Note how the option might have come after the linker script and
|
||||||
|
so couldn't have been set when the wild statements were created. */
|
||||||
update_wild_statements (statement_list.head);
|
update_wild_statements (statement_list.head);
|
||||||
|
|
||||||
/* Run through the contours of the script and attach input sections
|
/* Run through the contours of the script and attach input sections
|
||||||
@ -8367,12 +8311,15 @@ lang_add_wild (struct wildcard_spec *filespec,
|
|||||||
{
|
{
|
||||||
struct wildcard_list *curr, *next;
|
struct wildcard_list *curr, *next;
|
||||||
lang_wild_statement_type *new_stmt;
|
lang_wild_statement_type *new_stmt;
|
||||||
|
bool any_specs_sorted = false;
|
||||||
|
|
||||||
/* Reverse the list as the parser puts it back to front. */
|
/* Reverse the list as the parser puts it back to front. */
|
||||||
for (curr = section_list, section_list = NULL;
|
for (curr = section_list, section_list = NULL;
|
||||||
curr != NULL;
|
curr != NULL;
|
||||||
section_list = curr, curr = next)
|
section_list = curr, curr = next)
|
||||||
{
|
{
|
||||||
|
if (curr->spec.sorted != none && curr->spec.sorted != by_none)
|
||||||
|
any_specs_sorted = true;
|
||||||
next = curr->next;
|
next = curr->next;
|
||||||
curr->next = section_list;
|
curr->next = section_list;
|
||||||
}
|
}
|
||||||
@ -8388,6 +8335,7 @@ lang_add_wild (struct wildcard_spec *filespec,
|
|||||||
new_stmt = new_stat (lang_wild_statement, stat_ptr);
|
new_stmt = new_stat (lang_wild_statement, stat_ptr);
|
||||||
new_stmt->filename = NULL;
|
new_stmt->filename = NULL;
|
||||||
new_stmt->filenames_sorted = false;
|
new_stmt->filenames_sorted = false;
|
||||||
|
new_stmt->any_specs_sorted = any_specs_sorted;
|
||||||
new_stmt->section_flag_list = NULL;
|
new_stmt->section_flag_list = NULL;
|
||||||
new_stmt->exclude_name_list = NULL;
|
new_stmt->exclude_name_list = NULL;
|
||||||
if (filespec != NULL)
|
if (filespec != NULL)
|
||||||
|
@ -384,6 +384,7 @@ struct lang_wild_statement_struct
|
|||||||
lang_statement_header_type header;
|
lang_statement_header_type header;
|
||||||
const char *filename;
|
const char *filename;
|
||||||
bool filenames_sorted;
|
bool filenames_sorted;
|
||||||
|
bool any_specs_sorted;
|
||||||
struct wildcard_list *section_list;
|
struct wildcard_list *section_list;
|
||||||
bool keep_sections;
|
bool keep_sections;
|
||||||
lang_statement_list_type children;
|
lang_statement_list_type children;
|
||||||
@ -391,7 +392,7 @@ struct lang_wild_statement_struct
|
|||||||
|
|
||||||
walk_wild_section_handler_t walk_wild_section_handler;
|
walk_wild_section_handler_t walk_wild_section_handler;
|
||||||
struct wildcard_list *handler_data[4];
|
struct wildcard_list *handler_data[4];
|
||||||
lang_section_bst_type *tree;
|
lang_section_bst_type *tree, **rightmost;
|
||||||
struct flag_info *section_flag_list;
|
struct flag_info *section_flag_list;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
18
ld/testsuite/ld-scripts/sort-file.d
Normal file
18
ld/testsuite/ld-scripts/sort-file.d
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
#source: sort-file2.s
|
||||||
|
#source: sort-file1.s
|
||||||
|
#ld: -T sort-file.t
|
||||||
|
#nm: -n
|
||||||
|
|
||||||
|
# Check that SORT_BY_NAME on filenames works
|
||||||
|
# the text sections should come in sorted order, the data
|
||||||
|
# sections in input order. Note how we specifically pass
|
||||||
|
# the object filenames in non-alphabetical order
|
||||||
|
#...
|
||||||
|
0[0-9a-f]* t infile1
|
||||||
|
#...
|
||||||
|
0[0-9a-f]* t infile2
|
||||||
|
#...
|
||||||
|
0[0-9a-f]* d data2
|
||||||
|
#...
|
||||||
|
0[0-9a-f]* d data1
|
||||||
|
#pass
|
6
ld/testsuite/ld-scripts/sort-file.t
Normal file
6
ld/testsuite/ld-scripts/sort-file.t
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
SECTIONS
|
||||||
|
{
|
||||||
|
.text : { SORT_BY_NAME(*)(.text*) }
|
||||||
|
.data : { *(.data*) }
|
||||||
|
/DISCARD/ : { *(.*) }
|
||||||
|
}
|
6
ld/testsuite/ld-scripts/sort-file1.s
Normal file
6
ld/testsuite/ld-scripts/sort-file1.s
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
.text
|
||||||
|
infile1:
|
||||||
|
.long 0
|
||||||
|
.data
|
||||||
|
data1:
|
||||||
|
.long 0
|
6
ld/testsuite/ld-scripts/sort-file2.s
Normal file
6
ld/testsuite/ld-scripts/sort-file2.s
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
.text
|
||||||
|
infile2:
|
||||||
|
.long 0
|
||||||
|
.data
|
||||||
|
data2:
|
||||||
|
.long 0
|
Loading…
x
Reference in New Issue
Block a user