[RFC][PATCH v5 0/6] binutils patches for DT_GNU_FLAGS_1/DF_GNU_1_UNIQUE

classic Classic list List threaded Threaded
7 messages Options
Reply | Threaded
Open this post in threaded view
|

[RFC][PATCH v5 0/6] binutils patches for DT_GNU_FLAGS_1/DF_GNU_1_UNIQUE

Sourceware - binutils list mailing list
This patch series is in support of the glibc RTLD_SHARED work
discussed in https://sourceware.org/bugzilla/show_bug.cgi?id=22745.

This patch series adds changelog entries to the previous version.

It adds a DT_GNU_FLAGS_1 dynamic section and a DF_GNU_1_UNIQUE flag
which is intended to mark libraries which should implicitly be opened
as if RTLD_SHARED had been passed to dlmopen when the target namespace
is not LM_ID_BASE.

This patch series adds support for -z unique to ld, gold, and
readelf (and documents it in the help text and so forth).

It replaces previous patch series which (respectively):

 - added a DT_FLAGS_1 value (that flag space has been exhausted)
 - added a DT_GNU_UNIQUE section (whose contents were ignored)

Vivek Das Mohapatra (6):
  Define a new DT_GNU_FLAGS_1 dynamic section for ld, readelf et al
  Handle -z unique/-z nounique in ld
  Document -z unique/-z nounique in the ld man page and help output
  Handle DT_GNU_FLAGS_1 in readelf
  Define DT_GNU_FLAGS_1 and DF_GNU_1_UNIQUE for gold
  Implement and document -z unique / -z nounique handling in gold

 bfd/ChangeLog        | 46 +++++-----------------------------------------
 bfd/elflink.c        |  5 ++++-
 binutils/ChangeLog   |  5 +++++
 binutils/readelf.c   | 23 +++++++++++++++++++++++
 elfcpp/ChangeLog     |  5 +++++
 elfcpp/elfcpp.h      |  7 +++++++
 gold/ChangeLog       |  6 ++++++
 gold/layout.cc       |  6 ++++++
 gold/options.h       |  3 +++
 include/ChangeLog    |  5 +++++
 include/bfdlink.h    |  3 +++
 include/elf/common.h |  4 ++++
 ld/ChangeLog         |  7 +++++++
 ld/emultempl/elf.em  |  4 ++++
 ld/ld.texi           | 10 ++++++++++
 ld/lexsup.c          |  4 ++++
 16 files changed, 101 insertions(+), 42 deletions(-)

--
2.11.0

Reply | Threaded
Open this post in threaded view
|

[RFC][PATCH v5 1/6] Define a new DT_GNU_FLAGS_1 dynamic section for ld, readelf et al

Sourceware - binutils list mailing list
DT_GNU_FLAGS_1 added to the DT_VALRNGLO-DT_VALRNGHI range.
DT_GNU_FLAGS_1 value DF_GNU_1_UNIQUE added.
---
 include/ChangeLog    | 4 ++++
 include/elf/common.h | 4 ++++
 2 files changed, 8 insertions(+)

diff --git a/include/ChangeLog b/include/ChangeLog
index 49b9f038fa..c0303f0e6d 100644
--- a/include/ChangeLog
+++ b/include/ChangeLog
@@ -1,3 +1,7 @@
+2020-07-10  Vivek Das Mohapatra  <[hidden email]>
+
+ * elf/common.h (DT_GNU_FLAGS_1, DF_GNU_1_UNIQUE): Define.
+
 2020-07-09  John Baldwin  <[hidden email]>
 
  * elf/common.h (AT_FREEBSD_ARGC, AT_FREEBSD_ARGV, AT_FREEBSD_ENVC)
diff --git a/include/elf/common.h b/include/elf/common.h
index 88dd1c9983..1c62985b3b 100644
--- a/include/elf/common.h
+++ b/include/elf/common.h
@@ -1003,6 +1003,7 @@
    deliberate special case and we maintain it for backwards compatability.
  */
 #define DT_VALRNGLO 0x6ffffd00
+#define DT_GNU_FLAGS_1  0x6ffffdf4
 #define DT_GNU_PRELINKED 0x6ffffdf5
 #define DT_GNU_CONFLICTSZ 0x6ffffdf6
 #define DT_GNU_LIBLISTSZ 0x6ffffdf7
@@ -1066,6 +1067,9 @@
 #define DF_P1_LAZYLOAD 0x00000001
 #define DF_P1_GROUPPERM 0x00000002
 
+/* Flag value in the DT_GNU_FLAGS_1 /dynamic entry.  */
+#define DF_GNU_1_UNIQUE 0x00000001
+
 /* Flag value in in the DT_FLAGS_1 .dynamic entry.  */
 #define DF_1_NOW 0x00000001
 #define DF_1_GLOBAL 0x00000002
--
2.11.0

Reply | Threaded
Open this post in threaded view
|

[RFC][PATCH v5 2/6] Handle -z unique/-z nounique in ld

Sourceware - binutils list mailing list
In reply to this post by Sourceware - binutils list mailing list
Add (or suppress) a DT_GNU_FLAGS_1 dynamic section
with a bit flag value of DF_GNU_1_UNIQUE.
---
 bfd/ChangeLog       | 46 +++++-----------------------------------------
 bfd/elflink.c       |  5 ++++-
 include/ChangeLog   |  1 +
 include/bfdlink.h   |  3 +++
 ld/ChangeLog        |  5 +++++
 ld/emultempl/elf.em |  4 ++++
 6 files changed, 22 insertions(+), 42 deletions(-)

diff --git a/bfd/ChangeLog b/bfd/ChangeLog
index 3cb4881feb..001b00e36e 100644
--- a/bfd/ChangeLog
+++ b/bfd/ChangeLog
@@ -1,3 +1,8 @@
+2020-07-10  Vivek Das Mohapatra  <[hidden email]>
+
+ * elflink.c (bfd_elf_size_dynamic_sections): Call
+ _bfd_elf_add_dynamic_entry to add a DT_GNU_FLAGS_1 section.
+
 2020-07-10  Alan Modra  <[hidden email]>
 
  * elf64-ppc.h (struct ppc64_elf_params): Add power10_stubs.
@@ -370,47 +375,6 @@
  * elfxx-x86.h (elf_x86_link_hash_table): Remove
  readonly_dynrelocs_against_ifunc.
 
-2020-06-09  Alan Modra  <[hidden email]>
-
- * elf64-ppc.c (struct ppc_link_hash_table): Delete
- maybe_local_ifunc_resolver field.
- (build_global_entry_stubs_and_plt): Set local_ifunc_resolver in
- cases where maybe_local_ifunc_resolver was set.
- (ppc64_elf_relocate_section): Likewise.
- (ppc64_elf_finish_dynamic_sections): Downgrade ifunc with textrel
- error to a warning.
-
-2020-06-08  H.J. Lu  <[hidden email]>
-
- * elf-bfd.h (elf_link_hash_entry): Add tlsdesc_plt and
- tlsdesc_got.
- * elf32-arm.c (elf32_arm_link_hash_table): Remove tlsdesc_plt
- and dt_tlsdesc_got.
- (elf32_arm_size_dynamic_sections): Updated.  Clear
- root.tlsdesc_plt for DF_BIND_NOW.
- (elf32_arm_finish_dynamic_sections): Updated.
- (elf32_arm_output_arch_local_syms): Likewise.
- * elf32-nds32.c (nds32_elf_size_dynamic_sections): Updated.
- Clear root.tlsdesc_plt for DF_BIND_NOW.
- (nds32_elf_finish_dynamic_sections): Updated.
- * elf32-nds32.h (elf_nds32_link_hash_table): Remove
- dt_tlsdesc_plt and dt_tlsdesc_got.
- * elf64-x86-64.c (elf_x86_64_finish_dynamic_sections): Updated.
- * elfnn-aarch64.c (elf_aarch64_link_hash_table): Remove
- tlsdesc_plt and dt_tlsdesc_got.
- (elfNN_aarch64_allocate_dynrelocs): Updated.
- (elfNN_aarch64_finish_dynamic_sections): Likewise.
- (elfNN_aarch64_size_dynamic_sections): Updated.  Clear
- root.tlsdesc_plt for DF_BIND_NOW.  Don't check DF_BIND_NOW
- twice.
- * elfxx-x86.c (elf_x86_allocate_dynrelocs): Updated.
- (_bfd_x86_elf_size_dynamic_sections): Likewise.
- (_bfd_x86_elf_finish_dynamic_sections): Likewise.
- * elfxx-x86.h (elf_x86_link_hash_table): Remove tlsdesc_plt and
- tlsdesc_got.
-
-2020-06-07  H.J. Lu  <[hidden email]>
-
  * elf32-tic6x.c (elf32_bed): Defined the default to
  elf32_tic6x_bed.
 
diff --git a/bfd/elflink.c b/bfd/elflink.c
index 998b72f228..be6ba056f4 100644
--- a/bfd/elflink.c
+++ b/bfd/elflink.c
@@ -7132,7 +7132,10 @@ bfd_elf_size_dynamic_sections (bfd *output_bfd,
       || !_bfd_elf_add_dynamic_entry (info, DT_SYMTAB, 0)
       || !_bfd_elf_add_dynamic_entry (info, DT_STRSZ, strsize)
       || !_bfd_elf_add_dynamic_entry (info, DT_SYMENT,
-      bed->s->sizeof_sym))
+      bed->s->sizeof_sym)
+              || (info->gnu_flags_1
+                  && !_bfd_elf_add_dynamic_entry (info, DT_GNU_FLAGS_1,
+                                                  info->gnu_flags_1)))
     return FALSE;
  }
     }
diff --git a/include/ChangeLog b/include/ChangeLog
index c0303f0e6d..d5615db4b1 100644
--- a/include/ChangeLog
+++ b/include/ChangeLog
@@ -1,6 +1,7 @@
 2020-07-10  Vivek Das Mohapatra  <[hidden email]>
 
  * elf/common.h (DT_GNU_FLAGS_1, DF_GNU_1_UNIQUE): Define.
+ * bfdlink.h (struct bfd_link_info): New field gnu_flags_1.
 
 2020-07-09  John Baldwin  <[hidden email]>
 
diff --git a/include/bfdlink.h b/include/bfdlink.h
index 7163433383..e66c324040 100644
--- a/include/bfdlink.h
+++ b/include/bfdlink.h
@@ -649,6 +649,9 @@ struct bfd_link_info
   /* May be used to set DT_FLAGS_1 for ELF. */
   bfd_vma flags_1;
 
+  /* May be used to set DT_GNU_FLAGS_1 for ELF. */
+  bfd_vma gnu_flags_1;
+
   /* May be used to set ELF visibility for __start_* / __stop_.  */
   unsigned int start_stop_visibility;
 
diff --git a/ld/ChangeLog b/ld/ChangeLog
index c0bbaf95df..b10c354776 100644
--- a/ld/ChangeLog
+++ b/ld/ChangeLog
@@ -1,3 +1,8 @@
+2020-07-10  Vivek Das Mohapatra  <[hidden email]>
+
+ * emultempl/elf.em (gld${EMULATION_NAME}_handle_option):
+ Parse -z unique / -z nounique options.
+
 2020-07-10  Alan Modra  <[hidden email]>
 
  * ld.texi (PowerPC64 ELF64): Document --no-inline-optimize,
diff --git a/ld/emultempl/elf.em b/ld/emultempl/elf.em
index 356f34538b..32e8754ab7 100644
--- a/ld/emultempl/elf.em
+++ b/ld/emultempl/elf.em
@@ -805,6 +805,10 @@ fragment <<EOF
   link_info.flags |= (bfd_vma) DF_ORIGIN;
   link_info.flags_1 |= (bfd_vma) DF_1_ORIGIN;
  }
+      else if (strcmp (optarg, "unique") == 0)
+        link_info.gnu_flags_1 |= (bfd_vma) DF_GNU_1_UNIQUE;
+      else if (strcmp (optarg, "nounique") == 0)
+        link_info.gnu_flags_1 &= ~(bfd_vma) DF_GNU_1_UNIQUE;
       else if (strcmp (optarg, "combreloc") == 0)
  link_info.combreloc = TRUE;
       else if (strcmp (optarg, "nocombreloc") == 0)
--
2.11.0

Reply | Threaded
Open this post in threaded view
|

[RFC][PATCH v5 3/6] Document -z unique/-z nounique in the ld man page and help output

Sourceware - binutils list mailing list
In reply to this post by Sourceware - binutils list mailing list
---
 ld/ChangeLog |  2 ++
 ld/ld.texi   | 10 ++++++++++
 ld/lexsup.c  |  4 ++++
 3 files changed, 16 insertions(+)

diff --git a/ld/ChangeLog b/ld/ChangeLog
index b10c354776..45fa71f6cf 100644
--- a/ld/ChangeLog
+++ b/ld/ChangeLog
@@ -2,6 +2,8 @@
 
  * emultempl/elf.em (gld${EMULATION_NAME}_handle_option):
  Parse -z unique / -z nounique options.
+ * ld.texi (Options): Document -z unique and -z nounique.
+ * lexsup.c (elf_shlib_list_options): Likewise.
 
 2020-07-10  Alan Modra  <[hidden email]>
 
diff --git a/ld/ld.texi b/ld/ld.texi
index 165a3d935e..61bf4e0fa9 100644
--- a/ld/ld.texi
+++ b/ld/ld.texi
@@ -1305,6 +1305,16 @@ Specify that the dynamic loader should modify its symbol search order
 so that symbols in this shared library interpose all other shared
 libraries not so marked.
 
+@item unique
+@itemx nounique
+When generating a shared library or other dynamically loadable ELF
+object mark it as one that should (by default) only ever be loaded once,
+and only in the main namespace (when using @code{dlmopen}). This is
+primarily used to mark fundamental libraries such as libc, libpthread et
+al which do not usually function correctly unless they are the sole instances
+of themselves. This behaviour can be overridden by the @code{dlmopen} caller
+and does not apply to certain loading mechanisms (such as audit libraries).
+
 @item lazy
 When generating an executable or shared library, mark it to tell the
 dynamic linker to defer function call resolution to the point when
diff --git a/ld/lexsup.c b/ld/lexsup.c
index a79bec0b45..1f12ccb4c0 100644
--- a/ld/lexsup.c
+++ b/ld/lexsup.c
@@ -1925,6 +1925,10 @@ elf_shlib_list_options (FILE *file)
   fprintf (file, _("\
   -z interpose                Mark object to interpose all DSOs but executable\n"));
   fprintf (file, _("\
+  -z unique                   Mark DSO to be loaded at most once by default, and only in the main namespace\n"));
+  fprintf (file, _("\
+  -z nounique                 Don't mark DSO as a loadable at most once\n"));
+  fprintf (file, _("\
   -z lazy                     Mark object lazy runtime binding (default)\n"));
   fprintf (file, _("\
   -z loadfltr                 Mark object requiring immediate process\n"));
--
2.11.0

Reply | Threaded
Open this post in threaded view
|

[RFC][PATCH v5 4/6] Handle DT_GNU_FLAGS_1 in readelf

Sourceware - binutils list mailing list
In reply to this post by Sourceware - binutils list mailing list
---
 binutils/ChangeLog |  5 +++++
 binutils/readelf.c | 23 +++++++++++++++++++++++
 2 files changed, 28 insertions(+)

diff --git a/binutils/ChangeLog b/binutils/ChangeLog
index df8b90e095..db7e87c357 100644
--- a/binutils/ChangeLog
+++ b/binutils/ChangeLog
@@ -1,3 +1,8 @@
+2020-07-10  Vivek Das Mohapatra  <[hidden email]>
+
+ * readelf.c (get_dynamic_type): Handle DT_GNU_FLAGS_1.
+ (process_dynamic_section): Likewise.
+
 2020-07-10  Tom de Vries  <[hidden email]>
 
  * dwarf.c (display_debug_lines_decoded): Don't emit meaningless
diff --git a/binutils/readelf.c b/binutils/readelf.c
index 0feeed9831..1c26de5726 100644
--- a/binutils/readelf.c
+++ b/binutils/readelf.c
@@ -2229,6 +2229,7 @@ get_dynamic_type (Filedata * filedata, unsigned long type)
     case DT_GNU_LIBLIST: return "GNU_LIBLIST";
     case DT_GNU_LIBLISTSZ: return "GNU_LIBLISTSZ";
     case DT_GNU_HASH: return "GNU_HASH";
+    case DT_GNU_FLAGS_1: return "GNU_FLAGS_1";
 
     default:
       if ((type >= DT_LOPROC) && (type <= DT_HIPROC))
@@ -10941,6 +10942,28 @@ the .dynstr section doesn't match the DT_STRTAB and DT_STRSZ tags\n"));
     }
   break;
 
+        case DT_GNU_FLAGS_1:
+  if (do_dynamic)
+    {
+      printf (_("Flags:"));
+      if (entry->d_un.d_val == 0)
+ printf (_(" None\n"));
+      else
+ {
+  unsigned long int val = entry->d_un.d_val;
+
+  if (val & DF_GNU_1_UNIQUE)
+    {
+      printf (" UNIQUE");
+      val ^= DF_GNU_1_UNIQUE;
+    }
+  if (val != 0)
+    printf (" %lx", val);
+  puts ("");
+ }
+    }
+          break;
+
  default:
   if ((entry->d_tag >= DT_VERSYM) && (entry->d_tag <= DT_VERNEEDNUM))
     filedata->version_info[DT_VERSIONTAGIDX (entry->d_tag)]
--
2.11.0

Reply | Threaded
Open this post in threaded view
|

[RFC][PATCH v5 5/6] Define DT_GNU_FLAGS_1 and DF_GNU_1_UNIQUE for gold

Sourceware - binutils list mailing list
In reply to this post by Sourceware - binutils list mailing list
---
 elfcpp/ChangeLog | 5 +++++
 elfcpp/elfcpp.h  | 7 +++++++
 2 files changed, 12 insertions(+)

diff --git a/elfcpp/ChangeLog b/elfcpp/ChangeLog
index efb82c5770..5cb9933bb9 100644
--- a/elfcpp/ChangeLog
+++ b/elfcpp/ChangeLog
@@ -1,3 +1,8 @@
+2020-07-10  Vivek Das Mohapatra  <[hidden email]>
+
+ * elfcpp.h (enum DT): New enum member DT_GNU_FLAGS_1.
+ (enum DF_GNU_1): New enum DF_GNU_1 containing DF_GNU_1_UNIQUE.
+
 2020-07-04  Nick Clifton  <[hidden email]>
 
  Binutils 2.35 branch created.
diff --git a/elfcpp/elfcpp.h b/elfcpp/elfcpp.h
index 9c7c6294e4..19a10e1dba 100644
--- a/elfcpp/elfcpp.h
+++ b/elfcpp/elfcpp.h
@@ -728,6 +728,7 @@ enum DT
 
   // The remaining values are extensions used by GNU or Solaris.
   DT_VALRNGLO = 0x6ffffd00,
+  DT_GNU_FLAGS_1 = 0x6ffffdf4,
   DT_GNU_PRELINKED = 0x6ffffdf5,
   DT_GNU_CONFLICTSZ = 0x6ffffdf6,
   DT_GNU_LIBLISTSZ = 0x6ffffdf7,
@@ -917,6 +918,12 @@ enum DF_1
   DF_1_PIE = 0x08000000
 };
 
+// Flags found in the DT_GNU_FLAGS_1 dynamic element.
+enum DF_GNU_1
+{
+  DF_GNU_1_UNIQUE = 0x1,
+};
+
 // Version numbers which appear in the vd_version field of a Verdef
 // structure.
 
--
2.11.0

Reply | Threaded
Open this post in threaded view
|

[RFC][PATCH v5 6/6] Implement and document -z unique / -z nounique handling in gold

Sourceware - binutils list mailing list
In reply to this post by Sourceware - binutils list mailing list
---
 gold/ChangeLog | 6 ++++++
 gold/layout.cc | 6 ++++++
 gold/options.h | 3 +++
 3 files changed, 15 insertions(+)

diff --git a/gold/ChangeLog b/gold/ChangeLog
index f7520ba3cd..2a85fb78d1 100644
--- a/gold/ChangeLog
+++ b/gold/ChangeLog
@@ -1,3 +1,9 @@
+2020-07-10  Vivek Das Mohapatra  <[hidden email]>
+
+ Implement -z unique / -z nounique options.
+ * layout.cc (Layout::finish_dynamic_section): Set DF_GNU_1_UNIQUE.
+ * options.h (class General_options): Handle -z unique, -z nounique.
+
 2020-07-08  Nick Clifton  <[hidden email]>
 
  * testsuite/script_test_7.sh: Adjust expected address of the .bss
diff --git a/gold/layout.cc b/gold/layout.cc
index 13e533aaf2..9c4fc0d22d 100644
--- a/gold/layout.cc
+++ b/gold/layout.cc
@@ -5358,6 +5358,12 @@ Layout::finish_dynamic_section(const Input_objects* input_objects,
     flags |= elfcpp::DF_1_PIE;
   if (flags != 0)
     odyn->add_constant(elfcpp::DT_FLAGS_1, flags);
+
+  flags = 0;
+  if (parameters->options().unique())
+    flags |= elfcpp::DF_GNU_1_UNIQUE;
+  if (flags != 0)
+    odyn->add_constant(elfcpp::DT_GNU_FLAGS_1, flags);
 }
 
 // Set the size of the _DYNAMIC symbol table to be the size of the
diff --git a/gold/options.h b/gold/options.h
index 3c8d25a662..8902b94a84 100644
--- a/gold/options.h
+++ b/gold/options.h
@@ -1463,6 +1463,9 @@ class General_options
   DEFINE_bool(interpose, options::DASH_Z, '\0', false,
       N_("Mark object to interpose all DSOs but executable"),
       NULL);
+  DEFINE_bool(unique, options::DASH_Z, '\0', false,
+              N_("Mark DSO to be loaded at most once, and only in the main namespace"),
+              N_("Do not mark the DSO as one to be loaded only in the main namespace"));
   DEFINE_bool_alias(lazy, now, options::DASH_Z, '\0',
     N_("Mark object for lazy runtime binding"),
     NULL, true);
--
2.11.0