1 /* Mach-O support for BFD.
2    Copyright 1999, 2000, 2001, 2002, 2003, 2004, 2005
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
9    the Free Software Foundation; either version 2 of the License, or
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
18    along with this program; if not, write to the Free Software
19    Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA.  */
20 
21 #include "mach-o.h"
22 #include "bfd.h"
23 #include "sysdep.h"
24 #include "libbfd.h"
25 #include "libiberty.h"
26 #include <ctype.h>
27 
28 #ifndef BFD_IO_FUNCS
29 #define BFD_IO_FUNCS 0
30 #endif
31 
32 #define bfd_mach_o_mkarchive                          _bfd_noarchive_mkarchive
33 #define bfd_mach_o_read_ar_hdr                        _bfd_noarchive_read_ar_hdr
34 #define bfd_mach_o_slurp_armap                        _bfd_noarchive_slurp_armap
35 #define bfd_mach_o_slurp_extended_name_table          _bfd_noarchive_slurp_extended_name_table
36 #define bfd_mach_o_construct_extended_name_table      _bfd_noarchive_construct_extended_name_table
37 #define bfd_mach_o_truncate_arname                    _bfd_noarchive_truncate_arname
38 #define bfd_mach_o_write_armap                        _bfd_noarchive_write_armap
39 #define bfd_mach_o_get_elt_at_index                   _bfd_noarchive_get_elt_at_index
40 #define bfd_mach_o_generic_stat_arch_elt              _bfd_noarchive_generic_stat_arch_elt
41 #define bfd_mach_o_update_armap_timestamp             _bfd_noarchive_update_armap_timestamp
42 #define	bfd_mach_o_close_and_cleanup                  _bfd_generic_close_and_cleanup
43 #define bfd_mach_o_bfd_free_cached_info               _bfd_generic_bfd_free_cached_info
44 #define bfd_mach_o_new_section_hook                   _bfd_generic_new_section_hook
45 #define bfd_mach_o_get_section_contents_in_window     _bfd_generic_get_section_contents_in_window
46 #define bfd_mach_o_bfd_is_local_label_name            _bfd_nosymbols_bfd_is_local_label_name
47 #define bfd_mach_o_bfd_is_target_special_symbol       ((bfd_boolean (*) (bfd *, asymbol *)) bfd_false)
48 #define bfd_mach_o_bfd_is_local_label_name            _bfd_nosymbols_bfd_is_local_label_name
49 #define bfd_mach_o_get_lineno                         _bfd_nosymbols_get_lineno
50 #define bfd_mach_o_find_nearest_line                  _bfd_nosymbols_find_nearest_line
51 #define bfd_mach_o_find_inliner_info                  _bfd_nosymbols_find_inliner_info
52 #define bfd_mach_o_bfd_make_debug_symbol              _bfd_nosymbols_bfd_make_debug_symbol
53 #define bfd_mach_o_read_minisymbols                   _bfd_generic_read_minisymbols
54 #define bfd_mach_o_minisymbol_to_symbol               _bfd_generic_minisymbol_to_symbol
55 #define bfd_mach_o_get_reloc_upper_bound              _bfd_norelocs_get_reloc_upper_bound
56 #define bfd_mach_o_canonicalize_reloc                 _bfd_norelocs_canonicalize_reloc
57 #define bfd_mach_o_bfd_reloc_type_lookup              _bfd_norelocs_bfd_reloc_type_lookup
58 #define bfd_mach_o_bfd_get_relocated_section_contents bfd_generic_get_relocated_section_contents
59 #define bfd_mach_o_bfd_relax_section                  bfd_generic_relax_section
60 #define bfd_mach_o_bfd_link_hash_table_create         _bfd_generic_link_hash_table_create
61 #define bfd_mach_o_bfd_link_hash_table_free           _bfd_generic_link_hash_table_free
62 #define bfd_mach_o_bfd_link_add_symbols               _bfd_generic_link_add_symbols
63 #define bfd_mach_o_bfd_link_just_syms                 _bfd_generic_link_just_syms
64 #define bfd_mach_o_bfd_final_link                     _bfd_generic_final_link
65 #define bfd_mach_o_bfd_link_split_section             _bfd_generic_link_split_section
66 #define bfd_mach_o_set_arch_mach                      bfd_default_set_arch_mach
67 #define bfd_mach_o_bfd_merge_private_bfd_data         _bfd_generic_bfd_merge_private_bfd_data
68 #define bfd_mach_o_bfd_set_private_flags              _bfd_generic_bfd_set_private_flags
69 #define bfd_mach_o_bfd_print_private_bfd_data         _bfd_generic_bfd_print_private_bfd_data
70 #define bfd_mach_o_get_section_contents               _bfd_generic_get_section_contents
71 #define bfd_mach_o_set_section_contents               _bfd_generic_set_section_contents
72 #define bfd_mach_o_bfd_gc_sections                    bfd_generic_gc_sections
73 #define bfd_mach_o_bfd_merge_sections                 bfd_generic_merge_sections
74 #define bfd_mach_o_bfd_is_group_section               bfd_generic_is_group_section
75 #define bfd_mach_o_bfd_discard_group                  bfd_generic_discard_group
76 #define bfd_mach_o_section_already_linked             _bfd_generic_section_already_linked
77 #define bfd_mach_o_bfd_copy_private_header_data       _bfd_generic_bfd_copy_private_header_data
78 
79 
80 /* The flags field of a section structure is separated into two parts a section
81    type and section attributes.  The section types are mutually exclusive (it
82    can only have one type) but the section attributes are not (it may have more
83    than one attribute).  */
84 
85 #define SECTION_TYPE             0x000000ff     /* 256 section types.  */
86 #define SECTION_ATTRIBUTES       0xffffff00     /*  24 section attributes.  */
87 
88 /* Constants for the section attributes part of the flags field of a section
89    structure.  */
90 
91 #define SECTION_ATTRIBUTES_USR   0xff000000     /* User-settable attributes.  */
92 #define S_ATTR_PURE_INSTRUCTIONS 0x80000000     /* Section contains only true machine instructions.  */
93 #define SECTION_ATTRIBUTES_SYS   0x00ffff00     /* System setable attributes.  */
94 #define S_ATTR_SOME_INSTRUCTIONS 0x00000400     /* Section contains some machine instructions.  */
95 #define S_ATTR_EXT_RELOC         0x00000200     /* Section has external relocation entries.  */
96 #define S_ATTR_LOC_RELOC         0x00000100     /* Section has local relocation entries.  */
97 
98 #define N_STAB 0xe0
99 #define N_TYPE 0x1e
100 #define N_EXT  0x01
101 #define N_UNDF 0x0
102 #define N_ABS  0x2
103 #define N_SECT 0xe
104 #define N_INDR 0xa
105 
106 bfd_boolean
bfd_mach_o_valid(bfd * abfd)107 bfd_mach_o_valid (bfd *abfd)
108 {
109   if (abfd == NULL || abfd->xvec == NULL)
110     return 0;
111 
112   if (! ((abfd->xvec == &mach_o_be_vec)
113 	 || (abfd->xvec == &mach_o_le_vec)
114 	 || (abfd->xvec == &mach_o_fat_vec)))
115     return 0;
116 
117   if (abfd->tdata.mach_o_data == NULL)
118     return 0;
119   return 1;
120 }
121 
122 /* Copy any private info we understand from the input symbol
123    to the output symbol.  */
124 
125 static bfd_boolean
bfd_mach_o_bfd_copy_private_symbol_data(bfd * ibfd ATTRIBUTE_UNUSED,asymbol * isymbol ATTRIBUTE_UNUSED,bfd * obfd ATTRIBUTE_UNUSED,asymbol * osymbol ATTRIBUTE_UNUSED)126 bfd_mach_o_bfd_copy_private_symbol_data (bfd *ibfd ATTRIBUTE_UNUSED,
127 					 asymbol *isymbol ATTRIBUTE_UNUSED,
128 					 bfd *obfd ATTRIBUTE_UNUSED,
129 					 asymbol *osymbol ATTRIBUTE_UNUSED)
130 {
131   return TRUE;
132 }
133 
134 /* Copy any private info we understand from the input section
135    to the output section.  */
136 
137 static bfd_boolean
bfd_mach_o_bfd_copy_private_section_data(bfd * ibfd ATTRIBUTE_UNUSED,asection * isection ATTRIBUTE_UNUSED,bfd * obfd ATTRIBUTE_UNUSED,asection * osection ATTRIBUTE_UNUSED)138 bfd_mach_o_bfd_copy_private_section_data (bfd *ibfd ATTRIBUTE_UNUSED,
139 					  asection *isection ATTRIBUTE_UNUSED,
140 					  bfd *obfd ATTRIBUTE_UNUSED,
141 					  asection *osection ATTRIBUTE_UNUSED)
142 {
143   return TRUE;
144 }
145 
146 /* Copy any private info we understand from the input bfd
147    to the output bfd.  */
148 
149 static bfd_boolean
bfd_mach_o_bfd_copy_private_bfd_data(bfd * ibfd,bfd * obfd)150 bfd_mach_o_bfd_copy_private_bfd_data (bfd *ibfd, bfd *obfd)
151 {
152   BFD_ASSERT (bfd_mach_o_valid (ibfd));
153   BFD_ASSERT (bfd_mach_o_valid (obfd));
154 
155   obfd->tdata.mach_o_data = ibfd->tdata.mach_o_data;
156   obfd->tdata.mach_o_data->ibfd = ibfd;
157   return TRUE;
158 }
159 
160 static long
bfd_mach_o_count_symbols(bfd * abfd)161 bfd_mach_o_count_symbols (bfd *abfd)
162 {
163   bfd_mach_o_data_struct *mdata = NULL;
164   long nsyms = 0;
165   unsigned long i;
166 
167   BFD_ASSERT (bfd_mach_o_valid (abfd));
168   mdata = abfd->tdata.mach_o_data;
169 
170   for (i = 0; i < mdata->header.ncmds; i++)
171     if (mdata->commands[i].type == BFD_MACH_O_LC_SYMTAB)
172       {
173 	bfd_mach_o_symtab_command *sym = &mdata->commands[i].command.symtab;
174 	nsyms += sym->nsyms;
175       }
176 
177   return nsyms;
178 }
179 
180 static long
bfd_mach_o_get_symtab_upper_bound(bfd * abfd)181 bfd_mach_o_get_symtab_upper_bound (bfd *abfd)
182 {
183   long nsyms = bfd_mach_o_count_symbols (abfd);
184 
185   if (nsyms < 0)
186     return nsyms;
187 
188   return ((nsyms + 1) * sizeof (asymbol *));
189 }
190 
191 static long
bfd_mach_o_canonicalize_symtab(bfd * abfd,asymbol ** alocation)192 bfd_mach_o_canonicalize_symtab (bfd *abfd, asymbol **alocation)
193 {
194   bfd_mach_o_data_struct *mdata = abfd->tdata.mach_o_data;
195   long nsyms = bfd_mach_o_count_symbols (abfd);
196   asymbol **csym = alocation;
197   unsigned long i, j;
198 
199   if (nsyms < 0)
200     return nsyms;
201 
202   for (i = 0; i < mdata->header.ncmds; i++)
203     {
204       if (mdata->commands[i].type == BFD_MACH_O_LC_SYMTAB)
205 	{
206 	  bfd_mach_o_symtab_command *sym = &mdata->commands[i].command.symtab;
207 
208 	  if (bfd_mach_o_scan_read_symtab_symbols (abfd, &mdata->commands[i].command.symtab) != 0)
209 	    {
210 	      fprintf (stderr, "bfd_mach_o_canonicalize_symtab: unable to load symbols for section %lu\n", i);
211 	      return 0;
212 	    }
213 
214 	  BFD_ASSERT (sym->symbols != NULL);
215 
216 	  for (j = 0; j < sym->nsyms; j++)
217 	    {
218 	      BFD_ASSERT (csym < (alocation + nsyms));
219 	      *csym++ = &sym->symbols[j];
220 	    }
221 	}
222     }
223 
224   *csym++ = NULL;
225 
226   return nsyms;
227 }
228 
229 static void
bfd_mach_o_get_symbol_info(bfd * abfd ATTRIBUTE_UNUSED,asymbol * symbol,symbol_info * ret)230 bfd_mach_o_get_symbol_info (bfd *abfd ATTRIBUTE_UNUSED,
231 			    asymbol *symbol,
232 			    symbol_info *ret)
233 {
234   bfd_symbol_info (symbol, ret);
235 }
236 
237 static void
bfd_mach_o_print_symbol(bfd * abfd,PTR afile,asymbol * symbol,bfd_print_symbol_type how)238 bfd_mach_o_print_symbol (bfd *abfd,
239 			 PTR afile,
240 			 asymbol *symbol,
241 			 bfd_print_symbol_type how)
242 {
243   FILE *file = (FILE *) afile;
244 
245   switch (how)
246     {
247     case bfd_print_symbol_name:
248       fprintf (file, "%s", symbol->name);
249       break;
250     default:
251       bfd_print_symbol_vandf (abfd, (PTR) file, symbol);
252       fprintf (file, " %-5s %s", symbol->section->name, symbol->name);
253     }
254 }
255 
256 static void
bfd_mach_o_convert_architecture(bfd_mach_o_cpu_type mtype,bfd_mach_o_cpu_subtype msubtype ATTRIBUTE_UNUSED,enum bfd_architecture * type,unsigned long * subtype)257 bfd_mach_o_convert_architecture (bfd_mach_o_cpu_type mtype,
258 				 bfd_mach_o_cpu_subtype msubtype ATTRIBUTE_UNUSED,
259 				 enum bfd_architecture *type,
260 				 unsigned long *subtype)
261 {
262   *subtype = bfd_arch_unknown;
263 
264   switch (mtype)
265     {
266     case BFD_MACH_O_CPU_TYPE_VAX: *type = bfd_arch_vax; break;
267     case BFD_MACH_O_CPU_TYPE_MC680x0: *type = bfd_arch_m68k; break;
268     case BFD_MACH_O_CPU_TYPE_I386: *type = bfd_arch_i386; break;
269     case BFD_MACH_O_CPU_TYPE_MIPS: *type = bfd_arch_mips; break;
270     case BFD_MACH_O_CPU_TYPE_MC98000: *type = bfd_arch_m98k; break;
271     case BFD_MACH_O_CPU_TYPE_HPPA: *type = bfd_arch_hppa; break;
272     case BFD_MACH_O_CPU_TYPE_ARM: *type = bfd_arch_arm; break;
273     case BFD_MACH_O_CPU_TYPE_MC88000: *type = bfd_arch_m88k; break;
274     case BFD_MACH_O_CPU_TYPE_SPARC: *type = bfd_arch_sparc; break;
275     case BFD_MACH_O_CPU_TYPE_I860: *type = bfd_arch_i860; break;
276     case BFD_MACH_O_CPU_TYPE_ALPHA: *type = bfd_arch_alpha; break;
277     case BFD_MACH_O_CPU_TYPE_POWERPC: *type = bfd_arch_powerpc; break;
278     default: *type = bfd_arch_unknown; break;
279     }
280 
281   switch (*type)
282     {
283     case bfd_arch_i386: *subtype = bfd_mach_i386_i386; break;
284     case bfd_arch_sparc: *subtype = bfd_mach_sparc; break;
285     default:
286       *subtype = bfd_arch_unknown;
287     }
288 }
289 
290 static int
bfd_mach_o_write_header(bfd * abfd,bfd_mach_o_header * header)291 bfd_mach_o_write_header (bfd *abfd, bfd_mach_o_header *header)
292 {
293   unsigned char buf[28];
294 
295   bfd_h_put_32 (abfd, header->magic, buf + 0);
296   bfd_h_put_32 (abfd, header->cputype, buf + 4);
297   bfd_h_put_32 (abfd, header->cpusubtype, buf + 8);
298   bfd_h_put_32 (abfd, header->filetype, buf + 12);
299   bfd_h_put_32 (abfd, header->ncmds, buf + 16);
300   bfd_h_put_32 (abfd, header->sizeofcmds, buf + 20);
301   bfd_h_put_32 (abfd, header->flags, buf + 24);
302 
303   bfd_seek (abfd, 0, SEEK_SET);
304   if (bfd_bwrite ((PTR) buf, 28, abfd) != 28)
305     return -1;
306 
307   return 0;
308 }
309 
310 static int
bfd_mach_o_scan_write_thread(bfd * abfd,bfd_mach_o_load_command * command)311 bfd_mach_o_scan_write_thread (bfd *abfd,
312 			      bfd_mach_o_load_command *command)
313 {
314   bfd_mach_o_thread_command *cmd = &command->command.thread;
315   unsigned int i;
316   unsigned char buf[8];
317   bfd_vma offset;
318   unsigned int nflavours;
319 
320   BFD_ASSERT ((command->type == BFD_MACH_O_LC_THREAD)
321 	      || (command->type == BFD_MACH_O_LC_UNIXTHREAD));
322 
323   offset = 8;
324   nflavours = 0;
325   for (i = 0; i < cmd->nflavours; i++)
326     {
327       BFD_ASSERT ((cmd->flavours[i].size % 4) == 0);
328       BFD_ASSERT (cmd->flavours[i].offset == (command->offset + offset + 8));
329 
330       bfd_h_put_32 (abfd, cmd->flavours[i].flavour, buf);
331       bfd_h_put_32 (abfd, (cmd->flavours[i].size / 4), buf + 4);
332 
333       bfd_seek (abfd, command->offset + offset, SEEK_SET);
334       if (bfd_bwrite ((PTR) buf, 8, abfd) != 8)
335 	return -1;
336 
337       offset += cmd->flavours[i].size + 8;
338     }
339 
340   return 0;
341 }
342 
343 static int
bfd_mach_o_scan_write_section(bfd * abfd,bfd_mach_o_section * section,bfd_vma offset)344 bfd_mach_o_scan_write_section (bfd *abfd,
345 			       bfd_mach_o_section *section,
346 			       bfd_vma offset)
347 {
348   unsigned char buf[68];
349 
350   memcpy (buf, section->sectname, 16);
351   memcpy (buf + 16, section->segname, 16);
352   bfd_h_put_32 (abfd, section->addr, buf + 32);
353   bfd_h_put_32 (abfd, section->size, buf + 36);
354   bfd_h_put_32 (abfd, section->offset, buf + 40);
355   bfd_h_put_32 (abfd, section->align, buf + 44);
356   bfd_h_put_32 (abfd, section->reloff, buf + 48);
357   bfd_h_put_32 (abfd, section->nreloc, buf + 52);
358   bfd_h_put_32 (abfd, section->flags, buf + 56);
359   /* bfd_h_put_32 (abfd, section->reserved1, buf + 60); */
360   /* bfd_h_put_32 (abfd, section->reserved2, buf + 64); */
361 
362   bfd_seek (abfd, offset, SEEK_SET);
363   if (bfd_bwrite ((PTR) buf, 68, abfd) != 68)
364     return -1;
365 
366   return 0;
367 }
368 
369 static int
bfd_mach_o_scan_write_segment(bfd * abfd,bfd_mach_o_load_command * command)370 bfd_mach_o_scan_write_segment (bfd *abfd, bfd_mach_o_load_command *command)
371 {
372   unsigned char buf[48];
373   bfd_mach_o_segment_command *seg = &command->command.segment;
374   unsigned long i;
375 
376   BFD_ASSERT (command->type == BFD_MACH_O_LC_SEGMENT);
377 
378   memcpy (buf, seg->segname, 16);
379   bfd_h_put_32 (abfd, seg->vmaddr, buf + 16);
380   bfd_h_put_32 (abfd, seg->vmsize, buf + 20);
381   bfd_h_put_32 (abfd, seg->fileoff, buf + 24);
382   bfd_h_put_32 (abfd, seg->filesize, buf + 28);
383   bfd_h_put_32 (abfd, 0 /* seg->maxprot */, buf + 32);
384   bfd_h_put_32 (abfd, 0 /* seg->initprot */, buf + 36);
385   bfd_h_put_32 (abfd, seg->nsects, buf + 40);
386   bfd_h_put_32 (abfd, seg->flags, buf + 44);
387 
388   bfd_seek (abfd, command->offset + 8, SEEK_SET);
389   if (bfd_bwrite ((PTR) buf, 48, abfd) != 48)
390     return -1;
391 
392   {
393     char buf[1024];
394     bfd_vma nbytes = seg->filesize;
395     bfd_vma curoff = seg->fileoff;
396 
397     while (nbytes > 0)
398       {
399 	bfd_vma thisread = nbytes;
400 
401 	if (thisread > 1024)
402 	  thisread = 1024;
403 
404 	bfd_seek (abfd, curoff, SEEK_SET);
405 	if (bfd_bread ((PTR) buf, thisread, abfd) != thisread)
406 	  return -1;
407 
408 	bfd_seek (abfd, curoff, SEEK_SET);
409 	if (bfd_bwrite ((PTR) buf, thisread, abfd) != thisread)
410 	  return -1;
411 
412 	nbytes -= thisread;
413 	curoff += thisread;
414       }
415   }
416 
417   for (i = 0; i < seg->nsects; i++)
418     {
419       bfd_vma segoff = command->offset + 48 + 8 + (i * 68);
420 
421       if (bfd_mach_o_scan_write_section (abfd, &seg->sections[i], segoff) != 0)
422 	return -1;
423     }
424 
425   return 0;
426 }
427 
428 static int
bfd_mach_o_scan_write_symtab_symbols(bfd * abfd,bfd_mach_o_load_command * command)429 bfd_mach_o_scan_write_symtab_symbols (bfd *abfd,
430 				      bfd_mach_o_load_command *command)
431 {
432   bfd_mach_o_symtab_command *sym = &command->command.symtab;
433   asymbol *s = NULL;
434   unsigned long i;
435 
436   for (i = 0; i < sym->nsyms; i++)
437     {
438       unsigned char buf[12];
439       bfd_vma symoff = sym->symoff + (i * 12);
440       unsigned char ntype = 0;
441       unsigned char nsect = 0;
442       short ndesc = 0;
443 
444       s = &sym->symbols[i];
445 
446       /* Instead just set from the stored values.  */
447       ntype = (s->udata.i >> 24) & 0xff;
448       nsect = (s->udata.i >> 16) & 0xff;
449       ndesc = s->udata.i & 0xffff;
450 
451       bfd_h_put_32 (abfd, s->name - sym->strtab, buf);
452       bfd_h_put_8 (abfd, ntype, buf + 4);
453       bfd_h_put_8 (abfd, nsect, buf + 5);
454       bfd_h_put_16 (abfd, ndesc, buf + 6);
455       bfd_h_put_32 (abfd, s->section->vma + s->value, buf + 8);
456 
457       bfd_seek (abfd, symoff, SEEK_SET);
458       if (bfd_bwrite ((PTR) buf, 12, abfd) != 12)
459 	{
460 	  fprintf (stderr, "bfd_mach_o_scan_write_symtab_symbols: unable to write %d bytes at %lu\n",
461 		   12, (unsigned long) symoff);
462 	  return -1;
463 	}
464     }
465 
466   return 0;
467 }
468 
469 static int
bfd_mach_o_scan_write_symtab(bfd * abfd,bfd_mach_o_load_command * command)470 bfd_mach_o_scan_write_symtab (bfd *abfd, bfd_mach_o_load_command *command)
471 {
472   bfd_mach_o_symtab_command *seg = &command->command.symtab;
473   unsigned char buf[16];
474 
475   BFD_ASSERT (command->type == BFD_MACH_O_LC_SYMTAB);
476 
477   bfd_h_put_32 (abfd, seg->symoff, buf);
478   bfd_h_put_32 (abfd, seg->nsyms, buf + 4);
479   bfd_h_put_32 (abfd, seg->stroff, buf + 8);
480   bfd_h_put_32 (abfd, seg->strsize, buf + 12);
481 
482   bfd_seek (abfd, command->offset + 8, SEEK_SET);
483   if (bfd_bwrite ((PTR) buf, 16, abfd) != 16)
484     return -1;
485 
486   if (bfd_mach_o_scan_write_symtab_symbols (abfd, command) != 0)
487     return -1;
488 
489   return 0;
490 }
491 
492 static bfd_boolean
bfd_mach_o_write_contents(bfd * abfd)493 bfd_mach_o_write_contents (bfd *abfd)
494 {
495   unsigned int i;
496   asection *s;
497 
498   bfd_mach_o_data_struct *mdata = abfd->tdata.mach_o_data;
499 
500   /* Write data sections first in case they overlap header data to be
501      written later.  */
502 
503   for (s = abfd->sections; s != (asection *) NULL; s = s->next)
504     ;
505 
506   /* Now write header information.  */
507   if (bfd_mach_o_write_header (abfd, &mdata->header) != 0)
508     return FALSE;
509 
510   for (i = 0; i < mdata->header.ncmds; i++)
511     {
512       unsigned char buf[8];
513       bfd_mach_o_load_command *cur = &mdata->commands[i];
514       unsigned long typeflag;
515 
516       typeflag = cur->type_required ? cur->type & BFD_MACH_O_LC_REQ_DYLD : cur->type;
517 
518       bfd_h_put_32 (abfd, typeflag, buf);
519       bfd_h_put_32 (abfd, cur->len, buf + 4);
520 
521       bfd_seek (abfd, cur->offset, SEEK_SET);
522       if (bfd_bwrite ((PTR) buf, 8, abfd) != 8)
523 	return FALSE;
524 
525       switch (cur->type)
526 	{
527 	case BFD_MACH_O_LC_SEGMENT:
528 	  if (bfd_mach_o_scan_write_segment (abfd, cur) != 0)
529 	    return FALSE;
530 	  break;
531 	case BFD_MACH_O_LC_SYMTAB:
532 	  if (bfd_mach_o_scan_write_symtab (abfd, cur) != 0)
533 	    return FALSE;
534 	  break;
535 	case BFD_MACH_O_LC_SYMSEG:
536 	  break;
537 	case BFD_MACH_O_LC_THREAD:
538 	case BFD_MACH_O_LC_UNIXTHREAD:
539 	  if (bfd_mach_o_scan_write_thread (abfd, cur) != 0)
540 	    return FALSE;
541 	  break;
542 	case BFD_MACH_O_LC_LOADFVMLIB:
543 	case BFD_MACH_O_LC_IDFVMLIB:
544 	case BFD_MACH_O_LC_IDENT:
545 	case BFD_MACH_O_LC_FVMFILE:
546 	case BFD_MACH_O_LC_PREPAGE:
547 	case BFD_MACH_O_LC_DYSYMTAB:
548 	case BFD_MACH_O_LC_LOAD_DYLIB:
549 	case BFD_MACH_O_LC_LOAD_WEAK_DYLIB:
550 	case BFD_MACH_O_LC_ID_DYLIB:
551 	case BFD_MACH_O_LC_LOAD_DYLINKER:
552 	case BFD_MACH_O_LC_ID_DYLINKER:
553 	case BFD_MACH_O_LC_PREBOUND_DYLIB:
554 	case BFD_MACH_O_LC_ROUTINES:
555 	case BFD_MACH_O_LC_SUB_FRAMEWORK:
556 	  break;
557 	default:
558 	  fprintf (stderr,
559 		   "unable to write unknown load command 0x%lx\n",
560 		   (long) cur->type);
561 	  return FALSE;
562 	}
563     }
564 
565   return TRUE;
566 }
567 
568 static int
bfd_mach_o_sizeof_headers(bfd * a ATTRIBUTE_UNUSED,bfd_boolean b ATTRIBUTE_UNUSED)569 bfd_mach_o_sizeof_headers (bfd *a ATTRIBUTE_UNUSED,
570 			   bfd_boolean b ATTRIBUTE_UNUSED)
571 {
572   return 0;
573 }
574 
575 /* Make an empty symbol.  This is required only because
576    bfd_make_section_anyway wants to create a symbol for the section.  */
577 
578 static asymbol *
bfd_mach_o_make_empty_symbol(bfd * abfd)579 bfd_mach_o_make_empty_symbol (bfd *abfd)
580 {
581   asymbol *new;
582 
583   new = bfd_zalloc (abfd, sizeof (* new));
584   if (new == NULL)
585     return new;
586   new->the_bfd = abfd;
587   return new;
588 }
589 
590 static int
bfd_mach_o_read_header(bfd * abfd,bfd_mach_o_header * header)591 bfd_mach_o_read_header (bfd *abfd, bfd_mach_o_header *header)
592 {
593   unsigned char buf[28];
594   bfd_vma (*get32) (const void *) = NULL;
595 
596   bfd_seek (abfd, 0, SEEK_SET);
597 
598   if (bfd_bread ((PTR) buf, 28, abfd) != 28)
599     return -1;
600 
601   if (bfd_getb32 (buf) == 0xfeedface)
602     {
603       header->byteorder = BFD_ENDIAN_BIG;
604       header->magic = 0xfeedface;
605       get32 = bfd_getb32;
606     }
607   else if (bfd_getl32 (buf) == 0xfeedface)
608     {
609       header->byteorder = BFD_ENDIAN_LITTLE;
610       header->magic = 0xfeedface;
611       get32 = bfd_getl32;
612     }
613   else
614     {
615       header->byteorder = BFD_ENDIAN_UNKNOWN;
616       return -1;
617     }
618 
619   header->cputype = (*get32) (buf + 4);
620   header->cpusubtype = (*get32) (buf + 8);
621   header->filetype = (*get32) (buf + 12);
622   header->ncmds = (*get32) (buf + 16);
623   header->sizeofcmds = (*get32) (buf + 20);
624   header->flags = (*get32) (buf + 24);
625 
626   return 0;
627 }
628 
629 static asection *
bfd_mach_o_make_bfd_section(bfd * abfd,bfd_mach_o_section * section)630 bfd_mach_o_make_bfd_section (bfd *abfd, bfd_mach_o_section *section)
631 {
632   asection *bfdsec;
633   char *sname;
634   const char *prefix = "LC_SEGMENT";
635   unsigned int snamelen;
636 
637   snamelen = strlen (prefix) + 1
638     + strlen (section->segname) + 1
639     + strlen (section->sectname) + 1;
640 
641   sname = bfd_alloc (abfd, snamelen);
642   if (sname == NULL)
643     return NULL;
644   sprintf (sname, "%s.%s.%s", prefix, section->segname, section->sectname);
645 
646   bfdsec = bfd_make_section_anyway (abfd, sname);
647   if (bfdsec == NULL)
648     return NULL;
649 
650   bfdsec->vma = section->addr;
651   bfdsec->lma = section->addr;
652   bfdsec->size = section->size;
653   bfdsec->filepos = section->offset;
654   bfdsec->alignment_power = section->align;
655 
656   if (section->flags & BFD_MACH_O_S_ZEROFILL)
657     bfdsec->flags = SEC_ALLOC;
658   else
659     bfdsec->flags = SEC_HAS_CONTENTS | SEC_LOAD | SEC_ALLOC | SEC_CODE;
660 
661   return bfdsec;
662 }
663 
664 static int
bfd_mach_o_scan_read_section(bfd * abfd,bfd_mach_o_section * section,bfd_vma offset)665 bfd_mach_o_scan_read_section (bfd *abfd,
666 			      bfd_mach_o_section *section,
667 			      bfd_vma offset)
668 {
669   unsigned char buf[68];
670 
671   bfd_seek (abfd, offset, SEEK_SET);
672   if (bfd_bread ((PTR) buf, 68, abfd) != 68)
673     return -1;
674 
675   memcpy (section->sectname, buf, 16);
676   section->sectname[16] = '\0';
677   memcpy (section->segname, buf + 16, 16);
678   section->segname[16] = '\0';
679   section->addr = bfd_h_get_32 (abfd, buf + 32);
680   section->size = bfd_h_get_32 (abfd, buf + 36);
681   section->offset = bfd_h_get_32 (abfd, buf + 40);
682   section->align = bfd_h_get_32 (abfd, buf + 44);
683   section->reloff = bfd_h_get_32 (abfd, buf + 48);
684   section->nreloc = bfd_h_get_32 (abfd, buf + 52);
685   section->flags = bfd_h_get_32 (abfd, buf + 56);
686   section->reserved1 = bfd_h_get_32 (abfd, buf + 60);
687   section->reserved2 = bfd_h_get_32 (abfd, buf + 64);
688   section->bfdsection = bfd_mach_o_make_bfd_section (abfd, section);
689 
690   if (section->bfdsection == NULL)
691     return -1;
692 
693   return 0;
694 }
695 
696 int
bfd_mach_o_scan_read_symtab_symbol(bfd * abfd,bfd_mach_o_symtab_command * sym,asymbol * s,unsigned long i)697 bfd_mach_o_scan_read_symtab_symbol (bfd *abfd,
698 				    bfd_mach_o_symtab_command *sym,
699 				    asymbol *s,
700 				    unsigned long i)
701 {
702   bfd_mach_o_data_struct *mdata = abfd->tdata.mach_o_data;
703   bfd_vma symoff = sym->symoff + (i * 12);
704   unsigned char buf[12];
705   unsigned char type = -1;
706   unsigned char section = -1;
707   short desc = -1;
708   unsigned long value = -1;
709   unsigned long stroff = -1;
710   unsigned int symtype = -1;
711 
712   BFD_ASSERT (sym->strtab != NULL);
713 
714   bfd_seek (abfd, symoff, SEEK_SET);
715   if (bfd_bread ((PTR) buf, 12, abfd) != 12)
716     {
717       fprintf (stderr, "bfd_mach_o_scan_read_symtab_symbol: unable to read %d bytes at %lu\n",
718 	       12, (unsigned long) symoff);
719       return -1;
720     }
721 
722   stroff = bfd_h_get_32 (abfd, buf);
723   type = bfd_h_get_8 (abfd, buf + 4);
724   symtype = (type & 0x0e);
725   section = bfd_h_get_8 (abfd, buf + 5) - 1;
726   desc = bfd_h_get_16 (abfd, buf + 6);
727   value = bfd_h_get_32 (abfd, buf + 8);
728 
729   if (stroff >= sym->strsize)
730     {
731       fprintf (stderr, "bfd_mach_o_scan_read_symtab_symbol: symbol name out of range (%lu >= %lu)\n",
732 	       (unsigned long) stroff, (unsigned long) sym->strsize);
733       return -1;
734     }
735 
736   s->the_bfd = abfd;
737   s->name = sym->strtab + stroff;
738   s->value = value;
739   s->udata.i = (type << 24) | (section << 16) | desc;
740   s->flags = 0x0;
741 
742   if (type & BFD_MACH_O_N_STAB)
743     {
744       s->flags |= BSF_DEBUGGING;
745       s->section = bfd_und_section_ptr;
746     }
747   else
748     {
749       if (type & BFD_MACH_O_N_PEXT)
750 	{
751 	  type &= ~BFD_MACH_O_N_PEXT;
752 	  s->flags |= BSF_GLOBAL;
753 	}
754 
755       if (type & BFD_MACH_O_N_EXT)
756 	{
757 	  type &= ~BFD_MACH_O_N_EXT;
758 	  s->flags |= BSF_GLOBAL;
759 	}
760 
761       switch (symtype)
762 	{
763 	case BFD_MACH_O_N_UNDF:
764 	  s->section = bfd_und_section_ptr;
765 	  break;
766 	case BFD_MACH_O_N_PBUD:
767 	  s->section = bfd_und_section_ptr;
768 	  break;
769 	case BFD_MACH_O_N_ABS:
770 	  s->section = bfd_abs_section_ptr;
771 	  break;
772 	case BFD_MACH_O_N_SECT:
773 	  if ((section > 0) && (section <= mdata->nsects))
774 	    {
775 	      s->section = mdata->sections[section - 1]->bfdsection;
776 	      s->value = s->value - mdata->sections[section - 1]->addr;
777 	    }
778 	  else
779 	    {
780 	      /* Mach-O uses 0 to mean "no section"; not an error.  */
781 	      if (section != 0)
782 		{
783 		  fprintf (stderr, "bfd_mach_o_scan_read_symtab_symbol: "
784 			   "symbol \"%s\" specified invalid section %d (max %lu): setting to undefined\n",
785 			   s->name, section, mdata->nsects);
786 		}
787 	      s->section = bfd_und_section_ptr;
788 	    }
789 	  break;
790 	case BFD_MACH_O_N_INDR:
791 	  fprintf (stderr, "bfd_mach_o_scan_read_symtab_symbol: "
792 		   "symbol \"%s\" is unsupported 'indirect' reference: setting to undefined\n",
793 		   s->name);
794 	  s->section = bfd_und_section_ptr;
795 	  break;
796 	default:
797 	  fprintf (stderr, "bfd_mach_o_scan_read_symtab_symbol: "
798 		   "symbol \"%s\" specified invalid type field 0x%x: setting to undefined\n",
799 		   s->name, symtype);
800 	  s->section = bfd_und_section_ptr;
801 	  break;
802 	}
803     }
804 
805   return 0;
806 }
807 
808 int
bfd_mach_o_scan_read_symtab_strtab(bfd * abfd,bfd_mach_o_symtab_command * sym)809 bfd_mach_o_scan_read_symtab_strtab (bfd *abfd,
810 				    bfd_mach_o_symtab_command *sym)
811 {
812   BFD_ASSERT (sym->strtab == NULL);
813 
814   if (abfd->flags & BFD_IN_MEMORY)
815     {
816       struct bfd_in_memory *b;
817 
818       b = (struct bfd_in_memory *) abfd->iostream;
819 
820       if ((sym->stroff + sym->strsize) > b->size)
821 	{
822 	  bfd_set_error (bfd_error_file_truncated);
823 	  return -1;
824 	}
825       sym->strtab = (char *) b->buffer + sym->stroff;
826       return 0;
827     }
828 
829   sym->strtab = bfd_alloc (abfd, sym->strsize);
830   if (sym->strtab == NULL)
831     return -1;
832 
833   bfd_seek (abfd, sym->stroff, SEEK_SET);
834   if (bfd_bread ((PTR) sym->strtab, sym->strsize, abfd) != sym->strsize)
835     {
836       fprintf (stderr, "bfd_mach_o_scan_read_symtab_strtab: unable to read %lu bytes at %lu\n",
837 	       sym->strsize, sym->stroff);
838       return -1;
839     }
840 
841   return 0;
842 }
843 
844 int
bfd_mach_o_scan_read_symtab_symbols(bfd * abfd,bfd_mach_o_symtab_command * sym)845 bfd_mach_o_scan_read_symtab_symbols (bfd *abfd,
846 				     bfd_mach_o_symtab_command *sym)
847 {
848   unsigned long i;
849   int ret;
850 
851   BFD_ASSERT (sym->symbols == NULL);
852   sym->symbols = bfd_alloc (abfd, sym->nsyms * sizeof (asymbol));
853 
854   if (sym->symbols == NULL)
855     {
856       fprintf (stderr, "bfd_mach_o_scan_read_symtab_symbols: unable to allocate memory for symbols\n");
857       return -1;
858     }
859 
860   ret = bfd_mach_o_scan_read_symtab_strtab (abfd, sym);
861   if (ret != 0)
862     return ret;
863 
864   for (i = 0; i < sym->nsyms; i++)
865     {
866       ret = bfd_mach_o_scan_read_symtab_symbol (abfd, sym, &sym->symbols[i], i);
867       if (ret != 0)
868 	return ret;
869     }
870 
871   return 0;
872 }
873 
874 int
bfd_mach_o_scan_read_dysymtab_symbol(bfd * abfd,bfd_mach_o_dysymtab_command * dysym,bfd_mach_o_symtab_command * sym,asymbol * s,unsigned long i)875 bfd_mach_o_scan_read_dysymtab_symbol (bfd *abfd,
876 				      bfd_mach_o_dysymtab_command *dysym,
877 				      bfd_mach_o_symtab_command *sym,
878 				      asymbol *s,
879 				      unsigned long i)
880 {
881   unsigned long isymoff = dysym->indirectsymoff + (i * 4);
882   unsigned long symindex;
883   unsigned char buf[4];
884 
885   BFD_ASSERT (i < dysym->nindirectsyms);
886 
887   bfd_seek (abfd, isymoff, SEEK_SET);
888   if (bfd_bread ((PTR) buf, 4, abfd) != 4)
889     {
890       fprintf (stderr, "bfd_mach_o_scan_read_dysymtab_symbol: unable to read %lu bytes at %lu\n",
891 	       (unsigned long) 4, isymoff);
892       return -1;
893     }
894   symindex = bfd_h_get_32 (abfd, buf);
895 
896   return bfd_mach_o_scan_read_symtab_symbol (abfd, sym, s, symindex);
897 }
898 
899 static const char *
bfd_mach_o_i386_flavour_string(unsigned int flavour)900 bfd_mach_o_i386_flavour_string (unsigned int flavour)
901 {
902   switch ((int) flavour)
903     {
904     case BFD_MACH_O_i386_NEW_THREAD_STATE: return "i386_NEW_THREAD_STATE";
905     case BFD_MACH_O_i386_FLOAT_STATE: return "i386_FLOAT_STATE";
906     case BFD_MACH_O_i386_ISA_PORT_MAP_STATE: return "i386_ISA_PORT_MAP_STATE";
907     case BFD_MACH_O_i386_V86_ASSIST_STATE: return "i386_V86_ASSIST_STATE";
908     case BFD_MACH_O_i386_REGS_SEGS_STATE: return "i386_REGS_SEGS_STATE";
909     case BFD_MACH_O_i386_THREAD_SYSCALL_STATE: return "i386_THREAD_SYSCALL_STATE";
910     case BFD_MACH_O_i386_THREAD_STATE_NONE: return "i386_THREAD_STATE_NONE";
911     case BFD_MACH_O_i386_SAVED_STATE: return "i386_SAVED_STATE";
912     case BFD_MACH_O_i386_THREAD_STATE: return "i386_THREAD_STATE";
913     case BFD_MACH_O_i386_THREAD_FPSTATE: return "i386_THREAD_FPSTATE";
914     case BFD_MACH_O_i386_THREAD_EXCEPTSTATE: return "i386_THREAD_EXCEPTSTATE";
915     case BFD_MACH_O_i386_THREAD_CTHREADSTATE: return "i386_THREAD_CTHREADSTATE";
916     default: return "UNKNOWN";
917     }
918 }
919 
920 static const char *
bfd_mach_o_ppc_flavour_string(unsigned int flavour)921 bfd_mach_o_ppc_flavour_string (unsigned int flavour)
922 {
923   switch ((int) flavour)
924     {
925     case BFD_MACH_O_PPC_THREAD_STATE: return "PPC_THREAD_STATE";
926     case BFD_MACH_O_PPC_FLOAT_STATE: return "PPC_FLOAT_STATE";
927     case BFD_MACH_O_PPC_EXCEPTION_STATE: return "PPC_EXCEPTION_STATE";
928     case BFD_MACH_O_PPC_VECTOR_STATE: return "PPC_VECTOR_STATE";
929     default: return "UNKNOWN";
930     }
931 }
932 
933 static int
bfd_mach_o_scan_read_dylinker(bfd * abfd,bfd_mach_o_load_command * command)934 bfd_mach_o_scan_read_dylinker (bfd *abfd,
935 			       bfd_mach_o_load_command *command)
936 {
937   bfd_mach_o_dylinker_command *cmd = &command->command.dylinker;
938   unsigned char buf[4];
939   unsigned int nameoff;
940   asection *bfdsec;
941   char *sname;
942   const char *prefix;
943 
944   BFD_ASSERT ((command->type == BFD_MACH_O_LC_ID_DYLINKER)
945 	      || (command->type == BFD_MACH_O_LC_LOAD_DYLINKER));
946 
947   bfd_seek (abfd, command->offset + 8, SEEK_SET);
948   if (bfd_bread ((PTR) buf, 4, abfd) != 4)
949     return -1;
950 
951   nameoff = bfd_h_get_32 (abfd, buf + 0);
952 
953   cmd->name_offset = command->offset + nameoff;
954   cmd->name_len = command->len - nameoff;
955 
956   if (command->type == BFD_MACH_O_LC_LOAD_DYLINKER)
957     prefix = "LC_LOAD_DYLINKER";
958   else if (command->type == BFD_MACH_O_LC_ID_DYLINKER)
959     prefix = "LC_ID_DYLINKER";
960   else
961     abort ();
962 
963   sname = bfd_alloc (abfd, strlen (prefix) + 1);
964   if (sname == NULL)
965     return -1;
966   strcpy (sname, prefix);
967 
968   bfdsec = bfd_make_section_anyway (abfd, sname);
969   if (bfdsec == NULL)
970     return -1;
971 
972   bfdsec->vma = 0;
973   bfdsec->lma = 0;
974   bfdsec->size = command->len - 8;
975   bfdsec->filepos = command->offset + 8;
976   bfdsec->alignment_power = 0;
977   bfdsec->flags = SEC_HAS_CONTENTS;
978 
979   cmd->section = bfdsec;
980 
981   return 0;
982 }
983 
984 static int
bfd_mach_o_scan_read_dylib(bfd * abfd,bfd_mach_o_load_command * command)985 bfd_mach_o_scan_read_dylib (bfd *abfd, bfd_mach_o_load_command *command)
986 {
987   bfd_mach_o_dylib_command *cmd = &command->command.dylib;
988   unsigned char buf[16];
989   unsigned int nameoff;
990   asection *bfdsec;
991   char *sname;
992   const char *prefix;
993 
994   BFD_ASSERT ((command->type == BFD_MACH_O_LC_ID_DYLIB)
995 	      || (command->type == BFD_MACH_O_LC_LOAD_DYLIB)
996 	      || (command->type == BFD_MACH_O_LC_LOAD_WEAK_DYLIB));
997 
998   bfd_seek (abfd, command->offset + 8, SEEK_SET);
999   if (bfd_bread ((PTR) buf, 16, abfd) != 16)
1000     return -1;
1001 
1002   nameoff = bfd_h_get_32 (abfd, buf + 0);
1003   cmd->timestamp = bfd_h_get_32 (abfd, buf + 4);
1004   cmd->current_version = bfd_h_get_32 (abfd, buf + 8);
1005   cmd->compatibility_version = bfd_h_get_32 (abfd, buf + 12);
1006 
1007   cmd->name_offset = command->offset + nameoff;
1008   cmd->name_len = command->len - nameoff;
1009 
1010   if (command->type == BFD_MACH_O_LC_LOAD_DYLIB)
1011     prefix = "LC_LOAD_DYLIB";
1012   else if (command->type == BFD_MACH_O_LC_LOAD_WEAK_DYLIB)
1013     prefix = "LC_LOAD_WEAK_DYLIB";
1014   else if (command->type == BFD_MACH_O_LC_ID_DYLIB)
1015     prefix = "LC_ID_DYLIB";
1016   else
1017     abort ();
1018 
1019   sname = bfd_alloc (abfd, strlen (prefix) + 1);
1020   if (sname == NULL)
1021     return -1;
1022   strcpy (sname, prefix);
1023 
1024   bfdsec = bfd_make_section_anyway (abfd, sname);
1025   if (bfdsec == NULL)
1026     return -1;
1027 
1028   bfdsec->vma = 0;
1029   bfdsec->lma = 0;
1030   bfdsec->size = command->len - 8;
1031   bfdsec->filepos = command->offset + 8;
1032   bfdsec->alignment_power = 0;
1033   bfdsec->flags = SEC_HAS_CONTENTS;
1034 
1035   cmd->section = bfdsec;
1036 
1037   return 0;
1038 }
1039 
1040 static int
bfd_mach_o_scan_read_prebound_dylib(bfd * abfd ATTRIBUTE_UNUSED,bfd_mach_o_load_command * command ATTRIBUTE_UNUSED)1041 bfd_mach_o_scan_read_prebound_dylib (bfd *abfd ATTRIBUTE_UNUSED,
1042 				     bfd_mach_o_load_command *command ATTRIBUTE_UNUSED)
1043 {
1044   /* bfd_mach_o_prebound_dylib_command *cmd = &command->command.prebound_dylib; */
1045 
1046   BFD_ASSERT (command->type == BFD_MACH_O_LC_PREBOUND_DYLIB);
1047   return 0;
1048 }
1049 
1050 static int
bfd_mach_o_scan_read_thread(bfd * abfd,bfd_mach_o_load_command * command)1051 bfd_mach_o_scan_read_thread (bfd *abfd, bfd_mach_o_load_command *command)
1052 {
1053   bfd_mach_o_data_struct *mdata = NULL;
1054   bfd_mach_o_thread_command *cmd = &command->command.thread;
1055   unsigned char buf[8];
1056   bfd_vma offset;
1057   unsigned int nflavours;
1058   unsigned int i;
1059 
1060   BFD_ASSERT ((command->type == BFD_MACH_O_LC_THREAD)
1061 	      || (command->type == BFD_MACH_O_LC_UNIXTHREAD));
1062 
1063   BFD_ASSERT (bfd_mach_o_valid (abfd));
1064   mdata = abfd->tdata.mach_o_data;
1065 
1066   offset = 8;
1067   nflavours = 0;
1068   while (offset != command->len)
1069     {
1070       if (offset >= command->len)
1071 	return -1;
1072 
1073       bfd_seek (abfd, command->offset + offset, SEEK_SET);
1074 
1075       if (bfd_bread ((PTR) buf, 8, abfd) != 8)
1076 	return -1;
1077 
1078       offset += 8 + bfd_h_get_32 (abfd, buf + 4) * 4;
1079       nflavours++;
1080     }
1081 
1082   cmd->flavours = bfd_alloc (abfd, nflavours * sizeof (bfd_mach_o_thread_flavour));
1083   if (cmd->flavours == NULL)
1084     return -1;
1085   cmd->nflavours = nflavours;
1086 
1087   offset = 8;
1088   nflavours = 0;
1089   while (offset != command->len)
1090     {
1091       if (offset >= command->len)
1092 	return -1;
1093 
1094       if (nflavours >= cmd->nflavours)
1095 	return -1;
1096 
1097       bfd_seek (abfd, command->offset + offset, SEEK_SET);
1098 
1099       if (bfd_bread ((PTR) buf, 8, abfd) != 8)
1100 	return -1;
1101 
1102       cmd->flavours[nflavours].flavour = bfd_h_get_32 (abfd, buf);
1103       cmd->flavours[nflavours].offset = command->offset + offset + 8;
1104       cmd->flavours[nflavours].size = bfd_h_get_32 (abfd, buf + 4) * 4;
1105       offset += cmd->flavours[nflavours].size + 8;
1106       nflavours++;
1107     }
1108 
1109   for (i = 0; i < nflavours; i++)
1110     {
1111       asection *bfdsec;
1112       unsigned int snamelen;
1113       char *sname;
1114       const char *flavourstr;
1115       const char *prefix = "LC_THREAD";
1116       unsigned int j = 0;
1117 
1118       switch (mdata->header.cputype)
1119 	{
1120 	case BFD_MACH_O_CPU_TYPE_POWERPC:
1121 	  flavourstr = bfd_mach_o_ppc_flavour_string (cmd->flavours[i].flavour);
1122 	  break;
1123 	case BFD_MACH_O_CPU_TYPE_I386:
1124 	  flavourstr = bfd_mach_o_i386_flavour_string (cmd->flavours[i].flavour);
1125 	  break;
1126 	default:
1127 	  flavourstr = "UNKNOWN_ARCHITECTURE";
1128 	  break;
1129 	}
1130 
1131       snamelen = strlen (prefix) + 1 + 20 + 1 + strlen (flavourstr) + 1;
1132       sname = bfd_alloc (abfd, snamelen);
1133       if (sname == NULL)
1134 	return -1;
1135 
1136       for (;;)
1137 	{
1138 	  sprintf (sname, "%s.%s.%u", prefix, flavourstr, j);
1139 	  if (bfd_get_section_by_name (abfd, sname) == NULL)
1140 	    break;
1141 	  j++;
1142 	}
1143 
1144       bfdsec = bfd_make_section (abfd, sname);
1145 
1146       bfdsec->vma = 0;
1147       bfdsec->lma = 0;
1148       bfdsec->size = cmd->flavours[i].size;
1149       bfdsec->filepos = cmd->flavours[i].offset;
1150       bfdsec->alignment_power = 0x0;
1151       bfdsec->flags = SEC_HAS_CONTENTS;
1152 
1153       cmd->section = bfdsec;
1154     }
1155 
1156   return 0;
1157 }
1158 
1159 static int
bfd_mach_o_scan_read_dysymtab(bfd * abfd,bfd_mach_o_load_command * command)1160 bfd_mach_o_scan_read_dysymtab (bfd *abfd, bfd_mach_o_load_command *command)
1161 {
1162   bfd_mach_o_dysymtab_command *seg = &command->command.dysymtab;
1163   unsigned char buf[72];
1164 
1165   BFD_ASSERT (command->type == BFD_MACH_O_LC_DYSYMTAB);
1166 
1167   bfd_seek (abfd, command->offset + 8, SEEK_SET);
1168   if (bfd_bread ((PTR) buf, 72, abfd) != 72)
1169     return -1;
1170 
1171   seg->ilocalsym = bfd_h_get_32 (abfd, buf + 0);
1172   seg->nlocalsym = bfd_h_get_32 (abfd, buf + 4);
1173   seg->iextdefsym = bfd_h_get_32 (abfd, buf + 8);
1174   seg->nextdefsym = bfd_h_get_32 (abfd, buf + 12);
1175   seg->iundefsym = bfd_h_get_32 (abfd, buf + 16);
1176   seg->nundefsym = bfd_h_get_32 (abfd, buf + 20);
1177   seg->tocoff = bfd_h_get_32 (abfd, buf + 24);
1178   seg->ntoc = bfd_h_get_32 (abfd, buf + 28);
1179   seg->modtaboff = bfd_h_get_32 (abfd, buf + 32);
1180   seg->nmodtab = bfd_h_get_32 (abfd, buf + 36);
1181   seg->extrefsymoff = bfd_h_get_32 (abfd, buf + 40);
1182   seg->nextrefsyms = bfd_h_get_32 (abfd, buf + 44);
1183   seg->indirectsymoff = bfd_h_get_32 (abfd, buf + 48);
1184   seg->nindirectsyms = bfd_h_get_32 (abfd, buf + 52);
1185   seg->extreloff = bfd_h_get_32 (abfd, buf + 56);
1186   seg->nextrel = bfd_h_get_32 (abfd, buf + 60);
1187   seg->locreloff = bfd_h_get_32 (abfd, buf + 64);
1188   seg->nlocrel = bfd_h_get_32 (abfd, buf + 68);
1189 
1190   return 0;
1191 }
1192 
1193 static int
bfd_mach_o_scan_read_symtab(bfd * abfd,bfd_mach_o_load_command * command)1194 bfd_mach_o_scan_read_symtab (bfd *abfd, bfd_mach_o_load_command *command)
1195 {
1196   bfd_mach_o_symtab_command *seg = &command->command.symtab;
1197   unsigned char buf[16];
1198   asection *bfdsec;
1199   char *sname;
1200   const char *prefix = "LC_SYMTAB.stabs";
1201 
1202   BFD_ASSERT (command->type == BFD_MACH_O_LC_SYMTAB);
1203 
1204   bfd_seek (abfd, command->offset + 8, SEEK_SET);
1205   if (bfd_bread ((PTR) buf, 16, abfd) != 16)
1206     return -1;
1207 
1208   seg->symoff = bfd_h_get_32 (abfd, buf);
1209   seg->nsyms = bfd_h_get_32 (abfd, buf + 4);
1210   seg->stroff = bfd_h_get_32 (abfd, buf + 8);
1211   seg->strsize = bfd_h_get_32 (abfd, buf + 12);
1212   seg->symbols = NULL;
1213   seg->strtab = NULL;
1214 
1215   sname = bfd_alloc (abfd, strlen (prefix) + 1);
1216   if (sname == NULL)
1217     return -1;
1218   strcpy (sname, prefix);
1219 
1220   bfdsec = bfd_make_section_anyway (abfd, sname);
1221   if (bfdsec == NULL)
1222     return -1;
1223 
1224   bfdsec->vma = 0;
1225   bfdsec->lma = 0;
1226   bfdsec->size = seg->nsyms * 12;
1227   bfdsec->filepos = seg->symoff;
1228   bfdsec->alignment_power = 0;
1229   bfdsec->flags = SEC_HAS_CONTENTS;
1230 
1231   seg->stabs_segment = bfdsec;
1232 
1233   prefix = "LC_SYMTAB.stabstr";
1234   sname = bfd_alloc (abfd, strlen (prefix) + 1);
1235   if (sname == NULL)
1236     return -1;
1237   strcpy (sname, prefix);
1238 
1239   bfdsec = bfd_make_section_anyway (abfd, sname);
1240   if (bfdsec == NULL)
1241     return -1;
1242 
1243   bfdsec->vma = 0;
1244   bfdsec->lma = 0;
1245   bfdsec->size = seg->strsize;
1246   bfdsec->filepos = seg->stroff;
1247   bfdsec->alignment_power = 0;
1248   bfdsec->flags = SEC_HAS_CONTENTS;
1249 
1250   seg->stabstr_segment = bfdsec;
1251 
1252   return 0;
1253 }
1254 
1255 static int
bfd_mach_o_scan_read_segment(bfd * abfd,bfd_mach_o_load_command * command)1256 bfd_mach_o_scan_read_segment (bfd *abfd, bfd_mach_o_load_command *command)
1257 {
1258   unsigned char buf[48];
1259   bfd_mach_o_segment_command *seg = &command->command.segment;
1260   unsigned long i;
1261   asection *bfdsec;
1262   char *sname;
1263   const char *prefix = "LC_SEGMENT";
1264   unsigned int snamelen;
1265 
1266   BFD_ASSERT (command->type == BFD_MACH_O_LC_SEGMENT);
1267 
1268   bfd_seek (abfd, command->offset + 8, SEEK_SET);
1269   if (bfd_bread ((PTR) buf, 48, abfd) != 48)
1270     return -1;
1271 
1272   memcpy (seg->segname, buf, 16);
1273   seg->vmaddr = bfd_h_get_32 (abfd, buf + 16);
1274   seg->vmsize = bfd_h_get_32 (abfd, buf + 20);
1275   seg->fileoff = bfd_h_get_32 (abfd, buf + 24);
1276   seg->filesize = bfd_h_get_32 (abfd, buf +  28);
1277   /* seg->maxprot = bfd_h_get_32 (abfd, buf + 32); */
1278   /* seg->initprot = bfd_h_get_32 (abfd, buf + 36); */
1279   seg->nsects = bfd_h_get_32 (abfd, buf + 40);
1280   seg->flags = bfd_h_get_32 (abfd, buf + 44);
1281 
1282   snamelen = strlen (prefix) + 1 + strlen (seg->segname) + 1;
1283   sname = bfd_alloc (abfd, snamelen);
1284   if (sname == NULL)
1285     return -1;
1286   sprintf (sname, "%s.%s", prefix, seg->segname);
1287 
1288   bfdsec = bfd_make_section_anyway (abfd, sname);
1289   if (bfdsec == NULL)
1290     return -1;
1291 
1292   bfdsec->vma = seg->vmaddr;
1293   bfdsec->lma = seg->vmaddr;
1294   bfdsec->size = seg->filesize;
1295   bfdsec->filepos = seg->fileoff;
1296   bfdsec->alignment_power = 0x0;
1297   bfdsec->flags = SEC_HAS_CONTENTS | SEC_LOAD | SEC_ALLOC | SEC_CODE;
1298 
1299   seg->segment = bfdsec;
1300 
1301   if (seg->nsects != 0)
1302     {
1303       seg->sections = bfd_alloc (abfd, seg->nsects * sizeof (bfd_mach_o_section));
1304       if (seg->sections == NULL)
1305 	return -1;
1306 
1307       for (i = 0; i < seg->nsects; i++)
1308 	{
1309 	  bfd_vma segoff = command->offset + 48 + 8 + (i * 68);
1310 
1311 	  if (bfd_mach_o_scan_read_section (abfd, &seg->sections[i],
1312 					    segoff) != 0)
1313 	    return -1;
1314 	}
1315     }
1316 
1317   return 0;
1318 }
1319 
1320 static int
bfd_mach_o_scan_read_command(bfd * abfd,bfd_mach_o_load_command * command)1321 bfd_mach_o_scan_read_command (bfd *abfd, bfd_mach_o_load_command *command)
1322 {
1323   unsigned char buf[8];
1324 
1325   bfd_seek (abfd, command->offset, SEEK_SET);
1326   if (bfd_bread ((PTR) buf, 8, abfd) != 8)
1327     return -1;
1328 
1329   command->type = (bfd_h_get_32 (abfd, buf) & ~BFD_MACH_O_LC_REQ_DYLD);
1330   command->type_required = (bfd_h_get_32 (abfd, buf) & BFD_MACH_O_LC_REQ_DYLD
1331 			    ? 1 : 0);
1332   command->len = bfd_h_get_32 (abfd, buf + 4);
1333 
1334   switch (command->type)
1335     {
1336     case BFD_MACH_O_LC_SEGMENT:
1337       if (bfd_mach_o_scan_read_segment (abfd, command) != 0)
1338 	return -1;
1339       break;
1340     case BFD_MACH_O_LC_SYMTAB:
1341       if (bfd_mach_o_scan_read_symtab (abfd, command) != 0)
1342 	return -1;
1343       break;
1344     case BFD_MACH_O_LC_SYMSEG:
1345       break;
1346     case BFD_MACH_O_LC_THREAD:
1347     case BFD_MACH_O_LC_UNIXTHREAD:
1348       if (bfd_mach_o_scan_read_thread (abfd, command) != 0)
1349 	return -1;
1350       break;
1351     case BFD_MACH_O_LC_LOAD_DYLINKER:
1352     case BFD_MACH_O_LC_ID_DYLINKER:
1353       if (bfd_mach_o_scan_read_dylinker (abfd, command) != 0)
1354 	return -1;
1355       break;
1356     case BFD_MACH_O_LC_LOAD_DYLIB:
1357     case BFD_MACH_O_LC_ID_DYLIB:
1358     case BFD_MACH_O_LC_LOAD_WEAK_DYLIB:
1359       if (bfd_mach_o_scan_read_dylib (abfd, command) != 0)
1360 	return -1;
1361       break;
1362     case BFD_MACH_O_LC_PREBOUND_DYLIB:
1363       if (bfd_mach_o_scan_read_prebound_dylib (abfd, command) != 0)
1364 	return -1;
1365       break;
1366     case BFD_MACH_O_LC_LOADFVMLIB:
1367     case BFD_MACH_O_LC_IDFVMLIB:
1368     case BFD_MACH_O_LC_IDENT:
1369     case BFD_MACH_O_LC_FVMFILE:
1370     case BFD_MACH_O_LC_PREPAGE:
1371     case BFD_MACH_O_LC_ROUTINES:
1372     case BFD_MACH_O_LC_SUB_FRAMEWORK:
1373       break;
1374     case BFD_MACH_O_LC_DYSYMTAB:
1375       if (bfd_mach_o_scan_read_dysymtab (abfd, command) != 0)
1376 	return -1;
1377       break;
1378     case BFD_MACH_O_LC_SUB_UMBRELLA:
1379     case BFD_MACH_O_LC_SUB_CLIENT:
1380     case BFD_MACH_O_LC_SUB_LIBRARY:
1381     case BFD_MACH_O_LC_TWOLEVEL_HINTS:
1382     case BFD_MACH_O_LC_PREBIND_CKSUM:
1383       break;
1384     default:
1385       fprintf (stderr, "unable to read unknown load command 0x%lx\n",
1386 	       (unsigned long) command->type);
1387       break;
1388     }
1389 
1390   return 0;
1391 }
1392 
1393 static void
bfd_mach_o_flatten_sections(bfd * abfd)1394 bfd_mach_o_flatten_sections (bfd *abfd)
1395 {
1396   bfd_mach_o_data_struct *mdata = abfd->tdata.mach_o_data;
1397   long csect = 0;
1398   unsigned long i, j;
1399 
1400   mdata->nsects = 0;
1401 
1402   for (i = 0; i < mdata->header.ncmds; i++)
1403     {
1404       if (mdata->commands[i].type == BFD_MACH_O_LC_SEGMENT)
1405 	{
1406 	  bfd_mach_o_segment_command *seg;
1407 
1408 	  seg = &mdata->commands[i].command.segment;
1409 	  mdata->nsects += seg->nsects;
1410 	}
1411     }
1412 
1413   mdata->sections = bfd_alloc (abfd,
1414 			       mdata->nsects * sizeof (bfd_mach_o_section *));
1415   csect = 0;
1416 
1417   for (i = 0; i < mdata->header.ncmds; i++)
1418     {
1419       if (mdata->commands[i].type == BFD_MACH_O_LC_SEGMENT)
1420 	{
1421 	  bfd_mach_o_segment_command *seg;
1422 
1423 	  seg = &mdata->commands[i].command.segment;
1424 	  BFD_ASSERT (csect + seg->nsects <= mdata->nsects);
1425 
1426 	  for (j = 0; j < seg->nsects; j++)
1427 	    mdata->sections[csect++] = &seg->sections[j];
1428 	}
1429     }
1430 }
1431 
1432 int
bfd_mach_o_scan_start_address(bfd * abfd)1433 bfd_mach_o_scan_start_address (bfd *abfd)
1434 {
1435   bfd_mach_o_data_struct *mdata = abfd->tdata.mach_o_data;
1436   bfd_mach_o_thread_command *cmd = NULL;
1437   unsigned long i;
1438 
1439   for (i = 0; i < mdata->header.ncmds; i++)
1440     {
1441       if ((mdata->commands[i].type == BFD_MACH_O_LC_THREAD) ||
1442 	  (mdata->commands[i].type == BFD_MACH_O_LC_UNIXTHREAD))
1443 	{
1444 	  if (cmd == NULL)
1445 	    cmd = &mdata->commands[i].command.thread;
1446 	  else
1447 	    return 0;
1448 	}
1449     }
1450 
1451   if (cmd == NULL)
1452     return 0;
1453 
1454   for (i = 0; i < cmd->nflavours; i++)
1455     {
1456       if ((mdata->header.cputype == BFD_MACH_O_CPU_TYPE_I386)
1457 	  && (cmd->flavours[i].flavour
1458 	      == (unsigned long) BFD_MACH_O_i386_THREAD_STATE))
1459 	{
1460 	  unsigned char buf[4];
1461 
1462 	  bfd_seek (abfd, cmd->flavours[i].offset + 40, SEEK_SET);
1463 
1464 	  if (bfd_bread (buf, 4, abfd) != 4)
1465 	    return -1;
1466 
1467 	  abfd->start_address = bfd_h_get_32 (abfd, buf);
1468 	}
1469       else if ((mdata->header.cputype == BFD_MACH_O_CPU_TYPE_POWERPC)
1470 	       && (cmd->flavours[i].flavour == BFD_MACH_O_PPC_THREAD_STATE))
1471 	{
1472 	  unsigned char buf[4];
1473 
1474 	  bfd_seek (abfd, cmd->flavours[i].offset + 0, SEEK_SET);
1475 
1476 	  if (bfd_bread (buf, 4, abfd) != 4)
1477 	    return -1;
1478 
1479 	  abfd->start_address = bfd_h_get_32 (abfd, buf);
1480 	}
1481     }
1482 
1483   return 0;
1484 }
1485 
1486 int
bfd_mach_o_scan(bfd * abfd,bfd_mach_o_header * header,bfd_mach_o_data_struct * mdata)1487 bfd_mach_o_scan (bfd *abfd,
1488 		 bfd_mach_o_header *header,
1489 		 bfd_mach_o_data_struct *mdata)
1490 {
1491   unsigned int i;
1492   enum bfd_architecture cputype;
1493   unsigned long cpusubtype;
1494 
1495   mdata->header = *header;
1496   mdata->symbols = NULL;
1497 
1498   abfd->flags = (abfd->xvec->object_flags
1499 		 | (abfd->flags & (BFD_IN_MEMORY | BFD_IO_FUNCS)));
1500   abfd->tdata.mach_o_data = mdata;
1501 
1502   bfd_mach_o_convert_architecture (header->cputype, header->cpusubtype,
1503 				   &cputype, &cpusubtype);
1504   if (cputype == bfd_arch_unknown)
1505     {
1506       fprintf (stderr, "bfd_mach_o_scan: unknown architecture 0x%lx/0x%lx\n",
1507 	       header->cputype, header->cpusubtype);
1508       return -1;
1509     }
1510 
1511   bfd_set_arch_mach (abfd, cputype, cpusubtype);
1512 
1513   if (header->ncmds != 0)
1514     {
1515       mdata->commands = bfd_alloc (abfd, header->ncmds * sizeof (bfd_mach_o_load_command));
1516       if (mdata->commands == NULL)
1517 	return -1;
1518 
1519       for (i = 0; i < header->ncmds; i++)
1520 	{
1521 	  bfd_mach_o_load_command *cur = &mdata->commands[i];
1522 
1523 	  if (i == 0)
1524 	    cur->offset = 28;
1525 	  else
1526 	    {
1527 	      bfd_mach_o_load_command *prev = &mdata->commands[i - 1];
1528 	      cur->offset = prev->offset + prev->len;
1529 	    }
1530 
1531 	  if (bfd_mach_o_scan_read_command (abfd, cur) < 0)
1532 	    return -1;
1533 	}
1534     }
1535 
1536   if (bfd_mach_o_scan_start_address (abfd) < 0)
1537     return -1;
1538 
1539   bfd_mach_o_flatten_sections (abfd);
1540   return 0;
1541 }
1542 
1543 bfd_boolean
bfd_mach_o_mkobject(bfd * abfd)1544 bfd_mach_o_mkobject (bfd *abfd)
1545 {
1546   bfd_mach_o_data_struct *mdata = NULL;
1547 
1548   mdata = bfd_alloc (abfd, sizeof (bfd_mach_o_data_struct));
1549   if (mdata == NULL)
1550     return FALSE;
1551   abfd->tdata.mach_o_data = mdata;
1552 
1553   mdata->header.magic = 0;
1554   mdata->header.cputype = 0;
1555   mdata->header.cpusubtype = 0;
1556   mdata->header.filetype = 0;
1557   mdata->header.ncmds = 0;
1558   mdata->header.sizeofcmds = 0;
1559   mdata->header.flags = 0;
1560   mdata->header.byteorder = BFD_ENDIAN_UNKNOWN;
1561   mdata->commands = NULL;
1562   mdata->nsymbols = 0;
1563   mdata->symbols = NULL;
1564   mdata->nsects = 0;
1565   mdata->sections = NULL;
1566   mdata->ibfd = NULL;
1567 
1568   return TRUE;
1569 }
1570 
1571 const bfd_target *
bfd_mach_o_object_p(bfd * abfd)1572 bfd_mach_o_object_p (bfd *abfd)
1573 {
1574   struct bfd_preserve preserve;
1575   bfd_mach_o_header header;
1576 
1577   preserve.marker = NULL;
1578   if (bfd_mach_o_read_header (abfd, &header) != 0)
1579     goto wrong;
1580 
1581   if (! (header.byteorder == BFD_ENDIAN_BIG
1582 	 || header.byteorder == BFD_ENDIAN_LITTLE))
1583     {
1584       fprintf (stderr, "unknown header byte-order value 0x%lx\n",
1585 	       (long) header.byteorder);
1586       goto wrong;
1587     }
1588 
1589   if (! ((header.byteorder == BFD_ENDIAN_BIG
1590 	  && abfd->xvec->byteorder == BFD_ENDIAN_BIG
1591 	  && abfd->xvec->header_byteorder == BFD_ENDIAN_BIG)
1592 	 || (header.byteorder == BFD_ENDIAN_LITTLE
1593 	     && abfd->xvec->byteorder == BFD_ENDIAN_LITTLE
1594 	     && abfd->xvec->header_byteorder == BFD_ENDIAN_LITTLE)))
1595     goto wrong;
1596 
1597   preserve.marker = bfd_zalloc (abfd, sizeof (bfd_mach_o_data_struct));
1598   if (preserve.marker == NULL
1599       || !bfd_preserve_save (abfd, &preserve))
1600     goto fail;
1601 
1602   if (bfd_mach_o_scan (abfd, &header,
1603 		       (bfd_mach_o_data_struct *) preserve.marker) != 0)
1604     goto wrong;
1605 
1606   bfd_preserve_finish (abfd, &preserve);
1607   return abfd->xvec;
1608 
1609  wrong:
1610   bfd_set_error (bfd_error_wrong_format);
1611 
1612  fail:
1613   if (preserve.marker != NULL)
1614     bfd_preserve_restore (abfd, &preserve);
1615   return NULL;
1616 }
1617 
1618 const bfd_target *
bfd_mach_o_core_p(bfd * abfd)1619 bfd_mach_o_core_p (bfd *abfd)
1620 {
1621   struct bfd_preserve preserve;
1622   bfd_mach_o_header header;
1623 
1624   preserve.marker = NULL;
1625   if (bfd_mach_o_read_header (abfd, &header) != 0)
1626     goto wrong;
1627 
1628   if (! (header.byteorder == BFD_ENDIAN_BIG
1629 	 || header.byteorder == BFD_ENDIAN_LITTLE))
1630     {
1631       fprintf (stderr, "unknown header byte-order value 0x%lx\n",
1632 	       (long) header.byteorder);
1633       abort ();
1634     }
1635 
1636   if (! ((header.byteorder == BFD_ENDIAN_BIG
1637 	  && abfd->xvec->byteorder == BFD_ENDIAN_BIG
1638 	  && abfd->xvec->header_byteorder == BFD_ENDIAN_BIG)
1639 	 || (header.byteorder == BFD_ENDIAN_LITTLE
1640 	     && abfd->xvec->byteorder == BFD_ENDIAN_LITTLE
1641 	     && abfd->xvec->header_byteorder == BFD_ENDIAN_LITTLE)))
1642     goto wrong;
1643 
1644   if (header.filetype != BFD_MACH_O_MH_CORE)
1645     goto wrong;
1646 
1647   preserve.marker = bfd_zalloc (abfd, sizeof (bfd_mach_o_data_struct));
1648   if (preserve.marker == NULL
1649       || !bfd_preserve_save (abfd, &preserve))
1650     goto fail;
1651 
1652   if (bfd_mach_o_scan (abfd, &header,
1653 		       (bfd_mach_o_data_struct *) preserve.marker) != 0)
1654     goto wrong;
1655 
1656   bfd_preserve_finish (abfd, &preserve);
1657   return abfd->xvec;
1658 
1659  wrong:
1660   bfd_set_error (bfd_error_wrong_format);
1661 
1662  fail:
1663   if (preserve.marker != NULL)
1664     bfd_preserve_restore (abfd, &preserve);
1665   return NULL;
1666 }
1667 
1668 typedef struct mach_o_fat_archentry
1669 {
1670   unsigned long cputype;
1671   unsigned long cpusubtype;
1672   unsigned long offset;
1673   unsigned long size;
1674   unsigned long align;
1675   bfd *abfd;
1676 } mach_o_fat_archentry;
1677 
1678 typedef struct mach_o_fat_data_struct
1679 {
1680   unsigned long magic;
1681   unsigned long nfat_arch;
1682   mach_o_fat_archentry *archentries;
1683 } mach_o_fat_data_struct;
1684 
1685 const bfd_target *
bfd_mach_o_archive_p(bfd * abfd)1686 bfd_mach_o_archive_p (bfd *abfd)
1687 {
1688   mach_o_fat_data_struct *adata = NULL;
1689   unsigned char buf[20];
1690   unsigned long i;
1691 
1692   bfd_seek (abfd, 0, SEEK_SET);
1693   if (bfd_bread ((PTR) buf, 8, abfd) != 8)
1694     goto error;
1695 
1696   adata = bfd_alloc (abfd, sizeof (mach_o_fat_data_struct));
1697   if (adata == NULL)
1698     goto error;
1699 
1700   adata->magic = bfd_getb32 (buf);
1701   adata->nfat_arch = bfd_getb32 (buf + 4);
1702   if (adata->magic != 0xcafebabe)
1703     goto error;
1704 
1705   adata->archentries =
1706     bfd_alloc (abfd, adata->nfat_arch * sizeof (mach_o_fat_archentry));
1707   if (adata->archentries == NULL)
1708     goto error;
1709 
1710   for (i = 0; i < adata->nfat_arch; i++)
1711     {
1712       bfd_seek (abfd, 8 + 20 * i, SEEK_SET);
1713 
1714       if (bfd_bread ((PTR) buf, 20, abfd) != 20)
1715 	goto error;
1716       adata->archentries[i].cputype = bfd_getb32 (buf);
1717       adata->archentries[i].cpusubtype = bfd_getb32 (buf + 4);
1718       adata->archentries[i].offset = bfd_getb32 (buf + 8);
1719       adata->archentries[i].size = bfd_getb32 (buf + 12);
1720       adata->archentries[i].align = bfd_getb32 (buf + 16);
1721       adata->archentries[i].abfd = NULL;
1722     }
1723 
1724   abfd->tdata.mach_o_fat_data = adata;
1725   return abfd->xvec;
1726 
1727  error:
1728   if (adata != NULL)
1729     bfd_release (abfd, adata);
1730   bfd_set_error (bfd_error_wrong_format);
1731   return NULL;
1732 }
1733 
1734 bfd *
bfd_mach_o_openr_next_archived_file(bfd * archive,bfd * prev)1735 bfd_mach_o_openr_next_archived_file (bfd *archive, bfd *prev)
1736 {
1737   mach_o_fat_data_struct *adata;
1738   mach_o_fat_archentry *entry = NULL;
1739   unsigned long i;
1740 
1741   adata = (mach_o_fat_data_struct *) archive->tdata.mach_o_fat_data;
1742   BFD_ASSERT (adata != NULL);
1743 
1744   /* Find index of previous entry.  */
1745   if (prev == NULL)
1746     i = 0;	/* Start at first one.  */
1747   else
1748     {
1749       for (i = 0; i < adata->nfat_arch; i++)
1750 	{
1751 	  if (adata->archentries[i].abfd == prev)
1752 	    break;
1753 	}
1754 
1755       if (i == adata->nfat_arch)
1756 	{
1757 	  /* Not found.  */
1758 	  bfd_set_error (bfd_error_bad_value);
1759 	  return NULL;
1760 	}
1761     i++;	/* Get next entry.  */
1762   }
1763 
1764   if (i >= adata->nfat_arch)
1765     {
1766       bfd_set_error (bfd_error_no_more_archived_files);
1767       return NULL;
1768     }
1769 
1770   entry = &adata->archentries[i];
1771   if (entry->abfd == NULL)
1772     {
1773       bfd *nbfd = _bfd_new_bfd_contained_in (archive);
1774       char *s = NULL;
1775 
1776       if (nbfd == NULL)
1777 	return NULL;
1778 
1779       nbfd->origin = entry->offset;
1780       s = bfd_malloc (strlen (archive->filename) + 1);
1781       if (s == NULL)
1782 	return NULL;
1783       strcpy (s, archive->filename);
1784       nbfd->filename = s;
1785       nbfd->iostream = NULL;
1786       entry->abfd = nbfd;
1787     }
1788 
1789   return entry->abfd;
1790 }
1791 
1792 int
bfd_mach_o_lookup_section(bfd * abfd,asection * section,bfd_mach_o_load_command ** mcommand,bfd_mach_o_section ** msection)1793 bfd_mach_o_lookup_section (bfd *abfd,
1794 			   asection *section,
1795 			   bfd_mach_o_load_command **mcommand,
1796 			   bfd_mach_o_section **msection)
1797 {
1798   struct mach_o_data_struct *md = abfd->tdata.mach_o_data;
1799   unsigned int i, j, num;
1800 
1801   bfd_mach_o_load_command *ncmd = NULL;
1802   bfd_mach_o_section *nsect = NULL;
1803 
1804   BFD_ASSERT (mcommand != NULL);
1805   BFD_ASSERT (msection != NULL);
1806 
1807   num = 0;
1808   for (i = 0; i < md->header.ncmds; i++)
1809     {
1810       struct bfd_mach_o_load_command *cmd = &md->commands[i];
1811       struct bfd_mach_o_segment_command *seg = NULL;
1812 
1813       if (cmd->type != BFD_MACH_O_LC_SEGMENT)
1814 	continue;
1815       seg = &cmd->command.segment;
1816 
1817       if (seg->segment == section)
1818 	{
1819 	  if (num == 0)
1820 	    ncmd = cmd;
1821 	  num++;
1822 	}
1823 
1824       for (j = 0; j < seg->nsects; j++)
1825 	{
1826 	  struct bfd_mach_o_section *sect = &seg->sections[j];
1827 
1828 	  if (sect->bfdsection == section)
1829 	    {
1830 	      if (num == 0)
1831 		nsect = sect;
1832 	      num++;
1833 	    }
1834 	}
1835     }
1836 
1837   *mcommand = ncmd;
1838   *msection = nsect;
1839   return num;
1840 }
1841 
1842 int
bfd_mach_o_lookup_command(bfd * abfd,bfd_mach_o_load_command_type type,bfd_mach_o_load_command ** mcommand)1843 bfd_mach_o_lookup_command (bfd *abfd,
1844 			   bfd_mach_o_load_command_type type,
1845 			   bfd_mach_o_load_command **mcommand)
1846 {
1847   struct mach_o_data_struct *md = NULL;
1848   bfd_mach_o_load_command *ncmd = NULL;
1849   unsigned int i, num;
1850 
1851   md = abfd->tdata.mach_o_data;
1852 
1853   BFD_ASSERT (md != NULL);
1854   BFD_ASSERT (mcommand != NULL);
1855 
1856   num = 0;
1857   for (i = 0; i < md->header.ncmds; i++)
1858     {
1859       struct bfd_mach_o_load_command *cmd = &md->commands[i];
1860 
1861       if (cmd->type != type)
1862 	continue;
1863 
1864       if (num == 0)
1865 	ncmd = cmd;
1866       num++;
1867     }
1868 
1869   *mcommand = ncmd;
1870   return num;
1871 }
1872 
1873 unsigned long
bfd_mach_o_stack_addr(enum bfd_mach_o_cpu_type type)1874 bfd_mach_o_stack_addr (enum bfd_mach_o_cpu_type type)
1875 {
1876   switch (type)
1877     {
1878     case BFD_MACH_O_CPU_TYPE_MC680x0:
1879       return 0x04000000;
1880     case BFD_MACH_O_CPU_TYPE_MC88000:
1881       return 0xffffe000;
1882     case BFD_MACH_O_CPU_TYPE_POWERPC:
1883       return 0xc0000000;
1884     case BFD_MACH_O_CPU_TYPE_I386:
1885       return 0xc0000000;
1886     case BFD_MACH_O_CPU_TYPE_SPARC:
1887       return 0xf0000000;
1888     case BFD_MACH_O_CPU_TYPE_I860:
1889       return 0;
1890     case BFD_MACH_O_CPU_TYPE_HPPA:
1891       return 0xc0000000 - 0x04000000;
1892     default:
1893       return 0;
1894     }
1895 }
1896 
1897 int
bfd_mach_o_core_fetch_environment(bfd * abfd,unsigned char ** rbuf,unsigned int * rlen)1898 bfd_mach_o_core_fetch_environment (bfd *abfd,
1899 				   unsigned char **rbuf,
1900 				   unsigned int *rlen)
1901 {
1902   bfd_mach_o_data_struct *mdata = abfd->tdata.mach_o_data;
1903   unsigned long stackaddr = bfd_mach_o_stack_addr (mdata->header.cputype);
1904   unsigned int i = 0;
1905 
1906   for (i = 0; i < mdata->header.ncmds; i++)
1907     {
1908       bfd_mach_o_load_command *cur = &mdata->commands[i];
1909       bfd_mach_o_segment_command *seg = NULL;
1910 
1911       if (cur->type != BFD_MACH_O_LC_SEGMENT)
1912 	continue;
1913 
1914       seg = &cur->command.segment;
1915 
1916       if ((seg->vmaddr + seg->vmsize) == stackaddr)
1917 	{
1918 	  unsigned long start = seg->fileoff;
1919 	  unsigned long end = seg->fileoff + seg->filesize;
1920 	  unsigned char *buf = bfd_malloc (1024);
1921 	  unsigned long size = 1024;
1922 
1923 	  for (;;)
1924 	    {
1925 	      bfd_size_type nread = 0;
1926 	      unsigned long offset;
1927 	      int found_nonnull = 0;
1928 
1929 	      if (size > (end - start))
1930 		size = (end - start);
1931 
1932 	      buf = bfd_realloc (buf, size);
1933 
1934 	      bfd_seek (abfd, end - size, SEEK_SET);
1935 	      nread = bfd_bread (buf, size, abfd);
1936 
1937 	      if (nread != size)
1938 		return -1;
1939 
1940 	      for (offset = 4; offset <= size; offset += 4)
1941 		{
1942 		  unsigned long val;
1943 
1944 		  val = *((unsigned long *) (buf + size - offset));
1945 		  if (! found_nonnull)
1946 		    {
1947 		      if (val != 0)
1948 			found_nonnull = 1;
1949 		    }
1950 		  else if (val == 0x0)
1951 		    {
1952 		      unsigned long bottom;
1953 		      unsigned long top;
1954 
1955 		      bottom = seg->fileoff + seg->filesize - offset;
1956 		      top = seg->fileoff + seg->filesize - 4;
1957 		      *rbuf = bfd_malloc (top - bottom);
1958 		      *rlen = top - bottom;
1959 
1960 		      memcpy (*rbuf, buf + size - *rlen, *rlen);
1961 		      return 0;
1962 		    }
1963 		}
1964 
1965 	      if (size == (end - start))
1966 		break;
1967 
1968 	      size *= 2;
1969 	    }
1970 	}
1971     }
1972 
1973   return -1;
1974 }
1975 
1976 char *
bfd_mach_o_core_file_failing_command(bfd * abfd)1977 bfd_mach_o_core_file_failing_command (bfd *abfd)
1978 {
1979   unsigned char *buf = NULL;
1980   unsigned int len = 0;
1981   int ret = -1;
1982 
1983   ret = bfd_mach_o_core_fetch_environment (abfd, &buf, &len);
1984   if (ret < 0)
1985     return NULL;
1986 
1987   return (char *) buf;
1988 }
1989 
1990 int
bfd_mach_o_core_file_failing_signal(bfd * abfd ATTRIBUTE_UNUSED)1991 bfd_mach_o_core_file_failing_signal (bfd *abfd ATTRIBUTE_UNUSED)
1992 {
1993   return 0;
1994 }
1995 
1996 bfd_boolean
bfd_mach_o_core_file_matches_executable_p(bfd * core_bfd ATTRIBUTE_UNUSED,bfd * exec_bfd ATTRIBUTE_UNUSED)1997 bfd_mach_o_core_file_matches_executable_p (bfd *core_bfd ATTRIBUTE_UNUSED,
1998 					   bfd *exec_bfd ATTRIBUTE_UNUSED)
1999 {
2000   return TRUE;
2001 }
2002 
2003 #define TARGET_NAME 		mach_o_be_vec
2004 #define TARGET_STRING     	"mach-o-be"
2005 #define TARGET_BIG_ENDIAN 	1
2006 #define TARGET_ARCHIVE 		0
2007 
2008 #include "mach-o-target.c"
2009 
2010 #undef TARGET_NAME
2011 #undef TARGET_STRING
2012 #undef TARGET_BIG_ENDIAN
2013 #undef TARGET_ARCHIVE
2014 
2015 #define TARGET_NAME 		mach_o_le_vec
2016 #define TARGET_STRING 		"mach-o-le"
2017 #define TARGET_BIG_ENDIAN 	0
2018 #define TARGET_ARCHIVE 		0
2019 
2020 #include "mach-o-target.c"
2021 
2022 #undef TARGET_NAME
2023 #undef TARGET_STRING
2024 #undef TARGET_BIG_ENDIAN
2025 #undef TARGET_ARCHIVE
2026 
2027 #define TARGET_NAME 		mach_o_fat_vec
2028 #define TARGET_STRING 		"mach-o-fat"
2029 #define TARGET_BIG_ENDIAN 	1
2030 #define TARGET_ARCHIVE 		1
2031 
2032 #include "mach-o-target.c"
2033 
2034 #undef TARGET_NAME
2035 #undef TARGET_STRING
2036 #undef TARGET_BIG_ENDIAN
2037 #undef TARGET_ARCHIVE
2038