[BACK]Return to mach-o-arm.c CVS log [TXT][DIR] Up to [cvs.NetBSD.org] / src / external / gpl3 / binutils.old / dist / bfd

Annotation of src/external/gpl3/binutils.old/dist/bfd/mach-o-arm.c, Revision 1.1.1.1.4.1

1.1       christos    1: /* ARM Mach-O support for BFD.
1.1.1.1.4.1! martin      2:    Copyright (C) 2015-2018 Free Software Foundation, Inc.
1.1       christos    3:
                      4:    This file is part of BFD, the Binary File Descriptor library.
                      5:
                      6:    This program is free software; you can redistribute it and/or modify
                      7:    it under the terms of the GNU General Public License as published by
                      8:    the Free Software Foundation; either version 3 of the License, or
                      9:    (at your option) any later version.
                     10:
                     11:    This program is distributed in the hope that it will be useful,
                     12:    but WITHOUT ANY WARRANTY; without even the implied warranty of
                     13:    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
                     14:    GNU General Public License for more details.
                     15:
                     16:    You should have received a copy of the GNU General Public License
                     17:    along with this program; if not, write to the Free Software
                     18:    Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
                     19:    MA 02110-1301, USA.  */
                     20:
                     21: #include "sysdep.h"
                     22: #include "mach-o.h"
                     23: #include "bfd.h"
                     24: #include "libbfd.h"
                     25: #include "libiberty.h"
                     26: #include "mach-o/arm.h"
                     27:
                     28: #define bfd_mach_o_object_p bfd_mach_o_arm_object_p
                     29: #define bfd_mach_o_core_p bfd_mach_o_arm_core_p
                     30: #define bfd_mach_o_mkobject bfd_mach_o_arm_mkobject
                     31:
                     32: #define bfd_mach_o_canonicalize_one_reloc bfd_mach_o_arm_canonicalize_one_reloc
1.1.1.1.4.1! martin     33: #define bfd_mach_o_swap_reloc_out  NULL
1.1       christos   34: #define bfd_mach_o_bfd_reloc_type_lookup bfd_mach_o_arm_bfd_reloc_type_lookup
                     35: #define bfd_mach_o_bfd_reloc_name_lookup bfd_mach_o_arm_bfd_reloc_name_lookup
                     36:
                     37: #define bfd_mach_o_print_thread NULL
                     38: #define bfd_mach_o_tgt_seg_table NULL
                     39: #define bfd_mach_o_section_type_valid_for_tgt NULL
                     40:
                     41: static const bfd_target *
                     42: bfd_mach_o_arm_object_p (bfd *abfd)
                     43: {
                     44:   return bfd_mach_o_header_p (abfd, 0, 0, BFD_MACH_O_CPU_TYPE_ARM);
                     45: }
                     46:
                     47: static const bfd_target *
                     48: bfd_mach_o_arm_core_p (bfd *abfd)
                     49: {
                     50:   return bfd_mach_o_header_p (abfd, 0,
1.1.1.1.4.1! martin     51:                              BFD_MACH_O_MH_CORE, BFD_MACH_O_CPU_TYPE_ARM);
1.1       christos   52: }
                     53:
                     54: static bfd_boolean
                     55: bfd_mach_o_arm_mkobject (bfd *abfd)
                     56: {
                     57:   bfd_mach_o_data_struct *mdata;
                     58:
                     59:   if (!bfd_mach_o_mkobject_init (abfd))
                     60:     return FALSE;
                     61:
                     62:   mdata = bfd_mach_o_get_data (abfd);
                     63:   mdata->header.magic = BFD_MACH_O_MH_MAGIC;
                     64:   mdata->header.cputype = BFD_MACH_O_CPU_TYPE_ARM;
                     65:   mdata->header.cpusubtype = BFD_MACH_O_CPU_SUBTYPE_ARM_ALL;
                     66:   mdata->header.byteorder = BFD_ENDIAN_LITTLE;
                     67:   mdata->header.version = 1;
                     68:
                     69:   return TRUE;
                     70: }
                     71:
                     72: static reloc_howto_type arm_howto_table[]=
                     73: {
                     74:   /* 0 */
                     75:   HOWTO (BFD_RELOC_32, 0, 2, 32, FALSE, 0,
                     76:         complain_overflow_bitfield,
                     77:         NULL, "32",
                     78:         FALSE, 0xffffffff, 0xffffffff, FALSE),
                     79:   HOWTO (BFD_RELOC_16, 0, 1, 16, FALSE, 0,
                     80:         complain_overflow_bitfield,
                     81:         NULL, "16",
                     82:         FALSE, 0xffff, 0xffff, FALSE),
                     83:   HOWTO (BFD_RELOC_8, 0, 0, 8, FALSE, 0,
                     84:         complain_overflow_bitfield,
                     85:         NULL, "8",
                     86:         FALSE, 0xff, 0xff, FALSE),
                     87:   HOWTO (BFD_RELOC_32_PCREL, 0, 2, 32, TRUE, 0,
                     88:         complain_overflow_bitfield,
                     89:         NULL, "DISP32",
                     90:         FALSE, 0xffffffff, 0xffffffff, TRUE),
                     91:   /* 4 */
                     92:   HOWTO (BFD_RELOC_16_PCREL, 0, 1, 16, TRUE, 0,
                     93:         complain_overflow_bitfield,
                     94:         NULL, "DISP16",
                     95:         FALSE, 0xffff, 0xffff, TRUE),
                     96:   HOWTO (BFD_RELOC_MACH_O_SECTDIFF, 0, 2, 32, FALSE, 0,
                     97:         complain_overflow_bitfield,
                     98:         NULL, "SECTDIFF_32",
                     99:         FALSE, 0xffffffff, 0xffffffff, FALSE),
                    100:   HOWTO (BFD_RELOC_MACH_O_LOCAL_SECTDIFF, 0, 2, 32, FALSE, 0,
                    101:         complain_overflow_bitfield,
                    102:         NULL, "LSECTDIFF_32",
                    103:         FALSE, 0xffffffff, 0xffffffff, FALSE),
                    104:   HOWTO (BFD_RELOC_MACH_O_PAIR, 0, 2, 32, FALSE, 0,
                    105:         complain_overflow_bitfield,
                    106:         NULL, "PAIR_32",
                    107:         FALSE, 0xffffffff, 0xffffffff, FALSE),
                    108:   /* 8 */
                    109:   HOWTO (BFD_RELOC_MACH_O_SECTDIFF, 0, 1, 16, FALSE, 0,
                    110:         complain_overflow_bitfield,
                    111:         NULL, "SECTDIFF_16",
                    112:         FALSE, 0xffff, 0xffff, FALSE),
                    113:   HOWTO (BFD_RELOC_MACH_O_LOCAL_SECTDIFF, 0, 1, 16, FALSE, 0,
                    114:         complain_overflow_bitfield,
                    115:         NULL, "LSECTDIFF_16",
                    116:         FALSE, 0xffff, 0xffff, FALSE),
                    117:   HOWTO (BFD_RELOC_MACH_O_PAIR, 0, 1, 16, FALSE, 0,
                    118:         complain_overflow_bitfield,
                    119:         NULL, "PAIR_16",
                    120:         FALSE, 0xffff, 0xffff, FALSE),
                    121:   HOWTO (BFD_RELOC_ARM_PCREL_CALL, 2, 2, 24, TRUE, 0,
                    122:         complain_overflow_signed,
                    123:         NULL, "BR24",
                    124:         FALSE, 0x00ffffff, 0x00ffffff, TRUE),
                    125:   /* 12 */
                    126:   HOWTO (BFD_RELOC_ARM_MOVW, 0,        2, 16, FALSE, 0,
                    127:         complain_overflow_dont,
                    128:         NULL, "MOVW",
                    129:         FALSE, 0x000f0fff, 0x000f0fff, FALSE),
                    130:   HOWTO (BFD_RELOC_MACH_O_PAIR, 0, 2, 16, FALSE, 0,
                    131:         complain_overflow_bitfield,
                    132:         NULL, "PAIR_W",
                    133:         FALSE, 0x000f0fff, 0x000f0fff, FALSE),
                    134:   HOWTO (BFD_RELOC_ARM_MOVT, 0, 2, 16, FALSE, 0,
                    135:         complain_overflow_bitfield,
                    136:         NULL, "MOVT",
                    137:         FALSE, 0x000f0fff, 0x000f0fff, FALSE),
                    138:   HOWTO (BFD_RELOC_MACH_O_PAIR, 0, 2, 16, FALSE, 0,
                    139:         complain_overflow_bitfield,
                    140:         NULL, "PAIR_T",
                    141:         FALSE, 0x000f0fff, 0x000f0fff, FALSE),
                    142:   /* 16 */
                    143:   HOWTO (BFD_RELOC_THUMB_PCREL_BLX, 2, 2, 24, TRUE, 0,
                    144:         complain_overflow_signed,
                    145:         NULL, "TBR22",
                    146:         FALSE, 0x07ff2fff, 0x07ff2fff, TRUE)
                    147: };
                    148:
                    149: static bfd_boolean
1.1.1.1.4.1! martin    150: bfd_mach_o_arm_canonicalize_one_reloc (bfd *       abfd,
        !           151:                                       struct mach_o_reloc_info_external * raw,
        !           152:                                       arelent *   res,
        !           153:                                       asymbol **  syms,
        !           154:                                       arelent *   res_base)
        !           155: {
1.1       christos  156:   bfd_mach_o_reloc_info reloc;
                    157:
                    158:   if (!bfd_mach_o_pre_canonicalize_one_reloc (abfd, raw, &reloc, res, syms))
                    159:     return FALSE;
                    160:
                    161:   if (reloc.r_scattered)
                    162:     {
                    163:       switch (reloc.r_type)
1.1.1.1.4.1! martin    164:        {
        !           165:        case BFD_MACH_O_ARM_RELOC_PAIR:
        !           166:          /* PR 21813: Check for a corrupt PAIR reloc at the start.  */
        !           167:          if (res == res_base)
        !           168:            return FALSE;
        !           169:          if (reloc.r_length == 2)
        !           170:            {
1.1       christos  171:              res->howto = &arm_howto_table[7];
                    172:              res->address = res[-1].address;
                    173:              return TRUE;
1.1.1.1.4.1! martin    174:            }
        !           175:          else if (reloc.r_length == 1)
1.1       christos  176:            {
                    177:              res->howto = &arm_howto_table[10];
                    178:              res->address = res[-1].address;
                    179:              return TRUE;
                    180:            }
1.1.1.1.4.1! martin    181:          return FALSE;
        !           182:
        !           183:        case BFD_MACH_O_ARM_RELOC_SECTDIFF:
        !           184:          if (reloc.r_length == 2)
        !           185:            {
1.1       christos  186:              res->howto = &arm_howto_table[5];
                    187:              return TRUE;
1.1.1.1.4.1! martin    188:            }
        !           189:          else if (reloc.r_length == 1)
        !           190:            {
1.1       christos  191:              res->howto = &arm_howto_table[8];
                    192:              return TRUE;
1.1.1.1.4.1! martin    193:            }
        !           194:          return FALSE;
        !           195:
        !           196:        case BFD_MACH_O_ARM_RELOC_LOCAL_SECTDIFF:
        !           197:          if (reloc.r_length == 2)
        !           198:            {
1.1       christos  199:              res->howto = &arm_howto_table[6];
                    200:              return TRUE;
1.1.1.1.4.1! martin    201:            }
        !           202:          else if (reloc.r_length == 1)
        !           203:            {
1.1       christos  204:              res->howto = &arm_howto_table[9];
                    205:              return TRUE;
1.1.1.1.4.1! martin    206:            }
        !           207:          return FALSE;
        !           208:
1.1       christos  209:        case BFD_MACH_O_ARM_RELOC_HALF_SECTDIFF:
                    210:          switch (reloc.r_length)
                    211:            {
                    212:            case 2: /* :lower16: for movw arm.  */
                    213:              res->howto = &arm_howto_table[12];
                    214:              return TRUE;
                    215:            case 3: /* :upper16: for movt arm.  */
                    216:              res->howto = &arm_howto_table[14];
                    217:              return TRUE;
                    218:            }
                    219:          return FALSE;
1.1.1.1.4.1! martin    220:
        !           221:        default:
        !           222:          break;
        !           223:        }
1.1       christos  224:     }
                    225:   else
                    226:     {
                    227:       switch (reloc.r_type)
1.1.1.1.4.1! martin    228:        {
        !           229:        case BFD_MACH_O_ARM_RELOC_VANILLA:
        !           230:          switch ((reloc.r_length << 1) | reloc.r_pcrel)
        !           231:            {
        !           232:            case 0: /* len = 0, pcrel = 0  */
        !           233:              res->howto = &arm_howto_table[2];
        !           234:              return TRUE;
        !           235:            case 2: /* len = 1, pcrel = 0  */
        !           236:              res->howto = &arm_howto_table[1];
        !           237:              return TRUE;
        !           238:            case 3: /* len = 1, pcrel = 1  */
        !           239:              res->howto = &arm_howto_table[4];
        !           240:              return TRUE;
        !           241:            case 4: /* len = 2, pcrel = 0  */
        !           242:              res->howto = &arm_howto_table[0];
        !           243:              return TRUE;
        !           244:            case 5: /* len = 2, pcrel = 1  */
        !           245:              res->howto = &arm_howto_table[3];
        !           246:              return TRUE;
        !           247:            default:
        !           248:              return FALSE;
        !           249:            }
        !           250:          break;
        !           251:
        !           252:        case BFD_MACH_O_ARM_RELOC_BR24:
1.1       christos  253:          if (reloc.r_length == 2 && reloc.r_pcrel == 1)
                    254:            {
1.1.1.1.4.1! martin    255:              res->howto = &arm_howto_table[11];
        !           256:              return TRUE;
1.1       christos  257:            }
                    258:          break;
1.1.1.1.4.1! martin    259:
        !           260:        case BFD_MACH_O_THUMB_RELOC_BR22:
1.1       christos  261:          if (reloc.r_length == 2 && reloc.r_pcrel == 1)
                    262:            {
1.1.1.1.4.1! martin    263:              res->howto = &arm_howto_table[16];
        !           264:              return TRUE;
1.1       christos  265:            }
                    266:          break;
1.1.1.1.4.1! martin    267:
        !           268:        case BFD_MACH_O_ARM_RELOC_HALF:
1.1       christos  269:          if (reloc.r_pcrel == 0)
                    270:            switch (reloc.r_length)
                    271:              {
                    272:              case 0: /* :lower16: for movw arm.  */
                    273:                res->howto = &arm_howto_table[12];
                    274:                return TRUE;
                    275:              case 1: /* :upper16: for movt arm.  */
                    276:                res->howto = &arm_howto_table[14];
                    277:                return TRUE;
                    278:              }
1.1.1.1.4.1! martin    279:          break;
        !           280:
        !           281:        case BFD_MACH_O_ARM_RELOC_PAIR:
1.1       christos  282:          if (res[-1].howto == &arm_howto_table[12]
                    283:              && reloc.r_length == 0)
                    284:            {
                    285:              /* Pair for :lower16: of movw arm.  */
                    286:              res->howto = &arm_howto_table[13];
                    287:              /* This reloc contains the other half in its r_address field.  */
                    288:              res[-1].addend += (res->address & 0xffff) << 16;
                    289:              res->address = res[-1].address;
                    290:              return TRUE;
1.1.1.1.4.1! martin    291:            }
1.1       christos  292:          else if (res[-1].howto == &arm_howto_table[14]
                    293:                   && reloc.r_length == 1)
                    294:            {
                    295:              /* Pair for :upper16: of movt arm.  */
                    296:              res->howto = &arm_howto_table[15];
                    297:              /* This reloc contains the other half in its r_address field.  */
                    298:              res[-1].addend += res->address & 0xffff;
                    299:              res->address = res[-1].address;
                    300:              return TRUE;
1.1.1.1.4.1! martin    301:            }
        !           302:          break;
        !           303:
        !           304:        default:
        !           305:          break;
        !           306:        }
1.1       christos  307:     }
1.1.1.1.4.1! martin    308:
        !           309:   return FALSE;
1.1       christos  310: }
                    311:
                    312: static reloc_howto_type *
                    313: bfd_mach_o_arm_bfd_reloc_type_lookup (bfd *abfd ATTRIBUTE_UNUSED,
                    314:                                      bfd_reloc_code_real_type code)
                    315: {
                    316:   unsigned int i;
                    317:
                    318:   for (i = 0; i < sizeof (arm_howto_table) / sizeof (*arm_howto_table); i++)
                    319:     if (code == arm_howto_table[i].type)
                    320:       return &arm_howto_table[i];
                    321:   return NULL;
                    322: }
                    323:
                    324: static reloc_howto_type *
                    325: bfd_mach_o_arm_bfd_reloc_name_lookup (bfd *abfd ATTRIBUTE_UNUSED,
                    326:                                      const char *name ATTRIBUTE_UNUSED)
                    327: {
                    328:   return NULL;
                    329: }
                    330:
1.1.1.1.4.1! martin    331: #define TARGET_NAME            arm_mach_o_vec
        !           332: #define TARGET_STRING          "mach-o-arm"
1.1       christos  333: #define TARGET_ARCHITECTURE    bfd_arch_arm
                    334: #define TARGET_PAGESIZE                4096
1.1.1.1.4.1! martin    335: #define TARGET_BIG_ENDIAN      0
        !           336: #define TARGET_ARCHIVE         0
1.1       christos  337: #define TARGET_PRIORITY                0
                    338: #include "mach-o-target.c"

CVSweb <webmaster@jp.NetBSD.org>