public inbox for binutils@sourceware.org
 help / color / mirror / Atom feed
* [PATCH v2 0/2] elf: Implement indirect external access marker
@ 2021-06-22 23:57 H.J. Lu
  2021-06-22 23:57 ` [PATCH v2 1/2] elf: Add GNU_PROPERTY_1_NEEDED H.J. Lu
                   ` (2 more replies)
  0 siblings, 3 replies; 12+ messages in thread
From: H.J. Lu @ 2021-06-22 23:57 UTC (permalink / raw)
  To: binutils; +Cc: Florian Weimer, Alan Modra, Nick Clifton, Richard Earnshaw

Changes in the v2 patch.

1. Rename GNU_PROPERTY_1_NEEDED_SINGLE_GLOBAL_DEFINITION to
GNU_PROPERTY_1_NEEDED_INDIRECT_EXTERN_ACCESS.
2. Rename the option to -z [no]indirect-extern-access and move it to
ld/emulparams/extern_protected_data.sh.
3. Clear the indirect external access bit in executable when there are
non-GOT or non-PLT relocations in relocatable input files without this
bit set.
4. Add more tests.

---
On systems with copy relocation:
* A copy in executable is created for the definition in a shared library
at run-time by ld.so.
* The copy is referenced by executable and shared libraries.
* Executable can access the copy directly.

Issues are:
* Overhead of a copy, time and space, may be visible at run-time.
* Read-only data in the shared library becomes read-write copy in
executable at run-time.
* Local access to data with the STV_PROTECTED visibility in the shared
library must use GOT.

On systems without function descriptor, function pointers vary depending
on where and how the functions are defined.
* If the function is defined in executable, it can be the address of
function body.
* If the function, including the function with STV_PROTECTED visibility,
is defined in the shared library, it can be the address of the PLT entry
in executable or shared library.

Issues are:
* The address of function body may not be used as its function pointer.
* ld.so needs to search loaded shared libraries for the function pointer
of the function with STV_PROTECTED visibility.

Here is a proposal to remove copy relocation and use canonical function
pointer:

1. Accesses, including in PIE and non-PIE, to undefined symbols must
use GOT.
  a. Linker may optimize out GOT access if the data is defined in PIE or
  non-PIE.
2. Read-only data in the shared library remain read-only at run-time
3. Address of global data with the STV_PROTECTED visibility in the shared
library is the address of data body.
  a. Can use IP-relative access.
  b. May need GOT without IP-relative access.
4. For systems without function descriptor,
  a. All global function pointers of undefined functions in PIE and
  non-PIE must use GOT.  Linker may optimize out GOT access if the
  function is defined in PIE or non-PIE.
  b. Function pointer of functions with the STV_PROTECTED visibility in
  executable and shared library is the address of function body.
   i. Can use IP-relative access.
   ii. May need GOT without IP-relative access.
   iii. Branches to undefined functions may use PLT.
5. Single global definition marker:

Add GNU_PROPERTY_1_NEEDED:

#define GNU_PROPERTY_1_NEEDED GNU_PROPERTY_UINT32_OR_LO

to indicate the needed properties by the object file.

Add GNU_PROPERTY_1_NEEDED_INDIRECT_EXTERN_ACCESS:

#define GNU_PROPERTY_1_NEEDED_INDIRECT_EXTERN_ACCESS (1U << 0)

to indicate that the object file requires canonical function pointers and
cannot be used with copy relocation.

  a. Copy relocation should be disallowed at link-time and run-time.
  b. Canonical function pointers are required at link-time and run-tima

Linker change:

If any relocatable input files contain the indirect external access
marker:
* Generate the indirect external access marker in output.
  a. Linker should clear the indirect external access bit in executable
     when there are non-GOT or non-PLT relocations in relocatable input
     files without this bit set.
* Avoid copy relocation if possible.
* Access to symbols with the STV_PROTECTED visibility is the same as
local access.
* For systems without function descriptor, function pointer is the address
of function body.

H.J. Lu (2):
  elf: Add GNU_PROPERTY_1_NEEDED
  elf: Add GNU_PROPERTY_1_NEEDED check

 bfd/elf-bfd.h                                 |   6 +
 bfd/elf-properties.c                          | 126 ++++++++++++++---
 bfd/elf32-i386.c                              |   3 +
 bfd/elf64-x86-64.c                            |   6 +-
 bfd/elflink.c                                 |   4 +
 bfd/elfxx-x86.c                               |  19 +++
 bfd/elfxx-x86.h                               |   4 +
 binutils/readelf.c                            |  39 ++++++
 include/bfdlink.h                             |  23 ++-
 include/elf/common.h                          |   7 +
 ld/NEWS                                       |   3 +
 ld/emulparams/extern_protected_data.sh        |  11 ++
 ld/ld.texi                                    |  12 ++
 ld/ldmain.c                                   |   1 +
 .../ld-elf/indirect-extern-access-1.rd        |   8 ++
 .../ld-elf/indirect-extern-access-1a.c        |   1 +
 .../ld-elf/indirect-extern-access-1b.c        |  12 ++
 .../ld-elf/indirect-extern-access-2.rd        |   8 ++
 .../ld-elf/indirect-extern-access-2a.c        |  10 ++
 .../ld-elf/indirect-extern-access-2b.c        |  13 ++
 .../ld-elf/indirect-extern-access-3.rd        |   8 ++
 ld/testsuite/ld-elf/indirect-extern-access.S  |  20 +++
 ld/testsuite/ld-elf/linux-x86.exp             |  97 +++++++++++++
 ld/testsuite/ld-elf/property-1_needed-1.s     |  15 ++
 ld/testsuite/ld-elf/property-1_needed-1a.d    |  17 +++
 ld/testsuite/ld-elf/property-1_needed-1b.d    |  16 +++
 ld/testsuite/ld-elf/property-1_needed-1c.d    |  17 +++
 .../ld-x86-64/indirect-extern-access.rd       |   6 +
 ld/testsuite/ld-x86-64/protected-data-1.h     |  11 ++
 ld/testsuite/ld-x86-64/protected-data-1a.c    |  40 ++++++
 ld/testsuite/ld-x86-64/protected-data-1b.c    |  59 ++++++++
 ld/testsuite/ld-x86-64/protected-data-2a.S    | 109 +++++++++++++++
 ld/testsuite/ld-x86-64/protected-data-2b.S    | 119 ++++++++++++++++
 ld/testsuite/ld-x86-64/protected-func-2a.S    |  68 +++++++++
 ld/testsuite/ld-x86-64/protected-func-2b.S    |  83 +++++++++++
 ld/testsuite/ld-x86-64/protected-func-2c.c    |  29 ++++
 ld/testsuite/ld-x86-64/x86-64.exp             | 131 ++++++++++++++++++
 37 files changed, 1138 insertions(+), 23 deletions(-)
 create mode 100644 ld/testsuite/ld-elf/indirect-extern-access-1.rd
 create mode 100644 ld/testsuite/ld-elf/indirect-extern-access-1a.c
 create mode 100644 ld/testsuite/ld-elf/indirect-extern-access-1b.c
 create mode 100644 ld/testsuite/ld-elf/indirect-extern-access-2.rd
 create mode 100644 ld/testsuite/ld-elf/indirect-extern-access-2a.c
 create mode 100644 ld/testsuite/ld-elf/indirect-extern-access-2b.c
 create mode 100644 ld/testsuite/ld-elf/indirect-extern-access-3.rd
 create mode 100644 ld/testsuite/ld-elf/indirect-extern-access.S
 create mode 100644 ld/testsuite/ld-elf/property-1_needed-1.s
 create mode 100644 ld/testsuite/ld-elf/property-1_needed-1a.d
 create mode 100644 ld/testsuite/ld-elf/property-1_needed-1b.d
 create mode 100644 ld/testsuite/ld-elf/property-1_needed-1c.d
 create mode 100644 ld/testsuite/ld-x86-64/indirect-extern-access.rd
 create mode 100644 ld/testsuite/ld-x86-64/protected-data-1.h
 create mode 100644 ld/testsuite/ld-x86-64/protected-data-1a.c
 create mode 100644 ld/testsuite/ld-x86-64/protected-data-1b.c
 create mode 100644 ld/testsuite/ld-x86-64/protected-data-2a.S
 create mode 100644 ld/testsuite/ld-x86-64/protected-data-2b.S
 create mode 100644 ld/testsuite/ld-x86-64/protected-func-2a.S
 create mode 100644 ld/testsuite/ld-x86-64/protected-func-2b.S
 create mode 100644 ld/testsuite/ld-x86-64/protected-func-2c.c

-- 
2.31.1


^ permalink raw reply	[flat|nested] 12+ messages in thread

* [PATCH v2 1/2] elf: Add GNU_PROPERTY_1_NEEDED
  2021-06-22 23:57 [PATCH v2 0/2] elf: Implement indirect external access marker H.J. Lu
@ 2021-06-22 23:57 ` H.J. Lu
  2021-06-22 23:57 ` [PATCH v2 2/2] elf: Add GNU_PROPERTY_1_NEEDED check H.J. Lu
  2021-07-07 13:58 ` [PATCH v2 0/2] elf: Implement indirect external access marker H.J. Lu
  2 siblings, 0 replies; 12+ messages in thread
From: H.J. Lu @ 2021-06-22 23:57 UTC (permalink / raw)
  To: binutils; +Cc: Florian Weimer, Alan Modra, Nick Clifton, Richard Earnshaw

Add GNU_PROPERTY_1_NEEDED:

 #define GNU_PROPERTY_1_NEEDED      GNU_PROPERTY_UINT32_OR_LO

to indicate the needed properties by the object file.

Add GNU_PROPERTY_1_NEEDED_INDIRECT_EXTERN_ACCESS:

 #define GNU_PROPERTY_1_NEEDED_INDIRECT_EXTERN_ACCESS  (1U << 0)

to indicate that the object file requires canonical function pointers and
cannot be used with copy relocation.

binutils/

	* readelf.c (decode_1_needed): New.
	(print_gnu_property_note): Handle GNU_PROPERTY_1_NEEDED.

include/

	* elf/common.h (GNU_PROPERTY_1_NEEDED): New.
	(GNU_PROPERTY_1_NEEDED_INDIRECT_EXTERN_ACCESS): Likewise.

ld/

	* testsuite/ld-elf/property-1_needed-1a.d: New file.
	* testsuite/ld-elf/property-1_needed-1.s: Likewise.
---
 binutils/readelf.c                         | 39 ++++++++++++++++++++++
 include/elf/common.h                       |  7 ++++
 ld/testsuite/ld-elf/property-1_needed-1.s  | 15 +++++++++
 ld/testsuite/ld-elf/property-1_needed-1a.d | 17 ++++++++++
 4 files changed, 78 insertions(+)
 create mode 100644 ld/testsuite/ld-elf/property-1_needed-1.s
 create mode 100644 ld/testsuite/ld-elf/property-1_needed-1a.d

diff --git a/binutils/readelf.c b/binutils/readelf.c
index f7c64329f37..0c564a75248 100644
--- a/binutils/readelf.c
+++ b/binutils/readelf.c
@@ -19319,6 +19319,28 @@ decode_aarch64_feature_1_and (unsigned int bitmask)
     }
 }
 
+static void
+decode_1_needed (unsigned int bitmask)
+{
+  while (bitmask)
+    {
+      unsigned int bit = bitmask & (- bitmask);
+
+      bitmask &= ~ bit;
+      switch (bit)
+	{
+	case GNU_PROPERTY_1_NEEDED_INDIRECT_EXTERN_ACCESS:
+	  printf ("indirect external access");
+	  break;
+	default:
+	  printf (_("<unknown: %x>"), bit);
+	  break;
+	}
+      if (bitmask)
+	printf (", ");
+    }
+}
+
 static void
 print_gnu_property_note (Filedata * filedata, Elf_Internal_Note * pnote)
 {
@@ -19512,6 +19534,23 @@ print_gnu_property_note (Filedata * filedata, Elf_Internal_Note * pnote)
 		  || (type >= GNU_PROPERTY_UINT32_OR_LO
 		      && type <= GNU_PROPERTY_UINT32_OR_HI))
 		{
+		  switch (type)
+		    {
+		    case GNU_PROPERTY_1_NEEDED:
+		      if (datasz != 4)
+			printf (_("1_needed: <corrupt length: %#x> "),
+				datasz);
+		      else
+			{
+			  unsigned int bitmask = byte_get (ptr, 4);
+			  printf ("1_needed: ");
+			  decode_1_needed (bitmask);
+			}
+		      goto next;
+
+		    default:
+		      break;
+		    }
 		  if (type <= GNU_PROPERTY_UINT32_AND_HI)
 		    printf (_("UINT32_AND (%#x): "), type);
 		  else
diff --git a/include/elf/common.h b/include/elf/common.h
index 0cca28673dd..0d381f0d27b 100644
--- a/include/elf/common.h
+++ b/include/elf/common.h
@@ -792,6 +792,13 @@
 #define GNU_PROPERTY_UINT32_OR_LO	0xb0008000
 #define GNU_PROPERTY_UINT32_OR_HI	0xb000ffff
 
+/* The needed properties by the object file.  */
+#define GNU_PROPERTY_1_NEEDED		GNU_PROPERTY_UINT32_OR_LO
+
+/* Set if the object file requires canonical function pointers and
+   cannot be used with copy relocation.  */
+#define GNU_PROPERTY_1_NEEDED_INDIRECT_EXTERN_ACCESS	(1U << 0)
+
 /* Processor-specific semantics, lo */
 #define GNU_PROPERTY_LOPROC  0xc0000000
 /* Processor-specific semantics, hi */
diff --git a/ld/testsuite/ld-elf/property-1_needed-1.s b/ld/testsuite/ld-elf/property-1_needed-1.s
new file mode 100644
index 00000000000..5d5cdc87744
--- /dev/null
+++ b/ld/testsuite/ld-elf/property-1_needed-1.s
@@ -0,0 +1,15 @@
+	.section ".note.gnu.property", "a"
+	.p2align ALIGN
+	.long 1f - 0f		/* name length */
+	.long 5f - 2f		/* data length */
+	.long 5			/* note type */
+0:	.asciz "GNU"		/* vendor name */
+1:
+	.p2align ALIGN
+2:	.long 0xb0008000	/* pr_type.  */
+	.long 4f - 3f		/* pr_datasz.  */
+3:
+	.long 0x3
+4:
+	.p2align ALIGN
+5:
diff --git a/ld/testsuite/ld-elf/property-1_needed-1a.d b/ld/testsuite/ld-elf/property-1_needed-1a.d
new file mode 100644
index 00000000000..d994e6edece
--- /dev/null
+++ b/ld/testsuite/ld-elf/property-1_needed-1a.d
@@ -0,0 +1,17 @@
+#source: empty.s
+#source: property-1_needed-1.s
+#as:
+#ld: -shared
+#readelf: -n
+#xfail: ![check_shared_lib_support]
+#notarget: am33_2.0-*-* hppa*-*-hpux* mn10300-*-*
+# Assembly source file for the HPPA assembler is renamed and modifed by
+# sed.  mn10300 has relocations in .note.gnu.property section which
+# elf_parse_notes doesn't support.
+
+#...
+Displaying notes found in: .note.gnu.property
+[ 	]+Owner[ 	]+Data size[ 	]+Description
+  GNU                  0x[0-9a-f]+	NT_GNU_PROPERTY_TYPE_0
+      Properties: 1_needed: indirect external access, <unknown: 2>
+#pass
-- 
2.31.1


^ permalink raw reply	[flat|nested] 12+ messages in thread

* [PATCH v2 2/2] elf: Add GNU_PROPERTY_1_NEEDED check
  2021-06-22 23:57 [PATCH v2 0/2] elf: Implement indirect external access marker H.J. Lu
  2021-06-22 23:57 ` [PATCH v2 1/2] elf: Add GNU_PROPERTY_1_NEEDED H.J. Lu
@ 2021-06-22 23:57 ` H.J. Lu
  2021-07-07 13:58 ` [PATCH v2 0/2] elf: Implement indirect external access marker H.J. Lu
  2 siblings, 0 replies; 12+ messages in thread
From: H.J. Lu @ 2021-06-22 23:57 UTC (permalink / raw)
  To: binutils; +Cc: Florian Weimer, Alan Modra, Nick Clifton, Richard Earnshaw

If GNU_PROPERTY_1_NEEDED_INDIRECT_EXTERN_ACCESS is set on any input
relocatable files:

1. Don't generate copy relocations.
2. Turn off extern_protected_data since it implies
GNU_PROPERTY_NO_COPY_ON_PROTECTED.
3. Treate reference to protected symbols with indirect external access
as local.
4. Set GNU_PROPERTY_1_NEEDED_INDIRECT_EXTERN_ACCESS on output.
5. When generating executable, clear this bit when there are non-GOT or
non-PLT relocations in input relocatable files without the bit set.
6. Add -z [no]indirect-extern-access to control indirect external access.

bfd/

	* elf-bfd (elf_obj_tdata): Add has_indirect_extern_access.
	(elf_has_indirect_extern_access): New.
	* elf-properties.c (_bfd_elf_parse_gnu_properties): Set
	elf_has_indirect_extern_access and elf_has_no_copy_on_protected
	when seeing GNU_PROPERTY_1_NEEDED_INDIRECT_EXTERN_ACCESS.
	(elf_write_gnu_propertie): Add an argument to pass link_info.
	Set needed_1_p for GNU_PROPERTY_1_NEEDED in memory.
	(_bfd_elf_link_setup_gnu_properties): Handle
	GNU_PROPERTY_1_NEEDED_INDIRECT_EXTERN_ACCESS for
	-z indirect-extern-access.  Set nocopyreloc to true and
	extern_protected_data to false for indirect external access.
	(_bfd_elf_convert_gnu_properties): Updated.
	* elf32-i386.c (elf_i386_check_relocs): Set
	non_got_ref_without_indirect_extern_access on legacy non-GOT or
	non-PLT references.
	* elf64-x86-64.c (elf_x86_64_check_relocs): Likewise.
	* elflink.c (_bfd_elf_symbol_refs_local_p): Return true for
	STV_PROTECTED symbols with indirect external access.
	* elfxx-x86.c (_bfd_x86_elf_adjust_dynamic_symbol): Clear
	indirect_extern_access for legacy non-GOT/non-PLT references.
	* elfxx-x86.h (elf_x86_link_hash_entry): Add
	non_got_ref_without_indirect_extern_access.

include/

	* bfdlink.h (bfd_link_info): Add indirect_extern_access and
	needed_1_p.  Change nocopyreloc to int.

ld/

	* NEWS: Mention -z [no]indirect-extern-access
	* ld.texi: Document -z [no]indirect-extern-access
	* ldmain.c (main): Initialize link_info.indirect_extern_access
	to -1.
	* emulparams/extern_protected_data.sh: Support
	-z [no]indirect-extern-access.
	* testsuite/ld-elf/indirect-extern-access-1.rd: New file
	* testsuite/ld-elf/indirect-extern-access-1a.c: Likewise.
	* testsuite/ld-elf/indirect-extern-access-1b.c: Likewise.
	* testsuite/ld-elf/indirect-extern-access-2.rd: Likewise.
	* testsuite/ld-elf/indirect-extern-access-2a.c: Likewise.
	* testsuite/ld-elf/indirect-extern-access-2b.c: Likewise.
	* testsuite/ld-elf/indirect-extern-access-3.rd: Likewise.
	* testsuite/ld-elf/indirect-extern-access.S: Likewise.
	* testsuite/ld-elf/property-1_needed-1b.d: Likewise.
	* testsuite/ld-elf/property-1_needed-1c.d: Likewise.
	* testsuite/ld-x86-64/indirect-extern-access.rd: Likewise.
	* testsuite/ld-x86-64/protected-data-1.h: Likewise.
	* testsuite/ld-x86-64/protected-data-1a.c: Likewise.
	* testsuite/ld-x86-64/protected-data-1b.c: Likewise.
	* testsuite/ld-x86-64/protected-data-2a.S: Likewise.
	* testsuite/ld-x86-64/protected-data-2b.S: Likewise.
	* testsuite/ld-x86-64/protected-func-2a.S: Likewise.
	* testsuite/ld-x86-64/protected-func-2b.S: Likewise.
	* testsuite/ld-x86-64/protected-func-2c.c: Likewise.
	* testsuite/ld-elf/linux-x86.exp: Run test with
	GNU_PROPERTY_1_NEEDED_INDIRECT_EXTERN_ACCESS.
	* testsuite/ld-x86-64/x86-64.exp: Run tests for protected
	function and data with indirect external access.
---
 bfd/elf-bfd.h                                 |   6 +
 bfd/elf-properties.c                          | 126 ++++++++++++++---
 bfd/elf32-i386.c                              |   3 +
 bfd/elf64-x86-64.c                            |   6 +-
 bfd/elflink.c                                 |   4 +
 bfd/elfxx-x86.c                               |  19 +++
 bfd/elfxx-x86.h                               |   4 +
 include/bfdlink.h                             |  23 ++-
 ld/NEWS                                       |   3 +
 ld/emulparams/extern_protected_data.sh        |  11 ++
 ld/ld.texi                                    |  12 ++
 ld/ldmain.c                                   |   1 +
 .../ld-elf/indirect-extern-access-1.rd        |   8 ++
 .../ld-elf/indirect-extern-access-1a.c        |   1 +
 .../ld-elf/indirect-extern-access-1b.c        |  12 ++
 .../ld-elf/indirect-extern-access-2.rd        |   8 ++
 .../ld-elf/indirect-extern-access-2a.c        |  10 ++
 .../ld-elf/indirect-extern-access-2b.c        |  13 ++
 .../ld-elf/indirect-extern-access-3.rd        |   8 ++
 ld/testsuite/ld-elf/indirect-extern-access.S  |  20 +++
 ld/testsuite/ld-elf/linux-x86.exp             |  97 +++++++++++++
 ld/testsuite/ld-elf/property-1_needed-1b.d    |  16 +++
 ld/testsuite/ld-elf/property-1_needed-1c.d    |  17 +++
 .../ld-x86-64/indirect-extern-access.rd       |   6 +
 ld/testsuite/ld-x86-64/protected-data-1.h     |  11 ++
 ld/testsuite/ld-x86-64/protected-data-1a.c    |  40 ++++++
 ld/testsuite/ld-x86-64/protected-data-1b.c    |  59 ++++++++
 ld/testsuite/ld-x86-64/protected-data-2a.S    | 109 +++++++++++++++
 ld/testsuite/ld-x86-64/protected-data-2b.S    | 119 ++++++++++++++++
 ld/testsuite/ld-x86-64/protected-func-2a.S    |  68 +++++++++
 ld/testsuite/ld-x86-64/protected-func-2b.S    |  83 +++++++++++
 ld/testsuite/ld-x86-64/protected-func-2c.c    |  29 ++++
 ld/testsuite/ld-x86-64/x86-64.exp             | 131 ++++++++++++++++++
 33 files changed, 1060 insertions(+), 23 deletions(-)
 create mode 100644 ld/testsuite/ld-elf/indirect-extern-access-1.rd
 create mode 100644 ld/testsuite/ld-elf/indirect-extern-access-1a.c
 create mode 100644 ld/testsuite/ld-elf/indirect-extern-access-1b.c
 create mode 100644 ld/testsuite/ld-elf/indirect-extern-access-2.rd
 create mode 100644 ld/testsuite/ld-elf/indirect-extern-access-2a.c
 create mode 100644 ld/testsuite/ld-elf/indirect-extern-access-2b.c
 create mode 100644 ld/testsuite/ld-elf/indirect-extern-access-3.rd
 create mode 100644 ld/testsuite/ld-elf/indirect-extern-access.S
 create mode 100644 ld/testsuite/ld-elf/property-1_needed-1b.d
 create mode 100644 ld/testsuite/ld-elf/property-1_needed-1c.d
 create mode 100644 ld/testsuite/ld-x86-64/indirect-extern-access.rd
 create mode 100644 ld/testsuite/ld-x86-64/protected-data-1.h
 create mode 100644 ld/testsuite/ld-x86-64/protected-data-1a.c
 create mode 100644 ld/testsuite/ld-x86-64/protected-data-1b.c
 create mode 100644 ld/testsuite/ld-x86-64/protected-data-2a.S
 create mode 100644 ld/testsuite/ld-x86-64/protected-data-2b.S
 create mode 100644 ld/testsuite/ld-x86-64/protected-func-2a.S
 create mode 100644 ld/testsuite/ld-x86-64/protected-func-2b.S
 create mode 100644 ld/testsuite/ld-x86-64/protected-func-2c.c

diff --git a/bfd/elf-bfd.h b/bfd/elf-bfd.h
index 8f985ab8917..7d1e6b01620 100644
--- a/bfd/elf-bfd.h
+++ b/bfd/elf-bfd.h
@@ -2073,6 +2073,10 @@ struct elf_obj_tdata
      property.  */
   unsigned int has_no_copy_on_protected : 1;
 
+  /* Whether if the bfd contains the
+     GNU_PROPERTY_1_NEEDED_INDIRECT_EXTERN_ACCESS property.  */
+  unsigned int has_indirect_extern_access : 1;
+
   /* Irix 5 often screws up the symbol table, sorting local symbols
      after global symbols.  This flag is set if the symbol table in
      this BFD appears to be screwed up.  If it is, we ignore the
@@ -2138,6 +2142,8 @@ struct elf_obj_tdata
 #define elf_properties(bfd) (elf_tdata (bfd) -> properties)
 #define elf_has_no_copy_on_protected(bfd) \
   (elf_tdata(bfd) -> has_no_copy_on_protected)
+#define elf_has_indirect_extern_access(bfd) \
+  (elf_tdata(bfd) -> has_indirect_extern_access)
 \f
 extern void _bfd_elf_swap_verdef_in
   (bfd *, const Elf_External_Verdef *, Elf_Internal_Verdef *);
diff --git a/bfd/elf-properties.c b/bfd/elf-properties.c
index 56ee91d7786..d388df7a59f 100644
--- a/bfd/elf-properties.c
+++ b/bfd/elf-properties.c
@@ -195,6 +195,15 @@ _bfd_elf_parse_gnu_properties (bfd *abfd, Elf_Internal_Note *note)
 		  prop = _bfd_elf_get_property (abfd, type, datasz);
 		  prop->u.number |= bfd_h_get_32 (abfd, ptr);
 		  prop->pr_kind = property_number;
+		  if (type == GNU_PROPERTY_1_NEEDED
+		      && ((prop->u.number
+			   & GNU_PROPERTY_1_NEEDED_INDIRECT_EXTERN_ACCESS)
+			  != 0))
+		    {
+		      elf_has_indirect_extern_access (abfd) = true;
+		      /* GNU_PROPERTY_NO_COPY_ON_PROTECTED is implied.  */
+		      elf_has_no_copy_on_protected (abfd) = true;
+		    }
 		  goto next;
 		}
 	      break;
@@ -525,7 +534,8 @@ elf_get_gnu_property_section_size (elf_property_list *list,
 /* Write GNU properties.  */
 
 static void
-elf_write_gnu_properties (bfd *abfd, bfd_byte *contents,
+elf_write_gnu_properties (struct bfd_link_info *info,
+			  bfd *abfd, bfd_byte *contents,
 			  elf_property_list *list, unsigned int size,
 			  unsigned int align_size)
 {
@@ -570,6 +580,11 @@ elf_write_gnu_properties (bfd *abfd, bfd_byte *contents,
 	      break;
 
 	    case 4:
+	      /* Save the pointer to GNU_PROPERTY_1_NEEDED so that it
+		 can be updated later if needed.  */
+	      if (info != NULL
+		  && list->property.pr_type == GNU_PROPERTY_1_NEEDED)
+		info->needed_1_p = contents + size;
 	      bfd_h_put_32 (abfd, list->property.u.number,
 			    contents + size);
 	      break;
@@ -598,7 +613,7 @@ elf_write_gnu_properties (bfd *abfd, bfd_byte *contents,
 bfd *
 _bfd_elf_link_setup_gnu_properties (struct bfd_link_info *info)
 {
-  bfd *abfd, *first_pbfd = NULL;
+  bfd *abfd, *first_pbfd = NULL, *elf_bfd = NULL;
   elf_property_list *list;
   asection *sec;
   bool has_properties = false;
@@ -606,32 +621,75 @@ _bfd_elf_link_setup_gnu_properties (struct bfd_link_info *info)
     = get_elf_backend_data (info->output_bfd);
   unsigned int elfclass = bed->s->elfclass;
   int elf_machine_code = bed->elf_machine_code;
+  elf_property *p;
 
   /* Find the first relocatable ELF input with GNU properties.  */
   for (abfd = info->input_bfds; abfd != NULL; abfd = abfd->link.next)
     if (bfd_get_flavour (abfd) == bfd_target_elf_flavour
 	&& (abfd->flags & DYNAMIC) == 0
-	&& elf_properties (abfd) != NULL)
+	&& (elf_machine_code
+	    == get_elf_backend_data (abfd)->elf_machine_code)
+	&& (elfclass == get_elf_backend_data (abfd)->s->elfclass))
       {
-	has_properties = true;
-
 	/* Ignore GNU properties from ELF objects with different machine
 	   code or class.  Also skip objects without a GNU_PROPERTY note
 	   section.  */
-	if ((elf_machine_code
-	     == get_elf_backend_data (abfd)->elf_machine_code)
-	    && (elfclass
-		== get_elf_backend_data (abfd)->s->elfclass)
-	    && bfd_get_section_by_name (abfd,
-					NOTE_GNU_PROPERTY_SECTION_NAME) != NULL
-	    )
+	elf_bfd = abfd;
+
+	if (elf_properties (abfd) != NULL)
 	  {
-	    /* Keep .note.gnu.property section in FIRST_PBFD.  */
-	    first_pbfd = abfd;
-	    break;
+	    has_properties = true;
+
+	    if (bfd_get_section_by_name (abfd,
+					 NOTE_GNU_PROPERTY_SECTION_NAME)
+		!= NULL)
+	      {
+		/* Keep .note.gnu.property section in FIRST_PBFD.  */
+		first_pbfd = abfd;
+		break;
+	      }
 	  }
       }
 
+  if (info->indirect_extern_access > 0 && elf_bfd != NULL)
+    {
+      /* Support -z indirect-extern-access.  */
+      if (first_pbfd == NULL)
+	{
+	  sec = bfd_make_section_with_flags (elf_bfd,
+					     NOTE_GNU_PROPERTY_SECTION_NAME,
+					     (SEC_ALLOC
+					      | SEC_LOAD
+					      | SEC_IN_MEMORY
+					      | SEC_READONLY
+					      | SEC_HAS_CONTENTS
+					      | SEC_DATA));
+	  if (sec == NULL)
+	    info->callbacks->einfo (_("%F%P: failed to create GNU property section\n"));
+
+	  if (!bfd_set_section_alignment (sec,
+					  elfclass == ELFCLASS64 ? 3 : 2))
+	    info->callbacks->einfo (_("%F%pA: failed to align section\n"),
+				    sec);
+
+	  elf_section_type (sec) = SHT_NOTE;
+	  first_pbfd = elf_bfd;
+	  has_properties = true;
+	}
+
+      p = _bfd_elf_get_property (first_pbfd, GNU_PROPERTY_1_NEEDED, 4);
+      if (p->pr_kind == property_unknown)
+	{
+	  /* Create GNU_PROPERTY_1_NEEDED.  */
+	  p->u.number
+	    = GNU_PROPERTY_1_NEEDED_INDIRECT_EXTERN_ACCESS;
+	  p->pr_kind = property_number;
+	}
+      else
+	p->u.number
+	  |= GNU_PROPERTY_1_NEEDED_INDIRECT_EXTERN_ACCESS;
+    }
+
   /* Do nothing if there is no .note.gnu.property section.  */
   if (!has_properties)
     return NULL;
@@ -695,7 +753,6 @@ _bfd_elf_link_setup_gnu_properties (struct bfd_link_info *info)
 	 if N > 0.  */
       if (info->stacksize > 0)
 	{
-	  elf_property *p;
 	  bfd_vma stacksize = info->stacksize;
 
 	  p = _bfd_elf_get_property (first_pbfd, GNU_PROPERTY_STACK_SIZE,
@@ -737,7 +794,30 @@ _bfd_elf_link_setup_gnu_properties (struct bfd_link_info *info)
       sec->size = size;
       contents = (bfd_byte *) bfd_zalloc (first_pbfd, size);
 
-      elf_write_gnu_properties (first_pbfd, contents, list, size,
+      if (info->indirect_extern_access <= 0)
+	{
+	  /* Get GNU_PROPERTY_1_NEEDED properties.  */
+	  p = elf_find_and_remove_property (&elf_properties (first_pbfd),
+					    GNU_PROPERTY_1_NEEDED, false);
+	  if (p != NULL)
+	    {
+	      if (info->indirect_extern_access < 0)
+		{
+		  /* Set indirect_extern_access to 1 to indicate that
+		     it is turned on by input properties.  */
+		  if ((p->u.number
+		       & GNU_PROPERTY_1_NEEDED_INDIRECT_EXTERN_ACCESS)
+		      != 0)
+		    info->indirect_extern_access = 1;
+		}
+	      else
+		/* Turn off indirect external access.  */
+		p->u.number
+		  &= ~GNU_PROPERTY_1_NEEDED_INDIRECT_EXTERN_ACCESS;
+	    }
+	}
+
+      elf_write_gnu_properties (info, first_pbfd, contents, list, size,
 				align_size);
 
       /* Cache the section contents for elf_link_input_bfd.  */
@@ -747,6 +827,15 @@ _bfd_elf_link_setup_gnu_properties (struct bfd_link_info *info)
 	 symbol is defined in the shared object.  */
       if (elf_has_no_copy_on_protected (first_pbfd))
 	info->extern_protected_data = false;
+
+      if (info->indirect_extern_access > 0)
+	{
+	  /* For indirect external access, don't generate copy
+	     relocations.  NB: Set to nocopyreloc to 2 to indicate
+	     that it is implied by indirect_extern_access.  */
+	  info->nocopyreloc = 2;
+	  info->extern_protected_data = false;
+	}
     }
 
   return first_pbfd;
@@ -804,7 +893,8 @@ _bfd_elf_convert_gnu_properties (bfd *ibfd, asection *isec,
   *ptr_size = size;
 
   /* Generate the output .note.gnu.property section.  */
-  elf_write_gnu_properties (ibfd, contents, list, size, 1 << align_shift);
+  elf_write_gnu_properties (NULL, ibfd, contents, list, size,
+			    1 << align_shift);
 
   return true;
 }
diff --git a/bfd/elf32-i386.c b/bfd/elf32-i386.c
index cf7cd076b17..a4e2af003aa 100644
--- a/bfd/elf32-i386.c
+++ b/bfd/elf32-i386.c
@@ -1815,6 +1815,9 @@ elf_i386_check_relocs (bfd *abfd,
 		     adjust_dynamic_symbol.  */
 		  h->non_got_ref = 1;
 
+		  if (!elf_has_indirect_extern_access (sec->owner))
+		    eh->non_got_ref_without_indirect_extern_access = 1;
+
 		  /* We may need a .plt entry if the symbol is a function
 		     defined in a shared lib or is a function referenced
 		     from the code or read-only section.  */
diff --git a/bfd/elf64-x86-64.c b/bfd/elf64-x86-64.c
index 98fb88113c0..7c89cdbc9d6 100644
--- a/bfd/elf64-x86-64.c
+++ b/bfd/elf64-x86-64.c
@@ -1972,6 +1972,8 @@ elf_x86_64_check_relocs (bfd *abfd, struct bfd_link_info *info,
 	    break;
 	  }
 
+      eh = (struct elf_x86_link_hash_entry *) h;
+
       if (h != NULL)
 	{
 	  /* It is referenced by a non-shared object. */
@@ -2008,7 +2010,6 @@ elf_x86_64_check_relocs (bfd *abfd, struct bfd_link_info *info,
       if (h == htab->elf.hgot)
 	htab->got_referenced = true;
 
-      eh = (struct elf_x86_link_hash_entry *) h;
       switch (r_type)
 	{
 	case R_X86_64_TLSLD:
@@ -2263,6 +2264,9 @@ elf_x86_64_check_relocs (bfd *abfd, struct bfd_link_info *info,
 		     adjust_dynamic_symbol.  */
 		  h->non_got_ref = 1;
 
+		  if (!elf_has_indirect_extern_access (sec->owner))
+		    eh->non_got_ref_without_indirect_extern_access = 1;
+
 		  /* We may need a .plt entry if the symbol is a function
 		     defined in a shared lib or is a function referenced
 		     from the code or read-only section.  */
diff --git a/bfd/elflink.c b/bfd/elflink.c
index 9a05208253c..65bf2a58a95 100644
--- a/bfd/elflink.c
+++ b/bfd/elflink.c
@@ -3331,6 +3331,10 @@ _bfd_elf_symbol_refs_local_p (struct elf_link_hash_entry *h,
   if (!is_elf_hash_table (&hash_table->root))
     return true;
 
+  /* STV_PROTECTED symbols with indirect external access are local. */
+  if (info->indirect_extern_access > 0)
+    return true;
+
   bed = get_elf_backend_data (hash_table->dynobj);
 
   /* If extern_protected_data is false, STV_PROTECTED non-function
diff --git a/bfd/elfxx-x86.c b/bfd/elfxx-x86.c
index 088f6e5c536..fe4a822041b 100644
--- a/bfd/elfxx-x86.c
+++ b/bfd/elfxx-x86.c
@@ -1824,6 +1824,25 @@ _bfd_x86_elf_adjust_dynamic_symbol (struct bfd_link_info *info,
 
   eh = (struct elf_x86_link_hash_entry *) h;
 
+  /* Clear GNU_PROPERTY_1_NEEDED_INDIRECT_EXTERN_ACCESS if it is turned
+     on by an input relocatable file and there is a non-GOT/non-PLT
+     reference from another relocatable file without it.
+     NB: There can be non-GOT reference in data sections in input with
+     GNU_PROPERTY_1_NEEDED_INDIRECT_EXTERN_ACCESS.  */
+  if (eh->non_got_ref_without_indirect_extern_access
+      && info->indirect_extern_access == 1
+      && bfd_link_executable (info))
+    {
+      unsigned int needed_1;
+      info->indirect_extern_access = 0;
+      /* Turn off nocopyreloc if implied by indirect_extern_access.  */
+      if (info->nocopyreloc == 2)
+	info->nocopyreloc = 0;
+      needed_1 = bfd_h_get_32 (info->output_bfd, info->needed_1_p);
+      needed_1 &= ~GNU_PROPERTY_1_NEEDED_INDIRECT_EXTERN_ACCESS;
+      bfd_h_put_32 (info->output_bfd, needed_1, info->needed_1_p);
+    }
+
   /* STT_GNU_IFUNC symbol must go through PLT. */
   if (h->type == STT_GNU_IFUNC)
     {
diff --git a/bfd/elfxx-x86.h b/bfd/elfxx-x86.h
index db11327e96f..8251f641a77 100644
--- a/bfd/elfxx-x86.h
+++ b/bfd/elfxx-x86.h
@@ -279,6 +279,10 @@ struct elf_x86_link_hash_entry
   /* TRUE if symbol is defined by linker.  */
   unsigned int linker_def : 1;
 
+  /* TRUE if symbol is referenced by a non-GOT/non-PLT relocation in a
+     relocatable object file without indirect external access marker.  */
+  unsigned int non_got_ref_without_indirect_extern_access : 1;
+
   /* TRUE if symbol is referenced by R_386_GOTOFF relocation.  This is
      only used by i386.  */
   unsigned int gotoff_ref : 1;
diff --git a/include/bfdlink.h b/include/bfdlink.h
index 7f1b12dbf37..fd7a274dd83 100644
--- a/include/bfdlink.h
+++ b/include/bfdlink.h
@@ -335,10 +335,6 @@ struct bfd_link_info
   /* TRUE if BFD should pre-bind symbols in a shared object.  */
   unsigned int symbolic: 1;
 
-  /* TRUE if executable should not contain copy relocs.
-     Setting this true may result in a non-sharable text segment.  */
-  unsigned int nocopyreloc: 1;
-
   /* TRUE if BFD should export all symbols in the dynamic symbol table
      of an executable, rather than only those used.  */
   unsigned int export_dynamic: 1;
@@ -652,6 +648,25 @@ struct bfd_link_info
   /* How many spare .dynamic DT_NULL entries should be added?  */
   unsigned int spare_dynamic_tags;
 
+  /* GNU_PROPERTY_1_NEEDED_INDIRECT_EXTERN_ACCESS control:
+       > 1: Turn on by -z indirect-extern-access or by backend.
+      == 1: Turn on by an input.
+         0: Turn off.
+       < 0: Turn on if it is set on any inputs or let backend to
+	    decide.  */
+  int indirect_extern_access;
+
+  /* Non-zero if executable should not contain copy relocs.
+       > 1: Implied by indirect_extern_access.
+      == 1: Turn on by -z nocopyreloc.
+         0: Turn off.
+    Setting this to non-zero may result in a non-sharable text
+    segment.  */
+  int nocopyreloc;
+
+  /* Pointer to the GNU_PROPERTY_1_NEEDED property in memory.  */
+  bfd_byte *needed_1_p;
+
   /* May be used to set DT_FLAGS for ELF. */
   bfd_vma flags;
 
diff --git a/ld/NEWS b/ld/NEWS
index a5ed9058c04..705ae9efbb1 100644
--- a/ld/NEWS
+++ b/ld/NEWS
@@ -1,5 +1,8 @@
 -*- text -*-
 
+* Add -z indirect-extern-access/-z noindirect-extern-access to control
+  canonical function pointers and copy relocation.
+
 * arm-symbianelf support removed.
 
 * Add -z report-relative-reloc to x86 ELF linker to report dynamic
diff --git a/ld/emulparams/extern_protected_data.sh b/ld/emulparams/extern_protected_data.sh
index 30f3d1cdee5..30a830601ea 100644
--- a/ld/emulparams/extern_protected_data.sh
+++ b/ld/emulparams/extern_protected_data.sh
@@ -1,11 +1,22 @@
 PARSE_AND_LIST_OPTIONS_NOEXTEN_PROTECTED_DATA='
   fprintf (file, _("\
   -z noextern-protected-data  Do not treat protected data symbol as external\n"));
+  fprintf (file, _("\
+  -z indirect-extern-access Enable indirect external access\n"));
+  fprintf (file, _("\
+  -z noindirect-extern-access\n\
+                              Disable indirect external access\n"));
 '
 
+# Set link_info.indirect_extern_access to 2 to indicate that it is set
+# by "-z indirect-extern-access".
 PARSE_AND_LIST_ARGS_CASE_Z_NOEXTEN_PROTECTED_DATA='
       else if (strcmp (optarg, "noextern-protected-data") == 0)
 	link_info.extern_protected_data = false;
+      else if (strcmp (optarg, "indirect-extern-access") == 0)
+	link_info.indirect_extern_access = 2;
+      else if (strcmp (optarg, "noindirect-extern-access") == 0)
+	link_info.indirect_extern_access = 0;
 '
 
 
diff --git a/ld/ld.texi b/ld/ld.texi
index dd8f571d4e4..aa2139e035d 100644
--- a/ld/ld.texi
+++ b/ld/ld.texi
@@ -1293,6 +1293,18 @@ Generate GNU_PROPERTY_X86_FEATURE_1_IBT in .note.gnu.property section
 to indicate compatibility with IBT.  This also implies @option{ibtplt}.
 Supported for Linux/i386 and Linux/x86_64.
 
+@item indirect-extern-access
+@itemx noindirect-extern-access
+Generate GNU_PROPERTY_1_NEEDED_INDIRECT_EXTERN_ACCESS in
+.note.gnu.property section to indicate that object file requires
+canonical function pointers and cannot be used with copy relocation.
+This option also implies @option{noextern-protected-data} and
+@option{nocopyreloc}.  Supported for i386 and x86-64.
+
+@option{noindirect-extern-access} removes
+GNU_PROPERTY_1_NEEDED_INDIRECT_EXTERN_ACCESS from .note.gnu.property
+section.
+
 @item initfirst
 This option is only meaningful when building a shared object.
 It marks the object so that its runtime initialization will occur
diff --git a/ld/ldmain.c b/ld/ldmain.c
index 42660eb9a3c..1dfcf1c49e3 100644
--- a/ld/ldmain.c
+++ b/ld/ldmain.c
@@ -346,6 +346,7 @@ main (int argc, char **argv)
   link_info.relax_pass = 1;
   link_info.extern_protected_data = -1;
   link_info.dynamic_undefined_weak = -1;
+  link_info.indirect_extern_access = -1;
   link_info.pei386_auto_import = -1;
   link_info.spare_dynamic_tags = 5;
   link_info.path_separator = ':';
diff --git a/ld/testsuite/ld-elf/indirect-extern-access-1.rd b/ld/testsuite/ld-elf/indirect-extern-access-1.rd
new file mode 100644
index 00000000000..39dc89a41a9
--- /dev/null
+++ b/ld/testsuite/ld-elf/indirect-extern-access-1.rd
@@ -0,0 +1,8 @@
+#...
+[a-f0-9]+ +[0-9a-f]+ +R_.*_COPY +[a-f0-9]+ +indirect_extern_access( \+ 0|)
+#...
+Displaying notes found in: .note.gnu.property
+[ 	]+Owner[ 	]+Data size[ 	]+Description
+  GNU                  0x[0-9a-f]+	NT_GNU_PROPERTY_TYPE_0
+      Properties: 1_needed: 
+#pass
diff --git a/ld/testsuite/ld-elf/indirect-extern-access-1a.c b/ld/testsuite/ld-elf/indirect-extern-access-1a.c
new file mode 100644
index 00000000000..478981012d5
--- /dev/null
+++ b/ld/testsuite/ld-elf/indirect-extern-access-1a.c
@@ -0,0 +1 @@
+int indirect_extern_access = 1;
diff --git a/ld/testsuite/ld-elf/indirect-extern-access-1b.c b/ld/testsuite/ld-elf/indirect-extern-access-1b.c
new file mode 100644
index 00000000000..68adae5666a
--- /dev/null
+++ b/ld/testsuite/ld-elf/indirect-extern-access-1b.c
@@ -0,0 +1,12 @@
+#include <stdio.h>
+
+extern int indirect_extern_access;
+
+int
+main (void)
+{
+  if (indirect_extern_access == 1)
+    puts ("PASS");
+
+  return 0;
+}
diff --git a/ld/testsuite/ld-elf/indirect-extern-access-2.rd b/ld/testsuite/ld-elf/indirect-extern-access-2.rd
new file mode 100644
index 00000000000..9c7d72fae25
--- /dev/null
+++ b/ld/testsuite/ld-elf/indirect-extern-access-2.rd
@@ -0,0 +1,8 @@
+#...
+[a-f0-9]+ +[0-9a-f]+ +R_.*_JUMP_SLO(T|) +[a-f0-9]+ +indirect_extern_access( \+ 0|)
+#...
+Displaying notes found in: .note.gnu.property
+[ 	]+Owner[ 	]+Data size[ 	]+Description
+  GNU                  0x[0-9a-f]+	NT_GNU_PROPERTY_TYPE_0
+      Properties: 1_needed: 
+#pass
diff --git a/ld/testsuite/ld-elf/indirect-extern-access-2a.c b/ld/testsuite/ld-elf/indirect-extern-access-2a.c
new file mode 100644
index 00000000000..cb570689ae7
--- /dev/null
+++ b/ld/testsuite/ld-elf/indirect-extern-access-2a.c
@@ -0,0 +1,10 @@
+void
+indirect_extern_access (void)
+{
+}
+
+void *
+indirect_extern_access_p (void)
+{
+  return indirect_extern_access;
+}
diff --git a/ld/testsuite/ld-elf/indirect-extern-access-2b.c b/ld/testsuite/ld-elf/indirect-extern-access-2b.c
new file mode 100644
index 00000000000..dedfd9bce81
--- /dev/null
+++ b/ld/testsuite/ld-elf/indirect-extern-access-2b.c
@@ -0,0 +1,13 @@
+#include <stdio.h>
+
+extern void indirect_extern_access (void);
+extern void *indirect_extern_access_p (void);
+
+int
+main (void)
+{
+  if (&indirect_extern_access == indirect_extern_access_p ())
+    puts ("PASS");
+
+  return 0;
+}
diff --git a/ld/testsuite/ld-elf/indirect-extern-access-3.rd b/ld/testsuite/ld-elf/indirect-extern-access-3.rd
new file mode 100644
index 00000000000..ce777a56a2c
--- /dev/null
+++ b/ld/testsuite/ld-elf/indirect-extern-access-3.rd
@@ -0,0 +1,8 @@
+#...
+[a-f0-9]+ +[0-9a-f]+ +R_.*_GLOB_DAT +[a-f0-9]+ +indirect_extern_access( \+ 0|)
+#...
+Displaying notes found in: .note.gnu.property
+[ 	]+Owner[ 	]+Data size[ 	]+Description
+  GNU                  0x[0-9a-f]+	NT_GNU_PROPERTY_TYPE_0
+      Properties: 1_needed: indirect external access
+#pass
diff --git a/ld/testsuite/ld-elf/indirect-extern-access.S b/ld/testsuite/ld-elf/indirect-extern-access.S
new file mode 100644
index 00000000000..25b88ba82ca
--- /dev/null
+++ b/ld/testsuite/ld-elf/indirect-extern-access.S
@@ -0,0 +1,20 @@
+# ifdef __LP64__
+#  define ALIGN 3
+# else
+#  define ALIGN 2
+# endif
+	.section ".note.gnu.property", "a"
+	.p2align ALIGN
+	.long 1f - 0f		/* name length */
+	.long 5f - 2f		/* data length */
+	.long 5			/* note type */
+0:	.asciz "GNU"		/* vendor name */
+1:
+	.p2align ALIGN
+2:	.long 0xb0008000	/* pr_type.  */
+	.long 4f - 3f		/* pr_datasz.  */
+3:
+	.long 0x1
+4:
+	.p2align ALIGN
+5:
diff --git a/ld/testsuite/ld-elf/linux-x86.exp b/ld/testsuite/ld-elf/linux-x86.exp
index 7e3a0b7d84a..819237415e6 100644
--- a/ld/testsuite/ld-elf/linux-x86.exp
+++ b/ld/testsuite/ld-elf/linux-x86.exp
@@ -73,6 +73,103 @@ run_ld_link_tests [list \
     ] \
 ]
 
+run_cc_link_tests [list \
+    [list \
+	"Build indirect-extern-access-1.so" \
+	"-shared" \
+	"-fPIC" \
+	{ indirect-extern-access-1a.c } \
+	{} \
+	"indirect-extern-access-1.so" \
+    ] \
+    [list \
+	"Build indirect-extern-access-1a without PIE" \
+	"$NOPIE_LDFLAGS -Wl,--no-as-needed  \
+	 tmpdir/indirect-extern-access-1.so" \
+	"$NOPIE_CFLAGS" \
+	{ indirect-extern-access.S indirect-extern-access-1b.c } \
+	{{readelf -rn indirect-extern-access-1.rd}} \
+	"indirect-extern-access-1a" \
+    ] \
+    [list \
+	"Build indirect-extern-access-2.so" \
+	"-shared" \
+	"-fPIC" \
+	{ indirect-extern-access-2a.c } \
+	{} \
+	"indirect-extern-access-2.so" \
+    ] \
+    [list \
+	"Build indirect-extern-access-2a without PIE" \
+	"$NOPIE_LDFLAGS -Wl,--no-as-needed  \
+	 tmpdir/indirect-extern-access-2.so" \
+	"$NOPIE_CFLAGS" \
+	{ indirect-extern-access.S indirect-extern-access-1b.c } \
+	{{readelf -rn indirect-extern-access-2.rd}} \
+	"indirect-extern-access-2a" \
+    ] \
+    [list \
+	"Build indirect-extern-access-2b with PIE" \
+	"-pie -Wl,--no-as-needed  \
+	 tmpdir/indirect-extern-access-2.so" \
+	"-fpie" \
+	{ indirect-extern-access.S indirect-extern-access-2b.c } \
+	{{readelf -rn indirect-extern-access-3.rd}} \
+	"indirect-extern-access-2b" \
+    ] \
+]
+
+run_ld_link_exec_tests [list \
+    [list \
+	"Run indirect-extern-access-1a without PIE" \
+	"$NOPIE_LDFLAGS" \
+	"" \
+	{ indirect-extern-access.S indirect-extern-access-1b.c } \
+	"indirect-extern-access-1a" \
+	"pass.out" \
+	"$NOPIE_CFLAGS" \
+	"" \
+	"" \
+	"tmpdir/indirect-extern-access-1.so" \
+    ] \
+    [list \
+	"Run indirect-extern-access-1b with PIE" \
+	"-pie" \
+	"" \
+	{ indirect-extern-access.S indirect-extern-access-1b.c } \
+	"indirect-extern-access-1b" \
+	"pass.out" \
+	"-fpie" \
+	"" \
+	"" \
+	"tmpdir/indirect-extern-access-1.so" \
+    ] \
+    [list \
+	"Run indirect-extern-access-2a without PIE" \
+	"$NOPIE_LDFLAGS" \
+	"" \
+	{ indirect-extern-access.S indirect-extern-access-2b.c } \
+	"indirect-extern-access-2a" \
+	"pass.out" \
+	"$NOPIE_CFLAGS" \
+	"" \
+	"" \
+	"tmpdir/indirect-extern-access-2.so" \
+    ] \
+    [list \
+	"Run indirect-extern-access-2b with PIE" \
+	"-pie" \
+	"" \
+	{ indirect-extern-access.S indirect-extern-access-2b.c } \
+	"indirect-extern-access-2b" \
+	"pass.out" \
+	"-fpie" \
+	"" \
+	"" \
+	"tmpdir/indirect-extern-access-2.so" \
+    ] \
+]
+
 proc elfedit_test { options test output } {
     global ELFEDIT
     global READELF
diff --git a/ld/testsuite/ld-elf/property-1_needed-1b.d b/ld/testsuite/ld-elf/property-1_needed-1b.d
new file mode 100644
index 00000000000..b7a9eea344d
--- /dev/null
+++ b/ld/testsuite/ld-elf/property-1_needed-1b.d
@@ -0,0 +1,16 @@
+#source: empty.s
+#as:
+#ld: -shared -z indirect-extern-access
+#readelf: -n
+#xfail: ![check_shared_lib_support]
+#notarget: am33_2.0-*-* hppa*-*-hpux* mn10300-*-*
+# Assembly source file for the HPPA assembler is renamed and modifed by
+# sed.  mn10300 has relocations in .note.gnu.property section which
+# elf_parse_notes doesn't support.
+
+#...
+Displaying notes found in: .note.gnu.property
+[ 	]+Owner[ 	]+Data size[ 	]+Description
+  GNU                  0x[0-9a-f]+	NT_GNU_PROPERTY_TYPE_0
+      Properties: 1_needed: indirect external access
+#pass
diff --git a/ld/testsuite/ld-elf/property-1_needed-1c.d b/ld/testsuite/ld-elf/property-1_needed-1c.d
new file mode 100644
index 00000000000..21e1d26f4a4
--- /dev/null
+++ b/ld/testsuite/ld-elf/property-1_needed-1c.d
@@ -0,0 +1,17 @@
+#source: empty.s
+#source: property-1_needed-1.s
+#as:
+#ld: -shared -z noindirect-extern-access
+#readelf: -n
+#xfail: ![check_shared_lib_support]
+#notarget: am33_2.0-*-* hppa*-*-hpux* mn10300-*-*
+# Assembly source file for the HPPA assembler is renamed and modifed by
+# sed.  mn10300 has relocations in .note.gnu.property section which
+# elf_parse_notes doesn't support.
+
+#...
+Displaying notes found in: .note.gnu.property
+[ 	]+Owner[ 	]+Data size[ 	]+Description
+  GNU                  0x[0-9a-f]+	NT_GNU_PROPERTY_TYPE_0
+      Properties: 1_needed: <unknown: 2>
+#pass
diff --git a/ld/testsuite/ld-x86-64/indirect-extern-access.rd b/ld/testsuite/ld-x86-64/indirect-extern-access.rd
new file mode 100644
index 00000000000..696b06f2046
--- /dev/null
+++ b/ld/testsuite/ld-x86-64/indirect-extern-access.rd
@@ -0,0 +1,6 @@
+#...
+Displaying notes found in: .note.gnu.property
+[ 	]+Owner[ 	]+Data size[ 	]+Description
+  GNU                  0x[0-9a-f]+	NT_GNU_PROPERTY_TYPE_0
+      Properties: 1_needed: indirect external access
+#pass
diff --git a/ld/testsuite/ld-x86-64/protected-data-1.h b/ld/testsuite/ld-x86-64/protected-data-1.h
new file mode 100644
index 00000000000..a80c9769d37
--- /dev/null
+++ b/ld/testsuite/ld-x86-64/protected-data-1.h
@@ -0,0 +1,11 @@
+extern int protected_data_1a;
+extern int protected_data_1b;
+
+extern int *protected_data_1a_p ();
+extern int *protected_data_1b_p ();
+
+extern void set_protected_data_1a (int);
+extern void set_protected_data_1b (int);
+
+extern int check_protected_data_1a (int);
+extern int check_protected_data_1b (int);
diff --git a/ld/testsuite/ld-x86-64/protected-data-1a.c b/ld/testsuite/ld-x86-64/protected-data-1a.c
new file mode 100644
index 00000000000..6942426ecb3
--- /dev/null
+++ b/ld/testsuite/ld-x86-64/protected-data-1a.c
@@ -0,0 +1,40 @@
+#include "protected-data-1.h"
+
+int protected_data_1a __attribute__ ((visibility("protected"))) = 1;
+int protected_data_1b __attribute__ ((visibility("protected"))) = 2;
+
+int *
+protected_data_1a_p (void)
+{
+  return &protected_data_1a;
+}
+
+int *
+protected_data_1b_p (void)
+{
+  return &protected_data_1b;
+}
+
+void
+set_protected_data_1a (int i)
+{
+  protected_data_1a = i;
+}
+
+void
+set_protected_data_1b (int i)
+{
+  protected_data_1b = i;
+}
+
+int
+check_protected_data_1a (int i)
+{
+  return protected_data_1a == i ? 0 : 1;
+}
+
+int
+check_protected_data_1b (int i)
+{
+  return protected_data_1b == i ? 0 : 1;
+}
diff --git a/ld/testsuite/ld-x86-64/protected-data-1b.c b/ld/testsuite/ld-x86-64/protected-data-1b.c
new file mode 100644
index 00000000000..a4756ee08da
--- /dev/null
+++ b/ld/testsuite/ld-x86-64/protected-data-1b.c
@@ -0,0 +1,59 @@
+#include <stdio.h>
+
+#include "protected-data-1.h"
+
+int protected_data_1b = 3;
+
+int
+main (void)
+{
+  int res = 0;
+
+  /* Check if we get the same address for the protected data symbol.  */
+  if (&protected_data_1a != protected_data_1a_p ())
+    {
+      puts ("'protected_data_1a' in main and shared library doesn't have same address");
+      res = 1;
+    }
+
+  protected_data_1a = -1;
+  if (check_protected_data_1a (-1))
+    {
+      puts ("'protected_data_1a' in main and shared library doesn't have same value");
+      res = 1;
+    }
+
+  set_protected_data_1a (-3);
+  if (protected_data_1a != -3)
+    {
+      puts ("'protected_data_1a' in main and shared library doesn't have same value");
+      res = 1;
+    }
+
+  /* Check if we get the different addresses for the protected data
+     symbol.  */
+  if (&protected_data_1b == protected_data_1b_p ())
+    {
+      puts ("'protected_data_1b' in main and shared library has same address");
+      res = 1;
+    }
+
+  protected_data_1b = -10;
+  if (check_protected_data_1b (2))
+    {
+      puts ("'protected_data_1b' in main and shared library has same address");
+      res = 1;
+    }
+
+  set_protected_data_1b (-30);
+  if (protected_data_1b != -10)
+    {
+      puts ("'protected_data_1b' in main and shared library has same address");
+      res = 1;
+    }
+
+  if (!res)
+    puts ("PASS");
+
+  return res;
+}
diff --git a/ld/testsuite/ld-x86-64/protected-data-2a.S b/ld/testsuite/ld-x86-64/protected-data-2a.S
new file mode 100644
index 00000000000..865c1af9daa
--- /dev/null
+++ b/ld/testsuite/ld-x86-64/protected-data-2a.S
@@ -0,0 +1,109 @@
+	.text
+	.p2align 4
+	.protected	protected_data_1a
+	.globl	protected_data_1a_p
+	.type	protected_data_1a_p, @function
+protected_data_1a_p:
+.LFB0:
+	.cfi_startproc
+	leaq	protected_data_1a(%rip), %rax
+	ret
+	.cfi_endproc
+.LFE0:
+	.size	protected_data_1a_p, .-protected_data_1a_p
+	.p2align 4
+	.protected	protected_data_1b
+	.globl	protected_data_1b_p
+	.type	protected_data_1b_p, @function
+protected_data_1b_p:
+.LFB1:
+	.cfi_startproc
+	leaq	protected_data_1b(%rip), %rax
+	ret
+	.cfi_endproc
+.LFE1:
+	.size	protected_data_1b_p, .-protected_data_1b_p
+	.p2align 4
+	.globl	set_protected_data_1a
+	.type	set_protected_data_1a, @function
+set_protected_data_1a:
+.LFB2:
+	.cfi_startproc
+	movl	%edi, protected_data_1a(%rip)
+	ret
+	.cfi_endproc
+.LFE2:
+	.size	set_protected_data_1a, .-set_protected_data_1a
+	.p2align 4
+	.globl	set_protected_data_1b
+	.type	set_protected_data_1b, @function
+set_protected_data_1b:
+.LFB3:
+	.cfi_startproc
+	movl	%edi, protected_data_1b(%rip)
+	ret
+	.cfi_endproc
+.LFE3:
+	.size	set_protected_data_1b, .-set_protected_data_1b
+	.p2align 4
+	.globl	check_protected_data_1a
+	.type	check_protected_data_1a, @function
+check_protected_data_1a:
+.LFB4:
+	.cfi_startproc
+	xorl	%eax, %eax
+	cmpl	%edi, protected_data_1a(%rip)
+	setne	%al
+	ret
+	.cfi_endproc
+.LFE4:
+	.size	check_protected_data_1a, .-check_protected_data_1a
+	.p2align 4
+	.globl	check_protected_data_1b
+	.type	check_protected_data_1b, @function
+check_protected_data_1b:
+.LFB5:
+	.cfi_startproc
+	xorl	%eax, %eax
+	cmpl	%edi, protected_data_1b(%rip)
+	setne	%al
+	ret
+	.cfi_endproc
+.LFE5:
+	.size	check_protected_data_1b, .-check_protected_data_1b
+	.globl	protected_data_1b
+	.data
+	.align 4
+	.type	protected_data_1b, @object
+	.size	protected_data_1b, 4
+protected_data_1b:
+	.long	2
+	.globl	protected_data_1a
+	.align 4
+	.type	protected_data_1a, @object
+	.size	protected_data_1a, 4
+protected_data_1a:
+	.long	1
+	.section	.note.GNU-stack,"",@progbits
+#ifdef USE_GNU_PROPERTY_1_NEEDED_INDIRECT_EXTERN_ACCESS
+# ifdef __LP64__
+#  define ALIGN 3
+# else
+#  define ALIGN 2
+# endif
+	.section ".note.gnu.property", "a"
+	.p2align ALIGN
+	.long 1f - 0f		/* name length */
+	.long 5f - 2f		/* data length */
+	.long 5			/* note type */
+0:	.asciz "GNU"		/* vendor name */
+1:
+	.p2align ALIGN
+2:	.long 0xb0008000	/* pr_type.  */
+	.long 4f - 3f		/* pr_datasz.  */
+3:
+	.long 0x1
+4:
+	.p2align ALIGN
+5:
+#endif
diff --git a/ld/testsuite/ld-x86-64/protected-data-2b.S b/ld/testsuite/ld-x86-64/protected-data-2b.S
new file mode 100644
index 00000000000..da8956139fe
--- /dev/null
+++ b/ld/testsuite/ld-x86-64/protected-data-2b.S
@@ -0,0 +1,119 @@
+	.section	.rodata.str1.8,"aMS",@progbits,1
+	.align 8
+.LC0:
+	.string	"'protected_data_1a' in main and shared library doesn't have same address"
+	.align 8
+.LC1:
+	.string	"'protected_data_1a' in main and shared library doesn't have same value"
+	.align 8
+.LC2:
+	.string	"'protected_data_1b' in main and shared library has same address"
+	.section	.rodata.str1.1,"aMS",@progbits,1
+.LC3:
+	.string	"PASS"
+	.section	.text.startup,"ax",@progbits
+	.p2align 4,,15
+	.globl	main
+	.type	main, @function
+main:
+.LFB11:
+	.cfi_startproc
+	pushq	%rbp
+	.cfi_def_cfa_offset 16
+	.cfi_offset 6, -16
+	xorl	%eax, %eax
+	pushq	%rbx
+	.cfi_def_cfa_offset 24
+	.cfi_offset 3, -24
+	xorl	%ebx, %ebx
+	subq	$8, %rsp
+	.cfi_def_cfa_offset 32
+	call	protected_data_1a_p
+	movq	protected_data_1a@GOTPCREL(%rip), %rbp
+	cmpq	%rbp, %rax
+	je	.L2
+	leaq	.LC0(%rip), %rdi
+	movb	$1, %bl
+	call	puts
+.L2:
+	movl	$-1, %edi
+	movl	$-1, 0(%rbp)
+	call	check_protected_data_1a
+	testl	%eax, %eax
+	jne	.L17
+.L3:
+	movl	$-3, %edi
+	call	set_protected_data_1a
+	cmpl	$-3, 0(%rbp)
+	je	.L4
+	leaq	.LC1(%rip), %rdi
+	movl	$1, %ebx
+	call	puts
+.L4:
+	xorl	%eax, %eax
+	call	protected_data_1b_p
+	leaq	protected_data_1b(%rip), %rdx
+	cmpq	%rdx, %rax
+	je	.L18
+.L5:
+	movl	$2, %edi
+	movl	$-10, protected_data_1b(%rip)
+	call	check_protected_data_1b
+	testl	%eax, %eax
+	jne	.L19
+	movl	$-30, %edi
+	call	set_protected_data_1b
+	cmpl	$-10, protected_data_1b(%rip)
+	je	.L9
+.L7:
+	leaq	.LC2(%rip), %rdi
+	movl	$1, %ebx
+	call	puts
+.L8:
+	addq	$8, %rsp
+	.cfi_remember_state
+	.cfi_def_cfa_offset 24
+	movl	%ebx, %eax
+	popq	%rbx
+	.cfi_def_cfa_offset 16
+	popq	%rbp
+	.cfi_def_cfa_offset 8
+	ret
+.L9:
+	.cfi_restore_state
+	testl	%ebx, %ebx
+	jne	.L11
+	leaq	.LC3(%rip), %rdi
+	call	puts
+	jmp	.L8
+.L19:
+	leaq	.LC2(%rip), %rdi
+	call	puts
+	movl	$-30, %edi
+	call	set_protected_data_1b
+	cmpl	$-10, protected_data_1b(%rip)
+	jne	.L7
+.L11:
+	movl	$1, %ebx
+	jmp	.L8
+.L17:
+	leaq	.LC1(%rip), %rdi
+	movl	$1, %ebx
+	call	puts
+	jmp	.L3
+.L18:
+	leaq	.LC2(%rip), %rdi
+	movl	$1, %ebx
+	call	puts
+	jmp	.L5
+	.cfi_endproc
+.LFE11:
+	.size	main, .-main
+	.globl	protected_data_1b
+	.data
+	.align 4
+	.type	protected_data_1b, @object
+	.size	protected_data_1b, 4
+protected_data_1b:
+	.long	3
+	.section	.note.GNU-stack,"",@progbits
diff --git a/ld/testsuite/ld-x86-64/protected-func-2a.S b/ld/testsuite/ld-x86-64/protected-func-2a.S
new file mode 100644
index 00000000000..35c9cd121bd
--- /dev/null
+++ b/ld/testsuite/ld-x86-64/protected-func-2a.S
@@ -0,0 +1,68 @@
+	.text
+	.p2align 4
+	.protected	protected_func_1a
+	.globl	protected_func_1a
+	.type	protected_func_1a, @function
+protected_func_1a:
+.LFB0:
+	.cfi_startproc
+	movl	$1, %eax
+	ret
+	.cfi_endproc
+.LFE0:
+	.size	protected_func_1a, .-protected_func_1a
+	.p2align 4
+	.protected	protected_func_1b
+	.globl	protected_func_1b
+	.type	protected_func_1b, @function
+protected_func_1b:
+.LFB1:
+	.cfi_startproc
+	movl	$2, %eax
+	ret
+	.cfi_endproc
+.LFE1:
+	.size	protected_func_1b, .-protected_func_1b
+	.p2align 4
+	.globl	protected_func_1a_p
+	.type	protected_func_1a_p, @function
+protected_func_1a_p:
+.LFB2:
+	.cfi_startproc
+	leaq	protected_func_1a(%rip), %rax
+	ret
+	.cfi_endproc
+.LFE2:
+	.size	protected_func_1a_p, .-protected_func_1a_p
+	.p2align 4
+	.globl	protected_func_1b_p
+	.type	protected_func_1b_p, @function
+protected_func_1b_p:
+.LFB3:
+	.cfi_startproc
+	leaq	protected_func_1b(%rip), %rax
+	ret
+	.cfi_endproc
+.LFE3:
+	.size	protected_func_1b_p, .-protected_func_1b_p
+	.section	.note.GNU-stack,"",@progbits
+#ifdef __LP64__
+# define ALIGN 3
+#else
+# define ALIGN 2
+#endif
+	.section ".note.gnu.property", "a"
+	.p2align ALIGN
+	.long 1f - 0f		/* name length */
+	.long 5f - 2f		/* data length */
+	.long 5			/* note type */
+0:	.asciz "GNU"		/* vendor name */
+1:
+	.p2align ALIGN
+2:	.long 0xb0008000	/* pr_type.  */
+	.long 4f - 3f		/* pr_datasz.  */
+3:
+	.long 0x1
+4:
+	.p2align ALIGN
+5:
diff --git a/ld/testsuite/ld-x86-64/protected-func-2b.S b/ld/testsuite/ld-x86-64/protected-func-2b.S
new file mode 100644
index 00000000000..8fa4cbf09d6
--- /dev/null
+++ b/ld/testsuite/ld-x86-64/protected-func-2b.S
@@ -0,0 +1,83 @@
+	.text
+	.p2align 4
+	.globl	protected_func_1b
+	.type	protected_func_1b, @function
+protected_func_1b:
+.LFB11:
+	.cfi_startproc
+	movl	$3, %eax
+	ret
+	.cfi_endproc
+.LFE11:
+	.size	protected_func_1b, .-protected_func_1b
+	.section	.rodata.str1.8,"aMS",@progbits,1
+	.align 8
+.LC0:
+	.string	"'protected_func_1a' in main and shared library doesn't have same address"
+	.align 8
+.LC1:
+	.string	"'protected_func_1a' doesn't return the correct value"
+	.align 8
+.LC2:
+	.string	"'protected_func_1b' in main and shared library has same address"
+	.section	.rodata.str1.1,"aMS",@progbits,1
+.LC3:
+	.string	"PASS"
+	.section	.text.startup,"ax",@progbits
+	.p2align 4
+	.globl	main
+	.type	main, @function
+main:
+.LFB12:
+	.cfi_startproc
+	pushq	%r12
+	.cfi_def_cfa_offset 16
+	.cfi_offset 12, -16
+	xorl	%r12d, %r12d
+	call	protected_func_1a_p
+	cmpq	protected_func_1a@GOTPCREL(%rip), %rax
+	je	.L4
+	leaq	.LC0(%rip), %rdi
+	movl	$1, %r12d
+	call	puts
+.L4:
+	call	protected_func_1a
+	cmpl	$1, %eax
+	jne	.L13
+	call	protected_func_1b_p
+	leaq	protected_func_1b(%rip), %rdx
+	cmpq	%rax, %rdx
+	je	.L6
+	testl	%r12d, %r12d
+	jne	.L12
+	leaq	.LC3(%rip), %rdi
+	call	puts
+	movl	%r12d, %eax
+	popq	%r12
+	.cfi_remember_state
+	.cfi_def_cfa_offset 8
+	ret
+.L13:
+	.cfi_restore_state
+	leaq	.LC1(%rip), %rdi
+	call	puts
+	call	protected_func_1b_p
+	leaq	protected_func_1b(%rip), %rdx
+	cmpq	%rax, %rdx
+	je	.L6
+.L12:
+	movl	$1, %r12d
+	movl	%r12d, %eax
+	popq	%r12
+	.cfi_remember_state
+	.cfi_def_cfa_offset 8
+	ret
+.L6:
+	.cfi_restore_state
+	leaq	.LC2(%rip), %rdi
+	call	puts
+	jmp	.L12
+	.cfi_endproc
+.LFE12:
+	.size	main, .-main
+	.section	.note.GNU-stack,"",@progbits
diff --git a/ld/testsuite/ld-x86-64/protected-func-2c.c b/ld/testsuite/ld-x86-64/protected-func-2c.c
new file mode 100644
index 00000000000..c5ec1eca17e
--- /dev/null
+++ b/ld/testsuite/ld-x86-64/protected-func-2c.c
@@ -0,0 +1,29 @@
+#include "protected-func-1.h"
+
+protected_func_type protected_func_1a_ptr = protected_func_1a;
+
+__attribute__ ((visibility("protected")))
+int
+protected_func_1a (void)
+{
+  return 1;
+}
+
+__attribute__ ((visibility("protected")))
+int
+protected_func_1b (void)
+{
+  return 2;
+}
+
+protected_func_type
+protected_func_1a_p (void)
+{
+  return protected_func_1a;
+}
+
+protected_func_type
+protected_func_1b_p (void)
+{
+  return protected_func_1b;
+}
diff --git a/ld/testsuite/ld-x86-64/x86-64.exp b/ld/testsuite/ld-x86-64/x86-64.exp
index 3bf62504cf9..92577f4eb49 100644
--- a/ld/testsuite/ld-x86-64/x86-64.exp
+++ b/ld/testsuite/ld-x86-64/x86-64.exp
@@ -1334,6 +1334,47 @@ if { [isnative] && [check_compiler_available] } {
 	    {} \
 	    "libprotected-func-1.so" \
 	] \
+	[list \
+	    "Build libprotected-func-2a.so" \
+	    "-shared" \
+	    "-fPIC -Wa,-mx86-used-note=yes" \
+	    { protected-func-2a.S } \
+	    {{readelf -n indirect-extern-access.rd}}  \
+	    "libprotected-func-2a.so" \
+	] \
+	[list \
+	    "Build libprotected-func-2b.so" \
+	    "-shared -z indirect-extern-access" \
+	    "-fPIC -Wa,-mx86-used-note=yes" \
+	    { protected-func-2c.c } \
+	    {{readelf -n indirect-extern-access.rd}}  \
+	    "libprotected-func-2b.so" \
+	] \
+	[list \
+	    "Build libprotected-data-1.so" \
+	    "-shared" \
+	    "-fPIC -Wa,-mx86-used-note=yes" \
+	    { protected-data-1a.c } \
+	    {} \
+	    "libprotected-data-1.so" \
+	] \
+	[list \
+	    "Build libprotected-data-2a.so" \
+	    "-shared" \
+	    "-fPIC -Wa,-mx86-used-note=yes \
+	     -DUSE_GNU_PROPERTY_1_NEEDED_INDIRECT_EXTERN_ACCESS" \
+	    { protected-data-2a.S } \
+	    {{readelf -n indirect-extern-access.rd}}  \
+	    "libprotected-data-2a.so" \
+	] \
+	[list \
+	    "Build libprotected-data-2b.so" \
+	    "-shared -z indirect-extern-access" \
+	    "-fPIC -Wa,-mx86-used-note=yes" \
+	    { protected-data-2a.S } \
+	    {{readelf -n indirect-extern-access.rd}}  \
+	    "libprotected-data-2b.so" \
+	] \
     ]
 
     if  {[istarget "x86_64-*-linux*-gnux32"]} {
@@ -1761,6 +1802,96 @@ if { [isnative] && [check_compiler_available] } {
 	    "pass.out" \
 	    "-fPIE" \
 	] \
+	[list \
+	    "Run protected-func-2a without PIE" \
+	    "$NOPIE_LDFLAGS -Wl,--no-as-needed tmpdir/libprotected-func-2a.so" \
+	    "-Wa,-mx86-used-note=yes" \
+	    { protected-func-2b.S } \
+	    "protected-func-2a" \
+	    "pass.out" \
+	    "$NOPIE_CFLAGS" \
+	] \
+	[list \
+	    "Run protected-func-2b with PIE" \
+	    "-Wl,--no-as-needed -pie tmpdir/libprotected-func-2a.so" \
+	    "-Wa,-mx86-used-note=yes" \
+	    { protected-func-2b.S } \
+	    "protected-func-2b" \
+	    "pass.out" \
+	    "-fPIE" \
+	] \
+	[list \
+	    "Run protected-func-2c without PIE" \
+	    "$NOPIE_LDFLAGS -Wl,--no-as-needed tmpdir/libprotected-func-2b.so" \
+	    "-Wa,-mx86-used-note=yes" \
+	    { protected-func-2b.S } \
+	    "protected-func-2c" \
+	    "pass.out" \
+	    "$NOPIE_CFLAGS" \
+	] \
+	[list \
+	    "Run protected-func-2d with PIE" \
+	    "-Wl,--no-as-needed -pie tmpdir/libprotected-func-2b.so" \
+	    "-Wa,-mx86-used-note=yes" \
+	    { protected-func-2b.S } \
+	    "protected-func-2d" \
+	    "pass.out" \
+	    "-fPIE" \
+	] \
+	[list \
+	    "Run protected-data-1 without PIE" \
+	    "$NOPIE_LDFLAGS -Wl,--no-as-needed tmpdir/libprotected-data-1.so" \
+	    "-Wa,-mx86-used-note=yes" \
+	    { protected-data-1b.c } \
+	    "protected-data-1a" \
+	    "pass.out" \
+	    "$NOPIE_CFLAGS" \
+	] \
+	[list \
+	    "Run protected-data-1 with PIE" \
+	    "-Wl,--no-as-needed -pie tmpdir/libprotected-data-1.so" \
+	    "-Wa,-mx86-used-note=yes" \
+	    { protected-data-1b.c } \
+	    "protected-data-1b" \
+	    "pass.out" \
+	    "-fPIE" \
+	] \
+	[list \
+	    "Run protected-data-2a without PIE" \
+	    "$NOPIE_LDFLAGS -Wl,--no-as-needed tmpdir/libprotected-data-2a.so" \
+	    "-Wa,-mx86-used-note=yes" \
+	    { protected-data-2b.S } \
+	    "protected-data-2a" \
+	    "pass.out" \
+	    "$NOPIE_CFLAGS" \
+	] \
+	[list \
+	    "Run protected-data-2b with PIE" \
+	    "-Wl,--no-as-needed -pie tmpdir/libprotected-data-2a.so" \
+	    "-Wa,-mx86-used-note=yes" \
+	    { protected-data-2b.S } \
+	    "protected-data-2b" \
+	    "pass.out" \
+	    "-fPIE" \
+	] \
+	[list \
+	    "Run protected-data-2c without PIE" \
+	    "$NOPIE_LDFLAGS -Wl,--no-as-needed tmpdir/libprotected-data-2b.so" \
+	    "-Wa,-mx86-used-note=yes" \
+	    { protected-data-2b.S } \
+	    "protected-data-2c" \
+	    "pass.out" \
+	    "$NOPIE_CFLAGS" \
+	] \
+	[list \
+	    "Run protected-data-2d with PIE" \
+	    "-Wl,--no-as-needed -pie tmpdir/libprotected-data-2b.so" \
+	    "-Wa,-mx86-used-note=yes" \
+	    { protected-data-2b.S } \
+	    "protected-data-2d" \
+	    "pass.out" \
+	    "-fPIE" \
+	] \
     ]
 
     # Run-time tests which require working ifunc attribute support.
-- 
2.31.1


^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: [PATCH v2 0/2] elf: Implement indirect external access marker
  2021-06-22 23:57 [PATCH v2 0/2] elf: Implement indirect external access marker H.J. Lu
  2021-06-22 23:57 ` [PATCH v2 1/2] elf: Add GNU_PROPERTY_1_NEEDED H.J. Lu
  2021-06-22 23:57 ` [PATCH v2 2/2] elf: Add GNU_PROPERTY_1_NEEDED check H.J. Lu
@ 2021-07-07 13:58 ` H.J. Lu
  2021-07-07 14:00   ` Florian Weimer
  2 siblings, 1 reply; 12+ messages in thread
From: H.J. Lu @ 2021-07-07 13:58 UTC (permalink / raw)
  To: Binutils, Marcus Shawcroft, Ramana Radhakrishnan
  Cc: Florian Weimer, Alan Modra, Nick Clifton, Richard Earnshaw

On Tue, Jun 22, 2021 at 4:57 PM H.J. Lu <hjl.tools@gmail.com> wrote:
>
> Changes in the v2 patch.
>
> 1. Rename GNU_PROPERTY_1_NEEDED_SINGLE_GLOBAL_DEFINITION to
> GNU_PROPERTY_1_NEEDED_INDIRECT_EXTERN_ACCESS.
> 2. Rename the option to -z [no]indirect-extern-access and move it to
> ld/emulparams/extern_protected_data.sh.
> 3. Clear the indirect external access bit in executable when there are
> non-GOT or non-PLT relocations in relocatable input files without this
> bit set.
> 4. Add more tests.
>
> ---
> On systems with copy relocation:
> * A copy in executable is created for the definition in a shared library
> at run-time by ld.so.
> * The copy is referenced by executable and shared libraries.
> * Executable can access the copy directly.
>
> Issues are:
> * Overhead of a copy, time and space, may be visible at run-time.
> * Read-only data in the shared library becomes read-write copy in
> executable at run-time.
> * Local access to data with the STV_PROTECTED visibility in the shared
> library must use GOT.
>
> On systems without function descriptor, function pointers vary depending
> on where and how the functions are defined.
> * If the function is defined in executable, it can be the address of
> function body.
> * If the function, including the function with STV_PROTECTED visibility,
> is defined in the shared library, it can be the address of the PLT entry
> in executable or shared library.
>
> Issues are:
> * The address of function body may not be used as its function pointer.
> * ld.so needs to search loaded shared libraries for the function pointer
> of the function with STV_PROTECTED visibility.
>
> Here is a proposal to remove copy relocation and use canonical function
> pointer:
>
> 1. Accesses, including in PIE and non-PIE, to undefined symbols must
> use GOT.
>   a. Linker may optimize out GOT access if the data is defined in PIE or
>   non-PIE.
> 2. Read-only data in the shared library remain read-only at run-time
> 3. Address of global data with the STV_PROTECTED visibility in the shared
> library is the address of data body.
>   a. Can use IP-relative access.
>   b. May need GOT without IP-relative access.
> 4. For systems without function descriptor,
>   a. All global function pointers of undefined functions in PIE and
>   non-PIE must use GOT.  Linker may optimize out GOT access if the
>   function is defined in PIE or non-PIE.
>   b. Function pointer of functions with the STV_PROTECTED visibility in
>   executable and shared library is the address of function body.
>    i. Can use IP-relative access.
>    ii. May need GOT without IP-relative access.
>    iii. Branches to undefined functions may use PLT.
> 5. Single global definition marker:
>
> Add GNU_PROPERTY_1_NEEDED:
>
> #define GNU_PROPERTY_1_NEEDED GNU_PROPERTY_UINT32_OR_LO
>
> to indicate the needed properties by the object file.
>
> Add GNU_PROPERTY_1_NEEDED_INDIRECT_EXTERN_ACCESS:
>
> #define GNU_PROPERTY_1_NEEDED_INDIRECT_EXTERN_ACCESS (1U << 0)
>
> to indicate that the object file requires canonical function pointers and
> cannot be used with copy relocation.
>
>   a. Copy relocation should be disallowed at link-time and run-time.
>   b. Canonical function pointers are required at link-time and run-tima
>
> Linker change:
>
> If any relocatable input files contain the indirect external access
> marker:
> * Generate the indirect external access marker in output.
>   a. Linker should clear the indirect external access bit in executable
>      when there are non-GOT or non-PLT relocations in relocatable input
>      files without this bit set.
> * Avoid copy relocation if possible.
> * Access to symbols with the STV_PROTECTED visibility is the same as
> local access.
> * For systems without function descriptor, function pointer is the address
> of function body.
>
> H.J. Lu (2):
>   elf: Add GNU_PROPERTY_1_NEEDED
>   elf: Add GNU_PROPERTY_1_NEEDED check
>
>  bfd/elf-bfd.h                                 |   6 +
>  bfd/elf-properties.c                          | 126 ++++++++++++++---
>  bfd/elf32-i386.c                              |   3 +
>  bfd/elf64-x86-64.c                            |   6 +-
>  bfd/elflink.c                                 |   4 +
>  bfd/elfxx-x86.c                               |  19 +++
>  bfd/elfxx-x86.h                               |   4 +
>  binutils/readelf.c                            |  39 ++++++
>  include/bfdlink.h                             |  23 ++-
>  include/elf/common.h                          |   7 +
>  ld/NEWS                                       |   3 +
>  ld/emulparams/extern_protected_data.sh        |  11 ++
>  ld/ld.texi                                    |  12 ++
>  ld/ldmain.c                                   |   1 +
>  .../ld-elf/indirect-extern-access-1.rd        |   8 ++
>  .../ld-elf/indirect-extern-access-1a.c        |   1 +
>  .../ld-elf/indirect-extern-access-1b.c        |  12 ++
>  .../ld-elf/indirect-extern-access-2.rd        |   8 ++
>  .../ld-elf/indirect-extern-access-2a.c        |  10 ++
>  .../ld-elf/indirect-extern-access-2b.c        |  13 ++
>  .../ld-elf/indirect-extern-access-3.rd        |   8 ++
>  ld/testsuite/ld-elf/indirect-extern-access.S  |  20 +++
>  ld/testsuite/ld-elf/linux-x86.exp             |  97 +++++++++++++
>  ld/testsuite/ld-elf/property-1_needed-1.s     |  15 ++
>  ld/testsuite/ld-elf/property-1_needed-1a.d    |  17 +++
>  ld/testsuite/ld-elf/property-1_needed-1b.d    |  16 +++
>  ld/testsuite/ld-elf/property-1_needed-1c.d    |  17 +++
>  .../ld-x86-64/indirect-extern-access.rd       |   6 +
>  ld/testsuite/ld-x86-64/protected-data-1.h     |  11 ++
>  ld/testsuite/ld-x86-64/protected-data-1a.c    |  40 ++++++
>  ld/testsuite/ld-x86-64/protected-data-1b.c    |  59 ++++++++
>  ld/testsuite/ld-x86-64/protected-data-2a.S    | 109 +++++++++++++++
>  ld/testsuite/ld-x86-64/protected-data-2b.S    | 119 ++++++++++++++++
>  ld/testsuite/ld-x86-64/protected-func-2a.S    |  68 +++++++++
>  ld/testsuite/ld-x86-64/protected-func-2b.S    |  83 +++++++++++
>  ld/testsuite/ld-x86-64/protected-func-2c.c    |  29 ++++
>  ld/testsuite/ld-x86-64/x86-64.exp             | 131 ++++++++++++++++++
>  37 files changed, 1138 insertions(+), 23 deletions(-)
>  create mode 100644 ld/testsuite/ld-elf/indirect-extern-access-1.rd
>  create mode 100644 ld/testsuite/ld-elf/indirect-extern-access-1a.c
>  create mode 100644 ld/testsuite/ld-elf/indirect-extern-access-1b.c
>  create mode 100644 ld/testsuite/ld-elf/indirect-extern-access-2.rd
>  create mode 100644 ld/testsuite/ld-elf/indirect-extern-access-2a.c
>  create mode 100644 ld/testsuite/ld-elf/indirect-extern-access-2b.c
>  create mode 100644 ld/testsuite/ld-elf/indirect-extern-access-3.rd
>  create mode 100644 ld/testsuite/ld-elf/indirect-extern-access.S
>  create mode 100644 ld/testsuite/ld-elf/property-1_needed-1.s
>  create mode 100644 ld/testsuite/ld-elf/property-1_needed-1a.d
>  create mode 100644 ld/testsuite/ld-elf/property-1_needed-1b.d
>  create mode 100644 ld/testsuite/ld-elf/property-1_needed-1c.d
>  create mode 100644 ld/testsuite/ld-x86-64/indirect-extern-access.rd
>  create mode 100644 ld/testsuite/ld-x86-64/protected-data-1.h
>  create mode 100644 ld/testsuite/ld-x86-64/protected-data-1a.c
>  create mode 100644 ld/testsuite/ld-x86-64/protected-data-1b.c
>  create mode 100644 ld/testsuite/ld-x86-64/protected-data-2a.S
>  create mode 100644 ld/testsuite/ld-x86-64/protected-data-2b.S
>  create mode 100644 ld/testsuite/ld-x86-64/protected-func-2a.S
>  create mode 100644 ld/testsuite/ld-x86-64/protected-func-2b.S
>  create mode 100644 ld/testsuite/ld-x86-64/protected-func-2c.c
>
> --
> 2.31.1
>

I am checking in this patch by the end of this week.

-- 
H.J.

^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: [PATCH v2 0/2] elf: Implement indirect external access marker
  2021-07-07 13:58 ` [PATCH v2 0/2] elf: Implement indirect external access marker H.J. Lu
@ 2021-07-07 14:00   ` Florian Weimer
  2021-07-07 14:13     ` H.J. Lu
  0 siblings, 1 reply; 12+ messages in thread
From: Florian Weimer @ 2021-07-07 14:00 UTC (permalink / raw)
  To: H.J. Lu
  Cc: Binutils, Marcus Shawcroft, Ramana Radhakrishnan, Alan Modra,
	Nick Clifton, Richard Earnshaw

* H. J. Lu:

> I am checking in this patch by the end of this week.

Shouldn't the ABI specification be finalized first?  (Sorry.)

Thanks,
Florian


^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: [PATCH v2 0/2] elf: Implement indirect external access marker
  2021-07-07 14:00   ` Florian Weimer
@ 2021-07-07 14:13     ` H.J. Lu
  2021-07-07 14:27       ` Florian Weimer
  0 siblings, 1 reply; 12+ messages in thread
From: H.J. Lu @ 2021-07-07 14:13 UTC (permalink / raw)
  To: Florian Weimer
  Cc: Binutils, Marcus Shawcroft, Ramana Radhakrishnan, Alan Modra,
	Nick Clifton, Richard Earnshaw

On Wed, Jul 7, 2021 at 7:01 AM Florian Weimer <fweimer@redhat.com> wrote:
>
> * H. J. Lu:
>
> > I am checking in this patch by the end of this week.
>
> Shouldn't the ABI specification be finalized first?  (Sorry.)
>

Did you mean adding GNU_PROPERTY_1_NEEDED_INDIRECT_EXTERN_ACCESS?
I have submitted linker, GCC and glibc patches to show how it is used.
  To see how it
works, we need to start with a working linker.  That is why I want to
add it to the linker
now.

-- 
H.J.

^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: [PATCH v2 0/2] elf: Implement indirect external access marker
  2021-07-07 14:13     ` H.J. Lu
@ 2021-07-07 14:27       ` Florian Weimer
  2021-07-09  0:56         ` Alan Modra
  2021-07-09  3:25         ` Fangrui Song
  0 siblings, 2 replies; 12+ messages in thread
From: Florian Weimer @ 2021-07-07 14:27 UTC (permalink / raw)
  To: H.J. Lu
  Cc: Binutils, Marcus Shawcroft, Ramana Radhakrishnan, Alan Modra,
	Nick Clifton, Richard Earnshaw

* H. J. Lu:

> On Wed, Jul 7, 2021 at 7:01 AM Florian Weimer <fweimer@redhat.com> wrote:
>>
>> * H. J. Lu:
>>
>> > I am checking in this patch by the end of this week.
>>
>> Shouldn't the ABI specification be finalized first?  (Sorry.)
>>
>
> Did you mean adding GNU_PROPERTY_1_NEEDED_INDIRECT_EXTERN_ACCESS?
> I have submitted linker, GCC and glibc patches to show how it is used.
>
> To see how it works, we need to start with a working linker.  That is
> why I want to add it to the linker now.

Hmm, I see.  I guess it's up to the binutils maintainers to decide.

Thanks,
Florian


^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: [PATCH v2 0/2] elf: Implement indirect external access marker
  2021-07-07 14:27       ` Florian Weimer
@ 2021-07-09  0:56         ` Alan Modra
  2021-07-09  1:11           ` H.J. Lu
  2021-07-09  3:25         ` Fangrui Song
  1 sibling, 1 reply; 12+ messages in thread
From: Alan Modra @ 2021-07-09  0:56 UTC (permalink / raw)
  To: Florian Weimer
  Cc: H.J. Lu, Binutils, Marcus Shawcroft, Ramana Radhakrishnan,
	Nick Clifton, Richard Earnshaw

On Wed, Jul 07, 2021 at 04:27:43PM +0200, Florian Weimer wrote:
> Hmm, I see.  I guess it's up to the binutils maintainers to decide.

The current patch looks reasonable to me.

-- 
Alan Modra
Australia Development Lab, IBM

^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: [PATCH v2 0/2] elf: Implement indirect external access marker
  2021-07-09  0:56         ` Alan Modra
@ 2021-07-09  1:11           ` H.J. Lu
  2021-07-09  2:36             ` Alan Modra
  0 siblings, 1 reply; 12+ messages in thread
From: H.J. Lu @ 2021-07-09  1:11 UTC (permalink / raw)
  To: Alan Modra
  Cc: Florian Weimer, Binutils, Marcus Shawcroft, Ramana Radhakrishnan,
	Nick Clifton, Richard Earnshaw

On Thu, Jul 8, 2021 at 5:56 PM Alan Modra <amodra@gmail.com> wrote:
>
> On Wed, Jul 07, 2021 at 04:27:43PM +0200, Florian Weimer wrote:
> > Hmm, I see.  I guess it's up to the binutils maintainers to decide.
>
> The current patch looks reasonable to me.
>
> --
> Alan Modra
> Australia Development Lab, IBM

I am checking them in.

Thanks.

-- 
H.J.

^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: [PATCH v2 0/2] elf: Implement indirect external access marker
  2021-07-09  1:11           ` H.J. Lu
@ 2021-07-09  2:36             ` Alan Modra
  2021-07-09  3:16               ` H.J. Lu
  0 siblings, 1 reply; 12+ messages in thread
From: Alan Modra @ 2021-07-09  2:36 UTC (permalink / raw)
  To: H.J. Lu
  Cc: Florian Weimer, Binutils, Marcus Shawcroft, Ramana Radhakrishnan,
	Nick Clifton, Richard Earnshaw

On Thu, Jul 08, 2021 at 06:11:01PM -0700, H.J. Lu wrote:
> On Thu, Jul 8, 2021 at 5:56 PM Alan Modra <amodra@gmail.com> wrote:
> >
> > On Wed, Jul 07, 2021 at 04:27:43PM +0200, Florian Weimer wrote:
> > > Hmm, I see.  I guess it's up to the binutils maintainers to decide.
> >
> > The current patch looks reasonable to me.
> >
> > --
> > Alan Modra
> > Australia Development Lab, IBM
> 
> I am checking them in.

aarch64_be-linux-gnu_ilp32  +FAIL: ld-elf/property-1_needed-1b
aarch64_be-linux-gnu_ilp32  +FAIL: ld-elf/property-1_needed-1c
aarch64-elf  +FAIL: ld-elf/property-1_needed-1b
aarch64-elf  +FAIL: ld-elf/property-1_needed-1c
aarch64-linux  +FAIL: ld-elf/property-1_needed-1b
aarch64-linux  +FAIL: ld-elf/property-1_needed-1c
alpha-linux  +FAIL: ld-elf/property-1_needed-1b
alpha-linux  +FAIL: ld-elf/property-1_needed-1c
alpha-netbsd  +FAIL: ld-elf/property-1_needed-1b
alpha-netbsd  +FAIL: ld-elf/property-1_needed-1c
alpha-unknown-freebsd4.7  +FAIL: ld-elf/property-1_needed-1b
alpha-unknown-freebsd4.7  +FAIL: ld-elf/property-1_needed-1c
arc-elf  +FAIL: ld-elf/property-1_needed-1b
arc-elf  +FAIL: ld-elf/property-1_needed-1c
arc-linux-uclibc  +FAIL: ld-elf/property-1_needed-1b
arc-linux-uclibc  +FAIL: ld-elf/property-1_needed-1c
armeb-linuxeabi  +FAIL: ld-elf/property-1_needed-1b
armeb-linuxeabi  +FAIL: ld-elf/property-1_needed-1c
arm-elf  +FAIL: ld-elf/property-1_needed-1b
arm-elf  +FAIL: ld-elf/property-1_needed-1c
arm-linuxeabi  +FAIL: ld-elf/property-1_needed-1b
arm-linuxeabi  +FAIL: ld-elf/property-1_needed-1c
arm-nacl  +FAIL: ld-elf/property-1_needed-1b
arm-nacl  +FAIL: ld-elf/property-1_needed-1c
arm-netbsdelf  +FAIL: ld-elf/property-1_needed-1b
arm-netbsdelf  +FAIL: ld-elf/property-1_needed-1c
arm-nto  +FAIL: ld-elf/property-1_needed-1b
arm-nto  +FAIL: ld-elf/property-1_needed-1c
bfin-elf  +FAIL: ld-elf/property-1_needed-1b
bfin-elf  +FAIL: ld-elf/property-1_needed-1c
bfin-linux-uclibc  +FAIL: ld-elf/property-1_needed-1b
bfin-linux-uclibc  +FAIL: ld-elf/property-1_needed-1c
cris-linux  +FAIL: ld-elf/property-1_needed-1b
cris-linux  +FAIL: ld-elf/property-1_needed-1c
crisv32-linux  +FAIL: ld-elf/property-1_needed-1b
crisv32-linux  +FAIL: ld-elf/property-1_needed-1c
csky-linux  +FAIL: ld-elf/property-1_needed-1b
csky-linux  +FAIL: ld-elf/property-1_needed-1c
frv-linux  +FAIL: ld-elf/property-1_needed-1b
frv-linux  +FAIL: ld-elf/property-1_needed-1c
hppa64-linux  +FAIL: ld-elf/property-1_needed-1b
hppa64-linux  +FAIL: ld-elf/property-1_needed-1c
hppa-linux  +FAIL: ld-elf/property-1_needed-1b
hppa-linux  +FAIL: ld-elf/property-1_needed-1c
i386-darwin  +FAIL: eqv involving dot
i386-lynxos  +FAIL: ld-elf/property-1_needed-1b
i386-lynxos  +FAIL: ld-elf/property-1_needed-1c
i686-nto  +FAIL: ld-elf/property-1_needed-1b
i686-nto  +FAIL: ld-elf/property-1_needed-1c
ia64-elf  +FAIL: ld-elf/property-1_needed-1b
ia64-elf  +FAIL: ld-elf/property-1_needed-1c
ia64-freebsd5  +FAIL: ld-elf/property-1_needed-1b
ia64-freebsd5  +FAIL: ld-elf/property-1_needed-1c
ia64-linux  +FAIL: ld-elf/property-1_needed-1b
ia64-linux  +FAIL: ld-elf/property-1_needed-1c
ia64-netbsd  +FAIL: ld-elf/property-1_needed-1b
ia64-netbsd  +FAIL: ld-elf/property-1_needed-1c
lm32-linux  +FAIL: ld-elf/property-1_needed-1b
lm32-linux  +FAIL: ld-elf/property-1_needed-1c
m32r-linux  +FAIL: ld-elf/property-1_needed-1b
m32r-linux  +FAIL: ld-elf/property-1_needed-1c
m68k-elf  +FAIL: ld-elf/property-1_needed-1b
m68k-elf  +FAIL: ld-elf/property-1_needed-1c
m68k-linux  +FAIL: ld-elf/property-1_needed-1b
m68k-linux  +FAIL: ld-elf/property-1_needed-1c
metag-linux  +FAIL: ld-elf/property-1_needed-1b
metag-linux  +FAIL: ld-elf/property-1_needed-1c
microblaze-linux  +FAIL: ld-elf/property-1_needed-1b
microblaze-linux  +FAIL: ld-elf/property-1_needed-1c
mips64el-openbsd  +FAIL: ld-elf/property-1_needed-1b
mips64el-openbsd  +FAIL: ld-elf/property-1_needed-1c
mips64-linux  +FAIL: ld-elf/property-1_needed-1b
mips64-linux  +FAIL: ld-elf/property-1_needed-1c
mips64-openbsd  +FAIL: ld-elf/property-1_needed-1b
mips64-openbsd  +FAIL: ld-elf/property-1_needed-1c
mipsel-linux-gnu  +FAIL: ld-elf/property-1_needed-1b
mipsel-linux-gnu  +FAIL: ld-elf/property-1_needed-1c
mipsisa32el-linux  +FAIL: ld-elf/property-1_needed-1b
mipsisa32el-linux  +FAIL: ld-elf/property-1_needed-1c
mipsisa32r2el-elf  +FAIL: ld-elf/property-1_needed-1b
mipsisa32r2el-elf  +FAIL: ld-elf/property-1_needed-1c
mips-linux  +FAIL: ld-elf/property-1_needed-1b
mips-linux  +FAIL: ld-elf/property-1_needed-1c
mips-sgi-irix6  +FAIL: ld-elf/property-1_needed-1b
mips-sgi-irix6  +FAIL: ld-elf/property-1_needed-1c
mipstx39-elf  +FAIL: ld-elf/property-1_needed-1b
mipstx39-elf  +FAIL: ld-elf/property-1_needed-1c
nds32le-linux  +FAIL: ld-elf/property-1_needed-1b
nds32le-linux  +FAIL: ld-elf/property-1_needed-1c
nios2-linux  +FAIL: ld-elf/property-1_needed-1b
nios2-linux  +FAIL: ld-elf/property-1_needed-1c
or1k-linux  +FAIL: ld-elf/property-1_needed-1b
or1k-linux  +FAIL: ld-elf/property-1_needed-1c
pj-elf  -FAIL: pj
powerpc64-freebsd  +FAIL: ld-elf/property-1_needed-1b
powerpc64-freebsd  +FAIL: ld-elf/property-1_needed-1c
powerpc64le-linux  +FAIL: ld-elf/property-1_needed-1b
powerpc64le-linux  +FAIL: ld-elf/property-1_needed-1c
powerpc64-linux  +FAIL: ld-elf/property-1_needed-1b
powerpc64-linux  +FAIL: ld-elf/property-1_needed-1c
powerpc-eabisim  +FAIL: ld-elf/property-1_needed-1b
powerpc-eabisim  +FAIL: ld-elf/property-1_needed-1c
powerpc-eabivle  +FAIL: ld-elf/property-1_needed-1b
powerpc-eabivle  +FAIL: ld-elf/property-1_needed-1c
powerpc-freebsd  +FAIL: ld-elf/property-1_needed-1b
powerpc-freebsd  +FAIL: ld-elf/property-1_needed-1c
powerpcle-elf  +FAIL: ld-elf/property-1_needed-1b
powerpcle-elf  +FAIL: ld-elf/property-1_needed-1c
powerpc-linux  +FAIL: ld-elf/property-1_needed-1b
powerpc-linux  +FAIL: ld-elf/property-1_needed-1c
powerpc-nto  +FAIL: ld-elf/property-1_needed-1b
powerpc-nto  +FAIL: ld-elf/property-1_needed-1c
riscv64-linux  +FAIL: ld-elf/property-1_needed-1b
riscv64-linux  +FAIL: ld-elf/property-1_needed-1c
s390-linux  +FAIL: ld-elf/property-1_needed-1b
s390-linux  +FAIL: ld-elf/property-1_needed-1c
s390x-linux  +FAIL: ld-elf/property-1_needed-1b
s390x-linux  +FAIL: ld-elf/property-1_needed-1c
score-elf  +FAIL: ld-elf/property-1_needed-1b
score-elf  +FAIL: ld-elf/property-1_needed-1c
shle-unknown-netbsdelf  +FAIL: ld-elf/property-1_needed-1b
shle-unknown-netbsdelf  +FAIL: ld-elf/property-1_needed-1c
sh-linux  +FAIL: ld-elf/property-1_needed-1b
sh-linux  +FAIL: ld-elf/property-1_needed-1c
sh-nto  +FAIL: ld-elf/property-1_needed-1b
sh-nto  +FAIL: ld-elf/property-1_needed-1c
sh-rtems  +FAIL: ld-elf/property-1_needed-1b
sh-rtems  +FAIL: ld-elf/property-1_needed-1c
sparc64-linux  +FAIL: ld-elf/property-1_needed-1b
sparc64-linux  +FAIL: ld-elf/property-1_needed-1c
sparc-elf  +FAIL: ld-elf/property-1_needed-1b
sparc-elf  +FAIL: ld-elf/property-1_needed-1c
sparc-linux  +FAIL: ld-elf/property-1_needed-1b
sparc-linux  +FAIL: ld-elf/property-1_needed-1c
sparc-sun-solaris2  +FAIL: ld-elf/property-1_needed-1b
sparc-sun-solaris2  +FAIL: ld-elf/property-1_needed-1c
tic6x-elf  +FAIL: ld-elf/property-1_needed-1b
tic6x-elf  +FAIL: ld-elf/property-1_needed-1c
tilegx-linux  +FAIL: ld-elf/property-1_needed-1b
tilegx-linux  +FAIL: ld-elf/property-1_needed-1c
tilepro-linux  +FAIL: ld-elf/property-1_needed-1b
tilepro-linux  +FAIL: ld-elf/property-1_needed-1c
vax-netbsdelf  +FAIL: ld-elf/property-1_needed-1b
vax-netbsdelf  +FAIL: ld-elf/property-1_needed-1c
xtensa-elf  +FAIL: ld-elf/property-1_needed-1b
xtensa-elf  +FAIL: ld-elf/property-1_needed-1c

-- 
Alan Modra
Australia Development Lab, IBM

^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: [PATCH v2 0/2] elf: Implement indirect external access marker
  2021-07-09  2:36             ` Alan Modra
@ 2021-07-09  3:16               ` H.J. Lu
  0 siblings, 0 replies; 12+ messages in thread
From: H.J. Lu @ 2021-07-09  3:16 UTC (permalink / raw)
  To: Alan Modra
  Cc: Florian Weimer, Binutils, Marcus Shawcroft, Ramana Radhakrishnan,
	Nick Clifton, Richard Earnshaw

[-- Attachment #1: Type: text/plain, Size: 8040 bytes --]

On Thu, Jul 8, 2021 at 7:36 PM Alan Modra <amodra@gmail.com> wrote:
>
> On Thu, Jul 08, 2021 at 06:11:01PM -0700, H.J. Lu wrote:
> > On Thu, Jul 8, 2021 at 5:56 PM Alan Modra <amodra@gmail.com> wrote:
> > >
> > > On Wed, Jul 07, 2021 at 04:27:43PM +0200, Florian Weimer wrote:
> > > > Hmm, I see.  I guess it's up to the binutils maintainers to decide.
> > >
> > > The current patch looks reasonable to me.
> > >
> > > --
> > > Alan Modra
> > > Australia Development Lab, IBM
> >
> > I am checking them in.
>
> aarch64_be-linux-gnu_ilp32  +FAIL: ld-elf/property-1_needed-1b
> aarch64_be-linux-gnu_ilp32  +FAIL: ld-elf/property-1_needed-1c
> aarch64-elf  +FAIL: ld-elf/property-1_needed-1b
> aarch64-elf  +FAIL: ld-elf/property-1_needed-1c
> aarch64-linux  +FAIL: ld-elf/property-1_needed-1b
> aarch64-linux  +FAIL: ld-elf/property-1_needed-1c
> alpha-linux  +FAIL: ld-elf/property-1_needed-1b
> alpha-linux  +FAIL: ld-elf/property-1_needed-1c
> alpha-netbsd  +FAIL: ld-elf/property-1_needed-1b
> alpha-netbsd  +FAIL: ld-elf/property-1_needed-1c
> alpha-unknown-freebsd4.7  +FAIL: ld-elf/property-1_needed-1b
> alpha-unknown-freebsd4.7  +FAIL: ld-elf/property-1_needed-1c
> arc-elf  +FAIL: ld-elf/property-1_needed-1b
> arc-elf  +FAIL: ld-elf/property-1_needed-1c
> arc-linux-uclibc  +FAIL: ld-elf/property-1_needed-1b
> arc-linux-uclibc  +FAIL: ld-elf/property-1_needed-1c
> armeb-linuxeabi  +FAIL: ld-elf/property-1_needed-1b
> armeb-linuxeabi  +FAIL: ld-elf/property-1_needed-1c
> arm-elf  +FAIL: ld-elf/property-1_needed-1b
> arm-elf  +FAIL: ld-elf/property-1_needed-1c
> arm-linuxeabi  +FAIL: ld-elf/property-1_needed-1b
> arm-linuxeabi  +FAIL: ld-elf/property-1_needed-1c
> arm-nacl  +FAIL: ld-elf/property-1_needed-1b
> arm-nacl  +FAIL: ld-elf/property-1_needed-1c
> arm-netbsdelf  +FAIL: ld-elf/property-1_needed-1b
> arm-netbsdelf  +FAIL: ld-elf/property-1_needed-1c
> arm-nto  +FAIL: ld-elf/property-1_needed-1b
> arm-nto  +FAIL: ld-elf/property-1_needed-1c
> bfin-elf  +FAIL: ld-elf/property-1_needed-1b
> bfin-elf  +FAIL: ld-elf/property-1_needed-1c
> bfin-linux-uclibc  +FAIL: ld-elf/property-1_needed-1b
> bfin-linux-uclibc  +FAIL: ld-elf/property-1_needed-1c
> cris-linux  +FAIL: ld-elf/property-1_needed-1b
> cris-linux  +FAIL: ld-elf/property-1_needed-1c
> crisv32-linux  +FAIL: ld-elf/property-1_needed-1b
> crisv32-linux  +FAIL: ld-elf/property-1_needed-1c
> csky-linux  +FAIL: ld-elf/property-1_needed-1b
> csky-linux  +FAIL: ld-elf/property-1_needed-1c
> frv-linux  +FAIL: ld-elf/property-1_needed-1b
> frv-linux  +FAIL: ld-elf/property-1_needed-1c
> hppa64-linux  +FAIL: ld-elf/property-1_needed-1b
> hppa64-linux  +FAIL: ld-elf/property-1_needed-1c
> hppa-linux  +FAIL: ld-elf/property-1_needed-1b
> hppa-linux  +FAIL: ld-elf/property-1_needed-1c
> i386-darwin  +FAIL: eqv involving dot
> i386-lynxos  +FAIL: ld-elf/property-1_needed-1b
> i386-lynxos  +FAIL: ld-elf/property-1_needed-1c
> i686-nto  +FAIL: ld-elf/property-1_needed-1b
> i686-nto  +FAIL: ld-elf/property-1_needed-1c
> ia64-elf  +FAIL: ld-elf/property-1_needed-1b
> ia64-elf  +FAIL: ld-elf/property-1_needed-1c
> ia64-freebsd5  +FAIL: ld-elf/property-1_needed-1b
> ia64-freebsd5  +FAIL: ld-elf/property-1_needed-1c
> ia64-linux  +FAIL: ld-elf/property-1_needed-1b
> ia64-linux  +FAIL: ld-elf/property-1_needed-1c
> ia64-netbsd  +FAIL: ld-elf/property-1_needed-1b
> ia64-netbsd  +FAIL: ld-elf/property-1_needed-1c
> lm32-linux  +FAIL: ld-elf/property-1_needed-1b
> lm32-linux  +FAIL: ld-elf/property-1_needed-1c
> m32r-linux  +FAIL: ld-elf/property-1_needed-1b
> m32r-linux  +FAIL: ld-elf/property-1_needed-1c
> m68k-elf  +FAIL: ld-elf/property-1_needed-1b
> m68k-elf  +FAIL: ld-elf/property-1_needed-1c
> m68k-linux  +FAIL: ld-elf/property-1_needed-1b
> m68k-linux  +FAIL: ld-elf/property-1_needed-1c
> metag-linux  +FAIL: ld-elf/property-1_needed-1b
> metag-linux  +FAIL: ld-elf/property-1_needed-1c
> microblaze-linux  +FAIL: ld-elf/property-1_needed-1b
> microblaze-linux  +FAIL: ld-elf/property-1_needed-1c
> mips64el-openbsd  +FAIL: ld-elf/property-1_needed-1b
> mips64el-openbsd  +FAIL: ld-elf/property-1_needed-1c
> mips64-linux  +FAIL: ld-elf/property-1_needed-1b
> mips64-linux  +FAIL: ld-elf/property-1_needed-1c
> mips64-openbsd  +FAIL: ld-elf/property-1_needed-1b
> mips64-openbsd  +FAIL: ld-elf/property-1_needed-1c
> mipsel-linux-gnu  +FAIL: ld-elf/property-1_needed-1b
> mipsel-linux-gnu  +FAIL: ld-elf/property-1_needed-1c
> mipsisa32el-linux  +FAIL: ld-elf/property-1_needed-1b
> mipsisa32el-linux  +FAIL: ld-elf/property-1_needed-1c
> mipsisa32r2el-elf  +FAIL: ld-elf/property-1_needed-1b
> mipsisa32r2el-elf  +FAIL: ld-elf/property-1_needed-1c
> mips-linux  +FAIL: ld-elf/property-1_needed-1b
> mips-linux  +FAIL: ld-elf/property-1_needed-1c
> mips-sgi-irix6  +FAIL: ld-elf/property-1_needed-1b
> mips-sgi-irix6  +FAIL: ld-elf/property-1_needed-1c
> mipstx39-elf  +FAIL: ld-elf/property-1_needed-1b
> mipstx39-elf  +FAIL: ld-elf/property-1_needed-1c
> nds32le-linux  +FAIL: ld-elf/property-1_needed-1b
> nds32le-linux  +FAIL: ld-elf/property-1_needed-1c
> nios2-linux  +FAIL: ld-elf/property-1_needed-1b
> nios2-linux  +FAIL: ld-elf/property-1_needed-1c
> or1k-linux  +FAIL: ld-elf/property-1_needed-1b
> or1k-linux  +FAIL: ld-elf/property-1_needed-1c
> pj-elf  -FAIL: pj
> powerpc64-freebsd  +FAIL: ld-elf/property-1_needed-1b
> powerpc64-freebsd  +FAIL: ld-elf/property-1_needed-1c
> powerpc64le-linux  +FAIL: ld-elf/property-1_needed-1b
> powerpc64le-linux  +FAIL: ld-elf/property-1_needed-1c
> powerpc64-linux  +FAIL: ld-elf/property-1_needed-1b
> powerpc64-linux  +FAIL: ld-elf/property-1_needed-1c
> powerpc-eabisim  +FAIL: ld-elf/property-1_needed-1b
> powerpc-eabisim  +FAIL: ld-elf/property-1_needed-1c
> powerpc-eabivle  +FAIL: ld-elf/property-1_needed-1b
> powerpc-eabivle  +FAIL: ld-elf/property-1_needed-1c
> powerpc-freebsd  +FAIL: ld-elf/property-1_needed-1b
> powerpc-freebsd  +FAIL: ld-elf/property-1_needed-1c
> powerpcle-elf  +FAIL: ld-elf/property-1_needed-1b
> powerpcle-elf  +FAIL: ld-elf/property-1_needed-1c
> powerpc-linux  +FAIL: ld-elf/property-1_needed-1b
> powerpc-linux  +FAIL: ld-elf/property-1_needed-1c
> powerpc-nto  +FAIL: ld-elf/property-1_needed-1b
> powerpc-nto  +FAIL: ld-elf/property-1_needed-1c
> riscv64-linux  +FAIL: ld-elf/property-1_needed-1b
> riscv64-linux  +FAIL: ld-elf/property-1_needed-1c
> s390-linux  +FAIL: ld-elf/property-1_needed-1b
> s390-linux  +FAIL: ld-elf/property-1_needed-1c
> s390x-linux  +FAIL: ld-elf/property-1_needed-1b
> s390x-linux  +FAIL: ld-elf/property-1_needed-1c
> score-elf  +FAIL: ld-elf/property-1_needed-1b
> score-elf  +FAIL: ld-elf/property-1_needed-1c
> shle-unknown-netbsdelf  +FAIL: ld-elf/property-1_needed-1b
> shle-unknown-netbsdelf  +FAIL: ld-elf/property-1_needed-1c
> sh-linux  +FAIL: ld-elf/property-1_needed-1b
> sh-linux  +FAIL: ld-elf/property-1_needed-1c
> sh-nto  +FAIL: ld-elf/property-1_needed-1b
> sh-nto  +FAIL: ld-elf/property-1_needed-1c
> sh-rtems  +FAIL: ld-elf/property-1_needed-1b
> sh-rtems  +FAIL: ld-elf/property-1_needed-1c
> sparc64-linux  +FAIL: ld-elf/property-1_needed-1b
> sparc64-linux  +FAIL: ld-elf/property-1_needed-1c
> sparc-elf  +FAIL: ld-elf/property-1_needed-1b
> sparc-elf  +FAIL: ld-elf/property-1_needed-1c
> sparc-linux  +FAIL: ld-elf/property-1_needed-1b
> sparc-linux  +FAIL: ld-elf/property-1_needed-1c
> sparc-sun-solaris2  +FAIL: ld-elf/property-1_needed-1b
> sparc-sun-solaris2  +FAIL: ld-elf/property-1_needed-1c
> tic6x-elf  +FAIL: ld-elf/property-1_needed-1b
> tic6x-elf  +FAIL: ld-elf/property-1_needed-1c
> tilegx-linux  +FAIL: ld-elf/property-1_needed-1b
> tilegx-linux  +FAIL: ld-elf/property-1_needed-1c
> tilepro-linux  +FAIL: ld-elf/property-1_needed-1b
> tilepro-linux  +FAIL: ld-elf/property-1_needed-1c
> vax-netbsdelf  +FAIL: ld-elf/property-1_needed-1b
> vax-netbsdelf  +FAIL: ld-elf/property-1_needed-1c
> xtensa-elf  +FAIL: ld-elf/property-1_needed-1b
> xtensa-elf  +FAIL: ld-elf/property-1_needed-1c
>

I am checking this to limit GNU_PROPERTY_1_NEEDED
tests to Linux/x86.


--
H.J.

[-- Attachment #2: 0001-elf-Limits-2-GNU_PROPERTY_1_NEEDED-tests-to-Linux-x8.patch --]
[-- Type: application/x-patch, Size: 2050 bytes --]

^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: [PATCH v2 0/2] elf: Implement indirect external access marker
  2021-07-07 14:27       ` Florian Weimer
  2021-07-09  0:56         ` Alan Modra
@ 2021-07-09  3:25         ` Fangrui Song
  1 sibling, 0 replies; 12+ messages in thread
From: Fangrui Song @ 2021-07-09  3:25 UTC (permalink / raw)
  To: Florian Weimer
  Cc: H.J. Lu, Binutils, Ramana Radhakrishnan, Marcus Shawcroft,
	Richard Earnshaw

On 2021-07-07, Florian Weimer via Binutils wrote:
>* H. J. Lu:
>
>> On Wed, Jul 7, 2021 at 7:01 AM Florian Weimer <fweimer@redhat.com> wrote:
>>>
>>> * H. J. Lu:
>>>
>>> > I am checking in this patch by the end of this week.
>>>
>>> Shouldn't the ABI specification be finalized first?  (Sorry.)
>>>
>>
>> Did you mean adding GNU_PROPERTY_1_NEEDED_INDIRECT_EXTERN_ACCESS?
>> I have submitted linker, GCC and glibc patches to show how it is used.
>>
>> To see how it works, we need to start with a working linker.  That is
>> why I want to add it to the linker now.
>
>Hmm, I see.  I guess it's up to the binutils maintainers to decide.
>
>Thanks,
>Florian
>

Seems that the motivation is GNU ld internals
https://sourceware.org/pipermail/binutils/2021-June/117132.html
If so, I am fine with this GNU property (but I will not recommend it within llvm-project).

---

I hope glibc's diagnostic on "rejecting copy relocations on protected data symbol"
can be unconditional, not check this GNU property.

Here https://lists.llvm.org/pipermail/llvm-dev/2021-June/151248.html 
I investigated many binutils versions (2.11, 2.16, 2.20, 2.24, 2.35).
They have the same diagnostic

   relocation R_X86_64_PC32 against protected function `addr' can not be used when making a shared object

for

   // protected data is similar
   __attribute__((visibility("protected"))) void *addr() { return (void*)addr; }

so we should just assume protected definitions never works and don't
bother with gnu property complexity in glibc.

^ permalink raw reply	[flat|nested] 12+ messages in thread

end of thread, other threads:[~2021-07-09  3:26 UTC | newest]

Thread overview: 12+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2021-06-22 23:57 [PATCH v2 0/2] elf: Implement indirect external access marker H.J. Lu
2021-06-22 23:57 ` [PATCH v2 1/2] elf: Add GNU_PROPERTY_1_NEEDED H.J. Lu
2021-06-22 23:57 ` [PATCH v2 2/2] elf: Add GNU_PROPERTY_1_NEEDED check H.J. Lu
2021-07-07 13:58 ` [PATCH v2 0/2] elf: Implement indirect external access marker H.J. Lu
2021-07-07 14:00   ` Florian Weimer
2021-07-07 14:13     ` H.J. Lu
2021-07-07 14:27       ` Florian Weimer
2021-07-09  0:56         ` Alan Modra
2021-07-09  1:11           ` H.J. Lu
2021-07-09  2:36             ` Alan Modra
2021-07-09  3:16               ` H.J. Lu
2021-07-09  3:25         ` Fangrui Song

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).