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>