diff options
author | Tristan Gingold <gingold@adacore.com> | 2015-11-20 11:33:33 +0100 |
---|---|---|
committer | Tristan Gingold <gingold@adacore.com> | 2015-11-20 14:53:06 +0100 |
commit | f075eb5e6b0dd850304f78cf4d5c94df7b44c7a3 (patch) | |
tree | 2bb81dc6550084bc89b41de86543f36d2ad1c450 /bfd/mach-o-arm.c | |
parent | 11b8aeb88174dd67ff8b7c58377e8ef94ccf274e (diff) | |
download | fsf-binutils-gdb-f075eb5e6b0dd850304f78cf4d5c94df7b44c7a3.zip fsf-binutils-gdb-f075eb5e6b0dd850304f78cf4d5c94df7b44c7a3.tar.gz fsf-binutils-gdb-f075eb5e6b0dd850304f78cf4d5c94df7b44c7a3.tar.bz2 |
binutils: add support for arm-*-darwin and aarch64-*-darwin.
Currently only in bfd and binutils.
ChangeLog/
* configure.ac: Add aarch64-*-darwin* and arm-*-darwin*.
* configure: Regenerate.
bfd/ChangeLog/
* targets.c (aarch64_mach_o_vec, arm_mach_o_vec): Declare.
(_bfd_target_vector): Add new vectors.
* reloc.c (BFD_RELOC_MACH_O_SUBTRACTOR32)
(BFD_RELOC_MACH_O_SUBTRACTOR64, BFD_RELOC_MACH_O_ARM64_ADDEND)
(BFD_RELOC_MACH_O_ARM64_GOT_LOAD_PAGE21)
(BFD_RELOC_MACH_O_ARM64_GOT_LOAD_PAGEOFF12)
(BFD_RELOC_MACH_O_ARM64_POINTER_TO_GOT): New relocations.
(BFD_RELOC_MACH_O_X86_64_SUBTRACTOR32)
(BFD_RELOC_MACH_O_X86_64_SUBTRACTOR64): Remove.
* mach-o-x86-64.c (bfd_mach_o_x86_64_swap_reloc_out): Change
name of subtractor relocations.
* config.bfd: Handle aarch64-*-darwin*, arm-*-darwin*.
* Makefile.am (BFD32_BACKENDS): Add mach-o-arm.lo.
(BFD32_BACKENDS_CFILES): Add mach-o-arm.c.
(BFD64_BACKENDS): Add mach-o-aarch64.lo.
(BFD64_BACKENDS_CFILES): Add mach-o-aarch64.c.
* configure.ac: Handle aarch64_mach_o_vec and arm_mach_o_vec.
* mach-o-aarch64.c: New file.
* mach-o-arm.c: New file.
* Makefile.in: Regenerate.
* bfd-in2.h: Regenerate.
* configure: Regenerate.
* libbfd.h: Regenerate.
Diffstat (limited to 'bfd/mach-o-arm.c')
-rw-r--r-- | bfd/mach-o-arm.c | 326 |
1 files changed, 326 insertions, 0 deletions
diff --git a/bfd/mach-o-arm.c b/bfd/mach-o-arm.c new file mode 100644 index 0000000..b7c14df --- /dev/null +++ b/bfd/mach-o-arm.c @@ -0,0 +1,326 @@ +/* ARM Mach-O support for BFD. + Copyright (C) 2015 Free Software Foundation, Inc. + + This file is part of BFD, the Binary File Descriptor library. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, + MA 02110-1301, USA. */ + +#include "sysdep.h" +#include "mach-o.h" +#include "bfd.h" +#include "libbfd.h" +#include "libiberty.h" +#include "mach-o/arm.h" + +#define bfd_mach_o_object_p bfd_mach_o_arm_object_p +#define bfd_mach_o_core_p bfd_mach_o_arm_core_p +#define bfd_mach_o_mkobject bfd_mach_o_arm_mkobject + +#define bfd_mach_o_canonicalize_one_reloc bfd_mach_o_arm_canonicalize_one_reloc +#define bfd_mach_o_swap_reloc_out NULL +#define bfd_mach_o_bfd_reloc_type_lookup bfd_mach_o_arm_bfd_reloc_type_lookup +#define bfd_mach_o_bfd_reloc_name_lookup bfd_mach_o_arm_bfd_reloc_name_lookup + +#define bfd_mach_o_print_thread NULL +#define bfd_mach_o_tgt_seg_table NULL +#define bfd_mach_o_section_type_valid_for_tgt NULL + +static const bfd_target * +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 * +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 +bfd_mach_o_arm_mkobject (bfd *abfd) +{ + bfd_mach_o_data_struct *mdata; + + if (!bfd_mach_o_mkobject_init (abfd)) + return FALSE; + + mdata = bfd_mach_o_get_data (abfd); + mdata->header.magic = BFD_MACH_O_MH_MAGIC; + mdata->header.cputype = BFD_MACH_O_CPU_TYPE_ARM; + mdata->header.cpusubtype = BFD_MACH_O_CPU_SUBTYPE_ARM_ALL; + mdata->header.byteorder = BFD_ENDIAN_LITTLE; + mdata->header.version = 1; + + return TRUE; +} + +static reloc_howto_type arm_howto_table[]= +{ + /* 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, + complain_overflow_bitfield, + NULL, "16", + 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, + complain_overflow_bitfield, + NULL, "DISP32", + FALSE, 0xffffffff, 0xffffffff, TRUE), + /* 4 */ + 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, + complain_overflow_bitfield, + NULL, "SECTDIFF_32", + 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, + complain_overflow_bitfield, + NULL, "PAIR_32", + FALSE, 0xffffffff, 0xffffffff, FALSE), + /* 8 */ + 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, + complain_overflow_bitfield, + NULL, "LSECTDIFF_16", + 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, + complain_overflow_signed, + NULL, "BR24", + FALSE, 0x00ffffff, 0x00ffffff, TRUE), + /* 12 */ + 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, + complain_overflow_bitfield, + NULL, "PAIR_W", + 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, + complain_overflow_bitfield, + NULL, "PAIR_T", + FALSE, 0x000f0fff, 0x000f0fff, FALSE), + /* 16 */ + HOWTO (BFD_RELOC_THUMB_PCREL_BLX, 2, 2, 24, TRUE, 0, + complain_overflow_signed, + NULL, "TBR22", + FALSE, 0x07ff2fff, 0x07ff2fff, TRUE) +}; + +static bfd_boolean +bfd_mach_o_arm_canonicalize_one_reloc (bfd *abfd, + struct mach_o_reloc_info_external *raw, + arelent *res, asymbol **syms) + { + bfd_mach_o_reloc_info reloc; + + if (!bfd_mach_o_pre_canonicalize_one_reloc (abfd, raw, &reloc, res, syms)) + return FALSE; + + if (reloc.r_scattered) + { + switch (reloc.r_type) + { + case BFD_MACH_O_ARM_RELOC_PAIR: + if (reloc.r_length == 2) + { + res->howto = &arm_howto_table[7]; + res->address = res[-1].address; + return TRUE; + } + else if (reloc.r_length == 1) + { + res->howto = &arm_howto_table[10]; + res->address = res[-1].address; + return TRUE; + } + return FALSE; + case BFD_MACH_O_ARM_RELOC_SECTDIFF: + if (reloc.r_length == 2) + { + res->howto = &arm_howto_table[5]; + return TRUE; + } + else if (reloc.r_length == 1) + { + res->howto = &arm_howto_table[8]; + return TRUE; + } + return FALSE; + case BFD_MACH_O_ARM_RELOC_LOCAL_SECTDIFF: + if (reloc.r_length == 2) + { + res->howto = &arm_howto_table[6]; + return TRUE; + } + else if (reloc.r_length == 1) + { + res->howto = &arm_howto_table[9]; + return TRUE; + } + 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; + case 3: /* :upper16: for movt arm. */ + res->howto = &arm_howto_table[14]; + return TRUE; + } + return FALSE; + default: + return FALSE; + } + } + else + { + switch (reloc.r_type) + { + case BFD_MACH_O_ARM_RELOC_VANILLA: + switch ((reloc.r_length << 1) | reloc.r_pcrel) + { + case 0: /* len = 0, pcrel = 0 */ + res->howto = &arm_howto_table[2]; + return TRUE; + case 2: /* len = 1, pcrel = 0 */ + res->howto = &arm_howto_table[1]; + return TRUE; + case 3: /* len = 1, pcrel = 1 */ + res->howto = &arm_howto_table[4]; + return TRUE; + case 4: /* len = 2, pcrel = 0 */ + res->howto = &arm_howto_table[0]; + return TRUE; + case 5: /* len = 2, pcrel = 1 */ + res->howto = &arm_howto_table[3]; + return TRUE; + default: + return FALSE; + } + break; + case BFD_MACH_O_ARM_RELOC_BR24: + if (reloc.r_length == 2 && reloc.r_pcrel == 1) + { + res->howto = &arm_howto_table[11]; + return TRUE; + } + else + return FALSE; + break; + case BFD_MACH_O_THUMB_RELOC_BR22: + if (reloc.r_length == 2 && reloc.r_pcrel == 1) + { + res->howto = &arm_howto_table[16]; + return TRUE; + } + else + return FALSE; + break; + case BFD_MACH_O_ARM_RELOC_HALF: + if (reloc.r_pcrel == 0) + switch (reloc.r_length) + { + case 0: /* :lower16: for movw arm. */ + res->howto = &arm_howto_table[12]; + return TRUE; + case 1: /* :upper16: for movt arm. */ + res->howto = &arm_howto_table[14]; + return TRUE; + } + return FALSE; + case BFD_MACH_O_ARM_RELOC_PAIR: + if (res[-1].howto == &arm_howto_table[12] + && reloc.r_length == 0) + { + /* Pair for :lower16: of movw arm. */ + res->howto = &arm_howto_table[13]; + /* 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; + } + else if (res[-1].howto == &arm_howto_table[14] + && reloc.r_length == 1) + { + /* Pair for :upper16: of movt arm. */ + res->howto = &arm_howto_table[15]; + /* 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 FALSE; + default: + return FALSE; + } + } +} + +static reloc_howto_type * +bfd_mach_o_arm_bfd_reloc_type_lookup (bfd *abfd ATTRIBUTE_UNUSED, + bfd_reloc_code_real_type code) +{ + unsigned int i; + + for (i = 0; i < sizeof (arm_howto_table) / sizeof (*arm_howto_table); i++) + if (code == arm_howto_table[i].type) + return &arm_howto_table[i]; + return NULL; +} + +static reloc_howto_type * +bfd_mach_o_arm_bfd_reloc_name_lookup (bfd *abfd ATTRIBUTE_UNUSED, + const char *name ATTRIBUTE_UNUSED) +{ + return NULL; +} + +#define TARGET_NAME arm_mach_o_vec +#define TARGET_STRING "mach-o-arm" +#define TARGET_ARCHITECTURE bfd_arch_arm +#define TARGET_PAGESIZE 4096 +#define TARGET_BIG_ENDIAN 0 +#define TARGET_ARCHIVE 0 +#define TARGET_PRIORITY 0 +#include "mach-o-target.c" |