*** empty log message ***
[deliverable/binutils-gdb.git] / bfd / mach-o.c
1 /* Mach-O support for BFD.
2 Copyright 1999, 2000, 2001, 2002, 2003, 2004, 2005
3 Free Software Foundation, Inc.
4
5 This file is part of BFD, the Binary File Descriptor library.
6
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
9 the Free Software Foundation; either version 2 of the License, or
10 (at your option) any later version.
11
12 This program is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
16
17 You should have received a copy of the GNU General Public License
18 along with this program; if not, write to the Free Software
19 Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA. */
20
21 #include "mach-o.h"
22 #include "bfd.h"
23 #include "sysdep.h"
24 #include "libbfd.h"
25 #include "libiberty.h"
26 #include <ctype.h>
27
28 #ifndef BFD_IO_FUNCS
29 #define BFD_IO_FUNCS 0
30 #endif
31
32 #define bfd_mach_o_mkarchive _bfd_noarchive_mkarchive
33 #define bfd_mach_o_read_ar_hdr _bfd_noarchive_read_ar_hdr
34 #define bfd_mach_o_slurp_armap _bfd_noarchive_slurp_armap
35 #define bfd_mach_o_slurp_extended_name_table _bfd_noarchive_slurp_extended_name_table
36 #define bfd_mach_o_construct_extended_name_table _bfd_noarchive_construct_extended_name_table
37 #define bfd_mach_o_truncate_arname _bfd_noarchive_truncate_arname
38 #define bfd_mach_o_write_armap _bfd_noarchive_write_armap
39 #define bfd_mach_o_get_elt_at_index _bfd_noarchive_get_elt_at_index
40 #define bfd_mach_o_generic_stat_arch_elt _bfd_noarchive_generic_stat_arch_elt
41 #define bfd_mach_o_update_armap_timestamp _bfd_noarchive_update_armap_timestamp
42 #define bfd_mach_o_close_and_cleanup _bfd_generic_close_and_cleanup
43 #define bfd_mach_o_bfd_free_cached_info _bfd_generic_bfd_free_cached_info
44 #define bfd_mach_o_new_section_hook _bfd_generic_new_section_hook
45 #define bfd_mach_o_get_section_contents_in_window _bfd_generic_get_section_contents_in_window
46 #define bfd_mach_o_bfd_is_local_label_name _bfd_nosymbols_bfd_is_local_label_name
47 #define bfd_mach_o_bfd_is_target_special_symbol ((bfd_boolean (*) (bfd *, asymbol *)) bfd_false)
48 #define bfd_mach_o_bfd_is_local_label_name _bfd_nosymbols_bfd_is_local_label_name
49 #define bfd_mach_o_get_lineno _bfd_nosymbols_get_lineno
50 #define bfd_mach_o_find_nearest_line _bfd_nosymbols_find_nearest_line
51 #define bfd_mach_o_find_inliner_info _bfd_nosymbols_find_inliner_info
52 #define bfd_mach_o_bfd_make_debug_symbol _bfd_nosymbols_bfd_make_debug_symbol
53 #define bfd_mach_o_read_minisymbols _bfd_generic_read_minisymbols
54 #define bfd_mach_o_minisymbol_to_symbol _bfd_generic_minisymbol_to_symbol
55 #define bfd_mach_o_get_reloc_upper_bound _bfd_norelocs_get_reloc_upper_bound
56 #define bfd_mach_o_canonicalize_reloc _bfd_norelocs_canonicalize_reloc
57 #define bfd_mach_o_bfd_reloc_type_lookup _bfd_norelocs_bfd_reloc_type_lookup
58 #define bfd_mach_o_bfd_get_relocated_section_contents bfd_generic_get_relocated_section_contents
59 #define bfd_mach_o_bfd_relax_section bfd_generic_relax_section
60 #define bfd_mach_o_bfd_link_hash_table_create _bfd_generic_link_hash_table_create
61 #define bfd_mach_o_bfd_link_hash_table_free _bfd_generic_link_hash_table_free
62 #define bfd_mach_o_bfd_link_add_symbols _bfd_generic_link_add_symbols
63 #define bfd_mach_o_bfd_link_just_syms _bfd_generic_link_just_syms
64 #define bfd_mach_o_bfd_final_link _bfd_generic_final_link
65 #define bfd_mach_o_bfd_link_split_section _bfd_generic_link_split_section
66 #define bfd_mach_o_set_arch_mach bfd_default_set_arch_mach
67 #define bfd_mach_o_bfd_merge_private_bfd_data _bfd_generic_bfd_merge_private_bfd_data
68 #define bfd_mach_o_bfd_set_private_flags _bfd_generic_bfd_set_private_flags
69 #define bfd_mach_o_bfd_print_private_bfd_data _bfd_generic_bfd_print_private_bfd_data
70 #define bfd_mach_o_get_section_contents _bfd_generic_get_section_contents
71 #define bfd_mach_o_set_section_contents _bfd_generic_set_section_contents
72 #define bfd_mach_o_bfd_gc_sections bfd_generic_gc_sections
73 #define bfd_mach_o_bfd_merge_sections bfd_generic_merge_sections
74 #define bfd_mach_o_bfd_is_group_section bfd_generic_is_group_section
75 #define bfd_mach_o_bfd_discard_group bfd_generic_discard_group
76 #define bfd_mach_o_section_already_linked _bfd_generic_section_already_linked
77 #define bfd_mach_o_bfd_copy_private_header_data _bfd_generic_bfd_copy_private_header_data
78
79
80 /* The flags field of a section structure is separated into two parts a section
81 type and section attributes. The section types are mutually exclusive (it
82 can only have one type) but the section attributes are not (it may have more
83 than one attribute). */
84
85 #define SECTION_TYPE 0x000000ff /* 256 section types. */
86 #define SECTION_ATTRIBUTES 0xffffff00 /* 24 section attributes. */
87
88 /* Constants for the section attributes part of the flags field of a section
89 structure. */
90
91 #define SECTION_ATTRIBUTES_USR 0xff000000 /* User-settable attributes. */
92 #define S_ATTR_PURE_INSTRUCTIONS 0x80000000 /* Section contains only true machine instructions. */
93 #define SECTION_ATTRIBUTES_SYS 0x00ffff00 /* System setable attributes. */
94 #define S_ATTR_SOME_INSTRUCTIONS 0x00000400 /* Section contains some machine instructions. */
95 #define S_ATTR_EXT_RELOC 0x00000200 /* Section has external relocation entries. */
96 #define S_ATTR_LOC_RELOC 0x00000100 /* Section has local relocation entries. */
97
98 #define N_STAB 0xe0
99 #define N_TYPE 0x1e
100 #define N_EXT 0x01
101 #define N_UNDF 0x0
102 #define N_ABS 0x2
103 #define N_SECT 0xe
104 #define N_INDR 0xa
105
106 bfd_boolean
107 bfd_mach_o_valid (bfd *abfd)
108 {
109 if (abfd == NULL || abfd->xvec == NULL)
110 return 0;
111
112 if (! ((abfd->xvec == &mach_o_be_vec)
113 || (abfd->xvec == &mach_o_le_vec)
114 || (abfd->xvec == &mach_o_fat_vec)))
115 return 0;
116
117 if (abfd->tdata.mach_o_data == NULL)
118 return 0;
119 return 1;
120 }
121
122 /* Copy any private info we understand from the input symbol
123 to the output symbol. */
124
125 static bfd_boolean
126 bfd_mach_o_bfd_copy_private_symbol_data (bfd *ibfd ATTRIBUTE_UNUSED,
127 asymbol *isymbol ATTRIBUTE_UNUSED,
128 bfd *obfd ATTRIBUTE_UNUSED,
129 asymbol *osymbol ATTRIBUTE_UNUSED)
130 {
131 return TRUE;
132 }
133
134 /* Copy any private info we understand from the input section
135 to the output section. */
136
137 static bfd_boolean
138 bfd_mach_o_bfd_copy_private_section_data (bfd *ibfd ATTRIBUTE_UNUSED,
139 asection *isection ATTRIBUTE_UNUSED,
140 bfd *obfd ATTRIBUTE_UNUSED,
141 asection *osection ATTRIBUTE_UNUSED)
142 {
143 return TRUE;
144 }
145
146 /* Copy any private info we understand from the input bfd
147 to the output bfd. */
148
149 static bfd_boolean
150 bfd_mach_o_bfd_copy_private_bfd_data (bfd *ibfd, bfd *obfd)
151 {
152 BFD_ASSERT (bfd_mach_o_valid (ibfd));
153 BFD_ASSERT (bfd_mach_o_valid (obfd));
154
155 obfd->tdata.mach_o_data = ibfd->tdata.mach_o_data;
156 obfd->tdata.mach_o_data->ibfd = ibfd;
157 return TRUE;
158 }
159
160 static long
161 bfd_mach_o_count_symbols (bfd *abfd)
162 {
163 bfd_mach_o_data_struct *mdata = NULL;
164 long nsyms = 0;
165 unsigned long i;
166
167 BFD_ASSERT (bfd_mach_o_valid (abfd));
168 mdata = abfd->tdata.mach_o_data;
169
170 for (i = 0; i < mdata->header.ncmds; i++)
171 if (mdata->commands[i].type == BFD_MACH_O_LC_SYMTAB)
172 {
173 bfd_mach_o_symtab_command *sym = &mdata->commands[i].command.symtab;
174 nsyms += sym->nsyms;
175 }
176
177 return nsyms;
178 }
179
180 static long
181 bfd_mach_o_get_symtab_upper_bound (bfd *abfd)
182 {
183 long nsyms = bfd_mach_o_count_symbols (abfd);
184
185 if (nsyms < 0)
186 return nsyms;
187
188 return ((nsyms + 1) * sizeof (asymbol *));
189 }
190
191 static long
192 bfd_mach_o_canonicalize_symtab (bfd *abfd, asymbol **alocation)
193 {
194 bfd_mach_o_data_struct *mdata = abfd->tdata.mach_o_data;
195 long nsyms = bfd_mach_o_count_symbols (abfd);
196 asymbol **csym = alocation;
197 unsigned long i, j;
198
199 if (nsyms < 0)
200 return nsyms;
201
202 for (i = 0; i < mdata->header.ncmds; i++)
203 {
204 if (mdata->commands[i].type == BFD_MACH_O_LC_SYMTAB)
205 {
206 bfd_mach_o_symtab_command *sym = &mdata->commands[i].command.symtab;
207
208 if (bfd_mach_o_scan_read_symtab_symbols (abfd, &mdata->commands[i].command.symtab) != 0)
209 {
210 fprintf (stderr, "bfd_mach_o_canonicalize_symtab: unable to load symbols for section %lu\n", i);
211 return 0;
212 }
213
214 BFD_ASSERT (sym->symbols != NULL);
215
216 for (j = 0; j < sym->nsyms; j++)
217 {
218 BFD_ASSERT (csym < (alocation + nsyms));
219 *csym++ = &sym->symbols[j];
220 }
221 }
222 }
223
224 *csym++ = NULL;
225
226 return nsyms;
227 }
228
229 static void
230 bfd_mach_o_get_symbol_info (bfd *abfd ATTRIBUTE_UNUSED,
231 asymbol *symbol,
232 symbol_info *ret)
233 {
234 bfd_symbol_info (symbol, ret);
235 }
236
237 static void
238 bfd_mach_o_print_symbol (bfd *abfd,
239 PTR afile,
240 asymbol *symbol,
241 bfd_print_symbol_type how)
242 {
243 FILE *file = (FILE *) afile;
244
245 switch (how)
246 {
247 case bfd_print_symbol_name:
248 fprintf (file, "%s", symbol->name);
249 break;
250 default:
251 bfd_print_symbol_vandf (abfd, (PTR) file, symbol);
252 fprintf (file, " %-5s %s", symbol->section->name, symbol->name);
253 }
254 }
255
256 static void
257 bfd_mach_o_convert_architecture (bfd_mach_o_cpu_type mtype,
258 bfd_mach_o_cpu_subtype msubtype ATTRIBUTE_UNUSED,
259 enum bfd_architecture *type,
260 unsigned long *subtype)
261 {
262 *subtype = bfd_arch_unknown;
263
264 switch (mtype)
265 {
266 case BFD_MACH_O_CPU_TYPE_VAX: *type = bfd_arch_vax; break;
267 case BFD_MACH_O_CPU_TYPE_MC680x0: *type = bfd_arch_m68k; break;
268 case BFD_MACH_O_CPU_TYPE_I386: *type = bfd_arch_i386; break;
269 case BFD_MACH_O_CPU_TYPE_MIPS: *type = bfd_arch_mips; break;
270 case BFD_MACH_O_CPU_TYPE_MC98000: *type = bfd_arch_m98k; break;
271 case BFD_MACH_O_CPU_TYPE_HPPA: *type = bfd_arch_hppa; break;
272 case BFD_MACH_O_CPU_TYPE_ARM: *type = bfd_arch_arm; break;
273 case BFD_MACH_O_CPU_TYPE_MC88000: *type = bfd_arch_m88k; break;
274 case BFD_MACH_O_CPU_TYPE_SPARC: *type = bfd_arch_sparc; break;
275 case BFD_MACH_O_CPU_TYPE_I860: *type = bfd_arch_i860; break;
276 case BFD_MACH_O_CPU_TYPE_ALPHA: *type = bfd_arch_alpha; break;
277 case BFD_MACH_O_CPU_TYPE_POWERPC: *type = bfd_arch_powerpc; break;
278 default: *type = bfd_arch_unknown; break;
279 }
280
281 switch (*type)
282 {
283 case bfd_arch_i386: *subtype = bfd_mach_i386_i386; break;
284 case bfd_arch_sparc: *subtype = bfd_mach_sparc; break;
285 default:
286 *subtype = bfd_arch_unknown;
287 }
288 }
289
290 static int
291 bfd_mach_o_write_header (bfd *abfd, bfd_mach_o_header *header)
292 {
293 unsigned char buf[28];
294
295 bfd_h_put_32 (abfd, header->magic, buf + 0);
296 bfd_h_put_32 (abfd, header->cputype, buf + 4);
297 bfd_h_put_32 (abfd, header->cpusubtype, buf + 8);
298 bfd_h_put_32 (abfd, header->filetype, buf + 12);
299 bfd_h_put_32 (abfd, header->ncmds, buf + 16);
300 bfd_h_put_32 (abfd, header->sizeofcmds, buf + 20);
301 bfd_h_put_32 (abfd, header->flags, buf + 24);
302
303 bfd_seek (abfd, 0, SEEK_SET);
304 if (bfd_bwrite ((PTR) buf, 28, abfd) != 28)
305 return -1;
306
307 return 0;
308 }
309
310 static int
311 bfd_mach_o_scan_write_thread (bfd *abfd,
312 bfd_mach_o_load_command *command)
313 {
314 bfd_mach_o_thread_command *cmd = &command->command.thread;
315 unsigned int i;
316 unsigned char buf[8];
317 bfd_vma offset;
318 unsigned int nflavours;
319
320 BFD_ASSERT ((command->type == BFD_MACH_O_LC_THREAD)
321 || (command->type == BFD_MACH_O_LC_UNIXTHREAD));
322
323 offset = 8;
324 nflavours = 0;
325 for (i = 0; i < cmd->nflavours; i++)
326 {
327 BFD_ASSERT ((cmd->flavours[i].size % 4) == 0);
328 BFD_ASSERT (cmd->flavours[i].offset == (command->offset + offset + 8));
329
330 bfd_h_put_32 (abfd, cmd->flavours[i].flavour, buf);
331 bfd_h_put_32 (abfd, (cmd->flavours[i].size / 4), buf + 4);
332
333 bfd_seek (abfd, command->offset + offset, SEEK_SET);
334 if (bfd_bwrite ((PTR) buf, 8, abfd) != 8)
335 return -1;
336
337 offset += cmd->flavours[i].size + 8;
338 }
339
340 return 0;
341 }
342
343 static int
344 bfd_mach_o_scan_write_section (bfd *abfd,
345 bfd_mach_o_section *section,
346 bfd_vma offset)
347 {
348 unsigned char buf[68];
349
350 memcpy (buf, section->sectname, 16);
351 memcpy (buf + 16, section->segname, 16);
352 bfd_h_put_32 (abfd, section->addr, buf + 32);
353 bfd_h_put_32 (abfd, section->size, buf + 36);
354 bfd_h_put_32 (abfd, section->offset, buf + 40);
355 bfd_h_put_32 (abfd, section->align, buf + 44);
356 bfd_h_put_32 (abfd, section->reloff, buf + 48);
357 bfd_h_put_32 (abfd, section->nreloc, buf + 52);
358 bfd_h_put_32 (abfd, section->flags, buf + 56);
359 /* bfd_h_put_32 (abfd, section->reserved1, buf + 60); */
360 /* bfd_h_put_32 (abfd, section->reserved2, buf + 64); */
361
362 bfd_seek (abfd, offset, SEEK_SET);
363 if (bfd_bwrite ((PTR) buf, 68, abfd) != 68)
364 return -1;
365
366 return 0;
367 }
368
369 static int
370 bfd_mach_o_scan_write_segment (bfd *abfd, bfd_mach_o_load_command *command)
371 {
372 unsigned char buf[48];
373 bfd_mach_o_segment_command *seg = &command->command.segment;
374 unsigned long i;
375
376 BFD_ASSERT (command->type == BFD_MACH_O_LC_SEGMENT);
377
378 memcpy (buf, seg->segname, 16);
379 bfd_h_put_32 (abfd, seg->vmaddr, buf + 16);
380 bfd_h_put_32 (abfd, seg->vmsize, buf + 20);
381 bfd_h_put_32 (abfd, seg->fileoff, buf + 24);
382 bfd_h_put_32 (abfd, seg->filesize, buf + 28);
383 bfd_h_put_32 (abfd, 0 /* seg->maxprot */, buf + 32);
384 bfd_h_put_32 (abfd, 0 /* seg->initprot */, buf + 36);
385 bfd_h_put_32 (abfd, seg->nsects, buf + 40);
386 bfd_h_put_32 (abfd, seg->flags, buf + 44);
387
388 bfd_seek (abfd, command->offset + 8, SEEK_SET);
389 if (bfd_bwrite ((PTR) buf, 48, abfd) != 48)
390 return -1;
391
392 {
393 char buf[1024];
394 bfd_vma nbytes = seg->filesize;
395 bfd_vma curoff = seg->fileoff;
396
397 while (nbytes > 0)
398 {
399 bfd_vma thisread = nbytes;
400
401 if (thisread > 1024)
402 thisread = 1024;
403
404 bfd_seek (abfd, curoff, SEEK_SET);
405 if (bfd_bread ((PTR) buf, thisread, abfd) != thisread)
406 return -1;
407
408 bfd_seek (abfd, curoff, SEEK_SET);
409 if (bfd_bwrite ((PTR) buf, thisread, abfd) != thisread)
410 return -1;
411
412 nbytes -= thisread;
413 curoff += thisread;
414 }
415 }
416
417 for (i = 0; i < seg->nsects; i++)
418 {
419 bfd_vma segoff = command->offset + 48 + 8 + (i * 68);
420
421 if (bfd_mach_o_scan_write_section (abfd, &seg->sections[i], segoff) != 0)
422 return -1;
423 }
424
425 return 0;
426 }
427
428 static int
429 bfd_mach_o_scan_write_symtab_symbols (bfd *abfd,
430 bfd_mach_o_load_command *command)
431 {
432 bfd_mach_o_symtab_command *sym = &command->command.symtab;
433 asymbol *s = NULL;
434 unsigned long i;
435
436 for (i = 0; i < sym->nsyms; i++)
437 {
438 unsigned char buf[12];
439 bfd_vma symoff = sym->symoff + (i * 12);
440 unsigned char ntype = 0;
441 unsigned char nsect = 0;
442 short ndesc = 0;
443
444 s = &sym->symbols[i];
445
446 /* Instead just set from the stored values. */
447 ntype = (s->udata.i >> 24) & 0xff;
448 nsect = (s->udata.i >> 16) & 0xff;
449 ndesc = s->udata.i & 0xffff;
450
451 bfd_h_put_32 (abfd, s->name - sym->strtab, buf);
452 bfd_h_put_8 (abfd, ntype, buf + 4);
453 bfd_h_put_8 (abfd, nsect, buf + 5);
454 bfd_h_put_16 (abfd, ndesc, buf + 6);
455 bfd_h_put_32 (abfd, s->section->vma + s->value, buf + 8);
456
457 bfd_seek (abfd, symoff, SEEK_SET);
458 if (bfd_bwrite ((PTR) buf, 12, abfd) != 12)
459 {
460 fprintf (stderr, "bfd_mach_o_scan_write_symtab_symbols: unable to write %d bytes at %lu\n",
461 12, (unsigned long) symoff);
462 return -1;
463 }
464 }
465
466 return 0;
467 }
468
469 static int
470 bfd_mach_o_scan_write_symtab (bfd *abfd, bfd_mach_o_load_command *command)
471 {
472 bfd_mach_o_symtab_command *seg = &command->command.symtab;
473 unsigned char buf[16];
474
475 BFD_ASSERT (command->type == BFD_MACH_O_LC_SYMTAB);
476
477 bfd_h_put_32 (abfd, seg->symoff, buf);
478 bfd_h_put_32 (abfd, seg->nsyms, buf + 4);
479 bfd_h_put_32 (abfd, seg->stroff, buf + 8);
480 bfd_h_put_32 (abfd, seg->strsize, buf + 12);
481
482 bfd_seek (abfd, command->offset + 8, SEEK_SET);
483 if (bfd_bwrite ((PTR) buf, 16, abfd) != 16)
484 return -1;
485
486 if (bfd_mach_o_scan_write_symtab_symbols (abfd, command) != 0)
487 return -1;
488
489 return 0;
490 }
491
492 static bfd_boolean
493 bfd_mach_o_write_contents (bfd *abfd)
494 {
495 unsigned int i;
496 asection *s;
497
498 bfd_mach_o_data_struct *mdata = abfd->tdata.mach_o_data;
499
500 /* Write data sections first in case they overlap header data to be
501 written later. */
502
503 for (s = abfd->sections; s != (asection *) NULL; s = s->next)
504 ;
505
506 /* Now write header information. */
507 if (bfd_mach_o_write_header (abfd, &mdata->header) != 0)
508 return FALSE;
509
510 for (i = 0; i < mdata->header.ncmds; i++)
511 {
512 unsigned char buf[8];
513 bfd_mach_o_load_command *cur = &mdata->commands[i];
514 unsigned long typeflag;
515
516 typeflag = cur->type_required ? cur->type & BFD_MACH_O_LC_REQ_DYLD : cur->type;
517
518 bfd_h_put_32 (abfd, typeflag, buf);
519 bfd_h_put_32 (abfd, cur->len, buf + 4);
520
521 bfd_seek (abfd, cur->offset, SEEK_SET);
522 if (bfd_bwrite ((PTR) buf, 8, abfd) != 8)
523 return FALSE;
524
525 switch (cur->type)
526 {
527 case BFD_MACH_O_LC_SEGMENT:
528 if (bfd_mach_o_scan_write_segment (abfd, cur) != 0)
529 return FALSE;
530 break;
531 case BFD_MACH_O_LC_SYMTAB:
532 if (bfd_mach_o_scan_write_symtab (abfd, cur) != 0)
533 return FALSE;
534 break;
535 case BFD_MACH_O_LC_SYMSEG:
536 break;
537 case BFD_MACH_O_LC_THREAD:
538 case BFD_MACH_O_LC_UNIXTHREAD:
539 if (bfd_mach_o_scan_write_thread (abfd, cur) != 0)
540 return FALSE;
541 break;
542 case BFD_MACH_O_LC_LOADFVMLIB:
543 case BFD_MACH_O_LC_IDFVMLIB:
544 case BFD_MACH_O_LC_IDENT:
545 case BFD_MACH_O_LC_FVMFILE:
546 case BFD_MACH_O_LC_PREPAGE:
547 case BFD_MACH_O_LC_DYSYMTAB:
548 case BFD_MACH_O_LC_LOAD_DYLIB:
549 case BFD_MACH_O_LC_LOAD_WEAK_DYLIB:
550 case BFD_MACH_O_LC_ID_DYLIB:
551 case BFD_MACH_O_LC_LOAD_DYLINKER:
552 case BFD_MACH_O_LC_ID_DYLINKER:
553 case BFD_MACH_O_LC_PREBOUND_DYLIB:
554 case BFD_MACH_O_LC_ROUTINES:
555 case BFD_MACH_O_LC_SUB_FRAMEWORK:
556 break;
557 default:
558 fprintf (stderr,
559 "unable to write unknown load command 0x%lx\n",
560 (long) cur->type);
561 return FALSE;
562 }
563 }
564
565 return TRUE;
566 }
567
568 static int
569 bfd_mach_o_sizeof_headers (bfd *a ATTRIBUTE_UNUSED,
570 bfd_boolean b ATTRIBUTE_UNUSED)
571 {
572 return 0;
573 }
574
575 /* Make an empty symbol. This is required only because
576 bfd_make_section_anyway wants to create a symbol for the section. */
577
578 static asymbol *
579 bfd_mach_o_make_empty_symbol (bfd *abfd)
580 {
581 asymbol *new;
582
583 new = bfd_zalloc (abfd, sizeof (* new));
584 if (new == NULL)
585 return new;
586 new->the_bfd = abfd;
587 return new;
588 }
589
590 static int
591 bfd_mach_o_read_header (bfd *abfd, bfd_mach_o_header *header)
592 {
593 unsigned char buf[28];
594 bfd_vma (*get32) (const void *) = NULL;
595
596 bfd_seek (abfd, 0, SEEK_SET);
597
598 if (bfd_bread ((PTR) buf, 28, abfd) != 28)
599 return -1;
600
601 if (bfd_getb32 (buf) == 0xfeedface)
602 {
603 header->byteorder = BFD_ENDIAN_BIG;
604 header->magic = 0xfeedface;
605 get32 = bfd_getb32;
606 }
607 else if (bfd_getl32 (buf) == 0xfeedface)
608 {
609 header->byteorder = BFD_ENDIAN_LITTLE;
610 header->magic = 0xfeedface;
611 get32 = bfd_getl32;
612 }
613 else
614 {
615 header->byteorder = BFD_ENDIAN_UNKNOWN;
616 return -1;
617 }
618
619 header->cputype = (*get32) (buf + 4);
620 header->cpusubtype = (*get32) (buf + 8);
621 header->filetype = (*get32) (buf + 12);
622 header->ncmds = (*get32) (buf + 16);
623 header->sizeofcmds = (*get32) (buf + 20);
624 header->flags = (*get32) (buf + 24);
625
626 return 0;
627 }
628
629 static asection *
630 bfd_mach_o_make_bfd_section (bfd *abfd, bfd_mach_o_section *section)
631 {
632 asection *bfdsec;
633 char *sname;
634 const char *prefix = "LC_SEGMENT";
635 unsigned int snamelen;
636
637 snamelen = strlen (prefix) + 1
638 + strlen (section->segname) + 1
639 + strlen (section->sectname) + 1;
640
641 sname = bfd_alloc (abfd, snamelen);
642 if (sname == NULL)
643 return NULL;
644 sprintf (sname, "%s.%s.%s", prefix, section->segname, section->sectname);
645
646 bfdsec = bfd_make_section_anyway (abfd, sname);
647 if (bfdsec == NULL)
648 return NULL;
649
650 bfdsec->vma = section->addr;
651 bfdsec->lma = section->addr;
652 bfdsec->size = section->size;
653 bfdsec->filepos = section->offset;
654 bfdsec->alignment_power = section->align;
655
656 if (section->flags & BFD_MACH_O_S_ZEROFILL)
657 bfdsec->flags = SEC_ALLOC;
658 else
659 bfdsec->flags = SEC_HAS_CONTENTS | SEC_LOAD | SEC_ALLOC | SEC_CODE;
660
661 return bfdsec;
662 }
663
664 static int
665 bfd_mach_o_scan_read_section (bfd *abfd,
666 bfd_mach_o_section *section,
667 bfd_vma offset)
668 {
669 unsigned char buf[68];
670
671 bfd_seek (abfd, offset, SEEK_SET);
672 if (bfd_bread ((PTR) buf, 68, abfd) != 68)
673 return -1;
674
675 memcpy (section->sectname, buf, 16);
676 section->sectname[16] = '\0';
677 memcpy (section->segname, buf + 16, 16);
678 section->segname[16] = '\0';
679 section->addr = bfd_h_get_32 (abfd, buf + 32);
680 section->size = bfd_h_get_32 (abfd, buf + 36);
681 section->offset = bfd_h_get_32 (abfd, buf + 40);
682 section->align = bfd_h_get_32 (abfd, buf + 44);
683 section->reloff = bfd_h_get_32 (abfd, buf + 48);
684 section->nreloc = bfd_h_get_32 (abfd, buf + 52);
685 section->flags = bfd_h_get_32 (abfd, buf + 56);
686 section->reserved1 = bfd_h_get_32 (abfd, buf + 60);
687 section->reserved2 = bfd_h_get_32 (abfd, buf + 64);
688 section->bfdsection = bfd_mach_o_make_bfd_section (abfd, section);
689
690 if (section->bfdsection == NULL)
691 return -1;
692
693 return 0;
694 }
695
696 int
697 bfd_mach_o_scan_read_symtab_symbol (bfd *abfd,
698 bfd_mach_o_symtab_command *sym,
699 asymbol *s,
700 unsigned long i)
701 {
702 bfd_mach_o_data_struct *mdata = abfd->tdata.mach_o_data;
703 bfd_vma symoff = sym->symoff + (i * 12);
704 unsigned char buf[12];
705 unsigned char type = -1;
706 unsigned char section = -1;
707 short desc = -1;
708 unsigned long value = -1;
709 unsigned long stroff = -1;
710 unsigned int symtype = -1;
711
712 BFD_ASSERT (sym->strtab != NULL);
713
714 bfd_seek (abfd, symoff, SEEK_SET);
715 if (bfd_bread ((PTR) buf, 12, abfd) != 12)
716 {
717 fprintf (stderr, "bfd_mach_o_scan_read_symtab_symbol: unable to read %d bytes at %lu\n",
718 12, (unsigned long) symoff);
719 return -1;
720 }
721
722 stroff = bfd_h_get_32 (abfd, buf);
723 type = bfd_h_get_8 (abfd, buf + 4);
724 symtype = (type & 0x0e);
725 section = bfd_h_get_8 (abfd, buf + 5) - 1;
726 desc = bfd_h_get_16 (abfd, buf + 6);
727 value = bfd_h_get_32 (abfd, buf + 8);
728
729 if (stroff >= sym->strsize)
730 {
731 fprintf (stderr, "bfd_mach_o_scan_read_symtab_symbol: symbol name out of range (%lu >= %lu)\n",
732 (unsigned long) stroff, (unsigned long) sym->strsize);
733 return -1;
734 }
735
736 s->the_bfd = abfd;
737 s->name = sym->strtab + stroff;
738 s->value = value;
739 s->udata.i = (type << 24) | (section << 16) | desc;
740 s->flags = 0x0;
741
742 if (type & BFD_MACH_O_N_STAB)
743 {
744 s->flags |= BSF_DEBUGGING;
745 s->section = bfd_und_section_ptr;
746 }
747 else
748 {
749 if (type & BFD_MACH_O_N_PEXT)
750 {
751 type &= ~BFD_MACH_O_N_PEXT;
752 s->flags |= BSF_GLOBAL;
753 }
754
755 if (type & BFD_MACH_O_N_EXT)
756 {
757 type &= ~BFD_MACH_O_N_EXT;
758 s->flags |= BSF_GLOBAL;
759 }
760
761 switch (symtype)
762 {
763 case BFD_MACH_O_N_UNDF:
764 s->section = bfd_und_section_ptr;
765 break;
766 case BFD_MACH_O_N_PBUD:
767 s->section = bfd_und_section_ptr;
768 break;
769 case BFD_MACH_O_N_ABS:
770 s->section = bfd_abs_section_ptr;
771 break;
772 case BFD_MACH_O_N_SECT:
773 if ((section > 0) && (section <= mdata->nsects))
774 {
775 s->section = mdata->sections[section - 1]->bfdsection;
776 s->value = s->value - mdata->sections[section - 1]->addr;
777 }
778 else
779 {
780 /* Mach-O uses 0 to mean "no section"; not an error. */
781 if (section != 0)
782 {
783 fprintf (stderr, "bfd_mach_o_scan_read_symtab_symbol: "
784 "symbol \"%s\" specified invalid section %d (max %lu): setting to undefined\n",
785 s->name, section, mdata->nsects);
786 }
787 s->section = bfd_und_section_ptr;
788 }
789 break;
790 case BFD_MACH_O_N_INDR:
791 fprintf (stderr, "bfd_mach_o_scan_read_symtab_symbol: "
792 "symbol \"%s\" is unsupported 'indirect' reference: setting to undefined\n",
793 s->name);
794 s->section = bfd_und_section_ptr;
795 break;
796 default:
797 fprintf (stderr, "bfd_mach_o_scan_read_symtab_symbol: "
798 "symbol \"%s\" specified invalid type field 0x%x: setting to undefined\n",
799 s->name, symtype);
800 s->section = bfd_und_section_ptr;
801 break;
802 }
803 }
804
805 return 0;
806 }
807
808 int
809 bfd_mach_o_scan_read_symtab_strtab (bfd *abfd,
810 bfd_mach_o_symtab_command *sym)
811 {
812 BFD_ASSERT (sym->strtab == NULL);
813
814 if (abfd->flags & BFD_IN_MEMORY)
815 {
816 struct bfd_in_memory *b;
817
818 b = (struct bfd_in_memory *) abfd->iostream;
819
820 if ((sym->stroff + sym->strsize) > b->size)
821 {
822 bfd_set_error (bfd_error_file_truncated);
823 return -1;
824 }
825 sym->strtab = (char *) b->buffer + sym->stroff;
826 return 0;
827 }
828
829 sym->strtab = bfd_alloc (abfd, sym->strsize);
830 if (sym->strtab == NULL)
831 return -1;
832
833 bfd_seek (abfd, sym->stroff, SEEK_SET);
834 if (bfd_bread ((PTR) sym->strtab, sym->strsize, abfd) != sym->strsize)
835 {
836 fprintf (stderr, "bfd_mach_o_scan_read_symtab_strtab: unable to read %lu bytes at %lu\n",
837 sym->strsize, sym->stroff);
838 return -1;
839 }
840
841 return 0;
842 }
843
844 int
845 bfd_mach_o_scan_read_symtab_symbols (bfd *abfd,
846 bfd_mach_o_symtab_command *sym)
847 {
848 unsigned long i;
849 int ret;
850
851 BFD_ASSERT (sym->symbols == NULL);
852 sym->symbols = bfd_alloc (abfd, sym->nsyms * sizeof (asymbol));
853
854 if (sym->symbols == NULL)
855 {
856 fprintf (stderr, "bfd_mach_o_scan_read_symtab_symbols: unable to allocate memory for symbols\n");
857 return -1;
858 }
859
860 ret = bfd_mach_o_scan_read_symtab_strtab (abfd, sym);
861 if (ret != 0)
862 return ret;
863
864 for (i = 0; i < sym->nsyms; i++)
865 {
866 ret = bfd_mach_o_scan_read_symtab_symbol (abfd, sym, &sym->symbols[i], i);
867 if (ret != 0)
868 return ret;
869 }
870
871 return 0;
872 }
873
874 int
875 bfd_mach_o_scan_read_dysymtab_symbol (bfd *abfd,
876 bfd_mach_o_dysymtab_command *dysym,
877 bfd_mach_o_symtab_command *sym,
878 asymbol *s,
879 unsigned long i)
880 {
881 unsigned long isymoff = dysym->indirectsymoff + (i * 4);
882 unsigned long symindex;
883 unsigned char buf[4];
884
885 BFD_ASSERT (i < dysym->nindirectsyms);
886
887 bfd_seek (abfd, isymoff, SEEK_SET);
888 if (bfd_bread ((PTR) buf, 4, abfd) != 4)
889 {
890 fprintf (stderr, "bfd_mach_o_scan_read_dysymtab_symbol: unable to read %lu bytes at %lu\n",
891 (unsigned long) 4, isymoff);
892 return -1;
893 }
894 symindex = bfd_h_get_32 (abfd, buf);
895
896 return bfd_mach_o_scan_read_symtab_symbol (abfd, sym, s, symindex);
897 }
898
899 static const char *
900 bfd_mach_o_i386_flavour_string (unsigned int flavour)
901 {
902 switch ((int) flavour)
903 {
904 case BFD_MACH_O_i386_NEW_THREAD_STATE: return "i386_NEW_THREAD_STATE";
905 case BFD_MACH_O_i386_FLOAT_STATE: return "i386_FLOAT_STATE";
906 case BFD_MACH_O_i386_ISA_PORT_MAP_STATE: return "i386_ISA_PORT_MAP_STATE";
907 case BFD_MACH_O_i386_V86_ASSIST_STATE: return "i386_V86_ASSIST_STATE";
908 case BFD_MACH_O_i386_REGS_SEGS_STATE: return "i386_REGS_SEGS_STATE";
909 case BFD_MACH_O_i386_THREAD_SYSCALL_STATE: return "i386_THREAD_SYSCALL_STATE";
910 case BFD_MACH_O_i386_THREAD_STATE_NONE: return "i386_THREAD_STATE_NONE";
911 case BFD_MACH_O_i386_SAVED_STATE: return "i386_SAVED_STATE";
912 case BFD_MACH_O_i386_THREAD_STATE: return "i386_THREAD_STATE";
913 case BFD_MACH_O_i386_THREAD_FPSTATE: return "i386_THREAD_FPSTATE";
914 case BFD_MACH_O_i386_THREAD_EXCEPTSTATE: return "i386_THREAD_EXCEPTSTATE";
915 case BFD_MACH_O_i386_THREAD_CTHREADSTATE: return "i386_THREAD_CTHREADSTATE";
916 default: return "UNKNOWN";
917 }
918 }
919
920 static const char *
921 bfd_mach_o_ppc_flavour_string (unsigned int flavour)
922 {
923 switch ((int) flavour)
924 {
925 case BFD_MACH_O_PPC_THREAD_STATE: return "PPC_THREAD_STATE";
926 case BFD_MACH_O_PPC_FLOAT_STATE: return "PPC_FLOAT_STATE";
927 case BFD_MACH_O_PPC_EXCEPTION_STATE: return "PPC_EXCEPTION_STATE";
928 case BFD_MACH_O_PPC_VECTOR_STATE: return "PPC_VECTOR_STATE";
929 default: return "UNKNOWN";
930 }
931 }
932
933 static int
934 bfd_mach_o_scan_read_dylinker (bfd *abfd,
935 bfd_mach_o_load_command *command)
936 {
937 bfd_mach_o_dylinker_command *cmd = &command->command.dylinker;
938 unsigned char buf[4];
939 unsigned int nameoff;
940 asection *bfdsec;
941 char *sname;
942 const char *prefix;
943
944 BFD_ASSERT ((command->type == BFD_MACH_O_LC_ID_DYLINKER)
945 || (command->type == BFD_MACH_O_LC_LOAD_DYLINKER));
946
947 bfd_seek (abfd, command->offset + 8, SEEK_SET);
948 if (bfd_bread ((PTR) buf, 4, abfd) != 4)
949 return -1;
950
951 nameoff = bfd_h_get_32 (abfd, buf + 0);
952
953 cmd->name_offset = command->offset + nameoff;
954 cmd->name_len = command->len - nameoff;
955
956 if (command->type == BFD_MACH_O_LC_LOAD_DYLINKER)
957 prefix = "LC_LOAD_DYLINKER";
958 else if (command->type == BFD_MACH_O_LC_ID_DYLINKER)
959 prefix = "LC_ID_DYLINKER";
960 else
961 abort ();
962
963 sname = bfd_alloc (abfd, strlen (prefix) + 1);
964 if (sname == NULL)
965 return -1;
966 strcpy (sname, prefix);
967
968 bfdsec = bfd_make_section_anyway (abfd, sname);
969 if (bfdsec == NULL)
970 return -1;
971
972 bfdsec->vma = 0;
973 bfdsec->lma = 0;
974 bfdsec->size = command->len - 8;
975 bfdsec->filepos = command->offset + 8;
976 bfdsec->alignment_power = 0;
977 bfdsec->flags = SEC_HAS_CONTENTS;
978
979 cmd->section = bfdsec;
980
981 return 0;
982 }
983
984 static int
985 bfd_mach_o_scan_read_dylib (bfd *abfd, bfd_mach_o_load_command *command)
986 {
987 bfd_mach_o_dylib_command *cmd = &command->command.dylib;
988 unsigned char buf[16];
989 unsigned int nameoff;
990 asection *bfdsec;
991 char *sname;
992 const char *prefix;
993
994 BFD_ASSERT ((command->type == BFD_MACH_O_LC_ID_DYLIB)
995 || (command->type == BFD_MACH_O_LC_LOAD_DYLIB)
996 || (command->type == BFD_MACH_O_LC_LOAD_WEAK_DYLIB));
997
998 bfd_seek (abfd, command->offset + 8, SEEK_SET);
999 if (bfd_bread ((PTR) buf, 16, abfd) != 16)
1000 return -1;
1001
1002 nameoff = bfd_h_get_32 (abfd, buf + 0);
1003 cmd->timestamp = bfd_h_get_32 (abfd, buf + 4);
1004 cmd->current_version = bfd_h_get_32 (abfd, buf + 8);
1005 cmd->compatibility_version = bfd_h_get_32 (abfd, buf + 12);
1006
1007 cmd->name_offset = command->offset + nameoff;
1008 cmd->name_len = command->len - nameoff;
1009
1010 if (command->type == BFD_MACH_O_LC_LOAD_DYLIB)
1011 prefix = "LC_LOAD_DYLIB";
1012 else if (command->type == BFD_MACH_O_LC_LOAD_WEAK_DYLIB)
1013 prefix = "LC_LOAD_WEAK_DYLIB";
1014 else if (command->type == BFD_MACH_O_LC_ID_DYLIB)
1015 prefix = "LC_ID_DYLIB";
1016 else
1017 abort ();
1018
1019 sname = bfd_alloc (abfd, strlen (prefix) + 1);
1020 if (sname == NULL)
1021 return -1;
1022 strcpy (sname, prefix);
1023
1024 bfdsec = bfd_make_section_anyway (abfd, sname);
1025 if (bfdsec == NULL)
1026 return -1;
1027
1028 bfdsec->vma = 0;
1029 bfdsec->lma = 0;
1030 bfdsec->size = command->len - 8;
1031 bfdsec->filepos = command->offset + 8;
1032 bfdsec->alignment_power = 0;
1033 bfdsec->flags = SEC_HAS_CONTENTS;
1034
1035 cmd->section = bfdsec;
1036
1037 return 0;
1038 }
1039
1040 static int
1041 bfd_mach_o_scan_read_prebound_dylib (bfd *abfd ATTRIBUTE_UNUSED,
1042 bfd_mach_o_load_command *command ATTRIBUTE_UNUSED)
1043 {
1044 /* bfd_mach_o_prebound_dylib_command *cmd = &command->command.prebound_dylib; */
1045
1046 BFD_ASSERT (command->type == BFD_MACH_O_LC_PREBOUND_DYLIB);
1047 return 0;
1048 }
1049
1050 static int
1051 bfd_mach_o_scan_read_thread (bfd *abfd, bfd_mach_o_load_command *command)
1052 {
1053 bfd_mach_o_data_struct *mdata = NULL;
1054 bfd_mach_o_thread_command *cmd = &command->command.thread;
1055 unsigned char buf[8];
1056 bfd_vma offset;
1057 unsigned int nflavours;
1058 unsigned int i;
1059
1060 BFD_ASSERT ((command->type == BFD_MACH_O_LC_THREAD)
1061 || (command->type == BFD_MACH_O_LC_UNIXTHREAD));
1062
1063 BFD_ASSERT (bfd_mach_o_valid (abfd));
1064 mdata = abfd->tdata.mach_o_data;
1065
1066 offset = 8;
1067 nflavours = 0;
1068 while (offset != command->len)
1069 {
1070 if (offset >= command->len)
1071 return -1;
1072
1073 bfd_seek (abfd, command->offset + offset, SEEK_SET);
1074
1075 if (bfd_bread ((PTR) buf, 8, abfd) != 8)
1076 return -1;
1077
1078 offset += 8 + bfd_h_get_32 (abfd, buf + 4) * 4;
1079 nflavours++;
1080 }
1081
1082 cmd->flavours = bfd_alloc (abfd, nflavours * sizeof (bfd_mach_o_thread_flavour));
1083 if (cmd->flavours == NULL)
1084 return -1;
1085 cmd->nflavours = nflavours;
1086
1087 offset = 8;
1088 nflavours = 0;
1089 while (offset != command->len)
1090 {
1091 if (offset >= command->len)
1092 return -1;
1093
1094 if (nflavours >= cmd->nflavours)
1095 return -1;
1096
1097 bfd_seek (abfd, command->offset + offset, SEEK_SET);
1098
1099 if (bfd_bread ((PTR) buf, 8, abfd) != 8)
1100 return -1;
1101
1102 cmd->flavours[nflavours].flavour = bfd_h_get_32 (abfd, buf);
1103 cmd->flavours[nflavours].offset = command->offset + offset + 8;
1104 cmd->flavours[nflavours].size = bfd_h_get_32 (abfd, buf + 4) * 4;
1105 offset += cmd->flavours[nflavours].size + 8;
1106 nflavours++;
1107 }
1108
1109 for (i = 0; i < nflavours; i++)
1110 {
1111 asection *bfdsec;
1112 unsigned int snamelen;
1113 char *sname;
1114 const char *flavourstr;
1115 const char *prefix = "LC_THREAD";
1116 unsigned int j = 0;
1117
1118 switch (mdata->header.cputype)
1119 {
1120 case BFD_MACH_O_CPU_TYPE_POWERPC:
1121 flavourstr = bfd_mach_o_ppc_flavour_string (cmd->flavours[i].flavour);
1122 break;
1123 case BFD_MACH_O_CPU_TYPE_I386:
1124 flavourstr = bfd_mach_o_i386_flavour_string (cmd->flavours[i].flavour);
1125 break;
1126 default:
1127 flavourstr = "UNKNOWN_ARCHITECTURE";
1128 break;
1129 }
1130
1131 snamelen = strlen (prefix) + 1 + 20 + 1 + strlen (flavourstr) + 1;
1132 sname = bfd_alloc (abfd, snamelen);
1133 if (sname == NULL)
1134 return -1;
1135
1136 for (;;)
1137 {
1138 sprintf (sname, "%s.%s.%u", prefix, flavourstr, j);
1139 if (bfd_get_section_by_name (abfd, sname) == NULL)
1140 break;
1141 j++;
1142 }
1143
1144 bfdsec = bfd_make_section (abfd, sname);
1145
1146 bfdsec->vma = 0;
1147 bfdsec->lma = 0;
1148 bfdsec->size = cmd->flavours[i].size;
1149 bfdsec->filepos = cmd->flavours[i].offset;
1150 bfdsec->alignment_power = 0x0;
1151 bfdsec->flags = SEC_HAS_CONTENTS;
1152
1153 cmd->section = bfdsec;
1154 }
1155
1156 return 0;
1157 }
1158
1159 static int
1160 bfd_mach_o_scan_read_dysymtab (bfd *abfd, bfd_mach_o_load_command *command)
1161 {
1162 bfd_mach_o_dysymtab_command *seg = &command->command.dysymtab;
1163 unsigned char buf[72];
1164
1165 BFD_ASSERT (command->type == BFD_MACH_O_LC_DYSYMTAB);
1166
1167 bfd_seek (abfd, command->offset + 8, SEEK_SET);
1168 if (bfd_bread ((PTR) buf, 72, abfd) != 72)
1169 return -1;
1170
1171 seg->ilocalsym = bfd_h_get_32 (abfd, buf + 0);
1172 seg->nlocalsym = bfd_h_get_32 (abfd, buf + 4);
1173 seg->iextdefsym = bfd_h_get_32 (abfd, buf + 8);
1174 seg->nextdefsym = bfd_h_get_32 (abfd, buf + 12);
1175 seg->iundefsym = bfd_h_get_32 (abfd, buf + 16);
1176 seg->nundefsym = bfd_h_get_32 (abfd, buf + 20);
1177 seg->tocoff = bfd_h_get_32 (abfd, buf + 24);
1178 seg->ntoc = bfd_h_get_32 (abfd, buf + 28);
1179 seg->modtaboff = bfd_h_get_32 (abfd, buf + 32);
1180 seg->nmodtab = bfd_h_get_32 (abfd, buf + 36);
1181 seg->extrefsymoff = bfd_h_get_32 (abfd, buf + 40);
1182 seg->nextrefsyms = bfd_h_get_32 (abfd, buf + 44);
1183 seg->indirectsymoff = bfd_h_get_32 (abfd, buf + 48);
1184 seg->nindirectsyms = bfd_h_get_32 (abfd, buf + 52);
1185 seg->extreloff = bfd_h_get_32 (abfd, buf + 56);
1186 seg->nextrel = bfd_h_get_32 (abfd, buf + 60);
1187 seg->locreloff = bfd_h_get_32 (abfd, buf + 64);
1188 seg->nlocrel = bfd_h_get_32 (abfd, buf + 68);
1189
1190 return 0;
1191 }
1192
1193 static int
1194 bfd_mach_o_scan_read_symtab (bfd *abfd, bfd_mach_o_load_command *command)
1195 {
1196 bfd_mach_o_symtab_command *seg = &command->command.symtab;
1197 unsigned char buf[16];
1198 asection *bfdsec;
1199 char *sname;
1200 const char *prefix = "LC_SYMTAB.stabs";
1201
1202 BFD_ASSERT (command->type == BFD_MACH_O_LC_SYMTAB);
1203
1204 bfd_seek (abfd, command->offset + 8, SEEK_SET);
1205 if (bfd_bread ((PTR) buf, 16, abfd) != 16)
1206 return -1;
1207
1208 seg->symoff = bfd_h_get_32 (abfd, buf);
1209 seg->nsyms = bfd_h_get_32 (abfd, buf + 4);
1210 seg->stroff = bfd_h_get_32 (abfd, buf + 8);
1211 seg->strsize = bfd_h_get_32 (abfd, buf + 12);
1212 seg->symbols = NULL;
1213 seg->strtab = NULL;
1214
1215 sname = bfd_alloc (abfd, strlen (prefix) + 1);
1216 if (sname == NULL)
1217 return -1;
1218 strcpy (sname, prefix);
1219
1220 bfdsec = bfd_make_section_anyway (abfd, sname);
1221 if (bfdsec == NULL)
1222 return -1;
1223
1224 bfdsec->vma = 0;
1225 bfdsec->lma = 0;
1226 bfdsec->size = seg->nsyms * 12;
1227 bfdsec->filepos = seg->symoff;
1228 bfdsec->alignment_power = 0;
1229 bfdsec->flags = SEC_HAS_CONTENTS;
1230
1231 seg->stabs_segment = bfdsec;
1232
1233 prefix = "LC_SYMTAB.stabstr";
1234 sname = bfd_alloc (abfd, strlen (prefix) + 1);
1235 if (sname == NULL)
1236 return -1;
1237 strcpy (sname, prefix);
1238
1239 bfdsec = bfd_make_section_anyway (abfd, sname);
1240 if (bfdsec == NULL)
1241 return -1;
1242
1243 bfdsec->vma = 0;
1244 bfdsec->lma = 0;
1245 bfdsec->size = seg->strsize;
1246 bfdsec->filepos = seg->stroff;
1247 bfdsec->alignment_power = 0;
1248 bfdsec->flags = SEC_HAS_CONTENTS;
1249
1250 seg->stabstr_segment = bfdsec;
1251
1252 return 0;
1253 }
1254
1255 static int
1256 bfd_mach_o_scan_read_segment (bfd *abfd, bfd_mach_o_load_command *command)
1257 {
1258 unsigned char buf[48];
1259 bfd_mach_o_segment_command *seg = &command->command.segment;
1260 unsigned long i;
1261 asection *bfdsec;
1262 char *sname;
1263 const char *prefix = "LC_SEGMENT";
1264 unsigned int snamelen;
1265
1266 BFD_ASSERT (command->type == BFD_MACH_O_LC_SEGMENT);
1267
1268 bfd_seek (abfd, command->offset + 8, SEEK_SET);
1269 if (bfd_bread ((PTR) buf, 48, abfd) != 48)
1270 return -1;
1271
1272 memcpy (seg->segname, buf, 16);
1273 seg->vmaddr = bfd_h_get_32 (abfd, buf + 16);
1274 seg->vmsize = bfd_h_get_32 (abfd, buf + 20);
1275 seg->fileoff = bfd_h_get_32 (abfd, buf + 24);
1276 seg->filesize = bfd_h_get_32 (abfd, buf + 28);
1277 /* seg->maxprot = bfd_h_get_32 (abfd, buf + 32); */
1278 /* seg->initprot = bfd_h_get_32 (abfd, buf + 36); */
1279 seg->nsects = bfd_h_get_32 (abfd, buf + 40);
1280 seg->flags = bfd_h_get_32 (abfd, buf + 44);
1281
1282 snamelen = strlen (prefix) + 1 + strlen (seg->segname) + 1;
1283 sname = bfd_alloc (abfd, snamelen);
1284 if (sname == NULL)
1285 return -1;
1286 sprintf (sname, "%s.%s", prefix, seg->segname);
1287
1288 bfdsec = bfd_make_section_anyway (abfd, sname);
1289 if (bfdsec == NULL)
1290 return -1;
1291
1292 bfdsec->vma = seg->vmaddr;
1293 bfdsec->lma = seg->vmaddr;
1294 bfdsec->size = seg->filesize;
1295 bfdsec->filepos = seg->fileoff;
1296 bfdsec->alignment_power = 0x0;
1297 bfdsec->flags = SEC_HAS_CONTENTS | SEC_LOAD | SEC_ALLOC | SEC_CODE;
1298
1299 seg->segment = bfdsec;
1300
1301 if (seg->nsects != 0)
1302 {
1303 seg->sections = bfd_alloc (abfd, seg->nsects * sizeof (bfd_mach_o_section));
1304 if (seg->sections == NULL)
1305 return -1;
1306
1307 for (i = 0; i < seg->nsects; i++)
1308 {
1309 bfd_vma segoff = command->offset + 48 + 8 + (i * 68);
1310
1311 if (bfd_mach_o_scan_read_section (abfd, &seg->sections[i],
1312 segoff) != 0)
1313 return -1;
1314 }
1315 }
1316
1317 return 0;
1318 }
1319
1320 static int
1321 bfd_mach_o_scan_read_command (bfd *abfd, bfd_mach_o_load_command *command)
1322 {
1323 unsigned char buf[8];
1324
1325 bfd_seek (abfd, command->offset, SEEK_SET);
1326 if (bfd_bread ((PTR) buf, 8, abfd) != 8)
1327 return -1;
1328
1329 command->type = (bfd_h_get_32 (abfd, buf) & ~BFD_MACH_O_LC_REQ_DYLD);
1330 command->type_required = (bfd_h_get_32 (abfd, buf) & BFD_MACH_O_LC_REQ_DYLD
1331 ? 1 : 0);
1332 command->len = bfd_h_get_32 (abfd, buf + 4);
1333
1334 switch (command->type)
1335 {
1336 case BFD_MACH_O_LC_SEGMENT:
1337 if (bfd_mach_o_scan_read_segment (abfd, command) != 0)
1338 return -1;
1339 break;
1340 case BFD_MACH_O_LC_SYMTAB:
1341 if (bfd_mach_o_scan_read_symtab (abfd, command) != 0)
1342 return -1;
1343 break;
1344 case BFD_MACH_O_LC_SYMSEG:
1345 break;
1346 case BFD_MACH_O_LC_THREAD:
1347 case BFD_MACH_O_LC_UNIXTHREAD:
1348 if (bfd_mach_o_scan_read_thread (abfd, command) != 0)
1349 return -1;
1350 break;
1351 case BFD_MACH_O_LC_LOAD_DYLINKER:
1352 case BFD_MACH_O_LC_ID_DYLINKER:
1353 if (bfd_mach_o_scan_read_dylinker (abfd, command) != 0)
1354 return -1;
1355 break;
1356 case BFD_MACH_O_LC_LOAD_DYLIB:
1357 case BFD_MACH_O_LC_ID_DYLIB:
1358 case BFD_MACH_O_LC_LOAD_WEAK_DYLIB:
1359 if (bfd_mach_o_scan_read_dylib (abfd, command) != 0)
1360 return -1;
1361 break;
1362 case BFD_MACH_O_LC_PREBOUND_DYLIB:
1363 if (bfd_mach_o_scan_read_prebound_dylib (abfd, command) != 0)
1364 return -1;
1365 break;
1366 case BFD_MACH_O_LC_LOADFVMLIB:
1367 case BFD_MACH_O_LC_IDFVMLIB:
1368 case BFD_MACH_O_LC_IDENT:
1369 case BFD_MACH_O_LC_FVMFILE:
1370 case BFD_MACH_O_LC_PREPAGE:
1371 case BFD_MACH_O_LC_ROUTINES:
1372 case BFD_MACH_O_LC_SUB_FRAMEWORK:
1373 break;
1374 case BFD_MACH_O_LC_DYSYMTAB:
1375 if (bfd_mach_o_scan_read_dysymtab (abfd, command) != 0)
1376 return -1;
1377 break;
1378 case BFD_MACH_O_LC_SUB_UMBRELLA:
1379 case BFD_MACH_O_LC_SUB_CLIENT:
1380 case BFD_MACH_O_LC_SUB_LIBRARY:
1381 case BFD_MACH_O_LC_TWOLEVEL_HINTS:
1382 case BFD_MACH_O_LC_PREBIND_CKSUM:
1383 break;
1384 default:
1385 fprintf (stderr, "unable to read unknown load command 0x%lx\n",
1386 (unsigned long) command->type);
1387 break;
1388 }
1389
1390 return 0;
1391 }
1392
1393 static void
1394 bfd_mach_o_flatten_sections (bfd *abfd)
1395 {
1396 bfd_mach_o_data_struct *mdata = abfd->tdata.mach_o_data;
1397 long csect = 0;
1398 unsigned long i, j;
1399
1400 mdata->nsects = 0;
1401
1402 for (i = 0; i < mdata->header.ncmds; i++)
1403 {
1404 if (mdata->commands[i].type == BFD_MACH_O_LC_SEGMENT)
1405 {
1406 bfd_mach_o_segment_command *seg;
1407
1408 seg = &mdata->commands[i].command.segment;
1409 mdata->nsects += seg->nsects;
1410 }
1411 }
1412
1413 mdata->sections = bfd_alloc (abfd,
1414 mdata->nsects * sizeof (bfd_mach_o_section *));
1415 csect = 0;
1416
1417 for (i = 0; i < mdata->header.ncmds; i++)
1418 {
1419 if (mdata->commands[i].type == BFD_MACH_O_LC_SEGMENT)
1420 {
1421 bfd_mach_o_segment_command *seg;
1422
1423 seg = &mdata->commands[i].command.segment;
1424 BFD_ASSERT (csect + seg->nsects <= mdata->nsects);
1425
1426 for (j = 0; j < seg->nsects; j++)
1427 mdata->sections[csect++] = &seg->sections[j];
1428 }
1429 }
1430 }
1431
1432 int
1433 bfd_mach_o_scan_start_address (bfd *abfd)
1434 {
1435 bfd_mach_o_data_struct *mdata = abfd->tdata.mach_o_data;
1436 bfd_mach_o_thread_command *cmd = NULL;
1437 unsigned long i;
1438
1439 for (i = 0; i < mdata->header.ncmds; i++)
1440 {
1441 if ((mdata->commands[i].type == BFD_MACH_O_LC_THREAD) ||
1442 (mdata->commands[i].type == BFD_MACH_O_LC_UNIXTHREAD))
1443 {
1444 if (cmd == NULL)
1445 cmd = &mdata->commands[i].command.thread;
1446 else
1447 return 0;
1448 }
1449 }
1450
1451 if (cmd == NULL)
1452 return 0;
1453
1454 for (i = 0; i < cmd->nflavours; i++)
1455 {
1456 if ((mdata->header.cputype == BFD_MACH_O_CPU_TYPE_I386)
1457 && (cmd->flavours[i].flavour
1458 == (unsigned long) BFD_MACH_O_i386_THREAD_STATE))
1459 {
1460 unsigned char buf[4];
1461
1462 bfd_seek (abfd, cmd->flavours[i].offset + 40, SEEK_SET);
1463
1464 if (bfd_bread (buf, 4, abfd) != 4)
1465 return -1;
1466
1467 abfd->start_address = bfd_h_get_32 (abfd, buf);
1468 }
1469 else if ((mdata->header.cputype == BFD_MACH_O_CPU_TYPE_POWERPC)
1470 && (cmd->flavours[i].flavour == BFD_MACH_O_PPC_THREAD_STATE))
1471 {
1472 unsigned char buf[4];
1473
1474 bfd_seek (abfd, cmd->flavours[i].offset + 0, SEEK_SET);
1475
1476 if (bfd_bread (buf, 4, abfd) != 4)
1477 return -1;
1478
1479 abfd->start_address = bfd_h_get_32 (abfd, buf);
1480 }
1481 }
1482
1483 return 0;
1484 }
1485
1486 int
1487 bfd_mach_o_scan (bfd *abfd,
1488 bfd_mach_o_header *header,
1489 bfd_mach_o_data_struct *mdata)
1490 {
1491 unsigned int i;
1492 enum bfd_architecture cputype;
1493 unsigned long cpusubtype;
1494
1495 mdata->header = *header;
1496 mdata->symbols = NULL;
1497
1498 abfd->flags = (abfd->xvec->object_flags
1499 | (abfd->flags & (BFD_IN_MEMORY | BFD_IO_FUNCS)));
1500 abfd->tdata.mach_o_data = mdata;
1501
1502 bfd_mach_o_convert_architecture (header->cputype, header->cpusubtype,
1503 &cputype, &cpusubtype);
1504 if (cputype == bfd_arch_unknown)
1505 {
1506 fprintf (stderr, "bfd_mach_o_scan: unknown architecture 0x%lx/0x%lx\n",
1507 header->cputype, header->cpusubtype);
1508 return -1;
1509 }
1510
1511 bfd_set_arch_mach (abfd, cputype, cpusubtype);
1512
1513 if (header->ncmds != 0)
1514 {
1515 mdata->commands = bfd_alloc (abfd, header->ncmds * sizeof (bfd_mach_o_load_command));
1516 if (mdata->commands == NULL)
1517 return -1;
1518
1519 for (i = 0; i < header->ncmds; i++)
1520 {
1521 bfd_mach_o_load_command *cur = &mdata->commands[i];
1522
1523 if (i == 0)
1524 cur->offset = 28;
1525 else
1526 {
1527 bfd_mach_o_load_command *prev = &mdata->commands[i - 1];
1528 cur->offset = prev->offset + prev->len;
1529 }
1530
1531 if (bfd_mach_o_scan_read_command (abfd, cur) < 0)
1532 return -1;
1533 }
1534 }
1535
1536 if (bfd_mach_o_scan_start_address (abfd) < 0)
1537 return -1;
1538
1539 bfd_mach_o_flatten_sections (abfd);
1540 return 0;
1541 }
1542
1543 bfd_boolean
1544 bfd_mach_o_mkobject (bfd *abfd)
1545 {
1546 bfd_mach_o_data_struct *mdata = NULL;
1547
1548 mdata = bfd_alloc (abfd, sizeof (bfd_mach_o_data_struct));
1549 if (mdata == NULL)
1550 return FALSE;
1551 abfd->tdata.mach_o_data = mdata;
1552
1553 mdata->header.magic = 0;
1554 mdata->header.cputype = 0;
1555 mdata->header.cpusubtype = 0;
1556 mdata->header.filetype = 0;
1557 mdata->header.ncmds = 0;
1558 mdata->header.sizeofcmds = 0;
1559 mdata->header.flags = 0;
1560 mdata->header.byteorder = BFD_ENDIAN_UNKNOWN;
1561 mdata->commands = NULL;
1562 mdata->nsymbols = 0;
1563 mdata->symbols = NULL;
1564 mdata->nsects = 0;
1565 mdata->sections = NULL;
1566 mdata->ibfd = NULL;
1567
1568 return TRUE;
1569 }
1570
1571 const bfd_target *
1572 bfd_mach_o_object_p (bfd *abfd)
1573 {
1574 struct bfd_preserve preserve;
1575 bfd_mach_o_header header;
1576
1577 preserve.marker = NULL;
1578 if (bfd_mach_o_read_header (abfd, &header) != 0)
1579 goto wrong;
1580
1581 if (! (header.byteorder == BFD_ENDIAN_BIG
1582 || header.byteorder == BFD_ENDIAN_LITTLE))
1583 {
1584 fprintf (stderr, "unknown header byte-order value 0x%lx\n",
1585 (long) header.byteorder);
1586 goto wrong;
1587 }
1588
1589 if (! ((header.byteorder == BFD_ENDIAN_BIG
1590 && abfd->xvec->byteorder == BFD_ENDIAN_BIG
1591 && abfd->xvec->header_byteorder == BFD_ENDIAN_BIG)
1592 || (header.byteorder == BFD_ENDIAN_LITTLE
1593 && abfd->xvec->byteorder == BFD_ENDIAN_LITTLE
1594 && abfd->xvec->header_byteorder == BFD_ENDIAN_LITTLE)))
1595 goto wrong;
1596
1597 preserve.marker = bfd_zalloc (abfd, sizeof (bfd_mach_o_data_struct));
1598 if (preserve.marker == NULL
1599 || !bfd_preserve_save (abfd, &preserve))
1600 goto fail;
1601
1602 if (bfd_mach_o_scan (abfd, &header,
1603 (bfd_mach_o_data_struct *) preserve.marker) != 0)
1604 goto wrong;
1605
1606 bfd_preserve_finish (abfd, &preserve);
1607 return abfd->xvec;
1608
1609 wrong:
1610 bfd_set_error (bfd_error_wrong_format);
1611
1612 fail:
1613 if (preserve.marker != NULL)
1614 bfd_preserve_restore (abfd, &preserve);
1615 return NULL;
1616 }
1617
1618 const bfd_target *
1619 bfd_mach_o_core_p (bfd *abfd)
1620 {
1621 struct bfd_preserve preserve;
1622 bfd_mach_o_header header;
1623
1624 preserve.marker = NULL;
1625 if (bfd_mach_o_read_header (abfd, &header) != 0)
1626 goto wrong;
1627
1628 if (! (header.byteorder == BFD_ENDIAN_BIG
1629 || header.byteorder == BFD_ENDIAN_LITTLE))
1630 {
1631 fprintf (stderr, "unknown header byte-order value 0x%lx\n",
1632 (long) header.byteorder);
1633 abort ();
1634 }
1635
1636 if (! ((header.byteorder == BFD_ENDIAN_BIG
1637 && abfd->xvec->byteorder == BFD_ENDIAN_BIG
1638 && abfd->xvec->header_byteorder == BFD_ENDIAN_BIG)
1639 || (header.byteorder == BFD_ENDIAN_LITTLE
1640 && abfd->xvec->byteorder == BFD_ENDIAN_LITTLE
1641 && abfd->xvec->header_byteorder == BFD_ENDIAN_LITTLE)))
1642 goto wrong;
1643
1644 if (header.filetype != BFD_MACH_O_MH_CORE)
1645 goto wrong;
1646
1647 preserve.marker = bfd_zalloc (abfd, sizeof (bfd_mach_o_data_struct));
1648 if (preserve.marker == NULL
1649 || !bfd_preserve_save (abfd, &preserve))
1650 goto fail;
1651
1652 if (bfd_mach_o_scan (abfd, &header,
1653 (bfd_mach_o_data_struct *) preserve.marker) != 0)
1654 goto wrong;
1655
1656 bfd_preserve_finish (abfd, &preserve);
1657 return abfd->xvec;
1658
1659 wrong:
1660 bfd_set_error (bfd_error_wrong_format);
1661
1662 fail:
1663 if (preserve.marker != NULL)
1664 bfd_preserve_restore (abfd, &preserve);
1665 return NULL;
1666 }
1667
1668 typedef struct mach_o_fat_archentry
1669 {
1670 unsigned long cputype;
1671 unsigned long cpusubtype;
1672 unsigned long offset;
1673 unsigned long size;
1674 unsigned long align;
1675 bfd *abfd;
1676 } mach_o_fat_archentry;
1677
1678 typedef struct mach_o_fat_data_struct
1679 {
1680 unsigned long magic;
1681 unsigned long nfat_arch;
1682 mach_o_fat_archentry *archentries;
1683 } mach_o_fat_data_struct;
1684
1685 const bfd_target *
1686 bfd_mach_o_archive_p (bfd *abfd)
1687 {
1688 mach_o_fat_data_struct *adata = NULL;
1689 unsigned char buf[20];
1690 unsigned long i;
1691
1692 bfd_seek (abfd, 0, SEEK_SET);
1693 if (bfd_bread ((PTR) buf, 8, abfd) != 8)
1694 goto error;
1695
1696 adata = bfd_alloc (abfd, sizeof (mach_o_fat_data_struct));
1697 if (adata == NULL)
1698 goto error;
1699
1700 adata->magic = bfd_getb32 (buf);
1701 adata->nfat_arch = bfd_getb32 (buf + 4);
1702 if (adata->magic != 0xcafebabe)
1703 goto error;
1704
1705 adata->archentries =
1706 bfd_alloc (abfd, adata->nfat_arch * sizeof (mach_o_fat_archentry));
1707 if (adata->archentries == NULL)
1708 goto error;
1709
1710 for (i = 0; i < adata->nfat_arch; i++)
1711 {
1712 bfd_seek (abfd, 8 + 20 * i, SEEK_SET);
1713
1714 if (bfd_bread ((PTR) buf, 20, abfd) != 20)
1715 goto error;
1716 adata->archentries[i].cputype = bfd_getb32 (buf);
1717 adata->archentries[i].cpusubtype = bfd_getb32 (buf + 4);
1718 adata->archentries[i].offset = bfd_getb32 (buf + 8);
1719 adata->archentries[i].size = bfd_getb32 (buf + 12);
1720 adata->archentries[i].align = bfd_getb32 (buf + 16);
1721 adata->archentries[i].abfd = NULL;
1722 }
1723
1724 abfd->tdata.mach_o_fat_data = adata;
1725 return abfd->xvec;
1726
1727 error:
1728 if (adata != NULL)
1729 bfd_release (abfd, adata);
1730 bfd_set_error (bfd_error_wrong_format);
1731 return NULL;
1732 }
1733
1734 bfd *
1735 bfd_mach_o_openr_next_archived_file (bfd *archive, bfd *prev)
1736 {
1737 mach_o_fat_data_struct *adata;
1738 mach_o_fat_archentry *entry = NULL;
1739 unsigned long i;
1740
1741 adata = (mach_o_fat_data_struct *) archive->tdata.mach_o_fat_data;
1742 BFD_ASSERT (adata != NULL);
1743
1744 /* Find index of previous entry. */
1745 if (prev == NULL)
1746 i = 0; /* Start at first one. */
1747 else
1748 {
1749 for (i = 0; i < adata->nfat_arch; i++)
1750 {
1751 if (adata->archentries[i].abfd == prev)
1752 break;
1753 }
1754
1755 if (i == adata->nfat_arch)
1756 {
1757 /* Not found. */
1758 bfd_set_error (bfd_error_bad_value);
1759 return NULL;
1760 }
1761 i++; /* Get next entry. */
1762 }
1763
1764 if (i >= adata->nfat_arch)
1765 {
1766 bfd_set_error (bfd_error_no_more_archived_files);
1767 return NULL;
1768 }
1769
1770 entry = &adata->archentries[i];
1771 if (entry->abfd == NULL)
1772 {
1773 bfd *nbfd = _bfd_new_bfd_contained_in (archive);
1774 char *s = NULL;
1775
1776 if (nbfd == NULL)
1777 return NULL;
1778
1779 nbfd->origin = entry->offset;
1780 s = bfd_malloc (strlen (archive->filename) + 1);
1781 if (s == NULL)
1782 return NULL;
1783 strcpy (s, archive->filename);
1784 nbfd->filename = s;
1785 nbfd->iostream = NULL;
1786 entry->abfd = nbfd;
1787 }
1788
1789 return entry->abfd;
1790 }
1791
1792 int
1793 bfd_mach_o_lookup_section (bfd *abfd,
1794 asection *section,
1795 bfd_mach_o_load_command **mcommand,
1796 bfd_mach_o_section **msection)
1797 {
1798 struct mach_o_data_struct *md = abfd->tdata.mach_o_data;
1799 unsigned int i, j, num;
1800
1801 bfd_mach_o_load_command *ncmd = NULL;
1802 bfd_mach_o_section *nsect = NULL;
1803
1804 BFD_ASSERT (mcommand != NULL);
1805 BFD_ASSERT (msection != NULL);
1806
1807 num = 0;
1808 for (i = 0; i < md->header.ncmds; i++)
1809 {
1810 struct bfd_mach_o_load_command *cmd = &md->commands[i];
1811 struct bfd_mach_o_segment_command *seg = NULL;
1812
1813 if (cmd->type != BFD_MACH_O_LC_SEGMENT)
1814 continue;
1815 seg = &cmd->command.segment;
1816
1817 if (seg->segment == section)
1818 {
1819 if (num == 0)
1820 ncmd = cmd;
1821 num++;
1822 }
1823
1824 for (j = 0; j < seg->nsects; j++)
1825 {
1826 struct bfd_mach_o_section *sect = &seg->sections[j];
1827
1828 if (sect->bfdsection == section)
1829 {
1830 if (num == 0)
1831 nsect = sect;
1832 num++;
1833 }
1834 }
1835 }
1836
1837 *mcommand = ncmd;
1838 *msection = nsect;
1839 return num;
1840 }
1841
1842 int
1843 bfd_mach_o_lookup_command (bfd *abfd,
1844 bfd_mach_o_load_command_type type,
1845 bfd_mach_o_load_command **mcommand)
1846 {
1847 struct mach_o_data_struct *md = NULL;
1848 bfd_mach_o_load_command *ncmd = NULL;
1849 unsigned int i, num;
1850
1851 md = abfd->tdata.mach_o_data;
1852
1853 BFD_ASSERT (md != NULL);
1854 BFD_ASSERT (mcommand != NULL);
1855
1856 num = 0;
1857 for (i = 0; i < md->header.ncmds; i++)
1858 {
1859 struct bfd_mach_o_load_command *cmd = &md->commands[i];
1860
1861 if (cmd->type != type)
1862 continue;
1863
1864 if (num == 0)
1865 ncmd = cmd;
1866 num++;
1867 }
1868
1869 *mcommand = ncmd;
1870 return num;
1871 }
1872
1873 unsigned long
1874 bfd_mach_o_stack_addr (enum bfd_mach_o_cpu_type type)
1875 {
1876 switch (type)
1877 {
1878 case BFD_MACH_O_CPU_TYPE_MC680x0:
1879 return 0x04000000;
1880 case BFD_MACH_O_CPU_TYPE_MC88000:
1881 return 0xffffe000;
1882 case BFD_MACH_O_CPU_TYPE_POWERPC:
1883 return 0xc0000000;
1884 case BFD_MACH_O_CPU_TYPE_I386:
1885 return 0xc0000000;
1886 case BFD_MACH_O_CPU_TYPE_SPARC:
1887 return 0xf0000000;
1888 case BFD_MACH_O_CPU_TYPE_I860:
1889 return 0;
1890 case BFD_MACH_O_CPU_TYPE_HPPA:
1891 return 0xc0000000 - 0x04000000;
1892 default:
1893 return 0;
1894 }
1895 }
1896
1897 int
1898 bfd_mach_o_core_fetch_environment (bfd *abfd,
1899 unsigned char **rbuf,
1900 unsigned int *rlen)
1901 {
1902 bfd_mach_o_data_struct *mdata = abfd->tdata.mach_o_data;
1903 unsigned long stackaddr = bfd_mach_o_stack_addr (mdata->header.cputype);
1904 unsigned int i = 0;
1905
1906 for (i = 0; i < mdata->header.ncmds; i++)
1907 {
1908 bfd_mach_o_load_command *cur = &mdata->commands[i];
1909 bfd_mach_o_segment_command *seg = NULL;
1910
1911 if (cur->type != BFD_MACH_O_LC_SEGMENT)
1912 continue;
1913
1914 seg = &cur->command.segment;
1915
1916 if ((seg->vmaddr + seg->vmsize) == stackaddr)
1917 {
1918 unsigned long start = seg->fileoff;
1919 unsigned long end = seg->fileoff + seg->filesize;
1920 unsigned char *buf = bfd_malloc (1024);
1921 unsigned long size = 1024;
1922
1923 for (;;)
1924 {
1925 bfd_size_type nread = 0;
1926 unsigned long offset;
1927 int found_nonnull = 0;
1928
1929 if (size > (end - start))
1930 size = (end - start);
1931
1932 buf = bfd_realloc (buf, size);
1933
1934 bfd_seek (abfd, end - size, SEEK_SET);
1935 nread = bfd_bread (buf, size, abfd);
1936
1937 if (nread != size)
1938 return -1;
1939
1940 for (offset = 4; offset <= size; offset += 4)
1941 {
1942 unsigned long val;
1943
1944 val = *((unsigned long *) (buf + size - offset));
1945 if (! found_nonnull)
1946 {
1947 if (val != 0)
1948 found_nonnull = 1;
1949 }
1950 else if (val == 0x0)
1951 {
1952 unsigned long bottom;
1953 unsigned long top;
1954
1955 bottom = seg->fileoff + seg->filesize - offset;
1956 top = seg->fileoff + seg->filesize - 4;
1957 *rbuf = bfd_malloc (top - bottom);
1958 *rlen = top - bottom;
1959
1960 memcpy (*rbuf, buf + size - *rlen, *rlen);
1961 return 0;
1962 }
1963 }
1964
1965 if (size == (end - start))
1966 break;
1967
1968 size *= 2;
1969 }
1970 }
1971 }
1972
1973 return -1;
1974 }
1975
1976 char *
1977 bfd_mach_o_core_file_failing_command (bfd *abfd)
1978 {
1979 unsigned char *buf = NULL;
1980 unsigned int len = 0;
1981 int ret = -1;
1982
1983 ret = bfd_mach_o_core_fetch_environment (abfd, &buf, &len);
1984 if (ret < 0)
1985 return NULL;
1986
1987 return (char *) buf;
1988 }
1989
1990 int
1991 bfd_mach_o_core_file_failing_signal (bfd *abfd ATTRIBUTE_UNUSED)
1992 {
1993 return 0;
1994 }
1995
1996 bfd_boolean
1997 bfd_mach_o_core_file_matches_executable_p (bfd *core_bfd ATTRIBUTE_UNUSED,
1998 bfd *exec_bfd ATTRIBUTE_UNUSED)
1999 {
2000 return TRUE;
2001 }
2002
2003 #define TARGET_NAME mach_o_be_vec
2004 #define TARGET_STRING "mach-o-be"
2005 #define TARGET_BIG_ENDIAN 1
2006 #define TARGET_ARCHIVE 0
2007
2008 #include "mach-o-target.c"
2009
2010 #undef TARGET_NAME
2011 #undef TARGET_STRING
2012 #undef TARGET_BIG_ENDIAN
2013 #undef TARGET_ARCHIVE
2014
2015 #define TARGET_NAME mach_o_le_vec
2016 #define TARGET_STRING "mach-o-le"
2017 #define TARGET_BIG_ENDIAN 0
2018 #define TARGET_ARCHIVE 0
2019
2020 #include "mach-o-target.c"
2021
2022 #undef TARGET_NAME
2023 #undef TARGET_STRING
2024 #undef TARGET_BIG_ENDIAN
2025 #undef TARGET_ARCHIVE
2026
2027 #define TARGET_NAME mach_o_fat_vec
2028 #define TARGET_STRING "mach-o-fat"
2029 #define TARGET_BIG_ENDIAN 1
2030 #define TARGET_ARCHIVE 1
2031
2032 #include "mach-o-target.c"
2033
2034 #undef TARGET_NAME
2035 #undef TARGET_STRING
2036 #undef TARGET_BIG_ENDIAN
2037 #undef TARGET_ARCHIVE
This page took 0.072424 seconds and 4 git commands to generate.