Add section caches to coff_data_type
authorOleg Tolmatcev <oleg.tolmatcev@gmail.com>
Tue, 16 May 2023 13:25:32 +0000 (14:25 +0100)
committerNick Clifton <nickc@redhat.com>
Tue, 16 May 2023 13:25:32 +0000 (14:25 +0100)
  * libcoff-in.h (struct coff_tdata): Add section_by_index and section_by_target_index hash tables.
  * libcoff.h: Regenerate.
  * coffcode.h (htab_hash_section_index): New function. (htab_eq_section_index): New function. (htab_hash_section_target_index): New function. (htab_eq_section_target_index): New function. (coff_mkobject_hool): Create the hash tables.
  * peicode.h: Add the same new functions. (pe_mkobject_hook): Create the hash tables.
  * coff-x86_64.c (coff_amd64_rtype_to_howto): Use the new tables to speed up lookups.
  * coffgen.c (coff_section_from_bfd_index): Likewise. (_bfd_coff_close_and_cleanup): Delete the hash tables.

bfd/ChangeLog
bfd/coff-x86_64.c
bfd/coffcode.h
bfd/coffgen.c
bfd/libcoff-in.h
bfd/libcoff.h
bfd/peicode.h

index 5cb20e1c278ff9e55ec698c213a2a75ed42e6aaa..dc4620663b2c0253a48d21c6e13276f5f30c7201 100644 (file)
@@ -1,3 +1,20 @@
+2023-05-16  Oleg Tolmatcev  <oleg.tolmatcev@gmail.com>
+
+       * libcoff-in.h (struct coff_tdata): Add section_by_index and
+       section_by_target_index hash tables.
+       * libcoff.h: Regenerate.
+       * coffcode.h (htab_hash_section_index): New function.
+       (htab_eq_section_index): New function.
+       (htab_hash_section_target_index): New function.
+       (htab_eq_section_target_index): New function.
+       (coff_mkobject_hool): Create the hash tables.
+       * peicode.h: Add the same new functions.
+       (pe_mkobject_hook): Create the hash tables.
+       * coff-x86_64.c (coff_amd64_rtype_to_howto): Use the new tables to
+       speed up lookups.
+       * coffgen.c (coff_section_from_bfd_index): Likewise.
+       (_bfd_coff_close_and_cleanup): Delete the hash tables.
+
 2023-05-10  Luca Bonissi  <gcc@scarsita.it>
 
        PR 30422
index 822504a339b1942101cb9474ef7899c991f8f461..1f8c8d515c42ce483cc8dd954860ea39f578a807 100644 (file)
@@ -745,22 +745,37 @@ 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))
+      if (h != NULL
+         && (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
        {
+         htab_t table = coff_data (abfd)->section_by_index;
          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;
+         if (htab_elements (table) == 0)
+           {
+             /* Sigh - if we do not have a section index then the only way
+                to get the section to offset against is to find it the hard
+                way.  */
+             for (s = abfd->sections; s != NULL; s = s->next)
+               {
+                 void ** slot = htab_find_slot (table, s, INSERT);
+
+                 if (slot != NULL)
+                   *slot = s;
+               }
+           }
+
+         struct bfd_section needle;
 
-         osect_vma = s->output_section->vma;
+         needle.index = sym->n_scnum - 1;
+         s = htab_find (table, &needle);
+         if (s != NULL)
+           osect_vma = s->output_section->vma;
        }
 
       *addendp -= osect_vma;
index 974c8ad98543f7a5a1be2b2bc862ffc4d54bbe91..ab6f797b324f3824969326ec8c4035ccaa14dc13 100644 (file)
@@ -731,6 +731,36 @@ sec_to_styp_flags (const char *sec_name, flagword sec_flags)
 
 #ifndef COFF_WITH_PE
 
+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
 styp_to_sec_flags (bfd *abfd,
                   void * hdr,
@@ -2062,6 +2092,7 @@ coff_mkobject (bfd * abfd)
   abfd->tdata.coff_obj_data = bfd_zalloc (abfd, amt);
   if (abfd->tdata.coff_obj_data == NULL)
     return false;
+
   coff = coff_data (abfd);
   coff->symbols = NULL;
   coff->conversion_table = NULL;
@@ -2154,6 +2185,11 @@ coff_mkobject_hook (bfd * abfd,
     abfd->flags |= HAS_DEBUG;
 #endif
 
+  coff->section_by_index
+    = htab_create (10, htab_hash_section_index, htab_eq_section_index, NULL);
+  coff->section_by_target_index = htab_create
+    (10, htab_hash_section_target_index, htab_eq_section_target_index, NULL);
+
   return coff;
 }
 #endif
index ac936def5665ff91ad77a6ff4227338e771e65fa..03b64ac6762e0a991c94a9d1cce23b373ad02cb8 100644 (file)
@@ -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,32 @@ coff_section_from_bfd_index (bfd *abfd, int section_index)
   if (section_index == N_DEBUG)
     return bfd_abs_section_ptr;
 
+  struct bfd_section *answer;
+  htab_t table = coff_data (abfd)->section_by_target_index;
+
+  if (htab_elements (table) == 0)
+    {
+      answer = abfd->sections;
+
+      while (answer)
+       {
+         void **slot = htab_find_slot (table, 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 (table, &needle);
+  if (answer != NULL)
+    return answer;
+
+  answer = abfd->sections;
+
   while (answer)
     {
       if (answer->target_index == section_index)
@@ -3142,6 +3167,21 @@ _bfd_coff_close_and_cleanup (bfd *abfd)
 
   if (tdata != NULL)
     {
+      if (bfd_family_coff (abfd) && bfd_get_format (abfd) == bfd_object)
+       {
+         if (tdata->section_by_index)
+           {
+             htab_delete (tdata->section_by_index);
+             tdata->section_by_index = NULL;
+           }
+
+         if (tdata->section_by_target_index)
+           {
+             htab_delete (tdata->section_by_target_index);
+             tdata->section_by_target_index = NULL;
+           }
+       }
+
       /* PR 25447:
         Do not clear the keep_syms and keep_strings flags.
         These may have been set by pe_ILF_build_a_bfd() indicating
@@ -3158,5 +3198,6 @@ _bfd_coff_close_and_cleanup (bfd *abfd)
          _bfd_stab_cleanup (abfd, &tdata->line_info);
        }
     }
+
   return _bfd_generic_close_and_cleanup (abfd);
 }
index d0839c76e9615d6da311d5e68fd353fc55e2b82d..9c5780bfcc03cc3563041cd023c06f0f38bb584b 100644 (file)
@@ -24,6 +24,7 @@
 
 #include "bfdlink.h"
 #include "coff-bfd.h"
+#include "hashtab.h"
 
 #ifdef __cplusplus
 extern "C" {
@@ -129,6 +130,13 @@ 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.  */
index 235d5c3c8436f2cb9d616bfda292f216c9c69ed3..1a8d930773491b2f73096dc4c538c5d720a9fd87 100644 (file)
@@ -28,6 +28,7 @@
 
 #include "bfdlink.h"
 #include "coff-bfd.h"
+#include "hashtab.h"
 
 #ifdef __cplusplus
 extern "C" {
@@ -133,6 +134,13 @@ 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.  */
index e2e2be65b5d1c097b1718f9f58d91b1ff9c7bb2c..436ff54fbeae8338e7a24cb5177a3ddc582e8883 100644 (file)
@@ -255,6 +255,36 @@ coff_swap_scnhdr_in (bfd * abfd, void * ext, void * in)
 #endif
 }
 
+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)
 {
@@ -352,6 +382,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;
 }