Prevent an assertion failure in readelf & objdump when parsing corrupt DWARF information.
[external/binutils.git] / bfd / elf64-x86-64.c
index c66d286..c1237bb 100644 (file)
@@ -284,7 +284,8 @@ elf_x86_64_rtype_to_howto (bfd *abfd, unsigned r_type)
          /* xgettext:c-format */
          _bfd_error_handler (_("%pB: unsupported relocation type %#x"),
                              abfd, r_type);
-         r_type = R_X86_64_NONE;
+         bfd_set_error (bfd_error_bad_value);
+         return NULL;
        }
       i = r_type;
     }
@@ -336,19 +337,18 @@ elf_x86_64_reloc_name_lookup (bfd *abfd,
 
 /* Given an x86_64 ELF reloc type, fill in an arelent structure.  */
 
-static void
-elf_x86_64_info_to_howto (bfd *abfd ATTRIBUTE_UNUSED, arelent *cache_ptr,
+static bfd_boolean
+elf_x86_64_info_to_howto (bfd *abfd, arelent *cache_ptr,
                          Elf_Internal_Rela *dst)
 {
   unsigned r_type;
 
   r_type = ELF32_R_TYPE (dst->r_info);
-  if (r_type != (unsigned int) R_X86_64_GNU_VTINHERIT
-      && r_type != (unsigned int) R_X86_64_GNU_VTENTRY)
-    r_type &= ~R_X86_64_converted_reloc_bit;
   cache_ptr->howto = elf_x86_64_rtype_to_howto (abfd, r_type);
-
+  if (cache_ptr->howto == NULL)
+    return FALSE;
   BFD_ASSERT (r_type == cache_ptr->howto->type || cache_ptr->howto->type == R_X86_64_NONE);
+  return TRUE;
 }
 \f
 /* Support for core dump NOTE sections.  */
@@ -1311,6 +1311,9 @@ elf_x86_64_tls_transition (struct bfd_link_info *info, bfd *abfd,
       from = elf_x86_64_rtype_to_howto (abfd, from_type);
       to = elf_x86_64_rtype_to_howto (abfd, to_type);
 
+      if (from == NULL || to == NULL)
+       return FALSE;
+
       if (h)
        name = h->root.root.string;
       else
@@ -2497,6 +2500,10 @@ elf_x86_64_relocate_section (bfd *output_bfd,
 
          if ((input_section->flags & SEC_ALLOC) == 0)
            {
+             /* If this is a SHT_NOTE section without SHF_ALLOC, treat
+                STT_GNU_IFUNC symbol as STT_FUNC.  */
+             if (elf_section_type (input_section) == SHT_NOTE)
+               goto skip_ifunc;
              /* Dynamic relocs are not propagated for SEC_DEBUGGING
                 sections because such sections are not SEC_ALLOC and
                 thus ld.so will not process them.  */
@@ -2720,6 +2727,7 @@ do_ifunc_pointer:
            }
        }
 
+skip_ifunc:
       resolved_to_zero = (eh != NULL
                          && UNDEFINED_WEAK_RESOLVED_TO_ZERO (info, eh));
 
@@ -4400,15 +4408,23 @@ elf_x86_64_finish_dynamic_sections (bfd *output_bfd,
 
       if (htab->tlsdesc_plt)
        {
+         /* The TLSDESC entry in a lazy procedure linkage table.  */
+         static const bfd_byte tlsdesc_plt_entry[LAZY_PLT_ENTRY_SIZE] =
+           {
+             0xf3, 0x0f, 0x1e, 0xfa,   /* endbr64              */
+             0xff, 0x35, 8, 0, 0, 0,   /* pushq GOT+8(%rip)    */
+             0xff, 0x25, 16, 0, 0, 0   /* jmpq *GOT+TDG(%rip)  */
+           };
+
          bfd_put_64 (output_bfd, (bfd_vma) 0,
                      htab->elf.sgot->contents + htab->tlsdesc_got);
 
          memcpy (htab->elf.splt->contents + htab->tlsdesc_plt,
-                 htab->lazy_plt->plt0_entry,
-                 htab->lazy_plt->plt0_entry_size);
+                 tlsdesc_plt_entry, LAZY_PLT_ENTRY_SIZE);
 
-         /* Add offset for pushq GOT+8(%rip), since the
-            instruction uses 6 bytes subtract this value.  */
+         /* Add offset for pushq GOT+8(%rip), since ENDBR64 uses 4
+            bytes and the instruction uses 6 bytes, subtract these
+            values.  */
          bfd_put_32 (output_bfd,
                      (htab->elf.sgotplt->output_section->vma
                       + htab->elf.sgotplt->output_offset
@@ -4416,14 +4432,13 @@ elf_x86_64_finish_dynamic_sections (bfd *output_bfd,
                       - htab->elf.splt->output_section->vma
                       - htab->elf.splt->output_offset
                       - htab->tlsdesc_plt
-                      - 6),
+                      - 4 - 6),
                      (htab->elf.splt->contents
                       + htab->tlsdesc_plt
-                      + htab->lazy_plt->plt0_got1_offset));
-         /* Add offset for the PC-relative instruction accessing
-            GOT+TDG, where TDG stands for htab->tlsdesc_got,
-            subtracting the offset to the end of that
-            instruction.  */
+                      + 4 + 2));
+         /* Add offset for indirect branch via GOT+TDG, where TDG
+            stands for htab->tlsdesc_got, subtracting the offset
+            to the end of that instruction.  */
          bfd_put_32 (output_bfd,
                      (htab->elf.sgot->output_section->vma
                       + htab->elf.sgot->output_offset
@@ -4431,10 +4446,9 @@ elf_x86_64_finish_dynamic_sections (bfd *output_bfd,
                       - htab->elf.splt->output_section->vma
                       - htab->elf.splt->output_offset
                       - htab->tlsdesc_plt
-                      - htab->lazy_plt->plt0_got2_insn_end),
+                      - 4 - 6 - 6),
                      (htab->elf.splt->contents
-                      + htab->tlsdesc_plt
-                      + htab->lazy_plt->plt0_got2_offset));
+                      + htab->tlsdesc_plt + 4 + 6 + 2));
        }
     }
 
@@ -4936,7 +4950,11 @@ elf_x86_64_special_sections[]=
 #define ELF_ARCH                           bfd_arch_i386
 #define ELF_TARGET_ID                      X86_64_ELF_DATA
 #define ELF_MACHINE_CODE                   EM_X86_64
-#define ELF_MAXPAGESIZE                            0x200000
+#if DEFAULT_LD_Z_SEPARATE_CODE
+# define ELF_MAXPAGESIZE                   0x1000
+#else
+# define ELF_MAXPAGESIZE                   0x200000
+#endif
 #define ELF_MINPAGESIZE                            0x1000
 #define ELF_COMMONPAGESIZE                 0x1000
 
@@ -5002,6 +5020,9 @@ elf_x86_64_special_sections[]=
 #define elf_backend_hide_symbol \
   _bfd_x86_elf_hide_symbol
 
+#undef elf64_bed
+#define elf64_bed elf64_x86_64_bed
+
 #include "elf64-target.h"
 
 /* CloudABI support.  */
@@ -5286,6 +5307,9 @@ elf32_x86_64_nacl_elf_object_p (bfd *abfd)
 #define elf_backend_size_info \
   _bfd_elf32_size_info
 
+#undef elf32_bed
+#define        elf32_bed                       elf32_x86_64_bed
+
 #include "elf32-target.h"
 
 /* Restore defaults.  */
@@ -5329,7 +5353,11 @@ elf64_l1om_elf_object_p (bfd *abfd)
 #undef ELF_MAXPAGESIZE
 #undef ELF_MINPAGESIZE
 #undef ELF_COMMONPAGESIZE
-#define ELF_MAXPAGESIZE                        0x200000
+#if DEFAULT_LD_Z_SEPARATE_CODE
+# define ELF_MAXPAGESIZE               0x1000
+#else
+# define ELF_MAXPAGESIZE               0x200000
+#endif
 #define ELF_MINPAGESIZE                        0x1000
 #define ELF_COMMONPAGESIZE             0x1000
 #undef elf_backend_plt_alignment