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