Disable parts of gdb.base/source-dir.exp on remote host
[deliverable/binutils-gdb.git] / bfd / elf32-i386.c
index 9248ef5a41803b8de7b8c79869f710f7864bc3ac..6f4f7f47186ce5cef8078b44313c1d183755c2d6 100644 (file)
@@ -1,5 +1,5 @@
 /* Intel 80386/80486-specific support for 32-bit ELF
-   Copyright (C) 1993-2019 Free Software Foundation, Inc.
+   Copyright (C) 1993-2020 Free Software Foundation, Inc.
 
    This file is part of BFD, the Binary File Descriptor library.
 
@@ -843,14 +843,6 @@ static const struct elf_x86_non_lazy_plt_layout elf_i386_non_lazy_ibt_plt =
 #define PLTRESOLVE_RELOCS 2
 #define PLT_NON_JUMP_SLOT_RELOCS 2
 
-/* These are the standard parameters.  */
-static const struct elf_x86_backend_data elf_i386_arch_bed =
-  {
-    is_normal                          /* os */
-  };
-
-#define        elf_backend_arch_data   &elf_i386_arch_bed
-
 /* Return TRUE if the TLS access code sequence support transition
    from R_TYPE.  */
 
@@ -1226,6 +1218,7 @@ elf_i386_convert_load_reloc (bfd *abfd, Elf_Internal_Shdr *symtab_hdr,
   bfd_vma nop_offset;
   bfd_boolean is_pic;
   bfd_boolean to_reloc_32;
+  bfd_boolean abs_symbol;
   unsigned int r_type;
   unsigned int r_symndx;
   bfd_vma roff = irel->r_offset;
@@ -1249,6 +1242,21 @@ elf_i386_convert_load_reloc (bfd *abfd, Elf_Internal_Shdr *symtab_hdr,
   modrm = bfd_get_8 (abfd, contents + roff - 1);
   baseless = (modrm & 0xc7) == 0x5;
 
+  if (h)
+    {
+      /* NB: Also set linker_def via SYMBOL_REFERENCES_LOCAL_P.  */
+      local_ref = SYMBOL_REFERENCES_LOCAL_P (link_info, h);
+      isym = NULL;
+      abs_symbol = ABS_SYMBOL_P (h);
+    }
+  else
+    {
+      local_ref = TRUE;
+      isym = bfd_sym_from_r_symndx (&htab->sym_cache, abfd,
+                                   r_symndx);
+      abs_symbol = isym->st_shndx == SHN_ABS;
+    }
+
   if (baseless && is_pic)
     {
       /* For PIC, disallow R_386_GOT32X without a base register
@@ -1256,11 +1264,7 @@ elf_i386_convert_load_reloc (bfd *abfd, Elf_Internal_Shdr *symtab_hdr,
       const char *name;
 
       if (h == NULL)
-       {
-         isym = bfd_sym_from_r_symndx (&htab->sym_cache, abfd,
-                                       r_symndx);
-         name = bfd_elf_sym_name (abfd, symtab_hdr, isym, NULL);
-       }
+       name = bfd_elf_sym_name (abfd, symtab_hdr, isym, NULL);
       else
        name = h->root.root.string;
 
@@ -1294,9 +1298,6 @@ elf_i386_convert_load_reloc (bfd *abfd, Elf_Internal_Shdr *symtab_hdr,
        goto convert_load;
     }
 
-  /* NB: Also set linker_def via SYMBOL_REFERENCES_LOCAL_P.  */
-  local_ref = SYMBOL_REFERENCES_LOCAL_P (link_info, h);
-
   /* Undefined weak symbol is only bound locally in executable
      and its reference is resolved as 0.  */
   if (h->root.type == bfd_link_hash_undefweak
@@ -1327,7 +1328,7 @@ elf_i386_convert_load_reloc (bfd *abfd, Elf_Internal_Shdr *symtab_hdr,
          && local_ref)
        {
          /* The function is locally defined.   */
-convert_branch:
+       convert_branch:
          /* Convert R_386_GOT32X to R_386_PC32.  */
          if (modrm == 0x15 || (modrm & 0xf8) == 0x90)
            {
@@ -1393,9 +1394,12 @@ convert_branch:
               || h->root.type == bfd_link_hash_defweak)
              && local_ref))
        {
-convert_load:
+       convert_load:
          if (opcode == 0x8b)
            {
+             if (abs_symbol && local_ref)
+               to_reloc_32 = TRUE;
+
              if (to_reloc_32)
                {
                  /* Convert "mov foo@GOT[(%reg1)], %reg2" to
@@ -1475,15 +1479,6 @@ elf_i386_check_relocs (bfd *abfd,
   if (bfd_link_relocatable (info))
     return TRUE;
 
-  /* Don't do anything special with non-loaded, non-alloced sections.
-     In particular, any relocs in such sections should not affect GOT
-     and PLT reference counting (ie. we don't allow them to create GOT
-     or PLT entries), there's no possibility or desire to optimize TLS
-     relocs, and there's not much point in propagating relocs to shared
-     libs that the dynamic linker won't relocate.  */
-  if ((sec->flags & SEC_ALLOC) == 0)
-    return TRUE;
-
   htab = elf_x86_hash_table (info, I386_ELF_DATA);
   if (htab == NULL)
     {
@@ -1519,6 +1514,7 @@ elf_i386_check_relocs (bfd *abfd,
       Elf_Internal_Sym *isym;
       const char *name;
       bfd_boolean size_reloc;
+      bfd_boolean no_dynreloc;
 
       r_symndx = ELF32_R_SYM (rel->r_info);
       r_type = ELF32_R_TYPE (rel->r_info);
@@ -1587,6 +1583,10 @@ elf_i386_check_relocs (bfd *abfd,
            goto error_return;
        }
 
+      if (!_bfd_elf_x86_valid_reloc_p (sec, info, htab, rel, h, isym,
+                                      symtab_hdr, &no_dynreloc))
+       return FALSE;
+
       if (! elf_i386_tls_transition (info, abfd, sec, contents,
                                     symtab_hdr, sym_hashes,
                                     &r_type, GOT_UNKNOWN,
@@ -1739,7 +1739,7 @@ elf_i386_check_relocs (bfd *abfd,
 
        case R_386_GOTOFF:
        case R_386_GOTPC:
-create_got:
+       create_got:
          if (r_type != R_386_TLS_IE)
            {
              if (eh != NULL)
@@ -1769,7 +1769,7 @@ create_got:
        case R_386_PC32:
          if (eh != NULL && (sec->flags & SEC_CODE) != 0)
            eh->zero_undefweak |= 0x2;
-do_relocation:
+       do_relocation:
          /* We are called after all symbols have been resolved.  Only
             relocation against STT_GNU_IFUNC symbol must go through
             PLT.  */
@@ -1826,9 +1826,10 @@ do_relocation:
            }
 
          size_reloc = FALSE;
-do_size:
-         if (NEED_DYNAMIC_RELOCATION_P (info, FALSE, h, sec, r_type,
-                                        R_386_32))
+       do_size:
+         if (!no_dynreloc
+             && NEED_DYNAMIC_RELOCATION_P (info, FALSE, h, sec, r_type,
+                                           R_386_32))
            {
              struct elf_dyn_relocs *p;
              struct elf_dyn_relocs **head;
@@ -1849,7 +1850,7 @@ do_size:
                 relocations we need for this symbol.  */
              if (h != NULL)
                {
-                 head = &eh->dyn_relocs;
+                 head = &h->dyn_relocs;
                }
              else
                {
@@ -1875,7 +1876,7 @@ do_size:
              p = *head;
              if (p == NULL || p->sec != sec)
                {
-                 bfd_size_type amt = sizeof *p;
+                 size_t amt = sizeof *p;
                  p = (struct elf_dyn_relocs *) bfd_alloc (htab->elf.dynobj,
                                                           amt);
                  if (p == NULL)
@@ -1931,7 +1932,7 @@ do_size:
 
   return TRUE;
 
-error_return:
+ error_return:
   if (elf_section_data (sec)->this_hdr.contents != contents)
     free (contents);
   sec->check_relocs_failed = 1;
@@ -2034,7 +2035,7 @@ elf_i386_relocate_section (bfd *output_bfd,
   local_tlsdesc_gotents = elf_x86_local_tlsdesc_gotent (input_bfd);
   /* We have to handle relocations in vxworks .tls_vars sections
      specially, because the dynamic loader is 'weird'.  */
-  is_vxworks_tls = (htab->target_os == is_vxworks
+  is_vxworks_tls = (htab->elf.target_os == is_vxworks
                    && bfd_link_pic (info)
                    && !strcmp (input_section->output_section->name,
                                ".tls_vars"));
@@ -2362,7 +2363,7 @@ elf_i386_relocate_section (bfd *output_bfd,
          switch (r_type)
            {
            default:
-bad_ifunc_reloc:
+           bad_ifunc_reloc:
              if (h->root.root.string)
                name = h->root.root.string;
              else
@@ -2386,7 +2387,7 @@ bad_ifunc_reloc:
                  asection *sreloc;
                  bfd_vma offset;
 
-do_ifunc_pointer:
+               do_ifunc_pointer:
                  /* Need a dynamic relocation to get the real function
                     adddress.  */
                  offset = _bfd_elf_section_offset (output_bfd,
@@ -2449,7 +2450,7 @@ do_ifunc_pointer:
            }
        }
 
-skip_ifunc:
+    skip_ifunc:
       resolved_to_zero = (eh != NULL
                          && UNDEFINED_WEAK_RESOLVED_TO_ZERO (info, eh));
 
@@ -2551,7 +2552,7 @@ skip_ifunc:
                     we don't know what the GOT base is.  */
                  const char *name;
 
-disallow_got32:
+               disallow_got32:
                  if (h == NULL || h->root.root.string == NULL)
                    name = bfd_elf_sym_name (input_bfd, symtab_hdr, sym,
                                             NULL);
@@ -2704,7 +2705,7 @@ disallow_got32:
              || is_vxworks_tls)
            break;
 
-         if (GENERATE_DYNAMIC_RELOCATION_P (info, eh, r_type,
+         if (GENERATE_DYNAMIC_RELOCATION_P (info, eh, r_type, sec,
                                             FALSE, resolved_to_zero,
                                             (r_type == R_386_PC32)))
            {
@@ -3409,12 +3410,12 @@ disallow_got32:
          return FALSE;
        }
 
-do_relocation:
+    do_relocation:
       r = _bfd_final_link_relocate (howto, input_bfd, input_section,
                                    contents, rel->r_offset,
                                    relocation, 0);
 
-check_relocation_error:
+    check_relocation_error:
       if (r != bfd_reloc_ok)
        {
          const char *name;
@@ -3588,7 +3589,7 @@ elf_i386_finish_dynamic_symbol (bfd *output_bfd,
                      resolved_plt->contents + plt_offset
                      + htab->plt.plt_got_offset);
 
-         if (htab->target_os == is_vxworks)
+         if (htab->elf.target_os == is_vxworks)
            {
              int s, k, reloc_index;
 
@@ -3848,7 +3849,7 @@ elf_i386_finish_dynamic_symbol (bfd *output_bfd,
       else
        {
          BFD_ASSERT((h->got.offset & 1) == 0);
-do_glob_dat:
+       do_glob_dat:
          bfd_put_32 (output_bfd, (bfd_vma) 0,
                      htab->elf.sgot->contents + h->got.offset);
          rel.r_info = ELF32_R_INFO (h->dynindx, R_386_GLOB_DAT);
@@ -4006,7 +4007,7 @@ elf_i386_finish_dynamic_sections (bfd *output_bfd,
                          htab->elf.splt->contents
                          + htab->lazy_plt->plt0_got2_offset);
 
-             if (htab->target_os == is_vxworks)
+             if (htab->elf.target_os == is_vxworks)
                {
                  Elf_Internal_Rela rel;
                  int num_plts = (htab->elf.splt->size
@@ -4147,7 +4148,7 @@ elf_i386_get_synthetic_symtab (bfd *abfd,
   lazy_plt = NULL;
   non_lazy_ibt_plt = NULL;
   lazy_ibt_plt = NULL;
-  switch (get_elf_x86_backend_data (abfd)->target_os)
+  switch (get_elf_backend_data (abfd)->target_os)
     {
     case is_normal:
     case is_solaris:
@@ -4161,6 +4162,8 @@ elf_i386_get_synthetic_symtab (bfd *abfd,
     case is_nacl:
       lazy_plt = &elf_i386_nacl_plt;
       break;
+    default:
+      abort ();
     }
 
   got_addr = 0;
@@ -4307,7 +4310,7 @@ elf_i386_link_setup_gnu_properties (struct bfd_link_info *info)
 {
   struct elf_x86_init_table init_table;
 
-  switch (get_elf_x86_backend_data (info->output_bfd)->target_os)
+  switch (get_elf_backend_data (info->output_bfd)->target_os)
     {
     case is_normal:
     case is_solaris:
@@ -4331,6 +4334,8 @@ elf_i386_link_setup_gnu_properties (struct bfd_link_info *info)
       init_table.lazy_ibt_plt = NULL;
       init_table.non_lazy_ibt_plt = NULL;
       break;
+    default:
+      abort ();
     }
 
   init_table.r_info = elf32_r_info;
@@ -4400,10 +4405,11 @@ elf_i386_link_setup_gnu_properties (struct bfd_link_info *info)
    "FreeBSD" label in the ELF header.  So we put this label on all
    executables and (for simplicity) also all other object files.  */
 
-static void
-elf_i386_fbsd_post_process_headers (bfd *abfd, struct bfd_link_info *info)
+static bfd_boolean
+elf_i386_fbsd_init_file_header (bfd *abfd, struct bfd_link_info *info)
 {
-  _bfd_elf_post_process_headers (abfd, info);
+  if (!_bfd_elf_init_file_header (abfd, info))
+    return FALSE;
 
 #ifdef OLD_FREEBSD_ABI_LABEL
   {
@@ -4412,10 +4418,11 @@ elf_i386_fbsd_post_process_headers (bfd *abfd, struct bfd_link_info *info)
     memcpy (&i_ehdrp->e_ident[EI_ABIVERSION], "FreeBSD", 8);
   }
 #endif
+  return TRUE;
 }
 
-#undef elf_backend_post_process_headers
-#define        elf_backend_post_process_headers        elf_i386_fbsd_post_process_headers
+#undef elf_backend_init_file_header
+#define        elf_backend_init_file_header    elf_i386_fbsd_init_file_header
 #undef elf32_bed
 #define        elf32_bed                               elf32_i386_fbsd_bed
 
@@ -4423,6 +4430,8 @@ elf_i386_fbsd_post_process_headers (bfd *abfd, struct bfd_link_info *info)
 
 #include "elf32-target.h"
 
+#undef elf_backend_init_file_header
+
 /* Solaris 2.  */
 
 #undef TARGET_LITTLE_SYM
@@ -4430,15 +4439,8 @@ elf_i386_fbsd_post_process_headers (bfd *abfd, struct bfd_link_info *info)
 #undef TARGET_LITTLE_NAME
 #define        TARGET_LITTLE_NAME              "elf32-i386-sol2"
 
-static const struct elf_x86_backend_data elf_i386_solaris_arch_bed =
-  {
-    is_solaris                         /* os */
-  };
-
-#undef elf_backend_arch_data
-#define        elf_backend_arch_data           &elf_i386_solaris_arch_bed
-
-#undef elf_backend_post_process_headers
+#undef ELF_TARGET_OS
+#define        ELF_TARGET_OS                   is_solaris
 
 /* Restore default: we cannot use ELFOSABI_SOLARIS, otherwise ELFOSABI_NONE
    objects won't be recognized.  */
@@ -4564,9 +4566,7 @@ elf32_iamcu_elf_object_p (bfd *abfd)
 #undef ELF_MACHINE_CODE
 #define        ELF_MACHINE_CODE                EM_IAMCU
 
-#undef elf_backend_arch_data
-#define        elf_backend_arch_data           &elf_i386_arch_bed
-
+#undef ELF_TARGET_OS
 #undef ELF_OSABI
 
 #undef  elf32_bed
@@ -4607,7 +4607,6 @@ elf32_iamcu_elf_object_p (bfd *abfd)
 #undef ELF_OSABI
 #undef elf_backend_want_plt_sym
 #define elf_backend_want_plt_sym       0
-#undef elf_backend_post_process_headers
 #undef elf_backend_static_tls_alignment
 
 /* NaCl uses substantially different PLT entries for the same effects.  */
@@ -4694,7 +4693,7 @@ static const bfd_byte elf_i386_nacl_eh_frame_plt[] =
      || PLT_FDE_LENGTH != 36                           \
      || PLT_FDE_START_OFFSET != 4 + PLT_CIE_LENGTH + 8 \
      || PLT_FDE_LEN_OFFSET != 4 + PLT_CIE_LENGTH + 12)
-# error "Need elf_x86_backend_data parameters for eh_frame_plt offsets!"
+# error "Need PLT_CIE_LENGTH parameters for eh_frame_plt offsets!"
 #endif
     PLT_CIE_LENGTH, 0, 0, 0,           /* CIE length */
     0, 0, 0, 0,                                /* CIE ID */
@@ -4754,11 +4753,6 @@ static const struct elf_x86_lazy_plt_layout elf_i386_nacl_plt =
     sizeof (elf_i386_nacl_eh_frame_plt) /* eh_frame_plt_size */
   };
 
-static const struct elf_x86_backend_data elf_i386_nacl_arch_bed =
-  {
-    is_nacl                            /* os */
-  };
-
 static bfd_boolean
 elf32_i386_nacl_elf_object_p (bfd *abfd)
 {
@@ -4767,15 +4761,15 @@ elf32_i386_nacl_elf_object_p (bfd *abfd)
   return TRUE;
 }
 
-#undef elf_backend_arch_data
-#define elf_backend_arch_data  &elf_i386_nacl_arch_bed
+#undef ELF_TARGET_OS
+#define ELF_TARGET_OS          is_nacl
 
 #undef elf_backend_object_p
 #define elf_backend_object_p                   elf32_i386_nacl_elf_object_p
 #undef elf_backend_modify_segment_map
 #define        elf_backend_modify_segment_map          nacl_modify_segment_map
-#undef elf_backend_modify_program_headers
-#define        elf_backend_modify_program_headers      nacl_modify_program_headers
+#undef elf_backend_modify_headers
+#define        elf_backend_modify_headers              nacl_modify_headers
 #undef elf_backend_final_write_processing
 #define elf_backend_final_write_processing     nacl_final_write_processing
 
@@ -4784,7 +4778,7 @@ elf32_i386_nacl_elf_object_p (bfd *abfd)
 /* Restore defaults.  */
 #undef elf_backend_object_p
 #undef elf_backend_modify_segment_map
-#undef elf_backend_modify_program_headers
+#undef elf_backend_modify_headers
 #undef elf_backend_final_write_processing
 
 /* VxWorks support.  */
@@ -4799,13 +4793,8 @@ elf32_i386_nacl_elf_object_p (bfd *abfd)
 #undef elf_backend_plt_alignment
 #define elf_backend_plt_alignment      4
 
-static const struct elf_x86_backend_data elf_i386_vxworks_arch_bed =
-  {
-    is_vxworks                         /* os */
-  };
-
-#undef elf_backend_arch_data
-#define        elf_backend_arch_data   &elf_i386_vxworks_arch_bed
+#undef ELF_TARGET_OS
+#define ELF_TARGET_OS          is_vxworks
 
 #undef elf_backend_relocs_compatible
 #undef elf_backend_add_symbol_hook
This page took 0.0316 seconds and 4 git commands to generate.