ld/
authorH.J. Lu <hjl.tools@gmail.com>
Mon, 4 Oct 2004 16:45:51 +0000 (16:45 +0000)
committerH.J. Lu <hjl.tools@gmail.com>
Mon, 4 Oct 2004 16:45:51 +0000 (16:45 +0000)
2004-10-04  H.J. Lu  <hongjiu.lu@intel.com>

* NEWS: Mention SORT_BY_NAME, SORT_BY_ALIGNMENT and
--sort-section name|alignment.

* ld.texinfo: Document SORT_BY_NAME, SORT_BY_ALIGNMENT and
--sort-section name|alignment.

* ld.h (sort_type): New enum.
(wildcard_spec): Change the type of `sorted' to sort_type.

* ldgram.y (SORT): Removed.
(SORT_BY_NAME): Added.
(SORT_BY_ALIGNMENT): Added.
(wildcard_spec): Updated `sorted'. Handle SORT_BY_NAME and
SORT_BY_ALIGNMENT.
(input_section_spec_no_keep): Updated `sorted'.
(statement): Replace SORT with SORT_BY_NAME.

* ldlang.c (compare_section): New function to compare 2
sections with different sorting schemes.
(wild_sort): Updated. Use compare_section.
(update_wild_statements): New function.
(lang_process): Call update_wild_statements before
map_input_to_output_sections.

* ldlex.l (SORT_BY_NAME): New.
(SORT_BY_ALIGNMENT): New.
(SORT): Return SORT_BY_NAME.

* ldmain.c (sort_section): New. Defined.
(main): Initialize it to none.

* lexsup.c (option_values): Add OPTION_SORT_SECTION.
(ld_options): Add an entry for OPTION_SORT_SECTION.
(parse_args): Handle OPTION_SORT_SECTION.

* mri.c (mri_draw_tree): Updated `sorted'.

ld/testsuite/

2004-10-04  H.J. Lu  <hongjiu.lu@intel.com>

* ld-scripts/sort.exp: New file for section sorting tests.
* ld-scripts/sort_b_a.d: Likewise
* ld-scripts/sort_b_a.s: Likewise
* ld-scripts/sort_b_a.t: Likewise
* ld-scripts/sort_b_a_a-1.d: Likewise
* ld-scripts/sort_b_a_a-2.d: Likewise
* ld-scripts/sort_b_a_a-3.d: Likewise
* ld-scripts/sort_b_a_a.t: Likewise
* ld-scripts/sort_b_a_n-1.d: Likewise
* ld-scripts/sort_b_a_n-2.d: Likewise
* ld-scripts/sort_b_a_n-3.d: Likewise
* ld-scripts/sort_b_a_n.t: Likewise
* ld-scripts/sort_b_n.d: Likewise
* ld-scripts/sort_b_n.s: Likewise
* ld-scripts/sort_b_n.t: Likewise
* ld-scripts/sort_b_n_a-1.d: Likewise
* ld-scripts/sort_b_n_a-2.d: Likewise
* ld-scripts/sort_b_n_a-3.d: Likewise
* ld-scripts/sort_b_n_a.t: Likewise
* ld-scripts/sort_b_n_n-1.d: Likewise
* ld-scripts/sort_b_n_n-2.d: Likewise
* ld-scripts/sort_b_n_n-3.d: Likewise
* ld-scripts/sort_b_n_n.t: Likewise
* ld-scripts/sort_n_a-a.s: Likewise
* ld-scripts/sort_n_a-b.s: Likewise
* ld-scripts/sort_no-1.d: Likewise
* ld-scripts/sort_no-2.d: Likewise
* ld-scripts/sort_no.t: Likewise

39 files changed:
ld/ChangeLog
ld/NEWS
ld/ld.h
ld/ld.texinfo
ld/ldgram.y
ld/ldlang.c
ld/ldlex.l
ld/ldmain.c
ld/lexsup.c
ld/mri.c
ld/testsuite/ChangeLog
ld/testsuite/ld-scripts/sort.exp [new file with mode: 0644]
ld/testsuite/ld-scripts/sort_b_a.d [new file with mode: 0644]
ld/testsuite/ld-scripts/sort_b_a.s [new file with mode: 0644]
ld/testsuite/ld-scripts/sort_b_a.t [new file with mode: 0644]
ld/testsuite/ld-scripts/sort_b_a_a-1.d [new file with mode: 0644]
ld/testsuite/ld-scripts/sort_b_a_a-2.d [new file with mode: 0644]
ld/testsuite/ld-scripts/sort_b_a_a-3.d [new file with mode: 0644]
ld/testsuite/ld-scripts/sort_b_a_a.t [new file with mode: 0644]
ld/testsuite/ld-scripts/sort_b_a_n-1.d [new file with mode: 0644]
ld/testsuite/ld-scripts/sort_b_a_n-2.d [new file with mode: 0644]
ld/testsuite/ld-scripts/sort_b_a_n-3.d [new file with mode: 0644]
ld/testsuite/ld-scripts/sort_b_a_n.t [new file with mode: 0644]
ld/testsuite/ld-scripts/sort_b_n.d [new file with mode: 0644]
ld/testsuite/ld-scripts/sort_b_n.s [new file with mode: 0644]
ld/testsuite/ld-scripts/sort_b_n.t [new file with mode: 0644]
ld/testsuite/ld-scripts/sort_b_n_a-1.d [new file with mode: 0644]
ld/testsuite/ld-scripts/sort_b_n_a-2.d [new file with mode: 0644]
ld/testsuite/ld-scripts/sort_b_n_a-3.d [new file with mode: 0644]
ld/testsuite/ld-scripts/sort_b_n_a.t [new file with mode: 0644]
ld/testsuite/ld-scripts/sort_b_n_n-1.d [new file with mode: 0644]
ld/testsuite/ld-scripts/sort_b_n_n-2.d [new file with mode: 0644]
ld/testsuite/ld-scripts/sort_b_n_n-3.d [new file with mode: 0644]
ld/testsuite/ld-scripts/sort_b_n_n.t [new file with mode: 0644]
ld/testsuite/ld-scripts/sort_n_a-a.s [new file with mode: 0644]
ld/testsuite/ld-scripts/sort_n_a-b.s [new file with mode: 0644]
ld/testsuite/ld-scripts/sort_no-1.d [new file with mode: 0644]
ld/testsuite/ld-scripts/sort_no-2.d [new file with mode: 0644]
ld/testsuite/ld-scripts/sort_no.t [new file with mode: 0644]

index d39892c06da19d585c752dae6973b9ddd716c09e..b887b7ff1474cbb51b550aa441b4e59f901984a5 100644 (file)
@@ -1,3 +1,42 @@
+2004-10-04  H.J. Lu  <hongjiu.lu@intel.com>
+
+       * NEWS: Mention SORT_BY_NAME, SORT_BY_ALIGNMENT and
+       --sort-section name|alignment.
+
+       * ld.texinfo: Document SORT_BY_NAME, SORT_BY_ALIGNMENT and
+       --sort-section name|alignment.
+
+       * ld.h (sort_type): New enum.
+       (wildcard_spec): Change the type of `sorted' to sort_type.
+
+       * ldgram.y (SORT): Removed.
+       (SORT_BY_NAME): Added.
+       (SORT_BY_ALIGNMENT): Added.
+       (wildcard_spec): Updated `sorted'. Handle SORT_BY_NAME and
+       SORT_BY_ALIGNMENT.
+       (input_section_spec_no_keep): Updated `sorted'.
+       (statement): Replace SORT with SORT_BY_NAME.
+
+       * ldlang.c (compare_section): New function to compare 2
+       sections with different sorting schemes.
+       (wild_sort): Updated. Use compare_section.
+       (update_wild_statements): New function.
+       (lang_process): Call update_wild_statements before
+       map_input_to_output_sections.
+
+       * ldlex.l (SORT_BY_NAME): New.
+       (SORT_BY_ALIGNMENT): New.
+       (SORT): Return SORT_BY_NAME.
+
+       * ldmain.c (sort_section): New. Defined.
+       (main): Initialize it to none.
+
+       * lexsup.c (option_values): Add OPTION_SORT_SECTION.
+       (ld_options): Add an entry for OPTION_SORT_SECTION.
+       (parse_args): Handle OPTION_SORT_SECTION.
+
+       * mri.c (mri_draw_tree): Updated `sorted'.
+
 2004-10-04  Jakub Jelinek  <jakub@redhat.com>
 
        * ldgram.y (DATA_SEGMENT_RELRO_END): Add one argument.
diff --git a/ld/NEWS b/ld/NEWS
index aab2ef34f3764562af463327eaf47cffa74115e1..c264ae9752ca0cb74ed93774a75b951e74216548 100644 (file)
--- a/ld/NEWS
+++ b/ld/NEWS
@@ -1,5 +1,12 @@
 -*- text -*-
 
+* Added SORT_BY_NAME and SORT_BY_ALIGNMENT to the linker script
+  language to permit sorting sections by section name or section
+  maximum alignment.
+
+* Added a new linker command line switch, --sort-section name|alignment,
+  to sort sections by section name or maximum alignment.
+
 * New ELF --add-needed/--no-add-needed options to control if a
 DT_NEEDED tag should be added when a shared library comes from
 DT_NEEDED tags.
diff --git a/ld/ld.h b/ld/ld.h
index 2bcf7d27acb40ebc9143ae2744fad80bb13c82bf..c2337b6a1e981d74109a3ee7d2e4386e0b8a3be1 100644 (file)
--- a/ld/ld.h
+++ b/ld/ld.h
@@ -64,13 +64,18 @@ typedef struct name_list {
 }
 name_list;
 
-/* A wildcard specification.  This is only used in ldgram.y, but it
-   winds up in ldgram.h, so we need to define it outside.  */
+/* A wildcard specification.  */
+
+typedef enum {
+  none, by_name, by_alignment, by_name_alignment, by_alignment_name
+} sort_type;
+
+extern sort_type sort_section;
 
 struct wildcard_spec {
   const char *name;
   struct name_list *exclude_name_list;
-  bfd_boolean sorted;
+  sort_type sorted;
 };
 
 struct wildcard_list {
index 10134a648afed530b3f0c3970be3668479c87309..d6f9c254587a209e2fb7e8a10eb66d9015de887e 100644 (file)
@@ -1449,6 +1449,16 @@ byte symbols, then all the two byte, then all the four byte, and then
 everything else.  This is to prevent gaps between symbols due to
 alignment constraints.
 
+@kindex --sort-section name
+@item --sort-section name
+This option will apply @code{SORT_BY_NAME} to all wildcard section
+patterns in the linker script.
+
+@kindex --sort-section alignment
+@item --sort-section alignment
+This option will apply @code{SORT_BY_ALIGNMENT} to all wildcard section
+patterns in the linker script.
+
 @kindex --split-by-file
 @item --split-by-file [@var{size}]
 Similar to @option{--split-by-reloc} but creates a new output section for
@@ -3076,14 +3086,66 @@ sequence of input section descriptions is probably in error, because the
 .data1 : @{ data.o(.data) @}
 @end smallexample
 
-@cindex SORT
+@cindex SORT_BY_NAME
 Normally, the linker will place files and sections matched by wildcards
 in the order in which they are seen during the link.  You can change
-this by using the @code{SORT} keyword, which appears before a wildcard
-pattern in parentheses (e.g., @code{SORT(.text*)}).  When the
-@code{SORT} keyword is used, the linker will sort the files or sections
+this by using the @code{SORT_BY_NAME} keyword, which appears before a wildcard
+pattern in parentheses (e.g., @code{SORT_BY_NAME(.text*)}).  When the
+@code{SORT_BY_NAME} keyword is used, the linker will sort the files or sections
 into ascending order by name before placing them in the output file.
 
+@cindex SORT_BY_ALIGNMENT
+@code{SORT_BY_ALIGNMENT} is very similar to @code{SORT_BY_NAME}. The
+difference is @code{SORT_BY_ALIGNMENT} will sort sections into
+ascending order by alignment before placing them in the output file.
+
+@cindex SORT
+@code{SORT} is an alias for @code{SORT_BY_NAME}.
+
+When there are nested section sorting commands in linker script, there
+can be at most 1 level of nesting for section sorting commands.
+
+@enumerate
+@item
+@code{SORT_BY_NAME} (@code{SORT_BY_ALIGNMENT} (wildcard section pattern)).
+It will sort the input sections by name first, then by alignment if 2
+sections have the same name.
+@item
+@code{SORT_BY_ALIGNMENT} (@code{SORT_BY_NAME} (wildcard section pattern)).
+It will sort the input sections by alignment first, then by name if 2
+sections have the same alignment.
+@item
+@code{SORT_BY_NAME} (@code{SORT_BY_NAME} (wildcard section pattern)) is 
+treated the same as @code{SORT_BY_NAME} (wildcard section pattern).
+@item
+@code{SORT_BY_ALIGNMENT} (@code{SORT_BY_ALIGNMENT} (wildcard section pattern))
+is treated the same as @code{SORT_BY_ALIGNMENT} (wildcard section pattern).
+@item
+All other nested section sorting commands are invalid.
+@end enumerate
+
+When both command line section sorting option and linker script
+section sorting command are used, section sorting command always
+takes precedence over the command line option.
+
+If the section sorting command in linker script isn't nested, the
+command line option will make the section sorting command to be
+treated as nested sorting command.
+
+@enumerate
+@item
+@code{SORT_BY_NAME} (wildcard section pattern ) with
+@option{--sort-sections alignment} is equivalent to
+@code{SORT_BY_NAME} (@code{SORT_BY_ALIGNMENT} (wildcard section pattern)).
+@item
+@code{SORT_BY_ALIGNMENT} (wildcard section pattern) with
+@option{--sort-section name} is equivalent to
+@code{SORT_BY_ALIGNMENT} (@code{SORT_BY_NAME} (wildcard section pattern)).
+@end enumerate
+
+If the section sorting command in linker script is nested, the
+command line option will be ignored.
+
 If you ever get confused about where input sections are going, use the
 @samp{-M} linker option to generate a map file.  The map file shows
 precisely how input sections are mapped to output sections.
@@ -3149,7 +3211,7 @@ When link-time garbage collection is in use (@samp{--gc-sections}),
 it is often useful to mark sections that should not be eliminated.
 This is accomplished by surrounding an input section's wildcard entry
 with @code{KEEP()}, as in @code{KEEP(*(.init))} or
-@code{KEEP(SORT(*)(.ctors))}.
+@code{KEEP(SORT_BY_NAME(*)(.ctors))}.
 
 @node Input Section Example
 @subsubsection Input Section Example
@@ -3333,9 +3395,9 @@ If you are using the @sc{gnu} C++ support for initialization priority,
 which provides some control over the order in which global constructors
 are run, you must sort the constructors at link time to ensure that they
 are executed in the correct order.  When using the @code{CONSTRUCTORS}
-command, use @samp{SORT(CONSTRUCTORS)} instead.  When using the
-@code{.ctors} and @code{.dtors} sections, use @samp{*(SORT(.ctors))} and
-@samp{*(SORT(.dtors))} instead of just @samp{*(.ctors)} and
+command, use @samp{SORT_BY_NAME(CONSTRUCTORS)} instead.  When using the
+@code{.ctors} and @code{.dtors} sections, use @samp{*(SORT_BY_NAME(.ctors))} and
+@samp{*(SORT_BY_NAME(.dtors))} instead of just @samp{*(.ctors)} and
 @samp{*(.dtors)}.
 
 Normally the compiler and linker will handle these issues automatically,
index f4f4589327e8b252fd354a129dc12a770ddb0b71..bdfdcd5ddd65d7dd3ab934de53d7422ed5234e79 100644 (file)
@@ -128,7 +128,8 @@ static int error_index;
 %token END
 %left <token> '('
 %token <token> ALIGN_K BLOCK BIND QUAD SQUAD LONG SHORT BYTE
-%token SECTIONS PHDRS SORT DATA_SEGMENT_ALIGN DATA_SEGMENT_RELRO_END DATA_SEGMENT_END
+%token SECTIONS PHDRS DATA_SEGMENT_ALIGN DATA_SEGMENT_RELRO_END DATA_SEGMENT_END
+%token SORT_BY_NAME SORT_BY_ALIGNMENT
 %token '{' '}'
 %token SIZEOF_HEADERS OUTPUT_FORMAT FORCE_COMMON_ALLOCATION OUTPUT_ARCH
 %token INHIBIT_COMMON_ALLOCATION
@@ -412,25 +413,55 @@ wildcard_spec:
                wildcard_name
                        {
                          $$.name = $1;
-                         $$.sorted = FALSE;
+                         $$.sorted = none;
                          $$.exclude_name_list = NULL;
                        }
        |       EXCLUDE_FILE '(' exclude_name_list ')' wildcard_name
                        {
                          $$.name = $5;
-                         $$.sorted = FALSE;
+                         $$.sorted = none;
                          $$.exclude_name_list = $3;
                        }
-       |       SORT '(' wildcard_name ')'
+       |       SORT_BY_NAME '(' wildcard_name ')'
                        {
                          $$.name = $3;
-                         $$.sorted = TRUE;
+                         $$.sorted = by_name;
                          $$.exclude_name_list = NULL;
                        }
-       |       SORT '(' EXCLUDE_FILE '(' exclude_name_list ')' wildcard_name ')'
+       |       SORT_BY_ALIGNMENT '(' wildcard_name ')'
+                       {
+                         $$.name = $3;
+                         $$.sorted = by_alignment;
+                         $$.exclude_name_list = NULL;
+                       }
+       |       SORT_BY_NAME '(' SORT_BY_ALIGNMENT '(' wildcard_name ')' ')'
+                       {
+                         $$.name = $5;
+                         $$.sorted = by_name_alignment;
+                         $$.exclude_name_list = NULL;
+                       }
+       |       SORT_BY_NAME '(' SORT_BY_NAME '(' wildcard_name ')' ')'
+                       {
+                         $$.name = $5;
+                         $$.sorted = by_name;
+                         $$.exclude_name_list = NULL;
+                       }
+       |       SORT_BY_ALIGNMENT '(' SORT_BY_NAME '(' wildcard_name ')' ')'
+                       {
+                         $$.name = $5;
+                         $$.sorted = by_alignment_name;
+                         $$.exclude_name_list = NULL;
+                       }
+       |       SORT_BY_ALIGNMENT '(' SORT_BY_ALIGNMENT '(' wildcard_name ')' ')'
+                       {
+                         $$.name = $5;
+                         $$.sorted = by_alignment;
+                         $$.exclude_name_list = NULL;
+                       }
+       |       SORT_BY_NAME '(' EXCLUDE_FILE '(' exclude_name_list ')' wildcard_name ')'
                        {
                          $$.name = $7;
-                         $$.sorted = TRUE;
+                         $$.sorted = by_name;
                          $$.exclude_name_list = $5;
                        }
        ;
@@ -481,7 +512,7 @@ input_section_spec_no_keep:
                          struct wildcard_spec tmp;
                          tmp.name = $1;
                          tmp.exclude_name_list = NULL;
-                         tmp.sorted = FALSE;
+                         tmp.sorted = none;
                          lang_add_wild (&tmp, NULL, ldgram_had_keep);
                        }
         |      '[' file_NAME_list ']'
@@ -514,7 +545,7 @@ statement:
 
                  lang_add_attribute(lang_constructors_statement_enum);
                }
-       | SORT '(' CONSTRUCTORS ')'
+       | SORT_BY_NAME '(' CONSTRUCTORS ')'
                {
                  constructors_sorted = TRUE;
                  lang_add_attribute (lang_constructors_statement_enum);
index 55a42bebe0cf9c265c817473ef25b62a78c057ee..e520625e94ea390bcc9456003cac66db9cf00a6f 100644 (file)
@@ -1054,6 +1054,46 @@ lang_add_section (lang_statement_list_type *ptr,
     }
 }
 
+/* Compare sections ASEC and BSEC according to SORT.  */
+
+static int
+compare_section (sort_type sort, asection *asec, asection *bsec)
+{
+  int ret;
+
+  switch (sort)
+    {
+    default:
+      abort ();
+
+    case by_alignment_name:
+      ret = (bfd_section_alignment (bsec->owner, bsec)
+            - bfd_section_alignment (asec->owner, asec));
+      if (ret)
+       break;
+      /* Fall through.  */
+
+    case by_name:
+      ret = strcmp (bfd_get_section_name (asec->owner, asec),
+                   bfd_get_section_name (bsec->owner, bsec));
+      break;
+
+    case by_name_alignment:
+      ret = strcmp (bfd_get_section_name (asec->owner, asec),
+                   bfd_get_section_name (bsec->owner, bsec));
+      if (ret)
+       break;
+      /* Fall through.  */
+
+    case by_alignment:
+      ret = (bfd_section_alignment (bsec->owner, bsec)
+            - bfd_section_alignment (asec->owner, asec));
+      break;
+    }
+
+  return ret;
+}
+
 /* 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
@@ -1068,7 +1108,8 @@ wild_sort (lang_wild_statement_type *wild,
   const char *section_name;
   lang_statement_union_type *l;
 
-  if (!wild->filenames_sorted && (sec == NULL || !sec->spec.sorted))
+  if (!wild->filenames_sorted
+      && (sec == NULL || sec->spec.sorted == none))
     return NULL;
 
   section_name = bfd_get_section_name (file->the_bfd, section);
@@ -1142,12 +1183,10 @@ wild_sort (lang_wild_statement_type *wild,
       /* 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)
+      if (sec != NULL && sec->spec.sorted != none)
        {
-         if (strcmp (section_name,
-                     bfd_get_section_name (ls->ifile->the_bfd,
-                                           ls->section))
-             < 0)
+         if (compare_section (sec->spec.sorted, section,
+                              ls->section) < 0)
            break;
        }
     }
@@ -2016,6 +2055,71 @@ check_input_sections
     }
 }
 
+/* Update wildcard statements if needed.  */
+
+static void
+update_wild_statements (lang_statement_union_type *s)
+{
+  struct wildcard_list *sec;
+
+  switch (sort_section)
+    {
+    default:
+      FAIL ();
+
+    case none:
+      break;
+
+    case by_name:
+    case by_alignment:
+      for (; s != NULL; s = s->header.next)
+       {
+         switch (s->header.type)
+           {
+           default:
+             break;
+
+           case lang_wild_statement_enum:
+             sec = s->wild_statement.section_list;
+             if (sec != NULL)
+               {
+                 switch (sec->spec.sorted)
+                   {
+                   case none:
+                     sec->spec.sorted = sort_section;
+                     break;
+                   case by_name:
+                     if (sort_section == by_alignment)
+                       sec->spec.sorted = by_name_alignment;
+                     break;
+                   case by_alignment:
+                     if (sort_section == by_name)
+                       sec->spec.sorted = by_alignment_name;
+                     break;
+                   default:
+                     break;
+                   }
+               }
+             break;
+
+           case lang_constructors_statement_enum:
+             update_wild_statements (constructor_list.head);
+             break;
+
+           case lang_output_section_statement_enum:
+             update_wild_statements
+               (s->output_section_statement.children.head);
+             break;
+
+           case lang_group_statement_enum:
+             update_wild_statements (s->group_statement.children.head);
+             break;
+           }
+       }
+      break;
+    }
+}
+
 /* Open input files and attach to output sections.  */
 
 static void
@@ -4250,6 +4354,9 @@ lang_process (void)
   /* Size up the common data.  */
   lang_common ();
 
+  /* Update wild statements.  */
+  update_wild_statements (statement_list.head);
+
   /* Run through the contours of the script and attach input sections
      to the correct output sections.  */
   map_input_to_output_sections (statement_list.head, NULL, NULL);
@@ -4399,7 +4506,7 @@ lang_add_wild (struct wildcard_spec *filespec,
   if (filespec != NULL)
     {
       new->filename = filespec->name;
-      new->filenames_sorted = filespec->sorted;
+      new->filenames_sorted = filespec->sorted == by_name;
     }
   new->section_list = section_list;
   new->keep_sections = keep_sections;
index c0a85217bc06ff88388e6ffc8d072d300b644bda..e01332a3a2807d831d945521ef318a4e20ae303d 100644 (file)
@@ -289,7 +289,9 @@ V_IDENTIFIER [*?.$_a-zA-Z\[\]\-\!\^\\]([*?.$_a-zA-Z0-9\[\]\-\!\^\\]|::)*
 <BOTH,SCRIPT>"NOFLOAT"         { RTOKEN(NOFLOAT);}
 <EXPRESSION,BOTH,SCRIPT>"NOCROSSREFS"  { RTOKEN(NOCROSSREFS);}
 <BOTH,SCRIPT>"OVERLAY"                 { RTOKEN(OVERLAY); }
-<BOTH,SCRIPT>"SORT"                    { RTOKEN(SORT); }
+<BOTH,SCRIPT>"SORT_BY_NAME"            { RTOKEN(SORT_BY_NAME); }
+<BOTH,SCRIPT>"SORT_BY_ALIGNMENT"       { RTOKEN(SORT_BY_ALIGNMENT); }
+<BOTH,SCRIPT>"SORT"                    { RTOKEN(SORT_BY_NAME); }
 <EXPRESSION,BOTH,SCRIPT>"NOLOAD"       { RTOKEN(NOLOAD);}
 <EXPRESSION,BOTH,SCRIPT>"DSECT"                { RTOKEN(DSECT);}
 <EXPRESSION,BOTH,SCRIPT>"COPY"         { RTOKEN(COPY);}
index 45752218b5f75a73fdfa8e7df433830501c85709..8274d36dcd1f2b23dc509e83666bfcb3559eea04 100644 (file)
@@ -108,6 +108,8 @@ args_type command_line;
 
 ld_config_type config;
 
+sort_type sort_section;
+
 static char *get_emulation
   (int, char **);
 static void set_scripts_dir
@@ -280,6 +282,8 @@ main (int argc, char **argv)
   command_line.accept_unknown_input_arch = FALSE;
   command_line.reduce_memory_overheads = FALSE;
 
+  sort_section = none;
+
   /* We initialize DEMANGLING based on the environment variable
      COLLECT_NO_DEMANGLE.  The gcc collect2 program will demangle the
      output of the linker, unless COLLECT_NO_DEMANGLE is set in the
index 9a599a3d5c4920d563589d5fa6aecf52552b3eec..2340006223d74af735ce8bc63c893b81d35aedfb 100644 (file)
@@ -91,6 +91,7 @@ enum option_values
   OPTION_SHARED,
   OPTION_SONAME,
   OPTION_SORT_COMMON,
+  OPTION_SORT_SECTION,
   OPTION_STATS,
   OPTION_SYMBOLIC,
   OPTION_TASK_LINK,
@@ -419,6 +420,9 @@ static const struct ld_option ld_options[] =
     '\0', NULL, N_("Sort common symbols by size"), TWO_DASHES },
   { {"sort_common", no_argument, NULL, OPTION_SORT_COMMON},
     '\0', NULL, NULL, NO_HELP },
+  { {"sort-section", required_argument, NULL, OPTION_SORT_SECTION},
+    '\0', N_("name|alignment"), 
+    N_("Sort sections by name or maximum alignment"), TWO_DASHES },
   { {"spare-dynamic-tags", required_argument, NULL, OPTION_SPARE_DYNAMIC_TAGS},
     '\0', N_("COUNT"), N_("How many tags to reserve in .dynamic section"),
     TWO_DASHES },
@@ -1066,6 +1070,15 @@ parse_args (unsigned argc, char **argv)
        case OPTION_SORT_COMMON:
          config.sort_common = TRUE;
          break;
+       case OPTION_SORT_SECTION:
+         if (strcmp (optarg, N_("name")) == 0)
+           sort_section = by_name;
+         else if (strcmp (optarg, N_("alignment")) == 0)
+           sort_section = by_alignment;
+         else
+           einfo (_("%P%F: invalid section sorting option: %s\n"),
+                  optarg);
+         break;
        case OPTION_STATS:
          config.stats = TRUE;
          break;
index 0e95ef20644c103ebaf1a93e8f9145b801af7f75..aa344f6638494cd88b741af193811643e4b20d1c 100644 (file)
--- a/ld/mri.c
+++ b/ld/mri.c
@@ -226,7 +226,7 @@ mri_draw_tree (void)
          tmp->next = NULL;
          tmp->spec.name = p->name;
          tmp->spec.exclude_name_list = NULL;
-         tmp->spec.sorted = FALSE;
+         tmp->spec.sorted = none;
          lang_add_wild (NULL, tmp, FALSE);
 
          /* If there is an alias for this section, add it too.  */
@@ -237,7 +237,7 @@ mri_draw_tree (void)
                tmp->next = NULL;
                tmp->spec.name = aptr->name;
                tmp->spec.exclude_name_list = NULL;
-               tmp->spec.sorted = FALSE;
+               tmp->spec.sorted = none;
                lang_add_wild (NULL, tmp, FALSE);
              }
 
index dd58a7d75e612f6fba7135d0f2c7dd3cdad2f289..7cba4a4532a66bf507a0ff8ddf1ad9a93381eadf 100644 (file)
@@ -1,3 +1,34 @@
+2004-10-04  H.J. Lu  <hongjiu.lu@intel.com>
+
+       * ld-scripts/sort.exp: New file for section sorting tests.
+       * ld-scripts/sort_b_a.d: Likewise
+       * ld-scripts/sort_b_a.s: Likewise
+       * ld-scripts/sort_b_a.t: Likewise
+       * ld-scripts/sort_b_a_a-1.d: Likewise
+       * ld-scripts/sort_b_a_a-2.d: Likewise
+       * ld-scripts/sort_b_a_a-3.d: Likewise
+       * ld-scripts/sort_b_a_a.t: Likewise
+       * ld-scripts/sort_b_a_n-1.d: Likewise
+       * ld-scripts/sort_b_a_n-2.d: Likewise
+       * ld-scripts/sort_b_a_n-3.d: Likewise
+       * ld-scripts/sort_b_a_n.t: Likewise
+       * ld-scripts/sort_b_n.d: Likewise
+       * ld-scripts/sort_b_n.s: Likewise
+       * ld-scripts/sort_b_n.t: Likewise
+       * ld-scripts/sort_b_n_a-1.d: Likewise
+       * ld-scripts/sort_b_n_a-2.d: Likewise
+       * ld-scripts/sort_b_n_a-3.d: Likewise
+       * ld-scripts/sort_b_n_a.t: Likewise
+       * ld-scripts/sort_b_n_n-1.d: Likewise
+       * ld-scripts/sort_b_n_n-2.d: Likewise
+       * ld-scripts/sort_b_n_n-3.d: Likewise
+       * ld-scripts/sort_b_n_n.t: Likewise
+       * ld-scripts/sort_n_a-a.s: Likewise
+       * ld-scripts/sort_n_a-b.s: Likewise
+       * ld-scripts/sort_no-1.d: Likewise
+       * ld-scripts/sort_no-2.d: Likewise
+       * ld-scripts/sort_no.t: Likewise
+
 2004-10-01  H.J. Lu  <hongjiu.lu@intel.com>
 
        * ld-powerpc/tls.s: Don't set tls type for undefined syms.
diff --git a/ld/testsuite/ld-scripts/sort.exp b/ld/testsuite/ld-scripts/sort.exp
new file mode 100644 (file)
index 0000000..af88223
--- /dev/null
@@ -0,0 +1,26 @@
+# Test SORT_BY_NAME/SORT_BY_ALIGNMENT/SORT in a linker script.
+# By H.J. Lu  <hongjiu.lu@intel.com>
+#   Copyright 2004
+#   Free Software Foundation, Inc.
+#
+# This file is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+# 
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+# 
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+load_lib ld-lib.exp
+
+set sort_test_list [lsort [glob -nocomplain $srcdir/$subdir/sort*.d]]
+for { set i 0 } { $i < [llength $sort_test_list] } { incr i } {
+    verbose [file rootname [lindex $sort_test_list $i]]
+    run_dump_test [file rootname [lindex $sort_test_list $i]]
+}
diff --git a/ld/testsuite/ld-scripts/sort_b_a.d b/ld/testsuite/ld-scripts/sort_b_a.d
new file mode 100644 (file)
index 0000000..78fe1f1
--- /dev/null
@@ -0,0 +1,9 @@
+#source: sort_b_a.s
+#ld: -T sort_b_a.t
+#name: SORT_BY_ALIGNMENT
+#nm: -n
+
+0[0-9a-f]* t text3
+0[0-9a-f]* t text1
+0[0-9a-f]* t text
+0[0-9a-f]* t text2
diff --git a/ld/testsuite/ld-scripts/sort_b_a.s b/ld/testsuite/ld-scripts/sort_b_a.s
new file mode 100644 (file)
index 0000000..7b3851f
--- /dev/null
@@ -0,0 +1,16 @@
+       .section .text2
+       .p2align 3
+text2:
+       .long 0
+       .section .text3
+       .p2align 6
+text3:
+       .long 0
+       .section .text1
+       .p2align 5
+text1:
+       .long 0
+       .text
+text:
+       .p2align 4
+       .long 0
diff --git a/ld/testsuite/ld-scripts/sort_b_a.t b/ld/testsuite/ld-scripts/sort_b_a.t
new file mode 100644 (file)
index 0000000..cbfd3c3
--- /dev/null
@@ -0,0 +1,5 @@
+SECTIONS
+{
+  .text : {*(SORT_BY_ALIGNMENT(.text*))}
+  /DISCARD/ : { *(.*) }
+}
diff --git a/ld/testsuite/ld-scripts/sort_b_a_a-1.d b/ld/testsuite/ld-scripts/sort_b_a_a-1.d
new file mode 100644 (file)
index 0000000..4f70646
--- /dev/null
@@ -0,0 +1,14 @@
+#source: sort_n_a-a.s
+#source: sort_n_a-b.s
+#ld: -T sort_b_a_a.t
+#name: SORT_BY_ALIGNMENT(SORT_BY_ALIGNMENT())
+#nm: -n
+
+0[0-9a-f]* t text3b
+0[0-9a-f]* t text3a
+0[0-9a-f]* t text1a
+0[0-9a-f]* t text1b
+0[0-9a-f]* t texta
+0[0-9a-f]* t textb
+0[0-9a-f]* t text2a
+0[0-9a-f]* t text2b
diff --git a/ld/testsuite/ld-scripts/sort_b_a_a-2.d b/ld/testsuite/ld-scripts/sort_b_a_a-2.d
new file mode 100644 (file)
index 0000000..65919a4
--- /dev/null
@@ -0,0 +1,14 @@
+#source: sort_n_a-a.s
+#source: sort_n_a-b.s
+#ld: -T sort_b_a_a.t --sort-section alignment
+#name: SORT_BY_ALIGNMENT(SORT_BY_ALIGNMENT()) --sort-section alignment
+#nm: -n
+
+0[0-9a-f]* t text3b
+0[0-9a-f]* t text3a
+0[0-9a-f]* t text1a
+0[0-9a-f]* t text1b
+0[0-9a-f]* t texta
+0[0-9a-f]* t textb
+0[0-9a-f]* t text2a
+0[0-9a-f]* t text2b
diff --git a/ld/testsuite/ld-scripts/sort_b_a_a-3.d b/ld/testsuite/ld-scripts/sort_b_a_a-3.d
new file mode 100644 (file)
index 0000000..21b7732
--- /dev/null
@@ -0,0 +1,14 @@
+#source: sort_n_a-a.s
+#source: sort_n_a-b.s
+#ld: -T sort_b_a_a.t --sort-section name
+#name: SORT_BY_ALIGNMENT(SORT_BY_ALIGNMENT()) --sort-section name
+#nm: -n
+
+0[0-9a-f]* t text3b
+0[0-9a-f]* t text1a
+0[0-9a-f]* t text1b
+0[0-9a-f]* t text3a
+0[0-9a-f]* t texta
+0[0-9a-f]* t textb
+0[0-9a-f]* t text2a
+0[0-9a-f]* t text2b
diff --git a/ld/testsuite/ld-scripts/sort_b_a_a.t b/ld/testsuite/ld-scripts/sort_b_a_a.t
new file mode 100644 (file)
index 0000000..359cdff
--- /dev/null
@@ -0,0 +1,5 @@
+SECTIONS
+{
+  .text : {*(SORT_BY_ALIGNMENT(SORT_BY_ALIGNMENT(.text*)))}
+  /DISCARD/ : { *(.*) }
+}
diff --git a/ld/testsuite/ld-scripts/sort_b_a_n-1.d b/ld/testsuite/ld-scripts/sort_b_a_n-1.d
new file mode 100644 (file)
index 0000000..62363bc
--- /dev/null
@@ -0,0 +1,14 @@
+#source: sort_n_a-a.s
+#source: sort_n_a-b.s
+#ld: -T sort_b_a_n.t
+#name: SORT_BY_ALIGNMENT(SORT_BY_NAME())
+#nm: -n
+
+0[0-9a-f]* t text3b
+0[0-9a-f]* t text1a
+0[0-9a-f]* t text1b
+0[0-9a-f]* t text3a
+0[0-9a-f]* t texta
+0[0-9a-f]* t textb
+0[0-9a-f]* t text2a
+0[0-9a-f]* t text2b
diff --git a/ld/testsuite/ld-scripts/sort_b_a_n-2.d b/ld/testsuite/ld-scripts/sort_b_a_n-2.d
new file mode 100644 (file)
index 0000000..7402836
--- /dev/null
@@ -0,0 +1,14 @@
+#source: sort_n_a-a.s
+#source: sort_n_a-b.s
+#ld: -T sort_b_a_n.t --sort-section name
+#name: SORT_BY_ALIGNMENT(SORT_BY_NAME()) --sort-section name
+#nm: -n
+
+0[0-9a-f]* t text3b
+0[0-9a-f]* t text1a
+0[0-9a-f]* t text1b
+0[0-9a-f]* t text3a
+0[0-9a-f]* t texta
+0[0-9a-f]* t textb
+0[0-9a-f]* t text2a
+0[0-9a-f]* t text2b
diff --git a/ld/testsuite/ld-scripts/sort_b_a_n-3.d b/ld/testsuite/ld-scripts/sort_b_a_n-3.d
new file mode 100644 (file)
index 0000000..4421c77
--- /dev/null
@@ -0,0 +1,14 @@
+#source: sort_n_a-a.s
+#source: sort_n_a-b.s
+#ld: -T sort_b_a_n.t --sort-section alignment
+#name: SORT_BY_ALIGNMENT(SORT_BY_NAME()) --sort-section alignment
+#nm: -n
+
+0[0-9a-f]* t text3b
+0[0-9a-f]* t text1a
+0[0-9a-f]* t text1b
+0[0-9a-f]* t text3a
+0[0-9a-f]* t texta
+0[0-9a-f]* t textb
+0[0-9a-f]* t text2a
+0[0-9a-f]* t text2b
diff --git a/ld/testsuite/ld-scripts/sort_b_a_n.t b/ld/testsuite/ld-scripts/sort_b_a_n.t
new file mode 100644 (file)
index 0000000..04c3917
--- /dev/null
@@ -0,0 +1,5 @@
+SECTIONS
+{
+  .text : {*(SORT_BY_ALIGNMENT(SORT_BY_NAME(.text*)))}
+  /DISCARD/ : { *(.*) }
+}
diff --git a/ld/testsuite/ld-scripts/sort_b_n.d b/ld/testsuite/ld-scripts/sort_b_n.d
new file mode 100644 (file)
index 0000000..531a756
--- /dev/null
@@ -0,0 +1,9 @@
+#source: sort_b_n.s
+#ld: -T sort_b_n.t
+#name: SORT_BY_NAME
+#nm: -n
+
+0[0-9a-f]* t text
+0[0-9a-f]* t text1
+0[0-9a-f]* t text2
+0[0-9a-f]* t text3
diff --git a/ld/testsuite/ld-scripts/sort_b_n.s b/ld/testsuite/ld-scripts/sort_b_n.s
new file mode 100644 (file)
index 0000000..c99d75c
--- /dev/null
@@ -0,0 +1,12 @@
+       .section .text2
+text2:
+       .long 0
+       .section .text3
+text3:
+       .long 0
+       .section .text1
+text1:
+       .long 0
+       .text
+text:
+       .long 0
diff --git a/ld/testsuite/ld-scripts/sort_b_n.t b/ld/testsuite/ld-scripts/sort_b_n.t
new file mode 100644 (file)
index 0000000..26c2b6e
--- /dev/null
@@ -0,0 +1,5 @@
+SECTIONS
+{
+  .text : {*(SORT_BY_NAME(.text*))}
+  /DISCARD/ : { *(.*) }
+}
diff --git a/ld/testsuite/ld-scripts/sort_b_n_a-1.d b/ld/testsuite/ld-scripts/sort_b_n_a-1.d
new file mode 100644 (file)
index 0000000..ee123bf
--- /dev/null
@@ -0,0 +1,14 @@
+#source: sort_n_a-a.s
+#source: sort_n_a-b.s
+#ld: -T sort_b_n_a.t
+#name: SORT_BY_NAME(SORT_BY_ALIGNMENT())
+#nm: -n
+
+0[0-9a-f]* t texta
+0[0-9a-f]* t textb
+0[0-9a-f]* t text1a
+0[0-9a-f]* t text1b
+0[0-9a-f]* t text2a
+0[0-9a-f]* t text2b
+0[0-9a-f]* t text3b
+0[0-9a-f]* t text3a
diff --git a/ld/testsuite/ld-scripts/sort_b_n_a-2.d b/ld/testsuite/ld-scripts/sort_b_n_a-2.d
new file mode 100644 (file)
index 0000000..82f1805
--- /dev/null
@@ -0,0 +1,14 @@
+#source: sort_n_a-a.s
+#source: sort_n_a-b.s
+#ld: -T sort_b_n_a.t --sort-section name
+#name: SORT_BY_NAME(SORT_BY_ALIGNMENT()) --sort-section alignment
+#nm: -n
+
+0[0-9a-f]* t texta
+0[0-9a-f]* t textb
+0[0-9a-f]* t text1a
+0[0-9a-f]* t text1b
+0[0-9a-f]* t text2a
+0[0-9a-f]* t text2b
+0[0-9a-f]* t text3b
+0[0-9a-f]* t text3a
diff --git a/ld/testsuite/ld-scripts/sort_b_n_a-3.d b/ld/testsuite/ld-scripts/sort_b_n_a-3.d
new file mode 100644 (file)
index 0000000..5f3c863
--- /dev/null
@@ -0,0 +1,14 @@
+#source: sort_n_a-a.s
+#source: sort_n_a-b.s
+#ld: -T sort_b_n_a.t --sort-section alignment
+#name: SORT_BY_NAME(SORT_BY_ALIGNMENT()) --sort-section alignment
+#nm: -n
+
+0[0-9a-f]* t texta
+0[0-9a-f]* t textb
+0[0-9a-f]* t text1a
+0[0-9a-f]* t text1b
+0[0-9a-f]* t text2a
+0[0-9a-f]* t text2b
+0[0-9a-f]* t text3b
+0[0-9a-f]* t text3a
diff --git a/ld/testsuite/ld-scripts/sort_b_n_a.t b/ld/testsuite/ld-scripts/sort_b_n_a.t
new file mode 100644 (file)
index 0000000..49cbdd3
--- /dev/null
@@ -0,0 +1,5 @@
+SECTIONS
+{
+  .text : {*(SORT_BY_NAME(SORT_BY_ALIGNMENT(.text*)))}
+  /DISCARD/ : { *(.*) }
+}
diff --git a/ld/testsuite/ld-scripts/sort_b_n_n-1.d b/ld/testsuite/ld-scripts/sort_b_n_n-1.d
new file mode 100644 (file)
index 0000000..0bc18ae
--- /dev/null
@@ -0,0 +1,14 @@
+#source: sort_n_a-a.s
+#source: sort_n_a-b.s
+#ld: -T sort_b_n_n.t
+#name: SORT_BY_NAME(SORT_BY_NAME())
+#nm: -n
+
+0[0-9a-f]* t texta
+0[0-9a-f]* t textb
+0[0-9a-f]* t text1a
+0[0-9a-f]* t text1b
+0[0-9a-f]* t text2a
+0[0-9a-f]* t text2b
+0[0-9a-f]* t text3a
+0[0-9a-f]* t text3b
diff --git a/ld/testsuite/ld-scripts/sort_b_n_n-2.d b/ld/testsuite/ld-scripts/sort_b_n_n-2.d
new file mode 100644 (file)
index 0000000..834bf90
--- /dev/null
@@ -0,0 +1,14 @@
+#source: sort_n_a-a.s
+#source: sort_n_a-b.s
+#ld: -T sort_b_n_n.t --sort-section name
+#name: SORT_BY_NAME(SORT_BY_NAME()) --sort-section name
+#nm: -n
+
+0[0-9a-f]* t texta
+0[0-9a-f]* t textb
+0[0-9a-f]* t text1a
+0[0-9a-f]* t text1b
+0[0-9a-f]* t text2a
+0[0-9a-f]* t text2b
+0[0-9a-f]* t text3a
+0[0-9a-f]* t text3b
diff --git a/ld/testsuite/ld-scripts/sort_b_n_n-3.d b/ld/testsuite/ld-scripts/sort_b_n_n-3.d
new file mode 100644 (file)
index 0000000..7ba8a8b
--- /dev/null
@@ -0,0 +1,14 @@
+#source: sort_n_a-a.s
+#source: sort_n_a-b.s
+#ld: -T sort_b_n_n.t --sort-section alignment
+#name: SORT_BY_NAME(SORT_BY_NAME()) --sort-section alignment
+#nm: -n
+
+0[0-9a-f]* t texta
+0[0-9a-f]* t textb
+0[0-9a-f]* t text1a
+0[0-9a-f]* t text1b
+0[0-9a-f]* t text2a
+0[0-9a-f]* t text2b
+0[0-9a-f]* t text3b
+0[0-9a-f]* t text3a
diff --git a/ld/testsuite/ld-scripts/sort_b_n_n.t b/ld/testsuite/ld-scripts/sort_b_n_n.t
new file mode 100644 (file)
index 0000000..b4eabfe
--- /dev/null
@@ -0,0 +1,5 @@
+SECTIONS
+{
+  .text : {*(SORT_BY_NAME(SORT_BY_NAME(.text*)))}
+  /DISCARD/ : { *(.*) }
+}
diff --git a/ld/testsuite/ld-scripts/sort_n_a-a.s b/ld/testsuite/ld-scripts/sort_n_a-a.s
new file mode 100644 (file)
index 0000000..77dfc35
--- /dev/null
@@ -0,0 +1,16 @@
+       .section .text2
+       .p2align 3
+text2a:
+       .long 0
+       .section .text3
+       .p2align 5
+text3a:
+       .long 0
+       .section .text1
+       .p2align 5
+text1a:
+       .long 0
+       .text
+texta:
+       .p2align 4
+       .long 0
diff --git a/ld/testsuite/ld-scripts/sort_n_a-b.s b/ld/testsuite/ld-scripts/sort_n_a-b.s
new file mode 100644 (file)
index 0000000..781ba4e
--- /dev/null
@@ -0,0 +1,16 @@
+       .section .text2
+       .p2align 3
+text2b:
+       .long 0
+       .section .text3
+       .p2align 6
+text3b:
+       .long 0
+       .section .text1
+       .p2align 5
+text1b:
+       .long 0
+       .text
+textb:
+       .p2align 4
+       .long 0
diff --git a/ld/testsuite/ld-scripts/sort_no-1.d b/ld/testsuite/ld-scripts/sort_no-1.d
new file mode 100644 (file)
index 0000000..aef7863
--- /dev/null
@@ -0,0 +1,9 @@
+#source: sort_b_n.s
+#ld: -T sort_no.t
+#name: no SORT_BY_NAME/SORT_BY_ALIGNMENT/SORT
+#nm: -n
+
+0[0-9a-f]* t text
+0[0-9a-f]* t text2
+0[0-9a-f]* t text3
+0[0-9a-f]* t text1
diff --git a/ld/testsuite/ld-scripts/sort_no-2.d b/ld/testsuite/ld-scripts/sort_no-2.d
new file mode 100644 (file)
index 0000000..ddcd1c1
--- /dev/null
@@ -0,0 +1,9 @@
+#source: sort_b_a.s
+#ld: -T sort_no.t
+#name: no SORT_BY_NAME/SORT_BY_ALIGNMENT/SORT
+#nm: -n
+
+0[0-9a-f]* t text
+0[0-9a-f]* t text2
+0[0-9a-f]* t text3
+0[0-9a-f]* t text1
diff --git a/ld/testsuite/ld-scripts/sort_no.t b/ld/testsuite/ld-scripts/sort_no.t
new file mode 100644 (file)
index 0000000..d797c79
--- /dev/null
@@ -0,0 +1,5 @@
+SECTIONS
+{
+  .text : {*(.text*)}
+  /DISCARD/ : { *(.*) }
+}
This page took 0.046174 seconds and 4 git commands to generate.