OLD | NEW |
1 /* Intel i386 Mach-O support for BFD. | 1 /* Intel i386 Mach-O support for BFD. |
2 Copyright 2009 | 2 Copyright 2009 |
3 Free Software Foundation, Inc. | 3 Free Software Foundation, Inc. |
4 | 4 |
5 This file is part of BFD, the Binary File Descriptor library. | 5 This file is part of BFD, the Binary File Descriptor library. |
6 | 6 |
7 This program is free software; you can redistribute it and/or modify | 7 This program is free software; you can redistribute it and/or modify |
8 it under the terms of the GNU General Public License as published by | 8 it under the terms of the GNU General Public License as published by |
9 the Free Software Foundation; either version 3 of the License, or | 9 the Free Software Foundation; either version 3 of the License, or |
10 (at your option) any later version. | 10 (at your option) any later version. |
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
56 mdata->header.cputype = BFD_MACH_O_CPU_TYPE_I386; | 56 mdata->header.cputype = BFD_MACH_O_CPU_TYPE_I386; |
57 mdata->header.cpusubtype = BFD_MACH_O_CPU_SUBTYPE_X86_ALL; | 57 mdata->header.cpusubtype = BFD_MACH_O_CPU_SUBTYPE_X86_ALL; |
58 mdata->header.byteorder = BFD_ENDIAN_LITTLE; | 58 mdata->header.byteorder = BFD_ENDIAN_LITTLE; |
59 mdata->header.version = 1; | 59 mdata->header.version = 1; |
60 | 60 |
61 return TRUE; | 61 return TRUE; |
62 } | 62 } |
63 | 63 |
64 static reloc_howto_type i386_howto_table[]= | 64 static reloc_howto_type i386_howto_table[]= |
65 { | 65 { |
| 66 /* 0 */ |
66 HOWTO(BFD_RELOC_32, 0, 2, 32, FALSE, 0, | 67 HOWTO(BFD_RELOC_32, 0, 2, 32, FALSE, 0, |
67 complain_overflow_bitfield, | 68 complain_overflow_bitfield, |
68 NULL, "32", | 69 NULL, "32", |
69 FALSE, 0xffffffff, 0xffffffff, FALSE), | 70 FALSE, 0xffffffff, 0xffffffff, FALSE), |
70 HOWTO(BFD_RELOC_16, 0, 1, 16, FALSE, 0, | 71 HOWTO(BFD_RELOC_16, 0, 1, 16, FALSE, 0, |
71 complain_overflow_bitfield, | 72 complain_overflow_bitfield, |
72 NULL, "16", | 73 NULL, "16", |
73 FALSE, 0xffff, 0xffff, FALSE), | 74 FALSE, 0xffff, 0xffff, FALSE), |
74 HOWTO(BFD_RELOC_8, 0, 0, 8, FALSE, 0, | 75 HOWTO(BFD_RELOC_8, 0, 0, 8, FALSE, 0, |
75 complain_overflow_bitfield, | 76 complain_overflow_bitfield, |
76 NULL, "8", | 77 NULL, "8", |
77 FALSE, 0xff, 0xff, FALSE), | 78 FALSE, 0xff, 0xff, FALSE), |
78 HOWTO(BFD_RELOC_32_PCREL, 0, 2, 32, TRUE, 0, | 79 HOWTO(BFD_RELOC_32_PCREL, 0, 2, 32, TRUE, 0, |
79 complain_overflow_bitfield, | 80 complain_overflow_bitfield, |
80 NULL, "DISP32", | 81 NULL, "DISP32", |
81 FALSE, 0xffffffff, 0xffffffff, TRUE), | 82 FALSE, 0xffffffff, 0xffffffff, TRUE), |
| 83 /* 4 */ |
82 HOWTO(BFD_RELOC_16_PCREL, 0, 1, 16, TRUE, 0, | 84 HOWTO(BFD_RELOC_16_PCREL, 0, 1, 16, TRUE, 0, |
83 complain_overflow_bitfield, | 85 complain_overflow_bitfield, |
84 NULL, "DISP16", | 86 NULL, "DISP16", |
85 FALSE, 0xffff, 0xffff, TRUE), | 87 FALSE, 0xffff, 0xffff, TRUE), |
86 HOWTO(BFD_RELOC_MACH_O_SECTDIFF, 0, 2, 32, FALSE, 0, | 88 HOWTO(BFD_RELOC_MACH_O_SECTDIFF, 0, 2, 32, FALSE, 0, |
87 complain_overflow_bitfield, | 89 complain_overflow_bitfield, |
88 NULL, "SECTDIFF_32", | 90 NULL, "SECTDIFF_32", |
89 FALSE, 0xffffffff, 0xffffffff, FALSE), | 91 FALSE, 0xffffffff, 0xffffffff, FALSE), |
| 92 HOWTO(BFD_RELOC_MACH_O_LOCAL_SECTDIFF, 0, 2, 32, FALSE, 0, |
| 93 complain_overflow_bitfield, |
| 94 NULL, "LSECTDIFF_32", |
| 95 FALSE, 0xffffffff, 0xffffffff, FALSE), |
90 HOWTO(BFD_RELOC_MACH_O_PAIR, 0, 2, 32, FALSE, 0, | 96 HOWTO(BFD_RELOC_MACH_O_PAIR, 0, 2, 32, FALSE, 0, |
91 complain_overflow_bitfield, | 97 complain_overflow_bitfield, |
92 NULL, "PAIR_32", | 98 NULL, "PAIR_32", |
93 FALSE, 0xffffffff, 0xffffffff, FALSE), | 99 FALSE, 0xffffffff, 0xffffffff, FALSE), |
| 100 /* 8 */ |
| 101 HOWTO(BFD_RELOC_MACH_O_SECTDIFF, 0, 1, 16, FALSE, 0, |
| 102 complain_overflow_bitfield, |
| 103 NULL, "SECTDIFF_16", |
| 104 FALSE, 0xffff, 0xffff, FALSE), |
| 105 HOWTO(BFD_RELOC_MACH_O_LOCAL_SECTDIFF, 0, 1, 16, FALSE, 0, |
| 106 complain_overflow_bitfield, |
| 107 NULL, "LSECTDIFF_16", |
| 108 FALSE, 0xffff, 0xffff, FALSE), |
| 109 HOWTO(BFD_RELOC_MACH_O_PAIR, 0, 1, 16, FALSE, 0, |
| 110 complain_overflow_bitfield, |
| 111 NULL, "PAIR_16", |
| 112 FALSE, 0xffff, 0xffff, FALSE), |
94 }; | 113 }; |
95 | 114 |
96 static bfd_boolean | 115 static bfd_boolean |
97 bfd_mach_o_i386_swap_reloc_in (arelent *res, bfd_mach_o_reloc_info *reloc) | 116 bfd_mach_o_i386_swap_reloc_in (arelent *res, bfd_mach_o_reloc_info *reloc) |
98 { | 117 { |
99 if (reloc->r_scattered) | 118 if (reloc->r_scattered) |
100 { | 119 { |
101 switch (reloc->r_type) | 120 switch (reloc->r_type) |
102 { | 121 { |
103 case BFD_MACH_O_GENERIC_RELOC_PAIR: | 122 case BFD_MACH_O_GENERIC_RELOC_PAIR: |
104 if (reloc->r_length != 2) | 123 if (reloc->r_length == 2) |
105 return FALSE; | 124 { |
106 res->howto = &i386_howto_table[6]; | 125 » res->howto = &i386_howto_table[7]; |
107 res->address = res[-1].address; | 126 » res->address = res[-1].address; |
108 return TRUE; | 127 » return TRUE; |
| 128 } |
| 129 else if (reloc->r_length == 1) |
| 130 » { |
| 131 » res->howto = &i386_howto_table[10]; |
| 132 » res->address = res[-1].address; |
| 133 » return TRUE; |
| 134 » } |
| 135 return FALSE; |
109 case BFD_MACH_O_GENERIC_RELOC_SECTDIFF: | 136 case BFD_MACH_O_GENERIC_RELOC_SECTDIFF: |
| 137 if (reloc->r_length == 2) |
| 138 { |
| 139 res->howto = &i386_howto_table[5]; |
| 140 return TRUE; |
| 141 } |
| 142 else if (reloc->r_length == 1) |
| 143 { |
| 144 res->howto = &i386_howto_table[8]; |
| 145 return TRUE; |
| 146 } |
| 147 return FALSE; |
110 case BFD_MACH_O_GENERIC_RELOC_LOCAL_SECTDIFF: | 148 case BFD_MACH_O_GENERIC_RELOC_LOCAL_SECTDIFF: |
111 if (reloc->r_length != 2) | 149 if (reloc->r_length == 2) |
112 return FALSE; | 150 { |
113 res->howto = &i386_howto_table[5]; | 151 » res->howto = &i386_howto_table[6]; |
114 return TRUE; | 152 » return TRUE; |
| 153 } |
| 154 else if (reloc->r_length == 1) |
| 155 { |
| 156 » res->howto = &i386_howto_table[9]; |
| 157 » return TRUE; |
| 158 } |
| 159 return FALSE; |
115 default: | 160 default: |
116 return FALSE; | 161 return FALSE; |
117 } | 162 } |
118 } | 163 } |
119 else | 164 else |
120 { | 165 { |
121 switch (reloc->r_type) | 166 switch (reloc->r_type) |
122 { | 167 { |
123 case BFD_MACH_O_GENERIC_RELOC_VANILLA: | 168 case BFD_MACH_O_GENERIC_RELOC_VANILLA: |
124 switch ((reloc->r_length << 1) | reloc->r_pcrel) | 169 switch ((reloc->r_length << 1) | reloc->r_pcrel) |
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
171 else | 216 else |
172 { | 217 { |
173 rinfo->r_extern = 1; | 218 rinfo->r_extern = 1; |
174 rinfo->r_value = (*rel->sym_ptr_ptr)->udata.i; | 219 rinfo->r_value = (*rel->sym_ptr_ptr)->udata.i; |
175 } | 220 } |
176 break; | 221 break; |
177 case BFD_RELOC_MACH_O_SECTDIFF: | 222 case BFD_RELOC_MACH_O_SECTDIFF: |
178 rinfo->r_scattered = 1; | 223 rinfo->r_scattered = 1; |
179 rinfo->r_type = BFD_MACH_O_GENERIC_RELOC_SECTDIFF; | 224 rinfo->r_type = BFD_MACH_O_GENERIC_RELOC_SECTDIFF; |
180 rinfo->r_pcrel = 0; | 225 rinfo->r_pcrel = 0; |
181 rinfo->r_length = 2; | 226 rinfo->r_length = rel->howto->size; |
182 rinfo->r_extern = 0; | 227 rinfo->r_extern = 0; |
183 rinfo->r_value = (*rel->sym_ptr_ptr)->value | 228 rinfo->r_value = rel->addend; |
184 + (*rel->sym_ptr_ptr)->section->vma; | 229 break; |
| 230 case BFD_RELOC_MACH_O_LOCAL_SECTDIFF: |
| 231 rinfo->r_scattered = 1; |
| 232 rinfo->r_type = BFD_MACH_O_GENERIC_RELOC_LOCAL_SECTDIFF; |
| 233 rinfo->r_pcrel = 0; |
| 234 rinfo->r_length = rel->howto->size; |
| 235 rinfo->r_extern = 0; |
| 236 rinfo->r_value = rel->addend; |
185 break; | 237 break; |
186 case BFD_RELOC_MACH_O_PAIR: | 238 case BFD_RELOC_MACH_O_PAIR: |
187 rinfo->r_address = 0; | 239 rinfo->r_address = 0; |
188 rinfo->r_scattered = 1; | 240 rinfo->r_scattered = 1; |
189 rinfo->r_type = BFD_MACH_O_GENERIC_RELOC_PAIR; | 241 rinfo->r_type = BFD_MACH_O_GENERIC_RELOC_PAIR; |
190 rinfo->r_pcrel = 0; | 242 rinfo->r_pcrel = 0; |
191 rinfo->r_length = 2; | 243 rinfo->r_length = rel->howto->size; |
192 rinfo->r_extern = 0; | 244 rinfo->r_extern = 0; |
193 rinfo->r_value = (*rel->sym_ptr_ptr)->value | 245 rinfo->r_value = rel->addend; |
194 + (*rel->sym_ptr_ptr)->section->vma; | |
195 break; | 246 break; |
196 default: | 247 default: |
197 return FALSE; | 248 return FALSE; |
198 } | 249 } |
199 return TRUE; | 250 return TRUE; |
200 } | 251 } |
201 | 252 |
202 static reloc_howto_type * | 253 static reloc_howto_type * |
203 bfd_mach_o_i386_bfd_reloc_type_lookup (bfd *abfd ATTRIBUTE_UNUSED, | 254 bfd_mach_o_i386_bfd_reloc_type_lookup (bfd *abfd ATTRIBUTE_UNUSED, |
204 bfd_reloc_code_real_type code) | 255 bfd_reloc_code_real_type code) |
(...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
273 (unsigned long)bfd_get_32 (abfd, buf + 8), | 324 (unsigned long)bfd_get_32 (abfd, buf + 8), |
274 (unsigned long)bfd_get_32 (abfd, buf + 12), | 325 (unsigned long)bfd_get_32 (abfd, buf + 12), |
275 (unsigned long)bfd_get_32 (abfd, buf + 16)); | 326 (unsigned long)bfd_get_32 (abfd, buf + 16)); |
276 return TRUE; | 327 return TRUE; |
277 default: | 328 default: |
278 break; | 329 break; |
279 } | 330 } |
280 return FALSE; | 331 return FALSE; |
281 } | 332 } |
282 | 333 |
| 334 static const mach_o_section_name_xlat text_section_names_xlat[] = |
| 335 { |
| 336 { ".symbol_stub", "__symbol_stub", |
| 337 SEC_CODE | SEC_LOAD, BFD_MACH_O_S_SYMBOL_STUBS, |
| 338 BFD_MACH_O_S_ATTR_PURE_INSTRUCTIONS, |
| 339 0}, |
| 340 { ".picsymbol_stub", "__picsymbol_stub", |
| 341 SEC_CODE | SEC_LOAD, BFD_MACH_O_S_SYMBOL_STUBS, |
| 342 BFD_MACH_O_S_ATTR_PURE_INSTRUCTIONS, |
| 343 0}, |
| 344 { NULL, NULL, 0, 0, 0, 0} |
| 345 }; |
| 346 |
| 347 static const mach_o_section_name_xlat data_section_names_xlat[] = |
| 348 { |
| 349 /* The first two are recognized by i386, but not emitted for x86 by |
| 350 modern GCC. */ |
| 351 { ".non_lazy_symbol_pointer", "__nl_symbol_ptr", |
| 352 SEC_DATA | SEC_LOAD, BFD_MACH_O_S_NON_LAZY_SYMBOL_POINTERS, |
| 353 BFD_MACH_O_S_ATTR_NONE, 2}, |
| 354 { ".lazy_symbol_pointer", "__la_symbol_ptr", |
| 355 SEC_DATA | SEC_LOAD, BFD_MACH_O_S_LAZY_SYMBOL_POINTERS, |
| 356 BFD_MACH_O_S_ATTR_NONE, 2}, |
| 357 { ".lazy_symbol_pointer2", "__la_sym_ptr2", |
| 358 SEC_DATA | SEC_LOAD, BFD_MACH_O_S_LAZY_SYMBOL_POINTERS, |
| 359 BFD_MACH_O_S_ATTR_NONE, 2}, |
| 360 { ".lazy_symbol_pointer3", "__la_sym_ptr3", |
| 361 SEC_DATA | SEC_LOAD, BFD_MACH_O_S_LAZY_SYMBOL_POINTERS, |
| 362 BFD_MACH_O_S_ATTR_NONE, 2}, |
| 363 { NULL, NULL, 0, 0, 0, 0} |
| 364 }; |
| 365 |
| 366 static const mach_o_section_name_xlat import_section_names_xlat[] = |
| 367 { |
| 368 { ".picsymbol_stub3", "__jump_table", |
| 369 SEC_CODE | SEC_LOAD, BFD_MACH_O_S_SYMBOL_STUBS, |
| 370 BFD_MACH_O_S_ATTR_PURE_INSTRUCTIONS |
| 371 | BFD_MACH_O_S_SELF_MODIFYING_CODE, |
| 372 6}, |
| 373 { ".non_lazy_symbol_pointer_x86", "__pointers", |
| 374 SEC_DATA | SEC_LOAD, BFD_MACH_O_S_NON_LAZY_SYMBOL_POINTERS, |
| 375 BFD_MACH_O_S_ATTR_NONE, 2}, |
| 376 { NULL, NULL, 0, 0, 0, 0} |
| 377 }; |
| 378 |
| 379 const mach_o_segment_name_xlat mach_o_i386_segsec_names_xlat[] = |
| 380 { |
| 381 { "__TEXT", text_section_names_xlat }, |
| 382 { "__DATA", data_section_names_xlat }, |
| 383 { "__IMPORT", import_section_names_xlat }, |
| 384 { NULL, NULL } |
| 385 }; |
| 386 |
283 #define bfd_mach_o_swap_reloc_in bfd_mach_o_i386_swap_reloc_in | 387 #define bfd_mach_o_swap_reloc_in bfd_mach_o_i386_swap_reloc_in |
284 #define bfd_mach_o_swap_reloc_out bfd_mach_o_i386_swap_reloc_out | 388 #define bfd_mach_o_swap_reloc_out bfd_mach_o_i386_swap_reloc_out |
285 #define bfd_mach_o_print_thread bfd_mach_o_i386_print_thread | 389 #define bfd_mach_o_print_thread bfd_mach_o_i386_print_thread |
286 | 390 |
| 391 #define bfd_mach_o_tgt_seg_table mach_o_i386_segsec_names_xlat |
| 392 #define bfd_mach_o_section_type_valid_for_tgt NULL |
| 393 |
287 #define bfd_mach_o_bfd_reloc_type_lookup bfd_mach_o_i386_bfd_reloc_type_lookup | 394 #define bfd_mach_o_bfd_reloc_type_lookup bfd_mach_o_i386_bfd_reloc_type_lookup |
288 #define bfd_mach_o_bfd_reloc_name_lookup bfd_mach_o_i386_bfd_reloc_name_lookup | 395 #define bfd_mach_o_bfd_reloc_name_lookup bfd_mach_o_i386_bfd_reloc_name_lookup |
289 | 396 |
290 #define TARGET_NAME mach_o_i386_vec | 397 #define TARGET_NAME mach_o_i386_vec |
291 #define TARGET_STRING "mach-o-i386" | 398 #define TARGET_STRING "mach-o-i386" |
292 #define TARGET_ARCHITECTURE bfd_arch_i386 | 399 #define TARGET_ARCHITECTURE bfd_arch_i386 |
293 #define TARGET_BIG_ENDIAN 0 | 400 #define TARGET_BIG_ENDIAN 0 |
294 #define TARGET_ARCHIVE 0 | 401 #define TARGET_ARCHIVE 0 |
| 402 #define TARGET_PRIORITY 0 |
295 #include "mach-o-target.c" | 403 #include "mach-o-target.c" |
OLD | NEW |