[RFC,v2,2/6] Handle DT_GNU_UNIQUE/--unique-dso in ld

Message ID 20200617135945.12716-3-vivek@collabora.com
State New
Headers show
Series
  • binutils patches to add DT_GNU_UNIQUE
Related show

Commit Message

Alan Modra via Binutils June 17, 2020, 1:59 p.m.
---
 bfd/elflink.c       | 4 +++-
 include/bfdlink.h   | 3 +++
 ld/emultempl/elf.em | 8 +++++++-
 3 files changed, 13 insertions(+), 2 deletions(-)

-- 
2.11.0

Patch

diff --git a/bfd/elflink.c b/bfd/elflink.c
index 3e56a297f6..99ecba42b3 100644
--- a/bfd/elflink.c
+++ b/bfd/elflink.c
@@ -7124,7 +7124,9 @@  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->unique_dso
+		  && !_bfd_elf_add_dynamic_entry (info, DT_GNU_UNIQUE, 1)))
 	    return FALSE;
 	}
     }
diff --git a/include/bfdlink.h b/include/bfdlink.h
index 34a0d2ec4e..d47d085d03 100644
--- a/include/bfdlink.h
+++ b/include/bfdlink.h
@@ -657,6 +657,9 @@  struct bfd_link_info
 
   /* The version information.  */
   struct bfd_elf_version_tree *version_info;
+
+  /* Tag DSO to be loaded at most once (with a DT_GNU_UNIQUE section).  */
+  unsigned int unique_dso: 1;
 };
 
 /* Some forward-definitions used by some callbacks.  */
diff --git a/ld/emultempl/elf.em b/ld/emultempl/elf.em
index c4979eb953..feecc7fbce 100644
--- a/ld/emultempl/elf.em
+++ b/ld/emultempl/elf.em
@@ -551,7 +551,8 @@  enum elf_options
   OPTION_HASH_STYLE,
   OPTION_BUILD_ID,
   OPTION_AUDIT,
-  OPTION_COMPRESS_DEBUG
+  OPTION_COMPRESS_DEBUG,
+  OPTION_UNIQUE_DSO,
 };
 
 static void
@@ -591,6 +592,7 @@  fragment <<EOF
     {"no-eh-frame-hdr", no_argument, NULL, OPTION_NO_EH_FRAME_HDR},
     {"exclude-libs", required_argument, NULL, OPTION_EXCLUDE_LIBS},
     {"hash-style", required_argument, NULL, OPTION_HASH_STYLE},
+    {"unique-dso", no_argument, NULL, OPTION_UNIQUE_DSO},
 EOF
 fi
 if test -n "$PARSE_AND_LIST_LONGOPTS" ; then
@@ -696,6 +698,10 @@  fragment <<EOF
 	einfo (_("%F%P: invalid hash style \`%s'\n"), optarg);
       break;
 
+    case OPTION_UNIQUE_DSO:
+      link_info.unique_dso = 1;
+      break;
+
 EOF
 fi
 fragment <<EOF