* nto-tdep.h (nto_generic_supply_gpregset)
[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
c2f09c75 34unsigned int
1e8a024a
TG
35bfd_mach_o_version (bfd *abfd)
36{
37 bfd_mach_o_data_struct *mdata = NULL;
38
39 BFD_ASSERT (bfd_mach_o_valid (abfd));
40 mdata = abfd->tdata.mach_o_data;
41
42 return mdata->header.version;
43}
44
b34976b6 45bfd_boolean
116c20d2 46bfd_mach_o_valid (bfd *abfd)
3af9a47b
NC
47{
48 if (abfd == NULL || abfd->xvec == NULL)
154a1ee5 49 return FALSE;
3af9a47b 50
154a1ee5
TG
51 if (abfd->xvec->flavour != bfd_target_mach_o_flavour)
52 return FALSE;
3af9a47b
NC
53
54 if (abfd->tdata.mach_o_data == NULL)
154a1ee5
TG
55 return FALSE;
56 return TRUE;
57}
58
c2f09c75
TG
59static INLINE bfd_boolean
60mach_o_wide_p (bfd_mach_o_header *header)
61{
62 switch (header->version)
63 {
64 case 1:
65 return FALSE;
66 case 2:
67 return TRUE;
68 default:
69 BFD_FAIL ();
70 return FALSE;
71 }
72}
73
74static INLINE bfd_boolean
75bfd_mach_o_wide_p (bfd *abfd)
76{
77 return mach_o_wide_p (&abfd->tdata.mach_o_data->header);
78}
79
154a1ee5
TG
80/* Tables to translate well known Mach-O segment/section names to bfd
81 names. Use of canonical names (such as .text or .debug_frame) is required
82 by gdb. */
83
84struct mach_o_section_name_xlat
85{
86 const char *bfd_name;
87 const char *mach_o_name;
88};
89
90static const struct mach_o_section_name_xlat dwarf_section_names_xlat[] =
91 {
92 { ".debug_frame", "__debug_frame" },
93 { ".debug_info", "__debug_info" },
94 { ".debug_abbrev", "__debug_abbrev" },
95 { ".debug_aranges", "__debug_aranges" },
96 { ".debug_macinfo", "__debug_macinfo" },
97 { ".debug_line", "__debug_line" },
98 { ".debug_loc", "__debug_loc" },
99 { ".debug_pubnames", "__debug_pubnames" },
100 { ".debug_pubtypes", "__debug_pubtypes" },
101 { ".debug_str", "__debug_str" },
102 { ".debug_ranges", "__debug_ranges" },
103 { NULL, NULL}
104 };
105
106static const struct mach_o_section_name_xlat text_section_names_xlat[] =
107 {
108 { ".text", "__text" },
109 { ".cstring", "__cstring" },
110 { ".eh_frame", "__eh_frame" },
111 { NULL, NULL}
112 };
113
114static const struct mach_o_section_name_xlat data_section_names_xlat[] =
115 {
116 { ".data", "__data" },
117 { ".bss", "__bss" },
118 { NULL, NULL}
119 };
120
121struct mach_o_segment_name_xlat
122{
123 const char *segname;
124 const struct mach_o_section_name_xlat *sections;
125};
126
c2f09c75 127static const struct mach_o_segment_name_xlat segsec_names_xlat[] =
154a1ee5
TG
128 {
129 { "__DWARF", dwarf_section_names_xlat },
130 { "__TEXT", text_section_names_xlat },
131 { "__DATA", data_section_names_xlat },
132 { NULL, NULL }
133 };
134
135
136/* Mach-O to bfd names. */
137
138static char *
139bfd_mach_o_convert_section_name_to_bfd (bfd *abfd, bfd_mach_o_section *section)
140{
141 const struct mach_o_segment_name_xlat *seg;
142 char *res;
143 unsigned int len;
c2f09c75 144 const char *pfx = "";
154a1ee5
TG
145
146 for (seg = segsec_names_xlat; seg->segname; seg++)
147 {
148 if (strcmp (seg->segname, section->segname) == 0)
149 {
150 const struct mach_o_section_name_xlat *sec;
151
152 for (sec = seg->sections; sec->mach_o_name; sec++)
153 {
154 if (strcmp (sec->mach_o_name, section->sectname) == 0)
155 {
156 len = strlen (sec->bfd_name);
157 res = bfd_alloc (abfd, len + 1);
c2f09c75 158
154a1ee5
TG
159 if (res == NULL)
160 return NULL;
161 strcpy (res, sec->bfd_name);
162 return res;
163 }
164 }
165 }
166 }
167
c2f09c75 168 len = strlen (section->segname) + 1
154a1ee5
TG
169 + strlen (section->sectname) + 1;
170
c2f09c75
TG
171 /* Put "LC_SEGMENT." prefix if the segment name is weird (ie doesn't start
172 with an underscore. */
173 if (section->segname[0] != '_')
174 {
175 static const char seg_pfx[] = "LC_SEGMENT.";
176
177 pfx = seg_pfx;
178 len += sizeof (seg_pfx) - 1;
179 }
180
154a1ee5
TG
181 res = bfd_alloc (abfd, len);
182 if (res == NULL)
183 return NULL;
c2f09c75 184 snprintf (res, len, "%s%s.%s", pfx, section->segname, section->sectname);
154a1ee5
TG
185 return res;
186}
187
c2f09c75 188/* Convert a bfd section name to a Mach-O segment + section name. */
154a1ee5
TG
189
190static void
191bfd_mach_o_convert_section_name_to_mach_o (bfd *abfd ATTRIBUTE_UNUSED,
192 asection *sect,
193 bfd_mach_o_section *section)
194{
195 const struct mach_o_segment_name_xlat *seg;
196 const char *name = bfd_get_section_name (abfd, sect);
197 const char *dot;
198 unsigned int len;
199 unsigned int seglen;
200 unsigned int seclen;
201
c2f09c75
TG
202 /* List of well known names. They all start with a dot. */
203 if (name[0] == '.')
204 for (seg = segsec_names_xlat; seg->segname; seg++)
205 {
206 const struct mach_o_section_name_xlat *sec;
207
208 for (sec = seg->sections; sec->mach_o_name; sec++)
209 {
210 if (strcmp (sec->bfd_name, name) == 0)
211 {
212 strcpy (section->segname, seg->segname);
213 strcpy (section->sectname, sec->mach_o_name);
214 return;
215 }
216 }
217 }
154a1ee5
TG
218
219 /* Strip LC_SEGMENT. prefix. */
220 if (strncmp (name, "LC_SEGMENT.", 11) == 0)
221 name += 11;
222
223 /* Find a dot. */
224 dot = strchr (name, '.');
225 len = strlen (name);
226
227 /* Try to split name into segment and section names. */
228 if (dot && dot != name)
229 {
230 seglen = dot - name;
231 seclen = len - (dot + 1 - name);
232
233 if (seglen < 16 && seclen < 16)
234 {
235 memcpy (section->segname, name, seglen);
236 section->segname[seglen] = 0;
237 memcpy (section->sectname, dot + 1, seclen);
238 section->sectname[seclen] = 0;
239 return;
240 }
241 }
242
243 if (len > 16)
244 len = 16;
245 memcpy (section->segname, name, len);
246 section->segname[len] = 0;
247 memcpy (section->sectname, name, len);
248 section->sectname[len] = 0;
3af9a47b
NC
249}
250
251/* Copy any private info we understand from the input symbol
252 to the output symbol. */
253
154a1ee5 254bfd_boolean
116c20d2
NC
255bfd_mach_o_bfd_copy_private_symbol_data (bfd *ibfd ATTRIBUTE_UNUSED,
256 asymbol *isymbol ATTRIBUTE_UNUSED,
257 bfd *obfd ATTRIBUTE_UNUSED,
258 asymbol *osymbol ATTRIBUTE_UNUSED)
3af9a47b 259{
b34976b6 260 return TRUE;
3af9a47b
NC
261}
262
263/* Copy any private info we understand from the input section
264 to the output section. */
265
154a1ee5 266bfd_boolean
116c20d2
NC
267bfd_mach_o_bfd_copy_private_section_data (bfd *ibfd ATTRIBUTE_UNUSED,
268 asection *isection ATTRIBUTE_UNUSED,
269 bfd *obfd ATTRIBUTE_UNUSED,
270 asection *osection ATTRIBUTE_UNUSED)
3af9a47b 271{
b34976b6 272 return TRUE;
3af9a47b
NC
273}
274
275/* Copy any private info we understand from the input bfd
276 to the output bfd. */
277
154a1ee5 278bfd_boolean
116c20d2 279bfd_mach_o_bfd_copy_private_bfd_data (bfd *ibfd, bfd *obfd)
3af9a47b 280{
154a1ee5
TG
281 if (bfd_get_flavour (ibfd) != bfd_target_mach_o_flavour
282 || bfd_get_flavour (obfd) != bfd_target_mach_o_flavour)
283 return TRUE;
284
3af9a47b
NC
285 BFD_ASSERT (bfd_mach_o_valid (ibfd));
286 BFD_ASSERT (bfd_mach_o_valid (obfd));
287
154a1ee5
TG
288 /* FIXME: copy commands. */
289
b34976b6 290 return TRUE;
3af9a47b
NC
291}
292
154a1ee5
TG
293/* Count the total number of symbols. Traverse all sections. */
294
3af9a47b 295static long
116c20d2 296bfd_mach_o_count_symbols (bfd *abfd)
3af9a47b
NC
297{
298 bfd_mach_o_data_struct *mdata = NULL;
299 long nsyms = 0;
300 unsigned long i;
a95a4550 301
3af9a47b
NC
302 BFD_ASSERT (bfd_mach_o_valid (abfd));
303 mdata = abfd->tdata.mach_o_data;
304
305 for (i = 0; i < mdata->header.ncmds; i++)
306 if (mdata->commands[i].type == BFD_MACH_O_LC_SYMTAB)
307 {
308 bfd_mach_o_symtab_command *sym = &mdata->commands[i].command.symtab;
309 nsyms += sym->nsyms;
310 }
311
312 return nsyms;
313}
314
154a1ee5 315long
116c20d2 316bfd_mach_o_get_symtab_upper_bound (bfd *abfd)
3af9a47b
NC
317{
318 long nsyms = bfd_mach_o_count_symbols (abfd);
319
320 if (nsyms < 0)
321 return nsyms;
322
323 return ((nsyms + 1) * sizeof (asymbol *));
324}
325
154a1ee5 326long
116c20d2 327bfd_mach_o_canonicalize_symtab (bfd *abfd, asymbol **alocation)
3af9a47b
NC
328{
329 bfd_mach_o_data_struct *mdata = abfd->tdata.mach_o_data;
330 long nsyms = bfd_mach_o_count_symbols (abfd);
331 asymbol **csym = alocation;
332 unsigned long i, j;
333
334 if (nsyms < 0)
335 return nsyms;
336
337 for (i = 0; i < mdata->header.ncmds; i++)
338 {
339 if (mdata->commands[i].type == BFD_MACH_O_LC_SYMTAB)
340 {
341 bfd_mach_o_symtab_command *sym = &mdata->commands[i].command.symtab;
342
343 if (bfd_mach_o_scan_read_symtab_symbols (abfd, &mdata->commands[i].command.symtab) != 0)
344 {
6cee3f79 345 fprintf (stderr, "bfd_mach_o_canonicalize_symtab: unable to load symbols for section %lu\n", i);
3af9a47b
NC
346 return 0;
347 }
348
349 BFD_ASSERT (sym->symbols != NULL);
350
351 for (j = 0; j < sym->nsyms; j++)
352 {
353 BFD_ASSERT (csym < (alocation + nsyms));
354 *csym++ = &sym->symbols[j];
355 }
356 }
357 }
358
359 *csym++ = NULL;
a95a4550 360
3af9a47b
NC
361 return nsyms;
362}
363
154a1ee5 364void
116c20d2
NC
365bfd_mach_o_get_symbol_info (bfd *abfd ATTRIBUTE_UNUSED,
366 asymbol *symbol,
367 symbol_info *ret)
3af9a47b
NC
368{
369 bfd_symbol_info (symbol, ret);
370}
371
154a1ee5 372void
116c20d2
NC
373bfd_mach_o_print_symbol (bfd *abfd,
374 PTR afile,
375 asymbol *symbol,
376 bfd_print_symbol_type how)
3af9a47b
NC
377{
378 FILE *file = (FILE *) afile;
15e1c58a
TG
379 unsigned char ntype;
380 unsigned char nsect;
381 unsigned int ndesc;
382 const char *name;
3af9a47b
NC
383
384 switch (how)
385 {
386 case bfd_print_symbol_name:
387 fprintf (file, "%s", symbol->name);
388 break;
389 default:
390 bfd_print_symbol_vandf (abfd, (PTR) file, symbol);
15e1c58a
TG
391 ntype = BFD_MACH_O_SYM_NTYPE (symbol);
392 nsect = BFD_MACH_O_SYM_NSECT (symbol);
393 ndesc = BFD_MACH_O_SYM_NDESC (symbol);
394 if (ntype & BFD_MACH_O_N_STAB)
395 name = bfd_get_stab_name (ntype);
396 else
397 switch (ntype & BFD_MACH_O_N_TYPE)
398 {
399 case BFD_MACH_O_N_UNDF:
400 name = "UND";
401 break;
402 case BFD_MACH_O_N_ABS:
403 name = "ABS";
404 break;
405 case BFD_MACH_O_N_INDR:
406 name = "INDR";
407 break;
408 case BFD_MACH_O_N_PBUD:
409 name = "PBUD";
410 break;
411 case BFD_MACH_O_N_SECT:
412 name = "SECT";
413 break;
414 default:
415 name = "???";
416 break;
417 }
418 if (name == NULL)
419 name = "";
420 fprintf (file, " %02x %-6s %02x %04x", ntype, name, nsect, ndesc);
421 if ((ntype & BFD_MACH_O_N_STAB) == 0
422 && (ntype & BFD_MACH_O_N_TYPE) == BFD_MACH_O_N_SECT)
423 fprintf (file, " %-5s", symbol->section->name);
424 fprintf (file, " %s", symbol->name);
3af9a47b
NC
425 }
426}
427
428static void
116c20d2
NC
429bfd_mach_o_convert_architecture (bfd_mach_o_cpu_type mtype,
430 bfd_mach_o_cpu_subtype msubtype ATTRIBUTE_UNUSED,
431 enum bfd_architecture *type,
432 unsigned long *subtype)
3af9a47b
NC
433{
434 *subtype = bfd_arch_unknown;
435
436 switch (mtype)
437 {
438 case BFD_MACH_O_CPU_TYPE_VAX: *type = bfd_arch_vax; break;
439 case BFD_MACH_O_CPU_TYPE_MC680x0: *type = bfd_arch_m68k; break;
1e8a024a
TG
440 case BFD_MACH_O_CPU_TYPE_I386:
441 *type = bfd_arch_i386;
442 *subtype = bfd_mach_i386_i386;
443 break;
444 case BFD_MACH_O_CPU_TYPE_X86_64:
445 *type = bfd_arch_i386;
446 *subtype = bfd_mach_x86_64;
447 break;
3af9a47b
NC
448 case BFD_MACH_O_CPU_TYPE_MIPS: *type = bfd_arch_mips; break;
449 case BFD_MACH_O_CPU_TYPE_MC98000: *type = bfd_arch_m98k; break;
450 case BFD_MACH_O_CPU_TYPE_HPPA: *type = bfd_arch_hppa; break;
451 case BFD_MACH_O_CPU_TYPE_ARM: *type = bfd_arch_arm; break;
452 case BFD_MACH_O_CPU_TYPE_MC88000: *type = bfd_arch_m88k; break;
1e8a024a
TG
453 case BFD_MACH_O_CPU_TYPE_SPARC:
454 *type = bfd_arch_sparc;
455 *subtype = bfd_mach_sparc;
456 break;
3af9a47b
NC
457 case BFD_MACH_O_CPU_TYPE_I860: *type = bfd_arch_i860; break;
458 case BFD_MACH_O_CPU_TYPE_ALPHA: *type = bfd_arch_alpha; break;
1e8a024a
TG
459 case BFD_MACH_O_CPU_TYPE_POWERPC:
460 *type = bfd_arch_powerpc;
c2f09c75 461 *subtype = bfd_mach_ppc;
1e8a024a
TG
462 break;
463 case BFD_MACH_O_CPU_TYPE_POWERPC_64:
464 *type = bfd_arch_powerpc;
c2f09c75 465 *subtype = bfd_mach_ppc64;
1e8a024a 466 break;
3af9a47b 467 default:
1e8a024a
TG
468 *type = bfd_arch_unknown;
469 break;
3af9a47b
NC
470 }
471}
a95a4550 472
154a1ee5 473static bfd_boolean
116c20d2
NC
474bfd_mach_o_write_header (bfd *abfd, bfd_mach_o_header *header)
475{
1e8a024a
TG
476 unsigned char buf[32];
477 unsigned int size;
478
c2f09c75 479 size = mach_o_wide_p (header) ?
154a1ee5 480 BFD_MACH_O_HEADER_64_SIZE : BFD_MACH_O_HEADER_SIZE;
116c20d2
NC
481
482 bfd_h_put_32 (abfd, header->magic, buf + 0);
483 bfd_h_put_32 (abfd, header->cputype, buf + 4);
484 bfd_h_put_32 (abfd, header->cpusubtype, buf + 8);
485 bfd_h_put_32 (abfd, header->filetype, buf + 12);
486 bfd_h_put_32 (abfd, header->ncmds, buf + 16);
487 bfd_h_put_32 (abfd, header->sizeofcmds, buf + 20);
488 bfd_h_put_32 (abfd, header->flags, buf + 24);
489
c2f09c75 490 if (mach_o_wide_p (header))
1e8a024a
TG
491 bfd_h_put_32 (abfd, header->reserved, buf + 28);
492
c2f09c75
TG
493 if (bfd_seek (abfd, 0, SEEK_SET) != 0
494 || bfd_bwrite ((PTR) buf, size, abfd) != size)
154a1ee5 495 return FALSE;
116c20d2 496
154a1ee5 497 return TRUE;
116c20d2
NC
498}
499
500static int
1e8a024a 501bfd_mach_o_scan_write_thread (bfd *abfd, bfd_mach_o_load_command *command)
116c20d2
NC
502{
503 bfd_mach_o_thread_command *cmd = &command->command.thread;
504 unsigned int i;
505 unsigned char buf[8];
506 bfd_vma offset;
507 unsigned int nflavours;
508
509 BFD_ASSERT ((command->type == BFD_MACH_O_LC_THREAD)
510 || (command->type == BFD_MACH_O_LC_UNIXTHREAD));
511
512 offset = 8;
513 nflavours = 0;
514 for (i = 0; i < cmd->nflavours; i++)
515 {
516 BFD_ASSERT ((cmd->flavours[i].size % 4) == 0);
517 BFD_ASSERT (cmd->flavours[i].offset == (command->offset + offset + 8));
518
519 bfd_h_put_32 (abfd, cmd->flavours[i].flavour, buf);
520 bfd_h_put_32 (abfd, (cmd->flavours[i].size / 4), buf + 4);
521
c2f09c75
TG
522 if (bfd_seek (abfd, command->offset + offset, SEEK_SET) != 0
523 || bfd_bwrite ((PTR) buf, 8, abfd) != 8)
116c20d2
NC
524 return -1;
525
526 offset += cmd->flavours[i].size + 8;
527 }
528
529 return 0;
530}
531
532static int
1e8a024a
TG
533bfd_mach_o_scan_write_section_32 (bfd *abfd,
534 bfd_mach_o_section *section,
535 bfd_vma offset)
116c20d2 536{
154a1ee5 537 unsigned char buf[BFD_MACH_O_SECTION_SIZE];
116c20d2
NC
538
539 memcpy (buf, section->sectname, 16);
540 memcpy (buf + 16, section->segname, 16);
541 bfd_h_put_32 (abfd, section->addr, buf + 32);
542 bfd_h_put_32 (abfd, section->size, buf + 36);
543 bfd_h_put_32 (abfd, section->offset, buf + 40);
544 bfd_h_put_32 (abfd, section->align, buf + 44);
545 bfd_h_put_32 (abfd, section->reloff, buf + 48);
546 bfd_h_put_32 (abfd, section->nreloc, buf + 52);
547 bfd_h_put_32 (abfd, section->flags, buf + 56);
1e8a024a
TG
548 bfd_h_put_32 (abfd, section->reserved1, buf + 60);
549 bfd_h_put_32 (abfd, section->reserved2, buf + 64);
116c20d2 550
c2f09c75
TG
551 if (bfd_seek (abfd, offset, SEEK_SET) != 0
552 || (bfd_bwrite ((PTR) buf, BFD_MACH_O_SECTION_SIZE, abfd)
553 != BFD_MACH_O_SECTION_SIZE))
116c20d2
NC
554 return -1;
555
556 return 0;
557}
558
559static int
1e8a024a
TG
560bfd_mach_o_scan_write_section_64 (bfd *abfd,
561 bfd_mach_o_section *section,
562 bfd_vma offset)
116c20d2 563{
154a1ee5 564 unsigned char buf[BFD_MACH_O_SECTION_64_SIZE];
116c20d2 565
1e8a024a
TG
566 memcpy (buf, section->sectname, 16);
567 memcpy (buf + 16, section->segname, 16);
568 bfd_h_put_64 (abfd, section->addr, buf + 32);
569 bfd_h_put_64 (abfd, section->size, buf + 40);
570 bfd_h_put_32 (abfd, section->offset, buf + 48);
571 bfd_h_put_32 (abfd, section->align, buf + 52);
572 bfd_h_put_32 (abfd, section->reloff, buf + 56);
573 bfd_h_put_32 (abfd, section->nreloc, buf + 60);
574 bfd_h_put_32 (abfd, section->flags, buf + 64);
575 bfd_h_put_32 (abfd, section->reserved1, buf + 68);
576 bfd_h_put_32 (abfd, section->reserved2, buf + 72);
577 bfd_h_put_32 (abfd, section->reserved3, buf + 76);
116c20d2 578
c2f09c75
TG
579 if (bfd_seek (abfd, offset, SEEK_SET) != 0
580 || (bfd_bwrite ((PTR) buf, BFD_MACH_O_SECTION_64_SIZE, abfd)
581 != BFD_MACH_O_SECTION_64_SIZE))
116c20d2
NC
582 return -1;
583
1e8a024a
TG
584 return 0;
585}
586
587static int
c2f09c75 588bfd_mach_o_scan_write_segment_32 (bfd *abfd, bfd_mach_o_load_command *command)
1e8a024a 589{
c2f09c75 590 unsigned char buf[BFD_MACH_O_LC_SEGMENT_SIZE];
1e8a024a
TG
591 bfd_mach_o_segment_command *seg = &command->command.segment;
592 unsigned long i;
593
c2f09c75
TG
594 BFD_ASSERT (command->type == BFD_MACH_O_LC_SEGMENT);
595
596 memcpy (buf, seg->segname, 16);
597
598 bfd_h_put_32 (abfd, seg->vmaddr, buf + 16);
599 bfd_h_put_32 (abfd, seg->vmsize, buf + 20);
600 bfd_h_put_32 (abfd, seg->fileoff, buf + 24);
601 bfd_h_put_32 (abfd, seg->filesize, buf + 28);
602 bfd_h_put_32 (abfd, seg->maxprot, buf + 32);
603 bfd_h_put_32 (abfd, seg->initprot, buf + 36);
604 bfd_h_put_32 (abfd, seg->nsects, buf + 40);
605 bfd_h_put_32 (abfd, seg->flags, buf + 44);
606
607 if (bfd_seek (abfd, command->offset + 8, SEEK_SET) != 0
608 || (bfd_bwrite ((PTR) buf, BFD_MACH_O_LC_SEGMENT_SIZE, abfd)
609 != BFD_MACH_O_LC_SEGMENT_SIZE))
610 return -1;
1e8a024a 611
116c20d2
NC
612 for (i = 0; i < seg->nsects; i++)
613 {
c2f09c75
TG
614 bfd_vma segoff = command->offset + BFD_MACH_O_LC_SEGMENT_SIZE
615 + (i * BFD_MACH_O_SECTION_SIZE);
1e8a024a 616
c2f09c75 617 if (bfd_mach_o_scan_write_section_32 (abfd, &seg->sections[i], segoff))
116c20d2
NC
618 return -1;
619 }
116c20d2
NC
620 return 0;
621}
622
1e8a024a
TG
623static int
624bfd_mach_o_scan_write_segment_64 (bfd *abfd, bfd_mach_o_load_command *command)
625{
c2f09c75
TG
626 unsigned char buf[BFD_MACH_O_LC_SEGMENT_64_SIZE];
627 bfd_mach_o_segment_command *seg = &command->command.segment;
628 unsigned long i;
629
630 BFD_ASSERT (command->type == BFD_MACH_O_LC_SEGMENT_64);
631
632 memcpy (buf, seg->segname, 16);
633
634 bfd_h_put_64 (abfd, seg->vmaddr, buf + 16);
635 bfd_h_put_64 (abfd, seg->vmsize, buf + 24);
636 bfd_h_put_64 (abfd, seg->fileoff, buf + 32);
637 bfd_h_put_64 (abfd, seg->filesize, buf + 40);
638 bfd_h_put_32 (abfd, seg->maxprot, buf + 48);
639 bfd_h_put_32 (abfd, seg->initprot, buf + 52);
640 bfd_h_put_32 (abfd, seg->nsects, buf + 56);
641 bfd_h_put_32 (abfd, seg->flags, buf + 60);
642
643 if (bfd_seek (abfd, command->offset + 8, SEEK_SET) != 0
644 || (bfd_bwrite ((PTR) buf, BFD_MACH_O_LC_SEGMENT_64_SIZE, abfd)
645 != BFD_MACH_O_LC_SEGMENT_64_SIZE))
646 return -1;
647
648 for (i = 0; i < seg->nsects; i++)
649 {
650 bfd_vma segoff = command->offset + BFD_MACH_O_LC_SEGMENT_64_SIZE
651 + (i * BFD_MACH_O_SECTION_64_SIZE);
652
653 if (bfd_mach_o_scan_write_section_64 (abfd, &seg->sections[i], segoff))
654 return -1;
655 }
656 return 0;
1e8a024a
TG
657}
658
c2f09c75
TG
659static bfd_boolean
660bfd_mach_o_scan_write_symtab (bfd *abfd, bfd_mach_o_load_command *command)
116c20d2
NC
661{
662 bfd_mach_o_symtab_command *sym = &command->command.symtab;
c2f09c75 663 unsigned char buf[16];
116c20d2 664 unsigned long i;
c2f09c75
TG
665 unsigned int wide = bfd_mach_o_wide_p (abfd);
666 unsigned int symlen = wide ? 16 : 12;
667 struct bfd_strtab_hash *strtab;
668 asymbol **symbols = bfd_get_outsymbols (abfd);
669
670 BFD_ASSERT (command->type == BFD_MACH_O_LC_SYMTAB);
671
672 /* Write the symbols first. */
673 if (bfd_seek (abfd, sym->symoff, SEEK_SET) != 0)
674 return FALSE;
675
676 sym->nsyms = bfd_get_symcount (abfd);
677
678 strtab = _bfd_stringtab_init ();
679 if (strtab == NULL)
680 return FALSE;
116c20d2
NC
681
682 for (i = 0; i < sym->nsyms; i++)
683 {
c2f09c75
TG
684 unsigned char buf[16];
685 unsigned char ntype;
686 unsigned char nsect;
687 short ndesc;
688 bfd_size_type index;
689 asymbol *s = symbols[i];
690
691 /* Compute index. */
692 /* An index of 0 always means the empty string. */
693 if (s->name == 0 || s->name[0] == '\0')
694 index = 0;
695 else
696 {
697 index = _bfd_stringtab_add (strtab, s->name, TRUE, FALSE);
698 if (index == (bfd_size_type) -1)
699 goto err;
700 }
116c20d2 701
c2f09c75 702 /* Get back-end specific values. */
15e1c58a
TG
703 ntype = BFD_MACH_O_SYM_NTYPE (s);
704 nsect = BFD_MACH_O_SYM_NSECT (s);
705 ndesc = BFD_MACH_O_SYM_NDESC (s);
116c20d2 706
c2f09c75
TG
707 if (ntype == BFD_MACH_O_N_UNDF && !(s->flags & BSF_DEBUGGING))
708 {
709 /* As genuine Mach-O symbols type shouldn't be N_UNDF (undefined
710 symbols should be N_UNDEF | N_EXT), we suppose the back-end
711 values haven't been set. */
712 if (s->flags & (BSF_LOCAL | BSF_GLOBAL))
713 {
714 if (s->section == bfd_abs_section_ptr)
715 ntype = BFD_MACH_O_N_ABS;
716 else if (s->section == bfd_und_section_ptr)
717 ntype = BFD_MACH_O_N_UNDF;
718 else if (s->section == bfd_com_section_ptr)
719 ntype = BFD_MACH_O_N_UNDF | BFD_MACH_O_N_EXT;
720 else
721 ntype = BFD_MACH_O_N_SECT;
722
723 ntype |= (s->flags & BSF_GLOBAL) ? BFD_MACH_O_N_EXT : 0;
724 }
725 }
726
727 /* Compute section index. */
728 if (s->section != bfd_abs_section_ptr
729 && s->section != bfd_und_section_ptr
730 && s->section != bfd_com_section_ptr)
731 nsect = s->section->target_index;
732
733 bfd_h_put_32 (abfd, index, buf);
116c20d2
NC
734 bfd_h_put_8 (abfd, ntype, buf + 4);
735 bfd_h_put_8 (abfd, nsect, buf + 5);
736 bfd_h_put_16 (abfd, ndesc, buf + 6);
c2f09c75
TG
737 if (wide)
738 bfd_h_put_64 (abfd, s->section->vma + s->value, buf + 8);
739 else
740 bfd_h_put_32 (abfd, s->section->vma + s->value, buf + 8);
116c20d2 741
c2f09c75
TG
742 if (bfd_bwrite ((PTR) buf, symlen, abfd) != symlen)
743 goto err;
116c20d2 744 }
c2f09c75
TG
745 sym->strsize = _bfd_stringtab_size (strtab);
746 sym->stroff = sym->symoff + sym->nsyms * symlen;
116c20d2 747
c2f09c75
TG
748 if (_bfd_stringtab_emit (abfd, strtab) != TRUE)
749 goto err;
750 _bfd_stringtab_free (strtab);
116c20d2 751
c2f09c75
TG
752 /* The command. */
753 bfd_h_put_32 (abfd, sym->symoff, buf);
754 bfd_h_put_32 (abfd, sym->nsyms, buf + 4);
755 bfd_h_put_32 (abfd, sym->stroff, buf + 8);
756 bfd_h_put_32 (abfd, sym->strsize, buf + 12);
116c20d2 757
c2f09c75
TG
758 if (bfd_seek (abfd, command->offset + 8, SEEK_SET) != 0
759 || bfd_bwrite ((PTR) buf, 16, abfd) != 16)
760 return FALSE;
116c20d2 761
c2f09c75 762 return TRUE;
116c20d2 763
c2f09c75
TG
764 err:
765 _bfd_stringtab_free (strtab);
766 return FALSE;
116c20d2
NC
767}
768
154a1ee5 769bfd_boolean
116c20d2 770bfd_mach_o_write_contents (bfd *abfd)
3af9a47b
NC
771{
772 unsigned int i;
3af9a47b
NC
773 bfd_mach_o_data_struct *mdata = abfd->tdata.mach_o_data;
774
3af9a47b 775 /* Now write header information. */
c2f09c75
TG
776 if (mdata->header.filetype == 0)
777 {
778 if (abfd->flags & EXEC_P)
779 mdata->header.filetype = BFD_MACH_O_MH_EXECUTE;
780 else if (abfd->flags & DYNAMIC)
781 mdata->header.filetype = BFD_MACH_O_MH_DYLIB;
782 else
783 mdata->header.filetype = BFD_MACH_O_MH_OBJECT;
784 }
154a1ee5 785 if (!bfd_mach_o_write_header (abfd, &mdata->header))
b34976b6 786 return FALSE;
3af9a47b
NC
787
788 for (i = 0; i < mdata->header.ncmds; i++)
789 {
790 unsigned char buf[8];
791 bfd_mach_o_load_command *cur = &mdata->commands[i];
792 unsigned long typeflag;
793
154a1ee5 794 typeflag = cur->type | (cur->type_required ? BFD_MACH_O_LC_REQ_DYLD : 0);
3af9a47b
NC
795
796 bfd_h_put_32 (abfd, typeflag, buf);
797 bfd_h_put_32 (abfd, cur->len, buf + 4);
798
c2f09c75
TG
799 if (bfd_seek (abfd, cur->offset, SEEK_SET) != 0
800 || bfd_bwrite ((PTR) buf, 8, abfd) != 8)
b34976b6 801 return FALSE;
3af9a47b
NC
802
803 switch (cur->type)
804 {
805 case BFD_MACH_O_LC_SEGMENT:
1e8a024a
TG
806 if (bfd_mach_o_scan_write_segment_32 (abfd, cur) != 0)
807 return FALSE;
808 break;
809 case BFD_MACH_O_LC_SEGMENT_64:
810 if (bfd_mach_o_scan_write_segment_64 (abfd, cur) != 0)
b34976b6 811 return FALSE;
3af9a47b
NC
812 break;
813 case BFD_MACH_O_LC_SYMTAB:
c2f09c75 814 if (!bfd_mach_o_scan_write_symtab (abfd, cur))
b34976b6 815 return FALSE;
3af9a47b
NC
816 break;
817 case BFD_MACH_O_LC_SYMSEG:
818 break;
819 case BFD_MACH_O_LC_THREAD:
820 case BFD_MACH_O_LC_UNIXTHREAD:
821 if (bfd_mach_o_scan_write_thread (abfd, cur) != 0)
b34976b6 822 return FALSE;
3af9a47b
NC
823 break;
824 case BFD_MACH_O_LC_LOADFVMLIB:
825 case BFD_MACH_O_LC_IDFVMLIB:
826 case BFD_MACH_O_LC_IDENT:
827 case BFD_MACH_O_LC_FVMFILE:
828 case BFD_MACH_O_LC_PREPAGE:
829 case BFD_MACH_O_LC_DYSYMTAB:
830 case BFD_MACH_O_LC_LOAD_DYLIB:
831 case BFD_MACH_O_LC_LOAD_WEAK_DYLIB:
832 case BFD_MACH_O_LC_ID_DYLIB:
833 case BFD_MACH_O_LC_LOAD_DYLINKER:
834 case BFD_MACH_O_LC_ID_DYLINKER:
835 case BFD_MACH_O_LC_PREBOUND_DYLIB:
836 case BFD_MACH_O_LC_ROUTINES:
837 case BFD_MACH_O_LC_SUB_FRAMEWORK:
838 break;
839 default:
840 fprintf (stderr,
841 "unable to write unknown load command 0x%lx\n",
0af1713e 842 (unsigned long) cur->type);
b34976b6 843 return FALSE;
3af9a47b
NC
844 }
845 }
846
b34976b6 847 return TRUE;
3af9a47b
NC
848}
849
154a1ee5
TG
850/* Build Mach-O load commands from the sections. */
851
852bfd_boolean
853bfd_mach_o_build_commands (bfd *abfd)
854{
855 bfd_mach_o_data_struct *mdata = bfd_get_mach_o_data (abfd);
c2f09c75 856 unsigned int wide = mach_o_wide_p (&mdata->header);
154a1ee5
TG
857 bfd_mach_o_segment_command *seg;
858 bfd_mach_o_section *sections;
859 asection *sec;
860 file_ptr filepos;
c2f09c75
TG
861 bfd_mach_o_load_command *cmd;
862 bfd_mach_o_load_command *symtab_cmd;
863 int target_index;
154a1ee5
TG
864
865 /* Return now if commands are already built. */
866 if (mdata->header.ncmds)
867 return FALSE;
868
869 /* Very simple version: 1 command (segment) containing all sections. */
c2f09c75
TG
870 mdata->header.ncmds = 2;
871 mdata->commands = bfd_alloc (abfd, mdata->header.ncmds
154a1ee5
TG
872 * sizeof (bfd_mach_o_load_command));
873 if (mdata->commands == NULL)
874 return FALSE;
c2f09c75
TG
875 cmd = &mdata->commands[0];
876 seg = &cmd->command.segment;
877
154a1ee5
TG
878 seg->nsects = bfd_count_sections (abfd);
879 sections = bfd_alloc (abfd, seg->nsects * sizeof (bfd_mach_o_section));
880 if (sections == NULL)
881 return FALSE;
882 seg->sections = sections;
883
884 /* Set segment command. */
885 if (wide)
886 {
c2f09c75
TG
887 cmd->type = BFD_MACH_O_LC_SEGMENT_64;
888 cmd->offset = BFD_MACH_O_HEADER_64_SIZE;
889 cmd->len = BFD_MACH_O_LC_SEGMENT_64_SIZE
154a1ee5
TG
890 + BFD_MACH_O_SECTION_64_SIZE * seg->nsects;
891 }
892 else
893 {
c2f09c75
TG
894 cmd->type = BFD_MACH_O_LC_SEGMENT;
895 cmd->offset = BFD_MACH_O_HEADER_SIZE;
896 cmd->len = BFD_MACH_O_LC_SEGMENT_SIZE
154a1ee5
TG
897 + BFD_MACH_O_SECTION_SIZE * seg->nsects;
898 }
c2f09c75
TG
899 cmd->type_required = FALSE;
900 mdata->header.sizeofcmds = cmd->len;
901 filepos = cmd->offset + cmd->len;
154a1ee5 902
c2f09c75
TG
903 /* Set symtab command. */
904 symtab_cmd = &mdata->commands[1];
905
906 symtab_cmd->type = BFD_MACH_O_LC_SYMTAB;
907 symtab_cmd->offset = cmd->offset + cmd->len;
908 symtab_cmd->len = 6 * 4;
909 symtab_cmd->type_required = FALSE;
910
911 mdata->header.sizeofcmds += symtab_cmd->len;
912 filepos += symtab_cmd->len;
913
914 /* Fill segment command. */
154a1ee5
TG
915 memset (seg->segname, 0, sizeof (seg->segname));
916 seg->vmaddr = 0;
917 seg->fileoff = filepos;
918 seg->filesize = 0;
919 seg->maxprot = BFD_MACH_O_PROT_READ | BFD_MACH_O_PROT_WRITE
920 | BFD_MACH_O_PROT_EXECUTE;
921 seg->initprot = seg->maxprot;
922 seg->flags = 0;
923
924 /* Create Mach-O sections. */
c2f09c75 925 target_index = 0;
154a1ee5
TG
926 for (sec = abfd->sections; sec; sec = sec->next)
927 {
928 sections->bfdsection = sec;
929 bfd_mach_o_convert_section_name_to_mach_o (abfd, sec, sections);
930 sections->addr = bfd_get_section_vma (abfd, sec);
931 sections->size = bfd_get_section_size (sec);
932 sections->align = bfd_get_section_alignment (abfd, sec);
c2f09c75 933
154a1ee5
TG
934 filepos = (filepos + ((file_ptr) 1 << sections->align) - 1)
935 & ((file_ptr) -1 << sections->align);
936 sections->offset = filepos;
937 sections->reloff = 0;
938 sections->nreloc = 0;
939 sections->reserved1 = 0;
940 sections->reserved2 = 0;
941 sections->reserved3 = 0;
942
943 sec->filepos = filepos;
c2f09c75 944 sec->target_index = ++target_index;
154a1ee5
TG
945
946 filepos += sections->size;
947 sections++;
948 }
949 seg->filesize = filepos - seg->fileoff;
950 seg->vmsize = seg->filesize;
951
c2f09c75
TG
952 /* Fill symtab command.
953 Note: we don't know the number of symbols.
954 Also, symtab is at the end since the length of the symbol table (and
955 string table) is not known. */
956 symtab_cmd->command.symtab.symoff = filepos;
957
154a1ee5
TG
958 return TRUE;
959}
960
961/* Set the contents of a section. */
962
963bfd_boolean
964bfd_mach_o_set_section_contents (bfd *abfd,
965 asection *section,
966 const void * location,
967 file_ptr offset,
968 bfd_size_type count)
969{
970 file_ptr pos;
971
972 /* This must be done first, because bfd_set_section_contents is
973 going to set output_has_begun to TRUE. */
974 if (! abfd->output_has_begun && ! bfd_mach_o_build_commands (abfd))
975 return FALSE;
976
977 if (count == 0)
978 return TRUE;
979
980 pos = section->filepos + offset;
981 if (bfd_seek (abfd, pos, SEEK_SET) != 0
982 || bfd_bwrite (location, count, abfd) != count)
983 return FALSE;
984
985 return TRUE;
986}
987
988int
116c20d2 989bfd_mach_o_sizeof_headers (bfd *a ATTRIBUTE_UNUSED,
a6b96beb 990 struct bfd_link_info *info ATTRIBUTE_UNUSED)
3af9a47b
NC
991{
992 return 0;
993}
994
995/* Make an empty symbol. This is required only because
996 bfd_make_section_anyway wants to create a symbol for the section. */
997
154a1ee5 998asymbol *
116c20d2 999bfd_mach_o_make_empty_symbol (bfd *abfd)
3af9a47b
NC
1000{
1001 asymbol *new;
1002
116c20d2 1003 new = bfd_zalloc (abfd, sizeof (* new));
3af9a47b
NC
1004 if (new == NULL)
1005 return new;
1006 new->the_bfd = abfd;
1007 return new;
1008}
1009
154a1ee5 1010static bfd_boolean
116c20d2 1011bfd_mach_o_read_header (bfd *abfd, bfd_mach_o_header *header)
3af9a47b 1012{
1e8a024a
TG
1013 unsigned char buf[32];
1014 unsigned int size;
edeb6e24 1015 bfd_vma (*get32) (const void *) = NULL;
3af9a47b 1016
1e8a024a 1017 /* Just read the magic number. */
c2f09c75
TG
1018 if (bfd_seek (abfd, 0, SEEK_SET) != 0
1019 || bfd_bread ((PTR) buf, 4, abfd) != 4)
154a1ee5 1020 return FALSE;
3af9a47b 1021
154a1ee5 1022 if (bfd_getb32 (buf) == BFD_MACH_O_MH_MAGIC)
3af9a47b
NC
1023 {
1024 header->byteorder = BFD_ENDIAN_BIG;
154a1ee5 1025 header->magic = BFD_MACH_O_MH_MAGIC;
1e8a024a 1026 header->version = 1;
3af9a47b
NC
1027 get32 = bfd_getb32;
1028 }
154a1ee5 1029 else if (bfd_getl32 (buf) == BFD_MACH_O_MH_MAGIC)
3af9a47b 1030 {
a95a4550 1031 header->byteorder = BFD_ENDIAN_LITTLE;
154a1ee5 1032 header->magic = BFD_MACH_O_MH_MAGIC;
1e8a024a
TG
1033 header->version = 1;
1034 get32 = bfd_getl32;
1035 }
154a1ee5 1036 else if (bfd_getb32 (buf) == BFD_MACH_O_MH_MAGIC_64)
1e8a024a
TG
1037 {
1038 header->byteorder = BFD_ENDIAN_BIG;
154a1ee5 1039 header->magic = BFD_MACH_O_MH_MAGIC_64;
1e8a024a
TG
1040 header->version = 2;
1041 get32 = bfd_getb32;
1042 }
154a1ee5 1043 else if (bfd_getl32 (buf) == BFD_MACH_O_MH_MAGIC_64)
1e8a024a
TG
1044 {
1045 header->byteorder = BFD_ENDIAN_LITTLE;
154a1ee5 1046 header->magic = BFD_MACH_O_MH_MAGIC_64;
1e8a024a 1047 header->version = 2;
3af9a47b
NC
1048 get32 = bfd_getl32;
1049 }
1050 else
1051 {
1052 header->byteorder = BFD_ENDIAN_UNKNOWN;
154a1ee5 1053 return FALSE;
3af9a47b 1054 }
a95a4550 1055
1e8a024a 1056 /* Once the size of the header is known, read the full header. */
c2f09c75 1057 size = mach_o_wide_p (header) ?
154a1ee5 1058 BFD_MACH_O_HEADER_64_SIZE : BFD_MACH_O_HEADER_SIZE;
1e8a024a 1059
c2f09c75
TG
1060 if (bfd_seek (abfd, 0, SEEK_SET) != 0
1061 || bfd_bread ((PTR) buf, size, abfd) != size)
154a1ee5 1062 return FALSE;
1e8a024a 1063
3af9a47b
NC
1064 header->cputype = (*get32) (buf + 4);
1065 header->cpusubtype = (*get32) (buf + 8);
1066 header->filetype = (*get32) (buf + 12);
1067 header->ncmds = (*get32) (buf + 16);
1068 header->sizeofcmds = (*get32) (buf + 20);
1069 header->flags = (*get32) (buf + 24);
1070
c2f09c75 1071 if (mach_o_wide_p (header))
1e8a024a
TG
1072 header->reserved = (*get32) (buf + 28);
1073
154a1ee5 1074 return TRUE;
3af9a47b
NC
1075}
1076
1077static asection *
15e1c58a
TG
1078bfd_mach_o_make_bfd_section (bfd *abfd, bfd_mach_o_section *section,
1079 unsigned long prot)
3af9a47b
NC
1080{
1081 asection *bfdsec;
1082 char *sname;
117ed4f8 1083 flagword flags;
3af9a47b 1084
154a1ee5 1085 sname = bfd_mach_o_convert_section_name_to_bfd (abfd, section);
3af9a47b
NC
1086 if (sname == NULL)
1087 return NULL;
3af9a47b 1088
15e1c58a
TG
1089 if (section->flags & BFD_MACH_O_S_ATTR_DEBUG)
1090 flags = SEC_HAS_CONTENTS | SEC_DEBUGGING;
1091 else
1092 {
1093 flags = SEC_ALLOC;
1094 if ((section->flags & BFD_MACH_O_SECTION_TYPE_MASK)
1095 != BFD_MACH_O_S_ZEROFILL)
1096 {
1097 flags |= SEC_HAS_CONTENTS | SEC_LOAD;
1098 if (prot & BFD_MACH_O_PROT_EXECUTE)
1099 flags |= SEC_CODE;
1100 if (prot & BFD_MACH_O_PROT_WRITE)
1101 flags |= SEC_DATA;
1102 else if (prot & BFD_MACH_O_PROT_READ)
1103 flags |= SEC_READONLY;
1104 }
1105 }
117ed4f8 1106 bfdsec = bfd_make_section_anyway_with_flags (abfd, sname, flags);
3af9a47b
NC
1107 if (bfdsec == NULL)
1108 return NULL;
a95a4550 1109
3af9a47b
NC
1110 bfdsec->vma = section->addr;
1111 bfdsec->lma = section->addr;
eea6121a 1112 bfdsec->size = section->size;
3af9a47b
NC
1113 bfdsec->filepos = section->offset;
1114 bfdsec->alignment_power = section->align;
1e8a024a 1115 bfdsec->segment_mark = 0;
3af9a47b 1116
3af9a47b
NC
1117 return bfdsec;
1118}
1119
1120static int
1e8a024a
TG
1121bfd_mach_o_scan_read_section_32 (bfd *abfd,
1122 bfd_mach_o_section *section,
15e1c58a
TG
1123 bfd_vma offset,
1124 unsigned long prot)
3af9a47b 1125{
154a1ee5 1126 unsigned char buf[BFD_MACH_O_SECTION_SIZE];
3af9a47b 1127
c2f09c75
TG
1128 if (bfd_seek (abfd, offset, SEEK_SET) != 0
1129 || (bfd_bread ((PTR) buf, BFD_MACH_O_SECTION_SIZE, abfd)
1130 != BFD_MACH_O_SECTION_SIZE))
3af9a47b 1131 return -1;
a95a4550 1132
3af9a47b
NC
1133 memcpy (section->sectname, buf, 16);
1134 section->sectname[16] = '\0';
1135 memcpy (section->segname, buf + 16, 16);
1136 section->segname[16] = '\0';
1137 section->addr = bfd_h_get_32 (abfd, buf + 32);
1138 section->size = bfd_h_get_32 (abfd, buf + 36);
1139 section->offset = bfd_h_get_32 (abfd, buf + 40);
1140 section->align = bfd_h_get_32 (abfd, buf + 44);
1141 section->reloff = bfd_h_get_32 (abfd, buf + 48);
1142 section->nreloc = bfd_h_get_32 (abfd, buf + 52);
1143 section->flags = bfd_h_get_32 (abfd, buf + 56);
1144 section->reserved1 = bfd_h_get_32 (abfd, buf + 60);
1145 section->reserved2 = bfd_h_get_32 (abfd, buf + 64);
1e8a024a 1146 section->reserved3 = 0;
15e1c58a 1147 section->bfdsection = bfd_mach_o_make_bfd_section (abfd, section, prot);
1e8a024a
TG
1148
1149 if (section->bfdsection == NULL)
1150 return -1;
1151
1152 return 0;
1153}
1154
1155static int
1156bfd_mach_o_scan_read_section_64 (bfd *abfd,
1157 bfd_mach_o_section *section,
15e1c58a
TG
1158 bfd_vma offset,
1159 unsigned long prot)
1e8a024a 1160{
154a1ee5 1161 unsigned char buf[BFD_MACH_O_SECTION_64_SIZE];
1e8a024a 1162
c2f09c75
TG
1163 if (bfd_seek (abfd, offset, SEEK_SET) != 0
1164 || (bfd_bread ((PTR) buf, BFD_MACH_O_SECTION_64_SIZE, abfd)
1165 != BFD_MACH_O_SECTION_64_SIZE))
1e8a024a
TG
1166 return -1;
1167
1168 memcpy (section->sectname, buf, 16);
1169 section->sectname[16] = '\0';
1170 memcpy (section->segname, buf + 16, 16);
1171 section->segname[16] = '\0';
1172 section->addr = bfd_h_get_64 (abfd, buf + 32);
1173 section->size = bfd_h_get_64 (abfd, buf + 40);
1174 section->offset = bfd_h_get_32 (abfd, buf + 48);
1175 section->align = bfd_h_get_32 (abfd, buf + 52);
1176 section->reloff = bfd_h_get_32 (abfd, buf + 56);
1177 section->nreloc = bfd_h_get_32 (abfd, buf + 60);
1178 section->flags = bfd_h_get_32 (abfd, buf + 64);
1179 section->reserved1 = bfd_h_get_32 (abfd, buf + 68);
1180 section->reserved2 = bfd_h_get_32 (abfd, buf + 72);
1181 section->reserved3 = bfd_h_get_32 (abfd, buf + 76);
15e1c58a 1182 section->bfdsection = bfd_mach_o_make_bfd_section (abfd, section, prot);
3af9a47b
NC
1183
1184 if (section->bfdsection == NULL)
1185 return -1;
1186
1187 return 0;
1188}
1189
1e8a024a
TG
1190static int
1191bfd_mach_o_scan_read_section (bfd *abfd,
1192 bfd_mach_o_section *section,
1193 bfd_vma offset,
15e1c58a 1194 unsigned long prot,
1e8a024a
TG
1195 unsigned int wide)
1196{
1197 if (wide)
15e1c58a 1198 return bfd_mach_o_scan_read_section_64 (abfd, section, offset, prot);
1e8a024a 1199 else
15e1c58a 1200 return bfd_mach_o_scan_read_section_32 (abfd, section, offset, prot);
1e8a024a
TG
1201}
1202
3af9a47b 1203int
116c20d2
NC
1204bfd_mach_o_scan_read_symtab_symbol (bfd *abfd,
1205 bfd_mach_o_symtab_command *sym,
1206 asymbol *s,
1207 unsigned long i)
3af9a47b
NC
1208{
1209 bfd_mach_o_data_struct *mdata = abfd->tdata.mach_o_data;
c2f09c75 1210 unsigned int wide = mach_o_wide_p (&mdata->header);
1e8a024a
TG
1211 unsigned int symwidth = wide ? 16 : 12;
1212 bfd_vma symoff = sym->symoff + (i * symwidth);
1213 unsigned char buf[16];
3af9a47b
NC
1214 unsigned char type = -1;
1215 unsigned char section = -1;
1216 short desc = -1;
1e8a024a 1217 symvalue value = -1;
3af9a47b
NC
1218 unsigned long stroff = -1;
1219 unsigned int symtype = -1;
1220
1221 BFD_ASSERT (sym->strtab != NULL);
1222
c2f09c75
TG
1223 if (bfd_seek (abfd, symoff, SEEK_SET) != 0
1224 || bfd_bread ((PTR) buf, symwidth, abfd) != symwidth)
3af9a47b
NC
1225 {
1226 fprintf (stderr, "bfd_mach_o_scan_read_symtab_symbol: unable to read %d bytes at %lu\n",
1e8a024a 1227 symwidth, (unsigned long) symoff);
3af9a47b
NC
1228 return -1;
1229 }
1230
1231 stroff = bfd_h_get_32 (abfd, buf);
1232 type = bfd_h_get_8 (abfd, buf + 4);
c2f09c75 1233 symtype = type & BFD_MACH_O_N_TYPE;
15e1c58a 1234 section = bfd_h_get_8 (abfd, buf + 5);
3af9a47b 1235 desc = bfd_h_get_16 (abfd, buf + 6);
1e8a024a
TG
1236 if (wide)
1237 value = bfd_h_get_64 (abfd, buf + 8);
1238 else
1239 value = bfd_h_get_32 (abfd, buf + 8);
3af9a47b
NC
1240
1241 if (stroff >= sym->strsize)
1242 {
1243 fprintf (stderr, "bfd_mach_o_scan_read_symtab_symbol: symbol name out of range (%lu >= %lu)\n",
1244 (unsigned long) stroff, (unsigned long) sym->strsize);
a95a4550 1245 return -1;
3af9a47b
NC
1246 }
1247
1248 s->the_bfd = abfd;
1249 s->name = sym->strtab + stroff;
1250 s->value = value;
1251 s->udata.i = (type << 24) | (section << 16) | desc;
1252 s->flags = 0x0;
1253
1254 if (type & BFD_MACH_O_N_STAB)
1255 {
1256 s->flags |= BSF_DEBUGGING;
1257 s->section = bfd_und_section_ptr;
15e1c58a
TG
1258 switch (type)
1259 {
1260 case N_FUN:
1261 case N_STSYM:
1262 case N_LCSYM:
1263 case N_BNSYM:
1264 case N_SLINE:
1265 case N_ENSYM:
1266 case N_ECOMM:
1267 case N_ECOML:
1268 case N_GSYM:
1269 if ((section > 0) && (section <= mdata->nsects))
1270 {
1271 s->section = mdata->sections[section - 1]->bfdsection;
1272 s->value = s->value - mdata->sections[section - 1]->addr;
1273 }
1274 break;
1275 }
3af9a47b
NC
1276 }
1277 else
1278 {
1279 if (type & BFD_MACH_O_N_PEXT)
15e1c58a 1280 s->flags |= BSF_GLOBAL;
c2f09c75 1281
3af9a47b 1282 if (type & BFD_MACH_O_N_EXT)
15e1c58a
TG
1283 s->flags |= BSF_GLOBAL;
1284
1285 if (!(type & (BFD_MACH_O_N_PEXT | BFD_MACH_O_N_EXT)))
1286 s->flags |= BSF_LOCAL;
3af9a47b
NC
1287
1288 switch (symtype)
1289 {
1290 case BFD_MACH_O_N_UNDF:
c2f09c75
TG
1291 if (type == (BFD_MACH_O_N_UNDF | BFD_MACH_O_N_EXT)
1292 && s->value != 0)
1293 {
1294 /* A common symbol. */
1295 s->section = bfd_com_section_ptr;
1296 s->flags = BSF_NO_FLAGS;
1297 }
1298 else
1299 s->section = bfd_und_section_ptr;
3af9a47b
NC
1300 break;
1301 case BFD_MACH_O_N_PBUD:
1302 s->section = bfd_und_section_ptr;
1303 break;
1304 case BFD_MACH_O_N_ABS:
1305 s->section = bfd_abs_section_ptr;
1306 break;
1307 case BFD_MACH_O_N_SECT:
1308 if ((section > 0) && (section <= mdata->nsects))
1309 {
15e1c58a
TG
1310 s->section = mdata->sections[section - 1]->bfdsection;
1311 s->value = s->value - mdata->sections[section - 1]->addr;
3af9a47b
NC
1312 }
1313 else
1314 {
1315 /* Mach-O uses 0 to mean "no section"; not an error. */
1316 if (section != 0)
1317 {
1318 fprintf (stderr, "bfd_mach_o_scan_read_symtab_symbol: "
a95a4550 1319 "symbol \"%s\" specified invalid section %d (max %lu): setting to undefined\n",
3af9a47b
NC
1320 s->name, section, mdata->nsects);
1321 }
1322 s->section = bfd_und_section_ptr;
1323 }
1324 break;
1325 case BFD_MACH_O_N_INDR:
1326 fprintf (stderr, "bfd_mach_o_scan_read_symtab_symbol: "
a95a4550 1327 "symbol \"%s\" is unsupported 'indirect' reference: setting to undefined\n",
3af9a47b
NC
1328 s->name);
1329 s->section = bfd_und_section_ptr;
1330 break;
1331 default:
1332 fprintf (stderr, "bfd_mach_o_scan_read_symtab_symbol: "
a95a4550 1333 "symbol \"%s\" specified invalid type field 0x%x: setting to undefined\n",
3af9a47b
NC
1334 s->name, symtype);
1335 s->section = bfd_und_section_ptr;
1336 break;
1337 }
1338 }
1339
1340 return 0;
1341}
1342
1343int
116c20d2
NC
1344bfd_mach_o_scan_read_symtab_strtab (bfd *abfd,
1345 bfd_mach_o_symtab_command *sym)
3af9a47b
NC
1346{
1347 BFD_ASSERT (sym->strtab == NULL);
1348
1349 if (abfd->flags & BFD_IN_MEMORY)
1350 {
1351 struct bfd_in_memory *b;
1352
1353 b = (struct bfd_in_memory *) abfd->iostream;
1354
1355 if ((sym->stroff + sym->strsize) > b->size)
1356 {
1357 bfd_set_error (bfd_error_file_truncated);
1358 return -1;
1359 }
f075ee0c 1360 sym->strtab = (char *) b->buffer + sym->stroff;
3af9a47b
NC
1361 return 0;
1362 }
1363
1364 sym->strtab = bfd_alloc (abfd, sym->strsize);
1365 if (sym->strtab == NULL)
1366 return -1;
1367
c2f09c75
TG
1368 if (bfd_seek (abfd, sym->stroff, SEEK_SET) != 0
1369 || bfd_bread ((PTR) sym->strtab, sym->strsize, abfd) != sym->strsize)
3af9a47b
NC
1370 {
1371 fprintf (stderr, "bfd_mach_o_scan_read_symtab_strtab: unable to read %lu bytes at %lu\n",
1372 sym->strsize, sym->stroff);
a95a4550 1373 return -1;
3af9a47b
NC
1374 }
1375
1376 return 0;
1377}
1378
a95a4550 1379int
116c20d2
NC
1380bfd_mach_o_scan_read_symtab_symbols (bfd *abfd,
1381 bfd_mach_o_symtab_command *sym)
3af9a47b
NC
1382{
1383 unsigned long i;
1384 int ret;
1385
1386 BFD_ASSERT (sym->symbols == NULL);
1387 sym->symbols = bfd_alloc (abfd, sym->nsyms * sizeof (asymbol));
1388
1389 if (sym->symbols == NULL)
1390 {
1391 fprintf (stderr, "bfd_mach_o_scan_read_symtab_symbols: unable to allocate memory for symbols\n");
a95a4550 1392 return -1;
3af9a47b 1393 }
a95a4550 1394
3af9a47b
NC
1395 ret = bfd_mach_o_scan_read_symtab_strtab (abfd, sym);
1396 if (ret != 0)
1397 return ret;
1398
1399 for (i = 0; i < sym->nsyms; i++)
1400 {
1401 ret = bfd_mach_o_scan_read_symtab_symbol (abfd, sym, &sym->symbols[i], i);
1402 if (ret != 0)
1403 return ret;
1404 }
a95a4550 1405
3af9a47b
NC
1406 return 0;
1407}
1408
1409int
116c20d2
NC
1410bfd_mach_o_scan_read_dysymtab_symbol (bfd *abfd,
1411 bfd_mach_o_dysymtab_command *dysym,
1412 bfd_mach_o_symtab_command *sym,
1413 asymbol *s,
1414 unsigned long i)
3af9a47b
NC
1415{
1416 unsigned long isymoff = dysym->indirectsymoff + (i * 4);
1417 unsigned long symindex;
1418 unsigned char buf[4];
1419
1420 BFD_ASSERT (i < dysym->nindirectsyms);
a95a4550 1421
c2f09c75
TG
1422 if (bfd_seek (abfd, isymoff, SEEK_SET) != 0
1423 || bfd_bread ((PTR) buf, 4, abfd) != 4)
3af9a47b
NC
1424 {
1425 fprintf (stderr, "bfd_mach_o_scan_read_dysymtab_symbol: unable to read %lu bytes at %lu\n",
1426 (unsigned long) 4, isymoff);
1427 return -1;
1428 }
1429 symindex = bfd_h_get_32 (abfd, buf);
a95a4550 1430
3af9a47b
NC
1431 return bfd_mach_o_scan_read_symtab_symbol (abfd, sym, s, symindex);
1432}
1433
1434static const char *
116c20d2 1435bfd_mach_o_i386_flavour_string (unsigned int flavour)
3af9a47b
NC
1436{
1437 switch ((int) flavour)
1438 {
15e1c58a
TG
1439 case BFD_MACH_O_x86_THREAD_STATE32: return "x86_THREAD_STATE32";
1440 case BFD_MACH_O_x86_FLOAT_STATE32: return "x86_FLOAT_STATE32";
1441 case BFD_MACH_O_x86_EXCEPTION_STATE32: return "x86_EXCEPTION_STATE32";
1442 case BFD_MACH_O_x86_THREAD_STATE64: return "x86_THREAD_STATE64";
1443 case BFD_MACH_O_x86_FLOAT_STATE64: return "x86_FLOAT_STATE64";
1444 case BFD_MACH_O_x86_EXCEPTION_STATE64: return "x86_EXCEPTION_STATE64";
1445 case BFD_MACH_O_x86_THREAD_STATE: return "x86_THREAD_STATE";
1446 case BFD_MACH_O_x86_FLOAT_STATE: return "x86_FLOAT_STATE";
1447 case BFD_MACH_O_x86_EXCEPTION_STATE: return "x86_EXCEPTION_STATE";
1448 case BFD_MACH_O_x86_DEBUG_STATE32: return "x86_DEBUG_STATE32";
1449 case BFD_MACH_O_x86_DEBUG_STATE64: return "x86_DEBUG_STATE64";
1450 case BFD_MACH_O_x86_DEBUG_STATE: return "x86_DEBUG_STATE";
1451 case BFD_MACH_O_THREAD_STATE_NONE: return "THREAD_STATE_NONE";
3af9a47b
NC
1452 default: return "UNKNOWN";
1453 }
1454}
1455
1456static const char *
116c20d2 1457bfd_mach_o_ppc_flavour_string (unsigned int flavour)
3af9a47b
NC
1458{
1459 switch ((int) flavour)
1460 {
1461 case BFD_MACH_O_PPC_THREAD_STATE: return "PPC_THREAD_STATE";
1462 case BFD_MACH_O_PPC_FLOAT_STATE: return "PPC_FLOAT_STATE";
1463 case BFD_MACH_O_PPC_EXCEPTION_STATE: return "PPC_EXCEPTION_STATE";
1464 case BFD_MACH_O_PPC_VECTOR_STATE: return "PPC_VECTOR_STATE";
1465 default: return "UNKNOWN";
1466 }
1467}
1468
1469static int
116c20d2
NC
1470bfd_mach_o_scan_read_dylinker (bfd *abfd,
1471 bfd_mach_o_load_command *command)
3af9a47b
NC
1472{
1473 bfd_mach_o_dylinker_command *cmd = &command->command.dylinker;
1474 unsigned char buf[4];
1475 unsigned int nameoff;
1476 asection *bfdsec;
1477 char *sname;
1478 const char *prefix;
1479
1480 BFD_ASSERT ((command->type == BFD_MACH_O_LC_ID_DYLINKER)
1481 || (command->type == BFD_MACH_O_LC_LOAD_DYLINKER));
1482
c2f09c75
TG
1483 if (bfd_seek (abfd, command->offset + 8, SEEK_SET) != 0
1484 || bfd_bread ((PTR) buf, 4, abfd) != 4)
3af9a47b
NC
1485 return -1;
1486
1487 nameoff = bfd_h_get_32 (abfd, buf + 0);
1488
1489 cmd->name_offset = command->offset + nameoff;
1490 cmd->name_len = command->len - nameoff;
1491
1492 if (command->type == BFD_MACH_O_LC_LOAD_DYLINKER)
1493 prefix = "LC_LOAD_DYLINKER";
1494 else if (command->type == BFD_MACH_O_LC_ID_DYLINKER)
1495 prefix = "LC_ID_DYLINKER";
1496 else
1497 abort ();
1498
116c20d2 1499 sname = bfd_alloc (abfd, strlen (prefix) + 1);
3af9a47b
NC
1500 if (sname == NULL)
1501 return -1;
1502 strcpy (sname, prefix);
1503
117ed4f8 1504 bfdsec = bfd_make_section_anyway_with_flags (abfd, sname, SEC_HAS_CONTENTS);
3af9a47b
NC
1505 if (bfdsec == NULL)
1506 return -1;
a95a4550 1507
3af9a47b
NC
1508 bfdsec->vma = 0;
1509 bfdsec->lma = 0;
846b9259
TG
1510 bfdsec->size = command->len - nameoff;
1511 bfdsec->filepos = command->offset + nameoff;
3af9a47b 1512 bfdsec->alignment_power = 0;
3af9a47b
NC
1513
1514 cmd->section = bfdsec;
1515
1516 return 0;
1517}
1518
1519static int
116c20d2 1520bfd_mach_o_scan_read_dylib (bfd *abfd, bfd_mach_o_load_command *command)
3af9a47b
NC
1521{
1522 bfd_mach_o_dylib_command *cmd = &command->command.dylib;
1523 unsigned char buf[16];
1524 unsigned int nameoff;
1525 asection *bfdsec;
1526 char *sname;
1527 const char *prefix;
1528
1529 BFD_ASSERT ((command->type == BFD_MACH_O_LC_ID_DYLIB)
1530 || (command->type == BFD_MACH_O_LC_LOAD_DYLIB)
1531 || (command->type == BFD_MACH_O_LC_LOAD_WEAK_DYLIB));
1532
c2f09c75
TG
1533 if (bfd_seek (abfd, command->offset + 8, SEEK_SET) != 0
1534 || bfd_bread ((PTR) buf, 16, abfd) != 16)
3af9a47b
NC
1535 return -1;
1536
1537 nameoff = bfd_h_get_32 (abfd, buf + 0);
1538 cmd->timestamp = bfd_h_get_32 (abfd, buf + 4);
1539 cmd->current_version = bfd_h_get_32 (abfd, buf + 8);
1540 cmd->compatibility_version = bfd_h_get_32 (abfd, buf + 12);
1541
1542 cmd->name_offset = command->offset + nameoff;
1543 cmd->name_len = command->len - nameoff;
1544
1545 if (command->type == BFD_MACH_O_LC_LOAD_DYLIB)
1546 prefix = "LC_LOAD_DYLIB";
1547 else if (command->type == BFD_MACH_O_LC_LOAD_WEAK_DYLIB)
1548 prefix = "LC_LOAD_WEAK_DYLIB";
1549 else if (command->type == BFD_MACH_O_LC_ID_DYLIB)
1550 prefix = "LC_ID_DYLIB";
1551 else
1552 abort ();
1553
116c20d2 1554 sname = bfd_alloc (abfd, strlen (prefix) + 1);
3af9a47b
NC
1555 if (sname == NULL)
1556 return -1;
1557 strcpy (sname, prefix);
1558
117ed4f8 1559 bfdsec = bfd_make_section_anyway_with_flags (abfd, sname, SEC_HAS_CONTENTS);
3af9a47b
NC
1560 if (bfdsec == NULL)
1561 return -1;
a95a4550 1562
3af9a47b
NC
1563 bfdsec->vma = 0;
1564 bfdsec->lma = 0;
eea6121a 1565 bfdsec->size = command->len - 8;
3af9a47b
NC
1566 bfdsec->filepos = command->offset + 8;
1567 bfdsec->alignment_power = 0;
3af9a47b
NC
1568
1569 cmd->section = bfdsec;
1570
1571 return 0;
1572}
1573
1574static int
116c20d2
NC
1575bfd_mach_o_scan_read_prebound_dylib (bfd *abfd ATTRIBUTE_UNUSED,
1576 bfd_mach_o_load_command *command ATTRIBUTE_UNUSED)
3af9a47b
NC
1577{
1578 /* bfd_mach_o_prebound_dylib_command *cmd = &command->command.prebound_dylib; */
1579
1580 BFD_ASSERT (command->type == BFD_MACH_O_LC_PREBOUND_DYLIB);
1581 return 0;
1582}
1583
1584static int
116c20d2 1585bfd_mach_o_scan_read_thread (bfd *abfd, bfd_mach_o_load_command *command)
3af9a47b
NC
1586{
1587 bfd_mach_o_data_struct *mdata = NULL;
1588 bfd_mach_o_thread_command *cmd = &command->command.thread;
1589 unsigned char buf[8];
1590 bfd_vma offset;
1591 unsigned int nflavours;
1592 unsigned int i;
1593
1594 BFD_ASSERT ((command->type == BFD_MACH_O_LC_THREAD)
1595 || (command->type == BFD_MACH_O_LC_UNIXTHREAD));
1596
1597 BFD_ASSERT (bfd_mach_o_valid (abfd));
1598 mdata = abfd->tdata.mach_o_data;
a95a4550 1599
3af9a47b
NC
1600 offset = 8;
1601 nflavours = 0;
1602 while (offset != command->len)
1603 {
1604 if (offset >= command->len)
1605 return -1;
1606
c2f09c75
TG
1607 if (bfd_seek (abfd, command->offset + offset, SEEK_SET) != 0
1608 || bfd_bread ((PTR) buf, 8, abfd) != 8)
3af9a47b
NC
1609 return -1;
1610
1611 offset += 8 + bfd_h_get_32 (abfd, buf + 4) * 4;
1612 nflavours++;
1613 }
1614
116c20d2 1615 cmd->flavours = bfd_alloc (abfd, nflavours * sizeof (bfd_mach_o_thread_flavour));
3af9a47b
NC
1616 if (cmd->flavours == NULL)
1617 return -1;
1618 cmd->nflavours = nflavours;
1619
1620 offset = 8;
1621 nflavours = 0;
1622 while (offset != command->len)
1623 {
1624 if (offset >= command->len)
1625 return -1;
1626
1627 if (nflavours >= cmd->nflavours)
1628 return -1;
1629
c2f09c75
TG
1630 if (bfd_seek (abfd, command->offset + offset, SEEK_SET) != 0
1631 || bfd_bread ((PTR) buf, 8, abfd) != 8)
3af9a47b
NC
1632 return -1;
1633
1634 cmd->flavours[nflavours].flavour = bfd_h_get_32 (abfd, buf);
1635 cmd->flavours[nflavours].offset = command->offset + offset + 8;
1636 cmd->flavours[nflavours].size = bfd_h_get_32 (abfd, buf + 4) * 4;
1637 offset += cmd->flavours[nflavours].size + 8;
1638 nflavours++;
1639 }
1640
1641 for (i = 0; i < nflavours; i++)
1642 {
1643 asection *bfdsec;
1644 unsigned int snamelen;
1645 char *sname;
1646 const char *flavourstr;
1647 const char *prefix = "LC_THREAD";
a95a4550
AM
1648 unsigned int j = 0;
1649
3af9a47b
NC
1650 switch (mdata->header.cputype)
1651 {
1652 case BFD_MACH_O_CPU_TYPE_POWERPC:
1e8a024a 1653 case BFD_MACH_O_CPU_TYPE_POWERPC_64:
3af9a47b
NC
1654 flavourstr = bfd_mach_o_ppc_flavour_string (cmd->flavours[i].flavour);
1655 break;
1656 case BFD_MACH_O_CPU_TYPE_I386:
1e8a024a 1657 case BFD_MACH_O_CPU_TYPE_X86_64:
3af9a47b
NC
1658 flavourstr = bfd_mach_o_i386_flavour_string (cmd->flavours[i].flavour);
1659 break;
1660 default:
1661 flavourstr = "UNKNOWN_ARCHITECTURE";
1662 break;
1663 }
a95a4550 1664
3af9a47b 1665 snamelen = strlen (prefix) + 1 + 20 + 1 + strlen (flavourstr) + 1;
116c20d2 1666 sname = bfd_alloc (abfd, snamelen);
3af9a47b
NC
1667 if (sname == NULL)
1668 return -1;
1669
1670 for (;;)
1671 {
a95a4550
AM
1672 sprintf (sname, "%s.%s.%u", prefix, flavourstr, j);
1673 if (bfd_get_section_by_name (abfd, sname) == NULL)
3af9a47b 1674 break;
a95a4550 1675 j++;
3af9a47b
NC
1676 }
1677
117ed4f8 1678 bfdsec = bfd_make_section_with_flags (abfd, sname, SEC_HAS_CONTENTS);
a95a4550 1679
3af9a47b
NC
1680 bfdsec->vma = 0;
1681 bfdsec->lma = 0;
eea6121a 1682 bfdsec->size = cmd->flavours[i].size;
3af9a47b
NC
1683 bfdsec->filepos = cmd->flavours[i].offset;
1684 bfdsec->alignment_power = 0x0;
3af9a47b
NC
1685
1686 cmd->section = bfdsec;
1687 }
1688
1689 return 0;
1690}
1691
a95a4550 1692static int
116c20d2 1693bfd_mach_o_scan_read_dysymtab (bfd *abfd, bfd_mach_o_load_command *command)
3af9a47b
NC
1694{
1695 bfd_mach_o_dysymtab_command *seg = &command->command.dysymtab;
1696 unsigned char buf[72];
1697
1698 BFD_ASSERT (command->type == BFD_MACH_O_LC_DYSYMTAB);
1699
c2f09c75
TG
1700 if (bfd_seek (abfd, command->offset + 8, SEEK_SET) != 0
1701 || bfd_bread ((PTR) buf, 72, abfd) != 72)
3af9a47b
NC
1702 return -1;
1703
1704 seg->ilocalsym = bfd_h_get_32 (abfd, buf + 0);
1705 seg->nlocalsym = bfd_h_get_32 (abfd, buf + 4);
1706 seg->iextdefsym = bfd_h_get_32 (abfd, buf + 8);
1707 seg->nextdefsym = bfd_h_get_32 (abfd, buf + 12);
1708 seg->iundefsym = bfd_h_get_32 (abfd, buf + 16);
1709 seg->nundefsym = bfd_h_get_32 (abfd, buf + 20);
1710 seg->tocoff = bfd_h_get_32 (abfd, buf + 24);
1711 seg->ntoc = bfd_h_get_32 (abfd, buf + 28);
1712 seg->modtaboff = bfd_h_get_32 (abfd, buf + 32);
1713 seg->nmodtab = bfd_h_get_32 (abfd, buf + 36);
1714 seg->extrefsymoff = bfd_h_get_32 (abfd, buf + 40);
1715 seg->nextrefsyms = bfd_h_get_32 (abfd, buf + 44);
1716 seg->indirectsymoff = bfd_h_get_32 (abfd, buf + 48);
1717 seg->nindirectsyms = bfd_h_get_32 (abfd, buf + 52);
1718 seg->extreloff = bfd_h_get_32 (abfd, buf + 56);
1719 seg->nextrel = bfd_h_get_32 (abfd, buf + 60);
1720 seg->locreloff = bfd_h_get_32 (abfd, buf + 64);
1721 seg->nlocrel = bfd_h_get_32 (abfd, buf + 68);
1722
1723 return 0;
1724}
1725
a95a4550 1726static int
116c20d2 1727bfd_mach_o_scan_read_symtab (bfd *abfd, bfd_mach_o_load_command *command)
3af9a47b
NC
1728{
1729 bfd_mach_o_symtab_command *seg = &command->command.symtab;
1730 unsigned char buf[16];
3af9a47b
NC
1731
1732 BFD_ASSERT (command->type == BFD_MACH_O_LC_SYMTAB);
1733
c2f09c75
TG
1734 if (bfd_seek (abfd, command->offset + 8, SEEK_SET) != 0
1735 || bfd_bread ((PTR) buf, 16, abfd) != 16)
3af9a47b 1736 return -1;
a95a4550 1737
3af9a47b
NC
1738 seg->symoff = bfd_h_get_32 (abfd, buf);
1739 seg->nsyms = bfd_h_get_32 (abfd, buf + 4);
1740 seg->stroff = bfd_h_get_32 (abfd, buf + 8);
1741 seg->strsize = bfd_h_get_32 (abfd, buf + 12);
1742 seg->symbols = NULL;
1743 seg->strtab = NULL;
1744
15e1c58a
TG
1745 if (seg->nsyms != 0)
1746 abfd->flags |= HAS_SYMS;
1747
3af9a47b
NC
1748 return 0;
1749}
1750
15e1c58a
TG
1751static int
1752bfd_mach_o_scan_read_uuid (bfd *abfd, bfd_mach_o_load_command *command)
1753{
1754 bfd_mach_o_uuid_command *cmd = &command->command.uuid;
1755 asection *bfdsec;
1756 char *sname;
1757 static const char prefix[] = "LC_UUID";
1758
1759 BFD_ASSERT (command->type == BFD_MACH_O_LC_UUID);
1760
c2f09c75
TG
1761 if (bfd_seek (abfd, command->offset + 8, SEEK_SET) != 0
1762 || bfd_bread ((PTR) cmd->uuid, 16, abfd) != 16)
15e1c58a
TG
1763 return -1;
1764
1765 sname = bfd_alloc (abfd, strlen (prefix) + 1);
1766 if (sname == NULL)
1767 return -1;
1768 strcpy (sname, prefix);
1769
1770 bfdsec = bfd_make_section_anyway_with_flags (abfd, sname, SEC_HAS_CONTENTS);
1771 if (bfdsec == NULL)
1772 return -1;
1773
1774 bfdsec->vma = 0;
1775 bfdsec->lma = 0;
1776 bfdsec->size = command->len - 8;
1777 bfdsec->filepos = command->offset + 8;
1778 bfdsec->alignment_power = 0;
1779
1780 cmd->section = bfdsec;
1781
1782 return 0;
1783}
1784
3af9a47b 1785static int
1e8a024a
TG
1786bfd_mach_o_scan_read_segment (bfd *abfd,
1787 bfd_mach_o_load_command *command,
1788 unsigned int wide)
3af9a47b 1789{
1e8a024a 1790 unsigned char buf[64];
3af9a47b
NC
1791 bfd_mach_o_segment_command *seg = &command->command.segment;
1792 unsigned long i;
a95a4550 1793
1e8a024a
TG
1794 if (wide)
1795 {
1796 BFD_ASSERT (command->type == BFD_MACH_O_LC_SEGMENT_64);
3af9a47b 1797
c2f09c75
TG
1798 if (bfd_seek (abfd, command->offset + 8, SEEK_SET) != 0
1799 || bfd_bread ((PTR) buf, 64, abfd) != 64)
1e8a024a 1800 return -1;
3af9a47b 1801
1e8a024a 1802 memcpy (seg->segname, buf, 16);
15e1c58a 1803 seg->segname[16] = '\0';
1e8a024a
TG
1804
1805 seg->vmaddr = bfd_h_get_64 (abfd, buf + 16);
1806 seg->vmsize = bfd_h_get_64 (abfd, buf + 24);
1807 seg->fileoff = bfd_h_get_64 (abfd, buf + 32);
1808 seg->filesize = bfd_h_get_64 (abfd, buf + 40);
1809 seg->maxprot = bfd_h_get_32 (abfd, buf + 48);
1810 seg->initprot = bfd_h_get_32 (abfd, buf + 52);
1811 seg->nsects = bfd_h_get_32 (abfd, buf + 56);
1812 seg->flags = bfd_h_get_32 (abfd, buf + 60);
1813 }
1814 else
1815 {
1816 BFD_ASSERT (command->type == BFD_MACH_O_LC_SEGMENT);
1817
c2f09c75
TG
1818 if (bfd_seek (abfd, command->offset + 8, SEEK_SET) != 0
1819 || bfd_bread ((PTR) buf, 48, abfd) != 48)
1e8a024a
TG
1820 return -1;
1821
1822 memcpy (seg->segname, buf, 16);
15e1c58a 1823 seg->segname[16] = '\0';
1e8a024a
TG
1824
1825 seg->vmaddr = bfd_h_get_32 (abfd, buf + 16);
1826 seg->vmsize = bfd_h_get_32 (abfd, buf + 20);
1827 seg->fileoff = bfd_h_get_32 (abfd, buf + 24);
1828 seg->filesize = bfd_h_get_32 (abfd, buf + 28);
1829 seg->maxprot = bfd_h_get_32 (abfd, buf + 32);
1830 seg->initprot = bfd_h_get_32 (abfd, buf + 36);
1831 seg->nsects = bfd_h_get_32 (abfd, buf + 40);
1832 seg->flags = bfd_h_get_32 (abfd, buf + 44);
1833 }
3af9a47b 1834
3af9a47b
NC
1835 if (seg->nsects != 0)
1836 {
154a1ee5
TG
1837 seg->sections = bfd_alloc (abfd, seg->nsects
1838 * sizeof (bfd_mach_o_section));
3af9a47b
NC
1839 if (seg->sections == NULL)
1840 return -1;
a95a4550 1841
3af9a47b
NC
1842 for (i = 0; i < seg->nsects; i++)
1843 {
1e8a024a 1844 bfd_vma segoff;
154a1ee5 1845 if (wide)
c2f09c75 1846 segoff = command->offset + BFD_MACH_O_LC_SEGMENT_64_SIZE
154a1ee5
TG
1847 + (i * BFD_MACH_O_SECTION_64_SIZE);
1848 else
c2f09c75 1849 segoff = command->offset + BFD_MACH_O_LC_SEGMENT_SIZE
154a1ee5 1850 + (i * BFD_MACH_O_SECTION_SIZE);
3af9a47b 1851
1e8a024a 1852 if (bfd_mach_o_scan_read_section
15e1c58a 1853 (abfd, &seg->sections[i], segoff, seg->initprot, wide) != 0)
3af9a47b 1854 return -1;
a95a4550 1855 }
3af9a47b
NC
1856 }
1857
1858 return 0;
1859}
1860
1e8a024a
TG
1861static int
1862bfd_mach_o_scan_read_segment_32 (bfd *abfd, bfd_mach_o_load_command *command)
1863{
1864 return bfd_mach_o_scan_read_segment (abfd, command, 0);
1865}
1866
1867static int
1868bfd_mach_o_scan_read_segment_64 (bfd *abfd, bfd_mach_o_load_command *command)
1869{
1870 return bfd_mach_o_scan_read_segment (abfd, command, 1);
1871}
1872
3af9a47b 1873static int
116c20d2 1874bfd_mach_o_scan_read_command (bfd *abfd, bfd_mach_o_load_command *command)
3af9a47b
NC
1875{
1876 unsigned char buf[8];
1877
c2f09c75
TG
1878 if (bfd_seek (abfd, command->offset, SEEK_SET) != 0
1879 || bfd_bread ((PTR) buf, 8, abfd) != 8)
3af9a47b
NC
1880 return -1;
1881
154a1ee5 1882 command->type = bfd_h_get_32 (abfd, buf) & ~BFD_MACH_O_LC_REQ_DYLD;
e84d6fca 1883 command->type_required = (bfd_h_get_32 (abfd, buf) & BFD_MACH_O_LC_REQ_DYLD
154a1ee5 1884 ? TRUE : FALSE);
3af9a47b
NC
1885 command->len = bfd_h_get_32 (abfd, buf + 4);
1886
1887 switch (command->type)
1888 {
1889 case BFD_MACH_O_LC_SEGMENT:
1e8a024a
TG
1890 if (bfd_mach_o_scan_read_segment_32 (abfd, command) != 0)
1891 return -1;
1892 break;
1893 case BFD_MACH_O_LC_SEGMENT_64:
1894 if (bfd_mach_o_scan_read_segment_64 (abfd, command) != 0)
3af9a47b
NC
1895 return -1;
1896 break;
1897 case BFD_MACH_O_LC_SYMTAB:
1898 if (bfd_mach_o_scan_read_symtab (abfd, command) != 0)
1899 return -1;
1900 break;
1901 case BFD_MACH_O_LC_SYMSEG:
1902 break;
1903 case BFD_MACH_O_LC_THREAD:
1904 case BFD_MACH_O_LC_UNIXTHREAD:
1905 if (bfd_mach_o_scan_read_thread (abfd, command) != 0)
1906 return -1;
1907 break;
1908 case BFD_MACH_O_LC_LOAD_DYLINKER:
1909 case BFD_MACH_O_LC_ID_DYLINKER:
1910 if (bfd_mach_o_scan_read_dylinker (abfd, command) != 0)
1911 return -1;
1912 break;
1913 case BFD_MACH_O_LC_LOAD_DYLIB:
1914 case BFD_MACH_O_LC_ID_DYLIB:
1915 case BFD_MACH_O_LC_LOAD_WEAK_DYLIB:
1916 if (bfd_mach_o_scan_read_dylib (abfd, command) != 0)
1917 return -1;
1918 break;
1919 case BFD_MACH_O_LC_PREBOUND_DYLIB:
1920 if (bfd_mach_o_scan_read_prebound_dylib (abfd, command) != 0)
1921 return -1;
1922 break;
1923 case BFD_MACH_O_LC_LOADFVMLIB:
1924 case BFD_MACH_O_LC_IDFVMLIB:
1925 case BFD_MACH_O_LC_IDENT:
1926 case BFD_MACH_O_LC_FVMFILE:
1927 case BFD_MACH_O_LC_PREPAGE:
1928 case BFD_MACH_O_LC_ROUTINES:
1929 case BFD_MACH_O_LC_SUB_FRAMEWORK:
1930 break;
1931 case BFD_MACH_O_LC_DYSYMTAB:
1932 if (bfd_mach_o_scan_read_dysymtab (abfd, command) != 0)
1933 return -1;
1934 break;
1935 case BFD_MACH_O_LC_SUB_UMBRELLA:
1936 case BFD_MACH_O_LC_SUB_CLIENT:
1937 case BFD_MACH_O_LC_SUB_LIBRARY:
1938 case BFD_MACH_O_LC_TWOLEVEL_HINTS:
1939 case BFD_MACH_O_LC_PREBIND_CKSUM:
1940 break;
15e1c58a
TG
1941 case BFD_MACH_O_LC_UUID:
1942 if (bfd_mach_o_scan_read_uuid (abfd, command) != 0)
1943 return -1;
1944 break;
1945 case BFD_MACH_O_LC_CODE_SIGNATURE:
846b9259
TG
1946 case BFD_MACH_O_LC_SEGMENT_SPLIT_INFO:
1947 case BFD_MACH_O_LC_REEXPORT_DYLIB:
15e1c58a 1948 break;
3af9a47b
NC
1949 default:
1950 fprintf (stderr, "unable to read unknown load command 0x%lx\n",
1951 (unsigned long) command->type);
1952 break;
1953 }
1954
1955 return 0;
1956}
1957
1958static void
116c20d2 1959bfd_mach_o_flatten_sections (bfd *abfd)
3af9a47b
NC
1960{
1961 bfd_mach_o_data_struct *mdata = abfd->tdata.mach_o_data;
1962 long csect = 0;
1963 unsigned long i, j;
a95a4550 1964
15e1c58a 1965 /* Count total number of sections. */
3af9a47b
NC
1966 mdata->nsects = 0;
1967
1968 for (i = 0; i < mdata->header.ncmds; i++)
1969 {
1e8a024a
TG
1970 if (mdata->commands[i].type == BFD_MACH_O_LC_SEGMENT
1971 || mdata->commands[i].type == BFD_MACH_O_LC_SEGMENT_64)
3af9a47b 1972 {
e84d6fca
AM
1973 bfd_mach_o_segment_command *seg;
1974
1975 seg = &mdata->commands[i].command.segment;
3af9a47b
NC
1976 mdata->nsects += seg->nsects;
1977 }
1978 }
1979
15e1c58a 1980 /* Allocate sections array. */
e84d6fca
AM
1981 mdata->sections = bfd_alloc (abfd,
1982 mdata->nsects * sizeof (bfd_mach_o_section *));
15e1c58a
TG
1983
1984 /* Fill the array. */
3af9a47b
NC
1985 csect = 0;
1986
1987 for (i = 0; i < mdata->header.ncmds; i++)
1988 {
1e8a024a
TG
1989 if (mdata->commands[i].type == BFD_MACH_O_LC_SEGMENT
1990 || mdata->commands[i].type == BFD_MACH_O_LC_SEGMENT_64)
3af9a47b 1991 {
e84d6fca 1992 bfd_mach_o_segment_command *seg;
3af9a47b 1993
e84d6fca 1994 seg = &mdata->commands[i].command.segment;
3af9a47b
NC
1995 BFD_ASSERT (csect + seg->nsects <= mdata->nsects);
1996
1997 for (j = 0; j < seg->nsects; j++)
1998 mdata->sections[csect++] = &seg->sections[j];
1999 }
2000 }
2001}
2002
2003int
116c20d2 2004bfd_mach_o_scan_start_address (bfd *abfd)
3af9a47b
NC
2005{
2006 bfd_mach_o_data_struct *mdata = abfd->tdata.mach_o_data;
2007 bfd_mach_o_thread_command *cmd = NULL;
2008 unsigned long i;
2009
2010 for (i = 0; i < mdata->header.ncmds; i++)
2011 {
2012 if ((mdata->commands[i].type == BFD_MACH_O_LC_THREAD) ||
2013 (mdata->commands[i].type == BFD_MACH_O_LC_UNIXTHREAD))
2014 {
2015 if (cmd == NULL)
2016 cmd = &mdata->commands[i].command.thread;
2017 else
2018 return 0;
2019 }
2020 }
2021
2022 if (cmd == NULL)
2023 return 0;
2024
2025 for (i = 0; i < cmd->nflavours; i++)
2026 {
a95a4550 2027 if ((mdata->header.cputype == BFD_MACH_O_CPU_TYPE_I386)
e84d6fca 2028 && (cmd->flavours[i].flavour
15e1c58a 2029 == (unsigned long) BFD_MACH_O_x86_THREAD_STATE32))
3af9a47b
NC
2030 {
2031 unsigned char buf[4];
2032
c2f09c75
TG
2033 if (bfd_seek (abfd, cmd->flavours[i].offset + 40, SEEK_SET) != 0
2034 || bfd_bread (buf, 4, abfd) != 4)
3af9a47b
NC
2035 return -1;
2036
2037 abfd->start_address = bfd_h_get_32 (abfd, buf);
2038 }
a95a4550 2039 else if ((mdata->header.cputype == BFD_MACH_O_CPU_TYPE_POWERPC)
3af9a47b
NC
2040 && (cmd->flavours[i].flavour == BFD_MACH_O_PPC_THREAD_STATE))
2041 {
2042 unsigned char buf[4];
2043
c2f09c75
TG
2044 if (bfd_seek (abfd, cmd->flavours[i].offset + 0, SEEK_SET) != 0
2045 || bfd_bread (buf, 4, abfd) != 4)
3af9a47b
NC
2046 return -1;
2047
2048 abfd->start_address = bfd_h_get_32 (abfd, buf);
2049 }
1e8a024a
TG
2050 else if ((mdata->header.cputype == BFD_MACH_O_CPU_TYPE_POWERPC_64)
2051 && (cmd->flavours[i].flavour == BFD_MACH_O_PPC_THREAD_STATE_64))
2052 {
2053 unsigned char buf[8];
2054
c2f09c75
TG
2055 if (bfd_seek (abfd, cmd->flavours[i].offset + 0, SEEK_SET) != 0
2056 || bfd_bread (buf, 8, abfd) != 8)
1e8a024a
TG
2057 return -1;
2058
2059 abfd->start_address = bfd_h_get_64 (abfd, buf);
2060 }
2061 else if ((mdata->header.cputype == BFD_MACH_O_CPU_TYPE_X86_64)
2062 && (cmd->flavours[i].flavour == BFD_MACH_O_x86_THREAD_STATE64))
2063 {
2064 unsigned char buf[8];
2065
c2f09c75
TG
2066 if (bfd_seek (abfd, cmd->flavours[i].offset + (16 * 8), SEEK_SET) != 0
2067 || bfd_bread (buf, 8, abfd) != 8)
1e8a024a
TG
2068 return -1;
2069
2070 abfd->start_address = bfd_h_get_64 (abfd, buf);
2071 }
3af9a47b
NC
2072 }
2073
2074 return 0;
2075}
2076
2077int
116c20d2
NC
2078bfd_mach_o_scan (bfd *abfd,
2079 bfd_mach_o_header *header,
2080 bfd_mach_o_data_struct *mdata)
3af9a47b
NC
2081{
2082 unsigned int i;
3af9a47b
NC
2083 enum bfd_architecture cputype;
2084 unsigned long cpusubtype;
1e8a024a
TG
2085 unsigned int hdrsize;
2086
c2f09c75 2087 hdrsize = mach_o_wide_p (header) ?
154a1ee5 2088 BFD_MACH_O_HEADER_64_SIZE : BFD_MACH_O_HEADER_SIZE;
3af9a47b 2089
3af9a47b
NC
2090 mdata->header = *header;
2091 mdata->symbols = NULL;
2092
154a1ee5 2093 abfd->flags = abfd->flags & BFD_IN_MEMORY;
15e1c58a
TG
2094 switch (header->filetype)
2095 {
2096 case BFD_MACH_O_MH_OBJECT:
2097 abfd->flags |= HAS_RELOC;
2098 break;
2099 case BFD_MACH_O_MH_EXECUTE:
2100 abfd->flags |= EXEC_P;
2101 break;
2102 case BFD_MACH_O_MH_DYLIB:
2103 case BFD_MACH_O_MH_BUNDLE:
2104 abfd->flags |= DYNAMIC;
2105 break;
2106 }
2107
3af9a47b
NC
2108 abfd->tdata.mach_o_data = mdata;
2109
e84d6fca
AM
2110 bfd_mach_o_convert_architecture (header->cputype, header->cpusubtype,
2111 &cputype, &cpusubtype);
3af9a47b
NC
2112 if (cputype == bfd_arch_unknown)
2113 {
2114 fprintf (stderr, "bfd_mach_o_scan: unknown architecture 0x%lx/0x%lx\n",
2115 header->cputype, header->cpusubtype);
2116 return -1;
2117 }
2118
2119 bfd_set_arch_mach (abfd, cputype, cpusubtype);
a95a4550 2120
3af9a47b
NC
2121 if (header->ncmds != 0)
2122 {
116c20d2 2123 mdata->commands = bfd_alloc (abfd, header->ncmds * sizeof (bfd_mach_o_load_command));
3af9a47b
NC
2124 if (mdata->commands == NULL)
2125 return -1;
a95a4550 2126
3af9a47b
NC
2127 for (i = 0; i < header->ncmds; i++)
2128 {
2129 bfd_mach_o_load_command *cur = &mdata->commands[i];
2130
2131 if (i == 0)
1e8a024a 2132 cur->offset = hdrsize;
3af9a47b
NC
2133 else
2134 {
2135 bfd_mach_o_load_command *prev = &mdata->commands[i - 1];
2136 cur->offset = prev->offset + prev->len;
2137 }
2138
2139 if (bfd_mach_o_scan_read_command (abfd, cur) < 0)
2140 return -1;
a95a4550 2141 }
3af9a47b
NC
2142 }
2143
2144 if (bfd_mach_o_scan_start_address (abfd) < 0)
7e3102a7 2145 return -1;
3af9a47b
NC
2146
2147 bfd_mach_o_flatten_sections (abfd);
3af9a47b
NC
2148 return 0;
2149}
2150
b34976b6 2151bfd_boolean
154a1ee5 2152bfd_mach_o_mkobject_init (bfd *abfd)
3af9a47b
NC
2153{
2154 bfd_mach_o_data_struct *mdata = NULL;
2155
116c20d2 2156 mdata = bfd_alloc (abfd, sizeof (bfd_mach_o_data_struct));
3af9a47b 2157 if (mdata == NULL)
b34976b6 2158 return FALSE;
3af9a47b
NC
2159 abfd->tdata.mach_o_data = mdata;
2160
2161 mdata->header.magic = 0;
2162 mdata->header.cputype = 0;
2163 mdata->header.cpusubtype = 0;
2164 mdata->header.filetype = 0;
2165 mdata->header.ncmds = 0;
2166 mdata->header.sizeofcmds = 0;
2167 mdata->header.flags = 0;
2168 mdata->header.byteorder = BFD_ENDIAN_UNKNOWN;
2169 mdata->commands = NULL;
2170 mdata->nsymbols = 0;
2171 mdata->symbols = NULL;
2172 mdata->nsects = 0;
2173 mdata->sections = NULL;
2174 mdata->ibfd = NULL;
2175
b34976b6 2176 return TRUE;
3af9a47b
NC
2177}
2178
2179const bfd_target *
154a1ee5
TG
2180bfd_mach_o_header_p (bfd *abfd,
2181 bfd_mach_o_filetype filetype,
2182 bfd_mach_o_cpu_type cputype)
3af9a47b 2183{
e84d6fca 2184 struct bfd_preserve preserve;
3af9a47b
NC
2185 bfd_mach_o_header header;
2186
e84d6fca 2187 preserve.marker = NULL;
154a1ee5 2188 if (!bfd_mach_o_read_header (abfd, &header))
e84d6fca 2189 goto wrong;
3af9a47b 2190
e84d6fca
AM
2191 if (! (header.byteorder == BFD_ENDIAN_BIG
2192 || header.byteorder == BFD_ENDIAN_LITTLE))
3af9a47b 2193 {
e84d6fca 2194 fprintf (stderr, "unknown header byte-order value 0x%lx\n",
0af1713e 2195 (unsigned long) header.byteorder);
e84d6fca 2196 goto wrong;
3af9a47b
NC
2197 }
2198
e84d6fca
AM
2199 if (! ((header.byteorder == BFD_ENDIAN_BIG
2200 && abfd->xvec->byteorder == BFD_ENDIAN_BIG
2201 && abfd->xvec->header_byteorder == BFD_ENDIAN_BIG)
2202 || (header.byteorder == BFD_ENDIAN_LITTLE
2203 && abfd->xvec->byteorder == BFD_ENDIAN_LITTLE
2204 && abfd->xvec->header_byteorder == BFD_ENDIAN_LITTLE)))
2205 goto wrong;
3af9a47b 2206
154a1ee5
TG
2207 /* Check cputype and filetype.
2208 In case of wildcard, do not accept magics that are handled by existing
2209 targets. */
2210 if (cputype)
2211 {
2212 if (header.cputype != cputype)
2213 goto wrong;
2214 }
2215 else
2216 {
2217 switch (header.cputype)
2218 {
2219 case BFD_MACH_O_CPU_TYPE_I386:
2220 /* Handled by mach-o-i386 */
2221 goto wrong;
2222 default:
2223 break;
2224 }
2225 }
2226 if (filetype)
2227 {
2228 if (header.filetype != filetype)
2229 goto wrong;
2230 }
2231 else
2232 {
2233 switch (header.filetype)
2234 {
2235 case BFD_MACH_O_MH_CORE:
2236 /* Handled by core_p */
2237 goto wrong;
2238 default:
2239 break;
2240 }
2241 }
2242
e84d6fca
AM
2243 preserve.marker = bfd_zalloc (abfd, sizeof (bfd_mach_o_data_struct));
2244 if (preserve.marker == NULL
2245 || !bfd_preserve_save (abfd, &preserve))
2246 goto fail;
3af9a47b 2247
e84d6fca
AM
2248 if (bfd_mach_o_scan (abfd, &header,
2249 (bfd_mach_o_data_struct *) preserve.marker) != 0)
2250 goto wrong;
a95a4550 2251
e84d6fca 2252 bfd_preserve_finish (abfd, &preserve);
3af9a47b 2253 return abfd->xvec;
e84d6fca
AM
2254
2255 wrong:
2256 bfd_set_error (bfd_error_wrong_format);
2257
2258 fail:
2259 if (preserve.marker != NULL)
2260 bfd_preserve_restore (abfd, &preserve);
2261 return NULL;
3af9a47b
NC
2262}
2263
154a1ee5
TG
2264static const bfd_target *
2265bfd_mach_o_gen_object_p (bfd *abfd)
3af9a47b 2266{
154a1ee5
TG
2267 return bfd_mach_o_header_p (abfd, 0, 0);
2268}
e84d6fca 2269
154a1ee5
TG
2270static const bfd_target *
2271bfd_mach_o_gen_core_p (bfd *abfd)
2272{
2273 return bfd_mach_o_header_p (abfd, BFD_MACH_O_MH_CORE, 0);
3af9a47b
NC
2274}
2275
2276typedef struct mach_o_fat_archentry
2277{
2278 unsigned long cputype;
2279 unsigned long cpusubtype;
2280 unsigned long offset;
2281 unsigned long size;
2282 unsigned long align;
3af9a47b
NC
2283} mach_o_fat_archentry;
2284
2285typedef struct mach_o_fat_data_struct
2286{
2287 unsigned long magic;
2288 unsigned long nfat_arch;
2289 mach_o_fat_archentry *archentries;
2290} mach_o_fat_data_struct;
2291
2292const bfd_target *
116c20d2 2293bfd_mach_o_archive_p (bfd *abfd)
3af9a47b 2294{
e84d6fca 2295 mach_o_fat_data_struct *adata = NULL;
3af9a47b
NC
2296 unsigned char buf[20];
2297 unsigned long i;
2298
c2f09c75
TG
2299 if (bfd_seek (abfd, 0, SEEK_SET) != 0
2300 || bfd_bread ((PTR) buf, 8, abfd) != 8)
e84d6fca 2301 goto error;
3af9a47b 2302
116c20d2 2303 adata = bfd_alloc (abfd, sizeof (mach_o_fat_data_struct));
3af9a47b 2304 if (adata == NULL)
e84d6fca 2305 goto error;
a95a4550 2306
3af9a47b
NC
2307 adata->magic = bfd_getb32 (buf);
2308 adata->nfat_arch = bfd_getb32 (buf + 4);
2309 if (adata->magic != 0xcafebabe)
e84d6fca 2310 goto error;
27cc28f9
AS
2311 /* Avoid matching Java bytecode files, which have the same magic number.
2312 In the Java bytecode file format this field contains the JVM version,
2313 which starts at 43.0. */
2314 if (adata->nfat_arch > 30)
2315 goto error;
3af9a47b 2316
c2f09c75 2317 adata->archentries =
3af9a47b
NC
2318 bfd_alloc (abfd, adata->nfat_arch * sizeof (mach_o_fat_archentry));
2319 if (adata->archentries == NULL)
e84d6fca 2320 goto error;
3af9a47b
NC
2321
2322 for (i = 0; i < adata->nfat_arch; i++)
2323 {
c2f09c75
TG
2324 if (bfd_seek (abfd, 8 + 20 * i, SEEK_SET) != 0
2325 || bfd_bread ((PTR) buf, 20, abfd) != 20)
e84d6fca 2326 goto error;
3af9a47b
NC
2327 adata->archentries[i].cputype = bfd_getb32 (buf);
2328 adata->archentries[i].cpusubtype = bfd_getb32 (buf + 4);
2329 adata->archentries[i].offset = bfd_getb32 (buf + 8);
2330 adata->archentries[i].size = bfd_getb32 (buf + 12);
2331 adata->archentries[i].align = bfd_getb32 (buf + 16);
3af9a47b
NC
2332 }
2333
2334 abfd->tdata.mach_o_fat_data = adata;
2335 return abfd->xvec;
e84d6fca
AM
2336
2337 error:
2338 if (adata != NULL)
2339 bfd_release (abfd, adata);
2340 bfd_set_error (bfd_error_wrong_format);
2341 return NULL;
3af9a47b
NC
2342}
2343
2344bfd *
116c20d2 2345bfd_mach_o_openr_next_archived_file (bfd *archive, bfd *prev)
3af9a47b 2346{
e84d6fca 2347 mach_o_fat_data_struct *adata;
3af9a47b
NC
2348 mach_o_fat_archentry *entry = NULL;
2349 unsigned long i;
15e1c58a 2350 bfd *nbfd;
15e1c58a
TG
2351 enum bfd_architecture arch_type;
2352 unsigned long arch_subtype;
3af9a47b 2353
e84d6fca 2354 adata = (mach_o_fat_data_struct *) archive->tdata.mach_o_fat_data;
3af9a47b
NC
2355 BFD_ASSERT (adata != NULL);
2356
2357 /* Find index of previous entry. */
2358 if (prev == NULL)
2359 i = 0; /* Start at first one. */
2360 else
2361 {
2362 for (i = 0; i < adata->nfat_arch; i++)
2363 {
15e1c58a 2364 if (adata->archentries[i].offset == prev->origin)
3af9a47b
NC
2365 break;
2366 }
2367
2368 if (i == adata->nfat_arch)
2369 {
2370 /* Not found. */
2371 bfd_set_error (bfd_error_bad_value);
a95a4550 2372 return NULL;
3af9a47b
NC
2373 }
2374 i++; /* Get next entry. */
2375 }
a95a4550 2376
3af9a47b
NC
2377 if (i >= adata->nfat_arch)
2378 {
2379 bfd_set_error (bfd_error_no_more_archived_files);
2380 return NULL;
2381 }
2382
2383 entry = &adata->archentries[i];
15e1c58a
TG
2384 nbfd = _bfd_new_bfd_contained_in (archive);
2385 if (nbfd == NULL)
2386 return NULL;
2387
2388 nbfd->origin = entry->offset;
2389
2390 bfd_mach_o_convert_architecture (entry->cputype, entry->cpusubtype,
2391 &arch_type, &arch_subtype);
846b9259
TG
2392 /* Create the member filename.
2393 Use FILENAME:ARCH_NAME. */
2394 {
2395 char *s = NULL;
2396 const char *arch_name;
2397 size_t arch_file_len = strlen (bfd_get_filename (archive));
2398
2399 arch_name = bfd_printable_arch_mach (arch_type, arch_subtype);
2400 s = bfd_malloc (arch_file_len + 1 + strlen (arch_name) + 1);
2401 if (s == NULL)
2402 return NULL;
2403 memcpy (s, bfd_get_filename (archive), arch_file_len);
2404 s[arch_file_len] = ':';
2405 strcpy (s + arch_file_len + 1, arch_name);
2406 nbfd->filename = s;
2407 }
15e1c58a 2408 nbfd->iostream = NULL;
846b9259 2409 bfd_set_arch_mach (nbfd, arch_type, arch_subtype);
3af9a47b 2410
15e1c58a 2411 return nbfd;
3af9a47b
NC
2412}
2413
846b9259
TG
2414/* If ABFD format is FORMAT and architecture is ARCH, return it.
2415 If ABFD is a fat image containing a member that corresponds to FORMAT
2416 and ARCH, returns it.
2417 In other case, returns NULL.
2418 This function allows transparent uses of fat images. */
2419bfd *
2420bfd_mach_o_fat_extract (bfd *abfd,
2421 bfd_format format,
2422 const bfd_arch_info_type *arch)
2423{
2424 bfd *res;
2425 mach_o_fat_data_struct *adata;
2426 unsigned int i;
2427
2428 if (bfd_check_format (abfd, format))
2429 {
2430 if (bfd_get_arch_info (abfd) == arch)
2431 return abfd;
2432 return NULL;
2433 }
2434 if (!bfd_check_format (abfd, bfd_archive)
2435 || abfd->xvec != &mach_o_fat_vec)
2436 return NULL;
c2f09c75 2437
846b9259
TG
2438 /* This is a Mach-O fat image. */
2439 adata = (mach_o_fat_data_struct *) abfd->tdata.mach_o_fat_data;
2440 BFD_ASSERT (adata != NULL);
2441
2442 for (i = 0; i < adata->nfat_arch; i++)
2443 {
2444 struct mach_o_fat_archentry *e = &adata->archentries[i];
2445 enum bfd_architecture cpu_type;
2446 unsigned long cpu_subtype;
2447
2448 bfd_mach_o_convert_architecture (e->cputype, e->cpusubtype,
2449 &cpu_type, &cpu_subtype);
2450 if (cpu_type != arch->arch || cpu_subtype != arch->mach)
2451 continue;
2452
2453 /* The architecture is found. */
2454 res = _bfd_new_bfd_contained_in (abfd);
2455 if (res == NULL)
2456 return NULL;
2457
2458 res->origin = e->offset;
2459
2460 res->filename = strdup (abfd->filename);
2461 res->iostream = NULL;
2462
2463 if (bfd_check_format (res, format))
2464 {
2465 BFD_ASSERT (bfd_get_arch_info (res) == arch);
2466 return res;
2467 }
2468 bfd_close (res);
2469 return NULL;
2470 }
2471
2472 return NULL;
2473}
2474
e84d6fca 2475int
116c20d2
NC
2476bfd_mach_o_lookup_section (bfd *abfd,
2477 asection *section,
2478 bfd_mach_o_load_command **mcommand,
2479 bfd_mach_o_section **msection)
3af9a47b
NC
2480{
2481 struct mach_o_data_struct *md = abfd->tdata.mach_o_data;
2482 unsigned int i, j, num;
2483
2484 bfd_mach_o_load_command *ncmd = NULL;
2485 bfd_mach_o_section *nsect = NULL;
2486
2487 BFD_ASSERT (mcommand != NULL);
2488 BFD_ASSERT (msection != NULL);
2489
2490 num = 0;
2491 for (i = 0; i < md->header.ncmds; i++)
2492 {
2493 struct bfd_mach_o_load_command *cmd = &md->commands[i];
2494 struct bfd_mach_o_segment_command *seg = NULL;
2495
1e8a024a
TG
2496 if (cmd->type != BFD_MACH_O_LC_SEGMENT
2497 || cmd->type != BFD_MACH_O_LC_SEGMENT_64)
3af9a47b
NC
2498 continue;
2499 seg = &cmd->command.segment;
a95a4550 2500
3af9a47b
NC
2501 if (seg->segment == section)
2502 {
2503 if (num == 0)
2504 ncmd = cmd;
2505 num++;
2506 }
2507
2508 for (j = 0; j < seg->nsects; j++)
2509 {
2510 struct bfd_mach_o_section *sect = &seg->sections[j];
2511
2512 if (sect->bfdsection == section)
2513 {
2514 if (num == 0)
2515 nsect = sect;
2516 num++;
2517 }
2518 }
2519 }
a95a4550 2520
3af9a47b
NC
2521 *mcommand = ncmd;
2522 *msection = nsect;
2523 return num;
2524}
2525
2526int
116c20d2
NC
2527bfd_mach_o_lookup_command (bfd *abfd,
2528 bfd_mach_o_load_command_type type,
2529 bfd_mach_o_load_command **mcommand)
3af9a47b
NC
2530{
2531 struct mach_o_data_struct *md = NULL;
2532 bfd_mach_o_load_command *ncmd = NULL;
2533 unsigned int i, num;
2534
2535 md = abfd->tdata.mach_o_data;
2536
2537 BFD_ASSERT (md != NULL);
2538 BFD_ASSERT (mcommand != NULL);
2539
2540 num = 0;
2541 for (i = 0; i < md->header.ncmds; i++)
2542 {
2543 struct bfd_mach_o_load_command *cmd = &md->commands[i];
2544
2545 if (cmd->type != type)
2546 continue;
2547
2548 if (num == 0)
2549 ncmd = cmd;
2550 num++;
2551 }
2552
2553 *mcommand = ncmd;
2554 return num;
2555}
2556
2557unsigned long
116c20d2 2558bfd_mach_o_stack_addr (enum bfd_mach_o_cpu_type type)
3af9a47b
NC
2559{
2560 switch (type)
2561 {
2562 case BFD_MACH_O_CPU_TYPE_MC680x0:
2563 return 0x04000000;
2564 case BFD_MACH_O_CPU_TYPE_MC88000:
2565 return 0xffffe000;
2566 case BFD_MACH_O_CPU_TYPE_POWERPC:
2567 return 0xc0000000;
2568 case BFD_MACH_O_CPU_TYPE_I386:
2569 return 0xc0000000;
2570 case BFD_MACH_O_CPU_TYPE_SPARC:
2571 return 0xf0000000;
2572 case BFD_MACH_O_CPU_TYPE_I860:
2573 return 0;
2574 case BFD_MACH_O_CPU_TYPE_HPPA:
e84d6fca 2575 return 0xc0000000 - 0x04000000;
3af9a47b
NC
2576 default:
2577 return 0;
2578 }
2579}
2580
154a1ee5 2581bfd_boolean
15e1c58a
TG
2582bfd_mach_o_bfd_print_private_bfd_data (bfd *abfd, PTR ptr)
2583{
2584 bfd_mach_o_data_struct *mdata = abfd->tdata.mach_o_data;
2585 FILE *file = (FILE *) ptr;
2586 unsigned int i, j;
2587 unsigned int sec_nbr = 0;
2588
2589 fprintf (file, _("Segments and Sections:\n"));
2590 fprintf (file, _(" #: Segment name Section name Address\n"));
2591
2592 for (i = 0; i < mdata->header.ncmds; i++)
2593 {
2594 bfd_mach_o_segment_command *seg;
2595
2596 if (mdata->commands[i].type != BFD_MACH_O_LC_SEGMENT
2597 && mdata->commands[i].type != BFD_MACH_O_LC_SEGMENT_64)
2598 continue;
2599
2600 seg = &mdata->commands[i].command.segment;
2601
2602 fprintf (file, "[Segment %-16s ", seg->segname);
2603 fprintf_vma (file, seg->vmaddr);
2604 fprintf (file, "-");
2605 fprintf_vma (file, seg->vmaddr + seg->vmsize - 1);
2606 fputc (' ', file);
2607 fputc (seg->initprot & BFD_MACH_O_PROT_READ ? 'r' : '-', file);
2608 fputc (seg->initprot & BFD_MACH_O_PROT_WRITE ? 'w' : '-', file);
2609 fputc (seg->initprot & BFD_MACH_O_PROT_EXECUTE ? 'x' : '-', file);
2610 fprintf (file, "]\n");
2611 for (j = 0; j < seg->nsects; j++)
2612 {
2613 bfd_mach_o_section *sec = &seg->sections[j];
2614 fprintf (file, "%02u: %-16s %-16s ", ++sec_nbr,
2615 sec->segname, sec->sectname);
2616 fprintf_vma (file, sec->addr);
2617 fprintf (file, " ");
2618 fprintf_vma (file, sec->size);
2619 fprintf (file, " %08lx\n", sec->flags);
2620 }
2621 }
2622
2623 for (i = 0; i < mdata->header.ncmds; i++)
2624 {
2625 bfd_mach_o_load_command *cmd = &mdata->commands[i];
2626
2627 switch (cmd->type)
2628 {
2629 case BFD_MACH_O_LC_SEGMENT:
2630 case BFD_MACH_O_LC_SEGMENT_64:
2631 break;
2632 case BFD_MACH_O_LC_UUID:
2633 {
2634 bfd_mach_o_uuid_command *uuid = &cmd->command.uuid;
2635 unsigned int i;
2636
2637 fprintf (file, "\n"
2638 "UUID:");
2639 for (i = 0; i < sizeof (uuid->uuid); i++)
2640 fprintf (file, " %02x", uuid->uuid[i]);
2641 fputc ('\n', file);
2642 }
2643 break;
2644 case BFD_MACH_O_LC_LOAD_DYLIB:
2645 {
2646 bfd_mach_o_dylib_command *dylib = &cmd->command.dylib;
2647 bfd_byte *data = NULL;
2648
2649 if (! bfd_malloc_and_get_section (abfd, dylib->section, &data))
2650 {
2651 if (data != NULL)
2652 free (data);
2653 break;
2654 }
2655 fprintf (file, "\n"
2656 "LOAD_DYLIB: %s\n",
2657 data + dylib->name_offset - cmd->offset - 8);
2658 fprintf (file, " time stamp: 0x%08lx\n",
2659 dylib->timestamp);
2660 fprintf (file, " current version: 0x%08lx\n",
2661 dylib->current_version);
2662 fprintf (file, " comptibility version: 0x%08lx\n",
2663 dylib->compatibility_version);
2664 free (data);
2665 break;
2666 }
2667 case BFD_MACH_O_LC_LOAD_DYLINKER:
2668 {
2669 bfd_mach_o_dylinker_command *linker = &cmd->command.dylinker;
2670 bfd_byte *data = NULL;
2671
2672 if (! bfd_malloc_and_get_section (abfd, linker->section, &data))
2673 {
2674 if (data != NULL)
2675 free (data);
2676 break;
2677 }
2678 fprintf (file, "\n"
2679 "LOAD_DYLINKER: %s\n",
2680 data + linker->name_offset - cmd->offset - 8);
2681 free (data);
2682 break;
2683 }
2684 case BFD_MACH_O_LC_SYMTAB:
2685 {
2686 bfd_mach_o_symtab_command *symtab = &cmd->command.symtab;
2687 fprintf (file, "\n"
2688 "LC_SYMTAB: nsyms: %lu, strsize: %lu\n",
2689 symtab->nsyms, symtab->strsize);
2690 break;
2691 }
2692 case BFD_MACH_O_LC_DYSYMTAB:
2693 {
2694 bfd_mach_o_dysymtab_command *dysymtab = &cmd->command.dysymtab;
2695 fprintf (file, "\n"
2696 "LC_DYSYMTAB:\n"
2697 " local symbols: index: %lu number: %lu\n",
2698 dysymtab->ilocalsym, dysymtab->nlocalsym);
2699 fprintf (file,
2700 " external symbols: index: %lu number: %lu\n",
2701 dysymtab->iextdefsym, dysymtab->nextdefsym);
2702 fprintf (file,
2703 " undefined symbols: index: %lu number: %lu\n",
2704 dysymtab->iundefsym, dysymtab->nundefsym);
2705 fprintf (file,
2706 " ntoc: offset: %lu number: %lu\n",
2707 dysymtab->tocoff, dysymtab->ntoc);
2708 fprintf (file,
2709 " module table: offset: %lu number: %lu\n",
2710 dysymtab->modtaboff, dysymtab->nmodtab);
2711 break;
2712 }
2713 default:
2714 fprintf (file, "LC_%d\n", cmd->type);
2715 break;
2716 }
2717 }
2718
2719 return TRUE;
2720}
2721
3af9a47b 2722int
116c20d2
NC
2723bfd_mach_o_core_fetch_environment (bfd *abfd,
2724 unsigned char **rbuf,
2725 unsigned int *rlen)
3af9a47b
NC
2726{
2727 bfd_mach_o_data_struct *mdata = abfd->tdata.mach_o_data;
2728 unsigned long stackaddr = bfd_mach_o_stack_addr (mdata->header.cputype);
2729 unsigned int i = 0;
2730
2731 for (i = 0; i < mdata->header.ncmds; i++)
2732 {
2733 bfd_mach_o_load_command *cur = &mdata->commands[i];
2734 bfd_mach_o_segment_command *seg = NULL;
2735
2736 if (cur->type != BFD_MACH_O_LC_SEGMENT)
2737 continue;
2738
2739 seg = &cur->command.segment;
2740
2741 if ((seg->vmaddr + seg->vmsize) == stackaddr)
2742 {
2743 unsigned long start = seg->fileoff;
2744 unsigned long end = seg->fileoff + seg->filesize;
2745 unsigned char *buf = bfd_malloc (1024);
2746 unsigned long size = 1024;
2747
2748 for (;;)
2749 {
2750 bfd_size_type nread = 0;
2751 unsigned long offset;
2752 int found_nonnull = 0;
2753
2754 if (size > (end - start))
2755 size = (end - start);
2756
515ef31d
NC
2757 buf = bfd_realloc_or_free (buf, size);
2758 if (buf == NULL)
2759 return -1;
c2f09c75
TG
2760
2761 if (bfd_seek (abfd, end - size, SEEK_SET) != 0)
2762 {
2763 free (buf);
2764 return -1;
2765 }
2766
3af9a47b 2767 nread = bfd_bread (buf, size, abfd);
a95a4550 2768
3af9a47b 2769 if (nread != size)
515ef31d
NC
2770 {
2771 free (buf);
2772 return -1;
2773 }
a95a4550 2774
3af9a47b
NC
2775 for (offset = 4; offset <= size; offset += 4)
2776 {
e84d6fca 2777 unsigned long val;
3af9a47b 2778
e84d6fca 2779 val = *((unsigned long *) (buf + size - offset));
3af9a47b
NC
2780 if (! found_nonnull)
2781 {
2782 if (val != 0)
2783 found_nonnull = 1;
2784 }
2785 else if (val == 0x0)
2786 {
e84d6fca
AM
2787 unsigned long bottom;
2788 unsigned long top;
3af9a47b 2789
e84d6fca
AM
2790 bottom = seg->fileoff + seg->filesize - offset;
2791 top = seg->fileoff + seg->filesize - 4;
3af9a47b
NC
2792 *rbuf = bfd_malloc (top - bottom);
2793 *rlen = top - bottom;
2794
2795 memcpy (*rbuf, buf + size - *rlen, *rlen);
515ef31d 2796 free (buf);
3af9a47b
NC
2797 return 0;
2798 }
2799 }
2800
2801 if (size == (end - start))
2802 break;
2803
2804 size *= 2;
2805 }
515ef31d
NC
2806
2807 free (buf);
3af9a47b
NC
2808 }
2809 }
2810
2811 return -1;
2812}
2813
2814char *
116c20d2 2815bfd_mach_o_core_file_failing_command (bfd *abfd)
3af9a47b
NC
2816{
2817 unsigned char *buf = NULL;
2818 unsigned int len = 0;
2819 int ret = -1;
2820
2821 ret = bfd_mach_o_core_fetch_environment (abfd, &buf, &len);
2822 if (ret < 0)
2823 return NULL;
2824
f075ee0c 2825 return (char *) buf;
3af9a47b
NC
2826}
2827
2828int
116c20d2 2829bfd_mach_o_core_file_failing_signal (bfd *abfd ATTRIBUTE_UNUSED)
3af9a47b
NC
2830{
2831 return 0;
2832}
2833
116c20d2
NC
2834#define TARGET_NAME mach_o_be_vec
2835#define TARGET_STRING "mach-o-be"
2836#define TARGET_BIG_ENDIAN 1
2837#define TARGET_ARCHIVE 0
3af9a47b
NC
2838
2839#include "mach-o-target.c"
2840
2841#undef TARGET_NAME
2842#undef TARGET_STRING
2843#undef TARGET_BIG_ENDIAN
2844#undef TARGET_ARCHIVE
2845
116c20d2
NC
2846#define TARGET_NAME mach_o_le_vec
2847#define TARGET_STRING "mach-o-le"
2848#define TARGET_BIG_ENDIAN 0
2849#define TARGET_ARCHIVE 0
3af9a47b
NC
2850
2851#include "mach-o-target.c"
2852
2853#undef TARGET_NAME
2854#undef TARGET_STRING
2855#undef TARGET_BIG_ENDIAN
2856#undef TARGET_ARCHIVE
2857
116c20d2
NC
2858#define TARGET_NAME mach_o_fat_vec
2859#define TARGET_STRING "mach-o-fat"
2860#define TARGET_BIG_ENDIAN 1
2861#define TARGET_ARCHIVE 1
3af9a47b
NC
2862
2863#include "mach-o-target.c"
2864
2865#undef TARGET_NAME
2866#undef TARGET_STRING
2867#undef TARGET_BIG_ENDIAN
2868#undef TARGET_ARCHIVE
This page took 0.542879 seconds and 4 git commands to generate.