[55/59] ld: new options --ctf-variables and --ctf-share-types

Message ID 20200630233146.338613-56-nick.alcock@oracle.com
State New
Headers show
Series
  • Deduplicating CTF linker
Related show

Commit Message

H.J. Lu via Binutils June 30, 2020, 11:31 p.m.
libctf recently changed to make it possible to not emit the CTF
variables section.  Make this the default for ld: the variables section
is a simple name -> type mapping, and the names can be quite voluminous.
Nothing in the variables section appears in the symbol table, by
definition, so GDB cannot make use of them: special-purpose projects
that implement their own analogues of symbol table lookup can do so, but
they'll need to tell the linker to emit the variables section after all.

The new --ctf-variables option does this.

The --ctf-share-types option (valid values "share-duplicated" and
"share-unconflicted") allow the caller to specify the CTF link mode.
Most users will want share-duplicated, since it allows for more
convenient debugging: but very large projects composed of many decoupled
components may want to use share-unconflicted mode, which places types
that appear in only one TU into per-TU dicts.  (They may also want to
relink the CTF using the ctf_link API and cu-mapping, to make their
"components" larger than a single TU.  Right now the linker does not
expose the CU-mapping machinery.  Perhaps it should in future to make
this use case easier.)

For now, giving the linker the ability to emit share-duplicated CTF lets
us add testcases for that mode to the testsuite.

ld/
	* ldlex.h (option_values) <OPTION_CTF_VARIABLES,
	OPTION_NO_CTF_VARIABLES, OPTION_CTF_SHARE_TYPES>: New.
	* ld.h (ld_config_type) <ctf_variables, ctf_share_duplicated>:
	New fields.
	* ldlang.c (lang_merge_ctf): Use them.
	* lexsup.c (ld_options): Add ctf-variables, no-ctf-variables,
	ctf-share-types.
	(parse_args) <OPTION_CTF_VARIABLES, OPTION_NO_CTF_VARIABLES,
	OPTION_CTF_SHARE_TYPES>: New cases.
	* ld.texi: Document new options.
	* NEWS: Likewise.
---
 ld/NEWS     | 10 ++++++++++
 ld/ld.h     |  8 ++++++++
 ld/ld.texi  | 34 ++++++++++++++++++++++++++++++++++
 ld/ldlang.c | 10 +++++++++-
 ld/ldlex.h  |  3 +++
 ld/lexsup.c | 29 +++++++++++++++++++++++++++++
 6 files changed, 93 insertions(+), 1 deletion(-)

-- 
2.27.0.247.g3dff7de930

Patch

diff --git a/ld/NEWS b/ld/NEWS
index b236e588c6f..f7241a87c1d 100644
--- a/ld/NEWS
+++ b/ld/NEWS
@@ -1,5 +1,15 @@ 
 -*- text -*-
 
+* The linker now deduplicates the types in .ctf sections.  The new
+  command-line option --ctf-share-types describes how to do this:
+  its default value, share-unconflicted, produces the most compact
+  output.
+
+* The linker now omits the "variable section" from .ctf sections by
+  default, saving space.  This is almost certainly what you want
+  unless you are working on a project that has its own analogue
+  of symbol tables that are not reflected in the ELF symtabs.
+
 * X86 NaCl target support is removed.
 
 * Add ELF linker command-line options, --export-dynamic-symbol and
diff --git a/ld/ld.h b/ld/ld.h
index 1790dc81a66..7f7d71672e6 100644
--- a/ld/ld.h
+++ b/ld/ld.h
@@ -302,6 +302,14 @@  typedef struct
 
   /* If set, print discarded sections in map file output.  */
   bfd_boolean print_map_discarded;
+
+  /* If set, emit the names and types of statically-linked variables
+     into the CTF.  */
+  bfd_boolean ctf_variables;
+
+  /* If set, share only duplicated types in CTF, rather than sharing
+     all types that are not in conflict.  */
+  bfd_boolean ctf_share_duplicated;
 } ld_config_type;
 
 extern ld_config_type config;
diff --git a/ld/ld.texi b/ld/ld.texi
index 40b042de9b9..2a740706e0c 100644
--- a/ld/ld.texi
+++ b/ld/ld.texi
@@ -1612,6 +1612,40 @@  definition.  If the symbol is defined as a common value then any files
 where this happens appear next.  Finally any files that reference the
 symbol are listed.
 
+@cindex ctf variables
+@kindex --ctf-variables
+@kindex --no-ctf-variables
+@item --ctf-variables
+@item --no-ctf-variables
+The CTF debuginfo format supports a section which encodes the names and
+types of variables found in the program which do not appear in any symbol
+table. These variables clearly cannot be looked up by address by
+conventional debuggers, so the space used for their types and names is
+usually wasted: the types are usually small but the names are often not.
+@option{--ctf-variables} causes the generation of such a section.
+The default behaviour can be restored with @option{--no-ctf-variables}.
+
+@cindex ctf type sharing
+@kindex --ctf-share-types
+@item --ctf-share-types=@var{method}
+Adjust the method used to share types between translation units in CTF.
+
+@table @samp
+@item share-unconflicted
+Put all types that do not have ambiguous definitions into the shared dictionary,
+where debuggers can easily access them, even if they only occur in one
+translation unit.  This is the default.
+
+@item share-duplicated
+Put only types that occur in multiple translation units into the shared
+dictionary: types with only one definition go into per-translation-unit
+dictionaries.  Types with ambiguous definitions in multiple translation units
+always go into per-translation-unit dictionaries.  This tends to make the CTF
+larger, but may reduce the amount of CTF in the shared dictionary.  For very
+large projects this may speed up opening the CTF and save memory in the CTF
+consumer at runtime.
+@end table
+
 @cindex common allocation
 @kindex --no-define-common
 @item --no-define-common
diff --git a/ld/ldlang.c b/ld/ldlang.c
index ea947a8cd3c..da89838ed3d 100644
--- a/ld/ldlang.c
+++ b/ld/ldlang.c
@@ -3756,6 +3756,7 @@  static void
 lang_merge_ctf (void)
 {
   asection *output_sect;
+  int flags = 0;
 
   if (!ctf_output)
     return;
@@ -3792,7 +3793,14 @@  lang_merge_ctf (void)
 	}
     }
 
-  if (ctf_link (ctf_output, CTF_LINK_SHARE_UNCONFLICTED) < 0)
+  if (!config.ctf_share_duplicated)
+    flags = CTF_LINK_SHARE_UNCONFLICTED;
+  else
+    flags = CTF_LINK_SHARE_DUPLICATED;
+  if (!config.ctf_variables)
+    flags |= CTF_LINK_OMIT_VARIABLES_SECTION;
+
+  if (ctf_link (ctf_output, flags) < 0)
     {
       einfo (_("%P: warning: CTF linking failed; "
 	       "output will have no CTF section: `%s'\n"),
diff --git a/ld/ldlex.h b/ld/ldlex.h
index 5ea083ebeb3..6eac75cef53 100644
--- a/ld/ldlex.h
+++ b/ld/ldlex.h
@@ -155,6 +155,9 @@  enum option_values
   OPTION_NON_CONTIGUOUS_REGIONS,
   OPTION_NON_CONTIGUOUS_REGIONS_WARNINGS,
   OPTION_DEPENDENCY_FILE,
+  OPTION_CTF_VARIABLES,
+  OPTION_NO_CTF_VARIABLES,
+  OPTION_CTF_SHARE_TYPES,
 };
 
 /* The initial parser states.  */
diff --git a/ld/lexsup.c b/ld/lexsup.c
index 58c6c078325..d8b06736ed6 100644
--- a/ld/lexsup.c
+++ b/ld/lexsup.c
@@ -572,6 +572,18 @@  static const struct ld_option ld_options[] =
   { {"no-print-map-discarded", no_argument, NULL, OPTION_NO_PRINT_MAP_DISCARDED},
     '\0', NULL, N_("Do not show discarded sections in map file output"),
     TWO_DASHES },
+  { {"ctf-variables", no_argument, NULL, OPTION_CTF_VARIABLES},
+    '\0', NULL, N_("Emit names and types of static variables in CTF"),
+    TWO_DASHES },
+  { {"no-ctf-variables", no_argument, NULL, OPTION_NO_CTF_VARIABLES},
+    '\0', NULL, N_("Do not emit names and types of static variables in CTF"),
+    TWO_DASHES },
+  { {"ctf-share-types=<method>", required_argument, NULL,
+     OPTION_CTF_SHARE_TYPES},
+    '\0', NULL, N_("How to share CTF types between translation units.\n"
+		   "                                <method> is: share-unconflicted (default),\n"
+		   "                                             share-duplicated"),
+    TWO_DASHES },
 };
 
 #define OPTION_COUNT ARRAY_SIZE (ld_options)
@@ -1637,6 +1649,23 @@  parse_args (unsigned argc, char **argv)
 	case OPTION_DEPENDENCY_FILE:
 	  config.dependency_file = optarg;
 	  break;
+
+	case OPTION_CTF_VARIABLES:
+	  config.ctf_variables = TRUE;
+	  break;
+
+	case OPTION_NO_CTF_VARIABLES:
+	  config.ctf_variables = FALSE;
+	  break;
+
+	case OPTION_CTF_SHARE_TYPES:
+	  if (strcmp (optarg, "share-unconflicted") == 0)
+	    config.ctf_share_duplicated = FALSE;
+	  else if (strcmp (optarg, "share-duplicated") == 0)
+	    config.ctf_share_duplicated = TRUE;
+	  else
+	    einfo (_("%F%P: bad --ctf-share-types option: %s\n"), optarg);
+	  break;
 	}
     }