x86: Add elf_x86_allocate_local_got_info
authorH.J. Lu <hjl.tools@gmail.com>
Wed, 5 Jan 2022 21:14:20 +0000 (13:14 -0800)
committerH.J. Lu <hjl.tools@gmail.com>
Wed, 5 Jan 2022 21:22:31 +0000 (13:22 -0800)
Add elf_x86_allocate_local_got_info to allocate x86 GOT info for local
symbols.

* elf32-i386.c (elf_i386_check_relocs): Call
elf_x86_allocate_local_got_info.
* elf64-x86-64.c (elf_x86_64_check_relocs): Likewise.
* elfxx-x86.h (elf_x86_allocate_local_got_info): New.

bfd/elf32-i386.c
bfd/elf64-x86-64.c
bfd/elfxx-x86.h

index aa7d028313537382c4b4da96d3c384c76b7855b7..97962072ff009a58189d553452b607f14f46958b 100644 (file)
@@ -1668,25 +1668,12 @@ elf_i386_check_relocs (bfd *abfd,
              {
                bfd_signed_vma *local_got_refcounts;
 
+               if (!elf_x86_allocate_local_got_info (abfd,
+                                                     symtab_hdr->sh_info))
+                     goto error_return;
+
                /* This is a global offset table entry for a local symbol.  */
                local_got_refcounts = elf_local_got_refcounts (abfd);
-               if (local_got_refcounts == NULL)
-                 {
-                   bfd_size_type size;
-
-                   size = symtab_hdr->sh_info;
-                   size *= (sizeof (bfd_signed_vma)
-                            + sizeof (bfd_vma) + sizeof(char));
-                   local_got_refcounts = (bfd_signed_vma *)
-                       bfd_zalloc (abfd, size);
-                   if (local_got_refcounts == NULL)
-                     goto error_return;
-                   elf_local_got_refcounts (abfd) = local_got_refcounts;
-                   elf_x86_local_tlsdesc_gotent (abfd)
-                     = (bfd_vma *) (local_got_refcounts + symtab_hdr->sh_info);
-                   elf_x86_local_got_tls_type (abfd)
-                     = (char *) (local_got_refcounts + 2 * symtab_hdr->sh_info);
-                 }
                local_got_refcounts[r_symndx] = 1;
                old_tls_type = elf_x86_local_got_tls_type (abfd) [r_symndx];
              }
index 00e47bee1c69bf2547b1b2af32bfa0a6aa22421b..22aa3ee3b6824a549c5caabfc89f36be4bdd4381 100644 (file)
@@ -2066,25 +2066,12 @@ elf_x86_64_check_relocs (bfd *abfd, struct bfd_link_info *info,
              {
                bfd_signed_vma *local_got_refcounts;
 
+               if (!elf_x86_allocate_local_got_info (abfd,
+                                                     symtab_hdr->sh_info))
+                     goto error_return;
+
                /* This is a global offset table entry for a local symbol.  */
                local_got_refcounts = elf_local_got_refcounts (abfd);
-               if (local_got_refcounts == NULL)
-                 {
-                   bfd_size_type size;
-
-                   size = symtab_hdr->sh_info;
-                   size *= sizeof (bfd_signed_vma)
-                     + sizeof (bfd_vma) + sizeof (char);
-                   local_got_refcounts = ((bfd_signed_vma *)
-                                          bfd_zalloc (abfd, size));
-                   if (local_got_refcounts == NULL)
-                     goto error_return;
-                   elf_local_got_refcounts (abfd) = local_got_refcounts;
-                   elf_x86_local_tlsdesc_gotent (abfd)
-                     = (bfd_vma *) (local_got_refcounts + symtab_hdr->sh_info);
-                   elf_x86_local_got_tls_type (abfd)
-                     = (char *) (local_got_refcounts + 2 * symtab_hdr->sh_info);
-                 }
                local_got_refcounts[r_symndx] = 1;
                old_tls_type
                  = elf_x86_local_got_tls_type (abfd) [r_symndx];
index 25791af27d7acd60791ad81119dc541cd42e053b..16565a5638beeef578ee43f3736483b98db41f90 100644 (file)
@@ -789,3 +789,25 @@ elf_x86_start_stop_gc_p (struct bfd_link_info *link_info,
      --gc-sections or -z start-stop-gc isn't used.  */
   return false;
 }
+
+/* Allocate x86 GOT info for local symbols.  */
+
+static inline bool
+elf_x86_allocate_local_got_info (bfd *abfd, bfd_size_type count)
+{
+  bfd_signed_vma *local_got_refcounts = elf_local_got_refcounts (abfd);
+  if (local_got_refcounts == NULL)
+    {
+      bfd_size_type size = count * (sizeof (bfd_signed_vma)
+                                   + sizeof (bfd_vma) + sizeof(char));
+      local_got_refcounts = (bfd_signed_vma *) bfd_zalloc (abfd, size);
+      if (local_got_refcounts == NULL)
+       return false;
+      elf_local_got_refcounts (abfd) = local_got_refcounts;
+      elf_x86_local_tlsdesc_gotent (abfd) =
+       (bfd_vma *) (local_got_refcounts + count);
+      elf_x86_local_got_tls_type (abfd) =
+       (char *) (local_got_refcounts + 2 * count);
+    }
+  return true;
+}