2011-12-05 Tristan Gingold <gingold@adacore.com>
[binutils-gdb.git] / bfd / mach-o.c
1 /* Mach-O support for BFD.
2 Copyright 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008,
3 2009, 2010, 2011
4 Free Software Foundation, Inc.
5
6 This file is part of BFD, the Binary File Descriptor library.
7
8 This program is free software; you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
10 the Free Software Foundation; either version 3 of the License, or
11 (at your option) any later version.
12
13 This program is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
17
18 You should have received a copy of the GNU General Public License
19 along with this program; if not, write to the Free Software
20 Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
21 MA 02110-1301, USA. */
22
23 #include "sysdep.h"
24 #include "mach-o.h"
25 #include "bfd.h"
26 #include "libbfd.h"
27 #include "libiberty.h"
28 #include "aout/stab_gnu.h"
29 #include "mach-o/reloc.h"
30 #include "mach-o/external.h"
31 #include <ctype.h>
32
33 #define bfd_mach_o_object_p bfd_mach_o_gen_object_p
34 #define bfd_mach_o_core_p bfd_mach_o_gen_core_p
35 #define bfd_mach_o_mkobject bfd_mach_o_gen_mkobject
36
37 #define FILE_ALIGN(off, algn) \
38 (((off) + ((file_ptr) 1 << (algn)) - 1) & ((file_ptr) -1 << (algn)))
39
40 static int bfd_mach_o_read_symtab_symbols (bfd *);
41
42 unsigned int
43 bfd_mach_o_version (bfd *abfd)
44 {
45 bfd_mach_o_data_struct *mdata = NULL;
46
47 BFD_ASSERT (bfd_mach_o_valid (abfd));
48 mdata = bfd_mach_o_get_data (abfd);
49
50 return mdata->header.version;
51 }
52
53 bfd_boolean
54 bfd_mach_o_valid (bfd *abfd)
55 {
56 if (abfd == NULL || abfd->xvec == NULL)
57 return FALSE;
58
59 if (abfd->xvec->flavour != bfd_target_mach_o_flavour)
60 return FALSE;
61
62 if (bfd_mach_o_get_data (abfd) == NULL)
63 return FALSE;
64 return TRUE;
65 }
66
67 static INLINE bfd_boolean
68 mach_o_wide_p (bfd_mach_o_header *header)
69 {
70 switch (header->version)
71 {
72 case 1:
73 return FALSE;
74 case 2:
75 return TRUE;
76 default:
77 BFD_FAIL ();
78 return FALSE;
79 }
80 }
81
82 static INLINE bfd_boolean
83 bfd_mach_o_wide_p (bfd *abfd)
84 {
85 return mach_o_wide_p (&bfd_mach_o_get_data (abfd)->header);
86 }
87
88 /* Tables to translate well known Mach-O segment/section names to bfd
89 names. Use of canonical names (such as .text or .debug_frame) is required
90 by gdb. */
91
92 struct mach_o_section_name_xlat
93 {
94 const char *bfd_name;
95 const char *mach_o_name;
96 flagword flags;
97 };
98
99 static const struct mach_o_section_name_xlat dwarf_section_names_xlat[] =
100 {
101 { ".debug_frame", "__debug_frame", SEC_DEBUGGING },
102 { ".debug_info", "__debug_info", SEC_DEBUGGING },
103 { ".debug_abbrev", "__debug_abbrev", SEC_DEBUGGING },
104 { ".debug_aranges", "__debug_aranges", SEC_DEBUGGING },
105 { ".debug_macinfo", "__debug_macinfo", SEC_DEBUGGING },
106 { ".debug_line", "__debug_line", SEC_DEBUGGING },
107 { ".debug_loc", "__debug_loc", SEC_DEBUGGING },
108 { ".debug_pubnames", "__debug_pubnames", SEC_DEBUGGING },
109 { ".debug_pubtypes", "__debug_pubtypes", SEC_DEBUGGING },
110 { ".debug_str", "__debug_str", SEC_DEBUGGING },
111 { ".debug_ranges", "__debug_ranges", SEC_DEBUGGING },
112 { NULL, NULL, 0}
113 };
114
115 static const struct mach_o_section_name_xlat text_section_names_xlat[] =
116 {
117 { ".text", "__text", SEC_CODE | SEC_LOAD },
118 { ".const", "__const", SEC_READONLY | SEC_DATA | SEC_LOAD },
119 { ".cstring", "__cstring", SEC_READONLY | SEC_DATA | SEC_LOAD },
120 { ".eh_frame", "__eh_frame", SEC_READONLY | SEC_LOAD },
121 { NULL, NULL, 0}
122 };
123
124 static const struct mach_o_section_name_xlat data_section_names_xlat[] =
125 {
126 { ".data", "__data", SEC_DATA | SEC_LOAD },
127 { ".const_data", "__const", SEC_DATA | SEC_LOAD },
128 { ".dyld", "__dyld", SEC_DATA | SEC_LOAD },
129 { ".lazy_symbol_ptr", "__la_symbol_ptr", SEC_DATA | SEC_LOAD },
130 { ".non_lazy_symbol_ptr", "__nl_symbol_ptr", SEC_DATA | SEC_LOAD },
131 { ".bss", "__bss", SEC_NO_FLAGS },
132 { NULL, NULL, 0}
133 };
134
135 struct mach_o_segment_name_xlat
136 {
137 /* Segment name. */
138 const char *segname;
139
140 /* List of known sections for the segment. */
141 const struct mach_o_section_name_xlat *sections;
142 };
143
144 /* List of known segment names. */
145
146 static const struct mach_o_segment_name_xlat segsec_names_xlat[] =
147 {
148 { "__TEXT", text_section_names_xlat },
149 { "__DATA", data_section_names_xlat },
150 { "__DWARF", dwarf_section_names_xlat },
151 { NULL, NULL }
152 };
153
154 /* Mach-O to bfd names. */
155
156 void
157 bfd_mach_o_normalize_section_name (const char *segname, const char *sectname,
158 const char **name, flagword *flags)
159 {
160 const struct mach_o_segment_name_xlat *seg;
161
162 *name = NULL;
163 *flags = SEC_NO_FLAGS;
164
165 for (seg = segsec_names_xlat; seg->segname; seg++)
166 {
167 if (strncmp (seg->segname, segname, BFD_MACH_O_SEGNAME_SIZE) == 0)
168 {
169 const struct mach_o_section_name_xlat *sec;
170
171 for (sec = seg->sections; sec->mach_o_name; sec++)
172 {
173 if (strncmp (sec->mach_o_name, sectname,
174 BFD_MACH_O_SECTNAME_SIZE) == 0)
175 {
176 *name = sec->bfd_name;
177 *flags = sec->flags;
178 return;
179 }
180 }
181 return;
182 }
183 }
184 }
185
186 /* Convert Mach-O section name to BFD. Try to use standard names, otherwise
187 forge a new name. SEGNAME and SECTNAME are 16 bytes strings. */
188
189 static void
190 bfd_mach_o_convert_section_name_to_bfd
191 (bfd *abfd, const char *segname, const char *sectname,
192 const char **name, flagword *flags)
193 {
194 char *res;
195 unsigned int len;
196 const char *pfx = "";
197
198 /* First search for a canonical name. */
199 bfd_mach_o_normalize_section_name (segname, sectname, name, flags);
200
201 /* Return now if found. */
202 if (*name)
203 return;
204
205 len = 16 + 1 + 16 + 1;
206
207 /* Put "LC_SEGMENT." prefix if the segment name is weird (ie doesn't start
208 with an underscore. */
209 if (segname[0] != '_')
210 {
211 static const char seg_pfx[] = "LC_SEGMENT.";
212
213 pfx = seg_pfx;
214 len += sizeof (seg_pfx) - 1;
215 }
216
217 res = bfd_alloc (abfd, len);
218 if (res == NULL)
219 return;
220 snprintf (res, len, "%s%.16s.%.16s", pfx, segname, sectname);
221 *name = res;
222 *flags = SEC_NO_FLAGS;
223 }
224
225 /* Convert a bfd section name to a Mach-O segment + section name. */
226
227 static void
228 bfd_mach_o_convert_section_name_to_mach_o (bfd *abfd ATTRIBUTE_UNUSED,
229 asection *sect,
230 bfd_mach_o_section *section)
231 {
232 const struct mach_o_segment_name_xlat *seg;
233 const char *name = bfd_get_section_name (abfd, sect);
234 const char *dot;
235 unsigned int len;
236 unsigned int seglen;
237 unsigned int seclen;
238
239 /* List of well known names. They all start with a dot. */
240 if (name[0] == '.')
241 for (seg = segsec_names_xlat; seg->segname; seg++)
242 {
243 const struct mach_o_section_name_xlat *sec;
244
245 for (sec = seg->sections; sec->mach_o_name; sec++)
246 {
247 if (strcmp (sec->bfd_name, name) == 0)
248 {
249 strcpy (section->segname, seg->segname);
250 strcpy (section->sectname, sec->mach_o_name);
251 return;
252 }
253 }
254 }
255
256 /* Strip LC_SEGMENT. prefix. */
257 if (strncmp (name, "LC_SEGMENT.", 11) == 0)
258 name += 11;
259
260 /* Find a dot. */
261 dot = strchr (name, '.');
262 len = strlen (name);
263
264 /* Try to split name into segment and section names. */
265 if (dot && dot != name)
266 {
267 seglen = dot - name;
268 seclen = len - (dot + 1 - name);
269
270 if (seglen < 16 && seclen < 16)
271 {
272 memcpy (section->segname, name, seglen);
273 section->segname[seglen] = 0;
274 memcpy (section->sectname, dot + 1, seclen);
275 section->sectname[seclen] = 0;
276 return;
277 }
278 }
279
280 if (len > 16)
281 len = 16;
282 memcpy (section->segname, name, len);
283 section->segname[len] = 0;
284 memcpy (section->sectname, name, len);
285 section->sectname[len] = 0;
286 }
287
288 /* Return the size of an entry for section SEC.
289 Must be called only for symbol pointer section and symbol stubs
290 sections. */
291
292 static unsigned int
293 bfd_mach_o_section_get_entry_size (bfd *abfd, bfd_mach_o_section *sec)
294 {
295 switch (sec->flags & BFD_MACH_O_SECTION_TYPE_MASK)
296 {
297 case BFD_MACH_O_S_NON_LAZY_SYMBOL_POINTERS:
298 case BFD_MACH_O_S_LAZY_SYMBOL_POINTERS:
299 return bfd_mach_o_wide_p (abfd) ? 8 : 4;
300 case BFD_MACH_O_S_SYMBOL_STUBS:
301 return sec->reserved2;
302 default:
303 BFD_FAIL ();
304 return 0;
305 }
306 }
307
308 /* Return the number of indirect symbols for a section.
309 Must be called only for symbol pointer section and symbol stubs
310 sections. */
311
312 static unsigned int
313 bfd_mach_o_section_get_nbr_indirect (bfd *abfd, bfd_mach_o_section *sec)
314 {
315 unsigned int elsz;
316
317 elsz = bfd_mach_o_section_get_entry_size (abfd, sec);
318 if (elsz == 0)
319 return 0;
320 else
321 return sec->size / elsz;
322 }
323
324
325 /* Copy any private info we understand from the input symbol
326 to the output symbol. */
327
328 bfd_boolean
329 bfd_mach_o_bfd_copy_private_symbol_data (bfd *ibfd ATTRIBUTE_UNUSED,
330 asymbol *isymbol ATTRIBUTE_UNUSED,
331 bfd *obfd ATTRIBUTE_UNUSED,
332 asymbol *osymbol ATTRIBUTE_UNUSED)
333 {
334 return TRUE;
335 }
336
337 /* Copy any private info we understand from the input section
338 to the output section. */
339
340 bfd_boolean
341 bfd_mach_o_bfd_copy_private_section_data (bfd *ibfd ATTRIBUTE_UNUSED,
342 asection *isection ATTRIBUTE_UNUSED,
343 bfd *obfd ATTRIBUTE_UNUSED,
344 asection *osection ATTRIBUTE_UNUSED)
345 {
346 return TRUE;
347 }
348
349 /* Copy any private info we understand from the input bfd
350 to the output bfd. */
351
352 bfd_boolean
353 bfd_mach_o_bfd_copy_private_bfd_data (bfd *ibfd, bfd *obfd)
354 {
355 if (bfd_get_flavour (ibfd) != bfd_target_mach_o_flavour
356 || bfd_get_flavour (obfd) != bfd_target_mach_o_flavour)
357 return TRUE;
358
359 BFD_ASSERT (bfd_mach_o_valid (ibfd));
360 BFD_ASSERT (bfd_mach_o_valid (obfd));
361
362 /* FIXME: copy commands. */
363
364 return TRUE;
365 }
366
367 /* Count the total number of symbols. */
368
369 static long
370 bfd_mach_o_count_symbols (bfd *abfd)
371 {
372 bfd_mach_o_data_struct *mdata = bfd_mach_o_get_data (abfd);
373
374 if (mdata->symtab == NULL)
375 return 0;
376 return mdata->symtab->nsyms;
377 }
378
379 long
380 bfd_mach_o_get_symtab_upper_bound (bfd *abfd)
381 {
382 long nsyms = bfd_mach_o_count_symbols (abfd);
383
384 return ((nsyms + 1) * sizeof (asymbol *));
385 }
386
387 long
388 bfd_mach_o_canonicalize_symtab (bfd *abfd, asymbol **alocation)
389 {
390 bfd_mach_o_data_struct *mdata = bfd_mach_o_get_data (abfd);
391 long nsyms = bfd_mach_o_count_symbols (abfd);
392 bfd_mach_o_symtab_command *sym = mdata->symtab;
393 unsigned long j;
394
395 if (nsyms < 0)
396 return nsyms;
397
398 if (nsyms == 0)
399 {
400 /* Do not try to read symbols if there are none. */
401 alocation[0] = NULL;
402 return 0;
403 }
404
405 if (bfd_mach_o_read_symtab_symbols (abfd) != 0)
406 {
407 (*_bfd_error_handler) (_("bfd_mach_o_canonicalize_symtab: unable to load symbols"));
408 return 0;
409 }
410
411 BFD_ASSERT (sym->symbols != NULL);
412
413 for (j = 0; j < sym->nsyms; j++)
414 alocation[j] = &sym->symbols[j].symbol;
415
416 alocation[j] = NULL;
417
418 return nsyms;
419 }
420
421 long
422 bfd_mach_o_get_synthetic_symtab (bfd *abfd,
423 long symcount ATTRIBUTE_UNUSED,
424 asymbol **syms ATTRIBUTE_UNUSED,
425 long dynsymcount ATTRIBUTE_UNUSED,
426 asymbol **dynsyms ATTRIBUTE_UNUSED,
427 asymbol **ret)
428 {
429 bfd_mach_o_data_struct *mdata = bfd_mach_o_get_data (abfd);
430 bfd_mach_o_dysymtab_command *dysymtab = mdata->dysymtab;
431 bfd_mach_o_symtab_command *symtab = mdata->symtab;
432 asymbol *s;
433 unsigned long count, i, j, n;
434 size_t size;
435 char *names;
436 char *nul_name;
437
438 *ret = NULL;
439
440 if (dysymtab == NULL || symtab == NULL || symtab->symbols == NULL)
441 return 0;
442
443 if (dysymtab->nindirectsyms == 0)
444 return 0;
445
446 count = dysymtab->nindirectsyms;
447 size = count * sizeof (asymbol) + 1;
448
449 for (j = 0; j < count; j++)
450 {
451 unsigned int isym = dysymtab->indirect_syms[j];
452
453 if (isym < symtab->nsyms && symtab->symbols[isym].symbol.name)
454 size += strlen (symtab->symbols[isym].symbol.name) + sizeof ("$stub");
455 }
456
457 s = *ret = (asymbol *) bfd_malloc (size);
458 if (s == NULL)
459 return -1;
460 names = (char *) (s + count);
461 nul_name = names;
462 *names++ = 0;
463
464 n = 0;
465 for (i = 0; i < mdata->nsects; i++)
466 {
467 bfd_mach_o_section *sec = mdata->sections[i];
468 unsigned int first, last;
469 bfd_vma addr;
470 bfd_vma entry_size;
471
472 switch (sec->flags & BFD_MACH_O_SECTION_TYPE_MASK)
473 {
474 case BFD_MACH_O_S_NON_LAZY_SYMBOL_POINTERS:
475 case BFD_MACH_O_S_LAZY_SYMBOL_POINTERS:
476 case BFD_MACH_O_S_SYMBOL_STUBS:
477 first = sec->reserved1;
478 last = first + bfd_mach_o_section_get_nbr_indirect (abfd, sec);
479 addr = sec->addr;
480 entry_size = bfd_mach_o_section_get_entry_size (abfd, sec);
481 for (j = first; j < last; j++)
482 {
483 unsigned int isym = dysymtab->indirect_syms[j];
484
485 s->flags = BSF_GLOBAL | BSF_SYNTHETIC;
486 s->section = sec->bfdsection;
487 s->value = addr - sec->addr;
488 s->udata.p = NULL;
489
490 if (isym < symtab->nsyms
491 && symtab->symbols[isym].symbol.name)
492 {
493 const char *sym = symtab->symbols[isym].symbol.name;
494 size_t len;
495
496 s->name = names;
497 len = strlen (sym);
498 memcpy (names, sym, len);
499 names += len;
500 memcpy (names, "$stub", sizeof ("$stub"));
501 names += sizeof ("$stub");
502 }
503 else
504 s->name = nul_name;
505
506 addr += entry_size;
507 s++;
508 n++;
509 }
510 break;
511 default:
512 break;
513 }
514 }
515
516 return n;
517 }
518
519 void
520 bfd_mach_o_get_symbol_info (bfd *abfd ATTRIBUTE_UNUSED,
521 asymbol *symbol,
522 symbol_info *ret)
523 {
524 bfd_symbol_info (symbol, ret);
525 }
526
527 void
528 bfd_mach_o_print_symbol (bfd *abfd,
529 void * afile,
530 asymbol *symbol,
531 bfd_print_symbol_type how)
532 {
533 FILE *file = (FILE *) afile;
534 const char *name;
535 bfd_mach_o_asymbol *asym = (bfd_mach_o_asymbol *)symbol;
536
537 switch (how)
538 {
539 case bfd_print_symbol_name:
540 fprintf (file, "%s", symbol->name);
541 break;
542 default:
543 bfd_print_symbol_vandf (abfd, (void *) file, symbol);
544 if (asym->n_type & BFD_MACH_O_N_STAB)
545 name = bfd_get_stab_name (asym->n_type);
546 else
547 switch (asym->n_type & BFD_MACH_O_N_TYPE)
548 {
549 case BFD_MACH_O_N_UNDF:
550 if (symbol->value == 0)
551 name = "UND";
552 else
553 name = "COM";
554 break;
555 case BFD_MACH_O_N_ABS:
556 name = "ABS";
557 break;
558 case BFD_MACH_O_N_INDR:
559 name = "INDR";
560 break;
561 case BFD_MACH_O_N_PBUD:
562 name = "PBUD";
563 break;
564 case BFD_MACH_O_N_SECT:
565 name = "SECT";
566 break;
567 default:
568 name = "???";
569 break;
570 }
571 if (name == NULL)
572 name = "";
573 fprintf (file, " %02x %-6s %02x %04x",
574 asym->n_type, name, asym->n_sect, asym->n_desc);
575 if ((asym->n_type & BFD_MACH_O_N_STAB) == 0
576 && (asym->n_type & BFD_MACH_O_N_TYPE) == BFD_MACH_O_N_SECT)
577 fprintf (file, " [%s]", symbol->section->name);
578 fprintf (file, " %s", symbol->name);
579 }
580 }
581
582 static void
583 bfd_mach_o_convert_architecture (bfd_mach_o_cpu_type mtype,
584 bfd_mach_o_cpu_subtype msubtype ATTRIBUTE_UNUSED,
585 enum bfd_architecture *type,
586 unsigned long *subtype)
587 {
588 *subtype = bfd_arch_unknown;
589
590 switch (mtype)
591 {
592 case BFD_MACH_O_CPU_TYPE_VAX: *type = bfd_arch_vax; break;
593 case BFD_MACH_O_CPU_TYPE_MC680x0: *type = bfd_arch_m68k; break;
594 case BFD_MACH_O_CPU_TYPE_I386:
595 *type = bfd_arch_i386;
596 *subtype = bfd_mach_i386_i386;
597 break;
598 case BFD_MACH_O_CPU_TYPE_X86_64:
599 *type = bfd_arch_i386;
600 *subtype = bfd_mach_x86_64;
601 break;
602 case BFD_MACH_O_CPU_TYPE_MIPS: *type = bfd_arch_mips; break;
603 case BFD_MACH_O_CPU_TYPE_MC98000: *type = bfd_arch_m98k; break;
604 case BFD_MACH_O_CPU_TYPE_HPPA: *type = bfd_arch_hppa; break;
605 case BFD_MACH_O_CPU_TYPE_ARM: *type = bfd_arch_arm; break;
606 case BFD_MACH_O_CPU_TYPE_MC88000: *type = bfd_arch_m88k; break;
607 case BFD_MACH_O_CPU_TYPE_SPARC:
608 *type = bfd_arch_sparc;
609 *subtype = bfd_mach_sparc;
610 break;
611 case BFD_MACH_O_CPU_TYPE_I860: *type = bfd_arch_i860; break;
612 case BFD_MACH_O_CPU_TYPE_ALPHA: *type = bfd_arch_alpha; break;
613 case BFD_MACH_O_CPU_TYPE_POWERPC:
614 *type = bfd_arch_powerpc;
615 *subtype = bfd_mach_ppc;
616 break;
617 case BFD_MACH_O_CPU_TYPE_POWERPC_64:
618 *type = bfd_arch_powerpc;
619 *subtype = bfd_mach_ppc64;
620 break;
621 default:
622 *type = bfd_arch_unknown;
623 break;
624 }
625 }
626
627 static bfd_boolean
628 bfd_mach_o_write_header (bfd *abfd, bfd_mach_o_header *header)
629 {
630 struct mach_o_header_external raw;
631 unsigned int size;
632
633 size = mach_o_wide_p (header) ?
634 BFD_MACH_O_HEADER_64_SIZE : BFD_MACH_O_HEADER_SIZE;
635
636 bfd_h_put_32 (abfd, header->magic, raw.magic);
637 bfd_h_put_32 (abfd, header->cputype, raw.cputype);
638 bfd_h_put_32 (abfd, header->cpusubtype, raw.cpusubtype);
639 bfd_h_put_32 (abfd, header->filetype, raw.filetype);
640 bfd_h_put_32 (abfd, header->ncmds, raw.ncmds);
641 bfd_h_put_32 (abfd, header->sizeofcmds, raw.sizeofcmds);
642 bfd_h_put_32 (abfd, header->flags, raw.flags);
643
644 if (mach_o_wide_p (header))
645 bfd_h_put_32 (abfd, header->reserved, raw.reserved);
646
647 if (bfd_seek (abfd, 0, SEEK_SET) != 0
648 || bfd_bwrite (&raw, size, abfd) != size)
649 return FALSE;
650
651 return TRUE;
652 }
653
654 static int
655 bfd_mach_o_write_thread (bfd *abfd, bfd_mach_o_load_command *command)
656 {
657 bfd_mach_o_thread_command *cmd = &command->command.thread;
658 unsigned int i;
659 struct mach_o_thread_command_external raw;
660 unsigned int offset;
661
662 BFD_ASSERT ((command->type == BFD_MACH_O_LC_THREAD)
663 || (command->type == BFD_MACH_O_LC_UNIXTHREAD));
664
665 offset = 8;
666 for (i = 0; i < cmd->nflavours; i++)
667 {
668 BFD_ASSERT ((cmd->flavours[i].size % 4) == 0);
669 BFD_ASSERT (cmd->flavours[i].offset ==
670 (command->offset + offset + BFD_MACH_O_LC_SIZE));
671
672 bfd_h_put_32 (abfd, cmd->flavours[i].flavour, raw.flavour);
673 bfd_h_put_32 (abfd, (cmd->flavours[i].size / 4), raw.count);
674
675 if (bfd_seek (abfd, command->offset + offset, SEEK_SET) != 0
676 || bfd_bwrite (&raw, sizeof (raw), abfd) != sizeof (raw))
677 return -1;
678
679 offset += cmd->flavours[i].size + sizeof (raw);
680 }
681
682 return 0;
683 }
684
685 long
686 bfd_mach_o_get_reloc_upper_bound (bfd *abfd ATTRIBUTE_UNUSED,
687 asection *asect)
688 {
689 return (asect->reloc_count + 1) * sizeof (arelent *);
690 }
691
692 static int
693 bfd_mach_o_canonicalize_one_reloc (bfd *abfd,
694 struct mach_o_reloc_info_external *raw,
695 arelent *res, asymbol **syms)
696 {
697 bfd_mach_o_data_struct *mdata = bfd_mach_o_get_data (abfd);
698 bfd_mach_o_backend_data *bed = bfd_mach_o_get_backend_data (abfd);
699 bfd_mach_o_reloc_info reloc;
700 bfd_vma addr;
701 bfd_vma symnum;
702 asymbol **sym;
703
704 addr = bfd_get_32 (abfd, raw->r_address);
705 symnum = bfd_get_32 (abfd, raw->r_symbolnum);
706
707 if (addr & BFD_MACH_O_SR_SCATTERED)
708 {
709 unsigned int j;
710
711 /* Scattered relocation.
712 Extract section and offset from r_value. */
713 res->sym_ptr_ptr = NULL;
714 res->addend = 0;
715 for (j = 0; j < mdata->nsects; j++)
716 {
717 bfd_mach_o_section *sect = mdata->sections[j];
718 if (symnum >= sect->addr && symnum < sect->addr + sect->size)
719 {
720 res->sym_ptr_ptr = sect->bfdsection->symbol_ptr_ptr;
721 res->addend = symnum - sect->addr;
722 break;
723 }
724 }
725 res->address = BFD_MACH_O_GET_SR_ADDRESS (addr);
726 reloc.r_type = BFD_MACH_O_GET_SR_TYPE (addr);
727 reloc.r_length = BFD_MACH_O_GET_SR_LENGTH (addr);
728 reloc.r_pcrel = addr & BFD_MACH_O_SR_PCREL;
729 reloc.r_scattered = 1;
730 }
731 else
732 {
733 unsigned int num = BFD_MACH_O_GET_R_SYMBOLNUM (symnum);
734 res->addend = 0;
735 res->address = addr;
736 if (symnum & BFD_MACH_O_R_EXTERN)
737 {
738 sym = syms + num;
739 reloc.r_extern = 1;
740 }
741 else
742 {
743 BFD_ASSERT (num != 0);
744 BFD_ASSERT (num <= mdata->nsects);
745 sym = mdata->sections[num - 1]->bfdsection->symbol_ptr_ptr;
746 /* For a symbol defined in section S, the addend (stored in the
747 binary) contains the address of the section. To comply with
748 bfd conventio, substract the section address.
749 Use the address from the header, so that the user can modify
750 the vma of the section. */
751 res->addend = -mdata->sections[num - 1]->addr;
752 reloc.r_extern = 0;
753 }
754 res->sym_ptr_ptr = sym;
755 reloc.r_type = BFD_MACH_O_GET_R_TYPE (symnum);
756 reloc.r_length = BFD_MACH_O_GET_R_LENGTH (symnum);
757 reloc.r_pcrel = (symnum & BFD_MACH_O_R_PCREL) ? 1 : 0;
758 reloc.r_scattered = 0;
759 }
760
761 if (!(*bed->_bfd_mach_o_swap_reloc_in)(res, &reloc))
762 return -1;
763 return 0;
764 }
765
766 static int
767 bfd_mach_o_canonicalize_relocs (bfd *abfd, unsigned long filepos,
768 unsigned long count,
769 arelent *res, asymbol **syms)
770 {
771 unsigned long i;
772 struct mach_o_reloc_info_external *native_relocs;
773 bfd_size_type native_size;
774
775 /* Allocate and read relocs. */
776 native_size = count * BFD_MACH_O_RELENT_SIZE;
777 native_relocs =
778 (struct mach_o_reloc_info_external *) bfd_malloc (native_size);
779 if (native_relocs == NULL)
780 return -1;
781
782 if (bfd_seek (abfd, filepos, SEEK_SET) != 0
783 || bfd_bread (native_relocs, native_size, abfd) != native_size)
784 goto err;
785
786 for (i = 0; i < count; i++)
787 {
788 if (bfd_mach_o_canonicalize_one_reloc (abfd, &native_relocs[i],
789 &res[i], syms) < 0)
790 goto err;
791 }
792 free (native_relocs);
793 return i;
794 err:
795 free (native_relocs);
796 return -1;
797 }
798
799 long
800 bfd_mach_o_canonicalize_reloc (bfd *abfd, asection *asect,
801 arelent **rels, asymbol **syms)
802 {
803 bfd_mach_o_backend_data *bed = bfd_mach_o_get_backend_data (abfd);
804 unsigned long i;
805 arelent *res;
806
807 if (asect->reloc_count == 0)
808 return 0;
809
810 /* No need to go further if we don't know how to read relocs. */
811 if (bed->_bfd_mach_o_swap_reloc_in == NULL)
812 return 0;
813
814 res = bfd_malloc (asect->reloc_count * sizeof (arelent));
815 if (res == NULL)
816 return -1;
817
818 if (bfd_mach_o_canonicalize_relocs (abfd, asect->rel_filepos,
819 asect->reloc_count, res, syms) < 0)
820 {
821 free (res);
822 return -1;
823 }
824
825 for (i = 0; i < asect->reloc_count; i++)
826 rels[i] = &res[i];
827 rels[i] = NULL;
828 asect->relocation = res;
829
830 return i;
831 }
832
833 long
834 bfd_mach_o_get_dynamic_reloc_upper_bound (bfd *abfd)
835 {
836 bfd_mach_o_data_struct *mdata = bfd_mach_o_get_data (abfd);
837
838 if (mdata->dysymtab == NULL)
839 return 1;
840 return (mdata->dysymtab->nextrel + mdata->dysymtab->nlocrel)
841 * sizeof (arelent *);
842 }
843
844 long
845 bfd_mach_o_canonicalize_dynamic_reloc (bfd *abfd, arelent **rels,
846 struct bfd_symbol **syms)
847 {
848 bfd_mach_o_data_struct *mdata = bfd_mach_o_get_data (abfd);
849 bfd_mach_o_dysymtab_command *dysymtab = mdata->dysymtab;
850 bfd_mach_o_backend_data *bed = bfd_mach_o_get_backend_data (abfd);
851 unsigned long i;
852 arelent *res;
853
854 if (dysymtab == NULL)
855 return 0;
856 if (dysymtab->nextrel == 0 && dysymtab->nlocrel == 0)
857 return 0;
858
859 /* No need to go further if we don't know how to read relocs. */
860 if (bed->_bfd_mach_o_swap_reloc_in == NULL)
861 return 0;
862
863 res = bfd_malloc ((dysymtab->nextrel + dysymtab->nlocrel) * sizeof (arelent));
864 if (res == NULL)
865 return -1;
866
867 if (bfd_mach_o_canonicalize_relocs (abfd, dysymtab->extreloff,
868 dysymtab->nextrel, res, syms) < 0)
869 {
870 free (res);
871 return -1;
872 }
873
874 if (bfd_mach_o_canonicalize_relocs (abfd, dysymtab->locreloff,
875 dysymtab->nlocrel,
876 res + dysymtab->nextrel, syms) < 0)
877 {
878 free (res);
879 return -1;
880 }
881
882 for (i = 0; i < dysymtab->nextrel + dysymtab->nlocrel; i++)
883 rels[i] = &res[i];
884 rels[i] = NULL;
885 return i;
886 }
887
888 static bfd_boolean
889 bfd_mach_o_write_relocs (bfd *abfd, bfd_mach_o_section *section)
890 {
891 bfd_mach_o_data_struct *mdata = bfd_mach_o_get_data (abfd);
892 unsigned int i;
893 arelent **entries;
894 asection *sec;
895 bfd_mach_o_backend_data *bed = bfd_mach_o_get_backend_data (abfd);
896
897 sec = section->bfdsection;
898 if (sec->reloc_count == 0)
899 return TRUE;
900
901 if (bed->_bfd_mach_o_swap_reloc_out == NULL)
902 return TRUE;
903
904 /* Allocate relocation room. */
905 mdata->filelen = FILE_ALIGN(mdata->filelen, 2);
906 section->nreloc = sec->reloc_count;
907 sec->rel_filepos = mdata->filelen;
908 section->reloff = sec->rel_filepos;
909 mdata->filelen += sec->reloc_count * BFD_MACH_O_RELENT_SIZE;
910
911 if (bfd_seek (abfd, section->reloff, SEEK_SET) != 0)
912 return FALSE;
913
914 /* Convert and write. */
915 entries = section->bfdsection->orelocation;
916 for (i = 0; i < section->nreloc; i++)
917 {
918 arelent *rel = entries[i];
919 struct mach_o_reloc_info_external raw;
920 bfd_mach_o_reloc_info info, *pinfo = &info;
921
922 /* Convert relocation to an intermediate representation. */
923 if (!(*bed->_bfd_mach_o_swap_reloc_out) (rel, pinfo))
924 return FALSE;
925
926 /* Lower the relocation info. */
927 if (pinfo->r_scattered)
928 {
929 unsigned long v;
930
931 v = BFD_MACH_O_SR_SCATTERED
932 | (pinfo->r_pcrel ? BFD_MACH_O_SR_PCREL : 0)
933 | BFD_MACH_O_SET_SR_LENGTH(pinfo->r_length)
934 | BFD_MACH_O_SET_SR_TYPE(pinfo->r_type)
935 | BFD_MACH_O_SET_SR_ADDRESS(pinfo->r_address);
936 /* Note: scattered relocs have field in reverse order... */
937 bfd_put_32 (abfd, v, raw.r_address);
938 bfd_put_32 (abfd, pinfo->r_value, raw.r_symbolnum);
939 }
940 else
941 {
942 unsigned long v;
943
944 bfd_put_32 (abfd, pinfo->r_address, raw.r_address);
945 v = BFD_MACH_O_SET_R_SYMBOLNUM (pinfo->r_value)
946 | (pinfo->r_pcrel ? BFD_MACH_O_R_PCREL : 0)
947 | BFD_MACH_O_SET_R_LENGTH (pinfo->r_length)
948 | (pinfo->r_extern ? BFD_MACH_O_R_EXTERN : 0)
949 | BFD_MACH_O_SET_R_TYPE (pinfo->r_type);
950 bfd_put_32 (abfd, v, raw.r_symbolnum);
951 }
952
953 if (bfd_bwrite (&raw, BFD_MACH_O_RELENT_SIZE, abfd)
954 != BFD_MACH_O_RELENT_SIZE)
955 return FALSE;
956 }
957 return TRUE;
958 }
959
960 static int
961 bfd_mach_o_write_section_32 (bfd *abfd, bfd_mach_o_section *section)
962 {
963 struct mach_o_section_32_external raw;
964
965 memcpy (raw.sectname, section->sectname, 16);
966 memcpy (raw.segname, section->segname, 16);
967 bfd_h_put_32 (abfd, section->addr, raw.addr);
968 bfd_h_put_32 (abfd, section->size, raw.size);
969 bfd_h_put_32 (abfd, section->offset, raw.offset);
970 bfd_h_put_32 (abfd, section->align, raw.align);
971 bfd_h_put_32 (abfd, section->reloff, raw.reloff);
972 bfd_h_put_32 (abfd, section->nreloc, raw.nreloc);
973 bfd_h_put_32 (abfd, section->flags, raw.flags);
974 bfd_h_put_32 (abfd, section->reserved1, raw.reserved1);
975 bfd_h_put_32 (abfd, section->reserved2, raw.reserved2);
976
977 if (bfd_bwrite (&raw, BFD_MACH_O_SECTION_SIZE, abfd)
978 != BFD_MACH_O_SECTION_SIZE)
979 return -1;
980
981 return 0;
982 }
983
984 static int
985 bfd_mach_o_write_section_64 (bfd *abfd, bfd_mach_o_section *section)
986 {
987 struct mach_o_section_64_external raw;
988
989 memcpy (raw.sectname, section->sectname, 16);
990 memcpy (raw.segname, section->segname, 16);
991 bfd_h_put_64 (abfd, section->addr, raw.addr);
992 bfd_h_put_64 (abfd, section->size, raw.size);
993 bfd_h_put_32 (abfd, section->offset, raw.offset);
994 bfd_h_put_32 (abfd, section->align, raw.align);
995 bfd_h_put_32 (abfd, section->reloff, raw.reloff);
996 bfd_h_put_32 (abfd, section->nreloc, raw.nreloc);
997 bfd_h_put_32 (abfd, section->flags, raw.flags);
998 bfd_h_put_32 (abfd, section->reserved1, raw.reserved1);
999 bfd_h_put_32 (abfd, section->reserved2, raw.reserved2);
1000 bfd_h_put_32 (abfd, section->reserved3, raw.reserved3);
1001
1002 if (bfd_bwrite (&raw, BFD_MACH_O_SECTION_64_SIZE, abfd)
1003 != BFD_MACH_O_SECTION_64_SIZE)
1004 return -1;
1005
1006 return 0;
1007 }
1008
1009 static int
1010 bfd_mach_o_write_segment_32 (bfd *abfd, bfd_mach_o_load_command *command)
1011 {
1012 struct mach_o_segment_command_32_external raw;
1013 bfd_mach_o_segment_command *seg = &command->command.segment;
1014 bfd_mach_o_section *sec;
1015
1016 BFD_ASSERT (command->type == BFD_MACH_O_LC_SEGMENT);
1017
1018 for (sec = seg->sect_head; sec != NULL; sec = sec->next)
1019 if (!bfd_mach_o_write_relocs (abfd, sec))
1020 return -1;
1021
1022 memcpy (raw.segname, seg->segname, 16);
1023 bfd_h_put_32 (abfd, seg->vmaddr, raw.vmaddr);
1024 bfd_h_put_32 (abfd, seg->vmsize, raw.vmsize);
1025 bfd_h_put_32 (abfd, seg->fileoff, raw.fileoff);
1026 bfd_h_put_32 (abfd, seg->filesize, raw.filesize);
1027 bfd_h_put_32 (abfd, seg->maxprot, raw.maxprot);
1028 bfd_h_put_32 (abfd, seg->initprot, raw.initprot);
1029 bfd_h_put_32 (abfd, seg->nsects, raw.nsects);
1030 bfd_h_put_32 (abfd, seg->flags, raw.flags);
1031
1032 if (bfd_seek (abfd, command->offset + BFD_MACH_O_LC_SIZE, SEEK_SET) != 0
1033 || bfd_bwrite (&raw, sizeof (raw), abfd) != sizeof (raw))
1034 return -1;
1035
1036 for (sec = seg->sect_head; sec != NULL; sec = sec->next)
1037 if (bfd_mach_o_write_section_32 (abfd, sec))
1038 return -1;
1039
1040 return 0;
1041 }
1042
1043 static int
1044 bfd_mach_o_write_segment_64 (bfd *abfd, bfd_mach_o_load_command *command)
1045 {
1046 struct mach_o_segment_command_64_external raw;
1047 bfd_mach_o_segment_command *seg = &command->command.segment;
1048 bfd_mach_o_section *sec;
1049
1050 BFD_ASSERT (command->type == BFD_MACH_O_LC_SEGMENT_64);
1051
1052 for (sec = seg->sect_head; sec != NULL; sec = sec->next)
1053 if (!bfd_mach_o_write_relocs (abfd, sec))
1054 return -1;
1055
1056 memcpy (raw.segname, seg->segname, 16);
1057 bfd_h_put_64 (abfd, seg->vmaddr, raw.vmaddr);
1058 bfd_h_put_64 (abfd, seg->vmsize, raw.vmsize);
1059 bfd_h_put_64 (abfd, seg->fileoff, raw.fileoff);
1060 bfd_h_put_64 (abfd, seg->filesize, raw.filesize);
1061 bfd_h_put_32 (abfd, seg->maxprot, raw.maxprot);
1062 bfd_h_put_32 (abfd, seg->initprot, raw.initprot);
1063 bfd_h_put_32 (abfd, seg->nsects, raw.nsects);
1064 bfd_h_put_32 (abfd, seg->flags, raw.flags);
1065
1066 if (bfd_seek (abfd, command->offset + BFD_MACH_O_LC_SIZE, SEEK_SET) != 0
1067 || bfd_bwrite (&raw, sizeof (raw), abfd) != sizeof (raw))
1068 return -1;
1069
1070 for (sec = seg->sect_head; sec != NULL; sec = sec->next)
1071 if (bfd_mach_o_write_section_64 (abfd, sec))
1072 return -1;
1073
1074 return 0;
1075 }
1076
1077 static bfd_boolean
1078 bfd_mach_o_write_symtab (bfd *abfd, bfd_mach_o_load_command *command)
1079 {
1080 bfd_mach_o_data_struct *mdata = bfd_mach_o_get_data (abfd);
1081 bfd_mach_o_symtab_command *sym = &command->command.symtab;
1082 unsigned long i;
1083 unsigned int wide = bfd_mach_o_wide_p (abfd);
1084 unsigned int symlen = wide ? BFD_MACH_O_NLIST_64_SIZE : BFD_MACH_O_NLIST_SIZE;
1085 struct bfd_strtab_hash *strtab;
1086 asymbol **symbols = bfd_get_outsymbols (abfd);
1087
1088 BFD_ASSERT (command->type == BFD_MACH_O_LC_SYMTAB);
1089
1090 /* Write the symbols first. */
1091 mdata->filelen = FILE_ALIGN(mdata->filelen, wide ? 3 : 2);
1092 sym->symoff = mdata->filelen;
1093 if (bfd_seek (abfd, sym->symoff, SEEK_SET) != 0)
1094 return FALSE;
1095
1096 sym->nsyms = bfd_get_symcount (abfd);
1097 mdata->filelen += sym->nsyms * symlen;
1098
1099 strtab = _bfd_stringtab_init ();
1100 if (strtab == NULL)
1101 return FALSE;
1102
1103 for (i = 0; i < sym->nsyms; i++)
1104 {
1105 bfd_size_type str_index;
1106 bfd_mach_o_asymbol *s = (bfd_mach_o_asymbol *)symbols[i];
1107
1108 /* Compute name index. */
1109 /* An index of 0 always means the empty string. */
1110 if (s->symbol.name == 0 || s->symbol.name[0] == '\0')
1111 str_index = 0;
1112 else
1113 {
1114 str_index = _bfd_stringtab_add (strtab, s->symbol.name, TRUE, FALSE);
1115 if (str_index == (bfd_size_type) -1)
1116 goto err;
1117 }
1118
1119 if (wide)
1120 {
1121 struct mach_o_nlist_64_external raw;
1122
1123 bfd_h_put_32 (abfd, str_index, raw.n_strx);
1124 bfd_h_put_8 (abfd, s->n_type, raw.n_type);
1125 bfd_h_put_8 (abfd, s->n_sect, raw.n_sect);
1126 bfd_h_put_16 (abfd, s->n_desc, raw.n_desc);
1127 bfd_h_put_64 (abfd, s->symbol.section->vma + s->symbol.value,
1128 raw.n_value);
1129
1130 if (bfd_bwrite (&raw, sizeof (raw), abfd) != sizeof (raw))
1131 goto err;
1132 }
1133 else
1134 {
1135 struct mach_o_nlist_external raw;
1136
1137 bfd_h_put_32 (abfd, str_index, raw.n_strx);
1138 bfd_h_put_8 (abfd, s->n_type, raw.n_type);
1139 bfd_h_put_8 (abfd, s->n_sect, raw.n_sect);
1140 bfd_h_put_16 (abfd, s->n_desc, raw.n_desc);
1141 bfd_h_put_32 (abfd, s->symbol.section->vma + s->symbol.value,
1142 raw.n_value);
1143
1144 if (bfd_bwrite (&raw, sizeof (raw), abfd) != sizeof (raw))
1145 goto err;
1146 }
1147 }
1148 sym->strsize = _bfd_stringtab_size (strtab);
1149 sym->stroff = mdata->filelen;
1150 mdata->filelen += sym->strsize;
1151
1152 if (_bfd_stringtab_emit (abfd, strtab) != TRUE)
1153 goto err;
1154 _bfd_stringtab_free (strtab);
1155
1156 /* The command. */
1157 {
1158 struct mach_o_symtab_command_external raw;
1159
1160 bfd_h_put_32 (abfd, sym->symoff, raw.symoff);
1161 bfd_h_put_32 (abfd, sym->nsyms, raw.nsyms);
1162 bfd_h_put_32 (abfd, sym->stroff, raw.stroff);
1163 bfd_h_put_32 (abfd, sym->strsize, raw.strsize);
1164
1165 if (bfd_seek (abfd, command->offset + BFD_MACH_O_LC_SIZE, SEEK_SET) != 0
1166 || bfd_bwrite (&raw, sizeof (raw), abfd) != sizeof (raw))
1167 return FALSE;
1168 }
1169
1170 return TRUE;
1171
1172 err:
1173 _bfd_stringtab_free (strtab);
1174 return FALSE;
1175 }
1176
1177 /* Process the symbols and generate Mach-O specific fields.
1178 Number them. */
1179
1180 static bfd_boolean
1181 bfd_mach_o_mangle_symbols (bfd *abfd)
1182 {
1183 unsigned long i;
1184 asymbol **symbols = bfd_get_outsymbols (abfd);
1185
1186 for (i = 0; i < bfd_get_symcount (abfd); i++)
1187 {
1188 bfd_mach_o_asymbol *s = (bfd_mach_o_asymbol *)symbols[i];
1189
1190 if (s->n_type == BFD_MACH_O_N_UNDF && !(s->symbol.flags & BSF_DEBUGGING))
1191 {
1192 /* As genuine Mach-O symbols type shouldn't be N_UNDF (undefined
1193 symbols should be N_UNDEF | N_EXT), we suppose the back-end
1194 values haven't been set. */
1195 if (s->symbol.section == bfd_abs_section_ptr)
1196 s->n_type = BFD_MACH_O_N_ABS;
1197 else if (s->symbol.section == bfd_und_section_ptr)
1198 {
1199 s->n_type = BFD_MACH_O_N_UNDF;
1200 if (s->symbol.flags & BSF_WEAK)
1201 s->n_desc |= BFD_MACH_O_N_WEAK_REF;
1202 }
1203 else if (s->symbol.section == bfd_com_section_ptr)
1204 s->n_type = BFD_MACH_O_N_UNDF | BFD_MACH_O_N_EXT;
1205 else
1206 s->n_type = BFD_MACH_O_N_SECT;
1207
1208 if (s->symbol.flags & BSF_GLOBAL)
1209 s->n_type |= BFD_MACH_O_N_EXT;
1210 }
1211
1212 /* Compute section index. */
1213 if (s->symbol.section != bfd_abs_section_ptr
1214 && s->symbol.section != bfd_und_section_ptr
1215 && s->symbol.section != bfd_com_section_ptr)
1216 s->n_sect = s->symbol.section->target_index;
1217
1218 /* Number symbols. */
1219 s->symbol.udata.i = i;
1220 }
1221 return TRUE;
1222 }
1223
1224 bfd_boolean
1225 bfd_mach_o_write_contents (bfd *abfd)
1226 {
1227 unsigned int i;
1228 bfd_mach_o_data_struct *mdata = bfd_mach_o_get_data (abfd);
1229
1230 if (mdata->header.ncmds == 0)
1231 if (!bfd_mach_o_build_commands (abfd))
1232 return FALSE;
1233
1234 /* Now write header information. */
1235 if (mdata->header.filetype == 0)
1236 {
1237 if (abfd->flags & EXEC_P)
1238 mdata->header.filetype = BFD_MACH_O_MH_EXECUTE;
1239 else if (abfd->flags & DYNAMIC)
1240 mdata->header.filetype = BFD_MACH_O_MH_DYLIB;
1241 else
1242 mdata->header.filetype = BFD_MACH_O_MH_OBJECT;
1243 }
1244 if (!bfd_mach_o_write_header (abfd, &mdata->header))
1245 return FALSE;
1246
1247 /* Assign a number to each symbols. */
1248 if (!bfd_mach_o_mangle_symbols (abfd))
1249 return FALSE;
1250
1251 for (i = 0; i < mdata->header.ncmds; i++)
1252 {
1253 struct mach_o_load_command_external raw;
1254 bfd_mach_o_load_command *cur = &mdata->commands[i];
1255 unsigned long typeflag;
1256
1257 typeflag = cur->type | (cur->type_required ? BFD_MACH_O_LC_REQ_DYLD : 0);
1258
1259 bfd_h_put_32 (abfd, typeflag, raw.cmd);
1260 bfd_h_put_32 (abfd, cur->len, raw.cmdsize);
1261
1262 if (bfd_seek (abfd, cur->offset, SEEK_SET) != 0
1263 || bfd_bwrite (&raw, BFD_MACH_O_LC_SIZE, abfd) != 8)
1264 return FALSE;
1265
1266 switch (cur->type)
1267 {
1268 case BFD_MACH_O_LC_SEGMENT:
1269 if (bfd_mach_o_write_segment_32 (abfd, cur) != 0)
1270 return FALSE;
1271 break;
1272 case BFD_MACH_O_LC_SEGMENT_64:
1273 if (bfd_mach_o_write_segment_64 (abfd, cur) != 0)
1274 return FALSE;
1275 break;
1276 case BFD_MACH_O_LC_SYMTAB:
1277 if (!bfd_mach_o_write_symtab (abfd, cur))
1278 return FALSE;
1279 break;
1280 case BFD_MACH_O_LC_SYMSEG:
1281 break;
1282 case BFD_MACH_O_LC_THREAD:
1283 case BFD_MACH_O_LC_UNIXTHREAD:
1284 if (bfd_mach_o_write_thread (abfd, cur) != 0)
1285 return FALSE;
1286 break;
1287 case BFD_MACH_O_LC_LOADFVMLIB:
1288 case BFD_MACH_O_LC_IDFVMLIB:
1289 case BFD_MACH_O_LC_IDENT:
1290 case BFD_MACH_O_LC_FVMFILE:
1291 case BFD_MACH_O_LC_PREPAGE:
1292 case BFD_MACH_O_LC_DYSYMTAB:
1293 case BFD_MACH_O_LC_LOAD_DYLIB:
1294 case BFD_MACH_O_LC_LOAD_WEAK_DYLIB:
1295 case BFD_MACH_O_LC_ID_DYLIB:
1296 case BFD_MACH_O_LC_REEXPORT_DYLIB:
1297 case BFD_MACH_O_LC_LOAD_UPWARD_DYLIB:
1298 case BFD_MACH_O_LC_LOAD_DYLINKER:
1299 case BFD_MACH_O_LC_ID_DYLINKER:
1300 case BFD_MACH_O_LC_PREBOUND_DYLIB:
1301 case BFD_MACH_O_LC_ROUTINES:
1302 case BFD_MACH_O_LC_SUB_FRAMEWORK:
1303 break;
1304 default:
1305 (*_bfd_error_handler) (_("unable to write unknown load command 0x%lx"),
1306 (unsigned long) cur->type);
1307 return FALSE;
1308 }
1309 }
1310
1311 return TRUE;
1312 }
1313
1314 static void
1315 bfd_mach_o_append_section_to_segment (bfd_mach_o_segment_command *seg,
1316 asection *sec)
1317 {
1318 bfd_mach_o_section *s = (bfd_mach_o_section *)sec->used_by_bfd;
1319 if (seg->sect_head == NULL)
1320 seg->sect_head = s;
1321 else
1322 seg->sect_tail->next = s;
1323 seg->sect_tail = s;
1324 }
1325
1326 /* Create section Mach-O flags from BFD flags. */
1327
1328 static void
1329 bfd_mach_o_set_section_flags_from_bfd (bfd *abfd ATTRIBUTE_UNUSED, asection *sec)
1330 {
1331 flagword bfd_flags;
1332 bfd_mach_o_section *s = bfd_mach_o_get_mach_o_section (sec);
1333
1334 /* Create default flags. */
1335 bfd_flags = bfd_get_section_flags (abfd, sec);
1336 if ((bfd_flags & SEC_CODE) == SEC_CODE)
1337 s->flags = BFD_MACH_O_S_ATTR_PURE_INSTRUCTIONS
1338 | BFD_MACH_O_S_ATTR_SOME_INSTRUCTIONS
1339 | BFD_MACH_O_S_REGULAR;
1340 else if ((bfd_flags & (SEC_ALLOC | SEC_LOAD)) == SEC_ALLOC)
1341 s->flags = BFD_MACH_O_S_ZEROFILL;
1342 else if (bfd_flags & SEC_DEBUGGING)
1343 s->flags = BFD_MACH_O_S_REGULAR | BFD_MACH_O_S_ATTR_DEBUG;
1344 else
1345 s->flags = BFD_MACH_O_S_REGULAR;
1346 }
1347
1348 /* Build Mach-O load commands from the sections. */
1349
1350 bfd_boolean
1351 bfd_mach_o_build_commands (bfd *abfd)
1352 {
1353 bfd_mach_o_data_struct *mdata = bfd_mach_o_get_data (abfd);
1354 unsigned int wide = mach_o_wide_p (&mdata->header);
1355 bfd_mach_o_segment_command *seg;
1356 asection *sec;
1357 bfd_mach_o_load_command *cmd;
1358 bfd_mach_o_load_command *symtab_cmd;
1359 int target_index;
1360
1361 /* Return now if commands are already built. */
1362 if (mdata->header.ncmds)
1363 return FALSE;
1364
1365 /* Very simple version: a command (segment) to contain all the sections and
1366 a command for the symbol table. */
1367 mdata->header.ncmds = 2;
1368 mdata->commands = bfd_alloc (abfd, mdata->header.ncmds
1369 * sizeof (bfd_mach_o_load_command));
1370 if (mdata->commands == NULL)
1371 return FALSE;
1372 cmd = &mdata->commands[0];
1373 seg = &cmd->command.segment;
1374
1375 seg->nsects = bfd_count_sections (abfd);
1376
1377 /* Set segment command. */
1378 if (wide)
1379 {
1380 cmd->type = BFD_MACH_O_LC_SEGMENT_64;
1381 cmd->offset = BFD_MACH_O_HEADER_64_SIZE;
1382 cmd->len = BFD_MACH_O_LC_SEGMENT_64_SIZE
1383 + BFD_MACH_O_SECTION_64_SIZE * seg->nsects;
1384 }
1385 else
1386 {
1387 cmd->type = BFD_MACH_O_LC_SEGMENT;
1388 cmd->offset = BFD_MACH_O_HEADER_SIZE;
1389 cmd->len = BFD_MACH_O_LC_SEGMENT_SIZE
1390 + BFD_MACH_O_SECTION_SIZE * seg->nsects;
1391 }
1392 cmd->type_required = FALSE;
1393 mdata->header.sizeofcmds = cmd->len;
1394 mdata->filelen = cmd->offset + cmd->len;
1395
1396 /* Set symtab command. */
1397 symtab_cmd = &mdata->commands[1];
1398
1399 symtab_cmd->type = BFD_MACH_O_LC_SYMTAB;
1400 symtab_cmd->offset = cmd->offset + cmd->len;
1401 symtab_cmd->len = 6 * 4;
1402 symtab_cmd->type_required = FALSE;
1403
1404 mdata->header.sizeofcmds += symtab_cmd->len;
1405 mdata->filelen += symtab_cmd->len;
1406
1407 /* Fill segment command. */
1408 memset (seg->segname, 0, sizeof (seg->segname));
1409 seg->vmaddr = 0;
1410 seg->fileoff = mdata->filelen;
1411 seg->filesize = 0;
1412 seg->maxprot = BFD_MACH_O_PROT_READ | BFD_MACH_O_PROT_WRITE
1413 | BFD_MACH_O_PROT_EXECUTE;
1414 seg->initprot = seg->maxprot;
1415 seg->flags = 0;
1416 seg->sect_head = NULL;
1417 seg->sect_tail = NULL;
1418
1419 /* Create Mach-O sections. */
1420 target_index = 0;
1421 for (sec = abfd->sections; sec; sec = sec->next)
1422 {
1423 bfd_mach_o_section *msect = bfd_mach_o_get_mach_o_section (sec);
1424
1425 bfd_mach_o_append_section_to_segment (seg, sec);
1426
1427 if (msect->flags == 0)
1428 {
1429 /* We suppose it hasn't been set. Convert from BFD flags. */
1430 bfd_mach_o_set_section_flags_from_bfd (abfd, sec);
1431 }
1432 msect->addr = bfd_get_section_vma (abfd, sec);
1433 msect->size = bfd_get_section_size (sec);
1434 msect->align = bfd_get_section_alignment (abfd, sec);
1435
1436 if (msect->size != 0)
1437 {
1438 mdata->filelen = FILE_ALIGN (mdata->filelen, msect->align);
1439 msect->offset = mdata->filelen;
1440 }
1441 else
1442 msect->offset = 0;
1443
1444 sec->filepos = msect->offset;
1445 sec->target_index = ++target_index;
1446
1447 mdata->filelen += msect->size;
1448 }
1449 seg->filesize = mdata->filelen - seg->fileoff;
1450 seg->vmsize = seg->filesize;
1451
1452 return TRUE;
1453 }
1454
1455 /* Set the contents of a section. */
1456
1457 bfd_boolean
1458 bfd_mach_o_set_section_contents (bfd *abfd,
1459 asection *section,
1460 const void * location,
1461 file_ptr offset,
1462 bfd_size_type count)
1463 {
1464 file_ptr pos;
1465
1466 /* This must be done first, because bfd_set_section_contents is
1467 going to set output_has_begun to TRUE. */
1468 if (! abfd->output_has_begun && ! bfd_mach_o_build_commands (abfd))
1469 return FALSE;
1470
1471 if (count == 0)
1472 return TRUE;
1473
1474 pos = section->filepos + offset;
1475 if (bfd_seek (abfd, pos, SEEK_SET) != 0
1476 || bfd_bwrite (location, count, abfd) != count)
1477 return FALSE;
1478
1479 return TRUE;
1480 }
1481
1482 int
1483 bfd_mach_o_sizeof_headers (bfd *a ATTRIBUTE_UNUSED,
1484 struct bfd_link_info *info ATTRIBUTE_UNUSED)
1485 {
1486 return 0;
1487 }
1488
1489 /* Make an empty symbol. This is required only because
1490 bfd_make_section_anyway wants to create a symbol for the section. */
1491
1492 asymbol *
1493 bfd_mach_o_make_empty_symbol (bfd *abfd)
1494 {
1495 asymbol *new_symbol;
1496
1497 new_symbol = bfd_zalloc (abfd, sizeof (bfd_mach_o_asymbol));
1498 if (new_symbol == NULL)
1499 return new_symbol;
1500 new_symbol->the_bfd = abfd;
1501 new_symbol->udata.i = 0;
1502 return new_symbol;
1503 }
1504
1505 static bfd_boolean
1506 bfd_mach_o_read_header (bfd *abfd, bfd_mach_o_header *header)
1507 {
1508 struct mach_o_header_external raw;
1509 unsigned int size;
1510 bfd_vma (*get32) (const void *) = NULL;
1511
1512 /* Just read the magic number. */
1513 if (bfd_seek (abfd, 0, SEEK_SET) != 0
1514 || bfd_bread (raw.magic, sizeof (raw.magic), abfd) != 4)
1515 return FALSE;
1516
1517 if (bfd_getb32 (raw.magic) == BFD_MACH_O_MH_MAGIC)
1518 {
1519 header->byteorder = BFD_ENDIAN_BIG;
1520 header->magic = BFD_MACH_O_MH_MAGIC;
1521 header->version = 1;
1522 get32 = bfd_getb32;
1523 }
1524 else if (bfd_getl32 (raw.magic) == BFD_MACH_O_MH_MAGIC)
1525 {
1526 header->byteorder = BFD_ENDIAN_LITTLE;
1527 header->magic = BFD_MACH_O_MH_MAGIC;
1528 header->version = 1;
1529 get32 = bfd_getl32;
1530 }
1531 else if (bfd_getb32 (raw.magic) == BFD_MACH_O_MH_MAGIC_64)
1532 {
1533 header->byteorder = BFD_ENDIAN_BIG;
1534 header->magic = BFD_MACH_O_MH_MAGIC_64;
1535 header->version = 2;
1536 get32 = bfd_getb32;
1537 }
1538 else if (bfd_getl32 (raw.magic) == BFD_MACH_O_MH_MAGIC_64)
1539 {
1540 header->byteorder = BFD_ENDIAN_LITTLE;
1541 header->magic = BFD_MACH_O_MH_MAGIC_64;
1542 header->version = 2;
1543 get32 = bfd_getl32;
1544 }
1545 else
1546 {
1547 header->byteorder = BFD_ENDIAN_UNKNOWN;
1548 return FALSE;
1549 }
1550
1551 /* Once the size of the header is known, read the full header. */
1552 size = mach_o_wide_p (header) ?
1553 BFD_MACH_O_HEADER_64_SIZE : BFD_MACH_O_HEADER_SIZE;
1554
1555 if (bfd_seek (abfd, 0, SEEK_SET) != 0
1556 || bfd_bread (&raw, size, abfd) != size)
1557 return FALSE;
1558
1559 header->cputype = (*get32) (raw.cputype);
1560 header->cpusubtype = (*get32) (raw.cpusubtype);
1561 header->filetype = (*get32) (raw.filetype);
1562 header->ncmds = (*get32) (raw.ncmds);
1563 header->sizeofcmds = (*get32) (raw.sizeofcmds);
1564 header->flags = (*get32) (raw.flags);
1565
1566 if (mach_o_wide_p (header))
1567 header->reserved = (*get32) (raw.reserved);
1568
1569 return TRUE;
1570 }
1571
1572 bfd_boolean
1573 bfd_mach_o_new_section_hook (bfd *abfd, asection *sec)
1574 {
1575 bfd_mach_o_section *s;
1576
1577 s = bfd_mach_o_get_mach_o_section (sec);
1578 if (s == NULL)
1579 {
1580 flagword bfd_flags;
1581
1582 s = (bfd_mach_o_section *) bfd_zalloc (abfd, sizeof (*s));
1583 if (s == NULL)
1584 return FALSE;
1585 sec->used_by_bfd = s;
1586 s->bfdsection = sec;
1587
1588 /* Create default name. */
1589 bfd_mach_o_convert_section_name_to_mach_o (abfd, sec, s);
1590
1591 /* Create default flags. */
1592 bfd_flags = bfd_get_section_flags (abfd, sec);
1593 if ((bfd_flags & SEC_CODE) == SEC_CODE)
1594 s->flags = BFD_MACH_O_S_ATTR_PURE_INSTRUCTIONS
1595 | BFD_MACH_O_S_ATTR_SOME_INSTRUCTIONS
1596 | BFD_MACH_O_S_REGULAR;
1597 else if ((bfd_flags & (SEC_ALLOC | SEC_LOAD)) == SEC_ALLOC)
1598 s->flags = BFD_MACH_O_S_ZEROFILL;
1599 else if (bfd_flags & SEC_DEBUGGING)
1600 s->flags = BFD_MACH_O_S_REGULAR | BFD_MACH_O_S_ATTR_DEBUG;
1601 else
1602 s->flags = BFD_MACH_O_S_REGULAR;
1603 }
1604
1605 return _bfd_generic_new_section_hook (abfd, sec);
1606 }
1607
1608 static void
1609 bfd_mach_o_init_section_from_mach_o (bfd *abfd, asection *sec,
1610 unsigned long prot)
1611 {
1612 flagword flags;
1613 bfd_mach_o_section *section;
1614
1615 flags = bfd_get_section_flags (abfd, sec);
1616 section = bfd_mach_o_get_mach_o_section (sec);
1617
1618 if (flags == SEC_NO_FLAGS)
1619 {
1620 /* Try to guess flags. */
1621 if (section->flags & BFD_MACH_O_S_ATTR_DEBUG)
1622 flags = SEC_DEBUGGING;
1623 else
1624 {
1625 flags = SEC_ALLOC;
1626 if ((section->flags & BFD_MACH_O_SECTION_TYPE_MASK)
1627 != BFD_MACH_O_S_ZEROFILL)
1628 {
1629 flags |= SEC_LOAD;
1630 if (prot & BFD_MACH_O_PROT_EXECUTE)
1631 flags |= SEC_CODE;
1632 if (prot & BFD_MACH_O_PROT_WRITE)
1633 flags |= SEC_DATA;
1634 else if (prot & BFD_MACH_O_PROT_READ)
1635 flags |= SEC_READONLY;
1636 }
1637 }
1638 }
1639 else
1640 {
1641 if ((flags & SEC_DEBUGGING) == 0)
1642 flags |= SEC_ALLOC;
1643 }
1644
1645 if (section->offset != 0)
1646 flags |= SEC_HAS_CONTENTS;
1647 if (section->nreloc != 0)
1648 flags |= SEC_RELOC;
1649
1650 bfd_set_section_flags (abfd, sec, flags);
1651
1652 sec->vma = section->addr;
1653 sec->lma = section->addr;
1654 sec->size = section->size;
1655 sec->filepos = section->offset;
1656 sec->alignment_power = section->align;
1657 sec->segment_mark = 0;
1658 sec->reloc_count = section->nreloc;
1659 sec->rel_filepos = section->reloff;
1660 }
1661
1662 static asection *
1663 bfd_mach_o_make_bfd_section (bfd *abfd,
1664 const unsigned char *segname,
1665 const unsigned char *sectname)
1666 {
1667 const char *sname;
1668 flagword flags;
1669
1670 bfd_mach_o_convert_section_name_to_bfd
1671 (abfd, (const char *)segname, (const char *)sectname, &sname, &flags);
1672 if (sname == NULL)
1673 return NULL;
1674
1675 return bfd_make_section_anyway_with_flags (abfd, sname, flags);
1676 }
1677
1678 static asection *
1679 bfd_mach_o_read_section_32 (bfd *abfd,
1680 unsigned int offset,
1681 unsigned long prot)
1682 {
1683 struct mach_o_section_32_external raw;
1684 asection *sec;
1685 bfd_mach_o_section *section;
1686
1687 if (bfd_seek (abfd, offset, SEEK_SET) != 0
1688 || (bfd_bread (&raw, BFD_MACH_O_SECTION_SIZE, abfd)
1689 != BFD_MACH_O_SECTION_SIZE))
1690 return NULL;
1691
1692 sec = bfd_mach_o_make_bfd_section (abfd, raw.segname, raw.sectname);
1693 if (sec == NULL)
1694 return NULL;
1695
1696 section = bfd_mach_o_get_mach_o_section (sec);
1697 memcpy (section->segname, raw.segname, sizeof (raw.segname));
1698 section->segname[BFD_MACH_O_SEGNAME_SIZE] = 0;
1699 memcpy (section->sectname, raw.sectname, sizeof (raw.sectname));
1700 section->segname[BFD_MACH_O_SECTNAME_SIZE] = 0;
1701 section->addr = bfd_h_get_32 (abfd, raw.addr);
1702 section->size = bfd_h_get_32 (abfd, raw.size);
1703 section->offset = bfd_h_get_32 (abfd, raw.offset);
1704 section->align = bfd_h_get_32 (abfd, raw.align);
1705 section->reloff = bfd_h_get_32 (abfd, raw.reloff);
1706 section->nreloc = bfd_h_get_32 (abfd, raw.nreloc);
1707 section->flags = bfd_h_get_32 (abfd, raw.flags);
1708 section->reserved1 = bfd_h_get_32 (abfd, raw.reserved1);
1709 section->reserved2 = bfd_h_get_32 (abfd, raw.reserved2);
1710 section->reserved3 = 0;
1711
1712 bfd_mach_o_init_section_from_mach_o (abfd, sec, prot);
1713
1714 return sec;
1715 }
1716
1717 static asection *
1718 bfd_mach_o_read_section_64 (bfd *abfd,
1719 unsigned int offset,
1720 unsigned long prot)
1721 {
1722 struct mach_o_section_64_external raw;
1723 asection *sec;
1724 bfd_mach_o_section *section;
1725
1726 if (bfd_seek (abfd, offset, SEEK_SET) != 0
1727 || (bfd_bread (&raw, BFD_MACH_O_SECTION_64_SIZE, abfd)
1728 != BFD_MACH_O_SECTION_64_SIZE))
1729 return NULL;
1730
1731 sec = bfd_mach_o_make_bfd_section (abfd, raw.segname, raw.sectname);
1732 if (sec == NULL)
1733 return NULL;
1734
1735 section = bfd_mach_o_get_mach_o_section (sec);
1736 memcpy (section->segname, raw.segname, sizeof (raw.segname));
1737 section->segname[BFD_MACH_O_SEGNAME_SIZE] = 0;
1738 memcpy (section->sectname, raw.sectname, sizeof (raw.sectname));
1739 section->segname[BFD_MACH_O_SECTNAME_SIZE] = 0;
1740 section->addr = bfd_h_get_64 (abfd, raw.addr);
1741 section->size = bfd_h_get_64 (abfd, raw.size);
1742 section->offset = bfd_h_get_32 (abfd, raw.offset);
1743 section->align = bfd_h_get_32 (abfd, raw.align);
1744 section->reloff = bfd_h_get_32 (abfd, raw.reloff);
1745 section->nreloc = bfd_h_get_32 (abfd, raw.nreloc);
1746 section->flags = bfd_h_get_32 (abfd, raw.flags);
1747 section->reserved1 = bfd_h_get_32 (abfd, raw.reserved1);
1748 section->reserved2 = bfd_h_get_32 (abfd, raw.reserved2);
1749 section->reserved3 = bfd_h_get_32 (abfd, raw.reserved3);
1750
1751 bfd_mach_o_init_section_from_mach_o (abfd, sec, prot);
1752
1753 return sec;
1754 }
1755
1756 static asection *
1757 bfd_mach_o_read_section (bfd *abfd,
1758 unsigned int offset,
1759 unsigned long prot,
1760 unsigned int wide)
1761 {
1762 if (wide)
1763 return bfd_mach_o_read_section_64 (abfd, offset, prot);
1764 else
1765 return bfd_mach_o_read_section_32 (abfd, offset, prot);
1766 }
1767
1768 static int
1769 bfd_mach_o_read_symtab_symbol (bfd *abfd,
1770 bfd_mach_o_symtab_command *sym,
1771 bfd_mach_o_asymbol *s,
1772 unsigned long i)
1773 {
1774 bfd_mach_o_data_struct *mdata = bfd_mach_o_get_data (abfd);
1775 unsigned int wide = mach_o_wide_p (&mdata->header);
1776 unsigned int symwidth =
1777 wide ? BFD_MACH_O_NLIST_64_SIZE : BFD_MACH_O_NLIST_SIZE;
1778 unsigned int symoff = sym->symoff + (i * symwidth);
1779 struct mach_o_nlist_64_external raw;
1780 unsigned char type = -1;
1781 unsigned char section = -1;
1782 short desc = -1;
1783 symvalue value = -1;
1784 unsigned long stroff = -1;
1785 unsigned int symtype = -1;
1786
1787 BFD_ASSERT (sym->strtab != NULL);
1788
1789 if (bfd_seek (abfd, symoff, SEEK_SET) != 0
1790 || bfd_bread (&raw, symwidth, abfd) != symwidth)
1791 {
1792 (*_bfd_error_handler)
1793 (_("bfd_mach_o_read_symtab_symbol: unable to read %d bytes at %lu"),
1794 symwidth, (unsigned long) symoff);
1795 return -1;
1796 }
1797
1798 stroff = bfd_h_get_32 (abfd, raw.n_strx);
1799 type = bfd_h_get_8 (abfd, raw.n_type);
1800 symtype = type & BFD_MACH_O_N_TYPE;
1801 section = bfd_h_get_8 (abfd, raw.n_sect);
1802 desc = bfd_h_get_16 (abfd, raw.n_desc);
1803 if (wide)
1804 value = bfd_h_get_64 (abfd, raw.n_value);
1805 else
1806 value = bfd_h_get_32 (abfd, raw.n_value);
1807
1808 if (stroff >= sym->strsize)
1809 {
1810 (*_bfd_error_handler)
1811 (_("bfd_mach_o_read_symtab_symbol: name out of range (%lu >= %lu)"),
1812 (unsigned long) stroff,
1813 (unsigned long) sym->strsize);
1814 return -1;
1815 }
1816
1817 s->symbol.the_bfd = abfd;
1818 s->symbol.name = sym->strtab + stroff;
1819 s->symbol.value = value;
1820 s->symbol.flags = 0x0;
1821 s->symbol.udata.i = 0;
1822 s->n_type = type;
1823 s->n_sect = section;
1824 s->n_desc = desc;
1825
1826 if (type & BFD_MACH_O_N_STAB)
1827 {
1828 s->symbol.flags |= BSF_DEBUGGING;
1829 s->symbol.section = bfd_und_section_ptr;
1830 switch (type)
1831 {
1832 case N_FUN:
1833 case N_STSYM:
1834 case N_LCSYM:
1835 case N_BNSYM:
1836 case N_SLINE:
1837 case N_ENSYM:
1838 case N_ECOMM:
1839 case N_ECOML:
1840 case N_GSYM:
1841 if ((section > 0) && (section <= mdata->nsects))
1842 {
1843 s->symbol.section = mdata->sections[section - 1]->bfdsection;
1844 s->symbol.value =
1845 s->symbol.value - mdata->sections[section - 1]->addr;
1846 }
1847 break;
1848 }
1849 }
1850 else
1851 {
1852 if (type & BFD_MACH_O_N_PEXT)
1853 s->symbol.flags |= BSF_GLOBAL;
1854
1855 if (type & BFD_MACH_O_N_EXT)
1856 s->symbol.flags |= BSF_GLOBAL;
1857
1858 if (!(type & (BFD_MACH_O_N_PEXT | BFD_MACH_O_N_EXT)))
1859 s->symbol.flags |= BSF_LOCAL;
1860
1861 switch (symtype)
1862 {
1863 case BFD_MACH_O_N_UNDF:
1864 if (type == (BFD_MACH_O_N_UNDF | BFD_MACH_O_N_EXT)
1865 && s->symbol.value != 0)
1866 {
1867 /* A common symbol. */
1868 s->symbol.section = bfd_com_section_ptr;
1869 s->symbol.flags = BSF_NO_FLAGS;
1870 }
1871 else
1872 {
1873 s->symbol.section = bfd_und_section_ptr;
1874 if (s->n_desc & BFD_MACH_O_N_WEAK_REF)
1875 s->symbol.flags |= BSF_WEAK;
1876 }
1877 break;
1878 case BFD_MACH_O_N_PBUD:
1879 s->symbol.section = bfd_und_section_ptr;
1880 break;
1881 case BFD_MACH_O_N_ABS:
1882 s->symbol.section = bfd_abs_section_ptr;
1883 break;
1884 case BFD_MACH_O_N_SECT:
1885 if ((section > 0) && (section <= mdata->nsects))
1886 {
1887 s->symbol.section = mdata->sections[section - 1]->bfdsection;
1888 s->symbol.value =
1889 s->symbol.value - mdata->sections[section - 1]->addr;
1890 }
1891 else
1892 {
1893 /* Mach-O uses 0 to mean "no section"; not an error. */
1894 if (section != 0)
1895 {
1896 (*_bfd_error_handler) (_("bfd_mach_o_read_symtab_symbol: "
1897 "symbol \"%s\" specified invalid section %d (max %lu): setting to undefined"),
1898 s->symbol.name, section, mdata->nsects);
1899 }
1900 s->symbol.section = bfd_und_section_ptr;
1901 }
1902 break;
1903 case BFD_MACH_O_N_INDR:
1904 (*_bfd_error_handler) (_("bfd_mach_o_read_symtab_symbol: "
1905 "symbol \"%s\" is unsupported 'indirect' reference: setting to undefined"),
1906 s->symbol.name);
1907 s->symbol.section = bfd_und_section_ptr;
1908 break;
1909 default:
1910 (*_bfd_error_handler) (_("bfd_mach_o_read_symtab_symbol: "
1911 "symbol \"%s\" specified invalid type field 0x%x: setting to undefined"),
1912 s->symbol.name, symtype);
1913 s->symbol.section = bfd_und_section_ptr;
1914 break;
1915 }
1916 }
1917
1918 return 0;
1919 }
1920
1921 static int
1922 bfd_mach_o_read_symtab_strtab (bfd *abfd)
1923 {
1924 bfd_mach_o_data_struct *mdata = bfd_mach_o_get_data (abfd);
1925 bfd_mach_o_symtab_command *sym = mdata->symtab;
1926
1927 /* Fail if there is no symtab. */
1928 if (sym == NULL)
1929 return -1;
1930
1931 /* Success if already loaded. */
1932 if (sym->strtab)
1933 return 0;
1934
1935 if (abfd->flags & BFD_IN_MEMORY)
1936 {
1937 struct bfd_in_memory *b;
1938
1939 b = (struct bfd_in_memory *) abfd->iostream;
1940
1941 if ((sym->stroff + sym->strsize) > b->size)
1942 {
1943 bfd_set_error (bfd_error_file_truncated);
1944 return -1;
1945 }
1946 sym->strtab = (char *) b->buffer + sym->stroff;
1947 }
1948 else
1949 {
1950 sym->strtab = bfd_alloc (abfd, sym->strsize);
1951 if (sym->strtab == NULL)
1952 return -1;
1953
1954 if (bfd_seek (abfd, sym->stroff, SEEK_SET) != 0
1955 || bfd_bread ((void *) sym->strtab, sym->strsize, abfd) != sym->strsize)
1956 {
1957 bfd_set_error (bfd_error_file_truncated);
1958 return -1;
1959 }
1960 }
1961
1962 return 0;
1963 }
1964
1965 static int
1966 bfd_mach_o_read_symtab_symbols (bfd *abfd)
1967 {
1968 bfd_mach_o_data_struct *mdata = bfd_mach_o_get_data (abfd);
1969 bfd_mach_o_symtab_command *sym = mdata->symtab;
1970 unsigned long i;
1971 int ret;
1972
1973 if (sym == NULL || sym->symbols)
1974 {
1975 /* Return now if there are no symbols or if already loaded. */
1976 return 0;
1977 }
1978
1979 sym->symbols = bfd_alloc (abfd, sym->nsyms * sizeof (bfd_mach_o_asymbol));
1980
1981 if (sym->symbols == NULL)
1982 {
1983 (*_bfd_error_handler) (_("bfd_mach_o_read_symtab_symbols: unable to allocate memory for symbols"));
1984 return -1;
1985 }
1986
1987 ret = bfd_mach_o_read_symtab_strtab (abfd);
1988 if (ret != 0)
1989 return ret;
1990
1991 for (i = 0; i < sym->nsyms; i++)
1992 {
1993 ret = bfd_mach_o_read_symtab_symbol (abfd, sym, &sym->symbols[i], i);
1994 if (ret != 0)
1995 return ret;
1996 }
1997
1998 return 0;
1999 }
2000
2001 int
2002 bfd_mach_o_read_dysymtab_symbol (bfd *abfd,
2003 bfd_mach_o_dysymtab_command *dysym,
2004 bfd_mach_o_symtab_command *sym,
2005 bfd_mach_o_asymbol *s,
2006 unsigned long i)
2007 {
2008 unsigned long isymoff = dysym->indirectsymoff + (i * 4);
2009 unsigned long sym_index;
2010 unsigned char raw[4];
2011
2012 BFD_ASSERT (i < dysym->nindirectsyms);
2013
2014 if (bfd_seek (abfd, isymoff, SEEK_SET) != 0
2015 || bfd_bread (raw, sizeof (raw), abfd) != sizeof (raw))
2016 {
2017 (*_bfd_error_handler)
2018 (_("bfd_mach_o_read_dysymtab_symbol: unable to read %lu bytes at %lu"),
2019 (unsigned long) sizeof (raw), isymoff);
2020 return -1;
2021 }
2022 sym_index = bfd_h_get_32 (abfd, raw);
2023
2024 return bfd_mach_o_read_symtab_symbol (abfd, sym, s, sym_index);
2025 }
2026
2027 static const char *
2028 bfd_mach_o_i386_flavour_string (unsigned int flavour)
2029 {
2030 switch ((int) flavour)
2031 {
2032 case BFD_MACH_O_x86_THREAD_STATE32: return "x86_THREAD_STATE32";
2033 case BFD_MACH_O_x86_FLOAT_STATE32: return "x86_FLOAT_STATE32";
2034 case BFD_MACH_O_x86_EXCEPTION_STATE32: return "x86_EXCEPTION_STATE32";
2035 case BFD_MACH_O_x86_THREAD_STATE64: return "x86_THREAD_STATE64";
2036 case BFD_MACH_O_x86_FLOAT_STATE64: return "x86_FLOAT_STATE64";
2037 case BFD_MACH_O_x86_EXCEPTION_STATE64: return "x86_EXCEPTION_STATE64";
2038 case BFD_MACH_O_x86_THREAD_STATE: return "x86_THREAD_STATE";
2039 case BFD_MACH_O_x86_FLOAT_STATE: return "x86_FLOAT_STATE";
2040 case BFD_MACH_O_x86_EXCEPTION_STATE: return "x86_EXCEPTION_STATE";
2041 case BFD_MACH_O_x86_DEBUG_STATE32: return "x86_DEBUG_STATE32";
2042 case BFD_MACH_O_x86_DEBUG_STATE64: return "x86_DEBUG_STATE64";
2043 case BFD_MACH_O_x86_DEBUG_STATE: return "x86_DEBUG_STATE";
2044 case BFD_MACH_O_x86_THREAD_STATE_NONE: return "x86_THREAD_STATE_NONE";
2045 default: return "UNKNOWN";
2046 }
2047 }
2048
2049 static const char *
2050 bfd_mach_o_ppc_flavour_string (unsigned int flavour)
2051 {
2052 switch ((int) flavour)
2053 {
2054 case BFD_MACH_O_PPC_THREAD_STATE: return "PPC_THREAD_STATE";
2055 case BFD_MACH_O_PPC_FLOAT_STATE: return "PPC_FLOAT_STATE";
2056 case BFD_MACH_O_PPC_EXCEPTION_STATE: return "PPC_EXCEPTION_STATE";
2057 case BFD_MACH_O_PPC_VECTOR_STATE: return "PPC_VECTOR_STATE";
2058 case BFD_MACH_O_PPC_THREAD_STATE64: return "PPC_THREAD_STATE64";
2059 case BFD_MACH_O_PPC_EXCEPTION_STATE64: return "PPC_EXCEPTION_STATE64";
2060 default: return "UNKNOWN";
2061 }
2062 }
2063
2064 static int
2065 bfd_mach_o_read_dylinker (bfd *abfd, bfd_mach_o_load_command *command)
2066 {
2067 bfd_mach_o_dylinker_command *cmd = &command->command.dylinker;
2068 struct mach_o_str_command_external raw;
2069 unsigned int nameoff;
2070
2071 BFD_ASSERT ((command->type == BFD_MACH_O_LC_ID_DYLINKER)
2072 || (command->type == BFD_MACH_O_LC_LOAD_DYLINKER));
2073
2074 if (bfd_seek (abfd, command->offset + BFD_MACH_O_LC_SIZE, SEEK_SET) != 0
2075 || bfd_bread (&raw, sizeof (raw), abfd) != sizeof (raw))
2076 return -1;
2077
2078 nameoff = bfd_h_get_32 (abfd, raw.str);
2079
2080 cmd->name_offset = command->offset + nameoff;
2081 cmd->name_len = command->len - nameoff;
2082 cmd->name_str = bfd_alloc (abfd, cmd->name_len);
2083 if (cmd->name_str == NULL)
2084 return -1;
2085 if (bfd_seek (abfd, cmd->name_offset, SEEK_SET) != 0
2086 || bfd_bread (cmd->name_str, cmd->name_len, abfd) != cmd->name_len)
2087 return -1;
2088 return 0;
2089 }
2090
2091 static int
2092 bfd_mach_o_read_dylib (bfd *abfd, bfd_mach_o_load_command *command)
2093 {
2094 bfd_mach_o_dylib_command *cmd = &command->command.dylib;
2095 struct mach_o_dylib_command_external raw;
2096 unsigned int nameoff;
2097
2098 switch (command->type)
2099 {
2100 case BFD_MACH_O_LC_LOAD_DYLIB:
2101 case BFD_MACH_O_LC_LOAD_WEAK_DYLIB:
2102 case BFD_MACH_O_LC_ID_DYLIB:
2103 case BFD_MACH_O_LC_REEXPORT_DYLIB:
2104 case BFD_MACH_O_LC_LOAD_UPWARD_DYLIB:
2105 break;
2106 default:
2107 BFD_FAIL ();
2108 return -1;
2109 }
2110
2111 if (bfd_seek (abfd, command->offset + BFD_MACH_O_LC_SIZE, SEEK_SET) != 0
2112 || bfd_bread (&raw, sizeof (raw), abfd) != sizeof (raw))
2113 return -1;
2114
2115 nameoff = bfd_h_get_32 (abfd, raw.name);
2116 cmd->timestamp = bfd_h_get_32 (abfd, raw.timestamp);
2117 cmd->current_version = bfd_h_get_32 (abfd, raw.current_version);
2118 cmd->compatibility_version = bfd_h_get_32 (abfd, raw.compatibility_version);
2119
2120 cmd->name_offset = command->offset + nameoff;
2121 cmd->name_len = command->len - nameoff;
2122 cmd->name_str = bfd_alloc (abfd, cmd->name_len);
2123 if (cmd->name_str == NULL)
2124 return -1;
2125 if (bfd_seek (abfd, cmd->name_offset, SEEK_SET) != 0
2126 || bfd_bread (cmd->name_str, cmd->name_len, abfd) != cmd->name_len)
2127 return -1;
2128 return 0;
2129 }
2130
2131 static int
2132 bfd_mach_o_read_prebound_dylib (bfd *abfd ATTRIBUTE_UNUSED,
2133 bfd_mach_o_load_command *command ATTRIBUTE_UNUSED)
2134 {
2135 /* bfd_mach_o_prebound_dylib_command *cmd = &command->command.prebound_dylib; */
2136
2137 BFD_ASSERT (command->type == BFD_MACH_O_LC_PREBOUND_DYLIB);
2138 return 0;
2139 }
2140
2141 static int
2142 bfd_mach_o_read_thread (bfd *abfd, bfd_mach_o_load_command *command)
2143 {
2144 bfd_mach_o_data_struct *mdata = bfd_mach_o_get_data (abfd);
2145 bfd_mach_o_thread_command *cmd = &command->command.thread;
2146 unsigned int offset;
2147 unsigned int nflavours;
2148 unsigned int i;
2149
2150 BFD_ASSERT ((command->type == BFD_MACH_O_LC_THREAD)
2151 || (command->type == BFD_MACH_O_LC_UNIXTHREAD));
2152
2153 /* Count the number of threads. */
2154 offset = 8;
2155 nflavours = 0;
2156 while (offset != command->len)
2157 {
2158 struct mach_o_thread_command_external raw;
2159
2160 if (offset >= command->len)
2161 return -1;
2162
2163 if (bfd_seek (abfd, command->offset + offset, SEEK_SET) != 0
2164 || bfd_bread (&raw, sizeof (raw), abfd) != sizeof (raw))
2165 return -1;
2166
2167 offset += sizeof (raw) + bfd_h_get_32 (abfd, raw.count) * 4;
2168 nflavours++;
2169 }
2170
2171 /* Allocate threads. */
2172 cmd->flavours = bfd_alloc
2173 (abfd, nflavours * sizeof (bfd_mach_o_thread_flavour));
2174 if (cmd->flavours == NULL)
2175 return -1;
2176 cmd->nflavours = nflavours;
2177
2178 offset = 8;
2179 nflavours = 0;
2180 while (offset != command->len)
2181 {
2182 struct mach_o_thread_command_external raw;
2183
2184 if (offset >= command->len)
2185 return -1;
2186
2187 if (nflavours >= cmd->nflavours)
2188 return -1;
2189
2190 if (bfd_seek (abfd, command->offset + offset, SEEK_SET) != 0
2191 || bfd_bread (&raw, sizeof (raw), abfd) != sizeof (raw))
2192 return -1;
2193
2194 cmd->flavours[nflavours].flavour = bfd_h_get_32 (abfd, raw.flavour);
2195 cmd->flavours[nflavours].offset = command->offset + offset + sizeof (raw);
2196 cmd->flavours[nflavours].size = bfd_h_get_32 (abfd, raw.count) * 4;
2197 offset += cmd->flavours[nflavours].size + sizeof (raw);
2198 nflavours++;
2199 }
2200
2201 for (i = 0; i < nflavours; i++)
2202 {
2203 asection *bfdsec;
2204 unsigned int snamelen;
2205 char *sname;
2206 const char *flavourstr;
2207 const char *prefix = "LC_THREAD";
2208 unsigned int j = 0;
2209
2210 switch (mdata->header.cputype)
2211 {
2212 case BFD_MACH_O_CPU_TYPE_POWERPC:
2213 case BFD_MACH_O_CPU_TYPE_POWERPC_64:
2214 flavourstr = bfd_mach_o_ppc_flavour_string (cmd->flavours[i].flavour);
2215 break;
2216 case BFD_MACH_O_CPU_TYPE_I386:
2217 case BFD_MACH_O_CPU_TYPE_X86_64:
2218 flavourstr = bfd_mach_o_i386_flavour_string (cmd->flavours[i].flavour);
2219 break;
2220 default:
2221 flavourstr = "UNKNOWN_ARCHITECTURE";
2222 break;
2223 }
2224
2225 snamelen = strlen (prefix) + 1 + 20 + 1 + strlen (flavourstr) + 1;
2226 sname = bfd_alloc (abfd, snamelen);
2227 if (sname == NULL)
2228 return -1;
2229
2230 for (;;)
2231 {
2232 sprintf (sname, "%s.%s.%u", prefix, flavourstr, j);
2233 if (bfd_get_section_by_name (abfd, sname) == NULL)
2234 break;
2235 j++;
2236 }
2237
2238 bfdsec = bfd_make_section_with_flags (abfd, sname, SEC_HAS_CONTENTS);
2239
2240 bfdsec->vma = 0;
2241 bfdsec->lma = 0;
2242 bfdsec->size = cmd->flavours[i].size;
2243 bfdsec->filepos = cmd->flavours[i].offset;
2244 bfdsec->alignment_power = 0x0;
2245
2246 cmd->section = bfdsec;
2247 }
2248
2249 return 0;
2250 }
2251
2252 static int
2253 bfd_mach_o_read_dysymtab (bfd *abfd, bfd_mach_o_load_command *command)
2254 {
2255 bfd_mach_o_dysymtab_command *cmd = &command->command.dysymtab;
2256 bfd_mach_o_data_struct *mdata = bfd_mach_o_get_data (abfd);
2257
2258 BFD_ASSERT (command->type == BFD_MACH_O_LC_DYSYMTAB);
2259
2260 {
2261 struct mach_o_dysymtab_command_external raw;
2262
2263 if (bfd_seek (abfd, command->offset + BFD_MACH_O_LC_SIZE, SEEK_SET) != 0
2264 || bfd_bread (&raw, sizeof (raw), abfd) != sizeof (raw))
2265 return -1;
2266
2267 cmd->ilocalsym = bfd_h_get_32 (abfd, raw.ilocalsym);
2268 cmd->nlocalsym = bfd_h_get_32 (abfd, raw.nlocalsym);
2269 cmd->iextdefsym = bfd_h_get_32 (abfd, raw.iextdefsym);
2270 cmd->nextdefsym = bfd_h_get_32 (abfd, raw.nextdefsym);
2271 cmd->iundefsym = bfd_h_get_32 (abfd, raw.iundefsym);
2272 cmd->nundefsym = bfd_h_get_32 (abfd, raw.nundefsym);
2273 cmd->tocoff = bfd_h_get_32 (abfd, raw.tocoff);
2274 cmd->ntoc = bfd_h_get_32 (abfd, raw.ntoc);
2275 cmd->modtaboff = bfd_h_get_32 (abfd, raw.modtaboff);
2276 cmd->nmodtab = bfd_h_get_32 (abfd, raw.nmodtab);
2277 cmd->extrefsymoff = bfd_h_get_32 (abfd, raw.extrefsymoff);
2278 cmd->nextrefsyms = bfd_h_get_32 (abfd, raw.nextrefsyms);
2279 cmd->indirectsymoff = bfd_h_get_32 (abfd, raw.indirectsymoff);
2280 cmd->nindirectsyms = bfd_h_get_32 (abfd, raw.nindirectsyms);
2281 cmd->extreloff = bfd_h_get_32 (abfd, raw.extreloff);
2282 cmd->nextrel = bfd_h_get_32 (abfd, raw.nextrel);
2283 cmd->locreloff = bfd_h_get_32 (abfd, raw.locreloff);
2284 cmd->nlocrel = bfd_h_get_32 (abfd, raw.nlocrel);
2285 }
2286
2287 if (cmd->nmodtab != 0)
2288 {
2289 unsigned int i;
2290 int wide = bfd_mach_o_wide_p (abfd);
2291 unsigned int module_len = wide ? 56 : 52;
2292
2293 cmd->dylib_module =
2294 bfd_alloc (abfd, cmd->nmodtab * sizeof (bfd_mach_o_dylib_module));
2295 if (cmd->dylib_module == NULL)
2296 return -1;
2297
2298 if (bfd_seek (abfd, cmd->modtaboff, SEEK_SET) != 0)
2299 return -1;
2300
2301 for (i = 0; i < cmd->nmodtab; i++)
2302 {
2303 bfd_mach_o_dylib_module *module = &cmd->dylib_module[i];
2304 unsigned long v;
2305 unsigned char buf[56];
2306
2307 if (bfd_bread ((void *) buf, module_len, abfd) != module_len)
2308 return -1;
2309
2310 module->module_name_idx = bfd_h_get_32 (abfd, buf + 0);
2311 module->iextdefsym = bfd_h_get_32 (abfd, buf + 4);
2312 module->nextdefsym = bfd_h_get_32 (abfd, buf + 8);
2313 module->irefsym = bfd_h_get_32 (abfd, buf + 12);
2314 module->nrefsym = bfd_h_get_32 (abfd, buf + 16);
2315 module->ilocalsym = bfd_h_get_32 (abfd, buf + 20);
2316 module->nlocalsym = bfd_h_get_32 (abfd, buf + 24);
2317 module->iextrel = bfd_h_get_32 (abfd, buf + 28);
2318 module->nextrel = bfd_h_get_32 (abfd, buf + 32);
2319 v = bfd_h_get_32 (abfd, buf +36);
2320 module->iinit = v & 0xffff;
2321 module->iterm = (v >> 16) & 0xffff;
2322 v = bfd_h_get_32 (abfd, buf + 40);
2323 module->ninit = v & 0xffff;
2324 module->nterm = (v >> 16) & 0xffff;
2325 if (wide)
2326 {
2327 module->objc_module_info_size = bfd_h_get_32 (abfd, buf + 44);
2328 module->objc_module_info_addr = bfd_h_get_64 (abfd, buf + 48);
2329 }
2330 else
2331 {
2332 module->objc_module_info_addr = bfd_h_get_32 (abfd, buf + 44);
2333 module->objc_module_info_size = bfd_h_get_32 (abfd, buf + 48);
2334 }
2335 }
2336 }
2337
2338 if (cmd->ntoc != 0)
2339 {
2340 unsigned int i;
2341
2342 cmd->dylib_toc = bfd_alloc
2343 (abfd, cmd->ntoc * sizeof (bfd_mach_o_dylib_table_of_content));
2344 if (cmd->dylib_toc == NULL)
2345 return -1;
2346
2347 if (bfd_seek (abfd, cmd->tocoff, SEEK_SET) != 0)
2348 return -1;
2349
2350 for (i = 0; i < cmd->ntoc; i++)
2351 {
2352 struct mach_o_dylib_table_of_contents_external raw;
2353 bfd_mach_o_dylib_table_of_content *toc = &cmd->dylib_toc[i];
2354
2355 if (bfd_bread (&raw, sizeof (raw), abfd) != sizeof (raw))
2356 return -1;
2357
2358 toc->symbol_index = bfd_h_get_32 (abfd, raw.symbol_index);
2359 toc->module_index = bfd_h_get_32 (abfd, raw.module_index);
2360 }
2361 }
2362
2363 if (cmd->nindirectsyms != 0)
2364 {
2365 unsigned int i;
2366
2367 cmd->indirect_syms = bfd_alloc
2368 (abfd, cmd->nindirectsyms * sizeof (unsigned int));
2369 if (cmd->indirect_syms == NULL)
2370 return -1;
2371
2372 if (bfd_seek (abfd, cmd->indirectsymoff, SEEK_SET) != 0)
2373 return -1;
2374
2375 for (i = 0; i < cmd->nindirectsyms; i++)
2376 {
2377 unsigned char raw[4];
2378 unsigned int *is = &cmd->indirect_syms[i];
2379
2380 if (bfd_bread (raw, sizeof (raw), abfd) != sizeof (raw))
2381 return -1;
2382
2383 *is = bfd_h_get_32 (abfd, raw);
2384 }
2385 }
2386
2387 if (cmd->nextrefsyms != 0)
2388 {
2389 unsigned long v;
2390 unsigned int i;
2391
2392 cmd->ext_refs = bfd_alloc
2393 (abfd, cmd->nextrefsyms * sizeof (bfd_mach_o_dylib_reference));
2394 if (cmd->ext_refs == NULL)
2395 return -1;
2396
2397 if (bfd_seek (abfd, cmd->extrefsymoff, SEEK_SET) != 0)
2398 return -1;
2399
2400 for (i = 0; i < cmd->nextrefsyms; i++)
2401 {
2402 unsigned char raw[4];
2403 bfd_mach_o_dylib_reference *ref = &cmd->ext_refs[i];
2404
2405 if (bfd_bread (raw, sizeof (raw), abfd) != sizeof (raw))
2406 return -1;
2407
2408 /* Fields isym and flags are written as bit-fields, thus we need
2409 a specific processing for endianness. */
2410 v = bfd_h_get_32 (abfd, raw);
2411 if (bfd_big_endian (abfd))
2412 {
2413 ref->isym = (v >> 8) & 0xffffff;
2414 ref->flags = v & 0xff;
2415 }
2416 else
2417 {
2418 ref->isym = v & 0xffffff;
2419 ref->flags = (v >> 24) & 0xff;
2420 }
2421 }
2422 }
2423
2424 if (mdata->dysymtab)
2425 return -1;
2426 mdata->dysymtab = cmd;
2427
2428 return 0;
2429 }
2430
2431 static int
2432 bfd_mach_o_read_symtab (bfd *abfd, bfd_mach_o_load_command *command)
2433 {
2434 bfd_mach_o_symtab_command *symtab = &command->command.symtab;
2435 bfd_mach_o_data_struct *mdata = bfd_mach_o_get_data (abfd);
2436 struct mach_o_symtab_command_external raw;
2437
2438 BFD_ASSERT (command->type == BFD_MACH_O_LC_SYMTAB);
2439
2440 if (bfd_seek (abfd, command->offset + BFD_MACH_O_LC_SIZE, SEEK_SET) != 0
2441 || bfd_bread (&raw, sizeof (raw), abfd) != sizeof (raw))
2442 return -1;
2443
2444 symtab->symoff = bfd_h_get_32 (abfd, raw.symoff);
2445 symtab->nsyms = bfd_h_get_32 (abfd, raw.nsyms);
2446 symtab->stroff = bfd_h_get_32 (abfd, raw.stroff);
2447 symtab->strsize = bfd_h_get_32 (abfd, raw.strsize);
2448 symtab->symbols = NULL;
2449 symtab->strtab = NULL;
2450
2451 if (symtab->nsyms != 0)
2452 abfd->flags |= HAS_SYMS;
2453
2454 if (mdata->symtab)
2455 return -1;
2456 mdata->symtab = symtab;
2457 return 0;
2458 }
2459
2460 static int
2461 bfd_mach_o_read_uuid (bfd *abfd, bfd_mach_o_load_command *command)
2462 {
2463 bfd_mach_o_uuid_command *cmd = &command->command.uuid;
2464
2465 BFD_ASSERT (command->type == BFD_MACH_O_LC_UUID);
2466
2467 if (bfd_seek (abfd, command->offset + BFD_MACH_O_LC_SIZE, SEEK_SET) != 0
2468 || bfd_bread (cmd->uuid, 16, abfd) != 16)
2469 return -1;
2470
2471 return 0;
2472 }
2473
2474 static int
2475 bfd_mach_o_read_linkedit (bfd *abfd, bfd_mach_o_load_command *command)
2476 {
2477 bfd_mach_o_linkedit_command *cmd = &command->command.linkedit;
2478 struct mach_o_linkedit_data_command_external raw;
2479
2480 if (bfd_seek (abfd, command->offset + BFD_MACH_O_LC_SIZE, SEEK_SET) != 0
2481 || bfd_bread (&raw, sizeof (raw), abfd) != sizeof (raw))
2482 return -1;
2483
2484 cmd->dataoff = bfd_get_32 (abfd, raw.dataoff);
2485 cmd->datasize = bfd_get_32 (abfd, raw.datasize);
2486 return 0;
2487 }
2488
2489 static int
2490 bfd_mach_o_read_str (bfd *abfd, bfd_mach_o_load_command *command)
2491 {
2492 bfd_mach_o_str_command *cmd = &command->command.str;
2493 struct mach_o_str_command_external raw;
2494 unsigned long off;
2495
2496 if (bfd_seek (abfd, command->offset + BFD_MACH_O_LC_SIZE, SEEK_SET) != 0
2497 || bfd_bread (&raw, sizeof (raw), abfd) != sizeof (raw))
2498 return -1;
2499
2500 off = bfd_get_32 (abfd, raw.str);
2501 cmd->stroff = command->offset + off;
2502 cmd->str_len = command->len - off;
2503 cmd->str = bfd_alloc (abfd, cmd->str_len);
2504 if (cmd->str == NULL)
2505 return -1;
2506 if (bfd_seek (abfd, cmd->stroff, SEEK_SET) != 0
2507 || bfd_bread ((void *) cmd->str, cmd->str_len, abfd) != cmd->str_len)
2508 return -1;
2509 return 0;
2510 }
2511
2512 static int
2513 bfd_mach_o_read_dyld_info (bfd *abfd, bfd_mach_o_load_command *command)
2514 {
2515 bfd_mach_o_dyld_info_command *cmd = &command->command.dyld_info;
2516 struct mach_o_dyld_info_command_external raw;
2517
2518 if (bfd_seek (abfd, command->offset + BFD_MACH_O_LC_SIZE, SEEK_SET) != 0
2519 || bfd_bread (&raw, sizeof (raw), abfd) != sizeof (raw))
2520 return -1;
2521
2522 cmd->rebase_off = bfd_get_32 (abfd, raw.rebase_off);
2523 cmd->rebase_size = bfd_get_32 (abfd, raw.rebase_size);
2524 cmd->bind_off = bfd_get_32 (abfd, raw.bind_off);
2525 cmd->bind_size = bfd_get_32 (abfd, raw.bind_size);
2526 cmd->weak_bind_off = bfd_get_32 (abfd, raw.weak_bind_off);
2527 cmd->weak_bind_size = bfd_get_32 (abfd, raw.weak_bind_size);
2528 cmd->lazy_bind_off = bfd_get_32 (abfd, raw.lazy_bind_off);
2529 cmd->lazy_bind_size = bfd_get_32 (abfd, raw.lazy_bind_size);
2530 cmd->export_off = bfd_get_32 (abfd, raw.export_off);
2531 cmd->export_size = bfd_get_32 (abfd, raw.export_size);
2532 return 0;
2533 }
2534
2535 static bfd_boolean
2536 bfd_mach_o_read_version_min (bfd *abfd, bfd_mach_o_load_command *command)
2537 {
2538 bfd_mach_o_version_min_command *cmd = &command->command.version_min;
2539 struct mach_o_version_min_command_external raw;
2540 unsigned int ver;
2541
2542 if (bfd_seek (abfd, command->offset + BFD_MACH_O_LC_SIZE, SEEK_SET) != 0
2543 || bfd_bread (&raw, sizeof (raw), abfd) != sizeof (raw))
2544 return FALSE;
2545
2546 ver = bfd_get_32 (abfd, raw.version);
2547 cmd->rel = ver >> 16;
2548 cmd->maj = ver >> 8;
2549 cmd->min = ver;
2550 cmd->reserved = bfd_get_32 (abfd, raw.reserved);
2551 return TRUE;
2552 }
2553
2554 static int
2555 bfd_mach_o_read_segment (bfd *abfd,
2556 bfd_mach_o_load_command *command,
2557 unsigned int wide)
2558 {
2559 bfd_mach_o_segment_command *seg = &command->command.segment;
2560 unsigned long i;
2561
2562 if (wide)
2563 {
2564 struct mach_o_segment_command_64_external raw;
2565
2566 BFD_ASSERT (command->type == BFD_MACH_O_LC_SEGMENT_64);
2567
2568 if (bfd_seek (abfd, command->offset + BFD_MACH_O_LC_SIZE, SEEK_SET) != 0
2569 || bfd_bread (&raw, sizeof (raw), abfd) != sizeof (raw))
2570 return -1;
2571
2572 memcpy (seg->segname, raw.segname, 16);
2573 seg->segname[16] = '\0';
2574
2575 seg->vmaddr = bfd_h_get_64 (abfd, raw.vmaddr);
2576 seg->vmsize = bfd_h_get_64 (abfd, raw.vmsize);
2577 seg->fileoff = bfd_h_get_64 (abfd, raw.fileoff);
2578 seg->filesize = bfd_h_get_64 (abfd, raw.filesize);
2579 seg->maxprot = bfd_h_get_32 (abfd, raw.maxprot);
2580 seg->initprot = bfd_h_get_32 (abfd, raw.initprot);
2581 seg->nsects = bfd_h_get_32 (abfd, raw.nsects);
2582 seg->flags = bfd_h_get_32 (abfd, raw.flags);
2583 }
2584 else
2585 {
2586 struct mach_o_segment_command_32_external raw;
2587
2588 BFD_ASSERT (command->type == BFD_MACH_O_LC_SEGMENT);
2589
2590 if (bfd_seek (abfd, command->offset + BFD_MACH_O_LC_SIZE, SEEK_SET) != 0
2591 || bfd_bread (&raw, sizeof (raw), abfd) != sizeof (raw))
2592 return -1;
2593
2594 memcpy (seg->segname, raw.segname, 16);
2595 seg->segname[16] = '\0';
2596
2597 seg->vmaddr = bfd_h_get_32 (abfd, raw.vmaddr);
2598 seg->vmsize = bfd_h_get_32 (abfd, raw.vmsize);
2599 seg->fileoff = bfd_h_get_32 (abfd, raw.fileoff);
2600 seg->filesize = bfd_h_get_32 (abfd, raw.filesize);
2601 seg->maxprot = bfd_h_get_32 (abfd, raw.maxprot);
2602 seg->initprot = bfd_h_get_32 (abfd, raw.initprot);
2603 seg->nsects = bfd_h_get_32 (abfd, raw.nsects);
2604 seg->flags = bfd_h_get_32 (abfd, raw.flags);
2605 }
2606 seg->sect_head = NULL;
2607 seg->sect_tail = NULL;
2608
2609 for (i = 0; i < seg->nsects; i++)
2610 {
2611 bfd_vma segoff;
2612 asection *sec;
2613
2614 if (wide)
2615 segoff = command->offset + BFD_MACH_O_LC_SEGMENT_64_SIZE
2616 + (i * BFD_MACH_O_SECTION_64_SIZE);
2617 else
2618 segoff = command->offset + BFD_MACH_O_LC_SEGMENT_SIZE
2619 + (i * BFD_MACH_O_SECTION_SIZE);
2620
2621 sec = bfd_mach_o_read_section (abfd, segoff, seg->initprot, wide);
2622 if (sec == NULL)
2623 return -1;
2624
2625 bfd_mach_o_append_section_to_segment (seg, sec);
2626 }
2627
2628 return 0;
2629 }
2630
2631 static int
2632 bfd_mach_o_read_segment_32 (bfd *abfd, bfd_mach_o_load_command *command)
2633 {
2634 return bfd_mach_o_read_segment (abfd, command, 0);
2635 }
2636
2637 static int
2638 bfd_mach_o_read_segment_64 (bfd *abfd, bfd_mach_o_load_command *command)
2639 {
2640 return bfd_mach_o_read_segment (abfd, command, 1);
2641 }
2642
2643 static int
2644 bfd_mach_o_read_command (bfd *abfd, bfd_mach_o_load_command *command)
2645 {
2646 struct mach_o_load_command_external raw;
2647 unsigned int cmd;
2648
2649 /* Read command type and length. */
2650 if (bfd_seek (abfd, command->offset, SEEK_SET) != 0
2651 || bfd_bread (&raw, BFD_MACH_O_LC_SIZE, abfd) != BFD_MACH_O_LC_SIZE)
2652 return -1;
2653
2654 cmd = bfd_h_get_32 (abfd, raw.cmd);
2655 command->type = cmd & ~BFD_MACH_O_LC_REQ_DYLD;
2656 command->type_required = cmd & BFD_MACH_O_LC_REQ_DYLD ? TRUE : FALSE;
2657 command->len = bfd_h_get_32 (abfd, raw.cmdsize);
2658
2659 switch (command->type)
2660 {
2661 case BFD_MACH_O_LC_SEGMENT:
2662 if (bfd_mach_o_read_segment_32 (abfd, command) != 0)
2663 return -1;
2664 break;
2665 case BFD_MACH_O_LC_SEGMENT_64:
2666 if (bfd_mach_o_read_segment_64 (abfd, command) != 0)
2667 return -1;
2668 break;
2669 case BFD_MACH_O_LC_SYMTAB:
2670 if (bfd_mach_o_read_symtab (abfd, command) != 0)
2671 return -1;
2672 break;
2673 case BFD_MACH_O_LC_SYMSEG:
2674 break;
2675 case BFD_MACH_O_LC_THREAD:
2676 case BFD_MACH_O_LC_UNIXTHREAD:
2677 if (bfd_mach_o_read_thread (abfd, command) != 0)
2678 return -1;
2679 break;
2680 case BFD_MACH_O_LC_LOAD_DYLINKER:
2681 case BFD_MACH_O_LC_ID_DYLINKER:
2682 if (bfd_mach_o_read_dylinker (abfd, command) != 0)
2683 return -1;
2684 break;
2685 case BFD_MACH_O_LC_LOAD_DYLIB:
2686 case BFD_MACH_O_LC_ID_DYLIB:
2687 case BFD_MACH_O_LC_LOAD_WEAK_DYLIB:
2688 case BFD_MACH_O_LC_REEXPORT_DYLIB:
2689 case BFD_MACH_O_LC_LOAD_UPWARD_DYLIB:
2690 if (bfd_mach_o_read_dylib (abfd, command) != 0)
2691 return -1;
2692 break;
2693 case BFD_MACH_O_LC_PREBOUND_DYLIB:
2694 if (bfd_mach_o_read_prebound_dylib (abfd, command) != 0)
2695 return -1;
2696 break;
2697 case BFD_MACH_O_LC_LOADFVMLIB:
2698 case BFD_MACH_O_LC_IDFVMLIB:
2699 case BFD_MACH_O_LC_IDENT:
2700 case BFD_MACH_O_LC_FVMFILE:
2701 case BFD_MACH_O_LC_PREPAGE:
2702 case BFD_MACH_O_LC_ROUTINES:
2703 case BFD_MACH_O_LC_ROUTINES_64:
2704 break;
2705 case BFD_MACH_O_LC_SUB_FRAMEWORK:
2706 case BFD_MACH_O_LC_SUB_UMBRELLA:
2707 case BFD_MACH_O_LC_SUB_LIBRARY:
2708 case BFD_MACH_O_LC_SUB_CLIENT:
2709 case BFD_MACH_O_LC_RPATH:
2710 if (bfd_mach_o_read_str (abfd, command) != 0)
2711 return -1;
2712 break;
2713 case BFD_MACH_O_LC_DYSYMTAB:
2714 if (bfd_mach_o_read_dysymtab (abfd, command) != 0)
2715 return -1;
2716 break;
2717 case BFD_MACH_O_LC_TWOLEVEL_HINTS:
2718 case BFD_MACH_O_LC_PREBIND_CKSUM:
2719 break;
2720 case BFD_MACH_O_LC_UUID:
2721 if (bfd_mach_o_read_uuid (abfd, command) != 0)
2722 return -1;
2723 break;
2724 case BFD_MACH_O_LC_CODE_SIGNATURE:
2725 case BFD_MACH_O_LC_SEGMENT_SPLIT_INFO:
2726 case BFD_MACH_O_LC_FUNCTION_STARTS:
2727 if (bfd_mach_o_read_linkedit (abfd, command) != 0)
2728 return -1;
2729 break;
2730 case BFD_MACH_O_LC_DYLD_INFO:
2731 if (bfd_mach_o_read_dyld_info (abfd, command) != 0)
2732 return -1;
2733 break;
2734 case BFD_MACH_O_LC_VERSION_MIN_MACOSX:
2735 case BFD_MACH_O_LC_VERSION_MIN_IPHONEOS:
2736 if (!bfd_mach_o_read_version_min (abfd, command))
2737 return -1;
2738 break;
2739 default:
2740 (*_bfd_error_handler)(_("%B: unable to read unknown load command 0x%lx"),
2741 abfd, (unsigned long) command->type);
2742 break;
2743 }
2744
2745 return 0;
2746 }
2747
2748 static void
2749 bfd_mach_o_flatten_sections (bfd *abfd)
2750 {
2751 bfd_mach_o_data_struct *mdata = bfd_mach_o_get_data (abfd);
2752 long csect = 0;
2753 unsigned long i;
2754
2755 /* Count total number of sections. */
2756 mdata->nsects = 0;
2757
2758 for (i = 0; i < mdata->header.ncmds; i++)
2759 {
2760 if (mdata->commands[i].type == BFD_MACH_O_LC_SEGMENT
2761 || mdata->commands[i].type == BFD_MACH_O_LC_SEGMENT_64)
2762 {
2763 bfd_mach_o_segment_command *seg;
2764
2765 seg = &mdata->commands[i].command.segment;
2766 mdata->nsects += seg->nsects;
2767 }
2768 }
2769
2770 /* Allocate sections array. */
2771 mdata->sections = bfd_alloc (abfd,
2772 mdata->nsects * sizeof (bfd_mach_o_section *));
2773
2774 /* Fill the array. */
2775 csect = 0;
2776
2777 for (i = 0; i < mdata->header.ncmds; i++)
2778 {
2779 if (mdata->commands[i].type == BFD_MACH_O_LC_SEGMENT
2780 || mdata->commands[i].type == BFD_MACH_O_LC_SEGMENT_64)
2781 {
2782 bfd_mach_o_segment_command *seg;
2783 bfd_mach_o_section *sec;
2784
2785 seg = &mdata->commands[i].command.segment;
2786 BFD_ASSERT (csect + seg->nsects <= mdata->nsects);
2787
2788 for (sec = seg->sect_head; sec != NULL; sec = sec->next)
2789 mdata->sections[csect++] = sec;
2790 }
2791 }
2792 }
2793
2794 int
2795 bfd_mach_o_scan_start_address (bfd *abfd)
2796 {
2797 bfd_mach_o_data_struct *mdata = bfd_mach_o_get_data (abfd);
2798 bfd_mach_o_thread_command *cmd = NULL;
2799 unsigned long i;
2800
2801 for (i = 0; i < mdata->header.ncmds; i++)
2802 {
2803 if ((mdata->commands[i].type == BFD_MACH_O_LC_THREAD) ||
2804 (mdata->commands[i].type == BFD_MACH_O_LC_UNIXTHREAD))
2805 {
2806 if (cmd == NULL)
2807 cmd = &mdata->commands[i].command.thread;
2808 else
2809 return 0;
2810 }
2811 }
2812
2813 if (cmd == NULL)
2814 return 0;
2815
2816 for (i = 0; i < cmd->nflavours; i++)
2817 {
2818 if ((mdata->header.cputype == BFD_MACH_O_CPU_TYPE_I386)
2819 && (cmd->flavours[i].flavour
2820 == (unsigned long) BFD_MACH_O_x86_THREAD_STATE32))
2821 {
2822 unsigned char buf[4];
2823
2824 if (bfd_seek (abfd, cmd->flavours[i].offset + 40, SEEK_SET) != 0
2825 || bfd_bread (buf, 4, abfd) != 4)
2826 return -1;
2827
2828 abfd->start_address = bfd_h_get_32 (abfd, buf);
2829 }
2830 else if ((mdata->header.cputype == BFD_MACH_O_CPU_TYPE_POWERPC)
2831 && (cmd->flavours[i].flavour == BFD_MACH_O_PPC_THREAD_STATE))
2832 {
2833 unsigned char buf[4];
2834
2835 if (bfd_seek (abfd, cmd->flavours[i].offset + 0, SEEK_SET) != 0
2836 || bfd_bread (buf, 4, abfd) != 4)
2837 return -1;
2838
2839 abfd->start_address = bfd_h_get_32 (abfd, buf);
2840 }
2841 else if ((mdata->header.cputype == BFD_MACH_O_CPU_TYPE_POWERPC_64)
2842 && (cmd->flavours[i].flavour == BFD_MACH_O_PPC_THREAD_STATE64))
2843 {
2844 unsigned char buf[8];
2845
2846 if (bfd_seek (abfd, cmd->flavours[i].offset + 0, SEEK_SET) != 0
2847 || bfd_bread (buf, 8, abfd) != 8)
2848 return -1;
2849
2850 abfd->start_address = bfd_h_get_64 (abfd, buf);
2851 }
2852 else if ((mdata->header.cputype == BFD_MACH_O_CPU_TYPE_X86_64)
2853 && (cmd->flavours[i].flavour == BFD_MACH_O_x86_THREAD_STATE64))
2854 {
2855 unsigned char buf[8];
2856
2857 if (bfd_seek (abfd, cmd->flavours[i].offset + (16 * 8), SEEK_SET) != 0
2858 || bfd_bread (buf, 8, abfd) != 8)
2859 return -1;
2860
2861 abfd->start_address = bfd_h_get_64 (abfd, buf);
2862 }
2863 }
2864
2865 return 0;
2866 }
2867
2868 bfd_boolean
2869 bfd_mach_o_set_arch_mach (bfd *abfd,
2870 enum bfd_architecture arch,
2871 unsigned long machine)
2872 {
2873 bfd_mach_o_backend_data *bed = bfd_mach_o_get_backend_data (abfd);
2874
2875 /* If this isn't the right architecture for this backend, and this
2876 isn't the generic backend, fail. */
2877 if (arch != bed->arch
2878 && arch != bfd_arch_unknown
2879 && bed->arch != bfd_arch_unknown)
2880 return FALSE;
2881
2882 return bfd_default_set_arch_mach (abfd, arch, machine);
2883 }
2884
2885 int
2886 bfd_mach_o_scan (bfd *abfd,
2887 bfd_mach_o_header *header,
2888 bfd_mach_o_data_struct *mdata)
2889 {
2890 unsigned int i;
2891 enum bfd_architecture cputype;
2892 unsigned long cpusubtype;
2893 unsigned int hdrsize;
2894
2895 hdrsize = mach_o_wide_p (header) ?
2896 BFD_MACH_O_HEADER_64_SIZE : BFD_MACH_O_HEADER_SIZE;
2897
2898 mdata->header = *header;
2899
2900 abfd->flags = abfd->flags & BFD_IN_MEMORY;
2901 switch (header->filetype)
2902 {
2903 case BFD_MACH_O_MH_OBJECT:
2904 abfd->flags |= HAS_RELOC;
2905 break;
2906 case BFD_MACH_O_MH_EXECUTE:
2907 abfd->flags |= EXEC_P;
2908 break;
2909 case BFD_MACH_O_MH_DYLIB:
2910 case BFD_MACH_O_MH_BUNDLE:
2911 abfd->flags |= DYNAMIC;
2912 break;
2913 }
2914
2915 abfd->tdata.mach_o_data = mdata;
2916
2917 bfd_mach_o_convert_architecture (header->cputype, header->cpusubtype,
2918 &cputype, &cpusubtype);
2919 if (cputype == bfd_arch_unknown)
2920 {
2921 (*_bfd_error_handler) (_("bfd_mach_o_scan: unknown architecture 0x%lx/0x%lx"),
2922 header->cputype, header->cpusubtype);
2923 return -1;
2924 }
2925
2926 bfd_set_arch_mach (abfd, cputype, cpusubtype);
2927
2928 if (header->ncmds != 0)
2929 {
2930 mdata->commands = bfd_alloc
2931 (abfd, header->ncmds * sizeof (bfd_mach_o_load_command));
2932 if (mdata->commands == NULL)
2933 return -1;
2934
2935 for (i = 0; i < header->ncmds; i++)
2936 {
2937 bfd_mach_o_load_command *cur = &mdata->commands[i];
2938
2939 if (i == 0)
2940 cur->offset = hdrsize;
2941 else
2942 {
2943 bfd_mach_o_load_command *prev = &mdata->commands[i - 1];
2944 cur->offset = prev->offset + prev->len;
2945 }
2946
2947 if (bfd_mach_o_read_command (abfd, cur) < 0)
2948 return -1;
2949 }
2950 }
2951
2952 if (bfd_mach_o_scan_start_address (abfd) < 0)
2953 return -1;
2954
2955 bfd_mach_o_flatten_sections (abfd);
2956 return 0;
2957 }
2958
2959 bfd_boolean
2960 bfd_mach_o_mkobject_init (bfd *abfd)
2961 {
2962 bfd_mach_o_data_struct *mdata = NULL;
2963
2964 mdata = bfd_alloc (abfd, sizeof (bfd_mach_o_data_struct));
2965 if (mdata == NULL)
2966 return FALSE;
2967 abfd->tdata.mach_o_data = mdata;
2968
2969 mdata->header.magic = 0;
2970 mdata->header.cputype = 0;
2971 mdata->header.cpusubtype = 0;
2972 mdata->header.filetype = 0;
2973 mdata->header.ncmds = 0;
2974 mdata->header.sizeofcmds = 0;
2975 mdata->header.flags = 0;
2976 mdata->header.byteorder = BFD_ENDIAN_UNKNOWN;
2977 mdata->commands = NULL;
2978 mdata->nsects = 0;
2979 mdata->sections = NULL;
2980
2981 return TRUE;
2982 }
2983
2984 static bfd_boolean
2985 bfd_mach_o_gen_mkobject (bfd *abfd)
2986 {
2987 bfd_mach_o_data_struct *mdata;
2988
2989 if (!bfd_mach_o_mkobject_init (abfd))
2990 return FALSE;
2991
2992 mdata = bfd_mach_o_get_data (abfd);
2993 mdata->header.magic = BFD_MACH_O_MH_MAGIC;
2994 mdata->header.cputype = 0;
2995 mdata->header.cpusubtype = 0;
2996 mdata->header.byteorder = abfd->xvec->byteorder;
2997 mdata->header.version = 1;
2998
2999 return TRUE;
3000 }
3001
3002 const bfd_target *
3003 bfd_mach_o_header_p (bfd *abfd,
3004 bfd_mach_o_filetype filetype,
3005 bfd_mach_o_cpu_type cputype)
3006 {
3007 struct bfd_preserve preserve;
3008 bfd_mach_o_header header;
3009
3010 preserve.marker = NULL;
3011 if (!bfd_mach_o_read_header (abfd, &header))
3012 goto wrong;
3013
3014 if (! (header.byteorder == BFD_ENDIAN_BIG
3015 || header.byteorder == BFD_ENDIAN_LITTLE))
3016 {
3017 (*_bfd_error_handler) (_("unknown header byte-order value 0x%lx"),
3018 (unsigned long) header.byteorder);
3019 goto wrong;
3020 }
3021
3022 if (! ((header.byteorder == BFD_ENDIAN_BIG
3023 && abfd->xvec->byteorder == BFD_ENDIAN_BIG
3024 && abfd->xvec->header_byteorder == BFD_ENDIAN_BIG)
3025 || (header.byteorder == BFD_ENDIAN_LITTLE
3026 && abfd->xvec->byteorder == BFD_ENDIAN_LITTLE
3027 && abfd->xvec->header_byteorder == BFD_ENDIAN_LITTLE)))
3028 goto wrong;
3029
3030 /* Check cputype and filetype.
3031 In case of wildcard, do not accept magics that are handled by existing
3032 targets. */
3033 if (cputype)
3034 {
3035 if (header.cputype != cputype)
3036 goto wrong;
3037 }
3038 else
3039 {
3040 switch (header.cputype)
3041 {
3042 case BFD_MACH_O_CPU_TYPE_I386:
3043 /* Handled by mach-o-i386 */
3044 goto wrong;
3045 default:
3046 break;
3047 }
3048 }
3049 if (filetype)
3050 {
3051 if (header.filetype != filetype)
3052 goto wrong;
3053 }
3054 else
3055 {
3056 switch (header.filetype)
3057 {
3058 case BFD_MACH_O_MH_CORE:
3059 /* Handled by core_p */
3060 goto wrong;
3061 default:
3062 break;
3063 }
3064 }
3065
3066 preserve.marker = bfd_zalloc (abfd, sizeof (bfd_mach_o_data_struct));
3067 if (preserve.marker == NULL
3068 || !bfd_preserve_save (abfd, &preserve))
3069 goto fail;
3070
3071 if (bfd_mach_o_scan (abfd, &header,
3072 (bfd_mach_o_data_struct *) preserve.marker) != 0)
3073 goto wrong;
3074
3075 bfd_preserve_finish (abfd, &preserve);
3076 return abfd->xvec;
3077
3078 wrong:
3079 bfd_set_error (bfd_error_wrong_format);
3080
3081 fail:
3082 if (preserve.marker != NULL)
3083 bfd_preserve_restore (abfd, &preserve);
3084 return NULL;
3085 }
3086
3087 static const bfd_target *
3088 bfd_mach_o_gen_object_p (bfd *abfd)
3089 {
3090 return bfd_mach_o_header_p (abfd, 0, 0);
3091 }
3092
3093 static const bfd_target *
3094 bfd_mach_o_gen_core_p (bfd *abfd)
3095 {
3096 return bfd_mach_o_header_p (abfd, BFD_MACH_O_MH_CORE, 0);
3097 }
3098
3099 typedef struct mach_o_fat_archentry
3100 {
3101 unsigned long cputype;
3102 unsigned long cpusubtype;
3103 unsigned long offset;
3104 unsigned long size;
3105 unsigned long align;
3106 } mach_o_fat_archentry;
3107
3108 typedef struct mach_o_fat_data_struct
3109 {
3110 unsigned long magic;
3111 unsigned long nfat_arch;
3112 mach_o_fat_archentry *archentries;
3113 } mach_o_fat_data_struct;
3114
3115 const bfd_target *
3116 bfd_mach_o_archive_p (bfd *abfd)
3117 {
3118 mach_o_fat_data_struct *adata = NULL;
3119 struct mach_o_fat_header_external hdr;
3120 unsigned long i;
3121
3122 if (bfd_seek (abfd, 0, SEEK_SET) != 0
3123 || bfd_bread (&hdr, sizeof (hdr), abfd) != sizeof (hdr))
3124 goto error;
3125
3126 adata = bfd_alloc (abfd, sizeof (mach_o_fat_data_struct));
3127 if (adata == NULL)
3128 goto error;
3129
3130 adata->magic = bfd_getb32 (hdr.magic);
3131 adata->nfat_arch = bfd_getb32 (hdr.nfat_arch);
3132 if (adata->magic != 0xcafebabe)
3133 goto error;
3134 /* Avoid matching Java bytecode files, which have the same magic number.
3135 In the Java bytecode file format this field contains the JVM version,
3136 which starts at 43.0. */
3137 if (adata->nfat_arch > 30)
3138 goto error;
3139
3140 adata->archentries =
3141 bfd_alloc (abfd, adata->nfat_arch * sizeof (mach_o_fat_archentry));
3142 if (adata->archentries == NULL)
3143 goto error;
3144
3145 for (i = 0; i < adata->nfat_arch; i++)
3146 {
3147 struct mach_o_fat_arch_external arch;
3148 if (bfd_bread (&arch, sizeof (arch), abfd) != sizeof (arch))
3149 goto error;
3150 adata->archentries[i].cputype = bfd_getb32 (arch.cputype);
3151 adata->archentries[i].cpusubtype = bfd_getb32 (arch.cpusubtype);
3152 adata->archentries[i].offset = bfd_getb32 (arch.offset);
3153 adata->archentries[i].size = bfd_getb32 (arch.size);
3154 adata->archentries[i].align = bfd_getb32 (arch.align);
3155 }
3156
3157 abfd->tdata.mach_o_fat_data = adata;
3158 return abfd->xvec;
3159
3160 error:
3161 if (adata != NULL)
3162 bfd_release (abfd, adata);
3163 bfd_set_error (bfd_error_wrong_format);
3164 return NULL;
3165 }
3166
3167 bfd *
3168 bfd_mach_o_openr_next_archived_file (bfd *archive, bfd *prev)
3169 {
3170 mach_o_fat_data_struct *adata;
3171 mach_o_fat_archentry *entry = NULL;
3172 unsigned long i;
3173 bfd *nbfd;
3174 enum bfd_architecture arch_type;
3175 unsigned long arch_subtype;
3176
3177 adata = (mach_o_fat_data_struct *) archive->tdata.mach_o_fat_data;
3178 BFD_ASSERT (adata != NULL);
3179
3180 /* Find index of previous entry. */
3181 if (prev == NULL)
3182 i = 0; /* Start at first one. */
3183 else
3184 {
3185 for (i = 0; i < adata->nfat_arch; i++)
3186 {
3187 if (adata->archentries[i].offset == prev->origin)
3188 break;
3189 }
3190
3191 if (i == adata->nfat_arch)
3192 {
3193 /* Not found. */
3194 bfd_set_error (bfd_error_bad_value);
3195 return NULL;
3196 }
3197 i++; /* Get next entry. */
3198 }
3199
3200 if (i >= adata->nfat_arch)
3201 {
3202 bfd_set_error (bfd_error_no_more_archived_files);
3203 return NULL;
3204 }
3205
3206 entry = &adata->archentries[i];
3207 nbfd = _bfd_new_bfd_contained_in (archive);
3208 if (nbfd == NULL)
3209 return NULL;
3210
3211 nbfd->origin = entry->offset;
3212
3213 bfd_mach_o_convert_architecture (entry->cputype, entry->cpusubtype,
3214 &arch_type, &arch_subtype);
3215
3216 /* Create the member filename. Use ARCH_NAME. */
3217 nbfd->filename = bfd_printable_arch_mach (arch_type, arch_subtype);
3218 nbfd->iostream = NULL;
3219 bfd_set_arch_mach (nbfd, arch_type, arch_subtype);
3220
3221 return nbfd;
3222 }
3223
3224 /* If ABFD format is FORMAT and architecture is ARCH, return it.
3225 If ABFD is a fat image containing a member that corresponds to FORMAT
3226 and ARCH, returns it.
3227 In other case, returns NULL.
3228 This function allows transparent uses of fat images. */
3229 bfd *
3230 bfd_mach_o_fat_extract (bfd *abfd,
3231 bfd_format format,
3232 const bfd_arch_info_type *arch)
3233 {
3234 bfd *res;
3235 mach_o_fat_data_struct *adata;
3236 unsigned int i;
3237
3238 if (bfd_check_format (abfd, format))
3239 {
3240 if (bfd_get_arch_info (abfd) == arch)
3241 return abfd;
3242 return NULL;
3243 }
3244 if (!bfd_check_format (abfd, bfd_archive)
3245 || abfd->xvec != &mach_o_fat_vec)
3246 return NULL;
3247
3248 /* This is a Mach-O fat image. */
3249 adata = (mach_o_fat_data_struct *) abfd->tdata.mach_o_fat_data;
3250 BFD_ASSERT (adata != NULL);
3251
3252 for (i = 0; i < adata->nfat_arch; i++)
3253 {
3254 struct mach_o_fat_archentry *e = &adata->archentries[i];
3255 enum bfd_architecture cpu_type;
3256 unsigned long cpu_subtype;
3257
3258 bfd_mach_o_convert_architecture (e->cputype, e->cpusubtype,
3259 &cpu_type, &cpu_subtype);
3260 if (cpu_type != arch->arch || cpu_subtype != arch->mach)
3261 continue;
3262
3263 /* The architecture is found. */
3264 res = _bfd_new_bfd_contained_in (abfd);
3265 if (res == NULL)
3266 return NULL;
3267
3268 res->origin = e->offset;
3269
3270 res->filename = bfd_printable_arch_mach (cpu_type, cpu_subtype);
3271 res->iostream = NULL;
3272
3273 if (bfd_check_format (res, format))
3274 {
3275 BFD_ASSERT (bfd_get_arch_info (res) == arch);
3276 return res;
3277 }
3278 bfd_close (res);
3279 return NULL;
3280 }
3281
3282 return NULL;
3283 }
3284
3285 int
3286 bfd_mach_o_lookup_command (bfd *abfd,
3287 bfd_mach_o_load_command_type type,
3288 bfd_mach_o_load_command **mcommand)
3289 {
3290 struct mach_o_data_struct *md = bfd_mach_o_get_data (abfd);
3291 bfd_mach_o_load_command *ncmd = NULL;
3292 unsigned int i, num;
3293
3294 BFD_ASSERT (md != NULL);
3295 BFD_ASSERT (mcommand != NULL);
3296
3297 num = 0;
3298 for (i = 0; i < md->header.ncmds; i++)
3299 {
3300 struct bfd_mach_o_load_command *cmd = &md->commands[i];
3301
3302 if (cmd->type != type)
3303 continue;
3304
3305 if (num == 0)
3306 ncmd = cmd;
3307 num++;
3308 }
3309
3310 *mcommand = ncmd;
3311 return num;
3312 }
3313
3314 unsigned long
3315 bfd_mach_o_stack_addr (enum bfd_mach_o_cpu_type type)
3316 {
3317 switch (type)
3318 {
3319 case BFD_MACH_O_CPU_TYPE_MC680x0:
3320 return 0x04000000;
3321 case BFD_MACH_O_CPU_TYPE_MC88000:
3322 return 0xffffe000;
3323 case BFD_MACH_O_CPU_TYPE_POWERPC:
3324 return 0xc0000000;
3325 case BFD_MACH_O_CPU_TYPE_I386:
3326 return 0xc0000000;
3327 case BFD_MACH_O_CPU_TYPE_SPARC:
3328 return 0xf0000000;
3329 case BFD_MACH_O_CPU_TYPE_I860:
3330 return 0;
3331 case BFD_MACH_O_CPU_TYPE_HPPA:
3332 return 0xc0000000 - 0x04000000;
3333 default:
3334 return 0;
3335 }
3336 }
3337
3338 typedef struct bfd_mach_o_xlat_name
3339 {
3340 const char *name;
3341 unsigned long val;
3342 }
3343 bfd_mach_o_xlat_name;
3344
3345 static void
3346 bfd_mach_o_print_flags (const bfd_mach_o_xlat_name *table,
3347 unsigned long val,
3348 FILE *file)
3349 {
3350 int first = 1;
3351
3352 for (; table->name; table++)
3353 {
3354 if (table->val & val)
3355 {
3356 if (!first)
3357 fprintf (file, "+");
3358 fprintf (file, "%s", table->name);
3359 val &= ~table->val;
3360 first = 0;
3361 }
3362 }
3363 if (val)
3364 {
3365 if (!first)
3366 fprintf (file, "+");
3367 fprintf (file, "0x%lx", val);
3368 return;
3369 }
3370 if (first)
3371 fprintf (file, "-");
3372 }
3373
3374 static const char *
3375 bfd_mach_o_get_name_or_null (const bfd_mach_o_xlat_name *table,
3376 unsigned long val)
3377 {
3378 for (; table->name; table++)
3379 if (table->val == val)
3380 return table->name;
3381 return NULL;
3382 }
3383
3384 static const char *
3385 bfd_mach_o_get_name (const bfd_mach_o_xlat_name *table, unsigned long val)
3386 {
3387 const char *res = bfd_mach_o_get_name_or_null (table, val);
3388
3389 if (res == NULL)
3390 return "*UNKNOWN*";
3391 else
3392 return res;
3393 }
3394
3395 static bfd_mach_o_xlat_name bfd_mach_o_cpu_name[] =
3396 {
3397 { "vax", BFD_MACH_O_CPU_TYPE_VAX },
3398 { "mc680x0", BFD_MACH_O_CPU_TYPE_MC680x0 },
3399 { "i386", BFD_MACH_O_CPU_TYPE_I386 },
3400 { "mips", BFD_MACH_O_CPU_TYPE_MIPS },
3401 { "mc98000", BFD_MACH_O_CPU_TYPE_MC98000 },
3402 { "hppa", BFD_MACH_O_CPU_TYPE_HPPA },
3403 { "arm", BFD_MACH_O_CPU_TYPE_ARM },
3404 { "mc88000", BFD_MACH_O_CPU_TYPE_MC88000 },
3405 { "sparc", BFD_MACH_O_CPU_TYPE_SPARC },
3406 { "i860", BFD_MACH_O_CPU_TYPE_I860 },
3407 { "alpha", BFD_MACH_O_CPU_TYPE_ALPHA },
3408 { "powerpc", BFD_MACH_O_CPU_TYPE_POWERPC },
3409 { "powerpc_64", BFD_MACH_O_CPU_TYPE_POWERPC_64 },
3410 { "x86_64", BFD_MACH_O_CPU_TYPE_X86_64 },
3411 { NULL, 0}
3412 };
3413
3414 static bfd_mach_o_xlat_name bfd_mach_o_filetype_name[] =
3415 {
3416 { "object", BFD_MACH_O_MH_OBJECT },
3417 { "execute", BFD_MACH_O_MH_EXECUTE },
3418 { "fvmlib", BFD_MACH_O_MH_FVMLIB },
3419 { "core", BFD_MACH_O_MH_CORE },
3420 { "preload", BFD_MACH_O_MH_PRELOAD },
3421 { "dylib", BFD_MACH_O_MH_DYLIB },
3422 { "dylinker", BFD_MACH_O_MH_DYLINKER },
3423 { "bundle", BFD_MACH_O_MH_BUNDLE },
3424 { "dylib_stub", BFD_MACH_O_MH_DYLIB_STUB },
3425 { "dym", BFD_MACH_O_MH_DSYM },
3426 { "kext_bundle", BFD_MACH_O_MH_KEXT_BUNDLE },
3427 { NULL, 0}
3428 };
3429
3430 static bfd_mach_o_xlat_name bfd_mach_o_header_flags_name[] =
3431 {
3432 { "noundefs", BFD_MACH_O_MH_NOUNDEFS },
3433 { "incrlink", BFD_MACH_O_MH_INCRLINK },
3434 { "dyldlink", BFD_MACH_O_MH_DYLDLINK },
3435 { "bindatload", BFD_MACH_O_MH_BINDATLOAD },
3436 { "prebound", BFD_MACH_O_MH_PREBOUND },
3437 { "split_segs", BFD_MACH_O_MH_SPLIT_SEGS },
3438 { "lazy_init", BFD_MACH_O_MH_LAZY_INIT },
3439 { "twolevel", BFD_MACH_O_MH_TWOLEVEL },
3440 { "force_flat", BFD_MACH_O_MH_FORCE_FLAT },
3441 { "nomultidefs", BFD_MACH_O_MH_NOMULTIDEFS },
3442 { "nofixprebinding", BFD_MACH_O_MH_NOFIXPREBINDING },
3443 { "prebindable", BFD_MACH_O_MH_PREBINDABLE },
3444 { "allmodsbound", BFD_MACH_O_MH_ALLMODSBOUND },
3445 { "subsections_via_symbols", BFD_MACH_O_MH_SUBSECTIONS_VIA_SYMBOLS },
3446 { "canonical", BFD_MACH_O_MH_CANONICAL },
3447 { "weak_defines", BFD_MACH_O_MH_WEAK_DEFINES },
3448 { "binds_to_weak", BFD_MACH_O_MH_BINDS_TO_WEAK },
3449 { "allow_stack_execution", BFD_MACH_O_MH_ALLOW_STACK_EXECUTION },
3450 { "root_safe", BFD_MACH_O_MH_ROOT_SAFE },
3451 { "setuid_safe", BFD_MACH_O_MH_SETUID_SAFE },
3452 { "no_reexported_dylibs", BFD_MACH_O_MH_NO_REEXPORTED_DYLIBS },
3453 { "pie", BFD_MACH_O_MH_PIE },
3454 { NULL, 0}
3455 };
3456
3457 static bfd_mach_o_xlat_name bfd_mach_o_section_type_name[] =
3458 {
3459 { "regular", BFD_MACH_O_S_REGULAR},
3460 { "zerofill", BFD_MACH_O_S_ZEROFILL},
3461 { "cstring_literals", BFD_MACH_O_S_CSTRING_LITERALS},
3462 { "4byte_literals", BFD_MACH_O_S_4BYTE_LITERALS},
3463 { "8byte_literals", BFD_MACH_O_S_8BYTE_LITERALS},
3464 { "literal_pointers", BFD_MACH_O_S_LITERAL_POINTERS},
3465 { "non_lazy_symbol_pointers", BFD_MACH_O_S_NON_LAZY_SYMBOL_POINTERS},
3466 { "lazy_symbol_pointers", BFD_MACH_O_S_LAZY_SYMBOL_POINTERS},
3467 { "symbol_stubs", BFD_MACH_O_S_SYMBOL_STUBS},
3468 { "mod_init_func_pointers", BFD_MACH_O_S_MOD_INIT_FUNC_POINTERS},
3469 { "mod_fini_func_pointers", BFD_MACH_O_S_MOD_FINI_FUNC_POINTERS},
3470 { "coalesced", BFD_MACH_O_S_COALESCED},
3471 { "gb_zerofill", BFD_MACH_O_S_GB_ZEROFILL},
3472 { "interposing", BFD_MACH_O_S_INTERPOSING},
3473 { "16byte_literals", BFD_MACH_O_S_16BYTE_LITERALS},
3474 { "dtrace_dof", BFD_MACH_O_S_DTRACE_DOF},
3475 { "lazy_dylib_symbol_pointers", BFD_MACH_O_S_LAZY_DYLIB_SYMBOL_POINTERS},
3476 { NULL, 0}
3477 };
3478
3479 static bfd_mach_o_xlat_name bfd_mach_o_section_attribute_name[] =
3480 {
3481 { "loc_reloc", BFD_MACH_O_S_ATTR_LOC_RELOC },
3482 { "ext_reloc", BFD_MACH_O_S_ATTR_EXT_RELOC },
3483 { "some_instructions", BFD_MACH_O_S_ATTR_SOME_INSTRUCTIONS },
3484 { "debug", BFD_MACH_O_S_ATTR_DEBUG },
3485 { "modifying_code", BFD_MACH_O_S_SELF_MODIFYING_CODE },
3486 { "live_support", BFD_MACH_O_S_ATTR_LIVE_SUPPORT },
3487 { "no_dead_strip", BFD_MACH_O_S_ATTR_NO_DEAD_STRIP },
3488 { "strip_static_syms", BFD_MACH_O_S_ATTR_STRIP_STATIC_SYMS },
3489 { "no_toc", BFD_MACH_O_S_ATTR_NO_TOC },
3490 { "pure_instructions", BFD_MACH_O_S_ATTR_PURE_INSTRUCTIONS },
3491 { NULL, 0}
3492 };
3493
3494 static bfd_mach_o_xlat_name bfd_mach_o_load_command_name[] =
3495 {
3496 { "segment", BFD_MACH_O_LC_SEGMENT},
3497 { "symtab", BFD_MACH_O_LC_SYMTAB},
3498 { "symseg", BFD_MACH_O_LC_SYMSEG},
3499 { "thread", BFD_MACH_O_LC_THREAD},
3500 { "unixthread", BFD_MACH_O_LC_UNIXTHREAD},
3501 { "loadfvmlib", BFD_MACH_O_LC_LOADFVMLIB},
3502 { "idfvmlib", BFD_MACH_O_LC_IDFVMLIB},
3503 { "ident", BFD_MACH_O_LC_IDENT},
3504 { "fvmfile", BFD_MACH_O_LC_FVMFILE},
3505 { "prepage", BFD_MACH_O_LC_PREPAGE},
3506 { "dysymtab", BFD_MACH_O_LC_DYSYMTAB},
3507 { "load_dylib", BFD_MACH_O_LC_LOAD_DYLIB},
3508 { "id_dylib", BFD_MACH_O_LC_ID_DYLIB},
3509 { "load_dylinker", BFD_MACH_O_LC_LOAD_DYLINKER},
3510 { "id_dylinker", BFD_MACH_O_LC_ID_DYLINKER},
3511 { "prebound_dylib", BFD_MACH_O_LC_PREBOUND_DYLIB},
3512 { "routines", BFD_MACH_O_LC_ROUTINES},
3513 { "sub_framework", BFD_MACH_O_LC_SUB_FRAMEWORK},
3514 { "sub_umbrella", BFD_MACH_O_LC_SUB_UMBRELLA},
3515 { "sub_client", BFD_MACH_O_LC_SUB_CLIENT},
3516 { "sub_library", BFD_MACH_O_LC_SUB_LIBRARY},
3517 { "twolevel_hints", BFD_MACH_O_LC_TWOLEVEL_HINTS},
3518 { "prebind_cksum", BFD_MACH_O_LC_PREBIND_CKSUM},
3519 { "load_weak_dylib", BFD_MACH_O_LC_LOAD_WEAK_DYLIB},
3520 { "segment_64", BFD_MACH_O_LC_SEGMENT_64},
3521 { "routines_64", BFD_MACH_O_LC_ROUTINES_64},
3522 { "uuid", BFD_MACH_O_LC_UUID},
3523 { "rpath", BFD_MACH_O_LC_RPATH},
3524 { "code_signature", BFD_MACH_O_LC_CODE_SIGNATURE},
3525 { "segment_split_info", BFD_MACH_O_LC_SEGMENT_SPLIT_INFO},
3526 { "reexport_dylib", BFD_MACH_O_LC_REEXPORT_DYLIB},
3527 { "lazy_load_dylib", BFD_MACH_O_LC_LAZY_LOAD_DYLIB},
3528 { "encryption_info", BFD_MACH_O_LC_ENCRYPTION_INFO},
3529 { "dyld_info", BFD_MACH_O_LC_DYLD_INFO},
3530 { "load_upward_lib", BFD_MACH_O_LC_LOAD_UPWARD_DYLIB},
3531 { "version_min_macosx", BFD_MACH_O_LC_VERSION_MIN_MACOSX},
3532 { "version_min_iphoneos", BFD_MACH_O_LC_VERSION_MIN_IPHONEOS},
3533 { "function_starts", BFD_MACH_O_LC_FUNCTION_STARTS},
3534 { "dyld_environment", BFD_MACH_O_LC_DYLD_ENVIRONMENT},
3535 { NULL, 0}
3536 };
3537
3538 /* Get the section type from NAME. Return -1 if NAME is unknown. */
3539
3540 unsigned int
3541 bfd_mach_o_get_section_type_from_name (const char *name)
3542 {
3543 bfd_mach_o_xlat_name *x;
3544
3545 for (x = bfd_mach_o_section_type_name; x->name; x++)
3546 if (strcmp (x->name, name) == 0)
3547 return x->val;
3548 return (unsigned int)-1;
3549 }
3550
3551 /* Get the section attribute from NAME. Return -1 if NAME is unknown. */
3552
3553 unsigned int
3554 bfd_mach_o_get_section_attribute_from_name (const char *name)
3555 {
3556 bfd_mach_o_xlat_name *x;
3557
3558 for (x = bfd_mach_o_section_attribute_name; x->name; x++)
3559 if (strcmp (x->name, name) == 0)
3560 return x->val;
3561 return (unsigned int)-1;
3562 }
3563
3564 static void
3565 bfd_mach_o_print_private_header (bfd *abfd, FILE *file)
3566 {
3567 bfd_mach_o_data_struct *mdata = bfd_mach_o_get_data (abfd);
3568 bfd_mach_o_header *h = &mdata->header;
3569
3570 fputs (_("Mach-O header:\n"), file);
3571 fprintf (file, _(" magic : %08lx\n"), h->magic);
3572 fprintf (file, _(" cputype : %08lx (%s)\n"), h->cputype,
3573 bfd_mach_o_get_name (bfd_mach_o_cpu_name, h->cputype));
3574 fprintf (file, _(" cpusubtype: %08lx\n"), h->cpusubtype);
3575 fprintf (file, _(" filetype : %08lx (%s)\n"),
3576 h->filetype,
3577 bfd_mach_o_get_name (bfd_mach_o_filetype_name, h->filetype));
3578 fprintf (file, _(" ncmds : %08lx (%lu)\n"), h->ncmds, h->ncmds);
3579 fprintf (file, _(" sizeofcmds: %08lx\n"), h->sizeofcmds);
3580 fprintf (file, _(" flags : %08lx ("), h->flags);
3581 bfd_mach_o_print_flags (bfd_mach_o_header_flags_name, h->flags, file);
3582 fputs (_(")\n"), file);
3583 fprintf (file, _(" reserved : %08x\n"), h->reserved);
3584 }
3585
3586 static void
3587 bfd_mach_o_print_section_map (bfd *abfd, FILE *file)
3588 {
3589 bfd_mach_o_data_struct *mdata = bfd_mach_o_get_data (abfd);
3590 unsigned int i;
3591 unsigned int sec_nbr = 0;
3592
3593 fputs (_("Segments and Sections:\n"), file);
3594 fputs (_(" #: Segment name Section name Address\n"), file);
3595
3596 for (i = 0; i < mdata->header.ncmds; i++)
3597 {
3598 bfd_mach_o_segment_command *seg;
3599 bfd_mach_o_section *sec;
3600
3601 if (mdata->commands[i].type != BFD_MACH_O_LC_SEGMENT
3602 && mdata->commands[i].type != BFD_MACH_O_LC_SEGMENT_64)
3603 continue;
3604
3605 seg = &mdata->commands[i].command.segment;
3606
3607 fprintf (file, "[Segment %-16s ", seg->segname);
3608 fprintf_vma (file, seg->vmaddr);
3609 fprintf (file, "-");
3610 fprintf_vma (file, seg->vmaddr + seg->vmsize - 1);
3611 fputc (' ', file);
3612 fputc (seg->initprot & BFD_MACH_O_PROT_READ ? 'r' : '-', file);
3613 fputc (seg->initprot & BFD_MACH_O_PROT_WRITE ? 'w' : '-', file);
3614 fputc (seg->initprot & BFD_MACH_O_PROT_EXECUTE ? 'x' : '-', file);
3615 fprintf (file, "]\n");
3616
3617 for (sec = seg->sect_head; sec != NULL; sec = sec->next)
3618 {
3619 fprintf (file, "%02u: %-16s %-16s ", ++sec_nbr,
3620 sec->segname, sec->sectname);
3621 fprintf_vma (file, sec->addr);
3622 fprintf (file, " ");
3623 fprintf_vma (file, sec->size);
3624 fprintf (file, " %08lx\n", sec->flags);
3625 }
3626 }
3627 }
3628
3629 static void
3630 bfd_mach_o_print_section (bfd *abfd ATTRIBUTE_UNUSED,
3631 bfd_mach_o_section *sec, FILE *file)
3632 {
3633 fprintf (file, " Section: %-16s %-16s (bfdname: %s)\n",
3634 sec->sectname, sec->segname, sec->bfdsection->name);
3635 fprintf (file, " addr: ");
3636 fprintf_vma (file, sec->addr);
3637 fprintf (file, " size: ");
3638 fprintf_vma (file, sec->size);
3639 fprintf (file, " offset: ");
3640 fprintf_vma (file, sec->offset);
3641 fprintf (file, "\n");
3642 fprintf (file, " align: %ld", sec->align);
3643 fprintf (file, " nreloc: %lu reloff: ", sec->nreloc);
3644 fprintf_vma (file, sec->reloff);
3645 fprintf (file, "\n");
3646 fprintf (file, " flags: %08lx (type: %s", sec->flags,
3647 bfd_mach_o_get_name (bfd_mach_o_section_type_name,
3648 sec->flags & BFD_MACH_O_SECTION_TYPE_MASK));
3649 fprintf (file, " attr: ");
3650 bfd_mach_o_print_flags (bfd_mach_o_section_attribute_name,
3651 sec->flags & BFD_MACH_O_SECTION_ATTRIBUTES_MASK,
3652 file);
3653 fprintf (file, ")\n");
3654 switch (sec->flags & BFD_MACH_O_SECTION_TYPE_MASK)
3655 {
3656 case BFD_MACH_O_S_NON_LAZY_SYMBOL_POINTERS:
3657 case BFD_MACH_O_S_LAZY_SYMBOL_POINTERS:
3658 case BFD_MACH_O_S_SYMBOL_STUBS:
3659 fprintf (file, " first indirect sym: %lu", sec->reserved1);
3660 fprintf (file, " (%u entries)",
3661 bfd_mach_o_section_get_nbr_indirect (abfd, sec));
3662 break;
3663 default:
3664 fprintf (file, " reserved1: 0x%lx", sec->reserved1);
3665 break;
3666 }
3667 switch (sec->flags & BFD_MACH_O_SECTION_TYPE_MASK)
3668 {
3669 case BFD_MACH_O_S_SYMBOL_STUBS:
3670 fprintf (file, " stub size: %lu", sec->reserved2);
3671 break;
3672 default:
3673 fprintf (file, " reserved2: 0x%lx", sec->reserved2);
3674 break;
3675 }
3676 fprintf (file, " reserved3: 0x%lx\n", sec->reserved3);
3677 }
3678
3679 static void
3680 bfd_mach_o_print_segment (bfd *abfd ATTRIBUTE_UNUSED,
3681 bfd_mach_o_load_command *cmd, FILE *file)
3682 {
3683 bfd_mach_o_segment_command *seg = &cmd->command.segment;
3684 bfd_mach_o_section *sec;
3685
3686 fprintf (file, " name: %s\n", *seg->segname ? seg->segname : "*none*");
3687 fprintf (file, " vmaddr: ");
3688 fprintf_vma (file, seg->vmaddr);
3689 fprintf (file, " vmsize: ");
3690 fprintf_vma (file, seg->vmsize);
3691 fprintf (file, "\n");
3692 fprintf (file, " fileoff: ");
3693 fprintf_vma (file, seg->fileoff);
3694 fprintf (file, " filesize: ");
3695 fprintf_vma (file, (bfd_vma)seg->filesize);
3696 fprintf (file, " endoff: ");
3697 fprintf_vma (file, (bfd_vma)(seg->fileoff + seg->filesize));
3698 fprintf (file, "\n");
3699 fprintf (file, " nsects: %lu ", seg->nsects);
3700 fprintf (file, " flags: %lx\n", seg->flags);
3701 for (sec = seg->sect_head; sec != NULL; sec = sec->next)
3702 bfd_mach_o_print_section (abfd, sec, file);
3703 }
3704
3705 static void
3706 bfd_mach_o_print_dysymtab (bfd *abfd ATTRIBUTE_UNUSED,
3707 bfd_mach_o_load_command *cmd, FILE *file)
3708 {
3709 bfd_mach_o_dysymtab_command *dysymtab = &cmd->command.dysymtab;
3710 bfd_mach_o_data_struct *mdata = bfd_mach_o_get_data (abfd);
3711 unsigned int i;
3712
3713 fprintf (file, " local symbols: idx: %10lu num: %-8lu",
3714 dysymtab->ilocalsym, dysymtab->nlocalsym);
3715 fprintf (file, " (nxtidx: %lu)\n",
3716 dysymtab->ilocalsym + dysymtab->nlocalsym);
3717 fprintf (file, " external symbols: idx: %10lu num: %-8lu",
3718 dysymtab->iextdefsym, dysymtab->nextdefsym);
3719 fprintf (file, " (nxtidx: %lu)\n",
3720 dysymtab->iextdefsym + dysymtab->nextdefsym);
3721 fprintf (file, " undefined symbols: idx: %10lu num: %-8lu",
3722 dysymtab->iundefsym, dysymtab->nundefsym);
3723 fprintf (file, " (nxtidx: %lu)\n",
3724 dysymtab->iundefsym + dysymtab->nundefsym);
3725 fprintf (file, " table of content: off: 0x%08lx num: %-8lu",
3726 dysymtab->tocoff, dysymtab->ntoc);
3727 fprintf (file, " (endoff: 0x%08lx)\n",
3728 dysymtab->tocoff
3729 + dysymtab->ntoc * BFD_MACH_O_TABLE_OF_CONTENT_SIZE);
3730 fprintf (file, " module table: off: 0x%08lx num: %-8lu",
3731 dysymtab->modtaboff, dysymtab->nmodtab);
3732 fprintf (file, " (endoff: 0x%08lx)\n",
3733 dysymtab->modtaboff + dysymtab->nmodtab
3734 * (mach_o_wide_p (&mdata->header) ?
3735 BFD_MACH_O_DYLIB_MODULE_64_SIZE : BFD_MACH_O_DYLIB_MODULE_SIZE));
3736 fprintf (file, " external reference table: off: 0x%08lx num: %-8lu",
3737 dysymtab->extrefsymoff, dysymtab->nextrefsyms);
3738 fprintf (file, " (endoff: 0x%08lx)\n",
3739 dysymtab->extrefsymoff
3740 + dysymtab->nextrefsyms * BFD_MACH_O_REFERENCE_SIZE);
3741 fprintf (file, " indirect symbol table: off: 0x%08lx num: %-8lu",
3742 dysymtab->indirectsymoff, dysymtab->nindirectsyms);
3743 fprintf (file, " (endoff: 0x%08lx)\n",
3744 dysymtab->indirectsymoff
3745 + dysymtab->nindirectsyms * BFD_MACH_O_INDIRECT_SYMBOL_SIZE);
3746 fprintf (file, " external relocation table: off: 0x%08lx num: %-8lu",
3747 dysymtab->extreloff, dysymtab->nextrel);
3748 fprintf (file, " (endoff: 0x%08lx)\n",
3749 dysymtab->extreloff + dysymtab->nextrel * BFD_MACH_O_RELENT_SIZE);
3750 fprintf (file, " local relocation table: off: 0x%08lx num: %-8lu",
3751 dysymtab->locreloff, dysymtab->nlocrel);
3752 fprintf (file, " (endoff: 0x%08lx)\n",
3753 dysymtab->locreloff + dysymtab->nlocrel * BFD_MACH_O_RELENT_SIZE);
3754
3755 if (dysymtab->ntoc > 0
3756 || dysymtab->nindirectsyms > 0
3757 || dysymtab->nextrefsyms > 0)
3758 {
3759 /* Try to read the symbols to display the toc or indirect symbols. */
3760 bfd_mach_o_read_symtab_symbols (abfd);
3761 }
3762 else if (dysymtab->nmodtab > 0)
3763 {
3764 /* Try to read the strtab to display modules name. */
3765 bfd_mach_o_read_symtab_strtab (abfd);
3766 }
3767
3768 for (i = 0; i < dysymtab->nmodtab; i++)
3769 {
3770 bfd_mach_o_dylib_module *module = &dysymtab->dylib_module[i];
3771 fprintf (file, " module %u:\n", i);
3772 fprintf (file, " name: %lu", module->module_name_idx);
3773 if (mdata->symtab && mdata->symtab->strtab)
3774 fprintf (file, ": %s",
3775 mdata->symtab->strtab + module->module_name_idx);
3776 fprintf (file, "\n");
3777 fprintf (file, " extdefsym: idx: %8lu num: %lu\n",
3778 module->iextdefsym, module->nextdefsym);
3779 fprintf (file, " refsym: idx: %8lu num: %lu\n",
3780 module->irefsym, module->nrefsym);
3781 fprintf (file, " localsym: idx: %8lu num: %lu\n",
3782 module->ilocalsym, module->nlocalsym);
3783 fprintf (file, " extrel: idx: %8lu num: %lu\n",
3784 module->iextrel, module->nextrel);
3785 fprintf (file, " init: idx: %8u num: %u\n",
3786 module->iinit, module->ninit);
3787 fprintf (file, " term: idx: %8u num: %u\n",
3788 module->iterm, module->nterm);
3789 fprintf (file, " objc_module_info: addr: ");
3790 fprintf_vma (file, module->objc_module_info_addr);
3791 fprintf (file, " size: %lu\n", module->objc_module_info_size);
3792 }
3793
3794 if (dysymtab->ntoc > 0)
3795 {
3796 bfd_mach_o_symtab_command *symtab = mdata->symtab;
3797
3798 fprintf (file, " table of content: (symbol/module)\n");
3799 for (i = 0; i < dysymtab->ntoc; i++)
3800 {
3801 bfd_mach_o_dylib_table_of_content *toc = &dysymtab->dylib_toc[i];
3802
3803 fprintf (file, " %4u: ", i);
3804 if (symtab && symtab->symbols && toc->symbol_index < symtab->nsyms)
3805 {
3806 const char *name = symtab->symbols[toc->symbol_index].symbol.name;
3807 fprintf (file, "%s (%lu)", name ? name : "*invalid*",
3808 toc->symbol_index);
3809 }
3810 else
3811 fprintf (file, "%lu", toc->symbol_index);
3812
3813 fprintf (file, " / ");
3814 if (symtab && symtab->strtab
3815 && toc->module_index < dysymtab->nmodtab)
3816 {
3817 bfd_mach_o_dylib_module *mod;
3818 mod = &dysymtab->dylib_module[toc->module_index];
3819 fprintf (file, "%s (%lu)",
3820 symtab->strtab + mod->module_name_idx,
3821 toc->module_index);
3822 }
3823 else
3824 fprintf (file, "%lu", toc->module_index);
3825
3826 fprintf (file, "\n");
3827 }
3828 }
3829
3830 if (dysymtab->nindirectsyms != 0)
3831 {
3832 fprintf (file, " indirect symbols:\n");
3833
3834 for (i = 0; i < mdata->nsects; i++)
3835 {
3836 bfd_mach_o_section *sec = mdata->sections[i];
3837 unsigned int j, first, last;
3838 bfd_mach_o_symtab_command *symtab = mdata->symtab;
3839 bfd_vma addr;
3840 bfd_vma entry_size;
3841
3842 switch (sec->flags & BFD_MACH_O_SECTION_TYPE_MASK)
3843 {
3844 case BFD_MACH_O_S_NON_LAZY_SYMBOL_POINTERS:
3845 case BFD_MACH_O_S_LAZY_SYMBOL_POINTERS:
3846 case BFD_MACH_O_S_SYMBOL_STUBS:
3847 first = sec->reserved1;
3848 last = first + bfd_mach_o_section_get_nbr_indirect (abfd, sec);
3849 addr = sec->addr;
3850 entry_size = bfd_mach_o_section_get_entry_size (abfd, sec);
3851 fprintf (file, " for section %s.%s:\n",
3852 sec->segname, sec->sectname);
3853 for (j = first; j < last; j++)
3854 {
3855 unsigned int isym = dysymtab->indirect_syms[j];
3856
3857 fprintf (file, " ");
3858 fprintf_vma (file, addr);
3859 fprintf (file, " %5u: 0x%08x", j, isym);
3860 if (isym & BFD_MACH_O_INDIRECT_SYMBOL_LOCAL)
3861 fprintf (file, " LOCAL");
3862 if (isym & BFD_MACH_O_INDIRECT_SYMBOL_ABS)
3863 fprintf (file, " ABSOLUTE");
3864 if (symtab && symtab->symbols
3865 && isym < symtab->nsyms
3866 && symtab->symbols[isym].symbol.name)
3867 fprintf (file, " %s", symtab->symbols[isym].symbol.name);
3868 fprintf (file, "\n");
3869 addr += entry_size;
3870 }
3871 break;
3872 default:
3873 break;
3874 }
3875 }
3876 }
3877 if (dysymtab->nextrefsyms > 0)
3878 {
3879 bfd_mach_o_symtab_command *symtab = mdata->symtab;
3880
3881 fprintf (file, " external reference table: (symbol flags)\n");
3882 for (i = 0; i < dysymtab->nextrefsyms; i++)
3883 {
3884 bfd_mach_o_dylib_reference *ref = &dysymtab->ext_refs[i];
3885
3886 fprintf (file, " %4u: %5lu 0x%02lx", i, ref->isym, ref->flags);
3887 if (symtab && symtab->symbols
3888 && ref->isym < symtab->nsyms
3889 && symtab->symbols[ref->isym].symbol.name)
3890 fprintf (file, " %s", symtab->symbols[ref->isym].symbol.name);
3891 fprintf (file, "\n");
3892 }
3893 }
3894
3895 }
3896
3897 static void
3898 bfd_mach_o_print_dyld_info (bfd *abfd ATTRIBUTE_UNUSED,
3899 bfd_mach_o_load_command *cmd, FILE *file)
3900 {
3901 bfd_mach_o_dyld_info_command *info = &cmd->command.dyld_info;
3902
3903 fprintf (file, " rebase: off: 0x%08x size: %-8u\n",
3904 info->rebase_off, info->rebase_size);
3905 fprintf (file, " bind: off: 0x%08x size: %-8u\n",
3906 info->bind_off, info->bind_size);
3907 fprintf (file, " weak bind: off: 0x%08x size: %-8u\n",
3908 info->weak_bind_off, info->weak_bind_size);
3909 fprintf (file, " lazy bind: off: 0x%08x size: %-8u\n",
3910 info->lazy_bind_off, info->lazy_bind_size);
3911 fprintf (file, " export: off: 0x%08x size: %-8u\n",
3912 info->export_off, info->export_size);
3913 }
3914
3915 bfd_boolean
3916 bfd_mach_o_bfd_print_private_bfd_data (bfd *abfd, void * ptr)
3917 {
3918 bfd_mach_o_data_struct *mdata = bfd_mach_o_get_data (abfd);
3919 FILE *file = (FILE *) ptr;
3920 unsigned int i;
3921
3922 bfd_mach_o_print_private_header (abfd, file);
3923 fputc ('\n', file);
3924
3925 for (i = 0; i < mdata->header.ncmds; i++)
3926 {
3927 bfd_mach_o_load_command *cmd = &mdata->commands[i];
3928 const char *cmd_name;
3929
3930 cmd_name = bfd_mach_o_get_name_or_null
3931 (bfd_mach_o_load_command_name, cmd->type);
3932 fprintf (file, "Load command ");
3933 if (cmd_name == NULL)
3934 fprintf (file, "0x%02x:", cmd->type);
3935 else
3936 fprintf (file, "%s:", cmd_name);
3937
3938 switch (cmd->type)
3939 {
3940 case BFD_MACH_O_LC_SEGMENT:
3941 case BFD_MACH_O_LC_SEGMENT_64:
3942 bfd_mach_o_print_segment (abfd, cmd, file);
3943 break;
3944 case BFD_MACH_O_LC_UUID:
3945 {
3946 bfd_mach_o_uuid_command *uuid = &cmd->command.uuid;
3947 unsigned int j;
3948
3949 for (j = 0; j < sizeof (uuid->uuid); j ++)
3950 fprintf (file, " %02x", uuid->uuid[j]);
3951 fputc ('\n', file);
3952 }
3953 break;
3954 case BFD_MACH_O_LC_LOAD_DYLIB:
3955 case BFD_MACH_O_LC_LOAD_WEAK_DYLIB:
3956 case BFD_MACH_O_LC_REEXPORT_DYLIB:
3957 case BFD_MACH_O_LC_LOAD_UPWARD_DYLIB:
3958 case BFD_MACH_O_LC_ID_DYLIB:
3959 {
3960 bfd_mach_o_dylib_command *dylib = &cmd->command.dylib;
3961 fprintf (file, " %s\n", dylib->name_str);
3962 fprintf (file, " time stamp: 0x%08lx\n",
3963 dylib->timestamp);
3964 fprintf (file, " current version: 0x%08lx\n",
3965 dylib->current_version);
3966 fprintf (file, " comptibility version: 0x%08lx\n",
3967 dylib->compatibility_version);
3968 break;
3969 }
3970 case BFD_MACH_O_LC_LOAD_DYLINKER:
3971 case BFD_MACH_O_LC_ID_DYLINKER:
3972 fprintf (file, " %s\n", cmd->command.dylinker.name_str);
3973 break;
3974 case BFD_MACH_O_LC_SYMTAB:
3975 {
3976 bfd_mach_o_symtab_command *symtab = &cmd->command.symtab;
3977 fprintf (file,
3978 "\n"
3979 " symoff: 0x%08x nsyms: %8u (endoff: 0x%08x)\n",
3980 symtab->symoff, symtab->nsyms,
3981 symtab->symoff + symtab->nsyms
3982 * (mach_o_wide_p (&mdata->header)
3983 ? BFD_MACH_O_NLIST_64_SIZE : BFD_MACH_O_NLIST_SIZE));
3984 fprintf (file,
3985 " stroff: 0x%08x strsize: %8u (endoff: 0x%08x)\n",
3986 symtab->stroff, symtab->strsize,
3987 symtab->stroff + symtab->strsize);
3988 break;
3989 }
3990 case BFD_MACH_O_LC_DYSYMTAB:
3991 fprintf (file, "\n");
3992 bfd_mach_o_print_dysymtab (abfd, cmd, file);
3993 break;
3994 case BFD_MACH_O_LC_CODE_SIGNATURE:
3995 case BFD_MACH_O_LC_SEGMENT_SPLIT_INFO:
3996 case BFD_MACH_O_LC_FUNCTION_STARTS:
3997 {
3998 bfd_mach_o_linkedit_command *linkedit = &cmd->command.linkedit;
3999 fprintf
4000 (file, "\n"
4001 " dataoff: 0x%08lx datasize: 0x%08lx (endoff: 0x%08lx)\n",
4002 linkedit->dataoff, linkedit->datasize,
4003 linkedit->dataoff + linkedit->datasize);
4004 break;
4005 }
4006 case BFD_MACH_O_LC_SUB_FRAMEWORK:
4007 case BFD_MACH_O_LC_SUB_UMBRELLA:
4008 case BFD_MACH_O_LC_SUB_LIBRARY:
4009 case BFD_MACH_O_LC_SUB_CLIENT:
4010 case BFD_MACH_O_LC_RPATH:
4011 {
4012 bfd_mach_o_str_command *str = &cmd->command.str;
4013 fprintf (file, " %s\n", str->str);
4014 break;
4015 }
4016 case BFD_MACH_O_LC_THREAD:
4017 case BFD_MACH_O_LC_UNIXTHREAD:
4018 {
4019 bfd_mach_o_thread_command *thread = &cmd->command.thread;
4020 unsigned int j;
4021 bfd_mach_o_backend_data *bed = bfd_mach_o_get_backend_data (abfd);
4022
4023 fprintf (file, " nflavours: %lu\n", thread->nflavours);
4024 for (j = 0; j < thread->nflavours; j++)
4025 {
4026 bfd_mach_o_thread_flavour *flavour = &thread->flavours[j];
4027
4028 fprintf (file, " %2u: flavour: 0x%08lx offset: 0x%08lx"
4029 " size: 0x%08lx\n",
4030 j, flavour->flavour, flavour->offset,
4031 flavour->size);
4032 if (bed->_bfd_mach_o_print_thread)
4033 {
4034 char *buf = bfd_malloc (flavour->size);
4035
4036 if (buf
4037 && bfd_seek (abfd, flavour->offset, SEEK_SET) == 0
4038 && (bfd_bread (buf, flavour->size, abfd)
4039 == flavour->size))
4040 (*bed->_bfd_mach_o_print_thread)(abfd, flavour,
4041 file, buf);
4042 free (buf);
4043 }
4044 }
4045 break;
4046 }
4047 case BFD_MACH_O_LC_DYLD_INFO:
4048 fprintf (file, "\n");
4049 bfd_mach_o_print_dyld_info (abfd, cmd, file);
4050 break;
4051 case BFD_MACH_O_LC_VERSION_MIN_MACOSX:
4052 case BFD_MACH_O_LC_VERSION_MIN_IPHONEOS:
4053 {
4054 bfd_mach_o_version_min_command *ver = &cmd->command.version_min;
4055
4056 fprintf (file, " %u.%u.%u\n", ver->rel, ver->maj, ver->min);
4057 }
4058 break;
4059 default:
4060 fprintf (file, "\n");
4061 fprintf (file, " offset: 0x%08lx\n", (unsigned long)cmd->offset);
4062 fprintf (file, " size: 0x%08lx\n", (unsigned long)cmd->len);
4063 break;
4064 }
4065 fputc ('\n', file);
4066 }
4067
4068 bfd_mach_o_print_section_map (abfd, file);
4069
4070 return TRUE;
4071 }
4072
4073 int
4074 bfd_mach_o_core_fetch_environment (bfd *abfd,
4075 unsigned char **rbuf,
4076 unsigned int *rlen)
4077 {
4078 bfd_mach_o_data_struct *mdata = bfd_mach_o_get_data (abfd);
4079 unsigned long stackaddr = bfd_mach_o_stack_addr (mdata->header.cputype);
4080 unsigned int i = 0;
4081
4082 for (i = 0; i < mdata->header.ncmds; i++)
4083 {
4084 bfd_mach_o_load_command *cur = &mdata->commands[i];
4085 bfd_mach_o_segment_command *seg = NULL;
4086
4087 if (cur->type != BFD_MACH_O_LC_SEGMENT)
4088 continue;
4089
4090 seg = &cur->command.segment;
4091
4092 if ((seg->vmaddr + seg->vmsize) == stackaddr)
4093 {
4094 unsigned long start = seg->fileoff;
4095 unsigned long end = seg->fileoff + seg->filesize;
4096 unsigned char *buf = bfd_malloc (1024);
4097 unsigned long size = 1024;
4098
4099 for (;;)
4100 {
4101 bfd_size_type nread = 0;
4102 unsigned long offset;
4103 int found_nonnull = 0;
4104
4105 if (size > (end - start))
4106 size = (end - start);
4107
4108 buf = bfd_realloc_or_free (buf, size);
4109 if (buf == NULL)
4110 return -1;
4111
4112 if (bfd_seek (abfd, end - size, SEEK_SET) != 0)
4113 {
4114 free (buf);
4115 return -1;
4116 }
4117
4118 nread = bfd_bread (buf, size, abfd);
4119
4120 if (nread != size)
4121 {
4122 free (buf);
4123 return -1;
4124 }
4125
4126 for (offset = 4; offset <= size; offset += 4)
4127 {
4128 unsigned long val;
4129
4130 val = *((unsigned long *) (buf + size - offset));
4131 if (! found_nonnull)
4132 {
4133 if (val != 0)
4134 found_nonnull = 1;
4135 }
4136 else if (val == 0x0)
4137 {
4138 unsigned long bottom;
4139 unsigned long top;
4140
4141 bottom = seg->fileoff + seg->filesize - offset;
4142 top = seg->fileoff + seg->filesize - 4;
4143 *rbuf = bfd_malloc (top - bottom);
4144 *rlen = top - bottom;
4145
4146 memcpy (*rbuf, buf + size - *rlen, *rlen);
4147 free (buf);
4148 return 0;
4149 }
4150 }
4151
4152 if (size == (end - start))
4153 break;
4154
4155 size *= 2;
4156 }
4157
4158 free (buf);
4159 }
4160 }
4161
4162 return -1;
4163 }
4164
4165 char *
4166 bfd_mach_o_core_file_failing_command (bfd *abfd)
4167 {
4168 unsigned char *buf = NULL;
4169 unsigned int len = 0;
4170 int ret = -1;
4171
4172 ret = bfd_mach_o_core_fetch_environment (abfd, &buf, &len);
4173 if (ret < 0)
4174 return NULL;
4175
4176 return (char *) buf;
4177 }
4178
4179 int
4180 bfd_mach_o_core_file_failing_signal (bfd *abfd ATTRIBUTE_UNUSED)
4181 {
4182 return 0;
4183 }
4184
4185 #define bfd_mach_o_bfd_reloc_type_lookup _bfd_norelocs_bfd_reloc_type_lookup
4186 #define bfd_mach_o_bfd_reloc_name_lookup _bfd_norelocs_bfd_reloc_name_lookup
4187
4188 #define bfd_mach_o_swap_reloc_in NULL
4189 #define bfd_mach_o_swap_reloc_out NULL
4190 #define bfd_mach_o_print_thread NULL
4191
4192 #define TARGET_NAME mach_o_be_vec
4193 #define TARGET_STRING "mach-o-be"
4194 #define TARGET_ARCHITECTURE bfd_arch_unknown
4195 #define TARGET_BIG_ENDIAN 1
4196 #define TARGET_ARCHIVE 0
4197 #include "mach-o-target.c"
4198
4199 #undef TARGET_NAME
4200 #undef TARGET_STRING
4201 #undef TARGET_ARCHITECTURE
4202 #undef TARGET_BIG_ENDIAN
4203 #undef TARGET_ARCHIVE
4204
4205 #define TARGET_NAME mach_o_le_vec
4206 #define TARGET_STRING "mach-o-le"
4207 #define TARGET_ARCHITECTURE bfd_arch_unknown
4208 #define TARGET_BIG_ENDIAN 0
4209 #define TARGET_ARCHIVE 0
4210
4211 #include "mach-o-target.c"
4212
4213 #undef TARGET_NAME
4214 #undef TARGET_STRING
4215 #undef TARGET_ARCHITECTURE
4216 #undef TARGET_BIG_ENDIAN
4217 #undef TARGET_ARCHIVE
4218
4219 /* Not yet handled: creating an archive. */
4220 #define bfd_mach_o_mkarchive _bfd_noarchive_mkarchive
4221
4222 /* Not used. */
4223 #define bfd_mach_o_read_ar_hdr _bfd_noarchive_read_ar_hdr
4224 #define bfd_mach_o_write_ar_hdr _bfd_noarchive_write_ar_hdr
4225 #define bfd_mach_o_slurp_armap _bfd_noarchive_slurp_armap
4226 #define bfd_mach_o_slurp_extended_name_table _bfd_noarchive_slurp_extended_name_table
4227 #define bfd_mach_o_construct_extended_name_table _bfd_noarchive_construct_extended_name_table
4228 #define bfd_mach_o_truncate_arname _bfd_noarchive_truncate_arname
4229 #define bfd_mach_o_write_armap _bfd_noarchive_write_armap
4230 #define bfd_mach_o_get_elt_at_index _bfd_noarchive_get_elt_at_index
4231 #define bfd_mach_o_generic_stat_arch_elt _bfd_noarchive_generic_stat_arch_elt
4232 #define bfd_mach_o_update_armap_timestamp _bfd_noarchive_update_armap_timestamp
4233
4234 #define TARGET_NAME mach_o_fat_vec
4235 #define TARGET_STRING "mach-o-fat"
4236 #define TARGET_ARCHITECTURE bfd_arch_unknown
4237 #define TARGET_BIG_ENDIAN 1
4238 #define TARGET_ARCHIVE 1
4239
4240 #include "mach-o-target.c"
4241
4242 #undef TARGET_NAME
4243 #undef TARGET_STRING
4244 #undef TARGET_ARCHITECTURE
4245 #undef TARGET_BIG_ENDIAN
4246 #undef TARGET_ARCHIVE