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