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