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