This is the mail archive of the binutils@sourceware.org mailing list for the binutils project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[AArch64] Optimize .gnu.hash table size for executable


  For a loadable obj, if the one symbol is satisfied by another external obj,
then it's not necessary to be added into .gnu.hash (except that function's
address is taken in which case we need a undefined symbol with an absolute
value).  For the testcase attached, I found dec is added into the executable's
.gnu.hash section on AArch64.

  I am seeing the default hash hook is using the following check:

  _bfd_elf_hash_symbol:

         ! (...
            || ((h->root.type == bfd_link_hash_defined
                || h->root.type == bfd_link_hash_defweak)
               && h->root.u.def.section->output_section == NULL));

  While for function symbol defined in shared library and referenced in
executable, the output_section is not NULL.

  This patch borrows the same code from X86-64 and Powerpc to avoid such symbol
be added into .gnu.hash.

  For example like "Clang" binary, the .gnu.hash size reduced from 0x0c6820
into 0x0c630c after this patch.

  OK for master?

2017-01-17  Jiong Wang  <jiong.wang@arm.com>
bfd/
        * elfnn-aarch64.c (elf_aarch64_hash_symbol): New function.
        (elf_backend_hash_symbol): Define.

ld/
        * testsuite/ld-aarch64/aarch64-elf.exp (aarch64elflinktests): New tests.
        * testsuite/ld-aarch64/func-in-so.s: New test source file.
        * testsuite/ld-aarch64/func-sym-hash-opt.s: Likewise.
        * testsuite/ld-aarch64/func-sym-hash-opt.d: New expected test result.

diff --git a/bfd/elfnn-aarch64.c b/bfd/elfnn-aarch64.c
index 6ea2d355d412ec5cbbfa7aba3f1cc72926ebee5e..213cf55f624ea5499f7a16354bb829fd3f18bb89 100644
--- a/bfd/elfnn-aarch64.c
+++ b/bfd/elfnn-aarch64.c
@@ -2708,6 +2708,22 @@ elfNN_aarch64_stub_name (const asection *input_section,
   return stub_name;
 }
 
+/* Return TRUE if symbol H should be hashed in the `.gnu.hash' section.  For
+   executable PLT slots where the executable never takes the address of those
+   functions, the function symbols are not added to the hash table.  */
+
+static bfd_boolean
+elf_aarch64_hash_symbol (struct elf_link_hash_entry *h)
+{
+  if (h->plt.offset != (bfd_vma) -1
+      && !h->def_regular
+      && !h->pointer_equality_needed)
+    return FALSE;
+
+  return _bfd_elf_hash_symbol (h);
+}
+
+
 /* Look up an entry in the stub hash.  Stub entries are cached because
    creating the stub name takes a bit of time.  */
 
@@ -9412,6 +9428,7 @@ const struct elf_size_info elfNN_aarch64_size_info =
 #define elf_backend_got_header_size (GOT_ENTRY_SIZE * 3)
 #define elf_backend_default_execstack  0
 #define elf_backend_extern_protected_data 1
+#define elf_backend_hash_symbol elf_aarch64_hash_symbol
 
 #undef  elf_backend_obj_attrs_section
 #define elf_backend_obj_attrs_section		".ARM.attributes"
diff --git a/ld/testsuite/ld-aarch64/aarch64-elf.exp b/ld/testsuite/ld-aarch64/aarch64-elf.exp
index 09002678858ce8cb3efda37c93015da8220497f3..f77b169f606d73c6901cfea326da2b6b2909705a 100644
--- a/ld/testsuite/ld-aarch64/aarch64-elf.exp
+++ b/ld/testsuite/ld-aarch64/aarch64-elf.exp
@@ -323,6 +323,11 @@ set aarch64elflinktests {
     {} "copy-reloc-so.so"}
   {"ld-aarch64/exe with copy relocation" "-e0 tmpdir/copy-reloc-so.so" "" ""
     {copy-reloc-exe.s} {{objdump -R copy-reloc.d}} "copy-reloc"}
+  {"ld-aarch64/so with global func" "-shared" "" "" {func-in-so.s}
+    {} "func-in-so.so"}
+  {"ld-aarch64/func sym hash opt for exe"
+   "-e0 --hash-style=gnu tmpdir/func-in-so.so" "" ""
+    {func-sym-hash-opt.s} {{readelf --dyn-sym func-sym-hash-opt.d}} "hash-opt"}
 }
 
 run_ld_link_tests $aarch64elflinktests
diff --git a/ld/testsuite/ld-aarch64/func-in-so.s b/ld/testsuite/ld-aarch64/func-in-so.s
new file mode 100644
index 0000000000000000000000000000000000000000..608eead99cd04442d0fb6aae586a71769b1a4b17
--- /dev/null
+++ b/ld/testsuite/ld-aarch64/func-in-so.s
@@ -0,0 +1,6 @@
+	.text
+	.align	2
+	.global	dec
+	.type	dec, %function
+dec:
+	ret
diff --git a/ld/testsuite/ld-aarch64/func-sym-hash-opt.d b/ld/testsuite/ld-aarch64/func-sym-hash-opt.d
new file mode 100644
index 0000000000000000000000000000000000000000..8ffeb005907f278183c878d059226f7678b6424a
--- /dev/null
+++ b/ld/testsuite/ld-aarch64/func-sym-hash-opt.d
@@ -0,0 +1,6 @@
+
+Symbol table '.dynsym' contains .* entries:
+   Num:    Value          Size Type    Bind   Vis      Ndx Name
+     0: 0000000000000000     0 NOTYPE  LOCAL  DEFAULT  UND 
+     1: 0000000000000000     0 FUNC    GLOBAL DEFAULT  UND dec
+#...
diff --git a/ld/testsuite/ld-aarch64/func-sym-hash-opt.s b/ld/testsuite/ld-aarch64/func-sym-hash-opt.s
new file mode 100644
index 0000000000000000000000000000000000000000..70f8f8e0e813ba3ccb9d063e5e38bf31b3604bfe
--- /dev/null
+++ b/ld/testsuite/ld-aarch64/func-sym-hash-opt.s
@@ -0,0 +1,7 @@
+	.text
+	.align	2
+	.global	main
+	.type	main, %function
+main:
+	bl	dec
+	ret

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]