[prev in list] [next in list] [prev in thread] [next in thread] 

List:       binutils
Subject:    [PATCH] add section caches to coff_data_type
From:       Oleg Tolmatcev via Binutils <binutils () sourceware ! org>
Date:       2023-04-29 11:19:26
Message-ID: CACcXsZjWfeQR3_pC3nVtq+sAkq-QGfEnA3DE2K8rsDnK9edWrQ () mail ! gmail ! com
[Download RAW message or body]

Hello all,

final patch to ld. All the patches together improve linking
performance from 9 minutes to 1 minute when linking rpcs3 in debug
mode with BUILD_LLVM=ON.

---
 bfd/coff-x86_64.c | 35 +++++++++++++++++++++++------------
 bfd/coffgen.c     | 27 +++++++++++++++++++++++++--
 bfd/libcoff-in.h  |  6 ++++++
 bfd/libcoff.h     |  6 ++++++
 bfd/peicode.h     | 35 +++++++++++++++++++++++++++++++++++
 5 files changed, 95 insertions(+), 14 deletions(-)

diff --git a/bfd/coff-x86_64.c b/bfd/coff-x86_64.c
index 822504a339..09291e2455 100644
--- a/bfd/coff-x86_64.c
+++ b/bfd/coff-x86_64.c
@@ -745,23 +745,34 @@ coff_amd64_rtype_to_howto (bfd *abfd ATTRIBUTE_UNUSED,

   if (rel->r_type == R_AMD64_SECREL)
     {
-      bfd_vma osect_vma;
+      bfd_vma osect_vma = 0;

       if (h && (h->root.type == bfd_link_hash_defined
         || h->root.type == bfd_link_hash_defweak))
     osect_vma = h->root.u.def.section->output_section->vma;
       else
-    {
-      asection *s;
-      int i;
-
-      /* Sigh, the only way to get the section to offset against
-         is to find it the hard way.  */
-      for (s = abfd->sections, i = 1; i < sym->n_scnum; i++)
-        s = s->next;
-
-      osect_vma = s->output_section->vma;
-    }
+        {
+          asection *s;
+
+          /* Sigh, the only way to get the section to offset against
+             is to find it the hard way.  */
+
+          if (htab_elements (coff_data (abfd)->section_by_index) == 0)
+            {
+              for (s = abfd->sections; s != NULL; s = s->next)
+                {
+                  void **slot
+                      = htab_find_slot (coff_data
(abfd)->section_by_index, s, INSERT);
+                  if (slot != NULL)
+                    *slot = s;
+                }
+            }
+          struct bfd_section needle;
+          needle.index = sym->n_scnum - 1;
+          s = htab_find (coff_data (abfd)->section_by_index, &needle);
+          if (s != NULL)
+            osect_vma = s->output_section->vma;
+        }

       *addendp -= osect_vma;
     }
diff --git a/bfd/coffgen.c b/bfd/coffgen.c
index 05f2640abe..326a7dbd88 100644
--- a/bfd/coffgen.c
+++ b/bfd/coffgen.c
@@ -42,6 +42,7 @@
 #include "libbfd.h"
 #include "coff/internal.h"
 #include "libcoff.h"
+#include "hashtab.h"

 /* Take a section header read from a coff file (in HOST byte order),
    and make a BFD "section" out of it.  This is used by ECOFF.  */
@@ -360,8 +361,6 @@ coff_object_p (bfd *abfd)
 asection *
 coff_section_from_bfd_index (bfd *abfd, int section_index)
 {
-  struct bfd_section *answer = abfd->sections;
-
   if (section_index == N_ABS)
     return bfd_abs_section_ptr;
   if (section_index == N_UNDEF)
@@ -369,6 +368,30 @@ coff_section_from_bfd_index (bfd *abfd, int section_index)
   if (section_index == N_DEBUG)
     return bfd_abs_section_ptr;

+  struct bfd_section *answer;
+
+  if (htab_elements (coff_data (abfd)->section_by_target_index) == 0)
+    {
+      answer = abfd->sections;
+      while (answer)
+        {
+          void **slot
+              = htab_find_slot (coff_data
(abfd)->section_by_target_index, answer, INSERT);
+          if (slot == NULL)
+            return bfd_und_section_ptr;
+          *slot = answer;
+          answer = answer->next;
+        }
+    }
+
+  struct bfd_section needle;
+  needle.target_index = section_index;
+
+  answer = htab_find (coff_data (abfd)->section_by_target_index, &needle);
+  if (answer != NULL)
+    return answer;
+
+  answer = abfd->sections;
   while (answer)
     {
       if (answer->target_index == section_index)
diff --git a/bfd/libcoff-in.h b/bfd/libcoff-in.h
index cdd504605b..6f4109931c 100644
--- a/bfd/libcoff-in.h
+++ b/bfd/libcoff-in.h
@@ -130,6 +130,12 @@ typedef struct coff_tdata
      COFF object into memory.  */
   char * stub;
   bfd_size_type stub_size;
+
+  /* hash table containing sections by target index */
+  htab_t section_by_target_index;
+
+  /* hash table containing sections by index */
+  htab_t section_by_index;
 } coff_data_type;

 /* Tdata for pe image files.  */
diff --git a/bfd/libcoff.h b/bfd/libcoff.h
index b58ee8aded..0cb335ee8d 100644
--- a/bfd/libcoff.h
+++ b/bfd/libcoff.h
@@ -133,6 +133,12 @@ typedef struct coff_tdata
      COFF object into memory.  */
   char * stub;
   bfd_size_type stub_size;
+
+  /* hash table containing sections by target index */
+  htab_t section_by_target_index;
+
+  /* hash table containing sections by index */
+  htab_t section_by_index;
 } coff_data_type;

 /* Tdata for pe image files.  */
diff --git a/bfd/peicode.h b/bfd/peicode.h
index df1e678b5a..c60961be9f 100644
--- a/bfd/peicode.h
+++ b/bfd/peicode.h
@@ -274,6 +274,36 @@ htab_eq_flags (const void *e1, const void *e2)
          && fe1->target_index == fe2->target_index;
 }

+static hashval_t
+htab_hash_section_index (const void *entry)
+{
+  const struct bfd_section *sec = entry;
+  return sec->index;
+}
+
+static int
+htab_eq_section_index (const void *e1, const void *e2)
+{
+  const struct bfd_section *sec1 = e1;
+  const struct bfd_section *sec2 = e2;
+  return sec1->index == sec2->index;
+}
+
+static hashval_t
+htab_hash_section_target_index (const void *entry)
+{
+  const struct bfd_section *sec = entry;
+  return sec->target_index;
+}
+
+static int
+htab_eq_section_target_index (const void *e1, const void *e2)
+{
+  const struct bfd_section *sec1 = e1;
+  const struct bfd_section *sec2 = e2;
+  return sec1->target_index == sec2->target_index;
+}
+
 static bool
 pe_mkobject (bfd * abfd)
 {
@@ -373,6 +403,11 @@ pe_mkobject_hook (bfd * abfd,
   memcpy (pe->dos_message, internal_f->pe.dos_message,
       sizeof (pe->dos_message));

+  pe->coff.section_by_index
+      = htab_create (10, htab_hash_section_index, htab_eq_section_index, NULL);
+  pe->coff.section_by_target_index = htab_create (
+      10, htab_hash_section_target_index, htab_eq_section_target_index, NULL);
+
   return (void *) pe;
 }

-- 
2.40.0.windows.1
[prev in list] [next in list] [prev in thread] [next in thread] 

Configure | About | News | Add a list | Sponsored by KoreLogic