asan: Buffer overflow in evax_bfd_print_dst
[binutils-gdb.git] / bfd / mach-o-arm.c
index 2c147403d1dbee72aa81c4c6a5bd784106898208..b3286f7107f92741f7f73f1080a3a14033f8f3c5 100644 (file)
@@ -1,5 +1,5 @@
 /* ARM Mach-O support for BFD.
-   Copyright (C) 2015-2019 Free Software Foundation, Inc.
+   Copyright (C) 2015-2022 Free Software Foundation, Inc.
 
    This file is part of BFD, the Binary File Descriptor library.
 
 #define bfd_mach_o_tgt_seg_table NULL
 #define bfd_mach_o_section_type_valid_for_tgt NULL
 
-static const bfd_target *
+static bfd_cleanup
 bfd_mach_o_arm_object_p (bfd *abfd)
 {
   return bfd_mach_o_header_p (abfd, 0, 0, BFD_MACH_O_CPU_TYPE_ARM);
 }
 
-static const bfd_target *
+static bfd_cleanup
 bfd_mach_o_arm_core_p (bfd *abfd)
 {
   return bfd_mach_o_header_p (abfd, 0,
                              BFD_MACH_O_MH_CORE, BFD_MACH_O_CPU_TYPE_ARM);
 }
 
-static bfd_boolean
+static bool
 bfd_mach_o_arm_mkobject (bfd *abfd)
 {
   bfd_mach_o_data_struct *mdata;
 
   if (!bfd_mach_o_mkobject_init (abfd))
-    return FALSE;
+    return false;
 
   mdata = bfd_mach_o_get_data (abfd);
   mdata->header.magic = BFD_MACH_O_MH_MAGIC;
@@ -66,87 +66,87 @@ bfd_mach_o_arm_mkobject (bfd *abfd)
   mdata->header.byteorder = BFD_ENDIAN_LITTLE;
   mdata->header.version = 1;
 
-  return TRUE;
+  return true;
 }
 
 static reloc_howto_type arm_howto_table[]=
 {
   /* 0 */
-  HOWTO (BFD_RELOC_32, 0, 2, 32, FALSE, 0,
+  HOWTO (BFD_RELOC_32, 0, 2, 32, false, 0,
         complain_overflow_bitfield,
         NULL, "32",
-        FALSE, 0xffffffff, 0xffffffff, FALSE),
-  HOWTO (BFD_RELOC_16, 0, 1, 16, FALSE, 0,
+        false, 0xffffffff, 0xffffffff, false),
+  HOWTO (BFD_RELOC_16, 0, 1, 16, false, 0,
         complain_overflow_bitfield,
         NULL, "16",
-        FALSE, 0xffff, 0xffff, FALSE),
-  HOWTO (BFD_RELOC_8, 0, 0, 8, FALSE, 0,
+        false, 0xffff, 0xffff, false),
+  HOWTO (BFD_RELOC_8, 0, 0, 8, false, 0,
         complain_overflow_bitfield,
         NULL, "8",
-        FALSE, 0xff, 0xff, FALSE),
-  HOWTO (BFD_RELOC_32_PCREL, 0, 2, 32, TRUE, 0,
+        false, 0xff, 0xff, false),
+  HOWTO (BFD_RELOC_32_PCREL, 0, 2, 32, true, 0,
         complain_overflow_bitfield,
         NULL, "DISP32",
-        FALSE, 0xffffffff, 0xffffffff, TRUE),
+        false, 0xffffffff, 0xffffffff, true),
   /* 4 */
-  HOWTO (BFD_RELOC_16_PCREL, 0, 1, 16, TRUE, 0,
+  HOWTO (BFD_RELOC_16_PCREL, 0, 1, 16, true, 0,
         complain_overflow_bitfield,
         NULL, "DISP16",
-        FALSE, 0xffff, 0xffff, TRUE),
-  HOWTO (BFD_RELOC_MACH_O_SECTDIFF, 0, 2, 32, FALSE, 0,
+        false, 0xffff, 0xffff, true),
+  HOWTO (BFD_RELOC_MACH_O_SECTDIFF, 0, 2, 32, false, 0,
         complain_overflow_bitfield,
         NULL, "SECTDIFF_32",
-        FALSE, 0xffffffff, 0xffffffff, FALSE),
-  HOWTO (BFD_RELOC_MACH_O_LOCAL_SECTDIFF, 0, 2, 32, FALSE, 0,
+        false, 0xffffffff, 0xffffffff, false),
+  HOWTO (BFD_RELOC_MACH_O_LOCAL_SECTDIFF, 0, 2, 32, false, 0,
         complain_overflow_bitfield,
         NULL, "LSECTDIFF_32",
-        FALSE, 0xffffffff, 0xffffffff, FALSE),
-  HOWTO (BFD_RELOC_MACH_O_PAIR, 0, 2, 32, FALSE, 0,
+        false, 0xffffffff, 0xffffffff, false),
+  HOWTO (BFD_RELOC_MACH_O_PAIR, 0, 2, 32, false, 0,
         complain_overflow_bitfield,
         NULL, "PAIR_32",
-        FALSE, 0xffffffff, 0xffffffff, FALSE),
+        false, 0xffffffff, 0xffffffff, false),
   /* 8 */
-  HOWTO (BFD_RELOC_MACH_O_SECTDIFF, 0, 1, 16, FALSE, 0,
+  HOWTO (BFD_RELOC_MACH_O_SECTDIFF, 0, 1, 16, false, 0,
         complain_overflow_bitfield,
         NULL, "SECTDIFF_16",
-        FALSE, 0xffff, 0xffff, FALSE),
-  HOWTO (BFD_RELOC_MACH_O_LOCAL_SECTDIFF, 0, 1, 16, FALSE, 0,
+        false, 0xffff, 0xffff, false),
+  HOWTO (BFD_RELOC_MACH_O_LOCAL_SECTDIFF, 0, 1, 16, false, 0,
         complain_overflow_bitfield,
         NULL, "LSECTDIFF_16",
-        FALSE, 0xffff, 0xffff, FALSE),
-  HOWTO (BFD_RELOC_MACH_O_PAIR, 0, 1, 16, FALSE, 0,
+        false, 0xffff, 0xffff, false),
+  HOWTO (BFD_RELOC_MACH_O_PAIR, 0, 1, 16, false, 0,
         complain_overflow_bitfield,
         NULL, "PAIR_16",
-        FALSE, 0xffff, 0xffff, FALSE),
-  HOWTO (BFD_RELOC_ARM_PCREL_CALL, 2, 2, 24, TRUE, 0,
+        false, 0xffff, 0xffff, false),
+  HOWTO (BFD_RELOC_ARM_PCREL_CALL, 2, 2, 24, true, 0,
         complain_overflow_signed,
         NULL, "BR24",
-        FALSE, 0x00ffffff, 0x00ffffff, TRUE),
+        false, 0x00ffffff, 0x00ffffff, true),
   /* 12 */
-  HOWTO (BFD_RELOC_ARM_MOVW, 0,        2, 16, FALSE, 0,
+  HOWTO (BFD_RELOC_ARM_MOVW, 0,        2, 16, false, 0,
         complain_overflow_dont,
         NULL, "MOVW",
-        FALSE, 0x000f0fff, 0x000f0fff, FALSE),
-  HOWTO (BFD_RELOC_MACH_O_PAIR, 0, 2, 16, FALSE, 0,
+        false, 0x000f0fff, 0x000f0fff, false),
+  HOWTO (BFD_RELOC_MACH_O_PAIR, 0, 2, 16, false, 0,
         complain_overflow_bitfield,
         NULL, "PAIR_W",
-        FALSE, 0x000f0fff, 0x000f0fff, FALSE),
-  HOWTO (BFD_RELOC_ARM_MOVT, 0, 2, 16, FALSE, 0,
+        false, 0x000f0fff, 0x000f0fff, false),
+  HOWTO (BFD_RELOC_ARM_MOVT, 0, 2, 16, false, 0,
         complain_overflow_bitfield,
         NULL, "MOVT",
-        FALSE, 0x000f0fff, 0x000f0fff, FALSE),
-  HOWTO (BFD_RELOC_MACH_O_PAIR, 0, 2, 16, FALSE, 0,
+        false, 0x000f0fff, 0x000f0fff, false),
+  HOWTO (BFD_RELOC_MACH_O_PAIR, 0, 2, 16, false, 0,
         complain_overflow_bitfield,
         NULL, "PAIR_T",
-        FALSE, 0x000f0fff, 0x000f0fff, FALSE),
+        false, 0x000f0fff, 0x000f0fff, false),
   /* 16 */
-  HOWTO (BFD_RELOC_THUMB_PCREL_BLX, 2, 2, 24, TRUE, 0,
+  HOWTO (BFD_RELOC_THUMB_PCREL_BLX, 2, 2, 24, true, 0,
         complain_overflow_signed,
         NULL, "TBR22",
-        FALSE, 0x07ff2fff, 0x07ff2fff, TRUE)
+        false, 0x07ff2fff, 0x07ff2fff, true)
 };
 
-static bfd_boolean
+static bool
 bfd_mach_o_arm_canonicalize_one_reloc (bfd *       abfd,
                                       struct mach_o_reloc_info_external * raw,
                                       arelent *   res,
@@ -156,7 +156,7 @@ bfd_mach_o_arm_canonicalize_one_reloc (bfd *       abfd,
   bfd_mach_o_reloc_info reloc;
 
   if (!bfd_mach_o_pre_canonicalize_one_reloc (abfd, raw, &reloc, res, syms))
-    return FALSE;
+    return false;
 
   if (reloc.r_scattered)
     {
@@ -165,58 +165,72 @@ bfd_mach_o_arm_canonicalize_one_reloc (bfd *       abfd,
        case BFD_MACH_O_ARM_RELOC_PAIR:
          /* PR 21813: Check for a corrupt PAIR reloc at the start.  */
          if (res == res_base)
-           return FALSE;
+           {
+             _bfd_error_handler (_("malformed mach-o ARM reloc pair: "
+                                   "reloc is first reloc"));
+             return false;
+           }
          if (reloc.r_length == 2)
            {
              res->howto = &arm_howto_table[7];
              res->address = res[-1].address;
-             return TRUE;
+             return true;
            }
          else if (reloc.r_length == 1)
            {
              res->howto = &arm_howto_table[10];
              res->address = res[-1].address;
-             return TRUE;
+             return true;
            }
-         return FALSE;
+         _bfd_error_handler (_("malformed mach-o ARM reloc pair: "
+                               "invalid length: %d"), reloc.r_length);
+         return false;
 
        case BFD_MACH_O_ARM_RELOC_SECTDIFF:
          if (reloc.r_length == 2)
            {
              res->howto = &arm_howto_table[5];
-             return TRUE;
+             return true;
            }
          else if (reloc.r_length == 1)
            {
              res->howto = &arm_howto_table[8];
-             return TRUE;
+             return true;
            }
-         return FALSE;
+         _bfd_error_handler (_("malformed mach-o ARM sectdiff reloc: "
+                               "invalid length: %d"), reloc.r_length);
+         return false;
 
        case BFD_MACH_O_ARM_RELOC_LOCAL_SECTDIFF:
          if (reloc.r_length == 2)
            {
              res->howto = &arm_howto_table[6];
-             return TRUE;
+             return true;
            }
          else if (reloc.r_length == 1)
            {
              res->howto = &arm_howto_table[9];
-             return TRUE;
+             return true;
            }
-         return FALSE;
+         _bfd_error_handler (_("malformed mach-o ARM local sectdiff reloc: "
+                               "invalid length: %d"),
+                             reloc.r_length);
+         return false;
 
        case BFD_MACH_O_ARM_RELOC_HALF_SECTDIFF:
          switch (reloc.r_length)
            {
            case 2: /* :lower16: for movw arm.  */
              res->howto = &arm_howto_table[12];
-             return TRUE;
+             return true;
            case 3: /* :upper16: for movt arm.  */
              res->howto = &arm_howto_table[14];
-             return TRUE;
+             return true;
            }
-         return FALSE;
+         _bfd_error_handler (_("malformed mach-o ARM half sectdiff reloc: "
+                               "invalid length: %d"),
+                             reloc.r_length);
+         return false;
 
        default:
          break;
@@ -231,21 +245,24 @@ bfd_mach_o_arm_canonicalize_one_reloc (bfd *       abfd,
            {
            case 0: /* len = 0, pcrel = 0  */
              res->howto = &arm_howto_table[2];
-             return TRUE;
+             return true;
            case 2: /* len = 1, pcrel = 0  */
              res->howto = &arm_howto_table[1];
-             return TRUE;
+             return true;
            case 3: /* len = 1, pcrel = 1  */
              res->howto = &arm_howto_table[4];
-             return TRUE;
+             return true;
            case 4: /* len = 2, pcrel = 0  */
              res->howto = &arm_howto_table[0];
-             return TRUE;
+             return true;
            case 5: /* len = 2, pcrel = 1  */
              res->howto = &arm_howto_table[3];
-             return TRUE;
+             return true;
            default:
-             return FALSE;
+             _bfd_error_handler (_("malformed mach-o ARM vanilla reloc: "
+                                   "invalid length: %d (pcrel: %d)"),
+                                 reloc.r_length, reloc.r_pcrel);
+             return false;
            }
          break;
 
@@ -253,7 +270,7 @@ bfd_mach_o_arm_canonicalize_one_reloc (bfd *       abfd,
          if (reloc.r_length == 2 && reloc.r_pcrel == 1)
            {
              res->howto = &arm_howto_table[11];
-             return TRUE;
+             return true;
            }
          break;
 
@@ -261,7 +278,7 @@ bfd_mach_o_arm_canonicalize_one_reloc (bfd *       abfd,
          if (reloc.r_length == 2 && reloc.r_pcrel == 1)
            {
              res->howto = &arm_howto_table[16];
-             return TRUE;
+             return true;
            }
          break;
 
@@ -271,14 +288,20 @@ bfd_mach_o_arm_canonicalize_one_reloc (bfd *       abfd,
              {
              case 0: /* :lower16: for movw arm.  */
                res->howto = &arm_howto_table[12];
-               return TRUE;
+               return true;
              case 1: /* :upper16: for movt arm.  */
                res->howto = &arm_howto_table[14];
-               return TRUE;
+               return true;
              }
          break;
 
        case BFD_MACH_O_ARM_RELOC_PAIR:
+         if (res == res_base)
+           {
+             _bfd_error_handler (_("malformed mach-o ARM reloc pair: "
+                                   "reloc is first reloc"));
+             return false;
+           }
          if (res[-1].howto == &arm_howto_table[12]
              && reloc.r_length == 0)
            {
@@ -287,7 +310,7 @@ bfd_mach_o_arm_canonicalize_one_reloc (bfd *       abfd,
              /* This reloc contains the other half in its r_address field.  */
              res[-1].addend += (res->address & 0xffff) << 16;
              res->address = res[-1].address;
-             return TRUE;
+             return true;
            }
          else if (res[-1].howto == &arm_howto_table[14]
                   && reloc.r_length == 1)
@@ -297,7 +320,7 @@ bfd_mach_o_arm_canonicalize_one_reloc (bfd *       abfd,
              /* This reloc contains the other half in its r_address field.  */
              res[-1].addend += res->address & 0xffff;
              res->address = res[-1].address;
-             return TRUE;
+             return true;
            }
          break;
 
@@ -306,7 +329,9 @@ bfd_mach_o_arm_canonicalize_one_reloc (bfd *       abfd,
        }
     }
 
-  return FALSE;
+  _bfd_error_handler (_("malformed mach-o ARM reloc: "
+                       "unknown reloc type: %d"), reloc.r_length);
+  return false;
 }
 
 static reloc_howto_type *