rx-elf FAIL: SHF_GNU_RETAIN sections 27
[binutils-gdb.git] / bfd / reloc.c
index e01cb5182ec2a1e4d3d5675662d791b85d0fa5fa..9639ad262ae8093151723e17a8a4f4702fc07cd8 100644 (file)
@@ -1,5 +1,5 @@
 /* BFD support for handling relocation entries.
-   Copyright (C) 1990-2019 Free Software Foundation, Inc.
+   Copyright (C) 1990-2020 Free Software Foundation, Inc.
    Written by Cygnus Support.
 
    This file is part of BFD, the Binary File Descriptor library.
@@ -51,6 +51,7 @@ SECTION
 #include "bfdlink.h"
 #include "libbfd.h"
 #include "bfdver.h"
+#include "coff/internal.h"
 /*
 DOCDD
 INODE
@@ -432,8 +433,9 @@ DESCRIPTION
 .
 */
 
-/* N_ONES produces N one bits, without overflowing machine arithmetic.  */
-#define N_ONES(n) (((((bfd_vma) 1 << ((n) - 1)) - 1) << 1) | 1)
+/* N_ONES produces N one bits, without undefined behaviour for N
+   between zero and the number of bits in a bfd_vma.  */
+#define N_ONES(n) ((n) == 0 ? 0 : ((bfd_vma) 1 << ((n) - 1) << 1) - 1)
 
 /*
 FUNCTION
@@ -466,6 +468,9 @@ bfd_check_overflow (enum complain_overflow how,
   bfd_vma fieldmask, addrmask, signmask, ss, a;
   bfd_reloc_status_type flag = bfd_reloc_ok;
 
+  if (bitsize == 0)
+    return flag;
+
   /* Note: BITSIZE should always be <= ADDRSIZE, but in case it's not,
      we'll be permissive: extra bits in the field mask will
      automatically extend the address mask for purposes of the
@@ -744,14 +749,14 @@ bfd_perform_relocation (bfd *abfd,
   else
     output_base = reloc_target_output_section->vma;
 
-  /* For sections where relocations are in octets, output_base and
-     output_offset must also be converted to octets.  */
+  output_base += symbol->section->output_offset;
+
+  /* If symbol addresses are in octets, convert to bytes.  */
   if (bfd_get_flavour (abfd) == bfd_target_elf_flavour
       && (symbol->section->flags & SEC_ELF_OCTETS))
-    relocation += ((output_base + symbol->section->output_offset)
-                  * bfd_octets_per_byte (abfd, NULL));
-  else
-    relocation += output_base + symbol->section->output_offset;
+    output_base *= bfd_octets_per_byte (abfd, input_section);
+
+  relocation += output_base;
 
   /* Add in supplied addend.  */
   relocation += reloc_entry->addend;
@@ -900,6 +905,23 @@ space consuming.  For each target:
            }
        }
     }
+  else if (abfd->xvec->flavour == bfd_target_coff_flavour
+          && (input_section->output_section->owner->xvec->flavour
+              == bfd_target_elf_flavour)
+          && strcmp (abfd->xvec->name, "pe-x86-64") == 0
+          && strcmp (input_section->output_section->owner->xvec->name,
+                     "elf64-x86-64") == 0)
+    {
+      /* NB: bfd_perform_relocation isn't called to generate PE binary.
+        _bfd_relocate_contents is called instead.  When linking PE
+        object files to generate ELF output, _bfd_relocate_contents
+        isn't called and bfd_perform_relocation is used.  We need to
+        adjust relocation here.  */
+      relocation -= reloc_entry->addend;
+      if (howto->type >= R_AMD64_PCRLONG_1
+         && howto->type <= R_AMD64_PCRLONG_5)
+       relocation -= (bfd_vma)(howto->type - R_AMD64_PCRLONG);
+    }
 
   /* FIXME: This overflow checking is incomplete, because the value
      might have overflowed before we get here.  For a correct check we
@@ -1080,14 +1102,14 @@ bfd_install_relocation (bfd *abfd,
   else
     output_base = reloc_target_output_section->vma;
 
-  /* For sections where relocations are in octets, output_base and
-     output_offset must also be converted to octets.  */
+  output_base += symbol->section->output_offset;
+
+  /* If symbol addresses are in octets, convert to bytes.  */
   if (bfd_get_flavour (abfd) == bfd_target_elf_flavour
       && (symbol->section->flags & SEC_ELF_OCTETS))
-    relocation += ((output_base + symbol->section->output_offset)
-                  * bfd_octets_per_byte (abfd, NULL));
-  else
-    relocation += output_base + symbol->section->output_offset;
+    output_base *= bfd_octets_per_byte (abfd, input_section);
+
+  relocation += output_base;
 
   /* Add in supplied addend.  */
   relocation += reloc_entry->addend;
@@ -1383,10 +1405,7 @@ _bfd_final_link_relocate (reloc_howto_type *howto,
     }
 
   return _bfd_relocate_contents (howto, input_bfd, relocation,
-                                contents
-                                + address
-                                * bfd_octets_per_byte (input_bfd,
-                                                       input_section));
+                                contents + octets);
 }
 
 /* Relocate a given location using a given value and howto.  */
@@ -3028,13 +3047,13 @@ ENUMX
 ENUMX
   BFD_RELOC_PPC64_DTPREL34
 ENUMX
-  BFD_RELOC_PPC64_GOT_TLSGD34
+  BFD_RELOC_PPC64_GOT_TLSGD_PCREL34
 ENUMX
-  BFD_RELOC_PPC64_GOT_TLSLD34
+  BFD_RELOC_PPC64_GOT_TLSLD_PCREL34
 ENUMX
-  BFD_RELOC_PPC64_GOT_TPREL34
+  BFD_RELOC_PPC64_GOT_TPREL_PCREL34
 ENUMX
-  BFD_RELOC_PPC64_GOT_DTPREL34
+  BFD_RELOC_PPC64_GOT_DTPREL_PCREL34
 ENUMX
   BFD_RELOC_PPC64_TLS_PCREL
 ENUMDOC
@@ -6366,6 +6385,11 @@ ENUMX
   BFD_RELOC_MSP430_PREL31
 ENUMX
   BFD_RELOC_MSP430_SYM_DIFF
+ENUMX
+  BFD_RELOC_MSP430_SET_ULEB128
+ENUMX
+  BFD_RELOC_MSP430_SUB_ULEB128
+
 ENUMDOC
   msp430 specific relocation codes
 
@@ -6559,6 +6583,8 @@ ENUMX
 ENUMX
   BFD_RELOC_XTENSA_DIFF32
 ENUMDOC
+  Xtensa relocations for backward compatibility.  These have been replaced
+  by BFD_RELOC_XTENSA_PDIFF and BFD_RELOC_XTENSA_NDIFF.
   Xtensa relocations to mark the difference of two local symbols.
   These are only needed to support linker relaxation and can be ignored
   when not relaxing.  The field is set to the value of the difference
@@ -6671,11 +6697,61 @@ ENUMX
   BFD_RELOC_XTENSA_TLS_CALL
 ENUMDOC
   Xtensa TLS relocations.
+ENUM
+  BFD_RELOC_XTENSA_PDIFF8
+ENUMX
+  BFD_RELOC_XTENSA_PDIFF16
+ENUMX
+  BFD_RELOC_XTENSA_PDIFF32
+ENUMX
+  BFD_RELOC_XTENSA_NDIFF8
+ENUMX
+  BFD_RELOC_XTENSA_NDIFF16
+ENUMX
+  BFD_RELOC_XTENSA_NDIFF32
+ENUMDOC
+  Xtensa relocations to mark the difference of two local symbols.
+  These are only needed to support linker relaxation and can be ignored
+  when not relaxing.  The field is set to the value of the difference
+  assuming no relaxation.  The relocation encodes the position of the
+  subtracted symbol so the linker can determine whether to adjust the field
+  value.  PDIFF relocations are used for positive differences, NDIFF
+  relocations are used for negative differences.  The difference value
+  is treated as unsigned with these relocation types, giving full
+  8/16 value ranges.
 
 ENUM
   BFD_RELOC_Z80_DISP8
 ENUMDOC
   8 bit signed offset in (ix+d) or (iy+d).
+ENUM
+  BFD_RELOC_Z80_BYTE0
+ENUMDOC
+  First 8 bits of multibyte (32, 24 or 16 bit) value.
+ENUM
+  BFD_RELOC_Z80_BYTE1
+ENUMDOC
+  Second 8 bits of multibyte (32, 24 or 16 bit) value.
+ENUM
+  BFD_RELOC_Z80_BYTE2
+ENUMDOC
+  Third 8 bits of multibyte (32 or 24 bit) value.
+ENUM
+  BFD_RELOC_Z80_BYTE3
+ENUMDOC
+  Fourth 8 bits of multibyte (32 bit) value.
+ENUM
+  BFD_RELOC_Z80_WORD0
+ENUMDOC
+  Lowest 16 bits of multibyte (32 or 24 bit) value.
+ENUM
+  BFD_RELOC_Z80_WORD1
+ENUMDOC
+  Highest 16 bits of multibyte (32 or 24 bit) value.
+ENUM
+  BFD_RELOC_Z80_16_BE
+ENUMDOC
+  Like BFD_RELOC_16 but big-endian.
 
 ENUM
   BFD_RELOC_Z8K_DISP7
@@ -8449,7 +8525,7 @@ bfd_generic_get_relocated_section_contents (bfd *abfd,
   free (reloc_vector);
   return data;
 
-error_return:
+ error_return:
   free (reloc_vector);
   return NULL;
 }