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